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.
80 lines
3.5 KiB
TypeScript
80 lines
3.5 KiB
TypeScript
import type { Meta, StoryObj } from "@storybook/react-vite"
|
|
import { AspectRatio, Card, CardContent } from "@hm-design/ui"
|
|
import { StateBoard } from "@/components/story-board"
|
|
import { StoryPage, StoryPageHeader, StorySection } from "@/components/story-page"
|
|
|
|
// AspectRatio is a layout primitive: it keeps the ratio and nothing else. The image styling (object-fit, radius) in these Stories is
|
|
// the consumer's composition on the child, not part of AspectRatio. Images are inline data URIs (no network). The Card example only
|
|
// shows how a consumer can compose it; AspectRatio does not depend on Card.
|
|
|
|
const svg = (label: string, fill: string) =>
|
|
"data:image/svg+xml;utf8," +
|
|
encodeURIComponent(
|
|
`<svg xmlns="http://www.w3.org/2000/svg" width="480" height="320" viewBox="0 0 480 320"><rect width="480" height="320" fill="${fill}"/><circle cx="360" cy="90" r="40" fill="#bddfd4"/><path d="M0 320 L150 150 L260 260 L340 190 L480 320 Z" fill="#205241"/><text x="24" y="44" font-family="sans-serif" font-size="26" fill="#ffffff">${label}</text></svg>`
|
|
)
|
|
|
|
function Image({ ratio, label }: { ratio: number; label: string }) {
|
|
return (
|
|
<div style={{ width: "100%", maxWidth: 320 }}>
|
|
<AspectRatio ratio={ratio} data-testid={`ratio-${label}`}>
|
|
<img src={svg(label, "#266651")} alt={`${label} 예시 이미지`} className="size-full rounded-md object-cover" />
|
|
</AspectRatio>
|
|
</div>
|
|
)
|
|
}
|
|
|
|
function Placeholder() {
|
|
return (
|
|
<div style={{ width: "100%", maxWidth: 320 }}>
|
|
<AspectRatio ratio={16 / 9} data-testid="ratio-video">
|
|
<div className="grid size-full place-items-center rounded-md border bg-muted text-sm text-muted-foreground">영상 영역 16:9</div>
|
|
</AspectRatio>
|
|
</div>
|
|
)
|
|
}
|
|
|
|
function InCard() {
|
|
return (
|
|
<Card style={{ width: "100%", maxWidth: 320 }}>
|
|
<CardContent>
|
|
<AspectRatio ratio={4 / 3} data-testid="ratio-card">
|
|
<img src={svg("Card 4:3", "#3e3523")} alt="카드 안 4:3 이미지" className="size-full rounded-md object-cover" />
|
|
</AspectRatio>
|
|
</CardContent>
|
|
</Card>
|
|
)
|
|
}
|
|
|
|
const sections = [
|
|
{ id: "r169", label: "16:9", node: <Image ratio={16 / 9} label="16:9" /> },
|
|
{ id: "r43", label: "4:3", node: <Image ratio={4 / 3} label="4:3" /> },
|
|
{ id: "r11", label: "1:1", node: <Image ratio={1} label="1:1" /> },
|
|
{ id: "video", label: "Video", node: <Placeholder /> },
|
|
{ id: "card", label: "Card", node: <InCard /> },
|
|
]
|
|
|
|
const meta = { title: "Components/Data & Display/Aspect Ratio", component: AspectRatio, parameters: { layout: "padded" } } satisfies Meta<typeof AspectRatio>
|
|
export default meta
|
|
type Story = StoryObj<typeof meta>
|
|
|
|
const board = (...ids: string[]) => (
|
|
<StateBoard min={340} states={sections.filter((s) => 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.
|
|
export const All: Story = {
|
|
name: "Aspect Ratio",
|
|
parameters: { layout: "fullscreen", controls: { disable: true } },
|
|
render: () => (
|
|
<StoryPage>
|
|
<StoryPageHeader title="Aspect Ratio" />
|
|
<StorySection title="Overview">{board("r169")}</StorySection>
|
|
<StorySection title="Variants">{board("r43", "r11", "video")}</StorySection>
|
|
<StorySection title="Usage">{board("card")}</StorySection>
|
|
</StoryPage>
|
|
),
|
|
}
|
|
|
|
export const Wide: Story = { tags: ["verification"], name: "16:9", render: () => <Image ratio={16 / 9} label="16:9" /> }
|
|
export const Square: Story = { tags: ["verification"], name: "1:1", render: () => <Image ratio={1} label="1:1" /> }
|