UNPKG

3 kBJavaScriptView Raw
1import { Component, createRef } from "react";
2import PropTypes from "prop-types";
3
4import { Animated, Text } from "react-native";
5
6export default class BaseInput extends Component {
7 static propTypes = {
8 label: PropTypes.string,
9 value: PropTypes.string,
10 defaultValue: PropTypes.string,
11 style: PropTypes.any,
12 inputStyle: Text.propTypes?.style,
13 labelStyle: Text.propTypes?.style,
14 easing: PropTypes.func,
15 animationDuration: PropTypes.number,
16 useNativeDriver: PropTypes.bool,
17
18 editable: PropTypes.bool,
19
20 /* those are TextInput props which are overridden
21 * so, i'm calling them manually
22 */
23 onBlur: PropTypes.func,
24 onFocus: PropTypes.func,
25 onChange: PropTypes.func,
26 };
27
28 constructor(props, context) {
29 super(props, context);
30
31 this.input = createRef();
32 this._onLayout = this._onLayout.bind(this);
33 this._onChange = this._onChange.bind(this);
34 this._onBlur = this._onBlur.bind(this);
35 this._onFocus = this._onFocus.bind(this);
36 this.focus = this.focus.bind(this);
37
38 const value = props.value || props.defaultValue;
39
40 this.state = {
41 value,
42 focusedAnim: new Animated.Value(value ? 1 : 0),
43 width: null,
44 };
45 }
46
47 componentDidUpdate() {
48 const newValue = this.props.value;
49 if (this.props.hasOwnProperty("value") && newValue !== this.state.value) {
50 this.setState({
51 value: newValue,
52 });
53
54 // animate input if it's active state has changed with the new value
55 // and input is not focused currently.
56 const isFocused = this.inputRef().isFocused();
57 if (!isFocused) {
58 const isActive = Boolean(newValue);
59 if (isActive !== this.isActive) {
60 this._toggle(isActive);
61 }
62 }
63 }
64 }
65
66 _onLayout(event) {
67 this.setState({
68 width: event.nativeEvent.layout.width,
69 });
70 }
71
72 _onChange(event) {
73 this.setState({
74 value: event.nativeEvent.text,
75 });
76
77 const onChange = this.props.onChange;
78 if (onChange) {
79 onChange(event);
80 }
81 }
82
83 _onBlur(event) {
84 if (!this.state.value) {
85 this._toggle(false);
86 }
87
88 const onBlur = this.props.onBlur;
89 if (onBlur) {
90 onBlur(event);
91 }
92 }
93
94 _onFocus(event) {
95 this._toggle(true);
96
97 const onFocus = this.props.onFocus;
98 if (onFocus) {
99 onFocus(event);
100 }
101 }
102
103 _toggle(isActive) {
104 const { animationDuration, easing, useNativeDriver } = this.props;
105 this.isActive = isActive;
106 Animated.timing(this.state.focusedAnim, {
107 toValue: isActive ? 1 : 0,
108 duration: animationDuration,
109 easing,
110 useNativeDriver: useNativeDriver || false,
111 }).start();
112 }
113
114 // public methods
115
116 inputRef() {
117 return this.input.current;
118 }
119
120 focus() {
121 if (this.props.editable !== false) {
122 this.inputRef().focus();
123 }
124 }
125
126 blur() {
127 this.inputRef().blur();
128 }
129
130 isFocused() {
131 return this.inputRef().isFocused();
132 }
133
134 clear() {
135 this.inputRef().clear();
136 }
137}