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>
This commit is contained in:
parent
c22e4c69ec
commit
ec01d1b43f
5 changed files with 56 additions and 3 deletions
5
.changeset/gentle-donkeys-rule.md
Normal file
5
.changeset/gentle-donkeys-rule.md
Normal file
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
'@astrojs/renderer-lit': patch
|
||||
---
|
||||
|
||||
renderer-lit will bind to properties rather than attributes fixing certain binding issues
|
|
@ -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>
|
||||
`;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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>
|
|
@ -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
|
||||
|
|
|
@ -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 `>`;
|
||||
|
|
Loading…
Reference in a new issue