-
Notifications
You must be signed in to change notification settings - Fork 3.1k
/
Copy pathindex.ios.js
141 lines (120 loc) · 4.47 KB
/
index.ios.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
import React, {useEffect, useRef, useMemo, useCallback} from 'react';
import {StyleSheet} from 'react-native';
import PropTypes from 'prop-types';
import _ from 'underscore';
import RNTextInput from '../RNTextInput';
import themeColors from '../../styles/themes/default';
import * as ComposerUtils from '../../libs/ComposerUtils';
const propTypes = {
/** If the input should clear, it actually gets intercepted instead of .clear() */
shouldClear: PropTypes.bool,
/** A ref to forward to the text input */
forwardedRef: PropTypes.func,
/** When the input has cleared whoever owns this input should know about it */
onClear: PropTypes.func,
/** Set focus to this component the first time it renders.
* Override this in case you need to set focus on one field out of many, or when you want to disable autoFocus */
autoFocus: PropTypes.bool,
/** Prevent edits and interactions like focus for this input. */
isDisabled: PropTypes.bool,
/** Selection Object */
selection: PropTypes.shape({
start: PropTypes.number,
end: PropTypes.number,
}),
/** Whether the full composer can be opened */
isFullComposerAvailable: PropTypes.bool,
/** Maximum number of lines in the text input */
maxLines: PropTypes.number,
/** Allow the full composer to be opened */
setIsFullComposerAvailable: PropTypes.func,
/** Whether the composer is full size */
isComposerFullSize: PropTypes.bool,
/** General styles to apply to the text input */
// eslint-disable-next-line react/forbid-prop-types
style: PropTypes.any,
};
const defaultProps = {
shouldClear: false,
onClear: () => {},
autoFocus: false,
isDisabled: false,
forwardedRef: null,
selection: {
start: 0,
end: 0,
},
maxLines: undefined,
isFullComposerAvailable: false,
setIsFullComposerAvailable: () => {},
isComposerFullSize: false,
style: null,
};
function Composer({shouldClear, onClear, isDisabled, maxLines, forwardedRef, isComposerFullSize, setIsFullComposerAvailable, ...props}) {
const textInput = useRef(null);
/**
* Set the TextInput Ref
* @param {Element} el
*/
const setTextInputRef = useCallback((el) => {
textInput.current = el;
if (!_.isFunction(forwardedRef) || textInput.current === null) {
return;
}
// This callback prop is used by the parent component using the constructor to
// get a ref to the inner textInput element e.g. if we do
// <constructor ref={el => this.textInput = el} /> this will not
// return a ref to the component, but rather the HTML element by default
forwardedRef(textInput.current);
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
useEffect(() => {
if (!shouldClear) {
return;
}
textInput.current.clear();
onClear();
}, [shouldClear, onClear]);
/**
* Set maximum number of lines
* @return {Number}
*/
const maxNumberOfLines = useMemo(() => {
if (isComposerFullSize) {
return;
}
return maxLines;
}, [isComposerFullSize, maxLines]);
const styles = useMemo(() => {
StyleSheet.flatten(props.style);
}, [props.style]);
// On native layers we like to have the Text Input not focused so the
// user can read new chats without the keyboard in the way of the view.
// On Android the selection prop is required on the TextInput but this prop has issues on IOS
const propsToPass = _.omit(props, 'selection');
return (
<RNTextInput
autoComplete="off"
placeholderTextColor={themeColors.placeholderText}
ref={setTextInputRef}
onContentSizeChange={(e) => ComposerUtils.updateNumberOfLines({maxLines, isComposerFullSize, isDisabled, setIsFullComposerAvailable}, e)}
rejectResponderTermination={false}
textAlignVertical="center"
smartInsertDelete={false}
maxNumberOfLines={maxNumberOfLines}
style={styles}
/* eslint-disable-next-line react/jsx-props-no-spreading */
{...propsToPass}
editable={!isDisabled}
/>
);
}
Composer.propTypes = propTypes;
Composer.defaultProps = defaultProps;
export default React.forwardRef((props, ref) => (
<Composer
// eslint-disable-next-line react/jsx-props-no-spreading
{...props}
forwardedRef={ref}
/>
));