p-elements-core 1.2.17 → 1.2.18
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/demo/sample.js +1 -1
- package/dist/p-elements-core 2.js +1 -0
- package/dist/p-elements-core-modern 2.js +553 -0
- package/dist/p-elements-core-modern.js +1 -1
- package/dist/p-elements-core.js +1 -1
- package/p-elements-core.d.ts +187 -46
- package/package.json +1 -1
- package/readme.md +8 -0
- package/src/custom-element-controller.ts +8 -0
- package/src/custom-element.ts +37 -3
- package/src/decorators/property.ts +3 -3
- package/src/sample/mixin/highlight.tsx +1 -0
- package/src/sample/sample.tsx +25 -3
package/p-elements-core.d.ts
CHANGED
|
@@ -38,84 +38,196 @@ declare interface ProjectionOptions extends ProjectorOptions {
|
|
|
38
38
|
) => Function;
|
|
39
39
|
}
|
|
40
40
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
41
|
+
export type EventHandler = (this: Node, event: Event) => boolean | undefined | void;
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Object containing attributes, properties, event handlers and more that can be put on DOM nodes.
|
|
46
|
+
*
|
|
47
|
+
* For your convenience, all common attributes, properties and event handlers are listed here and are
|
|
48
|
+
* type-checked when using Typescript.
|
|
49
|
+
*/
|
|
50
|
+
export interface VNodeProperties {
|
|
51
|
+
/**
|
|
52
|
+
* The animation to perform when this node is added to an already existing parent.
|
|
53
|
+
* {@link http://maquettejs.org/docs/animations.html More about animations}.
|
|
54
|
+
* @param element - Element that was just added to the DOM.
|
|
55
|
+
* @param properties - The properties object that was supplied to the [[h]] method
|
|
56
|
+
*/
|
|
57
|
+
enterAnimation?: (element: Element, properties?: VNodeProperties) => void;
|
|
58
|
+
/**
|
|
59
|
+
* The animation to perform when this node is removed while its parent remains.
|
|
60
|
+
* @param element - Element that ought to be removed from to the DOM.
|
|
61
|
+
* @param removeElement - Function that removes the element from the DOM.
|
|
62
|
+
* This argument is provided purely for convenience.
|
|
63
|
+
* You may use this function to remove the element when the animation is done.
|
|
64
|
+
* @param properties - The properties object that was supplied to the [[h]] method that rendered this [[VNode]] the previous time.
|
|
65
|
+
*/
|
|
66
|
+
exitAnimation?(element: Element, removeElement: () => void, properties?: VNodeProperties): void;
|
|
67
|
+
/**
|
|
68
|
+
* The animation to perform when the properties of this node change.
|
|
69
|
+
* This also includes attributes, styles, css classes. This callback is also invoked when node contains only text and that text changes.
|
|
70
|
+
* {@link http://maquettejs.org/docs/animations.html More about animations}.
|
|
71
|
+
* @param element - Element that was modified in the DOM.
|
|
72
|
+
* @param properties - The last properties object that was supplied to the [[h]] method
|
|
73
|
+
* @param previousProperties - The previous properties object that was supplied to the [[h]] method
|
|
74
|
+
*/
|
|
75
|
+
updateAnimation?(
|
|
53
76
|
element: Element,
|
|
54
77
|
properties?: VNodeProperties,
|
|
55
78
|
previousProperties?: VNodeProperties
|
|
56
|
-
)
|
|
79
|
+
): void;
|
|
80
|
+
/**
|
|
81
|
+
* Callback that is executed after this node is added to the DOM. Child nodes and properties have
|
|
82
|
+
* already been applied.
|
|
83
|
+
* @param element - The element that was added to the DOM.
|
|
84
|
+
* @param projectionOptions - The projection options that were used, see [[createProjector]].
|
|
85
|
+
* @param vnodeSelector - The selector passed to the [[h]] function.
|
|
86
|
+
* @param properties - The properties passed to the [[h]] function.
|
|
87
|
+
* @param children - The children that were created.
|
|
88
|
+
*/
|
|
57
89
|
afterCreate?(
|
|
58
90
|
element: Element,
|
|
59
91
|
projectionOptions: ProjectionOptions,
|
|
60
92
|
vnodeSelector: string,
|
|
61
93
|
properties: VNodeProperties,
|
|
62
|
-
children: VNode[]
|
|
94
|
+
children: VNode[] | undefined
|
|
63
95
|
): void;
|
|
96
|
+
/**
|
|
97
|
+
* Callback that is executed every time this node may have been updated. Child nodes and properties
|
|
98
|
+
* have already been updated.
|
|
99
|
+
* @param element - The element that may have been updated in the DOM.
|
|
100
|
+
* @param projectionOptions - The projection options that were used, see [[createProjector]].
|
|
101
|
+
* @param vnodeSelector - The selector passed to the [[h]] function.
|
|
102
|
+
* @param properties - The properties passed to the [[h]] function.
|
|
103
|
+
* @param children - The children for this node.
|
|
104
|
+
*/
|
|
64
105
|
afterUpdate?(
|
|
65
106
|
element: Element,
|
|
66
107
|
projectionOptions: ProjectionOptions,
|
|
67
108
|
vnodeSelector: string,
|
|
68
109
|
properties: VNodeProperties,
|
|
69
|
-
children: VNode[]
|
|
110
|
+
children: VNode[] | undefined
|
|
70
111
|
): void;
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* Callback that is called when a node has been removed from the tree.
|
|
115
|
+
* The callback is called during idle state or after a timeout (fallback).
|
|
116
|
+
* {@link https://maquettejs.org/docs/dom-node-removal.html More info}
|
|
117
|
+
* @param element - The element that has been removed from the DOM.
|
|
118
|
+
*/
|
|
71
119
|
afterRemoved?(element: Element): void;
|
|
72
|
-
|
|
73
|
-
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* When specified, the event handlers will be invoked with 'this' pointing to the value.
|
|
123
|
+
* This is useful when using the prototype/class based implementation of MaquetteComponents.
|
|
124
|
+
*
|
|
125
|
+
* When no [[key]] is present, this object is also used to uniquely identify a DOM node.
|
|
126
|
+
*/
|
|
127
|
+
readonly bind?: unknown;
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* Used to uniquely identify a DOM node among siblings.
|
|
131
|
+
* A key is required when there are more children with the same selector and these children are added or removed dynamically.
|
|
132
|
+
* NOTE: this does not have to be a string or number, a [[MaquetteComponent]] Object for instance is also common.
|
|
133
|
+
*/
|
|
134
|
+
readonly key?: unknown;
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* An object containing event handlers to attach using addEventListener.
|
|
138
|
+
* Note that `projector.scheduleRender()` is called automatically when these event handlers are invoked.
|
|
139
|
+
*/
|
|
140
|
+
readonly on?: {
|
|
141
|
+
[eventName: string]:
|
|
142
|
+
| EventHandler
|
|
143
|
+
| {
|
|
144
|
+
listener: EventHandler;
|
|
145
|
+
options: { capture?: boolean; passive?: boolean; once?: boolean };
|
|
146
|
+
};
|
|
147
|
+
};
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
* An object containing event handlers to attach using addEventListener.
|
|
151
|
+
* Note that `projector.scheduleRender()` is called automatically when these event handlers are invoked.
|
|
152
|
+
*/
|
|
153
|
+
readonly onCapture?: { [eventName: string]: EventHandler };
|
|
154
|
+
|
|
155
|
+
/**
|
|
156
|
+
* An object literal like `{important:true}` which allows css classes, like `important` to be added and removed
|
|
157
|
+
* dynamically.
|
|
158
|
+
*/
|
|
74
159
|
readonly classes?: { [index: string]: boolean | null | undefined };
|
|
75
|
-
readonly styles?: { [index: string]: string | null | undefined };
|
|
76
160
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
161
|
+
/**
|
|
162
|
+
* An object literal like `{height:'100px'}` which allows styles to be changed dynamically. All values must be strings.
|
|
163
|
+
*/
|
|
164
|
+
readonly styles?: Partial<CSSStyleDeclaration> | { [cssVariable: string]: string };
|
|
165
|
+
|
|
166
|
+
/**
|
|
167
|
+
* For custom elements
|
|
168
|
+
*/
|
|
169
|
+
readonly is?: string;
|
|
81
170
|
|
|
171
|
+
// From Element
|
|
172
|
+
ontouchcancel?(ev: TouchEvent): boolean | void;
|
|
173
|
+
ontouchend?(ev: TouchEvent): boolean | void;
|
|
174
|
+
ontouchmove?(ev: TouchEvent): boolean | void;
|
|
175
|
+
ontouchstart?(ev: TouchEvent): boolean | void;
|
|
176
|
+
// From HTMLFormElement
|
|
82
177
|
readonly action?: string;
|
|
83
178
|
readonly encoding?: string;
|
|
84
179
|
readonly enctype?: string;
|
|
85
180
|
readonly method?: string;
|
|
86
181
|
readonly name?: string;
|
|
87
182
|
readonly target?: string;
|
|
88
|
-
|
|
183
|
+
// From HTMLAnchorElement
|
|
89
184
|
readonly href?: string;
|
|
90
185
|
readonly rel?: string;
|
|
91
|
-
|
|
92
|
-
onblur?(ev
|
|
93
|
-
onchange?(ev
|
|
94
|
-
onclick?(ev
|
|
95
|
-
ondblclick?(ev
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
186
|
+
// From HTMLElement
|
|
187
|
+
onblur?(ev: FocusEvent): boolean | void;
|
|
188
|
+
onchange?(ev: Event): boolean | void;
|
|
189
|
+
onclick?(ev: MouseEvent): boolean | void;
|
|
190
|
+
ondblclick?(ev: MouseEvent): boolean | void;
|
|
191
|
+
ondrag?(ev: DragEvent): boolean | void;
|
|
192
|
+
ondragend?(ev: DragEvent): boolean | void;
|
|
193
|
+
ondragenter?(ev: DragEvent): boolean | void;
|
|
194
|
+
ondragleave?(ev: DragEvent): boolean | void;
|
|
195
|
+
ondragover?(ev: DragEvent): boolean | void;
|
|
196
|
+
ondragstart?(ev: DragEvent): boolean | void;
|
|
197
|
+
ondrop?(ev: DragEvent): boolean | void;
|
|
198
|
+
onfocus?(ev: FocusEvent): boolean | void;
|
|
199
|
+
oninput?(ev: Event): boolean | void;
|
|
200
|
+
onkeydown?(ev: KeyboardEvent): boolean | void;
|
|
201
|
+
onkeypress?(ev: KeyboardEvent): boolean | void;
|
|
202
|
+
onkeyup?(ev: KeyboardEvent): boolean | void;
|
|
203
|
+
onload?(ev: Event): boolean | void;
|
|
204
|
+
onmousedown?(ev: MouseEvent): boolean | void;
|
|
205
|
+
onmouseenter?(ev: MouseEvent): boolean | void;
|
|
206
|
+
onmouseleave?(ev: MouseEvent): boolean | void;
|
|
207
|
+
onmousemove?(ev: MouseEvent): boolean | void;
|
|
208
|
+
onmouseout?(ev: MouseEvent): boolean | void;
|
|
209
|
+
onmouseover?(ev: MouseEvent): boolean | void;
|
|
210
|
+
onmouseup?(ev: MouseEvent): boolean | void;
|
|
211
|
+
onmousewheel?(ev: WheelEvent): boolean | void;
|
|
212
|
+
onscroll?(ev: UIEvent): boolean | void;
|
|
213
|
+
onsubmit?(ev: Event): boolean | void;
|
|
214
|
+
onpointercancel?(ev: PointerEvent): boolean | void;
|
|
215
|
+
onpointerdown?(ev: PointerEvent): boolean | void;
|
|
216
|
+
onpointerenter?(ev: PointerEvent): boolean | void;
|
|
217
|
+
onpointerleave?(ev: PointerEvent): boolean | void;
|
|
218
|
+
onpointermove?(ev: PointerEvent): boolean | void;
|
|
219
|
+
onpointerout?(ev: PointerEvent): boolean | void;
|
|
220
|
+
onpointerover?(ev: PointerEvent): boolean | void;
|
|
221
|
+
onpointerup?(ev: PointerEvent): boolean | void;
|
|
112
222
|
readonly spellcheck?: boolean;
|
|
113
223
|
readonly tabIndex?: number;
|
|
114
224
|
readonly disabled?: boolean;
|
|
115
225
|
readonly title?: string;
|
|
116
226
|
readonly accessKey?: string;
|
|
227
|
+
readonly class?: string;
|
|
117
228
|
readonly id?: string;
|
|
118
|
-
|
|
229
|
+
readonly draggable?: boolean;
|
|
230
|
+
// From HTMLInputElement
|
|
119
231
|
readonly type?: string;
|
|
120
232
|
readonly autocomplete?: string;
|
|
121
233
|
readonly checked?: boolean;
|
|
@@ -123,11 +235,25 @@ declare interface VNodeProperties {
|
|
|
123
235
|
readonly readOnly?: boolean;
|
|
124
236
|
readonly src?: string;
|
|
125
237
|
readonly value?: string;
|
|
126
|
-
|
|
238
|
+
// From HTMLImageElement
|
|
127
239
|
readonly alt?: string;
|
|
128
240
|
readonly srcset?: string;
|
|
241
|
+
/**
|
|
242
|
+
* Puts a non-interactive string of html inside the DOM node.
|
|
243
|
+
*
|
|
244
|
+
* Note: if you use innerHTML, maquette cannot protect you from XSS vulnerabilities and you must make sure that the innerHTML value is safe.
|
|
245
|
+
*/
|
|
129
246
|
readonly innerHTML?: string;
|
|
130
247
|
|
|
248
|
+
/**
|
|
249
|
+
* Do not use className, use class instead
|
|
250
|
+
*/
|
|
251
|
+
// eslint-disable-next-line @typescript-eslint/no-redundant-type-constituents
|
|
252
|
+
readonly className?: never | "Hint: do not use `className`, use `class` instead";
|
|
253
|
+
|
|
254
|
+
/**
|
|
255
|
+
* Everything that is not explicitly listed (properties and attributes that are either uncommon or custom).
|
|
256
|
+
*/
|
|
131
257
|
readonly [index: string]: any;
|
|
132
258
|
}
|
|
133
259
|
|
|
@@ -182,9 +308,21 @@ declare const CustomElementConfig: (
|
|
|
182
308
|
|
|
183
309
|
declare type ElementProjectorMode = "append" | "merge" | "replace";
|
|
184
310
|
|
|
311
|
+
export interface PropertyOptions {
|
|
312
|
+
type?: PropertyType;
|
|
313
|
+
reflect?: boolean;
|
|
314
|
+
attribute?: string;
|
|
315
|
+
readonly?: boolean;
|
|
316
|
+
converter?: AttributeConverter<any>;
|
|
317
|
+
}
|
|
318
|
+
export interface PropertyInfo extends PropertyOptions {
|
|
319
|
+
name: string;
|
|
320
|
+
}
|
|
321
|
+
|
|
185
322
|
declare abstract class CustomElement extends HTMLElement {
|
|
186
323
|
constructor(self?: any);
|
|
187
324
|
get internals(): ElementInternals;
|
|
325
|
+
get properties(): readonly PropertyInfo[];
|
|
188
326
|
protected addStylesheetToRootNode(
|
|
189
327
|
style: string,
|
|
190
328
|
rootNode: ShadowRoot | Document
|
|
@@ -199,6 +337,7 @@ declare abstract class CustomElement extends HTMLElement {
|
|
|
199
337
|
render: () => VNode
|
|
200
338
|
): Promise<Projector>;
|
|
201
339
|
addController(controller: CustomElementController): void;
|
|
340
|
+
scheduleRender(): void;
|
|
202
341
|
renderNow(): void;
|
|
203
342
|
connectedCallback(): void;
|
|
204
343
|
disconnectedCallback(): void;
|
|
@@ -215,6 +354,7 @@ declare abstract class CustomElementController {
|
|
|
215
354
|
constructor(hostElement: CustomElement);
|
|
216
355
|
hostElement: CustomElement;
|
|
217
356
|
renderNow(): void;
|
|
357
|
+
scheduleRender(): void;
|
|
218
358
|
init?(): void;
|
|
219
359
|
connected?(): void;
|
|
220
360
|
disconnected?(): void;
|
|
@@ -241,6 +381,7 @@ interface AttributeConverter<T> {
|
|
|
241
381
|
fromAttribute?(value: string | null): T;
|
|
242
382
|
toAttribute?(value: T): string;
|
|
243
383
|
}
|
|
384
|
+
|
|
244
385
|
declare type PropertyType = "string" | "number" | "boolean" | "object";
|
|
245
386
|
|
|
246
387
|
declare const Property: (options?: {
|
package/package.json
CHANGED
package/readme.md
CHANGED
|
@@ -192,6 +192,14 @@ Before a property is set to a new value
|
|
|
192
192
|
|
|
193
193
|
After a property value is set to a new value
|
|
194
194
|
|
|
195
|
+
#### `renderStart`
|
|
196
|
+
|
|
197
|
+
When the custom element start the rendering
|
|
198
|
+
|
|
199
|
+
#### `renderDone`
|
|
200
|
+
|
|
201
|
+
When the custom element is finished rendering
|
|
202
|
+
|
|
195
203
|
#### `attributeChangedCallback`
|
|
196
204
|
|
|
197
205
|
Call `super.attributeChangedCallback()` first.
|
|
@@ -1,8 +1,12 @@
|
|
|
1
|
+
import type { CustomElement } from './custom-element';
|
|
2
|
+
|
|
1
3
|
export interface ICustomElementController {
|
|
2
4
|
renderNow(): void;
|
|
3
5
|
init?: () => void;
|
|
4
6
|
connected? : () => void;
|
|
5
7
|
disconnected? : () => void;
|
|
8
|
+
hostRenderStart?: () => void;
|
|
9
|
+
hostRenderDone? : () => void;
|
|
6
10
|
hostElement: CustomElement;
|
|
7
11
|
}
|
|
8
12
|
export abstract class CustomElementController implements ICustomElementController {
|
|
@@ -20,4 +24,8 @@ export abstract class CustomElementController implements ICustomElementControlle
|
|
|
20
24
|
renderNow() {
|
|
21
25
|
this.hostElement?.renderNow();
|
|
22
26
|
}
|
|
27
|
+
|
|
28
|
+
scheduleRender() {
|
|
29
|
+
this.hostElement?.scheduleRender();
|
|
30
|
+
}
|
|
23
31
|
}
|
package/src/custom-element.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { PropertyInfo } from "./decorators/property";
|
|
2
2
|
import { replaceApplyToCssVars } from "./helpers/css";
|
|
3
3
|
import { ICustomElementController } from "./custom-element-controller";
|
|
4
|
+
import { Projector, VNode } from "./maquette/interfaces";
|
|
4
5
|
|
|
5
6
|
export type ElementProjectorMode = "append" | "merge" | "replace";
|
|
6
7
|
|
|
@@ -102,6 +103,7 @@ export abstract class CustomElement extends HTMLElement {
|
|
|
102
103
|
this.#polyfillCssApply();
|
|
103
104
|
});
|
|
104
105
|
}
|
|
106
|
+
|
|
105
107
|
}
|
|
106
108
|
|
|
107
109
|
#reflectProperties() {
|
|
@@ -272,18 +274,28 @@ export abstract class CustomElement extends HTMLElement {
|
|
|
272
274
|
let projector: Projector;
|
|
273
275
|
const mode = this.#projectorMode ? this.#projectorMode : "append";
|
|
274
276
|
requestAnimationFrame(() => {
|
|
275
|
-
projector = (window as any).Maquette.createProjector(
|
|
277
|
+
projector = (window as any).Maquette.createProjector({
|
|
278
|
+
performanceLogger: (eventName) => {
|
|
279
|
+
if (eventName === "renderStart" || eventName === "renderDone") {
|
|
280
|
+
this.#invokeRenderLifecycleFn(eventName);
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
});
|
|
276
284
|
projector[mode](element, render.bind(this));
|
|
277
285
|
this.#projector = projector;
|
|
278
286
|
this.#canReflect = true;
|
|
279
287
|
this.#reflectProperties();
|
|
280
|
-
|
|
281
|
-
|
|
288
|
+
projector.renderNow();
|
|
289
|
+
resolve(projector);
|
|
282
290
|
this.dispatchEvent(new CustomEvent("firstRender", {}));
|
|
283
291
|
});
|
|
284
292
|
});
|
|
285
293
|
}
|
|
286
294
|
|
|
295
|
+
scheduleRender(): void {
|
|
296
|
+
this.#projector?.scheduleRender();
|
|
297
|
+
}
|
|
298
|
+
|
|
287
299
|
renderNow(): void {
|
|
288
300
|
this.#projector?.renderNow();
|
|
289
301
|
}
|
|
@@ -328,4 +340,26 @@ export abstract class CustomElement extends HTMLElement {
|
|
|
328
340
|
this[prop.name] = JSON.parse(newValue);
|
|
329
341
|
}
|
|
330
342
|
}
|
|
343
|
+
|
|
344
|
+
#isFirstRenderStart = true;
|
|
345
|
+
|
|
346
|
+
#isFirstRenderDone = true;
|
|
347
|
+
|
|
348
|
+
|
|
349
|
+
#invokeRenderLifecycleFn(eventName: string) {
|
|
350
|
+
if (this[eventName]){
|
|
351
|
+
this[eventName](eventName === "renderStart" ? this.#isFirstRenderStart : this.#isFirstRenderDone);
|
|
352
|
+
}
|
|
353
|
+
const controllerEventName = `host${eventName.charAt(0).toUpperCase()}${eventName.slice(1)}`;
|
|
354
|
+
this.#controllers.forEach((controller) => {
|
|
355
|
+
if (controller[controllerEventName]) {
|
|
356
|
+
controller[controllerEventName](eventName === "renderStart" ? this.#isFirstRenderStart : this.#isFirstRenderDone);
|
|
357
|
+
}
|
|
358
|
+
});
|
|
359
|
+
if (eventName === "renderStart") {
|
|
360
|
+
this.#isFirstRenderStart = false;
|
|
361
|
+
} else {
|
|
362
|
+
this.#isFirstRenderDone = false;
|
|
363
|
+
}
|
|
364
|
+
}
|
|
331
365
|
}
|
|
@@ -61,7 +61,7 @@ export const property = (propertyOptions: PropertyOptions) => {
|
|
|
61
61
|
},
|
|
62
62
|
set: function (value) {
|
|
63
63
|
this[sym] = value;
|
|
64
|
-
this?.
|
|
64
|
+
this?.scheduleRender();
|
|
65
65
|
delete this[name];
|
|
66
66
|
Object.defineProperty(this, name, {
|
|
67
67
|
configurable: true,
|
|
@@ -102,7 +102,7 @@ export const property = (propertyOptions: PropertyOptions) => {
|
|
|
102
102
|
}
|
|
103
103
|
const handleChange = () => {
|
|
104
104
|
if (this[sym] !== oldValue) {
|
|
105
|
-
this?.
|
|
105
|
+
this?.scheduleRender && this.scheduleRender();
|
|
106
106
|
this?.updated && this.updated(name, oldValue, this[sym]);
|
|
107
107
|
}
|
|
108
108
|
};
|
|
@@ -135,7 +135,7 @@ export const property = (propertyOptions: PropertyOptions) => {
|
|
|
135
135
|
}
|
|
136
136
|
}
|
|
137
137
|
handleChange();
|
|
138
|
-
this?.
|
|
138
|
+
this?.scheduleRender && this.scheduleRender();
|
|
139
139
|
},
|
|
140
140
|
});
|
|
141
141
|
};
|
package/src/sample/sample.tsx
CHANGED
|
@@ -1,6 +1,13 @@
|
|
|
1
1
|
import { Highlightable } from "./mixin/highlight";
|
|
2
2
|
import anime from "animejs";
|
|
3
3
|
|
|
4
|
+
import {customElementConfig as CustomElementConfig} from "../decorators/custom-element-config";
|
|
5
|
+
import {property as Property, AttributeConverter} from "../decorators/property";
|
|
6
|
+
import {propertyRenderOnSet as PropertyRenderOnSet} from "../decorators/render-property-on-set";
|
|
7
|
+
import {query as Query} from "../decorators/query";
|
|
8
|
+
import {CustomElement} from "../custom-element";
|
|
9
|
+
import {CustomElementController} from "../custom-element-controller";
|
|
10
|
+
|
|
4
11
|
@CustomElementConfig({
|
|
5
12
|
tagName: "my-button",
|
|
6
13
|
})
|
|
@@ -10,7 +17,6 @@ export class MyButton extends CustomElement {
|
|
|
10
17
|
render = () => {
|
|
11
18
|
return <button class="foo"><slot></slot></button>;
|
|
12
19
|
}
|
|
13
|
-
|
|
14
20
|
}
|
|
15
21
|
|
|
16
22
|
@CustomElementConfig({
|
|
@@ -263,10 +269,18 @@ class DisabledController extends CustomElementController {
|
|
|
263
269
|
return true;
|
|
264
270
|
}
|
|
265
271
|
|
|
266
|
-
updated() {
|
|
267
|
-
console.info("updated",
|
|
272
|
+
updated(property, oldValue, newValue) {
|
|
273
|
+
console.info("updated", { property, oldValue, newValue });
|
|
268
274
|
this.#updateAttributes();
|
|
269
275
|
}
|
|
276
|
+
|
|
277
|
+
hostRenderStart(isFirstRender) {
|
|
278
|
+
console.info("hostRenderStart", { isFirstRender, controller: this });
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
hostRenderDone(isFirstRender) {
|
|
282
|
+
console.info("hostRenderDone", { isFirstRender, controller: this });
|
|
283
|
+
}
|
|
270
284
|
}
|
|
271
285
|
|
|
272
286
|
@CustomElementConfig({
|
|
@@ -317,6 +331,14 @@ class PFoo extends CustomElement {
|
|
|
317
331
|
}
|
|
318
332
|
}
|
|
319
333
|
|
|
334
|
+
renderStart(isFirstRender) {
|
|
335
|
+
console.info("renderStart", { isFirstRender, tag: this.tagName });
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
renderDone(isFirstRender) {
|
|
339
|
+
console.info("renderDone", { isFirstRender, tag: this.tagName });
|
|
340
|
+
}
|
|
341
|
+
|
|
320
342
|
render = () => {
|
|
321
343
|
return <div classes={{ foo: true, "foo__disabled": this.disabledController.disabled }}>
|
|
322
344
|
<div >Hello {this.name} {this.nickName ? <span> ({this.nickName})</span> : null}</div>
|