From aad018dad0a8cd3d3e0b98fb126c3202f561a935 Mon Sep 17 00:00:00 2001 From: DarkWiiPlayer Date: Thu, 7 Aug 2025 19:38:16 +0200 Subject: [PATCH] Add closed arrow key navigation --- src/better-select.js | 41 ++++++++++++++++++++++++++++++++++++----- 1 file changed, 36 insertions(+), 5 deletions(-) diff --git a/src/better-select.js b/src/better-select.js index 118e639..439ae18 100644 --- a/src/better-select.js +++ b/src/better-select.js @@ -126,6 +126,9 @@ export class BetterSelect extends HTMLElement { #abortOpen #value = {} + /** @type {number} */ + #index = undefined + #internals = this.attachInternals() #states = new StateAttributeSet(this, this.#internals.states) @@ -313,6 +316,14 @@ export class BetterSelect extends HTMLElement { this.keyboardSearchAppend(key) event.preventDefault() event.stopPropagation() + } else if (key == "Delete") { + this.clear() + } else if (key == "ArrowDown") { + event.preventDefault() + this.next() + } else if (key == "ArrowUp") { + event.preventDefault() + this.previous() } } }) @@ -459,14 +470,17 @@ export class BetterSelect extends HTMLElement { /** @param {HTMLElement} option */ setOption(option) { - return this.setValue(option.dataset.value, option.innerText) + return this.setValue(Number(option.dataset.index), option.dataset.value, option.innerText) } /** + * @param {number} index * @param {string} value * @param {string} state */ - setValue(value, state=value) { + setValue(index, value, state=value) { + this.#index = Number(index) + this.#value = {value, state} this.dispatchEvent(new Event("change", {bubbles: true})); this.#internals.setFormValue(value, state) @@ -498,9 +512,10 @@ export class BetterSelect extends HTMLElement { if (value === undefined) { this.clear() } else { + let index = 0 for (const option of this.options) { if (option.value === String(value)) { - this.setValue(option.value, option.innerText) + this.setValue(index++, option.value, option.innerText) return } } @@ -512,8 +527,9 @@ export class BetterSelect extends HTMLElement { setOptions() { this.list.replaceChildren() + let idx = 0 for (const option of this.options) { - const fragment = f`
  • ${option.innerText}
  • ` + const fragment = f`
  • ${option.innerText}
  • ` const li = fragment.querySelector("li") if (option.disabled) { li.part.add("disabled") @@ -555,7 +571,7 @@ export class BetterSelect extends HTMLElement { get form() { return this.#internals.form } clear() { - this.setValue(undefined, "") + this.setValue(undefined, undefined, "") } /** @@ -571,6 +587,21 @@ export class BetterSelect extends HTMLElement { return "Please select an option." } + next() { + const index = (this.#index ?? -1) + 1 + const item = /** @type {HTMLElement} */(this.list.children[index]) + if (item) { + this.setOption(item) + } + } + + previous() { + const index = (this.#index ?? this.options.length) - 1 + const item = /** @type {HTMLElement} */(this.list.children[index]) + if (item) { + this.setOption(item) + } + } setValidity() { if (this.required) {