@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,115 @@
|
|
|
1
|
+
import { cn } from "../../lib/utils.js";
|
|
2
|
+
import { Button } from "./button.js";
|
|
3
|
+
import { Input } from "./input.js";
|
|
4
|
+
import { Textarea } from "./textarea.js";
|
|
5
|
+
import "react";
|
|
6
|
+
import { jsx } from "react/jsx-runtime";
|
|
7
|
+
import { cva } from "class-variance-authority";
|
|
8
|
+
//#region src/components/ui/input-group.tsx
|
|
9
|
+
function InputGroup({ className, ...props }) {
|
|
10
|
+
return /* @__PURE__ */ jsx("div", {
|
|
11
|
+
"data-slot": "input-group",
|
|
12
|
+
role: "group",
|
|
13
|
+
className: cn("group/input-group relative flex h-8 w-full min-w-0 items-center rounded-lg border border-input transition-colors outline-none in-data-[slot=combobox-content]:focus-within:border-inherit in-data-[slot=combobox-content]:focus-within:ring-0 has-disabled:bg-input/50 has-disabled:opacity-50 has-[[data-slot=input-group-control]:focus-visible]:border-ring has-[[data-slot=input-group-control]:focus-visible]:ring-3 has-[[data-slot=input-group-control]:focus-visible]:ring-ring/50 has-[[data-slot][aria-invalid=true]]:border-destructive has-[[data-slot][aria-invalid=true]]:ring-3 has-[[data-slot][aria-invalid=true]]:ring-destructive/20 has-[>[data-align=block-end]]:h-auto has-[>[data-align=block-end]]:flex-col has-[>[data-align=block-start]]:h-auto has-[>[data-align=block-start]]:flex-col has-[>textarea]:h-auto dark:bg-input/30 dark:has-disabled:bg-input/80 dark:has-[[data-slot][aria-invalid=true]]:ring-destructive/40 has-[>[data-align=block-end]]:[&>input]:pt-3 has-[>[data-align=block-start]]:[&>input]:pb-3 has-[>[data-align=inline-end]]:[&>input]:pr-1.5 has-[>[data-align=inline-start]]:[&>input]:pl-1.5", className),
|
|
14
|
+
...props
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
var inputGroupAddonVariants = cva("flex h-auto cursor-text items-center justify-center gap-2 py-1.5 text-sm font-medium text-muted-foreground select-none group-data-[disabled=true]/input-group:opacity-50 [&>kbd]:rounded-[calc(var(--radius)-5px)] [&>svg:not([class*='size-'])]:size-4", {
|
|
18
|
+
variants: { align: {
|
|
19
|
+
"inline-start": "order-first pl-2 has-[>button]:ml-[-0.3rem] has-[>kbd]:ml-[-0.15rem]",
|
|
20
|
+
"inline-end": "order-last pr-2 has-[>button]:mr-[-0.3rem] has-[>kbd]:mr-[-0.15rem]",
|
|
21
|
+
"block-start": "order-first w-full justify-start px-2.5 pt-2 group-has-[>input]/input-group:pt-2 [.border-b]:pb-2",
|
|
22
|
+
"block-end": "order-last w-full justify-start px-2.5 pb-2 group-has-[>input]/input-group:pb-2 [.border-t]:pt-2"
|
|
23
|
+
} },
|
|
24
|
+
defaultVariants: { align: "inline-start" }
|
|
25
|
+
});
|
|
26
|
+
function InputGroupAddon({ className, align = "inline-start", ...props }) {
|
|
27
|
+
return /* @__PURE__ */ jsx("div", {
|
|
28
|
+
role: "group",
|
|
29
|
+
"data-slot": "input-group-addon",
|
|
30
|
+
"data-align": align,
|
|
31
|
+
className: cn(inputGroupAddonVariants({ align }), className),
|
|
32
|
+
onClick: (e) => {
|
|
33
|
+
if (e.target.closest("button")) return;
|
|
34
|
+
e.currentTarget.parentElement?.querySelector("input")?.focus();
|
|
35
|
+
},
|
|
36
|
+
...props
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
var inputGroupButtonVariants = cva("flex items-center gap-2 text-sm shadow-none", {
|
|
40
|
+
variants: { size: {
|
|
41
|
+
xs: "h-6 gap-1 rounded-[calc(var(--radius)-3px)] px-1.5 [&>svg:not([class*='size-'])]:size-3.5",
|
|
42
|
+
sm: "",
|
|
43
|
+
"icon-xs": "size-6 rounded-[calc(var(--radius)-3px)] p-0 has-[>svg]:p-0",
|
|
44
|
+
"icon-sm": "size-8 p-0 has-[>svg]:p-0"
|
|
45
|
+
} },
|
|
46
|
+
defaultVariants: { size: "xs" }
|
|
47
|
+
});
|
|
48
|
+
var INPUT_GROUP_ICON_ONLY_SIZE = {
|
|
49
|
+
xs: "icon-xs",
|
|
50
|
+
sm: "icon-sm"
|
|
51
|
+
};
|
|
52
|
+
function InputGroupButton({ className, type = "button", variant = "ghost", size = "xs", iconOnly = false, ...props }) {
|
|
53
|
+
const resolvedSize = iconOnly && size in INPUT_GROUP_ICON_ONLY_SIZE ? INPUT_GROUP_ICON_ONLY_SIZE[size] : size;
|
|
54
|
+
return /* @__PURE__ */ jsx(Button, {
|
|
55
|
+
type,
|
|
56
|
+
"data-size": resolvedSize,
|
|
57
|
+
variant,
|
|
58
|
+
className: cn(inputGroupButtonVariants({ size: resolvedSize }), className),
|
|
59
|
+
...props
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
function InputGroupText({ className, ...props }) {
|
|
63
|
+
return /* @__PURE__ */ jsx("span", {
|
|
64
|
+
className: cn("flex items-center gap-2 text-sm text-muted-foreground [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4", className),
|
|
65
|
+
...props
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
function InputGroupInput({ className, ...props }) {
|
|
69
|
+
return /* @__PURE__ */ jsx(Input, {
|
|
70
|
+
"data-slot": "input-group-control",
|
|
71
|
+
className: cn("flex-1 rounded-none border-0 bg-transparent shadow-none ring-0 focus-visible:ring-0 disabled:bg-transparent aria-invalid:ring-0 dark:bg-transparent dark:disabled:bg-transparent", className),
|
|
72
|
+
...props
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
function InputGroupTextarea({ className, ...props }) {
|
|
76
|
+
return /* @__PURE__ */ jsx(Textarea, {
|
|
77
|
+
"data-slot": "input-group-control",
|
|
78
|
+
className: cn("flex-1 resize-none rounded-none border-0 bg-transparent py-2 shadow-none ring-0 focus-visible:ring-0 disabled:bg-transparent aria-invalid:ring-0 dark:bg-transparent dark:disabled:bg-transparent", className),
|
|
79
|
+
...props
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* WHEN TO USE
|
|
84
|
+
* - A search field with a leading icon
|
|
85
|
+
* - A URL field with an "https://" prefix or a units suffix
|
|
86
|
+
* - A textarea with a send button beneath it (a composer) — use `align="block-end"` on the addon
|
|
87
|
+
*
|
|
88
|
+
* NOT WHEN
|
|
89
|
+
* - A plain field with no icon/affix — use Input or Textarea directly
|
|
90
|
+
* - Two or more unrelated buttons standing alone — use ButtonGroup
|
|
91
|
+
*
|
|
92
|
+
* KEY RULES
|
|
93
|
+
* - Use InputGroupInput / InputGroupTextarea inside, not the plain Input/Textarea — they strip the inner border/ring so only the InputGroup shell shows focus/error state
|
|
94
|
+
* - InputGroupAddon align: inline-start, inline-end (default row, sit beside the control), block-start, block-end (full-width row above/below the control — this is what turns the group into a multi-row composer)
|
|
95
|
+
* - Clicking an addon focuses the control automatically, unless the click target is a button inside it
|
|
96
|
+
* - InputGroupButton sizes: xs (default), sm — plus `iconOnly` for a square icon button at that step
|
|
97
|
+
* (the old icon-xs/icon-sm values still work as deprecated aliases) — matches the group's compact height
|
|
98
|
+
*
|
|
99
|
+
* USAGE
|
|
100
|
+
* <InputGroup>
|
|
101
|
+
* <InputGroupAddon><SearchIcon /></InputGroupAddon>
|
|
102
|
+
* <InputGroupInput placeholder="Search..." />
|
|
103
|
+
* </InputGroup>
|
|
104
|
+
*
|
|
105
|
+
* <InputGroup>
|
|
106
|
+
* <InputGroupTextarea placeholder="Message..." />
|
|
107
|
+
* <InputGroupAddon align="block-end">
|
|
108
|
+
* <InputGroupButton size="sm" iconOnly aria-label="Send"><SendIcon /></InputGroupButton>
|
|
109
|
+
* </InputGroupAddon>
|
|
110
|
+
* </InputGroup>
|
|
111
|
+
*/
|
|
112
|
+
//#endregion
|
|
113
|
+
export { InputGroup, InputGroupAddon, InputGroupButton, InputGroupInput, InputGroupText, InputGroupTextarea };
|
|
114
|
+
|
|
115
|
+
//# sourceMappingURL=input-group.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"input-group.js","names":[],"sources":["../../../src/components/ui/input-group.tsx"],"sourcesContent":["/**\n * InputGroup — Input/Textarea with attached icons, affixes, or buttons.\n *\n * A composite family: InputGroup is the bordered shell; InputGroupInput /\n * InputGroupTextarea render the actual control borderless inside it;\n * InputGroupAddon positions icons/text/buttons at any edge.\n * The group's focus/error rings live on the shell (InputGroup), not the\n * inner control.\n */\n\nimport * as React from \"react\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\n\nimport { cn } from \"@/lib/utils\"\nimport { Button } from \"@/components/ui/button\"\nimport { Input } from \"@/components/ui/input\"\nimport { Textarea } from \"@/components/ui/textarea\"\n\nfunction InputGroup({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"input-group\"\n role=\"group\"\n className={cn(\n \"group/input-group relative flex h-8 w-full min-w-0 items-center rounded-lg border border-input transition-colors outline-none in-data-[slot=combobox-content]:focus-within:border-inherit in-data-[slot=combobox-content]:focus-within:ring-0 has-disabled:bg-input/50 has-disabled:opacity-50 has-[[data-slot=input-group-control]:focus-visible]:border-ring has-[[data-slot=input-group-control]:focus-visible]:ring-3 has-[[data-slot=input-group-control]:focus-visible]:ring-ring/50 has-[[data-slot][aria-invalid=true]]:border-destructive has-[[data-slot][aria-invalid=true]]:ring-3 has-[[data-slot][aria-invalid=true]]:ring-destructive/20 has-[>[data-align=block-end]]:h-auto has-[>[data-align=block-end]]:flex-col has-[>[data-align=block-start]]:h-auto has-[>[data-align=block-start]]:flex-col has-[>textarea]:h-auto dark:bg-input/30 dark:has-disabled:bg-input/80 dark:has-[[data-slot][aria-invalid=true]]:ring-destructive/40 has-[>[data-align=block-end]]:[&>input]:pt-3 has-[>[data-align=block-start]]:[&>input]:pb-3 has-[>[data-align=inline-end]]:[&>input]:pr-1.5 has-[>[data-align=inline-start]]:[&>input]:pl-1.5\",\n className\n )}\n {...props}\n />\n )\n}\n\nconst inputGroupAddonVariants = cva(\n \"flex h-auto cursor-text items-center justify-center gap-2 py-1.5 text-sm font-medium text-muted-foreground select-none group-data-[disabled=true]/input-group:opacity-50 [&>kbd]:rounded-[calc(var(--radius)-5px)] [&>svg:not([class*='size-'])]:size-4\",\n {\n variants: {\n align: {\n \"inline-start\":\n \"order-first pl-2 has-[>button]:ml-[-0.3rem] has-[>kbd]:ml-[-0.15rem]\",\n \"inline-end\":\n \"order-last pr-2 has-[>button]:mr-[-0.3rem] has-[>kbd]:mr-[-0.15rem]\",\n \"block-start\":\n \"order-first w-full justify-start px-2.5 pt-2 group-has-[>input]/input-group:pt-2 [.border-b]:pb-2\",\n \"block-end\":\n \"order-last w-full justify-start px-2.5 pb-2 group-has-[>input]/input-group:pb-2 [.border-t]:pt-2\",\n },\n },\n defaultVariants: {\n align: \"inline-start\",\n },\n }\n)\n\nfunction InputGroupAddon({\n className,\n align = \"inline-start\",\n ...props\n}: React.ComponentProps<\"div\"> & VariantProps<typeof inputGroupAddonVariants>) {\n return (\n <div\n role=\"group\"\n data-slot=\"input-group-addon\"\n data-align={align}\n className={cn(inputGroupAddonVariants({ align }), className)}\n onClick={(e) => {\n if ((e.target as HTMLElement).closest(\"button\")) {\n return\n }\n e.currentTarget.parentElement?.querySelector(\"input\")?.focus()\n }}\n {...props}\n />\n )\n}\n\nconst inputGroupButtonVariants = cva(\n \"flex items-center gap-2 text-sm shadow-none\",\n {\n variants: {\n size: {\n xs: \"h-6 gap-1 rounded-[calc(var(--radius)-3px)] px-1.5 [&>svg:not([class*='size-'])]:size-3.5\",\n sm: \"\",\n \"icon-xs\":\n \"size-6 rounded-[calc(var(--radius)-3px)] p-0 has-[>svg]:p-0\",\n \"icon-sm\": \"size-8 p-0 has-[>svg]:p-0\",\n },\n },\n defaultVariants: {\n size: \"xs\",\n },\n }\n)\n\ntype InputGroupButtonSize = \"xs\" | \"sm\"\n/** @deprecated use `iconOnly` with \"xs\" | \"sm\" — same two-axis split as Button. */\ntype InputGroupButtonIconSize = \"icon-xs\" | \"icon-sm\"\nconst INPUT_GROUP_ICON_ONLY_SIZE: Record<\n InputGroupButtonSize,\n InputGroupButtonIconSize\n> = { xs: \"icon-xs\", sm: \"icon-sm\" }\n\nfunction InputGroupButton({\n className,\n type = \"button\",\n variant = \"ghost\",\n size = \"xs\",\n iconOnly = false,\n ...props\n}: React.ComponentProps<\"button\"> &\n Pick<React.ComponentProps<typeof Button>, \"variant\"> & {\n asChild?: boolean\n /** Height step inside the group: \"xs\" (default) or \"sm\". Icon-only is a separate axis — `iconOnly`. */\n size?: InputGroupButtonSize | InputGroupButtonIconSize\n /** Square, icon-only button at the chosen `size` step (the same split Button uses). Pass `aria-label`. */\n iconOnly?: boolean\n }) {\n const resolvedSize =\n iconOnly && size in INPUT_GROUP_ICON_ONLY_SIZE\n ? INPUT_GROUP_ICON_ONLY_SIZE[size as InputGroupButtonSize]\n : size\n return (\n <Button\n type={type}\n data-size={resolvedSize}\n variant={variant}\n className={cn(\n inputGroupButtonVariants({ size: resolvedSize }),\n className\n )}\n // `size` here is InputGroupButton's own scale, never forwarded to\n // Button (which stays at its own default), so `asChild`'s widened\n // boolean type can't actually violate the icon-only/aria-label\n // invariant at runtime — TS just can't prove that through a spread.\n {...(props as React.ComponentProps<typeof Button>)}\n />\n )\n}\n\nfunction InputGroupText({ className, ...props }: React.ComponentProps<\"span\">) {\n return (\n <span\n className={cn(\n \"flex items-center gap-2 text-sm text-muted-foreground [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction InputGroupInput({\n className,\n ...props\n}: Omit<React.ComponentProps<\"input\">, \"size\">) {\n return (\n <Input\n data-slot=\"input-group-control\"\n className={cn(\n \"flex-1 rounded-none border-0 bg-transparent shadow-none ring-0 focus-visible:ring-0 disabled:bg-transparent aria-invalid:ring-0 dark:bg-transparent dark:disabled:bg-transparent\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction InputGroupTextarea({\n className,\n ...props\n}: React.ComponentProps<\"textarea\">) {\n return (\n <Textarea\n data-slot=\"input-group-control\"\n className={cn(\n \"flex-1 resize-none rounded-none border-0 bg-transparent py-2 shadow-none ring-0 focus-visible:ring-0 disabled:bg-transparent aria-invalid:ring-0 dark:bg-transparent dark:disabled:bg-transparent\",\n className\n )}\n {...props}\n />\n )\n}\n\nexport {\n InputGroup,\n InputGroupAddon,\n InputGroupButton,\n InputGroupText,\n InputGroupInput,\n InputGroupTextarea,\n}\n\n/**\n * WHEN TO USE\n * - A search field with a leading icon\n * - A URL field with an \"https://\" prefix or a units suffix\n * - A textarea with a send button beneath it (a composer) — use `align=\"block-end\"` on the addon\n *\n * NOT WHEN\n * - A plain field with no icon/affix — use Input or Textarea directly\n * - Two or more unrelated buttons standing alone — use ButtonGroup\n *\n * KEY RULES\n * - Use InputGroupInput / InputGroupTextarea inside, not the plain Input/Textarea — they strip the inner border/ring so only the InputGroup shell shows focus/error state\n * - InputGroupAddon align: inline-start, inline-end (default row, sit beside the control), block-start, block-end (full-width row above/below the control — this is what turns the group into a multi-row composer)\n * - Clicking an addon focuses the control automatically, unless the click target is a button inside it\n * - InputGroupButton sizes: xs (default), sm — plus `iconOnly` for a square icon button at that step\n * (the old icon-xs/icon-sm values still work as deprecated aliases) — matches the group's compact height\n *\n * USAGE\n * <InputGroup>\n * <InputGroupAddon><SearchIcon /></InputGroupAddon>\n * <InputGroupInput placeholder=\"Search...\" />\n * </InputGroup>\n *\n * <InputGroup>\n * <InputGroupTextarea placeholder=\"Message...\" />\n * <InputGroupAddon align=\"block-end\">\n * <InputGroupButton size=\"sm\" iconOnly aria-label=\"Send\"><SendIcon /></InputGroupButton>\n * </InputGroupAddon>\n * </InputGroup>\n */\n"],"mappings":";;;;;;;;AAkBA,SAAS,WAAW,EAAE,WAAW,GAAG,SAAsC;CACxE,OACE,oBAAC,OAAD;EACE,aAAU;EACV,MAAK;EACL,WAAW,GACT,ylCACA,SACF;EACA,GAAI;CACL,CAAA;AAEL;AAEA,IAAM,0BAA0B,IAC9B,2PACA;CACE,UAAU,EACR,OAAO;EACL,gBACE;EACF,cACE;EACF,eACE;EACF,aACE;CACJ,EACF;CACA,iBAAiB,EACf,OAAO,eACT;AACF,CACF;AAEA,SAAS,gBAAgB,EACvB,WACA,QAAQ,gBACR,GAAG,SAC0E;CAC7E,OACE,oBAAC,OAAD;EACE,MAAK;EACL,aAAU;EACV,cAAY;EACZ,WAAW,GAAG,wBAAwB,EAAE,MAAM,CAAC,GAAG,SAAS;EAC3D,UAAU,MAAM;GACd,IAAK,EAAE,OAAuB,QAAQ,QAAQ,GAC5C;GAEF,EAAE,cAAc,eAAe,cAAc,OAAO,CAAC,EAAE,MAAM;EAC/D;EACA,GAAI;CACL,CAAA;AAEL;AAEA,IAAM,2BAA2B,IAC/B,+CACA;CACE,UAAU,EACR,MAAM;EACJ,IAAI;EACJ,IAAI;EACJ,WACE;EACF,WAAW;CACb,EACF;CACA,iBAAiB,EACf,MAAM,KACR;AACF,CACF;AAKA,IAAM,6BAGF;CAAE,IAAI;CAAW,IAAI;AAAU;AAEnC,SAAS,iBAAiB,EACxB,WACA,OAAO,UACP,UAAU,SACV,OAAO,MACP,WAAW,OACX,GAAG,SAQA;CACH,MAAM,eACJ,YAAY,QAAQ,6BAChB,2BAA2B,QAC3B;CACN,OACE,oBAAC,QAAD;EACQ;EACN,aAAW;EACF;EACT,WAAW,GACT,yBAAyB,EAAE,MAAM,aAAa,CAAC,GAC/C,SACF;EAKA,GAAK;CACN,CAAA;AAEL;AAEA,SAAS,eAAe,EAAE,WAAW,GAAG,SAAuC;CAC7E,OACE,oBAAC,QAAD;EACE,WAAW,GACT,0HACA,SACF;EACA,GAAI;CACL,CAAA;AAEL;AAEA,SAAS,gBAAgB,EACvB,WACA,GAAG,SAC2C;CAC9C,OACE,oBAAC,OAAD;EACE,aAAU;EACV,WAAW,GACT,oLACA,SACF;EACA,GAAI;CACL,CAAA;AAEL;AAEA,SAAS,mBAAmB,EAC1B,WACA,GAAG,SACgC;CACnC,OACE,oBAAC,UAAD;EACE,aAAU;EACV,WAAW,GACT,qMACA,SACF;EACA,GAAI;CACL,CAAA;AAEL"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* InputOTP — segmented input for entering a fixed-length one-time code.
|
|
3
|
+
*
|
|
4
|
+
* The underlying `input-otp` library (OTPInput) handles focus, paste-splitting,
|
|
5
|
+
* and caret behavior across slots; MMDS supplies the slot/group/separator
|
|
6
|
+
* visuals.
|
|
7
|
+
*/
|
|
8
|
+
import * as React from "react";
|
|
9
|
+
import { OTPInput } from "input-otp";
|
|
10
|
+
declare function InputOTP({ className, containerClassName, ...props }: React.ComponentProps<typeof OTPInput> & {
|
|
11
|
+
containerClassName?: string;
|
|
12
|
+
}): React.JSX.Element;
|
|
13
|
+
declare function InputOTPGroup({ className, ...props }: React.ComponentProps<"div">): React.JSX.Element;
|
|
14
|
+
declare function InputOTPSlot({ index, className, ...props }: React.ComponentProps<"div"> & {
|
|
15
|
+
index: number;
|
|
16
|
+
}): React.JSX.Element;
|
|
17
|
+
declare function InputOTPSeparator({ ...props }: React.ComponentProps<"div">): React.JSX.Element;
|
|
18
|
+
export { InputOTP, InputOTPGroup, InputOTPSlot, InputOTPSeparator };
|
|
19
|
+
/**
|
|
20
|
+
* WHEN TO USE
|
|
21
|
+
* - Entering a verification or 2FA code of a known, fixed length.
|
|
22
|
+
*
|
|
23
|
+
* NOT WHEN
|
|
24
|
+
* - General short text entry — use Input.
|
|
25
|
+
* - Passwords — use Input type="password".
|
|
26
|
+
*
|
|
27
|
+
* KEY RULES
|
|
28
|
+
* - `maxLength` on InputOTP sets the code length; render exactly one InputOTPSlot per index, 0 through maxLength - 1.
|
|
29
|
+
* - Split slots into multiple InputOTPGroup blocks with an InputOTPSeparator between them for a grouped layout (e.g. 3+3).
|
|
30
|
+
* - InputOTPSlot reads its char/caret/active state from context set by InputOTP — it must be rendered inside InputOTP, not standalone.
|
|
31
|
+
* - Pasting a full code fills all slots in one action (input-otp library behavior, not custom logic here).
|
|
32
|
+
*
|
|
33
|
+
* USAGE
|
|
34
|
+
* <InputOTP maxLength={6}>
|
|
35
|
+
* <InputOTPGroup>
|
|
36
|
+
* {Array.from({ length: 6 }, (_, i) => <InputOTPSlot key={i} index={i} />)}
|
|
37
|
+
* </InputOTPGroup>
|
|
38
|
+
* </InputOTP>
|
|
39
|
+
*
|
|
40
|
+
* // Split into two groups of three
|
|
41
|
+
* <InputOTP maxLength={6}>
|
|
42
|
+
* <InputOTPGroup>{[0, 1, 2].map((i) => <InputOTPSlot key={i} index={i} />)}</InputOTPGroup>
|
|
43
|
+
* <InputOTPSeparator />
|
|
44
|
+
* <InputOTPGroup>{[3, 4, 5].map((i) => <InputOTPSlot key={i} index={i} />)}</InputOTPGroup>
|
|
45
|
+
* </InputOTP>
|
|
46
|
+
*
|
|
47
|
+
* // Prefilled
|
|
48
|
+
* <InputOTP maxLength={4} defaultValue="1234">
|
|
49
|
+
* <InputOTPGroup>{[0, 1, 2, 3].map((i) => <InputOTPSlot key={i} index={i} />)}</InputOTPGroup>
|
|
50
|
+
* </InputOTP>
|
|
51
|
+
*/
|
|
52
|
+
//# sourceMappingURL=input-otp.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"input-otp.d.ts","sourceRoot":"","sources":["../../../src/components/ui/input-otp.tsx"],"names":[],"mappings":"AAEA;;;;;;GAMG;AAEH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAC9B,OAAO,EAAE,QAAQ,EAAmB,MAAM,WAAW,CAAA;AAKrD,iBAAS,QAAQ,CAAC,EAChB,SAAS,EACT,kBAAkB,EAClB,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,QAAQ,CAAC,GAAG;IACzC,kBAAkB,CAAC,EAAE,MAAM,CAAA;CAC5B,qBAaA;AAED,iBAAS,aAAa,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC,qBAW1E;AAED,iBAAS,YAAY,CAAC,EACpB,KAAK,EACL,SAAS,EACT,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC,GAAG;IAC/B,KAAK,EAAE,MAAM,CAAA;CACd,qBAsBA;AAED,iBAAS,iBAAiB,CAAC,EAAE,GAAG,KAAK,EAAE,EAAE,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC,qBAWnE;AAED,OAAO,EAAE,QAAQ,EAAE,aAAa,EAAE,YAAY,EAAE,iBAAiB,EAAE,CAAA;AAEnE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG"}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { cn } from "../../lib/utils.js";
|
|
3
|
+
import * as React from "react";
|
|
4
|
+
import { MinusIcon } from "lucide-react";
|
|
5
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
6
|
+
import { OTPInput, OTPInputContext } from "input-otp";
|
|
7
|
+
//#region src/components/ui/input-otp.tsx
|
|
8
|
+
/**
|
|
9
|
+
* InputOTP — segmented input for entering a fixed-length one-time code.
|
|
10
|
+
*
|
|
11
|
+
* The underlying `input-otp` library (OTPInput) handles focus, paste-splitting,
|
|
12
|
+
* and caret behavior across slots; MMDS supplies the slot/group/separator
|
|
13
|
+
* visuals.
|
|
14
|
+
*/
|
|
15
|
+
function InputOTP({ className, containerClassName, ...props }) {
|
|
16
|
+
return /* @__PURE__ */ jsx(OTPInput, {
|
|
17
|
+
"data-slot": "input-otp",
|
|
18
|
+
containerClassName: cn("cn-input-otp flex items-center has-disabled:opacity-50", containerClassName),
|
|
19
|
+
spellCheck: false,
|
|
20
|
+
className: cn("disabled:cursor-not-allowed", className),
|
|
21
|
+
...props
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
function InputOTPGroup({ className, ...props }) {
|
|
25
|
+
return /* @__PURE__ */ jsx("div", {
|
|
26
|
+
"data-slot": "input-otp-group",
|
|
27
|
+
className: cn("flex items-center rounded-lg has-aria-invalid:border-destructive has-aria-invalid:ring-3 has-aria-invalid:ring-destructive/20 dark:has-aria-invalid:ring-destructive/40", className),
|
|
28
|
+
...props
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
function InputOTPSlot({ index, className, ...props }) {
|
|
32
|
+
const { char, hasFakeCaret, isActive } = React.useContext(OTPInputContext)?.slots[index] ?? {};
|
|
33
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
34
|
+
"data-slot": "input-otp-slot",
|
|
35
|
+
"data-active": isActive,
|
|
36
|
+
className: cn("relative flex size-8 items-center justify-center border-y border-r border-input text-sm transition-colors outline-none first:rounded-l-lg first:border-l last:rounded-r-lg aria-invalid:border-destructive data-[active=true]:z-10 data-[active=true]:border-ring data-[active=true]:ring-3 data-[active=true]:ring-ring/50 data-[active=true]:aria-invalid:border-destructive data-[active=true]:aria-invalid:ring-destructive/20 dark:bg-input/30 dark:data-[active=true]:aria-invalid:ring-destructive/40", className),
|
|
37
|
+
...props,
|
|
38
|
+
children: [char, hasFakeCaret && /* @__PURE__ */ jsx("div", {
|
|
39
|
+
className: "pointer-events-none absolute inset-0 flex items-center justify-center",
|
|
40
|
+
children: /* @__PURE__ */ jsx("div", { className: "h-4 w-px animate-caret-blink bg-foreground duration-1000" })
|
|
41
|
+
})]
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
function InputOTPSeparator({ ...props }) {
|
|
45
|
+
return /* @__PURE__ */ jsx("div", {
|
|
46
|
+
"data-slot": "input-otp-separator",
|
|
47
|
+
className: "flex items-center [&_svg:not([class*='size-'])]:size-4",
|
|
48
|
+
role: "separator",
|
|
49
|
+
...props,
|
|
50
|
+
children: /* @__PURE__ */ jsx(MinusIcon, {})
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* WHEN TO USE
|
|
55
|
+
* - Entering a verification or 2FA code of a known, fixed length.
|
|
56
|
+
*
|
|
57
|
+
* NOT WHEN
|
|
58
|
+
* - General short text entry — use Input.
|
|
59
|
+
* - Passwords — use Input type="password".
|
|
60
|
+
*
|
|
61
|
+
* KEY RULES
|
|
62
|
+
* - `maxLength` on InputOTP sets the code length; render exactly one InputOTPSlot per index, 0 through maxLength - 1.
|
|
63
|
+
* - Split slots into multiple InputOTPGroup blocks with an InputOTPSeparator between them for a grouped layout (e.g. 3+3).
|
|
64
|
+
* - InputOTPSlot reads its char/caret/active state from context set by InputOTP — it must be rendered inside InputOTP, not standalone.
|
|
65
|
+
* - Pasting a full code fills all slots in one action (input-otp library behavior, not custom logic here).
|
|
66
|
+
*
|
|
67
|
+
* USAGE
|
|
68
|
+
* <InputOTP maxLength={6}>
|
|
69
|
+
* <InputOTPGroup>
|
|
70
|
+
* {Array.from({ length: 6 }, (_, i) => <InputOTPSlot key={i} index={i} />)}
|
|
71
|
+
* </InputOTPGroup>
|
|
72
|
+
* </InputOTP>
|
|
73
|
+
*
|
|
74
|
+
* // Split into two groups of three
|
|
75
|
+
* <InputOTP maxLength={6}>
|
|
76
|
+
* <InputOTPGroup>{[0, 1, 2].map((i) => <InputOTPSlot key={i} index={i} />)}</InputOTPGroup>
|
|
77
|
+
* <InputOTPSeparator />
|
|
78
|
+
* <InputOTPGroup>{[3, 4, 5].map((i) => <InputOTPSlot key={i} index={i} />)}</InputOTPGroup>
|
|
79
|
+
* </InputOTP>
|
|
80
|
+
*
|
|
81
|
+
* // Prefilled
|
|
82
|
+
* <InputOTP maxLength={4} defaultValue="1234">
|
|
83
|
+
* <InputOTPGroup>{[0, 1, 2, 3].map((i) => <InputOTPSlot key={i} index={i} />)}</InputOTPGroup>
|
|
84
|
+
* </InputOTP>
|
|
85
|
+
*/
|
|
86
|
+
//#endregion
|
|
87
|
+
export { InputOTP, InputOTPGroup, InputOTPSeparator, InputOTPSlot };
|
|
88
|
+
|
|
89
|
+
//# sourceMappingURL=input-otp.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"input-otp.js","names":[],"sources":["../../../src/components/ui/input-otp.tsx"],"sourcesContent":["\"use client\"\n\n/**\n * InputOTP — segmented input for entering a fixed-length one-time code.\n *\n * The underlying `input-otp` library (OTPInput) handles focus, paste-splitting,\n * and caret behavior across slots; MMDS supplies the slot/group/separator\n * visuals.\n */\n\nimport * as React from \"react\"\nimport { OTPInput, OTPInputContext } from \"input-otp\"\n\nimport { cn } from \"@/lib/utils\"\nimport { MinusIcon } from \"lucide-react\"\n\nfunction InputOTP({\n className,\n containerClassName,\n ...props\n}: React.ComponentProps<typeof OTPInput> & {\n containerClassName?: string\n}) {\n return (\n <OTPInput\n data-slot=\"input-otp\"\n containerClassName={cn(\n \"cn-input-otp flex items-center has-disabled:opacity-50\",\n containerClassName\n )}\n spellCheck={false}\n className={cn(\"disabled:cursor-not-allowed\", className)}\n {...props}\n />\n )\n}\n\nfunction InputOTPGroup({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"input-otp-group\"\n className={cn(\n \"flex items-center rounded-lg has-aria-invalid:border-destructive has-aria-invalid:ring-3 has-aria-invalid:ring-destructive/20 dark:has-aria-invalid:ring-destructive/40\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction InputOTPSlot({\n index,\n className,\n ...props\n}: React.ComponentProps<\"div\"> & {\n index: number\n}) {\n const inputOTPContext = React.useContext(OTPInputContext)\n const { char, hasFakeCaret, isActive } = inputOTPContext?.slots[index] ?? {}\n\n return (\n <div\n data-slot=\"input-otp-slot\"\n data-active={isActive}\n className={cn(\n \"relative flex size-8 items-center justify-center border-y border-r border-input text-sm transition-colors outline-none first:rounded-l-lg first:border-l last:rounded-r-lg aria-invalid:border-destructive data-[active=true]:z-10 data-[active=true]:border-ring data-[active=true]:ring-3 data-[active=true]:ring-ring/50 data-[active=true]:aria-invalid:border-destructive data-[active=true]:aria-invalid:ring-destructive/20 dark:bg-input/30 dark:data-[active=true]:aria-invalid:ring-destructive/40\",\n className\n )}\n {...props}\n >\n {char}\n {hasFakeCaret && (\n <div className=\"pointer-events-none absolute inset-0 flex items-center justify-center\">\n <div className=\"h-4 w-px animate-caret-blink bg-foreground duration-1000\" />\n </div>\n )}\n </div>\n )\n}\n\nfunction InputOTPSeparator({ ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"input-otp-separator\"\n className=\"flex items-center [&_svg:not([class*='size-'])]:size-4\"\n role=\"separator\"\n {...props}\n >\n <MinusIcon />\n </div>\n )\n}\n\nexport { InputOTP, InputOTPGroup, InputOTPSlot, InputOTPSeparator }\n\n/**\n * WHEN TO USE\n * - Entering a verification or 2FA code of a known, fixed length.\n *\n * NOT WHEN\n * - General short text entry — use Input.\n * - Passwords — use Input type=\"password\".\n *\n * KEY RULES\n * - `maxLength` on InputOTP sets the code length; render exactly one InputOTPSlot per index, 0 through maxLength - 1.\n * - Split slots into multiple InputOTPGroup blocks with an InputOTPSeparator between them for a grouped layout (e.g. 3+3).\n * - InputOTPSlot reads its char/caret/active state from context set by InputOTP — it must be rendered inside InputOTP, not standalone.\n * - Pasting a full code fills all slots in one action (input-otp library behavior, not custom logic here).\n *\n * USAGE\n * <InputOTP maxLength={6}>\n * <InputOTPGroup>\n * {Array.from({ length: 6 }, (_, i) => <InputOTPSlot key={i} index={i} />)}\n * </InputOTPGroup>\n * </InputOTP>\n *\n * // Split into two groups of three\n * <InputOTP maxLength={6}>\n * <InputOTPGroup>{[0, 1, 2].map((i) => <InputOTPSlot key={i} index={i} />)}</InputOTPGroup>\n * <InputOTPSeparator />\n * <InputOTPGroup>{[3, 4, 5].map((i) => <InputOTPSlot key={i} index={i} />)}</InputOTPGroup>\n * </InputOTP>\n *\n * // Prefilled\n * <InputOTP maxLength={4} defaultValue=\"1234\">\n * <InputOTPGroup>{[0, 1, 2, 3].map((i) => <InputOTPSlot key={i} index={i} />)}</InputOTPGroup>\n * </InputOTP>\n */\n"],"mappings":";;;;;;;;;;;;;;AAgBA,SAAS,SAAS,EAChB,WACA,oBACA,GAAG,SAGF;CACD,OACE,oBAAC,UAAD;EACE,aAAU;EACV,oBAAoB,GAClB,0DACA,kBACF;EACA,YAAY;EACZ,WAAW,GAAG,+BAA+B,SAAS;EACtD,GAAI;CACL,CAAA;AAEL;AAEA,SAAS,cAAc,EAAE,WAAW,GAAG,SAAsC;CAC3E,OACE,oBAAC,OAAD;EACE,aAAU;EACV,WAAW,GACT,2KACA,SACF;EACA,GAAI;CACL,CAAA;AAEL;AAEA,SAAS,aAAa,EACpB,OACA,WACA,GAAG,SAGF;CAED,MAAM,EAAE,MAAM,cAAc,aADJ,MAAM,WAAW,eACA,CAAA,EAAiB,MAAM,UAAU,CAAC;CAE3E,OACE,qBAAC,OAAD;EACE,aAAU;EACV,eAAa;EACb,WAAW,GACT,gfACA,SACF;EACA,GAAI;EAPN,UAAA,CASG,MACA,gBACC,oBAAC,OAAD;GAAK,WAAU;GACb,UAAA,oBAAC,OAAD,EAAK,WAAU,2DAA4D,CAAA;EACxE,CAAA,CAEJ;;AAET;AAEA,SAAS,kBAAkB,EAAE,GAAG,SAAsC;CACpE,OACE,oBAAC,OAAD;EACE,aAAU;EACV,WAAU;EACV,MAAK;EACL,GAAI;EAEJ,UAAA,oBAAC,WAAD,CAAY,CAAA;CACT,CAAA;AAET"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Input — single-line text field.
|
|
3
|
+
*
|
|
4
|
+
* A plain native `<input>` with MMDS border/focus/error styling. Error state
|
|
5
|
+
* is driven purely off `aria-invalid`
|
|
6
|
+
* (no separate `error` prop), there is no built-in icon/affix slot, and a
|
|
7
|
+
* `size` prop ("default" | "sm" | "xs") matching Select/Combobox/NativeSelect's
|
|
8
|
+
* own height/radius steps — default and sm share text size, only xs drops it.
|
|
9
|
+
* Omits the native `size` (character-width) attribute `<input>` normally has,
|
|
10
|
+
* same as ComboboxInput does, since that name is repurposed for this instead.
|
|
11
|
+
*/
|
|
12
|
+
import * as React from "react";
|
|
13
|
+
declare function Input({ className, type, size, ...props }: Omit<React.ComponentProps<"input">, "size"> & {
|
|
14
|
+
size?: "default" | "sm" | "xs";
|
|
15
|
+
}): React.JSX.Element;
|
|
16
|
+
export { Input };
|
|
17
|
+
/**
|
|
18
|
+
* WHEN TO USE
|
|
19
|
+
* - Short free text: names, emails, search queries, numeric values
|
|
20
|
+
* - Any native `type` (text, email, password, number, file, ...) — styling is type-agnostic
|
|
21
|
+
*
|
|
22
|
+
* NOT WHEN
|
|
23
|
+
* - Multi-line content — use Textarea
|
|
24
|
+
* - A fixed set of choices — use Select or Combobox
|
|
25
|
+
* - Needs a leading/trailing icon, prefix, or attached button — wrap in InputGroup instead of adding children here (Input renders no slots of its own)
|
|
26
|
+
*
|
|
27
|
+
* KEY RULES
|
|
28
|
+
* - Error state is driven entirely by `aria-invalid` — there is no `error` prop
|
|
29
|
+
* - Always pair with a Label (via htmlFor) or wrap in Field for validation messaging
|
|
30
|
+
* - size: default | sm | xs (default "default") — same height/radius steps as
|
|
31
|
+
* Select/Combobox/NativeSelect, so they line up in the same form row. default
|
|
32
|
+
* and sm share text size; xs also drops to text-xs.
|
|
33
|
+
* - An AI-filled value is a plain composition, not a dedicated prop, and the same shape as
|
|
34
|
+
* Textarea's: put `AILabel` in the label row as a sibling of FieldLabel — never inside the
|
|
35
|
+
* input box (via InputGroupAddon) where it reads as part of the value, and never inside the
|
|
36
|
+
* label (AILabelTrigger is a button). The Input itself stays plain: no `shadow-ai-glow` or
|
|
37
|
+
* gradient border — that boundary glow is reserved for card-like AI surfaces (Card, Dialog),
|
|
38
|
+
* never form controls, where it fights the field's own focus/invalid rings. Pass AILabel
|
|
39
|
+
* `edited={value !== aiValue}` and an `onRevert` that restores it, so once the user edits the
|
|
40
|
+
* marker becomes a ghost undo button (AILabel's own override/undo morph). See AI/Input.
|
|
41
|
+
*
|
|
42
|
+
* USAGE
|
|
43
|
+
* <Input placeholder="Email" type="email" />
|
|
44
|
+
* <Input aria-invalid defaultValue="not-an-email" />
|
|
45
|
+
* <Input size="sm" placeholder="Compact row" />
|
|
46
|
+
*/
|
|
47
|
+
//# sourceMappingURL=input.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"input.d.ts","sourceRoot":"","sources":["../../../src/components/ui/input.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAI9B,iBAAS,KAAK,CAAC,EACb,SAAS,EACT,IAAI,EACJ,IAAgB,EAChB,GAAG,KAAK,EACT,EAAE,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC,GAAG;IAC/C,IAAI,CAAC,EAAE,SAAS,GAAG,IAAI,GAAG,IAAI,CAAA;CAC/B,qBAmBA;AAED,OAAO,EAAE,KAAK,EAAE,CAAA;AAEhB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { cn } from "../../lib/utils.js";
|
|
2
|
+
import "react";
|
|
3
|
+
import { jsx } from "react/jsx-runtime";
|
|
4
|
+
//#region src/components/ui/input.tsx
|
|
5
|
+
function Input({ className, type, size = "default", ...props }) {
|
|
6
|
+
return /* @__PURE__ */ jsx("input", {
|
|
7
|
+
type,
|
|
8
|
+
"data-slot": "input",
|
|
9
|
+
"data-size": size,
|
|
10
|
+
className: cn("h-8 w-full min-w-0 rounded-lg border border-input bg-transparent px-2.5 py-1 text-base transition-colors outline-none file:inline-flex file:h-6 file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-muted-foreground 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 md:text-sm dark:bg-input/30 dark:disabled:bg-input/80 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40", "data-[size=sm]:h-7 data-[size=sm]:rounded-[min(var(--radius-md,0.375rem),10px)] data-[size=xs]:h-6 data-[size=xs]:px-2 data-[size=xs]:text-xs data-[size=xs]:md:text-xs data-[size=xs]:rounded-[min(var(--radius-md,0.375rem),8px)]", className),
|
|
11
|
+
...props
|
|
12
|
+
});
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* WHEN TO USE
|
|
16
|
+
* - Short free text: names, emails, search queries, numeric values
|
|
17
|
+
* - Any native `type` (text, email, password, number, file, ...) — styling is type-agnostic
|
|
18
|
+
*
|
|
19
|
+
* NOT WHEN
|
|
20
|
+
* - Multi-line content — use Textarea
|
|
21
|
+
* - A fixed set of choices — use Select or Combobox
|
|
22
|
+
* - Needs a leading/trailing icon, prefix, or attached button — wrap in InputGroup instead of adding children here (Input renders no slots of its own)
|
|
23
|
+
*
|
|
24
|
+
* KEY RULES
|
|
25
|
+
* - Error state is driven entirely by `aria-invalid` — there is no `error` prop
|
|
26
|
+
* - Always pair with a Label (via htmlFor) or wrap in Field for validation messaging
|
|
27
|
+
* - size: default | sm | xs (default "default") — same height/radius steps as
|
|
28
|
+
* Select/Combobox/NativeSelect, so they line up in the same form row. default
|
|
29
|
+
* and sm share text size; xs also drops to text-xs.
|
|
30
|
+
* - An AI-filled value is a plain composition, not a dedicated prop, and the same shape as
|
|
31
|
+
* Textarea's: put `AILabel` in the label row as a sibling of FieldLabel — never inside the
|
|
32
|
+
* input box (via InputGroupAddon) where it reads as part of the value, and never inside the
|
|
33
|
+
* label (AILabelTrigger is a button). The Input itself stays plain: no `shadow-ai-glow` or
|
|
34
|
+
* gradient border — that boundary glow is reserved for card-like AI surfaces (Card, Dialog),
|
|
35
|
+
* never form controls, where it fights the field's own focus/invalid rings. Pass AILabel
|
|
36
|
+
* `edited={value !== aiValue}` and an `onRevert` that restores it, so once the user edits the
|
|
37
|
+
* marker becomes a ghost undo button (AILabel's own override/undo morph). See AI/Input.
|
|
38
|
+
*
|
|
39
|
+
* USAGE
|
|
40
|
+
* <Input placeholder="Email" type="email" />
|
|
41
|
+
* <Input aria-invalid defaultValue="not-an-email" />
|
|
42
|
+
* <Input size="sm" placeholder="Compact row" />
|
|
43
|
+
*/
|
|
44
|
+
//#endregion
|
|
45
|
+
export { Input };
|
|
46
|
+
|
|
47
|
+
//# sourceMappingURL=input.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"input.js","names":[],"sources":["../../../src/components/ui/input.tsx"],"sourcesContent":["/**\n * Input — single-line text field.\n *\n * A plain native `<input>` with MMDS border/focus/error styling. Error state\n * is driven purely off `aria-invalid`\n * (no separate `error` prop), there is no built-in icon/affix slot, and a\n * `size` prop (\"default\" | \"sm\" | \"xs\") matching Select/Combobox/NativeSelect's\n * own height/radius steps — default and sm share text size, only xs drops it.\n * Omits the native `size` (character-width) attribute `<input>` normally has,\n * same as ComboboxInput does, since that name is repurposed for this instead.\n */\n\nimport * as React from \"react\"\n\nimport { cn } from \"@/lib/utils\"\n\nfunction Input({\n className,\n type,\n size = \"default\",\n ...props\n}: Omit<React.ComponentProps<\"input\">, \"size\"> & {\n size?: \"default\" | \"sm\" | \"xs\"\n}) {\n return (\n <input\n type={type}\n data-slot=\"input\"\n data-size={size}\n className={cn(\n \"h-8 w-full min-w-0 rounded-lg border border-input bg-transparent px-2.5 py-1 text-base transition-colors outline-none file:inline-flex file:h-6 file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-muted-foreground 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 md:text-sm dark:bg-input/30 dark:disabled:bg-input/80 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40\",\n // Same height/radius steps as Select/Combobox at matching sizes, so\n // an Input and a Select in the same form row line up. xs also drops\n // text size at every viewport (both the mobile text-base and the\n // md:text-sm above) — sm keeps the default text, only height/radius\n // tighten, same as Select's own sm step.\n \"data-[size=sm]:h-7 data-[size=sm]:rounded-[min(var(--radius-md,0.375rem),10px)] data-[size=xs]:h-6 data-[size=xs]:px-2 data-[size=xs]:text-xs data-[size=xs]:md:text-xs data-[size=xs]:rounded-[min(var(--radius-md,0.375rem),8px)]\",\n className\n )}\n {...props}\n />\n )\n}\n\nexport { Input }\n\n/**\n * WHEN TO USE\n * - Short free text: names, emails, search queries, numeric values\n * - Any native `type` (text, email, password, number, file, ...) — styling is type-agnostic\n *\n * NOT WHEN\n * - Multi-line content — use Textarea\n * - A fixed set of choices — use Select or Combobox\n * - Needs a leading/trailing icon, prefix, or attached button — wrap in InputGroup instead of adding children here (Input renders no slots of its own)\n *\n * KEY RULES\n * - Error state is driven entirely by `aria-invalid` — there is no `error` prop\n * - Always pair with a Label (via htmlFor) or wrap in Field for validation messaging\n * - size: default | sm | xs (default \"default\") — same height/radius steps as\n * Select/Combobox/NativeSelect, so they line up in the same form row. default\n * and sm share text size; xs also drops to text-xs.\n * - An AI-filled value is a plain composition, not a dedicated prop, and the same shape as\n * Textarea's: put `AILabel` in the label row as a sibling of FieldLabel — never inside the\n * input box (via InputGroupAddon) where it reads as part of the value, and never inside the\n * label (AILabelTrigger is a button). The Input itself stays plain: no `shadow-ai-glow` or\n * gradient border — that boundary glow is reserved for card-like AI surfaces (Card, Dialog),\n * never form controls, where it fights the field's own focus/invalid rings. Pass AILabel\n * `edited={value !== aiValue}` and an `onRevert` that restores it, so once the user edits the\n * marker becomes a ghost undo button (AILabel's own override/undo morph). See AI/Input.\n *\n * USAGE\n * <Input placeholder=\"Email\" type=\"email\" />\n * <Input aria-invalid defaultValue=\"not-an-email\" />\n * <Input size=\"sm\" placeholder=\"Compact row\" />\n */\n"],"mappings":";;;;AAgBA,SAAS,MAAM,EACb,WACA,MACA,OAAO,WACP,GAAG,SAGF;CACD,OACE,oBAAC,SAAD;EACQ;EACN,aAAU;EACV,aAAW;EACX,WAAW,GACT,+oBAMA,uOACA,SACF;EACA,GAAI;CACL,CAAA;AAEL"}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Item — row for an entity in a list: media, text, and actions.
|
|
3
|
+
*
|
|
4
|
+
* cva-driven `div` (or `Slot` via `asChild`), no external primitive.
|
|
5
|
+
* `ItemMedia` has `default` | `icon` | `image` variants only — there is no
|
|
6
|
+
* separate `avatar` variant, so an `<Avatar>` goes in a plain (`default`)
|
|
7
|
+
* `ItemMedia`.
|
|
8
|
+
*/
|
|
9
|
+
import * as React from "react";
|
|
10
|
+
import { type VariantProps } from "class-variance-authority";
|
|
11
|
+
import { Separator } from "../../components/ui/separator";
|
|
12
|
+
declare function ItemGroup({ className, ...props }: React.ComponentProps<"div">): React.JSX.Element;
|
|
13
|
+
declare function ItemSeparator({ className, ...props }: React.ComponentProps<typeof Separator>): React.JSX.Element;
|
|
14
|
+
declare const itemVariants: (props?: ({
|
|
15
|
+
variant?: "default" | "outline" | "muted" | null | undefined;
|
|
16
|
+
size?: "sm" | "default" | "xs" | null | undefined;
|
|
17
|
+
} & import("class-variance-authority/types").ClassProp) | undefined) => string;
|
|
18
|
+
declare function Item({ className, variant, size, asChild, ...props }: React.ComponentProps<"div"> & VariantProps<typeof itemVariants> & {
|
|
19
|
+
asChild?: boolean;
|
|
20
|
+
}): React.JSX.Element;
|
|
21
|
+
declare const itemMediaVariants: (props?: ({
|
|
22
|
+
variant?: "image" | "default" | "icon" | null | undefined;
|
|
23
|
+
} & import("class-variance-authority/types").ClassProp) | undefined) => string;
|
|
24
|
+
declare function ItemMedia({ className, variant, ...props }: React.ComponentProps<"div"> & VariantProps<typeof itemMediaVariants>): React.JSX.Element;
|
|
25
|
+
declare function ItemContent({ className, ...props }: React.ComponentProps<"div">): React.JSX.Element;
|
|
26
|
+
declare function ItemTitle({ className, ...props }: React.ComponentProps<"div">): React.JSX.Element;
|
|
27
|
+
declare function ItemDescription({ className, ...props }: React.ComponentProps<"p">): React.JSX.Element;
|
|
28
|
+
declare function ItemActions({ className, ...props }: React.ComponentProps<"div">): React.JSX.Element;
|
|
29
|
+
declare function ItemHeader({ className, ...props }: React.ComponentProps<"div">): React.JSX.Element;
|
|
30
|
+
declare function ItemFooter({ className, ...props }: React.ComponentProps<"div">): React.JSX.Element;
|
|
31
|
+
export { Item, ItemMedia, ItemContent, ItemActions, ItemGroup, ItemSeparator, ItemTitle, ItemDescription, ItemHeader, ItemFooter, };
|
|
32
|
+
/**
|
|
33
|
+
* WHEN TO USE
|
|
34
|
+
* - An entity list where each row has media, text, and actions — settings
|
|
35
|
+
* rows, search results, member lists, file/folder rows.
|
|
36
|
+
*
|
|
37
|
+
* NOT WHEN
|
|
38
|
+
* - Columnar data that needs alignment across rows — use Table.
|
|
39
|
+
* - A single grouped panel of content — use Card.
|
|
40
|
+
* - The row is a form control (checkbox, input, radio, select) — use Field.
|
|
41
|
+
*
|
|
42
|
+
* KEY RULES
|
|
43
|
+
* - Three sizes (default, sm, xs) and three variants (default, outline,
|
|
44
|
+
* muted) — `xs` is dense enough to use inside a dropdown-menu content
|
|
45
|
+
* area with zero padding.
|
|
46
|
+
* - `ItemMedia variant="icon"` auto-sizes any un-sized svg to `size-4`;
|
|
47
|
+
* `variant="image"` clips to a rounded square that shrinks with `size`.
|
|
48
|
+
* - `ItemGroup` sets `role="list"` and controls row gap by size — use it
|
|
49
|
+
* (not a plain `div`) whenever stacking more than one Item. Item only sets
|
|
50
|
+
* `role="listitem"` on itself when actually rendered inside an ItemGroup
|
|
51
|
+
* (detected via context) — a standalone Item outside any group stays role-less,
|
|
52
|
+
* since a bare `listitem` with no `list` ancestor is its own ARIA violation.
|
|
53
|
+
* - `ItemSeparator` is Separator pre-styled with `my-2` — use it between
|
|
54
|
+
* rows in a group instead of a raw `<Separator />`.
|
|
55
|
+
*
|
|
56
|
+
* USAGE
|
|
57
|
+
* <Item>
|
|
58
|
+
* <ItemMedia variant="icon"><FolderIcon /></ItemMedia>
|
|
59
|
+
* <ItemContent>
|
|
60
|
+
* <ItemTitle>Design tokens</ItemTitle>
|
|
61
|
+
* <ItemDescription>Colors, radius and typography.</ItemDescription>
|
|
62
|
+
* </ItemContent>
|
|
63
|
+
* <ItemActions>
|
|
64
|
+
* <Button variant="ghost" size="sm" iconOnly aria-label="Open"><ChevronRightIcon /></Button>
|
|
65
|
+
* </ItemActions>
|
|
66
|
+
* </Item>
|
|
67
|
+
*
|
|
68
|
+
* <ItemGroup className="rounded-xl border">
|
|
69
|
+
* <Item>...</Item>
|
|
70
|
+
* <ItemSeparator />
|
|
71
|
+
* <Item>...</Item>
|
|
72
|
+
* </ItemGroup>
|
|
73
|
+
*/
|
|
74
|
+
//# sourceMappingURL=item.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"item.d.ts","sourceRoot":"","sources":["../../../src/components/ui/item.tsx"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAC9B,OAAO,EAAO,KAAK,YAAY,EAAE,MAAM,0BAA0B,CAAA;AAIjE,OAAO,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAA;AAIrD,iBAAS,SAAS,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC,qBActE;AAED,iBAAS,aAAa,CAAC,EACrB,SAAS,EACT,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,SAAS,CAAC,qBASxC;AAED,QAAA,MAAM,YAAY;;;8EAoBjB,CAAA;AAED,iBAAS,IAAI,CAAC,EACZ,SAAS,EACT,OAAmB,EACnB,IAAgB,EAChB,OAAe,EACf,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC,GAC5B,YAAY,CAAC,OAAO,YAAY,CAAC,GAAG;IAAE,OAAO,CAAC,EAAE,OAAO,CAAA;CAAE,qBAa1D;AAED,QAAA,MAAM,iBAAiB;;8EAetB,CAAA;AAED,iBAAS,SAAS,CAAC,EACjB,SAAS,EACT,OAAmB,EACnB,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC,GAAG,YAAY,CAAC,OAAO,iBAAiB,CAAC,qBAStE;AAED,iBAAS,WAAW,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC,qBAWxE;AAED,iBAAS,SAAS,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC,qBAWtE;AAED,iBAAS,eAAe,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,KAAK,CAAC,cAAc,CAAC,GAAG,CAAC,qBAW1E;AAED,iBAAS,WAAW,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC,qBAQxE;AAED,iBAAS,UAAU,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC,qBAWvE;AAED,iBAAS,UAAU,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC,qBAWvE;AAED,OAAO,EACL,IAAI,EACJ,SAAS,EACT,WAAW,EACX,WAAW,EACX,SAAS,EACT,aAAa,EACb,SAAS,EACT,eAAe,EACf,UAAU,EACV,UAAU,GACX,CAAA;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyCG"}
|