NavigationMenu

A link list that can be arranged in horizontal or vertical orientation.

Usage

Use the NavigationMenu component to display a list of links horizontally or vertically.

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

const items = ref<NavigationMenuItem[]>([
  {
    label: 'Sales management',
    type: 'trigger',
    children: [
      {
        label: 'Lead management'
      },
      {
        label: 'Deal management'
      },
      {
        label: 'Pipelines'
      },
      {
        label: 'Access permissions'
      }
    ]
  },
  {
    label: 'Collaboration',
    type: 'trigger',
    children: [
      {
        label: 'Online workspace',
        to: 'https://www.bitrix24.com/tools/communications/online-workspace.php'
      },
      {
        label: 'CoPilot in Chat',
        to: 'https://www.bitrix24.com/tools/copilot-ai-powered-tools-for-business.php#copilot-in-chat'
      },
      {
        label: 'useToast',
        to: '/docs/composables/use-toast'
      }
    ]
  },
  {
    label: 'HR & Automation',
    type: 'trigger',
    badge: 5,
    active: true,
    children: [
      {
        label: 'Employee management',
        to: 'https://www.bitrix24.com/tools/hr_automation/employee-management.php'
      },
      {
        label: 'Culture & engagement',
        to: 'https://www.bitrix24.com/tools/hr_automation/culture-and-engagement.php'
      },
      {
        label: 'Automation',
        to: 'https://www.bitrix24.com/tools/hr_automation/automation.php',
        target: '_blank'
      }
    ]
  },
  {
    label: 'GitHub',
    to: 'https://github.com/bitrix24/b24ui',
    target: '_blank'
  },
  {
    label: 'Help',
    disabled: true
  }
])
</script>

<template>
  <B24NavigationMenu :items="items" />
</template>

Items

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

  • label?: string
  • icon?: IconComponent
  • avatar?: AvatarProps
  • badge?: string | number | BadgeProps
  • chip?: boolean | ChipProps
  • hint?: string
  • tooltip?: TooltipProps
  • popover?: PopoverProps
  • trailingIcon?: IconComponent
  • type?: 'label' | 'trigger' | 'link'
  • defaultOpen?: boolean
  • open?: boolean
  • value?: string
  • disabled?: boolean
  • slot?: string
  • viewportRtl?: boolean
  • onSelect?: (e: Event) => void
  • children?: NavigationMenuChildItem[]
  • class?: any
  • b24ui?: { linkLeadingAvatarSize?: ClassNameValue, linkLeadingAvatar?: ClassNameValue, linkLeadingIcon?: ClassNameValue, linkLeadingChipSize?: ClassNameValue, linkLabel?: ClassNameValue, linkLabelExternalIcon?: ClassNameValue, linkTrailing?: ClassNameValue, linkLeadingHint?: ClassNameValue, linkLeadingBadgeSize?: ClassNameValue, linkLeadingBadge?: ClassNameValue, linkTrailingIcon?: ClassNameValue, label?: ClassNameValue, link?: ClassNameValue, content?: ClassNameValue, childList?: ClassNameValue, childLabel?: ClassNameValue, childItem?: ClassNameValue, childLink?: ClassNameValue, childLinkIcon?: ClassNameValue, childLinkHint?: ClassNameValue, childLinkBadgeSize?: ClassNameValue, childLinkBadge?: ClassNameValue, childLinkWrapper?: ClassNameValue, childLinkLabel?: ClassNameValue, childLinkLabelExternalIcon?: ClassNameValue, popoverWrapper?: ClassNameValue }

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

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

const items = ref<NavigationMenuItem[]>([
  {
    label: 'Sales management',
    type: 'trigger',
    hint: 'note',
    children: [
      {
        label: 'Lead management'
      },
      {
        label: 'Deal management'
      },
      {
        label: 'Pipelines',
        hint: 'note'
      },
      {
        label: 'Access permissions'
      }
    ]
  },
  {
    label: 'Collaboration',
    type: 'trigger',
    children: [
      {
        label: 'Online workspace',
        to: 'https://www.bitrix24.com/tools/communications/online-workspace.php'
      },
      {
        label: 'CoPilot in Chat',
        to: 'https://www.bitrix24.com/tools/copilot-ai-powered-tools-for-business.php#copilot-in-chat'
      },
      {
        label: 'useToast',
        to: '/docs/composables/use-toast'
      }
    ]
  },
  {
    label: 'HR & Automation',
    type: 'trigger',
    badge: 5,
    active: true,
    children: [
      {
        label: 'Employee management',
        to: 'https://www.bitrix24.com/tools/hr_automation/employee-management.php'
      },
      {
        label: 'Culture & engagement',
        to: 'https://www.bitrix24.com/tools/hr_automation/culture-and-engagement.php'
      },
      {
        label: 'Automation',
        to: 'https://www.bitrix24.com/tools/hr_automation/automation.php',
        target: '_blank'
      }
    ]
  },
  {
    label: 'GitHub',
    to: 'https://github.com/bitrix24/b24ui',
    target: '_blank'
  },
  {
    label: 'Help',
    disabled: true
  }
])
</script>

<template>
  <B24NavigationMenu :items="items" class="w-full justify-center" />
</template>
You can also pass an array of arrays to the items prop to display groups of items.
Use a flat children array of objects to define submenus:
  • label: string
  • icon?: IconComponent
  • onSelect?(e: Event): void
  • class?: any

Orientation

Use the orientation prop to change the orientation of the NavigationMenu.

When orientation is vertical, an Accordion component is used to display each group. You can control the open state of each item using the open and defaultOpen properties and change the behavior using the collapsible and type props.
The last top-level menu item needs to have viewportRtl set to ensure the drop-down menu is positioned correctly.
<script setup lang="ts">
import type { NavigationMenuItem } from '@bitrix24/b24ui-nuxt'

const items = ref<NavigationMenuItem[][]>([
  [
    {
      label: 'Links',
      type: 'label'
    },
    {
      label: 'Sales management',
      type: 'trigger',
      hint: 'note',
      defaultOpen: true,
      children: [
        {
          label: 'Lead management'
        },
        {
          label: 'Deal management'
        },
        {
          label: 'Pipelines',
          hint: 'note'
        },
        {
          label: 'Access permissions'
        }
      ]
    }
  ],
  [
    {
      label: 'GitHub',
      to: 'https://github.com/bitrix24/b24ui',
      target: '_blank'
    },
    {
      label: 'Help',
      disabled: true
    },
    {
      label: 'HR & Automation',
      type: 'trigger',
      viewportRtl: true,
      badge: 5,
      active: true,
      children: [
        {
          label: 'Employee management',
          to: 'https://www.bitrix24.com/tools/hr_automation/employee-management.php'
        },
        {
          label: 'Culture & engagement',
          to: 'https://www.bitrix24.com/tools/hr_automation/culture-and-engagement.php'
        },
        {
          label: 'Automation',
          to: 'https://www.bitrix24.com/tools/hr_automation/automation.php',
          target: '_blank'
        }
      ]
    }
  ]
])
</script>

<template>
  <B24NavigationMenu orientation="vertical" :items="items" class="data-[orientation=vertical]:w-[430px]" />
