master
Hasan Genc 5 years ago
parent b73820cd26
commit f43229d96a
  1. 121
      src/components/slider/index.tsx
  2. 3
      src/index.ts
  3. 20
      src/styles/slider/styles.module.css
  4. 8
      src/styles/slider/styles.module.css.d.ts

@ -0,0 +1,121 @@
import React, {
FunctionComponent,
MouseEvent,
useState,
useRef,
useCallback,
} from 'react';
import { Item, SlideDirection } from '../../types/carousel';
import styles from '../../styles/slider/styles.module.css';
export const Slider: FunctionComponent<SliderProps> = ({
children,
className,
}: SliderProps) => {
const slider = useRef<HTMLDivElement>(null);
const [isDown, setIsDown] = useState(false);
const [position, setPosition] = useState({
startX: 0,
scrollLeft: 0,
});
const showArrows = (): Arrows => {
const sliderElement = slider.current;
return {
left: !!sliderElement && sliderElement.scrollLeft > 0,
right:
!!sliderElement &&
sliderElement.scrollWidth >
sliderElement.scrollLeft + sliderElement.offsetWidth,
};
};
const [showArrow, setShowArrow] = useState<Arrows>(showArrows());
const ref = useCallback(
(node) => {
if (node !== null) {
Object.defineProperty(slider, 'current', { value: node });
setShowArrow(showArrows());
}
},
[slider],
);
const mouseDown = (e: MouseEvent) => {
setIsDown(true);
setPosition({
startX: e.pageX - slider.current!.offsetLeft,
scrollLeft: slider.current!.scrollLeft,
});
};
const mouseUp = (_: MouseEvent) => {
setIsDown(false);
setShowArrow(showArrows());
};
const mouseMove = (e: MouseEvent) => {
if (!isDown) return;
e.preventDefault();
const eventPosition = e.pageX - slider.current!.offsetLeft;
const slide = eventPosition - position.startX;
slider.current!.scrollLeft = position.scrollLeft - slide;
};
const slide = (direction: SlideDirection) => {
const slideAmount = -1 * direction * slider.current!.offsetWidth * 0.9;
const start = slider.current!.scrollLeft;
smoothHorizontalScroll(500, slideAmount, start);
setShowArrow(showArrows());
};
const smoothHorizontalScroll = (time: number, amount: number, start: number) => {
let curTime = 0;
for (let scrollCounter = 0; curTime <= time; scrollCounter++) {
window.setTimeout(
smoothHorizontalScrollBehavior,
curTime,
(scrollCounter * amount) / 100 + start,
);
curTime += time / 100;
}
};
const smoothHorizontalScrollBehavior = (amount: number) => {
slider.current!.scrollLeft = amount;
setShowArrow(showArrows());
};
return (
<div className={`${styles.sliderBase} ${className}`}>
{showArrow.left && (
<button onClick={() => slide(SlideDirection.Left)}>left</button>
)}
{showArrow.right && (
<button onClick={() => slide(SlideDirection.Right)}>right</button>
)}
<div
ref={ref}
onMouseDown={mouseDown}
onMouseLeave={mouseUp}
onMouseUp={mouseUp}
onMouseMove={mouseMove}
className={styles.slider}
>
{children}
</div>
</div>
);
};
export interface SliderProps {
children: Item[];
className?: string;
}
export type Arrows = {
left: boolean;
right: boolean;
};

@ -1,3 +1,4 @@
import { Carousel } from './components/carousel';
import { Slider } from './components/slider';
export { Carousel };
export { Carousel, Slider };

@ -0,0 +1,20 @@
.sliderBase {
width: 100%;
position: relative;
}
.slider {
display: flex;
overflow-x: auto;
scrollbar-width: none; /* Firefox 64 */
-ms-overflow-style: none; /* Internet Explorer 11 */
}
.slider::-webkit-scrollbar {
/** WebKit */
display: none;
}
.slider > * {
flex: 0 0 auto;
}

@ -0,0 +1,8 @@
export const sliderBase: string;
export const slider: string;
interface Namespace {
sliderBase: string;
slider: string;
}
declare const stylesModule: Namespace;
export default stylesModule;
Loading…
Cancel
Save