11<script setup lang="ts">
22import type { CommandPaletteCommand } from ' ~/types/command-palette'
33
4- const { isOpen, query, close, toggle, view, setView } = useCommandPalette ()
5- const { groupedCommands, flatCommands, hasResults, submitSearchQuery, trimmedQuery } =
6- useCommandPaletteCommands ()
4+ const { isOpen, query, close, toggle, setView } = useCommandPalette ()
5+ const {
6+ groupedCommands,
7+ flatCommands,
8+ hasResults,
9+ submitSearchQuery,
10+ trailingCommands,
11+ trimmedQuery,
12+ viewMeta,
13+ } = useCommandPaletteCommands ()
714const keyboardShortcuts = useKeyboardShortcuts ()
815const route = useRoute ()
916
@@ -25,10 +32,6 @@ const statusId = `${dialogId}-status`
2532const resultsId = ` ${dialogId }-results `
2633
2734const inputDescribedBy = computed (() => ` ${descriptionId } ${statusId } ` )
28- const isLanguageView = computed (() => view .value === ' languages' )
29- const modalSubtitle = computed (() =>
30- isLanguageView .value ? $t (' command_palette.subtitle_languages' ) : $t (' command_palette.subtitle' ),
31- )
3235
3336const statusMessage = computed (() => {
3437 const count = flatCommands .value .length
@@ -56,6 +59,11 @@ function getInputElement() {
5659 return document .querySelector <HTMLInputElement >(` #${inputId } ` )
5760}
5861
62+ function isInputEventTarget(target : EventTarget | null ) {
63+ const input = getInputElement ()
64+ return !! input && (target === input || document .activeElement === input )
65+ }
66+
5967function getCommandElements() {
6068 return Array .from (
6169 getDialog ()?.querySelectorAll <HTMLButtonElement >(' [data-command-item="true"]' ) ?? [],
@@ -120,7 +128,22 @@ function handleGlobalKeydown(event: KeyboardEvent) {
120128 return
121129 }
122130
123- if (event .key === ' Enter' && document .activeElement === getInputElement ()) {
131+ if (
132+ event .key === ' ArrowLeft' &&
133+ viewMeta .value .canGoBack &&
134+ ! query .value &&
135+ ! event .altKey &&
136+ ! event .ctrlKey &&
137+ ! event .metaKey &&
138+ ! event .shiftKey &&
139+ isInputEventTarget (event .target )
140+ ) {
141+ event .preventDefault ()
142+ handleBack ()
143+ return
144+ }
145+
146+ if (event .key === ' Enter' && isInputEventTarget (event .target )) {
124147 const firstCommand = flatCommands .value [0 ]
125148 if (! firstCommand ) {
126149 if (! trimmedQuery .value ) return
@@ -201,8 +224,8 @@ useEventListener(document, 'keydown', handleGlobalKeydown)
201224 ref =" modalRef"
202225 :id =" dialogId"
203226 :modalTitle =" $t('command_palette.title')"
204- :modalSubtitle =" modalSubtitle "
205- class =" max-w-2xl p-0 overflow-hidden"
227+ :modalSubtitle =" viewMeta.subtitle "
228+ class =" max-w-[48rem] overflow-hidden p-0 "
206229 @close =" handleDialogClose"
207230 >
208231 <div class =" -mx-6 -mt-6" >
@@ -215,7 +238,7 @@ useEventListener(document, 'keydown', handleGlobalKeydown)
215238
216239 <div class =" border-b border-border/70 bg-bg-subtle/60 px-4 py-4 sm:px-5" >
217240 <button
218- v-if =" isLanguageView "
241+ v-if =" viewMeta.canGoBack "
219242 type =" button"
220243 class =" mb-3 inline-flex min-h-9 items-center gap-2 rounded-lg border border-transparent px-2.5 py-1.5 text-sm text-fg-muted lowercase transition-colors duration-150 hover:border-border/70 hover:bg-bg hover:text-fg focus-visible:outline-accent/70"
221244 @click =" handleBack"
@@ -228,8 +251,8 @@ useEventListener(document, 'keydown', handleGlobalKeydown)
228251 :id =" inputId"
229252 ref =" inputRef"
230253 v-model =" query"
231- type =" search "
232- :placeholder =" $t('command_palette .placeholder') "
254+ type =" text "
255+ :placeholder =" viewMeta .placeholder"
233256 no-correct
234257 size =" large"
235258 class =" w-full"
@@ -274,7 +297,7 @@ useEventListener(document, 'keydown', handleGlobalKeydown)
274297 <li v-for =" command in group.items" :key =" command.id" >
275298 <button
276299 type =" button"
277- class =" min-h-12 w-full cursor-pointer rounded-lg border border-transparent px-3 py-2.5 text-start transition-colors duration-150 hover:border-border/80 hover:bg-bg focus-visible:outline-accent/70"
300+ class =" min-h-12 w-full rounded-lg border border-transparent px-3 py-2.5 text-start transition-colors duration-150 hover:border-border/80 hover:bg-bg focus-visible:outline-accent/70"
278301 :class ="
279302 activeIndex === (commandIndexMap.get(command.id) ?? -1)
280303 ? 'border-border/80 bg-bg'
@@ -309,6 +332,12 @@ useEventListener(document, 'keydown', handleGlobalKeydown)
309332 >
310333 {{ command.activeLabel || $t('command_palette.current') }}
311334 </span >
335+ <span
336+ v-if =" command.previewColor"
337+ class =" inline-block h-3.5 w-3.5 shrink-0 rounded-full border border-border/70"
338+ :style =" { backgroundColor: command.previewColor }"
339+ aria-hidden =" true"
340+ />
312341 <span
313342 v-if =" command.external"
314343 class =" i-lucide:external-link inline-block h-3.5 w-3.5 shrink-0 text-fg-subtle"
@@ -322,6 +351,38 @@ useEventListener(document, 'keydown', handleGlobalKeydown)
322351 </li >
323352 </ul >
324353 </section >
354+
355+ <ul v-if =" trailingCommands.length" class =" m-0 flex list-none flex-col gap-1 p-0" >
356+ <li v-for =" command in trailingCommands" :key =" command.id" >
357+ <button
358+ type =" button"
359+ class =" min-h-12 w-full rounded-xl border border-border/70 bg-bg-subtle/70 px-3 py-2.5 text-start transition-colors duration-150 hover:border-border/80 hover:bg-bg focus-visible:outline-accent/70"
360+ :class ="
361+ activeIndex === (commandIndexMap.get(command.id) ?? -1)
362+ ? 'border-border/80 bg-bg'
363+ : ''
364+ "
365+ data-command-item =" true"
366+ :aria-current =" command.active ? 'true' : undefined"
367+ @click =" void handleCommandSelect(command)"
368+ @focus =" activeIndex = commandIndexMap.get(command.id) ?? -1"
369+ @mouseenter =" activeIndex = commandIndexMap.get(command.id) ?? -1"
370+ >
371+ <span class =" flex items-center gap-3" >
372+ <span
373+ class =" inline-block h-4 w-4 shrink-0 text-fg-subtle"
374+ :class =" command.iconClass"
375+ aria-hidden =" true"
376+ />
377+ <span class =" min-w-0 flex-1" >
378+ <span class =" block truncate text-base text-fg lowercase" >
379+ {{ command.label }}
380+ </span >
381+ </span >
382+ </span >
383+ </button >
384+ </li >
385+ </ul >
325386 </div >
326387 </div >
327388 </div >
0 commit comments