import { Iterated, } from '../Iterated'; import { IteratorProps, } from './IteratorProps'; import * as React from 'react'; export const Iterator: React.FunctionComponent = ({ children, collection, filter = () => true, mapper = (child) => child, }) => { const output = []; for (const item of collection) { let finalItem = item; if (typeof filter === 'function' && !filter(finalItem)) { break; } if (Array.isArray(children) || (React.isValidElement(children) && children.type !== Iterated)) { finalItem = recursivelyReplaceIterated(children, finalItem); } if (typeof mapper === 'function') { finalItem = mapper(finalItem); } output.push(finalItem); } return ( <>{...output} ); }; export const recursivelyReplaceIterated = ( child: React.ReactNode, replacement: React.ReactNode, ): React.ReactNode => { if (React.isValidElement(child)) { if (child.type === Iterated) { return replacement; } return React.cloneElement(child, { children: React.Children.map( child.props.children, recursivelyReplaceIterated, ), }); } else if (Array.isArray(child)) { return child.map(recursivelyReplaceIterated); } return child; };