diff --git a/docs/reports/storybook-ui-simplification-2026-10-22.md b/docs/reports/storybook-ui-simplification-2026-10-22.md new file mode 100644 index 0000000..7e32476 --- /dev/null +++ b/docs/reports/storybook-ui-simplification-2026-10-22.md @@ -0,0 +1,37 @@ +# Storybook UI 중심 간소화 (2026-10-22) + +기준: `main` `aa8b7f8`. Storybook 전용 파일만 수정했습니다. 패키지 컴포넌트·공개 API·Theme Token·Story ID·export는 변경하지 않았습니다. + +## 범위 + +- 조사: Story 파일 80개, Story 359개(사이드바 표시 83개, `verification`/`internal` 숨김 276개) +- 적용: 사이드바 표시 Story 83개 +- 숨김 Story 276개는 테스트 기준 화면이므로 그대로 둡니다. 숨김 Story와 공유하는 State note(Input Readonly, Textarea Hover/Readonly, Progress, Table 등)도 유지합니다. + +## 기준 + +| 유형 | 처리 | +|---|---| +| 상단 분류 라벨 `HM DESIGN SYSTEM / …` | 표시 Story에서 제거. `StoryPageHeader`의 `kicker`는 선택 Prop이 되었고 숨김 Story는 계속 전달합니다. | +| 섹션 제목을 반복하는 설명(`기본 Tooltip입니다.`, `side: …`, `className 확장입니다.`) | 제거 | +| 당연한 조작 안내(`버튼을 눌러 엽니다`, `포인터를 올려 확인합니다`) | 제거 | +| 긴 페이지·섹션 설명 | 핵심만 한 줄로 축약 | +| 내부 기술 설명(Figma 노드, 날짜, 내부 토큰명, CSS 파일명) | 화면에서 제거. 동작 상세는 `packages/sw/ai/COMPONENT_CATALOG.md`, `DESIGN_RULES.md`, `docs/components/*.md`에 이미 있습니다. | +| CENTER 반복 경계 안내(`CENTER_BOUNDARY`) | 한 줄로 축약하고 유지 | +| 필수 규격·제한(px 크기, 허용 조합, Hover 없음, 가상 데이터, 실제 인원 아님, 테스트 로고, 미확정 TBD/Candidate/Q3, 고정 날짜, GNB_ONLY Sidebar 금지) | 유지 | +| OrgChart 설명 | 제거하지 않고 축약만 합니다(verify-p8/p9가 `.sb-page-description`, `.sb-page-section-description` 스타일을 읽음). | +| SW 페이지 설명 | 기존 CSS가 이미 화면에서 숨기므로 표시 변화는 분류 라벨 제거뿐입니다. Home Menu만 소스 문구를 함께 축약했습니다. | + +## 결과 (1440 × 900, 첫 UI 영역 상단 위치) + +- 표시 설명 글자 수: 15,240 → 7,431 +- 첫 UI 위치: 평균 28px 위로 이동(최소 24, 최대 81). Button 290 → 266, Dialog 290 → 234, Resizable 266 → 210, CENTER Overview 317 → 236, SW 페이지 234 → 210 +- Story ID 359개는 변경 전후 동일합니다. + +## 검증 + +- `tsc -p tsconfig.app.json --noEmit` PASS, `npm run test:guard` 94/94, `npm run check:ai-docs` PASS +- `build-storybook` 성공. Story 359개를 직접 URL로 렌더했을 때 오류 화면은 없었습니다. Avatar `all`·`fallback-error`의 404는 의도된 이미지 실패 예시이며 변경 전에도 같습니다. +- `packages/sw/tests/storybook-simplification.browser.mjs` 9/9 PASS +- `examples/org-chart/verify-p9.mjs`: 변경 전 빌드로 만든 로컬 기준에 대해 변경 후 67 PASS / 17 FAIL입니다. 변경 전 빌드도 같은 17건이 FAIL이므로 기존 이슈입니다. +- `packages/sw/tests/integrated-visual.browser.mjs` capture/compare: 숨김 검증 Story 6종(detail-buttons 등)은 동일합니다. 표시 Story(overview, logo-slot, responsive-more, property-panel-compare)의 차이는 모두 분류 라벨 제거에 따른 세로 이동(24px, Overview는 12px)이며 그 외 픽셀 차이는 없습니다. 시각 기준 이미지는 갱신하지 않았습니다. diff --git a/src/center/center-facility.stories.tsx b/src/center/center-facility.stories.tsx index 5d6e5ba..1173a6e 100644 --- a/src/center/center-facility.stories.tsx +++ b/src/center/center-facility.stories.tsx @@ -10,7 +10,7 @@ import { RoadsideReferenceDemo, TunnelReferenceDemo, } from "@hm-design/center-graphic/reference" -import { STORY_KICKER, StoryPage, StoryPageHeader, StorySection } from "@/components/story-page" +import { StoryPage, StoryPageHeader, StorySection } from "@/components/story-page" import { CENTER_BOUNDARY, withRepresentation } from "./center-shared" // Owners: ui-viz docs/visualization/facility.md and facility-assets.md (128 approved SVG references, shipped unchanged). @@ -30,9 +30,8 @@ const page = (name: string, Demo: ComponentType): Story => ({ render: () => ( {withRepresentation(() => )} @@ -54,11 +53,10 @@ export const Linked: Story = { render: () => ( - CENTER 시설물 그래픽입니다. 승인 SVG Reference를 위치도(Position Map)와 실사화(Actual / Detail)로 표시합니다. + 승인 SVG Reference · 위치도 / 실사화
{CENTER_BOUNDARY} diff --git a/src/center/center-information.stories.tsx b/src/center/center-information.stories.tsx index 3b1c179..3d96007 100644 --- a/src/center/center-information.stories.tsx +++ b/src/center/center-information.stories.tsx @@ -1,6 +1,6 @@ import type { Meta, StoryObj } from "@storybook/react-vite" import { CenterInformationDisplayReferenceDemo } from "@hm-design/center-graphic/reference" -import { STORY_KICKER, StoryPage, StoryPageHeader, StorySection } from "@/components/story-page" +import { StoryPage, StoryPageHeader, StorySection } from "@/components/story-page" import { CENTER_BOUNDARY, withRepresentation } from "./center-shared" // Owner: ui-viz docs/patterns/center-information-presentation.md and center-information-{box,table,emphasis}.md. @@ -18,9 +18,8 @@ export const Information: Story = { render: () => ( {withRepresentation(() => ( diff --git a/src/center/center-overview.stories.tsx b/src/center/center-overview.stories.tsx index 3894a3b..5ce8216 100644 --- a/src/center/center-overview.stories.tsx +++ b/src/center/center-overview.stories.tsx @@ -1,5 +1,5 @@ import type { Meta, StoryObj } from "@storybook/react-vite" -import { STORY_KICKER, StoryPage, StoryPageHeader, StorySection } from "@/components/story-page" +import { StoryPage, StoryPageHeader, StorySection } from "@/components/story-page" import { CENTER_BOUNDARY, CenterFrame, SCALE_NOTE, StatusTable } from "./center-shared" // Mirrors the ui-viz docs/governance/center-domain.md §5 registry rows. The values stay in the owner documents. @@ -28,13 +28,13 @@ export const Overview: Story = { name: "Overview", render: () => ( - +
- +

{SCALE_NOTE}

- +
diff --git a/src/center/center-shared.tsx b/src/center/center-shared.tsx index 3e823c5..44dacb5 100644 --- a/src/center/center-shared.tsx +++ b/src/center/center-shared.tsx @@ -5,7 +5,7 @@ import "./center-stories.css" // CENTER is a separate domain from the UI Component System. These stories present the packaged CENTER components and the // reference demo pages; they do not own, create or promote CENTER contract values (see docs/center-graphic/README.md). export const CENTER_BOUNDARY = - "CENTER Web Reference 렌더링입니다. Canonical 값·상태는 ui-viz CENTER owner 문서가 소유하며 HOLD / TBD / Candidate / OWNER_DECISION_REQUIRED를 이 화면이 확정하지 않습니다." + "Reference 렌더링 · HOLD / TBD / Candidate 값은 ui-viz owner 문서 기준이며 이 화면이 확정하지 않음" export const SCALE_NOTE = "제작 대상이 7680 × 2160이면 CENTER 그래픽을 100%, 3840 × 2160이면 75%로 표시합니다. Storybook 화면 크기는 배율을 정하지 않으며, 다른 제작 해상도의 배율은 정해지지 않았습니다. 제작 대상은 주소에 centerResolution=3840x2160 을 붙여 바꿉니다." diff --git a/src/center/center-spatial.stories.tsx b/src/center/center-spatial.stories.tsx index 82459af..35f8c15 100644 --- a/src/center/center-spatial.stories.tsx +++ b/src/center/center-spatial.stories.tsx @@ -1,7 +1,7 @@ import type { Meta, StoryObj } from "@storybook/react-vite" import { RouteLine } from "@hm-design/center-graphic" import { CenterSpatialInformationReferenceDemo } from "@hm-design/center-graphic/reference" -import { STORY_KICKER, StoryPage, StoryPageHeader, StorySection } from "@/components/story-page" +import { StoryPage, StoryPageHeader, StorySection } from "@/components/story-page" import { CENTER_BOUNDARY, withRepresentation } from "./center-shared" // Owners: ui-viz docs/visualization/route.md, spatial-map.md, spatial-section.md, composition.md. @@ -20,9 +20,8 @@ export const Spatial: Story = { render: () => ( {withRepresentation(() => )} diff --git a/src/center/center-title.stories.tsx b/src/center/center-title.stories.tsx index 84c4ac9..9552f48 100644 --- a/src/center/center-title.stories.tsx +++ b/src/center/center-title.stories.tsx @@ -1,7 +1,7 @@ import type { Meta, StoryObj } from "@storybook/react-vite" import { CenterTitle, CENTER_TITLE_COMPOSITIONS, type CenterTitleComposition } from "@hm-design/center-graphic" import { CenterTitleReferenceDemo } from "@hm-design/center-graphic/reference" -import { STORY_KICKER, StoryPage, StoryPageHeader, StorySection } from "@/components/story-page" +import { StoryPage, StoryPageHeader, StorySection } from "@/components/story-page" import { CENTER_BOUNDARY, withRepresentation } from "./center-shared" // Owner: ui-viz docs/components/center-title.md. Title Resolution B numeric output is TBD; the per-Type palette is SCOPED_DESIGN_APPROVAL. @@ -21,9 +21,8 @@ export const Compositions: Story = { render: () => ( {withRepresentation(() => )} diff --git a/src/components/accordion.stories.tsx b/src/components/accordion.stories.tsx index 4cc1110..9b9ce81 100644 --- a/src/components/accordion.stories.tsx +++ b/src/components/accordion.stories.tsx @@ -2,7 +2,7 @@ import type { ReactNode } from "react" import type { Meta, StoryObj } from "@storybook/react-vite" import { Accordion, AccordionContent, AccordionItem, AccordionTrigger } from "@hm-design/ui" import { StateBoard } from "@/components/story-board" -import { STORY_KICKER, StoryPage, StoryPageHeader, StorySection } from "@/components/story-page" +import { StoryPage, StoryPageHeader, StorySection } from "@/components/story-page" // The representative "Accordion" Story puts each Radix mode on one page with real, clickable items. The same sections also exist // as Stories tagged `verification`, which the sidebar hides by default (see .storybook/main.ts). Modes use the Radix API @@ -126,12 +126,11 @@ export const All: Story = { render: () => ( - {board("single")} - + {board("single")} + {board("collapsible-single", "multiple")} {board("disabled")} diff --git a/src/components/alert-dialog.stories.tsx b/src/components/alert-dialog.stories.tsx index 8641e13..6ae81a7 100644 --- a/src/components/alert-dialog.stories.tsx +++ b/src/components/alert-dialog.stories.tsx @@ -11,7 +11,7 @@ import { AlertDialogTrigger, Button, } from "@hm-design/ui" -import { STORY_KICKER, StoryPage, StoryPageHeader, StorySection } from "@/components/story-page" +import { StoryPage, StoryPageHeader, StorySection } from "@/components/story-page" // Alert Dialog is a modal Radix overlay (Portal) for a decision that must be confirmed or cancelled: no Close (X), no outside // dismiss. The representative Story opens the real dialogs; the same cases start open in the verification Stories. @@ -74,14 +74,13 @@ export const All: Story = { render: () => ( - + - + diff --git a/src/components/alert.stories.tsx b/src/components/alert.stories.tsx index 9a0f9aa..309d9ba 100644 --- a/src/components/alert.stories.tsx +++ b/src/components/alert.stories.tsx @@ -2,7 +2,7 @@ import type { Meta, StoryObj } from "@storybook/react-vite" import { InfoIcon, TriangleAlertIcon } from "lucide-react" import { Alert, AlertDescription, AlertTitle } from "@hm-design/ui" import { StateBoard } from "@/components/story-board" -import { STORY_KICKER, StoryPage, StoryPageHeader, StorySection } from "@/components/story-page" +import { StoryPage, StoryPageHeader, StorySection } from "@/components/story-page" const meta = { title: "Components/Feedback/Alert", @@ -27,9 +27,8 @@ export const All: Story = { render: () => ( - + ( {board("r169")} - {board("r43", "r11", "video")} - {board("card")} + {board("r43", "r11", "video")} + {board("card")} ), } diff --git a/src/components/avatar.stories.tsx b/src/components/avatar.stories.tsx index 900079b..005e871 100644 --- a/src/components/avatar.stories.tsx +++ b/src/components/avatar.stories.tsx @@ -1,7 +1,7 @@ import type { Meta, StoryObj } from "@storybook/react-vite" import { Avatar, AvatarFallback, AvatarImage } from "@hm-design/ui" import { StateBoard } from "@/components/story-board" -import { STORY_KICKER, StoryPage, StoryPageHeader, StorySection } from "@/components/story-page" +import { StoryPage, StoryPageHeader, StorySection } from "@/components/story-page" // Images are inline data URIs so the Story does not depend on the network. "Broken" uses an address that cannot load so the // Radix fallback shows. Radix renders the image only after it loads. @@ -86,13 +86,12 @@ export const All: Story = { render: () => ( {board("image")} {board("fallback")} - {board("composition")} + {board("composition")} ), } diff --git a/src/components/badge.stories.tsx b/src/components/badge.stories.tsx index 0959bb0..72c18e2 100644 --- a/src/components/badge.stories.tsx +++ b/src/components/badge.stories.tsx @@ -2,7 +2,7 @@ import type { Meta, StoryObj } from "@storybook/react-vite" import { CheckIcon } from "lucide-react" import { Badge } from "@hm-design/ui" import { StateBoard } from "@/components/story-board" -import { STORY_KICKER, StoryPage, StoryPageHeader, StorySection } from "@/components/story-page" +import { StoryPage, StoryPageHeader, StorySection } from "@/components/story-page" const variants = ["default", "secondary", "destructive", "outline"] as const @@ -29,11 +29,10 @@ export const All: Story = { render: () => ( - + Badge @@ -70,7 +69,7 @@ export const All: Story = { ]} /> - + ( {board("basic")} - {board("ellipsis", "custom")} + {board("ellipsis", "custom")} {board("long")} ), diff --git a/src/components/button.stories.tsx b/src/components/button.stories.tsx index f9f06cf..983e8c6 100644 --- a/src/components/button.stories.tsx +++ b/src/components/button.stories.tsx @@ -3,7 +3,7 @@ import { DownloadIcon } from "lucide-react" import type { Meta, StoryObj } from "@storybook/react-vite" import { Button, type ButtonAppearance } from "@hm-design/ui" import { StateBoard } from "@/components/story-board" -import { STORY_KICKER, StoryPage, StoryPageHeader, StorySection } from "@/components/story-page" +import { StoryPage, StoryPageHeader, StorySection } from "@/components/story-page" // Story structure follows ui_viz (implementations/web/storybook/Button.stories.jsx): // one representative "Button" Story shows kinds, sizes and states on a single screen; the same sections also exist @@ -222,21 +222,17 @@ export const All: Story = { parameters: { layout: "fullscreen" }, render: () => ( - - + + - + - + - + ( {board("single")} {board("range", "months")} - {board("disabled")} + {board("disabled")} ), } diff --git a/src/components/card.stories.tsx b/src/components/card.stories.tsx index 04b7d84..ee7c0f2 100644 --- a/src/components/card.stories.tsx +++ b/src/components/card.stories.tsx @@ -4,7 +4,7 @@ import { Button } from "@hm-design/ui" import { Card, CardAction, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, type CardSurface } from "@hm-design/ui" import { Input } from "@hm-design/ui" import { StateBoard } from "@/components/story-board" -import { STORY_KICKER, StoryPage, StoryPageHeader, StorySection } from "@/components/story-page" +import { StoryPage, StoryPageHeader, StorySection } from "@/components/story-page" // Story structure follows Button / Input / Select: one representative "Card" Story shows the ui_viz cases on one page, // the same specimens also exist as separate Stories tagged `verification` (hidden from the sidebar, see .storybook/main.ts). @@ -71,14 +71,13 @@ export const All: Story = { render: () => ( - + }]} /> - + ( {board("basic")} - {board("multiple", "loop", "vertical")} - {board("media")} + {board("multiple", "loop", "vertical")} + {board("media")} ), } diff --git a/src/components/checkbox.stories.tsx b/src/components/checkbox.stories.tsx index 19dfbe5..afe1ddf 100644 --- a/src/components/checkbox.stories.tsx +++ b/src/components/checkbox.stories.tsx @@ -2,7 +2,7 @@ import { useId, useState, type ReactNode } from "react" import type { Meta, StoryObj } from "@storybook/react-vite" import { Checkbox, Label } from "@hm-design/ui" import { StateBoard } from "@/components/story-board" -import { STORY_KICKER, StoryPage, StoryPageHeader, StorySection } from "@/components/story-page" +import { StoryPage, StoryPageHeader, StorySection } from "@/components/story-page" // Current HM Checkbox. ui-viz has no Checkbox spec, so it was reference only. // The option label is the HM Label; its foreground role for Checkbox options is still TBD in ui_viz. @@ -48,9 +48,8 @@ export const All: Story = { render: () => ( - + {(id) => } }]} /> diff --git a/src/components/collapsible.stories.tsx b/src/components/collapsible.stories.tsx index 2da9cf9..497777f 100644 --- a/src/components/collapsible.stories.tsx +++ b/src/components/collapsible.stories.tsx @@ -3,7 +3,7 @@ import type { Meta, StoryObj } from "@storybook/react-vite" import { ChevronDownIcon } from "lucide-react" import { Button, Collapsible, CollapsibleContent, CollapsibleTrigger } from "@hm-design/ui" import { StateBoard } from "@/components/story-board" -import { STORY_KICKER, StoryPage, StoryPageHeader, StorySection } from "@/components/story-page" +import { StoryPage, StoryPageHeader, StorySection } from "@/components/story-page" // The representative "Collapsible" Story shows one independent disclosure per state with real, clickable triggers. The same // sections also exist as Stories tagged `verification` (hidden from the sidebar). Collapsible is a single disclosure: no divider @@ -81,13 +81,12 @@ export const All: Story = { render: () => ( {board("closed")} {board("open", "disabled")} - {board("long", "controlled")} + {board("long", "controlled")} ), } diff --git a/src/components/combobox.stories.tsx b/src/components/combobox.stories.tsx index 89ed4b3..71a50c9 100644 --- a/src/components/combobox.stories.tsx +++ b/src/components/combobox.stories.tsx @@ -2,7 +2,7 @@ import { useState, type ReactNode } from "react" import type { Meta, StoryObj } from "@storybook/react-vite" import { Combobox, Select, SelectContent, SelectItem, SelectTrigger, SelectValue, type ComboboxOption } from "@hm-design/ui" import { StateBoard } from "@/components/story-board" -import { STORY_KICKER, StoryPage, StoryPageHeader, StorySection } from "@/components/story-page" +import { StoryPage, StoryPageHeader, StorySection } from "@/components/story-page" // Combobox is a Popover + Command composition (search + single choice); Select stays for short lists without search. // The representative Story shows real comboboxes; the same specimens also exist as Stories tagged `verification` (hidden from the @@ -122,12 +122,11 @@ export const All: Story = { render: () => ( - {board("empty")} - + {board("empty")} + ( {board("basic")} {board("grouped")} diff --git a/src/components/context-menu.stories.tsx b/src/components/context-menu.stories.tsx index 3ea7574..00d1459 100644 --- a/src/components/context-menu.stories.tsx +++ b/src/components/context-menu.stories.tsx @@ -16,7 +16,7 @@ import { ContextMenuSubTrigger, ContextMenuTrigger, } from "@hm-design/ui" -import { STORY_KICKER, StoryPage, StoryPageHeader, StorySection } from "@/components/story-page" +import { StoryPage, StoryPageHeader, StorySection } from "@/components/story-page" // Context Menu opens from pointer context (right click, the context-menu key / Shift+F10, long press) on its trigger area. // The representative Story is a target area: right click it. Radix owns keyboard navigation, focus return and Escape. @@ -83,11 +83,10 @@ export const All: Story = { render: () => ( - + diff --git a/src/components/date-picker.stories.tsx b/src/components/date-picker.stories.tsx index c12b79b..8011703 100644 --- a/src/components/date-picker.stories.tsx +++ b/src/components/date-picker.stories.tsx @@ -2,7 +2,7 @@ import { useState, type ReactNode } from "react" import type { Meta, StoryObj } from "@storybook/react-vite" import { DatePicker } from "@hm-design/ui" import { StateBoard } from "@/components/story-board" -import { STORY_KICKER, StoryPage, StoryPageHeader, StorySection } from "@/components/story-page" +import { StoryPage, StoryPageHeader, StorySection } from "@/components/story-page" // DatePicker is a Popover + Calendar composition packaged as a component (value handling, trigger text, close on select). // The representative Story shows real pickers; the same specimens also exist as Stories tagged `verification` (hidden from the @@ -116,14 +116,13 @@ export const All: Story = { render: () => ( {board("empty")} - {board("medium")} + {board("medium")} {board("selected", "controlled", "disabled-dates", "disabled")} - {board("format")} + {board("format")} ), } diff --git a/src/components/dialog.stories.tsx b/src/components/dialog.stories.tsx index c51d405..0d222ab 100644 --- a/src/components/dialog.stories.tsx +++ b/src/components/dialog.stories.tsx @@ -4,7 +4,7 @@ import { Button } from "@hm-design/ui" import { Dialog, DialogBody, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, DialogTrigger } from "@hm-design/ui" import { Input } from "@hm-design/ui" import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@hm-design/ui" -import { STORY_KICKER, StoryPage, StoryPageHeader, StorySection } from "@/components/story-page" +import { StoryPage, StoryPageHeader, StorySection } from "@/components/story-page" // Dialog is an overlay (Radix Portal), so it does not fit the StateBoard. The representative Story is a row of triggers that open // the real Dialog for each ui_viz case (dialog.md §9 Reference Viewer examples); the same cases also exist as separate Stories tagged @@ -182,21 +182,19 @@ export const All: Story = { render: () => ( - + - +
- +
diff --git a/src/components/drawer.stories.tsx b/src/components/drawer.stories.tsx index 44137c0..822d5e2 100644 --- a/src/components/drawer.stories.tsx +++ b/src/components/drawer.stories.tsx @@ -2,7 +2,7 @@ import type { Meta, StoryObj } from "@storybook/react-vite" // Usage: preserved native label fixtures do not define a new-screen exception. Use public Label // for supported fields (docs/components/label.md §5); copy only actions requested by the screen. import { Button, Drawer, DrawerBody, DrawerClose, DrawerContent, DrawerDescription, DrawerFooter, DrawerHeader, DrawerTitle, DrawerTrigger, Input } from "@hm-design/ui" -import { STORY_KICKER, StoryPage, StoryPageHeader, StorySection } from "@/components/story-page" +import { StoryPage, StoryPageHeader, StorySection } from "@/components/story-page" // Drawer is a modal vaul overlay (Portal). The representative Story opens the real Drawer from its triggers; drag the handle or // the panel down to dismiss. The same cases start open in the verification Stories. vaul owns the drag, Radix the focus and ARIA. @@ -101,14 +101,13 @@ export const All: Story = { render: () => ( - + - +
diff --git a/src/components/dropdown-menu.stories.tsx b/src/components/dropdown-menu.stories.tsx index b8f5229..ff48097 100644 --- a/src/components/dropdown-menu.stories.tsx +++ b/src/components/dropdown-menu.stories.tsx @@ -17,7 +17,7 @@ import { DropdownMenuSubTrigger, DropdownMenuTrigger, } from "@hm-design/ui" -import { STORY_KICKER, StoryPage, StoryPageHeader, StorySection } from "@/components/story-page" +import { StoryPage, StoryPageHeader, StorySection } from "@/components/story-page" // Dropdown Menu is a Radix overlay (Portal), so the representative Story is a trigger that opens the real menu, the same way as // Dialog. The verification Story starts open. Radix owns keyboard navigation, focus return and Escape. @@ -85,11 +85,9 @@ export const All: Story = { render: () => ( - + diff --git a/src/components/hover-card.stories.tsx b/src/components/hover-card.stories.tsx index a4e729b..2364591 100644 --- a/src/components/hover-card.stories.tsx +++ b/src/components/hover-card.stories.tsx @@ -1,6 +1,6 @@ import type { Meta, StoryObj } from "@storybook/react-vite" import { HoverCard, HoverCardContent, HoverCardTrigger } from "@hm-design/ui" -import { STORY_KICKER, StoryPage, StoryPageHeader, StorySection } from "@/components/story-page" +import { StoryPage, StoryPageHeader, StorySection } from "@/components/story-page" // Hover Card is a Radix overlay (Portal) for a richer preview than Tooltip. The representative Story shows real triggers // (hover or focus to open); the verification Story starts one open. Radix owns the open / close delay and the hover bridge. @@ -54,14 +54,13 @@ export const All: Story = { render: () => ( - + - + diff --git a/src/components/input.stories.tsx b/src/components/input.stories.tsx index db7d581..814645e 100644 --- a/src/components/input.stories.tsx +++ b/src/components/input.stories.tsx @@ -2,7 +2,7 @@ import { useId, type ComponentProps, type ReactNode } from "react" import type { Meta, StoryObj } from "@storybook/react-vite" import { Input, type InputSize } from "@hm-design/ui" import { StateBoard } from "@/components/story-board" -import { STORY_KICKER, StoryPage, StoryPageHeader, StorySection } from "@/components/story-page" +import { StoryPage, StoryPageHeader, StorySection } from "@/components/story-page" // Story structure follows ui_viz (implementations/web/storybook/Input.stories.jsx and InputSizes.stories.jsx): // one representative "Input" Story shows the sizes and every state on one page; the same specimens also exist as @@ -126,17 +126,16 @@ export const All: Story = { render: () => ( - + }]} /> - + - + }, @@ -145,7 +144,7 @@ export const All: Story = { ]} /> - + }, diff --git a/src/components/label.stories.tsx b/src/components/label.stories.tsx index e846732..d200f1e 100644 --- a/src/components/label.stories.tsx +++ b/src/components/label.stories.tsx @@ -1,7 +1,7 @@ import type { Meta, StoryObj } from "@storybook/react-vite" import { Input, Label, Select, SelectTrigger, SelectValue, SelectContent, SelectItem } from "@hm-design/ui" import { StateBoard } from "@/components/story-board" -import { STORY_KICKER, StoryPage, StoryPageHeader, StorySection } from "@/components/story-page" +import { StoryPage, StoryPageHeader, StorySection } from "@/components/story-page" // Label has no standalone ui_viz spec. Its typography and color are the Field Label role owned by Input / Textarea // (14/20/500, color.fg.secondary). Required star and messages are composed here as a consumer would (not part of Label). @@ -28,9 +28,8 @@ export const All: Story = { render: () => ( - +
changeExample(event.target.value as Selection)}> diff --git a/src/sw/sw-header.stories.tsx b/src/sw/sw-header.stories.tsx index 03f7dca..b40d69b 100644 --- a/src/sw/sw-header.stories.tsx +++ b/src/sw/sw-header.stories.tsx @@ -453,7 +453,6 @@ export const LogoSlot: Story = { render: () => ( @@ -785,7 +784,7 @@ export const ResponsiveMore: Story = { parameters: { controls: { disable: true } }, render: () => ( - + {MORE_WIDTHS.map(width => ( @@ -931,5 +930,5 @@ function PropertyCompare() { } /** Rendered by SW/Popup › Property Panel · 4개 비교 (sw-property-panel.stories.tsx, ID sw-header--property-panel-compare). */ export function PropertyPanelComparePage() { - return + return } diff --git a/src/sw/sw-popup.stories.tsx b/src/sw/sw-popup.stories.tsx index 9a63f59..73648cc 100644 --- a/src/sw/sw-popup.stories.tsx +++ b/src/sw/sw-popup.stories.tsx @@ -12,7 +12,6 @@ import "./sw-integrated-stories.css" // SWPopup (2026-10-19): the SW property window frame with free children. Public API only, like a consuming // project. HM UI components are placed inside to show that the content is not restricted. -const KICKER = "HM DESIGN SYSTEM / SW" const LAYERS: SWHeaderLayer[] = [ { id: "0", name: "0", color: "#ffffff" }, { id: "wall", name: "WALL", color: "#ff4242" }, @@ -159,7 +158,7 @@ function PopupPage() { const [log, record] = useLog() return ( - {log} @@ -188,7 +187,7 @@ function StackPage() { const rows = Array.from({ length: 30 }, (_, index) => index + 1) return ( - {log} diff --git a/src/sw/sw-viewer.stories.tsx b/src/sw/sw-viewer.stories.tsx index 12daa3a..c516570 100644 --- a/src/sw/sw-viewer.stories.tsx +++ b/src/sw/sw-viewer.stories.tsx @@ -86,7 +86,7 @@ export const ViewerHeader: Story = { name: "Viewer Header", render: () => ( - + @@ -278,7 +278,7 @@ export const ContentVariants: Story = { const [snap, setSnap] = useState(true) return ( - + }> @@ -333,7 +333,7 @@ export const Responsive: Story = { const demo = useViewerDemo({ initialDocument: SAMPLES[1].name }) return ( - +
{[1920, 1440, 1280, 950, 860, 760, 520].map(width => ( @@ -372,7 +372,7 @@ export const CompareWithSWHeader: Story = { name: "SWHeader vs Viewer Header", render: () => ( - +
@@ -397,7 +397,7 @@ export const Logo: Story = { ] return ( - +
{rows.map(row => (