@hi-ui/input 4.2.1 → 4.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # @hi-ui/input
2
2
 
3
+ ## 4.3.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [#3092](https://github.com/XiaoMi/hiui/pull/3092) [`bf2179191`](https://github.com/XiaoMi/hiui/commit/bf21791917f96c0b33b6a74539650bc56aba1d99) Thanks [@zyprepare](https://github.com/zyprepare)! - feat(input): add awaitCompositionEnd api (#3090)
8
+
3
9
  ## 4.2.1
4
10
 
5
11
  ### Patch Changes
package/lib/cjs/Input.js CHANGED
@@ -67,7 +67,8 @@ var Input = /*#__PURE__*/React.forwardRef(function (_a, ref) {
67
67
  onClear = _a.onClear,
68
68
  type = _a.type,
69
69
  containerRef = _a.containerRef,
70
- rest = tslib.__rest(_a, ["prefixCls", "role", "className", "style", "size", "appearance", "prepend", "append", "prefix", "suffix", "clearableTrigger", "clearable", "invalid", "name", "autoFocus", "disabled", "readOnly", "maxLength", "placeholder", "defaultValue", "value", "onChange", "onFocus", "onBlur", "onKeyDown", "trimValueOnBlur", "onClear", "type", "containerRef"]);
70
+ waitCompositionEnd = _a.waitCompositionEnd,
71
+ rest = tslib.__rest(_a, ["prefixCls", "role", "className", "style", "size", "appearance", "prepend", "append", "prefix", "suffix", "clearableTrigger", "clearable", "invalid", "name", "autoFocus", "disabled", "readOnly", "maxLength", "placeholder", "defaultValue", "value", "onChange", "onFocus", "onBlur", "onKeyDown", "trimValueOnBlur", "onClear", "type", "containerRef", "waitCompositionEnd"]);
71
72
  // @TODO: 临时方案,后面迁移至 InputGroup
72
73
  var _useMemo = React.useMemo(function () {
73
74
  var shouldUnset = [false, false];
@@ -107,7 +108,8 @@ var Input = /*#__PURE__*/React.forwardRef(function (_a, ref) {
107
108
  onBlur: onBlur,
108
109
  onKeyDown: onKeyDown,
109
110
  trimValueOnBlur: trimValueOnBlur,
110
- type: type
111
+ type: type,
112
+ waitCompositionEnd: waitCompositionEnd
111
113
  }),
112
114
  tryChangeValue = _useInput.tryChangeValue,
113
115
  focused = _useInput.focused,
@@ -44,11 +44,18 @@ var useInput = function useInput(_ref) {
44
44
  _ref$type = _ref.type,
45
45
  type = _ref$type === void 0 ? 'text' : _ref$type,
46
46
  clearElementRef = _ref.clearElementRef,
47
- inputElementRef = _ref.inputElementRef;
47
+ inputElementRef = _ref.inputElementRef,
48
+ waitCompositionEnd = _ref.waitCompositionEnd;
48
49
  // Object.is 避免 trimValueOnBlur 和 点击 clearIcon 触发 2 次相同的 onCHange
49
50
  var _useUncontrolledState = useUncontrolledState.useUncontrolledState(defaultValue, valueProp, onChange, Object.is),
50
51
  value = _useUncontrolledState[0],
51
52
  tryChangeValue = _useUncontrolledState[1];
53
+ // 用于存储中文输入法下输入未完成时的值
54
+ var _useState = React.useState(''),
55
+ tempValue = _useState[0],
56
+ setTempValue = _useState[1];
57
+ // 是否正在输入中文
58
+ var isComposingRef = React.useRef(false);
52
59
  var _useInputCursor = useInputCursor.useInputCursor({
53
60
  inputElementRef: inputElementRef,
54
61
  value: index.format(value, type)
@@ -68,6 +75,13 @@ var useInput = function useInput(_ref) {
68
75
  }
69
76
  evt.persist();
70
77
  var nextValue = evt.target.value;
78
+ // 如果正在输入中文中,则更新临时要显示的值,并返回
79
+ if (waitCompositionEnd && isComposingRef.current) {
80
+ setTempValue(nextValue);
81
+ return;
82
+ }
83
+ // 中文输入完成后才触发 onChange 并清空临时值
84
+ setTempValue('');
71
85
  var valueTrue = index.pure(nextValue, type);
72
86
  // 防溢出,保证 onChange 拿到的是值是最新的 formatted value
73
87
  var value = index.format(nextValue, type);
@@ -81,10 +95,20 @@ var useInput = function useInput(_ref) {
81
95
  });
82
96
  tryChangeValue(valueTrue, event);
83
97
  needResetCursorPosition && formatHandleChange(event);
84
- }, [formatHandleChange, needResetCursorPosition, tryChangeValue, type]);
85
- var _useState = React.useState(autoFocus),
86
- focused = _useState[0],
87
- setFocused = _useState[1];
98
+ }, [formatHandleChange, needResetCursorPosition, tryChangeValue, type, waitCompositionEnd]);
99
+ var handleCompositionStart = React.useCallback(function () {
100
+ if (!waitCompositionEnd) return;
101
+ isComposingRef.current = true;
102
+ }, [waitCompositionEnd]);
103
+ var handleCompositionEnd = React.useCallback(function (event) {
104
+ if (!waitCompositionEnd) return;
105
+ isComposingRef.current = false;
106
+ setTempValue('');
107
+ handleChange(event);
108
+ }, [handleChange, waitCompositionEnd]);
109
+ var _useState2 = React.useState(autoFocus),
110
+ focused = _useState2[0],
111
+ setFocused = _useState2[1];
88
112
  var handleFocus = useLatest.useLatestCallback(function (evt) {
89
113
  setFocused(true);
90
114
  onFocus === null || onFocus === void 0 ? void 0 : onFocus(evt);
@@ -119,14 +143,16 @@ var useInput = function useInput(_ref) {
119
143
  var getInputProps = React.useCallback(function () {
120
144
  var nativeType = EXTRA_TYPE.includes(type) ? undefined : type;
121
145
  return Object.assign(Object.assign({}, nativeInputProps), {
122
- value: index.format(value, type),
146
+ value: tempValue || index.format(value, type),
123
147
  type: nativeType,
124
148
  onChange: handleChange,
125
149
  onFocus: handleFocus,
126
150
  onBlur: handleBlur,
127
- onKeyDown: needResetCursorPosition ? funcUtils.callAllFuncs(handleOnKeyDown, onKeyDown) : onKeyDown
151
+ onKeyDown: needResetCursorPosition ? funcUtils.callAllFuncs(handleOnKeyDown, onKeyDown) : onKeyDown,
152
+ onCompositionStart: handleCompositionStart,
153
+ onCompositionEnd: handleCompositionEnd
128
154
  });
129
- }, [type, nativeInputProps, value, handleChange, handleFocus, handleBlur, needResetCursorPosition, handleOnKeyDown, onKeyDown]);
155
+ }, [type, nativeInputProps, tempValue, value, handleChange, handleFocus, handleBlur, needResetCursorPosition, handleOnKeyDown, onKeyDown, handleCompositionStart, handleCompositionEnd]);
130
156
  React.useEffect(function () {
131
157
  // 满足以下条件时需要校对光标位置
132
158
  if (needResetCursorPosition && inputElementRef.current) {
package/lib/esm/Input.js CHANGED
@@ -55,7 +55,8 @@ var Input = /*#__PURE__*/forwardRef(function (_a, ref) {
55
55
  onClear = _a.onClear,
56
56
  type = _a.type,
57
57
  containerRef = _a.containerRef,
58
- rest = __rest(_a, ["prefixCls", "role", "className", "style", "size", "appearance", "prepend", "append", "prefix", "suffix", "clearableTrigger", "clearable", "invalid", "name", "autoFocus", "disabled", "readOnly", "maxLength", "placeholder", "defaultValue", "value", "onChange", "onFocus", "onBlur", "onKeyDown", "trimValueOnBlur", "onClear", "type", "containerRef"]);
58
+ waitCompositionEnd = _a.waitCompositionEnd,
59
+ rest = __rest(_a, ["prefixCls", "role", "className", "style", "size", "appearance", "prepend", "append", "prefix", "suffix", "clearableTrigger", "clearable", "invalid", "name", "autoFocus", "disabled", "readOnly", "maxLength", "placeholder", "defaultValue", "value", "onChange", "onFocus", "onBlur", "onKeyDown", "trimValueOnBlur", "onClear", "type", "containerRef", "waitCompositionEnd"]);
59
60
  // @TODO: 临时方案,后面迁移至 InputGroup
60
61
  var _useMemo = useMemo(function () {
61
62
  var shouldUnset = [false, false];
@@ -95,7 +96,8 @@ var Input = /*#__PURE__*/forwardRef(function (_a, ref) {
95
96
  onBlur: onBlur,
96
97
  onKeyDown: onKeyDown,
97
98
  trimValueOnBlur: trimValueOnBlur,
98
- type: type
99
+ type: type,
100
+ waitCompositionEnd: waitCompositionEnd
99
101
  }),
100
102
  tryChangeValue = _useInput.tryChangeValue,
101
103
  focused = _useInput.focused,
@@ -7,7 +7,7 @@
7
7
  * This source code is licensed under the MIT license found in the
8
8
  * LICENSE file in the root directory of this source tree.
9
9
  */
10
- import { useMemo, useCallback, useState, useEffect } from 'react';
10
+ import { useState, useRef, useMemo, useCallback, useEffect } from 'react';
11
11
  import { useUncontrolledState } from '@hi-ui/use-uncontrolled-state';
12
12
  import { useLatestCallback } from '@hi-ui/use-latest';
13
13
  import { setAttrStatus } from '@hi-ui/dom-utils';
@@ -39,11 +39,18 @@ var useInput = function useInput(_ref) {
39
39
  _ref$type = _ref.type,
40
40
  type = _ref$type === void 0 ? 'text' : _ref$type,
41
41
  clearElementRef = _ref.clearElementRef,
42
- inputElementRef = _ref.inputElementRef;
42
+ inputElementRef = _ref.inputElementRef,
43
+ waitCompositionEnd = _ref.waitCompositionEnd;
43
44
  // Object.is 避免 trimValueOnBlur 和 点击 clearIcon 触发 2 次相同的 onCHange
44
45
  var _useUncontrolledState = useUncontrolledState(defaultValue, valueProp, onChange, Object.is),
45
46
  value = _useUncontrolledState[0],
46
47
  tryChangeValue = _useUncontrolledState[1];
48
+ // 用于存储中文输入法下输入未完成时的值
49
+ var _useState = useState(''),
50
+ tempValue = _useState[0],
51
+ setTempValue = _useState[1];
52
+ // 是否正在输入中文
53
+ var isComposingRef = useRef(false);
47
54
  var _useInputCursor = useInputCursor({
48
55
  inputElementRef: inputElementRef,
49
56
  value: format(value, type)
@@ -63,6 +70,13 @@ var useInput = function useInput(_ref) {
63
70
  }
64
71
  evt.persist();
65
72
  var nextValue = evt.target.value;
73
+ // 如果正在输入中文中,则更新临时要显示的值,并返回
74
+ if (waitCompositionEnd && isComposingRef.current) {
75
+ setTempValue(nextValue);
76
+ return;
77
+ }
78
+ // 中文输入完成后才触发 onChange 并清空临时值
79
+ setTempValue('');
66
80
  var valueTrue = pure(nextValue, type);
67
81
  // 防溢出,保证 onChange 拿到的是值是最新的 formatted value
68
82
  var value = format(nextValue, type);
@@ -76,10 +90,20 @@ var useInput = function useInput(_ref) {
76
90
  });
77
91
  tryChangeValue(valueTrue, event);
78
92
  needResetCursorPosition && formatHandleChange(event);
79
- }, [formatHandleChange, needResetCursorPosition, tryChangeValue, type]);
80
- var _useState = useState(autoFocus),
81
- focused = _useState[0],
82
- setFocused = _useState[1];
93
+ }, [formatHandleChange, needResetCursorPosition, tryChangeValue, type, waitCompositionEnd]);
94
+ var handleCompositionStart = useCallback(function () {
95
+ if (!waitCompositionEnd) return;
96
+ isComposingRef.current = true;
97
+ }, [waitCompositionEnd]);
98
+ var handleCompositionEnd = useCallback(function (event) {
99
+ if (!waitCompositionEnd) return;
100
+ isComposingRef.current = false;
101
+ setTempValue('');
102
+ handleChange(event);
103
+ }, [handleChange, waitCompositionEnd]);
104
+ var _useState2 = useState(autoFocus),
105
+ focused = _useState2[0],
106
+ setFocused = _useState2[1];
83
107
  var handleFocus = useLatestCallback(function (evt) {
84
108
  setFocused(true);
85
109
  onFocus === null || onFocus === void 0 ? void 0 : onFocus(evt);
@@ -114,14 +138,16 @@ var useInput = function useInput(_ref) {
114
138
  var getInputProps = useCallback(function () {
115
139
  var nativeType = EXTRA_TYPE.includes(type) ? undefined : type;
116
140
  return Object.assign(Object.assign({}, nativeInputProps), {
117
- value: format(value, type),
141
+ value: tempValue || format(value, type),
118
142
  type: nativeType,
119
143
  onChange: handleChange,
120
144
  onFocus: handleFocus,
121
145
  onBlur: handleBlur,
122
- onKeyDown: needResetCursorPosition ? callAllFuncs(handleOnKeyDown, onKeyDown) : onKeyDown
146
+ onKeyDown: needResetCursorPosition ? callAllFuncs(handleOnKeyDown, onKeyDown) : onKeyDown,
147
+ onCompositionStart: handleCompositionStart,
148
+ onCompositionEnd: handleCompositionEnd
123
149
  });
124
- }, [type, nativeInputProps, value, handleChange, handleFocus, handleBlur, needResetCursorPosition, handleOnKeyDown, onKeyDown]);
150
+ }, [type, nativeInputProps, tempValue, value, handleChange, handleFocus, handleBlur, needResetCursorPosition, handleOnKeyDown, onKeyDown, handleCompositionStart, handleCompositionEnd]);
125
151
  useEffect(function () {
126
152
  // 满足以下条件时需要校对光标位置
127
153
  if (needResetCursorPosition && inputElementRef.current) {
@@ -89,6 +89,10 @@ export interface InputProps extends HiBaseHTMLFieldProps<'input'> {
89
89
  * @private
90
90
  */
91
91
  containerRef?: React.Ref<HTMLDivElement>;
92
+ /**
93
+ * 是否等待文本段落组成完成
94
+ */
95
+ waitCompositionEnd?: boolean;
92
96
  }
93
97
  /**
94
98
  * 模拟伪装目标事件 target
@@ -1,5 +1,5 @@
1
1
  import React from 'react';
2
- export declare const useInput: ({ name, autoFocus, disabled, readOnly, maxLength, placeholder, defaultValue, value: valueProp, onChange, onFocus, onBlur, onKeyDown, trimValueOnBlur, type, clearElementRef, inputElementRef, }: UseInputProps) => {
2
+ export declare const useInput: ({ name, autoFocus, disabled, readOnly, maxLength, placeholder, defaultValue, value: valueProp, onChange, onFocus, onBlur, onKeyDown, trimValueOnBlur, type, clearElementRef, inputElementRef, waitCompositionEnd, }: UseInputProps) => {
3
3
  focused: boolean;
4
4
  value: string;
5
5
  tryChangeValue: (stateOrFunction: React.SetStateAction<string>, ...args: any[]) => void;
@@ -10,6 +10,8 @@ export declare const useInput: ({ name, autoFocus, disabled, readOnly, maxLength
10
10
  onFocus: (evt: React.FocusEvent<HTMLInputElement | HTMLTextAreaElement>) => void;
11
11
  onBlur: (event: React.FocusEvent<HTMLInputElement | HTMLTextAreaElement>) => void;
12
12
  onKeyDown: ((evt: React.KeyboardEvent<any>) => void) | ((...args: any) => void) | undefined;
13
+ onCompositionStart: () => void;
14
+ onCompositionEnd: (event: any) => void;
13
15
  name: string | undefined;
14
16
  disabled: boolean;
15
17
  readOnly: boolean;
@@ -84,5 +86,9 @@ export interface UseInputProps {
84
86
  * 输入框 ref
85
87
  */
86
88
  inputElementRef?: any;
89
+ /**
90
+ * 是否等待文本段落组成完成
91
+ */
92
+ waitCompositionEnd?: boolean;
87
93
  }
88
94
  export declare type useInputReturn = ReturnType<typeof useInput>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hi-ui/input",
3
- "version": "4.2.1",
3
+ "version": "4.3.0",
4
4
  "description": "A sub-package for @hi-ui/hiui.",
5
5
  "keywords": [],
6
6
  "author": "HiUI <mi-hiui@xiaomi.com>",