@lightningtv/solid 3.0.1 → 3.0.3
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/dist/src/core/elementNode.d.ts +3 -0
- package/dist/src/core/elementNode.js +25 -37
- package/dist/src/core/elementNode.js.map +1 -1
- package/dist/src/core/intrinsicTypes.d.ts +1 -1
- package/dist/src/index.d.ts +2 -2
- package/dist/src/index.js +1 -2
- package/dist/src/index.js.map +1 -1
- package/dist/src/primitives/FadeInOut.d.ts +9 -1
- package/dist/src/primitives/FadeInOut.jsx +14 -2
- package/dist/src/primitives/FadeInOut.jsx.map +1 -1
- package/dist/src/primitives/Lazy.jsx +1 -1
- package/dist/src/primitives/Lazy.jsx.map +1 -1
- package/dist/src/primitives/Virtual.jsx +11 -3
- package/dist/src/primitives/Virtual.jsx.map +1 -1
- package/dist/src/primitives/borderBox.d.ts +8 -0
- package/dist/src/primitives/borderBox.jsx +46 -0
- package/dist/src/primitives/borderBox.jsx.map +1 -0
- package/dist/src/primitives/index.d.ts +2 -1
- package/dist/src/primitives/index.js +2 -1
- package/dist/src/primitives/index.js.map +1 -1
- package/dist/src/primitives/utils/handleNavigation.js +4 -2
- package/dist/src/primitives/utils/handleNavigation.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/src/core/elementNode.ts +50 -115
- package/src/core/intrinsicTypes.ts +5 -25
- package/src/index.ts +2 -11
- package/src/primitives/FadeInOut.tsx +17 -4
- package/src/primitives/Lazy.tsx +1 -1
- package/src/primitives/Virtual.tsx +14 -4
- package/src/primitives/borderBox.tsx +60 -0
- package/src/primitives/index.ts +2 -5
- package/src/primitives/utils/handleNavigation.ts +14 -39
package/src/core/elementNode.ts
CHANGED
|
@@ -49,11 +49,7 @@ import type {
|
|
|
49
49
|
} from '@lightningjs/renderer';
|
|
50
50
|
import { assertTruthy } from '@lightningjs/renderer/utils';
|
|
51
51
|
import { NodeType } from './nodeTypes.js';
|
|
52
|
-
import {
|
|
53
|
-
ForwardFocusHandler,
|
|
54
|
-
setActiveElement,
|
|
55
|
-
FocusNode,
|
|
56
|
-
} from './focusManager.js';
|
|
52
|
+
import { ForwardFocusHandler, setActiveElement, FocusNode } from './focusManager.js';
|
|
57
53
|
import simpleAnimation, { SimpleAnimationSettings } from './animation.js';
|
|
58
54
|
|
|
59
55
|
let layoutRunQueued = false;
|
|
@@ -77,11 +73,7 @@ function runLayout() {
|
|
|
77
73
|
}
|
|
78
74
|
}
|
|
79
75
|
|
|
80
|
-
const parseAndAssignShaderProps = (
|
|
81
|
-
prefix: string,
|
|
82
|
-
obj: Record<string, any>,
|
|
83
|
-
props: Record<string, any> = {},
|
|
84
|
-
) => {
|
|
76
|
+
const parseAndAssignShaderProps = (prefix: string, obj: Record<string, any>, props: Record<string, any> = {}) => {
|
|
85
77
|
if (!obj) return;
|
|
86
78
|
props[prefix] = obj;
|
|
87
79
|
Object.entries(obj).forEach(([key, value]) => {
|
|
@@ -144,7 +136,6 @@ const LightningRendererNonAnimatingProps = [
|
|
|
144
136
|
'contain',
|
|
145
137
|
'data',
|
|
146
138
|
'destroyed',
|
|
147
|
-
'fontFamily',
|
|
148
139
|
'fontStretch',
|
|
149
140
|
'fontStyle',
|
|
150
141
|
'imageType',
|
|
@@ -181,12 +172,7 @@ declare global {
|
|
|
181
172
|
}
|
|
182
173
|
|
|
183
174
|
export type RendererNode = AddColorString<
|
|
184
|
-
Partial<
|
|
185
|
-
NewOmit<
|
|
186
|
-
INode,
|
|
187
|
-
'parent' | 'shader' | 'src' | 'children' | 'id' | 'removeChild'
|
|
188
|
-
>
|
|
189
|
-
>
|
|
175
|
+
Partial<NewOmit<INode, 'parent' | 'shader' | 'src' | 'children' | 'id' | 'removeChild'>>
|
|
190
176
|
>;
|
|
191
177
|
export interface ElementNode extends RendererNode, FocusNode {
|
|
192
178
|
[key: string]: unknown;
|
|
@@ -208,6 +194,7 @@ export interface ElementNode extends RendererNode, FocusNode {
|
|
|
208
194
|
_containsFlexGrow?: boolean | null;
|
|
209
195
|
_hasRenderedChildren?: boolean;
|
|
210
196
|
_effects?: StyleEffects;
|
|
197
|
+
_fontFamily?: string;
|
|
211
198
|
_id: string | undefined;
|
|
212
199
|
_parent: ElementNode | undefined;
|
|
213
200
|
_rendererProps?: any;
|
|
@@ -270,10 +257,7 @@ export interface ElementNode extends RendererNode, FocusNode {
|
|
|
270
257
|
/**
|
|
271
258
|
* The underlying Lightning Renderer node object. This is where the properties are ultimately set for rendering.
|
|
272
259
|
*/
|
|
273
|
-
lng:
|
|
274
|
-
| Partial<ElementNode>
|
|
275
|
-
| IRendererNode
|
|
276
|
-
| (IRendererTextNode & { shader?: any });
|
|
260
|
+
lng: Partial<ElementNode> | IRendererNode | (IRendererTextNode & { shader?: any });
|
|
277
261
|
/**
|
|
278
262
|
* A reference to the `ElementNode` instance. Can be an object or a callback function.
|
|
279
263
|
*/
|
|
@@ -429,13 +413,7 @@ export interface ElementNode extends RendererNode, FocusNode {
|
|
|
429
413
|
*
|
|
430
414
|
* @see @see https://lightning-tv.github.io/solid/#/flow/layout?id=flex
|
|
431
415
|
*/
|
|
432
|
-
justifyContent?:
|
|
433
|
-
| 'flexStart'
|
|
434
|
-
| 'flexEnd'
|
|
435
|
-
| 'center'
|
|
436
|
-
| 'spaceBetween'
|
|
437
|
-
| 'spaceAround'
|
|
438
|
-
| 'spaceEvenly';
|
|
416
|
+
justifyContent?: 'flexStart' | 'flexEnd' | 'center' | 'spaceBetween' | 'spaceAround' | 'spaceEvenly';
|
|
439
417
|
/**
|
|
440
418
|
* Applies a linear gradient effect to the element.
|
|
441
419
|
*
|
|
@@ -519,10 +497,7 @@ export interface ElementNode extends RendererNode, FocusNode {
|
|
|
519
497
|
*
|
|
520
498
|
* @see https://lightning-tv.github.io/solid/#/essentials/transitions?id=transitions-animations
|
|
521
499
|
*/
|
|
522
|
-
transition?:
|
|
523
|
-
| Record<string, AnimationSettings | undefined | true | false>
|
|
524
|
-
| true
|
|
525
|
-
| false;
|
|
500
|
+
transition?: Record<string, AnimationSettings | undefined | true | false> | true | false;
|
|
526
501
|
/**
|
|
527
502
|
* Optional handlers for animation events.
|
|
528
503
|
*
|
|
@@ -670,23 +645,29 @@ export class ElementNode extends Object {
|
|
|
670
645
|
}
|
|
671
646
|
|
|
672
647
|
set fontWeight(v) {
|
|
648
|
+
if (this._fontWeight === v) {
|
|
649
|
+
return;
|
|
650
|
+
}
|
|
651
|
+
|
|
673
652
|
this._fontWeight = v;
|
|
674
|
-
const
|
|
675
|
-
|
|
676
|
-
(Config.fontWeightAlias &&
|
|
677
|
-
(Config.fontWeightAlias[v as string] as number | string)) ??
|
|
678
|
-
v;
|
|
679
|
-
this.fontFamily = `${family}${weight}`;
|
|
653
|
+
const weight = (Config.fontWeightAlias && (Config.fontWeightAlias[v as string] as number | string)) ?? v;
|
|
654
|
+
(this.lng as any).fontFamily = `${this.fontFamily}${weight}`;
|
|
680
655
|
}
|
|
681
656
|
|
|
682
657
|
get fontWeight() {
|
|
683
658
|
return this._fontWeight;
|
|
684
659
|
}
|
|
685
660
|
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
661
|
+
set fontFamily(v) {
|
|
662
|
+
this._fontFamily = v;
|
|
663
|
+
(this.lng as any).fontFamily = v;
|
|
664
|
+
}
|
|
665
|
+
|
|
666
|
+
get fontFamily() {
|
|
667
|
+
return this._fontFamily || Config.fontSettings?.fontFamily;
|
|
668
|
+
}
|
|
669
|
+
|
|
670
|
+
insertChild(node: ElementNode | ElementText | TextNode, beforeNode?: ElementNode | ElementText | TextNode | null) {
|
|
690
671
|
// always remove nodes if they have a parent - for back swap of node
|
|
691
672
|
// this will then put the node at the end of the array when re-added
|
|
692
673
|
if (node.parent) {
|
|
@@ -735,12 +716,8 @@ export class ElementNode extends Object {
|
|
|
735
716
|
return undefined;
|
|
736
717
|
}
|
|
737
718
|
|
|
738
|
-
set shader(
|
|
739
|
-
|
|
740
|
-
) {
|
|
741
|
-
this.lng.shader = isArray(shaderProps)
|
|
742
|
-
? renderer.createShader(...shaderProps)
|
|
743
|
-
: shaderProps;
|
|
719
|
+
set shader(shaderProps: IRendererShader | [kind: string, props: IRendererShaderProps]) {
|
|
720
|
+
this.lng.shader = isArray(shaderProps) ? renderer.createShader(...shaderProps) : shaderProps;
|
|
744
721
|
}
|
|
745
722
|
|
|
746
723
|
_sendToLightningAnimatable(name: string, value: number) {
|
|
@@ -748,9 +725,7 @@ export class ElementNode extends Object {
|
|
|
748
725
|
this.transition &&
|
|
749
726
|
this.rendered &&
|
|
750
727
|
Config.animationsEnabled &&
|
|
751
|
-
(this.transition === true ||
|
|
752
|
-
this.transition[name] ||
|
|
753
|
-
this.transition[getPropertyAlias(name)])
|
|
728
|
+
(this.transition === true || this.transition[name] || this.transition[getPropertyAlias(name)])
|
|
754
729
|
) {
|
|
755
730
|
const animationSettings =
|
|
756
731
|
this.transition === true || this.transition[name] === true
|
|
@@ -762,29 +737,20 @@ export class ElementNode extends Object {
|
|
|
762
737
|
this,
|
|
763
738
|
name,
|
|
764
739
|
value,
|
|
765
|
-
animationSettings ||
|
|
766
|
-
(this.animationSettings as SimpleAnimationSettings),
|
|
740
|
+
animationSettings || (this.animationSettings as SimpleAnimationSettings),
|
|
767
741
|
);
|
|
768
742
|
simpleAnimation.register(renderer.stage);
|
|
769
743
|
return;
|
|
770
744
|
} else {
|
|
771
|
-
const animationController = this.animate(
|
|
772
|
-
{ [name]: value },
|
|
773
|
-
animationSettings,
|
|
774
|
-
);
|
|
745
|
+
const animationController = this.animate({ [name]: value }, animationSettings);
|
|
775
746
|
|
|
776
747
|
if (this.onAnimation) {
|
|
777
|
-
const animationEvents = Object.keys(
|
|
778
|
-
this.onAnimation,
|
|
779
|
-
) as AnimationEvents[];
|
|
748
|
+
const animationEvents = Object.keys(this.onAnimation) as AnimationEvents[];
|
|
780
749
|
for (const event of animationEvents) {
|
|
781
750
|
const handler = this.onAnimation[event];
|
|
782
|
-
animationController.on(
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
handler!.call(this, controller, name, value, props);
|
|
786
|
-
},
|
|
787
|
-
);
|
|
751
|
+
animationController.on(event, (controller: IAnimationController, props?: any) => {
|
|
752
|
+
handler!.call(this, controller, name, value, props);
|
|
753
|
+
});
|
|
788
754
|
}
|
|
789
755
|
}
|
|
790
756
|
|
|
@@ -799,18 +765,11 @@ export class ElementNode extends Object {
|
|
|
799
765
|
props: Partial<INodeAnimateProps<CoreShaderNode>>,
|
|
800
766
|
animationSettings?: AnimationSettings,
|
|
801
767
|
): IAnimationController {
|
|
802
|
-
isDev &&
|
|
803
|
-
|
|
804
|
-
return (this.lng as IRendererNode).animate(
|
|
805
|
-
props,
|
|
806
|
-
animationSettings || this.animationSettings || {},
|
|
807
|
-
);
|
|
768
|
+
isDev && assertTruthy(this.rendered, 'Node must be rendered before animating');
|
|
769
|
+
return (this.lng as IRendererNode).animate(props, animationSettings || this.animationSettings || {});
|
|
808
770
|
}
|
|
809
771
|
|
|
810
|
-
chain(
|
|
811
|
-
props: Partial<INodeAnimateProps<CoreShaderNode>>,
|
|
812
|
-
animationSettings?: AnimationSettings,
|
|
813
|
-
) {
|
|
772
|
+
chain(props: Partial<INodeAnimateProps<CoreShaderNode>>, animationSettings?: AnimationSettings) {
|
|
814
773
|
if (this._animationRunning) {
|
|
815
774
|
this._animationQueue = [];
|
|
816
775
|
this._animationRunning = false;
|
|
@@ -819,8 +778,7 @@ export class ElementNode extends Object {
|
|
|
819
778
|
if (animationSettings) {
|
|
820
779
|
this._animationQueueSettings = animationSettings;
|
|
821
780
|
} else if (!this._animationQueueSettings) {
|
|
822
|
-
this._animationQueueSettings =
|
|
823
|
-
animationSettings || this.animationSettings;
|
|
781
|
+
this._animationQueueSettings = animationSettings || this.animationSettings;
|
|
824
782
|
}
|
|
825
783
|
animationSettings = animationSettings || this._animationQueueSettings;
|
|
826
784
|
this._animationQueue = this._animationQueue || [];
|
|
@@ -832,9 +790,7 @@ export class ElementNode extends Object {
|
|
|
832
790
|
let animation = this._animationQueue!.shift();
|
|
833
791
|
while (animation) {
|
|
834
792
|
this._animationRunning = true;
|
|
835
|
-
await this.animate(animation.props, animation.animationSettings)
|
|
836
|
-
.start()
|
|
837
|
-
.waitUntilStopped();
|
|
793
|
+
await this.animate(animation.props, animation.animationSettings).start().waitUntilStopped();
|
|
838
794
|
animation = this._animationQueue!.shift();
|
|
839
795
|
}
|
|
840
796
|
this._animationRunning = false;
|
|
@@ -866,8 +822,7 @@ export class ElementNode extends Object {
|
|
|
866
822
|
return;
|
|
867
823
|
}
|
|
868
824
|
} else {
|
|
869
|
-
const focusedIndex =
|
|
870
|
-
typeof this.forwardFocus === 'number' ? this.forwardFocus : null;
|
|
825
|
+
const focusedIndex = typeof this.forwardFocus === 'number' ? this.forwardFocus : null;
|
|
871
826
|
const nodes = this.children;
|
|
872
827
|
if (focusedIndex !== null && focusedIndex < nodes.length) {
|
|
873
828
|
const child = nodes[focusedIndex];
|
|
@@ -991,9 +946,7 @@ export class ElementNode extends Object {
|
|
|
991
946
|
}
|
|
992
947
|
|
|
993
948
|
set states(states: NodeStates) {
|
|
994
|
-
this._states = this._states
|
|
995
|
-
? this._states.merge(states)
|
|
996
|
-
: new States(this._stateChanged.bind(this), states);
|
|
949
|
+
this._states = this._states ? this._states.merge(states) : new States(this._stateChanged.bind(this), states);
|
|
997
950
|
if (this.rendered) {
|
|
998
951
|
this._stateChanged();
|
|
999
952
|
}
|
|
@@ -1061,8 +1014,7 @@ export class ElementNode extends Object {
|
|
|
1061
1014
|
|
|
1062
1015
|
const flexChanged = this.display === 'flex' && calculateFlex(this);
|
|
1063
1016
|
layoutQueue.delete(this);
|
|
1064
|
-
const onLayoutChanged =
|
|
1065
|
-
isFunc(this.onLayout) && this.onLayout.call(this, this);
|
|
1017
|
+
const onLayoutChanged = isFunc(this.onLayout) && this.onLayout.call(this, this);
|
|
1066
1018
|
|
|
1067
1019
|
if ((flexChanged || onLayoutChanged) && this.parent) {
|
|
1068
1020
|
addToLayoutQueue(this.parent);
|
|
@@ -1119,9 +1071,7 @@ export class ElementNode extends Object {
|
|
|
1119
1071
|
let newStyles: Styles;
|
|
1120
1072
|
if (numStates === 1) {
|
|
1121
1073
|
newStyles = this[states[0] as keyof Styles] as Styles;
|
|
1122
|
-
newStyles = stylesToUndo
|
|
1123
|
-
? { ...stylesToUndo, ...newStyles }
|
|
1124
|
-
: newStyles;
|
|
1074
|
+
newStyles = stylesToUndo ? { ...stylesToUndo, ...newStyles } : newStyles;
|
|
1125
1075
|
} else {
|
|
1126
1076
|
newStyles = states.reduce((acc, state) => {
|
|
1127
1077
|
const styles = this[state];
|
|
@@ -1236,17 +1186,13 @@ export class ElementNode extends Object {
|
|
|
1236
1186
|
}
|
|
1237
1187
|
|
|
1238
1188
|
if (!textProps.maxWidth) {
|
|
1239
|
-
textProps.maxWidth =
|
|
1240
|
-
parentWidth - textProps.x! - (textProps.marginRight || 0);
|
|
1189
|
+
textProps.maxWidth = parentWidth - textProps.x! - (textProps.marginRight || 0);
|
|
1241
1190
|
}
|
|
1242
1191
|
|
|
1243
1192
|
if (textProps.contain === 'both' && !textProps.maxHeight) {
|
|
1244
|
-
textProps.maxHeight =
|
|
1245
|
-
parentHeight - textProps.y! - (textProps.marginBottom || 0);
|
|
1193
|
+
textProps.maxHeight = parentHeight - textProps.y! - (textProps.marginBottom || 0);
|
|
1246
1194
|
} else if (textProps.maxLines === 1) {
|
|
1247
|
-
textProps.maxHeight = (textProps.maxHeight ||
|
|
1248
|
-
textProps.lineHeight ||
|
|
1249
|
-
textProps.fontSize) as number;
|
|
1195
|
+
textProps.maxHeight = (textProps.maxHeight || textProps.lineHeight || textProps.fontSize) as number;
|
|
1250
1196
|
}
|
|
1251
1197
|
|
|
1252
1198
|
textProps.w = textProps.h = undefined;
|
|
@@ -1258,9 +1204,7 @@ export class ElementNode extends Object {
|
|
|
1258
1204
|
}
|
|
1259
1205
|
|
|
1260
1206
|
isDev && log('Rendering: ', this, props);
|
|
1261
|
-
node.lng = renderer.createTextNode(
|
|
1262
|
-
props as unknown as IRendererTextNodeProps,
|
|
1263
|
-
);
|
|
1207
|
+
node.lng = renderer.createTextNode(props as unknown as IRendererTextNodeProps);
|
|
1264
1208
|
if (parent.requiresLayout()) {
|
|
1265
1209
|
if (!textProps.maxWidth || !textProps.maxHeight) {
|
|
1266
1210
|
node._layoutOnLoad();
|
|
@@ -1390,9 +1334,7 @@ function createRawShaderAccessor<T>(key: keyof StyleEffects) {
|
|
|
1390
1334
|
};
|
|
1391
1335
|
}
|
|
1392
1336
|
|
|
1393
|
-
function shaderAccessor<T extends Record<string, any> | number>(
|
|
1394
|
-
key: 'border' | 'shadow' | 'rounded',
|
|
1395
|
-
) {
|
|
1337
|
+
function shaderAccessor<T extends Record<string, any> | number>(key: 'border' | 'shadow' | 'rounded') {
|
|
1396
1338
|
return {
|
|
1397
1339
|
set(this: ElementNode, value: T) {
|
|
1398
1340
|
let target = this.lng.shader || {};
|
|
@@ -1401,17 +1343,12 @@ function shaderAccessor<T extends Record<string, any> | number>(
|
|
|
1401
1343
|
if (this.lng.shader?.program) {
|
|
1402
1344
|
target = this.lng.shader.props;
|
|
1403
1345
|
const transitionKey = key === 'rounded' ? 'borderRadius' : key;
|
|
1404
|
-
if (
|
|
1405
|
-
this.transition &&
|
|
1406
|
-
(this.transition === true || this.transition[transitionKey])
|
|
1407
|
-
) {
|
|
1346
|
+
if (this.transition && (this.transition === true || this.transition[transitionKey])) {
|
|
1408
1347
|
target = {};
|
|
1409
1348
|
animationSettings =
|
|
1410
1349
|
this.transition === true || this.transition[transitionKey] === true
|
|
1411
1350
|
? undefined
|
|
1412
|
-
: (this.transition[transitionKey] as
|
|
1413
|
-
| undefined
|
|
1414
|
-
| AnimationSettings);
|
|
1351
|
+
: (this.transition[transitionKey] as undefined | AnimationSettings);
|
|
1415
1352
|
}
|
|
1416
1353
|
}
|
|
1417
1354
|
|
|
@@ -1451,8 +1388,6 @@ Object.defineProperties(ElementNode.prototype, {
|
|
|
1451
1388
|
rounded: shaderAccessor<BorderRadius>('rounded'),
|
|
1452
1389
|
// Alias for rounded
|
|
1453
1390
|
borderRadius: shaderAccessor<BorderRadius>('rounded'),
|
|
1454
|
-
linearGradient:
|
|
1455
|
-
|
|
1456
|
-
radialGradient:
|
|
1457
|
-
createRawShaderAccessor<RadialGradientProps>('radialGradient'),
|
|
1391
|
+
linearGradient: createRawShaderAccessor<LinearGradientProps>('linearGradient'),
|
|
1392
|
+
radialGradient: createRawShaderAccessor<RadialGradientProps>('radialGradient'),
|
|
1458
1393
|
});
|
|
@@ -9,12 +9,7 @@ import {
|
|
|
9
9
|
ShaderRoundedProps,
|
|
10
10
|
ShaderShadowProps,
|
|
11
11
|
} from './shaders.js';
|
|
12
|
-
import {
|
|
13
|
-
EventHandlers,
|
|
14
|
-
DefaultKeyMap,
|
|
15
|
-
KeyHoldMap,
|
|
16
|
-
FocusNode,
|
|
17
|
-
} from './focusKeyTypes.js';
|
|
12
|
+
import { EventHandlers, DefaultKeyMap, KeyHoldMap, FocusNode } from './focusKeyTypes.js';
|
|
18
13
|
import type { JSXElement } from 'solid-js';
|
|
19
14
|
|
|
20
15
|
export type AnimationSettings = Partial<lngr.AnimationSettings>;
|
|
@@ -52,9 +47,7 @@ export type RemoveUnderscoreProps<T> = {
|
|
|
52
47
|
[K in keyof T as K extends `_${string}` ? never : K]: T[K];
|
|
53
48
|
};
|
|
54
49
|
|
|
55
|
-
type RendererText = AddColorString<
|
|
56
|
-
Partial<Omit<lngr.ITextNodeProps, 'debug' | 'shader' | 'parent'>>
|
|
57
|
-
>;
|
|
50
|
+
type RendererText = AddColorString<Partial<Omit<lngr.ITextNodeProps, 'debug' | 'shader' | 'parent'>>>;
|
|
58
51
|
|
|
59
52
|
type CleanElementNode = NewOmit<
|
|
60
53
|
RemoveUnderscoreProps<ElementNode>,
|
|
@@ -80,10 +73,7 @@ type CleanElementNode = NewOmit<
|
|
|
80
73
|
>;
|
|
81
74
|
/** Node text, children of a ElementNode of type TextNode */
|
|
82
75
|
export interface ElementText
|
|
83
|
-
extends NewOmit<
|
|
84
|
-
ElementNode,
|
|
85
|
-
'_type' | 'parent' | 'children' | 'src' | 'scale'
|
|
86
|
-
>,
|
|
76
|
+
extends NewOmit<ElementNode, '_type' | 'parent' | 'children' | 'src' | 'scale' | 'fontFamily'>,
|
|
87
77
|
NewOmit<RendererText, 'x' | 'y' | 'w' | 'h'> {
|
|
88
78
|
_type: 'textNode';
|
|
89
79
|
parent?: ElementNode;
|
|
@@ -107,14 +97,7 @@ export interface NodeProps
|
|
|
107
97
|
Partial<
|
|
108
98
|
NewOmit<
|
|
109
99
|
CleanElementNode,
|
|
110
|
-
| '
|
|
111
|
-
| 'text'
|
|
112
|
-
| 'lng'
|
|
113
|
-
| 'rendered'
|
|
114
|
-
| 'renderer'
|
|
115
|
-
| 'emit'
|
|
116
|
-
| 'preFlexwidth'
|
|
117
|
-
| 'preFlexHeight'
|
|
100
|
+
'children' | 'text' | 'lng' | 'rendered' | 'renderer' | 'emit' | 'preFlexwidth' | 'preFlexHeight'
|
|
118
101
|
>
|
|
119
102
|
> {
|
|
120
103
|
states?: NodeStates;
|
|
@@ -189,10 +172,7 @@ type EventPayloadMap = {
|
|
|
189
172
|
|
|
190
173
|
type NodeEvents = keyof EventPayloadMap;
|
|
191
174
|
|
|
192
|
-
type EventHandler<E extends NodeEvents> = (
|
|
193
|
-
target: ElementNode,
|
|
194
|
-
event?: EventPayloadMap[E],
|
|
195
|
-
) => void;
|
|
175
|
+
type EventHandler<E extends NodeEvents> = (target: ElementNode, event?: EventPayloadMap[E]) => void;
|
|
196
176
|
|
|
197
177
|
export type OnEvent = Partial<{
|
|
198
178
|
[K in NodeEvents]: EventHandler<K>;
|
package/src/index.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export * from '@lightningtv/solid/jsx-runtime';
|
|
1
|
+
export type * from '@lightningtv/solid/jsx-runtime';
|
|
2
2
|
export * from './core/index.js';
|
|
3
3
|
export type * from './core/index.js';
|
|
4
4
|
export type { KeyHandler, KeyMap } from './core/focusManager.js';
|
|
@@ -6,13 +6,4 @@ export * from './activeElement.js';
|
|
|
6
6
|
export * from './utils.js';
|
|
7
7
|
export * from './render.js';
|
|
8
8
|
export * from './types.js';
|
|
9
|
-
export {
|
|
10
|
-
For,
|
|
11
|
-
Show,
|
|
12
|
-
Suspense,
|
|
13
|
-
SuspenseList,
|
|
14
|
-
Switch,
|
|
15
|
-
Match,
|
|
16
|
-
Index,
|
|
17
|
-
ErrorBoundary,
|
|
18
|
-
} from 'solid-js';
|
|
9
|
+
export { For, Show, Suspense, SuspenseList, Switch, Match, Index, ErrorBoundary } from 'solid-js';
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ElementNode, NodeProps, View
|
|
1
|
+
import { ElementNode, NodeProps, View } from '@lightningtv/solid';
|
|
2
2
|
import { Show } from 'solid-js';
|
|
3
3
|
|
|
4
4
|
interface Props {
|
|
@@ -14,6 +14,19 @@ const DEFAULT_PROPS = {
|
|
|
14
14
|
easing: 'ease-in-out',
|
|
15
15
|
};
|
|
16
16
|
|
|
17
|
+
export const ALPHA_NONE = { alpha: 0 };
|
|
18
|
+
export const ALPHA_FULL = { alpha: 1 };
|
|
19
|
+
|
|
20
|
+
export function fadeIn(el: ElementNode): void {
|
|
21
|
+
if (!el?.lng?.animate) return;
|
|
22
|
+
el.alpha = 0;
|
|
23
|
+
el.animate(ALPHA_FULL).start();
|
|
24
|
+
}
|
|
25
|
+
export function fadeOut(el: ElementNode): Promise<void> {
|
|
26
|
+
if (!el?.lng?.animate) return Promise.resolve();
|
|
27
|
+
return el.animate(ALPHA_NONE).start().waitUntilStopped();
|
|
28
|
+
}
|
|
29
|
+
|
|
17
30
|
export default function FadeInOut(props: Props & NodeProps) {
|
|
18
31
|
const config = Object.assign({}, DEFAULT_PROPS, props.transition);
|
|
19
32
|
function onCreate(elm: ElementNode) {
|
|
@@ -23,12 +36,12 @@ export default function FadeInOut(props: Props & NodeProps) {
|
|
|
23
36
|
|
|
24
37
|
function onDestroy(elm: ElementNode) {
|
|
25
38
|
elm.rtt = true;
|
|
26
|
-
return elm.animate({ alpha: 0 }, { duration: config.duration, easing: config.easing })
|
|
27
|
-
.start().waitUntilStopped();
|
|
39
|
+
return elm.animate({ alpha: 0 }, { duration: config.duration, easing: config.easing }).start().waitUntilStopped();
|
|
28
40
|
}
|
|
29
41
|
|
|
30
42
|
return (
|
|
31
43
|
<Show when={props.when} keyed>
|
|
32
44
|
<View {...props} onDestroy={onDestroy} onCreate={onCreate} />
|
|
33
|
-
</Show>
|
|
45
|
+
</Show>
|
|
46
|
+
);
|
|
34
47
|
}
|
package/src/primitives/Lazy.tsx
CHANGED
|
@@ -68,7 +68,7 @@ function createLazy<T>(
|
|
|
68
68
|
if (itemLength != props.each.length) {
|
|
69
69
|
itemLength = props.each.length;
|
|
70
70
|
if (viewRef && !viewRef.noRefocus && lng.hasFocus(viewRef)) {
|
|
71
|
-
queueMicrotask(viewRef.setFocus);
|
|
71
|
+
queueMicrotask(() => viewRef.setFocus());
|
|
72
72
|
}
|
|
73
73
|
}
|
|
74
74
|
return props.each.slice(0, offset());
|
|
@@ -46,7 +46,7 @@ function createVirtual<T>(
|
|
|
46
46
|
return props.uniformSize !== false;
|
|
47
47
|
});
|
|
48
48
|
|
|
49
|
-
type SliceState = { start: number; slice: T[]; selected: number, delta: number, shiftBy: number, atStart: boolean };
|
|
49
|
+
type SliceState = { start: number; slice: T[]; selected: number, delta: number, shiftBy: number, atStart: boolean; cursor: number };
|
|
50
50
|
const [slice, setSlice] = s.createSignal<SliceState>({
|
|
51
51
|
start: 0,
|
|
52
52
|
slice: [],
|
|
@@ -54,6 +54,7 @@ function createVirtual<T>(
|
|
|
54
54
|
delta: 0,
|
|
55
55
|
shiftBy: 0,
|
|
56
56
|
atStart: true,
|
|
57
|
+
cursor: 0,
|
|
57
58
|
});
|
|
58
59
|
|
|
59
60
|
function normalizeDeltaForWindow(delta: number, windowLen: number): number {
|
|
@@ -86,7 +87,7 @@ function createVirtual<T>(
|
|
|
86
87
|
|
|
87
88
|
function computeSlice(c: number, delta: number, prev: SliceState): SliceState {
|
|
88
89
|
const total = itemCount();
|
|
89
|
-
if (total === 0) return { start: 0, slice: [], selected: 0, delta, shiftBy: 0, atStart: true };
|
|
90
|
+
if (total === 0) return { start: 0, slice: [], selected: 0, delta, shiftBy: 0, atStart: true, cursor: 0 };
|
|
90
91
|
|
|
91
92
|
const length = props.displaySize + bufferSize();
|
|
92
93
|
let start = prev.start;
|
|
@@ -186,7 +187,7 @@ function createVirtual<T>(
|
|
|
186
187
|
atStart = false;
|
|
187
188
|
} else {
|
|
188
189
|
// ScrollToIndex was called
|
|
189
|
-
if (
|
|
190
|
+
if (c !== prev.cursor) {
|
|
190
191
|
start = c;
|
|
191
192
|
if (c === 0) {
|
|
192
193
|
atStart = true;
|
|
@@ -286,7 +287,7 @@ function createVirtual<T>(
|
|
|
286
287
|
: items().slice(start, start + length);
|
|
287
288
|
}
|
|
288
289
|
|
|
289
|
-
const state: SliceState = { start, slice: newSlice, selected, delta, shiftBy, atStart };
|
|
290
|
+
const state: SliceState = { start, slice: newSlice, selected, delta, shiftBy, atStart, cursor: c };
|
|
290
291
|
|
|
291
292
|
if (props.debugInfo) {
|
|
292
293
|
console.log(`[Virtual]`, {
|
|
@@ -412,6 +413,15 @@ function createVirtual<T>(
|
|
|
412
413
|
if (lng.hasFocus(viewRef)) {
|
|
413
414
|
viewRef.children[activeIndex]?.setFocus();
|
|
414
415
|
}
|
|
416
|
+
|
|
417
|
+
if (newState.shiftBy === 0) return;
|
|
418
|
+
|
|
419
|
+
const childSize = computeSize(slice().selected);
|
|
420
|
+
// Original Position is offset to support scrollToIndex
|
|
421
|
+
originalPosition = originalPosition ?? viewRef.lng[axis];
|
|
422
|
+
targetPosition = targetPosition ?? viewRef.lng[axis];
|
|
423
|
+
|
|
424
|
+
viewRef.lng[axis] = (viewRef.lng[axis] || 0) + (childSize * -1);
|
|
415
425
|
});
|
|
416
426
|
};
|
|
417
427
|
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { ElementNode, insertNode, type NodeProps, type NodeStyles } from '@lightningtv/solid';
|
|
2
|
+
import { createMemo, getOwner, onMount, runWithOwner, type Accessor } from 'solid-js';
|
|
3
|
+
import { fadeIn, fadeOut } from './FadeInOut.jsx';
|
|
4
|
+
import { chainFunctions } from '@lightningtv/solid/primitives';
|
|
5
|
+
|
|
6
|
+
export const BorderBoxStyle: NodeStyles = {
|
|
7
|
+
alpha: 0,
|
|
8
|
+
borderSpace: 6,
|
|
9
|
+
borderRadius: 20,
|
|
10
|
+
border: { color: 0xffffff, width: 2 },
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
type BorderProps = NodeProps & { borderSpace?: number };
|
|
14
|
+
const borderComponent = (props: BorderProps) => {
|
|
15
|
+
const space = createMemo(() => props.borderSpace ?? (BorderBoxStyle.borderSpace as number));
|
|
16
|
+
return (
|
|
17
|
+
<>
|
|
18
|
+
<view
|
|
19
|
+
skipFocus
|
|
20
|
+
onCreate={(el) => {
|
|
21
|
+
const parent = el.parent!;
|
|
22
|
+
el.width = parent.width + space() * 2;
|
|
23
|
+
el.height = parent.height + space() * 2;
|
|
24
|
+
fadeIn(el);
|
|
25
|
+
}}
|
|
26
|
+
onDestroy={fadeOut}
|
|
27
|
+
style={BorderBoxStyle}
|
|
28
|
+
x={-space()}
|
|
29
|
+
y={-space()}
|
|
30
|
+
{...props}
|
|
31
|
+
/>
|
|
32
|
+
</>
|
|
33
|
+
);
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
// Solid directives can only be used on native root elements `view` and `text`
|
|
37
|
+
export default function borderbox(el: ElementNode, accessor: Accessor<BorderProps | true | undefined>) {
|
|
38
|
+
let border: ElementNode | null;
|
|
39
|
+
const owner = getOwner();
|
|
40
|
+
|
|
41
|
+
onMount(() => {
|
|
42
|
+
el.onFocusChanged = chainFunctions((f) => {
|
|
43
|
+
if (f) {
|
|
44
|
+
if (border) return;
|
|
45
|
+
runWithOwner(owner, () => {
|
|
46
|
+
const props = accessor();
|
|
47
|
+
border = borderComponent(
|
|
48
|
+
props === true || props === undefined ? ({} as NodeProps) : props,
|
|
49
|
+
) as any as ElementNode;
|
|
50
|
+
insertNode(el, border);
|
|
51
|
+
border.render();
|
|
52
|
+
});
|
|
53
|
+
} else if (border) {
|
|
54
|
+
border.destroy();
|
|
55
|
+
el.removeChild(border!);
|
|
56
|
+
border = null;
|
|
57
|
+
}
|
|
58
|
+
}, el.onFocusChanged);
|
|
59
|
+
});
|
|
60
|
+
}
|
package/src/primitives/index.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
export * from './useFocusManager.js';
|
|
2
2
|
export * from './announcer/index.js';
|
|
3
3
|
export * from './createInfiniteItems.js';
|
|
4
|
+
export * from './borderBox.jsx';
|
|
4
5
|
export * from './useMouse.js';
|
|
5
6
|
export * from './portal.jsx';
|
|
6
7
|
export * from './Lazy.jsx';
|
|
@@ -23,11 +24,7 @@ export * from './VirtualGrid.jsx';
|
|
|
23
24
|
export * from './Virtual.jsx';
|
|
24
25
|
export * from './utils/withScrolling.js';
|
|
25
26
|
export * from './createTag.jsx';
|
|
26
|
-
export {
|
|
27
|
-
type AnyFunction,
|
|
28
|
-
chainFunctions,
|
|
29
|
-
chainRefs,
|
|
30
|
-
} from './utils/chainFunctions.js';
|
|
27
|
+
export { type AnyFunction, chainFunctions, chainRefs } from './utils/chainFunctions.js';
|
|
31
28
|
export * from './utils/handleNavigation.js';
|
|
32
29
|
export { createSpriteMap, type SpriteDef } from './utils/createSpriteMap.js';
|
|
33
30
|
export { createBlurredImage } from './utils/createBlurredImage.js';
|