import { EnteSwitch } from "@/base/components/EnteSwitch"; import { SpaceBetweenFlex, VerticallyCenteredFlex, } from "@ente/shared/components/Container"; import { Box, MenuItem, Stack, Typography, type ButtonProps, type TypographyProps, } from "@mui/material"; import React from "react"; interface EnteMenuItemProps { onClick: () => void; color?: ButtonProps["color"]; /** * - Variant "captioned": The {@link caption}) is shown alongside the main * {@link label}, separated from it by a bullet. */ variant?: "primary" | "captioned" | "toggle" | "secondary" | "mini"; fontWeight?: TypographyProps["fontWeight"]; startIcon?: React.ReactNode; endIcon?: React.ReactNode; /** * One of {@link label} or {@link labelComponent} must be specified. * TODO: Try and reflect this is the type. */ label?: string; /** * The text (or icon) to show alongside the {@link label} when the variant * is "captioned". * * This is usually expected to be a string and is wrapped in a Typography * component before being rendered. However, it can also be an SvgIcon (or * any an arbitrary component, though in terms of styling, only an SvgIcon * usually makes sense). */ caption?: React.ReactNode; checked?: boolean; labelComponent?: React.ReactNode; disabled?: boolean; } /** * A MUI {@link MenuItem} customized as per our designs and use cases. */ export const EnteMenuItem: React.FC = ({ onClick, color = "primary", startIcon, endIcon, label, caption, checked, variant = "primary", fontWeight = "medium", labelComponent, disabled = false, }) => { const handleButtonClick = () => { if (variant == "toggle") { return; } onClick(); }; const handleIconClick = () => { if (variant != "toggle") { return; } onClick(); }; const labelOrDefault = label ?? ""; return ( ({ width: "100%", "&:hover": { backgroundColor: theme.vars.palette.fill.faintHover, }, "& .MuiSvgIcon-root": { fontSize: "20px", }, p: 0, borderRadius: "4px", }), variant != "captioned" && ((theme) => ({ color: theme.vars.palette[color].main, })), variant != "secondary" && variant != "mini" && ((theme) => ({ backgroundColor: theme.vars.palette.fill.faint, })), ]} > {startIcon && startIcon} {labelComponent ? ( labelComponent ) : variant == "captioned" ? ( {labelOrDefault} {"•"} {caption} ) : variant == "mini" ? ( {labelOrDefault} ) : ( {labelOrDefault} )} {endIcon && endIcon} {variant == "toggle" && ( )} ); }; const CaptionTypography: React.FC< React.PropsWithChildren<{ color: EnteMenuItemProps["color"] }> > = ({ color, children }) => ( {children} );