diff options
-rw-r--r-- | .changeset/gentle-donkeys-rule.md | 5 | ||||
-rw-r--r-- | packages/astro/test/fixtures/lit-element/src/components/my-element.js | 17 | ||||
-rw-r--r-- | packages/astro/test/fixtures/lit-element/src/pages/index.astro | 7 | ||||
-rw-r--r-- | packages/astro/test/lit-element.test.js | 20 | ||||
-rw-r--r-- | packages/renderers/renderer-lit/server.js | 10 |
5 files changed, 56 insertions, 3 deletions
diff --git a/.changeset/gentle-donkeys-rule.md b/.changeset/gentle-donkeys-rule.md new file mode 100644 index 000000000..eb33cfce1 --- /dev/null +++ b/.changeset/gentle-donkeys-rule.md @@ -0,0 +1,5 @@ +--- +'@astrojs/renderer-lit': patch +--- + +renderer-lit will bind to properties rather than attributes fixing certain binding issues diff --git a/packages/astro/test/fixtures/lit-element/src/components/my-element.js b/packages/astro/test/fixtures/lit-element/src/components/my-element.js index 7b7eed71c..6466bca02 100644 --- a/packages/astro/test/fixtures/lit-element/src/components/my-element.js +++ b/packages/astro/test/fixtures/lit-element/src/components/my-element.js @@ -3,9 +3,26 @@ import { LitElement, html } from 'lit'; export const tagName = 'my-element'; export class MyElement extends LitElement { + static properties = { + bool: {type: Boolean}, + str: {type: String, attribute: 'str-attr'}, + obj: {type: Object}, + } + + constructor() { + super(); + this.bool = true; + this.str = 'not initialized'; + this.obj = {data: null}; + // not a reactive property + this.foo = 'not initialized'; + } render() { return html` <div>Testing...</div> + <div id="bool">${this.bool ? 'A' : 'B'}</div> + <div id="str">${this.str}</div> + <div id="data">data: ${this.obj.data}</div> `; } } diff --git a/packages/astro/test/fixtures/lit-element/src/pages/index.astro b/packages/astro/test/fixtures/lit-element/src/pages/index.astro index 771736294..de1140656 100644 --- a/packages/astro/test/fixtures/lit-element/src/pages/index.astro +++ b/packages/astro/test/fixtures/lit-element/src/pages/index.astro @@ -7,6 +7,11 @@ import '../components/my-element.js'; <title>LitElements</title> </head> <body> - <my-element foo="bar"></my-element> + <my-element + foo="bar" + str-attr={'initialized'} + bool={false} + obj={{data: 1}}> + </my-element> </body> </html>
\ No newline at end of file diff --git a/packages/astro/test/lit-element.test.js b/packages/astro/test/lit-element.test.js index dd44ae3da..eed211d91 100644 --- a/packages/astro/test/lit-element.test.js +++ b/packages/astro/test/lit-element.test.js @@ -5,6 +5,7 @@ import { loadFixture } from './test-utils.js'; let fixture; const NODE_VERSION = parseFloat(process.versions.node); +const stripExpressionMarkers = (html) => html.replace(/<!--\/?lit-part-->/g, '') before(async () => { // @lit-labs/ssr/ requires Node 13.9 or higher @@ -27,11 +28,28 @@ describe('LitElement test', () => { const html = await fixture.readFile('/index.html'); const $ = cheerio.load(html); - // test 1: attributes rendered + // test 1: attributes rendered – non reactive properties expect($('my-element').attr('foo')).to.equal('bar'); // test 2: shadow rendered expect($('my-element').html()).to.include(`<div>Testing...</div>`); + + // test 3: string reactive property set + expect(stripExpressionMarkers($('my-element').html())).to.include(`<div id="str">initialized</div>`); + + // test 4: boolean reactive property correctly set + // <my-element bool="false"> Lit will equate to true because it uses + // this.hasAttribute to determine its value + expect(stripExpressionMarkers($('my-element').html())).to.include(`<div id="bool">B</div>`); + + // test 5: object reactive property set + // by default objects will be stringifed to [object Object] + expect(stripExpressionMarkers($('my-element').html())).to.include(`<div id="data">data: 1</div>`); + + // test 6: reactive properties are not rendered as attributes + expect($('my-element').attr('obj')).to.equal(undefined); + expect($('my-element').attr('bool')).to.equal(undefined); + expect($('my-element').attr('str')).to.equal(undefined); }); // Skipped because not supported by Lit diff --git a/packages/renderers/renderer-lit/server.js b/packages/renderers/renderer-lit/server.js index c827f1ad1..e08b2bf9a 100644 --- a/packages/renderers/renderer-lit/server.js +++ b/packages/renderers/renderer-lit/server.js @@ -28,10 +28,18 @@ function* render(tagName, attrs, children) { const instance = new LitElementRenderer(tagName); // LitElementRenderer creates a new element instance, so copy over. + const Ctr = getCustomElementConstructor(tagName); for (let [name, value] of Object.entries(attrs)) { - instance.setAttribute(name, value); + // check if this is a reactive property + if (name in Ctr.prototype) { + instance.setProperty(name, value); + } else { + instance.setAttribute(name, value); + } } + instance.connectedCallback(); + yield `<${tagName}`; yield* instance.renderAttributes(); yield `>`; |