mirror of
https://github.com/shoelace-style/webawesome.git
synced 2026-01-12 12:09:26 +00:00
fix select to use selected options
This commit is contained in:
@@ -6,6 +6,53 @@ native: select
|
||||
icon: select
|
||||
---
|
||||
|
||||
```html {.example}
|
||||
<form id="base-example">
|
||||
<wa-select name="select-1" value="option-2">
|
||||
<wa-option value="option-1">Option 1</wa-option>
|
||||
<wa-option value="option-2">Option 2</wa-option>
|
||||
<wa-option value="option-3">Option 3</wa-option>
|
||||
<wa-option value="option-4">Option 4</wa-option>
|
||||
<wa-option value="option-5">Option 5</wa-option>
|
||||
<wa-option value="option-6">Option 6</wa-option>
|
||||
</wa-select>
|
||||
<br>
|
||||
<wa-select name="select-2" multiple value="option-4">
|
||||
<wa-option value="option-1">Option 1</wa-option>
|
||||
<wa-option value="option-2">Option 2</wa-option>
|
||||
<wa-option value="option-3">Option 3</wa-option>
|
||||
<wa-option value="option-4">Option 4</wa-option>
|
||||
<wa-option value="option-5">Option 5</wa-option>
|
||||
<wa-option value="option-6">Option 6</wa-option>
|
||||
</wa-select>
|
||||
<br>
|
||||
<wa-button type="reset">Reset</wa-button>
|
||||
</form>
|
||||
<br>
|
||||
<pre><code id="formdata"></code></pre>
|
||||
<script type="module">
|
||||
const form = document.querySelector("#base-example")
|
||||
function showFormData() {
|
||||
const code = document.querySelector("#formdata")
|
||||
const formdata = new FormData(form)
|
||||
const obj = {}
|
||||
for (const key of formdata.keys()) {
|
||||
obj[key] = formdata.getAll(key).length > 1 ? formdata.getAll(key) : formdata.get(key)
|
||||
}
|
||||
code.innerHTML = JSON.stringify(obj, null, 2)
|
||||
}
|
||||
form.addEventListener("change", (e) => {
|
||||
showFormData()
|
||||
})
|
||||
await customElements.whenDefined("wa-select")
|
||||
await customElements.whenDefined("wa-option")
|
||||
setTimeout(() => {
|
||||
showFormData()
|
||||
})
|
||||
</script>
|
||||
|
||||
```
|
||||
|
||||
```html {.example}
|
||||
<wa-select>
|
||||
<wa-option value="option-1">Option 1</wa-option>
|
||||
@@ -400,4 +447,3 @@ This can be hard to conceptualize, so heres a fairly large example showing how l
|
||||
container.addEventListener("submit", handleLazySubmit)
|
||||
</script>
|
||||
```
|
||||
|
||||
|
||||
@@ -46,8 +46,6 @@ export default class WaOption extends WebAwesomeElement {
|
||||
// Set via the parent select
|
||||
@state() current = false;
|
||||
|
||||
@state() selected = false;
|
||||
|
||||
/**
|
||||
* The option's value. When selected, the containing form control will receive this value. The value must be unique
|
||||
* from other options in the same group. Values may not contain spaces, as spaces are used as delimiters when listing
|
||||
@@ -56,7 +54,11 @@ export default class WaOption extends WebAwesomeElement {
|
||||
@property({ reflect: true }) value = '';
|
||||
|
||||
/** Draws the option in a disabled state, preventing selection. */
|
||||
@property({ type: Boolean, reflect: true }) disabled = false;
|
||||
@property({ type: Boolean }) disabled = false;
|
||||
|
||||
@property({ type: Boolean, attribute: false }) selected = false
|
||||
|
||||
@property({ type: Boolean, attribute: "selected" }) defaultSelected = false
|
||||
|
||||
_label: string = '';
|
||||
/**
|
||||
@@ -136,6 +138,17 @@ export default class WaOption extends WebAwesomeElement {
|
||||
}
|
||||
};
|
||||
|
||||
protected willUpdate(changedProperties: PropertyValues<this>): void {
|
||||
if (changedProperties.has('defaultSelected')) {
|
||||
if (!this.closest("wa-select")?.hasInteracted) {
|
||||
const oldVal = this.selected
|
||||
this.selected = this.defaultSelected
|
||||
this.requestUpdate("selected", oldVal)
|
||||
}
|
||||
}
|
||||
super.willUpdate(changedProperties)
|
||||
}
|
||||
|
||||
updated(changedProperties: PropertyValues<this>) {
|
||||
super.updated(changedProperties);
|
||||
|
||||
@@ -146,6 +159,7 @@ export default class WaOption extends WebAwesomeElement {
|
||||
if (changedProperties.has('selected')) {
|
||||
this.setAttribute('aria-selected', this.selected ? 'true' : 'false');
|
||||
this.customStates.set('selected', this.selected);
|
||||
this.closest("wa-select")?.selectionChanged?.()
|
||||
}
|
||||
|
||||
if (changedProperties.has('value')) {
|
||||
@@ -155,12 +169,6 @@ export default class WaOption extends WebAwesomeElement {
|
||||
this.value = String(this.value);
|
||||
}
|
||||
|
||||
if (this.value.includes(' ')) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.error(`Option values cannot include a space. All spaces have been replaced with underscores.`, this);
|
||||
this.value = this.value.replace(/ /g, '_');
|
||||
}
|
||||
|
||||
this.handleDefaultSlotChange();
|
||||
}
|
||||
|
||||
|
||||
@@ -127,12 +127,7 @@ export default class WaSelect extends WebAwesomeFormAssociatedElement {
|
||||
private _defaultValue: string | string[] = '';
|
||||
|
||||
@property({
|
||||
attribute: 'value',
|
||||
reflect: true,
|
||||
converter: {
|
||||
fromAttribute: (value: string) => value.split(' '),
|
||||
toAttribute: (value: string | string[]) => (Array.isArray(value) ? value.join(' ') : value),
|
||||
},
|
||||
attribute: false,
|
||||
})
|
||||
set defaultValue(val: string | string[]) {
|
||||
this._defaultValue = this.convertDefaultValue(val);
|
||||
@@ -154,29 +149,33 @@ export default class WaSelect extends WebAwesomeFormAssociatedElement {
|
||||
const isMultiple = this.multiple || this.hasAttribute('multiple');
|
||||
|
||||
if (!isMultiple && Array.isArray(val)) {
|
||||
val = val.join(' ');
|
||||
val = val[0];
|
||||
}
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
private _value: string[] | undefined;
|
||||
@property({ attribute: false })
|
||||
@property({ attribute: "value", reflect: false })
|
||||
set value(val: string | string[]) {
|
||||
let oldValue = this.value;
|
||||
|
||||
if ((val as any) instanceof FormData) {
|
||||
val = (val as unknown as FormData).getAll(this.name) as string[]
|
||||
}
|
||||
|
||||
if (!Array.isArray(val)) {
|
||||
val = val.split(' ');
|
||||
}
|
||||
|
||||
if (!this._value || this._value.join(' ') !== val.join(' ')) {
|
||||
// if (!this._value || this._value.join(' ') !== val.join(' ')) {
|
||||
this._value = val;
|
||||
let newValue = this.value;
|
||||
|
||||
if (newValue !== oldValue) {
|
||||
this.requestUpdate('value', oldValue);
|
||||
}
|
||||
}
|
||||
// }
|
||||
}
|
||||
|
||||
get value() {
|
||||
@@ -645,7 +644,10 @@ export default class WaSelect extends WebAwesomeFormAssociatedElement {
|
||||
const newSelectedOptions = Array.isArray(option) ? option : [option];
|
||||
|
||||
// Clear existing selection
|
||||
allOptions.forEach(el => (el.selected = false));
|
||||
allOptions.forEach(el => {
|
||||
if (newSelectedOptions.includes(el)) { return }
|
||||
el.selected = false
|
||||
});
|
||||
|
||||
// Set the new selection
|
||||
if (newSelectedOptions.length) {
|
||||
@@ -847,6 +849,11 @@ export default class WaSelect extends WebAwesomeFormAssociatedElement {
|
||||
this.value = this.defaultValue;
|
||||
super.formResetCallback();
|
||||
this.handleValueChange();
|
||||
|
||||
this.updateComplete.then(() => {
|
||||
this.dispatchEvent(new InputEvent('input', { bubbles: true, composed: true }));
|
||||
this.dispatchEvent(new Event('change', { bubbles: true, composed: true }));
|
||||
})
|
||||
}
|
||||
|
||||
render() {
|
||||
|
||||
Reference in New Issue
Block a user