Skip to content

Fix caret jumping to the title after inserting a Plone block - #235

Merged
sneridagh merged 1 commit into
mainfrom
fix-plone-block-caret
Oct 6, 2026
Merged

sneridagh merged 1 commit into
mainfrom
fix-plone-block-caret

Conversation

@sneridagh

@sneridagh sneridagh commented Oct 6, 2026 •

Copy link
Copy Markdown
Member

Inserting a Plone block from the slash menu (Image, Teaser, Listing) left the caret at the start of the title instead of on the new block, so typing went into the title.

Two causes in plone-block-adapter.tsx:

  • Lazy Edit components suspended the whole block. Block edit/view components are React.lazy. The first render suspended up to a boundary above the element, so the block element and Slate's spacer text were not in the DOM when the slash menu refocused the editor. ReactEditor.focus threw Cannot resolve a DOM node from Slate node before calling el.focus(), and the browser caret stayed in the title.
  • The whole void element was contentEditable={false}, spacer included, so the browser could not place the caret on the block. Once the paragraph holding the slash command was removed, the caret fell back to the start of the editor. (This one shows up when the Edit component is already loaded, e.g. in Volto-based integrations of the editor.)

The fix gives the block's own UI its own Suspense boundary and moves contentEditable={false} onto a wrapper around it, so the element and its spacer render immediately and stay editable.

Tests

New acceptance test in packages/plate/acceptance/tests/slash-menu.test.ts, run for Image, Teaser and Listing: after inserting the block, the editor has focus and the DOM caret and Slate selection are on the new block. It fails on main and passes with this change. The full packages/plate acceptance suite (86) and unit tests (74) pass, and check:ts is clean.

Inserting a Plone block from the slash menu (image, teaser, listing) left
the caret at the start of the title instead of on the new block.

Two things in the Plone block adapter caused it:

- Block Edit components are lazy. The first time one is rendered it
  suspends, and since the nearest Suspense boundary was above the
  element, the whole block (including Slate's spacer text) stayed out of
  the DOM. When the slash menu refocused the editor, `ReactEditor.focus`
  threw "Cannot resolve a DOM node from Slate node" before focusing, and
  the browser kept the caret in the title.
- `contentEditable: false` was set on the void element itself, spacer
  included, so the browser could not place the caret on the block and
  dropped it at the start of the editor once the paragraph holding it was
  removed.

Give the block's own UI its own Suspense boundary and move
`contentEditable={false}` onto a wrapper around it, so the element and
its spacer render immediately and stay editable.
@sneridagh
sneridagh merged commit 7e1cc3f into main Oct 6, 2026
41 checks passed
@sneridagh
sneridagh deleted the fix-plone-block-caret branch October 6, 2026 10:18
sneridagh added a commit that referenced this pull request Oct 6, 2026
* b10-plone-blocks:
  Releasing @plone/aurora 1.0.0-alpha.18
  Release @plone/plate 1.0.0-alpha.24
  Remove unused @plone/quanta dependency from @plone/plate (#236)
  Releasing @plone/aurora 1.0.0-alpha.17
  Release @plone/plate 1.0.0-alpha.23
  Fix caret jumping to the title after inserting a Plone block (#235)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant