패널 정리 중간 커밋

This commit is contained in:
kjs 2025-10-28 17:33:03 +09:00
parent b5605d93da
commit 743ae6dbf1
43 changed files with 1191 additions and 1666 deletions

View File

@ -87,21 +87,12 @@ interface ScreenDesignerProps {
onBackToList: () => void;
}
// 패널 설정 (컴포넌트와 편집 2개)
// 패널 설정 (통합 패널 1개)
const panelConfigs: PanelConfig[] = [
// 컴포넌트 패널 (테이블 + 컴포넌트 탭)
// 통합 패널 (컴포넌트 + 편집 탭)
{
id: "components",
title: "컴포넌트",
defaultPosition: "left",
defaultWidth: 240,
defaultHeight: 700,
shortcutKey: "c",
},
// 편집 패널 (속성 + 스타일 & 해상도 탭)
{
id: "properties",
title: "편집",
id: "unified",
title: "패널",
defaultPosition: "left",
defaultWidth: 240,
defaultHeight: 700,
@ -141,14 +132,14 @@ export default function ScreenDesigner({ selectedScreen, onBackToList }: ScreenD
const [selectedComponent, setSelectedComponent] = useState<ComponentData | null>(null);
// 컴포넌트 선택 시 속성 패널 자동 열기
// 컴포넌트 선택 시 통합 패널 자동 열기
const handleComponentSelect = useCallback(
(component: ComponentData | null) => {
setSelectedComponent(component);
// 컴포넌트가 선택되면 속성 패널 자동 열기
// 컴포넌트가 선택되면 통합 패널 자동 열기
if (component) {
openPanel("properties");
openPanel("unified");
}
},
[openPanel],
@ -4119,74 +4110,72 @@ export default function ScreenDesigner({ selectedScreen, onBackToList }: ScreenD
{/* 좌측 통합 툴바 */}
<LeftUnifiedToolbar buttons={defaultToolbarButtons} panelStates={panelStates} onTogglePanel={togglePanel} />
{/* 열린 패널들 (좌측에서 우측으로 누적) */}
{panelStates.components?.isOpen && (
{/* 통합 패널 */}
{panelStates.unified?.isOpen && (
<div className="border-border bg-card flex h-full w-[240px] flex-col border-r shadow-sm">
<div className="border-border flex items-center justify-between border-b px-6 py-4">
<h3 className="text-foreground text-lg font-semibold"></h3>
<div className="border-border flex items-center justify-between border-b px-4 py-3">
<h3 className="text-foreground text-sm font-semibold"></h3>
<button
onClick={() => closePanel("components")}
onClick={() => closePanel("unified")}
className="text-muted-foreground hover:text-foreground focus-visible:ring-ring rounded-sm transition-colors focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:outline-none"
>
</button>
</div>
<div className="flex-1 overflow-hidden">
<ComponentsPanel
tables={filteredTables}
searchTerm={searchTerm}
onSearchChange={setSearchTerm}
onTableDragStart={(e, table, column) => {
const dragData = {
type: column ? "column" : "table",
table,
column,
};
e.dataTransfer.setData("application/json", JSON.stringify(dragData));
}}
selectedTableName={selectedScreen.tableName}
placedColumns={placedColumns}
/>
<div className="flex min-h-0 flex-1 flex-col">
<Tabs defaultValue="components" className="flex min-h-0 flex-1 flex-col">
<TabsList className="mx-4 mt-2 grid h-8 w-auto grid-cols-2 gap-1">
<TabsTrigger value="components" className="text-xs">
</TabsTrigger>
<TabsTrigger value="properties" className="text-xs">
</TabsTrigger>
</TabsList>
<TabsContent value="components" className="mt-0 flex-1 overflow-hidden">
<ComponentsPanel
tables={filteredTables}
searchTerm={searchTerm}
onSearchChange={setSearchTerm}
onTableDragStart={(e, table, column) => {
const dragData = {
type: column ? "column" : "table",
table,
column,
};
e.dataTransfer.setData("application/json", JSON.stringify(dragData));
}}
selectedTableName={selectedScreen.tableName}
placedColumns={placedColumns}
/>
</TabsContent>
<TabsContent value="properties" className="mt-0 flex-1 overflow-hidden">
<UnifiedPropertiesPanel
selectedComponent={selectedComponent || undefined}
tables={tables}
onUpdateProperty={updateComponentProperty}
onDeleteComponent={deleteComponent}
onCopyComponent={copyComponent}
currentTable={tables.length > 0 ? tables[0] : undefined}
currentTableName={selectedScreen?.tableName}
dragState={dragState}
onStyleChange={(style) => {
if (selectedComponent) {
updateComponentProperty(selectedComponent.id, "style", style);
}
}}
currentResolution={screenResolution}
onResolutionChange={handleResolutionChange}
allComponents={layout.components} // 🆕 플로우 위젯 감지용
/>
</TabsContent>
</Tabs>
</div>
</div>
)}
{panelStates.properties?.isOpen && (
<div className="border-border bg-card flex h-full w-[240px] flex-col border-r shadow-sm">
<div className="border-border flex items-center justify-between border-b px-6 py-4">
<h3 className="text-foreground text-lg font-semibold"></h3>
<button
onClick={() => closePanel("properties")}
className="text-muted-foreground hover:text-foreground focus-visible:ring-ring rounded-sm transition-colors focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:outline-none"
>
</button>
</div>
<div className="flex-1 overflow-hidden">
<UnifiedPropertiesPanel
selectedComponent={selectedComponent || undefined}
tables={tables}
onUpdateProperty={updateComponentProperty}
onDeleteComponent={deleteComponent}
onCopyComponent={copyComponent}
currentTable={tables.length > 0 ? tables[0] : undefined}
currentTableName={selectedScreen?.tableName}
dragState={dragState}
onStyleChange={(style) => {
if (selectedComponent) {
updateComponentProperty(selectedComponent.id, "style", style);
}
}}
currentResolution={screenResolution}
onResolutionChange={handleResolutionChange}
allComponents={layout.components} // 🆕 플로우 위젯 감지용
/>
</div>
</div>
)}
{/* 스타일과 해상도 패널은 속성 패널의 탭으로 통합됨 */}
{/* 메인 캔버스 영역 (스크롤 가능한 컨테이너) - 좌우 최소화, 위아래 넉넉한 여유 */}
<div ref={canvasContainerRef} className="bg-muted relative flex-1 overflow-auto px-16 py-6">
{/* Pan 모드 안내 - 제거됨 */}

View File

@ -28,17 +28,17 @@ export default function StyleEditor({ style, onStyleChange, className }: StyleEd
};
return (
<div className={`space-y-6 p-6 ${className}`}>
<div className={`space-y-4 p-3 ${className}`}>
{/* 테두리 섹션 */}
<div className="space-y-3">
<div className="space-y-2">
<div className="flex items-center gap-2">
<Square className="text-primary h-4 w-4" />
<Square className="text-primary h-3.5 w-3.5" />
<h3 className="text-sm font-semibold"></h3>
</div>
<Separator className="my-2" />
<div className="space-y-3">
<div className="grid grid-cols-2 gap-3">
<div className="space-y-1.5">
<Separator className="my-1.5" />
<div className="space-y-2">
<div className="grid grid-cols-2 gap-2">
<div className="space-y-1">
<Label htmlFor="borderWidth" className="text-xs font-medium">
</Label>
@ -48,10 +48,11 @@ export default function StyleEditor({ style, onStyleChange, className }: StyleEd
placeholder="1px"
value={localStyle.borderWidth || ""}
onChange={(e) => handleStyleChange("borderWidth", e.target.value)}
className="h-8 text-xs"
className="h-6 w-full px-2 py-0 text-xs"
style={{ fontSize: "12px" }}
/>
</div>
<div className="space-y-1.5">
<div className="space-y-1">
<Label htmlFor="borderStyle" className="text-xs font-medium">
</Label>
@ -59,42 +60,52 @@ export default function StyleEditor({ style, onStyleChange, className }: StyleEd
value={localStyle.borderStyle || "solid"}
onValueChange={(value) => handleStyleChange("borderStyle", value)}
>
<SelectTrigger className="h-8 text-xs">
<SelectTrigger className="h-6 w-full px-2 py-0" style={{ fontSize: "12px" }}>
<SelectValue />
</SelectTrigger>
<SelectContent>
<SelectItem value="solid"></SelectItem>
<SelectItem value="dashed"></SelectItem>
<SelectItem value="dotted"></SelectItem>
<SelectItem value="none"></SelectItem>
<SelectItem value="solid" style={{ fontSize: "12px" }}>
</SelectItem>
<SelectItem value="dashed" style={{ fontSize: "12px" }}>
</SelectItem>
<SelectItem value="dotted" style={{ fontSize: "12px" }}>
</SelectItem>
<SelectItem value="none" style={{ fontSize: "12px" }}>
</SelectItem>
</SelectContent>
</Select>
</div>
</div>
<div className="grid grid-cols-2 gap-3">
<div className="space-y-1.5">
<div className="grid grid-cols-2 gap-2">
<div className="space-y-1">
<Label htmlFor="borderColor" className="text-xs font-medium">
</Label>
<div className="flex gap-2">
<div className="flex gap-1">
<Input
id="borderColor"
type="color"
value={localStyle.borderColor || "#000000"}
onChange={(e) => handleStyleChange("borderColor", e.target.value)}
className="h-8 w-14 p-1 text-xs"
className="h-6 w-12 p-1"
style={{ fontSize: "12px" }}
/>
<Input
type="text"
value={localStyle.borderColor || "#000000"}
onChange={(e) => handleStyleChange("borderColor", e.target.value)}
placeholder="#000000"
className="h-8 flex-1 text-xs"
className="h-6 flex-1 text-xs"
style={{ fontSize: "12px" }}
/>
</div>
</div>
<div className="space-y-1.5">
<div className="space-y-1">
<Label htmlFor="borderRadius" className="text-xs font-medium">
</Label>
@ -104,7 +115,8 @@ export default function StyleEditor({ style, onStyleChange, className }: StyleEd
placeholder="5px"
value={localStyle.borderRadius || ""}
onChange={(e) => handleStyleChange("borderRadius", e.target.value)}
className="h-8 text-xs"
className="h-6 w-full px-2 py-0 text-xs"
style={{ fontSize: "12px" }}
/>
</div>
</div>
@ -112,38 +124,40 @@ export default function StyleEditor({ style, onStyleChange, className }: StyleEd
</div>
{/* 배경 섹션 */}
<div className="space-y-3">
<div className="space-y-2">
<div className="flex items-center gap-2">
<Palette className="text-primary h-4 w-4" />
<Palette className="text-primary h-3.5 w-3.5" />
<h3 className="text-sm font-semibold"></h3>
</div>
<Separator className="my-2" />
<div className="space-y-3">
<div className="space-y-1.5">
<Separator className="my-1.5" />
<div className="space-y-2">
<div className="space-y-1">
<Label htmlFor="backgroundColor" className="text-xs font-medium">
</Label>
<div className="flex gap-2">
<div className="flex gap-1">
<Input
id="backgroundColor"
type="color"
value={localStyle.backgroundColor || "#ffffff"}
onChange={(e) => handleStyleChange("backgroundColor", e.target.value)}
className="h-8 w-14 p-1 text-xs"
className="h-6 w-12 p-1"
style={{ fontSize: "12px" }}
/>
<Input
type="text"
value={localStyle.backgroundColor || "#ffffff"}
onChange={(e) => handleStyleChange("backgroundColor", e.target.value)}
placeholder="#ffffff"
className="h-8 flex-1 text-xs"
className="h-6 flex-1 text-xs"
style={{ fontSize: "12px" }}
/>
</div>
</div>
<div className="space-y-1.5">
<div className="space-y-1">
<Label htmlFor="backgroundImage" className="text-xs font-medium">
</Label>
<Input
id="backgroundImage"
@ -151,43 +165,46 @@ export default function StyleEditor({ style, onStyleChange, className }: StyleEd
placeholder="url('image.jpg')"
value={localStyle.backgroundImage || ""}
onChange={(e) => handleStyleChange("backgroundImage", e.target.value)}
className="h-8 text-xs"
className="h-6 w-full px-2 py-0 text-xs"
style={{ fontSize: "12px" }}
/>
</div>
</div>
</div>
{/* 텍스트 섹션 */}
<div className="space-y-3">
<div className="space-y-2">
<div className="flex items-center gap-2">
<Type className="text-primary h-4 w-4" />
<Type className="text-primary h-3.5 w-3.5" />
<h3 className="text-sm font-semibold"></h3>
</div>
<Separator className="my-2" />
<div className="space-y-3">
<div className="grid grid-cols-2 gap-3">
<div className="space-y-1.5">
<Separator className="my-1.5" />
<div className="space-y-2">
<div className="grid grid-cols-2 gap-2">
<div className="space-y-1">
<Label htmlFor="color" className="text-xs font-medium">
</Label>
<div className="flex gap-2">
<div className="flex gap-1">
<Input
id="color"
type="color"
value={localStyle.color || "#000000"}
onChange={(e) => handleStyleChange("color", e.target.value)}
className="h-8 w-14 p-1 text-xs"
className="h-6 w-12 p-1"
style={{ fontSize: "12px" }}
/>
<Input
type="text"
value={localStyle.color || "#000000"}
onChange={(e) => handleStyleChange("color", e.target.value)}
placeholder="#000000"
className="h-8 flex-1 text-xs"
className="h-6 flex-1 text-xs"
style={{ fontSize: "12px" }}
/>
</div>
</div>
<div className="space-y-1.5">
<div className="space-y-1">
<Label htmlFor="fontSize" className="text-xs font-medium">
</Label>
@ -197,70 +214,71 @@ export default function StyleEditor({ style, onStyleChange, className }: StyleEd
placeholder="14px"
value={localStyle.fontSize || ""}
onChange={(e) => handleStyleChange("fontSize", e.target.value)}
className="h-8 text-xs"
className="h-6 w-full px-2 py-0 text-xs"
style={{ fontSize: "12px" }}
/>
</div>
</div>
<div className="grid grid-cols-2 gap-2">
<div className="max-w-[140px] space-y-0.5">
<Label htmlFor="fontWeight" className="text-[10px] font-medium">
<div className="space-y-1">
<Label htmlFor="fontWeight" className="text-xs font-medium">
</Label>
<Select
value={localStyle.fontWeight || "normal"}
onValueChange={(value) => handleStyleChange("fontWeight", value)}
>
<SelectTrigger className="h-6 w-full px-2 text-[10px]">
<SelectTrigger className="h-6 w-full px-2 py-0" style={{ fontSize: "12px" }}>
<SelectValue />
</SelectTrigger>
<SelectContent>
<SelectItem value="normal" className="text-[10px]">
<SelectItem value="normal" style={{ fontSize: "12px" }}>
</SelectItem>
<SelectItem value="bold" className="text-[10px]">
<SelectItem value="bold" style={{ fontSize: "12px" }}>
</SelectItem>
<SelectItem value="100" className="text-[10px]">
<SelectItem value="100" style={{ fontSize: "12px" }}>
100
</SelectItem>
<SelectItem value="400" className="text-[10px]">
<SelectItem value="400" style={{ fontSize: "12px" }}>
400
</SelectItem>
<SelectItem value="500" className="text-[10px]">
<SelectItem value="500" style={{ fontSize: "12px" }}>
500
</SelectItem>
<SelectItem value="600" className="text-[10px]">
<SelectItem value="600" style={{ fontSize: "12px" }}>
600
</SelectItem>
<SelectItem value="700" className="text-[10px]">
<SelectItem value="700" style={{ fontSize: "12px" }}>
700
</SelectItem>
</SelectContent>
</Select>
</div>
<div className="max-w-[140px] space-y-0.5">
<Label htmlFor="textAlign" className="text-[10px] font-medium">
<div className="space-y-1">
<Label htmlFor="textAlign" className="text-xs font-medium">
</Label>
<Select
value={localStyle.textAlign || "left"}
onValueChange={(value) => handleStyleChange("textAlign", value)}
>
<SelectTrigger className="h-6 w-full px-2 text-[10px]">
<SelectTrigger className="h-6 w-full px-2 py-0" style={{ fontSize: "12px" }}>
<SelectValue />
</SelectTrigger>
<SelectContent>
<SelectItem value="left" className="text-[10px]">
<SelectItem value="left" style={{ fontSize: "12px" }}>
</SelectItem>
<SelectItem value="center" className="text-[10px]">
<SelectItem value="center" style={{ fontSize: "12px" }}>
</SelectItem>
<SelectItem value="right" className="text-[10px]">
<SelectItem value="right" style={{ fontSize: "12px" }}>
</SelectItem>
<SelectItem value="justify" className="text-[10px]">
<SelectItem value="justify" style={{ fontSize: "12px" }}>
</SelectItem>
</SelectContent>

View File

@ -298,7 +298,7 @@ export const ButtonConfigPanel: React.FC<ButtonConfigPanelProps> = ({
variant="outline"
role="combobox"
aria-expanded={modalScreenOpen}
className="h-10 w-full justify-between"
className="h-6 w-full px-2 py-0 justify-between" style={{ fontSize: "12px" }}
disabled={screensLoading}
>
{config.action?.targetScreenId
@ -372,7 +372,7 @@ export const ButtonConfigPanel: React.FC<ButtonConfigPanelProps> = ({
variant="outline"
role="combobox"
aria-expanded={modalScreenOpen}
className="h-10 w-full justify-between"
className="h-6 w-full px-2 py-0 justify-between" style={{ fontSize: "12px" }}
disabled={screensLoading}
>
{config.action?.targetScreenId
@ -526,7 +526,7 @@ export const ButtonConfigPanel: React.FC<ButtonConfigPanelProps> = ({
variant="outline"
role="combobox"
aria-expanded={displayColumnOpen}
className="mt-2 h-8 w-full justify-between text-xs"
className="mt-2 h-8 w-full justify-between text-xs" style={{ fontSize: "12px" }}
disabled={columnsLoading || tableColumns.length === 0}
>
{columnsLoading
@ -541,9 +541,9 @@ export const ButtonConfigPanel: React.FC<ButtonConfigPanelProps> = ({
</PopoverTrigger>
<PopoverContent className="p-0" style={{ width: "var(--radix-popover-trigger-width)" }} align="start">
<Command>
<CommandInput placeholder="컬럼 검색..." className="text-sm" />
<CommandInput placeholder="컬럼 검색..." className="text-xs" style={{ fontSize: "12px" }} />
<CommandList>
<CommandEmpty className="text-sm"> .</CommandEmpty>
<CommandEmpty className="text-xs" style={{ fontSize: "12px" }}> .</CommandEmpty>
<CommandGroup>
{tableColumns.map((column) => (
<CommandItem
@ -553,7 +553,7 @@ export const ButtonConfigPanel: React.FC<ButtonConfigPanelProps> = ({
onUpdateProperty("componentConfig.action.historyDisplayColumn", currentValue);
setDisplayColumnOpen(false);
}}
className="text-sm"
className="text-xs" style={{ fontSize: "12px" }}
>
<Check
className={cn(
@ -586,7 +586,7 @@ export const ButtonConfigPanel: React.FC<ButtonConfigPanelProps> = ({
variant="outline"
role="combobox"
aria-expanded={navScreenOpen}
className="h-10 w-full justify-between"
className="h-6 w-full px-2 py-0 justify-between" style={{ fontSize: "12px" }}
disabled={screensLoading}
>
{config.action?.targetScreenId
@ -659,7 +659,7 @@ export const ButtonConfigPanel: React.FC<ButtonConfigPanelProps> = ({
setLocalInputs((prev) => ({ ...prev, targetUrl: newValue }));
onUpdateProperty("componentConfig.action.targetUrl", newValue);
}}
className="h-8 text-xs"
className="h-6 w-full px-2 py-0 text-xs" style={{ fontSize: "12px" }}
/>
<p className="mt-1 text-xs text-gray-500">URL을 </p>
</div>

View File

@ -117,7 +117,7 @@ export const CheckboxConfigPanel: React.FC<WebTypeConfigPanelProps> = ({
return (
<Card>
<CardHeader>
<CardTitle className="flex items-center gap-2 text-sm">
<CardTitle className="flex items-center gap-2 text-xs" style={{ fontSize: "12px" }}>
<CheckSquare className="h-4 w-4" />
</CardTitle>
@ -173,7 +173,7 @@ export const CheckboxConfigPanel: React.FC<WebTypeConfigPanelProps> = ({
value={localConfig.label || ""}
onChange={(e) => updateConfig("label", e.target.value)}
placeholder="체크박스 라벨"
className="text-xs"
className="text-xs" style={{ fontSize: "12px" }}
/>
</div>
@ -187,7 +187,7 @@ export const CheckboxConfigPanel: React.FC<WebTypeConfigPanelProps> = ({
value={localConfig.checkedValue || ""}
onChange={(e) => updateConfig("checkedValue", e.target.value)}
placeholder="Y"
className="text-xs"
className="text-xs" style={{ fontSize: "12px" }}
/>
</div>
<div className="space-y-2">
@ -199,7 +199,7 @@ export const CheckboxConfigPanel: React.FC<WebTypeConfigPanelProps> = ({
value={localConfig.uncheckedValue || ""}
onChange={(e) => updateConfig("uncheckedValue", e.target.value)}
placeholder="N"
className="text-xs"
className="text-xs" style={{ fontSize: "12px" }}
/>
</div>
</div>
@ -232,7 +232,7 @@ export const CheckboxConfigPanel: React.FC<WebTypeConfigPanelProps> = ({
value={localConfig.groupLabel || ""}
onChange={(e) => updateConfig("groupLabel", e.target.value)}
placeholder="체크박스 그룹 제목"
className="text-xs"
className="text-xs" style={{ fontSize: "12px" }}
/>
</div>
@ -244,19 +244,19 @@ export const CheckboxConfigPanel: React.FC<WebTypeConfigPanelProps> = ({
value={newOptionLabel}
onChange={(e) => setNewOptionLabel(e.target.value)}
placeholder="라벨"
className="flex-1 text-xs"
className="flex-1 text-xs" style={{ fontSize: "12px" }}
/>
<Input
value={newOptionValue}
onChange={(e) => setNewOptionValue(e.target.value)}
placeholder="값"
className="flex-1 text-xs"
className="flex-1 text-xs" style={{ fontSize: "12px" }}
/>
<Button
size="sm"
onClick={addOption}
disabled={!newOptionLabel.trim() || !newOptionValue.trim()}
className="text-xs"
className="text-xs" style={{ fontSize: "12px" }}
>
<Plus className="h-3 w-3" />
</Button>
@ -277,13 +277,13 @@ export const CheckboxConfigPanel: React.FC<WebTypeConfigPanelProps> = ({
value={option.label}
onChange={(e) => updateOption(index, "label", e.target.value)}
placeholder="라벨"
className="flex-1 text-xs"
className="flex-1 text-xs" style={{ fontSize: "12px" }}
/>
<Input
value={option.value}
onChange={(e) => updateOption(index, "value", e.target.value)}
placeholder="값"
className="flex-1 text-xs"
className="flex-1 text-xs" style={{ fontSize: "12px" }}
/>
<Switch
checked={!option.disabled}
@ -361,7 +361,7 @@ export const CheckboxConfigPanel: React.FC<WebTypeConfigPanelProps> = ({
disabled={localConfig.readonly}
required={localConfig.required}
defaultChecked={localConfig.defaultChecked}
className="text-xs"
className="text-xs" style={{ fontSize: "12px" }}
/>
<Label htmlFor="preview-single" className="text-xs">
{localConfig.label || "체크박스 라벨"}
@ -380,7 +380,7 @@ export const CheckboxConfigPanel: React.FC<WebTypeConfigPanelProps> = ({
disabled={localConfig.readonly || option.disabled}
required={localConfig.required && index === 0} // 첫 번째에만 required 표시
defaultChecked={option.checked}
className="text-xs"
className="text-xs" style={{ fontSize: "12px" }}
/>
<Label htmlFor={`preview-group-${index}`} className="text-xs">
{option.label}

View File

@ -106,7 +106,7 @@ export const CodeConfigPanel: React.FC<WebTypeConfigPanelProps> = ({
return (
<Card>
<CardHeader>
<CardTitle className="flex items-center gap-2 text-sm">
<CardTitle className="flex items-center gap-2 text-xs" style={{ fontSize: "12px" }}>
<Code className="h-4 w-4" />
</CardTitle>
@ -174,7 +174,7 @@ export const CodeConfigPanel: React.FC<WebTypeConfigPanelProps> = ({
step={50}
value={localConfig.height || 300}
onChange={(e) => updateConfig("height", parseInt(e.target.value))}
className="text-xs"
className="text-xs" style={{ fontSize: "12px" }}
/>
<div className="text-muted-foreground flex justify-between text-xs">
<span>150px</span>
@ -199,7 +199,7 @@ export const CodeConfigPanel: React.FC<WebTypeConfigPanelProps> = ({
onChange={(e) => updateConfig("fontSize", parseInt(e.target.value))}
min={10}
max={24}
className="text-xs"
className="text-xs" style={{ fontSize: "12px" }}
/>
</div>
@ -214,7 +214,7 @@ export const CodeConfigPanel: React.FC<WebTypeConfigPanelProps> = ({
onChange={(e) => updateConfig("tabSize", parseInt(e.target.value))}
min={1}
max={8}
className="text-xs"
className="text-xs" style={{ fontSize: "12px" }}
/>
</div>
</div>
@ -308,7 +308,7 @@ export const CodeConfigPanel: React.FC<WebTypeConfigPanelProps> = ({
value={localConfig.placeholder || ""}
onChange={(e) => updateConfig("placeholder", e.target.value)}
placeholder="코드를 입력하세요..."
className="text-xs"
className="text-xs" style={{ fontSize: "12px" }}
/>
</div>
@ -330,7 +330,7 @@ export const CodeConfigPanel: React.FC<WebTypeConfigPanelProps> = ({
value={localConfig.defaultValue || ""}
onChange={(e) => updateConfig("defaultValue", e.target.value)}
placeholder="기본 코드 내용"
className="font-mono text-xs"
className="font-mono text-xs" style={{ fontSize: "12px" }}
rows={4}
/>
</div>

View File

@ -75,7 +75,7 @@ export const DateConfigPanel: React.FC<WebTypeConfigPanelProps> = ({
return (
<Card>
<CardHeader>
<CardTitle className="flex items-center gap-2 text-sm">
<CardTitle className="flex items-center gap-2 text-xs" style={{ fontSize: "12px" }}>
<Calendar className="h-4 w-4" />
</CardTitle>
@ -95,7 +95,7 @@ export const DateConfigPanel: React.FC<WebTypeConfigPanelProps> = ({
value={localConfig.placeholder || ""}
onChange={(e) => updateConfig("placeholder", e.target.value)}
placeholder="날짜를 선택하세요"
className="text-xs"
className="text-xs" style={{ fontSize: "12px" }}
/>
</div>
@ -149,7 +149,7 @@ export const DateConfigPanel: React.FC<WebTypeConfigPanelProps> = ({
type={localConfig.showTime ? "datetime-local" : "date"}
value={localConfig.minDate || ""}
onChange={(e) => updateConfig("minDate", e.target.value)}
className="flex-1 text-xs"
className="flex-1 text-xs" style={{ fontSize: "12px" }}
/>
<Button size="sm" variant="outline" onClick={() => setCurrentDate("minDate")} className="text-xs">
@ -167,7 +167,7 @@ export const DateConfigPanel: React.FC<WebTypeConfigPanelProps> = ({
type={localConfig.showTime ? "datetime-local" : "date"}
value={localConfig.maxDate || ""}
onChange={(e) => updateConfig("maxDate", e.target.value)}
className="flex-1 text-xs"
className="flex-1 text-xs" style={{ fontSize: "12px" }}
/>
<Button size="sm" variant="outline" onClick={() => setCurrentDate("maxDate")} className="text-xs">
@ -190,7 +190,7 @@ export const DateConfigPanel: React.FC<WebTypeConfigPanelProps> = ({
type={localConfig.showTime ? "datetime-local" : "date"}
value={localConfig.defaultValue || ""}
onChange={(e) => updateConfig("defaultValue", e.target.value)}
className="flex-1 text-xs"
className="flex-1 text-xs" style={{ fontSize: "12px" }}
/>
<Button size="sm" variant="outline" onClick={() => setCurrentDate("defaultValue")} className="text-xs">
@ -245,7 +245,7 @@ export const DateConfigPanel: React.FC<WebTypeConfigPanelProps> = ({
min={localConfig.minDate}
max={localConfig.maxDate}
defaultValue={localConfig.defaultValue}
className="text-xs"
className="text-xs" style={{ fontSize: "12px" }}
/>
<div className="text-muted-foreground mt-2 text-xs">
: {localConfig.format}

View File

@ -163,7 +163,7 @@ export const EntityConfigPanel: React.FC<WebTypeConfigPanelProps> = ({
return (
<Card>
<CardHeader>
<CardTitle className="flex items-center gap-2 text-sm">
<CardTitle className="flex items-center gap-2 text-xs" style={{ fontSize: "12px" }}>
<Database className="h-4 w-4" />
</CardTitle>
@ -183,7 +183,7 @@ export const EntityConfigPanel: React.FC<WebTypeConfigPanelProps> = ({
value={localConfig.entityType || ""}
onChange={(e) => updateConfig("entityType", e.target.value)}
placeholder="user, product, department..."
className="text-xs"
className="text-xs" style={{ fontSize: "12px" }}
/>
</div>
@ -196,7 +196,7 @@ export const EntityConfigPanel: React.FC<WebTypeConfigPanelProps> = ({
size="sm"
variant="outline"
onClick={() => applyEntityType(entity.value)}
className="text-xs"
className="text-xs" style={{ fontSize: "12px" }}
>
{entity.label}
</Button>
@ -213,7 +213,7 @@ export const EntityConfigPanel: React.FC<WebTypeConfigPanelProps> = ({
value={localConfig.apiEndpoint || ""}
onChange={(e) => updateConfig("apiEndpoint", e.target.value)}
placeholder="/api/entities/user"
className="text-xs"
className="text-xs" style={{ fontSize: "12px" }}
/>
</div>
</div>
@ -232,7 +232,7 @@ export const EntityConfigPanel: React.FC<WebTypeConfigPanelProps> = ({
value={localConfig.valueField || ""}
onChange={(e) => updateConfig("valueField", e.target.value)}
placeholder="id"
className="text-xs"
className="text-xs" style={{ fontSize: "12px" }}
/>
</div>
@ -245,7 +245,7 @@ export const EntityConfigPanel: React.FC<WebTypeConfigPanelProps> = ({
value={localConfig.labelField || ""}
onChange={(e) => updateConfig("labelField", e.target.value)}
placeholder="name"
className="text-xs"
className="text-xs" style={{ fontSize: "12px" }}
/>
</div>
</div>
@ -263,13 +263,13 @@ export const EntityConfigPanel: React.FC<WebTypeConfigPanelProps> = ({
value={newFieldName}
onChange={(e) => setNewFieldName(e.target.value)}
placeholder="필드명"
className="flex-1 text-xs"
className="flex-1 text-xs" style={{ fontSize: "12px" }}
/>
<Input
value={newFieldLabel}
onChange={(e) => setNewFieldLabel(e.target.value)}
placeholder="라벨"
className="flex-1 text-xs"
className="flex-1 text-xs" style={{ fontSize: "12px" }}
/>
<Select value={newFieldType} onValueChange={setNewFieldType}>
<SelectTrigger className="w-24 text-xs">
@ -287,7 +287,7 @@ export const EntityConfigPanel: React.FC<WebTypeConfigPanelProps> = ({
size="sm"
onClick={addDisplayField}
disabled={!newFieldName.trim() || !newFieldLabel.trim()}
className="text-xs"
className="text-xs" style={{ fontSize: "12px" }}
>
<Plus className="h-3 w-3" />
</Button>
@ -308,13 +308,13 @@ export const EntityConfigPanel: React.FC<WebTypeConfigPanelProps> = ({
value={field.name}
onChange={(e) => updateDisplayField(index, "name", e.target.value)}
placeholder="필드명"
className="flex-1 text-xs"
className="flex-1 text-xs" style={{ fontSize: "12px" }}
/>
<Input
value={field.label}
onChange={(e) => updateDisplayField(index, "label", e.target.value)}
placeholder="라벨"
className="flex-1 text-xs"
className="flex-1 text-xs" style={{ fontSize: "12px" }}
/>
<Select value={field.type} onValueChange={(value) => updateDisplayField(index, "type", value)}>
<SelectTrigger className="w-24 text-xs">
@ -332,7 +332,7 @@ export const EntityConfigPanel: React.FC<WebTypeConfigPanelProps> = ({
size="sm"
variant={localConfig.searchFields.includes(field.name) ? "default" : "outline"}
onClick={() => toggleSearchField(field.name)}
className="p-1 text-xs"
className="p-1 text-xs" style={{ fontSize: "12px" }}
title={localConfig.searchFields.includes(field.name) ? "검색 필드에서 제거" : "검색 필드로 추가"}
>
<Search className="h-3 w-3" />
@ -341,7 +341,7 @@ export const EntityConfigPanel: React.FC<WebTypeConfigPanelProps> = ({
size="sm"
variant="destructive"
onClick={() => removeDisplayField(index)}
className="p-1 text-xs"
className="p-1 text-xs" style={{ fontSize: "12px" }}
>
<Trash2 className="h-3 w-3" />
</Button>
@ -364,7 +364,7 @@ export const EntityConfigPanel: React.FC<WebTypeConfigPanelProps> = ({
value={localConfig.placeholder || ""}
onChange={(e) => updateConfig("placeholder", e.target.value)}
placeholder="엔티티를 선택하세요"
className="text-xs"
className="text-xs" style={{ fontSize: "12px" }}
/>
</div>
@ -377,7 +377,7 @@ export const EntityConfigPanel: React.FC<WebTypeConfigPanelProps> = ({
value={localConfig.emptyMessage || ""}
onChange={(e) => updateConfig("emptyMessage", e.target.value)}
placeholder="검색 결과가 없습니다"
className="text-xs"
className="text-xs" style={{ fontSize: "12px" }}
/>
</div>
@ -393,7 +393,7 @@ export const EntityConfigPanel: React.FC<WebTypeConfigPanelProps> = ({
onChange={(e) => updateConfig("minSearchLength", parseInt(e.target.value))}
min={0}
max={10}
className="text-xs"
className="text-xs" style={{ fontSize: "12px" }}
/>
</div>
@ -408,7 +408,7 @@ export const EntityConfigPanel: React.FC<WebTypeConfigPanelProps> = ({
onChange={(e) => updateConfig("pageSize", parseInt(e.target.value))}
min={5}
max={100}
className="text-xs"
className="text-xs" style={{ fontSize: "12px" }}
/>
</div>
</div>
@ -462,7 +462,7 @@ export const EntityConfigPanel: React.FC<WebTypeConfigPanelProps> = ({
}
}}
placeholder='{"status": "active", "department": "IT"}'
className="font-mono text-xs"
className="font-mono text-xs" style={{ fontSize: "12px" }}
rows={3}
/>
<p className="text-muted-foreground text-xs">API JSON .</p>

View File

@ -113,7 +113,7 @@ export const FileConfigPanel: React.FC<WebTypeConfigPanelProps> = ({
return (
<Card>
<CardHeader>
<CardTitle className="flex items-center gap-2 text-sm">
<CardTitle className="flex items-center gap-2 text-xs" style={{ fontSize: "12px" }}>
<Upload className="h-4 w-4" />
</CardTitle>
@ -133,7 +133,7 @@ export const FileConfigPanel: React.FC<WebTypeConfigPanelProps> = ({
value={localConfig.uploadText || ""}
onChange={(e) => updateConfig("uploadText", e.target.value)}
placeholder="파일을 선택하거나 여기에 드래그하세요"
className="text-xs"
className="text-xs" style={{ fontSize: "12px" }}
/>
</div>
@ -146,7 +146,7 @@ export const FileConfigPanel: React.FC<WebTypeConfigPanelProps> = ({
value={localConfig.browseText || ""}
onChange={(e) => updateConfig("browseText", e.target.value)}
placeholder="파일 선택"
className="text-xs"
className="text-xs" style={{ fontSize: "12px" }}
/>
</div>
@ -196,7 +196,7 @@ export const FileConfigPanel: React.FC<WebTypeConfigPanelProps> = ({
min={0.1}
max={1024}
step={0.1}
className="flex-1 text-xs"
className="flex-1 text-xs" style={{ fontSize: "12px" }}
/>
<span className="text-muted-foreground text-xs">MB</span>
</div>
@ -214,7 +214,7 @@ export const FileConfigPanel: React.FC<WebTypeConfigPanelProps> = ({
onChange={(e) => updateConfig("maxFiles", parseInt(e.target.value))}
min={1}
max={100}
className="text-xs"
className="text-xs" style={{ fontSize: "12px" }}
/>
</div>
)}
@ -257,7 +257,7 @@ export const FileConfigPanel: React.FC<WebTypeConfigPanelProps> = ({
value={newFileType}
onChange={(e) => setNewFileType(e.target.value)}
placeholder=".pdf 또는 pdf"
className="flex-1 text-xs"
className="flex-1 text-xs" style={{ fontSize: "12px" }}
/>
<Button size="sm" onClick={addFileType} disabled={!newFileType.trim()} className="text-xs">

View File

@ -269,7 +269,7 @@ export const FlowVisibilityConfigPanel: React.FC<FlowVisibilityConfigPanelProps>
setTimeout(() => applyConfig(), 0);
}}
>
<SelectTrigger className="h-8 text-xs sm:h-10 sm:text-sm">
<SelectTrigger className="h-6 text-xs sm:h-10 sm:text-xs" style={{ fontSize: "12px" }}>
<SelectValue placeholder="플로우 위젯 선택" />
</SelectTrigger>
<SelectContent>
@ -344,7 +344,7 @@ export const FlowVisibilityConfigPanel: React.FC<FlowVisibilityConfigPanelProps>
checked={isChecked}
onCheckedChange={() => toggleStep(step.id)}
/>
<Label htmlFor={`step-${step.id}`} className="flex flex-1 items-center gap-2 text-sm">
<Label htmlFor={`step-${step.id}`} className="flex flex-1 items-center gap-2 text-xs" style={{ fontSize: "12px" }}>
<Badge variant="outline" className="text-xs">
Step {step.stepOrder}
</Badge>
@ -403,7 +403,7 @@ export const FlowVisibilityConfigPanel: React.FC<FlowVisibilityConfigPanelProps>
value={groupId}
onChange={(e) => setGroupId(e.target.value)}
placeholder="group-1"
className="h-8 text-xs sm:h-9 sm:text-sm"
className="h-6 text-xs sm:h-9 sm:text-xs" style={{ fontSize: "12px" }}
/>
<p className="text-muted-foreground text-[10px]">
ID를
@ -453,7 +453,7 @@ export const FlowVisibilityConfigPanel: React.FC<FlowVisibilityConfigPanelProps>
setGroupGap(Number(e.target.value));
setTimeout(() => applyConfig(), 0);
}}
className="h-8 text-xs sm:h-9 sm:text-sm"
className="h-6 text-xs sm:h-9 sm:text-xs" style={{ fontSize: "12px" }}
/>
<Badge variant="outline" className="text-xs">
{groupGap}px
@ -473,7 +473,7 @@ export const FlowVisibilityConfigPanel: React.FC<FlowVisibilityConfigPanelProps>
setTimeout(() => applyConfig(), 0);
}}
>
<SelectTrigger id="group-align" className="h-8 text-xs sm:h-9 sm:text-sm">
<SelectTrigger id="group-align" className="h-6 text-xs sm:h-9 sm:text-xs" style={{ fontSize: "12px" }}>
<SelectValue />
</SelectTrigger>
<SelectContent>

View File

@ -54,7 +54,7 @@ export function FlowWidgetConfigPanel({ config = {}, onChange }: FlowWidgetConfi
{loading ? (
<div className="flex items-center gap-2 rounded-md border px-3 py-2">
<Loader2 className="h-4 w-4 animate-spin" />
<span className="text-muted-foreground text-sm"> ...</span>
<span className="text-muted-foreground text-xs" style={{ fontSize: "12px" }}> ...</span>
</div>
) : (
<>

View File

@ -56,7 +56,7 @@ export const NumberConfigPanel: React.FC<WebTypeConfigPanelProps> = ({
return (
<Card>
<CardHeader>
<CardTitle className="flex items-center gap-2 text-sm"> </CardTitle>
<CardTitle className="flex items-center gap-2 text-xs" style={{ fontSize: "12px" }}> </CardTitle>
<CardDescription className="text-xs"> .</CardDescription>
</CardHeader>
<CardContent className="space-y-4">
@ -73,7 +73,7 @@ export const NumberConfigPanel: React.FC<WebTypeConfigPanelProps> = ({
value={localConfig.placeholder || ""}
onChange={(e) => updateConfig("placeholder", e.target.value)}
placeholder="숫자를 입력하세요"
className="text-xs"
className="text-xs" style={{ fontSize: "12px" }}
/>
</div>
@ -88,7 +88,7 @@ export const NumberConfigPanel: React.FC<WebTypeConfigPanelProps> = ({
value={localConfig.min ?? ""}
onChange={(e) => updateConfig("min", e.target.value ? parseFloat(e.target.value) : undefined)}
placeholder="0"
className="text-xs"
className="text-xs" style={{ fontSize: "12px" }}
/>
</div>
<div className="space-y-2">
@ -101,7 +101,7 @@ export const NumberConfigPanel: React.FC<WebTypeConfigPanelProps> = ({
value={localConfig.max ?? ""}
onChange={(e) => updateConfig("max", e.target.value ? parseFloat(e.target.value) : undefined)}
placeholder="100"
className="text-xs"
className="text-xs" style={{ fontSize: "12px" }}
/>
</div>
</div>
@ -118,7 +118,7 @@ export const NumberConfigPanel: React.FC<WebTypeConfigPanelProps> = ({
placeholder="1"
min="0"
step="0.01"
className="text-xs"
className="text-xs" style={{ fontSize: "12px" }}
/>
<p className="text-muted-foreground text-xs">/ </p>
</div>
@ -158,7 +158,7 @@ export const NumberConfigPanel: React.FC<WebTypeConfigPanelProps> = ({
placeholder="2"
min="0"
max="10"
className="text-xs"
className="text-xs" style={{ fontSize: "12px" }}
/>
</div>
)}
@ -223,7 +223,7 @@ export const NumberConfigPanel: React.FC<WebTypeConfigPanelProps> = ({
min={localConfig.min}
max={localConfig.max}
step={localConfig.step}
className="text-xs"
className="text-xs" style={{ fontSize: "12px" }}
/>
<div className="text-muted-foreground mt-2 text-xs">
{localConfig.format === "currency" && "통화 형식으로 표시됩니다."}

View File

@ -168,7 +168,7 @@ export const RadioConfigPanel: React.FC<WebTypeConfigPanelProps> = ({
return (
<Card>
<CardHeader>
<CardTitle className="flex items-center gap-2 text-sm">
<CardTitle className="flex items-center gap-2 text-xs" style={{ fontSize: "12px" }}>
<Radio className="h-4 w-4" />
</CardTitle>
@ -188,7 +188,7 @@ export const RadioConfigPanel: React.FC<WebTypeConfigPanelProps> = ({
value={localConfig.groupLabel || ""}
onChange={(e) => updateConfig("groupLabel", e.target.value)}
placeholder="라디오버튼 그룹 제목"
className="text-xs"
className="text-xs" style={{ fontSize: "12px" }}
/>
</div>
@ -201,7 +201,7 @@ export const RadioConfigPanel: React.FC<WebTypeConfigPanelProps> = ({
value={localConfig.groupName || ""}
onChange={(e) => updateConfig("groupName", e.target.value)}
placeholder="자동 생성 (필드명 기반)"
className="text-xs"
className="text-xs" style={{ fontSize: "12px" }}
/>
<p className="text-muted-foreground text-xs"> .</p>
</div>
@ -252,19 +252,19 @@ export const RadioConfigPanel: React.FC<WebTypeConfigPanelProps> = ({
value={newOptionLabel}
onChange={(e) => setNewOptionLabel(e.target.value)}
placeholder="라벨"
className="flex-1 text-xs"
className="flex-1 text-xs" style={{ fontSize: "12px" }}
/>
<Input
value={newOptionValue}
onChange={(e) => setNewOptionValue(e.target.value)}
placeholder="값"
className="flex-1 text-xs"
className="flex-1 text-xs" style={{ fontSize: "12px" }}
/>
<Button
size="sm"
onClick={addOption}
disabled={!newOptionLabel.trim() || !newOptionValue.trim()}
className="text-xs"
className="text-xs" style={{ fontSize: "12px" }}
>
<Plus className="h-3 w-3" />
</Button>
@ -278,7 +278,7 @@ export const RadioConfigPanel: React.FC<WebTypeConfigPanelProps> = ({
value={bulkOptions}
onChange={(e) => setBulkOptions(e.target.value)}
placeholder="한 줄당 하나씩 입력하세요.&#10;라벨만 입력하면 값과 동일하게 설정됩니다.&#10;라벨|값 형식으로 입력하면 별도 값을 설정할 수 있습니다.&#10;&#10;예시:&#10;서울&#10;부산&#10;대구시|daegu"
className="h-20 text-xs"
className="h-20 text-xs" style={{ fontSize: "12px" }}
/>
<Button size="sm" onClick={addBulkOptions} disabled={!bulkOptions.trim()} className="text-xs">
@ -295,13 +295,13 @@ export const RadioConfigPanel: React.FC<WebTypeConfigPanelProps> = ({
value={option.label}
onChange={(e) => updateOption(index, "label", e.target.value)}
placeholder="라벨"
className="flex-1 text-xs"
className="flex-1 text-xs" style={{ fontSize: "12px" }}
/>
<Input
value={option.value}
onChange={(e) => updateOption(index, "value", e.target.value)}
placeholder="값"
className="flex-1 text-xs"
className="flex-1 text-xs" style={{ fontSize: "12px" }}
/>
<Switch
checked={!option.disabled}
@ -328,7 +328,7 @@ export const RadioConfigPanel: React.FC<WebTypeConfigPanelProps> = ({
id="defaultValue"
value={localConfig.defaultValue || ""}
onChange={(e) => updateConfig("defaultValue", e.target.value)}
className="w-full rounded-md border px-3 py-1 text-xs"
className="w-full rounded-md border px-3 py-1 text-xs" style={{ fontSize: "12px" }}
>
<option value=""> </option>
{localConfig.options.map((option, index) => (
@ -390,7 +390,7 @@ export const RadioConfigPanel: React.FC<WebTypeConfigPanelProps> = ({
disabled={localConfig.readonly || option.disabled}
required={localConfig.required && index === 0} // 첫 번째에만 required 표시
defaultChecked={localConfig.defaultValue === option.value}
className="text-xs"
className="text-xs" style={{ fontSize: "12px" }}
/>
<Label htmlFor={`preview-radio-${index}`} className="text-xs">
{option.label}

View File

@ -153,7 +153,7 @@ export const SelectConfigPanel: React.FC<WebTypeConfigPanelProps> = ({
return (
<Card>
<CardHeader>
<CardTitle className="flex items-center gap-2 text-sm">
<CardTitle className="flex items-center gap-2 text-xs" style={{ fontSize: "12px" }}>
<List className="h-4 w-4" />
</CardTitle>
@ -173,7 +173,7 @@ export const SelectConfigPanel: React.FC<WebTypeConfigPanelProps> = ({
value={localConfig.placeholder || ""}
onChange={(e) => updateConfig("placeholder", e.target.value)}
placeholder="선택하세요"
className="text-xs"
className="text-xs" style={{ fontSize: "12px" }}
/>
</div>
@ -186,7 +186,7 @@ export const SelectConfigPanel: React.FC<WebTypeConfigPanelProps> = ({
value={localConfig.emptyMessage || ""}
onChange={(e) => updateConfig("emptyMessage", e.target.value)}
placeholder="선택 가능한 옵션이 없습니다"
className="text-xs"
className="text-xs" style={{ fontSize: "12px" }}
/>
</div>
@ -247,19 +247,19 @@ export const SelectConfigPanel: React.FC<WebTypeConfigPanelProps> = ({
value={newOptionLabel}
onChange={(e) => setNewOptionLabel(e.target.value)}
placeholder="라벨"
className="flex-1 text-xs"
className="flex-1 text-xs" style={{ fontSize: "12px" }}
/>
<Input
value={newOptionValue}
onChange={(e) => setNewOptionValue(e.target.value)}
placeholder="값"
className="flex-1 text-xs"
className="flex-1 text-xs" style={{ fontSize: "12px" }}
/>
<Button
size="sm"
onClick={addOption}
disabled={!newOptionLabel.trim() || !newOptionValue.trim()}
className="text-xs"
className="text-xs" style={{ fontSize: "12px" }}
>
<Plus className="h-3 w-3" />
</Button>
@ -273,7 +273,7 @@ export const SelectConfigPanel: React.FC<WebTypeConfigPanelProps> = ({
value={bulkOptions}
onChange={(e) => setBulkOptions(e.target.value)}
placeholder="한 줄당 하나씩 입력하세요.&#10;라벨만 입력하면 값과 동일하게 설정됩니다.&#10;라벨|값 형식으로 입력하면 별도 값을 설정할 수 있습니다.&#10;&#10;예시:&#10;서울&#10;부산&#10;대구시|daegu"
className="h-20 text-xs"
className="h-20 text-xs" style={{ fontSize: "12px" }}
/>
<Button size="sm" onClick={addBulkOptions} disabled={!bulkOptions.trim()} className="text-xs">
@ -290,13 +290,13 @@ export const SelectConfigPanel: React.FC<WebTypeConfigPanelProps> = ({
value={option.label}
onChange={(e) => updateOption(index, "label", e.target.value)}
placeholder="라벨"
className="flex-1 text-xs"
className="flex-1 text-xs" style={{ fontSize: "12px" }}
/>
<Input
value={option.value}
onChange={(e) => updateOption(index, "value", e.target.value)}
placeholder="값"
className="flex-1 text-xs"
className="flex-1 text-xs" style={{ fontSize: "12px" }}
/>
<Switch
checked={!option.disabled}
@ -323,7 +323,7 @@ export const SelectConfigPanel: React.FC<WebTypeConfigPanelProps> = ({
id="defaultValue"
value={localConfig.defaultValue || ""}
onChange={(e) => updateConfig("defaultValue", e.target.value)}
className="w-full rounded-md border px-3 py-1 text-xs"
className="w-full rounded-md border px-3 py-1 text-xs" style={{ fontSize: "12px" }}
>
<option value=""> </option>
{localConfig.options.map((option, index) => (
@ -376,7 +376,7 @@ export const SelectConfigPanel: React.FC<WebTypeConfigPanelProps> = ({
disabled={localConfig.readonly}
required={localConfig.required}
multiple={localConfig.multiple}
className="w-full rounded-md border px-3 py-1 text-xs"
className="w-full rounded-md border px-3 py-1 text-xs" style={{ fontSize: "12px" }}
defaultValue={localConfig.defaultValue}
>
<option value="" disabled>

View File

@ -55,7 +55,7 @@ export const TextConfigPanel: React.FC<WebTypeConfigPanelProps> = ({
return (
<Card>
<CardHeader>
<CardTitle className="flex items-center gap-2 text-sm"> </CardTitle>
<CardTitle className="flex items-center gap-2 text-xs" style={{ fontSize: "12px" }}> </CardTitle>
<CardDescription className="text-xs"> .</CardDescription>
</CardHeader>
<CardContent className="space-y-4">
@ -72,7 +72,7 @@ export const TextConfigPanel: React.FC<WebTypeConfigPanelProps> = ({
value={localConfig.placeholder || ""}
onChange={(e) => updateConfig("placeholder", e.target.value)}
placeholder="입력 안내 텍스트"
className="text-xs"
className="text-xs" style={{ fontSize: "12px" }}
/>
</div>
@ -88,7 +88,7 @@ export const TextConfigPanel: React.FC<WebTypeConfigPanelProps> = ({
onChange={(e) => updateConfig("minLength", e.target.value ? parseInt(e.target.value) : undefined)}
placeholder="0"
min="0"
className="text-xs"
className="text-xs" style={{ fontSize: "12px" }}
/>
</div>
<div className="space-y-2">
@ -102,7 +102,7 @@ export const TextConfigPanel: React.FC<WebTypeConfigPanelProps> = ({
onChange={(e) => updateConfig("maxLength", e.target.value ? parseInt(e.target.value) : undefined)}
placeholder="100"
min="1"
className="text-xs"
className="text-xs" style={{ fontSize: "12px" }}
/>
</div>
</div>
@ -141,7 +141,7 @@ export const TextConfigPanel: React.FC<WebTypeConfigPanelProps> = ({
value={localConfig.pattern || ""}
onChange={(e) => updateConfig("pattern", e.target.value)}
placeholder="예: [A-Za-z0-9]+"
className="font-mono text-xs"
className="font-mono text-xs" style={{ fontSize: "12px" }}
/>
<p className="text-muted-foreground text-xs">JavaScript .</p>
</div>
@ -219,7 +219,7 @@ export const TextConfigPanel: React.FC<WebTypeConfigPanelProps> = ({
minLength={localConfig.minLength}
pattern={localConfig.pattern}
autoComplete={localConfig.autoComplete}
className="text-xs"
className="text-xs" style={{ fontSize: "12px" }}
/>
</div>
</div>

View File

@ -68,7 +68,7 @@ export const TextareaConfigPanel: React.FC<WebTypeConfigPanelProps> = ({
return (
<Card>
<CardHeader>
<CardTitle className="flex items-center gap-2 text-sm">
<CardTitle className="flex items-center gap-2 text-xs" style={{ fontSize: "12px" }}>
<AlignLeft className="h-4 w-4" />
</CardTitle>
@ -88,7 +88,7 @@ export const TextareaConfigPanel: React.FC<WebTypeConfigPanelProps> = ({
value={localConfig.placeholder || ""}
onChange={(e) => updateConfig("placeholder", e.target.value)}
placeholder="내용을 입력하세요"
className="text-xs"
className="text-xs" style={{ fontSize: "12px" }}
/>
</div>
@ -101,7 +101,7 @@ export const TextareaConfigPanel: React.FC<WebTypeConfigPanelProps> = ({
value={localConfig.defaultValue || ""}
onChange={(e) => updateConfig("defaultValue", e.target.value)}
placeholder="기본 텍스트 내용"
className="text-xs"
className="text-xs" style={{ fontSize: "12px" }}
rows={3}
/>
{localConfig.showCharCount && (
@ -151,7 +151,7 @@ export const TextareaConfigPanel: React.FC<WebTypeConfigPanelProps> = ({
placeholder="자동 (CSS로 제어)"
min={10}
max={200}
className="text-xs"
className="text-xs" style={{ fontSize: "12px" }}
/>
<p className="text-muted-foreground text-xs"> CSS width로 .</p>
</div>
@ -203,7 +203,7 @@ export const TextareaConfigPanel: React.FC<WebTypeConfigPanelProps> = ({
}}
placeholder="제한 없음"
min={0}
className="text-xs"
className="text-xs" style={{ fontSize: "12px" }}
/>
</div>
@ -221,7 +221,7 @@ export const TextareaConfigPanel: React.FC<WebTypeConfigPanelProps> = ({
}}
placeholder="제한 없음"
min={1}
className="text-xs"
className="text-xs" style={{ fontSize: "12px" }}
/>
</div>
@ -333,7 +333,7 @@ export const TextareaConfigPanel: React.FC<WebTypeConfigPanelProps> = ({
resize: localConfig.resizable ? "both" : "none",
minHeight: localConfig.autoHeight ? "auto" : undefined,
}}
className="text-xs"
className="text-xs" style={{ fontSize: "12px" }}
wrap={localConfig.wrap}
/>
{localConfig.showCharCount && (

View File

@ -94,7 +94,7 @@ export const FlowButtonGroupDialog: React.FC<FlowButtonGroupDialogProps> = ({
max={100}
value={gap}
onChange={(e) => setGap(Number(e.target.value))}
className="h-9 text-sm sm:h-10"
className="h-6 w-full px-2 py-0 text-xs" style={{ fontSize: "12px" }}
/>
<Badge variant="outline" className="text-xs">
{gap}px
@ -109,7 +109,7 @@ export const FlowButtonGroupDialog: React.FC<FlowButtonGroupDialogProps> = ({
</Label>
<Select value={align} onValueChange={(value: any) => setAlign(value)}>
<SelectTrigger id="align" className="h-9 text-sm sm:h-10">
<SelectTrigger id="align" className="h-6 w-full px-2 py-0 text-xs" style={{ fontSize: "12px" }}>
<SelectValue />
</SelectTrigger>
<SelectContent>

View File

@ -177,7 +177,7 @@ export function ComponentsPanel({
onSearchChange(value);
}
}}
className="h-8 pl-8 text-xs"
className="h-8 pl-8 text-xs" style={{ fontSize: "12px" }}
/>
</div>
</div>

View File

@ -458,7 +458,7 @@ const DataTableConfigPanelComponent: React.FC<DataTableConfigPanelProps> = ({
updateSettings({ options: newOptions });
}}
placeholder="옵션명"
className="h-7 text-xs"
className="h-7 text-xs" style={{ fontSize: "12px" }}
/>
<Button
type="button"
@ -483,7 +483,7 @@ const DataTableConfigPanelComponent: React.FC<DataTableConfigPanelProps> = ({
const newOption = { label: "", value: "" };
updateSettings({ options: [...(localSettings.options || []), newOption] });
}}
className="h-7 text-xs"
className="h-7 text-xs" style={{ fontSize: "12px" }}
>
<Plus className="mr-1 h-3 w-3" />
@ -548,7 +548,7 @@ const DataTableConfigPanelComponent: React.FC<DataTableConfigPanelProps> = ({
value={localSettings.min || ""}
onChange={(e) => updateSettings({ min: e.target.value ? Number(e.target.value) : undefined })}
placeholder="최소값"
className="h-7 text-xs"
className="h-7 text-xs" style={{ fontSize: "12px" }}
/>
</div>
<div className="space-y-1">
@ -558,7 +558,7 @@ const DataTableConfigPanelComponent: React.FC<DataTableConfigPanelProps> = ({
value={localSettings.max || ""}
onChange={(e) => updateSettings({ max: e.target.value ? Number(e.target.value) : undefined })}
placeholder="최대값"
className="h-7 text-xs"
className="h-7 text-xs" style={{ fontSize: "12px" }}
/>
</div>
</div>
@ -571,7 +571,7 @@ const DataTableConfigPanelComponent: React.FC<DataTableConfigPanelProps> = ({
value={localSettings.step || "0.01"}
onChange={(e) => updateSettings({ step: e.target.value })}
placeholder="0.01"
className="h-7 text-xs"
className="h-7 text-xs" style={{ fontSize: "12px" }}
/>
</div>
)}
@ -589,7 +589,7 @@ const DataTableConfigPanelComponent: React.FC<DataTableConfigPanelProps> = ({
type="date"
value={localSettings.minDate || ""}
onChange={(e) => updateSettings({ minDate: e.target.value })}
className="h-7 text-xs"
className="h-7 text-xs" style={{ fontSize: "12px" }}
/>
</div>
<div className="space-y-1">
@ -598,7 +598,7 @@ const DataTableConfigPanelComponent: React.FC<DataTableConfigPanelProps> = ({
type="date"
value={localSettings.maxDate || ""}
onChange={(e) => updateSettings({ maxDate: e.target.value })}
className="h-7 text-xs"
className="h-7 text-xs" style={{ fontSize: "12px" }}
/>
</div>
</div>
@ -626,7 +626,7 @@ const DataTableConfigPanelComponent: React.FC<DataTableConfigPanelProps> = ({
value={localSettings.maxLength || ""}
onChange={(e) => updateSettings({ maxLength: e.target.value ? Number(e.target.value) : undefined })}
placeholder="최대 문자 수"
className="h-7 text-xs"
className="h-7 text-xs" style={{ fontSize: "12px" }}
/>
</div>
<div className="space-y-1">
@ -635,7 +635,7 @@ const DataTableConfigPanelComponent: React.FC<DataTableConfigPanelProps> = ({
value={localSettings.placeholder || ""}
onChange={(e) => updateSettings({ placeholder: e.target.value })}
placeholder="입력 안내 텍스트"
className="h-7 text-xs"
className="h-7 text-xs" style={{ fontSize: "12px" }}
/>
</div>
</div>
@ -652,7 +652,7 @@ const DataTableConfigPanelComponent: React.FC<DataTableConfigPanelProps> = ({
value={localSettings.rows || "3"}
onChange={(e) => updateSettings({ rows: Number(e.target.value) })}
placeholder="3"
className="h-7 text-xs"
className="h-7 text-xs" style={{ fontSize: "12px" }}
/>
</div>
<div className="space-y-1">
@ -662,7 +662,7 @@ const DataTableConfigPanelComponent: React.FC<DataTableConfigPanelProps> = ({
value={localSettings.maxLength || ""}
onChange={(e) => updateSettings({ maxLength: e.target.value ? Number(e.target.value) : undefined })}
placeholder="최대 문자 수"
className="h-7 text-xs"
className="h-7 text-xs" style={{ fontSize: "12px" }}
/>
</div>
</div>
@ -678,7 +678,7 @@ const DataTableConfigPanelComponent: React.FC<DataTableConfigPanelProps> = ({
value={localSettings.accept || ""}
onChange={(e) => updateSettings({ accept: e.target.value })}
placeholder=".jpg,.png,.pdf"
className="h-7 text-xs"
className="h-7 text-xs" style={{ fontSize: "12px" }}
/>
</div>
<div className="space-y-1">
@ -688,7 +688,7 @@ const DataTableConfigPanelComponent: React.FC<DataTableConfigPanelProps> = ({
value={localSettings.maxSize ? localSettings.maxSize / 1024 / 1024 : "10"}
onChange={(e) => updateSettings({ maxSize: Number(e.target.value) * 1024 * 1024 })}
placeholder="10"
className="h-7 text-xs"
className="h-7 text-xs" style={{ fontSize: "12px" }}
/>
</div>
<div className="flex items-center space-x-2">
@ -1132,7 +1132,7 @@ const DataTableConfigPanelComponent: React.FC<DataTableConfigPanelProps> = ({
{/* 기본 설정 */}
<Card>
<CardHeader>
<CardTitle className="flex items-center space-x-2 text-sm">
<CardTitle className="flex items-center space-x-2 text-xs" style={{ fontSize: "12px" }}>
<Settings className="h-4 w-4" />
<span> </span>
</CardTitle>
@ -1184,7 +1184,7 @@ const DataTableConfigPanelComponent: React.FC<DataTableConfigPanelProps> = ({
onUpdateComponent({ enableAdd: checked as boolean });
}}
/>
<Label htmlFor="enable-add" className="text-sm">
<Label htmlFor="enable-add" className="text-xs" style={{ fontSize: "12px" }}>
</Label>
</div>
@ -1198,7 +1198,7 @@ const DataTableConfigPanelComponent: React.FC<DataTableConfigPanelProps> = ({
onUpdateComponent({ enableEdit: checked as boolean });
}}
/>
<Label htmlFor="enable-edit" className="text-sm">
<Label htmlFor="enable-edit" className="text-xs" style={{ fontSize: "12px" }}>
</Label>
</div>
@ -1212,7 +1212,7 @@ const DataTableConfigPanelComponent: React.FC<DataTableConfigPanelProps> = ({
onUpdateComponent({ enableDelete: checked as boolean });
}}
/>
<Label htmlFor="enable-delete" className="text-sm">
<Label htmlFor="enable-delete" className="text-xs" style={{ fontSize: "12px" }}>
</Label>
</div>
@ -1220,7 +1220,7 @@ const DataTableConfigPanelComponent: React.FC<DataTableConfigPanelProps> = ({
<div className="grid grid-cols-3 gap-4">
<div className="space-y-2">
<Label htmlFor="add-button-text" className="text-sm">
<Label htmlFor="add-button-text" className="text-xs" style={{ fontSize: "12px" }}>
</Label>
<Input
@ -1233,12 +1233,12 @@ const DataTableConfigPanelComponent: React.FC<DataTableConfigPanelProps> = ({
}}
placeholder="추가"
disabled={!localValues.enableAdd}
className="h-8 text-sm"
className="h-6 w-full px-2 py-0 text-xs" style={{ fontSize: "12px" }}
/>
</div>
<div className="space-y-2">
<Label htmlFor="edit-button-text" className="text-sm">
<Label htmlFor="edit-button-text" className="text-xs" style={{ fontSize: "12px" }}>
</Label>
<Input
@ -1251,12 +1251,12 @@ const DataTableConfigPanelComponent: React.FC<DataTableConfigPanelProps> = ({
}}
placeholder="수정"
disabled={!localValues.enableEdit}
className="h-8 text-sm"
className="h-6 w-full px-2 py-0 text-xs" style={{ fontSize: "12px" }}
/>
</div>
<div className="space-y-2">
<Label htmlFor="delete-button-text" className="text-sm">
<Label htmlFor="delete-button-text" className="text-xs" style={{ fontSize: "12px" }}>
</Label>
<Input
@ -1269,7 +1269,7 @@ const DataTableConfigPanelComponent: React.FC<DataTableConfigPanelProps> = ({
}}
placeholder="삭제"
disabled={!localValues.enableDelete}
className="h-8 text-sm"
className="h-6 w-full px-2 py-0 text-xs" style={{ fontSize: "12px" }}
/>
</div>
</div>
@ -1284,7 +1284,7 @@ const DataTableConfigPanelComponent: React.FC<DataTableConfigPanelProps> = ({
<div className="grid grid-cols-2 gap-4">
<div className="space-y-2">
<Label htmlFor="modal-title" className="text-sm">
<Label htmlFor="modal-title" className="text-xs" style={{ fontSize: "12px" }}>
</Label>
<Input
@ -1298,12 +1298,12 @@ const DataTableConfigPanelComponent: React.FC<DataTableConfigPanelProps> = ({
});
}}
placeholder="새 데이터 추가"
className="h-8 text-sm"
className="h-6 w-full px-2 py-0 text-xs" style={{ fontSize: "12px" }}
/>
</div>
<div className="space-y-2">
<Label htmlFor="modal-width" className="text-sm">
<Label htmlFor="modal-width" className="text-xs" style={{ fontSize: "12px" }}>
</Label>
<select
@ -1328,7 +1328,7 @@ const DataTableConfigPanelComponent: React.FC<DataTableConfigPanelProps> = ({
</div>
<div className="space-y-2">
<Label htmlFor="modal-description" className="text-sm">
<Label htmlFor="modal-description" className="text-xs" style={{ fontSize: "12px" }}>
</Label>
<Input
@ -1342,13 +1342,13 @@ const DataTableConfigPanelComponent: React.FC<DataTableConfigPanelProps> = ({
});
}}
placeholder="모달에 표시될 설명을 입력하세요"
className="h-8 text-sm"
className="h-6 w-full px-2 py-0 text-xs" style={{ fontSize: "12px" }}
/>
</div>
<div className="grid grid-cols-2 gap-4">
<div className="space-y-2">
<Label htmlFor="modal-layout" className="text-sm">
<Label htmlFor="modal-layout" className="text-xs" style={{ fontSize: "12px" }}>
</Label>
<select
@ -1370,7 +1370,7 @@ const DataTableConfigPanelComponent: React.FC<DataTableConfigPanelProps> = ({
{localValues.modalLayout === "grid" && (
<div className="space-y-2">
<Label htmlFor="modal-grid-columns" className="text-sm">
<Label htmlFor="modal-grid-columns" className="text-xs" style={{ fontSize: "12px" }}>
</Label>
<select
@ -1394,7 +1394,7 @@ const DataTableConfigPanelComponent: React.FC<DataTableConfigPanelProps> = ({
<div className="grid grid-cols-2 gap-4">
<div className="space-y-2">
<Label htmlFor="modal-submit-text" className="text-sm">
<Label htmlFor="modal-submit-text" className="text-xs" style={{ fontSize: "12px" }}>
</Label>
<Input
@ -1408,12 +1408,12 @@ const DataTableConfigPanelComponent: React.FC<DataTableConfigPanelProps> = ({
});
}}
placeholder="추가"
className="h-8 text-sm"
className="h-6 w-full px-2 py-0 text-xs" style={{ fontSize: "12px" }}
/>
</div>
<div className="space-y-2">
<Label htmlFor="modal-cancel-text" className="text-sm">
<Label htmlFor="modal-cancel-text" className="text-xs" style={{ fontSize: "12px" }}>
</Label>
<Input
@ -1427,7 +1427,7 @@ const DataTableConfigPanelComponent: React.FC<DataTableConfigPanelProps> = ({
});
}}
placeholder="취소"
className="h-8 text-sm"
className="h-6 w-full px-2 py-0 text-xs" style={{ fontSize: "12px" }}
/>
</div>
</div>
@ -1441,7 +1441,7 @@ const DataTableConfigPanelComponent: React.FC<DataTableConfigPanelProps> = ({
<div className="space-y-3">
<div className="space-y-2">
<Label htmlFor="edit-modal-title" className="text-sm">
<Label htmlFor="edit-modal-title" className="text-xs" style={{ fontSize: "12px" }}>
</Label>
<Input
@ -1455,13 +1455,13 @@ const DataTableConfigPanelComponent: React.FC<DataTableConfigPanelProps> = ({
});
}}
placeholder="데이터 수정"
className="h-8 text-sm"
className="h-6 w-full px-2 py-0 text-xs" style={{ fontSize: "12px" }}
/>
<p className="text-xs text-gray-500"> </p>
</div>
<div className="space-y-2">
<Label htmlFor="edit-modal-description" className="text-sm">
<Label htmlFor="edit-modal-description" className="text-xs" style={{ fontSize: "12px" }}>
</Label>
<Input
@ -1475,7 +1475,7 @@ const DataTableConfigPanelComponent: React.FC<DataTableConfigPanelProps> = ({
});
}}
placeholder="선택한 데이터를 수정합니다"
className="h-8 text-sm"
className="h-6 w-full px-2 py-0 text-xs" style={{ fontSize: "12px" }}
/>
<p className="text-xs text-gray-500"> </p>
</div>
@ -1494,7 +1494,7 @@ const DataTableConfigPanelComponent: React.FC<DataTableConfigPanelProps> = ({
onUpdateComponent({ showSearchButton: checked as boolean });
}}
/>
<Label htmlFor="show-search-button" className="text-sm">
<Label htmlFor="show-search-button" className="text-xs" style={{ fontSize: "12px" }}>
</Label>
</div>
@ -1509,7 +1509,7 @@ const DataTableConfigPanelComponent: React.FC<DataTableConfigPanelProps> = ({
onUpdateComponent({ enableExport: checked as boolean });
}}
/>
<Label htmlFor="enable-export" className="text-sm">
<Label htmlFor="enable-export" className="text-xs" style={{ fontSize: "12px" }}>
</Label>
</div>
@ -1521,7 +1521,7 @@ const DataTableConfigPanelComponent: React.FC<DataTableConfigPanelProps> = ({
<TabsContent value="columns" className="mt-4 max-h-[70vh] overflow-y-auto">
<Card>
<CardHeader>
<CardTitle className="flex items-center space-x-2 text-sm">
<CardTitle className="flex items-center space-x-2 text-xs" style={{ fontSize: "12px" }}>
<Columns className="h-4 w-4" />
<span> </span>
</CardTitle>
@ -1535,7 +1535,7 @@ const DataTableConfigPanelComponent: React.FC<DataTableConfigPanelProps> = ({
<div className="flex flex-wrap items-center gap-2">
{/* 파일 컬럼 추가 버튼 */}
<Button size="sm" variant="outline" onClick={addVirtualFileColumn} className="h-8 text-xs">
<Button size="sm" variant="outline" onClick={addVirtualFileColumn} className="h-6 w-full px-2 py-0 text-xs">
<Plus className="h-4 w-4" />
<span className="ml-1"> </span>
</Button>
@ -1654,7 +1654,7 @@ const DataTableConfigPanelComponent: React.FC<DataTableConfigPanelProps> = ({
}
}}
placeholder="표시명을 입력하세요"
className="h-8 text-xs"
className="h-6 w-full px-2 py-0 text-xs" style={{ fontSize: "12px" }}
/>
</div>
@ -1673,7 +1673,7 @@ const DataTableConfigPanelComponent: React.FC<DataTableConfigPanelProps> = ({
updateColumn(column.id, { gridColumns: newGridColumns });
}}
>
<SelectTrigger className="h-8 text-xs">
<SelectTrigger className="h-6 w-full px-2 py-0 text-xs">
<SelectValue />
</SelectTrigger>
<SelectContent>
@ -1861,7 +1861,7 @@ const DataTableConfigPanelComponent: React.FC<DataTableConfigPanelProps> = ({
});
}}
>
<SelectTrigger className="h-8 text-xs">
<SelectTrigger className="h-6 w-full px-2 py-0 text-xs">
<SelectValue />
</SelectTrigger>
<SelectContent>
@ -1902,7 +1902,7 @@ const DataTableConfigPanelComponent: React.FC<DataTableConfigPanelProps> = ({
});
}}
>
<SelectTrigger className="h-8 text-xs">
<SelectTrigger className="h-6 w-full px-2 py-0 text-xs">
<SelectValue />
</SelectTrigger>
<SelectContent>
@ -1947,7 +1947,7 @@ const DataTableConfigPanelComponent: React.FC<DataTableConfigPanelProps> = ({
});
}}
placeholder="고정값 입력..."
className="h-8 text-xs"
className="h-6 w-full px-2 py-0 text-xs" style={{ fontSize: "12px" }}
/>
</div>
)}
@ -1967,7 +1967,7 @@ const DataTableConfigPanelComponent: React.FC<DataTableConfigPanelProps> = ({
<TabsContent value="filters" className="mt-4 max-h-[70vh] overflow-y-auto">
<Card>
<CardHeader>
<CardTitle className="flex items-center space-x-2 text-sm">
<CardTitle className="flex items-center space-x-2 text-xs" style={{ fontSize: "12px" }}>
<Filter className="h-4 w-4" />
<span> </span>
</CardTitle>
@ -1995,7 +1995,7 @@ const DataTableConfigPanelComponent: React.FC<DataTableConfigPanelProps> = ({
{component.filters.length === 0 ? (
<div className="text-muted-foreground py-8 text-center">
<Filter className="mx-auto mb-2 h-8 w-8 opacity-50" />
<p className="text-sm"> </p>
<p className="text-xs" style={{ fontSize: "12px" }}> </p>
<p className="text-xs"> </p>
</div>
) : (
@ -2073,7 +2073,7 @@ const DataTableConfigPanelComponent: React.FC<DataTableConfigPanelProps> = ({
updateFilter(index, { label: newValue });
}}
placeholder="필터 이름 입력..."
className="h-8 text-xs"
className="h-6 w-full px-2 py-0 text-xs" style={{ fontSize: "12px" }}
/>
</div>
<p className="text-muted-foreground mt-1 text-xs">
@ -2112,7 +2112,7 @@ const DataTableConfigPanelComponent: React.FC<DataTableConfigPanelProps> = ({
}
}}
>
<SelectTrigger className="h-8 text-xs">
<SelectTrigger className="h-6 w-full px-2 py-0 text-xs">
<SelectValue />
</SelectTrigger>
<SelectContent>
@ -2144,7 +2144,7 @@ const DataTableConfigPanelComponent: React.FC<DataTableConfigPanelProps> = ({
value={filter.gridColumns.toString()}
onValueChange={(value) => updateFilter(index, { gridColumns: parseInt(value) })}
>
<SelectTrigger className="h-8 text-xs">
<SelectTrigger className="h-6 w-full px-2 py-0 text-xs">
<SelectValue />
</SelectTrigger>
<SelectContent>
@ -2192,7 +2192,7 @@ const DataTableConfigPanelComponent: React.FC<DataTableConfigPanelProps> = ({
<TabsContent value="modal" className="mt-4 max-h-[70vh] overflow-y-auto">
<Card>
<CardHeader>
<CardTitle className="flex items-center space-x-2 text-sm">
<CardTitle className="flex items-center space-x-2 text-xs" style={{ fontSize: "12px" }}>
<Settings className="h-4 w-4" />
<span> </span>
</CardTitle>
@ -2258,7 +2258,7 @@ const DataTableConfigPanelComponent: React.FC<DataTableConfigPanelProps> = ({
});
}}
/>
<Label htmlFor="show-page-size-selector" className="text-sm">
<Label htmlFor="show-page-size-selector" className="text-xs" style={{ fontSize: "12px" }}>
</Label>
</div>
@ -2278,7 +2278,7 @@ const DataTableConfigPanelComponent: React.FC<DataTableConfigPanelProps> = ({
});
}}
/>
<Label htmlFor="show-page-info" className="text-sm">
<Label htmlFor="show-page-info" className="text-xs" style={{ fontSize: "12px" }}>
</Label>
</div>
@ -2298,7 +2298,7 @@ const DataTableConfigPanelComponent: React.FC<DataTableConfigPanelProps> = ({
});
}}
/>
<Label htmlFor="show-first-last" className="text-sm">
<Label htmlFor="show-first-last" className="text-xs" style={{ fontSize: "12px" }}>
/
</Label>
</div>

View File

@ -148,7 +148,8 @@ export const DetailSettingsPanel: React.FC<DetailSettingsPanelProps> = ({
onUpdateProperty(layoutComponent.id, "zones", newZones);
}
}}
className="w-full rounded border border-gray-300 px-2 py-1 text-sm"
className="w-full rounded border border-gray-300 px-2 py-1 text-xs"
style={{ fontSize: "12px" }}
/>
</div>
<div>
@ -185,7 +186,8 @@ export const DetailSettingsPanel: React.FC<DetailSettingsPanelProps> = ({
onUpdateProperty(layoutComponent.id, "zones", newZones);
}
}}
className="w-full rounded border border-gray-300 px-2 py-1 text-sm"
className="w-full rounded border border-gray-300 px-2 py-1 text-xs"
style={{ fontSize: "12px" }}
/>
</div>
</div>
@ -199,7 +201,8 @@ export const DetailSettingsPanel: React.FC<DetailSettingsPanelProps> = ({
onChange={(e) =>
onUpdateProperty(layoutComponent.id, "layoutConfig.grid.gap", parseInt(e.target.value))
}
className="w-full rounded border border-gray-300 px-2 py-1 text-sm"
className="w-full rounded border border-gray-300 px-2 py-1 text-xs"
style={{ fontSize: "12px" }}
/>
</div>
</div>
@ -243,7 +246,8 @@ export const DetailSettingsPanel: React.FC<DetailSettingsPanelProps> = ({
onUpdateProperty(layoutComponent.id, "zones", updatedZones);
}
}}
className="w-full rounded border border-gray-300 px-2 py-1 text-sm"
className="w-full rounded border border-gray-300 px-2 py-1 text-xs"
style={{ fontSize: "12px" }}
>
<option value="row"> (row)</option>
<option value="column"> (column)</option>
@ -302,7 +306,8 @@ export const DetailSettingsPanel: React.FC<DetailSettingsPanelProps> = ({
onUpdateProperty(layoutComponent.id, "zones", newZones);
}
}}
className="w-20 rounded border border-gray-300 px-2 py-1 text-sm"
className="w-20 rounded border border-gray-300 px-2 py-1 text-xs"
style={{ fontSize: "12px" }}
/>
<span className="text-xs text-gray-500"></span>
</div>
@ -317,7 +322,8 @@ export const DetailSettingsPanel: React.FC<DetailSettingsPanelProps> = ({
onChange={(e) =>
onUpdateProperty(layoutComponent.id, "layoutConfig.flexbox.gap", parseInt(e.target.value))
}
className="w-full rounded border border-gray-300 px-2 py-1 text-sm"
className="w-full rounded border border-gray-300 px-2 py-1 text-xs"
style={{ fontSize: "12px" }}
/>
</div>
</div>
@ -332,7 +338,8 @@ export const DetailSettingsPanel: React.FC<DetailSettingsPanelProps> = ({
<select
value={layoutComponent.layoutConfig?.split?.direction || "horizontal"}
onChange={(e) => onUpdateProperty(layoutComponent.id, "layoutConfig.split.direction", e.target.value)}
className="w-full rounded border border-gray-300 px-2 py-1 text-sm"
className="w-full rounded border border-gray-300 px-2 py-1 text-xs"
style={{ fontSize: "12px" }}
>
<option value="horizontal"> </option>
<option value="vertical"> </option>
@ -381,7 +388,8 @@ export const DetailSettingsPanel: React.FC<DetailSettingsPanelProps> = ({
e.target.value,
)
}
className="w-full rounded border border-gray-300 px-2 py-1 text-sm"
className="w-full rounded border border-gray-300 px-2 py-1 text-xs"
style={{ fontSize: "12px" }}
>
<option value=""> </option>
{currentTable.columns?.map((column) => (
@ -403,7 +411,8 @@ export const DetailSettingsPanel: React.FC<DetailSettingsPanelProps> = ({
e.target.value,
)
}
className="w-full rounded border border-gray-300 px-2 py-1 text-sm"
className="w-full rounded border border-gray-300 px-2 py-1 text-xs"
style={{ fontSize: "12px" }}
>
<option value=""> </option>
{currentTable.columns?.map((column) => (
@ -425,7 +434,8 @@ export const DetailSettingsPanel: React.FC<DetailSettingsPanelProps> = ({
e.target.value,
)
}
className="w-full rounded border border-gray-300 px-2 py-1 text-sm"
className="w-full rounded border border-gray-300 px-2 py-1 text-xs"
style={{ fontSize: "12px" }}
>
<option value=""> </option>
{currentTable.columns?.map((column) => (
@ -447,7 +457,8 @@ export const DetailSettingsPanel: React.FC<DetailSettingsPanelProps> = ({
e.target.value,
)
}
className="w-full rounded border border-gray-300 px-2 py-1 text-sm"
className="w-full rounded border border-gray-300 px-2 py-1 text-xs"
style={{ fontSize: "12px" }}
>
<option value=""> </option>
{currentTable.columns?.map((column) => (
@ -475,6 +486,7 @@ export const DetailSettingsPanel: React.FC<DetailSettingsPanelProps> = ({
);
}}
className="bg-primary text-primary-foreground hover:bg-primary/90 rounded px-2 py-1 text-xs"
style={{ fontSize: "12px" }}
>
+
</button>
@ -497,7 +509,8 @@ export const DetailSettingsPanel: React.FC<DetailSettingsPanelProps> = ({
currentColumns,
);
}}
className="flex-1 rounded border border-gray-300 px-2 py-1 text-sm"
className="flex-1 rounded border border-gray-300 px-2 py-1 text-xs"
style={{ fontSize: "12px" }}
>
<option value=""> </option>
{currentTable.columns?.map((col) => (
@ -520,6 +533,7 @@ export const DetailSettingsPanel: React.FC<DetailSettingsPanelProps> = ({
);
}}
className="bg-destructive text-destructive-foreground hover:bg-destructive/90 rounded px-2 py-1 text-xs"
style={{ fontSize: "12px" }}
>
</button>
@ -554,7 +568,8 @@ export const DetailSettingsPanel: React.FC<DetailSettingsPanelProps> = ({
onChange={(e) =>
onUpdateProperty(layoutComponent.id, "layoutConfig.card.cardsPerRow", parseInt(e.target.value))
}
className="w-full rounded border border-gray-300 px-2 py-1 text-sm"
className="w-full rounded border border-gray-300 px-2 py-1 text-xs"
style={{ fontSize: "12px" }}
/>
</div>
@ -568,7 +583,8 @@ export const DetailSettingsPanel: React.FC<DetailSettingsPanelProps> = ({
onChange={(e) =>
onUpdateProperty(layoutComponent.id, "layoutConfig.card.cardSpacing", parseInt(e.target.value))
}
className="w-full rounded border border-gray-300 px-2 py-1 text-sm"
className="w-full rounded border border-gray-300 px-2 py-1 text-xs"
style={{ fontSize: "12px" }}
/>
</div>
</div>
@ -657,7 +673,8 @@ export const DetailSettingsPanel: React.FC<DetailSettingsPanelProps> = ({
parseInt(e.target.value),
)
}
className="w-full rounded border border-gray-300 px-2 py-1 text-sm"
className="w-full rounded border border-gray-300 px-2 py-1 text-xs"
style={{ fontSize: "12px" }}
/>
</div>
</div>
@ -685,6 +702,7 @@ export const DetailSettingsPanel: React.FC<DetailSettingsPanelProps> = ({
onUpdateProperty(layoutComponent.id, `zones.${index}.size.width`, e.target.value)
}
className="w-full rounded border border-gray-300 px-2 py-1 text-xs"
style={{ fontSize: "12px" }}
placeholder="100%"
/>
</div>
@ -697,6 +715,7 @@ export const DetailSettingsPanel: React.FC<DetailSettingsPanelProps> = ({
onUpdateProperty(layoutComponent.id, `zones.${index}.size.height`, e.target.value)
}
className="w-full rounded border border-gray-300 px-2 py-1 text-xs"
style={{ fontSize: "12px" }}
placeholder="auto"
/>
</div>
@ -909,7 +928,9 @@ export const DetailSettingsPanel: React.FC<DetailSettingsPanelProps> = ({
<h3 className="font-medium text-gray-900"> </h3>
</div>
<div className="mt-2 flex items-center space-x-2">
<span className="text-muted-foreground text-sm">:</span>
<span className="text-muted-foreground text-xs" style={{ fontSize: "12px" }}>
:
</span>
<span className="rounded bg-green-100 px-2 py-1 text-xs font-medium text-green-800">{componentType}</span>
</div>
</div>
@ -957,7 +978,9 @@ export const DetailSettingsPanel: React.FC<DetailSettingsPanelProps> = ({
<h3 className="font-medium text-gray-900"> </h3>
</div>
<div className="mt-2 flex items-center space-x-2">
<span className="text-muted-foreground text-sm">:</span>
<span className="text-muted-foreground text-xs" style={{ fontSize: "12px" }}>
:
</span>
<span className="rounded bg-purple-100 px-2 py-1 text-xs font-medium text-purple-800"> </span>
</div>
<div className="mt-1 text-xs text-gray-500">
@ -1044,12 +1067,16 @@ export const DetailSettingsPanel: React.FC<DetailSettingsPanelProps> = ({
{/* 컴포넌트 정보 */}
<div className="mb-4 space-y-2">
<div className="flex items-center space-x-2">
<span className="text-muted-foreground text-sm">:</span>
<span className="text-muted-foreground text-xs" style={{ fontSize: "12px" }}>
:
</span>
<span className="rounded bg-green-100 px-2 py-1 text-xs font-medium text-green-800">{componentId}</span>
</div>
{webType && currentBaseInputType && (
<div className="flex items-center space-x-2">
<span className="text-muted-foreground text-sm"> :</span>
<span className="text-muted-foreground text-xs" style={{ fontSize: "12px" }}>
:
</span>
<span className="rounded bg-blue-100 px-2 py-1 text-xs font-medium text-blue-800">
{currentBaseInputType}
</span>
@ -1057,7 +1084,9 @@ export const DetailSettingsPanel: React.FC<DetailSettingsPanelProps> = ({
)}
{selectedComponent.columnName && (
<div className="flex items-center space-x-2">
<span className="text-muted-foreground text-sm">:</span>
<span className="text-muted-foreground text-xs" style={{ fontSize: "12px" }}>
:
</span>
<span className="text-xs text-gray-700">{selectedComponent.columnName}</span>
</div>
)}
@ -1137,7 +1166,9 @@ export const DetailSettingsPanel: React.FC<DetailSettingsPanelProps> = ({
<h3 className="font-medium text-gray-900"> </h3>
</div>
<div className="mt-2 flex items-center space-x-2">
<span className="text-muted-foreground text-sm"> :</span>
<span className="text-muted-foreground text-xs" style={{ fontSize: "12px" }}>
:
</span>
<span className="rounded bg-blue-100 px-2 py-1 text-xs font-medium text-blue-800">
{currentBaseInputType}
</span>
@ -1150,7 +1181,7 @@ export const DetailSettingsPanel: React.FC<DetailSettingsPanelProps> = ({
<div className="space-y-2">
<label className="block text-sm font-medium text-gray-700"> </label>
<Select value={localDetailType} onValueChange={handleDetailTypeChange}>
<SelectTrigger className="h-8 w-full bg-white text-xs">
<SelectTrigger className="h-6 w-full px-2 py-0 bg-white text-xs" style={{ fontSize: "12px" }}>
<SelectValue placeholder="세부 타입을 선택하세요" />
</SelectTrigger>
<SelectContent>

View File

@ -98,7 +98,7 @@ export const FlowButtonGroupPanel: React.FC<FlowButtonGroupPanelProps> = ({
size="sm"
variant="ghost"
onClick={() => onSelectGroup(groupInfo.buttons.map((b) => b.id))}
className="h-7 px-2 text-xs"
className="h-7 px-2 text-xs" style={{ fontSize: "12px" }}
>
</Button>
@ -152,7 +152,7 @@ export const FlowButtonGroupPanel: React.FC<FlowButtonGroupPanelProps> = ({
{groupInfo.buttons.map((button) => (
<div
key={button.id}
className="flex items-center gap-2 rounded bg-white px-2 py-1.5 text-xs"
className="flex items-center gap-2 rounded bg-white px-2 py-1.5 text-xs" style={{ fontSize: "12px" }}
>
<div className="h-2 w-2 rounded-full bg-blue-500" />
<span className="flex-1 truncate font-medium">

View File

@ -68,7 +68,7 @@ export const GridPanel: React.FC<GridPanelProps> = ({
size="sm"
variant="outline"
onClick={onForceGridUpdate}
className="h-7 px-2 text-xs"
className="h-7 px-2 text-xs" style={{ fontSize: "12px" }}
title="현재 해상도에 맞게 모든 컴포넌트를 격자에 재정렬합니다"
>
<RefreshCw className="mr-1 h-3 w-3" />
@ -266,7 +266,7 @@ export const GridPanel: React.FC<GridPanelProps> = ({
<div className="space-y-3">
<h4 className="font-medium text-gray-900"> </h4>
<div className="space-y-2 text-sm">
<div className="space-y-2 text-xs" style={{ fontSize: "12px" }}>
<div className="flex justify-between">
<span className="text-muted-foreground">:</span>
<span className="font-mono">

View File

@ -214,7 +214,7 @@ export default function LayoutsPanel({
</Badge>
</div>
</div>
<CardTitle className="text-sm">{layout.name}</CardTitle>
<CardTitle className="text-xs" style={{ fontSize: "12px" }}>{layout.name}</CardTitle>
</CardHeader>
<CardContent className="pt-0">
{layout.description && (

View File

@ -645,7 +645,7 @@ const PropertiesPanelComponent: React.FC<PropertiesPanelProps> = ({
}}
className="border-input bg-background text-primary focus:ring-ring h-4 w-4 rounded border focus:ring-2 focus:ring-offset-2"
/>
<Label htmlFor="required" className="text-sm">
<Label htmlFor="required" className="text-xs" style={{ fontSize: "12px" }}>
</Label>
</div>
@ -661,7 +661,7 @@ const PropertiesPanelComponent: React.FC<PropertiesPanelProps> = ({
}}
className="border-input bg-background text-primary focus:ring-ring h-4 w-4 rounded border focus:ring-2 focus:ring-offset-2"
/>
<Label htmlFor="readonly" className="text-sm">
<Label htmlFor="readonly" className="text-xs" style={{ fontSize: "12px" }}>
</Label>
</div>
@ -942,7 +942,7 @@ const PropertiesPanelComponent: React.FC<PropertiesPanelProps> = ({
</>
) : (
<div className="bg-accent col-span-2 rounded-lg p-3 text-center">
<p className="text-primary text-sm"> </p>
<p className="text-primary text-xs" style={{ fontSize: "12px" }}> </p>
<p className="mt-1 text-xs text-blue-500"> </p>
</div>
)}

View File

@ -84,7 +84,7 @@ const ResolutionPanel: React.FC<ResolutionPanelProps> = ({ currentResolution, on
<div className="space-y-2">
<Label className="text-xs font-medium"> </Label>
<Select value={selectedPreset} onValueChange={handlePresetChange}>
<SelectTrigger className="h-8 text-xs">
<SelectTrigger className="h-6 w-full px-2 py-0" style={{ fontSize: "12px" }}>
<SelectValue placeholder="해상도를 선택하세요" />
</SelectTrigger>
<SelectContent>
@ -146,7 +146,8 @@ const ResolutionPanel: React.FC<ResolutionPanelProps> = ({ currentResolution, on
onChange={(e) => setCustomWidth(e.target.value)}
placeholder="1920"
min="1"
className="h-8 text-xs"
className="h-6 w-full px-2 py-0 text-xs" style={{ fontSize: "12px" }}
style={{ fontSize: "12px" }}
/>
</div>
<div className="space-y-1">
@ -157,11 +158,17 @@ const ResolutionPanel: React.FC<ResolutionPanelProps> = ({ currentResolution, on
onChange={(e) => setCustomHeight(e.target.value)}
placeholder="1080"
min="1"
className="h-8 text-xs"
className="h-6 w-full px-2 py-0 text-xs" style={{ fontSize: "12px" }}
style={{ fontSize: "12px" }}
/>
</div>
</div>
<Button onClick={handleCustomResolution} size="sm" className="h-8 w-full text-xs">
<Button
onClick={handleCustomResolution}
size="sm"
className="h-6 w-full px-2 py-0 text-xs" style={{ fontSize: "12px" }}
style={{ fontSize: "12px" }}
>
</Button>
</div>

View File

@ -106,7 +106,7 @@ export const RowSettingsPanel: React.FC<RowSettingsPanelProps> = ({ row, onUpdat
variant={row.gap === preset ? "default" : "outline"}
size="sm"
onClick={() => onUpdateRow({ gap: preset })}
className="text-xs"
className="text-xs" style={{ fontSize: "12px" }}
>
{GAP_PRESETS[preset].label}
</Button>
@ -127,7 +127,7 @@ export const RowSettingsPanel: React.FC<RowSettingsPanelProps> = ({ row, onUpdat
variant={row.padding === preset ? "default" : "outline"}
size="sm"
onClick={() => onUpdateRow({ padding: preset })}
className="text-xs"
className="text-xs" style={{ fontSize: "12px" }}
>
{GAP_PRESETS[preset].label}
</Button>

View File

@ -528,7 +528,7 @@ export const TemplatesPanel: React.FC<TemplatesPanelProps> = ({ onDragStart }) =
<div className="flex items-center justify-between rounded-xl bg-amber-50/80 border border-amber-200/60 p-3 text-amber-800 mb-4">
<div className="flex items-center space-x-2">
<Info className="h-4 w-4" />
<span className="text-sm">릿 , 릿 </span>
<span className="text-xs" style={{ fontSize: "12px" }}>릿 , 릿 </span>
</div>
<Button size="sm" variant="outline" onClick={() => refetch()} className="border-amber-300 text-amber-700 hover:bg-amber-100">
<RefreshCw className="h-4 w-4" />

View File

@ -201,20 +201,22 @@ export const UnifiedPropertiesPanel: React.FC<UnifiedPropertiesPanelProps> = ({
const area = selectedComponent as AreaComponent;
return (
<div className="space-y-1.5">
<div className="space-y-2">
{/* 라벨 + 최소 높이 (같은 행) */}
<div className="grid grid-cols-2 gap-1.5">
<div className="space-y-0.5">
<Label className="text-[10px]"></Label>
<div className="grid grid-cols-2 gap-2">
<div className="space-y-1">
<Label className="text-xs"></Label>
<Input
value={widget.label || ""}
onChange={(e) => handleUpdate("label", e.target.value)}
placeholder="라벨"
className="h-6 text-[10px]"
className="h-6 w-full px-2 py-0 text-xs"
style={{ fontSize: "12px" }}
style={{ fontSize: "12px" }}
/>
</div>
<div className="space-y-0.5">
<Label className="text-[10px]"></Label>
<div className="space-y-1">
<Label className="text-xs"></Label>
<Input
type="number"
value={selectedComponent.size?.height || 0}
@ -225,127 +227,152 @@ export const UnifiedPropertiesPanel: React.FC<UnifiedPropertiesPanelProps> = ({
}}
step={40}
placeholder="40"
className="h-6 text-[10px]"
className="h-6 w-full px-2 py-0 text-xs"
style={{ fontSize: "12px" }}
style={{ fontSize: "12px" }}
/>
</div>
</div>
{/* Placeholder (widget만) */}
{selectedComponent.type === "widget" && (
<div className="space-y-0.5">
<Label className="text-[10px]">Placeholder</Label>
<div className="space-y-1">
<Label className="text-xs">Placeholder</Label>
<Input
value={widget.placeholder || ""}
onChange={(e) => handleUpdate("placeholder", e.target.value)}
placeholder="입력 안내 텍스트"
className="h-6 text-[10px]"
className="h-6 w-full px-2 py-0 text-xs"
style={{ fontSize: "12px" }}
style={{ fontSize: "12px" }}
/>
</div>
)}
{/* Title (group/area) */}
{(selectedComponent.type === "group" || selectedComponent.type === "area") && (
<div className="space-y-0.5">
<Label className="text-[10px]"></Label>
<div className="space-y-1">
<Label className="text-xs"></Label>
<Input
value={group.title || area.title || ""}
onChange={(e) => handleUpdate("title", e.target.value)}
placeholder="제목"
className="h-6 text-[10px]"
className="h-6 w-full px-2 py-0 text-xs"
style={{ fontSize: "12px" }}
style={{ fontSize: "12px" }}
/>
</div>
)}
{/* Description (area만) */}
{selectedComponent.type === "area" && (
<div className="space-y-0.5">
<Label className="text-[10px]"></Label>
<div className="space-y-1">
<Label className="text-xs"></Label>
<Input
value={area.description || ""}
onChange={(e) => handleUpdate("description", e.target.value)}
placeholder="설명"
className="h-6 text-[10px]"
className="h-6 w-full px-2 py-0 text-xs"
style={{ fontSize: "12px" }}
style={{ fontSize: "12px" }}
/>
</div>
)}
{/* Grid Columns */}
{(selectedComponent as any).gridColumns !== undefined && (
<div className="space-y-0.5">
<Label className="text-[10px]">Grid Columns</Label>
<Select
value={((selectedComponent as any).gridColumns || 12).toString()}
onValueChange={(value) => handleUpdate("gridColumns", parseInt(value))}
>
<SelectTrigger className="h-6 text-[10px]">
<SelectValue />
</SelectTrigger>
<SelectContent>
{COLUMN_NUMBERS.map((span) => (
<SelectItem key={span} value={span.toString()}>
{span} ({Math.round((span / 12) * 100)}%)
</SelectItem>
))}
</SelectContent>
</Select>
{/* Grid Columns + Z-Index (같은 행) */}
<div className="grid grid-cols-2 gap-2">
{(selectedComponent as any).gridColumns !== undefined && (
<div className="space-y-1">
<Label className="text-xs">Grid</Label>
<Select
value={((selectedComponent as any).gridColumns || 12).toString()}
onValueChange={(value) => handleUpdate("gridColumns", parseInt(value))}
>
<SelectTrigger className="h-6 w-full px-2 py-0" style={{ fontSize: "12px" }}>
<SelectValue />
</SelectTrigger>
<SelectContent>
{COLUMN_NUMBERS.map((span) => (
<SelectItem key={span} value={span.toString()} style={{ fontSize: "12px" }}>
{span}
</SelectItem>
))}
</SelectContent>
</Select>
</div>
)}
<div className="space-y-1">
<Label className="text-xs">Z-Index</Label>
<Input
type="number"
value={currentPosition.z || 1}
onChange={(e) => handleUpdate("position.z", parseInt(e.target.value) || 1)}
className="h-6 w-full px-2 py-0 text-xs"
style={{ fontSize: "12px" }}
style={{ fontSize: "12px" }}
/>
</div>
)}
{/* Z-Index */}
<div className="space-y-0.5">
<Label className="text-[10px]">Z-Index ()</Label>
<Input
type="number"
value={currentPosition.z || 1}
onChange={(e) => handleUpdate("position.z", parseInt(e.target.value) || 1)}
className="h-6 text-[10px]"
/>
</div>
{/* 라벨 스타일 */}
<Collapsible>
<CollapsibleTrigger className="flex w-full items-center justify-between rounded-lg bg-slate-50 p-2 text-sm font-medium hover:bg-slate-100">
<CollapsibleTrigger className="flex w-full items-center justify-between rounded-lg bg-slate-50 p-2 text-xs font-medium hover:bg-slate-100">
<ChevronDown className="h-4 w-4" />
<ChevronDown className="h-3.5 w-3.5" />
</CollapsibleTrigger>
<CollapsibleContent className="mt-2 space-y-2">
<div>
<Label> </Label>
<div className="space-y-1">
<Label className="text-xs"> </Label>
<Input
value={selectedComponent.style?.labelText || selectedComponent.label || ""}
onChange={(e) => handleUpdate("style.labelText", e.target.value)}
className="h-6 w-full px-2 py-0 text-xs"
style={{ fontSize: "12px" }}
style={{ fontSize: "12px" }}
/>
</div>
<div className="grid grid-cols-2 gap-2">
<div>
<Label> </Label>
<div className="space-y-1">
<Label className="text-xs"></Label>
<Input
value={selectedComponent.style?.labelFontSize || "12px"}
onChange={(e) => handleUpdate("style.labelFontSize", e.target.value)}
className="h-6 w-full px-2 py-0 text-xs"
style={{ fontSize: "12px" }}
style={{ fontSize: "12px" }}
/>
</div>
<div>
<Label></Label>
<div className="space-y-1">
<Label className="text-xs"></Label>
<Input
type="color"
value={selectedComponent.style?.labelColor || "#212121"}
onChange={(e) => handleUpdate("style.labelColor", e.target.value)}
className="h-6 w-full px-2 py-0 text-xs"
style={{ fontSize: "12px" }}
style={{ fontSize: "12px" }}
/>
</div>
</div>
<div>
<Label> </Label>
<Input
value={selectedComponent.style?.labelMarginBottom || "4px"}
onChange={(e) => handleUpdate("style.labelMarginBottom", e.target.value)}
/>
</div>
<div className="flex items-center space-x-2">
<Checkbox
checked={selectedComponent.style?.labelDisplay !== false}
onCheckedChange={(checked) => handleUpdate("style.labelDisplay", checked)}
/>
<Label> </Label>
<div className="grid grid-cols-2 gap-2">
<div className="space-y-1">
<Label className="text-xs"></Label>
<Input
value={selectedComponent.style?.labelMarginBottom || "4px"}
onChange={(e) => handleUpdate("style.labelMarginBottom", e.target.value)}
className="h-6 w-full px-2 py-0 text-xs"
style={{ fontSize: "12px" }}
style={{ fontSize: "12px" }}
/>
</div>
<div className="flex items-center space-x-2 pt-5">
<Checkbox
checked={selectedComponent.style?.labelDisplay !== false}
onCheckedChange={(checked) => handleUpdate("style.labelDisplay", checked)}
className="h-4 w-4"
/>
<Label className="text-xs"></Label>
</div>
</div>
</CollapsibleContent>
</Collapsible>
@ -357,8 +384,9 @@ export const UnifiedPropertiesPanel: React.FC<UnifiedPropertiesPanelProps> = ({
<Checkbox
checked={widget.required === true || selectedComponent.componentConfig?.required === true}
onCheckedChange={(checked) => handleUpdate("componentConfig.required", checked)}
className="h-4 w-4"
/>
<Label> </Label>
<Label className="text-xs"></Label>
</div>
)}
{widget.readonly !== undefined && (
@ -366,8 +394,9 @@ export const UnifiedPropertiesPanel: React.FC<UnifiedPropertiesPanelProps> = ({
<Checkbox
checked={widget.readonly === true || selectedComponent.componentConfig?.readonly === true}
onCheckedChange={(checked) => handleUpdate("componentConfig.readonly", checked)}
className="h-4 w-4"
/>
<Label> </Label>
<Label className="text-xs"></Label>
</div>
)}
</div>
@ -468,7 +497,7 @@ export const UnifiedPropertiesPanel: React.FC<UnifiedPropertiesPanelProps> = ({
<div>
<Label> </Label>
<Select value={localComponentDetailType || webType} onValueChange={handleDetailTypeChange}>
<SelectTrigger className="h-8 text-xs">
<SelectTrigger className="h-6 w-full px-2 py-0 text-xs" style={{ fontSize: "12px" }}>
<SelectValue placeholder="세부 타입 선택" />
</SelectTrigger>
<SelectContent>
@ -516,7 +545,7 @@ export const UnifiedPropertiesPanel: React.FC<UnifiedPropertiesPanelProps> = ({
<div>
<Label> </Label>
<Select value={widget.webType} onValueChange={(value) => handleUpdate("webType", value)}>
<SelectTrigger className="h-8 text-xs">
<SelectTrigger className="h-6 w-full px-2 py-0 text-xs" style={{ fontSize: "12px" }}>
<SelectValue />
</SelectTrigger>
<SelectContent>

View File

@ -109,7 +109,7 @@ export const WebTypeConfigPanel: React.FC<WebTypeConfigPanelProps> = ({ webType,
<>
<Separator />
<div className="flex items-center justify-between">
<Label htmlFor="multiple" className="text-sm">
<Label htmlFor="multiple" className="text-xs" style={{ fontSize: "12px" }}>
</Label>
<Checkbox
@ -121,7 +121,7 @@ export const WebTypeConfigPanel: React.FC<WebTypeConfigPanelProps> = ({ webType,
/>
</div>
<div className="flex items-center justify-between">
<Label htmlFor="searchable" className="text-sm">
<Label htmlFor="searchable" className="text-xs" style={{ fontSize: "12px" }}>
</Label>
<Checkbox
@ -259,7 +259,7 @@ export const WebTypeConfigPanel: React.FC<WebTypeConfigPanelProps> = ({ webType,
{baseType === "date" && (
<div className="flex items-center justify-between">
<Label htmlFor="showTime" className="text-sm">
<Label htmlFor="showTime" className="text-xs" style={{ fontSize: "12px" }}>
</Label>
<Checkbox
@ -395,7 +395,7 @@ export const WebTypeConfigPanel: React.FC<WebTypeConfigPanelProps> = ({ webType,
</div>
<div className="flex items-center justify-between">
<Label htmlFor="fileMultiple" className="text-sm">
<Label htmlFor="fileMultiple" className="text-xs" style={{ fontSize: "12px" }}>
</Label>
<Checkbox

View File

@ -122,7 +122,7 @@ export const CheckboxTypeConfigPanel: React.FC<CheckboxTypeConfigPanelProps> = (
</Label>
<Select value={localValues.labelPosition} onValueChange={(value) => updateConfig("labelPosition", value)}>
<SelectTrigger className="mt-1 h-8 text-xs">
<SelectTrigger className="mt-1 h-6 w-full px-2 py-0 text-xs" style={{ fontSize: "12px" }}>
<SelectValue placeholder="라벨 위치 선택" />
</SelectTrigger>
<SelectContent>
@ -194,18 +194,18 @@ export const CheckboxTypeConfigPanel: React.FC<CheckboxTypeConfigPanelProps> = (
<Label className="text-sm font-medium text-gray-700"></Label>
<div className="mt-2 flex items-center space-x-2">
{localValues.labelPosition === "left" && localValues.checkboxText && (
<span className="text-sm">{localValues.checkboxText}</span>
<span className="text-xs" style={{ fontSize: "12px" }}>{localValues.checkboxText}</span>
)}
{localValues.labelPosition === "top" && localValues.checkboxText && (
<div className="w-full">
<div className="text-sm">{localValues.checkboxText}</div>
<div className="text-xs" style={{ fontSize: "12px" }}>{localValues.checkboxText}</div>
<Checkbox checked={localValues.defaultChecked} className="mt-1" />
</div>
)}
{(localValues.labelPosition === "right" || localValues.labelPosition === "bottom") && (
<>
<Checkbox checked={localValues.defaultChecked} />
{localValues.checkboxText && <span className="text-sm">{localValues.checkboxText}</span>}
{localValues.checkboxText && <span className="text-xs" style={{ fontSize: "12px" }}>{localValues.checkboxText}</span>}
</>
)}
{localValues.labelPosition === "left" && <Checkbox checked={localValues.defaultChecked} />}

View File

@ -121,7 +121,7 @@ export const CodeTypeConfigPanel: React.FC<CodeTypeConfigPanelProps> = ({ config
</Label>
<Select value={localValues.language} onValueChange={(value) => updateConfig("language", value)}>
<SelectTrigger className="mt-1 h-8 text-xs">
<SelectTrigger className="mt-1 h-6 w-full px-2 py-0 text-xs" style={{ fontSize: "12px" }}>
<SelectValue placeholder="언어 선택" />
</SelectTrigger>
<SelectContent className="max-h-60">
@ -140,7 +140,7 @@ export const CodeTypeConfigPanel: React.FC<CodeTypeConfigPanelProps> = ({ config
</Label>
<Select value={localValues.theme} onValueChange={(value) => updateConfig("theme", value)}>
<SelectTrigger className="mt-1 h-8 text-xs">
<SelectTrigger className="mt-1 h-6 w-full px-2 py-0 text-xs" style={{ fontSize: "12px" }}>
<SelectValue placeholder="테마 선택" />
</SelectTrigger>
<SelectContent>

View File

@ -193,7 +193,7 @@ export const DateTypeConfigPanel: React.FC<DateTypeConfigPanelProps> = ({ config
}, 0);
}}
>
<SelectTrigger className="mt-1 h-8 text-xs">
<SelectTrigger className="mt-1 h-6 w-full px-2 py-0 text-xs" style={{ fontSize: "12px" }}>
<SelectValue placeholder="날짜 형식 선택" />
</SelectTrigger>
<SelectContent>

View File

@ -233,7 +233,7 @@ export const EntityTypeConfigPanel: React.FC<EntityTypeConfigPanelProps> = ({ co
</Label>
<Select value={localValues.displayFormat} onValueChange={(value) => updateConfig("displayFormat", value)}>
<SelectTrigger className="mt-1 h-8 text-xs">
<SelectTrigger className="mt-1 h-6 w-full px-2 py-0 text-xs" style={{ fontSize: "12px" }}>
<SelectValue placeholder="형식 선택" />
</SelectTrigger>
<SelectContent>
@ -267,7 +267,7 @@ export const EntityTypeConfigPanel: React.FC<EntityTypeConfigPanelProps> = ({ co
{/* 기존 필터 목록 */}
<div className="max-h-40 space-y-2 overflow-y-auto">
{Object.entries(safeConfig.filters || {}).map(([field, value]) => (
<div key={field} className="flex items-center space-x-2 rounded border p-2 text-sm">
<div key={field} className="flex items-center space-x-2 rounded border p-2 text-xs" style={{ fontSize: "12px" }}>
<Input
value={field}
onChange={(e) => updateFilter(field, e.target.value, value as string)}
@ -317,7 +317,7 @@ export const EntityTypeConfigPanel: React.FC<EntityTypeConfigPanelProps> = ({ co
<div className="mt-2">
<div className="flex items-center space-x-2 rounded border bg-white p-2">
<Search className="h-4 w-4 text-gray-400" />
<div className="text-muted-foreground flex-1 text-sm">
<div className="text-muted-foreground flex-1 text-xs" style={{ fontSize: "12px" }}>
{localValues.placeholder || `${localValues.referenceTable || "엔터티"}를 선택하세요`}
</div>
<Database className="h-4 w-4 text-gray-400" />

View File

@ -111,7 +111,7 @@ export const NumberTypeConfigPanel: React.FC<NumberTypeConfigPanelProps> = ({ co
</Label>
<Select value={localValues.format} onValueChange={(value) => updateConfig("format", value)}>
<SelectTrigger className="mt-1 h-8 text-xs">
<SelectTrigger className="mt-1 h-6 w-full px-2 py-0 text-xs" style={{ fontSize: "12px" }}>
<SelectValue placeholder="숫자 형식 선택" />
</SelectTrigger>
<SelectContent>

View File

@ -259,7 +259,7 @@ export const RadioTypeConfigPanel: React.FC<RadioTypeConfigPanelProps> = ({ conf
{(safeConfig.options || []).map((option) => (
<div key={option.value} className="flex items-center space-x-2">
<RadioGroupItem value={option.value} id={`preview-${option.value}`} />
<Label htmlFor={`preview-${option.value}`} className="text-sm">
<Label htmlFor={`preview-${option.value}`} className="text-xs" style={{ fontSize: "12px" }}>
{option.label}
</Label>
</div>

View File

@ -170,7 +170,7 @@ export const SelectTypeConfigPanel: React.FC<SelectTypeConfigPanelProps> = ({ co
value={localValues.placeholder}
onChange={(e) => updateConfig("placeholder", e.target.value)}
placeholder="옵션을 선택하세요"
className="mt-1 h-8 text-xs"
className="mt-1 h-6 w-full px-2 py-0 text-xs" style={{ fontSize: "12px" }} style={{ fontSize: "12px" }}
/>
</div>
@ -254,7 +254,7 @@ export const SelectTypeConfigPanel: React.FC<SelectTypeConfigPanelProps> = ({ co
onCheckedChange={(checked) => updateOption(index, "disabled", !!checked)}
title="비활성화"
/>
<Button size="sm" variant="ghost" onClick={() => removeOption(index)} className="h-8 w-8 p-1">
<Button size="sm" variant="ghost" onClick={() => removeOption(index)} className="h-6 w-8 p-1">
<X className="h-4 w-4" />
</Button>
</div>
@ -279,7 +279,7 @@ export const SelectTypeConfigPanel: React.FC<SelectTypeConfigPanelProps> = ({ co
size="sm"
onClick={addOption}
disabled={!newOption.label.trim() || !newOption.value.trim()}
className="h-8 w-8 p-1"
className="h-6 w-8 p-1"
>
<Plus className="h-4 w-4" />
</Button>

View File

@ -114,7 +114,7 @@ export const TextTypeConfigPanel: React.FC<TextTypeConfigPanelProps> = ({ config
</Label>
<Select value={localValues.format} onValueChange={(value) => updateConfig("format", value)}>
<SelectTrigger className="mt-1 h-8 text-xs">
<SelectTrigger className="mt-1 h-6 w-full px-2 py-0 text-xs" style={{ fontSize: "12px" }}>
<SelectValue placeholder="입력 형식 선택" />
</SelectTrigger>
<SelectContent>
@ -226,7 +226,7 @@ export const TextTypeConfigPanel: React.FC<TextTypeConfigPanelProps> = ({ config
</Label>
<Select value={localValues.autoValueType} onValueChange={(value) => updateConfig("autoValueType", value)}>
<SelectTrigger className="mt-1 h-8 text-xs">
<SelectTrigger className="mt-1 h-6 w-full px-2 py-0 text-xs" style={{ fontSize: "12px" }}>
<SelectValue placeholder="자동값 타입 선택" />
</SelectTrigger>
<SelectContent>

View File

@ -202,7 +202,7 @@ export const TextareaTypeConfigPanel: React.FC<TextareaTypeConfigPanelProps> = (
<Label className="text-sm font-medium text-gray-700"></Label>
<div className="mt-2">
<textarea
className="w-full rounded border border-gray-300 p-2 text-sm"
className="w-full rounded border border-gray-300 p-2 text-xs" style={{ fontSize: "12px" }}
rows={localValues.rows}
placeholder={localValues.placeholder || "텍스트를 입력하세요..."}
style={{

View File

@ -71,26 +71,16 @@ export const LeftUnifiedToolbar: React.FC<LeftUnifiedToolbarProps> = ({ buttons,
);
};
// 기본 버튼 설정 (컴포넌트와 편집 2개)
// 기본 버튼 설정 (통합 패널 1개)
export const defaultToolbarButtons: ToolbarButton[] = [
// 컴포넌트 그룹 (테이블 + 컴포넌트 탭)
// 통합 패널 (컴포넌트 + 편집 탭)
{
id: "components",
label: "컴포넌트",
id: "unified",
label: "패널",
icon: <Layout className="h-5 w-5" />,
shortcut: "C",
group: "source",
panelWidth: 400,
},
// 편집 그룹 (속성 + 스타일 & 해상도 탭)
{
id: "properties",
label: "편집",
icon: <Settings className="h-5 w-5" />,
shortcut: "P",
group: "editor",
panelWidth: 400,
group: "source",
panelWidth: 240,
},
];

View File

@ -938,7 +938,7 @@ export function FlowWidget({
setStepDataPage(1); // 페이지 크기 변경 시 첫 페이지로
}}
>
<SelectTrigger className="h-8 w-20 text-xs">
<SelectTrigger className="h-6 w-full px-2 py-0 text-xs" style={{ fontSize: "12px" }}>
<SelectValue />
</SelectTrigger>
<SelectContent>

View File

@ -33,7 +33,8 @@ export default function InputWidget({ widget, value, onChange, className }: Inpu
onChange={handleChange}
required={widget.required}
readOnly={widget.readonly}
className={cn("h-9 w-full text-sm", widget.readonly && "bg-muted/50 cursor-not-allowed")}
className={cn("h-6 w-full text-xs", widget.readonly && "bg-muted/50 cursor-not-allowed")}
style={{ fontSize: "12px" }}
/>
</div>
);

View File

@ -53,7 +53,7 @@ export default function SelectWidget({ widget, value, onChange, options = [], cl
</Label>
)}
<Select value={value} onValueChange={handleChange} disabled={widget.readonly}>
<SelectTrigger className="h-9 w-full text-sm">
<SelectTrigger className="h-6 w-full px-2 py-0 text-xs" style={{ fontSize: "12px" }}>
<SelectValue placeholder={widget.placeholder || "선택해주세요"} />
</SelectTrigger>
<SelectContent>

View File

@ -20,18 +20,18 @@ function SelectValue({ ...props }: React.ComponentProps<typeof SelectPrimitive.V
function SelectTrigger({
className,
size = "default",
size = "xs",
children,
...props
}: React.ComponentProps<typeof SelectPrimitive.Trigger> & {
size?: "sm" | "default";
size?: "xs" | "sm" | "default";
}) {
return (
<SelectPrimitive.Trigger
data-slot="select-trigger"
data-size={size}
className={cn(
"border-input data-[placeholder]:text-muted-foreground [&_svg:not([class*='text-'])]:text-muted-foreground focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:bg-input/30 dark:hover:bg-input/50 flex w-48 items-center justify-between gap-2 rounded-md border bg-transparent px-3 py-2 text-sm whitespace-nowrap shadow-xs transition-[color,box-shadow] outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50 data-[size=default]:h-9 data-[size=sm]:h-8 *:data-[slot=select-value]:line-clamp-1 *:data-[slot=select-value]:flex *:data-[slot=select-value]:items-center *:data-[slot=select-value]:gap-2 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
"border-input data-[placeholder]:text-muted-foreground [&_svg:not([class*='text-'])]:text-muted-foreground focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:bg-input/30 dark:hover:bg-input/50 flex w-48 items-center justify-between gap-2 rounded-md border bg-transparent text-sm whitespace-nowrap shadow-xs transition-[color,box-shadow] outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50 data-[size=default]:h-9 data-[size=default]:px-3 data-[size=default]:py-2 data-[size=sm]:h-8 data-[size=sm]:px-3 data-[size=sm]:py-1 data-[size=xs]:h-6 data-[size=xs]:px-2 data-[size=xs]:py-0 *:data-[slot=select-value]:line-clamp-1 *:data-[slot=select-value]:flex *:data-[slot=select-value]:items-center *:data-[slot=select-value]:gap-2 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
className,
)}
{...props}
@ -51,7 +51,7 @@ function SelectContent({
...props
}: React.ComponentProps<typeof SelectPrimitive.Content>) {
return (
<SelectPrimitive.Portal container={document.querySelector('[data-radix-portal]') || document.body}>
<SelectPrimitive.Portal container={document.querySelector("[data-radix-portal]") || document.body}>
<SelectPrimitive.Content
data-slot="select-content"
className={cn(