From daebd0847596f04037866b33e34d983075a66d15 Mon Sep 17 00:00:00 2001 From: Cory LaViska Date: Fri, 18 Nov 2022 09:56:05 -0500 Subject: [PATCH] add validation states to all form controls; closes #1011 --- docs/resources/changelog.md | 12 ++ src/components/button/button.ts | 72 ++++++++++-- src/components/checkbox/checkbox.ts | 17 ++- src/components/color-picker/color-picker.ts | 35 +++--- src/components/input/input.ts | 23 ++-- src/components/radio-group/radio-group.ts | 19 ++-- src/components/range/range.ts | 23 ++-- src/components/select/select.ts | 19 +++- src/components/switch/switch.ts | 17 +-- src/components/textarea/textarea.ts | 19 ++-- src/internal/default-value.ts | 6 +- src/internal/form.ts | 119 ++++++++++++++++---- src/internal/shoelace-element.ts | 26 +++++ 13 files changed, 295 insertions(+), 112 deletions(-) diff --git a/docs/resources/changelog.md b/docs/resources/changelog.md index 4bdf2901e..e60361a1f 100644 --- a/docs/resources/changelog.md +++ b/docs/resources/changelog.md @@ -13,6 +13,16 @@ New versions of Shoelace are released as-needed and generally occur when a criti - 🚨 BREAKING: Removed the `fieldset` property from `` (use CSS parts if you want to keep the border) [#965](https://github.com/shoelace-style/shoelace/issues/965) - 🚨 BREAKING: Removed `base` and `label` parts from `` (use `form-control` and `form-control__label` instead) [#965](https://github.com/shoelace-style/shoelace/issues/965) - 🚨 BREAKING: Removed the `base` part from `` (style the host element directly instead) +- 🚨 BREAKING: Removed the `invalid` attribute from form controls (use `[data-invalid]` to target it with CSS) +- Added validation states to all form controls to allow styling based on various validation states [#1011](https://github.com/shoelace-style/shoelace/issues/1011) + - `data-required` - indicates that a value is required + - `data-optional` - indicates that a value is NOT required + - `data-invalid` - indicates that the form control is invalid + - `data-valid` - indicates that the form control is valid + - `data-user-invalid` - indicates the form control is invalid and the user has interacted with it + - `data-user-valid` - indicates the form control is valid and the user has interacted with it +- Added `checkValidity()` method to all form controls +- Added `reportValidity()` method to `` - Added `button--checked` to `` and `control--checked` to `` to style just the checked state [#933](https://github.com/shoelace-style/shoelace/pull/933) - Added tests for ``, ``, ``, ``, ``, ``, `` and `` [#935](https://github.com/shoelace-style/shoelace/pull/935) [#949](https://github.com/shoelace-style/shoelace/pull/949) [#951](https://github.com/shoelace-style/shoelace/pull/951) [#953](https://github.com/shoelace-style/shoelace/pull/953) @@ -37,6 +47,7 @@ New versions of Shoelace are released as-needed and generally occur when a criti - Fixed a bug in `` that prevented the `invalid` property from correctly reflecting validity sometimes [#992](https://github.com/shoelace-style/shoelace/issues/992) - Fixed a bug in `` that prevented selections from working correctly on dynamically added tree items [#963](https://github.com/shoelace-style/shoelace/issues/963) - Fixed module paths in `custom-elements.json` so they point to the dist file instead of the source file [#725](https://github.com/shoelace-style/shoelace/issues/725) +- Fixed an incorrect return value for `reportValidity()` in `` - Improved `` to improve padding and render relative to the current font size - Improved how many components display in forced-colors mode / Windows High Contrast mode - Improved `` so it's usable in forced-colors mode @@ -50,6 +61,7 @@ New versions of Shoelace are released as-needed and generally occur when a criti - Improved `` so selected items are visible in forced-colors mode - Improved `` so tabs are cleaner and easier to understand in forced-colors mode - Moved all component descriptions to `@summary` to get them within documentation tools [#962](https://github.com/shoelace-style/shoelace/pull/962) +- Refactored form controls to use the `ShoelaceFormControl` interface to improve type safety and consistency - Updated Lit to 2.4.1 - Updated Bootstrap Icons to 1.10.2 - Updated TypeScript to 4.8.4 diff --git a/src/components/button/button.ts b/src/components/button/button.ts index c9ffa9777..191a5cd3e 100644 --- a/src/components/button/button.ts +++ b/src/components/button/button.ts @@ -5,10 +5,12 @@ import { html, literal } from 'lit/static-html.js'; import { FormSubmitController } from '../../internal/form'; import ShoelaceElement from '../../internal/shoelace-element'; import { HasSlotController } from '../../internal/slot'; +import { watch } from '../../internal/watch'; import { LocalizeController } from '../../utilities/localize'; import '../icon/icon'; import '../spinner/spinner'; import styles from './button.styles'; +import type { ShoelaceFormControl } from '../../internal/shoelace-element'; import type { CSSResultGroup } from 'lit'; /** @@ -34,13 +36,13 @@ import type { CSSResultGroup } from 'lit'; * @csspart caret - The button's caret icon. */ @customElement('sl-button') -export default class SlButton extends ShoelaceElement { +export default class SlButton extends ShoelaceElement implements ShoelaceFormControl { static styles: CSSResultGroup = styles; @query('.button') button: HTMLButtonElement | HTMLLinkElement; private readonly formSubmitController = new FormSubmitController(this, { - form: (input: HTMLInputElement) => { + form: input => { // Buttons support a form attribute that points to an arbitrary form, so if this attribute it set we need to query // the form from the same root using its id if (input.hasAttribute('form')) { @@ -57,6 +59,7 @@ export default class SlButton extends ShoelaceElement { private readonly localize = new LocalizeController(this); @state() private hasFocus = false; + @state() invalid = false; /** The button's variant. */ @property({ reflect: true }) variant: 'default' | 'primary' | 'success' | 'neutral' | 'warning' | 'danger' | 'text' = @@ -90,16 +93,16 @@ export default class SlButton extends ShoelaceElement { @property() type: 'button' | 'submit' | 'reset' = 'button'; /** An optional name for the button. Ignored when `href` is set. */ - @property() name?: string; + @property() name = ''; /** An optional value for the button. Ignored when `href` is set. */ - @property() value?: string; + @property() value = ''; /** When set, the underlying button will be rendered as an `` with this `href` instead of a `