One choice from a short, visible set of options, with a single form value.
<tp-radio-group>
Radio Group
Default density
Compact density
Restart from the initial state
Show the copyable source
Standard · 4–6 business daysExpress · 2 business daysOvernight · Next morning
Standard · 4–6 business daysExpress · 2 business daysOvernight · Next morning
<tp-field label="Delivery" description="Arrives at your office address.">
<tp-radio-group name="delivery" default-value="standard">
<tp-radio-group-item value="standard">Standard · 4–6 business days</tp-radio-group-item>
<tp-radio-group-item value="express">Express · 2 business days</tp-radio-group-item>
<tp-radio-group-item value="overnight">Overnight · Next morning</tp-radio-group-item>
</tp-radio-group>
</tp-field>
Usage
Use a Radio Group when every option should stay visible and exactly one applies. For long lists, use Select; for an on/off setting, use Switch. The group owns the value and the single tab stop; each tp-radio-group-item supplies a value and its label as content.
Press/Space selects; pressing the selected item does not clear it. Enter does not select. Arrow keys follow orientation and writing direction, wrap and skip disabled items, and select the focused Radio; consumed keys and arrows carrying Alt, Ctrl or Meta are left to the browser. Home/End choose the first/last eligible Radio. One selected enabled Radio is the tab stop, otherwise the first enabled Radio is; Tab leaves the group.
Labelling
A Field provides the visible label, description and error. Without one, give the group a label so it still has an accessible name.
Standalone
Default density
Compact density
Restart from the initial state
Show the copyable source
readonly keeps the current choice visible, focusable and submitted, but blocks changing it.
Read-only
Default density
Compact density
Restart from the initial state
Show the copyable source
MonthlyYearly
MonthlyYearly
<tp-field label="Billing interval" description="Locked until your contract renews on March 1.">
<tp-radio-group name="interval" default-value="yearly" readonly>
<tp-radio-group-item value="monthly">Monthly</tp-radio-group-item>
<tp-radio-group-item value="yearly">Yearly</tp-radio-group-item>
</tp-radio-group>
</tp-field>
Controlled
Set value to own the selection and accept each proposal in onValueChange; an empty value starts with nothing selected. Because your code holds the value, it can also change it from elsewhere, such as a recommendation.
The first update fixes controlled versus uncontrolled ownership. Cancel with event.preventDefault() or event.detail.cancelled = true.
Controlled value
Default density
Compact density
Restart from the initial state
Show the copyable source
Standard · 3–5 days · FreeExpress · Next day · $9Pick up in store · TodayChoose the fastest for my address
Standard · 3–5 days · FreeExpress · Next day · $9Pick up in store · TodayChoose the fastest for my address
<div id="radio-group-controlled" style="display:grid;gap:var(--tp-space-4);justify-items:start">
<tp-field label="Delivery">
<tp-radio-group value="">
<tp-radio-group-item value="standard">Standard · 3–5 days · Free</tp-radio-group-item>
<tp-radio-group-item value="express">Express · Next day · $9</tp-radio-group-item>
<tp-radio-group-item value="pickup">Pick up in store · Today</tp-radio-group-item>
</tp-radio-group>
</tp-field>
<tp-button variant="outline" size="sm" data-recommend>Choose the fastest for my address</tp-button>
</div>
<script type="module">
const root = document.querySelector('#radio-group-controlled');
const group = root.querySelector('tp-radio-group');
group.onValueChange = (event) => {
if (event.defaultPrevented || event.detail.cancelled) return;
group.value = event.detail.value;
};
root.querySelector('[data-recommend]').addEventListener('click', () => {
group.value = 'pickup';
});
</script>
Forms
The group submits once under its name, or the Field’s. required blocks submission while nothing is chosen, and reset restores default-value.
The group submits once only while a matching eligible Radio is mounted. String/number/Boolean values stringify; object values use JSON serialization while selection uses identity. Unmatched values remain stored, render no selection and fail required validity; matching remounts restore the checked presentation. Read-only retains submission; disabled omits it.
Required
Default density
Compact density
Restart from the initial state
Show the copyable source
AttributePropertyTypeDefaultDescriptiondefault-valuedefaultValueunknown—The selected value at first render and after a form reset, when the page does not own value.labellabelstring''The accessible name of the group when no Field or visible heading names it.
Properties
PropertyTypeDefaultDescriptiononValueChange((event: TpValueChangeEvent<unknown>) => void) | undefined—Called with each proposed selection before it commits; assign value to accept it or cancel
the event to reject it.memberChanged——Re-reads the items after one is added, removed or changes its value or disabled state.
Events
EventTypeDescriptiontp-value-changeTpValueChangeEvent<unknown>Cancelable proposal of a new selection before it commits; detail.value, detail.previousValue and the detail.reason for the change.tp-field-valueCustomEvent<{ value: unknown; previousValue: unknown; reason: ChangeReason; }>After the selection commits, with the same value, previousValue and reason; the enclosing Field listens for it.
Methods
MethodReturnsDescriptionisChecked(element)booleanWhether the given item holds the selected value; items call it to render their state.isDisabled(element)booleanWhether the given item is disabled, by itself or by the group.tabStop(member)numberThe tab index of the given item: 0 for the selected item, or the first enabled one, and -1
for the rest.requestSelection(element, event, reason)voidProposes the given item's value as the selection; items call it when pressed.setValue(value, reason, source?)voidProposes a new selection as if the user had made it, notifying listeners first.
Slots
SlotDescriptiondefaultThe Radio group items, in order, optionally inside layout wrappers.
CSS parts
PartDescription::part(radio-group)The element with the radiogroup role that holds the items.
<tp-radio-group-item>
Attributes
AttributePropertyTypeDefaultDescriptionnative-actionnativeActionbooleanfalseRenders the radio as a native button instead of a span, for a form layout that expects one.keep-mountedkeepMountedbooleanfalseKeeps the hidden dot in the tree while unselected, so a custom style can transition it out.
Properties
PropertyTypeDefaultDescriptionpresentationOwnerread-onlyHTMLElement | null—The Radio group whose presentation settings this item follows.radioGroupRadioSelectionOwner | null—The group that owns this item's selection; set by the group itself.checkedread-onlyboolean—Whether this item holds the group's value.radioDisabledread-onlyboolean—Whether the item is disabled, by itself or by its group; an item outside a group is always
disabled.radioReadOnlyread-onlyboolean—Whether the item ignores presses because it or its group is read-only.controlElementread-onlyHTMLElement | null—The inner element that carries the radio role and receives focus.
Slots
SlotDescriptiondefaultThe option's label; a press on it selects the option.
CSS parts
PartDescription::part(radio-group-indicator)The dot inside the selected item's radio.::part(radio-group-item)The radio with its label inside each item, which receives focus and presses.
Related
Components, widgets and patterns that use this one.