diff --git a/src/component.ts b/src/component.ts index 126573f..1d59496 100644 --- a/src/component.ts +++ b/src/component.ts @@ -29,16 +29,22 @@ interface Options

{ function makeComponent(render: RenderFunction): Creator { class Scheduler

extends BaseScheduler, Component

> { frag: DocumentFragment | HTMLElement; + isFirstRender: boolean; constructor(renderer: Renderer

, frag: DocumentFragment, host: HTMLElement); constructor(renderer: Renderer

, host: HTMLElement); constructor(renderer: Renderer

, frag: DocumentFragment | HTMLElement, host?: HTMLElement) { super(renderer, (host || frag) as Component

); this.frag = frag; + this.isFirstRender = true; } commit(result: unknown): void { + // Clear component's content before first render + // Needed by lit-html v2. See https://lit.dev/docs/releases/upgrade/#lit-html + if (this.isFirstRender) clearContent(this.frag); render(result, this.frag); + this.isFirstRender = false; } } @@ -150,4 +156,14 @@ function makeComponent(render: RenderFunction): Creator { return component; } +// Clear content of element or fragment +// Same as element.innerHTML = '', but works on fragments as well +function clearContent(frag: DocumentFragment | HTMLElement) { + if (frag.replaceChildren) { + frag.replaceChildren() // New API + } else { + while (frag.firstChild) frag.removeChild(frag.lastChild!); // Fallback for old browsers + } +} + export { makeComponent, Component, Constructor as ComponentConstructor, Creator as ComponentCreator }; diff --git a/test/first-render.test.ts b/test/first-render.test.ts new file mode 100644 index 0000000..9975ee3 --- /dev/null +++ b/test/first-render.test.ts @@ -0,0 +1,15 @@ +import { component, html } from '../src/haunted.js'; +import { fixture, expect } from '@open-wc/testing'; + +describe('First Render', () => { + it('should clear content', async () => { + customElements.define('no-shadow-test', component(() => { + return html`Template Content`; + }, HTMLElement, {useShadowDOM: false})); + + // This "Loading..." text should be cleared after first render + const el = await fixture(html`Loading...`); + + expect(el.innerText).to.equal('Template Content'); + }); +})