@alpic-ai/ui 0.0.0-dev.4a35dc7 → 0.0.0-dev.85c8341

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.
Files changed (93) hide show
  1. package/dist/components/accordion-card.d.mts +1 -1
  2. package/dist/components/accordion.d.mts +1 -1
  3. package/dist/components/alert.d.mts +1 -1
  4. package/dist/components/attachment-tile.mjs +1 -1
  5. package/dist/components/avatar.d.mts +1 -1
  6. package/dist/components/breadcrumb.d.mts +1 -1
  7. package/dist/components/button.d.mts +1 -1
  8. package/dist/components/card.d.mts +1 -1
  9. package/dist/components/checkbox.d.mts +1 -1
  10. package/dist/components/collapsible.d.mts +1 -1
  11. package/dist/components/combobox.d.mts +1 -1
  12. package/dist/components/combobox.mjs +1 -1
  13. package/dist/components/command.d.mts +1 -1
  14. package/dist/components/copyable.d.mts +1 -1
  15. package/dist/components/copyable.mjs +1 -1
  16. package/dist/components/description-list.d.mts +1 -1
  17. package/dist/components/dialog.d.mts +1 -1
  18. package/dist/components/dropdown-menu.d.mts +1 -1
  19. package/dist/components/form.d.mts +119 -0
  20. package/dist/components/form.mjs +192 -0
  21. package/dist/components/input-group.d.mts +1 -1
  22. package/dist/components/input.d.mts +3 -1
  23. package/dist/components/input.mjs +20 -11
  24. package/dist/components/label.d.mts +1 -1
  25. package/dist/components/pagination.d.mts +1 -1
  26. package/dist/components/popover.d.mts +1 -1
  27. package/dist/components/radio-group.d.mts +1 -1
  28. package/dist/components/scroll-area.d.mts +1 -1
  29. package/dist/components/select-trigger-variants.mjs +1 -0
  30. package/dist/components/select.d.mts +1 -1
  31. package/dist/components/separator.d.mts +1 -1
  32. package/dist/components/sheet.d.mts +1 -1
  33. package/dist/components/sidebar.d.mts +1 -1
  34. package/dist/components/sidebar.mjs +2 -2
  35. package/dist/components/sonner.d.mts +1 -1
  36. package/dist/components/switch.d.mts +1 -1
  37. package/dist/components/table.d.mts +1 -1
  38. package/dist/components/tabs.d.mts +1 -1
  39. package/dist/components/tabs.mjs +1 -1
  40. package/dist/components/textarea.d.mts +3 -1
  41. package/dist/components/textarea.mjs +20 -11
  42. package/dist/components/toggle-group.d.mts +1 -1
  43. package/dist/components/toggle-group.mjs +1 -1
  44. package/dist/components/tooltip-icon-button.mjs +1 -1
  45. package/dist/components/tooltip.d.mts +1 -1
  46. package/package.json +4 -5
  47. package/src/components/form.tsx +343 -0
  48. package/src/components/input.tsx +12 -0
  49. package/src/components/select-trigger-variants.ts +1 -0
  50. package/src/components/textarea.tsx +12 -1
  51. package/src/stories/accordion-card.stories.tsx +53 -0
  52. package/src/stories/accordion.stories.tsx +65 -0
  53. package/src/stories/alert.stories.tsx +58 -0
  54. package/src/stories/attachment-tile.stories.tsx +37 -0
  55. package/src/stories/avatar.stories.tsx +54 -0
  56. package/src/stories/badge.stories.tsx +50 -0
  57. package/src/stories/breadcrumb.stories.tsx +107 -0
  58. package/src/stories/button.stories.tsx +342 -0
  59. package/src/stories/card.stories.tsx +89 -0
  60. package/src/stories/checkbox.stories.tsx +56 -0
  61. package/src/stories/collapsible.stories.tsx +69 -0
  62. package/src/stories/combobox.stories.tsx +214 -0
  63. package/src/stories/command.stories.tsx +95 -0
  64. package/src/stories/copyable.stories.tsx +29 -0
  65. package/src/stories/description-list.stories.tsx +71 -0
  66. package/src/stories/dialog.stories.tsx +135 -0
  67. package/src/stories/dropdown-menu.stories.tsx +191 -0
  68. package/src/stories/form.stories.tsx +91 -0
  69. package/src/stories/input-group.stories.tsx +63 -0
  70. package/src/stories/input.stories.tsx +72 -0
  71. package/src/stories/label.stories.tsx +26 -0
  72. package/src/stories/ladle.css +3 -0
  73. package/src/stories/pagination.stories.tsx +35 -0
  74. package/src/stories/popover.stories.tsx +34 -0
  75. package/src/stories/radio-group.stories.tsx +59 -0
  76. package/src/stories/scroll-area.stories.tsx +43 -0
  77. package/src/stories/select.stories.tsx +95 -0
  78. package/src/stories/separator.stories.tsx +36 -0
  79. package/src/stories/sheet.stories.tsx +76 -0
  80. package/src/stories/sidebar.stories.tsx +255 -0
  81. package/src/stories/skeleton.stories.tsx +47 -0
  82. package/src/stories/sonner.stories.tsx +91 -0
  83. package/src/stories/spinner.stories.tsx +66 -0
  84. package/src/stories/status-dot.stories.tsx +27 -0
  85. package/src/stories/switch.stories.tsx +46 -0
  86. package/src/stories/table.stories.tsx +242 -0
  87. package/src/stories/tabs.stories.tsx +169 -0
  88. package/src/stories/tag.stories.tsx +82 -0
  89. package/src/stories/textarea.stories.tsx +60 -0
  90. package/src/stories/toggle-group.stories.tsx +142 -0
  91. package/src/stories/tooltip-icon-button.stories.tsx +59 -0
  92. package/src/stories/tooltip.stories.tsx +54 -0
  93. package/README.md +0 -33
