Input: With Error

Input

When to use this component

Use the input component to let users enter text or a value that is not longer than a single line.

When not to use this component

Do not use the input component to let users enter longer text that might have multiple lines. In this case, use textarea component instead.

How it works

Types of input

  • Default (simple text or text value that is not longer than a single line, no format)
  • Date (date format)
  • Time
  • Number (number format)
  • Password (password, characters are masked)
  • Email (automatically validated)
  • Telephone number

Date input

To let users enter a date, use the input type date. This will trigger the built-in browser date picker functionality for a consistent user experience. It is also the best way to let the user enter a date on mobile and it is accessible (most custom date pickers aren’t).

For browsers that do not support the input type date, make sure there is a fallback, for instance, by adding a field message explaining the date format that should be used combined with pattern validation.

Usage, behaviour, layout and validation

The input component is a form element that should always be used in a form. For a description of the usage, the behavior, the layout and validation of form elements, see the form component examples and documentation.

{% set describedBy = null %}
{% if field_description %}
  {% set describedBy = id ~ "-description" %}
{% endif %}
{% if field_message %}
  {% set describedBy = id ~ "-message" %}
{% endif %}
<div class="form-item {{ modifier ? ' ' ~ modifier : '' }}{{ stacked ? ' stacked' : '' }}">
  {% include '@label' with {
    "label": label,
    "for": id,
    "label_optional": label_optional
  } %}
  {% include '@field-message' with {
    "field_message": field_description,
    "modifier": null,
    "id": id ~ "-description"
  } %}
  <div class="form-columns">
    <div class="form-item-column">
      {% include '@'~input_component with {
        "id": id,
        "name": name|default(id),
        "ariaDescribedBy": describedBy,
        "type": type,
        "invalid": modifier == 'error',
        "modifier": modifier
      }%}
    </div>
    <div class="form-item-column">
      {% if field_message %}
        {% include '@field-message' with {
          "modifier": modifier,
          "id": id ~ "-message"
        } %}
      {% endif %}
    </div>
  </div>
</div>
<div class="form-item  error">
      <label for="input_text--error">input-text
          <span class="label-optional">
              (Optional)
          </span>
      </label>
      <div class="form-columns">
          <div class="form-item-column">

              <input type="text" id="input_text--error" aria-describedby="input_text--error-message" name="input_text--error" class="text error" aria-invalid="true" />
          </div>
          <div class="form-item-column">
              <div class="field-message error" role="alert" id="input_text--error-message">
                  Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec laoreet, urna sit amet convallis rhoncus, felis ex.
                  <div class="accolade "></div>
              </div>
          </div>
      </div>
  </div>
{
  "label": "input-text",
  "id": "input_text--error",
  "label_optional": "Optional",
  "field_description": null,
  "field_message": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec laoreet, urna sit amet convallis rhoncus, felis ex.",
  "input_component": "input",
  "type": "text",
  "modifier": "error"
}
  • Content:
    .form-item {
      margin-bottom: 1.2rem;
    
      > * {
        max-width: 20.5rem;
    
        @include desktop {
          max-width: 41rem;
    
          &.field-message {
            max-width: 20.5rem;
          }
        }
      }
    
      .field-message:not(.error):not(.success) {
        margin-bottom: .4rem;
      }
    
      &:not(.stacked) {
        .form-columns {
          margin-bottom: 0;
    
          @include desktop {
            display: flex;
    
            .form-item-column {
              width: 50%;
    
              &:last-child {
                display: flex;
                align-items: flex-start;
    
                .field-message {
                  margin: 0 0 gutter()/2 .2rem;
                  padding: .7rem 1.2rem .7rem 3.9rem;
    
                  &::before {
                    top: .5rem;
                    left: 1.7rem;
                  }
    
                  .accolade {
                    right: auto;
                    bottom: 0;
                    left: 0;
                    width: 1rem;
                    height: 100%;
                    transform: rotate(0deg);
    
                    &::before,
                    &::after {
                      width: 1rem;
                      border: 0;
                    }
    
                    &::before {
                      top: 0;
                      bottom: 1.2rem;
                      height: 1.2rem;
                      border-radius: 0 0 border-radius("radius-4");
                    }
    
                    &::after {
                      top: 1.2rem;
                      right: 0;
                      bottom: -1px;
                      height: auto;
                      border-radius: 0 border-radius("radius-4") 0 0;
                    }
                  }
                }
              }
            }
          }
        }
      }
    
      &.stacked {
        > * {
          max-width: none;
        }
    
        .form-columns {
          flex-wrap: wrap;
          margin-top: auto;
        }
    
        .form-columns .form-item-column {
          width: 100%;
          max-width: 40rem;
    
          .field-message {
            margin-top: .2rem;
            margin-left: 0;
          }
        }
      }
    }
    
  • URL: /components/raw/form-item/_form-item.scss
  • Filesystem Path: components/31-molecules/form-item/_form-item.scss
  • Size: 1.9 KB