@lightningtv/solid 3.0.0-21 → 3.0.0-22

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 (29) hide show
  1. package/dist/src/core/animation.js +1 -2
  2. package/dist/src/core/animation.js.map +1 -1
  3. package/dist/src/core/dom-renderer/domRenderer.d.ts +137 -0
  4. package/dist/src/core/dom-renderer/domRenderer.js +1545 -0
  5. package/dist/src/core/dom-renderer/domRenderer.js.map +1 -0
  6. package/dist/src/core/dom-renderer/domRendererTypes.d.ts +117 -0
  7. package/dist/src/core/dom-renderer/domRendererTypes.js +2 -0
  8. package/dist/src/core/dom-renderer/domRendererTypes.js.map +1 -0
  9. package/dist/src/core/dom-renderer/domRendererUtils.d.ts +16 -0
  10. package/dist/src/core/dom-renderer/domRendererUtils.js +132 -0
  11. package/dist/src/core/dom-renderer/domRendererUtils.js.map +1 -0
  12. package/dist/src/core/elementNode.d.ts +260 -6
  13. package/dist/src/core/elementNode.js +17 -16
  14. package/dist/src/core/elementNode.js.map +1 -1
  15. package/dist/src/core/focusManager.js +10 -3
  16. package/dist/src/core/focusManager.js.map +1 -1
  17. package/dist/src/primitives/utils/createSpriteMap.js +2 -2
  18. package/dist/src/primitives/utils/createSpriteMap.js.map +1 -1
  19. package/dist/src/primitives/utils/handleNavigation.js +3 -3
  20. package/dist/src/primitives/utils/handleNavigation.js.map +1 -1
  21. package/dist/src/render.d.ts +1 -1
  22. package/dist/tsconfig.tsbuildinfo +1 -1
  23. package/package.json +4 -1
  24. package/src/core/animation.ts +4 -2
  25. package/src/core/elementNode.ts +279 -28
  26. package/src/core/focusManager.ts +11 -1
  27. package/src/primitives/utils/createSpriteMap.ts +2 -2
  28. package/src/primitives/utils/handleNavigation.ts +3 -3
  29. package/src/core/timings.ts +0 -261
@@ -27,7 +27,6 @@ import calculateFlex from './flex.js';
27
27
  import {
28
28
  log,
29
29
  isArray,
30
- isNumber,
31
30
  isFunc,
32
31
  keyExists,
33
32
  isINode,
@@ -214,50 +213,218 @@ export interface ElementNode extends RendererNode, FocusNode {
214
213
  _type: 'element' | 'textNode';
215
214
  _undoStyles?: string[];
216
215
  autosize?: boolean;
216
+ /**
217
+ * The distance from the bottom edge of the parent element.
218
+ * When `bottom` is set, `mountY` is automatically set to 1.
219
+ *
220
+ * @see https://lightning-tv.github.io/solid/#/flow/layout
221
+ */
217
222
  bottom?: number;
223
+ /**
224
+ * An array of child `ElementNode` or `ElementText` nodes.
225
+ */
218
226
  children: Array<ElementNode | ElementText>;
227
+ /**
228
+ * Enable debug logging for this specific node.
229
+ */
219
230
  debug?: boolean;
231
+ /**
232
+ * Specifies how much a flex item should grow relative to the rest of the flex items.
233
+ *
234
+ * @see https://lightning-tv.github.io/solid/#/flow/layout?id=flex-grow
235
+ */
220
236
  flexGrow?: number;
237
+ /**
238
+ * Specifies whether flex items are forced onto one line or can wrap onto multiple lines.
239
+ *
240
+ * @see https://lightning-tv.github.io/solid/#/flow/layout?id=flex
241
+ */
221
242
  flexWrap?: 'nowrap' | 'wrap';
243
+ /**
244
+ * Determines if an element is a flex item. If set to `false`, the element will be ignored by the flexbox layout.
245
+ * @default false
246
+ */
222
247
  flexItem?: boolean;
248
+ /**
249
+ * Specifies the order of a flex item relative to the rest of the flex items.
250
+ *
251
+ * @see https://lightning-tv.github.io/solid/#/flow/layout?id=flex
252
+ */
223
253
  flexOrder?: number;
254
+ /**
255
+ * Forwards focus to a child element. It can be a numeric index of the child or a handler function.
256
+ *
257
+ * @see https://lightning-tv.github.io/solid/#/essentials/focus?id=forwardfocus
258
+ */
224
259
  forwardFocus?: number | ForwardFocusHandler;
260
+ /**
261
+ * If `true`, the states of this node will be propagated to its children.
262
+ *
263
+ * @see https://lightning-tv.github.io/solid/#/essentials/states?id=forwardstates
264
+ */
225
265
  forwardStates?: boolean;
226
- /** For children of {@link NavigableElement}, set to `true` to prevent being selected */
227
- skipFocus?: boolean;
228
- /** function to be called on mouse click */
229
- onMouseClick?: (
230
- this: ElementNode,
231
- event: MouseEvent,
232
- active: ElementNode,
233
- ) => void;
266
+ /**
267
+ * The underlying Lightning Renderer node object. This is where the properties are ultimately set for rendering.
268
+ */
234
269
  lng:
235
270
  | Partial<ElementNode>
236
271
  | IRendererNode
237
272
  | (IRendererTextNode & { shader?: any });
273
+ /**
274
+ * A reference to the `ElementNode` instance. Can be an object or a callback function.
275
+ */
238
276
  ref?: ElementNode | ((node: ElementNode) => void) | undefined;
277
+ /**
278
+ * A boolean indicating whether the node has been rendered.
279
+ */
239
280
  rendered: boolean;
281
+ /**
282
+ * The main renderer instance.
283
+ */
240
284
  renderer?: RendererMain;
285
+ /**
286
+ * The distance from the right edge of the parent element.
287
+ * When `right` is set, `mountX` is automatically set to 1.
288
+ *
289
+ * @see https://lightning-tv.github.io/solid/#/flow/layout?id=layout-and-positioning-elements
290
+ */
241
291
  right?: number;
292
+ /**
293
+ * The index of the currently selected child element, used for focus management for Column and Row components.
294
+ */
242
295
  selected?: number;
296
+ /**
297
+ * The width of the element before flexbox layout is applied. Used internally for layout calculations.
298
+ */
243
299
  preFlexwidth?: number;
300
+ /**
301
+ * The height of the element before flexbox layout is applied. Used internally for layout calculations.
302
+ */
244
303
  preFlexheight?: number;
304
+ /**
305
+ * The text content of a text node.
306
+ */
245
307
  text?: string;
308
+ /**
309
+ * Aligns flex items along the cross axis of the current line of the flex container.
310
+ *
311
+ * @see https://lightning-tv.github.io/solid/#/flow/layout?id=flex-properties
312
+ */
246
313
  alignItems?: 'flexStart' | 'flexEnd' | 'center';
314
+ /**
315
+ * Aligns a flex item along the cross axis, overriding the `alignItems` value of the flex container.
316
+ *
317
+ * @see https://lightning-tv.github.io/solid/#/flow/layout?id=flex-properties
318
+ */
247
319
  alignSelf?: 'flexStart' | 'flexEnd' | 'center';
320
+ /**
321
+ * The border style for all sides of the element. Takes an object with width and color properties.
322
+ *
323
+ * @see https://lightning-tv.github.io/solid/#/essentials/effects?id=border-and-borderradius
324
+ */
248
325
  border?: BorderStyle;
326
+ /**
327
+ * The border style for the bottom side of the element.
328
+ *
329
+ * @see https://lightning-tv.github.io/solid/#/essentials/effects?id=border-and-borderradius
330
+ */
331
+ borderBottom?: BorderStyle;
332
+ /**
333
+ * The border style for the left side of the element.
334
+ *
335
+ * @see https://lightning-tv.github.io/solid/#/essentials/effects?id=border-and-borderradius
336
+ */
337
+ borderLeft?: BorderStyle;
338
+ /**
339
+ * The radius of the element's corners.
340
+ *
341
+ * @see https://lightning-tv.github.io/solid/#/essentials/effects?id=border-and-borderradius
342
+ */
249
343
  borderRadius?: BorderRadius;
344
+ /**
345
+ * The border style for the right side of the element.
346
+ *
347
+ * @see https://lightning-tv.github.io/solid/#/essentials/effects?id=border-and-borderradius
348
+ */
349
+ borderRight?: BorderStyle;
350
+ /**
351
+ * The border style for the top side of the element.
352
+ *
353
+ * @see https://lightning-tv.github.io/solid/#/essentials/effects?id=border-and-borderradius
354
+ */
355
+ borderTop?: BorderStyle;
356
+ /**
357
+ * A shorthand to set both `centerX` and `centerY` to true.
358
+ *
359
+ * @see https://lightning-tv.github.io/solid/#/flow/layout?id=layout-and-positioning-elements
360
+ */
250
361
  center?: boolean;
362
+ /**
363
+ * If `true`, centers the element horizontally within its parent.
364
+ *
365
+ * @see https://lightning-tv.github.io/solid/#/flow/layout?id=layout-and-positioning-elements
366
+ */
251
367
  centerX?: boolean;
368
+ /**
369
+ * If `true`, centers the element vertically within its parent.
370
+ *
371
+ * @see https://lightning-tv.github.io/solid/#/flow/layout?id=layout-and-positioning-elements
372
+ */
252
373
  centerY?: boolean;
374
+ /**
375
+ * Specifies the direction of the flex items.
376
+ *
377
+ * @see https://lightning-tv.github.io/solid/#/flow/layout?id=flex
378
+ */
253
379
  direction?: 'ltr' | 'rtl';
380
+ /**
381
+ * Specifies the display behavior of an element. 'flex' enables flexbox layout.
382
+ *
383
+ * @default 'block'
384
+ * @see https://lightning-tv.github.io/solid/#/flow/layout?id=flex
385
+ */
254
386
  display?: 'flex' | 'block';
387
+ /**
388
+ * Defines how the flex container's size is determined. 'contain' allows it to grow with its content, 'fixed' keeps it at its specified size.
389
+ *
390
+ * @see https://lightning-tv.github.io/solid/#/flow/layout?id=flex
391
+ */
255
392
  flexBoundary?: 'contain' | 'fixed';
393
+ /**
394
+ * Defines how the flex container's cross-axis size is determined. 'fixed' keeps it at its specified size. Default is 'contain'.
395
+ *
396
+ * @see https://lightning-tv.github.io/solid/#/flow/layout?id=flex
397
+ */
256
398
  flexCrossBoundary?: 'fixed'; // default is contain
399
+ /**
400
+ * Specifies the direction of the main axis for flex items.
401
+ *
402
+ * @see https://lightning-tv.github.io/solid/#/flow/layout?id=flex
403
+ */
257
404
  flexDirection?: 'row' | 'column';
405
+ /**
406
+ * The gap between flex items.
407
+ *
408
+ * @see @see https://lightning-tv.github.io/solid/#/flow/layout?id=flex
409
+ */
258
410
  gap?: number;
411
+ /**
412
+ * The gap between flex rows.
413
+ *
414
+ * @see @see https://lightning-tv.github.io/solid/#/flow/layout?id=flex
415
+ */
259
416
  rowGap?: number;
417
+ /**
418
+ * The gap between flex columns.
419
+ *
420
+ * @see @see https://lightning-tv.github.io/solid/#/flow/layout?id=flex
421
+ */
260
422
  columnGap?: number;
423
+ /**
424
+ * Defines the alignment of flex items along the main axis.
425
+ *
426
+ * @see @see https://lightning-tv.github.io/solid/#/flow/layout?id=flex
427
+ */
261
428
  justifyContent?:
262
429
  | 'flexStart'
263
430
  | 'flexEnd'
@@ -265,19 +432,89 @@ export interface ElementNode extends RendererNode, FocusNode {
265
432
  | 'spaceBetween'
266
433
  | 'spaceAround'
267
434
  | 'spaceEvenly';
435
+ /**
436
+ * Applies a linear gradient effect to the element.
437
+ *
438
+ * @see https://lightning-tv.github.io/solid/#/essentials/effects
439
+ */
268
440
  linearGradient?: LinearGradientProps;
441
+ /**
442
+ * Applies a radial gradient effect to the element.
443
+ *
444
+ * @see https://lightning-tv.github.io/solid/#/essentials/effects
445
+ */
269
446
  radialGradient?: RadialGradientProps;
447
+ /**
448
+ * The margin on the bottom side of the element for a flexItem.
449
+ *
450
+ * @see https://lightning-tv.github.io/solid/#/flow/layout
451
+ */
270
452
  marginBottom?: number;
453
+ /**
454
+ * The margin on the left side of the element for a flexItem.
455
+ *
456
+ * @see https://lightning-tv.github.io/solid/#/flow/layout
457
+ */
271
458
  marginLeft?: number;
459
+ /**
460
+ * The margin on the right side of the element for a flexItem.
461
+ *
462
+ * @see https://lightning-tv.github.io/solid/#/flow/layout
463
+ */
272
464
  marginRight?: number;
465
+ /**
466
+ * The margin on the top side of the element for a flexItem.
467
+ *
468
+ * @see https://lightning-tv.github.io/solid/#/flow/layout
469
+ */
273
470
  marginTop?: number;
471
+ /**
472
+ * The padding on all sides of the flex element.
473
+ *
474
+ * @see https://lightning-tv.github.io/solid/#/flow/layout
475
+ */
274
476
  padding?: number;
477
+ /**
478
+ * The x-coordinate of the element's position.
479
+ *
480
+ * @see https://lightning-tv.github.io/solid/#/flow/layout
481
+ */
275
482
  x: number;
483
+ /**
484
+ * The y-coordinate of the element's position.
485
+ *
486
+ * @see https://lightning-tv.github.io/solid/#/flow/layout
487
+ */
276
488
  y: number;
489
+ /**
490
+ * Throttles key press events by the specified number of milliseconds.
491
+ *
492
+ * @see https://lightning-tv.github.io/solid/#/primitives/useFocusManager?id=input-throttling-available-core-212
493
+ */
277
494
  throttleInput?: number;
495
+ /**
496
+ * The width of the element.
497
+ *
498
+ * @see https://lightning-tv.github.io/solid/#/flow/layout
499
+ */
278
500
  w: number;
501
+ /**
502
+ * The height of the element.
503
+ *
504
+ * @see https://lightning-tv.github.io/solid/#/flow/layout
505
+ */
279
506
  h: number;
507
+ /**
508
+ * The z-index of the element, which affects its stacking order.
509
+ *
510
+ * @see https://lightning-tv.github.io/solid/#/flow/layout
511
+ */
280
512
  zIndex?: number;
513
+ /**
514
+ * Defines transitions for animatable properties.
515
+ *
516
+ * @see https://lightning-tv.github.io/solid/#/essentials/transitions?id=transitions-animations
517
+ */
281
518
  transition?:
282
519
  | Record<string, AnimationSettings | undefined | true | false>
283
520
  | true
@@ -301,21 +538,28 @@ export interface ElementNode extends RendererNode, FocusNode {
301
538
  * @see https://lightning-tv.github.io/solid/#/essentials/transitions?id=animation-callbacks
302
539
  */
303
540
  onAnimation?: Partial<Record<AnimationEvents, AnimationEventHandler>>;
304
- /**
305
- * Optional handler for when the element is created and rendered.
541
+ /** Optional handler for when the element is created and rendered.
542
+ *
543
+ * @see https://lightning-tv.github.io/solid/#/flow/ondestroy
306
544
  */
307
545
  onCreate?: (this: ElementNode, el: ElementNode) => void;
308
546
  /**
309
547
  * Optional handler for when the element is destroyed.
310
548
  * It can return a promise to wait for the cleanup to finish before the element is destroyed.
549
+ *
550
+ * @see https://lightning-tv.github.io/solid/#/flow/ondestroy
311
551
  */
312
552
  onDestroy?: (this: ElementNode, el: ElementNode) => Promise<any> | void;
313
553
  /**
314
554
  * Optional handlers for when the element is rendered—after creation and when switching parents.
555
+ *
556
+ * @see https://lightning-tv.github.io/solid/#/primitives/KeepAlive
315
557
  */
316
558
  onRender?: (this: ElementNode, el: ElementNode) => void;
317
559
  /**
318
560
  * Optional handlers for when the element is removed from a parent element.
561
+ *
562
+ * @see https://lightning-tv.github.io/solid/#/primitives/KeepAlive
319
563
  */
320
564
  onRemove?: (this: ElementNode, el: ElementNode) => void;
321
565
  /**
@@ -339,6 +583,12 @@ export interface ElementNode extends RendererNode, FocusNode {
339
583
  * @see https://lightning-tv.github.io/solid/#/essentials/events
340
584
  */
341
585
  onEvent?: OnEvent;
586
+
587
+ /**
588
+ * Callback run after flex layout is calculated on flex elements
589
+ *
590
+ * @see https://lightning-tv.github.io/solid/#/flow/layout
591
+ */
342
592
  onLayout?: (this: ElementNode, target: ElementNode) => void;
343
593
  }
344
594
 
@@ -965,31 +1215,32 @@ export class ElementNode extends Object {
965
1215
 
966
1216
  // contain is either width or both
967
1217
  if (textProps.contain) {
968
- if (!textProps.w) {
969
- textProps.w =
1218
+ if (textProps.contain === 'both') {
1219
+ textProps.maxWidth = textProps.maxWidth ?? textProps.w;
1220
+ textProps.maxHeight = textProps.maxHeight ?? textProps.h;
1221
+ } else if (textProps.contain === 'width') {
1222
+ textProps.maxWidth = textProps.maxWidth ?? textProps.w;
1223
+ }
1224
+
1225
+ if (!textProps.h && !textProps.maxHeight) {
1226
+ textProps.maxLines = textProps.maxLines ?? 99;
1227
+ }
1228
+
1229
+ if (!textProps.maxWidth) {
1230
+ textProps.maxWidth =
970
1231
  parentWidth - textProps.x! - (textProps.marginRight || 0);
971
1232
  }
972
1233
 
973
- if (
974
- textProps.contain === 'both' &&
975
- !textProps.h &&
976
- !textProps.maxLines
977
- ) {
978
- textProps.h =
1234
+ if (textProps.contain === 'both' && !textProps.maxHeight) {
1235
+ textProps.maxHeight =
979
1236
  parentHeight - textProps.y! - (textProps.marginBottom || 0);
980
1237
  } else if (textProps.maxLines === 1) {
981
- textProps.h = (textProps.h ||
1238
+ textProps.maxHeight = (textProps.maxHeight ||
982
1239
  textProps.lineHeight ||
983
1240
  textProps.fontSize) as number;
984
1241
  }
985
1242
 
986
- if (textProps.contain === 'both') {
987
- textProps.maxWidth = textProps.w;
988
- textProps.maxHeight = textProps.h;
989
- } else if (textProps.contain === 'width') {
990
- textProps.maxWidth = textProps.w;
991
- textProps.maxLines = textProps.maxLines ?? 1;
992
- }
1243
+ textProps.w = textProps.h = undefined;
993
1244
  }
994
1245
 
995
1246
  // Can you put effects on Text nodes? Need to confirm...
@@ -1002,7 +1253,7 @@ export class ElementNode extends Object {
1002
1253
  props as unknown as IRendererTextNodeProps,
1003
1254
  );
1004
1255
  if (parent.requiresLayout()) {
1005
- if (!props.w || !props.h) {
1256
+ if (!textProps.maxWidth || !textProps.maxHeight) {
1006
1257
  node._layoutOnLoad();
1007
1258
  }
1008
1259
  }
@@ -134,6 +134,7 @@ const updateFocusPath = (
134
134
  };
135
135
 
136
136
  let lastGlobalKeyPressTime = 0;
137
+ let lastInputKey: string | number | undefined;
137
138
 
138
139
  const propagateKeyPress = (
139
140
  e: KeyboardEvent,
@@ -142,8 +143,15 @@ const propagateKeyPress = (
142
143
  isUp: boolean = false,
143
144
  ): boolean => {
144
145
  const currentTime = performance.now();
146
+ const key = e.key || e.keyCode;
147
+ const sameKey = lastInputKey === key;
148
+ lastInputKey = key;
149
+
145
150
  if (!isUp && Config.throttleInput) {
146
- if (currentTime - lastGlobalKeyPressTime < Config.throttleInput) {
151
+ if (
152
+ sameKey &&
153
+ currentTime - lastGlobalKeyPressTime < Config.throttleInput
154
+ ) {
147
155
  if (isDev && Config.keyDebug) {
148
156
  console.log(
149
157
  `Keypress throttled by global Config.throttleInput: ${Config.throttleInput}ms`,
@@ -166,6 +174,7 @@ const propagateKeyPress = (
166
174
  // Check throttle for capture phase
167
175
  if (elm.throttleInput) {
168
176
  if (
177
+ sameKey &&
169
178
  elm._lastAnyKeyPressTime !== undefined &&
170
179
  currentTime - elm._lastAnyKeyPressTime < elm.throttleInput
171
180
  ) {
@@ -205,6 +214,7 @@ const propagateKeyPress = (
205
214
  // Check throttle for bubbling phase
206
215
  if (elm.throttleInput) {
207
216
  if (
217
+ sameKey &&
208
218
  elm._lastAnyKeyPressTime !== undefined &&
209
219
  currentTime - elm._lastAnyKeyPressTime < elm.throttleInput
210
220
  ) {
@@ -24,8 +24,8 @@ export function createSpriteMap(
24
24
  texture: spriteMapTexture,
25
25
  x,
26
26
  y,
27
- width,
28
- height,
27
+ w: width,
28
+ h: height,
29
29
  }) as InstanceType<TextureMap['SubTexture']>;
30
30
  return acc;
31
31
  }, {});
@@ -3,7 +3,7 @@ import * as lng from '../../index.js';
3
3
  import * as lngp from '../index.js';
4
4
 
5
5
  function idxInArray(idx: number, arr: readonly any[]): boolean {
6
- return idx === 0 || (idx >= 0 && idx < arr.length);
6
+ return idx >= 0 && idx < arr.length;
7
7
  }
8
8
 
9
9
  function findFirstFocusableChildIdx(
@@ -70,10 +70,10 @@ export function onGridFocus(
70
70
  export const navigableForwardFocus: lng.ForwardFocusHandler = function () {
71
71
  const navigable = this as lngp.NavigableElement;
72
72
 
73
- let selected = navigable.selected;
73
+ let selected = Math.max(navigable.selected, 0);
74
74
 
75
75
  if (selected !== 0) {
76
- selected = lng.clamp(selected, 0, this.children.length - 1);
76
+ selected = lng.clamp(selected, 0, Math.max(0, this.children.length - 1));
77
77
  while (!idxInArray(selected, this.children)) {
78
78
  selected--;
79
79
  }