summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Elliott Marquez <5981958+e111077@users.noreply.github.com> 2021-11-22 13:01:32 -0800
committerGravatar GitHub <noreply@github.com> 2021-11-22 15:01:32 -0600
commitec01d1b43f069d909a18bfb73ee414f954d25c9a (patch)
tree4d72b2cba89772d1c16eb9624fcfa16e1251c554
parentc22e4c69ec3c544abda22d48526193c66351ccd9 (diff)
downloadastro-ec01d1b43f069d909a18bfb73ee414f954d25c9a.tar.gz
astro-ec01d1b43f069d909a18bfb73ee414f954d25c9a.tar.zst
astro-ec01d1b43f069d909a18bfb73ee414f954d25c9a.zip
fix(lit-renderer): certain reactive props not init correctly (#1874)
* fix(lit-renderer): reactive props not init correctly * test(renderer-lit): implement testing suggestiosn * chore(renderer-lit): upload changeset * fix(renderer-lit): call connCallback on server * fix(renderer-lit): do not set reserved JSX props * fix(renderer-lit): do not check for reserved attributes Co-authored-by: Nate Moore <nate@skypack.dev>
-rw-r--r--.changeset/gentle-donkeys-rule.md5
-rw-r--r--packages/astro/test/fixtures/lit-element/src/components/my-element.js17
-rw-r--r--packages/astro/test/fixtures/lit-element/src/pages/index.astro7
-rw-r--r--packages/astro/test/lit-element.test.js20
-rw-r--r--packages/renderers/renderer-lit/server.js10
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 `>`;