diff --git a/__tests__/scrollingCarousel.spec.tsx b/__tests__/scrollingCarousel.spec.tsx index 1a6f549..33a7f09 100644 --- a/__tests__/scrollingCarousel.spec.tsx +++ b/__tests__/scrollingCarousel.spec.tsx @@ -1,5 +1,5 @@ import React, { MouseEvent } from 'react'; -import { render, cleanup } from '@testing-library/react'; +import { render, cleanup, fireEvent, wait } from '@testing-library/react'; import { ScrollingCarousel } from '../src'; import { carouselItemNodes } from './__fixtures__/nodes'; import * as helpers from '../src/helpers'; @@ -21,15 +21,15 @@ describe('', () => { Object.defineProperties(HTMLDivElement.prototype, { scrollWidth: { value: 1000, - writable: true + writable: true, }, scrollLeft: { value: 100, - writable: true + writable: true, }, offsetWidth: { value: 200, - writable: true + writable: true, }, }); @@ -41,9 +41,7 @@ describe('', () => { it('should render right layout', async () => { const { getByTestId } = render( - , + , ); const carousel = getByTestId('carousel'); @@ -51,9 +49,10 @@ describe('', () => { expect(carousel.firstChild!.firstChild).toBeTruthy(); }); - it('should render arrow icons', async () => { + it('should render right arrow icon', async () => { const { getByTestId } = render( } children={carouselItemNodes(6)} />, @@ -64,6 +63,43 @@ describe('', () => { expect(carousel.firstChild); expect(carousel.firstChild!.firstChild).toBeTruthy(); expect(rightArrow!.firstChild).toBeInstanceOf(HTMLElement); + expect(leftArrow).toBe(null); + }); + + it('should render left arrow icon', async () => { + const { getByTestId } = render( + } + children={carouselItemNodes(6)} + />, + ); + const carousel = getByTestId('carousel'); + const rightArrow = carousel.querySelector('[data-arrow="right"]'); + const leftArrow = carousel.querySelector('[data-arrow="left"]'); + expect(carousel.firstChild); + expect(carousel.firstChild!.firstChild).toBeTruthy(); + expect(rightArrow).toBe(null); expect(leftArrow!.firstChild).toBeInstanceOf(HTMLElement); }); + + it('should add sliding class when isDown is true', async () => { + jest.spyOn((window as any).Math, 'abs').mockReturnValue(4); + + const { getByTestId, container } = render( + } + children={carouselItemNodes(6)} + />, + ); + + const sliderList = getByTestId('sliderList'); + fireEvent.mouseDown(sliderList, { pageX: 600 }); + fireEvent.mouseMove(sliderList, { pageX: 600 }); + + wait(() => { + expect(container.querySelector('.sliding')).toBeInTheDocument(); + }); + }); }); diff --git a/src/components/scrolling-carousel/defaultProps.ts b/src/components/scrolling-carousel/defaultProps.ts new file mode 100644 index 0000000..dba80bb --- /dev/null +++ b/src/components/scrolling-carousel/defaultProps.ts @@ -0,0 +1,9 @@ +import { SliderProps } from '.'; + +export const defaultProps: Required = { + children: [], + className: '', + leftIcon: null, + rightIcon: null, + triggerClickOn: 3, +}; diff --git a/src/components/scrolling-carousel/index.tsx b/src/components/scrolling-carousel/index.tsx index 1f8d839..e15a85c 100644 --- a/src/components/scrolling-carousel/index.tsx +++ b/src/components/scrolling-carousel/index.tsx @@ -9,13 +9,15 @@ import React, { import { Item, SlideDirection } from '../../types/carousel'; import styles from '../../styles/slider/styles.module.css'; import { getOuterWidth } from '../../helpers'; - -export const ScrollingCarousel: FunctionComponent = ({ - children, - className, - leftIcon, - rightIcon, -}: SliderProps) => { +import { defaultProps } from './defaultProps'; + +export const ScrollingCarousel: FunctionComponent = ( + userProps: SliderProps, +) => { + const { children, className, leftIcon, rightIcon, triggerClickOn } = { + ...defaultProps, + ...userProps, + }; const slider = useRef(null); const [isDown, setIsDown] = useState(false); const [position, setPosition] = useState({ @@ -67,10 +69,12 @@ export const ScrollingCarousel: FunctionComponent = ({ const mouseMove = (e: MouseEvent) => { if (!isDown) return; e.preventDefault(); - slider.current!.classList.add(styles.sliding); const eventPosition = e.pageX - slider.current!.offsetLeft; const slide = eventPosition - position.startX; + if (Math.abs(slide) > triggerClickOn) { + slider.current!.classList.add(styles.sliding); + } slider.current!.scrollLeft = position.scrollLeft - slide; }; @@ -136,9 +140,14 @@ export const ScrollingCarousel: FunctionComponent = ({ return (
- {showArrow.left && getArrow(SlideDirection.Right, 'left', leftIcon)} - {showArrow.right && getArrow(SlideDirection.Left, 'right', rightIcon)} + {showArrow.left && + leftIcon && + getArrow(SlideDirection.Right, 'left', leftIcon)} + {showArrow.right && + rightIcon && + getArrow(SlideDirection.Left, 'right', rightIcon)}
= ({ export interface SliderProps { children: Item[]; className?: string; - leftIcon?: ReactElement; - rightIcon?: ReactElement; + leftIcon?: ReactElement | null; + rightIcon?: ReactElement | null; + triggerClickOn?: number; } export type Arrows = {