RiseUI
Components

Radio

Single-choice selection group with orientation, variants, and validation states — aligned with @heroui/react RadioGroup and radio-group.css.

Usage

Plan selection with label, description, and vertical stack (`mt-4`).

RiseRadioGroup<String>(
  value: selected,
  onChanged: (v) => setState(() => selected = v),
  label: const Text('Plan selection'),
  description: const Text('Choose the plan that suits you best'),
  options: plans,
)

Horizontal orientation

`flex-row flex-wrap gap-4` for subscription-style rows.

RiseRadioGroup<String>(
  value: selected,
  onChanged: (v) => setState(() => selected = v),
  orientation: RiseRadioGroupOrientation.horizontal,
  label: const Text('Subscription plan'),
  options: plans,
)

Controlled

Selection mirrored in helper text.

RiseRadioGroup<String>(
  value: selected,
  onChanged: (v) => setState(() => selected = v),
  options: plans,
)

Uncontrolled pattern

Local state with “last chosen” readout (Hero defaultValue + onChange story).

RiseRadioGroup<String>(
  value: lastChosen,
  onChanged: (v) => setState(() => lastChosen = v),
  options: plans,
)

Validation

Required group, submit, and [RiseFieldError].

RiseRadioGroup<String>(
  value: selected,
  onChanged: (v) => setState(() => selected = v),
  isRequired: true,
  isInvalid: showError && selected == null,
  errorMessage: showError && selected == null ? Text('Please select a plan.') : null,
  options: plans,
)

Disabled

Whole group non-interactive with description.

RiseRadioGroup<String>(
  value: 'pro',
  onChanged: (_) {},
  isDisabled: true,
  label: const Text('Subscription plan'),
  description: const Text('Plan changes are temporarily paused.'),
  options: plans,
)

Variants

Primary (`shadow-field`) vs secondary (`shadow-none`, surface control fill).

RiseRadioGroup<String>(
  value: 'a',
  onChanged: (_) {},
  variant: RiseRadioGroupVariant.secondary,
  options: options,
)

Invalid

Required + danger strokes + error line.

RiseRadioGroup<String>(
  value: selected,
  onChanged: (v) => setState(() => selected = v),
  isRequired: true,
  isInvalid: selected == null,
  errorMessage: selected == null ? Text('Please choose one option.') : null,
  options: options,
)

In surface

[RiseSurface] + `variant: secondary` for lower emphasis on card shells.

RiseSurface(
  showShadow: true,
  child: RiseRadioGroup<String>(
    value: selected,
    onChanged: (v) => setState(() => selected = v),
    variant: RiseRadioGroupVariant.secondary,
    options: plans,
  ),
)