-
Notifications
You must be signed in to change notification settings - Fork 0
LayrzRadioInput
Radio button group input with generic type support and responsive grid layout.
DERIVED from layrz_theme. This specification is extracted from the current ThemedRadioInput<T> API and awaits team confirmation. Details may change during the M3 inputs review.
| Field | Value |
|---|---|
| Mirrors |
ThemedRadioInput<T> from layrz_theme |
| Phase | M3 (Core Inputs) |
| Domain | Inputs |
| Composes | UNCLEAR — possibly a bare radio group, not LayrzTextInput (see Composition Architecture section below) |
| SDK Primitive |
RawRadio (raw_radio.dart:44) — design-agnostic radio control, used by both Material and Cupertino |
LayrzRadioInput does NOT compose LayrzTextInput, as a radio group is not a text field. However, it follows the same spirit as the input contract in terms of:
- Shared label and error display patterns
- Responsive layout using the grid system
- Theme-aware styling
The contract does not apply directly. Refer to Input-Specific API below for the actual interface.
-
Value type: Generic
T(caller-specified, oftenStringor an enum) - Selection surface: Inline radio button group (no dialog or popup)
- Layout: Responsive grid — buttons arranged in columns per breakpoint (1 column on XS, 2 on SM, 3 on MD, etc.)
LayrzRadioInput is a bare radio group, not a decorated text field. It does not compose LayrzTextInput because:
- Radio groups are not text fields; they have no text editing capability.
- The interactive surface is the button grid, not a single field chrome.
- The label and errors are rendered at the group level, not per-radio.
However, the component maintains the input contract's spirit:
- labelText for group label
- errors and hideDetails for error display
- padding for consistent spacing
- disabled for disabling the whole group
LayrzRadioInput is generic: the value and items can be of any type T.
// Design sketch — generic type T
class LayrzRadioInput<T> extends StatefulWidget {
/// The currently selected value, or null if nothing is selected.
final T? value;
/// The list of selectable items, each with a value and label.
final List<LayrzSelectItem<T>> items;
/// Callback invoked when the user selects a different value.
final void Function(T?)? onChanged;
// ...
}Each item in the items list has a structure like:
class LayrzSelectItem<T> {
/// The value associated with this item.
final T value;
/// The human-readable label displayed next to the radio button.
final String label;
}LayrzRadioInput adds the following over the base patterns:
-
value(T?) — the currently selected value. Corresponds to one of the items' values, or null if nothing is selected. -
items(List<LayrzSelectItem<T>>, required) — the list of selectable options. Each item has avalueandlabel.
-
xsSize(Sizes) — number of columns on extra-small screens (0–599 px). Default:Sizes.col12(full width, 1 column). -
smSize(Sizes?) — number of columns on small screens (600–999 px). Default:Sizes.col6(2 columns). -
mdSize(Sizes?) — number of columns on medium screens (1000–1399 px). Default:Sizes.col4(3 columns). -
lgSize(Sizes?) — number of columns on large screens (1400–1999 px). Default:Sizes.col3(4 columns). -
xlSize(Sizes?) — number of columns on extra-large screens (2000+ px). Default:Sizes.col2(6 columns).
These values correspond to a 12-column responsive grid. Sizes.col12 = 1 item per row, Sizes.col6 = 2 items per row, Sizes.col4 = 3 per row, Sizes.col3 = 4 per row, Sizes.col2 = 6 per row. This allows the radio group to reflow its layout at different screen sizes.
-
onChanged(void Function(T?)?) — invoked when the user selects a radio button. Receives the new value (or null if deselection is allowed). -
disabled(bool) — when true, all radio buttons are not interactive.
-
labelText(String?) — label text for the radio group. Rendered above the buttons. -
label(Widget?) — label widget. NOT supported in layrz_ui (labelText only). -
padding(EdgeInsets) — padding around the entire group. Default:EdgeInsets.all(10). -
hideDetails(bool) — whether to suppress error display. Default:false. -
errors(List<String>) — list of error messages displayed below the group.
For porting purposes, the current layrz_theme implementation exposes (extracted from source):
// Design sketch — parameter names from layrz_theme source
class ThemedRadioInput<T> extends StatefulWidget {
final String? labelText;
final Widget? label; // NOT supported
final void Function(T?)? onChanged;
final T? value;
final List<ThemedSelectItem<T>> items; // Required
final bool disabled; // Default: false
final List<String> errors; // Default: []
final bool hideDetails; // Default: false
final EdgeInsets padding; // Default: EdgeInsets.all(10)
final Sizes xsSize; // Default: .col12
final Sizes? smSize; // Default: .col6
final Sizes? mdSize; // Default: .col4
final Sizes? lgSize; // Default: .col3
final Sizes? xlSize; // Default: .col2
}Rendering (from source):
- The component wraps items in a
ResponsiveRowcontainer. - Each item becomes a
ResponsiveColwith the breakpoint-specific size. - Inside each column is a
Rowwith aRadio<T>widget and aGestureDetector-wrapped label. - Clicking the label toggles the selection.
The Flutter SDK provides RawRadio<T> (raw_radio.dart:44), which is:
- Design-agnostic: Used by both Material and Cupertino without Material/Cupertino imports in the widget's build method.
-
Generically typed: Supports any comparable type
T. -
Constructor:
RawRadio<T>({ required T value, required T? groupValue, required ValueChanged<T?> onChanged, bool toggleable = false, // ... other Material-specific parameters like fillColor, splashRadius, etc. })
Note: RawRadio is design-agnostic for selection logic, but some constructor parameters (e.g., fillColor, splashRadius) are Material-oriented. Custom styling via BuildContext.theme (layrz_ui) must override these for a consistent design.
RawRadio<T> is available in Flutter's SDK without Material/Cupertino imports. No additional dependency or blocker.
LayrzRadioInput requires a way to pair values with labels. In layrz_theme, this is ThemedSelectItem<T>. In layrz_ui, this may be renamed to LayrzSelectItem<T> or a similar data class.
Status: Must align with the broader LayrzSelectInput implementation.
The responsive layout uses breakpoint sizes from layrz_ui's grid system (xsSize, smSize, mdSize, etc.). This system must be stable in M1.
Status: Available in M1.
- Does LayrzRadioInput compose LayrzTextInput in any form? (Answer: Almost certainly no, since it's not a text field.)
- Is LayrzRadioInput considered part of the "input family" that conforms to the shared input contract, or is it a separate category?
- Can the caller provide a custom widget to render each radio item (not just a string label)?
- If yes, what is the callback signature (e.g.,
Widget Function(LayrzSelectItem<T>))?
- Does LayrzRadioInput support multiselect (i.e., multiple values simultaneously), or only single selection?
- If multiselect is needed, is that a separate
LRadioGroupInputor a variant?
- Can the user click a selected radio button again to deselect it (toggle to null), or does it require a separate action?
- Should
toggleableparameter be exposed to control this behavior?
- What is the visual appearance of unselected vs. selected radio buttons?
- Should custom colors (e.g., fillColor, strokeColor) be exposed as parameters?
- Should animation (e.g., smooth transition when selecting) be built-in?
- Is the label text clickable (clicking toggles the selection)?
- Should there be a separate touch target area around both the radio and label?
- Should the radio group support arrow keys (← → ↑ ↓) to navigate between options?
- Should Tab navigate through the group or skip it?
- Are radio buttons announced correctly with screen readers (VoiceOver, TalkBack)?
- Should each option have a semantic label distinct from its text label (for i18n)?
Last updated: 2026-08-13
Related documents: Input Contract, LayrzTextInput, ./l_checkbox_input.md, Design Tokens
Made with ❤️ by Golden M, Inc.
- LayrzTextInput
- LayrzSelectableAction
- LayrzSelectionToolbar
- LayrzTextSelectionControls
- LayrzSelectionMagnifier
- LayrzSelectionHandlePainter
- LayrzTextAreaInput
- LayrzComboBoxInput
- LayrzNumberInput
- LayrzPasswordInput
- LayrzCheckboxInput
- LayrzRadioInput
- LayrzSelectInput
- LayrzMultiSelectInput
- LayrzSearchInput
- LayrzDualListInput
- LayrzDurationInput