My Design System

Custom Field

Custom Field is a component for wrapping multiple components as a single field. It has the same features as Input Fields, such as its own label, helper, validation, and data binding. Use it to create custom input components.

Open in a
new tab
<vaadin-custom-field
  label="Enrollment period"
  helper-text="Cannot be longer than 30 days"
  required
  ...="${field(this.binder.model.enrollmentPeriod)}"
>
  <vaadin-date-picker id="start" placeholder="Start date"></vaadin-date-picker>
  &ndash;
  <vaadin-date-picker id="end" placeholder="End date"></vaadin-date-picker>
</vaadin-custom-field>

Basic Usage

Custom Field is optimised for wrapping the following components:

It can also be used to provide a label, helper, and the other field features, for components that don’t have them built-in, such as List Box.

Native Input Fields

Custom Field works with native HTML elements.

Open in a
new tab
<vaadin-custom-field
  label="Payment information"
  @change="${(e: CustomFieldValueChangedEvent) => (this.customFieldValue = e.detail.value)}"
>
  <vaadin-horizontal-layout theme="spacing-s">
    <input
      aria-label="Cardholder name"
      pattern="[\\p{L} \\-]+"
      placeholder="Cardholder name"
      required
      type="text"
    />
    <input
      aria-label="Card number"
      pattern="[\\d ]{12,23}"
      placeholder="Card number"
      required
      type="text"
    />
    <input
      aria-label="Security code"
      pattern="[0-9]{3,4}"
      placeholder="Security code"
      required
      type="text"
    />
  </vaadin-horizontal-layout>
</vaadin-custom-field>
<p><b>Payment information:</b> ${this.customFieldValue}</p>

Supported Features

Size Variants

The small theme variant can be used to make Custom Field’s label, helper, and error message smaller. Custom Field does not propagate its theme variant to its internal components, meaning each internal component’s theme variant must be set individually.

Open in a
new tab

The inline .renderer function is encapsulated by the guard directive for performance reasons. See the official Lit documentation for more details.

<vaadin-custom-field label="Price" theme="small">
  <vaadin-horizontal-layout theme="spacing-s">
    <vaadin-text-field id="amount" theme="small"></vaadin-text-field>
    <vaadin-select
      id="currency"
      theme="small"
      style="width: 6em;"
      .renderer="${guard(
        [],
        () => (root: HTMLElement) =>
          render(
            html`
              <vaadin-list-box>
                <vaadin-item value="eur">AUD</vaadin-item>
                <vaadin-item value="eur">CAD</vaadin-item>
                <vaadin-item value="eur">CHF</vaadin-item>
                <vaadin-item value="eur">EUR</vaadin-item>
                <vaadin-item value="gbp">GBP</vaadin-item>
                <vaadin-item value="gbp">JPY</vaadin-item>
                <vaadin-item value="usd">USD</vaadin-item>
              </vaadin-list-box>
            `,
            root
          )
      )}"
    ></vaadin-select>
  </vaadin-horizontal-layout>
</vaadin-custom-field>