From cada3646d36cc355146d7ac280c656c951195773 Mon Sep 17 00:00:00 2001 From: DarkWiiPlayer Date: Thu, 7 Aug 2025 14:53:42 +0200 Subject: [PATCH] Allow disabling of individual options --- index.html | 2 +- src/better-select.css | 6 +++++- src/better-select.js | 24 ++++++++++++++++++------ 3 files changed, 24 insertions(+), 8 deletions(-) diff --git a/index.html b/index.html index 55463e2..f0d04c1 100644 --- a/index.html +++ b/index.html @@ -53,7 +53,7 @@ Placeholder... - + diff --git a/src/better-select.css b/src/better-select.css index 801a59a..98def13 100644 --- a/src/better-select.css +++ b/src/better-select.css @@ -62,10 +62,14 @@ better-select { padding-inline: var(--h-padding); } - &::part(item):is(:hover, :focus) { + &::part(item enabled):is(:hover, :focus) { background-color: var(--highlight); } + &::part(item disabled) { + opacity: .6; + } + &:not(:state(open))::part(drop-down) { transform: scale(100%, 70%) translate(0, -30%); opacity: 0; diff --git a/src/better-select.js b/src/better-select.js index f0d9299..5c7487d 100644 --- a/src/better-select.js +++ b/src/better-select.js @@ -185,10 +185,12 @@ export class BetterSelect extends HTMLElement { [part="list"] { display: contents; } - [part="item"] { + [part~="item"] { display: block; - cursor: pointer; white-space: nowrap; + &[part~="enabled"] { + cursor: pointer; + } } [part="item"]:focus { font-weight: bold; @@ -258,9 +260,11 @@ export class BetterSelect extends HTMLElement { /** @type {HTMLLIElement} */ const item = event.target.closest("#list > li") if (item) { - this.setOption(item) - this.dispatchEvent(new InputEvent("input", {bubbles: true})) - this.close() + if (!item.part.contains("disabled")) { + this.setOption(item) + this.dispatchEvent(new InputEvent("input", {bubbles: true})) + this.close() + } } else if (!this.#states.has("open")) { this.open() } else if (this.display.contains(event.target) || this.display.contains(event.target.closest("[slot]")?.assignedSlot)) { @@ -475,7 +479,15 @@ export class BetterSelect extends HTMLElement { setOptions() { this.list.replaceChildren() for (const option of this.options) { - this.list.append(f`
  • ${option.innerText}
  • `) + const fragment = f`
  • ${option.innerText}
  • ` + 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) { this.value = option.value }