Kontextmenü

Ein Menü zum Anzeigen von Aktionen beim Rechtsklick auf ein Element.

Bearbeiten

Verwenden Sie alles, was Sie im Standard-Slot des ContextMenu möchten, und klicken Sie mit der rechten Maustaste darauf, um das Menü anzuzeigen.

Right click here
<script setup lang="ts">
import type { ContextMenuItem } from '@nuxt/ui'

const items = ref<ContextMenuItem[][]>([
  [
    {
      label: 'Appearance',
      children: [
        {
          label: 'System',
          icon: 'i-lucide-monitor'
        },
        {
          label: 'Light',
          icon: 'i-lucide-sun'
        },
        {
          label: 'Dark',
          icon: 'i-lucide-moon'
        }
      ]
    }
  ],
  [
    {
      label: 'Show Sidebar',
      kbds: ['meta', 's']
    },
    {
      label: 'Show Toolbar',
      kbds: ['shift', 'meta', 'd']
    },
    {
      label: 'Collapse Pinned Tabs',
      disabled: true
    }
  ],
  [
    {
      label: 'Refresh the Page'
    },
    {
      label: 'Clear Cookies and Refresh'
    },
    {
      label: 'Clear Cache and Refresh'
    },
    {
      type: 'separator'
    },
    {
      label: 'Developer',
      children: [
        [
          {
            label: 'View Source',
            kbds: ['meta', 'shift', 'u']
          },
          {
            label: 'Developer Tools',
            kbds: ['option', 'meta', 'i']
          },
          {
            label: 'Inspect Elements',
            kbds: ['option', 'meta', 'c']
          }
        ],
        [
          {
            label: 'JavaScript Console',
            kbds: ['option', 'meta', 'j']
          }
        ]
      ]
    }
  ]
])
</script>

<template>
  <UContextMenu :items="items">
    <div
      class="flex items-center justify-center rounded-md border border-dashed border-accented text-sm aspect-video w-72"
    >
      Right click here
    </div>
  </UContextMenu>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import type { ContextMenuItem } from '@nuxt/ui'

const items = ref<ContextMenuItem[][]>([
  [
    {
      label: 'Appearance',
      children: [
        {
          label: 'System',
          icon: 'i-lucide-monitor'
        },
        {
          label: 'Light',
          icon: 'i-lucide-sun'
        },
        {
          label: 'Dark',
          icon: 'i-lucide-moon'
        }
      ]
    }
  ],
  [
    {
      label: 'Show Sidebar',
      kbds: ['meta', 's']
    },
    {
      label: 'Show Toolbar',
      kbds: ['shift', 'meta', 'd']
    },
    {
      label: 'Collapse Pinned Tabs',
      disabled: true
    }
  ],
  [
    {
      label: 'Refresh the Page'
    },
    {
      label: 'Clear Cookies and Refresh'
    },
    {
      label: 'Clear Cache and Refresh'
    },
    {
      type: 'separator'
    },
    {
      label: 'Developer',
      children: [
        [
          {
            label: 'View Source',
            kbds: ['meta', 'shift', 'u']
          },
          {
            label: 'Developer Tools',
            kbds: ['option', 'meta', 'i']
          },
          {
            label: 'Inspect Elements',
            kbds: ['option', 'meta', 'c']
          }
        ],
        [
          {
            label: 'JavaScript Console',
            kbds: ['option', 'meta', 'j']
          }
        ]
      ]
    }
  ]
])
</script>

<template>
  <UContextMenu :items="items">
    <div
      class="flex items-center justify-center rounded-md border border-dashed border-accented text-sm aspect-video w-72"
    >
      Right click here
    </div>
  </UContextMenu>
</template>

Einträge