</template>
Groups will be spaced when orientation is horizontal and separated when orientation is vertical.

Collapsed

In vertical orientation, use the collapsed prop to collapse the NavigationMenu, this can be useful in a sidebar for example.

You can use the tooltip and popover props to display more information on the collapsed items.
<script setup lang="ts">
import type { NavigationMenuItem } from '@bitrix24/b24ui-nuxt'
import ConnectionIcon from '@bitrix24/b24icons-vue/actions/ConnectionIcon'
import Info1Icon from '@bitrix24/b24icons-vue/main/Info1Icon'
import MicrophoneOnIcon from '@bitrix24/b24icons-vue/main/MicrophoneOnIcon'
import CrmMapIcon from '@bitrix24/b24icons-vue/crm/CrmMapIcon'
import Settings5Icon from '@bitrix24/b24icons-vue/editor/Settings5Icon'

const items: NavigationMenuItem[] = [
  {
    label: 'Sales Pipeline',
    icon: ConnectionIcon,
    children: [
      {
        label: 'Lead Generation',
        description: 'Initial contact with potential clients'
      },
      {
        label: 'Lead Qualification',
        description: 'Client potential assessment'
      },
      {
        label: 'Negotiations',
        description: 'Deal terms discussion',
        icon: MicrophoneOnIcon
      }
    ]
  },
  {
    label: 'Sales Analytics',
    icon: CrmMapIcon,
    badge: '+3',
    children: [
      {
        label: 'Sales Reports',
        icon: CrmMapIcon,
        active: true,
        badge: 1
      },
      {
        label: 'Key Metrics',
        icon: Settings5Icon,
        badge: {
          label: 2,
          color: 'air-primary-copilot' as const
        }
      },
      {
        label: 'CRM Integration'
      }
    ]
  },
  {
    label: 'Resources',
    icon: Info1Icon,
    children: [
      {
        label: 'Support',
        icon: Info1Icon,
        disabled: true,
        to: 'https://helpdesk.bitrix24.com/',
        target: '_blank'
      },
      {
        label: 'RestApi Integration'
      }
    ]
  }
]

const isCollapsed = ref(true)
</script>

<template>
  <div class="flex flex-col items-center gap-[4px]">
    <div class="flex flex-row flex-wrap items-center justify-center gap-[4px]">
      <B24Switch v-model="isCollapsed" label="collapsed" />
    </div>
    <B24Separator class="my-[4px]" />
    <B24NavigationMenu
      orientation="vertical"
      :collapsed="isCollapsed"
      :items="items"
      class="data-[collapsed=true]:w-[50px]"
    />
  </div>
</template>

Trailing Icon

Use the trailing-icon prop to customize the trailing Icon of each item. This icon is only displayed when an item has children.

You can also set an icon for a specific item by using the trailingIcon property in the item object.
<script setup lang="ts">
import RocketIcon from '@bitrix24/b24icons-vue/main/RocketIcon'
import type { NavigationMenuItem } from '@bitrix24/b24ui-nuxt'

const items = ref<NavigationMenuItem[]>([
  {
    label: 'Sales management',
    type: 'trigger',
    children: [
      {
        label: 'Lead management'
      },
      {
        label: 'Deal management'
      },
      {
        label: 'Pipelines'
      },
      {
        label: 'Access permissions'
      }
    ]
  },
  {
    label: 'Collaboration',
    type: 'trigger',
    children: [
      {
        label: 'Online workspace',
        to: 'https://www.bitrix24.com/tools/communications/online-workspace.php'
      },
      {
        label: 'CoPilot in Chat',
        to: 'https://www.bitrix24.com/tools/copilot-ai-powered-tools-for-business.php#copilot-in-chat'
      },
      {
        label: 'useToast',
        to: '/docs/composables/use-toast'
      }
    ]
  },
  {
    label: 'HR & Automation',
    type: 'trigger',
    badge: 5,
    active: true,
    children: [
      {
        label: 'Employee management',
        to: 'https://www.bitrix24.com/tools/hr_automation/employee-management.php'
      },
      {
        label: 'Culture & engagement',
        to: 'https://www.bitrix24.com/tools/hr_automation/culture-and-engagement.php'
      },
      {
        label: 'Automation',
        to: 'https://www.bitrix24.com/tools/hr_automation/automation.php',
        target: '_blank'
      }
    ]
  }
])
</script>

<template>
  <B24NavigationMenu :trailing-icon="RocketIcon" :items="items" class="w-full justify-center" />
</template>

Unmount

Use the unmount-on-hide prop to control the content unmounting behavior. Defaults to true.

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

const items = ref<NavigationMenuItem[]>([
  {
    label: 'Sales management',
    type: 'trigger',
    children: [
      {
        label: 'Lead management'
      },
      {
        label: 'Deal management'
      },
      {
        label: 'Pipelines'
      },
      {
        label: 'Access permissions'
      }
    ]
  },
  {
    label: 'Collaboration',
    type: 'trigger',
    children: [
      {
        label: 'Online workspace',
        to: 'https://www.bitrix24.com/tools/communications/online-workspace.php'
      },
      {
        label: 'CoPilot in Chat',
        to: 'https://www.bitrix24.com/tools/copilot-ai-powered-tools-for-business.php#copilot-in-chat'
      },
      {
        label: 'useToast',
        to: '/docs/composables/use-toast'
      }
    ]
  },
  {
    label: 'HR & Automation',
    type: 'trigger',
    badge: 5,
    active: true,
    children: [
      {
        label: 'Employee management',
        to: 'https://www.bitrix24.com/tools/hr_automation/employee-management.php'
      },
      {
        label: 'Culture & engagement',
        to: 'https://www.bitrix24.com/tools/hr_automation/culture-and-engagement.php'
      },
      {
        label: 'Automation',
        to: 'https://www.bitrix24.com/tools/hr_automation/automation.php',
        target: '_blank'
      }
    ]
  }
])
</script>

<template>
  <B24NavigationMenu :unmount-on-hide="false" :items="items" class="w-full justify-center" />
</template>
You can inspect the DOM to see each item's content being rendered.

Examples

Control active item

You can control the active item(s) by using the default-value prop or the v-model directive with the value of the item. If no value is provided, it defaults to item-${index} for top-level items or item-${level}-${index} for nested items.

<script setup lang="ts">
import type { NavigationMenuItem } from '@bitrix24/b24ui-nuxt'
import ConnectionIcon from '@bitrix24/b24icons-vue/actions/ConnectionIcon'
import Info1Icon from '@bitrix24/b24icons-vue/main/Info1Icon'
import MicrophoneOnIcon from '@bitrix24/b24icons-vue/main/MicrophoneOnIcon'
import CrmMapIcon from '@bitrix24/b24icons-vue/crm/CrmMapIcon'
import Settings5Icon from '@bitrix24/b24icons-vue/editor/Settings5Icon'

