Skip to content

Commit 65c47ff

Browse files
authored
Merge pull request #384 from qa-guru/QAGDEV-731
QAGDEV-731 - Мигает pop-up редактор таблицы при активации таблицы
2 parents e55bd0f + 347d724 commit 65c47ff

File tree

3 files changed

+69
-39
lines changed

3 files changed

+69
-39
lines changed

src/shared/lib/mui-tiptap/controls/controlled-bubble-menu.tsx

Lines changed: 11 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,10 @@
11
import { ReactNode, useCallback } from "react";
22
import {
3-
Fade,
43
Paper,
54
type PaperProps,
65
Popover,
76
type PopoverProps,
87
type PopoverVirtualElement,
9-
useTheme,
108
} from "@mui/material";
119
import { type Editor, isNodeSelection, posToDOMRect } from "@tiptap/core";
1210
import { makeStyles } from "tss-react/mui";
@@ -77,7 +75,6 @@ export default function ControlledBubbleMenu({
7775
const { classes, cx } = useStyles(undefined, {
7876
props: { classes: overrideClasses },
7977
});
80-
const theme = useTheme();
8178

8279
const defaultAnchorEl = useCallback((): VirtualElement => {
8380
const { ranges } = editor.state.selection;
@@ -119,24 +116,18 @@ export default function ControlledBubbleMenu({
119116
}}
120117
transformOrigin={{ vertical: "top", horizontal: "left" }}
121118
className={cx(controlledBubbleMenuClasses.root, classes.root, className)}
122-
transitionDuration={{
123-
enter: theme.transitions.duration.enteringScreen,
124-
exit: 0,
125-
}}
126119
>
127-
<Fade in={open}>
128-
<Paper
129-
elevation={7}
130-
{...PaperProps}
131-
className={cx(
132-
controlledBubbleMenuClasses.paper,
133-
classes.paper,
134-
PaperProps?.className
135-
)}
136-
>
137-
{children}
138-
</Paper>
139-
</Fade>
120+
<Paper
121+
elevation={7}
122+
{...PaperProps}
123+
className={cx(
124+
controlledBubbleMenuClasses.paper,
125+
classes.paper,
126+
PaperProps?.className
127+
)}
128+
>
129+
{children}
130+
</Paper>
140131
</Popover>
141132
);
142133
}

src/shared/lib/mui-tiptap/controls/table-bubble-menu.tsx

Lines changed: 40 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { findParentNodeClosestToPos, posToDOMRect } from "@tiptap/core";
2-
import { useMemo } from "react";
2+
import { useMemo, useCallback, useEffect, useState } from "react";
33
import { makeStyles } from "tss-react/mui";
44
import type { Except } from "type-fest";
55
import { type PopoverVirtualElement } from "@mui/material";
@@ -13,14 +13,8 @@ import { useRichTextEditorContext } from "../context";
1313
import TableMenuControls, {
1414
type TableMenuControlsProps,
1515
} from "./table-menu-controls";
16-
import useDebouncedFocus from "../hooks/use-debounced-focus";
17-
import DebounceRender, {
18-
type DebounceRenderProps,
19-
} from "../utils/debounce-render";
2016

2117
export type TableBubbleMenuProps = {
22-
disableDebounce?: boolean;
23-
DebounceProps?: Except<DebounceRenderProps, "children">;
2418
labels?: TableMenuControlsProps["labels"];
2519
} & Partial<Except<ControlledBubbleMenuProps, "open" | "editor" | "children">>;
2620

@@ -34,15 +28,12 @@ const useStyles = makeStyles({
3428
}));
3529

3630
export default function TableBubbleMenu({
37-
disableDebounce = false,
38-
DebounceProps,
3931
labels,
4032
...controlledBubbleMenuProps
4133
}: TableBubbleMenuProps) {
4234
const editor = useRichTextEditorContext();
4335
const { classes } = useStyles();
44-
45-
const isEditorFocusedDebounced = useDebouncedFocus({ editor });
36+
const [isManuallyHidden, setIsManuallyHidden] = useState(false);
4637

4738
const bubbleMenuAnchorEl = useMemo(
4839
() =>
@@ -61,7 +52,7 @@ export default function TableBubbleMenu({
6152
nearestTableParent.pos
6253
) as Maybe<HTMLElement | undefined>;
6354

64-
const tableDomNode = wrapperDomNode?.querySelector("admin");
55+
const tableDomNode = wrapperDomNode?.querySelector("table");
6556
if (tableDomNode) {
6657
return tableDomNode.getBoundingClientRect();
6758
}
@@ -77,18 +68,52 @@ export default function TableBubbleMenu({
7768
[editor]
7869
);
7970

71+
const handleClose = useCallback(() => {
72+
setIsManuallyHidden(true);
73+
if (editor) {
74+
editor.commands.blur();
75+
}
76+
}, [editor]);
77+
78+
useEffect(() => {
79+
if (!editor?.isActive("table")) {
80+
setIsManuallyHidden(false);
81+
}
82+
}, [editor?.isActive("table")]);
83+
84+
useEffect(() => {
85+
const handleKeyDown = (event: KeyboardEvent) => {
86+
if (event.key === "Escape" && editor?.isActive("table")) {
87+
handleClose();
88+
}
89+
};
90+
91+
document.addEventListener("keydown", handleKeyDown);
92+
return () => {
93+
document.removeEventListener("keydown", handleKeyDown);
94+
};
95+
}, [editor, handleClose]);
96+
8097
if (!editor?.isEditable) {
8198
return null;
8299
}
83100

84101
const controls = (
85-
<TableMenuControls className={classes.controls} labels={labels} />
102+
<TableMenuControls
103+
className={classes.controls}
104+
labels={labels}
105+
onClose={handleClose}
106+
/>
86107
);
87108

109+
// Логика показа меню - активная таблица и не скрыто вручную
110+
const shouldShowMenu = editor.isActive("table") && !isManuallyHidden;
111+
88112
return (
89113
<ControlledBubbleMenu
90114
editor={editor}
91-
open={isEditorFocusedDebounced && editor.isActive("table")}
115+
open={shouldShowMenu}
116+
onClose={handleClose}
92117
anchorEl={bubbleMenuAnchorEl as PopoverVirtualElement}
93118
placement={{
94119
anchorOrigin: { vertical: "top", horizontal: "left" },
@@ -104,11 +129,7 @@ export default function TableBubbleMenu({
104129
flipPadding={{ top: 35, left: 8, right: 8, bottom: -Infinity }}
105130
{...controlledBubbleMenuProps}
106131
>
107-
{disableDebounce ? (
108-
controls
109-
) : (
110-
<DebounceRender {...DebounceProps}>{controls}</DebounceRender>
111-
)}
132+
{controls}
112133
</ControlledBubbleMenu>
113134
);
114135
}

src/shared/lib/mui-tiptap/controls/table-menu-controls.tsx

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import FormatColorFill from "@mui/icons-material/FormatColorFill";
22
import GridOff from "@mui/icons-material/GridOff";
3+
import Close from "@mui/icons-material/Close";
34

45
import MenuDivider from "./menu-divider";
56
import { useRichTextEditorContext } from "../context";
@@ -18,6 +19,7 @@ import LayoutColumnFill from "../icons/layout-column-fill";
1819

1920
export type TableMenuControlsProps = {
2021
className?: string;
22+
onClose?: () => void;
2123

2224
labels?: {
2325
insertColumnBefore?: string;
@@ -38,6 +40,7 @@ export type TableMenuControlsProps = {
3840
export default function TableMenuControls({
3941
className,
4042
labels,
43+
onClose,
4144
}: TableMenuControlsProps) {
4245
const editor = useRichTextEditorContext();
4346
return (
@@ -134,6 +137,21 @@ export default function TableMenuControls({
134137
onClick={() => editor?.chain().focus().deleteTable().run()}
135138
disabled={!editor?.can().deleteTable()}
136139
/>
140+
141+
<MenuDivider />
142+
143+
<MenuButton
144+
tooltipLabel="Close"
145+
IconComponent={Close}
146+
onClick={() => {
147+
if (onClose) {
148+
onClose();
149+
} else {
150+
editor?.commands.blur();
151+
}
152+
}}
153+
disabled={!editor?.isEditable}
154+
/>
137155
</MenuControlsContainer>
138156
);
139157
}

0 commit comments

Comments
 (0)