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.
106 lines
3.2 KiB
TypeScript
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>
|
|
),
|
|
}
|