const items: NavigationMenuItem[] = [
  {
    label: 'Sales Pipeline',
    icon: ConnectionIcon,
    children: [
      {
        label: 'Lead Generation',
        description: 'Initial contact with potential clients'
      },
      {
        label: 'Lead Qualification',
        description: 'Client potential assessment'
      },
      {
        label: 'Negotiations',
        description: 'Deal terms discussion',
        icon: MicrophoneOnIcon
      }
    ]
  },
  {
    label: 'Sales Analytics',
    badge: '+3',
    children: [
      {
        label: 'Sales Reports',
        icon: CrmMapIcon,
        active: true,
        badge: 1
      },
      {
        label: 'Key Metrics',
        icon: Settings5Icon,
        badge: {
          label: 2,
          color: 'air-primary-copilot' as const
        }
      },
      {
        label: 'CRM Integration'
      }
    ]
  },
  {
    label: 'Resources',
    children: [
      {
        label: 'Support',
        icon: Info1Icon,
        disabled: true,
        to: 'https://helpdesk.bitrix24.com/',
        target: '_blank'
      },
      {
        label: 'RestApi Integration'
      }
    ]
  }
]

const active = ref()

defineShortcuts({
  1: () => {
    active.value = 'item-0'
  },
  2: () => {
    active.value = 'item-1'
  },
  3: () => {
    active.value = 'item-2'
  }
})
</script>

<template>
  <B24NavigationMenu v-model="active" :items="items" class="w-full justify-center" />
</template>
Use the value-key prop to change the key used to match items when a v-model or default-value is provided.
In this example, leveraging defineShortcuts, you can switch the active item by pressing 1, 2, or 3.

With tooltip in items

When orientation is vertical and the menu is collapsed, you can set the tooltip prop to true to display a Tooltip around items with their label, but you can also use the tooltip property on each item to override the default tooltip. In horizontal orientation, you can use the tooltip property on each item to display a Tooltip around items.

The tooltip property on an item will always display a tooltip regardless of the global tooltip prop.

You can pass any property from the Tooltip component globally or on each item.

<script setup lang="ts">
import type { NavigationMenuItem, NavigationMenuProps } from '@bitrix24/b24ui-nuxt'
import ConnectionIcon from '@bitrix24/b24icons-vue/actions/ConnectionIcon'
import Info1Icon from '@bitrix24/b24icons-vue/main/Info1Icon'
import MicrophoneOnIcon from '@bitrix24/b24icons-vue/main/MicrophoneOnIcon'
import CrmMapIcon from '@bitrix24/b24icons-vue/crm/CrmMapIcon'
import Settings5Icon from '@bitrix24/b24icons-vue/editor/Settings5Icon'
import GitHubIcon from '@bitrix24/b24icons-vue/social/GitHubIcon'

const items: NavigationMenuItem[] = [
  {
    label: 'Sales Pipeline',
    icon: ConnectionIcon,
    children: [
      {
        label: 'Lead Generation',
        description: 'Initial contact with potential clients'
      },
      {
        label: 'Lead Qualification',
        description: 'Client potential assessment'
      },
      {
        label: 'Negotiations',
        description: 'Deal terms discussion',
        icon: MicrophoneOnIcon
      }
    ]
  },
  {
    label: 'Sales Analytics',
    icon: CrmMapIcon,
    badge: '+3',
    children: [
      {
        label: 'Sales Reports',
        icon: CrmMapIcon,
        active: true,
        badge: 1
      },
      {
        label: 'Key Metrics',
        icon: Settings5Icon,
        badge: {
          label: 2,
          color: 'air-primary-copilot' as const
        }
      },
      {
        label: 'CRM Integration'
      }
    ]
  },
  {
    label: 'Resources',
    icon: Info1Icon,
    children: [
      {
        label: 'Support',
        icon: Info1Icon,
        disabled: true,
        to: 'https://helpdesk.bitrix24.com/',
        target: '_blank'
      },
      {
        label: 'RestApi Integration'
      }
    ]
  },
  {
    label: 'Resources',
    icon: GitHubIcon,
    to: 'https://github.com/bitrix24/b24ui',
    target: '_blank',
    tooltip: {
      text: 'Open on GitHub',
      kbds: ['meta', 'G']
    }
  }
]

const orientation = ref<NavigationMenuProps['orientation']>('vertical')
const idCollapsed = ref(true)
const isTooltip = ref(true)
</script>

<template>
  <div class="flex flex-col items-center gap-[4px]">
    <div class="flex flex-row flex-wrap items-center justify-center gap-[4px]">
      <B24Select v-model="orientation" :items="['horizontal', 'vertical']" class="min-w-[175px]" />
      <B24Switch v-model="idCollapsed" label="collapsed" />
      <B24Switch v-model="isTooltip" label="tooltip" />
    </div>
    <B24Separator class="my-[4px]" />
    <B24NavigationMenu
      :orientation="orientation"
      :collapsed="idCollapsed"
      :tooltip="isTooltip"
      :items="items"
      class="data-[collapsed=true]:w-[50px]"
    />
  </div>
</template>

With popover in items

When orientation is vertical and the menu is collapsed, you can set the popover prop to true to display a Popover around items with their children but you can also use the popover property on each item to override the default popover.

The popover property on an item will always display a popover regardless of the global popover prop.

You can pass any property from the Popover component globally or on each item.

<script setup lang="ts">
import type { NavigationMenuItem } from '@bitrix24/b24ui-nuxt'
import ConnectionIcon from '@bitrix24/b24icons-vue/actions/ConnectionIcon'
import Info1Icon from '@bitrix24/b24icons-vue/main/Info1Icon'
import MicrophoneOnIcon from '@bitrix24/b24icons-vue/main/MicrophoneOnIcon'
import CrmMapIcon from '@bitrix24/b24icons-vue/crm/CrmMapIcon'
import Settings5Icon from '@bitrix24/b24icons-vue/editor/Settings5Icon'

const items: NavigationMenuItem[] = [
  {
    label: 'Sales Pipeline',
    icon: ConnectionIcon,
    children: [
      {
        label: 'Lead Generation',
        description: 'Initial contact with potential clients'
      },
      {
        label: 'Lead Qualification',
        description: 'Client potential assessment'
      },
      {
        label: 'Negotiations',
        description: 'Deal terms discussion',
        icon: MicrophoneOnIcon
      }
    ]
  },
  {
    label: 'Sales Analytics',
    icon: CrmMapIcon,
    badge: '+3',
    children: [
      {
        label: 'Sales Reports',
        icon: CrmMapIcon,
        active: true,
        badge: 1
      },
      {
        label: 'Key Metrics',
        icon: Settings5Icon,
        badge: {
          label: 2,
          color: 'air-primary-copilot' as const
        }
      },
      {
        label: 'CRM Integration'
      }
    ]
  },
  {
    label: 'Resources',
    icon: Info1Icon,
    children: [
      {
        label: 'Support',
        icon: Info1Icon,
        disabled: true,
        to: 'https://helpdesk.bitrix24.com/',
        target: '_blank'
      },
      {
        label: 'RestApi Integration'
      }
    ]
  }
]

const isCollapsed = ref(true)
const isPopover = ref(true)
</script>

