BlockMenuTurnInto.tsx 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. import React, { MouseEvent, useEffect, useRef } from 'react';
  2. import { ArrowRight, Transform } from '@mui/icons-material';
  3. import MenuItem from '$app/components/document/_shared/MenuItem';
  4. import TurnIntoPopover from '$app/components/document/_shared/TurnInto';
  5. function BlockMenuTurnInto({
  6. id,
  7. onClose,
  8. onHovered,
  9. isHovered,
  10. menuOpened,
  11. lable,
  12. }: {
  13. id: string;
  14. onClose: () => void;
  15. onHovered: (e: MouseEvent) => void;
  16. isHovered: boolean;
  17. menuOpened: boolean;
  18. lable?: string;
  19. }) {
  20. const ref = useRef<HTMLDivElement | null>(null);
  21. const [anchorPosition, setAnchorPosition] = React.useState<{ top: number; left: number }>();
  22. const open = Boolean(anchorPosition);
  23. useEffect(() => {
  24. if (isHovered && menuOpened) {
  25. const rect = ref.current?.getBoundingClientRect();
  26. if (!rect) return;
  27. setAnchorPosition({
  28. top: rect.top + rect.height / 2,
  29. left: rect.left + rect.width,
  30. });
  31. } else {
  32. setAnchorPosition(undefined);
  33. }
  34. }, [isHovered, menuOpened]);
  35. return (
  36. <>
  37. <MenuItem
  38. ref={ref}
  39. title={lable}
  40. isHovered={isHovered}
  41. icon={<Transform />}
  42. extra={<ArrowRight />}
  43. onHover={(e) => {
  44. onHovered(e);
  45. }}
  46. />
  47. <TurnIntoPopover
  48. id={id}
  49. open={open}
  50. disableRestoreFocus
  51. disableAutoFocus
  52. sx={{
  53. pointerEvents: 'none',
  54. }}
  55. PaperProps={{
  56. style: {
  57. pointerEvents: 'auto',
  58. },
  59. }}
  60. onClose={onClose}
  61. anchorReference={'anchorPosition'}
  62. anchorPosition={anchorPosition}
  63. transformOrigin={{
  64. vertical: 'center',
  65. horizontal: 'left',
  66. }}
  67. />
  68. </>
  69. );
  70. }
  71. export default BlockMenuTurnInto;