Skip to content
Merged
2 changes: 2 additions & 0 deletions packages/webawesome/docs/docs/resources/changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ Components with the <wa-badge variant="warning">Experimental</wa-badge> badge sh
<small>TBD</small>

- Added `wa-button` class for styling `<a>` elements as buttons [pr:2040]
- Fixed a bug in `<wa-select>` where options with `selected` set via framework property binding (e.g., Vue's `:selected`) were not respected when `with-clear` was present [pr:1985]
- Fixed a bug `<wa-color-picker>` that prevented it from flipping horizontally when position to the right of the viewport. [pr:2024]
- Fixed a bug by adding `color: inherit` to the `<wa-dialog>` and `<wa-drawer>` styles so they inherit the text color from the document context rather than the browser default. [pr:2064]
- Fixed a bug that caused 0ms animations to not fire correctly in the internal `animateWithClass()` function [pr#2068]
Expand All @@ -30,6 +31,7 @@ Components with the <wa-badge variant="warning">Experimental</wa-badge> badge sh

<small>February 4, 2026</small>

- Fixed a bug in `<wa-select>` where the `selected` attribute on `<wa-option>` was ignored when `with-clear` was present [#1922]
- Added `<wa-file-input>` as an experimental pro component [issue:1240]
- Added `<wa-sparkline>` as an experimental pro component
- Added `<wa-number-input>` as an experimental component for numeric input with stepper buttons [issue:1688]
Expand Down
25 changes: 22 additions & 3 deletions packages/webawesome/src/components/option/option.ts
Original file line number Diff line number Diff line change
Expand Up @@ -147,9 +147,13 @@ export default class WaOption extends WebAwesomeElement {
if (changedProperties.has('defaultSelected')) {
// We cast to <wa-select> because it shares the same API as combobox
if (!this.closest<WaSelect>('wa-combobox, wa-select')?.hasInteracted) {
const oldVal = this.selected;
this.selected = this.defaultSelected;
this.requestUpdate('selected', oldVal);
// Only sync if defaultSelected is becoming true
// This prevents overwriting `selected` when it was set directly by frameworks like Vue
if (this.defaultSelected) {
const oldVal = this.selected;
this.selected = this.defaultSelected;
this.requestUpdate('selected', oldVal);
}
}
}
super.willUpdate(changedProperties);
Expand Down Expand Up @@ -183,6 +187,21 @@ export default class WaOption extends WebAwesomeElement {
}
}

protected firstUpdated(changedProperties: PropertyValues<this>) {
super.firstUpdated(changedProperties);

// If the `selected` property was set directly (e.g., by Vue's :selected binding),
// notify the parent select to update its selection. This is needed because
// Vue binds to the `selected` property instead of the `defaultSelected` property
// when using `:selected="true"` syntax.
if (this.selected && !this.defaultSelected) {
const parent = this.closest<WaSelect>('wa-select, wa-combobox');
if (parent && !parent.hasInteracted) {
parent.selectionChanged?.();
}
}
}
Comment on lines +190 to +203
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤔 I'm a little worried about this firing many times for initial page load as selectionChanged() is going to iterate all <wa-option> elements everytime a new one is added and could make this fire many times, and to me seems like an expensive operation.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any suggestions to move this forward?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think I'd feel safer with something like a debounced selectionChanged tbh, but thats just my personal preference.

This is probably fine tbh


private updateDefaultLabel() {
let oldValue = this.defaultLabel;
this.defaultLabel = getText(this).trim();
Expand Down
41 changes: 41 additions & 0 deletions packages/webawesome/src/components/select/select.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -857,6 +857,47 @@ describe('<wa-select>', () => {
const values = formData.getAll('test');
expect(values).to.have.members(['option with spaces', 'another option']);
});

it('should select options using the selected attribute with with-clear', async () => {
// Issue #1922: selected attribute was ignored when with-clear was present
const el = await fixture<WaSelect>(html`
<wa-select with-clear>
<wa-option value="option-1">Option 1</wa-option>
<wa-option value="option-2" selected>Option 2</wa-option>
<wa-option value="option-3">Option 3</wa-option>
</wa-select>
`);

expect(el.value).to.equal('option-2');
expect(el.displayInput.value).to.equal('Option 2');
});

it('should select options with selected attribute, with-clear, and placeholder', async () => {
// This is the exact combination reported in bug #1922
const el = await fixture<WaSelect>(html`
<wa-select placeholder="Placeholder" with-clear>
<wa-option value="option-1" selected>Option 1</wa-option>
<wa-option value="option-2">Option 2</wa-option>
<wa-option value="option-3">Option 3</wa-option>
</wa-select>
`);

expect(el.value).to.equal('option-1');
expect(el.displayInput.value).to.equal('Option 1');
});

it('should select multiple options with selected attribute and with-clear', async () => {
const el = await fixture<WaSelect>(html`
<wa-select multiple with-clear>
<wa-option value="option-1" selected>Option 1</wa-option>
<wa-option value="option-2" selected>Option 2</wa-option>
<wa-option value="option-3">Option 3</wa-option>
</wa-select>
`);

expect(el.value).to.have.members(['option-1', 'option-2']);
expect(el.value).to.have.length(2);
});
});

it('should allow interaction after being disabled and re-enabled', async () => {
Expand Down
1 change: 0 additions & 1 deletion packages/webawesome/src/components/select/select.ts
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,6 @@ export default class WaSelect extends WebAwesomeFormAssociatedElement {
private selectionOrder: Map<string, number> = new Map();
private typeToSelectString = '';
private typeToSelectTimeout: number;

@query('.select') popup: WaPopup;
@query('.combobox') combobox: HTMLSlotElement;
@query('.display-input') displayInput: HTMLInputElement;
Expand Down