Skip to content

fix(sender): preserve slots for text selection deletion - #2033

Open
advance-hub wants to merge 3 commits into
ant-design:mainfrom
advance-hub:codex/fix-slot-selection-delete
Open

advance-hub wants to merge 3 commits into
ant-design:mainfrom
advance-hub:codex/fix-slot-selection-delete

Conversation

@advance-hub

@advance-hub advance-hub commented Aug 25, 2026 •

Copy link
Copy Markdown
Contributor

Why

In Sender slot mode, Backspace treated a non-collapsed text selection as a caret at offset zero. When the selection edge touched a slot, Sender removed the slot and prevented the browser from deleting the selected text.

Fixes #1906.

What changed

  • Restrict preceding-slot deletion to collapsed caret ranges.
  • Let the browser handle normal non-collapsed text selection deletion.
  • Add a regression test for a backwards text selection whose edge touches a slot.

Verification

  • Sender slot Jest suite: 23 passed.
  • TypeScript --noEmit check passed.
  • Biome and git diff --check passed.
  • Real Chromium before/after reproduction passed.

Before / After

Before: Backspace removes the adjacent slot while the selected text remains.

before.mp4

After: Backspace deletes the selected text while preserving the slot.

after.mp4

Changelog: Fix Sender slot mode deleting the adjacent slot before a selected text range.

Summary by CodeRabbit

  • Bug 修复
    • 修复在选中文本时按 Backspace 误删相邻标签槽位或技能项的问题;现在会优先删除选中的文本并保留相邻项目。
    • 光标未选中文本且位于标签槽位或技能项后方时,按 Backspace 可删除前置项目,同时保留其后的文本。

Why:
- Backspace treated a non-collapsed selection as a caret at offset zero.
- When the selection edge touched a slot, Sender removed the slot and prevented the browser from deleting the selected text.

What:
- Limit preceding-slot removal to collapsed ranges.
- Add a regression test for a backwards text selection adjacent to a slot.

Testing:
- Sender slot Jest suite (23 tests)
- TypeScript noEmit check
- Biome check and git diff --check
- Real Chromium before/after interaction
@dosubot dosubot Bot added the bug Something isn't working label Aug 25, 2026
@coderabbitai

coderabbitai Bot commented Aug 25, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

No actionable comments were generated in the recent review.

Recent review info
Run configuration
  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: Repository UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 05a5df5c-77a8-4886-9de8-d5543c956306
Commits

Reviewing files that changed from the base of the PR and between b57a287 and cab9d7b.

Files selected for processing: 1
  • packages/x/components/sender/__tests__/slot.test.tsx

Included review availability: This review used your included allowance. Your plan provides up to 8 included reviews per hour; 7 remain after this review.

Walkthrough

本次变更收紧 SlotTextArea 的退格删除条件。选区折叠时,Backspace 可删除相邻的 slot 或 skill;选区非折叠时,前置 slot 保留。新增测试覆盖这两类选区及 onChange 调用结果。

Changes: Sender slot 删除行为

Layer / File(s) Summary
退格删除条件与回归测试
packages/x/components/sender/components/SlotTextArea.tsx, packages/x/components/sender/__tests__/slot.test.tsx
SlotTextArea 仅在选区折叠时通过 Backspace 删除前置 slot 或 skill。测试验证折叠选区可删除 skill 或 slot 并调用一次 onChange;非折叠选区会保留 slot,且不调用 onChange。

Priority: Normal

Estimated code review effort: 2 (Simple) | ~10 minutes

Change: Bug fix

Possibly related issues

  • ant-design/x#1906:该问题报告选中文本删除触及 slot 时会先删除 slot。本次变更针对非折叠选区增加保护。

Suggested reviewers: nrps9909

Merge Risk: Minimal · up to cab9d

The slot-preservation regression is covered, and no outstanding issue was identified. This change is ready to merge after normal checks.

Pre-merge checks: Passed 5
Check name Status Explanation
Description Check Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check Passed 标题准确概括了主要变更:修复文本选区删除时保留前置 slot。标题简洁、明确,并与代码及测试变更一致。
Linked Issues check Passed PR #1906 的编码要求是修复 Sender slot 模式下删除非折叠文本选区时误删 slot 或阻止正常删除的问题。SlotTextArea.tsx 在退格删除分支中仅对 range?.collapsed 的光标执行前置 slot/skill 删除。非折叠选区交由浏览器处理。slot.test.tsx 新增了选区边缘接触 slot 的回归测试,并验证 slot 保留且不触发 `…
Out of Scope Changes check Passed 变更仅涉及 SlotTextArea.tsx 的退格删除条件和对应的 slot.test.tsx 回归测试。测试重构直接验证 slot 删除与非折叠选区删除行为。未发现与 PR #1906 无关的产品功能、公共 API 或其他范围外变更。
Docstring Coverage Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check. Docstring coverage is scoped to functions touched by this diff. Analyzed 0 functions across 2…
Full details: Linked Issues check

Explanation

PR #1906 的编码要求是修复 Sender slot 模式下删除非折叠文本选区时误删 slot 或阻止正常删除的问题。SlotTextArea.tsx 在退格删除分支中仅对 range?.collapsed 的光标执行前置 slot/skill 删除。非折叠选区交由浏览器处理。slot.test.tsx 新增了选区边缘接触 slot 的回归测试,并验证 slot 保留且不触发 onChange。测试还覆盖了折叠光标删除前置 slot 和 skill 的原有行为。现有证据支持该问题已实现修复。

Full details: Docstring Coverage

Explanation

No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check. Docstring coverage is scoped to functions touched by this diff. Analyzed 0 functions across 2 files.

Finishing Touches
🧪 Generate unit tests (beta)
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

一只小兔轻敲退格键,
折叠光标旁,slot 轻轻离开。
选中文本时,slot 留在原地,
skill 删除后,文本依然清晰。
测试点点头,回调记录一次。
月光下,小兔收起键盘。<fixed_issue_severity>Medium</fixed_issue_severity>

Comment @coderabbitai help to get the list of available commands.

@nrps9909 nrps9909 left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Reviewed exact head 189de5b3d21d6792b68920cc95440697c58e6aa1 against base 25aad7b9c13abeb165466d53b375d0f2ffe81fa0.

The collapsed-range guard is the right boundary. Reverting only that guard makes the submitted backwards-selection regression fail exactly as intended: the keydown is prevented at the focus edge and the adjacent slot enters the deletion path. Restoring this head makes the complete Sender slot file pass 23/23. I also added a temporary complementary probe for a collapsed caret at offset zero; all 24 tests passed, and the preceding slot was still removed with one onChange, so the existing caret behavior is preserved.

Additional exact-head validation:

  • package TypeScript --noEmit passes
  • Biome check passes on both changed files
  • git diff --check passes
  • GitHub reports the head mergeable and all current remote checks green

The repository has no lockfile, so I ran the behavioral suite with an internally consistent @ant-design/cssinjs dependency pair and reran TypeScript after deduping the currently resolved pair; this avoids treating an unrelated transform-cache/dependency-topology issue as a Sender failure.

AI assistance disclosure: Codex helped inspect the exact diff and run the red/green and complementary probes; I verified the SHA, source paths, outputs, static checks, and live status directly.

Approved.

@codecov

codecov Bot commented Oct 24, 2026 •

Copy link
Copy Markdown

Bundle Report

Changes will decrease total bundle size by 2.4MB (-41.12%) ⬇️. This is within the configured threshold ✅

Detailed changes
Bundle name Size Change
x-markdown-array-push 146.35kB -1.46MB (-90.9%) ⬇️
antdx-array-push 1.17MB -938.62kB (-44.49%) ⬇️

Affected Assets, Files, and Routes:

view changes for bundle: antdx-array-push

Assets Changed:

Asset Name Size Change Total Size Change (%)
antdx.min.js -938.62kB 1.17MB -44.49%
view changes for bundle: x-markdown-array-push

Assets Changed:

Asset Name Size Change Total Size Change (%)
x-markdown.min.js (New) 138.43kB 138.43kB 100.0% 🚀
x-markdown.min.css (New) 7.91kB 7.91kB 100.0% 🚀
latex.js (Deleted) -506.75kB 0 bytes -100.0% 🗑️
static/KaTeX_AMS-Regular.*.ttf (Deleted) -63.63kB 0 bytes -100.0% 🗑️
static/KaTeX_Main-Regular.*.ttf (Deleted) -53.58kB 0 bytes -100.0% 🗑️
static/KaTeX_Main-Bold.*.ttf (Deleted) -51.34kB 0 bytes -100.0% 🗑️
static/KaTeX_Main-Italic.*.ttf (Deleted) -33.58kB 0 bytes -100.0% 🗑️
static/KaTeX_AMS-Regular.*.woff (Deleted) -33.52kB 0 bytes -100.0% 🗑️
static/KaTeX_Main-BoldItalic.*.ttf (Deleted) -32.97kB 0 bytes -100.0% 🗑️
static/KaTeX_Math-Italic.*.ttf (Deleted) -31.31kB 0 bytes -100.0% 🗑️
static/KaTeX_Math-BoldItalic.*.ttf (Deleted) -31.2kB 0 bytes -100.0% 🗑️
static/KaTeX_Main-Regular.*.woff (Deleted) -30.77kB 0 bytes -100.0% 🗑️
static/KaTeX_Main-Bold.*.woff (Deleted) -29.91kB 0 bytes -100.0% 🗑️
static/KaTeX_AMS-Regular.*.woff2 (Deleted) -28.08kB 0 bytes -100.0% 🗑️
static/KaTeX_Typewriter-Regular.*.ttf (Deleted) -27.56kB 0 bytes -100.0% 🗑️
static/KaTeX_Main-Regular.*.woff2 (Deleted) -26.27kB 0 bytes -100.0% 🗑️
static/KaTeX_Main-Bold.*.woff2 (Deleted) -25.32kB 0 bytes -100.0% 🗑️
static/KaTeX_SansSerif-Bold.*.ttf (Deleted) -24.5kB 0 bytes -100.0% 🗑️
latex.css (Deleted) -24.39kB 0 bytes -100.0% 🗑️
static/KaTeX_SansSerif-Italic.*.ttf (Deleted) -22.36kB 0 bytes -100.0% 🗑️
static/KaTeX_Main-Italic.*.woff (Deleted) -19.68kB 0 bytes -100.0% 🗑️
static/KaTeX_Fraktur-Bold.*.ttf (Deleted) -19.58kB 0 bytes -100.0% 🗑️
static/KaTeX_Fraktur-Regular.*.ttf (Deleted) -19.57kB 0 bytes -100.0% 🗑️
static/KaTeX_SansSerif-Regular.*.ttf (Deleted) -19.44kB 0 bytes -100.0% 🗑️
static/KaTeX_Main-BoldItalic.*.woff (Deleted) -19.41kB 0 bytes -100.0% 🗑️
static/KaTeX_Math-Italic.*.woff (Deleted) -18.75kB 0 bytes -100.0% 🗑️
static/KaTeX_Math-BoldItalic.*.woff (Deleted) -18.67kB 0 bytes -100.0% 🗑️
static/KaTeX_Main-Italic.*.woff2 (Deleted) -16.99kB 0 bytes -100.0% 🗑️
static/KaTeX_Main-BoldItalic.*.woff2 (Deleted) -16.78kB 0 bytes -100.0% 🗑️
static/KaTeX_Script-Regular.*.ttf (Deleted) -16.65kB 0 bytes -100.0% 🗑️
static/KaTeX_Math-Italic.*.woff2 (Deleted) -16.44kB 0 bytes -100.0% 🗑️
static/KaTeX_Math-BoldItalic.*.woff2 (Deleted) -16.4kB 0 bytes -100.0% 🗑️
static/KaTeX_Typewriter-Regular.*.woff (Deleted) -16.03kB 0 bytes -100.0% 🗑️
static/KaTeX_SansSerif-Bold.*.woff (Deleted) -14.41kB 0 bytes -100.0% 🗑️
static/KaTeX_SansSerif-Italic.*.woff (Deleted) -14.11kB 0 bytes -100.0% 🗑️
static/KaTeX_Typewriter-Regular.*.woff2 (Deleted) -13.57kB 0 bytes -100.0% 🗑️
static/KaTeX_Fraktur-Bold.*.woff (Deleted) -13.3kB 0 bytes -100.0% 🗑️
static/KaTeX_Fraktur-Regular.*.woff (Deleted) -13.21kB 0 bytes -100.0% 🗑️
static/KaTeX_Caligraphic-Bold.*.ttf (Deleted) -12.37kB 0 bytes -100.0% 🗑️
static/KaTeX_Caligraphic-Regular.*.ttf (Deleted) -12.34kB 0 bytes -100.0% 🗑️
static/KaTeX_SansSerif-Regular.*.woff (Deleted) -12.32kB 0 bytes -100.0% 🗑️
static/KaTeX_Size1-Regular.*.ttf (Deleted) -12.23kB 0 bytes -100.0% 🗑️
static/KaTeX_SansSerif-Bold.*.woff2 (Deleted) -12.22kB 0 bytes -100.0% 🗑️
static/KaTeX_SansSerif-Italic.*.woff2 (Deleted) -12.03kB 0 bytes -100.0% 🗑️
static/KaTeX_Size2-Regular.*.ttf (Deleted) -11.51kB 0 bytes -100.0% 🗑️
static/KaTeX_Fraktur-Bold.*.woff2 (Deleted) -11.35kB 0 bytes -100.0% 🗑️
static/KaTeX_Fraktur-Regular.*.woff2 (Deleted) -11.32kB 0 bytes -100.0% 🗑️
static/KaTeX_Script-Regular.*.woff (Deleted) -10.59kB 0 bytes -100.0% 🗑️
static/KaTeX_Size4-Regular.*.ttf (Deleted) -10.36kB 0 bytes -100.0% 🗑️
static/KaTeX_SansSerif-Regular.*.woff2 (Deleted) -10.34kB 0 bytes -100.0% 🗑️
static/KaTeX_Script-Regular.*.woff2 (Deleted) -9.64kB 0 bytes -100.0% 🗑️
static/KaTeX_Caligraphic-Bold.*.woff (Deleted) -7.72kB 0 bytes -100.0% 🗑️
static/KaTeX_Caligraphic-Regular.*.woff (Deleted) -7.66kB 0 bytes -100.0% 🗑️
static/KaTeX_Size3-Regular.*.ttf (Deleted) -7.59kB 0 bytes -100.0% 🗑️
static/KaTeX_Caligraphic-Bold.*.woff2 (Deleted) -6.91kB 0 bytes -100.0% 🗑️
static/KaTeX_Caligraphic-Regular.*.woff2 (Deleted) -6.91kB 0 bytes -100.0% 🗑️
static/KaTeX_Size1-Regular.*.woff (Deleted) -6.5kB 0 bytes -100.0% 🗑️
static/KaTeX_Size2-Regular.*.woff (Deleted) -6.19kB 0 bytes -100.0% 🗑️
static/KaTeX_Size4-Regular.*.woff (Deleted) -5.98kB 0 bytes -100.0% 🗑️
static/KaTeX_Size1-Regular.*.woff2 (Deleted) -5.47kB 0 bytes -100.0% 🗑️
static/KaTeX_Size2-Regular.*.woff2 (Deleted) -5.21kB 0 bytes -100.0% 🗑️
static/KaTeX_Size4-Regular.*.woff2 (Deleted) -4.93kB 0 bytes -100.0% 🗑️
static/KaTeX_Size3-Regular.*.woff (Deleted) -4.42kB 0 bytes -100.0% 🗑️
static/KaTeX_Size3-Regular.*.woff2 (Deleted) -3.62kB 0 bytes -100.0% 🗑️

@codecov

codecov Bot commented Oct 24, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 97.25%. Comparing base (25aad7b) to head (cab9d7b).
⚠️ Report is 39 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #2033      +/-   ##
==========================================
+ Coverage   97.07%   97.25%   +0.18%     
==========================================
  Files         159      163       +4     
  Lines        5777     6305     +528     
  Branches     1702     1878     +176     
==========================================
+ Hits         5608     6132     +524     
- Misses        167      171       +4     
  Partials        2        2              

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

This branch has not been deployed

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

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

sender的slot模式选中文本删除问题

2 participants