Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Conversation

@anxLiang
Copy link
Contributor

@anxLiang anxLiang commented Jan 26, 2026

中文版模板 / Chinese template

🤔 This is a ...

  • 🆕 New feature
  • 🐞 Bug fix
  • 📝 Site / documentation improvement
  • 📽️ Demo improvement
  • 💄 Component style improvement
  • 🤖 TypeScript definition improvement
  • 📦 Bundle size optimization
  • ⚡️ Performance optimization
  • ⭐️ Feature enhancement
  • 🌐 Internationalization
  • 🛠 Refactoring
  • 🎨 Code style optimization
  • ✅ Test Case
  • 🔀 Branch merge
  • ⏩ Workflow
  • ⌨️ Accessibility improvement
  • ❓ Other (about what?)

🔗 Related Issues

  • Describe the source of related requirements, such as links to relevant issue discussions.
  • For example: close #xxxx, fix #xxxx

fix #1684

💡 Background and Solution

  • The specific problem to be addressed.
  • List the final API implementation and usage if needed.
  • If there are UI/interaction changes, consider providing screenshots or GIFs.

📝 Change Log

Language Changelog
🇺🇸 English Change the way Bubble.List listens for scrollbar changes.
🇨🇳 Chinese 改变 Bubble.List 对滚动条变化的监听方式

Summary by CodeRabbit

发行说明

  • 新增功能

    • 列表引入独立的滚动内容容器,提升与尺寸观察器的兼容性和滚动控制精度。
  • 性能改进

    • 将内容变化检测切换为基于尺寸观察的方式,改善在窗口或内容变更时的滚动定位与响应。
  • 样式优化

    • 调整列表与滚动区的布局与内边距,优化内容间距与自适应行为。
  • 修复

    • 调整自动滚动与消息渲染顺序与展示文本,确保在不同滚动模式下显示一致性。

✏️ Tip: You can customize this high-level summary in your review settings.

@github-actions
Copy link
Contributor

github-actions bot commented Jan 26, 2026

Preview is ready

@codecov
Copy link

codecov bot commented Jan 26, 2026

Bundle Report

Changes will increase total bundle size by 1.25MB (66.43%) ⬆️⚠️, exceeding the configured threshold of 5%.

Bundle name Size Change
x-markdown-array-push 1.37MB 1.25MB (1048.02%) ⬆️⚠️
antdx-array-push 1.76MB 194 bytes (0.01%) ⬆️

Affected Assets, Files, and Routes:

view changes for bundle: antdx-array-push

Assets Changed:

Asset Name Size Change Total Size Change (%)
antdx.min.js 194 bytes 1.76MB 0.01%
view changes for bundle: x-markdown-array-push

Assets Changed:

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

@dosubot dosubot bot added the bug Something isn't working label Jan 26, 2026
@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello @anxLiang, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request significantly enhances the Bubble.List component's scroll management by overhauling its content change detection. By switching to a ResizeObserver on a dedicated content wrapper, the component can now more reliably maintain scroll position and auto-scroll behavior, particularly when list items are dynamically added or removed. This change directly addresses a known issue with scrollbar change detection, leading to a more robust and compatible user experience.

Highlights

  • Refactored Scroll Observation: The useCompatibleScroll hook now utilizes a ResizeObserver on a dedicated content container (scrollContentDom) instead of a MutationObserver on the main scroll box. This change aims to provide more precise and efficient monitoring of content size changes for scroll locking.
  • New DOM Structure for Scroll Content: A new div element with the class ant-bubble-list-scroll-content has been introduced within Bubble.List to wrap the actual list items. This new element serves as the target for the ResizeObserver.
  • Improved Scroll Locking Logic: The logic within useCompatibleScroll for determining if the scroll is at the bottom (isScrollToBottom) has been updated to correctly account for the new content container, ensuring proper scroll behavior, especially in column-reverse layouts.
  • Updated Styling and Tests: Associated CSS styles have been adjusted to accommodate the new DOM structure, and comprehensive unit and snapshot tests have been updated or added to validate the new scroll observation mechanism and ensure its correct functionality.

🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console.

Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jan 26, 2026

Note

Other AI code review bot(s) detected

CodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review.

📝 Walkthrough

Walkthrough

该 PR 为 BubbleList 引入独立的内容容器 scrollContentDom 并将内容监听由 MutationObserver 切换为 ResizeObserver,更新了 hook 签名、组件渲染结构、样式及对应测试以配合新的滚动/监听逻辑。

Changes

