@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,27 @@
1
+ import type { Story } from "@ladle/react";
2
+ import { StatusDot } from "../components/status-dot";
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">Success</p>
8
+ <StatusDot variant="success" />
9
+ </div>
10
+ <div className="flex flex-col gap-1.5">
11
+ <p className="type-text-xs font-medium text-subtle-foreground">Destructive</p>
12
+ <StatusDot variant="destructive" />
13
+ </div>
14
+ <div className="flex flex-col gap-1.5">
15
+ <p className="type-text-xs font-medium text-subtle-foreground">Warning</p>
16
+ <StatusDot variant="warning" />
17
+ </div>
18
+ <div className="flex flex-col gap-1.5">
19
+ <p className="type-text-xs font-medium text-subtle-foreground">Muted</p>
20
+ <StatusDot variant="muted" />
21
+ </div>
22
+ <div className="flex flex-col gap-1.5">
23
+ <p className="type-text-xs font-medium text-subtle-foreground">Warning + Pulse</p>
24
+ <StatusDot variant="warning" pulse />
25
+ </div>
26
+ </div>
27
+ );
@@ -0,0 +1,46 @@
1
+ import type { Story } from "@ladle/react";
2
+ import { Label } from "../components/label";
3
+ import { Switch } from "../components/switch";
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">Off (default)</p>
9
+ <Switch />
10
+ </div>
11
+
12
+ <div className="flex flex-col gap-1.5">
13
+ <p className="type-text-xs font-medium text-subtle-foreground">On (defaultChecked)</p>
14
+ <Switch defaultChecked />
15
+ </div>
16
+
17
+ <div className="flex flex-col gap-1.5">
18
+ <p className="type-text-xs font-medium text-subtle-foreground">Disabled (off)</p>
19
+ <Switch disabled />
20
+ </div>
21
+
22
+ <div className="flex flex-col gap-1.5">
23
+ <p className="type-text-xs font-medium text-subtle-foreground">Disabled (on)</p>
24
+ <Switch disabled defaultChecked />
25
+ </div>
26
+
27
+ <div className="flex flex-col gap-1.5">
28
+ <p className="type-text-xs font-medium text-subtle-foreground">With label</p>
29
+ <div className="flex items-center gap-2">
30
+ <Switch id="with-label" />
31
+ <Label htmlFor="with-label">Remember me</Label>
32
+ </div>
33
+ </div>
34
+
35
+ <div className="flex flex-col gap-1.5">
36
+ <p className="type-text-xs font-medium text-subtle-foreground">With label and description</p>
37
+ <div className="flex gap-2">
38
+ <Switch id="with-description" className="mt-0.5" />
39
+ <div className="flex flex-col">
40
+ <Label htmlFor="with-description">Remember me</Label>
41
+ <p className="type-text-sm text-subtle-foreground">Save my login details for next time.</p>
42
+ </div>
43
+ </div>
44
+ </div>
45
+ </div>
46
+ );
@@ -0,0 +1,242 @@
1
+ import type { Story } from "@ladle/react";
2
+ import { useState } from "react";
3
+ import { AvatarLabelGroup } from "../components/avatar";
4
+ import { Badge } from "../components/badge";
5
+ import { Checkbox } from "../components/checkbox";
6
+ import { Pagination } from "../components/pagination";
7
+ import {
8
+ Table,
9
+ TableBody,
10
+ TableCaption,
11
+ TableCell,
12
+ TableFooter,
13
+ TableHead,
14
+ TableHeader,
15
+ TableRow,
16
+ } from "../components/table";
17
+
18
+ const DEMO_AVATAR = "https://i.pravatar.cc/150";
19
+
20
+ const USERS = [
21
+ {
22
+ id: "1",
23
+ name: "Alice Carter",
24
+ handle: "@alice",
25
+ role: "Product Designer",
26
+ email: "alice.carter@example.com",
27
+ status: "Active",
28
+ },
29
+ {
30
+ id: "2",
31
+ name: "Bob Miller",
32
+ handle: "@bob",
33
+ role: "Product Manager",
34
+ email: "bob.miller@example.com",
35
+ status: "Active",
36
+ },
37
+ {
38
+ id: "3",
39
+ name: "Charlie Davis",
40
+ handle: "@charlie",
41
+ role: "Frontend Developer",
42
+ email: "charlie.davis@example.com",
43
+ status: "Active",
44
+ },
45
+ {
46
+ id: "4",
47
+ name: "Diana Moore",
48
+ handle: "@diana",
49
+ role: "Backend Developer",
50
+ email: "diana.moore@example.com",
51
+ status: "Active",
52
+ },
53
+ {
54
+ id: "5",
55
+ name: "Ethan Taylor",
56
+ handle: "@ethan",
57
+ role: "Fullstack Developer",
58
+ email: "ethan.taylor@example.com",
59
+ status: "Active",
60
+ },
61
+ {
62
+ id: "6",
63
+ name: "Fiona Zhang",
64
+ handle: "@fiona",
65
+ role: "DevOps Engineer",
66
+ email: "fiona.zhang@example.com",
67
+ status: "Active",
68
+ },
69
+ {
70
+ id: "7",
71
+ name: "George Kim",
72
+ handle: "@george",
73
+ role: "QA Engineer",
74
+ email: "george.kim@example.com",
75
+ status: "Active",
76
+ },
77
+ {
78
+ id: "8",
79
+ name: "Hannah Lee",
80
+ handle: "@hannah",
81
+ role: "Data Scientist",
82
+ email: "hannah.lee@example.com",
83
+ status: "Inactive",
84
+ },
85
+ ] as const;
86
+
87
+ const PAGE_SIZE = 3;
88
+
89
+ export const AllVariants: Story = () => (
90
+ <div className="flex flex-col gap-8 p-6 bg-background max-w-4xl">
91
+ {/* Text-only table */}
92
+ <div className="flex flex-col gap-1.5">
93
+ <p className="type-text-xs font-medium text-subtle-foreground">Text cells</p>
94
+ <Table>
95
+ <TableHeader>
96
+ <TableRow>
97
+ <TableHead>Name</TableHead>
98
+ <TableHead>Role</TableHead>
99
+ <TableHead>Email</TableHead>
100
+ <TableHead>Status</TableHead>
101
+ </TableRow>
102
+ </TableHeader>
103
+ <TableBody>
104
+ {USERS.map((user) => (
105
+ <TableRow key={user.id}>
106
+ <TableCell className="font-medium text-foreground">{user.name}</TableCell>
107
+ <TableCell className="text-subtle-foreground">{user.role}</TableCell>
108
+ <TableCell className="text-subtle-foreground">{user.email}</TableCell>
109
+ <TableCell>
110
+ <Badge variant="success">{user.status}</Badge>
111
+ </TableCell>
112
+ </TableRow>
113
+ ))}
114
+ </TableBody>
115
+ </Table>
116
+ </div>
117
+
118
+ {/* Avatar cells + checkbox */}
119
+ <div className="flex flex-col gap-1.5">
120
+ <p className="type-text-xs font-medium text-subtle-foreground">Avatar cells + checkbox</p>
121
+ <Table>
122
+ <TableHeader>
123
+ <TableRow>
124
+ <TableHead>
125
+ <Checkbox role="checkbox" aria-label="Select all" />
126
+ </TableHead>
127
+ <TableHead>Name</TableHead>
128
+ <TableHead>Role</TableHead>
129
+ <TableHead>Status</TableHead>
130
+ </TableRow>
131
+ </TableHeader>
132
+ <TableBody>
133
+ {USERS.map((user) => (
134
+ <TableRow key={user.id}>
135
+ <TableCell>
136
+ <Checkbox role="checkbox" aria-label={`Select ${user.name}`} />
137
+ </TableCell>
138
+ <TableCell>
139
+ <AvatarLabelGroup size="md" src={DEMO_AVATAR} name={user.name} label={user.handle} />
140
+ </TableCell>
141
+ <TableCell className="text-subtle-foreground">{user.role}</TableCell>
142
+ <TableCell>
143
+ <Badge variant="success">{user.status}</Badge>
144
+ </TableCell>
145
+ </TableRow>
146
+ ))}
147
+ </TableBody>
148
+ </Table>
149
+ </div>
150
+
151
+ {/* With footer */}
152
+ <div className="flex flex-col gap-1.5">
153
+ <p className="type-text-xs font-medium text-subtle-foreground">With caption + footer</p>
154
+ <Table>
155
+ <TableCaption>Team members — 5 total</TableCaption>
156
+ <TableHeader>
157
+ <TableRow>
158
+ <TableHead>Name</TableHead>
159
+ <TableHead>Role</TableHead>
160
+ <TableHead>Email</TableHead>
161
+ </TableRow>
162
+ </TableHeader>
163
+ <TableBody>
164
+ {USERS.slice(0, 3).map((user) => (
165
+ <TableRow key={user.id}>
166
+ <TableCell className="font-medium text-foreground">{user.name}</TableCell>
167
+ <TableCell className="text-subtle-foreground">{user.role}</TableCell>
168
+ <TableCell className="text-subtle-foreground">{user.email}</TableCell>
169
+ </TableRow>
170
+ ))}
171
+ </TableBody>
172
+ <TableFooter>
173
+ <TableRow>
174
+ <TableCell colSpan={2}>Total</TableCell>
175
+ <TableCell>3 members</TableCell>
176
+ </TableRow>
177
+ </TableFooter>
178
+ </Table>
179
+ </div>
180
+
181
+ {/* Selected row state */}
182
+ <div className="flex flex-col gap-1.5">
183
+ <p className="type-text-xs font-medium text-subtle-foreground">Selected row state</p>
184
+ <Table>
185
+ <TableHeader>
186
+ <TableRow>
187
+ <TableHead>Name</TableHead>
188
+ <TableHead>Role</TableHead>
189
+ <TableHead>Email</TableHead>
190
+ </TableRow>
191
+ </TableHeader>
192
+ <TableBody>
193
+ {USERS.slice(0, 3).map((user, i) => (
194
+ <TableRow key={user.id} data-state={i === 1 ? "selected" : undefined}>
195
+ <TableCell className="font-medium text-foreground">{user.name}</TableCell>
196
+ <TableCell className="text-subtle-foreground">{user.role}</TableCell>
197
+ <TableCell className="text-subtle-foreground">{user.email}</TableCell>
198
+ </TableRow>
199
+ ))}
200
+ </TableBody>
201
+ </Table>
202
+ </div>
203
+
204
+ {/* Paginated table */}
205
+ <PaginatedTableExample />
206
+ </div>
207
+ );
208
+
209
+ function PaginatedTableExample() {
210
+ const [page, setPage] = useState(1);
211
+ const totalPages = Math.ceil(USERS.length / PAGE_SIZE);
212
+ const paginatedUsers = USERS.slice((page - 1) * PAGE_SIZE, page * PAGE_SIZE);
213
+
214
+ return (
215
+ <div className="flex flex-col gap-4">
216
+ <p className="type-text-xs font-medium text-subtle-foreground">With pagination</p>
217
+ <Pagination currentPage={page} totalPages={totalPages} onPageChange={setPage} />
218
+ <Table>
219
+ <TableHeader>
220
+ <TableRow>
221
+ <TableHead>Name</TableHead>
222
+ <TableHead>Role</TableHead>
223
+ <TableHead>Email</TableHead>
224
+ <TableHead>Status</TableHead>
225
+ </TableRow>
226
+ </TableHeader>
227
+ <TableBody>
228
+ {paginatedUsers.map((user) => (
229
+ <TableRow key={user.id}>
230
+ <TableCell className="font-medium text-foreground">{user.name}</TableCell>
231
+ <TableCell className="text-subtle-foreground">{user.role}</TableCell>
232
+ <TableCell className="text-subtle-foreground">{user.email}</TableCell>
233
+ <TableCell>
234
+ <Badge variant={user.status === "Active" ? "success" : "secondary"}>{user.status}</Badge>
235
+ </TableCell>
236
+ </TableRow>
237
+ ))}
238
+ </TableBody>
239
+ </Table>
240
+ </div>
241
+ );
242
+ }
@@ -0,0 +1,169 @@
1
+ import type { Story } from "@ladle/react";
2
+ import { ChartBar, Layers, PackageOpen, Presentation, Rocket, Search, Settings } from "lucide-react";
3
+ import { useEffect, useState } from "react";
4
+
5
+ import { Tabs, TabsContent, TabsList, TabsNav, TabsNavList, TabsNavTrigger, TabsTrigger } from "../components/tabs";
6
+
7
+ const SECTION_HEADER = "type-text-xs font-medium text-muted-foreground uppercase tracking-wide pt-4";
8
+
9
+ const navTabs = [
10
+ { id: "overview", label: "Overview", icon: Presentation },
11
+ { id: "deployments", label: "Deployments", icon: Rocket },
12
+ { id: "analytics", label: "Analytics", icon: ChartBar },
13
+ { id: "logs", label: "Logs", icon: Search },
14
+ { id: "environments", label: "Environments", icon: Layers },
15
+ { id: "distribution", label: "Distribution", icon: PackageOpen },
16
+ { id: "settings", label: "Settings", icon: Settings },
17
+ ];
18
+
19
+ const sideNavTabs = [
20
+ { id: "general", label: "General" },
21
+ { id: "authentication", label: "Authentication" },
22
+ { id: "notifications", label: "Notifications" },
23
+ { id: "billing", label: "Billing" },
24
+ ];
25
+
26
+ function useHashRoute(fallback: string) {
27
+ const [active, setActive] = useState(() => window.location.hash.slice(1) || fallback);
28
+
29
+ useEffect(() => {
30
+ const onChange = () => setActive(window.location.hash.slice(1) || fallback);
31
+ window.addEventListener("hashchange", onChange);
32
+ return () => window.removeEventListener("hashchange", onChange);
33
+ }, [fallback]);
34
+
35
+ return active;
36
+ }
37
+
38
+ export const AllVariants: Story = () => {
39
+ const activeNav = useHashRoute("overview");
40
+
41
+ return (
42
+ <div className="flex flex-col gap-10 p-8">
43
+ {/* ─── Navigation tabs ─────────────────────────────────────── */}
44
+
45
+ {/* Horizontal + line (default) */}
46
+ <div>
47
+ <p className={SECTION_HEADER}>Nav — horizontal, variant="line" (default)</p>
48
+ <div className="mt-4">
49
+ <TabsNav aria-label="Project" orientation="horizontal" variant="line">
50
+ <TabsNavList>
51
+ {navTabs.map(({ id, label, icon: Icon }) => (
52
+ <TabsNavTrigger key={id} href={`#${id}`} active={activeNav === id}>
53
+ <Icon className="h-4 w-4" />
54
+ {label}
55
+ </TabsNavTrigger>
56
+ ))}
57
+ </TabsNavList>
58
+ </TabsNav>
59
+ </div>
60
+ </div>
61
+
62
+ {/* Horizontal + pill */}
63
+ <div>
64
+ <p className={SECTION_HEADER}>Nav — horizontal, variant="pill"</p>
65
+ <div className="mt-4">
66
+ <TabsNav aria-label="Project" orientation="horizontal" variant="pill">
67
+ <TabsNavList>
68
+ {navTabs.slice(0, 4).map(({ id, label, icon: Icon }) => (
69
+ <TabsNavTrigger key={id} href={`#${id}`} active={activeNav === id}>
70
+ <Icon className="h-4 w-4" />
71
+ {label}
72
+ </TabsNavTrigger>
73
+ ))}
74
+ </TabsNavList>
75
+ </TabsNav>
76
+ </div>
77
+ </div>
78
+
79
+ {/* Vertical + pill (default) */}
80
+ <div>
81
+ <p className={SECTION_HEADER}>Nav — vertical, variant="pill" (default)</p>
82
+ <div className="mt-4 flex gap-6">
83
+ <aside className="shrink-0 basis-40">
84
+ <TabsNav aria-label="Settings" orientation="vertical" variant="pill">
85
+ <TabsNavList>
86
+ {sideNavTabs.map(({ id, label }) => (
87
+ <TabsNavTrigger key={id} href={`#${id}`} active={activeNav === id}>
88
+ {label}
89
+ </TabsNavTrigger>
90
+ ))}
91
+ </TabsNavList>
92
+ </TabsNav>
93
+ </aside>
94
+ <div className="flex-1 rounded-md border p-4">
95
+ <p className="type-text-sm text-muted-foreground">Content for "{activeNav}"</p>
96
+ </div>
97
+ </div>
98
+ </div>
99
+
100
+ {/* ─── Tabs (state-based) ────────────────────────────── */}
101
+
102
+ {/* Tabs — line */}
103
+ <div>
104
+ <p className={SECTION_HEADER}>Tabs — line variant</p>
105
+ <Tabs defaultValue="all" className="mt-4">
106
+ <TabsList variant="line">
107
+ <TabsTrigger value="all">All</TabsTrigger>
108
+ <TabsTrigger value="tool">Tool</TabsTrigger>
109
+ <TabsTrigger value="resource">Resource</TabsTrigger>
110
+ <TabsTrigger value="prompt">Prompt</TabsTrigger>
111
+ </TabsList>
112
+ <TabsContent value="all">All content</TabsContent>
113
+ <TabsContent value="tool">Tool content</TabsContent>
114
+ <TabsContent value="resource">Resource content</TabsContent>
115
+ <TabsContent value="prompt">Prompt content</TabsContent>
116
+ </Tabs>
117
+ </div>
118
+
119
+ {/* Tabs — default (horizontal) */}
120
+ <div>
121
+ <p className={SECTION_HEADER}>Tabs — default variant (horizontal)</p>
122
+ <Tabs defaultValue="all" className="mt-4">
123
+ <TabsList>
124
+ <TabsTrigger value="all">All</TabsTrigger>
125
+ <TabsTrigger value="tool">Tool</TabsTrigger>
126
+ <TabsTrigger value="resource">Resource</TabsTrigger>
127
+ <TabsTrigger value="prompt">Prompt</TabsTrigger>
128
+ </TabsList>
129
+ <TabsContent value="all">All content</TabsContent>
130
+ <TabsContent value="tool">Tool content</TabsContent>
131
+ <TabsContent value="resource">Resource content</TabsContent>
132
+ <TabsContent value="prompt">Prompt content</TabsContent>
133
+ </Tabs>
134
+ </div>
135
+
136
+ {/* Tabs — default (vertical) */}
137
+ <div>
138
+ <p className={SECTION_HEADER}>Tabs — default variant (vertical)</p>
139
+ <Tabs defaultValue="overview" orientation="vertical" className="mt-4">
140
+ <TabsList>
141
+ <TabsTrigger value="overview">Overview</TabsTrigger>
142
+ <TabsTrigger value="analytics">Analytics</TabsTrigger>
143
+ <TabsTrigger value="settings">Settings</TabsTrigger>
144
+ </TabsList>
145
+ <TabsContent value="overview">Overview content</TabsContent>
146
+ <TabsContent value="analytics">Analytics content</TabsContent>
147
+ <TabsContent value="settings">Settings content</TabsContent>
148
+ </Tabs>
149
+ </div>
150
+
151
+ {/* Tabs — disabled */}
152
+ <div>
153
+ <p className={SECTION_HEADER}>Tabs — disabled trigger</p>
154
+ <Tabs defaultValue="one" className="mt-4">
155
+ <TabsList>
156
+ <TabsTrigger value="one">One</TabsTrigger>
157
+ <TabsTrigger value="two" disabled>
158
+ Two (disabled)
159
+ </TabsTrigger>
160
+ <TabsTrigger value="three">Three</TabsTrigger>
161
+ </TabsList>
162
+ <TabsContent value="one">One content</TabsContent>
163
+ <TabsContent value="two">Two content</TabsContent>
164
+ <TabsContent value="three">Three content</TabsContent>
165
+ </Tabs>
166
+ </div>
167
+ </div>
168
+ );
169
+ };
@@ -0,0 +1,82 @@
1
+ import type { Story } from "@ladle/react";
2
+ import { Tag, TagCount, TagDismissible } from "../components/tag";
3
+
4
+ const PlaceholderIcon = () => (
5
+ <svg
6
+ aria-hidden="true"
7
+ xmlns="http://www.w3.org/2000/svg"
8
+ width="16"
9
+ height="16"
10
+ viewBox="0 0 24 24"
11
+ fill="none"
12
+ stroke="currentColor"
13
+ strokeWidth="2"
14
+ strokeLinecap="round"
15
+ strokeLinejoin="round"
16
+ >
17
+ <circle cx="12" cy="12" r="10" />
18
+ </svg>
19
+ );
20
+
21
+ export const AllVariants: Story = () => (
22
+ <div className="flex flex-col gap-6">
23
+ <div className="flex flex-col gap-1.5">
24
+ <p className="type-text-xs font-medium text-subtle-foreground">Text only</p>
25
+ <div className="flex gap-1.5">
26
+ <Tag>Design</Tag>
27
+ <Tag>Engineering</Tag>
28
+ <Tag>Product</Tag>
29
+ </div>
30
+ </div>
31
+
32
+ <div className="flex flex-col gap-1.5">
33
+ <p className="type-text-xs font-medium text-subtle-foreground">Text only + icon</p>
34
+ <div className="flex gap-1.5">
35
+ <Tag icon={<PlaceholderIcon />}>Design</Tag>
36
+ <Tag icon={<PlaceholderIcon />}>Engineering</Tag>
37
+ </div>
38
+ </div>
39
+
40
+ <div className="flex flex-col gap-1.5">
41
+ <p className="type-text-xs font-medium text-subtle-foreground">Dismissible</p>
42
+ <div className="flex gap-1.5">
43
+ <TagDismissible onDismiss={() => {}}>Olivia</TagDismissible>
44
+ <TagDismissible onDismiss={() => {}}>Phoenix</TagDismissible>
45
+ <TagDismissible onDismiss={() => {}}>Lana</TagDismissible>
46
+ </div>
47
+ </div>
48
+
49
+ <div className="flex flex-col gap-1.5">
50
+ <p className="type-text-xs font-medium text-subtle-foreground">Dismissible + icon</p>
51
+ <div className="flex gap-1.5">
52
+ <TagDismissible icon={<PlaceholderIcon />} onDismiss={() => {}}>
53
+ Label
54
+ </TagDismissible>
55
+ <TagDismissible icon={<PlaceholderIcon />} onDismiss={() => {}}>
56
+ Design
57
+ </TagDismissible>
58
+ </div>
59
+ </div>
60
+
61
+ <div className="flex flex-col gap-1.5">
62
+ <p className="type-text-xs font-medium text-subtle-foreground">Count</p>
63
+ <div className="flex gap-1.5">
64
+ <TagCount count={5}>Label</TagCount>
65
+ <TagCount count={3}>Product</TagCount>
66
+ <TagCount count={12}>Engineering</TagCount>
67
+ </div>
68
+ </div>
69
+
70
+ <div className="flex flex-col gap-1.5">
71
+ <p className="type-text-xs font-medium text-subtle-foreground">Count + icon</p>
72
+ <div className="flex gap-1.5">
73
+ <TagCount icon={<PlaceholderIcon />} count={5}>
74
+ Label
75
+ </TagCount>
76
+ <TagCount icon={<PlaceholderIcon />} count={3}>
77
+ Product
78
+ </TagCount>
79
+ </div>
80
+ </div>
81
+ </div>
82
+ );
@@ -0,0 +1,60 @@
1
+ import { Textarea } from "../components/textarea";
2
+
3
+ const SECTION_HEADER = "type-text-xs text-muted-foreground font-semibold uppercase tracking-wide pt-4";
4
+
5
+ export const AllVariants = () => {
6
+ return (
7
+ <div className="flex flex-col gap-6 p-8 max-w-sm">
8
+ <span className={SECTION_HEADER}>Default</span>
9
+ <Textarea id="default" placeholder="Enter a description..." />
10
+
11
+ <span className={SECTION_HEADER}>With label</span>
12
+ <Textarea id="with-label" label="Description" placeholder="Enter a description..." />
13
+
14
+ <span className={SECTION_HEADER}>Required + hint</span>
15
+ <Textarea
16
+ id="required-hint"
17
+ label="Description"
18
+ required
19
+ placeholder="Enter a description..."
20
+ hint="This is a hint text to help user."
21
+ />
22
+
23
+ <span className={SECTION_HEADER}>With tooltip</span>
24
+ <Textarea
25
+ id="with-tooltip"
26
+ label="Description"
27
+ required
28
+ tooltip="Briefly describe what this project is about."
29
+ placeholder="Enter a description..."
30
+ />
31
+
32
+ <span className={SECTION_HEADER}>Filled</span>
33
+ <Textarea
34
+ id="filled"
35
+ label="Description"
36
+ required
37
+ defaultValue="A little about the company and the team that you'll be working with."
38
+ hint="This is a hint text to help user."
39
+ />
40
+
41
+ <span className={SECTION_HEADER}>Error</span>
42
+ <Textarea
43
+ id="error"
44
+ label="Description"
45
+ required
46
+ placeholder="Enter a description..."
47
+ error="Description is required."
48
+ />
49
+
50
+ <span className={SECTION_HEADER}>Disabled</span>
51
+ <Textarea
52
+ id="disabled"
53
+ label="Description"
54
+ placeholder="Enter a description..."
55
+ hint="This is a hint text to help user."
56
+ disabled
57
+ />
58
+ </div>
59
+ );
60
+ };