@lightningtv/solid 3.0.0-2 → 3.0.0-21

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 (206) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +6 -0
  3. package/dist/src/activeElement.d.ts +1 -1
  4. package/dist/src/core/animation.d.ts +35 -0
  5. package/dist/src/core/animation.js +120 -0
  6. package/dist/src/core/animation.js.map +1 -0
  7. package/dist/src/core/config.d.ts +47 -0
  8. package/dist/src/core/config.js +23 -0
  9. package/dist/src/core/config.js.map +1 -0
  10. package/dist/src/core/domRenderer.d.ts +117 -0
  11. package/dist/src/core/domRenderer.js +1160 -0
  12. package/dist/src/core/domRenderer.js.map +1 -0
  13. package/dist/src/core/elementNode.d.ts +209 -0
  14. package/dist/src/core/elementNode.js +829 -0
  15. package/dist/src/core/elementNode.js.map +1 -0
  16. package/dist/src/core/flex.d.ts +2 -0
  17. package/dist/src/core/flex.js +243 -0
  18. package/dist/src/core/flex.js.map +1 -0
  19. package/dist/src/core/focusKeyTypes.d.ts +42 -0
  20. package/dist/src/core/focusKeyTypes.js +2 -0
  21. package/dist/src/core/focusKeyTypes.js.map +1 -0
  22. package/dist/src/core/focusManager.d.ts +13 -0
  23. package/dist/src/core/focusManager.js +269 -0
  24. package/dist/src/core/focusManager.js.map +1 -0
  25. package/dist/src/core/index.d.ts +12 -0
  26. package/dist/src/core/index.js +12 -0
  27. package/dist/src/core/index.js.map +1 -0
  28. package/dist/src/core/intrinsicTypes.d.ts +90 -0
  29. package/dist/src/core/intrinsicTypes.js +2 -0
  30. package/dist/src/core/intrinsicTypes.js.map +1 -0
  31. package/dist/src/core/lightningInit.d.ts +89 -0
  32. package/dist/src/core/lightningInit.js +26 -0
  33. package/dist/src/core/lightningInit.js.map +1 -0
  34. package/dist/src/core/nodeTypes.d.ts +6 -0
  35. package/dist/src/core/nodeTypes.js +6 -0
  36. package/dist/src/core/nodeTypes.js.map +1 -0
  37. package/dist/src/core/shaders.d.ts +51 -0
  38. package/dist/src/core/shaders.js +446 -0
  39. package/dist/src/core/shaders.js.map +1 -0
  40. package/dist/src/core/states.d.ts +12 -0
  41. package/dist/src/core/states.js +84 -0
  42. package/dist/src/core/states.js.map +1 -0
  43. package/dist/src/core/timings.d.ts +36 -0
  44. package/dist/src/core/timings.js +199 -0
  45. package/dist/src/core/timings.js.map +1 -0
  46. package/dist/src/core/utils.d.ts +39 -0
  47. package/dist/src/core/utils.js +164 -0
  48. package/dist/src/core/utils.js.map +1 -0
  49. package/dist/src/devtools/index.d.ts +1 -1
  50. package/dist/src/devtools/index.js +1 -1
  51. package/dist/src/devtools/index.js.map +1 -1
  52. package/dist/src/index.d.ts +3 -3
  53. package/dist/src/index.js +1 -1
  54. package/dist/src/index.js.map +1 -1
  55. package/dist/src/jsx-runtime.d.ts +1 -3
  56. package/dist/src/primitives/Column.jsx +9 -10
  57. package/dist/src/primitives/Column.jsx.map +1 -1
  58. package/dist/src/primitives/FPSCounter.jsx +14 -1
  59. package/dist/src/primitives/FPSCounter.jsx.map +1 -1
  60. package/dist/src/primitives/Grid.d.ts +15 -6
  61. package/dist/src/primitives/Grid.jsx +35 -22
  62. package/dist/src/primitives/Grid.jsx.map +1 -1
  63. package/dist/src/primitives/Image.d.ts +8 -0
  64. package/dist/src/primitives/Image.jsx +24 -0
  65. package/dist/src/primitives/Image.jsx.map +1 -0
  66. package/dist/src/primitives/KeepAlive.d.ts +30 -0
  67. package/dist/src/primitives/KeepAlive.jsx +77 -0
  68. package/dist/src/primitives/KeepAlive.jsx.map +1 -0
  69. package/dist/src/primitives/Lazy.d.ts +8 -7
  70. package/dist/src/primitives/Lazy.jsx +52 -23
  71. package/dist/src/primitives/Lazy.jsx.map +1 -1
  72. package/dist/src/primitives/Marquee.d.ts +64 -0
  73. package/dist/src/primitives/Marquee.jsx +86 -0
  74. package/dist/src/primitives/Marquee.jsx.map +1 -0
  75. package/dist/src/primitives/Preserve.d.ts +4 -0
  76. package/dist/src/primitives/Preserve.jsx +11 -0
  77. package/dist/src/primitives/Preserve.jsx.map +1 -0
  78. package/dist/src/primitives/Row.jsx +9 -10
  79. package/dist/src/primitives/Row.jsx.map +1 -1
  80. package/dist/src/primitives/Suspense.d.ts +22 -0
  81. package/dist/src/primitives/Suspense.jsx +33 -0
  82. package/dist/src/primitives/Suspense.jsx.map +1 -0
  83. package/dist/src/primitives/Virtual.d.ts +18 -0
  84. package/dist/src/primitives/Virtual.jsx +434 -0
  85. package/dist/src/primitives/Virtual.jsx.map +1 -0
  86. package/dist/src/primitives/VirtualGrid.d.ts +13 -0
  87. package/dist/src/primitives/VirtualGrid.jsx +160 -0
  88. package/dist/src/primitives/VirtualGrid.jsx.map +1 -0
  89. package/dist/src/primitives/VirtualList.d.ts +11 -0
  90. package/dist/src/primitives/VirtualList.jsx +96 -0
  91. package/dist/src/primitives/VirtualList.jsx.map +1 -0
  92. package/dist/src/primitives/VirtualRow.d.ts +13 -0
  93. package/dist/src/primitives/VirtualRow.jsx +97 -0
  94. package/dist/src/primitives/VirtualRow.jsx.map +1 -0
  95. package/dist/src/primitives/Visible.d.ts +0 -1
  96. package/dist/src/primitives/Visible.jsx +1 -1
  97. package/dist/src/primitives/Visible.jsx.map +1 -1
  98. package/dist/src/primitives/announcer/announcer.d.ts +2 -0
  99. package/dist/src/primitives/announcer/announcer.js +7 -5
  100. package/dist/src/primitives/announcer/announcer.js.map +1 -1
  101. package/dist/src/primitives/announcer/index.d.ts +5 -1
  102. package/dist/src/primitives/announcer/index.js +8 -2
  103. package/dist/src/primitives/announcer/index.js.map +1 -1
  104. package/dist/src/primitives/announcer/speech.d.ts +2 -2
  105. package/dist/src/primitives/announcer/speech.js +157 -28
  106. package/dist/src/primitives/announcer/speech.js.map +1 -1
  107. package/dist/src/primitives/createFocusStack.d.ts +4 -4
  108. package/dist/src/primitives/createFocusStack.jsx +15 -6
  109. package/dist/src/primitives/createFocusStack.jsx.map +1 -1
  110. package/dist/src/primitives/createTag.d.ts +8 -0
  111. package/dist/src/primitives/createTag.jsx +20 -0
  112. package/dist/src/primitives/createTag.jsx.map +1 -0
  113. package/dist/src/primitives/index.d.ts +14 -4
  114. package/dist/src/primitives/index.js +13 -3
  115. package/dist/src/primitives/index.js.map +1 -1
  116. package/dist/src/primitives/types.d.ts +5 -2
  117. package/dist/src/primitives/useFocusManager.d.ts +2 -2
  118. package/dist/src/primitives/useFocusManager.js +2 -2
  119. package/dist/src/primitives/useFocusManager.js.map +1 -1
  120. package/dist/src/primitives/useHold.d.ts +27 -0
  121. package/dist/src/primitives/useHold.js +54 -0
  122. package/dist/src/primitives/useHold.js.map +1 -0
  123. package/dist/src/primitives/useMouse.d.ts +18 -2
  124. package/dist/src/primitives/useMouse.js +171 -47
  125. package/dist/src/primitives/useMouse.js.map +1 -1
  126. package/dist/src/primitives/utils/chainFunctions.d.ts +30 -4
  127. package/dist/src/primitives/utils/chainFunctions.js +14 -3
  128. package/dist/src/primitives/utils/chainFunctions.js.map +1 -1
  129. package/dist/src/primitives/utils/createBlurredImage.d.ts +56 -0
  130. package/dist/src/primitives/utils/createBlurredImage.js +223 -0
  131. package/dist/src/primitives/utils/createBlurredImage.js.map +1 -0
  132. package/dist/src/primitives/utils/createSpriteMap.d.ts +2 -2
  133. package/dist/src/primitives/utils/createSpriteMap.js +1 -1
  134. package/dist/src/primitives/utils/createSpriteMap.js.map +1 -1
  135. package/dist/src/primitives/utils/handleNavigation.d.ts +79 -5
  136. package/dist/src/primitives/utils/handleNavigation.js +242 -69
  137. package/dist/src/primitives/utils/handleNavigation.js.map +1 -1
  138. package/dist/src/primitives/utils/withScrolling.d.ts +14 -2
  139. package/dist/src/primitives/utils/withScrolling.js +66 -7
  140. package/dist/src/primitives/utils/withScrolling.js.map +1 -1
  141. package/dist/src/render.d.ts +8 -7
  142. package/dist/src/render.js +5 -1
  143. package/dist/src/render.js.map +1 -1
  144. package/dist/src/solidOpts.d.ts +1 -7
  145. package/dist/src/solidOpts.js +32 -16
  146. package/dist/src/solidOpts.js.map +1 -1
  147. package/dist/src/types.d.ts +1 -13
  148. package/dist/src/universal.d.ts +25 -0
  149. package/dist/src/universal.js +232 -0
  150. package/dist/src/universal.js.map +1 -0
  151. package/dist/src/utils.d.ts +3 -1
  152. package/dist/src/utils.js +9 -1
  153. package/dist/src/utils.js.map +1 -1
  154. package/dist/tsconfig.tsbuildinfo +1 -1
  155. package/jsx-runtime.d.ts +2 -4
  156. package/package.json +17 -15
  157. package/src/activeElement.ts +1 -1
  158. package/src/core/animation.ts +183 -0
  159. package/src/core/config.ts +77 -0
  160. package/src/core/domRenderer.ts +1308 -0
  161. package/src/core/elementNode.ts +1198 -0
  162. package/src/core/flex.ts +284 -0
  163. package/src/core/focusKeyTypes.ts +87 -0
  164. package/src/core/focusManager.ts +359 -0
  165. package/src/core/index.ts +13 -0
  166. package/src/core/intrinsicTypes.ts +199 -0
  167. package/src/core/lightningInit.ts +147 -0
  168. package/src/core/nodeTypes.ts +6 -0
  169. package/src/core/shaders.ts +567 -0
  170. package/src/core/states.ts +91 -0
  171. package/src/core/timings.ts +261 -0
  172. package/src/core/utils.ts +222 -0
  173. package/src/devtools/index.ts +1 -1
  174. package/src/index.ts +3 -3
  175. package/src/primitives/Column.tsx +10 -12
  176. package/src/primitives/FPSCounter.tsx +15 -1
  177. package/src/primitives/Grid.tsx +57 -33
  178. package/src/primitives/Image.tsx +36 -0
  179. package/src/primitives/KeepAlive.tsx +124 -0
  180. package/src/primitives/Lazy.tsx +66 -37
  181. package/src/primitives/Marquee.tsx +149 -0
  182. package/src/primitives/Preserve.tsx +18 -0
  183. package/src/primitives/Row.tsx +13 -14
  184. package/src/primitives/Suspense.tsx +39 -0
  185. package/src/primitives/Virtual.tsx +478 -0
  186. package/src/primitives/VirtualGrid.tsx +220 -0
  187. package/src/primitives/Visible.tsx +1 -2
  188. package/src/primitives/announcer/announcer.ts +16 -10
  189. package/src/primitives/announcer/index.ts +12 -2
  190. package/src/primitives/announcer/speech.ts +188 -27
  191. package/src/primitives/createFocusStack.tsx +18 -7
  192. package/src/primitives/createTag.tsx +31 -0
  193. package/src/primitives/index.ts +18 -4
  194. package/src/primitives/types.ts +12 -2
  195. package/src/primitives/useFocusManager.ts +3 -3
  196. package/src/primitives/useHold.ts +69 -0
  197. package/src/primitives/useMouse.ts +306 -67
  198. package/src/primitives/utils/chainFunctions.ts +40 -9
  199. package/src/primitives/utils/createBlurredImage.ts +366 -0
  200. package/src/primitives/utils/createSpriteMap.ts +6 -4
  201. package/src/primitives/utils/handleNavigation.ts +300 -84
  202. package/src/primitives/utils/withScrolling.ts +91 -18
  203. package/src/render.ts +10 -8
  204. package/src/solidOpts.ts +31 -24
  205. package/src/types.ts +1 -15
  206. package/src/utils.ts +11 -1
@@ -0,0 +1,829 @@
1
+ import { renderer, } from './lightningInit.js';
2
+ import States from './states.js';
3
+ import calculateFlex from './flex.js';
4
+ import { log, isArray, isFunc, keyExists, isINode, isElementNode, isElementText, logRenderTree, isFunction, spliceItem, } from './utils.js';
5
+ import { Config, DOM_RENDERING, isDev, SHADERS_ENABLED } from './config.js';
6
+ import { assertTruthy } from '@lightningjs/renderer/utils';
7
+ import { NodeType } from './nodeTypes.js';
8
+ import { setActiveElement, } from './focusManager.js';
9
+ import simpleAnimation from './animation.js';
10
+ let layoutRunQueued = false;
11
+ const layoutQueue = new Set();
12
+ function addToLayoutQueue(node) {
13
+ layoutQueue.add(node);
14
+ if (!layoutRunQueued) {
15
+ layoutRunQueued = true;
16
+ queueMicrotask(runLayout);
17
+ }
18
+ }
19
+ function runLayout() {
20
+ layoutRunQueued = false;
21
+ const queue = [...layoutQueue];
22
+ layoutQueue.clear();
23
+ for (let i = queue.length - 1; i >= 0; i--) {
24
+ const node = queue[i];
25
+ node.updateLayout();
26
+ }
27
+ }
28
+ const parseAndAssignShaderProps = (prefix, obj, props = {}) => {
29
+ if (!obj)
30
+ return;
31
+ props[prefix] = obj;
32
+ Object.entries(obj).forEach(([key, value]) => {
33
+ let transformedKey = key === 'width' ? 'w' : key;
34
+ props[`${prefix}-${transformedKey}`] = value;
35
+ });
36
+ };
37
+ function convertToShader(_node, v) {
38
+ let type = 'rounded';
39
+ if (v.border)
40
+ type += 'WithBorder';
41
+ if (v.shadow)
42
+ type += 'WithShadow';
43
+ return renderer.createShader(type, v);
44
+ }
45
+ function getPropertyAlias(name) {
46
+ if (name === 'w')
47
+ return 'width';
48
+ if (name === 'h')
49
+ return 'height';
50
+ return name;
51
+ }
52
+ export const LightningRendererNumberProps = [
53
+ 'alpha',
54
+ 'color',
55
+ 'colorTop',
56
+ 'colorRight',
57
+ 'colorLeft',
58
+ 'colorBottom',
59
+ 'colorTl',
60
+ 'colorTr',
61
+ 'colorBl',
62
+ 'colorBr',
63
+ 'h',
64
+ 'fontSize',
65
+ 'lineHeight',
66
+ 'mount',
67
+ 'mountX',
68
+ 'mountY',
69
+ 'pivot',
70
+ 'pivotX',
71
+ 'pivotY',
72
+ 'rotation',
73
+ 'scale',
74
+ 'scaleX',
75
+ 'scaleY',
76
+ 'w',
77
+ 'worldX',
78
+ 'worldY',
79
+ 'x',
80
+ 'y',
81
+ 'zIndex',
82
+ 'zIndexLocked',
83
+ ];
84
+ const LightningRendererNonAnimatingProps = [
85
+ 'absX',
86
+ 'absY',
87
+ 'autosize',
88
+ 'clipping',
89
+ 'contain',
90
+ 'data',
91
+ 'destroyed',
92
+ 'fontFamily',
93
+ 'fontStretch',
94
+ 'fontStyle',
95
+ 'fontWeight',
96
+ 'imageType',
97
+ 'letterSpacing',
98
+ 'maxHeight',
99
+ 'maxLines',
100
+ 'maxWidth',
101
+ 'offsetY',
102
+ 'overflowSuffix',
103
+ 'preventCleanup',
104
+ 'rtt',
105
+ 'scrollable',
106
+ 'scrollY',
107
+ 'srcHeight',
108
+ 'srcWidth',
109
+ 'srcX',
110
+ 'srcY',
111
+ 'strictBounds',
112
+ 'text',
113
+ 'textAlign',
114
+ 'textBaseline',
115
+ 'textOverflow',
116
+ 'texture',
117
+ 'textureOptions',
118
+ 'verticalAlign',
119
+ 'wordWrap',
120
+ ];
121
+ export class ElementNode extends Object {
122
+ constructor(name) {
123
+ super();
124
+ this._type = name === 'text' ? NodeType.TextNode : NodeType.Element;
125
+ this.rendered = false;
126
+ this.lng = {};
127
+ this.children = [];
128
+ }
129
+ get effects() {
130
+ return this.lng.shader;
131
+ }
132
+ set effects(v) {
133
+ if (!SHADERS_ENABLED)
134
+ return;
135
+ let target = this.lng.shader || {};
136
+ if (this.lng.shader?.program) {
137
+ target = this.lng.shader.props;
138
+ }
139
+ if (v.rounded)
140
+ target.radius = v.rounded.radius;
141
+ if (v.borderRadius)
142
+ target.radius = v.borderRadius;
143
+ if (v.border)
144
+ parseAndAssignShaderProps('border', v.border, target);
145
+ if (v.shadow)
146
+ parseAndAssignShaderProps('shadow', v.shadow, target);
147
+ if (this.rendered) {
148
+ if (!this.lng.shader) {
149
+ this.lng.shader = convertToShader(this, target);
150
+ }
151
+ else if (DOM_RENDERING) {
152
+ this.lng.shader = this.lng.shader; // lng.shader is a setter, force style update
153
+ }
154
+ }
155
+ else {
156
+ this.lng.shader = target;
157
+ }
158
+ }
159
+ set id(id) {
160
+ this._id = id;
161
+ if (Config.rendererOptions?.inspector) {
162
+ this.data = { ...this.data, testId: id };
163
+ }
164
+ }
165
+ get id() {
166
+ return this._id;
167
+ }
168
+ get parent() {
169
+ return this._parent;
170
+ }
171
+ set parent(p) {
172
+ this._parent = p;
173
+ if (this.rendered && p?.rendered) {
174
+ this.lng.parent = p.lng ?? null;
175
+ }
176
+ }
177
+ get height() {
178
+ return this.h;
179
+ }
180
+ set height(h) {
181
+ this.h = h;
182
+ }
183
+ get width() {
184
+ return this.w;
185
+ }
186
+ set width(w) {
187
+ this.w = w;
188
+ }
189
+ set fontWeight(v) {
190
+ this._fontWeight = v;
191
+ this.fontFamily = `{${this.fontFamily}${v}`;
192
+ }
193
+ get fontWeight() {
194
+ return this._fontWeight;
195
+ }
196
+ insertChild(node, beforeNode) {
197
+ // always remove nodes if they have a parent - for back swap of node
198
+ // this will then put the node at the end of the array when re-added
199
+ if (node.parent) {
200
+ node.parent.removeChild(node);
201
+ // We're inserting a node thats been rendered into a node that hasn't been
202
+ if (!this.rendered) {
203
+ this._hasRenderedChildren = true;
204
+ }
205
+ }
206
+ node.parent = this;
207
+ if (beforeNode) {
208
+ // SolidJS can move nodes around in the children array.
209
+ // We need to insert following DOM insertBefore which moves elements.
210
+ spliceItem(this.children, node, 1);
211
+ if (spliceItem(this.children, beforeNode, 0, node) > -1) {
212
+ return;
213
+ }
214
+ }
215
+ this.children.push(node);
216
+ }
217
+ removeChild(node) {
218
+ if (spliceItem(this.children, node, 1) > -1) {
219
+ node.onRemove?.call(node, node);
220
+ if (this.requiresLayout()) {
221
+ addToLayoutQueue(this);
222
+ }
223
+ }
224
+ }
225
+ get selectedNode() {
226
+ const selectedIndex = this.selected || 0;
227
+ for (let i = selectedIndex; i < this.children.length; i++) {
228
+ const element = this.children[i];
229
+ if (isElementNode(element)) {
230
+ this.selected = i;
231
+ return element;
232
+ }
233
+ }
234
+ return undefined;
235
+ }
236
+ set shader(shaderProps) {
237
+ this.lng.shader = isArray(shaderProps)
238
+ ? renderer.createShader(...shaderProps)
239
+ : shaderProps;
240
+ }
241
+ _sendToLightningAnimatable(name, value) {
242
+ if (this.transition &&
243
+ this.rendered &&
244
+ Config.animationsEnabled &&
245
+ (this.transition === true ||
246
+ this.transition[name] ||
247
+ this.transition[getPropertyAlias(name)])) {
248
+ const animationSettings = this.transition === true || this.transition[name] === true
249
+ ? undefined
250
+ : this.transition[name];
251
+ if (Config.simpleAnimationsEnabled) {
252
+ simpleAnimation.add(this, name, value, animationSettings ||
253
+ this.animationSettings);
254
+ simpleAnimation.register(renderer.stage);
255
+ return;
256
+ }
257
+ else {
258
+ const animationController = this.animate({ [name]: value }, animationSettings);
259
+ if (this.onAnimation) {
260
+ const animationEvents = Object.keys(this.onAnimation);
261
+ for (const event of animationEvents) {
262
+ const handler = this.onAnimation[event];
263
+ animationController.on(event, (controller, props) => {
264
+ handler.call(this, controller, name, value, props);
265
+ });
266
+ }
267
+ }
268
+ return animationController.start();
269
+ }
270
+ }
271
+ this.lng[name] = value;
272
+ }
273
+ animate(props, animationSettings) {
274
+ isDev &&
275
+ assertTruthy(this.rendered, 'Node must be rendered before animating');
276
+ return this.lng.animate(props, animationSettings || this.animationSettings || {});
277
+ }
278
+ chain(props, animationSettings) {
279
+ if (this._animationRunning) {
280
+ this._animationQueue = [];
281
+ this._animationRunning = false;
282
+ }
283
+ if (animationSettings) {
284
+ this._animationQueueSettings = animationSettings;
285
+ }
286
+ else if (!this._animationQueueSettings) {
287
+ this._animationQueueSettings =
288
+ animationSettings || this.animationSettings;
289
+ }
290
+ animationSettings = animationSettings || this._animationQueueSettings;
291
+ this._animationQueue = this._animationQueue || [];
292
+ this._animationQueue.push({ props, animationSettings });
293
+ return this;
294
+ }
295
+ async start() {
296
+ let animation = this._animationQueue.shift();
297
+ while (animation) {
298
+ this._animationRunning = true;
299
+ await this.animate(animation.props, animation.animationSettings)
300
+ .start()
301
+ .waitUntilStopped();
302
+ animation = this._animationQueue.shift();
303
+ }
304
+ this._animationRunning = false;
305
+ this._animationQueueSettings = undefined;
306
+ }
307
+ emit(event, ...args) {
308
+ let current = this;
309
+ const capitalizedEvent = `on${event.charAt(0).toUpperCase()}${event.slice(1)}`;
310
+ while (current) {
311
+ const handler = current[capitalizedEvent];
312
+ if (isFunction(handler)) {
313
+ if (handler.call(current, this, ...args) === true) {
314
+ return true;
315
+ }
316
+ }
317
+ current = current.parent;
318
+ }
319
+ return false;
320
+ }
321
+ setFocus() {
322
+ if (this.rendered) {
323
+ // can be 0
324
+ if (this.forwardFocus !== undefined) {
325
+ if (isFunc(this.forwardFocus)) {
326
+ if (this.forwardFocus.call(this, this) !== false) {
327
+ return;
328
+ }
329
+ }
330
+ else {
331
+ const focusedIndex = typeof this.forwardFocus === 'number' ? this.forwardFocus : null;
332
+ const nodes = this.children;
333
+ if (focusedIndex !== null && focusedIndex < nodes.length) {
334
+ const child = nodes[focusedIndex];
335
+ isElementNode(child) && child.setFocus();
336
+ return;
337
+ }
338
+ }
339
+ }
340
+ // Delay setting focus so children can render (useful for Row + Column)
341
+ queueMicrotask(() => setActiveElement(this));
342
+ }
343
+ else {
344
+ this._autofocus = true;
345
+ }
346
+ }
347
+ _layoutOnLoad() {
348
+ this.lng.on('loaded', () => {
349
+ this.parent.updateLayout();
350
+ });
351
+ }
352
+ getText() {
353
+ let result = '';
354
+ for (let i = 0; i < this.children.length; i++) {
355
+ result += this.children[i].text;
356
+ }
357
+ return result;
358
+ }
359
+ destroy() {
360
+ if (this.onDestroy) {
361
+ const destroyPromise = this.onDestroy(this);
362
+ // If onDestroy returns a promise, wait for it to resolve before destroying
363
+ // Useful with animations waitUntilStopped method which returns promise
364
+ if (destroyPromise instanceof Promise) {
365
+ destroyPromise.then(() => this._destroy());
366
+ }
367
+ else {
368
+ this._destroy();
369
+ }
370
+ }
371
+ else {
372
+ this._destroy();
373
+ }
374
+ }
375
+ _destroy() {
376
+ if (isINode(this.lng)) {
377
+ this.lng.destroy();
378
+ }
379
+ }
380
+ set style(style) {
381
+ if (isDev && this._style) {
382
+ // Avoid processing style changes again
383
+ console.warn('Style already set: https://lightning-tv.github.io/solid/#/essentials/styling?id=style-patterns-to-avoid');
384
+ }
385
+ if (Config.lockStyles && this._style) {
386
+ return;
387
+ }
388
+ if (!style) {
389
+ return;
390
+ }
391
+ this._style = style;
392
+ // Keys set in JSX are more important
393
+ for (const key in this._style) {
394
+ // be careful of 0 values
395
+ if (this[key] === undefined) {
396
+ this[key] = this._style[key];
397
+ }
398
+ }
399
+ }
400
+ get style() {
401
+ return this._style;
402
+ }
403
+ get hasChildren() {
404
+ return this.children.length > 0;
405
+ }
406
+ set src(src) {
407
+ if (typeof src === 'string') {
408
+ this.lng.src = src;
409
+ if (!this.color && this.rendered) {
410
+ this.color = 0xffffffff;
411
+ }
412
+ }
413
+ else {
414
+ this.color = 0x00000000;
415
+ }
416
+ }
417
+ get src() {
418
+ return this.lng.src;
419
+ }
420
+ getChildById(id) {
421
+ return this.children.find((c) => c.id === id);
422
+ }
423
+ searchChildrenById(id) {
424
+ // traverse all the childrens children
425
+ for (let i = 0; i < this.children.length; i++) {
426
+ const child = this.children[i];
427
+ if (isElementNode(child)) {
428
+ if (child.id === id) {
429
+ return child;
430
+ }
431
+ const found = child.searchChildrenById(id);
432
+ if (found) {
433
+ return found;
434
+ }
435
+ }
436
+ }
437
+ }
438
+ set states(states) {
439
+ this._states = this._states
440
+ ? this._states.merge(states)
441
+ : new States(this._stateChanged.bind(this), states);
442
+ if (this.rendered) {
443
+ this._stateChanged();
444
+ }
445
+ }
446
+ get states() {
447
+ this._states = this._states || new States(this._stateChanged.bind(this));
448
+ return this._states;
449
+ }
450
+ get animationSettings() {
451
+ return this._animationSettings || Config.animationSettings;
452
+ }
453
+ set animationSettings(animationSettings) {
454
+ this._animationSettings = animationSettings;
455
+ }
456
+ set hidden(val) {
457
+ this.alpha = val ? 0 : 1;
458
+ }
459
+ get hidden() {
460
+ return this.alpha === 0;
461
+ }
462
+ /**
463
+ * Sets the autofocus state of the element.
464
+ * When set to a truthy value, the element will automatically gain focus.
465
+ * You can also set it to a signal to recalculate
466
+ *
467
+ * @param val - A value to determine if the element should autofocus.
468
+ * A truthy value enables autofocus, otherwise disables it.
469
+ */
470
+ set autofocus(val) {
471
+ this._autofocus = val;
472
+ // Delay setting focus so children can render (useful for Row + Column)
473
+ // which now uses forwardFocus
474
+ val && queueMicrotask(() => this.setFocus());
475
+ }
476
+ get autofocus() {
477
+ return this._autofocus;
478
+ }
479
+ requiresLayout() {
480
+ return this.display === 'flex' || this.onLayout;
481
+ }
482
+ set updateLayoutOn(v) {
483
+ this.updateLayout();
484
+ }
485
+ get updateLayoutOn() {
486
+ return null;
487
+ }
488
+ updateLayout() {
489
+ if (this.hasChildren) {
490
+ isDev && log('Layout: ', this);
491
+ if (this.display === 'flex' && this.flexGrow && this.width === 0) {
492
+ return;
493
+ }
494
+ const flexChanged = this.display === 'flex' && calculateFlex(this);
495
+ layoutQueue.delete(this);
496
+ const onLayoutChanged = isFunc(this.onLayout) && this.onLayout.call(this, this);
497
+ if ((flexChanged || onLayoutChanged) && this.parent) {
498
+ addToLayoutQueue(this.parent);
499
+ }
500
+ if (this._containsFlexGrow === true) {
501
+ // Need to reprocess children
502
+ this.children.forEach((c) => {
503
+ if (c.display === 'flex' && isElementNode(c)) {
504
+ // calculating directly to prevent infinite loops recalculating parents
505
+ calculateFlex(c);
506
+ isFunc(c.onLayout) && c.onLayout.call(c, c);
507
+ addToLayoutQueue(this);
508
+ }
509
+ });
510
+ }
511
+ }
512
+ }
513
+ _stateChanged() {
514
+ isDev && log('State Changed: ', this, this.states);
515
+ if (this.forwardStates) {
516
+ // apply states to children first
517
+ const states = this.states.slice();
518
+ this.children.forEach((c) => {
519
+ c.states = states;
520
+ });
521
+ }
522
+ const states = this.states;
523
+ if (this._undoStyles || keyExists(this, states)) {
524
+ let stylesToUndo;
525
+ if (this._undoStyles && this._undoStyles.length) {
526
+ stylesToUndo = {};
527
+ this._undoStyles.forEach((styleKey) => {
528
+ if (isDev) {
529
+ if (this.style[styleKey] === undefined) {
530
+ console.warn('fallback style key not found: ', styleKey);
531
+ }
532
+ }
533
+ stylesToUndo[styleKey] = this.style[styleKey];
534
+ });
535
+ }
536
+ const numStates = states.length;
537
+ if (numStates === 0) {
538
+ Object.assign(this, stylesToUndo);
539
+ this._undoStyles = [];
540
+ return;
541
+ }
542
+ let newStyles;
543
+ if (numStates === 1) {
544
+ newStyles = this[states[0]];
545
+ newStyles = stylesToUndo
546
+ ? { ...stylesToUndo, ...newStyles }
547
+ : newStyles;
548
+ }
549
+ else {
550
+ newStyles = states.reduce((acc, state) => {
551
+ const styles = this[state];
552
+ return styles ? { ...acc, ...styles } : acc;
553
+ }, stylesToUndo || {});
554
+ }
555
+ if (newStyles) {
556
+ this._undoStyles = Object.keys(newStyles);
557
+ // Apply transition first
558
+ if (newStyles.transition !== undefined) {
559
+ this.transition = newStyles.transition;
560
+ }
561
+ // Apply the styles
562
+ Object.assign(this, newStyles);
563
+ }
564
+ else {
565
+ this._undoStyles = [];
566
+ }
567
+ }
568
+ }
569
+ render(topNode) {
570
+ // Elements are inserted from the inside out, then rendered from the outside in.
571
+ // Render starts when an element is inserted with a parent that is already renderered.
572
+ const node = this;
573
+ const parent = this.parent;
574
+ if (!parent) {
575
+ console.warn('Parent not set - no node created for: ', this);
576
+ return;
577
+ }
578
+ if (!parent.rendered) {
579
+ console.warn('Parent not rendered yet: ', this);
580
+ return;
581
+ }
582
+ if (parent.requiresLayout()) {
583
+ layoutQueue.add(parent);
584
+ }
585
+ if (this.rendered) {
586
+ // This happens if Array of items is reordered to reuse elements.
587
+ // We return after layout is queued so the change can trigger layout updates.
588
+ this.onRender?.(this);
589
+ return;
590
+ }
591
+ if (this._states) {
592
+ this._stateChanged();
593
+ }
594
+ const props = node.lng;
595
+ const parentWidth = parent.w || 0;
596
+ const parentHeight = parent.h || 0;
597
+ props.x = props.x || 0;
598
+ props.y = props.y || 0;
599
+ props.parent = parent.lng;
600
+ if (this.right || this.right === 0) {
601
+ props.x = parentWidth - this.right;
602
+ props.mountX = 1;
603
+ }
604
+ if (this.bottom || this.bottom === 0) {
605
+ props.y = parentHeight - this.bottom;
606
+ props.mountY = 1;
607
+ }
608
+ if (this.center) {
609
+ this.centerX = this.centerY = true;
610
+ }
611
+ if (this.centerX) {
612
+ props.x += parentWidth / 2;
613
+ props.mountX = 0.5;
614
+ }
615
+ if (this.centerY) {
616
+ props.y += parentHeight / 2;
617
+ props.mountY = 0.5;
618
+ }
619
+ if (isElementText(node)) {
620
+ const textProps = props;
621
+ if (Config.fontSettings) {
622
+ for (const key in Config.fontSettings) {
623
+ if (textProps[key] === undefined) {
624
+ textProps[key] = Config.fontSettings[key];
625
+ }
626
+ }
627
+ }
628
+ textProps.text = textProps.text || node.getText();
629
+ if (textProps.textAlign && !textProps.contain) {
630
+ console.warn('Text align requires contain: ', node.getText());
631
+ }
632
+ // contain is either width or both
633
+ if (textProps.contain) {
634
+ if (!textProps.w) {
635
+ textProps.w =
636
+ parentWidth - textProps.x - (textProps.marginRight || 0);
637
+ }
638
+ if (textProps.contain === 'both' &&
639
+ !textProps.h &&
640
+ !textProps.maxLines) {
641
+ textProps.h =
642
+ parentHeight - textProps.y - (textProps.marginBottom || 0);
643
+ }
644
+ else if (textProps.maxLines === 1) {
645
+ textProps.h = (textProps.h ||
646
+ textProps.lineHeight ||
647
+ textProps.fontSize);
648
+ }
649
+ if (textProps.contain === 'both') {
650
+ textProps.maxWidth = textProps.w;
651
+ textProps.maxHeight = textProps.h;
652
+ }
653
+ else if (textProps.contain === 'width') {
654
+ textProps.maxWidth = textProps.w;
655
+ textProps.maxLines = textProps.maxLines ?? 1;
656
+ }
657
+ }
658
+ // Can you put effects on Text nodes? Need to confirm...
659
+ if (SHADERS_ENABLED && props.shader && !props.shader.program) {
660
+ props.shader = convertToShader(node, props.shader);
661
+ }
662
+ isDev && log('Rendering: ', this, props);
663
+ node.lng = renderer.createTextNode(props);
664
+ if (parent.requiresLayout()) {
665
+ if (!props.w || !props.h) {
666
+ node._layoutOnLoad();
667
+ }
668
+ }
669
+ }
670
+ else {
671
+ // If its not an image or texture apply some defaults
672
+ if (!props.texture) {
673
+ // Set width and height to parent less offset
674
+ if (isNaN(props.w)) {
675
+ props.w = node.flexGrow ? 0 : parentWidth - props.x;
676
+ node._calcWidth = true;
677
+ }
678
+ if (isNaN(props.h)) {
679
+ props.h = parentHeight - props.y;
680
+ node._calcHeight = true;
681
+ }
682
+ if (props.rtt && !props.color) {
683
+ props.color = 0xffffffff;
684
+ }
685
+ if (!props.color && !props.src) {
686
+ // Default color to transparent - If you later set a src, you'll need
687
+ // to set color '#ffffffff'
688
+ props.color = 0x00000000;
689
+ }
690
+ }
691
+ if (SHADERS_ENABLED && props.shader && !props.shader.program) {
692
+ props.shader = convertToShader(node, props.shader);
693
+ }
694
+ isDev && log('Rendering: ', this, props);
695
+ node.lng = renderer.createNode(props);
696
+ if (node._hasRenderedChildren) {
697
+ node._hasRenderedChildren = false;
698
+ for (const child of node.children) {
699
+ if (isElementNode(child) && isINode(child.lng)) {
700
+ child.lng.parent = node.lng;
701
+ }
702
+ }
703
+ }
704
+ }
705
+ node.rendered = true;
706
+ if (isDev) {
707
+ // Store props so we can recreate raw renderer code
708
+ node._rendererProps = props;
709
+ }
710
+ if (node.autosize && parent.requiresLayout()) {
711
+ node._layoutOnLoad();
712
+ }
713
+ this.onCreate?.(this);
714
+ this.onRender?.(this);
715
+ if (node.onEvent) {
716
+ for (const [name, handler] of Object.entries(node.onEvent)) {
717
+ node.lng.on(name, (_inode, data) => handler.call(node, node, data));
718
+ }
719
+ }
720
+ // L3 Inspector adds div to the lng object
721
+ if (node.lng?.div) {
722
+ node.lng.div.element = node;
723
+ }
724
+ if (node._type === NodeType.Element) {
725
+ // only element nodes will have children that need rendering
726
+ const numChildren = node.children.length;
727
+ for (let i = 0; i < numChildren; i++) {
728
+ const c = node.children[i];
729
+ isDev && assertTruthy(c, 'Child is undefined');
730
+ // Text elements sneak in from Solid creating tracked nodes
731
+ if (isElementNode(c)) {
732
+ c.render();
733
+ }
734
+ }
735
+ }
736
+ if (topNode && !layoutRunQueued) {
737
+ //Do one pass of layout, then another with Text loads
738
+ layoutRunQueued = true;
739
+ // We use queue because <For> loop will add children one at a time, causing lots of layout
740
+ queueMicrotask(runLayout);
741
+ }
742
+ node._autofocus && node.setFocus();
743
+ }
744
+ }
745
+ for (const key of LightningRendererNumberProps) {
746
+ Object.defineProperty(ElementNode.prototype, key, {
747
+ get() {
748
+ return this.lng[key];
749
+ },
750
+ set(v) {
751
+ this._sendToLightningAnimatable(key, v);
752
+ },
753
+ });
754
+ }
755
+ for (const key of LightningRendererNonAnimatingProps) {
756
+ Object.defineProperty(ElementNode.prototype, key, {
757
+ get() {
758
+ return this.lng[key];
759
+ },
760
+ set(v) {
761
+ this.lng[key] = v;
762
+ },
763
+ });
764
+ }
765
+ function createRawShaderAccessor(key) {
766
+ return {
767
+ set(value) {
768
+ this.shader = [key, value];
769
+ },
770
+ get() {
771
+ return this.shader;
772
+ },
773
+ };
774
+ }
775
+ function shaderAccessor(key) {
776
+ return {
777
+ set(value) {
778
+ let target = this.lng.shader || {};
779
+ let animationSettings;
780
+ if (this.lng.shader?.program) {
781
+ target = this.lng.shader.props;
782
+ const transitionKey = key === 'rounded' ? 'borderRadius' : key;
783
+ if (this.transition &&
784
+ (this.transition === true || this.transition[transitionKey])) {
785
+ target = {};
786
+ animationSettings =
787
+ this.transition === true || this.transition[transitionKey] === true
788
+ ? undefined
789
+ : this.transition[transitionKey];
790
+ }
791
+ }
792
+ if (key === 'rounded' || typeof value === 'number') {
793
+ target.radius = value;
794
+ }
795
+ else {
796
+ parseAndAssignShaderProps(key, value, target);
797
+ }
798
+ if (this.rendered) {
799
+ if (!this.lng.shader) {
800
+ this.lng.shader = convertToShader(this, target);
801
+ }
802
+ }
803
+ else {
804
+ this.lng.shader = target;
805
+ }
806
+ if (animationSettings) {
807
+ this.animate({ shaderProps: target }, animationSettings).start();
808
+ }
809
+ },
810
+ get() {
811
+ return this.effects?.[key];
812
+ },
813
+ };
814
+ }
815
+ if (isDev) {
816
+ ElementNode.prototype.lngTree = function () {
817
+ return logRenderTree(this);
818
+ };
819
+ }
820
+ Object.defineProperties(ElementNode.prototype, {
821
+ border: shaderAccessor('border'),
822
+ shadow: shaderAccessor('shadow'),
823
+ rounded: shaderAccessor('rounded'),
824
+ // Alias for rounded
825
+ borderRadius: shaderAccessor('rounded'),
826
+ linearGradient: createRawShaderAccessor('linearGradient'),
827
+ radialGradient: createRawShaderAccessor('radialGradient'),
828
+ });
829
+ //# sourceMappingURL=elementNode.js.map