Dropdownmenu hinzufügen
Bearbeiten
Verwenden Sie einen Button oder eine andere Komponente im Standard-Slot des DropdownMenu.
<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 Bearbeiten
Verwenden Sie die items-prop als Array von Objekten mit den folgenden Eigenschaften:
label?: string(nicht)icon?: string(nicht)avatar?: AvatarProps(nicht)kbds?: string[] | KbdProps[](nicht)type?: "link" | "label" | "separator" | "checkbox") #with-checkbox-items129x125{lang="ts-type"}](xph128)color?: "error" | "primary" | "secondary" | "success" | "info" | "warning" | "neutral")136x137{lang="ts-type"}ph136xx136x136x136x136xx136xx136xx137x136xx136x136xchecked?: booleandisabled?: boolean(nicht)slot?: stringonSelect?: (e: Event) => void(englisch)onUpdateChecked?: (checked: boolean) => voidchildren?: DropdownMenuItem[] | DropdownMenuItem[][](englisch)filter?: boolean | InputPropsfilterFields?: string[](nicht vorhanden)ignoreFilter?: boolean(nicht vorhanden)class?: any(englisch)ui?: { item?: ClassNameValue, label?: ClassNameValue, separator?: ClassNameValue, itemLeadingIcon?: ClassNameValue, itemLeadingAvatarSize?: ClassNameValue, itemLeadingAvatar?: ClassNameValue, itemLabel?: ClassNameValue, itemLabelExternalIcon?: ClassNameValue, itemTrailing?: ClassNameValue, itemTrailingIcon?: ClassNameValue, itemTrailingKbds?: ClassNameValue, itemTrailingKbdsSize?: ClassNameValue }(englisch)
Sie können jede Eigenschaft aus der Komponente Link übergeben, z. B. to, target usw.
<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-prop übergeben, um getrennte Gruppen von Elementen zu erstellen.children-Array von Objekten mit den gleichen Eigenschaften wie die items-Prop verwenden, um ein verschachteltes Menü zu erstellen, das mit den Eigenschaften open, defaultOpen und content gesteuert werden kann.Inhalt
Verwenden Sie die content-Prop, um zu steuern, wie der DropdownMenu-Inhalt gerendert wird, z. B. align oder 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>Filter: badge{label="4.6+" class="align-text-top"}
Verwenden Sie die filter-Prop, um einen Filtereingang innerhalb des DropdownMenu anzuzeigen. Standardmäßig ist false.
ignore-filter-prop, um die interne Suche zu deaktivieren und Ihre eigene Suchlogik zu verwenden.filter-fields prop, um anzugeben, nach welchen Feldern gefiltert werden soll. Standardmäßig wird die labelKey prop verwendet.Sie können jede Eigenschaft der Komponente Input übergeben, um sie anzupassen.
<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>filter für Elemente mit children verwenden.Arrow Bearbeiten
Verwenden Sie die arrow-Prop, um einen Pfeil im DropdownMenü anzuzeigen.
<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>Size ist
Verwenden Sie die size-Prop, um die Größe des DropdownMenu zu steuern.
<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-Prop wird nicht an den Button weitergeleitet, Sie müssen sie selbst einstellen.Modal Bearbeiten
Verwenden Sie die modal-Prop, um zu steuern, ob das DropdownMenu die Interaktion mit externen Inhalten blockiert.
<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 (nicht verfügbar)
Verwenden Sie die disabled-Prop, um das DropdownMenu zu deaktivieren.
<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>Beispiele
With Checkbox Items (Deutsche Übersetzung)
Sie können die type-Eigenschaft mit checkbox verwenden und die checked/onUpdateChecked-Eigenschaften verwenden, um den überprüften Zustand des Elements zu steuern.
<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-Status von Elementen zu gewährleisten, wird empfohlen, das items-Array in ein computed zu wickeln.Mit farbigen Elementen
Sie können die color-Eigenschaft verwenden, um bestimmte Elemente mit einer Farbe hervorzuheben.
<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>
With filter items: badge{label="4.6+" class="align-text-top"} (Mit Filterelementen: badge{label="4.6+" class="align-text-top"})
Sie können die filter-Eigenschaft für Elemente mit children verwenden, um eine Filtereingabe im Untermenü anzuzeigen.
<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 im Open State
Sie können den offenen Zustand mit der default-open-prop-oder der v-model:open-Anweisung steuern.
<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 das DropdownMenu umschalten, indem Sie: kbd{value="O"}.Mit Custom Slot
Verwenden Sie die slot-Eigenschaft, um ein bestimmtes Element anzupassen.
Sie haben Zugriff auf folgende Slots:
#{{ item.slot }}#{{ item.slot }}-leading(nicht)#{{ item.slot }}-label(nicht)#{{ 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>
#item, #item-leading, #item-label und #item-trailing Steckplätze verwenden, um alle Elemente anzupassen.With switch in items (Mit Schalter in Elementen)
Sie können die slot-Eigenschaft mit einem #{{ slot }}-trailing-Steckplatz verwenden, um einen Switch in einem Element zu rendern.
<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>
With ignore filter: badge{label="4.6+" class="align-text-top"} (mit dem Filter "ignorieren")
Wenn Sie die filter-prop oder das filter-Feld für Elemente mit children verwenden, können Sie die ignore-filter-prop auf true setzen, um die interne Suche zu deaktivieren und Ihre eigene Suchlogik zu verwenden.
<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 verwendet, um die API-Aufrufe zu entkräften. Der Abruf wird mit immediate: false verschoben, so dass keine Anfrage gestellt wird, bis das Menü geöffnet wird.With Filterfelder: badge{label="4.6+" class="align-text-top"}
Wenn Sie die filter-Prop oder das filter-Feld für Elemente mit children verwenden, können Sie die filter-fields-Prop mit einem Array von Feldern zum Filtern festlegen.
<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>
With trigger content width (Inhaltsbreite des Triggers)
Sie können den Inhalt auf die volle Breite der Schaltfläche erweitern, indem Sie die w-(--reka-dropdown-menu-trigger-width)-Klasse auf dem ui.content-Steckplatz hinzufügen.
<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 ändern:export default defineAppConfig({
ui: {
dropdownMenu: {
slots: {
content: 'w-(--reka-dropdown-menu-trigger-width)'
}
}
}
})
Extract Shortcuts (englisch)
Verwenden Sie das Dienstprogramm extractShortcuts, um automatisch Verknüpfungen von Menüelementen mit einer kbds-Eigenschaft zu definieren. Es extrahiert rekursiv Verknüpfungen und gibt ein Objekt zurück, das mit defineShortcuts kompatibel ist.
<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 des entsprechenden Elements auslösen.API (englisch)
Props Bearbeiten
| 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; } |
Slots (englisch)
| 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 Bearbeiten
| Event | Type |
|---|---|
update:open | [payload: boolean] |
update:searchTerm | [value: string] |
Themes Bearbeiten
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'
}
}
}
})
]
})