<State initial={{value1: true, value2: false}}>
{([state, setState]) => (
<>
<ToggleSwitch
checked={state.value1}
label="Toggle 1"
name="Toggle1"
onChange={() => setState(prev => ({...prev, value1: !state.value1}))}
/>
<br />
<br />
<ToggleSwitch
checked={state.value2}
label="Toggle 2"
name="Toggle2"
onChange={() => setState(prev => ({...prev, value2: !state.value2}))}
/>
</>
)}
</State>
Toggle Switch Labels
Toggle Switch labels are on the right side of the toggle element. They generally have two pieces: the action being taken, and the subject matter.
<ToggleSwitch
label="Show Audit Trail"
name="Toggle-1"
value="Test1"
/>
Label Help
Labels can have a help icon with a tooltip to provide additional context to a label.
<Form>
<Form.ToggleSwitch
label="Toggle Switch Label"
labelProps={{
help: "This is help text"
}}
/>
</Form>
Action Only
Sometimes it make sense for the toggle's subject to be separated from the toggle itself. This is useful in a list-context or if the subject is tied to a more complex UI component such as a Card, Table, or Page title.
Action Only With Cards
<State initial={{value1: true, value2: false}}>
{([state, setState]) => (
<>
<Card
sharp
active={state.value1}
raised={state.value1}
onClick={() => setState(prev => ({...prev, value1: !state.value1}))}
>
<Stack alignItems='center'>
<Stack.Item fill>
<BodyText size="large" bold>Report Form Widget</BodyText>
<BodyText subdued>Lorem ipsum dolar emit</BodyText>
</Stack.Item>
<Stack.Item>
<ToggleSwitch
checked={state.value1}
label="Toggle 1"
name="Toggle1"
/>
</Stack.Item>
</Stack>
</Card>
<Card
className="m-t-2"
sharp
active={state.value2}
raised={state.value2}
onClick={() => setState(prev => ({...prev, value2: !state.value2}))}
>
<Stack alignItems='center'>
<Stack.Item fill>
<BodyText size="large" bold>Audit Inventory Widget</BodyText>
<BodyText subdued>Lorem ipsum dolar emit</BodyText>
</Stack.Item>
<Stack.Item>
<ToggleSwitch
checked={state.value2}
label="Toggle 2"
name="Toggle2"
/>
</Stack.Item>
</Stack>
</Card>
</>
)}
</State>
Action Only In a List
When scanning a set of options, it may make sense to separate the toggle's subject to the left. This can be done with caution: the user should be able to understand they are toggling the text to the left on or off.
<Form>
<ToggleSwitch
className="m-b-2 d-b"
label="Show Technician Availability"
name="Toggle-1"
value="Test1"
/>
<ToggleSwitch
className="m-b-2 d-b"
label="Show Job Audit"
name="Toggle-1"
value="Test1"
/>
<ToggleSwitch
className="m-b-2 d-b"
label="Show Smart Estimates"
name="Toggle-1"
value="Test1"
/>
</Form>
<Stack alignItems="stretch">
<Stack direction="column" justifyContent="space-between" className="flex-grow-1 m-r-4">
<BodyText
el="label"
htmlFor="switch-id1"
>
Technician Availability
</BodyText>
<BodyText
el="label"
htmlFor="switch-id2"
>
Job Audit
</BodyText>
<BodyText
el="label"
htmlFor="switch-id3"
>
Smart Estimates
</BodyText>
</Stack>
<Stack direction="column" justifyContent="space-between">
<ToggleSwitch
className="m-b-2"
label="Enabled"
name="Toggle-1"
value="Test1"
id="switch-id1"
/>
<ToggleSwitch
className="m-b-2"
label="Enabled"
name="Toggle-2"
value="Test2"
id="switch-id2"
/>
<ToggleSwitch
label="Enabled"
name="Toggle-3"
value="Test3"
id="switch-id3"
/>
</Stack>
</Stack>
No Label
A toggle switch can also have no label when the context of what it turns on or off can be clearly understood. A tooltip can also be applied to describe the toggle's current state.
<State initial={{value1: true, value2: false, value3: false}}>
{([state, setState]) => (
<Form className="example">
<style>{`
.example .field { margin-bottom: 24px !important; }
.example .field > label { display: none !important; }
`}</style>
<Stack alignItems="center" spacing="1" className="m-b-3">
<Input
defaultValue="Leia Doe"
disabled={!state.value1}
/>
<Input
defaultValue="leia12345@email.com"
disabled={!state.value1}
/>
<Input
defaultValue="(123) 456–7890"
disabled={!state.value1}
/>
<Tooltip text={"Leia Doe account is " + (state.value1 ? "enabled" : "disabled")} direction="tl">
<ToggleSwitch
checked={state.value1}
onClick={() => setState(prev => ({...prev, value1: !state.value1}))}
/>
</Tooltip>
</Stack>
<Stack alignItems="center" spacing="1" className="m-b-3">
<Input
defaultValue="Jane Spencer"
disabled={!state.value2}
/>
<Input
defaultValue="janespencer@email.com"
disabled={!state.value2}
/>
<Input
defaultValue="(555) 456–7890"
disabled={!state.value2}
/>
<Tooltip text={"Jane Spencer account is " + (state.value2 ? "enabled" : "disabled")} direction="tl">
<ToggleSwitch
checked={state.value2}
onClick={() => setState(prev => ({...prev, value2: !state.value2}))}
/>
</Tooltip>
</Stack>
<Stack alignItems="center" spacing="1">
<Input
defaultValue="Bob Smith"
disabled={!state.value3}
/>
<Input
defaultValue="bob@email.com"
disabled={!state.value3}
/>
<Input
defaultValue="(492) 451–1290"
disabled={!state.value3}
/>
<Tooltip text={"Bob Smith account is " + (state.value3 ? "enabled" : "disabled")} direction="tl">
<ToggleSwitch
checked={state.value3}
onClick={() => setState(prev => ({...prev, value3: !state.value3}))}
/>
</Tooltip>
</Stack>
</Form>
)}
</State>
Constant Labeling
The Toggle Switch label is always the same text. It describes what the "ON" state of the toggle is. The label should not switch based off the toggle's state.
<Form>
<ToggleSwitch
label="Active"
name="Toggle-1"
value="Test1"
/>
</Form>
<State initial={true}>
{([state, setState]) => (
<Form>
<ToggleSwitch
label={state ? "Active" : "Inactive" }
name="Toggle-1"
onChange={() => setState(!state)}
/>
</Form>
)}
</State>
Positive Wording
Labels in general should be positive. Since the label and toggle are generally thought of as turning something on, labels should reenforce this. Examples include “Show”, “Hide”, “Activate”, “Group [by]”, “Track”, and “Activate”. Negative labeling can be used with caution, if it makes sense to a user to perform a negative action.
<Form>
<ToggleSwitch
label="Show Tech Map"
name="Toggle-1"
value="Test1"
/>
</Form>
<Form>
<ToggleSwitch
label="Hide Tech Map"
name="Toggle-1"
value="Test1"
/>
</Form>
In general, toggle switches should provide immediate feedback that something has occurred.
<State initial={false}>
{([unlocked, setUnlocked]) => (
<Form>
<ToggleSwitch
checked={unlocked}
label="Unlock Custom Name"
name="Toggle-1"
onChange={() => setUnlocked(!unlocked)}
/>
<Form.Group widths="equal" className="p-t-3">
<Form.Input label="First Name" defaultValue="Jane" placeholder="Leia" disabled={!unlocked} />
<Form.Input label="Last Name" defaultValue="Doe" placeholder="Organa" disabled={!unlocked} />
</Form.Group>
</Form>
)}
</State>
Consider using a Checkbox when a button needs to be pressed in for the setting to take place.
<Form>
<Form.Checkbox
label="Show Option 1"
name="Check-1"
/>
<Form.Checkbox
label="Show Option 2"
name="Check-2"
/>
<Form.Checkbox
label="Show Option 3"
name="Check-3"
/>
<Form.Button full primary>Apply</Form.Button>
</Form>
<State initial={{value1: true, value2: false, value3: false}}>
{([state, setState]) => (
<Form>
<Form.ToggleSwitch
checked={state.value1}
onChange={() => setState(prev => ({...prev, value1: !state.value1}))}
label="Show Option 1"
/>
<Form.ToggleSwitch
checked={state.value2}
onChange={() => setState(prev => ({...prev, value2: !state.value2}))}
label="Show Option 2"
/>
<Form.ToggleSwitch
checked={state.value3}
onChange={() => setState(prev => ({...prev, value3: !state.value3}))}
label="Show Option 3"
/>
<Form.Button full primary>Apply</Form.Button>
</Form>
)}
</State>
A Toggle Switch can also be added into a Form component.
<Form>
<Headline el="div" className="m-b-4">Add Contact</Headline>
<Form.Group widths="equal">
<Form.Input label="First Name" placeholder="Leia" />
<Form.Input label="Last Name" placeholder="Organa" />
</Form.Group>
<State>
{([planet, setPlanet]) => (
<Form.Select
label="Home Planet"
placeholder="Choose Planet"
options={[
{key:1, value: 1, text: 'Alderaan'},
{key:2, value: 2, text: 'Bespin'},
{key:3, value: 3, text: 'Coruscant'},
{key:4, value: 4, text: 'Dagobah'},
{key:5, value: 5, text: 'Hoth'},
{key:6, value: 6, text: 'Kashyyyk'},
{key:7, value: 7, text: 'Naboo',},
{key:8, value: 8, text: 'Tatooine'},
{key:9, value: 9, text: 'Yavin'},
]}
onChange={(event, value) => setPlanet(value.value)}
value={planet}
/>
)}
</State>
<State initial={{disabled: true, duration: undefined}}>
{([state, setState]) => (
<>
<Form.ToggleSwitch
checked={!state.disabled}
label="Track Tax Values"
onChange={() => setState(prev => ({...prev, disabled: !state.disabled}))}
/>
<Form.Group>
<Form.Input disabled={state.disabled} label="Tax Rate" placeholder="8.45%" />
<Form.Input disabled={state.disabled} label="Duration" placeholder="3" />
<Form.Select
disabled={state.disabled}
label="Duration Units"
placeholder="Choose Units"
options={[
{key:1, value: 1, text: 'Days'},
{key:2, value: 2, text: 'Weeks'},
{key:3, value: 3, text: 'Months'}
]}
onChange={(event, value) => setState(prev => ({...prev, duration: !value.value}))}
value={state.duration}
/>
</Form.Group>
</>
)}
</State>
</Form>
Disabled State
<div>
<ToggleSwitch
checked
className="d-b m-b-2"
label="Default On"
name="Toggle-1"
value="Test1"
/>
<ToggleSwitch
className="d-b m-b-4"
label="Default Off"
name="Toggle-1"
value="Test1"
/>
<ToggleSwitch
checked
className="d-b m-b-2"
disabled
label="Disabled On"
name="Toggle-1"
value="Test1"
/>
<ToggleSwitch
disabled
label="Disabled Off"
name="Toggle-1"
value="Test1"
/>
</div>
<State initial={{value1: true, value2: true, value3: true}}>
{([state, setState]) => (
<div>
<BodyText className="m-b-2">Notification settings:</BodyText>
<ToggleSwitch
className="m-r-4"
checked={state.value1}
label="Enable all notifications"
onChange={() => setState(prev => ({...prev, value1: !state.value1}))}
/>
<ToggleSwitch
className="m-r-4"
checked={state.value2 || state.value1}
disabled={state.value1}
label="SMS"
onChange={() => setState(prev => ({...prev, value2: !state.value2}))}
/>
<ToggleSwitch
className="m-r-4"
checked={state.value3 || state.value1}
disabled={state.value1}
label="Email"
onChange={() => setState(prev => ({...prev, value3: !state.value3}))}
/>
</div>
)}
</State>
Best Practices
- Toggle Switches in general should provide immediate results.
- Toggle Switch options should be reducible to an On/Off choice.
- Labels should be framed positively.
- If using a Tooltip, display the current Toggle Switch state.
- When in doubt, use the label to describe both the action and the subject of the Toggle Switch.
- Use visual indicators such as disabled and active states on other elements to reenforce the state of the Toggle Switch.
Content Guidelines
Give a descriptive, direct label
The toggle switch label should describe what the control does when it is turned on. Rule of thumb: say the label name and add an “on/off”.
Use sentence case (capitalize only the first word and proper nouns) so control labels are easy to scan. Do not use periods for short phrases or single sentences.
The toggle switch label might not give the required information and context they need to make an informed decision about the option.
Inline help is the best option for this situation because it requires no user interaction and is always visible. Keep inline help to 1-2 sentences. Use the content guidelines for inline help.
Avoid using a tooltip to communicate this kind of information about an option. It’s an additional step for users to mouse over the tooltip to reveal its information, and users can’t refer to the tooltip content and take action at the same time.
<Form.ToggleSwitch
label="Project labels"
name="Toggle-1"
value="Test1"
description="This allows techs to view, apply and edit project labels given to job records"
labelProps={{ help: "A project label can be attached to expense items like timesheet activities to provide a visual representation of expense spending." }}
/>
Components
- When needing a Yes/No choice, or needing to submit a form, use a Checkbox.
- For more complex, mutually exclusive choices, use a Button Toggle or Radio.
Patterns
- Form design pattern for how related controls are ordered.
Importing
import { ToggleSwitch } from '@servicetitan/design-system';