# Shadow editor

Edits one shadow: a preview card drawn with it, its layers with their offsets, blur, spread, color and opacity, and a button to add a layer.

Block: `smbk-shadow-editor`. Status: experimental. Figma: the Figma file, https://www.figma.com/community/file/1688324308358870630. Desktop and mobile: differ by presentation only.

## Options

| Axis | Values | Default | Meaning |
|---|---|---|---|

Parts: `smbk-shadow-editor__preview`, `smbk-shadow-editor__card`, `smbk-shadow-editor__layers`, `smbk-shadow-editor__layer`, `smbk-shadow-editor__head`, `smbk-shadow-editor__title`, `smbk-shadow-editor__handle`, `smbk-shadow-editor__name`, `smbk-shadow-editor__remove`, `smbk-shadow-editor__fields`, `smbk-shadow-editor__paint`, `smbk-shadow-editor__field`, `smbk-shadow-editor__label`, `smbk-shadow-editor__add`, `smbk-shadow-editor__hidden`

## Markup

```html
<div
  style="--smbk-shadow-editor-shadow:0px 4px 12px -2px rgba(0, 0, 0, 0.12), 0px 1px 2px 0px rgba(0, 0, 0, 0.08)"
  class="smbk-shadow-editor"
>
  <div class="smbk-shadow-editor__preview" aria-hidden="true">
    <div class="smbk-shadow-editor__card"></div>
  </div>
  <span
    id="shadow-editor-1-hint"
    class="smbk-shadow-editor__hidden"
  >Up and down arrow keys move the layer.</span>
  <ol class="smbk-shadow-editor__layers">
    <li class="smbk-shadow-editor__layer" aria-labelledby="shadow-editor-1-0-name">
      <div class="smbk-shadow-editor__head">
        <span class="smbk-shadow-editor__title">
          <button
            type="button"
            class="smbk-shadow-editor__handle"
            aria-label="Move Layer 1"
            aria-describedby="shadow-editor-1-hint"
          >
            <i class="ph ph-dots-six-vertical smbk-icon smbk-icon--size-md" aria-hidden="true"></i>
          </button>
          <span id="shadow-editor-1-0-name" class="smbk-shadow-editor__name">Layer 1</span>
        </span>
        <button
          type="button"
          class="smbk-btn smbk-btn--tone-ghost smbk-btn--size-xs smbk-btn--icon-only smbk-shadow-editor__remove"
          aria-label="Remove Layer 1"
        >
          <i class="ph ph-trash smbk-icon smbk-icon--size-md smbk-btn__icon" aria-hidden="true"></i>
        </button>
      </div>
      <div class="smbk-shadow-editor__fields">
        <span class="smbk-shadow-editor__field">
          <span
            id="shadow-editor-1-0-x"
            class="smbk-shadow-editor__label"
          >X<span class="smbk-shadow-editor__hidden"> offset in pixels</span></span>
          <span class="smbk-input smbk-input--size-sm smbk-number-field smbk-number-field--size-sm">
            <input
              aria-labelledby="shadow-editor-1-0-name shadow-editor-1-0-x"
              aria-describedby="react-aria-shadow-editor-2 react-aria-shadow-editor-3"
              id="react-aria-shadow-editor-4"
              type="text"
              autoComplete="off"
              inputMode="numeric"
              autoCorrect="off"
              spellCheck="false"
              tabindex="0"
              aria-roledescription="Number field"
              class="smbk-input__control smbk-number-field__control"
              value="0"
            >
          </span>
        </span>
        <span class="smbk-shadow-editor__field">
          <span
            id="shadow-editor-1-0-y"
            class="smbk-shadow-editor__label"
          >Y<span class="smbk-shadow-editor__hidden"> offset in pixels</span></span>
          <span class="smbk-input smbk-input--size-sm smbk-number-field smbk-number-field--size-sm">
            <input
              aria-labelledby="shadow-editor-1-0-name shadow-editor-1-0-y"
              aria-describedby="react-aria-shadow-editor-5 react-aria-shadow-editor-6"
              id="react-aria-shadow-editor-7"
              type="text"
              autoComplete="off"
              inputMode="numeric"
              autoCorrect="off"
              spellCheck="false"
              tabindex="0"
              aria-roledescription="Number field"
              class="smbk-input__control smbk-number-field__control"
              value="4"
            >
          </span>
        </span>
        <span class="smbk-shadow-editor__field">
          <span
            id="shadow-editor-1-0-blur"
            class="smbk-shadow-editor__label"
          >Blur<span class="smbk-shadow-editor__hidden"> in pixels</span></span>
          <span class="smbk-input smbk-input--size-sm smbk-number-field smbk-number-field--size-sm">
            <input
              aria-labelledby="shadow-editor-1-0-name shadow-editor-1-0-blur"
              aria-describedby="react-aria-shadow-editor-8 react-aria-shadow-editor-9"
              id="react-aria-shadow-editor-10"
              type="text"
              autoComplete="off"
              inputMode="numeric"
              autoCorrect="off"
              spellCheck="false"
              tabindex="0"
              aria-roledescription="Number field"
              class="smbk-input__control smbk-number-field__control"
              value="12"
            >
          </span>
        </span>
        <span class="smbk-shadow-editor__field">
          <span
            id="shadow-editor-1-0-spread"
            class="smbk-shadow-editor__label"
          >Spread<span class="smbk-shadow-editor__hidden"> in pixels</span></span>
          <span class="smbk-input smbk-input--size-sm smbk-number-field smbk-number-field--size-sm">
            <input
              aria-labelledby="shadow-editor-1-0-name shadow-editor-1-0-spread"
              aria-describedby="react-aria-shadow-editor-11 react-aria-shadow-editor-12"
              id="react-aria-shadow-editor-13"
              type="text"
              autoComplete="off"
              inputMode="numeric"
              autoCorrect="off"
              spellCheck="false"
              tabindex="0"
              aria-roledescription="Number field"
              class="smbk-input__control smbk-number-field__control"
              value="-2"
            >
          </span>
        </span>
      </div>
      <div class="smbk-shadow-editor__paint">
        <span class="smbk-shadow-editor__field">
          <span id="shadow-editor-1-0-color" class="smbk-shadow-editor__label">Color</span>
          <span class="smbk-color-picker smbk-color-picker--type-field smbk-color-picker--size-sm">
            <div class="smbk-popover__anchor">
              <button
                type="button"
                id="shadow-editor-14-opener"
                class="smbk-input smbk-input--size-sm smbk-select__well smbk-color-picker__trigger"
                aria-labelledby="shadow-editor-1-0-name shadow-editor-1-0-color shadow-editor-15-value"
                aria-haspopup="dialog"
                aria-expanded="false"
                aria-controls="shadow-editor-14-panel"
              >
                <span class="smbk-input__leading-content">
                  <span
                    aria-hidden="true"
                    class="smbk-color-swatch smbk-color-swatch--size-xs smbk-color-swatch--shape-square smbk-color-picker__swatch"
                  ><span class="smbk-color-checker"></span><span class="smbk-color-swatch__color" style="background-color:rgba(0, 0, 0, 1)"></span></span>
                </span>
                <span
                  class="smbk-select__value smbk-color-picker__value"
                  aria-hidden="true"
                >#000000</span>
                <span
                  id="shadow-editor-15-value"
                  class="smbk-color-picker__name"
                >#000000, black</span>
                <i
                  class="ph ph-caret-down smbk-icon smbk-icon--size-md smbk-input__icon smbk-select__icon smbk-color-picker__caret"
                  aria-hidden="true"
                ></i>
              </button>
              <div class="smbk-popover__layer">
                <div
                  id="shadow-editor-14-panel"
                  role="dialog"
                  aria-label="Color picker"
                  class="smbk-popover smbk-popover--align-start smbk-popover--side-below smbk-color-picker__panel"
                  tabindex="-1"
                  data-scrollbar=""
                  hidden=""
                >
                  <div
                    id="react-aria-shadow-editor-16"
                    role="group"
                    style="position:relative;touch-action:none;forced-color-adjust:none;background:linear-gradient(to top, black, transparent), linear-gradient(to right, hsla(0, 0%, 100%, 1), transparent), hsla(0, 100%, 50%, 1)"
                    class="smbk-color-area smbk-color-picker__area"
                  >
                    <div
                      style="position:absolute;left:0%;top:100%;transform:translate(-50%, -50%);touch-action:none;forced-color-adjust:none;background-color:hsla(0, 0%, 0%, 1)"
                      role="presentation"
                      class="smbk-color-thumb smbk-color-area__thumb"
                    ><input id="react-aria-shadow-editor-17" aria-label="Color picker" style="border:0;clip:rect(0 0 0 0);clip-path:inset(50%);height:100%;margin:-1px;overflow:hidden;padding:0;position:absolute;width:100%;white-space:nowrap;opacity:0.0001;pointer-events:none" type="range" min="0" max="100" step="1" aria-roledescription="2D slider" aria-valuetext="Saturation: 0%, Brightness: 0%, Hue: 0°, black" aria-orientation="horizontal" value="0"/><input id="react-aria-shadow-editor-18" aria-label="Color picker" style="border:0;clip:rect(0 0 0 0);clip-path:inset(50%);height:100%;margin:-1px;overflow:hidden;padding:0;position:absolute;width:100%;white-space:nowrap;opacity:0.0001;pointer-events:none" type="range" min="0" max="100" step="1" aria-roledescription="2D slider" aria-valuetext="Brightness: 0%, Saturation: 0%, Hue: 0°, black" aria-orientation="vertical" tabindex="-1" aria-hidden="true" value="0"/></div>
                  </div>
                  <div class="smbk-color-slider smbk-color-slider--channel-hue smbk-color-slider--size-md smbk-color-picker__slider">
                    <div
                      role="group"
                      id="react-aria-shadow-editor-19"
                      aria-label="Hue"
                      style="position:relative;touch-action:none;forced-color-adjust:none"
                      class="smbk-color-slider__track"
                    ><span class="smbk-color-slider__gradient" style="background:linear-gradient(to right, hsla(0, 100%, 50%, 1), hsla(60, 100%, 50%, 1), hsla(120, 100%, 50%, 1), hsla(180, 100%, 50%, 1), hsla(240, 100%, 50%, 1), hsla(300, 100%, 50%, 1), hsla(360, 100%, 50%, 1))"></span><div class="smbk-color-slider__rail"><div style="position:absolute;left:0%;transform:translate(-50%, -50%);touch-action:none;forced-color-adjust:none;background-color:hsla(0, 100%, 50%, 1)" class="smbk-color-thumb smbk-color-thumb--size-md smbk-color-slider__thumb"><input tabindex="0" id="react-aria-shadow-editor-19-0" aria-labelledby="react-aria-shadow-editor-19" type="range" min="0" max="360" step="1" aria-orientation="horizontal" aria-valuetext="0°, red" aria-describedby="" aria-details="" style="border:0;clip:rect(0 0 0 0);clip-path:inset(50%);height:100%;margin:-1px;overflow:hidden;padding:0;position:absolute;width:100%;white-space:nowrap;opacity:0.0001;pointer-events:none" value="0"/></div></div></div>
                  </div>
                  <div class="smbk-color-picker__code">
                    <span class="smbk-select smbk-select--size-sm smbk-color-picker__format">
                      <button
                        type="button"
                        id="selectshadow-editor-20"
                        class="smbk-input smbk-input--size-sm smbk-select__well"
                        role="combobox"
                        aria-haspopup="listbox"
                        aria-expanded="false"
                        aria-label="Color format"
                      >
                        <span class="smbk-select__value">Hex</span>
                        <i
                          class="ph ph-caret-down smbk-icon smbk-icon--size-md smbk-input__icon smbk-select__icon"
                          aria-hidden="true"
                        ></i>
                      </button>
                    </span>
                    <span class="smbk-input smbk-input--size-sm smbk-color-field smbk-color-field--size-sm smbk-color-picker__field">
                      <span class="smbk-input__leading-content">
                        <span
                          aria-hidden="true"
                          class="smbk-color-swatch smbk-color-swatch--size-xs smbk-color-swatch--shape-square smbk-color-field__swatch"
                        ><span class="smbk-color-checker"></span><span class="smbk-color-swatch__color" style="background-color:rgba(0, 0, 0, 1)"></span></span>
                      </span>
                      <input
                        id="react-aria-shadow-editor-21"
                        aria-label="Color code"
                        aria-describedby="react-aria-shadow-editor-22 react-aria-shadow-editor-23"
                        type="text"
                        autoComplete="off"
                        autoCapitalize="off"
                        autoCorrect="off"
                        spellCheck="false"
                        tabindex="0"
                        role="textbox"
                        class="smbk-input__control smbk-color-field__control"
                        value="#000000"
                      >
                    </span>
                  </div>
                </div>
              </div>
            </div>
          </span>
        </span>
        <span class="smbk-shadow-editor__field">
          <span id="shadow-editor-1-0-opacity" class="smbk-shadow-editor__label">Opacity</span>
          <span class="smbk-input smbk-input--size-sm smbk-number-field smbk-number-field--size-sm">
            <input
              aria-labelledby="shadow-editor-1-0-name shadow-editor-1-0-opacity"
              aria-describedby="react-aria-shadow-editor-24 react-aria-shadow-editor-25"
              id="react-aria-shadow-editor-26"
              type="text"
              autoComplete="off"
              inputMode="numeric"
              autoCorrect="off"
              spellCheck="false"
              tabindex="0"
              aria-roledescription="Number field"
              class="smbk-input__control smbk-number-field__control"
              value="12%"
            >
          </span>
        </span>
      </div>
    </li>
    <li class="smbk-shadow-editor__layer" aria-labelledby="shadow-editor-1-1-name">
      <div class="smbk-shadow-editor__head">
        <span class="smbk-shadow-editor__title">
          <button
            type="button"
            class="smbk-shadow-editor__handle"
            aria-label="Move Layer 2"
            aria-describedby="shadow-editor-1-hint"
          >
            <i class="ph ph-dots-six-vertical smbk-icon smbk-icon--size-md" aria-hidden="true"></i>
          </button>
          <span id="shadow-editor-1-1-name" class="smbk-shadow-editor__name">Layer 2</span>
        </span>
        <button
          type="button"
          class="smbk-btn smbk-btn--tone-ghost smbk-btn--size-xs smbk-btn--icon-only smbk-shadow-editor__remove"
          aria-label="Remove Layer 2"
        >
          <i class="ph ph-trash smbk-icon smbk-icon--size-md smbk-btn__icon" aria-hidden="true"></i>
        </button>
      </div>
      <div class="smbk-shadow-editor__fields">
        <span class="smbk-shadow-editor__field">
          <span
            id="shadow-editor-1-1-x"
            class="smbk-shadow-editor__label"
          >X<span class="smbk-shadow-editor__hidden"> offset in pixels</span></span>
          <span class="smbk-input smbk-input--size-sm smbk-number-field smbk-number-field--size-sm">
            <input
              aria-labelledby="shadow-editor-1-1-name shadow-editor-1-1-x"
              aria-describedby="react-aria-shadow-editor-27 react-aria-shadow-editor-28"
              id="react-aria-shadow-editor-29"
              type="text"
              autoComplete="off"
              inputMode="numeric"
              autoCorrect="off"
              spellCheck="false"
              tabindex="0"
              aria-roledescription="Number field"
              class="smbk-input__control smbk-number-field__control"
              value="0"
            >
          </span>
        </span>
        <span class="smbk-shadow-editor__field">
          <span
            id="shadow-editor-1-1-y"
            class="smbk-shadow-editor__label"
          >Y<span class="smbk-shadow-editor__hidden"> offset in pixels</span></span>
          <span class="smbk-input smbk-input--size-sm smbk-number-field smbk-number-field--size-sm">
            <input
              aria-labelledby="shadow-editor-1-1-name shadow-editor-1-1-y"
              aria-describedby="react-aria-shadow-editor-30 react-aria-shadow-editor-31"
              id="react-aria-shadow-editor-32"
              type="text"
              autoComplete="off"
              inputMode="numeric"
              autoCorrect="off"
              spellCheck="false"
              tabindex="0"
              aria-roledescription="Number field"
              class="smbk-input__control smbk-number-field__control"
              value="1"
            >
          </span>
        </span>
        <span class="smbk-shadow-editor__field">
          <span
            id="shadow-editor-1-1-blur"
            class="smbk-shadow-editor__label"
          >Blur<span class="smbk-shadow-editor__hidden"> in pixels</span></span>
          <span class="smbk-input smbk-input--size-sm smbk-number-field smbk-number-field--size-sm">
            <input
              aria-labelledby="shadow-editor-1-1-name shadow-editor-1-1-blur"
              aria-describedby="react-aria-shadow-editor-33 react-aria-shadow-editor-34"
              id="react-aria-shadow-editor-35"
              type="text"
              autoComplete="off"
              inputMode="numeric"
              autoCorrect="off"
              spellCheck="false"
              tabindex="0"
              aria-roledescription="Number field"
              class="smbk-input__control smbk-number-field__control"
              value="2"
            >
          </span>
        </span>
        <span class="smbk-shadow-editor__field">
          <span
            id="shadow-editor-1-1-spread"
            class="smbk-shadow-editor__label"
          >Spread<span class="smbk-shadow-editor__hidden"> in pixels</span></span>
          <span class="smbk-input smbk-input--size-sm smbk-number-field smbk-number-field--size-sm">
            <input
              aria-labelledby="shadow-editor-1-1-name shadow-editor-1-1-spread"
              aria-describedby="react-aria-shadow-editor-36 react-aria-shadow-editor-37"
              id="react-aria-shadow-editor-38"
              type="text"
              autoComplete="off"
              inputMode="numeric"
              autoCorrect="off"
              spellCheck="false"
              tabindex="0"
              aria-roledescription="Number field"
              class="smbk-input__control smbk-number-field__control"
              value="0"
            >
          </span>
        </span>
      </div>
      <div class="smbk-shadow-editor__paint">
        <span class="smbk-shadow-editor__field">
          <span id="shadow-editor-1-1-color" class="smbk-shadow-editor__label">Color</span>
          <span class="smbk-color-picker smbk-color-picker--type-field smbk-color-picker--size-sm">
            <div class="smbk-popover__anchor">
              <button
                type="button"
                id="shadow-editor-39-opener"
                class="smbk-input smbk-input--size-sm smbk-select__well smbk-color-picker__trigger"
                aria-labelledby="shadow-editor-1-1-name shadow-editor-1-1-color shadow-editor-40-value"
                aria-haspopup="dialog"
                aria-expanded="false"
                aria-controls="shadow-editor-39-panel"
              >
                <span class="smbk-input__leading-content">
                  <span
                    aria-hidden="true"
                    class="smbk-color-swatch smbk-color-swatch--size-xs smbk-color-swatch--shape-square smbk-color-picker__swatch"
                  ><span class="smbk-color-checker"></span><span class="smbk-color-swatch__color" style="background-color:rgba(0, 0, 0, 1)"></span></span>
                </span>
                <span
                  class="smbk-select__value smbk-color-picker__value"
                  aria-hidden="true"
                >#000000</span>
                <span
                  id="shadow-editor-40-value"
                  class="smbk-color-picker__name"
                >#000000, black</span>
                <i
                  class="ph ph-caret-down smbk-icon smbk-icon--size-md smbk-input__icon smbk-select__icon smbk-color-picker__caret"
                  aria-hidden="true"
                ></i>
              </button>
              <div class="smbk-popover__layer">
                <div
                  id="shadow-editor-39-panel"
                  role="dialog"
                  aria-label="Color picker"
                  class="smbk-popover smbk-popover--align-start smbk-popover--side-below smbk-color-picker__panel"
                  tabindex="-1"
                  data-scrollbar=""
                  hidden=""
                >
                  <div
                    id="react-aria-shadow-editor-41"
                    role="group"
                    style="position:relative;touch-action:none;forced-color-adjust:none;background:linear-gradient(to top, black, transparent), linear-gradient(to right, hsla(0, 0%, 100%, 1), transparent), hsla(0, 100%, 50%, 1)"
                    class="smbk-color-area smbk-color-picker__area"
                  >
                    <div
                      style="position:absolute;left:0%;top:100%;transform:translate(-50%, -50%);touch-action:none;forced-color-adjust:none;background-color:hsla(0, 0%, 0%, 1)"
                      role="presentation"
                      class="smbk-color-thumb smbk-color-area__thumb"
                    ><input id="react-aria-shadow-editor-42" aria-label="Color picker" style="border:0;clip:rect(0 0 0 0);clip-path:inset(50%);height:100%;margin:-1px;overflow:hidden;padding:0;position:absolute;width:100%;white-space:nowrap;opacity:0.0001;pointer-events:none" type="range" min="0" max="100" step="1" aria-roledescription="2D slider" aria-valuetext="Saturation: 0%, Brightness: 0%, Hue: 0°, black" aria-orientation="horizontal" value="0"/><input id="react-aria-shadow-editor-43" aria-label="Color picker" style="border:0;clip:rect(0 0 0 0);clip-path:inset(50%);height:100%;margin:-1px;overflow:hidden;padding:0;position:absolute;width:100%;white-space:nowrap;opacity:0.0001;pointer-events:none" type="range" min="0" max="100" step="1" aria-roledescription="2D slider" aria-valuetext="Brightness: 0%, Saturation: 0%, Hue: 0°, black" aria-orientation="vertical" tabindex="-1" aria-hidden="true" value="0"/></div>
                  </div>
                  <div class="smbk-color-slider smbk-color-slider--channel-hue smbk-color-slider--size-md smbk-color-picker__slider">
                    <div
                      role="group"
                      id="react-aria-shadow-editor-44"
                      aria-label="Hue"
                      style="position:relative;touch-action:none;forced-color-adjust:none"
                      class="smbk-color-slider__track"
                    ><span class="smbk-color-slider__gradient" style="background:linear-gradient(to right, hsla(0, 100%, 50%, 1), hsla(60, 100%, 50%, 1), hsla(120, 100%, 50%, 1), hsla(180, 100%, 50%, 1), hsla(240, 100%, 50%, 1), hsla(300, 100%, 50%, 1), hsla(360, 100%, 50%, 1))"></span><div class="smbk-color-slider__rail"><div style="position:absolute;left:0%;transform:translate(-50%, -50%);touch-action:none;forced-color-adjust:none;background-color:hsla(0, 100%, 50%, 1)" class="smbk-color-thumb smbk-color-thumb--size-md smbk-color-slider__thumb"><input tabindex="0" id="react-aria-shadow-editor-44-0" aria-labelledby="react-aria-shadow-editor-44" type="range" min="0" max="360" step="1" aria-orientation="horizontal" aria-valuetext="0°, red" aria-describedby="" aria-details="" style="border:0;clip:rect(0 0 0 0);clip-path:inset(50%);height:100%;margin:-1px;overflow:hidden;padding:0;position:absolute;width:100%;white-space:nowrap;opacity:0.0001;pointer-events:none" value="0"/></div></div></div>
                  </div>
                  <div class="smbk-color-picker__code">
                    <span class="smbk-select smbk-select--size-sm smbk-color-picker__format">
                      <button
                        type="button"
                        id="selectshadow-editor-45"
                        class="smbk-input smbk-input--size-sm smbk-select__well"
                        role="combobox"
                        aria-haspopup="listbox"
                        aria-expanded="false"
                        aria-label="Color format"
                      >
                        <span class="smbk-select__value">Hex</span>
                        <i
                          class="ph ph-caret-down smbk-icon smbk-icon--size-md smbk-input__icon smbk-select__icon"
                          aria-hidden="true"
                        ></i>
                      </button>
                    </span>
                    <span class="smbk-input smbk-input--size-sm smbk-color-field smbk-color-field--size-sm smbk-color-picker__field">
                      <span class="smbk-input__leading-content">
                        <span
                          aria-hidden="true"
                          class="smbk-color-swatch smbk-color-swatch--size-xs smbk-color-swatch--shape-square smbk-color-field__swatch"
                        ><span class="smbk-color-checker"></span><span class="smbk-color-swatch__color" style="background-color:rgba(0, 0, 0, 1)"></span></span>
                      </span>
                      <input
                        id="react-aria-shadow-editor-46"
                        aria-label="Color code"
                        aria-describedby="react-aria-shadow-editor-47 react-aria-shadow-editor-48"
                        type="text"
                        autoComplete="off"
                        autoCapitalize="off"
                        autoCorrect="off"
                        spellCheck="false"
                        tabindex="0"
                        role="textbox"
                        class="smbk-input__control smbk-color-field__control"
                        value="#000000"
                      >
                    </span>
                  </div>
                </div>
              </div>
            </div>
          </span>
        </span>
        <span class="smbk-shadow-editor__field">
          <span id="shadow-editor-1-1-opacity" class="smbk-shadow-editor__label">Opacity</span>
          <span class="smbk-input smbk-input--size-sm smbk-number-field smbk-number-field--size-sm">
            <input
              aria-labelledby="shadow-editor-1-1-name shadow-editor-1-1-opacity"
              aria-describedby="react-aria-shadow-editor-49 react-aria-shadow-editor-50"
              id="react-aria-shadow-editor-51"
              type="text"
              autoComplete="off"
              inputMode="numeric"
              autoCorrect="off"
              spellCheck="false"
              tabindex="0"
              aria-roledescription="Number field"
              class="smbk-input__control smbk-number-field__control"
              value="8%"
            >
          </span>
        </span>
      </div>
    </li>
  </ol>
  <button
    type="button"
    class="smbk-btn smbk-btn--tone-ghost smbk-btn--size-sm smbk-shadow-editor__add"
  >
    <i class="ph ph-plus smbk-icon smbk-icon--size-md smbk-btn__icon" aria-hidden="true"></i>
    <span class="smbk-btn__label">Add layer</span>
  </button>
  <span role="status" class="smbk-shadow-editor__hidden"></span>
</div>
```

## React

```tsx
import { ShadowEditor } from './design-system/components/shadow-editor/shadow-editor.js';

<ShadowEditor defaultValue={[{ x: 0, y: 4, blur: 12, spread: -2, color: "#000000e6", opacity: 0.12 }, { x: 0, y: 1, blur: 2, spread: 0, color: "#000000e6", opacity: 0.08 }]} />
```

## Stylesheet

```css
/* smbk-shadow-editor — Shadow editor. Figma "Shadow editor" 7417:172 (Preview and Add layer switches) and its
 * "ShadowLayer" 7417:87 (Remove switch).
 * A column, the medium stack step apart: a preview (a card on the default surface, raised by the shadow being edited, in
 * a well of the canvas color inside a subtle edge), the layers from top to bottom, and the Add layer button.
 * Each layer is a card on the default surface inside a subtle edge, the medium inset round it and the small stack step
 * between its rows: a head (the move handle and the layer's name in Label MD, and the Remove button), a row of four
 * small number boxes (X, Y, Blur, Spread) and a row of the color picker's field with the opacity box, each box under its
 * label in Body XS. The shadow on the preview's card is data: the wrapper writes it to a custom property on the block. */

.smbk-shadow-editor {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--smbk-space-stack-md);
  min-width: 0;
}

/* The block frames the words it hides for screen readers, so they stay inside it wherever it is placed: without a
   frame they hang from the page itself and stretch it, past the end of an area that scrolls. No weight, so a parent
   that places the block keeps its say. */
:where(.smbk-shadow-editor) {
  position: relative;
}

.smbk-shadow-editor__preview,
.smbk-shadow-editor__layers {
  align-self: stretch;
}

/* The preview: a 64 tall card in the middle of a 128 tall well. Figma's card is 112 wide, written here as the 48 and 64
   size steps together, since no one size step is 112. */
.smbk-shadow-editor__preview {
  display: flex;
  align-items: center;
  justify-content: center;
  box-sizing: border-box;
  padding-block: var(--smbk-space-inset-3xl);
  border: var(--smbk-border-width-hairline) solid var(--smbk-color-border-subtle);
  border-radius: var(--smbk-radius-container-sm);
  background: var(--smbk-color-surface-canvas);
}

.smbk-shadow-editor__card {
  width: calc(var(--smbk-size-48) + var(--smbk-size-64));
  height: var(--smbk-size-64);
  border-radius: var(--smbk-radius-container-sm);
  background: var(--smbk-color-surface-default);
  box-shadow: var(--smbk-shadow-editor-shadow, none);
}

.smbk-shadow-editor__layers {
  display: flex;
  flex-direction: column;
  gap: var(--smbk-space-stack-md);
  margin: 0;
  padding: 0;
  list-style: none;
}

/* ---- a layer (Figma's ShadowLayer) ---- */

.smbk-shadow-editor__layer {
  display: flex;
  flex-direction: column;
  gap: var(--smbk-space-stack-sm);
  box-sizing: border-box;
  min-width: 0;
  padding: var(--smbk-space-inset-md);
  border: var(--smbk-border-width-hairline) solid var(--smbk-color-border-subtle);
  border-radius: var(--smbk-radius-container-sm);
  background: var(--smbk-color-surface-default);
}

.smbk-shadow-editor__layer[data-dragging] {
  box-shadow: var(--smbk-elevation-raised);
}

.smbk-shadow-editor__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  min-height: var(--smbk-size-control-xs);
}

.smbk-shadow-editor__title {
  display: flex;
  align-items: center;
  gap: var(--smbk-space-inline-xs);
  min-width: 0;
}

.smbk-shadow-editor__name {
  color: var(--smbk-color-text-default);
  font-family: var(--smbk-typography-label-md-font-family);
  font-size: var(--smbk-typography-label-md-font-size);
  font-weight: var(--smbk-typography-label-md-font-weight);
  line-height: var(--smbk-typography-label-md-line-height);
  letter-spacing: var(--smbk-typography-label-md-letter-spacing);
}

/* The move handle: Figma's 16 px DotsSixVertical icon, in a 24 px target that moves the layer. */
.smbk-shadow-editor__handle {
  position: relative;
  display: inline-flex;
  flex-shrink: 0;
  align-items: center;
  justify-content: center;
  width: var(--smbk-size-icon-sm);
  height: var(--smbk-size-icon-sm);
  margin: 0;
  padding: 0;
  border: 0;
  border-radius: var(--smbk-radius-control-xs);
  background: none;
  color: var(--smbk-color-text-subtle);
  cursor: grab;
  touch-action: none;
  outline: none;
}

.smbk-shadow-editor__handle::before {
  content: '';
  position: absolute;
  inset: calc((var(--smbk-size-icon-sm) - var(--smbk-size-control-xs)) / 2);
}

.smbk-shadow-editor__handle .smbk-icon {
  font-size: var(--smbk-size-icon-sm);
}

@media (hover: hover) {
  .smbk-shadow-editor__handle:hover {
    color: var(--smbk-color-text-default);
  }
}

.smbk-shadow-editor__layer[data-dragging] .smbk-shadow-editor__handle {
  cursor: grabbing;
}

.smbk-shadow-editor__handle:focus-visible {
  outline: var(--smbk-focus-ring-width) solid var(--smbk-color-border-focus);
  outline-offset: var(--smbk-focus-ring-offset);
}

.smbk-shadow-editor__fields,
.smbk-shadow-editor__paint {
  display: grid;
  gap: var(--smbk-space-inline-sm);
}

.smbk-shadow-editor__fields {
  grid-template-columns: repeat(4, minmax(0, 1fr));
}

/* The color takes the room the opacity box, Figma's 64, leaves. */
.smbk-shadow-editor__paint {
  grid-template-columns: minmax(0, 1fr) var(--smbk-size-64);
}

.smbk-shadow-editor__field {
  display: flex;
  flex-direction: column;
  gap: var(--smbk-space-stack-xs);
  min-width: 0;
}

.smbk-shadow-editor__label {
  color: var(--smbk-color-text-subtle);
  font-family: var(--smbk-typography-body-xs-font-family);
  font-size: var(--smbk-typography-body-xs-font-size);
  font-weight: var(--smbk-typography-body-xs-font-weight);
  line-height: var(--smbk-typography-body-xs-line-height);
  letter-spacing: var(--smbk-typography-body-xs-letter-spacing);
}

/* Words for screen readers only: a label's unit, a move's hint and what changed. */
/* .smbk-shadow-editor__hidden: hidden from view, kept for screen readers and the keyboard, by the shared rule in visually-hidden/visually-hidden.css. */

/* ---- touch: the move handle's area reaches the comfortable target ----
   On a touch screen the handle's invisible area grows from the smallest target to the comfortable one; the dots, the
   focus ring and every place stay as drawn. */

@media (pointer: coarse) {
  .smbk-shadow-editor__handle::before {
    inset: min(0%, (100% - var(--smbk-size-target-comfortable)) / 2);
  }
}

/* ---- high contrast (forced colors) ---- */
@media (forced-colors: active) {
  .smbk-shadow-editor__preview,
  .smbk-shadow-editor__layer {
    border-color: CanvasText;
  }

  .smbk-shadow-editor__card {
    outline: var(--smbk-border-width-hairline) solid CanvasText;
  }

  .smbk-shadow-editor__handle:focus-visible {
    outline-color: Highlight;
  }
}
```

## Tokens it reads

```json
{
  "space": {
    "stack": {
      "md": {
        "$type": "dimension",
        "$value": "{{space.12}}",
        "$description": "Gap between things stacked one above another, medium."
      },
      "sm": {
        "$type": "dimension",
        "$value": "{{space.8}}",
        "$description": "Gap between things stacked one above another, small."
      },
      "xs": {
        "$type": "dimension",
        "$value": "{{space.4}}",
        "$description": "Gap between things stacked one above another, extra small."
      }
    },
    "inset": {
      "3xl": {
        "$type": "dimension",
        "$value": "{{space.32}}",
        "$description": "Padding inside a component, 3× large."
      },
      "md": {
        "$type": "dimension",
        "$value": "{{space.8}}",
        "$description": "Padding inside a component, medium."
      }
    },
    "inline": {
      "xs": {
        "$type": "dimension",
        "$value": "{{space.4}}",
        "$description": "Gap between things side by side, extra small."
      },
      "sm": {
        "$type": "dimension",
        "$value": "{{space.6}}",
        "$description": "Gap between things side by side, small."
      }
    }
  },
  "border-width": {
    "hairline": {
      "$type": "dimension",
      "$value": "{{border-width.1}}",
      "$description": "Thin lines: dividers and almost every edge."
    }
  },
  "color": {
    "border": {
      "subtle": {
        "$type": "color",
        "$value": "{{color.grey.300}}",
        "$description": "Dividers and quiet edges."
      },
      "focus": {
        "$type": "color",
        "$value": "{{color.red.600}}",
        "$description": "Keyboard focus ring on controls."
      }
    },
    "surface": {
      "canvas": {
        "$type": "color",
        "$value": "{{color.grey.200}}",
        "$description": "Page background."
      },
      "default": {
        "$type": "color",
        "$value": "{{color.grey.100}}",
        "$description": "Standard surface: cards, panels, the header."
      }
    },
    "text": {
      "default": {
        "$type": "color",
        "$value": "{{color.grey.900}}",
        "$description": "Main text."
      },
      "subtle": {
        "$type": "color",
        "$value": "{{color.grey.700}}",
        "$description": "Secondary text: descriptions, metadata."
      }
    }
  },
  "radius": {
    "container": {
      "sm": {
        "$type": "dimension",
        "$value": "{{radius.8}}",
        "$description": "Corners of cards, panels and dialogs, small."
      }
    },
    "control": {
      "xs": {
        "$type": "dimension",
        "$value": "{{radius.2}}",
        "$description": "Corners of controls, extra small."
      }
    }
  },
  "size": {
    "48": {
      "$type": "dimension",
      "$value": "48px",
      "$description": "Raw size step, 48 px. Only for fixed sizes inside a component; semantic sizes (size/control, icon, mark) point here."
    },
    "64": {
      "$type": "dimension",
      "$value": "64px",
      "$description": "Raw size step, 64 px. Only for fixed sizes inside a component; semantic sizes (size/control, icon, mark) point here."
    },
    "control": {
      "xs": {
        "$type": "dimension",
        "$value": "{{size.24}}",
        "$description": "Height of the extra-small control: 24 in both densities, the smallest target allowed. Dashboard recipe: use compact density; 40 for the page’s one main action and for forms; 32 for toolbars and filters, the size used most; 28 for actions inside table rows and cards. On phones switch to comfortable density, or give small controls an invisible 44 px tap area (size/target/comfortable)."
      }
    },
    "icon": {
      "sm": {
        "$type": "dimension",
        "$value": "{{size.16}}",
        "$description": "Icon box, small."
      }
    },
    "target": {
      "comfortable": {
        "$type": "dimension",
        "$value": "{{size.44}}",
        "$description": "Comfortable touch target (44)."
      }
    }
  },
  "elevation": {
    "raised": {
      "$type": "shadow",
      "$value": {
        "light": "0px 2px 8px 1px #373d431a, 0px 1px 2px 0px #373d431a",
        "dark": "0px 2px 8px 1px #00000026, 0px 1px 2px 0px #00000026"
      }
    }
  },
  "typography": {
    "label-md": {
      "$type": "typography",
      "$value": {
        "fontFamily": "Geist, Geist Fallback, system-ui, sans-serif",
        "fontSize": "14px",
        "fontWeight": 500,
        "lineHeight": 1.4,
        "letterSpacing": "0px"
      },
      "$description": "Label MD: labels on controls and short UI text (buttons, chips, tabs, menu headings). Geist Medium, sentence case. Code and keys use Code SM and Code MD."
    },
    "body-xs": {
      "$type": "typography",
      "$value": {
        "fontFamily": "Geist, Geist Fallback, system-ui, sans-serif",
        "fontSize": "12px",
        "fontWeight": 400,
        "lineHeight": 1.5,
        "letterSpacing": "0px"
      }
    }
  },
  "focus": {
    "ring": {
      "width": {
        "$type": "dimension",
        "$value": "{{border-width.2}}",
        "$description": "Thickness of the focus ring."
      },
      "offset": {
        "$type": "dimension",
        "$value": "{{space.2}}",
        "$description": "Gap between a control and its focus ring."
      }
    }
  }
}
```

## Purpose

Edits one shadow, such as a design system's shadow level: a preview card drawn with it, its layers from top to bottom, each with its offsets, blur, spread, color and opacity, and a button to add a layer. It is for tools that edit a design system's elevation. To show a shadow without editing it, draw it on a card.

## Anatomy

- The block: a column of the preview, the layers and Add layer, each part of which can be left out but the layers.
- The preview part: a well of the canvas color holding a card (the card part) on the default surface, raised by the shadow being edited.
- The layers part: a list of the layer part, top layer first. Each layer is a card on the default surface inside a subtle edge:
  - the head part: the move handle (the handle part, shown when there are two layers or more) and the layer's name, such as "Layer 1" (the name part), then the Remove button (the remove part), which can be left out;
  - the fields part: four small number boxes, X, Y, Blur and Spread, each under its label (the field and label parts);
  - the paint part: the color picker's field and the opacity box, in percent.
- The add part: a ghost button, "Add layer".

## When to use

- To set the layers of a shadow, and see it as it is set.

## When not to use

- To choose among a system's shadow levels by name. Offer them by name.
- For a shadow of one hard layer, which reads as a line: soft shadows are two or three layers.

## Behavior

Each change is drawn on the preview at once and reported to the page with every layer. `shadowToCss` writes the layers as a CSS `box-shadow`. A layer's color keeps its code; its opacity is the layer's own, so the color's own opacity is replaced. Blur never goes below 0. A layer marked as inset stays inset, though the editor offers no switch for it.