Cohort / File(s) 变更摘要
Hook API 更新
packages/x/components/bubble/hooks/useCompatibleScroll.ts
将 hook 签名从单参数 dom 改为双参数 (scrollDom, contentDom);用 ResizeObserver 替代 MutationObserver;调整 observer、哨兵插入及滚动/锁定逻辑,更新依赖数组和早期返回条件。
组件实现变更
packages/x/components/bubble/BubbleList.tsx
增加 scrollContentDom 引用,调用新签名的 useCompatibleScroll(scrollDom, contentDom);调整渲染结构,将 items 包裹进 .scroll-content 容器以便观测内容高度变化。
样式调整
packages/x/components/bubble/style/list.ts
在列表样式中移除部分在滚动盒层的布局属性,新增 .scroll-content 样式(flex、width、height: fit-content、paddingInline 等)以匹配新的 DOM 结构。
测试用例更新:滚动
packages/x/components/bubble/__tests__/list-scroll.test.tsx
所有相关测试改为传入 contentDom 参数并用 ResizeObserver 模拟尺寸变化;将 MutationObserver 断言替换为 ResizeObserver 断言,验证 scrollLock 与 底部追踪 在不同方向/场景下的行为。
测试用例更新:渲染期望
packages/x/components/bubble/__tests__/list.test.tsx
调整 autoScroll 场景的顺序断言(渲染顺序反转)并更新若干文本期望(如将 '消息' 改为 '用户消息')。
Demo 布局调整
packages/x/components/bubble/demo/list-scroll.tsx, packages/x/components/bubble/demo/list.tsx
按钮区改为允许换行的横向布局;将 Bubble.List 包裹于 div(display:flex; flex:1; minHeight:0)以约束尺寸,未改变外部 API。

Sequence Diagram

sequenceDiagram
    participant BubbleList as BubbleList<br/>Component
    participant useScroll as useCompatibleScroll<br/>Hook
    participant RO as ResizeObserver
    participant ScrollDom as Scroll<br/>Container
    participant ContentDom as ScrollContent<br/>Container

    BubbleList->>BubbleList: 获取 scrollBoxDom 和 scrollContentDom 引用
    BubbleList->>useScroll: 调用 useCompatibleScroll(scrollDom, contentDom)
    useScroll->>useScroll: 校验 scrollDom 与 contentDom 是否存在
    alt 任一 DOM 不存在
        useScroll-->>BubbleList: 提前返回(无 observers)
    else 都存在
        useScroll->>RO: 创建 ResizeObserver 并监听 ContentDom
        useScroll->>ScrollDom: 在 ScrollDom 中插入哨兵元素(IntersectionObserver 关联)
        ContentDom->>RO: 内容高度发生变化(展开/折叠)
        RO->>useScroll: 触发 resize 回调
        useScroll->>useScroll: 计算是否处于底部并决定是否 scrollTo
        alt 处于底部
            useScroll->>ScrollDom: 执行 scrollTo 保持底部
        else 非底部
            useScroll->>ScrollDom: 保持当前滚动位置
        end
        useScroll-->>BubbleList: 返回滚动控制接口
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

🐰 我把内容盒轻轻搬,
观察器换成了 Resize 的窗,
展开折叠不扰端点忙,
滚动稳住像根小胡萝卜,
鼓掌庆祝,兔子来唱一曲 🌿

🚥 Pre-merge checks | ✅ 4 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed PR标题清晰准确地反映了主要变更:将Bubble.List的滚动观察器从MutationObserver改为ResizeObserver,这是解决问题#1684的核心改动。
Linked Issues check ✅ Passed 代码变更完全满足linked issue #1684的要求:通过将scrollContentDom分离出来并使用ResizeObserver替代MutationObserver,能够准确监听内容高度变化,从而在Thinking组件展开/折叠时保持滚动位置稳定。
Out of Scope Changes check ✅ Passed 所有代码变更都在#1684的解决方案范围内。样式调整、Demo布局优化、测试更新均是为支持新的scroll observer实现而必需的相关改动。

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix/bubblelist

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

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

@codecov
Copy link

codecov bot commented Jan 26, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 97.32%. Comparing base (20994e9) to head (526fd55).
⚠️ Report is 1 commits behind head on main.

Additional details and impacted files
@@           Coverage Diff           @@
##             main    #1690   +/-   ##
=======================================
  Coverage   97.32%   97.32%           
=======================================
  Files         144      144           
  Lines        4565     4568    +3     
  Branches     1271     1265    -6     
=======================================
+ Hits         4443     4446    +3     
  Misses        120      120           
  Partials        2        2           

