import React, { forwardRef, useEffect, useState } from 'react'; import { useEvent, useForwardedRef } from '@anton.bobrov/react-hooks'; import { Timeline } from 'vevet'; import { IProps } from './types'; export const FadeContentItem = forwardRef( ( { className, children, duration, state: stateProp, onShow: onShowProp, onShowProgress: onShowProgressProp, onShown: onShownProp, onHide: onHideProp, onHidden: onHiddenProp, }, forwardedRef, ) => { const ref = useForwardedRef(forwardedRef); const onShow = useEvent(onShowProp); const onShowProgress = useEvent(onShowProgressProp); const onShown = useEvent(onShownProp); const onHide = useEvent(onHideProp); const onHidden = useEvent(onHiddenProp); const render = useEvent((state: 'hide' | 'show', p: number) => { if (state === 'show') { ref.current!.style.opacity = `${p}`; } if (state === 'hide') { ref.current!.style.opacity = `${1 - p}`; } }); const [initialState] = useState(stateProp); useEffect(() => { if (initialState === stateProp) { return undefined; } if (stateProp !== 'hide' && stateProp !== 'show') { return undefined; } const element = ref.current!; if (stateProp === 'show') { onShow(); } else if (stateProp === 'hide') { onHide(); } const timeline = new Timeline({ duration }); timeline.addCallback('progress', ({ p, e }) => { render(stateProp, e); if (stateProp === 'show') { onShowProgress(element, p); } if (stateProp === 'show' && p === 1) { onShown(); } else if (stateProp === 'hide' && p === 1) { onHidden(); } }); timeline.play(); return () => timeline.destroy(); }, [ initialState, stateProp, ref, duration, onShow, onShowProgress, onShown, onHide, onHidden, render, ]); return (
{children}
); }, ); FadeContentItem.displayName = 'FadeContentItem';