@leavepulse/ui 0.46.0 → 0.48.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.
Files changed (75) hide show
  1. package/dist/assets/HighlightText-BwC5xbqn.css +6 -0
  2. package/dist/assets/{LpCommandPalette-5miKYsb-.css → LpCommandPalette-DmQUsJqA.css} +21 -21
  3. package/dist/assets/LpKeys-BxRhfQda.css +36 -0
  4. package/dist/assets/LpPaletteFacts-B9FdVmIO.css +93 -0
  5. package/dist/assets/LpPaletteHeader-BVOu1UX5.css +70 -0
  6. package/dist/assets/LpPalettePreview-CJmAKgYW.css +43 -0
  7. package/dist/assets/LpPaletteStats-ClE-37MK.css +33 -0
  8. package/dist/assets/LpPaletteSwatches-CA0B8y2E.css +21 -0
  9. package/dist/assets/{LpShortcutsDialog-CqYX3yy6.css → LpShortcutsDialog-BUp_BX4s.css} +7 -28
  10. package/dist/assets/{LpTable-BoeA_TgK.css → LpTable-xWwI4KPZ.css} +17 -17
  11. package/dist/chunks/HighlightText-BvnYZkhi.js +27 -0
  12. package/dist/chunks/{LpAvatar-DeSb6H0c.js → LpAvatar-Cb1jtOVv.js} +21 -3
  13. package/dist/chunks/{LpLightbox-DSDahF23.js → LpLightbox-EVXzAq62.js} +3 -3
  14. package/dist/chunks/{LpMediaGallery-YKr-cQPN.js → LpMediaGallery-BnlkN_1f.js} +1 -1
  15. package/dist/chunks/LpPalettePreview-CFav_7co.js +19 -0
  16. package/dist/chunks/LpRangeSlider-C1yF9-nP.js +86 -0
  17. package/dist/chunks/LpVideoBackdrop-DN6xPUav.js +251 -0
  18. package/dist/component-names.d.ts +1 -1
  19. package/dist/components/HighlightText.vue.d.ts +7 -0
  20. package/dist/components/HighlightText.vue.js +4 -0
  21. package/dist/components/LpAvatar.vue.d.ts +12 -0
  22. package/dist/components/LpAvatar.vue.js +1 -1
  23. package/dist/components/LpCommandPalette.vue.d.ts +152 -15
  24. package/dist/components/LpCommandPalette.vue.js +178 -92
  25. package/dist/components/LpKeys.vue.d.ts +22 -0
  26. package/dist/components/LpKeys.vue.js +52 -0
  27. package/dist/components/LpLightbox.vue.js +1 -1
  28. package/dist/components/LpMediaGallery.vue.js +1 -1
  29. package/dist/components/LpPaletteFacts.vue.d.ts +25 -0
  30. package/dist/components/LpPaletteFacts.vue.js +85 -0
  31. package/dist/components/LpPaletteHeader.vue.d.ts +32 -0
  32. package/dist/components/LpPaletteHeader.vue.js +103 -0
  33. package/dist/components/LpPalettePreview.vue.d.ts +19 -0
  34. package/dist/components/LpPalettePreview.vue.js +4 -0
  35. package/dist/components/LpPaletteStats.vue.d.ts +11 -0
  36. package/dist/components/LpPaletteStats.vue.js +47 -0
  37. package/dist/components/LpPaletteSwatches.vue.d.ts +10 -0
  38. package/dist/components/LpPaletteSwatches.vue.js +34 -0
  39. package/dist/components/LpRangeSlider.vue.d.ts +39 -0
  40. package/dist/components/LpRangeSlider.vue.js +4 -0
  41. package/dist/components/LpShortcutsDialog.vue.js +8 -28
  42. package/dist/components/LpTable.vue.js +5 -3
  43. package/dist/components/LpVideoBackdrop.vue.d.ts +61 -0
  44. package/dist/components/LpVideoBackdrop.vue.js +4 -0
  45. package/dist/components/commandPalette.d.ts +157 -0
  46. package/dist/components/commandPalette.js +103 -0
  47. package/dist/components/commandSearch.d.ts +32 -0
  48. package/dist/components/commandSearch.js +48 -0
  49. package/dist/components/keys.d.ts +2 -0
  50. package/dist/components/keys.js +11 -0
  51. package/dist/components/videoBackdrop.d.ts +37 -0
  52. package/dist/components/videoBackdrop.js +40 -0
  53. package/dist/index.d.ts +16 -3
  54. package/dist/index.js +167 -134
  55. package/package.json +1 -1
  56. package/src/component-names.ts +9 -1
  57. package/src/components/HighlightText.vue +28 -0
  58. package/src/components/LpAvatar.vue +21 -2
  59. package/src/components/LpCommandPalette.vue +387 -87
  60. package/src/components/LpKeys.vue +79 -0
  61. package/src/components/LpLightbox.vue +4 -1
  62. package/src/components/LpPaletteFacts.vue +165 -0
  63. package/src/components/LpPaletteHeader.vue +155 -0
  64. package/src/components/LpPalettePreview.vue +77 -0
  65. package/src/components/LpPaletteStats.vue +81 -0
  66. package/src/components/LpPaletteSwatches.vue +56 -0
  67. package/src/components/LpRangeSlider.vue +96 -0
  68. package/src/components/LpShortcutsDialog.vue +2 -45
  69. package/src/components/LpTable.vue +6 -1
  70. package/src/components/LpVideoBackdrop.vue +303 -0
  71. package/src/components/commandPalette.ts +264 -0
  72. package/src/components/commandSearch.ts +79 -0
  73. package/src/components/keys.ts +13 -0
  74. package/src/components/videoBackdrop.ts +73 -0
  75. package/src/index.ts +16 -3
