Skip to content

fix: richTextEditor issue with +3 mentions#3917

Draft
xavikp wants to merge 1 commit intomainfrom
fix-mentions-tagging
Draft

fix: richTextEditor issue with +3 mentions#3917
xavikp wants to merge 1 commit intomainfrom
fix-mentions-tagging

Conversation

@xavikp
Copy link
Copy Markdown
Contributor

@xavikp xavikp commented Apr 10, 2026

Description

  • Fixed a RichTextEditor mention regression where inserting a 4th @mention in the same paragraph could replace an existing mention (typically the 3rd) instead of appending the new one.
  • The fix makes mention insertion deterministic by using TipTap’s tracked suggestion range and avoiding stale command context.

Screenshots (if applicable)

[Link to Figma Design](Figma URL here)

Implementation details

  • In src/components/RichText/CoreEditor/Extensions/Mention/suggestion.tsx:
    • Replaced manual @ backtracking logic with insertContentAt(latestProps.range, ...).
    • Moved to one atomic chain (focus + insertContentAt + run) instead of separate delete/insert runs.
    • Added latestProps updates in onStart/onUpdate so command execution always uses fresh range/editor state.
  • Kept mention payload and behavior unchanged (id, label, image_url, href, plus trailing space).
  • Added regressions in:
    • src/components/RichText/CoreEditor/Extensions/Mention/suggestion.test.tsx
    • src/components/RichText/RichTextEditor/mentions.test.tsx

Copilot AI review requested due to automatic review settings April 10, 2026 15:30
@github-actions github-actions bot added the react Changes affect packages/react label Apr 10, 2026
@github-actions
Copy link
Copy Markdown
Contributor

✅ No New Circular Dependencies

No new circular dependencies detected. Current count: 0

@github-actions
Copy link
Copy Markdown
Contributor

📦 Alpha Package Version Published

Use pnpm i github:factorialco/f0#npm/alpha-pr-3917 to install the package

Use pnpm i github:factorialco/f0#f953be608ae2f70766c521b4271c55473ddc33cb to install this specific commit

@github-actions
Copy link
Copy Markdown
Contributor

🔍 Visual review for your branch is published 🔍

Here are the links to:

@github-actions
Copy link
Copy Markdown
Contributor

Coverage Report for packages/react

Status Category Percentage Covered / Total
🔵 Lines 46.77% 11610 / 24820
🔵 Statements 45.99% 11968 / 26021
🔵 Functions 38.46% 2619 / 6809
🔵 Branches 38.53% 7639 / 19821
File Coverage
File Stmts Branches Functions Lines Uncovered Lines
Changed Files
packages/react/src/components/RichText/CoreEditor/Extensions/Mention/suggestion.tsx 81.7% 62.29% 100% 84.41% 28-33, 48, 73, 81, 137, 156, 161, 164-168
Generated in workflow #12746 for commit 1cc017f by the Vitest Coverage Report Action

@xavikp xavikp changed the title Fix richTextEditor issue with +3 mentions fix: richTextEditor issue with +3 mentions Apr 10, 2026
@github-actions github-actions bot added the fix label Apr 10, 2026
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Fixes a RichTextEditor @mention regression where inserting the 4th mention in the same paragraph could replace an existing mention, by making insertion rely on TipTap’s tracked suggestion range and by adding regressions to prevent future breakage.

Changes:

  • Switch mention insertion to insertContentAt(range, ...) using the latest suggestion props/range for deterministic behavior.
  • Add regression tests covering 4+ mentions in the same paragraph and mentions across paragraphs/consecutive mentions.
  • Minor import re-order in an existing RichTextEditor test.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 5 comments.

File Description
packages/react/src/components/RichText/CoreEditor/Extensions/Mention/suggestion.tsx Updates mention suggestion insertion logic to use the latest suggestion range and an atomic chain.
packages/react/src/components/RichText/CoreEditor/Extensions/Mention/suggestion.test.tsx Adds unit coverage ensuring the mention insertion uses the latest range/editor state.
packages/react/src/components/RichText/RichTextEditor/mentions.test.tsx Adds integration regressions for multiple mentions, including the “4th mention” scenario.
packages/react/src/components/RichText/RichTextEditor/index.spec.tsx Minor import reordering in an existing test file.

})

import { RichTextEditor } from "./index"
import React from "react"
Copy link

Copilot AI Apr 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

import React from "react" is unused in this test file (JSX runtime doesn't require it here). With oxlint no-unused-vars enabled, this will fail lint; remove the import or use it for a referenced type/value.

Suggested change
import React from "react"

Copilot uses AI. Check for mistakes.
import { waitFor } from "@testing-library/react"
import { afterEach, describe, expect, it, vi } from "vitest"

import { screen, userEvent, zeroRender } from "../../../testing/test-utils"
Copy link

Copilot AI Apr 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The test utilities are imported via a long relative path. The repo consistently uses the @/ alias for internal imports (e.g. @/testing/test-utils), which is less brittle if folders move.

Suggested change
import { screen, userEvent, zeroRender } from "../../../testing/test-utils"
import { screen, userEvent, zeroRender } from "@/testing/test-utils"

Copilot uses AI. Check for mistakes.
Comment on lines +55 to +57

const editor = document.querySelector(".ProseMirror") as HTMLElement

Copy link

Copilot AI Apr 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

document.querySelector(".ProseMirror") as HTMLElement will throw a confusing runtime error if the editor isn't rendered. Prefer asserting the element exists (or querying via Testing Library) before using it, to make failures actionable.

Copilot uses AI. Check for mistakes.
Comment on lines 1 to 3
import { render, screen } from "@testing-library/react"
import userEvent from "@testing-library/user-event"
import { expect, test, vi } from "vitest"
Copy link

Copilot AI Apr 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This test uses render/userEvent directly from Testing Library. In packages/react, the established convention is to use zeroRender (and the preconfigured userEvent) from @/testing/test-utils for consistent providers/setup.

Copilot uses AI. Check for mistakes.
Comment on lines 51 to 55
let component: ReactRenderer | null = null
let popoverRoot: Root | null = null
let container: HTMLDivElement | null = null
let latestProps: SuggestionRenderProps | null = null

Copy link

Copilot AI Apr 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

latestProps is retained in a closure and never cleared. Consider resetting it in onExit (and/or when handling Escape) to avoid holding stale editor references longer than needed.

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

fix react Changes affect packages/react

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants