129 lines
3.6 KiB
TypeScript
129 lines
3.6 KiB
TypeScript
import type { Meta, StoryObj } from "@storybook/react-vite";
|
|
import { expect, userEvent, within } from "storybook/test";
|
|
import { useState } from "react";
|
|
|
|
import {
|
|
Alert,
|
|
Badge,
|
|
Button,
|
|
Card,
|
|
Dialog,
|
|
Menu,
|
|
ProgressBar,
|
|
Skeleton,
|
|
Tabs,
|
|
TextArea,
|
|
TextField,
|
|
} from "./index.js";
|
|
|
|
const meta = {
|
|
title: "Platform/Design System",
|
|
component: Button,
|
|
tags: ["autodocs"],
|
|
parameters: {
|
|
layout: "padded",
|
|
},
|
|
} satisfies Meta<typeof Button>;
|
|
|
|
export default meta;
|
|
type Story = StoryObj<typeof meta>;
|
|
|
|
export const Primitives: Story = {
|
|
render: () => (
|
|
<div className="ui-stack">
|
|
<Card title="Actions and status">
|
|
<div className="ui-cluster">
|
|
<Button>Primary</Button>
|
|
<Button variant="secondary">Secondary</Button>
|
|
<Button variant="danger">Danger</Button>
|
|
<Button pending pendingLabel="Processing">
|
|
Save
|
|
</Button>
|
|
</div>
|
|
<div className="ui-cluster">
|
|
<Badge variant="neutral">Neutral</Badge>
|
|
<Badge variant="success">Success</Badge>
|
|
<Badge variant="warning">Warning</Badge>
|
|
<Badge variant="danger">Danger</Badge>
|
|
</div>
|
|
</Card>
|
|
<TextField
|
|
description="A stable accessible description"
|
|
label="Name"
|
|
placeholder="Example"
|
|
/>
|
|
<TextField error="Enter a name" label="Invalid name" value="" readOnly />
|
|
<TextArea
|
|
defaultValue="Long-form content"
|
|
label="Notes"
|
|
maxLength={100}
|
|
/>
|
|
<Alert title="Platform status" variant="info">
|
|
The component workshop uses the same tokens and providers as the app.
|
|
</Alert>
|
|
<ProgressBar label="Build readiness" value={72} />
|
|
<Skeleton label="Loading example" />
|
|
</div>
|
|
),
|
|
};
|
|
|
|
function OverlayExample() {
|
|
const [open, setOpen] = useState(false);
|
|
return (
|
|
<div className="ui-stack">
|
|
<Button onClick={() => setOpen(true)}>Open dialog</Button>
|
|
<Dialog
|
|
actions={<Button onClick={() => setOpen(false)}>Confirm</Button>}
|
|
onClose={() => setOpen(false)}
|
|
open={open}
|
|
title="Confirm platform action"
|
|
>
|
|
Keyboard dismissal must restore focus to the trigger.
|
|
</Dialog>
|
|
<Menu
|
|
items={[
|
|
{ id: "first", label: "First action", onSelect() {} },
|
|
{ id: "second", label: "Second action", onSelect() {} },
|
|
]}
|
|
triggerLabel="Open menu"
|
|
/>
|
|
<Tabs
|
|
defaultValue="one"
|
|
label="Example sections"
|
|
tabs={[
|
|
{ id: "one", label: "One", panel: "First panel" },
|
|
{ id: "two", label: "Two", panel: "Second panel" },
|
|
]}
|
|
/>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
export const OverlayInteraction: Story = {
|
|
render: () => <OverlayExample />,
|
|
play: async ({ canvasElement }) => {
|
|
const canvas = within(canvasElement);
|
|
const trigger = canvas.getByRole("button", { name: "Open dialog" });
|
|
await userEvent.click(trigger);
|
|
const dialog = within(document.body).getByRole("dialog", {
|
|
name: "Confirm platform action",
|
|
});
|
|
await expect(dialog).toBeVisible();
|
|
await userEvent.keyboard("{Escape}");
|
|
await expect(dialog).not.toBeVisible();
|
|
await expect(trigger).toHaveFocus();
|
|
},
|
|
};
|
|
|
|
export const LongPseudoLikeContent: Story = {
|
|
render: () => (
|
|
<Card title="[!! Ćømƥøñëñţ ţøķëñ åñđ ļøñğ ţëжţ vëŕïƒïćåţïøñ !!]">
|
|
<p>
|
|
[!! Ţhïš šţøŕÿ vëŕïƒïëš ţhåţ å ƥŕïmïţïvë ŕëmåïñš ŕëåđåɓļë
|
|
ïñ å ćømƥåćţ ćøñţåïñëŕ. !!]
|
|
</p>
|
|
<Button>[!! Ćøñţïñüë !!]</Button>
|
|
</Card>
|
|
),
|
|
};
|