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.
146 lines
5.0 KiB
TypeScript
146 lines
5.0 KiB
TypeScript
import { Fragment, type ReactNode } from "react"
|
|
import type { Meta, StoryObj } from "@storybook/react-vite"
|
|
import {
|
|
Breadcrumb,
|
|
BreadcrumbEllipsis,
|
|
BreadcrumbItem,
|
|
BreadcrumbLink,
|
|
BreadcrumbList,
|
|
BreadcrumbPage,
|
|
BreadcrumbSeparator,
|
|
DropdownMenu,
|
|
DropdownMenuContent,
|
|
DropdownMenuItem,
|
|
DropdownMenuTrigger,
|
|
} from "@hm-design/ui"
|
|
import { StateBoard } from "@/components/story-board"
|
|
import { StoryPage, StoryPageHeader, StorySection } from "@/components/story-page"
|
|
|
|
// The representative "Breadcrumb" Story shows each case on one page (real links with sample hrefs); the same specimens also exist
|
|
// as Stories tagged `verification` (hidden from the sidebar). BreadcrumbEllipsis is presentational: the Dropdown Menu example is
|
|
// a consumer composition, not part of Breadcrumb.
|
|
|
|
const narrow = (children: ReactNode) => <div className="w-full max-w-xl">{children}</div>
|
|
|
|
function Basic() {
|
|
return (
|
|
<Breadcrumb>
|
|
<BreadcrumbList>
|
|
<BreadcrumbItem>
|
|
<BreadcrumbLink href="#home">홈</BreadcrumbLink>
|
|
</BreadcrumbItem>
|
|
<BreadcrumbSeparator />
|
|
<BreadcrumbItem>
|
|
<BreadcrumbLink href="#users">사용자</BreadcrumbLink>
|
|
</BreadcrumbItem>
|
|
<BreadcrumbSeparator />
|
|
<BreadcrumbItem>
|
|
<BreadcrumbPage>상세</BreadcrumbPage>
|
|
</BreadcrumbItem>
|
|
</BreadcrumbList>
|
|
</Breadcrumb>
|
|
)
|
|
}
|
|
|
|
function Ellipsis() {
|
|
return (
|
|
<Breadcrumb>
|
|
<BreadcrumbList>
|
|
<BreadcrumbItem>
|
|
<BreadcrumbLink href="#home">홈</BreadcrumbLink>
|
|
</BreadcrumbItem>
|
|
<BreadcrumbSeparator />
|
|
<BreadcrumbItem>
|
|
<DropdownMenu>
|
|
<DropdownMenuTrigger aria-label="중간 경로 보기">
|
|
<BreadcrumbEllipsis />
|
|
</DropdownMenuTrigger>
|
|
<DropdownMenuContent align="start">
|
|
<DropdownMenuItem>문서</DropdownMenuItem>
|
|
<DropdownMenuItem>설정</DropdownMenuItem>
|
|
</DropdownMenuContent>
|
|
</DropdownMenu>
|
|
</BreadcrumbItem>
|
|
<BreadcrumbSeparator />
|
|
<BreadcrumbItem>
|
|
<BreadcrumbLink href="#project">프로젝트</BreadcrumbLink>
|
|
</BreadcrumbItem>
|
|
<BreadcrumbSeparator />
|
|
<BreadcrumbItem>
|
|
<BreadcrumbPage>상세</BreadcrumbPage>
|
|
</BreadcrumbItem>
|
|
</BreadcrumbList>
|
|
</Breadcrumb>
|
|
)
|
|
}
|
|
|
|
function Long() {
|
|
const labels = ["홈", "프로젝트", "한맥 프로젝트 관리 시스템", "노선 정보", "시설물 목록", "교량", "상세 정보 및 점검 이력"]
|
|
return (
|
|
<Breadcrumb>
|
|
<BreadcrumbList>
|
|
{labels.map((label, i) => (
|
|
<Fragment key={label}>
|
|
<BreadcrumbItem>
|
|
{i === labels.length - 1 ? <BreadcrumbPage>{label}</BreadcrumbPage> : <BreadcrumbLink href={`#${i}`}>{label}</BreadcrumbLink>}
|
|
</BreadcrumbItem>
|
|
{i < labels.length - 1 ? <BreadcrumbSeparator /> : null}
|
|
</Fragment>
|
|
))}
|
|
</BreadcrumbList>
|
|
</Breadcrumb>
|
|
)
|
|
}
|
|
|
|
// asChild: the link is any element (here a plain <a> standing in for a router Link) and keeps the Breadcrumb look.
|
|
function CustomLink() {
|
|
return (
|
|
<Breadcrumb>
|
|
<BreadcrumbList>
|
|
<BreadcrumbItem>
|
|
<BreadcrumbLink asChild>
|
|
<a href="#router-home">홈 (custom link)</a>
|
|
</BreadcrumbLink>
|
|
</BreadcrumbItem>
|
|
<BreadcrumbSeparator>/</BreadcrumbSeparator>
|
|
<BreadcrumbItem>
|
|
<BreadcrumbPage>현재 페이지</BreadcrumbPage>
|
|
</BreadcrumbItem>
|
|
</BreadcrumbList>
|
|
</Breadcrumb>
|
|
)
|
|
}
|
|
|
|
const sections = [
|
|
{ id: "basic", label: "Basic", node: <Basic /> },
|
|
{ id: "ellipsis", label: "Ellipsis", node: <Ellipsis /> },
|
|
{ id: "long", label: "Long path", node: <Long /> },
|
|
{ id: "custom", label: "Custom link · separator", node: <CustomLink /> },
|
|
]
|
|
|
|
const meta = { title: "Components/Navigation/Breadcrumb", component: Breadcrumb, parameters: { layout: "padded" } } satisfies Meta<typeof Breadcrumb>
|
|
export default meta
|
|
type Story = StoryObj<typeof meta>
|
|
|
|
const board = (...ids: string[]) => (
|
|
<StateBoard min={420} states={sections.filter((s) => ids.includes(s.id)).map((s) => ({ id: s.id, label: s.label, children: narrow(s.node) }))} />
|
|
)
|
|
|
|
// Representative Story: the common Story page; the sections group the same specimens.
|
|
export const All: Story = {
|
|
name: "Breadcrumb",
|
|
parameters: { layout: "fullscreen", controls: { disable: true } },
|
|
render: () => (
|
|
<StoryPage>
|
|
<StoryPageHeader title="Breadcrumb" />
|
|
<StorySection title="Overview">{board("basic")}</StorySection>
|
|
<StorySection title="Variants">{board("ellipsis", "custom")}</StorySection>
|
|
<StorySection title="Usage">{board("long")}</StorySection>
|
|
</StoryPage>
|
|
),
|
|
}
|
|
|
|
export const Basic3: Story = { tags: ["verification"], name: "Basic", render: () => <Basic /> }
|
|
export const WithEllipsis: Story = { tags: ["verification"], name: "Ellipsis", render: () => <Ellipsis /> }
|
|
export const LongPath: Story = { tags: ["verification"], name: "Long Path", render: () => narrow(<Long />) }
|