@macrulez/vue-command-palette 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,1035 @@
1
+ import { h as W, reactive as pe, ref as L, computed as S, inject as ee, readonly as ae, onUnmounted as Ie, defineComponent as te, openBlock as u, createElementBlock as h, normalizeClass as Q, renderSlot as y, createBlock as V, resolveDynamicComponent as ge, withCtx as C, createTextVNode as ue, toDisplayString as q, createCommentVNode as M, createElementVNode as R, Fragment as T, renderList as H, createSlots as Y, mergeProps as E, watch as me, normalizeStyle as se, nextTick as ye, unref as k, Teleport as xe, createVNode as ie, Transition as Ae, withModifiers as Le, withDirectives as $e, isRef as De, vModelText as Ge, normalizeProps as re, guardReactiveProps as le, vShow as Ke } from "vue";
2
+ function ke(t) {
3
+ return t.normalize("NFD").replace(/\p{Diacritic}/gu, "").toLowerCase();
4
+ }
5
+ function ce(t, s) {
6
+ const n = ke(t), r = ke(s);
7
+ if (!n) return { score: 0, matches: [] };
8
+ if (r === n) return { score: 100, matches: [[0, s.length - 1]] };
9
+ if (r.startsWith(n)) return { score: 80, matches: [[0, n.length - 1]] };
10
+ const m = r.indexOf(n);
11
+ if (m !== -1) return { score: 60, matches: [[m, m + n.length - 1]] };
12
+ const c = [];
13
+ let a = 0, v = 0, d = -1;
14
+ for (let $ = 0; $ < r.length && a < n.length; $++)
15
+ r[$] === n[a] && (c.push($), d !== -1 && (v += $ - d - 1), d = $, a++);
16
+ if (a < n.length) return { score: -1, matches: [] };
17
+ const b = [];
18
+ let w = c[0], g = c[0];
19
+ for (let $ = 1; $ < c.length; $++)
20
+ c[$] === g + 1 || (b.push([w, g]), w = c[$]), g = c[$];
21
+ b.push([w, g]);
22
+ const I = v / (s.length || 1);
23
+ return { score: Math.max(1, 40 - I * 20), matches: b };
24
+ }
25
+ function Pe(t) {
26
+ return !(t.disabled || t.enabled && !t.enabled());
27
+ }
28
+ function Me(t, s) {
29
+ if (!t.trim()) return [];
30
+ const n = [];
31
+ for (const r of s) {
32
+ if (!Pe(r)) continue;
33
+ let m = ce(t, r.label);
34
+ for (const c of r.keywords ?? []) {
35
+ const a = ce(t, c);
36
+ a.score > m.score && (m = { score: a.score, matches: [] });
37
+ }
38
+ for (const c of r.aliases ?? []) {
39
+ const a = ce(t, c);
40
+ a.score > m.score && (m = { score: a.score, matches: [] });
41
+ }
42
+ m.score > 0 && n.push({ command: r, score: m.score, matches: m.matches });
43
+ }
44
+ return n.sort((r, m) => m.score - r.score);
45
+ }
46
+ function Oe(t, s) {
47
+ if (!s.length) return W("span", t);
48
+ const n = [];
49
+ let r = 0;
50
+ for (const [m, c] of s)
51
+ r < m && n.push(W("span", t.slice(r, m))), n.push(W("mark", { class: "vcp-match" }, t.slice(m, c + 1))), r = c + 1;
52
+ return r < t.length && n.push(W("span", t.slice(r))), W("span", n);
53
+ }
54
+ function He() {
55
+ const t = pe({
56
+ groups: /* @__PURE__ */ new Map(),
57
+ commands: /* @__PURE__ */ new Map()
58
+ });
59
+ function s(a, v) {
60
+ for (const d of a)
61
+ if (t.commands.set(d.id, d), v && t.groups.has(v)) {
62
+ const b = t.groups.get(v);
63
+ b.commands.find((w) => w.id === d.id) || b.commands.push(d);
64
+ }
65
+ return () => {
66
+ for (const d of a)
67
+ if (t.commands.delete(d.id), v && t.groups.has(v)) {
68
+ const b = t.groups.get(v), w = b.commands.findIndex((g) => g.id === d.id);
69
+ w !== -1 && b.commands.splice(w, 1);
70
+ }
71
+ };
72
+ }
73
+ function n(a) {
74
+ t.groups.set(a.id, pe(a));
75
+ for (const v of a.commands)
76
+ t.commands.set(v.id, v);
77
+ return () => {
78
+ const v = t.groups.get(a.id);
79
+ if (v)
80
+ for (const d of v.commands) t.commands.delete(d.id);
81
+ t.groups.delete(a.id);
82
+ };
83
+ }
84
+ function r() {
85
+ return Array.from(t.commands.values());
86
+ }
87
+ function m(a) {
88
+ const v = r();
89
+ if (!a.trim()) return [];
90
+ const d = Me(a, v);
91
+ for (const b of d)
92
+ for (const [w, g] of t.groups)
93
+ if (g.commands.find((I) => I.id === b.command.id)) {
94
+ b.groupId = w;
95
+ break;
96
+ }
97
+ return d;
98
+ }
99
+ function c() {
100
+ return Array.from(t.groups.values()).sort(
101
+ (a, v) => (v.priority ?? 0) - (a.priority ?? 0)
102
+ );
103
+ }
104
+ return { state: t, registerCommands: s, registerGroup: n, search: m, getAllCommands: r, getSortedGroups: c };
105
+ }
106
+ const ze = /* @__PURE__ */ new Set(["shift", "ctrl", "meta", "alt", "$mod"]);
107
+ function Ve(t) {
108
+ return ze.has(t);
109
+ }
110
+ function be(t) {
111
+ return t.length >= 2 && t.every((s) => !Ve(s));
112
+ }
113
+ function qe(t, s) {
114
+ return t === "$mod" ? s.metaKey || s.ctrlKey : t === "shift" ? s.shiftKey : t === "alt" ? s.altKey : t === "ctrl" ? s.ctrlKey : t === "meta" ? s.metaKey : s.key.toLowerCase() === t.toLowerCase();
115
+ }
116
+ function Be(t, s) {
117
+ const n = t.slice(0, -1), r = t[t.length - 1];
118
+ for (const m of n)
119
+ if (!qe(m, s)) return !1;
120
+ return !n.includes("$mod") && !n.includes("ctrl") && !n.includes("meta") && (s.ctrlKey || s.metaKey) || !n.includes("shift") && s.shiftKey || !n.includes("alt") && s.altKey ? !1 : s.key.toLowerCase() === r.toLowerCase();
121
+ }
122
+ function _e() {
123
+ const t = [];
124
+ let s = [], n = null, r = !1;
125
+ function m(d) {
126
+ for (const { keys: g, handler: I } of t)
127
+ if (!be(g) && Be(g, d)) {
128
+ d.preventDefault(), I();
129
+ return;
130
+ }
131
+ const b = t.filter((g) => be(g.keys));
132
+ if (!b.length || d.metaKey || d.ctrlKey || d.altKey) return;
133
+ s.push(d.key.toLowerCase()), n && clearTimeout(n), n = setTimeout(() => {
134
+ s = [];
135
+ }, 500);
136
+ const w = s;
137
+ for (const { keys: g, handler: I } of b) {
138
+ const $ = g.map((G) => G.toLowerCase());
139
+ if (w.length >= $.length && w.slice(-$.length).every((O, K) => O === $[K])) {
140
+ d.preventDefault(), s = [], I();
141
+ return;
142
+ }
143
+ }
144
+ }
145
+ function c(d, b) {
146
+ const w = { keys: d, handler: b };
147
+ return t.push(w), () => {
148
+ const g = t.indexOf(w);
149
+ g !== -1 && t.splice(g, 1);
150
+ };
151
+ }
152
+ function a() {
153
+ r || typeof document > "u" || (r = !0, document.addEventListener("keydown", m));
154
+ }
155
+ function v() {
156
+ typeof document > "u" || (r = !1, document.removeEventListener("keydown", m));
157
+ }
158
+ return { registerShortcut: c, start: a, stop: v };
159
+ }
160
+ const Z = Symbol("@macrulez/vue-command-palette"), It = {
161
+ install(t, s = {}) {
162
+ const {
163
+ hotkey: n = ["$mod", "k"],
164
+ persistRecent: r = !0,
165
+ maxRecent: m = 5,
166
+ maxRecentPerGroup: c = 0,
167
+ localStorageKey: a = "vcp:recent",
168
+ colorTheme: v = "system",
169
+ onOpen: d,
170
+ onClose: b,
171
+ onError: w
172
+ } = s, g = He(), I = _e(), $ = L(!1), G = L(""), O = L(0), K = L([]), x = L(null);
173
+ let D = [];
174
+ if (r && typeof localStorage < "u")
175
+ try {
176
+ D = JSON.parse(localStorage.getItem(a) ?? "[]");
177
+ } catch {
178
+ }
179
+ const P = L(D), z = S(() => g.search(G.value)), B = L(v), J = {
180
+ store: g,
181
+ keyboard: I,
182
+ isOpen: $,
183
+ query: G,
184
+ activeIndex: O,
185
+ history: K,
186
+ recentIds: P,
187
+ loadingCommandId: x,
188
+ results: z,
189
+ colorTheme: B,
190
+ persistRecent: r,
191
+ maxRecent: m,
192
+ maxRecentPerGroup: c ?? 0,
193
+ localStorageKey: a,
194
+ onOpen: d,
195
+ onClose: b,
196
+ onError: w
197
+ };
198
+ t.provide(Z, J), I.registerShortcut(n, () => {
199
+ $.value = !$.value, $.value ? (G.value = "", O.value = 0, d?.()) : b?.();
200
+ }), I.start();
201
+ const N = t.unmount.bind(t);
202
+ t.unmount = () => {
203
+ I.stop(), N();
204
+ };
205
+ }
206
+ };
207
+ function Ne(t, s) {
208
+ if (!(typeof localStorage > "u"))
209
+ try {
210
+ localStorage.setItem(s, JSON.stringify(t));
211
+ } catch {
212
+ }
213
+ }
214
+ function Ue() {
215
+ const t = ee(Z);
216
+ if (!t) throw new Error("[@macrulez/vue-command-palette] Plugin not installed. Use app.use(VCommandPalettePlugin).");
217
+ const {
218
+ store: s,
219
+ isOpen: n,
220
+ query: r,
221
+ activeIndex: m,
222
+ history: c,
223
+ recentIds: a,
224
+ loadingCommandId: v,
225
+ results: d,
226
+ colorTheme: b,
227
+ persistRecent: w,
228
+ maxRecent: g,
229
+ localStorageKey: I,
230
+ onOpen: $,
231
+ onClose: G,
232
+ onError: O
233
+ } = t;
234
+ function K(p) {
235
+ p && n.value ? (c.value.push({ paletteId: p, query: r.value, activeIndex: m.value }), r.value = "", m.value = 0) : (n.value = !0, r.value = "", m.value = 0, $?.());
236
+ }
237
+ function x() {
238
+ n.value = !1, r.value = "", m.value = 0, c.value = [], G?.();
239
+ }
240
+ function D() {
241
+ n.value ? x() : K();
242
+ }
243
+ function P() {
244
+ if (!c.value.length) {
245
+ x();
246
+ return;
247
+ }
248
+ const p = c.value.pop();
249
+ r.value = p.query, m.value = p.activeIndex;
250
+ }
251
+ function z(p) {
252
+ if (!w) return;
253
+ const A = a.value.filter((F) => F !== p);
254
+ A.unshift(p), a.value = A.slice(0, g), Ne(a.value, I);
255
+ }
256
+ async function B(p) {
257
+ if (!(p.disabled || p.enabled && !p.enabled())) {
258
+ if (p.subCommands?.length) {
259
+ K(p.id);
260
+ return;
261
+ }
262
+ z(p.id), x(), v.value = p.id;
263
+ try {
264
+ await p.perform();
265
+ } catch (A) {
266
+ O ? O(A, p) : console.error("[@macrulez/vue-command-palette] Command error:", A);
267
+ } finally {
268
+ v.value = null;
269
+ }
270
+ }
271
+ }
272
+ async function J() {
273
+ const p = d.value[m.value];
274
+ p && await B(p.command);
275
+ }
276
+ function N() {
277
+ const p = s.getAllCommands();
278
+ return a.value.map((A) => p.find((F) => F.id === A)).filter((A) => !!A);
279
+ }
280
+ function j(p) {
281
+ return s.registerCommands(p);
282
+ }
283
+ function oe(p) {
284
+ return s.registerGroup(p);
285
+ }
286
+ return {
287
+ isOpen: ae(n),
288
+ query: r,
289
+ results: d,
290
+ activeIndex: m,
291
+ history: ae(c),
292
+ loadingCommandId: ae(v),
293
+ colorTheme: b,
294
+ open: K,
295
+ close: x,
296
+ toggle: D,
297
+ goBack: P,
298
+ executeActive: J,
299
+ executeCommand: B,
300
+ getRecentCommands: N,
301
+ registerCommands: j,
302
+ registerGroup: oe,
303
+ addRecent: z
304
+ };
305
+ }
306
+ function Et(t) {
307
+ const s = ee(Z);
308
+ if (!s) throw new Error("[@macrulez/vue-command-palette] Plugin not installed.");
309
+ const n = s.store.registerCommands(t);
310
+ Ie(n);
311
+ }
312
+ function St(t) {
313
+ const s = ee(Z);
314
+ if (!s) throw new Error("[@macrulez/vue-command-palette] Plugin not installed.");
315
+ const n = s.store.registerGroup(t);
316
+ Ie(n);
317
+ }
318
+ const Ye = ["id", "aria-selected", "aria-disabled"], Fe = {
319
+ key: 0,
320
+ class: "vcp-item__icon"
321
+ }, Je = { class: "vcp-item__body" }, je = { class: "vcp-item__label" }, We = {
322
+ key: 0,
323
+ class: "vcp-item__description"
324
+ }, Qe = {
325
+ key: 0,
326
+ class: "vcp-item__spinner",
327
+ "aria-label": "Loading"
328
+ }, Xe = {
329
+ key: 1,
330
+ class: "vcp-item__shortcut"
331
+ }, X = /* @__PURE__ */ te({
332
+ __name: "CommandItem",
333
+ props: {
334
+ command: {},
335
+ active: { type: Boolean },
336
+ matches: {},
337
+ itemId: {},
338
+ loadingCommandId: {}
339
+ },
340
+ emits: ["execute", "activate"],
341
+ setup(t) {
342
+ const s = t, n = S(
343
+ () => s.command.disabled || s.command.enabled != null && !s.command.enabled()
344
+ ), r = S(() => s.loadingCommandId === s.command.id), m = S(() => Oe(s.command.label, s.matches));
345
+ function c(a) {
346
+ return a === "$mod" ? typeof navigator < "u" && navigator.platform.includes("Mac") ? "⌘" : "Ctrl" : a === "shift" ? "⇧" : a === "alt" ? typeof navigator < "u" && navigator.platform.includes("Mac") ? "⌥" : "Alt" : a.toUpperCase();
347
+ }
348
+ return (a, v) => (u(), h("div", {
349
+ id: t.itemId,
350
+ class: Q(["vcp-item", {
351
+ "vcp-item--active": t.active,
352
+ "vcp-item--disabled": n.value,
353
+ "vcp-item--loading": r.value
354
+ }]),
355
+ role: "option",
356
+ "aria-selected": t.active,
357
+ "aria-disabled": n.value,
358
+ onClick: v[0] || (v[0] = (d) => !n.value && !r.value && a.$emit("execute")),
359
+ onMouseenter: v[1] || (v[1] = (d) => !n.value && a.$emit("activate"))
360
+ }, [
361
+ y(a.$slots, "default", {
362
+ command: t.command,
363
+ active: t.active,
364
+ matches: t.matches
365
+ }, () => [
366
+ y(a.$slots, "item-icon", { command: t.command }, () => [
367
+ t.command.icon ? (u(), h("span", Fe, [
368
+ (u(), V(ge(typeof t.command.icon == "string" ? "span" : t.command.icon), null, {
369
+ default: C(() => [
370
+ ue(q(typeof t.command.icon == "string" ? t.command.icon : ""), 1)
371
+ ]),
372
+ _: 1
373
+ }))
374
+ ])) : M("", !0)
375
+ ]),
376
+ R("span", Je, [
377
+ R("span", je, [
378
+ (u(), V(ge(m.value)))
379
+ ]),
380
+ t.command.description ? (u(), h("span", We, q(t.command.description), 1)) : M("", !0)
381
+ ]),
382
+ y(a.$slots, "item-shortcut", { command: t.command }, () => [
383
+ r.value ? (u(), h("span", Qe)) : t.command.shortcut?.length ? (u(), h("span", Xe, [
384
+ (u(!0), h(T, null, H(t.command.shortcut, (d) => (u(), h("kbd", {
385
+ key: d,
386
+ class: "vcp-kbd"
387
+ }, q(c(d)), 1))), 128))
388
+ ])) : M("", !0)
389
+ ])
390
+ ])
391
+ ], 42, Ye));
392
+ }
393
+ }), Ze = {
394
+ key: 0,
395
+ class: "vcp-group"
396
+ }, et = {
397
+ class: "vcp-group__header",
398
+ "aria-hidden": "true"
399
+ }, Ce = /* @__PURE__ */ te({
400
+ __name: "CommandGroup",
401
+ props: {
402
+ group: {},
403
+ items: {},
404
+ activeIndex: {},
405
+ globalOffset: {},
406
+ loadingCommandId: {}
407
+ },
408
+ emits: ["execute", "activate"],
409
+ setup(t) {
410
+ return (s, n) => t.items.length ? (u(), h("div", Ze, [
411
+ y(s.$slots, "group-header", { group: t.group }, () => [
412
+ R("div", et, q(t.group.label), 1)
413
+ ]),
414
+ (u(!0), h(T, null, H(t.items, (r, m) => (u(), V(X, {
415
+ key: r.command.id,
416
+ command: r.command,
417
+ active: t.globalOffset + m === t.activeIndex,
418
+ matches: r.matches,
419
+ "item-id": `vcp-item-${r.command.id}`,
420
+ "loading-command-id": t.loadingCommandId,
421
+ onExecute: (c) => s.$emit("execute", r.command),
422
+ onActivate: (c) => s.$emit("activate", t.globalOffset + m)
423
+ }, Y({ _: 2 }, [
424
+ s.$slots["item-icon"] ? {
425
+ name: "item-icon",
426
+ fn: C((c) => [
427
+ y(s.$slots, "item-icon", E({ ref_for: !0 }, c))
428
+ ]),
429
+ key: "0"
430
+ } : void 0,
431
+ s.$slots["item-shortcut"] ? {
432
+ name: "item-shortcut",
433
+ fn: C((c) => [
434
+ y(s.$slots, "item-shortcut", E({ ref_for: !0 }, c))
435
+ ]),
436
+ key: "1"
437
+ } : void 0,
438
+ s.$slots.item ? {
439
+ name: "default",
440
+ fn: C((c) => [
441
+ y(s.$slots, "item", E({ ref_for: !0 }, c))
442
+ ]),
443
+ key: "2"
444
+ } : void 0
445
+ ]), 1032, ["command", "active", "matches", "item-id", "loading-command-id", "onExecute", "onActivate"]))), 128))
446
+ ])) : M("", !0);
447
+ }
448
+ }), tt = /* @__PURE__ */ te({
449
+ __name: "VirtualList",
450
+ props: {
451
+ items: {},
452
+ itemHeight: {},
453
+ containerHeight: {},
454
+ overscan: { default: 3 }
455
+ },
456
+ setup(t, { expose: s }) {
457
+ const n = t, r = L(), m = L(0), c = S(() => n.items.length * n.itemHeight), a = S(
458
+ () => Math.max(0, Math.floor(m.value / n.itemHeight) - n.overscan)
459
+ ), v = S(() => {
460
+ const g = Math.ceil(n.containerHeight / n.itemHeight);
461
+ return Math.min(n.items.length - 1, a.value + g + n.overscan * 2);
462
+ }), d = S(() => a.value * n.itemHeight), b = S(
463
+ () => n.items.slice(a.value, v.value + 1).map((g, I) => ({
464
+ data: g,
465
+ index: a.value + I
466
+ }))
467
+ );
468
+ function w(g) {
469
+ m.value = g.target.scrollTop;
470
+ }
471
+ return me(() => n.items, () => {
472
+ m.value = 0, r.value && (r.value.scrollTop = 0);
473
+ }), s({ containerEl: r }), (g, I) => (u(), h("div", {
474
+ ref_key: "containerEl",
475
+ ref: r,
476
+ class: "vcp-virtual",
477
+ style: se({ height: t.containerHeight + "px", overflowY: "auto" }),
478
+ onScrollPassive: w
479
+ }, [
480
+ R("div", {
481
+ style: se({ height: c.value + "px", position: "relative" })
482
+ }, [
483
+ R("div", {
484
+ style: se({ transform: `translateY(${d.value}px)` })
485
+ }, [
486
+ (u(!0), h(T, null, H(b.value, ($) => y(g.$slots, "default", {
487
+ key: $.index,
488
+ item: $.data,
489
+ index: $.index
490
+ })), 128))
491
+ ], 4)
492
+ ], 4)
493
+ ], 36));
494
+ }
495
+ }), ot = {
496
+ key: 0,
497
+ class: "vcp-breadcrumb",
498
+ "aria-live": "polite"
499
+ }, nt = {
500
+ key: 0,
501
+ class: "vcp-breadcrumb__sep",
502
+ "aria-hidden": "true"
503
+ }, at = {
504
+ key: 1,
505
+ class: "vcp-confirm"
506
+ }, st = { class: "vcp-confirm__text" }, it = { class: "vcp-confirm__actions" }, rt = { class: "vcp-input-wrap" }, lt = ["placeholder", "aria-activedescendant"], ct = {
507
+ class: "vcp-theme-switcher",
508
+ "aria-label": "Color theme"
509
+ }, ut = ["title", "onClick"], mt = ["aria-label"], dt = {
510
+ key: 0,
511
+ class: "vcp-state vcp-state--loading"
512
+ }, ft = {
513
+ key: 0,
514
+ class: "vcp-section",
515
+ "aria-hidden": "true"
516
+ }, vt = {
517
+ key: 0,
518
+ class: "vcp-section",
519
+ "aria-hidden": "true"
520
+ }, ht = {
521
+ key: 0,
522
+ class: "vcp-group__header",
523
+ "aria-hidden": "true"
524
+ }, pt = {
525
+ key: 1,
526
+ class: "vcp-section",
527
+ "aria-hidden": "true"
528
+ }, gt = {
529
+ key: 0,
530
+ class: "vcp-section",
531
+ "aria-hidden": "true"
532
+ }, yt = {
533
+ key: 4,
534
+ class: "vcp-state vcp-state--empty"
535
+ }, $t = 50, kt = 40, bt = 360, Ct = "vcp-input", we = "vcp-listbox", Tt = /* @__PURE__ */ te({
536
+ __name: "CommandPalette",
537
+ props: {
538
+ placeholder: { default: "Search commands…" },
539
+ maxResults: { default: 10 },
540
+ emptyText: { default: "No commands found." },
541
+ loadingText: { default: "Loading…" },
542
+ teleportTo: { default: "body" },
543
+ theme: { default: "default" },
544
+ animationDuration: { default: 150 }
545
+ },
546
+ setup(t) {
547
+ const s = t, n = ee(Z), r = Ue(), { isOpen: m, query: c, activeIndex: a, history: v, loadingCommandId: d, close: b, toggle: w, open: g, executeCommand: I, getRecentCommands: $ } = r, G = L(), O = L(), K = L(!1), x = L(null), D = S(() => {
548
+ const e = $();
549
+ if (!n.maxRecentPerGroup) return e;
550
+ const l = {};
551
+ return e.filter((o) => {
552
+ const i = o.group ?? "__none__";
553
+ return l[i] = (l[i] ?? 0) + 1, l[i] <= n.maxRecentPerGroup;
554
+ });
555
+ }), P = S(() => {
556
+ if (!v.value.length) return null;
557
+ const e = v.value[v.value.length - 1].paletteId, l = n.store.getAllCommands().find((o) => o.id === e);
558
+ return l?.subCommands?.length ? l.subCommands.filter((o) => !o.disabled && (o.enabled == null || o.enabled())) : null;
559
+ }), z = S(
560
+ () => n.store.getSortedGroups().map((e) => ({
561
+ group: e,
562
+ items: e.commands.filter((l) => !l.disabled && (l.enabled == null || l.enabled())).map((l) => ({ command: l, score: 0, matches: [], groupId: e.id }))
563
+ })).filter((e) => e.items.length > 0)
564
+ ), B = S(() => z.value.flatMap((e) => e.items));
565
+ function J(e) {
566
+ return z.value.slice(0, e).reduce((l, o) => l + o.items.length, 0);
567
+ }
568
+ const N = L([]);
569
+ let j = null;
570
+ me(c, async (e) => {
571
+ j && clearTimeout(j);
572
+ const l = n.store.getSortedGroups().filter((o) => o.onSearch);
573
+ if (!l.length || !e.trim()) {
574
+ N.value = [];
575
+ return;
576
+ }
577
+ j = setTimeout(async () => {
578
+ K.value = !0;
579
+ try {
580
+ const o = await Promise.all(
581
+ l.map((i) => i.onSearch(e).then(
582
+ (f) => f.map((U) => ({ command: U, score: 50, matches: [], groupId: i.id }))
583
+ ))
584
+ );
585
+ N.value = o.flat();
586
+ } finally {
587
+ K.value = !1;
588
+ }
589
+ }, 200);
590
+ });
591
+ const oe = S(() => n.store.search(c.value)), p = S(() => {
592
+ const e = P.value;
593
+ if (e !== null && c.value.trim()) {
594
+ const o = c.value.toLowerCase();
595
+ return e.filter(
596
+ (i) => i.label.toLowerCase().includes(o) || i.description?.toLowerCase().includes(o) || i.keywords?.some((f) => f.toLowerCase().includes(o))
597
+ ).map((i) => ({ command: i, score: 50, matches: [], groupId: void 0 }));
598
+ }
599
+ const l = [...oe.value];
600
+ for (const o of N.value)
601
+ l.find((i) => i.command.id === o.command.id) || l.push(o);
602
+ return l.sort((o, i) => i.score - o.score).slice(0, s.maxResults);
603
+ }), A = S(() => {
604
+ const e = n.store.getSortedGroups(), l = [];
605
+ let o = 0;
606
+ for (let i = 0; i < e.length; i++) {
607
+ const f = e[i], U = p.value.filter((ne) => ne.groupId === f.id);
608
+ U.length && (l.push({ group: f, items: U, offset: o, section: i > 0 && l.length > 0 }), o += U.length);
609
+ }
610
+ return l;
611
+ }), F = S(() => A.value.reduce((e, l) => e + l.items.length, 0)), de = S(() => p.value.filter((e) => !e.groupId)), Ee = S(() => {
612
+ const e = [];
613
+ let l = 0;
614
+ for (let o = 0; o < A.value.length; o++) {
615
+ const { group: i, items: f, section: U } = A.value[o];
616
+ U && e.push({ type: "section" }), e.push({ type: "group-header", label: i.label });
617
+ for (const ne of f) e.push({ type: "command", result: ne, index: l++ });
618
+ }
619
+ for (const o of de.value) e.push({ type: "command", result: o, index: l++ });
620
+ return e;
621
+ }), Se = S(() => {
622
+ const e = p.value[a.value];
623
+ return e ? `vcp-item-${e.command.id}` : void 0;
624
+ });
625
+ function Te(e) {
626
+ return n.store.getAllCommands().find((l) => l.id === e)?.label ?? e;
627
+ }
628
+ function fe() {
629
+ a.value = 0;
630
+ }
631
+ async function _(e) {
632
+ if (e.confirm) {
633
+ x.value = e;
634
+ return;
635
+ }
636
+ await I(e);
637
+ }
638
+ async function ve() {
639
+ if (!x.value) return;
640
+ const e = x.value;
641
+ x.value = null, await I(e);
642
+ }
643
+ function he() {
644
+ ye(() => {
645
+ O.value?.querySelector('[aria-selected="true"]')?.scrollIntoView({ block: "nearest" });
646
+ });
647
+ }
648
+ function Re(e) {
649
+ if (x.value) {
650
+ e.key === "Escape" && (e.preventDefault(), x.value = null), e.key === "Enter" && (e.preventDefault(), ve());
651
+ return;
652
+ }
653
+ const l = p.value.length || (c.value.trim() ? 0 : P.value ? P.value.length : D.value.length + B.value.length);
654
+ if (e.key === "ArrowDown")
655
+ e.preventDefault(), l && (a.value = (a.value + 1) % l), he();
656
+ else if (e.key === "ArrowUp")
657
+ e.preventDefault(), l && (a.value = (a.value - 1 + l) % l), he();
658
+ else if (e.key === "Enter")
659
+ if (e.preventDefault(), c.value.trim()) {
660
+ const o = p.value[a.value];
661
+ o?.command && _(o.command);
662
+ } else {
663
+ const o = a.value;
664
+ let i;
665
+ P.value ? i = P.value[o] : i = o < D.value.length ? D.value[o] : B.value[o - D.value.length]?.command, i && _(i);
666
+ }
667
+ else e.key === "Escape" ? (e.preventDefault(), v.value.length ? r.goBack() : b()) : e.key === "Backspace" && !c.value ? (e.preventDefault(), r.goBack()) : e.key === "Tab" && (e.preventDefault(), G.value?.focus());
668
+ }
669
+ return me(m, async (e) => {
670
+ typeof document > "u" || (e ? (a.value = 0, document.body.style.overflow = "hidden", await ye(), G.value?.focus()) : (document.body.style.overflow = "", x.value = null));
671
+ }), (e, l) => (u(), h(T, null, [
672
+ y(e.$slots, "trigger", {
673
+ open: k(g),
674
+ toggle: k(w)
675
+ }),
676
+ (u(), V(xe, { to: t.teleportTo }, [
677
+ ie(Ae, { name: "vcp-fade" }, {
678
+ default: C(() => [
679
+ k(m) ? (u(), h("div", {
680
+ key: 0,
681
+ class: Q(["vcp-overlay", k(n).colorTheme.value !== "system" ? `vcp-theme-${k(n).colorTheme.value}` : ""]),
682
+ role: "presentation",
683
+ onClick: l[6] || (l[6] = Le(
684
+ //@ts-ignore
685
+ (...o) => k(b) && k(b)(...o),
686
+ ["self"]
687
+ ))
688
+ }, [
689
+ R("div", {
690
+ class: Q(["vcp-dialog", `vcp-dialog--${t.theme}`]),
691
+ role: "dialog",
692
+ "aria-modal": "true",
693
+ "aria-label": "Command palette",
694
+ onKeydown: Re
695
+ }, [
696
+ k(v).length ? (u(), h("div", ot, [
697
+ (u(!0), h(T, null, H(k(v), (o, i) => (u(), h("span", {
698
+ key: o.paletteId,
699
+ class: "vcp-breadcrumb__item"
700
+ }, [
701
+ i > 0 ? (u(), h("span", nt, "›")) : M("", !0),
702
+ ue(" " + q(Te(o.paletteId)), 1)
703
+ ]))), 128)),
704
+ l[7] || (l[7] = R("span", {
705
+ class: "vcp-breadcrumb__sep",
706
+ "aria-hidden": "true"
707
+ }, "›", -1))
708
+ ])) : M("", !0),
709
+ x.value ? (u(), h("div", at, [
710
+ R("p", st, q(x.value.confirm), 1),
711
+ R("div", it, [
712
+ R("button", {
713
+ class: "vcp-confirm__btn vcp-confirm__btn--yes",
714
+ onClick: ve
715
+ }, " Yes, proceed "),
716
+ R("button", {
717
+ class: "vcp-confirm__btn vcp-confirm__btn--no",
718
+ onClick: l[0] || (l[0] = (o) => x.value = null)
719
+ }, " Cancel ")
720
+ ])
721
+ ])) : (u(), h(T, { key: 2 }, [
722
+ y(e.$slots, "header"),
723
+ R("div", rt, [
724
+ y(e.$slots, "input", {
725
+ query: k(c),
726
+ onInput: fe
727
+ }, () => [
728
+ $e(R("input", {
729
+ id: Ct,
730
+ ref_key: "inputEl",
731
+ ref: G,
732
+ "onUpdate:modelValue": l[1] || (l[1] = (o) => De(c) ? c.value = o : null),
733
+ class: "vcp-input",
734
+ type: "text",
735
+ autocomplete: "off",
736
+ spellcheck: "false",
737
+ placeholder: t.placeholder,
738
+ role: "combobox",
739
+ "aria-expanded": "true",
740
+ "aria-controls": we,
741
+ "aria-activedescendant": Se.value,
742
+ onInput: fe
743
+ }, null, 40, lt), [
744
+ [Ge, k(c)]
745
+ ])
746
+ ]),
747
+ R("div", ct, [
748
+ (u(), h(T, null, H(["light", "system", "dark"], (o) => R("button", {
749
+ key: o,
750
+ class: Q(["vcp-theme-btn", { "vcp-theme-btn--active": k(n).colorTheme.value === o }]),
751
+ title: o === "light" ? "Light theme" : o === "dark" ? "Dark theme" : "System theme",
752
+ type: "button",
753
+ onClick: (i) => k(n).colorTheme.value = o
754
+ }, [
755
+ R("span", {
756
+ class: Q(["vcp-theme-icon", `vcp-theme-icon--${o}`]),
757
+ "aria-hidden": "true"
758
+ }, null, 2)
759
+ ], 10, ut)), 64))
760
+ ])
761
+ ]),
762
+ $e(R("div", {
763
+ id: we,
764
+ ref_key: "listEl",
765
+ ref: O,
766
+ class: "vcp-list",
767
+ role: "listbox",
768
+ "aria-label": t.placeholder
769
+ }, [
770
+ K.value ? (u(), h("div", dt, q(t.loadingText), 1)) : k(c).trim() ? p.value.length > $t ? (u(), V(tt, {
771
+ key: 2,
772
+ items: Ee.value,
773
+ "item-height": kt,
774
+ "container-height": bt
775
+ }, {
776
+ default: C(({ item: o }) => [
777
+ o.type === "group-header" ? (u(), h("div", ht, q(o.label), 1)) : o.type === "section" ? (u(), h("div", pt)) : (u(), V(X, {
778
+ key: 2,
779
+ command: o.result.command,
780
+ active: o.index === k(a),
781
+ matches: o.result.matches,
782
+ "item-id": `vcp-item-${o.result.command.id}`,
783
+ "loading-command-id": k(d),
784
+ onExecute: (i) => _(o.result.command),
785
+ onActivate: (i) => a.value = o.index
786
+ }, Y({ _: 2 }, [
787
+ e.$slots["item-icon"] ? {
788
+ name: "item-icon",
789
+ fn: C((i) => [
790
+ y(e.$slots, "item-icon", re(le(i)))
791
+ ]),
792
+ key: "0"
793
+ } : void 0,
794
+ e.$slots["item-shortcut"] ? {
795
+ name: "item-shortcut",
796
+ fn: C((i) => [
797
+ y(e.$slots, "item-shortcut", re(le(i)))
798
+ ]),
799
+ key: "1"
800
+ } : void 0,
801
+ e.$slots.item ? {
802
+ name: "default",
803
+ fn: C((i) => [
804
+ y(e.$slots, "item", re(le(i)))
805
+ ]),
806
+ key: "2"
807
+ } : void 0
808
+ ]), 1032, ["command", "active", "matches", "item-id", "loading-command-id", "onExecute", "onActivate"]))
809
+ ]),
810
+ _: 3
811
+ }, 8, ["items"])) : p.value.length ? (u(), h(T, { key: 3 }, [
812
+ (u(!0), h(T, null, H(A.value, (o) => (u(), h(T, {
813
+ key: o.group.id
814
+ }, [
815
+ o.section ? (u(), h("div", gt)) : M("", !0),
816
+ ie(Ce, {
817
+ group: o.group,
818
+ items: o.items,
819
+ "active-index": k(a),
820
+ "global-offset": o.offset,
821
+ "loading-command-id": k(d),
822
+ onExecute: l[4] || (l[4] = (i) => _(i)),
823
+ onActivate: l[5] || (l[5] = (i) => a.value = i)
824
+ }, Y({ _: 2 }, [
825
+ e.$slots["group-header"] ? {
826
+ name: "group-header",
827
+ fn: C((i) => [
828
+ y(e.$slots, "group-header", E({ ref_for: !0 }, i))
829
+ ]),
830
+ key: "0"
831
+ } : void 0,
832
+ e.$slots["item-icon"] ? {
833
+ name: "item-icon",
834
+ fn: C((i) => [
835
+ y(e.$slots, "item-icon", E({ ref_for: !0 }, i))
836
+ ]),
837
+ key: "1"
838
+ } : void 0,
839
+ e.$slots["item-shortcut"] ? {
840
+ name: "item-shortcut",
841
+ fn: C((i) => [
842
+ y(e.$slots, "item-shortcut", E({ ref_for: !0 }, i))
843
+ ]),
844
+ key: "2"
845
+ } : void 0,
846
+ e.$slots.item ? {
847
+ name: "item",
848
+ fn: C((i) => [
849
+ y(e.$slots, "item", E({ ref_for: !0 }, i))
850
+ ]),
851
+ key: "3"
852
+ } : void 0
853
+ ]), 1032, ["group", "items", "active-index", "global-offset", "loading-command-id"])
854
+ ], 64))), 128)),
855
+ (u(!0), h(T, null, H(de.value, (o, i) => (u(), V(X, {
856
+ key: o.command.id,
857
+ command: o.command,
858
+ active: F.value + i === k(a),
859
+ matches: o.matches,
860
+ "item-id": `vcp-item-${o.command.id}`,
861
+ "loading-command-id": k(d),
862
+ onExecute: (f) => _(o.command),
863
+ onActivate: (f) => a.value = F.value + i
864
+ }, Y({ _: 2 }, [
865
+ e.$slots["item-icon"] ? {
866
+ name: "item-icon",
867
+ fn: C((f) => [
868
+ y(e.$slots, "item-icon", E({ ref_for: !0 }, f))
869
+ ]),
870
+ key: "0"
871
+ } : void 0,
872
+ e.$slots["item-shortcut"] ? {
873
+ name: "item-shortcut",
874
+ fn: C((f) => [
875
+ y(e.$slots, "item-shortcut", E({ ref_for: !0 }, f))
876
+ ]),
877
+ key: "1"
878
+ } : void 0,
879
+ e.$slots.item ? {
880
+ name: "default",
881
+ fn: C((f) => [
882
+ y(e.$slots, "item", E({ ref_for: !0 }, f))
883
+ ]),
884
+ key: "2"
885
+ } : void 0
886
+ ]), 1032, ["command", "active", "matches", "item-id", "loading-command-id", "onExecute", "onActivate"]))), 128))
887
+ ], 64)) : k(c).trim() ? (u(), h("div", yt, [
888
+ y(e.$slots, "empty", { query: k(c) }, () => [
889
+ ue(q(t.emptyText), 1)
890
+ ])
891
+ ])) : M("", !0) : (u(), h(T, { key: 1 }, [
892
+ P.value ? (u(!0), h(T, { key: 0 }, H(P.value, (o, i) => (u(), V(X, {
893
+ key: o.id,
894
+ command: o,
895
+ active: i === k(a),
896
+ matches: [],
897
+ "item-id": `vcp-item-sub-${o.id}`,
898
+ "loading-command-id": k(d),
899
+ onExecute: (f) => _(o),
900
+ onActivate: (f) => a.value = i
901
+ }, Y({ _: 2 }, [
902
+ e.$slots["item-icon"] ? {
903
+ name: "item-icon",
904
+ fn: C((f) => [
905
+ y(e.$slots, "item-icon", E({ ref_for: !0 }, f))
906
+ ]),
907
+ key: "0"
908
+ } : void 0,
909
+ e.$slots["item-shortcut"] ? {
910
+ name: "item-shortcut",
911
+ fn: C((f) => [
912
+ y(e.$slots, "item-shortcut", E({ ref_for: !0 }, f))
913
+ ]),
914
+ key: "1"
915
+ } : void 0,
916
+ e.$slots.item ? {
917
+ name: "default",
918
+ fn: C((f) => [
919
+ y(e.$slots, "item", E({ ref_for: !0 }, f))
920
+ ]),
921
+ key: "2"
922
+ } : void 0
923
+ ]), 1032, ["command", "active", "item-id", "loading-command-id", "onExecute", "onActivate"]))), 128)) : (u(), h(T, { key: 1 }, [
924
+ D.value.length ? (u(), h(T, { key: 0 }, [
925
+ l[8] || (l[8] = R("div", {
926
+ class: "vcp-group__header",
927
+ "aria-hidden": "true"
928
+ }, "Recent", -1)),
929
+ (u(!0), h(T, null, H(D.value, (o, i) => (u(), V(X, {
930
+ key: o.id,
931
+ command: o,
932
+ active: i === k(a),
933
+ matches: [],
934
+ "item-id": `vcp-item-recent-${o.id}`,
935
+ "loading-command-id": k(d),
936
+ onExecute: (f) => _(o),
937
+ onActivate: (f) => a.value = i
938
+ }, Y({ _: 2 }, [
939
+ e.$slots["item-icon"] ? {
940
+ name: "item-icon",
941
+ fn: C((f) => [
942
+ y(e.$slots, "item-icon", E({ ref_for: !0 }, f))
943
+ ]),
944
+ key: "0"
945
+ } : void 0,
946
+ e.$slots["item-shortcut"] ? {
947
+ name: "item-shortcut",
948
+ fn: C((f) => [
949
+ y(e.$slots, "item-shortcut", E({ ref_for: !0 }, f))
950
+ ]),
951
+ key: "1"
952
+ } : void 0,
953
+ e.$slots.item ? {
954
+ name: "default",
955
+ fn: C((f) => [
956
+ y(e.$slots, "item", E({ ref_for: !0 }, f))
957
+ ]),
958
+ key: "2"
959
+ } : void 0
960
+ ]), 1032, ["command", "active", "item-id", "loading-command-id", "onExecute", "onActivate"]))), 128)),
961
+ z.value.length ? (u(), h("div", ft)) : M("", !0)
962
+ ], 64)) : M("", !0),
963
+ (u(!0), h(T, null, H(z.value, (o, i) => (u(), h(T, {
964
+ key: o.group.id
965
+ }, [
966
+ i > 0 ? (u(), h("div", vt)) : M("", !0),
967
+ ie(Ce, {
968
+ group: o.group,
969
+ items: o.items,
970
+ "active-index": k(a),
971
+ "global-offset": D.value.length + J(i),
972
+ "loading-command-id": k(d),
973
+ onExecute: l[2] || (l[2] = (f) => _(f)),
974
+ onActivate: l[3] || (l[3] = (f) => a.value = f)
975
+ }, Y({ _: 2 }, [
976
+ e.$slots["group-header"] ? {
977
+ name: "group-header",
978
+ fn: C((f) => [
979
+ y(e.$slots, "group-header", E({ ref_for: !0 }, f))
980
+ ]),
981
+ key: "0"
982
+ } : void 0,
983
+ e.$slots["item-icon"] ? {
984
+ name: "item-icon",
985
+ fn: C((f) => [
986
+ y(e.$slots, "item-icon", E({ ref_for: !0 }, f))
987
+ ]),
988
+ key: "1"
989
+ } : void 0,
990
+ e.$slots["item-shortcut"] ? {
991
+ name: "item-shortcut",
992
+ fn: C((f) => [
993
+ y(e.$slots, "item-shortcut", E({ ref_for: !0 }, f))
994
+ ]),
995
+ key: "2"
996
+ } : void 0,
997
+ e.$slots.item ? {
998
+ name: "item",
999
+ fn: C((f) => [
1000
+ y(e.$slots, "item", E({ ref_for: !0 }, f))
1001
+ ]),
1002
+ key: "3"
1003
+ } : void 0
1004
+ ]), 1032, ["group", "items", "active-index", "global-offset", "loading-command-id"])
1005
+ ], 64))), 128))
1006
+ ], 64))
1007
+ ], 64))
1008
+ ], 8, mt), [
1009
+ [Ke, K.value || P.value != null || D.value.length || k(c).trim() || B.value.length]
1010
+ ]),
1011
+ y(e.$slots, "footer")
1012
+ ], 64))
1013
+ ], 34)
1014
+ ], 2)) : M("", !0)
1015
+ ]),
1016
+ _: 3
1017
+ })
1018
+ ], 8, ["to"]))
1019
+ ], 64));
1020
+ }
1021
+ });
1022
+ export {
1023
+ Ce as CommandGroup,
1024
+ X as CommandItem,
1025
+ Tt as CommandPalette,
1026
+ It as VCommandPalettePlugin,
1027
+ tt as VirtualList,
1028
+ He as createCommandStore,
1029
+ _e as createKeyboardManager,
1030
+ Me as fuzzySearch,
1031
+ Oe as highlightMatches,
1032
+ Ue as useCommandPalette,
1033
+ Et as useRegisterCommands,
1034
+ St as useRegisterGroup
1035
+ };