@legendapp/list 3.0.5 → 3.0.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/CHANGELOG.md +4 -0
- package/animated.d.ts +2 -1
- package/keyboard-legacy.d.ts +2 -1
- package/keyboard.d.ts +2 -1
- package/package.json +1 -1
- package/react-native.d.ts +2 -1
- package/react-native.js +100 -21
- package/react-native.mjs +100 -21
- package/react-native.web.d.ts +2 -1
- package/react-native.web.js +81 -18
- package/react-native.web.mjs +81 -18
- package/react.d.ts +2 -1
- package/react.js +81 -18
- package/react.mjs +81 -18
- package/reanimated.d.ts +2 -1
- package/section-list.d.ts +2 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
## 3.0.6
|
|
2
|
+
|
|
3
|
+
- Fix: KeyboardAwareLegendList now accounts for bottom insets when alignItemsAtEnd is used, so short chat-style lists stay pinned above the keyboard or safe area instead of being pushed too low or leaving extra scroll space.
|
|
4
|
+
|
|
1
5
|
## 3.0.5
|
|
2
6
|
|
|
3
7
|
- Fix: clearCaches now rechecks the rows that are already on screen, so resetting the size cache does not leave items stuck in old positions.
|
package/animated.d.ts
CHANGED
|
@@ -8,10 +8,11 @@ interface MaintainVisibleContentPositionNormalized<ItemT = any> {
|
|
|
8
8
|
shouldRestorePosition?: (item: ItemT, index: number, data: readonly ItemT[]) => boolean;
|
|
9
9
|
}
|
|
10
10
|
|
|
11
|
-
type ListenerType = "activeStickyIndex" | "anchoredEndSpaceSize" | "debugComputedScroll" | "debugRawScroll" | "extraData" | "footerSize" | "headerSize" | "lastItemKeys" | "lastPositionUpdate" | "maintainVisibleContentPosition" | "numColumns" | "numContainers" | "numContainersPooled" | "otherAxisSize" | "readyToRender" | "scrollAdjust" | "scrollAdjustPending" | "scrollAdjustUserOffset" | "scrollSize" | "snapToOffsets" | "stylePaddingTop" | "totalSize" | "isAtEnd" | "isAtStart" | "isNearEnd" | "isNearStart" | "isWithinMaintainScrollAtEndThreshold" | `containerColumn${number}` | `containerSpan${number}` | `containerItemData${number}` | `containerItemKey${number}` | `containerPosition${number}` | `containerSticky${number}`;
|
|
11
|
+
type ListenerType = "activeStickyIndex" | "alignItemsAtEndPadding" | "anchoredEndSpaceSize" | "debugComputedScroll" | "debugRawScroll" | "extraData" | "footerSize" | "headerSize" | "lastItemKeys" | "lastPositionUpdate" | "maintainVisibleContentPosition" | "numColumns" | "numContainers" | "numContainersPooled" | "otherAxisSize" | "readyToRender" | "scrollAdjust" | "scrollAdjustPending" | "scrollAdjustUserOffset" | "scrollSize" | "snapToOffsets" | "stylePaddingTop" | "totalSize" | "isAtEnd" | "isAtStart" | "isNearEnd" | "isNearStart" | "isWithinMaintainScrollAtEndThreshold" | `containerColumn${number}` | `containerSpan${number}` | `containerItemData${number}` | `containerItemKey${number}` | `containerPosition${number}` | `containerSticky${number}`;
|
|
12
12
|
type LegendListListenerType = Extract<ListenerType, "activeStickyIndex" | "anchoredEndSpaceSize" | "footerSize" | "headerSize" | "isAtEnd" | "isAtStart" | "isNearEnd" | "isNearStart" | "isWithinMaintainScrollAtEndThreshold" | "lastItemKeys" | "lastPositionUpdate" | "numContainers" | "numContainersPooled" | "otherAxisSize" | "readyToRender" | "snapToOffsets" | "totalSize">;
|
|
13
13
|
type ListenerTypeValueMap = {
|
|
14
14
|
activeStickyIndex: number;
|
|
15
|
+
alignItemsAtEndPadding: number;
|
|
15
16
|
anchoredEndSpaceSize: number;
|
|
16
17
|
animatedScrollY: any;
|
|
17
18
|
debugComputedScroll: number;
|
package/keyboard-legacy.d.ts
CHANGED
|
@@ -9,10 +9,11 @@ interface MaintainVisibleContentPositionNormalized<ItemT = any> {
|
|
|
9
9
|
shouldRestorePosition?: (item: ItemT, index: number, data: readonly ItemT[]) => boolean;
|
|
10
10
|
}
|
|
11
11
|
|
|
12
|
-
type ListenerType = "activeStickyIndex" | "anchoredEndSpaceSize" | "debugComputedScroll" | "debugRawScroll" | "extraData" | "footerSize" | "headerSize" | "lastItemKeys" | "lastPositionUpdate" | "maintainVisibleContentPosition" | "numColumns" | "numContainers" | "numContainersPooled" | "otherAxisSize" | "readyToRender" | "scrollAdjust" | "scrollAdjustPending" | "scrollAdjustUserOffset" | "scrollSize" | "snapToOffsets" | "stylePaddingTop" | "totalSize" | "isAtEnd" | "isAtStart" | "isNearEnd" | "isNearStart" | "isWithinMaintainScrollAtEndThreshold" | `containerColumn${number}` | `containerSpan${number}` | `containerItemData${number}` | `containerItemKey${number}` | `containerPosition${number}` | `containerSticky${number}`;
|
|
12
|
+
type ListenerType = "activeStickyIndex" | "alignItemsAtEndPadding" | "anchoredEndSpaceSize" | "debugComputedScroll" | "debugRawScroll" | "extraData" | "footerSize" | "headerSize" | "lastItemKeys" | "lastPositionUpdate" | "maintainVisibleContentPosition" | "numColumns" | "numContainers" | "numContainersPooled" | "otherAxisSize" | "readyToRender" | "scrollAdjust" | "scrollAdjustPending" | "scrollAdjustUserOffset" | "scrollSize" | "snapToOffsets" | "stylePaddingTop" | "totalSize" | "isAtEnd" | "isAtStart" | "isNearEnd" | "isNearStart" | "isWithinMaintainScrollAtEndThreshold" | `containerColumn${number}` | `containerSpan${number}` | `containerItemData${number}` | `containerItemKey${number}` | `containerPosition${number}` | `containerSticky${number}`;
|
|
13
13
|
type LegendListListenerType = Extract<ListenerType, "activeStickyIndex" | "anchoredEndSpaceSize" | "footerSize" | "headerSize" | "isAtEnd" | "isAtStart" | "isNearEnd" | "isNearStart" | "isWithinMaintainScrollAtEndThreshold" | "lastItemKeys" | "lastPositionUpdate" | "numContainers" | "numContainersPooled" | "otherAxisSize" | "readyToRender" | "snapToOffsets" | "totalSize">;
|
|
14
14
|
type ListenerTypeValueMap = {
|
|
15
15
|
activeStickyIndex: number;
|
|
16
|
+
alignItemsAtEndPadding: number;
|
|
16
17
|
anchoredEndSpaceSize: number;
|
|
17
18
|
animatedScrollY: any;
|
|
18
19
|
debugComputedScroll: number;
|
package/keyboard.d.ts
CHANGED
|
@@ -10,10 +10,11 @@ interface MaintainVisibleContentPositionNormalized<ItemT = any> {
|
|
|
10
10
|
shouldRestorePosition?: (item: ItemT, index: number, data: readonly ItemT[]) => boolean;
|
|
11
11
|
}
|
|
12
12
|
|
|
13
|
-
type ListenerType = "activeStickyIndex" | "anchoredEndSpaceSize" | "debugComputedScroll" | "debugRawScroll" | "extraData" | "footerSize" | "headerSize" | "lastItemKeys" | "lastPositionUpdate" | "maintainVisibleContentPosition" | "numColumns" | "numContainers" | "numContainersPooled" | "otherAxisSize" | "readyToRender" | "scrollAdjust" | "scrollAdjustPending" | "scrollAdjustUserOffset" | "scrollSize" | "snapToOffsets" | "stylePaddingTop" | "totalSize" | "isAtEnd" | "isAtStart" | "isNearEnd" | "isNearStart" | "isWithinMaintainScrollAtEndThreshold" | `containerColumn${number}` | `containerSpan${number}` | `containerItemData${number}` | `containerItemKey${number}` | `containerPosition${number}` | `containerSticky${number}`;
|
|
13
|
+
type ListenerType = "activeStickyIndex" | "alignItemsAtEndPadding" | "anchoredEndSpaceSize" | "debugComputedScroll" | "debugRawScroll" | "extraData" | "footerSize" | "headerSize" | "lastItemKeys" | "lastPositionUpdate" | "maintainVisibleContentPosition" | "numColumns" | "numContainers" | "numContainersPooled" | "otherAxisSize" | "readyToRender" | "scrollAdjust" | "scrollAdjustPending" | "scrollAdjustUserOffset" | "scrollSize" | "snapToOffsets" | "stylePaddingTop" | "totalSize" | "isAtEnd" | "isAtStart" | "isNearEnd" | "isNearStart" | "isWithinMaintainScrollAtEndThreshold" | `containerColumn${number}` | `containerSpan${number}` | `containerItemData${number}` | `containerItemKey${number}` | `containerPosition${number}` | `containerSticky${number}`;
|
|
14
14
|
type LegendListListenerType = Extract<ListenerType, "activeStickyIndex" | "anchoredEndSpaceSize" | "footerSize" | "headerSize" | "isAtEnd" | "isAtStart" | "isNearEnd" | "isNearStart" | "isWithinMaintainScrollAtEndThreshold" | "lastItemKeys" | "lastPositionUpdate" | "numContainers" | "numContainersPooled" | "otherAxisSize" | "readyToRender" | "snapToOffsets" | "totalSize">;
|
|
15
15
|
type ListenerTypeValueMap = {
|
|
16
16
|
activeStickyIndex: number;
|
|
17
|
+
alignItemsAtEndPadding: number;
|
|
17
18
|
anchoredEndSpaceSize: number;
|
|
18
19
|
animatedScrollY: any;
|
|
19
20
|
debugComputedScroll: number;
|
package/package.json
CHANGED
package/react-native.d.ts
CHANGED
|
@@ -8,10 +8,11 @@ interface MaintainVisibleContentPositionNormalized<ItemT = any> {
|
|
|
8
8
|
shouldRestorePosition?: (item: ItemT, index: number, data: readonly ItemT[]) => boolean;
|
|
9
9
|
}
|
|
10
10
|
|
|
11
|
-
type ListenerType = "activeStickyIndex" | "anchoredEndSpaceSize" | "debugComputedScroll" | "debugRawScroll" | "extraData" | "footerSize" | "headerSize" | "lastItemKeys" | "lastPositionUpdate" | "maintainVisibleContentPosition" | "numColumns" | "numContainers" | "numContainersPooled" | "otherAxisSize" | "readyToRender" | "scrollAdjust" | "scrollAdjustPending" | "scrollAdjustUserOffset" | "scrollSize" | "snapToOffsets" | "stylePaddingTop" | "totalSize" | "isAtEnd" | "isAtStart" | "isNearEnd" | "isNearStart" | "isWithinMaintainScrollAtEndThreshold" | `containerColumn${number}` | `containerSpan${number}` | `containerItemData${number}` | `containerItemKey${number}` | `containerPosition${number}` | `containerSticky${number}`;
|
|
11
|
+
type ListenerType = "activeStickyIndex" | "alignItemsAtEndPadding" | "anchoredEndSpaceSize" | "debugComputedScroll" | "debugRawScroll" | "extraData" | "footerSize" | "headerSize" | "lastItemKeys" | "lastPositionUpdate" | "maintainVisibleContentPosition" | "numColumns" | "numContainers" | "numContainersPooled" | "otherAxisSize" | "readyToRender" | "scrollAdjust" | "scrollAdjustPending" | "scrollAdjustUserOffset" | "scrollSize" | "snapToOffsets" | "stylePaddingTop" | "totalSize" | "isAtEnd" | "isAtStart" | "isNearEnd" | "isNearStart" | "isWithinMaintainScrollAtEndThreshold" | `containerColumn${number}` | `containerSpan${number}` | `containerItemData${number}` | `containerItemKey${number}` | `containerPosition${number}` | `containerSticky${number}`;
|
|
12
12
|
type LegendListListenerType = Extract<ListenerType, "activeStickyIndex" | "anchoredEndSpaceSize" | "footerSize" | "headerSize" | "isAtEnd" | "isAtStart" | "isNearEnd" | "isNearStart" | "isWithinMaintainScrollAtEndThreshold" | "lastItemKeys" | "lastPositionUpdate" | "numContainers" | "numContainersPooled" | "otherAxisSize" | "readyToRender" | "snapToOffsets" | "totalSize">;
|
|
13
13
|
type ListenerTypeValueMap = {
|
|
14
14
|
activeStickyIndex: number;
|
|
15
|
+
alignItemsAtEndPadding: number;
|
|
15
16
|
anchoredEndSpaceSize: number;
|
|
16
17
|
animatedScrollY: any;
|
|
17
18
|
debugComputedScroll: number;
|
package/react-native.js
CHANGED
|
@@ -154,6 +154,7 @@ function StateProvider({ children }) {
|
|
|
154
154
|
positionListeners: /* @__PURE__ */ new Map(),
|
|
155
155
|
state: void 0,
|
|
156
156
|
values: /* @__PURE__ */ new Map([
|
|
157
|
+
["alignItemsAtEndPadding", 0],
|
|
157
158
|
["stylePaddingTop", 0],
|
|
158
159
|
["headerSize", 0],
|
|
159
160
|
["numContainers", 0],
|
|
@@ -296,15 +297,16 @@ function getContentInsetEnd(ctx, contentInsetEndAdjustmentOverride) {
|
|
|
296
297
|
|
|
297
298
|
// src/state/getContentSize.ts
|
|
298
299
|
function getContentSize(ctx) {
|
|
299
|
-
var _a3;
|
|
300
|
+
var _a3, _b;
|
|
300
301
|
const { values, state } = ctx;
|
|
301
302
|
const stylePaddingTop = values.get("stylePaddingTop") || 0;
|
|
302
303
|
const stylePaddingBottom = state.props.stylePaddingBottom || 0;
|
|
304
|
+
const alignItemsAtEndPadding = values.get("alignItemsAtEndPadding") || 0;
|
|
303
305
|
const headerSize = values.get("headerSize") || 0;
|
|
304
306
|
const footerSize = values.get("footerSize") || 0;
|
|
305
307
|
const contentInsetBottom = getContentInsetEnd(ctx);
|
|
306
|
-
const totalSize = (_a3 = state.pendingTotalSize) != null ? _a3 : values.get("totalSize");
|
|
307
|
-
return headerSize + footerSize + totalSize + stylePaddingTop + stylePaddingBottom + (contentInsetBottom || 0);
|
|
308
|
+
const totalSize = (_b = (_a3 = state.pendingTotalSize) != null ? _a3 : state.totalSize) != null ? _b : values.get("totalSize");
|
|
309
|
+
return headerSize + footerSize + totalSize + stylePaddingTop + alignItemsAtEndPadding + stylePaddingBottom + (contentInsetBottom || 0);
|
|
308
310
|
}
|
|
309
311
|
|
|
310
312
|
// src/components/DebugView.tsx
|
|
@@ -479,8 +481,16 @@ var PositionViewSticky = typedMemo(function PositionViewSticky2({
|
|
|
479
481
|
...rest
|
|
480
482
|
}) {
|
|
481
483
|
const ctx = useStateContext();
|
|
482
|
-
const [
|
|
484
|
+
const [
|
|
485
|
+
position = POSITION_OUT_OF_VIEW,
|
|
486
|
+
alignItemsAtEndPadding = 0,
|
|
487
|
+
headerSize = 0,
|
|
488
|
+
stylePaddingTop = 0,
|
|
489
|
+
itemKey,
|
|
490
|
+
_totalSize = 0
|
|
491
|
+
] = useArr$([
|
|
483
492
|
`containerPosition${id}`,
|
|
493
|
+
"alignItemsAtEndPadding",
|
|
484
494
|
"headerSize",
|
|
485
495
|
"stylePaddingTop",
|
|
486
496
|
`containerItemKey${id}`,
|
|
@@ -494,7 +504,7 @@ var PositionViewSticky = typedMemo(function PositionViewSticky2({
|
|
|
494
504
|
var _a3;
|
|
495
505
|
if (animatedScrollY) {
|
|
496
506
|
const stickyConfigOffset = (_a3 = stickyHeaderConfig == null ? void 0 : stickyHeaderConfig.offset) != null ? _a3 : 0;
|
|
497
|
-
const stickyStart = position + headerSize + stylePaddingTop - stickyConfigOffset;
|
|
507
|
+
const stickyStart = position + headerSize + stylePaddingTop + alignItemsAtEndPadding - stickyConfigOffset;
|
|
498
508
|
let nextStickyPosition;
|
|
499
509
|
if (pushLimit !== void 0) {
|
|
500
510
|
if (pushLimit <= position) {
|
|
@@ -517,7 +527,15 @@ var PositionViewSticky = typedMemo(function PositionViewSticky2({
|
|
|
517
527
|
}
|
|
518
528
|
return horizontal ? [{ translateX: nextStickyPosition }] : [{ translateY: nextStickyPosition }];
|
|
519
529
|
}
|
|
520
|
-
}, [
|
|
530
|
+
}, [
|
|
531
|
+
alignItemsAtEndPadding,
|
|
532
|
+
animatedScrollY,
|
|
533
|
+
headerSize,
|
|
534
|
+
position,
|
|
535
|
+
pushLimit,
|
|
536
|
+
stylePaddingTop,
|
|
537
|
+
stickyHeaderConfig == null ? void 0 : stickyHeaderConfig.offset
|
|
538
|
+
]);
|
|
521
539
|
const viewStyle = React2__namespace.useMemo(() => [style, { zIndex: index + 1e3 }, { transform }], [style, transform]);
|
|
522
540
|
const renderStickyHeaderBackdrop = React2__namespace.useMemo(() => {
|
|
523
541
|
if (!(stickyHeaderConfig == null ? void 0 : stickyHeaderConfig.backdropComponent)) {
|
|
@@ -1174,6 +1192,51 @@ function WebAnchoredEndSpace({ horizontal }) {
|
|
|
1174
1192
|
const style = horizontal ? { height: "100%", width: anchoredEndSpaceSize || 0 } : { height: anchoredEndSpaceSize || 0 };
|
|
1175
1193
|
return /* @__PURE__ */ React2__namespace.createElement("div", { style }, null);
|
|
1176
1194
|
}
|
|
1195
|
+
|
|
1196
|
+
// src/core/updateContentMetrics.ts
|
|
1197
|
+
function getRawContentLength(ctx) {
|
|
1198
|
+
var _a3, _b, _c;
|
|
1199
|
+
const { state, values } = ctx;
|
|
1200
|
+
return (values.get("headerSize") || 0) + (values.get("footerSize") || 0) + ((_c = (_b = (_a3 = state.pendingTotalSize) != null ? _a3 : state.totalSize) != null ? _b : values.get("totalSize")) != null ? _c : 0) + (state.props.stylePaddingTop || 0) + (state.props.stylePaddingBottom || 0);
|
|
1201
|
+
}
|
|
1202
|
+
function getAlignItemsAtEndPadding(ctx) {
|
|
1203
|
+
const { state } = ctx;
|
|
1204
|
+
const shouldPad = !!state.props.alignItemsAtEndPaddingEnabled && !state.props.horizontal && state.props.data.length > 0 && state.scrollLength > 0;
|
|
1205
|
+
return shouldPad ? Math.max(0, state.scrollLength - getRawContentLength(ctx) - getContentInsetEnd(ctx)) : 0;
|
|
1206
|
+
}
|
|
1207
|
+
function updateContentMetrics(ctx) {
|
|
1208
|
+
const nextPadding = getAlignItemsAtEndPadding(ctx);
|
|
1209
|
+
if (peek$(ctx, "alignItemsAtEndPadding") !== nextPadding) {
|
|
1210
|
+
set$(ctx, "alignItemsAtEndPadding", nextPadding);
|
|
1211
|
+
}
|
|
1212
|
+
}
|
|
1213
|
+
function setContentLengthSignal(ctx, signalName, size) {
|
|
1214
|
+
if (peek$(ctx, signalName) !== size) {
|
|
1215
|
+
set$(ctx, signalName, size);
|
|
1216
|
+
updateContentMetrics(ctx);
|
|
1217
|
+
}
|
|
1218
|
+
}
|
|
1219
|
+
function setHeaderSize(ctx, size) {
|
|
1220
|
+
setContentLengthSignal(ctx, "headerSize", size);
|
|
1221
|
+
}
|
|
1222
|
+
function setFooterSize(ctx, size) {
|
|
1223
|
+
setContentLengthSignal(ctx, "footerSize", size);
|
|
1224
|
+
}
|
|
1225
|
+
function areInsetsEqual(left, right) {
|
|
1226
|
+
var _a3, _b, _c, _d, _e, _f, _g, _h;
|
|
1227
|
+
return ((_a3 = left == null ? void 0 : left.top) != null ? _a3 : 0) === ((_b = right == null ? void 0 : right.top) != null ? _b : 0) && ((_c = left == null ? void 0 : left.bottom) != null ? _c : 0) === ((_d = right == null ? void 0 : right.bottom) != null ? _d : 0) && ((_e = left == null ? void 0 : left.left) != null ? _e : 0) === ((_f = right == null ? void 0 : right.left) != null ? _f : 0) && ((_g = left == null ? void 0 : left.right) != null ? _g : 0) === ((_h = right == null ? void 0 : right.right) != null ? _h : 0);
|
|
1228
|
+
}
|
|
1229
|
+
function setContentInsetOverride(ctx, inset) {
|
|
1230
|
+
const { state } = ctx;
|
|
1231
|
+
const previousInset = state.contentInsetOverride;
|
|
1232
|
+
const nextInset = inset != null ? inset : void 0;
|
|
1233
|
+
const didChange = !areInsetsEqual(previousInset, nextInset);
|
|
1234
|
+
state.contentInsetOverride = nextInset;
|
|
1235
|
+
if (didChange) {
|
|
1236
|
+
updateContentMetrics(ctx);
|
|
1237
|
+
}
|
|
1238
|
+
return didChange;
|
|
1239
|
+
}
|
|
1177
1240
|
function useLatestRef(value) {
|
|
1178
1241
|
const ref = React2__namespace.useRef(value);
|
|
1179
1242
|
ref.current = value;
|
|
@@ -1232,7 +1295,7 @@ var ListComponent = typedMemo(function ListComponent2({
|
|
|
1232
1295
|
}) {
|
|
1233
1296
|
const ctx = useStateContext();
|
|
1234
1297
|
const maintainVisibleContentPosition = ctx.state.props.maintainVisibleContentPosition;
|
|
1235
|
-
const [otherAxisSize = 0] = useArr$(["otherAxisSize"]);
|
|
1298
|
+
const [alignItemsAtEndPadding = 0, otherAxisSize = 0] = useArr$(["alignItemsAtEndPadding", "otherAxisSize"]);
|
|
1236
1299
|
const autoOtherAxisStyle = getAutoOtherAxisStyle({
|
|
1237
1300
|
horizontal,
|
|
1238
1301
|
needsOtherAxisSize: ctx.state.needsOtherAxisSize,
|
|
@@ -1246,23 +1309,23 @@ var ListComponent = typedMemo(function ListComponent2({
|
|
|
1246
1309
|
const SnapOrScroll = snapToIndices ? SnapWrapper : ScrollComponent;
|
|
1247
1310
|
React2.useLayoutEffect(() => {
|
|
1248
1311
|
if (!ListHeaderComponent) {
|
|
1249
|
-
|
|
1312
|
+
setHeaderSize(ctx, 0);
|
|
1250
1313
|
}
|
|
1251
1314
|
if (!ListFooterComponent) {
|
|
1252
|
-
|
|
1315
|
+
setFooterSize(ctx, 0);
|
|
1253
1316
|
}
|
|
1254
1317
|
}, [ListHeaderComponent, ListFooterComponent, ctx]);
|
|
1255
1318
|
const onLayoutHeader = React2.useCallback(
|
|
1256
1319
|
(rect) => {
|
|
1257
1320
|
const size = rect[horizontal ? "width" : "height"];
|
|
1258
|
-
|
|
1321
|
+
setHeaderSize(ctx, size);
|
|
1259
1322
|
},
|
|
1260
1323
|
[ctx, horizontal]
|
|
1261
1324
|
);
|
|
1262
1325
|
const onLayoutFooterInternal = React2.useCallback(
|
|
1263
1326
|
(rect, fromLayoutEffect) => {
|
|
1264
1327
|
const size = rect[horizontal ? "width" : "height"];
|
|
1265
|
-
|
|
1328
|
+
setFooterSize(ctx, size);
|
|
1266
1329
|
onLayoutFooter == null ? void 0 : onLayoutFooter(rect, fromLayoutEffect);
|
|
1267
1330
|
},
|
|
1268
1331
|
[ctx, horizontal, onLayoutFooter]
|
|
@@ -1290,6 +1353,13 @@ var ListComponent = typedMemo(function ListComponent2({
|
|
|
1290
1353
|
/* @__PURE__ */ React2__namespace.createElement(ScrollAdjust, null),
|
|
1291
1354
|
ListHeaderComponent && /* @__PURE__ */ React2__namespace.createElement(LayoutView, { onLayoutChange: onLayoutHeader, style: ListHeaderComponentStyle }, getComponent(ListHeaderComponent)),
|
|
1292
1355
|
ListEmptyComponent && getComponent(ListEmptyComponent),
|
|
1356
|
+
alignItemsAtEndPadding > 0 && /* @__PURE__ */ React2__namespace.createElement(
|
|
1357
|
+
View,
|
|
1358
|
+
{
|
|
1359
|
+
style: horizontal ? { flexShrink: 0, width: alignItemsAtEndPadding } : { flexShrink: 0, height: alignItemsAtEndPadding }
|
|
1360
|
+
},
|
|
1361
|
+
null
|
|
1362
|
+
),
|
|
1293
1363
|
canRender && !ListEmptyComponent && /* @__PURE__ */ React2__namespace.createElement(
|
|
1294
1364
|
Containers,
|
|
1295
1365
|
{
|
|
@@ -1781,7 +1851,7 @@ function calculateOffsetForIndex(ctx, index) {
|
|
|
1781
1851
|
|
|
1782
1852
|
// src/core/getTopOffsetAdjustment.ts
|
|
1783
1853
|
function getTopOffsetAdjustment(ctx) {
|
|
1784
|
-
return (peek$(ctx, "stylePaddingTop") || 0) + (peek$(ctx, "headerSize") || 0);
|
|
1854
|
+
return (peek$(ctx, "stylePaddingTop") || 0) + (peek$(ctx, "alignItemsAtEndPadding") || 0) + (peek$(ctx, "headerSize") || 0);
|
|
1785
1855
|
}
|
|
1786
1856
|
|
|
1787
1857
|
// src/utils/getId.ts
|
|
@@ -1819,6 +1889,7 @@ function addTotalSize(ctx, key, add, notifyTotalSize = true) {
|
|
|
1819
1889
|
if (notifyTotalSize) {
|
|
1820
1890
|
set$(ctx, "totalSize", totalSize);
|
|
1821
1891
|
}
|
|
1892
|
+
updateContentMetrics(ctx);
|
|
1822
1893
|
}
|
|
1823
1894
|
} else if (notifyTotalSize && ctx.values.get("totalSize") !== totalSize) {
|
|
1824
1895
|
set$(ctx, "totalSize", totalSize);
|
|
@@ -4166,7 +4237,7 @@ function areViewabilityAmountTokensEqual(prev, next) {
|
|
|
4166
4237
|
}
|
|
4167
4238
|
function computeViewability(state, ctx, viewabilityConfig, containerId, key, scrollSize, item, index) {
|
|
4168
4239
|
const { sizes, scroll: scrollState } = state;
|
|
4169
|
-
const topPad = (peek$(ctx, "stylePaddingTop") || 0) + (peek$(ctx, "headerSize") || 0);
|
|
4240
|
+
const topPad = (peek$(ctx, "stylePaddingTop") || 0) + (peek$(ctx, "alignItemsAtEndPadding") || 0) + (peek$(ctx, "headerSize") || 0);
|
|
4170
4241
|
const { itemVisiblePercentThreshold, viewAreaCoveragePercentThreshold } = viewabilityConfig;
|
|
4171
4242
|
const viewAreaMode = viewAreaCoveragePercentThreshold != null;
|
|
4172
4243
|
const viewablePercentThreshold = viewAreaMode ? viewAreaCoveragePercentThreshold : itemVisiblePercentThreshold;
|
|
@@ -4617,7 +4688,7 @@ function calculateItemsInView(ctx, params = {}) {
|
|
|
4617
4688
|
return;
|
|
4618
4689
|
}
|
|
4619
4690
|
let totalSize = getContentSize(ctx);
|
|
4620
|
-
const topPad = peek$(ctx, "stylePaddingTop") + peek$(ctx, "headerSize");
|
|
4691
|
+
const topPad = peek$(ctx, "stylePaddingTop") + peek$(ctx, "alignItemsAtEndPadding") + peek$(ctx, "headerSize");
|
|
4621
4692
|
const numColumns = peek$(ctx, "numColumns");
|
|
4622
4693
|
const speed = getScrollVelocity(state);
|
|
4623
4694
|
const scrollExtra = 0;
|
|
@@ -5157,6 +5228,7 @@ function handleLayout(ctx, layoutParam, setCanRender) {
|
|
|
5157
5228
|
if (didChange) {
|
|
5158
5229
|
state.scrollLength = scrollLength;
|
|
5159
5230
|
state.otherAxisSize = otherAxisSize;
|
|
5231
|
+
updateContentMetrics(ctx);
|
|
5160
5232
|
state.lastBatchingAction = Date.now();
|
|
5161
5233
|
state.scrollForNextCalculateItemsInView = void 0;
|
|
5162
5234
|
if (scrollLength > 0) {
|
|
@@ -5844,10 +5916,7 @@ function createImperativeHandle(ctx, scheduleImperativeScrollCommit) {
|
|
|
5844
5916
|
startBuffered: state.startBuffered
|
|
5845
5917
|
}),
|
|
5846
5918
|
reportContentInset: (inset) => {
|
|
5847
|
-
|
|
5848
|
-
const previousInset = state.contentInsetOverride;
|
|
5849
|
-
state.contentInsetOverride = inset != null ? inset : void 0;
|
|
5850
|
-
const didChange = ((_a3 = previousInset == null ? void 0 : previousInset.top) != null ? _a3 : 0) !== ((_c = (_b = state.contentInsetOverride) == null ? void 0 : _b.top) != null ? _c : 0) || ((_d = previousInset == null ? void 0 : previousInset.bottom) != null ? _d : 0) !== ((_f = (_e = state.contentInsetOverride) == null ? void 0 : _e.bottom) != null ? _f : 0) || ((_g = previousInset == null ? void 0 : previousInset.left) != null ? _g : 0) !== ((_i = (_h = state.contentInsetOverride) == null ? void 0 : _h.left) != null ? _i : 0) || ((_j = previousInset == null ? void 0 : previousInset.right) != null ? _j : 0) !== ((_l = (_k = state.contentInsetOverride) == null ? void 0 : _k.right) != null ? _l : 0);
|
|
5919
|
+
const didChange = setContentInsetOverride(ctx, inset);
|
|
5851
5920
|
updateScroll(ctx, state.scroll, true, { markHasScrolled: false });
|
|
5852
5921
|
if (didChange) {
|
|
5853
5922
|
retargetActiveInitialScrollAtEnd(ctx);
|
|
@@ -6203,10 +6272,11 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
6203
6272
|
...restProps
|
|
6204
6273
|
} = rest;
|
|
6205
6274
|
const contentContainerStyleBase = StyleSheet.flatten(contentContainerStyleProp);
|
|
6206
|
-
const
|
|
6275
|
+
const useAlignItemsAtEndPadding = alignItemsAtEnd && !horizontal && (contentContainerStyleBase == null ? void 0 : contentContainerStyleBase.minHeight) == null && dataProp.length > 0;
|
|
6276
|
+
const shouldFlexGrow = alignItemsAtEnd && !useAlignItemsAtEndPadding && (horizontal ? (contentContainerStyleBase == null ? void 0 : contentContainerStyleBase.minWidth) == null : (contentContainerStyleBase == null ? void 0 : contentContainerStyleBase.minHeight) == null);
|
|
6207
6277
|
const contentContainerStyle = {
|
|
6208
6278
|
...contentContainerStyleBase,
|
|
6209
|
-
...alignItemsAtEnd ? {
|
|
6279
|
+
...alignItemsAtEnd && !useAlignItemsAtEndPadding ? {
|
|
6210
6280
|
display: "flex",
|
|
6211
6281
|
flexDirection: horizontal ? "row" : "column",
|
|
6212
6282
|
...shouldFlexGrow ? { flexGrow: 1 } : {},
|
|
@@ -6370,6 +6440,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
6370
6440
|
const didAnchoredEndSpaceAnchorIndexChange = !isFirstLocal && !didDataChangeLocal && ((_g = state.props.anchoredEndSpace) == null ? void 0 : _g.anchorIndex) !== (anchoredEndSpaceResolved == null ? void 0 : anchoredEndSpaceResolved.anchorIndex);
|
|
6371
6441
|
state.props = {
|
|
6372
6442
|
alignItemsAtEnd,
|
|
6443
|
+
alignItemsAtEndPaddingEnabled: useAlignItemsAtEndPadding,
|
|
6373
6444
|
alwaysRender,
|
|
6374
6445
|
alwaysRenderIndicesArr: alwaysRenderIndices.arr,
|
|
6375
6446
|
alwaysRenderIndicesSet: alwaysRenderIndices.set,
|
|
@@ -6427,6 +6498,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
6427
6498
|
const prevPaddingTop = peek$(ctx, "stylePaddingTop");
|
|
6428
6499
|
setPaddingTop(ctx, { stylePaddingTop: stylePaddingTopState });
|
|
6429
6500
|
refState.current.props.stylePaddingBottom = stylePaddingBottomState;
|
|
6501
|
+
updateContentMetrics(ctx);
|
|
6430
6502
|
let paddingDiff = stylePaddingTopState - prevPaddingTop;
|
|
6431
6503
|
if (shouldAdjustPadding && maintainVisibleContentPositionConfig.size && paddingDiff && prevPaddingTop !== void 0 && Platform.OS === "ios") {
|
|
6432
6504
|
if (state.scroll < 0) {
|
|
@@ -6550,7 +6622,14 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
6550
6622
|
}, [snapToIndices]);
|
|
6551
6623
|
React2.useLayoutEffect(
|
|
6552
6624
|
() => initializeStateVars(true),
|
|
6553
|
-
[
|
|
6625
|
+
[
|
|
6626
|
+
dataVersion,
|
|
6627
|
+
memoizedLastItemKeys.join(","),
|
|
6628
|
+
numColumnsProp,
|
|
6629
|
+
stylePaddingBottomState,
|
|
6630
|
+
stylePaddingTopState,
|
|
6631
|
+
useAlignItemsAtEndPadding
|
|
6632
|
+
]
|
|
6554
6633
|
);
|
|
6555
6634
|
React2.useLayoutEffect(() => {
|
|
6556
6635
|
const {
|
package/react-native.mjs
CHANGED
|
@@ -133,6 +133,7 @@ function StateProvider({ children }) {
|
|
|
133
133
|
positionListeners: /* @__PURE__ */ new Map(),
|
|
134
134
|
state: void 0,
|
|
135
135
|
values: /* @__PURE__ */ new Map([
|
|
136
|
+
["alignItemsAtEndPadding", 0],
|
|
136
137
|
["stylePaddingTop", 0],
|
|
137
138
|
["headerSize", 0],
|
|
138
139
|
["numContainers", 0],
|
|
@@ -275,15 +276,16 @@ function getContentInsetEnd(ctx, contentInsetEndAdjustmentOverride) {
|
|
|
275
276
|
|
|
276
277
|
// src/state/getContentSize.ts
|
|
277
278
|
function getContentSize(ctx) {
|
|
278
|
-
var _a3;
|
|
279
|
+
var _a3, _b;
|
|
279
280
|
const { values, state } = ctx;
|
|
280
281
|
const stylePaddingTop = values.get("stylePaddingTop") || 0;
|
|
281
282
|
const stylePaddingBottom = state.props.stylePaddingBottom || 0;
|
|
283
|
+
const alignItemsAtEndPadding = values.get("alignItemsAtEndPadding") || 0;
|
|
282
284
|
const headerSize = values.get("headerSize") || 0;
|
|
283
285
|
const footerSize = values.get("footerSize") || 0;
|
|
284
286
|
const contentInsetBottom = getContentInsetEnd(ctx);
|
|
285
|
-
const totalSize = (_a3 = state.pendingTotalSize) != null ? _a3 : values.get("totalSize");
|
|
286
|
-
return headerSize + footerSize + totalSize + stylePaddingTop + stylePaddingBottom + (contentInsetBottom || 0);
|
|
287
|
+
const totalSize = (_b = (_a3 = state.pendingTotalSize) != null ? _a3 : state.totalSize) != null ? _b : values.get("totalSize");
|
|
288
|
+
return headerSize + footerSize + totalSize + stylePaddingTop + alignItemsAtEndPadding + stylePaddingBottom + (contentInsetBottom || 0);
|
|
287
289
|
}
|
|
288
290
|
|
|
289
291
|
// src/components/DebugView.tsx
|
|
@@ -458,8 +460,16 @@ var PositionViewSticky = typedMemo(function PositionViewSticky2({
|
|
|
458
460
|
...rest
|
|
459
461
|
}) {
|
|
460
462
|
const ctx = useStateContext();
|
|
461
|
-
const [
|
|
463
|
+
const [
|
|
464
|
+
position = POSITION_OUT_OF_VIEW,
|
|
465
|
+
alignItemsAtEndPadding = 0,
|
|
466
|
+
headerSize = 0,
|
|
467
|
+
stylePaddingTop = 0,
|
|
468
|
+
itemKey,
|
|
469
|
+
_totalSize = 0
|
|
470
|
+
] = useArr$([
|
|
462
471
|
`containerPosition${id}`,
|
|
472
|
+
"alignItemsAtEndPadding",
|
|
463
473
|
"headerSize",
|
|
464
474
|
"stylePaddingTop",
|
|
465
475
|
`containerItemKey${id}`,
|
|
@@ -473,7 +483,7 @@ var PositionViewSticky = typedMemo(function PositionViewSticky2({
|
|
|
473
483
|
var _a3;
|
|
474
484
|
if (animatedScrollY) {
|
|
475
485
|
const stickyConfigOffset = (_a3 = stickyHeaderConfig == null ? void 0 : stickyHeaderConfig.offset) != null ? _a3 : 0;
|
|
476
|
-
const stickyStart = position + headerSize + stylePaddingTop - stickyConfigOffset;
|
|
486
|
+
const stickyStart = position + headerSize + stylePaddingTop + alignItemsAtEndPadding - stickyConfigOffset;
|
|
477
487
|
let nextStickyPosition;
|
|
478
488
|
if (pushLimit !== void 0) {
|
|
479
489
|
if (pushLimit <= position) {
|
|
@@ -496,7 +506,15 @@ var PositionViewSticky = typedMemo(function PositionViewSticky2({
|
|
|
496
506
|
}
|
|
497
507
|
return horizontal ? [{ translateX: nextStickyPosition }] : [{ translateY: nextStickyPosition }];
|
|
498
508
|
}
|
|
499
|
-
}, [
|
|
509
|
+
}, [
|
|
510
|
+
alignItemsAtEndPadding,
|
|
511
|
+
animatedScrollY,
|
|
512
|
+
headerSize,
|
|
513
|
+
position,
|
|
514
|
+
pushLimit,
|
|
515
|
+
stylePaddingTop,
|
|
516
|
+
stickyHeaderConfig == null ? void 0 : stickyHeaderConfig.offset
|
|
517
|
+
]);
|
|
500
518
|
const viewStyle = React2.useMemo(() => [style, { zIndex: index + 1e3 }, { transform }], [style, transform]);
|
|
501
519
|
const renderStickyHeaderBackdrop = React2.useMemo(() => {
|
|
502
520
|
if (!(stickyHeaderConfig == null ? void 0 : stickyHeaderConfig.backdropComponent)) {
|
|
@@ -1153,6 +1171,51 @@ function WebAnchoredEndSpace({ horizontal }) {
|
|
|
1153
1171
|
const style = horizontal ? { height: "100%", width: anchoredEndSpaceSize || 0 } : { height: anchoredEndSpaceSize || 0 };
|
|
1154
1172
|
return /* @__PURE__ */ React2.createElement("div", { style }, null);
|
|
1155
1173
|
}
|
|
1174
|
+
|
|
1175
|
+
// src/core/updateContentMetrics.ts
|
|
1176
|
+
function getRawContentLength(ctx) {
|
|
1177
|
+
var _a3, _b, _c;
|
|
1178
|
+
const { state, values } = ctx;
|
|
1179
|
+
return (values.get("headerSize") || 0) + (values.get("footerSize") || 0) + ((_c = (_b = (_a3 = state.pendingTotalSize) != null ? _a3 : state.totalSize) != null ? _b : values.get("totalSize")) != null ? _c : 0) + (state.props.stylePaddingTop || 0) + (state.props.stylePaddingBottom || 0);
|
|
1180
|
+
}
|
|
1181
|
+
function getAlignItemsAtEndPadding(ctx) {
|
|
1182
|
+
const { state } = ctx;
|
|
1183
|
+
const shouldPad = !!state.props.alignItemsAtEndPaddingEnabled && !state.props.horizontal && state.props.data.length > 0 && state.scrollLength > 0;
|
|
1184
|
+
return shouldPad ? Math.max(0, state.scrollLength - getRawContentLength(ctx) - getContentInsetEnd(ctx)) : 0;
|
|
1185
|
+
}
|
|
1186
|
+
function updateContentMetrics(ctx) {
|
|
1187
|
+
const nextPadding = getAlignItemsAtEndPadding(ctx);
|
|
1188
|
+
if (peek$(ctx, "alignItemsAtEndPadding") !== nextPadding) {
|
|
1189
|
+
set$(ctx, "alignItemsAtEndPadding", nextPadding);
|
|
1190
|
+
}
|
|
1191
|
+
}
|
|
1192
|
+
function setContentLengthSignal(ctx, signalName, size) {
|
|
1193
|
+
if (peek$(ctx, signalName) !== size) {
|
|
1194
|
+
set$(ctx, signalName, size);
|
|
1195
|
+
updateContentMetrics(ctx);
|
|
1196
|
+
}
|
|
1197
|
+
}
|
|
1198
|
+
function setHeaderSize(ctx, size) {
|
|
1199
|
+
setContentLengthSignal(ctx, "headerSize", size);
|
|
1200
|
+
}
|
|
1201
|
+
function setFooterSize(ctx, size) {
|
|
1202
|
+
setContentLengthSignal(ctx, "footerSize", size);
|
|
1203
|
+
}
|
|
1204
|
+
function areInsetsEqual(left, right) {
|
|
1205
|
+
var _a3, _b, _c, _d, _e, _f, _g, _h;
|
|
1206
|
+
return ((_a3 = left == null ? void 0 : left.top) != null ? _a3 : 0) === ((_b = right == null ? void 0 : right.top) != null ? _b : 0) && ((_c = left == null ? void 0 : left.bottom) != null ? _c : 0) === ((_d = right == null ? void 0 : right.bottom) != null ? _d : 0) && ((_e = left == null ? void 0 : left.left) != null ? _e : 0) === ((_f = right == null ? void 0 : right.left) != null ? _f : 0) && ((_g = left == null ? void 0 : left.right) != null ? _g : 0) === ((_h = right == null ? void 0 : right.right) != null ? _h : 0);
|
|
1207
|
+
}
|
|
1208
|
+
function setContentInsetOverride(ctx, inset) {
|
|
1209
|
+
const { state } = ctx;
|
|
1210
|
+
const previousInset = state.contentInsetOverride;
|
|
1211
|
+
const nextInset = inset != null ? inset : void 0;
|
|
1212
|
+
const didChange = !areInsetsEqual(previousInset, nextInset);
|
|
1213
|
+
state.contentInsetOverride = nextInset;
|
|
1214
|
+
if (didChange) {
|
|
1215
|
+
updateContentMetrics(ctx);
|
|
1216
|
+
}
|
|
1217
|
+
return didChange;
|
|
1218
|
+
}
|
|
1156
1219
|
function useLatestRef(value) {
|
|
1157
1220
|
const ref = React2.useRef(value);
|
|
1158
1221
|
ref.current = value;
|
|
@@ -1211,7 +1274,7 @@ var ListComponent = typedMemo(function ListComponent2({
|
|
|
1211
1274
|
}) {
|
|
1212
1275
|
const ctx = useStateContext();
|
|
1213
1276
|
const maintainVisibleContentPosition = ctx.state.props.maintainVisibleContentPosition;
|
|
1214
|
-
const [otherAxisSize = 0] = useArr$(["otherAxisSize"]);
|
|
1277
|
+
const [alignItemsAtEndPadding = 0, otherAxisSize = 0] = useArr$(["alignItemsAtEndPadding", "otherAxisSize"]);
|
|
1215
1278
|
const autoOtherAxisStyle = getAutoOtherAxisStyle({
|
|
1216
1279
|
horizontal,
|
|
1217
1280
|
needsOtherAxisSize: ctx.state.needsOtherAxisSize,
|
|
@@ -1225,23 +1288,23 @@ var ListComponent = typedMemo(function ListComponent2({
|
|
|
1225
1288
|
const SnapOrScroll = snapToIndices ? SnapWrapper : ScrollComponent;
|
|
1226
1289
|
useLayoutEffect(() => {
|
|
1227
1290
|
if (!ListHeaderComponent) {
|
|
1228
|
-
|
|
1291
|
+
setHeaderSize(ctx, 0);
|
|
1229
1292
|
}
|
|
1230
1293
|
if (!ListFooterComponent) {
|
|
1231
|
-
|
|
1294
|
+
setFooterSize(ctx, 0);
|
|
1232
1295
|
}
|
|
1233
1296
|
}, [ListHeaderComponent, ListFooterComponent, ctx]);
|
|
1234
1297
|
const onLayoutHeader = useCallback(
|
|
1235
1298
|
(rect) => {
|
|
1236
1299
|
const size = rect[horizontal ? "width" : "height"];
|
|
1237
|
-
|
|
1300
|
+
setHeaderSize(ctx, size);
|
|
1238
1301
|
},
|
|
1239
1302
|
[ctx, horizontal]
|
|
1240
1303
|
);
|
|
1241
1304
|
const onLayoutFooterInternal = useCallback(
|
|
1242
1305
|
(rect, fromLayoutEffect) => {
|
|
1243
1306
|
const size = rect[horizontal ? "width" : "height"];
|
|
1244
|
-
|
|
1307
|
+
setFooterSize(ctx, size);
|
|
1245
1308
|
onLayoutFooter == null ? void 0 : onLayoutFooter(rect, fromLayoutEffect);
|
|
1246
1309
|
},
|
|
1247
1310
|
[ctx, horizontal, onLayoutFooter]
|
|
@@ -1269,6 +1332,13 @@ var ListComponent = typedMemo(function ListComponent2({
|
|
|
1269
1332
|
/* @__PURE__ */ React2.createElement(ScrollAdjust, null),
|
|
1270
1333
|
ListHeaderComponent && /* @__PURE__ */ React2.createElement(LayoutView, { onLayoutChange: onLayoutHeader, style: ListHeaderComponentStyle }, getComponent(ListHeaderComponent)),
|
|
1271
1334
|
ListEmptyComponent && getComponent(ListEmptyComponent),
|
|
1335
|
+
alignItemsAtEndPadding > 0 && /* @__PURE__ */ React2.createElement(
|
|
1336
|
+
View,
|
|
1337
|
+
{
|
|
1338
|
+
style: horizontal ? { flexShrink: 0, width: alignItemsAtEndPadding } : { flexShrink: 0, height: alignItemsAtEndPadding }
|
|
1339
|
+
},
|
|
1340
|
+
null
|
|
1341
|
+
),
|
|
1272
1342
|
canRender && !ListEmptyComponent && /* @__PURE__ */ React2.createElement(
|
|
1273
1343
|
Containers,
|
|
1274
1344
|
{
|
|
@@ -1760,7 +1830,7 @@ function calculateOffsetForIndex(ctx, index) {
|
|
|
1760
1830
|
|
|
1761
1831
|
// src/core/getTopOffsetAdjustment.ts
|
|
1762
1832
|
function getTopOffsetAdjustment(ctx) {
|
|
1763
|
-
return (peek$(ctx, "stylePaddingTop") || 0) + (peek$(ctx, "headerSize") || 0);
|
|
1833
|
+
return (peek$(ctx, "stylePaddingTop") || 0) + (peek$(ctx, "alignItemsAtEndPadding") || 0) + (peek$(ctx, "headerSize") || 0);
|
|
1764
1834
|
}
|
|
1765
1835
|
|
|
1766
1836
|
// src/utils/getId.ts
|
|
@@ -1798,6 +1868,7 @@ function addTotalSize(ctx, key, add, notifyTotalSize = true) {
|
|
|
1798
1868
|
if (notifyTotalSize) {
|
|
1799
1869
|
set$(ctx, "totalSize", totalSize);
|
|
1800
1870
|
}
|
|
1871
|
+
updateContentMetrics(ctx);
|
|
1801
1872
|
}
|
|
1802
1873
|
} else if (notifyTotalSize && ctx.values.get("totalSize") !== totalSize) {
|
|
1803
1874
|
set$(ctx, "totalSize", totalSize);
|
|
@@ -4145,7 +4216,7 @@ function areViewabilityAmountTokensEqual(prev, next) {
|
|
|
4145
4216
|
}
|
|
4146
4217
|
function computeViewability(state, ctx, viewabilityConfig, containerId, key, scrollSize, item, index) {
|
|
4147
4218
|
const { sizes, scroll: scrollState } = state;
|
|
4148
|
-
const topPad = (peek$(ctx, "stylePaddingTop") || 0) + (peek$(ctx, "headerSize") || 0);
|
|
4219
|
+
const topPad = (peek$(ctx, "stylePaddingTop") || 0) + (peek$(ctx, "alignItemsAtEndPadding") || 0) + (peek$(ctx, "headerSize") || 0);
|
|
4149
4220
|
const { itemVisiblePercentThreshold, viewAreaCoveragePercentThreshold } = viewabilityConfig;
|
|
4150
4221
|
const viewAreaMode = viewAreaCoveragePercentThreshold != null;
|
|
4151
4222
|
const viewablePercentThreshold = viewAreaMode ? viewAreaCoveragePercentThreshold : itemVisiblePercentThreshold;
|
|
@@ -4596,7 +4667,7 @@ function calculateItemsInView(ctx, params = {}) {
|
|
|
4596
4667
|
return;
|
|
4597
4668
|
}
|
|
4598
4669
|
let totalSize = getContentSize(ctx);
|
|
4599
|
-
const topPad = peek$(ctx, "stylePaddingTop") + peek$(ctx, "headerSize");
|
|
4670
|
+
const topPad = peek$(ctx, "stylePaddingTop") + peek$(ctx, "alignItemsAtEndPadding") + peek$(ctx, "headerSize");
|
|
4600
4671
|
const numColumns = peek$(ctx, "numColumns");
|
|
4601
4672
|
const speed = getScrollVelocity(state);
|
|
4602
4673
|
const scrollExtra = 0;
|
|
@@ -5136,6 +5207,7 @@ function handleLayout(ctx, layoutParam, setCanRender) {
|
|
|
5136
5207
|
if (didChange) {
|
|
5137
5208
|
state.scrollLength = scrollLength;
|
|
5138
5209
|
state.otherAxisSize = otherAxisSize;
|
|
5210
|
+
updateContentMetrics(ctx);
|
|
5139
5211
|
state.lastBatchingAction = Date.now();
|
|
5140
5212
|
state.scrollForNextCalculateItemsInView = void 0;
|
|
5141
5213
|
if (scrollLength > 0) {
|
|
@@ -5823,10 +5895,7 @@ function createImperativeHandle(ctx, scheduleImperativeScrollCommit) {
|
|
|
5823
5895
|
startBuffered: state.startBuffered
|
|
5824
5896
|
}),
|
|
5825
5897
|
reportContentInset: (inset) => {
|
|
5826
|
-
|
|
5827
|
-
const previousInset = state.contentInsetOverride;
|
|
5828
|
-
state.contentInsetOverride = inset != null ? inset : void 0;
|
|
5829
|
-
const didChange = ((_a3 = previousInset == null ? void 0 : previousInset.top) != null ? _a3 : 0) !== ((_c = (_b = state.contentInsetOverride) == null ? void 0 : _b.top) != null ? _c : 0) || ((_d = previousInset == null ? void 0 : previousInset.bottom) != null ? _d : 0) !== ((_f = (_e = state.contentInsetOverride) == null ? void 0 : _e.bottom) != null ? _f : 0) || ((_g = previousInset == null ? void 0 : previousInset.left) != null ? _g : 0) !== ((_i = (_h = state.contentInsetOverride) == null ? void 0 : _h.left) != null ? _i : 0) || ((_j = previousInset == null ? void 0 : previousInset.right) != null ? _j : 0) !== ((_l = (_k = state.contentInsetOverride) == null ? void 0 : _k.right) != null ? _l : 0);
|
|
5898
|
+
const didChange = setContentInsetOverride(ctx, inset);
|
|
5830
5899
|
updateScroll(ctx, state.scroll, true, { markHasScrolled: false });
|
|
5831
5900
|
if (didChange) {
|
|
5832
5901
|
retargetActiveInitialScrollAtEnd(ctx);
|
|
@@ -6182,10 +6251,11 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
6182
6251
|
...restProps
|
|
6183
6252
|
} = rest;
|
|
6184
6253
|
const contentContainerStyleBase = StyleSheet.flatten(contentContainerStyleProp);
|
|
6185
|
-
const
|
|
6254
|
+
const useAlignItemsAtEndPadding = alignItemsAtEnd && !horizontal && (contentContainerStyleBase == null ? void 0 : contentContainerStyleBase.minHeight) == null && dataProp.length > 0;
|
|
6255
|
+
const shouldFlexGrow = alignItemsAtEnd && !useAlignItemsAtEndPadding && (horizontal ? (contentContainerStyleBase == null ? void 0 : contentContainerStyleBase.minWidth) == null : (contentContainerStyleBase == null ? void 0 : contentContainerStyleBase.minHeight) == null);
|
|
6186
6256
|
const contentContainerStyle = {
|
|
6187
6257
|
...contentContainerStyleBase,
|
|
6188
|
-
...alignItemsAtEnd ? {
|
|
6258
|
+
...alignItemsAtEnd && !useAlignItemsAtEndPadding ? {
|
|
6189
6259
|
display: "flex",
|
|
6190
6260
|
flexDirection: horizontal ? "row" : "column",
|
|
6191
6261
|
...shouldFlexGrow ? { flexGrow: 1 } : {},
|
|
@@ -6349,6 +6419,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
6349
6419
|
const didAnchoredEndSpaceAnchorIndexChange = !isFirstLocal && !didDataChangeLocal && ((_g = state.props.anchoredEndSpace) == null ? void 0 : _g.anchorIndex) !== (anchoredEndSpaceResolved == null ? void 0 : anchoredEndSpaceResolved.anchorIndex);
|
|
6350
6420
|
state.props = {
|
|
6351
6421
|
alignItemsAtEnd,
|
|
6422
|
+
alignItemsAtEndPaddingEnabled: useAlignItemsAtEndPadding,
|
|
6352
6423
|
alwaysRender,
|
|
6353
6424
|
alwaysRenderIndicesArr: alwaysRenderIndices.arr,
|
|
6354
6425
|
alwaysRenderIndicesSet: alwaysRenderIndices.set,
|
|
@@ -6406,6 +6477,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
6406
6477
|
const prevPaddingTop = peek$(ctx, "stylePaddingTop");
|
|
6407
6478
|
setPaddingTop(ctx, { stylePaddingTop: stylePaddingTopState });
|
|
6408
6479
|
refState.current.props.stylePaddingBottom = stylePaddingBottomState;
|
|
6480
|
+
updateContentMetrics(ctx);
|
|
6409
6481
|
let paddingDiff = stylePaddingTopState - prevPaddingTop;
|
|
6410
6482
|
if (shouldAdjustPadding && maintainVisibleContentPositionConfig.size && paddingDiff && prevPaddingTop !== void 0 && Platform.OS === "ios") {
|
|
6411
6483
|
if (state.scroll < 0) {
|
|
@@ -6529,7 +6601,14 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
6529
6601
|
}, [snapToIndices]);
|
|
6530
6602
|
useLayoutEffect(
|
|
6531
6603
|
() => initializeStateVars(true),
|
|
6532
|
-
[
|
|
6604
|
+
[
|
|
6605
|
+
dataVersion,
|
|
6606
|
+
memoizedLastItemKeys.join(","),
|
|
6607
|
+
numColumnsProp,
|
|
6608
|
+
stylePaddingBottomState,
|
|
6609
|
+
stylePaddingTopState,
|
|
6610
|
+
useAlignItemsAtEndPadding
|
|
6611
|
+
]
|
|
6533
6612
|
);
|
|
6534
6613
|
useLayoutEffect(() => {
|
|
6535
6614
|
const {
|
package/react-native.web.d.ts
CHANGED
|
@@ -31,10 +31,11 @@ interface MaintainVisibleContentPositionNormalized<ItemT = any> {
|
|
|
31
31
|
shouldRestorePosition?: (item: ItemT, index: number, data: readonly ItemT[]) => boolean;
|
|
32
32
|
}
|
|
33
33
|
|
|
34
|
-
type ListenerType = "activeStickyIndex" | "anchoredEndSpaceSize" | "debugComputedScroll" | "debugRawScroll" | "extraData" | "footerSize" | "headerSize" | "lastItemKeys" | "lastPositionUpdate" | "maintainVisibleContentPosition" | "numColumns" | "numContainers" | "numContainersPooled" | "otherAxisSize" | "readyToRender" | "scrollAdjust" | "scrollAdjustPending" | "scrollAdjustUserOffset" | "scrollSize" | "snapToOffsets" | "stylePaddingTop" | "totalSize" | "isAtEnd" | "isAtStart" | "isNearEnd" | "isNearStart" | "isWithinMaintainScrollAtEndThreshold" | `containerColumn${number}` | `containerSpan${number}` | `containerItemData${number}` | `containerItemKey${number}` | `containerPosition${number}` | `containerSticky${number}`;
|
|
34
|
+
type ListenerType = "activeStickyIndex" | "alignItemsAtEndPadding" | "anchoredEndSpaceSize" | "debugComputedScroll" | "debugRawScroll" | "extraData" | "footerSize" | "headerSize" | "lastItemKeys" | "lastPositionUpdate" | "maintainVisibleContentPosition" | "numColumns" | "numContainers" | "numContainersPooled" | "otherAxisSize" | "readyToRender" | "scrollAdjust" | "scrollAdjustPending" | "scrollAdjustUserOffset" | "scrollSize" | "snapToOffsets" | "stylePaddingTop" | "totalSize" | "isAtEnd" | "isAtStart" | "isNearEnd" | "isNearStart" | "isWithinMaintainScrollAtEndThreshold" | `containerColumn${number}` | `containerSpan${number}` | `containerItemData${number}` | `containerItemKey${number}` | `containerPosition${number}` | `containerSticky${number}`;
|
|
35
35
|
type LegendListListenerType = Extract<ListenerType, "activeStickyIndex" | "anchoredEndSpaceSize" | "footerSize" | "headerSize" | "isAtEnd" | "isAtStart" | "isNearEnd" | "isNearStart" | "isWithinMaintainScrollAtEndThreshold" | "lastItemKeys" | "lastPositionUpdate" | "numContainers" | "numContainersPooled" | "otherAxisSize" | "readyToRender" | "snapToOffsets" | "totalSize">;
|
|
36
36
|
type ListenerTypeValueMap = {
|
|
37
37
|
activeStickyIndex: number;
|
|
38
|
+
alignItemsAtEndPadding: number;
|
|
38
39
|
anchoredEndSpaceSize: number;
|
|
39
40
|
animatedScrollY: any;
|
|
40
41
|
debugComputedScroll: number;
|