Template · Settings workflow
Settings Page
Organize preferences into readable sections while your application owns values, validation, and persistence.
Live playground
Preferences
Choose how this workspace looks, notifies you, and behaves on this device.
Appearance
Keep display preferences local to the person and device that chose them.
Match the operating system light or dark appearance.
Prefer transitions that do not rely on large movement.
Notifications
Product code owns delivery channels, persistence, and permission prompts.
Receive occasional notes about meaningful changes.
Activity summaries
Bundle lower-priority activity into a concise summary.
Compose sections from stable parts
SettingsSection owns the semantic section, heading, and optional description. It does not own fields or saved values.
SettingsGroup is the Surface-backed rows container. SettingsSection.Group is the same implementation, not a second component.
- Use SettingsRow for each label, description, and control relationship.
Keep settings behavior in the application
- The application owns routing, validation, persistence, permission prompts, and saves.
- Associate every switch or unnamed control with its visible SettingsRow.Label.
Keep one h1 for the page and h2 headings for sections. Use a visible SettingsRow.Label for controls; an action row may use the h3 SettingsRow.Title.
Implementation
Install the Recipe as editable source, then connect each control to application-owned values and persistence.
import { SettingsRow } from "@lenso/ui/settings-row";
import { Switch } from "@lenso/ui/switch";
import { SettingsGroup, SettingsSection } from "@/components/lenso/recipes/settings-section";
export function AppearanceSettings() {
return (
<SettingsSection.Root aria-labelledby="appearance-title">
<SettingsSection.Header>
<SettingsSection.Title id="appearance-title">Appearance</SettingsSection.Title>
<SettingsSection.Description>
Choose how the application looks on this device.
</SettingsSection.Description>
</SettingsSection.Header>
<SettingsGroup>
<SettingsRow.Root>
<SettingsRow.Copy>
<SettingsRow.Label>Follow system theme</SettingsRow.Label>
<SettingsRow.Description>
Match the operating system appearance.
</SettingsRow.Description>
</SettingsRow.Copy>
<SettingsRow.Control>
{({ controlId, disabled, labelId, visualState }) => (
<Switch.Root
aria-labelledby={labelId}
data-visual-state={visualState}
disabled={disabled}
id={controlId}
layout="control-only"
>
<Switch.Thumb />
</Switch.Root>
)}
</SettingsRow.Control>
</SettingsRow.Root>
</SettingsGroup>
</SettingsSection.Root>
);
}