/* eslint-disable arrow-body-style */ import * as React from 'react'; // @ts-ignore import CSSMotion from 'rc-animate/lib/CSSMotion'; import classNames from 'classnames'; import List, { ListRef } from '../src/List'; import './animate.less'; let uuid = 0; function genItem() { const item = { id: `key_${uuid}`, uuid, }; uuid += 1; return item; } const originData: Item[] = []; for (let i = 0; i < 1000; i += 1) { originData.push(genItem()); } interface Item { id: string; uuid: number; } interface MyItemProps extends Item { visible: boolean; motionAppear: boolean; onClose: (id: string) => void; onLeave: (id: string) => void; onAppear: (...args: any[]) => void; onInsertBefore: (id: string) => void; onInsertAfter: (id: string) => void; } const getCurrentHeight = (node: HTMLElement) => ({ height: node.offsetHeight }); const getMaxHeight = (node: HTMLElement) => { return { height: node.scrollHeight }; }; const getCollapsedHeight = () => ({ height: 0, opacity: 0 }); const MyItem: React.ForwardRefRenderFunction = ( { id, uuid: itemUuid, visible, onClose, onLeave, onAppear, onInsertBefore, onInsertAfter, motionAppear, }, ref, ) => { const motionRef = React.useRef(false); React.useEffect(() => { return () => { if (motionRef.current) { onAppear(); } }; }, []); return ( { motionRef.current = true; return getMaxHeight(node); }} onAppearEnd={onAppear} onLeaveStart={getCurrentHeight} onLeaveActive={getCollapsedHeight} onLeaveEnd={() => { onLeave(id); }} > {({ className, style }, passedMotionRef) => { return (
{id}
); }}
); }; const ForwardMyItem = React.forwardRef(MyItem); const Demo = () => { const [data, setData] = React.useState(originData); const [closeMap, setCloseMap] = React.useState<{ [id: number]: boolean }>({}); const [animating, setAnimating] = React.useState(false); const [insertIndex, setInsertIndex] = React.useState(); const listRef = React.useRef(); const onClose = (id: string) => { setCloseMap({ ...closeMap, [id]: true, }); }; const onLeave = (id: string) => { const newData = data.filter(item => item.id !== id); setData(newData); }; const onAppear = (...args: any[]) => { console.log('Appear:', args); setAnimating(false); }; function lockForAnimation() { setAnimating(true); } const onInsertBefore = (id: string) => { const index = data.findIndex(item => item.id === id); const newData = [...data.slice(0, index), genItem(), ...data.slice(index)]; setInsertIndex(index); setData(newData); lockForAnimation(); }; const onInsertAfter = (id: string) => { const index = data.findIndex(item => item.id === id) + 1; const newData = [...data.slice(0, index), genItem(), ...data.slice(index)]; setInsertIndex(index); setData(newData); lockForAnimation(); }; return (

Animate

Current: {data.length} records

data={data} data-id="list" height={200} itemHeight={20} itemKey="id" // disabled={animating} ref={listRef} style={{ border: '1px solid red', boxSizing: 'border-box', }} // onSkipRender={onAppear} // onItemRemove={onAppear} > {(item, index) => ( )}
); }; export default Demo;