# Field message

The line under a field or a group of choices: help that says what to enter, a warning to notice, or an error that says what is wrong.

Block: `smbk-field-message`. 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 |
|---|---|---|---|
| `type` | `help`, `warning`, `error` | `help` | Help is quiet text with no icon. Warning leads with the warning icon; error leads with the circled cross and turns the danger color. |

Parts: `smbk-field-message__icon`, `smbk-field-message__text`

## Markup

```html
<p class="smbk-field-message smbk-field-message--type-help">
  <span class="smbk-field-message__text">Add the part after the @, such as example.com.</span>
</p>
```

## React

```tsx
import { FieldMessage } from './design-system/components/field-message/field-message.js';

<FieldMessage type="help">Add the part after the @, such as example.com.</FieldMessage>
```

## Stylesheet

```css
/* smbk-field-message — Field message. Figma "Field message" 7101:46 (Type: Help, Warning, Error).
 * The line under a field or a group of choices: help that says what to enter,
 * a warning to notice (a password field's Caps Lock notice), or an error that
 * says what is wrong. Body SM. The warning and the error lead with an icon at
 * the small icon size, so neither is told by color alone; help has none. */

.smbk-field-message {
  display: flex;
  align-items: flex-start;
  gap: var(--smbk-space-inline-xs);
  margin: 0;
  color: var(--smbk-color-text-subtlest);
  font-family: var(--smbk-typography-body-sm-font-family);
  font-size: var(--smbk-typography-body-sm-font-size);
  font-weight: var(--smbk-typography-body-sm-font-weight);
  line-height: var(--smbk-typography-body-sm-line-height);
  letter-spacing: var(--smbk-typography-body-sm-letter-spacing);
}

/* The icon's box is as tall as the text's line, so the icon sits on the first line's middle. */
.smbk-field-message__icon {
  height: calc(var(--smbk-typography-body-sm-font-size) * var(--smbk-typography-body-sm-line-height));
  font-size: var(--smbk-size-icon-sm);
}

.smbk-field-message__text {
  min-width: 0;
}

.smbk-field-message--type-warning {
  color: var(--smbk-color-text-subtle);
}

.smbk-field-message--type-warning .smbk-field-message__icon {
  color: var(--smbk-color-feedback-warning-icon);
}

.smbk-field-message--type-error {
  color: var(--smbk-color-feedback-danger-text-on-subtle);
}

.smbk-field-message--type-error .smbk-field-message__icon {
  color: var(--smbk-color-feedback-danger-icon);
}
```

## Tokens it reads

```json
{
  "space": {
    "inline": {
      "xs": {
        "$type": "dimension",
        "$value": "{{space.4}}",
        "$description": "Gap between things side by side, extra small."
      }
    }
  },
  "color": {
    "text": {
      "subtlest": {
        "$type": "color",
        "$value": "{{color.grey.600}}",
        "$description": "Quietest text: hints, captions, placeholders."
      },
      "subtle": {
        "$type": "color",
        "$value": "{{color.grey.700}}",
        "$description": "Secondary text: descriptions, metadata."
      }
    },
    "feedback": {
      "warning": {
        "icon": {
          "$type": "color",
          "$value": "{{color.orange.600}}",
          "$description": "The warning tone’s own icon (a warning sign), so the tone is never shown by colour alone."
        }
      },
      "danger": {
        "text-on-subtle": {
          "$type": "color",
          "$value": "{{color.red.700}}",
          "$description": "Danger messages: text on the pale fill."
        },
        "icon": {
          "$type": "color",
          "$value": "{{color.red.600}}",
          "$description": "The danger tone’s own icon (an alert sign), so the tone is never shown by colour alone."
        }
      }
    }
  },
  "typography": {
    "body-sm": {
      "$type": "typography",
      "$value": {
        "fontFamily": "Geist, Geist Fallback, system-ui, sans-serif",
        "fontSize": "14px",
        "fontWeight": 400,
        "lineHeight": 1.5,
        "letterSpacing": "0px"
      }
    }
  },
  "size": {
    "icon": {
      "sm": {
        "$type": "dimension",
        "$value": "{{size.16}}",
        "$description": "Icon box, small."
      }
    }
  }
}
```

## Purpose

The line under a control or a group of choices. It says what to enter, flags something to notice, or says what is wrong and how to put it right. Every form part draws its line with it, so help, warnings and errors look and read the same everywhere.

## Anatomy

- The block, one line of the small body text that wraps when it must.
- The icon part, before the words: the warning sign for a warning, the circled cross for an error. Help has none.
- The text part, the words.

## When to use

- Help under a control: what to enter, or why it is asked.
- A warning the reader should notice while filling it in, such as Caps Lock being on in a password.
- An error under a control or a group of choices, saying what is wrong and how to fix it.

## When not to use

- A single control's help or error inside a field. The [field](field.md) draws its line with this component and links it for you.
- A message about the whole form or page. Use the [alert](alert.md).
- A message that comes and goes on its own. Use the [toast](toast.md).

## Behavior

Three types. Help is quiet text with no icon. A warning leads with the warning icon in the warning color, its words in the secondary text color. An error leads with the circled cross and turns its words the danger color. Nothing moves.

It is a paragraph, for a line of words. With `as="div"` it is a div, its words in a div too, for words written as blocks, such as paragraphs or a list, which a paragraph cannot hold; the component that places it spaces the blocks, as the field group does.

## Accessibility

### What it does for you

- An error is an alert, so a screen reader reads it as it appears; a warning that appears while the reader types is better as a status, which waits for a pause. Pass the role to change it.
- A status is read out only when words arrive in a place already on the page. Draw the message with no words (`null`) while there is nothing to say: it keeps an empty place, with no icon, and the words fill it when they come.
- A warning and an error are words with an icon, never color alone. The icon is decorative; the words say it all.

### What you must do

- Give the message an id and point the control's or the group's `aria-describedby` at it, so it is read with the control's name.
- Pass `null` as the words while there is nothing to say, so the place is on the page before the words arrive.
- Choose the role: leave an error as an alert, and pass the status role for a warning that appears while the reader types.

### How to test

- With a screen reader, focus the control: the message is read after its name.
- Cause an error: it is read as it appears. Cause a warning while typing: it is read after a pause.
- With the colors removed, the icon and the words still say it is a warning or an error.
- With text at 200% and the page 320 pixels wide, the words wrap and stay whole.
- In a forced-color mode, the icon is still visible.

## Usage rules

### Do

- Write an error as what to do: "Choose a delivery speed", not "Required".
- Keep help to one short line.

### Don't

- Show an error before the reader has had a chance to answer.
- Use a warning for an error: a warning does not stop the form.
