Skip to content

Form associated elements validation slots

Damyan Petev edited this page Oct 4, 2024 · 2 revisions

Improve web components validation story

Owned by

Team name: Web Tools

Developer name Radoslav Karaivanov

Requires approval from

  • Damyan Petev
  • Svilen Dimchevksi

Signed off by

  • - Damyan Petev 2024-10-04
  • - Radoslav Mirchev

Revision history

Version Author Date Notes
Draft Radoslav Karaivanov 2024-06-20 Initial draft
Draft Radoslav Karaivanov 2024-06-28 Updated draft specification
Draft Radoslav Karaivanov 2024-09-26 Updated draft specification
1 Radoslav Karaivanov 2024-09-30 Finalized specification

Overview

This document defines a mechanism for declarative rendering of error messages based on the validation state of a given form-associated component.

Acceptance criteria

  • Provide a declarative way for users of the product to define and customize validation messages based on the set validation constraints.
  • Give a distinct slot for each category of validation errors state for granular control.
  • Give a "catch-all" slot to display validation error messages based on the invalid state of the control.
  • Automatically replace any slotted helper text with slotted error message(s) if the host component in in invalid state. Once the host is valid switch back to showing the helper-text. This does not trigger if there are no slotted error messages.
  • Integrate the behavior in the established validation pipeline for form-associated components of the library so that it works with user interaction, form submit and form reset patterns.
  • Integrate the behavior with the default look and feel of the product while giving opportunities for customization of presentation.
  • Try to make it as accessible as possible by default and without additional configuration from the user.

Developer stories

As a developer I expect to be able to:

  • slot different error messages based on the active invalid flags of a given component in order to guide end-users and prevent the submission of invalid data.
  • slot error message(s) based on the invalid state of the control regardless of what kind of invalid flag is set.
  • do that declaratively
  • have both description (helper-text) and error slotted content in the same component. While the component is in invalid state, I expect the end-user to see the current error context message(s). Once the component is in a valid state I expect the description to be shown.

User stories

As an end-user of the product I expect to be able to:

  • have a visual indication that a certain form input has failed validity constraints.
  • be given information on why a certain form input has failed validation and what is expected as an input/interaction from me to make it valid and submit the form.

Functionality

End-user experience

Design Handoff

Overview

The feature is implemented by a new internal component igc-validator.

The IgcValidationContainerComponent automatically manages reacting to the host invalid state(s) and the rendering of any slotted error messages based on those states and the available validators of the host component.

In addition, the IgcValidationContainerComponent, dy default, will also create a helper-text slot, which is currently present on the majority of form-associated components in the library. When there are both a slotted helper text and error messages, the IgcValidationContainerComponent automatically replaces the helper text with the current set of error messages when the host component is in invalid state. Once the component is back into valid state, the validator component will switch to showing the helper text again.

Note

This behavior does not trigger when there are no slotted error messages.


Developers can choose which and how many error messages they want to present to the end-user by using the appropriate slots for each category of error.

Note, that error slots will be rendered only if the host component is in invalid state and the appropriate validation constraint is applied. For example a message slotted into a value-missing slot inside an igc-input will not show unless the igc-input has the required attribute present and is in invalid state.

The invalid slot

Additionally, each form-associated custom element that has an IgcValidationContainerComponent, exposes an invalid slot. This slot is a "catch-all" mechanism for the invalid state of the component, triggering when the component is in invalid state regardless of the type of validation flag that failed to validate. This can be used by developers that don't want granular error messages and want to show just a generic message to the end-user.

Refer to the default mapping between validation error states and the matching error slots.

Examples

The following code samples show an igc-input with different configuration of error message slots and validators applied.

No slotted errors and no slotted description (helper text).

<igc-input label="Input" required></igc-input>

Nothing extra is rendered as nothing is slotted in the input component regardless of valid/invalid states.

Description (helper text) with no slotted errors

<igc-input label="Input" required>
  <p slot="helper-text">...</p>
</igc-input>

When the input is invalid state, the description is still being shown as there are no slotted error messages.

Description (helper text) and errors

<igc-input label="Input" required>
  <p slot="helper-text">...</p>
  <p slot="value-missing">This field is required</p>
</igc-input>

When the input is in invalid state, the description is replaced with the content of the associated error slot. Once the component passes the validation constrain the description is shown again.

Multiple error slots

<igc-input label="Input" type="email" minlength="8">
  <p slot="type-mismatch">A valid email address is required</p>
  <p slot="too-short">The provided email address is too short</p>
</igc-input>

Multiple error slots with required

<igc-input label="Input" type="email" minlength="8" required>
  <p slot="value-missing">This field is required</p>
  <p slot="type-mismatch">A valid email address is required</p>
  <p slot="too-short">The provided email address is too short</p>
</igc-input>

Following the standard browser behavior, when a valueMissing is set in the validity state of the component, all other states, except customError are "discarded". Thus only the value-missing slot would be shown until the valueMissing validation is satisfied.

Custom error slot

<igc-input label="Input" type="email" minlength="8" required>
  <p slot="custom-error">...</p>
  <p slot="value-missing">This field is required</p>
  <p slot="type-mismatch">A valid email address is required</p>
  <p slot="too-short">The provided email address is too short</p>
</igc-input>

Again, following the standard browser behavior, when a customError is set (by calling setCustomValidity(message)), the state and the slot will persist until the developer calls setCustomValidity('').

Invalid error slot

<igc-input label="Input" type="email" minlength="8" required>
  <p slot="invalid">
    The provided value does not satisfy the input constraints!
  </p>
</igc-input>

Similar to the code snippet above, but in this case the invalid slot is used as a single container for the validation error message regardless of which validator fails.

Validation mapping table

The following table summarizes the mapping of validity state keys to slot names which will render any error message when the associated key is present in the component validity state.

ValidityState key Slot name Validator attribute/property Library components
badInput bad-input - igc-mask-input, igc-date-picker
customError custom-error - igc-input, igc-checkbox, igc-switch, igc-radio, igc-mask-input, igc-select, igc-combo, igc-date-time-input, igc-date-picker, igc-textarea
patternMismatch pattern-mismatch pattern All text-based igc-input types.
rangeOverflow range-overflow max igc-input[type="number"], igc-date-time-input, igc-date-picker
rangeUnderflow range-underflow min igc-input[type="number"], igc-date-time-input, igc-date-picker
stepMismatch step-mismatch step igc-input[type="number"]
tooLong too-long maxlength All text-based igc-input types, igc-textarea
tooShort too-short minlength All text-based igc-input types, igc-textarea
typeMismatch type-mismatch - igc-input[type="email"], igc-input[type="url"]
valueMissing value-missing required igc-input, igc-checkbox, igc-switch, igc-radio, igc-mask-input, igc-select, igc-combo, igc-date-time-input, igc-date-picker, igc-textarea
!valid invalid - igc-input, igc-checkbox, igc-switch, igc-radio, igc-mask-input, igc-select, igc-combo, igc-date-time-input, igc-date-picker, igc-textarea

IgcValidationContainerComponent

Usage

The typical usage pattern is to call the static create method of the IgcValidationContainerComponent class inside the DOM template of the host component.

IgcValidationContainerComponent.create(host, {
  // The `id` attribute bound to the igc-validator element.
  id: '...'
  // Additional part(s) bound to the igc-validator element.
  part: '...',
  // Where to slot the igc-validator element in more advanced
  // DOM structures.
  slot: '...',
  // Whether the igc-validator should expose a helper-text slot.
  hasHelperText: true
})

The igc-validator element will automatically hook up and handle and invalid events from its host as well as dynamic slot changes.

API

Properties

Property Attribute Reflected Property Type Default Description
invalid invalid No Boolean false Whether the host element is in invalid state.
target - No IgcFormControl - The host element which provides validation state.

Methods

Name Type signature Description
create (host: IgcFormControl, config: ValidationContainerConfig): TemplateResult Static method to initialize a new igc-validator element on a given host with a config.

Events

None applicable.

Slots

CSS Shadow Parts

Part Description
helper-text The base wrapper of the helper-text slot container.
validation-message The validation error message container.
validation-icon The validation error igc-icon element.

Test scenarios

Automation

Rendering and initialization
  • is correctly initialized and rendered
Behaviors
  • should render content slotted in the helper-text slot.
  • should not override slotted content in the helper-text slot when the host is invalid and no validation slot is present.
  • should render validation slot content when the host element is invalid and there are slotted validation slots.
  • should override slotted content in the helper-text slot when the host is invalid and there are slotted validation slots.
  • should render multiple validation slots when the host fails multiple validation constraints.

Additional tests should be added for each form component to test its own validators/validation slots rendering and logic.

Accessibility

ARIA

No intrinsic roles are applied to the igc-validator element itself.

However, it is strongly recommended to set the aria-describedby attribute of the host input to the id attribute of the igc-validator element.

Keyboard navigation

None applicable.

Localization

None applicable.

RTL

The component should work in a Right-To-Left context without additional setup or configuration.

Clone this wiki locally