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.
107 lines
4.0 KiB
TypeScript
107 lines
4.0 KiB
TypeScript
import { useState } from "react"
|
|
import type { Meta, StoryObj } from "@storybook/react-vite"
|
|
import {
|
|
Button,
|
|
DropdownMenu,
|
|
DropdownMenuCheckboxItem,
|
|
DropdownMenuContent,
|
|
DropdownMenuGroup,
|
|
DropdownMenuItem,
|
|
DropdownMenuLabel,
|
|
DropdownMenuRadioGroup,
|
|
DropdownMenuRadioItem,
|
|
DropdownMenuSeparator,
|
|
DropdownMenuShortcut,
|
|
DropdownMenuSub,
|
|
DropdownMenuSubContent,
|
|
DropdownMenuSubTrigger,
|
|
DropdownMenuTrigger,
|
|
} from "@hm-design/ui"
|
|
import { StoryPage, StoryPageHeader, StorySection } from "@/components/story-page"
|
|
|
|
// Dropdown Menu is a Radix overlay (Portal), so the representative Story is a trigger that opens the real menu, the same way as
|
|
// Dialog. The verification Story starts open. Radix owns keyboard navigation, focus return and Escape.
|
|
|
|
function Full({ defaultOpen }: { defaultOpen?: boolean }) {
|
|
const [showStatus, setShowStatus] = useState(true)
|
|
const [showPanel, setShowPanel] = useState(false)
|
|
const [position, setPosition] = useState("bottom")
|
|
return (
|
|
<DropdownMenu defaultOpen={defaultOpen}>
|
|
<DropdownMenuTrigger asChild>
|
|
<Button variant="primary" appearance="outline">
|
|
메뉴 열기
|
|
</Button>
|
|
</DropdownMenuTrigger>
|
|
<DropdownMenuContent className="w-56" align="start">
|
|
<DropdownMenuLabel>내 계정</DropdownMenuLabel>
|
|
<DropdownMenuGroup>
|
|
<DropdownMenuItem>
|
|
프로필 <DropdownMenuShortcut>⇧⌘P</DropdownMenuShortcut>
|
|
</DropdownMenuItem>
|
|
<DropdownMenuItem>
|
|
설정 <DropdownMenuShortcut>⌘,</DropdownMenuShortcut>
|
|
</DropdownMenuItem>
|
|
<DropdownMenuItem disabled>결제 (사용 불가)</DropdownMenuItem>
|
|
</DropdownMenuGroup>
|
|
<DropdownMenuSeparator />
|
|
<DropdownMenuLabel>보기</DropdownMenuLabel>
|
|
<DropdownMenuCheckboxItem checked={showStatus} onCheckedChange={setShowStatus}>
|
|
상태 표시줄
|
|
</DropdownMenuCheckboxItem>
|
|
<DropdownMenuCheckboxItem checked={showPanel} onCheckedChange={setShowPanel}>
|
|
패널
|
|
</DropdownMenuCheckboxItem>
|
|
<DropdownMenuSeparator />
|
|
<DropdownMenuLabel>위치</DropdownMenuLabel>
|
|
<DropdownMenuRadioGroup value={position} onValueChange={setPosition}>
|
|
<DropdownMenuRadioItem value="top">상단</DropdownMenuRadioItem>
|
|
<DropdownMenuRadioItem value="bottom">하단</DropdownMenuRadioItem>
|
|
<DropdownMenuRadioItem value="right">오른쪽</DropdownMenuRadioItem>
|
|
</DropdownMenuRadioGroup>
|
|
<DropdownMenuSeparator />
|
|
<DropdownMenuSub>
|
|
<DropdownMenuSubTrigger>더 보기</DropdownMenuSubTrigger>
|
|
<DropdownMenuSubContent>
|
|
<DropdownMenuItem>이메일로 공유</DropdownMenuItem>
|
|
<DropdownMenuItem>링크 복사</DropdownMenuItem>
|
|
</DropdownMenuSubContent>
|
|
</DropdownMenuSub>
|
|
<DropdownMenuSeparator />
|
|
<DropdownMenuItem variant="destructive">로그아웃</DropdownMenuItem>
|
|
</DropdownMenuContent>
|
|
</DropdownMenu>
|
|
)
|
|
}
|
|
|
|
const meta = { title: "Components/Overlay/Dropdown Menu", component: DropdownMenu, parameters: { layout: "centered" } } satisfies Meta<typeof DropdownMenu>
|
|
export default meta
|
|
type Story = StoryObj<typeof meta>
|
|
|
|
// Representative Story: the trigger opens the full menu (item, disabled, separator, checkbox, radio group, sub menu, destructive).
|
|
export const All: Story = {
|
|
name: "Dropdown Menu",
|
|
parameters: { layout: "fullscreen", controls: { disable: true } },
|
|
render: () => (
|
|
<StoryPage>
|
|
<StoryPageHeader
|
|
title="Dropdown Menu"
|
|
/>
|
|
<StorySection title="Overview">
|
|
<Full />
|
|
</StorySection>
|
|
</StoryPage>
|
|
),
|
|
}
|
|
|
|
// Verification Story: the same menu starting open, hidden from the sidebar (tag `verification`).
|
|
export const Open: Story = {
|
|
tags: ["verification"],
|
|
parameters: { layout: "fullscreen" },
|
|
render: () => (
|
|
<div className="flex min-h-[560px] justify-center p-8">
|
|
<Full defaultOpen />
|
|
</div>
|
|
),
|
|
}
|