HelixOverviewComponentsMapsGraphIntroductionInstallationDeriving a themeSandboxTheme builderVisual testingCortexDocsEngramBuildingTraceBuildingRecallDeclaredServicesInsightsGet in touchSource on GitHub
Loading the reference
ToggleView SourceEdit in SandboxView MarkdownCopy MarkdownOpen in ClaudeOpen in CursorOne option in a toggle group.StableSince 0.1.0ActionsUsageimport'@fusion.dev/helix/toggle'import'@fusion.dev/helix-headless/toggle'Preview
API ReferenceRoothelix-toggleOne option in a toggle group.
PropTypeDescriptiondefaultSelectedbooleanWhether the markup declares the item chosen. A form reset returns to it.disabledbooleanDefaultfalseWhether the item is disabled and cannot be chosen.focusablebooleanWhether the item holds the group's tab stop. Unset, no group holds the
item, and it is a toggle button with a tab stop of its own.pressedbooleanWhether the item is pressed, in a group where several can be, and
undefined in a group where one is chosen.selectedbooleanDefaultfalseWhether the item is selected.valuestringDefault""The item's value, which identifies it in its set and is what a form
submits.
ReadTypeDescriptionwhenSettledPromise<void>Resolves a frame after the first update, when transitions are switched on.
SlotDescription(default)The item's label.endContent after the label, such as a count or a shortcut.startContent before the label, such as an icon.
EventTypeDescriptionchangeEventFired after a toggle button on its own is pressed or released.helix-selectHelixSelectEventFired when the item is chosen. Cancelable: call preventDefault() to keep the current choice.
MethodTypeDescriptionclick() => voidPresses the toggle, as click() does a native button: passed to the control
inside, so the one click a listener hears is the control's, after it has
moved. See HostClickController.focusItem() => voidMoves focus to the item's control, for the set's arrow keys.select() => booleanSelects the item and fires helix-select. Returns false if the item is
disabled or a listener cancels the event.
PartDescriptionitemThe radio button.
CSS PropertyDescription--toggle-item-colorText color of an item that is not chosen. Read by the base layer, which styles the item part.--toggle-item-color-selectedText color of the chosen item, and of each pressed item in a group that allows several.--toggle-item-padding-inlineSpace either side of an item's label.
Custom stateDescriptionpressedThe item is pressed, on its own or in a group where several can be.selectedThe item is chosen.settledSet one frame after the first render. Transitions wait for it, so an element does not animate its own arrival.
Grouphelix-toggle-groupA row of options with the selection marked by a moving indicator.
PropTypeDescriptionallowEmptySelectionbooleanDefaultfalseWhether a press on the chosen item, or Space or Enter on it, takes it
back so nothing is chosen, as React Aria's ToggleButtonGroup and
Radix's ToggleGroup do in a single group. Absent, a single group always
keeps its choice once it has one, as a radio group does. A multiple group
releases a pressed item either way.defaultValuestringDefault""The value the control starts with. A form reset returns it to this value,
and to the value attribute where this one is not written, as a native
control resets to the value it declares.disabledbooleanDefaultfalseWhether the control is disabled and cannot be used.feedbackstringDefault""The validation message shown under the control. It replaces the
browser's message.focusablebooleanDefaulttrueWhether the group holds a tab stop of its own.hintstringDefault""Help text shown under the control. A validation message replaces it.labelstringDefault""The field's label, which is also its accessible name. Content in the
label slot replaces it.labelPlacement"start"Where the group's label sits. start puts it on the track's line.namestringDefault""The name the control's value is submitted under.orientation"horizontal"|"vertical"The direction the items run. vertical puts them in a column, and the up
and down arrows move between them.requiredbooleanDefaultfalseWhether the field needs a value before the form can submit.selectionMode"multiple"|"single"Whether one item is chosen, as a radio group, or several can be pressed,
as a toolbar of buttons with aria-pressed.separation"outlined"|"plain"How the group is set apart from the page.valuestringThe control's current value, which its form submits.valueMissingMessagestringThe message shown when the field is required and empty.valuesstring[]The pressed values as a list, under selection-mode="multiple", in the
order the items are written. Written, it presses exactly those items.
Where one item is chosen, it is that one value, or none.
ReadTypeDescriptionformHTMLFormElement|nullThe form the control belongs to, or null.labelsNodeListThe labels associated with the control.validationMessagestringThe message the browser would show for the control, or an empty string.validityValidityStateWhether the control meets its constraints, and why not.whenSettledPromise<void>Resolves a frame after the first update, when transitions are switched on.willValidatebooleanWhether the control is checked when its form is submitted.
SlotDescription(default)The group's items.endContent after the track, on the same line, such as a count or a reset.feedbackThe message that says what is wrong, for content richer than a string. It shows while there is a message.hintHelp under the control, for content richer than the hint text.labelThe label, for content richer than the label text.startContent before the track, on the same line, such as an icon or a caption.
EventTypeDescriptionchangeEventFired after the value changes.helix-before-changeHelixBeforeChangeEventFired before the choice changes. Cancelable: call preventDefault() to keep the current choice.helix-selectHelixSelectEventFired when an item is chosen. The item sends it, and you listen for it on the group. Cancelable: call preventDefault() to keep the current choice.inputEventFired after the value changes.
MethodTypeDescriptioncheckValidity() => booleanReturns whether the control is valid, and fires invalid on it when it is
not. The control shows no message for it: reportValidity() does that.focus(options: FocusOptions) => voidMoves focus to the control, as focusing a native control does.reportValidity() => booleanReturns whether the control is valid, and when it is not, fires invalid
and shows the browser's message at the control.requestValue(next: string) => booleanRequests a new value, and returns whether the change was applied.setCustomValidity(message: string) => voidMarks the control invalid with message, or clears that with an empty
string, as on a native control. The form does not submit while it is set.
PartDescriptionfeedbackThe error message under the row.hintThe help text under the row, shown while there is no error.indicatorThe moving marker behind the selected item.labelThe label above the row.rowThe line that holds the track and the content on either side of it.trackThe bar the items sit in. Draw the line between an inline label and the items with ::part(track)::before in your stylesheet. This tier ships no CSS, so it renders no separate element for the line, which would add an empty child to your layout.
CSS PropertyDescription--toggle-group-background-colorThe groove behind the items, when the group is framed.--toggle-group-border-colorThe edge of the groove, when the group is framed.--toggle-group-indicator-colorThe fill of the moving marker, and of each pressed item under selection-mode="multiple".--toggle-group-indicator-shadowThe shadow of the moving marker and of each pressed item.--toggle-group-item-radiusCorner radius of each item, the marker, and a pressed item's fill. Without it, the curve stays concentric with the groove.--toggle-group-radiusCorner radius of the groove, when the group is framed.
Custom stateDescriptioninvalidThe group has an error to show, from the browser's validation or from your feedback.settledSet one frame after the first render. Transitions wait for it, so an element does not animate its own arrival.
Roothelix-headless-toggleOne option in a toggle group, or a toggle button on its own.
PropTypeDescriptiondefaultSelectedbooleanWhether the markup declares the item chosen. A form reset returns to it.disabledbooleanDefaultfalseWhether the item is disabled and cannot be chosen.focusablebooleanWhether the item holds the group's tab stop. Unset, no group holds the
item, and it is a toggle button with a tab stop of its own.pressedbooleanWhether the item is pressed, in a group where several can be, and
undefined in a group where one is chosen.selectedbooleanDefaultfalseWhether the item is selected.valuestringDefault""The item's value, which identifies it in its set and is what a form
submits.
ReadTypeDescriptionwhenSettledPromise<void>Resolves a frame after the first update, when transitions are switched on.
SlotDescription(default)The item's label.endContent after the label, such as a count or a shortcut.startContent before the label, such as an icon.
EventTypeDescriptionchangeEventFired after a toggle button on its own is pressed or released.helix-selectHelixSelectEventFired when the item is chosen. Cancelable: call preventDefault() to keep the current choice.
MethodTypeDescriptionclick() => voidPresses the toggle, as click() does a native button: passed to the control
inside, so the one click a listener hears is the control's, after it has
moved. See HostClickController.focusItem() => voidMoves focus to the item's control, for the set's arrow keys.select() => booleanChooses the item in its group, or, on its own, flips selected once
helix-select stands and sends change.
PartDescriptionitemThe button: a radio in a group where one is chosen, and a button with aria-pressed on its own or in a group where several can be.
Custom stateDescriptionpressedThe item is pressed, on its own or in a group where several can be.selectedThe item is chosen.settledSet one frame after the first render. Transitions wait for it, so an element does not animate its own arrival.
Grouphelix-headless-toggle-groupA row of options with the selection marked by a moving indicator.
PropTypeDescriptionallowEmptySelectionbooleanDefaultfalseWhether a press on the chosen item, or Space or Enter on it, takes it
back so nothing is chosen, as React Aria's ToggleButtonGroup and
Radix's ToggleGroup do in a single group. Absent, a single group always
keeps its choice once it has one, as a radio group does. A multiple group
releases a pressed item either way.defaultValuestringDefault""The value the control starts with. A form reset returns it to this value,
and to the value attribute where this one is not written, as a native
control resets to the value it declares.disabledbooleanDefaultfalseWhether the control is disabled and cannot be used.feedbackstringDefault""The validation message shown under the control. It replaces the
browser's message.focusablebooleanDefaulttrueWhether the group holds a tab stop of its own.hintstringDefault""Help text shown under the control. A validation message replaces it.labelstringDefault""The field's label, which is also its accessible name. Content in the
label slot replaces it.labelPlacement"start"Where the group's label sits. start puts it on the track's line.namestringDefault""The name the control's value is submitted under.orientation"horizontal"|"vertical"The direction the items run. vertical puts them in a column, and the up
and down arrows move between them.requiredbooleanDefaultfalseWhether the field needs a value before the form can submit.selectionMode"multiple"|"single"Whether one item is chosen, as a radio group, or several can be pressed,
as a toolbar of buttons with aria-pressed.valuestringThe control's current value, which its form submits.valueMissingMessagestringThe message shown when the field is required and empty.valuesstring[]The pressed values as a list, under selection-mode="multiple", in the
order the items are written. Written, it presses exactly those items.
Where one item is chosen, it is that one value, or none.
ReadTypeDescriptionformHTMLFormElement|nullThe form the control belongs to, or null.labelsNodeListThe labels associated with the control.validationMessagestringThe message the browser would show for the control, or an empty string.validityValidityStateWhether the control meets its constraints, and why not.whenSettledPromise<void>Resolves a frame after the first update, when transitions are switched on.willValidatebooleanWhether the control is checked when its form is submitted.
SlotDescription(default)The group's items.endContent after the track, on the same line, such as a count or a reset.feedbackThe message that says what is wrong, for content richer than a string. It shows while there is a message.hintHelp under the control, for content richer than the hint text.labelThe label, for content richer than the label text.startContent before the track, on the same line, such as an icon or a caption.
EventTypeDescriptionchangeEventFired after the value changes.helix-before-changeHelixBeforeChangeEventFired before the choice changes. Cancelable: call preventDefault() to keep the current choice.helix-selectHelixSelectEventFired when an item is chosen. The item sends it, and you listen for it on the group. Cancelable: call preventDefault() to keep the current choice.inputEventFired after the value changes.
MethodTypeDescriptioncheckValidity() => booleanReturns whether the control is valid, and fires invalid on it when it is
not. The control shows no message for it: reportValidity() does that.focus(options: FocusOptions) => voidMoves focus to the control, as focusing a native control does.reportValidity() => booleanReturns whether the control is valid, and when it is not, fires invalid
and shows the browser's message at the control.requestValue(next: string) => booleanRequests a new value, and returns whether the change was applied.setCustomValidity(message: string) => voidMarks the control invalid with message, or clears that with an empty
string, as on a native control. The form does not submit while it is set.
PartDescriptionfeedbackThe error message under the row.hintThe help text under the row, shown while there is no error.indicatorThe moving marker behind the selected item.labelThe label above the row.rowThe line that holds the track and the content on either side of it.trackThe bar the items sit in. Draw the line between an inline label and the items with ::part(track)::before in your stylesheet. This tier ships no CSS, so it renders no separate element for the line, which would add an empty child to your layout.
Custom stateDescriptioninvalidThe group has an error to show, from the browser's validation or from your feedback.settledSet one frame after the first render. Transitions wait for it, so an element does not animate its own arrival.
Examples
NameDescriptionDisabledA whole group disabled, and one item disabled in an enabled group.EventsButtons where one stays pressed, which fire the same events as a form value.IconsToggles with an icon before each label, in the start slot.InvalidThe group showing an error because nothing was chosen.Label FirstThe label before the control, for a row read as a sentence.MultipleA toolbar of formatting buttons where several can be pressed at once.OutlinedA group with separation set to outlined, which frames the track with a border.PlainA group with no track and no border, for use inside a container that has both.PreviewButtons where one stays pressed, to make a choice.PreviewButtons where one stays pressed, to make a choice.StatesA labeled group with chosen, unchosen, and disabled items, and a group named by aria-label.