@zentauri-ui/zentauri-components 1.7.2 → 1.7.4

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.
Files changed (69) hide show
  1. package/README.md +10 -6
  2. package/cli/registry.json +2 -0
  3. package/dist/chunk-KEKMMNL5.mjs +600 -0
  4. package/dist/chunk-KEKMMNL5.mjs.map +1 -0
  5. package/dist/chunk-NZDHSIIC.js +616 -0
  6. package/dist/chunk-NZDHSIIC.js.map +1 -0
  7. package/dist/design-system/command.d.ts +41 -0
  8. package/dist/design-system/command.d.ts.map +1 -0
  9. package/dist/design-system/index.d.ts +2 -0
  10. package/dist/design-system/index.d.ts.map +1 -1
  11. package/dist/design-system/otp-input.d.ts +27 -0
  12. package/dist/design-system/otp-input.d.ts.map +1 -0
  13. package/dist/ui/command/animated/animations.d.ts +3 -0
  14. package/dist/ui/command/animated/animations.d.ts.map +1 -0
  15. package/dist/ui/command/animated/command-content-animated.d.ts +6 -0
  16. package/dist/ui/command/animated/command-content-animated.d.ts.map +1 -0
  17. package/dist/ui/command/animated/index.d.ts +4 -0
  18. package/dist/ui/command/animated/index.d.ts.map +1 -0
  19. package/dist/ui/command/animated/types.d.ts +9 -0
  20. package/dist/ui/command/animated/types.d.ts.map +1 -0
  21. package/dist/ui/command/animated.js +92 -0
  22. package/dist/ui/command/animated.js.map +1 -0
  23. package/dist/ui/command/animated.mjs +89 -0
  24. package/dist/ui/command/animated.mjs.map +1 -0
  25. package/dist/ui/command/command-base.d.ts +53 -0
  26. package/dist/ui/command/command-base.d.ts.map +1 -0
  27. package/dist/ui/command/command.d.ts +6 -0
  28. package/dist/ui/command/command.d.ts.map +1 -0
  29. package/dist/ui/command/index.d.ts +5 -0
  30. package/dist/ui/command/index.d.ts.map +1 -0
  31. package/dist/ui/command/types.d.ts +111 -0
  32. package/dist/ui/command/types.d.ts.map +1 -0
  33. package/dist/ui/command/variants.d.ts +15 -0
  34. package/dist/ui/command/variants.d.ts.map +1 -0
  35. package/dist/ui/command.js +69 -0
  36. package/dist/ui/command.js.map +1 -0
  37. package/dist/ui/command.mjs +16 -0
  38. package/dist/ui/command.mjs.map +1 -0
  39. package/dist/ui/otp-input/index.d.ts +4 -0
  40. package/dist/ui/otp-input/index.d.ts.map +1 -0
  41. package/dist/ui/otp-input/otp-input.d.ts +6 -0
  42. package/dist/ui/otp-input/otp-input.d.ts.map +1 -0
  43. package/dist/ui/otp-input/types.d.ts +23 -0
  44. package/dist/ui/otp-input/types.d.ts.map +1 -0
  45. package/dist/ui/otp-input/variants.d.ts +5 -0
  46. package/dist/ui/otp-input/variants.d.ts.map +1 -0
  47. package/dist/ui/otp-input.js +302 -0
  48. package/dist/ui/otp-input.js.map +1 -0
  49. package/dist/ui/otp-input.mjs +299 -0
  50. package/dist/ui/otp-input.mjs.map +1 -0
  51. package/package.json +1 -1
  52. package/src/design-system/command.ts +80 -0
  53. package/src/design-system/index.ts +2 -0
  54. package/src/design-system/otp-input.ts +50 -0
  55. package/src/ui/command/animated/animations.ts +29 -0
  56. package/src/ui/command/animated/command-content-animated.tsx +58 -0
  57. package/src/ui/command/animated/index.ts +10 -0
  58. package/src/ui/command/animated/types.ts +23 -0
  59. package/src/ui/command/command-base.tsx +660 -0
  60. package/src/ui/command/command.test.tsx +130 -0
  61. package/src/ui/command/command.tsx +8 -0
  62. package/src/ui/command/index.ts +34 -0
  63. package/src/ui/command/types.ts +129 -0
  64. package/src/ui/command/variants.ts +41 -0
  65. package/src/ui/otp-input/index.ts +9 -0
  66. package/src/ui/otp-input/otp-input.test.tsx +99 -0
  67. package/src/ui/otp-input/otp-input.tsx +327 -0
  68. package/src/ui/otp-input/types.ts +32 -0
  69. package/src/ui/otp-input/variants.ts +18 -0
package/README.md CHANGED
@@ -13,14 +13,14 @@ Published artifacts live under `dist/`. Imports use **per-entry subpaths**: `@ze
13
13
 
14
14
  ## Package status and test coverage
15
15
 
16
- | Metric | Result |
17
- | ----------- | ---------------- |
18
- | Test files | 57 passed (57) |
19
- | Tests | 352 passed (352) |
16
+ | Metric | Result |
17
+ | ---------- | ---------------- |
18
+ | Test files | 57 passed (57) |
19
+ | Tests | 358 passed (358) |
20
20
 
21
21
  | Area | Test files | Tests |
22
22
  | --------------------------- | ---------- | ----- |
23
- | Components and UI utilities | 29 | 258 |
23
+ | Components and UI utilities | 29 | 264 |
24
24
  | React hooks | 26 | 85 |
25
25
  | CLI and import rewriting | 2 | 9 |
26
26
 
@@ -35,9 +35,11 @@ Published artifacts live under `dist/`. Imports use **per-entry subpaths**: `@ze
35
35
  | `cli/cli.integration.test.ts` | 4 |
36
36
  | `src/ui/buttons/button.test.tsx` | 41 |
37
37
  | `src/ui/inputs/input.test.tsx` | 40 |
