diff --git a/components/input/__docs__/demo/clear/index.tsx b/components/input/__docs__/demo/clear/index.tsx
index cb9d086e07..88112bd421 100644
--- a/components/input/__docs__/demo/clear/index.tsx
+++ b/components/input/__docs__/demo/clear/index.tsx
@@ -42,6 +42,24 @@ ReactDOM.render(
/>
+
+
+
+
+
+
,
mountNode
);
diff --git a/components/input/__docs__/index.en-us.md b/components/input/__docs__/index.en-us.md
index 718d6bb451..af55029d5b 100644
--- a/components/input/__docs__/index.en-us.md
+++ b/components/input/__docs__/index.en-us.md
@@ -16,83 +16,84 @@ Form Input, use it with Form components usually.
### Input
-| Param | Descripiton | Type | Default Value |
-| --------------- | ------------------------------------------------------------------------------------------------------------------------------------- | ------------- | --------- |
-| value | current value | String/Number | - |
-| size | Size
option:
'small'
'medium'
'large' | Enum | 'medium' |
-| defaultValue | inital value | String/Number | - |
-| onChange | callback when value changes
**signature**:
Function(value: String, e: Event) => void
**params**:
_value_: {String} data
_e_: {Event} DOM Event Object | Function | func.noop |
-| onKeyDown | callback when on key down
**signature**:
Function(e: Event, opts: Object) => void
**params**:
_e_: {Event} DOM Event Object
_opts_: {Object} extended information:
- opts.overMaxLength: {Boolean} input has reached max length
- opts.beTrimed: {Boolean} input whitespace has been trimed | Function | func.noop |
-| disabled | disabled state | Boolean | false |
-| maxLength | max length | Number | null |
-| showLimitHint | limit max num of characters | Boolean | false |
-| cutString | when maxLength is set, auto cut string | Boolean | true |
-| readOnly | read only, forbid editing | Boolean | false |
-| trim | onChange will auto trim text | Boolean | false |
-| placeholder | place holder | String | - |
-| onFocus | callback when input get focused
**signature**:
Function(e: Event) => void
**params**:
_e_: {Event} DOM Event Object | Function | func.noop |
-| onBlur | callback when input lose focused
**signature**:
Function(e: Event) => void
**params**:
_e_: {Event} DOM Event Object | Function | func.noop |
-| getValueLength | define the value length caculation
**signature**:
Function(value: String) => Number
**params**:
_value_: {String} Data
returns:
{Number} caculated length
| Function | func.noop |
-| htmlType | html input type | String | - |
-| state | state
option:
'error'
'loading'
'success' | Enum | - |
-| label | label | ReactNode | - |
-| hasClear | clear button displays or not | Boolean | - |
-| hasBorder | input border displays or not | Boolean | true |
-| onKeyDown | callback when keyboard press down
**signature**:
Function() => void | Function | func.noop |
-| onPressEnter | callback when the enter key press down
**signature**:
Function() => void | Function | func.noop |
-| hint | watermark, a type of Icon, share a place with hasClear | String | - |
-| innerBefore | Elements appended before text | ReactNode | - |
-| innerAfter | Elements appended after text | ReactNode | - |
-| addonBefore | Elements appended before input | ReactNode | - |
-| addonAfter | Elements appended after input | ReactNode | - |
-| addonTextBefore | text appended before input | ReactNode | - |
-| addonTextAfter | text appended before input | ReactNode | - |
-| autoComplete | require browser support | String | 'off' |
-| autoFocus | require browser support | Boolean | - |
-| hoverShowClear | show clear while hover (use while hasClear=true) | Boolean | false | 1.24 |
+| Param | Descripiton | Type | Default Value |
+| --------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------- | ------------- | ---- |
+| value | current value | String/Number | - |
+| size | Size
option:
'small'
'medium'
'large' | Enum | 'medium' |
+| defaultValue | inital value | String/Number | - |
+| onChange | callback when value changes
**signature**:
Function(value: String, e: Event) => void
**params**:
_value_: {String} data
_e_: {Event} DOM Event Object | Function | func.noop |
+| onKeyDown | callback when on key down
**signature**:
Function(e: Event, opts: Object) => void
**params**:
_e_: {Event} DOM Event Object
_opts_: {Object} extended information:
- opts.overMaxLength: {Boolean} input has reached max length
- opts.beTrimed: {Boolean} input whitespace has been trimed | Function | func.noop |
+| disabled | disabled state | Boolean | false |
+| maxLength | max length | Number | null |
+| showLimitHint | limit max num of characters | Boolean | false |
+| cutString | when maxLength is set, auto cut string | Boolean | true |
+| readOnly | read only, forbid editing | Boolean | false |
+| trim | onChange will auto trim text | Boolean | false |
+| placeholder | place holder | String | - |
+| onFocus | callback when input get focused
**signature**:
Function(e: Event) => void
**params**:
_e_: {Event} DOM Event Object | Function | func.noop |
+| onBlur | callback when input lose focused
**signature**:
Function(e: Event) => void
**params**:
_e_: {Event} DOM Event Object | Function | func.noop |
+| getValueLength | define the value length caculation
**signature**:
Function(value: String) => Number
**params**:
_value_: {String} Data
returns:
{Number} caculated length
| Function | func.noop |
+| htmlType | html input type | String | - |
+| state | state
option:
'error'
'loading'
'success' | Enum | - |
+| label | label | ReactNode | - |
+| hasClear | clear button displays or not | Boolean | - |
+| hasBorder | input border displays or not | Boolean | true |
+| onKeyDown | callback when keyboard press down
**signature**:
Function() => void | Function | func.noop |
+| onPressEnter | callback when the enter key press down
**signature**:
Function() => void | Function | func.noop |
+| hint | watermark, a type of Icon, share a place with hasClear | String | - |
+| innerBefore | Elements appended before text | ReactNode | - |
+| innerAfter | Elements appended after text | ReactNode | - |
+| addonBefore | Elements appended before input | ReactNode | - |
+| addonAfter | Elements appended after input | ReactNode | - |
+| addonTextBefore | text appended before input | ReactNode | - |
+| addonTextAfter | text appended before input | ReactNode | - |
+| autoComplete | require browser support | String | 'off' |
+| autoFocus | require browser support | Boolean | - |
+| hoverShowClear | show clear while hover (use while hasClear=true) | Boolean | false | 1.24 |
### Input.TextArea
-| Param | Descripiton | Type | Default Value |
-| -------------- | ------------------------------------------------------------------------------------------------------------------------------------- | -------------- | --------- |
-| value | currentValue | String/Number | - |
-| defaultValue | inital value | String/Number | - |
-| onChange | callback when value changes
**signature**:
Function(value: String, e: Event) => void
**params**:
_value_: {String} Data
_e_: {Event} DOM Event | Function | func.noop |
-| onKeyDown | callback when on key down
**signature**:
Function(e: Event, opts: Object) => void
**params**:
_e_: {Event} DOM Event Object
_opts_: {Object} extended information:
- opts.overMaxLength: {Boolean} input has reached max length
- opts.beTrimed: {Boolean} input whitespace has been trimed | Function | func.noop |
-| disabled | disabled state | Boolean | false |
-| maxLength | max length | Number | null |
-| showLimitHint | limit max num of characters | Boolean | false |
-| cutString | when maxLength is set, auto cut string | Boolean | true |
-| readOnly | read only, forbid editing | Boolean | false |
-| trim | onChange will auto trim text | Boolean | false |
-| placeholder | placeholder | String | - |
-| onFocus | callback when input get focused
**signature**:
Function() => void | Function | func.noop |
-| onBlur | callback when input lose focused
**signature**:
Function() => void | Function | func.noop |
-| getValueLength | define the value length caculation
**signature**:
Function(value: String) => Number
**params**:
_value_: {String} Data
returns:
{Number} caculated length
| Function | func.noop |
-| htmlType | html input type | String | - |
-| state | state
option:
'error'
'loading'
'success' | Enum | - |
-| autoHeight | height auto fit, exapmle: true / {minRows: 2, maxRows: 4} | Boolean/Object | false |
-| rows | multiline text height
(Never use `height` to controll textarea's height for compatibility with IE9/10) | Number | 4 |
+| Param | Descripiton | Type | Default Value |
+| -------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------------- | ------------- |
+| value | currentValue | String/Number | - |
+| defaultValue | inital value | String/Number | - |
+| onChange | callback when value changes
**signature**:
Function(value: String, e: Event) => void
**params**:
_value_: {String} Data
_e_: {Event} DOM Event | Function | func.noop |
+| onKeyDown | callback when on key down
**signature**:
Function(e: Event, opts: Object) => void
**params**:
_e_: {Event} DOM Event Object
_opts_: {Object} extended information:
- opts.overMaxLength: {Boolean} input has reached max length
- opts.beTrimed: {Boolean} input whitespace has been trimed | Function | func.noop |
+| disabled | disabled state | Boolean | false |
+| maxLength | max length | Number | null |
+| showLimitHint | limit max num of characters | Boolean | false |
+| cutString | when maxLength is set, auto cut string | Boolean | true |
+| readOnly | read only, forbid editing | Boolean | false |
+| trim | onChange will auto trim text | Boolean | false |
+| placeholder | placeholder | String | - |
+| onFocus | callback when input get focused
**signature**:
Function() => void | Function | func.noop |
+| onBlur | callback when input lose focused
**signature**:
Function() => void | Function | func.noop |
+| getValueLength | define the value length caculation
**signature**:
Function(value: String) => Number
**params**:
_value_: {String} Data
returns:
{Number} caculated length
| Function | func.noop |
+| htmlType | html input type | String | - |
+| state | state
option:
'error'
'loading'
'success' | Enum | - |
+| autoHeight | height auto fit, exapmle: true / {minRows: 2, maxRows: 4} | Boolean/Object | false |
+| rows | multiline text height
(Never use `height` to controll textarea's height for compatibility with IE9/10) | Number | 4 |
+| hasClear | clear button displays or not | Boolean | - |
### Input.Group
-| Param | Descripiton | Type | Default Value |
-| -------------------- | ----------- | --------- | --- |
-| addonBefore | Elements appended before input | ReactNode | - |
-| addonBeforeClassName | Classnames before input, usually use for css | String | - |
-| addonAfter | Elements appended after input | ReactNode | - |
-| addonAfterClassName | Classnames after input , usually use for css | String | - |
+| Param | Descripiton | Type | Default Value |
+| -------------------- | -------------------------------------------- | --------- | ------------- |
+| addonBefore | Elements appended before input | ReactNode | - |
+| addonBeforeClassName | Classnames before input, usually use for css | String | - |
+| addonAfter | Elements appended after input | ReactNode | - |
+| addonAfterClassName | Classnames after input , usually use for css | String | - |
## Input/TextArea Inner Methods(Got by refs)
-| Param | Descripiton | Type | Default Value |
-| ------------ | ------------------------------------------------------------------------------------------------------------------------ | -------- | --- |
-| getInputNode | get truely input html dom node | Function | |
-| focus | get foucs
**signature**:
Function(start:Number, end: Number)
**params**:
_start_: {Number} cursor postion
_end_: {Number} select end postion | Function | |
-
+| Param | Descripiton | Type | Default Value |
+| ------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- | ------------- |
+| getInputNode | get truely input html dom node | Function | |
+| focus | get foucs
**signature**:
Function(start:Number, end: Number)
**params**:
_start_: {Number} cursor postion
_end_: {Number} select end postion | Function | |
## ARIA and KeyBoard
-| KeyBoard | Descripiton |
-| :---------- | :------------------------------ |
-| Enter | Trigger the onKeyDown event |
-| Any | Trigger the onChange event |
+
+| KeyBoard | Descripiton |
+| :------- | :-------------------------- |
+| Enter | Trigger the onKeyDown event |
+| Any | Trigger the onChange event |
diff --git a/components/input/__docs__/index.md b/components/input/__docs__/index.md
index 303647fa85..58e4be3362 100644
--- a/components/input/__docs__/index.md
+++ b/components/input/__docs__/index.md
@@ -11,7 +11,7 @@
## 何时使用
-表单输入,一般配合 Form 使用。
+表单输入,一般配合 Form 使用。
- Input 不支持 Number 类型数字,如有需要使用 NumberPicker 支持数字选择
- `1.23` 版本新增了 API `composition` , 开启后可以在输入法结束后再触发 onChange (包括中文输入法、日语输入法等)
@@ -20,93 +20,94 @@
### Input
-| 参数 | 说明 | 类型 | 默认值 | 版本支持 |
-| --------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------- | --------- | ---- |
-| value | 当前值 | String/Number | - | |
-| size | 尺寸
**可选值**:
'small'(小)
'medium'(中)
'large'(大) | Enum | 'medium' | |
-| defaultValue | 初始化值 | String/Number | - | |
-| onChange | 发生改变的时候触发的回调
**签名**:
Function(value: String, e: Event) => void
**参数**:
_value_: {String} 数据
_e_: {Event} DOM事件对象 | Function | func.noop | |
-| onKeyDown | 键盘按下的时候触发的回调
**签名**:
Function(e: Event, opts: Object) => void
**参数**:
_e_: {Event} DOM事件对象
_opts_: {Object} 可扩展的附加信息:
- opts.overMaxLength: {Boolean} 已超出最大长度
- opts.beTrimed: {Boolean} 输入的空格被清理 | Function | func.noop | |
-| disabled | 禁用状态 | Boolean | false | |
-| maxLength | 最大长度 | Number | null | |
-| showLimitHint | 是否展现最大长度样式(旧版本为 hasLimitHint,目前仍兼容旧用法,将在2.x直接废弃) | Boolean | false | |
-| cutString | 当设置了maxLength时,是否截断超出字符串 | Boolean | true | |
-| readOnly | 只读 | Boolean | false | |
-| trim | onChange返回会自动去除头尾空字符 | Boolean | false | |
-| placeholder | 输入提示 | String | - | |
-| onFocus | 获取焦点时候触发的回调
**签名**:
Function(e: Event) => void
**参数**:
_e_: {Event} DOM事件对象 | Function | func.noop | |
-| onBlur | 失去焦点时候触发的回调
**签名**:
Function(e: Event) => void
**参数**:
_e_: {Event} DOM事件对象 | Function | func.noop | |
-| getValueLength | 自定义字符串计算长度方式
**签名**:
Function(value: String) => Number
**参数**:
_value_: {String} 数据
**返回值**:
{Number} 自定义长度
| Function | func.noop | |
-| htmlType | 原生type | String | - | |
-| name | name | String | - | |
-| state | 状态
**可选值**:
'error'(错误)
'loading'(校验中)
'success'(成功)
'warning'(警告) | Enum | - | |
-| isPreview | 是否为预览态 | Boolean | false | |
-| renderPreview | 预览态模式下渲染的内容
**签名**:
Function(value: number) => void
**参数**:
_value_: {number} 评分值 | Function | - | |
-| composition | 开启后会过滤输入法中间字母状态,文字输入完成后才会触发 onChange | Boolean | false | 1.23 |
-| label | label | ReactNode | - | |
-| hasClear | 是否出现clear按钮 | Boolean | - | |
-| hasBorder | 是否有边框 | Boolean | true | |
-| onPressEnter | 按下回车的回调
**签名**:
Function() => void | Function | func.noop | |
-| hint | 水印 (Icon的type类型,和hasClear占用一个地方) | String/ReactNode | - | |
-| innerBefore | 文字前附加内容 | ReactNode | - | |
-| innerAfter | 文字后附加内容 | ReactNode | - | |
-| addonBefore | 输入框前附加内容 | ReactNode | - | |
-| addonAfter | 输入框后附加内容 | ReactNode | - | |
-| addonTextBefore | 输入框前附加文字 | ReactNode | - | |
-| addonTextAfter | 输入框后附加文字 | ReactNode | - | |
-| autoComplete | (原生input支持) | String | 'off' | |
-| autoFocus | 自动聚焦(原生input支持) | Boolean | - | |
-| hoverShowClear | hover展示clear (配合 hasClear=true使用) | Boolean | false | 1.24 |
+| 参数 | 说明 | 类型 | 默认值 | 版本支持 |
+| --------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ---------------- | --------- | -------- |
+| value | 当前值 | String/Number | - | |
+| size | 尺寸
**可选值**:
'small'(小)
'medium'(中)
'large'(大) | Enum | 'medium' | |
+| defaultValue | 初始化值 | String/Number | - | |
+| onChange | 发生改变的时候触发的回调
**签名**:
Function(value: String, e: Event) => void
**参数**:
_value_: {String} 数据
_e_: {Event} DOM事件对象 | Function | func.noop | |
+| onKeyDown | 键盘按下的时候触发的回调
**签名**:
Function(e: Event, opts: Object) => void
**参数**:
_e_: {Event} DOM事件对象
_opts_: {Object} 可扩展的附加信息:
- opts.overMaxLength: {Boolean} 已超出最大长度
- opts.beTrimed: {Boolean} 输入的空格被清理 | Function | func.noop | |
+| disabled | 禁用状态 | Boolean | false | |
+| maxLength | 最大长度 | Number | null | |
+| showLimitHint | 是否展现最大长度样式(旧版本为 hasLimitHint,目前仍兼容旧用法,将在2.x直接废弃) | Boolean | false | |
+| cutString | 当设置了maxLength时,是否截断超出字符串 | Boolean | true | |
+| readOnly | 只读 | Boolean | false | |
+| trim | onChange返回会自动去除头尾空字符 | Boolean | false | |
+| placeholder | 输入提示 | String | - | |
+| onFocus | 获取焦点时候触发的回调
**签名**:
Function(e: Event) => void
**参数**:
_e_: {Event} DOM事件对象 | Function | func.noop | |
+| onBlur | 失去焦点时候触发的回调
**签名**:
Function(e: Event) => void
**参数**:
_e_: {Event} DOM事件对象 | Function | func.noop | |
+| getValueLength | 自定义字符串计算长度方式
**签名**:
Function(value: String) => Number
**参数**:
_value_: {String} 数据
**返回值**:
{Number} 自定义长度
| Function | func.noop | |
+| htmlType | 原生type | String | - | |
+| name | name | String | - | |
+| state | 状态
**可选值**:
'error'(错误)
'loading'(校验中)
'success'(成功)
'warning'(警告) | Enum | - | |
+| isPreview | 是否为预览态 | Boolean | false | |
+| renderPreview | 预览态模式下渲染的内容
**签名**:
Function(value: number) => void
**参数**:
_value_: {number} 评分值 | Function | - | |
+| composition | 开启后会过滤输入法中间字母状态,文字输入完成后才会触发 onChange | Boolean | false | 1.23 |
+| label | label | ReactNode | - | |
+| hasClear | 是否出现clear按钮 | Boolean | - | |
+| hasBorder | 是否有边框 | Boolean | true | |
+| onPressEnter | 按下回车的回调
**签名**:
Function() => void | Function | func.noop | |
+| hint | 水印 (Icon的type类型,和hasClear占用一个地方) | String/ReactNode | - | |
+| innerBefore | 文字前附加内容 | ReactNode | - | |
+| innerAfter | 文字后附加内容 | ReactNode | - | |
+| addonBefore | 输入框前附加内容 | ReactNode | - | |
+| addonAfter | 输入框后附加内容 | ReactNode | - | |
+| addonTextBefore | 输入框前附加文字 | ReactNode | - | |
+| addonTextAfter | 输入框后附加文字 | ReactNode | - | |
+| autoComplete | (原生input支持) | String | 'off' | |
+| autoFocus | 自动聚焦(原生input支持) | Boolean | - | |
+| hoverShowClear | hover展示clear (配合 hasClear=true使用) | Boolean | false | 1.24 |
### Input.TextArea
-| 参数 | 说明 | 类型 | 默认值 | 版本支持 |
-| -------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------- | --------- | ---- |
-| value | 当前值 | String/Number | - | |
-| size | 尺寸
**可选值**:
'small'(小)
'medium'(中)
'large'(大) | Enum | 'medium' | |
-| defaultValue | 初始化值 | String/Number | - | |
-| onChange | 发生改变的时候触发的回调
**签名**:
Function(value: String, e: Event) => void
**参数**:
_value_: {String} 数据
_e_: {Event} DOM事件对象 | Function | func.noop | |
-| onKeyDown | 键盘按下的时候触发的回调
**签名**:
Function(e: Event, opts: Object) => void
**参数**:
_e_: {Event} DOM事件对象
_opts_: {Object} 可扩展的附加信息:
- opts.overMaxLength: {Boolean} 已超出最大长度
- opts.beTrimed: {Boolean} 输入的空格被清理 | Function | func.noop | |
-| disabled | 禁用状态 | Boolean | false | |
-| maxLength | 最大长度 | Number | null | |
-| showLimitHint | 是否展现最大长度样式(旧版本为 hasLimitHint,目前仍兼容旧用法,将在2.x直接废弃) | Boolean | false | |
-| cutString | 当设置了maxLength时,是否截断超出字符串 | Boolean | true | |
-| readOnly | 只读 | Boolean | false | |
-| trim | onChange返回会自动去除头尾空字符 | Boolean | false | |
-| placeholder | 输入提示 | String | - | |
-| onFocus | 获取焦点时候触发的回调
**签名**:
Function(e: Event) => void
**参数**:
_e_: {Event} DOM事件对象 | Function | func.noop | |
-| onBlur | 失去焦点时候触发的回调
**签名**:
Function(e: Event) => void
**参数**:
_e_: {Event} DOM事件对象 | Function | func.noop | |
-| getValueLength | 自定义字符串计算长度方式
**签名**:
Function(value: String) => Number
**参数**:
_value_: {String} 数据
**返回值**:
{Number} 自定义长度
| Function | func.noop | |
-| htmlType | 原生type | String | - | |
-| name | name | String | - | |
-| state | 状态
**可选值**:
'error'(错误)
'warning' | Enum | - | |
-| isPreview | 是否为预览态 | Boolean | false | |
-| renderPreview | 预览态模式下渲染的内容
**签名**:
Function(value: number) => void
**参数**:
_value_: {number} 评分值 | Function | - | |
-| composition | 开启后会过滤输入法中间字母状态,文字输入完成后才会触发 onChange | Boolean | false | 1.23 |
-| hasBorder | 是否有边框 | Boolean | true | |
-| autoHeight | 自动高度 true / {minRows: 2, maxRows: 4} | Boolean/Object | false | |
-| rows | 多行文本框高度
(不要直接用height设置多行文本框的高度, ie9 10会有兼容性问题) | Number | 4 | |
+| 参数 | 说明 | 类型 | 默认值 | 版本支持 |
+| -------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------------- | --------- | -------- |
+| value | 当前值 | String/Number | - | |
+| size | 尺寸
**可选值**:
'small'(小)
'medium'(中)
'large'(大) | Enum | 'medium' | |
+| defaultValue | 初始化值 | String/Number | - | |
+| onChange | 发生改变的时候触发的回调
**签名**:
Function(value: String, e: Event) => void
**参数**:
_value_: {String} 数据
_e_: {Event} DOM事件对象 | Function | func.noop | |
+| onKeyDown | 键盘按下的时候触发的回调
**签名**:
Function(e: Event, opts: Object) => void
**参数**:
_e_: {Event} DOM事件对象
_opts_: {Object} 可扩展的附加信息:
- opts.overMaxLength: {Boolean} 已超出最大长度
- opts.beTrimed: {Boolean} 输入的空格被清理 | Function | func.noop | |
+| disabled | 禁用状态 | Boolean | false | |
+| maxLength | 最大长度 | Number | null | |
+| showLimitHint | 是否展现最大长度样式(旧版本为 hasLimitHint,目前仍兼容旧用法,将在2.x直接废弃) | Boolean | false | |
+| cutString | 当设置了maxLength时,是否截断超出字符串 | Boolean | true | |
+| readOnly | 只读 | Boolean | false | |
+| trim | onChange返回会自动去除头尾空字符 | Boolean | false | |
+| placeholder | 输入提示 | String | - | |
+| onFocus | 获取焦点时候触发的回调
**签名**:
Function(e: Event) => void
**参数**:
_e_: {Event} DOM事件对象 | Function | func.noop | |
+| onBlur | 失去焦点时候触发的回调
**签名**:
Function(e: Event) => void
**参数**:
_e_: {Event} DOM事件对象 | Function | func.noop | |
+| getValueLength | 自定义字符串计算长度方式
**签名**:
Function(value: String) => Number
**参数**:
_value_: {String} 数据
**返回值**:
{Number} 自定义长度
| Function | func.noop | |
+| htmlType | 原生type | String | - | |
+| name | name | String | - | |
+| state | 状态
**可选值**:
'error'(错误)
'warning' | Enum | - | |
+| isPreview | 是否为预览态 | Boolean | false | |
+| renderPreview | 预览态模式下渲染的内容
**签名**:
Function(value: number) => void
**参数**:
_value_: {number} 评分值 | Function | - | |
+| composition | 开启后会过滤输入法中间字母状态,文字输入完成后才会触发 onChange | Boolean | false | 1.23 |
+| hasBorder | 是否有边框 | Boolean | true | |
+| autoHeight | 自动高度 true / {minRows: 2, maxRows: 4} | Boolean/Object | false | |
+| rows | 多行文本框高度
(不要直接用height设置多行文本框的高度, ie9 10会有兼容性问题) | Number | 4 | |
+| hasClear | 是否出现clear按钮 | Boolean | - | |
### Input.Group
-| 参数 | 说明 | 类型 | 默认值 |
-| -------------------- | ----------- | --------- | --- |
-| addonBefore | 输入框前附加内容 | ReactNode | - |
-| addonBeforeClassName | 输入框前附加内容css | String | - |
-| addonAfter | 输入框后附加内容 | ReactNode | - |
-| addonAfterClassName | 输入框后额外css | String | - |
-| rtl | rtl | Boolean | - |
+| 参数 | 说明 | 类型 | 默认值 |
+| -------------------- | ------------------- | --------- | ------ |
+| addonBefore | 输入框前附加内容 | ReactNode | - |
+| addonBeforeClassName | 输入框前附加内容css | String | - |
+| addonAfter | 输入框后附加内容 | ReactNode | - |
+| addonAfterClassName | 输入框后额外css | String | - |
+| rtl | rtl | Boolean | - |
## Input/TextArea 内部函数(通过refs获取)
-| 参数 | 说明 | 类型 | 默认值 |
-| ------------ | ---------------------------------------------------------------------------------------------------------------------------- | -------- | --- |
-| getInputNode | 获取真正input节点 | Function | |
-| focus | 获取焦点
**签名**:
Function(start:Number, end: Number)
**参数**:
_start_: {Number} 光标起始位置
_end_: {Number} 选择结束位置 | Function | |
+| 参数 | 说明 | 类型 | 默认值 |
+| ------------ | ------------------------------------------------------------------------------------------------------------------------------------------------ | -------- | ------ |
+| getInputNode | 获取真正input节点 | Function | |
+| focus | 获取焦点
**签名**:
Function(start:Number, end: Number)
**参数**:
_start_: {Number} 光标起始位置
_end_: {Number} 选择结束位置 | Function | |
## 无障碍键盘操作指南
-| 按键 | 说明 |
-| :---- | :------------ |
+| 按键 | 说明 |
+| :---- | :---------------- |
| Enter | 触发onKeyDown事件 |
| Any | 触发onChange事件 |
diff --git a/components/input/__tests__/textarea-spec.js b/components/input/__tests__/textarea-spec.js
index 3635785399..fa15bf328a 100644
--- a/components/input/__tests__/textarea-spec.js
+++ b/components/input/__tests__/textarea-spec.js
@@ -1,4 +1,5 @@
-import React from 'react';
+import React, { useState } from 'react';
+import ReactTestUtils from 'react-dom/test-utils';
import ReactDOM from 'react-dom';
import Enzyme, { mount } from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';
@@ -7,7 +8,10 @@ import assert from 'power-assert';
import Input from '../index';
Enzyme.configure({ adapter: new Adapter() });
-
+function delay(duration) {
+ return new Promise(resolve => setTimeout(resolve, duration));
+}
+/* eslint-disable no-undef, react/jsx-filename-extension */
describe('TextArea', () => {
describe('render', () => {
let parent;
@@ -23,23 +27,55 @@ describe('TextArea', () => {
});
it('should textarea isPreview', () => {
- ReactDOM.render(, parent);
+ ReactDOM.render(
+ ,
+ parent
+ );
assert(document.querySelectorAll('#ispreview-input')[0].innerText === 'abc');
});
it('should textarea isPreview compatible value null', () => {
- ReactDOM.render(, parent);
+ ReactDOM.render(
+ ,
+ parent
+ );
assert(document.querySelectorAll('#ispreview-input-null')[0].innerText === '');
});
it('should textarea renderPreview', () => {
ReactDOM.render(
- 'ddd'} />,
+ 'ddd'}
+ />,
parent
);
assert(document.querySelectorAll('#renderpreview-input')[0].innerText === 'ddd');
});
+ it('should support hasClear ,close #4334', async () => {
+ const ref = { current: null };
+ function Demo() {
+ const [value, setValue] = useState('aaa');
+ ref.current = { value };
+ return (
+ setValue(v)}
+ />
+ );
+ }
+ mount(, { attachTo: parent });
+ await delay(100);
+ const btn = parent.querySelector('.next-input-clear');
+ ReactTestUtils.Simulate.click(btn);
+ assert(ref.current.value === '');
+ });
});
describe('behavior', () => {
@@ -48,7 +84,9 @@ describe('TextArea', () => {
const onChange = sinon.spy();
const onFocus = sinon.spy();
const onBlur = sinon.spy();
- const wrapper = mount();
+ const wrapper = mount(
+
+ );
wrapper.find('textarea').simulate('change', { target: { value: '20' } });
assert(onChange.calledOnce);
wrapper.find('textarea').simulate('focus');
@@ -125,7 +163,9 @@ describe('TextArea', () => {
});
it('should support maxLength & hasLimitHint', done => {
- const wrapper = mount();
+ const wrapper = mount(
+
+ );
assert(!wrapper.find('.next-input-len').hasClass('next-error'));
wrapper.find('textarea').simulate('change', { target: { value: '12345678901' } });
@@ -176,7 +216,9 @@ describe('TextArea', () => {
{
- assert(this.refs.textarea.getInstance().getInputNode() !== undefined);
+ assert(
+ this.refs.textarea.getInstance().getInputNode() !== undefined
+ );
}}
/>
);
@@ -191,7 +233,13 @@ describe('TextArea', () => {
it('should support getValueLength', done => {
const getValueLength = sinon.spy();
- mount();
+ mount(
+
+ );
assert(getValueLength.calledOnce);
let getValueLength2 = value => {
@@ -208,7 +256,12 @@ describe('TextArea', () => {
assert(wrapper.find('.next-input-len').text() === '1/10');
const wrapper2 = mount(
-
+
);
assert(wrapper2.find('.next-input-len').text() === '1/10');
@@ -219,15 +272,23 @@ describe('TextArea', () => {
const wrapper = mount();
// console.log(wrapper.find('textarea[data-real]').instance().clientHeight)
// let originHeight = wrapper.find('textarea[data-real]').instance().clientHeight;
- wrapper.find('textarea[data-real]').simulate('change', { target: { value: '1\n2\n3\n4\n5\n' } });
+ wrapper
+ .find('textarea[data-real]')
+ .simulate('change', { target: { value: '1\n2\n3\n4\n5\n' } });
// assert(wrapper.find('textarea[data-real]').at(0).getElement().clientHeight > originHeight);
- const wrapper2 = mount();
+ const wrapper2 = mount(
+
+ );
// console.log(wrapper2.find('textarea[data-real]').instance().clientHeight)
// let originHeight = wrapper2.find('textarea[data-real]').instance().clientHeight;
- wrapper2.find('textarea[data-real]').simulate('change', { target: { value: '1\n2\n3\n4\n5\n' } });
- wrapper2.find('textarea[data-real]').simulate('change', { target: { value: '1\n2\n3\n4' } });
+ wrapper2
+ .find('textarea[data-real]')
+ .simulate('change', { target: { value: '1\n2\n3\n4\n5\n' } });
+ wrapper2
+ .find('textarea[data-real]')
+ .simulate('change', { target: { value: '1\n2\n3\n4' } });
//
@@ -241,10 +302,7 @@ describe('TextArea', () => {
}
}
const wrapper = mount();
- wrapper
- .ref('textarea')
- .getInstance()
- .focus();
+ wrapper.ref('textarea').getInstance().focus();
wrapper.update();
// assert(wrapper.find('.next-input').hasClass('next-focus'));
diff --git a/components/input/base.jsx b/components/input/base.jsx
index f2644bb557..9695afbee5 100644
--- a/components/input/base.jsx
+++ b/components/input/base.jsx
@@ -2,11 +2,11 @@ import React from 'react';
import PropTypes from 'prop-types';
import classNames from 'classnames';
import { polyfill } from 'react-lifecycles-compat';
-
import ConfigProvider from '../config-provider';
import { func } from '../util';
import zhCN from '../locale/zh-cn';
+
class Base extends React.Component {
static propTypes = {
...ConfigProvider.propTypes,
@@ -252,18 +252,10 @@ class Base extends React.Component {
const content = rtl ? `${maxLength}/${len}` : `${len}/${maxLength}`;
- return maxLength && showLimitHint ? {content} : null;
+ return maxLength && showLimitHint ? {content} : null
}
- renderControl() {
- const lenWrap = this.renderLength();
- return lenWrap ? (
- this.focus()} className={`${this.props.prefix}input-control`}>
- {lenWrap}
-
- ) : null;
- }
getClass() {
const { disabled, state, prefix } = this.props;
diff --git a/components/input/index.d.ts b/components/input/index.d.ts
index efaea760e7..ba8fd838cd 100644
--- a/components/input/index.d.ts
+++ b/components/input/index.d.ts
@@ -133,6 +133,10 @@ export interface TextAreaProps extends HTMLAttributesWeak, CommonProps {
* 开启后会过滤输入法中间字母状态,文字输入完成后才会触发 onChange
*/
composition?: boolean;
+ /**
+ * 是否出现clear按钮
+ */
+ hasClear?: boolean;
}
export class TextArea extends React.Component {}
diff --git a/components/input/main.scss b/components/input/main.scss
index d292b14f2a..d9181b08d2 100644
--- a/components/input/main.scss
+++ b/components/input/main.scss
@@ -55,6 +55,7 @@
}
}
+
display: inline-table;
border-collapse: separate;
font-size: 0;
@@ -97,6 +98,7 @@
&.#{$css-prefix}small textarea {
font-size: $form-element-medium-font-size;
}
+
&.#{$css-prefix}large textarea {
font-size: $form-element-large-font-size;
}
@@ -107,12 +109,26 @@
border-radius: $input-multiple-corner;
}
+ #{$input-prefix}-control-textarea {
+ display: flex;
+ justify-content: end;
+ padding: 0 $input-l-icon-padding-right 4px ;
+ }
#{$input-prefix}-len {
- padding: 0 $input-l-icon-padding-right 4px;
display: block;
text-align: right;
width: auto;
}
+
+ #{$input-prefix}-clear-before {
+ &::before {
+ content: "|";
+ color:$input-disabled-border-color;
+ display: inline-block;
+ padding: 0 4px 0 2px;
+ }
+ }
+
border-radius: $input-multiple-corner;
font-size: 0;
}
@@ -126,12 +142,15 @@
z-index: 1;
position: absolute;
}
+
#{$input-prefix}-hint {
opacity: 1;
}
}
- #{$input-prefix}-clear-icon, .#{$css-prefix}icon-eye, .#{$css-prefix}icon-eye-close {
+ #{$input-prefix}-clear-icon,
+ .#{$css-prefix}icon-eye,
+ .#{$css-prefix}icon-eye-close {
&:hover {
cursor: pointer;
color: $input-hint-hover-color;
@@ -141,7 +160,7 @@
@mixin clear-icon-visible {
opacity: 1;
- + #{$input-prefix}-hint {
+ +#{$input-prefix}-hint {
opacity: 0;
}
}
@@ -150,7 +169,8 @@
opacity: 0;
}
- &:hover, &.#{$css-prefix}focus {
+ &:hover,
+ &.#{$css-prefix}focus {
border-color: $input-hover-border-color;
background-color: $input-hover-bg-color;
@@ -191,7 +211,8 @@
border-color: $input-feedback-error-border-color;
background-color: $input-feedback-error-bg-color;
- input, textarea {
+ input,
+ textarea {
color: $input-feedback-error-color;
}
@@ -232,13 +253,13 @@
}
}
- > * {
+ >* {
display: table-cell;
width: 1%;
top: 0;
}
- > *:not(:last-child) {
+ >*:not(:last-child) {
padding-right: $s-1;
}
@@ -249,23 +270,29 @@
#{$input-prefix}-warning-icon {
color: $input-feedback-warning-color;
+
&::before {
content: $input-feedback-warning-icon;
}
}
+
#{$input-prefix}-success-icon {
color: $input-feedback-success-color;
+
&::before {
content: $input-feedback-success-icon;
}
}
+
#{$input-prefix}-loading-icon {
color: $input-feedback-loading-color;
+
&::before {
content: $input-feedback-loading-icon;
animation: loadingCircle 1s infinite linear;
}
}
+
#{$input-prefix}-clear-icon {
&::before {
content: $input-feedback-clear-icon;
@@ -273,7 +300,8 @@
}
}
- &-label, &-inner-text {
+ &-label,
+ &-inner-text {
color: $input-label-color;
}
@@ -285,15 +313,18 @@
&.#{$css-prefix}disabled {
@include input-disabled();
- input, textarea {
+ input,
+ textarea {
-webkit-text-fill-color: $input-disabled-color;
color: $input-disabled-color;
@include input-placeholder($input-disabled-color);
}
- #{$input-prefix}-label, #{$input-prefix}-inner-text {
+ #{$input-prefix}-label,
+ #{$input-prefix}-inner-text {
color: $input-disabled-color;
}
+
#{$input-prefix}-len {
color: $input-disabled-color;
}
@@ -302,6 +333,7 @@
#{$input-prefix}-clear {
opacity: 0;
}
+
#{$input-prefix}-hint {
opacity: 1;
}
@@ -319,7 +351,9 @@
}
}
- &-inner, &-control, &-label {
+ &-inner,
+ &-control,
+ &-label {
display: table-cell;
width: 1px;
vertical-align: middle;
@@ -343,15 +377,17 @@
border-radius: 0 !important;
}
- > #{$input-prefix} {
+ >#{$input-prefix} {
border-radius: 0;
- &.#{$css-prefix}focus,&:hover {
+
+ &.#{$css-prefix}focus,
+ &:hover {
position: relative;
z-index: 1;
}
}
- > #{$input-prefix}:first-child {
+ >#{$input-prefix}:first-child {
&.#{$css-prefix}small {
border-top-left-radius: $form-element-small-corner !important;
border-bottom-left-radius: $form-element-small-corner !important;
@@ -367,7 +403,8 @@
border-bottom-left-radius: $form-element-large-corner !important;
}
}
- > #{$input-prefix}:last-child {
+
+ >#{$input-prefix}:last-child {
&.#{$css-prefix}small {
border-top-right-radius: $form-element-small-corner !important;
border-bottom-right-radius: $form-element-small-corner !important;
@@ -384,6 +421,7 @@
}
}
}
+
&-group-addon {
width: 1px;
display: table-cell;
@@ -394,40 +432,48 @@
&:first-child {
border-bottom-right-radius: 0 !important;
border-top-right-radius: 0 !important;
+
//TODO: removed in 2.x
- > * {
+ >* {
margin-right: calc(0px - #{$input-border-width});
border-bottom-right-radius: 0 !important;
border-top-right-radius: 0 !important;
+
&.#{$css-prefix}focus {
position: relative;
z-index: 1;
}
- > #{$input-prefix} {
+
+ >#{$input-prefix} {
border-bottom-right-radius: 0 !important;
border-top-right-radius: 0 !important;
}
- > #{$input-prefix}.#{$css-prefix}focus {
+
+ >#{$input-prefix}.#{$css-prefix}focus {
position: relative;
z-index: 1;
}
}
}
+
&:last-child {
border-bottom-left-radius: 0 !important;
border-top-left-radius: 0 !important;
+
//TODO: removed in 2.x
- > * {
+ >* {
margin-left: calc(0px - #{$input-border-width});
border-bottom-left-radius: 0 !important;
border-top-left-radius: 0 !important;
- > #{$input-prefix} {
+
+ >#{$input-prefix} {
border-bottom-left-radius: 0 !important;
border-top-left-radius: 0 !important;
}
}
}
}
+
&-group-text {
color: $input-addon-text-color;
background-color: $input-addon-bg-color;
@@ -438,6 +484,7 @@
&:first-child {
border-right-width: 0;
}
+
&:last-child {
border-left-width: 0;
}
diff --git a/components/input/textarea.jsx b/components/input/textarea.jsx
index 27f0ef4eba..f31db89e20 100644
--- a/components/input/textarea.jsx
+++ b/components/input/textarea.jsx
@@ -2,6 +2,7 @@ import React from 'react';
import ReactDOM from 'react-dom';
import PropTypes from 'prop-types';
import classNames from 'classnames';
+import Input from '../locale/zh-cn';
import { obj, env } from '../util';
import Base from './base';
@@ -36,6 +37,10 @@ const hiddenStyle = {
right: 0,
};
+function preventDefault(e) {
+ e.preventDefault();
+}
+
/**
* Input.TextArea
* @order 2
@@ -71,6 +76,10 @@ export default class TextArea extends Base {
* @param {number} value 评分值
*/
renderPreview: PropTypes.func,
+ /**
+ * 国际化配置
+ */
+ locale: PropTypes.object,
};
static defaultProps = {
@@ -79,6 +88,7 @@ export default class TextArea extends Base {
isPreview: false,
rows: 4,
autoHeight: false,
+ locale: Input.Input,
};
constructor(props) {
@@ -217,7 +227,62 @@ export default class TextArea extends Base {
saveHelpRef(ref) {
this.helpRef = ref;
}
+ handleKeyDownFromClear = e => {
+ if (e.keyCode === 13) {
+ this.onClear(e);
+ }
+ };
+
+ onClear(e) {
+ if (this.props.disabled) {
+ return;
+ }
+ // 非受控模式清空内部数据
+ if (!('value' in this.props)) {
+ this.setState({
+ value: '',
+ });
+ }
+ this.props.onChange('', e, 'clear');
+ this.focus();
+ }
+ renderClear() {
+ const { hasClear, readOnly, state, prefix, disabled, showLimitHint, maxLength,locale } = this.props;
+ const len = maxLength > 0 && this.state.value ? this.getValueLength(this.state.value) : 0;
+ let clearWrap = null;
+ // showClear属性应该与disable属性为互斥状态
+ const showClear = hasClear && !readOnly && !!`${this.state.value}` && !disabled;
+ const cls = classNames({
+ [`${prefix}input-clear-before`]: !!showLimitHint,
+ [`${prefix}input-len`]: true,
+ [`${prefix}error`]: len > maxLength,
+ })
+ clearWrap = showClear ?
+ {locale.clear}
+ : null;
+ if (state === 'loading') {
+ clearWrap = null;
+ }
+ return clearWrap;
+ }
+ renderControl() {
+ const lenWrap = this.renderLength();
+ const { prefix } = this.props
+ const cls = classNames({
+ [`${prefix}input-control`]: true,
+ [`${prefix}input-control-textarea`]: true,
+ })
+ return (
+ this.focus()} className={cls}>
+ {lenWrap && lenWrap} {this.renderClear()}
+
+ );
+ }
render() {
const {
rows,