import React, { memo, useCallback, useMemo } from "react"; import { useLocation } from "react-router-dom"; import Avatar from "@mui/material/Avatar"; import ListItemButton, { ListItemButtonProps } from "@mui/material/ListItemButton"; import ListItemIcon from "@mui/material/ListItemIcon"; import ListItemText from "@mui/material/ListItemText"; import { styled } from "@mui/material/styles"; import { Box } from "@mui/system"; import { RouteInfo, useRouter } from "../../contexts/RouterContext"; import { LogoType } from "../../types"; import Logo from "../Logo"; export interface NavRailItemProps extends Omit { icon?: LogoType; href?: string; onClick?: () => void; route?: RouteInfo; subtitle?: string | React.ReactNode; title: string; } export const StyledListItemButton = styled(ListItemButton, { name: "BananasNavRail", slot: "Item", })(({ theme }) => theme.unstable_sx({ color: "inherit", px: "unset", marginInline: 0.5, py: 1, "&.Mui-selected .MuiBox-root": { bgcolor: theme.palette.mode == "light" ? "rgba(0, 0, 0, 0.25)" : "rgba(0, 0, 0, 0.25)", }, "&:hover": { bgcolor: "transparent", }, "&:hover .MuiBox-root, &.Mui-selected:hover .MuiBox-root": { bgcolor: theme.palette.mode == "light" ? "rgba(0, 0, 0, 0.25)" : "rgba(255, 255, 255, 0.1)", }, "&.Mui-selected, &.Mui-selected:hover": { bgcolor: "transparent", }, "&:hover .navRailItemTextPrimary": { fontWeight: 600, }, }), ); export const StyledListItemIconBox = styled(Box, { name: "BananasNavRail", slot: "ItemIconBox", })(({ theme }) => theme.unstable_sx({ display: "flex", alignItems: "center", justifyContent: "center", borderRadius: "999px", width: 56, height: 32, transition: theme.transitions.create(["background-color"], { duration: theme.transitions.duration.shortest, }), }), ); export const StyledListItemIcon = styled(ListItemIcon, { name: "BananasNavRail", slot: "ItemIcon", })(({ theme }) => theme.unstable_sx({ p: 1, py: 0.4, color: "currentColor", justifyContent: "center", ".MuiSvgIcon-root": { height: 22, }, transition: theme.transitions.create(["transform"], { duration: theme.transitions.duration.shortest, }), }), ); export const NavRailItem: React.FC> = ({ children, icon: Icon, href, onClick, route, subtitle, sx, title, ...props }) => { const location = useLocation(); const { navigate } = useRouter(); const isHref = href != null; const handleClick = useCallback(() => { if (isHref) { return; } else if (onClick != null) { onClick(); } else if (route != null) { navigate(route); } else { console.error(`[NAV_RAIL_ITEM] ${title} must have either a route or an onClick prop.`); } }, [isHref, navigate, onClick, route]); if (route == null && onClick == null && !isHref) { console.error(`[NAV_RAIL_ITEM] ${title} must have either a route or an onClick prop.`); } if (route != null && onClick != null) { console.error(`[NAV_RAIL_ITEM] ${title} cannot have both a route and an onClick prop.`); } const isSelected = useMemo( () => (route?.path ? location.pathname.startsWith(route?.path) : false), [location.pathname, route?.path], ); return ( {Icon != null ? ( ) : ( {title.substring(0, 1)} )} {children} ); }; export default memo(NavRailItem);