docs(command-palette): update

This commit is contained in:
Benjamin Canac
2024-10-14 14:47:39 +02:00
parent 6e9f6a8ef4
commit e9affb6f5b
11 changed files with 481 additions and 175 deletions

View File

@@ -1,40 +1,68 @@
<script setup lang="ts">
const groups = [{
id: 'settings',
items: [{
label: 'Profile',
icon: 'i-heroicons-user',
kbds: ['meta', 'P']
}, {
label: 'Billing',
icon: 'i-heroicons-credit-card',
kbds: ['meta', 'B'],
slot: 'billing'
}, {
label: 'Notifications',
icon: 'i-heroicons-bell'
}, {
label: 'Security',
icon: 'i-heroicons-lock-closed'
}]
items: [
{
label: 'Profile',
icon: 'i-heroicons-user',
kbds: ['meta', 'P']
},
{
label: 'Billing',
icon: 'i-heroicons-credit-card',
kbds: ['meta', 'B'],
slot: 'billing'
},
{
label: 'Notifications',
icon: 'i-heroicons-bell'
},
{
label: 'Security',
icon: 'i-heroicons-lock-closed'
}
]
}, {
id: 'users',
label: 'Users',
slot: 'users',
items: [
{ id: 1, label: 'Durward Reynolds' },
{ id: 2, label: 'Kenton Towne' },
{ id: 3, label: 'Therese Wunsch' },
{ id: 4, label: 'Benedict Kessler' },
{ id: 5, label: 'Katelyn Rohan' }
{
label: 'Benjamin Canac',
suffix: 'benjamincanac'
},
{
label: 'Sylvain Marroufin',
suffix: 'smarroufin'
},
{
label: 'Sébastien Chopin',
suffix: 'atinux'
},
{
label: 'Romain Hamel',
suffix: 'romhml'
},
{
label: 'Haytham A. Salama',
suffix: 'Haythamasalama'
},
{
label: 'Daniel Roe',
suffix: 'danielroe'
},
{
label: 'Neil Richter',
suffix: 'noook'
}
]
}]
</script>
<template>
<UCommandPalette :groups="groups" class="flex-1 h-80">
<template #users-leading="{ index }">
<UAvatar :src="`https://i.pravatar.cc/120?img=${index}`" size="2xs" />
<template #users-leading="{ item }">
<UAvatar :src="`https://github.com/${item.suffix}.png`" size="2xs" />
</template>
<template #billing-label="{ item }">

View File

@@ -1,24 +0,0 @@
<script setup lang="ts">
const users = [
{ id: 1, label: 'Durward Reynolds' },
{ id: 2, label: 'Kenton Towne' },
{ id: 3, label: 'Therese Wunsch' },
{ id: 4, label: 'Benedict Kessler' },
{ id: 5, label: 'Katelyn Rohan' }
]
const selected = ref(users[0])
function onSelect(item: any) {
console.log(item)
}
</script>
<template>
<UCommandPalette
v-model="selected"
:groups="[{ id: 'users', items: users }]"
class="flex-1"
@update:model-value="onSelect"
/>
</template>

View File

@@ -1,25 +0,0 @@
<script setup lang="ts">
const users = [
{ id: 1, label: 'Durward Reynolds' },
{ id: 2, label: 'Kenton Towne' },
{ id: 3, label: 'Therese Wunsch' },
{ id: 4, label: 'Benedict Kessler' },
{ id: 5, label: 'Katelyn Rohan' }
]
const selected = ref([users[0], users[1]])
function onSelect(items: any) {
console.log(items)
}
</script>
<template>
<UCommandPalette
v-model="selected"
multiple
:groups="[{ id: 'users', items: users }]"
class="flex-1"
@update:model-value="onSelect"
/>
</template>

View File

