DropdownMenu

A contextual menu for actions triggered by clicking an element.

Usage

Use a Button or any other component in the default slot of the DropdownMenu.

<script setup lang="ts">
import type { DropdownMenuItem } from '@bitrix24/b24ui-nuxt'

const items = ref<DropdownMenuItem[][]>([
  [
    {
      label: 'Bitrix24',
      avatar: {
        src: 'https://github.com/bitrix24.png'
      },
      type: 'label'
    }
  ],
  [
    {
      label: 'Profile'
    },
    {
      label: 'Billing'
    },
    {
      label: 'Settings',
      kbds: [',']
    },
    {
      label: 'Keyboard shortcuts'
    }
  ],
  [
    {
      label: 'Team'
    },
    {
      label: 'Invite users',
      children: [
        [
          {
            label: 'Email'
          },
          {
            label: 'Message'
          }
        ],
        [
          {
            label: 'More'
          }
        ]
      ]
    },
    {
      label: 'New team',
      kbds: ['meta', 'n']
    }
  ],
  [
    {
      label: 'GitHub',
      to: 'https://github.com/bitrix24/b24ui',
      target: '_blank'
    },
    {
      label: 'Support',
      to: '/docs/components/dropdown-menu/'
    },
    {
      label: 'API',
      disabled: true
    }
  ],
  [
    {
      label: 'Logout',
      kbds: ['shift', 'meta', 'q']
    }
  ]
])
</script>

<template>
  <B24DropdownMenu :items="items">
    <B24Button label="Open" />
  </B24DropdownMenu>
</template>

Items

Use the items prop as an array of objects with the following properties:

You can pass any property from the Link component such as to, target, etc.

<script setup lang="ts">
import type { DropdownMenuItem } from '@bitrix24/b24ui-nuxt'

const items = ref<DropdownMenuItem[][]>([
  [
    {
      label: 'Bitrix24',
      avatar: {
        src: 'https://github.com/bitrix24.png'
      },
      type: 'label'
    }
  ],
  [
    {
      label: 'Profile'
    },
    {
      label: 'Billing'
    },
    {
      label: 'Settings',
      kbds: [',']
    },
    {
      label: 'Keyboard shortcuts'
    }
  ],
  [
    {
      label: 'Team'
    },
    {
      label: 'Invite users',
      children: [
        [
          {
            label: 'Email'
          },
          {
            label: 'Message'
          }
        ],
        [
          {
            label: 'More'
          }
        ]
      ]
    },
    {
      label: 'New team',
      kbds: ['meta', 'n']
    }
  ],
  [
    {
      label: 'GitHub',
      to: 'https://github.com/bitrix24/b24ui',
      target: '_blank'
    },
    {
      label: 'Support',
      to: '/docs/components/dropdown-menu/'
    },
    {
      label: 'API',
      disabled: true
    }
  ],
  [
    {
      label: 'Logout',
      kbds: ['shift', 'meta', 'q']
    }
  ]
])
</script>

<template>
  <B24DropdownMenu :items="items">
    <B24Button label="Open" />
  </B24DropdownMenu>
</template>
You can also pass an array of arrays to the items prop to create separated groups of items.
Each item can take a children array of objects with the same properties as the items prop to create a nested menu which can be controlled using the open, defaultOpen and content properties.

Content

Use the content prop to control how the DropdownMenu content is rendered, like its align or side for example.

<script setup lang="ts">
import type { DropdownMenuItem } from '@bitrix24/b24ui-nuxt'

const items = ref<DropdownMenuItem[]>([
  {
    label: 'Profile'
  },
  {
    label: 'Billing'
  },
  {
    label: 'Settings'
  }
])
</script>

<template>
  <B24DropdownMenu
    :items="items"
    :content="{
      align: 'start',
      side: 'bottom',
      sideOffset: 8
    }"
  >
    <B24Button label="Open" />
  </B24DropdownMenu>
</template>

Arrow

Use the arrow prop to display an arrow on the DropdownMenu.

<script setup lang="ts">
import type { DropdownMenuItem } from '@bitrix24/b24ui-nuxt'

const items = ref<DropdownMenuItem[]>([
  {
    label: 'Profile'
  },
  {
    label: 'Billing'
  },
  {
    label: 'Settings'
  }
])
</script>

<template>
  <B24DropdownMenu arrow :items="items">
    <B24Button label="Open" />
  </B24DropdownMenu>
</template>

Use the modal prop to control whether the DropdownMenu blocks interaction with outside content. Defaults to true.

<script setup lang="ts">
import type { DropdownMenuItem } from '@bitrix24/b24ui-nuxt'

const items = ref<DropdownMenuItem[]>([
  {
    label: 'Profile'
  },
  {
    label: 'Billing'
  },
  {
    label: 'Settings'
  }
])
</script>

<template>
  <B24DropdownMenu
    :modal="false"
    :items="items"
    :b24ui="{
      content: 'w-48'
    }"
  >
    <B24Button label="Open" />
  </B24DropdownMenu>
</template>

Disabled

Use the disabled prop to disable the DropdownMenu.

<script setup lang="ts">
import type { DropdownMenuItem } from '@bitrix24/b24ui-nuxt'

const items = ref<DropdownMenuItem[]>([
  {
    label: 'Profile'
  },
  {
    label: 'Billing'
  },
  {
    label: 'Settings'
  }
])
</script>

<template>
  <B24DropdownMenu
    disabled
    :items="items"
    :ui="{
      content: 'w-48'
    }"
  >
    <B24Button label="Open" />
  </B24DropdownMenu>
</template>

Examples

With checkbox items

You can use the type property with checkbox and use the checked / onUpdateChecked properties to control the checked state of the item.

<script setup lang="ts">
import type { DropdownMenuItem } from '@bitrix24/b24ui-nuxt'
import HamburgerMenuIcon from '@bitrix24/b24icons-vue/outline/HamburgerMenuIcon'
import CloudDownloadIcon from '@bitrix24/b24icons-vue/outline/CloudDownloadIcon'
import ClockWithArrowIcon from '@bitrix24/b24icons-vue/main/ClockWithArrowIcon'
import Bookmark2Icon from '@bitrix24/b24icons-vue/outline/Bookmark2Icon'
import WindowScreenIcon from '@bitrix24/b24icons-vue/social/WindowScreenIcon'

const showBookmarks = ref(true)
const showHistory = ref(false)
const showDownloads = ref(false)

const items = computed(() => [
  {
    label: 'Interface',
    icon: WindowScreenIcon,
    type: 'label' as const
  },
  {
    label: 'Show Bookmarks',
    icon: Bookmark2Icon,
    type: 'checkbox' as const,
    checked: showBookmarks.value,
    onUpdateChecked(checked: boolean) {
      showBookmarks.value = checked
    },
    onSelect(e: Event) {
      e.preventDefault()
    }
  },
  {
    label: 'Show History',
    icon: ClockWithArrowIcon,
    type: 'checkbox' as const,
    checked: showHistory.value,
    onUpdateChecked(checked: boolean) {
      showHistory.value = checked
    }
  },
  {
    type: 'separator' as const
  },
  {
    label: 'Show Downloads',
    icon: CloudDownloadIcon,
    type: 'checkbox' as const,
    checked: showDownloads.value,
    onUpdateChecked(checked: boolean) {
      showDownloads.value = checked
    }
  }
] satisfies DropdownMenuItem[])
</script>

<template>
  <B24DropdownMenu :items="items" :content="{ align: 'start' }" :ui="{ content: 'w-48' }">
    <B24Button label="Open" :icon="HamburgerMenuIcon" />
  </B24DropdownMenu>
</template>
To ensure reactivity for the checked state of items, it's recommended to wrap your items array inside a computed.

With color items

You can use the color property to highlight certain items with a color.

<script setup lang="ts">
import type { DropdownMenuItem } from '@bitrix24/b24ui-nuxt'
import HamburgerMenuIcon from '@bitrix24/b24icons-vue/outline/HamburgerMenuIcon'
import OpenedEyeIcon from '@bitrix24/b24icons-vue/main/OpenedEyeIcon'
import TrashBinIcon from '@bitrix24/b24icons-vue/main/TrashBinIcon'
import CopyPlatesIcon from '@bitrix24/b24icons-vue/actions/CopyPlatesIcon'
import PencilDrawIcon from '@bitrix24/b24icons-vue/actions/PencilDrawIcon'

const items: DropdownMenuItem[][] = [
  [
    {
      label: 'View',
      icon: OpenedEyeIcon
    },
    {
      label: 'Copy',
      icon: CopyPlatesIcon
    },
    {
      label: 'Edit',
      icon: PencilDrawIcon
    }
  ],
  [
    {
      label: 'Delete',
      color: 'air-primary-alert' as const,
      icon: TrashBinIcon
    }
  ]
]
</script>

<template>
  <B24DropdownMenu :items="items" :ui="{ content: 'w-48' }">
    <B24Button label="Open" :icon="HamburgerMenuIcon" />
  </B24DropdownMenu>
</template>

Control open state

You can control the open state by using the default-open prop or the v-model:open directive.

<script setup lang="ts">
import type { DropdownMenuItem } from '@bitrix24/b24ui-nuxt'
import UserIcon from '@bitrix24/b24icons-vue/common-b24/UserIcon'
import PaymentIcon from '@bitrix24/b24icons-vue/outline/PaymentIcon'
import Settings3Icon from '@bitrix24/b24icons-vue/actions/Settings3Icon'
import HamburgerMenuIcon from '@bitrix24/b24icons-vue/outline/HamburgerMenuIcon'

const open = ref(false)

defineShortcuts({
  o: () => open.value = !open.value
})

const items: DropdownMenuItem[] = [
  {
    label: 'Profile',
    icon: UserIcon,
    slot: 'profile' as const
  }, {
    label: 'Billing',
    icon: PaymentIcon
  }, {
    label: 'Settings',
    icon: Settings3Icon
  }
]
</script>

<template>
  <B24DropdownMenu v-model:open="open" :items="items" :b24ui="{ content: 'w-[200px]', viewport: 'w-[200px]' }">
    <B24Button label="Open" :icon="HamburgerMenuIcon" />
  </B24DropdownMenu>
</template>
In this example, leveraging defineShortcuts, you can toggle the DropdownMenu by pressing O.

With custom slot

Use the slot property to customize a specific item.

You will have access to the following slots:

  • #{{ item.slot }}
  • #{{ item.slot }}-leading
  • #{{ item.slot }}-label
  • #{{ item.slot }}-trailing
<script setup lang="ts">
import type { DropdownMenuItem } from '@bitrix24/b24ui-nuxt'
import UserIcon from '@bitrix24/b24icons-vue/common-b24/UserIcon'
import PaymentIcon from '@bitrix24/b24icons-vue/outline/PaymentIcon'
import Settings3Icon from '@bitrix24/b24icons-vue/actions/Settings3Icon'
import HamburgerMenuIcon from '@bitrix24/b24icons-vue/outline/HamburgerMenuIcon'
import CloudWithCheckIcon from '@bitrix24/b24icons-vue/outline/CloudWithCheckIcon'

const items = [
  {
    label: 'Profile',
    icon: UserIcon,
    slot: 'profile' as const
  }, {
    label: 'Billing',
    icon: PaymentIcon
  }, {
    label: 'Settings',
    icon: Settings3Icon
  }
] satisfies DropdownMenuItem[]
</script>

<template>
  <B24DropdownMenu :items="items" :ui="{ content: 'w-48' }">
    <B24Button label="Open" :icon="HamburgerMenuIcon" />

    <template #profile-trailing>
      <CloudWithCheckIcon class="shrink-0 size-5 text-(--ui-color-accent-main-primary)" />
    </template>
  </B24DropdownMenu>
</template>
You can also use the #item, #item-leading, #item-label and #item-trailing slots to customize all items.

With trigger content width

You can expand the content to the full width of its button by adding the w-(--reka-dropdown-menu-trigger-width) class on the b24ui.content and b24ui.viewport slot.

<script setup lang="ts">
import type { DropdownMenuItem } from '@bitrix24/b24ui-nuxt'
import HamburgerMenuIcon from '@bitrix24/b24icons-vue/outline/HamburgerMenuIcon'
import OpenedEyeIcon from '@bitrix24/b24icons-vue/main/OpenedEyeIcon'
import TrashBinIcon from '@bitrix24/b24icons-vue/main/TrashBinIcon'
import CopyPlatesIcon from '@bitrix24/b24icons-vue/actions/CopyPlatesIcon'
import PencilDrawIcon from '@bitrix24/b24icons-vue/actions/PencilDrawIcon'

const items: DropdownMenuItem[][] = [
  [
    {
      label: 'View',
      icon: OpenedEyeIcon
    },
    {
      label: 'Copy',
      icon: CopyPlatesIcon
    },
    {
      label: 'Edit',
      icon: PencilDrawIcon
    }
  ],
  [
    {
      label: 'Delete',
      color: 'air-primary-alert' as const,
      icon: TrashBinIcon
    }
  ]
]
</script>

