p-elements-core 1.2.30 → 1.2.32-rc-10

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.
Files changed (82) hide show
  1. package/.editorconfig +17 -17
  2. package/.gitlab-ci.yml +18 -18
  3. package/CHANGELOG.md +201 -0
  4. package/demo/sample.js +1 -1
  5. package/demo/screen.css +16 -16
  6. package/demo/theme.css +1 -0
  7. package/dist/p-elements-core-modern.js +1 -1
  8. package/dist/p-elements-core.js +1 -1
  9. package/docs/package-lock.json +6897 -6897
  10. package/docs/package.json +27 -27
  11. package/docs/src/404.md +8 -8
  12. package/docs/src/_data/demos/hello-world/hello-world.tsx +35 -35
  13. package/docs/src/_data/demos/hello-world/index.html +10 -10
  14. package/docs/src/_data/demos/hello-world/project.json +7 -7
  15. package/docs/src/_data/demos/timer/demo-timer.tsx +120 -120
  16. package/docs/src/_data/demos/timer/icons.tsx +62 -62
  17. package/docs/src/_data/demos/timer/index.html +12 -12
  18. package/docs/src/_data/demos/timer/project.json +8 -8
  19. package/docs/src/_data/global.js +13 -13
  20. package/docs/src/_data/helpers.js +19 -19
  21. package/docs/src/_includes/layouts/base.njk +30 -30
  22. package/docs/src/_includes/layouts/playground.njk +40 -40
  23. package/docs/src/_includes/partials/app-header.njk +8 -8
  24. package/docs/src/_includes/partials/head.njk +14 -14
  25. package/docs/src/_includes/partials/nav.njk +19 -19
  26. package/docs/src/_includes/partials/top-nav.njk +51 -51
  27. package/docs/src/documentation/custom-element.md +221 -221
  28. package/docs/src/documentation/decorators/bind.md +71 -71
  29. package/docs/src/documentation/decorators/custom-element-config.md +63 -63
  30. package/docs/src/documentation/decorators/property.md +83 -83
  31. package/docs/src/documentation/decorators/query.md +66 -66
  32. package/docs/src/documentation/decorators/render-property-on-set.md +60 -60
  33. package/docs/src/documentation/decorators.md +9 -9
  34. package/docs/src/documentation/reactive-properties.md +53 -53
  35. package/docs/src/index.d.ts +25 -25
  36. package/docs/src/index.md +3 -3
  37. package/docs/src/scripts/components/app-mode-switch/app-mode-switch.css +78 -78
  38. package/docs/src/scripts/components/app-mode-switch/app-mode-switch.tsx +166 -166
  39. package/docs/src/scripts/components/app-playground/app-playground.tsx +189 -189
  40. package/docs/tsconfig.json +22 -22
  41. package/index.html +15 -2
  42. package/p-elements-core.d.ts +12 -3
  43. package/package.json +11 -4
  44. package/readme.md +206 -206
  45. package/src/custom-element-controller.test.ts +226 -0
  46. package/src/custom-element-controller.ts +31 -31
  47. package/src/custom-element.test.ts +906 -0
  48. package/src/custom-element.ts +471 -188
  49. package/src/custom-style-element.ts +4 -1
  50. package/src/decorators/bind.test.ts +163 -0
  51. package/src/decorators/bind.ts +46 -46
  52. package/src/decorators/custom-element-config.ts +17 -17
  53. package/src/decorators/property.test.ts +279 -0
  54. package/src/decorators/property.ts +822 -150
  55. package/src/decorators/query.test.ts +146 -0
  56. package/src/decorators/query.ts +12 -12
  57. package/src/decorators/render-property-on-set.ts +3 -3
  58. package/src/helpers/css.test.ts +150 -0
  59. package/src/helpers/css.ts +71 -71
  60. package/src/maquette/cache.test.ts +150 -0
  61. package/src/maquette/cache.ts +35 -35
  62. package/src/maquette/dom.test.ts +263 -0
  63. package/src/maquette/dom.ts +115 -115
  64. package/src/maquette/h.test.ts +165 -0
  65. package/src/maquette/h.ts +100 -100
  66. package/src/maquette/index.ts +12 -12
  67. package/src/maquette/interfaces.ts +536 -536
  68. package/src/maquette/jsx.ts +61 -61
  69. package/src/maquette/mapping.test.ts +294 -0
  70. package/src/maquette/mapping.ts +56 -56
  71. package/src/maquette/maquette.test.ts +493 -0
  72. package/src/maquette/projection.test.ts +366 -0
  73. package/src/maquette/projection.ts +666 -666
  74. package/src/maquette/projector.test.ts +351 -0
  75. package/src/maquette/projector.ts +200 -200
  76. package/src/sample/mixin/highlight.tsx +33 -32
  77. package/src/sample/sample.tsx +167 -7
  78. package/src/test-setup.ts +85 -0
  79. package/src/test-utils.ts +223 -0
  80. package/tsconfig.json +1 -0
  81. package/vitest.config.ts +41 -0
  82. package/webpack.config.js +1 -1
package/readme.md CHANGED
@@ -1,206 +1,206 @@
1
- # P-Element
2
-
3
- ## CustomElement base class
4
-
5
- ### Static properties
6
-
7
- #### `projectorMode` "append", "merge" or "replace"
8
-
9
- The projector mode when using `templateFromString` function
10
-
11
- #### `style` string
12
-
13
- The style is adopted to the rootNode.
14
- if this is set there is no need for calling `templateFromString`. A root node is created and replaced with the result of the `render` function.
15
-
16
- example
17
-
18
- ``` typescript
19
- class MyElement extends CustomElement {
20
- static style = `
21
- :host {
22
- color: red;
23
- }`;
24
-
25
- render = () :VNode {
26
- return <div>Hello world</div>;
27
- }
28
- }
29
- ```
30
-
31
- #### `isFormAssociated` boolean
32
-
33
- If true, elementInternals are created using attachInternals in the constructor.
34
-
35
- example
36
-
37
- ``` typescript
38
- class MyElement extends CustomElement {
39
-
40
- static isFormAssociated = true;
41
-
42
- @Property({type: "string", attribute: "value", reflect: true })
43
- value: string = "Peter" ;
44
-
45
- updated(property: string, oldValue: any, newValue: any) {
46
- if (property === "value"){
47
- this.internals.setFormValue(this.value);
48
- }
49
- }
50
-
51
- render = () :VNode {
52
- return <div>Hello {this.value}.</div>;
53
- }
54
- }
55
- ```
56
-
57
- ### Decorators
58
-
59
- #### `@CustomElementConfig`
60
-
61
- Use this decorator to define the custom element
62
-
63
- example
64
-
65
- ``` typescript
66
- @CustomElementConfig({
67
- tagName: "p-foo",
68
- })
69
- class PFooElement extends CustomElement {
70
- ...
71
- }
72
- ```
73
-
74
- If you want to extend a build in component you need to specify the buildin.
75
-
76
- example
77
-
78
- ``` typescript
79
- @CustomElementConfig({
80
- tagName: "super-a",
81
- options: {
82
- extends: "a",
83
- },
84
- })
85
- class SuperAnchorElement extends HTMLAnchorElement {
86
- ...
87
- }
88
- ```
89
-
90
- #### `@Property`
91
-
92
- Use the `@Property` decorator to define reactive properties.
93
-
94
- example
95
-
96
- ``` typescript
97
- @CustomElementConfig({
98
- tagName: "p-foo",
99
- })
100
- class PFooElement extends CustomElement {
101
- ...
102
-
103
- @Property({type: "string", attribute: "nick-name", reflect: true})
104
- nickName: string;
105
-
106
- attributeChangedCallback(name: string, oldValue: string, newValue: string): void {
107
- super.attributeChangedCallback(name, oldValue, newValue);
108
- ...
109
- }
110
- ```
111
- The `type` option could be "string", "number", "boolean" or "object".
112
-
113
- If `attribute` option is set the property will be set on attribute change. If you implement a `attributeChangeCallback` you need to call the `super.attributeChangedCallback`.
114
-
115
- If `reflect` is `true` the attribute is set on property change.
116
-
117
- Use `converter` option to convert attribute to property
118
-
119
- ``` typescript
120
- const stringArrayConverter: AttributeConverter<string[]> = {
121
- fromAttribute: (value) => {
122
- if (!value) {
123
- return null;
124
- }
125
- return value.split(",").map((v) => v.trim());
126
- },
127
- toAttribute: (value) => {
128
- if (!value.join) {
129
- return null;
130
- }
131
- return value.join(",");
132
- },
133
- };
134
-
135
- class MyElement extend CustomElement {
136
- @Property({attribute: "items", reflect: true, converter: stringArrayConverter})
137
- items: string[] = ["foo", "bar"];
138
- }
139
- ```
140
- #### `@Query` decorator
141
-
142
- Use the `@Query` decorator to define a property that returns an element from the shadow dom.
143
-
144
- example
145
-
146
- ``` typescript
147
- class PFooElement extends CustomElement {
148
- ...
149
- @Query("#MyInput")
150
- nameInput: HTMLInputElement;
151
-
152
- render = () => {
153
- return <div>
154
- <label for="MyInput"></label>
155
- <input type="text" id="MyInput" />
156
- </div>;
157
- }
158
- }
159
- ```
160
-
161
- #### `@PropertyRenderOnSet` `@RenderOnSet`
162
-
163
- Properties decorated with `@PropertyRenderOnSet` or `@RenderOnSet` call renderNow when setting a value.
164
-
165
- example
166
-
167
- ``` typescript
168
- class PFooElement extends CustomElement {
169
- ...
170
- @PropertyRenderOnSet
171
- public foo: string = "foo";
172
- }
173
- ```
174
-
175
- #### `@Bind`
176
- (deprecated, use arrow function `myFn = () => console.log('myFn')`)
177
-
178
- Functions decorated with `@Bind` will be replaced with the result of bind(this) on the function.
179
-
180
-
181
- ### Hooks
182
-
183
- #### `init`
184
-
185
- The init is the first function called after initialising of the custom element
186
-
187
- #### `shouldUpdate`
188
-
189
- Before a property is set to a new value
190
-
191
- #### `updated`
192
-
193
- After a property value is set to a new value
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
-
203
- #### `attributeChangedCallback`
204
-
205
- Call `super.attributeChangedCallback()` first.
206
-
1
+ # P-Element
2
+
3
+ ## CustomElement base class
4
+
5
+ ### Static properties
6
+
7
+ #### `projectorMode` "append", "merge" or "replace"
8
+
9
+ The projector mode when using `templateFromString` function
10
+
11
+ #### `style` string
12
+
13
+ The style is adopted to the rootNode.
14
+ if this is set there is no need for calling `templateFromString`. A root node is created and replaced with the result of the `render` function.
15
+
16
+ example
17
+
18
+ ``` typescript
19
+ class MyElement extends CustomElement {
20
+ static style = `
21
+ :host {
22
+ color: red;
23
+ }`;
24
+
25
+ render = () :VNode {
26
+ return <div>Hello world</div>;
27
+ }
28
+ }
29
+ ```
30
+
31
+ #### `isFormAssociated` boolean
32
+
33
+ If true, elementInternals are created using attachInternals in the constructor.
34
+
35
+ example
36
+
37
+ ``` typescript
38
+ class MyElement extends CustomElement {
39
+
40
+ static isFormAssociated = true;
41
+
42
+ @Property({type: "string", attribute: "value", reflect: true })
43
+ value: string = "Peter" ;
44
+
45
+ updated(property: string, oldValue: any, newValue: any) {
46
+ if (property === "value"){
47
+ this.internals.setFormValue(this.value);
48
+ }
49
+ }
50
+
51
+ render = () :VNode {
52
+ return <div>Hello {this.value}.</div>;
53
+ }
54
+ }
55
+ ```
56
+
57
+ ### Decorators
58
+
59
+ #### `@CustomElementConfig`
60
+
61
+ Use this decorator to define the custom element
62
+
63
+ example
64
+
65
+ ``` typescript
66
+ @CustomElementConfig({
67
+ tagName: "p-foo",
68
+ })
69
+ class PFooElement extends CustomElement {
70
+ ...
71
+ }
72
+ ```
73
+
74
+ If you want to extend a build in component you need to specify the buildin.
75
+
76
+ example
77
+
78
+ ``` typescript
79
+ @CustomElementConfig({
80
+ tagName: "super-a",
81
+ options: {
82
+ extends: "a",
83
+ },
84
+ })
85
+ class SuperAnchorElement extends HTMLAnchorElement {
86
+ ...
87
+ }
88
+ ```
89
+
90
+ #### `@Property`
91
+
92
+ Use the `@Property` decorator to define reactive properties.
93
+
94
+ example
95
+
96
+ ``` typescript
97
+ @CustomElementConfig({
98
+ tagName: "p-foo",
99
+ })
100
+ class PFooElement extends CustomElement {
101
+ ...
102
+
103
+ @Property({type: "string", attribute: "nick-name", reflect: true})
104
+ nickName: string;
105
+
106
+ attributeChangedCallback(name: string, oldValue: string, newValue: string): void {
107
+ super.attributeChangedCallback(name, oldValue, newValue);
108
+ ...
109
+ }
110
+ ```
111
+ The `type` option could be "string", "number", "boolean" or "object".
112
+
113
+ If `attribute` option is set the property will be set on attribute change. If you implement a `attributeChangeCallback` you need to call the `super.attributeChangedCallback`.
114
+
115
+ If `reflect` is `true` the attribute is set on property change.
116
+
117
+ Use `converter` option to convert attribute to property
118
+
119
+ ``` typescript
120
+ const stringArrayConverter: AttributeConverter<string[]> = {
121
+ fromAttribute: (value) => {
122
+ if (!value) {
123
+ return null;
124
+ }
125
+ return value.split(",").map((v) => v.trim());
126
+ },
127
+ toAttribute: (value) => {
128
+ if (!value.join) {
129
+ return null;
130
+ }
131
+ return value.join(",");
132
+ },
133
+ };
134
+
135
+ class MyElement extend CustomElement {
136
+ @Property({attribute: "items", reflect: true, converter: stringArrayConverter})
137
+ items: string[] = ["foo", "bar"];
138
+ }
139
+ ```
140
+ #### `@Query` decorator
141
+
142
+ Use the `@Query` decorator to define a property that returns an element from the shadow dom.
143
+
144
+ example
145
+
146
+ ``` typescript
147
+ class PFooElement extends CustomElement {
148
+ ...
149
+ @Query("#MyInput")
150
+ nameInput: HTMLInputElement;
151
+
152
+ render = () => {
153
+ return <div>
154
+ <label for="MyInput"></label>
155
+ <input type="text" id="MyInput" />
156
+ </div>;
157
+ }
158
+ }
159
+ ```
160
+
161
+ #### `@PropertyRenderOnSet` `@RenderOnSet`
162
+
163
+ Properties decorated with `@PropertyRenderOnSet` or `@RenderOnSet` call renderNow when setting a value.
164
+
165
+ example
166
+
167
+ ``` typescript
168
+ class PFooElement extends CustomElement {
169
+ ...
170
+ @PropertyRenderOnSet
171
+ public foo: string = "foo";
172
+ }
173
+ ```
174
+
175
+ #### `@Bind`
176
+ (deprecated, use arrow function `myFn = () => console.log('myFn')`)
177
+
178
+ Functions decorated with `@Bind` will be replaced with the result of bind(this) on the function.
179
+
180
+
181
+ ### Hooks
182
+
183
+ #### `init`
184
+
185
+ The init is the first function called after initialising of the custom element
186
+
187
+ #### `shouldUpdate`
188
+
189
+ Before a property is set to a new value
190
+
191
+ #### `updated`
192
+
193
+ After a property value is set to a new value
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
+
203
+ #### `attributeChangedCallback`
204
+
205
+ Call `super.attributeChangedCallback()` first.
206
+
@@ -0,0 +1,226 @@
1
+ /**
2
+ * Tests for CustomElementController
3
+ */
4
+
5
+ import { describe, it, expect } from 'vitest';
6
+ import './test-setup.js';
7
+ import { CustomElement } from './custom-element.js';
8
+ import { CustomElementController } from './custom-element-controller.js';
9
+ import { customElementConfig } from './decorators/custom-element-config.js';
10
+ import { generateUniqueTagName } from './test-setup.js';
11
+ import { waitForRender } from './test-utils.js';
12
+
13
+ describe('CustomElementController', () => {
14
+ describe('Controller lifecycle', () => {
15
+ it('should register controller with host element', async () => {
16
+ const tagName = generateUniqueTagName('controller-test');
17
+ let controller: TestController | null = null;
18
+
19
+ class TestController extends CustomElementController {
20
+ testMethod() {
21
+ return 'test';
22
+ }
23
+ }
24
+
25
+ @customElementConfig({ tagName })
26
+ class ControllerTest extends CustomElement {
27
+ controller: TestController;
28
+
29
+ init() {
30
+ this.controller = new TestController(this);
31
+ }
32
+
33
+ render() {
34
+ return { vnodeSelector: 'div', properties: {}, children: [], text: undefined, domNode: null };
35
+ }
36
+ }
37
+
38
+ const el = document.createElement(tagName) as ControllerTest;
39
+ document.body.appendChild(el);
40
+ await waitForRender(el);
41
+
42
+ expect(el.controller).toBeDefined();
43
+ expect(el.controller.hostElement).toBe(el);
44
+ expect(el.controller.testMethod()).toBe('test');
45
+
46
+ document.body.removeChild(el);
47
+ });
48
+
49
+ it('should call controller.connected() on element connection', async () => {
50
+ const tagName = generateUniqueTagName('controller-test');
51
+ let connectedCalled = false;
52
+
53
+ class TestController extends CustomElementController {
54
+ connected() {
55
+ connectedCalled = true;
56
+ }
57
+ }
58
+
59
+ @customElementConfig({ tagName })
60
+ class ControllerTest extends CustomElement {
61
+ init() {
62
+ new TestController(this);
63
+ }
64
+
65
+ render() {
66
+ return { vnodeSelector: 'div', properties: {}, children: [], text: undefined, domNode: null };
67
+ }
68
+ }
69
+
70
+ const el = document.createElement(tagName) as ControllerTest;
71
+ expect(connectedCalled).toBe(false);
72
+
73
+ document.body.appendChild(el);
74
+ await waitForRender(el);
75
+
76
+ expect(connectedCalled).toBe(true);
77
+ document.body.removeChild(el);
78
+ });
79
+
80
+ it('should call controller.disconnected() on element disconnection', async () => {
81
+ const tagName = generateUniqueTagName('controller-test');
82
+ let disconnectedCalled = false;
83
+
84
+ class TestController extends CustomElementController {
85
+ disconnected() {
86
+ disconnectedCalled = true;
87
+ }
88
+ }
89
+
90
+ @customElementConfig({ tagName })
91
+ class ControllerTest extends CustomElement {
92
+ static style = ':host { display: block; }';
93
+
94
+ init() {
95
+ new TestController(this);
96
+ }
97
+
98
+ render() {
99
+ return { vnodeSelector: 'div', properties: {}, children: [], text: undefined, domNode: null };
100
+ }
101
+ }
102
+
103
+ const el = document.createElement(tagName) as ControllerTest;
104
+ document.body.appendChild(el);
105
+ await waitForRender(el);
106
+
107
+ expect(disconnectedCalled).toBe(false);
108
+
109
+ document.body.removeChild(el);
110
+ expect(disconnectedCalled).toBe(true);
111
+ });
112
+
113
+ it('should trigger render when controller calls renderNow()', async () => {
114
+ const tagName = generateUniqueTagName('controller-test');
115
+ let renderCount = 0;
116
+
117
+ class TestController extends CustomElementController {
118
+ triggerRender() {
119
+ this.renderNow();
120
+ }
121
+ }
122
+
123
+ @customElementConfig({ tagName })
124
+ class ControllerTest extends CustomElement {
125
+ static style = ':host { display: block; }';
126
+ controller: TestController;
127
+
128
+ init() {
129
+ this.controller = new TestController(this);
130
+ }
131
+
132
+ render() {
133
+ renderCount++;
134
+ return { vnodeSelector: 'div', properties: {}, children: [], text: undefined, domNode: null };
135
+ }
136
+ }
137
+
138
+ const el = document.createElement(tagName) as ControllerTest;
139
+ document.body.appendChild(el);
140
+ await waitForRender(el);
141
+
142
+ const initialRenderCount = renderCount;
143
+ el.controller.triggerRender();
144
+ await waitForRender(el);
145
+
146
+ expect(renderCount).toBeGreaterThan(initialRenderCount);
147
+ document.body.removeChild(el);
148
+ });
149
+
150
+ it('should schedule render when controller calls scheduleRender()', async () => {
151
+ const tagName = generateUniqueTagName('controller-test');
152
+ let renderCount = 0;
153
+
154
+ class TestController extends CustomElementController {
155
+ triggerSchedule() {
156
+ this.scheduleRender();
157
+ }
158
+ }
159
+
160
+ @customElementConfig({ tagName })
161
+ class ControllerTest extends CustomElement {
162
+ static style = ':host { display: block; }';
163
+ controller: TestController;
164
+
165
+ init() {
166
+ this.controller = new TestController(this);
167
+ }
168
+
169
+ render() {
170
+ renderCount++;
171
+ return { vnodeSelector: 'div', properties: {}, children: [], text: undefined, domNode: null };
172
+ }
173
+ }
174
+
175
+ const el = document.createElement(tagName) as ControllerTest;
176
+ document.body.appendChild(el);
177
+ await waitForRender(el);
178
+
179
+ const initialRenderCount = renderCount;
180
+ el.controller.triggerSchedule();
181
+ await waitForRender(el);
182
+
183
+ expect(renderCount).toBeGreaterThan(initialRenderCount);
184
+ document.body.removeChild(el);
185
+ });
186
+
187
+ it('should call hostRenderStart and hostRenderDone hooks', async () => {
188
+ const tagName = generateUniqueTagName('controller-test');
189
+ let startCalled = false;
190
+ let doneCalled = false;
191
+
192
+ class TestController extends CustomElementController {
193
+ hostRenderStart() {
194
+ startCalled = true;
195
+ }
196
+
197
+ hostRenderDone() {
198
+ doneCalled = true;
199
+ }
200
+ }
201
+
202
+ @customElementConfig({ tagName })
203
+ class ControllerTest extends CustomElement {
204
+ static style = ':host { display: block; }';
205
+
206
+ constructor() {
207
+ super();
208
+ new TestController(this);
209
+ }
210
+
211
+ render() {
212
+ return { vnodeSelector: 'div', properties: {}, children: [], text: undefined, domNode: null };
213
+ }
214
+ }
215
+
216
+ const el = document.createElement(tagName) as ControllerTest;
217
+ document.body.appendChild(el);
218
+ await waitForRender(el);
219
+
220
+ expect(startCalled).toBe(true);
221
+ expect(doneCalled).toBe(true);
222
+
223
+ document.body.removeChild(el);
224
+ });
225
+ });
226
+ });
@@ -1,31 +1,31 @@
1
- import type { CustomElement } from './custom-element';
2
-
3
- export interface ICustomElementController {
4
- renderNow(): void;
5
- init?: () => void;
6
- connected? : () => void;
7
- disconnected? : () => void;
8
- hostRenderStart?: () => void;
9
- hostRenderDone? : () => void;
10
- hostElement: CustomElement;
11
- }
12
- export abstract class CustomElementController implements ICustomElementController {
13
- constructor(hostElement: CustomElement) {
14
- this.#hostElement = hostElement;
15
- this.#hostElement.addController(this);
16
- }
17
-
18
- #hostElement: CustomElement;
19
-
20
- get hostElement() {
21
- return this.#hostElement;
22
- }
23
-
24
- renderNow() {
25
- this.hostElement?.renderNow();
26
- }
27
-
28
- scheduleRender() {
29
- this.hostElement?.scheduleRender();
30
- }
31
- }
1
+ import type { CustomElement } from './custom-element';
2
+
3
+ export interface ICustomElementController {
4
+ renderNow(): void;
5
+ init?: () => void;
6
+ connected? : () => void;
7
+ disconnected? : () => void;
8
+ hostRenderStart?: () => void;
9
+ hostRenderDone? : () => void;
10
+ hostElement: CustomElement;
11
+ }
12
+ export abstract class CustomElementController implements ICustomElementController {
13
+ constructor(hostElement: CustomElement) {
14
+ this.#hostElement = hostElement;
15
+ this.#hostElement.addController(this);
16
+ }
17
+
18
+ #hostElement: CustomElement;
19
+
20
+ get hostElement() {
21
+ return this.#hostElement;
22
+ }
23
+
24
+ renderNow() {
25
+ this.hostElement?.renderNow();
26
+ }
27
+
28
+ scheduleRender() {
29
+ this.hostElement?.scheduleRender();
30
+ }
31
+ }