Files
ui/docs/content/4.navigation/2.command-palette.md
Benjamin Canac 6da0db0113 feat: rewrite to use app config and rework docs (#143)
Co-authored-by: Daniel Roe <daniel@roe.dev>
Co-authored-by: Sébastien Chopin <seb@nuxt.com>
2023-05-04 14:49:19 +02:00

6.1 KiB

github, headlessui
github headlessui
true
label to
Combobox https://headlessui.com/vue/combobox

Usage

Use a v-model to display a searchable and selectable list of commands.

::component-example

padding: false

#default :command-palette-example-basic{class="h-[257px]"}

#code

<script setup>
const people = [
  { id: 1, label: 'Wade Cooper' },
  { id: 2, label: 'Arlene Mccoy' },
  { id: 3, label: 'Devon Webb' },
  { id: 4, label: 'Tom Cook' },
  { id: 5, label: 'Tanya Fox' },
  { id: 6, label: 'Hellen Schmidt' },
  { id: 7, label: 'Caroline Schultz' },
  { id: 8, label: 'Mason Heaney' },
  { id: 9, label: 'Claudie Smitham' },
  { id: 10, label: 'Emil Schaefer' }
]

const selected = ref([people[3]])
</script>

<template>
  <UCommandPalette
    v-model="selected"
    multiple
    nullable
    :groups="[{ key: 'people', commands: people }]"
    :fuse="{ resultLimit: 6 }"
  />
</template>

::

You can put a CommandPalette anywhere you want but it's most commonly used inside of a modal.

::component-example #default :command-palette-example-modal

#code

<script setup>
const open = ref(false)

const people = [
  { id: 1, label: 'Wade Cooper' },
  { id: 2, label: 'Arlene Mccoy' },
  { id: 3, label: 'Devon Webb' },
  { id: 4, label: 'Tom Cook' },
  { id: 5, label: 'Tanya Fox' },
  { id: 6, label: 'Hellen Schmidt' },
  { id: 7, label: 'Caroline Schultz' },
  { id: 8, label: 'Mason Heaney' },
  { id: 9, label: 'Claudie Smitham' },
  { id: 10, label: 'Emil Schaefer' }
]

const selected = ref([])
</script>

<template>
  <div>
    <UButton label="Open" @click="open = true" />

    <UModal v-model="open">
      <UCommandPalette
        v-model="selected"
        multiple
        nullable
        :groups="[{ key: 'people', commands: people }]"
      />
    </UModal>
  </div>
</template>

::

You can pass multiple groups of commands to the component. Each group will be separated by a divider and will display a label.

Without a v-model, you can also listen on @update:model-value to navigate to a link or do something else when a command is clicked.

::component-example

padding: false

#default :command-palette-example-groups{class="h-[274px]"}

#code

<script setup>
const router = useRouter()

const commandPaletteRef = ref()

const users = [
  { id: 'benjamincanac', label: 'benjamincanac', href: 'https://github.com/benjamincanac', target: '_blank', avatar: { src: 'https://avatars.githubusercontent.com/u/739984?v=4' } },
  { id: 'Atinux', label: 'Atinux', href: 'https://github.com/Atinux', target: '_blank', avatar: { src: 'https://avatars.githubusercontent.com/u/904724?v=4' } },
  { id: 'smarroufin', label: 'smarroufin', href: 'https://github.com/smarroufin', target: '_blank', avatar: { src: 'https://avatars.githubusercontent.com/u/7547335?v=4' } }
]

const actions = [
  { id: 'new-file', label: 'Add new file', icon: 'i-heroicons-document-plus', click: () => alert('New file') },
  { id: 'new-folder', label: 'Add new folder', icon: 'i-heroicons-folder-plus', click: () => alert('New folder') },
  { id: 'hashtag', label: 'Add hashtag', icon: 'i-heroicons-hashtag', click: () => alert('Add hashtag') },
  { id: 'label', label: 'Add label', icon: 'i-heroicons-tag', click: () => alert('Add label') }
]

const groups = computed(() => commandPaletteRef.value?.query
  ? [{
      key: 'users',
      commands: users
    }]
  : [{
      key: 'recent',
      label: 'Recent searches',
      commands: users.slice(0, 1)
    }, {
      key: 'actions',
      commands: actions
    }])

function onSelect (option) {
  if (option.click) {
    option.click()
  } else if (option.to) {
    router.push(option.to)
  } else if (option.href) {
    window.open(option.href, '_blank')
  }
}
</script>

<template>
  <UCommandPalette ref="commandPaletteRef" :groups="groups" @update:model-value="onSelect" />
</template>

::

Icon

Use any icon from Iconify by setting the icon prop by using this pattern: i-{collection_name}-{icon_name}.

::component-card

padding: false baseProps: empty: null props: icon: 'i-heroicons-command-line' excludedProps:

  • icon

::

Placeholder

Use the placeholder prop to change the input placeholder

::component-card

padding: false baseProps: empty: null props: placeholder: 'Type a command...' excludedProps:

  • icon

::

Close

Use the close prop to display a close button on the right side of the input.

You can pass all the props of the Button component to customize it through the close prop or globally through ui.commandPalette.default.close.

::component-card

padding: false baseProps: empty: null props: close: icon: 'i-heroicons-x-mark-20-solid' color: 'gray' variant: 'link' padded: false excludedProps:

  • close

::

Empty

Use the empty prop to display a message when there are no results.

You can pass an object through the empty prop or globally through ui.commandPalette.default.empty. Here is the default:

::component-card

padding: false baseProps: placeholder: 'Type something to see the empty label change' props: empty: icon: 'i-heroicons-magnifying-glass-20-solid' label: "We couldn't find any items." queryLabel: "We couldn't find any items with that term. Please try again." excludedProps:

  • empty

::

Themes

Our theming system provides a lot of flexibility to customize the component. Here is some examples of what you can do.

Algolia

::component-example

padding: false

#default :command-palette-theme-algolia{class="max-h-[480px] rounded-md"} ::

::alert{icon="i-simple-icons-github" to="https://github.com/nuxtlabs/ui/blob/docs/rework/docs/components/content/themes/CommandPaletteThemeAlgolia.vue#L23"} Take a look at the component! ::

Raycast

::component-example

padding: false

#default :command-palette-theme-raycast{class="max-h-[480px] rounded-md"} ::

::alert{icon="i-simple-icons-github" to="https://github.com/nuxtlabs/ui/blob/docs/rework/docs/components/content/themes/CommandPaletteThemeRaycast.vue#L30"} Take a look at the component! ::

Props

:component-props

Preset

:component-preset