Skip to content

Accordion / expander

In review
Live · web

Single-open: opening one closes the rest

Per-session overrides. Leave untouched to inherit the registry defaults for this model + provider.

temperature 0.7 · top_p 0.95 · max_tokens 4096

Multi-open: each section toggles independently

$ bun run build
✓ 142 modules · 2.4s

Header accessory + uncontrolled: always-visible delete, each self-manages

Open me and delete me independently. The trash button never toggles the row, and no host holds my open state (defaultExpanded seeds it, I keep it).

Zebra (task 2763, experimental): opt-in alternating row tone; default stays plain

Single-open: sampling · multi-open: 1 section expanded. The island is live.

// Web: React, consuming @dizyx/nockerl-tokens. (Web is the laggard platform. Spec + live demo,
// not yet exported from @dizyx/nockerl-react; promotion is tracked.)
import { useState } from 'react';
export function SessionAdvanced() {
// Single-open: opening one closes the rest (Voice `expandedID` semantics).
const [open, setOpen] = useState<string | null>('sampling');
return (
<Accordion mode="single" value={open} onValueChange={setOpen}>
<AccordionItem
id="sampling"
title="Sampling"
hint="Temperature, top-p, penalties"
icon={<TuneIcon />}
pill={{ text: 'MODIFIED', tone: 'accent' }}
>
<SamplingSliders />
</AccordionItem>
<AccordionItem id="workspace" title="Workspace" hint="Locked by your administrator" disabled>
<WorkspaceFields />
</AccordionItem>
</Accordion>
);
}
PropTypeDefaultDescription
mode'single' | 'multiple''single'Disclosure policy. single closes siblings on open (Voice); multiple lets sections stack open (Android).
valuestring | string[] | nullControlled open id(s). A string | null in single mode, a string[] in multiple mode.
onValueChange(value) => voidFired on toggle with the next open id(s). Pair with value for a controlled accordion.
AccordionItem.id *stringStable identity used by value to track which item is open.
AccordionItem.title *stringHeader label: the disclosure's accessible name (label.large role).
AccordionItem.hintstringOptional supporting line under the title (body.small role).
AccordionItem.iconReactNodeOptional leading glyph rendered in a fixed slot, so titles align with or without it.
AccordionItem.pill{ text: string; tone: 'accent' | 'success' | 'warning' }Optional trailing header pill. accent for 'modified', warm tones for status only.
AccordionItem.headerAccessoryReactNodeAlways-visible header controls pinned to the trailing edge, left of the chevron. Rendered outside the toggle button so a delete IconButton / count Badge fires independently and never toggles the row. Reserves trailing space via --nk-acc-accessory-reserve (default 64px). Matches the headerAccessory seat from FormSection / TodoWidget.
AccordionItem.expandedbooleanControlled open state. When set, the item is controlled. Pair with onExpandedChange.
AccordionItem.onExpandedChange(next: boolean) => voidFired with the requested next open state on toggle (controlled).
AccordionItem.defaultExpandedbooleanfalseInitial open state for uncontrolled usage: the item self-manages when neither expanded nor onExpandedChange is given.
AccordionItem.disabledbooleanfalseInert and clearly seen (never faded to invisible); header is not focusable.