nb-button-split-dropdown

This is a split and dropdown button component for Vue.js 3+. A split and dropdown button combines a primary action button with a dropdown menu for additional actions. It can also function as a simple dropdown button when showPopupButton is set to false.

Loading component...

Installation

Yarn
yarn add @vlalg-nimbus/nb-buttons
NPM
npm install @vlalg-nimbus/nb-buttons

Usage

Vue 3
import { createApp } from 'vue'
import App from './App.vue'

import NbButtonsComponents from '@vlalg-nimbus/nb-buttons'
import "@vlalg-nimbus/nb-buttons/dist/style.css";

const app = createApp(App)
app.use(NbButtonsComponents)
app.mount('#app')
Nuxt 3
import NbButtonsComponents from '@vlalg-nimbus/nb-buttons'
import "@vlalg-nimbus/nb-buttons/dist/style.css";

export default defineNuxtPlugin(context => {
  context.vueApp.use(NbButtonsComponents)
})

To use, simply call the component, in this case it will be NbButtonSplitDropdown or nb-button-split-dropdown.

Mode 1
<template>
  <NbButtonSplitDropdown
    nb-id="split-button-1"
    main-button-text="Save"
    :menu-items="menuItems"
  />
</template>
Mode 2
<template>
  <nb-button-split-dropdown
    nb-id="split-button-1"
    main-button-text="Save"
    :menu-items="menuItems"
  />
</template>
Mode 3
<template>
  <nb-button-split-dropdown
    nb-id="split-button-1"
    main-button-text="Save"
    :menu-items="menuItems"
  ></nb-button-split-dropdown>
</template>

Preview & Playground

Select the component you want to edit/test

Loading Sandbox...

Props

Items with an (*) mean they are required

nameValue typeDefaultDescription
nbId (*)StringSets the id attribute to differentiate from other components
displayString'ib'Defines the display type. Accepts ib (inline-block) and b (block).
mainButtonTextString'Save'Defines the text displayed in the main button.
mainButtonAriaLabelString''Defines the aria-label attribute for the main button.
menuItemsArrayArray of menu items for the popup. Each item must have a label property. Can also have disabled and icon properties.
popupButtonTitleString'Open for more actions'Defines the title attribute for the popup button.
tabIndexNumber0Defines the tab index. Set this property to make the button focusable by the keyboard.
hasTabIndexEnterBooleantrueEnables the button to be activated with the Enter key when focused.
hasTabIndexSpaceBooleantrueEnables the button to be activated with the Space key when focused.
ariaLabelString'Split/Dropdown Button'Defines the aria-label attribute for screen readers.
ariaAttrsObject{}Allows passing custom aria attributes as an object. Keys will automatically receive the aria- prefix. Example: { 'describedby': 'help-id', 'invalid': 'false' }
themeString'light'Defines the theme. Accepts dark and light. When theme is set, uses theme-specific color props.
menuItemFocusOutlineColorStringnullDefines the outline color when menu items are focused. If not provided, uses currentColor.
menuItemFocusOutlineWidthString'2px'Defines the outline width when menu items are focused.
menuItemFocusOutlineOffsetString'-2px'Defines the outline offset when menu items are focused.
showBorderBooleantrueDefines if the border should be shown.
lightButtonColorString'#f5f5f5'Defines the button background color for light theme. Accepts Color name and Hex
lightButtonColorHoverString'#e0e0e0'Defines the button background color on hover for light theme. Accepts Color name and Hex
lightTextColorString'#333333'Defines the text color for light theme. Accepts Color name and Hex
lightTextColorHoverString'#000000'Defines the text color on hover for light theme. Accepts Color name and Hex
lightBorderColorString'#cccccc'Defines the border color for light theme. Accepts Color name and Hex
lightBorderColorHoverString'#bbbbbb'Defines the border color on hover for light theme. Accepts Color name and Hex
lightPopupBgColorString'#ffffff'Defines the background color of the popup menu for light theme. Accepts Color name and Hex
lightMenuItemHoverColorString'#f5f5f5'Defines the background color of menu items on hover for light theme. Accepts Color name and Hex
lightMenuItemTextColorString'#333333'Defines the text color of menu items for light theme. Accepts Color name and Hex
lightDisabledBgColorString'#dfdfd9'Defines the disabled background color for light theme. Accepts Color name and Hex
darkButtonColorString'#2d2d2d'Defines the button background color for dark theme. Accepts Color name and Hex
darkButtonColorHoverString'#3d3d3d'Defines the button background color on hover for dark theme. Accepts Color name and Hex
darkTextColorString'#e0e0e0'Defines the text color for dark theme. Accepts Color name and Hex
darkTextColorHoverString'#ffffff'Defines the text color on hover for dark theme. Accepts Color name and Hex
darkBorderColorString'#555555'Defines the border color for dark theme. Accepts Color name and Hex
darkBorderColorHoverString'#666666'Defines the border color on hover for dark theme. Accepts Color name and Hex
darkPopupBgColorString'#2d2d2d'Defines the background color of the popup menu for dark theme. Accepts Color name and Hex
darkMenuItemHoverColorString'#3d3d3d'Defines the background color of menu items on hover for dark theme. Accepts Color name and Hex
darkMenuItemTextColorString'#e0e0e0'Defines the text color of menu items for dark theme. Accepts Color name and Hex
darkDisabledBgColorString'rgba(40, 42, 54, 1)'Defines the disabled background color for dark theme. Accepts Color name and Hex
showPopupButtonBooleantrueDefines if the popup button (dropdown arrow) should be shown. When false, the component behaves as a dropdown (single button that opens the menu).
borderRadiusNumber0.375Defines border-radius for the buttons.
popupBorderRadiusNumbernullDefines border-radius for the popup menu. If not provided, uses borderRadius.
widthNumbernullDefines button width. If not provided, width is auto.
paddingXNumber1Defines button padding-left and padding-right.
paddingYNumber0.2Defines button padding-top and padding-bottom.
popupPaddingXNumbernullDefines popup menu items padding-left and padding-right. If not provided, uses paddingX.
popupPaddingYNumbernullDefines popup menu items padding-top and padding-bottom. If not provided, uses paddingY.
disabledBooleanfalseDefines if the button is disabled
fontFamilyString"'Lato', sans-serif"Defines the font-family for both buttons
fontSizeString'1.6em'Defines the font-size for both buttons
fontWeightNumber400Defines the font-weight for both buttons
popupFontFamilyStringnullDefines the font-family for popup menu items. If not provided, uses fontFamily.
popupFontSizeStringnullDefines the font-size for popup menu items. If not provided, uses fontSize.
popupFontWeightNumbernullDefines the font-weight for popup menu items. If not provided, uses fontWeight.

Events

nameReturn typeDescription
clickedObjectFired when any button is clicked. Returns an object with type property ('main' or 'menu-item'). If type is 'menu-item', also includes item and index properties.
main-clickednothingFired when the main button is clicked, returns nothing.
menu-item-clickedObjectFired when a menu item is clicked. Returns an object with item and index properties.

Slots

The component has three slots:

main-content

Slot for customizing the main button content. Defaults to mainButtonText prop value.

<template>
  <NbButtonSplitDropdown nb-id="split-1" :menu-items="menuItems">
    <template #main-content>
      Custom Main Button Text
    </template>
  </NbButtonSplitDropdown>
</template>

Slot for customizing the popup button icon. Defaults to a chevron down SVG icon.

<template>
  <NbButtonSplitDropdown nb-id="split-1" :menu-items="menuItems">
    <template #popup-icon>
      <svg>...</svg>
    </template>
  </NbButtonSplitDropdown>
</template>

item-icon-{index}

Slot for customizing individual menu item icons. The slot receives the item as a prop.

<template>
  <NbButtonSplitDropdown nb-id="split-1" :menu-items="menuItems">
    <template #item-icon-0="{ item }">
      <span>Icon for {{ item.label }}</span>
    </template>
  </NbButtonSplitDropdown>
</template>

Example

SplitButton with Light Theme (default)

<template>
  <NbButtonSplitDropdown
    nb-id="split-button-example"
    display="b"
    main-button-text="Save"
    :menu-items="menuItems"
    theme="light"
    :show-border="true"
    :show-popup-button="true"
    light-button-color="#dbeafe"
    light-button-color-hover="#bfdbfe"
    light-text-color="#1e40af"
    light-text-color-hover="#1e3a8a"
    light-border-color="#93c5fd"
    light-border-color-hover="#60a5fa"
    light-popup-bg-color="#ffffff"
    light-menu-item-hover-color="#e0e7ff"
    light-menu-item-text-color="#1e40af"
    :border-radius="0.375"
    :padding-x="1"
    :padding-y="0.2"
    :tab-index="0"
    :has-tab-index-enter="true"
    :has-tab-index-space="true"
    aria-label="Split Button Example"
    @main-clicked="handleMainClick"
    @menu-item-clicked="handleMenuItemClick"
    @clicked="handleClick"
  />
