r3f-motion 1.0.8 → 1.0.10
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/cjs/index.js +16 -9
- package/dist/es/components/Carousel/index.mjs +16 -9
- package/dist/index.d.ts +2 -1
- package/package.json +1 -1
package/dist/cjs/index.js
CHANGED
|
@@ -1120,7 +1120,7 @@ function AnimatePresence({ children, mode = "sync", onExitComplete, custom, }) {
|
|
|
1120
1120
|
}
|
|
1121
1121
|
|
|
1122
1122
|
const DEFAULT_SPRING = {
|
|
1123
|
-
type:
|
|
1123
|
+
type: "spring",
|
|
1124
1124
|
stiffness: 600,
|
|
1125
1125
|
damping: 100,
|
|
1126
1126
|
restDelta: 0.001,
|
|
@@ -1139,7 +1139,7 @@ const CarouselSlotContext = react.createContext(null);
|
|
|
1139
1139
|
const useCarouselSlot = () => {
|
|
1140
1140
|
const ctx = react.useContext(CarouselSlotContext);
|
|
1141
1141
|
if (!ctx)
|
|
1142
|
-
throw new Error(
|
|
1142
|
+
throw new Error("useCarouselSlot must be used inside <Carousel>");
|
|
1143
1143
|
return ctx;
|
|
1144
1144
|
};
|
|
1145
1145
|
const CarouselSlot = react.memo(({ item, itemWidth, slotRef, visible }) => {
|
|
@@ -1161,14 +1161,17 @@ const CarouselSlot = react.memo(({ item, itemWidth, slotRef, visible }) => {
|
|
|
1161
1161
|
}, [itemWidth]);
|
|
1162
1162
|
// Dispose the generated geometry on unmount — useLayoutEffect's replacement
|
|
1163
1163
|
// logic only disposes the *previous* geometry, not the final one.
|
|
1164
|
-
react.useEffect(() => () => {
|
|
1164
|
+
react.useEffect(() => () => {
|
|
1165
|
+
var _a;
|
|
1166
|
+
(_a = coverRef.current) === null || _a === void 0 ? void 0 : _a.geometry.dispose();
|
|
1167
|
+
}, []);
|
|
1165
1168
|
// No onClick on the cover — the carousel's document-level capture listener
|
|
1166
1169
|
// handles click suppression. The cover stays as a drag hit-target so swiping
|
|
1167
1170
|
// works on slot regions where user content has gaps.
|
|
1168
1171
|
return (jsxRuntime.jsxs("group", { ref: slotRef, children: [jsxRuntime.jsx("group", { ref: contentRef, children: visible ? item : null }), jsxRuntime.jsxs("mesh", { ref: coverRef, children: [jsxRuntime.jsx("planeGeometry", { args: [itemWidth, itemWidth] }), jsxRuntime.jsx("meshBasicMaterial", { transparent: true, opacity: 0, depthWrite: false })] })] }));
|
|
1169
1172
|
});
|
|
1170
1173
|
const Carousel = (_a) => {
|
|
1171
|
-
var { items, itemWidth = 1.5, gap = 0.5, defaultValue = 0, transition = DEFAULT_SPRING, onSwitch, onDragStart, onDrag, onDragEnd, renderThreshold, dragThreshold = DRAG_THRESHOLD_RATIO, flickVelocity = FLICK_VELOCITY } = _a, props = tslib.__rest(_a, ["items", "itemWidth", "gap", "defaultValue", "transition", "onSwitch", "onDragStart", "onDrag", "onDragEnd", "renderThreshold", "dragThreshold", "flickVelocity"]);
|
|
1174
|
+
var { items, itemWidth = 1.5, gap = 0.5, defaultValue = 0, transition = DEFAULT_SPRING, onSwitch, onDragStart, onDrag, onDragEnd, renderThreshold, dragThreshold = DRAG_THRESHOLD_RATIO, flickVelocity = FLICK_VELOCITY, disable } = _a, props = tslib.__rest(_a, ["items", "itemWidth", "gap", "defaultValue", "transition", "onSwitch", "onDragStart", "onDrag", "onDragEnd", "renderThreshold", "dragThreshold", "flickVelocity", "disable"]);
|
|
1172
1175
|
const slideWidth = itemWidth + gap;
|
|
1173
1176
|
const count = items.length;
|
|
1174
1177
|
// Render twice the items and center on the first item of the second copy.
|
|
@@ -1236,8 +1239,8 @@ const Carousel = (_a) => {
|
|
|
1236
1239
|
e.stopPropagation();
|
|
1237
1240
|
}
|
|
1238
1241
|
};
|
|
1239
|
-
document.addEventListener(
|
|
1240
|
-
return () => document.removeEventListener(
|
|
1242
|
+
document.addEventListener("click", onClickCapture, true);
|
|
1243
|
+
return () => document.removeEventListener("click", onClickCapture, true);
|
|
1241
1244
|
}, []);
|
|
1242
1245
|
// Drag start: stop any in-flight snap and capture the slot we started on
|
|
1243
1246
|
// so an under-threshold release can elastic back to it.
|
|
@@ -1303,7 +1306,9 @@ const Carousel = (_a) => {
|
|
|
1303
1306
|
// one fades out — keeps the loop seamless mid-drag instead of waiting
|
|
1304
1307
|
// for snap to settle on an integer slot.
|
|
1305
1308
|
const slotDist = (groupX + ref.position.x) / slideWidth;
|
|
1306
|
-
const shouldBeVisible = renderThreshold
|
|
1309
|
+
const shouldBeVisible = renderThreshold
|
|
1310
|
+
? Math.abs(slotDist) <= renderThreshold + 0.5
|
|
1311
|
+
: true;
|
|
1307
1312
|
ref.visible = shouldBeVisible;
|
|
1308
1313
|
if (visibleMaskRef.current[i] !== shouldBeVisible) {
|
|
1309
1314
|
if (!nextMask)
|
|
@@ -1316,7 +1321,7 @@ const Carousel = (_a) => {
|
|
|
1316
1321
|
setVisibleMask(nextMask);
|
|
1317
1322
|
}
|
|
1318
1323
|
});
|
|
1319
|
-
return (jsxRuntime.jsx(motion.group, Object.assign({ ref: groupRef, drag: "x", dragMomentum: false, initial: initial }, props, { onDragStart: handleDragStart, onDragEnd: handleDragEnd, onDrag: (_e, info) => onDrag === null || onDrag === void 0 ? void 0 : onDrag(info), children: loopedItems.map((item, i) => {
|
|
1324
|
+
return (jsxRuntime.jsx(motion.group, Object.assign({ ref: groupRef, drag: disable ? false : "x", dragMomentum: false, initial: initial }, props, { onDragStart: handleDragStart, onDragEnd: handleDragEnd, onDrag: (_e, info) => onDrag === null || onDrag === void 0 ? void 0 : onDrag(info), children: loopedItems.map((item, i) => {
|
|
1320
1325
|
var _a;
|
|
1321
1326
|
const raw = i - currentSlot;
|
|
1322
1327
|
const halfWrap = (((raw + slotCount / 2) % slotCount) + slotCount) % slotCount;
|
|
@@ -1328,7 +1333,9 @@ const Carousel = (_a) => {
|
|
|
1328
1333
|
isActive: distance === 0,
|
|
1329
1334
|
isNearby: distance <= 1,
|
|
1330
1335
|
currIndex,
|
|
1331
|
-
}, children: jsxRuntime.jsx(CarouselSlot, { item: item, itemWidth: itemWidth, slotRef: (el) => {
|
|
1336
|
+
}, children: jsxRuntime.jsx(CarouselSlot, { item: item, itemWidth: itemWidth, slotRef: (el) => {
|
|
1337
|
+
itemRefs.current[i] = el;
|
|
1338
|
+
}, visible: (_a = visibleMask[i]) !== null && _a !== void 0 ? _a : false }) }, `carouselItem-${i}`));
|
|
1332
1339
|
}) })));
|
|
1333
1340
|
};
|
|
1334
1341
|
var index = react.memo(Carousel);
|
|
@@ -8,7 +8,7 @@ import { useMotionValue, animate } from 'motion/react';
|
|
|
8
8
|
import { motion } from '../../render/motion.mjs';
|
|
9
9
|
|
|
10
10
|
const DEFAULT_SPRING = {
|
|
11
|
-
type:
|
|
11
|
+
type: "spring",
|
|
12
12
|
stiffness: 600,
|
|
13
13
|
damping: 100,
|
|
14
14
|
restDelta: 0.001,
|
|
@@ -27,7 +27,7 @@ const CarouselSlotContext = createContext(null);
|
|
|
27
27
|
const useCarouselSlot = () => {
|
|
28
28
|
const ctx = useContext(CarouselSlotContext);
|
|
29
29
|
if (!ctx)
|
|
30
|
-
throw new Error(
|
|
30
|
+
throw new Error("useCarouselSlot must be used inside <Carousel>");
|
|
31
31
|
return ctx;
|
|
32
32
|
};
|
|
33
33
|
const CarouselSlot = memo(({ item, itemWidth, slotRef, visible }) => {
|
|
@@ -49,14 +49,17 @@ const CarouselSlot = memo(({ item, itemWidth, slotRef, visible }) => {
|
|
|
49
49
|
}, [itemWidth]);
|
|
50
50
|
// Dispose the generated geometry on unmount — useLayoutEffect's replacement
|
|
51
51
|
// logic only disposes the *previous* geometry, not the final one.
|
|
52
|
-
useEffect(() => () => {
|
|
52
|
+
useEffect(() => () => {
|
|
53
|
+
var _a;
|
|
54
|
+
(_a = coverRef.current) === null || _a === void 0 ? void 0 : _a.geometry.dispose();
|
|
55
|
+
}, []);
|
|
53
56
|
// No onClick on the cover — the carousel's document-level capture listener
|
|
54
57
|
// handles click suppression. The cover stays as a drag hit-target so swiping
|
|
55
58
|
// works on slot regions where user content has gaps.
|
|
56
59
|
return (jsxs("group", { ref: slotRef, children: [jsx("group", { ref: contentRef, children: visible ? item : null }), jsxs("mesh", { ref: coverRef, children: [jsx("planeGeometry", { args: [itemWidth, itemWidth] }), jsx("meshBasicMaterial", { transparent: true, opacity: 0, depthWrite: false })] })] }));
|
|
57
60
|
});
|
|
58
61
|
const Carousel = (_a) => {
|
|
59
|
-
var { items, itemWidth = 1.5, gap = 0.5, defaultValue = 0, transition = DEFAULT_SPRING, onSwitch, onDragStart, onDrag, onDragEnd, renderThreshold, dragThreshold = DRAG_THRESHOLD_RATIO, flickVelocity = FLICK_VELOCITY } = _a, props = __rest(_a, ["items", "itemWidth", "gap", "defaultValue", "transition", "onSwitch", "onDragStart", "onDrag", "onDragEnd", "renderThreshold", "dragThreshold", "flickVelocity"]);
|
|
62
|
+
var { items, itemWidth = 1.5, gap = 0.5, defaultValue = 0, transition = DEFAULT_SPRING, onSwitch, onDragStart, onDrag, onDragEnd, renderThreshold, dragThreshold = DRAG_THRESHOLD_RATIO, flickVelocity = FLICK_VELOCITY, disable } = _a, props = __rest(_a, ["items", "itemWidth", "gap", "defaultValue", "transition", "onSwitch", "onDragStart", "onDrag", "onDragEnd", "renderThreshold", "dragThreshold", "flickVelocity", "disable"]);
|
|
60
63
|
const slideWidth = itemWidth + gap;
|
|
61
64
|
const count = items.length;
|
|
62
65
|
// Render twice the items and center on the first item of the second copy.
|
|
@@ -124,8 +127,8 @@ const Carousel = (_a) => {
|
|
|
124
127
|
e.stopPropagation();
|
|
125
128
|
}
|
|
126
129
|
};
|
|
127
|
-
document.addEventListener(
|
|
128
|
-
return () => document.removeEventListener(
|
|
130
|
+
document.addEventListener("click", onClickCapture, true);
|
|
131
|
+
return () => document.removeEventListener("click", onClickCapture, true);
|
|
129
132
|
}, []);
|
|
130
133
|
// Drag start: stop any in-flight snap and capture the slot we started on
|
|
131
134
|
// so an under-threshold release can elastic back to it.
|
|
@@ -191,7 +194,9 @@ const Carousel = (_a) => {
|
|
|
191
194
|
// one fades out — keeps the loop seamless mid-drag instead of waiting
|
|
192
195
|
// for snap to settle on an integer slot.
|
|
193
196
|
const slotDist = (groupX + ref.position.x) / slideWidth;
|
|
194
|
-
const shouldBeVisible = renderThreshold
|
|
197
|
+
const shouldBeVisible = renderThreshold
|
|
198
|
+
? Math.abs(slotDist) <= renderThreshold + 0.5
|
|
199
|
+
: true;
|
|
195
200
|
ref.visible = shouldBeVisible;
|
|
196
201
|
if (visibleMaskRef.current[i] !== shouldBeVisible) {
|
|
197
202
|
if (!nextMask)
|
|
@@ -204,7 +209,7 @@ const Carousel = (_a) => {
|
|
|
204
209
|
setVisibleMask(nextMask);
|
|
205
210
|
}
|
|
206
211
|
});
|
|
207
|
-
return (jsx(motion.group, Object.assign({ ref: groupRef, drag: "x", dragMomentum: false, initial: initial }, props, { onDragStart: handleDragStart, onDragEnd: handleDragEnd, onDrag: (_e, info) => onDrag === null || onDrag === void 0 ? void 0 : onDrag(info), children: loopedItems.map((item, i) => {
|
|
212
|
+
return (jsx(motion.group, Object.assign({ ref: groupRef, drag: disable ? false : "x", dragMomentum: false, initial: initial }, props, { onDragStart: handleDragStart, onDragEnd: handleDragEnd, onDrag: (_e, info) => onDrag === null || onDrag === void 0 ? void 0 : onDrag(info), children: loopedItems.map((item, i) => {
|
|
208
213
|
var _a;
|
|
209
214
|
const raw = i - currentSlot;
|
|
210
215
|
const halfWrap = (((raw + slotCount / 2) % slotCount) + slotCount) % slotCount;
|
|
@@ -216,7 +221,9 @@ const Carousel = (_a) => {
|
|
|
216
221
|
isActive: distance === 0,
|
|
217
222
|
isNearby: distance <= 1,
|
|
218
223
|
currIndex,
|
|
219
|
-
}, children: jsx(CarouselSlot, { item: item, itemWidth: itemWidth, slotRef: (el) => {
|
|
224
|
+
}, children: jsx(CarouselSlot, { item: item, itemWidth: itemWidth, slotRef: (el) => {
|
|
225
|
+
itemRefs.current[i] = el;
|
|
226
|
+
}, visible: (_a = visibleMask[i]) !== null && _a !== void 0 ? _a : false }) }, `carouselItem-${i}`));
|
|
220
227
|
}) })));
|
|
221
228
|
};
|
|
222
229
|
var index = memo(Carousel);
|
package/dist/index.d.ts
CHANGED
|
@@ -140,6 +140,7 @@ interface CarouselProps {
|
|
|
140
140
|
renderThreshold?: number;
|
|
141
141
|
dragThreshold?: number;
|
|
142
142
|
flickVelocity?: number;
|
|
143
|
+
disable?: boolean;
|
|
143
144
|
}
|
|
144
145
|
interface CarouselSlotInfo {
|
|
145
146
|
slotIndex: number;
|
|
@@ -150,7 +151,7 @@ interface CarouselSlotInfo {
|
|
|
150
151
|
isNearby: boolean;
|
|
151
152
|
}
|
|
152
153
|
declare const useCarouselSlot: () => CarouselSlotInfo;
|
|
153
|
-
declare const Carousel: ({ items, itemWidth, gap, defaultValue, transition, onSwitch, onDragStart, onDrag, onDragEnd, renderThreshold, dragThreshold, flickVelocity, ...props }: CarouselProps) => react_jsx_runtime.JSX.Element;
|
|
154
|
+
declare const Carousel: ({ items, itemWidth, gap, defaultValue, transition, onSwitch, onDragStart, onDrag, onDragEnd, renderThreshold, dragThreshold, flickVelocity, disable, ...props }: CarouselProps) => react_jsx_runtime.JSX.Element;
|
|
154
155
|
declare const _default: typeof Carousel;
|
|
155
156
|
|
|
156
157
|
export { AnimatePresence, _default as Carousel, MotionCamera, motion, useCarouselSlot, usePresence };
|
package/package.json
CHANGED