import type { Meta, StoryObj } from "@storybook/react-vite" import { useId, useState, type ComponentProps, type CSSProperties, type ReactNode } from "react" import { Card, CardContent, CardHeader, CardTitle, Input, Label, Textarea, Table, TableBody, TableCell, TableHead, TableHeader, TableRow, Tabs, TabsContent, TabsList, TabsTrigger, } from "@hm-design/ui" import { StateBoard, type BoardState } from "@/components/story-board" import { StoryPage, StoryPageHeader, StorySection } from "@/components/story-page" // Representative "Tabs" Story shows default Primary, explicit API comparisons and Secondary; Legacy stays verification-only. // Fill panels use the actual parent surface without a nested box. The representative page sets its own content padding. // D-02 is shipped by the public Tabs theme mapping (Primary top White alpha .8). Legacy stays compatibility-only. type Variant = "primary" | "secondary" type ListProps = Pick, "fill" | "panelSurface"> // Primary = Fill + panelSurface="content", Secondary = Fill + panelSurface="surface" (2026-10-06 사용자 결정). const variantProps = { primary: { listProps: {}, surface: "bg-background" }, secondary: { listProps: { fill: true, panelSurface: "surface" }, surface: "bg-card" }, } as const const previewPanelSpacing = "px-4 pt-3 pb-6" function Specimen({ variant = "primary", defaultValue = "menu2", disabledSecond, count = 3, labels, listProps, panelSpacing = "px-0 py-6", }: { variant?: Variant defaultValue?: string disabledSecond?: boolean count?: number labels?: string[] listProps?: ListProps panelSpacing?: string }) { const { listProps: defaults, surface } = variantProps[variant] const effectiveListProps: ListProps = listProps ?? defaults const legacy = effectiveListProps.fill === false const items = labels?.map((label, i) => ({ value: `menu${i + 1}`, label })) ?? Array.from({ length: count }, (_, i) => ({ value: `menu${i + 1}`, label: `메뉴 ${i + 1}` })) return ( {items.map(({ value, label }, i) => ( {label} ))} {items.map(({ value }, i) => ( 메뉴 {i + 1} 콘텐츠 ))} ) } const longLabels = ["기본 정보", "보상 협의 및 계약 진행 현황", "토지 및 지장물 조사 내역"] // Component composition reference, not a new application screen. All visual controls use public HM exports. // Input state lives above the panels so the draft survives Radix's inactive-panel unmount. function SurfaceUsage({ inCard = false }: { inCard?: boolean }) { const id = useId() const [project, setProject] = useState("") const [purpose, setPurpose] = useState("") // 2026-11-13: both examples use the same panel inset (16 / 12 / 24). In the Card, the Card / CardContent padding stays as is; // the extra inset applies only to the panel below the tab header, so the header keeps its size and position. const panelSpacing = previewPanelSpacing const tabs = ( 기본 정보 일정·산출물
setProject(event.target.value)} placeholder="프로젝트명을 입력하세요" />