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 add @vlalg-nimbus/nb-navigation
Usage
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')
To use, simply call the component, in this case it will be NbAccordion or nb-accordion.
<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>
Preview & Playground
Select the component you want to edit/test
items shape
Each entry in the items array must be an object with at least:
| key | Type | Description |
|---|---|---|
| key (*) | String | Unique identifier of the item (validated by the prop) |
| label (*) | String | Title shown in the panel header |
| content | Any | Default 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
| name | Value type | Default | Description |
|---|---|---|---|
| nbId (*) | String | Sets the id attribute and is used to build the per-item ids (accordion-{nbId}-{index}) | |
| items | Array | [] | Array of items rendered as collapsible panels (each entry must have key and label) |
| selecteds | Array<Number> | [] | Indexes of items that should start opened |
| disableds | Array<Number> | [] | Indexes of items that should be disabled |
| display | String | 'b' | Component display. Accepts 'b' (block) or 'ib' (inline-block) |
| theme | String | 'light' | Defines theme. Accepts light and dark |
| disabled | Boolean | false | Disables all panels at once |
| blockClick | Boolean | false | Blocks toggle on click when true |
| blockRightClick | Boolean | false | Prevents the browser's context menu over each panel |
| tabIndex | Number | 0 | Keyboard tab index for each header |
| hasTabIndexEnter | Boolean | true | Enables toggle with Enter key |
| hasTabIndexSpace | Boolean | true | Enables toggle with Space key |
| ariaLabel | String | 'Collapse' | aria-label value for accessibility |
| ariaAttrs | Object | {} | Additional aria attributes (auto-prefixed with aria-) |
| textAlign | String | 'left' | Text alignment. Accepts left, center, right |
| activeTextStyle | String | 'normal' | Title style when active. Accepts normal, italic, oblique |
| ellipsisText | Boolean | true | Truncates the title with ellipsis when overflowing |
| isScrollClass | Boolean | false | Enables scrollClass to be applied on each panel content area when true |
| scrollClass | String | '' | Custom CSS class applied to the scrollable content area (only applied when isScrollClass is true) |
Title
| name | Value type | Default | Description |
|---|---|---|---|
| titleGap | Number | 0.5 | Gap (rem) between title label and trailing icon |
| titlePaddingX | Number | 0.7 | Horizontal padding (rem) of the header |
| titlePaddingY | Number | 0.7 | Vertical padding (rem) of the header |
| titleBorderRadius | String | '0px 0px 0px 0px' | Header border-radius when closed (flat by default for stacking) |
| titleBorderRadiusActive | String | '0px 0px 0px 0px' | Header border-radius when open |
| titleFontFamily | String | "'Lato', sans-serif" | Title font-family |
| titleFontSize | String | '1.6em' | Title font-size |
| titleFontWeight | Number | 500 | Title font-weight |
| titleIconWidth | String | '2.4rem' | Fixed width of the trailing icon area |
| titleIconFontFamily | String | "'Lato', sans-serif" | Trailing icon font-family |
| titleIconFontSize | String | '2em' | Trailing icon font-size |
| titleIconFontWeight | Number | 700 | Trailing icon font-weight |
Content
| name | Value type | Default | Description |
|---|---|---|---|
| contentPaddingX | Number | 1 | Horizontal padding (rem) of the content area |
| contentPaddingY | Number | 1 | Vertical padding (rem) of the content area |
| contentFontFamily | String | "'Lato', sans-serif" | Content font-family |
| contentFontSize | String | '1.6em' | Content font-size |
| contentFontWeight | Number | 500 | Content font-weight |
| contentBorderRadiusActive | String | '0px 0px 0px 0px' | Content border-radius when open |
| contentHasBorder | Boolean | true | Draws side and bottom borders when open |
| contentMaxHeight | Number | 200 | Maximum 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.
| name | Value type | Default | Description |
|---|---|---|---|
| lightTitleColor | String | #1f2937 | Title text color |
| lightTitleColorActive | String | #1d4ed8 | Title color when open |
| lightTitleColorHover | String | #111827 | Title color on hover |
| lightTitleIconColor | String | #6b7280 | Trailing icon color |
| lightTitleIconColorActive | String | #1d4ed8 | Trailing icon color when open |
| lightTitleIconColorHover | String | #374151 | Trailing icon color on hover |
| lightButtonBgColor | String | #f3f4f6 | Header background color |
| lightButtonBgColorActive | String | #e0e7ff | Header background color when open |
| lightButtonBgColorHover | String | #e5e7eb | Header background color on hover |
| lightContentColor | String | #1f2937 | Content text color |
| lightContentBgColor | String | #ffffff | Content background color |
| lightContentBorderColor | String | #e5e7eb | Content border color when open |
Theme Colors (Dark)
Same color roles as light, tuned for dark surfaces.
| name | Value type | Default | Description |
|---|---|---|---|
| darkTitleColor | String | #e5e7eb | Title text color |
| darkTitleColorActive | String | #60a5fa | Title color when open |
| darkTitleColorHover | String | #f9fafb | Title color on hover |
| darkTitleIconColor | String | #9ca3af | Trailing icon color |
| darkTitleIconColorActive | String | #60a5fa | Trailing icon color when open |
| darkTitleIconColorHover | String | #d1d5db | Trailing icon color on hover |
| darkButtonBgColor | String | #1f2937 | Header background color |
| darkButtonBgColorActive | String | #1e3a8a | Header background color when open |
| darkButtonBgColorHover | String | #374151 | Header background color on hover |
| darkContentColor | String | #e5e7eb | Content text color |
| darkContentBgColor | String | #111827 | Content background color |
| darkContentBorderColor | String | #374151 | Content 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.
| name | Slot props | Description |
|---|---|---|
| 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.labelfor the title,+/โfor the icon, anditem.contentwrapped 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.
| name | Return type | Description |
|---|---|---|
| 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-clicked | Event | Fired 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
keyof each item is required for the prop validator, but the per-item DOM id uses the index (accordion-{nbId}-{index}) to guarantee uniqueness. selectedsanddisabledsare arrays of indexes (numbers), not item keys.- This component is purely presentational over
NbCollapse. To open/close panels programmatically, mutateselectedsfrom the parent. - All styling props are forwarded to every panel; if you need different styling per item, render multiple
NbCollapseinstances directly instead of usingNbAccordion.
