+
)
}
)
-
-TextArea.defaultProps = defaultProps
diff --git a/src/hooks/index.tsx b/src/hooks/index.tsx
index c5d141ebd0..3bcf24046c 100644
--- a/src/hooks/index.tsx
+++ b/src/hooks/index.tsx
@@ -1,6 +1,9 @@
export { useFieldNames } from './useFieldNames'
export type { FieldNamesType } from './useFieldNames'
+export { useClearable } from './useClearable'
+export type { ClearableConfig } from './useClearable'
+
export type BaseOptionType = {
[key: string]: any
}
diff --git a/src/hooks/useClearable.tsx b/src/hooks/useClearable.tsx
new file mode 100644
index 0000000000..6e4f53deb8
--- /dev/null
+++ b/src/hooks/useClearable.tsx
@@ -0,0 +1,64 @@
+import { CloseCircleFill } from 'antd-mobile-icons'
+import type { ReactNode } from 'react'
+import React from 'react'
+
+export interface ClearableConfig {
+ onClear?: () => void
+ clearIcon?: ReactNode
+}
+
+export interface UseClearableProps {
+ /** Boolean as toggle, object for detailed config (custom icon / callback) */
+ clearable?: boolean | ClearableConfig
+ /** Fallback onClear when clearable is boolean (for flat-props pattern like Input) */
+ onClear?: () => void
+ /** Fallback clearIcon when clearable is boolean (for flat-props pattern like Input) */
+ clearIcon?: ReactNode
+ value: string
+ hasFocus: boolean
+ readOnly?: boolean
+ disabled?: boolean
+ /** Icon from ConfigProvider, lower priority than clearable config / clearIcon prop */
+ defaultClearIcon?: ReactNode
+ /** Whether to only show clear button when focused */
+ onlyShowClearWhenFocus?: boolean
+}
+
+export function useClearable(props: UseClearableProps) {
+ const {
+ clearable,
+ value,
+ hasFocus,
+ readOnly = false,
+ disabled = false,
+ onlyShowClearWhenFocus,
+ } = props
+
+ // Normalize clearable: falsy → off, true → empty config, object → use as-is
+ const config: ClearableConfig | null = (() => {
+ if (!clearable) return null
+ if (clearable === true) return {}
+ return clearable
+ })()
+
+ // Clearable is disabled when readOnly or disabled
+ const isClearable = !!config && !readOnly && !disabled
+
+ // Show clear button only when: clearable enabled + has value + focus condition met.
+ // By default hasFocus is required; only skip focus check when onlyShowClearWhenFocus is explicitly false.
+ const shouldShowClear = (() => {
+ if (!isClearable || !value) return false
+ if (onlyShowClearWhenFocus === false) return true
+ return hasFocus
+ })()
+
+ // clearIcon priority: config.clearIcon > props.clearIcon > props.defaultClearIcon > built-in default
+ const clearIcon = config?.clearIcon ??
+ props.clearIcon ??
+ props.defaultClearIcon ??
+
+ // onClear priority: config.onClear > props.onClear
+ const onClear = config?.onClear ?? props.onClear
+
+ return { isClearable, shouldShowClear, clearIcon, onClear }
+}
diff --git a/src/locales/ar-SA.ts b/src/locales/ar-SA.ts
index e3f3724fbb..d865a2995f 100644
--- a/src/locales/ar-SA.ts
+++ b/src/locales/ar-SA.ts
@@ -111,6 +111,7 @@ const arSA = mergeLocale(base, {
'Stepper': { 'decrease': 'يقلل', 'increase': 'يزيد' },
'Switch': { 'name': 'زر الفتح والإغلاق' },
'Selector': { 'name': 'اختر مجموعة' },
+ 'TextArea': { 'clear': 'إزالة' },
})
export default arSA
diff --git a/src/locales/base.ts b/src/locales/base.ts
index c74bd83ffa..e17b967191 100644
--- a/src/locales/base.ts
+++ b/src/locales/base.ts
@@ -141,6 +141,9 @@ export const base = {
Selector: {
name: 'Selector',
},
+ TextArea: {
+ clear: 'clear',
+ },
}
export type Locale = typeof base
diff --git a/src/locales/cnr-ME.ts b/src/locales/cnr-ME.ts
index 0b8372b2ea..4165420049 100644
--- a/src/locales/cnr-ME.ts
+++ b/src/locales/cnr-ME.ts
@@ -144,6 +144,9 @@ const cnrME = mergeLocale(base, {
Selector: {
name: 'Selektor',
},
+ TextArea: {
+ clear: 'očisti',
+ },
})
export default cnrME
diff --git a/src/locales/da-DK.ts b/src/locales/da-DK.ts
index 4ded438139..e26b0e1168 100644
--- a/src/locales/da-DK.ts
+++ b/src/locales/da-DK.ts
@@ -126,6 +126,9 @@ const daDK = mergeLocale(base, {
Selector: {
name: 'Vælger',
},
+ TextArea: {
+ clear: 'ryd',
+ },
})
export default daDK
diff --git a/src/locales/de-DE.ts b/src/locales/de-DE.ts
index dd8e5bfa21..3685cf5a4d 100644
--- a/src/locales/de-DE.ts
+++ b/src/locales/de-DE.ts
@@ -116,6 +116,7 @@ const deDE = mergeLocale(base, {
'Stepper': { 'decrease': 'Reduzieren', 'increase': 'Erhöhen' },
'Switch': { 'name': 'Schalter' },
'Selector': { 'name': 'Gruppe auswählen' },
+ 'TextArea': { 'clear': 'Löschen' },
})
export default deDE
diff --git a/src/locales/es-ES.ts b/src/locales/es-ES.ts
index 79547406f1..3fa3c79166 100644
--- a/src/locales/es-ES.ts
+++ b/src/locales/es-ES.ts
@@ -92,6 +92,9 @@ const esES = mergeLocale(base, {
ImageUploader: {
uploading: 'Subiendo...',
},
+ Input: {
+ clear: 'Borrar',
+ },
Mask: {
name: 'Máscara',
},
@@ -106,6 +109,9 @@ const esES = mergeLocale(base, {
canRelease: 'Suelte para refrescar inmediatamente',
complete: 'Refrescó exitosamente',
},
+ TextArea: {
+ clear: 'Borrar',
+ },
})
export default esES
diff --git a/src/locales/fa-IR.ts b/src/locales/fa-IR.ts
index f3b749bcd0..ddcaedd516 100644
--- a/src/locales/fa-IR.ts
+++ b/src/locales/fa-IR.ts
@@ -108,6 +108,9 @@ const faIR = mergeLocale(base, {
NumberKeyboard: {
backspace: 'حذف',
},
+ TextArea: {
+ clear: 'پاک کردن',
+ },
})
export default faIR
diff --git a/src/locales/fr-FR.ts b/src/locales/fr-FR.ts
index eb472d006c..2fb28fadb2 100644
--- a/src/locales/fr-FR.ts
+++ b/src/locales/fr-FR.ts
@@ -96,6 +96,9 @@ const frFR = mergeLocale(base, {
InfiniteScroll: {
noMore: 'Non, plus maintenant.',
},
+ Input: {
+ clear: 'Effacer',
+ },
Mask: {
name: 'Masques',
},
@@ -110,6 +113,9 @@ const frFR = mergeLocale(base, {
canRelease: 'Libérez instantanément rafraîchir',
complete: 'Rafraîchir avec succès',
},
+ TextArea: {
+ clear: 'Effacer',
+ },
})
export default frFR
diff --git a/src/locales/hr-HR.ts b/src/locales/hr-HR.ts
index a1200a59f8..35120d1589 100644
--- a/src/locales/hr-HR.ts
+++ b/src/locales/hr-HR.ts
@@ -144,6 +144,9 @@ const hrHR = mergeLocale(base, {
Selector: {
name: 'Selektor',
},
+ TextArea: {
+ clear: 'očisti',
+ },
})
export default hrHR
diff --git a/src/locales/hu-HU.ts b/src/locales/hu-HU.ts
index 2fe3056fc6..f880ab3983 100644
--- a/src/locales/hu-HU.ts
+++ b/src/locales/hu-HU.ts
@@ -141,6 +141,9 @@ export const huHU = mergeLocale(base, {
Selector: {
name: 'Kiválasztás',
},
+ TextArea: {
+ clear: 'törlés',
+ },
})
export default huHU
diff --git a/src/locales/id-ID.ts b/src/locales/id-ID.ts
index 5999d4b7e4..4fd558ab01 100644
--- a/src/locales/id-ID.ts
+++ b/src/locales/id-ID.ts
@@ -125,6 +125,9 @@ const idID = mergeLocale(base, {
Switch: {
name: 'Mengalihkan',
},
+ TextArea: {
+ clear: 'Hapus',
+ },
})
export default idID
diff --git a/src/locales/in-ID.ts b/src/locales/in-ID.ts
index ae6b32134d..fd777eb149 100644
--- a/src/locales/in-ID.ts
+++ b/src/locales/in-ID.ts
@@ -114,6 +114,7 @@ const inID = mergeLocale(base, {
Stepper: { decrease: 'mengurangi', increase: 'meningkat' },
Switch: { name: 'Mengalihkan' },
Selector: { name: 'Grup pilih' },
+ TextArea: { clear: 'Hapus' },
})
export default inID
diff --git a/src/locales/it-IT.ts b/src/locales/it-IT.ts
index 092fc8096d..d40ab79500 100644
--- a/src/locales/it-IT.ts
+++ b/src/locales/it-IT.ts
@@ -138,6 +138,9 @@ const itIT = mergeLocale(base, {
Selector: {
name: 'Selettore',
},
+ TextArea: {
+ clear: 'cancella',
+ },
})
export default itIT
diff --git a/src/locales/ja-JP.ts b/src/locales/ja-JP.ts
index 7975bb55bd..95e155c3f8 100644
--- a/src/locales/ja-JP.ts
+++ b/src/locales/ja-JP.ts
@@ -131,6 +131,9 @@ const jaJP = mergeLocale(base, {
Switch: {
name: 'スイッチ',
},
+ TextArea: {
+ clear: 'クリア',
+ },
})
export default jaJP
diff --git a/src/locales/kk-KZ.ts b/src/locales/kk-KZ.ts
index 938bd32f31..a4b6aa0144 100644
--- a/src/locales/kk-KZ.ts
+++ b/src/locales/kk-KZ.ts
@@ -115,6 +115,9 @@ const kkKZ = mergeLocale(base, {
Switch: {
name: 'Сөндіргіш',
},
+ TextArea: {
+ clear: 'тазарту',
+ },
})
export default kkKZ
diff --git a/src/locales/ko-KR.ts b/src/locales/ko-KR.ts
index a46b48eb5e..0bf33b12c3 100644
--- a/src/locales/ko-KR.ts
+++ b/src/locales/ko-KR.ts
@@ -135,6 +135,9 @@ const koKR = mergeLocale(base, {
Switch: {
name: '스위치',
},
+ TextArea: {
+ clear: '지우기',
+ },
})
export default koKR
diff --git a/src/locales/ms-MY.ts b/src/locales/ms-MY.ts
index aa77e4ff74..15ac3f53e2 100644
--- a/src/locales/ms-MY.ts
+++ b/src/locales/ms-MY.ts
@@ -117,6 +117,7 @@ const msMY = mergeLocale(base, {
'Stepper': { 'decrease': 'Menurun', 'increase': 'Meningkat' },
'Switch': { 'name': 'Suis' },
'Selector': { 'name': 'Pilih kumpulan' },
+ 'TextArea': { 'clear': 'Padam' },
})
export default msMY
diff --git a/src/locales/nb-NO.ts b/src/locales/nb-NO.ts
index 1a067d3105..b72ebca92c 100644
--- a/src/locales/nb-NO.ts
+++ b/src/locales/nb-NO.ts
@@ -138,6 +138,9 @@ const nbNO = mergeLocale(base, {
Selector: {
name: 'Velger',
},
+ TextArea: {
+ clear: 'fjern',
+ },
})
export default nbNO
diff --git a/src/locales/nl-NL.ts b/src/locales/nl-NL.ts
index 7cf1a1325f..1b9d5ef333 100644
--- a/src/locales/nl-NL.ts
+++ b/src/locales/nl-NL.ts
@@ -138,6 +138,9 @@ const nlNL = mergeLocale(base, {
Selector: {
name: 'Selector',
},
+ TextArea: {
+ clear: 'wissen',
+ },
})
export default nlNL
diff --git a/src/locales/pt-BR.ts b/src/locales/pt-BR.ts
index ab87b5bb53..f2646fa720 100644
--- a/src/locales/pt-BR.ts
+++ b/src/locales/pt-BR.ts
@@ -138,6 +138,9 @@ const ptBR = mergeLocale(base, {
Selector: {
name: 'Seletor',
},
+ TextArea: {
+ clear: 'limpar',
+ },
})
export default ptBR
diff --git a/src/locales/ru-RU.ts b/src/locales/ru-RU.ts
index c2e6f3e8fe..6dcae857bd 100644
--- a/src/locales/ru-RU.ts
+++ b/src/locales/ru-RU.ts
@@ -145,6 +145,9 @@ const ruRU = mergeLocale(base, {
Selector: {
name: 'Селектор',
},
+ TextArea: {
+ clear: 'очистить',
+ },
})
export default ruRU
diff --git a/src/locales/sr-RS.ts b/src/locales/sr-RS.ts
index e28f605238..e6a7d6d5e0 100644
--- a/src/locales/sr-RS.ts
+++ b/src/locales/sr-RS.ts
@@ -144,6 +144,9 @@ const srRS = mergeLocale(base, {
Selector: {
name: 'Селектор',
},
+ TextArea: {
+ clear: 'очисти',
+ },
})
export default srRS
diff --git a/src/locales/th-TH.ts b/src/locales/th-TH.ts
index e158021bcd..229f5a4789 100644
--- a/src/locales/th-TH.ts
+++ b/src/locales/th-TH.ts
@@ -152,6 +152,9 @@ const thTH = mergeLocale(base, {
Selector: {
name: 'เลือก',
},
+ TextArea: {
+ clear: 'ล้าง',
+ },
})
export default thTH
diff --git a/src/locales/tr-TR.ts b/src/locales/tr-TR.ts
index 9843bb87c8..ec90b37fa4 100644
--- a/src/locales/tr-TR.ts
+++ b/src/locales/tr-TR.ts
@@ -138,6 +138,9 @@ const trTR = mergeLocale(base, {
Selector: {
name: 'Seçici',
},
+ TextArea: {
+ clear: 'temizle',
+ },
})
export default trTR
diff --git a/src/locales/vi-VN.ts b/src/locales/vi-VN.ts
index 2fbb7b2706..2d3eb75d26 100644
--- a/src/locales/vi-VN.ts
+++ b/src/locales/vi-VN.ts
@@ -111,6 +111,7 @@ const viVN = mergeLocale(base, {
'Stepper': { 'decrease': 'Giảm', 'increase': 'Tăng' },
'Switch': { 'name': 'Bật tắt' },
'Selector': { 'name': 'Chọn nhóm' },
+ 'TextArea': { 'clear': 'Xóa' },
})
export default viVN
diff --git a/src/locales/zh-CN.ts b/src/locales/zh-CN.ts
index c259f573bb..f1e48984d2 100644
--- a/src/locales/zh-CN.ts
+++ b/src/locales/zh-CN.ts
@@ -143,6 +143,9 @@ const zhCN: Locale = {
Selector: {
name: '选择组',
},
+ TextArea: {
+ clear: '清除',
+ },
}
export default zhCN
diff --git a/src/locales/zh-HK.ts b/src/locales/zh-HK.ts
index 7c8f985ab8..1ca236b3da 100644
--- a/src/locales/zh-HK.ts
+++ b/src/locales/zh-HK.ts
@@ -96,6 +96,9 @@ const zhHK = mergeLocale(base, {
InfiniteScroll: {
noMore: '沒有更多了',
},
+ Input: {
+ clear: '清除',
+ },
Mask: {
name: '遮罩層',
},
@@ -110,6 +113,9 @@ const zhHK = mergeLocale(base, {
canRelease: '釋放立即刷新',
complete: '刷新成功',
},
+ TextArea: {
+ clear: '清除',
+ },
})
export default zhHK
diff --git a/src/locales/zh-TW.ts b/src/locales/zh-TW.ts
index e86d8d72d8..89d1028af4 100644
--- a/src/locales/zh-TW.ts
+++ b/src/locales/zh-TW.ts
@@ -96,6 +96,9 @@ const zhTW = mergeLocale(base, {
InfiniteScroll: {
noMore: '沒有更多了',
},
+ Input: {
+ clear: '清除',
+ },
Mask: {
name: '遮罩層',
},
@@ -110,6 +113,9 @@ const zhTW = mergeLocale(base, {
canRelease: '釋放立即刷新',
complete: '刷新成功',
},
+ TextArea: {
+ clear: '清除',
+ },
})
export default zhTW