Switch
A controlled switch for boolean settings.
Examples
Section titled “Examples”Default
Section titled “Default”Receive product updates and account alerts.
function SwitchStory(args: React.ComponentProps<typeof Switch>) { const [isSelected, setIsSelected] = useState(args.isSelected); const onChange = args.onChange as SwitchProps['onChange'] | undefined; return ( <Switch {...args} isSelected={isSelected} onChange={(nextIsSelected, event) => { setIsSelected(nextIsSelected); onChange?.(nextIsSelected, event); }} /> );}
<SwitchStory {...args} />States
Section titled “States”Loading
Loading
Loading
<VStack gap={4}> <Switch isSelected={false} label="Off" onChange={() => {}} /> <Switch isSelected label="On" onChange={() => {}} /> <Switch isDisabled isSelected={false} label="Disabled" onChange={() => {}} /> <Switch isDisabled isLoading isSelected label="Disabled loading" onChange={() => {}} /> <Switch isLoading isSelected={false} label="Loading off" onChange={() => {}} /> <Switch isLoading isSelected label="Loading" onChange={() => {}} /></VStack>Loading
Loading
Loading
<VStack gap={4}> {SIZES.map(size => ( <HStack align="center" gap={4} key={size}> <Switch isSelected={false} label={`Off (${size})`} onChange={() => {}} size={size} /> <Switch isSelected label={`On (${size})`} onChange={() => {}} size={size} /> <Switch isLoading isSelected label={`Loading (${size})`} onChange={() => {}} size={size} /> </HStack> ))}</VStack>Size Alignment
Section titled “Size Alignment”Radio sm
Radio md
Radio lg
<VStack gap={6}> {SIZES.map(size => ( <HStack align="center" gap={6} key={size}> <Switch isSelected label={`Switch ${size}`} onChange={() => {}} size={size} /> <CheckboxInput label={`Checkbox ${size}`} onChange={() => {}} size={size} value width="auto" /> <RadioGroup isLabelHidden label={`Radio ${size}`} onChange={() => {}} size={size} value="on"> <RadioGroupItem label={`Radio ${size}`} value="on" /> </RadioGroup> </HStack> ))}</VStack>Receive product updates and account alerts.
This setting is required.
function SwitchStory(args: React.ComponentProps<typeof Switch>) { const [isSelected, setIsSelected] = useState(args.isSelected); const onChange = args.onChange as SwitchProps['onChange'] | undefined; return ( <Switch {...args} isSelected={isSelected} onChange={(nextIsSelected, event) => { setIsSelected(nextIsSelected); onChange?.(nextIsSelected, event); }} /> );}
<SwitchStory {...args} />Label Start
Section titled “Label Start”Receive product updates and account alerts.
function SwitchStory(args: React.ComponentProps<typeof Switch>) { const [isSelected, setIsSelected] = useState(args.isSelected); const onChange = args.onChange as SwitchProps['onChange'] | undefined; return ( <Switch {...args} isSelected={isSelected} onChange={(nextIsSelected, event) => { setIsSelected(nextIsSelected); onChange?.(nextIsSelected, event); }} /> );}
<SwitchStory {...args} />Spread
Section titled “Spread”Receive product updates and account alerts.
function SwitchStory(args: React.ComponentProps<typeof Switch>) { const [isSelected, setIsSelected] = useState(args.isSelected); const onChange = args.onChange as SwitchProps['onChange'] | undefined; return ( <Switch {...args} isSelected={isSelected} onChange={(nextIsSelected, event) => { setIsSelected(nextIsSelected); onChange?.(nextIsSelected, event); }} /> );}
<SwitchStory {...args} />Hidden Label
Section titled “Hidden Label”Receive account alerts.
function SwitchStory(args: React.ComponentProps<typeof Switch>) { const [isSelected, setIsSelected] = useState(args.isSelected); const onChange = args.onChange as SwitchProps['onChange'] | undefined; return ( <Switch {...args} isSelected={isSelected} onChange={(nextIsSelected, event) => { setIsSelected(nextIsSelected); onChange?.(nextIsSelected, event); }} /> );}
<SwitchStory {...args} />Hidden Label Without Description
Section titled “Hidden Label Without Description”function SwitchStory(args: React.ComponentProps<typeof Switch>) { const [isSelected, setIsSelected] = useState(args.isSelected); const onChange = args.onChange as SwitchProps['onChange'] | undefined; return ( <Switch {...args} isSelected={isSelected} onChange={(nextIsSelected, event) => { setIsSelected(nextIsSelected); onChange?.(nextIsSelected, event); }} /> );}
<SwitchStory {...args} />Label Icon
Section titled “Label Icon”Receive product updates and account alerts.
function SwitchStory(args: React.ComponentProps<typeof Switch>) { const [isSelected, setIsSelected] = useState(args.isSelected); const onChange = args.onChange as SwitchProps['onChange'] | undefined; return ( <Switch {...args} isSelected={isSelected} onChange={(nextIsSelected, event) => { setIsSelected(nextIsSelected); onChange?.(nextIsSelected, event); }} /> );}
<SwitchStory {...args} />Label Tooltip
Section titled “Label Tooltip”Receive product updates and account alerts.
function SwitchStory(args: React.ComponentProps<typeof Switch>) { const [isSelected, setIsSelected] = useState(args.isSelected); const onChange = args.onChange as SwitchProps['onChange'] | undefined; return ( <Switch {...args} isSelected={isSelected} onChange={(nextIsSelected, event) => { setIsSelected(nextIsSelected); onChange?.(nextIsSelected, event); }} /> );}
<SwitchStory {...args} />Necessity
Section titled “Necessity”<VStack gap={4}> <Switch isRequired isSelected label="Required setting" onChange={() => {}} /> <Switch isOptional isSelected={false} label="Optional setting" onChange={() => {}} /></VStack>Description
Section titled “Description”This longer description explains when the setting applies and wraps onto multiple lines in constrained layouts.
<VStack gap={4}> <Switch isSelected label="Compact setting" onChange={() => {}} /> <Switch description="This longer description explains when the setting applies and wraps onto multiple lines in constrained layouts." isSelected label="Detailed setting" onChange={() => {}} style={{maxWidth: 360}} /></VStack>Warning
Section titled “Warning”Receive product updates and account alerts.
Notification delivery may be delayed.
function SwitchStory(args: React.ComponentProps<typeof Switch>) { const [isSelected, setIsSelected] = useState(args.isSelected); const onChange = args.onChange as SwitchProps['onChange'] | undefined; return ( <Switch {...args} isSelected={isSelected} onChange={(nextIsSelected, event) => { setIsSelected(nextIsSelected); onChange?.(nextIsSelected, event); }} /> );}
<SwitchStory {...args} />Success
Section titled “Success”Receive product updates and account alerts.
This setting is active and healthy.
function SwitchStory(args: React.ComponentProps<typeof Switch>) { const [isSelected, setIsSelected] = useState(args.isSelected); const onChange = args.onChange as SwitchProps['onChange'] | undefined; return ( <Switch {...args} isSelected={isSelected} onChange={(nextIsSelected, event) => { setIsSelected(nextIsSelected); onChange?.(nextIsSelected, event); }} /> );}
<SwitchStory {...args} />Read Only
Section titled “Read Only”Receive product updates and account alerts.
function SwitchStory(args: React.ComponentProps<typeof Switch>) { const [isSelected, setIsSelected] = useState(args.isSelected); const onChange = args.onChange as SwitchProps['onChange'] | undefined; return ( <Switch {...args} isSelected={isSelected} onChange={(nextIsSelected, event) => { setIsSelected(nextIsSelected); onChange?.(nextIsSelected, event); }} /> );}
<SwitchStory {...args} />Switch
Section titled “Switch”A controlled switch for boolean settings.
When isOptional: false, isRequired: false
| Prop | Type | Default | Description |
|---|---|---|---|
className | string | — | Additional CSS class names applied to the field root. |
data-testid | string | — | Test ID applied to the checkbox input. |
description | ReactNode | — | Supporting text displayed below the label. |
htmlName | string | — | HTML name attribute for native form submission. |
isDisabled | boolean | false | Whether the switch is disabled. |
isLabelHidden | boolean | false | Whether to visually hide the label. |
isLoading | boolean | false | Whether the switch is loading. |
isReadOnly | boolean | false | Whether the value is displayed without allowing focus or interaction. |
isSelected* | boolean | — | Whether the switch is on. |
label* | string | — | Switch label. |
labelIcon | IconComponent | — | Content rendered before the label. |
labelPosition | "start" | "end" | 'end' | Which side of the switch the label appears on. |
labelSpacing | "default" | "spread" | 'default' | Spacing behavior between label and switch. |
labelTooltip | ReactNode | — | Tooltip content shown next to the label. |
onBlur | (event: FocusEvent<HTMLInputElement>) => void | — | Called when the switch loses focus. |
onChange* | (checked: boolean, event: ChangeEvent<HTMLInputElement>) => void | — | Called when the checked state changes. |
onFocus | (event: FocusEvent<HTMLInputElement>) => void | — | Called when the switch receives focus. |
ref | Ref<HTMLInputElement> | — | Ref forwarded to the checkbox input. |
size | "sm" | "md" | "lg" | 'md' | Visual size of the switch. Defaults to the ambient size when unset. |
status | InputStatus | — | Validation status displayed below the switch. |
style | CSSProperties | — | Inline styles applied to the field root. |
isOptional | false | — | |
isRequired | false | — |
When isOptional: true, isRequired: false
| Prop | Type | Default | Description |
|---|---|---|---|
className | string | — | Additional CSS class names applied to the field root. |
data-testid | string | — | Test ID applied to the checkbox input. |
description | ReactNode | — | Supporting text displayed below the label. |
htmlName | string | — | HTML name attribute for native form submission. |
isDisabled | boolean | false | Whether the switch is disabled. |
isLabelHidden | boolean | false | Whether to visually hide the label. |
isLoading | boolean | false | Whether the switch is loading. |
isReadOnly | boolean | false | Whether the value is displayed without allowing focus or interaction. |
isSelected* | boolean | — | Whether the switch is on. |
label* | string | — | Switch label. |
labelIcon | IconComponent | — | Content rendered before the label. |
labelPosition | "start" | "end" | 'end' | Which side of the switch the label appears on. |
labelSpacing | "default" | "spread" | 'default' | Spacing behavior between label and switch. |
labelTooltip | ReactNode | — | Tooltip content shown next to the label. |
onBlur | (event: FocusEvent<HTMLInputElement>) => void | — | Called when the switch loses focus. |
onChange* | (checked: boolean, event: ChangeEvent<HTMLInputElement>) => void | — | Called when the checked state changes. |
onFocus | (event: FocusEvent<HTMLInputElement>) => void | — | Called when the switch receives focus. |
ref | Ref<HTMLInputElement> | — | Ref forwarded to the checkbox input. |
size | "sm" | "md" | "lg" | 'md' | Visual size of the switch. Defaults to the ambient size when unset. |
status | InputStatus | — | Validation status displayed below the switch. |
style | CSSProperties | — | Inline styles applied to the field root. |
isOptional* | true | — | |
isRequired | false | — |
When isOptional: false, isRequired: true
| Prop | Type | Default | Description |
|---|---|---|---|
className | string | — | Additional CSS class names applied to the field root. |
data-testid | string | — | Test ID applied to the checkbox input. |
description | ReactNode | — | Supporting text displayed below the label. |
htmlName | string | — | HTML name attribute for native form submission. |
isDisabled | boolean | false | Whether the switch is disabled. |
isLabelHidden | boolean | false | Whether to visually hide the label. |
isLoading | boolean | false | Whether the switch is loading. |
isReadOnly | boolean | false | Whether the value is displayed without allowing focus or interaction. |
isSelected* | boolean | — | Whether the switch is on. |
label* | string | — | Switch label. |
labelIcon | IconComponent | — | Content rendered before the label. |
labelPosition | "start" | "end" | 'end' | Which side of the switch the label appears on. |
labelSpacing | "default" | "spread" | 'default' | Spacing behavior between label and switch. |
labelTooltip | ReactNode | — | Tooltip content shown next to the label. |
onBlur | (event: FocusEvent<HTMLInputElement>) => void | — | Called when the switch loses focus. |
onChange* | (checked: boolean, event: ChangeEvent<HTMLInputElement>) => void | — | Called when the checked state changes. |
onFocus | (event: FocusEvent<HTMLInputElement>) => void | — | Called when the switch receives focus. |
ref | Ref<HTMLInputElement> | — | Ref forwarded to the checkbox input. |
size | "sm" | "md" | "lg" | 'md' | Visual size of the switch. Defaults to the ambient size when unset. |
status | InputStatus | — | Validation status displayed below the switch. |
style | CSSProperties | — | Inline styles applied to the field root. |
isOptional | false | — | |
isRequired* | true | — |