<template>
  <B24DropdownMenu :items="items" :b24ui="{ content: 'w-(--reka-dropdown-menu-trigger-width)', viewport: 'w-(--reka-dropdown-menu-trigger-width)' }">
    <B24Button
      label="Open"
      class="w-46"
      block
      :icon="HamburgerMenuIcon"
    />
  </B24DropdownMenu>
</template>

Extract shortcuts

Use the extractShortcuts utility to automatically define shortcuts from menu items with a kbds property. It recursively extracts shortcuts and returns an object compatible with defineShortcuts.

<script setup lang="ts">
import type { DropdownMenuItem } from '@bitrix24/b24ui-nuxt'

const items: DropdownMenuItem[] = [{
  label: 'Invite users',
  children: [{
    label: 'Invite by email',
    kbds: ['meta', 'e'],
    onSelect() {
      console.log('Invite by email clicked')
    }
  }, {
    label: 'Invite by link',
    kbds: ['meta', 'i'],
    onSelect() {
      console.log('Invite by link clicked')
    }
  }]
}, {
  label: 'New team',
  kbds: ['meta', 'n'],
  onSelect() {
    console.log('New team clicked')
  }
}]

defineShortcuts(extractShortcuts(items))
</script>
In this example, E, I and N would trigger the select function of the corresponding item.

API

Props

Prop Default Type
items T
checkedIconicons.checkIconComponent

The icon displayed when an item is checked.

externalIcontrueIconComponent

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

content{ side: 'bottom', sideOffset: 8, collisionPadding: 8 } DropdownMenuContentProps & Partial<EmitsToProps<MenuContentEmits>>

The content of the menu.

arrowfalseboolean | DropdownMenuArrowProps

Display an arrow alongside the menu.

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

disabledfalseboolean
defaultOpenboolean

The open state of the dropdown menu when it is initially rendered. Use when you do not need to control its open state.

openboolean

The controlled open state of the menu. Can be used as v-model:open.

modaltrueboolean

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.

b24ui { content?: ClassNameValue; viewport?: ClassNameValue; arrow?: ClassNameValue; group?: ClassNameValue; label?: ClassNameValue; separator?: ClassNameValue; item?: ClassNameValue; itemLeadingIcon?: ClassNameValue; itemLeadingAvatar?: ClassNameValue; itemLeadingAvatarSize?: ClassNameValue; itemTrailing?: ClassNameValue; itemTrailingIcon?: ClassNameValue; itemTrailingKbds?: ClassNameValue; itemTrailingKbdsSize?: ClassNameValue; itemWrapper?: ClassNameValue; itemLabel?: ClassNameValue; itemDescription?: ClassNameValue; itemLabelExternalIcon?: ClassNameValue; }

Slots

Slot Type
default{ open: boolean; }
item{ item: NestedItem<T>; active: boolean; index: number; b24ui: object; }
item-leading{ item: NestedItem<T>; active: boolean; index: number; b24ui: 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; b24ui: object; }
content-top{ sub: boolean; }
content-bottom{ sub: boolean; }

Emits

Event Type
update:open[payload: boolean]

Theme

