Initial commit: HMDesignSystem baseline
This commit is contained in:
commit
b6a0a61103
486 files changed
+68432
No files matched your search
@@ -0,0 +1,115 @@
|
||||
import { useState, type ReactNode } from "react"
|
||||
import type { Meta, StoryObj } from "@storybook/react-vite"
|
||||
import { CalendarIcon, SettingsIcon, UserIcon } from "lucide-react"
|
||||
import { Command, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, CommandSeparator, CommandShortcut } from "@hm-design/ui"
|
||||
import { StateBoard } from "@/components/story-board"
|
||||
import { STORY_KICKER, StoryPage, StoryPageHeader, StorySection } from "@/components/story-page"
|
||||
|
||||
// The representative "Command" Story shows real, typeable lists; the same specimens also exist as Stories tagged `verification`
|
||||
// (hidden from the sidebar). Filtering is cmdk's. The bordered box is Story composition (Command draws no border of its own).
|
||||
// A selection log shows that Enter / click reach `onSelect`.
|
||||
|
||||
const box = (node: ReactNode) => <div className="w-full max-w-sm rounded-md border">{node}</div>
|
||||
|
||||
function Basic() {
|
||||
const [last, setLast] = useState("-")
|
||||
return (
|
||||
<div className="grid gap-2">
|
||||
{box(
|
||||
<Command>
|
||||
<CommandInput placeholder="검색..." />
|
||||
<CommandList>
|
||||
<CommandEmpty>결과가 없습니다.</CommandEmpty>
|
||||
<CommandItem onSelect={setLast}>사과</CommandItem>
|
||||
<CommandItem onSelect={setLast}>바나나</CommandItem>
|
||||
<CommandItem onSelect={setLast} disabled>
|
||||
체리 (품절)
|
||||
</CommandItem>
|
||||
<CommandItem onSelect={setLast}>포도</CommandItem>
|
||||
</CommandList>
|
||||
</Command>
|
||||
)}
|
||||
<span className="text-sm text-muted-foreground" data-testid="last">{`선택: ${last}`}</span>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
function Grouped() {
|
||||
return box(
|
||||
<Command>
|
||||
<CommandInput placeholder="명령 검색..." />
|
||||
<CommandList>
|
||||
<CommandEmpty>결과가 없습니다.</CommandEmpty>
|
||||
<CommandGroup heading="제안">
|
||||
<CommandItem>
|
||||
<CalendarIcon />
|
||||
일정 보기
|
||||
</CommandItem>
|
||||
<CommandItem>
|
||||
<UserIcon />
|
||||
프로필
|
||||
<CommandShortcut>⌘P</CommandShortcut>
|
||||
</CommandItem>
|
||||
</CommandGroup>
|
||||
<CommandSeparator />
|
||||
<CommandGroup heading="설정">
|
||||
<CommandItem>
|
||||
<SettingsIcon />
|
||||
환경설정
|
||||
<CommandShortcut>⌘,</CommandShortcut>
|
||||
</CommandItem>
|
||||
<CommandItem disabled>결제 (사용 불가)</CommandItem>
|
||||
</CommandGroup>
|
||||
</CommandList>
|
||||
</Command>
|
||||
)
|
||||
}
|
||||
|
||||
function Long() {
|
||||
return box(
|
||||
<Command>
|
||||
<CommandInput placeholder="항목 검색..." />
|
||||
<CommandList>
|
||||
<CommandEmpty>결과가 없습니다.</CommandEmpty>
|
||||
{Array.from({ length: 30 }, (_, i) => (
|
||||
<CommandItem key={i}>{`항목 ${i + 1} — 긴 항목 이름도 줄바꿈 없이 한 줄로 이어질 수 있습니다`}</CommandItem>
|
||||
))}
|
||||
</CommandList>
|
||||
</Command>
|
||||
)
|
||||
}
|
||||
|
||||
const sections = [
|
||||
{ id: "basic", label: "Search + disabled item", node: <Basic /> },
|
||||
{ id: "grouped", label: "Groups, icons, shortcut", node: <Grouped /> },
|
||||
{ id: "long", label: "Long list (list scrolls)", node: <Long /> },
|
||||
]
|
||||
|
||||
const meta = { title: "Components/Search & Date/Command", component: Command, parameters: { layout: "padded" } } satisfies Meta<typeof Command>
|
||||
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 }))} />
|
||||
)
|
||||
|
||||
// Representative Story: the common Story page; the sections group the same specimens.
|
||||
export const All: Story = {
|
||||
name: "Command",
|
||||
parameters: { layout: "fullscreen", controls: { disable: true } },
|
||||
render: () => (
|
||||
<StoryPage>
|
||||
<StoryPageHeader
|
||||
kicker={STORY_KICKER.components}
|
||||
title="Command"
|
||||
description="입력한 검색어로 항목을 걸러 고르는 목록입니다. Combobox와 명령 팔레트의 기반입니다."
|
||||
/>
|
||||
<StorySection title="Overview">{board("basic")}</StorySection>
|
||||
<StorySection title="Variants">{board("grouped")}</StorySection>
|
||||
<StorySection title="Usage">{board("long")}</StorySection>
|
||||
</StoryPage>
|
||||
),
|
||||
}
|
||||
|
||||
export const Search: Story = { tags: ["verification"], render: () => <Basic /> }
|
||||
export const GroupedList: Story = { tags: ["verification"], name: "Grouped", render: () => <Grouped /> }
|
||||
Reference in new issue
Block a user