Accordion
Overviewimport { Accordion, AccordionGroup } from '@nili/ui';This is the library’s own overview page, rendered live. Switch the language or the theme in the header and it follows.
Basic
A single accordion needs nothing but a title and its content. content is an alias for children — pass whichever reads better at the call site.
import { Accordion } from "@nili/ui"
export function Example() {
return (
<>
<Accordion
title="How long does delivery take?"
content="Orders placed before 14:00 ship the same day."
/>
{/* the same thing, as children */}
<Accordion title="What is the return policy?">
Anything unopened can be returned within thirty days.
</Accordion>
</>
)
}Open, controlled and disabled
defaultOpen starts it expanded and leaves it alone. open plus onOpenChange hands the state to you — for an accordion whose open item is a URL parameter, say.
Support is available every day from 09:00 to 21:00, by chat or email. Most tickets are answered within an hour.
Orders placed before 14:00 ship the same day. Delivery inside the country takes two to four working days.
import { Accordion } from "@nili/ui"
export function Example() {
const [open, setOpen] = useState(true)
return (
<>
<Accordion defaultOpen title={t('states.startsOpen')} content="…" />
<Accordion
open={open}
onOpenChange={setOpen}
title="Controlled"
content="…"
/>
<Accordion disabled title="Disabled" content="…" />
</>
)
}Indicator and leading slot
indicatorPosition follows reading direction. indicator replaces the + / - glyph entirely; startAdornment adds a decorative element before the title.
import { Accordion, Icon } from "@nili/ui"
import { RiQuestionLine, RiArrowDownSLine } from "@remixicon/react"
export function Example() {
return (
<>
<Accordion
indicatorPosition="start"
title={t('indicator.atStart')}
content="…"
/>
<Accordion
indicator={<Icon icon={RiArrowDownSLine} />}
title={t('indicator.custom')}
content="…"
/>
<Accordion
startAdornment={<Icon icon={RiQuestionLine} size={20} />}
title={t('indicator.withIcon')}
content="…"
/>
</>
)
}Group — multiple
AccordionGroup coordinates a set. Each child needs a unique id, which is what the group tracks. multiple is the default: opening one leaves the others alone.
Orders placed before 14:00 ship the same day. Delivery inside the country takes two to four working days.
import { Accordion, AccordionGroup } from "@nili/ui"
export function Example() {
return (
<AccordionGroup defaultValue={["shipping"]}>
<Accordion id="shipping" title="How long does delivery take?" content="…" />
<Accordion id="returns" title="What is the return policy?" content="…" />
<Accordion id="support" title="How do I reach support?" content="…" />
</AccordionGroup>
)
}Group — single
single closes the others on open. collapsible={false} keeps one item open at all times — for a panel that must always show something.
Orders placed before 14:00 ship the same day. Delivery inside the country takes two to four working days.
import { Accordion, AccordionGroup } from "@nili/ui"
export function Example() {
return (
<AccordionGroup type="single" collapsible={false} defaultValue={["shipping"]}>
<Accordion id="shipping" title="How long does delivery take?" content="…" />
<Accordion id="returns" title="What is the return policy?" content="…" />
</AccordionGroup>
)
}Accordion
extends Omit< ComponentPropsWithoutRef<'div'>, 'title' | 'content' | 'onToggle' >
Variant axes — from the component’s cva definition
| Prop | Type | Default | Notes |
|---|---|---|---|
| open | boolean | false | Controlled open state. Pair with `onOpenChange`. |
| disabled | boolean | false |
Other props
| Prop | Type | Default | Notes |
|---|---|---|---|
| children | ReactNode | — | |
| aria-label | string | — | |
| title* | ReactNode | — | |
| content | ReactNode | — | Alias for `children`, kept for call sites that pass content as a prop. |
| defaultOpen | boolean | false | Uncontrolled initial state. |
| onOpenChange | (open: boolean) => void | — | |
| indicatorPosition | start | end | end | Where the expand/collapse indicator sits. Follows reading direction. |
| indicator | ReactNode | — | Replaces the default + / - indicator entirely. |
| startAdornment | ReactNode | — | Decorative element shown before the title (e.g. a category icon). |
| id | string | — | Override the generated ids used to wire `aria-controls`/`aria-labelledby`. |
AccordionContent
internalVariant axes — from the component’s cva definition
| Prop | Type | Default | Notes |
|---|---|---|---|
| open | 'true' | 'false' | false |
AccordionGroup
extends Omit< ComponentPropsWithoutRef<'div'>, 'defaultValue' | 'onChange' >
Other props
| Prop | Type | Default | Notes |
|---|---|---|---|
| children | ReactNode | — | |
| aria-label | string | — | |
| type | single | multiple | multiple | `'single'` closes the others on open; `'multiple'` leaves them alone. |
| collapsible | boolean | true | In `'single'` mode, allow closing the open item by clicking it again. |
| value | string[] | — | |
| defaultValue | string[] | — | |
| onValueChange | (value: string[]) => void | — |
AccordionIndicator
internalVariant axes — from the component’s cva definition
| Prop | Type | Default | Notes |
|---|---|---|---|
| position | start | end | end |
AccordionPanel
internalVariant axes — from the component’s cva definition
| Prop | Type | Default | Notes |
|---|---|---|---|
| start | 0 | 1 | 2 | 0 | |
| end | 0 | 1 | 1 |
AccordionTrigger
internalVariant axes — from the component’s cva definition
| Prop | Type | Default | Notes |
|---|---|---|---|
| open | 'true' | 'false' | false |