@fvc/accordion
v1.1.3
Published
`@fvc/accordion` provides FE-VIS styled accordion primitives on top of Ant Design Collapse. It keeps the Ant Design Collapse API familiar while adding the design-system behaviour used across FE-VIS applications: bordered and transparent variants, item-lev
Readme
@fvc/accordion
@fvc/accordion provides FE-VIS styled accordion primitives on top of Ant Design Collapse. It keeps the Ant Design Collapse API familiar while adding the design-system behaviour used across FE-VIS applications: bordered and transparent variants, item-level border and background controls, header alignment options, collapse layout mode, and a disabled state.
Installation
bun add @fvc/accordionPeer Dependencies
The package expects these dependencies to be available in the consuming application:
bun add react antdImport
import { Accordion } from '@fvc/accordion';Quick Start
import { Accordion } from '@fvc/accordion';
export function FaqSection() {
return (
<Accordion
defaultActiveKey="1"
items={[
{ key: '1', label: 'What is FE-VIS?', children: 'FE-VIS is a design system for enterprise applications.' },
{ key: '2', label: 'How do I install it?', children: 'Run bun add @fvc/accordion.' },
]}
/>
);
}Common Usage
Bordered and Borderless
Bordered is the default. Pass bordered: false inside collapseProps to remove the outer border.
<Accordion
collapseProps={{ bordered: false }}
items={[
{ key: '1', label: 'Section', children: 'Content' },
]}
/>Transparent Background
<Accordion
collapseProps={{ transparent: true }}
items={[
{ key: '1', label: 'Section', children: 'Content' },
]}
/>Collapse Layout Mode
Use collapse for a flat, borderless layout without rounded corners — suitable for panels embedded inside cards or drawers.
<Accordion
collapse
items={[
{ key: '1', label: 'Details', children: 'Content' },
{ key: '2', label: 'More', children: 'Content' },
]}
/>Header Vertical Alignment
By default the header text and expand icon are top-aligned. Use center to flex-center them — useful when the label contains multi-line or rich content.
<Accordion
collapseHeaderProps={{ verticalAlign: 'center' }}
items={[
{ key: '1', label: 'Section', children: 'Content' },
]}
/>Multiple Open Panels
<Accordion
defaultActiveKey={['1', '2']}
items={[
{ key: '1', label: 'First', children: 'Content' },
{ key: '2', label: 'Second', children: 'Content' },
{ key: '3', label: 'Third', children: 'Content' },
]}
/>Disabled State
Disable the entire accordion with the disabled prop, or disable individual items via the items array.
{/* Entire accordion disabled */}
<Accordion
disabled
items={[
{ key: '1', label: 'Section', children: 'Content' },
]}
/>
{/* Single item disabled */}
<Accordion
items={[
{ key: '1', label: 'Available', children: 'Content' },
{ key: '2', label: 'Unavailable', children: 'Content', disabled: true },
]}
/>Custom Header Content
The label field accepts any React node.
<Accordion
items={[
{
key: '1',
label: <span style={{ fontWeight: 700 }}>Custom Header</span>,
children: 'Content',
},
]}
/>Expand Icon Position
<Accordion
expandIconPosition="end"
items={[
{ key: '1', label: 'Section', children: 'Content' },
]}
/>Item-level Border and Background
Override border and background for individual items using collapseItemProps.
<Accordion
collapseItemProps={{ bordered: false, transparent: true }}
items={[
{ key: '1', label: 'Section', children: 'Content' },
]}
/>Nested Components
Use forceRender to prevent lazy unmounting when the panel closes — required when the child component holds internal state.
<Accordion
items={[
{
key: '1',
label: 'Data table',
children: <Table columns={columns} dataSource={data} />,
forceRender: true,
},
]}
/>Controlled
<Accordion
activeKey={activeKey}
onChange={(key) => setActiveKey(key)}
items={[
{ key: '1', label: 'Section', children: 'Content' },
]}
/>Props
| Prop | Type | Description |
| --- | --- | --- |
| collapseProps | { bordered?: boolean; transparent?: boolean } | Styling for the outer collapse container. |
| collapseItemProps | { bordered?: boolean; transparent?: boolean } | Styling applied to every accordion item. |
| collapseHeaderProps | { verticalAlign?: 'default' \| 'center' } | Header alignment. Defaults to 'default' (top-aligned). |
| disabled | boolean | Disables the entire accordion. |
| collapse | boolean | Flat, borderless collapse layout mode. |
| testId | string | Maps to data-testid. Defaults to 'accordion'. |
| All CollapseProps | — | All Ant Design Collapse props are supported (items, activeKey, defaultActiveKey, expandIcon, expandIconPosition, onChange, etc.). |
Deprecated props:
children(useitemsinstead) and theonChangewrapper (use the nativeCollapseProps.onChangedirectly).
Consumer Example
import { Accordion } from '@fvc/accordion';
export function ContractDetails({ contract }) {
return (
<Accordion
collapse
collapseHeaderProps={{ verticalAlign: 'center' }}
defaultActiveKey="general"
items={[
{
key: 'general',
label: 'General information',
children: <GeneralInfoPanel data={contract.general} />,
},
{
key: 'parties',
label: 'Parties',
children: <PartiesPanel data={contract.parties} />,
},
{
key: 'attachments',
label: 'Attachments',
children: <AttachmentsTable data={contract.attachments} />,
forceRender: true,
},
]}
/>
);
}Testing
Use testId when a stable test selector is needed.
<Accordion
testId="faq-accordion"
items={[
{ key: '1', label: 'Question', children: 'Answer' },
]}
/>screen.getByTestId('faq-accordion');Customisation
@fvc/accordion exposes its visual tokens as CSS custom properties declared in src/styles/variables.scss. Override any of these in your own stylesheet — no fork, no file in the component, no re-bundle required.
/* consumer's own app stylesheet */
:root {
--accordion-bg-color: #f9fafb;
--accordion-border-color: #e5e7eb;
--accordion-border-radius: 4px;
--accordion-item-active-header-color: #6941c6;
--accordion-content-color: #374151;
}Available variables
| Variable | Default | Controls |
| --- | --- | --- |
| --accordion-bg-color | var(--neutral-0) | Background color of the accordion container |
| --accordion-border-color | var(--blue-gray-200) | Border color of the accordion container and collapse items |
| --accordion-border-width | 1px | Border thickness of the accordion container |
| --accordion-border-radius | 8px | Corner radius of the accordion container |
| --accordion-header-padding | 12px 16px 12px 40px | Padding of the accordion item header |
| --accordion-header-fz | 16px | Font size of the accordion item header text |
| --accordion-header-fw | 600 | Font weight of the accordion item header text |
| --accordion-header-lh | 20px | Line height of the accordion item header |
| --accordion-header-ff | 'Montserrat', sans-serif | Font family of the accordion item header text |
| --accordion-header-no-arrow-pl | 12px | Header left padding when the expand arrow is hidden |
| --accordion-arrow-fz | 12px | Font size of the expand/collapse arrow icon |
| --accordion-item-active-header-color | var(--link-on-light-bg-color-500) | Header text color of the currently active (open) item |
| --accordion-content-color | var(--body-text-color-1000) | Text color of the accordion item content area |
| --accordion-content-fz | 16px | Font size of the accordion item content area |
| --accordion-content-ff | 'Roboto', sans-serif | Font family of the accordion item content area |
| --accordion-disabled-color | rgba(0,0,0,0.25) | Text color of a disabled accordion item header |
| --accordion-borderless-content-pt | 4px | Top padding of content in the borderless variant |
| --accordion-ghost-content-padding-y | 12px | Top and bottom padding of content in the ghost variant |
Development
bun run lint
bun run type-check
bun run test
bun run build