1- import React from 'react' ;
1+ import React , { useEffect , useRef } from 'react' ;
22import _ from 'underscore' ;
33import styles from '../../styles/styles' ;
44import * as styleConst from './styleConst' ;
@@ -7,65 +7,66 @@ import * as baseTextInputPropTypes from './baseTextInputPropTypes';
77import DomUtils from '../../libs/DomUtils' ;
88import Visibility from '../../libs/Visibility' ;
99
10- class TextInput extends React . Component {
11- componentDidMount ( ) {
12- if ( this . props . disableKeyboard ) {
13- this . textInput . setAttribute ( 'inputmode' , 'none' ) ;
10+ function TextInput ( props ) {
11+ const textInputRef = useRef ( null ) ;
12+ const removeVisibilityListenerRef = useRef ( null ) ;
13+
14+ useEffect ( ( ) => {
15+ if ( props . disableKeyboard ) {
16+ textInputRef . current . setAttribute ( 'inputmode' , 'none' ) ;
1417 }
1518
16- if ( this . props . name ) {
17- this . textInput . setAttribute ( 'name' , this . props . name ) ;
19+ if ( props . name ) {
20+ textInputRef . current . setAttribute ( 'name' , props . name ) ;
1821 }
1922
20- // Forcefully activate the soft keyboard when the user switches between tabs while input was focused.
21- this . removeVisibilityListener = Visibility . onVisibilityChange ( ( ) => {
22- if ( ! Visibility . isVisible ( ) || ! this . textInput || DomUtils . getActiveElement ( ) !== this . textInput ) {
23+ removeVisibilityListenerRef . current = Visibility . onVisibilityChange ( ( ) => {
24+ if ( ! Visibility . isVisible ( ) || ! textInputRef . current || DomUtils . getActiveElement ( ) !== textInputRef . current ) {
2325 return ;
2426 }
25- this . textInput . blur ( ) ;
26- this . textInput . focus ( ) ;
27+ textInputRef . current . blur ( ) ;
28+ textInputRef . current . focus ( ) ;
2729 } ) ;
28- }
29-
30- componentWillUnmount ( ) {
31- if ( ! this . removeVisibilityListener ) {
32- return ;
33- }
34- this . removeVisibilityListener ( ) ;
35- }
3630
37- render ( ) {
38- const isLabeledMultiline = Boolean ( this . props . label . length ) && this . props . multiline ;
39- const labelAnimationStyle = {
40- '--active-label-translate-y' : `${ styleConst . ACTIVE_LABEL_TRANSLATE_Y } px` ,
41- '--active-label-scale' : `${ styleConst . ACTIVE_LABEL_SCALE } ` ,
42- '--label-transition-duration' : `${ styleConst . LABEL_ANIMATION_DURATION } ms` ,
31+ return ( ) => {
32+ if ( ! removeVisibilityListenerRef . current ) return ;
33+ removeVisibilityListenerRef . current ( ) ;
4334 } ;
35+ // eslint-disable-next-line react-hooks/exhaustive-deps
36+ } , [ ] ) ;
37+
38+ const isLabeledMultiline = Boolean ( props . label . length ) && props . multiline ;
39+ const labelAnimationStyle = {
40+ '--active-label-translate-y' : `${ styleConst . ACTIVE_LABEL_TRANSLATE_Y } px` ,
41+ '--active-label-scale' : `${ styleConst . ACTIVE_LABEL_SCALE } ` ,
42+ '--label-transition-duration' : `${ styleConst . LABEL_ANIMATION_DURATION } ms` ,
43+ } ;
4444
45- return (
46- < BaseTextInput
47- // eslint-disable-next-line react/jsx-props-no-spreading
48- { ... this . props }
49- innerRef = { ( el ) => {
50- this . textInput = el ;
51- if ( ! this . props . innerRef ) {
52- return ;
53- }
45+ return (
46+ < BaseTextInput
47+ // eslint-disable-next-line react/jsx-props-no-spreading
48+ { ...props }
49+ innerRef = { ( el ) => {
50+ textInputRef . current = el ;
51+ if ( ! props . innerRef ) {
52+ return ;
53+ }
5454
55- if ( _ . isFunction ( this . props . innerRef ) ) {
56- this . props . innerRef ( el ) ;
57- return ;
58- }
55+ if ( _ . isFunction ( props . innerRef ) ) {
56+ props . innerRef ( el ) ;
57+ return ;
58+ }
5959
60- this . props . innerRef . current = el ;
61- } }
62- inputStyle = { [ styles . baseTextInput , styles . textInputDesktop , isLabeledMultiline ? styles . textInputMultiline : { } , ... this . props . inputStyle ] }
63- textInputContainerStyles = { [ labelAnimationStyle , ...this . props . textInputContainerStyles ] }
64- />
65- ) ;
66- }
60+ // eslint-disable-next-line no-param-reassign
61+ props . innerRef . current = el ;
62+ } }
63+ inputStyle = { [ styles . baseTextInput , styles . textInputDesktop , isLabeledMultiline ? styles . textInputMultiline : { } , ...props . inputStyle ] }
64+ textInputContainerStyles = { [ labelAnimationStyle , ... props . textInputContainerStyles ] }
65+ />
66+ ) ;
6767}
6868
69+ TextInput . displayName = 'TextInput' ;
6970TextInput . propTypes = baseTextInputPropTypes . propTypes ;
7071TextInput . defaultProps = baseTextInputPropTypes . defaultProps ;
7172
0 commit comments