@@ -0,0 +1,191 @@
1
+ import type { Story } from "@ladle/react";
2
+ import {
3
+ Cloud,
4
+ CreditCard,
5
+ GitBranch,
6
+ Keyboard,
7
+ LifeBuoy,
8
+ LogOut,
9
+ Mail,
10
+ MessageSquare,
11
+ Plus,
12
+ PlusCircle,
13
+ Settings,
14
+ Trash2,
15
+ User,
16
+ UserPlus,
17
+ Users,
18
+ } from "lucide-react";
19
+ import { Button } from "../components/button";
20
+ import {
21
+ DropdownMenu,
22
+ DropdownMenuContent,
23
+ DropdownMenuGroup,
24
+ DropdownMenuHeader,
25
+ DropdownMenuItem,
26
+ DropdownMenuLabel,
27
+ DropdownMenuSeparator,
28
+ DropdownMenuShortcut,
29
+ DropdownMenuSub,
30
+ DropdownMenuSubContent,
31
+ DropdownMenuSubTrigger,
32
+ DropdownMenuTrigger,
33
+ } from "../components/dropdown-menu";
34
+
35
+ export const AllVariants: Story = () => (
36
+ <div className="flex flex-col gap-10 p-10">
37
+ {/* Basic with icons & shortcuts */}
38
+ <div className="flex flex-col gap-1.5">
39
+ <p className="type-text-xs font-medium text-subtle-foreground">Default with icons &amp; shortcuts</p>
40
+ <DropdownMenu>
41
+ <DropdownMenuTrigger asChild>
42
+ <Button variant="secondary">Open menu</Button>
43
+ </DropdownMenuTrigger>
44
+ <DropdownMenuContent className="w-56">
45
+ <DropdownMenuLabel>My Account</DropdownMenuLabel>
46
+ <DropdownMenuSeparator />
47
+ <DropdownMenuGroup>
48
+ <DropdownMenuItem>
49
+ <User />
50
+ Profile
51
+ <DropdownMenuShortcut>⇧⌘P</DropdownMenuShortcut>
52
+ </DropdownMenuItem>
53
+ <DropdownMenuItem>
54
+ <CreditCard />
55
+ Billing
56
+ <DropdownMenuShortcut>⌘B</DropdownMenuShortcut>
57
+ </DropdownMenuItem>
58
+ <DropdownMenuItem>
59
+ <Settings />
60
+ Settings
61
+ <DropdownMenuShortcut>⌘S</DropdownMenuShortcut>
62
+ </DropdownMenuItem>
63
+ <DropdownMenuItem>
64
+ <Keyboard />
65
+ Keyboard shortcuts
66
+ <DropdownMenuShortcut>⌘K</DropdownMenuShortcut>
67
+ </DropdownMenuItem>
68
+ </DropdownMenuGroup>
69
+ <DropdownMenuSeparator />
70
+ <DropdownMenuGroup>
71
+ <DropdownMenuItem>
72
+ <Users />
73
+ Team
74
+ </DropdownMenuItem>
75
+ <DropdownMenuSub>
76
+ <DropdownMenuSubTrigger>
77
+ <UserPlus />
78
+ Invite users
79
+ </DropdownMenuSubTrigger>
80
+ <DropdownMenuSubContent>
81
+ <DropdownMenuItem>
82
+ <Mail />
83
+ Email
84
+ </DropdownMenuItem>
85
+ <DropdownMenuItem>
86
+ <MessageSquare />
87
+ Message
88
+ </DropdownMenuItem>
89
+ <DropdownMenuSeparator />
90
+ <DropdownMenuItem>
91
+ <PlusCircle />
92
+ More...
93
+ </DropdownMenuItem>
94
+ </DropdownMenuSubContent>
95
+ </DropdownMenuSub>
96
+ <DropdownMenuItem>
97
+ <Plus />
98
+ New Team
99
+ <DropdownMenuShortcut>⌘+T</DropdownMenuShortcut>
100
+ </DropdownMenuItem>
101
+ </DropdownMenuGroup>
102
+ <DropdownMenuSeparator />
103
+ <DropdownMenuItem>
104
+ <GitBranch />
105
+ GitHub
106
+ </DropdownMenuItem>
107
+ <DropdownMenuItem>
108
+ <LifeBuoy />
109
+ Support
110
+ </DropdownMenuItem>
111
+ <DropdownMenuItem disabled>
112
+ <Cloud />
113
+ API
114
+ </DropdownMenuItem>
115
+ <DropdownMenuSeparator />
116
+ <DropdownMenuItem variant="destructive">
117
+ <LogOut />
118
+ Log out
119
+ <DropdownMenuShortcut>⇧⌘Q</DropdownMenuShortcut>
120
+ </DropdownMenuItem>
121
+ </DropdownMenuContent>
122
+ </DropdownMenu>
123
+ </div>
124
+
125
+ {/* Destructive variant */}
126
+ <div className="flex flex-col gap-1.5">
127
+ <p className="type-text-xs font-medium text-subtle-foreground">Destructive item</p>
128
+ <DropdownMenu>
129
+ <DropdownMenuTrigger asChild>
130
+ <Button variant="secondary">Actions</Button>
131
+ </DropdownMenuTrigger>
132
+ <DropdownMenuContent>
133
+ <DropdownMenuItem>
134
+ <Settings />
135
+ Settings
136
+ </DropdownMenuItem>
137
+ <DropdownMenuSeparator />
138
+ <DropdownMenuItem variant="destructive">
139
+ <Trash2 />
140
+ Delete
141
+ </DropdownMenuItem>
142
+ </DropdownMenuContent>
143
+ </DropdownMenu>
144
+ </div>
145
+
146
+ {/* Header with avatar */}
147
+ <div className="flex flex-col gap-1.5">
148
+ <p className="type-text-xs font-medium text-subtle-foreground">With header (avatar group)</p>
149
+ <DropdownMenu>
150
+ <DropdownMenuTrigger asChild>
151
+ <Button variant="secondary">Account</Button>
152
+ </DropdownMenuTrigger>
153
+ <DropdownMenuContent className="w-60">
154
+ <DropdownMenuHeader>
155
+ <div className="flex size-10 items-center justify-center rounded-full bg-primary text-primary-foreground type-text-sm font-semibold">
156
+ OR
157
+ </div>
158
+ <div className="flex flex-col">
159
+ <span className="type-text-sm font-semibold text-foreground">Olivia Rhye</span>
160
+ <span className="type-text-sm text-subtle-foreground">olivia@alpic.ai</span>
161
+ </div>
162
+ </DropdownMenuHeader>
163
+ <DropdownMenuItem>
164
+ <Settings />
165
+ Settings
166
+ </DropdownMenuItem>
167
+ <DropdownMenuSeparator />
168
+ <DropdownMenuItem variant="destructive">
169
+ <LogOut />
170
+ Log out
171
+ </DropdownMenuItem>
172
+ </DropdownMenuContent>
173
+ </DropdownMenu>
174
+ </div>
175
+
176
+ {/* Disabled items */}
177
+ <div className="flex flex-col gap-1.5">
178
+ <p className="type-text-xs font-medium text-subtle-foreground">Disabled items</p>
179
+ <DropdownMenu>
180
+ <DropdownMenuTrigger asChild>
181
+ <Button variant="secondary">Options</Button>
182
+ </DropdownMenuTrigger>
183
+ <DropdownMenuContent>
184
+ <DropdownMenuItem>Enabled item</DropdownMenuItem>
185
+ <DropdownMenuItem disabled>Disabled item</DropdownMenuItem>
186
+ <DropdownMenuItem>Another enabled item</DropdownMenuItem>
187
+ </DropdownMenuContent>
188
+ </DropdownMenu>
189
+ </div>
190
+ </div>
191
+ );
@@ -0,0 +1,91 @@
1
+ import type { Story } from "@ladle/react";
2
+ import { useForm } from "react-hook-form";
3
+ import { Form, FormFields, FormHeader, InputField, SelectField, TextareaField } from "../components/form";
4
+
5
+ /* ── Types ───────────────────────────────────────────────────────────────── */
6
+
7
+ interface CreateProjectForm {
8
+ email: string;
9
+ role: string;
10
+ description: string;
11
+ }
12
+
13
+ const roles = [
14
+ { value: "admin", label: "Admin" },
15
+ { value: "editor", label: "Editor" },
16
+ { value: "viewer", label: "Viewer" },
17
+ ];
18
+
19
+ /* ── Composed Form ───────────────────────────────────────────────────────── */
20
+
21
+ function ComposedForm() {
22
+ const form = useForm<CreateProjectForm>({
23
+ defaultValues: { email: "", role: "", description: "" },
24
+ });
25
+
26
+ const onSubmit = (data: CreateProjectForm) => {
27
+ alert(JSON.stringify(data, null, 2));
28
+ };
29
+
30
+ return (
31
+ <div className="flex flex-col max-w-[480px] p-6 rounded-2xl border border-border bg-background">
32
+ <Form {...form}>
33
+ <form onSubmit={form.handleSubmit(onSubmit)}>
34
+ <FormHeader title="Create project" description="Set up your new project with a few details." />
35
+
36
+ <div className="flex flex-col gap-8 pt-12">
37
+ <FormFields>
38
+ <InputField
39
+ control={form.control}
40
+ name="email"
41
+ rules={{ required: "Email is required." }}
42
+ label="Email"
43
+ placeholder="you@company.com"
44
+ description="We'll use this to send you notifications."
45
+ required
46
+ />
47
+
48
+ <SelectField
49
+ control={form.control}
50
+ name="role"
51
+ rules={{ required: "Role is required." }}
52
+ label="Role"
53
+ placeholder="Select a role..."
54
+ options={roles}
55
+ required
56
+ />
57
+
58
+ <TextareaField
59
+ control={form.control}
60
+ name="description"
61
+ rules={{ required: "Description is required." }}
62
+ label="Description"
63
+ tooltip="Briefly describe what this project is about."
64
+ placeholder="A short description of your project..."
65
+ required
66
+ />
67
+ </FormFields>
68
+
69
+ <button
70
+ type="submit"
71
+ className="flex h-12 w-full items-center justify-center rounded-md bg-primary px-2 type-text-sm font-medium text-primary-foreground"
72
+ >
73
+ Get started
74
+ </button>
75
+ </div>
76
+ </form>
77
+ </Form>
78
+ </div>
79
+ );
80
+ }
81
+
82
+ /* ── Story ────────────────────────────────────────────────────────────────── */
83
+
84
+ export const AllVariants: Story = () => (
85
+ <div className="flex flex-col gap-3">
86
+ <p className="type-text-xs font-medium text-subtle-foreground uppercase tracking-wide">
87
+ Composed form (all field types)
88
+ </p>
89
+ <ComposedForm />
90
+ </div>
91
+ );
@@ -0,0 +1,63 @@
1
+ import type { Story } from "@ladle/react";
2
+ import { Paperclip, Send } from "lucide-react";
3
+
4
+ import { InputGroup, InputGroupAddon, InputGroupTextarea } from "../components/input-group";
5
+
6
+ const SECTION_HEADER = "type-text-xs font-medium text-muted-foreground uppercase tracking-wide pt-4";
7
+
8
+ export const AllVariants: Story = () => (
9
+ <div className="flex flex-col gap-6 p-8 max-w-lg">
10
+ {/* Textarea with block-end addon */}
11
+ <span className={SECTION_HEADER}>Textarea + block-end footer</span>
12
+ <InputGroup>
13
+ <InputGroupTextarea placeholder="Type a message…" />
14
+ <InputGroupAddon align="block-end" className="justify-between">
15
+ <button type="button" className="p-1.5 text-muted-foreground">
16
+ <Paperclip className="size-4" />
17
+ </button>
18
+ <button type="button" className="p-1.5 text-primary">
19
+ <Send className="size-4" />
20
+ </button>
21
+ </InputGroupAddon>
22
+ </InputGroup>
23
+
24
+ {/* Inline-start addon */}
25
+ <span className={SECTION_HEADER}>Inline-start addon (icon)</span>
26
+ <InputGroup>
27
+ <InputGroupAddon align="inline-start">
28
+ <Paperclip className="size-4" />
29
+ </InputGroupAddon>
30
+ <input
31
+ data-slot="input-group-control"
32
+ className="flex-1 min-w-0 bg-transparent py-2 pr-3 outline-none type-text-md text-foreground placeholder:text-placeholder"
33
+ placeholder="Search files…"
34
+ />
35
+ </InputGroup>
36
+
37
+ {/* Inline-end addon */}
38
+ <span className={SECTION_HEADER}>Inline-end addon (button)</span>
39
+ <InputGroup>
40
+ <input
41
+ data-slot="input-group-control"
42
+ className="flex-1 min-w-0 bg-transparent py-2 pl-3 outline-none type-text-md text-foreground placeholder:text-placeholder"
43
+ placeholder="Enter a prompt…"
44
+ />
45
+ <InputGroupAddon align="inline-end">
46
+ <button type="button" className="p-1 text-primary">
47
+ <Send className="size-4" />
48
+ </button>
49
+ </InputGroupAddon>
50
+ </InputGroup>
51
+
52
+ {/* Disabled state */}
53
+ <span className={SECTION_HEADER}>Disabled</span>
54
+ <InputGroup>
55
+ <InputGroupTextarea placeholder="Cannot type here…" disabled />
56
+ <InputGroupAddon align="block-end" className="justify-end">
57
+ <button type="button" className="p-1.5 text-muted-foreground opacity-50" disabled>
58
+ <Send className="size-4" />
59
+ </button>
60
+ </InputGroupAddon>
61
+ </InputGroup>
62
+ </div>
63
+ );
@@ -0,0 +1,72 @@
1
+ import type { Story } from "@ladle/react";
2
+ import { Mail } from "lucide-react";
3
+
4
+ import { Input } from "../components/input";
5
+
6
+ const SECTION_HEADER = "type-text-xs font-medium text-muted-foreground uppercase tracking-wide pt-4";
7
+
8
+ export const AllVariants: Story = () => (
9
+ <div className="flex flex-col gap-6 p-8 max-w-sm">
10
+ {/* Default */}
11
+ <span className={SECTION_HEADER}>Default</span>
12
+ <Input id="default" placeholder="alice@example.com" />
13
+
14
+ {/* With label + hint */}
15
+ <span className={SECTION_HEADER}>With label + hint</span>
16
+ <Input
17
+ id="with-label"
18
+ label="Email"
19
+ required
20
+ placeholder="alice@example.com"
21
+ hint="This is a hint text to help user."
22
+ />
23
+
24
+ {/* With tooltip */}
25
+ <span className={SECTION_HEADER}>With tooltip</span>
26
+ <Input
27
+ id="with-tooltip"
28
+ label="Email"
29
+ required
30
+ tooltip="We'll use this to send you notifications."
31
+ placeholder="alice@example.com"
32
+ />
33
+
34
+ {/* Error */}
35
+ <span className={SECTION_HEADER}>Error</span>
36
+ <Input
37
+ id="error"
38
+ label="Email"
39
+ required
40
+ placeholder="alice@example.com"
41
+ error="Please enter a valid email address."
42
+ />
43
+
44
+ {/* Disabled */}
45
+ <span className={SECTION_HEADER}>Disabled</span>
46
+ <Input
47
+ id="disabled"
48
+ label="Email"
49
+ placeholder="alice@example.com"
50
+ hint="This is a hint text to help user."
51
+ disabled
52
+ />
53
+
54
+ {/* Leading icon */}
55
+ <span className={SECTION_HEADER}>Leading icon (email)</span>
56
+ <Input id="leading-icon" label="Email" required placeholder="alice@example.com" leadingIcon={<Mail />} />
57
+
58
+ {/* Leading text (website) */}
59
+ <span className={SECTION_HEADER}>Leading text</span>
60
+ <Input id="leading-text" label="Website" required placeholder="www.example.com" leadingText="http://" />
61
+
62
+ {/* Small size */}
63
+ <span className={SECTION_HEADER}>Small size</span>
64
+ <Input id="sm-default" size="sm" placeholder="alice@example.com" label="Email" />
65
+
66
+ <span className={SECTION_HEADER}>Small + leading icon</span>
67
+ <Input id="sm-icon" size="sm" placeholder="alice@example.com" leadingIcon={<Mail />} />
68
+
69
+ <span className={SECTION_HEADER}>Small + leading text</span>
70
+ <Input id="sm-text" size="sm" placeholder="www.example.com" leadingText="http://" />
71
+ </div>
72
+ );
@@ -0,0 +1,26 @@
1
+ import type { Story } from "@ladle/react";
2
+ import { Label } from "../components/label";
3
+
4
+ export const AllVariants: Story = () => (
5
+ <div className="flex flex-col gap-6">
6
+ <div className="flex flex-col gap-1.5">
7
+ <p className="type-text-xs font-medium text-subtle-foreground">Default</p>
8
+ <Label>Email address</Label>
9
+ </div>
10
+
11
+ <div className="flex flex-col gap-1.5">
12
+ <p className="type-text-xs font-medium text-subtle-foreground">With input</p>
13
+ <div className="flex flex-col gap-2">
14
+ <Label htmlFor="email">Email address</Label>
15
+ <input id="email" type="email" placeholder="you@example.com" className="rounded-md border px-3 py-2 text-sm" />
16
+ </div>
17
+ </div>
18
+
19
+ <div className="flex flex-col gap-1.5">
20
+ <p className="type-text-xs font-medium text-subtle-foreground">Disabled</p>
21
+ <div className="group" data-disabled="true">
22
+ <Label>Disabled label</Label>
23
+ </div>
24
+ </div>
25
+ </div>
26
+ );
@@ -0,0 +1,3 @@
1
+ @import "tailwindcss";
2
+ @import "tw-animate-css";
3
+ @import "../styles/tokens.css";
@@ -0,0 +1,35 @@
1
+ import type { Story } from "@ladle/react";
2
+ import { useState } from "react";
3
+
4
+ import { Pagination } from "../components/pagination";
5
+
6
+ const SECTION_HEADER = "type-text-xs font-medium text-muted-foreground uppercase tracking-wide pt-4";
7
+
8
+ export const AllVariants: Story = () => {
9
+ const [page, setPage] = useState(1);
10
+
11
+ return (
12
+ <div className="flex flex-col gap-8 p-8 max-w-lg">
13
+ <div>
14
+ <p className={SECTION_HEADER}>Interactive</p>
15
+ <Pagination className="mt-4" currentPage={page} totalPages={5} onPageChange={setPage} />
16
+ </div>
17
+
18
+ <div>
19
+ <p className={SECTION_HEADER}>First page (previous disabled)</p>
20
+ <Pagination className="mt-4" currentPage={1} totalPages={10} onPageChange={() => {}} />
21
+ </div>
22
+
23
+ <div>
24
+ <p className={SECTION_HEADER}>Last page (next disabled)</p>
25
+ <Pagination className="mt-4" currentPage={10} totalPages={10} onPageChange={() => {}} />
26
+ </div>
27
+
28
+ <div>
29
+ <p className={SECTION_HEADER}>Single page (hidden)</p>
30
+ <Pagination className="mt-4" currentPage={1} totalPages={1} onPageChange={() => {}} />
31
+ <p className="type-text-xs text-muted-foreground mt-2">Nothing renders when totalPages &lt;= 1</p>
32
+ </div>
33
+ </div>
34
+ );
35
+ };
@@ -0,0 +1,34 @@
1
+ import type { Story } from "@ladle/react";
2
+ import { Button } from "../components/button";
3
+ import { Popover, PopoverContent, PopoverTrigger } from "../components/popover";
4
+
5
+ export const AllVariants: Story = () => (
6
+ <div className="flex flex-col gap-10 p-10">
7
+ <div className="flex flex-col gap-1.5">
8
+ <p className="type-text-xs font-medium text-subtle-foreground">Default</p>
9
+ <Popover>
10
+ <PopoverTrigger asChild>
11
+ <Button variant="secondary">Open popover</Button>
12
+ </PopoverTrigger>
13
+ <PopoverContent>
14
+ <div className="flex flex-col gap-2">
15
+ <p className="type-text-sm font-semibold text-foreground">Popover content</p>
16
+ <p className="type-text-sm text-muted-foreground">This is a generic floating container.</p>
17
+ </div>
18
+ </PopoverContent>
19
+ </Popover>
20
+ </div>
21
+
22
+ <div className="flex flex-col gap-1.5">
23
+ <p className="type-text-xs font-medium text-subtle-foreground">Align: start</p>
24
+ <Popover>
25
+ <PopoverTrigger asChild>
26
+ <Button variant="secondary">Align start</Button>
27
+ </PopoverTrigger>
28
+ <PopoverContent align="start">
29
+ <p className="type-text-sm text-muted-foreground">Aligned to the start of the trigger.</p>
30
+ </PopoverContent>
31
+ </Popover>
32
+ </div>
33
+ </div>
34
+ );
@@ -0,0 +1,59 @@
1
+ import type { Story } from "@ladle/react";
2
+ import { Label } from "../components/label";
3
+ import { RadioGroup, RadioGroupItem } from "../components/radio-group";
4
+
5
+ export const AllVariants: Story = () => (
6
+ <div className="flex flex-col gap-6">
7
+ <div className="flex flex-col gap-1.5">
8
+ <p className="type-text-xs font-medium text-subtle-foreground">Default</p>
9
+ <RadioGroup defaultValue="option-1">
10
+ <div className="flex items-center gap-2">
11
+ <RadioGroupItem value="option-1" id="r1" />
12
+ <Label htmlFor="r1">Option one</Label>
13
+ </div>
14
+ <div className="flex items-center gap-2">
15
+ <RadioGroupItem value="option-2" id="r2" />
16
+ <Label htmlFor="r2">Option two</Label>
17
+ </div>
18
+ <div className="flex items-center gap-2">
19
+ <RadioGroupItem value="option-3" id="r3" />
20
+ <Label htmlFor="r3">Option three</Label>
21
+ </div>
22
+ </RadioGroup>
23
+ </div>
24
+
25
+ <div className="flex flex-col gap-1.5">
26
+ <p className="type-text-xs font-medium text-subtle-foreground">Disabled</p>
27
+ <RadioGroup defaultValue="option-1" disabled>
28
+ <div className="flex items-center gap-2">
29
+ <RadioGroupItem value="option-1" id="r4" />
30
+ <Label htmlFor="r4">Option one</Label>
31
+ </div>
32
+ <div className="flex items-center gap-2">
33
+ <RadioGroupItem value="option-2" id="r5" />
34
+ <Label htmlFor="r5">Option two</Label>
35
+ </div>
36
+ </RadioGroup>
37
+ </div>
38
+
39
+ <div className="flex flex-col gap-1.5">
40
+ <p className="type-text-xs font-medium text-subtle-foreground">With description</p>
41
+ <RadioGroup defaultValue="auto">
42
+ <div className="flex gap-2">
43
+ <RadioGroupItem value="auto" id="r6" className="mt-0.5" />
44
+ <div className="flex flex-col">
45
+ <Label htmlFor="r6">Auto-detect</Label>
46
+ <p className="type-text-sm text-subtle-foreground">Automatically detect the root directory.</p>
47
+ </div>
48
+ </div>
49
+ <div className="flex gap-2">
50
+ <RadioGroupItem value="manual" id="r7" className="mt-0.5" />
51
+ <div className="flex flex-col">
52
+ <Label htmlFor="r7">Manual</Label>
53
+ <p className="type-text-sm text-subtle-foreground">Specify the root directory manually.</p>
54
+ </div>
55
+ </div>
56
+ </RadioGroup>
57
+ </div>
58
+ </div>
59
+ );
@@ -0,0 +1,43 @@
1
+ import type { Story } from "@ladle/react";
2
+ import { ScrollArea, ScrollBar } from "../components/scroll-area";
3
+ import { Separator } from "../components/separator";
4
+
5
+ const tags = Array.from({ length: 50 }).map((_, index) => `v1.2.0-beta.${index}`);
6
+
7
+ export const AllVariants: Story = () => (
8
+ <div className="flex flex-col gap-6">
9
+ <div className="flex flex-col gap-1.5">
10
+ <p className="type-text-xs font-medium text-subtle-foreground">Vertical</p>
11
+ <ScrollArea className="h-72 w-48 rounded-md border">
12
+ <div className="p-4">
13
+ <h4 className="type-text-sm font-semibold">Tags</h4>
14
+ {tags.map((tag) => (
15
+ <div key={tag}>
16
+ <div className="type-text-sm py-2">{tag}</div>
17
+ <Separator />
18
+ </div>
19
+ ))}
20
+ </div>
21
+ </ScrollArea>
22
+ </div>
23
+
24
+ <div className="flex flex-col gap-1.5">
25
+ <p className="type-text-xs font-medium text-subtle-foreground">Horizontal</p>
26
+ <ScrollArea className="w-96 whitespace-nowrap rounded-md border">
27
+ <div className="flex gap-4 p-4">
28
+ {["Alpha", "Beta", "Gamma", "Delta", "Epsilon", "Zeta", "Eta", "Theta", "Iota", "Kappa", "Lambda", "Mu"].map(
29
+ (label) => (
30
+ <div
31
+ key={label}
32
+ className="flex h-24 w-36 shrink-0 items-center justify-center rounded-md bg-muted type-text-sm"
33
+ >
34
+ {label}
35
+ </div>
36
+ ),
37
+ )}
38
+ </div>
39
+ <ScrollBar orientation="horizontal" />
40
+ </ScrollArea>
41
+ </div>
42
+ </div>
43
+ );