From de41f1d9e5d18255bdc922e961524628d4dce474 Mon Sep 17 00:00:00 2001 From: oasis Date: Mon, 10 Feb 2025 16:10:52 +0800 Subject: [PATCH 1/3] perf: input --- src/packages/input/input.taro.tsx | 63 ++++------- src/packages/input/input.tsx | 174 ++++++++++++------------------ 2 files changed, 92 insertions(+), 145 deletions(-) diff --git a/src/packages/input/input.taro.tsx b/src/packages/input/input.taro.tsx index 14bf459591..4850358001 100644 --- a/src/packages/input/input.taro.tsx +++ b/src/packages/input/input.taro.tsx @@ -14,6 +14,7 @@ import { } from '@tarojs/components' import { MaskClose } from '@nutui/icons-react-taro' import Taro, { ENV_TYPE, getEnv } from '@tarojs/taro' +import { BaseEventOrig } from '@tarojs/components/types/common' import { formatNumber } from './utils' import { useConfig, useRtl } from '@/packages/configprovider/index.taro' import { BasicComponent, ComponentDefaults } from '@/utils/typings' @@ -153,23 +154,14 @@ export const Input = forwardRef( trigger: InputFormatTrigger = 'onChange' ) => { let val = value - if (type === 'number') { - val = formatNumber(val, false, true) - } - if (type === 'digit') { - val = formatNumber(val, true, true) - } - if (formatter && trigger === formatTrigger) { - val = formatter(val) - } + if (type === 'number') val = formatNumber(val, false, true) + if (type === 'digit') val = formatNumber(val, true, true) + if (formatter && trigger === formatTrigger) val = formatter(val) + setValue(val) const eventHandler = props[trigger] - if ( - eventHandler && - typeof eventHandler === 'function' && - trigger !== 'onChange' - ) { - eventHandler(val) + if (trigger !== 'onChange') { + eventHandler?.(val) } forceUpdate() } @@ -185,31 +177,31 @@ export const Input = forwardRef( setActive(true) } - const handleInput = (value: string) => { - updateValue(value, 'onChange') + const handleInput = (event: BaseEventOrig) => { + updateValue((event.detail || event.currentTarget).value, 'onChange') } const handleBlur = (event: any) => { const val = Taro.getEnv() === 'WEB' ? (event.target as any).value : value updateValue(val, 'onBlur') - setTimeout(() => { - setActive(false) - }, 200) + setTimeout(() => setActive(false), 200) } const inputType = (type: any) => { if (getEnv() === ENV_TYPE.WEB) { - if (type === 'digit') { - return 'text' - } - if (type === 'number') { - return 'tel' - } + if (type === 'digit') return 'text' + if (type === 'number') return 'tel' } else if (type === 'password') { return 'text' } return type } - + const getTextAlign = () => { + if (rtl) { + if (align === 'right') return 'left' + if (align === 'left') return 'right' + } + return align + } return ( { - handleInput((e.detail || e.currentTarget).value) - }} + onInput={handleInput} /> void + formatter?: (value: string) => string onChange?: (value: string) => void onBlur?: (value: string) => void onFocus?: (value: string) => void onClear?: (value: string) => void - onClick?: (value: MouseEvent) => void + onClick?: (event: MouseEvent) => void } -const defaultProps = { +const defaultProps: InputProps = { ...ComponentDefaults, type: 'text', name: '', @@ -71,6 +71,7 @@ export const Input = forwardRef( ) => { const rtl = useRtl() const { locale } = useConfig() + const { type, name, @@ -97,129 +98,102 @@ export const Input = forwardRef( onCompositionStart, onCompositionEnd, ...rest - } = { - ...defaultProps, - ...props, - } + } = { ...defaultProps, ...props } + const [value, setValue] = usePropsValue({ value: _value, defaultValue, finalValue: '', onChange, }) + const inputRef = useRef(null) const composingRef = useRef(false) const [active, setActive] = useState(false) - useImperativeHandle(ref, () => { - return { - clear: () => { - setValue('') - }, - focus: () => { - inputRef.current?.focus() - }, - blur: () => { - inputRef.current?.blur() - }, - get nativeElement() { - return inputRef.current - }, - } - }) + useImperativeHandle(ref, () => ({ + clear: () => setValue(''), + focus: () => inputRef.current?.focus(), + blur: () => inputRef.current?.blur(), + get nativeElement() { + return inputRef.current + }, + })) - const inputClass = useCallback(() => { - const classPrefix = 'nut-input' + const getInputClass = useCallback(() => { + const base = 'nut-input' return [ - classPrefix, - disabled ? `${classPrefix}-disabled` : '', - readOnly ? `${classPrefix}-readonly` : '', - plain ? `${classPrefix}-plain` : `${classPrefix}-container`, + base, + disabled ? `${base}-disabled` : '', + readOnly ? `${base}-readonly` : '', + plain ? `${base}-plain` : `${base}-container`, ] .filter(Boolean) .join(' ') - }, [disabled]) + }, [disabled, readOnly, plain]) - const updateValue = ( - value: any, - trigger: InputFormatTrigger = 'onChange' + const handleValueUpdate = ( + inputValue: string, + trigger: InputFormatTrigger ) => { - let val = value + let updatedValue = inputValue - if (type === 'number') { - val = formatNumber(val, false, true) - } - if (type === 'digit') { - val = formatNumber(val, true, true) - } - if (formatter && trigger === formatTrigger) { - val = formatter(val) - } - setValue(val) - const eventHandler = props[trigger] - if ( - eventHandler && - typeof eventHandler === 'function' && - trigger !== 'onChange' - ) { - eventHandler(val) + if (type === 'number') + updatedValue = formatNumber(updatedValue, false, true) + if (type === 'digit') + updatedValue = formatNumber(updatedValue, true, true) + if (formatter && trigger === formatTrigger) + updatedValue = formatter(updatedValue) + + setValue(updatedValue) + + if (trigger !== 'onChange') { + const eventHandler = props[trigger] + eventHandler?.(updatedValue) } } - const handleFocus = (event: Event) => { - const val: any = (event.target as any).value - onFocus && onFocus(val) + const handleFocus = (event: React.FocusEvent) => { + onFocus?.(event.target.value) setActive(true) } - const handleInput = (value: string) => { - updateValue(value, 'onChange') + const handleBlur = (event: React.FocusEvent) => { + handleValueUpdate(event.target.value, 'onBlur') + setTimeout(() => setActive(false), 200) } - const handleBlur = (event: Event) => { - const val: any = (event.target as any).value - updateValue(val, 'onBlur') - setTimeout(() => { - setActive(false) - }, 200) + const handleInputChange = (event: React.ChangeEvent) => { + handleValueUpdate(event.target.value, 'onChange') } - const inputType = (type: string) => { - if (type === 'digit') { - return 'text' - } - if (type === 'number') { - return 'tel' + const getInputType = (inputType: InputType) => { + if (inputType === 'digit') return 'text' + if (inputType === 'number') return 'tel' + return inputType + } + + const getTextAlign = () => { + if (rtl) { + if (align === 'right') return 'left' + if (align === 'left') return 'right' } - return type + return align } return (
{ - onClick && onClick(e) - }} + onClick={onClick} > { - handleBlur(e) - }} - onFocus={(e: any) => { - handleFocus(e) - }} - onChange={(e: any) => { - handleInput(e.currentTarget.value) - }} + onFocus={handleFocus} + onBlur={handleBlur} + onChange={handleInputChange} onCompositionStart={(e) => { composingRef.current = true onCompositionStart?.(e) @@ -247,19 +215,19 @@ export const Input = forwardRef( onCompositionEnd?.(e) }} /> - {clearable && !readOnly && active && value.length > 0 ? ( + {clearable && !readOnly && active && value.length > 0 && ( { if (!disabled) { setValue('') - onClear && onClear('') + onClear?.('') } }} > {clearIcon || } - ) : null} + )}
) } From 848856a556ea33918d0f9963f99d966d76f8f00f Mon Sep 17 00:00:00 2001 From: oasis Date: Tue, 25 Feb 2025 11:11:37 +0800 Subject: [PATCH 2/3] fix: review --- src/packages/input/input.taro.tsx | 2 +- src/packages/input/input.tsx | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/packages/input/input.taro.tsx b/src/packages/input/input.taro.tsx index 241d97ccef..a13e770592 100644 --- a/src/packages/input/input.taro.tsx +++ b/src/packages/input/input.taro.tsx @@ -159,8 +159,8 @@ export const Input = forwardRef( if (formatter && trigger === formatTrigger) val = formatter(val) setValue(val) - const eventHandler = props[trigger] if (trigger !== 'onChange') { + const eventHandler = props[trigger] eventHandler?.(val) } forceUpdate() diff --git a/src/packages/input/input.tsx b/src/packages/input/input.tsx index 16977a53d5..955c38ce40 100644 --- a/src/packages/input/input.tsx +++ b/src/packages/input/input.tsx @@ -121,12 +121,12 @@ export const Input = forwardRef( })) const getInputClass = useCallback(() => { - const base = 'nut-input' + const classPrefix = 'nut-input' return [ - base, - disabled ? `${base}-disabled` : '', - readOnly ? `${base}-readonly` : '', - plain ? `${base}-plain` : `${base}-container`, + classPrefix, + `${disabled ? `${classPrefix}-disabled` : ''}`, + readOnly ? `${classPrefix}-readonly` : '', + `${plain ? `${classPrefix}-plain` : `${classPrefix}-container`}`, ] .filter(Boolean) .join(' ') From 9051fd561a4a0360b43459bef9ca1532f3022026 Mon Sep 17 00:00:00 2001 From: oasis Date: Tue, 25 Feb 2025 13:53:17 +0800 Subject: [PATCH 3/3] fix: review --- src/packages/input/input.taro.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/packages/input/input.taro.tsx b/src/packages/input/input.taro.tsx index a13e770592..518333343a 100644 --- a/src/packages/input/input.taro.tsx +++ b/src/packages/input/input.taro.tsx @@ -40,7 +40,7 @@ export interface InputProps extends BasicComponent { autoFocus: boolean confirmType: InputConfirmType plain: boolean - formatter?: (value: string) => void + formatter?: (value: string) => string onChange?: (value: string) => void onBlur?: (value: string) => void onFocus?: (value: string, height?: number) => void