Single-choice form control group with option items, field text, and one canonical value-change event.
Install @wyrd-company/react or the Flutter package and use it directly —
your DESIGN.md does the styling.
catalog/contracts/radio-group.ymlsource of truth · verbatim
$schema: https://thewyrdingway.dev/schemas/component-contract.schema.ymlcontractVersion: 0.1.0identity:name: RadioGrouptag: wyrd-radio-grouppackage: wyrd.component.radio-grouptitle: Radio Groupsummary: Single-choice form control group with option items, field text, and one canonical value-change event.relationships:related-to: - quality-parity-and-gatesclassification:category: form-fieldcomposition: multi-slotinteractive: truetarget-strategy:react: requiredflutter: requiredsurface:properties: - name: valuetype:kind: stringrequired: falsecontrolled: trueserializable: truesummary: Controlled selected option value. - name: default-valuetype:kind: stringrequired: falseserializable: truesummary: Initial uncontrolled selected option value. - name: optionstype:kind: arrayitem:kind: objectfields:value:kind: stringlabel:kind: stringdescription:kind: stringdisabled:kind: booleanrequired: falsedefault: []serializable: truesummary: Ordered selectable radio option items. - name: is-disabledtype:kind: booleanrequired: falsedefault: falsereflects: trueserializable: truesummary: Prevents changing selection and exposes disabled group semantics. - name: is-requiredtype:kind: booleanrequired: falsedefault: falsereflects: trueserializable: truesummary: Marks the group as requiring one selected option. - name: is-invalidtype:kind: booleanrequired: falsedefault: falsereflects: trueserializable: truesummary: Marks the selection as invalid and associates the error slot.slots: - name: labelrequired: truecardinality: exactly-oneaccepts: - textsummary: Visible group label and accessible-name source. - name: descriptionrequired: falsecardinality: zero-or-oneaccepts: - textsummary: Help text associated with the radio group. - name: errorrequired: falsecardinality: zero-or-oneaccepts: - textsummary: Validation error associated when is-invalid is true.events: - name: value-changepayload:value:kind: stringaction:kind: action-refbubbles: truecomposed: truecancelable: falsesummary: Canonical value-change event carrying the selected option value.states: - name: defaultsource: platformsummary: Enabled group with no invalid or disabled state. - name: checkedsource: propertysummary: State when an option matching value or default-value is selected. - name: focus-visiblesource: platformsummary: Keyboard-visible focus state on a radio option. - name: disabledsource: propertysummary: Disabled state derived from is-disabled or option disabled. - name: invalidsource: propertysummary: Invalid state derived from is-invalid. - name: requiredsource: propertysummary: Required state derived from is-required.parts: - name: rootsummary: Field container.slots: - label - description - error - name: labelsummary: Group label text.slots: - label - name: groupsummary: Native radio group container. - name: optionsummary: Option row label and control. - name: controlsummary: Native radio control. - name: option-labelsummary: Option label text. - name: option-descriptionsummary: Option description text. - name: descriptionsummary: Group description text.slots: - description - name: errorsummary: Group error text.slots: - errortokens:root:gap: spacing.xslabel:color: color.on-surfacetext: typography.label-mdrequired-indicator:color: color.errorgroup:gap: spacing.smoption:gap: spacing.smpadding-y: spacing.xscontrol:accent: color.primaryfocus-ring: color.primarydisabled-opacity: opacity.disabledoption-label:color: color.on-surfacetext: typography.body-mdoption-description:color: color.on-surface-varianttext: typography.body-mddescription:color: color.on-surface-varianttext: typography.body-mderror:color: color.errortext: typography.body-mdmessages: []obligations:accessibility:role: radiogroupname: Label slot provides the accessible name.description: Description and error slots are programmatically associated with the group.keyboard: - Tab moves focus into and out of the group in document order. - Arrow keys move selection between enabled radio options according to platform behavior. - Space selects the focused enabled radio option.semantics: - The group exposes required, invalid, and disabled state where the platform supports it. - Each option exposes checked and disabled state through native radio semantics. - Error text is associated only when invalid.behavior:model: inputinteractions: - Selecting an enabled option emits value-change with that option value. - Disabled groups and disabled options do not change value. - Controlled value wins over default-value.hostEffects: - Dispatch value-change event. - Bind value to SDUI form state when present.conditions: - rtl - reduced-motion - cvd-deuteranopia - density-compact - text-expansionsdui:status: serializableserializableProperties: - value - default-value - options - is-disabled - is-required - is-invalidserializableSlots: - label - description - erroreventBindings: - value-changenotes: Options serialize as ordered records; value-change serializes to a named binding/action channel.examples: - name: emptystate: defaultproperties:options: - value: emaillabel: Email - value: phonelabel: Phone - value: maillabel: Mailslots:label: Contact methoddescription: Choose how collaborators should reach you. - name: selectedstate: checkedproperties:default-value: emailoptions: - value: emaillabel: Email - value: phonelabel: Phone - value: maillabel: Mailslots:label: Contact method - name: invalidstate: invalidproperties:is-invalid: trueis-required: trueoptions: - value: emaillabel: Email - value: phonelabel: Phone - value: maillabel: Mailslots:label: Contact methoderror: Select a contact method.
01
Examples
Generated from the contract's examples block.
Previews are the published @wyrd-company/react component, themed by the
brand's role tokens — flip the site's light/dark toggle and they follow.
emptystate: default
Contact method
Choose how collaborators should reach you.
Usage
import { WyrdRadioGroup } from"@wyrd-company/react";
<WyrdRadioGroup options={[{"value":"email","label":"Email"},{"value":"phone","label":"Phone"},{"value":"mail","label":"Mail"}]} label="Contact method" description="Choose how collaborators should reach you." />
// events: onValueChange
import'package:wyrd_flutter/wyrd_flutter.dart';
WyrdRadioGroup(
options: [{"value":"email","label":"Email"},{"value":"phone","label":"Phone"},{"value":"mail","label":"Mail"}],
label: Text('Contact method'),
description: Text('Choose how collaborators should reach you.'),
)
// events: onChanged
Prevents changing selection and exposes disabled group semantics.
is-required
boolean
false
Marks the group as requiring one selected option.
is-invalid
boolean
false
Marks the selection as invalid and associates the error slot.
03
Slots & events
Slot
Cardinality
Accepts
Summary
label
exactly-one
text
Visible group label and accessible-name source.
description
zero-or-one
text
Help text associated with the radio group.
error
zero-or-one
text
Validation error associated when is-invalid is true.
Event
Payload
Summary
value-change
value, action
Canonical value-change event carrying the selected option value.
04
Tokens
The contract's token bindings. Open the shared contextual sidebar from any example;
primary swatches reflect the color you pick there. Error swatches show the active
preset's values; editing any knob switches to custom and resets error to TWW · Ink.
Binding
Token
root.gap
spacing.xs
label.color
color.on-surface
label.text
typography.label-md
required-indicator.color
color.error
group.gap
spacing.sm
option.gap
spacing.sm
option.padding-y
spacing.xs
control.accent
color.primary
control.focus-ring
color.primary
control.disabled-opacity
opacity.disabled
option-label.color
color.on-surface
option-label.text
typography.body-md
option-description.color
color.on-surface-variant
option-description.text
typography.body-md
description.color
color.on-surface-variant
description.text
typography.body-md
error.color
color.error
error.text
typography.body-md
05
States
State
Source
Summary
default
platform
Enabled group with no invalid or disabled state.
checked
property
State when an option matching value or default-value is selected.
focus-visible
platform
Keyboard-visible focus state on a radio option.
disabled
property
Disabled state derived from is-disabled or option disabled.
invalid
property
Invalid state derived from is-invalid.
required
property
Required state derived from is-required.
06
Accessibility
From the contract's accessibility obligations. Role radiogroup; Label slot provides the accessible name.
Tab moves focus into and out of the group in document order.
Arrow keys move selection between enabled radio options according to platform behavior.
Space selects the focused enabled radio option.
The group exposes required, invalid, and disabled state where the platform supports it.
Each option exposes checked and disabled state through native radio semantics.