app.config.ts
export default defineAppConfig({
  b24ui: {
    dropdownMenu: {
      slots: {
        content: 'base-mode bg-(--ui-color-bg-content-primary) shadow-(--popup-window-box-shadow) rounded-(--ui-border-radius-xl) will-change-[opacity] motion-safe:data-[state=open]:animate-[scale-in_100ms_ease-out] motion-safe:data-[state=closed]:animate-[scale-out_100ms_ease-in] origin-(--reka-dropdown-menu-content-transform-origin) font-[family-name:var(--ui-font-family-primary)] relative isolate px-0 py-(--menu-popup-padding) pointer-events-auto',
        viewport: 'relative w-full max-h-[40vh] min-w-[192px] overflow-x-hidden overflow-y-auto scrollbar-thin',
        arrow: 'fill-(--ui-color-bg-content-primary)',
        group: 'grid',
        label: 'w-full h-(--popup-window-delimiter-section-height) px-[18px] mt-(--menu-item-block-stack-space) flex flex-row rtl:flex-row-reverse items-center select-none outline-none whitespace-nowrap text-start text-(length:--ui-size-sm) text-(--b24ui-typography-legend-color) font-(--ui-font-weight-normal) after:ms-[10px] after:block after:flex-1 after:min-w-[15px] after:h-px after:bg-(--ui-color-divider-vibrant-default)',
        separator: 'my-[8px] mx-[18px] h-[1px] bg-(--ui-color-divider-vibrant-default)',
        item: 'group w-full h-[36px] px-[18px] mt-(--menu-item-block-stack-space) relative flex flex-row rtl:flex-row-reverse items-center select-none outline-none whitespace-nowrap cursor-pointer data-disabled:cursor-not-allowed data-disabled:opacity-30 text-start text-(length:--ui-font-size-md) text-(--b24ui-typography-legend-color) hover:text-(--b24ui-typography-label-color) data-highlighted:text-(--b24ui-typography-label-color) data-[state=open]:text-(--b24ui-typography-label-color) hover:bg-(--ui-color-divider-optical-1-alt) data-highlighted:bg-(--ui-color-divider-optical-1-alt) data-[state=open]:bg-(--ui-color-divider-optical-1-alt) transition-colors',
        itemLeadingIcon: 'shrink-0 size-[18px] text-(--ui-color-design-plain-content-icon-secondary) group-data-highlighted:text-(--ui-color-accent-main-primary) group-data-[state=open]:text-(--ui-color-accent-main-primary) group-data-[state=checked]:text-(--ui-color-accent-main-primary) transition-colors',
        itemLeadingAvatar: 'shrink-0 size-[16px] me-[8px]',
        itemLeadingAvatarSize: '2xs',
        itemTrailing: 'ml-auto rtl:ml-0 rtl:mr-auto inline-flex gap-1.5 items-center',
        itemTrailingIcon: 'shrink-0 size-[24px] text-(--ui-color-accent-main-primary)',
        itemTrailingKbds: 'shrink-0 hidden lg:inline-flex items-center gap-0.5',
        itemTrailingKbdsSize: 'md',
        itemWrapper: 'flex-1 flex flex-col text-start min-w-0',
        itemLabel: 'max-w-[240px] truncate -mt-px group-data-[state=checked]:text-(--ui-color-accent-main-primary)',
        itemDescription: 'max-w-[240px] truncate -mt-[6px] text-(--b24ui-typography-description-color) text-(length:--ui-font-size-sm)',
        itemLabelExternalIcon: 'inline-block size-[16px] text-(--ui-color-design-plain-content-icon-secondary)'
      },
      variants: {
        color: {
          'air-primary': {
            item: 'style-filled'
          },
          'air-primary-success': {
            item: 'style-filled-success'
          },
          'air-primary-alert': {
            item: 'style-filled-alert'
          },
          'air-primary-copilot': {
            item: 'style-filled-copilot'
          },
          'air-primary-warning': {
            item: 'style-filled-warning'
          },
          default: {
            item: 'style-old-default'
          },
          danger: {
            item: 'style-old-danger'
          },
          success: {
            item: 'style-old-success'
          },
          warning: {
            item: 'style-old-warning'
          },
          primary: {
            item: 'style-old-primary'
          },
          secondary: {
            item: 'style-old-secondary'
          },
          collab: {
            item: 'style-old-collab'
          },
          ai: {
            item: 'style-old-ai'
          }
        },
        active: {
          true: {
            item: 'text-(--ui-color-accent-main-primary) hover:text-(--ui-color-accent-main-primary)',
            itemLeadingIcon: 'text-(--ui-color-accent-main-primary) hover:text-(--ui-color-accent-main-primary) group-data-[state=open]:text-(--ui-color-accent-main-primary)'
          },
          false: {}
        },
        loading: {
          true: {
            itemLeadingIcon: 'animate-spin'
          }
        }
      },
      compoundVariants: [],
      defaultVariants: {}
    }
  }
})
vite.config.ts
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import bitrix24UIPluginVite from '@bitrix24/b24ui-nuxt/vite'

