From 8a93fb53e3920e9deb642005d6053ac4f9397bec Mon Sep 17 00:00:00 2001 From: arimieandreea Date: Thu, 25 Jun 2026 13:16:42 +0300 Subject: [PATCH 1/4] fix(editable-html-tip-tap): prevent toolbar closing when clicking the page scrollbar inline-dropdown PIE-575 --- .../src/components/respArea/InlineDropdown.jsx | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/packages/editable-html-tip-tap/src/components/respArea/InlineDropdown.jsx b/packages/editable-html-tip-tap/src/components/respArea/InlineDropdown.jsx index 914a8dd31..2b7a15235 100644 --- a/packages/editable-html-tip-tap/src/components/respArea/InlineDropdown.jsx +++ b/packages/editable-html-tip-tap/src/components/respArea/InlineDropdown.jsx @@ -93,6 +93,18 @@ const InlineDropdown = (props) => { } }, [editor, node, selected]); + + const isScrollbarClicked = (event) => event.clientX >= document.documentElement.clientWidth || + event.clientY >= document.documentElement.clientHeight || + // macOS overlay: target is document.documentElement or document.body directly + // when clicking the window scrollbar — never a child element + ( + (event.target === document.documentElement || event.target === document.body) && + // within 20px of the right or bottom edge of the viewport + (event.clientX >= window.innerWidth - 20 || event.clientY >= window.innerHeight - 20) + ); + + useEffect(() => { // Calculate position relative to selection const bodyRect = document.body.getBoundingClientRect(); @@ -105,6 +117,10 @@ const InlineDropdown = (props) => { }); const handleClickOutside = (event) => { + + if( isScrollbarClicked(event) ) { + return; + } const insideSomeEditor = event.target.closest('[data-toolbar-for]'); if ( From 1b38e20965ee0b3dd7ffe84e7af625865987a4d9 Mon Sep 17 00:00:00 2001 From: arimieandreea Date: Thu, 25 Jun 2026 13:46:20 +0300 Subject: [PATCH 2/4] fix(editable-html-tip-tap): use strict greater-than for scrollbar viewport check inlinedropdown PIE-575 --- .../components/__tests__/InlineDropdown.test.jsx | 14 ++++++++++++++ .../src/components/respArea/InlineDropdown.jsx | 14 +++++--------- 2 files changed, 19 insertions(+), 9 deletions(-) diff --git a/packages/editable-html-tip-tap/src/components/__tests__/InlineDropdown.test.jsx b/packages/editable-html-tip-tap/src/components/__tests__/InlineDropdown.test.jsx index a05d0c392..b2419bfe4 100644 --- a/packages/editable-html-tip-tap/src/components/__tests__/InlineDropdown.test.jsx +++ b/packages/editable-html-tip-tap/src/components/__tests__/InlineDropdown.test.jsx @@ -464,6 +464,20 @@ describe('InlineDropdown', () => { expect(queryByTestId('inline-dropdown-toolbar')).toBeInTheDocument(); }); + it('does not close toolbar when clicking the page scrollbar (documentElement)', async () => { + const { queryByTestId } = render(); + + await waitFor(() => { + expect(queryByTestId('inline-dropdown-toolbar')).toBeInTheDocument(); + }); + + fireEvent.mouseDown(document.documentElement); + + await waitFor(() => { + expect(queryByTestId('inline-dropdown-toolbar')).toBeInTheDocument(); + }); +}); + it('renders delete control on portaled custom toolbar when container el is set', async () => { const { findByLabelText } = render(); expect(await findByLabelText('Delete')).toBeInTheDocument(); diff --git a/packages/editable-html-tip-tap/src/components/respArea/InlineDropdown.jsx b/packages/editable-html-tip-tap/src/components/respArea/InlineDropdown.jsx index 2b7a15235..da1031e6b 100644 --- a/packages/editable-html-tip-tap/src/components/respArea/InlineDropdown.jsx +++ b/packages/editable-html-tip-tap/src/components/respArea/InlineDropdown.jsx @@ -94,15 +94,11 @@ const InlineDropdown = (props) => { }, [editor, node, selected]); - const isScrollbarClicked = (event) => event.clientX >= document.documentElement.clientWidth || - event.clientY >= document.documentElement.clientHeight || - // macOS overlay: target is document.documentElement or document.body directly - // when clicking the window scrollbar — never a child element - ( - (event.target === document.documentElement || event.target === document.body) && - // within 20px of the right or bottom edge of the viewport - (event.clientX >= window.innerWidth - 20 || event.clientY >= window.innerHeight - 20) - ); + + const isScrollbarClicked = (event) => + event.clientX > document.documentElement.clientWidth || + event.clientY > document.documentElement.clientHeight || + event.target === document.documentElement; useEffect(() => { From 1b1c54591c5150ad4ff2ab04c773f48bd4415587 Mon Sep 17 00:00:00 2001 From: Patricia Romaniuc Date: Thu, 25 Jun 2026 15:48:35 +0300 Subject: [PATCH 3/4] feat(math-rendering): add abs macro support in TeX configuration PIE-442 --- .../math-rendering/src/__tests__/render-math.test.js | 11 +++++++++++ packages/math-rendering/src/render-math.js | 1 + 2 files changed, 12 insertions(+) diff --git a/packages/math-rendering/src/__tests__/render-math.test.js b/packages/math-rendering/src/__tests__/render-math.test.js index 446bd6f57..0219bba8e 100644 --- a/packages/math-rendering/src/__tests__/render-math.test.js +++ b/packages/math-rendering/src/__tests__/render-math.test.js @@ -1,5 +1,6 @@ import React from 'react'; import { render } from '@testing-library/react'; +import { TeX } from 'mathjax-full/js/input/tex'; import renderMath, { fixMathElement } from '../render-math'; import { times } from 'lodash-es'; @@ -140,6 +141,16 @@ describe('render-math', () => { }); }); + it('registers the abs macro in the TeX config', () => { + const div = document.createElement('div'); + + renderMath(div); + + const texConfig = TeX.mock.calls[0][0]; + + expect(texConfig.macros.abs).toEqual(['\\left|#1\\right|', 1]); + }); + it('wraps the math containing element the right way', () => { const { container } = render(
diff --git a/packages/math-rendering/src/render-math.js b/packages/math-rendering/src/render-math.js index 7e173b03c..50c824125 100644 --- a/packages/math-rendering/src/render-math.js +++ b/packages/math-rendering/src/render-math.js @@ -132,6 +132,7 @@ const createMathMLInstance = (opts, docProvided = document) => { overarc: '\\overparen', napprox: '\\not\\approx', longdiv: '\\enclose{longdiv}', + abs: ['\\left|#1\\right|', 1], }; const texConfig = opts.useSingleDollar From 84e2d40d74cc89f8c36d61737de1e4b93c0dd084 Mon Sep 17 00:00:00 2001 From: Andrei Miron Date: Wed, 1 Jul 2026 00:18:56 +0300 Subject: [PATCH 4/4] fix(editable-html): copy font styles and append character limit element to document body PIE-674 --- .../src/components/TiptapContainer.jsx | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/packages/editable-html-tip-tap/src/components/TiptapContainer.jsx b/packages/editable-html-tip-tap/src/components/TiptapContainer.jsx index 610a839c3..60a0ea1a9 100644 --- a/packages/editable-html-tip-tap/src/components/TiptapContainer.jsx +++ b/packages/editable-html-tip-tap/src/components/TiptapContainer.jsx @@ -171,10 +171,25 @@ function TiptapContainer(props) { el.style.whiteSpace = 'nowrap'; el.textContent = 'W'.repeat(props.charactersLimit); - rootRef.current.appendChild(el); + // Copy font styles from the editor container so the width measurement reflects the actual font + const computedStyles = window.getComputedStyle(rootRef.current); + const fontStyleProps = [ + 'fontFamily', + 'fontSize', + 'fontWeight', + 'fontStyle', + 'letterSpacing', + 'wordSpacing', + 'textTransform', + 'lineHeight', + ]; + + fontStyleProps.forEach((prop) => { + el.style[prop] = computedStyles[prop]; + }); + document.body.appendChild(el); setAdjustedWidth(`${el.offsetWidth + 27}px`); - el.remove(); } }, [props.adjustWidthForLimit, props.charactersLimit]);