Description
Description
Slot markup follows special rules in relation to the Shadow DOM:
DOM elements that are passed to a component via slots aren't owned by the component and aren't in the component's shadow tree. To access DOM elements passed via slots, call
this.querySelector()
. The component doesn't own these elements, so you don't usetemplate
.
Unfortunately, there is no corresponding tracking for focused elements when the focused elements are passed in by slot; there is no this.activeElement
, for example, which only returns focused elements that are part of slot-passed-in markup.
Steps to Reproduce
I've included a sandboxed repro below:
https://developer.salesforce.com/docs/component-library/tools/playground/WXAr7bdAW/12/edit
This is the specific bit that ends up being problematic:
//focusableElems is a list where the first element is injected by slot
if (focusableElems.length > 0) {
focusableElems[0].focus();
console.log(this.template.activeElement) // output: null
}
If, for example, the snippet is updated to use focusableElems[1].focus()
, then this.template.activeElement
is immediately set.
Expected Results
Either this.template.activeElement
tracks all markup, independent of whether it is part of the component's Shadow DOM, or an alternative means of tracking focus for injected markup is made available.
Actual Results
this.template.activeElement
returns null
when markup injected via slot is focused, and there is no alternative means to track selected elements.
Version
- LWC: 1.6.0
Possible Solution
I'd like to hear thoughts on also exposing an activeElement
property on the component itself, which will act just like the template
version of activeElement
while maintaining the existing separation of concerns that has already been built into distinguishing between component-owned markup versus what's being passed in.
Related to: WICG/webcomponents#358 and WICG/webcomponents#479
Activity