PreferencesMatrix
On and off choices in groups, against channels such as email and push.
import { PreferencesMatrix } from "@butteryui/react";Demo
| Money | Text | Push | |
|---|---|---|---|
| Payouts | |||
| DisputesAlways emailed |
When to use it
Use it for
- Notification preferences across channels, on a SettingsPage with width="narrow"
- Any set of yes-or-no choices that share the same columns
Not for
- One channel: use a list of Switches or Checkboxes
- Choices that wait for a Save across the whole page: put the matrix in a SettingsSection form
Examples
Locked security alerts
Preferences in two tabs, with security alerts locked on by email.
| Security | Text | |
|---|---|---|
| New sign-inAlways emailed, so you hear about it |
Notification settings
A settings section for the shop's notifications: the matrix holds a draft, and Save or Cancel settle it.
Choose how the shop tells you about money and stock.
| Money | Text | Push | |
|---|---|---|---|
| Payouts | |||
| DisputesAlways emailed |
| Stock | Text | Push | |
|---|---|---|---|
| Low green coffeeWhen a coffee drops under 20 kg |
No changes yet
Team notifications
Team notifications across email and push, controlled, with a summary of what's on.
| Money | Push | |
|---|---|---|
| Payouts | ||
| Refunds |
1 on
Variants and states
Notification preferences
Groups of rows against the channels; a locked cell holds its value greyed.
| Money | Text | Push | |
|---|---|---|---|
| Payouts | |||
| DisputesAlways emailed |
| Stock | Text | Push | |
|---|---|---|---|
| Low green coffee |
Props
PreferencesMatrix
| Prop | Type | Default | Description |
|---|---|---|---|
labelrequired | string | Names the matrix, and its tab row when it has more than one tab, such as "Notifications". | |
channelsrequired | readonly PreferenceChannel[] | The ways to be told, its columns, in order. | |
tabsrequired | readonly PreferenceTab[] | Its tabs, each with groups of rows. With one, no tab row shows. | |
value | PreferenceValue | Which channels are on for each row. Pair with onValueChange to control it. | |
defaultValue | PreferenceValue | The value it starts with when uncontrolled. Defaults to every channel off. | |
onValueChange | ((value: PreferenceValue) => void) | Called with the whole value whenever a box is ticked or cleared, locked channels included as they're held. | |
tab | string | The tab shown. Pair with onTabChange to control it. | |
defaultTab | string | The tab shown first when uncontrolled. Defaults to the first. | |
onTabChange | ((tab: string) => void) | Called when another tab is chosen. |
It also takes Omit<ComponentPropsWithRef<"div">, "defaultValue" | "onChange">.
PreferenceChannel
One way to be told, a column of the matrix, such as Email.
| Field | Type | Default | Description |
|---|---|---|---|
idrequired | string | Identifies the channel in the value. | |
labelrequired | string | Its column's header, such as "Email". |
PreferenceTab
A tab of the matrix, such as Account, holding its groups.
| Field | Type | Default | Description |
|---|---|---|---|
idrequired | string | Identifies the tab. | |
labelrequired | string | Its label in the tab row. | |
groupsrequired | readonly PreferenceGroup[] | Its groups. |
PreferenceGroup
Rows under one heading, the channels' headers repeated beside it.
| Field | Type | Default | Description |
|---|---|---|---|
idrequired | string | Identifies the group. | |
titlerequired | string | Its heading, such as "Money". | |
rowsrequired | readonly PreferenceRow[] | Its rows. |
PreferenceRow
One thing to be told about, a row of the matrix.
| Field | Type | Default | Description |
|---|---|---|---|
idrequired | string | Identifies the row in the value. | |
labelrequired | string | What it's about, such as "Payouts", the row's header. | |
description | string | A line under the label. | |
locked | Readonly<Partial<Record<string, boolean>>> | Channels this row can't change, each held on (true) or off (false) and drawn greyed. The value reports them as held. |
Accessibility
A group named by label. Each group is a table named by its title, whose heading row repeats the channels as column headers and whose rows' labels are row headers. Each cell is a checkbox named for its channel and row, such as "Email for Payouts"; a locked cell is a disabled checkbox holding its value. With more than one tab, underline Tabs switch the tables.
| Keys | What they do |
|---|---|
| Tab | Moves from the tab row into the tables and through their checkboxes row by row, skipping locked ones |
| Space | Ticks or clears the checkbox with focus |
| Left or Right arrow | Moves to the tab before or after and shows its tables, when there's more than one tab |
| Home or End | Shows the first or last tab |
Motion
Its selection indicator slides to the chosen option on `spring.snappy`, inside one track.
With reduced motion: The tab row's underline moves to the chosen tab at once.
Layout
It fills its container. Each group is a table as wide as the matrix, each channel's column 64px and the row labels taking the rest, their words wrapping. Rows are padded 12px above and below with a 1px line between them, groups sit 32px apart and the tab row 24px above them. Each checkbox is 18px with a 24px target.
Related
See it in the roastery demo's settings.