diff --git a/src/components/accordion.stories.tsx b/src/components/accordion.stories.tsx index 3ccbd66..7e9763e 100644 --- a/src/components/accordion.stories.tsx +++ b/src/components/accordion.stories.tsx @@ -1,7 +1,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 { StateBoard, type BoardState } from "@/components/story-board" 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 @@ -115,8 +115,21 @@ const meta = { title: "Components/Disclosure/Accordion", parameters: { layout: " export default meta type Story = StoryObj -const board = (...ids: string[]) => ( - ids.includes(s.id)).map((s) => ({ id: s.id, label: s.label, children: s.node }))} /> +// Representative-page layout (Storybook presentation only): equal columns on PC (iframe width 1000px and up), one column +// below that. Each specimen sits in its own single-column StateBoard (min larger than any column), so the title, divider and +// specimen start line up, unused columns stay empty and `items-start` lets an opened item grow without touching its neighbors. +function StateGrid({ states, cols }: { states: BoardState[]; cols: 2 | 3 }) { + return ( +
+ {states.map((state) => ( + + ))} +
+ ) +} + +const board = (cols: 2 | 3, ...ids: string[]) => ( + ids.includes(s.id)).map((s) => ({ id: s.id, label: s.label, children: s.node }))} /> ) // Representative Story: the common Story page; the sections group the same specimens. @@ -126,12 +139,8 @@ export const All: Story = { render: () => ( - {board("single")} - - {board("collapsible-single", "multiple")} - - {board("disabled")} - {board("long")} + {board(3, "single", "collapsible-single", "multiple")} + {board(3, "disabled", "long")} ), } diff --git a/src/components/collapsible.stories.tsx b/src/components/collapsible.stories.tsx index 9d2ca16..0e47d4d 100644 --- a/src/components/collapsible.stories.tsx +++ b/src/components/collapsible.stories.tsx @@ -2,7 +2,7 @@ import { useState, type ReactNode } from "react" 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 { StateBoard, type BoardState } from "@/components/story-board" import { StoryPage, StoryPageHeader, StorySection } from "@/components/story-page" // The representative "Collapsible" Story shows one independent disclosure per state with real, clickable triggers. The same @@ -70,8 +70,21 @@ const meta = { title: "Components/Disclosure/Collapsible", component: Collapsibl export default meta type Story = StoryObj -const board = (...ids: string[]) => ( - ids.includes(s.id)).map((s) => ({ id: s.id, label: s.label, children: s.node }))} /> +// Representative-page layout (Storybook presentation only): equal columns on PC (iframe width 1000px and up), one column +// below that. Each specimen sits in its own single-column StateBoard (min larger than any column), so the title, divider and +// specimen start line up, unused columns stay empty and `items-start` lets an opened item grow without touching its neighbors. +function StateGrid({ states, cols }: { states: BoardState[]; cols: 2 | 3 }) { + return ( +
+ {states.map((state) => ( + + ))} +
+ ) +} + +const board = (cols: 2 | 3, ...ids: string[]) => ( + ids.includes(s.id)).map((s) => ({ id: s.id, label: s.label, children: s.node }))} /> ) // Representative Story: the common Story page; the sections group the same specimens. @@ -81,9 +94,8 @@ export const All: Story = { render: () => ( - {board("closed")} - {board("open", "disabled")} - {board("long", "controlled")} + {board(3, "closed", "open", "disabled")} + {board(3, "long", "controlled")} ), } diff --git a/src/components/resizable.stories.tsx b/src/components/resizable.stories.tsx index b8872d5..2111e9c 100644 --- a/src/components/resizable.stories.tsx +++ b/src/components/resizable.stories.tsx @@ -1,7 +1,7 @@ import type { ReactNode } from "react" import type { Meta, StoryObj } from "@storybook/react-vite" import { ResizableHandle, ResizablePanel, ResizablePanelGroup } from "@hm-design/ui" -import { StateBoard } from "@/components/story-board" +import { StateBoard, type BoardState } from "@/components/story-board" import { StoryPage, StoryPageHeader, StorySection } from "@/components/story-page" // The representative Story shows real, draggable layouts; the same specimens also exist as Stories tagged `verification` (hidden @@ -99,8 +99,21 @@ const meta = { title: "Components/Disclosure/Resizable", component: ResizablePan export default meta type Story = StoryObj -const board = (...ids: string[]) => ( - ids.includes(s.id)).map((s) => ({ id: s.id, label: s.label, children: s.node }))} /> +// Representative-page layout (Storybook presentation only): equal columns on PC (iframe width 1000px and up), one column +// below that. Each specimen sits in its own single-column StateBoard (min larger than any column), so the title, divider and +// specimen start line up and unused columns stay empty. The frames keep their own size (max 560px wide). +function StateGrid({ states, cols }: { states: BoardState[]; cols: 2 | 3 }) { + return ( +
+ {states.map((state) => ( + + ))} +
+ ) +} + +const board = (cols: 2 | 3, ...ids: string[]) => ( + ids.includes(s.id)).map((s) => ({ id: s.id, label: s.label, children: s.node }))} /> ) // Representative Story: the common Story page; the sections group the same specimens. @@ -112,9 +125,8 @@ export const All: Story = { - {board("horizontal")} - {board("vertical", "handle")} - {board("minmax", "collapsible")} + {board(3, "horizontal", "handle", "vertical")} + {board(3, "minmax", "collapsible")} ), }