From 46ea4de7c2fe7af798c846466d5cc27a29e9382e Mon Sep 17 00:00:00 2001
From: ming680 <827668037@qq.com>
Date: Tue, 24 Sep 2024 22:17:21 +0800
Subject: [PATCH] =?UTF-8?q?fix(input):=20fix=20input=20=E5=8F=97=E6=8E=A7?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
src/input/_example/align.tsx | 2 --
src/input/_example/auto-width.tsx | 1 +
src/input/_example/base.tsx | 2 ++
src/input/_example/borderless.tsx | 2 ++
src/input/_example/clearable.tsx | 12 +++++--
src/input/_example/format.tsx | 1 +
src/input/_example/password.tsx | 24 ++++++++++++--
src/input/_example/status.tsx | 9 ++++++
src/input/input.tsx | 54 +++++++++++++++++++++++--------
9 files changed, 86 insertions(+), 21 deletions(-)
diff --git a/src/input/_example/align.tsx b/src/input/_example/align.tsx
index 7938608..d0071a4 100644
--- a/src/input/_example/align.tsx
+++ b/src/input/_example/align.tsx
@@ -4,8 +4,6 @@ import 'tdesign-web-components/space';
import { Component } from 'omi';
export default class InputAlign extends Component {
- inputValue = '';
-
render() {
return (
diff --git a/src/input/_example/auto-width.tsx b/src/input/_example/auto-width.tsx
index 1e48bfe..9f253d6 100644
--- a/src/input/_example/auto-width.tsx
+++ b/src/input/_example/auto-width.tsx
@@ -13,6 +13,7 @@ export default class InputAutowidth extends Component {
defaultValue="宽度自适应"
onChange={(value) => {
this.inputValue = value;
+ this.update();
}}
/>
diff --git a/src/input/_example/base.tsx b/src/input/_example/base.tsx
index 07b0509..7598e58 100644
--- a/src/input/_example/base.tsx
+++ b/src/input/_example/base.tsx
@@ -15,6 +15,7 @@ export default class InputBase extends Component {
placeholder="请输入内容(无默认值)"
onChange={(value) => {
this.value1 = value;
+ this.update();
console.log('change', value);
}}
onFocus={() => {
@@ -30,6 +31,7 @@ export default class InputBase extends Component {
onChange={(value) => {
console.log(value);
this.value2 = value;
+ this.update();
}}
onEnter={(value) => {
console.log(value);
diff --git a/src/input/_example/borderless.tsx b/src/input/_example/borderless.tsx
index 12239a0..3c9ebc7 100644
--- a/src/input/_example/borderless.tsx
+++ b/src/input/_example/borderless.tsx
@@ -15,6 +15,7 @@ export default class InputBase extends Component {
placeholder="请输入内容(无默认值)"
onChange={(value) => {
this.value1 = value;
+ this.update();
console.log(value);
}}
/>
@@ -24,6 +25,7 @@ export default class InputBase extends Component {
onChange={(value) => {
console.log(value);
this.value2 = value;
+ this.update();
}}
onEnter={(value) => {
console.log(value);
diff --git a/src/input/_example/clearable.tsx b/src/input/_example/clearable.tsx
index 5f00f25..da6ccbc 100644
--- a/src/input/_example/clearable.tsx
+++ b/src/input/_example/clearable.tsx
@@ -1,6 +1,6 @@
+import 'tdesign-icons-web-components/esm/components/lock-on';
import 'tdesign-web-components/input';
import 'tdesign-web-components/space';
-import 'tdesign-icons-web-components/esm/components/lock-on';
import { Component } from 'omi';
@@ -10,7 +10,15 @@ export default class InputBase extends Component {
render() {
return (
-
+ {
+ this.value1 = value;
+ this.update();
+ }}
+ clearable
+ />
);
}
diff --git a/src/input/_example/format.tsx b/src/input/_example/format.tsx
index 72788b2..620ffbb 100644
--- a/src/input/_example/format.tsx
+++ b/src/input/_example/format.tsx
@@ -21,6 +21,7 @@ export default class InputForMat extends Component {
value={this.inputValue}
onChange={(value) => {
this.inputValue = value;
+ this.update();
}}
status={inputStatus}
format={format}
diff --git a/src/input/_example/password.tsx b/src/input/_example/password.tsx
index 50b2d14..4fa7285 100644
--- a/src/input/_example/password.tsx
+++ b/src/input/_example/password.tsx
@@ -1,6 +1,6 @@
+import 'tdesign-icons-web-components/esm/components/lock-on';
import 'tdesign-web-components/input';
import 'tdesign-web-components/space';
-import 'tdesign-icons-web-components/esm/components/lock-on';
import { Component } from 'omi';
@@ -12,8 +12,26 @@ export default class InputBase extends Component {
render() {
return (
- } />
- } />
+ }
+ onChange={(value) => {
+ this.value1 = value;
+ this.update();
+ }}
+ />
+ }
+ onChange={(value) => {
+ this.value2 = value;
+ this.update();
+ }}
+ />
);
}
diff --git a/src/input/_example/status.tsx b/src/input/_example/status.tsx
index c662cff..af5ea7b 100644
--- a/src/input/_example/status.tsx
+++ b/src/input/_example/status.tsx
@@ -18,6 +18,7 @@ export default class InputStatus extends Component {
value={this.inputValue}
onChange={(value) => {
this.inputValue = value;
+ this.update();
}}
/>
{
this.inputValue = value;
+ this.update();
}}
/>
@@ -35,6 +37,7 @@ export default class InputStatus extends Component {
value={this.inputValue}
onChange={(value) => {
this.inputValue = value;
+ this.update();
}}
status="success"
/>
@@ -43,6 +46,7 @@ export default class InputStatus extends Component {
value={this.inputValue}
onChange={(value) => {
this.inputValue = value;
+ this.update();
}}
status="warning"
/>
@@ -51,6 +55,7 @@ export default class InputStatus extends Component {
value={this.inputValue}
onChange={(value) => {
this.inputValue = value;
+ this.update();
}}
status="error"
/>
@@ -62,6 +67,7 @@ export default class InputStatus extends Component {
value={this.inputValue}
onChange={(value) => {
this.inputValue = value;
+ this.update();
}}
/>
{
this.inputValue = value;
+ this.update();
}}
status="success"
/>
@@ -79,6 +86,7 @@ export default class InputStatus extends Component {
value={this.inputValue}
onChange={(value) => {
this.inputValue = value;
+ this.update();
}}
status="warning"
/>
@@ -88,6 +96,7 @@ export default class InputStatus extends Component {
value={this.inputValue}
onChange={(value) => {
this.inputValue = value;
+ this.update();
}}
status="error"
/>
diff --git a/src/input/input.tsx b/src/input/input.tsx
index cb04628..58401ee 100644
--- a/src/input/input.tsx
+++ b/src/input/input.tsx
@@ -87,7 +87,7 @@ export default class Input extends Component {
composingRef = createRef();
- value;
+ innerValue;
composingValue = '';
@@ -103,6 +103,10 @@ export default class Input extends Component {
eventProps;
+ private get isControlled() {
+ return Reflect.has(this.props, 'value');
+ }
+
private handlePasswordVisible = (e: MouseEvent) => {
e.stopImmediatePropagation();
if (this.props.disabled) return;
@@ -116,7 +120,7 @@ export default class Input extends Component {
const { maxlength, maxcharacter, allowInputOverMax, status, onValidate, onChange } = this.props;
const { getValueByLimitNumber } = useLengthLimit({
- value: this.value === undefined ? undefined : String(this.value),
+ value: this.innerValue === undefined ? undefined : String(this.innerValue),
status,
maxlength,
maxcharacter,
@@ -134,7 +138,9 @@ export default class Input extends Component {
// 完成中文输入时同步一次 composingValue
this.composingValue = newStr;
// 防止输入中文后移开光标触发mouseleave时value没更新
- this.value = newStr;
+ if (!this.isControlled) {
+ this.innerValue = newStr;
+ }
const { onValidateChange } = useLengthLimit({
value: newStr === undefined ? undefined : String(newStr),
status: this.status,
@@ -189,7 +195,6 @@ export default class Input extends Component {
private handleClear = (e: MouseEvent) => {
const { onChange, onClear } = this.props;
this.composingValue = '';
- this.value = '';
this.update();
onChange?.('', { e });
onClear?.({ e });
@@ -198,20 +203,27 @@ export default class Input extends Component {
private handleKeyDown = (e: KeyboardEvent) => {
const { onEnter } = this.props;
const { key, currentTarget }: { key: string; currentTarget: any } = e;
- this.value = '';
key === 'Enter' && onEnter?.(currentTarget.value, { e });
this.props.onMyKeydown?.(currentTarget.value, { e });
+ this.props.onKeydown?.(currentTarget.value, { e });
+ // 防止 最外层 onKeydown
+ e.stopPropagation();
};
private handleKeyUp = (e: KeyboardEvent) => {
const { currentTarget }: { currentTarget: any } = e;
this.props.onMyKeyup?.(currentTarget.value, { e });
+ this.props.onKeyup?.(currentTarget.value, { e });
+ // 防止 最外层 onKeyup
+ e.stopPropagation();
};
private handleKeyPress = (e: KeyboardEvent) => {
const { onKeypress } = this.props;
const { currentTarget }: { currentTarget: any } = e;
onKeypress?.(currentTarget.value, { e });
+ // 防止 最外层 onKeypress
+ e.stopPropagation();
};
private handleCompositionStart = (e: CompositionEvent) => {
@@ -245,7 +257,7 @@ export default class Input extends Component {
private resizeObserver: ResizeObserver | null = null;
install() {
- this.value = this.props.defaultValue || this.props.value;
+ this.innerValue = this.props.value || this.props.defaultValue;
this.status = this.props.status;
}
@@ -270,9 +282,12 @@ export default class Input extends Component {
return;
}
const target = e.currentTarget as any;
- this.value = target.value;
+ if (!this.isControlled) {
+ this.innerValue = target.value;
+ }
+
const { getValueByLimitNumber, onValidateChange } = useLengthLimit({
- value: this.value === undefined ? undefined : String(this.value),
+ value: this.innerValue === undefined ? undefined : String(this.innerValue),
status: this.status,
maxlength: this.props.maxlength,
maxcharacter: this.props.maxcharacter,
@@ -280,7 +295,9 @@ export default class Input extends Component {
onValidate: this.props.onValidate,
});
const limitedValue = getValueByLimitNumber(target.value);
- this.value = limitedValue;
+ if (!this.isControlled) {
+ this.innerValue = limitedValue;
+ }
this.composingValue = limitedValue;
this.props.onChange?.(limitedValue);
if (!this.props.allowInputOverMax) {
@@ -290,6 +307,15 @@ export default class Input extends Component {
});
}
+ receiveProps(props: InputProps | OmiProps, oldProps: InputProps | OmiProps) {
+ if (
+ (this.isControlled && props.value !== oldProps.value) ||
+ (Reflect.has(oldProps, 'value') && !this.isControlled)
+ ) {
+ this.innerValue = props.value;
+ }
+ }
+
render(props: OmiProps) {
const {
autoWidth,
@@ -322,7 +348,7 @@ export default class Input extends Component {
} = props;
const { limitNumber, tStatus } = useLengthLimit({
- value: this.value === undefined ? undefined : String(this.value),
+ value: this.innerValue === undefined ? undefined : String(this.innerValue),
status,
maxlength,
maxcharacter,
@@ -330,7 +356,7 @@ export default class Input extends Component {
onValidate,
});
- const isShowClearIcon = ((clearable && this.value && !disabled) || showClearIconOnEmpty) && this.isHover;
+ const isShowClearIcon = ((clearable && this.innerValue && !disabled) || showClearIconOnEmpty) && this.isHover;
const prefixIconContent = prefixIcon
? renderIcon(
@@ -390,8 +416,8 @@ export default class Input extends Component {
}
const suffixIconContent = renderIcon('t', 'suffix', parseTNode(convertToLightDomNode(suffixIconNew)));
- const labelContent = isFunction(label) ? label() : label;
- const suffixContent = isFunction(suffix) ? suffix() : suffix;
+ const labelContent = isFunction(label) ? label({}) : label;
+ const suffixContent = isFunction(suffix) ? suffix({}) : suffix;
const limitNumberNode =
limitNumber() && showLimitNumber ? (
@@ -404,7 +430,7 @@ export default class Input extends Component {
) : null;
- const innerValue = this.composingRef.current ? this.composingValue : this.value ?? '';
+ const innerValue = this.composingRef.current ? this.composingValue : this.innerValue ?? '';
const formatDisplayValue = format && !this.isFocused ? format(innerValue) : innerValue;
const renderInput = (