Files
shkim4 4c29894e56 refactor(storybook): simplify component and preview examples
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.
2026-10-23 00:28:05 +09:00

106 lines
3.2 KiB
TypeScript

import type { Meta, StoryObj } from "@storybook/react-vite"
import { Button, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "@hm-design/ui"
import { StoryPage, StoryPageHeader, StorySection } from "@/components/story-page"
// Tooltip is a Radix overlay (Portal) with short, non-interactive text. The representative Story shows real triggers
// (hover or focus to open); the verification Story starts one open. Interactive content belongs in Popover / Hover Card.
const longText = "긴 설명은 최대 폭에서 줄바꿈됩니다. 이 정도 길이가 Tooltip의 한계이며, 더 긴 내용은 Popover나 Hover Card를 사용합니다."
function Basic({ defaultOpen }: { defaultOpen?: boolean }) {
return (
<Tooltip defaultOpen={defaultOpen}>
<TooltipTrigger asChild>
<Button variant="primary" appearance="outline">
기본
</Button>
</TooltipTrigger>
<TooltipContent>저장하지 않은 변경 사항이 있습니다</TooltipContent>
</Tooltip>
)
}
function Placements() {
return (
<div className="flex flex-wrap gap-3">
{(["top", "right", "bottom", "left"] as const).map((side) => (
<Tooltip key={side}>
<TooltipTrigger asChild>
<Button variant="primary" appearance="outline" size="sm">
{side}
</Button>
</TooltipTrigger>
<TooltipContent side={side}>{`side="${side}"`}</TooltipContent>
</Tooltip>
))}
</div>
)
}
function LongText() {
return (
<Tooltip>
<TooltipTrigger asChild>
<Button variant="primary" appearance="outline">
긴 텍스트
</Button>
</TooltipTrigger>
<TooltipContent>{longText}</TooltipContent>
</Tooltip>
)
}
function Disabled() {
// A disabled button gets no pointer events, so the trigger is a wrapper element.
return (
<Tooltip>
<TooltipTrigger asChild>
<span tabIndex={0} className="inline-block">
<Button variant="primary" appearance="solid" disabled>
비활성
</Button>
</span>
</TooltipTrigger>
<TooltipContent>권한이 없어 사용할 수 없습니다</TooltipContent>
</Tooltip>
)
}
const meta = { title: "Components/Overlay/Tooltip", component: Tooltip, parameters: { layout: "centered" } } satisfies Meta<typeof Tooltip>
export default meta
type Story = StoryObj<typeof meta>
export const All: Story = {
name: "Tooltip",
parameters: { layout: "fullscreen", controls: { disable: true } },
render: () => (
<TooltipProvider>
<StoryPage>
<StoryPageHeader title="Tooltip" />
<StorySection title="Overview">
<Basic />
</StorySection>
<StorySection title="Variants">
<Placements />
</StorySection>
<StorySection title="Usage">
<div className="flex flex-wrap gap-3">
<LongText />
<Disabled />
</div>
</StorySection>
</StoryPage>
</TooltipProvider>
),
}
export const Open: Story = {
tags: ["verification"],
parameters: { layout: "fullscreen" },
render: () => (
<div className="flex min-h-[200px] items-end justify-center p-8">
<Basic defaultOpen />
</div>
),
}