Press n or j to go to the next uncovered block, b, p or k for the previous block.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 | 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 88x 88x 88x 88x 88x 88x 88x 88x 88x 88x 88x 88x 88x 88x 88x 88x 87x 87x 87x 87x 87x 87x 87x 88x 88x 88x 88x 88x 88x 88x 88x 88x 88x 88x 88x 88x 88x 88x 88x 88x 88x 88x 88x 88x 1x | import React, { useMemo, useState, useId } from 'react'; import { motion } from 'framer-motion'; import classNames from 'classnames'; import CollapseHeader from './CollapseHeader'; import { useFallbackTranslation } from '@/hooks/useFallbackTranslation'; interface IPadding { paddingTop?: number | null; paddingRight?: number | null; paddingBottom?: number | null; paddingLeft?: number | null; } interface CollapseProps { children: React.ReactNode; duration?: number; ease?: 'easeInOut' | 'easeIn' | 'easeOut' | 'linear'; padding?: IPadding | null; className?: string; iconArrowLast?: boolean; header?: string; } const defaultPadding: Required<IPadding> = { paddingTop: 8, paddingRight: 8, paddingBottom: 8, paddingLeft: 8, }; const Collapse: React.FC<CollapseProps> = ({ className, children, duration = 0.35, ease = 'easeInOut', padding = {}, iconArrowLast = false, header, }) => { const [collapsed, setCollapsed] = useState<boolean>(false); const { t } = useFallbackTranslation(); const collapseId = useId(); const mergedPadding: Required<IPadding> = useMemo(() => ({ ...defaultPadding, ...padding }), [padding]); const containerClass = useMemo(() => classNames('collapsed', className), [className]); return ( <div className={containerClass}> {header && ( <CollapseHeader id={collapseId} isOpen={collapsed} iconArrowLast={iconArrowLast} label={t(header)} onClick={() => setCollapsed((prev) => !prev)} /> )} <motion.div id={`${collapseId}-content`} role="region" aria-labelledby={collapseId} initial={false} animate={{ height: collapsed ? 'auto' : 0, opacity: collapsed ? 1 : 0, paddingLeft: `${mergedPadding.paddingLeft}px`, paddingRight: `${mergedPadding.paddingRight}px`, paddingTop: collapsed ? `${mergedPadding.paddingTop}px` : '0', paddingBottom: collapsed ? `${mergedPadding.paddingBottom}px` : '0', }} style={{ overflow: 'hidden' }} className="d-block" transition={{ duration, ease }} aria-hidden={!collapsed} > {children} </motion.div> </div> ); }; export default Collapse; |