<template>
  <div class="flex flex-col items-center gap-[4px]">
    <div class="flex flex-row flex-wrap items-center justify-center gap-[4px]">
      <B24Switch v-model="isCollapsed" label="collapsed" />
      <B24Switch v-model="isPopover" label="popover" />
    </div>
    <B24Separator class="my-[4px]" />
    <B24NavigationMenu
      orientation="vertical"
      :collapsed="isCollapsed"
      :popover="isPopover"
      :items="items"
      class="data-[collapsed=true]:w-[50px]"
    />
  </div>
</template>
You can use the #content slot to customize the content of the popover in the vertical orientation.

With chip in items

Use the chip property to display a Chip around the icon of the items, you can pass any of its props.

<script setup lang="ts">
import type { NavigationMenuItem, NavigationMenuProps } from '@bitrix24/b24ui-nuxt'
import ConnectionIcon from '@bitrix24/b24icons-vue/actions/ConnectionIcon'
import Info1Icon from '@bitrix24/b24icons-vue/main/Info1Icon'
import MicrophoneOnIcon from '@bitrix24/b24icons-vue/main/MicrophoneOnIcon'
import CrmMapIcon from '@bitrix24/b24icons-vue/crm/CrmMapIcon'
import Settings5Icon from '@bitrix24/b24icons-vue/editor/Settings5Icon'

const items: NavigationMenuItem[] = [
  {
    label: 'Sales Pipeline',
    icon: ConnectionIcon,
    chip: { color: 'air-primary-alert' },
    children: [
      {
        label: 'Lead Generation',
        description: 'Initial contact with potential clients'
      },
      {
        label: 'Lead Qualification',
        description: 'Client potential assessment'
      },
      {
        label: 'Negotiations',
        description: 'Deal terms discussion',
        chip: { color: 'air-primary-alert' },
        icon: MicrophoneOnIcon
      }
    ]
  },
  {
    label: 'Sales Analytics',
    icon: CrmMapIcon,
    chip: { color: 'air-primary', text: 3 },
    children: [
      {
        label: 'Sales Reports',
        icon: CrmMapIcon,
        active: true,
        chip: { text: 1 }
      },
      {
        label: 'Key Metrics',
        icon: Settings5Icon,
        chip: { color: 'air-primary-copilot', text: 2 }
      },
      {
        label: 'CRM Integration'
      }
    ]
  },
  {
    label: 'Resources',
    icon: Info1Icon,
    chip: true,
    children: [
      {
        label: 'Support',
        icon: Info1Icon,
        disabled: true,
        to: 'https://helpdesk.bitrix24.com/',
        target: '_blank'
      },
      {
        label: 'RestApi Integration'
      }
    ]
  }
]

const orientation = ref<NavigationMenuProps['orientation']>('horizontal')
const isCollapsed = ref(false)
const isPopover = ref(false)
</script>

<template>
  <div class="flex flex-col items-center gap-[4px]">
    <div class="flex flex-row flex-wrap items-center justify-center gap-[4px]">
      <B24Select v-model="orientation" :items="['horizontal', 'vertical']" class="min-w-[175px]" />
      <B24Switch v-model="isCollapsed" label="collapsed" />
      <B24Switch v-model="isPopover" label="popover" />
    </div>
    <B24Separator class="my-[4px]" />
    <B24NavigationMenu
      :orientation="orientation"
      :collapsed="isCollapsed"
      :popover="isPopover"
      :items="items"
      class="data-[collapsed=true]:w-[50px]"
    />
  </div>
</template>

With bottom tab bar

Use the b24ui prop to transform the NavigationMenu into a mobile-style bottom tab bar with icons and small labels.

<script setup lang="ts">
import type { NavigationMenuItem } from '@bitrix24/b24ui-nuxt'
import HomeIcon from '@bitrix24/b24icons-vue/outline/HomeIcon'
import PlayIcon from '@bitrix24/b24icons-vue/common-service/PlayIcon'
import CompassIcon from '@bitrix24/b24icons-vue/main/CompassIcon'
import BookmarkIcon from '@bitrix24/b24icons-vue/outline/BookmarkIcon'

const items: NavigationMenuItem[] = [
  {
    label: 'Home',
    icon: HomeIcon,
    active: true
  },
  {
    label: 'Samples',
    icon: PlayIcon
  },
  {
    label: 'Explore',
    icon: CompassIcon
  },
  {
    label: 'Library',
    icon: BookmarkIcon
  }
]

const b24UiCustom = ref({
  root: 'justify-around border-t border-(--ui-color-divider-default) py-2',
  link: 'h-[64px]',
  item: 'py-0',
  linkLabelWrapper: 'flex-col gap-1 px-3',
  linkLeadingIcon: 'size-8',
  linkLabel: 'text-[10px]/3 font-normal'
})
</script>

<template>
  <B24NavigationMenu
    :items="items"
    :b24ui="b24UiCustom"
    class="w-full"
  >
    <template #item-leading="{ item, active, b24ui }">
      <template v-if="item.icon">
        <Component
          :is="item.icon"
          class="size-5"
          :class="b24ui.linkLeadingIcon({ class: [b24UiCustom?.linkLeadingIcon], active, disabled: !!item.disabled })"
        />
      </template>
    </template>
  </B24NavigationMenu>
</template>

With collapsed labels

Use the b24ui prop to display a label underneath each icon when collapsed.

<script setup lang="ts">
import type { NavigationMenuItem } from '@bitrix24/b24ui-nuxt'
import HomeIcon from '@bitrix24/b24icons-vue/outline/HomeIcon'
import PlayIcon from '@bitrix24/b24icons-vue/common-service/PlayIcon'
import CompassIcon from '@bitrix24/b24icons-vue/main/CompassIcon'
import BookmarkIcon from '@bitrix24/b24icons-vue/outline/BookmarkIcon'

const items: NavigationMenuItem[] = [
  {
    label: 'Home',
    icon: HomeIcon,
    active: true
  },
  {
    label: 'Samples',
    icon: PlayIcon
  },
  {
    label: 'Explore',
    icon: CompassIcon
  },
  {
    label: 'Library',
    icon: BookmarkIcon
  }
]

const b24UiCustom = ref({
  root: 'w-[76px] ps-0',
  item: 'w-[54px]',
  link: 'h-[54px]',
  linkLabelWrapper: 'h-[44px] w-[44px] flex-col gap-0.5 px-3',
  linkLabel: 'block text-[10px]/3 text-center'
})
</script>

<template>
  <B24NavigationMenu
    collapsed
    orientation="vertical"
    :items="items"
    :b24ui="b24UiCustom"
  />
</template>

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
  • #{{ item.slot }}-content
<script setup lang="ts">
import type { NavigationMenuItem } from '@bitrix24/b24ui-nuxt'
import ConnectionIcon from '@bitrix24/b24icons-vue/actions/ConnectionIcon'
import Info1Icon from '@bitrix24/b24icons-vue/main/Info1Icon'

const items = [
  {
    label: 'Sales Pipeline',
    icon: ConnectionIcon
  },
  {
    label: 'Sales Analytics',
    badge: '+3'
  },
  {
    label: 'Resources'
  },
  {
    label: 'Support',
    icon: Info1Icon,
    slot: 'support' as const
  }
] satisfies NavigationMenuItem[]
</script>

<template>
  <B24NavigationMenu :items="items" class="w-full justify-center">
    <template #support-trailing>
      <B24Badge label="44" size="sm" />
    </template>
  </B24NavigationMenu>
