App shell
Settings Modal
The “Settings & members” dialog: a 240px searchable nav of groups and tabs, and a scrolling 800px content column of sections and rows.
Account
Workspace
Access & billing
Preferences
Choose how you want Motion to look and behave.
Appearance
Theme
Choose a theme for Motion on this device
High contrastBeta
Increase contrast for improved visibility
Input options
Use Enter to add a new line
Press Cmd+Enter to send messages
Usage
- Use it for app or workspace settings with several categories.
- Group related options in
SettingsSections; one control perSettingsRow, applied immediately (switches) or on choice (selects). - Don’t use it for a single setting or a quick choice; use a
Popover,MenuorDialog. - Don’t put destructive actions next to everyday options; give them their own section and confirm with
ConfirmDialog.
Installation
Install the package (React 19):
terminal
terminal
terminal
Import the styles once, in your app entry or root layout:
/src/main.tsx
Use it anywhere inside your app's <Theme> (see Installation):
/src/SettingsModalExample.tsx
Examples
As a modal
Rows
Notifications
Mobile push notifications
Receive push notifications on mentions and comments
Email digests
Updates from pages you follow
Composition
anatomy
API Reference
SettingsModal
| Prop | Type | Default |
|---|---|---|
open | boolean | |
onOpenChange | (open: boolean) => void | |
nav | ReactNode | |
children | ReactNode | |
title | string | "Settings & members" |
SettingsLayout
Based on <div>. The modal’s two columns without the dialog.
| Prop | Type | Default |
|---|---|---|
nav | ReactNode | |
children | ReactNode |
SettingsNav
Based on <div>.
| Prop | Type | Default |
|---|---|---|
search | boolean | true |
searchProps | InputHTMLAttributes<HTMLInputElement> | |
footer | ReactNode |
SettingsNavGroup
Based on <div>.
| Prop | Type | Default |
|---|---|---|
label | ReactNode |
SettingsNavItem
Based on <button role="tab">.
| Prop | Type | Default |
|---|---|---|
icon | IconName | ReactElement | |
selected | boolean | false |
badge | ReactNode | |
tone | "default""accent" | "default" |
SettingsBadge
| Prop | Type | Default |
|---|---|---|
tone | "gray""blue" | "gray" |
children | ReactNode |
SettingsPage
Based on <div> (except title).
| Prop | Type | Default |
|---|---|---|
title | ReactNode | |
description | ReactNode |
SettingsSection
Based on <section> (except title).
| Prop | Type | Default |
|---|---|---|
title | ReactNode |
SettingsRow
Based on <div> (except title).
| Prop | Type | Default |
|---|---|---|
label | ReactNode | |
description | ReactNode | |
badge | ReactNode | |
control | ReactNode |
SettingsSelect
Based on <button>: 28px outline select button with a chevron.
| Prop | Type | Default |
|---|---|---|
...props | ButtonHTMLAttributes<HTMLButtonElement> |
SettingsSwitch
Alias of the Switch atom (30x18). Inside a SettingsRow it is named by the row label.
| Prop | Type | Default |
|---|---|---|
label | ReactNode | |
invalid | boolean | false |
...props | SwitchProps |
Accessibility
- Radix Dialog: focus trapped inside, Escape and the underlay close it, focus returns to the trigger; the title ("Settings & members") is visually hidden but announced.
- The nav is a vertical
tablistlabelled "Settings" (↑/↓, Home/End move focus);SettingsNavItems arerole="tab"witharia-selected. - The search field is labelled "Search settings". Each
SettingsRownames its control with the row label and describes it with the description (unless the control has its own label);SettingsSwitchtoggles with Space. - The page title is an
h2under the dialog title.
© 2026 Motion. Internal documentation.