NPM Minzip Package NPM Download
A fast, composable, unstyled
Command+Kinterface (Command Palette) for Vue.
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.
TOC
- 🧩 Compound Component + Namespaced Components Design
- 💄 Completely unstyled, but more customizable
- 🔍 Fuzzy search support to find relevant command
- ⌨️ keyboard shortcut support to bind custom keybindings to your command
yarn add vue-command-palette
# or
pnpm add vue-command-paletteThen you can import the Command Compound Component in your project.
<script lang="ts" setup> import { ref } from 'vue' import { Command } from 'vue-command-palette' </script> <template> <Command theme="custom"> <Command.Input placeholder="Type a command or search..." /> <Command.List> <Command.Empty>No results found.</Command.Empty> <Command.Group heading="Letters"> <Command.Item>a</Command.Item> <Command.Item>b</Command.Item> <Command.Separator /> <Command.Item>c</Command.Item> </Command.Group> <Command.Item>Apple</Command.Item> </Command.List> </Command> </template> <style> // import your custom css @import '~/assets/css/custom.css'; </style>
or in a dialog:
<script lang="ts" setup> import { ref } from 'vue' import { Command } from 'vue-command-palette' const visible = ref(false) </script> <template> <Command.Dialog :visible="visible" theme="custom"> <template #header> <Command.Input placeholder="Type a command or search..." /> </template> <template #body> <Command.List> <Command.Empty>No results found.</Command.Empty> <Command.Group heading="Letters"> <Command.Item>a</Command.Item> <Command.Item>b</Command.Item> <Command.Separator /> <Command.Item>c</Command.Item> </Command.Group> <Command.Item>Apple</Command.Item> </Command.List> </template> </Command.Dialog> </template> <style> // import your custom css @import '~/assets/css/custom.css'; </style>
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/coreto bind the keybindings
<script lang="ts" setup> import { watch } from 'vue' import { useMagicKeys } from '@vueuse/core' const keys = useMagicKeys() const CmdK = keys['Meta+K'] watch(CmdK, (v) => { if (v) { console.log('Meta + K has been pressed') // do your own logic, maybe make dialog visible } }) </script>
| Name | Description | Parameters |
|---|---|---|
select-item |
Every time an item is being selected in Command or Command.Dialog |
(item) => void |
All namespaced components have a specific data-attribute starting with command- that can be used for styling.
eg:
div[command-root=''] { background: #ffffff; }
Command.Dialog wraped by built-in components Transition, you can customize the animation using the name command-dialog .
Animate height using the --command-list-height CSS variable.
With Namespaced components, You can use component tags with dots like <Foo.Bar> to refer to components nested under object properties. This is useful when you import multiple components from a single file.
The root component, Passes the theme props to set your own style.
<Command theme="custom"> <!-- Contains other namespaced components --> </Command>
The root component with a dialog interface, Teleport dialog to body tag. Passes the theme props to set your own style, and visible props control whether render it.
<Command.Dialog :visible="visible" theme="custom"> <!-- Contains other namespaced components --> <template #header></template> <template #body></template> <template #footer></template> </Command.Dialog>
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.
Usually we need a input in the command palette to search sth.
<Command.Input placeholder="Type a command or search..." v-model:value="inputValue" />
Contains items and groups. Animate height using the --command-list-height CSS variable.
[command-list] { min-height: 300px; height: var(--command-list-height); max-height: 500px; transition: height 100ms ease; }
<Command.List> <!-- Contains Group, Item, Empty --> </Command.List>
Group items ([command-group-items]) together with the given heading ([command-group-heading])
<Command.Group heading="Perference"> <Command.Item>Toggle Dark Mode</Command.Item> <Command.Item>Change Language</Command.Item> </Command.Group>
Passed the data-value, we use data-value to fetch the value.
<Command.Item v-for="item in items" :data-value="item.label" :shortcut="item.shortcut" :perform="item.perform" @select="(itemInfo) => console.log('selected', itemInfo)" // the itemInfo.value is some as `data-value` > {{ item.label }} </Command.Item>
Usually used to distinguish between different groups
Automatically renders when there are no results for the search query.
Your should manually control loading
- cmdk - Fast, unstyled command menu React component.
- kbar - fast, portable, and extensible cmd+k interface for your site.
MIT @xiaoluoboding