Skip to content

Commit

Permalink
Merge pull request #258 from ameerul-deriv/ameerul-add-scroll-to-acco…
Browse files Browse the repository at this point in the history
…rdion

Ameerul / Add Scroll To Accordion Functionality
  • Loading branch information
shayan-deriv authored Sep 30, 2024
2 parents 5017050 + 7a9638b commit dcf7793
Show file tree
Hide file tree
Showing 2 changed files with 82 additions and 64 deletions.
2 changes: 1 addition & 1 deletion src/components/Accordion/Accordion.scss
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ $animation-duration: 0.3s;
}
&__content {
width: 100%;
overflow: auto;
overflow: scroll;
opacity: 0;
background-color: var(--content-bg-color);
transition: all $animation-duration ease;
Expand Down
144 changes: 81 additions & 63 deletions src/components/Accordion/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import React, {
ReactNode,
useEffect,
ComponentProps,
forwardRef,
} from "react";
import Chevron from "./Chevron.svg";
import clsx from "clsx";
Expand All @@ -15,6 +16,7 @@ type AccordionProps = Omit<ComponentProps<"div">, "title"> & {
children: ReactNode;
defaultOpen?: boolean;
isCompact?: boolean;
onScrollToAccordion?: () => void;
title: string | JSX.Element;
variant?: AccordionVariants;
headerClassName?: string;
Expand All @@ -27,80 +29,96 @@ const AccordionVariant = {
underline: "deriv-accordion--underline",
} as const;

export const Accordion = ({
defaultOpen = false,
children,
isCompact = false,
title,
variant = "underline",
className,
headerClassName,
contentClassName,
...props
}: AccordionProps) => {
const [active, setActive] = useState(defaultOpen);
const [setHeight, setHeightState] = useState(defaultOpen ? "auto" : "0px");
export const Accordion = forwardRef<HTMLDivElement, AccordionProps>(
(
{
defaultOpen = false,
children,
isCompact = false,
onScrollToAccordion,
title,
variant = "underline",
className,
headerClassName,
contentClassName,
...props
},
ref,
) => {
const [active, setActive] = useState(defaultOpen);
const [heightState, setHeightState] = useState(
defaultOpen ? "auto" : "0px",
);

const content = useRef<HTMLDivElement | null>(null);
const content = useRef<HTMLDivElement | null>(null);

useEffect(() => {
const scrollHeight = content?.current?.scrollHeight;
setHeightState(active ? `${scrollHeight}px` : "0px");
}, [active]);
useEffect(() => {
const scrollHeight = content?.current?.scrollHeight;
setHeightState(active ? `${scrollHeight}px` : "0px");
}, [active]);

const toggleAccordion = () => setActive(!active);
const toggleAccordion = () => {
const newActiveState = !active;
setActive(newActiveState);
setTimeout(() => {
if (onScrollToAccordion && newActiveState)
onScrollToAccordion();
}, 200);
};

return (
<div
className={clsx(
"deriv-accordion",
AccordionVariant[variant],
{
"deriv-accordion--compact": isCompact,
},
className,
)}
{...props}
>
<button
className={clsx(
"deriv-accordion__header",
{
"deriv-accordion__header--active": active,
},
headerClassName,
)}
onClick={toggleAccordion}
aria-expanded={active}
type="button"
>
{typeof title === "string" ? <p>{title}</p> : title}
<img
src={Chevron}
className={clsx("deriv-accordion__icon", {
"deriv-accordion__icon--active": active,
})}
/>
</button>
return (
<div
ref={content}
style={{ maxHeight: setHeight }}
className={clsx(
"deriv-accordion__content",
"deriv-accordion",
AccordionVariant[variant],
{
"deriv-accordion__content--active": active,
"deriv-accordion--compact": isCompact,
},
contentClassName
className,
)}
ref={ref}
{...props}
>
<button
className={clsx(
"deriv-accordion__header",
{
"deriv-accordion__header--active": active,
},
headerClassName,
)}
onClick={toggleAccordion}
aria-expanded={active}
type="button"
>
{typeof title === "string" ? <p>{title}</p> : title}
<img
src={Chevron}
className={clsx("deriv-accordion__icon", {
"deriv-accordion__icon--active": active,
})}
/>
</button>
<div
className={clsx("deriv-accordion__text", {
"deriv-accordion__text--compact": isCompact,
})}
ref={content}
style={{ maxHeight: heightState }}
className={clsx(
"deriv-accordion__content",
{
"deriv-accordion__content--active": active,
},
contentClassName,
)}
>
{children}
<div
className={clsx("deriv-accordion__text", {
"deriv-accordion__text--compact": isCompact,
})}
>
{children}
</div>
</div>
</div>
</div>
);
};
);
},
);

0 comments on commit dcf7793

Please sign in to comment.