feat: add sheet component and docs qa baseline
This commit is contained in:
@@ -10,10 +10,48 @@ import {
|
||||
} from "@ai-ui/ui";
|
||||
import type { Meta, StoryObj } from "@storybook/react";
|
||||
|
||||
type LaunchDialogProps = {
|
||||
description?: string;
|
||||
size?: "sm" | "md" | "lg";
|
||||
title?: string;
|
||||
triggerLabel?: string;
|
||||
};
|
||||
|
||||
function LaunchDialog({
|
||||
description = "This will notify the routing team and publish the release note to the activity feed.",
|
||||
size = "md",
|
||||
title = "Launch this release?",
|
||||
triggerLabel = "Open approval dialog"
|
||||
}: LaunchDialogProps) {
|
||||
return (
|
||||
<Dialog>
|
||||
<DialogTrigger asChild>
|
||||
<Button>{triggerLabel}</Button>
|
||||
</DialogTrigger>
|
||||
<DialogContent size={size}>
|
||||
<DialogHeader>
|
||||
<DialogTitle>{title}</DialogTitle>
|
||||
<DialogDescription>{description}</DialogDescription>
|
||||
</DialogHeader>
|
||||
<DialogFooter>
|
||||
<Button variant="ghost">Cancel</Button>
|
||||
<Button>Confirm launch</Button>
|
||||
</DialogFooter>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
);
|
||||
}
|
||||
|
||||
const meta = {
|
||||
title: "Components/Dialog",
|
||||
component: Dialog,
|
||||
parameters: {
|
||||
docs: {
|
||||
description: {
|
||||
component:
|
||||
"Dialog is the system's blocking overlay for focused decisions, confirmation flows, and dense tasks that must temporarily interrupt the surrounding page. It ships with a portal, overlay, close affordance, semantic title and description wiring, and token-driven motion on both the surface and backdrop."
|
||||
}
|
||||
},
|
||||
layout: "centered"
|
||||
},
|
||||
tags: ["autodocs"]
|
||||
@@ -24,23 +62,98 @@ export default meta;
|
||||
type Story = StoryObj<typeof meta>;
|
||||
|
||||
export const Playground: Story = {
|
||||
render: () => <LaunchDialog />
|
||||
};
|
||||
|
||||
export const Sizes: Story = {
|
||||
render: () => (
|
||||
<Dialog>
|
||||
<DialogTrigger asChild>
|
||||
<Button>Open approval dialog</Button>
|
||||
</DialogTrigger>
|
||||
<DialogContent>
|
||||
<DialogHeader>
|
||||
<DialogTitle>Launch this release?</DialogTitle>
|
||||
<DialogDescription>
|
||||
This will notify the routing team and publish the release note to the activity feed.
|
||||
</DialogDescription>
|
||||
</DialogHeader>
|
||||
<DialogFooter>
|
||||
<Button variant="ghost">Cancel</Button>
|
||||
<Button>Confirm launch</Button>
|
||||
</DialogFooter>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
<div className="grid w-[720px] gap-3 sm:grid-cols-2">
|
||||
<LaunchDialog
|
||||
description="Use the compact size for short confirmations that only need a title, one supporting sentence, and one primary action."
|
||||
size="sm"
|
||||
title="Publish summary?"
|
||||
triggerLabel="Compact dialog"
|
||||
/>
|
||||
<LaunchDialog
|
||||
description="Use the large size when the flow needs denser copy, audit context, or multi-step review detail before a final action."
|
||||
size="lg"
|
||||
title="Review rollout checklist"
|
||||
triggerLabel="Large dialog"
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
};
|
||||
|
||||
export const Anatomy: Story = {
|
||||
render: () => (
|
||||
<div className="w-[700px] rounded-[var(--radius-lg)] border border-[var(--color-border)] bg-[var(--color-card)] p-6 text-[var(--color-foreground)] shadow-[var(--shadow-sm)]">
|
||||
<div className="space-y-3">
|
||||
<p className="text-xs uppercase tracking-[var(--tracking-caps)] text-[var(--color-muted-foreground)]">
|
||||
Dialog anatomy
|
||||
</p>
|
||||
<LaunchDialog triggerLabel="Preview dialog structure" />
|
||||
<div className="grid gap-3 text-sm leading-6 text-[var(--color-muted-foreground)]">
|
||||
<p>
|
||||
<code className="text-[var(--color-foreground)]">data-slot="overlay"</code> sits
|
||||
behind the surface and carries the backdrop motion.
|
||||
</p>
|
||||
<p>
|
||||
<code className="text-[var(--color-foreground)]">data-slot="content"</code> wraps
|
||||
the modal panel and exposes <code className="text-[var(--color-foreground)]">data-size</code>.
|
||||
</p>
|
||||
<p>
|
||||
<code className="text-[var(--color-foreground)]">data-slot="header"</code>,{" "}
|
||||
<code className="text-[var(--color-foreground)]">data-slot="footer"</code>,{" "}
|
||||
<code className="text-[var(--color-foreground)]">data-slot="label"</code>, and{" "}
|
||||
<code className="text-[var(--color-foreground)]">data-slot="description"</code>
|
||||
provide stable hooks for structure and docs.
|
||||
</p>
|
||||
<p>
|
||||
The close button is built into <code className="text-[var(--color-foreground)]">DialogContent</code>,
|
||||
so every dialog gets a dismiss affordance even when the footer stays minimal.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
};
|
||||
|
||||
export const Accessibility: Story = {
|
||||
parameters: {
|
||||
docs: {
|
||||
description: {
|
||||
story:
|
||||
"Use dialog only when the user must resolve or dismiss a blocking task. Focus is trapped while open, Escape closes the surface, and the title and description are announced through the Radix dialog semantics."
|
||||
}
|
||||
}
|
||||
},
|
||||
render: () => (
|
||||
<div className="grid w-[760px] gap-4 lg:grid-cols-[minmax(0,0.95fr)_minmax(0,1.05fr)]">
|
||||
<article className="rounded-[var(--radius-lg)] border border-[var(--color-border)] bg-[var(--color-card)] p-6 shadow-[var(--shadow-sm)]">
|
||||
<h3 className="text-lg font-semibold tracking-[var(--tracking-tight)]">
|
||||
Accessibility notes
|
||||
</h3>
|
||||
<div className="mt-4 grid gap-3 text-sm leading-6 text-[var(--color-muted-foreground)]">
|
||||
<p>Keep the title outcome-oriented so assistive tech announces the decision clearly.</p>
|
||||
<p>
|
||||
Use the description for the consequence or next step, not decorative copy.
|
||||
</p>
|
||||
<p>
|
||||
Keep the trigger specific. "Open approval dialog" is more useful than a generic
|
||||
"Open".
|
||||
</p>
|
||||
<p>
|
||||
Reserve dialogs for blocking work. If the content should not trap focus, prefer
|
||||
a popover instead.
|
||||
</p>
|
||||
</div>
|
||||
</article>
|
||||
<div className="flex items-center justify-center rounded-[var(--radius-lg)] border border-dashed border-[var(--color-border-strong)] bg-[var(--color-background)] p-6">
|
||||
<LaunchDialog
|
||||
description="Keyboard focus moves into the surface, Escape closes it, and the trigger regains focus after dismissal."
|
||||
triggerLabel="Open accessible dialog"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user