@amazon-devices/vega-carousel 0.2.1 → 0.2.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/CarouselScrollable/native/CarouselNativeLogic.d.ts +42 -1
- package/dist/CarouselScrollable/native/CarouselNativeLogic.js +58 -1
- package/dist/CarouselScrollable/native/CarouselNativeWrapper.js +14 -3
- package/dist/kepler/aarch64-debug/lib/com.amazon.keplerscript.carousel.so +0 -0
- package/dist/kepler/aarch64-debug/lib/com.amazon.keplerscript.carousel.so.debug +0 -0
- package/dist/kepler/aarch64-release/lib/com.amazon.keplerscript.carousel.so +0 -0
- package/dist/kepler/aarch64-release/lib/com.amazon.keplerscript.carousel.so.debug +0 -0
- package/dist/kepler/armv7-debug/lib/com.amazon.keplerscript.carousel.so +0 -0
- package/dist/kepler/armv7-debug/lib/com.amazon.keplerscript.carousel.so.debug +0 -0
- package/dist/kepler/armv7-release/lib/com.amazon.keplerscript.carousel.so +0 -0
- package/dist/kepler/armv7-release/lib/com.amazon.keplerscript.carousel.so.debug +0 -0
- package/dist/kepler/x86_64-debug/lib/com.amazon.keplerscript.carousel.so +0 -0
- package/dist/kepler/x86_64-debug/lib/com.amazon.keplerscript.carousel.so.debug +0 -0
- package/dist/kepler/x86_64-release/lib/com.amazon.keplerscript.carousel.so +0 -0
- package/dist/kepler/x86_64-release/lib/com.amazon.keplerscript.carousel.so.debug +0 -0
- package/package.json +1 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { HostComponent, StyleProp, ViewStyle } from 'react-native';
|
|
2
|
-
import { ListOrientation, OnItemBindFunc, OnItemUnbindFunc, OnSelectionChangedCallback } from '../CarouselScrollableTypes';
|
|
2
|
+
import { ListOrientation, ListSelectionStrategy, OnItemBindFunc, OnItemUnbindFunc, OnSelectionChangedCallback } from '../CarouselScrollableTypes';
|
|
3
3
|
import { CarouselNativeHostComponentSelectionChangedEvent, CarouselNativeHostComponentProps } from './CarouselNativeHostComponent';
|
|
4
4
|
import { CarouselDataAdapter, CarouselDataChange, CarouselResolvedDataValues, RenderItemFunc } from '../../CarouselData';
|
|
5
5
|
import { AnyValue } from '../../utils';
|
|
@@ -112,6 +112,47 @@ export declare function callReset(hostComponent: HostComponent<CarouselNativeHos
|
|
|
112
112
|
* `baseStyle` and a _row_ or _column_ flex direction.
|
|
113
113
|
*/
|
|
114
114
|
export declare function addFlexDirectionStyle(baseStyle: StyleProp<ViewStyle>, orientation: ListOrientation): StyleProp<ViewStyle>;
|
|
115
|
+
/**
|
|
116
|
+
* Resolves how many items {@link getInitialData} should place **before** the
|
|
117
|
+
* `initialStartIndex` in the initial render window.
|
|
118
|
+
*
|
|
119
|
+
* For {@link ListSelectionStrategy.ANCHORED} and
|
|
120
|
+
* {@link ListSelectionStrategy.NATURAL}, the initial pool is a leading-margin
|
|
121
|
+
* window, so the back count is simply `numOffsetItems` (the historical
|
|
122
|
+
* behavior).
|
|
123
|
+
*
|
|
124
|
+
* For {@link ListSelectionStrategy.PINNED} the native layer redistributes the
|
|
125
|
+
* initial pool so the selected item rests at its pin proportion. If JS resolves
|
|
126
|
+
* a different window than native pins to, the leading pin-window frames native
|
|
127
|
+
* wants were never sent by JS, so native fires an async `bindTo` roundtrip to
|
|
128
|
+
* refill them — a visible pop-in on the leading side (VEGATV-116583). To stay
|
|
129
|
+
* in lockstep this MIRRORS native `computePinnedPoolStart`'s `itemsBefore`
|
|
130
|
+
* exactly:
|
|
131
|
+
*
|
|
132
|
+
* pool = min(renderedItemsCount, itemCount) // native items_.size()
|
|
133
|
+
* itemsBefore = clamp(floor(pool * pin), minBefore, maxBefore)
|
|
134
|
+
* minBefore = (hasDataBefore && pool > 2) ? 1 : 0
|
|
135
|
+
* maxBefore = (hasDataAfter && pool > 2) ? pool - 2 : pool - 1
|
|
136
|
+
*
|
|
137
|
+
* A plain `min(floor(pool*pin), pool-1)` diverges from native at the extremes
|
|
138
|
+
* (e.g. pool 8 pin 0.9 → JS 7 vs native 6; pin 0.0 mid-list → JS 0 vs native 1),
|
|
139
|
+
* and that off-by-one frame is exactly the leading frame native would then have
|
|
140
|
+
* to bind async — the roundtrip this change removes. Center pins already match;
|
|
141
|
+
* mirroring the clamp closes the extremes.
|
|
142
|
+
*
|
|
143
|
+
* @param {ListSelectionStrategy} selectionStrategy The list's selection strategy.
|
|
144
|
+
* @param {number} renderedItemsCount The configured render window size.
|
|
145
|
+
* @param {number} numOffsetItems The leading-margin back count used for the
|
|
146
|
+
* non-pinned strategies.
|
|
147
|
+
* @param {number} pinnedFocusOffset The resolved pin proportion (0.0 - 1.0);
|
|
148
|
+
* only used when `selectionStrategy` is `PINNED`.
|
|
149
|
+
* @param {number} initialStartIndex The selected data index at mount (used to
|
|
150
|
+
* detect whether data exists before/after, matching native).
|
|
151
|
+
* @param {number} itemCount Total number of items in the data set.
|
|
152
|
+
*
|
|
153
|
+
* @return {number} The number of items to resolve before `initialStartIndex`.
|
|
154
|
+
*/
|
|
155
|
+
export declare function resolveInitialBackCount(selectionStrategy: ListSelectionStrategy, renderedItemsCount: number, numOffsetItems: number, pinnedFocusOffset: number, initialStartIndex: number, itemCount: number): number;
|
|
115
156
|
/**
|
|
116
157
|
* This function is the core logic to retrieve items on the {@link CarouselScrollable}
|
|
117
158
|
* initial render.
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* PROPRIETARY/CONFIDENTIAL. USE IS SUBJECT TO LICENSE TERMS.
|
|
6
6
|
*/
|
|
7
7
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
|
-
exports.triggerOnItemBindCallback = exports.triggerOnItemUnbindCallback = exports.triggerOnSelectionChangeCallback = exports.getInitialData = exports.addFlexDirectionStyle = exports.callReset = exports.callNativeNotifyDataChange = exports.callNativeSetOverflowItemsVisible = exports.callNativeSetSelectedItem = exports.callNativeEnableInputEvents = void 0;
|
|
8
|
+
exports.triggerOnItemBindCallback = exports.triggerOnItemUnbindCallback = exports.triggerOnSelectionChangeCallback = exports.getInitialData = exports.resolveInitialBackCount = exports.addFlexDirectionStyle = exports.callReset = exports.callNativeNotifyDataChange = exports.callNativeSetOverflowItemsVisible = exports.callNativeSetSelectedItem = exports.callNativeEnableInputEvents = void 0;
|
|
9
9
|
const react_native_1 = require("react-native");
|
|
10
10
|
const CarouselScrollableTypes_1 = require("../CarouselScrollableTypes");
|
|
11
11
|
const CarouselNativeHostComponent_1 = require("./CarouselNativeHostComponent");
|
|
@@ -154,6 +154,63 @@ function addFlexDirectionStyle(baseStyle, orientation) {
|
|
|
154
154
|
: FlexDirectionColumn);
|
|
155
155
|
}
|
|
156
156
|
exports.addFlexDirectionStyle = addFlexDirectionStyle;
|
|
157
|
+
/**
|
|
158
|
+
* Resolves how many items {@link getInitialData} should place **before** the
|
|
159
|
+
* `initialStartIndex` in the initial render window.
|
|
160
|
+
*
|
|
161
|
+
* For {@link ListSelectionStrategy.ANCHORED} and
|
|
162
|
+
* {@link ListSelectionStrategy.NATURAL}, the initial pool is a leading-margin
|
|
163
|
+
* window, so the back count is simply `numOffsetItems` (the historical
|
|
164
|
+
* behavior).
|
|
165
|
+
*
|
|
166
|
+
* For {@link ListSelectionStrategy.PINNED} the native layer redistributes the
|
|
167
|
+
* initial pool so the selected item rests at its pin proportion. If JS resolves
|
|
168
|
+
* a different window than native pins to, the leading pin-window frames native
|
|
169
|
+
* wants were never sent by JS, so native fires an async `bindTo` roundtrip to
|
|
170
|
+
* refill them — a visible pop-in on the leading side (VEGATV-116583). To stay
|
|
171
|
+
* in lockstep this MIRRORS native `computePinnedPoolStart`'s `itemsBefore`
|
|
172
|
+
* exactly:
|
|
173
|
+
*
|
|
174
|
+
* pool = min(renderedItemsCount, itemCount) // native items_.size()
|
|
175
|
+
* itemsBefore = clamp(floor(pool * pin), minBefore, maxBefore)
|
|
176
|
+
* minBefore = (hasDataBefore && pool > 2) ? 1 : 0
|
|
177
|
+
* maxBefore = (hasDataAfter && pool > 2) ? pool - 2 : pool - 1
|
|
178
|
+
*
|
|
179
|
+
* A plain `min(floor(pool*pin), pool-1)` diverges from native at the extremes
|
|
180
|
+
* (e.g. pool 8 pin 0.9 → JS 7 vs native 6; pin 0.0 mid-list → JS 0 vs native 1),
|
|
181
|
+
* and that off-by-one frame is exactly the leading frame native would then have
|
|
182
|
+
* to bind async — the roundtrip this change removes. Center pins already match;
|
|
183
|
+
* mirroring the clamp closes the extremes.
|
|
184
|
+
*
|
|
185
|
+
* @param {ListSelectionStrategy} selectionStrategy The list's selection strategy.
|
|
186
|
+
* @param {number} renderedItemsCount The configured render window size.
|
|
187
|
+
* @param {number} numOffsetItems The leading-margin back count used for the
|
|
188
|
+
* non-pinned strategies.
|
|
189
|
+
* @param {number} pinnedFocusOffset The resolved pin proportion (0.0 - 1.0);
|
|
190
|
+
* only used when `selectionStrategy` is `PINNED`.
|
|
191
|
+
* @param {number} initialStartIndex The selected data index at mount (used to
|
|
192
|
+
* detect whether data exists before/after, matching native).
|
|
193
|
+
* @param {number} itemCount Total number of items in the data set.
|
|
194
|
+
*
|
|
195
|
+
* @return {number} The number of items to resolve before `initialStartIndex`.
|
|
196
|
+
*/
|
|
197
|
+
function resolveInitialBackCount(selectionStrategy, renderedItemsCount, numOffsetItems, pinnedFocusOffset, initialStartIndex, itemCount) {
|
|
198
|
+
if (selectionStrategy !== CarouselScrollableTypes_1.ListSelectionStrategy.PINNED) {
|
|
199
|
+
return numOffsetItems;
|
|
200
|
+
}
|
|
201
|
+
// Pool = the number of frames native actually renders (native items_.size()).
|
|
202
|
+
const pool = Math.min(renderedItemsCount, itemCount);
|
|
203
|
+
const rawItemsBefore = Math.floor(pool * pinnedFocusOffset);
|
|
204
|
+
const hasDataBefore = initialStartIndex > 0;
|
|
205
|
+
const hasDataAfter = initialStartIndex < itemCount - 1;
|
|
206
|
+
// The pool > 2 guard matches native (prevents an inverted [minBefore, maxBefore] range for
|
|
207
|
+
// tiny pools, i.e. minBefore > maxBefore).
|
|
208
|
+
const minBefore = hasDataBefore && pool > 2 ? 1 : 0;
|
|
209
|
+
const maxBefore = hasDataAfter && pool > 2 ? pool - 2 : pool - 1;
|
|
210
|
+
// std::clamp(v, lo, hi) == min(max(v, lo), hi)
|
|
211
|
+
return Math.min(Math.max(rawItemsBefore, minBefore), maxBefore);
|
|
212
|
+
}
|
|
213
|
+
exports.resolveInitialBackCount = resolveInitialBackCount;
|
|
157
214
|
/**
|
|
158
215
|
* This function is the core logic to retrieve items on the {@link CarouselScrollable}
|
|
159
216
|
* initial render.
|
|
@@ -51,10 +51,21 @@ function CarouselNativeInner(rawProps, ref) {
|
|
|
51
51
|
const dataAdapter = (0, CarouselScrollableProps_1.getDataAdapter)(props);
|
|
52
52
|
const hostRef = react_1.default.useRef(null);
|
|
53
53
|
const [childrenStates] = react_1.default.useState(new Map());
|
|
54
|
-
const { style, uniqueId, initialStartIndex, orientation, renderedItemsCount, numOffsetItems, showSelectionBorder, selectionBorderStyle, selectionBorderStrategy, focusedItemScaleFactor, pressedItemScaleFactor, shiftItemsOnSelection, renderItem, onItemBind, onItemUnbind, onSelectionChanged, } = props;
|
|
54
|
+
const { style, uniqueId, initialStartIndex, orientation, renderedItemsCount, numOffsetItems, selectionStrategy, pinnedFocusOffset, showSelectionBorder, selectionBorderStyle, selectionBorderStrategy, focusedItemScaleFactor, pressedItemScaleFactor, shiftItemsOnSelection, renderItem, onItemBind, onItemUnbind, onSelectionChanged, } = props;
|
|
55
55
|
const initialStartIndexInternal = react_1.default.useMemo(() => initialStartIndex < dataAdapter.getItemCount()
|
|
56
56
|
? initialStartIndex
|
|
57
57
|
: Math.max(0, dataAdapter.getItemCount() - 1), [initialStartIndex, dataAdapter]);
|
|
58
|
+
// For PINNED, resolve the same pin-centered window native binds to on mount so
|
|
59
|
+
// the leading pin-window frames are already in initialData and native never has
|
|
60
|
+
// to fire an async bindTo roundtrip to refill them (VEGATV-116583).
|
|
61
|
+
const initialBackCount = react_1.default.useMemo(() => (0, CarouselNativeLogic_1.resolveInitialBackCount)(selectionStrategy, renderedItemsCount, numOffsetItems, pinnedFocusOffset, initialStartIndexInternal, dataAdapter.getItemCount()), [
|
|
62
|
+
selectionStrategy,
|
|
63
|
+
renderedItemsCount,
|
|
64
|
+
numOffsetItems,
|
|
65
|
+
pinnedFocusOffset,
|
|
66
|
+
initialStartIndexInternal,
|
|
67
|
+
dataAdapter,
|
|
68
|
+
]);
|
|
58
69
|
// Activation animations on the native layer assume pressedItemScaleFactor is based on the unselected dimensions of an item.
|
|
59
70
|
// However, the prop for this wrapper is documented to be based on the selected dimensions to better align with specs given by BXT.
|
|
60
71
|
// This means that if a partner passes an pressedItemScaleFactor of 0.94 and a focusedItemScaleFactor of 1.4, when an item is pressed it should
|
|
@@ -86,13 +97,13 @@ function CarouselNativeInner(rawProps, ref) {
|
|
|
86
97
|
const styleWithFlexDirection = react_1.default.useMemo(() => (0, CarouselNativeLogic_1.addFlexDirectionStyle)(style, orientation), [style, orientation]);
|
|
87
98
|
let initialData = lastInitialData.current && lastInitialData.current.length !== 0
|
|
88
99
|
? lastInitialData.current
|
|
89
|
-
: (0, CarouselNativeLogic_1.getInitialData)(dataAdapter, renderItem, initialStartIndexInternal,
|
|
100
|
+
: (0, CarouselNativeLogic_1.getInitialData)(dataAdapter, renderItem, initialStartIndexInternal, initialBackCount, renderedFrames.current);
|
|
90
101
|
if (!lastParentId.current || !lastInitialData.current) {
|
|
91
102
|
lastParentId.current = uniqueId;
|
|
92
103
|
lastInitialData.current = initialData;
|
|
93
104
|
}
|
|
94
105
|
if (lastParentId.current !== uniqueId) {
|
|
95
|
-
initialData = (0, CarouselNativeLogic_1.getInitialData)(dataAdapter, renderItem, initialStartIndexInternal,
|
|
106
|
+
initialData = (0, CarouselNativeLogic_1.getInitialData)(dataAdapter, renderItem, initialStartIndexInternal, initialBackCount, renderedFrames.current);
|
|
96
107
|
lastParentId.current = uniqueId;
|
|
97
108
|
lastInitialData.current = initialData;
|
|
98
109
|
}
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/package.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"name": "@amazon-devices/vega-carousel", "version": "0.2.
|
|
1
|
+
{"name": "@amazon-devices/vega-carousel", "version": "0.2.5", "main": "dist/index.js", "types": "dist/index.d.ts", "files": ["dist", "react-native.config.js", "THIRD_PARTY_NOTICES.txt"], "scripts": {"clean": "rm -rf build dist generated logs node_modules", "test:snapshot": "jest --colors --updateSnapshot", "start": "node node_modules/react-native/local-cli/cli.js start", "test": "jest --colors", "lint": "eslint src --ext .ts,.tsx", "lint:fix": "eslint src --ext .ts,.tsx --fix", "lint-staged": "lint-staged --allow-empty", "format": "clang-format -i --glob=\"native/**/*.{cpp,h}\"", "git-commit-template": "git-commit-template .git-commit-template", "compile": "tsc -p tsconfig-build.json", "build": "npm-run-all format compile"}, "dependencies": {"@amazon-devices/react-native-kepler": "^2.0.0", "ansi-colors": "^4.1.3", "react": "^18.2.0", "react-native": "^0.72.0", "recyclerlistview": "4.2.1"}, "devDependencies": {"@babel/core": "^7.20.0", "@babel/plugin-transform-private-methods": "^7.23.3", "@babel/runtime": "^7.20.0", "@bam.tech/jest-junit-reports-merger": "^1.1.0", "@react-native-community/eslint-config": "^3.2.0", "@testing-library/jest-native": "^5.4.3", "@testing-library/react-native": "^11.5.4", "@types/jest": "^28.0.0", "@types/react-test-renderer": "^18.0.0", "@typescript-eslint/eslint-plugin": "^5.18.0", "babel-jest": "^28.0.0", "clang-format": "^1.8.0", "eslint": "^8.19.0", "eslint-plugin-react-native": "^4.1.0", "git-commit-template": "^1.0.5", "lint-staged": "^12.3.7", "jest": "^28.0.0", "jest-junit": "^16.0.0", "metro-react-native-babel-preset": "^0.76.5", "npm-run-all": "^4.1.5", "prettier": "^3.0.0", "react": "^18.2.0", "react-native": "^0.72.0", "react-test-renderer": "18.2.0", "ts-jest": "^28.0.0", "typedoc": "^0.25.7", "typescript": "4.9.5", "@amazon-devices/kepler-cli-platform": "^0", "@react-native-community/cli": "^11.2.0"}, "resolutions": {"@types/react": "^18"}, "peerDependencies": {"react": "^18.2.0", "react-native": "^0.72.0"}, "kepler": {"projectType": "turbomodule", "toolchain": "clang", "targets": ["tv"], "os": ["vega"]}, "eslintConfig": {"extends": "@react-native-community", "parser": "@typescript-eslint/parser", "plugins": ["@typescript-eslint"], "root": true}, "prettier": {"arrowParens": "avoid", "bracketSameLine": true, "bracketSpacing": false, "singleQuote": true, "trailingComma": "all"}, "npm-pretty-much": {"allowUnsafeName": "reason for using a unsafe name"}, "license": "See license in LICENSE"}
|