123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136 |
- /*
- * Copyright 2021-2024 Avaiga Private Limited
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
- * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations under the License.
- */
- import React, { useCallback, useMemo, useState, MouseEvent, CSSProperties } from "react";
- import MenuIco from "@mui/icons-material/Menu";
- import ListItemButton from "@mui/material/ListItemButton";
- import Drawer from "@mui/material/Drawer";
- import List from "@mui/material/List";
- import Avatar from "@mui/material/Avatar";
- import CardHeader from "@mui/material/CardHeader";
- import ListItemAvatar from "@mui/material/ListItemAvatar";
- import Box from "@mui/material/Box";
- import Tooltip from "@mui/material/Tooltip";
- import { Theme, useTheme } from "@mui/system";
- import { SingleItem } from "./lovUtils";
- import { createSendActionNameAction } from "../../context/taipyReducers";
- import { MenuProps } from "../../utils/lov";
- import { useClassNames, useDispatch, useModule } from "../../utils/hooks";
- import { emptyArray } from "../../utils";
- import { getComponentClassName } from "./TaipyStyle";
- const boxDrawerStyle = { overflowX: "hidden" } as CSSProperties;
- const headerSx = { padding: 0 };
- const avatarSx = { bgcolor: (theme: Theme) => theme.palette.text.primary };
- const baseTitleProps = { noWrap: true, variant: "h6" } as const;
- const Menu = (props: MenuProps) => {
- const { label, onAction = "", lov, width, inactiveIds = emptyArray, active = true } = props;
- const [selectedValue, setSelectedValue] = useState<string>("");
- const [opened, setOpened] = useState(false);
- const dispatch = useDispatch();
- const theme = useTheme();
- const module = useModule();
- const className = useClassNames(props.libClassName, props.dynamicClassName, props.className);
- const clickHandler = useCallback(
- (evt: MouseEvent<HTMLElement>) => {
- if (active) {
- const { id: key = "" } = evt.currentTarget.dataset;
- setSelectedValue(() => {
- dispatch(createSendActionNameAction("menu", module, onAction, key));
- return key;
- });
- }
- },
- [active, dispatch, module, onAction]
- );
- const openHandler = useCallback((evt: MouseEvent<HTMLElement>) => {
- evt.stopPropagation();
- setOpened((o) => !o);
- }, []);
- const selected = useMemo(() => {
- const selected = Array.isArray(props.selected) ? props.selected : [];
- if (selectedValue && !selected.includes(selectedValue)) {
- return [...selected, selectedValue];
- }
- return selected;
- }, [props.selected, selectedValue]);
- const [drawerSx, titleProps] = useMemo(() => {
- const drawerWidth = opened ? width : `calc(${theme.spacing(9)} + 1px)`;
- const titleWidth = opened ? `calc(${width} - ${theme.spacing(10)})` : undefined;
- return [
- {
- width: drawerWidth,
- flexShrink: 0,
- "& .MuiDrawer-paper": {
- width: drawerWidth,
- boxSizing: "border-box",
- transition: "width 0.3s",
- },
- transition: "width 0.3s",
- },
- { ...baseTitleProps, width: titleWidth },
- ];
- }, [opened, width, theme]);
- return lov && lov.length ? (
- <Drawer
- variant="permanent"
- anchor="left"
- sx={drawerSx}
- className={`${className} ${getComponentClassName(props.children)}`}
- >
- <Box style={boxDrawerStyle}>
- <List>
- <ListItemButton key="taipy_menu_0" onClick={openHandler}>
- <ListItemAvatar>
- <CardHeader
- sx={headerSx}
- avatar={
- <Tooltip title={label || false}>
- <Avatar sx={avatarSx}>
- <MenuIco />
- </Avatar>
- </Tooltip>
- }
- title={label}
- titleTypographyProps={titleProps}
- />
- </ListItemAvatar>
- </ListItemButton>
- {lov.map((elt) => (
- <SingleItem
- key={elt.id}
- value={elt.id}
- item={elt.item}
- selectedValue={selected}
- clickHandler={clickHandler}
- disabled={!active || inactiveIds.includes(elt.id)}
- withAvatar={true}
- titleTypographyProps={titleProps}
- />
- ))}
- </List>
- </Box>
- {props.children}
- </Drawer>
- ) : null;
- };
- export default Menu;
|