Remove takes a layer out; Add layer adds one at the foot. A layer's handle moves it up and down the list, dragged or with the arrow keys; the first layer is drawn on top.

On a touch screen the move handle keeps its size and takes an invisible press area round it, out to the comfortable touch target.

## Accessibility

### What it does for you

- The layers are a list. Each box is named with its layer and its label, such as "Layer 1 Blur in pixels".
- The move handle is a button named "Move Layer 1"; the up and down arrow keys move its layer, and focus stays on it. Dragging is never the only way.
- Remove is named with its layer, "Remove Layer 2". After it, focus moves to the layer that takes its place, or to Add layer when none is left. Add layer moves focus to the new layer's first box.
- Each change to the list is said politely: "Layer 3 added", "Layer 2 removed", "Layer 1 moved to place 2 of 3".
- The preview is hidden from screen readers; the numbers are the content.
- Every word it says by itself, such as the layers' names, the labels and what it says as layers change, keeps its English unless the page gives its own.
- On a touch screen the move handle keeps its size and takes an invisible press area round it, out to the comfortable touch target.
- In a forced-color mode, the edges of the preview and the layers are drawn in the reader's text color.

### What you must do

- Give the layers' names, the labels and the announcements in the page's own language when the page is not in English.

### How to test

- Tab to a layer's boxes and type a number: the preview changes at once. Tab to a move handle and press Up Arrow or Down Arrow: the layer moves, focus stays on the handle, and the move is announced.
- Press Enter on Remove: the layer goes and focus moves to the layer that took its place, or to Add layer when none is left. Press Enter on Add layer: focus moves to the new layer's first box.
- With a screen reader, the layers are read as a list, each box by its layer and its label, and each change is announced politely.
- With text at 200% and the page 320 pixels wide, the layers' boxes stay whole and reachable.
- In a forced-color mode, the edges of the layers and the preview stay visible.

### Keyboard

| Key | What it does |
|---|---|
| Tab | Moves focus through the controls of each layer in turn, then to Add layer. |
| Up Arrow or Down Arrow | On a move handle, moves its layer up or down the list. Focus stays on the handle. |
| Enter or Space | On Remove or Add layer, presses it. |

## Usage rules

### Do

- Keep a shadow to two or three soft layers.

### Don't

- Hide Remove and Add layer where the reader is meant to change how many layers there are.
