ImageAlign.tsx 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. import React, { useCallback, useEffect, useRef, useState } from 'react';
  2. import { useAppDispatch } from '$app/stores/store';
  3. import { useSubscribeDocument } from '$app/components/document/_shared/SubscribeDoc.hooks';
  4. import { Align } from '$app/interfaces/document';
  5. import { FormatAlignCenter, FormatAlignLeft, FormatAlignRight } from '@mui/icons-material';
  6. import { updateNodeDataThunk } from '$app_reducers/document/async-actions';
  7. import MenuTooltip from '$app/components/document/TextActionMenu/menu/MenuTooltip';
  8. import Popover from '@mui/material/Popover';
  9. function ImageAlign({
  10. id,
  11. align,
  12. onOpen,
  13. onClose,
  14. }: {
  15. id: string;
  16. align: Align;
  17. onOpen: () => void;
  18. onClose: () => void;
  19. }) {
  20. const ref = useRef<HTMLDivElement | null>(null);
  21. const [anchorEl, setAnchorEl] = useState<HTMLDivElement>();
  22. const popoverOpen = Boolean(anchorEl);
  23. useEffect(() => {
  24. if (popoverOpen) {
  25. onOpen();
  26. } else {
  27. onClose();
  28. }
  29. }, [onClose, onOpen, popoverOpen]);
  30. const dispatch = useAppDispatch();
  31. const { controller } = useSubscribeDocument();
  32. const renderAlign = (align: Align) => {
  33. switch (align) {
  34. case Align.Left:
  35. return <FormatAlignLeft />;
  36. case Align.Center:
  37. return <FormatAlignCenter />;
  38. default:
  39. return <FormatAlignRight />;
  40. }
  41. };
  42. const updateAlign = useCallback(
  43. (align: Align) => {
  44. dispatch(
  45. updateNodeDataThunk({
  46. id,
  47. data: {
  48. align,
  49. },
  50. controller,
  51. })
  52. );
  53. setAnchorEl(undefined);
  54. },
  55. [controller, dispatch, id]
  56. );
  57. return (
  58. <>
  59. <MenuTooltip title='Align'>
  60. <div
  61. ref={ref}
  62. className='flex items-center justify-center p-1'
  63. onClick={(_) => {
  64. ref.current && setAnchorEl(ref.current);
  65. }}
  66. >
  67. {renderAlign(align)}
  68. </div>
  69. </MenuTooltip>
  70. <Popover
  71. open={popoverOpen}
  72. anchorOrigin={{
  73. vertical: 'bottom',
  74. horizontal: 'center',
  75. }}
  76. transformOrigin={{
  77. vertical: 'top',
  78. horizontal: 'center',
  79. }}
  80. onMouseDown={(e) => e.stopPropagation()}
  81. anchorEl={anchorEl}
  82. onClose={() => setAnchorEl(undefined)}
  83. PaperProps={{
  84. style: {
  85. backgroundColor: '#1E1E1E',
  86. opacity: 0.8,
  87. },
  88. }}
  89. >
  90. <div className='flex items-center justify-center bg-transparent p-1'>
  91. {[Align.Left, Align.Center, Align.Right].map((item: Align) => {
  92. return (
  93. <div
  94. key={item}
  95. style={{
  96. color: align === item ? '#00BCF0' : '#fff',
  97. }}
  98. className={'cursor-pointer'}
  99. onClick={() => {
  100. updateAlign(item);
  101. }}
  102. >
  103. {renderAlign(item)}
  104. </div>
  105. );
  106. })}
  107. </div>
  108. </Popover>
  109. </>
  110. );
  111. }
  112. export default ImageAlign;