RiseUI
Components

Accordion

Collapsible panels with a compound API (trigger, indicator, content). Defaults align with HeroUI v3 — text-sm triggers, muted body, motion tokens, optional surface shell.

Usage · Default

Full-width accordion with hairline separators and no outer chrome (HeroUI `variant="default"`). Triggers use 14px / font-medium; body uses muted 14px text; chevron 250ms; panel 200ms.

final muted = context.riseTheme.mutedForeground(0.65);

RiseAccordion(
  selectionMode: RiseAccordionSelectionMode.single,
  initialExpanded: const ['2'],
  children: [
    RiseAccordionItem.panel(
      value: '1',
      leading: Icon(Icons.shopping_bag_outlined, size: 16, color: muted),
      title: const Text('How do I place an order?'),
      content: const Text('…'),
    ),
    // …more RiseAccordionItem.panel
  ],
)

Usage · Surface

`RiseAccordionVariant.surface` → rounded 24px `RiseThemeData.surface` shell, wider padding, inset dividers (`surface-foreground/6%`), `bg-default` trigger hover — HeroUI `variant="surface"`.

RiseAccordion(
  variant: RiseAccordionVariant.surface,
  horizontalPadding: 20,
  separatorMargin: const EdgeInsets.symmetric(horizontal: 12),
  selectionMode: RiseAccordionSelectionMode.single,
  children: [
    RiseAccordionItem.panel(
      value: 'a',
      title: const Text('Surface panel A'),
      content: const Text('…'),
    ),
  ],
)

Usage · Multiple expanded

Set `selectionMode: RiseAccordionSelectionMode.multiple`.

RiseAccordion(
  selectionMode: RiseAccordionSelectionMode.multiple,
  initialExpanded: const ['x', 'y'],
  children: [
    RiseAccordionItem.panel(value: 'x', title: const Text('X'), content: const Text('…')),
    RiseAccordionItem.panel(value: 'y', title: const Text('Y'), content: const Text('…')),
  ],
)

Usage · Custom indicator

`RiseAccordionIndicator` with `child` and `expandedTurns` (e.g. 0.125 for a 45° plus).

RiseAccordionItem(
  value: 'plus',
  child: Column(
    children: [
      RiseAccordionTrigger(
        child: Row(
          children: [
            Expanded(child: Text('Title', style: titleStyle)),
            RiseAccordionIndicator(
              expandedTurns: 0.125,
              child: Icon(Icons.add, size: 16, color: muted),
            ),
          ],
        ),
      ),
      RiseAccordionContent(child: const Text('…')),
    ],
  ),
)

Usage · Custom indicator variants

Plus, caret, and arrow rows — each uses a custom indicator child.

RiseAccordionItem(
  value: 'i1',
  child: Column(
    children: [
      RiseAccordionTrigger(
        child: Row(
          children: [
            Expanded(child: Text('Using Plus')),
            RiseAccordionIndicator(
              expandedTurns: 0.125,
              child: Icon(Icons.add, size: 16),
            ),
          ],
        ),
      ),
      RiseAccordionContent(child: Text('…')),
    ],
  ),
)

Usage · Disabled (root)

`isDisabled: true` on `RiseAccordion`.

RiseAccordion(
  isDisabled: true,
  children: [
    RiseAccordionItem.panel(value: 'd1', title: const Text('…'), content: const Text('…')),
  ],
)

Usage · Disabled (items)

Per-item `isDisabled`.

RiseAccordion(
  children: [
    RiseAccordionItem.panel(value: 'a', title: const Text('Active'), content: const Text('…')),
    RiseAccordionItem.panel(
      value: 'b',
      isDisabled: true,
      title: const Text('Disabled'),
      content: const Text('…'),
    ),
  ],
)

Usage · Without separator

`hideSeparator: true`.

RiseAccordion(
  hideSeparator: true,
  children: [
    RiseAccordionItem.panel(value: '1', title: const Text('One'), content: const Text('…')),
  ],
)

Usage · Custom render

`RiseAccordionItem.render` exposes `isExpanded` / `value` to the builder.

RiseAccordionItem.render(
  value: 'r',
  builder: (context, data) {
    return Column(
      children: [
        RiseAccordionTrigger(
          child: Row(
            children: [
              Expanded(child: Text(data.isExpanded ? 'Open' : 'Closed')),
              const RiseAccordionIndicator(),
            ],
          ),
        ),
        RiseAccordionContent(child: const Text('…')),
      ],
    );
  },
)

Usage · FAQ layout

Page title, subtitle, section labels (General, Licensing, …) and one `RiseAccordion` per section — HeroUI FAQ story.

Column(
  crossAxisAlignment: CrossAxisAlignment.stretch,
  children: [
    Text('Frequently Asked Questions', style: …),
    Text('Everything you need to know…', style: muted),
    // Section label (e.g. GENERAL)
    RiseAccordion(
      selectionMode: RiseAccordionSelectionMode.single,
      children: [
        RiseAccordionItem.panel(value: 'gen-1', title: …, content: …),
      ],
    ),
    // More sections + RiseAccordion blocks…
  ],
)

Usage · Custom styles

Rich triggers: title + subtitle in the trigger row; body in `RiseAccordionContent`.

RiseAccordionTrigger(
  child: Row(
    children: [
      Icon(Icons.notifications_outlined, size: 20, color: iconColor),
      SizedBox(width: 12),
      Expanded(
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            Text('Set Up Notifications', style: titleStyle),
            Text('Receive account activity updates', style: subtitleStyle),
          ],
        ),
      ),
      const RiseAccordionIndicator(),
    ],
  ),
)