ドロップダウンメニュー
使用法
DropdownMenuのデフォルトスロットにあるButtonまたはその他のコンポーネントを使用します。
<script setup lang="ts">
import type { DropdownMenuItem } from '@nuxt/ui'
const items = ref<DropdownMenuItem[][]>([
[
{
label: 'Benjamin',
avatar: {
src: 'https://github.com/benjamincanac.png',
loading: 'lazy'
},
type: 'label'
}
],
[
{
label: 'Profile',
icon: 'i-lucide-user'
},
{
label: 'Billing',
icon: 'i-lucide-credit-card'
},
{
label: 'Settings',
icon: 'i-lucide-cog',
kbds: [',']
},
{
label: 'Keyboard shortcuts',
icon: 'i-lucide-monitor'
}
],
[
{
label: 'Team',
icon: 'i-lucide-users',
filter: {
placeholder: 'Search members...'
},
children: [
[
{
label: 'benjamincanac',
avatar: {
src: 'https://github.com/benjamincanac.png',
loading: 'lazy'
}
},
{
label: 'HugoRCD',
avatar: {
src: 'https://github.com/HugoRCD.png',
loading: 'lazy'
}
},
{
label: 'atinux',
avatar: {
src: 'https://github.com/atinux.png',
loading: 'lazy'
}
},
{
label: 'romhml',
avatar: {
src: 'https://github.com/romhml.png',
loading: 'lazy'
}
},
{
label: 'sandros94',
avatar: {
src: 'https://github.com/sandros94.png',
loading: 'lazy'
}
},
{
label: 'J-Michalek',
avatar: {
src: 'https://github.com/J-Michalek.png',
loading: 'lazy'
}
},
{
label: 'hywax',
avatar: {
src: 'https://github.com/hywax.png',
loading: 'lazy'
}
}
]
]
},
{
label: 'Invite users',
icon: 'i-lucide-user-plus',
children: [
[
{
label: 'Email',
icon: 'i-lucide-mail'
},
{
label: 'Message',
icon: 'i-lucide-message-square'
}
],
[
{
label: 'More',
icon: 'i-lucide-circle-plus',
children: [
{
label: 'Import from Slack',
icon: 'i-simple-icons-slack',
to: 'https://slack.com',
target: '_blank'
},
{
label: 'Import from Trello',
icon: 'i-simple-icons-trello'
},
{
label: 'Import from Asana',
icon: 'i-simple-icons-asana'
}
]
}
]
]
},
{
label: 'New team',
icon: 'i-lucide-plus',
kbds: ['meta', 'n']
}
],
[
{
label: 'GitHub',
icon: 'i-simple-icons-github',
to: 'https://github.com/nuxt/ui',
target: '_blank'
},
{
label: 'Support',
icon: 'i-lucide-life-buoy',
to: '/docs/components/dropdown-menu'
},
{
label: 'API',
icon: 'i-lucide-cloud',
disabled: true
}
],
[
{
label: 'Logout',
icon: 'i-lucide-log-out',
color: 'error',
kbds: ['shift', 'meta', 'q']
}
]
])
</script>
<template>
<UDropdownMenu :items="items">
<UButton icon="i-lucide-menu" color="neutral" variant="outline" />
</UDropdownMenu>
</template><script setup lang="ts">
import { ref } from 'vue'
import type { DropdownMenuItem } from '@nuxt/ui'
const items = ref<DropdownMenuItem[][]>([
[
{
label: 'Benjamin',
avatar: {
src: 'https://github.com/benjamincanac.png',
loading: 'lazy'
},
type: 'label'
}
],
[
{
label: 'Profile',
icon: 'i-lucide-user'
},
{
label: 'Billing',
icon: 'i-lucide-credit-card'
},
{
label: 'Settings',
icon: 'i-lucide-cog',
kbds: [',']
},
{
label: 'Keyboard shortcuts',
icon: 'i-lucide-monitor'
}
],
[
{
label: 'Team',
icon: 'i-lucide-users',
filter: {
placeholder: 'Search members...'
},
children: [
[
{
label: 'benjamincanac',
avatar: {
src: 'https://github.com/benjamincanac.png',
loading: 'lazy'
}
},
{
label: 'HugoRCD',
avatar: {
src: 'https://github.com/HugoRCD.png',
loading: 'lazy'
}
},
{
label: 'atinux',
avatar: {
src: 'https://github.com/atinux.png',
loading: 'lazy'
}
},
{
label: 'romhml',
avatar: {
src: 'https://github.com/romhml.png',
loading: 'lazy'
}
},
{
label: 'sandros94',
avatar: {
src: 'https://github.com/sandros94.png',
loading: 'lazy'
}
},
{
label: 'J-Michalek',
avatar: {
src: 'https://github.com/J-Michalek.png',
loading: 'lazy'
}
},
{
label: 'hywax',
avatar: {
src: 'https://github.com/hywax.png',
loading: 'lazy'
}
}
]
]
},
{
label: 'Invite users',
icon: 'i-lucide-user-plus',
children: [
[
{
label: 'Email',
icon: 'i-lucide-mail'
},
{
label: 'Message',
icon: 'i-lucide-message-square'
}
],
[
{
label: 'More',
icon: 'i-lucide-circle-plus',
children: [
{
label: 'Import from Slack',
icon: 'i-simple-icons-slack',
to: 'https://slack.com',
target: '_blank'
},
{
label: 'Import from Trello',
icon: 'i-simple-icons-trello'
},
{
label: 'Import from Asana',
icon: 'i-simple-icons-asana'
}
]
}
]
]
},
{
label: 'New team',
icon: 'i-lucide-plus',
kbds: ['meta', 'n']
}
],
[
{
label: 'GitHub',
icon: 'i-simple-icons-github',
to: 'https://github.com/nuxt/ui',
target: '_blank'
},
{
label: 'Support',
icon: 'i-lucide-life-buoy',
to: '/docs/components/dropdown-menu'
},
{
label: 'API',
icon: 'i-lucide-cloud',
disabled: true
}
],
[
{
label: 'Logout',
icon: 'i-lucide-log-out',
color: 'error',
kbds: ['shift', 'meta', 'q']
}
]
])
</script>
<template>
<UDropdownMenu :items="items">
<UButton icon="i-lucide-menu" color="neutral" variant="outline" />
</UDropdownMenu>
</template>アイテム
itemsプロパティを次のプロパティを持つオブジェクトの配列として使用します。
label?: stringicon?: stringavatar?: AvatarPropskbds?: string[] | KbdProps[]type?: "link" | "label" | "separator" | "checkbox"color?: "error" | "primary" | "secondary" | "success" | "info" | "warning" | "neutral"checked?: booleandisabled?: booleanslot?: string- ph156{lang="ts-type"}
onUpdateChecked?: (checked: boolean) => voidchildren?: DropdownMenuItem[] | DropdownMenuItem[][]filter?: boolean | InputPropsfilterFields?: string[]ignoreFilter?: booleanclass?: anyui?: { item?: ClassNameValue, label?: ClassNameValue, separator?: ClassNameValue, itemLeadingIcon?: ClassNameValue, itemLeadingAvatarSize?: ClassNameValue, itemLeadingAvatar?: ClassNameValue, itemLabel?: ClassNameValue, itemLabelExternalIcon?: ClassNameValue, itemTrailing?: ClassNameValue, itemTrailingIcon?: ClassNameValue, itemTrailingKbds?: ClassNameValue, itemTrailingKbdsSize?: ClassNameValue }
Linkコンポーネントから、to、targetなどの任意のプロパティを渡すことができます。
<script setup lang="ts">
import type { DropdownMenuItem } from '@nuxt/ui'
const items = ref<DropdownMenuItem[][]>([
[
{
label: 'Benjamin',
avatar: {
src: 'https://github.com/benjamincanac.png',
loading: 'lazy'
},
type: 'label'
}
],
[
{
label: 'Profile',
icon: 'i-lucide-user'
},
{
label: 'Billing',
icon: 'i-lucide-credit-card'
},
{
label: 'Settings',
icon: 'i-lucide-cog',
kbds: [',']
},
{
label: 'Keyboard shortcuts',
icon: 'i-lucide-monitor'
}
],
[
{
label: 'Team',
icon: 'i-lucide-users'
},
{
label: 'Invite users',
icon: 'i-lucide-user-plus',
children: [
[
{
label: 'Email',
icon: 'i-lucide-mail'
},
{
label: 'Message',
icon: 'i-lucide-message-square'
}
],
[
{
label: 'More',
icon: 'i-lucide-circle-plus',
children: [
{
label: 'Import from Slack',
icon: 'i-simple-icons-slack',
to: 'https://slack.com',
target: '_blank'
},
{
label: 'Import from Trello',
icon: 'i-simple-icons-trello'
},
{
label: 'Import from Asana',
icon: 'i-simple-icons-asana'
}
]
}
]
]
},
{
label: 'New team',
icon: 'i-lucide-plus',
kbds: ['meta', 'n']
}
],
[
{
label: 'GitHub',
icon: 'i-simple-icons-github',
to: 'https://github.com/nuxt/ui',
target: '_blank'
},
{
label: 'Support',
icon: 'i-lucide-life-buoy',
to: '/docs/components/dropdown-menu'
},
{
label: 'API',
icon: 'i-lucide-cloud',
disabled: true
}
],
[
{
label: 'Logout',
icon: 'i-lucide-log-out',
kbds: ['shift', 'meta', 'q']
}
]
])
</script>
<template>
<UDropdownMenu
:items="items"
:ui="{
content: 'w-48'
}"
>
<UButton icon="i-lucide-menu" color="neutral" variant="outline" />
</UDropdownMenu>
</template><script setup lang="ts">
import { ref } from 'vue'
import type { DropdownMenuItem } from '@nuxt/ui'
const items = ref<DropdownMenuItem[][]>([
[
{
label: 'Benjamin',
avatar: {
src: 'https://github.com/benjamincanac.png',
loading: 'lazy'
},
type: 'label'
}
],
[
{
label: 'Profile',
icon: 'i-lucide-user'
},
{
label: 'Billing',
icon: 'i-lucide-credit-card'
},
{
label: 'Settings',
icon: 'i-lucide-cog',
kbds: [',']
},
{
label: 'Keyboard shortcuts',
icon: 'i-lucide-monitor'
}
],
[
{
label: 'Team',
icon: 'i-lucide-users'
},
{
label: 'Invite users',
icon: 'i-lucide-user-plus',
children: [
[
{
label: 'Email',
icon: 'i-lucide-mail'
},
{
label: 'Message',
icon: 'i-lucide-message-square'
}
],
[
{
label: 'More',
icon: 'i-lucide-circle-plus',
children: [
{
label: 'Import from Slack',
icon: 'i-simple-icons-slack',
to: 'https://slack.com',
target: '_blank'
},
{
label: 'Import from Trello',
icon: 'i-simple-icons-trello'
},
{
label: 'Import from Asana',
icon: 'i-simple-icons-asana'
}
]
}
]
]
},
{
label: 'New team',
icon: 'i-lucide-plus',
kbds: ['meta', 'n']
}
],
[
{
label: 'GitHub',
icon: 'i-simple-icons-github',
to: 'https://github.com/nuxt/ui',
target: '_blank'
},
{
label: 'Support',
icon: 'i-lucide-life-buoy',
to: '/docs/components/dropdown-menu'
},
{
label: 'API',
icon: 'i-lucide-cloud',
disabled: true
}
],
[
{
label: 'Logout',
icon: 'i-lucide-log-out',
kbds: ['shift', 'meta', 'q']
}
]
])
</script>
<template>
<UDropdownMenu
:items="items"
:ui="{
content: 'w-48'
}"
>
<UButton icon="i-lucide-menu" color="neutral" variant="outline" />
</UDropdownMenu>
</template>itemsプロパティに配列の配列を渡して、項目の分離グループを作成することもできます。itemsプロパティと同じプロパティを持つオブジェクトのchildren配列を取り、open、defaultOpen、contentプロパティを使用して制御できるネストされたメニューを作成できます。コンテンツ
contentプロパティを使用して、DropdownMenuコンテンツのレンダリング方法を制御します。例えば、alignやsideです。
<script setup lang="ts">
import type { DropdownMenuItem } from '@nuxt/ui'
const items = ref<DropdownMenuItem[]>([
{
label: 'Profile',
icon: 'i-lucide-user'
},
{
label: 'Billing',
icon: 'i-lucide-credit-card'
},
{
label: 'Settings',
icon: 'i-lucide-cog'
}
])
</script>
<template>
<UDropdownMenu
:items="items"
:content="{
align: 'start',
side: 'bottom',
sideOffset: 8
}"
:ui="{
content: 'w-48'
}"
>
<UButton label="Open" icon="i-lucide-menu" color="neutral" variant="outline" />
</UDropdownMenu>
</template><script setup lang="ts">
import { ref } from 'vue'
import type { DropdownMenuItem } from '@nuxt/ui'
const items = ref<DropdownMenuItem[]>([
{
label: 'Profile',
icon: 'i-lucide-user'
},
{
label: 'Billing',
icon: 'i-lucide-credit-card'
},
{
label: 'Settings',
icon: 'i-lucide-cog'
}
])
</script>
<template>
<UDropdownMenu
:items="items"
:content="{
align: 'start',
side: 'bottom',
sideOffset: 8
}"
:ui="{
content: 'w-48'
}"
>
<UButton label="Open" icon="i-lucide-menu" color="neutral" variant="outline" />
</UDropdownMenu>
</template>フィルター badge{label="4.6+" class="align-text-top"}
filterプロパティを使用して、DropdownMenu内にフィルター入力を表示します。デフォルトはfalseです。
Inputコンポーネントの任意のプロパティを渡してカスタマイズできます。
<script setup lang="ts">
import type { DropdownMenuItem } from '@nuxt/ui'
const items = ref<DropdownMenuItem[]>([
{
label: 'Profile',
icon: 'i-lucide-user'
},
{
label: 'Billing',
icon: 'i-lucide-credit-card'
},
{
label: 'Settings',
icon: 'i-lucide-cog'
},
{
label: 'Team',
icon: 'i-lucide-users'
},
{
label: 'Invite users',
icon: 'i-lucide-user-plus'
},
{
label: 'New team',
icon: 'i-lucide-plus'
}
])
</script>
<template>
<UDropdownMenu
:filter="{
icon: 'i-lucide-search'
}"
:items="items"
:content="{
align: 'start'
}"
:ui="{
content: 'w-48'
}"
>
<UButton label="Open" icon="i-lucide-menu" color="neutral" variant="outline" />
</UDropdownMenu>
</template><script setup lang="ts">
import { ref } from 'vue'
import type { DropdownMenuItem } from '@nuxt/ui'
const items = ref<DropdownMenuItem[]>([
{
label: 'Profile',
icon: 'i-lucide-user'
},
{
label: 'Billing',
icon: 'i-lucide-credit-card'
},
{
label: 'Settings',
icon: 'i-lucide-cog'
},
{
label: 'Team',
icon: 'i-lucide-users'
},
{
label: 'Invite users',
icon: 'i-lucide-user-plus'
},
{
label: 'New team',
icon: 'i-lucide-plus'
}
])
</script>
<template>
<UDropdownMenu
:filter="{
icon: 'i-lucide-search'
}"
:items="items"
:content="{
align: 'start'
}"
:ui="{
content: 'w-48'
}"
>
<UButton label="Open" icon="i-lucide-menu" color="neutral" variant="outline" />
</UDropdownMenu>
</template>Arrow
arrowプロパティを使用して、DropdownMenuに矢印を表示します。
<script setup lang="ts">
import type { DropdownMenuItem } from '@nuxt/ui'
const items = ref<DropdownMenuItem[]>([
{
label: 'Profile',
icon: 'i-lucide-user'
},
{
label: 'Billing',
icon: 'i-lucide-credit-card'
},
{
label: 'Settings',
icon: 'i-lucide-cog'
}
])
</script>
<template>
<UDropdownMenu
arrow
:items="items"
:ui="{
content: 'w-48'
}"
>
<UButton label="Open" icon="i-lucide-menu" color="neutral" variant="outline" />
</UDropdownMenu>
</template><script setup lang="ts">
import { ref } from 'vue'
import type { DropdownMenuItem } from '@nuxt/ui'
const items = ref<DropdownMenuItem[]>([
{
label: 'Profile',
icon: 'i-lucide-user'
},
{
label: 'Billing',
icon: 'i-lucide-credit-card'
},
{
label: 'Settings',
icon: 'i-lucide-cog'
}
])
</script>
<template>
<UDropdownMenu
arrow
:items="items"
:ui="{
content: 'w-48'
}"
>
<UButton label="Open" icon="i-lucide-menu" color="neutral" variant="outline" />
</UDropdownMenu>
</template>サイズ
DropdownMenuのサイズを制御するには、sizeプロパティを使用します。
<script setup lang="ts">
import type { DropdownMenuItem } from '@nuxt/ui'
const items = ref<DropdownMenuItem[]>([
{
label: 'Profile',
icon: 'i-lucide-user'
},
{
label: 'Billing',
icon: 'i-lucide-credit-card'
},
{
label: 'Settings',
icon: 'i-lucide-cog'
}
])
</script>
<template>
<UDropdownMenu
size="xl"
:items="items"
:content="{
align: 'start'
}"
:ui="{
content: 'w-48'
}"
>
<UButton size="xl" label="Open" icon="i-lucide-menu" color="neutral" variant="outline" />
</UDropdownMenu>
</template><script setup lang="ts">
import { ref } from 'vue'
import type { DropdownMenuItem } from '@nuxt/ui'
const items = ref<DropdownMenuItem[]>([
{
label: 'Profile',
icon: 'i-lucide-user'
},
{
label: 'Billing',
icon: 'i-lucide-credit-card'
},
{
label: 'Settings',
icon: 'i-lucide-cog'
}
])
</script>
<template>
<UDropdownMenu
size="xl"
:items="items"
:content="{
align: 'start'
}"
:ui="{
content: 'w-48'
}"
>
<UButton size="xl" label="Open" icon="i-lucide-menu" color="neutral" variant="outline" />
</UDropdownMenu>
</template>sizeプロパティはButtonにプロキシされません。自分で設定する必要があります。Modal
modalプロパティを使用して、DropdownMenuが外部コンテンツとのインタラクションをブロックするかどうかを制御します。デフォルトはtrueです。
<script setup lang="ts">
import type { DropdownMenuItem } from '@nuxt/ui'
const items = ref<DropdownMenuItem[]>([
{
label: 'Profile',
icon: 'i-lucide-user'
},
{
label: 'Billing',
icon: 'i-lucide-credit-card'
},
{
label: 'Settings',
icon: 'i-lucide-cog'
}
])
</script>
<template>
<UDropdownMenu
:modal="false"
:items="items"
:ui="{
content: 'w-48'
}"
>
<UButton label="Open" icon="i-lucide-menu" color="neutral" variant="outline" />
</UDropdownMenu>
</template><script setup lang="ts">
import { ref } from 'vue'
import type { DropdownMenuItem } from '@nuxt/ui'
const items = ref<DropdownMenuItem[]>([
{
label: 'Profile',
icon: 'i-lucide-user'
},
{
label: 'Billing',
icon: 'i-lucide-credit-card'
},
{
label: 'Settings',
icon: 'i-lucide-cog'
}
])
</script>
<template>
<UDropdownMenu
:modal="false"
:items="items"
:ui="{
content: 'w-48'
}"
>
<UButton label="Open" icon="i-lucide-menu" color="neutral" variant="outline" />
</UDropdownMenu>
</template>無効
disabledプロパティを使用してDropdownMenuを無効にします。
<script setup lang="ts">
import type { DropdownMenuItem } from '@nuxt/ui'
const items = ref<DropdownMenuItem[]>([
{
label: 'Profile',
icon: 'i-lucide-user'
},
{
label: 'Billing',
icon: 'i-lucide-credit-card'
},
{
label: 'Settings',
icon: 'i-lucide-cog'
}
])
</script>
<template>
<UDropdownMenu
disabled
:items="items"
:ui="{
content: 'w-48'
}"
>
<UButton label="Open" icon="i-lucide-menu" color="neutral" variant="outline" />
</UDropdownMenu>
</template><script setup lang="ts">
import { ref } from 'vue'
import type { DropdownMenuItem } from '@nuxt/ui'
const items = ref<DropdownMenuItem[]>([
{
label: 'Profile',
icon: 'i-lucide-user'
},
{
label: 'Billing',
icon: 'i-lucide-credit-card'
},
{
label: 'Settings',
icon: 'i-lucide-cog'
}
])
</script>
<template>
<UDropdownMenu
disabled
:items="items"
:ui="{
content: 'w-48'
}"
>
<UButton label="Open" icon="i-lucide-menu" color="neutral" variant="outline" />
</UDropdownMenu>
</template>例
チェックボックス項目付き
checkboxでtypeプロパティを使用し、checked/onUpdateCheckedプロパティを使用して項目のチェック状態を制御できます。
<script setup lang="ts">
import type { DropdownMenuItem } from '@nuxt/ui'
const showBookmarks = ref(true)
const showHistory = ref(false)
const showDownloads = ref(false)
const items = computed(() => [{
label: 'Interface',
icon: 'i-lucide-app-window',
type: 'label' as const
}, {
type: 'separator' as const
}, {
label: 'Show Bookmarks',
icon: 'i-lucide-bookmark',
type: 'checkbox' as const,
checked: showBookmarks.value,
onUpdateChecked(checked: boolean) {
showBookmarks.value = checked
},
onSelect(e: Event) {
e.preventDefault()
}
}, {
label: 'Show History',
icon: 'i-lucide-clock',
type: 'checkbox' as const,
checked: showHistory.value,
onUpdateChecked(checked: boolean) {
showHistory.value = checked
}
}, {
label: 'Show Downloads',
icon: 'i-lucide-download',
type: 'checkbox' as const,
checked: showDownloads.value,
onUpdateChecked(checked: boolean) {
showDownloads.value = checked
}
}] satisfies DropdownMenuItem[])
</script>
<template>
<UDropdownMenu :items="items" :content="{ align: 'start' }" :ui="{ content: 'w-48' }">
<UButton label="Open" color="neutral" variant="outline" icon="i-lucide-menu" />
</UDropdownMenu>
</template>
<script setup lang="ts">
import { ref, computed } from 'vue'
import type { DropdownMenuItem } from '@nuxt/ui'
const showBookmarks = ref(true)
const showHistory = ref(false)
const showDownloads = ref(false)
const items = computed(() => [{
label: 'Interface',
icon: 'i-lucide-app-window',
type: 'label' as const
}, {
type: 'separator' as const
}, {
label: 'Show Bookmarks',
icon: 'i-lucide-bookmark',
type: 'checkbox' as const,
checked: showBookmarks.value,
onUpdateChecked(checked: boolean) {
showBookmarks.value = checked
},
onSelect(e: Event) {
e.preventDefault()
}
}, {
label: 'Show History',
icon: 'i-lucide-clock',
type: 'checkbox' as const,
checked: showHistory.value,
onUpdateChecked(checked: boolean) {
showHistory.value = checked
}
}, {
label: 'Show Downloads',
icon: 'i-lucide-download',
type: 'checkbox' as const,
checked: showDownloads.value,
onUpdateChecked(checked: boolean) {
showDownloads.value = checked
}
}] satisfies DropdownMenuItem[])
</script>
<template>
<UDropdownMenu :items="items" :content="{ align: 'start' }" :ui="{ content: 'w-48' }">
<UButton label="Open" color="neutral" variant="outline" icon="i-lucide-menu" />
</UDropdownMenu>
</template>
checked状態に対する反応性を確保するには、items配列をcomputed内でラップすることをお勧めします。カラーアイテム付き
colorプロパティを使用して、特定のアイテムを色でハイライトできます。
<script setup lang="ts">
import type { DropdownMenuItem } from '@nuxt/ui'
const items: DropdownMenuItem[][] = [
[
{
label: 'View',
icon: 'i-lucide-eye'
},
{
label: 'Copy',
icon: 'i-lucide-copy'
},
{
label: 'Edit',
icon: 'i-lucide-pencil'
}
],
[
{
label: 'Delete',
color: 'error',
icon: 'i-lucide-trash'
}
]
]
</script>
<template>
<UDropdownMenu :items="items" :ui="{ content: 'w-48' }">
<UButton label="Open" color="neutral" variant="outline" icon="i-lucide-menu" />
</UDropdownMenu>
</template>
フィルター項目付き:badge{label="4.6+" class="align-text-top"}
childrenを持つアイテムのfilterプロパティを使用して、サブメニュー内にフィルター入力を表示できます。
<script setup lang="ts">
import type { DropdownMenuItem } from '@nuxt/ui'
const items: DropdownMenuItem[][] = [[{
label: 'Profile',
icon: 'i-lucide-user'
}, {
label: 'Billing',
icon: 'i-lucide-credit-card'
}, {
label: 'Settings',
icon: 'i-lucide-cog'
}], [{
label: 'Team',
icon: 'i-lucide-users',
filter: {
placeholder: 'Search members...'
},
children: [
{
label: 'benjamincanac',
avatar: { src: 'https://github.com/benjamincanac.png', loading: 'lazy' as const }
},
{
label: 'HugoRCD',
avatar: { src: 'https://github.com/HugoRCD.png', loading: 'lazy' as const }
},
{
label: 'atinux',
avatar: { src: 'https://github.com/atinux.png', loading: 'lazy' as const }
},
{
label: 'romhml',
avatar: { src: 'https://github.com/romhml.png', loading: 'lazy' as const }
},
{
label: 'sandros94',
avatar: { src: 'https://github.com/sandros94.png', loading: 'lazy' as const }
},
{
label: 'J-Michalek',
avatar: { src: 'https://github.com/J-Michalek.png', loading: 'lazy' as const }
},
{
label: 'hywax',
avatar: { src: 'https://github.com/hywax.png', loading: 'lazy' as const }
}
]
}, {
label: 'Invite users',
icon: 'i-lucide-user-plus',
children: [{
label: 'Invite by email',
icon: 'i-lucide-mail'
}, {
label: 'Invite by link',
icon: 'i-lucide-link'
}, {
label: 'Invite by SMS',
icon: 'i-lucide-message-square'
}, {
label: 'Invite by WhatsApp',
icon: 'i-simple-icons-whatsapp'
}]
}, {
label: 'New team',
icon: 'i-lucide-plus'
}]]
</script>
<template>
<UDropdownMenu :items="items" :content="{ align: 'start' }" :ui="{ content: 'w-48' }">
<UButton label="Open" color="neutral" variant="outline" icon="i-lucide-menu" />
</UDropdownMenu>
</template>
Controlオープンステート
オープン状態はdefault-openプロパティまたはv-model:openディレクティブを使用して制御できます。
<script setup lang="ts">
import type { DropdownMenuItem } from '@nuxt/ui'
const open = ref(false)
defineShortcuts({
o: () => open.value = !open.value
})
const items: DropdownMenuItem[] = [
{
label: 'Profile',
icon: 'i-lucide-user'
}, {
label: 'Billing',
icon: 'i-lucide-credit-card'
}, {
label: 'Settings',
icon: 'i-lucide-cog'
}
]
</script>
<template>
<UDropdownMenu v-model:open="open" :items="items" :ui="{ content: 'w-48' }">
<UButton label="Open" color="neutral" variant="outline" icon="i-lucide-menu" />
</UDropdownMenu>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import type { DropdownMenuItem } from '@nuxt/ui'
const open = ref(false)
defineShortcuts({
o: () => open.value = !open.value
})
const items: DropdownMenuItem[] = [
{
label: 'Profile',
icon: 'i-lucide-user'
}, {
label: 'Billing',
icon: 'i-lucide-credit-card'
}, {
label: 'Settings',
icon: 'i-lucide-cog'
}
]
</script>
<template>
<UDropdownMenu v-model:open="open" :items="items" :ui="{ content: 'w-48' }">
<UButton label="Open" color="neutral" variant="outline" icon="i-lucide-menu" />
</UDropdownMenu>
</template>
defineShortcutsを活用して、kbd{value="O"}を押してDropdownMenuを切り替えることができます。カスタムスロット付き
slotプロパティを使用して、特定の項目をカスタマイズします。
以下のスロットにアクセスできます:
#{{ item.slot }}#{{ item.slot }}-leading#{{ item.slot }}-label#{{ item.slot }}-trailing
<script setup lang="ts">
import type { DropdownMenuItem } from '@nuxt/ui'
const items = [
{
label: 'Profile',
icon: 'i-lucide-user',
slot: 'profile' as const
}, {
label: 'Billing',
icon: 'i-lucide-credit-card'
}, {
label: 'Settings',
icon: 'i-lucide-cog'
}
] satisfies DropdownMenuItem[]
</script>
<template>
<UDropdownMenu :items="items" :ui="{ content: 'w-48' }">
<UButton label="Open" color="neutral" variant="outline" icon="i-lucide-menu" />
<template #profile-trailing>
<UIcon name="i-lucide-badge-check" class="shrink-0 size-5 text-primary" />
</template>
</UDropdownMenu>
</template>
アイテムのスイッチ付き
slotプロパティを#{{ slot }}-trailingスロットとともに使用して、アイテム内のSwitchをレンダリングできます。
<script setup lang="ts">
import type { DropdownMenuItem } from '@nuxt/ui'
const showBookmarks = ref(true)
const showHistory = ref(false)
const showDownloads = ref(false)
const items = computed(() => [{
label: 'Show Bookmarks',
icon: 'i-lucide-bookmark',
slot: 'switch' as const,
checked: showBookmarks.value,
onSelect(e: Event) {
e.preventDefault()
showBookmarks.value = !showBookmarks.value
}
}, {
label: 'Show History',
icon: 'i-lucide-clock',
slot: 'switch' as const,
checked: showHistory.value,
onSelect(e: Event) {
e.preventDefault()
showHistory.value = !showHistory.value
}
}, {
label: 'Show Downloads',
icon: 'i-lucide-download',
slot: 'switch' as const,
checked: showDownloads.value,
onSelect(e: Event) {
e.preventDefault()
showDownloads.value = !showDownloads.value
}
}] satisfies DropdownMenuItem[])
</script>
<template>
<UDropdownMenu :items="items" :content="{ align: 'start' }" :ui="{ content: 'w-48' }">
<UButton label="Open" color="neutral" variant="outline" icon="i-lucide-menu" />
<template #switch-trailing="{ item }">
<USwitch :model-value="item.checked" tabindex="-1" />
</template>
</UDropdownMenu>
</template>
<script setup lang="ts">
import { ref, computed } from 'vue'
import type { DropdownMenuItem } from '@nuxt/ui'
const showBookmarks = ref(true)
const showHistory = ref(false)
const showDownloads = ref(false)
const items = computed(() => [{
label: 'Show Bookmarks',
icon: 'i-lucide-bookmark',
slot: 'switch' as const,
checked: showBookmarks.value,
onSelect(e: Event) {
e.preventDefault()
showBookmarks.value = !showBookmarks.value
}
}, {
label: 'Show History',
icon: 'i-lucide-clock',
slot: 'switch' as const,
checked: showHistory.value,
onSelect(e: Event) {
e.preventDefault()
showHistory.value = !showHistory.value
}
}, {
label: 'Show Downloads',
icon: 'i-lucide-download',
slot: 'switch' as const,
checked: showDownloads.value,
onSelect(e: Event) {
e.preventDefault()
showDownloads.value = !showDownloads.value
}
}] satisfies DropdownMenuItem[])
</script>
<template>
<UDropdownMenu :items="items" :content="{ align: 'start' }" :ui="{ content: 'w-48' }">
<UButton label="Open" color="neutral" variant="outline" icon="i-lucide-menu" />
<template #switch-trailing="{ item }">
<USwitch :model-value="item.checked" tabindex="-1" />
</template>
</UDropdownMenu>
</template>
無視フィルタ付きbadge{label="4.6+" class="align-text-top"}
childrenを持つアイテムでfilterプロパティまたはfilterフィールドを使用する場合、ignore-filterプロパティをtrueに設定して内部検索を無効にし、独自の検索ロジックを使用できます。
<script setup lang="ts">
import { refDebounced } from '@vueuse/core'
import type { DropdownMenuItem } from '@nuxt/ui'
const searchTerm = ref('')
const searchTermDebounced = refDebounced(searchTerm, 200)
const { data: users, status, execute } = await useLazyFetch('https://jsonplaceholder.typicode.com/users', {
key: 'dropdown-menu-users-search',
params: { q: searchTermDebounced },
transform: (data: { id: number, name: string }[]) => {
return data?.map(user => ({
label: user.name,
avatar: { src: `https://i.pravatar.cc/120?img=${user.id}`, loading: 'lazy' as const }
})) as DropdownMenuItem[]
},
immediate: false
})
function onOpen() {
if (!users.value?.length) {
execute()
}
}
</script>
<template>
<UDropdownMenu
v-model:search-term="searchTerm"
:items="users || []"
:filter="{
icon: 'i-lucide-search',
loading: status === 'pending'
}"
ignore-filter
:content="{ align: 'start' }"
:ui="{ content: 'w-48' }"
@update:open="onOpen"
>
<UButton label="Open" color="neutral" variant="outline" icon="i-lucide-menu" />
</UDropdownMenu>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import { refDebounced } from '@vueuse/core'
import type { DropdownMenuItem } from '@nuxt/ui'
const searchTerm = ref('')
const searchTermDebounced = refDebounced(searchTerm, 200)
const { data: users, status, execute } = await useLazyFetch('https://jsonplaceholder.typicode.com/users', {
key: 'dropdown-menu-users-search',
params: { q: searchTermDebounced },
transform: (data: { id: number, name: string }[]) => {
return data?.map(user => ({
label: user.name,
avatar: { src: `https://i.pravatar.cc/120?img=${user.id}`, loading: 'lazy' as const }
})) as DropdownMenuItem[]
},
immediate: false
})
function onOpen() {
if (!users.value?.length) {
execute()
}
}
</script>
<template>
<UDropdownMenu
v-model:search-term="searchTerm"
:items="users || []"
:filter="{
icon: 'i-lucide-search',
loading: status === 'pending'
}"
ignore-filter
:content="{ align: 'start' }"
:ui="{ content: 'w-48' }"
@update:open="onOpen"
>
<UButton label="Open" color="neutral" variant="outline" icon="i-lucide-menu" />
</UDropdownMenu>
</template>
refDebouncedを使用してAPI呼び出しをデバウンスします。フェッチはimmediate: falseで延期されるため、メニューが開くまでリクエストは行われません。フィルタフィールド付きbadge{label="4.6+" class="align-text-top"}
filterプロパティまたはfilterフィールドをchildrenでアイテムに使用する場合、filter-fieldsプロパティにフィルターをかけるフィールドの配列を設定できます。デフォルトは[labelKey]です。
<script setup lang="ts">
import type { DropdownMenuItem } from '@nuxt/ui'
const items: DropdownMenuItem[] = [{
label: 'Leanne Graham',
description: 'Sincere@april.biz'
}, {
label: 'Ervin Howell',
description: 'Shanna@melissa.tv'
}, {
label: 'Clementine Bauch',
description: 'Nathan@yesenia.net'
}, {
label: 'Patricia Lebsack',
description: 'Julianne.OConner@kory.org'
}, {
label: 'Chelsey Dietrich',
description: 'Lucio_Hettinger@annie.me'
}]
</script>
<template>
<UDropdownMenu
:items="items"
filter
:filter-fields="['label', 'description']"
:content="{ align: 'start' }"
:ui="{ content: 'w-64' }"
>
<UButton label="Open" color="neutral" variant="outline" icon="i-lucide-menu" />
</UDropdownMenu>
</template>
トリガーコンテンツ幅付き
ui.contentスロットにw-(--reka-dropdown-menu-trigger-width)クラスを追加することで、コンテンツをボタンの幅いっぱいに展開できます。
<script setup lang="ts">
import type { DropdownMenuItem } from '@nuxt/ui'
const items: DropdownMenuItem[][] = [
[
{
label: 'View',
icon: 'i-lucide-eye'
},
{
label: 'Copy',
icon: 'i-lucide-copy'
},
{
label: 'Edit',
icon: 'i-lucide-pencil'
}
],
[
{
label: 'Delete',
color: 'error',
icon: 'i-lucide-trash'
}
]
]
</script>
<template>
<UDropdownMenu :items="items" :ui="{ content: 'w-(--reka-dropdown-menu-trigger-width)' }">
<UButton
label="Open"
class="w-46"
color="neutral"
variant="outline"
block
trailing-icon="i-lucide-chevron-down"
/>
</UDropdownMenu>
</template>
app.config.tsでコンテンツ幅をグローバルに変更することもできます:export default defineAppConfig({
ui: {
dropdownMenu: {
slots: {
content: 'w-(--reka-dropdown-menu-trigger-width)'
}
}
}
})
ショートカットを抽出
extractShortcutsユーティリティを使用して、メニュー項目から自動的にショートカットをkbdsプロパティで定義します。ショートカットを再帰的に抽出し、defineShortcutsと互換性のあるオブジェクトを返します。
<script setup lang="ts">
import type { DropdownMenuItem } from '@nuxt/ui'
const items: DropdownMenuItem[] = [{
label: 'Invite users',
icon: 'i-lucide-user-plus',
children: [{
label: 'Invite by email',
icon: 'i-lucide-send-horizontal',
kbds: ['meta', 'e'],
onSelect() {
console.log('Invite by email clicked')
}
}, {
label: 'Invite by link',
icon: 'i-lucide-link',
kbds: ['meta', 'i'],
onSelect() {
console.log('Invite by link clicked')
}
}]
}, {
label: 'New team',
icon: 'i-lucide-plus',
kbds: ['meta', 'n'],
onSelect() {
console.log('New team clicked')
}
}]
defineShortcuts(extractShortcuts(items))
</script>
select関数をトリガーします。API
Props
| Prop | Default | Type |
|---|---|---|
size | 'md' | "sm" | "md" | "xs" | "lg" | "xl" |
items | T | |
checkedIcon | appConfig.ui.icons.check | anyThe icon displayed when an item is checked. |
loadingIcon | appConfig.ui.icons.loading | anyThe icon displayed when an item is loading. |
externalIcon | true | anyThe icon displayed when the item is an external link.
Set to |
content | { side: 'bottom', sideOffset: 8, collisionPadding: 8 } | DropdownMenuContentProps & Partial<EmitsToProps<MenuContentEmits>>The content of the menu. |
arrow | false | boolean | DropdownMenuArrowProps Display an arrow alongside the menu.
|
portal | true | string | false | true | HTMLElementRender the menu in a portal. |
labelKey | 'label' | keyof Extract<NestedItem<T>, object> & string | DotPathKeys<Extract<NestedItem<T>, object>>The key used to get the label from the item. |
descriptionKey | 'description' | keyof Extract<NestedItem<T>, object> & string | DotPathKeys<Extract<NestedItem<T>, object>>The key used to get the description from the item. |
filter | false | boolean | Omit<InputProps<AcceptableValue, ModelModifiers>, "modelValue" | "defaultValue"> Whether to display a filter input or not.
Can be an object to pass additional props to the input.
|
filterFields | [labelKey] | string[]The fields to filter by. |
ignoreFilter | false | boolean When |
disabled | boolean | |
defaultOpen | boolean The open state of the dropdown menu when it is initially rendered. Use when you do not need to control its open state. | |
open | boolean The controlled open state of the menu. Can be used as | |
modal | true | boolean The modality of the dropdown menu. When set to |
searchTerm | '' | string |
ui | { content?: SlotClass; input?: SlotClass; empty?: SlotClass; viewport?: SlotClass; arrow?: SlotClass; group?: SlotClass; label?: SlotClass; separator?: SlotClass; item?: SlotClass; itemLeadingIcon?: SlotClass; itemLeadingAvatar?: SlotClass; itemLeadingAvatarSize?: SlotClass; itemTrailing?: SlotClass; itemTrailingIcon?: SlotClass; itemTrailingKbds?: SlotClass; itemTrailingKbdsSize?: SlotClass; itemWrapper?: SlotClass; itemLabel?: SlotClass; itemDescription?: SlotClass; itemLabelExternalIcon?: SlotClass; } |
スロット
| Slot | Type |
|---|---|
default | { open: boolean; } |
item | { item: NestedItem<T>; active: boolean; index: number; ui: object; } |
item-leading | { item: NestedItem<T>; active: boolean; index: number; ui: object; } |
item-label | { item: NestedItem<T>; active: boolean; index: number; } |
item-description | { item: NestedItem<T>; active: boolean; index: number; } |
item-trailing | { item: NestedItem<T>; active: boolean; index: number; ui: object; } |
empty | { searchTerm: string; } |
content-top | { sub: boolean; } |
content-bottom | { sub: boolean; } |
Emits
| Event | Type |
|---|---|
update:open | [payload: boolean] |
update:searchTerm | [value: string] |
Theme
export default defineAppConfig({
ui: {
dropdownMenu: {
slots: {
content: 'min-w-32 max-h-(--reka-dropdown-menu-content-available-height) bg-default shadow-lg rounded-md ring ring-default overflow-hidden data-[state=open]:animate-[scale-in_100ms_var(--ease-out)] data-[state=closed]:animate-[scale-out_100ms_var(--ease-out)] origin-(--reka-dropdown-menu-content-transform-origin) flex flex-col',
input: 'border-b border-default',
empty: 'text-center text-muted',
viewport: 'relative divide-y divide-default scroll-py-1 overflow-y-auto flex-1',
arrow: 'fill-bg stroke-default',
group: 'p-1 isolate',
label: 'w-full flex items-center font-semibold text-highlighted',
separator: '-mx-1 my-1 h-px bg-border',
item: 'group relative w-full flex items-start select-none outline-none before:absolute before:z-[-1] before:inset-px before:rounded-md data-disabled:cursor-not-allowed data-disabled:opacity-75',
itemLeadingIcon: 'shrink-0',
itemLeadingAvatar: 'shrink-0',
itemLeadingAvatarSize: '',
itemTrailing: 'ms-auto inline-flex gap-1.5 items-center',
itemTrailingIcon: 'shrink-0',
itemTrailingKbds: 'hidden lg:inline-flex items-center shrink-0',
itemTrailingKbdsSize: '',
itemWrapper: 'flex-1 flex flex-col text-start min-w-0',
itemLabel: 'truncate',
itemDescription: 'truncate text-muted',
itemLabelExternalIcon: 'inline-block size-3 align-top text-dimmed'
},
variants: {
color: {
primary: '',
secondary: '',
success: '',
info: '',
warning: '',
error: '',
neutral: ''
},
active: {
true: {
item: 'text-highlighted before:bg-elevated',
itemLeadingIcon: 'text-default'
},
false: {
item: [
'text-default data-highlighted:text-highlighted data-[state=open]:text-highlighted data-highlighted:before:bg-elevated/50 data-[state=open]:before:bg-elevated/50',
'transition-colors before:transition-colors'
],
itemLeadingIcon: [
'text-dimmed group-data-highlighted:text-default group-data-[state=open]:text-default',
'transition-colors'
]
}
},
loading: {
true: {
itemLeadingIcon: 'animate-spin'
}
},
size: {
xs: {
label: 'p-1 text-xs gap-1',
item: 'p-1 text-xs gap-1',
empty: 'p-2 text-xs',
itemLeadingIcon: 'size-4',
itemLeadingAvatarSize: '3xs',
itemTrailingIcon: 'size-4',
itemTrailingKbds: 'gap-0.5',
itemTrailingKbdsSize: 'sm'
},
sm: {
label: 'p-1.5 text-xs gap-1.5',
item: 'p-1.5 text-xs gap-1.5',
empty: 'p-2.5 text-xs',
itemLeadingIcon: 'size-4',
itemLeadingAvatarSize: '3xs',
itemTrailingIcon: 'size-4',
itemTrailingKbds: 'gap-0.5',
itemTrailingKbdsSize: 'sm'
},
md: {
label: 'p-1.5 text-sm gap-1.5',
item: 'p-1.5 text-sm gap-1.5',
empty: 'p-2.5 text-sm',
itemLeadingIcon: 'size-5',
itemLeadingAvatarSize: '2xs',
itemTrailingIcon: 'size-5',
itemTrailingKbds: 'gap-0.5',
itemTrailingKbdsSize: 'md'
},
lg: {
label: 'p-2 text-sm gap-2',
item: 'p-2 text-sm gap-2',
empty: 'p-3 text-sm',
itemLeadingIcon: 'size-5',
itemLeadingAvatarSize: '2xs',
itemTrailingIcon: 'size-5',
itemTrailingKbds: 'gap-1',
itemTrailingKbdsSize: 'md'
},
xl: {
label: 'p-2 text-base gap-2',
item: 'p-2 text-base gap-2',
empty: 'p-3 text-base',
itemLeadingIcon: 'size-6',
itemLeadingAvatarSize: 'xs',
itemTrailingIcon: 'size-6',
itemTrailingKbds: 'gap-1',
itemTrailingKbdsSize: 'lg'
}
}
},
compoundVariants: [
{
color: 'primary',
active: false,
class: {
item: 'text-primary data-highlighted:text-primary data-highlighted:before:bg-primary/10 data-[state=open]:before:bg-primary/10',
itemLeadingIcon: 'text-primary/75 group-data-highlighted:text-primary group-data-[state=open]:text-primary'
}
},
{
color: 'primary',
active: true,
class: {
item: 'text-primary before:bg-primary/10',
itemLeadingIcon: 'text-primary'
}
}
],
defaultVariants: {
size: 'md'
}
}
}
})import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import ui from '@nuxt/ui/vite'
export default defineConfig({
plugins: [
vue(),
ui({
ui: {
dropdownMenu: {
slots: {
content: 'min-w-32 max-h-(--reka-dropdown-menu-content-available-height) bg-default shadow-lg rounded-md ring ring-default overflow-hidden data-[state=open]:animate-[scale-in_100ms_var(--ease-out)] data-[state=closed]:animate-[scale-out_100ms_var(--ease-out)] origin-(--reka-dropdown-menu-content-transform-origin) flex flex-col',
input: 'border-b border-default',
empty: 'text-center text-muted',
viewport: 'relative divide-y divide-default scroll-py-1 overflow-y-auto flex-1',
arrow: 'fill-bg stroke-default',
group: 'p-1 isolate',
label: 'w-full flex items-center font-semibold text-highlighted',
separator: '-mx-1 my-1 h-px bg-border',
item: 'group relative w-full flex items-start select-none outline-none before:absolute before:z-[-1] before:inset-px before:rounded-md data-disabled:cursor-not-allowed data-disabled:opacity-75',
itemLeadingIcon: 'shrink-0',
itemLeadingAvatar: 'shrink-0',
itemLeadingAvatarSize: '',
itemTrailing: 'ms-auto inline-flex gap-1.5 items-center',
itemTrailingIcon: 'shrink-0',
itemTrailingKbds: 'hidden lg:inline-flex items-center shrink-0',
itemTrailingKbdsSize: '',
itemWrapper: 'flex-1 flex flex-col text-start min-w-0',
itemLabel: 'truncate',
itemDescription: 'truncate text-muted',
itemLabelExternalIcon: 'inline-block size-3 align-top text-dimmed'
},
variants: {
color: {
primary: '',
secondary: '',
success: '',
info: '',
warning: '',
error: '',
neutral: ''
},
active: {
true: {
item: 'text-highlighted before:bg-elevated',
itemLeadingIcon: 'text-default'
},
false: {
item: [
'text-default data-highlighted:text-highlighted data-[state=open]:text-highlighted data-highlighted:before:bg-elevated/50 data-[state=open]:before:bg-elevated/50',
'transition-colors before:transition-colors'
],
itemLeadingIcon: [
'text-dimmed group-data-highlighted:text-default group-data-[state=open]:text-default',
'transition-colors'
]
}
},
loading: {
true: {
itemLeadingIcon: 'animate-spin'
}
},
size: {
xs: {
label: 'p-1 text-xs gap-1',
item: 'p-1 text-xs gap-1',
empty: 'p-2 text-xs',
itemLeadingIcon: 'size-4',
itemLeadingAvatarSize: '3xs',
itemTrailingIcon: 'size-4',
itemTrailingKbds: 'gap-0.5',
itemTrailingKbdsSize: 'sm'
},
sm: {
label: 'p-1.5 text-xs gap-1.5',
item: 'p-1.5 text-xs gap-1.5',
empty: 'p-2.5 text-xs',
itemLeadingIcon: 'size-4',
itemLeadingAvatarSize: '3xs',
itemTrailingIcon: 'size-4',
itemTrailingKbds: 'gap-0.5',
itemTrailingKbdsSize: 'sm'
},
md: {
label: 'p-1.5 text-sm gap-1.5',
item: 'p-1.5 text-sm gap-1.5',
empty: 'p-2.5 text-sm',
itemLeadingIcon: 'size-5',
itemLeadingAvatarSize: '2xs',
itemTrailingIcon: 'size-5',
itemTrailingKbds: 'gap-0.5',
itemTrailingKbdsSize: 'md'
},
lg: {
label: 'p-2 text-sm gap-2',
item: 'p-2 text-sm gap-2',
empty: 'p-3 text-sm',
itemLeadingIcon: 'size-5',
itemLeadingAvatarSize: '2xs',
itemTrailingIcon: 'size-5',
itemTrailingKbds: 'gap-1',
itemTrailingKbdsSize: 'md'
},
xl: {
label: 'p-2 text-base gap-2',
item: 'p-2 text-base gap-2',
empty: 'p-3 text-base',
itemLeadingIcon: 'size-6',
itemLeadingAvatarSize: 'xs',
itemTrailingIcon: 'size-6',
itemTrailingKbds: 'gap-1',
itemTrailingKbdsSize: 'lg'
}
}
},
compoundVariants: [
{
color: 'primary',
active: false,
class: {
item: 'text-primary data-highlighted:text-primary data-highlighted:before:bg-primary/10 data-[state=open]:before:bg-primary/10',
itemLeadingIcon: 'text-primary/75 group-data-highlighted:text-primary group-data-[state=open]:text-primary'
}
},
{
color: 'primary',
active: true,
class: {
item: 'text-primary before:bg-primary/10',
itemLeadingIcon: 'text-primary'
}
}
],
defaultVariants: {
size: 'md'
}
}
}
})
]
})