1
+ import './style.scss' ;
2
+ import * as React from 'react' ;
3
+ import { classNames , prefixClaName } from 'mo/common/className' ;
4
+
5
+ import TextArea from './TextArea' ;
6
+ import { LiteralUnion } from 'mo/common/type' ;
7
+
8
+ type SizeType = 'normal' | 'large'
9
+ export interface InputProps {
10
+ disabled ?: boolean ;
11
+ size ?: SizeType ;
12
+ type ?: LiteralUnion <
13
+ | 'button'
14
+ | 'checkbox'
15
+ | 'search'
16
+ | 'submit'
17
+ | 'text' ,
18
+ string
19
+ > ;
20
+ placeholder ?: string ;
21
+ value ?: string ;
22
+ defaultValue ?: string ;
23
+ inputClassName ?: string ;
24
+ readonly onFocus ?: ( e : React . FocusEvent < HTMLInputElement > ) => void ;
25
+ readonly onBlur ?: ( e : React . FocusEvent < HTMLInputElement > ) => void ;
26
+ readonly onPressEnter ?: React . KeyboardEventHandler < HTMLInputElement > ;
27
+ readonly onKeyDown ?: ( e : React . KeyboardEvent < HTMLInputElement > ) => void ;
28
+ readonly onChange ?: ( e : any ) => void ;
29
+ }
30
+
31
+ export function fixControlledValue < T > ( value : T ) {
32
+ if ( typeof value === 'undefined' || value === null ) return '' ;
33
+ return value ;
34
+ }
35
+
36
+ export function resolveOnChange (
37
+ target : HTMLInputElement | HTMLTextAreaElement ,
38
+ e :
39
+ | React . ChangeEvent < HTMLTextAreaElement | HTMLInputElement >
40
+ | React . MouseEvent < HTMLElement , MouseEvent > ,
41
+ onChange ?: ( event : React . ChangeEvent < HTMLInputElement | HTMLTextAreaElement > ) => void ,
42
+ ) {
43
+ if ( onChange ) {
44
+ let event = e ;
45
+ if ( e . type === 'click' ) {
46
+ // click clear icon
47
+ event = Object . create ( e ) ;
48
+ event . target = target ;
49
+ event . currentTarget = target ;
50
+ const originalInputValue = target . value ;
51
+ // change target ref value cause e.target.value should be '' when clear input
52
+ target . value = '' ;
53
+ onChange ( event as React . ChangeEvent < HTMLInputElement | HTMLTextAreaElement > ) ;
54
+ // reset target ref value
55
+ target . value = originalInputValue ;
56
+ return ;
57
+ }
58
+ onChange ( event as React . ChangeEvent < HTMLInputElement | HTMLTextAreaElement > ) ;
59
+ }
60
+ }
61
+
62
+ export function getInputClassName (
63
+ prefixCls : string ,
64
+ size ?: SizeType ,
65
+ disabled ?: boolean ,
66
+ ) {
67
+ return classNames ( prefixCls , {
68
+ [ `${ prefixCls } --normal` ] : size === 'normal' ,
69
+ [ `${ prefixCls } --lg` ] : size === 'large' ,
70
+ [ `${ prefixCls } --disabled` ] : disabled ,
71
+ } ) ;
72
+ }
73
+
74
+ export interface InputState {
75
+ value : any ;
76
+ prevValue : any ;
77
+ }
78
+
79
+ class Input extends React . Component < InputProps , InputState > {
80
+
81
+ // static Search: typeof Search;
82
+ static TextArea : typeof TextArea ;
83
+
84
+ static defaultProps = {
85
+ type : 'text' ,
86
+ } ;
87
+
88
+ input : any ;
89
+
90
+ constructor ( props : InputProps ) {
91
+ super ( props ) ;
92
+ const value = typeof props . value === 'undefined' ? props . defaultValue : props . value ;
93
+ this . state = {
94
+ value,
95
+ prevValue : props . value ,
96
+ } ;
97
+ }
98
+
99
+ static getDerivedStateFromProps ( nextProps : InputProps , { prevValue } : InputState ) {
100
+ const newState : Partial < InputState > = { prevValue : nextProps . value } ;
101
+ if ( nextProps . value !== undefined || prevValue !== nextProps . value ) {
102
+ newState . value = nextProps . value ;
103
+ }
104
+ return newState ;
105
+ }
106
+
107
+ saveInput = ( input : HTMLInputElement ) => {
108
+ this . input = input ;
109
+ } ;
110
+
111
+ setValue ( value : string , callback ?: ( ) => void ) {
112
+ if ( this . props . value === undefined ) {
113
+ this . setState ( { value } , callback ) ;
114
+ } else {
115
+ callback ?.( ) ;
116
+ }
117
+ }
118
+
119
+ handleChange = ( e : React . ChangeEvent < HTMLInputElement > ) => {
120
+ this . setValue ( e . target . value ) ;
121
+ resolveOnChange ( this . input , e , this . props . onChange ) ;
122
+ } ;
123
+
124
+ handleKeyDown = ( e : React . KeyboardEvent < HTMLInputElement > ) => {
125
+ const { onPressEnter, onKeyDown } = this . props ;
126
+ if ( e . keyCode === 13 && onPressEnter ) {
127
+ onPressEnter ( e ) ;
128
+ }
129
+ onKeyDown ?.( e ) ;
130
+ } ;
131
+
132
+ render ( ) {
133
+ const { inputClassName, size, disabled = false , onFocus, onBlur } = this . props
134
+ return (
135
+ < input
136
+ onChange = { this . handleChange }
137
+ onFocus = { e => onFocus ?.( e ) }
138
+ onBlur = { e => onBlur ?.( e ) }
139
+ onKeyDown = { this . handleKeyDown }
140
+ className = { classNames (
141
+ inputClassName ,
142
+ getInputClassName ( 'input' , size , disabled ) ,
143
+ ) }
144
+ ref = { this . saveInput }
145
+ />
146
+ ) ;
147
+ }
148
+ }
149
+
150
+ export default Input ;
0 commit comments