I've found that it seems impossible to focus on any element in the shadow dom
- we have shadow options like
delegatesFocus, and that's great, but not what i'm talking about - i also see articles about determining which element has focus, but that's not it either
- simply put, when i call
myShadowElement.focus()on a text input or button, it simply does nothing at all
this seems like a crippling problem in my efforts to make a good web component for modal dialogs. i'll also need this control to trap the focus within the dialog
is this really impossible? what workarounds might i consider?
currently, my best option seems to be to cancel the shadow-dom work, and bring the whole thing into the light dom — but that stinks, because i'd love the have the CSS encapsulation
edit turns out that the issue does NOT reproduce.
i suspect my problem was that it only seemed that way from the perspective of the developer console. doh! you can't focus anything from the debugging javascript console, because the browser's focus is in the devtools. of course!
const {light, shadow, say, sleep} = boringSetup()
void async function repeatingDemo() {
light.querySelector("input").focus()
await say(2, "focus light input")
shadow.querySelector("input").focus()
await say(2, "focus shadow input")
await repeatingDemo()
}()
function boringSetup() {
const message = document.createElement("p")
const light = document.createElement("div")
const host = document.createElement("div")
const shadow = host.attachShadow({
mode: "closed",
})
light.innerHTML = `<input type="text" placeholder="light"/>`
shadow.innerHTML = `<input type="text" placeholder="shadow"/>`
document.body.appendChild(message)
document.body.appendChild(light)
document.body.appendChild(host)
const sleep = async seconds => new Promise(
resolve => setTimeout(resolve, seconds * 1000)
)
const say = async(seconds, words) => {
message.textContent = words
await sleep(seconds)
}
return {light, shadow, say}
}