Now that Chrome and Node.js ships with class properties proposal, maybe we could implement support for it.
Until now, the only way to initialize properties is putting them inside a constructor:
class Modal extends LitElement {
constructor() {
super()
this.open = false
this.title = ''
}
static properties = {
title: { type: String },
radius: { type: String },
open: { type: Boolean }
}
}
Would be simpler do this:
class Modal extends LitElement {
open = false
title = 'default title'
static properties = {
title: { type: String },
radius: { type: String },
open: { type: Boolean }
}
}
Also, we can got benefit from property decorator without using TypeScript.
Thoughts?
Big 👍 on recommendation. Aside from those pointed out in example, it's
elegant.
On Tue, May 7, 2019, 1:49 PM Guz notifications@github.com wrote:
Now that Chrome and Node.js ships with class properties proposal
https://github.com/tc39/proposal-class-fields, maybe we could implement
support for it.Until now, the only way to initialize properties is putting them inside a
constructor:class Modal extends LitElement {
constructor() {
super()
this.open = false
this.title = ''
}static properties = {
title: { type: String },
radius: { type: String },
open: { type: Boolean }
}
}Would be simpler do this:
class Modal extends LitElement {
open = false
title = 'default title'static properties = {
title: { type: String },
radius: { type: String },
open: { type: Boolean }
}
}Also, we can got benefit from property decorator without using TypeScript.
Thoughts?
—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
https://github.com/Polymer/lit-element/issues/671, or mute the thread
https://github.com/notifications/unsubscribe-auth/AGALN3LHY3AQBWXTLGA3X3DPUHFLZANCNFSM4HLLREPA
.
@gugadev this already works out of the box in Chrome: https://stackblitz.com/edit/wtxiby?file=my-element.js And, you're right, super power and elegant!
If you have the correct plugins in your Babel setup, it'll transpile back to any older browsers you support. Enjoy!
@hyperpress @Westbrook Thanks! But there is a little issue with that type of declaration: the value is not updated.
Consider this example:
Modal
import {
LitElement, html, css, unsafeCSS
} from 'lit-element'
import { classMap } from 'lit-html/directives/class-map'
import styles from './modal.styles.css'
class Modal extends LitElement {
open = false // don't update after attribute change on parent component
title = ''
radius = ''
styleEl = null
render() {
const classes = {
'ck-modal': true,
'ck-modal--open': this.open
}
return html`
<div class=${classMap(classes)}>
<div class="ck-overlay"></div>
<ck-elevation level="3" style="z-index: 8">
<section class="ck-modal__content">
<header class="ck-modal__header">
<h2>${this.title}</h2>
<span>×</span>
</header>
<article class="ck-modal__body">
<slot></slot>
</article>
</section>
</ck-elevation>
</div>
`
}
updated() {
const content = this.shadowRoot.querySelector('.ck-modal__content')
content.style.setProperty('--radius', this.radius || 'var(--modal-radius)')
if (this.open) {
document.body.style.overflow = 'hidden' // avoid scrolling on show
}
}
static styles = css`${unsafeCSS(styles)}`
static properties = {
title: { type: String },
radius: { type: String },
open: { type: Boolean }
}
}
customElements.define('ck-modal', Modal)
The expected behaviour is that when in the parent component the value for the open property is updated, the component should be re-render it's template, showing off the modal, but this didn't happen because inside Modal component the property is never updated.
You can see this issue in this demo.
Oh, tricky that you can set properties and styles but not the default values for the properties themselves: https://codesandbox.io/s/8zy211o1m9 Thanks for the clarification, would be a nice add!
But there is a little issue with that type of declaration: the value is not updated.
This is a know (an undocumented) issue. For more info see https://github.com/Polymer/lit-element/issues/414
@blikblum thanks for the reference, I didn't aware about it. Seems we have to use Typescript by now.
Also, would be great if provide decorators for JS following the new syntax. I'll try to work on this one and hope raise a PR soon.
Thanks to all.
The issue title is not clear, but I do not want to create new issue for probably same problem.
As I see the class field declaration (even without initialization) is breaking the element live cycle.
Simple example:
class App extends LitElement {
static properties = {count: false};
constructor() {
super();
this.count = 0;
}
render = () => html`<button @click=${this.click}>Hello ${this.count}</button>`;
click = () => this.count += 1;
}
If we will just add field declaration, component stops working:
class App extends LitElement {
static properties = {count: false};
count;
constructor() {
super();
this.count = 0;
}
render = () => html`<button @click=${this.click}>Hello ${this.count}</button>`;
click = () => this.count += 1;
}
This is also causing impossible to use private # field syntax, as such field have to be declared on class level (spec requirement).
PS.
I know I can use tool X, Y, Z, but I do not using Typescript, Bable, ect, and I do not want/need :)
We can't use undecorated class fields. We'll need to wait for decorators.