Command Palette for Vue

A fast, composable, unstyled command palette interface for Vue.

README

Command Palette for Vue


vue-command-palette minzip package size
vue-command-palette package version

A fast, composable, unstyled command + k interface (Command Palette) for Vue.


Preview


Preview

Concepts


Command palette interfaces are used to create a web experience where users can quickly get in charge with keyboard shortcuts, rather than using the mouse.

With macOS's Spotlight and Raycast's command palette experience in mind, vue-command-palette is designed to provide a fast, composable, unstyled command palette to your site.

Features


- 💄 Completely unstyled, but more customizable
- 🔍 Fuzzy search support to find relevant command
- ⌨️ keyboard shortcut support to bind custom keybindings to your command

Install


  1. ``` sh
  2. yarn add vue-command-palette
  3. # or
  4. pnpm add vue-command-palette
  5. ```

Usage


Then you can import the Command Compound Component in your project.

  1. ```vue
  2. <template>
  3.   <Command theme="custom">
  4.     <Command.Input placeholder="Type a command or search..." />
  5.     <Command.List>
  6.       <Command.Empty>No results found.</Command.Empty>
  7. <Command.Group heading="Letters">
  8.         <Command.Item>a</Command.Item>
  9.         <Command.Item>b</Command.Item>
  10.         <Command.Separator />
  11.         <Command.Item>c</Command.Item>
  12.       </Command.Group>
  13. <Command.Item>Apple</Command.Item>
  14.     </Command.List>
  15.   </Command>
  16. </template>
  17. <script lang="ts" setup>
  18. import { ref } from 'vue'
  19. import { Command } from 'vue-command-palette'
  20. </script>
  21. <style>
  22. // import your custom css
  23. @import '~/assets/css/custom.css';
  24. </style>
  25. ```

or in a dialog:

  1. ```vue
  2. <template>
  3.   <Command.Dialog :visible="visible" theme="custom">
  4.     <template #header>
  5.       <Command.Input placeholder="Type a command or search..." />
  6.     </template>
  7.     <template #body>
  8.       <Command.List>
  9.         <Command.Empty>No results found.</Command.Empty>
  10. <Command.Group heading="Letters">
  11.           <Command.Item>a</Command.Item>
  12.           <Command.Item>b</Command.Item>
  13.           <Command.Separator />
  14.           <Command.Item>c</Command.Item>
  15.         </Command.Group>
  16. <Command.Item>Apple</Command.Item>
  17.       </Command.List>
  18.     </template>
  19.   </Command.Dialog>
  20. </template>
  21. <script lang="ts" setup>
  22. import { ref } from 'vue'
  23. import { Command } from 'vue-command-palette'

  24. const visible = ref(false)
  25. </script>
  26. <style>
  27. // import your custom css
  28. @import '~/assets/css/custom.css';
  29. </style>
  30. ```

### Command + K or ?

Do I have to use command + K? No, it's just a convention that you can use any key binding to perform the Command Palette.

Tips, we use @vueuse/core to bind the keybindings


  1. ``` html
  2. <script lang="ts" setup>
  3.   import { watch } from 'vue'
  4.   import { useMagicKeys } from '@vueuse/core'
  5.   const keys = useMagicKeys()
  6.   const CmdK = keys['Meta+K']
  7.   watch(CmdK, (v) => {
  8.     if (v) {
  9.       console.log('Meta + K has been pressed')
  10.       // do your own logic, maybe make dialog visible
  11.     }
  12.   })
  13. </script>
  14. ```

Events


|     Name      | Description                                                           | Parameters       |
| :-----------: | --------------------------------------------------------------------- | :--------------- |
| select-item | Every time an item is being selected in Command or Command.Dialog | (item) => void |

Styling


All namespaced components have a specific data-attribute starting with command- that can be used for styling.

eg:

  1. ```css
  2. div[command-root=''] {
  3.   background: #ffffff;
  4. }
  5. ```

Animation


Command.Dialog


Command.Dialog wraped by built-in components Transition, you can customize the animation using the namecommand-dialog .


List Item Height


Animate height using the --command-list-height CSS variable.


Namespaced components


With [Namespaced components](https://vuejs.org/api/sfc-script-setup.html#using-components), You can use component tags with dots like `` to refer to components nested under object properties. This is useful when you import multiple components from a single file.

Command [command-root=""]


The root component, Passes the theme props to set your own style.

  1. ```vue
  2. <Command theme="custom">
  3.   
  4. </Command>
  5. ```

Command.Dialog [command-dialog=""]


The root component with a dialog interface, Teleport dialog tobody tag. Passes the theme props to set your own style, and visible props control whether render it.

  1. ```vue
  2. <Command.Dialog :visible="visible" theme="custom">
  3.   
  4.   <template #header></template>
  5.   <template #body></template>
  6.   <template #footer></template>
  7. </Command.Dialog>
  8. ```

data-attribute within dialog

- [command-dialog-mask] - the mask is always rendered.
- [command-dialog-wrapper] - the wrapper on top of mask.
- [command-dialog-header] - the parent of dialog header slot.
- [command-dialog-body] - the parent of dialog body slot.
- [command-dialog-footer] - the parent of dialog footer slot.

Command.Input [command-input=""]


Usually we need a input in the command palette to search sth.

  1. ```vue
  2. <Command.Input
  3.   placeholder="Type a command or search..."
  4.   v-model:value="inputValue"
  5. />
  6. ```

Command.List [command-list=""]


Contains items and groups. Animate height using the --command-list-height CSS variable.

  1. ```css
  2. [command-list] {
  3.   min-height: 300px;
  4.   height: var(--command-list-height);
  5.   max-height: 500px;
  6.   transition: height 100ms ease;
  7. }
  8. ```

  1. ```vue
  2. <Command.List>
  3.   
  4. </Command.List>
  5. ```

Command.Group [command-group=""]


Group items ([command-group-items]) together with the given heading ([command-group-heading])

  1. ```vue
  2. <Command.Group heading="Perference">
  3.   <Command.Item>Toggle Dark Mode</Command.Item>
  4.   <Command.Item>Change Language</Command.Item>
  5. </Command.Group>
  6. ```

Command.Item [command-item=""]


Passed the data-value, we use data-value to fetch the value.

  1. ```vue
  2. <Command.Item
  3.   v-for="item in items"
  4.   :data-value="item.label"
  5.   :shortcut="item.shortcut"
  6.   :perform="item.perform"
  7.   @select="(itemInfo) => console.log('selected', itemInfo)"
  8.   // the itemInfo.value is some as `data-value`
  9. >
  10.   {{ item.label }}
  11. </Command.Item>
  12. ```

Command.Separator [command-separator=""]


Usually used to distinguish between different groups

Command.Empty [command-empty=""]


Automatically renders when there are no results for the search query.

Command.Loading [command-loading=""]


Your should manually control loading

Inspiration


- cmdk - Fast, unstyled command menu React component.
- kbar - fast, portable, and extensible cmd+k interface for your site.

License