☔ View full report in Codecov by Sentry.
📢 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.

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

The pull request refactors the scroll observation mechanism in Bubble.List to use a ResizeObserver on a dedicated content div (scrollContentDom) instead of a MutationObserver on the main scroll container (scrollBoxDom). This change enhances the accuracy and efficiency of detecting content size changes for scroll locking, particularly in column-reverse layouts. Associated test files and styling have been updated to reflect these changes, ensuring consistency across the component. The removal of explicit data reversal logic (.reverse()) suggests that the visual order is now primarily managed by CSS flex-direction: column-reverse, simplifying the rendering process.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
packages/x/components/bubble/__tests__/list.test.tsx (1)

140-146: 测试注释与实际逻辑不符

Line 144-145 的注释标注都是 // user role,但实际上 mockItemsitem1 是 user,item2 是 ai。建议修正注释以避免维护时产生困惑。

💡 建议修正注释
     it('should support empty role', () => {
       const { container } = render(<BubbleList items={mockItems} />);
       const bubbles = container.querySelectorAll('.ant-bubble');
 
-      expect(bubbles[1]).toHaveClass('ant-bubble-start'); // user role
-      expect(bubbles[0]).toHaveClass('ant-bubble-start'); // ai role
+      expect(bubbles[1]).toHaveClass('ant-bubble-start'); // ai role (item2)
+      expect(bubbles[0]).toHaveClass('ant-bubble-start'); // user role (item1)
     });
🧹 Nitpick comments (3)
packages/x/components/bubble/hooks/useCompatibleScroll.ts (2)

107-108: handleScroll 依赖数组中 scrollDom 未被使用

handleScroll 的依赖数组包含 scrollDom,但函数体内通过 e.target 获取元素,实际上并未使用 scrollDom。建议移除该依赖或添加注释说明保留原因。

♻️ 建议修改
   const handleScroll = useCallback(
     (e: Event) => {
       const target = e.target as HTMLElement;
       if (!isReverse(target)) return;
       const { scrollTop, scrollHeight } = target;
       // 倒序, top 在变化,但 bottom 固定
       lockedScrollBottomPos.current = scrollHeight + scrollTop;
       // 检测并恢复自然触发状态
       if (callOnScrollNotNative.current) {
         callOnScrollNotNative.current = false;
         return;
       }
       if (scrolling.current) {
         clearTimeout(scrolling.current);
       }
       setTimer();
     },
-    [scrollDom],
+    [setTimer],
   );

52-66: ResizeObserver 回调中 scrollDom 检查位置可优化

在 ResizeObserver 回调中,Line 53 检查 !scrollDom 后提前返回,但 Line 66 调用 enforceScrollLock() 时该函数内部使用了非空断言 scrollDom!。虽然当前逻辑上是安全的,但建议将 scrollDom 检查提前到回调开头,确保后续所有操作都在有效 DOM 上执行。

packages/x/components/bubble/BubbleList.tsx (1)

195-195: 移除注释掉的代码

Line 195 的注释代码 // const renderData = autoScroll ? [...items].reverse() : items; 应该删除。如果保留是为了记录历史实现,建议使用 git 历史而非代码注释。

♻️ 建议修改
-  // const renderData = autoScroll ? [...items].reverse() : items;
-
   // ============================ Render ============================

@github-actions
Copy link
Contributor

github-actions bot commented Jan 26, 2026

size-limit report 📦

Path Size
packages/x/dist/antdx.min.js 441.82 KB (+115 B 🔺)
packages/x-sdk/dist/x-sdk.min.js 7.88 KB
packages/x-markdown/dist/x-markdown.min.js 30.96 KB
packages/x-markdown/dist/plugins/latex.min.js 61.95 KB

@cloudflare-workers-and-pages
Copy link

cloudflare-workers-and-pages bot commented Jan 26, 2026

Deploying ant-design-x with  Cloudflare Pages  Cloudflare Pages

Latest commit: 526fd55
Status: ✅  Deploy successful!
Preview URL: https://564929f5.ant-design-x.pages.dev
Branch Preview URL: https://fix-bubblelist.ant-design-x.pages.dev

View logs

@dosubot dosubot bot added the lgtm This PR has been approved by a maintainer label Jan 26, 2026
@kimteayon kimteayon merged commit d17c173 into main Jan 26, 2026
16 checks passed
@kimteayon kimteayon deleted the fix/bubblelist branch January 26, 2026 09:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working lgtm This PR has been approved by a maintainer

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Thinking 组件在 Bubble.List 里折叠展开会影响滚动位置

3 participants