From 9763f23c7b0c915c51d9f774e4b3bf3d63c21946 Mon Sep 17 00:00:00 2001 From: Hasan Genc Date: Fri, 3 Jul 2020 12:16:54 +0300 Subject: [PATCH] Change carousel items when items reload --- __tests__/helpers.spec.tsx | 42 ++++++++++++++++++++++++++++++- src/components/carousel/index.tsx | 9 +++++-- src/helpers/index.ts | 19 ++++++++++++-- 3 files changed, 65 insertions(+), 5 deletions(-) diff --git a/__tests__/helpers.spec.tsx b/__tests__/helpers.spec.tsx index 484dfa6..40a4a8c 100644 --- a/__tests__/helpers.spec.tsx +++ b/__tests__/helpers.spec.tsx @@ -82,9 +82,49 @@ describe('helpers', () => { const oldNodes = reactNodes('old', 5) as Item[]; const newNodes = reactNodes('new', 6) as Item[]; const expected = reactNodes('new', 5) as Item[]; + const infinite = true; + const slide = 5; - const result = helpers.updateNodes(oldNodes, newNodes); + const result = helpers.updateNodes(oldNodes, newNodes, slide, infinite); expect(result).toEqual(expected); }); + + it('should change nodes with new items when nodes not matched', async () => { + const oldNodes = reactNodes('old', 5) as Item[]; + const infinite = true; + const slide = 2; + const newNodes = ([ + { + key: 14, + props: '', + }, + { + key: 15, + props: '', + }, + ] as unknown) as Item[]; + const expectedNodes = ([ + { + key: 14, + props: '', + }, + { + key: 15, + props: '', + }, + { + key: 14, + props: '', + }, + { + key: 15, + props: '', + }, + ] as unknown) as Item[]; + + const result = helpers.updateNodes(oldNodes, newNodes, slide, infinite); + + expect(result).toEqual(expectedNodes); + }); }); diff --git a/src/components/carousel/index.tsx b/src/components/carousel/index.tsx index a8ee5d0..7140487 100644 --- a/src/components/carousel/index.tsx +++ b/src/components/carousel/index.tsx @@ -32,7 +32,12 @@ export const Carousel: FunctionComponent = (userProps: CarouselPr if (props.dynamic) { React.useEffect(() => { - const newItems = updateNodes(items, userProps.children); + const newItems = updateNodes( + items, + userProps.children, + props.slide, + props.infinite, + ); setItems(newItems); }, userProps.children); } @@ -156,7 +161,7 @@ export interface CarouselProps { className?: string; useArrowKeys?: boolean; a11y?: { [key: string]: string }; - dynamic: boolean; + dynamic?: boolean; } export interface CarouselState { diff --git a/src/helpers/index.ts b/src/helpers/index.ts index 35fb81d..5b5595a 100644 --- a/src/helpers/index.ts +++ b/src/helpers/index.ts @@ -144,8 +144,23 @@ export function getOuterWidth(el: HTMLElement) { ); } -export function updateNodes(oldItems: Item[], newItems: Item[]): Item[] { - return oldItems.map((oldItem) => { +export function updateNodes( + oldItems: Item[], + newItems: Item[], + slide: number, + infinite: boolean, +): Item[] { + const matchedItems = oldItems.map((oldItem) => { return newItems.find((newItem) => oldItem.key === newItem.key) as Item; }); + + if (areItemsNotMatched(matchedItems)) { + return initItems(newItems, slide, infinite); + } + + return matchedItems; +} + +export function areItemsNotMatched(items: Item[]): boolean { + return items.some((item) => item === undefined); }