@xhub-reels/sdk 0.1.19 → 0.1.21
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/index.cjs +53 -100
- package/dist/index.js +53 -100
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -1624,43 +1624,6 @@ function DefaultSkeleton() {
|
|
|
1624
1624
|
}
|
|
1625
1625
|
}
|
|
1626
1626
|
),
|
|
1627
|
-
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
1628
|
-
"div",
|
|
1629
|
-
{
|
|
1630
|
-
style: {
|
|
1631
|
-
position: "absolute",
|
|
1632
|
-
bottom: 100,
|
|
1633
|
-
left: 16,
|
|
1634
|
-
display: "flex",
|
|
1635
|
-
flexDirection: "column",
|
|
1636
|
-
gap: 8
|
|
1637
|
-
},
|
|
1638
|
-
children: [
|
|
1639
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { style: skeletonBar(120, 14) }),
|
|
1640
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { style: skeletonBar(200, 12) }),
|
|
1641
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { style: skeletonBar(160, 12) })
|
|
1642
|
-
]
|
|
1643
|
-
}
|
|
1644
|
-
),
|
|
1645
|
-
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
1646
|
-
"div",
|
|
1647
|
-
{
|
|
1648
|
-
style: {
|
|
1649
|
-
position: "absolute",
|
|
1650
|
-
bottom: 100,
|
|
1651
|
-
right: 16,
|
|
1652
|
-
display: "flex",
|
|
1653
|
-
flexDirection: "column",
|
|
1654
|
-
gap: 20,
|
|
1655
|
-
alignItems: "center"
|
|
1656
|
-
},
|
|
1657
|
-
children: [
|
|
1658
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { style: skeletonCircle(40) }),
|
|
1659
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { style: skeletonCircle(40) }),
|
|
1660
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { style: skeletonCircle(40) })
|
|
1661
|
-
]
|
|
1662
|
-
}
|
|
1663
|
-
),
|
|
1664
1627
|
/* @__PURE__ */ jsxRuntime.jsx("style", { children: `
|
|
1665
1628
|
@keyframes reels-sdk-shimmer {
|
|
1666
1629
|
0% { transform: translateX(-100%); }
|
|
@@ -1671,22 +1634,6 @@ function DefaultSkeleton() {
|
|
|
1671
1634
|
}
|
|
1672
1635
|
);
|
|
1673
1636
|
}
|
|
1674
|
-
function skeletonBar(width, height) {
|
|
1675
|
-
return {
|
|
1676
|
-
width,
|
|
1677
|
-
height,
|
|
1678
|
-
borderRadius: height / 2,
|
|
1679
|
-
background: "rgba(255,255,255,0.1)"
|
|
1680
|
-
};
|
|
1681
|
-
}
|
|
1682
|
-
function skeletonCircle(size) {
|
|
1683
|
-
return {
|
|
1684
|
-
width: size,
|
|
1685
|
-
height: size,
|
|
1686
|
-
borderRadius: "50%",
|
|
1687
|
-
background: "rgba(255,255,255,0.1)"
|
|
1688
|
-
};
|
|
1689
|
-
}
|
|
1690
1637
|
function DefaultPauseAction() {
|
|
1691
1638
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
1692
1639
|
"div",
|
|
@@ -1723,8 +1670,8 @@ function DefaultPauseAction() {
|
|
|
1723
1670
|
}
|
|
1724
1671
|
);
|
|
1725
1672
|
}
|
|
1726
|
-
var PLAY_AHEAD_MAX_CONCURRENT =
|
|
1727
|
-
var PLAY_AHEAD_STAGGER_MS =
|
|
1673
|
+
var PLAY_AHEAD_MAX_CONCURRENT = 2;
|
|
1674
|
+
var PLAY_AHEAD_STAGGER_MS = 80;
|
|
1728
1675
|
var _playAheadActive = 0;
|
|
1729
1676
|
var _playAheadQueue = [];
|
|
1730
1677
|
function acquirePlayAhead() {
|
|
@@ -1733,9 +1680,8 @@ function acquirePlayAhead() {
|
|
|
1733
1680
|
return Promise.resolve();
|
|
1734
1681
|
}
|
|
1735
1682
|
return new Promise((resolve) => {
|
|
1736
|
-
const queuePosition = _playAheadQueue.length;
|
|
1737
1683
|
_playAheadQueue.push(() => {
|
|
1738
|
-
setTimeout(resolve, PLAY_AHEAD_STAGGER_MS
|
|
1684
|
+
setTimeout(resolve, PLAY_AHEAD_STAGGER_MS);
|
|
1739
1685
|
});
|
|
1740
1686
|
});
|
|
1741
1687
|
}
|
|
@@ -2149,38 +2095,40 @@ function VideoSlotInner({
|
|
|
2149
2095
|
children: renderPauseAction ? renderPauseAction(item, pauseActions) : /* @__PURE__ */ jsxRuntime.jsx(DefaultPauseAction, {})
|
|
2150
2096
|
}
|
|
2151
2097
|
),
|
|
2152
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2153
|
-
"
|
|
2154
|
-
|
|
2155
|
-
|
|
2156
|
-
|
|
2157
|
-
|
|
2158
|
-
|
|
2159
|
-
|
|
2160
|
-
|
|
2161
|
-
|
|
2162
|
-
|
|
2163
|
-
|
|
2164
|
-
|
|
2165
|
-
|
|
2166
|
-
|
|
2167
|
-
|
|
2168
|
-
|
|
2169
|
-
|
|
2170
|
-
|
|
2171
|
-
|
|
2172
|
-
|
|
2173
|
-
|
|
2174
|
-
|
|
2175
|
-
|
|
2176
|
-
|
|
2177
|
-
|
|
2178
|
-
|
|
2179
|
-
|
|
2180
|
-
|
|
2181
|
-
|
|
2182
|
-
|
|
2183
|
-
|
|
2098
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { style: {
|
|
2099
|
+
position: "absolute",
|
|
2100
|
+
bottom: 0,
|
|
2101
|
+
left: 0,
|
|
2102
|
+
right: 0,
|
|
2103
|
+
top: 0,
|
|
2104
|
+
zIndex: 1e3
|
|
2105
|
+
}, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { style: {
|
|
2106
|
+
position: "relative",
|
|
2107
|
+
width: "100%",
|
|
2108
|
+
height: "100%"
|
|
2109
|
+
}, children: [
|
|
2110
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2111
|
+
"div",
|
|
2112
|
+
{
|
|
2113
|
+
style: {
|
|
2114
|
+
background: "linear-gradient(to bottom, transparent, rgba(0,0,0,0.5))",
|
|
2115
|
+
position: "absolute",
|
|
2116
|
+
width: "100%",
|
|
2117
|
+
height: "30%",
|
|
2118
|
+
bottom: 0,
|
|
2119
|
+
left: 0
|
|
2120
|
+
}
|
|
2121
|
+
}
|
|
2122
|
+
),
|
|
2123
|
+
renderOverlay ? renderOverlay(item, actions) : /* @__PURE__ */ jsxRuntime.jsx(DefaultOverlay, { item }),
|
|
2124
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2125
|
+
"div",
|
|
2126
|
+
{
|
|
2127
|
+
onClick: (e) => e.stopPropagation(),
|
|
2128
|
+
children: renderActions ? renderActions(item, actions) : /* @__PURE__ */ jsxRuntime.jsx(DefaultActions, { item, actions })
|
|
2129
|
+
}
|
|
2130
|
+
)
|
|
2131
|
+
] }) }),
|
|
2184
2132
|
showFps && /* @__PURE__ */ jsxRuntime.jsx(FpsCounter, {})
|
|
2185
2133
|
]
|
|
2186
2134
|
}
|
|
@@ -2270,7 +2218,6 @@ function ReelsFeed({
|
|
|
2270
2218
|
const slotCacheRef = react.useRef(/* @__PURE__ */ new Map());
|
|
2271
2219
|
const activeIndexRef = react.useRef(0);
|
|
2272
2220
|
activeIndexRef.current = focusedIndex;
|
|
2273
|
-
const [isSnapping, setIsSnapping] = react.useState(false);
|
|
2274
2221
|
const { animateSnap, animateBounceBack, cancelAnimation } = useSnapAnimation({
|
|
2275
2222
|
duration: snapConfig?.duration ?? 260,
|
|
2276
2223
|
easing: snapConfig?.easing ?? "cubic-bezier(0.25, 0.46, 0.45, 0.94)"
|
|
@@ -2376,13 +2323,7 @@ function ReelsFeed({
|
|
|
2376
2323
|
return;
|
|
2377
2324
|
}
|
|
2378
2325
|
cancelAnimation();
|
|
2379
|
-
setIsSnapping(true);
|
|
2380
2326
|
setPrefetchIndex(null);
|
|
2381
|
-
setFocusedIndexImmediate(next);
|
|
2382
|
-
const nextItem = items[next];
|
|
2383
|
-
if (nextItem) {
|
|
2384
|
-
onSlotChange?.(next, nextItem, current);
|
|
2385
|
-
}
|
|
2386
2327
|
const h = containerHeight.current;
|
|
2387
2328
|
const targets = [];
|
|
2388
2329
|
for (const [idx, el] of slotCacheRef.current) {
|
|
@@ -2393,7 +2334,13 @@ function ReelsFeed({
|
|
|
2393
2334
|
});
|
|
2394
2335
|
}
|
|
2395
2336
|
animateSnap(targets);
|
|
2396
|
-
|
|
2337
|
+
requestAnimationFrame(() => {
|
|
2338
|
+
setFocusedIndexImmediate(next);
|
|
2339
|
+
const nextItem = items[next];
|
|
2340
|
+
if (nextItem) {
|
|
2341
|
+
onSlotChange?.(next, nextItem, current);
|
|
2342
|
+
}
|
|
2343
|
+
});
|
|
2397
2344
|
},
|
|
2398
2345
|
[items, animateSnap, animateBounceBack, cancelAnimation, setFocusedIndexImmediate, setPrefetchIndex, onSlotChange]
|
|
2399
2346
|
);
|
|
@@ -2415,13 +2362,13 @@ function ReelsFeed({
|
|
|
2415
2362
|
setIsDragMuted(true);
|
|
2416
2363
|
}, []);
|
|
2417
2364
|
const handleDragEnd = react.useCallback(() => {
|
|
2418
|
-
setTimeout(() => setIsDragMuted(false),
|
|
2365
|
+
setTimeout(() => setIsDragMuted(false), 300);
|
|
2419
2366
|
}, []);
|
|
2420
2367
|
const { bind } = usePointerGesture({
|
|
2421
2368
|
axis: "y",
|
|
2422
2369
|
velocityThreshold: gestureConfig?.velocityThreshold ?? 0.3,
|
|
2423
2370
|
distanceThreshold: gestureConfig?.distanceThreshold ?? 80,
|
|
2424
|
-
disabled:
|
|
2371
|
+
disabled: false,
|
|
2425
2372
|
containerSize: containerHeight.current,
|
|
2426
2373
|
dragThresholdRatio: gestureConfig?.dragThresholdRatio ?? 0.5,
|
|
2427
2374
|
onDragOffset: (offset) => {
|
|
@@ -2495,7 +2442,13 @@ function ReelsFeed({
|
|
|
2495
2442
|
const wrapperStyle = {
|
|
2496
2443
|
position: "absolute",
|
|
2497
2444
|
inset: 0,
|
|
2498
|
-
|
|
2445
|
+
// Fix 4: 'strict' = layout + style + paint + size containment.
|
|
2446
|
+
// Tells browser this slot is fully self-contained — no layout
|
|
2447
|
+
// escapes to parent. Eliminates layout thrash during animation.
|
|
2448
|
+
contain: "strict",
|
|
2449
|
+
// Fix 4: willChange only on active ±1 (3 slots max).
|
|
2450
|
+
// Previously ±1 already, keep it. Avoids unnecessary GPU layers
|
|
2451
|
+
// on warm/cold slots that are never animated directly.
|
|
2499
2452
|
willChange: distFromFocus <= 1 ? "transform" : "auto",
|
|
2500
2453
|
transform: getInitialTransformPx(index)
|
|
2501
2454
|
};
|
package/dist/index.js
CHANGED
|
@@ -1618,43 +1618,6 @@ function DefaultSkeleton() {
|
|
|
1618
1618
|
}
|
|
1619
1619
|
}
|
|
1620
1620
|
),
|
|
1621
|
-
/* @__PURE__ */ jsxs(
|
|
1622
|
-
"div",
|
|
1623
|
-
{
|
|
1624
|
-
style: {
|
|
1625
|
-
position: "absolute",
|
|
1626
|
-
bottom: 100,
|
|
1627
|
-
left: 16,
|
|
1628
|
-
display: "flex",
|
|
1629
|
-
flexDirection: "column",
|
|
1630
|
-
gap: 8
|
|
1631
|
-
},
|
|
1632
|
-
children: [
|
|
1633
|
-
/* @__PURE__ */ jsx("div", { style: skeletonBar(120, 14) }),
|
|
1634
|
-
/* @__PURE__ */ jsx("div", { style: skeletonBar(200, 12) }),
|
|
1635
|
-
/* @__PURE__ */ jsx("div", { style: skeletonBar(160, 12) })
|
|
1636
|
-
]
|
|
1637
|
-
}
|
|
1638
|
-
),
|
|
1639
|
-
/* @__PURE__ */ jsxs(
|
|
1640
|
-
"div",
|
|
1641
|
-
{
|
|
1642
|
-
style: {
|
|
1643
|
-
position: "absolute",
|
|
1644
|
-
bottom: 100,
|
|
1645
|
-
right: 16,
|
|
1646
|
-
display: "flex",
|
|
1647
|
-
flexDirection: "column",
|
|
1648
|
-
gap: 20,
|
|
1649
|
-
alignItems: "center"
|
|
1650
|
-
},
|
|
1651
|
-
children: [
|
|
1652
|
-
/* @__PURE__ */ jsx("div", { style: skeletonCircle(40) }),
|
|
1653
|
-
/* @__PURE__ */ jsx("div", { style: skeletonCircle(40) }),
|
|
1654
|
-
/* @__PURE__ */ jsx("div", { style: skeletonCircle(40) })
|
|
1655
|
-
]
|
|
1656
|
-
}
|
|
1657
|
-
),
|
|
1658
1621
|
/* @__PURE__ */ jsx("style", { children: `
|
|
1659
1622
|
@keyframes reels-sdk-shimmer {
|
|
1660
1623
|
0% { transform: translateX(-100%); }
|
|
@@ -1665,22 +1628,6 @@ function DefaultSkeleton() {
|
|
|
1665
1628
|
}
|
|
1666
1629
|
);
|
|
1667
1630
|
}
|
|
1668
|
-
function skeletonBar(width, height) {
|
|
1669
|
-
return {
|
|
1670
|
-
width,
|
|
1671
|
-
height,
|
|
1672
|
-
borderRadius: height / 2,
|
|
1673
|
-
background: "rgba(255,255,255,0.1)"
|
|
1674
|
-
};
|
|
1675
|
-
}
|
|
1676
|
-
function skeletonCircle(size) {
|
|
1677
|
-
return {
|
|
1678
|
-
width: size,
|
|
1679
|
-
height: size,
|
|
1680
|
-
borderRadius: "50%",
|
|
1681
|
-
background: "rgba(255,255,255,0.1)"
|
|
1682
|
-
};
|
|
1683
|
-
}
|
|
1684
1631
|
function DefaultPauseAction() {
|
|
1685
1632
|
return /* @__PURE__ */ jsx(
|
|
1686
1633
|
"div",
|
|
@@ -1717,8 +1664,8 @@ function DefaultPauseAction() {
|
|
|
1717
1664
|
}
|
|
1718
1665
|
);
|
|
1719
1666
|
}
|
|
1720
|
-
var PLAY_AHEAD_MAX_CONCURRENT =
|
|
1721
|
-
var PLAY_AHEAD_STAGGER_MS =
|
|
1667
|
+
var PLAY_AHEAD_MAX_CONCURRENT = 2;
|
|
1668
|
+
var PLAY_AHEAD_STAGGER_MS = 80;
|
|
1722
1669
|
var _playAheadActive = 0;
|
|
1723
1670
|
var _playAheadQueue = [];
|
|
1724
1671
|
function acquirePlayAhead() {
|
|
@@ -1727,9 +1674,8 @@ function acquirePlayAhead() {
|
|
|
1727
1674
|
return Promise.resolve();
|
|
1728
1675
|
}
|
|
1729
1676
|
return new Promise((resolve) => {
|
|
1730
|
-
const queuePosition = _playAheadQueue.length;
|
|
1731
1677
|
_playAheadQueue.push(() => {
|
|
1732
|
-
setTimeout(resolve, PLAY_AHEAD_STAGGER_MS
|
|
1678
|
+
setTimeout(resolve, PLAY_AHEAD_STAGGER_MS);
|
|
1733
1679
|
});
|
|
1734
1680
|
});
|
|
1735
1681
|
}
|
|
@@ -2143,38 +2089,40 @@ function VideoSlotInner({
|
|
|
2143
2089
|
children: renderPauseAction ? renderPauseAction(item, pauseActions) : /* @__PURE__ */ jsx(DefaultPauseAction, {})
|
|
2144
2090
|
}
|
|
2145
2091
|
),
|
|
2146
|
-
/* @__PURE__ */ jsx(
|
|
2147
|
-
"
|
|
2148
|
-
|
|
2149
|
-
|
|
2150
|
-
|
|
2151
|
-
|
|
2152
|
-
|
|
2153
|
-
|
|
2154
|
-
|
|
2155
|
-
|
|
2156
|
-
|
|
2157
|
-
|
|
2158
|
-
|
|
2159
|
-
|
|
2160
|
-
|
|
2161
|
-
|
|
2162
|
-
|
|
2163
|
-
|
|
2164
|
-
|
|
2165
|
-
|
|
2166
|
-
|
|
2167
|
-
|
|
2168
|
-
|
|
2169
|
-
|
|
2170
|
-
|
|
2171
|
-
|
|
2172
|
-
|
|
2173
|
-
|
|
2174
|
-
|
|
2175
|
-
|
|
2176
|
-
|
|
2177
|
-
|
|
2092
|
+
/* @__PURE__ */ jsx("div", { style: {
|
|
2093
|
+
position: "absolute",
|
|
2094
|
+
bottom: 0,
|
|
2095
|
+
left: 0,
|
|
2096
|
+
right: 0,
|
|
2097
|
+
top: 0,
|
|
2098
|
+
zIndex: 1e3
|
|
2099
|
+
}, children: /* @__PURE__ */ jsxs("div", { style: {
|
|
2100
|
+
position: "relative",
|
|
2101
|
+
width: "100%",
|
|
2102
|
+
height: "100%"
|
|
2103
|
+
}, children: [
|
|
2104
|
+
/* @__PURE__ */ jsx(
|
|
2105
|
+
"div",
|
|
2106
|
+
{
|
|
2107
|
+
style: {
|
|
2108
|
+
background: "linear-gradient(to bottom, transparent, rgba(0,0,0,0.5))",
|
|
2109
|
+
position: "absolute",
|
|
2110
|
+
width: "100%",
|
|
2111
|
+
height: "30%",
|
|
2112
|
+
bottom: 0,
|
|
2113
|
+
left: 0
|
|
2114
|
+
}
|
|
2115
|
+
}
|
|
2116
|
+
),
|
|
2117
|
+
renderOverlay ? renderOverlay(item, actions) : /* @__PURE__ */ jsx(DefaultOverlay, { item }),
|
|
2118
|
+
/* @__PURE__ */ jsx(
|
|
2119
|
+
"div",
|
|
2120
|
+
{
|
|
2121
|
+
onClick: (e) => e.stopPropagation(),
|
|
2122
|
+
children: renderActions ? renderActions(item, actions) : /* @__PURE__ */ jsx(DefaultActions, { item, actions })
|
|
2123
|
+
}
|
|
2124
|
+
)
|
|
2125
|
+
] }) }),
|
|
2178
2126
|
showFps && /* @__PURE__ */ jsx(FpsCounter, {})
|
|
2179
2127
|
]
|
|
2180
2128
|
}
|
|
@@ -2264,7 +2212,6 @@ function ReelsFeed({
|
|
|
2264
2212
|
const slotCacheRef = useRef(/* @__PURE__ */ new Map());
|
|
2265
2213
|
const activeIndexRef = useRef(0);
|
|
2266
2214
|
activeIndexRef.current = focusedIndex;
|
|
2267
|
-
const [isSnapping, setIsSnapping] = useState(false);
|
|
2268
2215
|
const { animateSnap, animateBounceBack, cancelAnimation } = useSnapAnimation({
|
|
2269
2216
|
duration: snapConfig?.duration ?? 260,
|
|
2270
2217
|
easing: snapConfig?.easing ?? "cubic-bezier(0.25, 0.46, 0.45, 0.94)"
|
|
@@ -2370,13 +2317,7 @@ function ReelsFeed({
|
|
|
2370
2317
|
return;
|
|
2371
2318
|
}
|
|
2372
2319
|
cancelAnimation();
|
|
2373
|
-
setIsSnapping(true);
|
|
2374
2320
|
setPrefetchIndex(null);
|
|
2375
|
-
setFocusedIndexImmediate(next);
|
|
2376
|
-
const nextItem = items[next];
|
|
2377
|
-
if (nextItem) {
|
|
2378
|
-
onSlotChange?.(next, nextItem, current);
|
|
2379
|
-
}
|
|
2380
2321
|
const h = containerHeight.current;
|
|
2381
2322
|
const targets = [];
|
|
2382
2323
|
for (const [idx, el] of slotCacheRef.current) {
|
|
@@ -2387,7 +2328,13 @@ function ReelsFeed({
|
|
|
2387
2328
|
});
|
|
2388
2329
|
}
|
|
2389
2330
|
animateSnap(targets);
|
|
2390
|
-
|
|
2331
|
+
requestAnimationFrame(() => {
|
|
2332
|
+
setFocusedIndexImmediate(next);
|
|
2333
|
+
const nextItem = items[next];
|
|
2334
|
+
if (nextItem) {
|
|
2335
|
+
onSlotChange?.(next, nextItem, current);
|
|
2336
|
+
}
|
|
2337
|
+
});
|
|
2391
2338
|
},
|
|
2392
2339
|
[items, animateSnap, animateBounceBack, cancelAnimation, setFocusedIndexImmediate, setPrefetchIndex, onSlotChange]
|
|
2393
2340
|
);
|
|
@@ -2409,13 +2356,13 @@ function ReelsFeed({
|
|
|
2409
2356
|
setIsDragMuted(true);
|
|
2410
2357
|
}, []);
|
|
2411
2358
|
const handleDragEnd = useCallback(() => {
|
|
2412
|
-
setTimeout(() => setIsDragMuted(false),
|
|
2359
|
+
setTimeout(() => setIsDragMuted(false), 300);
|
|
2413
2360
|
}, []);
|
|
2414
2361
|
const { bind } = usePointerGesture({
|
|
2415
2362
|
axis: "y",
|
|
2416
2363
|
velocityThreshold: gestureConfig?.velocityThreshold ?? 0.3,
|
|
2417
2364
|
distanceThreshold: gestureConfig?.distanceThreshold ?? 80,
|
|
2418
|
-
disabled:
|
|
2365
|
+
disabled: false,
|
|
2419
2366
|
containerSize: containerHeight.current,
|
|
2420
2367
|
dragThresholdRatio: gestureConfig?.dragThresholdRatio ?? 0.5,
|
|
2421
2368
|
onDragOffset: (offset) => {
|
|
@@ -2489,7 +2436,13 @@ function ReelsFeed({
|
|
|
2489
2436
|
const wrapperStyle = {
|
|
2490
2437
|
position: "absolute",
|
|
2491
2438
|
inset: 0,
|
|
2492
|
-
|
|
2439
|
+
// Fix 4: 'strict' = layout + style + paint + size containment.
|
|
2440
|
+
// Tells browser this slot is fully self-contained — no layout
|
|
2441
|
+
// escapes to parent. Eliminates layout thrash during animation.
|
|
2442
|
+
contain: "strict",
|
|
2443
|
+
// Fix 4: willChange only on active ±1 (3 slots max).
|
|
2444
|
+
// Previously ±1 already, keep it. Avoids unnecessary GPU layers
|
|
2445
|
+
// on warm/cold slots that are never animated directly.
|
|
2493
2446
|
willChange: distFromFocus <= 1 ? "transform" : "auto",
|
|
2494
2447
|
transform: getInitialTransformPx(index)
|
|
2495
2448
|
};
|