#Command
Fast, composable, unstyled command menu for Vue.
#Component Features
- ⚡ Fast & Responsive: Built on top of Radix Vue for ultimate interactive performance.
- 🧩 Highly Composable: Composed of multiple small components, flexible for various business scenarios.
- 🎨 Unstyled by Default: Provides a basic skeleton, easily customizable via Tailwind CSS.
- ⌨️ Keyboard Navigation: Fully accessible via keyboard, offering a smooth keyboard operation experience.
- 📋 Nested Support: Supports sub-commands and hierarchical navigation for complex command trees.
#Basic Usage
<script setup lang="ts">
import {
BrCommand,
BrCommandEmpty,
BrCommandGroup,
BrCommandInput,
BrCommandItem,
BrCommandList,
BrCommandSeparator,
BrCommandShortcut,
} from '@breezeui/vue'
</script>
<template>
<BrCommand class="rounded-lg border shadow-md max-w-[450px]">
<BrCommandInput placeholder="Type a command or search..." />
<BrCommandList>
<BrCommandEmpty>No results found.</BrCommandEmpty>
<BrCommandGroup heading="Suggestions">
<BrCommandItem value="calendar">
Calendar
</BrCommandItem>
<BrCommandItem value="search-emoji">
Search Emoji
</BrCommandItem>
<BrCommandItem value="calculator">
Calculator
</BrCommandItem>
</BrCommandGroup>
<BrCommandSeparator />
<BrCommandGroup heading="Settings">
<BrCommandItem value="profile">
Profile
<BrCommandShortcut>⌘P</BrCommandShortcut>
</BrCommandItem>
<BrCommandItem value="billing">
Billing
<BrCommandShortcut>⌘B</BrCommandShortcut>
</BrCommandItem>
<BrCommandItem value="settings">
Settings
<BrCommandShortcut>⌘S</BrCommandShortcut>
</BrCommandItem>
</BrCommandGroup>
</BrCommandList>
</BrCommand>
</template>#Dialog
You can use the BrCommandDialog component to render the command menu in a dialog.
<script setup lang="ts">
import { ref } from 'vue'
import {
BrButton,
BrCommandDialog,
BrCommandEmpty,
BrCommandGroup,
BrCommandInput,
BrCommandItem,
BrCommandList,
BrCommandSeparator,
BrCommandShortcut,
} from '@breezeui/vue'
const open = ref(false)
// Optional: Add keyboard shortcut to open the command dialog
// import { onMounted, onUnmounted } from 'vue'
// onMounted(() => {
// const down = (e: KeyboardEvent) => {
// if (e.key === 'k' && (e.metaKey || e.ctrlKey)) {
// e.preventDefault()
// open.value = !open.value
// }
// }
// document.addEventListener('keydown', down)
// onUnmounted(() => document.removeEventListener('keydown', down))
// })
</script>
<template>
<div>
<p class="text-sm text-muted-foreground mb-4">
Press <kbd class="pointer-events-none inline-flex h-5 select-none items-center gap-1 rounded border bg-muted px-1.5 font-mono text-[10px] font-medium text-muted-foreground opacity-100"><span class="text-xs">⌘</span>K</kbd> or click the button below.
</p>
<BrButton variant="outline" @click="open = true">
Open Command Dialog
</BrButton>
<BrCommandDialog v-model:open="open">
<BrCommandInput placeholder="Type a command or search..." />
<BrCommandList>
<BrCommandEmpty>No results found.</BrCommandEmpty>
<BrCommandGroup heading="Suggestions">
<BrCommandItem value="calendar">
Calendar
</BrCommandItem>
<BrCommandItem value="search-emoji">
Search Emoji
</BrCommandItem>
<BrCommandItem value="calculator">
Calculator
</BrCommandItem>
</BrCommandGroup>
<BrCommandSeparator />
<BrCommandGroup heading="Settings">
<BrCommandItem value="profile">
Profile
<BrCommandShortcut>⌘P</BrCommandShortcut>
</BrCommandItem>
<BrCommandItem value="billing">
Billing
<BrCommandShortcut>⌘B</BrCommandShortcut>
</BrCommandItem>
<BrCommandItem value="settings">
Settings
<BrCommandShortcut>⌘S</BrCommandShortcut>
</BrCommandItem>
</BrCommandGroup>
</BrCommandList>
</BrCommandDialog>
</div>
</template>#Nested Commands
You can navigate between different command groups by changing the active page.
<script setup lang="ts">
import { ref } from 'vue'
import {
BrCommand,
BrCommandEmpty,
BrCommandGroup,
BrCommandInput,
BrCommandItem,
BrCommandList,
BrCommandSeparator,
} from '@breezeui/vue'
const activePage = ref('home')
</script>
<template>
<BrCommand class="rounded-lg border shadow-md max-w-[450px]">
<BrCommandInput placeholder="Type a command or search..." />
<BrCommandList>
<BrCommandEmpty>No results found.</BrCommandEmpty>
<template v-if="activePage === 'home'">
<BrCommandGroup heading="Suggestions">
<BrCommandItem value="search-projects" @select="activePage = 'projects'">
Search Projects...
</BrCommandItem>
<BrCommandItem value="search-users" @select="activePage = 'users'">
Search Users...
</BrCommandItem>
</BrCommandGroup>
<BrCommandSeparator />
<BrCommandGroup heading="Settings">
<BrCommandItem value="profile">
Profile
</BrCommandItem>
</BrCommandGroup>
</template>
<template v-else-if="activePage === 'projects'">
<BrCommandItem value="back" @select="activePage = 'home'">
← Back
</BrCommandItem>
<BrCommandGroup heading="Projects">
<BrCommandItem value="breeze-ui">
Breeze UI
</BrCommandItem>
<BrCommandItem value="vue-app">
Vue App
</BrCommandItem>
</BrCommandGroup>
</template>
<template v-else-if="activePage === 'users'">
<BrCommandItem value="back" @select="activePage = 'home'">
← Back
</BrCommandItem>
<BrCommandGroup heading="Users">
<BrCommandItem value="admin">
Admin
</BrCommandItem>
<BrCommandItem value="guest">
Guest
</BrCommandItem>
</BrCommandGroup>
</template>
</BrCommandList>
</BrCommand>
</template>#Global Shortcut
You can bind a global keyboard shortcut to open the command dialog.
<script setup lang="ts">
import { ref, onMounted, onUnmounted } from 'vue'
import {
BrCommandDialog,
BrCommandEmpty,
BrCommandGroup,
BrCommandInput,
BrCommandItem,
BrCommandList,
BrCommandSeparator,
BrCommandShortcut,
} from '@breezeui/vue'
const open = ref(false)
const handleKeyDown = (e: KeyboardEvent) => {
if (e.key === 'k' && (e.metaKey || e.ctrlKey)) {
e.preventDefault()
open.value = !open.value
}
}
onMounted(() => {
document.addEventListener('keydown', handleKeyDown)
})
onUnmounted(() => {
document.removeEventListener('keydown', handleKeyDown)
})
</script>
<template>
<div>
<p class="text-sm text-muted-foreground mb-4">
Press <kbd class="pointer-events-none inline-flex h-5 select-none items-center gap-1 rounded border bg-muted px-1.5 font-mono text-[10px] font-medium text-muted-foreground opacity-100"><span class="text-xs">⌘</span>K</kbd> to open the command dialog.
</p>
<BrCommandDialog v-model:open="open">
<BrCommandInput placeholder="Type a command or search..." />
<BrCommandList>
<BrCommandEmpty>No results found.</BrCommandEmpty>
<BrCommandGroup heading="Suggestions">
<BrCommandItem value="calendar">
Calendar
</BrCommandItem>
<BrCommandItem value="search-emoji">
Search Emoji
</BrCommandItem>
<BrCommandItem value="calculator">
Calculator
</BrCommandItem>
</BrCommandGroup>
<BrCommandSeparator />
<BrCommandGroup heading="Settings">
<BrCommandItem value="profile">
Profile
<BrCommandShortcut>⌘P</BrCommandShortcut>
</BrCommandItem>
<BrCommandItem value="billing">
Billing
<BrCommandShortcut>⌘B</BrCommandShortcut>
</BrCommandItem>
<BrCommandItem value="settings">
Settings
<BrCommandShortcut>⌘S</BrCommandShortcut>
</BrCommandItem>
</BrCommandGroup>
</BrCommandList>
</BrCommandDialog>
</div>
</template>#API
#Command Props
| Name | Type | Default | Description |
|---|---|---|---|
| open | boolean | true | The open state of the command menu. |
| modelValue | string | '' | The value of the selected item. |
| filterFunction | (val: any[], search: string) => any[] | - | Custom filter function. |
#CommandInput Props
| Name | Type | Default | Description |
|---|---|---|---|
| value | string | '' | The search value. |
#CommandItem Props
| Name | Type | Default | Description |
|---|---|---|---|
| value | string | - | The value of the item. |
| disabled | boolean | false | Whether the item is disabled. |
#CommandGroup Props
| Name | Type | Default | Description |
|---|---|---|---|
| heading | string | - | The heading of the group. |
#CommandDialog Props
| Name | Type | Default | Description |
|---|---|---|---|
| open | boolean | false | The open state of the dialog. |