</template>

<script setup>
defineOptions({
  name: 'CompSplit',
});

const menuItems = [
  { label: 'Save and New', icon: '๐Ÿ“„' },
  { label: 'Save and Close', icon: 'โœ…' },
  { label: 'Save as Draft', icon: '๐Ÿ’พ', disabled: false },
  { label: 'Delete', icon: '๐Ÿ—‘๏ธ', disabled: true }
];

const handleMainClick = () => {
  console.log('Main button clicked');
};

const handleMenuItemClick = ({ item, index }) => {
  console.log('Menu item clicked:', item, index);
};

const handleClick = (data) => {
  console.log('Button clicked:', data);
};
</script>

SplitButton with Dark Theme

<template>
  <NbButtonSplitDropdown
    nb-id="split-button-dark-example"
    display="b"
    main-button-text="Save"
    :menu-items="menuItems"
    theme="dark"
    :show-border="true"
    :show-popup-button="true"
    dark-button-color="#8b5cf6"
    dark-button-color-hover="#7c3aed"
    dark-text-color="#f3f4f6"
    dark-text-color-hover="#ffffff"
    dark-border-color="#a78bfa"
    dark-border-color-hover="#8b5cf6"
    dark-popup-bg-color="#2d2d2d"
    dark-menu-item-hover-color="#3d3d3d"
    dark-menu-item-text-color="#e0e0e0"
    :border-radius="0.5"
    :popup-border-radius="0.5"
    :padding-x="1.5"
    :padding-y="0.4"
    @main-clicked="handleMainClick"
    @menu-item-clicked="handleMenuItemClick"
    @clicked="handleClick"
  />
</template>

<script setup>
defineOptions({
  name: 'CompSplitDark',
});

const menuItems = [
  { label: 'Save and New', icon: '๐Ÿ“„' },
  { label: 'Save and Close', icon: 'โœ…' },
  { label: 'Save as Draft', icon: '๐Ÿ’พ' }
];

const handleMainClick = () => {
  console.log('Main button clicked');
};

const handleMenuItemClick = ({ item, index }) => {
  console.log('Menu item clicked:', item, index);
};

const handleClick = (data) => {
  console.log('Button clicked:', data);
};
</script>

When showPopupButton is set to false, the component behaves as a dropdown button. The popup button is hidden and clicking the main button opens the menu.

<template>
  <NbButtonSplitDropdown
    nb-id="dropdown-button-example"
    display="b"
    main-button-text="Options"
    :menu-items="menuItems"
    theme="light"
    :show-border="true"
    :show-popup-button="false"
    :border-radius="0.375"
    :padding-x="1"
    :padding-y="0.2"
    :tab-index="0"
    :has-tab-index-enter="true"
    :has-tab-index-space="true"
    aria-label="Dropdown Button Example"
    @menu-item-clicked="handleMenuItemClick"
    @clicked="handleClick"
  />
</template>

<script setup>
defineOptions({
  name: 'CompDropdown',
});

const menuItems = [
  { label: 'Option 1', icon: '๐Ÿ“„' },
  { label: 'Option 2', icon: 'โœ…' },
  { label: 'Option 3', icon: '๐Ÿ’พ' }
];

const handleMenuItemClick = ({ item, index }) => {
  console.log('Menu item clicked:', item, index);
};

const handleClick = (data) => {
  console.log('Button clicked:', data);
};
</script>

Note: When showPopupButton is false, the main-clicked event is not fired when clicking the main button (it opens the menu instead). Only menu-item-clicked and clicked events are fired.

Accessibility

The component follows accessibility best practices:

  • Uses proper ARIA attributes (aria-haspopup, aria-expanded)
  • Supports keyboard navigation (Enter, Space, Arrow keys, Escape, Backspace)
  • Manages focus properly when opening/closing the popup
  • Supports screen readers with customizable aria-label and ariaAttrs
  • Each button can be independently focused and activated

Keyboard Navigation

  • Enter/Space: Activates the focused button or menu item
  • Arrow Up/Down: Navigates through menu items when popup is open
  • Escape/Backspace: Closes the popup menu
  • Tab: Moves focus between buttons and menu items