diff --git a/demo/App.tsx b/demo/App.tsx
index 6232e96..3eb9d4f 100644
--- a/demo/App.tsx
+++ b/demo/App.tsx
@@ -1,8 +1,8 @@
import React from 'react';
-import MarqueeSliderDemo from './MarqueeSliderDemo';
+// import MarqueeSliderDemo from './MarqueeSliderDemo';
// import FreeScrollSliderDemo from './FreeScrollSliderDemo';
// import ThumbnailSliderDemo from './ThumbnailSliderDemo';
-// import ScrollSnapSliderDemo from './ScrollSnapSliderDemo';
+import ScrollSnapSliderDemo from './ScrollSnapSliderDemo';
const App: React.FC = () => (
= (props) => {
index,
htmlElement = 'div',
children,
- style: styleFromProps,
+ style,
onClick: onClickFromProps,
...rest
} = props;
- const [style, setStyle] = useState();
+ const [snapStyles, setSnapStyles] = useState();
const slider = useSlider();
const slideRef = useRef(null);
@@ -70,14 +70,15 @@ const Slide: React.FC = (props) => {
index,
]);
+ // here
useEffect(() => {
if (scrollSnap) {
- setStyle({
+ setSnapStyles({
scrollSnapStop: 'always',
scrollSnapAlign: 'start',
})
} else {
- setStyle(undefined);
+ setSnapStyles(undefined);
}
}, [scrollSnap]);
@@ -101,7 +102,7 @@ const Slide: React.FC = (props) => {
flexShrink: 0,
width: slideWidth,
...style || {},
- ...styleFromProps || {},
+ ...snapStyles || {},
}
return (
diff --git a/src/SliderProvider/context.tsx b/src/SliderProvider/context.tsx
index 27085ad..2cff568 100644
--- a/src/SliderProvider/context.tsx
+++ b/src/SliderProvider/context.tsx
@@ -19,6 +19,7 @@ export interface ISliderContext extends Omit {
slideWidth?: string
isPaused?: boolean
setIsPaused: (is: boolean) => void // eslint-disable-line no-unused-vars
+ isDragging: boolean
}
export const SliderContext = createContext({} as ISliderContext);
diff --git a/src/SliderProvider/index.tsx b/src/SliderProvider/index.tsx
index 3871368..efde438 100644
--- a/src/SliderProvider/index.tsx
+++ b/src/SliderProvider/index.tsx
@@ -79,6 +79,7 @@ const SliderProvider: React.FC = (props) => {
const [isPaused, setIsPaused] = useState(false);
const [isFullyScrolled, setIsFullyScrolled] = useState(false);
const sliderTrackRef = useRef(null);
+ const [isDragging, setIsDragging] = useState(false);
const [sliderState, dispatchSliderState] = useReducer(reducer, {
currentSlideIndex: slideIndexFromProps,
@@ -89,7 +90,9 @@ const SliderProvider: React.FC = (props) => {
useDragScroll({
ref: sliderTrackRef,
scrollYAxis: false,
- enable: dragScroll || (scrollable && dragScroll !== false)
+ enable: dragScroll || (scrollable && dragScroll !== false),
+ onDrag: () => { setIsDragging(true) },
+ onDragEnd: () => { setIsDragging(false) },
});
useMarquee({
@@ -206,7 +209,8 @@ const SliderProvider: React.FC = (props) => {
setIsPaused,
isPaused,
pauseOnHover,
- alignLastSlide
+ alignLastSlide,
+ isDragging
};
return (
diff --git a/src/SliderProvider/useDragScroll.ts b/src/SliderProvider/useDragScroll.ts
index adfbb77..dc786de 100644
--- a/src/SliderProvider/useDragScroll.ts
+++ b/src/SliderProvider/useDragScroll.ts
@@ -5,6 +5,8 @@ type Args = {
scrollYAxis?: boolean
enable?: boolean
ref: React.MutableRefObject
+ onDrag: () => void
+ onDragEnd: () => void
}
export type UseDraggable = (args?: Args) => null // eslint-disable-line no-unused-vars
@@ -14,7 +16,9 @@ export const useDraggable: UseDraggable = (args) => {
buttons = [1, 4, 5], // See https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/buttons
scrollYAxis,
enable,
- ref
+ ref,
+ onDrag,
+ onDragEnd
} = args || {};
// Position of the mouse on the page on mousedown
@@ -37,6 +41,9 @@ export const useDraggable: UseDraggable = (args) => {
setStartY(e.pageY - ref.current.offsetTop);
setStartScrollLeft(ref.current.scrollLeft);
setStartScrollTop(ref.current.scrollTop);
+ if (typeof onDrag === 'function') {
+ onDrag();
+ }
}
};
@@ -57,15 +64,16 @@ export const useDraggable: UseDraggable = (args) => {
}
e.preventDefault();
+
// Position of mouse on the page
const mouseX = e.pageX - ref.current.offsetLeft;
const mouseY = e.pageY - ref.current.offsetTop;
// Distance of the mouse from the origin of the last mousedown event
- const walkX = mouseX - startX;
- const walkY = mouseY - startY;
- // Set element scroll
- ref.current.scrollLeft = startScrollLeft - walkX;
- const newScrollTop = startScrollTop - walkY;
+ const xDisplacement = mouseX - startX;
+ const yDisplacement = mouseY - startY;
+ // Finally, set the element's scroll
+ ref.current.scrollLeft = startScrollLeft - xDisplacement;
+ const newScrollTop = startScrollTop - yDisplacement;
if (scrollYAxis !== false) {
ref.current.scrollTop = newScrollTop;
}
@@ -80,6 +88,9 @@ export const useDraggable: UseDraggable = (args) => {
const childAsElement = child as HTMLElement;
childAsElement.style.removeProperty('pointer-events');
});
+ if (typeof onDragEnd === 'function') {
+ onDragEnd();
+ }
}
};
@@ -101,7 +112,9 @@ export const useDraggable: UseDraggable = (args) => {
startY,
scrollYAxis,
enable,
- ref
+ ref,
+ onDragEnd,
+ onDrag
]);
return null;
diff --git a/src/SliderTrack/index.tsx b/src/SliderTrack/index.tsx
index 9806666..709e8a4 100644
--- a/src/SliderTrack/index.tsx
+++ b/src/SliderTrack/index.tsx
@@ -25,7 +25,8 @@ const SliderTrack: React.FC = (props) => {
scrollSnap,
setIsPaused,
pauseOnHover,
- alignLastSlide
+ alignLastSlide,
+ isDragging
} = sliderContext;
const hasAddedScrollListener = useRef(false);
@@ -85,6 +86,7 @@ const SliderTrack: React.FC = (props) => {
track.addEventListener('wheel', (e) => { e.preventDefault() })
}
}
+
return () => {
if (track) {
track.removeEventListener('scroll', onScroll);
@@ -98,6 +100,11 @@ const SliderTrack: React.FC = (props) => {
const ghostSlideWidth = getGhostSlideWidth(sliderContext);
+ let scrollSnapType;
+ if (scrollSnap && slideWidth) {
+ scrollSnapType = !isDragging ? 'x mandatory' : 'none';
+ }
+
return (
= (props) => {
display: 'flex',
overflowX: 'scroll', // NOTE: 'WebkitOverflowScrolling: touch' does not work when 'auto'
WebkitOverflowScrolling: 'touch',
- scrollSnapType: (scrollSnap && slideWidth) ? 'x mandatory' : undefined, // NOTE: only apply after slide width has populated
+ // NOTE: only apply after slide width has populated and while NOT dragging
+ scrollSnapType,
...style,
},
ref: sliderTrackRef,