@leavepulse/ui 0.37.11 → 0.38.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/assets/LpCommandPalette-BV6-oPGZ.css +21 -0
- package/dist/components/LpCommandPalette.vue.d.ts +87 -1
- package/dist/components/LpCommandPalette.vue.js +412 -122
- package/package.json +1 -1
- package/src/components/LpCommandPalette.vue +498 -76
- package/src/tokens/tokens.css +21 -0
- package/dist/assets/LpCommandPalette-B-g1fa8r.css +0 -16
|
@@ -1,48 +1,80 @@
|
|
|
1
|
-
import { defineComponent, computed, ref, shallowRef, watch, nextTick, openBlock, createBlock, unref, withCtx, createVNode, withModifiers, createTextVNode, createElementVNode, createElementBlock, Fragment, renderList, createCommentVNode, toDisplayString, withDirectives, withKeys, vModelText,
|
|
1
|
+
import { defineComponent, computed, ref, useId, shallowRef, watch, nextTick, openBlock, createBlock, unref, withCtx, createVNode, withModifiers, normalizeClass, createTextVNode, createElementVNode, createElementBlock, Fragment, renderList, createCommentVNode, toDisplayString, withDirectives, withKeys, vModelText, resolveDynamicComponent, normalizeStyle, 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";
|
|
5
5
|
import { useAsyncTask } from "../composables/useAsyncTask.js";
|
|
6
|
+
import { useClipboard } from "../composables/useClipboard.js";
|
|
6
7
|
import { useHotkeys } from "../composables/useHotkeys.js";
|
|
7
8
|
import { _ as _export_sfc } from "../chunks/_plugin-vue_export-helper-1tPrXgE0.js";
|
|
8
|
-
import '../assets/LpCommandPalette-
|
|
9
|
+
import '../assets/LpCommandPalette-BV6-oPGZ.css';const _hoisted_1 = { class: "flex shrink-0 items-center gap-2.5 border-b border-line px-4" };
|
|
9
10
|
const _hoisted_2 = ["title", "onClick"];
|
|
10
|
-
const _hoisted_3 = ["placeholder", "onKeydown"];
|
|
11
|
-
const _hoisted_4 = {
|
|
12
|
-
key: 0,
|
|
13
|
-
class: "px-2 py-10 text-center text-sm text-muted"
|
|
14
|
-
};
|
|
11
|
+
const _hoisted_3 = ["aria-activedescendant", "placeholder", "onKeydown"];
|
|
12
|
+
const _hoisted_4 = { class: "flex min-h-0 flex-1" };
|
|
15
13
|
const _hoisted_5 = {
|
|
16
14
|
key: 0,
|
|
17
|
-
class: "px-2
|
|
15
|
+
class: "px-2 py-10 text-center text-sm text-muted"
|
|
18
16
|
};
|
|
19
|
-
const _hoisted_6 = ["
|
|
20
|
-
const _hoisted_7 =
|
|
21
|
-
const _hoisted_8 = { class: "
|
|
22
|
-
const _hoisted_9 = {
|
|
17
|
+
const _hoisted_6 = ["aria-labelledby"];
|
|
18
|
+
const _hoisted_7 = ["id"];
|
|
19
|
+
const _hoisted_8 = { class: "min-w-0 flex-1" };
|
|
20
|
+
const _hoisted_9 = { class: "block truncate font-medium" };
|
|
21
|
+
const _hoisted_10 = {
|
|
23
22
|
key: 0,
|
|
24
23
|
class: "rounded-xs bg-brand/25 text-ink"
|
|
25
24
|
};
|
|
26
|
-
const
|
|
25
|
+
const _hoisted_11 = {
|
|
27
26
|
key: 0,
|
|
28
27
|
class: "mt-0.5 block truncate text-xs text-muted"
|
|
29
28
|
};
|
|
30
|
-
const
|
|
29
|
+
const _hoisted_12 = {
|
|
31
30
|
key: 0,
|
|
32
31
|
class: "rounded-xs bg-brand/20 text-ink"
|
|
33
32
|
};
|
|
34
|
-
const
|
|
33
|
+
const _hoisted_13 = {
|
|
34
|
+
key: 0,
|
|
35
|
+
class: "rounded-xs bg-brand/20 text-ink"
|
|
36
|
+
};
|
|
37
|
+
const _hoisted_14 = {
|
|
35
38
|
key: 1,
|
|
36
39
|
class: "shrink-0 text-xs text-muted"
|
|
37
40
|
};
|
|
38
|
-
const
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
41
|
+
const _hoisted_15 = {
|
|
42
|
+
key: 0,
|
|
43
|
+
class: "hidden min-h-0 w-[56%] shrink-0 flex-col border-l border-line md:flex"
|
|
44
|
+
};
|
|
45
|
+
const _hoisted_16 = { class: "flex items-center gap-2 text-ink" };
|
|
46
|
+
const _hoisted_17 = { class: "min-w-0 text-base font-semibold" };
|
|
47
|
+
const _hoisted_18 = {
|
|
48
|
+
key: 0,
|
|
49
|
+
class: "mt-0.5 text-xs text-muted"
|
|
50
|
+
};
|
|
51
|
+
const _hoisted_19 = {
|
|
52
|
+
key: 1,
|
|
53
|
+
class: "mt-3 whitespace-pre-line text-sm leading-relaxed text-ink/90"
|
|
54
|
+
};
|
|
55
|
+
const _hoisted_20 = {
|
|
56
|
+
key: 0,
|
|
57
|
+
class: "rounded-xs bg-brand/25 text-ink"
|
|
58
|
+
};
|
|
59
|
+
const _hoisted_21 = {
|
|
60
|
+
key: 2,
|
|
61
|
+
class: "mt-3 text-sm text-muted"
|
|
62
|
+
};
|
|
63
|
+
const _hoisted_22 = { class: "flex shrink-0 items-center gap-4 border-t border-line px-4 py-2.5 text-[11px] text-muted" };
|
|
64
|
+
const _hoisted_23 = { class: "flex items-center gap-1" };
|
|
65
|
+
const _hoisted_24 = { class: "flex items-center gap-1" };
|
|
66
|
+
const _hoisted_25 = {
|
|
42
67
|
key: 0,
|
|
43
68
|
class: "flex items-center gap-1"
|
|
44
69
|
};
|
|
45
|
-
const
|
|
70
|
+
const _hoisted_26 = {
|
|
71
|
+
key: 1,
|
|
72
|
+
class: "flex items-center gap-1"
|
|
73
|
+
};
|
|
74
|
+
const _hoisted_27 = { class: "ml-auto flex items-center gap-1" };
|
|
75
|
+
const LATIN = "qwertyuiop[]asdfghjkl;'zxcvbnm,.`";
|
|
76
|
+
const CYRILLIC = "йцукенгшщзхъфывапролджэячсмитьбюё";
|
|
77
|
+
const TYPO_MIN = 5;
|
|
46
78
|
const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
47
79
|
__name: "LpCommandPalette",
|
|
48
80
|
props: {
|
|
@@ -58,7 +90,11 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
58
90
|
recentLimit: { default: 5 },
|
|
59
91
|
recentLabel: { default: "Recent" },
|
|
60
92
|
resultsLabel: { default: "Results" },
|
|
61
|
-
labels: {}
|
|
93
|
+
labels: {},
|
|
94
|
+
excerptLines: { default: 4 },
|
|
95
|
+
groupLimit: { default: 0 },
|
|
96
|
+
layoutFallback: { type: Boolean, default: true },
|
|
97
|
+
previewPane: { type: Boolean, default: false }
|
|
62
98
|
},
|
|
63
99
|
emits: ["update:open", "select", "run"],
|
|
64
100
|
setup(__props, { emit: __emit }) {
|
|
@@ -68,17 +104,63 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
68
104
|
select: "select",
|
|
69
105
|
close: "close",
|
|
70
106
|
back: "back",
|
|
71
|
-
searching: "Searching…"
|
|
107
|
+
searching: "Searching…",
|
|
108
|
+
searchFailed: "Search is unavailable right now.",
|
|
109
|
+
retry: "Retry",
|
|
110
|
+
showMore: "Show {count} more",
|
|
111
|
+
actions: "actions",
|
|
112
|
+
openInNewTab: "Open in new tab",
|
|
113
|
+
copyLink: "Copy link",
|
|
114
|
+
linkCopied: "Link copied",
|
|
115
|
+
noPreview: "No preview"
|
|
72
116
|
};
|
|
73
117
|
const text = computed(() => ({ ...DEFAULT_LABELS, ...props.labels }));
|
|
74
118
|
const emit = __emit;
|
|
75
119
|
const query = ref("");
|
|
120
|
+
const listId = `lp-cmd-${useId()}`;
|
|
121
|
+
function optionId(index) {
|
|
122
|
+
return `${listId}-${index}`;
|
|
123
|
+
}
|
|
124
|
+
const activeId = computed(() => flat.value.length ? optionId(selectedIndex.value) : void 0);
|
|
76
125
|
const selectedIndex = ref(0);
|
|
77
126
|
const inputRef = ref(null);
|
|
78
127
|
const scrollRef = ref(null);
|
|
79
128
|
const trail = shallowRef([]);
|
|
80
129
|
const mode = computed(() => trail.value[trail.value.length - 1] ?? null);
|
|
81
130
|
const modeItems = shallowRef([]);
|
|
131
|
+
const { copy } = useClipboard();
|
|
132
|
+
function actionsOf(c) {
|
|
133
|
+
if (!c || c.disabled || moreOf.has(c)) return [];
|
|
134
|
+
const own = c.actions ?? [];
|
|
135
|
+
const href = c.href;
|
|
136
|
+
if (!href) return own;
|
|
137
|
+
const link = new URL(href, window.location.href).href;
|
|
138
|
+
return [
|
|
139
|
+
...own,
|
|
140
|
+
{
|
|
141
|
+
id: `${c.id}:open-in-new-tab`,
|
|
142
|
+
label: text.value.openInNewTab,
|
|
143
|
+
icon: "lucide:external-link",
|
|
144
|
+
onSelect: () => window.open(href, "_blank", "noopener")
|
|
145
|
+
},
|
|
146
|
+
{
|
|
147
|
+
id: `${c.id}:copy-link`,
|
|
148
|
+
label: text.value.copyLink,
|
|
149
|
+
icon: "lucide:link",
|
|
150
|
+
onSelect: () => void copy(link, { toast: text.value.linkCopied || false })
|
|
151
|
+
}
|
|
152
|
+
];
|
|
153
|
+
}
|
|
154
|
+
const selectedActions = computed(() => actionsOf(flat.value[selectedIndex.value]));
|
|
155
|
+
function onTab(event) {
|
|
156
|
+
if (event.shiftKey) return;
|
|
157
|
+
const c = flat.value[selectedIndex.value];
|
|
158
|
+
const actions = selectedActions.value;
|
|
159
|
+
if (!c || !actions.length) return;
|
|
160
|
+
event.preventDefault();
|
|
161
|
+
event.stopPropagation();
|
|
162
|
+
enter({ id: `${c.id}:actions`, label: c.label, icon: c.icon, children: actions });
|
|
163
|
+
}
|
|
82
164
|
function enter(c) {
|
|
83
165
|
trail.value = [...trail.value, c];
|
|
84
166
|
query.value = "";
|
|
@@ -115,9 +197,11 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
115
197
|
function cancel() {
|
|
116
198
|
task.cancel();
|
|
117
199
|
}
|
|
200
|
+
const failed = ref(false);
|
|
118
201
|
function refresh() {
|
|
119
202
|
cancel();
|
|
120
203
|
found.value = [];
|
|
204
|
+
failed.value = false;
|
|
121
205
|
const run2 = fetcher();
|
|
122
206
|
if (!run2) return;
|
|
123
207
|
const q = query.value.trim();
|
|
@@ -126,21 +210,60 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
126
210
|
task.run((signal) => run2(q, signal), {
|
|
127
211
|
delay: props.debounce,
|
|
128
212
|
apply: (hits) => found.value = hits,
|
|
129
|
-
fail: () =>
|
|
213
|
+
fail: () => {
|
|
214
|
+
found.value = [];
|
|
215
|
+
failed.value = true;
|
|
216
|
+
}
|
|
130
217
|
});
|
|
131
218
|
}
|
|
132
219
|
const source = computed(() => mode.value ? modeItems.value : props.commands);
|
|
133
|
-
const
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
220
|
+
const SWAP = /* @__PURE__ */ new Map();
|
|
221
|
+
for (let i = 0; i < LATIN.length; i++) {
|
|
222
|
+
SWAP.set(LATIN[i], CYRILLIC[i]);
|
|
223
|
+
SWAP.set(CYRILLIC[i], LATIN[i]);
|
|
224
|
+
}
|
|
225
|
+
function swapLayout(term) {
|
|
226
|
+
return [...term].map((ch) => SWAP.get(ch) ?? ch).join("");
|
|
227
|
+
}
|
|
228
|
+
function withinOne(a, b) {
|
|
229
|
+
if (Math.abs(a.length - b.length) > 1) return false;
|
|
230
|
+
let i = 0;
|
|
231
|
+
while (i < a.length && i < b.length && a[i] === b[i]) i++;
|
|
232
|
+
if (i === a.length || i === b.length) return true;
|
|
233
|
+
const rest = (x, y) => a.slice(i + x) === b.slice(i + y);
|
|
234
|
+
return rest(1, 1) || rest(1, 0) || rest(0, 1) || a[i] === b[i + 1] && a[i + 1] === b[i] && rest(2, 2);
|
|
235
|
+
}
|
|
236
|
+
function nearWord(term, label) {
|
|
237
|
+
if (term.length < TYPO_MIN) return false;
|
|
238
|
+
return label.split(/[^\p{L}\p{N}]+/u).some((word) => withinOne(term, word) || word.length > term.length && withinOne(term, word.slice(0, term.length)));
|
|
239
|
+
}
|
|
240
|
+
function score(c, terms) {
|
|
241
|
+
const label = c.label.toLowerCase();
|
|
242
|
+
const keywords = (c.keywords ?? []).map((k) => k.toLowerCase());
|
|
243
|
+
const description = c.description?.toLowerCase() ?? "";
|
|
244
|
+
let total = 0;
|
|
245
|
+
for (const term of terms) {
|
|
246
|
+
let hit = (label.includes(term) ? 4 : 0) + (keywords.some((k) => k.includes(term)) ? 3 : 0) + (description.includes(term) ? 2 : 0);
|
|
247
|
+
if (!hit && nearWord(term, label)) hit = 1;
|
|
248
|
+
if (!hit) return 0;
|
|
249
|
+
total += hit;
|
|
250
|
+
}
|
|
251
|
+
return total;
|
|
252
|
+
}
|
|
253
|
+
function rank(items, terms) {
|
|
254
|
+
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);
|
|
255
|
+
}
|
|
256
|
+
const typedTerms = computed(() => query.value.trim().toLowerCase().split(/\s+/).filter(Boolean));
|
|
257
|
+
const local = computed(() => {
|
|
258
|
+
const terms = typedTerms.value;
|
|
259
|
+
if (!terms.length) return { items: source.value.filter((c) => !c.hidden), terms };
|
|
260
|
+
const items = rank(source.value, terms);
|
|
261
|
+
if (items.length || !props.layoutFallback) return { items, terms };
|
|
262
|
+
const swapped = terms.map(swapLayout);
|
|
263
|
+
const other = rank(source.value, swapped);
|
|
264
|
+
return other.length ? { items: other, terms: swapped } : { items, terms };
|
|
143
265
|
});
|
|
266
|
+
const ranked = computed(() => local.value.items);
|
|
144
267
|
const fetched = computed(() => {
|
|
145
268
|
if (!found.value.length) return [];
|
|
146
269
|
const seen = new Set(ranked.value.map((c) => c.id));
|
|
@@ -171,14 +294,45 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
171
294
|
for (const c of recent) push(c, props.recentLabel);
|
|
172
295
|
for (const c of ranked.value) if (!recent.includes(c)) push(c, c.group ?? "");
|
|
173
296
|
for (const c of fetched.value) push(c, c.group ?? "");
|
|
174
|
-
return order.map((name) => ({ name, items: map.get(name) }));
|
|
297
|
+
return order.map((name) => ({ name, items: folded(name, map.get(name)) }));
|
|
175
298
|
});
|
|
299
|
+
const expanded = ref(/* @__PURE__ */ new Set());
|
|
300
|
+
const moreOf = /* @__PURE__ */ new WeakMap();
|
|
301
|
+
function folded(name, items) {
|
|
302
|
+
const limit = props.groupLimit;
|
|
303
|
+
if (!limit || items.length <= limit + 1 || expanded.value.has(name)) return items;
|
|
304
|
+
const more = {
|
|
305
|
+
id: `lp-cmd-more:${name}`,
|
|
306
|
+
label: text.value.showMore.replace("{count}", String(items.length - limit)),
|
|
307
|
+
icon: "lucide:chevron-down",
|
|
308
|
+
keepOpen: true
|
|
309
|
+
};
|
|
310
|
+
moreOf.set(more, name);
|
|
311
|
+
return [...items.slice(0, limit), more];
|
|
312
|
+
}
|
|
176
313
|
const flat = computed(() => grouped.value.flatMap((g) => g.items));
|
|
314
|
+
const active = computed(() => {
|
|
315
|
+
const c = flat.value[selectedIndex.value];
|
|
316
|
+
return c && !moreOf.has(c) ? c : void 0;
|
|
317
|
+
});
|
|
318
|
+
const previewRef = ref(null);
|
|
319
|
+
watch(
|
|
320
|
+
() => active.value?.id,
|
|
321
|
+
async () => {
|
|
322
|
+
if (!props.previewPane) return;
|
|
323
|
+
await nextTick();
|
|
324
|
+
const viewport = previewRef.value?.viewportEl;
|
|
325
|
+
if (!viewport) return;
|
|
326
|
+
const mark = viewport.querySelector("mark");
|
|
327
|
+
if (mark) mark.scrollIntoView({ block: "center" });
|
|
328
|
+
else viewport.scrollTop = 0;
|
|
329
|
+
}
|
|
330
|
+
);
|
|
177
331
|
function flatIndexOf(c) {
|
|
178
332
|
return flat.value.indexOf(c);
|
|
179
333
|
}
|
|
180
|
-
function highlight(value) {
|
|
181
|
-
const terms = [...new Set(
|
|
334
|
+
function highlight(value, extra = []) {
|
|
335
|
+
const terms = [...new Set([...local.value.terms, ...extra.map((t) => t.toLowerCase())].filter((t) => t.length >= 2))].sort(
|
|
182
336
|
(a, b) => b.length - a.length
|
|
183
337
|
);
|
|
184
338
|
if (!value || terms.length === 0) return value ? [{ text: value, hit: false }] : [];
|
|
@@ -209,6 +363,9 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
209
363
|
selectedIndex.value = 0;
|
|
210
364
|
refresh();
|
|
211
365
|
});
|
|
366
|
+
watch([query, trail, () => props.open], () => {
|
|
367
|
+
expanded.value = /* @__PURE__ */ new Set();
|
|
368
|
+
});
|
|
212
369
|
watch(
|
|
213
370
|
() => flat.value.length,
|
|
214
371
|
(len) => {
|
|
@@ -233,13 +390,36 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
233
390
|
const len = flat.value.length;
|
|
234
391
|
if (len) selectedIndex.value = (selectedIndex.value - 1 + len) % len;
|
|
235
392
|
}
|
|
236
|
-
function runSelected() {
|
|
237
|
-
|
|
393
|
+
function runSelected(event) {
|
|
394
|
+
const c = flat.value[selectedIndex.value];
|
|
395
|
+
if (c?.href && !c.disabled && (event?.ctrlKey || event?.metaKey)) {
|
|
396
|
+
openInNewTab(c);
|
|
397
|
+
return;
|
|
398
|
+
}
|
|
399
|
+
run(c);
|
|
400
|
+
}
|
|
401
|
+
function openInNewTab(c) {
|
|
402
|
+
if (!c.href) return;
|
|
403
|
+
window.open(c.href, "_blank", "noopener");
|
|
404
|
+
emit("run", c.id, c);
|
|
405
|
+
emit("update:open", false);
|
|
406
|
+
}
|
|
407
|
+
function onRowClick(event, c) {
|
|
408
|
+
if (c.href && (event.ctrlKey || event.metaKey || event.shiftKey || event.altKey || event.button !== 0)) return;
|
|
409
|
+
event.preventDefault();
|
|
410
|
+
run(c);
|
|
238
411
|
}
|
|
239
412
|
function run(c) {
|
|
240
413
|
if (!c || c.disabled) return;
|
|
414
|
+
const group = moreOf.get(c);
|
|
415
|
+
if (group !== void 0) {
|
|
416
|
+
expanded.value = /* @__PURE__ */ new Set([...expanded.value, group]);
|
|
417
|
+
inputRef.value?.focus();
|
|
418
|
+
return;
|
|
419
|
+
}
|
|
241
420
|
emit("select", c);
|
|
242
421
|
c.onSelect?.();
|
|
422
|
+
if (!c.onSelect && c.href && !c.children) window.location.assign(c.href);
|
|
243
423
|
if (c.children) {
|
|
244
424
|
enter(c);
|
|
245
425
|
return;
|
|
@@ -272,11 +452,13 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
272
452
|
trail.value = [];
|
|
273
453
|
modeItems.value = [];
|
|
274
454
|
found.value = [];
|
|
455
|
+
failed.value = false;
|
|
275
456
|
if (o) {
|
|
276
457
|
await nextTick();
|
|
277
458
|
inputRef.value?.focus();
|
|
278
459
|
}
|
|
279
|
-
}
|
|
460
|
+
},
|
|
461
|
+
{ immediate: true }
|
|
280
462
|
);
|
|
281
463
|
useHotkeys(
|
|
282
464
|
() => props.hotkey ? [
|
|
@@ -292,26 +474,26 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
292
474
|
return (_ctx, _cache) => {
|
|
293
475
|
return openBlock(), createBlock(unref(DialogRoot), {
|
|
294
476
|
open: __props.open,
|
|
295
|
-
"onUpdate:open": _cache[
|
|
477
|
+
"onUpdate:open": _cache[3] || (_cache[3] = (v) => emit("update:open", v))
|
|
296
478
|
}, {
|
|
297
479
|
default: withCtx(() => [
|
|
298
480
|
createVNode(unref(DialogPortal), null, {
|
|
299
481
|
default: withCtx(() => [
|
|
300
482
|
createVNode(unref(DialogOverlay), { class: "lp-scrim fixed inset-0 z-(--z-overlay) data-[state=open]:animate-[fade-in_150ms_ease] data-[state=closed]:animate-[fade-out_130ms_ease]" }),
|
|
301
483
|
createVNode(unref(DialogContent), {
|
|
302
|
-
class: "fixed left-1/2 top-[12vh] z-(--z-modal) flex max-h-[76vh] w-[min(92vw,40rem)] -translate-x-1/2 flex-col overflow-hidden rounded-card border border-line
|
|
303
|
-
onOpenAutoFocus: _cache[
|
|
484
|
+
class: normalizeClass(["fixed left-1/2 top-[12vh] z-(--z-modal) flex max-h-[76vh] w-[min(92vw,40rem)] -translate-x-1/2 flex-col overflow-hidden rounded-card border border-line lp-glass-overlay shadow-panel outline-none data-[state=open]:animate-[pop-in_160ms_var(--ease-emphasized)] data-[state=closed]:animate-[pop-out_130ms_ease]", __props.previewPane && "md:h-[min(76vh,36rem)] md:w-[min(92vw,64rem)]"]),
|
|
485
|
+
onOpenAutoFocus: _cache[2] || (_cache[2] = withModifiers(() => {
|
|
304
486
|
}, ["prevent"]))
|
|
305
487
|
}, {
|
|
306
488
|
default: withCtx(() => [
|
|
307
489
|
createVNode(unref(DialogTitle), { class: "sr-only" }, {
|
|
308
|
-
default: withCtx(() => [..._cache[
|
|
490
|
+
default: withCtx(() => [..._cache[4] || (_cache[4] = [
|
|
309
491
|
createTextVNode("Command palette", -1)
|
|
310
492
|
])]),
|
|
311
493
|
_: 1
|
|
312
494
|
}),
|
|
313
495
|
createVNode(unref(DialogDescription), { class: "sr-only" }, {
|
|
314
|
-
default: withCtx(() => [..._cache[
|
|
496
|
+
default: withCtx(() => [..._cache[5] || (_cache[5] = [
|
|
315
497
|
createTextVNode("Search and run a command.", -1)
|
|
316
498
|
])]),
|
|
317
499
|
_: 1
|
|
@@ -354,6 +536,11 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
354
536
|
ref: inputRef,
|
|
355
537
|
"onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => query.value = $event),
|
|
356
538
|
type: "text",
|
|
539
|
+
role: "combobox",
|
|
540
|
+
"aria-autocomplete": "list",
|
|
541
|
+
"aria-expanded": "true",
|
|
542
|
+
"aria-controls": listId,
|
|
543
|
+
"aria-activedescendant": activeId.value,
|
|
357
544
|
placeholder: mode.value?.childPlaceholder ?? __props.placeholder,
|
|
358
545
|
class: "h-12 min-w-0 flex-1 bg-transparent text-sm text-ink outline-none placeholder:text-muted",
|
|
359
546
|
onKeydown: [
|
|
@@ -361,111 +548,214 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
361
548
|
withKeys(withModifiers(moveUp, ["prevent"]), ["up"]),
|
|
362
549
|
withKeys(withModifiers(runSelected, ["prevent"]), ["enter"]),
|
|
363
550
|
withKeys(onBackspace, ["backspace"]),
|
|
364
|
-
withKeys(onEscape, ["esc"])
|
|
551
|
+
withKeys(onEscape, ["esc"]),
|
|
552
|
+
withKeys(onTab, ["tab"])
|
|
365
553
|
]
|
|
366
554
|
}, null, 40, _hoisted_3), [
|
|
367
555
|
[vModelText, query.value]
|
|
368
556
|
]),
|
|
369
|
-
_cache[
|
|
557
|
+
_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))
|
|
370
558
|
]),
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
559
|
+
createElementVNode("div", _hoisted_4, [
|
|
560
|
+
createVNode(_sfc_main$2, {
|
|
561
|
+
ref_key: "scrollRef",
|
|
562
|
+
ref: scrollRef,
|
|
563
|
+
class: "min-h-0 min-w-0 flex-1",
|
|
564
|
+
"content-class": "p-2"
|
|
565
|
+
}, {
|
|
566
|
+
default: withCtx(() => [
|
|
567
|
+
flat.value.length === 0 && !failed.value ? (openBlock(), createElementBlock("p", _hoisted_5, toDisplayString(unref(searching) ? text.value.searching : __props.emptyText), 1)) : createCommentVNode("", true),
|
|
568
|
+
createElementVNode("div", {
|
|
569
|
+
id: listId,
|
|
570
|
+
role: "listbox"
|
|
382
571
|
}, [
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
"data-cmd-index": flatIndexOf(c),
|
|
389
|
-
disabled: c.disabled,
|
|
390
|
-
class: normalizeClass(["lp-cmd-item flex w-full items-center gap-3 rounded-md px-2.5 py-2 text-left text-sm outline-none transition-colors duration-[var(--duration-fast)] disabled:pointer-events-none disabled:opacity-45", flatIndexOf(c) === selectedIndex.value ? "bg-brand-soft text-brand" : "text-ink hover:bg-surface-soft/60"]),
|
|
391
|
-
onClick: ($event) => run(c),
|
|
392
|
-
onPointerenter: ($event) => selectedIndex.value = flatIndexOf(c)
|
|
572
|
+
(openBlock(true), createElementBlock(Fragment, null, renderList(grouped.value, (group, gi) => {
|
|
573
|
+
return openBlock(), createElementBlock("div", {
|
|
574
|
+
key: group.name,
|
|
575
|
+
role: "group",
|
|
576
|
+
"aria-labelledby": group.name ? `${listId}-g${gi}` : void 0
|
|
393
577
|
}, [
|
|
394
|
-
|
|
578
|
+
group.name ? (openBlock(), createElementBlock("div", {
|
|
579
|
+
key: 0,
|
|
580
|
+
id: `${listId}-g${gi}`,
|
|
581
|
+
class: "px-2 pb-1 pt-3 text-[11px] font-semibold uppercase tracking-[0.08em] text-muted"
|
|
582
|
+
}, toDisplayString(group.name), 9, _hoisted_7)) : createCommentVNode("", true),
|
|
583
|
+
(openBlock(true), createElementBlock(Fragment, null, renderList(group.items, (c) => {
|
|
584
|
+
return openBlock(), createBlock(resolveDynamicComponent(c.href ? "a" : "button"), {
|
|
585
|
+
id: optionId(flatIndexOf(c)),
|
|
586
|
+
key: c.id,
|
|
587
|
+
href: c.disabled ? void 0 : c.href,
|
|
588
|
+
type: c.href ? void 0 : "button",
|
|
589
|
+
role: "option",
|
|
590
|
+
tabindex: "-1",
|
|
591
|
+
"aria-selected": flatIndexOf(c) === selectedIndex.value,
|
|
592
|
+
"aria-disabled": c.disabled || void 0,
|
|
593
|
+
"data-cmd-index": flatIndexOf(c),
|
|
594
|
+
disabled: c.href ? void 0 : c.disabled,
|
|
595
|
+
class: normalizeClass(["lp-cmd-item flex w-full gap-3 rounded-md px-2.5 py-2 text-left text-sm outline-none transition-colors duration-[var(--duration-fast)] disabled:pointer-events-none disabled:opacity-45 aria-disabled:pointer-events-none aria-disabled:opacity-45", [
|
|
596
|
+
c.excerpt ? "items-start" : "items-center",
|
|
597
|
+
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"
|
|
598
|
+
]]),
|
|
599
|
+
onClick: ($event) => onRowClick($event, c),
|
|
600
|
+
onPointerenter: ($event) => selectedIndex.value = flatIndexOf(c)
|
|
601
|
+
}, {
|
|
602
|
+
default: withCtx(() => [
|
|
603
|
+
c.icon ? (openBlock(), createBlock(_sfc_main$1, {
|
|
604
|
+
key: 0,
|
|
605
|
+
name: c.icon,
|
|
606
|
+
size: 16,
|
|
607
|
+
class: normalizeClass(["shrink-0", { "mt-0.5": c.excerpt }])
|
|
608
|
+
}, null, 8, ["name", "class"])) : createCommentVNode("", true),
|
|
609
|
+
createElementVNode("span", _hoisted_8, [
|
|
610
|
+
createElementVNode("span", _hoisted_9, [
|
|
611
|
+
(openBlock(true), createElementBlock(Fragment, null, renderList(highlight(c.label, c.highlight), (p, pi) => {
|
|
612
|
+
return openBlock(), createElementBlock(Fragment, {
|
|
613
|
+
key: `l${pi}`
|
|
614
|
+
}, [
|
|
615
|
+
p.hit ? (openBlock(), createElementBlock("mark", _hoisted_10, toDisplayString(p.text), 1)) : (openBlock(), createElementBlock(Fragment, { key: 1 }, [
|
|
616
|
+
createTextVNode(toDisplayString(p.text), 1)
|
|
617
|
+
], 64))
|
|
618
|
+
], 64);
|
|
619
|
+
}), 128))
|
|
620
|
+
]),
|
|
621
|
+
c.description ? (openBlock(), createElementBlock("span", _hoisted_11, [
|
|
622
|
+
(openBlock(true), createElementBlock(Fragment, null, renderList(highlight(c.description, c.highlight), (p, pi) => {
|
|
623
|
+
return openBlock(), createElementBlock(Fragment, {
|
|
624
|
+
key: `d${pi}`
|
|
625
|
+
}, [
|
|
626
|
+
p.hit ? (openBlock(), createElementBlock("mark", _hoisted_12, toDisplayString(p.text), 1)) : (openBlock(), createElementBlock(Fragment, { key: 1 }, [
|
|
627
|
+
createTextVNode(toDisplayString(p.text), 1)
|
|
628
|
+
], 64))
|
|
629
|
+
], 64);
|
|
630
|
+
}), 128))
|
|
631
|
+
])) : createCommentVNode("", true),
|
|
632
|
+
c.excerpt ? (openBlock(), createElementBlock("span", {
|
|
633
|
+
key: 1,
|
|
634
|
+
class: "lp-cmd-excerpt mt-1 block text-[13px] leading-snug text-ink/80",
|
|
635
|
+
style: normalizeStyle({ "-webkit-line-clamp": __props.excerptLines })
|
|
636
|
+
}, [
|
|
637
|
+
(openBlock(true), createElementBlock(Fragment, null, renderList(highlight(c.excerpt, c.highlight), (p, pi) => {
|
|
638
|
+
return openBlock(), createElementBlock(Fragment, {
|
|
639
|
+
key: `e${pi}`
|
|
640
|
+
}, [
|
|
641
|
+
p.hit ? (openBlock(), createElementBlock("mark", _hoisted_13, toDisplayString(p.text), 1)) : (openBlock(), createElementBlock(Fragment, { key: 1 }, [
|
|
642
|
+
createTextVNode(toDisplayString(p.text), 1)
|
|
643
|
+
], 64))
|
|
644
|
+
], 64);
|
|
645
|
+
}), 128))
|
|
646
|
+
], 4)) : createCommentVNode("", true)
|
|
647
|
+
]),
|
|
648
|
+
c.shortcut ? (openBlock(), createElementBlock("kbd", _hoisted_14, toDisplayString(c.shortcut), 1)) : c.children ? (openBlock(), createBlock(_sfc_main$1, {
|
|
649
|
+
key: 2,
|
|
650
|
+
name: "lucide:chevron-right",
|
|
651
|
+
size: 14,
|
|
652
|
+
class: "shrink-0 text-muted"
|
|
653
|
+
})) : createCommentVNode("", true)
|
|
654
|
+
]),
|
|
655
|
+
_: 2
|
|
656
|
+
}, 1064, ["id", "href", "type", "aria-selected", "aria-disabled", "data-cmd-index", "disabled", "class", "onClick", "onPointerenter"]);
|
|
657
|
+
}), 128))
|
|
658
|
+
], 8, _hoisted_6);
|
|
659
|
+
}), 128))
|
|
660
|
+
]),
|
|
661
|
+
failed.value ? (openBlock(), createElementBlock("div", {
|
|
662
|
+
key: 1,
|
|
663
|
+
role: "alert",
|
|
664
|
+
class: normalizeClass(["flex items-center justify-center gap-2 px-2 text-sm text-muted", flat.value.length ? "pb-1 pt-3" : "py-10"])
|
|
665
|
+
}, [
|
|
666
|
+
createVNode(_sfc_main$1, {
|
|
667
|
+
name: "lucide:circle-alert",
|
|
668
|
+
size: 15,
|
|
669
|
+
class: "shrink-0"
|
|
670
|
+
}),
|
|
671
|
+
createElementVNode("span", null, toDisplayString(text.value.searchFailed), 1),
|
|
672
|
+
createElementVNode("button", {
|
|
673
|
+
type: "button",
|
|
674
|
+
class: "rounded-md px-1.5 py-0.5 font-medium text-brand outline-none transition-colors hover:bg-brand-soft focus-visible:ring-2 focus-visible:ring-ring",
|
|
675
|
+
onClick: _cache[1] || (_cache[1] = ($event) => {
|
|
676
|
+
refresh();
|
|
677
|
+
inputRef.value?.focus();
|
|
678
|
+
})
|
|
679
|
+
}, toDisplayString(text.value.retry), 1)
|
|
680
|
+
], 2)) : createCommentVNode("", true)
|
|
681
|
+
]),
|
|
682
|
+
_: 1
|
|
683
|
+
}, 512),
|
|
684
|
+
__props.previewPane ? (openBlock(), createElementBlock("aside", _hoisted_15, [
|
|
685
|
+
createVNode(_sfc_main$2, {
|
|
686
|
+
ref_key: "previewRef",
|
|
687
|
+
ref: previewRef,
|
|
688
|
+
class: "min-h-0 flex-1",
|
|
689
|
+
"content-class": "px-5 py-4"
|
|
690
|
+
}, {
|
|
691
|
+
default: withCtx(() => [
|
|
692
|
+
active.value ? renderSlot(_ctx.$slots, "preview", {
|
|
693
|
+
key: 0,
|
|
694
|
+
command: active.value
|
|
695
|
+
}, () => [
|
|
696
|
+
createElementVNode("div", _hoisted_16, [
|
|
697
|
+
active.value.icon ? (openBlock(), createBlock(_sfc_main$1, {
|
|
395
698
|
key: 0,
|
|
396
|
-
name:
|
|
699
|
+
name: active.value.icon,
|
|
397
700
|
size: 16,
|
|
398
|
-
class: "shrink-0"
|
|
399
|
-
}, null, 8, ["name"])) : createCommentVNode("", true),
|
|
400
|
-
createElementVNode("span", _hoisted_7, [
|
|
401
|
-
createElementVNode("span", _hoisted_8, [
|
|
402
|
-
(openBlock(true), createElementBlock(Fragment, null, renderList(highlight(c.label), (p, pi) => {
|
|
403
|
-
return openBlock(), createElementBlock(Fragment, {
|
|
404
|
-
key: `l${pi}`
|
|
405
|
-
}, [
|
|
406
|
-
p.hit ? (openBlock(), createElementBlock("mark", _hoisted_9, toDisplayString(p.text), 1)) : (openBlock(), createElementBlock(Fragment, { key: 1 }, [
|
|
407
|
-
createTextVNode(toDisplayString(p.text), 1)
|
|
408
|
-
], 64))
|
|
409
|
-
], 64);
|
|
410
|
-
}), 128))
|
|
411
|
-
]),
|
|
412
|
-
c.description ? (openBlock(), createElementBlock("span", _hoisted_10, [
|
|
413
|
-
(openBlock(true), createElementBlock(Fragment, null, renderList(highlight(c.description), (p, pi) => {
|
|
414
|
-
return openBlock(), createElementBlock(Fragment, {
|
|
415
|
-
key: `d${pi}`
|
|
416
|
-
}, [
|
|
417
|
-
p.hit ? (openBlock(), createElementBlock("mark", _hoisted_11, toDisplayString(p.text), 1)) : (openBlock(), createElementBlock(Fragment, { key: 1 }, [
|
|
418
|
-
createTextVNode(toDisplayString(p.text), 1)
|
|
419
|
-
], 64))
|
|
420
|
-
], 64);
|
|
421
|
-
}), 128))
|
|
422
|
-
])) : createCommentVNode("", true)
|
|
423
|
-
]),
|
|
424
|
-
c.shortcut ? (openBlock(), createElementBlock("kbd", _hoisted_12, toDisplayString(c.shortcut), 1)) : c.children ? (openBlock(), createBlock(_sfc_main$1, {
|
|
425
|
-
key: 2,
|
|
426
|
-
name: "lucide:chevron-right",
|
|
427
|
-
size: 14,
|
|
428
701
|
class: "shrink-0 text-muted"
|
|
429
|
-
})) : createCommentVNode("", true)
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
702
|
+
}, null, 8, ["name"])) : createCommentVNode("", true),
|
|
703
|
+
createElementVNode("h3", _hoisted_17, toDisplayString(active.value.label), 1)
|
|
704
|
+
]),
|
|
705
|
+
active.value.description ? (openBlock(), createElementBlock("p", _hoisted_18, toDisplayString(active.value.description), 1)) : createCommentVNode("", true),
|
|
706
|
+
active.value.preview || active.value.excerpt ? (openBlock(), createElementBlock("p", _hoisted_19, [
|
|
707
|
+
(openBlock(true), createElementBlock(Fragment, null, renderList(highlight(active.value.preview ?? active.value.excerpt ?? "", active.value.highlight), (p, pi) => {
|
|
708
|
+
return openBlock(), createElementBlock(Fragment, {
|
|
709
|
+
key: `p${pi}`
|
|
710
|
+
}, [
|
|
711
|
+
p.hit ? (openBlock(), createElementBlock("mark", _hoisted_20, toDisplayString(p.text), 1)) : (openBlock(), createElementBlock(Fragment, { key: 1 }, [
|
|
712
|
+
createTextVNode(toDisplayString(p.text), 1)
|
|
713
|
+
], 64))
|
|
714
|
+
], 64);
|
|
715
|
+
}), 128))
|
|
716
|
+
])) : (openBlock(), createElementBlock("p", _hoisted_21, toDisplayString(text.value.noPreview), 1))
|
|
717
|
+
], true) : createCommentVNode("", true)
|
|
718
|
+
]),
|
|
719
|
+
_: 3
|
|
720
|
+
}, 512)
|
|
721
|
+
])) : createCommentVNode("", true)
|
|
722
|
+
]),
|
|
723
|
+
createElementVNode("div", _hoisted_22, [
|
|
724
|
+
createElementVNode("span", _hoisted_23, [
|
|
725
|
+
_cache[7] || (_cache[7] = createElementVNode("kbd", { class: "rounded border border-line px-1 text-[10px]" }, "↑", -1)),
|
|
726
|
+
_cache[8] || (_cache[8] = createElementVNode("kbd", { class: "rounded border border-line px-1 text-[10px]" }, "↓", -1)),
|
|
441
727
|
createTextVNode(" " + toDisplayString(text.value.navigate), 1)
|
|
442
728
|
]),
|
|
443
|
-
createElementVNode("span",
|
|
444
|
-
_cache[
|
|
729
|
+
createElementVNode("span", _hoisted_24, [
|
|
730
|
+
_cache[9] || (_cache[9] = createElementVNode("kbd", { class: "rounded border border-line px-1 text-[10px]" }, "↵", -1)),
|
|
445
731
|
createTextVNode(" " + toDisplayString(text.value.select), 1)
|
|
446
732
|
]),
|
|
447
|
-
|
|
448
|
-
_cache[
|
|
733
|
+
selectedActions.value.length ? (openBlock(), createElementBlock("span", _hoisted_25, [
|
|
734
|
+
_cache[10] || (_cache[10] = createElementVNode("kbd", { class: "rounded border border-line px-1 text-[10px]" }, "tab", -1)),
|
|
735
|
+
createTextVNode(" " + toDisplayString(text.value.actions), 1)
|
|
736
|
+
])) : createCommentVNode("", true),
|
|
737
|
+
trail.value.length ? (openBlock(), createElementBlock("span", _hoisted_26, [
|
|
738
|
+
_cache[11] || (_cache[11] = createElementVNode("kbd", { class: "rounded border border-line px-1 text-[10px]" }, "⌫", -1)),
|
|
449
739
|
createTextVNode(" " + toDisplayString(text.value.back), 1)
|
|
450
740
|
])) : createCommentVNode("", true),
|
|
451
|
-
createElementVNode("span",
|
|
452
|
-
_cache[
|
|
741
|
+
createElementVNode("span", _hoisted_27, [
|
|
742
|
+
_cache[12] || (_cache[12] = createElementVNode("kbd", { class: "rounded border border-line px-1 text-[10px]" }, "esc", -1)),
|
|
453
743
|
createTextVNode(" " + toDisplayString(text.value.close), 1)
|
|
454
744
|
])
|
|
455
745
|
])
|
|
456
746
|
]),
|
|
457
|
-
_:
|
|
458
|
-
})
|
|
747
|
+
_: 3
|
|
748
|
+
}, 8, ["class"])
|
|
459
749
|
]),
|
|
460
|
-
_:
|
|
750
|
+
_: 3
|
|
461
751
|
})
|
|
462
752
|
]),
|
|
463
|
-
_:
|
|
753
|
+
_: 3
|
|
464
754
|
}, 8, ["open"]);
|
|
465
755
|
};
|
|
466
756
|
}
|
|
467
757
|
});
|
|
468
|
-
const LpCommandPalette = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-
|
|
758
|
+
const LpCommandPalette = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-cc5b91ea"]]);
|
|
469
759
|
export {
|
|
470
760
|
LpCommandPalette as default
|
|
471
761
|
};
|