export default defineConfig({
  plugins: [
    vue(),
    bitrix24UIPluginVite({
      b24ui: {
        dropdownMenu: {
          slots: {
            content: 'base-mode bg-(--ui-color-bg-content-primary) shadow-(--popup-window-box-shadow) rounded-(--ui-border-radius-xl) will-change-[opacity] motion-safe:data-[state=open]:animate-[scale-in_100ms_ease-out] motion-safe:data-[state=closed]:animate-[scale-out_100ms_ease-in] origin-(--reka-dropdown-menu-content-transform-origin) font-[family-name:var(--ui-font-family-primary)] relative isolate px-0 py-(--menu-popup-padding) pointer-events-auto',
            viewport: 'relative w-full max-h-[40vh] min-w-[192px] overflow-x-hidden overflow-y-auto scrollbar-thin',
            arrow: 'fill-(--ui-color-bg-content-primary)',
            group: 'grid',
            label: 'w-full h-(--popup-window-delimiter-section-height) px-[18px] mt-(--menu-item-block-stack-space) flex flex-row rtl:flex-row-reverse items-center select-none outline-none whitespace-nowrap text-start text-(length:--ui-size-sm) text-(--b24ui-typography-legend-color) font-(--ui-font-weight-normal) after:ms-[10px] after:block after:flex-1 after:min-w-[15px] after:h-px after:bg-(--ui-color-divider-vibrant-default)',
            separator: 'my-[8px] mx-[18px] h-[1px] bg-(--ui-color-divider-vibrant-default)',
            item: 'group w-full h-[36px] px-[18px] mt-(--menu-item-block-stack-space) relative flex flex-row rtl:flex-row-reverse items-center select-none outline-none whitespace-nowrap cursor-pointer data-disabled:cursor-not-allowed data-disabled:opacity-30 text-start text-(length:--ui-font-size-md) text-(--b24ui-typography-legend-color) hover:text-(--b24ui-typography-label-color) data-highlighted:text-(--b24ui-typography-label-color) data-[state=open]:text-(--b24ui-typography-label-color) hover:bg-(--ui-color-divider-optical-1-alt) data-highlighted:bg-(--ui-color-divider-optical-1-alt) data-[state=open]:bg-(--ui-color-divider-optical-1-alt) transition-colors',
            itemLeadingIcon: 'shrink-0 size-[18px] text-(--ui-color-design-plain-content-icon-secondary) group-data-highlighted:text-(--ui-color-accent-main-primary) group-data-[state=open]:text-(--ui-color-accent-main-primary) group-data-[state=checked]:text-(--ui-color-accent-main-primary) transition-colors',
            itemLeadingAvatar: 'shrink-0 size-[16px] me-[8px]',
            itemLeadingAvatarSize: '2xs',
            itemTrailing: 'ml-auto rtl:ml-0 rtl:mr-auto inline-flex gap-1.5 items-center',
            itemTrailingIcon: 'shrink-0 size-[24px] text-(--ui-color-accent-main-primary)',
            itemTrailingKbds: 'shrink-0 hidden lg:inline-flex items-center gap-0.5',
            itemTrailingKbdsSize: 'md',
            itemWrapper: 'flex-1 flex flex-col text-start min-w-0',
            itemLabel: 'max-w-[240px] truncate -mt-px group-data-[state=checked]:text-(--ui-color-accent-main-primary)',
            itemDescription: 'max-w-[240px] truncate -mt-[6px] text-(--b24ui-typography-description-color) text-(length:--ui-font-size-sm)',
            itemLabelExternalIcon: 'inline-block size-[16px] text-(--ui-color-design-plain-content-icon-secondary)'
          },
          variants: {
            color: {
              'air-primary': {
                item: 'style-filled'
              },
              'air-primary-success': {
                item: 'style-filled-success'
              },
              'air-primary-alert': {
                item: 'style-filled-alert'
              },
              'air-primary-copilot': {
                item: 'style-filled-copilot'
              },
              'air-primary-warning': {
                item: 'style-filled-warning'
              },
              default: {
                item: 'style-old-default'
              },
              danger: {
                item: 'style-old-danger'
              },
              success: {
                item: 'style-old-success'
              },
              warning: {
                item: 'style-old-warning'
              },
              primary: {
                item: 'style-old-primary'
              },
              secondary: {
                item: 'style-old-secondary'
              },
              collab: {
                item: 'style-old-collab'
              },
              ai: {
                item: 'style-old-ai'
              }
            },
            active: {
              true: {
                item: 'text-(--ui-color-accent-main-primary) hover:text-(--ui-color-accent-main-primary)',
                itemLeadingIcon: 'text-(--ui-color-accent-main-primary) hover:text-(--ui-color-accent-main-primary) group-data-[state=open]:text-(--ui-color-accent-main-primary)'
              },
              false: {}
            },
            loading: {
              true: {
                itemLeadingIcon: 'animate-spin'
              }
            }
          },
          compoundVariants: [],
          defaultVariants: {}
        }
      }
    })
  ]
})
Some colors in compoundVariants are omitted for readability. Check out the source code on GitHub.
Releases
Published under MIT License.

Copyright © 2024-present Bitrix24