From 89d4384bb34cfbe33b5daee36bca3f8c13048ba9 Mon Sep 17 00:00:00 2001 From: Hasan Genc Date: Mon, 22 Jun 2020 11:18:36 +0300 Subject: [PATCH] Add dynamic prop --- __tests__/__fixtures__/nodes.tsx | 27 ++++++++++- __tests__/carousel.spec.tsx | 64 +++++++++++++++++++++---- src/components/carousel/defaultProps.ts | 1 + src/components/carousel/index.tsx | 11 +++-- website/docs/carousel.md | 27 ++++++----- 5 files changed, 104 insertions(+), 26 deletions(-) diff --git a/__tests__/__fixtures__/nodes.tsx b/__tests__/__fixtures__/nodes.tsx index 4b1ed25..719efad 100644 --- a/__tests__/__fixtures__/nodes.tsx +++ b/__tests__/__fixtures__/nodes.tsx @@ -1,4 +1,4 @@ -import React from 'react'; +import React, { FunctionComponent, useState } from 'react'; export const carouselItemNodes = (len: number) => { return new Array(len).fill(0).map((_, i) => { @@ -6,6 +6,31 @@ export const carouselItemNodes = (len: number) => { }); }; +export const dynamicCarouselItemNodes = () => { + const Component: FunctionComponent = ({ + id, + }: DynamicCarouselItemNodesProps) => { + const [state, setstate] = useState(0); + return ( + + ); + }; + + return [ + , + , + , + , + ]; +}; + +interface DynamicCarouselItemNodesProps { + id: number; + children?: React.ReactNode; +} + export const reactNodes = (prop: string, len: number) => { return new Array(len).fill(0).map((_, i) => { return { diff --git a/__tests__/carousel.spec.tsx b/__tests__/carousel.spec.tsx index 6ca7093..4dda1ab 100644 --- a/__tests__/carousel.spec.tsx +++ b/__tests__/carousel.spec.tsx @@ -2,7 +2,7 @@ import React, { MouseEvent } from 'react'; import { render, cleanup, fireEvent } from '@testing-library/react'; import { Carousel } from '../src/components/carousel'; import { defaultProps } from '../src/components/carousel/defaultProps'; -import { carouselItemNodes } from './__fixtures__/nodes'; +import { carouselItemNodes, dynamicCarouselItemNodes } from './__fixtures__/nodes'; import * as helpers from '../src/helpers'; describe('', () => { @@ -40,7 +40,11 @@ describe('', () => { it('should render right layout', async () => { const { getByTestId } = render( - , + , ); const carousel = getByTestId('carousel'); @@ -52,7 +56,11 @@ describe('', () => { it('should transform when pressing arrow keys', async () => { const { getByTestId } = render( - , + , ); const carousel = getByTestId('carousel'); @@ -69,7 +77,11 @@ describe('', () => { it("shouldn't listen keyboard event if useArrowKeys option false", async () => { const { getByTestId } = render( - , + , ); const carousel = getByTestId('carousel'); @@ -115,7 +127,11 @@ describe('', () => { it('should slide to left when click left button', async () => { const { getByTestId } = render( - , + , ); const carousel = getByTestId('carousel'); const button = carousel.querySelector('button'); @@ -134,7 +150,11 @@ describe('', () => { it('should slide to right when click right button', async () => { const { getByTestId } = render( - , + , ); const carousel = getByTestId('carousel'); const button = carousel.querySelectorAll('button')[1]; @@ -218,7 +238,11 @@ describe('', () => { it("shouldn't rotate items if carousel is not infinite", async () => { const { getByTestId } = render( - , + , ); const carousel = getByTestId('carousel'); const button = carousel.querySelector('button'); @@ -237,7 +261,11 @@ describe('', () => { it('should rotate items if carousel is infinite', async () => { const { getByTestId } = render( - , + , ); const carousel = getByTestId('carousel'); const button = carousel.querySelector('button'); @@ -253,4 +281,24 @@ describe('', () => { defaultProps.transition * 1000, ); }); + + it('should render stateful items when dynamic prop is true', async () => { + const { getByTestId } = render( + , + ); + + const carousel = getByTestId('trackList'); + const button = carousel.querySelector('button'); + + expect(button).not.toBeNull(); + + fireEvent.click(button!); + + expect(button!.innerHTML).toEqual('1'); + }); }); diff --git a/src/components/carousel/defaultProps.ts b/src/components/carousel/defaultProps.ts index 508eedf..b86e0b7 100644 --- a/src/components/carousel/defaultProps.ts +++ b/src/components/carousel/defaultProps.ts @@ -12,4 +12,5 @@ export const defaultProps: Required = { className: '', useArrowKeys: false, a11y: {}, + dynamic: false, }; diff --git a/src/components/carousel/index.tsx b/src/components/carousel/index.tsx index 950ffff..a8ee5d0 100644 --- a/src/components/carousel/index.tsx +++ b/src/components/carousel/index.tsx @@ -30,10 +30,12 @@ export const Carousel: FunctionComponent = (userProps: CarouselPr getShowArrow(props.children.length, props.show, props.infinite, current), ); - React.useEffect(() => { - const newItems = updateNodes(items, userProps.children); - setItems(newItems); - }, userProps.children); + if (props.dynamic) { + React.useEffect(() => { + const newItems = updateNodes(items, userProps.children); + setItems(newItems); + }, userProps.children); + } const slide = (direction: SlideDirection, slide: number): void => { if ( @@ -154,6 +156,7 @@ export interface CarouselProps { className?: string; useArrowKeys?: boolean; a11y?: { [key: string]: string }; + dynamic: boolean; } export interface CarouselState { diff --git a/website/docs/carousel.md b/website/docs/carousel.md index e03dbf2..0eabf7c 100644 --- a/website/docs/carousel.md +++ b/website/docs/carousel.md @@ -11,16 +11,17 @@ Creates carousel component. ### Props -| Name | type | required | default | descripiton | -| ------------ | :-----: | -------: | ------: | --------------------------------------------------------------------------------: | -| children | Node[] | true | [] | Child items that will be wrapped by carousel | -| show | number | false | 1 | number of items to show at per slide | -| slide | number | false | 1 | number of how many items to slide | -| infinite | boolean | false | true | scrolling infinity | -| transition | number | false | 0.5 | same as css transition property's second value | -| swiping | boolean | false | false | enable swiping/dragging with mouse/touch events | -| swipeOn | number | false | 1 | percantage of item width that slides when user drag count exceeds | -| responsive | boolean | false | false | enables the feature that adjusts items width according to screen size dynamically | -| className | string | false | "" | same as react's className property | -| useArrowKeys | boolean | false | false | enables sliding when press arrow keys | -| a11y | Array | false | {} | accessibility attributes | +| Name | type | required | default | descripiton | +| ------------ | :-----: | -------: | ------: | ----------------------------------------------------------------------------------------------: | +| children | Node[] | true | [] | Child items that will be wrapped by carousel | +| show | number | false | 1 | number of items to show at per slide | +| slide | number | false | 1 | number of how many items to slide | +| infinite | boolean | false | true | scrolling infinity | +| transition | number | false | 0.5 | same as css transition property's second value | +| swiping | boolean | false | false | enable swiping/dragging with mouse/touch events | +| swipeOn | number | false | 1 | percantage of item width that slides when user drag count exceeds | +| responsive | boolean | false | false | enables the feature that adjusts items width according to screen size dynamically | +| className | string | false | "" | same as react's className property | +| useArrowKeys | boolean | false | false | enables sliding when press arrow keys | +| a11y | Array | false | {} | accessibility attributes | +| dynamic | Boolean | false | false | if items are stateful, specify this option as true. Also give unique key to each item (like id) |