open-ds 0.0.0-stage → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +66 -2
- package/assets/schemes/accessible-first.json +3093 -0
- package/assets/schemes/brand-expressive.json +3124 -0
- package/assets/schemes/content-first.json +3110 -0
- package/assets/schemes/dense-data.json +3489 -0
- package/assets/schemes/grammar.json +3903 -0
- package/assets/schemes/multi-brand.json +4359 -0
- package/assets/skills/open-ds/SKILL.md +50 -0
- package/assets/skills/open-ds-build/SKILL.md +19 -0
- package/assets/skills/open-ds-change/SKILL.md +19 -0
- package/assets/skills/open-ds-choose/SKILL.md +18 -0
- package/assets/skills/open-ds-review/SKILL.md +22 -0
- package/assets/skills/open-ds-write/SKILL.md +13 -0
- package/assets/stories/accordion.stories.tsx +46 -0
- package/assets/stories/alert-dialog.stories.tsx +65 -0
- package/assets/stories/alert.stories.tsx +44 -0
- package/assets/stories/aspect-ratio.stories.tsx +37 -0
- package/assets/stories/avatar.stories.tsx +42 -0
- package/assets/stories/badge.stories.tsx +39 -0
- package/assets/stories/breadcrumb.stories.tsx +54 -0
- package/assets/stories/button.stories.tsx +46 -0
- package/assets/stories/calendar.stories.tsx +30 -0
- package/assets/stories/card.stories.tsx +50 -0
- package/assets/stories/carousel.stories.tsx +64 -0
- package/assets/stories/chart.stories.tsx +61 -0
- package/assets/stories/checkbox.stories.tsx +29 -0
- package/assets/stories/collapsible.stories.tsx +39 -0
- package/assets/stories/combobox.stories.tsx +57 -0
- package/assets/stories/command.stories.tsx +60 -0
- package/assets/stories/context-menu.stories.tsx +55 -0
- package/assets/stories/data-table.stories.tsx +93 -0
- package/assets/stories/date-picker.stories.tsx +27 -0
- package/assets/stories/dialog.stories.tsx +70 -0
- package/assets/stories/drawer.stories.tsx +62 -0
- package/assets/stories/dropdown-menu.stories.tsx +65 -0
- package/assets/stories/empty.stories.tsx +39 -0
- package/assets/stories/field.stories.tsx +42 -0
- package/assets/stories/form.stories.tsx +56 -0
- package/assets/stories/input-group.stories.tsx +41 -0
- package/assets/stories/input-otp.stories.tsx +48 -0
- package/assets/stories/input.stories.tsx +32 -0
- package/assets/stories/kbd.stories.tsx +30 -0
- package/assets/stories/label.stories.tsx +26 -0
- package/assets/stories/native-select.stories.tsx +39 -0
- package/assets/stories/navigation-menu.stories.tsx +41 -0
- package/assets/stories/pagination.stories.tsx +61 -0
- package/assets/stories/popover.stories.tsx +37 -0
- package/assets/stories/progress.stories.tsx +30 -0
- package/assets/stories/radio-group.stories.tsx +45 -0
- package/assets/stories/resizable.stories.tsx +54 -0
- package/assets/stories/scroll-area.stories.tsx +47 -0
- package/assets/stories/select.stories.tsx +57 -0
- package/assets/stories/separator.stories.tsx +28 -0
- package/assets/stories/sheet.stories.tsx +46 -0
- package/assets/stories/sidebar.stories.tsx +62 -0
- package/assets/stories/skeleton.stories.tsx +27 -0
- package/assets/stories/slider.stories.tsx +44 -0
- package/assets/stories/spinner.stories.tsx +25 -0
- package/assets/stories/switch.stories.tsx +29 -0
- package/assets/stories/table.stories.tsx +97 -0
- package/assets/stories/tabs.stories.tsx +55 -0
- package/assets/stories/textarea.stories.tsx +28 -0
- package/assets/stories/toast.stories.tsx +30 -0
- package/assets/stories/toggle-group.stories.tsx +41 -0
- package/assets/stories/toggle.stories.tsx +20 -0
- package/assets/stories/tooltip.stories.tsx +49 -0
- package/assets/tokens/accessible-first/content.json +32 -0
- package/assets/tokens/accessible-first/dark.tokens.json +581 -0
- package/assets/tokens/accessible-first/light.tokens.json +581 -0
- package/assets/tokens/accessible-first/shadcn.css +21 -0
- package/assets/tokens/accessible-first/theme.css +101 -0
- package/assets/tokens/accessible-first/tokens.css +331 -0
- package/assets/tokens/accessible-first/tokens.json +1616 -0
- package/assets/tokens/accessible-first/tokens.scoped.css +333 -0
- package/assets/tokens/brand-expressive/content.json +32 -0
- package/assets/tokens/brand-expressive/dark.tokens.json +585 -0
- package/assets/tokens/brand-expressive/light.tokens.json +585 -0
- package/assets/tokens/brand-expressive/shadcn.css +21 -0
- package/assets/tokens/brand-expressive/theme.css +101 -0
- package/assets/tokens/brand-expressive/tokens.css +331 -0
- package/assets/tokens/brand-expressive/tokens.json +1651 -0
- package/assets/tokens/brand-expressive/tokens.scoped.css +333 -0
- package/assets/tokens/content-first/content.json +32 -0
- package/assets/tokens/content-first/dark.tokens.json +582 -0
- package/assets/tokens/content-first/light.tokens.json +582 -0
- package/assets/tokens/content-first/shadcn.css +21 -0
- package/assets/tokens/content-first/theme.css +101 -0
- package/assets/tokens/content-first/tokens.css +331 -0
- package/assets/tokens/content-first/tokens.json +1631 -0
- package/assets/tokens/content-first/tokens.scoped.css +333 -0
- package/assets/tokens/dense-data/content.json +32 -0
- package/assets/tokens/dense-data/dark.tokens.json +580 -0
- package/assets/tokens/dense-data/light.tokens.json +580 -0
- package/assets/tokens/dense-data/shadcn.css +21 -0
- package/assets/tokens/dense-data/theme.css +101 -0
- package/assets/tokens/dense-data/tokens.css +331 -0
- package/assets/tokens/dense-data/tokens.json +1623 -0
- package/assets/tokens/dense-data/tokens.scoped.css +333 -0
- package/assets/tokens/index.json +143 -0
- package/assets/tokens/multi-brand/aster-dark.tokens.json +625 -0
- package/assets/tokens/multi-brand/aster-light.tokens.json +625 -0
- package/assets/tokens/multi-brand/birch-dark.tokens.json +625 -0
- package/assets/tokens/multi-brand/birch-light.tokens.json +625 -0
- package/assets/tokens/multi-brand/content.json +32 -0
- package/assets/tokens/multi-brand/coral-dark.tokens.json +625 -0
- package/assets/tokens/multi-brand/coral-light.tokens.json +625 -0
- package/assets/tokens/multi-brand/shadcn.css +21 -0
- package/assets/tokens/multi-brand/theme.css +101 -0
- package/assets/tokens/multi-brand/tokens.css +1002 -0
- package/assets/tokens/multi-brand/tokens.json +1754 -0
- package/assets/tokens/multi-brand/tokens.scoped.css +1022 -0
- package/assets/tokens/shadcn-map.json +34 -0
- package/assets/ui/components/accordion.tsx +60 -0
- package/assets/ui/components/alert-dialog.tsx +171 -0
- package/assets/ui/components/alert.tsx +56 -0
- package/assets/ui/components/aspect-ratio.tsx +17 -0
- package/assets/ui/components/avatar.tsx +96 -0
- package/assets/ui/components/badge.tsx +36 -0
- package/assets/ui/components/breadcrumb.tsx +99 -0
- package/assets/ui/components/button.tsx +53 -0
- package/assets/ui/components/calendar.tsx +169 -0
- package/assets/ui/components/card.tsx +72 -0
- package/assets/ui/components/carousel.tsx +224 -0
- package/assets/ui/components/chart.tsx +315 -0
- package/assets/ui/components/checkbox.tsx +29 -0
- package/assets/ui/components/collapsible.tsx +25 -0
- package/assets/ui/components/combobox.tsx +275 -0
- package/assets/ui/components/command.tsx +145 -0
- package/assets/ui/components/context-menu.tsx +218 -0
- package/assets/ui/components/data-table.tsx +307 -0
- package/assets/ui/components/date-picker.tsx +79 -0
- package/assets/ui/components/dialog.tsx +68 -0
- package/assets/ui/components/drawer.tsx +115 -0
- package/assets/ui/components/dropdown-menu.tsx +58 -0
- package/assets/ui/components/empty.tsx +92 -0
- package/assets/ui/components/field.tsx +234 -0
- package/assets/ui/components/form.tsx +146 -0
- package/assets/ui/components/input-group.tsx +154 -0
- package/assets/ui/components/input-otp.tsx +75 -0
- package/assets/ui/components/input.tsx +25 -0
- package/assets/ui/components/kbd.tsx +30 -0
- package/assets/ui/components/label.tsx +22 -0
- package/assets/ui/components/native-select.tsx +59 -0
- package/assets/ui/components/navigation-menu.tsx +149 -0
- package/assets/ui/components/pagination.tsx +108 -0
- package/assets/ui/components/popover.tsx +61 -0
- package/assets/ui/components/progress.tsx +31 -0
- package/assets/ui/components/radio-group.tsx +40 -0
- package/assets/ui/components/resizable.tsx +54 -0
- package/assets/ui/components/scroll-area.tsx +55 -0
- package/assets/ui/components/select.tsx +81 -0
- package/assets/ui/components/separator.tsx +35 -0
- package/assets/ui/components/sheet.tsx +114 -0
- package/assets/ui/components/sidebar.tsx +685 -0
- package/assets/ui/components/skeleton.tsx +15 -0
- package/assets/ui/components/slider.tsx +70 -0
- package/assets/ui/components/spinner.tsx +16 -0
- package/assets/ui/components/switch.tsx +32 -0
- package/assets/ui/components/table.tsx +78 -0
- package/assets/ui/components/tabs.tsx +49 -0
- package/assets/ui/components/textarea.tsx +25 -0
- package/assets/ui/components/toast.tsx +54 -0
- package/assets/ui/components/toggle-group.tsx +88 -0
- package/assets/ui/components/toggle.tsx +48 -0
- package/assets/ui/components/tooltip.tsx +34 -0
- package/assets/ui/lib/use-mobile.ts +20 -0
- package/assets/ui/lib/utils.ts +7 -0
- package/assets/ui/styles.css +27 -0
- package/bin/open-ds.js +6 -0
- package/package.json +56 -4
- package/src/agents.mjs +150 -0
- package/src/cli.mjs +445 -0
- package/src/components.mjs +69 -0
- package/src/context.mjs +143 -0
- package/src/create.mjs +377 -0
- package/src/docs.mjs +570 -0
- package/src/guidance.mjs +63 -0
- package/src/index.mjs +20 -0
- package/src/mcp.mjs +660 -0
- package/src/readmes.mjs +106 -0
- package/src/schemes.mjs +188 -0
- package/src/tokens.mjs +127 -0
- package/templates/project/.github/workflows/ci.yml +15 -0
- package/templates/project/.storybook/component-docs.mdx +26 -0
- package/templates/project/.storybook/main.ts +17 -0
- package/templates/project/.storybook/manager-head.html +3 -0
- package/templates/project/.storybook/manager.ts +37 -0
- package/templates/project/.storybook/preview-head.html +3 -0
- package/templates/project/.storybook/preview.tsx +82 -0
- package/templates/project/docs/docusaurus.config.ts +64 -0
- package/templates/project/docs/sidebars.ts +8 -0
- package/templates/project/docs/src/css/custom.css +275 -0
- package/templates/project/gitignore +6 -0
- package/templates/project/src/styles/index.css +16 -0
- package/templates/project/src/vite-env.d.ts +7 -0
- package/templates/project/stories/docs-blocks.tsx +190 -0
- package/templates/project/stories/samples.tsx +102 -0
- package/templates/project/stories/usage.tsx +31 -0
- package/templates/project/tokens/build.mjs +468 -0
- package/templates/project/tsconfig.json +15 -0
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from "@storybook/react-vite";
|
|
2
|
+
import {
|
|
3
|
+
Button,
|
|
4
|
+
DropdownMenu,
|
|
5
|
+
DropdownMenuContent,
|
|
6
|
+
DropdownMenuItem,
|
|
7
|
+
DropdownMenuSeparator,
|
|
8
|
+
DropdownMenuTrigger,
|
|
9
|
+
} from "@open-ds/ui";
|
|
10
|
+
import { MoreHorizontal } from "lucide-react";
|
|
11
|
+
import { Show, toneOf } from "../src/samples";
|
|
12
|
+
|
|
13
|
+
const meta = {
|
|
14
|
+
parameters: { openDs: { component: "dropdown-menu", situations: ["row-action", "menu-or-dialog"] } },
|
|
15
|
+
title: "Components/Dropdown menu",
|
|
16
|
+
component: DropdownMenu,
|
|
17
|
+
} satisfies Meta<typeof DropdownMenu>;
|
|
18
|
+
export default meta;
|
|
19
|
+
type Story = StoryObj<typeof meta>;
|
|
20
|
+
|
|
21
|
+
export const Playground: Story = {
|
|
22
|
+
args: { modal: true },
|
|
23
|
+
render: (args) => (
|
|
24
|
+
<Show component="dropdown-menu">
|
|
25
|
+
{(s) => (
|
|
26
|
+
<DropdownMenu {...args}>
|
|
27
|
+
<DropdownMenuTrigger asChild>
|
|
28
|
+
<Button variant="secondary">{s.menu!.trigger}</Button>
|
|
29
|
+
</DropdownMenuTrigger>
|
|
30
|
+
<DropdownMenuContent>
|
|
31
|
+
{s.menu!.items.map((item) => (
|
|
32
|
+
<DropdownMenuItem key={item}>{item}</DropdownMenuItem>
|
|
33
|
+
))}
|
|
34
|
+
</DropdownMenuContent>
|
|
35
|
+
</DropdownMenu>
|
|
36
|
+
)}
|
|
37
|
+
</Show>
|
|
38
|
+
),
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
// The destructive action sits last, in the danger tone, because choosing it loses something.
|
|
42
|
+
export const Examples: Story = {
|
|
43
|
+
render: () => (
|
|
44
|
+
<Show component="dropdown-menu">
|
|
45
|
+
{(s) => (
|
|
46
|
+
<div>
|
|
47
|
+
<DropdownMenu>
|
|
48
|
+
<DropdownMenuTrigger asChild>
|
|
49
|
+
<Button variant="ghost" size="icon" aria-label={s.menu!.trigger}>
|
|
50
|
+
<MoreHorizontal />
|
|
51
|
+
</Button>
|
|
52
|
+
</DropdownMenuTrigger>
|
|
53
|
+
<DropdownMenuContent>
|
|
54
|
+
{s.menu!.items.map((item) => (
|
|
55
|
+
<DropdownMenuItem key={item}>{item}</DropdownMenuItem>
|
|
56
|
+
))}
|
|
57
|
+
<DropdownMenuSeparator />
|
|
58
|
+
<DropdownMenuItem tone="danger">{s.menu!.destructive}</DropdownMenuItem>
|
|
59
|
+
</DropdownMenuContent>
|
|
60
|
+
</DropdownMenu>
|
|
61
|
+
</div>
|
|
62
|
+
)}
|
|
63
|
+
</Show>
|
|
64
|
+
),
|
|
65
|
+
};
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from "@storybook/react-vite";
|
|
2
|
+
import { Empty, EmptyHeader, EmptyTitle, EmptyDescription, EmptyContent, Button } from "@open-ds/ui";
|
|
3
|
+
import { Show } from "../src/samples";
|
|
4
|
+
|
|
5
|
+
const meta = {
|
|
6
|
+
parameters: { openDs: { component: "empty", situations: ["empty-words"] } },
|
|
7
|
+
title: "Components/Empty",
|
|
8
|
+
component: Empty,
|
|
9
|
+
} satisfies Meta<typeof Empty>;
|
|
10
|
+
export default meta;
|
|
11
|
+
type Story = StoryObj<typeof meta>;
|
|
12
|
+
|
|
13
|
+
export const Playground: Story = {
|
|
14
|
+
render: (args) => (
|
|
15
|
+
<Empty {...args}>
|
|
16
|
+
<EmptyHeader>
|
|
17
|
+
<EmptyTitle>Nothing here yet</EmptyTitle>
|
|
18
|
+
</EmptyHeader>
|
|
19
|
+
</Empty>
|
|
20
|
+
),
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
export const Examples: Story = {
|
|
24
|
+
render: () => (
|
|
25
|
+
<Show component="empty">
|
|
26
|
+
{(s) => (
|
|
27
|
+
<Empty className="max-w-lg border border-dashed border-[var(--color-border-strong)]">
|
|
28
|
+
<EmptyHeader>
|
|
29
|
+
<EmptyTitle>{s.messages?.neutral ?? s.screen}</EmptyTitle>
|
|
30
|
+
<EmptyDescription>{s.field.hint}</EmptyDescription>
|
|
31
|
+
</EmptyHeader>
|
|
32
|
+
<EmptyContent>
|
|
33
|
+
<Button>{s.actions.primary}</Button>
|
|
34
|
+
</EmptyContent>
|
|
35
|
+
</Empty>
|
|
36
|
+
)}
|
|
37
|
+
</Show>
|
|
38
|
+
),
|
|
39
|
+
};
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from "@storybook/react-vite";
|
|
2
|
+
import { Field, FieldLabel, FieldDescription, FieldError, Input } from "@open-ds/ui";
|
|
3
|
+
import { Show } from "../src/samples";
|
|
4
|
+
|
|
5
|
+
const meta = {
|
|
6
|
+
parameters: { openDs: { component: "field", situations: ["field-label", "error-message"] } },
|
|
7
|
+
title: "Components/Field",
|
|
8
|
+
component: Field,
|
|
9
|
+
} satisfies Meta<typeof Field>;
|
|
10
|
+
export default meta;
|
|
11
|
+
type Story = StoryObj<typeof meta>;
|
|
12
|
+
|
|
13
|
+
export const Playground: Story = {
|
|
14
|
+
render: (args) => (
|
|
15
|
+
<Field {...args} className="max-w-sm">
|
|
16
|
+
<FieldLabel htmlFor="f-play">Label</FieldLabel>
|
|
17
|
+
<Input id="f-play" />
|
|
18
|
+
<FieldDescription>A hint.</FieldDescription>
|
|
19
|
+
</Field>
|
|
20
|
+
),
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
export const Examples: Story = {
|
|
24
|
+
render: () => (
|
|
25
|
+
<Show component="field">
|
|
26
|
+
{(s) => (
|
|
27
|
+
<div className="grid max-w-sm gap-[var(--space-gap-group)]">
|
|
28
|
+
<Field>
|
|
29
|
+
<FieldLabel htmlFor="f-ok">{s.field.label}</FieldLabel>
|
|
30
|
+
<Input id="f-ok" placeholder={s.field.placeholder || undefined} />
|
|
31
|
+
<FieldDescription>{s.field.hint}</FieldDescription>
|
|
32
|
+
</Field>
|
|
33
|
+
<Field data-invalid>
|
|
34
|
+
<FieldLabel htmlFor="f-bad">{s.field.label}</FieldLabel>
|
|
35
|
+
<Input id="f-bad" aria-invalid defaultValue={s.field.invalid} />
|
|
36
|
+
<FieldError>{s.field.error}</FieldError>
|
|
37
|
+
</Field>
|
|
38
|
+
</div>
|
|
39
|
+
)}
|
|
40
|
+
</Show>
|
|
41
|
+
),
|
|
42
|
+
};
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from "@storybook/react-vite";
|
|
2
|
+
import {
|
|
3
|
+
Form,
|
|
4
|
+
FormField,
|
|
5
|
+
FormItem,
|
|
6
|
+
FormLabel,
|
|
7
|
+
FormControl,
|
|
8
|
+
FormDescription,
|
|
9
|
+
FormMessage,
|
|
10
|
+
Input,
|
|
11
|
+
Button,
|
|
12
|
+
} from "@open-ds/ui";
|
|
13
|
+
import { useForm } from "react-hook-form";
|
|
14
|
+
import type { Samples } from "../src/samples";
|
|
15
|
+
import { Show } from "../src/samples";
|
|
16
|
+
|
|
17
|
+
const meta = {
|
|
18
|
+
parameters: { openDs: { component: "form", situations: ["field-label", "error-message"] } },
|
|
19
|
+
title: "Components/Form",
|
|
20
|
+
component: FormItem,
|
|
21
|
+
} satisfies Meta<typeof FormItem>;
|
|
22
|
+
export default meta;
|
|
23
|
+
type Story = StoryObj<typeof meta>;
|
|
24
|
+
|
|
25
|
+
export const Playground: Story = { render: () => <Show component="form">{(s) => <FormExample s={s} />}</Show> };
|
|
26
|
+
|
|
27
|
+
export const Examples: Story = {
|
|
28
|
+
render: () => <Show component="form">{(s) => <FormExample s={s} />}</Show>,
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
// A form wired to react-hook-form: the field shows the scheme's error when the value is empty.
|
|
32
|
+
function FormExample({ s }: { s: Samples }) {
|
|
33
|
+
const form = useForm<{ value: string }>({ defaultValues: { value: "" } });
|
|
34
|
+
return (
|
|
35
|
+
<Form {...form}>
|
|
36
|
+
<form onSubmit={form.handleSubmit(() => undefined)} className="grid max-w-sm gap-[var(--space-gap-group)]">
|
|
37
|
+
<FormField
|
|
38
|
+
control={form.control}
|
|
39
|
+
name="value"
|
|
40
|
+
rules={{ required: s.field.error }}
|
|
41
|
+
render={({ field }) => (
|
|
42
|
+
<FormItem>
|
|
43
|
+
<FormLabel>{s.field.label}</FormLabel>
|
|
44
|
+
<FormControl>
|
|
45
|
+
<Input placeholder={s.field.placeholder || undefined} {...field} />
|
|
46
|
+
</FormControl>
|
|
47
|
+
<FormDescription>{s.field.hint}</FormDescription>
|
|
48
|
+
<FormMessage />
|
|
49
|
+
</FormItem>
|
|
50
|
+
)}
|
|
51
|
+
/>
|
|
52
|
+
<Button type="submit">{s.actions.primary}</Button>
|
|
53
|
+
</form>
|
|
54
|
+
</Form>
|
|
55
|
+
);
|
|
56
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from "@storybook/react-vite";
|
|
2
|
+
import { InputGroup, InputGroupAddon, InputGroupInput, InputGroupText } from "@open-ds/ui";
|
|
3
|
+
import { Search } from "lucide-react";
|
|
4
|
+
import { Show } from "../src/samples";
|
|
5
|
+
|
|
6
|
+
const meta = {
|
|
7
|
+
parameters: { openDs: { component: "input-group", situations: ["field-label", "error-message"] } },
|
|
8
|
+
title: "Components/Input group",
|
|
9
|
+
component: InputGroup,
|
|
10
|
+
} satisfies Meta<typeof InputGroup>;
|
|
11
|
+
export default meta;
|
|
12
|
+
type Story = StoryObj<typeof meta>;
|
|
13
|
+
|
|
14
|
+
export const Playground: Story = {
|
|
15
|
+
render: (args) => (
|
|
16
|
+
<InputGroup {...args} className="max-w-sm">
|
|
17
|
+
<InputGroupAddon>
|
|
18
|
+
<Search />
|
|
19
|
+
</InputGroupAddon>
|
|
20
|
+
<InputGroupInput placeholder="Search" />
|
|
21
|
+
</InputGroup>
|
|
22
|
+
),
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
export const Examples: Story = {
|
|
26
|
+
render: () => (
|
|
27
|
+
<Show component="input-group">
|
|
28
|
+
{(s) => (
|
|
29
|
+
<InputGroup className="max-w-sm">
|
|
30
|
+
<InputGroupAddon>
|
|
31
|
+
<Search />
|
|
32
|
+
</InputGroupAddon>
|
|
33
|
+
<InputGroupInput aria-label={s.field.label} placeholder={s.field.placeholder || s.field.label} />
|
|
34
|
+
<InputGroupAddon align="inline-end">
|
|
35
|
+
<InputGroupText>{s.table?.rows.length ?? s.metrics.length}</InputGroupText>
|
|
36
|
+
</InputGroupAddon>
|
|
37
|
+
</InputGroup>
|
|
38
|
+
)}
|
|
39
|
+
</Show>
|
|
40
|
+
),
|
|
41
|
+
};
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from "@storybook/react-vite";
|
|
2
|
+
import { InputOTP, InputOTPGroup, InputOTPSlot, InputOTPSeparator } from "@open-ds/ui";
|
|
3
|
+
import { Show } from "../src/samples";
|
|
4
|
+
|
|
5
|
+
const meta = {
|
|
6
|
+
parameters: { openDs: { component: "input-otp", situations: ["field-label", "error-message"] } },
|
|
7
|
+
title: "Components/Input otp",
|
|
8
|
+
component: InputOTPGroup,
|
|
9
|
+
} satisfies Meta<typeof InputOTPGroup>;
|
|
10
|
+
export default meta;
|
|
11
|
+
type Story = StoryObj<typeof meta>;
|
|
12
|
+
|
|
13
|
+
export const Playground: Story = {
|
|
14
|
+
render: () => (
|
|
15
|
+
<InputOTP maxLength={6}>
|
|
16
|
+
<InputOTPGroup>
|
|
17
|
+
{[0, 1, 2, 3, 4, 5].map((i) => (
|
|
18
|
+
<InputOTPSlot key={i} index={i} />
|
|
19
|
+
))}
|
|
20
|
+
</InputOTPGroup>
|
|
21
|
+
</InputOTP>
|
|
22
|
+
),
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
export const Examples: Story = {
|
|
26
|
+
render: () => (
|
|
27
|
+
<Show component="input-otp">
|
|
28
|
+
{(s) => (
|
|
29
|
+
<div className="flex flex-col gap-[var(--space-gap-default)]">
|
|
30
|
+
<p className="text-[var(--color-text-secondary)]">{s.field.hint}</p>
|
|
31
|
+
<InputOTP maxLength={6} aria-label={s.field.label}>
|
|
32
|
+
<InputOTPGroup>
|
|
33
|
+
{[0, 1, 2].map((i) => (
|
|
34
|
+
<InputOTPSlot key={i} index={i} />
|
|
35
|
+
))}
|
|
36
|
+
</InputOTPGroup>
|
|
37
|
+
<InputOTPSeparator />
|
|
38
|
+
<InputOTPGroup>
|
|
39
|
+
{[3, 4, 5].map((i) => (
|
|
40
|
+
<InputOTPSlot key={i} index={i} />
|
|
41
|
+
))}
|
|
42
|
+
</InputOTPGroup>
|
|
43
|
+
</InputOTP>
|
|
44
|
+
</div>
|
|
45
|
+
)}
|
|
46
|
+
</Show>
|
|
47
|
+
),
|
|
48
|
+
};
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from "@storybook/react-vite";
|
|
2
|
+
import { Input, Label } from "@open-ds/ui";
|
|
3
|
+
import { Show, toneOf } from "../src/samples";
|
|
4
|
+
|
|
5
|
+
const meta = {
|
|
6
|
+
parameters: { openDs: { component: "input", situations: ["field-label", "error-message", "keyboard-focus"] } },
|
|
7
|
+
title: "Components/Input",
|
|
8
|
+
component: Input,
|
|
9
|
+
} satisfies Meta<typeof Input>;
|
|
10
|
+
export default meta;
|
|
11
|
+
type Story = StoryObj<typeof meta>;
|
|
12
|
+
|
|
13
|
+
export const Playground: Story = { args: { placeholder: "Type here", disabled: false } };
|
|
14
|
+
|
|
15
|
+
export const Examples: Story = {
|
|
16
|
+
render: () => (
|
|
17
|
+
<Show component="input">
|
|
18
|
+
{(s) => (
|
|
19
|
+
<div className="grid max-w-sm gap-[var(--space-gap-tight)]">
|
|
20
|
+
<Label htmlFor="field">{s.field.label}</Label>
|
|
21
|
+
<p className="text-[var(--color-text-secondary)]">{s.field.hint}</p>
|
|
22
|
+
<Input id="field" placeholder={s.field.placeholder || undefined} />
|
|
23
|
+
<Label htmlFor="field-bad">{s.field.label}</Label>
|
|
24
|
+
<Input id="field-bad" aria-invalid aria-describedby="field-error" defaultValue={s.field.invalid} />
|
|
25
|
+
<p id="field-error" className="text-[var(--color-status-danger)]">
|
|
26
|
+
{s.field.error}
|
|
27
|
+
</p>
|
|
28
|
+
</div>
|
|
29
|
+
)}
|
|
30
|
+
</Show>
|
|
31
|
+
),
|
|
32
|
+
};
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from "@storybook/react-vite";
|
|
2
|
+
import { Kbd, KbdGroup } from "@open-ds/ui";
|
|
3
|
+
import { Show } from "../src/samples";
|
|
4
|
+
|
|
5
|
+
const meta = {
|
|
6
|
+
parameters: { openDs: { component: "kbd", situations: ["keyboard-focus"] } },
|
|
7
|
+
title: "Components/Kbd",
|
|
8
|
+
component: Kbd,
|
|
9
|
+
args: { children: "K" },
|
|
10
|
+
} satisfies Meta<typeof Kbd>;
|
|
11
|
+
export default meta;
|
|
12
|
+
type Story = StoryObj<typeof meta>;
|
|
13
|
+
|
|
14
|
+
export const Playground: Story = {};
|
|
15
|
+
|
|
16
|
+
export const Examples: Story = {
|
|
17
|
+
render: () => (
|
|
18
|
+
<Show component="kbd">
|
|
19
|
+
{(s) => (
|
|
20
|
+
<p className="flex items-center gap-[var(--space-gap-default)]">
|
|
21
|
+
{s.icon_action ?? s.actions.primary}
|
|
22
|
+
<KbdGroup>
|
|
23
|
+
<Kbd>Ctrl</Kbd>
|
|
24
|
+
<Kbd>K</Kbd>
|
|
25
|
+
</KbdGroup>
|
|
26
|
+
</p>
|
|
27
|
+
)}
|
|
28
|
+
</Show>
|
|
29
|
+
),
|
|
30
|
+
};
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from "@storybook/react-vite";
|
|
2
|
+
import { Input, Label } from "@open-ds/ui";
|
|
3
|
+
import { Show, toneOf } from "../src/samples";
|
|
4
|
+
|
|
5
|
+
const meta = {
|
|
6
|
+
parameters: { openDs: { component: "label", situations: ["field-label"] } },
|
|
7
|
+
title: "Components/Label",
|
|
8
|
+
component: Label,
|
|
9
|
+
} satisfies Meta<typeof Label>;
|
|
10
|
+
export default meta;
|
|
11
|
+
type Story = StoryObj<typeof meta>;
|
|
12
|
+
|
|
13
|
+
export const Playground: Story = { args: { children: "Label" } };
|
|
14
|
+
|
|
15
|
+
export const Examples: Story = {
|
|
16
|
+
render: () => (
|
|
17
|
+
<Show component="label">
|
|
18
|
+
{(s) => (
|
|
19
|
+
<div className="grid max-w-sm gap-[var(--space-gap-tight)]">
|
|
20
|
+
<Label htmlFor="labelled">{s.field.label}</Label>
|
|
21
|
+
<Input id="labelled" placeholder={s.field.placeholder || undefined} />
|
|
22
|
+
</div>
|
|
23
|
+
)}
|
|
24
|
+
</Show>
|
|
25
|
+
),
|
|
26
|
+
};
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from "@storybook/react-vite";
|
|
2
|
+
import { NativeSelect, NativeSelectOption, Label } from "@open-ds/ui";
|
|
3
|
+
import { Show } from "../src/samples";
|
|
4
|
+
|
|
5
|
+
const meta = {
|
|
6
|
+
parameters: { openDs: { component: "native-select", situations: ["field-label", "error-message"] } },
|
|
7
|
+
title: "Components/Native select",
|
|
8
|
+
component: NativeSelect,
|
|
9
|
+
} satisfies Meta<typeof NativeSelect>;
|
|
10
|
+
export default meta;
|
|
11
|
+
type Story = StoryObj<typeof meta>;
|
|
12
|
+
|
|
13
|
+
export const Playground: Story = {
|
|
14
|
+
render: (args) => (
|
|
15
|
+
<NativeSelect {...args} aria-label="Choice">
|
|
16
|
+
<NativeSelectOption value="a">A</NativeSelectOption>
|
|
17
|
+
<NativeSelectOption value="b">B</NativeSelectOption>
|
|
18
|
+
</NativeSelect>
|
|
19
|
+
),
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
export const Examples: Story = {
|
|
23
|
+
render: () => (
|
|
24
|
+
<Show component="native-select">
|
|
25
|
+
{(s) => (
|
|
26
|
+
<div className="grid max-w-sm gap-[var(--space-gap-tight)]">
|
|
27
|
+
<Label htmlFor="native">{s.select?.label ?? s.field.label}</Label>
|
|
28
|
+
<NativeSelect id="native" defaultValue={s.select?.value}>
|
|
29
|
+
{(s.select?.options ?? s.checkbox ?? s.statuses.map((x) => x.label)).map((o) => (
|
|
30
|
+
<NativeSelectOption key={o} value={o}>
|
|
31
|
+
{o}
|
|
32
|
+
</NativeSelectOption>
|
|
33
|
+
))}
|
|
34
|
+
</NativeSelect>
|
|
35
|
+
</div>
|
|
36
|
+
)}
|
|
37
|
+
</Show>
|
|
38
|
+
),
|
|
39
|
+
};
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from "@storybook/react-vite";
|
|
2
|
+
import { NavigationMenu, NavigationMenuList, NavigationMenuItem, NavigationMenuLink } from "@open-ds/ui";
|
|
3
|
+
import { Show } from "../src/samples";
|
|
4
|
+
|
|
5
|
+
const meta = {
|
|
6
|
+
parameters: { openDs: { component: "navigation-menu", situations: ["link", "keyboard-focus"] } },
|
|
7
|
+
title: "Components/Navigation menu",
|
|
8
|
+
component: NavigationMenu,
|
|
9
|
+
} satisfies Meta<typeof NavigationMenu>;
|
|
10
|
+
export default meta;
|
|
11
|
+
type Story = StoryObj<typeof meta>;
|
|
12
|
+
|
|
13
|
+
export const Playground: Story = {
|
|
14
|
+
render: (args) => (
|
|
15
|
+
<NavigationMenu {...args}>
|
|
16
|
+
<NavigationMenuList>
|
|
17
|
+
<NavigationMenuItem>
|
|
18
|
+
<NavigationMenuLink href="#">Link</NavigationMenuLink>
|
|
19
|
+
</NavigationMenuItem>
|
|
20
|
+
</NavigationMenuList>
|
|
21
|
+
</NavigationMenu>
|
|
22
|
+
),
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
export const Examples: Story = {
|
|
26
|
+
render: () => (
|
|
27
|
+
<Show component="navigation-menu">
|
|
28
|
+
{(s) => (
|
|
29
|
+
<NavigationMenu>
|
|
30
|
+
<NavigationMenuList>
|
|
31
|
+
{(s.tabs?.map((t) => t.label) ?? s.metrics.map((m) => m.label)).map((x) => (
|
|
32
|
+
<NavigationMenuItem key={x}>
|
|
33
|
+
<NavigationMenuLink href="#">{x}</NavigationMenuLink>
|
|
34
|
+
</NavigationMenuItem>
|
|
35
|
+
))}
|
|
36
|
+
</NavigationMenuList>
|
|
37
|
+
</NavigationMenu>
|
|
38
|
+
)}
|
|
39
|
+
</Show>
|
|
40
|
+
),
|
|
41
|
+
};
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from "@storybook/react-vite";
|
|
2
|
+
import {
|
|
3
|
+
Pagination,
|
|
4
|
+
PaginationContent,
|
|
5
|
+
PaginationItem,
|
|
6
|
+
PaginationLink,
|
|
7
|
+
PaginationPrevious,
|
|
8
|
+
PaginationNext,
|
|
9
|
+
} from "@open-ds/ui";
|
|
10
|
+
import { Show } from "../src/samples";
|
|
11
|
+
|
|
12
|
+
const meta = {
|
|
13
|
+
parameters: { openDs: { component: "pagination", situations: ["link", "keyboard-focus"] } },
|
|
14
|
+
title: "Components/Pagination",
|
|
15
|
+
component: Pagination,
|
|
16
|
+
} satisfies Meta<typeof Pagination>;
|
|
17
|
+
export default meta;
|
|
18
|
+
type Story = StoryObj<typeof meta>;
|
|
19
|
+
|
|
20
|
+
export const Playground: Story = {
|
|
21
|
+
render: (args) => (
|
|
22
|
+
<Pagination {...args}>
|
|
23
|
+
<PaginationContent>
|
|
24
|
+
<PaginationItem>
|
|
25
|
+
<PaginationLink href="#" isActive>
|
|
26
|
+
1
|
|
27
|
+
</PaginationLink>
|
|
28
|
+
</PaginationItem>
|
|
29
|
+
</PaginationContent>
|
|
30
|
+
</Pagination>
|
|
31
|
+
),
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
export const Examples: Story = {
|
|
35
|
+
render: () => (
|
|
36
|
+
<Show component="pagination">
|
|
37
|
+
{(s) => (
|
|
38
|
+
<div className="flex flex-col items-start gap-[var(--space-gap-default)]">
|
|
39
|
+
<p className="text-[var(--color-text-secondary)]">{s.table?.caption ?? s.screen}</p>
|
|
40
|
+
<Pagination className="mx-0 justify-start">
|
|
41
|
+
<PaginationContent>
|
|
42
|
+
<PaginationItem>
|
|
43
|
+
<PaginationPrevious href="#" />
|
|
44
|
+
</PaginationItem>
|
|
45
|
+
{[1, 2, 3].map((n) => (
|
|
46
|
+
<PaginationItem key={n}>
|
|
47
|
+
<PaginationLink href="#" isActive={n === 1}>
|
|
48
|
+
{n}
|
|
49
|
+
</PaginationLink>
|
|
50
|
+
</PaginationItem>
|
|
51
|
+
))}
|
|
52
|
+
<PaginationItem>
|
|
53
|
+
<PaginationNext href="#" />
|
|
54
|
+
</PaginationItem>
|
|
55
|
+
</PaginationContent>
|
|
56
|
+
</Pagination>
|
|
57
|
+
</div>
|
|
58
|
+
)}
|
|
59
|
+
</Show>
|
|
60
|
+
),
|
|
61
|
+
};
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from "@storybook/react-vite";
|
|
2
|
+
import { Popover, PopoverTrigger, PopoverContent, Button } from "@open-ds/ui";
|
|
3
|
+
import { Show } from "../src/samples";
|
|
4
|
+
|
|
5
|
+
const meta = {
|
|
6
|
+
parameters: { openDs: { component: "popover", situations: ["menu-or-dialog"] } },
|
|
7
|
+
title: "Components/Popover",
|
|
8
|
+
component: Popover,
|
|
9
|
+
} satisfies Meta<typeof Popover>;
|
|
10
|
+
export default meta;
|
|
11
|
+
type Story = StoryObj<typeof meta>;
|
|
12
|
+
|
|
13
|
+
export const Playground: Story = {
|
|
14
|
+
render: (args) => (
|
|
15
|
+
<Popover {...args}>
|
|
16
|
+
<PopoverTrigger asChild>
|
|
17
|
+
<Button variant="secondary">Open</Button>
|
|
18
|
+
</PopoverTrigger>
|
|
19
|
+
<PopoverContent>Details.</PopoverContent>
|
|
20
|
+
</Popover>
|
|
21
|
+
),
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
export const Examples: Story = {
|
|
25
|
+
render: () => (
|
|
26
|
+
<Show component="popover">
|
|
27
|
+
{(s) => (
|
|
28
|
+
<Popover defaultOpen>
|
|
29
|
+
<PopoverTrigger asChild>
|
|
30
|
+
<Button variant="secondary">{s.card?.title ?? s.actions.secondary}</Button>
|
|
31
|
+
</PopoverTrigger>
|
|
32
|
+
<PopoverContent>{s.card?.description ?? s.field.hint}</PopoverContent>
|
|
33
|
+
</Popover>
|
|
34
|
+
)}
|
|
35
|
+
</Show>
|
|
36
|
+
),
|
|
37
|
+
};
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from "@storybook/react-vite";
|
|
2
|
+
import { Progress } from "@open-ds/ui";
|
|
3
|
+
import { Show } from "../src/samples";
|
|
4
|
+
|
|
5
|
+
const meta = {
|
|
6
|
+
parameters: { openDs: { component: "progress", situations: ["reduced-motion"] } },
|
|
7
|
+
title: "Components/Progress",
|
|
8
|
+
component: Progress,
|
|
9
|
+
args: { value: 40 },
|
|
10
|
+
} satisfies Meta<typeof Progress>;
|
|
11
|
+
export default meta;
|
|
12
|
+
type Story = StoryObj<typeof meta>;
|
|
13
|
+
|
|
14
|
+
export const Playground: Story = { render: (args) => <Progress {...args} className="max-w-sm" /> };
|
|
15
|
+
|
|
16
|
+
export const Examples: Story = {
|
|
17
|
+
render: () => (
|
|
18
|
+
<Show component="progress">
|
|
19
|
+
{(s) => (
|
|
20
|
+
<div className="grid max-w-sm gap-[var(--space-gap-tight)]">
|
|
21
|
+
<p className="flex justify-between">
|
|
22
|
+
<span>{s.metrics[0].label}</span>
|
|
23
|
+
<span className="[font-family:var(--type-data-font-family)]">{s.metrics[0].value}</span>
|
|
24
|
+
</p>
|
|
25
|
+
<Progress value={50} aria-label={s.metrics[0].label} />
|
|
26
|
+
</div>
|
|
27
|
+
)}
|
|
28
|
+
</Show>
|
|
29
|
+
),
|
|
30
|
+
};
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from "@storybook/react-vite";
|
|
2
|
+
import { RadioGroup, RadioGroupItem, Label } from "@open-ds/ui";
|
|
3
|
+
import { Show } from "../src/samples";
|
|
4
|
+
|
|
5
|
+
const meta = {
|
|
6
|
+
parameters: { openDs: { component: "radio-group", situations: ["field-label", "error-message"] } },
|
|
7
|
+
title: "Components/Radio group",
|
|
8
|
+
component: RadioGroup,
|
|
9
|
+
} satisfies Meta<typeof RadioGroup>;
|
|
10
|
+
export default meta;
|
|
11
|
+
type Story = StoryObj<typeof meta>;
|
|
12
|
+
|
|
13
|
+
export const Playground: Story = {
|
|
14
|
+
render: (args) => (
|
|
15
|
+
<RadioGroup {...args} defaultValue="a">
|
|
16
|
+
<Label>
|
|
17
|
+
<RadioGroupItem value="a" /> A
|
|
18
|
+
</Label>
|
|
19
|
+
<Label>
|
|
20
|
+
<RadioGroupItem value="b" /> B
|
|
21
|
+
</Label>
|
|
22
|
+
</RadioGroup>
|
|
23
|
+
),
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
export const Examples: Story = {
|
|
27
|
+
render: () => (
|
|
28
|
+
<Show component="radio-group">
|
|
29
|
+
{(s) => (
|
|
30
|
+
<fieldset className="grid gap-[var(--space-gap-default)]">
|
|
31
|
+
<legend className="mb-[var(--space-gap-default)] [font-weight:var(--type-label-font-weight)]">
|
|
32
|
+
{s.select?.label ?? s.field.label}
|
|
33
|
+
</legend>
|
|
34
|
+
<RadioGroup defaultValue={s.select?.value ?? (s.checkbox ?? s.statuses.map((x) => x.label))[0]}>
|
|
35
|
+
{(s.select?.options ?? s.checkbox ?? s.statuses.map((x) => x.label)).map((o) => (
|
|
36
|
+
<Label key={o}>
|
|
37
|
+
<RadioGroupItem value={o} /> {o}
|
|
38
|
+
</Label>
|
|
39
|
+
))}
|
|
40
|
+
</RadioGroup>
|
|
41
|
+
</fieldset>
|
|
42
|
+
)}
|
|
43
|
+
</Show>
|
|
44
|
+
),
|
|
45
|
+
};
|