mirror of
https://github.com/ArthurDanjou/ui.git
synced 2026-01-14 12:14:41 +01:00
up
This commit is contained in:
@@ -10,8 +10,9 @@ const open = ref(false)
|
||||
const searchTerm = ref('')
|
||||
// const searchTermDebounced = refDebounced(searchTerm, 200)
|
||||
const selected = ref([])
|
||||
const commandPalette = useTemplateRef('commandPalette')
|
||||
|
||||
const { data: users, status } = await useFetch('https://jsonplaceholder.typicode.com/users', {
|
||||
const { data: _users, status } = await useFetch('https://jsonplaceholder.typicode.com/users', {
|
||||
// params: { q: searchTermDebounced },
|
||||
transform: (data: User[]) => {
|
||||
return data?.map(user => ({ id: user.id, label: user.name, suffix: user.email, avatar: { src: `https://i.pravatar.cc/120?img=${user.id}` } })) || []
|
||||
@@ -259,6 +260,12 @@ function onSelect(item: any) {
|
||||
|
||||
defineShortcuts({
|
||||
meta_k: () => open.value = !open.value,
|
||||
meta_shift_a: {
|
||||
usingInput: true,
|
||||
handler: () => {
|
||||
commandPalette.value?.openView('askAI')
|
||||
}
|
||||
},
|
||||
...extractShortcuts(groups.value)
|
||||
})
|
||||
</script>
|
||||
@@ -266,6 +273,7 @@ defineShortcuts({
|
||||
<template>
|
||||
<DefineTemplate>
|
||||
<UCommandPalette
|
||||
ref="commandPalette"
|
||||
v-model="selected"
|
||||
v-model:search-term="searchTerm"
|
||||
:loading="status === 'pending'"
|
||||
@@ -279,8 +287,7 @@ defineShortcuts({
|
||||
class="sm:max-h-80"
|
||||
@update:model-value="onSelect"
|
||||
>
|
||||
<template #view="{ viewName }">
|
||||
<div v-if="viewName === 'wallpaper'" class="flex flex-col h-full w-full">
|
||||
<template #wallpaper>
|
||||
<div class="flex-1 overflow-y-auto p-6">
|
||||
<div class="grid grid-cols-4 gap-4">
|
||||
<div
|
||||
@@ -313,6 +320,14 @@ defineShortcuts({
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template #askAI>
|
||||
<div class="flex flex-col items-center justify-center gap-4 p-6">
|
||||
<UIcon name="i-lucide-sparkles" class="size-8 text-primary" />
|
||||
<span class="text-lg font-semibold text-highlighted">
|
||||
Ask me anything...
|
||||
</span>
|
||||
</div>
|
||||
</template>
|
||||
</UCommandPalette>
|
||||
|
||||
@@ -154,12 +154,11 @@ export type CommandPaletteSlots<G extends CommandPaletteGroup<T> = CommandPalett
|
||||
'empty'(props: { searchTerm?: string }): any
|
||||
'back'(props: { ui: { [K in keyof Required<CommandPalette['slots']>]: (props?: Record<string, any>) => string } }): any
|
||||
'close'(props: { ui: { [K in keyof Required<CommandPalette['slots']>]: (props?: Record<string, any>) => string } }): any
|
||||
'view'(props: { viewName?: string, current: any, searchTerm: string, navigateBack: () => void }): any
|
||||
'item': SlotProps<T>
|
||||
'item-leading': SlotProps<T>
|
||||
'item-label': SlotProps<T>
|
||||
'item-trailing': SlotProps<T>
|
||||
} & Record<string, SlotProps<G>> & Record<string, SlotProps<T>>
|
||||
} & Record<string, SlotProps<G>> & Record<string, SlotProps<T>> & Record<string, (props: { current: any, searchTerm: string, navigateBack: () => void, close: () => void }) => any>
|
||||
|
||||
</script>
|
||||
|
||||
@@ -290,6 +289,31 @@ const filteredGroups = computed(() => {
|
||||
|
||||
const listboxRootRef = useTemplateRef('listboxRootRef')
|
||||
|
||||
// Exposed methods for programmatic control
|
||||
function openView(viewName: string) {
|
||||
history.value.push({
|
||||
id: `view-${viewName}`,
|
||||
label: viewName,
|
||||
view: viewName,
|
||||
items: []
|
||||
} as any)
|
||||
|
||||
searchTerm.value = ''
|
||||
listboxRootRef.value?.highlightFirstItem()
|
||||
}
|
||||
|
||||
function closeView() {
|
||||
if (history.value.length > 0) {
|
||||
navigateBack()
|
||||
}
|
||||
}
|
||||
|
||||
defineExpose({
|
||||
openView,
|
||||
closeView,
|
||||
navigateBack
|
||||
})
|
||||
|
||||
function navigate(item: T) {
|
||||
if (!item.children?.length && !item.view) {
|
||||
return
|
||||
@@ -385,11 +409,11 @@ function onSelect(e: Event, item: T) {
|
||||
<ListboxContent :class="ui.content({ class: props.ui?.content })">
|
||||
<div v-if="currentView" :class="ui.viewport({ class: props.ui?.viewport })">
|
||||
<slot
|
||||
name="view"
|
||||
:view-name="currentView.view"
|
||||
:name="currentView.view"
|
||||
:current="currentView"
|
||||
:search-term="searchTerm"
|
||||
:navigate-back="navigateBack"
|
||||
:close="closeView"
|
||||
/>
|
||||
</div>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user