import React, { forwardRef, useEffect, useState } from 'react'; import { useForwardedRef, usePrevious } from '@anton.bobrov/react-hooks'; import cn from 'classnames'; import { TKey } from '@types'; import { prefixedClasNames } from '../../utils/prefixedClassNames'; import { IFadeContentProps } from './types'; import { FadeContentItem } from './Item'; import { useParentHeight } from './utils/useParentHeight'; /** * FadeContent component for displaying content with fade-in and fade-out transitions. * This component is ideal for creating animated tabs, providing a smooth transition. * * @link See examples https://antonbobrov.github.io/react-kit/?path=/docs/wrappers-fadecontent--docs * * @requires Requires styles: `@import '~@anton.bobrov/react-components/lib/styles/components/FadeContent';` */ export const FadeContent = forwardRef( ( { className, style, content, activeKey, duration = 600, hasFocus = true }, forwardedRef, ) => { const ref = useForwardedRef(forwardedRef); const prevActiveKey = usePrevious(activeKey, activeKey); const [showKey, setShowKey] = useState(undefined); const [hideKey, setHideKey] = useState(undefined); const [currentKey, setCurrentKey] = useState(activeKey); const getState = (key: TKey) => { if (key === hideKey) { return 'hide'; } if (key === showKey) { return 'show'; } if (key === currentKey) { return 'active'; } return 'unactive'; }; useEffect(() => { if (activeKey !== prevActiveKey) { setHideKey(prevActiveKey); } }, [activeKey, prevActiveKey]); const parentHeight = useParentHeight(ref); return (
{content.map(({ key, children }) => { const state = getState(key); return ( hasFocus && ref.current?.focus({ preventScroll: true }) } onShowProgress={(element, progress) => parentHeight.interpolate( element.getBoundingClientRect().height, progress, ) } onShown={() => { setHideKey(undefined); setShowKey(undefined); parentHeight.reset(); }} onHide={() => parentHeight.save()} onHidden={() => { setHideKey(undefined); setShowKey(activeKey); setCurrentKey(activeKey); }} > {state !== 'unactive' && children} ); })}
); }, ); FadeContent.displayName = 'FadeContent';