@lightningtv/solid 2.10.0 → 2.10.2
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/primitives/Virtual.d.ts +14 -0
- package/dist/src/primitives/Virtual.jsx +107 -0
- package/dist/src/primitives/Virtual.jsx.map +1 -0
- package/dist/src/primitives/VirtualGrid.d.ts +1 -0
- package/dist/src/primitives/VirtualGrid.jsx +6 -5
- package/dist/src/primitives/VirtualGrid.jsx.map +1 -1
- package/dist/src/primitives/VirtualRow.d.ts +13 -0
- package/dist/src/primitives/VirtualRow.jsx +97 -0
- package/dist/src/primitives/VirtualRow.jsx.map +1 -0
- package/dist/src/primitives/index.d.ts +1 -1
- package/dist/src/primitives/index.js +1 -1
- package/dist/src/primitives/index.js.map +1 -1
- package/dist/src/universal.d.ts +25 -0
- package/dist/src/universal.js +232 -0
- package/dist/src/universal.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/src/primitives/Virtual.tsx +159 -0
- package/src/primitives/VirtualGrid.tsx +10 -7
- package/src/primitives/index.ts +1 -1
- package/src/primitives/VirtualList.tsx +0 -140
|
@@ -1,140 +0,0 @@
|
|
|
1
|
-
import * as s from 'solid-js';
|
|
2
|
-
import * as lng from '@lightningtv/solid';
|
|
3
|
-
import * as lngp from '@lightningtv/solid/primitives';
|
|
4
|
-
import { List } from '@solid-primitives/list';
|
|
5
|
-
import * as utils from '../utils.js';
|
|
6
|
-
|
|
7
|
-
const rowOnLeft = lngp.handleNavigation('left');
|
|
8
|
-
const rowOnRight = lngp.handleNavigation('right');
|
|
9
|
-
const rowScroll = lngp.withScrolling(true);
|
|
10
|
-
|
|
11
|
-
const rowStyles: lng.NodeStyles = {
|
|
12
|
-
display: 'flex',
|
|
13
|
-
gap: 30,
|
|
14
|
-
transition: {
|
|
15
|
-
x: {
|
|
16
|
-
duration: 250,
|
|
17
|
-
easing: 'ease-out',
|
|
18
|
-
},
|
|
19
|
-
},
|
|
20
|
-
};
|
|
21
|
-
|
|
22
|
-
function scrollToIndex(this: lng.ElementNode, index: number) {
|
|
23
|
-
this.selected = index;
|
|
24
|
-
rowScroll(index, this);
|
|
25
|
-
this.setFocus();
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
export type VirtualListProps<T> = lng.NewOmit<lngp.RowProps, 'children'> & {
|
|
29
|
-
each: readonly T[] | undefined | null | false;
|
|
30
|
-
displaySize: number;
|
|
31
|
-
bufferSize?: number;
|
|
32
|
-
fallback?: s.JSX.Element;
|
|
33
|
-
children: (item: s.Accessor<T>, index: s.Accessor<number>) => s.JSX.Element;
|
|
34
|
-
};
|
|
35
|
-
|
|
36
|
-
export function VirtualList<T>(props: VirtualListProps<T>): s.JSX.Element {
|
|
37
|
-
|
|
38
|
-
const [ cursor, setCursor ] = s.createSignal(props.selected ?? 0);
|
|
39
|
-
|
|
40
|
-
const bufferSize = () => props.bufferSize ?? 2;
|
|
41
|
-
|
|
42
|
-
const items = s.createMemo(() => props.each || []);
|
|
43
|
-
|
|
44
|
-
const start = () =>
|
|
45
|
-
utils.clamp(cursor() - bufferSize(), 0, Math.max(0, items().length - props.displaySize - bufferSize()));
|
|
46
|
-
|
|
47
|
-
const end = () =>
|
|
48
|
-
Math.min(items().length, cursor() + props.displaySize + bufferSize());
|
|
49
|
-
|
|
50
|
-
const [ slice, setSlice ] = s.createSignal(items().slice(start(), end()));
|
|
51
|
-
|
|
52
|
-
s.createEffect(s.on([ () => props.selected, items ], ([selected]) => {
|
|
53
|
-
if (!viewRef || !selected) return;
|
|
54
|
-
|
|
55
|
-
const item = items()![selected];
|
|
56
|
-
let active = viewRef.children.find(x => x.item === item);
|
|
57
|
-
const lastSelected = viewRef.selected;
|
|
58
|
-
|
|
59
|
-
if (active instanceof lng.ElementNode) {
|
|
60
|
-
viewRef.selected = viewRef.children.indexOf(active);
|
|
61
|
-
chainedOnSelectedChanged.call(viewRef, viewRef.selected, viewRef, active, lastSelected);
|
|
62
|
-
}
|
|
63
|
-
else {
|
|
64
|
-
setCursor(selected);
|
|
65
|
-
setSlice(items().slice(start(), end()));
|
|
66
|
-
queueMicrotask(() => {
|
|
67
|
-
viewRef.updateLayout();
|
|
68
|
-
active = viewRef.children.find(x => x.item === item);
|
|
69
|
-
if (active instanceof lng.ElementNode) {
|
|
70
|
-
viewRef.selected = viewRef.children.indexOf(active);
|
|
71
|
-
chainedOnSelectedChanged.call(viewRef, viewRef.selected, viewRef, active, lastSelected);
|
|
72
|
-
}
|
|
73
|
-
});
|
|
74
|
-
}
|
|
75
|
-
}));
|
|
76
|
-
|
|
77
|
-
s.createEffect(s.on(items, () => {
|
|
78
|
-
if (!viewRef) return;
|
|
79
|
-
setSlice(items().slice(start(), end()));
|
|
80
|
-
}, { defer: true }));
|
|
81
|
-
|
|
82
|
-
const onSelectedChanged: lngp.OnSelectedChanged = function (
|
|
83
|
-
_idx, elm, active, _lastIdx,
|
|
84
|
-
) {
|
|
85
|
-
let idx = _idx;
|
|
86
|
-
let lastIdx = _lastIdx;
|
|
87
|
-
|
|
88
|
-
if (idx === lastIdx) return;
|
|
89
|
-
|
|
90
|
-
const prevChildX = this.x + active.x;
|
|
91
|
-
const prevStart = start();
|
|
92
|
-
|
|
93
|
-
// Update the displayed slice of items
|
|
94
|
-
setCursor(prevStart + idx);
|
|
95
|
-
setSlice(items().slice(start(), end()));
|
|
96
|
-
|
|
97
|
-
// this.selected is relative to the slice
|
|
98
|
-
// and it doesn't get corrected automatically after children change
|
|
99
|
-
const idxCorrection = prevStart - start();
|
|
100
|
-
if (lastIdx) lastIdx += idxCorrection;
|
|
101
|
-
idx += idxCorrection;
|
|
102
|
-
this.selected += idxCorrection;
|
|
103
|
-
|
|
104
|
-
// Microtask & this.updateLayout() to make sure the child position is recalculated
|
|
105
|
-
queueMicrotask(() => {
|
|
106
|
-
this.updateLayout();
|
|
107
|
-
|
|
108
|
-
// Correct this.x for changes to children, bypass animation
|
|
109
|
-
this.lng.x = prevChildX - active.x;
|
|
110
|
-
|
|
111
|
-
// smoothly scroll to new selected element
|
|
112
|
-
rowScroll(idx, elm, active, lastIdx);
|
|
113
|
-
});
|
|
114
|
-
};
|
|
115
|
-
|
|
116
|
-
const chainedOnSelectedChanged = lngp.chainFunctions(props.onSelectedChanged, onSelectedChanged)!;
|
|
117
|
-
|
|
118
|
-
let viewRef!: lngp.NavigableElement;
|
|
119
|
-
return <>
|
|
120
|
-
<view
|
|
121
|
-
{...props}
|
|
122
|
-
scroll='always' // only supporting always scroll at the moment
|
|
123
|
-
ref={lngp.chainRefs(el => { viewRef = el as lngp.NavigableElement; }, props.ref)}
|
|
124
|
-
selected={props.selected || 0}
|
|
125
|
-
cursor={cursor()}
|
|
126
|
-
onLeft={/* @once */ lngp.chainFunctions(props.onLeft, rowOnLeft)}
|
|
127
|
-
onRight={/* @once */ lngp.chainFunctions(props.onRight, rowOnRight)}
|
|
128
|
-
forwardFocus={/* @once */ lngp.navigableForwardFocus}
|
|
129
|
-
scrollToIndex={scrollToIndex}
|
|
130
|
-
onCreate={/* @once */
|
|
131
|
-
props.selected ? lngp.chainFunctions(props.onCreate, rowScroll) : props.onCreate
|
|
132
|
-
}
|
|
133
|
-
/* lngp.NavigableElement.onSelectedChanged is used by lngp.handleNavigation */
|
|
134
|
-
onSelectedChanged={chainedOnSelectedChanged}
|
|
135
|
-
style={/* @once */ lng.combineStyles(props.style, rowStyles)}
|
|
136
|
-
>
|
|
137
|
-
<List each={slice()}>{props.children}</List>
|
|
138
|
-
</view>
|
|
139
|
-
</>;
|
|
140
|
-
}
|