Add tooltip custom element with position-anchor support on the :host#409
Add tooltip custom element with position-anchor support on the :host#409jpzwarte wants to merge 4 commits into
:host#409Conversation
✅ Deploy Preview for anchor-position-wpt canceled.
|
✅ Deploy Preview for anchor-polyfill ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
jamesnw
left a comment
There was a problem hiding this comment.
I think this is adding a bug. If the position-anchor is defined in the Constructed Stylesheet, on :host, and the anchor-name is defined in the light dom, browsers do not find the anchor-name. With this change, the polyfill does find the anchor.
:host{
position-anchor: --a;
}
I'm not entirely certain of what is correct per the spec here. My understanding of the spec is that the target should not be able to find the anchor. The anchor has to be named in the same tree where it is used.
If that's the case, I'd like to figure out the more general pattern we could apply, so that the polyfill works for your example, without overeagerly exposing anchor names.
| this.setAttribute( | ||
| 'style', | ||
| 'position-anchor: --position-anchor-on-host', | ||
| ); | ||
| target?.setAttribute( | ||
| 'style', | ||
| 'anchor-name: --position-anchor-on-host', | ||
| ); |
There was a problem hiding this comment.
Is this necessary for the functionality? I think you can test the same functionality by setting the style directly on the light dom elements, and it makes it a bit easier to understand.
| --element-color: var(--target, var(--outer-anchored)); | ||
| background: var(--element-color); | ||
| border: thin solid var(--border); | ||
| border-radius: var(--radius-1); | ||
| color: white; | ||
| font-weight: bold; |
There was a problem hiding this comment.
| --element-color: var(--target, var(--outer-anchored)); | |
| background: var(--element-color); | |
| border: thin solid var(--border); | |
| border-radius: var(--radius-1); | |
| color: white; | |
| font-weight: bold; |
I think we can exclude the styling CSS from the code block to simplify the example (but keep it in the actual custom element definition).
| if (trimmed === ':host') { | ||
| return true; | ||
| } | ||
| const match = /^:host\(\s*(.+?)\s*\)$/.exec(trimmed); |
There was a problem hiding this comment.
I think this works, but could we parse it as CSS rather than using regex? I think that might allow us to handle selector lists like :host(.blue, .red)
Fixes #408
What this fixes
When
position-anchoris set on a custom element host (i.e. via a:hostrule in an adopted stylesheet), the polyfill failed to position the element. Three separate issues combined to cause this::hosttargets were never matched.querySelectorAll(':host')returns nothing when called from within a shadow root, so the polyfill never recognised the custom element as a target. Fixed insrc/dom.tsby resolving:host/:host(...)selectors directly against the shadow root's host element.The anchor lived outside the polyfilled roots. The anchor element (e.g. a
<div>in the light DOM) was not in any of the shadow roots passed topolyfill(), sogetAnchorElcouldn't find it. Fixed insrc/parse.tsby also searching the target element's own root node when looking up its anchor.Inline styles set via typed CSSOM were silently dropped. Setting
el.style.anchorName = ...in a browser without native anchor-positioning support discards the unknown declaration, leaving nostyleattribute for the polyfill to read. Fixed in the demo (shadow-dom.html) by writing the declarations as raw attribute strings viasetAttribute('style', ...), which browsers preserve literally.New demo
A
<position-anchor-on-host>custom element is added toshadow-dom.html. ItsconnectedCallbackwires up the anchor link at runtime: