From 812badd721eb8f9829cbf7ad72c9e060247da7ee Mon Sep 17 00:00:00 2001 From: Konnor Rogers Date: Mon, 23 Dec 2024 16:39:16 -0500 Subject: [PATCH 1/2] fix switch --- docs/docs/resources/changelog.md | 6 +++- src/components/switch/switch.test.ts | 13 +++++++ src/components/switch/switch.ts | 51 ++++++++++++++-------------- 3 files changed, 43 insertions(+), 27 deletions(-) diff --git a/docs/docs/resources/changelog.md b/docs/docs/resources/changelog.md index d40176650..20247328e 100644 --- a/docs/docs/resources/changelog.md +++ b/docs/docs/resources/changelog.md @@ -12,6 +12,10 @@ Components with the Experimental bad During the alpha period, things might break! We take breaking changes very seriously, but sometimes they're necessary to make the final product that much better. We appreciate your patience! ::: +## Next + +- Fixed a bug in `` where it would not properly change its "checked" state when its property changed. + ## 3.0.0-alpha.7 - Renamed applied.css to webawesome.css @@ -126,4 +130,4 @@ Here's a list of some of the things that have changed since Shoelace v2. For que Did we miss something? [Let us know!](https://github.com/shoelace-style/webawesome-alpha/discussions) -Are you coming from Shoelace? [The 2.x changelog can be found here.](https://shoelace.style/resources/changelog/) +Are you coming from Shoelace? [The 2.x changelog can be found here.](https://shoelace.style/resources/changelog/) \ No newline at end of file diff --git a/src/components/switch/switch.test.ts b/src/components/switch/switch.test.ts index 7240712f5..bfbd20b40 100644 --- a/src/components/switch/switch.test.ts +++ b/src/components/switch/switch.test.ts @@ -328,6 +328,19 @@ describe('', () => { await aTimeout(10); expect(window.scrollY).to.equal(0); }); + + // https://github.com/shoelace-style/webawesome-alpha/discussions/124 + it("Should properly flag changes to checked and reflect", async () => { + const el = await fixture(html``) + await el.updateComplete + expect(el.checked).to.equal(false) + + el.checked = true + + await el.updateComplete + + expect(el.checked).to.equal(true) + }) }); } }); diff --git a/src/components/switch/switch.ts b/src/components/switch/switch.ts index d60c458e8..54b451efa 100644 --- a/src/components/switch/switch.ts +++ b/src/components/switch/switch.ts @@ -1,6 +1,6 @@ import type { PropertyValues } from 'lit'; import { html } from 'lit'; -import { customElement, property, query, state } from 'lit/decorators.js'; +import { customElement, property, query } from 'lit/decorators.js'; import { classMap } from 'lit/directives/class-map.js'; import { ifDefined } from 'lit/directives/if-defined.js'; import { live } from 'lit/directives/live.js'; @@ -68,30 +68,18 @@ export default class WaSwitch extends WebAwesomeFormAssociatedElement { /** The name of the switch, submitted as a name/value pair with form data. */ @property({ reflect: true }) name: string | null = null; - private _value: string | null = null; + private _value: string | null = this.getAttribute('value') ?? null; - /** The current value of the switch, submitted as a name/value pair with form data. */ + /** The value of the switch, submitted as a name/value pair with form data. */ get value(): string | null { - if (this.valueHasChanged) { - return this._value; - } - - return this._value ?? this.defaultValue; + return this._value ?? 'on'; } - @state() + @property({ reflect: true }) set value(val: string | null) { - if (this._value === val) { - return; - } - - this.valueHasChanged = true; this._value = val; } - /** The default value of the form control. Primarily used for resetting the form control. */ - @property({ attribute: 'value', reflect: true }) defaultValue: string | null = this.getAttribute('value') || null; - /** The switch's size. */ @property({ reflect: true }) size: 'small' | 'medium' | 'large' = 'medium'; @@ -166,23 +154,24 @@ export default class WaSwitch extends WebAwesomeFormAssociatedElement { protected willUpdate(changedProperties: PropertyValues): void { super.willUpdate(changedProperties); - if (changedProperties.has('defaultChecked') || changedProperties.has('value') || changedProperties.has('checked')) { + if (changedProperties.has('defaultChecked')) { + if (!this.hasInteracted) { + this.checked = this.defaultChecked; + } + } + + if (changedProperties.has('value') || changedProperties.has('checked')) { this.handleValueOrCheckedChange(); } } handleValueOrCheckedChange() { - this.handleDefaultCheckedChange(); - this.value = this.checked ? this.value || 'on' : null; - - if (this.input) { - this.input.checked = this.checked; // force a sync update - } - - this.setValue(this.value, this.value); + // 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('defaultChecked') handleDefaultCheckedChange() { if (!this.hasInteracted && this.checked !== this.defaultChecked) { this.checked = this.defaultChecked; @@ -190,6 +179,16 @@ export default class WaSwitch extends WebAwesomeFormAssociatedElement { } } + @watch(['checked']) + handleStateChange() { + if (this.hasUpdated) { + this.input.checked = this.checked; // force a sync update + } + + this.toggleCustomState('checked', this.checked); + this.updateValidity(); + } + @watch('disabled', { waitUntilFirstUpdate: true }) handleDisabledChange() { // Disabled form controls are always valid From 1a8908acf7e1dc1c672a4f169afe6d862ffa1faf Mon Sep 17 00:00:00 2001 From: Konnor Rogers Date: Mon, 23 Dec 2024 16:39:32 -0500 Subject: [PATCH 2/2] prettier --- src/components/switch/switch.test.ts | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/components/switch/switch.test.ts b/src/components/switch/switch.test.ts index bfbd20b40..3b9e24c2c 100644 --- a/src/components/switch/switch.test.ts +++ b/src/components/switch/switch.test.ts @@ -330,17 +330,17 @@ describe('', () => { }); // https://github.com/shoelace-style/webawesome-alpha/discussions/124 - it("Should properly flag changes to checked and reflect", async () => { - const el = await fixture(html``) - await el.updateComplete - expect(el.checked).to.equal(false) + it('Should properly flag changes to checked and reflect', async () => { + const el = await fixture(html``); + await el.updateComplete; + expect(el.checked).to.equal(false); - el.checked = true + el.checked = true; - await el.updateComplete + await el.updateComplete; - expect(el.checked).to.equal(true) - }) + expect(el.checked).to.equal(true); + }); }); } });