83 lines
3.0 KiB
TypeScript
83 lines
3.0 KiB
TypeScript
import React, { useCallback, useEffect } from "react";
|
|
import { IBlock } from "../BlockList/Block";
|
|
import classes from "./classes.module.scss";
|
|
import Typography, { ETypo, ETypoColor } from "../../Typography";
|
|
import { ChevronDownIcon } from "@heroicons/react/24/outline";
|
|
type IProps = {
|
|
blocks: IBlock[];
|
|
onSelectedBlock: (block: IBlock) => void;
|
|
defaultSelectedBlock?: IBlock;
|
|
};
|
|
|
|
export default function DropdownNavigation({ blocks, onSelectedBlock, defaultSelectedBlock = blocks[0] }: IProps) {
|
|
const [selectedBlock, setSelectedBlock] = React.useState<IBlock | null>(defaultSelectedBlock ?? null);
|
|
const [isDropdownOpened, setIsDropdownOpened] = React.useState<boolean>(false);
|
|
const rootRef = React.useRef<HTMLDivElement>(null);
|
|
|
|
const selectBlock = useCallback(
|
|
(id: string) => {
|
|
setIsDropdownOpened(false);
|
|
setSelectedBlock(blocks.find((folder) => folder.id === id)!);
|
|
onSelectedBlock && onSelectedBlock(blocks.find((folder) => folder.id === id)!);
|
|
},
|
|
[blocks, onSelectedBlock],
|
|
);
|
|
|
|
const handleOnClick = () => setIsDropdownOpened((prev) => !prev);
|
|
|
|
useEffect(() => {
|
|
// on click outside of root, close dropdown
|
|
const handleClickOutside = (event: MouseEvent) => {
|
|
if (rootRef.current && !rootRef.current.contains(event.target as Node)) {
|
|
setIsDropdownOpened(false);
|
|
}
|
|
};
|
|
document.addEventListener("mousedown", handleClickOutside);
|
|
return () => document.removeEventListener("mousedown", handleClickOutside);
|
|
}, []);
|
|
|
|
useEffect(() => {
|
|
if (defaultSelectedBlock) setSelectedBlock(defaultSelectedBlock);
|
|
}, [defaultSelectedBlock]);
|
|
return (
|
|
<div className={classes["root"]} data-is-opened={isDropdownOpened} ref={rootRef}>
|
|
{selectedBlock && (
|
|
<>
|
|
<div className={classes["dropdown-header"]} onClick={handleOnClick}>
|
|
<div className={classes["text-container"]}>
|
|
{selectedBlock.secondaryText && (
|
|
<Typography typo={ETypo.TEXT_MD_LIGHT} color={ETypoColor.NAVIGATION_BUTTON_CONTRAST_DEFAULT}>
|
|
{selectedBlock.secondaryText}
|
|
</Typography>
|
|
)}
|
|
<Typography typo={ETypo.TEXT_MD_BOLD} color={ETypoColor.NAVIGATION_BUTTON_CONTRAST_DEFAULT}>
|
|
{selectedBlock.primaryText}
|
|
</Typography>
|
|
</div>
|
|
<ChevronDownIcon height="24" width="24" color={`var(${ETypoColor.NAVIGATION_BUTTON_CONTRAST_DEFAULT})`} />
|
|
</div>
|
|
|
|
{isDropdownOpened && (
|
|
<div className={classes["dropdown-content"]}>
|
|
{blocks
|
|
.filter((block) => block.id !== selectedBlock.id)
|
|
.map((block) => (
|
|
<div key={block.id} className={classes["dropdown-item"]} onClick={() => selectBlock(block.id)}>
|
|
{block.secondaryText && (
|
|
<Typography typo={ETypo.TEXT_MD_LIGHT} color={ETypoColor.NAVIGATION_BUTTON_CONTRAST_DEFAULT}>
|
|
{block.secondaryText}
|
|
</Typography>
|
|
)}
|
|
<Typography typo={ETypo.TEXT_MD_BOLD} color={ETypoColor.NAVIGATION_BUTTON_CONTRAST_DEFAULT}>
|
|
{block.primaryText}
|
|
</Typography>
|
|
</div>
|
|
))}
|
|
</div>
|
|
)}
|
|
</>
|
|
)}
|
|
</div>
|
|
);
|
|
}
|