</template>
You can also use the #item, #item-leading, #item-label, #item-trailing and #item-content slots to customize all items.

With trailing slot

Use the #item-trailing slot or the slot property (#{{ item.slot }}-trailing) to add a DropdownMenu that appears on hover, similar to Notion or Linear.

<script setup lang="ts">
import type { NavigationMenuItem, DropdownMenuItem } from '@bitrix24/b24ui-nuxt'
import FolderIcon from '@bitrix24/b24icons-vue/outline/FolderIcon'
import BookOpenIcon from '@bitrix24/b24icons-vue/crm/BookOpenIcon'
import Share1Icon from '@bitrix24/b24icons-vue/main/Share1Icon'
import TrashcanIcon from '@bitrix24/b24icons-vue/outline/TrashcanIcon'
import PlusLIcon from '@bitrix24/b24icons-vue/outline/PlusLIcon'
import MoreMIcon from '@bitrix24/b24icons-vue/outline/MoreMIcon'

const items: NavigationMenuItem[][] = [
  [
    {
      label: 'Personal',
      type: 'label',
      slot: 'personal-label' as const
    },
    {
      label: 'Design System',
      icon: FolderIcon,
      active: true
    },
    {
      label: 'Travel',
      icon: FolderIcon
    }
  ],
  [
    {
      label: 'Teams',
      type: 'label',
      slot: 'teams-label' as const
    },
    {
      label: 'Engineering',
      icon: FolderIcon
    },
    {
      label: 'Marketing',
      icon: FolderIcon
    }
  ]
]

const dropdownItems: DropdownMenuItem[][] = [
  [
    { label: 'View Project', icon: BookOpenIcon },
    { label: 'Share Project', icon: Share1Icon }
  ],
  [
    { label: 'Delete Project', icon: TrashcanIcon, color: 'air-primary-alert' }
  ]
]
</script>

<template>
  <B24NavigationMenu
    orientation="vertical"
    :items="items"
    :b24ui="{ label: 'flex items-center justify-between gap-1.5 ' }"
    class="w-48"
  >
    <template #personal-label-trailing>
      <B24Button :icon="PlusLIcon" color="air-tertiary" size="xs" />
    </template>

    <template #teams-label-trailing>
      <B24Button :icon="PlusLIcon" color="air-tertiary" size="xs" />
    </template>

    <template #item-trailing>
      <div class="flex -mr-1.5 -my-0.5 translate-x-full group-hover:translate-x-0 has-data-[state=open]:translate-x-0 transition-transform">
        <B24DropdownMenu
          :items="dropdownItems"
          :content="{ align: 'start' }"
          :modal="false"
          size="xs"
        >
          <B24Button
            as="div"
            :icon="MoreMIcon"
            color="air-tertiary"
            size="xs"
            class="text-(--b24ui-typography-description-color) hover:text-(--b24ui-typography-label-color) hover:bg-(--ui-color-accent-soft-element-blue)/40 data-[state=open]:bg-(--ui-color-accent-soft-element-blue)/30 mr-1.5"
          />
        </B24DropdownMenu>
      </div>
    </template>
  </B24NavigationMenu>
</template>

With content slot

Use the #item-content slot or the slot property (#{{ item.slot }}-content) to customize the content of a specific item.

<script setup lang="ts">
import type { NavigationMenuItem } from '@bitrix24/b24ui-nuxt'
import ConnectionIcon from '@bitrix24/b24icons-vue/actions/ConnectionIcon'
import MicrophoneOnIcon from '@bitrix24/b24icons-vue/main/MicrophoneOnIcon'
import GitHubIcon from '@bitrix24/b24icons-vue/social/GitHubIcon'
import CrmMapIcon from '@bitrix24/b24icons-vue/crm/CrmMapIcon'
import Settings5Icon from '@bitrix24/b24icons-vue/editor/Settings5Icon'

const items = [
  {
    label: 'Sales Pipeline',
    icon: ConnectionIcon,
    slot: 'pipeline' as const,
    children: [
      {
        label: 'Lead Generation',
        description: 'Initial contact with potential clients'
      },
      {
        label: 'Lead Qualification',
        description: 'Client potential assessment'
      },
      {
        label: 'Negotiations',
        description: 'Deal terms discussion',
        icon: MicrophoneOnIcon
      }
    ]
  },
  {
    label: 'Sales Analytics',
    badge: '+3',
    children: [
      {
        label: 'Sales Reports',
        icon: CrmMapIcon,
        active: true,
        badge: 1
      },
      {
        label: 'Key Metrics',
        icon: Settings5Icon,
        badge: {
          label: 2,
          color: 'air-primary-copilot' as const
        }
      },
      {
        label: 'CRM Integration'
      }
    ]
  },
  {
    label: 'GitHub',
    icon: GitHubIcon,
    to: 'https://github.com/bitrix24/b24ui',
    target: '_blank'
  }
] satisfies NavigationMenuItem[]
</script>

<template>
  <B24NavigationMenu
    :items="items"
    :b24ui="{
      viewport: 'sm:w-(--reka-navigation-menu-viewport-width)',
      content: 'sm:w-auto',
      childList: 'sm:w-[380px]'
    }"
    class="w-full justify-center"
  >
    <template #pipeline-content="{ item }">
      <ul class="grid gap-2 p-4 lg:w-[500px] lg:grid-cols-[minmax(0,.75fr)_minmax(0,1fr)]">
        <li class="row-span-3">
          <Placeholder class="size-full min-h-[203px]" />
        </li>

        <li v-for="child in item.children" :key="child.label">
          <B24Link class="group text-(length:--ui-font-size-sm) text-left rounded-(--ui-border-radius-md) p-3 transition-colors hover:no-underline hover:bg-(--ui-color-bg-content-secondary)">
            <p class="font-(--ui-font-weight-medium) text-(--b24ui-typography-legend-color) group-hover:text-(--ui-color-accent-main-primary-alt-2)">
              {{ child.label }}
            </p>
            <p class="text-(--b24ui-typography-description-color) line-clamp-2">
              {{ child.description }}
            </p>
          </B24Link>
        </li>
      </ul>
    </template>
  </B24NavigationMenu>
</template>
In this example, we add the sm:w-(--reka-navigation-menu-viewport-width) class on the viewport to have a dynamic width. This requires to set a width on the content's first child.

API

Props

Prop Default Type
as'div'any

The element or component this component should render as.

type'multiple' K

Determines whether a "single" or "multiple" items can be selected at a time.

Only works when orientation is vertical.

modelValue NavigationMenuModelValue<K, O>

The controlled value of the active item(s).

  • In horizontal orientation: always string
  • In vertical orientation with type="single": string
  • In vertical orientation with type="multiple": string[]

Use this when you need to control the state of the items. Can be binded with v-model

defaultValue NavigationMenuModelValue<K, O>

The default active value of the item(s).

  • In horizontal orientation: always string
  • In vertical orientation with type="single": string
  • In vertical orientation with type="multiple": string[]

Use when you do not need to control the state of the item(s).

trailingIconicons.chevronDownIconComponent

The icon displayed to open the menu.

