All components (204)
Switch
Choice · Switch · .amset-switch
What it is and when to use it
An on/off switch for a setting that applies immediately, without a Save button.
When to use it
- Settings that take effect as soon as they are touched: "Send the invoice by email", "Notify me when it is back in stock".
- When what is being decided is turning something on or off, not answering a question.
loadingwhile the server confirms the change: it does not change value or accept another press, but it remains focusable and the knob carries a spinner.
When not to
- If the change needs a Save (a form, terms that are accepted):
Checkbox. - Choosing between two options with names of their own (monthly or yearly, list or grid):
SegmentedGroup.
Keyboard: it is a native checkbox with the role of a switch: Tab reaches it and Space turns it on and off. With disabled it leaves the Tab order.
Accessibility: it is announced as switch, with its on or off state. The name is the text, which is required; the description is read afterwards, as a description. The track and the knob are decorative. In a right-to-left language the knob moves toward the left without touching anything.
Sizes: track 28, 34 or 44 px wide, centered on the first line of the text. With a finger, the row reaches 44 px.
States: hover, pressed (the knob stretches toward where it is going), keyboard focus, on (the knob crosses the track), read-only (dashed track, no accent) and disabled.
Fine-tuning: variables --amset-switch-width, -height, -knob, -stretch, -font, -description, -track, -track-active and -color-knob.
What it looks like
<Switch defaultSelected>Email alerts</Switch>
<Switch description="Applied on entry">Dark mode</Switch>Props
Import it with import { Switch } from '@amset/ui'. Required props are marked.
| Prop | Type | What it does |
|---|---|---|
childrenrequired | ReactNode | The name of the setting: it is what the screen reader hears. |
aria-controls | string | Identifies the element (or elements) whose contents or presence are controlled by the current element. |
aria-describedby | string | Identifies the element (or elements) that describes the object. |
aria-details | string | Identifies the element that provides a detailed, extended description for the object. |
aria-label | string | Defines a string value that labels the current element. |
aria-labelledby | string | Identifies the element (or elements) that labels the current element. |
autoFocus | boolean | — |
className | string | Merged with the library classes; it does not replace them. |
defaultSelected | boolean | On at the start, managing its own state. |
description | string | What the setting does, under the name. It is read as a description, not as part of the name. |
disabled | boolean | — |
excludeFromTabOrder | boolean | Takes it out of the tab order without removing focus programmatically. |
form | string | The `id` of the `<form>` it belongs to, if it is not wrapped by it. |
id | string | It goes to the `<input>`, which is the focusable node: `WeeklySchedule` looks it up with `getElementById` to take focus to it, and on the `<label>` it would not work. |
inputRef | Ref<HTMLInputElement> | To reach the real `<input>`. |
loading | boolean | Waiting for whoever mounts it to confirm the change (a request to the server). While it lasts it does NOT change value and does not notify, but it stays in the tab order (focus is not lost) and carries a spinner on the handle. It is what prevents pressing it again without knowing the first click has not arrived yet. |
name | string | The name it travels under in the form. |
onBlur | (event: FocusEvent<HTMLInputElement>) => void | — |
onChange | (selected: boolean) => void | — |
onChangeEvent | (event: ChangeEvent<HTMLInputElement>) => void | Like `onChange`, but with the native event of the `<input>`: `e.target.checked`... It exists to migrate a front end that already writes its handlers with the event (AMS-735). If you only want to know whether it is checked, `onChange` already gives you that. |
onFocus | (event: FocusEvent<HTMLInputElement>) => void | — |
onPress | (event: ChoicePressEvent) => void | Notified when pressed, saying what it was pressed with. |
readOnly | boolean | It is read and focused, but does not change. |
selected | boolean | On, controlled from outside. |
size | "sm" | "md" | "lg" | Size of the track and the text: 28, 34 or 44 px wide. With a finger, the row reaches 44 px. |
value | string | The value it travels with in the form when it is on. |
It also accepts the attributes of the element it renders: className, style, data-*, aria-* and its events.
CSS variables
These CSS variables are how you adapt it. Declare them on the component's selector, not on :root: the stylesheet redeclares them in the rule itself, and a declaration on the same element always wins.
| Variable | Default |
|---|---|
--amset-switch-width | 2.125rem |
--amset-switch-height | 1.25rem |
--amset-switch-knob | 1rem |
--amset-switch-stretch | 0.25rem |
--amset-switch-font | var(--amset-text-base) |
--amset-switch-description | var(--amset-text-sm) |
--amset-switch-track | var(--amset-border-bold) |
--amset-switch-track-active | var(--amset-accent) |
--amset-switch-color-knob | var(--amset-surface) |
--amset-switch-slot | calc((var(--amset-switch-height) - var(--amset-switch-knob)) / 2) |
--amset-switch-line | calc(var(--amset-switch-font) * var(--amset-line-tight)) |
--amset-switch-extra | 0px |
--amset-switch-target | 1.5rem |
How to change it
.amset-switch {
--amset-switch-width: ...;
--amset-switch-height: ...;
}In the test bench
Every state and variant, to try one at a time, on its page at ui.amset.tech:
