@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,144 @@
|
|
|
1
|
+
import { cn } from "../../lib/utils.js";
|
|
2
|
+
import { getPortalContainer } from "../../lib/scope.js";
|
|
3
|
+
import * as React from "react";
|
|
4
|
+
import { Popover as Popover$1 } from "radix-ui";
|
|
5
|
+
import { jsx } from "react/jsx-runtime";
|
|
6
|
+
//#region src/components/ui/popover.tsx
|
|
7
|
+
/**
|
|
8
|
+
* Popover — floating panel anchored to a trigger, opened by click.
|
|
9
|
+
*
|
|
10
|
+
* Built on the Radix Popover primitive. Adds PopoverHeader/PopoverTitle/
|
|
11
|
+
* PopoverDescription slots, matching the Header/Title/Description pattern
|
|
12
|
+
* used across this overlay family (Sheet, AlertDialog, Drawer).
|
|
13
|
+
*/
|
|
14
|
+
var PopoverIdContext = React.createContext(null);
|
|
15
|
+
function Popover({ ...props }) {
|
|
16
|
+
const [titleId, setTitleId] = React.useState(null);
|
|
17
|
+
const [descriptionId, setDescriptionId] = React.useState(null);
|
|
18
|
+
const idContext = React.useMemo(() => ({
|
|
19
|
+
titleId,
|
|
20
|
+
setTitleId,
|
|
21
|
+
descriptionId,
|
|
22
|
+
setDescriptionId
|
|
23
|
+
}), [titleId, descriptionId]);
|
|
24
|
+
return /* @__PURE__ */ jsx(PopoverIdContext.Provider, {
|
|
25
|
+
value: idContext,
|
|
26
|
+
children: /* @__PURE__ */ jsx(Popover$1.Root, {
|
|
27
|
+
"data-slot": "popover",
|
|
28
|
+
...props
|
|
29
|
+
})
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
function PopoverTrigger({ ...props }) {
|
|
33
|
+
return /* @__PURE__ */ jsx(Popover$1.Trigger, {
|
|
34
|
+
"data-slot": "popover-trigger",
|
|
35
|
+
...props
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
function PopoverContent({ className, align = "center", sideOffset = 4, "aria-labelledby": ariaLabelledby, "aria-describedby": ariaDescribedby, ...props }) {
|
|
39
|
+
const idContext = React.useContext(PopoverIdContext);
|
|
40
|
+
const resolvedLabelledby = ariaLabelledby ?? (!props["aria-label"] ? idContext?.titleId ?? void 0 : void 0);
|
|
41
|
+
const resolvedDescribedby = ariaDescribedby ?? idContext?.descriptionId ?? void 0;
|
|
42
|
+
return /* @__PURE__ */ jsx(Popover$1.Portal, {
|
|
43
|
+
container: getPortalContainer(),
|
|
44
|
+
children: /* @__PURE__ */ jsx(Popover$1.Content, {
|
|
45
|
+
"data-slot": "popover-content",
|
|
46
|
+
align,
|
|
47
|
+
sideOffset,
|
|
48
|
+
"aria-labelledby": resolvedLabelledby,
|
|
49
|
+
"aria-describedby": resolvedDescribedby,
|
|
50
|
+
className: cn("z-50 flex w-72 origin-(--radix-popover-content-transform-origin) flex-col gap-2.5 rounded-lg bg-popover p-2.5 text-sm text-popover-foreground shadow-popover ring-1 ring-foreground/10 outline-hidden duration-100 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95", className),
|
|
51
|
+
...props
|
|
52
|
+
})
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
function PopoverAnchor({ ...props }) {
|
|
56
|
+
return /* @__PURE__ */ jsx(Popover$1.Anchor, {
|
|
57
|
+
"data-slot": "popover-anchor",
|
|
58
|
+
...props
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
function PopoverHeader({ className, ...props }) {
|
|
62
|
+
return /* @__PURE__ */ jsx("div", {
|
|
63
|
+
"data-slot": "popover-header",
|
|
64
|
+
className: cn("flex flex-col gap-0.5 text-sm", className),
|
|
65
|
+
...props
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
function PopoverTitle({ className, id, ...props }) {
|
|
69
|
+
const generatedId = React.useId();
|
|
70
|
+
const titleId = id ?? generatedId;
|
|
71
|
+
const idContext = React.useContext(PopoverIdContext);
|
|
72
|
+
React.useLayoutEffect(() => {
|
|
73
|
+
idContext?.setTitleId(titleId);
|
|
74
|
+
return () => idContext?.setTitleId(null);
|
|
75
|
+
}, [titleId]);
|
|
76
|
+
return /* @__PURE__ */ jsx("div", {
|
|
77
|
+
"data-slot": "popover-title",
|
|
78
|
+
id: titleId,
|
|
79
|
+
className: cn("font-medium", className),
|
|
80
|
+
...props
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
function PopoverDescription({ className, id, ...props }) {
|
|
84
|
+
const generatedId = React.useId();
|
|
85
|
+
const descriptionId = id ?? generatedId;
|
|
86
|
+
const idContext = React.useContext(PopoverIdContext);
|
|
87
|
+
React.useLayoutEffect(() => {
|
|
88
|
+
idContext?.setDescriptionId(descriptionId);
|
|
89
|
+
return () => idContext?.setDescriptionId(null);
|
|
90
|
+
}, [descriptionId]);
|
|
91
|
+
return /* @__PURE__ */ jsx("p", {
|
|
92
|
+
"data-slot": "popover-description",
|
|
93
|
+
id: descriptionId,
|
|
94
|
+
className: cn("text-muted-foreground", className),
|
|
95
|
+
...props
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* WHEN TO USE
|
|
100
|
+
* - Controls or detail anchored to an element that the user opts into by
|
|
101
|
+
* clicking — date pickers, filter forms, quick-edit panels
|
|
102
|
+
* - Content that's interactive (inputs, buttons) but doesn't need full
|
|
103
|
+
* modal focus-trapping
|
|
104
|
+
*
|
|
105
|
+
* NOT WHEN
|
|
106
|
+
* - A plain, non-interactive hover label — use Tooltip
|
|
107
|
+
* - A richer hover-triggered preview with no click required — use HoverCard
|
|
108
|
+
* - The interaction must interrupt the page and trap focus — use Dialog
|
|
109
|
+
*
|
|
110
|
+
* KEY RULES
|
|
111
|
+
* - Opens on click via PopoverTrigger, not hover — this is the trigger
|
|
112
|
+
* mechanism that separates it from Tooltip/HoverCard
|
|
113
|
+
* - `align` defaults to "center", `sideOffset` defaults to 4
|
|
114
|
+
* - PopoverContent is 18rem (w-72) wide by default; override via className
|
|
115
|
+
* - PopoverAnchor lets you anchor the content to a different element than
|
|
116
|
+
* the trigger (e.g. anchor to an input while triggering from a button)
|
|
117
|
+
* - PopoverContent's `role="dialog"` picks up `aria-labelledby`/`aria-describedby` automatically
|
|
118
|
+
* from PopoverTitle/PopoverDescription rendered anywhere inside the same Popover — pass an
|
|
119
|
+
* explicit `aria-label`/`aria-labelledby` yourself only to override that default
|
|
120
|
+
*
|
|
121
|
+
* USAGE
|
|
122
|
+
* <Popover>
|
|
123
|
+
* <PopoverTrigger asChild><Button variant="outline">Open popover</Button></PopoverTrigger>
|
|
124
|
+
* <PopoverContent className="w-72">
|
|
125
|
+
* <PopoverHeader>
|
|
126
|
+
* <PopoverTitle>Dimensions</PopoverTitle>
|
|
127
|
+
* <PopoverDescription>Set the layout dimensions.</PopoverDescription>
|
|
128
|
+
* </PopoverHeader>
|
|
129
|
+
* <div className="grid gap-3">
|
|
130
|
+
* <div className="grid gap-2">
|
|
131
|
+
* <Label htmlFor="width">Width</Label>
|
|
132
|
+
* <Input id="width" defaultValue="100%" />
|
|
133
|
+
* </div>
|
|
134
|
+
* </div>
|
|
135
|
+
* </PopoverContent>
|
|
136
|
+
* </Popover>
|
|
137
|
+
*
|
|
138
|
+
* // Placement
|
|
139
|
+
* <PopoverContent side="right">Anchored right.</PopoverContent>
|
|
140
|
+
*/
|
|
141
|
+
//#endregion
|
|
142
|
+
export { Popover, PopoverAnchor, PopoverContent, PopoverDescription, PopoverHeader, PopoverTitle, PopoverTrigger };
|
|
143
|
+
|
|
144
|
+
//# sourceMappingURL=popover.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"popover.js","names":[],"sources":["../../../src/components/ui/popover.tsx"],"sourcesContent":["/**\n * Popover — floating panel anchored to a trigger, opened by click.\n *\n * Built on the Radix Popover primitive. Adds PopoverHeader/PopoverTitle/\n * PopoverDescription slots, matching the Header/Title/Description pattern\n * used across this overlay family (Sheet, AlertDialog, Drawer).\n */\nimport * as React from \"react\"\nimport { Popover as PopoverPrimitive } from \"radix-ui\"\n\nimport { cn } from \"@/lib/utils\"\nimport { getPortalContainer } from \"@/lib/scope\"\n\n// Radix's Popover (unlike Dialog) has no Title/Description parts or\n// context of its own — PopoverTitle/PopoverDescription are plain MMDS\n// slots with no id-wiring by default, so PopoverContent's role=\"dialog\"\n// would otherwise ship with no accessible name/description even when a\n// consumer follows the documented Header/Title/Description pattern.\nconst PopoverIdContext = React.createContext<{\n titleId: string | null\n setTitleId: (id: string | null) => void\n descriptionId: string | null\n setDescriptionId: (id: string | null) => void\n} | null>(null)\n\nfunction Popover({\n ...props\n}: React.ComponentProps<typeof PopoverPrimitive.Root>) {\n const [titleId, setTitleId] = React.useState<string | null>(null)\n const [descriptionId, setDescriptionId] = React.useState<string | null>(\n null\n )\n const idContext = React.useMemo(\n () => ({ titleId, setTitleId, descriptionId, setDescriptionId }),\n [titleId, descriptionId]\n )\n\n return (\n <PopoverIdContext.Provider value={idContext}>\n <PopoverPrimitive.Root data-slot=\"popover\" {...props} />\n </PopoverIdContext.Provider>\n )\n}\n\nfunction PopoverTrigger({\n ...props\n}: React.ComponentProps<typeof PopoverPrimitive.Trigger>) {\n return <PopoverPrimitive.Trigger data-slot=\"popover-trigger\" {...props} />\n}\n\nfunction PopoverContent({\n className,\n align = \"center\",\n sideOffset = 4,\n \"aria-labelledby\": ariaLabelledby,\n \"aria-describedby\": ariaDescribedby,\n ...props\n}: React.ComponentProps<typeof PopoverPrimitive.Content>) {\n const idContext = React.useContext(PopoverIdContext)\n const resolvedLabelledby =\n ariaLabelledby ??\n (!props[\"aria-label\"] ? idContext?.titleId ?? undefined : undefined)\n const resolvedDescribedby = ariaDescribedby ?? idContext?.descriptionId ?? undefined\n\n return (\n <PopoverPrimitive.Portal container={getPortalContainer()}>\n <PopoverPrimitive.Content\n data-slot=\"popover-content\"\n align={align}\n sideOffset={sideOffset}\n aria-labelledby={resolvedLabelledby}\n aria-describedby={resolvedDescribedby}\n className={cn(\n \"z-50 flex w-72 origin-(--radix-popover-content-transform-origin) flex-col gap-2.5 rounded-lg bg-popover p-2.5 text-sm text-popover-foreground shadow-popover ring-1 ring-foreground/10 outline-hidden duration-100 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95\",\n className\n )}\n {...props}\n />\n </PopoverPrimitive.Portal>\n )\n}\n\nfunction PopoverAnchor({\n ...props\n}: React.ComponentProps<typeof PopoverPrimitive.Anchor>) {\n return <PopoverPrimitive.Anchor data-slot=\"popover-anchor\" {...props} />\n}\n\nfunction PopoverHeader({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"popover-header\"\n className={cn(\"flex flex-col gap-0.5 text-sm\", className)}\n {...props}\n />\n )\n}\n\nfunction PopoverTitle({\n className,\n id,\n ...props\n}: React.ComponentProps<\"h2\">) {\n const generatedId = React.useId()\n const titleId = id ?? generatedId\n const idContext = React.useContext(PopoverIdContext)\n\n React.useLayoutEffect(() => {\n idContext?.setTitleId(titleId)\n return () => idContext?.setTitleId(null)\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [titleId])\n\n return (\n <div\n data-slot=\"popover-title\"\n id={titleId}\n className={cn(\"font-medium\", className)}\n {...props}\n />\n )\n}\n\nfunction PopoverDescription({\n className,\n id,\n ...props\n}: React.ComponentProps<\"p\">) {\n const generatedId = React.useId()\n const descriptionId = id ?? generatedId\n const idContext = React.useContext(PopoverIdContext)\n\n React.useLayoutEffect(() => {\n idContext?.setDescriptionId(descriptionId)\n return () => idContext?.setDescriptionId(null)\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [descriptionId])\n\n return (\n <p\n data-slot=\"popover-description\"\n id={descriptionId}\n className={cn(\"text-muted-foreground\", className)}\n {...props}\n />\n )\n}\n\nexport {\n Popover,\n PopoverAnchor,\n PopoverContent,\n PopoverDescription,\n PopoverHeader,\n PopoverTitle,\n PopoverTrigger,\n}\n\n/**\n * WHEN TO USE\n * - Controls or detail anchored to an element that the user opts into by\n * clicking — date pickers, filter forms, quick-edit panels\n * - Content that's interactive (inputs, buttons) but doesn't need full\n * modal focus-trapping\n *\n * NOT WHEN\n * - A plain, non-interactive hover label — use Tooltip\n * - A richer hover-triggered preview with no click required — use HoverCard\n * - The interaction must interrupt the page and trap focus — use Dialog\n *\n * KEY RULES\n * - Opens on click via PopoverTrigger, not hover — this is the trigger\n * mechanism that separates it from Tooltip/HoverCard\n * - `align` defaults to \"center\", `sideOffset` defaults to 4\n * - PopoverContent is 18rem (w-72) wide by default; override via className\n * - PopoverAnchor lets you anchor the content to a different element than\n * the trigger (e.g. anchor to an input while triggering from a button)\n * - PopoverContent's `role=\"dialog\"` picks up `aria-labelledby`/`aria-describedby` automatically\n * from PopoverTitle/PopoverDescription rendered anywhere inside the same Popover — pass an\n * explicit `aria-label`/`aria-labelledby` yourself only to override that default\n *\n * USAGE\n * <Popover>\n * <PopoverTrigger asChild><Button variant=\"outline\">Open popover</Button></PopoverTrigger>\n * <PopoverContent className=\"w-72\">\n * <PopoverHeader>\n * <PopoverTitle>Dimensions</PopoverTitle>\n * <PopoverDescription>Set the layout dimensions.</PopoverDescription>\n * </PopoverHeader>\n * <div className=\"grid gap-3\">\n * <div className=\"grid gap-2\">\n * <Label htmlFor=\"width\">Width</Label>\n * <Input id=\"width\" defaultValue=\"100%\" />\n * </div>\n * </div>\n * </PopoverContent>\n * </Popover>\n *\n * // Placement\n * <PopoverContent side=\"right\">Anchored right.</PopoverContent>\n */\n"],"mappings":";;;;;;;;;;;;;AAkBA,IAAM,mBAAmB,MAAM,cAKrB,IAAI;AAEd,SAAS,QAAQ,EACf,GAAG,SACkD;CACrD,MAAM,CAAC,SAAS,cAAc,MAAM,SAAwB,IAAI;CAChE,MAAM,CAAC,eAAe,oBAAoB,MAAM,SAC9C,IACF;CACA,MAAM,YAAY,MAAM,eACf;EAAE;EAAS;EAAY;EAAe;CAAiB,IAC9D,CAAC,SAAS,aAAa,CACzB;CAEA,OACE,oBAAC,iBAAiB,UAAlB;EAA2B,OAAO;EAChC,UAAA,oBAAC,UAAiB,MAAlB;GAAuB,aAAU;GAAU,GAAI;EAAQ,CAAA;CAC9B,CAAA;AAE/B;AAEA,SAAS,eAAe,EACtB,GAAG,SACqD;CACxD,OAAO,oBAAC,UAAiB,SAAlB;EAA0B,aAAU;EAAkB,GAAI;CAAQ,CAAA;AAC3E;AAEA,SAAS,eAAe,EACtB,WACA,QAAQ,UACR,aAAa,GACb,mBAAmB,gBACnB,oBAAoB,iBACpB,GAAG,SACqD;CACxD,MAAM,YAAY,MAAM,WAAW,gBAAgB;CACnD,MAAM,qBACJ,mBACC,CAAC,MAAM,gBAAgB,WAAW,WAAW,KAAA,IAAY,KAAA;CAC5D,MAAM,sBAAsB,mBAAmB,WAAW,iBAAiB,KAAA;CAE3E,OACE,oBAAC,UAAiB,QAAlB;EAAyB,WAAW,mBAAmB;EACrD,UAAA,oBAAC,UAAiB,SAAlB;GACE,aAAU;GACH;GACK;GACZ,mBAAiB;GACjB,oBAAkB;GAClB,WAAW,GACT,uiBACA,SACF;GACA,GAAI;EACL,CAAA;CACsB,CAAA;AAE7B;AAEA,SAAS,cAAc,EACrB,GAAG,SACoD;CACvD,OAAO,oBAAC,UAAiB,QAAlB;EAAyB,aAAU;EAAiB,GAAI;CAAQ,CAAA;AACzE;AAEA,SAAS,cAAc,EAAE,WAAW,GAAG,SAAsC;CAC3E,OACE,oBAAC,OAAD;EACE,aAAU;EACV,WAAW,GAAG,iCAAiC,SAAS;EACxD,GAAI;CACL,CAAA;AAEL;AAEA,SAAS,aAAa,EACpB,WACA,IACA,GAAG,SAC0B;CAC7B,MAAM,cAAc,MAAM,MAAM;CAChC,MAAM,UAAU,MAAM;CACtB,MAAM,YAAY,MAAM,WAAW,gBAAgB;CAEnD,MAAM,sBAAsB;EAC1B,WAAW,WAAW,OAAO;EAC7B,aAAa,WAAW,WAAW,IAAI;CAEzC,GAAG,CAAC,OAAO,CAAC;CAEZ,OACE,oBAAC,OAAD;EACE,aAAU;EACV,IAAI;EACJ,WAAW,GAAG,eAAe,SAAS;EACtC,GAAI;CACL,CAAA;AAEL;AAEA,SAAS,mBAAmB,EAC1B,WACA,IACA,GAAG,SACyB;CAC5B,MAAM,cAAc,MAAM,MAAM;CAChC,MAAM,gBAAgB,MAAM;CAC5B,MAAM,YAAY,MAAM,WAAW,gBAAgB;CAEnD,MAAM,sBAAsB;EAC1B,WAAW,iBAAiB,aAAa;EACzC,aAAa,WAAW,iBAAiB,IAAI;CAE/C,GAAG,CAAC,aAAa,CAAC;CAElB,OACE,oBAAC,KAAD;EACE,aAAU;EACV,IAAI;EACJ,WAAW,GAAG,yBAAyB,SAAS;EAChD,GAAI;CACL,CAAA;AAEL"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Progress — determinate horizontal bar showing measurable task completion.
|
|
3
|
+
*
|
|
4
|
+
* Fill width is driven by a `translateX` transform computed from `value`.
|
|
5
|
+
* Built on the Radix Progress primitive with a single-element shape (just
|
|
6
|
+
* Root + Indicator, no separate Track/Label/Value parts).
|
|
7
|
+
*/
|
|
8
|
+
import * as React from "react";
|
|
9
|
+
import { Progress as ProgressPrimitive } from "radix-ui";
|
|
10
|
+
declare function Progress({ className, value, "aria-label": ariaLabel, ...props }: React.ComponentProps<typeof ProgressPrimitive.Root>): React.JSX.Element;
|
|
11
|
+
export { Progress };
|
|
12
|
+
/**
|
|
13
|
+
* WHEN TO USE
|
|
14
|
+
* - Showing measurable completion with a known percentage — upload progress, quota consumed, goal progress.
|
|
15
|
+
* - Any case where `value` (0–100) changes over time or is set once from a known total.
|
|
16
|
+
*
|
|
17
|
+
* NOT WHEN
|
|
18
|
+
* - Duration is unknown or indeterminate — use Spinner (inline) or Skeleton (whole region) instead.
|
|
19
|
+
* - Showing step position in a multi-step flow — use a dedicated stepper/questionnaire progress indicator instead.
|
|
20
|
+
*
|
|
21
|
+
* KEY RULES
|
|
22
|
+
* - `value` is a plain number 0–100; there is no built-in clamping, so pass values already within range.
|
|
23
|
+
* - Omitting `value` renders the bar at 0% (indicator fully translated out of view) — it does not show an indeterminate/animated state.
|
|
24
|
+
* - Track height (`h-1`) and full-rounding are set by the component; only override via `className` if the design truly requires a different scale.
|
|
25
|
+
* - Always pass `aria-label` describing what's progressing (e.g. "Upload progress") — the
|
|
26
|
+
* underlying `role="progressbar"` has no accessible name of its own otherwise.
|
|
27
|
+
*
|
|
28
|
+
* USAGE
|
|
29
|
+
* <Progress value={60} aria-label="Upload progress" />
|
|
30
|
+
*
|
|
31
|
+
* // Animated / polling progress
|
|
32
|
+
* const [value, setValue] = React.useState(10)
|
|
33
|
+
* <Progress value={value} />
|
|
34
|
+
*/
|
|
35
|
+
//# sourceMappingURL=progress.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"progress.d.ts","sourceRoot":"","sources":["../../../src/components/ui/progress.tsx"],"names":[],"mappings":"AAEA;;;;;;GAMG;AAEH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAC9B,OAAO,EAAE,QAAQ,IAAI,iBAAiB,EAAE,MAAM,UAAU,CAAA;AAIxD,iBAAS,QAAQ,CAAC,EAChB,SAAS,EACT,KAAK,EACL,YAAY,EAAE,SAAS,EACvB,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,iBAAiB,CAAC,IAAI,CAAC,qBAqBrD;AAED,OAAO,EAAE,QAAQ,EAAE,CAAA;AAEnB;;;;;;;;;;;;;;;;;;;;;;GAsBG"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { cn } from "../../lib/utils.js";
|
|
3
|
+
import "react";
|
|
4
|
+
import { Progress as Progress$1 } from "radix-ui";
|
|
5
|
+
import { jsx } from "react/jsx-runtime";
|
|
6
|
+
//#region src/components/ui/progress.tsx
|
|
7
|
+
function Progress({ className, value, "aria-label": ariaLabel, ...props }) {
|
|
8
|
+
return /* @__PURE__ */ jsx(Progress$1.Root, {
|
|
9
|
+
"data-slot": "progress",
|
|
10
|
+
"aria-label": ariaLabel ?? "Progress",
|
|
11
|
+
className: cn("relative flex h-1 w-full items-center overflow-x-hidden rounded-full bg-muted", className),
|
|
12
|
+
...props,
|
|
13
|
+
children: /* @__PURE__ */ jsx(Progress$1.Indicator, {
|
|
14
|
+
"data-slot": "progress-indicator",
|
|
15
|
+
className: "size-full flex-1 bg-primary transition-transform",
|
|
16
|
+
style: { transform: `translateX(-${100 - (value || 0)}%)` }
|
|
17
|
+
})
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* WHEN TO USE
|
|
22
|
+
* - Showing measurable completion with a known percentage — upload progress, quota consumed, goal progress.
|
|
23
|
+
* - Any case where `value` (0–100) changes over time or is set once from a known total.
|
|
24
|
+
*
|
|
25
|
+
* NOT WHEN
|
|
26
|
+
* - Duration is unknown or indeterminate — use Spinner (inline) or Skeleton (whole region) instead.
|
|
27
|
+
* - Showing step position in a multi-step flow — use a dedicated stepper/questionnaire progress indicator instead.
|
|
28
|
+
*
|
|
29
|
+
* KEY RULES
|
|
30
|
+
* - `value` is a plain number 0–100; there is no built-in clamping, so pass values already within range.
|
|
31
|
+
* - Omitting `value` renders the bar at 0% (indicator fully translated out of view) — it does not show an indeterminate/animated state.
|
|
32
|
+
* - Track height (`h-1`) and full-rounding are set by the component; only override via `className` if the design truly requires a different scale.
|
|
33
|
+
* - Always pass `aria-label` describing what's progressing (e.g. "Upload progress") — the
|
|
34
|
+
* underlying `role="progressbar"` has no accessible name of its own otherwise.
|
|
35
|
+
*
|
|
36
|
+
* USAGE
|
|
37
|
+
* <Progress value={60} aria-label="Upload progress" />
|
|
38
|
+
*
|
|
39
|
+
* // Animated / polling progress
|
|
40
|
+
* const [value, setValue] = React.useState(10)
|
|
41
|
+
* <Progress value={value} />
|
|
42
|
+
*/
|
|
43
|
+
//#endregion
|
|
44
|
+
export { Progress };
|
|
45
|
+
|
|
46
|
+
//# sourceMappingURL=progress.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"progress.js","names":[],"sources":["../../../src/components/ui/progress.tsx"],"sourcesContent":["\"use client\"\n\n/**\n * Progress — determinate horizontal bar showing measurable task completion.\n *\n * Fill width is driven by a `translateX` transform computed from `value`.\n * Built on the Radix Progress primitive with a single-element shape (just\n * Root + Indicator, no separate Track/Label/Value parts).\n */\n\nimport * as React from \"react\"\nimport { Progress as ProgressPrimitive } from \"radix-ui\"\n\nimport { cn } from \"@/lib/utils\"\n\nfunction Progress({\n className,\n value,\n \"aria-label\": ariaLabel,\n ...props\n}: React.ComponentProps<typeof ProgressPrimitive.Root>) {\n return (\n <ProgressPrimitive.Root\n data-slot=\"progress\"\n // Falls back to a generic accessible name when the consumer forgets\n // one — `role=\"progressbar\"` has no accessible name otherwise (4.1.2).\n // Prefer passing a real one describing what's progressing.\n aria-label={ariaLabel ?? \"Progress\"}\n className={cn(\n \"relative flex h-1 w-full items-center overflow-x-hidden rounded-full bg-muted\",\n className\n )}\n {...props}\n >\n <ProgressPrimitive.Indicator\n data-slot=\"progress-indicator\"\n className=\"size-full flex-1 bg-primary transition-transform\"\n style={{ transform: `translateX(-${100 - (value || 0)}%)` }}\n />\n </ProgressPrimitive.Root>\n )\n}\n\nexport { Progress }\n\n/**\n * WHEN TO USE\n * - Showing measurable completion with a known percentage — upload progress, quota consumed, goal progress.\n * - Any case where `value` (0–100) changes over time or is set once from a known total.\n *\n * NOT WHEN\n * - Duration is unknown or indeterminate — use Spinner (inline) or Skeleton (whole region) instead.\n * - Showing step position in a multi-step flow — use a dedicated stepper/questionnaire progress indicator instead.\n *\n * KEY RULES\n * - `value` is a plain number 0–100; there is no built-in clamping, so pass values already within range.\n * - Omitting `value` renders the bar at 0% (indicator fully translated out of view) — it does not show an indeterminate/animated state.\n * - Track height (`h-1`) and full-rounding are set by the component; only override via `className` if the design truly requires a different scale.\n * - Always pass `aria-label` describing what's progressing (e.g. \"Upload progress\") — the\n * underlying `role=\"progressbar\"` has no accessible name of its own otherwise.\n *\n * USAGE\n * <Progress value={60} aria-label=\"Upload progress\" />\n *\n * // Animated / polling progress\n * const [value, setValue] = React.useState(10)\n * <Progress value={value} />\n */\n"],"mappings":";;;;;;AAeA,SAAS,SAAS,EAChB,WACA,OACA,cAAc,WACd,GAAG,SACmD;CACtD,OACE,oBAAC,WAAkB,MAAnB;EACE,aAAU;EAIV,cAAY,aAAa;EACzB,WAAW,GACT,iFACA,SACF;EACA,GAAI;EAEJ,UAAA,oBAAC,WAAkB,WAAnB;GACE,aAAU;GACV,WAAU;GACV,OAAO,EAAE,WAAW,eAAe,OAAO,SAAS,GAAG,IAAI;EAC3D,CAAA;CACqB,CAAA;AAE5B"}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Questionnaire — multi-step form that shows one question at a time.
|
|
3
|
+
*
|
|
4
|
+
* Wraps the `@shadcn/react` Questionnaire primitive (Root, Item, Choice,
|
|
5
|
+
* Input, Previous/Skip/Next/Submit), which handles step sequencing,
|
|
6
|
+
* navigation, and validation; the root renders a <form> that tracks the
|
|
7
|
+
* active item. MMDS styles choices as bordered, checkbox/radio-style cards
|
|
8
|
+
* and lays out Previous/Skip/Next/Submit in a fixed 3-column grid.
|
|
9
|
+
*/
|
|
10
|
+
import * as React from "react";
|
|
11
|
+
import { Questionnaire as QuestionnairePrimitive } from "@shadcn/react/questionnaire";
|
|
12
|
+
import { type Button } from "../../components/ui/button";
|
|
13
|
+
declare function Questionnaire({ className, ...props }: React.ComponentProps<typeof QuestionnairePrimitive.Root>): React.JSX.Element;
|
|
14
|
+
declare function QuestionnaireProgress({ className, ...props }: React.ComponentProps<typeof QuestionnairePrimitive.Progress>): React.JSX.Element;
|
|
15
|
+
declare function QuestionnaireItem({ className, ...props }: React.ComponentProps<typeof QuestionnairePrimitive.Item>): React.JSX.Element;
|
|
16
|
+
declare function QuestionnaireTitle({ className, id, ...props }: React.ComponentProps<typeof QuestionnairePrimitive.Title>): React.JSX.Element;
|
|
17
|
+
declare function QuestionnaireDescription({ className, id, ...props }: React.ComponentProps<typeof QuestionnairePrimitive.Description>): React.JSX.Element;
|
|
18
|
+
declare function QuestionnaireChoices({ className, ...props }: React.ComponentProps<typeof QuestionnairePrimitive.Choices>): React.JSX.Element;
|
|
19
|
+
declare function QuestionnaireChoice({ children, className, ...props }: React.ComponentProps<typeof QuestionnairePrimitive.Choice>): React.JSX.Element;
|
|
20
|
+
declare function QuestionnaireChoiceDescription({ className, ...props }: React.ComponentProps<"span">): React.JSX.Element;
|
|
21
|
+
declare function QuestionnaireInput({ className, "aria-labelledby": ariaLabelledby, "aria-describedby": ariaDescribedby, ...props }: React.ComponentProps<typeof QuestionnairePrimitive.Input>): React.JSX.Element;
|
|
22
|
+
declare function QuestionnaireError({ className, ...props }: React.ComponentProps<typeof QuestionnairePrimitive.Error>): React.JSX.Element;
|
|
23
|
+
declare function QuestionnaireActions({ className, ...props }: React.ComponentProps<"div">): React.JSX.Element;
|
|
24
|
+
declare function QuestionnairePrevious({ children, className, size, variant, ...props }: React.ComponentProps<typeof QuestionnairePrimitive.Previous> & Pick<React.ComponentProps<typeof Button>, "size" | "variant">): React.JSX.Element;
|
|
25
|
+
declare function QuestionnaireSkip({ children, className, size, variant, ...props }: React.ComponentProps<typeof QuestionnairePrimitive.Skip> & Pick<React.ComponentProps<typeof Button>, "size" | "variant">): React.JSX.Element;
|
|
26
|
+
declare function QuestionnaireNext({ children, className, size, variant, ...props }: React.ComponentProps<typeof QuestionnairePrimitive.Next> & Pick<React.ComponentProps<typeof Button>, "size" | "variant">): React.JSX.Element;
|
|
27
|
+
declare function QuestionnaireSubmit({ children, className, size, variant, ...props }: React.ComponentProps<typeof QuestionnairePrimitive.Submit> & Pick<React.ComponentProps<typeof Button>, "size" | "variant">): React.JSX.Element;
|
|
28
|
+
export { Questionnaire, QuestionnaireActions, QuestionnaireChoice, QuestionnaireChoiceDescription, QuestionnaireChoices, QuestionnaireDescription, QuestionnaireError, QuestionnaireInput, QuestionnaireItem, QuestionnaireNext, QuestionnairePrevious, QuestionnaireProgress, QuestionnaireSkip, QuestionnaireSubmit, QuestionnaireTitle, };
|
|
29
|
+
/**
|
|
30
|
+
* WHEN TO USE
|
|
31
|
+
* - Guided multi-step intake, onboarding, or surveys where only one question is shown at a time.
|
|
32
|
+
* - Flows that need per-step required/skip logic and a progress indicator.
|
|
33
|
+
*
|
|
34
|
+
* NOT WHEN
|
|
35
|
+
* - All fields should be visible at once in a single form — use Field + FieldSet instead.
|
|
36
|
+
* - Sections don't need to be shown in sequence — use Tabs instead.
|
|
37
|
+
*
|
|
38
|
+
* KEY RULES
|
|
39
|
+
* - `items` on Questionnaire declares the sequence of entries and which are `required`; each QuestionnaireItem matches an entry by `name`.
|
|
40
|
+
* - A QuestionnaireItem's `required`/`multiple` props should match its entry in `items` — `multiple` renders a checkbox-style choice group instead of radio-style.
|
|
41
|
+
* - `shortcuts="letters"` on Questionnaire adds A/B/C key hints to each QuestionnaireChoice.
|
|
42
|
+
* - QuestionnairePrevious / QuestionnaireSkip / QuestionnaireNext / QuestionnaireSubmit manage their own visibility based on step position — render all of them and let the primitive decide which shows.
|
|
43
|
+
* - QuestionnaireError only renders when the active item fails validation (e.g. a required choice wasn't picked).
|
|
44
|
+
* - QuestionnaireInput automatically picks up `aria-labelledby`/`aria-describedby` from the
|
|
45
|
+
* QuestionnaireTitle/QuestionnaireDescription rendered in the same QuestionnaireItem (unlike
|
|
46
|
+
* Choice steps, a free-text step has no native `<label>` wrapping it) — pass an explicit
|
|
47
|
+
* `aria-label`/`aria-labelledby` yourself only if you need to override that default.
|
|
48
|
+
*
|
|
49
|
+
* USAGE
|
|
50
|
+
* <Questionnaire
|
|
51
|
+
* items={[
|
|
52
|
+
* { name: "base", required: true, choices: [{ value: "radix" }, { value: "base-ui" }] },
|
|
53
|
+
* { name: "notes" },
|
|
54
|
+
* ]}
|
|
55
|
+
* >
|
|
56
|
+
* <QuestionnaireProgress />
|
|
57
|
+
* <QuestionnaireItem name="base" required>
|
|
58
|
+
* <QuestionnaireTitle>Which primitive base do you use?</QuestionnaireTitle>
|
|
59
|
+
* <QuestionnaireChoices>
|
|
60
|
+
* <QuestionnaireChoice value="radix">Radix UI</QuestionnaireChoice>
|
|
61
|
+
* <QuestionnaireChoice value="base-ui">Base UI</QuestionnaireChoice>
|
|
62
|
+
* </QuestionnaireChoices>
|
|
63
|
+
* <QuestionnaireError>Pick one to continue.</QuestionnaireError>
|
|
64
|
+
* </QuestionnaireItem>
|
|
65
|
+
* <QuestionnaireItem name="notes">
|
|
66
|
+
* <QuestionnaireTitle>Anything else?</QuestionnaireTitle>
|
|
67
|
+
* <QuestionnaireInput type="text" placeholder="Optional" />
|
|
68
|
+
* </QuestionnaireItem>
|
|
69
|
+
* <QuestionnaireActions>
|
|
70
|
+
* <QuestionnairePrevious>Back</QuestionnairePrevious>
|
|
71
|
+
* <QuestionnaireNext>Next</QuestionnaireNext>
|
|
72
|
+
* <QuestionnaireSubmit>Submit</QuestionnaireSubmit>
|
|
73
|
+
* </QuestionnaireActions>
|
|
74
|
+
* </Questionnaire>
|
|
75
|
+
*
|
|
76
|
+
* // Letter shortcuts (A/B/C hints on choices)
|
|
77
|
+
* <Questionnaire
|
|
78
|
+
* shortcuts="letters"
|
|
79
|
+
* items={[{ name: "spice", required: true, choices: [{ value: "turmeric" }] }]}
|
|
80
|
+
* >
|
|
81
|
+
* <QuestionnaireItem name="spice" required>
|
|
82
|
+
* <QuestionnaireTitle>Pick a spice</QuestionnaireTitle>
|
|
83
|
+
* <QuestionnaireChoices>
|
|
84
|
+
* <QuestionnaireChoice value="turmeric">Turmeric</QuestionnaireChoice>
|
|
85
|
+
* </QuestionnaireChoices>
|
|
86
|
+
* </QuestionnaireItem>
|
|
87
|
+
* <QuestionnaireActions>
|
|
88
|
+
* <QuestionnaireSubmit>Submit</QuestionnaireSubmit>
|
|
89
|
+
* </QuestionnaireActions>
|
|
90
|
+
* </Questionnaire>
|
|
91
|
+
*/
|
|
92
|
+
//# sourceMappingURL=questionnaire.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"questionnaire.d.ts","sourceRoot":"","sources":["../../../src/components/ui/questionnaire.tsx"],"names":[],"mappings":"AAEA;;;;;;;;GAQG;AAEH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAC9B,OAAO,EAAE,aAAa,IAAI,sBAAsB,EAAE,MAAM,6BAA6B,CAAA;AAGrF,OAAO,EAAkB,KAAK,MAAM,EAAE,MAAM,wBAAwB,CAAA;AAiBpE,iBAAS,aAAa,CAAC,EACrB,SAAS,EACT,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,sBAAsB,CAAC,IAAI,CAAC,qBAQ1D;AAED,iBAAS,qBAAqB,CAAC,EAC7B,SAAS,EACT,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,sBAAsB,CAAC,QAAQ,CAAC,qBAW9D;AAED,iBAAS,iBAAiB,CAAC,EACzB,SAAS,EACT,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,sBAAsB,CAAC,IAAI,CAAC,qBAsB1D;AAED,iBAAS,kBAAkB,CAAC,EAC1B,SAAS,EACT,EAAE,EACF,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,sBAAsB,CAAC,KAAK,CAAC,qBAsB3D;AAED,iBAAS,wBAAwB,CAAC,EAChC,SAAS,EACT,EAAE,EACF,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,sBAAsB,CAAC,WAAW,CAAC,qBAmBjE;AAED,iBAAS,oBAAoB,CAAC,EAC5B,SAAS,EACT,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,sBAAsB,CAAC,OAAO,CAAC,qBAW7D;AAED,iBAAS,mBAAmB,CAAC,EAC3B,QAAQ,EACR,SAAS,EACT,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,sBAAsB,CAAC,MAAM,CAAC,qBAyC5D;AAED,iBAAS,8BAA8B,CAAC,EACtC,SAAS,EACT,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,MAAM,CAAC,qBAQ9B;AAED,iBAAS,kBAAkB,CAAC,EAC1B,SAAS,EACT,iBAAiB,EAAE,cAAc,EACjC,kBAAkB,EAAE,eAAe,EACnC,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,sBAAsB,CAAC,KAAK,CAAC,qBA6B3D;AAED,iBAAS,kBAAkB,CAAC,EAC1B,SAAS,EACT,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,sBAAsB,CAAC,KAAK,CAAC,qBAQ3D;AAED,iBAAS,oBAAoB,CAAC,EAC5B,SAAS,EACT,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC,qBAW7B;AAED,iBAAS,qBAAqB,CAAC,EAC7B,QAAQ,EACR,SAAS,EACT,IAAgB,EAChB,OAAmB,EACnB,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,sBAAsB,CAAC,QAAQ,CAAC,GAC7D,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,OAAO,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC,qBAgB9D;AAED,iBAAS,iBAAiB,CAAC,EACzB,QAAQ,EACR,SAAS,EACT,IAAgB,EAChB,OAAmB,EACnB,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,sBAAsB,CAAC,IAAI,CAAC,GACzD,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,OAAO,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC,qBAgB9D;AAED,iBAAS,iBAAiB,CAAC,EACzB,QAAQ,EACR,SAAS,EACT,IAAgB,EAChB,OAAmB,EACnB,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,sBAAsB,CAAC,IAAI,CAAC,GACzD,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,OAAO,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC,qBAgB9D;AAED,iBAAS,mBAAmB,CAAC,EAC3B,QAAQ,EACR,SAAS,EACT,IAAgB,EAChB,OAAmB,EACnB,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,sBAAsB,CAAC,MAAM,CAAC,GAC3D,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,OAAO,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC,qBAgB9D;AAED,OAAO,EACL,aAAa,EACb,oBAAoB,EACpB,mBAAmB,EACnB,8BAA8B,EAC9B,oBAAoB,EACpB,wBAAwB,EACxB,kBAAkB,EAClB,kBAAkB,EAClB,iBAAiB,EACjB,iBAAiB,EACjB,qBAAqB,EACrB,qBAAqB,EACrB,iBAAiB,EACjB,mBAAmB,EACnB,kBAAkB,GACnB,CAAA;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8DG"}
|
|
@@ -0,0 +1,277 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { cn } from "../../lib/utils.js";
|
|
3
|
+
import { buttonVariants } from "./button.js";
|
|
4
|
+
import * as React from "react";
|
|
5
|
+
import { CheckIcon } from "lucide-react";
|
|
6
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
7
|
+
import { Questionnaire as Questionnaire$1 } from "@shadcn/react/questionnaire";
|
|
8
|
+
//#region src/components/ui/questionnaire.tsx
|
|
9
|
+
/**
|
|
10
|
+
* Questionnaire — multi-step form that shows one question at a time.
|
|
11
|
+
*
|
|
12
|
+
* Wraps the `@shadcn/react` Questionnaire primitive (Root, Item, Choice,
|
|
13
|
+
* Input, Previous/Skip/Next/Submit), which handles step sequencing,
|
|
14
|
+
* navigation, and validation; the root renders a <form> that tracks the
|
|
15
|
+
* active item. MMDS styles choices as bordered, checkbox/radio-style cards
|
|
16
|
+
* and lays out Previous/Skip/Next/Submit in a fixed 3-column grid.
|
|
17
|
+
*/
|
|
18
|
+
var QuestionnaireLabelContext = React.createContext(null);
|
|
19
|
+
function Questionnaire({ className, ...props }) {
|
|
20
|
+
return /* @__PURE__ */ jsx(Questionnaire$1.Root, {
|
|
21
|
+
"data-slot": "questionnaire",
|
|
22
|
+
className: cn("flex w-full min-w-0 flex-col gap-4", className),
|
|
23
|
+
...props
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
function QuestionnaireProgress({ className, ...props }) {
|
|
27
|
+
return /* @__PURE__ */ jsx(Questionnaire$1.Progress, {
|
|
28
|
+
"data-slot": "questionnaire-progress",
|
|
29
|
+
className: cn("min-h-[1lh] w-fit min-w-[14ch] text-xs font-medium text-muted-foreground tabular-nums", className),
|
|
30
|
+
...props
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
function QuestionnaireItem({ className, ...props }) {
|
|
34
|
+
const [titleId, setTitleId] = React.useState(null);
|
|
35
|
+
const [descriptionId, setDescriptionId] = React.useState(null);
|
|
36
|
+
const labelContext = React.useMemo(() => ({
|
|
37
|
+
titleId,
|
|
38
|
+
setTitleId,
|
|
39
|
+
descriptionId,
|
|
40
|
+
setDescriptionId
|
|
41
|
+
}), [titleId, descriptionId]);
|
|
42
|
+
return /* @__PURE__ */ jsx(QuestionnaireLabelContext.Provider, {
|
|
43
|
+
value: labelContext,
|
|
44
|
+
children: /* @__PURE__ */ jsx(Questionnaire$1.Item, {
|
|
45
|
+
"data-slot": "questionnaire-item",
|
|
46
|
+
className: cn("flex min-w-0 flex-col gap-4 border-0 p-0 outline-none", className),
|
|
47
|
+
...props
|
|
48
|
+
})
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
function QuestionnaireTitle({ className, id, ...props }) {
|
|
52
|
+
const generatedId = React.useId();
|
|
53
|
+
const titleId = id ?? generatedId;
|
|
54
|
+
const labelContext = React.useContext(QuestionnaireLabelContext);
|
|
55
|
+
React.useLayoutEffect(() => {
|
|
56
|
+
labelContext?.setTitleId(titleId);
|
|
57
|
+
return () => labelContext?.setTitleId(null);
|
|
58
|
+
}, [titleId]);
|
|
59
|
+
return /* @__PURE__ */ jsx(Questionnaire$1.Title, {
|
|
60
|
+
"data-slot": "questionnaire-title",
|
|
61
|
+
id: titleId,
|
|
62
|
+
className: cn("text-base leading-snug font-medium text-pretty [&:not(:has(~[data-slot=questionnaire-description]))]:mb-4", className),
|
|
63
|
+
...props
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
function QuestionnaireDescription({ className, id, ...props }) {
|
|
67
|
+
const generatedId = React.useId();
|
|
68
|
+
const descriptionId = id ?? generatedId;
|
|
69
|
+
const labelContext = React.useContext(QuestionnaireLabelContext);
|
|
70
|
+
React.useLayoutEffect(() => {
|
|
71
|
+
labelContext?.setDescriptionId(descriptionId);
|
|
72
|
+
return () => labelContext?.setDescriptionId(null);
|
|
73
|
+
}, [descriptionId]);
|
|
74
|
+
return /* @__PURE__ */ jsx(Questionnaire$1.Description, {
|
|
75
|
+
"data-slot": "questionnaire-description",
|
|
76
|
+
id: descriptionId,
|
|
77
|
+
className: cn("text-sm text-pretty text-muted-foreground", className),
|
|
78
|
+
...props
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
function QuestionnaireChoices({ className, ...props }) {
|
|
82
|
+
return /* @__PURE__ */ jsx(Questionnaire$1.Choices, {
|
|
83
|
+
"data-slot": "questionnaire-choices",
|
|
84
|
+
className: cn("group/questionnaire-choices grid min-w-0 gap-2", className),
|
|
85
|
+
...props
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
function QuestionnaireChoice({ children, className, ...props }) {
|
|
89
|
+
return /* @__PURE__ */ jsxs(Questionnaire$1.Choice, {
|
|
90
|
+
"data-slot": "questionnaire-choice",
|
|
91
|
+
className: cn("group/questionnaire-choice relative flex min-h-11 cursor-pointer items-start gap-2.5 rounded-lg border border-input bg-transparent px-3 py-2.5 text-start text-sm transition-colors outline-none select-none hover:bg-muted/50 has-[>input:focus-visible]:border-ring has-[>input:focus-visible]:ring-3 has-[>input:focus-visible]:ring-ring/50 data-invalid:border-destructive dark:bg-input/20 data-checked:border-primary/40 data-checked:bg-muted dark:data-checked:bg-muted", "data-disabled:pointer-events-none data-disabled:cursor-not-allowed data-disabled:opacity-50", className),
|
|
92
|
+
...props,
|
|
93
|
+
children: [
|
|
94
|
+
/* @__PURE__ */ jsx(Questionnaire$1.ChoiceInput, {
|
|
95
|
+
"data-slot": "questionnaire-choice-input",
|
|
96
|
+
className: "absolute inset-0 z-10 size-full cursor-pointer opacity-0"
|
|
97
|
+
}),
|
|
98
|
+
/* @__PURE__ */ jsxs("span", {
|
|
99
|
+
"aria-hidden": "true",
|
|
100
|
+
"data-slot": "questionnaire-choice-indicator",
|
|
101
|
+
className: "pointer-events-none relative flex size-4 shrink-0 translate-y-[--spacing(0.45)] items-center justify-center rounded-[4px] border border-input group-has-data-[slot=questionnaire-choice-description]/questionnaire-choice:translate-y-0.5 group-data-[type=radio]/questionnaire-choice:rounded-full group-data-checked/questionnaire-choice:border-primary group-data-checked/questionnaire-choice:bg-primary group-data-checked/questionnaire-choice:text-primary-foreground dark:bg-input/30 dark:group-data-checked/questionnaire-choice:bg-primary",
|
|
102
|
+
children: [/* @__PURE__ */ jsx("span", {
|
|
103
|
+
"data-slot": "questionnaire-choice-indicator-dot",
|
|
104
|
+
className: "hidden size-2 rounded-full bg-primary-foreground group-data-[type=checkbox]/questionnaire-choice:hidden group-data-checked/questionnaire-choice:block"
|
|
105
|
+
}), /* @__PURE__ */ jsx(CheckIcon, {
|
|
106
|
+
"data-slot": "questionnaire-choice-indicator-check",
|
|
107
|
+
className: "hidden size-3.5 group-data-[type=radio]/questionnaire-choice:hidden group-data-checked/questionnaire-choice:block"
|
|
108
|
+
})]
|
|
109
|
+
}),
|
|
110
|
+
/* @__PURE__ */ jsx(Questionnaire$1.ChoiceLabel, {
|
|
111
|
+
"data-slot": "questionnaire-choice-label",
|
|
112
|
+
className: "flex min-w-0 flex-1 flex-col gap-0.5 leading-snug",
|
|
113
|
+
children
|
|
114
|
+
}),
|
|
115
|
+
/* @__PURE__ */ jsx(Questionnaire$1.ChoiceShortcut, {
|
|
116
|
+
"data-slot": "questionnaire-choice-shortcut",
|
|
117
|
+
className: "pointer-events-none ms-auto hidden size-5 shrink-0 translate-y-[--spacing(0.45)] items-center justify-center rounded-md border border-input bg-background font-mono text-[0.625rem] leading-none font-medium text-muted-foreground group-has-data-[slot=questionnaire-choice-description]/questionnaire-choice:translate-y-0.5 group-data-[shortcut]/questionnaire-choice:inline-flex"
|
|
118
|
+
})
|
|
119
|
+
]
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
function QuestionnaireChoiceDescription({ className, ...props }) {
|
|
123
|
+
return /* @__PURE__ */ jsx("span", {
|
|
124
|
+
"data-slot": "questionnaire-choice-description",
|
|
125
|
+
className: cn("text-muted-foreground", className),
|
|
126
|
+
...props
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
function QuestionnaireInput({ className, "aria-labelledby": ariaLabelledby, "aria-describedby": ariaDescribedby, ...props }) {
|
|
130
|
+
const labelContext = React.useContext(QuestionnaireLabelContext);
|
|
131
|
+
const resolvedLabelledby = ariaLabelledby ?? (!props["aria-label"] ? labelContext?.titleId ?? void 0 : void 0);
|
|
132
|
+
const resolvedDescribedby = ariaDescribedby ?? labelContext?.descriptionId ?? void 0;
|
|
133
|
+
return /* @__PURE__ */ jsx("div", {
|
|
134
|
+
"data-slot": "questionnaire-input-wrapper",
|
|
135
|
+
className: "group/questionnaire-input relative w-full min-w-0",
|
|
136
|
+
children: /* @__PURE__ */ jsx(Questionnaire$1.Input, {
|
|
137
|
+
"data-slot": "questionnaire-input",
|
|
138
|
+
"aria-labelledby": resolvedLabelledby,
|
|
139
|
+
"aria-describedby": resolvedDescribedby,
|
|
140
|
+
className: cn("h-8 min-h-11 w-full min-w-0 rounded-lg border border-input bg-transparent px-2.5 py-1 text-base transition-[color,box-shadow,background-color] outline-none focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 disabled:pointer-events-none disabled:cursor-not-allowed disabled:bg-input/50 disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 sm:min-h-0 md:text-sm dark:bg-input/30 dark:disabled:bg-input/80 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40", "selection:bg-primary selection:text-primary-foreground placeholder:text-muted-foreground", className),
|
|
141
|
+
...props
|
|
142
|
+
})
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
function QuestionnaireError({ className, ...props }) {
|
|
146
|
+
return /* @__PURE__ */ jsx(Questionnaire$1.Error, {
|
|
147
|
+
"data-slot": "questionnaire-error",
|
|
148
|
+
className: cn("mt-2 text-sm text-destructive", className),
|
|
149
|
+
...props
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
function QuestionnaireActions({ className, ...props }) {
|
|
153
|
+
return /* @__PURE__ */ jsx("div", {
|
|
154
|
+
"data-slot": "questionnaire-actions",
|
|
155
|
+
className: cn("grid min-h-11 w-full grid-cols-[minmax(0,1fr)_auto_auto] items-center gap-2 sm:min-h-8", className),
|
|
156
|
+
...props
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
function QuestionnairePrevious({ children, className, size = "default", variant = "outline", ...props }) {
|
|
160
|
+
return /* @__PURE__ */ jsx(Questionnaire$1.Previous, {
|
|
161
|
+
"data-slot": "questionnaire-previous",
|
|
162
|
+
"data-size": size,
|
|
163
|
+
"data-variant": variant,
|
|
164
|
+
className: cn(buttonVariants({
|
|
165
|
+
size,
|
|
166
|
+
variant
|
|
167
|
+
}), "col-start-1 row-start-1 min-h-11 justify-self-start sm:min-h-0", className),
|
|
168
|
+
...props,
|
|
169
|
+
children: children ?? "Previous"
|
|
170
|
+
});
|
|
171
|
+
}
|
|
172
|
+
function QuestionnaireSkip({ children, className, size = "default", variant = "outline", ...props }) {
|
|
173
|
+
return /* @__PURE__ */ jsx(Questionnaire$1.Skip, {
|
|
174
|
+
"data-slot": "questionnaire-skip",
|
|
175
|
+
"data-size": size,
|
|
176
|
+
"data-variant": variant,
|
|
177
|
+
className: cn(buttonVariants({
|
|
178
|
+
size,
|
|
179
|
+
variant
|
|
180
|
+
}), "col-start-2 row-start-1 min-h-11 justify-self-end sm:min-h-0", className),
|
|
181
|
+
...props,
|
|
182
|
+
children: children ?? "Skip"
|
|
183
|
+
});
|
|
184
|
+
}
|
|
185
|
+
function QuestionnaireNext({ children, className, size = "default", variant = "default", ...props }) {
|
|
186
|
+
return /* @__PURE__ */ jsx(Questionnaire$1.Next, {
|
|
187
|
+
"data-slot": "questionnaire-next",
|
|
188
|
+
"data-size": size,
|
|
189
|
+
"data-variant": variant,
|
|
190
|
+
className: cn(buttonVariants({
|
|
191
|
+
size,
|
|
192
|
+
variant
|
|
193
|
+
}), "col-start-3 row-start-1 min-h-11 justify-self-end sm:min-h-0", className),
|
|
194
|
+
...props,
|
|
195
|
+
children: children ?? "Next"
|
|
196
|
+
});
|
|
197
|
+
}
|
|
198
|
+
function QuestionnaireSubmit({ children, className, size = "default", variant = "default", ...props }) {
|
|
199
|
+
return /* @__PURE__ */ jsx(Questionnaire$1.Submit, {
|
|
200
|
+
"data-slot": "questionnaire-submit",
|
|
201
|
+
"data-size": size,
|
|
202
|
+
"data-variant": variant,
|
|
203
|
+
className: cn(buttonVariants({
|
|
204
|
+
size,
|
|
205
|
+
variant
|
|
206
|
+
}), "col-start-3 row-start-1 min-h-11 justify-self-end sm:min-h-0", className),
|
|
207
|
+
...props,
|
|
208
|
+
children: children ?? "Submit"
|
|
209
|
+
});
|
|
210
|
+
}
|
|
211
|
+
/**
|
|
212
|
+
* WHEN TO USE
|
|
213
|
+
* - Guided multi-step intake, onboarding, or surveys where only one question is shown at a time.
|
|
214
|
+
* - Flows that need per-step required/skip logic and a progress indicator.
|
|
215
|
+
*
|
|
216
|
+
* NOT WHEN
|
|
217
|
+
* - All fields should be visible at once in a single form — use Field + FieldSet instead.
|
|
218
|
+
* - Sections don't need to be shown in sequence — use Tabs instead.
|
|
219
|
+
*
|
|
220
|
+
* KEY RULES
|
|
221
|
+
* - `items` on Questionnaire declares the sequence of entries and which are `required`; each QuestionnaireItem matches an entry by `name`.
|
|
222
|
+
* - A QuestionnaireItem's `required`/`multiple` props should match its entry in `items` — `multiple` renders a checkbox-style choice group instead of radio-style.
|
|
223
|
+
* - `shortcuts="letters"` on Questionnaire adds A/B/C key hints to each QuestionnaireChoice.
|
|
224
|
+
* - QuestionnairePrevious / QuestionnaireSkip / QuestionnaireNext / QuestionnaireSubmit manage their own visibility based on step position — render all of them and let the primitive decide which shows.
|
|
225
|
+
* - QuestionnaireError only renders when the active item fails validation (e.g. a required choice wasn't picked).
|
|
226
|
+
* - QuestionnaireInput automatically picks up `aria-labelledby`/`aria-describedby` from the
|
|
227
|
+
* QuestionnaireTitle/QuestionnaireDescription rendered in the same QuestionnaireItem (unlike
|
|
228
|
+
* Choice steps, a free-text step has no native `<label>` wrapping it) — pass an explicit
|
|
229
|
+
* `aria-label`/`aria-labelledby` yourself only if you need to override that default.
|
|
230
|
+
*
|
|
231
|
+
* USAGE
|
|
232
|
+
* <Questionnaire
|
|
233
|
+
* items={[
|
|
234
|
+
* { name: "base", required: true, choices: [{ value: "radix" }, { value: "base-ui" }] },
|
|
235
|
+
* { name: "notes" },
|
|
236
|
+
* ]}
|
|
237
|
+
* >
|
|
238
|
+
* <QuestionnaireProgress />
|
|
239
|
+
* <QuestionnaireItem name="base" required>
|
|
240
|
+
* <QuestionnaireTitle>Which primitive base do you use?</QuestionnaireTitle>
|
|
241
|
+
* <QuestionnaireChoices>
|
|
242
|
+
* <QuestionnaireChoice value="radix">Radix UI</QuestionnaireChoice>
|
|
243
|
+
* <QuestionnaireChoice value="base-ui">Base UI</QuestionnaireChoice>
|
|
244
|
+
* </QuestionnaireChoices>
|
|
245
|
+
* <QuestionnaireError>Pick one to continue.</QuestionnaireError>
|
|
246
|
+
* </QuestionnaireItem>
|
|
247
|
+
* <QuestionnaireItem name="notes">
|
|
248
|
+
* <QuestionnaireTitle>Anything else?</QuestionnaireTitle>
|
|
249
|
+
* <QuestionnaireInput type="text" placeholder="Optional" />
|
|
250
|
+
* </QuestionnaireItem>
|
|
251
|
+
* <QuestionnaireActions>
|
|
252
|
+
* <QuestionnairePrevious>Back</QuestionnairePrevious>
|
|
253
|
+
* <QuestionnaireNext>Next</QuestionnaireNext>
|
|
254
|
+
* <QuestionnaireSubmit>Submit</QuestionnaireSubmit>
|
|
255
|
+
* </QuestionnaireActions>
|
|
256
|
+
* </Questionnaire>
|
|
257
|
+
*
|
|
258
|
+
* // Letter shortcuts (A/B/C hints on choices)
|
|
259
|
+
* <Questionnaire
|
|
260
|
+
* shortcuts="letters"
|
|
261
|
+
* items={[{ name: "spice", required: true, choices: [{ value: "turmeric" }] }]}
|
|
262
|
+
* >
|
|
263
|
+
* <QuestionnaireItem name="spice" required>
|
|
264
|
+
* <QuestionnaireTitle>Pick a spice</QuestionnaireTitle>
|
|
265
|
+
* <QuestionnaireChoices>
|
|
266
|
+
* <QuestionnaireChoice value="turmeric">Turmeric</QuestionnaireChoice>
|
|
267
|
+
* </QuestionnaireChoices>
|
|
268
|
+
* </QuestionnaireItem>
|
|
269
|
+
* <QuestionnaireActions>
|
|
270
|
+
* <QuestionnaireSubmit>Submit</QuestionnaireSubmit>
|
|
271
|
+
* </QuestionnaireActions>
|
|
272
|
+
* </Questionnaire>
|
|
273
|
+
*/
|
|
274
|
+
//#endregion
|
|
275
|
+
export { Questionnaire, QuestionnaireActions, QuestionnaireChoice, QuestionnaireChoiceDescription, QuestionnaireChoices, QuestionnaireDescription, QuestionnaireError, QuestionnaireInput, QuestionnaireItem, QuestionnaireNext, QuestionnairePrevious, QuestionnaireProgress, QuestionnaireSkip, QuestionnaireSubmit, QuestionnaireTitle };
|
|
276
|
+
|
|
277
|
+
//# sourceMappingURL=questionnaire.js.map
|