Toggle
The Toggle component is a button that switches between two states — selected and unselected. It supports variants, sizes, icons, and an optional tooltip, and can be used in controlled or uncontrolled mode.
Variations
Controlled and uncontrolled
The Toggle component can be used in both controlled and uncontrolled modes. In controlled mode, the selected prop drives the toggle’s state and onChange fires with the new boolean when the user activates it. In uncontrolled mode, defaultValue sets the initial state and the component manages its own state internally.
Variants
The variant prop controls the unselected style: outline, ghost, or transparent. The selectedVariant prop controls the style when the toggle is selected, with options primary and secondary.
Sizes
The size prop controls the toggle’s overall dimensions. Supported values are md (default), sm, and xs.
Rounded
Pass rounded to give the underlying button fully rounded corners.
Icon only
Pass iconOnly to size the toggle to fit a single icon, suitable for icon-only buttons. When iconOnly is set, the prefixIcon is the only icon displayed and the text prop becomes the button’s aria-label.
With tooltip
Pass tooltipProps to wrap the toggle in a Tooltip. It accepts the title, content, side, and align properties from TooltipProps.
Installation
import { Toggle } from "@harnessio/ui/components";
<Toggle size="sm" variant="outline" selectedVariant="primary" rounded tooltipProps={{ content: <p>This is a tooltip</p>, }} text="Toggle"/>;Anatomy
Toggle renders a single pressable button that reflects a selected / unselected state.
- The button hosts an optional
prefixIcon, thetextlabel, and an optionalsuffixIcon. IniconOnlymode only theprefixIconshows andtextsupplies the accessible label. - The unselected appearance comes from
variant; when selected, the button switches toselectedVariant(except fortransparent, which stays transparent). - Activating the toggle flips its state and fires
onChangewith the new boolean value. Provideselectedto control the state yourself, ordefaultValueto let the component manage it.
Best practices
Do
- Give every toggle a
textlabel; iniconOnlymode keeptextset so the control still has an accessible name. - Use a
Togglefor a single on/off choice; reach forToggleGroupwhen several related toggles form one set. - Pair
selectedwithonChangein controlled mode, or usedefaultValuefor uncontrolled — don’t mix the two.
Don’t
- Don’t rely on colour alone (the
selectedVariant) to signal state without a clear label or icon. - Don’t use a
Togglefor actions that submit or navigate — use aButtoninstead.
Accessibility
Keyboard
- The toggle is a real
<button>, so it is focusable and activates with Space or Enter.
Labeling & semantics
- The pressed state is exposed to assistive tech (
aria-pressed/data-state) by the underlying Radix Toggle primitive. - In
iconOnlymode thetextprop becomes the button’saria-label; always provide it so the icon-only control has an accessible name.
Properties
Prop | Required | Default | Type |
|---|---|---|---|
| text | false | string | |
| variant | false | 'outline' | 'outline' | 'ghost' | 'transparent' |
| selectedVariant | false | 'primary' | 'primary' | 'secondary' |
| size | false | 'md' | 'md' | 'sm' | 'xs' |
| selected | false | boolean | |
| defaultValue | false | false | boolean |
| onChange | false | (selected: boolean) => void | |
| iconOnly | false | false | boolean |
| rounded | false | false | boolean |
| disabled | false | false | boolean |
| prefixIcon | false | IconName | |
| prefixIconProps | false | Omit<IconPropsV2, 'name'> | |
| suffixIcon | false | IconName | |
| suffixIconProps | false | Omit<IconPropsV2, 'name'> | |
| tooltipProps | false | Pick<TooltipProps, 'title' | 'content' | 'side' | 'align'> | |
| className | false | string |