Compare commits

..

No commits in common. "ab7a89b41301810ac59e779b642a9355dbb67fa5" and "d689d970e030683d4f156890dc5171c9febffec4" have entirely different histories.

4 changed files with 14 additions and 76 deletions

View file

@ -53,7 +53,7 @@
<better-select name="better-selection" class="search" placeholder="Placeholder..." search-placeholder="Search..."> <better-select name="better-selection" class="search" placeholder="Placeholder..." search-placeholder="Search...">
<span slot="placeholder">Placeholder...</span> <span slot="placeholder">Placeholder...</span>
<option value="first">First value</option> <option value="first">First value</option>
<option value="second" disabled>Second value</option> <option value="second">Second value</option>
<option value="third">Third value</option> <option value="third">Third value</option>
</better-select> </better-select>

View file

@ -62,14 +62,10 @@ better-select {
padding-inline: var(--h-padding); padding-inline: var(--h-padding);
} }
&::part(item enabled):is(:hover, :focus) { &::part(item):is(:hover, :focus) {
background-color: var(--highlight); background-color: var(--highlight);
} }
&::part(item disabled) {
opacity: .6;
}
&:not(:state(open))::part(drop-down) { &:not(:state(open))::part(drop-down) {
transform: scale(100%, 70%) translate(0, -30%); transform: scale(100%, 70%) translate(0, -30%);
opacity: 0; opacity: 0;
@ -87,13 +83,4 @@ better-select {
&:state(open)::part(display)::after { &:state(open)::part(display)::after {
transform: rotate(180deg); transform: rotate(180deg);
} }
&:not([required]):state(value)::part(display)::after {
display: none;
}
&::part(clear) {
display: block;
margin-left: auto;
}
} }

View file

@ -45,8 +45,7 @@ export class BetterSelect extends HTMLElement {
* @param {string} state * @param {string} state
*/ */
setValue(value: string, state?: string): void; setValue(value: string, state?: string): void;
updateClearButton(): void; set value(arg: any);
set value(value: any);
get value(): any; get value(): any;
get valueText(): any; get valueText(): any;
setOptions(): void; setOptions(): void;
@ -61,7 +60,7 @@ export class BetterSelect extends HTMLElement {
/** /**
* @param {String} name * @param {String} name
*/ */
set name(name: string); set name(arg: string);
/** /**
* @return {String} * @return {String}
*/ */
@ -71,7 +70,7 @@ export class BetterSelect extends HTMLElement {
/** /**
* @param {Boolean} disabled * @param {Boolean} disabled
*/ */
set disabled(disabled: boolean); set disabled(arg: boolean);
get disabled(): boolean; get disabled(): boolean;
/** /**
* @param {ValidityConstraint} _constraint * @param {ValidityConstraint} _constraint
@ -85,7 +84,7 @@ export class BetterSelect extends HTMLElement {
/** /**
* @param {Boolean} required * @param {Boolean} required
*/ */
set required(required: boolean); set required(arg: boolean);
get required(): boolean; get required(): boolean;
reportValidity(): boolean; reportValidity(): boolean;
requiredChanged(): void; requiredChanged(): void;

View file

@ -154,10 +154,7 @@ export class BetterSelect extends HTMLElement {
[part="display-text"]:empty { [part="display-text"]:empty {
display: none; display: none;
} }
:not(#text:empty + *)[name="placeholder"] { :not(:empty + *)[name="placeholder"] {
display: none;
}
#text:empty ~ *[name="clear"] {
display: none; display: none;
} }
[part="drop-down"], [part="item"] { [part="drop-down"], [part="item"] {
@ -188,12 +185,10 @@ export class BetterSelect extends HTMLElement {
[part="list"] { [part="list"] {
display: contents; display: contents;
} }
[part~="item"] { [part="item"] {
display: block; display: block;
cursor: pointer;
white-space: nowrap; white-space: nowrap;
&[part~="enabled"] {
cursor: pointer;
}
} }
[part="item"]:focus { [part="item"]:focus {
font-weight: bold; font-weight: bold;
@ -208,13 +203,6 @@ export class BetterSelect extends HTMLElement {
[part="list"] { display: none; } [part="list"] { display: none; }
slot[name="loading"] { display: block; } slot[name="loading"] { display: block; }
} }
slot[name="clear"] > button {
all: unset;
transform: rotate(45deg);
&::after {
content: "+";
}
}
` `
/** @type {HTMLElement} */ /** @type {HTMLElement} */
@ -242,11 +230,6 @@ export class BetterSelect extends HTMLElement {
<slot name="placeholder" aria-hidden="true"> <slot name="placeholder" aria-hidden="true">
<span part="placeholder" id="placeholder" aria-hidden="true"></span> <span part="placeholder" id="placeholder" aria-hidden="true"></span>
</slot> </slot>
<template id="clear-template">
<slot name="clear" part="clear">
<button></button>
</slot>
</template>
</div> </div>
<dialog id="dialog" part="drop-down"> <dialog id="dialog" part="drop-down">
<slot name="top"></slot> <slot name="top"></slot>
@ -275,11 +258,9 @@ export class BetterSelect extends HTMLElement {
/** @type {HTMLLIElement} */ /** @type {HTMLLIElement} */
const item = event.target.closest("#list > li") const item = event.target.closest("#list > li")
if (item) { if (item) {
if (!item.part.contains("disabled")) { this.setOption(item)
this.setOption(item) this.dispatchEvent(new InputEvent("input", {bubbles: true}))
this.dispatchEvent(new InputEvent("input", {bubbles: true})) this.close()
this.close()
}
} else if (!this.#states.has("open")) { } else if (!this.#states.has("open")) {
this.open() this.open()
} else if (this.display.contains(event.target) || this.display.contains(event.target.closest("[slot]")?.assignedSlot)) { } else if (this.display.contains(event.target) || this.display.contains(event.target.closest("[slot]")?.assignedSlot)) {
@ -471,27 +452,9 @@ export class BetterSelect extends HTMLElement {
this.#internals.setFormValue(value, state) this.#internals.setFormValue(value, state)
this.text.innerText = state this.text.innerText = state
this.#states.toggle("value", value)
this.updateClearButton()
this.setValidity() this.setValidity()
} }
updateClearButton() {
const template = /** @type {HTMLTemplateElement} */(this.shadowRoot.getElementById("clear-template"))
const clearButton = template.nextElementSibling
if (this.required || this.#value.value === undefined) {
clearButton?.remove()
} else if (!clearButton && !this.required) {
const button = template.content.cloneNode(true)
template.after(button)
template.nextElementSibling.addEventListener("click", event => {
event.stopPropagation()
this.clear()
})
}
}
get value() { return this.#value.value } get value() { return this.#value.value }
set value(value) { set value(value) {
if (value === undefined) { if (value === undefined) {
@ -512,15 +475,7 @@ export class BetterSelect extends HTMLElement {
setOptions() { setOptions() {
this.list.replaceChildren() this.list.replaceChildren()
for (const option of this.options) { for (const option of this.options) {
const fragment = f`<li tabindex="0" part="item" data-value="${option.value}">${option.innerText}</li>` this.list.append(f`<li tabindex="0" part="item" data-value="${option.value}">${option.innerText}</li>`)
const li = fragment.querySelector("li")
if (option.disabled) {
li.part.add("disabled")
li.removeAttribute("tabindex")
} else {
li.part.add("enabled")
}
this.list.append(fragment)
if (this.value == undefined && option.selected) { if (this.value == undefined && option.selected) {
this.value = option.value this.value = option.value
} }
@ -602,10 +557,7 @@ export class BetterSelect extends HTMLElement {
reportValidity() { return this.#internals.reportValidity() } reportValidity() { return this.#internals.reportValidity() }
requiredChanged() { requiredChanged() { this.setValidity() }
this.updateClearButton()
this.setValidity()
}
/** /**
* @param {String} name * @param {String} name