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.
105 lines
3.7 KiB
TypeScript
105 lines
3.7 KiB
TypeScript
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 { 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).
|
|
|
|
const meta = {
|
|
title: "Components/Form/Label",
|
|
component: Label,
|
|
parameters: {
|
|
layout: "padded",
|
|
docs: {
|
|
description: {
|
|
component:
|
|
"Field Label 14/20/500, 색 color.fg.secondary (ui_viz input.md §9, §10). Radix Label의 htmlFor·클릭 시 컨트롤 focus 동작을 유지합니다. Required 별표·문구는 Label이 아닌 소비 조합입니다.",
|
|
},
|
|
},
|
|
},
|
|
} satisfies Meta<typeof Label>
|
|
export default meta
|
|
type Story = StoryObj<typeof meta>
|
|
|
|
export const All: Story = {
|
|
name: "Label",
|
|
parameters: { layout: "fullscreen", controls: { disable: true } },
|
|
render: () => (
|
|
<StoryPage>
|
|
<StoryPageHeader title="Label" />
|
|
<StorySection title="Overview">
|
|
<StateBoard
|
|
states={[
|
|
{
|
|
id: "default",
|
|
label: "Default",
|
|
children: (
|
|
<div className="grid max-w-sm gap-2">
|
|
<Label htmlFor="label-default">Project name</Label>
|
|
<Input id="label-default" size="medium" placeholder="Enter a project name" />
|
|
</div>
|
|
),
|
|
},
|
|
]}
|
|
/>
|
|
</StorySection>
|
|
<StorySection title="States">
|
|
<StateBoard
|
|
states={[
|
|
{
|
|
id: "disabled",
|
|
label: "Disabled",
|
|
children: (
|
|
<div className="grid max-w-sm gap-2">
|
|
<Input id="label-disabled" size="medium" disabled defaultValue="Unavailable" className="peer order-2" />
|
|
<Label htmlFor="label-disabled" className="order-1">
|
|
Project name
|
|
</Label>
|
|
</div>
|
|
),
|
|
},
|
|
]}
|
|
/>
|
|
</StorySection>
|
|
<StorySection title="Usage">
|
|
<div className="mb-4 grid max-w-sm gap-2">
|
|
<Label htmlFor="label-select">부서 선택</Label>
|
|
<Select><SelectTrigger id="label-select" size="medium"><SelectValue placeholder="부서를 선택하세요" /></SelectTrigger>
|
|
<SelectContent><SelectItem value="design">디자인</SelectItem><SelectItem value="engineering">개발</SelectItem></SelectContent>
|
|
</Select>
|
|
</div>
|
|
<StateBoard
|
|
states={[
|
|
{
|
|
id: "required",
|
|
label: "Required",
|
|
children: (
|
|
<div className="grid max-w-sm gap-2">
|
|
<Label htmlFor="label-required">
|
|
Project name
|
|
<span aria-hidden="true" className="text-destructive">
|
|
*
|
|
</span>
|
|
</Label>
|
|
<Input id="label-required" size="medium" required />
|
|
</div>
|
|
),
|
|
},
|
|
{
|
|
id: "long",
|
|
label: "Long Label",
|
|
children: (
|
|
<div className="grid max-w-[220px] gap-2">
|
|
<Label htmlFor="label-long">A very long label text that wraps to multiple lines</Label>
|
|
<Input id="label-long" size="medium" />
|
|
</div>
|
|
),
|
|
},
|
|
]}
|
|
/>
|
|
</StorySection>
|
|
</StoryPage>
|
|
),
|
|
}
|