Verwenden Sie die items-prop als Array von Objekten mit den folgenden Eigenschaften:

  • label?: string (nicht vorhanden)
  • icon?: string (nicht vorhanden)
  • avatar?: AvatarProps (nicht vorhanden)
  • kbds?: string[] | KbdProps[]078x078x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
  • type?: "link" | "label" | "separator" | "checkbox"
  • color?: "error" | "primary" | "secondary" | "success" | "info" | "warning" | "neutral" ) xph08800)
  • checked?: boolean ) xph0998x xph0999999xxph0999xx{lang="ts-type"}x{lang="ts-type"}x{lang="ts-type"}xx09xx)
  • disabled?: boolean (nicht)
  • slot?: string
  • onSelect?: (e: Event) => void (englisch)
  • onUpdateChecked?: (checked: boolean) => void )
  • children?: ContextMenuItem[] | ContextMenuItem[][] (nicht)
  • class?: any (nicht)
  • 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 } (nicht)

Sie können jede Eigenschaft der Komponente Link übergeben, z. B. to, target usw.

Right click here
<script setup lang="ts">
import type { ContextMenuItem } from '@nuxt/ui'

const items = ref<ContextMenuItem[][]>([
  [
    {
      label: 'Appearance',
      children: [
        {
          label: 'System',
          icon: 'i-lucide-monitor'
        },
        {
          label: 'Light',
          icon: 'i-lucide-sun'
        },
        {
          label: 'Dark',
          icon: 'i-lucide-moon'
        }
      ]
    }
  ],
  [
    {
      label: 'Show Sidebar',
      kbds: ['meta', 's']
    },
    {
      label: 'Show Toolbar',
      kbds: ['shift', 'meta', 'd']
    },
    {
      label: 'Collapse Pinned Tabs',
      disabled: true
    }
  ],
  [
    {
      label: 'Refresh the Page'
    },
    {
      label: 'Clear Cookies and Refresh'
    },
    {
      label: 'Clear Cache and Refresh'
    },
    {
      type: 'separator'
    },
    {
      label: 'Developer',
      children: [
        [
          {
            label: 'View Source',
            kbds: ['meta', 'shift', 'u']
          },
          {
            label: 'Developer Tools',
            kbds: ['option', 'meta', 'i']
          },
          {
            label: 'Inspect Elements',
            kbds: ['option', 'meta', 'c']
          }
        ],
        [
          {
            label: 'JavaScript Console',
            kbds: ['option', 'meta', 'j']
          }
        ]
      ]
    }
  ]
])
</script>

<template>
  <UContextMenu
    :items="items"
    :ui="{
      content: 'w-48'
    }"
  >
    <div
      class="flex items-center justify-center rounded-md border border-dashed border-accented text-sm aspect-video w-72"
    >
      Right click here
    </div>
  </UContextMenu>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import type { ContextMenuItem } from '@nuxt/ui'

const items = ref<ContextMenuItem[][]>([
  [
    {
      label: 'Appearance',
      children: [
        {
          label: 'System',
          icon: 'i-lucide-monitor'
        },
        {
          label: 'Light',
          icon: 'i-lucide-sun'
        },
        {
          label: 'Dark',
          icon: 'i-lucide-moon'
        }
      ]
    }
  ],
  [
    {
      label: 'Show Sidebar',
      kbds: ['meta', 's']
    },
    {
      label: 'Show Toolbar',
      kbds: ['shift', 'meta', 'd']
    },
    {
      label: 'Collapse Pinned Tabs',
      disabled: true
    }
  ],
  [
    {
      label: 'Refresh the Page'
    },
    {
      label: 'Clear Cookies and Refresh'
    },
    {
      label: 'Clear Cache and Refresh'
    },
    {
      type: 'separator'
    },
    {
      label: 'Developer',
      children: [
        [
          {
            label: 'View Source',
            kbds: ['meta', 'shift', 'u']
          },
          {
            label: 'Developer Tools',
            kbds: ['option', 'meta', 'i']
          },
          {
            label: 'Inspect Elements',
            kbds: ['option', 'meta', 'c']
          }
        ],
        [
          {
            label: 'JavaScript Console',
            kbds: ['option', 'meta', 'j']
          }
        ]
      ]
    }
  ]
])
</script>

<template>
  <UContextMenu
    :items="items"
    :ui="{
      content: 'w-48'
    }"
  >
    <div
      class="flex items-center justify-center rounded-md border border-dashed border-accented text-sm aspect-video w-72"
    >
      Right click here
    </div>
  </UContextMenu>
</template>
Sie können auch ein Array von Arrays an die items-Prop übergeben, um getrennte Gruppen von Elementen zu erstellen.
Jedes Element kann ein 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.

Size ist

Verwenden Sie die size-prop, um die Größe des Kontextmenüs zu ändern.

Right click here
<script setup lang="ts">
import type { ContextMenuItem } from '@nuxt/ui'

const items = ref<ContextMenuItem[]>([
  {
    label: 'System',
    icon: 'i-lucide-monitor'
  },
  {
    label: 'Light',
    icon: 'i-lucide-sun'
  },
  {
    label: 'Dark',
    icon: 'i-lucide-moon'
  }
])
</script>

<template>
  <UContextMenu
    size="xl"
    :items="items"
    :ui="{
      content: 'w-48'
    }"
  >
    <div
      class="flex items-center justify-center rounded-md border border-dashed border-accented text-sm aspect-video w-72"
    >
      Right click here
    </div>
  </UContextMenu>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import type { ContextMenuItem } from '@nuxt/ui'

const items = ref<ContextMenuItem[]>([
  {
    label: 'System',
    icon: 'i-lucide-monitor'
  },
  {
    label: 'Light',
    icon: 'i-lucide-sun'
  },
  {
    label: 'Dark',
    icon: 'i-lucide-moon'
  }
])
</script>

<template>
  <UContextMenu
    size="xl"
    :items="items"
    :ui="{
      content: 'w-48'
    }"
  >
    <div
      class="flex items-center justify-center rounded-md border border-dashed border-accented text-sm aspect-video w-72"
    >
      Right click here
    </div>
  </UContextMenu>
</template>

Verwenden Sie die modal-prop, um zu steuern, ob das ContextMenu die Interaktion mit externen Inhalten blockiert.

Right click here
<script setup lang="ts">
import type { ContextMenuItem } from '@nuxt/ui'

const items = ref<ContextMenuItem[]>([
  {
    label: 'System',
    icon: 'i-lucide-monitor'
  },
  {
    label: 'Light',
    icon: 'i-lucide-sun'
  },
  {
    label: 'Dark',
    icon: 'i-lucide-moon'
  }
])
</script>

<template>
  <UContextMenu
    :modal="false"
    :items="items"
    :ui="{
      content: 'w-48'
    }"
  >
    <div
      class="flex items-center justify-center rounded-md border border-dashed border-accented text-sm aspect-video w-72"
    >
      Right click here
    </div>
  </UContextMenu>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import type { ContextMenuItem } from '@nuxt/ui'

const items = ref<ContextMenuItem[]>([
  {
    label: 'System',
    icon: 'i-lucide-monitor'
  },
  {
    label: 'Light',
    icon: 'i-lucide-sun'
  },
  {
    label: 'Dark',
    icon: 'i-lucide-moon'
  }
])
</script>

<template>
  <UContextMenu
    :modal="false"
    :items="items"
    :ui="{
      content: 'w-48'
    }"
  >
    <div
      class="flex items-center justify-center rounded-md border border-dashed border-accented text-sm aspect-video w-72"
    >
      Right click here
    </div>
  </UContextMenu>
</template>

Disabled (nicht verfügbar)

Verwenden Sie die disabled-prop, um das Kontextmenü zu deaktivieren.

Right click here
<script setup lang="ts">
import type { ContextMenuItem } from '@nuxt/ui'

const items = ref<ContextMenuItem[]>([
  {
    label: 'System',
    icon: 'i-lucide-monitor'
  },
  {
    label: 'Light',
    icon: 'i-lucide-sun'
  },
  {
    label: 'Dark',
    icon: 'i-lucide-moon'
  }
])
</script>

<template>
  <UContextMenu
    disabled
    :items="items"
    :ui="{
      content: 'w-48'
    }"
  >
    <div
      class="flex items-center justify-center rounded-md border border-dashed border-accented text-sm aspect-video w-72"
    >
      Right click here
    </div>
  </UContextMenu>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import type { ContextMenuItem } from '@nuxt/ui'

const items = ref<ContextMenuItem[]>([
  {
    label: 'System',
    icon: 'i-lucide-monitor'
  },
  {
    label: 'Light',
    icon: 'i-lucide-sun'
  },
  {
    label: 'Dark',
    icon: 'i-lucide-moon'
  }
])
</script>

<template>
  <UContextMenu
    disabled
    :items="items"
    :ui="{
      content: 'w-48'
    }"
  >
    <div
      class="flex items-center justify-center rounded-md border border-dashed border-accented text-sm aspect-video w-72"
    >
      Right click here
    </div>
  </UContextMenu>
</template>

Beispiele

With Checkbox-Elemente

Sie können die type-Eigenschaft mit checkbox verwenden und die checked/onUpdateChecked-Eigenschaften verwenden, um den überprüften Zustand des Elements zu steuern.

Right click here
<script setup lang="ts">
import type { ContextMenuItem } from '@nuxt/ui'

const showSidebar = ref(true)
const showToolbar = ref(false)

const items = computed<ContextMenuItem[]>(() => [{
  label: 'View',
  type: 'label' as const
}, {
  type: 'separator' as const
}, {
  label: 'Show Sidebar',
  type: 'checkbox' as const,
  checked: showSidebar.value,
  onUpdateChecked(checked: boolean) {
    showSidebar.value = checked
  },
  onSelect(e: Event) {
    e.preventDefault()
  }
}, {
  label: 'Show Toolbar',
  type: 'checkbox' as const,
  checked: showToolbar.value,
  onUpdateChecked(checked: boolean) {
    showToolbar.value = checked
  }
}, {
  label: 'Collapse Pinned Tabs',
  type: 'checkbox' as const,
  disabled: true
}])
</script>

<template>
  <UContextMenu :items="items" :ui="{ content: 'w-48' }">
    <div class="flex items-center justify-center rounded-md border border-dashed border-accented text-sm aspect-video w-72">
      Right click here
    </div>
  </UContextMenu>
</template>
<script setup lang="ts">
import { ref, computed } from 'vue'
import type { ContextMenuItem } from '@nuxt/ui'

const showSidebar = ref(true)
const showToolbar = ref(false)

const items = computed<ContextMenuItem[]>(() => [{
  label: 'View',
  type: 'label' as const
}, {
  type: 'separator' as const
}, {
  label: 'Show Sidebar',
  type: 'checkbox' as const,
  checked: showSidebar.value,
  onUpdateChecked(checked: boolean) {
    showSidebar.value = checked
  },
  onSelect(e: Event) {
    e.preventDefault()
  }
}, {
  label: 'Show Toolbar',
  type: 'checkbox' as const,
  checked: showToolbar.value,
  onUpdateChecked(checked: boolean) {
    showToolbar.value = checked
  }
}, {
  label: 'Collapse Pinned Tabs',
  type: 'checkbox' as const,
  disabled: true
}])
</script>

<template>
  <UContextMenu :items="items" :ui="{ content: 'w-48' }">
    <div class="flex items-center justify-center rounded-md border border-dashed border-accented text-sm aspect-video w-72">
      Right click here
    </div>
  </UContextMenu>
</template>
Um die Reaktivität für den checked-Status von Elementen zu gewährleisten, wird empfohlen, das items-Array in ein computed zu wickeln.

