diff --git a/packages/editable-html-tip-tap/src/extensions/__tests__/math.test.js b/packages/editable-html-tip-tap/src/extensions/__tests__/math.test.js
index ac3d40393..35087bc40 100644
--- a/packages/editable-html-tip-tap/src/extensions/__tests__/math.test.js
+++ b/packages/editable-html-tip-tap/src/extensions/__tests__/math.test.js
@@ -1,5 +1,5 @@
import React from 'react';
-import { render, waitFor, fireEvent } from '@testing-library/react';
+import { render, waitFor, fireEvent, act } from '@testing-library/react';
import { EnsureTextAfterMathPlugin, MathNode, MathNodeView, ZeroWidthSpaceHandlingPlugin } from '../math';
import * as toolbarUtils from '../../utils/toolbar';
@@ -390,6 +390,7 @@ describe('MathNodeView', () => {
selection: {
from: 0,
to: 1,
+ node: { type: { name: 'math' } },
},
tr: {
setSelection: jest.fn().mockReturnThis(),
@@ -724,6 +725,54 @@ describe('MathNodeView', () => {
});
});
+ describe('selection-based toolbar guard', () => {
+ it('opens toolbar when selected transitions to true and the editor has a NodeSelection on math', async () => {
+ const { queryByTestId, rerender } = render();
+ expect(queryByTestId('math-toolbar')).not.toBeInTheDocument();
+
+ rerender();
+ await waitFor(() => {
+ expect(queryByTestId('math-toolbar')).toBeInTheDocument();
+ });
+ });
+
+ it('does not open toolbar when selected briefly becomes true but editor selection has no node (Cmd+A / drag case)', async () => {
+ const editor = {
+ ...defaultProps.editor,
+ state: {
+ ...defaultProps.editor.state,
+ selection: { from: 0, to: 100 }, // no .node — TextSelection / AllSelection shape
+ },
+ };
+
+ const { queryByTestId, rerender } = render(
+ ,
+ );
+ rerender();
+
+ await act(async () => {});
+ expect(queryByTestId('math-toolbar')).not.toBeInTheDocument();
+ });
+
+ it('does not open toolbar when selected briefly becomes true but NodeSelection targets a non-math node', async () => {
+ const editor = {
+ ...defaultProps.editor,
+ state: {
+ ...defaultProps.editor.state,
+ selection: { from: 0, to: 1, node: { type: { name: 'image' } } },
+ },
+ };
+
+ const { queryByTestId, rerender } = render(
+ ,
+ );
+ rerender();
+
+ await act(async () => {});
+ expect(queryByTestId('math-toolbar')).not.toBeInTheDocument();
+ });
+ });
+
it('does not close toolbar when clicking equation editor dropdown', async () => {
const { queryByTestId } = render();
diff --git a/packages/editable-html-tip-tap/src/extensions/math.js b/packages/editable-html-tip-tap/src/extensions/math.js
index 5c100d560..97d297624 100644
--- a/packages/editable-html-tip-tap/src/extensions/math.js
+++ b/packages/editable-html-tip-tap/src/extensions/math.js
@@ -232,11 +232,19 @@ export const MathNodeView = (props) => {
editor.commands.focus();
};
+ // Only open the toolbar when this node is *explicitly* selected
+ // via a NodeSelection — not when it's merely included in a broader
+ // TextSelection or AllSelection (e.g. click-drag across math, or Cmd+A).
useEffect(() => {
- if (selected) {
+ if (!selected) return;
+
+ const { selection } = editor.state;
+ const isNodeSelected = selection.node?.type?.name === 'math';
+
+ if (isNodeSelected) {
setShowToolbar(true);
}
- }, [selected]);
+ }, [selected, editor]);
useEffect(() => {
setToolbarOpened(editor, selected || showToolbar);