nb-accordion

This is an accordion component for Vue.js 3+.

It is a thin wrapper around NbCollapse that renders a list of collapsible panels from an items array, with optional control of which panels are open (selecteds) and which are disabled (disableds).

It exposes per-item slots so each panel can have a fully custom title, icon and content while keeping the styling props centralized at the accordion level.

Loading component...

Installation

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

Usage

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

import NbNavigationComponents from '@vlalg-nimbus/nb-navigation'
import "@vlalg-nimbus/nb-navigation/dist/style.css";

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

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

To use, simply call the component, in this case it will be NbAccordion or nb-accordion.

Basic
<template>
  <NbAccordion
    nb-id="accordion-1"
    :items="items"
  />
</template>

<script setup>
import { ref } from 'vue'

const items = ref([
  { key: 'item-1', label: 'Section 1', content: 'Content of section 1' },
  { key: 'item-2', label: 'Section 2', content: 'Content of section 2' },
  { key: 'item-3', label: 'Section 3', content: 'Content of section 3' }
])
</script>
Custom slots per item
<template>
  <NbAccordion nb-id="accordion-2" :items="items">
    <template #title-0="{ item, isActive }">
      <strong>{{ item.label }} {{ isActive ? '(open)' : '' }}</strong>
    </template>

    <template #content-1="{ item }">
      <ul>
        <li v-for="row in item.rows" :key="row">{{ row }}</li>
      </ul>
    </template>
  </NbAccordion>
</template>
Pre-opened / disabled items
<template>
  <NbAccordion
    nb-id="accordion-3"
    :items="items"
    :selecteds="[0, 2]"
    :disableds="[1]"
  />
</template>

Preview & Playground

Select the component you want to edit/test

Loading Sandbox...

items shape

Each entry in the items array must be an object with at least:

keyTypeDescription
key (*)StringUnique identifier of the item (validated by the prop)
label (*)StringTitle shown in the panel header
contentAnyDefault content rendered inside the panel

Extra properties are allowed and are exposed back through the slot props as item.

Props

Items with an (*) mean they are required

Core

nameValue typeDefaultDescription
nbId (*)StringSets the id attribute and is used to build the per-item ids (accordion-{nbId}-{index})
itemsArray[]Array of items rendered as collapsible panels (each entry must have key and label)
selectedsArray<Number>[]Indexes of items that should start opened
disabledsArray<Number>[]Indexes of items that should be disabled
displayString'b'Component display. Accepts 'b' (block) or 'ib' (inline-block)
themeString'light'Defines theme. Accepts light and dark
disabledBooleanfalseDisables all panels at once
blockClickBooleanfalseBlocks toggle on click when true
blockRightClickBooleanfalsePrevents the browser's context menu over each panel
tabIndexNumber0Keyboard tab index for each header
hasTabIndexEnterBooleantrueEnables toggle with Enter key
hasTabIndexSpaceBooleantrueEnables toggle with Space key
ariaLabelString'Collapse'aria-label value for accessibility
ariaAttrsObject{}Additional aria attributes (auto-prefixed with aria-)
textAlignString'left'Text alignment. Accepts left, center, right
activeTextStyleString'normal'Title style when active. Accepts normal, italic, oblique
ellipsisTextBooleantrueTruncates the title with ellipsis when overflowing
isScrollClassBooleanfalseEnables scrollClass to be applied on each panel content area when true
scrollClassString''Custom CSS class applied to the scrollable content area (only applied when isScrollClass is true)

Title

nameValue typeDefaultDescription
titleGapNumber0.5Gap (rem) between title label and trailing icon
titlePaddingXNumber0.7Horizontal padding (rem) of the header
titlePaddingYNumber0.7Vertical padding (rem) of the header
titleBorderRadiusString'0px 0px 0px 0px'Header border-radius when closed (flat by default for stacking)
titleBorderRadiusActiveString'0px 0px 0px 0px'Header border-radius when open
titleFontFamilyString"'Lato', sans-serif"Title font-family
titleFontSizeString'1.6em'Title font-size
titleFontWeightNumber500Title font-weight
titleIconWidthString'2.4rem'Fixed width of the trailing icon area
titleIconFontFamilyString"'Lato', sans-serif"Trailing icon font-family
titleIconFontSizeString'2em'Trailing icon font-size
titleIconFontWeightNumber700Trailing icon font-weight