externalIcontrueIconComponent

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

items T
orientation'horizontal' O

The orientation of the menu.

collapsedfalseboolean

Collapse the navigation menu to only show icons. Only works when orientation is vertical.

tooltipfalseboolean | TooltipProps

Display a tooltip on the items with the label of the item. Only works when orientation is vertical and collapsed is true. { delayDuration: 0, content: { side: 'right' } }

popoverfalseboolean | PopoverProps<PopoverMode>

Display a popover on the items when the menu is collapsed with the children list. { mode: 'hover', content: { side: 'right', align: 'center', alignOffset: 2 } }

content NavigationMenuContentProps & Partial<EmitsToProps<DismissableLayerEmits>>

The content of the menu.

valueKey'value' keyof Extract<NestedItem<T>, object> & string | DotPathKeys<Extract<NestedItem<T>, object>>

The key used to get the value from the item.

labelKey'label' keyof Extract<NestedItem<T>, object> & string | DotPathKeys<Extract<NestedItem<T>, object>>

The key used to get the label from the item.

delayDuration0 number

The duration from when the pointer enters the trigger until the tooltip gets opened.

disableClickTriggerfalseboolean

If true, menu cannot be open by click on trigger

disableHoverTriggerfalseboolean

If true, menu cannot be open by hover on trigger

skipDelayDuration300 number

How much time a user has to enter another trigger without incurring a delay again.

disablePointerLeaveClosefalseboolean

If true, menu will not close during pointer leave event

unmountOnHidetrueboolean

When true, the element will be unmounted on closed state.

disabledfalseboolean

When true, prevents the user from interacting with the accordion and all its items

collapsibletrueboolean

When type is "single", allows closing content when clicking trigger for an open item. When type is "multiple", this prop has no effect.

b24ui { root?: ClassNameValue; list?: ClassNameValue; label?: ClassNameValue; item?: ClassNameValue; link?: ClassNameValue; linkLeadingIcon?: ClassNameValue; linkLeadingAvatar?: ClassNameValue; linkLeadingAvatarSize?: ClassNameValue; linkLeadingChipSize?: ClassNameValue; linkLeadingHint?: ClassNameValue; linkLeadingBadge?: ClassNameValue; linkLeadingBadgeSize?: ClassNameValue; linkTrailing?: ClassNameValue; linkTrailingIcon?: ClassNameValue; linkLabel?: ClassNameValue; linkLabelWrapper?: ClassNameValue; linkLabelExternalIcon?: ClassNameValue; childList?: ClassNameValue; childLabel?: ClassNameValue; childItem?: ClassNameValue; childLink?: ClassNameValue; childLinkWrapper?: ClassNameValue; childLinkIcon?: ClassNameValue; childLinkHint?: ClassNameValue; childLinkBadge?: ClassNameValue; childLinkBadgeSize?: ClassNameValue; childLinkLabel?: ClassNameValue; childLinkLabelExternalIcon?: ClassNameValue; separator?: ClassNameValue; popoverWrapper?: ClassNameValue; viewportWrapper?: ClassNameValue; viewport?: ClassNameValue; content?: ClassNameValue; }

Slots

Slot Type
item{ item: NestedItem<T>; index: number; active: boolean; b24ui: object; }
item-leading{ item: NestedItem<T>; index: number; active: boolean; b24ui: object; }
item-label{ item: NestedItem<T>; index: number; active: boolean; }
item-trailing{ item: NestedItem<T>; index: number; active: boolean; b24ui: object; }
item-content{ item: NestedItem<T>; index: number; active: boolean; b24ui: object; }
list-leading{}
list-trailing{}

Emits

Event Type
update:modelValue[value: NavigationMenuModelValue<K, O> | undefined]

Theme

