Passer au contenu principal

SettingsPanel

Implemented

A settings surface's full anatomy: optional panel title, a stack of titled concerns (rendered through FormSection) and an optional actions footer. Chrome-less composition extracted from the 11 dashboard/portal sites that hand-rolled it.

Categorymolecules
Sourcesrc/components/molecules/SettingsPanel/SettingsPanel.tsx
AI HintUse for any settings/form surface composed of titled concerns plus an action row — the shape EventForm, PackageManager, PassForm, TicketTypeForm, PrivateLinkManager, ProductManager, EventProductAttach, ProductCatalogForm, EventDetail and the portal account/login pages share. Sections render through FormSection (divider rhythm included); gap selects the container rhythm. Ships no copy — all strings are caller-owned.

A settings surface’s full anatomy: an optional panel title, a stack of titled concerns (each rendered through FormSection, so the sibling divider rhythm is automatic), and an optional actions footer. Chrome-less by design — carded looks come from the consumer’s className.

SettingsPanel

Molecule — Form family

Default panel (div, 24px rhythm): three concerns stacked through FormSection. This is the composition the dashboard hand-rolled around FormSection in 11 places.

Profile

Preferences

Applies to every device you sign in from.

Notifications

This component supports light and dark mode.

WithTitleAndFooter

Molecule — Form family

Panel title + footer slot: the account-settings shape. The footer renders after the sections and only contributes the vertical gap — pass a styled action row.

Account settings

Profile

Preferences

Applies to every device you sign in from.

Notifications

This component supports light and dark mode.

AsFieldset

Molecule — Form family

as="fieldset" + disabled: the EventForm save-lock. Toggling disabled disables every contained field without touching each one.

Profile

Preferences

Applies to every device you sign in from.

This component supports light and dark mode.

Props

Prop
Type
Default
Description
title
string
—

Optional panel heading above the section stack; wired as aria-labelledby.

sections*
SettingsPanelSection[]
—

The panel’s concerns — each {title, description?, content, as?, className?} renders as a FormSection; null-content sections are skipped.

footer
React.ReactNode
—

Actions after the section stack. Layout-neutral — bring your own container.

as
"div" | "section" | "fieldset"
div

Root element — "fieldset" preserves the dashboard’s disable-all semantics.

disabled
boolean
—

Forwarded to the root when as="fieldset".

gap
"sm" | "md" | "lg" | "none"
md

Vertical rhythm: md 24px (.um-form), sm 16px (.um-tabpanel), lg 32px (portal), none for margin-managed containers.

className
string
—

Extra classes on the root (e.g. um-tabpanel for the carded look).

id
string
—

Root id — the panel title is wired as aria-labelledby.

Props

Preview

SettingsPanel

Prop
Type
Required
Default
Description
title
string
Optional
—

Optional panel heading above the section stack; wired as aria-labelledby

sections
SettingsPanelSection[]
Required
—

The panel's concerns — each {title, description?, content, as?, className?} renders as a FormSection; null-content sections are skipped. Named SettingsPanelSection so it cannot collide with the SettingsLayout template's SettingsSection

footer
React.ReactNode
Optional
—

Actions after the section stack (Save/Cancel row). Layout-neutral — bring your own container

as
'div' | 'section' | 'fieldset'
Optional
'div'

Root element — 'fieldset' preserves the dashboard's disable-all semantics

disabled
boolean
Optional
—

Forwarded to the root when as='fieldset' — disables every contained field

gap
'sm' | 'md' | 'lg' | 'none'
Optional
'md'

Vertical rhythm between title/sections/footer — md 24px (.um-form), sm 16px (.um-tabpanel), lg 32px (portal), none for margin-managed containers

className
string
Optional
—

Extra classes on the root (e.g. um-tabpanel for the carded look)

id
string
Optional
—

Root id — the panel title is wired as aria-labelledby

Quick use:<SettingsPanel />

Accessibility

ARIA rolegroup (when as='fieldset')

Type

1 rule

NASA Rule 5

renders zero chrome of its own — a bare flex column; carded looks come from the consumer's className so migration changes no pixels

ARIA

1 rule

WCAG 1.3.1

as='fieldset' exposes the implicit group role and forwards disabled so a whole settings surface can be locked during a save

Usage

Import

tsxSnippet
import { SettingsPanel } from "@epasslive/design-system"

Example 1

tsxSnippet
<SettingsPanel as="fieldset" disabled={saving} className="um-tabpanel" gap="sm" sections={[{title: t("sections.general"), content: <ResponsiveFieldGroup>…</ResponsiveFieldGroup>}, …]} />

Example 2

tsxSnippet
<SettingsPanel gap="md" sections={sections} footer={<div className="um-form-actions"><Button>Save</Button></div>} />

Anti-patterns

— Do not wrap it in a second sectioning container for spacing — the panel is the container

— Do not hand-roll the action row inside a section's content — use the footer slot

— Do not add card chrome here — pass the carded className (um-tabpanel today) so the dashboard look stays caller-owned

Design System v4.1.0 | ePassLive