@@ -1,5 +1,6 @@
1
- import { defineComponent, ref, useId, computed, shallowRef, watch, useSlots, nextTick, onBeforeUnmount, openBlock, createBlock, unref, withCtx, createVNode, normalizeStyle, normalizeClass, withModifiers, createTextVNode, toDisplayString, createElementVNode, createElementBlock, Fragment, renderList, createCommentVNode, withDirectives, withKeys, vModelText, resolveDynamicComponent, Transition, renderSlot } from "vue";
1
+ import { defineComponent, ref, useId, computed, shallowRef, watch, useSlots, onBeforeUnmount, nextTick, openBlock, createBlock, unref, withCtx, createVNode, normalizeStyle, normalizeClass, withModifiers, createTextVNode, toDisplayString, createElementVNode, createElementBlock, Fragment, renderList, createCommentVNode, withDirectives, withKeys, vModelText, resolveDynamicComponent, Transition, renderSlot } from "vue";
2
2
  import { DialogRoot, DialogPortal, DialogOverlay, DialogContent, DialogTitle, DialogDescription } from "reka-ui";
3
+ import { _ as _sfc_main$3 } from "../chunks/LpAvatar-Cb1jtOVv.js";
3
4
  import { _ as _sfc_main$1 } from "../chunks/LpIcon-DYtaid0K.js";
4
5
  import { _ as _sfc_main$2 } from "../chunks/LpScrollArea-Hz3-JWUG.js";
5
6
  import { useAsyncTask } from "../composables/useAsyncTask.js";
@@ -8,9 +9,10 @@ import { useClipboard } from "../composables/useClipboard.js";
8
9
  import { useHotkeys } from "../composables/useHotkeys.js";
9
10
  import { useModalLayer } from "./modalDepth.js";
10
11
  import { useLabels } from "../composables/useLpConfig.js";
11
- import { parseCommandQuery, rankCommandItems } from "./commandSearch.js";
12
+ import { parseCommandQuery, rankCommandItems, applyQueryFilters, parsePaletteQuery, highlightParts } from "./commandSearch.js";
13
+ import { fallbackRows, readRecent, resolveRecentItems, recentVisible, commandHasPreview, matchModePrefix, modeChipLabel, toRecentItem, pushRecent } from "./commandPalette.js";
12
14
  import { _ as _export_sfc } from "../chunks/_plugin-vue_export-helper-1tPrXgE0.js";
13
- import '../assets/LpCommandPalette-5miKYsb-.css';const _hoisted_1 = { class: "flex shrink-0 items-center gap-2.5 border-b border-line px-4" };
15
+ import '../assets/LpCommandPalette-DmQUsJqA.css';const _hoisted_1 = { class: "flex shrink-0 items-center gap-2.5 border-b border-line px-4" };
14
16
  const _hoisted_2 = ["title", "onClick"];
15
17
  const _hoisted_3 = ["aria-activedescendant", "placeholder", "onKeydown"];
16
18
  const _hoisted_4 = { class: "shrink-0 rounded border border-line px-1.5 py-0.5 text-[10px] text-muted" };
@@ -39,37 +41,42 @@ const _hoisted_13 = {
39
41
  class: "rounded-xs bg-brand/20 text-ink"
40
42
  };
41
43
  const _hoisted_14 = {
42
- key: 1,
44
+ key: 2,
43
45
  class: "shrink-0 text-xs text-muted"
44
46
  };
45
47
  const _hoisted_15 = {
48
+ key: 3,
49
+ class: "shrink-0 rounded border border-line px-1.5 font-mono text-[11px] whitespace-pre text-muted"
50
+ };
51
+ const _hoisted_16 = {
46
52
  key: 0,
47
53
  class: "lp-cmd-pane hidden min-h-0 shrink-0 flex-col border-l border-line md:flex"
48
54
  };
