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 per SettingsRow, applied immediately (switches) or on choice (selects).
  • Don’t use it for a single setting or a quick choice; use a Popover, Menu or Dialog.
  • 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
npm install @krackedui/motion

Import the styles once, in your app entry or root layout:

/src/main.tsx
import '@krackedui/motion/styles.css';

Use it anywhere inside your app's <Theme> (see Installation):

/src/SettingsModalExample.tsx
import { SettingsLayout, Avatar, Icon, SettingsBadge, SettingsNav, SettingsNavGroup, SettingsNavItem, SettingsPage, SettingsRow, SettingsSection, SettingsSelect, SettingsSwitch } from '@krackedui/motion';

export function SettingsModalExample() {
  // The dialog's two-column layout, embedded without the modal:

  return (
    <SettingsLayout
      nav={
        <SettingsNav footer={null}>
          <SettingsNavGroup label="Account">
            <SettingsNavItem icon={<Avatar name="Ada Lovelace" shape="user" />}>Ada Lovelace</SettingsNavItem>
            <SettingsNavItem icon="sliders" selected>Preferences</SettingsNavItem>
            <SettingsNavItem icon="bell">Notifications</SettingsNavItem>
          </SettingsNavGroup>
          <SettingsNavGroup label="Workspace">
            <SettingsNavItem icon="gear">General</SettingsNavItem>
            <SettingsNavItem icon="people">People</SettingsNavItem>
            <SettingsNavItem icon="paperMicrophone" badge={<SettingsBadge tone="blue">New</SettingsBadge>}>Meeting notes</SettingsNavItem>
          </SettingsNavGroup>
          <SettingsNavGroup label="Access & billing">
            <SettingsNavItem icon={<Icon name="arrowInCircleUpFill" size={18} />} tone="accent">Upgrade plan</SettingsNavItem>
          </SettingsNavGroup>
        </SettingsNav>
      }
    >
      <SettingsPage title="Preferences" description="Choose how you want Motion to look and behave.">
        <SettingsSection title="Appearance">
          <SettingsRow label="Theme" description="Choose a theme for Motion on this device" control={<SettingsSelect>Light</SettingsSelect>} />
          <SettingsRow label="High contrast" badge={<SettingsBadge>Beta</SettingsBadge>} description="Increase contrast for improved visibility" control={<SettingsSelect>Use system setting</SettingsSelect>} />
        </SettingsSection>
        <SettingsSection title="Input options">
          <SettingsRow label="Use Enter to add a new line" description="Press Cmd+Enter to send messages" control={<SettingsSwitch />} />
        </SettingsSection>
      </SettingsPage>
    </SettingsLayout>
  );
}

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
<SettingsModal open onOpenChange nav>          // Radix Dialog; full-screen on phones (nav stacked above content)
  <SettingsLayout>                               // also usable on its own
    nav      → <SettingsNav search footer>
                 <SettingsNavGroup label> <SettingsNavItem icon selected badge tone/> × n </SettingsNavGroup>
               </SettingsNav>
    content  → <SettingsPage title description>
                 <SettingsSection title>
                   <SettingsRow label description badge control={<SettingsSelect/> | <SettingsSwitch/>}/>
                 </SettingsSection>
               </SettingsPage>
  close (×)
</SettingsModal>

API Reference

SettingsModal

PropTypeDefault
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.

PropTypeDefault
nav
ReactNode
children
ReactNode

SettingsNav

Based on <div>.

PropTypeDefault
search
boolean
true
searchProps
InputHTMLAttributes<HTMLInputElement>
footer
ReactNode

SettingsNavGroup

Based on <div>.

PropTypeDefault
label
ReactNode

SettingsNavItem

Based on <button role="tab">.

PropTypeDefault
icon
IconName | ReactElement
selected
boolean
false
badge
ReactNode
tone
"default""accent"
"default"

SettingsBadge

PropTypeDefault
tone
"gray""blue"
"gray"
children
ReactNode

SettingsPage

Based on <div> (except title).

PropTypeDefault
title
ReactNode
description
ReactNode

SettingsSection

Based on <section> (except title).

PropTypeDefault
title
ReactNode

SettingsRow

Based on <div> (except title).

PropTypeDefault
label
ReactNode
description
ReactNode
badge
ReactNode
control
ReactNode

SettingsSelect

Based on <button>: 28px outline select button with a chevron.

PropTypeDefault
...props
ButtonHTMLAttributes<HTMLButtonElement>

SettingsSwitch

Alias of the Switch atom (30x18). Inside a SettingsRow it is named by the row label.

PropTypeDefault
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 tablist labelled "Settings" (↑/↓, Home/End move focus); SettingsNavItems are role="tab" with aria-selected.
  • The search field is labelled "Search settings". Each SettingsRow names its control with the row label and describes it with the description (unless the control has its own label); SettingsSwitch toggles with Space.
  • The page title is an h2 under the dialog title.
© 2026 Motion. Internal documentation.