|
| 1 | +/** |
| 2 | + * ButtonMultiSelect Component |
| 3 | + * |
| 4 | + * Overview: |
| 5 | + * The ButtonMultiSelect component is a reusable, configurable button group component. |
| 6 | + * It allows the creation of a configurable buttons which allows for selecting from multiple possible actions. |
| 7 | + * The state of the selected button is saved in localStorage. |
| 8 | + * |
| 9 | + * Usage: |
| 10 | + * To use this component, define an array of ButtonConfig objects, each representing a button's configuration. |
| 11 | + * Pass this array along with a localStorage key (for saving the selected button's state) to the component. |
| 12 | + * |
| 13 | + * Example: |
| 14 | + * ``` |
| 15 | + * <ButtonMultiSelect |
| 16 | + * buttonConfigs={[ |
| 17 | + * { id: 'save', iconName: 'save_icon', label: 'Save', onClick: handleSave }, |
| 18 | + * { id: 'cancel', iconName: 'cancel_icon', label: 'Cancel', onClick: handleCancel } |
| 19 | + * ]} |
| 20 | + * localStorageKey="myButtonSelectKey" |
| 21 | + * size="medium" |
| 22 | + * isLoading={false} |
| 23 | + * isCompact={true} |
| 24 | + * /> |
| 25 | + * ``` |
| 26 | + */ |
| 27 | +import LoadingButton from "@mui/lab/LoadingButton"; |
| 28 | +import Button from "@mui/material/Button"; |
| 29 | +import ButtonGroup from "@mui/material/ButtonGroup"; |
| 30 | +import Menu from "@mui/material/Menu"; |
| 31 | +import MenuItem from "@mui/material/MenuItem"; |
| 32 | +import React, { useCallback, useEffect, useState } from "react"; |
| 33 | +import IconByName from "../icon/IconByName"; |
| 34 | +function ButtonMultiSelect({ id, buttonConfigs, size = "small", localStorageKey, isLoading = false, isCompact = false, }) { |
| 35 | + const [anchorEl, setAnchorEl] = useState(null); |
| 36 | + const [selectedOption, setSelectedOption] = useState(buttonConfigs[0]); |
| 37 | + const mainButtonRef = React.useRef(null); |
| 38 | + const open = Boolean(anchorEl); |
| 39 | + // load saved option from local storage |
| 40 | + useEffect(() => { |
| 41 | + const savedOptionKey = localStorage.getItem(localStorageKey); |
| 42 | + const savedOption = buttonConfigs.find((config) => config.id === savedOptionKey); |
| 43 | + // check if value matches one of the button configs |
| 44 | + if (savedOption) { |
| 45 | + setSelectedOption(savedOption); |
| 46 | + } |
| 47 | + }, []); |
| 48 | + const handleExpandClick = useCallback(() => { |
| 49 | + setAnchorEl(mainButtonRef.current); |
| 50 | + }, []); |
| 51 | + const handleClose = useCallback(() => { |
| 52 | + setAnchorEl(null); |
| 53 | + }, []); |
| 54 | + const handleMenuClick = useCallback((config) => { |
| 55 | + localStorage.setItem("selectedSaveOption", config.id); |
| 56 | + setSelectedOption(config); |
| 57 | + handleClose(); |
| 58 | + }, []); |
| 59 | + return (React.createElement(React.Fragment, null, |
| 60 | + React.createElement(ButtonGroup, { variant: "contained", size: size, sx: { height: "fit-content" } }, |
| 61 | + React.createElement(LoadingButton, { id: id, ref: mainButtonRef, size: size, onClick: selectedOption.onClick, variant: "contained", loading: isLoading, startIcon: !isCompact && React.createElement(IconByName, { name: selectedOption.iconName, fontSize: size }) }, isCompact ? (React.createElement(IconByName, { name: selectedOption.iconName, fontSize: size })) : (selectedOption.label)), |
| 62 | + React.createElement(Button, { onClick: handleExpandClick, size: size }, |
| 63 | + React.createElement(IconByName, { name: "shapes.arrow.dropdown", fontSize: size }))), |
| 64 | + React.createElement(Menu, { anchorEl: anchorEl, keepMounted: true, open: open, onClose: handleClose }, buttonConfigs.map((config) => (React.createElement(MenuItem, { key: config.id, onClick: () => handleMenuClick(config) }, config.label)))))); |
| 65 | +} |
| 66 | +export default ButtonMultiSelect; |
0 commit comments