38
+ | `src/ui/otp-input/otp-input.test.tsx` | 10 |
38
39
  | `src/ui/card/card.test.tsx` | 7 |
39
40
  | `src/ui/checkbox/checkbox.test.tsx` | 6 |
40
41
  | `src/ui/popover/popover.test.tsx` | 4 |
42
+ | `src/ui/command/command.test.tsx` | 7 |
41
43
  | `src/ui/tooltip/tooltip.test.tsx` | 4 |
42
44
  | `src/ui/dropdown/dropdown.test.tsx` | 6 |
43
45
  | `src/hooks/useFocusManagement/useFocusManagement.test.tsx` | 3 |
@@ -131,6 +133,7 @@ Import static primitives from `@zentauri-ui/zentauri-components/ui/<subpath>` wh
131
133
  | Card | `card` | `card/animated` |
132
134
  | Checkbox | `checkbox` | `checkbox/animated` |
133
135
  | Charts | `charts/<type>` | — |
136
+ | Command | `command` | `command/animated` |
134
137
  | Divider | `divider` | `divider/animated` |
135
138
  | Drawer | `drawer` | `drawer/animated` |
136
139
  | Dropdown | `dropdown` | — |
@@ -139,6 +142,7 @@ Import static primitives from `@zentauri-ui/zentauri-components/ui/<subpath>` wh
139
142
  | File upload | `file-upload` | — |
140
143
  | Input | `inputs` | `inputs/animated` |
141
144
  | Modal | `modal` | `modal/animated` |
145
+ | OTP input | `otp-input` | — |
142
146
  | Pagination | `pagination` | — |
143
147
  | Popover | `popover` | `popover/animated` |
144
148
  | Progress | `progress` | `progress/animated` |
@@ -656,7 +660,7 @@ From this package directory in the monorepo:
656
660
 
657
661
  - `pnpm build` (or `npm run build`) — production bundle via `tsup` (Rollup treeshake + `scripts/prepend-use-client.mjs` via `onSuccess` so each UI entry under `dist/ui/`, the chart entry under `dist/charts/`, and `dist/ui/<name>/animated.*` starts with `"use client"` where needed)
658
662
  - `pnpm dev` — `tsup` watch mode (same `onSuccess` hook after each rebuild)
659
- - `pnpm test` / `pnpm test:watch` — **Vitest** and **Testing Library** unit tests // covered 348 test cases in total
663
+ - `pnpm test` / `pnpm test:watch` — **Vitest** and **Testing Library** unit tests // covered 358 test cases in total
660
664
  - **`pnpm run generate:registry`** — runs `scripts/generate-registry.mjs`, which reads **`uiComponentNames`**, **`chartEntryNames`**, and **`hooksEntryNames`** from `tsup.config.ts`, merges in **`spinner`**, applies fixed **`nameAliases`**, and writes **`cli/registry.json`** (`components` + `hooks`). Run this after adding or renaming UI/chart areas or hook entries so the CLI stays in sync (the script prints counts).
661
665
 
662
666
  ## Github Release log
package/cli/registry.json CHANGED
@@ -15,6 +15,7 @@
15
15
  "charts/line",
16
16
  "charts/pie",
17
17
  "checkbox",
18
+ "command",
18
19
  "divider",
19
20
  "drawer",
20
21
  "dropdown",
@@ -23,6 +24,7 @@
23
24
  "file-upload",
24
25
  "inputs",
25
26
  "modal",
27
+ "otp-input",
26
28
  "pagination",
27
29
  "popover",
28
30
  "progress",