app.config.ts
export default defineAppConfig({
  b24ui: {
    navigationMenu: {
      slots: {
        root: 'relative flex [&>div]:min-w-0 font-[family-name:var(--ui-font-family-secondary)]',
        list: 'isolate min-w-0',
        label: 'w-full h-[22px] overflow-hidden mt-[10px] opacity-70 text-(length:--ui-font-size-sm)',
        item: 'min-w-0',
        link: 'min-w-[38px] w-full max-w-full p-0 m-0 group relative cursor-pointer flex items-center gap-[2px] font-(--ui-font-weight-normal) text-(length:--ui-font-size-lg) focus:outline-none focus-visible:rounded-(--menu-item-border-radius) focus-visible:outline-none focus-visible:ring-inset focus-visible:ring-1 focus-visible:ring-(--ui-color-base-4) rounded-(--menu-item-border-radius) text-(--menu-item-color) bg-(--menu-item-background) hover:bg-(--menu-item-background-hover) data-[state=open]:bg-(--menu-item-background-hover) border-0',
        linkLeadingIcon: 'shrink-0 size-[26px]',
        linkLeadingAvatar: 'shrink-0',
        linkLeadingAvatarSize: 'xs',
        linkLeadingChipSize: 'sm',
        linkLeadingHint: 'inline-flex m-0 absolute -top-[5px] left-[8px] text-(length:--ui-font-size-4xs) leading-[8px] font-semibold text-(--b24ui-typography-description-color) uppercase ml-px',
        linkLeadingBadge: 'inline-flex m-0 absolute',
        linkLeadingBadgeSize: 'xs',
        linkTrailing: 'group inline-flex mt-[2px] items-center',
        linkTrailingIcon: 'text-(--ui-color-design-plain-na-content-icon) shrink-0',
        linkLabel: 'truncate',
        linkLabelWrapper: 'flex items-center justify-between rtl:flex-row-reverse',
        linkLabelExternalIcon: 'inline-block size-[16px] text-(--ui-color-design-plain-content-icon-secondary)',
        childList: 'isolate',
        childLabel: '',
        childItem: 'h-[36px] mt-(--menu-item-block-stack-space)',
        childLink: 'group relative size-full flex flex-row rtl:flex-row-reverse items-center transition-colors text-start',
        childLinkWrapper: 'min-w-0 flex-1 flex flex-row items-center justify-start rtl:justify-end gap-0.5',
        childLinkIcon: 'size-[18px] shrink-0',
        childLinkHint: 'inline-flex m-0 absolute -top-[2px] left-[24px] text-(length:--ui-font-size-4xs) leading-[8px] font-semibold text-(--b24ui-typography-description-color) uppercase ml-px',
        childLinkBadge: 'inline-flex m-0',
        childLinkBadgeSize: 'xs',
        childLinkLabel: 'truncate ms-[2px] -mt-px',
        childLinkLabelExternalIcon: 'inline-block size-4 text-(--ui-color-design-plain-content-icon-secondary)',
        separator: 'h-px bg-(--leftmenu-bg-divider) my-[16px]',
        popoverWrapper: 'px-0 py-(--menu-popup-padding)',
        viewportWrapper: 'absolute top-[53px] left-0 flex w-full',
        viewport: 'relative overflow-hidden w-full base-mode bg-(--ui-color-bg-content-primary) shadow-(--popup-window-box-shadow) h-(--reka-navigation-menu-viewport-height) w-(--reka-navigation-menu-viewport-width) left-(--reka-navigation-menu-viewport-left) rounded-(--ui-border-radius-xl) will-change-[opacity] [&:has(>[data-viewport=rtl])]:left-auto [&:has(>[data-viewport=rtl])]:-right-[calc(100%-var(--reka-navigation-menu-viewport-width))] transition-[width,height] duration-200 origin-[top_center] z-[1]',
        content: ''
      },
      variants: {
        orientation: {
          horizontal: {
            root: 'relative h-full items-center justify-between',
            list: 'flex items-center gap-x-1 h-full',
            item: 'empty:hidden',
            link: 'menu-item-horizontal h-[32px] min-h-[32px] px-[10px] border border-(--menu-item-background) hover:border-(--ui-color-design-plain-na-focused-stroke) data-[state=open]:bg-(--ui-color-design-plain-na-focused-stroke)',
            linkTrailingIcon: 'size-[16px]',
            linkLeadingBadge: '-top-[6px] -right-[14px] -translate-x-1/2',
            linkLabelWrapper: 'gap-[4px] truncate',
            childList: 'grid px-0 py-(--menu-popup-padding)',
            childLink: 'px-[18px] min-w-[195px] whitespace-nowrap font-[family-name:var(--ui-font-family-primary)] text-(length:--ui-font-size-md) text-(--b24ui-typography-legend-color) hover:text-(--b24ui-typography-label-color) hover:bg-(--ui-color-divider-optical-1-alt)',
            childLinkLabel: '',
            content: 'absolute top-0 left-0 w-full max-h-[70vh] overflow-y-auto scrollbar-thin scrollbar-transparent'
          },
          vertical: {
            root: 'flex-col w-full ps-(--menu-items-block-padding-x) rtl:pe-(--menu-items-block-padding-x)',
            list: 'flex flex-col',
            item: 'mt-(--menu-item-block-stack-space) data-[state=open]:rounded-(--menu-item-border-radius) data-[state=open]:border-(length:--leftmenu-group-stroke-weight) data-[state=open]:border-(--leftmenu-group-stroke)',
            link: 'menu-item-vertical overflow-hidden h-[38px] min-h-[38px] p-[6px] flex-row rtl:flex-row-reverse justify-between data-[state=open]:text-(length:--ui-font-size-sm) data-[state=open]:opacity-70',
            linkLeadingIcon: '',
            linkTrailingIcon: 'size-[20px] group-data-[state=open]:rotate-180 transition-transform duration-200',
            linkLeadingBadge: '-top-[4px] left-[24px] -translate-x-1/2',
            linkLabelWrapper: 'relative h-[22px]',
            childList: '',
            childLink: 'px-[18px] min-w-[195px] whitespace-nowrap font-[family-name:var(--ui-font-family-primary)] text-(length:--ui-font-size-md) text-(--b24ui-typography-legend-color) hover:text-(--b24ui-typography-label-color) hover:bg-(--ui-color-divider-optical-1-alt)',
            childLabel: 'w-full min-w-[195px] 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)'
          }
        },
        active: {
          true: {
            childLink: 'text-(--ui-color-accent-main-primary) hover:text-(--ui-color-accent-main-primary)',
            childLinkIcon: 'text-(--ui-color-accent-main-primary)'
          },
          false: {
            linkLeadingIcon: 'text-(--ui-color-design-plain-content-icon-secondary)',
            childLinkIcon: 'text-(--ui-color-design-plain-content-icon-secondary) group-hover:text-(--ui-color-accent-main-primary)'
          }
        },
        disabled: {
          true: {
            link: 'cursor-not-allowed opacity-75'
          }
        },
        level: {
          true: ''
        },
        collapsed: {
          true: ''
        }
      },
      compoundVariants: [
        {
          orientation: 'horizontal',
          class: {
            childList: '',
            content: 'w-[240px]'
          }
        },
        {
          orientation: 'vertical',
          collapsed: false,
          class: {
            item: 'data-[state=open]:bg-(--leftmenu-group-bg)',
            childList: '',
            childItem: '',
            content: 'motion-safe:data-[state=open]:animate-[collapsible-down_200ms_ease-out] motion-safe:data-[state=closed]:animate-[collapsible-up_200ms_ease-out] overflow-hidden',
            linkLabel: 'ms-[9px]'
          }
        },
        {
          orientation: 'vertical',
          collapsed: true,
          class: {
            childList: 'grid px-0 py-(--menu-popup-padding)',
            linkLabel: 'hidden',
            linkLabelExternalIcon: 'hidden',
            linkTrailing: 'hidden'
          }
        },
        {
          orientation: 'vertical',
          collapsed: false,
          class: {
            link: 'collapsed data-[state=open]:-mt-(--leftmenu-group-stroke-weight) data-[state=open]:-mx-(--leftmenu-group-stroke-weight)'
          }
        },
        {
          disabled: false,
          active: false,
          class: {
            link: 'transition-colors',
            linkLeadingIcon: 'group-hover:text-(--ui-color-design-selection-content-icon)'
          }
        },
        {
          active: true,
          class: {
            link: 'leading-9 text-(--menu-item-color-active) bg-(--menu-item-background-active)'
          }
        },
        {
          active: true,
          orientation: 'horizontal',
          class: {
            link: 'menu-item-horizontal-active border-(--menu-item-border)'
          }
        },
        {
          active: true,
          orientation: 'vertical',
          class: {
            link: 'menu-item-vertical-active'
          }
        }
      ],
      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: {
        navigationMenu: {
          slots: {
            root: 'relative flex [&>div]:min-w-0 font-[family-name:var(--ui-font-family-secondary)]',
            list: 'isolate min-w-0',
            label: 'w-full h-[22px] overflow-hidden mt-[10px] opacity-70 text-(length:--ui-font-size-sm)',
            item: 'min-w-0',
            link: 'min-w-[38px] w-full max-w-full p-0 m-0 group relative cursor-pointer flex items-center gap-[2px] font-(--ui-font-weight-normal) text-(length:--ui-font-size-lg) focus:outline-none focus-visible:rounded-(--menu-item-border-radius) focus-visible:outline-none focus-visible:ring-inset focus-visible:ring-1 focus-visible:ring-(--ui-color-base-4) rounded-(--menu-item-border-radius) text-(--menu-item-color) bg-(--menu-item-background) hover:bg-(--menu-item-background-hover) data-[state=open]:bg-(--menu-item-background-hover) border-0',
            linkLeadingIcon: 'shrink-0 size-[26px]',
            linkLeadingAvatar: 'shrink-0',
            linkLeadingAvatarSize: 'xs',
            linkLeadingChipSize: 'sm',
            linkLeadingHint: 'inline-flex m-0 absolute -top-[5px] left-[8px] text-(length:--ui-font-size-4xs) leading-[8px] font-semibold text-(--b24ui-typography-description-color) uppercase ml-px',
            linkLeadingBadge: 'inline-flex m-0 absolute',
            linkLeadingBadgeSize: 'xs',
            linkTrailing: 'group inline-flex mt-[2px] items-center',
            linkTrailingIcon: 'text-(--ui-color-design-plain-na-content-icon) shrink-0',
            linkLabel: 'truncate',
            linkLabelWrapper: 'flex items-center justify-between rtl:flex-row-reverse',
            linkLabelExternalIcon: 'inline-block size-[16px] text-(--ui-color-design-plain-content-icon-secondary)',
            childList: 'isolate',
            childLabel: '',
            childItem: 'h-[36px] mt-(--menu-item-block-stack-space)',
            childLink: 'group relative size-full flex flex-row rtl:flex-row-reverse items-center transition-colors text-start',
            childLinkWrapper: 'min-w-0 flex-1 flex flex-row items-center justify-start rtl:justify-end gap-0.5',
            childLinkIcon: 'size-[18px] shrink-0',
            childLinkHint: 'inline-flex m-0 absolute -top-[2px] left-[24px] text-(length:--ui-font-size-4xs) leading-[8px] font-semibold text-(--b24ui-typography-description-color) uppercase ml-px',
            childLinkBadge: 'inline-flex m-0',
            childLinkBadgeSize: 'xs',
            childLinkLabel: 'truncate ms-[2px] -mt-px',
            childLinkLabelExternalIcon: 'inline-block size-4 text-(--ui-color-design-plain-content-icon-secondary)',
            separator: 'h-px bg-(--leftmenu-bg-divider) my-[16px]',
            popoverWrapper: 'px-0 py-(--menu-popup-padding)',
            viewportWrapper: 'absolute top-[53px] left-0 flex w-full',
            viewport: 'relative overflow-hidden w-full base-mode bg-(--ui-color-bg-content-primary) shadow-(--popup-window-box-shadow) h-(--reka-navigation-menu-viewport-height) w-(--reka-navigation-menu-viewport-width) left-(--reka-navigation-menu-viewport-left) rounded-(--ui-border-radius-xl) will-change-[opacity] [&:has(>[data-viewport=rtl])]:left-auto [&:has(>[data-viewport=rtl])]:-right-[calc(100%-var(--reka-navigation-menu-viewport-width))] transition-[width,height] duration-200 origin-[top_center] z-[1]',
            content: ''
          },
          variants: {
            orientation: {
              horizontal: {
                root: 'relative h-full items-center justify-between',
                list: 'flex items-center gap-x-1 h-full',
                item: 'empty:hidden',
                link: 'menu-item-horizontal h-[32px] min-h-[32px] px-[10px] border border-(--menu-item-background) hover:border-(--ui-color-design-plain-na-focused-stroke) data-[state=open]:bg-(--ui-color-design-plain-na-focused-stroke)',
                linkTrailingIcon: 'size-[16px]',
                linkLeadingBadge: '-top-[6px] -right-[14px] -translate-x-1/2',
                linkLabelWrapper: 'gap-[4px] truncate',
                childList: 'grid px-0 py-(--menu-popup-padding)',
                childLink: 'px-[18px] min-w-[195px] whitespace-nowrap font-[family-name:var(--ui-font-family-primary)] text-(length:--ui-font-size-md) text-(--b24ui-typography-legend-color) hover:text-(--b24ui-typography-label-color) hover:bg-(--ui-color-divider-optical-1-alt)',
                childLinkLabel: '',
                content: 'absolute top-0 left-0 w-full max-h-[70vh] overflow-y-auto scrollbar-thin scrollbar-transparent'
              },
              vertical: {
                root: 'flex-col w-full ps-(--menu-items-block-padding-x) rtl:pe-(--menu-items-block-padding-x)',
                list: 'flex flex-col',
                item: 'mt-(--menu-item-block-stack-space) data-[state=open]:rounded-(--menu-item-border-radius) data-[state=open]:border-(length:--leftmenu-group-stroke-weight) data-[state=open]:border-(--leftmenu-group-stroke)',
                link: 'menu-item-vertical overflow-hidden h-[38px] min-h-[38px] p-[6px] flex-row rtl:flex-row-reverse justify-between data-[state=open]:text-(length:--ui-font-size-sm) data-[state=open]:opacity-70',
                linkLeadingIcon: '',
                linkTrailingIcon: 'size-[20px] group-data-[state=open]:rotate-180 transition-transform duration-200',
                linkLeadingBadge: '-top-[4px] left-[24px] -translate-x-1/2',
                linkLabelWrapper: 'relative h-[22px]',
                childList: '',
                childLink: 'px-[18px] min-w-[195px] whitespace-nowrap font-[family-name:var(--ui-font-family-primary)] text-(length:--ui-font-size-md) text-(--b24ui-typography-legend-color) hover:text-(--b24ui-typography-label-color) hover:bg-(--ui-color-divider-optical-1-alt)',
                childLabel: 'w-full min-w-[195px] 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)'
              }
            },
            active: {
              true: {
                childLink: 'text-(--ui-color-accent-main-primary) hover:text-(--ui-color-accent-main-primary)',
                childLinkIcon: 'text-(--ui-color-accent-main-primary)'
              },
              false: {
                linkLeadingIcon: 'text-(--ui-color-design-plain-content-icon-secondary)',
                childLinkIcon: 'text-(--ui-color-design-plain-content-icon-secondary) group-hover:text-(--ui-color-accent-main-primary)'
              }
            },
            disabled: {
              true: {
                link: 'cursor-not-allowed opacity-75'
              }
            },
            level: {
              true: ''
            },
            collapsed: {
              true: ''
            }
          },
          compoundVariants: [
            {
              orientation: 'horizontal',
              class: {
                childList: '',
                content: 'w-[240px]'
              }
            },
            {
              orientation: 'vertical',
              collapsed: false,
              class: {
                item: 'data-[state=open]:bg-(--leftmenu-group-bg)',
                childList: '',
                childItem: '',
                content: 'motion-safe:data-[state=open]:animate-[collapsible-down_200ms_ease-out] motion-safe:data-[state=closed]:animate-[collapsible-up_200ms_ease-out] overflow-hidden',
                linkLabel: 'ms-[9px]'
              }
            },
            {
              orientation: 'vertical',
              collapsed: true,
              class: {
                childList: 'grid px-0 py-(--menu-popup-padding)',
                linkLabel: 'hidden',
                linkLabelExternalIcon: 'hidden',
                linkTrailing: 'hidden'
              }
            },
            {
              orientation: 'vertical',
              collapsed: false,
              class: {
                link: 'collapsed data-[state=open]:-mt-(--leftmenu-group-stroke-weight) data-[state=open]:-mx-(--leftmenu-group-stroke-weight)'
              }
            },
            {
              disabled: false,
              active: false,
              class: {
                link: 'transition-colors',
                linkLeadingIcon: 'group-hover:text-(--ui-color-design-selection-content-icon)'
              }
            },
            {
              active: true,
              class: {
                link: 'leading-9 text-(--menu-item-color-active) bg-(--menu-item-background-active)'
              }
            },
            {
              active: true,
              orientation: 'horizontal',
              class: {
                link: 'menu-item-horizontal-active border-(--menu-item-border)'
              }
            },
            {
              active: true,
              orientation: 'vertical',
              class: {
                link: 'menu-item-vertical-active'
              }
            }
          ],
          defaultVariants: {}
        }
      }
    })
  ]
})
Releases
Published under MIT License.

Copyright © 2024-present Bitrix24