menu.tsx 2.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. import { IconButton, styled, type PaperProps } from "@mui/material";
  2. import Menu from "@mui/material/Menu";
  3. import React, { useState } from "react";
  4. import { OverflowMenuContext } from "./context";
  5. export interface Iprops {
  6. triggerButtonIcon: React.ReactNode;
  7. triggerButtonProps?: any;
  8. children?: React.ReactNode;
  9. ariaControls: string;
  10. menuPaperProps?: Partial<PaperProps>;
  11. }
  12. export const StyledMenu = styled(Menu)`
  13. & .MuiPaper-root {
  14. margin: 16px auto;
  15. box-shadow:
  16. 0px 0px 6px rgba(0, 0, 0, 0.16),
  17. 0px 3px 6px rgba(0, 0, 0, 0.12);
  18. }
  19. & .MuiList-root {
  20. padding: 0;
  21. border: none;
  22. }
  23. `;
  24. export default function OverflowMenu({
  25. children,
  26. ariaControls,
  27. triggerButtonIcon,
  28. triggerButtonProps,
  29. menuPaperProps,
  30. }: Iprops) {
  31. const [sortByEl, setSortByEl] = useState(null);
  32. const handleClose = () => setSortByEl(null);
  33. return (
  34. <OverflowMenuContext.Provider value={{ close: handleClose }}>
  35. <IconButton
  36. onClick={(event) => setSortByEl(event.currentTarget)}
  37. aria-controls={sortByEl ? ariaControls : undefined}
  38. aria-haspopup="true"
  39. aria-expanded={sortByEl ? "true" : undefined}
  40. {...triggerButtonProps}
  41. >
  42. {triggerButtonIcon}
  43. </IconButton>
  44. <StyledMenu
  45. id={ariaControls}
  46. anchorEl={sortByEl}
  47. open={Boolean(sortByEl)}
  48. onClose={handleClose}
  49. MenuListProps={{
  50. disablePadding: true,
  51. "aria-labelledby": ariaControls,
  52. }}
  53. PaperProps={menuPaperProps}
  54. anchorOrigin={{
  55. vertical: "bottom",
  56. horizontal: "right",
  57. }}
  58. transformOrigin={{
  59. vertical: "top",
  60. horizontal: "right",
  61. }}
  62. >
  63. {children}
  64. </StyledMenu>
  65. </OverflowMenuContext.Provider>
  66. );
  67. }