@boxcustodia/library 2.0.0-alpha.13 → 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 +1083 -715
- package/dist/index.es.js +7077 -56175
- 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 +119 -103
- 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 +6 -0
- 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 +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 +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 +25 -29
- 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 +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 +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 -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,175 +1,98 @@
|
|
|
1
|
-
|
|
2
|
-
import { HTMLProps, ReactNode, useEffect, useRef, useState } from "react";
|
|
3
|
-
import { cn } from "../../lib";
|
|
4
|
-
import { TabsContextProvider, useTabsContext } from "./context/tabs-context";
|
|
1
|
+
"use client";
|
|
5
2
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
triggerClassName: TabTriggerProps["className"];
|
|
10
|
-
triggerProps: TabTriggerProps;
|
|
11
|
-
contentClassName: TabContentProps["className"];
|
|
12
|
-
contentProps: TabContentProps;
|
|
13
|
-
}
|
|
3
|
+
import { Tabs as TabsPrimitive } from "@base-ui/react/tabs";
|
|
4
|
+
import type React from "react";
|
|
5
|
+
import { cn } from "../../lib";
|
|
14
6
|
|
|
15
|
-
|
|
16
|
-
extends Omit<
|
|
17
|
-
HTMLProps<HTMLDivElement>,
|
|
18
|
-
"value" | "defaultValue" | "onChange"
|
|
19
|
-
> {
|
|
20
|
-
value?: string;
|
|
21
|
-
onChange?: (tab: string) => void;
|
|
22
|
-
defaultValue?: string;
|
|
23
|
-
variant?: "default" | "background";
|
|
24
|
-
}
|
|
7
|
+
export type TabsVariant = "underline" | "background";
|
|
25
8
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
value: prop,
|
|
29
|
-
onChange,
|
|
30
|
-
defaultValue,
|
|
31
|
-
variant = "default",
|
|
9
|
+
export function Tabs({
|
|
10
|
+
className,
|
|
32
11
|
...props
|
|
33
|
-
}:
|
|
34
|
-
const [activeTab = "", setActiveTab] = useControllableState<string>({
|
|
35
|
-
prop,
|
|
36
|
-
onChange,
|
|
37
|
-
defaultProp: defaultValue as string,
|
|
38
|
-
});
|
|
39
|
-
const [targetRef, setTargetRef] = useState<HTMLButtonElement | null>(null);
|
|
40
|
-
|
|
12
|
+
}: TabsPrimitive.Root.Props): React.ReactElement {
|
|
41
13
|
return (
|
|
42
|
-
<
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
14
|
+
<TabsPrimitive.Root
|
|
15
|
+
className={cn(
|
|
16
|
+
"flex flex-col gap-2 data-[orientation=vertical]:flex-row",
|
|
17
|
+
className,
|
|
18
|
+
)}
|
|
19
|
+
data-slot="tabs"
|
|
20
|
+
{...props}
|
|
21
|
+
/>
|
|
49
22
|
);
|
|
50
|
-
};
|
|
51
|
-
|
|
52
|
-
interface TabListProps {
|
|
53
|
-
children: ReactNode;
|
|
54
|
-
className?: string;
|
|
55
|
-
indicatorClassName?: string;
|
|
56
23
|
}
|
|
57
24
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
25
|
+
export function TabsList({
|
|
26
|
+
variant = "underline",
|
|
27
|
+
centered = false,
|
|
28
|
+
className,
|
|
29
|
+
children,
|
|
30
|
+
...props
|
|
31
|
+
}: TabsPrimitive.List.Props & {
|
|
32
|
+
variant?: TabsVariant;
|
|
33
|
+
centered?: boolean;
|
|
34
|
+
}): React.ReactElement {
|
|
61
35
|
return (
|
|
62
|
-
<
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
36
|
+
<TabsPrimitive.List
|
|
37
|
+
data-variant={variant}
|
|
38
|
+
className={cn(
|
|
39
|
+
"group/tabs-list relative z-0 flex w-fit items-center justify-center gap-x-0.5 text-muted-foreground",
|
|
40
|
+
centered && "mx-auto",
|
|
41
|
+
"data-[orientation=vertical]:flex-col data-[orientation=vertical]:justify-start",
|
|
42
|
+
variant === "background"
|
|
43
|
+
? "rounded-lg border border-border p-0.5"
|
|
44
|
+
: "data-[orientation=vertical]:px-1 data-[orientation=horizontal]:py-1 *:data-[slot=tabs-tab]:hover:bg-accent",
|
|
45
|
+
className,
|
|
46
|
+
)}
|
|
47
|
+
data-slot="tabs-list"
|
|
48
|
+
{...props}
|
|
49
|
+
>
|
|
50
|
+
{children}
|
|
51
|
+
<TabsPrimitive.Indicator
|
|
52
|
+
className={cn(
|
|
53
|
+
"absolute bottom-0 left-0 h-(--active-tab-height) w-(--active-tab-width) translate-x-(--active-tab-left) -translate-y-(--active-tab-bottom) transition-[width,translate] duration-200 ease-in-out",
|
|
54
|
+
variant === "background"
|
|
55
|
+
? "-z-1 rounded-md bg-primary shadow-sm/5"
|
|
56
|
+
: "z-10 bg-primary data-[orientation=horizontal]:h-0.5 data-[orientation=vertical]:w-0.5 data-[orientation=vertical]:-translate-x-px data-[orientation=horizontal]:translate-y-px",
|
|
57
|
+
)}
|
|
58
|
+
data-slot="tab-indicator"
|
|
69
59
|
/>
|
|
70
|
-
</
|
|
60
|
+
</TabsPrimitive.List>
|
|
71
61
|
);
|
|
72
|
-
};
|
|
73
|
-
|
|
74
|
-
interface TabTriggerProps
|
|
75
|
-
extends Omit<HTMLProps<HTMLButtonElement>, "onClick" | "type"> {
|
|
76
|
-
value: string;
|
|
77
62
|
}
|
|
78
63
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
64
|
+
export function TabsTab({
|
|
65
|
+
className,
|
|
66
|
+
...props
|
|
67
|
+
}: TabsPrimitive.Tab.Props): React.ReactElement {
|
|
83
68
|
return (
|
|
84
|
-
<
|
|
85
|
-
data-slot="tabs-trigger"
|
|
86
|
-
{...props}
|
|
87
|
-
type="button"
|
|
88
|
-
ref={(element) => {
|
|
89
|
-
if (isActive) setTargetRef(element);
|
|
90
|
-
}}
|
|
91
|
-
onClick={() => setActiveTab(value)}
|
|
92
|
-
data-tab={value}
|
|
93
|
-
data-selected={isActive}
|
|
94
|
-
aria-selected={isActive}
|
|
69
|
+
<TabsPrimitive.Tab
|
|
95
70
|
className={cn(
|
|
96
|
-
"px-2
|
|
97
|
-
variant === "background"
|
|
98
|
-
? "hover:bg-transparent aria-selected:text-primary-foreground rounded"
|
|
99
|
-
: "hover:bg-accent hover:text-accent-foreground",
|
|
71
|
+
"relative flex h-9 shrink-0 grow cursor-pointer items-center justify-center gap-1.5 whitespace-nowrap rounded-md border border-transparent px-[calc(--spacing(2.5)-1px)] font-medium text-base outline-none transition-[color,background-color,box-shadow] hover:text-muted-foreground focus-visible:ring-2 focus-visible:ring-ring data-disabled:pointer-events-none data-[orientation=vertical]:w-full data-[orientation=vertical]:grow-0 data-[orientation=vertical]:justify-start data-active:text-foreground data-disabled:opacity-64 group-data-[variant=background]/tabs-list:data-active:text-primary-foreground sm:h-8 sm:text-sm [&_svg:not([class*='size-'])]:size-4.5 sm:[&_svg:not([class*='size-'])]:size-4 [&_svg]:pointer-events-none [&_svg]:-mx-0.5 [&_svg]:shrink-0",
|
|
100
72
|
className,
|
|
101
73
|
)}
|
|
74
|
+
data-slot="tabs-tab"
|
|
75
|
+
{...props}
|
|
102
76
|
/>
|
|
103
77
|
);
|
|
104
|
-
};
|
|
105
|
-
|
|
106
|
-
interface TabContentProps extends HTMLProps<HTMLDivElement> {
|
|
107
|
-
value: string;
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
const TabContent = ({ value, ...props }: TabContentProps) => {
|
|
111
|
-
const { activeTab } = useTabsContext();
|
|
112
|
-
const isActiveTab = activeTab === value;
|
|
113
|
-
if (!isActiveTab) return null;
|
|
114
|
-
return <div data-slot="tabs-content" {...props} />;
|
|
115
|
-
};
|
|
116
|
-
|
|
117
|
-
interface TabsIndicatorProps {
|
|
118
|
-
targetRef: HTMLButtonElement | null;
|
|
119
|
-
indicatorClassName?: string;
|
|
120
78
|
}
|
|
121
79
|
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
}:
|
|
126
|
-
const indicatorRef = useRef<HTMLDivElement>(null);
|
|
127
|
-
const indicator = indicatorRef?.current;
|
|
128
|
-
const targetResizeObserver = useRef<ResizeObserver>(null);
|
|
129
|
-
const { variant } = useTabsContext();
|
|
130
|
-
|
|
131
|
-
const updatePosition = (): void => {
|
|
132
|
-
if (!targetRef || !indicator) return;
|
|
133
|
-
|
|
134
|
-
const leftDistance = targetRef.offsetLeft;
|
|
135
|
-
const width = targetRef.offsetWidth;
|
|
136
|
-
|
|
137
|
-
indicator.style.width = width + "px";
|
|
138
|
-
indicator.style.left = leftDistance + "px";
|
|
139
|
-
};
|
|
140
|
-
|
|
141
|
-
useEffect(() => {
|
|
142
|
-
if (targetRef) {
|
|
143
|
-
updatePosition();
|
|
144
|
-
targetResizeObserver.current = new ResizeObserver(updatePosition);
|
|
145
|
-
targetResizeObserver.current.observe(targetRef);
|
|
146
|
-
|
|
147
|
-
return () => {
|
|
148
|
-
targetResizeObserver.current?.disconnect();
|
|
149
|
-
};
|
|
150
|
-
}
|
|
151
|
-
}, [targetRef]);
|
|
152
|
-
|
|
80
|
+
export function TabsPanel({
|
|
81
|
+
className,
|
|
82
|
+
...props
|
|
83
|
+
}: TabsPrimitive.Panel.Props): React.ReactElement {
|
|
153
84
|
return (
|
|
154
|
-
<
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
"transition-all duration-300 absolute rounded bg-primary",
|
|
159
|
-
variant === "background"
|
|
160
|
-
? "inset-0 -z-10 h-full top-0"
|
|
161
|
-
: "top-full h-[3px]",
|
|
162
|
-
indicatorClassName,
|
|
163
|
-
)}
|
|
85
|
+
<TabsPrimitive.Panel
|
|
86
|
+
className={cn("flex-1 outline-none", className)}
|
|
87
|
+
data-slot="tabs-content"
|
|
88
|
+
{...props}
|
|
164
89
|
/>
|
|
165
90
|
);
|
|
166
|
-
}
|
|
91
|
+
}
|
|
167
92
|
|
|
168
|
-
export {
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
TabsProps,
|
|
174
|
-
TabTriggerProps,
|
|
93
|
+
export {
|
|
94
|
+
TabsPrimitive,
|
|
95
|
+
TabsTab as TabsTrigger,
|
|
96
|
+
TabsPanel as TabsContent,
|
|
97
|
+
TabsList as TabList,
|
|
175
98
|
};
|
|
@@ -1,170 +1,205 @@
|
|
|
1
|
-
import { Tag } from "../../components";
|
|
2
|
-
import { createToastManager, ToastProvider } from "../toast";
|
|
3
|
-
|
|
4
|
-
const toastManager = createToastManager();
|
|
5
|
-
|
|
6
1
|
import type { Meta, StoryObj } from "@storybook/react-vite";
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
2
|
+
import { BadgeCheck, CheckIcon, X } from "lucide-react";
|
|
3
|
+
import { useState } from "react";
|
|
4
|
+
import { Tag } from "../../components";
|
|
5
|
+
import { Loader } from "../loader";
|
|
9
6
|
|
|
10
7
|
/**
|
|
11
|
-
*
|
|
8
|
+
* Displays a tag or a component that looks like a tag.
|
|
9
|
+
* Supports the Base UI `render` prop to swap the root element (e.g. `<a>`, `<button>`)
|
|
10
|
+
* without losing styles or accessibility.
|
|
11
|
+
*
|
|
12
|
+
* See [Base UI useRender docs](https://base-ui.com/react/utils/use-render) for the full `render` prop API.
|
|
12
13
|
*/
|
|
13
14
|
const meta: Meta<typeof Tag> = {
|
|
14
|
-
title: "
|
|
15
|
+
title: "Components/Tag",
|
|
15
16
|
component: Tag,
|
|
17
|
+
parameters: { layout: "centered" },
|
|
16
18
|
args: {
|
|
17
|
-
children: "
|
|
19
|
+
children: "Tag",
|
|
18
20
|
},
|
|
21
|
+
tags: ["beta"],
|
|
19
22
|
};
|
|
20
23
|
|
|
21
24
|
export default meta;
|
|
22
25
|
type Story = StoryObj<typeof Tag>;
|
|
23
26
|
|
|
24
|
-
|
|
25
|
-
* Variante principal del Tag.
|
|
26
|
-
* Ideal para destacar información importante o etiquetas primarias.
|
|
27
|
-
*/
|
|
28
|
-
export const Primary: Story = {
|
|
29
|
-
args: {
|
|
30
|
-
children: "Tag básico",
|
|
31
|
-
variant: "primary",
|
|
32
|
-
},
|
|
33
|
-
};
|
|
34
|
-
|
|
35
|
-
/**
|
|
36
|
-
* Variante secundaria con un énfasis visual más sutil.
|
|
37
|
-
* Perfecta para información complementaria o categorías secundarias.
|
|
38
|
-
*/
|
|
39
|
-
export const Secondary: Story = {
|
|
40
|
-
args: {
|
|
41
|
-
variant: "secondary",
|
|
42
|
-
children: "Tag secundario",
|
|
43
|
-
},
|
|
44
|
-
};
|
|
45
|
-
|
|
46
|
-
/**
|
|
47
|
-
* Variante de error para resaltar estados problemáticos o alertas.
|
|
48
|
-
* Usar con moderación y solo cuando sea necesario indicar un error o advertencia.
|
|
49
|
-
*/
|
|
50
|
-
export const ErrorVariant: Story = {
|
|
51
|
-
args: {
|
|
52
|
-
variant: "error",
|
|
53
|
-
children: "Tag de error",
|
|
54
|
-
},
|
|
55
|
-
};
|
|
27
|
+
export const Default: Story = {};
|
|
56
28
|
|
|
57
29
|
/**
|
|
58
|
-
*
|
|
59
|
-
* Útil para interfaces minimalistas o cuando se necesita un contraste menor.
|
|
30
|
+
* Use the `variant` prop to change the visual style of the tag.
|
|
60
31
|
*/
|
|
61
|
-
export const
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
32
|
+
export const Variants: Story = {
|
|
33
|
+
render: () => (
|
|
34
|
+
<div className="flex flex-wrap items-center gap-2">
|
|
35
|
+
<Tag>Default</Tag>
|
|
36
|
+
<Tag variant="secondary">Secondary</Tag>
|
|
37
|
+
<Tag variant="error">Error</Tag>
|
|
38
|
+
<Tag variant="outline">Outline</Tag>
|
|
39
|
+
<Tag variant="ghost">Ghost</Tag>
|
|
40
|
+
<Tag variant="link">Link</Tag>
|
|
41
|
+
</div>
|
|
42
|
+
),
|
|
66
43
|
};
|
|
67
44
|
|
|
68
45
|
/**
|
|
69
|
-
*
|
|
46
|
+
* Add `data-icon="inline-start"` or `data-icon="inline-end"` to the icon element
|
|
47
|
+
* to adjust the lateral padding automatically.
|
|
48
|
+
*
|
|
49
|
+
* ```tsx
|
|
50
|
+
* <Tag>
|
|
51
|
+
* <BadgeCheck data-icon="inline-start" />
|
|
52
|
+
* Verified
|
|
53
|
+
* </Tag>
|
|
54
|
+
* ```
|
|
70
55
|
*/
|
|
71
|
-
export const
|
|
56
|
+
export const WithIcon: Story = {
|
|
72
57
|
render: () => (
|
|
73
|
-
<div className="flex
|
|
74
|
-
<Tag
|
|
75
|
-
|
|
58
|
+
<div className="flex flex-wrap items-center gap-2">
|
|
59
|
+
<Tag>
|
|
60
|
+
<BadgeCheck data-icon="inline-start" />
|
|
61
|
+
Verified
|
|
76
62
|
</Tag>
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
63
|
+
<Tag variant="secondary">
|
|
64
|
+
8.5
|
|
65
|
+
<CheckIcon data-icon="inline-end" />
|
|
80
66
|
</Tag>
|
|
81
|
-
<Tag
|
|
82
|
-
|
|
67
|
+
<Tag variant="error">
|
|
68
|
+
<X data-icon="inline-start" />
|
|
69
|
+
Rejected
|
|
83
70
|
</Tag>
|
|
84
71
|
</div>
|
|
85
72
|
),
|
|
86
73
|
};
|
|
87
74
|
|
|
88
75
|
/**
|
|
89
|
-
*
|
|
76
|
+
* Pass `data-icon="inline-start"` or `data-icon="inline-end"` to the `Loader`
|
|
77
|
+
* so its padding matches icon placement conventions.
|
|
90
78
|
*/
|
|
91
|
-
export const
|
|
79
|
+
export const WithSpinner: Story = {
|
|
92
80
|
render: () => (
|
|
93
|
-
<div className="flex flex-
|
|
94
|
-
<Tag
|
|
95
|
-
|
|
81
|
+
<div className="flex flex-wrap items-center gap-2">
|
|
82
|
+
<Tag>
|
|
83
|
+
<Loader
|
|
84
|
+
data-icon="inline-start"
|
|
85
|
+
size="xs"
|
|
86
|
+
className="text-primary-foreground"
|
|
87
|
+
/>
|
|
88
|
+
Processing
|
|
96
89
|
</Tag>
|
|
97
|
-
<Tag
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
<Tag rounded={"square"}>Solido cuadrado</Tag>
|
|
101
|
-
<Tag rounded={"full"} variant={"error"}>
|
|
102
|
-
Solido redondo
|
|
103
|
-
</Tag>
|
|
104
|
-
<Tag rounded={"full"} color="blue" icon={<User />}>
|
|
105
|
-
Solido redondo con icono bordeado
|
|
106
|
-
</Tag>
|
|
107
|
-
<Tag
|
|
108
|
-
rounded={"full"}
|
|
109
|
-
color="red"
|
|
110
|
-
variant={"borderless"}
|
|
111
|
-
icon={<Settings />}
|
|
112
|
-
>
|
|
113
|
-
Coloreado sin borde redondo con icono
|
|
114
|
-
</Tag>
|
|
115
|
-
<Tag
|
|
116
|
-
color="magenta"
|
|
117
|
-
variant={"borderless"}
|
|
118
|
-
closable
|
|
119
|
-
onClose={() => {
|
|
120
|
-
action("onClose")();
|
|
121
|
-
toastManager.add({ variant: "success", description: "Tag cerrado" });
|
|
122
|
-
}}
|
|
123
|
-
>
|
|
124
|
-
Coloreado sin borde redondo y cerrable
|
|
125
|
-
</Tag>
|
|
126
|
-
<Tag color="magenta" variant={"borderless"}>
|
|
127
|
-
Coloreado sin borde
|
|
90
|
+
<Tag variant="secondary">
|
|
91
|
+
<Loader data-icon="inline-start" size="xs" variant="ghost" />
|
|
92
|
+
Loading
|
|
128
93
|
</Tag>
|
|
129
94
|
</div>
|
|
130
95
|
),
|
|
131
96
|
};
|
|
132
97
|
|
|
133
98
|
/**
|
|
134
|
-
*
|
|
135
|
-
*
|
|
99
|
+
* Use the `render` prop to render the tag as a link or any other element.
|
|
100
|
+
* Styles and accessibility semantics from the target element are preserved.
|
|
101
|
+
*
|
|
102
|
+
* ```tsx
|
|
103
|
+
* <Tag render={<a href="/docs" />}>Documentation</Tag>
|
|
104
|
+
* ```
|
|
136
105
|
*/
|
|
137
|
-
export const
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
106
|
+
export const Link: Story = {
|
|
107
|
+
render: () => (
|
|
108
|
+
<div className="flex flex-wrap items-center gap-2">
|
|
109
|
+
<Tag render={<a href="#" />}>Default link</Tag>
|
|
110
|
+
<Tag variant="outline" render={<a href="#" />}>
|
|
111
|
+
Outline link
|
|
112
|
+
</Tag>
|
|
113
|
+
<Tag variant="link" render={<a href="#" />}>
|
|
114
|
+
Underline link
|
|
115
|
+
</Tag>
|
|
116
|
+
</div>
|
|
117
|
+
),
|
|
118
|
+
parameters: {
|
|
119
|
+
docs: {
|
|
120
|
+
source: {
|
|
121
|
+
code: `<Tag render={<a href="/docs" />}>Documentation</Tag>`,
|
|
122
|
+
},
|
|
123
|
+
},
|
|
141
124
|
},
|
|
142
125
|
};
|
|
143
126
|
|
|
144
127
|
/**
|
|
145
|
-
*
|
|
146
|
-
*
|
|
147
|
-
*
|
|
148
|
-
* Al pasar la propiedad `closable` a true, se debe pasar la propiedad `onClose` con una función que se ejecutará al cerrar el tag.
|
|
128
|
+
* The `closable` and `onClose` props were removed in v2. Dismissal is now achieved
|
|
129
|
+
* by composing a `<button>` child with `data-icon="inline-end"` — the variant handles
|
|
130
|
+
* padding automatically via the `has-data-[icon]` selector.
|
|
149
131
|
*
|
|
150
132
|
* ```tsx
|
|
151
|
-
* <Tag
|
|
133
|
+
* <Tag>
|
|
134
|
+
* Closable tag
|
|
135
|
+
* <button type="button" data-icon="inline-end" onClick={onClose}>
|
|
136
|
+
* <X className="size-3" />
|
|
137
|
+
* </button>
|
|
138
|
+
* </Tag>
|
|
152
139
|
* ```
|
|
153
140
|
*/
|
|
141
|
+
const CLOSABLE_TAGS = [
|
|
142
|
+
{ id: 1, label: "Default", variant: "default" },
|
|
143
|
+
{ id: 2, label: "Secondary", variant: "secondary" },
|
|
144
|
+
{ id: 3, label: "Outline", variant: "outline" },
|
|
145
|
+
{ id: 4, label: "Error", variant: "error" },
|
|
146
|
+
{ id: 5, label: "Ghost", variant: "ghost" },
|
|
147
|
+
] as const;
|
|
148
|
+
|
|
154
149
|
export const Closable: Story = {
|
|
155
|
-
|
|
156
|
-
(
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
150
|
+
render: () => {
|
|
151
|
+
const [visible, setVisible] = useState(CLOSABLE_TAGS.map((t) => t.id));
|
|
152
|
+
|
|
153
|
+
return (
|
|
154
|
+
<div className="flex flex-col gap-4">
|
|
155
|
+
<div className="flex flex-wrap items-center gap-2">
|
|
156
|
+
{CLOSABLE_TAGS.filter((t) => visible.includes(t.id)).map((t) => (
|
|
157
|
+
<Tag key={t.id} variant={t.variant}>
|
|
158
|
+
{t.label}
|
|
159
|
+
<button
|
|
160
|
+
type="button"
|
|
161
|
+
data-icon="inline-end"
|
|
162
|
+
className="cursor-pointer"
|
|
163
|
+
onClick={() =>
|
|
164
|
+
setVisible((prev) => prev.filter((id) => id !== t.id))
|
|
165
|
+
}
|
|
166
|
+
>
|
|
167
|
+
<X className="size-3" />
|
|
168
|
+
</button>
|
|
169
|
+
</Tag>
|
|
170
|
+
))}
|
|
171
|
+
</div>
|
|
172
|
+
{visible.length < CLOSABLE_TAGS.length && (
|
|
173
|
+
<button
|
|
174
|
+
type="button"
|
|
175
|
+
className="text-xs text-muted-foreground underline underline-offset-4 self-start cursor-pointer"
|
|
176
|
+
onClick={() => setVisible(CLOSABLE_TAGS.map((t) => t.id))}
|
|
177
|
+
>
|
|
178
|
+
Reset
|
|
179
|
+
</button>
|
|
180
|
+
)}
|
|
181
|
+
</div>
|
|
182
|
+
);
|
|
169
183
|
},
|
|
170
184
|
};
|
|
185
|
+
|
|
186
|
+
/**
|
|
187
|
+
* Override colors with custom Tailwind classes via `className`.
|
|
188
|
+
* Classes merge with the variant defaults through `cn` (tailwind-merge).
|
|
189
|
+
*/
|
|
190
|
+
export const CustomColors: Story = {
|
|
191
|
+
render: () => (
|
|
192
|
+
<div className="flex flex-wrap items-center gap-2">
|
|
193
|
+
<Tag className="bg-green-50 text-green-700 dark:bg-green-800/40 dark:text-green-200">
|
|
194
|
+
<BadgeCheck data-icon="inline-start" />
|
|
195
|
+
Success
|
|
196
|
+
</Tag>
|
|
197
|
+
<Tag className="bg-amber-50 text-amber-700 dark:bg-amber-800/40 dark:text-amber-200">
|
|
198
|
+
Pending
|
|
199
|
+
</Tag>
|
|
200
|
+
<Tag className="bg-blue-50 text-blue-700 dark:bg-blue-800/40 dark:text-blue-200">
|
|
201
|
+
Info
|
|
202
|
+
</Tag>
|
|
203
|
+
</div>
|
|
204
|
+
),
|
|
205
|
+
};
|