lwc icon indicating copy to clipboard operation
lwc copied to clipboard

Be homogenous to traverse the parent DOM between shadow dom and `lwc:render-mode="light"` mode

Open rochejul opened this issue 1 year ago • 1 comments

Is your feature request related to a problem? Please describe.

When we don't use the light mode (the shadow mode), we are able to find our parent element by using the following snippet: this.template?.host

However when the light dom mode is enabled, this snippet failed and worth, we don't have an easy (and safe way) to go on the parent (no parentElement for example) and we should something like this?.firstElementChild?.parentElement where we took the assumption the template contains a visible element.

Here an example to illustrate the issue: https://stackblitz.com/edit/salesforce-lwc-jujury?file=src%2Fmodules%2Fx%2Flight%2Flight.js

Describe the solution you'd like

Ideally, we should still have a similar this.template?.host, or at least to have this.parentElement

Describe alternatives you've considered At this time, we use this?.firstElementChild?.parentElement. but it means the component's template should have at least one visible elemlent

Additional context n/a

rochejul avatar May 23 '24 07:05 rochejul

@rochejul Why do you need access to the host element itself? Is there a specific property that you need that is not being exposed?

(In general, this is supposed to behave "close enough" to the actual HTMLElement object, although in practice the proxying does not perfectly emulate it.)

nolanlawson avatar May 30 '24 16:05 nolanlawson

Hi @nolanlawson Well, I would like at least to have the same similarity between this.template?.host in shadow mode and this in light mode.

For example, in shadow mode, I am able to inspect the parent dom and then to ensure I am in the "right place" (I want to ensure to be used only with some components, without using private events which are not really private). In light mode, I cannot inspect the parent dom (the parentElement or parentNode are omitted). So at the end, we have some gaps between the two mode

rochejul avatar Jun 03 '24 06:06 rochejul

@rochejul The fact that this does not give you a real HTMLElement is a legacy behavior of LWC (mostly due to Locker and lack of JS private properties at the time).

Since it might be a while before we can fix that, maybe something like this.selfAsElement or this.elementSelf would solve your use case?

renderedCallback() {
  console.log(this); // LWC's shim that emulates the `HTMLElement`
  console.log(this.elementSelf); // the actual `HTMLElement`, in both shadow and light DOM
}

nolanlawson avatar Jun 03 '24 14:06 nolanlawson

Hi

Sure, it could be a good idea (similarly to globalThis) to have a property which abstracts regardless of the context we are!

On Mon, Jun 3, 2024 at 4:50 PM Nolan Lawson @.***> wrote:

@rochejul https://github.com/rochejul The fact that this does not give you a real HTMLElement is a legacy behavior of LWC (mostly due to Locker and lack of JS private properties at the time).

Since it might be a while before we can fix that, maybe something like this.selfAsElement or this.elementSelf would solve your use case?

renderedCallback() { console.log(this); // LWC's shim that emulates the HTMLElement console.log(this.elementSelf); // the actual HTMLElement, in both shadow and light DOM}

— Reply to this email directly, view it on GitHub https://github.com/salesforce/lwc/issues/4219#issuecomment-2145402584, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAB32B46I366KK473GJQMYLZFR7DTAVCNFSM6AAAAABIFALR3SVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDCNBVGQYDENJYGQ . You are receiving this because you were mentioned.Message ID: @.***>

-- Julien Roche Software Engineering LMTS | Salesforce - France - Meylan Mobile: 33-06-63-91-94-63

rochejul avatar Jun 04 '24 06:06 rochejul

Marking as up-for-grabs since I think this should be pretty uncontroversial. We already expose it; this would just be formalizing what we expose.

Feature summary:

As a component author, I want to be able to access the real HTMLElement of my LightningElement from within one of its callbacks (e.g. renderedCallback), consistently in both shadow DOM and light DOM.

Solution: let's add this.elementSelf as a new property on LightningElement. You can look to the implementation of tagName for an example of how to do this: https://github.com/salesforce/lwc/pull/3642

Unlike the recent this.style PR (https://github.com/salesforce/lwc/pull/4044), I don't think we need API versioning for this. elementSelf is such an uncommon property name that I doubt anyone is squatting it.

nolanlawson avatar Jun 04 '24 15:06 nolanlawson

Hi @nolanlawson I created this PR if you are interested: #4259

Please let me know if I could help more

Many thanks for your help

rochejul avatar Jun 05 '24 09:06 rochejul