1
1
'use client' ;
2
2
3
3
import clsx from 'clsx' ;
4
- import React , { useState , useEffect , useRef , FocusEvent , ChangeEvent , useCallback , useImperativeHandle } from 'react' ;
4
+ import React , {
5
+ useState ,
6
+ useEffect ,
7
+ useRef ,
8
+ FocusEvent ,
9
+ ChangeEvent ,
10
+ useCallback ,
11
+ useImperativeHandle ,
12
+ useMemo ,
13
+ } from 'react' ;
5
14
import type { InputProps } from './types' ;
6
15
import { useOnScreen } from '../../../utils/hooks' ;
7
16
@@ -11,7 +20,7 @@ const MDBInput: React.FC<InputProps> = React.forwardRef<HTMLInputElement, InputP
11
20
className,
12
21
size,
13
22
contrast,
14
- value,
23
+ value : valueProp ,
15
24
defaultValue,
16
25
id,
17
26
labelClass,
@@ -31,20 +40,24 @@ const MDBInput: React.FC<InputProps> = React.forwardRef<HTMLInputElement, InputP
31
40
} ,
32
41
ref
33
42
) => {
34
- const [ newValue , setNewValue ] = useState ( value || defaultValue ) ;
43
+ const [ valueState , setValueState ] = useState ( defaultValue ) ;
44
+ const value = useMemo ( ( ) => {
45
+ if ( valueProp !== undefined ) {
46
+ return valueProp ;
47
+ }
48
+ return valueState ;
49
+ } , [ valueProp , valueState ] ) ;
50
+
35
51
const [ labelWidth , setLabelWidth ] = useState ( 0 ) ;
36
52
const [ active , setActive ] = useState ( false ) ;
37
53
const [ counter , setCounter ] = useState ( 0 ) ;
38
-
39
54
const innerRef = useRef < HTMLInputElement > ( null ) ;
40
55
const isVisible = useOnScreen ( innerRef ) ;
41
-
42
- useImperativeHandle ( ref , ( ) => innerRef . current as HTMLInputElement ) ;
43
-
44
56
const labelEl = useRef < HTMLLabelElement > ( null ) ;
45
-
46
57
const labelReference = labelRef ? labelRef : labelEl ;
47
58
59
+ useImperativeHandle ( ref , ( ) => innerRef . current as HTMLInputElement ) ;
60
+
48
61
const wrapperClasses = clsx ( 'form-outline' , contrast && 'form-white' , wrapperClass ) ;
49
62
const inputClasses = clsx (
50
63
'form-control' ,
@@ -55,58 +68,42 @@ const MDBInput: React.FC<InputProps> = React.forwardRef<HTMLInputElement, InputP
55
68
) ;
56
69
const labelClasses = clsx ( 'form-label' , labelClass ) ;
57
70
58
- useEffect ( ( ) => {
59
- if ( ! innerRef . current ) return ;
60
-
61
- const { value } = innerRef . current ;
62
-
63
- value != '' ? setActive ( true ) : setActive ( false ) ;
64
- } , [ innerRef . current ?. value ] ) ;
65
-
66
- useEffect ( ( ) => {
67
- if ( value === undefined ) return ;
68
- value != '' ? setActive ( true ) : setActive ( false ) ;
69
- } , [ value ] ) ;
70
-
71
- useEffect ( ( ) => {
72
- if ( defaultValue === undefined ) return ;
73
- defaultValue != '' ? setActive ( true ) : setActive ( false ) ;
74
- } , [ defaultValue ] ) ;
75
-
76
71
const setWidth = useCallback ( ( ) => {
77
72
if ( labelReference . current ?. clientWidth ) {
78
73
setLabelWidth ( labelReference . current . clientWidth * 0.8 + 8 ) ;
79
74
}
80
75
} , [ labelReference ] ) ;
81
76
82
- useEffect ( ( ) => {
83
- setWidth ( ) ;
84
- } , [ labelReference . current ?. clientWidth , setWidth , isVisible ] ) ;
85
-
86
77
const handleChange = ( e : ChangeEvent < HTMLInputElement > ) => {
87
- setNewValue ( e . target . value ) ;
78
+ setValueState ( e . target . value ) ;
88
79
showCounter && setCounter ( e . target . value . length ) ;
89
80
onChange ?.( e ) ;
90
81
} ;
91
82
92
83
const handleBlur = useCallback (
93
84
( e : FocusEvent < HTMLInputElement , Element > ) => {
94
85
if ( ! innerRef . current ) return ;
95
-
96
- if (
97
- ( newValue !== undefined && newValue != '' ) ||
98
- ( value !== undefined && value != '' ) ||
99
- innerRef . current . value != ''
100
- ) {
86
+ if ( value ) {
101
87
setActive ( true ) ;
102
88
} else {
103
89
setActive ( false ) ;
104
90
}
105
91
onBlur && onBlur ( e ) ;
106
92
} ,
107
- [ newValue , value , onBlur ]
93
+ [ value , onBlur ]
108
94
) ;
109
95
96
+ useEffect ( ( ) => {
97
+ setWidth ( ) ;
98
+ } , [ labelReference . current ?. clientWidth , setWidth , isVisible ] ) ;
99
+
100
+ useEffect ( ( ) => {
101
+ if ( value ) {
102
+ return setActive ( true ) ;
103
+ }
104
+ setActive ( false ) ;
105
+ } , [ value ] ) ;
106
+
110
107
return (
111
108
< WrapperTag className = { wrapperClasses } style = { wrapperStyle } >
112
109
< input
@@ -116,7 +113,7 @@ const MDBInput: React.FC<InputProps> = React.forwardRef<HTMLInputElement, InputP
116
113
onBlur = { handleBlur }
117
114
onChange = { handleChange }
118
115
onFocus = { setWidth }
119
- value = { value }
116
+ value = { valueProp }
120
117
defaultValue = { defaultValue }
121
118
id = { id }
122
119
ref = { innerRef }
0 commit comments