feat: add sheet component and docs qa baseline
This commit is contained in:
@@ -16,24 +16,15 @@ import {
|
||||
} from "@ai-ui/ui";
|
||||
import type { Meta, StoryObj } from "@storybook/react";
|
||||
|
||||
const meta = {
|
||||
title: "Components/DropdownMenu",
|
||||
component: DropdownMenu,
|
||||
parameters: {
|
||||
layout: "centered"
|
||||
},
|
||||
tags: ["autodocs"]
|
||||
} satisfies Meta<typeof DropdownMenu>;
|
||||
type ReleaseMenuProps = {
|
||||
triggerLabel?: string;
|
||||
};
|
||||
|
||||
export default meta;
|
||||
|
||||
type Story = StoryObj<typeof meta>;
|
||||
|
||||
export const Playground: Story = {
|
||||
render: () => (
|
||||
function ReleaseMenu({ triggerLabel = "Open menu" }: ReleaseMenuProps) {
|
||||
return (
|
||||
<DropdownMenu>
|
||||
<DropdownMenuTrigger asChild>
|
||||
<Button variant="secondary">Open menu</Button>
|
||||
<Button variant="secondary">{triggerLabel}</Button>
|
||||
</DropdownMenuTrigger>
|
||||
<DropdownMenuContent>
|
||||
<DropdownMenuLabel>Launch actions</DropdownMenuLabel>
|
||||
@@ -45,6 +36,10 @@ export const Playground: Story = {
|
||||
Share preview
|
||||
<DropdownMenuShortcut>S</DropdownMenuShortcut>
|
||||
</DropdownMenuItem>
|
||||
<DropdownMenuItem disabled>
|
||||
Retry checks
|
||||
<DropdownMenuShortcut>⌘R</DropdownMenuShortcut>
|
||||
</DropdownMenuItem>
|
||||
<DropdownMenuSeparator />
|
||||
<DropdownMenuCheckboxItem checked>Notify stakeholders</DropdownMenuCheckboxItem>
|
||||
<DropdownMenuSeparator />
|
||||
@@ -62,5 +57,110 @@ export const Playground: Story = {
|
||||
</DropdownMenuSub>
|
||||
</DropdownMenuContent>
|
||||
</DropdownMenu>
|
||||
);
|
||||
}
|
||||
|
||||
const meta = {
|
||||
title: "Components/DropdownMenu",
|
||||
component: DropdownMenu,
|
||||
parameters: {
|
||||
docs: {
|
||||
description: {
|
||||
component:
|
||||
"DropdownMenu is the compact action surface for contextual commands, quick toggles, and short decision trees. It supports labels, separators, nested submenus, checkbox and radio items, destructive emphasis, and keyboard-first navigation without introducing a separate API style."
|
||||
}
|
||||
},
|
||||
layout: "centered"
|
||||
},
|
||||
tags: ["autodocs"]
|
||||
} satisfies Meta<typeof DropdownMenu>;
|
||||
|
||||
export default meta;
|
||||
|
||||
type Story = StoryObj<typeof meta>;
|
||||
|
||||
export const Playground: Story = {
|
||||
render: () => <ReleaseMenu />
|
||||
};
|
||||
|
||||
export const States: Story = {
|
||||
parameters: {
|
||||
docs: {
|
||||
description: {
|
||||
story:
|
||||
"Open the menu to inspect the checked checkbox item, the selected radio item, a disabled action, the inset submenu trigger, and the destructive nested action."
|
||||
}
|
||||
}
|
||||
},
|
||||
render: () => (
|
||||
<div className="grid w-[680px] gap-3 sm:grid-cols-2">
|
||||
<ReleaseMenu triggerLabel="Review lane menu" />
|
||||
<ReleaseMenu triggerLabel="Launch action menu" />
|
||||
</div>
|
||||
)
|
||||
};
|
||||
|
||||
export const Anatomy: Story = {
|
||||
render: () => (
|
||||
<div className="w-[720px] 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)]">
|
||||
Dropdown menu anatomy
|
||||
</p>
|
||||
<ReleaseMenu triggerLabel="Inspect menu structure" />
|
||||
<div className="grid gap-3 text-sm leading-6 text-[var(--color-muted-foreground)]">
|
||||
<p>
|
||||
<code className="text-[var(--color-foreground)]">data-slot="content"</code> frames
|
||||
the floating panel and exposes sizing for denser menus.
|
||||
</p>
|
||||
<p>
|
||||
<code className="text-[var(--color-foreground)]">data-slot="item"</code>,{" "}
|
||||
<code className="text-[var(--color-foreground)]">data-slot="trigger"</code>, and{" "}
|
||||
<code className="text-[var(--color-foreground)]">data-slot="shortcut"</code> map the
|
||||
action rows, nested trigger, and keyboard hint.
|
||||
</p>
|
||||
<p>
|
||||
<code className="text-[var(--color-foreground)]">data-slot="label"</code>,{" "}
|
||||
<code className="text-[var(--color-foreground)]">data-slot="separator"</code>, and{" "}
|
||||
<code className="text-[var(--color-foreground)]">data-slot="icon"</code> support
|
||||
grouping, dividers, and selection markers.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
};
|
||||
|
||||
export const Accessibility: Story = {
|
||||
parameters: {
|
||||
docs: {
|
||||
description: {
|
||||
story:
|
||||
"Dropdown menus are optimized for keyboard and pointer parity. Focus moves with arrow keys, typeahead remains available through Radix semantics, and destructive options should stay visually distinct from neutral commands."
|
||||
}
|
||||
}
|
||||
},
|
||||
render: () => (
|
||||
<div className="grid w-[760px] gap-4 lg:grid-cols-[minmax(0,0.9fr)_minmax(0,1.1fr)]">
|
||||
<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)]">
|
||||
Keyboard guidance
|
||||
</h3>
|
||||
<div className="mt-4 grid gap-3 text-sm leading-6 text-[var(--color-muted-foreground)]">
|
||||
<p>Use labels and separators to group commands into short scannable clusters.</p>
|
||||
<p>
|
||||
Keep checkbox and radio items in menus only when the state change is immediate
|
||||
and local to the current context.
|
||||
</p>
|
||||
<p>
|
||||
Prefer concise labels. Long explanatory copy belongs in a dialog or popover,
|
||||
not in a menu row.
|
||||
</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">
|
||||
<ReleaseMenu triggerLabel="Open keyboard-friendly menu" />
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user