@craftzbay/ui 0.9.0 → 0.11.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 +82 -10
- package/dist-lib/__tests__/helpers/color.d.ts +9 -0
- package/dist-lib/__tests__/helpers/theme.d.ts +18 -0
- package/dist-lib/components/ui/Accordion.js +71 -0
- package/dist-lib/components/ui/Accordion.js.map +1 -0
- package/dist-lib/components/ui/Alert.d.ts +17 -1
- package/dist-lib/components/ui/Alert.js +79 -0
- package/dist-lib/components/ui/Alert.js.map +1 -0
- package/dist-lib/components/ui/Avatar.d.ts +3 -3
- package/dist-lib/components/ui/Avatar.js +94 -0
- package/dist-lib/components/ui/Avatar.js.map +1 -0
- package/dist-lib/components/ui/Badge.d.ts +4 -2
- package/dist-lib/components/ui/Badge.js +76 -0
- package/dist-lib/components/ui/Badge.js.map +1 -0
- package/dist-lib/components/ui/Breadcrumbs.d.ts +2 -0
- package/dist-lib/components/ui/Breadcrumbs.js +52 -0
- package/dist-lib/components/ui/Breadcrumbs.js.map +1 -0
- package/dist-lib/components/ui/Button.d.ts +6 -4
- package/dist-lib/components/ui/Button.js +131 -0
- package/dist-lib/components/ui/Button.js.map +1 -0
- package/dist-lib/components/ui/Calendar.d.ts +7 -1
- package/dist-lib/components/ui/Calendar.js +139 -0
- package/dist-lib/components/ui/Calendar.js.map +1 -0
- package/dist-lib/components/ui/Card.d.ts +3 -1
- package/dist-lib/components/ui/Card.js +97 -0
- package/dist-lib/components/ui/Card.js.map +1 -0
- package/dist-lib/components/ui/Carousel.d.ts +11 -7
- package/dist-lib/components/ui/Carousel.js +174 -0
- package/dist-lib/components/ui/Carousel.js.map +1 -0
- package/dist-lib/components/ui/Chart.d.ts +68 -7
- package/dist-lib/components/ui/Chart.js +487 -0
- package/dist-lib/components/ui/Chart.js.map +1 -0
- package/dist-lib/components/ui/Checkbox.js +70 -0
- package/dist-lib/components/ui/Checkbox.js.map +1 -0
- package/dist-lib/components/ui/Combobox.d.ts +9 -0
- package/dist-lib/components/ui/Combobox.js +195 -0
- package/dist-lib/components/ui/Combobox.js.map +1 -0
- package/dist-lib/components/ui/CommandPalette.d.ts +9 -6
- package/dist-lib/components/ui/CommandPalette.js +179 -0
- package/dist-lib/components/ui/CommandPalette.js.map +1 -0
- package/dist-lib/components/ui/ContextMenu.d.ts +7 -2
- package/dist-lib/components/ui/ContextMenu.js +165 -0
- package/dist-lib/components/ui/ContextMenu.js.map +1 -0
- package/dist-lib/components/ui/DataGrid.d.ts +17 -4
- package/dist-lib/components/ui/DataGrid.js +99 -0
- package/dist-lib/components/ui/DataGrid.js.map +1 -0
- package/dist-lib/components/ui/DatePicker.d.ts +16 -13
- package/dist-lib/components/ui/DatePicker.js +193 -0
- package/dist-lib/components/ui/DatePicker.js.map +1 -0
- package/dist-lib/components/ui/DesignSystemProvider.d.ts +102 -41
- package/dist-lib/components/ui/DesignSystemProvider.js +135 -0
- package/dist-lib/components/ui/DesignSystemProvider.js.map +1 -0
- package/dist-lib/components/ui/Dialog.d.ts +19 -4
- package/dist-lib/components/ui/Dialog.js +165 -0
- package/dist-lib/components/ui/Dialog.js.map +1 -0
- package/dist-lib/components/ui/Drawer.d.ts +23 -2
- package/dist-lib/components/ui/Drawer.js +132 -0
- package/dist-lib/components/ui/Drawer.js.map +1 -0
- package/dist-lib/components/ui/DropdownMenu.js +169 -0
- package/dist-lib/components/ui/DropdownMenu.js.map +1 -0
- package/dist-lib/components/ui/EmptyState.d.ts +2 -0
- package/dist-lib/components/ui/EmptyState.js +46 -0
- package/dist-lib/components/ui/EmptyState.js.map +1 -0
- package/dist-lib/components/ui/ErrorState.d.ts +13 -2
- package/dist-lib/components/ui/ErrorState.js +69 -0
- package/dist-lib/components/ui/ErrorState.js.map +1 -0
- package/dist-lib/components/ui/FileUpload.d.ts +3 -0
- package/dist-lib/components/ui/FileUpload.js +111 -0
- package/dist-lib/components/ui/FileUpload.js.map +1 -0
- package/dist-lib/components/ui/Form.d.ts +16 -2
- package/dist-lib/components/ui/Form.js +131 -0
- package/dist-lib/components/ui/Form.js.map +1 -0
- package/dist-lib/components/ui/Icon.d.ts +1 -1
- package/dist-lib/components/ui/Icon.js +32 -0
- package/dist-lib/components/ui/Icon.js.map +1 -0
- package/dist-lib/components/ui/IconButton.d.ts +3 -3
- package/dist-lib/components/ui/IconButton.js +64 -0
- package/dist-lib/components/ui/IconButton.js.map +1 -0
- package/dist-lib/components/ui/Input.d.ts +9 -4
- package/dist-lib/components/ui/Input.js +149 -0
- package/dist-lib/components/ui/Input.js.map +1 -0
- package/dist-lib/components/ui/Kbd.js +24 -0
- package/dist-lib/components/ui/Kbd.js.map +1 -0
- package/dist-lib/components/ui/MultiSelect.d.ts +3 -1
- package/dist-lib/components/ui/MultiSelect.js +210 -0
- package/dist-lib/components/ui/MultiSelect.js.map +1 -0
- package/dist-lib/components/ui/Pagination.d.ts +23 -0
- package/dist-lib/components/ui/Pagination.js +153 -0
- package/dist-lib/components/ui/Pagination.js.map +1 -0
- package/dist-lib/components/ui/Popover.js +35 -0
- package/dist-lib/components/ui/Popover.js.map +1 -0
- package/dist-lib/components/ui/Progress.d.ts +3 -3
- package/dist-lib/components/ui/Progress.js +100 -0
- package/dist-lib/components/ui/Progress.js.map +1 -0
- package/dist-lib/components/ui/RadioGroup.d.ts +1 -1
- package/dist-lib/components/ui/RadioGroup.js +81 -0
- package/dist-lib/components/ui/RadioGroup.js.map +1 -0
- package/dist-lib/components/ui/RelativeTime.d.ts +19 -0
- package/dist-lib/components/ui/RelativeTime.js +31 -0
- package/dist-lib/components/ui/RelativeTime.js.map +1 -0
- package/dist-lib/components/ui/ScrollArea.d.ts +9 -1
- package/dist-lib/components/ui/ScrollArea.js +60 -0
- package/dist-lib/components/ui/ScrollArea.js.map +1 -0
- package/dist-lib/components/ui/Select.d.ts +6 -1
- package/dist-lib/components/ui/Select.js +139 -0
- package/dist-lib/components/ui/Select.js.map +1 -0
- package/dist-lib/components/ui/Separator.js +26 -0
- package/dist-lib/components/ui/Separator.js.map +1 -0
- package/dist-lib/components/ui/Sheet.d.ts +10 -1
- package/dist-lib/components/ui/Sheet.js +136 -0
- package/dist-lib/components/ui/Sheet.js.map +1 -0
- package/dist-lib/components/ui/Sidebar.d.ts +29 -14
- package/dist-lib/components/ui/Sidebar.js +212 -0
- package/dist-lib/components/ui/Sidebar.js.map +1 -0
- package/dist-lib/components/ui/Skeleton.d.ts +13 -2
- package/dist-lib/components/ui/Skeleton.js +29 -0
- package/dist-lib/components/ui/Skeleton.js.map +1 -0
- package/dist-lib/components/ui/Slider.js +64 -0
- package/dist-lib/components/ui/Slider.js.map +1 -0
- package/dist-lib/components/ui/Snackbar.d.ts +1 -1
- package/dist-lib/components/ui/Snackbar.js +57 -0
- package/dist-lib/components/ui/Snackbar.js.map +1 -0
- package/dist-lib/components/ui/Spinner.js +54 -0
- package/dist-lib/components/ui/Spinner.js.map +1 -0
- package/dist-lib/components/ui/Stepper.d.ts +6 -0
- package/dist-lib/components/ui/Stepper.js +111 -0
- package/dist-lib/components/ui/Stepper.js.map +1 -0
- package/dist-lib/components/ui/Switch.js +80 -0
- package/dist-lib/components/ui/Switch.js.map +1 -0
- package/dist-lib/components/ui/Table.d.ts +41 -5
- package/dist-lib/components/ui/Table.js +179 -0
- package/dist-lib/components/ui/Table.js.map +1 -0
- package/dist-lib/components/ui/Tabs.d.ts +1 -1
- package/dist-lib/components/ui/Tabs.js +91 -0
- package/dist-lib/components/ui/Tabs.js.map +1 -0
- package/dist-lib/components/ui/TagInput.d.ts +17 -2
- package/dist-lib/components/ui/TagInput.js +111 -0
- package/dist-lib/components/ui/TagInput.js.map +1 -0
- package/dist-lib/components/ui/Textarea.js +88 -0
- package/dist-lib/components/ui/Textarea.js.map +1 -0
- package/dist-lib/components/ui/Timeline.d.ts +16 -6
- package/dist-lib/components/ui/Timeline.js +56 -0
- package/dist-lib/components/ui/Timeline.js.map +1 -0
- package/dist-lib/components/ui/Toast.d.ts +1 -1
- package/dist-lib/components/ui/Toast.js +158 -0
- package/dist-lib/components/ui/Toast.js.map +1 -0
- package/dist-lib/components/ui/Tooltip.d.ts +4 -1
- package/dist-lib/components/ui/Tooltip.js +60 -0
- package/dist-lib/components/ui/Tooltip.js.map +1 -0
- package/dist-lib/components/ui/TopNav.d.ts +7 -3
- package/dist-lib/components/ui/TopNav.js +62 -0
- package/dist-lib/components/ui/TopNav.js.map +1 -0
- package/dist-lib/components/ui/Tree.d.ts +34 -7
- package/dist-lib/components/ui/Tree.js +170 -0
- package/dist-lib/components/ui/Tree.js.map +1 -0
- package/dist-lib/hooks/use-debounce.d.ts +19 -0
- package/dist-lib/hooks/use-debounce.js +36 -0
- package/dist-lib/hooks/use-debounce.js.map +1 -0
- package/dist-lib/hooks/use-delayed-loading.d.ts +21 -0
- package/dist-lib/hooks/use-delayed-loading.js +20 -0
- package/dist-lib/hooks/use-delayed-loading.js.map +1 -0
- package/dist-lib/hooks/use-field-ids.d.ts +30 -0
- package/dist-lib/hooks/use-field-ids.js +18 -0
- package/dist-lib/hooks/use-field-ids.js.map +1 -0
- package/dist-lib/hooks/use-media-query.d.ts +3 -1
- package/dist-lib/hooks/use-media-query.js +22 -0
- package/dist-lib/hooks/use-media-query.js.map +1 -0
- package/dist-lib/hooks/use-modifier-key.d.ts +13 -0
- package/dist-lib/hooks/use-modifier-key.js +19 -0
- package/dist-lib/hooks/use-modifier-key.js.map +1 -0
- package/dist-lib/hooks/use-strings.d.ts +5 -0
- package/dist-lib/hooks/use-strings.js +12 -0
- package/dist-lib/hooks/use-strings.js.map +1 -0
- package/dist-lib/hooks/use-toast.d.ts +7 -2
- package/dist-lib/hooks/use-toast.js +67 -0
- package/dist-lib/hooks/use-toast.js.map +1 -0
- package/dist-lib/icon.d.ts +8 -0
- package/dist-lib/icon.js +7 -0
- package/dist-lib/icon.js.map +1 -0
- package/dist-lib/icons/index.d.ts +80 -88
- package/dist-lib/icons/index.js +163 -0
- package/dist-lib/icons/index.js.map +1 -0
- package/dist-lib/illustrations/index.d.ts +1 -0
- package/dist-lib/illustrations/index.js +114 -0
- package/dist-lib/illustrations/index.js.map +1 -0
- package/dist-lib/index.d.ts +68 -59
- package/dist-lib/index.js +288 -4530
- package/dist-lib/index.js.map +1 -1
- package/dist-lib/lib/format.d.ts +65 -0
- package/dist-lib/lib/format.js +95 -0
- package/dist-lib/lib/format.js.map +1 -0
- package/dist-lib/lib/return-focus.d.ts +11 -0
- package/dist-lib/lib/return-focus.js +12 -0
- package/dist-lib/lib/return-focus.js.map +1 -0
- package/dist-lib/lib/strings.d.ts +190 -0
- package/dist-lib/lib/strings.js +141 -0
- package/dist-lib/lib/strings.js.map +1 -0
- package/dist-lib/lib/strings.mn.d.ts +3 -0
- package/dist-lib/lib/strings.mn.js +115 -0
- package/dist-lib/lib/strings.mn.js.map +1 -0
- package/dist-lib/lib/utils.d.ts +0 -1
- package/dist-lib/lib/utils.js +10 -0
- package/dist-lib/lib/utils.js.map +1 -0
- package/dist-lib/styles.css +1 -1
- package/dist-lib/theme.css +840 -0
- package/package.json +38 -8
- package/dist-lib/index.cjs +0 -8
- package/dist-lib/index.cjs.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Checkbox.js","sources":["../../../src/components/ui/Checkbox.tsx"],"sourcesContent":["'use client';\n\nimport {\n forwardRef,\n useId,\n type ComponentPropsWithoutRef,\n type ElementRef,\n type ReactNode,\n} from 'react';\nimport * as CheckboxPrimitive from '@radix-ui/react-checkbox';\nimport { Check, Minus } from '@/icons';\nimport { cn } from '@/lib/utils';\n\nexport interface CheckboxProps extends Omit<\n ComponentPropsWithoutRef<typeof CheckboxPrimitive.Root>,\n 'asChild'\n> {\n /** Visible label rendered to the right of the box. */\n label?: ReactNode;\n /** Secondary description rendered below the label. */\n description?: ReactNode;\n /** Validation error message. */\n error?: ReactNode;\n /** Hide the label visually while keeping it in the a11y tree. */\n hideLabel?: boolean;\n}\n\n/**\n * Checkbox with optional inline label + description. Pass `checked=\"indeterminate\"`\n * for the indeterminate state — Radix renders a `Minus` icon automatically.\n *\n * @example Single\n * <Checkbox label=\"I agree to the terms\" checked={ok} onCheckedChange={setOk} />\n *\n * @example Tri-state header\n * <Checkbox aria-label=\"Select all\"\n * checked={allSelected ? true : someSelected ? 'indeterminate' : false}\n * onCheckedChange={toggleAll} />\n *\n * @do Use indeterminate to summarise child rows in a table header.\n * @dont Use a Checkbox for mutually exclusive choices — use RadioGroup.\n */\nexport const Checkbox = forwardRef<ElementRef<typeof CheckboxPrimitive.Root>, CheckboxProps>(\n function Checkbox(\n {\n className,\n label,\n description,\n error,\n hideLabel,\n id,\n disabled,\n 'aria-describedby': ariaDescribedby,\n 'aria-invalid': ariaInvalid,\n ...props\n },\n ref,\n ) {\n const autoId = useId();\n const fieldId = id ?? autoId;\n const descId = description ? `${fieldId}-desc` : undefined;\n const errorId = error ? `${fieldId}-error` : undefined;\n const describedBy = [errorId, descId, ariaDescribedby].filter(Boolean).join(' ') || undefined;\n const isError = Boolean(error) || ariaInvalid === true || ariaInvalid === 'true';\n\n return (\n <div className={cn('flex flex-col gap-1', className)}>\n <div className=\"flex items-start gap-2.5\">\n <CheckboxPrimitive.Root\n ref={ref}\n id={fieldId}\n disabled={disabled}\n aria-describedby={describedBy}\n aria-invalid={isError ? true : ariaInvalid}\n className={cn(\n 'peer relative mt-0.5 flex size-4 shrink-0 items-center justify-center rounded-sm border',\n // WCAG 2.5.8: 16px visual box, ≥24px hit area via an invisible inset halo.\n 'before:absolute before:-inset-1.5 before:content-[\"\"]',\n 'transition-colors duration-[var(--duration-fast)] ease-[var(--ease-out)]',\n 'focus-visible:ring-ring focus-visible:ring-offset-background outline-none focus-visible:ring-2 focus-visible:ring-offset-2',\n 'data-[state=checked]:bg-accent data-[state=checked]:border-accent data-[state=checked]:text-on-accent',\n 'data-[state=indeterminate]:bg-accent data-[state=indeterminate]:border-accent data-[state=indeterminate]:text-on-accent',\n 'disabled:cursor-not-allowed disabled:opacity-50',\n 'border-border-input aria-invalid:border-danger',\n )}\n {...props}\n >\n <CheckboxPrimitive.Indicator className=\"flex items-center justify-center\">\n {props.checked === 'indeterminate' ? (\n <Minus className=\"size-3\" aria-hidden strokeWidth={3} />\n ) : (\n <Check className=\"size-3\" aria-hidden strokeWidth={3} />\n )}\n </CheckboxPrimitive.Indicator>\n </CheckboxPrimitive.Root>\n\n {label && (\n <div className=\"flex flex-col gap-0.5\">\n <label\n htmlFor={fieldId}\n className={cn(\n 'text-foreground text-sm select-none',\n disabled && 'cursor-not-allowed opacity-50',\n hideLabel && 'sr-only',\n )}\n >\n {label}\n </label>\n {description && (\n <p id={descId} className=\"text-foreground-subtle text-xs\">\n {description}\n </p>\n )}\n </div>\n )}\n </div>\n {error && (\n <p id={errorId} className=\"text-danger-text text-xs\">\n {error}\n </p>\n )}\n </div>\n );\n },\n);\n\nCheckbox.displayName = 'Checkbox';\n"],"names":["Checkbox","forwardRef","className","label","description","error","hideLabel","id","disabled","ariaDescribedby","ariaInvalid","props","ref","autoId","useId","fieldId","descId","errorId","describedBy","isError","cn","jsxs","jsx","CheckboxPrimitive","Minus","Check"],"mappings":";;;;;;AA0CO,MAAMA,IAAWC;AAAA,EACtB,SACE;AAAA,IACE,WAAAC;AAAA,IACA,OAAAC;AAAA,IACA,aAAAC;AAAA,IACA,OAAAC;AAAA,IACA,WAAAC;AAAA,IACA,IAAAC;AAAA,IACA,UAAAC;AAAA,IACA,oBAAoBC;AAAA,IACpB,gBAAgBC;AAAA,IAChB,GAAGC;AAAA,EAAA,GAELC,GACA;AACA,UAAMC,IAASC,EAAA,GACTC,IAAUR,KAAMM,GAChBG,IAASZ,IAAc,GAAGW,CAAO,UAAU,QAC3CE,IAAUZ,IAAQ,GAAGU,CAAO,WAAW,QACvCG,IAAc,CAACD,GAASD,GAAQP,CAAe,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG,KAAK,QAC9EU,IAAU,EAAQd,KAAUK,MAAgB,MAAQA,MAAgB;AAE1E,6BACG,OAAA,EAAI,WAAWU,EAAG,uBAAuBlB,CAAS,GACjD,UAAA;AAAA,MAAA,gBAAAmB,EAAC,OAAA,EAAI,WAAU,4BACb,UAAA;AAAA,QAAA,gBAAAC;AAAA,UAACC,EAAkB;AAAA,UAAlB;AAAA,YACC,KAAAX;AAAA,YACA,IAAIG;AAAA,YACJ,UAAAP;AAAA,YACA,oBAAkBU;AAAA,YAClB,gBAAcC,IAAU,KAAOT;AAAA,YAC/B,WAAWU;AAAA,cACT;AAAA;AAAA,cAEA;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,YAAA;AAAA,YAED,GAAGT;AAAA,YAEJ,UAAA,gBAAAW,EAACC,EAAkB,WAAlB,EAA4B,WAAU,oCACpC,UAAAZ,EAAM,YAAY,kBACjB,gBAAAW,EAACE,GAAA,EAAM,WAAU,UAAS,eAAW,IAAC,aAAa,EAAA,CAAG,IAEtD,gBAAAF,EAACG,GAAA,EAAM,WAAU,UAAS,eAAW,IAAC,aAAa,EAAA,CAAG,EAAA,CAE1D;AAAA,UAAA;AAAA,QAAA;AAAA,QAGDtB,KACC,gBAAAkB,EAAC,OAAA,EAAI,WAAU,yBACb,UAAA;AAAA,UAAA,gBAAAC;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,SAASP;AAAA,cACT,WAAWK;AAAA,gBACT;AAAA,gBACAZ,KAAY;AAAA,gBACZF,KAAa;AAAA,cAAA;AAAA,cAGd,UAAAH;AAAA,YAAA;AAAA,UAAA;AAAA,UAEFC,KACC,gBAAAkB,EAAC,KAAA,EAAE,IAAIN,GAAQ,WAAU,kCACtB,UAAAZ,EAAA,CACH;AAAA,QAAA,EAAA,CAEJ;AAAA,MAAA,GAEJ;AAAA,MACCC,KACC,gBAAAiB,EAAC,KAAA,EAAE,IAAIL,GAAS,WAAU,4BACvB,UAAAZ,EAAA,CACH;AAAA,IAAA,GAEJ;AAAA,EAEJ;AACF;AAEAL,EAAS,cAAc;"}
|
|
@@ -17,6 +17,11 @@ export interface ComboboxProps {
|
|
|
17
17
|
* Use for server-side search.
|
|
18
18
|
*/
|
|
19
19
|
loadOptions?: (query: string) => Promise<ComboboxOption[]>;
|
|
20
|
+
/**
|
|
21
|
+
* Label to show for a preset `value` in `loadOptions` mode before the
|
|
22
|
+
* first search has resolved (the component has no option list yet).
|
|
23
|
+
*/
|
|
24
|
+
selectedLabel?: string;
|
|
20
25
|
/** Visible label above the field. */
|
|
21
26
|
label?: ReactNode;
|
|
22
27
|
/** Hint below the field. Hidden when `error` is set. */
|
|
@@ -29,12 +34,16 @@ export interface ComboboxProps {
|
|
|
29
34
|
searchPlaceholder?: string;
|
|
30
35
|
/** Empty state copy when nothing matches. */
|
|
31
36
|
emptyText?: string;
|
|
37
|
+
/** Message shown when `loadOptions` rejects. */
|
|
38
|
+
loadErrorText?: string;
|
|
32
39
|
/** Allow clearing the selection with an inline ×. */
|
|
33
40
|
clearable?: boolean;
|
|
34
41
|
/** Disable the entire field. */
|
|
35
42
|
disabled?: boolean;
|
|
36
43
|
/** Field size, matches Input. */
|
|
37
44
|
size?: 'sm' | 'md' | 'lg';
|
|
45
|
+
/** Consumer-supplied id for the trigger (label association). */
|
|
46
|
+
id?: string;
|
|
38
47
|
className?: string;
|
|
39
48
|
}
|
|
40
49
|
/**
|
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsxs as o, jsx as r } from "react/jsx-runtime";
|
|
3
|
+
import { forwardRef as de, useState as s, useCallback as D, useMemo as M, useRef as ie, useEffect as Q } from "react";
|
|
4
|
+
import * as p from "@radix-ui/react-popover";
|
|
5
|
+
import { Command as f } from "cmdk";
|
|
6
|
+
import { X as ce, ChevronsUpDown as ue, Loader2 as me, Check as fe } from "../../icons/index.js";
|
|
7
|
+
import { cn as b } from "../../lib/utils.js";
|
|
8
|
+
import { useStrings as be } from "../../hooks/use-strings.js";
|
|
9
|
+
import { useFieldIds as xe } from "../../hooks/use-field-ids.js";
|
|
10
|
+
import { IconButton as pe } from "./IconButton.js";
|
|
11
|
+
const ge = de(function({
|
|
12
|
+
value: a,
|
|
13
|
+
onChange: g,
|
|
14
|
+
options: k,
|
|
15
|
+
loadOptions: l,
|
|
16
|
+
selectedLabel: h,
|
|
17
|
+
label: n,
|
|
18
|
+
helperText: v,
|
|
19
|
+
error: y,
|
|
20
|
+
placeholder: U,
|
|
21
|
+
searchPlaceholder: V,
|
|
22
|
+
emptyText: X,
|
|
23
|
+
loadErrorText: A,
|
|
24
|
+
clearable: z = !0,
|
|
25
|
+
disabled: L,
|
|
26
|
+
size: x = "md",
|
|
27
|
+
id: R,
|
|
28
|
+
className: G
|
|
29
|
+
}, J) {
|
|
30
|
+
const d = be(), N = U ?? d.combobox.placeholder, K = V ?? d.combobox.searchPlaceholder, W = X ?? d.combobox.empty, Y = A ?? d.combobox.loadError, w = !!y, { fieldId: c, helperId: Z, errorId: _, describedBy: O } = xe(R, {
|
|
31
|
+
hasHelper: !!v,
|
|
32
|
+
hasError: w
|
|
33
|
+
}), [ee, re] = s(void 0), te = D((e) => re(e == null ? void 0 : e.id), []), [u, B] = s(!1), [C, oe] = s(""), [S, j] = s([]), [I, F] = s(!1), [T, $] = s(!1), [m, H] = s(null), E = M(
|
|
34
|
+
() => l ? S : k ?? [],
|
|
35
|
+
[l, S, k]
|
|
36
|
+
), q = ie(l);
|
|
37
|
+
Q(() => {
|
|
38
|
+
q.current = l;
|
|
39
|
+
}), Q(() => {
|
|
40
|
+
const e = q.current;
|
|
41
|
+
if (!e || !u) return;
|
|
42
|
+
let t = !1;
|
|
43
|
+
return F(!0), $(!1), e(C).then((P) => {
|
|
44
|
+
t || j(P);
|
|
45
|
+
}).catch(() => {
|
|
46
|
+
t || (j([]), $(!0));
|
|
47
|
+
}).finally(() => {
|
|
48
|
+
t || F(!1);
|
|
49
|
+
}), () => {
|
|
50
|
+
t = !0;
|
|
51
|
+
};
|
|
52
|
+
}, [C, u, !!l]);
|
|
53
|
+
const i = M(() => {
|
|
54
|
+
if (a == null) return null;
|
|
55
|
+
const e = E.find((t) => t.value === a);
|
|
56
|
+
return e || ((m == null ? void 0 : m.value) === a ? m : h !== void 0 ? { value: a, label: h } : null);
|
|
57
|
+
}, [E, a, m, h]), ae = x === "sm" ? "h-8" : x === "lg" ? "h-10" : "h-9", se = x === "sm" ? "px-2.5" : x === "lg" ? "px-3.5" : "px-3", le = z ? "pr-14" : "pr-9", ne = D(() => {
|
|
58
|
+
H(null), g(null);
|
|
59
|
+
}, [g]);
|
|
60
|
+
return /* @__PURE__ */ o("div", { ref: J, className: b("flex flex-col gap-1.5", G), children: [
|
|
61
|
+
n && /* @__PURE__ */ r(
|
|
62
|
+
"label",
|
|
63
|
+
{
|
|
64
|
+
id: `${c}-label`,
|
|
65
|
+
htmlFor: c,
|
|
66
|
+
className: "text-foreground text-sm font-medium",
|
|
67
|
+
children: n
|
|
68
|
+
}
|
|
69
|
+
),
|
|
70
|
+
/* @__PURE__ */ o(p.Root, { open: u, onOpenChange: B, children: [
|
|
71
|
+
/* @__PURE__ */ o("div", { className: "relative w-full", children: [
|
|
72
|
+
/* @__PURE__ */ r(p.Trigger, { asChild: !0, children: /* @__PURE__ */ r(
|
|
73
|
+
"button",
|
|
74
|
+
{
|
|
75
|
+
id: c,
|
|
76
|
+
type: "button",
|
|
77
|
+
role: "combobox",
|
|
78
|
+
"aria-expanded": u,
|
|
79
|
+
"aria-haspopup": "listbox",
|
|
80
|
+
"aria-controls": u ? ee : void 0,
|
|
81
|
+
"aria-labelledby": n ? `${c}-label` : void 0,
|
|
82
|
+
"aria-label": n || R ? void 0 : N,
|
|
83
|
+
"aria-invalid": w || void 0,
|
|
84
|
+
"aria-describedby": O,
|
|
85
|
+
disabled: L,
|
|
86
|
+
className: b(
|
|
87
|
+
"bg-card text-foreground inline-flex w-full items-center justify-between gap-2 rounded-md border text-sm",
|
|
88
|
+
"transition-colors duration-[var(--duration-fast)] ease-[var(--ease-out)]",
|
|
89
|
+
"focus-visible:ring-offset-background outline-none focus-visible:ring-2 focus-visible:ring-offset-2",
|
|
90
|
+
"disabled:cursor-not-allowed disabled:opacity-50",
|
|
91
|
+
ae,
|
|
92
|
+
se,
|
|
93
|
+
le,
|
|
94
|
+
w ? "border-danger focus-visible:border-danger focus-visible:ring-danger" : "border-border-input focus-visible:border-accent focus-visible:ring-ring"
|
|
95
|
+
),
|
|
96
|
+
children: /* @__PURE__ */ r(
|
|
97
|
+
"span",
|
|
98
|
+
{
|
|
99
|
+
className: b("truncate", !i && "text-foreground-subtle"),
|
|
100
|
+
title: i ? i.label : void 0,
|
|
101
|
+
children: i ? i.label : N
|
|
102
|
+
}
|
|
103
|
+
)
|
|
104
|
+
}
|
|
105
|
+
) }),
|
|
106
|
+
/* @__PURE__ */ o("span", { className: "pointer-events-none absolute inset-y-0 right-0 flex items-center gap-0.5 pr-2", children: [
|
|
107
|
+
z && i && !L && /* @__PURE__ */ r(
|
|
108
|
+
pe,
|
|
109
|
+
{
|
|
110
|
+
size: "sm",
|
|
111
|
+
variant: "ghost",
|
|
112
|
+
"aria-label": d.combobox.clear,
|
|
113
|
+
icon: /* @__PURE__ */ r(ce, {}),
|
|
114
|
+
onClick: ne,
|
|
115
|
+
className: "text-foreground-subtle hover:text-foreground pointer-events-auto size-6"
|
|
116
|
+
}
|
|
117
|
+
),
|
|
118
|
+
/* @__PURE__ */ r(ue, { className: "text-foreground-subtle size-4", "aria-hidden": !0 })
|
|
119
|
+
] })
|
|
120
|
+
] }),
|
|
121
|
+
/* @__PURE__ */ r(p.Portal, { children: /* @__PURE__ */ r(
|
|
122
|
+
p.Content,
|
|
123
|
+
{
|
|
124
|
+
"aria-labelledby": n ? `${c}-label` : void 0,
|
|
125
|
+
"aria-label": n ? void 0 : N,
|
|
126
|
+
align: "start",
|
|
127
|
+
sideOffset: 4,
|
|
128
|
+
className: b(
|
|
129
|
+
"border-border bg-popover text-popover-foreground z-[var(--z-popover)] w-[var(--radix-popover-trigger-width)] overflow-hidden rounded-lg border shadow-md",
|
|
130
|
+
"data-[state=open]:animate-in data-[state=closed]:animate-out",
|
|
131
|
+
"data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
|
|
132
|
+
"data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95"
|
|
133
|
+
),
|
|
134
|
+
children: /* @__PURE__ */ o(f, { shouldFilter: !l, className: "flex h-full w-full flex-col", children: [
|
|
135
|
+
/* @__PURE__ */ o("div", { className: "border-border flex items-center border-b px-3", children: [
|
|
136
|
+
/* @__PURE__ */ r(
|
|
137
|
+
f.Input,
|
|
138
|
+
{
|
|
139
|
+
value: C,
|
|
140
|
+
onValueChange: oe,
|
|
141
|
+
placeholder: K,
|
|
142
|
+
className: "placeholder:text-foreground-subtle flex h-9 w-full bg-transparent py-2 text-lg outline-none md:text-sm"
|
|
143
|
+
}
|
|
144
|
+
),
|
|
145
|
+
I && /* @__PURE__ */ r(me, { className: "text-foreground-subtle size-4 animate-spin", "aria-hidden": !0 })
|
|
146
|
+
] }),
|
|
147
|
+
/* @__PURE__ */ o(
|
|
148
|
+
f.List,
|
|
149
|
+
{
|
|
150
|
+
ref: te,
|
|
151
|
+
label: d.command.suggestions,
|
|
152
|
+
className: "max-h-64 overflow-y-auto p-1",
|
|
153
|
+
children: [
|
|
154
|
+
E.map((e) => {
|
|
155
|
+
const t = e.value === a;
|
|
156
|
+
return /* @__PURE__ */ o(
|
|
157
|
+
f.Item,
|
|
158
|
+
{
|
|
159
|
+
value: e.value,
|
|
160
|
+
keywords: e.description ? [e.label, e.description] : [e.label],
|
|
161
|
+
disabled: e.disabled,
|
|
162
|
+
onSelect: (P) => {
|
|
163
|
+
H(e), g(P), B(!1);
|
|
164
|
+
},
|
|
165
|
+
className: b(
|
|
166
|
+
"text-foreground flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm",
|
|
167
|
+
"data-[selected=true]:bg-background-muted",
|
|
168
|
+
"data-[disabled=true]:pointer-events-none data-[disabled=true]:opacity-50"
|
|
169
|
+
),
|
|
170
|
+
children: [
|
|
171
|
+
/* @__PURE__ */ r("span", { className: "flex-1", children: e.label }),
|
|
172
|
+
e.description && /* @__PURE__ */ r("span", { className: "text-foreground-subtle text-xs", children: e.description }),
|
|
173
|
+
t && /* @__PURE__ */ r(fe, { className: "text-accent size-4", "aria-hidden": !0 })
|
|
174
|
+
]
|
|
175
|
+
},
|
|
176
|
+
e.value
|
|
177
|
+
);
|
|
178
|
+
}),
|
|
179
|
+
T && !I && /* @__PURE__ */ r("div", { className: "text-danger-text px-2 py-6 text-center text-sm", children: Y }),
|
|
180
|
+
!I && !T && /* @__PURE__ */ r(f.Empty, { className: "text-foreground-subtle px-2 py-6 text-center text-sm", children: W })
|
|
181
|
+
]
|
|
182
|
+
}
|
|
183
|
+
)
|
|
184
|
+
] })
|
|
185
|
+
}
|
|
186
|
+
) })
|
|
187
|
+
] }),
|
|
188
|
+
y ? /* @__PURE__ */ r("p", { id: _, className: "text-danger-text text-xs", children: y }) : v ? /* @__PURE__ */ r("p", { id: Z, className: "text-foreground-subtle text-xs", children: v }) : null
|
|
189
|
+
] });
|
|
190
|
+
});
|
|
191
|
+
ge.displayName = "Combobox";
|
|
192
|
+
export {
|
|
193
|
+
ge as Combobox
|
|
194
|
+
};
|
|
195
|
+
//# sourceMappingURL=Combobox.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Combobox.js","sources":["../../../src/components/ui/Combobox.tsx"],"sourcesContent":["'use client';\n\nimport {\n forwardRef,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n type ReactNode,\n} from 'react';\nimport * as PopoverPrimitive from '@radix-ui/react-popover';\nimport { Command as CommandPrimitive } from 'cmdk';\nimport { Check, ChevronsUpDown, Loader2, X } from '@/icons';\nimport { cn } from '@/lib/utils';\nimport { useStrings } from '@/hooks/use-strings';\nimport { useFieldIds } from '@/hooks/use-field-ids';\nimport { IconButton } from './IconButton';\n\nexport interface ComboboxOption {\n value: string;\n label: string;\n description?: string;\n disabled?: boolean;\n}\n\nexport interface ComboboxProps {\n /** Currently selected value (controlled). */\n value: string | null;\n /** Called when a value is picked or cleared. */\n onChange: (value: string | null) => void;\n /** Static options. Ignored if `loadOptions` is provided. */\n options?: ComboboxOption[];\n /**\n * Async loader called with the current query each time it changes.\n * Use for server-side search.\n */\n loadOptions?: (query: string) => Promise<ComboboxOption[]>;\n /**\n * Label to show for a preset `value` in `loadOptions` mode before the\n * first search has resolved (the component has no option list yet).\n */\n selectedLabel?: string;\n /** Visible label above the field. */\n label?: ReactNode;\n /** Hint below the field. Hidden when `error` is set. */\n helperText?: ReactNode;\n /** Validation error. */\n error?: ReactNode;\n /** Placeholder shown when no value is selected. */\n placeholder?: string;\n /** Search placeholder inside the popover. */\n searchPlaceholder?: string;\n /** Empty state copy when nothing matches. */\n emptyText?: string;\n /** Message shown when `loadOptions` rejects. */\n loadErrorText?: string;\n /** Allow clearing the selection with an inline ×. */\n clearable?: boolean;\n /** Disable the entire field. */\n disabled?: boolean;\n /** Field size, matches Input. */\n size?: 'sm' | 'md' | 'lg';\n /** Consumer-supplied id for the trigger (label association). */\n id?: string;\n className?: string;\n}\n\n/**\n * Single-select with typeahead. Use `options` for client-side filtering or\n * `loadOptions` for server-side search.\n *\n * @example Client-side\n * <Combobox label=\"Country\" options={countries} value={c} onChange={setC} />\n *\n * @example Server-side\n * <Combobox label=\"Assignee\"\n * value={user}\n * onChange={setUser}\n * loadOptions={async (q) => api.searchUsers(q)} />\n *\n * @do Use Combobox over Select for >12 options or when the user is expected\n * to know what they want.\n * @dont Re-query on every keystroke without debouncing — pass a debounced\n * `loadOptions` to avoid hammering the server.\n */\nexport const Combobox = forwardRef<HTMLDivElement, ComboboxProps>(function Combobox(\n {\n value,\n onChange,\n options,\n loadOptions,\n selectedLabel,\n label,\n helperText,\n error,\n placeholder: placeholderProp,\n searchPlaceholder: searchPlaceholderProp,\n emptyText: emptyTextProp,\n loadErrorText: loadErrorTextProp,\n clearable = true,\n disabled,\n size = 'md',\n id,\n className,\n },\n ref,\n) {\n const strings = useStrings();\n const placeholder = placeholderProp ?? strings.combobox.placeholder;\n const searchPlaceholder = searchPlaceholderProp ?? strings.combobox.searchPlaceholder;\n const emptyText = emptyTextProp ?? strings.combobox.empty;\n const loadErrorText = loadErrorTextProp ?? strings.combobox.loadError;\n const isError = Boolean(error);\n const { fieldId, helperId, errorId, describedBy } = useFieldIds(id, {\n hasHelper: Boolean(helperText),\n hasError: isError,\n });\n // cmdk assigns its own id to the list, so read it back from the node once\n // the portal mounts; aria-controls is only set while the listbox exists.\n const [listId, setListId] = useState<string | undefined>(undefined);\n const listRef = useCallback((el: HTMLDivElement | null) => setListId(el?.id), []);\n\n const [open, setOpen] = useState(false);\n const [query, setQuery] = useState('');\n const [loaded, setLoaded] = useState<ComboboxOption[]>([]);\n const [loading, setLoading] = useState(false);\n const [loadError, setLoadError] = useState(false);\n // In async mode the option list only exists after the first search, so the\n // chosen option is remembered here to keep its label on the trigger.\n const [selectedOption, setSelectedOption] = useState<ComboboxOption | null>(null);\n\n // Resolve options: static or async-loaded.\n const items = useMemo(\n () => (loadOptions ? loaded : (options ?? [])),\n [loadOptions, loaded, options],\n );\n\n // Latest loader in a ref so an inline `loadOptions={async q => …}` does not\n // retrigger the fetch on every parent render — only query / open do.\n const loadRef = useRef(loadOptions);\n useEffect(() => {\n loadRef.current = loadOptions;\n });\n const hasLoader = Boolean(loadOptions);\n useEffect(() => {\n const load = loadRef.current;\n if (!load || !open) return;\n let cancelled = false;\n setLoading(true);\n setLoadError(false);\n load(query)\n .then((res) => {\n if (!cancelled) setLoaded(res);\n })\n .catch(() => {\n if (!cancelled) {\n setLoaded([]);\n setLoadError(true);\n }\n })\n .finally(() => {\n if (!cancelled) setLoading(false);\n });\n return () => {\n cancelled = true;\n };\n }, [query, open, hasLoader]);\n\n const selected = useMemo<ComboboxOption | null>(() => {\n if (value === null || value === undefined) return null;\n const fromItems = items.find((o) => o.value === value);\n if (fromItems) return fromItems;\n if (selectedOption?.value === value) return selectedOption;\n if (selectedLabel !== undefined) return { value, label: selectedLabel };\n return null;\n }, [items, value, selectedOption, selectedLabel]);\n\n const triggerHeight = size === 'sm' ? 'h-8' : size === 'lg' ? 'h-10' : 'h-9';\n const triggerPadding = size === 'sm' ? 'px-2.5' : size === 'lg' ? 'px-3.5' : 'px-3';\n // Leave room on the right for the clear button + chevron.\n const triggerPaddingRight = clearable ? 'pr-14' : 'pr-9';\n\n const handleClear = useCallback(() => {\n setSelectedOption(null);\n onChange(null);\n }, [onChange]);\n\n return (\n <div ref={ref} className={cn('flex flex-col gap-1.5', className)}>\n {label && (\n <label\n id={`${fieldId}-label`}\n htmlFor={fieldId}\n className=\"text-foreground text-sm font-medium\"\n >\n {label}\n </label>\n )}\n\n <PopoverPrimitive.Root open={open} onOpenChange={setOpen}>\n <div className=\"relative w-full\">\n <PopoverPrimitive.Trigger asChild>\n <button\n id={fieldId}\n type=\"button\"\n role=\"combobox\"\n aria-expanded={open}\n aria-haspopup=\"listbox\"\n aria-controls={open ? listId : undefined}\n // role=combobox takes no name from content, so the placeholder\n // must be exposed explicitly. A consumer `id` implies an external\n // <label htmlFor>, which aria-label would override.\n aria-labelledby={label ? `${fieldId}-label` : undefined}\n aria-label={label || id ? undefined : placeholder}\n aria-invalid={isError || undefined}\n aria-describedby={describedBy}\n disabled={disabled}\n className={cn(\n 'bg-card text-foreground inline-flex w-full items-center justify-between gap-2 rounded-md border text-sm',\n 'transition-colors duration-[var(--duration-fast)] ease-[var(--ease-out)]',\n 'focus-visible:ring-offset-background outline-none focus-visible:ring-2 focus-visible:ring-offset-2',\n 'disabled:cursor-not-allowed disabled:opacity-50',\n triggerHeight,\n triggerPadding,\n triggerPaddingRight,\n isError\n ? 'border-danger focus-visible:border-danger focus-visible:ring-danger'\n : 'border-border-input focus-visible:border-accent focus-visible:ring-ring',\n )}\n >\n <span\n className={cn('truncate', !selected && 'text-foreground-subtle')}\n title={selected ? selected.label : undefined}\n >\n {selected ? selected.label : placeholder}\n </span>\n </button>\n </PopoverPrimitive.Trigger>\n\n {/* Controls sit outside the trigger: a button inside a button is invalid HTML. */}\n <span className=\"pointer-events-none absolute inset-y-0 right-0 flex items-center gap-0.5 pr-2\">\n {clearable && selected && !disabled && (\n <IconButton\n size=\"sm\"\n variant=\"ghost\"\n aria-label={strings.combobox.clear}\n icon={<X />}\n onClick={handleClear}\n className=\"text-foreground-subtle hover:text-foreground pointer-events-auto size-6\"\n />\n )}\n <ChevronsUpDown className=\"text-foreground-subtle size-4\" aria-hidden />\n </span>\n </div>\n\n <PopoverPrimitive.Portal>\n <PopoverPrimitive.Content\n // Radix gives the popover role=\"dialog\"; name it after the field.\n aria-labelledby={label ? `${fieldId}-label` : undefined}\n aria-label={label ? undefined : placeholder}\n align=\"start\"\n sideOffset={4}\n className={cn(\n 'border-border bg-popover text-popover-foreground z-[var(--z-popover)] w-[var(--radix-popover-trigger-width)] overflow-hidden rounded-lg border shadow-md',\n 'data-[state=open]:animate-in data-[state=closed]:animate-out',\n 'data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0',\n 'data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95',\n )}\n >\n <CommandPrimitive shouldFilter={!loadOptions} className=\"flex h-full w-full flex-col\">\n <div className=\"border-border flex items-center border-b px-3\">\n <CommandPrimitive.Input\n value={query}\n onValueChange={setQuery}\n placeholder={searchPlaceholder}\n className=\"placeholder:text-foreground-subtle flex h-9 w-full bg-transparent py-2 text-lg outline-none md:text-sm\"\n />\n {loading && (\n <Loader2 className=\"text-foreground-subtle size-4 animate-spin\" aria-hidden />\n )}\n </div>\n <CommandPrimitive.List\n ref={listRef}\n label={strings.command.suggestions}\n className=\"max-h-64 overflow-y-auto p-1\"\n >\n {items.map((opt) => {\n const isSelected = opt.value === value;\n return (\n <CommandPrimitive.Item\n key={opt.value}\n value={opt.value}\n // cmdk matches on value + keywords; users type the label, not the id.\n keywords={opt.description ? [opt.label, opt.description] : [opt.label]}\n disabled={opt.disabled}\n onSelect={(v) => {\n setSelectedOption(opt);\n onChange(v);\n setOpen(false);\n }}\n className={cn(\n 'text-foreground flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm',\n 'data-[selected=true]:bg-background-muted',\n 'data-[disabled=true]:pointer-events-none data-[disabled=true]:opacity-50',\n )}\n >\n <span className=\"flex-1\">{opt.label}</span>\n {opt.description && (\n <span className=\"text-foreground-subtle text-xs\">{opt.description}</span>\n )}\n {isSelected && <Check className=\"text-accent size-4\" aria-hidden />}\n </CommandPrimitive.Item>\n );\n })}\n {loadError && !loading && (\n <div className=\"text-danger-text px-2 py-6 text-center text-sm\">\n {loadErrorText}\n </div>\n )}\n {/* cmdk only shows Empty when no item matches the query, so it can always be mounted. */}\n {!loading && !loadError && (\n <CommandPrimitive.Empty className=\"text-foreground-subtle px-2 py-6 text-center text-sm\">\n {emptyText}\n </CommandPrimitive.Empty>\n )}\n </CommandPrimitive.List>\n </CommandPrimitive>\n </PopoverPrimitive.Content>\n </PopoverPrimitive.Portal>\n </PopoverPrimitive.Root>\n\n {error ? (\n <p id={errorId} className=\"text-danger-text text-xs\">\n {error}\n </p>\n ) : helperText ? (\n <p id={helperId} className=\"text-foreground-subtle text-xs\">\n {helperText}\n </p>\n ) : null}\n </div>\n );\n});\n\nCombobox.displayName = 'Combobox';\n"],"names":["Combobox","forwardRef","value","onChange","options","loadOptions","selectedLabel","label","helperText","error","placeholderProp","searchPlaceholderProp","emptyTextProp","loadErrorTextProp","clearable","disabled","size","id","className","ref","strings","useStrings","placeholder","searchPlaceholder","emptyText","loadErrorText","isError","fieldId","helperId","errorId","describedBy","useFieldIds","listId","setListId","useState","listRef","useCallback","el","open","setOpen","query","setQuery","loaded","setLoaded","loading","setLoading","loadError","setLoadError","selectedOption","setSelectedOption","items","useMemo","loadRef","useRef","useEffect","load","cancelled","res","selected","fromItems","o","triggerHeight","triggerPadding","triggerPaddingRight","handleClear","cn","jsx","PopoverPrimitive","jsxs","IconButton","X","ChevronsUpDown","CommandPrimitive","Loader2","opt","isSelected","v","Check"],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ReactNode } from 'react';
|
|
1
|
+
import { Dispatch, ReactNode, SetStateAction } from 'react';
|
|
2
2
|
export declare const Command: import('react').ForwardRefExoticComponent<Omit<{
|
|
3
3
|
children?: React.ReactNode;
|
|
4
4
|
} & Pick<Pick<import('react').DetailedHTMLProps<import('react').HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "key" | keyof import('react').HTMLAttributes<HTMLDivElement>> & {
|
|
@@ -20,7 +20,7 @@ export declare const CommandInput: import('react').ForwardRefExoticComponent<Omi
|
|
|
20
20
|
ref?: React.Ref<HTMLInputElement>;
|
|
21
21
|
} & {
|
|
22
22
|
asChild?: boolean;
|
|
23
|
-
}, "key" | "asChild" | keyof import('react').InputHTMLAttributes<HTMLInputElement>>, "
|
|
23
|
+
}, "key" | "asChild" | keyof import('react').InputHTMLAttributes<HTMLInputElement>>, "value" | "type" | "onChange"> & {
|
|
24
24
|
value?: string;
|
|
25
25
|
onValueChange?: (search: string) => void;
|
|
26
26
|
} & import('react').RefAttributes<HTMLInputElement>, "ref"> & import('react').RefAttributes<HTMLInputElement>>;
|
|
@@ -46,7 +46,7 @@ export declare const CommandGroup: import('react').ForwardRefExoticComponent<Omi
|
|
|
46
46
|
ref?: React.Ref<HTMLDivElement>;
|
|
47
47
|
} & {
|
|
48
48
|
asChild?: boolean;
|
|
49
|
-
}, "key" | keyof import('react').HTMLAttributes<HTMLDivElement> | "asChild">, "
|
|
49
|
+
}, "key" | keyof import('react').HTMLAttributes<HTMLDivElement> | "asChild">, "value" | "heading"> & {
|
|
50
50
|
heading?: React.ReactNode;
|
|
51
51
|
value?: string;
|
|
52
52
|
forceMount?: boolean;
|
|
@@ -64,17 +64,20 @@ export declare const CommandItem: import('react').ForwardRefExoticComponent<Omit
|
|
|
64
64
|
ref?: React.Ref<HTMLDivElement>;
|
|
65
65
|
} & {
|
|
66
66
|
asChild?: boolean;
|
|
67
|
-
}, "key" | keyof import('react').HTMLAttributes<HTMLDivElement> | "asChild">, "
|
|
67
|
+
}, "key" | keyof import('react').HTMLAttributes<HTMLDivElement> | "asChild">, "value" | "onSelect" | "disabled"> & {
|
|
68
68
|
disabled?: boolean;
|
|
69
69
|
onSelect?: (value: string) => void;
|
|
70
70
|
value?: string;
|
|
71
71
|
keywords?: string[];
|
|
72
72
|
forceMount?: boolean;
|
|
73
73
|
} & import('react').RefAttributes<HTMLDivElement>, "ref"> & import('react').RefAttributes<HTMLDivElement>>;
|
|
74
|
-
export declare function CommandShortcut({ children, className }: {
|
|
74
|
+
export declare function CommandShortcut({ children, className, }: {
|
|
75
75
|
children: ReactNode;
|
|
76
76
|
className?: string;
|
|
77
77
|
}): import("react/jsx-runtime").JSX.Element;
|
|
78
|
+
export declare namespace CommandShortcut {
|
|
79
|
+
var displayName: string;
|
|
80
|
+
}
|
|
78
81
|
export interface CommandDialogProps {
|
|
79
82
|
open: boolean;
|
|
80
83
|
onOpenChange: (open: boolean) => void;
|
|
@@ -106,4 +109,4 @@ export declare function CommandDialog({ open, onOpenChange, children, title }: C
|
|
|
106
109
|
* @dont Hide essential actions behind the palette only — keep at least one
|
|
107
110
|
* button entry in the UI.
|
|
108
111
|
*/
|
|
109
|
-
export declare function useCommandPaletteShortcut(setOpen:
|
|
112
|
+
export declare function useCommandPaletteShortcut(setOpen: Dispatch<SetStateAction<boolean>>): void;
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as a, jsxs as u } from "react/jsx-runtime";
|
|
3
|
+
import { forwardRef as d, useRef as x, useEffect as y } from "react";
|
|
4
|
+
import { Command as m } from "cmdk";
|
|
5
|
+
import * as l from "@radix-ui/react-dialog";
|
|
6
|
+
import { Search as C } from "../../icons/index.js";
|
|
7
|
+
import { cn as r } from "../../lib/utils.js";
|
|
8
|
+
import { useStrings as p } from "../../hooks/use-strings.js";
|
|
9
|
+
const f = d(function({ className: t, ...e }, o) {
|
|
10
|
+
return /* @__PURE__ */ a(
|
|
11
|
+
m,
|
|
12
|
+
{
|
|
13
|
+
ref: o,
|
|
14
|
+
className: r(
|
|
15
|
+
"bg-popover text-popover-foreground flex h-full w-full flex-col overflow-hidden rounded-lg",
|
|
16
|
+
t
|
|
17
|
+
),
|
|
18
|
+
...e
|
|
19
|
+
}
|
|
20
|
+
);
|
|
21
|
+
});
|
|
22
|
+
f.displayName = "Command";
|
|
23
|
+
const b = d(function({ className: t, ...e }, o) {
|
|
24
|
+
return /* @__PURE__ */ u("div", { className: "border-border flex items-center gap-2 border-b px-3", "cmdk-input-wrapper": "", children: [
|
|
25
|
+
/* @__PURE__ */ a(C, { className: "text-foreground-subtle size-4 shrink-0", "aria-hidden": !0 }),
|
|
26
|
+
/* @__PURE__ */ a(
|
|
27
|
+
m.Input,
|
|
28
|
+
{
|
|
29
|
+
ref: o,
|
|
30
|
+
className: r(
|
|
31
|
+
"flex h-11 w-full bg-transparent py-3 text-lg outline-none md:text-sm",
|
|
32
|
+
"placeholder:text-foreground-subtle disabled:cursor-not-allowed disabled:opacity-50",
|
|
33
|
+
t
|
|
34
|
+
),
|
|
35
|
+
...e
|
|
36
|
+
}
|
|
37
|
+
)
|
|
38
|
+
] });
|
|
39
|
+
});
|
|
40
|
+
b.displayName = "CommandInput";
|
|
41
|
+
const h = d(function({ className: t, label: e, ...o }, i) {
|
|
42
|
+
const s = p();
|
|
43
|
+
return /* @__PURE__ */ a(
|
|
44
|
+
m.List,
|
|
45
|
+
{
|
|
46
|
+
ref: i,
|
|
47
|
+
label: e ?? s.command.suggestions,
|
|
48
|
+
className: r("max-h-[320px] overflow-y-auto p-1", t),
|
|
49
|
+
...o
|
|
50
|
+
}
|
|
51
|
+
);
|
|
52
|
+
});
|
|
53
|
+
h.displayName = "CommandList";
|
|
54
|
+
const v = d(function({ className: t, ...e }, o) {
|
|
55
|
+
return /* @__PURE__ */ a(
|
|
56
|
+
m.Empty,
|
|
57
|
+
{
|
|
58
|
+
ref: o,
|
|
59
|
+
className: r("text-foreground-subtle py-8 text-center text-sm", t),
|
|
60
|
+
...e
|
|
61
|
+
}
|
|
62
|
+
);
|
|
63
|
+
});
|
|
64
|
+
v.displayName = "CommandEmpty";
|
|
65
|
+
const N = d(function({ className: t, ...e }, o) {
|
|
66
|
+
return /* @__PURE__ */ a(
|
|
67
|
+
m.Group,
|
|
68
|
+
{
|
|
69
|
+
ref: o,
|
|
70
|
+
className: r(
|
|
71
|
+
"text-foreground overflow-hidden p-1",
|
|
72
|
+
"[&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:py-1.5",
|
|
73
|
+
"[&_[cmdk-group-heading]]:text-xs [&_[cmdk-group-heading]]:font-medium",
|
|
74
|
+
"[&_[cmdk-group-heading]]:text-foreground-subtle",
|
|
75
|
+
t
|
|
76
|
+
),
|
|
77
|
+
...e
|
|
78
|
+
}
|
|
79
|
+
);
|
|
80
|
+
});
|
|
81
|
+
N.displayName = "CommandGroup";
|
|
82
|
+
const w = d(function({ className: t, ...e }, o) {
|
|
83
|
+
return /* @__PURE__ */ a(m.Separator, { ref: o, asChild: !0, ...e, children: /* @__PURE__ */ a("div", { role: "none", className: r("bg-border -mx-1 my-1 h-px", t) }) });
|
|
84
|
+
});
|
|
85
|
+
w.displayName = "CommandSeparator";
|
|
86
|
+
const k = d(function({ className: t, ...e }, o) {
|
|
87
|
+
return /* @__PURE__ */ a(
|
|
88
|
+
m.Item,
|
|
89
|
+
{
|
|
90
|
+
ref: o,
|
|
91
|
+
className: r(
|
|
92
|
+
"text-foreground relative flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-none select-none",
|
|
93
|
+
"data-[selected=true]:bg-background-muted data-[selected=true]:text-foreground",
|
|
94
|
+
"data-[disabled=true]:pointer-events-none data-[disabled=true]:opacity-50",
|
|
95
|
+
"[&_svg]:text-foreground-subtle [&_svg]:size-4",
|
|
96
|
+
t
|
|
97
|
+
),
|
|
98
|
+
...e
|
|
99
|
+
}
|
|
100
|
+
);
|
|
101
|
+
});
|
|
102
|
+
k.displayName = "CommandItem";
|
|
103
|
+
function S({
|
|
104
|
+
children: n,
|
|
105
|
+
className: t
|
|
106
|
+
}) {
|
|
107
|
+
return /* @__PURE__ */ a(
|
|
108
|
+
"span",
|
|
109
|
+
{
|
|
110
|
+
className: r(
|
|
111
|
+
"text-foreground-subtle ml-auto inline-flex items-center gap-0.5 font-mono text-xs tracking-widest",
|
|
112
|
+
t
|
|
113
|
+
),
|
|
114
|
+
children: n
|
|
115
|
+
}
|
|
116
|
+
);
|
|
117
|
+
}
|
|
118
|
+
S.displayName = "CommandShortcut";
|
|
119
|
+
function K({ open: n, onOpenChange: t, children: e, title: o }) {
|
|
120
|
+
const i = p(), s = x(null);
|
|
121
|
+
return /* @__PURE__ */ a(l.Root, { open: n, onOpenChange: t, children: /* @__PURE__ */ u(l.Portal, { children: [
|
|
122
|
+
/* @__PURE__ */ a(
|
|
123
|
+
l.Overlay,
|
|
124
|
+
{
|
|
125
|
+
className: r(
|
|
126
|
+
"bg-overlay fixed inset-0 z-[var(--z-overlay)]",
|
|
127
|
+
"data-[state=open]:animate-in data-[state=closed]:animate-out",
|
|
128
|
+
"data-[state=open]:fade-in-0 data-[state=closed]:fade-out-0"
|
|
129
|
+
)
|
|
130
|
+
}
|
|
131
|
+
),
|
|
132
|
+
/* @__PURE__ */ u(
|
|
133
|
+
l.Content,
|
|
134
|
+
{
|
|
135
|
+
"aria-describedby": void 0,
|
|
136
|
+
onOpenAutoFocus: () => {
|
|
137
|
+
s.current = document.activeElement;
|
|
138
|
+
},
|
|
139
|
+
onCloseAutoFocus: (g) => {
|
|
140
|
+
var c;
|
|
141
|
+
g.preventDefault(), (c = s.current) == null || c.focus(), s.current = null;
|
|
142
|
+
},
|
|
143
|
+
className: r(
|
|
144
|
+
"fixed top-[20%] left-1/2 z-[var(--z-modal)] -translate-x-1/2",
|
|
145
|
+
"w-[calc(100%-2rem)] max-w-[640px] overflow-hidden",
|
|
146
|
+
"border-border bg-popover text-popover-foreground rounded-lg border shadow-lg",
|
|
147
|
+
"data-[state=open]:animate-in data-[state=closed]:animate-out",
|
|
148
|
+
"data-[state=open]:fade-in-0 data-[state=closed]:fade-out-0",
|
|
149
|
+
"data-[state=open]:zoom-in-95 data-[state=closed]:zoom-out-95"
|
|
150
|
+
),
|
|
151
|
+
children: [
|
|
152
|
+
/* @__PURE__ */ a(l.Title, { className: "sr-only", children: o ?? i.commandDialog.title }),
|
|
153
|
+
/* @__PURE__ */ a(f, { children: e })
|
|
154
|
+
]
|
|
155
|
+
}
|
|
156
|
+
)
|
|
157
|
+
] }) });
|
|
158
|
+
}
|
|
159
|
+
function G(n) {
|
|
160
|
+
y(() => {
|
|
161
|
+
const t = (e) => {
|
|
162
|
+
(e.key === "k" || e.key === "K") && (e.metaKey || e.ctrlKey) && !e.altKey && (e.preventDefault(), n((o) => !o));
|
|
163
|
+
};
|
|
164
|
+
return window.addEventListener("keydown", t), () => window.removeEventListener("keydown", t);
|
|
165
|
+
}, [n]);
|
|
166
|
+
}
|
|
167
|
+
export {
|
|
168
|
+
f as Command,
|
|
169
|
+
K as CommandDialog,
|
|
170
|
+
v as CommandEmpty,
|
|
171
|
+
N as CommandGroup,
|
|
172
|
+
b as CommandInput,
|
|
173
|
+
k as CommandItem,
|
|
174
|
+
h as CommandList,
|
|
175
|
+
w as CommandSeparator,
|
|
176
|
+
S as CommandShortcut,
|
|
177
|
+
G as useCommandPaletteShortcut
|
|
178
|
+
};
|
|
179
|
+
//# sourceMappingURL=CommandPalette.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CommandPalette.js","sources":["../../../src/components/ui/CommandPalette.tsx"],"sourcesContent":["'use client';\n\nimport {\n forwardRef,\n useEffect,\n useRef,\n type ComponentPropsWithoutRef,\n type Dispatch,\n type ElementRef,\n type ReactNode,\n type SetStateAction,\n} from 'react';\nimport { Command as CommandPrimitive } from 'cmdk';\nimport * as DialogPrimitive from '@radix-ui/react-dialog';\nimport { Search } from '@/icons';\nimport { cn } from '@/lib/utils';\nimport { useStrings } from '@/hooks/use-strings';\n\n/* -----------------------------------------------------------------------------\n * CommandPalette is a Dialog hosting a `cmdk` Command. It supports grouped\n * items, keyboard navigation (handled by cmdk), an empty state, and a\n * pluggable list of \"recent\" items shown when the search input is empty.\n * --------------------------------------------------------------------------- */\n\nexport const Command = forwardRef<\n ElementRef<typeof CommandPrimitive>,\n ComponentPropsWithoutRef<typeof CommandPrimitive>\n>(function Command({ className, ...props }, ref) {\n return (\n <CommandPrimitive\n ref={ref}\n className={cn(\n 'bg-popover text-popover-foreground flex h-full w-full flex-col overflow-hidden rounded-lg',\n className,\n )}\n {...props}\n />\n );\n});\nCommand.displayName = 'Command';\n\nexport const CommandInput = forwardRef<\n ElementRef<typeof CommandPrimitive.Input>,\n ComponentPropsWithoutRef<typeof CommandPrimitive.Input>\n>(function CommandInput({ className, ...props }, ref) {\n return (\n <div className=\"border-border flex items-center gap-2 border-b px-3\" cmdk-input-wrapper=\"\">\n <Search className=\"text-foreground-subtle size-4 shrink-0\" aria-hidden />\n <CommandPrimitive.Input\n ref={ref}\n className={cn(\n 'flex h-11 w-full bg-transparent py-3 text-lg outline-none md:text-sm',\n 'placeholder:text-foreground-subtle disabled:cursor-not-allowed disabled:opacity-50',\n className,\n )}\n {...props}\n />\n </div>\n );\n});\nCommandInput.displayName = 'CommandInput';\n\nexport const CommandList = forwardRef<\n ElementRef<typeof CommandPrimitive.List>,\n ComponentPropsWithoutRef<typeof CommandPrimitive.List>\n>(function CommandList({ className, label, ...props }, ref) {\n const strings = useStrings();\n return (\n <CommandPrimitive.List\n ref={ref}\n label={label ?? strings.command.suggestions}\n className={cn('max-h-[320px] overflow-y-auto p-1', className)}\n {...props}\n />\n );\n});\nCommandList.displayName = 'CommandList';\n\nexport const CommandEmpty = forwardRef<\n ElementRef<typeof CommandPrimitive.Empty>,\n ComponentPropsWithoutRef<typeof CommandPrimitive.Empty>\n>(function CommandEmpty({ className, ...props }, ref) {\n return (\n <CommandPrimitive.Empty\n ref={ref}\n className={cn('text-foreground-subtle py-8 text-center text-sm', className)}\n {...props}\n />\n );\n});\nCommandEmpty.displayName = 'CommandEmpty';\n\nexport const CommandGroup = forwardRef<\n ElementRef<typeof CommandPrimitive.Group>,\n ComponentPropsWithoutRef<typeof CommandPrimitive.Group>\n>(function CommandGroup({ className, ...props }, ref) {\n return (\n <CommandPrimitive.Group\n ref={ref}\n className={cn(\n 'text-foreground overflow-hidden p-1',\n '[&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:py-1.5',\n '[&_[cmdk-group-heading]]:text-xs [&_[cmdk-group-heading]]:font-medium',\n '[&_[cmdk-group-heading]]:text-foreground-subtle',\n className,\n )}\n {...props}\n />\n );\n});\nCommandGroup.displayName = 'CommandGroup';\n\nexport const CommandSeparator = forwardRef<\n ElementRef<typeof CommandPrimitive.Separator>,\n ComponentPropsWithoutRef<typeof CommandPrimitive.Separator>\n>(function CommandSeparator({ className, ...props }, ref) {\n // cmdk hard-codes role=\"separator\", which is not a permitted child of the\n // listbox. asChild lets the child's role win: the divider is purely visual.\n return (\n <CommandPrimitive.Separator ref={ref} asChild {...props}>\n <div role=\"none\" className={cn('bg-border -mx-1 my-1 h-px', className)} />\n </CommandPrimitive.Separator>\n );\n});\nCommandSeparator.displayName = 'CommandSeparator';\n\nexport const CommandItem = forwardRef<\n ElementRef<typeof CommandPrimitive.Item>,\n ComponentPropsWithoutRef<typeof CommandPrimitive.Item>\n>(function CommandItem({ className, ...props }, ref) {\n return (\n <CommandPrimitive.Item\n ref={ref}\n className={cn(\n 'text-foreground relative flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-none select-none',\n 'data-[selected=true]:bg-background-muted data-[selected=true]:text-foreground',\n 'data-[disabled=true]:pointer-events-none data-[disabled=true]:opacity-50',\n '[&_svg]:text-foreground-subtle [&_svg]:size-4',\n className,\n )}\n {...props}\n />\n );\n});\nCommandItem.displayName = 'CommandItem';\n\nexport function CommandShortcut({\n children,\n className,\n}: {\n children: ReactNode;\n className?: string;\n}) {\n return (\n <span\n className={cn(\n 'text-foreground-subtle ml-auto inline-flex items-center gap-0.5 font-mono text-xs tracking-widest',\n className,\n )}\n >\n {children}\n </span>\n );\n}\nCommandShortcut.displayName = 'CommandShortcut';\n\n/* -----------------------------------------------------------------------------\n * Dialog wrapper — a ready-to-use ⌘K palette.\n * --------------------------------------------------------------------------- */\n\nexport interface CommandDialogProps {\n open: boolean;\n onOpenChange: (open: boolean) => void;\n children: ReactNode;\n /** Visible label for screen readers. */\n title?: string;\n}\n\nexport function CommandDialog({ open, onOpenChange, children, title }: CommandDialogProps) {\n const strings = useStrings();\n // The palette has no DialogTrigger (⌘K / any button opens it), so Radix has\n // no trigger to return focus to and would drop it on <body>. Remember what\n // was focused when the dialog opened and restore it on close.\n const returnFocusRef = useRef<HTMLElement | null>(null);\n return (\n <DialogPrimitive.Root open={open} onOpenChange={onOpenChange}>\n <DialogPrimitive.Portal>\n <DialogPrimitive.Overlay\n className={cn(\n 'bg-overlay fixed inset-0 z-[var(--z-overlay)]',\n 'data-[state=open]:animate-in data-[state=closed]:animate-out',\n 'data-[state=open]:fade-in-0 data-[state=closed]:fade-out-0',\n )}\n />\n <DialogPrimitive.Content\n aria-describedby={undefined}\n onOpenAutoFocus={() => {\n returnFocusRef.current = document.activeElement as HTMLElement | null;\n }}\n onCloseAutoFocus={(event) => {\n event.preventDefault();\n returnFocusRef.current?.focus();\n returnFocusRef.current = null;\n }}\n className={cn(\n 'fixed top-[20%] left-1/2 z-[var(--z-modal)] -translate-x-1/2',\n 'w-[calc(100%-2rem)] max-w-[640px] overflow-hidden',\n 'border-border bg-popover text-popover-foreground rounded-lg border shadow-lg',\n 'data-[state=open]:animate-in data-[state=closed]:animate-out',\n 'data-[state=open]:fade-in-0 data-[state=closed]:fade-out-0',\n 'data-[state=open]:zoom-in-95 data-[state=closed]:zoom-out-95',\n )}\n >\n <DialogPrimitive.Title className=\"sr-only\">\n {title ?? strings.commandDialog.title}\n </DialogPrimitive.Title>\n <Command>{children}</Command>\n </DialogPrimitive.Content>\n </DialogPrimitive.Portal>\n </DialogPrimitive.Root>\n );\n}\n\n/**\n * Hook that wires ⌘K / Ctrl+K to a setter — the canonical way to mount the\n * palette in an app shell.\n *\n * @example\n * const [open, setOpen] = useState(false);\n * useCommandPaletteShortcut(setOpen);\n * …\n * <CommandDialog open={open} onOpenChange={setOpen}>\n * <CommandInput placeholder=\"Type a command…\" />\n * <CommandList>\n * <CommandEmpty>No results.</CommandEmpty>\n * <CommandGroup heading=\"Suggestions\">\n * <CommandItem>Create project</CommandItem>\n * <CommandItem>Invite teammate</CommandItem>\n * </CommandGroup>\n * </CommandList>\n * </CommandDialog>\n *\n * @do Group items by category. Show \"Recent\" first when the query is empty.\n * @dont Hide essential actions behind the palette only — keep at least one\n * button entry in the UI.\n */\nexport function useCommandPaletteShortcut(setOpen: Dispatch<SetStateAction<boolean>>): void {\n useEffect(() => {\n const onKey = (e: KeyboardEvent) => {\n if ((e.key === 'k' || e.key === 'K') && (e.metaKey || e.ctrlKey) && !e.altKey) {\n e.preventDefault();\n // Functional update: ⌘K toggles without the hook tracking open state.\n setOpen((prev) => !prev);\n }\n };\n window.addEventListener('keydown', onKey);\n return () => window.removeEventListener('keydown', onKey);\n }, [setOpen]);\n}\n"],"names":["Command","forwardRef","className","props","ref","jsx","CommandPrimitive","cn","CommandInput","jsxs","Search","CommandList","label","strings","useStrings","CommandEmpty","CommandGroup","CommandSeparator","CommandItem","CommandShortcut","children","CommandDialog","open","onOpenChange","title","returnFocusRef","useRef","DialogPrimitive","event","_a","useCommandPaletteShortcut","setOpen","useEffect","onKey","prev"],"mappings":"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"}
|
|
@@ -29,15 +29,20 @@ export declare const ContextMenuGroup: import('react').ForwardRefExoticComponent
|
|
|
29
29
|
export declare const ContextMenuPortal: import('react').FC<ContextMenuPrimitive.ContextMenuPortalProps>;
|
|
30
30
|
export declare const ContextMenuSub: import('react').FC<ContextMenuPrimitive.ContextMenuSubProps>;
|
|
31
31
|
export declare const ContextMenuRadioGroup: import('react').ForwardRefExoticComponent<ContextMenuPrimitive.ContextMenuRadioGroupProps & import('react').RefAttributes<HTMLDivElement>>;
|
|
32
|
-
export declare const ContextMenuSubTrigger: import('react').ForwardRefExoticComponent<Omit<ContextMenuPrimitive.ContextMenuSubTriggerProps & import('react').RefAttributes<HTMLDivElement>, "ref"> &
|
|
32
|
+
export declare const ContextMenuSubTrigger: import('react').ForwardRefExoticComponent<Omit<ContextMenuPrimitive.ContextMenuSubTriggerProps & import('react').RefAttributes<HTMLDivElement>, "ref"> & {
|
|
33
|
+
inset?: boolean;
|
|
34
|
+
} & import('react').RefAttributes<HTMLDivElement>>;
|
|
33
35
|
export declare const ContextMenuSubContent: import('react').ForwardRefExoticComponent<Omit<ContextMenuPrimitive.ContextMenuSubContentProps & import('react').RefAttributes<HTMLDivElement>, "ref"> & import('react').RefAttributes<HTMLDivElement>>;
|
|
34
36
|
export declare const ContextMenuContent: import('react').ForwardRefExoticComponent<Omit<ContextMenuPrimitive.ContextMenuContentProps & import('react').RefAttributes<HTMLDivElement>, "ref"> & import('react').RefAttributes<HTMLDivElement>>;
|
|
35
37
|
export declare const ContextMenuItem: import('react').ForwardRefExoticComponent<Omit<ContextMenuPrimitive.ContextMenuItemProps & import('react').RefAttributes<HTMLDivElement>, "ref"> & {
|
|
38
|
+
inset?: boolean;
|
|
36
39
|
destructive?: boolean;
|
|
37
40
|
} & import('react').RefAttributes<HTMLDivElement>>;
|
|
38
41
|
export declare const ContextMenuCheckboxItem: import('react').ForwardRefExoticComponent<Omit<ContextMenuPrimitive.ContextMenuCheckboxItemProps & import('react').RefAttributes<HTMLDivElement>, "ref"> & import('react').RefAttributes<HTMLDivElement>>;
|
|
39
42
|
export declare const ContextMenuRadioItem: import('react').ForwardRefExoticComponent<Omit<ContextMenuPrimitive.ContextMenuRadioItemProps & import('react').RefAttributes<HTMLDivElement>, "ref"> & import('react').RefAttributes<HTMLDivElement>>;
|
|
40
|
-
export declare const ContextMenuLabel: import('react').ForwardRefExoticComponent<Omit<ContextMenuPrimitive.ContextMenuLabelProps & import('react').RefAttributes<HTMLDivElement>, "ref"> &
|
|
43
|
+
export declare const ContextMenuLabel: import('react').ForwardRefExoticComponent<Omit<ContextMenuPrimitive.ContextMenuLabelProps & import('react').RefAttributes<HTMLDivElement>, "ref"> & {
|
|
44
|
+
inset?: boolean;
|
|
45
|
+
} & import('react').RefAttributes<HTMLDivElement>>;
|
|
41
46
|
export declare const ContextMenuSeparator: import('react').ForwardRefExoticComponent<Omit<ContextMenuPrimitive.ContextMenuSeparatorProps & import('react').RefAttributes<HTMLDivElement>, "ref"> & import('react').RefAttributes<HTMLDivElement>>;
|
|
42
47
|
export declare function ContextMenuShortcut({ className, ...props }: HTMLAttributes<HTMLSpanElement>): import("react/jsx-runtime").JSX.Element;
|
|
43
48
|
export declare namespace ContextMenuShortcut {
|