import { useIsomorphicLayoutEffect } from "framer-motion"; import debounce from "lodash/debounce"; import React, { useCallback, useMemo, useRef, useState } from "react"; import { Box } from "../Box"; import { DropdownMenuItemType } from "../DropdownMenu/types"; import { AtomBox } from "../AtomBox"; import MenuItem from "../MenuItem/MenuItem"; import { ChevronLeftIcon, ChevronRightIcon, OpenNewIcon } from "../Svg"; import StyledSubMenuItems, { LeftMaskLayer, RightMaskLayer, StyledSubMenuItemWrapper, SubMenuItemWrapper, } from "./styles"; import { SubMenuItemsProps } from "./types"; import { FlexGap } from "../Layouts"; import NotificationDot from "../NotificationDot/NotificationDot"; import { LinkStatus } from "../DropdownMenu/styles"; const SUBMENU_CHEVRON_CLICK_MOVE_PX = 100; const SUBMENU_SCROLL_DEVIATION = 3; const SubMenuItems: React.FC> = ({ items = [], activeItem, isMobileOnly = false, ...props }) => { const scrollLayerRef = useRef(null); const chevronLeftRef = useRef(null); const chevronRightRef = useRef(null); const [rightClassName, setRightClassName] = useState(""); const [leftClassName, setLeftClassName] = useState(""); const hasOverflowing = scrollLayerRef.current ? scrollLayerRef.current.offsetHeight < scrollLayerRef.current.scrollHeight || scrollLayerRef.current.offsetWidth < scrollLayerRef.current.scrollWidth : false; const layerController = useCallback(() => { if (!scrollLayerRef.current || !chevronLeftRef.current || !chevronRightRef.current) return; const scrollLayer = scrollLayerRef.current; if (scrollLayer.scrollLeft !== 0) setLeftClassName("show"); else setLeftClassName(""); if (scrollLayer.scrollLeft + scrollLayer.offsetWidth < scrollLayer.scrollWidth - SUBMENU_SCROLL_DEVIATION) setRightClassName("show"); else setRightClassName(""); }, []); const { hasHighlightedItem, highlightedItemColor } = useMemo(() => { const anyLabelIcon = items.some((item) => !!item.LabelIcon); if (anyLabelIcon) { return { hasHighlightedItem: true, highlightedItemColor: "success" as const }; } const anyStatusIcon = items.find((item) => !!item.status); if (anyStatusIcon) { return { hasHighlightedItem: true, highlightedItemColor: anyStatusIcon?.status?.color || ("success" as const) }; } return { hasHighlightedItem: false, highlightedItemColor: "success" as const }; }, [items]); useIsomorphicLayoutEffect(() => { layerController(); }, [layerController, items]); return ( { if (!scrollLayerRef.current) return; scrollLayerRef.current.scrollLeft -= SUBMENU_CHEVRON_CLICK_MOVE_PX; }} > { if (!scrollLayerRef.current || !hasOverflowing) return; scrollLayerRef.current.scrollLeft += SUBMENU_CHEVRON_CLICK_MOVE_PX; }} > {hasOverflowing && ( )} {items.map(({ label, LabelIcon, status, href, icon, itemProps, type, disabled, onClick }) => { const Icon = icon; const isExternalLink = type === DropdownMenuItemType.EXTERNAL_LINK; const linkProps = isExternalLink ? { as: "a", target: "_blank", } : {}; const isActive = href === activeItem; return ( label && ( {Icon && } {label} {LabelIcon ? : null} {status && ( {status.text} )} {isExternalLink && ( )} ) ); })} ); }; export default SubMenuItems;