Put tp-toggle elements with unique values inside the group. The selection is always an ordered list of values, in both modes, so default-value takes a JSON array. Give the group a label; it is one tab stop and arrow keys move between items without selecting.
A scalar attribute value is treated as one identifier; it is never split on spaces. Use properties or JSON arrays for lists.
In multiple mode, membership is ordered by registered items and retains unmatched selected values. In a standalone Group, arrow keys follow orientation/direction and skip disabled members; Home/End move to boundary items. Action controls never submit a value or reset on native form reset; consumer-owned form participation must be explicit.
Multiple selection
multiple lets each item toggle independently, as in a formatting toolbar. Icon-only items need an aria-label, and an icon-* size on the group makes them square. An explicitly supplied Icon size remains authoritative.
Text formatting
Default density
Compact density
Restart from the initial state
Show the copyable source
The group’s size and variant override the items’ own. size takes the Button’s set: xs, sm, the default and lg for text, and the square icon-xs, icon-sm, icon and icon-lg for icon-only items. orientation="vertical" stacks the items and switches arrow navigation to Up and Down.
The host sizes to its members. An inline size set on the host (for example inline-size: 100% to span a column or a grid cell) is the group’s own size: the toggle-group part fills the host, vertical members stretch across it, and a grid set on the part through partPresentation lays its tiles out over the full width.
Vertical, small
Default density
Compact density
Restart from the initial state
Show the copyable source
An item can pair an Icon with its text. With visible text the item needs no aria-label, and data-icon="inline-start" tightens the padding beside the icon.
View switcher
Default density
Compact density
Restart from the initial state
Show the copyable source
Items can hold more than a word, such as a sample above its name. Reshape an item through its partContracts: here styleHook stacks the content and gives each item its own weight. A Field names the group, and its description reports the selection.
Font weight
Default density
Compact density
Restart from the initial state
Show the copyable source
Arrow navigation skips disabled items. disabled on the group disables every item while keeping each item’s own setting for later.
Inside a Toolbar
A Toggle group placed inside a ToolbarController root becomes one of its groups by itself; it needs no registration call. Its toggle-group part is registered as the toolbar group and keeps role="group" and the group’s label, and its Toggles join the toolbar’s single arrow-key sequence in order. The group then has no tab stop or arrow-key handling of its own: the toolbar’s orientation, loopFocus and Home/End apply, while the group’s orientation still lays out its Toggles. Selection mode, values and tp-value-change are unchanged. A disabled Toggle, or every Toggle of a disabled group, stays a focusable toolbar stop that does not activate; a Toggle excluded for a missing or duplicate value is skipped.
Do not register the group’s host, its part or its Toggles with the toolbar yourself; a Toggle that is already registered keeps that registration, and the group reports a tp-diagnostic. A group added to the toolbar later, or present before the toolbar is created, joins it once; a group removed from the toolbar, or a disposed toolbar, restores the standalone tab stop and arrow keys. A Toggle group inside a popup or dialog placed within the toolbar stays independent.
import { ToolbarController } from '@tweakpad/ui';
import '@tweakpad/ui/register';
await customElements.whenDefined('tp-button');
const toolbar = new ToolbarController(document.getElementById('view-tools')!);
toolbar.registerItem(document.getElementById('fit')!, { kind: 'button' });
// The Layout group registers itself and its Toggles.
API Reference
Every element also accepts motion-policy.
Attributes
AttributePropertyTypeDefaultDescriptiondefault-valuedefaultValuereadonly string[] | undefined—The pressed values at first render, as a JSON array in the attribute, when the page does not
own value.multiplemultipleboolean—Lets each Toggle be pressed independently; otherwise pressing one releases the others.selection-modeselectionMode'single' | 'multiple'—The same choice as multiple, as a word: single or multiple.loop-focusloopFocusbooleantrueWhether the arrow keys wrap from the last Toggle to the first and back.variantvariant'ghost' | 'outline''ghost'The paint of every Toggle in the group, overriding their own.sizesizeToggleSize'default'The size of every Toggle in the group, overriding their own; the icon-* sizes make square
Toggles for Icons alone.spacingspacingnumber2The gap between the Toggles in spacing units; 0 joins them into one segmented control with
shared seams.labellabelstring''The accessible name of the group when no Field names it.
Properties
PropertyTypeDefaultDescriptiononValueChange((event: TpValueChangeEvent<readonly string[]>) => void) | undefined—Called with each proposed selection before it commits; assign value to accept it or cancel
the event to reject it.
Events
EventTypeDescriptiontp-value-changeTpValueChangeEvent<readonly string[]>Cancelable proposal of a new selection before it commits; detail.value is the list of pressed values, with detail.previousValue and the detail.reason.
Methods
MethodReturnsDescriptionisPressed(member)booleanWhether the given Toggle's value is in the selection; Toggles call it to render their state.isDisabled(member)booleanWhether the group disables the given Toggle.tabStop(member)numberThe tab index of the given Toggle: 0 for the one the group's tab stop lands on, -1 for the
rest.memberChanged()voidRe-reads the Toggles after one is added, removed or changes its value or disabled state.requestToggle(member, pressed, source)voidProposes pressing or releasing the given Toggle; Toggles call it when pressed.setValue(value, reason, source?)voidProposes a new selection as if the user had made it, notifying listeners first; single mode
keeps only the first value.
Slots
SlotDescriptiondefaultThe Toggles, each with a unique value.
CSS parts
PartDescription::part(toggle-group)The element with the group role that holds the Toggles.
<tp-toggle>
Attributes
AttributePropertyTypeDefaultDescriptionpressedpressedboolean—Whether the Toggle is pressed. Set it to own the state: presses then propose changes and the
Toggle shows only what you assign.default-presseddefaultPressedboolean | undefined—The pressed state at first render, when the page does not own pressed.aria-labelariaLabelstring | null—The accessible name of a Toggle that shows only an Icon.native-actionnativeActionbooleantrueRenders the control as a native button; turn it off only when a part contract supplies another
element.variantvariant'ghost' | 'outline'—The paint: ghost shows a fill only while pressed or hovered, outline adds a border for a
Toggle that stands alone.sizesizeToggleSize—The height and padding, matching the Button sizes; the icon-* sizes make a square Toggle for
an Icon alone.
Properties
PropertyTypeDefaultDescriptiononPressedChange((event: TpValueChangeEvent<boolean>) => void) | undefined—Called with each proposed state before it commits; assign pressed to accept it or cancel the
event to reject it.selectionOwnerToggleSelectionOwner | null—The Toggle group that owns this Toggle's state, if any; set by the group itself.controlElementread-onlyHTMLElement | null—The inner button that carries the pressed state and receives focus.toggleDisabledread-onlyboolean—Whether the Toggle is disabled, by itself or by its Toggle group.
Events
EventTypeDescriptiontp-value-changeTpValueChangeEvent<boolean>Cancelable proposal of the inverse pressed state on each press of a standalone Toggle; detail.value, detail.previousValue and the detail.reason.
Methods
MethodReturnsDescriptionsetPressed(pressed, reason, event?)voidProposes a new pressed state as if the user had made it, notifying listeners first; a grouped
Toggle ignores it, since its group owns the value.
Slots
SlotDescriptiondefaultThe label: text, an Icon, or both. Mark a leading or trailing Icon with data-icon="inline-start" or data-icon="inline-end" to tighten the padding on that edge.
CSS parts
PartDescription::part(toggle)The native button that carries the pressed state.::part(toggle-content)The label inside the button; its part contract can render content from the pressed state.
Related
Components, widgets and patterns that use this one.