@boxcustodia/library 2.0.0-alpha.13 → 2.0.0-alpha.15
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/dist/index.cjs.js +1 -138
- package/dist/index.d.ts +1083 -717
- package/dist/index.es.js +7059 -56179
- package/dist/theme.css +1 -1
- package/package.json +34 -26
- package/src/__doc__/Changelog.mdx +6 -6
- package/src/__doc__/Examples.tsx +1 -1
- package/src/__doc__/Intro.mdx +3 -3
- package/src/__doc__/Tabs.mdx +112 -0
- package/src/__doc__/V2.mdx +1245 -0
- package/src/components/accordion/accordion.stories.tsx +143 -0
- package/src/components/accordion/accordion.tsx +135 -0
- package/src/components/accordion/index.ts +1 -0
- package/src/components/alert/alert.stories.tsx +24 -4
- package/src/components/alert/alert.tsx +17 -9
- package/src/components/alert-dialog/alert-dialog.stories.tsx +24 -0
- package/src/components/alert-dialog/alert-dialog.test.tsx +1 -1
- package/src/components/alert-dialog/alert-dialog.tsx +58 -10
- package/src/components/auto-complete/auto-complete.stories.tsx +615 -200
- package/src/components/auto-complete/auto-complete.tsx +420 -68
- package/src/components/auto-complete/index.ts +0 -1
- package/src/components/avatar/avatar.stories.tsx +162 -21
- package/src/components/avatar/avatar.tsx +79 -20
- package/src/components/button/button.stories.tsx +236 -294
- package/src/components/button/button.test.tsx +10 -17
- package/src/components/button/button.tsx +53 -18
- package/src/components/button/components/base-button.tsx +25 -53
- package/src/components/button/index.ts +0 -1
- package/src/components/calendar/calendar.stories.tsx +1 -1
- package/src/components/calendar/calendar.tsx +4 -4
- package/src/components/card/card.stories.tsx +140 -69
- package/src/components/card/card.tsx +155 -54
- package/src/components/center/center.stories.tsx +22 -39
- package/src/components/checkbox/checkbox.stories.tsx +25 -5
- package/src/components/checkbox/checkbox.tsx +76 -15
- package/src/components/checkbox-group/checkbox-group.stories.tsx +116 -28
- package/src/components/checkbox-group/checkbox-group.tsx +84 -3
- package/src/components/combobox/combobox.stories.tsx +33 -23
- package/src/components/combobox/combobox.tsx +120 -104
- package/src/components/date-picker/date-input.stories.tsx +14 -6
- package/src/components/date-picker/date-input.tsx +3 -3
- package/src/components/date-picker/date-picker.model.ts +13 -4
- package/src/components/date-picker/date-picker.stories.tsx +38 -12
- package/src/components/date-picker/date-picker.tsx +29 -15
- package/src/components/dialog/dialog.stories.tsx +18 -0
- package/src/components/dialog/dialog.test.tsx +1 -1
- package/src/components/dialog/dialog.tsx +51 -20
- package/src/components/divider/divider.stories.tsx +6 -0
- package/src/components/dropzone/dropzone.stories.tsx +70 -90
- package/src/components/dropzone/dropzone.tsx +383 -105
- package/src/components/dropzone/index.ts +0 -1
- package/src/components/empty/empty.stories.tsx +164 -0
- package/src/components/empty/empty.tsx +156 -0
- package/src/components/empty/index.ts +1 -0
- package/src/components/field/field.stories.tsx +226 -3
- package/src/components/field/field.tsx +77 -42
- package/src/components/form/form.stories.tsx +320 -197
- package/src/components/form/form.tsx +3 -23
- package/src/components/index.ts +2 -6
- package/src/components/input/input.stories.tsx +5 -5
- package/src/components/input/input.tsx +5 -5
- package/src/components/kbd/kbd.stories.tsx +1 -0
- package/src/components/label/label.stories.tsx +16 -0
- package/src/components/label/label.tsx +13 -2
- package/src/components/loader/loader.stories.tsx +7 -5
- package/src/components/loader/loader.tsx +8 -3
- package/src/components/menu/menu-primitives.tsx +207 -196
- package/src/components/menu/menu.stories.tsx +275 -146
- package/src/components/menu/menu.tsx +146 -54
- package/src/components/number-input/number-input.stories.tsx +27 -4
- package/src/components/number-input/number-input.test.tsx +2 -2
- package/src/components/number-input/number-input.tsx +29 -33
- package/src/components/otp/index.ts +1 -0
- package/src/components/otp/otp.stories.tsx +209 -0
- package/src/components/otp/otp.tsx +100 -0
- package/src/components/pagination/index.ts +1 -0
- package/src/components/pagination/pagination.model.ts +2 -0
- package/src/components/pagination/pagination.stories.tsx +153 -59
- package/src/components/pagination/pagination.test.tsx +122 -57
- package/src/components/pagination/pagination.tsx +575 -77
- package/src/components/password/password.stories.tsx +18 -3
- package/src/components/password/password.tsx +26 -10
- package/src/components/popover/popover.stories.tsx +26 -5
- package/src/components/popover/popover.tsx +15 -23
- package/src/components/progress/progress.stories.tsx +1 -0
- package/src/components/radio-group/index.ts +1 -0
- package/src/components/radio-group/radio-group.stories.tsx +251 -0
- package/src/components/radio-group/radio-group.tsx +212 -0
- package/src/components/scroll-area/scroll-area.stories.tsx +1 -0
- package/src/components/select/select.stories.tsx +118 -19
- package/src/components/select/select.tsx +67 -62
- package/src/components/skeleton/skeleton.stories.tsx +1 -0
- package/src/components/stack/stack.stories.tsx +179 -89
- package/src/components/stack/stack.tsx +2 -2
- package/src/components/stepper/index.ts +1 -1
- package/src/components/stepper/stepper.stories.tsx +766 -83
- package/src/components/stepper/stepper.test.tsx +18 -18
- package/src/components/stepper/stepper.tsx +554 -0
- package/src/components/switch/switch.stories.tsx +15 -1
- package/src/components/switch/switch.tsx +17 -4
- package/src/components/table/index.ts +0 -2
- package/src/components/table/table.stories.tsx +131 -18
- package/src/components/table/table.test.tsx +1 -1
- package/src/components/table/table.tsx +183 -77
- package/src/components/tabs/tabs.stories.tsx +372 -155
- package/src/components/tabs/tabs.test.tsx +12 -12
- package/src/components/tabs/tabs.tsx +72 -149
- package/src/components/tag/index.ts +0 -1
- package/src/components/tag/tag.stories.tsx +147 -120
- package/src/components/tag/tag.tsx +47 -95
- package/src/components/textarea/textarea.stories.tsx +8 -22
- package/src/components/textarea/textarea.tsx +17 -79
- package/src/components/timeline/timeline.stories.tsx +322 -42
- package/src/components/timeline/timeline.tsx +359 -132
- package/src/components/toast/toast.stories.tsx +1 -0
- package/src/components/tooltip/tooltip.tsx +11 -9
- package/src/components/tree/index.ts +0 -1
- package/src/components/tree/tree.stories.tsx +364 -408
- package/src/components/tree/tree.test.tsx +163 -0
- package/src/components/tree/tree.tsx +212 -36
- package/src/hooks/useAsync/__doc__/useAsync.stories.tsx +5 -5
- package/src/hooks/useClipboard/__doc__/useClipboard.stories.tsx +1 -3
- package/src/hooks/useDebounceCallback/__doc__/useDebouncedCallback.stories.tsx +6 -6
- package/src/hooks/useDocumentTitle/__doc__/useDocumentTitle.stories.tsx +1 -1
- package/src/hooks/useEventListener/__test__/useEventListener.test.tsx +1 -1
- package/src/hooks/useLocalStorage/__doc__/useLocalStorage.stories.tsx +1 -1
- package/src/hooks/usePagination/usePagination.tsx +36 -24
- package/src/styles/theme.css +1 -1
- package/src/utils/form.tsx +69 -37
- package/src/utils/index.ts +1 -1
- package/src/__doc__/Migration.mdx +0 -451
- package/src/components/auto-complete/auto-complete-primitives.tsx +0 -155
- package/src/components/background-image/background-image.stories.tsx +0 -21
- package/src/components/background-image/background-image.test.tsx +0 -29
- package/src/components/background-image/background-image.tsx +0 -23
- package/src/components/background-image/index.ts +0 -1
- package/src/components/button/button.variants.ts +0 -44
- package/src/components/button/components/loader-overlay.tsx +0 -21
- package/src/components/button/components/loading-icon.tsx +0 -47
- package/src/components/dropzone/upload-primitives.tsx +0 -310
- package/src/components/dropzone/use-dropzone.ts +0 -122
- package/src/components/empty-state/empty-state.stories.tsx +0 -56
- package/src/components/empty-state/empty-state.tsx +0 -39
- package/src/components/empty-state/index.ts +0 -1
- package/src/components/heading/heading.stories.tsx +0 -74
- package/src/components/heading/heading.tsx +0 -28
- package/src/components/heading/heading.variants.ts +0 -27
- package/src/components/heading/index.ts +0 -1
- package/src/components/kbd/kbd.variants.ts +0 -26
- package/src/components/menu/util/render-menu-item.tsx +0 -54
- package/src/components/multi-select/hooks/use-multi-select.ts +0 -66
- package/src/components/multi-select/index.ts +0 -1
- package/src/components/multi-select/multi-select.stories.tsx +0 -294
- package/src/components/multi-select/multi-select.tsx +0 -300
- package/src/components/multi-select/multi-select.variants.ts +0 -22
- package/src/components/pagination/components/pagination-option.tsx +0 -27
- package/src/components/show/index.ts +0 -1
- package/src/components/show/show.stories.tsx +0 -197
- package/src/components/show/show.test.tsx +0 -41
- package/src/components/show/show.tsx +0 -16
- package/src/components/stepper/Stepper.tsx +0 -190
- package/src/components/stepper/context/stepper-context.tsx +0 -11
- package/src/components/table/table-primitives.tsx +0 -122
- package/src/components/table/table.model.ts +0 -20
- package/src/components/table-pagination/index.ts +0 -2
- package/src/components/table-pagination/table-pagination.model.ts +0 -2
- package/src/components/table-pagination/table-pagination.stories.tsx +0 -23
- package/src/components/table-pagination/table-pagination.test.tsx +0 -32
- package/src/components/table-pagination/table-pagination.tsx +0 -108
- package/src/components/tabs/context/tabs-context.tsx +0 -14
- package/src/components/tag/tag.variants.ts +0 -31
- package/src/components/timeline/timeline-status.ts +0 -5
- package/src/components/tree/hooks/use-controllable-tree-state.ts +0 -80
- package/src/components/tree/tree-primitives.tsx +0 -126
|
@@ -1,182 +1,399 @@
|
|
|
1
1
|
import type { Meta, StoryObj } from "@storybook/react-vite";
|
|
2
|
-
import { useState } from "react";
|
|
3
2
|
import {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
import {
|
|
3
|
+
BellIcon,
|
|
4
|
+
CreditCardIcon,
|
|
5
|
+
LockIcon,
|
|
6
|
+
PaletteIcon,
|
|
7
|
+
UserIcon,
|
|
8
|
+
} from "lucide-react";
|
|
9
|
+
import React from "react";
|
|
10
|
+
import { Button } from "../../components";
|
|
11
|
+
import { Tabs, TabsList, TabsPanel, TabsPrimitive, TabsTab } from "./tabs";
|
|
12
12
|
|
|
13
|
+
/**
|
|
14
|
+
* Accessible tab component built on Base UI Tabs primitives.
|
|
15
|
+
*
|
|
16
|
+
* `variant` lives on `TabsList`, not on `Tabs`. Two variants are available:
|
|
17
|
+
* `"underline"` (default) renders a line indicator at the edge of the active
|
|
18
|
+
* tab; `"background"` renders a rounded background behind the active tab.
|
|
19
|
+
*
|
|
20
|
+
* Use `value` + `onValueChange` for controlled state.
|
|
21
|
+
* Set `orientation="vertical"` on `Tabs` to switch to a column layout.
|
|
22
|
+
*/
|
|
13
23
|
const meta: Meta<typeof Tabs> = {
|
|
14
|
-
title: "
|
|
24
|
+
title: "Components/Tabs",
|
|
15
25
|
component: Tabs,
|
|
16
|
-
|
|
26
|
+
parameters: {
|
|
27
|
+
layout: "centered",
|
|
28
|
+
},
|
|
29
|
+
subcomponents: {
|
|
30
|
+
TabsList: TabsList as React.ComponentType<unknown>,
|
|
31
|
+
TabsTab: TabsTab as React.ComponentType<unknown>,
|
|
32
|
+
TabsPanel: TabsPanel as React.ComponentType<unknown>,
|
|
33
|
+
},
|
|
17
34
|
};
|
|
18
35
|
|
|
19
36
|
export default meta;
|
|
20
37
|
type Story = StoryObj<typeof Tabs>;
|
|
21
38
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
39
|
+
// ---------------------------------------------------------------------------
|
|
40
|
+
// Shared content blocks
|
|
41
|
+
// ---------------------------------------------------------------------------
|
|
42
|
+
|
|
43
|
+
const AccountPanel = () => (
|
|
44
|
+
<div className="space-y-4 py-2">
|
|
45
|
+
<div className="flex items-center gap-4">
|
|
46
|
+
<div className="size-14 rounded-full bg-muted flex items-center justify-center text-muted-foreground">
|
|
47
|
+
<UserIcon className="size-6" />
|
|
48
|
+
</div>
|
|
49
|
+
<div>
|
|
50
|
+
<p className="font-medium">John Doe</p>
|
|
51
|
+
<p className="text-sm text-muted-foreground">john@example.com</p>
|
|
52
|
+
</div>
|
|
53
|
+
</div>
|
|
54
|
+
<div className="grid gap-3">
|
|
55
|
+
<div className="grid gap-1.5">
|
|
56
|
+
<label className="text-sm font-medium">Display name</label>
|
|
57
|
+
<input
|
|
58
|
+
defaultValue="John Doe"
|
|
59
|
+
className="h-9 rounded-md border bg-background px-3 text-sm outline-none focus:ring-2 focus:ring-ring"
|
|
60
|
+
/>
|
|
61
|
+
</div>
|
|
62
|
+
<div className="grid gap-1.5">
|
|
63
|
+
<label className="text-sm font-medium">Email</label>
|
|
64
|
+
<input
|
|
65
|
+
defaultValue="john@example.com"
|
|
66
|
+
type="email"
|
|
67
|
+
className="h-9 rounded-md border bg-background px-3 text-sm outline-none focus:ring-2 focus:ring-ring"
|
|
68
|
+
/>
|
|
69
|
+
</div>
|
|
70
|
+
</div>
|
|
71
|
+
<div className="flex justify-end">
|
|
72
|
+
<Button size="sm">Save changes</Button>
|
|
73
|
+
</div>
|
|
74
|
+
</div>
|
|
75
|
+
);
|
|
76
|
+
|
|
77
|
+
const SecurityPanel = () => (
|
|
78
|
+
<div className="space-y-3 py-2">
|
|
79
|
+
{[
|
|
80
|
+
{
|
|
81
|
+
label: "Password",
|
|
82
|
+
meta: "Last changed 3 months ago",
|
|
83
|
+
action: "Change",
|
|
84
|
+
},
|
|
85
|
+
{
|
|
86
|
+
label: "Two-factor authentication",
|
|
87
|
+
meta: "Add an extra layer of security",
|
|
88
|
+
action: "Enable",
|
|
89
|
+
},
|
|
90
|
+
{
|
|
91
|
+
label: "Active sessions",
|
|
92
|
+
meta: "2 devices currently signed in",
|
|
93
|
+
action: "Manage",
|
|
94
|
+
},
|
|
95
|
+
].map(({ label, meta, action }) => (
|
|
96
|
+
<div
|
|
97
|
+
key={label}
|
|
98
|
+
className="flex items-center justify-between rounded-lg border p-3.5"
|
|
99
|
+
>
|
|
100
|
+
<div>
|
|
101
|
+
<p className="text-sm font-medium">{label}</p>
|
|
102
|
+
<p className="text-xs text-muted-foreground">{meta}</p>
|
|
103
|
+
</div>
|
|
104
|
+
<Button variant="outline" size="sm">
|
|
105
|
+
{action}
|
|
106
|
+
</Button>
|
|
107
|
+
</div>
|
|
108
|
+
))}
|
|
109
|
+
</div>
|
|
110
|
+
);
|
|
111
|
+
|
|
112
|
+
const NotificationsPanel = () => (
|
|
113
|
+
<div className="space-y-3 py-2">
|
|
114
|
+
{[
|
|
115
|
+
{ title: "Email notifications", desc: "Weekly digest and alerts" },
|
|
116
|
+
{ title: "Push notifications", desc: "Desktop and mobile" },
|
|
117
|
+
{ title: "Security alerts", desc: "Unusual sign-in activity" },
|
|
118
|
+
].map(({ title, desc }) => (
|
|
119
|
+
<div key={title} className="flex items-center justify-between py-1">
|
|
120
|
+
<div>
|
|
121
|
+
<p className="text-sm font-medium">{title}</p>
|
|
122
|
+
<p className="text-xs text-muted-foreground">{desc}</p>
|
|
123
|
+
</div>
|
|
124
|
+
<div className="size-5 rounded border border-input bg-background" />
|
|
125
|
+
</div>
|
|
126
|
+
))}
|
|
127
|
+
</div>
|
|
128
|
+
);
|
|
129
|
+
|
|
130
|
+
const BillingPanel = () => (
|
|
131
|
+
<div className="space-y-3 py-2">
|
|
132
|
+
<div className="rounded-lg border p-4 flex items-start gap-3">
|
|
133
|
+
<CreditCardIcon className="size-5 mt-0.5 text-muted-foreground" />
|
|
134
|
+
<div className="flex-1">
|
|
135
|
+
<p className="text-sm font-medium">Pro plan · $12/month</p>
|
|
136
|
+
<p className="text-xs text-muted-foreground">Renews on Jun 1, 2025</p>
|
|
137
|
+
</div>
|
|
138
|
+
<Button variant="outline" size="sm">
|
|
139
|
+
Manage
|
|
140
|
+
</Button>
|
|
141
|
+
</div>
|
|
142
|
+
<div className="rounded-lg border p-4">
|
|
143
|
+
<p className="text-sm font-medium mb-2">Payment method</p>
|
|
144
|
+
<p className="text-sm text-muted-foreground">Visa ending in 4242</p>
|
|
145
|
+
</div>
|
|
146
|
+
</div>
|
|
147
|
+
);
|
|
148
|
+
|
|
149
|
+
const AppearancePanel = () => (
|
|
150
|
+
<div className="space-y-3 py-2">
|
|
151
|
+
<div>
|
|
152
|
+
<p className="text-sm font-medium mb-2">Theme</p>
|
|
153
|
+
<div className="flex gap-2">
|
|
154
|
+
{["Light", "Dark", "System"].map((t) => (
|
|
155
|
+
<button
|
|
156
|
+
key={t}
|
|
157
|
+
className="rounded-md border px-3 py-1.5 text-sm data-[active]:border-primary data-[active]:bg-primary/5 cursor-pointer"
|
|
158
|
+
data-active={t === "Light" ? "" : undefined}
|
|
159
|
+
>
|
|
160
|
+
{t}
|
|
161
|
+
</button>
|
|
162
|
+
))}
|
|
163
|
+
</div>
|
|
164
|
+
</div>
|
|
165
|
+
<div>
|
|
166
|
+
<p className="text-sm font-medium mb-2">Density</p>
|
|
167
|
+
<div className="flex gap-2">
|
|
168
|
+
{["Compact", "Comfortable", "Spacious"].map((d) => (
|
|
169
|
+
<button
|
|
170
|
+
key={d}
|
|
171
|
+
className="rounded-md border px-3 py-1.5 text-sm cursor-pointer"
|
|
172
|
+
>
|
|
173
|
+
{d}
|
|
174
|
+
</button>
|
|
175
|
+
))}
|
|
176
|
+
</div>
|
|
177
|
+
</div>
|
|
178
|
+
</div>
|
|
179
|
+
);
|
|
180
|
+
|
|
181
|
+
// ---------------------------------------------------------------------------
|
|
182
|
+
// Stories
|
|
183
|
+
// ---------------------------------------------------------------------------
|
|
184
|
+
|
|
185
|
+
export const Default: Story = {
|
|
186
|
+
render: () => (
|
|
187
|
+
<Tabs defaultValue="account" className="w-[480px] h-[340px]">
|
|
188
|
+
<TabsList>
|
|
189
|
+
<TabsTab value="account">Account</TabsTab>
|
|
190
|
+
<TabsTab value="security">Security</TabsTab>
|
|
191
|
+
<TabsTab value="notifications">Notifications</TabsTab>
|
|
192
|
+
</TabsList>
|
|
193
|
+
<TabsPanel value="account">
|
|
194
|
+
<AccountPanel />
|
|
195
|
+
</TabsPanel>
|
|
196
|
+
<TabsPanel value="security">
|
|
197
|
+
<SecurityPanel />
|
|
198
|
+
</TabsPanel>
|
|
199
|
+
<TabsPanel value="notifications">
|
|
200
|
+
<NotificationsPanel />
|
|
201
|
+
</TabsPanel>
|
|
202
|
+
</Tabs>
|
|
203
|
+
),
|
|
29
204
|
};
|
|
30
205
|
|
|
31
|
-
const
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
<
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
206
|
+
export const Background: Story = {
|
|
207
|
+
render: () => (
|
|
208
|
+
<Tabs defaultValue="account" className="w-[480px] h-[340px]">
|
|
209
|
+
<TabsList variant="background">
|
|
210
|
+
<TabsTab value="account">Account</TabsTab>
|
|
211
|
+
<TabsTab value="security">Security</TabsTab>
|
|
212
|
+
<TabsTab value="notifications">Notifications</TabsTab>
|
|
213
|
+
</TabsList>
|
|
214
|
+
<TabsPanel value="account">
|
|
215
|
+
<AccountPanel />
|
|
216
|
+
</TabsPanel>
|
|
217
|
+
<TabsPanel value="security">
|
|
218
|
+
<SecurityPanel />
|
|
219
|
+
</TabsPanel>
|
|
220
|
+
<TabsPanel value="notifications">
|
|
221
|
+
<NotificationsPanel />
|
|
222
|
+
</TabsPanel>
|
|
223
|
+
</Tabs>
|
|
224
|
+
),
|
|
38
225
|
};
|
|
39
226
|
|
|
40
|
-
const
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
227
|
+
export const Vertical: Story = {
|
|
228
|
+
render: () => (
|
|
229
|
+
<Tabs
|
|
230
|
+
defaultValue="account"
|
|
231
|
+
orientation="vertical"
|
|
232
|
+
className="w-[620px] h-[300px]"
|
|
233
|
+
>
|
|
234
|
+
<TabsList className="w-44 shrink-0">
|
|
235
|
+
<TabsTab value="account">Account</TabsTab>
|
|
236
|
+
<TabsTab value="security">Security</TabsTab>
|
|
237
|
+
<TabsTab value="billing">Billing</TabsTab>
|
|
238
|
+
<TabsTab value="appearance">Appearance</TabsTab>
|
|
239
|
+
</TabsList>
|
|
240
|
+
<div className="flex-1 min-w-0">
|
|
241
|
+
<TabsPanel value="account">
|
|
242
|
+
<AccountPanel />
|
|
243
|
+
</TabsPanel>
|
|
244
|
+
<TabsPanel value="security">
|
|
245
|
+
<SecurityPanel />
|
|
246
|
+
</TabsPanel>
|
|
247
|
+
<TabsPanel value="billing">
|
|
248
|
+
<BillingPanel />
|
|
249
|
+
</TabsPanel>
|
|
250
|
+
<TabsPanel value="appearance">
|
|
251
|
+
<AppearancePanel />
|
|
252
|
+
</TabsPanel>
|
|
253
|
+
</div>
|
|
254
|
+
</Tabs>
|
|
255
|
+
),
|
|
46
256
|
};
|
|
47
257
|
|
|
48
|
-
const
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
258
|
+
export const PillVertical: Story = {
|
|
259
|
+
render: () => (
|
|
260
|
+
<Tabs
|
|
261
|
+
defaultValue="account"
|
|
262
|
+
orientation="vertical"
|
|
263
|
+
className="w-[620px] h-[300px]"
|
|
264
|
+
>
|
|
265
|
+
<TabsList variant="background" className="w-44 shrink-0">
|
|
266
|
+
<TabsTab value="account">Account</TabsTab>
|
|
267
|
+
<TabsTab value="security">Security</TabsTab>
|
|
268
|
+
<TabsTab value="billing">Billing</TabsTab>
|
|
269
|
+
<TabsTab value="appearance">Appearance</TabsTab>
|
|
270
|
+
</TabsList>
|
|
271
|
+
<div className="flex-1 min-w-0">
|
|
272
|
+
<TabsPanel value="account">
|
|
273
|
+
<AccountPanel />
|
|
274
|
+
</TabsPanel>
|
|
275
|
+
<TabsPanel value="security">
|
|
276
|
+
<SecurityPanel />
|
|
277
|
+
</TabsPanel>
|
|
278
|
+
<TabsPanel value="billing">
|
|
279
|
+
<BillingPanel />
|
|
280
|
+
</TabsPanel>
|
|
281
|
+
<TabsPanel value="appearance">
|
|
282
|
+
<AppearancePanel />
|
|
283
|
+
</TabsPanel>
|
|
284
|
+
</div>
|
|
285
|
+
</Tabs>
|
|
286
|
+
),
|
|
287
|
+
};
|
|
62
288
|
|
|
63
|
-
export const
|
|
64
|
-
render: () =>
|
|
65
|
-
|
|
66
|
-
<
|
|
67
|
-
<
|
|
68
|
-
<
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
289
|
+
export const WithIcons: Story = {
|
|
290
|
+
render: () => (
|
|
291
|
+
<Tabs defaultValue="account" className="w-[480px] h-[340px]">
|
|
292
|
+
<TabsList>
|
|
293
|
+
<TabsTab value="account">
|
|
294
|
+
<UserIcon />
|
|
295
|
+
Account
|
|
296
|
+
</TabsTab>
|
|
297
|
+
<TabsTab value="security">
|
|
298
|
+
<LockIcon />
|
|
299
|
+
Security
|
|
300
|
+
</TabsTab>
|
|
301
|
+
<TabsTab value="notifications">
|
|
302
|
+
<BellIcon />
|
|
303
|
+
Notifications
|
|
304
|
+
</TabsTab>
|
|
305
|
+
<TabsTab value="appearance">
|
|
306
|
+
<PaletteIcon />
|
|
307
|
+
Appearance
|
|
308
|
+
</TabsTab>
|
|
309
|
+
</TabsList>
|
|
310
|
+
<TabsPanel value="account">
|
|
311
|
+
<AccountPanel />
|
|
312
|
+
</TabsPanel>
|
|
313
|
+
<TabsPanel value="security">
|
|
314
|
+
<SecurityPanel />
|
|
315
|
+
</TabsPanel>
|
|
316
|
+
<TabsPanel value="notifications">
|
|
317
|
+
<NotificationsPanel />
|
|
318
|
+
</TabsPanel>
|
|
319
|
+
<TabsPanel value="appearance">
|
|
320
|
+
<AppearancePanel />
|
|
321
|
+
</TabsPanel>
|
|
322
|
+
</Tabs>
|
|
323
|
+
),
|
|
87
324
|
};
|
|
88
325
|
|
|
89
326
|
/**
|
|
90
|
-
*
|
|
327
|
+
* Any tab can be disabled via the `disabled` prop on `TabsTab`.
|
|
328
|
+
* The indicator skips over disabled tabs.
|
|
91
329
|
*/
|
|
92
|
-
export const
|
|
93
|
-
render: () =>
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
key={value}
|
|
114
|
-
value={value}
|
|
115
|
-
className="space-y-2 min-h-[150px]"
|
|
116
|
-
>
|
|
117
|
-
{content}
|
|
118
|
-
</TabContent>
|
|
119
|
-
))}
|
|
120
|
-
<div className="flex justify-end mt-2 gap-x-2">
|
|
121
|
-
<Button variant="ghost" disabled={isFirstStep} onClick={back}>
|
|
122
|
-
Prev
|
|
123
|
-
</Button>
|
|
124
|
-
<Button disabled={isLastStep} onClick={next}>
|
|
125
|
-
Next
|
|
126
|
-
</Button>
|
|
127
|
-
</div>
|
|
128
|
-
</Tabs>
|
|
129
|
-
);
|
|
130
|
-
},
|
|
330
|
+
export const Disabled: Story = {
|
|
331
|
+
render: () => (
|
|
332
|
+
<Tabs defaultValue="account" className="w-[480px] h-[340px]">
|
|
333
|
+
<TabsList>
|
|
334
|
+
<TabsTab value="account">Account</TabsTab>
|
|
335
|
+
<TabsTab value="security">Security</TabsTab>
|
|
336
|
+
<TabsTab value="billing" disabled>
|
|
337
|
+
Billing
|
|
338
|
+
</TabsTab>
|
|
339
|
+
<TabsTab value="enterprise" disabled>
|
|
340
|
+
Enterprise
|
|
341
|
+
</TabsTab>
|
|
342
|
+
</TabsList>
|
|
343
|
+
<TabsPanel value="account">
|
|
344
|
+
<AccountPanel />
|
|
345
|
+
</TabsPanel>
|
|
346
|
+
<TabsPanel value="security">
|
|
347
|
+
<SecurityPanel />
|
|
348
|
+
</TabsPanel>
|
|
349
|
+
</Tabs>
|
|
350
|
+
),
|
|
131
351
|
};
|
|
132
352
|
|
|
133
353
|
/**
|
|
134
|
-
*
|
|
135
|
-
*
|
|
354
|
+
* Use `TabsPrimitive` to access the raw Base UI API when the styled wrappers
|
|
355
|
+
* don't cover your use case — custom indicators, additional ARIA attributes, etc.
|
|
136
356
|
*/
|
|
137
|
-
export const
|
|
138
|
-
render: () =>
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
</Tabs>
|
|
179
|
-
</div>
|
|
180
|
-
);
|
|
357
|
+
export const Primitive: Story = {
|
|
358
|
+
render: () => (
|
|
359
|
+
<TabsPrimitive.Root
|
|
360
|
+
defaultValue="account"
|
|
361
|
+
className="w-[480px] h-[340px] flex flex-col gap-2"
|
|
362
|
+
>
|
|
363
|
+
<TabsPrimitive.List className="flex gap-1 border-b">
|
|
364
|
+
<TabsPrimitive.Tab
|
|
365
|
+
value="account"
|
|
366
|
+
className="px-4 py-2 text-sm font-medium data-active:border-b-2 data-active:border-primary cursor-pointer"
|
|
367
|
+
>
|
|
368
|
+
Account
|
|
369
|
+
</TabsPrimitive.Tab>
|
|
370
|
+
<TabsPrimitive.Tab
|
|
371
|
+
value="security"
|
|
372
|
+
className="px-4 py-2 text-sm font-medium data-active:border-b-2 data-active:border-primary cursor-pointer"
|
|
373
|
+
>
|
|
374
|
+
Security
|
|
375
|
+
</TabsPrimitive.Tab>
|
|
376
|
+
</TabsPrimitive.List>
|
|
377
|
+
<TabsPrimitive.Panel value="account">
|
|
378
|
+
<AccountPanel />
|
|
379
|
+
</TabsPrimitive.Panel>
|
|
380
|
+
<TabsPrimitive.Panel value="security">
|
|
381
|
+
<SecurityPanel />
|
|
382
|
+
</TabsPrimitive.Panel>
|
|
383
|
+
</TabsPrimitive.Root>
|
|
384
|
+
),
|
|
385
|
+
parameters: {
|
|
386
|
+
docs: {
|
|
387
|
+
source: {
|
|
388
|
+
code: `<TabsPrimitive.Root defaultValue="account">
|
|
389
|
+
<TabsPrimitive.List>
|
|
390
|
+
<TabsPrimitive.Tab value="account">Account</TabsPrimitive.Tab>
|
|
391
|
+
<TabsPrimitive.Tab value="security">Security</TabsPrimitive.Tab>
|
|
392
|
+
</TabsPrimitive.List>
|
|
393
|
+
<TabsPrimitive.Panel value="account">…</TabsPrimitive.Panel>
|
|
394
|
+
<TabsPrimitive.Panel value="security">…</TabsPrimitive.Panel>
|
|
395
|
+
</TabsPrimitive.Root>`,
|
|
396
|
+
},
|
|
397
|
+
},
|
|
181
398
|
},
|
|
182
399
|
};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { render, screen, waitFor } from "@testing-library/react";
|
|
2
2
|
import { describe, expect, it, vi } from "vitest";
|
|
3
|
-
import {
|
|
4
|
-
import { click } from "../../utils";
|
|
3
|
+
import { TabList, Tabs, TabsContent, TabsTrigger } from "../../components";
|
|
4
|
+
import { click } from "../../utils/tests";
|
|
5
5
|
|
|
6
6
|
describe("Tabs component", () => {
|
|
7
7
|
it("should render correctly", () => {
|
|
@@ -14,8 +14,8 @@ describe("Tabs component", () => {
|
|
|
14
14
|
render(
|
|
15
15
|
<Tabs>
|
|
16
16
|
<TabList>
|
|
17
|
-
<
|
|
18
|
-
<
|
|
17
|
+
<TabsTrigger value="trigger">Trigger</TabsTrigger>
|
|
18
|
+
<TabsTrigger value="test">Test</TabsTrigger>
|
|
19
19
|
</TabList>
|
|
20
20
|
</Tabs>,
|
|
21
21
|
);
|
|
@@ -28,10 +28,10 @@ describe("Tabs component", () => {
|
|
|
28
28
|
render(
|
|
29
29
|
<Tabs defaultValue="trigger">
|
|
30
30
|
<TabList>
|
|
31
|
-
<
|
|
32
|
-
<
|
|
31
|
+
<TabsTrigger value="trigger">Trigger</TabsTrigger>
|
|
32
|
+
<TabsTrigger value="test">Test</TabsTrigger>
|
|
33
33
|
</TabList>
|
|
34
|
-
<
|
|
34
|
+
<TabsContent value="trigger">Contenido de trigger</TabsContent>
|
|
35
35
|
</Tabs>,
|
|
36
36
|
);
|
|
37
37
|
|
|
@@ -41,13 +41,13 @@ describe("Tabs component", () => {
|
|
|
41
41
|
it("should be controlled", () => {
|
|
42
42
|
const mock = vi.fn();
|
|
43
43
|
render(
|
|
44
|
-
<Tabs value="trigger"
|
|
44
|
+
<Tabs value="trigger" onValueChange={mock}>
|
|
45
45
|
<TabList>
|
|
46
|
-
<
|
|
47
|
-
<
|
|
46
|
+
<TabsTrigger value="trigger">Trigger</TabsTrigger>
|
|
47
|
+
<TabsTrigger value="test">Test</TabsTrigger>
|
|
48
48
|
</TabList>
|
|
49
|
-
<
|
|
50
|
-
<
|
|
49
|
+
<TabsContent value="trigger">Contenido de trigger</TabsContent>
|
|
50
|
+
<TabsContent value="test">Contenido de test</TabsContent>
|
|
51
51
|
</Tabs>,
|
|
52
52
|
);
|
|
53
53
|
|