You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: packages/lit-dev-content/site/docs/v3/components/decorators.md
+1-7Lines changed: 1 addition & 7 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -76,7 +76,7 @@ TypeScript supports both experimental decorators and standard decorators. We rec
76
76
77
77
To use experimental decorators you must enable the `experimentalDecorators` compiler option.
78
78
79
-
You should also ensure that the `useDefineForClassFields` setting is `false`. Note, this is only required when the `target` is set to `ES2022` or greater, but it is recommended to explicitly set this to `false`.
79
+
You should also ensure that the `useDefineForClassFields` setting is `false`. This is only required when `target` is set to `ES2022` or greater, but it is recommended to explicitly set this to `false`. This is needed to [avoid issues with class fields when declaring properties](/docs/v3/components/properties/#avoiding-issues-with-class-fields).
80
80
81
81
```json
82
82
// tsconfig.json
@@ -125,12 +125,6 @@ Enable decorators by adding [`@babel/plugin-proposal-decorators`](https://babelj
125
125
126
126
Note: Lit decorators only work with `"version": "2023-05"`. Other versions, including the formerly supported `"2018-09"`, are not supported.
127
127
128
-
### Avoiding issues with class fields and decorators {#avoiding-issues-with-class-fields}
129
-
130
-
Standard [class fields](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes/Public_class_fields) have a problematic interaction with declaring reactive properties. See [Avoiding issues with class fields when declaring properties](/docs/v3/components/properties/#avoiding-issues-with-class-fields) for more information.
131
-
132
-
When using decorators, transpiler settings for Babel and TypeScript must be configured correctly as shown in the sections above for [TypeScript](#decorators-typescript) and [Babel](#decorators-babel).
133
-
134
128
## Decorator versions
135
129
136
130
Decorators are a [stage 3 proposal](https://github.com/tc39/proposal-decorators) for addition to the ECMAScript standard. Compilers like [Babel](https://babeljs.io/) and [TypeScript](https://www.typescriptlang.org/) support decorators, though no browsers have implemented them yet. Lit decorators work with Babel and TypeScript, and will work in browsers when they implement them natively.
Copy file name to clipboardExpand all lines: packages/lit-dev-content/site/docs/v3/components/properties.md
+60-17Lines changed: 60 additions & 17 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -120,34 +120,77 @@ An empty option object is equivalent to specifying the default value for all opt
120
120
121
121
### Avoiding issues with class fields when declaring properties {#avoiding-issues-with-class-fields}
122
122
123
-
[Class fields](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes/Public_class_fields) have a problematic interaction with reactive properties. Class fields are defined on the element instance. Reactive properties are defined as accessors on the element prototype. According to the rules of JavaScript, an instance property takes precedence over and effectively hides a prototype property. This means that reactive property accessors do not function when class fields are used. When a property is set, the element does not update.
123
+
[Class fields](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes/Public_class_fields) have a problematic interaction with reactive properties. Class fields are defined on the element instance whereas reactive properties are defined as accessors on the element prototype. According to the rules of JavaScript, an instance property takes precedence over and effectively hides a prototype property. This means that reactive property accessors do not function when class fields are used such that setting the property won't trigger an element update.
124
124
125
-
In **JavaScript** you **must not use class fields** when declaring reactive properties. Instead, properties must be initialized in the element constructor:
125
+
```js
126
+
classMyElementextendsLitElement {
127
+
static properties = {foo: {type:String}}
128
+
foo ='Default'; // ❌ this will make `foo` not reactive
129
+
}
130
+
```
126
131
132
+
In **JavaScript**, you **must not use class fields** when declaring reactive properties. Instead, properties must be initialized in the element constructor:
127
133
```js
128
-
constructor() {
129
-
super();
130
-
this.data= {};
134
+
classMyElementextendsLitElement {
135
+
static properties = {foo: {type:String}}
136
+
constructor() {
137
+
super();
138
+
this.foo='Default';
139
+
}
131
140
}
132
141
```
133
142
134
-
For **TypeScript**, you **may use class fields** for declaring reactive properties as long as you use one of these patterns:
135
-
* Set the `useDefineForClassFields` setting in your `tsconfig` to `false`. Note, this is not required for some configurations of TypeScript, but it's recommended to explicitly set it to `false`.
136
-
* Add the `declare` keyword on the field, and put the field's initializer in the constructor.
143
+
Alternatively, you may use [standard decorators with Babel](/docs/v3/components/decorators/#decorators-babel) to declare reactive properties.
144
+
```ts
145
+
classMyElementextendsLitElement {
146
+
@property()
147
+
accessor foo ='Default';
148
+
}
149
+
```
137
150
138
-
When compiling JavaScript with **Babel**, you **may use class fields** for declaring reactive properties as long as you set `setPublicClassFields` to `true` in the `assumptions` config of your `babelrc`. Note, for older versions of Babel, you also need to include the plugin `@babel/plugin-proposal-class-properties`:
151
+
For **TypeScript**, you **may use class fields** for declaring reactive properties as long as you use one of these patterns:
152
+
* Set the `useDefineForClassFields` compiler option to `false`. This is already the recommendation when [using decorators with TypeScript](/docs/v3/components/decorators/#decorators-typescript).
153
+
```json
154
+
// tsconfig.json
155
+
{
156
+
"compilerOptions": {
157
+
"experimentalDecorators": true, // If using decorators
158
+
"useDefineForClassFields": false,
159
+
}
160
+
}
161
+
```
162
+
```ts
163
+
classMyElementextendsLitElement {
164
+
static properties = {foo: {type: String}}
165
+
foo ='Default';
139
166
140
-
```js
141
-
assumptions = {
142
-
"setPublicClassFields":true
143
-
};
167
+
@property()
168
+
bar ='Default';
169
+
}
170
+
```
144
171
145
-
plugins = [
146
-
["@babel/plugin-proposal-class-properties"],
147
-
];
172
+
* Add the `declare` keyword on the field, and put the field's initializer in the constructor.
173
+
```ts
174
+
classMyElementextendsLitElement {
175
+
declare foo:string;
176
+
static properties = {foo: {type: String}}
177
+
constructor() {
178
+
super();
179
+
this.foo='Default';
180
+
}
181
+
}
148
182
```
149
183
150
-
For information about using class fields with **decorators**, see [Avoiding issues with class fields and decorators](/docs/v3/components/decorators/#avoiding-issues-with-class-fields).
184
+
* Add the `accessor` keyword on the field to use [auto-accessors](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-4-9.html#auto-accessors-in-classes).
0 commit comments