# Settings list
> Generated from settings-list.contract.json — do not edit by hand.

A schema-driven group of settings rows — semibold label left (with a "?" help tooltip), control right — reusing existing DS controls.

Tier: **leaf-lit**. Frameworks: HTML (paste-and-run, no build step) · React · Vue 3.

Surfaces: editor, settings, dashboard.

## Props
| Prop | Type | Default | Notes |
| --- | --- | --- | --- |
| `schema` | object | `—` | (list, property) Settings schema { sections:[{ label, rows:[{ key, label, description?, layout?, consequence?, control }] }] } — an array is treated as one section's rows; renders rows and reuses DS controls. Also settable as a JSON `schema` attribute for the build-free HTML form A row may declare visible_if (structured `visibleIf:{key,equals?,in?,not?}` or the Shopify string `visible_if:"{{ settings.<key> }}"`) — the row is shown only when its trigger is on and hidden when off, rendered nested (indented, de-emphasised). |
| `label` | string | `—` | Group header (a 1–3 word noun phrase); on <aha-settings-item> it is the setting name. Ignored when a schema supplies section labels |
| `description` | string | `—` | (item / schema row) Guidance text — rendered as the "?" HELP TOOLTIP after the label (DS <aha-tooltip help>), NOT a standing line. Default: no help glyph |
| `consequence` | string | `—` | (item / schema row) RARE opt-in must-see-consequence line shown as a standing line under the label (e.g. 'This cannot be undone.') — default none |
| `layout` | 'inline' | 'stack' | `inline` | (item / schema row) inline = label left / control right (align-items:center, space-between, gap 12); stack = label above / control full-width (column, gap 8) for wide controls (textarea / wide select) |
| `control` | slot | schema | `—` | (item) The DS control on the right — <aha-switch>, <aha-checkbox>, <aha-input>… slotted by hand, or named in a schema row's `control:{ type }` and instantiated for you |
| `density` | 'default' | 'compact' | `default` | (list) Row/group rhythm. compact tightens the spacing (16 between groups, 8 between siblings) — never adds lines or boxes |
| `disabled` | boolean | `false` | (item / schema row) Dims the label to text-disabled, disables the reused control, sets aria-disabled |
| `locked` | boolean | `false` | (schema row) Plan-gates the row: stays visible, its control becomes the shared Paywall crown badge → upsell. Pair with `plan` ('essential'|'pro') and `feature` (the upsell label) |

## Visual standard (measured)
- Group: column · 16px between sibling settings · 32px between groups · semibold (600) header (SectionHeader); member/row labels are ALSO semibold (600) per the reference SettingRow
- Row (inline, default): label left, control right · align-items:center · justify-content:space-between · min-height 24 · 12px gap
- Row (stack): layout=stack → label above, control full-width (flex-direction:column · 8px gap) — for wide controls (textarea / wide select)
- Label: 14/21 Semibold (600) #1A1A1A (name = noun phrase, no leading verb)
- Help: guidance = a "?" help trigger after the label (DS <aha-tooltip help>, icon system-question-mark, muted ~50% = text-tertiary #8A8A8A → brand on hover/focus) + tooltip; NO standing description line. `description` is the tooltip content
- Consequence (rare): opt-in `consequence` → a standing must-see line 12/18 #8A8A8A under the label; default none
- Disabled row: row disabled → label dims to text-disabled #B5B5B5, control disabled, aria-disabled
- Plan-gated row: row locked → visible but the control is the shared Paywall crown (opens the upsell), never hidden
- Density: density=compact tightens the rhythm (16 between groups, 8 between siblings) — spacing, never lines
- Structure: no divider lines, no card/box around plain settings
- Schema: sections[] → rows[] { key, label, description?, layout?, consequence?, disabled?, locked?, plan?, feature?, control:{ type, …props } }; renders + reuses DS controls
- visible_if: a follow-up row shown only when its trigger is on (Shopify model) — nested (24 indent, tighter gap, de-emphasised label); hidden = display:none, no phantom gap (SETTINGS-19/07/14)

## When to use
- **Settings list** — a group of related on/off or choice settings in a panel, page or drawer
- **Form** — values are submitted together with validation and a submit step
- **a single Switch/Select** — one setting that applies on its own

Name each setting as a noun phrase (no leading verb — the control says on/off). Use a toggle for immediate effect, a checkbox for consent/saved-together — never mix in one group. Guidance lives in the "?" help tooltip after the label — never a standing description line (reserve the rare `consequence` line for a genuine must-see, e.g. an irreversible action). Hierarchy is spacing, never lines or boxes. Use `layout:'stack'` for wide controls (textarea / wide select). See the settings pattern for grouping, sub-settings and the danger zone.
