Skip to content

Commit

Permalink
feat: 🎸 add [vertical] flag to useSlider() hook
Browse files Browse the repository at this point in the history
  • Loading branch information
streamich committed Jan 3, 2020
1 parent 1980d46 commit 777865c
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 7 deletions.
19 changes: 13 additions & 6 deletions src/useSlider.ts
Expand Up @@ -15,6 +15,7 @@ export interface Options {
onScrubStop: () => void;
reverse: boolean;
styles: boolean | CSSProperties;
vertical?: boolean;
}

const noop = () => {};
Expand Down Expand Up @@ -59,13 +60,17 @@ const useSlider = (ref: RefObject<HTMLElement>, options: Partial<Options> = {}):
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);
Expand All @@ -83,19 +88,21 @@ const useSlider = (ref: RefObject<HTMLElement>, options: Partial<Options> = {}):
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;
Expand Down Expand Up @@ -126,7 +133,7 @@ const useSlider = (ref: RefObject<HTMLElement>, options: Partial<Options> = {}):
} else {
return undefined;
}
}, [ref]);
}, [ref, options.vertical]);

return state;
};
Expand Down
20 changes: 19 additions & 1 deletion stories/useSlider.story.tsx
Expand Up @@ -20,6 +20,24 @@ const Demo = () => {
);
};

const DemoVertical = () => {
const ref = React.useRef(null);
const state = useSlider(ref, { vertical: true });

return (
<div>
<div ref={ref} style={{ position: 'relative', background: 'yellow', padding: 4, width: 30, height: 400 }}>
<p style={{ margin: 0, textAlign: 'center' }}>Slide me</p>
<div style={{ position: 'absolute', left: 0, top: (100 * state.value) + '%', transform: 'scale(2)' }}>
{state.isSliding ? '🏂' : '🎿'}
</div>
</div>
<pre>{JSON.stringify(state, null, 2)}</pre>
</div>
);
};

storiesOf('UI|useSlider', module)
.add('Docs', () => <ShowDocs md={require('../docs/useSlider.md')} />)
.add('Demo', () => <Demo />);
.add('Horizontal', () => <Demo />)
.add('Vertical', () => <DemoVertical />);

0 comments on commit 777865c

Please sign in to comment.