@cascivo/react 0.5.1 → 0.6.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.
package/README.md CHANGED
@@ -116,6 +116,48 @@ aliases are documented in
116
116
  All components are client components (`'use client'` is preserved in the
117
117
  bundle), so the package works in Next.js App Router projects out of the box.
118
118
 
119
+ ## Using with AI tools (v0, Cursor, Claude Code, Gemini)
120
+
121
+ cascivo is AI-first, but a model can only build with it if the knowledge reaches
122
+ the tool. cascivo has no training-data footprint yet, so **don't rely on a tool
123
+ fetching cascivo.com** — that channel is the least reliable one. Use the channels
124
+ that travel with the package instead:
125
+
126
+ - **One file, one fetch — paste or link this into any chat/agent:**
127
+ [`https://cascivo.com/llms-full.txt`](https://cascivo.com/llms-full.txt). It is
128
+ the entire library — setup, the signals/CSS-layer rules, and every component's
129
+ props/examples/a11y — inlined, so a single successful fetch is enough. The
130
+ shorter index is [`llms.txt`](https://cascivo.com/llms.txt).
131
+ - **v0 / shadcn CLI** — components install straight from the
132
+ [shadcn-compatible registry](https://cascivo.com/r/shadcn/registry.json):
133
+
134
+ ```sh
135
+ npx shadcn@latest add https://cascivo.com/r/shadcn/button.json
136
+ ```
137
+
138
+ Each item inlines its own source and points its dependencies at absolute
139
+ `https://cascivo.com/r/shadcn/<name>.json` URLs, so the CLI resolves them
140
+ transitively. Register the whole namespace in `components.json` to use short
141
+ names (`npx shadcn add @cascivo/button`):
142
+
143
+ ```json
144
+ { "registries": { "@cascivo": "https://cascivo.com/r/shadcn/{name}.json" } }
145
+ ```
146
+
147
+ - **MCP-capable agents** (Claude Code, Cursor, Gemini CLI, Windsurf) — point the
148
+ client at the [`@cascivo/mcp`](https://www.npmjs.com/package/@cascivo/mcp)
149
+ server so it can query components with no web fetch at all:
150
+
151
+ ```json
152
+ { "mcpServers": { "cascivo": { "command": "npx", "args": ["-y", "@cascivo/mcp"] } } }
153
+ ```
154
+
155
+ **One rule to give the model:** cascivo is signal-driven — use `useSignal` /
156
+ `useComputed` / `useSignalEffect` from `@cascivo/core`, never `useState` /
157
+ `useEffect`, and in any app without the Babel signals transform a component that
158
+ reads `signal.value` in render must call `useSignals()` first or it won't
159
+ re-render. `llms-full.txt` carries the full contract.
160
+
119
161
  ## Guides
120
162
 
121
163
  - [Theming & branding](https://github.com/cascivo/cascivo/blob/main/docs/THEMING.md) — match a brand by overriding tokens (layer cascade, the `data-theme` specificity footgun, per-role radius/control-height tokens, a starter theme).
@@ -310,6 +352,7 @@ routing break after adding one of these, check that the import resolves to
310
352
  - **Cta** — Call-to-action band — quiet hairline-bordered section with title, description, and centered actions. Replace demo content before shipping.
311
353
  - **DashboardLayout** — Dashboard page layout with stats strip, main content area, and optional aside.
312
354
  - **FeatureGrid** — Feature section — AutoGrid of items with optional title, description, and icon slots. Icons are optional; the grid works text-only. Replace demo content before shipping.
355
+ - **Flex** — Flex layout primitive for vertical or horizontal stacking with gap control.
313
356
  - **Grid** — CSS grid layout primitive with responsive column collapsing.
314
357
  - **Hero** — Page hero section — centered or split layout with eyebrow, title, description, actions and media slots. Replace demo content before shipping.
315
358
  - **Indicator** — Positions an overlay element (badge, dot, count) at a corner of its child
@@ -325,7 +368,6 @@ routing break after adding one of these, check that the import resolves to
325
368
  - **Spacer** — Fixed-height spacing block using design token steps.
326
369
  - **SplitView** — Resizable two-pane split layout with keyboard and pointer drag support.
327
370
  - **Stack** — Overlaps children in a CSS grid stack with a configurable offset to create a card-pile effect
328
- - **Stack** — Flex layout primitive for vertical or horizontal stacking with gap control.
329
371
  - **StatsBand** — KPI strip — horizontal band of stats with optional delta and inline sparkline trend. Wraps via AutoGrid on narrow containers. No visible heading; provide aria-label for accessibility.
330
372
 
331
373
  ### Feedback
@@ -1 +1 @@
1
- @layer cascivo.component{._dialog_cpgn8_2{border-radius:var(--cascivo-radius-overlay);inline-size:min(40rem, calc(100vw - var(--cascivo-space-8)));max-block-size:calc(85vh - var(--cascivo-space-16));opacity:0;transition:opacity var(--cascivo-motion-exit), scale var(--cascivo-motion-exit), display var(--cascivo-duration-150) allow-discrete, overlay var(--cascivo-duration-150) allow-discrete;background:0 0;border:none;margin-block-start:15vh;margin-inline:auto;padding:0;overflow:visible;scale:.96}._dialog_cpgn8_2[open]{opacity:1;transition:opacity var(--cascivo-motion-enter), scale var(--cascivo-motion-enter), display var(--cascivo-duration-200) allow-discrete, overlay var(--cascivo-duration-200) allow-discrete;scale:1}@starting-style{._dialog_cpgn8_2[open]{opacity:0;scale:.96}}._dialog_cpgn8_2::backdrop{-webkit-backdrop-filter:blur(2px);backdrop-filter:blur(2px);opacity:0;transition:opacity var(--cascivo-motion-exit), display var(--cascivo-duration-150) allow-discrete, overlay var(--cascivo-duration-150) allow-discrete;background-color:#00000080}._dialog_cpgn8_2[open]::backdrop{opacity:1;transition:opacity var(--cascivo-motion-enter), display var(--cascivo-duration-200) allow-discrete, overlay var(--cascivo-duration-200) allow-discrete}@starting-style{._dialog_cpgn8_2[open]::backdrop{opacity:0}}._panel_cpgn8_62{background-color:var(--cascivo-color-surface-overlay);border:1px solid var(--cascivo-color-border);border-radius:var(--cascivo-radius-overlay);box-shadow:var(--cascivo-shadow-overlay);flex-direction:column;display:flex;overflow:hidden}._search_cpgn8_72{align-items:center;gap:var(--cascivo-space-3);padding-inline:var(--cascivo-space-4);border-block-end:1px solid var(--cascivo-color-border);display:flex}._searchIcon_cpgn8_80{color:var(--cascivo-color-text-muted);flex-shrink:0}._input_cpgn8_85{block-size:3rem;font-family:var(--cascivo-font-sans);font-size:var(--cascivo-text-base);color:var(--cascivo-color-text);background:0 0;border:none;flex:1;padding:0}._input_cpgn8_85:focus{outline:none}._input_cpgn8_85::placeholder{color:var(--cascivo-color-text-muted)}._list_cpgn8_104{max-block-size:20rem;padding:var(--cascivo-space-2);overflow-y:auto}._group_cpgn8_110+._group_cpgn8_110{margin-block-start:var(--cascivo-space-2)}._heading_cpgn8_114{padding-inline:var(--cascivo-space-2);padding-block:var(--cascivo-space-1);font-family:var(--cascivo-font-sans);font-size:var(--cascivo-text-xs);font-weight:var(--cascivo-font-medium);color:var(--cascivo-color-text-subtle)}._option_cpgn8_123{align-items:center;gap:var(--cascivo-space-3);padding-inline:var(--cascivo-space-2);padding-block:var(--cascivo-space-2);border-radius:var(--cascivo-radius-item);font-family:var(--cascivo-font-sans);font-size:var(--cascivo-text-sm);color:var(--cascivo-color-text);cursor:pointer;-webkit-user-select:none;user-select:none;display:flex}._option_cpgn8_123[data-state=active]{background-color:var(--cascivo-color-accent-muted)}._option_cpgn8_123[data-disabled]{opacity:.5;cursor:not-allowed}._icon_cpgn8_148{color:var(--cascivo-color-text-muted);flex-shrink:0;align-items:center;display:inline-flex}._label_cpgn8_155{text-overflow:ellipsis;white-space:nowrap;flex:1;overflow:hidden}._shortcut_cpgn8_162{gap:var(--cascivo-space-1);margin-inline-start:auto;display:inline-flex}._empty_cpgn8_168{padding-block:var(--cascivo-space-8);font-family:var(--cascivo-font-sans);font-size:var(--cascivo-text-sm);color:var(--cascivo-color-text-muted);text-align:center}._footer_cpgn8_176{gap:var(--cascivo-space-4);padding-inline:var(--cascivo-space-4);padding-block:var(--cascivo-space-2);border-block-start:1px solid var(--cascivo-color-border);font-family:var(--cascivo-font-sans);font-size:var(--cascivo-text-xs);color:var(--cascivo-color-text-subtle);display:flex}._hint_cpgn8_187{align-items:center;gap:var(--cascivo-space-1);display:inline-flex}}
1
+ @layer cascivo.component{._dialog_1dfrg_2{border-radius:var(--cascivo-radius-overlay);inline-size:min(40rem, calc(100vw - var(--cascivo-space-8)));max-block-size:calc(85vh - var(--cascivo-space-16));opacity:0;transition:opacity var(--cascivo-motion-exit), scale var(--cascivo-motion-exit), display var(--cascivo-duration-150) allow-discrete, overlay var(--cascivo-duration-150) allow-discrete;background:0 0;border:none;margin-block-start:15vh;margin-inline:auto;padding:0;overflow:visible;scale:.96}._dialog_1dfrg_2[open]{opacity:1;transition:opacity var(--cascivo-motion-enter), scale var(--cascivo-motion-enter), display var(--cascivo-duration-200) allow-discrete, overlay var(--cascivo-duration-200) allow-discrete;scale:1}@starting-style{._dialog_1dfrg_2[open]{opacity:0;scale:.96}}._dialog_1dfrg_2::backdrop{-webkit-backdrop-filter:blur(2px);backdrop-filter:blur(2px);opacity:0;transition:opacity var(--cascivo-motion-exit), display var(--cascivo-duration-150) allow-discrete, overlay var(--cascivo-duration-150) allow-discrete;background-color:#00000080}._dialog_1dfrg_2[open]::backdrop{opacity:1;transition:opacity var(--cascivo-motion-enter), display var(--cascivo-duration-200) allow-discrete, overlay var(--cascivo-duration-200) allow-discrete}@starting-style{._dialog_1dfrg_2[open]::backdrop{opacity:0}}._panel_1dfrg_62{background-color:var(--cascivo-color-surface-overlay);border:1px solid var(--cascivo-color-border);border-radius:var(--cascivo-radius-overlay);box-shadow:var(--cascivo-shadow-overlay);flex-direction:column;display:flex;overflow:hidden}._search_1dfrg_72{align-items:center;gap:var(--cascivo-space-3);padding-inline:var(--cascivo-space-4);border-block-end:1px solid var(--cascivo-color-border);display:flex}._searchIcon_1dfrg_80{color:var(--cascivo-color-text-muted);flex-shrink:0}._scopeChip_1dfrg_85{align-items:center;gap:var(--cascivo-space-1);padding-inline:var(--cascivo-space-2);padding-block:var(--cascivo-space-1);border:1px solid var(--cascivo-color-accent-subtle);border-radius:var(--cascivo-radius-item);background-color:var(--cascivo-color-accent-muted);font-family:var(--cascivo-font-sans);font-size:var(--cascivo-text-xs);font-weight:var(--cascivo-font-medium);color:var(--cascivo-color-accent-content);white-space:nowrap;flex-shrink:0;display:inline-flex}._scopeChip_1dfrg_85 ._scopeClear_1dfrg_101{color:inherit;cursor:pointer;opacity:.7;background:0 0;border:none;justify-content:center;align-items:center;padding:0;display:inline-flex}._scopeChip_1dfrg_85 ._scopeClear_1dfrg_101:hover{opacity:1}@media (pointer:coarse){._scopeChip_1dfrg_85 ._scopeClear_1dfrg_101{min-inline-size:var(--cascivo-space-6);min-block-size:var(--cascivo-space-6)}}._input_1dfrg_123{block-size:3rem;font-family:var(--cascivo-font-sans);font-size:var(--cascivo-text-base);color:var(--cascivo-color-text);background:0 0;border:none;flex:1;padding:0}._input_1dfrg_123:focus{outline:none}._input_1dfrg_123::placeholder{color:var(--cascivo-color-text-muted)}._scopes_1dfrg_142{align-items:center;gap:var(--cascivo-space-2);padding-inline:var(--cascivo-space-4);padding-block:var(--cascivo-space-2);border-block-end:1px solid var(--cascivo-color-border);background-color:var(--cascivo-color-bg-subtle);display:flex;overflow-x:auto}._scopesLabel_1dfrg_153{font-family:var(--cascivo-font-sans);font-size:var(--cascivo-text-xs);font-weight:var(--cascivo-font-medium);letter-spacing:.04em;text-transform:uppercase;color:var(--cascivo-color-text-subtle);flex-shrink:0}._scopePill_1dfrg_163{align-items:center;gap:var(--cascivo-space-1);padding-inline:var(--cascivo-space-2);padding-block:var(--cascivo-space-1);border:1px solid var(--cascivo-color-border);border-radius:var(--cascivo-radius-item);font-family:var(--cascivo-font-sans);font-size:var(--cascivo-text-xs);color:var(--cascivo-color-text-muted);cursor:pointer;background:0 0;flex-shrink:0;display:inline-flex}._scopePill_1dfrg_163:hover{color:var(--cascivo-color-text)}._scopePill_1dfrg_163[data-active]{border-color:var(--cascivo-color-accent-subtle);background-color:var(--cascivo-color-accent-muted);color:var(--cascivo-color-accent-content)}@media (pointer:coarse){._scopePill_1dfrg_163{min-block-size:var(--cascivo-target-min-coarse,2.75rem)}}._scopePrefix_1dfrg_193{font-family:var(--cascivo-font-mono);font-weight:var(--cascivo-font-medium);opacity:.85}._list_1dfrg_199{max-block-size:20rem;padding:var(--cascivo-space-2);overflow-y:auto}._group_1dfrg_205+._group_1dfrg_205{margin-block-start:var(--cascivo-space-2)}._heading_1dfrg_209{justify-content:space-between;align-items:baseline;gap:var(--cascivo-space-2);padding-inline:var(--cascivo-space-2);padding-block:var(--cascivo-space-1);font-family:var(--cascivo-font-sans);font-size:var(--cascivo-text-xs);font-weight:var(--cascivo-font-medium);color:var(--cascivo-color-text-subtle);display:flex}._count_1dfrg_222{font-family:var(--cascivo-font-mono);font-weight:var(--cascivo-font-normal);color:var(--cascivo-color-text-muted)}._option_1dfrg_228{align-items:center;gap:var(--cascivo-space-3);padding-inline:var(--cascivo-space-2);padding-block:var(--cascivo-space-2);border-radius:var(--cascivo-radius-item);font-family:var(--cascivo-font-sans);font-size:var(--cascivo-text-sm);color:var(--cascivo-color-text);cursor:pointer;-webkit-user-select:none;user-select:none;display:flex}._option_1dfrg_228[data-state=active]{background-color:var(--cascivo-color-accent-muted)}._option_1dfrg_228[data-disabled]{opacity:.5;cursor:not-allowed}._icon_1dfrg_253{color:var(--cascivo-color-text-muted);flex-shrink:0;align-items:center;display:inline-flex}._text_1dfrg_260{flex-direction:column;flex:1;gap:.125rem;min-inline-size:0;display:flex}._label_1dfrg_268{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}._match_1dfrg_274{color:var(--cascivo-color-accent-content);font-weight:var(--cascivo-font-semibold);background:0 0}._description_1dfrg_280{text-overflow:ellipsis;white-space:nowrap;font-family:var(--cascivo-font-mono);font-size:var(--cascivo-text-xs);color:var(--cascivo-color-text-muted);overflow:hidden}._status_1dfrg_289{align-items:center;gap:var(--cascivo-space-1);padding-inline:var(--cascivo-space-2);border-radius:var(--cascivo-radius-pill,9999px);font-size:var(--cascivo-text-xs);font-weight:var(--cascivo-font-medium);flex-shrink:0;margin-inline-start:auto;padding-block:.125rem;display:inline-flex}._status_1dfrg_289[data-tone=healthy]{background-color:var(--cascivo-color-success-subtle);color:var(--cascivo-color-success-foreground)}._status_1dfrg_289[data-tone=degraded]{background-color:var(--cascivo-color-warning-subtle);color:var(--cascivo-color-warning-foreground)}._status_1dfrg_289[data-tone=neutral]{background-color:var(--cascivo-color-bg-subtle);color:var(--cascivo-color-text-muted)}._status_1dfrg_289 ._statusDot_1dfrg_316{background-color:currentColor;border-radius:9999px;block-size:.375rem;inline-size:.375rem}._actions_1dfrg_325{gap:var(--cascivo-space-1);opacity:0;pointer-events:none;transition:opacity var(--cascivo-motion-enter);flex-shrink:0;margin-inline-start:auto;display:inline-flex}._status_1dfrg_289+._actions_1dfrg_325{margin-inline-start:var(--cascivo-space-2)}._option_1dfrg_228[data-state=active] ._actions_1dfrg_325,._option_1dfrg_228:hover ._actions_1dfrg_325{opacity:1;pointer-events:auto}._action_1dfrg_325{align-items:center;gap:var(--cascivo-space-1);padding-inline:var(--cascivo-space-2);padding-block:var(--cascivo-space-1);border:1px solid var(--cascivo-color-border);border-radius:var(--cascivo-radius-item);background-color:var(--cascivo-color-surface-overlay);font-family:var(--cascivo-font-sans);font-size:var(--cascivo-text-xs);color:var(--cascivo-color-text);cursor:pointer;display:inline-flex}._action_1dfrg_325:hover{border-color:var(--cascivo-color-accent-subtle)}@media (pointer:coarse){._action_1dfrg_325{min-block-size:var(--cascivo-target-min-coarse,2.75rem)}}._actionKeys_1dfrg_369{gap:var(--cascivo-space-1);display:inline-flex}._shortcut_1dfrg_374{gap:var(--cascivo-space-1);flex-shrink:0;margin-inline-start:auto;display:inline-flex}._actions_1dfrg_325~._shortcut_1dfrg_374{margin-inline-start:var(--cascivo-space-2)}@media (prefers-reduced-motion:reduce){._actions_1dfrg_325{transition:none}}._empty_1dfrg_392{padding-block:var(--cascivo-space-8);font-family:var(--cascivo-font-sans);font-size:var(--cascivo-text-sm);color:var(--cascivo-color-text-muted);text-align:center}._footer_1dfrg_400{gap:var(--cascivo-space-4);padding-inline:var(--cascivo-space-4);padding-block:var(--cascivo-space-2);border-block-start:1px solid var(--cascivo-color-border);font-family:var(--cascivo-font-sans);font-size:var(--cascivo-text-xs);color:var(--cascivo-color-text-subtle);display:flex}._hint_1dfrg_411{align-items:center;gap:var(--cascivo-space-1);display:inline-flex}}
@@ -6,18 +6,27 @@ import n from "./command-menu.module.js";
6
6
  import { batch as r, cn as i, useSignal as a, useSignalEffect as o, useSignals as s } from "@cascivo/core";
7
7
  import { builtin as c, t as l } from "@cascivo/i18n";
8
8
  import { jsx as u, jsxs as d } from "react/jsx-runtime";
9
- import { useId as f, useRef as p } from "react";
9
+ import { useId as ee, useRef as f } from "react";
10
10
  //#region ../components/src/command-menu/command-menu.tsx
11
- function m(e, t) {
12
- if (e.length === 0) return 1;
13
- let n = e.toLowerCase(), r = t.toLowerCase(), i = 0, a = 0, o = -2;
11
+ function p(e, t) {
12
+ if (e.length === 0) return {
13
+ score: 1,
14
+ indices: []
15
+ };
16
+ let n = e.toLowerCase(), r = t.toLowerCase(), i = 0, a = 0, o = -2, s = [];
14
17
  for (let e = 0; e < r.length && a < n.length; e++) {
15
18
  if (r[e] !== n[a]) continue;
16
19
  i += 1, e === o + 1 && (i += 4);
17
20
  let t = e === 0 ? " " : r[e - 1];
18
- (t === " " || t === "-" || t === "_" || t === "/") && (i += 8), o = e, a++;
21
+ (t === " " || t === "-" || t === "_" || t === "/") && (i += 8), o = e, s.push(e), a++;
19
22
  }
20
- return a === n.length ? i : 0;
23
+ return a === n.length ? {
24
+ score: i,
25
+ indices: s
26
+ } : null;
27
+ }
28
+ function m(e, t) {
29
+ return p(e, t)?.score ?? 0;
21
30
  }
22
31
  function h(e, t) {
23
32
  let n = m(e, t.label);
@@ -27,198 +36,344 @@ function h(e, t) {
27
36
  }
28
37
  return n;
29
38
  }
30
- function g({ open: m, onOpenChange: g, groups: _, placeholder: v, emptyLabel: y, hotkey: b = !0, label: x, loading: S = !1, onQueryChange: C, className: w }) {
39
+ function g(e, t) {
40
+ if (t.length === 0) return e;
41
+ let r = new Set(t), i = [], a = "", o = r.has(0), s = (e) => {
42
+ a !== "" && (i.push(o ? /* @__PURE__ */ u("mark", {
43
+ className: n.match,
44
+ children: a
45
+ }, e) : a), a = "");
46
+ };
47
+ for (let t = 0; t < e.length; t++) {
48
+ let n = r.has(t);
49
+ n !== o && (s(t), o = n), a += e[t];
50
+ }
51
+ return s(e.length), i;
52
+ }
53
+ function _(e, t) {
54
+ for (let n of t) {
55
+ let t = n.prefix;
56
+ if (t) {
57
+ if (e.startsWith(`${t} `) || e.startsWith(`${t}:`)) return {
58
+ scope: n,
59
+ rest: e.slice(t.length + 1).replace(/^\s+/, "")
60
+ };
61
+ if (!/\w/.test(t) && e.startsWith(t)) return {
62
+ scope: n,
63
+ rest: e.slice(t.length).replace(/^\s+/, "")
64
+ };
65
+ }
66
+ }
67
+ return null;
68
+ }
69
+ function v({ open: m, onOpenChange: v, groups: te, placeholder: y, emptyLabel: b, hotkey: x = !0, label: S, loading: C = !1, onQueryChange: w, scopes: T = [], className: E }) {
31
70
  s();
32
- let T = x ?? l(c.commandMenu.label), E = y ?? l(c.commandMenu.empty), D = f(), O = `${D}-listbox`, k = p(null), A = p(null), j = p([]), M = p(g);
33
- M.current = g;
34
- let N = p(C);
35
- N.current = C;
36
- let P = a(m);
37
- P.value = m;
38
- let F = a(b);
39
- F.value = b;
40
- let I = a(""), L = a(0), R = a([]), z = R.value.at(-1)?.groups ?? _, B = v ?? R.value.at(-1)?.placeholder ?? l(c.commandMenu.placeholder), V = z.map((e) => ({
71
+ let D = S ?? l(c.commandMenu.label), ne = b ?? l(c.commandMenu.empty), O = ee(), k = `${O}-listbox`, A = f(null), j = f(null), M = f([]), N = f(v);
72
+ N.current = v;
73
+ let P = f(w);
74
+ P.current = w;
75
+ let F = a(m);
76
+ F.value = m;
77
+ let I = a(x);
78
+ I.value = x;
79
+ let L = a(""), R = a(0), z = a([]), B = a(null), re = z.value.at(-1)?.groups ?? te, ie = y ?? z.value.at(-1)?.placeholder ?? l(c.commandMenu.placeholder), V = T.find((e) => e.id === B.value) ?? null, H = re.filter((e) => !B.value || !e.scope || e.scope === B.value).map((e) => ({
41
80
  heading: e.heading,
42
81
  items: e.items.map((e) => ({
43
82
  item: e,
44
- score: h(I.value, e)
45
- })).filter(({ score: e }) => e > 0).sort((e, t) => t.score - e.score).map(({ item: e }) => e)
46
- })).filter((e) => e.items.length > 0), H = V.flatMap((e) => e.items), U = H.flatMap((e, t) => e.disabled ? [] : [t]), W = U.includes(L.value) ? L.value : U[0] ?? -1, G = (e) => `${D}-option-${e}`;
83
+ score: h(L.value, e)
84
+ })).filter(({ score: e }) => e > 0).sort((e, t) => t.score - e.score).map(({ item: e }) => ({
85
+ item: e,
86
+ indices: p(L.value, e.label)?.indices ?? []
87
+ }))
88
+ })).filter((e) => e.items.length > 0), U = H.flatMap((e) => e.items.map((e) => e.item)), W = U.flatMap((e, t) => e.disabled ? [] : [t]), G = W.includes(R.value) ? R.value : W[0] ?? -1, K = (e) => `${O}-option-${e}`;
47
89
  o(() => {
48
- let e = k.current;
49
- e && (P.value ? e.open || (r(() => {
50
- I.value = "", L.value = 0, R.value = [];
51
- }), typeof e.showModal == "function" && e.showModal(), A.current?.focus()) : e.open && (R.value = [], e.close()));
90
+ let e = A.current;
91
+ e && (F.value ? e.open || (r(() => {
92
+ L.value = "", R.value = 0, z.value = [], B.value = null;
93
+ }), typeof e.showModal == "function" && e.showModal(), j.current?.focus()) : e.open && (z.value = [], e.close()));
52
94
  }), o(() => {
53
- let e = k.current;
95
+ let e = A.current;
54
96
  if (!e) return;
55
- let t = () => M.current(!1);
97
+ let t = () => N.current(!1);
56
98
  return e.addEventListener("close", t), () => e.removeEventListener("close", t);
57
99
  }), o(() => {
58
- if (!F.value) return;
100
+ if (!I.value) return;
59
101
  let e = (e) => {
60
- (e.metaKey || e.ctrlKey) && e.key.toLowerCase() === "k" && (e.preventDefault(), M.current(!P.value));
102
+ (e.metaKey || e.ctrlKey) && e.key.toLowerCase() === "k" && (e.preventDefault(), N.current(!F.value));
61
103
  };
62
104
  return window.addEventListener("keydown", e), () => window.removeEventListener("keydown", e);
63
105
  });
64
- let K = (e) => {
65
- L.value = e;
66
- let t = j.current[e];
106
+ let q = (e) => {
107
+ R.value = e;
108
+ let t = M.current[e];
67
109
  t && typeof t.scrollIntoView == "function" && t.scrollIntoView({ block: "nearest" });
68
- }, q = (e) => {
69
- if (U.length === 0) return;
70
- let t = U[(U.indexOf(W) + e + U.length) % U.length];
71
- t !== void 0 && K(t);
72
110
  }, J = (e) => {
73
- !e || e.disabled || (e.page ? r(() => {
74
- R.value = [...R.value, e.page], I.value = "", L.value = 0;
75
- }) : (e.onSelect?.(), g(!1)));
76
- }, Y = () => {
111
+ if (W.length === 0) return;
112
+ let t = W[(W.indexOf(G) + e + W.length) % W.length];
113
+ t !== void 0 && q(t);
114
+ }, Y = (e) => {
115
+ e.onSelect(), v(!1);
116
+ }, X = (e, t) => {
117
+ if (!(!e || e.disabled)) {
118
+ if (e.page) {
119
+ if (t === "secondary") return;
120
+ r(() => {
121
+ z.value = [...z.value, e.page], L.value = "", R.value = 0;
122
+ });
123
+ return;
124
+ }
125
+ if (e.actions && e.actions.length > 0) {
126
+ let n = t === "secondary" ? e.actions[1] : e.actions[0];
127
+ n && Y(n);
128
+ return;
129
+ }
130
+ t !== "secondary" && (e.onSelect?.(), v(!1));
131
+ }
132
+ }, ae = (e) => {
133
+ if (T.length === 0) return;
134
+ let t = [null, ...T.map((e) => e.id)], n = t[(t.indexOf(B.value) + e + t.length) % t.length];
135
+ r(() => {
136
+ B.value = n ?? null, R.value = 0;
137
+ });
138
+ }, Z = () => {
139
+ r(() => {
140
+ B.value = null, R.value = 0;
141
+ }), j.current?.focus();
142
+ }, Q = () => {
77
143
  r(() => {
78
- R.value = R.value.slice(0, -1), I.value = "", L.value = 0;
144
+ z.value = z.value.slice(0, -1), L.value = "", R.value = 0;
79
145
  });
80
- }, X = (e) => {
146
+ }, oe = (e) => {
81
147
  switch (e.key) {
82
148
  case "ArrowDown":
83
- e.preventDefault(), q(1);
149
+ e.preventDefault(), J(1);
84
150
  break;
85
151
  case "ArrowUp":
86
- e.preventDefault(), q(-1);
152
+ e.preventDefault(), J(-1);
153
+ break;
154
+ case "Tab":
155
+ T.length > 0 && (e.preventDefault(), ae(e.shiftKey ? -1 : 1));
87
156
  break;
88
157
  case "Home":
89
- e.preventDefault(), U[0] !== void 0 && K(U[0]);
158
+ e.preventDefault(), W[0] !== void 0 && q(W[0]);
90
159
  break;
91
160
  case "End": {
92
161
  e.preventDefault();
93
- let t = U[U.length - 1];
94
- t !== void 0 && K(t);
162
+ let t = W[W.length - 1];
163
+ t !== void 0 && q(t);
95
164
  break;
96
165
  }
97
166
  case "Enter":
98
- e.preventDefault(), W >= 0 && J(H[W]);
167
+ e.preventDefault(), G >= 0 && X(U[G], e.metaKey || e.ctrlKey ? "secondary" : "primary");
99
168
  break;
100
169
  case "Backspace":
101
- I.value === "" && R.value.length > 0 && (e.preventDefault(), Y());
170
+ L.value === "" && (z.value.length > 0 ? (e.preventDefault(), Q()) : B.value && (e.preventDefault(), Z()));
102
171
  break;
103
172
  }
104
- }, Z = (e) => {
105
- e.key === "Escape" && (e.preventDefault(), R.value.length > 0 ? Y() : k.current?.close());
106
- }, Q = (e) => {
107
- e.target === k.current && k.current?.close();
173
+ }, se = (e) => {
174
+ e.key === "Escape" && (e.preventDefault(), z.value.length > 0 ? Q() : A.current?.close());
175
+ }, ce = (e) => {
176
+ e.target === A.current && A.current?.close();
108
177
  }, $ = -1;
109
178
  return /* @__PURE__ */ u("dialog", {
110
- ref: k,
111
- "aria-label": T,
112
- className: i(n.dialog, w),
113
- onClick: Q,
114
- onKeyDown: Z,
179
+ ref: A,
180
+ "aria-label": D,
181
+ className: i(n.dialog, E),
182
+ onClick: ce,
183
+ onKeyDown: se,
115
184
  children: /* @__PURE__ */ d("div", {
116
185
  className: n.panel,
117
186
  children: [
118
187
  /* @__PURE__ */ d("div", {
119
188
  className: n.search,
120
- children: [/* @__PURE__ */ d("svg", {
121
- className: n.searchIcon,
122
- "aria-hidden": "true",
123
- viewBox: "0 0 16 16",
124
- width: "16",
125
- height: "16",
126
- fill: "none",
127
- stroke: "currentColor",
128
- strokeWidth: "1.5",
129
- strokeLinecap: "round",
130
- children: [/* @__PURE__ */ u("circle", {
131
- cx: "7",
132
- cy: "7",
133
- r: "4.5"
134
- }), /* @__PURE__ */ u("line", {
135
- x1: "10.5",
136
- y1: "10.5",
137
- x2: "14",
138
- y2: "14"
139
- })]
140
- }), /* @__PURE__ */ u("input", {
141
- ref: A,
142
- type: "text",
143
- role: "combobox",
144
- "aria-expanded": "true",
145
- "aria-controls": O,
146
- "aria-activedescendant": W >= 0 ? G(W) : void 0,
147
- "aria-autocomplete": "list",
148
- "aria-label": T,
149
- autoComplete: "off",
150
- spellCheck: !1,
151
- className: n.input,
152
- placeholder: B,
153
- value: I.value,
154
- onChange: (e) => {
155
- I.value = e.target.value, L.value = 0, N.current?.(e.target.value);
189
+ children: [
190
+ /* @__PURE__ */ d("svg", {
191
+ className: n.searchIcon,
192
+ "aria-hidden": "true",
193
+ viewBox: "0 0 16 16",
194
+ width: "16",
195
+ height: "16",
196
+ fill: "none",
197
+ stroke: "currentColor",
198
+ strokeWidth: "1.5",
199
+ strokeLinecap: "round",
200
+ children: [/* @__PURE__ */ u("circle", {
201
+ cx: "7",
202
+ cy: "7",
203
+ r: "4.5"
204
+ }), /* @__PURE__ */ u("line", {
205
+ x1: "10.5",
206
+ y1: "10.5",
207
+ x2: "14",
208
+ y2: "14"
209
+ })]
210
+ }),
211
+ V && /* @__PURE__ */ d("span", {
212
+ className: n.scopeChip,
213
+ children: [V.label, /* @__PURE__ */ u("button", {
214
+ type: "button",
215
+ className: n.scopeClear,
216
+ "aria-label": l(c.commandMenu.clearScope),
217
+ onClick: Z,
218
+ children: /* @__PURE__ */ u("svg", {
219
+ viewBox: "0 0 16 16",
220
+ width: "12",
221
+ height: "12",
222
+ "aria-hidden": "true",
223
+ children: /* @__PURE__ */ u("path", {
224
+ d: "M4 4l8 8M12 4l-8 8",
225
+ fill: "none",
226
+ stroke: "currentColor",
227
+ strokeWidth: "1.5",
228
+ strokeLinecap: "round"
229
+ })
230
+ })
231
+ })]
232
+ }),
233
+ /* @__PURE__ */ u("input", {
234
+ ref: j,
235
+ type: "text",
236
+ role: "combobox",
237
+ "aria-expanded": "true",
238
+ "aria-controls": k,
239
+ "aria-activedescendant": G >= 0 ? K(G) : void 0,
240
+ "aria-autocomplete": "list",
241
+ "aria-label": D,
242
+ autoComplete: "off",
243
+ spellCheck: !1,
244
+ className: n.input,
245
+ placeholder: ie,
246
+ value: L.value,
247
+ onChange: (e) => {
248
+ let t = e.target.value;
249
+ if (!B.value && T.length > 0) {
250
+ let e = _(t, T);
251
+ e && (B.value = e.scope.id, t = e.rest);
252
+ }
253
+ L.value = t, R.value = 0, P.current?.(t);
254
+ },
255
+ onKeyDown: oe
256
+ })
257
+ ]
258
+ }),
259
+ T.length > 0 && /* @__PURE__ */ d("div", {
260
+ className: n.scopes,
261
+ children: [/* @__PURE__ */ u("span", {
262
+ className: n.scopesLabel,
263
+ children: l(c.commandMenu.scopeLabel)
264
+ }), T.map((e) => /* @__PURE__ */ d("button", {
265
+ type: "button",
266
+ className: n.scopePill,
267
+ "data-active": e.id === B.value || void 0,
268
+ onClick: () => {
269
+ r(() => {
270
+ B.value = B.value === e.id ? null : e.id, R.value = 0;
271
+ }), j.current?.focus();
156
272
  },
157
- onKeyDown: X
158
- })]
273
+ children: [e.prefix && /* @__PURE__ */ u("span", {
274
+ className: n.scopePrefix,
275
+ children: e.prefix
276
+ }), e.label]
277
+ }, e.id))]
159
278
  }),
160
279
  /* @__PURE__ */ d("div", {
161
280
  className: n.list,
162
281
  children: [/* @__PURE__ */ u("div", {
163
282
  role: "listbox",
164
- id: O,
165
- "aria-label": x,
166
- children: V.map((e, r) => /* @__PURE__ */ d("div", {
283
+ id: k,
284
+ "aria-label": S,
285
+ children: H.map((e, r) => /* @__PURE__ */ d("div", {
167
286
  role: "group",
168
287
  "aria-label": e.heading,
169
288
  className: n.group,
170
- children: [e.heading && /* @__PURE__ */ u("div", {
289
+ children: [e.heading && /* @__PURE__ */ d("div", {
171
290
  className: n.heading,
172
291
  "aria-hidden": "true",
173
- children: e.heading
292
+ children: [/* @__PURE__ */ u("span", { children: e.heading }), L.value !== "" && /* @__PURE__ */ u("span", {
293
+ className: n.count,
294
+ children: l(c.commandMenu.matches, { count: e.items.length })
295
+ })]
174
296
  }), e.items.map((e) => {
297
+ let { item: r, indices: i } = e;
175
298
  $++;
176
- let r = $;
299
+ let a = $;
177
300
  return /* @__PURE__ */ d("div", {
178
301
  ref: (e) => {
179
- j.current[r] = e;
302
+ M.current[a] = e;
180
303
  },
181
- id: G(r),
304
+ id: K(a),
182
305
  role: "option",
183
- "aria-selected": r === W,
184
- "aria-disabled": e.disabled || void 0,
185
- "data-state": r === W ? "active" : void 0,
186
- "data-disabled": e.disabled || void 0,
306
+ "aria-selected": a === G,
307
+ "aria-disabled": r.disabled || void 0,
308
+ "data-state": a === G ? "active" : void 0,
309
+ "data-disabled": r.disabled || void 0,
187
310
  className: n.option,
188
311
  onMouseEnter: () => {
189
- e.disabled || (L.value = r);
312
+ r.disabled || (R.value = a);
190
313
  },
191
- onClick: () => J(e),
314
+ onClick: () => X(r, "primary"),
192
315
  children: [
193
- e.icon && /* @__PURE__ */ u("span", {
316
+ r.icon && /* @__PURE__ */ u("span", {
194
317
  className: n.icon,
195
318
  "aria-hidden": "true",
196
- children: e.icon
319
+ children: r.icon
320
+ }),
321
+ /* @__PURE__ */ d("span", {
322
+ className: n.text,
323
+ children: [/* @__PURE__ */ u("span", {
324
+ className: n.label,
325
+ children: g(r.label, i)
326
+ }), r.description && /* @__PURE__ */ u("span", {
327
+ className: n.description,
328
+ children: r.description
329
+ })]
197
330
  }),
198
- /* @__PURE__ */ u("span", {
199
- className: n.label,
200
- children: e.label
331
+ r.status && /* @__PURE__ */ d("span", {
332
+ className: n.status,
333
+ "data-tone": r.status.tone ?? "neutral",
334
+ children: [/* @__PURE__ */ u("span", {
335
+ className: n.statusDot,
336
+ "aria-hidden": "true"
337
+ }), r.status.label]
201
338
  }),
202
- e.shortcut && /* @__PURE__ */ u("span", {
339
+ r.actions && r.actions.length > 0 && /* @__PURE__ */ u("span", {
340
+ className: n.actions,
341
+ children: r.actions.map((e) => /* @__PURE__ */ d("button", {
342
+ type: "button",
343
+ className: n.action,
344
+ onClick: (t) => {
345
+ t.stopPropagation(), Y(e);
346
+ },
347
+ children: [e.label, e.shortcut && /* @__PURE__ */ u("span", {
348
+ className: n.actionKeys,
349
+ "aria-hidden": "true",
350
+ children: e.shortcut.map((e, n) => /* @__PURE__ */ u(t, {
351
+ size: "sm",
352
+ children: e
353
+ }, n))
354
+ })]
355
+ }, e.id))
356
+ }),
357
+ r.shortcut && /* @__PURE__ */ u("span", {
203
358
  className: n.shortcut,
204
359
  "aria-hidden": "true",
205
- children: e.shortcut.map((e, n) => /* @__PURE__ */ u(t, {
360
+ children: r.shortcut.map((e, n) => /* @__PURE__ */ u(t, {
206
361
  size: "sm",
207
362
  children: e
208
363
  }, n))
209
364
  })
210
365
  ]
211
- }, e.id);
366
+ }, r.id);
212
367
  })]
213
368
  }, e.heading ?? `group-${r}`))
214
- }), H.length === 0 && (S ? /* @__PURE__ */ d("div", {
369
+ }), U.length === 0 && (C ? /* @__PURE__ */ d("div", {
215
370
  role: "status",
216
371
  className: n.empty,
217
372
  children: [/* @__PURE__ */ u(e, { size: "sm" }), l(c.commandMenu.loading)]
218
373
  }) : /* @__PURE__ */ u("div", {
219
374
  role: "status",
220
375
  className: n.empty,
221
- children: E
376
+ children: ne
222
377
  }))]
223
378
  }),
224
379
  /* @__PURE__ */ d("div", {
@@ -236,7 +391,7 @@ function g({ open: m, onOpenChange: g, groups: _, placeholder: v, emptyLabel: y,
236
391
  size: "sm",
237
392
  children: "↓"
238
393
  }),
239
- " to navigate"
394
+ " navigate"
240
395
  ]
241
396
  }),
242
397
  /* @__PURE__ */ d("span", {
@@ -244,14 +399,21 @@ function g({ open: m, onOpenChange: g, groups: _, placeholder: v, emptyLabel: y,
244
399
  children: [/* @__PURE__ */ u(t, {
245
400
  size: "sm",
246
401
  children: "↵"
247
- }), " to select"]
402
+ }), " open"]
403
+ }),
404
+ T.length > 0 && /* @__PURE__ */ d("span", {
405
+ className: n.hint,
406
+ children: [/* @__PURE__ */ u(t, {
407
+ size: "sm",
408
+ children: "Tab"
409
+ }), " scope"]
248
410
  }),
249
411
  /* @__PURE__ */ d("span", {
250
412
  className: n.hint,
251
413
  children: [/* @__PURE__ */ u(t, {
252
414
  size: "sm",
253
415
  children: "esc"
254
- }), " to close"]
416
+ }), " close"]
255
417
  })
256
418
  ]
257
419
  })
@@ -260,4 +422,4 @@ function g({ open: m, onOpenChange: g, groups: _, placeholder: v, emptyLabel: y,
260
422
  });
261
423
  }
262
424
  //#endregion
263
- export { g as CommandMenu, m as fuzzyScore };
425
+ export { v as CommandMenu, p as fuzzyMatch, m as fuzzyScore };