@boxcustodia/library 2.0.0-alpha.12 → 2.0.0-alpha.14
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 +1087 -720
- package/dist/index.es.js +7011 -56097
- package/dist/theme.css +1 -1
- package/package.json +34 -26
- 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 +1246 -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 +616 -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 +219 -294
- package/src/components/button/button.test.tsx +10 -17
- package/src/components/button/button.tsx +78 -19
- package/src/components/button/components/base-button.tsx +30 -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 +141 -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 +99 -77
- package/src/components/date-picker/date-input.stories.tsx +14 -6
- package/src/components/date-picker/date-input.tsx +2 -2
- 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 +28 -14
- 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 +126 -51
- package/src/components/divider/divider.tsx +16 -16
- package/src/components/dropzone/dropzone.stories.tsx +71 -90
- package/src/components/dropzone/dropzone.tsx +383 -105
- package/src/components/dropzone/index.ts +0 -1
- package/src/components/empty/empty.stories.tsx +165 -0
- package/src/components/empty/empty.tsx +156 -0
- package/src/components/empty/index.ts +1 -0
- package/src/components/field/field.stories.tsx +227 -4
- 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 +4 -4
- 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 +276 -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 +31 -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 +154 -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 +29 -9
- 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 +767 -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 +373 -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 +155 -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 +323 -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 +365 -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 +67 -37
- package/src/utils/index.ts +1 -1
- package/src/__doc__/Migration.mdx +0 -475
- 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,6 +1,6 @@
|
|
|
1
1
|
import { useControllableState } from "@radix-ui/react-use-controllable-state";
|
|
2
2
|
import { CalendarIcon } from "lucide-react";
|
|
3
|
-
import { ReactNode, useRef, useState } from "react";
|
|
3
|
+
import { type ReactElement, ReactNode, useRef, useState } from "react";
|
|
4
4
|
import {
|
|
5
5
|
Calendar,
|
|
6
6
|
FieldControl,
|
|
@@ -24,11 +24,14 @@ import {
|
|
|
24
24
|
formatSingleDate,
|
|
25
25
|
} from "./date-picker.utils";
|
|
26
26
|
|
|
27
|
-
export
|
|
27
|
+
export function DatePicker(props: SingleDatePickerProps): ReactElement;
|
|
28
|
+
export function DatePicker(props: RangeDatePickerProps): ReactElement;
|
|
29
|
+
export function DatePicker(props: MultipleDatePickerProps): ReactElement;
|
|
30
|
+
export function DatePicker(props: DatePickerProps): ReactElement {
|
|
28
31
|
if (props.mode === "range") return <RangePicker {...props} />;
|
|
29
32
|
if (props.mode === "multiple") return <MultiplePicker {...props} />;
|
|
30
33
|
return <SinglePicker {...props} />;
|
|
31
|
-
}
|
|
34
|
+
}
|
|
32
35
|
|
|
33
36
|
// ─── Shared popover shell ────────────────────────────────────────────────────
|
|
34
37
|
|
|
@@ -39,6 +42,7 @@ type PickerShellProps = {
|
|
|
39
42
|
hasValue: boolean;
|
|
40
43
|
disabled?: boolean;
|
|
41
44
|
className?: string;
|
|
45
|
+
classNames?: DatePickerProps["classNames"];
|
|
42
46
|
children: ReactNode;
|
|
43
47
|
footer?: ReactNode;
|
|
44
48
|
slot: string;
|
|
@@ -53,6 +57,7 @@ const PickerShell = ({
|
|
|
53
57
|
hasValue,
|
|
54
58
|
disabled,
|
|
55
59
|
className,
|
|
60
|
+
classNames,
|
|
56
61
|
children,
|
|
57
62
|
footer,
|
|
58
63
|
slot,
|
|
@@ -100,13 +105,16 @@ const PickerShell = ({
|
|
|
100
105
|
}
|
|
101
106
|
/>
|
|
102
107
|
<PopoverPopup
|
|
103
|
-
className="w-auto p-0"
|
|
108
|
+
className={cn("w-auto p-0", classNames?.popup)}
|
|
104
109
|
align="start"
|
|
105
110
|
data-slot={`${slot}-content`}
|
|
106
111
|
>
|
|
107
112
|
{children}
|
|
108
113
|
{footer && (
|
|
109
|
-
<div
|
|
114
|
+
<div
|
|
115
|
+
className={cn("p-2", classNames?.footer)}
|
|
116
|
+
data-slot={`${slot}-footer`}
|
|
117
|
+
>
|
|
110
118
|
{footer}
|
|
111
119
|
</div>
|
|
112
120
|
)}
|
|
@@ -120,19 +128,20 @@ const PickerShell = ({
|
|
|
120
128
|
const SinglePicker = ({
|
|
121
129
|
value: valueProp,
|
|
122
130
|
defaultValue,
|
|
123
|
-
|
|
131
|
+
onValueChange,
|
|
124
132
|
placeholder = "Seleccionar fecha",
|
|
125
133
|
disabled,
|
|
126
134
|
disabledDate,
|
|
127
135
|
renderFooter,
|
|
128
136
|
className,
|
|
137
|
+
classNames,
|
|
129
138
|
required,
|
|
130
139
|
}: SingleDatePickerProps) => {
|
|
131
140
|
const [open, setOpen] = useState(false);
|
|
132
141
|
|
|
133
142
|
const [value, setValue] = useControllableState<Date | null>({
|
|
134
143
|
prop: valueProp,
|
|
135
|
-
onChange: (next) =>
|
|
144
|
+
onChange: (next) => onValueChange?.(next ?? null),
|
|
136
145
|
defaultProp: defaultValue ?? null,
|
|
137
146
|
});
|
|
138
147
|
|
|
@@ -157,12 +166,13 @@ const SinglePicker = ({
|
|
|
157
166
|
hasValue={!!value}
|
|
158
167
|
disabled={disabled}
|
|
159
168
|
className={className}
|
|
169
|
+
classNames={classNames}
|
|
160
170
|
footer={renderFooter?.(footerProps)}
|
|
161
171
|
formValue={formatSingleDate(value, "")}
|
|
162
172
|
required={required}
|
|
163
173
|
>
|
|
164
174
|
<Calendar
|
|
165
|
-
className="border-none"
|
|
175
|
+
className={cn("border-none", classNames?.calendar)}
|
|
166
176
|
mode="single"
|
|
167
177
|
selected={value ?? undefined}
|
|
168
178
|
onSelect={(next) => {
|
|
@@ -183,19 +193,20 @@ const EMPTY_RANGE: DateRange = { start: null, end: null };
|
|
|
183
193
|
const RangePicker = ({
|
|
184
194
|
value: valueProp,
|
|
185
195
|
defaultValue,
|
|
186
|
-
|
|
196
|
+
onValueChange,
|
|
187
197
|
placeholder = "Seleccionar rango",
|
|
188
198
|
disabled,
|
|
189
199
|
disabledDate,
|
|
190
200
|
renderFooter,
|
|
191
201
|
className,
|
|
202
|
+
classNames,
|
|
192
203
|
required,
|
|
193
204
|
}: RangeDatePickerProps) => {
|
|
194
205
|
const [open, setOpen] = useState(false);
|
|
195
206
|
|
|
196
207
|
const [value, setValue] = useControllableState<DateRange>({
|
|
197
208
|
prop: valueProp,
|
|
198
|
-
onChange: (next) =>
|
|
209
|
+
onChange: (next) => onValueChange?.(next ?? EMPTY_RANGE),
|
|
199
210
|
defaultProp: defaultValue ?? EMPTY_RANGE,
|
|
200
211
|
});
|
|
201
212
|
|
|
@@ -220,6 +231,7 @@ const RangePicker = ({
|
|
|
220
231
|
hasValue={!!(range.start || range.end)}
|
|
221
232
|
disabled={disabled}
|
|
222
233
|
className={className}
|
|
234
|
+
classNames={classNames}
|
|
223
235
|
footer={renderFooter?.(footerProps)}
|
|
224
236
|
formValue={formatRangeDate(
|
|
225
237
|
range.start || range.end ? range : undefined,
|
|
@@ -228,7 +240,7 @@ const RangePicker = ({
|
|
|
228
240
|
required={required}
|
|
229
241
|
>
|
|
230
242
|
<Calendar
|
|
231
|
-
className="border-none"
|
|
243
|
+
className={cn("border-none", classNames?.calendar)}
|
|
232
244
|
mode="range"
|
|
233
245
|
selected={{
|
|
234
246
|
from: range.start ?? undefined,
|
|
@@ -248,19 +260,20 @@ const RangePicker = ({
|
|
|
248
260
|
const MultiplePicker = ({
|
|
249
261
|
value: valueProp,
|
|
250
262
|
defaultValue,
|
|
251
|
-
|
|
263
|
+
onValueChange,
|
|
252
264
|
placeholder = "Seleccionar fechas",
|
|
253
265
|
disabled,
|
|
254
266
|
disabledDate,
|
|
255
267
|
renderFooter,
|
|
256
268
|
className,
|
|
269
|
+
classNames,
|
|
257
270
|
required,
|
|
258
271
|
}: MultipleDatePickerProps) => {
|
|
259
272
|
const [open, setOpen] = useState(false);
|
|
260
273
|
|
|
261
274
|
const [value, setValue] = useControllableState<Date[]>({
|
|
262
275
|
prop: valueProp,
|
|
263
|
-
onChange: (next) =>
|
|
276
|
+
onChange: (next) => onValueChange?.(next ?? []),
|
|
264
277
|
defaultProp: defaultValue ?? [],
|
|
265
278
|
});
|
|
266
279
|
|
|
@@ -280,12 +293,13 @@ const MultiplePicker = ({
|
|
|
280
293
|
hasValue={(value?.length ?? 0) > 0}
|
|
281
294
|
disabled={disabled}
|
|
282
295
|
className={className}
|
|
296
|
+
classNames={classNames}
|
|
283
297
|
footer={renderFooter?.(footerProps)}
|
|
284
298
|
formValue={formatMultipleDates(value, "")}
|
|
285
299
|
required={required}
|
|
286
300
|
>
|
|
287
301
|
<Calendar
|
|
288
|
-
className="border-none"
|
|
302
|
+
className={cn("border-none", classNames?.calendar)}
|
|
289
303
|
mode="multiple"
|
|
290
304
|
selected={value ?? []}
|
|
291
305
|
onSelect={(next) => {
|
|
@@ -42,6 +42,7 @@ const meta: Meta<typeof Dialog> = {
|
|
|
42
42
|
hideClose: { control: "boolean" },
|
|
43
43
|
footer: { control: false },
|
|
44
44
|
children: { control: false },
|
|
45
|
+
classNames: { control: false },
|
|
45
46
|
},
|
|
46
47
|
};
|
|
47
48
|
|
|
@@ -50,6 +51,23 @@ type Story = StoryObj<typeof Dialog>;
|
|
|
50
51
|
|
|
51
52
|
export const Default: Story = {};
|
|
52
53
|
|
|
54
|
+
/**
|
|
55
|
+
* `className` styles the popup panel. `classNames` exposes the `backdrop`,
|
|
56
|
+
* `viewport`, `header`, `title`, `description`, `footer`, and `closeButton` slots.
|
|
57
|
+
*/
|
|
58
|
+
export const WithClassNames: Story = {
|
|
59
|
+
args: {
|
|
60
|
+
trigger: <Button variant="outline">Open styled dialog</Button>,
|
|
61
|
+
title: "Styled dialog",
|
|
62
|
+
description: "Each internal slot can be tweaked via classNames.",
|
|
63
|
+
classNames: {
|
|
64
|
+
backdrop: "bg-primary/30",
|
|
65
|
+
title: "text-primary",
|
|
66
|
+
closeButton: "text-primary",
|
|
67
|
+
},
|
|
68
|
+
},
|
|
69
|
+
};
|
|
70
|
+
|
|
53
71
|
/**
|
|
54
72
|
* The primary use case: a dialog containing a form.
|
|
55
73
|
* `children` renders between the description and the footer.
|
|
@@ -68,24 +68,31 @@ export function DialogViewport({
|
|
|
68
68
|
/**
|
|
69
69
|
* Dialog content container. Includes Portal, Backdrop and Viewport internally.
|
|
70
70
|
* Pass `portalProps` to configure the portal (e.g. a custom `container`).
|
|
71
|
-
*
|
|
71
|
+
* `classNames` styles the internal `backdrop`, `viewport` and `closeButton` slots.
|
|
72
72
|
*/
|
|
73
73
|
export function DialogPopup({
|
|
74
74
|
className,
|
|
75
|
+
classNames,
|
|
75
76
|
children,
|
|
76
77
|
hideClose,
|
|
77
|
-
closeProps,
|
|
78
78
|
portalProps,
|
|
79
79
|
...props
|
|
80
80
|
}: DialogBase.Popup.Props & {
|
|
81
81
|
hideClose?: boolean;
|
|
82
|
-
closeProps?: DialogBase.Close.Props;
|
|
83
82
|
portalProps?: DialogBase.Portal.Props;
|
|
83
|
+
classNames?: {
|
|
84
|
+
/** Overlay rendered behind the dialog. */
|
|
85
|
+
backdrop?: string;
|
|
86
|
+
/** Full-screen container that centers the popup. */
|
|
87
|
+
viewport?: string;
|
|
88
|
+
/** Close (×) button rendered inside the popup. */
|
|
89
|
+
closeButton?: string;
|
|
90
|
+
};
|
|
84
91
|
}) {
|
|
85
92
|
return (
|
|
86
93
|
<DialogBase.Portal {...portalProps}>
|
|
87
|
-
<DialogBackdrop />
|
|
88
|
-
<DialogViewport>
|
|
94
|
+
<DialogBackdrop className={classNames?.backdrop} />
|
|
95
|
+
<DialogViewport className={classNames?.viewport}>
|
|
89
96
|
<DialogBase.Popup
|
|
90
97
|
data-slot="dialog-popup"
|
|
91
98
|
className={cn(
|
|
@@ -101,9 +108,8 @@ export function DialogPopup({
|
|
|
101
108
|
{!hideClose && (
|
|
102
109
|
<DialogBase.Close
|
|
103
110
|
aria-label="Close"
|
|
104
|
-
className="absolute right-2 top-2"
|
|
111
|
+
className={cn("absolute right-2 top-2", classNames?.closeButton)}
|
|
105
112
|
render={<Button size="icon" variant="ghost" />}
|
|
106
|
-
{...closeProps}
|
|
107
113
|
>
|
|
108
114
|
<X className="size-4" />
|
|
109
115
|
</DialogBase.Close>
|
|
@@ -201,12 +207,25 @@ export type DialogProps = Omit<DialogBase.Root.Props, "children"> & {
|
|
|
201
207
|
onClose?: () => void;
|
|
202
208
|
/** Hides the close (×) button inside the popup. */
|
|
203
209
|
hideClose?: boolean;
|
|
204
|
-
/**
|
|
205
|
-
closeProps?: DialogBase.Close.Props;
|
|
206
|
-
/** Props forwarded to the portal. */
|
|
207
|
-
portalProps?: DialogBase.Portal.Props;
|
|
208
|
-
/** Additional className forwarded to the popup panel. */
|
|
210
|
+
/** Styles the dialog popup panel. */
|
|
209
211
|
className?: string;
|
|
212
|
+
/** Styles applied to each internal slot. */
|
|
213
|
+
classNames?: {
|
|
214
|
+
/** Overlay rendered behind the dialog. */
|
|
215
|
+
backdrop?: string;
|
|
216
|
+
/** Full-screen container that centers the popup. */
|
|
217
|
+
viewport?: string;
|
|
218
|
+
/** Layout wrapper for title and description. */
|
|
219
|
+
header?: string;
|
|
220
|
+
/** Dialog heading. */
|
|
221
|
+
title?: string;
|
|
222
|
+
/** Supporting text below the title. */
|
|
223
|
+
description?: string;
|
|
224
|
+
/** Layout wrapper for footer content. */
|
|
225
|
+
footer?: string;
|
|
226
|
+
/** Close (×) button rendered inside the popup. */
|
|
227
|
+
closeButton?: string;
|
|
228
|
+
};
|
|
210
229
|
};
|
|
211
230
|
|
|
212
231
|
/**
|
|
@@ -216,6 +235,10 @@ export type DialogProps = Omit<DialogBase.Root.Props, "children"> & {
|
|
|
216
235
|
* making it composable with `<Tooltip>` at the primitive level.
|
|
217
236
|
* For full structural control, use the exported primitives directly.
|
|
218
237
|
*
|
|
238
|
+
* `className` styles the popup panel. `classNames` exposes the `backdrop`,
|
|
239
|
+
* `viewport`, `header`, `title`, `description`, `footer`, and `closeButton`
|
|
240
|
+
* slots for fine-grained tweaks without dropping to primitives.
|
|
241
|
+
*
|
|
219
242
|
* @example
|
|
220
243
|
* ```tsx
|
|
221
244
|
* <Dialog
|
|
@@ -236,9 +259,8 @@ export function Dialog({
|
|
|
236
259
|
footer,
|
|
237
260
|
onClose,
|
|
238
261
|
hideClose,
|
|
239
|
-
closeProps,
|
|
240
|
-
portalProps,
|
|
241
262
|
className,
|
|
263
|
+
classNames,
|
|
242
264
|
onOpenChange,
|
|
243
265
|
...props
|
|
244
266
|
}: DialogProps) {
|
|
@@ -254,19 +276,28 @@ export function Dialog({
|
|
|
254
276
|
<DialogPopup
|
|
255
277
|
className={className}
|
|
256
278
|
hideClose={hideClose}
|
|
257
|
-
|
|
258
|
-
|
|
279
|
+
classNames={{
|
|
280
|
+
backdrop: classNames?.backdrop,
|
|
281
|
+
viewport: classNames?.viewport,
|
|
282
|
+
closeButton: classNames?.closeButton,
|
|
283
|
+
}}
|
|
259
284
|
>
|
|
260
285
|
{(title || description) && (
|
|
261
|
-
<DialogHeader>
|
|
262
|
-
{title &&
|
|
286
|
+
<DialogHeader className={classNames?.header}>
|
|
287
|
+
{title && (
|
|
288
|
+
<DialogTitle className={classNames?.title}>{title}</DialogTitle>
|
|
289
|
+
)}
|
|
263
290
|
{description && (
|
|
264
|
-
<DialogDescription
|
|
291
|
+
<DialogDescription className={classNames?.description}>
|
|
292
|
+
{description}
|
|
293
|
+
</DialogDescription>
|
|
265
294
|
)}
|
|
266
295
|
</DialogHeader>
|
|
267
296
|
)}
|
|
268
297
|
{children}
|
|
269
|
-
{footer &&
|
|
298
|
+
{footer && (
|
|
299
|
+
<DialogFooter className={classNames?.footer}>{footer}</DialogFooter>
|
|
300
|
+
)}
|
|
270
301
|
</DialogPopup>
|
|
271
302
|
</DialogRoot>
|
|
272
303
|
);
|
|
@@ -1,70 +1,145 @@
|
|
|
1
|
-
import { Meta, StoryObj } from "@storybook/react-vite";
|
|
2
|
-
import {
|
|
3
|
-
import { Button, Divider } from "../../components";
|
|
1
|
+
import type { Meta, StoryObj } from "@storybook/react-vite";
|
|
2
|
+
import { Divider } from "../../components";
|
|
4
3
|
|
|
4
|
+
/**
|
|
5
|
+
* Visual separator between sections or inline elements.
|
|
6
|
+
*
|
|
7
|
+
* Built on the Base UI `Separator` primitive. Supports `orientation` (`horizontal` | `vertical`)
|
|
8
|
+
* and a `render` prop for polymorphic composition. The DOM element receives `data-orientation`
|
|
9
|
+
* which can be used as a CSS selector for conditional styles.
|
|
10
|
+
*/
|
|
5
11
|
const meta: Meta<typeof Divider> = {
|
|
6
|
-
title: "
|
|
12
|
+
title: "Components/Divider",
|
|
7
13
|
component: Divider,
|
|
14
|
+
args: {
|
|
15
|
+
orientation: "horizontal",
|
|
16
|
+
},
|
|
17
|
+
argTypes: {
|
|
18
|
+
orientation: {
|
|
19
|
+
control: "radio",
|
|
20
|
+
options: ["horizontal", "vertical"],
|
|
21
|
+
},
|
|
22
|
+
},
|
|
23
|
+
parameters: {
|
|
24
|
+
layout: "centered",
|
|
25
|
+
},
|
|
8
26
|
};
|
|
9
27
|
|
|
10
28
|
export default meta;
|
|
11
|
-
type Story = StoryObj<typeof
|
|
29
|
+
type Story = StoryObj<typeof Divider>;
|
|
30
|
+
|
|
31
|
+
export const Default: Story = {
|
|
32
|
+
render: () => (
|
|
33
|
+
<div className="w-72 rounded-lg border p-4 text-sm">
|
|
34
|
+
<div className="flex items-center justify-between">
|
|
35
|
+
<span className="font-medium">Deployment #847</span>
|
|
36
|
+
<span className="text-xs text-green-500">● Live</span>
|
|
37
|
+
</div>
|
|
38
|
+
<Divider className="my-3" />
|
|
39
|
+
<div className="space-y-1.5 text-muted-foreground">
|
|
40
|
+
<div className="flex justify-between">
|
|
41
|
+
<span>Triggered by</span>
|
|
42
|
+
<span className="text-foreground">fbaigorria</span>
|
|
43
|
+
</div>
|
|
44
|
+
<div className="flex justify-between">
|
|
45
|
+
<span>Branch</span>
|
|
46
|
+
<span className="text-foreground">develop</span>
|
|
47
|
+
</div>
|
|
48
|
+
<div className="flex justify-between">
|
|
49
|
+
<span>Duration</span>
|
|
50
|
+
<span className="text-foreground">1m 43s</span>
|
|
51
|
+
</div>
|
|
52
|
+
</div>
|
|
53
|
+
<Divider className="my-3" />
|
|
54
|
+
<div className="flex items-center justify-center gap-4 text-muted-foreground">
|
|
55
|
+
<span>2 warnings</span>
|
|
56
|
+
<Divider orientation="vertical" className="h-4" />
|
|
57
|
+
<span>0 errors</span>
|
|
58
|
+
<Divider orientation="vertical" className="h-4" />
|
|
59
|
+
<span>127 tests</span>
|
|
60
|
+
</div>
|
|
61
|
+
</div>
|
|
62
|
+
),
|
|
63
|
+
};
|
|
12
64
|
|
|
65
|
+
/**
|
|
66
|
+
* Default orientation. Renders a full-width 1px horizontal line via `data-[orientation=horizontal]`.
|
|
67
|
+
* Commonly used to separate named sections inside a panel or card.
|
|
68
|
+
*/
|
|
13
69
|
export const Horizontal: Story = {
|
|
70
|
+
render: () => (
|
|
71
|
+
<div className="w-72 rounded-lg border p-4 space-y-4">
|
|
72
|
+
<div>
|
|
73
|
+
<p className="text-sm font-medium">Profile</p>
|
|
74
|
+
<p className="text-xs text-muted-foreground">Franco Baigorria</p>
|
|
75
|
+
</div>
|
|
76
|
+
<Divider />
|
|
77
|
+
<div>
|
|
78
|
+
<p className="text-sm font-medium">Team</p>
|
|
79
|
+
<p className="text-xs text-muted-foreground">Engineering</p>
|
|
80
|
+
</div>
|
|
81
|
+
<Divider />
|
|
82
|
+
<div>
|
|
83
|
+
<p className="text-sm font-medium">Role</p>
|
|
84
|
+
<p className="text-xs text-muted-foreground">Frontend Architect</p>
|
|
85
|
+
</div>
|
|
86
|
+
</div>
|
|
87
|
+
),
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* In vertical orientation the component uses `self-stretch` to fill the full height of
|
|
92
|
+
* the flex container. Wrapping in a `div` with `flex` and a defined height is the expected pattern.
|
|
93
|
+
*/
|
|
94
|
+
export const Vertical: Story = {
|
|
14
95
|
args: {
|
|
15
|
-
orientation: "
|
|
96
|
+
orientation: "vertical",
|
|
16
97
|
},
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
<
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
</Button>
|
|
27
|
-
<Story />
|
|
28
|
-
<Button size="icon">
|
|
29
|
-
<Github />
|
|
30
|
-
</Button>
|
|
31
|
-
</div>
|
|
32
|
-
),
|
|
33
|
-
],
|
|
98
|
+
render: (args) => (
|
|
99
|
+
<div className="flex h-10 items-center gap-4">
|
|
100
|
+
<span className="text-sm">Section A</span>
|
|
101
|
+
<Divider {...args} />
|
|
102
|
+
<span className="text-sm">Section B</span>
|
|
103
|
+
<Divider {...args} />
|
|
104
|
+
<span className="text-sm">Section C</span>
|
|
105
|
+
</div>
|
|
106
|
+
),
|
|
34
107
|
};
|
|
35
108
|
|
|
36
109
|
/**
|
|
37
|
-
*
|
|
38
|
-
*
|
|
110
|
+
* The `render` prop replaces the rendered DOM element. Useful for swapping semantics
|
|
111
|
+
* to `<hr>` or any other element without losing component styles.
|
|
39
112
|
*
|
|
40
113
|
* ```tsx
|
|
41
|
-
* <
|
|
42
|
-
* <PencilIcon />
|
|
43
|
-
* <Divider orientation="vertical" /> // <- vertical
|
|
44
|
-
* <CatIcon />
|
|
45
|
-
* </div>
|
|
114
|
+
* <Divider render={<hr />} />
|
|
46
115
|
* ```
|
|
47
116
|
*/
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
117
|
+
export const Render: Story = {
|
|
118
|
+
render: (args) => (
|
|
119
|
+
<div className="w-64">
|
|
120
|
+
<Divider {...args} render={<hr />} />
|
|
121
|
+
</div>
|
|
122
|
+
),
|
|
123
|
+
parameters: {
|
|
124
|
+
docs: {
|
|
125
|
+
source: {
|
|
126
|
+
code: `<Divider render={<hr />} />`,
|
|
127
|
+
},
|
|
128
|
+
},
|
|
52
129
|
},
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
),
|
|
69
|
-
],
|
|
130
|
+
};
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* `className` accepts Tailwind classes to override color, thickness, or spacing.
|
|
134
|
+
* `data-[orientation=horizontal]` and `data-[orientation=vertical]` are available
|
|
135
|
+
* as CSS selectors for advanced conditional styles.
|
|
136
|
+
*/
|
|
137
|
+
export const Custom: Story = {
|
|
138
|
+
render: () => (
|
|
139
|
+
<div className="space-y-4 w-64">
|
|
140
|
+
<Divider className="bg-primary" />
|
|
141
|
+
<Divider className="bg-error" />
|
|
142
|
+
<Divider className="border-t border-dashed border-input bg-transparent" />
|
|
143
|
+
</div>
|
|
144
|
+
),
|
|
70
145
|
};
|
|
@@ -1,23 +1,23 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import
|
|
3
|
-
|
|
4
|
-
type Props = {
|
|
5
|
-
orientation?: "horizontal" | "vertical";
|
|
6
|
-
} & HTMLProps<HTMLHRElement>;
|
|
7
|
-
|
|
8
|
-
export const Divider = (props: Props) => {
|
|
9
|
-
const { className, orientation = "horizontal" } = props;
|
|
1
|
+
import { Separator as SeparatorPrimitive } from "@base-ui/react/separator";
|
|
2
|
+
import type React from "react";
|
|
3
|
+
import { cn } from "tailwind-variants";
|
|
10
4
|
|
|
5
|
+
export function Divider({
|
|
6
|
+
className,
|
|
7
|
+
orientation = "horizontal",
|
|
8
|
+
...props
|
|
9
|
+
}: SeparatorPrimitive.Props): React.ReactElement {
|
|
11
10
|
return (
|
|
12
|
-
<
|
|
13
|
-
{...props}
|
|
14
|
-
aria-orientation={orientation}
|
|
11
|
+
<SeparatorPrimitive
|
|
15
12
|
className={cn(
|
|
16
|
-
"shrink-0 bg-input",
|
|
17
|
-
orientation === "horizontal" ? "h-[1px] w-full" : "h-full w-[1px]",
|
|
13
|
+
"shrink-0 bg-input data-[orientation=horizontal]:h-px data-[orientation=horizontal]:w-full data-[orientation=vertical]:w-px data-[orientation=vertical]:not-[[class^='h-']]:not-[[class*='_h-']]:self-stretch",
|
|
18
14
|
className,
|
|
19
15
|
)}
|
|
20
|
-
data-slot="
|
|
16
|
+
data-slot="separator"
|
|
17
|
+
orientation={orientation}
|
|
18
|
+
{...props}
|
|
21
19
|
/>
|
|
22
20
|
);
|
|
23
|
-
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export { SeparatorPrimitive };
|