@zentauri-ui/zentauri-components 1.7.2 → 1.7.3

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 (49) hide show
  1. package/README.md +5 -3
  2. package/cli/registry.json +1 -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 +1 -0
  10. package/dist/design-system/index.d.ts.map +1 -1
  11. package/dist/ui/command/animated/animations.d.ts +3 -0
  12. package/dist/ui/command/animated/animations.d.ts.map +1 -0
  13. package/dist/ui/command/animated/command-content-animated.d.ts +6 -0
  14. package/dist/ui/command/animated/command-content-animated.d.ts.map +1 -0
  15. package/dist/ui/command/animated/index.d.ts +4 -0
  16. package/dist/ui/command/animated/index.d.ts.map +1 -0
  17. package/dist/ui/command/animated/types.d.ts +9 -0
  18. package/dist/ui/command/animated/types.d.ts.map +1 -0
  19. package/dist/ui/command/animated.js +92 -0
  20. package/dist/ui/command/animated.js.map +1 -0
  21. package/dist/ui/command/animated.mjs +89 -0
  22. package/dist/ui/command/animated.mjs.map +1 -0
  23. package/dist/ui/command/command-base.d.ts +53 -0
  24. package/dist/ui/command/command-base.d.ts.map +1 -0
  25. package/dist/ui/command/command.d.ts +6 -0
  26. package/dist/ui/command/command.d.ts.map +1 -0
  27. package/dist/ui/command/index.d.ts +5 -0
  28. package/dist/ui/command/index.d.ts.map +1 -0
  29. package/dist/ui/command/types.d.ts +111 -0
  30. package/dist/ui/command/types.d.ts.map +1 -0
  31. package/dist/ui/command/variants.d.ts +15 -0
  32. package/dist/ui/command/variants.d.ts.map +1 -0
  33. package/dist/ui/command.js +69 -0
  34. package/dist/ui/command.js.map +1 -0
  35. package/dist/ui/command.mjs +16 -0
  36. package/dist/ui/command.mjs.map +1 -0
  37. package/package.json +1 -1
  38. package/src/design-system/command.ts +80 -0
  39. package/src/design-system/index.ts +1 -0
  40. package/src/ui/command/animated/animations.ts +29 -0
  41. package/src/ui/command/animated/command-content-animated.tsx +58 -0
  42. package/src/ui/command/animated/index.ts +10 -0
  43. package/src/ui/command/animated/types.ts +23 -0
  44. package/src/ui/command/command-base.tsx +660 -0
  45. package/src/ui/command/command.test.tsx +130 -0
  46. package/src/ui/command/command.tsx +8 -0
  47. package/src/ui/command/index.ts +34 -0
  48. package/src/ui/command/types.ts +129 -0
  49. package/src/ui/command/variants.ts +41 -0
package/README.md CHANGED
@@ -16,11 +16,11 @@ Published artifacts live under `dist/`. Imports use **per-entry subpaths**: `@ze
16
16
  | Metric | Result |
17
17
  | ----------- | ---------------- |
18
18
  | Test files | 57 passed (57) |
19
- | Tests | 352 passed (352) |
19
+ | Tests | 355 passed (355) |
20
20
 
21
21
  | Area | Test files | Tests |
22
22
  | --------------------------- | ---------- | ----- |
23
- | Components and UI utilities | 29 | 258 |
23
+ | Components and UI utilities | 29 | 261 |
24
24
  | React hooks | 26 | 85 |
25
25
  | CLI and import rewriting | 2 | 9 |
26
26
 
@@ -38,6 +38,7 @@ Published artifacts live under `dist/`. Imports use **per-entry subpaths**: `@ze
38
38
  | `src/ui/card/card.test.tsx` | 7 |
39
39
  | `src/ui/checkbox/checkbox.test.tsx` | 6 |
40
40
  | `src/ui/popover/popover.test.tsx` | 4 |
41
+ | `src/ui/command/command.test.tsx` | 7 |
41
42
  | `src/ui/tooltip/tooltip.test.tsx` | 4 |
42
43
  | `src/ui/dropdown/dropdown.test.tsx` | 6 |
43
44
  | `src/hooks/useFocusManagement/useFocusManagement.test.tsx` | 3 |
@@ -131,6 +132,7 @@ Import static primitives from `@zentauri-ui/zentauri-components/ui/<subpath>` wh
131
132
  | Card | `card` | `card/animated` |
132
133
  | Checkbox | `checkbox` | `checkbox/animated` |
133
134
  | Charts | `charts/<type>` | — |
135
+ | Command | `command` | `command/animated` |
134
136
  | Divider | `divider` | `divider/animated` |
135
137
  | Drawer | `drawer` | `drawer/animated` |
136
138
  | Dropdown | `dropdown` | — |
@@ -656,7 +658,7 @@ From this package directory in the monorepo:
656
658
 
657
659
  - `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
660
  - `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
661
+ - `pnpm test` / `pnpm test:watch` — **Vitest** and **Testing Library** unit tests // covered 355 test cases in total
660
662
  - **`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
663
 
662
664
  ## 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",
@@ -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