Content

nameValue typeDefaultDescription
contentPaddingXNumber1Horizontal padding (rem) of the content area
contentPaddingYNumber1Vertical padding (rem) of the content area
contentFontFamilyString"'Lato', sans-serif"Content font-family
contentFontSizeString'1.6em'Content font-size
contentFontWeightNumber500Content font-weight
contentBorderRadiusActiveString'0px 0px 0px 0px'Content border-radius when open
contentHasBorderBooleantrueDraws side and bottom borders when open
contentMaxHeightNumber200Maximum height (px) of each panel content area. When the content exceeds it, vertical scroll is enabled automatically

Theme Colors (Light)

Default palette uses Tailwind-like neutral grays with blue as the active accent. Designed for light surfaces.

nameValue typeDefaultDescription
lightTitleColorString#1f2937Title text color
lightTitleColorActiveString#1d4ed8Title color when open
lightTitleColorHoverString#111827Title color on hover
lightTitleIconColorString#6b7280Trailing icon color
lightTitleIconColorActiveString#1d4ed8Trailing icon color when open
lightTitleIconColorHoverString#374151Trailing icon color on hover
lightButtonBgColorString#f3f4f6Header background color
lightButtonBgColorActiveString#e0e7ffHeader background color when open
lightButtonBgColorHoverString#e5e7ebHeader background color on hover
lightContentColorString#1f2937Content text color
lightContentBgColorString#ffffffContent background color
lightContentBorderColorString#e5e7ebContent border color when open

Theme Colors (Dark)

Same color roles as light, tuned for dark surfaces.

nameValue typeDefaultDescription
darkTitleColorString#e5e7ebTitle text color
darkTitleColorActiveString#60a5faTitle color when open
darkTitleColorHoverString#f9fafbTitle color on hover
darkTitleIconColorString#9ca3afTrailing icon color
darkTitleIconColorActiveString#60a5faTrailing icon color when open
darkTitleIconColorHoverString#d1d5dbTrailing icon color on hover
darkButtonBgColorString#1f2937Header background color
darkButtonBgColorActiveString#1e3a8aHeader background color when open
darkButtonBgColorHoverString#374151Header background color on hover
darkContentColorString#e5e7ebContent text color
darkContentBgColorString#111827Content background color
darkContentBorderColorString#374151Content border color when open

Slots

Slots are exposed per item using the index from the items array. Each slot receives the full item, its index, and the current state flags so you can adapt the rendering individually.

nameSlot propsDescription
title-{index}{ item, index, title, selected, disabled }Custom header content for the item at index
title-icon-{index}{ item, index, isActive, selected, disabled }Custom trailing icon for the item at index
content-{index}{ item, index, content, selected, disabled }Custom body content for the item at index

The default rendering uses item.label for the title, + / โˆ’ for the icon, and item.content wrapped in a <p> for the body.

Events

The accordion forwards the events emitted by each internal NbCollapse. The order of the events follows the user's interaction with the corresponding panel.

nameReturn typeDescription
clickedโ€”Fired when any panel header is clicked or activated by Enter/Space
focusedโ€”Fired when any panel header receives focus
blurredโ€”Fired when any panel header loses focus
outside-clickedEventFired when the user clicks outside an open panel
resized{ event, width, height }Fired when the viewport is resized; reports the current panel size

Notes

  • The key of each item is required for the prop validator, but the per-item DOM id uses the index (accordion-{nbId}-{index}) to guarantee uniqueness.
  • selecteds and disableds are arrays of indexes (numbers), not item keys.
  • This component is purely presentational over NbCollapse. To open/close panels programmatically, mutate selecteds from the parent.
  • All styling props are forwarded to every panel; if you need different styling per item, render multiple NbCollapse instances directly instead of using NbAccordion.