DropdownButton
Description
A button that opens a dropdown menu when clicked.
Parameters
{ options, onClick, icon, disabled, ...rest }
input
DropdownButtonProps
=>
react.JSX.Element
The component.
Example
Inspect
Source code
/packages/react-ui/DropdownButton/DropdownButton.tsx
import {
Button,
type ButtonProps,
IconButton,
List,
ListItemButton,
ListItemText,
Popover,
} from "@mui/material";
import { type MouseEvent, type ReactElement, useId, useState } from "react";
/**
* The type of the options of the {@link DropdownButton} component.
* @public
*/
export type DropdownButtonOption = {
label: string | ReactElement;
value: string;
};
/**
* The props of the {@link DropdownButton} component.
* @public
*/
export type DropdownButtonProps = Omit<ButtonProps, "onClick"> & {
options?: DropdownButtonOption[];
icon?: ReactElement;
onClick?: (event: any, value: any) => void;
};
/**
* A button that opens a dropdown menu when clicked.
* @param props - The props of the component.
* @returns The component.
* @public
*/
export function DropdownButton({ options, onClick, icon, disabled, ...rest }: DropdownButtonProps) {
const id = useId();
const [open, setOpen] = useState(false);
const [anchorEl, setAnchorEl] = useState<HTMLButtonElement | null>(null);
const handleButtonClick = (event: MouseEvent<HTMLButtonElement>) => {
event.stopPropagation();
setAnchorEl(event.currentTarget);
setOpen(true);
};
const handleOnOptionClick = (
event: MouseEvent<HTMLDivElement, globalThis.MouseEvent>,
option: DropdownButtonOption,
) => {
if (!onClick) return;
event.stopPropagation();
onClick(event, option.value);
setOpen(false);
};
const handleOnClose = (event: MouseEvent<HTMLButtonElement>) => {
event.stopPropagation();
setOpen(false);
};
return (
<>
{icon ? (
<IconButton
{...rest}
aria-describedby={id}
onClick={handleButtonClick}
disabled={disabled || !options?.length}
>
{icon}
</IconButton>
) : (
<Button
{...rest}
aria-describedby={id}
onClick={handleButtonClick}
disabled={disabled || !options?.length}
/>
)}
<Popover
id={id}
open={open}
anchorEl={anchorEl}
onClose={handleOnClose}
anchorOrigin={{
vertical: "bottom",
horizontal: "left",
}}
>
<List sx={{ minWidth: 240 }}>
{options?.map((option) => (
<ListItemButton
key={option.value}
onClick={(event) => handleOnOptionClick(event, option)}
>
{typeof option.label === "string" ? (
<ListItemText primary={option.label} />
) : (
option.label
)}
</ListItemButton>
))}
</List>
</Popover>
</>
);
}Last updated on