@leavepulse/ui 0.41.0 → 0.43.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 (157) hide show
  1. package/dist/assets/{LpCommandPalette-DyT6aGdW.css → LpCommandPalette-s_kKuCRf.css} +21 -21
  2. package/dist/chunks/{LpAddressInput-CMjaPQVw.js → LpAddressInput-B-Zvxsn7.js} +1 -1
  3. package/dist/chunks/{LpAppShell-Bcv6EhqU.js → LpAppShell-BGQVIY-3.js} +1 -1
  4. package/dist/chunks/{LpConfirmDialog-BNAvOR24.js → LpConfirmDialog-Q-bxff8z.js} +1 -1
  5. package/dist/chunks/{LpDrawer-DgaS2s2i.js → LpDrawer-BZ6k3hvo.js} +3 -3
  6. package/dist/chunks/{LpLightbox-oLqyjOln.js → LpLightbox-2sYVMY-S.js} +12 -4
  7. package/dist/chunks/{LpMediaGallery-Cid7PGYx.js → LpMediaGallery-FF-NquIo.js} +1 -1
  8. package/dist/chunks/{LpModal-8bja5bWS.js → LpModal-Bt0pQCI_.js} +2 -2
  9. package/dist/chunks/{LpModalNav-w9kfwHqO.js → LpModalNav-YaifHrXC.js} +2 -2
  10. package/dist/chunks/{LpSidebar-DlTn5nXc.js → LpSidebar-ClBUwoEz.js} +1 -1
  11. package/dist/components/LpAddressInput.vue.js +1 -1
  12. package/dist/components/LpAppShell.vue.js +1 -1
  13. package/dist/components/LpCommandPalette.vue.js +124 -115
  14. package/dist/components/LpConfirmDialog.vue.js +1 -1
  15. package/dist/components/LpDrawer.vue.js +1 -1
  16. package/dist/components/LpLightbox.vue.js +1 -1
  17. package/dist/components/LpMediaGallery.vue.js +1 -1
  18. package/dist/components/LpModal.vue.js +1 -1
  19. package/dist/components/LpModalNav.vue.js +1 -1
  20. package/dist/components/LpShortcutsDialog.vue.js +1 -1
  21. package/dist/components/LpSidebar.vue.js +1 -1
  22. package/dist/components/commandSearch.js +66 -0
  23. package/dist/components/modalDepth.js +3 -2
  24. package/dist/composables/useHotkeys.js +41 -21
  25. package/dist/index.js +13 -9
  26. package/package.json +3 -3
  27. package/src/components/LpCommandPalette.vue +81 -99
  28. package/src/components/LpDrawer.vue +3 -3
  29. package/src/components/LpLightbox.vue +11 -5
  30. package/src/components/LpModal.vue +2 -2
  31. package/src/components/commandSearch.ts +92 -0
  32. package/src/components/modalDepth.ts +4 -48
  33. package/src/composables/useHotkeys.ts +54 -33
  34. package/src/index.ts +2 -0
  35. package/src/tokens/tokens.css +13 -19
  36. package/dist/component-names.d.ts +0 -1
  37. package/dist/components/LayoutCanvas.vue.d.ts +0 -28
  38. package/dist/components/LayoutNode.vue.d.ts +0 -40
  39. package/dist/components/LpActionBar.vue.d.ts +0 -84
  40. package/dist/components/LpAddressInput.vue.d.ts +0 -70
  41. package/dist/components/LpAlert.vue.d.ts +0 -44
  42. package/dist/components/LpAppShell.vue.d.ts +0 -123
  43. package/dist/components/LpAutocomplete.vue.d.ts +0 -50
  44. package/dist/components/LpAvatar.vue.d.ts +0 -34
  45. package/dist/components/LpBadge.vue.d.ts +0 -20
  46. package/dist/components/LpBreadcrumbs.vue.d.ts +0 -32
  47. package/dist/components/LpButton.vue.d.ts +0 -113
  48. package/dist/components/LpCalendar.vue.d.ts +0 -29
  49. package/dist/components/LpCard.vue.d.ts +0 -60
  50. package/dist/components/LpChart.vue.d.ts +0 -130
  51. package/dist/components/LpCheckbox.vue.d.ts +0 -32
  52. package/dist/components/LpCodeBlock.vue.d.ts +0 -58
  53. package/dist/components/LpColorPicker.vue.d.ts +0 -124
  54. package/dist/components/LpCommandPalette.vue.d.ts +0 -206
  55. package/dist/components/LpConfirmDialog.vue.d.ts +0 -59
  56. package/dist/components/LpContextMenu.vue.d.ts +0 -44
  57. package/dist/components/LpDatePicker.vue.d.ts +0 -33
  58. package/dist/components/LpDisclosure.vue.d.ts +0 -47
  59. package/dist/components/LpDivider.vue.d.ts +0 -17
  60. package/dist/components/LpDrawer.vue.d.ts +0 -170
  61. package/dist/components/LpDropdownMenu.vue.d.ts +0 -23
  62. package/dist/components/LpDropzone.vue.d.ts +0 -90
  63. package/dist/components/LpEmptyState.vue.d.ts +0 -28
  64. package/dist/components/LpFileTree.vue.d.ts +0 -126
  65. package/dist/components/LpFileTreeNode.vue.d.ts +0 -62
  66. package/dist/components/LpFormField.vue.d.ts +0 -24
  67. package/dist/components/LpIcon.vue.d.ts +0 -8
  68. package/dist/components/LpImageEditor.vue.d.ts +0 -106
  69. package/dist/components/LpInfraNode.vue.d.ts +0 -65
  70. package/dist/components/LpInput.vue.d.ts +0 -80
  71. package/dist/components/LpLaneNode.vue.d.ts +0 -24
  72. package/dist/components/LpLightbox.vue.d.ts +0 -62
  73. package/dist/components/LpLink.vue.d.ts +0 -93
  74. package/dist/components/LpLogViewer.vue.d.ts +0 -153
  75. package/dist/components/LpMapPicker.vue.d.ts +0 -59
  76. package/dist/components/LpMediaGallery.vue.d.ts +0 -80
  77. package/dist/components/LpModal.vue.d.ts +0 -66
  78. package/dist/components/LpModalNav.vue.d.ts +0 -66
  79. package/dist/components/LpNotificationBell.vue.d.ts +0 -85
  80. package/dist/components/LpNumberField.vue.d.ts +0 -21
  81. package/dist/components/LpNumberFlow.vue.d.ts +0 -35
  82. package/dist/components/LpOtpInput.vue.d.ts +0 -39
  83. package/dist/components/LpPagination.vue.d.ts +0 -35
  84. package/dist/components/LpPasswordInput.vue.d.ts +0 -36
  85. package/dist/components/LpPhoneInput.vue.d.ts +0 -49
  86. package/dist/components/LpPie.vue.d.ts +0 -196
  87. package/dist/components/LpPopover.vue.d.ts +0 -34
  88. package/dist/components/LpProgress.vue.d.ts +0 -66
  89. package/dist/components/LpRadio.vue.d.ts +0 -18
  90. package/dist/components/LpRadioGroup.vue.d.ts +0 -26
  91. package/dist/components/LpRollingText.vue.d.ts +0 -33
  92. package/dist/components/LpScrollArea.vue.d.ts +0 -28
  93. package/dist/components/LpSection.vue.d.ts +0 -120
  94. package/dist/components/LpSegmented.vue.d.ts +0 -30
  95. package/dist/components/LpSelect.vue.d.ts +0 -47
  96. package/dist/components/LpServiceNode.vue.d.ts +0 -14
  97. package/dist/components/LpShift.vue.d.ts +0 -36
  98. package/dist/components/LpShortcutsDialog.vue.d.ts +0 -24
  99. package/dist/components/LpSidebar.vue.d.ts +0 -146
  100. package/dist/components/LpSidebarNav.vue.d.ts +0 -54
  101. package/dist/components/LpSkeleton.vue.d.ts +0 -16
  102. package/dist/components/LpSlider.vue.d.ts +0 -30
  103. package/dist/components/LpSparkline.vue.d.ts +0 -48
  104. package/dist/components/LpStat.vue.d.ts +0 -69
  105. package/dist/components/LpStepper.vue.d.ts +0 -36
  106. package/dist/components/LpSwitch.vue.d.ts +0 -42
  107. package/dist/components/LpTable.vue.d.ts +0 -124
  108. package/dist/components/LpTableOfContents.vue.d.ts +0 -19
  109. package/dist/components/LpTabs.vue.d.ts +0 -47
  110. package/dist/components/LpTextarea.vue.d.ts +0 -22
  111. package/dist/components/LpThemeSwitcher.vue.d.ts +0 -47
  112. package/dist/components/LpTilt.vue.d.ts +0 -31
  113. package/dist/components/LpTimeField.vue.d.ts +0 -24
  114. package/dist/components/LpToaster.vue.d.ts +0 -3
  115. package/dist/components/LpTooltip.vue.d.ts +0 -58
  116. package/dist/components/LpTopologyCanvas.vue.d.ts +0 -205
  117. package/dist/components/LpUptimeBar.vue.d.ts +0 -46
  118. package/dist/components/LpWaypointEdge.vue.d.ts +0 -21
  119. package/dist/components/actionBar.d.ts +0 -19
  120. package/dist/components/address.d.ts +0 -107
  121. package/dist/components/chart.d.ts +0 -180
  122. package/dist/components/codeHighlight.d.ts +0 -8
  123. package/dist/components/color.d.ts +0 -65
  124. package/dist/components/countries-data.d.ts +0 -2
  125. package/dist/components/countries.d.ts +0 -20
  126. package/dist/components/dropdown.d.ts +0 -29
  127. package/dist/components/fileTree.d.ts +0 -79
  128. package/dist/components/lightbox.d.ts +0 -24
  129. package/dist/components/modalDepth.d.ts +0 -15
  130. package/dist/components/sidebar.d.ts +0 -42
  131. package/dist/composables/easing.d.ts +0 -46
  132. package/dist/composables/useAsyncTask.d.ts +0 -18
  133. package/dist/composables/useClipboard.d.ts +0 -46
  134. package/dist/composables/useFormDraft.d.ts +0 -67
  135. package/dist/composables/useGlass.d.ts +0 -9
  136. package/dist/composables/useHotkeys.d.ts +0 -99
  137. package/dist/composables/useInputFilter.d.ts +0 -14
  138. package/dist/composables/useMergedClass.d.ts +0 -42
  139. package/dist/composables/usePillTransition.d.ts +0 -21
  140. package/dist/composables/useReveal.d.ts +0 -26
  141. package/dist/composables/useRovingFocus.d.ts +0 -49
  142. package/dist/composables/useSettled.d.ts +0 -26
  143. package/dist/composables/useShift.d.ts +0 -35
  144. package/dist/composables/useTilt.d.ts +0 -23
  145. package/dist/composables/useToast.d.ts +0 -41
  146. package/dist/composables/useZoomPan.d.ts +0 -58
  147. package/dist/icons.d.ts +0 -1
  148. package/dist/index.d.ts +0 -160
  149. package/dist/layout/registry.d.ts +0 -26
  150. package/dist/layout/tree.d.ts +0 -75
  151. package/dist/layout/useLayout.d.ts +0 -39
  152. package/dist/theme/backdrop.d.ts +0 -9
  153. package/dist/theme/config.d.ts +0 -16
  154. package/dist/theme/define.d.ts +0 -12
  155. package/dist/theme/presets.d.ts +0 -20
  156. package/dist/theme/tokens.d.ts +0 -75
  157. package/dist/theme/useTheme.d.ts +0 -46
