Implement quick search in closed selects

This commit is contained in:
Talia 2025-01-16 16:16:56 +01:00
parent aa93cee9fa
commit df795fe894
Signed by: darkwiiplayer
GPG key ID: 7808674088232B3E
2 changed files with 60 additions and 7 deletions

View file

@ -3,6 +3,6 @@
"browser": "src/BetterSelect.js",
"type": "module",
"license": "MIT",
"version": "1.2.2",
"version": "1.3.0",
"url": "https://darkwiiplayer.github.io/BetterSelect/"
}

View file

@ -191,14 +191,30 @@ export class BetterSelect extends HTMLElement {
})
this.addEventListener("keydown", event => {
if (event.key == " " && this.list.contains(this.shadowRoot.activeElement)) {
if (this.#internals.states.has("--open")) {
const key = event.key
if (this.#internals.states.has("--open")) {
if (key == " " && this.list.contains(this.shadowRoot.activeElement)) {
this.close()
event.preventDefault()
event.stopPropagation()
} else if (key == "Escape") {
this.close()
} else {
this.open()
}
} else if (event.key == "Escape") {
this.close()
} else {
if (key == " ") {
this.open()
} else if (key == "Escape") {
this.keyboardSearchBuffer = ""
event.preventDefault()
event.stopPropagation()
} else if (key == "Backspace") {
event.preventDefault()
event.stopPropagation()
} else if (!event.ctrlKey && !event.altKey && key.match(/^[a-zA-Z0-9]$/)) {
this.keyboardSearchAppend(key)
event.preventDefault()
event.stopPropagation()
}
}
})
@ -211,6 +227,39 @@ export class BetterSelect extends HTMLElement {
})
}
/**
* @param {String} key
*/
keyboardSearchAppend(key) {
this.searchTimeout?.abort()
this.searchTimeout = new AbortController()
const timeout = 1000 * (Number(this.getAttribute("search-timeout")) || 1)
const ref = setTimeout(()=> {
console.warn("Clearing buffer: " + this.keyboardSearchBuffer)
this.keyboardSearchBuffer = ""
}, timeout)
this.searchTimeout.signal.addEventListener("abort", () => {
window.clearTimeout(ref)
})
this.keyboardSearchBuffer = (this.keyboardSearchBuffer || "") + key
this.closedSearch(this.keyboardSearchBuffer)
}
/**
* @param {string} search
*/
closedSearch(search) {
for (const item of this.list.children) {
if (this.match(search, item)) {
this.setOption(item)
return
}
}
}
async open() {
if (this.#abortOpen) return
@ -343,4 +392,8 @@ export class BetterSelect extends HTMLElement {
}
}
}
clear() {
this.setValue(undefined, "")
}
}