Skip to content

[CRAFTING] fix(rich-text-web): run on change on leave only after an edit - #2456

Closed
samuelreichert wants to merge 1 commit into
mainfrom
fix/rich-text-onleave-without-edit
Closed

samuelreichert wants to merge 1 commit into
mainfrom
fix/rich-text-onleave-without-edit

Conversation

@samuelreichert

@samuelreichert samuelreichert commented Oct 6, 2026 •

Copy link
Copy Markdown
Contributor

Pull request type

Bug fix (non-breaking change which fixes an issue)


Description

With On change type = When user leaves input field, the On change action ran on every blur, even when nothing had been edited. Tabbing through a form ran the On change microflow or nanoflow without any change.

Fix: a dirty flag is set by a real edit (onUpdate). On blur, On change runs only when the flag is set, and the flag is then cleared. Syncing the external value uses emitUpdate: false, so it never sets the flag. On leave (onBlur) still runs on every blur.

The change was written test-first: the new regression test failed before the fix. Lint and the full package test suite pass, and there is a CHANGELOG entry under [Unreleased].

Note: Out of scope here: clicking a toolbar button also blurs the editor, so editing and then clicking the toolbar still runs On change. That can be a follow-up.

Based on main (rebased after #2453 was merged).

What should be covered while testing?

  1. Configure On change (type: when user leaves input field) to show a message.
  2. Tab into and out of the editor without typing. No message appears.
  3. Type, then leave the editor. The message appears once.
  4. Enter and leave again without typing. No message appears.

🤖 Generated with Claude Code

@samuelreichert
samuelreichert requested a review from a team as a code owner October 6, 2026 13:55
@samuelreichert
samuelreichert force-pushed the test/rich-text-unit-coverage branch from be0a685 to a153c39 Compare October 12, 2026 09:11
Base automatically changed from test/rich-text-unit-coverage to main October 12, 2026 11:20
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@samuelreichert
samuelreichert force-pushed the fix/rich-text-onleave-without-edit branch from e6c584d to 812c44a Compare October 12, 2026 12:57
@github-actions

Copy link
Copy Markdown
Contributor

AI Code Review

✅ Approved — no issues found


What was reviewed

File Change
packages/pluggableWidgets/rich-text-web/CHANGELOG.md Added [Unreleased] ### Fixed entry
packages/pluggableWidgets/rich-text-web/src/components/Editor.tsx Added isDirtyRef guard so onChange only fires on leave after a genuine edit
packages/pluggableWidgets/rich-text-web/src/__tests__/RichText.runtime.spec.tsx Two new regression tests; updated stale action test to include an edit before blur

Skipped (out of scope): dist/, pnpm-lock.yaml


Positives

  • Test-first approach is correct: the two new regression tests precisely cover the bug (no-edit blur → no onChange) and the reset-per-edit semantics (edit → leave → leave again → onChange fires only once). Both map directly to the bug report steps.
  • useRef is the right tool: using a ref instead of state means the dirty flag is read/written synchronously in the TipTap callbacks without triggering re-renders and without stale-closure issues — the onUpdate and onBlur handlers inside useEditor({…}, []) always see the live ref value through closure.
  • emitUpdate: false invariant is documented: the comment on isDirtyRef explicitly calls out why the external-value sync path never sets the flag, which is the key non-obvious constraint.
  • Existing test corrected: the "executes the ActionValues from the latest render" test was silently wrong after the fix (blur without edit would no longer trigger onChange); adding edit(container, "<p>edited</p>") there is the right surgical correction.
  • CHANGELOG entry is user-focused: describes observable behaviour, not implementation detail.

@samuelreichert

Copy link
Copy Markdown
Contributor Author

Superseded by #2495, which combines this fix with the other Rich Text fixes on top of the latest main.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant