@legendapp/list 0.5.4 → 0.5.6
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/index.d.mts +14 -10
- package/index.d.ts +14 -10
- package/index.js +163 -35
- package/index.mjs +163 -35
- package/package.json +1 -1
package/index.d.mts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { ComponentProps, ReactNode, ForwardedRef, ReactElement } from 'react';
|
|
2
2
|
import { ScrollView, StyleProp, ViewStyle, ScrollViewComponent, ScrollResponderMixin } from 'react-native';
|
|
3
3
|
|
|
4
|
-
type LegendListProps<
|
|
5
|
-
data: ArrayLike<any> &
|
|
4
|
+
type LegendListProps<ItemT> = Omit<ComponentProps<typeof ScrollView>, 'contentOffset' | 'contentInset' | 'maintainVisibleContentPosition' | 'stickyHeaderIndices'> & {
|
|
5
|
+
data: ArrayLike<any> & ItemT[];
|
|
6
6
|
initialScrollOffset?: number;
|
|
7
7
|
initialScrollIndex?: number;
|
|
8
8
|
drawDistance?: number;
|
|
@@ -14,16 +14,17 @@ type LegendListProps<T> = Omit<ComponentProps<typeof ScrollView>, 'contentOffset
|
|
|
14
14
|
maintainScrollAtEndThreshold?: number;
|
|
15
15
|
alignItemsAtEnd?: boolean;
|
|
16
16
|
maintainVisibleContentPosition?: boolean;
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
distanceFromEnd: number;
|
|
21
|
-
}) => void) | null | undefined;
|
|
17
|
+
numColumns?: number;
|
|
18
|
+
estimatedItemSize?: number;
|
|
19
|
+
getEstimatedItemSize?: (index: number, item: ItemT) => number;
|
|
22
20
|
onStartReached?: ((info: {
|
|
23
21
|
distanceFromStart: number;
|
|
24
22
|
}) => void) | null | undefined;
|
|
25
|
-
|
|
26
|
-
|
|
23
|
+
onEndReached?: ((info: {
|
|
24
|
+
distanceFromEnd: number;
|
|
25
|
+
}) => void) | null | undefined;
|
|
26
|
+
keyExtractor?: (item: ItemT, index: number) => string;
|
|
27
|
+
renderItem?: (props: LegendListRenderItemProps<ItemT>) => ReactNode;
|
|
27
28
|
ListHeaderComponent?: React.ComponentType<any> | React.ReactElement | null | undefined;
|
|
28
29
|
ListHeaderComponentStyle?: StyleProp<ViewStyle> | undefined;
|
|
29
30
|
ListFooterComponent?: React.ComponentType<any> | React.ReactElement | null | undefined;
|
|
@@ -37,7 +38,9 @@ type LegendListProps<T> = Omit<ComponentProps<typeof ScrollView>, 'contentOffset
|
|
|
37
38
|
};
|
|
38
39
|
interface InternalState {
|
|
39
40
|
positions: Map<string, number>;
|
|
41
|
+
columns: Map<string, number>;
|
|
40
42
|
sizes: Map<string, number>;
|
|
43
|
+
sizesLaidOut: Map<string, number> | undefined;
|
|
41
44
|
pendingAdjust: number;
|
|
42
45
|
animFrameLayout: any;
|
|
43
46
|
animFrameTotalSize: number | null;
|
|
@@ -61,6 +64,7 @@ interface InternalState {
|
|
|
61
64
|
scrollAdjustPending: number;
|
|
62
65
|
totalSize: number;
|
|
63
66
|
timeouts: Set<number>;
|
|
67
|
+
timeoutSizeMessage: any;
|
|
64
68
|
nativeMarginTop: number;
|
|
65
69
|
indexByKey: Map<string, number>;
|
|
66
70
|
contentSize: {
|
|
@@ -87,7 +91,7 @@ interface LegendListRenderItemProps<ItemT> {
|
|
|
87
91
|
useViewability: (configId: string, callback: ViewabilityCallback) => void;
|
|
88
92
|
useViewabilityAmount: (callback: ViewabilityAmountCallback) => void;
|
|
89
93
|
useRecyclingEffect: (effect: (info: LegendListRecyclingState<ItemT>) => void | (() => void)) => void;
|
|
90
|
-
useRecyclingState: <T>(updateState: (info: LegendListRecyclingState<ItemT>) => T) => [T, React.Dispatch<T>];
|
|
94
|
+
useRecyclingState: <T>(updateState: ((info: LegendListRecyclingState<ItemT>) => T) | T) => [T, React.Dispatch<T>];
|
|
91
95
|
}
|
|
92
96
|
type LegendListRef = {
|
|
93
97
|
/**
|
package/index.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { ComponentProps, ReactNode, ForwardedRef, ReactElement } from 'react';
|
|
2
2
|
import { ScrollView, StyleProp, ViewStyle, ScrollViewComponent, ScrollResponderMixin } from 'react-native';
|
|
3
3
|
|
|
4
|
-
type LegendListProps<
|
|
5
|
-
data: ArrayLike<any> &
|
|
4
|
+
type LegendListProps<ItemT> = Omit<ComponentProps<typeof ScrollView>, 'contentOffset' | 'contentInset' | 'maintainVisibleContentPosition' | 'stickyHeaderIndices'> & {
|
|
5
|
+
data: ArrayLike<any> & ItemT[];
|
|
6
6
|
initialScrollOffset?: number;
|
|
7
7
|
initialScrollIndex?: number;
|
|
8
8
|
drawDistance?: number;
|
|
@@ -14,16 +14,17 @@ type LegendListProps<T> = Omit<ComponentProps<typeof ScrollView>, 'contentOffset
|
|
|
14
14
|
maintainScrollAtEndThreshold?: number;
|
|
15
15
|
alignItemsAtEnd?: boolean;
|
|
16
16
|
maintainVisibleContentPosition?: boolean;
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
distanceFromEnd: number;
|
|
21
|
-
}) => void) | null | undefined;
|
|
17
|
+
numColumns?: number;
|
|
18
|
+
estimatedItemSize?: number;
|
|
19
|
+
getEstimatedItemSize?: (index: number, item: ItemT) => number;
|
|
22
20
|
onStartReached?: ((info: {
|
|
23
21
|
distanceFromStart: number;
|
|
24
22
|
}) => void) | null | undefined;
|
|
25
|
-
|
|
26
|
-
|
|
23
|
+
onEndReached?: ((info: {
|
|
24
|
+
distanceFromEnd: number;
|
|
25
|
+
}) => void) | null | undefined;
|
|
26
|
+
keyExtractor?: (item: ItemT, index: number) => string;
|
|
27
|
+
renderItem?: (props: LegendListRenderItemProps<ItemT>) => ReactNode;
|
|
27
28
|
ListHeaderComponent?: React.ComponentType<any> | React.ReactElement | null | undefined;
|
|
28
29
|
ListHeaderComponentStyle?: StyleProp<ViewStyle> | undefined;
|
|
29
30
|
ListFooterComponent?: React.ComponentType<any> | React.ReactElement | null | undefined;
|
|
@@ -37,7 +38,9 @@ type LegendListProps<T> = Omit<ComponentProps<typeof ScrollView>, 'contentOffset
|
|
|
37
38
|
};
|
|
38
39
|
interface InternalState {
|
|
39
40
|
positions: Map<string, number>;
|
|
41
|
+
columns: Map<string, number>;
|
|
40
42
|
sizes: Map<string, number>;
|
|
43
|
+
sizesLaidOut: Map<string, number> | undefined;
|
|
41
44
|
pendingAdjust: number;
|
|
42
45
|
animFrameLayout: any;
|
|
43
46
|
animFrameTotalSize: number | null;
|
|
@@ -61,6 +64,7 @@ interface InternalState {
|
|
|
61
64
|
scrollAdjustPending: number;
|
|
62
65
|
totalSize: number;
|
|
63
66
|
timeouts: Set<number>;
|
|
67
|
+
timeoutSizeMessage: any;
|
|
64
68
|
nativeMarginTop: number;
|
|
65
69
|
indexByKey: Map<string, number>;
|
|
66
70
|
contentSize: {
|
|
@@ -87,7 +91,7 @@ interface LegendListRenderItemProps<ItemT> {
|
|
|
87
91
|
useViewability: (configId: string, callback: ViewabilityCallback) => void;
|
|
88
92
|
useViewabilityAmount: (callback: ViewabilityAmountCallback) => void;
|
|
89
93
|
useRecyclingEffect: (effect: (info: LegendListRecyclingState<ItemT>) => void | (() => void)) => void;
|
|
90
|
-
useRecyclingState: <T>(updateState: (info: LegendListRecyclingState<ItemT>) => T) => [T, React.Dispatch<T>];
|
|
94
|
+
useRecyclingState: <T>(updateState: ((info: LegendListRecyclingState<ItemT>) => T) | T) => [T, React.Dispatch<T>];
|
|
91
95
|
}
|
|
92
96
|
type LegendListRef = {
|
|
93
97
|
/**
|
package/index.js
CHANGED
|
@@ -100,11 +100,11 @@ var LeanView = React7__namespace.forwardRef((props, ref) => {
|
|
|
100
100
|
LeanView.displayName = "RCTView";
|
|
101
101
|
|
|
102
102
|
// src/$View.tsx
|
|
103
|
-
function $View({ $key, $key2, $style, ...rest }) {
|
|
103
|
+
function $View({ $key, $key2, $key3, $key4, $style, ...rest }) {
|
|
104
104
|
use$($key);
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
105
|
+
$key2 && use$($key2);
|
|
106
|
+
$key3 && use$($key3);
|
|
107
|
+
$key4 && use$($key4);
|
|
108
108
|
const style = $style();
|
|
109
109
|
return /* @__PURE__ */ React7__namespace.createElement(LeanView, { style, ...rest });
|
|
110
110
|
}
|
|
@@ -128,17 +128,23 @@ var Container = ({
|
|
|
128
128
|
const ctx = useStateContext();
|
|
129
129
|
const createStyle = () => {
|
|
130
130
|
const position = peek$(ctx, `containerPosition${id}`);
|
|
131
|
+
const column = peek$(ctx, `containerColumn${id}`) || 0;
|
|
131
132
|
const visible = peek$(ctx, `containerDidLayout${id}`);
|
|
133
|
+
const numColumns = peek$(ctx, "numColumns");
|
|
134
|
+
const otherAxisPos = numColumns > 1 ? `${(column - 1) / numColumns * 100}%` : 0;
|
|
135
|
+
const otherAxisSize = numColumns > 1 ? `${1 / numColumns * 100}%` : void 0;
|
|
132
136
|
return horizontal ? {
|
|
133
137
|
flexDirection: "row",
|
|
134
138
|
position: "absolute",
|
|
135
|
-
top: visible ?
|
|
136
|
-
bottom: 0,
|
|
139
|
+
top: visible ? otherAxisPos : -1e7,
|
|
140
|
+
bottom: numColumns > 1 ? null : 0,
|
|
141
|
+
height: otherAxisSize,
|
|
137
142
|
left: position
|
|
138
143
|
} : {
|
|
139
144
|
position: "absolute",
|
|
140
|
-
left: visible ?
|
|
141
|
-
right: 0,
|
|
145
|
+
left: visible ? otherAxisPos : -1e7,
|
|
146
|
+
right: numColumns > 1 ? null : 0,
|
|
147
|
+
width: otherAxisSize,
|
|
142
148
|
top: position
|
|
143
149
|
};
|
|
144
150
|
};
|
|
@@ -147,6 +153,8 @@ var Container = ({
|
|
|
147
153
|
{
|
|
148
154
|
$key: `containerPosition${id}`,
|
|
149
155
|
$key2: `containerDidLayout${id}`,
|
|
156
|
+
$key3: `containerColumn${id}`,
|
|
157
|
+
$key4: "numColumns",
|
|
150
158
|
$style: createStyle,
|
|
151
159
|
onLayout: (event) => {
|
|
152
160
|
const key = peek$(ctx, `containerItemKey${id}`);
|
|
@@ -466,6 +474,7 @@ function maybeUpdateViewabilityCallback(ctx, configId, viewToken) {
|
|
|
466
474
|
var DEFAULT_DRAW_DISTANCE = 250;
|
|
467
475
|
var INITIAL_SCROLL_ADJUST = 1e4;
|
|
468
476
|
var POSITION_OUT_OF_VIEW = -1e7;
|
|
477
|
+
var DEFAULT_ITEM_SIZE = 100;
|
|
469
478
|
var LegendList = React7.forwardRef(function LegendList2(props, forwardedRef) {
|
|
470
479
|
return /* @__PURE__ */ React7__namespace.createElement(StateProvider, null, /* @__PURE__ */ React7__namespace.createElement(LegendListInner, { ...props, ref: forwardedRef }));
|
|
471
480
|
});
|
|
@@ -486,6 +495,8 @@ var LegendListInner = React7.forwardRef(function LegendListInner2(props, forward
|
|
|
486
495
|
alignItemsAtEnd = false,
|
|
487
496
|
maintainVisibleContentPosition = false,
|
|
488
497
|
onScroll: onScrollProp,
|
|
498
|
+
numColumns: numColumnsProp = 1,
|
|
499
|
+
style: styleProp,
|
|
489
500
|
keyExtractor,
|
|
490
501
|
renderItem,
|
|
491
502
|
estimatedItemSize,
|
|
@@ -495,7 +506,7 @@ var LegendListInner = React7.forwardRef(function LegendListInner2(props, forward
|
|
|
495
506
|
ListEmptyComponent,
|
|
496
507
|
...rest
|
|
497
508
|
} = props;
|
|
498
|
-
const {
|
|
509
|
+
const { contentContainerStyle } = props;
|
|
499
510
|
const ctx = useStateContext();
|
|
500
511
|
const internalRef = React7.useRef(null);
|
|
501
512
|
const refScroller = internalRef;
|
|
@@ -511,11 +522,12 @@ var LegendListInner = React7.forwardRef(function LegendListInner2(props, forward
|
|
|
511
522
|
return `${ret}`;
|
|
512
523
|
};
|
|
513
524
|
const getItemSize = (key, index, data2) => {
|
|
525
|
+
var _a2;
|
|
514
526
|
const sizeKnown = refState.current.sizes.get(key);
|
|
515
527
|
if (sizeKnown !== void 0) {
|
|
516
528
|
return sizeKnown;
|
|
517
529
|
}
|
|
518
|
-
const size = getEstimatedItemSize ? getEstimatedItemSize(index, data2) : estimatedItemSize;
|
|
530
|
+
const size = (_a2 = getEstimatedItemSize ? getEstimatedItemSize(index, data2) : estimatedItemSize) != null ? _a2 : DEFAULT_ITEM_SIZE;
|
|
519
531
|
refState.current.sizes.set(key, size);
|
|
520
532
|
return size;
|
|
521
533
|
};
|
|
@@ -538,6 +550,7 @@ var LegendListInner = React7.forwardRef(function LegendListInner2(props, forward
|
|
|
538
550
|
refState.current = {
|
|
539
551
|
sizes: /* @__PURE__ */ new Map(),
|
|
540
552
|
positions: /* @__PURE__ */ new Map(),
|
|
553
|
+
columns: /* @__PURE__ */ new Map(),
|
|
541
554
|
pendingAdjust: 0,
|
|
542
555
|
animFrameLayout: null,
|
|
543
556
|
animFrameTotalSize: null,
|
|
@@ -566,7 +579,9 @@ var LegendListInner = React7.forwardRef(function LegendListInner2(props, forward
|
|
|
566
579
|
indexByKey: /* @__PURE__ */ new Map(),
|
|
567
580
|
scrollHistory: [],
|
|
568
581
|
scrollVelocity: 0,
|
|
569
|
-
contentSize: { width: 0, height: 0 }
|
|
582
|
+
contentSize: { width: 0, height: 0 },
|
|
583
|
+
sizesLaidOut: __DEV__ ? /* @__PURE__ */ new Map() : void 0,
|
|
584
|
+
timeoutSizeMessage: 0
|
|
570
585
|
};
|
|
571
586
|
refState.current.idsInFirstRender = new Set(data.map((_, i) => getId(i)));
|
|
572
587
|
set$(ctx, "scrollAdjust", refState.current.scrollAdjustPending);
|
|
@@ -576,12 +591,12 @@ var LegendListInner = React7.forwardRef(function LegendListInner2(props, forward
|
|
|
576
591
|
refState.current.scrollAdjustPending -= diff;
|
|
577
592
|
}
|
|
578
593
|
};
|
|
579
|
-
const addTotalSize = React7.useCallback((key, add
|
|
594
|
+
const addTotalSize = React7.useCallback((key, add) => {
|
|
580
595
|
const state = refState.current;
|
|
581
596
|
const index = key === null ? 0 : state.indexByKey.get(key);
|
|
582
597
|
const isAbove = key !== null && index < (state.startNoBuffer || 0);
|
|
583
598
|
const prev = state.totalSize;
|
|
584
|
-
if (
|
|
599
|
+
if (key === null) {
|
|
585
600
|
state.totalSize = add;
|
|
586
601
|
} else {
|
|
587
602
|
state.totalSize += add;
|
|
@@ -597,7 +612,7 @@ var LegendListInner = React7.forwardRef(function LegendListInner2(props, forward
|
|
|
597
612
|
if (isAbove) {
|
|
598
613
|
adjustScroll(add);
|
|
599
614
|
}
|
|
600
|
-
if (!prev ||
|
|
615
|
+
if (!prev || key === null) {
|
|
601
616
|
doAdd();
|
|
602
617
|
} else if (!state.animFrameTotalSize) {
|
|
603
618
|
state.animFrameTotalSize = requestAnimationFrame(doAdd);
|
|
@@ -606,7 +621,15 @@ var LegendListInner = React7.forwardRef(function LegendListInner2(props, forward
|
|
|
606
621
|
const calculateItemsInView = React7.useCallback((speed = 0) => {
|
|
607
622
|
var _a2, _b2, _c2;
|
|
608
623
|
const state = refState.current;
|
|
609
|
-
const {
|
|
624
|
+
const {
|
|
625
|
+
data: data2,
|
|
626
|
+
scrollLength,
|
|
627
|
+
scroll: scrollState,
|
|
628
|
+
startBuffered: startBufferedState,
|
|
629
|
+
positions,
|
|
630
|
+
sizes,
|
|
631
|
+
columns
|
|
632
|
+
} = state;
|
|
610
633
|
if (state.animFrameLayout) {
|
|
611
634
|
cancelAnimationFrame(state.animFrameLayout);
|
|
612
635
|
state.animFrameLayout = null;
|
|
@@ -621,6 +644,7 @@ var LegendListInner = React7.forwardRef(function LegendListInner2(props, forward
|
|
|
621
644
|
0,
|
|
622
645
|
scrollState - topPad - (USE_CONTENT_INSET ? scrollAdjustPending : 0) + scrollExtra
|
|
623
646
|
);
|
|
647
|
+
const scrollBottom = scroll + scrollLength;
|
|
624
648
|
let startNoBuffer = null;
|
|
625
649
|
let startBuffered = null;
|
|
626
650
|
let endNoBuffer = null;
|
|
@@ -641,13 +665,24 @@ var LegendListInner = React7.forwardRef(function LegendListInner2(props, forward
|
|
|
641
665
|
}
|
|
642
666
|
}
|
|
643
667
|
}
|
|
668
|
+
const numColumns = peek$(ctx, "numColumns");
|
|
669
|
+
const loopStartMod = loopStart % numColumns;
|
|
670
|
+
if (loopStartMod > 0) {
|
|
671
|
+
loopStart -= loopStartMod;
|
|
672
|
+
}
|
|
644
673
|
let top = loopStart > 0 ? positions.get(getId(loopStart)) : 0;
|
|
674
|
+
let column = 1;
|
|
675
|
+
let maxSizeInRow = 0;
|
|
645
676
|
for (let i = loopStart; i < data2.length; i++) {
|
|
646
677
|
const id = getId(i);
|
|
647
678
|
const size = getItemSize(id, i, data2[i]);
|
|
679
|
+
maxSizeInRow = Math.max(maxSizeInRow, size);
|
|
648
680
|
if (positions.get(id) !== top) {
|
|
649
681
|
positions.set(id, top);
|
|
650
682
|
}
|
|
683
|
+
if (columns.get(id) !== column) {
|
|
684
|
+
columns.set(id, column);
|
|
685
|
+
}
|
|
651
686
|
if (startNoBuffer === null && top + size > scroll) {
|
|
652
687
|
startNoBuffer = i;
|
|
653
688
|
}
|
|
@@ -655,16 +690,21 @@ var LegendListInner = React7.forwardRef(function LegendListInner2(props, forward
|
|
|
655
690
|
startBuffered = i;
|
|
656
691
|
}
|
|
657
692
|
if (startNoBuffer !== null) {
|
|
658
|
-
if (top <=
|
|
693
|
+
if (top <= scrollBottom) {
|
|
659
694
|
endNoBuffer = i;
|
|
660
695
|
}
|
|
661
|
-
if (top <=
|
|
696
|
+
if (top <= scrollBottom + scrollBuffer) {
|
|
662
697
|
endBuffered = i;
|
|
663
698
|
} else {
|
|
664
699
|
break;
|
|
665
700
|
}
|
|
666
701
|
}
|
|
667
|
-
|
|
702
|
+
column++;
|
|
703
|
+
if (column > numColumns) {
|
|
704
|
+
top += maxSizeInRow;
|
|
705
|
+
column = 1;
|
|
706
|
+
maxSizeInRow = 0;
|
|
707
|
+
}
|
|
668
708
|
}
|
|
669
709
|
Object.assign(refState.current, {
|
|
670
710
|
startBuffered,
|
|
@@ -712,6 +752,7 @@ var LegendListInner = React7.forwardRef(function LegendListInner2(props, forward
|
|
|
712
752
|
numContainers++;
|
|
713
753
|
set$(ctx, `containerItemKey${containerId}`, id);
|
|
714
754
|
set$(ctx, `containerPosition${containerId}`, POSITION_OUT_OF_VIEW);
|
|
755
|
+
set$(ctx, `containerColumn${containerId}`, -1);
|
|
715
756
|
if (__DEV__ && numContainers > peek$(ctx, "numContainersPooled")) {
|
|
716
757
|
console.warn(
|
|
717
758
|
"[legend-list] No container to recycle, consider increasing initialContainers or estimatedItemSize. numContainers:",
|
|
@@ -733,12 +774,24 @@ var LegendListInner = React7.forwardRef(function LegendListInner2(props, forward
|
|
|
733
774
|
const item = data2[itemIndex];
|
|
734
775
|
if (item) {
|
|
735
776
|
const id = getId(itemIndex);
|
|
736
|
-
if (
|
|
777
|
+
if (itemKey !== id || itemIndex < startBuffered || itemIndex > endBuffered) {
|
|
778
|
+
const prevPos = peek$(ctx, `containerPosition${i}`) - scrollAdjustPending;
|
|
779
|
+
const pos = positions.get(id) || 0;
|
|
780
|
+
const size = sizes.get(id) || 0;
|
|
781
|
+
if (pos + size >= scroll && pos <= scrollBottom || prevPos + size >= scroll && prevPos <= scrollBottom) {
|
|
782
|
+
set$(ctx, `containerPosition${i}`, POSITION_OUT_OF_VIEW);
|
|
783
|
+
}
|
|
784
|
+
} else {
|
|
737
785
|
const pos = (positions.get(id) || 0) + scrollAdjustPending;
|
|
786
|
+
const column2 = columns.get(id) || 1;
|
|
738
787
|
const prevPos = peek$(ctx, `containerPosition${i}`);
|
|
788
|
+
const prevColumn = peek$(ctx, `containerColumn${i}`);
|
|
739
789
|
if (pos >= 0 && pos !== prevPos) {
|
|
740
790
|
set$(ctx, `containerPosition${i}`, pos);
|
|
741
791
|
}
|
|
792
|
+
if (column2 >= 0 && column2 !== prevColumn) {
|
|
793
|
+
set$(ctx, `containerColumn${i}`, column2);
|
|
794
|
+
}
|
|
742
795
|
}
|
|
743
796
|
}
|
|
744
797
|
}
|
|
@@ -755,6 +808,18 @@ var LegendListInner = React7.forwardRef(function LegendListInner2(props, forward
|
|
|
755
808
|
);
|
|
756
809
|
}
|
|
757
810
|
}, []);
|
|
811
|
+
const style = React7.useMemo(() => {
|
|
812
|
+
const extraStyle = {};
|
|
813
|
+
if (data.length > 0) {
|
|
814
|
+
const size = getItemSize(getId(0), 0, data[0]);
|
|
815
|
+
if (horizontal) {
|
|
816
|
+
extraStyle.minHeight = size;
|
|
817
|
+
} else {
|
|
818
|
+
extraStyle.minWidth = size;
|
|
819
|
+
}
|
|
820
|
+
}
|
|
821
|
+
return reactNative.StyleSheet.compose(styleProp, extraStyle);
|
|
822
|
+
}, []);
|
|
758
823
|
const doUpdatePaddingTop = () => {
|
|
759
824
|
if (alignItemsAtEnd) {
|
|
760
825
|
const { scrollLength, totalSize } = refState.current;
|
|
@@ -819,20 +884,33 @@ var LegendListInner = React7.forwardRef(function LegendListInner2(props, forward
|
|
|
819
884
|
}
|
|
820
885
|
};
|
|
821
886
|
const isFirst = !refState.current.renderItem;
|
|
822
|
-
if (isFirst || data !== refState.current.data) {
|
|
887
|
+
if (isFirst || data !== refState.current.data || numColumnsProp !== peek$(ctx, "numColumns")) {
|
|
888
|
+
if (!keyExtractor && !isFirst && data !== refState.current.data) {
|
|
889
|
+
refState.current.sizes.clear();
|
|
890
|
+
refState.current.positions.clear();
|
|
891
|
+
}
|
|
823
892
|
refState.current.data = data;
|
|
824
893
|
let totalSize = 0;
|
|
825
894
|
const indexByKey = /* @__PURE__ */ new Map();
|
|
895
|
+
let column = 1;
|
|
896
|
+
let maxSizeInRow = 0;
|
|
826
897
|
for (let i = 0; i < data.length; i++) {
|
|
827
898
|
const key = getId(i);
|
|
828
899
|
indexByKey.set(key, i);
|
|
829
|
-
|
|
900
|
+
const size = getItemSize(key, i, data[i]);
|
|
901
|
+
maxSizeInRow = Math.max(maxSizeInRow, size);
|
|
830
902
|
if (maintainVisibleContentPosition && i < refState.current.startNoBuffer && !refState.current.indexByKey.has(key)) {
|
|
831
|
-
const
|
|
832
|
-
adjustScroll(
|
|
903
|
+
const size2 = getItemSize(key, i, data[i]);
|
|
904
|
+
adjustScroll(size2);
|
|
905
|
+
}
|
|
906
|
+
column++;
|
|
907
|
+
if (column > numColumnsProp) {
|
|
908
|
+
totalSize += maxSizeInRow;
|
|
909
|
+
column = 1;
|
|
910
|
+
maxSizeInRow = 0;
|
|
833
911
|
}
|
|
834
912
|
}
|
|
835
|
-
addTotalSize(null, totalSize
|
|
913
|
+
addTotalSize(null, totalSize);
|
|
836
914
|
if (maintainVisibleContentPosition) {
|
|
837
915
|
for (const [key, index] of refState.current.indexByKey) {
|
|
838
916
|
if (index < refState.current.startNoBuffer && !indexByKey.has(key)) {
|
|
@@ -850,6 +928,11 @@ var LegendListInner = React7.forwardRef(function LegendListInner2(props, forward
|
|
|
850
928
|
for (let i = 0; i < numContainers; i++) {
|
|
851
929
|
set$(ctx, `containerItemKey${i}`, void 0);
|
|
852
930
|
set$(ctx, `containerPosition${i}`, POSITION_OUT_OF_VIEW);
|
|
931
|
+
set$(ctx, `containerColumn${i}`, -1);
|
|
932
|
+
}
|
|
933
|
+
if (!keyExtractor) {
|
|
934
|
+
refState.current.sizes.clear();
|
|
935
|
+
refState.current.positions;
|
|
853
936
|
}
|
|
854
937
|
calculateItemsInView();
|
|
855
938
|
doMaintainScrollAtEnd(false);
|
|
@@ -859,6 +942,7 @@ var LegendListInner = React7.forwardRef(function LegendListInner2(props, forward
|
|
|
859
942
|
}
|
|
860
943
|
refState.current.renderItem = renderItem;
|
|
861
944
|
set$(ctx, "lastItemKey", getId(data[data.length - 1]));
|
|
945
|
+
set$(ctx, "numColumns", numColumnsProp);
|
|
862
946
|
set$(
|
|
863
947
|
ctx,
|
|
864
948
|
"stylePaddingTop",
|
|
@@ -934,17 +1018,17 @@ var LegendListInner = React7.forwardRef(function LegendListInner2(props, forward
|
|
|
934
1018
|
listen$(ctx, signal, run);
|
|
935
1019
|
}, []);
|
|
936
1020
|
};
|
|
937
|
-
const useRecyclingState = (
|
|
1021
|
+
const useRecyclingState = (valueOrFun) => {
|
|
938
1022
|
const stateInfo = React7.useState(
|
|
939
|
-
() =>
|
|
1023
|
+
() => typeof valueOrFun === "function" ? valueOrFun({
|
|
940
1024
|
index,
|
|
941
1025
|
item: refState.current.data[index],
|
|
942
1026
|
prevIndex: void 0,
|
|
943
1027
|
prevItem: void 0
|
|
944
|
-
})
|
|
1028
|
+
}) : valueOrFun
|
|
945
1029
|
);
|
|
946
1030
|
useRecyclingEffect((state2) => {
|
|
947
|
-
const newState =
|
|
1031
|
+
const newState = typeof valueOrFun === "function" ? valueOrFun(state2) : valueOrFun;
|
|
948
1032
|
stateInfo[1](newState);
|
|
949
1033
|
});
|
|
950
1034
|
return stateInfo;
|
|
@@ -960,12 +1044,14 @@ var LegendListInner = React7.forwardRef(function LegendListInner2(props, forward
|
|
|
960
1044
|
return renderedItem;
|
|
961
1045
|
}, []);
|
|
962
1046
|
useInit(() => {
|
|
1047
|
+
var _a2;
|
|
963
1048
|
refState.current.viewabilityConfigCallbackPairs = setupViewability(props);
|
|
964
1049
|
const scrollLength = refState.current.scrollLength;
|
|
965
|
-
const averageItemSize = estimatedItemSize != null ? estimatedItemSize : getEstimatedItemSize == null ? void 0 : getEstimatedItemSize(0, data[0]);
|
|
966
|
-
const numContainers = initialNumContainers || Math.ceil((scrollLength + scrollBuffer * 2) / averageItemSize);
|
|
1050
|
+
const averageItemSize = (_a2 = estimatedItemSize != null ? estimatedItemSize : getEstimatedItemSize == null ? void 0 : getEstimatedItemSize(0, data[0])) != null ? _a2 : DEFAULT_ITEM_SIZE;
|
|
1051
|
+
const numContainers = (initialNumContainers || Math.ceil((scrollLength + scrollBuffer * 2) / averageItemSize)) * numColumnsProp;
|
|
967
1052
|
for (let i = 0; i < numContainers; i++) {
|
|
968
1053
|
set$(ctx, `containerPosition${i}`, POSITION_OUT_OF_VIEW);
|
|
1054
|
+
set$(ctx, `containerColumn${i}`, -1);
|
|
969
1055
|
}
|
|
970
1056
|
set$(ctx, "numContainers", numContainers);
|
|
971
1057
|
set$(ctx, "numContainersPooled", numContainers * 2);
|
|
@@ -977,15 +1063,56 @@ var LegendListInner = React7.forwardRef(function LegendListInner2(props, forward
|
|
|
977
1063
|
if (!data2) {
|
|
978
1064
|
return;
|
|
979
1065
|
}
|
|
980
|
-
const
|
|
1066
|
+
const state = refState.current;
|
|
1067
|
+
const { sizes, indexByKey, idsInFirstRender, columns, sizesLaidOut } = state;
|
|
981
1068
|
const index = indexByKey.get(key);
|
|
982
1069
|
const wasInFirstRender = idsInFirstRender.has(key);
|
|
983
1070
|
const prevSize = sizes.get(key) || (wasInFirstRender ? getItemSize(key, index, data2[index]) : 0);
|
|
984
1071
|
if (!prevSize || Math.abs(prevSize - size) > 0.5) {
|
|
985
|
-
|
|
986
|
-
|
|
1072
|
+
let diff;
|
|
1073
|
+
const numColumns = peek$(ctx, "numColumns");
|
|
1074
|
+
if (numColumns > 1) {
|
|
1075
|
+
const column = columns.get(key);
|
|
1076
|
+
const loopStart = index - (column - 1);
|
|
1077
|
+
let prevMaxSizeInRow = 0;
|
|
1078
|
+
for (let i = loopStart; i < loopStart + numColumns; i++) {
|
|
1079
|
+
const id = getId(i);
|
|
1080
|
+
const size2 = getItemSize(id, i, data2[i]);
|
|
1081
|
+
prevMaxSizeInRow = Math.max(prevMaxSizeInRow, size2);
|
|
1082
|
+
}
|
|
1083
|
+
sizes.set(key, size);
|
|
1084
|
+
let nextMaxSizeInRow = 0;
|
|
1085
|
+
for (let i = loopStart; i < loopStart + numColumns; i++) {
|
|
1086
|
+
const id = getId(i);
|
|
1087
|
+
const size2 = getItemSize(id, i, data2[i]);
|
|
1088
|
+
nextMaxSizeInRow = Math.max(nextMaxSizeInRow, size2);
|
|
1089
|
+
}
|
|
1090
|
+
diff = nextMaxSizeInRow - prevMaxSizeInRow;
|
|
1091
|
+
} else {
|
|
1092
|
+
sizes.set(key, size);
|
|
1093
|
+
diff = size - prevSize;
|
|
1094
|
+
}
|
|
1095
|
+
if (__DEV__ && !estimatedItemSize && !getEstimatedItemSize) {
|
|
1096
|
+
sizesLaidOut.set(key, size);
|
|
1097
|
+
if (state.timeoutSizeMessage) {
|
|
1098
|
+
clearTimeout(state.timeoutSizeMessage);
|
|
1099
|
+
}
|
|
1100
|
+
state.timeoutSizeMessage = setTimeout(() => {
|
|
1101
|
+
state.timeoutSizeMessage = void 0;
|
|
1102
|
+
let total = 0;
|
|
1103
|
+
let num = 0;
|
|
1104
|
+
for (const [key2, size2] of sizesLaidOut) {
|
|
1105
|
+
num++;
|
|
1106
|
+
total += size2;
|
|
1107
|
+
}
|
|
1108
|
+
const avg = Math.round(total / num);
|
|
1109
|
+
console.warn(
|
|
1110
|
+
`[legend-list] estimatedItemSize or getEstimatedItemSize are not defined. Based on the ${num} items rendered so far, the optimal estimated size is ${avg}.`
|
|
1111
|
+
);
|
|
1112
|
+
}, 1e3);
|
|
1113
|
+
}
|
|
1114
|
+
addTotalSize(key, diff);
|
|
987
1115
|
doMaintainScrollAtEnd(true);
|
|
988
|
-
const state = refState.current;
|
|
989
1116
|
const scrollVelocity = state.scrollVelocity;
|
|
990
1117
|
if (!state.animFrameLayout && (Number.isNaN(scrollVelocity) || Math.abs(scrollVelocity) < 1)) {
|
|
991
1118
|
state.animFrameLayout = requestAnimationFrame(() => {
|
|
@@ -1103,7 +1230,8 @@ var LegendListInner = React7.forwardRef(function LegendListInner2(props, forward
|
|
|
1103
1230
|
recycleItems,
|
|
1104
1231
|
alignItemsAtEnd,
|
|
1105
1232
|
addTotalSize,
|
|
1106
|
-
ListEmptyComponent: data.length === 0 ? ListEmptyComponent : void 0
|
|
1233
|
+
ListEmptyComponent: data.length === 0 ? ListEmptyComponent : void 0,
|
|
1234
|
+
style
|
|
1107
1235
|
}
|
|
1108
1236
|
);
|
|
1109
1237
|
});
|
package/index.mjs
CHANGED
|
@@ -79,11 +79,11 @@ var LeanView = React7.forwardRef((props, ref) => {
|
|
|
79
79
|
LeanView.displayName = "RCTView";
|
|
80
80
|
|
|
81
81
|
// src/$View.tsx
|
|
82
|
-
function $View({ $key, $key2, $style, ...rest }) {
|
|
82
|
+
function $View({ $key, $key2, $key3, $key4, $style, ...rest }) {
|
|
83
83
|
use$($key);
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
84
|
+
$key2 && use$($key2);
|
|
85
|
+
$key3 && use$($key3);
|
|
86
|
+
$key4 && use$($key4);
|
|
87
87
|
const style = $style();
|
|
88
88
|
return /* @__PURE__ */ React7.createElement(LeanView, { style, ...rest });
|
|
89
89
|
}
|
|
@@ -107,17 +107,23 @@ var Container = ({
|
|
|
107
107
|
const ctx = useStateContext();
|
|
108
108
|
const createStyle = () => {
|
|
109
109
|
const position = peek$(ctx, `containerPosition${id}`);
|
|
110
|
+
const column = peek$(ctx, `containerColumn${id}`) || 0;
|
|
110
111
|
const visible = peek$(ctx, `containerDidLayout${id}`);
|
|
112
|
+
const numColumns = peek$(ctx, "numColumns");
|
|
113
|
+
const otherAxisPos = numColumns > 1 ? `${(column - 1) / numColumns * 100}%` : 0;
|
|
114
|
+
const otherAxisSize = numColumns > 1 ? `${1 / numColumns * 100}%` : void 0;
|
|
111
115
|
return horizontal ? {
|
|
112
116
|
flexDirection: "row",
|
|
113
117
|
position: "absolute",
|
|
114
|
-
top: visible ?
|
|
115
|
-
bottom: 0,
|
|
118
|
+
top: visible ? otherAxisPos : -1e7,
|
|
119
|
+
bottom: numColumns > 1 ? null : 0,
|
|
120
|
+
height: otherAxisSize,
|
|
116
121
|
left: position
|
|
117
122
|
} : {
|
|
118
123
|
position: "absolute",
|
|
119
|
-
left: visible ?
|
|
120
|
-
right: 0,
|
|
124
|
+
left: visible ? otherAxisPos : -1e7,
|
|
125
|
+
right: numColumns > 1 ? null : 0,
|
|
126
|
+
width: otherAxisSize,
|
|
121
127
|
top: position
|
|
122
128
|
};
|
|
123
129
|
};
|
|
@@ -126,6 +132,8 @@ var Container = ({
|
|
|
126
132
|
{
|
|
127
133
|
$key: `containerPosition${id}`,
|
|
128
134
|
$key2: `containerDidLayout${id}`,
|
|
135
|
+
$key3: `containerColumn${id}`,
|
|
136
|
+
$key4: "numColumns",
|
|
129
137
|
$style: createStyle,
|
|
130
138
|
onLayout: (event) => {
|
|
131
139
|
const key = peek$(ctx, `containerItemKey${id}`);
|
|
@@ -445,6 +453,7 @@ function maybeUpdateViewabilityCallback(ctx, configId, viewToken) {
|
|
|
445
453
|
var DEFAULT_DRAW_DISTANCE = 250;
|
|
446
454
|
var INITIAL_SCROLL_ADJUST = 1e4;
|
|
447
455
|
var POSITION_OUT_OF_VIEW = -1e7;
|
|
456
|
+
var DEFAULT_ITEM_SIZE = 100;
|
|
448
457
|
var LegendList = forwardRef(function LegendList2(props, forwardedRef) {
|
|
449
458
|
return /* @__PURE__ */ React7.createElement(StateProvider, null, /* @__PURE__ */ React7.createElement(LegendListInner, { ...props, ref: forwardedRef }));
|
|
450
459
|
});
|
|
@@ -465,6 +474,8 @@ var LegendListInner = forwardRef(function LegendListInner2(props, forwardedRef)
|
|
|
465
474
|
alignItemsAtEnd = false,
|
|
466
475
|
maintainVisibleContentPosition = false,
|
|
467
476
|
onScroll: onScrollProp,
|
|
477
|
+
numColumns: numColumnsProp = 1,
|
|
478
|
+
style: styleProp,
|
|
468
479
|
keyExtractor,
|
|
469
480
|
renderItem,
|
|
470
481
|
estimatedItemSize,
|
|
@@ -474,7 +485,7 @@ var LegendListInner = forwardRef(function LegendListInner2(props, forwardedRef)
|
|
|
474
485
|
ListEmptyComponent,
|
|
475
486
|
...rest
|
|
476
487
|
} = props;
|
|
477
|
-
const {
|
|
488
|
+
const { contentContainerStyle } = props;
|
|
478
489
|
const ctx = useStateContext();
|
|
479
490
|
const internalRef = useRef(null);
|
|
480
491
|
const refScroller = internalRef;
|
|
@@ -490,11 +501,12 @@ var LegendListInner = forwardRef(function LegendListInner2(props, forwardedRef)
|
|
|
490
501
|
return `${ret}`;
|
|
491
502
|
};
|
|
492
503
|
const getItemSize = (key, index, data2) => {
|
|
504
|
+
var _a2;
|
|
493
505
|
const sizeKnown = refState.current.sizes.get(key);
|
|
494
506
|
if (sizeKnown !== void 0) {
|
|
495
507
|
return sizeKnown;
|
|
496
508
|
}
|
|
497
|
-
const size = getEstimatedItemSize ? getEstimatedItemSize(index, data2) : estimatedItemSize;
|
|
509
|
+
const size = (_a2 = getEstimatedItemSize ? getEstimatedItemSize(index, data2) : estimatedItemSize) != null ? _a2 : DEFAULT_ITEM_SIZE;
|
|
498
510
|
refState.current.sizes.set(key, size);
|
|
499
511
|
return size;
|
|
500
512
|
};
|
|
@@ -517,6 +529,7 @@ var LegendListInner = forwardRef(function LegendListInner2(props, forwardedRef)
|
|
|
517
529
|
refState.current = {
|
|
518
530
|
sizes: /* @__PURE__ */ new Map(),
|
|
519
531
|
positions: /* @__PURE__ */ new Map(),
|
|
532
|
+
columns: /* @__PURE__ */ new Map(),
|
|
520
533
|
pendingAdjust: 0,
|
|
521
534
|
animFrameLayout: null,
|
|
522
535
|
animFrameTotalSize: null,
|
|
@@ -545,7 +558,9 @@ var LegendListInner = forwardRef(function LegendListInner2(props, forwardedRef)
|
|
|
545
558
|
indexByKey: /* @__PURE__ */ new Map(),
|
|
546
559
|
scrollHistory: [],
|
|
547
560
|
scrollVelocity: 0,
|
|
548
|
-
contentSize: { width: 0, height: 0 }
|
|
561
|
+
contentSize: { width: 0, height: 0 },
|
|
562
|
+
sizesLaidOut: __DEV__ ? /* @__PURE__ */ new Map() : void 0,
|
|
563
|
+
timeoutSizeMessage: 0
|
|
549
564
|
};
|
|
550
565
|
refState.current.idsInFirstRender = new Set(data.map((_, i) => getId(i)));
|
|
551
566
|
set$(ctx, "scrollAdjust", refState.current.scrollAdjustPending);
|
|
@@ -555,12 +570,12 @@ var LegendListInner = forwardRef(function LegendListInner2(props, forwardedRef)
|
|
|
555
570
|
refState.current.scrollAdjustPending -= diff;
|
|
556
571
|
}
|
|
557
572
|
};
|
|
558
|
-
const addTotalSize = useCallback((key, add
|
|
573
|
+
const addTotalSize = useCallback((key, add) => {
|
|
559
574
|
const state = refState.current;
|
|
560
575
|
const index = key === null ? 0 : state.indexByKey.get(key);
|
|
561
576
|
const isAbove = key !== null && index < (state.startNoBuffer || 0);
|
|
562
577
|
const prev = state.totalSize;
|
|
563
|
-
if (
|
|
578
|
+
if (key === null) {
|
|
564
579
|
state.totalSize = add;
|
|
565
580
|
} else {
|
|
566
581
|
state.totalSize += add;
|
|
@@ -576,7 +591,7 @@ var LegendListInner = forwardRef(function LegendListInner2(props, forwardedRef)
|
|
|
576
591
|
if (isAbove) {
|
|
577
592
|
adjustScroll(add);
|
|
578
593
|
}
|
|
579
|
-
if (!prev ||
|
|
594
|
+
if (!prev || key === null) {
|
|
580
595
|
doAdd();
|
|
581
596
|
} else if (!state.animFrameTotalSize) {
|
|
582
597
|
state.animFrameTotalSize = requestAnimationFrame(doAdd);
|
|
@@ -585,7 +600,15 @@ var LegendListInner = forwardRef(function LegendListInner2(props, forwardedRef)
|
|
|
585
600
|
const calculateItemsInView = useCallback((speed = 0) => {
|
|
586
601
|
var _a2, _b2, _c2;
|
|
587
602
|
const state = refState.current;
|
|
588
|
-
const {
|
|
603
|
+
const {
|
|
604
|
+
data: data2,
|
|
605
|
+
scrollLength,
|
|
606
|
+
scroll: scrollState,
|
|
607
|
+
startBuffered: startBufferedState,
|
|
608
|
+
positions,
|
|
609
|
+
sizes,
|
|
610
|
+
columns
|
|
611
|
+
} = state;
|
|
589
612
|
if (state.animFrameLayout) {
|
|
590
613
|
cancelAnimationFrame(state.animFrameLayout);
|
|
591
614
|
state.animFrameLayout = null;
|
|
@@ -600,6 +623,7 @@ var LegendListInner = forwardRef(function LegendListInner2(props, forwardedRef)
|
|
|
600
623
|
0,
|
|
601
624
|
scrollState - topPad - (USE_CONTENT_INSET ? scrollAdjustPending : 0) + scrollExtra
|
|
602
625
|
);
|
|
626
|
+
const scrollBottom = scroll + scrollLength;
|
|
603
627
|
let startNoBuffer = null;
|
|
604
628
|
let startBuffered = null;
|
|
605
629
|
let endNoBuffer = null;
|
|
@@ -620,13 +644,24 @@ var LegendListInner = forwardRef(function LegendListInner2(props, forwardedRef)
|
|
|
620
644
|
}
|
|
621
645
|
}
|
|
622
646
|
}
|
|
647
|
+
const numColumns = peek$(ctx, "numColumns");
|
|
648
|
+
const loopStartMod = loopStart % numColumns;
|
|
649
|
+
if (loopStartMod > 0) {
|
|
650
|
+
loopStart -= loopStartMod;
|
|
651
|
+
}
|
|
623
652
|
let top = loopStart > 0 ? positions.get(getId(loopStart)) : 0;
|
|
653
|
+
let column = 1;
|
|
654
|
+
let maxSizeInRow = 0;
|
|
624
655
|
for (let i = loopStart; i < data2.length; i++) {
|
|
625
656
|
const id = getId(i);
|
|
626
657
|
const size = getItemSize(id, i, data2[i]);
|
|
658
|
+
maxSizeInRow = Math.max(maxSizeInRow, size);
|
|
627
659
|
if (positions.get(id) !== top) {
|
|
628
660
|
positions.set(id, top);
|
|
629
661
|
}
|
|
662
|
+
if (columns.get(id) !== column) {
|
|
663
|
+
columns.set(id, column);
|
|
664
|
+
}
|
|
630
665
|
if (startNoBuffer === null && top + size > scroll) {
|
|
631
666
|
startNoBuffer = i;
|
|
632
667
|
}
|
|
@@ -634,16 +669,21 @@ var LegendListInner = forwardRef(function LegendListInner2(props, forwardedRef)
|
|
|
634
669
|
startBuffered = i;
|
|
635
670
|
}
|
|
636
671
|
if (startNoBuffer !== null) {
|
|
637
|
-
if (top <=
|
|
672
|
+
if (top <= scrollBottom) {
|
|
638
673
|
endNoBuffer = i;
|
|
639
674
|
}
|
|
640
|
-
if (top <=
|
|
675
|
+
if (top <= scrollBottom + scrollBuffer) {
|
|
641
676
|
endBuffered = i;
|
|
642
677
|
} else {
|
|
643
678
|
break;
|
|
644
679
|
}
|
|
645
680
|
}
|
|
646
|
-
|
|
681
|
+
column++;
|
|
682
|
+
if (column > numColumns) {
|
|
683
|
+
top += maxSizeInRow;
|
|
684
|
+
column = 1;
|
|
685
|
+
maxSizeInRow = 0;
|
|
686
|
+
}
|
|
647
687
|
}
|
|
648
688
|
Object.assign(refState.current, {
|
|
649
689
|
startBuffered,
|
|
@@ -691,6 +731,7 @@ var LegendListInner = forwardRef(function LegendListInner2(props, forwardedRef)
|
|
|
691
731
|
numContainers++;
|
|
692
732
|
set$(ctx, `containerItemKey${containerId}`, id);
|
|
693
733
|
set$(ctx, `containerPosition${containerId}`, POSITION_OUT_OF_VIEW);
|
|
734
|
+
set$(ctx, `containerColumn${containerId}`, -1);
|
|
694
735
|
if (__DEV__ && numContainers > peek$(ctx, "numContainersPooled")) {
|
|
695
736
|
console.warn(
|
|
696
737
|
"[legend-list] No container to recycle, consider increasing initialContainers or estimatedItemSize. numContainers:",
|
|
@@ -712,12 +753,24 @@ var LegendListInner = forwardRef(function LegendListInner2(props, forwardedRef)
|
|
|
712
753
|
const item = data2[itemIndex];
|
|
713
754
|
if (item) {
|
|
714
755
|
const id = getId(itemIndex);
|
|
715
|
-
if (
|
|
756
|
+
if (itemKey !== id || itemIndex < startBuffered || itemIndex > endBuffered) {
|
|
757
|
+
const prevPos = peek$(ctx, `containerPosition${i}`) - scrollAdjustPending;
|
|
758
|
+
const pos = positions.get(id) || 0;
|
|
759
|
+
const size = sizes.get(id) || 0;
|
|
760
|
+
if (pos + size >= scroll && pos <= scrollBottom || prevPos + size >= scroll && prevPos <= scrollBottom) {
|
|
761
|
+
set$(ctx, `containerPosition${i}`, POSITION_OUT_OF_VIEW);
|
|
762
|
+
}
|
|
763
|
+
} else {
|
|
716
764
|
const pos = (positions.get(id) || 0) + scrollAdjustPending;
|
|
765
|
+
const column2 = columns.get(id) || 1;
|
|
717
766
|
const prevPos = peek$(ctx, `containerPosition${i}`);
|
|
767
|
+
const prevColumn = peek$(ctx, `containerColumn${i}`);
|
|
718
768
|
if (pos >= 0 && pos !== prevPos) {
|
|
719
769
|
set$(ctx, `containerPosition${i}`, pos);
|
|
720
770
|
}
|
|
771
|
+
if (column2 >= 0 && column2 !== prevColumn) {
|
|
772
|
+
set$(ctx, `containerColumn${i}`, column2);
|
|
773
|
+
}
|
|
721
774
|
}
|
|
722
775
|
}
|
|
723
776
|
}
|
|
@@ -734,6 +787,18 @@ var LegendListInner = forwardRef(function LegendListInner2(props, forwardedRef)
|
|
|
734
787
|
);
|
|
735
788
|
}
|
|
736
789
|
}, []);
|
|
790
|
+
const style = useMemo(() => {
|
|
791
|
+
const extraStyle = {};
|
|
792
|
+
if (data.length > 0) {
|
|
793
|
+
const size = getItemSize(getId(0), 0, data[0]);
|
|
794
|
+
if (horizontal) {
|
|
795
|
+
extraStyle.minHeight = size;
|
|
796
|
+
} else {
|
|
797
|
+
extraStyle.minWidth = size;
|
|
798
|
+
}
|
|
799
|
+
}
|
|
800
|
+
return StyleSheet.compose(styleProp, extraStyle);
|
|
801
|
+
}, []);
|
|
737
802
|
const doUpdatePaddingTop = () => {
|
|
738
803
|
if (alignItemsAtEnd) {
|
|
739
804
|
const { scrollLength, totalSize } = refState.current;
|
|
@@ -798,20 +863,33 @@ var LegendListInner = forwardRef(function LegendListInner2(props, forwardedRef)
|
|
|
798
863
|
}
|
|
799
864
|
};
|
|
800
865
|
const isFirst = !refState.current.renderItem;
|
|
801
|
-
if (isFirst || data !== refState.current.data) {
|
|
866
|
+
if (isFirst || data !== refState.current.data || numColumnsProp !== peek$(ctx, "numColumns")) {
|
|
867
|
+
if (!keyExtractor && !isFirst && data !== refState.current.data) {
|
|
868
|
+
refState.current.sizes.clear();
|
|
869
|
+
refState.current.positions.clear();
|
|
870
|
+
}
|
|
802
871
|
refState.current.data = data;
|
|
803
872
|
let totalSize = 0;
|
|
804
873
|
const indexByKey = /* @__PURE__ */ new Map();
|
|
874
|
+
let column = 1;
|
|
875
|
+
let maxSizeInRow = 0;
|
|
805
876
|
for (let i = 0; i < data.length; i++) {
|
|
806
877
|
const key = getId(i);
|
|
807
878
|
indexByKey.set(key, i);
|
|
808
|
-
|
|
879
|
+
const size = getItemSize(key, i, data[i]);
|
|
880
|
+
maxSizeInRow = Math.max(maxSizeInRow, size);
|
|
809
881
|
if (maintainVisibleContentPosition && i < refState.current.startNoBuffer && !refState.current.indexByKey.has(key)) {
|
|
810
|
-
const
|
|
811
|
-
adjustScroll(
|
|
882
|
+
const size2 = getItemSize(key, i, data[i]);
|
|
883
|
+
adjustScroll(size2);
|
|
884
|
+
}
|
|
885
|
+
column++;
|
|
886
|
+
if (column > numColumnsProp) {
|
|
887
|
+
totalSize += maxSizeInRow;
|
|
888
|
+
column = 1;
|
|
889
|
+
maxSizeInRow = 0;
|
|
812
890
|
}
|
|
813
891
|
}
|
|
814
|
-
addTotalSize(null, totalSize
|
|
892
|
+
addTotalSize(null, totalSize);
|
|
815
893
|
if (maintainVisibleContentPosition) {
|
|
816
894
|
for (const [key, index] of refState.current.indexByKey) {
|
|
817
895
|
if (index < refState.current.startNoBuffer && !indexByKey.has(key)) {
|
|
@@ -829,6 +907,11 @@ var LegendListInner = forwardRef(function LegendListInner2(props, forwardedRef)
|
|
|
829
907
|
for (let i = 0; i < numContainers; i++) {
|
|
830
908
|
set$(ctx, `containerItemKey${i}`, void 0);
|
|
831
909
|
set$(ctx, `containerPosition${i}`, POSITION_OUT_OF_VIEW);
|
|
910
|
+
set$(ctx, `containerColumn${i}`, -1);
|
|
911
|
+
}
|
|
912
|
+
if (!keyExtractor) {
|
|
913
|
+
refState.current.sizes.clear();
|
|
914
|
+
refState.current.positions;
|
|
832
915
|
}
|
|
833
916
|
calculateItemsInView();
|
|
834
917
|
doMaintainScrollAtEnd(false);
|
|
@@ -838,6 +921,7 @@ var LegendListInner = forwardRef(function LegendListInner2(props, forwardedRef)
|
|
|
838
921
|
}
|
|
839
922
|
refState.current.renderItem = renderItem;
|
|
840
923
|
set$(ctx, "lastItemKey", getId(data[data.length - 1]));
|
|
924
|
+
set$(ctx, "numColumns", numColumnsProp);
|
|
841
925
|
set$(
|
|
842
926
|
ctx,
|
|
843
927
|
"stylePaddingTop",
|
|
@@ -913,17 +997,17 @@ var LegendListInner = forwardRef(function LegendListInner2(props, forwardedRef)
|
|
|
913
997
|
listen$(ctx, signal, run);
|
|
914
998
|
}, []);
|
|
915
999
|
};
|
|
916
|
-
const useRecyclingState = (
|
|
1000
|
+
const useRecyclingState = (valueOrFun) => {
|
|
917
1001
|
const stateInfo = useState(
|
|
918
|
-
() =>
|
|
1002
|
+
() => typeof valueOrFun === "function" ? valueOrFun({
|
|
919
1003
|
index,
|
|
920
1004
|
item: refState.current.data[index],
|
|
921
1005
|
prevIndex: void 0,
|
|
922
1006
|
prevItem: void 0
|
|
923
|
-
})
|
|
1007
|
+
}) : valueOrFun
|
|
924
1008
|
);
|
|
925
1009
|
useRecyclingEffect((state2) => {
|
|
926
|
-
const newState =
|
|
1010
|
+
const newState = typeof valueOrFun === "function" ? valueOrFun(state2) : valueOrFun;
|
|
927
1011
|
stateInfo[1](newState);
|
|
928
1012
|
});
|
|
929
1013
|
return stateInfo;
|
|
@@ -939,12 +1023,14 @@ var LegendListInner = forwardRef(function LegendListInner2(props, forwardedRef)
|
|
|
939
1023
|
return renderedItem;
|
|
940
1024
|
}, []);
|
|
941
1025
|
useInit(() => {
|
|
1026
|
+
var _a2;
|
|
942
1027
|
refState.current.viewabilityConfigCallbackPairs = setupViewability(props);
|
|
943
1028
|
const scrollLength = refState.current.scrollLength;
|
|
944
|
-
const averageItemSize = estimatedItemSize != null ? estimatedItemSize : getEstimatedItemSize == null ? void 0 : getEstimatedItemSize(0, data[0]);
|
|
945
|
-
const numContainers = initialNumContainers || Math.ceil((scrollLength + scrollBuffer * 2) / averageItemSize);
|
|
1029
|
+
const averageItemSize = (_a2 = estimatedItemSize != null ? estimatedItemSize : getEstimatedItemSize == null ? void 0 : getEstimatedItemSize(0, data[0])) != null ? _a2 : DEFAULT_ITEM_SIZE;
|
|
1030
|
+
const numContainers = (initialNumContainers || Math.ceil((scrollLength + scrollBuffer * 2) / averageItemSize)) * numColumnsProp;
|
|
946
1031
|
for (let i = 0; i < numContainers; i++) {
|
|
947
1032
|
set$(ctx, `containerPosition${i}`, POSITION_OUT_OF_VIEW);
|
|
1033
|
+
set$(ctx, `containerColumn${i}`, -1);
|
|
948
1034
|
}
|
|
949
1035
|
set$(ctx, "numContainers", numContainers);
|
|
950
1036
|
set$(ctx, "numContainersPooled", numContainers * 2);
|
|
@@ -956,15 +1042,56 @@ var LegendListInner = forwardRef(function LegendListInner2(props, forwardedRef)
|
|
|
956
1042
|
if (!data2) {
|
|
957
1043
|
return;
|
|
958
1044
|
}
|
|
959
|
-
const
|
|
1045
|
+
const state = refState.current;
|
|
1046
|
+
const { sizes, indexByKey, idsInFirstRender, columns, sizesLaidOut } = state;
|
|
960
1047
|
const index = indexByKey.get(key);
|
|
961
1048
|
const wasInFirstRender = idsInFirstRender.has(key);
|
|
962
1049
|
const prevSize = sizes.get(key) || (wasInFirstRender ? getItemSize(key, index, data2[index]) : 0);
|
|
963
1050
|
if (!prevSize || Math.abs(prevSize - size) > 0.5) {
|
|
964
|
-
|
|
965
|
-
|
|
1051
|
+
let diff;
|
|
1052
|
+
const numColumns = peek$(ctx, "numColumns");
|
|
1053
|
+
if (numColumns > 1) {
|
|
1054
|
+
const column = columns.get(key);
|
|
1055
|
+
const loopStart = index - (column - 1);
|
|
1056
|
+
let prevMaxSizeInRow = 0;
|
|
1057
|
+
for (let i = loopStart; i < loopStart + numColumns; i++) {
|
|
1058
|
+
const id = getId(i);
|
|
1059
|
+
const size2 = getItemSize(id, i, data2[i]);
|
|
1060
|
+
prevMaxSizeInRow = Math.max(prevMaxSizeInRow, size2);
|
|
1061
|
+
}
|
|
1062
|
+
sizes.set(key, size);
|
|
1063
|
+
let nextMaxSizeInRow = 0;
|
|
1064
|
+
for (let i = loopStart; i < loopStart + numColumns; i++) {
|
|
1065
|
+
const id = getId(i);
|
|
1066
|
+
const size2 = getItemSize(id, i, data2[i]);
|
|
1067
|
+
nextMaxSizeInRow = Math.max(nextMaxSizeInRow, size2);
|
|
1068
|
+
}
|
|
1069
|
+
diff = nextMaxSizeInRow - prevMaxSizeInRow;
|
|
1070
|
+
} else {
|
|
1071
|
+
sizes.set(key, size);
|
|
1072
|
+
diff = size - prevSize;
|
|
1073
|
+
}
|
|
1074
|
+
if (__DEV__ && !estimatedItemSize && !getEstimatedItemSize) {
|
|
1075
|
+
sizesLaidOut.set(key, size);
|
|
1076
|
+
if (state.timeoutSizeMessage) {
|
|
1077
|
+
clearTimeout(state.timeoutSizeMessage);
|
|
1078
|
+
}
|
|
1079
|
+
state.timeoutSizeMessage = setTimeout(() => {
|
|
1080
|
+
state.timeoutSizeMessage = void 0;
|
|
1081
|
+
let total = 0;
|
|
1082
|
+
let num = 0;
|
|
1083
|
+
for (const [key2, size2] of sizesLaidOut) {
|
|
1084
|
+
num++;
|
|
1085
|
+
total += size2;
|
|
1086
|
+
}
|
|
1087
|
+
const avg = Math.round(total / num);
|
|
1088
|
+
console.warn(
|
|
1089
|
+
`[legend-list] estimatedItemSize or getEstimatedItemSize are not defined. Based on the ${num} items rendered so far, the optimal estimated size is ${avg}.`
|
|
1090
|
+
);
|
|
1091
|
+
}, 1e3);
|
|
1092
|
+
}
|
|
1093
|
+
addTotalSize(key, diff);
|
|
966
1094
|
doMaintainScrollAtEnd(true);
|
|
967
|
-
const state = refState.current;
|
|
968
1095
|
const scrollVelocity = state.scrollVelocity;
|
|
969
1096
|
if (!state.animFrameLayout && (Number.isNaN(scrollVelocity) || Math.abs(scrollVelocity) < 1)) {
|
|
970
1097
|
state.animFrameLayout = requestAnimationFrame(() => {
|
|
@@ -1082,7 +1209,8 @@ var LegendListInner = forwardRef(function LegendListInner2(props, forwardedRef)
|
|
|
1082
1209
|
recycleItems,
|
|
1083
1210
|
alignItemsAtEnd,
|
|
1084
1211
|
addTotalSize,
|
|
1085
|
-
ListEmptyComponent: data.length === 0 ? ListEmptyComponent : void 0
|
|
1212
|
+
ListEmptyComponent: data.length === 0 ? ListEmptyComponent : void 0,
|
|
1213
|
+
style
|
|
1086
1214
|
}
|
|
1087
1215
|
);
|
|
1088
1216
|
});
|