From 777865c3ac6772fbda2bc0a6f58cde3eff7dec43 Mon Sep 17 00:00:00 2001 From: streamich Date: Fri, 3 Jan 2020 19:53:12 +0100 Subject: [PATCH] =?UTF-8?q?feat:=20=F0=9F=8E=B8=20add=20[vertical]=20flag?= =?UTF-8?q?=20to=20useSlider()=20hook?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/useSlider.ts | 19 +++++++++++++------ stories/useSlider.story.tsx | 20 +++++++++++++++++++- 2 files changed, 32 insertions(+), 7 deletions(-) diff --git a/src/useSlider.ts b/src/useSlider.ts index a7548bceca..f123cdc61f 100644 --- a/src/useSlider.ts +++ b/src/useSlider.ts @@ -15,6 +15,7 @@ export interface Options { onScrubStop: () => void; reverse: boolean; styles: boolean | CSSProperties; + vertical?: boolean; } const noop = () => {}; @@ -59,13 +60,17 @@ const useSlider = (ref: RefObject, options: Partial = {}): startScrubbing(); onMouseMove(event); }; - const onMouseMove = (event: MouseEvent) => onScrub(event.clientX); + const onMouseMove = options.vertical + ? (event: MouseEvent) => onScrub(event.clientY) + : (event: MouseEvent) => onScrub(event.clientX); const onTouchStart = (event: TouchEvent) => { startScrubbing(); onTouchMove(event); }; - const onTouchMove = (event: TouchEvent) => onScrub(event.changedTouches[0].clientX); + const onTouchMove = options.vertical + ? (event: TouchEvent) => onScrub(event.changedTouches[0].clientY) + : (event: TouchEvent) => onScrub(event.changedTouches[0].clientX); const bindEvents = () => { on(document, 'mousemove', onMouseMove); @@ -83,19 +88,21 @@ const useSlider = (ref: RefObject, options: Partial = {}): off(document, 'touchend', stopScrubbing); }; - const onScrub = (clientX: number) => { + const onScrub = (clientXY: number) => { cancelAnimationFrame(frame.current); frame.current = requestAnimationFrame(() => { if (isMounted() && ref.current) { - const { left: pos, width: length } = ref.current.getBoundingClientRect(); + const rect = ref.current.getBoundingClientRect(); + const pos = options.vertical ? rect.top : rect.left; + const length = options.vertical ? rect.height : rect.width; // Prevent returning 0 when element is hidden by CSS if (!length) { return; } - let value = (clientX - pos) / length; + let value = (clientXY - pos) / length; if (value > 1) { value = 1; @@ -126,7 +133,7 @@ const useSlider = (ref: RefObject, options: Partial = {}): } else { return undefined; } - }, [ref]); + }, [ref, options.vertical]); return state; }; diff --git a/stories/useSlider.story.tsx b/stories/useSlider.story.tsx index 7f5934dab7..9626a8b43a 100644 --- a/stories/useSlider.story.tsx +++ b/stories/useSlider.story.tsx @@ -20,6 +20,24 @@ const Demo = () => { ); }; +const DemoVertical = () => { + const ref = React.useRef(null); + const state = useSlider(ref, { vertical: true }); + + return ( +
+
+

Slide me

+
+ {state.isSliding ? '🏂' : '🎿'} +
+
+
{JSON.stringify(state, null, 2)}
+
+ ); +}; + storiesOf('UI|useSlider', module) .add('Docs', () => ) - .add('Demo', () => ); + .add('Horizontal', () => ) + .add('Vertical', () => );