react-spring-carousel 1.9.29-beta1 → 1.9.29-beta13

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.es.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { jsx } from 'react/jsx-runtime';
2
- import { useRef, useEffect, createContext, useCallback, useContext, useState } from 'react';
3
- import { useSpring, animated, config, useTransition } from 'react-spring';
2
+ import { useRef, useEffect, forwardRef, createContext, useCallback, useContext, useState } from 'react';
3
+ import { animated, useSpring, config, useTransition } from 'react-spring';
4
4
  import { useDrag } from '@use-gesture/react';
5
5
  import { Subject } from 'rxjs';
6
6
  import screenfull from 'screenfull';
@@ -90,98 +90,140 @@ function getIsBrowser() {
90
90
  return typeof window !== 'undefined';
91
91
  }
92
92
 
93
- function useThumbsModule({ items, withThumbs, thumbsSlideAxis = 'x', springConfig, thumbsWrapperRef, prepareThumbsData, }) {
93
+ const InternalWrapper = forwardRef(({ children, ...rest }, ref) => {
94
+ return (jsx(animated.div, Object.assign({}, rest, { ref: ref }, { children: children }), void 0));
95
+ });
96
+ function useThumbsModule({ items, withThumbs, thumbsSlideAxis = 'x', springConfig, prepareThumbsData, itemsPerSlide, getFluidWrapperScrollValue = () => 0, getSlideValue = () => 0, CustomThumbsWrapperComponent, }) {
94
97
  const internalThumbsWrapperRef = useRef(null);
95
98
  const [thumbListStyles, setThumbListStyles] = useSpring(() => ({
96
- [thumbsSlideAxis]: 0,
99
+ x: 0,
100
+ y: 0,
97
101
  config: springConfig,
102
+ onChange: ({ value }) => {
103
+ if (internalThumbsWrapperRef.current) {
104
+ internalThumbsWrapperRef.current[thumbsSlideAxis === 'x' ? 'scrollLeft' : 'scrollTop'] = Math.abs(value[thumbsSlideAxis]);
105
+ }
106
+ },
98
107
  }));
99
108
  useMount(() => {
100
- if (withThumbs) {
101
- const missingThumbs = items.some(item => !item.renderThumb);
102
- if (missingThumbs) {
103
- throw new Error('The renderThumb property is missing in one or more items. You need to add the renderThumb property to every item of the carousel when the prop withThumbs={true} or eventually set withThumbs={false}.');
104
- }
109
+ if (withThumbs && !internalThumbsWrapperRef.current) {
110
+ throw new Error("The thumbs wrapper is not defined. If you've passed a Functional component, be sure to wrap your component in forwardRef.");
105
111
  }
106
112
  });
107
- function handleThumbsScroll(activeItem) {
108
- function getOffsetDirection() {
109
- return thumbsSlideAxis === 'x' ? 'offsetLeft' : 'offsetTop';
110
- }
111
- function getOffsetDimension() {
112
- return thumbsSlideAxis === 'x' ? 'offsetWidth' : 'offsetHeight';
113
- }
114
- function getScrollDirecton() {
115
- return thumbsSlideAxis === 'x' ? 'scrollLeft' : 'scrollTop';
116
- }
117
- function getThumbNode() {
118
- return internalThumbsWrapperRef.current.querySelector(`#thumb-${items[activeItem].id}`);
119
- }
120
- function getThumbOffsetPosition({ thumbNode, offsetDirection, offsetDimension, }) {
121
- return thumbNode[offsetDirection] + thumbNode[offsetDimension] / 2;
122
- }
123
- function getThumbScrollDimension({ thumbWrapper, offsetDimension, }) {
124
- return thumbWrapper[offsetDimension] / 2;
125
- }
126
- function getScrollFromValue({ thumbWrapper, scrollDirection, }) {
127
- return thumbWrapper[scrollDirection];
128
- }
129
- function getScrollToValue({ thumbWrapper, thumbOffsetPosition, thumbScrollDimension, offsetDimension, }) {
130
- const scrollDimensionProperty = thumbsSlideAxis === 'x' ? 'scrollWidth' : 'scrollHeight';
131
- if (activeItem === items.length - 1 ||
132
- thumbOffsetPosition - thumbScrollDimension >
133
- thumbWrapper[scrollDimensionProperty] - thumbWrapper[offsetDimension]) {
134
- return thumbWrapper[scrollDimensionProperty] - thumbWrapper[offsetDimension];
113
+ function getCurrentThumbScrollValue() {
114
+ return internalThumbsWrapperRef.current[thumbsSlideAxis === 'x' ? 'scrollLeft' : 'scrollTop'];
115
+ }
116
+ function getThumbsTotalScrollableValue() {
117
+ return Math.round(Number(internalThumbsWrapperRef.current?.[thumbsSlideAxis === 'x' ? 'scrollWidth' : 'scrollHeight']) -
118
+ internalThumbsWrapperRef.current.getBoundingClientRect()[thumbsSlideAxis === 'x' ? 'width' : 'height']);
119
+ }
120
+ function getThumbSlideValue() {
121
+ const thumbSlideTotal = Math.round(getFluidWrapperScrollValue() / getSlideValue());
122
+ const totalScrollableValue = getThumbsTotalScrollableValue();
123
+ return totalScrollableValue / thumbSlideTotal;
124
+ }
125
+ function handleThumbsScroll(activeItem, actionType) {
126
+ if (itemsPerSlide === 'fluid') {
127
+ const totalScrollableValue = getThumbsTotalScrollableValue();
128
+ if (actionType === 'next') {
129
+ const nextValue = getCurrentThumbScrollValue() + getThumbSlideValue();
130
+ setThumbListStyles.start({
131
+ from: {
132
+ [thumbsSlideAxis]: getCurrentThumbScrollValue(),
133
+ },
134
+ to: {
135
+ [thumbsSlideAxis]: nextValue > totalScrollableValue ? totalScrollableValue : nextValue,
136
+ },
137
+ });
135
138
  }
136
- if (activeItem === 0) {
137
- return 0;
139
+ if (actionType === 'prev') {
140
+ const nextValue = getCurrentThumbScrollValue() - getThumbSlideValue();
141
+ setThumbListStyles.start({
142
+ from: {
143
+ [thumbsSlideAxis]: getCurrentThumbScrollValue(),
144
+ },
145
+ to: {
146
+ [thumbsSlideAxis]: nextValue < 0 ? 0 : nextValue,
147
+ },
148
+ });
138
149
  }
139
- return thumbOffsetPosition - thumbScrollDimension;
140
150
  }
141
- if (thumbsWrapperRef && thumbsWrapperRef.current) {
142
- internalThumbsWrapperRef.current = thumbsWrapperRef.current;
143
- }
144
- const thumbNode = getThumbNode();
145
- if (thumbNode) {
146
- const thumbWrapper = internalThumbsWrapperRef.current;
147
- const offsetDirection = getOffsetDirection();
148
- const offsetDimension = getOffsetDimension();
149
- const scrollDirection = getScrollDirecton();
150
- const thumbOffsetPosition = getThumbOffsetPosition({
151
- thumbNode,
152
- offsetDimension,
153
- offsetDirection,
154
- });
155
- const thumbScrollDimension = getThumbScrollDimension({
156
- thumbWrapper,
157
- offsetDimension,
158
- });
159
- setThumbListStyles.start({
160
- from: {
161
- [thumbsSlideAxis]: getScrollFromValue({
162
- thumbWrapper,
163
- scrollDirection,
164
- }),
165
- },
166
- to: {
167
- [thumbsSlideAxis]: getScrollToValue({
168
- thumbWrapper,
169
- thumbOffsetPosition,
170
- thumbScrollDimension,
171
- offsetDimension,
172
- }),
173
- },
174
- onChange: val => {
175
- if (thumbsSlideAxis === 'x') {
176
- // @ts-ignore
177
- internalThumbsWrapperRef.current.scrollLeft = val.x;
178
- }
179
- else {
180
- // @ts-ignore
181
- internalThumbsWrapperRef.current.scrollTop = val.y;
182
- }
183
- },
184
- });
151
+ else {
152
+ function getOffsetDirection() {
153
+ return thumbsSlideAxis === 'x' ? 'offsetLeft' : 'offsetTop';
154
+ }
155
+ function getOffsetDimension() {
156
+ return thumbsSlideAxis === 'x' ? 'offsetWidth' : 'offsetHeight';
157
+ }
158
+ function getScrollDirecton() {
159
+ return thumbsSlideAxis === 'x' ? 'scrollLeft' : 'scrollTop';
160
+ }
161
+ function getThumbNode() {
162
+ return internalThumbsWrapperRef.current.querySelector(`#thumb-${items[activeItem].id}`);
163
+ }
164
+ function getThumbOffsetPosition({ thumbNode, offsetDirection, offsetDimension, }) {
165
+ return thumbNode[offsetDirection] + thumbNode[offsetDimension] / 2;
166
+ }
167
+ function getThumbScrollDimension({ thumbWrapper, offsetDimension, }) {
168
+ return thumbWrapper[offsetDimension] / 2;
169
+ }
170
+ function getScrollFromValue({ thumbWrapper, scrollDirection, }) {
171
+ return thumbWrapper[scrollDirection];
172
+ }
173
+ function getScrollToValue({ thumbWrapper, thumbOffsetPosition, thumbScrollDimension, offsetDimension, }) {
174
+ const scrollDimensionProperty = thumbsSlideAxis === 'x' ? 'scrollWidth' : 'scrollHeight';
175
+ if (activeItem === items.length - 1 ||
176
+ thumbOffsetPosition - thumbScrollDimension >
177
+ thumbWrapper[scrollDimensionProperty] - thumbWrapper[offsetDimension]) {
178
+ return thumbWrapper[scrollDimensionProperty] - thumbWrapper[offsetDimension];
179
+ }
180
+ if (activeItem === 0) {
181
+ return 0;
182
+ }
183
+ return thumbOffsetPosition - thumbScrollDimension;
184
+ }
185
+ const thumbNode = getThumbNode();
186
+ if (thumbNode) {
187
+ const thumbWrapper = internalThumbsWrapperRef.current;
188
+ const offsetDirection = getOffsetDirection();
189
+ const offsetDimension = getOffsetDimension();
190
+ const scrollDirection = getScrollDirecton();
191
+ const thumbOffsetPosition = getThumbOffsetPosition({
192
+ thumbNode,
193
+ offsetDimension,
194
+ offsetDirection,
195
+ });
196
+ const thumbScrollDimension = getThumbScrollDimension({
197
+ thumbWrapper,
198
+ offsetDimension,
199
+ });
200
+ setThumbListStyles.start({
201
+ from: {
202
+ [thumbsSlideAxis]: getScrollFromValue({
203
+ thumbWrapper,
204
+ scrollDirection,
205
+ }),
206
+ },
207
+ to: {
208
+ [thumbsSlideAxis]: getScrollToValue({
209
+ thumbWrapper,
210
+ thumbOffsetPosition,
211
+ thumbScrollDimension,
212
+ offsetDimension,
213
+ }),
214
+ },
215
+ onChange: val => {
216
+ if (thumbsSlideAxis === 'x') {
217
+ // @ts-ignore
218
+ internalThumbsWrapperRef.current.scrollLeft = val.x;
219
+ }
220
+ else {
221
+ // @ts-ignore
222
+ internalThumbsWrapperRef.current.scrollTop = val.y;
223
+ }
224
+ },
225
+ });
226
+ }
185
227
  }
186
228
  }
187
229
  function handlePrepareThumbsDate() {
@@ -196,19 +238,12 @@ function useThumbsModule({ items, withThumbs, thumbsSlideAxis = 'x', springConfi
196
238
  }
197
239
  return getPreparedItems(items);
198
240
  }
199
- function getScrollDirectionSpringValue() {
200
- if (thumbsSlideAxis === 'x') {
201
- return {
202
- // @ts-ignore
203
- scrollLeft: thumbListStyles.x,
204
- };
205
- }
206
- return {
207
- // @ts-ignore
208
- scrollTop: thumbListStyles.y,
209
- };
210
- }
211
- const thumbsFragment = withThumbs ? (jsx(animated.div, Object.assign({ ref: internalThumbsWrapperRef }, getScrollDirectionSpringValue(), { style: {
241
+ const Wrapper = CustomThumbsWrapperComponent
242
+ ? animated(CustomThumbsWrapperComponent)
243
+ : InternalWrapper;
244
+ const thumbsFragment = withThumbs ? (jsx(Wrapper, Object.assign({ ref: internalThumbsWrapperRef, className: "use-spring-carousel-thumbs-wrapper", onWheel: () => {
245
+ thumbListStyles[thumbsSlideAxis].stop();
246
+ }, style: {
212
247
  display: 'flex',
213
248
  flex: 1,
214
249
  position: 'relative',
@@ -230,22 +265,14 @@ function useThumbsModule({ items, withThumbs, thumbsSlideAxis = 'x', springConfi
230
265
  }
231
266
 
232
267
  const UseSpringCarouselContext = createContext(undefined);
233
- function useSpringCarouselContext() {
234
- const context = useContext(UseSpringCarouselContext);
235
- if (!context) {
236
- throw new Error(`useSpringCarouselContext isn't being used within the useSringCarousel context;
237
- use the context only inside a component that is rendered within the Carousel.`);
238
- }
239
- return context;
240
- }
241
- function useSpringCarousel({ items, withLoop = false, draggingSlideTreshold = 140, springConfig = config.default, shouldResizeOnWindowResize = true, withThumbs = false, enableThumbsWrapperScroll = true, carouselSlideAxis = 'x', thumbsSlideAxis = 'x', thumbsWrapperRef, prepareThumbsData, itemsPerSlide = 1, initialActiveItem = 0, initialStartingPosition = 'start', disableGestures = false, gutter = 0, startEndGutter = 0, touchAction = 'none', slideAmount, }) {
268
+ function useSpringCarousel({ itemsPerSlide = 1, items, withLoop = false, draggingSlideTreshold = 140, springConfig = config.default, shouldResizeOnWindowResize = true, withThumbs = false, enableThumbsWrapperScroll = true, carouselSlideAxis = 'x', thumbsSlideAxis = 'x', prepareThumbsData, initialActiveItem = 0, initialStartingPosition = 'start', disableGestures = false, gutter = 0, startEndGutter = 0, touchAction, slideAmount, freeScroll = false, CustomThumbsWrapperComponent, }) {
242
269
  function getItems() {
243
270
  if (withLoop) {
244
271
  return [...items, ...items, ...items];
245
272
  }
246
273
  return items;
247
274
  }
248
- const slideActionType = useRef('next');
275
+ const slideActionType = useRef('initial');
249
276
  const internalItems = getItems();
250
277
  const activeItem = useRef(initialActiveItem);
251
278
  const mainCarouselWrapperRef = useRef(null);
@@ -256,33 +283,51 @@ function useSpringCarousel({ items, withLoop = false, draggingSlideTreshold = 14
256
283
  const currentWindowWidth = useRef(0);
257
284
  const fluidTotalWrapperScrollValue = useRef(0);
258
285
  const slideFluidEndReached = useRef(false);
259
- const currentSlidedValue = useRef(0);
260
- const currentStepSlideValue = useRef(0);
261
- function getCarouselItem() {
262
- return carouselTrackWrapperRef.current?.querySelector('.use-spring-carousel-item');
263
- }
264
- const getFluidWrapperScrollValue = useCallback(() => {
265
- return Math.round(Number(carouselTrackWrapperRef.current?.[carouselSlideAxis === 'x' ? 'scrollWidth' : 'scrollHeight']) -
266
- carouselTrackWrapperRef.current.getBoundingClientRect()[carouselSlideAxis === 'x' ? 'width' : 'height']);
267
- }, [carouselSlideAxis]);
286
+ const initialWindowWidth = useRef(0);
268
287
  const [carouselStyles, setCarouselStyles] = useSpring(() => ({
269
288
  y: 0,
270
289
  x: 0,
271
290
  config: springConfig,
272
- onRest: ({ value }) => {
273
- currentSlidedValue.current = value[carouselSlideAxis];
274
- currentStepSlideValue.current = value[carouselSlideAxis];
291
+ onChange: ({ value }) => {
292
+ if (mainCarouselWrapperRef.current && freeScroll) {
293
+ mainCarouselWrapperRef.current[carouselSlideAxis === 'x' ? 'scrollLeft' : 'scrollTop'] = Math.abs(value[carouselSlideAxis]);
294
+ }
275
295
  },
276
296
  }));
277
- const getSlideValue = useCallback(() => {
278
- if (!carouselTrackWrapperRef.current) {
279
- return 0;
297
+ function getCarouselItem() {
298
+ return carouselTrackWrapperRef.current?.querySelector('.use-spring-carousel-item');
299
+ }
300
+ const getMainCarouselWrapperWidth = useCallback(() => {
301
+ if (!mainCarouselWrapperRef.current) {
302
+ throw new Error('mainCarouselWrapperRef is not available');
280
303
  }
304
+ return mainCarouselWrapperRef.current.getBoundingClientRect()[carouselSlideAxis === 'x' ? 'width' : 'height'];
305
+ }, [carouselSlideAxis]);
306
+ const getCarouselItemWidth = useCallback(() => {
281
307
  const carouselItem = getCarouselItem();
282
308
  if (!carouselItem) {
283
309
  throw Error('No carousel items available!');
284
310
  }
285
- const itemVal = carouselItem.getBoundingClientRect()[carouselSlideAxis === 'x' ? 'width' : 'height'] + gutter;
311
+ return (carouselItem.getBoundingClientRect()[carouselSlideAxis === 'x' ? 'width' : 'height'] + gutter);
312
+ }, [carouselSlideAxis, gutter]);
313
+ const getCurrentSlidedValue = useCallback(() => {
314
+ return carouselStyles[carouselSlideAxis].get();
315
+ }, [carouselSlideAxis, carouselStyles]);
316
+ const getIfItemsNotFillTheCarousel = useCallback(() => {
317
+ return getCarouselItemWidth() * items.length < getMainCarouselWrapperWidth();
318
+ }, [getCarouselItemWidth, getMainCarouselWrapperWidth, items.length]);
319
+ const getFluidWrapperScrollValue = useCallback(() => {
320
+ return Math.round(Number(carouselTrackWrapperRef.current?.[carouselSlideAxis === 'x' ? 'scrollWidth' : 'scrollHeight']) -
321
+ carouselTrackWrapperRef.current.getBoundingClientRect()[carouselSlideAxis === 'x' ? 'width' : 'height']);
322
+ }, [carouselSlideAxis]);
323
+ const getIsFirstItem = useCallback(() => {
324
+ return getCurrentActiveItem() === 0;
325
+ }, []);
326
+ const getSlideValue = useCallback(() => {
327
+ if (!carouselTrackWrapperRef.current) {
328
+ return 0;
329
+ }
330
+ const itemVal = getCarouselItemWidth();
286
331
  if (itemsPerSlide === 'fluid' && typeof slideAmount === 'number') {
287
332
  if (slideAmount < itemVal) {
288
333
  throw new Error('slideAmount must be greater than the width of a single item.');
@@ -290,21 +335,23 @@ function useSpringCarousel({ items, withLoop = false, draggingSlideTreshold = 14
290
335
  return slideAmount;
291
336
  }
292
337
  return itemVal;
293
- }, [carouselSlideAxis, gutter, itemsPerSlide, slideAmount]);
338
+ }, [getCarouselItemWidth, itemsPerSlide, slideAmount]);
294
339
  const adjustCarouselWrapperPosition = useCallback((ref) => {
295
- if (itemsPerSlide !== 'fluid' && typeof itemsPerSlide === 'number') {
296
- const positionProperty = carouselSlideAxis === 'x' ? 'left' : 'top';
297
- function getDefaultPositionValue() {
298
- return getSlideValue() * items.length;
299
- }
300
- function setPosition(v) {
301
- ref.style.top = '0px';
302
- ref.style.left = '0px';
340
+ const positionProperty = carouselSlideAxis === 'x' ? 'left' : 'top';
341
+ function getDefaultPositionValue() {
342
+ return getCarouselItemWidth() * items.length;
343
+ }
344
+ function setPosition(v) {
345
+ ref.style.top = '0px';
346
+ ref.style.left = '0px';
347
+ if (withLoop) {
303
348
  ref.style[positionProperty] = `-${v - startEndGutter}px`;
304
349
  }
305
- function setStartPosition() {
306
- setPosition(getDefaultPositionValue());
307
- }
350
+ }
351
+ function setStartPosition() {
352
+ setPosition(getDefaultPositionValue());
353
+ }
354
+ if (itemsPerSlide !== 'fluid' && typeof itemsPerSlide === 'number') {
308
355
  function setCenterPosition() {
309
356
  setPosition(getDefaultPositionValue() -
310
357
  getSlideValue() * Math.round((itemsPerSlide - 1) / 2));
@@ -334,33 +381,49 @@ function useSpringCarousel({ items, withLoop = false, draggingSlideTreshold = 14
334
381
  setStartPosition();
335
382
  }
336
383
  }
384
+ else {
385
+ setStartPosition();
386
+ }
337
387
  }, [
338
- startEndGutter,
339
388
  carouselSlideAxis,
389
+ itemsPerSlide,
390
+ getCarouselItemWidth,
391
+ items.length,
392
+ startEndGutter,
340
393
  getSlideValue,
341
394
  initialStartingPosition,
342
- items.length,
343
- itemsPerSlide,
395
+ withLoop,
344
396
  ]);
345
397
  const handleResize = useCallback(() => {
346
- if (window.innerWidth === currentWindowWidth.current) {
398
+ if (window.innerWidth === currentWindowWidth.current || freeScroll) {
347
399
  return;
348
400
  }
349
401
  currentWindowWidth.current = window.innerWidth;
350
402
  if (itemsPerSlide === 'fluid') {
403
+ if (getIfItemsNotFillTheCarousel()) {
404
+ setCarouselStyles.start({
405
+ immediate: true,
406
+ [carouselSlideAxis]: 0,
407
+ });
408
+ return;
409
+ }
351
410
  fluidTotalWrapperScrollValue.current = getFluidWrapperScrollValue();
411
+ const diff = currentWindowWidth.current - initialWindowWidth.current;
352
412
  if (slideFluidEndReached.current) {
413
+ const nextValue = -fluidTotalWrapperScrollValue.current;
353
414
  setCarouselStyles.start({
354
415
  immediate: true,
355
- [carouselSlideAxis]: -fluidTotalWrapperScrollValue.current,
416
+ [carouselSlideAxis]: nextValue,
356
417
  });
357
418
  }
358
419
  else {
359
- const lastItem = document.querySelector('.use-spring-carousel-item:last-of-type');
360
- console.log({
361
- lastItem: lastItem.offsetLeft,
420
+ const nextValue = getCurrentSlidedValue() + diff;
421
+ setCarouselStyles.start({
422
+ immediate: true,
423
+ [carouselSlideAxis]: nextValue,
362
424
  });
363
425
  }
426
+ initialWindowWidth.current = window.innerWidth;
364
427
  }
365
428
  else {
366
429
  setCarouselStyles.start({
@@ -373,17 +436,17 @@ function useSpringCarousel({ items, withLoop = false, draggingSlideTreshold = 14
373
436
  [carouselSlideAxis]: -(getSlideValue() * getCurrentActiveItem()),
374
437
  });
375
438
  }
376
- if (withLoop) {
377
- adjustCarouselWrapperPosition(carouselTrackWrapperRef.current);
378
- }
439
+ adjustCarouselWrapperPosition(carouselTrackWrapperRef.current);
379
440
  }, [
380
- adjustCarouselWrapperPosition,
381
- carouselSlideAxis,
382
- getSlideValue,
383
- setCarouselStyles,
384
- withLoop,
385
441
  itemsPerSlide,
442
+ getIfItemsNotFillTheCarousel,
386
443
  getFluidWrapperScrollValue,
444
+ freeScroll,
445
+ setCarouselStyles,
446
+ carouselSlideAxis,
447
+ getCurrentSlidedValue,
448
+ getSlideValue,
449
+ adjustCarouselWrapperPosition,
387
450
  ]);
388
451
  // Custom modules
389
452
  const { useListenToCustomEvent, emitObservable } = useCustomEventsModule();
@@ -397,18 +460,29 @@ function useSpringCarousel({ items, withLoop = false, draggingSlideTreshold = 14
397
460
  items,
398
461
  thumbsSlideAxis,
399
462
  springConfig,
400
- thumbsWrapperRef,
401
463
  prepareThumbsData,
464
+ itemsPerSlide,
465
+ getFluidWrapperScrollValue,
466
+ getSlideValue,
467
+ CustomThumbsWrapperComponent,
402
468
  });
403
- function getCurrentSlidedValue() {
404
- return carouselStyles[carouselSlideAxis].get();
469
+ function getWrapperScrollDirection() {
470
+ if (!mainCarouselWrapperRef.current) {
471
+ throw new Error('Missing mainCarouselWrapperRef.current');
472
+ }
473
+ return mainCarouselWrapperRef.current[carouselSlideAxis === 'x' ? 'scrollLeft' : 'scrollTop'];
405
474
  }
406
475
  const bindDrag = useDrag(props => {
407
476
  const isDragging = props.dragging;
408
477
  const movement = props.movement[carouselSlideAxis === 'x' ? 0 : 1];
409
478
  function resetAnimation() {
410
479
  if (itemsPerSlide === 'fluid') {
411
- if (getIsFirstItem()) {
480
+ if (getIfItemsNotFillTheCarousel()) {
481
+ setCarouselStyles.start({
482
+ [carouselSlideAxis]: 0,
483
+ });
484
+ }
485
+ else if (getIsFirstItem()) {
412
486
  slideToPrevItem();
413
487
  }
414
488
  else if (slideFluidEndReached.current) {
@@ -418,7 +492,7 @@ function useSpringCarousel({ items, withLoop = false, draggingSlideTreshold = 14
418
492
  }
419
493
  else {
420
494
  setCarouselStyles.start({
421
- [carouselSlideAxis]: currentStepSlideValue.current,
495
+ [carouselSlideAxis]: getCurrentSlidedValue(),
422
496
  });
423
497
  }
424
498
  }
@@ -428,24 +502,46 @@ function useSpringCarousel({ items, withLoop = false, draggingSlideTreshold = 14
428
502
  });
429
503
  }
430
504
  }
431
- if (props.first) {
432
- currentSlidedValue.current = getCurrentSlidedValue();
433
- }
434
505
  if (isDragging) {
435
506
  setIsDragging(true);
436
507
  emitObservable({
437
508
  eventName: 'onDrag',
438
509
  ...props,
439
510
  });
440
- setCarouselStyles.start({
441
- [carouselSlideAxis]: currentSlidedValue.current + movement,
442
- });
511
+ if (freeScroll) {
512
+ const direction = props.direction[carouselSlideAxis === 'x' ? 0 : 1];
513
+ if (getWrapperScrollDirection() === 0 && direction > 0) {
514
+ props.cancel();
515
+ }
516
+ else {
517
+ setCarouselStyles.start({
518
+ from: {
519
+ [carouselSlideAxis]: getWrapperScrollDirection(),
520
+ },
521
+ to: {
522
+ [carouselSlideAxis]: direction > 0
523
+ ? getWrapperScrollDirection() - Math.abs(movement)
524
+ : getWrapperScrollDirection() + Math.abs(movement),
525
+ },
526
+ });
527
+ }
528
+ }
529
+ else {
530
+ setCarouselStyles.start({
531
+ [carouselSlideAxis]: getCurrentSlidedValue() + movement,
532
+ });
533
+ }
443
534
  const prevItemTreshold = movement > draggingSlideTreshold;
444
535
  const nextItemTreshold = movement < -draggingSlideTreshold;
445
536
  if (mainCarouselWrapperRef.current.getBoundingClientRect().width >=
446
537
  items.length * getSlideValue()) {
447
538
  slideFluidEndReached.current = true;
448
539
  }
540
+ if ((prevItemTreshold || nextItemTreshold) && getIfItemsNotFillTheCarousel()) {
541
+ props.cancel();
542
+ resetAnimation();
543
+ return;
544
+ }
449
545
  if (slideFluidEndReached.current && movement < 0) {
450
546
  if (nextItemTreshold) {
451
547
  props.cancel();
@@ -473,7 +569,7 @@ function useSpringCarousel({ items, withLoop = false, draggingSlideTreshold = 14
473
569
  }
474
570
  }
475
571
  }
476
- if (props.last && !props.pressed) {
572
+ if (props.last && !props.pressed && !freeScroll) {
477
573
  resetAnimation();
478
574
  }
479
575
  }, {
@@ -518,6 +614,7 @@ function useSpringCarousel({ items, withLoop = false, draggingSlideTreshold = 14
518
614
  }
519
615
  });
520
616
  useMount(() => {
617
+ initialWindowWidth.current = window.innerWidth;
521
618
  if (initialActiveItem > 0 && initialActiveItem <= items.length) {
522
619
  slideToItem({
523
620
  to: initialActiveItem,
@@ -527,10 +624,13 @@ function useSpringCarousel({ items, withLoop = false, draggingSlideTreshold = 14
527
624
  }
528
625
  });
529
626
  useEffect(() => {
627
+ function resize() {
628
+ setTimeout(handleResize);
629
+ }
530
630
  if (shouldResizeOnWindowResize) {
531
- window.addEventListener('resize', handleResize);
631
+ window.addEventListener('resize', resize);
532
632
  return () => {
533
- window.removeEventListener('resize', handleResize);
633
+ window.removeEventListener('resize', resize);
534
634
  };
535
635
  }
536
636
  }, [handleResize, shouldResizeOnWindowResize]);
@@ -601,18 +701,21 @@ function useSpringCarousel({ items, withLoop = false, draggingSlideTreshold = 14
601
701
  function findItemIndex(id) {
602
702
  return items.findIndex(item => item.id === id);
603
703
  }
604
- function slideToItem({ from, to, customTo, immediate = false, onRest = () => { }, }) {
704
+ function slideToItem({ from, to = -1, customTo, immediate = false, onRest = () => { }, }) {
605
705
  if (!immediate) {
606
706
  setActiveItem(to);
607
707
  setIsAnimating(true);
608
708
  emitObservable({
609
709
  eventName: 'onSlideStartChange',
610
- nextItem: to,
611
710
  slideActionType: getSlideActionType(),
711
+ nextItem: {
712
+ index: to,
713
+ id: items[to].id,
714
+ },
612
715
  });
613
716
  }
614
717
  function getFromValue() {
615
- if (from) {
718
+ if (typeof from === 'number') {
616
719
  return {
617
720
  from: {
618
721
  [carouselSlideAxis]: from,
@@ -622,7 +725,7 @@ function useSpringCarousel({ items, withLoop = false, draggingSlideTreshold = 14
622
725
  return {};
623
726
  }
624
727
  function getToValue() {
625
- if (customTo) {
728
+ if (typeof customTo === 'number') {
626
729
  return {
627
730
  [carouselSlideAxis]: customTo,
628
731
  };
@@ -643,67 +746,68 @@ function useSpringCarousel({ items, withLoop = false, draggingSlideTreshold = 14
643
746
  if (!immediate) {
644
747
  emitObservable({
645
748
  eventName: 'onSlideChange',
646
- currentItem: getCurrentActiveItem(),
647
749
  slideActionType: getSlideActionType(),
750
+ currentItem: {
751
+ index: getCurrentActiveItem(),
752
+ id: items[getCurrentActiveItem()].id,
753
+ },
648
754
  });
649
755
  }
650
756
  }
651
757
  },
652
758
  });
653
759
  if (enableThumbsWrapperScroll && withThumbs && !immediate) {
654
- handleThumbsScroll(to);
655
- }
656
- }
657
- function getWrapperFromValue(element) {
658
- if (element.style.transform === 'none') {
659
- return 0;
760
+ handleThumbsScroll(to, getSlideActionType());
660
761
  }
661
- const values = element.style.transform.split(/\w+\(|\);?/);
662
- return Number(values[1].split(/,\s?/g)[carouselSlideAxis === 'x' ? 0 : 1].replace('px', ''));
663
- }
664
- function getIsFirstItem() {
665
- return getCurrentActiveItem() === 0;
666
762
  }
667
763
  function getIsLastItem() {
668
764
  return getCurrentActiveItem() === items.length - 1;
669
765
  }
670
766
  function slideToPrevItem() {
671
- if (itemsPerSlide === 'fluid' && !withLoop) {
672
- const currentSlideVal = getWrapperFromValue(carouselTrackWrapperRef.current);
673
- const nextPrevValue = currentSlideVal + getSlideValue() + 100;
674
- if (getIsFirstItem()) {
675
- slideToItem({
676
- to: 0,
677
- });
767
+ setSlideActionType('prev');
768
+ if (itemsPerSlide === 'fluid') {
769
+ if (getIfItemsNotFillTheCarousel()) {
678
770
  return;
679
771
  }
680
- if (nextPrevValue >= 0) {
772
+ const nextPrevValue = getCurrentSlidedValue() + getSlideValue() + 200;
773
+ if (freeScroll) {
774
+ const nextValue = mainCarouselWrapperRef.current.scrollLeft - getSlideValue();
681
775
  slideToItem({
682
- to: 0,
776
+ customTo: nextValue < 0 ? 0 : nextValue,
777
+ from: mainCarouselWrapperRef.current.scrollLeft,
683
778
  });
684
- currentStepSlideValue.current = 0;
779
+ }
780
+ else if (nextPrevValue >= 0) {
781
+ if (withLoop) {
782
+ slideToItem({
783
+ from: getCurrentSlidedValue() - getCarouselItemWidth() * items.length,
784
+ customTo: getCurrentSlidedValue() -
785
+ getCarouselItemWidth() * items.length +
786
+ getSlideValue(),
787
+ });
788
+ }
789
+ else {
790
+ slideToItem({
791
+ customTo: 0,
792
+ });
793
+ }
685
794
  }
686
795
  else {
687
- const nextVal = currentStepSlideValue.current + getSlideValue();
688
- currentStepSlideValue.current = nextVal;
689
796
  slideToItem({
690
- to: getPrevItem(),
691
- customTo: nextVal,
797
+ customTo: getCurrentSlidedValue() + getSlideValue(),
692
798
  });
693
799
  }
694
800
  if (slideFluidEndReached.current) {
695
801
  slideFluidEndReached.current = false;
696
802
  }
697
803
  }
698
- else if ((!withLoop && getCurrentActiveItem() === 0) || windowIsHidden.current) {
699
- return;
700
- }
701
804
  else {
702
- setSlideActionType('prev');
805
+ if ((!withLoop && getCurrentActiveItem() === 0) || windowIsHidden.current) {
806
+ return;
807
+ }
703
808
  if (getIsFirstItem()) {
704
809
  slideToItem({
705
- from: -(Math.abs(getWrapperFromValue(carouselTrackWrapperRef.current)) +
706
- getSlideValue() * items.length),
810
+ from: getCurrentSlidedValue() - getSlideValue() * items.length,
707
811
  to: items.length - 1,
708
812
  });
709
813
  }
@@ -715,58 +819,51 @@ function useSpringCarousel({ items, withLoop = false, draggingSlideTreshold = 14
715
819
  }
716
820
  }
717
821
  function slideToNextItem() {
718
- if (itemsPerSlide === 'fluid' && !withLoop) {
719
- const willGoAfterLastFluidItem = Math.abs(getNextItem() * getSlideValue()) + 100 >=
822
+ setSlideActionType('next');
823
+ if (itemsPerSlide === 'fluid') {
824
+ if (getIfItemsNotFillTheCarousel()) {
825
+ return;
826
+ }
827
+ const willGoAfterLastFluidItem = Math.abs(getCurrentSlidedValue() - getSlideValue()) + 100 >=
720
828
  fluidTotalWrapperScrollValue.current;
721
- function getDefaultNextValue() {
722
- return -(getNextItem() * getSlideValue());
829
+ if (freeScroll) {
830
+ slideToItem({
831
+ customTo: mainCarouselWrapperRef.current.scrollLeft + getSlideValue(),
832
+ from: mainCarouselWrapperRef.current.scrollLeft,
833
+ });
723
834
  }
724
- console.log(getDefaultNextValue());
725
- if (mainCarouselWrapperRef.current.getBoundingClientRect().width >=
726
- items.length * getSlideValue()) {
727
- slideFluidEndReached.current = true;
835
+ else if (withLoop &&
836
+ Math.abs(getCurrentSlidedValue() - getSlideValue()) >=
837
+ items.length * getCarouselItemWidth()) {
838
+ const currentWidth = getCarouselItemWidth() * items.length;
839
+ slideToItem({
840
+ from: getCurrentSlidedValue() + currentWidth,
841
+ customTo: getCurrentSlidedValue() + currentWidth - getSlideValue(),
842
+ });
728
843
  }
729
- if (slideFluidEndReached.current) {
844
+ else if (slideFluidEndReached.current) {
730
845
  return;
731
846
  }
732
- if (willGoAfterLastFluidItem) {
733
- const nextValue = -fluidTotalWrapperScrollValue.current;
847
+ else if (willGoAfterLastFluidItem) {
734
848
  slideFluidEndReached.current = true;
735
- currentStepSlideValue.current = nextValue;
736
849
  slideToItem({
737
- customTo: nextValue,
738
- to: getNextItem(),
850
+ customTo: -fluidTotalWrapperScrollValue.current,
739
851
  });
740
852
  }
741
853
  else {
742
- const isPure = Math.abs(currentStepSlideValue.current % getSlideValue()) === 0;
743
- if (!isPure) {
744
- const nextValue = currentStepSlideValue.current - getSlideValue();
745
- currentStepSlideValue.current = nextValue;
746
- slideToItem({
747
- to: getNextItem(),
748
- customTo: nextValue,
749
- });
750
- }
751
- else {
752
- currentStepSlideValue.current = getDefaultNextValue();
753
- slideToItem({
754
- to: getNextItem(),
755
- customTo: getDefaultNextValue(),
756
- });
757
- }
854
+ slideToItem({
855
+ customTo: getCurrentSlidedValue() - getSlideValue(),
856
+ });
758
857
  }
759
858
  }
760
- else if ((!withLoop && getCurrentActiveItem() === internalItems.length - 1) ||
761
- windowIsHidden.current) {
762
- return;
763
- }
764
859
  else {
765
- setSlideActionType('next');
860
+ if ((!withLoop && getCurrentActiveItem() === internalItems.length - 1) ||
861
+ windowIsHidden.current) {
862
+ return;
863
+ }
766
864
  if (getIsLastItem()) {
767
865
  slideToItem({
768
- from: getWrapperFromValue(carouselTrackWrapperRef.current) +
769
- getSlideValue() * items.length,
866
+ from: getCurrentSlidedValue() + getSlideValue() * items.length,
770
867
  to: 0,
771
868
  });
772
869
  }
@@ -815,14 +912,18 @@ function useSpringCarousel({ items, withLoop = false, draggingSlideTreshold = 14
815
912
  getIsPrevItem,
816
913
  slideToPrevItem,
817
914
  slideToNextItem,
818
- slideToItem: _slideToItem,
819
- getIsActiveItem: id => {
820
- return findItemIndex(id) === getCurrentActiveItem();
821
- },
822
- getCurrentActiveItem: () => ({
823
- id: items[getCurrentActiveItem()].id,
824
- index: getCurrentActiveItem(),
825
- }),
915
+ ...(typeof itemsPerSlide === 'number'
916
+ ? {
917
+ slideToItem: _slideToItem,
918
+ getIsActiveItem: (id) => {
919
+ return findItemIndex(id) === getCurrentActiveItem();
920
+ },
921
+ getCurrentActiveItem: () => ({
922
+ id: items[getCurrentActiveItem()].id,
923
+ index: getCurrentActiveItem(),
924
+ }),
925
+ }
926
+ : {}),
826
927
  };
827
928
  function getItemStyles() {
828
929
  if (typeof itemsPerSlide === 'number') {
@@ -846,28 +947,59 @@ function useSpringCarousel({ items, withLoop = false, draggingSlideTreshold = 14
846
947
  height: carouselSlideAxis === 'y' ? percentValue : '100%',
847
948
  };
848
949
  }
849
- const carouselFragment = (jsx(UseSpringCarouselContext.Provider, Object.assign({ value: contextProps }, { children: jsx("div", Object.assign({ ref: mainCarouselWrapperRef, "data-testid": "use-spring-carousel-wrapper", style: {
950
+ function handleCarouselFragmentRef(ref) {
951
+ if (ref) {
952
+ carouselTrackWrapperRef.current = ref;
953
+ adjustCarouselWrapperPosition(ref);
954
+ }
955
+ }
956
+ function getOverflowStyles() {
957
+ if (freeScroll) {
958
+ if (carouselSlideAxis === 'x') {
959
+ return {
960
+ overflowX: 'auto',
961
+ };
962
+ }
963
+ return {
964
+ overflowY: 'auto',
965
+ };
966
+ }
967
+ return {};
968
+ }
969
+ function getWheelEvent() {
970
+ if (freeScroll) {
971
+ return {
972
+ onWheel() {
973
+ carouselStyles[carouselSlideAxis].stop();
974
+ },
975
+ };
976
+ }
977
+ return {};
978
+ }
979
+ function getTouchAction() {
980
+ if (!touchAction) {
981
+ if (carouselSlideAxis === 'x') {
982
+ return 'pan-y';
983
+ }
984
+ return 'pan-x';
985
+ }
986
+ return touchAction;
987
+ }
988
+ const carouselFragment = (jsx(UseSpringCarouselContext.Provider, Object.assign({ value: contextProps }, { children: jsx("div", Object.assign({ ref: mainCarouselWrapperRef, className: "use-spring-carousel-main-wrapper", "data-testid": "use-spring-carousel-wrapper" }, getWheelEvent(), {
989
+ // @ts-ignore
990
+ style: {
850
991
  display: 'flex',
851
992
  position: 'relative',
852
993
  width: '100%',
853
994
  height: '100%',
854
- overflow: 'hidden',
855
- } }, { children: jsx(animated.div, Object.assign({}, bindDrag(), { "data-testid": "use-spring-carousel-animated-wrapper", style: {
995
+ ...getOverflowStyles(),
996
+ } }, { children: jsx(animated.div, Object.assign({}, bindDrag(), { className: "use-spring-carousel-track-wrapper", "data-testid": "use-spring-carousel-animated-wrapper", ref: handleCarouselFragmentRef, style: {
856
997
  display: 'flex',
857
- top: 0,
858
- left: 0,
859
998
  position: 'relative',
860
- touchAction,
999
+ touchAction: getTouchAction(),
861
1000
  flexDirection: carouselSlideAxis === 'x' ? 'row' : 'column',
862
1001
  ...getAnimatedWrapperStyles(),
863
- ...carouselStyles,
864
- }, ref: ref => {
865
- if (ref) {
866
- carouselTrackWrapperRef.current = ref;
867
- if (withLoop) {
868
- adjustCarouselWrapperPosition(ref);
869
- }
870
- }
1002
+ ...(freeScroll ? {} : carouselStyles),
871
1003
  } }, { children: internalItems.map(({ id, renderItem }, index) => {
872
1004
  return (jsx("div", Object.assign({ className: "use-spring-carousel-item", "data-testid": "use-spring-carousel-item-wrapper", style: {
873
1005
  display: 'flex',
@@ -877,10 +1009,17 @@ function useSpringCarousel({ items, withLoop = false, draggingSlideTreshold = 14
877
1009
  }) }), void 0) }), void 0) }), void 0));
878
1010
  const thumbsFragment = (jsx(UseSpringCarouselContext.Provider, Object.assign({ value: contextProps }, { children: _thumbsFragment }), void 0));
879
1011
  return {
1012
+ ...contextProps,
880
1013
  carouselFragment,
881
1014
  thumbsFragment,
882
- ...contextProps,
883
1015
  };
1016
+ }
1017
+ function useSpringCarouselContext() {
1018
+ const context = useContext(UseSpringCarouselContext);
1019
+ if (!context) {
1020
+ throw new Error('useSpringCarouselContext must be used only inside a component that is rendered inside the Carousel.');
1021
+ }
1022
+ return context;
884
1023
  }
885
1024
 
886
1025
  const UseTransitionCarouselContext = createContext(undefined);
@@ -892,7 +1031,7 @@ function useTransitionCarouselContext() {
892
1031
  }
893
1032
  return context;
894
1033
  }
895
- function useTransitionCarousel({ items, withLoop = false, withThumbs = false, springConfig = config.default, thumbsSlideAxis = 'x', enableThumbsWrapperScroll = true, draggingSlideTreshold = 50, prepareThumbsData, toPrevItemSpringProps, toNextItemSpringProps, disableGestures = false, springAnimationProps = {
1034
+ function useTransitionCarousel({ items, withLoop = false, withThumbs = false, springConfig = config.default, thumbsSlideAxis = 'x', enableThumbsWrapperScroll = true, draggingSlideTreshold = 50, prepareThumbsData, toPrevItemSpringProps, toNextItemSpringProps, disableGestures = false, CustomThumbsWrapperComponent, springAnimationProps = {
896
1035
  initial: {
897
1036
  opacity: 1,
898
1037
  position: 'relative',
@@ -925,6 +1064,7 @@ function useTransitionCarousel({ items, withLoop = false, withThumbs = false, sp
925
1064
  thumbsSlideAxis,
926
1065
  springConfig,
927
1066
  prepareThumbsData,
1067
+ CustomThumbsWrapperComponent,
928
1068
  });
929
1069
  const bindSwipe = useDrag(({ last, movement: [mx] }) => {
930
1070
  if (getIsAnimating()) {
@@ -1016,8 +1156,11 @@ function useTransitionCarousel({ items, withLoop = false, withThumbs = false, sp
1016
1156
  setIsAnimating(false);
1017
1157
  emitObservable({
1018
1158
  eventName: 'onSlideChange',
1019
- currentItem: activeItem,
1020
1159
  slideActionType: getSlideActionType(),
1160
+ currentItem: {
1161
+ index: activeItem,
1162
+ id: items[activeItem].id,
1163
+ },
1021
1164
  });
1022
1165
  }
1023
1166
  },
@@ -1059,8 +1202,11 @@ function useTransitionCarousel({ items, withLoop = false, withThumbs = false, sp
1059
1202
  const newActiveItem = findItemIndex(items[itemIndex].id);
1060
1203
  emitObservable({
1061
1204
  eventName: 'onSlideStartChange',
1062
- nextItem: newActiveItem,
1063
1205
  slideActionType: getSlideActionType(),
1206
+ nextItem: {
1207
+ index: newActiveItem,
1208
+ id: items[itemIndex].id,
1209
+ },
1064
1210
  });
1065
1211
  if (newActiveItem > currentItem) {
1066
1212
  setSlideActionType('next');
@@ -1080,16 +1226,22 @@ function useTransitionCarousel({ items, withLoop = false, withThumbs = false, sp
1080
1226
  if (isLastItem) {
1081
1227
  emitObservable({
1082
1228
  eventName: 'onSlideStartChange',
1083
- nextItem: 0,
1084
1229
  slideActionType: getSlideActionType(),
1230
+ nextItem: {
1231
+ index: 0,
1232
+ id: items[0].id,
1233
+ },
1085
1234
  });
1086
1235
  setActiveItem(0);
1087
1236
  }
1088
1237
  else {
1089
1238
  emitObservable({
1090
1239
  eventName: 'onSlideStartChange',
1091
- nextItem: activeItem + 1,
1092
1240
  slideActionType: getSlideActionType(),
1241
+ nextItem: {
1242
+ index: activeItem + 1,
1243
+ id: items[activeItem + 1].id,
1244
+ },
1093
1245
  });
1094
1246
  setActiveItem(activeItem + 1);
1095
1247
  }
@@ -1098,8 +1250,11 @@ function useTransitionCarousel({ items, withLoop = false, withThumbs = false, sp
1098
1250
  if (!isLastItem) {
1099
1251
  emitObservable({
1100
1252
  eventName: 'onSlideStartChange',
1101
- nextItem: activeItem + 1,
1102
1253
  slideActionType: getSlideActionType(),
1254
+ nextItem: {
1255
+ index: activeItem + 1,
1256
+ id: items[activeItem + 1].id,
1257
+ },
1103
1258
  });
1104
1259
  setSlideActionType('next');
1105
1260
  setActiveItem(activeItem + 1);
@@ -1113,16 +1268,22 @@ function useTransitionCarousel({ items, withLoop = false, withThumbs = false, sp
1113
1268
  if (isFirstItem) {
1114
1269
  emitObservable({
1115
1270
  eventName: 'onSlideStartChange',
1116
- nextItem: items.length - 1,
1117
1271
  slideActionType: getSlideActionType(),
1272
+ nextItem: {
1273
+ index: activeItem - 1,
1274
+ id: items[activeItem - 1].id,
1275
+ },
1118
1276
  });
1119
1277
  setActiveItem(items.length - 1);
1120
1278
  }
1121
1279
  else {
1122
1280
  emitObservable({
1123
1281
  eventName: 'onSlideStartChange',
1124
- nextItem: activeItem - 1,
1125
1282
  slideActionType: getSlideActionType(),
1283
+ nextItem: {
1284
+ index: activeItem - 1,
1285
+ id: items[activeItem - 1].id,
1286
+ },
1126
1287
  });
1127
1288
  setActiveItem(activeItem - 1);
1128
1289
  }
@@ -1132,8 +1293,11 @@ function useTransitionCarousel({ items, withLoop = false, withThumbs = false, sp
1132
1293
  setSlideActionType('prev');
1133
1294
  emitObservable({
1134
1295
  eventName: 'onSlideStartChange',
1135
- nextItem: activeItem - 1,
1136
1296
  slideActionType: getSlideActionType(),
1297
+ nextItem: {
1298
+ index: activeItem - 1,
1299
+ id: items[activeItem - 1].id,
1300
+ },
1137
1301
  });
1138
1302
  setActiveItem(activeItem - 1);
1139
1303
  }