Switch
Switch components provide a way to toggle between two states, typically representing on/off or enabled/disabled states.
Source
LLM docs
Package
Examples
7
Properties
61
Playground
Basics
Control a
Switch with local state and surface its status with supporting text and the description prop.Loading demo…
import { useState } from 'react';
import { Block, Switch, Text } from '@plocks/ui';
export function Demo() {
const [enabled, setEnabled] = useState<boolean>(true);
return (
<Block>
<Switch
checked={enabled}
onChange={setEnabled}
label="Enable live score alerts"
description="Send push notifications when the match score changes."
/>
<Text variant="small" c="muted">
Notices are {enabled ? 'enabled' : 'disabled'}.
</Text>
</Block>
);
}Sizes
Choose a
size token to scale the switch track and thumb; defaultChecked seeds uncontrolled switches.Loading demo…
import { Block, Row, Switch, Text } from '@plocks/ui';
const SIZES = ['xs', 'sm', 'md', 'lg', 'xl', '2xl', '3xl'] as const;
export function Demo() {
return (
<Row align="center" gap="lg" wrap="wrap">
{SIZES.map((size) => (
<Block key={size} align="center">
<Switch accessibilityLabel={`Switch ${size}`} size={size} defaultChecked />
<Text variant="small">{size}</Text>
</Block>
))}
</Row>
);
}Variants
Choose between a solid
filled track (default) and an outline track whose border and thumb take on the active color.Loading demo…
import { useState } from 'react';
import { Block, Row, Switch, Text } from '@plocks/ui';
const VARIANTS = [
{ variant: 'filled', hint: 'filled (default) — solid track fills with the active color' },
{ variant: 'outline', hint: 'outline — bordered track with a colored thumb' },
{ variant: 'ios', hint: 'ios — large white thumb in a rounded pill track' },
{ variant: 'android', hint: 'android — Material dot thumb that grows and whitens when on' },
] as const;
export function Demo() {
const [on, setOn] = useState<Record<string, boolean>>({
filled: true,
outline: true,
ios: true,
android: true,
});
return (
<Block>
{VARIANTS.map(({ variant, hint }) => (
<Block key={variant}>
<Text variant="small" c="muted">
{hint}
</Text>
<Row gap="lg" wrap="wrap" align="center">
<Switch
variant={variant}
checked={on[variant]}
onChange={(v) => setOn((prev) => ({ ...prev, [variant]: v }))}
label="On"
/>
<Switch variant={variant} checked={false} label="Off" />
<Switch variant={variant} checked color="success" label="Success" />
</Row>
</Block>
))}
</Block>
);
}Label on the thumb
Render content inside the moving thumb with the
onIcon / offIcon props — an icon or a short text label that swaps with the on/off state.Loading demo…
import { useState } from 'react';
import { Block, Icon, Switch, Text, useTheme } from '@plocks/ui';
export function Demo() {
const theme = useTheme();
const [wifi, setWifi] = useState<boolean>(true);
const [available, setAvailable] = useState<boolean>(true);
return (
<Block>
<Block>
<Text variant="small" c="muted">
Icon on the thumb — swaps with the on/off state
</Text>
<Switch
checked={wifi}
onChange={setWifi}
size="xl"
label="Wi-Fi"
onIcon={<Icon name="check" size={18} color={theme.colors.primary[3]} stroke={3} />}
offIcon={<Icon name="close" size={18} color={theme.text.muted} stroke={3} />}
/>
</Block>
<Block>
<Text variant="small" c="muted">
Text label on the thumb
</Text>
<Switch
checked={available}
onChange={setAvailable}
size="3xl"
color="success"
label="Availability"
onIcon={
<Text style={{ fontSize: 12, lineHeight: 11, fontWeight: '700', color: theme.colors.success[5] }}>
ON
</Text>
}
offIcon={
<Text style={{ fontSize: 12, lineHeight: 11, fontWeight: '700', color: theme.text.muted }}>
OFF
</Text>
}
/>
</Block>
</Block>
);
}Colors
Provide a
color token to align switches with semantic palettes such as primary, success, or error states.Loading demo…
import { Block, Row, Switch, Text } from '@plocks/ui';
const COLOR_VARIANTS = [
{ label: 'Primary', color: 'primary' },
{ label: 'Secondary', color: 'secondary' },
{ label: 'Success', color: 'success' },
{ label: 'Warning', color: 'warning' },
{ label: 'Error', color: 'error' }
] as const;
export function Demo() {
return (
<Block>
<Text variant="small" c="muted">
Semantic color variants
</Text>
<Row gap="md" wrap="wrap">
{COLOR_VARIANTS.map(({ label, color }) => (
<Switch key={color} defaultChecked label={label} labelPosition="right" color={color} />
))}
</Row>
</Block>
);
}States
Present interactive, disabled, and validation states by combining
checked, disabled, required, and error props.Loading demo…
import { useState } from 'react';
import { Block, Switch, Text } from '@plocks/ui';
export function Demo() {
const [homeAlerts, setHomeAlerts] = useState(true);
const [awayAlerts, setAwayAlerts] = useState(false);
return (
<Block>
<Block>
<Text variant="small" c="muted">
Interactive states
</Text>
<Switch
checked={homeAlerts}
onChange={setHomeAlerts}
label="Home team alerts"
/>
<Switch
checked={awayAlerts}
onChange={setAwayAlerts}
label="Away team alerts"
/>
</Block>
<Block>
<Text variant="small" c="muted">
Disabled states
</Text>
<Switch defaultChecked label="Lineup lock" disabled />
<Switch label="Sound effects" disabled />
</Block>
<Block>
<Text variant="small" c="muted">
Validation helpers
</Text>
<Switch
label="Require broadcast approval"
required
error="Approval is needed before publishing."
/>
<Switch
defaultChecked
label="Send pre-game summary"
description="Dispatch an email recap to coaches and analysts."
/>
</Block>
</Block>
);
}Shared State
Coordinate multiple switches with a shared state object and reflect the current selections in supporting copy.
Loading demo…
import { useState } from 'react';
import { Block, Switch, Text } from '@plocks/ui';
const PREFERENCE_CONTROLS = [
{
key: 'scoreAlerts',
label: 'Live score alerts',
description: 'Push notifications for scoring plays.'
},
{
key: 'newsEmails',
label: 'Breaking news emails',
description: 'Send a morning recap with roster updates.'
},
{
key: 'audioHighlights',
label: 'Audio highlights',
description: 'Play broadcast clips after each match.'
}
] as const;
type PreferenceKey = (typeof PREFERENCE_CONTROLS)[number]['key'];
const INITIAL_SETTINGS: Record<PreferenceKey, boolean> = {
scoreAlerts: true,
newsEmails: false,
audioHighlights: false
};
export function Demo() {
const [settings, setSettings] = useState<Record<PreferenceKey, boolean>>(
() => ({ ...INITIAL_SETTINGS })
);
return (
<Block>
<Block>
<Text variant="small" c="muted">
Shared state
</Text>
{PREFERENCE_CONTROLS.map(({ key, label, description }) => (
<Switch
key={key}
checked={settings[key]}
onChange={(checked) =>
setSettings((prev) => ({ ...prev, [key]: checked }))
}
label={label}
description={description}
/>
))}
</Block>
<Block>
<Text variant="small" c="muted">
Summary
</Text>
<Text variant="p">
Score alerts are {settings.scoreAlerts ? 'on' : 'off'}.
</Text>
<Text variant="p">
Breaking news emails are {settings.newsEmails ? 'on' : 'off'}.
</Text>
<Text variant="p">
Audio highlights are {settings.audioHighlights ? 'on' : 'off'}.
</Text>
</Block>
</Block>
);
}React Native design for iOS, Android, and Web.
Quick Links
Resources