@xsolla/xui-toggle-button-group
v0.209.1
Published
A control for picking one or several options from a linear set of closely related options; useful for filtering or sorting. <!-- BEGIN:xui-mcp-instructions:toggle-button-group --> A group of buttons where one or more options can be selected. Used to switc
Readme
ToggleButtonGroup
A control for picking one or several options from a linear set of closely related options; useful for filtering or sorting.
A group of buttons where one or more options can be selected. Used to switch between modes, apply filters, or pick compact options — both as an immediate inline control and inside a form via Field Group. Not used for navigation.
ToggleButtonGroup can be placed inside a Field Group as the content slot. This gives it a label, helper text, and validation message — the same as any other form control. Use this pattern when the selection is part of a form and needs a label or needs to align visually with adjacent fields.
Checkbox vs ToggleButtonGroup:
- Decision guide
When to use
- When a user needs to select one or more options from a small, fixed set (2–8+ items)
- To switch between views, display modes, or content filters
- When options are equal in weight and benefit from a persistent, visible selection state
- When a compact button-style control fits better than a list of checkboxes
- Inside a form via Field Group — as a styled alternative to radio buttons or checkboxes
When not to use
- When the choice triggers a navigation change — use Tabs
- For a single binary on/off toggle — use a Switch
- When there are more options than fit comfortably in a row
- When options are numerous, have descriptions, or need a long vertical list — use a Context-menu with Checkboxes
Content guidelines
- Keep item labels short — one word or a brief noun phrase (e.g. Day, Week, Month).
- Use parallel structure across all items in the same group (all nouns, or all verbs).
- Icons should reinforce the label meaning; avoid using icons that require the label to be understood.
- If using icon-only items (no label), ensure all icons are recognizable and add a tooltip.
Behaviour guidelines
- Clicking an item toggles it between Active and Default.
- The group supports both single-select (one active at a time) and multi-select (multiple active simultaneously) — the selection model is defined at the product level, not by the component itself.
- A Disable item cannot be clicked and cannot receive Active state.
- The group does not close or collapse on selection — it remains fully visible.
Accessibility
- When used as a single-select control, the group should use role="radiogroup" and each item role="radio" with aria-checked.
- When used as a multi-select control, each item should use role="checkbox" with aria-checked.
- Apply aria-disabled="true" to disabled items.
- Provide an accessible label on the group via aria-label or aria-labelledby.
- Focus should be manageable via arrow keys within the group (roving tabindex pattern).
Installation
npm install @xsolla/xui-toggle-button-groupImports
import { ToggleButtonGroup } from '@xsolla/xui-toggle-button-group';
import type {
ToggleButtonGroupProps,
ToggleButtonGroupItem,
ToggleButtonGroupSize,
ToggleButtonGroupAppearance,
} from '@xsolla/xui-toggle-button-group';Quick start
onChange is typed (value: string | string[]) => void regardless of multiple, so single-select callers cast the value to string.
const [value, setValue] = useState('item1');
<ToggleButtonGroup
items={[
{ id: 'item1', label: 'Option 1' },
{ id: 'item2', label: 'Option 2' },
{ id: 'item3', label: 'Option 3' },
]}
value={value}
onChange={(v) => setValue(v as string)}
/>;API Reference
<ToggleButtonGroup>
| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| items | ToggleButtonGroupItem[] | — | Items to display. |
| value | string \| string[] | — | Controlled value; string for single, array for multiple. |
| defaultValue | string \| string[] | — | Initial value for uncontrolled mode. |
| onChange | (value: string \| string[]) => void | — | Fired when the selection changes. |
| size | 'xs' \| 'sm' \| 'md' \| 'lg' \| 'xl' | 'sm' | Size variant. |
| appearance | 'separated' \| 'united' | 'separated' | separated adds gaps; united connects items. |
| view | 'horizontal' \| 'vertical' | 'horizontal' | Stack items in a row or column. |
| multiple | boolean | false | Allow multiple selections. |
| fullWidth | boolean | false | Stretch to fill the container. |
| id | string | — | HTML id. |
| testID | string | — | Test identifier for the group root. |
| aria-label | string | — | Accessible label for the group. |
| aria-labelledby | string | — | ID of an element that labels the group. |
Inherits ThemeOverrideProps (themeMode, themeProductContext).
ToggleButtonGroupItem
| Field | Type | Description |
| --- | --- | --- |
| id | string | Unique identifier. |
| label | string | Display text. Omit for icon-only items (set aria-label and tooltip). |
| iconLeft | ReactNode | Icon shown before the label. |
| iconRight | ReactNode | Icon shown after the label. |
| disabled | boolean | Disable the individual item. |
| testID | string | Applied as data-testid on the item's button root — one test id per option, for QA automation. |
| aria-label | string | Accessible label. Required when label is omitted. |
| tooltip | Omit<TooltipProps, 'children'> | Tooltip props for the button (web only). placement defaults to "top" (horizontal) or "right" (vertical); size defaults from theme.sizing.toggleButtonGroup(size).tooltipSize. |
Types
type ToggleButtonGroupSize = 'xs' | 'sm' | 'md' | 'lg' | 'xl';
type ToggleButtonGroupAppearance = 'separated' | 'united';
type ToggleButtonGroupView = 'horizontal' | 'vertical';
type ToggleButtonGroupItemTooltip = Omit<TooltipProps, 'children'>;Examples
Multiple selection
onChange is still typed (value: string | string[]) => void, so multi-select callers cast the value to string[].
const [values, setValues] = useState(['item1', 'item3']);
<ToggleButtonGroup
multiple
items={[
{ id: 'item1', label: 'Option 1' },
{ id: 'item2', label: 'Option 2' },
{ id: 'item3', label: 'Option 3' },
]}
value={values}
onChange={(v) => setValues(v as string[])}
/>United appearance, full width
<ToggleButtonGroup
appearance="united"
fullWidth
items={[
{ id: 'day', label: 'Day' },
{ id: 'week', label: 'Week' },
{ id: 'month', label: 'Month' },
]}
defaultValue="week"
/>Per-item test IDs
Set testID on each item to emit a data-testid on that option's button root. QA automation can target options declaratively instead of relying on DOM order.
<ToggleButtonGroup
items={[
{ id: 'day', label: 'Day', testID: 'period-day' },
{ id: 'week', label: 'Week', testID: 'period-week' },
{ id: 'month', label: 'Month', testID: 'period-month' },
]}
defaultValue="week"
aria-label="Period"
/>Icons
import { BadgeDiscount, Crown } from '@xsolla/xui-icons-base';
<ToggleButtonGroup
items={[
{ id: 'sale', label: 'Sale', iconLeft: <BadgeDiscount variant="line" /> },
{ id: 'premium', label: 'Premium', iconRight: <Crown variant="line" /> },
{
id: 'vip',
iconLeft: <Crown variant="line" />,
'aria-label': 'VIP',
tooltip: { content: 'VIP' },
},
]}
defaultValue="sale"
/>Accessibility
role="radiogroup"for single selection,role="group"for multiple selection.- Arrow keys move between items; Enter/Space toggles selection.
aria-checkedandaria-disabledreflect item state.
