Skip to content

Commit

Permalink
fix: fix carousel click problem (#99)
Browse files Browse the repository at this point in the history
Co-authored-by: Burcu Saglam <[email protected]>
  • Loading branch information
saglamburcu and Burcu Saglam authored Feb 8, 2023
1 parent 6eb0727 commit 16e77ad
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 20 deletions.
52 changes: 44 additions & 8 deletions __tests__/scrollingCarousel.spec.tsx
Original file line number Diff line number Diff line change
@@ -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';
Expand All @@ -21,15 +21,15 @@ describe('<ScrollingCarousel />', () => {
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,
},
});

Expand All @@ -41,19 +41,18 @@ describe('<ScrollingCarousel />', () => {

it('should render right layout', async () => {
const { getByTestId } = render(
<ScrollingCarousel
children={carouselItemNodes(6)}
/>,
<ScrollingCarousel triggerClickOn={3} children={carouselItemNodes(6)} />,
);
const carousel = getByTestId('carousel');

expect(carousel.firstChild);
expect(carousel.firstChild!.firstChild).toBeTruthy();
});

it('should render arrow icons', async () => {
it('should render right arrow icon', async () => {
const { getByTestId } = render(
<ScrollingCarousel
triggerClickOn={3}
rightIcon={<i />}
children={carouselItemNodes(6)}
/>,
Expand All @@ -64,6 +63,43 @@ describe('<ScrollingCarousel />', () => {
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(
<ScrollingCarousel
triggerClickOn={3}
leftIcon={<i />}
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(
<ScrollingCarousel
triggerClickOn={3}
leftIcon={<i />}
children={carouselItemNodes(6)}
/>,
);

const sliderList = getByTestId('sliderList');
fireEvent.mouseDown(sliderList, { pageX: 600 });
fireEvent.mouseMove(sliderList, { pageX: 600 });

wait(() => {
expect(container.querySelector('.sliding')).toBeInTheDocument();
});
});
});
9 changes: 9 additions & 0 deletions src/components/scrolling-carousel/defaultProps.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { SliderProps } from '.';

export const defaultProps: Required<SliderProps> = {
children: [],
className: '',
leftIcon: null,
rightIcon: null,
triggerClickOn: 3,
};
34 changes: 22 additions & 12 deletions src/components/scrolling-carousel/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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<SliderProps> = ({
children,
className,
leftIcon,
rightIcon,
}: SliderProps) => {
import { defaultProps } from './defaultProps';

export const ScrollingCarousel: FunctionComponent<SliderProps> = (
userProps: SliderProps,
) => {
const { children, className, leftIcon, rightIcon, triggerClickOn } = {
...defaultProps,
...userProps,
};
const slider = useRef<HTMLDivElement>(null);
const [isDown, setIsDown] = useState(false);
const [position, setPosition] = useState({
Expand Down Expand Up @@ -67,10 +69,12 @@ export const ScrollingCarousel: FunctionComponent<SliderProps> = ({
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;
};

Expand Down Expand Up @@ -136,9 +140,14 @@ export const ScrollingCarousel: FunctionComponent<SliderProps> = ({

return (
<div className={`${styles.sliderBase} ${className}`} data-testid="carousel">
{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)}
<div
data-testid="sliderList"
ref={ref}
onMouseDown={mouseDown}
onMouseLeave={mouseUp}
Expand All @@ -155,8 +164,9 @@ export const ScrollingCarousel: FunctionComponent<SliderProps> = ({
export interface SliderProps {
children: Item[];
className?: string;
leftIcon?: ReactElement;
rightIcon?: ReactElement;
leftIcon?: ReactElement | null;
rightIcon?: ReactElement | null;
triggerClickOn?: number;
}

export type Arrows = {
Expand Down

0 comments on commit 16e77ad

Please sign in to comment.