import React, { useReducer } from 'react'; import { useAnimatedListItems } from './useAnimatedListItems'; type Mutation = 'reverse' | 'randomize' | 'insert' | 'remove'; function getRandomChar(): string { return String.fromCharCode(98 + Math.floor(Math.random() * 25)); } function getRandomItemName(): string { return `Serial Number - ${new Array(16) .fill('') .map(() => getRandomChar()) .join('')}`; } /** * Randomizer function shamelessly copied unmodified from https://stackoverflow.com/a/12646864 * * License: https://creativecommons.org/licenses/by-sa/4.0/ * * Author(s): * - https://stackoverflow.com/users/310500/laurens-holst * - https://stackoverflow.com/users/8112776/ashleedawg */ function shuffleArray(array) { for (let i = array.length - 1; i > 0; i--) { const j = Math.floor(Math.random() * (i + 1)); [array[i], array[j]] = [array[j], array[i]]; } } function insertRandomlyIntoArray(array: string[]): string[] { const insertBefore = Math.floor(Math.random() * (array.length + 1)); const newItem = getRandomItemName(); if (insertBefore === 0) { return [newItem, ...array]; } return [ ...array.slice(0, insertBefore), newItem, ...array.slice(insertBefore), ]; } function removeRandomlyFromArray(array: string[]): string[] { const removeIndex = Math.floor(Math.random() * array.length); if (removeIndex === 0) { return [...array.slice(1)]; } if (removeIndex === array.length) { return [...array.slice(0, -1)]; } return [...array.slice(0, removeIndex), ...array.slice(removeIndex + 1)]; } export const AnimatedListDemo = () => { const [items, mutateItems] = useReducer( (prevState: string[], mutation: Mutation) => { let newState: string[] = [...prevState]; switch (mutation) { case 'reverse': newState.reverse(); break; case 'randomize': shuffleArray(newState); break; case 'insert': newState = insertRandomlyIntoArray(newState); break; case 'remove': newState = removeRandomlyFromArray(newState); break; default: return prevState; } return newState; }, new Array(4).fill('').map(() => getRandomItemName()), ); const { updateItemRef, updateItemPositions, itemStyles } = useAnimatedListItems({ keys: items }); return ( <>