I have a component MyWrapper which consists of flowing text on the left and a margin on the right. In the margin, there are MarginElement components that should be vertically aligned with <mark> tags in the text.
import {html, css, LitElement} from 'lit';
import {customElement, property} from 'lit/decorators.js';
@customElement('my-wrapper')
export class MyWrapper extends LitElement {
static styles = css`:host{display:flex}`
render() {
return html`
<p>
<mark id="mark1">Lorem</mark> ipsum dolor sit amet, consectetur adipiscing elit, sed
do eiusmod tempor incididunt ut labore et dolore magna aliqua.
Ut enim ad minim veniam, quis nostrud exercitation ullamco
laboris nisi ut aliquip ex ea commodo consequat. Duis aute
irure dolor in reprehenderit in voluptate velit esse <mark id="mark2">cillium</mark>.
</p>
<div class="margin" style="width:50%">
<margin-element id="m1" related-element-id="mark1">Some note</margin-element>
<margin-element id="m2" related-element-id="mark2">Some other note</margin-element>
</div>`;
}
updated(){this.positionMargin()}
positionMargin() {
const elements = this.shadowRoot.querySelectorAll('margin-element')
elements.forEach(el => {
const relatedElement = this.shadowRoot.querySelector(`#${el.relatedElementId}`)
el.style.top = relatedElement.getBoundingClientRect().top + 'px'
})
}
}
@customElement('margin-element')
export class MarginElement extends LitElement {
static styles = css`:host {position: absolute; border: 1px solid red;}`
@property({type: String, attribute: 'related-element-id'}) relatedElementId: string
render() {return html`<slot></slot>`}
}
I would like to run the function positionMargin() once rendering on MyWrapper is completed, but I understand that to call relatedElement.getBoundingClientRect() margin-element must itself be rendered. Looking at the docs updated() seems to be the best place to call positionMargin(). Yet it seems as if the child <margin-element>s are not rendered by then. Consequently, getBoundingClientRect() is unavailable.
How can this be resolved?