Skip to content

feat(TextArea): add clearable functionality to TextArea component (#7021)#7022

Open
viko16 wants to merge 13 commits into
ant-design:masterfrom
viko16:feature/textarea-clearable
Open

feat(TextArea): add clearable functionality to TextArea component (#7021)#7022
viko16 wants to merge 13 commits into
ant-design:masterfrom
viko16:feature/textarea-clearable

Conversation

@viko16
Copy link
Copy Markdown

@viko16 viko16 commented Jan 19, 2026

TextArea 支持 clearable

功能描述

截图

image

视觉层级

┌─ adm-text-area ─────────────────────────────────┐
│  ┌──────────────────────────────────────────┐   │
│  │  • <textarea>              ┌─ clear ─┐   │   │
│  │  • <textarea hidden>       │   ✕     │   │   │
│  │                            └─────────┘   │   │
│  └──────────────────────────────────────────┘   │
│  ┌─ count ──────────────────────────────────┐   │
│  │  3/100                                   │   │
│  └──────────────────────────────────────────┘   │
└─────────────────────────────────────────────────┘

HTML 结构

.adm-text-area
  textarea
  .adm-text-area-count
  textarea[hidden]
  .adm-text-area-clear

Summary by CodeRabbit

  • 新功能

    • 为文本区域添加清空按钮,支持 clearable、可自定义图标及 onClear 回调,并在示例中新增清空与自适应高度演示
  • 文档

    • 新增 clearable、clearIcon、onClear 说明;更新原生属性支持列表(含 onKeyDown、enterKeyHint)及常见问答
  • 样式

    • 增加清空按钮与相关布局样式
  • 本地化

    • 为 25+ 种语言添加文本区域“清除”翻译
  • 测试

    • 增加清空行为、iOS 组合输入、回调与自定义图标测试覆盖

- Introduced `clearable` prop to enable a clear icon for the TextArea.
- Added `clearIcon` prop for custom clear icon support.
- Implemented `onClear` callback to handle clear button actions.
- Updated documentation in English and Chinese to reflect new props.
- Enhanced styles for the clear button in the TextArea component.
- Added tests to verify clear button functionality and integration with composition events.
@dosubot dosubot Bot added the size:L This PR changes 100-499 lines, ignoring generated files. label Jan 19, 2026
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Jan 19, 2026

Prepare preview

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Jan 19, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

新增 TextArea 清空功能:添加 clearable/clearIcon/onClear 属性,支持从 ConfigProvider 合并全局 clearIcon,新增样式、示例、测试与多语言文案 TextArea.clear,调整渲染结构与聚焦/组合态行为。

Changes

Cohort / File(s) Summary
组件实现
src/components/text-area/text-area.tsx
新增 clearableclearIcononClear props;读取 useConfig 中的 textArea.clearIcon;增加清空按钮渲染与交互逻辑,含 iOS composition/blur 修复与焦点状态。
样式
src/components/text-area/text-area.less
新增容器 wrapper 与 .adm-text-area-clear 样式,使用 flex 布局以容纳清空控件与可见性控制。
配置提供器
src/components/config-provider/config-provider.tsx
扩展导出 Config 类型,新增可选 textArea?: { clearIcon?: ReactNode } 字段以支持全局清空图标配置。
示例
src/components/text-area/demos/demo1.tsx
调整 import 顺序并新增两个示例块,展示带清空按钮与 autoSize+清空按钮的用法。
文档
src/components/text-area/index.en.md, src/components/text-area/index.zh.md
为 TextArea 文档新增 clearableclearIcononClear 描述,补充原生属性(如 onKeyDownenterKeyHint)与 FAQ 说明。
测试
src/components/text-area/tests/text-area.test.tsx
新增大量测试覆盖清空按钮显示/隐藏、iOS composition 与焦点处理、onClear 调用、clearIcon 优先级(默认/prop/ConfigProvider)以及 disabled/readOnly 行为。
国际化
src/locales/...
(例:src/locales/base.ts, src/locales/zh-CN.ts, src/locales/fr-FR.ts, src/locales/es-ES.ts, 等)
为多个语言包新增 TextArea.clear 翻译(部分语言同时新增/同步 Input.clear)。

Sequence Diagram(s)

sequenceDiagram
    participant User as User
    participant TextArea as TextArea
    participant ConfigProvider as ConfigProvider
    participant Locale as Locale
    User->>TextArea: 输入文本 / 点击清空按钮
    TextArea->>ConfigProvider: 请求 textArea.clearIcon(若存在)
    TextArea->>Locale: 获取 TextArea.clear 文案(无障碍标签)
    TextArea->>TextArea: 清空 value,调用 onClear(若存在),更新聚焦/组合态
    alt iOS composition 活跃
        TextArea->>TextArea: 处理 composition 并执行 blur/focus 修复
    end
    TextArea->>User: 更新 UI(清空文本、更新控件可见性)
Loading

Estimated code review effort

🎯 3 (中等) | ⏱️ ~25 minutes

诗句

我是兔子来报新,清空一按心轻盈,
图标可配全局传,示例样式与测例行,
小按一触界面净,欢跳继续去吃青 🐰

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed PR标题清晰准确地总结了主要变更:为TextArea组件添加clearable功能。
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

@gemini-code-assist
Copy link
Copy Markdown
Contributor

Summary of Changes

Hello @viko16, 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!

此拉取请求为 TextArea 组件引入了清除功能,极大地提升了用户体验,允许用户快速清空文本输入。通过新增的 clearable 属性、可自定义的 clearIcon 以及 onClear 回调,开发者可以灵活地控制和响应清除操作。同时,还完善了多语言支持和组件样式,确保了功能在不同语言环境下的可用性和良好的视觉表现。

Highlights

  • 新增 clearable 功能: TextArea 组件现在支持 clearable 属性,允许用户点击清除按钮一键清空输入内容。
  • 自定义清除图标: 引入了 clearIcon 属性,支持自定义清除按钮的图标,并且可以通过 ConfigProvider 进行全局配置。
  • 新增 onClear 回调: 在点击清除按钮后,会触发 onClear 回调函数,方便开发者处理清空后的逻辑。
  • 多语言支持与文档更新: 为 TextArea 的清除功能添加了多语言翻译,并更新了中英文文档,详细说明了新属性和用法。同时,修正了部分 Input 组件遗漏的翻译。
  • 样式与测试覆盖: 更新了 TextArea 的样式以支持清除按钮的布局和视觉效果,并增加了全面的单元测试,确保新功能的稳定性和兼容性。

🧠 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.

@dosubot dosubot Bot added the feature label Jan 19, 2026
Copy link
Copy Markdown
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

你好,感谢你的贡献。这次 PR 为 TextArea 组件成功添加了 clearable 功能,与 Input 组件的行为保持了一致,做得很好。实现方面考虑得很周全,包括对 props、全局配置、样式、可访问性和国际化的支持。测试用例也比较完整。我有一个关于如何改进测试结构以覆盖更多场景的建议,请查看下面的具体评论。

Comment thread src/components/text-area/tests/text-area.test.tsx Outdated
Copy link
Copy Markdown

@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: 2

🤖 Fix all issues with AI agents
In `@src/locales/ar-SA.ts`:
- Line 114: The translations for TextArea.clear and Input.clear are
inconsistent: TextArea.clear currently uses 'مسح' while Input.clear uses
'إزالة'; update the TextArea.clear entry to use the same Arabic term as
Input.clear (use 'إزالة') so both TextArea.clear and Input.clear are identical
and the user experience is consistent.

In `@src/locales/hr-HR.ts`:
- Around line 147-149: TextArea.clear currently uses the Croatian word 'obriši'
while Input.clear uses 'očisti', causing inconsistent wording; update
TextArea.clear to use the same translation as Input.clear (i.e., replace the
value for TextArea.clear to match Input.clear) so both keys (TextArea.clear and
Input.clear) are consistent across the locale file.
🧹 Nitpick comments (4)
src/components/text-area/text-area.less (1)

81-93: 可选:为清除按钮补充键盘可见焦点
若该元素可聚焦,建议添加 :focus-visible 样式以提升键盘可访问性。

♿ 建议补充可见焦点样式
 .adm-text-area-clear {
   flex: none;
   margin-left: 8px;
   color: var(--adm-color-light);
   &:active {
     color: var(--adm-color-weak);
   }
   padding: 4px;
   cursor: pointer;
+  &:focus-visible {
+    outline: 2px solid currentColor;
+    outline-offset: 2px;
+  }
   .antd-mobile-icon {
     display: block;
     font-size: var(--adm-font-size-7);
   }
 }
src/components/text-area/tests/text-area.test.tsx (1)

6-10: 建议:增加非 iOS 场景的测试覆盖。

当前 mock 强制 isIOS() 始终返回 true,这意味着只测试了 iOS 特定的清除逻辑(composition 期间会触发 blur)。建议考虑增加非 iOS 场景的测试,验证在非 iOS 设备上点击清除按钮时不会触发 blur。

可以通过条件 mock 或在单独的 describe 块中重置 mock 来实现:

♻️ 建议的测试补充
describe('TextArea on non-iOS', () => {
  beforeAll(() => {
    jest.resetModules()
    jest.doMock('../../../utils/validate', () => ({
      isIOS: () => false,
    }))
  })

  it('should not blur on clear during composition', async () => {
    // 测试非 iOS 场景
  })
})
src/components/text-area/text-area.tsx (2)

253-253: 可选:移除冗余的 defaultProps 赋值。

由于在 Line 86 已通过 mergeProps(defaultProps, componentConfig, p) 处理了默认值合并,此处的 TextArea.defaultProps = defaultProps 是冗余的。不过保留它也不会造成问题,这只是一个小的代码整洁建议。


215-234: 为清除按钮添加 role="button"tabIndex={0} 和键盘事件处理以增强无障碍访问。

清除按钮使用 <div> 元素实现,作为一个独立的交互控件,虽然已添加 aria-label,但缺少必要的无障碍属性。建议补充:

  • role="button" 使屏幕阅读器正确识别该控件为按钮
  • tabIndex={0} 使键盘用户能够通过 Tab 键访问该按钮
  • onKeyDown 处理器支持 Enter 和空格键激活按钮
建议的改进
         <div
           className={`${classPrefix}-clear`}
+          role='button'
+          tabIndex={0}
           onMouseDown={e => {
             e.preventDefault()
           }}
           onClick={() => {
             setValue('')
             props.onClear?.()

             // https://github.com/ant-design/ant-design-mobile/issues/5212
             if (isIOS() && compositingRef.current) {
               compositingRef.current = false
               nativeTextAreaRef.current?.blur()
             }
           }}
+          onKeyDown={e => {
+            if (e.key === 'Enter' || e.key === ' ') {
+              e.preventDefault()
+              setValue('')
+              props.onClear?.()
+            }
+          }}
           aria-label={locale.TextArea.clear}
         >

建议确认 Input 组件的清除按钮是否采用相同的无障碍模式,以保持全库的一致性。

Comment thread src/locales/ar-SA.ts Outdated
Comment thread src/locales/hr-HR.ts
@pkg-pr-new
Copy link
Copy Markdown

pkg-pr-new Bot commented Jan 20, 2026

npm i https://pkg.pr.new/antd-mobile@7022

commit: d4760e3

Comment thread src/components/text-area/text-area.tsx Outdated

const compositingRef = useRef(false)

const shouldShowClear =
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Input 的设计是聚焦的时候才展示清除按钮。因为在长表单的情况下,手机不同于 PC,清除按钮会过多占据视觉区域。

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

我曾经尝试过添加 onlyShowClearWhenFocus 功能,但问题是如果清除按钮动态出现/消失的话,会导致 TextArea 宽度变化,影响 autoSize 功能。

Input 没问题是因为永远只有单行,改变输入区域宽度不影响高度。

同时也调研过淘宝、拼多多、微信的多行输入框,都是常驻。感觉我们可以在 #7021 上讨论下。

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

我的想法是可以在存在 clear 的时候提供一下边缘 padding,这样宽度就是稳定的了。因为 Input 和 TextArea 混用一个有一个没有,这个是非常古怪的。

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

但是当自定义 clearIcon 的时候,这个 padding 就不固定了

A. 按照默认 <CloseCircleFill /> 固定一个 padding,那如果自定义 clearIcon 更宽就会遮挡
B. 要求自定义 clearIcon 的时候再传入 padding 或者 CSS Var,可行但是更绕了

而且提供边缘 padding 的时候,一样空了一列,视觉上其实也蛮奇怪的
image

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

嗯,明白。这个的确是比较讨厌的点。在 Input 里不用考虑换行做的动态 padding。要不然这样,如果有动态高度的,就固定 padding,反之就是动态 padding 如何?做尽可能的保全

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

longshot20260225104727_compressed.mp4

调整成了 clearIcon 会根据 focus 显示消失,按照上面的讨论:

  • 在 autoSize 时,clearIcon 的位置会持续占据一列
  • 非 autoSize 时,clearIcon 仅在聚焦的时候出现

取了一个相对平衡的点,也在文档上补充说明了这种现象。

- Updated TextArea styles for full responsiveness in width and height.
- Refactored component structure to improve layout consistency and flexibility.
- Clear button now only displays when TextArea has focus in non-autoSize mode
- In autoSize mode, clear container space is reserved to prevent layout jitter
- Added `hasFocus` state to track focus status
- Enhanced tests for clear button focus behavior on both autoSize and non-autoSize scenarios
- Updated documentation to explain why onlyShowClearWhenFocus property is not needed
Copy link
Copy Markdown

@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: 4

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/components/text-area/index.en.md`:
- Around line 34-39: Rename the FAQ header "Why there is no
onlyShowClearWhenFocus property?" to "Why is there no onlyShowClearWhenFocus
property?" and update the non-autoSize description to explicitly mention the
"value is non-empty" condition (i.e., in non-autoSize scenario the clear icon
only shows when focused and the value is non-empty) while keeping the autoSize
explanation about reserving space for the clear icon to avoid width/height
jitter; reference the "onlyShowClearWhenFocus" property and "autoSize" behavior
in the updated text.

In `@src/components/text-area/index.zh.md`:
- Around line 38-39: The doc lines describing clear-icon behavior are missing
the "有内容时" condition and should match the implementation: update the two bullets
(for non-autoSize and autoSize) in the TextArea docs so the non-autoSize bullet
reads that the clear icon only appears when 聚焦且有内容 (focused and has value), and
the autoSize bullet notes it always reserves space when 有内容 to avoid
width/height flicker; reference the TextArea component and the autoSize behavior
to ensure wording aligns with the actual show/visibility logic.

In `@src/components/text-area/text-area.less`:
- Around line 96-100: 在样式中 &:active 选择器块后直接跟着 padding 和 cursor 会触发 stylelint 的
declaration-empty-line-before 规则;在 text-area.less 中找到 &:active
块并在其结束后与后续声明(padding 和 cursor)之间插入一个空行,确保在 &:active { ... } 和 padding: 4px;
之间有空行以通过 linter(或调整相应声明使其在同一规则块内,如果更合适)。

In `@src/components/text-area/text-area.tsx`:
- Around line 240-259: Replace the non-semantic clear control div with a
semantic, keyboard-accessible button (e.g., <button type="button">) while
preserving behavior: keep className construction using classPrefix and
shouldShowClear, keep aria-hidden={!shouldShowClear} and
aria-label={locale.TextArea.clear}, retain the onMouseDown preventDefault logic
and the onClick handler that calls setValue(''), props.onClear?.(), and the iOS
compositing logic using compositingRef and nativeTextAreaRef; ensure the element
remains type="button" so it does not submit forms and that props.clearIcon is
rendered inside the button.

ℹ️ Review info

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 5f25903 and 413944a.

⛔ Files ignored due to path filters (1)
  • src/components/text-area/tests/__snapshots__/text-area.test.tsx.snap is excluded by !**/*.snap
📒 Files selected for processing (5)
  • src/components/text-area/index.en.md
  • src/components/text-area/index.zh.md
  • src/components/text-area/tests/text-area.test.tsx
  • src/components/text-area/text-area.less
  • src/components/text-area/text-area.tsx

Comment thread src/components/text-area/index.en.md Outdated
Comment thread src/components/text-area/index.zh.md Outdated
Comment thread src/components/text-area/text-area.less
Comment thread src/components/text-area/text-area.tsx Outdated
Comment on lines +240 to +259
<div
className={`${classPrefix}-clear ${!shouldShowClear ? `${classPrefix}-clear-hidden` : ''}`}
aria-hidden={!shouldShowClear}
onMouseDown={e => {
e.preventDefault()
}}
onClick={() => {
setValue('')
props.onClear?.()

{autoSize && (
<textarea
ref={hiddenTextAreaRef}
className={`${classPrefix}-element ${classPrefix}-element-hidden`}
value={value}
rows={rows}
aria-hidden
readOnly
/>
)}
// https://github.com/ant-design/ant-design-mobile/issues/5212
if (isIOS() && compositingRef.current) {
compositingRef.current = false
nativeTextAreaRef.current?.blur()
}
}}
aria-label={locale.TextArea.clear}
>
{props.clearIcon}
</div>
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# 查找 clear 控件的实现代码
rg -n "className=\`\${classPrefix}-clear" src/components/text-area/text-area.tsx -A 15 -B 2

Repository: ant-design/ant-design-mobile

Length of output: 198


🏁 Script executed:

#!/bin/bash
# 查找键盘事件处理和 aria 相关实现
rg -n "onKeyDown|onKeyPress|onKeyUp|role=.*button|tabIndex" src/components/text-area/text-area.tsx

Repository: ant-design/ant-design-mobile

Length of output: 172


🏁 Script executed:

#!/bin/bash
# 检查测试文件中是否有键盘相关的测试
rg -n "clear.*key|keyboard|Enter|Space|keyDown" src/components/text-area/tests/text-area.test.tsx -C 2

Repository: ant-design/ant-design-mobile

Length of output: 900


🏁 Script executed:

#!/bin/bash
# 查看测试文件的结构和是否有 clear 相关测试
fd "text-area.test" src/components/text-area/ && cat src/components/text-area/text-area.test.tsx | head -100

Repository: ant-design/ant-design-mobile

Length of output: 283


🏁 Script executed:

#!/bin/bash
# 查看文本框组件的完整 clear 控件代码
sed -n '230,270p' src/components/text-area/text-area.tsx

Repository: ant-design/ant-design-mobile

Length of output: 1213


🏁 Script executed:

#!/bin/bash
# 查看整个 text-area.tsx 文件的大小和内容片段
wc -l src/components/text-area/text-area.tsx
sed -n '235,265p' src/components/text-area/text-area.tsx

Repository: ant-design/ant-design-mobile

Length of output: 1045


🏁 Script executed:

#!/bin/bash
# 搜索 clear 相关的代码和事件处理
rg -n "shouldShowClear" src/components/text-area/text-area.tsx -B 3 -A 10

Repository: ant-design/ant-design-mobile

Length of output: 1195


🏁 Script executed:

#!/bin/bash
# 查看测试文件中是否有 clear 控件的键盘可访问性测试
rg -n "clear" src/components/text-area/tests/text-area.test.tsx -C 3

Repository: ant-design/ant-design-mobile

Length of output: 7324


将清除控件改为语义化按钮以支持键盘访问。

当前使用 div + onClick 无法通过键盘激活,仅有 aria-label 无法弥补交互语义缺失。改为 <button type="button"> 使其具备键盘可达性、正确的语义角色和屏幕阅读器支持。

建议修改
           {(shouldShowClear || reserveClearSpace) && (
-            <div
+            <button
+              type="button"
               className={`${classPrefix}-clear ${!shouldShowClear ? `${classPrefix}-clear-hidden` : ''}`}
               aria-hidden={!shouldShowClear}
               onMouseDown={e => {
                 e.preventDefault()
               }}
               onClick={() => {
                 setValue('')
                 props.onClear?.()

                 // https://github.com/ant-design/ant-design-mobile/issues/5212
                 if (isIOS() && compositingRef.current) {
                   compositingRef.current = false
                   nativeTextAreaRef.current?.blur()
                 }
               }}
               aria-label={locale.TextArea.clear}
             >
               {props.clearIcon}
-            </div>
+            </button>
           )}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
<div
className={`${classPrefix}-clear ${!shouldShowClear ? `${classPrefix}-clear-hidden` : ''}`}
aria-hidden={!shouldShowClear}
onMouseDown={e => {
e.preventDefault()
}}
onClick={() => {
setValue('')
props.onClear?.()
{autoSize && (
<textarea
ref={hiddenTextAreaRef}
className={`${classPrefix}-element ${classPrefix}-element-hidden`}
value={value}
rows={rows}
aria-hidden
readOnly
/>
)}
// https://github.com/ant-design/ant-design-mobile/issues/5212
if (isIOS() && compositingRef.current) {
compositingRef.current = false
nativeTextAreaRef.current?.blur()
}
}}
aria-label={locale.TextArea.clear}
>
{props.clearIcon}
</div>
<button
type="button"
className={`${classPrefix}-clear ${!shouldShowClear ? `${classPrefix}-clear-hidden` : ''}`}
aria-hidden={!shouldShowClear}
onMouseDown={e => {
e.preventDefault()
}}
onClick={() => {
setValue('')
props.onClear?.()
// https://github.com/ant-design/ant-design-mobile/issues/5212
if (isIOS() && compositingRef.current) {
compositingRef.current = false
nativeTextAreaRef.current?.blur()
}
}}
aria-label={locale.TextArea.clear}
>
{props.clearIcon}
</button>
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/components/text-area/text-area.tsx` around lines 240 - 259, Replace the
non-semantic clear control div with a semantic, keyboard-accessible button
(e.g., <button type="button">) while preserving behavior: keep className
construction using classPrefix and shouldShowClear, keep
aria-hidden={!shouldShowClear} and aria-label={locale.TextArea.clear}, retain
the onMouseDown preventDefault logic and the onClick handler that calls
setValue(''), props.onClear?.(), and the iOS compositing logic using
compositingRef and nativeTextAreaRef; ensure the element remains type="button"
so it does not submit forms and that props.clearIcon is rendered inside the
button.

@AglaiaWang
Copy link
Copy Markdown
Contributor

AglaiaWang commented Feb 25, 2026 via email

- Replace separate clearIcon/onClear props with clearable: boolean | TextAreaClearableConfig
- Add IIFE to resolve clearable config with priority: prop config > ConfigProvider > default
- Update tests to use clearable object form for onClear and clearIcon cases
- Update zh/en docs with TextAreaClearableConfig sub-table
- Add demo for clearable object config with custom icon and callback

Made-with: Cursor
@dosubot dosubot Bot added size:XL This PR changes 500-999 lines, ignoring generated files. and removed size:L This PR changes 100-499 lines, ignoring generated files. labels Mar 20, 2026
Comment thread src/components/text-area/text-area.tsx Outdated
})

// Resolve clearable: boolean acts as toggle, object acts as detailed config
const clearableConfig = (() => {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

抽个 hooks 出来,未来方便复用~

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

已更新,目前放在了 src/hooks 下,整体往通用的方向拆了。
目前暂时只用在了 textarea ,如果 input 和 virtual-input 也要支持,我感觉可以再拉一个新 PR 来做🤔。

viko16 added 2 commits March 24, 2026 20:51
- Add src/hooks/useClearable.tsx with generic ClearableConfig interface and useClearable hook
- Support both object-style (TextArea) and flat-props-style (Input) clearable patterns
- Implement multi-level fallback chain for clearIcon and onClear resolution
- Refactor TextArea to consume useClearable, removing inline clearableConfig logic
- Remove TextAreaClearableConfig type in favor of shared ClearableConfig
- Update docs to reference ClearableConfig instead of TextAreaClearableConfig
- Change onlyShowClearWhenFocus check from truthy to strict === false comparison
- hasFocus is now factored into shouldShowClear by default
- Only skip focus check when onlyShowClearWhenFocus is explicitly false (e.g. SearchBar)
@codecov
Copy link
Copy Markdown

codecov Bot commented Apr 7, 2026

Codecov Report

❌ Patch coverage is 96.92308% with 2 lines in your changes missing coverage. Please review.
✅ Project coverage is 93.01%. Comparing base (006e607) to head (d4760e3).
⚠️ Report is 4 commits behind head on master.

Files with missing lines Patch % Lines
src/components/text-area/text-area.tsx 95.34% 2 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master    #7022      +/-   ##
==========================================
+ Coverage   92.94%   93.01%   +0.06%     
==========================================
  Files         337      338       +1     
  Lines        7375     7417      +42     
  Branches     1879     1899      +20     
==========================================
+ Hits         6855     6899      +44     
+ Misses        512      482      -30     
- Partials        8       36      +28     

☔ 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.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Comment thread src/components/text-area/text-area.tsx Outdated
/>
{count}
<div className={`${classPrefix}-input-wrapper`}>
<div className={`${classPrefix}-textarea-wrapper`}>
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

套两层 dom 感觉有点太复杂了,在 focus 的时候直接 padding 一下。然后 clear 按钮悬浮在右侧。这样是不是就够了?

… var

- Remove input-wrapper and textarea-wrapper, flatten to single container
- Use absolute positioning for clear icon instead of flex layout
- Add --clear-icon-padding CSS variable (default 28px)
- Document --clear-icon-padding in zh and en markdown files
- Update snapshot to reflect the flattened DOM structure
@dosubot dosubot Bot added size:L This PR changes 100-499 lines, ignoring generated files. and removed size:XL This PR changes 500-999 lines, ignoring generated files. labels Apr 14, 2026
- Add test case 'clear button should preventDefault on mouseDown'
- Render TextArea with clearable and defaultValue, focus to show clear button
- Fire mouseDown on clear button and assert preventDefault was called
- Covers line 250 of text-area.tsx (onMouseDown handler)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

feature size:L This PR changes 100-499 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants