Skip to content
ArcadiaDesign

Appearance

Theme
Reduce motion
Keep the cache warm

TSX

The one settings anatomy, in an app and on a website alike. The group label sits outside the card on its left edge, in the group type; the card is a hairline frame a step above the page; rows split by hairlines. A row is its name on the left and its control on the right. Below 560px the control drops under the text.

A settings page shows names and controls, and nothing to read. A setting whose name says what it does takes no other text. One that cannot be named clearly takes a hint: a question mark after the label that opens a sentence on demand (a Hint). The setting's current value sits before its control, and a row that is an object (a device, a session) takes one line of meta under its name. A form never sits open on the page: the row shows the value and a button opens the form.

One primary action per page at most. A group-wide action rides the label's line (action); a row's own action is its control.

Examples

Values

What a setting is now sits before its control, in one line that gives way first: its end fades, and a text value shows whole on hover.

Account

Username
ada
Password

The form that changes it opens from the button.

Notice

SettingsNotice is the one sentence a page may show at rest: a warning, a blocker, a security fact or a decision, with at most one action.

Devices

This is your only device and your Recovery Key is not saved. Lose it and the saved sign-ins are gone.

MacBook ProThis device

It is never an explanation of a control. Inside a group it is a row of the card; alone it is a card of its own.

Group action

One action for the whole group sits at the end of the label's line, not in a row of its own.

Sessions

Chrome on macOSThis device
Desktop appSeen 47m ago

Dense

A reference list keeps every row one line high at a 40px pitch. Qualifiers go after the label, never on a second line.

Anywhere

New chat
Search

Give a row a settingId and revealSetting(id) lands on it: it scrolls into view, takes a wash of the selection that fades out, and its control takes focus.

Sounds

Play a sound when a chat finishes
Sound
Default chime

A group is a section labelled by its heading, so a screen reader can jump between groups. A row is plain structure: the control inside carries its own name (hideLabel on a switch still names it), and an error is announced with role="alert". A hint is a button after the label, before the control in the tab order, and its text is its description. A warning notice is a status, a danger notice an alert. A row found by revealSetting moves focus to its control, so Space or an arrow acts at once; under reduced motion the wash is a ring for the same time instead.

SettingsGroup

label
ReactNode
The group's name, outside the card, inset to the rows' text.
hint
string
Why or how, for a group its name cannot explain: a Hint after the label. At most 160 characters.
action
ReactNode
One action at the end of the label's line (a refresh, "Sign out everywhere else").
collapsible
booleanDefault false
The label is a disclosure that shows and hides the card ("Advanced"). A search that lands on a row inside opens it.
defaultOpen
booleanDefault true
A collapsible group's first state.
dense
booleanDefault false
One-line rows at a 40px pitch (a reference list such as keyboard shortcuts).
flush
booleanDefault false
The card hands its whole box to its content (a table, a list with its own rows): no row anatomy.
danger
booleanDefault false
The card's frame takes a red cast: the group's actions can't be undone.
fill
booleanDefault false
The group fills the height of the column it sits in, its card what the label leaves (cards side by side).
id
string
rootStyle
RootStyle
Typed StyleX override: where the group sits.

leading
ReactNode
A leading mark (a provider's tile, a mode's icon), centred on the row's text.
labelrequired
ReactNode
hint
string
Why or how, for a setting its name cannot explain: a Hint after the label. At most 160 characters.
meta
ReactNode
Data about the object this row is (a device's "Seen 2m ago", a path, a plan). One line, text-3: cut, its end fades and the whole shows on hover.
value
ReactNode
The setting's current value, before the control: one line, text-2 ("ada", "Default chime", "4 active").
control
ReactNode
The control on the right: a switch, a segmented control, a button, a field. It takes at most 60% of the row.
menu
ReactNode
The row's menu (its More), after the control. On a narrow screen it stays at the end of the name's line while the control drops under the text.
error
ReactNode
A validation or action error under the text, in the danger ink (announced).
align
"center" | "start"Default "center"
start pins the control to the first line of a tall row.
dim
booleanDefault false
Can't be used right now (not connected, a plan gate): the label drops a rank.
settingId
string
The setting's stable id ("general.theme"): a search result lands on it with revealSetting(id). Rendered as data-setting.

idrequired
string
A stable id ("devices.untrusted"): the product's lint lists every notice with its reason. Rendered as data-notice.
tone
"neutral" | "warning" | "danger"Default "neutral"
neutral: a fact to act on. warning: something is at risk. danger: something is wrong now.
action
ReactNode
One button (two for a choice between sides), at the end.
childrenrequired
ReactNode
One or two sentences: what the user must read to act safely. Never an explanation of a control.