add custom states to checkbox/radio

This commit is contained in:
Cory LaViska
2024-12-17 11:12:40 -05:00
parent 8fbd0b54e4
commit 5d687f1aa0
2 changed files with 24 additions and 9 deletions

View File

@@ -36,8 +36,6 @@ import styles from './checkbox.css';
*
* @csspart base - The component's label .
* @csspart control - The square container that wraps the checkbox's checked state.
* @csspart control--checked - Matches the control part when the checkbox is checked.
* @csspart control--indeterminate - Matches the control part when the checkbox is indeterminate.
* @csspart checked-icon - The checked icon, a `<wa-icon>` element.
* @csspart indeterminate-icon - The indeterminate icon, a `<wa-icon>` element.
* @csspart label - The container that wraps the checkbox's label.
@@ -53,6 +51,11 @@ import styles from './checkbox.css';
* @cssproperty --box-shadow - The shadow effects around the edges of the checkbox.
* @cssproperty --checked-icon-color - The color of the checkbox's icon.
* @cssproperty --toggle-size - The size of the checkbox.
*
* @cssstate checked - Applied when the checkbox is checked.
* @cssstate disabled - Applied when the checkbox is disabled.
* @cssstate indeterminate - Applied when the checkbox is in an indeterminate state.
*
*/
@customElement('wa-checkbox')
export default class WaCheckbox extends WebAwesomeFormAssociatedElement {
@@ -157,20 +160,28 @@ export default class WaCheckbox extends WebAwesomeFormAssociatedElement {
}
handleValueOrCheckedChange() {
this.toggleCustomState('checked', this.checked);
// These @watch() commands seem to override the base element checks for changes, so we need to setValue for the form and and updateValidity()
this.setValue(this.checked ? this.value : null, this._value);
this.updateValidity();
}
@watch(['checked', 'indeterminate'], { waitUntilFirstUpdate: true })
@watch(['checked', 'indeterminate'])
handleStateChange() {
this.input.checked = this.checked; // force a sync update
this.input.indeterminate = this.indeterminate; // force a sync update
if (this.hasUpdated) {
this.input.checked = this.checked; // force a sync update
this.input.indeterminate = this.indeterminate; // force a sync update
}
this.toggleCustomState('checked', this.checked);
this.toggleCustomState('indeterminate', this.indeterminate);
this.updateValidity();
}
@watch('disabled')
handleDisabledChange() {
this.toggleCustomState('disabled', this.disabled);
}
protected willUpdate(changedProperties: PropertyValues<this>): void {
super.willUpdate(changedProperties);

View File

@@ -24,7 +24,6 @@ import styles from './radio.css';
*
* @csspart base - The component's base wrapper.
* @csspart control - The circular container that wraps the radio's checked state.
* @csspart control--checked - The radio control when the radio is checked.
* @csspart checked-icon - The checked icon.
* @csspart label - The container that wraps the radio's label.
*
@@ -38,6 +37,9 @@ import styles from './radio.css';
* @cssproperty --checked-icon-color - The color of the radio's checked icon.
* @cssproperty --checked-icon-scale - The size of the checked icon relative to the radio.
* @cssproperty --toggle-size - The size of the radio.
*
* @cssstate checked - Applied when the control is checked.
* @cssstate disabled - Applied when the control is disabled.
*/
@customElement('wa-radio')
export default class WaRadio extends WebAwesomeFormAssociatedElement {
@@ -92,6 +94,7 @@ export default class WaRadio extends WebAwesomeFormAssociatedElement {
@watch('checked')
handleCheckedChange() {
this.toggleCustomState('checked', this.checked);
this.setAttribute('aria-checked', this.checked ? 'true' : 'false');
this.tabIndex = this.checked ? 0 : -1;
}
@@ -105,6 +108,7 @@ export default class WaRadio extends WebAwesomeFormAssociatedElement {
@watch('disabled', { waitUntilFirstUpdate: true })
handleDisabledChange() {
this.toggleCustomState('disabled', this.disabled);
this.setAttribute('aria-disabled', this.disabled ? 'true' : 'false');
}
@@ -124,7 +128,7 @@ export default class WaRadio extends WebAwesomeFormAssociatedElement {
'radio--disabled': this.disabled,
})}
>
<span part="${`control${this.checked ? ' control--checked' : ''}`}" class="radio__control">
<span part="control" class="radio__control">
${this.checked
? html`
<svg