SettingsCard
Vercel-style settings card with a per-card save action. Each card
represents a cohesive group of related settings; pair rows inside it
with SettingsRow for the standard label/description/control layout.
Usage
import { SettingsCard, settingsCardAnatomy, SettingsCardProps, SettingsRow, SettingsRowProps } from "@desk/ui/components/settings-card";Best practices
Fill it with
SettingsRowchildren for the standard label/description/control layout; useSettingsCardfor grouped form settings, notCard, when you want the built-in per-card save footer.The footer only renders when
onSaveis passed, and the Save button is gated ondirty(and disabled whileloading) — wire form dirty state through, or the button stays disabled.Give each card one cohesive group of settings with its own save; don't nest multiple
SettingsCards or share one across unrelated sections.
Props
SettingsCard
| Prop | Type | Default | Description |
|---|---|---|---|
| children | React.ReactNode | Row content — typically SettingsRow / Field compositions. | |
| description | string | Subheading shown under the title. | |
| dirty | boolean | Whether the form has unsaved changes. Gates the save button. | |
| loading | boolean | Whether a save is in flight. Disables and animates the save button. | |
| onSave | () => void | Called when the save button is pressed. Omit to render no footer. | |
| saveLabel | string | Save button label. Defaults to "Save". | |
| title | string | Card title. | |
| border | BorderStyle | ||
| shadow | boolean | Whether the card casts a shadow. Defaults to true (each variant's own shadow). Set to false for flat cards on a shaded canvas — e.g. several cards stacked on a muted-background page/panel, where the color contrast alone separates them and a shadow on every one would be redundant. | |
| testId | string | ||
| variant | "muted" | "ghost" | "accent" | "card" | null | undefined |
SettingsRow
| Prop | Type | Default | Description |
|---|---|---|---|
| children | React.ReactNode | Row control(s) — inputs, selects, switches, and their FieldError. | |
| description | React.ReactNode | Helper text shown below the control. | |
| htmlFor | string | Associates the label with the control's id for a11y. | |
| id | string | Shared id passed to the underlying Field (drives FieldError/FieldDescription auto-association). | |
| label | React.ReactNode | Row label. | |
| orientation | ResponsiveOrientation | Layout orientation. Defaults to "vertical". |
Also exports
- const
settingsCardAnatomy - interface
SettingsCardProps - interface
SettingsRowProps
Anatomy
SettingsCard
cardSettings section with a per-card save action
CardHeader
card-headerTitle and optional description
CardContent
card-contentStacked SettingsRow (or other) content
SettingsRow
fieldLabel + control row (label/description/children)
CardFooter
card-footerSave button, rendered only when onSave is provided