49
- const _hoisted_16 = { class: "lp-cmd-para flex items-center gap-2 text-ink" };
50
- const _hoisted_17 = { class: "min-w-0 text-base font-semibold" };
51
- const _hoisted_18 = {
55
+ const _hoisted_17 = { class: "lp-cmd-para flex items-center gap-2 text-ink" };
56
+ const _hoisted_18 = { class: "min-w-0 text-base font-semibold" };
57
+ const _hoisted_19 = {
52
58
  key: 0,
53
59
  class: "lp-cmd-para mt-0.5 text-xs text-muted"
54
60
  };
55
- const _hoisted_19 = {
61
+ const _hoisted_20 = {
56
62
  key: 0,
57
63
  class: "rounded-xs bg-brand/25 text-ink"
58
64
  };
59
- const _hoisted_20 = { class: "flex shrink-0 items-center gap-4 border-t border-line px-4 py-2.5 text-[11px] text-muted [@media(hover:none)_and_(pointer:coarse)]:hidden" };
60
- const _hoisted_21 = { class: "flex items-center gap-1" };
65
+ const _hoisted_21 = { class: "flex shrink-0 items-center gap-4 border-t border-line px-4 py-2.5 text-[11px] text-muted [@media(hover:none)_and_(pointer:coarse)]:hidden" };
61
66
  const _hoisted_22 = { class: "flex items-center gap-1" };
62
- const _hoisted_23 = {
67
+ const _hoisted_23 = { class: "flex items-center gap-1" };
68
+ const _hoisted_24 = {
63
69
  key: 0,
64
70
  class: "flex items-center gap-1"
65
71
  };
66
- const _hoisted_24 = {
72
+ const _hoisted_25 = {
67
73
  key: 1,
68
74
  class: "flex items-center gap-1"
69
75
  };
70
- const _hoisted_25 = { class: "ml-auto flex items-center gap-1" };
71
- const _hoisted_26 = { class: "rounded border border-line px-1 text-[10px]" };
76
+ const _hoisted_26 = { class: "ml-auto flex items-center gap-1" };
77
+ const _hoisted_27 = { class: "rounded border border-line px-1 text-[10px]" };
72
78
  const RECENT_KEEP = 20;
79
+ const PANE_LINGER_MS = 160;
73
80
  const STAGGER_MS = 45;
74
81
  const STAGGER_MAX = 10;
75
82
  const _sfc_main = /* @__PURE__ */ defineComponent({
@@ -85,6 +92,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
85
92
  minChars: { default: 1 },
86
93
  recent: {},
87
94
  recentKey: {},
95
+ resolveRecent: {},
88
96
  recentLimit: { default: 5 },
89
97
  recentLabel: { default: "Recent" },
90
98
  resultsLabel: { default: "Results" },
@@ -92,9 +100,10 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
92
100
  excerptLines: { default: 4 },
93
101
  groupLimit: { default: 0 },
94
102
  previewPane: { type: Boolean, default: false },
103
+ hasPreview: {},
95
104
  glass: { type: Boolean, default: void 0 }
96
105
  },
97
- emits: ["update:open", "select", "run"],
106
+ emits: ["update:open", "select", "run", "remember"],
98
107
  setup(__props, { emit: __emit }) {
99
108
  const props = __props;
100
109
  const frosted = useGlass(() => props.glass);
@@ -165,7 +174,9 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
165
174
  if (!c || !actions.length) return;
166
175
  event.preventDefault();
167
176
  event.stopPropagation();
168
- enter({ id: `${c.id}:actions`, label: c.label, icon: c.icon, children: actions });
177
+ const actionsMode = { id: `${c.id}:actions`, label: c.label, icon: c.icon, children: actions };
178
+ syntheticModes.add(actionsMode);
179
+ enter(actionsMode);
169
180
  }
170
181
  watch(
171
182
  () => props.commands,
@@ -184,8 +195,8 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
184
195
  if (last && Array.isArray(last.children)) modeItems.value = last.children;
185
196
  }
186
197
  );
187
- function enter(c) {
188
- trailState.value = [...trailState.value, { query: query.value, selectedId: selectedId.value }];
198
+ function enter(c, parentQuery = query.value) {
199
+ trailState.value = [...trailState.value, { query: parentQuery, selectedId: selectedId.value }];
189
200
  trail.value = [...trail.value, c];
190
201
  query.value = "";
191
202
  select(0);
@@ -234,10 +245,11 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
234
245
  failed.value = false;
235
246
  const run2 = fetcher();
236
247
  if (!run2) return;
237
- const q = query.value.trim();
248
+ const parsed = parsePaletteQuery(query.value.trim());
249
+ const q = parsed.text;
238
250
  const inMode = mode.value !== null;
239
251
  if (!inMode && q.length < Math.max(1, props.minChars)) return;
240
- task.run((signal) => run2(q, signal), {
252
+ task.run((signal) => run2(q, signal, parsed), {
241
253
  delay: props.debounce,
242
254
  apply: (hits) => found.value = hits,
243
255
  fail: () => {
@@ -249,7 +261,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
249
261
  const source = computed(() => mode.value ? modeItems.value : props.commands);
250
262
  const local = computed(() => {
251
263
  const terms = parseCommandQuery(query.value);
252
- const filtered = query.value.trim() ? source.value : source.value.filter((c) => !c.hidden);
264
+ const filtered = query.value.trim() ? source.value.filter((c) => !c.fallback) : source.value.filter((c) => !c.hidden && !c.fallback);
253
265
  if (!terms.include.length && !terms.exclude.length && !terms.groups.length) return { items: filtered, terms: [] };
254
266
  const items = rankCommandItems(filtered, terms);
255
267
  return { items, terms: terms.include };
@@ -258,39 +270,63 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
258
270
  const fetched = computed(() => {
259
271
  if (!found.value.length) return [];
260
272
  const seen = new Set(ranked.value.map((c) => c.id));
261
- return found.value.filter((c) => !seen.has(c.id)).map((c) => c.group ? c : { ...c, group: props.resultsLabel });
273
+ const rows = found.value.filter((c) => !seen.has(c.id)).map((c) => c.group ? c : { ...c, group: props.resultsLabel });
274
+ return applyQueryFilters(rows, parseCommandQuery(query.value));
262
275
  });
276
+ const fallbackOf = /* @__PURE__ */ new WeakMap();
277
+ const fallbacks = computed(
278
+ () => fallbackRows(source.value, query.value).map(({ command, label }) => {
279
+ const row = { ...command, label };
280
+ fallbackOf.set(row, command);
281
+ return row;
282
+ })
283
+ );
263
284
  const ownRecent = ref([]);
264
285
  watch(
265
286
  () => props.recentKey,
266
287
  (key) => {
267
288
  if (!key || typeof localStorage === "undefined") return;
268
289
  try {
269
- const stored = JSON.parse(localStorage.getItem(key) ?? "[]");
270
- ownRecent.value = Array.isArray(stored) ? stored.filter((v) => typeof v === "string") : [];
290
+ ownRecent.value = readRecent(JSON.parse(localStorage.getItem(key) ?? "[]"));
271
291
  } catch {
272
292
  ownRecent.value = [];
273
293
  }
274
294
  },
275
295
  { immediate: true }
276
296
  );
277
- function remember(id) {
297
+ const recentPath = /* @__PURE__ */ new WeakMap();
298
+ const syntheticModes = /* @__PURE__ */ new WeakSet();
299
+ function remember(c) {
300
+ if (c.remember === false || trail.value.some((step) => syntheticModes.has(step))) return;
301
+ const path = recentPath.get(c) ?? trail.value.map((step) => step.id);
302
+ const item = toRecentItem(c, path);
303
+ emit("remember", item, c);
278
304
  const key = props.recentKey;
279
305
  if (!key || props.recent) return;
280
- ownRecent.value = [id, ...ownRecent.value.filter((v) => v !== id)].slice(0, RECENT_KEEP);
306
+ ownRecent.value = pushRecent(ownRecent.value, item, RECENT_KEEP);
281
307
  try {
282
308
  localStorage.setItem(key, JSON.stringify(ownRecent.value));
283
309
  } catch {
284
310
  }
285
311
  }
286
- const recentIds = computed(() => props.recent ?? (props.recentKey ? ownRecent.value : []));
312
+ const recentList = computed(() => props.recent ?? (props.recentKey ? ownRecent.value : []));
313
+ function fromEntry(entry) {
314
+ return { id: entry.id, label: entry.label, description: entry.description, icon: entry.icon, image: entry.image, href: entry.href };
315
+ }
287
316
  const recentItems = computed(() => {
288
- if (mode.value || query.value.trim() || !recentIds.value.length) return [];
289
- const byId = new Map(props.commands.map((c) => [c.id, c]));
317
+ if (mode.value || !recentList.value.length) return [];
318
+ const terms = parseCommandQuery(query.value);
319
+ if (terms.include.length) return [];
320
+ const found2 = resolveRecentItems(recentList.value, props.commands, {
321
+ limit: Number.POSITIVE_INFINITY,
322
+ resolve: props.resolveRecent,
323
+ fromEntry
324
+ });
290
325
  const out = [];
291
- for (const id of recentIds.value) {
292
- const c = byId.get(id);
293
- if (c && !c.disabled && !out.includes(c)) out.push(c);
326
+ for (const { command, path } of found2) {
327
+ if (out.includes(command) || !recentVisible(command, terms, props.recentLabel)) continue;
328
+ recentPath.set(command, path);
329
+ out.push(command);
294
330
  if (out.length >= props.recentLimit) break;
295
331
  }
296
332
  return out;
@@ -309,6 +345,16 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
309
345
  for (const c of recent) push(c, props.recentLabel);
310
346
  for (const c of ranked.value) if (!recent.includes(c)) push(c, c.group ?? "");
311
347
  for (const c of fetched.value) push(c, c.group ?? "");
348
+ const tail = /* @__PURE__ */ new Map();
349
+ for (const c of fallbacks.value) {
350
+ const group = c.group ?? "";
351
+ if (map.has(group)) map.get(group).push(c);
352
+ else tail.set(group, [...tail.get(group) ?? [], c]);
353
+ }
354
+ for (const [group, items] of tail) {
355
+ map.set(group, items);
356
+ order.push(group);
357
+ }
312
358
  return order.map((name) => ({ name, items: folded(name, map.get(name)) }));
313
359
  });
314
360
  const expanded = ref(/* @__PURE__ */ new Set());
@@ -334,20 +380,45 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
334
380
  return c && !moreOf.has(c) ? c : void 0;
335
381
  });
336
382
  const previewRef = ref(null);
337
- const paneOpen = computed(
338
- () => props.previewPane && !!active.value && (!!slots.preview || !!(active.value.preview || active.value.excerpt))
383
+ const previewable = computed(
384
+ () => props.previewPane && commandHasPreview(active.value, { slot: !!slots.preview, hasPreview: props.hasPreview })
385
+ );
386
+ const paneCommand = shallowRef();
387
+ let lingerTimer;
388
+ watch(
389
+ [active, previewable],
390
+ ([command, show]) => {
391
+ clearTimeout(lingerTimer);
392
+ if (show) {
393
+ paneCommand.value = command;
394
+ return;
395
+ }
396
+ if (!paneCommand.value) return;
397
+ lingerTimer = setTimeout(() => paneCommand.value = void 0, PANE_LINGER_MS);
398
+ },
399
+ { immediate: true }
339
400
  );
401
+ onBeforeUnmount(() => clearTimeout(lingerTimer));
402
+ const paneOpen = computed(() => props.previewPane && !!paneCommand.value);
403
+ function paneHighlight(text2) {
404
+ return highlight(text2, paneBody.value?.highlight);
405
+ }
406
+ const paneQuery = computed(() => parsePaletteQuery(query.value.trim()));
407
+ const paneBody = shallowRef();
408
+ watch(paneCommand, (command) => {
409
+ if (command) paneBody.value = command;
410
+ });
340
411
  const paragraphs = computed(
341
- () => (active.value?.preview ?? active.value?.excerpt ?? "").split(/\n{2,}/).map((part) => part.trim()).filter(Boolean)
412
+ () => (paneBody.value?.preview ?? paneBody.value?.excerpt ?? "").split(/\n{2,}/).map((part) => part.trim()).filter(Boolean)
342
413
  );
343
414
  const paneDescription = computed(() => {
344
- const description = active.value?.description?.trim();
415
+ const description = paneBody.value?.description?.trim();
345
416
  if (!description) return void 0;
346
417
  const body = paragraphs.value.join(" ");
347
418
  return body.startsWith(description) ? void 0 : description;
348
419
  });
349
420
  watch(
350
- () => active.value?.id,
421
+ () => paneCommand.value?.id,
351
422
  async () => {
352
423
  if (!paneOpen.value) return;
353
424
  await nextTick();
@@ -363,37 +434,26 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
363
434
  return flatIndex.value.get(c) ?? -1;
364
435
  }
365
436
  function highlight(value, extra = []) {
366
- const terms = [...new Set([...local.value.terms, ...extra.map((t) => t.toLowerCase())].filter((t) => t.length >= 2))].sort(
367
- (a, b) => b.length - a.length
368
- );
369
- if (!value || terms.length === 0) return value ? [{ text: value, hit: false }] : [];
370
- const lower = value.toLowerCase();
371
- const parts = [];
372
- let i = 0;
373
- while (i < value.length) {
374
- let at = -1;
375
- let term = "";
376
- for (const t of terms) {
377
- const found2 = lower.indexOf(t, i);
378
- if (found2 !== -1 && (at === -1 || found2 < at || found2 === at && t.length > term.length)) {
379
- at = found2;
380
- term = t;
381
- }
382
- }
383
- if (at === -1) {
384
- parts.push({ text: value.slice(i), hit: false });
385
- break;
386
- }
387
- if (at > i) parts.push({ text: value.slice(i, at), hit: false });
388
- parts.push({ text: value.slice(at, at + term.length), hit: true });
389
- i = at + term.length;
390
- }
391
- return parts;
437
+ return highlightParts(value, [...local.value.terms, ...extra]);
392
438
  }
393
- watch(query, () => {
439
+ const IMAGE_RADIUS = { circle: "rounded-pill", soft: "rounded-[6px]", square: "rounded-[3px]" };
440
+ function imageOf(c) {
441
+ if (!c.image) return null;
442
+ const image = typeof c.image === "string" ? { src: c.image } : c.image;
443
+ return { ...image, icon: image.icon ?? c.icon };
444
+ }
445
+ watch(query, (value) => {
446
+ if (enterByPrefix(value)) return;
394
447
  select(0);
395
448
  refresh();
396
449
  });
450
+ function enterByPrefix(value) {
451
+ const hit = matchModePrefix(value, source.value);
452
+ if (!hit) return false;
453
+ enter(hit.command, "");
454
+ query.value = hit.rest;
455
+ return true;
456
+ }
397
457
  watch([query, trail, () => props.open], () => {
398
458
  expanded.value = /* @__PURE__ */ new Set();
399
459
  });
@@ -463,6 +523,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
463
523
  if (!c.href) return;
464
524
  window.open(c.href, "_blank", "noopener");
465
525
  emit("run", c.id, c);
526
+ remember(c);
466
527
  emit("update:open", false);
467
528
  }
468
529
  function onRowClick(event, c) {
@@ -470,11 +531,12 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
470
531
  event.preventDefault();
471
532
  run(c);
472
533
  }
473
- function run(c) {
474
- if (!c || c.disabled) return;
475
- const group = moreOf.get(c);
534
+ function run(row) {
535
+ if (!row || row.disabled) return;
536
+ const c = fallbackOf.get(row) ?? row;
537
+ const group = moreOf.get(row);
476
538
  if (group !== void 0) {
477
- selectedId.value = firstHidden.get(c) ?? null;
539
+ selectedId.value = firstHidden.get(row) ?? null;
478
540
  expanded.value = /* @__PURE__ */ new Set([...expanded.value, group]);
479
541
  inputRef.value?.focus();
480
542
  return;
@@ -483,11 +545,13 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
483
545
  c.onSelect?.();
484
546
  if (!c.onSelect && c.href && !c.children) window.location.assign(c.href);
485
547
  if (c.children) {
548
+ const carried = query.value;
486
549
  enter(c);
550
+ if (c.carryQuery) query.value = carried;
487
551
  return;
488
552
  }
489
553
  emit("run", c.id, c);
490
- if (!mode.value) remember(c.id);
554
+ remember(c);
491
555
  if (c.keepOpen) {
492
556
  query.value = "";
493
557
  if (mode.value) void nextTick(() => select(Math.max(0, flat.value.findIndex((x) => x.id === c.id))));
@@ -602,7 +666,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
602
666
  name: step.icon,
603
667
  size: 13
604
668
  }, null, 8, ["name"])) : createCommentVNode("", true),
605
- createTextVNode(" " + toDisplayString(step.label) + " ", 1),
669
+ createTextVNode(" " + toDisplayString(unref(modeChipLabel)(step)) + " ", 1),
606
670
  createVNode(_sfc_main$1, {
607
671
  name: "lucide:x",
608
672
  size: 12,
@@ -680,8 +744,17 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
680
744
  onPointerenter: ($event) => onPointerEnter(c)
681
745
  }, {
682
746
  default: withCtx(() => [
683
- c.icon ? (openBlock(), createBlock(_sfc_main$1, {
747
+ imageOf(c) ? (openBlock(), createBlock(_sfc_main$3, {
684
748
  key: 0,
749
+ src: imageOf(c).src ?? void 0,
750
+ alt: imageOf(c).alt ?? "",
751
+ fallback: imageOf(c).fallback,
752
+ icon: imageOf(c).icon,
753
+ shape: imageOf(c).shape ?? "soft",
754
+ "pixel-size": 20,
755
+ class: normalizeClass(["-my-0.5 -ml-0.5 shrink-0 text-[9px]", IMAGE_RADIUS[imageOf(c).shape ?? "soft"]])
756
+ }, null, 8, ["src", "alt", "fallback", "icon", "shape", "class"])) : c.icon ? (openBlock(), createBlock(_sfc_main$1, {
757
+ key: 1,
685
758
  name: c.icon,
686
759
  size: 16,
687
760
  class: normalizeClass(["shrink-0", { "mt-0.5": c.excerpt }])
@@ -725,8 +798,8 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
725
798
  }), 128))
726
799
  ], 4)) : createCommentVNode("", true)
727
800
  ]),
728
- c.shortcut ? (openBlock(), createElementBlock("kbd", _hoisted_14, toDisplayString(c.shortcut), 1)) : c.children ? (openBlock(), createBlock(_sfc_main$1, {
729
- key: 2,
801
+ c.shortcut ? (openBlock(), createElementBlock("kbd", _hoisted_14, toDisplayString(c.shortcut), 1)) : c.prefix && c.children ? (openBlock(), createElementBlock("kbd", _hoisted_15, toDisplayString(c.prefix), 1)) : c.children ? (openBlock(), createBlock(_sfc_main$1, {
802
+ key: 4,
730
803
  name: "lucide:chevron-right",
731
804
  size: 14,
732
805
  class: "shrink-0 text-muted"
@@ -763,7 +836,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
763
836
  }, 512),
764
837
  createVNode(Transition, { name: "lp-cmd-pane" }, {
765
838
  default: withCtx(() => [
766
- paneOpen.value ? (openBlock(), createElementBlock("aside", _hoisted_15, [
839
+ paneOpen.value ? (openBlock(), createElementBlock("aside", _hoisted_16, [
767
840
  createVNode(_sfc_main$2, {
768
841
  ref_key: "previewRef",
769
842
  ref: previewRef,
@@ -771,31 +844,44 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
771
844
  "content-class": "px-5 py-4"
772
845
  }, {
773
846
  default: withCtx(() => [
774
- active.value ? (openBlock(), createElementBlock("div", {
775
- key: active.value.id
847
+ paneBody.value ? (openBlock(), createElementBlock("div", {
848
+ key: paneBody.value.id
776
849
  }, [
777
- renderSlot(_ctx.$slots, "preview", { command: active.value }, () => [
778
- createElementVNode("div", _hoisted_16, [
779
- active.value.icon ? (openBlock(), createBlock(_sfc_main$1, {
850
+ renderSlot(_ctx.$slots, "preview", {
851
+ command: paneBody.value,
852
+ highlight: paneHighlight,
853
+ query: paneQuery.value
854
+ }, () => [
855
+ createElementVNode("div", _hoisted_17, [
856
+ imageOf(paneBody.value) ? (openBlock(), createBlock(_sfc_main$3, {
780
857
  key: 0,
781
- name: active.value.icon,
858
+ src: imageOf(paneBody.value).src ?? void 0,
859
+ alt: imageOf(paneBody.value).alt ?? "",
860
+ fallback: imageOf(paneBody.value).fallback,
861
+ icon: imageOf(paneBody.value).icon,
862
+ shape: imageOf(paneBody.value).shape ?? "soft",
863
+ "pixel-size": 28,
864
+ class: normalizeClass(["shrink-0", IMAGE_RADIUS[imageOf(paneBody.value).shape ?? "soft"]])
865
+ }, null, 8, ["src", "alt", "fallback", "icon", "shape", "class"])) : paneBody.value.icon ? (openBlock(), createBlock(_sfc_main$1, {
866
+ key: 1,
867
+ name: paneBody.value.icon,
782
868
  size: 16,
783
869
  class: "shrink-0 text-muted"
784
870
  }, null, 8, ["name"])) : createCommentVNode("", true),
785
- createElementVNode("h3", _hoisted_17, toDisplayString(active.value.label), 1)
871
+ createElementVNode("h3", _hoisted_18, toDisplayString(paneBody.value.label), 1)
786
872
  ]),
787
- paneDescription.value ? (openBlock(), createElementBlock("p", _hoisted_18, toDisplayString(paneDescription.value), 1)) : createCommentVNode("", true),
873
+ paneDescription.value ? (openBlock(), createElementBlock("p", _hoisted_19, toDisplayString(paneDescription.value), 1)) : createCommentVNode("", true),
788
874
  (openBlock(true), createElementBlock(Fragment, null, renderList(paragraphs.value, (para, i) => {
789
875
  return openBlock(), createElementBlock("p", {
790
876
  key: i,
791
877
  class: "lp-cmd-para mt-3 whitespace-pre-line text-sm leading-relaxed text-ink/90",
792
878
  style: normalizeStyle({ animationDelay: `${Math.min(i + 1, STAGGER_MAX) * STAGGER_MS}ms` })
793
879
  }, [
794
- (openBlock(true), createElementBlock(Fragment, null, renderList(highlight(para, active.value.highlight), (p, pi) => {
880
+ (openBlock(true), createElementBlock(Fragment, null, renderList(highlight(para, paneBody.value.highlight), (p, pi) => {
795
881
  return openBlock(), createElementBlock(Fragment, {
796
882
  key: `p${pi}`
797
883
  }, [
798
- p.hit ? (openBlock(), createElementBlock("mark", _hoisted_19, toDisplayString(p.text), 1)) : (openBlock(), createElementBlock(Fragment, { key: 1 }, [
884
+ p.hit ? (openBlock(), createElementBlock("mark", _hoisted_20, toDisplayString(p.text), 1)) : (openBlock(), createElementBlock(Fragment, { key: 1 }, [
799
885
  createTextVNode(toDisplayString(p.text), 1)
800
886
  ], 64))
801
887
  ], 64);
@@ -812,26 +898,26 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
812
898
  _: 3
813
899
  })
814
900
  ], 32),
815
- createElementVNode("div", _hoisted_20, [
816
- createElementVNode("span", _hoisted_21, [
901
+ createElementVNode("div", _hoisted_21, [
902
+ createElementVNode("span", _hoisted_22, [
817
903
  _cache[4] || (_cache[4] = createElementVNode("kbd", { class: "rounded border border-line px-1 text-[10px]" }, "↑", -1)),
818
904
  _cache[5] || (_cache[5] = createElementVNode("kbd", { class: "rounded border border-line px-1 text-[10px]" }, "↓", -1)),
819
905
  createTextVNode(" " + toDisplayString(unref(text).navigate), 1)
820
906
  ]),
821
- createElementVNode("span", _hoisted_22, [
907
+ createElementVNode("span", _hoisted_23, [
822
908
  _cache[6] || (_cache[6] = createElementVNode("kbd", { class: "rounded border border-line px-1 text-[10px]" }, "↵", -1)),
823
909
  createTextVNode(" " + toDisplayString(unref(text).select), 1)
824
910
  ]),
825
- selectedActions.value.length ? (openBlock(), createElementBlock("span", _hoisted_23, [
911
+ selectedActions.value.length ? (openBlock(), createElementBlock("span", _hoisted_24, [
826
912
  _cache[7] || (_cache[7] = createElementVNode("kbd", { class: "rounded border border-line px-1 text-[10px]" }, "tab", -1)),
827
913
  createTextVNode(" " + toDisplayString(unref(text).actions), 1)
828
914
  ])) : createCommentVNode("", true),
829
- trail.value.length ? (openBlock(), createElementBlock("span", _hoisted_24, [
915
+ trail.value.length ? (openBlock(), createElementBlock("span", _hoisted_25, [
830
916
  _cache[8] || (_cache[8] = createElementVNode("kbd", { class: "rounded border border-line px-1 text-[10px]" }, "⌫", -1)),
831
917
  createTextVNode(" " + toDisplayString(unref(text).back), 1)
832
918
  ])) : createCommentVNode("", true),
833
- createElementVNode("span", _hoisted_25, [
834
- createElementVNode("kbd", _hoisted_26, toDisplayString(unref(text).esc), 1),
919
+ createElementVNode("span", _hoisted_26, [
920
+ createElementVNode("kbd", _hoisted_27, toDisplayString(unref(text).esc), 1),
835
921
  createTextVNode(" " + toDisplayString(unref(text).close), 1)
836
922
  ])
837
923
  ])
@@ -847,7 +933,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
847
933
  };
848
934
  }
849
935
  });
850
- const LpCommandPalette = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-254e59f7"]]);
936
+ const LpCommandPalette = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-6da7fe88"]]);
851
937
  export {
852
938
  LpCommandPalette as default
853
939
  };
@@ -0,0 +1,22 @@
1
+ type __VLS_Props = {
2
+ /** "Ctrl+K", "Ctrl++", or a sequence "G I". Or keys already split. */
3
+ combo: string | string[];
4
+ /** Text after the caps, e.g. what the keys do. */
5
+ label?: string;
6
+ size?: "sm" | "md";
7
+ };
8
+ declare var __VLS_1: {};
9
+ type __VLS_Slots = {} & {
10
+ default?: (props: typeof __VLS_1) => any;
11
+ };
12
+ declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {
13
+ size: "sm" | "md";
14
+ }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
15
+ declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
16
+ declare const _default: typeof __VLS_export;
17
+ export default _default;
18
+ type __VLS_WithSlots<T, S> = T & {
19
+ new (): {
20
+ $slots: S;
21
+ };
22
+ };
@@ -0,0 +1,52 @@
1
+ import { defineComponent, computed, openBlock, createElementBlock, normalizeClass, Fragment, renderList, toDisplayString, unref, createCommentVNode, renderSlot, createTextVNode } from "vue";
2
+ import { useAppleKeyboard, appleModifierLabel } from "../composables/useHotkeys.js";
3
+ import { useLabels } from "../composables/useLpConfig.js";
4
+ import { comboSteps } from "./keys.js";
5
+ import { _ as _export_sfc } from "../chunks/_plugin-vue_export-helper-1tPrXgE0.js";
6
+ import '../assets/LpKeys-BxRhfQda.css';const _hoisted_1 = {
7
+ key: 0,
8
+ class: "lp-keys__then"
9
+ };
10
+ const _hoisted_2 = {
11
+ key: 0,
12
+ class: "lp-keys__label"
13
+ };
14
+ const _sfc_main = /* @__PURE__ */ defineComponent({
15
+ __name: "LpKeys",
16
+ props: {
17
+ combo: {},
18
+ label: {},
19
+ size: { default: "md" }
20
+ },
21
+ setup(__props) {
22
+ const props = __props;
23
+ const text = useLabels("shortcuts", { then: "then" });
24
+ const apple = useAppleKeyboard();
25
+ const steps = computed(() => Array.isArray(props.combo) ? [props.combo] : comboSteps(props.combo));
26
+ return (_ctx, _cache) => {
27
+ return openBlock(), createElementBlock("span", {
28
+ class: normalizeClass(["lp-keys", `lp-keys--${__props.size}`])
29
+ }, [
30
+ (openBlock(true), createElementBlock(Fragment, null, renderList(steps.value, (step, stepIndex) => {
31
+ return openBlock(), createElementBlock(Fragment, { key: stepIndex }, [
32
+ stepIndex ? (openBlock(), createElementBlock("span", _hoisted_1, toDisplayString(unref(text).then), 1)) : createCommentVNode("", true),
33
+ (openBlock(true), createElementBlock(Fragment, null, renderList(step, (key, index) => {
34
+ return openBlock(), createElementBlock("kbd", {
35
+ key: `${key}-${index}`
36
+ }, toDisplayString(unref(appleModifierLabel)(key.trim(), unref(apple))), 1);
37
+ }), 128))
38
+ ], 64);
39
+ }), 128)),
40
+ __props.label || _ctx.$slots.default ? (openBlock(), createElementBlock("span", _hoisted_2, [
41
+ renderSlot(_ctx.$slots, "default", {}, () => [
42
+ createTextVNode(toDisplayString(__props.label), 1)
43
+ ], true)
44
+ ])) : createCommentVNode("", true)
45
+ ], 2);
46
+ };
47
+ }
48
+ });
49
+ const LpKeys = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-5c6ae8ec"]]);
50
+ export {
51
+ LpKeys as default
52
+ };
@@ -1,4 +1,4 @@
1
- import { _ as _sfc_main } from "../chunks/LpLightbox-DSDahF23.js";
1
+ import { _ as _sfc_main } from "../chunks/LpLightbox-EVXzAq62.js";
2
2
  export {
3
3
  _sfc_main as default
4
4
  };
@@ -1,4 +1,4 @@
1
- import { _ as _sfc_main } from "../chunks/LpMediaGallery-YKr-cQPN.js";
1
+ import { _ as _sfc_main } from "../chunks/LpMediaGallery-BnlkN_1f.js";
2
2
  export {
3
3
  _sfc_main as default
4
4
  };
@@ -0,0 +1,25 @@
1
+ import type { PaletteFact } from "./commandPalette";
2
+ type __VLS_Props = {
3
+ items: PaletteFact[];
4
+ /** Small heading over the list. */
5
+ title?: string;
6
+ /** Plain rows instead of soft tiles, for a list read as text. */
7
+ plain?: boolean;
8
+ };
9
+ type __VLS_Slots = {
10
+ value?: (props: {
11
+ item: PaletteFact;
12
+ index: number;
13
+ }) => unknown;
14
+ };
15
+ declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {
16
+ plain: boolean;
17
+ }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
18
+ declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
19
+ declare const _default: typeof __VLS_export;
20
+ export default _default;
21
+ type __VLS_WithSlots<T, S> = T & {
22
+ new (): {
23
+ $slots: S;
24
+ };
25
+ };