@@ -2,11 +2,55 @@
const open = ref(false)
const users = [
{ id: 1, label: 'Durward Reynolds' },
{ id: 2, label: 'Kenton Towne' },
{ id: 3, label: 'Therese Wunsch' },
{ id: 4, label: 'Benedict Kessler' },
{ id: 5, label: 'Katelyn Rohan' }
{
label: 'Benjamin Canac',
suffix: 'benjamincanac',
avatar: {
src: 'https://github.com/benjamincanac.png'
}
},
{
label: 'Sylvain Marroufin',
suffix: 'smarroufin',
avatar: {
src: 'https://github.com/smarroufin.png'
}
},
{
label: 'Sébastien Chopin',
suffix: 'atinux',
avatar: {
src: 'https://github.com/atinux.png'
}
},
{
label: 'Romain Hamel',
suffix: 'romhml',
avatar: {
src: 'https://github.com/romhml.png'
}
},
{
label: 'Haytham A. Salama',
suffix: 'Haythamasalama',
avatar: {
src: 'https://github.com/Haythamasalama.png'
}
},
{
label: 'Daniel Roe',
suffix: 'danielroe',
avatar: {
src: 'https://github.com/danielroe.png'
}
},
{
label: 'Neil Richter',
suffix: 'noook',
avatar: {
src: 'https://github.com/noook.png'
}
}
]
</script>
@@ -20,11 +64,7 @@ const users = [
/>
<template #content>
<UCommandPalette
close
:groups="[{ id: 'users', items: users }]"
@update:open="open = $event"
/>
<UCommandPalette close :groups="[{ id: 'users', items: users }]" @update:open="open = $event" />
</template>
</UModal>
</template>

View File

@@ -1,29 +1,36 @@
<script setup lang="ts">
const items = [{
id: '/',
label: 'Introduction',
level: 1
}, {
id: '/getting-started#whats-new-in-v3',
label: 'What\'s new in v3?',
level: 2
}, {
id: '/getting-started#radix-vue-3',
label: 'Radix Vue',
level: 3
}, {
id: '/getting-started#tailwind-css-v4',
label: 'Tailwind CSS v4',
level: 3
}, {
id: '/getting-started#tailwind-variants',
label: 'Tailwind Variants',
level: 3
}, {
id: '/getting-started/installation',
label: 'Installation',
level: 1
}]
const items = [
{
id: '/',
label: 'Introduction',
level: 1
},
{
id: '/getting-started#whats-new-in-v3',
label: 'What\'s new in v3?',
level: 2
},
{
id: '/getting-started#radix-vue-3',
label: 'Radix Vue',
level: 3
},
{
id: '/getting-started#tailwind-css-v4',
label: 'Tailwind CSS v4',
level: 3
},
{
id: '/getting-started#tailwind-variants',
label: 'Tailwind Variants',
level: 3
},
{
id: '/getting-started/installation',
label: 'Installation',
level: 1
}
]
function postFilter(searchTerm: string, items: any[]) {
// Filter only first level items if no searchTerm

View File

@@ -1,13 +1,82 @@
<script setup lang="ts">
const users = [
{ id: 1, label: 'Durward Reynolds' },
{ id: 2, label: 'Kenton Towne' },
{ id: 3, label: 'Therese Wunsch' },
{ id: 4, label: 'Benedict Kessler' },
{ id: 5, label: 'Katelyn Rohan' }
{
label: 'Benjamin Canac',
suffix: 'benjamincanac',
to: 'https://github.com/benjamincanac',
target: '_blank',
avatar: {
src: 'https://github.com/benjamincanac.png',
alt: 'benjamincanac'
}
},
{
label: 'Sylvain Marroufin',
suffix: 'smarroufin',
to: 'https://github.com/smarroufin',
target: '_blank',
avatar: {
src: 'https://github.com/smarroufin.png',
alt: 'smarroufin'
}
},
{
label: 'Sébastien Chopin',
suffix: 'atinux',
to: 'https://github.com/atinux',
target: '_blank',
avatar: {
src: 'https://github.com/atinux.png',
alt: 'atinux'
}
},
{
label: 'Romain Hamel',
suffix: 'romhml',
to: 'https://github.com/romhml',
target: '_blank',
avatar: {
src: 'https://github.com/romhml.png',
alt: 'romhml'
}
},
{
label: 'Haytham A. Salama',
suffix: 'Haythamasalama',
to: 'https://github.com/Haythamasalama',
target: '_blank',
avatar: {
src: 'https://github.com/Haythamasalama.png',
alt: 'Haythamasalama'
}
},
{
label: 'Daniel Roe',
suffix: 'danielroe',
to: 'https://github.com/danielroe',
target: '_blank',
avatar: {
src: 'https://github.com/danielroe.png',
alt: 'danielroe'
}
},
{
label: 'Neil Richter',
suffix: 'noook',
to: 'https://github.com/noook',
target: '_blank',
avatar: {
src: 'https://github.com/noook.png',
alt: 'noook'
}
}
]
const searchTerm = ref('Th')
const searchTerm = ref('')
function onSelect() {
searchTerm.value = ''
}
</script>
<template>
@@ -15,5 +84,6 @@ const searchTerm = ref('Th')
v-model:search-term="searchTerm"
:groups="[{ id: 'users', items: users }]"
class="flex-1"
@update:model-value="onSelect"
/>
</template>

View File

@@ -0,0 +1,155 @@
<script setup lang="ts">
const router = useRouter()
const groups = ref([
{
id: 'users',
label: 'Users',
items: [
{
label: 'Benjamin Canac',
suffix: 'benjamincanac',
to: 'https://github.com/benjamincanac',
target: '_blank',
avatar: {
src: 'https://github.com/benjamincanac.png',
alt: 'benjamincanac'
}
},
{
label: 'Sylvain Marroufin',
suffix: 'smarroufin',
to: 'https://github.com/smarroufin',
target: '_blank',
avatar: {
src: 'https://github.com/smarroufin.png',
alt: 'smarroufin'
}
},
{
label: 'Sébastien Chopin',
suffix: 'atinux',
to: 'https://github.com/atinux',
target: '_blank',
avatar: {
src: 'https://github.com/atinux.png',
alt: 'atinux'
}
},
{
label: 'Romain Hamel',
suffix: 'romhml',
to: 'https://github.com/romhml',
target: '_blank',
avatar: {
src: 'https://github.com/romhml.png',
alt: 'romhml'
}
},
{
label: 'Haytham A. Salama',
suffix: 'Haythamasalama',
to: 'https://github.com/Haythamasalama',
target: '_blank',
avatar: {
src: 'https://github.com/Haythamasalama.png',
alt: 'Haythamasalama'
}
},
{
label: 'Daniel Roe',
suffix: 'danielroe',
to: 'https://github.com/danielroe',
target: '_blank',
avatar: {
src: 'https://github.com/danielroe.png',
alt: 'danielroe'
}
},
{
label: 'Neil Richter',
suffix: 'noook',
to: 'https://github.com/noook',
target: '_blank',
avatar: {
src: 'https://github.com/noook.png',
alt: 'noook'
}
}
]
},
{
id: 'actions',
items: [
{
label: 'Add new file',
suffix: 'Create a new file in the current directory or workspace.',
icon: 'i-heroicons-document-plus',
kbds: [
'meta',
'N'
],
select: () => {
console.log('Add new file')
}
},
{
label: 'Add new folder',
suffix: 'Create a new folder in the current directory or workspace.',
icon: 'i-heroicons-folder-plus',
kbds: [
'meta',
'F'
],
select: () => {
console.log('Add new folder')
}
},
{
label: 'Add hashtag',
suffix: 'Add a hashtag to the current item.',
icon: 'i-heroicons-hashtag',
kbds: [
'meta',
'H'
],
select: () => {
console.log('Add hashtag')
}
},
{
label: 'Add label',
suffix: 'Add a label to the current item.',
icon: 'i-heroicons-tag',
kbds: [
'meta',
'L'
],
select: () => {
console.log('Add label')
}
}
]
}
])
function onSelect(item: any) {
if (item.select) {
item.select()
} else if (item.to) {
if (typeof item.to === 'string' && (item.target === '_blank' || item.to.startsWith('http'))) {
window.open(item.to, item.target || '_blank')
} else {
router.push(item.to)
}
}
}
</script>
<template>
<UCommandPalette
:groups="groups"
class="flex-1 h-80"
@update:model-value="onSelect"
/>
</template>

View File

@@ -18,7 +18,7 @@ const groups = computed(() => [{
</script>
<template>
<UDrawer>
<UDrawer :handle="false">
<UButton
label="Search users..."
color="neutral"
@@ -32,7 +32,7 @@ const groups = computed(() => [{
:loading="status === 'pending'"
:groups="groups"
placeholder="Search users..."
class="h-96 border-t border-[var(--ui-border)]"
class="h-80"
/>
</template>
</UDrawer>

View File

@@ -32,7 +32,7 @@ const groups = computed(() => [{
:loading="status === 'pending'"
:groups="groups"
placeholder="Search users..."
class="h-96"
class="h-80"
/>
</template>
</UModal>

View File

@@ -31,13 +31,14 @@ useSeoMeta({
titleTemplate: '%s - Nuxt UI v3',
title: page.value.navigation?.title || page.value.title,
ogTitle: `${page.value.navigation?.title || page.value.title} - Nuxt UI v3`,
description: page.value.description,
ogDescription: page.value.description
description: page.value.seo?.description || page.value.description,
ogDescription: page.value.seo?.description || page.value.description
})
defineOgImageComponent('Docs', {
headline: headline.value,
title: page.value.title
title: page.value.title,
description: page.value.seo?.description || page.value.description
})
const communityLinks = computed(() => [{

View File

@@ -1,6 +1,8 @@
---
title: CommandPalette
description: A command palette to search and execute commands with full-text search.
description: A command palette with full-text search powered by [Fuse.js](https://fusejs.io/) for efficient fuzzy matching.
seo:
description: A command palette with full-text search powered by Fuse.js for efficient fuzzy matching.
links:
- label: Combobox
icon: i-custom-radix-vue
@@ -12,11 +14,15 @@ links:
## Usage
The CommandPalette component leverages [Fuse.js](https://fusejs.io/) to provide robust and efficient fuzzy search functionality.
Use the `v-model` directive to control the value of the CommandPalette or the `default-value` prop to set the initial value when you do not need to control its state.
::tip{to="#control-selected-items"}
You can also use the `@update:model-value` event to listen to the selected item(s).
::
### Groups
When searching for a command, the groups are filtered and the matching commands are presented in order of relevance. Use the `groups` prop as an array of objects with the following properties:
The CommandPalette component filters groups and ranks matching commands by relevance as users type. It provides dynamic, instant search results for efficient command discovery. Use the `groups` prop as an array of objects with the following properties:
- `id: string`{lang="ts-type"}
- `label?: string`{lang="ts-type"}
@@ -44,48 +50,47 @@ Each group takes some `items` as an array of objects with the following properti
collapse: true
ignore:
- groups
- modelValue
- class
external:
- groups
- modelValue
class: '!p-0'
props:
modelValue: {}
groups:
- id: 'suggestions'
label: 'Suggestions'
- id: 'users'
label: 'Users'
items:
- label: 'Calendar'
icon: 'i-heroicons-calendar'
- label: 'Music'
icon: 'i-heroicons-musical-note'
- label: 'Maps'
icon: 'i-heroicons-map'
- id: 'actions'
items:
- label: 'Add new file'
suffix: 'Create a new file in the current directory or workspace.'
icon: 'i-heroicons-document-plus'
kbds:
- meta
- N
- label: 'Add new folder'
suffix: 'Create a new folder in the current directory or workspace.'
icon: 'i-heroicons-folder-plus'
kbds:
- meta
- F
- label: 'Add hashtag'
suffix: 'Add a hashtag to the current item.'
icon: 'i-heroicons-hashtag'
kbds:
- meta
- H
- label: 'Add label'
suffix: 'Add a label to the current item.'
icon: 'i-heroicons-tag'
kbds:
- meta
- L
class: 'flex-1 max-h-80'
- label: 'Benjamin Canac'
suffix: 'benjamincanac'
avatar:
src: 'https://github.com/benjamincanac.png'
- label: 'Sylvain Marroufin'
suffix: 'smarroufin'
avatar:
src: 'https://github.com/smarroufin.png'
- label: 'Sébastien Chopin'
suffix: 'atinux'
avatar:
src: 'https://github.com/atinux.png'
- label: 'Romain Hamel'
suffix: 'romhml'
avatar:
src: 'https://github.com/romhml.png'
- label: 'Haytham A. Salama'
suffix: 'Haythamasalama'
avatar:
src: 'https://github.com/Haythamasalama.png'
- label: 'Daniel Roe'
suffix: 'danielroe'
avatar:
src: 'https://github.com/danielroe.png'
- label: 'Neil Richter'
suffix: 'noook'
avatar:
src: 'https://github.com/noook.png'
class: 'flex-1'
---
::
@@ -93,6 +98,65 @@ props:
You must provide an `id` for each group otherwise the group will be ignored.
::
### Multiple
Use the `multiple` prop to allow multiple selections.
::component-code
---
collapse: true
ignore:
- groups
- modelValue
- multiple
- class
external:
- groups
- modelValue
class: '!p-0'
props:
multiple: true
modelValue: []
groups:
- id: 'users'
label: 'Users'
items:
- label: 'Benjamin Canac'
suffix: 'benjamincanac'
avatar:
src: 'https://github.com/benjamincanac.png'
- label: 'Sylvain Marroufin'
suffix: 'smarroufin'
avatar:
src: 'https://github.com/smarroufin.png'
- label: 'Sébastien Chopin'
suffix: 'atinux'
avatar:
src: 'https://github.com/atinux.png'
- label: 'Romain Hamel'
suffix: 'romhml'
avatar:
src: 'https://github.com/romhml.png'
- label: 'Haytham A. Salama'
suffix: 'Haythamasalama'
avatar:
src: 'https://github.com/Haythamasalama.png'
- label: 'Daniel Roe'
suffix: 'danielroe'
avatar:
src: 'https://github.com/danielroe.png'
- label: 'Neil Richter'
suffix: 'noook'
avatar:
src: 'https://github.com/noook.png'
class: 'flex-1'
---
::
::caution
Ensure to pass an array to the `default-value` prop or the `v-model` directive.
::
### Placeholder
Use the `placeholder` prop to change the placeholder text.
@@ -345,32 +409,18 @@ You can customize this icon globally in your `app.config.ts` under `ui.icons.clo
### Control selected item(s)
You can control the selected item by using the `default-value` prop or the `v-model` directive.
You can control the selected item by using the `default-value` prop or the `v-model` directive, by using the `select` field on each item or by using the `@update:model-value` event.
::component-example
---
collapse: true
name: 'command-palette-model-value-example'
name: 'command-palette-select-example'
class: '!p-0'
---
::
::tip
You can also use the `select` field on each item and/or the `@update:model-value` event.
::
Use the `multiple` prop to allow multiple selections.
::component-example
---
collapse: true
name: 'command-palette-model-value-multiple-example'
class: '!p-0'
---
::
::caution
Ensure to pass an array to the `default-value` prop or the `v-model` directive.
::note
This example demonstrates how to use the `@update:model-value` event to handle different selection scenarios.
::
### Control search term
@@ -385,6 +435,10 @@ class: '!p-0'
---
::
::note
This example uses the `@update:model-value` event to reset the search term when an item is selected.
::
### With fetched items
You can fetch items from an API and use them in the CommandPalette.