@inui/design-system 0.0.0-stage → 1.22.0
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/README.md +360 -2
- package/dist/components/ui/accordion.d.ts +44 -0
- package/dist/components/ui/accordion.d.ts.map +1 -0
- package/dist/components/ui/accordion.js +86 -0
- package/dist/components/ui/accordion.js.map +1 -0
- package/dist/components/ui/ai-avatar.d.ts +46 -0
- package/dist/components/ui/ai-avatar.d.ts.map +1 -0
- package/dist/components/ui/ai-avatar.js +43 -0
- package/dist/components/ui/ai-avatar.js.map +1 -0
- package/dist/components/ui/ai-label.d.ts +118 -0
- package/dist/components/ui/ai-label.d.ts.map +1 -0
- package/dist/components/ui/ai-label.js +184 -0
- package/dist/components/ui/ai-label.js.map +1 -0
- package/dist/components/ui/ai-sparkle.d.ts +91 -0
- package/dist/components/ui/ai-sparkle.d.ts.map +1 -0
- package/dist/components/ui/ai-sparkle.js +200 -0
- package/dist/components/ui/ai-sparkle.js.map +1 -0
- package/dist/components/ui/alert-dialog.d.ts +79 -0
- package/dist/components/ui/alert-dialog.d.ts.map +1 -0
- package/dist/components/ui/alert-dialog.js +147 -0
- package/dist/components/ui/alert-dialog.js.map +1 -0
- package/dist/components/ui/alert.d.ts +71 -0
- package/dist/components/ui/alert.d.ts.map +1 -0
- package/dist/components/ui/alert.js +108 -0
- package/dist/components/ui/alert.js.map +1 -0
- package/dist/components/ui/aspect-ratio.d.ts +30 -0
- package/dist/components/ui/aspect-ratio.d.ts.map +1 -0
- package/dist/components/ui/aspect-ratio.js +40 -0
- package/dist/components/ui/aspect-ratio.js.map +1 -0
- package/dist/components/ui/attachment.d.ts +74 -0
- package/dist/components/ui/attachment.d.ts.map +1 -0
- package/dist/components/ui/attachment.js +142 -0
- package/dist/components/ui/attachment.js.map +1 -0
- package/dist/components/ui/avatar.d.ts +82 -0
- package/dist/components/ui/avatar.d.ts.map +1 -0
- package/dist/components/ui/avatar.js +123 -0
- package/dist/components/ui/avatar.js.map +1 -0
- package/dist/components/ui/badge.d.ts +130 -0
- package/dist/components/ui/badge.d.ts.map +1 -0
- package/dist/components/ui/badge.js +226 -0
- package/dist/components/ui/badge.js.map +1 -0
- package/dist/components/ui/breadcrumb.d.ts +43 -0
- package/dist/components/ui/breadcrumb.d.ts.map +1 -0
- package/dist/components/ui/breadcrumb.js +98 -0
- package/dist/components/ui/breadcrumb.js.map +1 -0
- package/dist/components/ui/browser-tabs.d.ts +218 -0
- package/dist/components/ui/browser-tabs.d.ts.map +1 -0
- package/dist/components/ui/browser-tabs.js +528 -0
- package/dist/components/ui/browser-tabs.js.map +1 -0
- package/dist/components/ui/bubble.d.ts +80 -0
- package/dist/components/ui/bubble.d.ts.map +1 -0
- package/dist/components/ui/bubble.js +235 -0
- package/dist/components/ui/bubble.js.map +1 -0
- package/dist/components/ui/button-group.d.ts +60 -0
- package/dist/components/ui/button-group.d.ts.map +1 -0
- package/dist/components/ui/button-group.js +89 -0
- package/dist/components/ui/button-group.js.map +1 -0
- package/dist/components/ui/button.d.ts +157 -0
- package/dist/components/ui/button.d.ts.map +1 -0
- package/dist/components/ui/button.js +144 -0
- package/dist/components/ui/button.js.map +1 -0
- package/dist/components/ui/calendar.d.ts +57 -0
- package/dist/components/ui/calendar.d.ts.map +1 -0
- package/dist/components/ui/calendar.js +163 -0
- package/dist/components/ui/calendar.js.map +1 -0
- package/dist/components/ui/card.d.ts +96 -0
- package/dist/components/ui/card.d.ts.map +1 -0
- package/dist/components/ui/card.js +131 -0
- package/dist/components/ui/card.js.map +1 -0
- package/dist/components/ui/carousel.d.ts +86 -0
- package/dist/components/ui/carousel.d.ts.map +1 -0
- package/dist/components/ui/carousel.js +207 -0
- package/dist/components/ui/carousel.js.map +1 -0
- package/dist/components/ui/checkbox.d.ts +54 -0
- package/dist/components/ui/checkbox.d.ts.map +1 -0
- package/dist/components/ui/checkbox.js +78 -0
- package/dist/components/ui/checkbox.js.map +1 -0
- package/dist/components/ui/collapsible.d.ts +45 -0
- package/dist/components/ui/collapsible.d.ts.map +1 -0
- package/dist/components/ui/collapsible.js +65 -0
- package/dist/components/ui/collapsible.js.map +1 -0
- package/dist/components/ui/combobox.d.ts +111 -0
- package/dist/components/ui/combobox.d.ts.map +1 -0
- package/dist/components/ui/combobox.js +264 -0
- package/dist/components/ui/combobox.js.map +1 -0
- package/dist/components/ui/command.d.ts +71 -0
- package/dist/components/ui/command.d.ts.map +1 -0
- package/dist/components/ui/command.js +133 -0
- package/dist/components/ui/command.js.map +1 -0
- package/dist/components/ui/context-menu.d.ts +70 -0
- package/dist/components/ui/context-menu.d.ts.map +1 -0
- package/dist/components/ui/context-menu.js +163 -0
- package/dist/components/ui/context-menu.js.map +1 -0
- package/dist/components/ui/count-badge.d.ts +40 -0
- package/dist/components/ui/count-badge.d.ts.map +1 -0
- package/dist/components/ui/count-badge.js +43 -0
- package/dist/components/ui/count-badge.js.map +1 -0
- package/dist/components/ui/data-table.d.ts +1026 -0
- package/dist/components/ui/data-table.d.ts.map +1 -0
- package/dist/components/ui/data-table.js +3423 -0
- package/dist/components/ui/data-table.js.map +1 -0
- package/dist/components/ui/dialog.d.ts +73 -0
- package/dist/components/ui/dialog.d.ts.map +1 -0
- package/dist/components/ui/dialog.js +145 -0
- package/dist/components/ui/dialog.js.map +1 -0
- package/dist/components/ui/direction.d.ts +35 -0
- package/dist/components/ui/direction.d.ts.map +1 -0
- package/dist/components/ui/direction.js +35 -0
- package/dist/components/ui/direction.js.map +1 -0
- package/dist/components/ui/drawer.d.ts +53 -0
- package/dist/components/ui/drawer.d.ts.map +1 -0
- package/dist/components/ui/drawer.js +115 -0
- package/dist/components/ui/drawer.js.map +1 -0
- package/dist/components/ui/dropdown-menu.d.ts +75 -0
- package/dist/components/ui/dropdown-menu.d.ts.map +1 -0
- package/dist/components/ui/dropdown-menu.js +173 -0
- package/dist/components/ui/dropdown-menu.js.map +1 -0
- package/dist/components/ui/dropzone.d.ts +141 -0
- package/dist/components/ui/dropzone.d.ts.map +1 -0
- package/dist/components/ui/dropzone.js +257 -0
- package/dist/components/ui/dropzone.js.map +1 -0
- package/dist/components/ui/empty.d.ts +94 -0
- package/dist/components/ui/empty.d.ts.map +1 -0
- package/dist/components/ui/empty.js +149 -0
- package/dist/components/ui/empty.js.map +1 -0
- package/dist/components/ui/field.d.ts +122 -0
- package/dist/components/ui/field.d.ts.map +1 -0
- package/dist/components/ui/field.js +254 -0
- package/dist/components/ui/field.js.map +1 -0
- package/dist/components/ui/hover-card.d.ts +51 -0
- package/dist/components/ui/hover-card.d.ts.map +1 -0
- package/dist/components/ui/hover-card.js +101 -0
- package/dist/components/ui/hover-card.js.map +1 -0
- package/dist/components/ui/input-group.d.ts +62 -0
- package/dist/components/ui/input-group.d.ts.map +1 -0
- package/dist/components/ui/input-group.js +115 -0
- package/dist/components/ui/input-group.js.map +1 -0
- package/dist/components/ui/input-otp.d.ts +52 -0
- package/dist/components/ui/input-otp.d.ts.map +1 -0
- package/dist/components/ui/input-otp.js +89 -0
- package/dist/components/ui/input-otp.js.map +1 -0
- package/dist/components/ui/input.d.ts +47 -0
- package/dist/components/ui/input.d.ts.map +1 -0
- package/dist/components/ui/input.js +47 -0
- package/dist/components/ui/input.js.map +1 -0
- package/dist/components/ui/item.d.ts +74 -0
- package/dist/components/ui/item.d.ts.map +1 -0
- package/dist/components/ui/item.js +176 -0
- package/dist/components/ui/item.js.map +1 -0
- package/dist/components/ui/kbd.d.ts +41 -0
- package/dist/components/ui/kbd.d.ts.map +1 -0
- package/dist/components/ui/kbd.js +58 -0
- package/dist/components/ui/kbd.js.map +1 -0
- package/dist/components/ui/key-value-pair.d.ts +56 -0
- package/dist/components/ui/key-value-pair.d.ts.map +1 -0
- package/dist/components/ui/key-value-pair.js +110 -0
- package/dist/components/ui/key-value-pair.js.map +1 -0
- package/dist/components/ui/label.d.ts +83 -0
- package/dist/components/ui/label.d.ts.map +1 -0
- package/dist/components/ui/label.js +85 -0
- package/dist/components/ui/label.js.map +1 -0
- package/dist/components/ui/marker.d.ts +54 -0
- package/dist/components/ui/marker.d.ts.map +1 -0
- package/dist/components/ui/marker.js +79 -0
- package/dist/components/ui/marker.js.map +1 -0
- package/dist/components/ui/menubar.d.ts +72 -0
- package/dist/components/ui/menubar.d.ts.map +1 -0
- package/dist/components/ui/menubar.js +174 -0
- package/dist/components/ui/menubar.js.map +1 -0
- package/dist/components/ui/message-scroller.d.ts +53 -0
- package/dist/components/ui/message-scroller.d.ts.map +1 -0
- package/dist/components/ui/message-scroller.js +95 -0
- package/dist/components/ui/message-scroller.js.map +1 -0
- package/dist/components/ui/message.d.ts +63 -0
- package/dist/components/ui/message.d.ts.map +1 -0
- package/dist/components/ui/message.js +92 -0
- package/dist/components/ui/message.js.map +1 -0
- package/dist/components/ui/meta-list.d.ts +55 -0
- package/dist/components/ui/meta-list.d.ts.map +1 -0
- package/dist/components/ui/meta-list.js +75 -0
- package/dist/components/ui/meta-list.js.map +1 -0
- package/dist/components/ui/native-select.d.ts +51 -0
- package/dist/components/ui/native-select.d.ts.map +1 -0
- package/dist/components/ui/native-select.js +75 -0
- package/dist/components/ui/native-select.js.map +1 -0
- package/dist/components/ui/navigation-menu.d.ts +56 -0
- package/dist/components/ui/navigation-menu.d.ts.map +1 -0
- package/dist/components/ui/navigation-menu.js +116 -0
- package/dist/components/ui/navigation-menu.js.map +1 -0
- package/dist/components/ui/page-header.d.ts +223 -0
- package/dist/components/ui/page-header.d.ts.map +1 -0
- package/dist/components/ui/page-header.js +233 -0
- package/dist/components/ui/page-header.js.map +1 -0
- package/dist/components/ui/pagination.d.ts +68 -0
- package/dist/components/ui/pagination.d.ts.map +1 -0
- package/dist/components/ui/pagination.js +145 -0
- package/dist/components/ui/pagination.js.map +1 -0
- package/dist/components/ui/popover.d.ts +61 -0
- package/dist/components/ui/popover.d.ts.map +1 -0
- package/dist/components/ui/popover.js +144 -0
- package/dist/components/ui/popover.js.map +1 -0
- package/dist/components/ui/progress.d.ts +35 -0
- package/dist/components/ui/progress.d.ts.map +1 -0
- package/dist/components/ui/progress.js +46 -0
- package/dist/components/ui/progress.js.map +1 -0
- package/dist/components/ui/questionnaire.d.ts +92 -0
- package/dist/components/ui/questionnaire.d.ts.map +1 -0
- package/dist/components/ui/questionnaire.js +277 -0
- package/dist/components/ui/questionnaire.js.map +1 -0
- package/dist/components/ui/radio-group.d.ts +50 -0
- package/dist/components/ui/radio-group.d.ts.map +1 -0
- package/dist/components/ui/radio-group.js +65 -0
- package/dist/components/ui/radio-group.js.map +1 -0
- package/dist/components/ui/resizable.d.ts +44 -0
- package/dist/components/ui/resizable.d.ts.map +1 -0
- package/dist/components/ui/resizable.js +73 -0
- package/dist/components/ui/resizable.js.map +1 -0
- package/dist/components/ui/scroll-area.d.ts +55 -0
- package/dist/components/ui/scroll-area.d.ts.map +1 -0
- package/dist/components/ui/scroll-area.js +72 -0
- package/dist/components/ui/scroll-area.js.map +1 -0
- package/dist/components/ui/select.d.ts +274 -0
- package/dist/components/ui/select.d.ts.map +1 -0
- package/dist/components/ui/select.js +609 -0
- package/dist/components/ui/select.js.map +1 -0
- package/dist/components/ui/separator.d.ts +31 -0
- package/dist/components/ui/separator.d.ts.map +1 -0
- package/dist/components/ui/separator.js +38 -0
- package/dist/components/ui/separator.js.map +1 -0
- package/dist/components/ui/sheet.d.ts +59 -0
- package/dist/components/ui/sheet.d.ts.map +1 -0
- package/dist/components/ui/sheet.js +128 -0
- package/dist/components/ui/sheet.js.map +1 -0
- package/dist/components/ui/sidebar.d.ts +166 -0
- package/dist/components/ui/sidebar.d.ts.map +1 -0
- package/dist/components/ui/sidebar.js +512 -0
- package/dist/components/ui/sidebar.js.map +1 -0
- package/dist/components/ui/skeleton.d.ts +35 -0
- package/dist/components/ui/skeleton.d.ts.map +1 -0
- package/dist/components/ui/skeleton.js +46 -0
- package/dist/components/ui/skeleton.js.map +1 -0
- package/dist/components/ui/slider.d.ts +39 -0
- package/dist/components/ui/slider.d.ts.map +1 -0
- package/dist/components/ui/slider.js +75 -0
- package/dist/components/ui/slider.js.map +1 -0
- package/dist/components/ui/sonner.d.ts +56 -0
- package/dist/components/ui/sonner.d.ts.map +1 -0
- package/dist/components/ui/sonner.js +96 -0
- package/dist/components/ui/sonner.js.map +1 -0
- package/dist/components/ui/spinner.d.ts +37 -0
- package/dist/components/ui/spinner.d.ts.map +1 -0
- package/dist/components/ui/spinner.js +51 -0
- package/dist/components/ui/spinner.js.map +1 -0
- package/dist/components/ui/stepper.d.ts +84 -0
- package/dist/components/ui/stepper.d.ts.map +1 -0
- package/dist/components/ui/stepper.js +145 -0
- package/dist/components/ui/stepper.js.map +1 -0
- package/dist/components/ui/switch.d.ts +36 -0
- package/dist/components/ui/switch.d.ts.map +1 -0
- package/dist/components/ui/switch.js +44 -0
- package/dist/components/ui/switch.js.map +1 -0
- package/dist/components/ui/table.d.ts +80 -0
- package/dist/components/ui/table.d.ts.map +1 -0
- package/dist/components/ui/table.js +130 -0
- package/dist/components/ui/table.js.map +1 -0
- package/dist/components/ui/tabs.d.ts +87 -0
- package/dist/components/ui/tabs.d.ts.map +1 -0
- package/dist/components/ui/tabs.js +128 -0
- package/dist/components/ui/tabs.js.map +1 -0
- package/dist/components/ui/textarea.d.ts +35 -0
- package/dist/components/ui/textarea.d.ts.map +1 -0
- package/dist/components/ui/textarea.js +38 -0
- package/dist/components/ui/textarea.js.map +1 -0
- package/dist/components/ui/time-picker.d.ts +58 -0
- package/dist/components/ui/time-picker.d.ts.map +1 -0
- package/dist/components/ui/time-picker.js +188 -0
- package/dist/components/ui/time-picker.js.map +1 -0
- package/dist/components/ui/toggle-group.d.ts +52 -0
- package/dist/components/ui/toggle-group.d.ts.map +1 -0
- package/dist/components/ui/toggle-group.js +94 -0
- package/dist/components/ui/toggle-group.js.map +1 -0
- package/dist/components/ui/toggle.d.ts +50 -0
- package/dist/components/ui/toggle.d.ts.map +1 -0
- package/dist/components/ui/toggle.js +70 -0
- package/dist/components/ui/toggle.js.map +1 -0
- package/dist/components/ui/tooltip.d.ts +51 -0
- package/dist/components/ui/tooltip.d.ts.map +1 -0
- package/dist/components/ui/tooltip.js +78 -0
- package/dist/components/ui/tooltip.js.map +1 -0
- package/dist/hooks/use-dark-mode.d.ts +2 -0
- package/dist/hooks/use-dark-mode.d.ts.map +1 -0
- package/dist/hooks/use-dark-mode.js +36 -0
- package/dist/hooks/use-dark-mode.js.map +1 -0
- package/dist/hooks/use-mobile.d.ts +2 -0
- package/dist/hooks/use-mobile.d.ts.map +1 -0
- package/dist/hooks/use-mobile.js +20 -0
- package/dist/hooks/use-mobile.js.map +1 -0
- package/dist/index.d.ts +88 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +77 -0
- package/dist/lib/scope.d.ts +64 -0
- package/dist/lib/scope.d.ts.map +1 -0
- package/dist/lib/scope.js +74 -0
- package/dist/lib/scope.js.map +1 -0
- package/dist/lib/utils.d.ts +3 -0
- package/dist/lib/utils.d.ts.map +1 -0
- package/dist/lib/utils.js +11 -0
- package/dist/lib/utils.js.map +1 -0
- package/dist/styles.css +2 -0
- package/dist/theme-tokens.css +537 -0
- package/dist/theme.css +417 -0
- package/package.json +103 -3
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { cn } from "../../lib/utils.js";
|
|
3
|
+
import { Tabs, TabsContent, TabsList, TabsTrigger } from "./tabs.js";
|
|
4
|
+
import * as React from "react";
|
|
5
|
+
import { CheckIcon } from "lucide-react";
|
|
6
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
7
|
+
//#region src/components/ui/stepper.tsx
|
|
8
|
+
/**
|
|
9
|
+
* Stepper — a horizontal sequence of named steps with pending/done state.
|
|
10
|
+
*
|
|
11
|
+
* A thin composite over Tabs, not a new primitive: `StepperList`/
|
|
12
|
+
* `StepperTrigger`/`StepperContent` are Tabs' own List/Trigger/Content,
|
|
13
|
+
* restyled — the same Radix Tabs keyboard/roving-focus/panel behavior
|
|
14
|
+
* applies unchanged. `StepperTrigger` adds one thing Tabs doesn't have: a
|
|
15
|
+
* leading step-circle icon (empty for pending, checked for done), using the
|
|
16
|
+
* same `data-icon="inline-start"` slot convention as Tabs' own icon support
|
|
17
|
+
* (see Tabs' "With icons" story) — not a new icon prop shape.
|
|
18
|
+
*/
|
|
19
|
+
var StepperAnnounceContext = React.createContext(null);
|
|
20
|
+
function Stepper({ children, ...props }) {
|
|
21
|
+
const [announcement, setAnnouncement] = React.useState("");
|
|
22
|
+
return /* @__PURE__ */ jsx(StepperAnnounceContext.Provider, {
|
|
23
|
+
value: setAnnouncement,
|
|
24
|
+
children: /* @__PURE__ */ jsxs(Tabs, {
|
|
25
|
+
"data-slot": "stepper",
|
|
26
|
+
...props,
|
|
27
|
+
children: [children, /* @__PURE__ */ jsx("span", {
|
|
28
|
+
role: "status",
|
|
29
|
+
className: "sr-only",
|
|
30
|
+
children: announcement
|
|
31
|
+
})]
|
|
32
|
+
})
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
function StepperList({ ...props }) {
|
|
36
|
+
return /* @__PURE__ */ jsx(TabsList, {
|
|
37
|
+
"data-slot": "stepper-list",
|
|
38
|
+
...props
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
function StepperTrigger({ status = "pending", className, children, ...props }) {
|
|
42
|
+
const announce = React.useContext(StepperAnnounceContext);
|
|
43
|
+
const prevStatusRef = React.useRef(status);
|
|
44
|
+
React.useEffect(() => {
|
|
45
|
+
if (prevStatusRef.current !== "done" && status === "done") announce?.(`${typeof children === "string" ? children : "Step"} done`);
|
|
46
|
+
prevStatusRef.current = status;
|
|
47
|
+
}, [
|
|
48
|
+
status,
|
|
49
|
+
announce,
|
|
50
|
+
children
|
|
51
|
+
]);
|
|
52
|
+
return /* @__PURE__ */ jsxs(TabsTrigger, {
|
|
53
|
+
"data-slot": "stepper-trigger",
|
|
54
|
+
className,
|
|
55
|
+
...props,
|
|
56
|
+
children: [
|
|
57
|
+
/* @__PURE__ */ jsx("span", {
|
|
58
|
+
"aria-hidden": "true",
|
|
59
|
+
"data-icon": "inline-start",
|
|
60
|
+
className: cn("flex size-4 shrink-0 items-center justify-center rounded-full border-2 border-current transition-colors", status === "done" && "border-primary bg-primary text-primary-foreground"),
|
|
61
|
+
children: status === "done" && /* @__PURE__ */ jsx(CheckIcon, {
|
|
62
|
+
className: "size-2.5",
|
|
63
|
+
strokeWidth: 3
|
|
64
|
+
})
|
|
65
|
+
}),
|
|
66
|
+
children,
|
|
67
|
+
status === "done" && /* @__PURE__ */ jsx("span", {
|
|
68
|
+
className: "sr-only",
|
|
69
|
+
children: ", done"
|
|
70
|
+
})
|
|
71
|
+
]
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
function StepperContent({ ...props }) {
|
|
75
|
+
return /* @__PURE__ */ jsx(TabsContent, {
|
|
76
|
+
"data-slot": "stepper-content",
|
|
77
|
+
...props
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* WHEN TO USE
|
|
82
|
+
* - A short, ordered sequence of named steps the user moves through, where
|
|
83
|
+
* each step's completion state matters — account setup, a multi-part
|
|
84
|
+
* form's section nav, an order/shipment progress row.
|
|
85
|
+
*
|
|
86
|
+
* NOT WHEN
|
|
87
|
+
* - The steps are actually a full one-question-at-a-time form flow with its
|
|
88
|
+
* own Previous/Next/Submit navigation — use Questionnaire, which has that
|
|
89
|
+
* built in (its `QuestionnaireProgress` is a plain text label, not this).
|
|
90
|
+
* - The panels are unrelated views with no inherent order or completion
|
|
91
|
+
* state — use plain Tabs.
|
|
92
|
+
* - Showing hierarchical position, not sequence — use Breadcrumb.
|
|
93
|
+
*
|
|
94
|
+
* KEY RULES
|
|
95
|
+
* - It's Tabs underneath: same `value`/`defaultValue`/`onValueChange` on
|
|
96
|
+
* Stepper, same `variant`/`size` on StepperList, same `disabled` per
|
|
97
|
+
* trigger, same `orientation="vertical"` for a side-by-side layout.
|
|
98
|
+
* - `status` on StepperTrigger ("pending" default | "done") is independent
|
|
99
|
+
* of which step is currently active: a step can be active-and-pending
|
|
100
|
+
* (viewing unfinished work) or inactive-and-done (already completed, user
|
|
101
|
+
* has since moved on). A pending circle's outline is `border-current`, so
|
|
102
|
+
* it automatically tracks whatever color TabsTrigger's own hover/active
|
|
103
|
+
* rules put on the trigger's text — muted normally, primary when it's the
|
|
104
|
+
* active step, primary-hover on hover — the same currentColor mechanism a
|
|
105
|
+
* plain lucide icon in Tabs already gets for free, not extra state here.
|
|
106
|
+
* A "done" circle stays a fixed filled primary regardless of hover/active,
|
|
107
|
+
* since completion should read as stable, not reactive to the pointer.
|
|
108
|
+
* - Tracking which steps are "done" is the consumer's own state — Stepper
|
|
109
|
+
* doesn't infer completion from navigation; nothing marks a step done
|
|
110
|
+
* just because the user moved past it.
|
|
111
|
+
* - A step transitioning to `status="done"` is announced via a shared sr-only live region on
|
|
112
|
+
* Stepper itself (not just the trigger's own `, done` text) — the common "finish step N, focus
|
|
113
|
+
* moves to N+1, step N flips to done behind you" flow still reaches screen-reader users.
|
|
114
|
+
* - No connector line between circles — this is triggers-in-a-row, same
|
|
115
|
+
* visual weight as Tabs. Compose one in yourself (an absolutely
|
|
116
|
+
* positioned `border-t` between items) if a specific design calls for it.
|
|
117
|
+
*
|
|
118
|
+
* USAGE
|
|
119
|
+
* <Stepper defaultValue="account">
|
|
120
|
+
* <StepperList>
|
|
121
|
+
* <StepperTrigger value="account" status="done">Account</StepperTrigger>
|
|
122
|
+
* <StepperTrigger value="profile" status="pending">Profile</StepperTrigger>
|
|
123
|
+
* <StepperTrigger value="review" status="pending">Review</StepperTrigger>
|
|
124
|
+
* </StepperList>
|
|
125
|
+
* <StepperContent value="account">...</StepperContent>
|
|
126
|
+
* <StepperContent value="profile">...</StepperContent>
|
|
127
|
+
* <StepperContent value="review">...</StepperContent>
|
|
128
|
+
* </Stepper>
|
|
129
|
+
*
|
|
130
|
+
* // Vertical — StepperList stacks in a column, StepperContent sits beside
|
|
131
|
+
* // it, exactly like Tabs' own orientation="vertical" (no Stepper-specific
|
|
132
|
+
* // layout code involved).
|
|
133
|
+
* <Stepper defaultValue="account" orientation="vertical" className="flex-row gap-6">
|
|
134
|
+
* <StepperList className="flex-col">
|
|
135
|
+
* <StepperTrigger value="account" status="done">Account</StepperTrigger>
|
|
136
|
+
* <StepperTrigger value="profile" status="pending">Profile</StepperTrigger>
|
|
137
|
+
* </StepperList>
|
|
138
|
+
* <StepperContent value="account">...</StepperContent>
|
|
139
|
+
* <StepperContent value="profile">...</StepperContent>
|
|
140
|
+
* </Stepper>
|
|
141
|
+
*/
|
|
142
|
+
//#endregion
|
|
143
|
+
export { Stepper, StepperContent, StepperList, StepperTrigger };
|
|
144
|
+
|
|
145
|
+
//# sourceMappingURL=stepper.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stepper.js","names":[],"sources":["../../../src/components/ui/stepper.tsx"],"sourcesContent":["\"use client\"\n\n/**\n * Stepper — a horizontal sequence of named steps with pending/done state.\n *\n * A thin composite over Tabs, not a new primitive: `StepperList`/\n * `StepperTrigger`/`StepperContent` are Tabs' own List/Trigger/Content,\n * restyled — the same Radix Tabs keyboard/roving-focus/panel behavior\n * applies unchanged. `StepperTrigger` adds one thing Tabs doesn't have: a\n * leading step-circle icon (empty for pending, checked for done), using the\n * same `data-icon=\"inline-start\"` slot convention as Tabs' own icon support\n * (see Tabs' \"With icons\" story) — not a new icon prop shape.\n */\n\nimport * as React from \"react\"\nimport { CheckIcon } from \"lucide-react\"\n\nimport { cn } from \"@/lib/utils\"\nimport { Tabs, TabsList, TabsTrigger, TabsContent } from \"@/components/ui/tabs\"\n\n// A step flipping to \"done\" typically happens while focus has already\n// moved on to the next step (finish step N, advance to N+1) — the `, done`\n// sr-only text on the trigger itself only reaches AT users if they\n// re-navigate back to it. This live region lets StepperTrigger announce\n// the transition from wherever focus actually is.\nconst StepperAnnounceContext = React.createContext<\n ((text: string) => void) | null\n>(null)\n\nfunction Stepper({ children, ...props }: React.ComponentProps<typeof Tabs>) {\n const [announcement, setAnnouncement] = React.useState(\"\")\n return (\n <StepperAnnounceContext.Provider value={setAnnouncement}>\n <Tabs data-slot=\"stepper\" {...props}>\n {children}\n <span role=\"status\" className=\"sr-only\">\n {announcement}\n </span>\n </Tabs>\n </StepperAnnounceContext.Provider>\n )\n}\n\nfunction StepperList({ ...props }: React.ComponentProps<typeof TabsList>) {\n return <TabsList data-slot=\"stepper-list\" {...props} />\n}\n\nfunction StepperTrigger({\n status = \"pending\",\n className,\n children,\n ...props\n}: React.ComponentProps<typeof TabsTrigger> & {\n /** \"pending\" (empty circle, default) | \"done\" (filled circle with a check) — independent of whether this step is the currently active one, which Tabs' own active styling already communicates. */\n status?: \"pending\" | \"done\"\n}) {\n const announce = React.useContext(StepperAnnounceContext)\n // Skip the announcement on mount (a step already \"done\" when the\n // Stepper first renders isn't a state *change*) — only fire when it\n // actually transitions from pending to done while mounted.\n const prevStatusRef = React.useRef(status)\n React.useEffect(() => {\n if (prevStatusRef.current !== \"done\" && status === \"done\") {\n announce?.(\n `${typeof children === \"string\" ? children : \"Step\"} done`\n )\n }\n prevStatusRef.current = status\n }, [status, announce, children])\n\n return (\n <TabsTrigger data-slot=\"stepper-trigger\" className={className} {...props}>\n <span\n aria-hidden=\"true\"\n data-icon=\"inline-start\"\n className={cn(\n // border-current (not a fixed border-muted-foreground) so the\n // circle's outline tracks whatever color TabsTrigger's own\n // hover/data-active rules put on the trigger's text — muted on a\n // plain pending step, primary when it's the active step, and\n // primary-hover on hover — the same currentColor mechanism a\n // plain lucide icon in Tabs already gets for free.\n \"flex size-4 shrink-0 items-center justify-center rounded-full border-2 border-current transition-colors\",\n status === \"done\" && \"border-primary bg-primary text-primary-foreground\"\n )}\n >\n {status === \"done\" && <CheckIcon className=\"size-2.5\" strokeWidth={3} />}\n </span>\n {children}\n {/* The circle icon above is aria-hidden — this is the only thing that\n actually tells assistive tech a step is done, not just color/shape. */}\n {status === \"done\" && <span className=\"sr-only\">, done</span>}\n </TabsTrigger>\n )\n}\n\nfunction StepperContent({ ...props }: React.ComponentProps<typeof TabsContent>) {\n return <TabsContent data-slot=\"stepper-content\" {...props} />\n}\n\nexport { Stepper, StepperList, StepperTrigger, StepperContent }\n\n/**\n * WHEN TO USE\n * - A short, ordered sequence of named steps the user moves through, where\n * each step's completion state matters — account setup, a multi-part\n * form's section nav, an order/shipment progress row.\n *\n * NOT WHEN\n * - The steps are actually a full one-question-at-a-time form flow with its\n * own Previous/Next/Submit navigation — use Questionnaire, which has that\n * built in (its `QuestionnaireProgress` is a plain text label, not this).\n * - The panels are unrelated views with no inherent order or completion\n * state — use plain Tabs.\n * - Showing hierarchical position, not sequence — use Breadcrumb.\n *\n * KEY RULES\n * - It's Tabs underneath: same `value`/`defaultValue`/`onValueChange` on\n * Stepper, same `variant`/`size` on StepperList, same `disabled` per\n * trigger, same `orientation=\"vertical\"` for a side-by-side layout.\n * - `status` on StepperTrigger (\"pending\" default | \"done\") is independent\n * of which step is currently active: a step can be active-and-pending\n * (viewing unfinished work) or inactive-and-done (already completed, user\n * has since moved on). A pending circle's outline is `border-current`, so\n * it automatically tracks whatever color TabsTrigger's own hover/active\n * rules put on the trigger's text — muted normally, primary when it's the\n * active step, primary-hover on hover — the same currentColor mechanism a\n * plain lucide icon in Tabs already gets for free, not extra state here.\n * A \"done\" circle stays a fixed filled primary regardless of hover/active,\n * since completion should read as stable, not reactive to the pointer.\n * - Tracking which steps are \"done\" is the consumer's own state — Stepper\n * doesn't infer completion from navigation; nothing marks a step done\n * just because the user moved past it.\n * - A step transitioning to `status=\"done\"` is announced via a shared sr-only live region on\n * Stepper itself (not just the trigger's own `, done` text) — the common \"finish step N, focus\n * moves to N+1, step N flips to done behind you\" flow still reaches screen-reader users.\n * - No connector line between circles — this is triggers-in-a-row, same\n * visual weight as Tabs. Compose one in yourself (an absolutely\n * positioned `border-t` between items) if a specific design calls for it.\n *\n * USAGE\n * <Stepper defaultValue=\"account\">\n * <StepperList>\n * <StepperTrigger value=\"account\" status=\"done\">Account</StepperTrigger>\n * <StepperTrigger value=\"profile\" status=\"pending\">Profile</StepperTrigger>\n * <StepperTrigger value=\"review\" status=\"pending\">Review</StepperTrigger>\n * </StepperList>\n * <StepperContent value=\"account\">...</StepperContent>\n * <StepperContent value=\"profile\">...</StepperContent>\n * <StepperContent value=\"review\">...</StepperContent>\n * </Stepper>\n *\n * // Vertical — StepperList stacks in a column, StepperContent sits beside\n * // it, exactly like Tabs' own orientation=\"vertical\" (no Stepper-specific\n * // layout code involved).\n * <Stepper defaultValue=\"account\" orientation=\"vertical\" className=\"flex-row gap-6\">\n * <StepperList className=\"flex-col\">\n * <StepperTrigger value=\"account\" status=\"done\">Account</StepperTrigger>\n * <StepperTrigger value=\"profile\" status=\"pending\">Profile</StepperTrigger>\n * </StepperList>\n * <StepperContent value=\"account\">...</StepperContent>\n * <StepperContent value=\"profile\">...</StepperContent>\n * </Stepper>\n */\n"],"mappings":";;;;;;;;;;;;;;;;;;AAyBA,IAAM,yBAAyB,MAAM,cAEnC,IAAI;AAEN,SAAS,QAAQ,EAAE,UAAU,GAAG,SAA4C;CAC1E,MAAM,CAAC,cAAc,mBAAmB,MAAM,SAAS,EAAE;CACzD,OACE,oBAAC,uBAAuB,UAAxB;EAAiC,OAAO;EACtC,UAAA,qBAAC,MAAD;GAAM,aAAU;GAAU,GAAI;GAA9B,UAAA,CACG,UACD,oBAAC,QAAD;IAAM,MAAK;IAAS,WAAU;IAC3B,UAAA;GACG,CAAA,CACF;;CACyB,CAAA;AAErC;AAEA,SAAS,YAAY,EAAE,GAAG,SAAgD;CACxE,OAAO,oBAAC,UAAD;EAAU,aAAU;EAAe,GAAI;CAAQ,CAAA;AACxD;AAEA,SAAS,eAAe,EACtB,SAAS,WACT,WACA,UACA,GAAG,SAIF;CACD,MAAM,WAAW,MAAM,WAAW,sBAAsB;CAIxD,MAAM,gBAAgB,MAAM,OAAO,MAAM;CACzC,MAAM,gBAAgB;EACpB,IAAI,cAAc,YAAY,UAAU,WAAW,QACjD,WACE,GAAG,OAAO,aAAa,WAAW,WAAW,OAAO,MACtD;EAEF,cAAc,UAAU;CAC1B,GAAG;EAAC;EAAQ;EAAU;CAAQ,CAAC;CAE/B,OACE,qBAAC,aAAD;EAAa,aAAU;EAA6B;EAAW,GAAI;EAAnE,UAAA;GACE,oBAAC,QAAD;IACE,eAAY;IACZ,aAAU;IACV,WAAW,GAOT,2GACA,WAAW,UAAU,mDACvB;IAEC,UAAA,WAAW,UAAU,oBAAC,WAAD;KAAW,WAAU;KAAW,aAAa;IAAI,CAAA;GACnE,CAAA;GACL;GAGA,WAAW,UAAU,oBAAC,QAAD;IAAM,WAAU;IAAU,UAAA;GAAY,CAAA;EACjD;;AAEjB;AAEA,SAAS,eAAe,EAAE,GAAG,SAAmD;CAC9E,OAAO,oBAAC,aAAD;EAAa,aAAU;EAAkB,GAAI;CAAQ,CAAA;AAC9D"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Switch — on/off control that applies immediately.
|
|
3
|
+
*
|
|
4
|
+
* Built on the Radix Switch primitive. Adds a `size="sm"` step alongside
|
|
5
|
+
* the default size and drives error styling off `aria-invalid` instead of a
|
|
6
|
+
* prop.
|
|
7
|
+
*/
|
|
8
|
+
import * as React from "react";
|
|
9
|
+
import { Switch as SwitchPrimitive } from "radix-ui";
|
|
10
|
+
declare function Switch({ className, size, ...props }: React.ComponentProps<typeof SwitchPrimitive.Root> & {
|
|
11
|
+
size?: "sm" | "default";
|
|
12
|
+
}): React.JSX.Element;
|
|
13
|
+
export { Switch };
|
|
14
|
+
/**
|
|
15
|
+
* WHEN TO USE
|
|
16
|
+
* - Settings and feature flags that take effect the instant they're flipped, with no
|
|
17
|
+
* separate save/submit step (e.g. "Airplane mode")
|
|
18
|
+
*
|
|
19
|
+
* NOT WHEN
|
|
20
|
+
* - A value that's part of a form and needs explicit submission — use Checkbox
|
|
21
|
+
* - A formatting/state toggle inside a toolbar (e.g. bold, alignment) — use Toggle
|
|
22
|
+
*
|
|
23
|
+
* KEY RULES
|
|
24
|
+
* - size: sm | default (default "default") — sm is a smaller footprint for dense settings rows
|
|
25
|
+
* - Error state is driven entirely by `aria-invalid` — there is no `error` prop
|
|
26
|
+
* - Wrap in a Label so the text is a clickable target and is announced to screen readers
|
|
27
|
+
*
|
|
28
|
+
* USAGE
|
|
29
|
+
* <Label className="flex items-center gap-2">
|
|
30
|
+
* <Switch />
|
|
31
|
+
* Airplane mode
|
|
32
|
+
* </Label>
|
|
33
|
+
*
|
|
34
|
+
* <Switch size="sm" defaultChecked />
|
|
35
|
+
*/
|
|
36
|
+
//# sourceMappingURL=switch.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"switch.d.ts","sourceRoot":"","sources":["../../../src/components/ui/switch.tsx"],"names":[],"mappings":"AAEA;;;;;;GAMG;AAEH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAC9B,OAAO,EAAE,MAAM,IAAI,eAAe,EAAE,MAAM,UAAU,CAAA;AAIpD,iBAAS,MAAM,CAAC,EACd,SAAS,EACT,IAAgB,EAChB,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,eAAe,CAAC,IAAI,CAAC,GAAG;IACrD,IAAI,CAAC,EAAE,IAAI,GAAG,SAAS,CAAA;CACxB,qBAiBA;AAED,OAAO,EAAE,MAAM,EAAE,CAAA;AAEjB;;;;;;;;;;;;;;;;;;;;;GAqBG"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { cn } from "../../lib/utils.js";
|
|
3
|
+
import "react";
|
|
4
|
+
import { Switch as Switch$1 } from "radix-ui";
|
|
5
|
+
import { jsx } from "react/jsx-runtime";
|
|
6
|
+
//#region src/components/ui/switch.tsx
|
|
7
|
+
function Switch({ className, size = "default", ...props }) {
|
|
8
|
+
return /* @__PURE__ */ jsx(Switch$1.Root, {
|
|
9
|
+
"data-slot": "switch",
|
|
10
|
+
"data-size": size,
|
|
11
|
+
className: cn("peer group/switch relative inline-flex shrink-0 items-center rounded-full border border-transparent transition-colors outline-none after:absolute after:-inset-x-3 after:-inset-y-2 focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 data-[size=default]:h-[18.4px] data-[size=default]:w-[32px] data-[size=sm]:h-[14px] data-[size=sm]:w-[24px] dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 data-[state=checked]:bg-primary data-[state=unchecked]:bg-input dark:data-[state=unchecked]:bg-input/80 data-disabled:cursor-not-allowed data-disabled:opacity-50", className),
|
|
12
|
+
...props,
|
|
13
|
+
children: /* @__PURE__ */ jsx(Switch$1.Thumb, {
|
|
14
|
+
"data-slot": "switch-thumb",
|
|
15
|
+
className: "pointer-events-none block rounded-full bg-background ring-0 transition-transform group-data-[size=default]/switch:size-4 group-data-[size=sm]/switch:size-3 group-data-[size=default]/switch:data-[state=checked]:translate-x-[calc(100%-2px)] group-data-[size=sm]/switch:data-[state=checked]:translate-x-[calc(100%-2px)] dark:data-[state=checked]:bg-primary-foreground group-data-[size=default]/switch:data-[state=unchecked]:translate-x-0 group-data-[size=sm]/switch:data-[state=unchecked]:translate-x-0 dark:data-[state=unchecked]:bg-foreground"
|
|
16
|
+
})
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* WHEN TO USE
|
|
21
|
+
* - Settings and feature flags that take effect the instant they're flipped, with no
|
|
22
|
+
* separate save/submit step (e.g. "Airplane mode")
|
|
23
|
+
*
|
|
24
|
+
* NOT WHEN
|
|
25
|
+
* - A value that's part of a form and needs explicit submission — use Checkbox
|
|
26
|
+
* - A formatting/state toggle inside a toolbar (e.g. bold, alignment) — use Toggle
|
|
27
|
+
*
|
|
28
|
+
* KEY RULES
|
|
29
|
+
* - size: sm | default (default "default") — sm is a smaller footprint for dense settings rows
|
|
30
|
+
* - Error state is driven entirely by `aria-invalid` — there is no `error` prop
|
|
31
|
+
* - Wrap in a Label so the text is a clickable target and is announced to screen readers
|
|
32
|
+
*
|
|
33
|
+
* USAGE
|
|
34
|
+
* <Label className="flex items-center gap-2">
|
|
35
|
+
* <Switch />
|
|
36
|
+
* Airplane mode
|
|
37
|
+
* </Label>
|
|
38
|
+
*
|
|
39
|
+
* <Switch size="sm" defaultChecked />
|
|
40
|
+
*/
|
|
41
|
+
//#endregion
|
|
42
|
+
export { Switch };
|
|
43
|
+
|
|
44
|
+
//# sourceMappingURL=switch.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"switch.js","names":[],"sources":["../../../src/components/ui/switch.tsx"],"sourcesContent":["\"use client\"\n\n/**\n * Switch — on/off control that applies immediately.\n *\n * Built on the Radix Switch primitive. Adds a `size=\"sm\"` step alongside\n * the default size and drives error styling off `aria-invalid` instead of a\n * prop.\n */\n\nimport * as React from \"react\"\nimport { Switch as SwitchPrimitive } from \"radix-ui\"\n\nimport { cn } from \"@/lib/utils\"\n\nfunction Switch({\n className,\n size = \"default\",\n ...props\n}: React.ComponentProps<typeof SwitchPrimitive.Root> & {\n size?: \"sm\" | \"default\"\n}) {\n return (\n <SwitchPrimitive.Root\n data-slot=\"switch\"\n data-size={size}\n className={cn(\n \"peer group/switch relative inline-flex shrink-0 items-center rounded-full border border-transparent transition-colors outline-none after:absolute after:-inset-x-3 after:-inset-y-2 focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 data-[size=default]:h-[18.4px] data-[size=default]:w-[32px] data-[size=sm]:h-[14px] data-[size=sm]:w-[24px] dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 data-[state=checked]:bg-primary data-[state=unchecked]:bg-input dark:data-[state=unchecked]:bg-input/80 data-disabled:cursor-not-allowed data-disabled:opacity-50\",\n className\n )}\n {...props}\n >\n <SwitchPrimitive.Thumb\n data-slot=\"switch-thumb\"\n className=\"pointer-events-none block rounded-full bg-background ring-0 transition-transform group-data-[size=default]/switch:size-4 group-data-[size=sm]/switch:size-3 group-data-[size=default]/switch:data-[state=checked]:translate-x-[calc(100%-2px)] group-data-[size=sm]/switch:data-[state=checked]:translate-x-[calc(100%-2px)] dark:data-[state=checked]:bg-primary-foreground group-data-[size=default]/switch:data-[state=unchecked]:translate-x-0 group-data-[size=sm]/switch:data-[state=unchecked]:translate-x-0 dark:data-[state=unchecked]:bg-foreground\"\n />\n </SwitchPrimitive.Root>\n )\n}\n\nexport { Switch }\n\n/**\n * WHEN TO USE\n * - Settings and feature flags that take effect the instant they're flipped, with no\n * separate save/submit step (e.g. \"Airplane mode\")\n *\n * NOT WHEN\n * - A value that's part of a form and needs explicit submission — use Checkbox\n * - A formatting/state toggle inside a toolbar (e.g. bold, alignment) — use Toggle\n *\n * KEY RULES\n * - size: sm | default (default \"default\") — sm is a smaller footprint for dense settings rows\n * - Error state is driven entirely by `aria-invalid` — there is no `error` prop\n * - Wrap in a Label so the text is a clickable target and is announced to screen readers\n *\n * USAGE\n * <Label className=\"flex items-center gap-2\">\n * <Switch />\n * Airplane mode\n * </Label>\n *\n * <Switch size=\"sm\" defaultChecked />\n */\n"],"mappings":";;;;;;AAeA,SAAS,OAAO,EACd,WACA,OAAO,WACP,GAAG,SAGF;CACD,OACE,oBAAC,SAAgB,MAAjB;EACE,aAAU;EACV,aAAW;EACX,WAAW,GACT,krBACA,SACF;EACA,GAAI;EAEJ,UAAA,oBAAC,SAAgB,OAAjB;GACE,aAAU;GACV,WAAU;EACX,CAAA;CACmB,CAAA;AAE1B"}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Table — styled semantic table elements.
|
|
3
|
+
*
|
|
4
|
+
* Plain `<table>`/`<thead>`/`<tbody>`/`<tr>`/`<th>`/`<td>` wrappers.
|
|
5
|
+
* No sorting, filtering, selection, or
|
|
6
|
+
* pagination logic — bring your own state, or a headless table library
|
|
7
|
+
* (e.g. TanStack Table) and render into these primitives.
|
|
8
|
+
*
|
|
9
|
+
* `size` (row density) lives on the outer container as `group/table`;
|
|
10
|
+
* TableHead/TableCell react to it via `group-data-[size=x]/table`, the same
|
|
11
|
+
* prop-drilling-free pattern Attachment/Empty use — no size prop on those
|
|
12
|
+
* two, just set it once on `Table` itself.
|
|
13
|
+
*/
|
|
14
|
+
import * as React from "react";
|
|
15
|
+
import { type VariantProps } from "class-variance-authority";
|
|
16
|
+
declare const tableVariants: (props?: ({
|
|
17
|
+
size?: "sm" | "default" | "xs" | null | undefined;
|
|
18
|
+
} & import("class-variance-authority/types").ClassProp) | undefined) => string;
|
|
19
|
+
declare function Table({ className, size, ...props }: React.ComponentProps<"table"> & VariantProps<typeof tableVariants>): React.JSX.Element;
|
|
20
|
+
declare function TableHeader({ className, ...props }: React.ComponentProps<"thead">): React.JSX.Element;
|
|
21
|
+
declare function TableBody({ className, ...props }: React.ComponentProps<"tbody">): React.JSX.Element;
|
|
22
|
+
declare function TableFooter({ className, ...props }: React.ComponentProps<"tfoot">): React.JSX.Element;
|
|
23
|
+
declare function TableRow({ className, ...props }: React.ComponentProps<"tr">): React.JSX.Element;
|
|
24
|
+
declare function TableHead({ className, ...props }: React.ComponentProps<"th">): React.JSX.Element;
|
|
25
|
+
declare function TableCell({ className, ...props }: React.ComponentProps<"td">): React.JSX.Element;
|
|
26
|
+
declare function TableCaption({ className, ...props }: React.ComponentProps<"caption">): React.JSX.Element;
|
|
27
|
+
export { Table, TableHeader, TableBody, TableFooter, TableHead, TableRow, TableCell, TableCaption, };
|
|
28
|
+
/**
|
|
29
|
+
* WHEN TO USE
|
|
30
|
+
* - Structured tabular data with columns and rows the user compares
|
|
31
|
+
* across — invoices, reports, admin lists with fixed columns.
|
|
32
|
+
*
|
|
33
|
+
* NOT WHEN
|
|
34
|
+
* - An entity list where each row has a primary action and no real
|
|
35
|
+
* column alignment — use Item instead.
|
|
36
|
+
* - Key/value pairs — a two-column layout or definition list reads better.
|
|
37
|
+
* - Hierarchical/nested data — use Accordion.
|
|
38
|
+
*
|
|
39
|
+
* KEY RULES
|
|
40
|
+
* - `Table` already wraps itself in a `relative w-full overflow-x-auto`
|
|
41
|
+
* container — don't add another scroll wrapper around it.
|
|
42
|
+
* - Rows are edge-to-edge by default: `Table` pulls itself out by the
|
|
43
|
+
* nearest `--card-spacing` (Card's own padding token, 0 outside a Card)
|
|
44
|
+
* so row dividers/backgrounds reach the surface's true edge, while
|
|
45
|
+
* `TableHead`/`TableCell` push their first/last-column padding back out
|
|
46
|
+
* by the same amount — cell content still lines up with a `CardTitle`
|
|
47
|
+
* above it, only the divider extends further. This is automatic; there's
|
|
48
|
+
* no prop for it.
|
|
49
|
+
* - `TableRow` highlights via `data-[state=selected]:bg-muted` — drive
|
|
50
|
+
* selection with that data attribute, not a custom className.
|
|
51
|
+
* - No built-in sort/filter/paginate — compose with Pagination and
|
|
52
|
+
* Checkbox (in a `TableHead`/`TableCell` for the selection column)
|
|
53
|
+
* yourself, or drive rows from a headless table library.
|
|
54
|
+
* - `size` on `Table` sets row density: "default" (h-10 head, p-2 cells) |
|
|
55
|
+
* "sm" (h-9 head, tighter vertical cell padding) | "xs" (h-8 head, text-xs,
|
|
56
|
+
* tightest padding) — same default/sm/xs vocabulary as Button/Item/
|
|
57
|
+
* Attachment/Select, not Table-specific naming. Set it once on `Table`;
|
|
58
|
+
* `TableHead`/`TableCell` react to it automatically.
|
|
59
|
+
*
|
|
60
|
+
* USAGE
|
|
61
|
+
* <Table>
|
|
62
|
+
* <TableCaption>A list of your recent invoices.</TableCaption>
|
|
63
|
+
* <TableHeader>
|
|
64
|
+
* <TableRow>
|
|
65
|
+
* <TableHead>Invoice</TableHead>
|
|
66
|
+
* <TableHead className="text-right">Amount</TableHead>
|
|
67
|
+
* </TableRow>
|
|
68
|
+
* </TableHeader>
|
|
69
|
+
* <TableBody>
|
|
70
|
+
* <TableRow>
|
|
71
|
+
* <TableCell className="font-medium">INV001</TableCell>
|
|
72
|
+
* <TableCell className="text-right">$250.00</TableCell>
|
|
73
|
+
* </TableRow>
|
|
74
|
+
* </TableBody>
|
|
75
|
+
* </Table>
|
|
76
|
+
*
|
|
77
|
+
* // Denser row height for a data-heavy admin grid
|
|
78
|
+
* <Table size="xs">...</Table>
|
|
79
|
+
*/
|
|
80
|
+
//# sourceMappingURL=table.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"table.d.ts","sourceRoot":"","sources":["../../../src/components/ui/table.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAC9B,OAAO,EAAO,KAAK,YAAY,EAAE,MAAM,0BAA0B,CAAA;AAIjE,QAAA,MAAM,aAAa;;8EAWjB,CAAA;AAEF,iBAAS,KAAK,CAAC,EACb,SAAS,EACT,IAAgB,EAChB,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,CAAC,GAAG,YAAY,CAAC,OAAO,aAAa,CAAC,qBAqBpE;AAED,iBAAS,WAAW,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,CAAC,qBAQ1E;AAED,iBAAS,SAAS,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,CAAC,qBAQxE;AAED,iBAAS,WAAW,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,CAAC,qBAW1E;AAED,iBAAS,QAAQ,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,KAAK,CAAC,cAAc,CAAC,IAAI,CAAC,qBAiBpE;AAED,iBAAS,SAAS,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,KAAK,CAAC,cAAc,CAAC,IAAI,CAAC,qBAYrE;AAED,iBAAS,SAAS,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,KAAK,CAAC,cAAc,CAAC,IAAI,CAAC,qBAYrE;AAED,iBAAS,YAAY,CAAC,EACpB,SAAS,EACT,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,SAAS,CAAC,qBAQjC;AAED,OAAO,EACL,KAAK,EACL,WAAW,EACX,SAAS,EACT,WAAW,EACX,SAAS,EACT,QAAQ,EACR,SAAS,EACT,YAAY,GACb,CAAA;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmDG"}
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
import { cn } from "../../lib/utils.js";
|
|
2
|
+
import "react";
|
|
3
|
+
import { jsx } from "react/jsx-runtime";
|
|
4
|
+
import { cva } from "class-variance-authority";
|
|
5
|
+
//#region src/components/ui/table.tsx
|
|
6
|
+
var tableVariants = cva("w-full caption-bottom", {
|
|
7
|
+
variants: { size: {
|
|
8
|
+
default: "text-sm",
|
|
9
|
+
sm: "text-sm",
|
|
10
|
+
xs: "text-xs"
|
|
11
|
+
} },
|
|
12
|
+
defaultVariants: { size: "default" }
|
|
13
|
+
});
|
|
14
|
+
function Table({ className, size = "default", ...props }) {
|
|
15
|
+
return /* @__PURE__ */ jsx("div", {
|
|
16
|
+
"data-slot": "table-container",
|
|
17
|
+
"data-size": size,
|
|
18
|
+
className: "group/table relative -mx-(--card-spacing,0px) w-[calc(100%+var(--card-spacing,0px)*2)] overflow-x-auto",
|
|
19
|
+
children: /* @__PURE__ */ jsx("table", {
|
|
20
|
+
"data-slot": "table",
|
|
21
|
+
className: cn(tableVariants({ size }), className),
|
|
22
|
+
...props
|
|
23
|
+
})
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
function TableHeader({ className, ...props }) {
|
|
27
|
+
return /* @__PURE__ */ jsx("thead", {
|
|
28
|
+
"data-slot": "table-header",
|
|
29
|
+
className: cn("[&_tr]:border-b", className),
|
|
30
|
+
...props
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
function TableBody({ className, ...props }) {
|
|
34
|
+
return /* @__PURE__ */ jsx("tbody", {
|
|
35
|
+
"data-slot": "table-body",
|
|
36
|
+
className: cn("[&_tr:last-child]:border-0", className),
|
|
37
|
+
...props
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
function TableFooter({ className, ...props }) {
|
|
41
|
+
return /* @__PURE__ */ jsx("tfoot", {
|
|
42
|
+
"data-slot": "table-footer",
|
|
43
|
+
className: cn("border-t bg-muted/50 font-medium [&>tr]:last:border-b-0", className),
|
|
44
|
+
...props
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
function TableRow({ className, ...props }) {
|
|
48
|
+
return /* @__PURE__ */ jsx("tr", {
|
|
49
|
+
"data-slot": "table-row",
|
|
50
|
+
className: cn("group/row border-b transition-colors hover:bg-muted/50 has-aria-expanded:bg-muted/50 data-[state=selected]:bg-muted", className),
|
|
51
|
+
...props
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
function TableHead({ className, ...props }) {
|
|
55
|
+
return /* @__PURE__ */ jsx("th", {
|
|
56
|
+
"data-slot": "table-head",
|
|
57
|
+
className: cn("h-10 px-2 text-left align-middle font-medium whitespace-nowrap text-foreground first:pl-(--card-spacing,--spacing(2)) last:pr-(--card-spacing,--spacing(2)) [&:has([role=checkbox])]:pr-0", "group-data-[size=sm]/table:h-9 group-data-[size=xs]/table:h-8 group-data-[size=xs]/table:px-1.5", className),
|
|
58
|
+
...props
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
function TableCell({ className, ...props }) {
|
|
62
|
+
return /* @__PURE__ */ jsx("td", {
|
|
63
|
+
"data-slot": "table-cell",
|
|
64
|
+
className: cn("p-2 align-middle whitespace-nowrap first:pl-(--card-spacing,--spacing(2)) last:pr-(--card-spacing,--spacing(2)) [&:has([role=checkbox])]:pr-0", "group-data-[size=sm]/table:py-1.5 group-data-[size=xs]/table:px-1.5 group-data-[size=xs]/table:py-1", className),
|
|
65
|
+
...props
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
function TableCaption({ className, ...props }) {
|
|
69
|
+
return /* @__PURE__ */ jsx("caption", {
|
|
70
|
+
"data-slot": "table-caption",
|
|
71
|
+
className: cn("mt-4 text-sm text-muted-foreground", className),
|
|
72
|
+
...props
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* WHEN TO USE
|
|
77
|
+
* - Structured tabular data with columns and rows the user compares
|
|
78
|
+
* across — invoices, reports, admin lists with fixed columns.
|
|
79
|
+
*
|
|
80
|
+
* NOT WHEN
|
|
81
|
+
* - An entity list where each row has a primary action and no real
|
|
82
|
+
* column alignment — use Item instead.
|
|
83
|
+
* - Key/value pairs — a two-column layout or definition list reads better.
|
|
84
|
+
* - Hierarchical/nested data — use Accordion.
|
|
85
|
+
*
|
|
86
|
+
* KEY RULES
|
|
87
|
+
* - `Table` already wraps itself in a `relative w-full overflow-x-auto`
|
|
88
|
+
* container — don't add another scroll wrapper around it.
|
|
89
|
+
* - Rows are edge-to-edge by default: `Table` pulls itself out by the
|
|
90
|
+
* nearest `--card-spacing` (Card's own padding token, 0 outside a Card)
|
|
91
|
+
* so row dividers/backgrounds reach the surface's true edge, while
|
|
92
|
+
* `TableHead`/`TableCell` push their first/last-column padding back out
|
|
93
|
+
* by the same amount — cell content still lines up with a `CardTitle`
|
|
94
|
+
* above it, only the divider extends further. This is automatic; there's
|
|
95
|
+
* no prop for it.
|
|
96
|
+
* - `TableRow` highlights via `data-[state=selected]:bg-muted` — drive
|
|
97
|
+
* selection with that data attribute, not a custom className.
|
|
98
|
+
* - No built-in sort/filter/paginate — compose with Pagination and
|
|
99
|
+
* Checkbox (in a `TableHead`/`TableCell` for the selection column)
|
|
100
|
+
* yourself, or drive rows from a headless table library.
|
|
101
|
+
* - `size` on `Table` sets row density: "default" (h-10 head, p-2 cells) |
|
|
102
|
+
* "sm" (h-9 head, tighter vertical cell padding) | "xs" (h-8 head, text-xs,
|
|
103
|
+
* tightest padding) — same default/sm/xs vocabulary as Button/Item/
|
|
104
|
+
* Attachment/Select, not Table-specific naming. Set it once on `Table`;
|
|
105
|
+
* `TableHead`/`TableCell` react to it automatically.
|
|
106
|
+
*
|
|
107
|
+
* USAGE
|
|
108
|
+
* <Table>
|
|
109
|
+
* <TableCaption>A list of your recent invoices.</TableCaption>
|
|
110
|
+
* <TableHeader>
|
|
111
|
+
* <TableRow>
|
|
112
|
+
* <TableHead>Invoice</TableHead>
|
|
113
|
+
* <TableHead className="text-right">Amount</TableHead>
|
|
114
|
+
* </TableRow>
|
|
115
|
+
* </TableHeader>
|
|
116
|
+
* <TableBody>
|
|
117
|
+
* <TableRow>
|
|
118
|
+
* <TableCell className="font-medium">INV001</TableCell>
|
|
119
|
+
* <TableCell className="text-right">$250.00</TableCell>
|
|
120
|
+
* </TableRow>
|
|
121
|
+
* </TableBody>
|
|
122
|
+
* </Table>
|
|
123
|
+
*
|
|
124
|
+
* // Denser row height for a data-heavy admin grid
|
|
125
|
+
* <Table size="xs">...</Table>
|
|
126
|
+
*/
|
|
127
|
+
//#endregion
|
|
128
|
+
export { Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, TableRow };
|
|
129
|
+
|
|
130
|
+
//# sourceMappingURL=table.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"table.js","names":[],"sources":["../../../src/components/ui/table.tsx"],"sourcesContent":["/**\n * Table — styled semantic table elements.\n *\n * Plain `<table>`/`<thead>`/`<tbody>`/`<tr>`/`<th>`/`<td>` wrappers.\n * No sorting, filtering, selection, or\n * pagination logic — bring your own state, or a headless table library\n * (e.g. TanStack Table) and render into these primitives.\n *\n * `size` (row density) lives on the outer container as `group/table`;\n * TableHead/TableCell react to it via `group-data-[size=x]/table`, the same\n * prop-drilling-free pattern Attachment/Empty use — no size prop on those\n * two, just set it once on `Table` itself.\n */\n\nimport * as React from \"react\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\n\nimport { cn } from \"@/lib/utils\"\n\nconst tableVariants = cva(\"w-full caption-bottom\", {\n variants: {\n size: {\n default: \"text-sm\",\n sm: \"text-sm\",\n xs: \"text-xs\",\n },\n },\n defaultVariants: {\n size: \"default\",\n },\n})\n\nfunction Table({\n className,\n size = \"default\",\n ...props\n}: React.ComponentProps<\"table\"> & VariantProps<typeof tableVariants>) {\n return (\n <div\n data-slot=\"table-container\"\n data-size={size}\n // Edge-to-edge by default: the table always sits on some surface\n // (almost always a Card), so it pulls itself out by that surface's\n // own --card-spacing (falls back to 0 outside a Card, i.e. no-op) so\n // row dividers/backgrounds reach the surface's true edge, while\n // TableHead/TableCell push their own first/last-column padding back\n // out by the same amount — content still lines up with a CardTitle\n // above it, only the divider extends further.\n className=\"group/table relative -mx-(--card-spacing,0px) w-[calc(100%+var(--card-spacing,0px)*2)] overflow-x-auto\"\n >\n <table\n data-slot=\"table\"\n className={cn(tableVariants({ size }), className)}\n {...props}\n />\n </div>\n )\n}\n\nfunction TableHeader({ className, ...props }: React.ComponentProps<\"thead\">) {\n return (\n <thead\n data-slot=\"table-header\"\n className={cn(\"[&_tr]:border-b\", className)}\n {...props}\n />\n )\n}\n\nfunction TableBody({ className, ...props }: React.ComponentProps<\"tbody\">) {\n return (\n <tbody\n data-slot=\"table-body\"\n className={cn(\"[&_tr:last-child]:border-0\", className)}\n {...props}\n />\n )\n}\n\nfunction TableFooter({ className, ...props }: React.ComponentProps<\"tfoot\">) {\n return (\n <tfoot\n data-slot=\"table-footer\"\n className={cn(\n \"border-t bg-muted/50 font-medium [&>tr]:last:border-b-0\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction TableRow({ className, ...props }: React.ComponentProps<\"tr\">) {\n return (\n <tr\n data-slot=\"table-row\"\n className={cn(\n // `group/row` — an opaque pinned cell (DataTable's own\n // `getPinnedClassName`) sits on top of this row's own\n // hover/selected tint and would otherwise hide it for that one\n // column; that pinned cell reacts to this row's hover/selected\n // state directly via `group-hover/row`/`group-data-[state=selected]/row`\n // instead of relying on the tint showing through underneath it.\n \"group/row border-b transition-colors hover:bg-muted/50 has-aria-expanded:bg-muted/50 data-[state=selected]:bg-muted\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction TableHead({ className, ...props }: React.ComponentProps<\"th\">) {\n return (\n <th\n data-slot=\"table-head\"\n className={cn(\n \"h-10 px-2 text-left align-middle font-medium whitespace-nowrap text-foreground first:pl-(--card-spacing,--spacing(2)) last:pr-(--card-spacing,--spacing(2)) [&:has([role=checkbox])]:pr-0\",\n \"group-data-[size=sm]/table:h-9 group-data-[size=xs]/table:h-8 group-data-[size=xs]/table:px-1.5\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction TableCell({ className, ...props }: React.ComponentProps<\"td\">) {\n return (\n <td\n data-slot=\"table-cell\"\n className={cn(\n \"p-2 align-middle whitespace-nowrap first:pl-(--card-spacing,--spacing(2)) last:pr-(--card-spacing,--spacing(2)) [&:has([role=checkbox])]:pr-0\",\n \"group-data-[size=sm]/table:py-1.5 group-data-[size=xs]/table:px-1.5 group-data-[size=xs]/table:py-1\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction TableCaption({\n className,\n ...props\n}: React.ComponentProps<\"caption\">) {\n return (\n <caption\n data-slot=\"table-caption\"\n className={cn(\"mt-4 text-sm text-muted-foreground\", className)}\n {...props}\n />\n )\n}\n\nexport {\n Table,\n TableHeader,\n TableBody,\n TableFooter,\n TableHead,\n TableRow,\n TableCell,\n TableCaption,\n}\n\n/**\n * WHEN TO USE\n * - Structured tabular data with columns and rows the user compares\n * across — invoices, reports, admin lists with fixed columns.\n *\n * NOT WHEN\n * - An entity list where each row has a primary action and no real\n * column alignment — use Item instead.\n * - Key/value pairs — a two-column layout or definition list reads better.\n * - Hierarchical/nested data — use Accordion.\n *\n * KEY RULES\n * - `Table` already wraps itself in a `relative w-full overflow-x-auto`\n * container — don't add another scroll wrapper around it.\n * - Rows are edge-to-edge by default: `Table` pulls itself out by the\n * nearest `--card-spacing` (Card's own padding token, 0 outside a Card)\n * so row dividers/backgrounds reach the surface's true edge, while\n * `TableHead`/`TableCell` push their first/last-column padding back out\n * by the same amount — cell content still lines up with a `CardTitle`\n * above it, only the divider extends further. This is automatic; there's\n * no prop for it.\n * - `TableRow` highlights via `data-[state=selected]:bg-muted` — drive\n * selection with that data attribute, not a custom className.\n * - No built-in sort/filter/paginate — compose with Pagination and\n * Checkbox (in a `TableHead`/`TableCell` for the selection column)\n * yourself, or drive rows from a headless table library.\n * - `size` on `Table` sets row density: \"default\" (h-10 head, p-2 cells) |\n * \"sm\" (h-9 head, tighter vertical cell padding) | \"xs\" (h-8 head, text-xs,\n * tightest padding) — same default/sm/xs vocabulary as Button/Item/\n * Attachment/Select, not Table-specific naming. Set it once on `Table`;\n * `TableHead`/`TableCell` react to it automatically.\n *\n * USAGE\n * <Table>\n * <TableCaption>A list of your recent invoices.</TableCaption>\n * <TableHeader>\n * <TableRow>\n * <TableHead>Invoice</TableHead>\n * <TableHead className=\"text-right\">Amount</TableHead>\n * </TableRow>\n * </TableHeader>\n * <TableBody>\n * <TableRow>\n * <TableCell className=\"font-medium\">INV001</TableCell>\n * <TableCell className=\"text-right\">$250.00</TableCell>\n * </TableRow>\n * </TableBody>\n * </Table>\n *\n * // Denser row height for a data-heavy admin grid\n * <Table size=\"xs\">...</Table>\n */\n"],"mappings":";;;;;AAmBA,IAAM,gBAAgB,IAAI,yBAAyB;CACjD,UAAU,EACR,MAAM;EACJ,SAAS;EACT,IAAI;EACJ,IAAI;CACN,EACF;CACA,iBAAiB,EACf,MAAM,UACR;AACF,CAAC;AAED,SAAS,MAAM,EACb,WACA,OAAO,WACP,GAAG,SACkE;CACrE,OACE,oBAAC,OAAD;EACE,aAAU;EACV,aAAW;EAQX,WAAU;EAEV,UAAA,oBAAC,SAAD;GACE,aAAU;GACV,WAAW,GAAG,cAAc,EAAE,KAAK,CAAC,GAAG,SAAS;GAChD,GAAI;EACL,CAAA;CACE,CAAA;AAET;AAEA,SAAS,YAAY,EAAE,WAAW,GAAG,SAAwC;CAC3E,OACE,oBAAC,SAAD;EACE,aAAU;EACV,WAAW,GAAG,mBAAmB,SAAS;EAC1C,GAAI;CACL,CAAA;AAEL;AAEA,SAAS,UAAU,EAAE,WAAW,GAAG,SAAwC;CACzE,OACE,oBAAC,SAAD;EACE,aAAU;EACV,WAAW,GAAG,8BAA8B,SAAS;EACrD,GAAI;CACL,CAAA;AAEL;AAEA,SAAS,YAAY,EAAE,WAAW,GAAG,SAAwC;CAC3E,OACE,oBAAC,SAAD;EACE,aAAU;EACV,WAAW,GACT,2DACA,SACF;EACA,GAAI;CACL,CAAA;AAEL;AAEA,SAAS,SAAS,EAAE,WAAW,GAAG,SAAqC;CACrE,OACE,oBAAC,MAAD;EACE,aAAU;EACV,WAAW,GAOT,uHACA,SACF;EACA,GAAI;CACL,CAAA;AAEL;AAEA,SAAS,UAAU,EAAE,WAAW,GAAG,SAAqC;CACtE,OACE,oBAAC,MAAD;EACE,aAAU;EACV,WAAW,GACT,6LACA,mGACA,SACF;EACA,GAAI;CACL,CAAA;AAEL;AAEA,SAAS,UAAU,EAAE,WAAW,GAAG,SAAqC;CACtE,OACE,oBAAC,MAAD;EACE,aAAU;EACV,WAAW,GACT,iJACA,uGACA,SACF;EACA,GAAI;CACL,CAAA;AAEL;AAEA,SAAS,aAAa,EACpB,WACA,GAAG,SAC+B;CAClC,OACE,oBAAC,WAAD;EACE,aAAU;EACV,WAAW,GAAG,sCAAsC,SAAS;EAC7D,GAAI;CACL,CAAA;AAEL"}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tabs — switches between panels of the same content area.
|
|
3
|
+
*
|
|
4
|
+
* Radix Tabs primitive with two TabsList visual variants: "default" (pill
|
|
5
|
+
* background, active tab gets a raised background) and "line" (transparent
|
|
6
|
+
* background, active tab gets an underline).
|
|
7
|
+
*/
|
|
8
|
+
import * as React from "react";
|
|
9
|
+
import { type VariantProps } from "class-variance-authority";
|
|
10
|
+
import { Tabs as TabsPrimitive } from "radix-ui";
|
|
11
|
+
declare function Tabs({ className, orientation, ...props }: React.ComponentProps<typeof TabsPrimitive.Root>): React.JSX.Element;
|
|
12
|
+
declare const tabsListVariants: (props?: ({
|
|
13
|
+
variant?: "line" | "default" | null | undefined;
|
|
14
|
+
size?: "sm" | "default" | null | undefined;
|
|
15
|
+
} & import("class-variance-authority/types").ClassProp) | undefined) => string;
|
|
16
|
+
declare function TabsList({ className, variant, size, ...props }: React.ComponentProps<typeof TabsPrimitive.List> & VariantProps<typeof tabsListVariants>): React.JSX.Element;
|
|
17
|
+
declare function TabsTrigger({ className, ...props }: React.ComponentProps<typeof TabsPrimitive.Trigger>): React.JSX.Element;
|
|
18
|
+
declare function TabsContent({ className, ...props }: React.ComponentProps<typeof TabsPrimitive.Content>): React.JSX.Element;
|
|
19
|
+
export { Tabs, TabsList, TabsTrigger, TabsContent, tabsListVariants };
|
|
20
|
+
/**
|
|
21
|
+
* WHEN TO USE
|
|
22
|
+
* - Switching between 2–6 named views of the same entity (e.g. a record's
|
|
23
|
+
* Overview / History / Notes)
|
|
24
|
+
* - orientation="vertical" for a side-by-side settings-style layout
|
|
25
|
+
*
|
|
26
|
+
* NOT WHEN
|
|
27
|
+
* - Top-level app navigation — use NavigationMenu
|
|
28
|
+
* - An ordered sequence where each step has its own pending/done state —
|
|
29
|
+
* use Stepper, which is Tabs plus a step-circle icon
|
|
30
|
+
* - A one-question-at-a-time form flow with its own Previous/Next/Submit —
|
|
31
|
+
* use Questionnaire
|
|
32
|
+
* - Showing hierarchical position — use Breadcrumb
|
|
33
|
+
*
|
|
34
|
+
* KEY RULES
|
|
35
|
+
* - TabsList variant: "default" (transparent track, default) | "line"
|
|
36
|
+
* (underline, also transparent) — set once on TabsList, not per trigger
|
|
37
|
+
* - Both variants read the active tab as primary, not neutral: "default" gets a
|
|
38
|
+
* subtle bg-primary/10 fill + text-primary (translucent, so it blends on any
|
|
39
|
+
* surface with no per-container overrides needed); "line" gets text-primary
|
|
40
|
+
* plus a bg-primary underline, no fill (there's no track to fill)
|
|
41
|
+
* - Hover, inactive tab: "default" gets a bg-muted fill + darker text; "line"
|
|
42
|
+
* doesn't change text at all — it reveals a bg-border underline instead,
|
|
43
|
+
* a plain hover affordance, not a color change
|
|
44
|
+
* - Hover, active tab: "default"'s fill doesn't change, only its text darkens
|
|
45
|
+
* to text-primary-hover; "line" darkens BOTH its text and its underline to
|
|
46
|
+
* text-primary-hover/bg-primary-hover — hovering the current tab still
|
|
47
|
+
* reads as "this one, more so," not a neutral hover state
|
|
48
|
+
* - A leading icon on a trigger uses the same `data-icon="inline-start"` slot
|
|
49
|
+
* convention as Button/Toggle/SelectTrigger — no separate icon prop; the
|
|
50
|
+
* trigger's own padding adjusts automatically once that attribute is present
|
|
51
|
+
* - Individual TabsTrigger can be `disabled`
|
|
52
|
+
* - orientation defaults to "horizontal"; vertical stacks TabsList in a column
|
|
53
|
+
* - TabsList size: "default" (h-8 track, text-sm triggers) | "sm" (h-7,
|
|
54
|
+
* text-xs, tighter gap/padding) — same default/sm vocabulary as Button/
|
|
55
|
+
* Item/Attachment/Select, not Tabs-specific naming. Set once on TabsList;
|
|
56
|
+
* TabsTrigger reacts to it automatically.
|
|
57
|
+
* - A count next to a label (e.g. "Inbox 12") is a plain `Badge` child, same
|
|
58
|
+
* `gap-1.5` slot the leading-icon convention above already uses — no
|
|
59
|
+
* dedicated count prop. Badge's own static color reads fine against both
|
|
60
|
+
* the active and inactive tab state as-is.
|
|
61
|
+
*
|
|
62
|
+
* USAGE
|
|
63
|
+
* <Tabs defaultValue="overview">
|
|
64
|
+
* <TabsList>
|
|
65
|
+
* <TabsTrigger value="overview">Overview</TabsTrigger>
|
|
66
|
+
* <TabsTrigger value="history">History</TabsTrigger>
|
|
67
|
+
* </TabsList>
|
|
68
|
+
* <TabsContent value="overview">...</TabsContent>
|
|
69
|
+
* <TabsContent value="history">...</TabsContent>
|
|
70
|
+
* </Tabs>
|
|
71
|
+
*
|
|
72
|
+
* <TabsList size="sm">
|
|
73
|
+
* <TabsTrigger value="a">A</TabsTrigger>
|
|
74
|
+
* <TabsTrigger value="b">B</TabsTrigger>
|
|
75
|
+
* </TabsList>
|
|
76
|
+
*
|
|
77
|
+
* <TabsList variant="line">
|
|
78
|
+
* <TabsTrigger value="a">A</TabsTrigger>
|
|
79
|
+
* <TabsTrigger value="b" disabled>B</TabsTrigger>
|
|
80
|
+
* </TabsList>
|
|
81
|
+
*
|
|
82
|
+
* <TabsTrigger value="overview">
|
|
83
|
+
* <LayoutGridIcon data-icon="inline-start" />
|
|
84
|
+
* Overview
|
|
85
|
+
* </TabsTrigger>
|
|
86
|
+
*/
|
|
87
|
+
//# sourceMappingURL=tabs.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tabs.d.ts","sourceRoot":"","sources":["../../../src/components/ui/tabs.tsx"],"names":[],"mappings":"AAEA;;;;;;GAMG;AAEH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAC9B,OAAO,EAAO,KAAK,YAAY,EAAE,MAAM,0BAA0B,CAAA;AACjE,OAAO,EAAE,IAAI,IAAI,aAAa,EAAE,MAAM,UAAU,CAAA;AAIhD,iBAAS,IAAI,CAAC,EACZ,SAAS,EACT,WAA0B,EAC1B,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,aAAa,CAAC,IAAI,CAAC,qBAYjD;AAED,QAAA,MAAM,gBAAgB;;;8EAkBrB,CAAA;AAED,iBAAS,QAAQ,CAAC,EAChB,SAAS,EACT,OAAmB,EACnB,IAAgB,EAChB,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,aAAa,CAAC,IAAI,CAAC,GAChD,YAAY,CAAC,OAAO,gBAAgB,CAAC,qBAUtC;AAED,iBAAS,WAAW,CAAC,EACnB,SAAS,EACT,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,aAAa,CAAC,OAAO,CAAC,qBAiBpD;AAED,iBAAS,WAAW,CAAC,EACnB,SAAS,EACT,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,aAAa,CAAC,OAAO,CAAC,qBAWpD;AAED,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,WAAW,EAAE,gBAAgB,EAAE,CAAA;AAErE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkEG"}
|