With color items (Deutsche Übersetzung)

Mit der Eigenschaft color können Sie bestimmte Elemente mit einer Farbe hervorheben.

Right click here
<script setup lang="ts">
import type { ContextMenuItem } from '@nuxt/ui'

const items: ContextMenuItem[][] = [
  [
    {
      label: 'View',
      icon: 'i-lucide-eye'
    },
    {
      label: 'Copy',
      icon: 'i-lucide-copy'
    },
    {
      label: 'Edit',
      icon: 'i-lucide-pencil'
    }
  ],
  [
    {
      label: 'Delete',
      color: 'error' as const,
      icon: 'i-lucide-trash'
    }
  ]
]
</script>

<template>
  <UContextMenu :items="items" :ui="{ content: 'w-48' }">
    <div class="flex items-center justify-center rounded-md border border-dashed border-accented text-sm aspect-video w-72">
      Right click here
    </div>
  </UContextMenu>
</template>

Mit benutzerdefiniertem Slot

Verwenden Sie die slot-Eigenschaft, um ein bestimmtes Element anzupassen.

Sie haben Zugriff auf folgende Slots:

  • #{{ item.slot }} (nicht)
  • #{{ item.slot }}-leading324x
  • #{{ item.slot }}-label (nicht)
  • #{{ item.slot }}-trailing (nicht)
Right click here
<script setup lang="ts">
import type { ContextMenuItem } from '@nuxt/ui'

const loading = ref(true)

const items = [
  {
    label: 'Refresh the Page',
    slot: 'refresh' as const
  },
  {
    label: 'Clear Cookies and Refresh'
  },
  {
    label: 'Clear Cache and Refresh'
  }
] satisfies ContextMenuItem[]
</script>

<template>
  <UContextMenu :items="items" :ui="{ content: 'w-48' }">
    <div class="flex items-center justify-center rounded-md border border-dashed border-accented text-sm aspect-video w-72">
      Right click here
    </div>

    <template #refresh-label>
      {{ loading ? 'Refreshing...' : 'Refresh the Page' }}
    </template>

    <template #refresh-trailing>
      <UIcon v-if="loading" name="i-lucide-loader-circle" class="shrink-0 size-5 text-primary animate-spin" />
    </template>
  </UContextMenu>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import type { ContextMenuItem } from '@nuxt/ui'

const loading = ref(true)

const items = [
  {
    label: 'Refresh the Page',
    slot: 'refresh' as const
  },
  {
    label: 'Clear Cookies and Refresh'
  },
  {
    label: 'Clear Cache and Refresh'
  }
] satisfies ContextMenuItem[]
</script>

<template>
  <UContextMenu :items="items" :ui="{ content: 'w-48' }">
    <div class="flex items-center justify-center rounded-md border border-dashed border-accented text-sm aspect-video w-72">
      Right click here
    </div>

    <template #refresh-label>
      {{ loading ? 'Refreshing...' : 'Refresh the Page' }}
    </template>

    <template #refresh-trailing>
      <UIcon v-if="loading" name="i-lucide-loader-circle" class="shrink-0 size-5 text-primary animate-spin" />
    </template>
  </UContextMenu>
</template>
Sie können auch die #item, #item-leading, #item-label und #item-trailing Steckplätze verwenden, um alle Elemente anzupassen.

Extract Shortcuts (englisch)

Verwenden Sie das Dienstprogramm extractShortcuts, um automatisch Verknüpfungen von Menüelementen mit einer kbds-Eigenschaft zu definieren.

