@pie-lib/editable-html-tip-tap 1.2.0-next.24 → 1.2.0-next.26

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (32) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/lib/components/EditableHtml.js +4 -4
  3. package/lib/components/EditableHtml.js.map +1 -1
  4. package/lib/components/MenuBar.js +1 -1
  5. package/lib/components/MenuBar.js.map +1 -1
  6. package/lib/components/TiptapContainer.js +0 -5
  7. package/lib/components/TiptapContainer.js.map +1 -1
  8. package/lib/components/respArea/ExplicitConstructedResponse.js +2 -1
  9. package/lib/components/respArea/ExplicitConstructedResponse.js.map +1 -1
  10. package/lib/extensions/ensure-empty-root-div.js +48 -0
  11. package/lib/extensions/ensure-empty-root-div.js.map +1 -0
  12. package/lib/extensions/extended-table-cell.js +22 -0
  13. package/lib/extensions/extended-table-cell.js.map +1 -0
  14. package/lib/extensions/image-component.js +36 -13
  15. package/lib/extensions/image-component.js.map +1 -1
  16. package/lib/extensions/math.js +2 -4
  17. package/lib/extensions/math.js.map +1 -1
  18. package/package.json +4 -4
  19. package/src/__tests__/EditableHtml.test.jsx +7 -6
  20. package/src/__tests__/index.test.jsx +5 -2
  21. package/src/components/EditableHtml.jsx +5 -4
  22. package/src/components/MenuBar.jsx +1 -1
  23. package/src/components/TiptapContainer.jsx +0 -5
  24. package/src/components/respArea/ExplicitConstructedResponse.jsx +3 -0
  25. package/src/extensions/__tests__/ensure-empty-root-div.test.js +57 -0
  26. package/src/extensions/__tests__/extended-table-cell.test.js +22 -0
  27. package/src/extensions/__tests__/image-component.test.jsx +1 -0
  28. package/src/extensions/__tests__/math.test.js +1 -1
  29. package/src/extensions/ensure-empty-root-div.js +47 -0
  30. package/src/extensions/extended-table-cell.js +19 -0
  31. package/src/extensions/image-component.jsx +36 -10
  32. package/src/extensions/math.js +2 -4
@@ -1 +1 @@
1
- {"version":3,"file":"math.js","names":["_react","_interopRequireWildcard","require","_reactDom","_interopRequireDefault","_core","_react2","_prosemirrorState","_mathToolbar","_mathRendering","e","t","WeakMap","r","n","__esModule","o","i","f","__proto__","_typeof","has","get","set","_t","hasOwnProperty","call","Object","defineProperty","getOwnPropertyDescriptor","ownKeys","keys","getOwnPropertySymbols","filter","enumerable","push","apply","_objectSpread","arguments","length","forEach","_defineProperty2","getOwnPropertyDescriptors","defineProperties","ensureTextAfterMathPluginKey","PluginKey","generateAdditionalKeys","keyData","undefined","map","key","name","latex","write","label","EnsureTextAfterMathPlugin","exports","mathNodeName","Plugin","appendTransaction","transactions","oldState","newState","some","tr","docChanged","changed","doc","descendants","node","pos","type","nextPos","nodeSize","nextNode","nodeAt","insert","schema","text","ZeroWidthSpaceHandlingPlugin","props","handleKeyDown","view","event","state","dispatch","selection","from","empty","prevChar","textBetween","posBefore","resolved","resolve","maybeNode","nodeAfter","nodeBefore","nodePos","nodeResolved","setSelection","NodeSelection","create","TextSelection","MathNode","Node","group","inline","atom","addAttributes","wrapper","html","addProseMirrorPlugins","parseHTML","tag","getAttrs","el","getAttribute","textContent","innerHTML","addCommands","_this","insertMath","_ref","_node$type","editor","nodes","math","$from","sel","renderHTML","_ref2","HTMLAttributes","dangerouslySetInnerHTML","__html","wrapMath","addNodeView","_this2","ReactNodeViewRenderer","createElement","MathNodeView","options","updateAttributes","selected","_useState","useState","_useState2","_slicedToArray2","showToolbar","setShowToolbar","toolbarRef","useRef","_useState3","top","left","_useState4","position","setPosition","_ref3","_ref3$math","mathOptions","keypadMode","_mathOptions$controll","controlledKeypadMode","_mathOptions$customKe","customKeys","keyPadCharacterRef","setKeypadInteraction","attrs","useEffect","_toolbarOpened","bodyRect","document","body","getBoundingClientRect","start","coordsAtPos","Math","abs","handleClickOutside","_document$querySelect","_document","_target$closest","_target$closest2","_target$closest3","target","equationEditorListboxes","querySelectorAll","equationEditorPopoverOpen","clickedEquationEditorSelect","id","includes","closest","clickedMathNode","current","contains","addEventListener","removeEventListener","handleChange","newLatex","handleDone","_editor$state","commands","focus","NodeViewWrapper","className","style","display","cursor","margin","onClick","contentEditable","MathPreview","ReactDOM","createPortal","ref","instanceId","concat","zIndex","background","boxShadow","MathToolbar","autoFocus","onChange","onDone","additionalKeys"],"sources":["../../src/extensions/math.js"],"sourcesContent":["import React, { useEffect, useRef, useState } from 'react';\nimport ReactDOM from 'react-dom';\nimport { Node } from '@tiptap/core';\nimport { NodeViewWrapper, ReactNodeViewRenderer } from '@tiptap/react';\nimport { NodeSelection, Plugin, PluginKey, TextSelection } from 'prosemirror-state';\nimport { MathPreview, MathToolbar } from '@pie-lib/math-toolbar';\nimport { wrapMath } from '@pie-lib/math-rendering';\n\nconst ensureTextAfterMathPluginKey = new PluginKey('ensureTextAfterMath');\n\nconst generateAdditionalKeys = (keyData = []) => {\n return keyData.map((key) => ({\n name: key,\n latex: key,\n write: key,\n label: key,\n }));\n};\n\nexport const EnsureTextAfterMathPlugin = (mathNodeName) =>\n new Plugin({\n key: ensureTextAfterMathPluginKey,\n appendTransaction: (transactions, oldState, newState) => {\n // Only act when the doc actually changed\n if (!transactions.some((tr) => tr.docChanged)) return null;\n\n const tr = newState.tr;\n let changed = false;\n\n newState.doc.descendants((node, pos) => {\n if (node.type.name === mathNodeName) {\n const nextPos = pos + node.nodeSize;\n const nextNode = newState.doc.nodeAt(nextPos);\n\n // If there's no node after, or the next node isn't text, insert a space\n if (!nextNode || nextNode.type.name !== 'text') {\n tr.insert(nextPos, newState.schema.text('\\u200b'));\n changed = true;\n }\n }\n });\n\n return changed ? tr : null;\n },\n });\n\nexport const ZeroWidthSpaceHandlingPlugin = new Plugin({\n key: new PluginKey('zeroWidthSpaceHandling'),\n props: {\n handleKeyDown(view, event) {\n const { state, dispatch } = view;\n const { selection, doc } = state;\n const { from, empty } = selection;\n\n if (empty && event.key === 'Backspace' && from > 0) {\n const prevChar = doc.textBetween(from - 1, from, '\\uFFFC', '\\uFFFC');\n if (prevChar === '\\u200b') {\n const tr = state.tr.delete(from - 2, from);\n dispatch(tr);\n return true; // handled\n }\n }\n\n if (empty && event.key === 'ArrowLeft' && from > 0) {\n const prevChar = doc.textBetween(from - 1, from, '\\uFFFC', '\\uFFFC');\n // If the previous character is the zero-width space...\n if (prevChar === '\\u200b') {\n const posBefore = from - 1;\n const resolved = state.doc.resolve(posBefore - 1); // look just before the zwsp\n const maybeNode = resolved.nodeAfter || resolved.nodeBefore;\n\n // Check if there's an inline selectable node (e.g., your math node)\n if (maybeNode) {\n const nodePos = posBefore - maybeNode.nodeSize;\n const nodeResolved = state.doc.resolve(nodePos);\n const tr = state.tr.setSelection(NodeSelection.create(state.doc, nodeResolved.pos));\n dispatch(tr);\n return true;\n } else {\n // Just move the text cursor before the zwsp\n const tr = state.tr.setSelection(TextSelection.create(state.doc, from - 2));\n dispatch(tr);\n return true;\n }\n }\n }\n\n return false;\n },\n },\n});\n\nexport const MathNode = Node.create({\n name: 'math',\n group: 'inline',\n inline: true,\n atom: true,\n\n addAttributes() {\n return {\n latex: { default: '' },\n wrapper: { default: null },\n html: { default: null },\n };\n },\n\n addProseMirrorPlugins() {\n return [EnsureTextAfterMathPlugin(this.name), ZeroWidthSpaceHandlingPlugin];\n },\n\n parseHTML() {\n return [\n {\n tag: 'span[data-latex]',\n getAttrs: (el) => ({\n latex: el.getAttribute('data-raw') || el.textContent,\n }),\n },\n {\n tag: 'span[data-type=\"mathml\"]',\n getAttrs: (el) => ({\n html: el.innerHTML,\n }),\n },\n ];\n },\n\n addCommands() {\n return {\n insertMath:\n (latex = '') =>\n ({ tr, editor, dispatch }) => {\n const { state } = editor.view;\n const node = state.schema.nodes.math.create({\n latex,\n });\n const { selection } = state;\n\n // The inserted node is typically just before the cursor\n const pos = selection.$from.pos;\n\n tr.insert(pos, node);\n\n if (node?.type?.name === this.name) {\n // Create a NodeSelection from the current doc\n const sel = NodeSelection.create(tr.doc, selection.$from.pos);\n\n // Build a fresh transaction from the current state and set the selection\n tr.setSelection(sel);\n }\n\n dispatch(tr);\n\n return true;\n },\n // insertMath: (latex = '') => ({ commands }) => {\n // return commands.insertContent({\n // type: this.name,\n // attrs: { latex },\n // });\n // },\n };\n },\n\n renderHTML({ HTMLAttributes }) {\n if (HTMLAttributes.html) {\n return ['span', { 'data-type': 'mathml', dangerouslySetInnerHTML: { __html: HTMLAttributes.html } }];\n }\n\n return [\n 'span',\n { 'data-latex': '', 'data-raw': HTMLAttributes.latex },\n wrapMath(HTMLAttributes.latex, HTMLAttributes.wrapper),\n ];\n },\n\n addNodeView() {\n return ReactNodeViewRenderer((props) => <MathNodeView {...{ ...props, options: this.options }} />);\n },\n});\n\nexport const MathNodeView = (props) => {\n const { node, updateAttributes, editor, selected, options } = props;\n const [showToolbar, setShowToolbar] = useState(selected);\n const toolbarRef = useRef(null);\n const [position, setPosition] = useState({ top: 0, left: 0 });\n const { math: mathOptions = {} } = options || {};\n const {\n keypadMode,\n controlledKeypadMode = true,\n customKeys = [],\n keyPadCharacterRef,\n setKeypadInteraction,\n } = mathOptions;\n\n const latex = node.attrs.latex || '';\n\n useEffect(() => {\n if (selected) {\n setShowToolbar(true);\n }\n }, [selected]);\n\n useEffect(() => {\n editor._toolbarOpened = !!showToolbar;\n }, [showToolbar]);\n\n useEffect(() => {\n // Calculate position relative to selection\n const bodyRect = document.body.getBoundingClientRect();\n const { from } = editor.state.selection;\n const start = editor.view.coordsAtPos(from);\n setPosition({\n top: start.top + Math.abs(bodyRect.top) + 40, // shift above\n left: start.left,\n });\n\n const handleClickOutside = (event) => {\n const target = event?.target;\n\n // MUI's `Select` renders its dropdown options in a portal attached to `document.body`.\n // Those clicks should not dismiss the math toolbar.\n const equationEditorListboxes =\n document.querySelectorAll?.(\n '[id^=\"equation-editor-select\"][id*=\"listbox\"], [aria-labelledby=\"equation-editor-label\"][role=\"listbox\"]',\n ) || [];\n\n const equationEditorPopoverOpen = equationEditorListboxes.length > 0;\n const clickedEquationEditorSelect =\n !!(target?.id && target.id.includes('equation-editor-select')) ||\n !!target?.closest?.('[id*=\"equation-editor-select\"]');\n\n // If the click originated from the math node preview itself (the element\n // that opens the toolbar), ignore it here — the node's own onClick handler\n // will keep/re-open the toolbar. Without this guard, closing and then\n // immediately clicking the math node would fire this listener in the same\n // event cycle and close the toolbar before it could open.\n const clickedMathNode = !!target?.closest?.('.math-node');\n\n if (\n toolbarRef.current &&\n !toolbarRef.current.contains(target) &&\n !target?.closest?.('[data-inline-node]') &&\n !equationEditorPopoverOpen &&\n !clickedEquationEditorSelect &&\n !clickedMathNode\n ) {\n setShowToolbar(false);\n }\n };\n\n if (showToolbar) {\n // Use `click` (not `mousedown`) so interacting with browser UI like the scrollbar\n // doesn't automatically dismiss the math toolbar.\n document.addEventListener('click', handleClickOutside);\n } else {\n document.removeEventListener('click', handleClickOutside);\n }\n\n return () => document.removeEventListener('click', handleClickOutside);\n }, [editor, showToolbar]);\n\n const handleChange = (newLatex) => {\n updateAttributes({ latex: newLatex });\n };\n\n const handleDone = (newLatex) => {\n updateAttributes({ latex: newLatex });\n setShowToolbar(false);\n\n editor._toolbarOpened = false;\n\n const { selection, tr, doc } = editor.state;\n const sel = TextSelection.create(doc, selection.from + 1);\n\n // Build a fresh transaction from the current state and set the selection\n tr.setSelection(sel);\n editor.view.dispatch(tr);\n editor.commands.focus();\n };\n\n return (\n <NodeViewWrapper\n className=\"math-node\"\n style={{\n display: 'inline-flex',\n cursor: 'pointer',\n margin: '0 4px',\n }}\n data-selected={selected}\n >\n <div onClick={() => setShowToolbar(true)} contentEditable={false}>\n <MathPreview latex={latex} />\n </div>\n {showToolbar &&\n ReactDOM.createPortal(\n <div\n ref={toolbarRef}\n data-toolbar-for={editor.instanceId}\n style={{\n position: 'absolute',\n top: `${position.top}px`,\n left: `${position.left}px`,\n zIndex: 20,\n background: 'var(--editable-html-toolbar-bg, #efefef)',\n boxShadow:\n '0px 1px 5px 0px rgba(0, 0, 0, 0.2), 0px 2px 2px 0px rgba(0, 0, 0, 0.14), 0px 3px 1px -2px rgba(0, 0, 0, 0.12)',\n }}\n >\n <MathToolbar\n latex={latex}\n autoFocus\n onChange={handleChange}\n onDone={handleDone}\n keypadMode={keypadMode}\n controlledKeypadMode={controlledKeypadMode}\n additionalKeys={generateAdditionalKeys(customKeys)}\n keyPadCharacterRef={keyPadCharacterRef}\n setKeypadInteraction={setKeypadInteraction}\n />\n </div>,\n document.body,\n )}\n </NodeViewWrapper>\n );\n};\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"file":"math.js","names":["_react","_interopRequireWildcard","require","_reactDom","_interopRequireDefault","_core","_react2","_prosemirrorState","_mathToolbar","_mathRendering","e","t","WeakMap","r","n","__esModule","o","i","f","__proto__","_typeof","has","get","set","_t","hasOwnProperty","call","Object","defineProperty","getOwnPropertyDescriptor","ownKeys","keys","getOwnPropertySymbols","filter","enumerable","push","apply","_objectSpread","arguments","length","forEach","_defineProperty2","getOwnPropertyDescriptors","defineProperties","ensureTextAfterMathPluginKey","PluginKey","generateAdditionalKeys","keyData","undefined","map","key","name","latex","write","label","EnsureTextAfterMathPlugin","exports","mathNodeName","Plugin","appendTransaction","transactions","oldState","newState","some","tr","docChanged","changed","doc","descendants","node","pos","type","nextPos","nodeSize","nextNode","nodeAt","insert","schema","text","ZeroWidthSpaceHandlingPlugin","props","handleKeyDown","view","event","state","dispatch","selection","from","empty","prevChar","textBetween","posBefore","resolved","resolve","maybeNode","nodeAfter","nodeBefore","nodePos","nodeResolved","setSelection","NodeSelection","create","TextSelection","MathNode","Node","group","inline","atom","addAttributes","wrapper","html","addProseMirrorPlugins","parseHTML","tag","getAttrs","el","getAttribute","textContent","innerHTML","addCommands","_this","insertMath","_ref","_node$type","editor","nodes","math","$from","sel","renderHTML","_ref2","HTMLAttributes","dangerouslySetInnerHTML","__html","wrapMath","addNodeView","_this2","ReactNodeViewRenderer","createElement","MathNodeView","options","updateAttributes","selected","_useState","useState","_useState2","_slicedToArray2","showToolbar","setShowToolbar","toolbarRef","useRef","_useState3","top","left","_useState4","position","setPosition","_ref3","_ref3$math","mathOptions","keypadMode","_mathOptions$controll","controlledKeypadMode","_mathOptions$customKe","customKeys","keyPadCharacterRef","setKeypadInteraction","attrs","useEffect","_toolbarOpened","bodyRect","document","body","getBoundingClientRect","start","coordsAtPos","Math","abs","handleClickOutside","_document$querySelect","_document","_target$closest","_target$closest2","_target$closest3","target","equationEditorListboxes","querySelectorAll","equationEditorPopoverOpen","clickedEquationEditorSelect","id","includes","closest","clickedMathNode","current","contains","addEventListener","removeEventListener","handleChange","newLatex","handleDone","_editor$state","commands","focus","NodeViewWrapper","className","style","display","cursor","margin","onClick","contentEditable","MathPreview","ReactDOM","createPortal","ref","instanceId","marginTop","zIndex","background","boxShadow","MathToolbar","autoFocus","onChange","onDone","additionalKeys","_tiptapContainerEl"],"sources":["../../src/extensions/math.js"],"sourcesContent":["import React, { useEffect, useRef, useState } from 'react';\nimport ReactDOM from 'react-dom';\nimport { Node } from '@tiptap/core';\nimport { NodeViewWrapper, ReactNodeViewRenderer } from '@tiptap/react';\nimport { NodeSelection, Plugin, PluginKey, TextSelection } from 'prosemirror-state';\nimport { MathPreview, MathToolbar } from '@pie-lib/math-toolbar';\nimport { wrapMath } from '@pie-lib/math-rendering';\n\nconst ensureTextAfterMathPluginKey = new PluginKey('ensureTextAfterMath');\n\nconst generateAdditionalKeys = (keyData = []) => {\n return keyData.map((key) => ({\n name: key,\n latex: key,\n write: key,\n label: key,\n }));\n};\n\nexport const EnsureTextAfterMathPlugin = (mathNodeName) =>\n new Plugin({\n key: ensureTextAfterMathPluginKey,\n appendTransaction: (transactions, oldState, newState) => {\n // Only act when the doc actually changed\n if (!transactions.some((tr) => tr.docChanged)) return null;\n\n const tr = newState.tr;\n let changed = false;\n\n newState.doc.descendants((node, pos) => {\n if (node.type.name === mathNodeName) {\n const nextPos = pos + node.nodeSize;\n const nextNode = newState.doc.nodeAt(nextPos);\n\n // If there's no node after, or the next node isn't text, insert a space\n if (!nextNode || nextNode.type.name !== 'text') {\n tr.insert(nextPos, newState.schema.text('\\u200b'));\n changed = true;\n }\n }\n });\n\n return changed ? tr : null;\n },\n });\n\nexport const ZeroWidthSpaceHandlingPlugin = new Plugin({\n key: new PluginKey('zeroWidthSpaceHandling'),\n props: {\n handleKeyDown(view, event) {\n const { state, dispatch } = view;\n const { selection, doc } = state;\n const { from, empty } = selection;\n\n if (empty && event.key === 'Backspace' && from > 0) {\n const prevChar = doc.textBetween(from - 1, from, '\\uFFFC', '\\uFFFC');\n if (prevChar === '\\u200b') {\n const tr = state.tr.delete(from - 2, from);\n dispatch(tr);\n return true; // handled\n }\n }\n\n if (empty && event.key === 'ArrowLeft' && from > 0) {\n const prevChar = doc.textBetween(from - 1, from, '\\uFFFC', '\\uFFFC');\n // If the previous character is the zero-width space...\n if (prevChar === '\\u200b') {\n const posBefore = from - 1;\n const resolved = state.doc.resolve(posBefore - 1); // look just before the zwsp\n const maybeNode = resolved.nodeAfter || resolved.nodeBefore;\n\n // Check if there's an inline selectable node (e.g., your math node)\n if (maybeNode) {\n const nodePos = posBefore - maybeNode.nodeSize;\n const nodeResolved = state.doc.resolve(nodePos);\n const tr = state.tr.setSelection(NodeSelection.create(state.doc, nodeResolved.pos));\n dispatch(tr);\n return true;\n } else {\n // Just move the text cursor before the zwsp\n const tr = state.tr.setSelection(TextSelection.create(state.doc, from - 2));\n dispatch(tr);\n return true;\n }\n }\n }\n\n return false;\n },\n },\n});\n\nexport const MathNode = Node.create({\n name: 'math',\n group: 'inline',\n inline: true,\n atom: true,\n\n addAttributes() {\n return {\n latex: { default: '' },\n wrapper: { default: null },\n html: { default: null },\n };\n },\n\n addProseMirrorPlugins() {\n return [EnsureTextAfterMathPlugin(this.name), ZeroWidthSpaceHandlingPlugin];\n },\n\n parseHTML() {\n return [\n {\n tag: 'span[data-latex]',\n getAttrs: (el) => ({\n latex: el.getAttribute('data-raw') || el.textContent,\n }),\n },\n {\n tag: 'span[data-type=\"mathml\"]',\n getAttrs: (el) => ({\n html: el.innerHTML,\n }),\n },\n ];\n },\n\n addCommands() {\n return {\n insertMath:\n (latex = '') =>\n ({ tr, editor, dispatch }) => {\n const { state } = editor.view;\n const node = state.schema.nodes.math.create({\n latex,\n });\n const { selection } = state;\n\n // The inserted node is typically just before the cursor\n const pos = selection.$from.pos;\n\n tr.insert(pos, node);\n\n if (node?.type?.name === this.name) {\n // Create a NodeSelection from the current doc\n const sel = NodeSelection.create(tr.doc, selection.$from.pos);\n\n // Build a fresh transaction from the current state and set the selection\n tr.setSelection(sel);\n }\n\n dispatch(tr);\n\n return true;\n },\n // insertMath: (latex = '') => ({ commands }) => {\n // return commands.insertContent({\n // type: this.name,\n // attrs: { latex },\n // });\n // },\n };\n },\n\n renderHTML({ HTMLAttributes }) {\n if (HTMLAttributes.html) {\n return ['span', { 'data-type': 'mathml', dangerouslySetInnerHTML: { __html: HTMLAttributes.html } }];\n }\n\n return [\n 'span',\n { 'data-latex': '', 'data-raw': HTMLAttributes.latex },\n wrapMath(HTMLAttributes.latex, HTMLAttributes.wrapper),\n ];\n },\n\n addNodeView() {\n return ReactNodeViewRenderer((props) => <MathNodeView {...{ ...props, options: this.options }} />);\n },\n});\n\nexport const MathNodeView = (props) => {\n const { node, updateAttributes, editor, selected, options } = props;\n const [showToolbar, setShowToolbar] = useState(selected);\n const toolbarRef = useRef(null);\n const [position, setPosition] = useState({ top: 0, left: 0 });\n const { math: mathOptions = {} } = options || {};\n const {\n keypadMode,\n controlledKeypadMode = true,\n customKeys = [],\n keyPadCharacterRef,\n setKeypadInteraction,\n } = mathOptions;\n\n const latex = node.attrs.latex || '';\n\n useEffect(() => {\n if (selected) {\n setShowToolbar(true);\n }\n }, [selected]);\n\n useEffect(() => {\n editor._toolbarOpened = !!showToolbar;\n }, [showToolbar]);\n\n useEffect(() => {\n // Calculate position relative to selection\n const bodyRect = document.body.getBoundingClientRect();\n const { from } = editor.state.selection;\n const start = editor.view.coordsAtPos(from);\n setPosition({\n top: start.top + Math.abs(bodyRect.top) + 40, // shift above\n left: start.left,\n });\n\n const handleClickOutside = (event) => {\n const target = event?.target;\n\n // MUI's `Select` renders its dropdown options in a portal attached to `document.body`.\n // Those clicks should not dismiss the math toolbar.\n const equationEditorListboxes =\n document.querySelectorAll?.(\n '[id^=\"equation-editor-select\"][id*=\"listbox\"], [aria-labelledby=\"equation-editor-label\"][role=\"listbox\"]',\n ) || [];\n\n const equationEditorPopoverOpen = equationEditorListboxes.length > 0;\n const clickedEquationEditorSelect =\n !!(target?.id && target.id.includes('equation-editor-select')) ||\n !!target?.closest?.('[id*=\"equation-editor-select\"]');\n\n // If the click originated from the math node preview itself (the element\n // that opens the toolbar), ignore it here — the node's own onClick handler\n // will keep/re-open the toolbar. Without this guard, closing and then\n // immediately clicking the math node would fire this listener in the same\n // event cycle and close the toolbar before it could open.\n const clickedMathNode = !!target?.closest?.('.math-node');\n\n if (\n toolbarRef.current &&\n !toolbarRef.current.contains(target) &&\n !target?.closest?.('[data-inline-node]') &&\n !equationEditorPopoverOpen &&\n !clickedEquationEditorSelect &&\n !clickedMathNode\n ) {\n setShowToolbar(false);\n }\n };\n\n if (showToolbar) {\n // Use `click` (not `mousedown`) so interacting with browser UI like the scrollbar\n // doesn't automatically dismiss the math toolbar.\n document.addEventListener('click', handleClickOutside);\n } else {\n document.removeEventListener('click', handleClickOutside);\n }\n\n return () => document.removeEventListener('click', handleClickOutside);\n }, [editor, showToolbar]);\n\n const handleChange = (newLatex) => {\n updateAttributes({ latex: newLatex });\n };\n\n const handleDone = (newLatex) => {\n updateAttributes({ latex: newLatex });\n setShowToolbar(false);\n\n editor._toolbarOpened = false;\n\n const { selection, tr, doc } = editor.state;\n const sel = TextSelection.create(doc, selection.from + 1);\n\n // Build a fresh transaction from the current state and set the selection\n tr.setSelection(sel);\n editor.view.dispatch(tr);\n editor.commands.focus();\n };\n\n return (\n <NodeViewWrapper\n className=\"math-node\"\n style={{\n display: 'inline-flex',\n cursor: 'pointer',\n margin: '0 4px',\n }}\n data-selected={selected}\n >\n <div onClick={() => setShowToolbar(true)} contentEditable={false}>\n <MathPreview latex={latex} />\n </div>\n {showToolbar &&\n ReactDOM.createPortal(\n <div\n ref={toolbarRef}\n data-toolbar-for={editor.instanceId}\n style={{\n marginTop: '6px',\n zIndex: 20,\n background: 'var(--editable-html-toolbar-bg, #efefef)',\n boxShadow:\n '0px 1px 5px 0px rgba(0, 0, 0, 0.2), 0px 2px 2px 0px rgba(0, 0, 0, 0.14), 0px 3px 1px -2px rgba(0, 0, 0, 0.12)',\n }}\n >\n <MathToolbar\n latex={latex}\n autoFocus\n onChange={handleChange}\n onDone={handleDone}\n keypadMode={keypadMode}\n controlledKeypadMode={controlledKeypadMode}\n additionalKeys={generateAdditionalKeys(customKeys)}\n keyPadCharacterRef={keyPadCharacterRef}\n setKeypadInteraction={setKeypadInteraction}\n />\n </div>,\n editor?._tiptapContainerEl || document.body,\n )}\n </NodeViewWrapper>\n );\n};\n"],"mappings":"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","ignoreList":[]}
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "publishConfig": {
4
4
  "access": "public"
5
5
  },
6
- "version": "1.2.0-next.24",
6
+ "version": "1.2.0-next.26",
7
7
  "description": "",
8
8
  "license": "ISC",
9
9
  "main": "lib/index.js",
@@ -17,9 +17,9 @@
17
17
  "@mui/icons-material": "^7.3.4",
18
18
  "@mui/material": "^7.3.4",
19
19
  "@pie-lib/drag": "^3.2.0-next.8",
20
- "@pie-lib/math-input": "^7.2.0-next.11",
20
+ "@pie-lib/math-input": "^7.2.0-next.12",
21
21
  "@pie-lib/math-rendering": "^4.2.0-next.3",
22
- "@pie-lib/math-toolbar": "^2.2.0-next.13",
22
+ "@pie-lib/math-toolbar": "^2.2.0-next.14",
23
23
  "@pie-lib/render-ui": "^5.2.0-next.7",
24
24
  "@tiptap/core": "3.0.9",
25
25
  "@tiptap/extension-character-count": "3.0.9",
@@ -59,6 +59,6 @@
59
59
  "peerDependencies": {
60
60
  "react": "^18.2.0"
61
61
  },
62
- "gitHead": "4b408d584fbf5a1cd7db74fa2f5b326b29ec2f5c",
62
+ "gitHead": "109bafa6cffd57dac6c0a30ddc36dfc0c82ba541",
63
63
  "scripts": {}
64
64
  }
@@ -70,12 +70,9 @@ jest.mock('@tiptap/extension-table-row', () => ({
70
70
  TableRow: {},
71
71
  }));
72
72
 
73
- jest.mock('@tiptap/extension-table-cell', () => ({
74
- TableCell: {},
75
- }));
76
-
77
- jest.mock('@tiptap/extension-table-header', () => ({
78
- TableHeader: {},
73
+ jest.mock('../extensions/extended-table-cell', () => ({
74
+ ExtendedTableCell: {},
75
+ ExtendedTableHeader: {},
79
76
  }));
80
77
 
81
78
  jest.mock('../extensions/extended-table', () => ({
@@ -83,6 +80,10 @@ jest.mock('../extensions/extended-table', () => ({
83
80
  default: {},
84
81
  }));
85
82
 
83
+ jest.mock('../extensions/ensure-empty-root-div', () => ({
84
+ EnsureEmptyRootIsDiv: {},
85
+ }));
86
+
86
87
  jest.mock('../extensions/responseArea', () => ({
87
88
  ExplicitConstructedResponseNode: {
88
89
  configure: jest.fn(() => ({})),
@@ -30,9 +30,12 @@ jest.mock('@tiptap/extension-text-align', () => ({
30
30
  jest.mock('@tiptap/extension-image', () => ({ __esModule: true, default: {} }));
31
31
  jest.mock('@tiptap/extension-table', () => ({ __esModule: true, default: {} }));
32
32
  jest.mock('@tiptap/extension-table-row', () => ({ TableRow: {} }));
33
- jest.mock('@tiptap/extension-table-cell', () => ({ TableCell: {} }));
34
- jest.mock('@tiptap/extension-table-header', () => ({ TableHeader: {} }));
33
+ jest.mock('../extensions/extended-table-cell', () => ({
34
+ ExtendedTableCell: {},
35
+ ExtendedTableHeader: {},
36
+ }));
35
37
  jest.mock('../extensions/extended-table', () => ({ __esModule: true, default: {} }));
38
+ jest.mock('../extensions/ensure-empty-root-div', () => ({ EnsureEmptyRootIsDiv: {} }));
36
39
  jest.mock('../extensions/responseArea', () => ({
37
40
  ExplicitConstructedResponseNode: { configure: jest.fn(() => ({})) },
38
41
  DragInTheBlankNode: { configure: jest.fn(() => ({})) },
@@ -13,10 +13,10 @@ import Placeholder from '@tiptap/extension-placeholder';
13
13
  import { normalizeInitialMarkup } from '../utils/helper';
14
14
 
15
15
  import ExtendedTable from '../extensions/extended-table';
16
+ import { ExtendedTableCell, ExtendedTableHeader } from '../extensions/extended-table-cell';
16
17
  import { DivNode } from '../extensions/div-node';
18
+ import { EnsureEmptyRootIsDiv } from '../extensions/ensure-empty-root-div';
17
19
  import { TableRow } from '@tiptap/extension-table-row';
18
- import { TableCell } from '@tiptap/extension-table-cell';
19
- import { TableHeader } from '@tiptap/extension-table-header';
20
20
  import {
21
21
  DragInTheBlankNode,
22
22
  ExplicitConstructedResponseNode,
@@ -152,6 +152,7 @@ export const EditableHtml = (props) => {
152
152
  },
153
153
  }),
154
154
  DivNode,
155
+ EnsureEmptyRootIsDiv,
155
156
  Placeholder.configure({
156
157
  placeholder: props.placeholder,
157
158
  // show placeholder even when editor is focused
@@ -161,8 +162,8 @@ export const EditableHtml = (props) => {
161
162
  }),
162
163
  ExtendedTable,
163
164
  TableRow,
164
- TableHeader,
165
- TableCell,
165
+ ExtendedTableHeader,
166
+ ExtendedTableCell,
166
167
  ResponseAreaExtension.configure(props.responseAreaProps),
167
168
  ExplicitConstructedResponseNode.configure(props.responseAreaProps),
168
169
  DragInTheBlankNode.configure(props.responseAreaProps),
@@ -142,7 +142,7 @@ function MenuBar({
142
142
  [classes.toolbarWithNoDone]: !hasDoneButton,
143
143
  [classes.toolbarTop]: toolbarOpts.position === 'top',
144
144
  [classes.toolbarRight]: toolbarOpts.alignment === 'right',
145
- [classes.focused]: toolbarOpts.alwaysVisible || (editorState.isFocused && !editor._toolbarOpened),
145
+ [classes.focused]: toolbarOpts.alwaysVisible || (editorState.isFocused && !editor._toolbarOpened && !editorState.hideDefaultToolbar),
146
146
  [classes.autoWidth]: autoWidth,
147
147
  [classes.fullWidth]: !autoWidth,
148
148
  [classes.hidden]: toolbarOpts.isHidden === true,
@@ -78,11 +78,6 @@ const StyledRoot = styled('div', {
78
78
  margin: '1.5em 10px',
79
79
  padding: '.5em 10px',
80
80
  },
81
- '& hr': {
82
- border: 'none',
83
- borderTop: '1px solid var(--gray-2)',
84
- margin: '2rem 0',
85
- },
86
81
  '& p': {
87
82
  margin: '0',
88
83
  },
@@ -38,7 +38,10 @@ const ExplicitConstructedResponse = (props) => {
38
38
 
39
39
  useEffect(() => {
40
40
  const handleClickOutside = (event) => {
41
+ const insideCharacterPicker = event.target.closest('.insert-character-dialog') || event.target.closest('[data-toolbar-for]');
42
+
41
43
  if (
44
+ !insideCharacterPicker &&
42
45
  toolbarRef.current &&
43
46
  !toolbarRef.current.contains(event.target) &&
44
47
  !event.target.closest('[data-inline-node]')
@@ -0,0 +1,57 @@
1
+ import { Editor } from '@tiptap/core';
2
+ import StarterKit from '@tiptap/starter-kit';
3
+ import { DivNode } from '../div-node';
4
+ import { EnsureEmptyRootIsDiv } from '../ensure-empty-root-div';
5
+
6
+ /** Match EditableHtml so TrailingNode does not add a second empty block next to an empty paragraph. */
7
+ const starterKitConfigured = StarterKit.configure({
8
+ trailingNode: {
9
+ node: 'paragraph',
10
+ notAfter: ['paragraph', 'div'],
11
+ },
12
+ });
13
+
14
+ describe('EnsureEmptyRootIsDiv', () => {
15
+ const extensions = [starterKitConfigured, DivNode, EnsureEmptyRootIsDiv];
16
+
17
+ let editor;
18
+
19
+ afterEach(() => {
20
+ if (editor) {
21
+ editor.destroy();
22
+ editor = null;
23
+ }
24
+ });
25
+
26
+ it('replaces a lone root paragraph with an empty div after select-all and delete (full delete flow)', () => {
27
+ editor = new Editor({
28
+ extensions,
29
+ content: '<p>hello</p>',
30
+ });
31
+
32
+ editor.chain().focus().selectAll().deleteSelection().run();
33
+
34
+ expect(editor.state.doc.childCount).toBe(1);
35
+ expect(editor.state.doc.firstChild.type.name).toBe('div');
36
+ expect(editor.state.doc.firstChild.textContent).toBe('');
37
+ });
38
+
39
+ it('does not replace a root paragraph that still has text', () => {
40
+ editor = new Editor({
41
+ extensions,
42
+ content: '<p>x</p>',
43
+ });
44
+
45
+ expect(editor.state.doc.firstChild.type.name).toBe('paragraph');
46
+ });
47
+
48
+ it('does not run when there is more than one top-level block', () => {
49
+ editor = new Editor({
50
+ extensions,
51
+ content: '<p>a</p><p>b</p>',
52
+ });
53
+
54
+ expect(editor.state.doc.childCount).toBe(2);
55
+ expect(editor.state.doc.firstChild.type.name).toBe('paragraph');
56
+ });
57
+ });
@@ -0,0 +1,22 @@
1
+ import { ExtendedTableCell, ExtendedTableHeader } from '../extended-table-cell';
2
+
3
+ describe('ExtendedTableCell / ExtendedTableHeader', () => {
4
+ it('exports cell and header extensions with div preferred over paragraph in content spec', () => {
5
+ expect(ExtendedTableCell.name).toBe('tableCell');
6
+ expect(ExtendedTableHeader.name).toBe('tableHeader');
7
+
8
+ const cellContent =
9
+ ExtendedTableCell.options?.content ??
10
+ ExtendedTableCell.config?.content ??
11
+ ExtendedTableCell.extendOptions?.content;
12
+
13
+ expect(String(cellContent)).toMatch(/^\(div \| paragraph/);
14
+
15
+ const headerContent =
16
+ ExtendedTableHeader.options?.content ??
17
+ ExtendedTableHeader.config?.content ??
18
+ ExtendedTableHeader.extendOptions?.content;
19
+
20
+ expect(headerContent).toBe(cellContent);
21
+ });
22
+ });
@@ -36,6 +36,7 @@ jest.mock('../custom-toolbar-wrapper', () => ({
36
36
 
37
37
  describe('ImageComponent', () => {
38
38
  const mockEditor = {
39
+ _tiptapContainerEl: document.body,
39
40
  commands: {
40
41
  updateAttributes: jest.fn(),
41
42
  focus: jest.fn(),
@@ -245,7 +245,7 @@ describe('MathNodeView', () => {
245
245
  const { container } = render(<MathNodeView {...defaultProps} selected={true} />);
246
246
  await waitFor(() => {
247
247
  const toolbar = container.querySelector('[data-toolbar-for]');
248
- expect(toolbar).toHaveStyle({ position: 'absolute' });
248
+ expect(toolbar).toBeInTheDocument();
249
249
  });
250
250
  });
251
251
 
@@ -0,0 +1,47 @@
1
+ import { Extension } from '@tiptap/core';
2
+ import { Plugin, PluginKey } from '@tiptap/pm/state';
3
+
4
+ /**
5
+ * After ProseMirror repairs an empty document, it often inserts a `paragraph`.
6
+ * We want a lone empty top-level block to be `div` (DivNode) so typing stays `<div>A</div>`.
7
+ */
8
+ export const EnsureEmptyRootIsDiv = Extension.create({
9
+ name: 'ensureEmptyRootIsDiv',
10
+
11
+ addProseMirrorPlugins() {
12
+ const key = new PluginKey(this.name);
13
+
14
+ return [
15
+ new Plugin({
16
+ key,
17
+ appendTransaction(transactions, _oldState, newState) {
18
+ if (!transactions.some((tr) => tr.docChanged)) {
19
+ return null;
20
+ }
21
+
22
+ const { doc } = newState;
23
+ if (doc.childCount !== 1) {
24
+ return null;
25
+ }
26
+
27
+ const first = doc.firstChild;
28
+ if (first.type.name !== 'paragraph' || first.content.size > 0) {
29
+ return null;
30
+ }
31
+
32
+ const divType = newState.schema.nodes.div;
33
+ if (!divType) {
34
+ return null;
35
+ }
36
+
37
+ // Top-level content positions are 0 .. doc.content.size. The first block spans
38
+ // [0, first.nodeSize). Using start=1 replaces the wrong slice and can leave the
39
+ // document inconsistent after a full delete (Cmd+A, Backspace).
40
+ const start = 0;
41
+ const end = first.nodeSize;
42
+ return newState.tr.replaceWith(start, end, divType.create());
43
+ },
44
+ }),
45
+ ];
46
+ },
47
+ });
@@ -0,0 +1,19 @@
1
+ import { TableCell } from '@tiptap/extension-table-cell';
2
+ import { TableHeader } from '@tiptap/extension-table-header';
3
+
4
+ /**
5
+ * Default table cells use ProseMirror `createAndFill()`, which prefers the first
6
+ * block type allowed by the content expression. Stock cells use `block+`, so
7
+ * `paragraph` wins. Listing `div` first matches the editor default for plain text
8
+ * (see DivNode) while still allowing other blocks (lists, headings, images, …).
9
+ */
10
+ const TABLE_CELL_BLOCK_CONTENT =
11
+ '(div | paragraph | heading | bulletList | orderedList | blockquote | codeBlock | horizontalRule | image | imageUploadNode)+';
12
+
13
+ export const ExtendedTableCell = TableCell.extend({
14
+ content: TABLE_CELL_BLOCK_CONTENT,
15
+ });
16
+
17
+ export const ExtendedTableHeader = TableHeader.extend({
18
+ content: TABLE_CELL_BLOCK_CONTENT,
19
+ });
@@ -5,6 +5,7 @@ import debug from 'debug';
5
5
  import LinearProgress from '@mui/material/LinearProgress';
6
6
  import { styled } from '@mui/material/styles';
7
7
  import { NodeViewWrapper } from '@tiptap/react';
8
+ import ReactDOM from 'react-dom';
8
9
  import InsertImageHandler from '../components/image/InsertImageHandler';
9
10
  import ImageToolbar from '../components/image/ImageToolbar';
10
11
  import CustomToolbarWrapper from './custom-toolbar-wrapper';
@@ -133,8 +134,6 @@ function ImageComponent(props) {
133
134
  if (resizeHandle) {
134
135
  resizeHandle.removeEventListener('mousedown', initResize, false);
135
136
  }
136
-
137
- options.imageHandling.onDelete(latestNodeRef.current);
138
137
  };
139
138
  }, []);
140
139
 
@@ -195,6 +194,22 @@ function ImageComponent(props) {
195
194
  [editor, node.attrs],
196
195
  );
197
196
 
197
+ // Helper to find this node's current position in the doc.
198
+ // We cannot use object identity (n === node) because ProseMirror replaces
199
+ // node objects after every transaction — match by src instead.
200
+ const findNodePos = useCallback(() => {
201
+ let found = null;
202
+ const src = latestNodeRef.current.attrs.src;
203
+ editor.state.doc.descendants((n, pos) => {
204
+ if (found !== null) return false;
205
+ if (n.type.name === 'imageUploadNode' && n.attrs.src === src) {
206
+ found = pos;
207
+ return false;
208
+ }
209
+ });
210
+ return found;
211
+ }, [editor]);
212
+
198
213
  const onChange = useCallback(
199
214
  (newValues) => {
200
215
  editor.commands.updateAttributes('imageUploadNode', newValues);
@@ -244,13 +259,10 @@ function ImageComponent(props) {
244
259
  </StyledImageContainer>
245
260
  </StyledRoot>
246
261
 
247
- {showToolbar && (
262
+ {showToolbar && editor._tiptapContainerEl && ReactDOM.createPortal(
248
263
  <div
249
264
  ref={toolbarRef}
250
265
  style={{
251
- position: 'absolute',
252
- top: '100%',
253
- left: 0,
254
266
  zIndex: 20,
255
267
  background: 'var(--editable-html-toolbar-bg, #efefef)',
256
268
  boxShadow:
@@ -260,11 +272,24 @@ function ImageComponent(props) {
260
272
  >
261
273
  <CustomToolbarWrapper
262
274
  showDone
263
- {...options}
275
+ deletable
276
+ toolbarOpts={options.toolbarOpts || {}}
277
+ onDelete={() => {
278
+ const nodePos = findNodePos();
279
+ if (nodePos === null) return;
280
+
281
+ options.imageHandling?.onDelete?.(latestNodeRef.current);
282
+
283
+ editor.view.dispatch(
284
+ editor.state.tr.delete(nodePos, nodePos + editor.state.doc.nodeAt(nodePos).nodeSize),
285
+ );
286
+ setShowToolbar(false);
287
+ editor.commands.focus();
288
+ }}
264
289
  onDone={() => {
265
290
  setShowToolbar(false);
266
- props.imageHandling?.onDone();
267
- props.editor.commands.focus('end');
291
+ options.imageHandling?.onDone?.();
292
+ editor.commands.focus('end');
268
293
  }}
269
294
  >
270
295
  <ImageToolbar
@@ -275,7 +300,8 @@ function ImageComponent(props) {
275
300
  onChange={onChange}
276
301
  />
277
302
  </CustomToolbarWrapper>
278
- </div>
303
+ </div>,
304
+ editor._tiptapContainerEl,
279
305
  )}
280
306
  </NodeViewWrapper>
281
307
  );
@@ -298,9 +298,7 @@ export const MathNodeView = (props) => {
298
298
  ref={toolbarRef}
299
299
  data-toolbar-for={editor.instanceId}
300
300
  style={{
301
- position: 'absolute',
302
- top: `${position.top}px`,
303
- left: `${position.left}px`,
301
+ marginTop: '6px',
304
302
  zIndex: 20,
305
303
  background: 'var(--editable-html-toolbar-bg, #efefef)',
306
304
  boxShadow:
@@ -319,7 +317,7 @@ export const MathNodeView = (props) => {
319
317
  setKeypadInteraction={setKeypadInteraction}
320
318
  />
321
319
  </div>,
322
- document.body,
320
+ editor?._tiptapContainerEl || document.body,
323
321
  )}
324
322
  </NodeViewWrapper>
325
323
  );