diff --git a/docs/docs/resources/changelog.md b/docs/docs/resources/changelog.md
index 21f637e6e..8a9653b62 100644
--- a/docs/docs/resources/changelog.md
+++ b/docs/docs/resources/changelog.md
@@ -12,8 +12,9 @@ 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
+## Next
+- Fixed a bug in `` where it would not properly change its "checked" state when its property changed.
- Updated the Japanese translation
## 3.0.0-alpha.7
@@ -130,4 +131,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..3b9e24c2c 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