@@ -1,4 +1,4 @@
1
- import { defineComponent, computed, ref, useId, shallowRef, useSlots, watch, nextTick, openBlock, createBlock, unref, withCtx, createVNode, normalizeClass, withModifiers, createTextVNode, createElementVNode, createElementBlock, Fragment, renderList, createCommentVNode, toDisplayString, withDirectives, withKeys, vModelText, resolveDynamicComponent, normalizeStyle, Transition, renderSlot } from "vue";
1
+ import { defineComponent, computed, ref, useId, shallowRef, useSlots, watch, nextTick, onBeforeUnmount, openBlock, createBlock, unref, withCtx, createVNode, normalizeStyle, normalizeClass, withModifiers, createTextVNode, createElementVNode, createElementBlock, Fragment, renderList, createCommentVNode, toDisplayString, withDirectives, withKeys, vModelText, resolveDynamicComponent, Transition, renderSlot } from "vue";
2
2
  import { DialogRoot, DialogPortal, DialogOverlay, DialogContent, DialogTitle, DialogDescription } from "reka-ui";
3
3
  import { _ as _sfc_main$1 } from "../chunks/LpIcon-CCnX5_2j.js";
4
4
  import { _ as _sfc_main$2 } from "../chunks/LpScrollArea-D8xyKXcF.js";
@@ -6,68 +6,66 @@ import { useAsyncTask } from "../composables/useAsyncTask.js";
6
6
  import { useGlass } from "../composables/useGlass.js";
7
7
  import { useClipboard } from "../composables/useClipboard.js";
8
8
  import { useHotkeys } from "../composables/useHotkeys.js";
9
+ import { useModalLayer } from "./modalDepth.js";
10
+ import { parseCommandQuery, rankCommandItems, swapCommandTerms } from "./commandSearch.js";
9
11
  import { _ as _export_sfc } from "../chunks/_plugin-vue_export-helper-1tPrXgE0.js";
10
- import '../assets/LpCommandPalette-DyT6aGdW.css';const _hoisted_1 = { class: "flex shrink-0 items-center gap-2.5 border-b border-line px-4" };
12
+ import '../assets/LpCommandPalette-s_kKuCRf.css';const _hoisted_1 = { class: "flex shrink-0 items-center gap-2.5 border-b border-line px-4" };
11
13
  const _hoisted_2 = ["title", "onClick"];
12
14
  const _hoisted_3 = ["aria-activedescendant", "placeholder", "onKeydown"];
13
- const _hoisted_4 = { class: "flex min-h-0 flex-1" };
14
- const _hoisted_5 = {
15
+ const _hoisted_4 = {
15
16
  key: 0,
16
17
  class: "px-2 py-10 text-center text-sm text-muted"
17
18
  };
18
- const _hoisted_6 = ["aria-labelledby"];
19
- const _hoisted_7 = ["id"];
20
- const _hoisted_8 = { class: "min-w-0 flex-1" };
21
- const _hoisted_9 = { class: "block truncate font-medium" };
22
- const _hoisted_10 = {
19
+ const _hoisted_5 = ["aria-labelledby"];
20
+ const _hoisted_6 = ["id"];
21
+ const _hoisted_7 = { class: "min-w-0 flex-1" };
22
+ const _hoisted_8 = { class: "block truncate font-medium" };
23
+ const _hoisted_9 = {
23
24
  key: 0,
24
25
  class: "rounded-xs bg-brand/25 text-ink"
25
26
  };
26
- const _hoisted_11 = {
27
+ const _hoisted_10 = {
27
28
  key: 0,
28
29
  class: "mt-0.5 block truncate text-xs text-muted"
29
30
  };
30
- const _hoisted_12 = {
31
+ const _hoisted_11 = {
31
32
  key: 0,
32
33
  class: "rounded-xs bg-brand/20 text-ink"
33
34
  };
34
- const _hoisted_13 = {
35
+ const _hoisted_12 = {
35
36
  key: 0,
36
37
  class: "rounded-xs bg-brand/20 text-ink"
37
38
  };
38
- const _hoisted_14 = {
39
+ const _hoisted_13 = {
39
40
  key: 1,
40
41
  class: "shrink-0 text-xs text-muted"
41
42
  };
42
- const _hoisted_15 = {
43
+ const _hoisted_14 = {
43
44
  key: 0,
44
45
  class: "lp-cmd-pane hidden min-h-0 shrink-0 flex-col border-l border-line md:flex"
45
46
  };
46
- const _hoisted_16 = { class: "lp-cmd-para flex items-center gap-2 text-ink" };
47
- const _hoisted_17 = { class: "min-w-0 text-base font-semibold" };
48
- const _hoisted_18 = {
47
+ const _hoisted_15 = { class: "lp-cmd-para flex items-center gap-2 text-ink" };
48
+ const _hoisted_16 = { class: "min-w-0 text-base font-semibold" };
49
+ const _hoisted_17 = {
49
50
  key: 0,
50
51
  class: "lp-cmd-para mt-0.5 text-xs text-muted"
51
52
  };
52
- const _hoisted_19 = {
53
+ const _hoisted_18 = {
53
54
  key: 0,
54
55
  class: "rounded-xs bg-brand/25 text-ink"
55
56
  };
56
- const _hoisted_20 = { class: "flex shrink-0 items-center gap-4 border-t border-line px-4 py-2.5 text-[11px] text-muted" };
57
+ const _hoisted_19 = { class: "flex shrink-0 items-center gap-4 border-t border-line px-4 py-2.5 text-[11px] text-muted" };
58
+ const _hoisted_20 = { class: "flex items-center gap-1" };
57
59
  const _hoisted_21 = { class: "flex items-center gap-1" };
58
- const _hoisted_22 = { class: "flex items-center gap-1" };
59
- const _hoisted_23 = {
60
+ const _hoisted_22 = {
60
61
  key: 0,
61
62
  class: "flex items-center gap-1"
62
63
  };
63
- const _hoisted_24 = {
64
+ const _hoisted_23 = {
64
65
  key: 1,
65
66
  class: "flex items-center gap-1"
66
67
  };
67
- const _hoisted_25 = { class: "ml-auto flex items-center gap-1" };
68
- const LATIN = "qwertyuiop[]asdfghjkl;'zxcvbnm,.`";
69
- const CYRILLIC = "йцукенгшщзхъфывапролджэячсмитьбюё";
70
- const TYPO_MIN = 5;
68
+ const _hoisted_24 = { class: "ml-auto flex items-center gap-1" };
71
69
  const STAGGER_MS = 45;
72
70
  const STAGGER_MAX = 10;
73
71
  const _sfc_main = /* @__PURE__ */ defineComponent({
@@ -96,6 +94,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
96
94
  setup(__props, { emit: __emit }) {
97
95
  const props = __props;
98
96
  const frosted = useGlass(() => props.glass);
97
+ const { claim, release, layer } = useModalLayer();
99
98
  const DEFAULT_LABELS = {
100
99
  navigate: "navigate",
101
100
  select: "select",
@@ -120,9 +119,11 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
120
119
  }
121
120
  const activeId = computed(() => flat.value.length ? optionId(selectedIndex.value) : void 0);
122
121
  const selectedIndex = ref(0);
122
+ const selectedId = ref(null);
123
123
  const inputRef = ref(null);
124
124
  const scrollRef = ref(null);
125
125
  const trail = shallowRef([]);
126
+ const trailState = shallowRef([]);
126
127
  const mode = computed(() => trail.value[trail.value.length - 1] ?? null);
127
128
  const modeItems = shallowRef([]);
128
129
  const { copy } = useClipboard();
@@ -150,30 +151,37 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
150
151
  }
151
152
  const selectedActions = computed(() => actionsOf(flat.value[selectedIndex.value]));
152
153
  function onTab(event) {
154
+ event.preventDefault();
155
+ event.stopPropagation();
153
156
  if (event.shiftKey) return;
154
157
  const c = flat.value[selectedIndex.value];
155
158
  const actions = selectedActions.value;
156
159
  if (!c || !actions.length) return;
157
- event.preventDefault();
158
- event.stopPropagation();
159
160
  enter({ id: `${c.id}:actions`, label: c.label, icon: c.icon, children: actions });
160
161
  }
161
162
  function enter(c) {
163
+ trailState.value = [...trailState.value, { query: query.value, selectedId: selectedId.value }];
162
164
  trail.value = [...trail.value, c];
163
165
  query.value = "";
164
- selectedIndex.value = 0;
166
+ select(0);
165
167
  modeItems.value = Array.isArray(c.children) ? c.children : [];
166
168
  refresh();
167
169
  inputRef.value?.focus();
168
170
  }
169
171
  function popTo(depth) {
172
+ const state = trailState.value[depth] || { query: "", selectedId: null };
170
173
  const next = trail.value.slice(0, Math.max(0, depth));
174
+ trailState.value = trailState.value.slice(0, Math.max(0, depth));
171
175
  trail.value = next;
172
- query.value = "";
173
- selectedIndex.value = 0;
174
176
  const parent = next[next.length - 1];
175
177
  modeItems.value = parent && Array.isArray(parent.children) ? parent.children : [];
178
+ query.value = state.query;
179
+ select(0);
176
180
  refresh();
181
+ void nextTick(() => {
182
+ const index = state.selectedId ? flat.value.findIndex((c) => c.id === state.selectedId) : -1;
183
+ select(index >= 0 ? index : 0);
184
+ });
177
185
  inputRef.value?.focus();
178
186
  }
179
187
  function back() {
@@ -214,51 +222,15 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
214
222
  });
215
223
  }
216
224
  const source = computed(() => mode.value ? modeItems.value : props.commands);
217
- const SWAP = /* @__PURE__ */ new Map();
218
- for (let i = 0; i < LATIN.length; i++) {
219
- SWAP.set(LATIN[i], CYRILLIC[i]);
220
- SWAP.set(CYRILLIC[i], LATIN[i]);
221
- }
222
- function swapLayout(term) {
223
- return [...term].map((ch) => SWAP.get(ch) ?? ch).join("");
224
- }
225
- function withinOne(a, b) {
226
- if (Math.abs(a.length - b.length) > 1) return false;
227
- let i = 0;
228
- while (i < a.length && i < b.length && a[i] === b[i]) i++;
229
- if (i === a.length || i === b.length) return true;
230
- const rest = (x, y) => a.slice(i + x) === b.slice(i + y);
231
- return rest(1, 1) || rest(1, 0) || rest(0, 1) || a[i] === b[i + 1] && a[i + 1] === b[i] && rest(2, 2);
232
- }
233
- function nearWord(term, label) {
234
- if (term.length < TYPO_MIN) return false;
235
- return label.split(/[^\p{L}\p{N}]+/u).some((word) => withinOne(term, word) || word.length > term.length && withinOne(term, word.slice(0, term.length)));
236
- }
237
- function score(c, terms) {
238
- const label = c.label.toLowerCase();
239
- const keywords = (c.keywords ?? []).map((k) => k.toLowerCase());
240
- const description = c.description?.toLowerCase() ?? "";
241
- let total = 0;
242
- for (const term of terms) {
243
- let hit = (label.includes(term) ? 4 : 0) + (keywords.some((k) => k.includes(term)) ? 3 : 0) + (description.includes(term) ? 2 : 0);
244
- if (!hit && nearWord(term, label)) hit = 1;
245
- if (!hit) return 0;
246
- total += hit;
247
- }
248
- return total;
249
- }
250
- function rank(items, terms) {
251
- return items.map((c) => ({ c, score: score(c, terms) })).filter((e) => e.score > 0).sort((a, b) => b.score - a.score || a.c.label.localeCompare(b.c.label)).map((e) => e.c);
252
- }
253
- const typedTerms = computed(() => query.value.trim().toLowerCase().split(/\s+/).filter(Boolean));
254
225
  const local = computed(() => {
255
- const terms = typedTerms.value;
256
- if (!terms.length) return { items: source.value.filter((c) => !c.hidden), terms };
257
- const items = rank(source.value, terms);
258
- if (items.length || !props.layoutFallback) return { items, terms };
259
- const swapped = terms.map(swapLayout);
260
- const other = rank(source.value, swapped);
261
- return other.length ? { items: other, terms: swapped } : { items, terms };
226
+ const terms = parseCommandQuery(query.value);
227
+ const filtered = query.value.trim() ? source.value : source.value.filter((c) => !c.hidden);
228
+ if (!terms.include.length && !terms.exclude.length && !terms.groups.length) return { items: filtered, terms: [] };
229
+ const items = rankCommandItems(filtered, terms);
230
+ if (items.length || !props.layoutFallback) return { items, terms: terms.include };
231
+ const swapped = swapCommandTerms(terms);
232
+ const other = rankCommandItems(filtered, swapped);
233
+ return other.length ? { items: other, terms: swapped.include } : { items, terms: terms.include };
262
234
  });
263
235
  const ranked = computed(() => local.value.items);
264
236
  const fetched = computed(() => {
@@ -364,16 +336,17 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
364
336
  return parts;
365
337
  }
366
338
  watch(query, () => {
367
- selectedIndex.value = 0;
339
+ select(0);
368
340
  refresh();
369
341
  });
370
342
  watch([query, trail, () => props.open], () => {
371
343
  expanded.value = /* @__PURE__ */ new Set();
372
344
  });
373
345
  watch(
374
- () => flat.value.length,
375
- (len) => {
376
- if (selectedIndex.value >= len) selectedIndex.value = Math.max(0, len - 1);
346
+ () => flat.value.map((c) => c.id).join("|"),
347
+ () => {
348
+ const index = selectedId.value ? flat.value.findIndex((c) => c.id === selectedId.value) : -1;
349
+ select(index >= 0 ? index : 0);
377
350
  }
378
351
  );
379
352
  watch([selectedIndex, () => flat.value.map((c) => c.id).join("|")], async () => {
@@ -386,13 +359,40 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
386
359
  );
387
360
  el?.scrollIntoView({ block: "nearest" });
388
361
  }
362
+ const keyboardSelection = ref(false);
363
+ function select(index, keyboard = false) {
364
+ const len = flat.value.length;
365
+ selectedIndex.value = len ? Math.max(0, Math.min(index, len - 1)) : 0;
366
+ selectedId.value = flat.value[selectedIndex.value]?.id ?? null;
367
+ if (keyboard) keyboardSelection.value = true;
368
+ }
389
369
  function moveDown() {
390
370
  const len = flat.value.length;
391
- if (len) selectedIndex.value = (selectedIndex.value + 1) % len;
371
+ if (len) select((selectedIndex.value + 1) % len, true);
392
372
  }
393
373
  function moveUp() {
394
374
  const len = flat.value.length;
395
- if (len) selectedIndex.value = (selectedIndex.value - 1 + len) % len;
375
+ if (len) select((selectedIndex.value - 1 + len) % len, true);
376
+ }
377
+ function movePage(direction) {
378
+ select(selectedIndex.value + direction * 8, true);
379
+ }
380
+ function onPaletteKeydown(event) {
381
+ if (event.isComposing) return;
382
+ if (!["ArrowDown", "ArrowUp", "Home", "End", "PageDown", "PageUp"].includes(event.key)) return;
383
+ event.preventDefault();
384
+ event.stopPropagation();
385
+ if (event.key === "ArrowDown") moveDown();
386
+ else if (event.key === "ArrowUp") moveUp();
387
+ else if (event.key === "Home") select(0, true);
388
+ else if (event.key === "End") select(flat.value.length - 1, true);
389
+ else movePage(event.key === "PageDown" ? 1 : -1);
390
+ }
391
+ function onPointerMove() {
392
+ keyboardSelection.value = false;
393
+ }
394
+ function onPointerEnter(c) {
395
+ if (!keyboardSelection.value) select(flatIndexOf(c));
396
396
  }
397
397
  function runSelected(event) {
398
398
  const c = flat.value[selectedIndex.value];
@@ -431,7 +431,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
431
431
  emit("run", c.id, c);
432
432
  if (c.keepOpen) {
433
433
  query.value = "";
434
- selectedIndex.value = 0;
434
+ select(0);
435
435
  inputRef.value?.focus();
436
436
  return;
437
437
  }
@@ -450,10 +450,14 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
450
450
  watch(
451
451
  () => props.open,
452
452
  async (o) => {
453
+ if (o) claim();
454
+ else release();
453
455
  cancel();
454
456
  query.value = "";
455
- selectedIndex.value = 0;
457
+ select(0);
458
+ selectedId.value = null;
456
459
  trail.value = [];
460
+ trailState.value = [];
457
461
  modeItems.value = [];
458
462
  found.value = [];
459
463
  failed.value = false;
@@ -464,6 +468,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
464
468
  },
465
469
  { immediate: true }
466
470
  );
471
+ onBeforeUnmount(release);
467
472
  useHotkeys(
468
473
  () => props.hotkey ? [
469
474
  {
@@ -484,13 +489,16 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
484
489
  createVNode(unref(DialogPortal), null, {
485
490
  default: withCtx(() => [
486
491
  createVNode(unref(DialogOverlay), {
487
- class: normalizeClass([{ "lp-scrim--light": unref(frosted) }, "lp-scrim fixed inset-0 z-(--z-overlay) data-[state=open]:animate-[fade-in_150ms_ease] data-[state=closed]:animate-[fade-out_130ms_ease]"])
488
- }, null, 8, ["class"]),
492
+ class: normalizeClass([{ "lp-scrim--light": unref(frosted), "lp-scrim--nested": unref(layer).nested }, "lp-scrim fixed inset-0 data-[state=open]:animate-[fade-in_150ms_ease] data-[state=closed]:animate-[fade-out_130ms_ease]"]),
493
+ style: normalizeStyle({ zIndex: unref(layer).scrim })
494
+ }, null, 8, ["class", "style"]),
489
495
  createVNode(unref(DialogContent), {
490
- class: normalizeClass(["lp-cmd-dialog fixed left-1/2 top-[12vh] z-(--z-modal) flex max-h-[76vh] -translate-x-1/2 flex-col overflow-hidden rounded-card border border-line shadow-panel outline-none data-[state=open]:animate-[pop-in_160ms_var(--ease-emphasized)] data-[state=closed]:animate-[pop-out_130ms_ease]", [unref(frosted) ? "lp-glass-overlay" : "bg-surface-raised", __props.previewPane && "lp-cmd-split"]]),
496
+ class: normalizeClass(["lp-cmd-dialog fixed left-1/2 top-[12vh] flex max-h-[76vh] -translate-x-1/2 flex-col overflow-hidden rounded-card border border-line shadow-panel outline-none data-[state=open]:animate-[pop-in_160ms_var(--ease-emphasized)] data-[state=closed]:animate-[pop-out_130ms_ease]", [unref(frosted) ? unref(layer).nested ? "lp-glass-overlay--nested" : "lp-glass-overlay" : "bg-surface-raised", __props.previewPane && "lp-cmd-split"]]),
497
+ style: normalizeStyle({ zIndex: unref(layer).panel }),
491
498
  "data-pane": paneOpen.value ? "open" : void 0,
492
499
  onOpenAutoFocus: _cache[2] || (_cache[2] = withModifiers(() => {
493
- }, ["prevent"]))
500
+ }, ["prevent"])),
501
+ onKeydownCapture: onPaletteKeydown
494
502
  }, {
495
503
  default: withCtx(() => [
496
504
  createVNode(unref(DialogTitle), { class: "sr-only" }, {
@@ -551,8 +559,6 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
551
559
  placeholder: mode.value?.childPlaceholder ?? __props.placeholder,
552
560
  class: "h-12 min-w-0 flex-1 bg-transparent text-sm text-ink outline-none placeholder:text-muted",
553
561
  onKeydown: [
554
- withKeys(withModifiers(moveDown, ["prevent"]), ["down"]),
555
- withKeys(withModifiers(moveUp, ["prevent"]), ["up"]),
556
562
  withKeys(withModifiers(runSelected, ["prevent"]), ["enter"]),
557
563
  withKeys(onBackspace, ["backspace"]),
558
564
  withKeys(onEscape, ["esc"]),
@@ -563,7 +569,10 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
563
569
  ]),
564
570
  _cache[6] || (_cache[6] = createElementVNode("kbd", { class: "shrink-0 rounded border border-line px-1.5 py-0.5 text-[10px] text-muted" }, "esc", -1))
565
571
  ]),
566
- createElementVNode("div", _hoisted_4, [
572
+ createElementVNode("div", {
573
+ class: "flex min-h-0 flex-1",
574
+ onPointermove: onPointerMove
575
+ }, [
567
576
  createVNode(_sfc_main$2, {
568
577
  ref_key: "scrollRef",
569
578
  ref: scrollRef,
@@ -571,7 +580,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
571
580
  "content-class": "p-2"
572
581
  }, {
573
582
  default: withCtx(() => [
574
- flat.value.length === 0 && !failed.value ? (openBlock(), createElementBlock("p", _hoisted_5, toDisplayString(unref(searching) ? text.value.searching : __props.emptyText), 1)) : createCommentVNode("", true),
583
+ flat.value.length === 0 && !failed.value ? (openBlock(), createElementBlock("p", _hoisted_4, toDisplayString(unref(searching) ? text.value.searching : __props.emptyText), 1)) : createCommentVNode("", true),
575
584
  createElementVNode("div", {
576
585
  id: listId,
577
586
  role: "listbox"
@@ -586,7 +595,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
586
595
  key: 0,
587
596
  id: `${listId}-g${gi}`,
588
597
  class: "px-2 pb-1 pt-3 text-[11px] font-semibold uppercase tracking-[0.08em] text-muted"
589
- }, toDisplayString(group.name), 9, _hoisted_7)) : createCommentVNode("", true),
598
+ }, toDisplayString(group.name), 9, _hoisted_6)) : createCommentVNode("", true),
590
599
  (openBlock(true), createElementBlock(Fragment, null, renderList(group.items, (c) => {
591
600
  return openBlock(), createBlock(resolveDynamicComponent(c.href ? "a" : "button"), {
592
601
  id: optionId(flatIndexOf(c)),
@@ -604,7 +613,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
604
613
  flatIndexOf(c) === selectedIndex.value ? "bg-brand-soft text-brand" : unref(moreOf).has(c) ? "text-muted hover:bg-surface-soft/60" : "text-ink hover:bg-surface-soft/60"
605
614
  ]]),
606
615
  onClick: ($event) => onRowClick($event, c),
607
- onPointerenter: ($event) => selectedIndex.value = flatIndexOf(c)
616
+ onPointerenter: ($event) => onPointerEnter(c)
608
617
  }, {
609
618
  default: withCtx(() => [
610
619
  c.icon ? (openBlock(), createBlock(_sfc_main$1, {
@@ -613,24 +622,24 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
613
622
  size: 16,
614
623
  class: normalizeClass(["shrink-0", { "mt-0.5": c.excerpt }])
615
624
  }, null, 8, ["name", "class"])) : createCommentVNode("", true),
616
- createElementVNode("span", _hoisted_8, [
617
- createElementVNode("span", _hoisted_9, [
625
+ createElementVNode("span", _hoisted_7, [
626
+ createElementVNode("span", _hoisted_8, [
618
627
  (openBlock(true), createElementBlock(Fragment, null, renderList(highlight(c.label, c.highlight), (p, pi) => {
619
628
  return openBlock(), createElementBlock(Fragment, {
620
629
  key: `l${pi}`
621
630
  }, [
622
- p.hit ? (openBlock(), createElementBlock("mark", _hoisted_10, toDisplayString(p.text), 1)) : (openBlock(), createElementBlock(Fragment, { key: 1 }, [
631
+ p.hit ? (openBlock(), createElementBlock("mark", _hoisted_9, toDisplayString(p.text), 1)) : (openBlock(), createElementBlock(Fragment, { key: 1 }, [
623
632
  createTextVNode(toDisplayString(p.text), 1)
624
633
  ], 64))
625
634
  ], 64);
626
635
  }), 128))
627
636
  ]),
628
- c.description ? (openBlock(), createElementBlock("span", _hoisted_11, [
637
+ c.description ? (openBlock(), createElementBlock("span", _hoisted_10, [
629
638
  (openBlock(true), createElementBlock(Fragment, null, renderList(highlight(c.description, c.highlight), (p, pi) => {
630
639
  return openBlock(), createElementBlock(Fragment, {
631
640
  key: `d${pi}`
632
641
  }, [
633
- p.hit ? (openBlock(), createElementBlock("mark", _hoisted_12, toDisplayString(p.text), 1)) : (openBlock(), createElementBlock(Fragment, { key: 1 }, [
642
+ p.hit ? (openBlock(), createElementBlock("mark", _hoisted_11, toDisplayString(p.text), 1)) : (openBlock(), createElementBlock(Fragment, { key: 1 }, [
634
643
  createTextVNode(toDisplayString(p.text), 1)
635
644
  ], 64))
636
645
  ], 64);
@@ -645,14 +654,14 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
645
654
  return openBlock(), createElementBlock(Fragment, {
646
655
  key: `e${pi}`
647
656
  }, [
648
- p.hit ? (openBlock(), createElementBlock("mark", _hoisted_13, toDisplayString(p.text), 1)) : (openBlock(), createElementBlock(Fragment, { key: 1 }, [
657
+ p.hit ? (openBlock(), createElementBlock("mark", _hoisted_12, toDisplayString(p.text), 1)) : (openBlock(), createElementBlock(Fragment, { key: 1 }, [
649
658
  createTextVNode(toDisplayString(p.text), 1)
650
659
  ], 64))
651
660
  ], 64);
652
661
  }), 128))
653
662
  ], 4)) : createCommentVNode("", true)
654
663
  ]),
655
- c.shortcut ? (openBlock(), createElementBlock("kbd", _hoisted_14, toDisplayString(c.shortcut), 1)) : c.children ? (openBlock(), createBlock(_sfc_main$1, {
664
+ c.shortcut ? (openBlock(), createElementBlock("kbd", _hoisted_13, toDisplayString(c.shortcut), 1)) : c.children ? (openBlock(), createBlock(_sfc_main$1, {
656
665
  key: 2,
657
666
  name: "lucide:chevron-right",
658
667
  size: 14,
@@ -662,7 +671,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
662
671
  _: 2
663
672
  }, 1064, ["id", "href", "type", "aria-selected", "aria-disabled", "data-cmd-index", "disabled", "class", "onClick", "onPointerenter"]);
664
673
  }), 128))
665
- ], 8, _hoisted_6);
674
+ ], 8, _hoisted_5);
666
675
  }), 128))
667
676
  ]),
668
677
  failed.value ? (openBlock(), createElementBlock("div", {
@@ -690,7 +699,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
690
699
  }, 512),
691
700
  createVNode(Transition, { name: "lp-cmd-pane" }, {
692
701
  default: withCtx(() => [
693
- paneOpen.value ? (openBlock(), createElementBlock("aside", _hoisted_15, [
702
+ paneOpen.value ? (openBlock(), createElementBlock("aside", _hoisted_14, [
694
703
  createVNode(_sfc_main$2, {
695
704
  ref_key: "previewRef",
696
705
  ref: previewRef,
@@ -702,16 +711,16 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
702
711
  key: active.value.id
703
712
  }, [
704
713
  renderSlot(_ctx.$slots, "preview", { command: active.value }, () => [
705
- createElementVNode("div", _hoisted_16, [
714
+ createElementVNode("div", _hoisted_15, [
706
715
  active.value.icon ? (openBlock(), createBlock(_sfc_main$1, {
707
716
  key: 0,
708
717
  name: active.value.icon,
709
718
  size: 16,
710
719
  class: "shrink-0 text-muted"
711
720
  }, null, 8, ["name"])) : createCommentVNode("", true),
712
- createElementVNode("h3", _hoisted_17, toDisplayString(active.value.label), 1)
721
+ createElementVNode("h3", _hoisted_16, toDisplayString(active.value.label), 1)
713
722
  ]),
714
- active.value.description ? (openBlock(), createElementBlock("p", _hoisted_18, toDisplayString(active.value.description), 1)) : createCommentVNode("", true),
723
+ active.value.description ? (openBlock(), createElementBlock("p", _hoisted_17, toDisplayString(active.value.description), 1)) : createCommentVNode("", true),
715
724
  (openBlock(true), createElementBlock(Fragment, null, renderList(paragraphs.value, (para, i) => {
716
725
  return openBlock(), createElementBlock("p", {
717
726
  key: i,
@@ -722,7 +731,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
722
731
  return openBlock(), createElementBlock(Fragment, {
723
732
  key: `p${pi}`
724
733
  }, [
725
- p.hit ? (openBlock(), createElementBlock("mark", _hoisted_19, toDisplayString(p.text), 1)) : (openBlock(), createElementBlock(Fragment, { key: 1 }, [
734
+ p.hit ? (openBlock(), createElementBlock("mark", _hoisted_18, toDisplayString(p.text), 1)) : (openBlock(), createElementBlock(Fragment, { key: 1 }, [
726
735
  createTextVNode(toDisplayString(p.text), 1)
727
736
  ], 64))
728
737
  ], 64);
@@ -738,33 +747,33 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
738
747
  ]),
739
748
  _: 3
740
749
  })
741
- ]),
742
- createElementVNode("div", _hoisted_20, [
743
- createElementVNode("span", _hoisted_21, [
750
+ ], 32),
751
+ createElementVNode("div", _hoisted_19, [
752
+ createElementVNode("span", _hoisted_20, [
744
753
  _cache[7] || (_cache[7] = createElementVNode("kbd", { class: "rounded border border-line px-1 text-[10px]" }, "↑", -1)),
745
754
  _cache[8] || (_cache[8] = createElementVNode("kbd", { class: "rounded border border-line px-1 text-[10px]" }, "↓", -1)),
746
755
  createTextVNode(" " + toDisplayString(text.value.navigate), 1)
747
756
  ]),
748
- createElementVNode("span", _hoisted_22, [
757
+ createElementVNode("span", _hoisted_21, [
749
758
  _cache[9] || (_cache[9] = createElementVNode("kbd", { class: "rounded border border-line px-1 text-[10px]" }, "↵", -1)),
750
759
  createTextVNode(" " + toDisplayString(text.value.select), 1)
751
760
  ]),
752
- selectedActions.value.length ? (openBlock(), createElementBlock("span", _hoisted_23, [
761
+ selectedActions.value.length ? (openBlock(), createElementBlock("span", _hoisted_22, [
753
762
  _cache[10] || (_cache[10] = createElementVNode("kbd", { class: "rounded border border-line px-1 text-[10px]" }, "tab", -1)),
754
763
  createTextVNode(" " + toDisplayString(text.value.actions), 1)
755
764
  ])) : createCommentVNode("", true),
756
- trail.value.length ? (openBlock(), createElementBlock("span", _hoisted_24, [
765
+ trail.value.length ? (openBlock(), createElementBlock("span", _hoisted_23, [
757
766
  _cache[11] || (_cache[11] = createElementVNode("kbd", { class: "rounded border border-line px-1 text-[10px]" }, "⌫", -1)),
758
767
  createTextVNode(" " + toDisplayString(text.value.back), 1)
759
768
  ])) : createCommentVNode("", true),
760
- createElementVNode("span", _hoisted_25, [
769
+ createElementVNode("span", _hoisted_24, [
761
770
  _cache[12] || (_cache[12] = createElementVNode("kbd", { class: "rounded border border-line px-1 text-[10px]" }, "esc", -1)),
762
771
  createTextVNode(" " + toDisplayString(text.value.close), 1)
763
772
  ])
764
773
  ])
765
774
  ]),
766
775
  _: 3
767
- }, 8, ["class", "data-pane"])
776
+ }, 8, ["class", "style", "data-pane"])
768
777
  ]),
769
778
  _: 3
770
779
  })
@@ -774,7 +783,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
774
783
  };
775
784
  }
776
785
  });
777
- const LpCommandPalette = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-19283172"]]);
786
+ const LpCommandPalette = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-10500f32"]]);
778
787
  export {
779
788
  LpCommandPalette as default
780
789
  };
@@ -1,4 +1,4 @@
1
- import { _ as _sfc_main } from "../chunks/LpConfirmDialog-BNAvOR24.js";
1
+ import { _ as _sfc_main } from "../chunks/LpConfirmDialog-Q-bxff8z.js";
2
2
  export {
3
3
  _sfc_main as default
4
4
  };
@@ -1,4 +1,4 @@
1
- import { _ as _sfc_main } from "../chunks/LpDrawer-DgaS2s2i.js";
1
+ import { _ as _sfc_main } from "../chunks/LpDrawer-BZ6k3hvo.js";
2
2
  export {
3
3
  _sfc_main as default
4
4
  };
@@ -1,4 +1,4 @@
1
- import { _ as _sfc_main } from "../chunks/LpLightbox-oLqyjOln.js";
1
+ import { _ as _sfc_main } from "../chunks/LpLightbox-2sYVMY-S.js";
2
2
  export {
3
3
  _sfc_main as default
4
4
  };
@@ -1,4 +1,4 @@
1
- import { _ as _sfc_main } from "../chunks/LpMediaGallery-Cid7PGYx.js";
1
+ import { _ as _sfc_main } from "../chunks/LpMediaGallery-FF-NquIo.js";
2
2
  export {
3
3
  _sfc_main as default
4
4
  };
@@ -1,4 +1,4 @@
1
- import { _ as _sfc_main } from "../chunks/LpModal-8bja5bWS.js";
1
+ import { _ as _sfc_main } from "../chunks/LpModal-Bt0pQCI_.js";
2
2
  export {
3
3
  _sfc_main as default
4
4
  };
@@ -1,4 +1,4 @@
1
- import { _ as _sfc_main } from "../chunks/LpModalNav-w9kfwHqO.js";
1
+ import { _ as _sfc_main } from "../chunks/LpModalNav-YaifHrXC.js";
2
2
  export {
3
3
  _sfc_main as default
4
4
  };
@@ -1,5 +1,5 @@
1
1
  import { defineComponent, computed, openBlock, createBlock, withCtx, createElementVNode, createElementBlock, Fragment, renderList, toDisplayString, unref } from "vue";
2
- import { _ as _sfc_main$1 } from "../chunks/LpModal-8bja5bWS.js";
2
+ import { _ as _sfc_main$1 } from "../chunks/LpModal-Bt0pQCI_.js";
3
3
  import { mergeShortcutGroups, activeShortcuts, appleModifierLabel } from "../composables/useHotkeys.js";
4
4
  import { _ as _export_sfc } from "../chunks/_plugin-vue_export-helper-1tPrXgE0.js";
5
5
  import '../assets/LpShortcutsDialog-C6YoQ8_M.css';const _hoisted_1 = { class: "shortcut-groups" };
@@ -1,4 +1,4 @@
1
- import { _ as _sfc_main } from "../chunks/LpSidebar-DlTn5nXc.js";
1
+ import { _ as _sfc_main } from "../chunks/LpSidebar-ClBUwoEz.js";
2
2
  export {
3
3
  _sfc_main as default
4
4
  };