@@ -0,0 +1,600 @@
1
+ import { useFocusManagement } from './chunk-K6YI4FJO.mjs';
2
+ import { cn } from './chunk-4D54YOL6.mjs';
3
+ import { cva } from 'class-variance-authority';
4
+ import { createContext, useContext, useState, useCallback, useId, useRef, useMemo, useEffect } from 'react';
5
+ import { createPortal } from 'react-dom';
6
+ import { jsxs, jsx } from 'react/jsx-runtime';
7
+
8
+ // src/design-system/command.ts
9
+ var zuiCommandOverlayBase = "fixed inset-0 z-9999 bg-[var(--zui-command-overlay-bg,oklch(12.9%_0.042_264.695_/_0.6))] backdrop-blur-sm";
10
+ var zuiCommandTriggerBase = "relative inline-flex shrink-0 cursor-pointer items-center gap-2 rounded-md border border-[color:var(--zui-command-trigger-border,#0000001a)] dark:border-[color:var(--zui-command-trigger-border-dark,#ffffff1a)] bg-[var(--zui-command-trigger-bg,oklch(98.4%_0.003_247.858))] dark:bg-[var(--zui-command-trigger-bg-dark,oklch(12.9%_0.042_264.695))] px-3 py-2 text-sm text-[color:var(--zui-command-trigger-fg,oklch(44.6%_0.03_256.802))] dark:text-[color:var(--zui-command-trigger-fg-dark,oklch(86.9%_0.022_252.894))] transition hover:bg-black/5 dark:hover:bg-white/5 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-cyan-500/40";
11
+ var zuiCommandContentBase = "fixed left-1/2 top-[15%] z-9999 w-[calc(100%-2rem)] -translate-x-1/2 overflow-hidden rounded-xl border border-[color:var(--zui-command-content-border,#0000001a)] dark:border-[color:var(--zui-command-content-border-dark,#ffffff1a)] bg-[var(--zui-command-content-bg,oklch(98.4%_0.003_247.858))] dark:bg-[var(--zui-command-content-bg-dark,oklch(12.9%_0.042_264.695))] text-[color:var(--zui-command-content-fg,oklch(20.8%_0.042_265.755))] dark:text-[color:var(--zui-command-content-fg-dark,oklch(98.4%_0.003_247.858))] shadow-[var(--zui-command-content-shadow,0_12px_40px_rgba(15,23,42,0.18))] dark:shadow-[var(--zui-command-content-shadow-dark,0_24px_80px_rgba(15,23,42,0.6))] focus:outline-none";
12
+ var zuiCommandContentSizes = {
13
+ sm: "max-w-md",
14
+ md: "max-w-lg",
15
+ lg: "max-w-2xl"
16
+ };
17
+ var zuiCommandInputRowBase = "flex items-center gap-2 border-b border-[color:var(--zui-command-input-border,#0000000f)] dark:border-[color:var(--zui-command-input-border-dark,#ffffff14)] px-4";
18
+ var zuiCommandInputBase = "h-12 w-full bg-transparent text-sm text-[color:var(--zui-command-input-fg,oklch(20.8%_0.042_265.755))] dark:text-[color:var(--zui-command-input-fg-dark,oklch(98.4%_0.003_247.858))] placeholder:text-[color:var(--zui-command-input-placeholder,oklch(55.1%_0.027_264.364))] dark:placeholder:text-[color:var(--zui-command-input-placeholder-dark,oklch(55.1%_0.027_264.364))] focus:outline-none";
19
+ var zuiCommandListBase = "max-h-[min(60vh,420px)] overflow-y-auto overscroll-contain p-2";
20
+ var zuiCommandGroupHeadingBase = "px-2 pb-1 pt-3 text-xs font-semibold uppercase tracking-[0.12em] text-[color:var(--zui-command-group-heading-fg,oklch(55.1%_0.027_264.364))] dark:text-[color:var(--zui-command-group-heading-fg-dark,oklch(70.7%_0.022_261.325))]";
21
+ var zuiCommandItemBase = "flex cursor-pointer items-center gap-3 rounded-lg px-3 py-2 text-sm text-[color:var(--zui-command-item-fg,oklch(27.8%_0.033_256.848))] dark:text-[color:var(--zui-command-item-fg-dark,oklch(86.9%_0.022_252.894))] transition-colors data-[active=true]:bg-[var(--zui-command-item-active-bg,oklch(95.1%_0.026_236.824))] dark:data-[active=true]:bg-[var(--zui-command-item-active-bg-dark,oklch(28.2%_0.091_267.935_/_0.55))] data-[active=true]:text-[color:var(--zui-command-item-active-fg,oklch(20.8%_0.042_265.755))] dark:data-[active=true]:text-[color:var(--zui-command-item-active-fg-dark,oklch(98.4%_0.003_247.858))] aria-disabled:cursor-not-allowed aria-disabled:opacity-50";
22
+ var zuiCommandSeparatorBase = "my-1 h-px bg-[var(--zui-command-separator-bg,#0000000f)] dark:bg-[var(--zui-command-separator-bg-dark,#ffffff14)]";
23
+ var zuiCommandEmptyBase = "px-3 py-8 text-center text-sm text-[color:var(--zui-command-empty-fg,oklch(55.1%_0.027_264.364))] dark:text-[color:var(--zui-command-empty-fg-dark,oklch(70.7%_0.022_261.325))]";
24
+ var zuiCommandFooterBase = "flex items-center gap-3 border-t border-[color:var(--zui-command-footer-border,#0000000f)] dark:border-[color:var(--zui-command-footer-border-dark,#ffffff14)] px-4 py-2 text-xs text-[color:var(--zui-command-footer-fg,oklch(55.1%_0.027_264.364))] dark:text-[color:var(--zui-command-footer-fg-dark,oklch(70.7%_0.022_261.325))]";
25
+ var zuiCommandContentAppearances = {
26
+ default: "bg-[var(--zui-command-content-default-bg,oklch(98.4%_0.003_247.858))] dark:bg-[var(--zui-command-content-default-bg-dark,oklch(12.9%_0.042_264.695))]",
27
+ glass: "border-[color:var(--zui-command-content-glass-border,#00000026)] dark:border-[color:var(--zui-command-content-glass-border-dark,#ffffff26)] bg-[var(--zui-command-content-glass-bg,oklch(98.4%_0.003_247.858_/_0.7))] dark:bg-[var(--zui-command-content-glass-bg-dark,oklch(12.9%_0.042_264.695_/_0.7))] backdrop-blur-xl",
28
+ sky: "border-[color:var(--zui-command-content-sky-border,oklch(44.3%_0.11_240.79))] dark:border-[color:var(--zui-command-content-sky-border-dark,oklch(58.8%_0.158_241.966))] bg-[var(--zui-command-content-sky-bg,oklch(97.7%_0.013_236.62))] dark:bg-[var(--zui-command-content-sky-bg-dark,oklch(29.3%_0.066_243.157_/_0.7))] backdrop-blur-xl",
29
+ rose: "border-[color:var(--zui-command-content-rose-border,oklch(45.5%_0.188_13.697))] dark:border-[color:var(--zui-command-content-rose-border-dark,oklch(58.6%_0.253_17.585))] bg-[var(--zui-command-content-rose-bg,oklch(96.9%_0.015_12.422))] dark:bg-[var(--zui-command-content-rose-bg-dark,oklch(27.1%_0.105_12.094_/_0.7))] backdrop-blur-xl",
30
+ purple: "border-[color:var(--zui-command-content-purple-border,oklch(43.8%_0.218_303.724))] dark:border-[color:var(--zui-command-content-purple-border-dark,oklch(55.8%_0.288_302.321))] bg-[var(--zui-command-content-purple-bg,oklch(97.7%_0.014_308.299))] dark:bg-[var(--zui-command-content-purple-bg-dark,oklch(29.1%_0.149_302.717_/_0.7))] backdrop-blur-xl",
31
+ pink: "border-[color:var(--zui-command-content-pink-border,oklch(45.9%_0.187_3.815))] dark:border-[color:var(--zui-command-content-pink-border-dark,oklch(59.2%_0.249_0.584))] bg-[var(--zui-command-content-pink-bg,oklch(97.1%_0.014_343.198))] dark:bg-[var(--zui-command-content-pink-bg-dark,oklch(28.4%_0.109_3.907_/_0.7))] backdrop-blur-xl",
32
+ orange: "border-[color:var(--zui-command-content-orange-border,oklch(47%_0.157_37.304))] dark:border-[color:var(--zui-command-content-orange-border-dark,oklch(64.6%_0.222_41.116))] bg-[var(--zui-command-content-orange-bg,oklch(98%_0.016_73.684))] dark:bg-[var(--zui-command-content-orange-bg-dark,oklch(26.6%_0.079_36.259_/_0.7))] backdrop-blur-xl",
33
+ yellow: "border-[color:var(--zui-command-content-yellow-border,oklch(47.6%_0.114_61.907))] dark:border-[color:var(--zui-command-content-yellow-border-dark,oklch(68.1%_0.162_75.834))] bg-[var(--zui-command-content-yellow-bg,oklch(98.7%_0.026_102.212))] dark:bg-[var(--zui-command-content-yellow-bg-dark,oklch(28.6%_0.066_53.813_/_0.7))] backdrop-blur-xl",
34
+ teal: "border-[color:var(--zui-command-content-teal-border,oklch(43.7%_0.078_188.216))] dark:border-[color:var(--zui-command-content-teal-border-dark,oklch(60%_0.118_184.704))] bg-[var(--zui-command-content-teal-bg,oklch(98.4%_0.014_180.72))] dark:bg-[var(--zui-command-content-teal-bg-dark,oklch(27.7%_0.046_192.524_/_0.7))] backdrop-blur-xl",
35
+ indigo: "border-[color:var(--zui-command-content-indigo-border,oklch(39.8%_0.195_277.366))] dark:border-[color:var(--zui-command-content-indigo-border-dark,oklch(51.1%_0.262_276.966))] bg-[var(--zui-command-content-indigo-bg,oklch(96.2%_0.018_272.314))] dark:bg-[var(--zui-command-content-indigo-bg-dark,oklch(25.7%_0.09_281.288_/_0.7))] backdrop-blur-xl",
36
+ emerald: "border-[color:var(--zui-command-content-emerald-border,oklch(43.2%_0.095_166.913))] dark:border-[color:var(--zui-command-content-emerald-border-dark,oklch(59.6%_0.145_163.225))] bg-[var(--zui-command-content-emerald-bg,oklch(97.9%_0.021_166.113))] dark:bg-[var(--zui-command-content-emerald-bg-dark,oklch(26.2%_0.051_172.552_/_0.7))] backdrop-blur-xl",
37
+ gray: "border-[color:var(--zui-command-content-gray-border,oklch(27.8%_0.033_256.848))] dark:border-[color:var(--zui-command-content-gray-border-dark,oklch(44.6%_0.03_256.802))] bg-[var(--zui-command-content-gray-bg,oklch(98.5%_0.002_247.839))] dark:bg-[var(--zui-command-content-gray-bg-dark,oklch(13%_0.028_261.692_/_0.7))] backdrop-blur-xl",
38
+ amber: "border-[color:var(--zui-command-content-amber-border,oklch(47.3%_0.137_46.201))] dark:border-[color:var(--zui-command-content-amber-border-dark,oklch(66.6%_0.179_58.318))] bg-[var(--zui-command-content-amber-bg,oklch(98.7%_0.022_95.277))] dark:bg-[var(--zui-command-content-amber-bg-dark,oklch(27.9%_0.077_45.635_/_0.7))] backdrop-blur-xl",
39
+ violet: "border-[color:var(--zui-command-content-violet-border,oklch(43.2%_0.232_292.759))] dark:border-[color:var(--zui-command-content-violet-border-dark,oklch(54.1%_0.281_293.009))] bg-[var(--zui-command-content-violet-bg,oklch(96.9%_0.016_293.756))] dark:bg-[var(--zui-command-content-violet-bg-dark,oklch(28.3%_0.141_291.089_/_0.7))] backdrop-blur-xl",
40
+ "gradient-blue": "border-[color:var(--zui-command-content-gradient-blue-border,oklch(42.4%_0.199_265.638))] dark:border-[color:var(--zui-command-content-gradient-blue-border-dark,oklch(54.6%_0.245_262.881))] bg-linear-to-br from-[var(--zui-command-content-gradient-blue-from,oklch(97%_0.014_254.604))] dark:from-[var(--zui-command-content-gradient-blue-from-dark,oklch(28.2%_0.091_267.935_/_0.85))] to-[var(--zui-command-content-gradient-blue-to,oklch(97.7%_0.014_308.299))] dark:to-[var(--zui-command-content-gradient-blue-to-dark,oklch(29.1%_0.149_302.717_/_0.85))] backdrop-blur-xl",
41
+ "gradient-green": "border-[color:var(--zui-command-content-gradient-green-border,oklch(44.8%_0.119_151.328))] dark:border-[color:var(--zui-command-content-gradient-green-border-dark,oklch(62.7%_0.194_149.214))] bg-linear-to-br from-[var(--zui-command-content-gradient-green-from,oklch(98.2%_0.018_155.826))] dark:from-[var(--zui-command-content-gradient-green-from-dark,oklch(26.6%_0.065_152.934_/_0.85))] to-[var(--zui-command-content-gradient-green-to,oklch(98.6%_0.031_120.757))] dark:to-[var(--zui-command-content-gradient-green-to-dark,oklch(27.4%_0.072_132.109_/_0.85))] backdrop-blur-xl",
42
+ "gradient-red": "border-[color:var(--zui-command-content-gradient-red-border,oklch(44.4%_0.177_26.899))] dark:border-[color:var(--zui-command-content-gradient-red-border-dark,oklch(57.7%_0.245_27.325))] bg-linear-to-br from-[var(--zui-command-content-gradient-red-from,oklch(97.1%_0.013_17.38))] dark:from-[var(--zui-command-content-gradient-red-from-dark,oklch(25.8%_0.092_26.042_/_0.85))] to-[var(--zui-command-content-gradient-red-to,oklch(97.1%_0.014_343.198))] dark:to-[var(--zui-command-content-gradient-red-to-dark,oklch(28.4%_0.109_3.907_/_0.85))] backdrop-blur-xl",
43
+ "gradient-yellow": "border-[color:var(--zui-command-content-gradient-yellow-border,oklch(47.6%_0.114_61.907))] dark:border-[color:var(--zui-command-content-gradient-yellow-border-dark,oklch(68.1%_0.162_75.834))] bg-linear-to-br from-[var(--zui-command-content-gradient-yellow-from,oklch(98.7%_0.026_102.212))] dark:from-[var(--zui-command-content-gradient-yellow-from-dark,oklch(28.6%_0.066_53.813_/_0.85))] to-[var(--zui-command-content-gradient-yellow-to,oklch(98%_0.016_73.684))] dark:to-[var(--zui-command-content-gradient-yellow-to-dark,oklch(26.6%_0.079_36.259_/_0.85))] backdrop-blur-xl",
44
+ "gradient-purple": "border-[color:var(--zui-command-content-gradient-purple-border,oklch(43.8%_0.218_303.724))] dark:border-[color:var(--zui-command-content-gradient-purple-border-dark,oklch(55.8%_0.288_302.321))] bg-linear-to-br from-[var(--zui-command-content-gradient-purple-from,oklch(97.7%_0.014_308.299))] dark:from-[var(--zui-command-content-gradient-purple-from-dark,oklch(29.1%_0.149_302.717_/_0.85))] to-[var(--zui-command-content-gradient-purple-to,oklch(97.1%_0.014_343.198))] dark:to-[var(--zui-command-content-gradient-purple-to-dark,oklch(28.4%_0.109_3.907_/_0.85))] backdrop-blur-xl",
45
+ "gradient-teal": "border-[color:var(--zui-command-content-gradient-teal-border,oklch(43.7%_0.078_188.216))] dark:border-[color:var(--zui-command-content-gradient-teal-border-dark,oklch(60%_0.118_184.704))] bg-linear-to-br from-[var(--zui-command-content-gradient-teal-from,oklch(98.4%_0.014_180.72))] dark:from-[var(--zui-command-content-gradient-teal-from-dark,oklch(27.7%_0.046_192.524_/_0.85))] to-[var(--zui-command-content-gradient-teal-to,oklch(98.4%_0.019_200.873))] dark:to-[var(--zui-command-content-gradient-teal-to-dark,oklch(30.2%_0.056_229.695_/_0.85))] backdrop-blur-xl",
46
+ "gradient-indigo": "border-[color:var(--zui-command-content-gradient-indigo-border,oklch(39.8%_0.195_277.366))] dark:border-[color:var(--zui-command-content-gradient-indigo-border-dark,oklch(51.1%_0.262_276.966))] bg-linear-to-br from-[var(--zui-command-content-gradient-indigo-from,oklch(96.2%_0.018_272.314))] dark:from-[var(--zui-command-content-gradient-indigo-from-dark,oklch(25.7%_0.09_281.288_/_0.85))] to-[var(--zui-command-content-gradient-indigo-to,oklch(97.7%_0.014_308.299))] dark:to-[var(--zui-command-content-gradient-indigo-to-dark,oklch(29.1%_0.149_302.717_/_0.85))] backdrop-blur-xl",
47
+ "gradient-pink": "border-[color:var(--zui-command-content-gradient-pink-border,oklch(45.9%_0.187_3.815))] dark:border-[color:var(--zui-command-content-gradient-pink-border-dark,oklch(59.2%_0.249_0.584))] bg-linear-to-br from-[var(--zui-command-content-gradient-pink-from,oklch(97.1%_0.014_343.198))] dark:from-[var(--zui-command-content-gradient-pink-from-dark,oklch(28.4%_0.109_3.907_/_0.85))] to-[var(--zui-command-content-gradient-pink-to,oklch(96.9%_0.015_12.422))] dark:to-[var(--zui-command-content-gradient-pink-to-dark,oklch(27.1%_0.105_12.094_/_0.85))] backdrop-blur-xl"
48
+ };
49
+
50
+ // src/ui/command/variants.ts
51
+ var commandOverlayVariants = cva(zuiCommandOverlayBase);
52
+ var commandTriggerVariants = cva(zuiCommandTriggerBase);
53
+ var commandContentVariants = cva(zuiCommandContentBase, {
54
+ variants: {
55
+ size: zuiCommandContentSizes,
56
+ appearance: zuiCommandContentAppearances
57
+ },
58
+ defaultVariants: {
59
+ size: "md",
60
+ appearance: "default"
61
+ }
62
+ });
63
+ var commandInputRowVariants = cva(zuiCommandInputRowBase);
64
+ var commandInputVariants = cva(zuiCommandInputBase);
65
+ var commandListVariants = cva(zuiCommandListBase);
66
+ var commandGroupHeadingVariants = cva(zuiCommandGroupHeadingBase);
67
+ var commandItemVariants = cva(zuiCommandItemBase);
68
+ var commandSeparatorVariants = cva(zuiCommandSeparatorBase);
69
+ var commandEmptyVariants = cva(zuiCommandEmptyBase);
70
+ var commandFooterVariants = cva(zuiCommandFooterBase);
71
+ var CommandContext = createContext(null);
72
+ function useCommandContext(component) {
73
+ const ctx = useContext(CommandContext);
74
+ if (!ctx) {
75
+ throw new Error(`${component} must be used within <Command>`);
76
+ }
77
+ return ctx;
78
+ }
79
+ function itemMatches(value, meta, normalized) {
80
+ if (!normalized) {
81
+ return true;
82
+ }
83
+ if (value.toLowerCase().includes(normalized)) {
84
+ return true;
85
+ }
86
+ if (meta.searchText?.toLowerCase().includes(normalized)) {
87
+ return true;
88
+ }
89
+ return Boolean(
90
+ meta.keywords?.some(
91
+ (keyword) => keyword.toLowerCase().includes(normalized)
92
+ )
93
+ );
94
+ }
95
+ function isEditableEventTarget(target) {
96
+ if (!(target instanceof HTMLElement)) {
97
+ return false;
98
+ }
99
+ if (target.isContentEditable) {
100
+ return true;
101
+ }
102
+ return Boolean(
103
+ target.closest("input, textarea, select, [contenteditable=true]")
104
+ );
105
+ }
106
+ function useCommandPortalTarget() {
107
+ const [isMounted, setIsMounted] = useState(false);
108
+ useEffect(() => {
109
+ setIsMounted(true);
110
+ }, []);
111
+ if (!isMounted) {
112
+ return null;
113
+ }
114
+ return document.body;
115
+ }
116
+ function CommandPortal({ children }) {
117
+ const portalTarget = useCommandPortalTarget();
118
+ if (!portalTarget) {
119
+ return null;
120
+ }
121
+ return createPortal(children, portalTarget);
122
+ }
123
+ function CommandPortalFrame({ children }) {
124
+ return /* @__PURE__ */ jsx("div", { className: "fixed inset-0 z-9999", "data-slot": "command-portal", children });
125
+ }
126
+ function CommandContentLayer({
127
+ className,
128
+ size,
129
+ appearance,
130
+ children,
131
+ ref,
132
+ id,
133
+ style,
134
+ componentName,
135
+ renderPresence,
136
+ renderOverlay,
137
+ renderPanel
138
+ }) {
139
+ const { open, setOpen, labelId, contentRef, triggerRef } = useCommandContext(componentName);
140
+ useFocusManagement({
141
+ open,
142
+ setOpen,
143
+ contentRef,
144
+ triggerRef
145
+ });
146
+ const overlayProps = {
147
+ role: "presentation",
148
+ "data-slot": "command-overlay",
149
+ className: commandOverlayVariants(),
150
+ onClick: () => setOpen(false)
151
+ };
152
+ const panelProps = {
153
+ ref: (node) => {
154
+ contentRef.current = node;
155
+ if (typeof ref === "function") {
156
+ ref(node);
157
+ } else if (ref) {
158
+ ref.current = node;
159
+ }
160
+ },
161
+ role: "dialog",
162
+ "aria-modal": true,
163
+ "aria-labelledby": labelId,
164
+ "data-slot": "command-content",
165
+ tabIndex: -1,
166
+ className: cn(commandContentVariants({ size, appearance }), className),
167
+ id,
168
+ style,
169
+ children
170
+ };
171
+ const content = open ? /* @__PURE__ */ jsxs(CommandPortalFrame, { children: [
172
+ renderOverlay ? renderOverlay(overlayProps) : /* @__PURE__ */ jsx("div", { ...overlayProps }),
173
+ renderPanel ? renderPanel(panelProps) : /* @__PURE__ */ jsx("div", { ...panelProps })
174
+ ] }) : null;
175
+ return /* @__PURE__ */ jsx(CommandPortal, { children: renderPresence ? renderPresence(content) : content });
176
+ }
177
+ function Command({
178
+ open,
179
+ defaultOpen = false,
180
+ onOpenChange,
181
+ hotkey,
182
+ label = "Command menu",
183
+ children
184
+ }) {
185
+ const isControlled = open !== void 0;
186
+ const [uncontrolledOpen, setUncontrolledOpen] = useState(defaultOpen);
187
+ const resolvedOpen = isControlled ? Boolean(open) : uncontrolledOpen;
188
+ const setOpen = useCallback(
189
+ (next) => {
190
+ if (!isControlled) {
191
+ setUncontrolledOpen(next);
192
+ }
193
+ onOpenChange?.(next);
194
+ },
195
+ [isControlled, onOpenChange]
196
+ );
197
+ const labelId = useId();
198
+ const listId = useId();
199
+ const contentRef = useRef(null);
200
+ const triggerRef = useRef(null);
201
+ const inputRef = useRef(null);
202
+ const [query, setQuery] = useState("");
203
+ const [activeValue, setActiveValue] = useState(null);
204
+ const itemsRef = useRef([]);
205
+ const [registryVersion, setRegistryVersion] = useState(0);
206
+ const registerItem = useCallback((item) => {
207
+ itemsRef.current = [...itemsRef.current, item];
208
+ setRegistryVersion((version) => version + 1);
209
+ return () => {
210
+ itemsRef.current = itemsRef.current.filter((entry) => entry !== item);
211
+ setRegistryVersion((version) => version + 1);
212
+ };
213
+ }, []);
214
+ const invalidateRegistry = useCallback(() => {
215
+ setRegistryVersion((version) => version + 1);
216
+ }, []);
217
+ const visibleValues = useMemo(() => {
218
+ const normalized = query.trim().toLowerCase();
219
+ return itemsRef.current.filter((item) => {
220
+ const meta = item.metaRef.current;
221
+ if (meta.disabled) {
222
+ return false;
223
+ }
224
+ return itemMatches(item.value, meta, normalized);
225
+ }).map((item) => item.value);
226
+ }, [query, registryVersion]);
227
+ const visibleSet = useMemo(() => new Set(visibleValues), [visibleValues]);
228
+ const isVisible = useCallback(
229
+ (value) => visibleSet.has(value),
230
+ [visibleSet]
231
+ );
232
+ const selectValue = useCallback((value) => {
233
+ const entry = itemsRef.current.find((item) => item.value === value);
234
+ if (!entry || entry.metaRef.current.disabled) {
235
+ return false;
236
+ }
237
+ entry?.metaRef.current.onSelect?.(value);
238
+ return true;
239
+ }, []);
240
+ useEffect(() => {
241
+ if (!resolvedOpen) {
242
+ setQuery("");
243
+ setActiveValue(null);
244
+ }
245
+ }, [resolvedOpen]);
246
+ useEffect(() => {
247
+ if (!resolvedOpen) {
248
+ return;
249
+ }
250
+ if (activeValue && visibleSet.has(activeValue)) {
251
+ return;
252
+ }
253
+ setActiveValue(visibleValues[0] ?? null);
254
+ }, [resolvedOpen, activeValue, visibleSet, visibleValues]);
255
+ useEffect(() => {
256
+ if (!hotkey) {
257
+ return;
258
+ }
259
+ const key = (typeof hotkey === "string" ? hotkey : "k").toLowerCase();
260
+ const handler = (event) => {
261
+ if (isEditableEventTarget(event.target)) {
262
+ return;
263
+ }
264
+ if ((event.metaKey || event.ctrlKey) && event.key.toLowerCase() === key) {
265
+ event.preventDefault();
266
+ setOpen(!resolvedOpen);
267
+ }
268
+ };
269
+ window.addEventListener("keydown", handler);
270
+ return () => window.removeEventListener("keydown", handler);
271
+ }, [hotkey, resolvedOpen, setOpen]);
272
+ const ctx = useMemo(
273
+ () => ({
274
+ open: resolvedOpen,
275
+ setOpen,
276
+ labelId,
277
+ listId,
278
+ query,
279
+ setQuery,
280
+ activeValue,
281
+ setActiveValue,
282
+ visibleValues,
283
+ isVisible,
284
+ registerItem,
285
+ invalidateRegistry,
286
+ selectValue,
287
+ contentRef,
288
+ triggerRef,
289
+ inputRef
290
+ }),
291
+ [
292
+ resolvedOpen,
293
+ setOpen,
294
+ labelId,
295
+ listId,
296
+ query,
297
+ activeValue,
298
+ visibleValues,
299
+ isVisible,
300
+ registerItem,
301
+ invalidateRegistry,
302
+ selectValue
303
+ ]
304
+ );
305
+ return /* @__PURE__ */ jsxs(CommandContext.Provider, { value: ctx, children: [
306
+ /* @__PURE__ */ jsx("span", { hidden: true, id: labelId, children: label }),
307
+ children
308
+ ] });
309
+ }
310
+ Command.displayName = "Command";
311
+ function CommandTrigger({
312
+ className,
313
+ children,
314
+ onClick,
315
+ ref: refProp
316
+ }) {
317
+ const { setOpen, triggerRef } = useCommandContext("CommandTrigger");
318
+ return /* @__PURE__ */ jsx(
319
+ "button",
320
+ {
321
+ ref: (node) => {
322
+ triggerRef.current = node;
323
+ if (typeof refProp === "function") {
324
+ refProp(node);
325
+ } else if (refProp) {
326
+ refProp.current = node;
327
+ }
328
+ },
329
+ type: "button",
330
+ "data-slot": "command-trigger",
331
+ className: cn(commandTriggerVariants(), className),
332
+ onClick: (event) => {
333
+ onClick?.(event);
334
+ if (!event.defaultPrevented) {
335
+ setOpen(true);
336
+ }
337
+ },
338
+ children
339
+ }
340
+ );
341
+ }
342
+ CommandTrigger.displayName = "CommandTrigger";
343
+ function CommandContent({
344
+ className,
345
+ size,
346
+ appearance,
347
+ children,
348
+ ref,
349
+ id,
350
+ style
351
+ }) {
352
+ return /* @__PURE__ */ jsx(
353
+ CommandContentLayer,
354
+ {
355
+ appearance,
356
+ className,
357
+ componentName: "CommandContent",
358
+ id,
359
+ ref,
360
+ size,
361
+ style,
362
+ children
363
+ }
364
+ );
365
+ }
366
+ CommandContent.displayName = "CommandContent";
367
+ function CommandInput({
368
+ className,
369
+ placeholder,
370
+ ref
371
+ }) {
372
+ const {
373
+ query,
374
+ setQuery,
375
+ visibleValues,
376
+ activeValue,
377
+ setActiveValue,
378
+ selectValue,
379
+ setOpen,
380
+ inputRef,
381
+ listId
382
+ } = useCommandContext("CommandInput");
383
+ const moveActive = (direction) => {
384
+ if (visibleValues.length === 0) {
385
+ return;
386
+ }
387
+ const currentIndex = activeValue ? visibleValues.indexOf(activeValue) : -1;
388
+ const nextIndex = currentIndex === -1 ? direction === 1 ? 0 : visibleValues.length - 1 : (currentIndex + direction + visibleValues.length) % visibleValues.length;
389
+ setActiveValue(visibleValues[nextIndex] ?? null);
390
+ };
391
+ return /* @__PURE__ */ jsxs("div", { className: commandInputRowVariants(), "data-slot": "command-input-row", children: [
392
+ /* @__PURE__ */ jsxs(
393
+ "svg",
394
+ {
395
+ "aria-hidden": true,
396
+ viewBox: "0 0 24 24",
397
+ className: "size-4 shrink-0 opacity-60",
398
+ fill: "none",
399
+ stroke: "currentColor",
400
+ strokeWidth: "2",
401
+ strokeLinecap: "round",
402
+ strokeLinejoin: "round",
403
+ children: [
404
+ /* @__PURE__ */ jsx("circle", { cx: "11", cy: "11", r: "8" }),
405
+ /* @__PURE__ */ jsx("path", { d: "m21 21-4.3-4.3" })
406
+ ]
407
+ }
408
+ ),
409
+ /* @__PURE__ */ jsx(
410
+ "input",
411
+ {
412
+ ref: (node) => {
413
+ inputRef.current = node;
414
+ if (typeof ref === "function") {
415
+ ref(node);
416
+ } else if (ref) {
417
+ ref.current = node;
418
+ }
419
+ },
420
+ type: "text",
421
+ autoFocus: true,
422
+ role: "combobox",
423
+ "aria-expanded": true,
424
+ "aria-controls": listId,
425
+ "aria-autocomplete": "list",
426
+ "data-slot": "command-input",
427
+ className: cn(commandInputVariants(), className),
428
+ placeholder,
429
+ value: query,
430
+ onChange: (event) => setQuery(event.target.value),
431
+ onKeyDown: (event) => {
432
+ if (event.key === "ArrowDown") {
433
+ event.preventDefault();
434
+ moveActive(1);
435
+ } else if (event.key === "ArrowUp") {
436
+ event.preventDefault();
437
+ moveActive(-1);
438
+ } else if (event.key === "Enter") {
439
+ if (activeValue && visibleValues.includes(activeValue)) {
440
+ event.preventDefault();
441
+ if (selectValue(activeValue)) {
442
+ setOpen(false);
443
+ }
444
+ }
445
+ }
446
+ }
447
+ }
448
+ )
449
+ ] });
450
+ }
451
+ CommandInput.displayName = "CommandInput";
452
+ function CommandList({ className, children }) {
453
+ const { listId } = useCommandContext("CommandList");
454
+ return /* @__PURE__ */ jsx(
455
+ "div",
456
+ {
457
+ id: listId,
458
+ role: "listbox",
459
+ "aria-label": "Commands",
460
+ "data-slot": "command-list",
461
+ className: cn(commandListVariants(), className),
462
+ children
463
+ }
464
+ );
465
+ }
466
+ CommandList.displayName = "CommandList";
467
+ function CommandGroup({
468
+ className,
469
+ heading,
470
+ children
471
+ }) {
472
+ return /* @__PURE__ */ jsxs(
473
+ "div",
474
+ {
475
+ role: "group",
476
+ "data-slot": "command-group",
477
+ className: cn(
478
+ "[&:not(:has([data-slot=command-item]:not([hidden])))]:hidden",
479
+ className
480
+ ),
481
+ children: [
482
+ heading ? /* @__PURE__ */ jsx("div", { className: commandGroupHeadingVariants(), "aria-hidden": true, children: heading }) : null,
483
+ children
484
+ ]
485
+ }
486
+ );
487
+ }
488
+ CommandGroup.displayName = "CommandGroup";
489
+ function CommandItem({
490
+ className,
491
+ value,
492
+ keywords,
493
+ disabled,
494
+ onSelect,
495
+ children
496
+ }) {
497
+ const {
498
+ registerItem,
499
+ invalidateRegistry,
500
+ isVisible,
501
+ activeValue,
502
+ setActiveValue,
503
+ selectValue,
504
+ setOpen
505
+ } = useCommandContext("CommandItem");
506
+ const itemRef = useRef(null);
507
+ const keywordSignature = keywords?.join("\0") ?? "";
508
+ const metaRef = useRef({ keywords, disabled, onSelect });
509
+ metaRef.current = {
510
+ keywords,
511
+ disabled,
512
+ onSelect,
513
+ searchText: metaRef.current.searchText
514
+ };
515
+ useEffect(() => {
516
+ const unregister = registerItem({ value, metaRef });
517
+ return unregister;
518
+ }, [registerItem, value]);
519
+ useEffect(() => {
520
+ metaRef.current = {
521
+ keywords: metaRef.current.keywords,
522
+ disabled,
523
+ onSelect: metaRef.current.onSelect,
524
+ searchText: itemRef.current?.textContent ?? void 0
525
+ };
526
+ invalidateRegistry();
527
+ }, [children, disabled, invalidateRegistry, keywordSignature]);
528
+ const visible = isVisible(value);
529
+ const active = activeValue === value;
530
+ return /* @__PURE__ */ jsx(
531
+ "div",
532
+ {
533
+ ref: itemRef,
534
+ role: "option",
535
+ "aria-selected": active,
536
+ "aria-disabled": disabled || void 0,
537
+ "data-slot": "command-item",
538
+ "data-value": value,
539
+ "data-active": active || void 0,
540
+ hidden: !visible || void 0,
541
+ className: cn(commandItemVariants(), className),
542
+ onMouseEnter: () => {
543
+ if (!disabled) {
544
+ setActiveValue(value);
545
+ }
546
+ },
547
+ onClick: () => {
548
+ if (disabled) {
549
+ return;
550
+ }
551
+ if (selectValue(value)) {
552
+ setOpen(false);
553
+ }
554
+ },
555
+ children
556
+ }
557
+ );
558
+ }
559
+ CommandItem.displayName = "CommandItem";
560
+ function CommandSeparator({ className }) {
561
+ return /* @__PURE__ */ jsx(
562
+ "div",
563
+ {
564
+ role: "separator",
565
+ "data-slot": "command-separator",
566
+ className: cn(commandSeparatorVariants(), className)
567
+ }
568
+ );
569
+ }
570
+ CommandSeparator.displayName = "CommandSeparator";
571
+ function CommandEmpty({ className, children }) {
572
+ const { visibleValues } = useCommandContext("CommandEmpty");
573
+ if (visibleValues.length > 0) {
574
+ return null;
575
+ }
576
+ return /* @__PURE__ */ jsx(
577
+ "div",
578
+ {
579
+ "data-slot": "command-empty",
580
+ className: cn(commandEmptyVariants(), className),
581
+ children
582
+ }
583
+ );
584
+ }
585
+ CommandEmpty.displayName = "CommandEmpty";
586
+ function CommandFooter({ className, children }) {
587
+ return /* @__PURE__ */ jsx(
588
+ "div",
589
+ {
590
+ "data-slot": "command-footer",
591
+ className: cn(commandFooterVariants(), className),
592
+ children
593
+ }
594
+ );
595
+ }
596
+ CommandFooter.displayName = "CommandFooter";
597
+
598
+ export { Command, CommandContent, CommandContentLayer, CommandEmpty, CommandFooter, CommandGroup, CommandInput, CommandItem, CommandList, CommandSeparator, CommandTrigger, commandContentVariants, commandItemVariants, commandOverlayVariants, useCommandContext };
599
+ //# sourceMappingURL=chunk-KEKMMNL5.mjs.map
600
+ //# sourceMappingURL=chunk-KEKMMNL5.mjs.map