refactor(storybook): simplify component and preview examples

Drop page / section descriptions, state notes and repeated captions from
the representative Stories of 44 components, the Patterns, Center
Graphic and OrgChart pages. Value readouts, spec lists and captions hide
only on the representative page; hidden verification Stories keep them.
Tabs Default API and the Filter Bar draft / applied counts move to the
hidden DefaultApi and DraftApplied Stories; Center Overview is hidden
with its direct URL kept. Story IDs are unchanged.

Align the component, pattern and OrgChart docs with the pages, point the
quality reference check at the DraftApplied Story, and make the P8
styles check expect no section header on the preview-only Expanded page.
This commit is contained in:
shkim4 committed 2026-10-23 00:28:05 +09:00
1 parent 48977e7823
commit 4c29894e56
81 files changed
+520 -671

No files matched your search

+18 -26
View File
@@ -1,15 +1,15 @@
import { useState } from "react"
import { useState, type ReactNode } from "react"
import type { Meta, StoryObj } from "@storybook/react-vite"
import { AlignCenterIcon, AlignLeftIcon, AlignRightIcon, BoldIcon, ItalicIcon, UnderlineIcon } from "lucide-react"
import { ToggleGroup, ToggleGroupItem } from "@hm-design/ui"
import { StateBoard } from "@/components/story-board"
import { StoryPage, StoryPageHeader, StorySection } from "@/components/story-page"
// Toggle Group is a group of pressed-state items (toolbar-style), not a content switcher (that is Tabs). The representative Story
// shows single / multiple / icon-only / disabled / vertical / spaced groups with real controls; the same specimens also exist as
// Stories tagged `verification` (hidden from the sidebar). Icon-only items carry an `aria-label`.
function Single() {
// `showValue={false}` hides the selected-value readout on the representative page; the verification Stories keep it.
function Single({ showValue = true }: { showValue?: boolean }) {
const [value, setValue] = useState("left")
return (
<div className="grid gap-2">
@@ -18,12 +18,12 @@ function Single() {
<ToggleGroupItem value="center">가운데</ToggleGroupItem>
<ToggleGroupItem value="right">오른쪽</ToggleGroupItem>
</ToggleGroup>
<span className="text-sm text-muted-foreground" data-testid="single">{`value = ${value}`}</span>
{showValue ? <span className="text-sm text-muted-foreground" data-testid="single">{`value = ${value}`}</span> : null}
</div>
)
}
function Multiple() {
function Multiple({ showValue = true }: { showValue?: boolean }) {
const [value, setValue] = useState<string[]>(["bold"])
return (
<div className="grid gap-2">
@@ -38,7 +38,7 @@ function Multiple() {
<UnderlineIcon />
</ToggleGroupItem>
</ToggleGroup>
<span className="text-sm text-muted-foreground" data-testid="multiple">{`value = [${value.join(", ")}]`}</span>
{showValue ? <span className="text-sm text-muted-foreground" data-testid="multiple">{`value = [${value.join(", ")}]`}</span> : null}
</div>
)
}
@@ -111,23 +111,18 @@ function Sizes() {
)
}
const sections = [
{ id: "single", label: "Single selection", node: <Single /> },
{ id: "multiple", label: "Multiple selection (icon-only)", node: <Multiple /> },
{ id: "sizes", label: "Sizes · Icon-only / Icon + Text / Text-only", node: <Sizes /> },
{ id: "disabled", label: "Disabled group / item", node: <Disabled /> },
{ id: "vertical", label: "Vertical", node: <Vertical /> },
{ id: "spaced", label: "spacing={2} (separated)", node: <Spaced /> },
{ id: "many", label: "Many items (spacing + flex-wrap, consumer opts in)", node: <Many /> },
]
// No `component`: ToggleGroup props are a union (single | multiple), so Stories without args would not type-check.
const meta = { title: "Components/Form/Toggle Group", parameters: { layout: "padded" } } satisfies Meta
export default meta
type Story = StoryObj<typeof meta>
const board = (...ids: string[]) => (
<StateBoard min={360} states={sections.filter((s) => ids.includes(s.id)).map((s) => ({ id: s.id, label: s.label, children: s.node }))} />
// The representative page shows the groups without example titles: the section title names them.
const examples = (...nodes: ReactNode[]) => (
<div className="flex flex-wrap items-start gap-x-10 gap-y-6">
{nodes.map((node, i) => (
<div key={i}>{node}</div>
))}
</div>
)
// Representative Story: the common Story page; the sections group the same specimens.
@@ -136,17 +131,14 @@ export const All: Story = {
parameters: { layout: "fullscreen", controls: { disable: true } },
render: () => (
<StoryPage>
<StoryPageHeader
title="Toggle Group"
description="툴바형 눌림 항목 묶음 · 내용 전환은 Tabs 사용"
/>
<StorySection title="Overview">{board("single")}</StorySection>
<StoryPageHeader title="Toggle Group" />
<StorySection title="Overview">{examples(<Single showValue={false} />)}</StorySection>
<StorySection title="Sizes">
<Sizes />
</StorySection>
<StorySection title="Variants">{board("multiple", "vertical", "spaced")}</StorySection>
<StorySection title="States">{board("disabled")}</StorySection>
<StorySection title="Usage">{board("many")}</StorySection>
<StorySection title="Variants">{examples(<Multiple showValue={false} />, <Vertical />, <Spaced />)}</StorySection>
<StorySection title="States">{examples(<Disabled />)}</StorySection>
<StorySection title="Usage">{examples(<div className="max-w-sm"><Many /></div>)}</StorySection>
</StoryPage>
),
}