Skip to content

Commit

Permalink
feat: add validity property to form components (#9210)
Browse files Browse the repository at this point in the history
**Related issue:** #9229

## Summary

Add the readonly `validity` property to form components, which exposes
the [`ValidityState`](https://developer.mozilla.org/en-US/docs/Web/API/ValidityState).
This allows users to set custom validation messages based on the invalid
constraint. See the new validation demo for a usage example.
  • Loading branch information
benelan committed Apr 30, 2024
1 parent f110d63 commit e49902b
Show file tree
Hide file tree
Showing 16 changed files with 574 additions and 25 deletions.
2 changes: 1 addition & 1 deletion packages/calcite-components/conventions/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ Private/internal properties should be annotated accordingly to avoid exposing th

### Property values

Property values should be meaningful. Avoid using values such as "default" for default values. Instead, use a more descriptive value.
Property values should be meaningful. Avoid using values such as "default" for default values. Instead, use a more descriptive value.

For instance: `placement: "start" | "end" = "start";` is preferred to `placement: "default" | "end" = "default";`

Expand Down
134 changes: 134 additions & 0 deletions packages/calcite-components/src/components.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import { ButtonMessages } from "./components/button/assets/button/t9n";
import { CardMessages } from "./components/card/assets/card/t9n";
import { ArrowType, AutoplayType } from "./components/carousel/interfaces";
import { CarouselMessages } from "./components/carousel/assets/carousel/t9n";
import { MutableValidityState } from "./utils/form";
import { ChipMessages } from "./components/chip/assets/chip/t9n";
import { ColorValue, InternalColor } from "./components/color-picker/interfaces";
import { Format } from "./components/color-picker/utils";
Expand Down Expand Up @@ -114,6 +115,7 @@ export { ButtonMessages } from "./components/button/assets/button/t9n";
export { CardMessages } from "./components/card/assets/card/t9n";
export { ArrowType, AutoplayType } from "./components/carousel/interfaces";
export { CarouselMessages } from "./components/carousel/assets/carousel/t9n";
export { MutableValidityState } from "./utils/form";
export { ChipMessages } from "./components/chip/assets/chip/t9n";
export { ColorValue, InternalColor } from "./components/color-picker/interfaces";
export { Format } from "./components/color-picker/utils";
Expand Down Expand Up @@ -945,6 +947,12 @@ export namespace Components {
* Specifies the status of the input field, which determines message and icons.
*/
"status": Status;
/**
* The current validation state of the component.
* @readonly
* @mdn [ValidityState](https://developer.mozilla.org/en-US/docs/Web/API/ValidityState)
*/
"validity": MutableValidityState;
/**
* The component's value.
*/
Expand Down Expand Up @@ -1299,6 +1307,12 @@ export namespace Components {
* Specifies the validation message to display under the component.
*/
"validationMessage": string;
/**
* The current validation state of the component.
* @readonly
* @mdn [ValidityState](https://developer.mozilla.org/en-US/docs/Web/API/ValidityState)
*/
"validity": MutableValidityState;
/**
* The component's value(s) from the selected `calcite-combobox-item`(s).
*/
Expand Down Expand Up @@ -2184,6 +2198,12 @@ export namespace Components {
* Specifies the validation message to display under the component.
*/
"validationMessage": string;
/**
* The current validation state of the component.
* @readonly
* @mdn [ValidityState](https://developer.mozilla.org/en-US/docs/Web/API/ValidityState)
*/
"validity": MutableValidityState;
/**
* The component's value.
*/
Expand Down Expand Up @@ -2301,6 +2321,12 @@ export namespace Components {
* Specifies the validation message to display under the component.
*/
"validationMessage": string;
/**
* The current validation state of the component.
* @readonly
* @mdn [ValidityState](https://developer.mozilla.org/en-US/docs/Web/API/ValidityState)
*/
"validity": MutableValidityState;
/**
* Selected date as a string in ISO format (`"yyyy-mm-dd"`).
*/
Expand Down Expand Up @@ -2475,6 +2501,12 @@ export namespace Components {
* Specifies the validation message to display under the component.
*/
"validationMessage": string;
/**
* The current validation state of the component.
* @readonly
* @mdn [ValidityState](https://developer.mozilla.org/en-US/docs/Web/API/ValidityState)
*/
"validity": MutableValidityState;
/**
* The component's value.
*/
Expand Down Expand Up @@ -2595,6 +2627,12 @@ export namespace Components {
* Specifies the validation message to display under the component.
*/
"validationMessage": string;
/**
* The current validation state of the component.
* @readonly
* @mdn [ValidityState](https://developer.mozilla.org/en-US/docs/Web/API/ValidityState)
*/
"validity": MutableValidityState;
/**
* The component's value.
*/
Expand Down Expand Up @@ -2679,6 +2717,12 @@ export namespace Components {
* Specifies the validation message to display under the component.
*/
"validationMessage": string;
/**
* The current validation state of the component.
* @readonly
* @mdn [ValidityState](https://developer.mozilla.org/en-US/docs/Web/API/ValidityState)
*/
"validity": MutableValidityState;
/**
* The time value in ISO (24-hour) format.
*/
Expand Down Expand Up @@ -2756,6 +2800,12 @@ export namespace Components {
* Specifies the validation message to display under the component.
*/
"validationMessage": string;
/**
* The current validation state of the component.
* @readonly
* @mdn [ValidityState](https://developer.mozilla.org/en-US/docs/Web/API/ValidityState)
*/
"validity": MutableValidityState;
/**
* The component's value, where the value is the time zone offset or the difference, in minutes, between the selected time zone and UTC. If no value is provided, the user's time zone offset will be selected by default.
* @see https://www.w3.org/International/core/2005/09/timezone.html#:~:text=What%20is%20a%20%22zone%20offset,or%20%22%2D%22%20from%20UTC.
Expand Down Expand Up @@ -4034,6 +4084,12 @@ export namespace Components {
* Specifies the validation message to display under the component.
*/
"validationMessage": string;
/**
* The current validation state of the component.
* @readonly
* @mdn [ValidityState](https://developer.mozilla.org/en-US/docs/Web/API/ValidityState)
*/
"validity": MutableValidityState;
/**
* The component's `selectedItem` value.
*/
Expand Down Expand Up @@ -4123,6 +4179,12 @@ export namespace Components {
* Specifies the validation message to display under the component.
*/
"validationMessage": string;
/**
* The current validation state of the component.
* @readonly
* @mdn [ValidityState](https://developer.mozilla.org/en-US/docs/Web/API/ValidityState)
*/
"validity": MutableValidityState;
/**
* The component's `selectedOption` value.
*/
Expand Down Expand Up @@ -5058,6 +5120,12 @@ export namespace Components {
* Specifies the validation message to display under the component.
*/
"validationMessage": string;
/**
* The current validation state of the component.
* @readonly
* @mdn [ValidityState](https://developer.mozilla.org/en-US/docs/Web/API/ValidityState)
*/
"validity": MutableValidityState;
/**
* The component's value.
*/
Expand Down Expand Up @@ -8446,6 +8514,12 @@ declare namespace LocalJSX {
* Specifies the status of the input field, which determines message and icons.
*/
"status"?: Status;
/**
* The current validation state of the component.
* @readonly
* @mdn [ValidityState](https://developer.mozilla.org/en-US/docs/Web/API/ValidityState)
*/
"validity"?: MutableValidityState;
/**
* The component's value.
*/
Expand Down Expand Up @@ -8829,6 +8903,12 @@ declare namespace LocalJSX {
* Specifies the validation message to display under the component.
*/
"validationMessage"?: string;
/**
* The current validation state of the component.
* @readonly
* @mdn [ValidityState](https://developer.mozilla.org/en-US/docs/Web/API/ValidityState)
*/
"validity"?: MutableValidityState;
/**
* The component's value(s) from the selected `calcite-combobox-item`(s).
*/
Expand Down Expand Up @@ -9755,6 +9835,12 @@ declare namespace LocalJSX {
* Specifies the validation message to display under the component.
*/
"validationMessage"?: string;
/**
* The current validation state of the component.
* @readonly
* @mdn [ValidityState](https://developer.mozilla.org/en-US/docs/Web/API/ValidityState)
*/
"validity"?: MutableValidityState;
/**
* The component's value.
*/
Expand Down Expand Up @@ -9883,6 +9969,12 @@ declare namespace LocalJSX {
* Specifies the validation message to display under the component.
*/
"validationMessage"?: string;
/**
* The current validation state of the component.
* @readonly
* @mdn [ValidityState](https://developer.mozilla.org/en-US/docs/Web/API/ValidityState)
*/
"validity"?: MutableValidityState;
/**
* Selected date as a string in ISO format (`"yyyy-mm-dd"`).
*/
Expand Down Expand Up @@ -10059,6 +10151,12 @@ declare namespace LocalJSX {
* Specifies the validation message to display under the component.
*/
"validationMessage"?: string;
/**
* The current validation state of the component.
* @readonly
* @mdn [ValidityState](https://developer.mozilla.org/en-US/docs/Web/API/ValidityState)
*/
"validity"?: MutableValidityState;
/**
* The component's value.
*/
Expand Down Expand Up @@ -10184,6 +10282,12 @@ declare namespace LocalJSX {
* Specifies the validation message to display under the component.
*/
"validationMessage"?: string;
/**
* The current validation state of the component.
* @readonly
* @mdn [ValidityState](https://developer.mozilla.org/en-US/docs/Web/API/ValidityState)
*/
"validity"?: MutableValidityState;
/**
* The component's value.
*/
Expand Down Expand Up @@ -10279,6 +10383,12 @@ declare namespace LocalJSX {
* Specifies the validation message to display under the component.
*/
"validationMessage"?: string;
/**
* The current validation state of the component.
* @readonly
* @mdn [ValidityState](https://developer.mozilla.org/en-US/docs/Web/API/ValidityState)
*/
"validity"?: MutableValidityState;
/**
* The time value in ISO (24-hour) format.
*/
Expand Down Expand Up @@ -10375,6 +10485,12 @@ declare namespace LocalJSX {
* Specifies the validation message to display under the component.
*/
"validationMessage"?: string;
/**
* The current validation state of the component.
* @readonly
* @mdn [ValidityState](https://developer.mozilla.org/en-US/docs/Web/API/ValidityState)
*/
"validity"?: MutableValidityState;
/**
* The component's value, where the value is the time zone offset or the difference, in minutes, between the selected time zone and UTC. If no value is provided, the user's time zone offset will be selected by default.
* @see https://www.w3.org/International/core/2005/09/timezone.html#:~:text=What%20is%20a%20%22zone%20offset,or%20%22%2D%22%20from%20UTC.
Expand Down Expand Up @@ -11715,6 +11831,12 @@ declare namespace LocalJSX {
* Specifies the validation message to display under the component.
*/
"validationMessage"?: string;
/**
* The current validation state of the component.
* @readonly
* @mdn [ValidityState](https://developer.mozilla.org/en-US/docs/Web/API/ValidityState)
*/
"validity"?: MutableValidityState;
/**
* The component's `selectedItem` value.
*/
Expand Down Expand Up @@ -11808,6 +11930,12 @@ declare namespace LocalJSX {
* Specifies the validation message to display under the component.
*/
"validationMessage"?: string;
/**
* The current validation state of the component.
* @readonly
* @mdn [ValidityState](https://developer.mozilla.org/en-US/docs/Web/API/ValidityState)
*/
"validity"?: MutableValidityState;
/**
* The component's `selectedOption` value.
*/
Expand Down Expand Up @@ -12764,6 +12892,12 @@ declare namespace LocalJSX {
* Specifies the validation message to display under the component.
*/
"validationMessage"?: string;
/**
* The current validation state of the component.
* @readonly
* @mdn [ValidityState](https://developer.mozilla.org/en-US/docs/Web/API/ValidityState)
*/
"validity"?: MutableValidityState;
/**
* The component's value.
*/
Expand Down
25 changes: 23 additions & 2 deletions packages/calcite-components/src/components/checkbox/checkbox.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import {
connectForm,
disconnectForm,
HiddenFormInputSlot,
MutableValidityState,
} from "../../utils/form";
import { guid } from "../../utils/guid";
import {
Expand Down Expand Up @@ -59,8 +60,7 @@ export class Checkbox
*
* When not set, the component will be associated with its ancestor form element, if any.
*/
@Prop({ reflect: true })
form: string;
@Prop({ reflect: true }) form: string;

/** The `id` attribute of the component. When omitted, a globally unique identifier is used. */
@Prop({ reflect: true, mutable: true }) guid: string;
Expand Down Expand Up @@ -100,6 +100,27 @@ export class Checkbox
/** Specifies the status of the input field, which determines message and icons. */
@Prop({ reflect: true }) status: Status = "idle";

/**
* The current validation state of the component.
*
* @readonly
* @mdn [ValidityState](https://developer.mozilla.org/en-US/docs/Web/API/ValidityState)
*/
// eslint-disable-next-line @stencil-community/strict-mutable -- updated in form util when syncing hidden input
@Prop({ mutable: true }) validity: MutableValidityState = {
valid: false,
badInput: false,
customError: false,
patternMismatch: false,
rangeOverflow: false,
rangeUnderflow: false,
stepMismatch: false,
tooLong: false,
tooShort: false,
typeMismatch: false,
valueMissing: false,
};

/** The component's value. */
@Prop() value: any;

Expand Down
22 changes: 22 additions & 0 deletions packages/calcite-components/src/components/combobox/combobox.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ import {
disconnectForm,
FormComponent,
HiddenFormInputSlot,
MutableValidityState,
submitForm,
} from "../../utils/form";
import { guid } from "../../utils/guid";
Expand Down Expand Up @@ -184,6 +185,27 @@ export class Combobox
/** Specifies the validation icon to display under the component. */
@Prop({ reflect: true }) validationIcon: string | boolean;

/**
* The current validation state of the component.
*
* @readonly
* @mdn [ValidityState](https://developer.mozilla.org/en-US/docs/Web/API/ValidityState)
*/
// eslint-disable-next-line @stencil-community/strict-mutable -- updated in form util when syncing hidden input
@Prop({ mutable: true }) validity: MutableValidityState = {
valid: false,
badInput: false,
customError: false,
patternMismatch: false,
rangeOverflow: false,
rangeUnderflow: false,
stepMismatch: false,
tooLong: false,
tooShort: false,
typeMismatch: false,
valueMissing: false,
};

/**
* Specifies the name of the component.
*
Expand Down

0 comments on commit e49902b

Please sign in to comment.