Skip to content

Update collab text to use anchor tracking - #27907

Merged
daesunp merged 9 commits into
microsoft:mainfrom
daesunp:collab-text-anchor-track
Aug 25, 2026
Merged

daesunp merged 9 commits into
microsoft:mainfrom
daesunp:collab-text-anchor-track

Conversation

@daesunp

@daesunp daesunp commented Aug 10, 2026

Copy link
Copy Markdown
Contributor

Description

Updates collab text plain text selection tracking to use the array node anchor tracking feature.

Copilot AI lite review requested due to automatic review settings August 10, 2026 18:06
@daesunp
daesunp requested review from a team as code owners August 10, 2026 18:06
@github-actions github-actions Bot added base: main PRs targeted against main branch area: framework Framework is a tag for issues involving the developer framework. Eg Aqueduct area: tools area: dds Issues related to distributed data structures area: repo Repo related work area: website public api change Changes to a public API area: dds: tree changeset-present labels Aug 10, 2026
@github-actions

github-actions Bot commented Aug 10, 2026 •

Copy link
Copy Markdown
Contributor

Hi! Thank you for opening this PR. Want me to review it?

Based on the diff (411 lines, 7 files), I've queued these reviewers:

  • Correctness — logic errors, race conditions, lifecycle issues
  • Security — vulnerabilities, secret exposure, injection
  • API Compatibility — breaking changes, release tags, type design
  • Performance — algorithmic regressions, memory leaks
  • Testing — coverage gaps, hollow tests

How this works

  • Adjust the reviewer set by ticking/unticking boxes above. Reviewer toggles alone don't trigger anything.

  • Tick Start review below to dispatch the review fleet.

  • After review finishes, tick Start review again to request another run — it auto-resets after each dispatch.

  • This comment updates as new commits land; your reviewer selections are preserved.

  • Start review

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Updates the React plain-text collaboration utilities to track textarea selections via PlainText.Tree insertion anchors, so selections follow remote edits without manual per-delta cursor math.

Changes:

  • Add PlainText.Tree.createInsertionAnchor() (tree) and switch selection tracking to use anchor indices (React hook + editor view).
  • Extend useTreeSynchronizedString to expose setSelection() and compute selections from anchors.
  • Simplify applyTextOps to only return the updated string; expand tests to cover anchor-based selection behaviors (including hydration and surrogate pairs).

Reviewed changes

Copilot reviewed 12 out of 12 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
packages/framework/react/src/text/plain/useTreeSynchronizedString.ts Reworks selection tracking to use insertion anchors and exposes setSelection() to update tracked selection.
packages/framework/react/src/text/plain/plainUtils.ts Simplifies applyTextOps to return just the updated string; keeps reread-based selection remapping helper.
packages/framework/react/src/text/plain/plainTextView.tsx Wires textarea onSelect/onChange to setSelection() so the editor can preserve selection across remote edits.
packages/framework/react/src/test/text/useTreeSynchronizedString.spec.ts Adds/updates tests for anchor-based selection behavior, bounds clamping, surrogate pairs, and hydration.
packages/framework/react/src/test/text/plainUtils.test.ts Updates tests to match the simplified applyTextOps return type and scope.
packages/framework/react/api-report/react.alpha.api.md API report update for SynchronizedString.setSelection.
packages/framework/fluid-framework/api-report/fluid-framework.alpha.api.md API report update for PlainText.Tree.createInsertionAnchor.
packages/dds/tree/src/text/textDomainFormatted.ts Adds createInsertionAnchor implementation for formatted text’s underlying content array.
packages/dds/tree/src/text/textDomain.ts Adds createInsertionAnchor to PlainText members and implements it via array insertion anchors.
packages/dds/tree/src/test/text/textDomain.spec.ts Adds hydration test verifying insertion anchors track across edits.
packages/dds/tree/api-report/tree.alpha.api.md API report update for PlainText.Tree.createInsertionAnchor.
.changeset/small-suns-tickle.md Declares minor bumps and documents the new anchor-based selection tracking behavior.
Suppressed comments (2)

packages/framework/react/src/text/plain/plainTextView.tsx:108

  • HTMLTextAreaElement.selectionStart/selectionEnd are typed as number | null. Normalize them (e.g. ?? 0) before calling setSelection to avoid null propagation / TS errors.
		(event: SyntheticEvent<HTMLTextAreaElement>) => {
			setSelection({
				start: event.currentTarget.selectionStart,
				end: event.currentTarget.selectionEnd,
			});

packages/framework/react/src/text/plain/useTreeSynchronizedString.ts:78

  • The example uses selectionStart/selectionEnd directly, but in TS DOM typings these are number | null. Adding a fallback avoids TS errors when consumers copy/paste this snippet.
 *     onChange={(e) => {
 *       TreeAlpha.context(tree).runTransaction(() => syncTextToTree(tree, e.target.value));
 *       setSelection({ start: e.target.selectionStart, end: e.target.selectionEnd });
 *     }}

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Added a couple more comments, but otherwise this is looking good to me.

@Josmithr

Copy link
Copy Markdown
Contributor

daesunp Craig is merging a PR that makes the tree API changes here. #28045

@github-actions github-actions Bot removed area: dds Issues related to distributed data structures area: dds: tree labels Aug 24, 2026
@github-actions

Copy link
Copy Markdown
Contributor

🔗 No broken links found! ✅

Your attention to detail is admirable.

linkcheck output

$ start-server-and-test "npm run serve -- --host 127.0.0.1 --no-open" http://127.0.0.1:3000 check-links
1: starting server using command "npm run serve -- --host 127.0.0.1 --no-open"
and when url "[ 'http://127.0.0.1:3000' ]" is responding with HTTP status code 200
running tests using command "npm run check-links"


> fluid-framework-website@0.0.0 serve
> docusaurus serve --host 127.0.0.1 --no-open

[SUCCESS] Serving "build" directory at: http://127.0.0.1:3000/

> fluid-framework-website@0.0.0 check-links
> linkcheck http://127.0.0.1:3000 --skip-file skipped-urls.txt

Crawling...

Stats:
  338440 links
    2041 destination URLs
    2297 URLs ignored
       0 warnings
       0 errors


@github-actions

Copy link
Copy Markdown
Contributor

Bundle size comparison

Base commit: 7ab015c49deec84833cdfe1fb5e1606b901f6e81
Head commit: 0fcb05a547608f68d43ae0f968279bd79ec1865d

Pending — Build - client packages is running. Results will appear here when the build completes.

@daesunp
daesunp merged commit 23c8323 into microsoft:main Aug 25, 2026
39 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: framework Framework is a tag for issues involving the developer framework. Eg Aqueduct area: repo Repo related work area: tools area: website base: main PRs targeted against main branch changeset-present public api change Changes to a public API

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants