# Settings panel

A column of settings beside what they change: a choice at the top, groups that open and close, and a footer to count and reset changes.

A block: a ready-made arrangement of components, to copy into a project. Its own classes carry the `site-` prefix; rename it to your project's own. Status: experimental. Figma: the Figma file, https://www.figma.com/community/file/1688324308358870630. Built from: Card, Button, Icon, Segmented control, Accordion, Field, Label, Input, Divider, Link.

## Examples

### Usage

Which theme the settings change, then two groups of them, the first open, and a footer that counts the changes and resets them.

```html
<article
  class="smbk-card smbk-card--surface-outline smbk-card--layout-panel site-settings-panel"
  aria-label="Settings"
>
  <div class="smbk-card__content">
    <header class="smbk-card__header smbk-card__header--type-title smbk-card__header--size-sm">
      <div class="smbk-card__header-text">
        <div class="smbk-card__title-row">
          <h3 class="smbk-card__title">Settings</h3>
        </div>
      </div>
      <div class="smbk-card__trailing">
        <button
          type="button"
          class="smbk-btn smbk-btn--tone-ghost smbk-btn--size-sm smbk-btn--icon-only"
          aria-label="More settings"
        >
          <i
            class="ph ph-dots-three smbk-icon smbk-icon--size-md smbk-btn__icon"
            aria-hidden="true"
          ></i>
        </button>
      </div>
    </header>
    <div class="smbk-card__body smbk-card__body--type-slot">
      <div
        role="radiogroup"
        aria-label="Theme to edit"
        class="smbk-segmented smbk-segmented--size-sm smbk-segmented--item-width-equal smbk-segmented--content-label smbk-segmented--look-standard"
      >
        <span class="smbk-segmented__indicator" aria-hidden="true"></span>
        <label class="smbk-segmented__item">
          <input type="radio" class="smbk-segmented__control" name="settings-theme" value="light"/>
          <span class="smbk-segmented__label">Light</span>
        </label>
        <label class="smbk-segmented__item">
          <input
            type="radio"
            class="smbk-segmented__control"
            name="settings-theme"
            checked=""
            value="dark"
          >
          <span class="smbk-segmented__label">Dark</span>
        </label>
      </div>
      <div class="smbk-accordion smbk-accordion--look-flat smbk-accordion--size-sm site-settings-panel__groups">
        <details class="smbk-accordion__item" open="" name="settings-panel-1">
          <summary class="smbk-accordion__summary">
            <span class="smbk-accordion__title">Starting colors</span>
            <i
              class="ph ph-caret-down smbk-icon smbk-icon--size-md smbk-accordion__caret"
              aria-hidden="true"
            ></i>
          </summary>
          <div class="smbk-accordion__content">
            <div class="site-settings-panel__group">
              <p class="site-settings-panel__hint">The colors every other one is worked out from.</p>
              <div class="smbk-field smbk-field--layout-side-by-side">
                <label
                  class="smbk-label smbk-label--tone-subtle smbk-label--type-default smbk-field__label"
                  id="fieldsettings-panel-2-label"
                  for="fieldsettings-panel-2"
                >
                  <span class="smbk-label__text">Brand</span>
                  <span class="smbk-label__required" aria-hidden="true">*</span>
                </label>
                <span class="smbk-input smbk-input--size-sm">
                  <input
                    class="smbk-input__control"
                    id="fieldsettings-panel-2"
                    aria-labelledby="fieldsettings-panel-2-label"
                    required=""
                    value="Coral red"
                  >
                </span>
              </div>
              <div class="smbk-field smbk-field--layout-side-by-side">
                <label
                  class="smbk-label smbk-label--tone-subtle smbk-label--type-default smbk-field__label"
                  id="fieldsettings-panel-3-label"
                  for="fieldsettings-panel-3"
                >
                  <span class="smbk-label__text">Accent</span>
                  <span class="smbk-label__required" aria-hidden="true">*</span>
                </label>
                <span class="smbk-input smbk-input--size-sm">
                  <input
                    class="smbk-input__control"
                    id="fieldsettings-panel-3"
                    aria-labelledby="fieldsettings-panel-3-label"
                    required=""
                    value="Indigo"
                  >
                </span>
              </div>
            </div>
          </div>
        </details>
        <hr
          class="smbk-divider smbk-divider--orientation-horizontal smbk-accordion__divider"
          aria-hidden="true"
        >
        <details class="smbk-accordion__item" name="settings-panel-1">
          <summary class="smbk-accordion__summary">
            <span class="smbk-accordion__title">Action colors</span>
            <i
              class="ph ph-caret-down smbk-icon smbk-icon--size-md smbk-accordion__caret"
              aria-hidden="true"
            ></i>
          </summary>
          <div class="smbk-accordion__content">
            <div class="site-settings-panel__group">
              <p class="site-settings-panel__hint">The colors of buttons and links as they are pressed.</p>
              <div class="smbk-field smbk-field--layout-side-by-side">
                <label
                  class="smbk-label smbk-label--tone-subtle smbk-label--type-default smbk-field__label"
                  id="fieldsettings-panel-4-label"
                  for="fieldsettings-panel-4"
                >
                  <span class="smbk-label__text">Hover</span>
                </label>
                <span class="smbk-input smbk-input--size-sm">
                  <input
                    class="smbk-input__control"
                    id="fieldsettings-panel-4"
                    aria-labelledby="fieldsettings-panel-4-label"
                    value="Darker by 8%"
                  >
                </span>
              </div>
              <div class="smbk-field smbk-field--layout-side-by-side">
                <label
                  class="smbk-label smbk-label--tone-subtle smbk-label--type-default smbk-field__label"
                  id="fieldsettings-panel-5-label"
                  for="fieldsettings-panel-5"
                >
                  <span class="smbk-label__text">Pressed</span>
                </label>
                <span class="smbk-input smbk-input--size-sm">
                  <input
                    class="smbk-input__control"
                    id="fieldsettings-panel-5"
                    aria-labelledby="fieldsettings-panel-5-label"
                    value="Darker by 16%"
                  >
                </span>
              </div>
            </div>
          </div>
        </details>
        <hr
          class="smbk-divider smbk-divider--orientation-horizontal smbk-accordion__divider"
          aria-hidden="true"
        >
      </div>
    </div>
    <hr class="smbk-divider smbk-divider--orientation-horizontal smbk-card__divider"/>
    <footer class="smbk-card__footer smbk-card__footer--type-link-and-actions">
      <div class="smbk-card__footer-row">
        <div class="smbk-card__footer-start">
          <a
            class="smbk-link smbk-link--size-md smbk-link--standalone"
            href="#changes"
          ><span class="smbk-link__label">3 changes on color</span></a>
        </div>
        <div class="smbk-card__footer-end">
          <button type="button" class="smbk-btn smbk-btn--tone-ghost smbk-btn--size-sm">
            <span class="smbk-btn__label">Reset color</span>
          </button>
        </div>
      </div>
    </footer>
  </div>
</article>
```

```tsx
import { Card, CardHeader, CardFooter, CardBody } from './design-system/components/card/card.js';
import { Button } from './design-system/components/button/button.js';
import { Link } from './design-system/components/link/link.js';
import { SegmentedControl } from './design-system/components/segmented-control/segmented-control.js';
import { Accordion } from './design-system/components/accordion/accordion.js';
import { Field } from './design-system/components/field/field.js';
import { Input } from './design-system/components/input/input.js';

<Card surface="outline" layout="panel" className="site-settings-panel" aria-label="Settings" header={<CardHeader size="sm" title="Settings" menu={<Button tone="ghost" size="sm" icon-only icon="DotsThree" aria-label="More settings" />} />} footer={<CardFooter type="link-and-actions" start={<Link href="#changes" size="md" standalone>3 changes on color</Link>} end={<Button tone="ghost" size="sm">Reset color</Button>} />}>
  <CardBody type="slot">
    <SegmentedControl size="sm" name="settings-theme" label="Theme to edit" defaultValue="dark" options={[{ value: "light", label: "Light" }, { value: "dark", label: "Dark" }]} />
    <Accordion look="flat" size="sm" className="site-settings-panel__groups" items={[{ title: "Starting colors", open: true, children: <div className="site-settings-panel__group">
  <p className="site-settings-panel__hint">The colors every other one is worked out from.</p>
  <Field label="Brand" required layout="side-by-side">
    <Input size="sm" defaultValue="Coral red" />
  </Field>
  <Field label="Accent" required layout="side-by-side">
    <Input size="sm" defaultValue="Indigo" />
  </Field>
</div> }, { title: "Action colors", children: <div className="site-settings-panel__group">
  <p className="site-settings-panel__hint">The colors of buttons and links as they are pressed.</p>
  <Field label="Hover" layout="side-by-side">
    <Input size="sm" defaultValue="Darker by 8%" />
  </Field>
  <Field label="Pressed" layout="side-by-side">
    <Input size="sm" defaultValue="Darker by 16%" />
  </Field>
</div> }]} />
  </CardBody>
</Card>
```

### Three groups

Three groups of a page's settings, the first open. Nothing has changed yet, so the reset button is off.

```html
<article
  class="smbk-card smbk-card--surface-outline smbk-card--layout-panel site-settings-panel"
  aria-label="Page settings"
>
  <div class="smbk-card__content">
    <header class="smbk-card__header smbk-card__header--type-title smbk-card__header--size-sm">
      <div class="smbk-card__header-text">
        <div class="smbk-card__title-row">
          <h3 class="smbk-card__title">Page settings</h3>
        </div>
      </div>
      <div class="smbk-card__trailing">
        <button
          type="button"
          class="smbk-btn smbk-btn--tone-ghost smbk-btn--size-sm smbk-btn--icon-only"
          aria-label="More page settings"
        >
          <i
            class="ph ph-dots-three smbk-icon smbk-icon--size-md smbk-btn__icon"
            aria-hidden="true"
          ></i>
        </button>
      </div>
    </header>
    <div class="smbk-card__body smbk-card__body--type-slot">
      <div
        role="radiogroup"
        aria-label="Device to edit"
        class="smbk-segmented smbk-segmented--size-sm smbk-segmented--item-width-equal smbk-segmented--content-label smbk-segmented--look-standard"
      >
        <span class="smbk-segmented__indicator" aria-hidden="true"></span>
        <label class="smbk-segmented__item">
          <input
            type="radio"
            class="smbk-segmented__control"
            name="settings-device"
            checked=""
            value="desktop"
          >
          <span class="smbk-segmented__label">Desktop</span>
        </label>
        <label class="smbk-segmented__item">
          <input type="radio" class="smbk-segmented__control" name="settings-device" value="phone"/>
          <span class="smbk-segmented__label">Phone</span>
        </label>
      </div>
      <div class="smbk-accordion smbk-accordion--look-flat smbk-accordion--size-sm site-settings-panel__groups">
        <details class="smbk-accordion__item" open="" name="settings-panel-1">
          <summary class="smbk-accordion__summary">
            <span class="smbk-accordion__title">Layout</span>
            <i
              class="ph ph-caret-down smbk-icon smbk-icon--size-md smbk-accordion__caret"
              aria-hidden="true"
            ></i>
          </summary>
          <div class="smbk-accordion__content">
            <div class="site-settings-panel__group">
              <div class="smbk-field smbk-field--layout-side-by-side">
                <label
                  class="smbk-label smbk-label--tone-subtle smbk-label--type-default smbk-field__label"
                  id="fieldsettings-panel-2-label"
                  for="fieldsettings-panel-2"
                >
                  <span class="smbk-label__text">Columns</span>
                </label>
                <span class="smbk-input smbk-input--size-sm">
                  <input
                    class="smbk-input__control"
                    id="fieldsettings-panel-2"
                    aria-labelledby="fieldsettings-panel-2-label"
                    value="3"
                  >
                </span>
              </div>
              <div class="smbk-field smbk-field--layout-side-by-side">
                <label
                  class="smbk-label smbk-label--tone-subtle smbk-label--type-default smbk-field__label"
                  id="fieldsettings-panel-3-label"
                  for="fieldsettings-panel-3"
                >
                  <span class="smbk-label__text">Gap</span>
                </label>
                <span class="smbk-input smbk-input--size-sm">
                  <input
                    class="smbk-input__control"
                    id="fieldsettings-panel-3"
                    aria-labelledby="fieldsettings-panel-3-label"
                    value="Medium"
                  >
                </span>
              </div>
            </div>
          </div>
        </details>
        <hr
          class="smbk-divider smbk-divider--orientation-horizontal smbk-accordion__divider"
          aria-hidden="true"
        >
        <details class="smbk-accordion__item" name="settings-panel-1">
          <summary class="smbk-accordion__summary">
            <span class="smbk-accordion__title">Header</span>
            <i
              class="ph ph-caret-down smbk-icon smbk-icon--size-md smbk-accordion__caret"
              aria-hidden="true"
            ></i>
          </summary>
          <div class="smbk-accordion__content">
            <div class="site-settings-panel__group">
              <div class="smbk-field smbk-field--layout-side-by-side">
                <label
                  class="smbk-label smbk-label--tone-subtle smbk-label--type-default smbk-field__label"
                  id="fieldsettings-panel-4-label"
                  for="fieldsettings-panel-4"
                >
                  <span class="smbk-label__text">Title</span>
                </label>
                <span class="smbk-input smbk-input--size-sm">
                  <input
                    class="smbk-input__control"
                    id="fieldsettings-panel-4"
                    aria-labelledby="fieldsettings-panel-4-label"
                    value="Our work"
                  >
                </span>
              </div>
            </div>
          </div>
        </details>
        <hr
          class="smbk-divider smbk-divider--orientation-horizontal smbk-accordion__divider"
          aria-hidden="true"
        >
        <details class="smbk-accordion__item" name="settings-panel-1">
          <summary class="smbk-accordion__summary">
            <span class="smbk-accordion__title">Search engines</span>
            <i
              class="ph ph-caret-down smbk-icon smbk-icon--size-md smbk-accordion__caret"
              aria-hidden="true"
            ></i>
          </summary>
          <div class="smbk-accordion__content">
            <div class="site-settings-panel__group">
              <div class="smbk-field smbk-field--layout-side-by-side">
                <label
                  class="smbk-label smbk-label--tone-subtle smbk-label--type-default smbk-field__label"
                  id="fieldsettings-panel-5-label"
                  for="fieldsettings-panel-5"
                >
                  <span class="smbk-label__text">Description</span>
                </label>
                <span class="smbk-input smbk-input--size-sm">
                  <input
                    class="smbk-input__control"
                    id="fieldsettings-panel-5"
                    aria-labelledby="fieldsettings-panel-5-label"
                    value="Projects from the last year"
                  >
                </span>
              </div>
            </div>
          </div>
        </details>
        <hr
          class="smbk-divider smbk-divider--orientation-horizontal smbk-accordion__divider"
          aria-hidden="true"
        >
      </div>
    </div>
    <hr class="smbk-divider smbk-divider--orientation-horizontal smbk-card__divider"/>
    <footer class="smbk-card__footer smbk-card__footer--type-link-and-actions">
      <div class="smbk-card__footer-row">
        <div class="smbk-card__footer-start">No changes yet</div>
        <div class="smbk-card__footer-end">
          <button
            type="button"
            class="smbk-btn smbk-btn--tone-ghost smbk-btn--size-sm"
            aria-disabled="true"
          >
            <span class="smbk-btn__label">Reset page</span>
          </button>
        </div>
      </div>
    </footer>
  </div>
</article>
```

```tsx
import { Card, CardHeader, CardFooter, CardBody } from './design-system/components/card/card.js';
import { Button } from './design-system/components/button/button.js';
import { SegmentedControl } from './design-system/components/segmented-control/segmented-control.js';
import { Accordion } from './design-system/components/accordion/accordion.js';
import { Field } from './design-system/components/field/field.js';
import { Input } from './design-system/components/input/input.js';

<Card surface="outline" layout="panel" className="site-settings-panel" aria-label="Page settings" header={<CardHeader size="sm" title="Page settings" menu={<Button tone="ghost" size="sm" icon-only icon="DotsThree" aria-label="More page settings" />} />} footer={<CardFooter type="link-and-actions" start="No changes yet" end={<Button tone="ghost" size="sm" aria-disabled="true">Reset page</Button>} />}>
  <CardBody type="slot">
    <SegmentedControl size="sm" name="settings-device" label="Device to edit" defaultValue="desktop" options={[{ value: "desktop", label: "Desktop" }, { value: "phone", label: "Phone" }]} />
    <Accordion look="flat" size="sm" className="site-settings-panel__groups" items={[{ title: "Layout", open: true, children: <div className="site-settings-panel__group">
  <Field label="Columns" layout="side-by-side">
    <Input size="sm" defaultValue="3" />
  </Field>
  <Field label="Gap" layout="side-by-side">
    <Input size="sm" defaultValue="Medium" />
  </Field>
</div> }, { title: "Header", children: <div className="site-settings-panel__group">
  <Field label="Title" layout="side-by-side">
    <Input size="sm" defaultValue="Our work" />
  </Field>
</div> }, { title: "Search engines", children: <div className="site-settings-panel__group">
  <Field label="Description" layout="side-by-side">
    <Input size="sm" defaultValue="Projects from the last year" />
  </Field>
</div> }]} />
  </CardBody>
</Card>
```

## Purpose

Holds the settings of what sits beside it, such as a theme, a page or a chart: which version the settings change, the settings in groups that open and close, and a footer that says how many have changed and resets them.

## Anatomy

- The panel, the Card component in its outline surface and panel layout: the header on a band, the body padded, the divider over the footer.
- The header: the panel's title in the small header size, and a menu button at its end.
- The choice, the Segmented control component at its small size: which version the settings below change, such as light or dark.
- The groups, the Accordion component, flat and small: each a title that opens and closes, and inside it a line saying what the group is for and its settings. The line after the last group is hidden, since the panel's divider already runs there.
- Each setting, the Field component side by side, its label beside a small Input.
- The footer, the card's link and actions kind: a link to the changes, and a quiet button that resets them.

## When to use

- In a column beside a canvas, a preview or a page, where each change shows at once.

## When not to use

- For a long form a reader fills in once. Use a page of fields with one button to send them.
- For two or three settings. Use a popover from the thing they change.

## Behavior

Each group opens and closes on its own. Settings change what they set as they are edited, so the panel has no button to send them; the footer counts what changed and resets it. With nothing changed, the reset button is off.

## Accessibility

### What it does for you

- The choice is a radio group, moved through with the arrow keys.
- Each group's title is a button that says whether it is open.
- Every setting keeps its label; a required one says so.

### What you must do

- Name the panel by its title, and make its title a heading at the level the page needs.
- Name the choice for what it chooses, such as "Theme to edit".
- Name the menu button for what it holds, such as "More settings".

### How to test

- Tab to the choice and move it with the arrow keys; Tab to a group's title and open or close it with Enter or Space.
- With a screen reader, the choice is read by its name, each group's title as a button that says whether it is open, and each setting by its label, a required one as required.

### Keyboard

| Key | What it does |
|---|---|
| Tab | Moves focus through the choice, each group's title, the settings of the open groups and the footer. |
| Down Arrow or Right Arrow | In the choice, moves the choice to the next item. |
| Up Arrow or Left Arrow | In the choice, moves the choice to the previous item. |
| Enter or Space | On a group's title, opens the group, or closes it when it is open. |

## Usage rules

### Do

- Open the group a reader needs first.
- Say in each group's first line what its settings change.

### Don't

- Put a button to save in the footer: every change already shows.
- Nest a group inside another.

## Stylesheet

```css
/* site-settings-panel — Settings panel, a block: a column of settings beside what they change, its choice at the
 * top, its groups that open and close, and a footer that counts the changes and resets them. Copy it into your
 * project and rename site- to your project's own prefix. The frame is the Card component, outline surface, in its
 * panel layout; the segmented control, accordion, fields and inputs are the system's own. The block draws only the
 * room inside a group, and hides the line after the last group, where the panel's own divider already runs. */

.site-settings-panel__group {
  display: flex;
  flex-direction: column;
  gap: var(--smbk-space-stack-md);
}

.site-settings-panel__hint {
  margin: 0;
}

/* The flat accordion ends every group with a divider; the last one would double the line over the footer. */
.site-settings-panel__groups > :last-child:not(details) {
  display: none;
}
```
