Untitled

mail@pastecode.io avatar
unknown
javascript
2 months ago
3.7 kB
2
Indexable
Never
import React, {useEffect, useRef, useState} from "react";
import classNames from "classnames";
import OutsideClickHandler from "react-outside-click-handler";

const Accordion = (props) => {

    const {
        title,
        handleScrollChange = false,
        children,
        isOpen = false,
        disableOutsideClick = false,
        contentClassNames,
        scrollValue = 0
    } = props;

    const childrenRef = useRef();
    const scrollRef = useRef();
    const firstVisit = useRef(true);

    const [open, setOpen] = useState(isOpen);

    const handleScroll = () => {
        if (handleScrollChange) {
            // Eğer dış bileşene bir geri çağrı işlevi geçirildiyse, scrollTop değerini ona ilet
            handleScrollChange(scrollRef.current.scrollTop);
        }
    };

    const handleTransitionEnd = () => {
        if (!open) {
            childrenRef.current.classList.add('hidden');
        }
    };

    useEffect(() => {
        if (open) {
            childrenRef.current.classList.remove('hidden');
        }
    }, [open]);

    useEffect(() => {
        scrollRef.current.scrollTop = scrollValue;
    }, [scrollValue])

    return (
        <OutsideClickHandler onOutsideClick={() => {!disableOutsideClick && setOpen(open => false)}}>
            <div className="outline-none text-sm mt-5 mb-5">
                <button
                    className={classNames(`${contentClassNames} flex justify-between border rounded-[10px] px-4 py-[7px] items-center transition  duration-500 cursor-pointer pl-7 relative group-focus-within:border-b-0 border-box w-full pr-1 bg-[#fafafa]`, {
                        "rounded-b-none" : open
                    })}
                    onClick={() => {
                        setOpen(open => !open);
                        firstVisit.current = false
                    }}
                >
                    <div
                        className={classNames("items-center inline-flex justify-center transform transition duration-500 absolute left-0 ml-2 mr-auto h-full", {
                            "rotate-90" : open
                        })}
                    >
                        <span className={classNames("material-symbols-outlined transition-colors duration-300", {
                            "text-primary" : open,
                            "text-base-text": !open
                        })}>
                            arrow_forward_ios
                        </span>
                    </div>
                    <div className="ml-2">
                        <p className={classNames("font-bold text-start transition-colors duration-300", {
                            "text-primary" : open
                        })}>
                            {title}
                        </p>
                    </div>
                </button>
                <div
                    ref={scrollRef}
                    className={classNames(`${contentClassNames || ""} transition-all duration-500 border-box rounded-[10px] rounded-t-none px-4 bg-[#fafafa]`, {
                        "max-h-screen overflow-y-scroll border-x border-b pt-2" : open,
                        "max-h-0" : !open
                    })}
                    onTransitionEnd={handleTransitionEnd}
                    onScroll={handleScrollChange}
                >
                    <div
                        ref={childrenRef}
                        className={`h-[600px] ${!open && 'animate-fadeOut'} ${firstVisit.current ? 'hidden' : ''}`}
                    >
                        {children}
                    </div>
                </div>
            </div>
        </OutsideClickHandler>
    )
}

export default Accordion;
Leave a Comment