<script setup lang="ts">
const items = [
  [{
    label: 'Show Sidebar',
    kbds: ['meta', 'S'],
    onSelect() {
      console.log('Show Sidebar clicked')
    }
  }, {
    label: 'Show Toolbar',
    kbds: ['shift', 'meta', 'D'],
    onSelect() {
      console.log('Show Toolbar clicked')
    }
  }, {
    label: 'Collapse Pinned Tabs',
    disabled: true
  }], [{
    label: 'Refresh the Page'
  }, {
    label: 'Clear Cookies and Refresh'
  }, {
    label: 'Clear Cache and Refresh'
  }, {
    type: 'separator' as const
  }, {
    label: 'Developer',
    children: [[{
      label: 'View Source',
      kbds: ['option', 'meta', 'U'],
      onSelect() {
        console.log('View Source clicked')
      }
    }, {
      label: 'Developer Tools',
      kbds: ['option', 'meta', 'I'],
      onSelect() {
        console.log('Developer Tools clicked')
      }
    }], [{
      label: 'Inspect Elements',
      kbds: ['option', 'meta', 'C'],
      onSelect() {
        console.log('Inspect Elements clicked')
      }
    }], [{
      label: 'JavaScript Console',
      kbds: ['option', 'meta', 'J'],
      onSelect() {
        console.log('JavaScript Console clicked')
      }
    }]]
  }]
]

defineShortcuts(extractShortcuts(items))
</script>
In diesem Beispiel: kbd{value="meta"}: kbd{value="S" class="ms-px"},: kbd{value="shift"}: kbd{value="meta" class="ms-px"}: kbd{value="D" class="ms-px"},: kbd{value="option"}: kbd{value="meta" class="ms-px"}: kbd{value="U" class="ms-px"},: kbd{value="option"}: kbd{value="meta" class="ms-px"}: kbd{value="I" class="ms-px"},: kbd{value="option"}: kbd{value="meta" class="ms-px"}: kbd{value="meta" class="ms-px"}: kbd{value="meta" class="ms-px"} würde die entsprechende Funktion auslösen.

API (Englisch)

Props Bearbeiten

Prop Default Type
size
'md'
"sm" | "md" | "xs" | "lg" | "xl"
items
T
checkedIcon
appConfig.ui.icons.check
any

The icon displayed when an item is checked.

loadingIcon
appConfig.ui.icons.loading
any

The icon displayed when an item is loading.

externalIcon
true
any

The icon displayed when the item is an external link. Set to false to hide the external icon.

content
ContextMenuContentProps & Partial<EmitsToProps<MenuContentEmits>>

The content of the menu.

portal
true
string | false | true | HTMLElement

Render 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.

disabled
boolean
modal
true
boolean

The modality of the dropdown menu.

When set to true, interaction with outside elements will be disabled and only menu content will be visible to screen readers.

pressOpenDelay
700
number

The duration from when the trigger is pressed until the menu opens.

ui
{ content?: SlotClass; viewport?: 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
{}
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; }
content-top
{ sub: boolean; }
content-bottom
{ sub: boolean; }

Emits (Englisch)

Event Type
update:open
[payload: boolean]

Theme Bearbeiten

app.config.ts
export default defineAppConfig({
  ui: {
    contextMenu: {
      slots: {
        content: 'min-w-32 max-h-(--reka-context-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-context-menu-content-transform-origin) flex flex-col',
        viewport: 'relative divide-y divide-default scroll-py-1 overflow-y-auto flex-1',
        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',
            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',
            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',
            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',
            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',
            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'
      }
    }
  }
})
vite.config.ts
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import ui from '@nuxt/ui/vite'

export default defineConfig({
  plugins: [
    vue(),
    ui({
      ui: {
        contextMenu: {
          slots: {
            content: 'min-w-32 max-h-(--reka-context-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-context-menu-content-transform-origin) flex flex-col',
            viewport: 'relative divide-y divide-default scroll-py-1 overflow-y-auto flex-1',
            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',
                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',
                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',
                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',
                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',
                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'
          }
        }
      }
    })
  ]
})
Some colors in compoundVariants are omitted for readability. Check out the source code on GitHub.

Changelog (englisch)

No recent changes