feat: add possibility to clear invite search field
This commit is contained in:
parent
9c1b802997
commit
d7483f07e3
|
@ -7,6 +7,7 @@ import {
|
|||
Alert,
|
||||
FlatList,
|
||||
KeyboardAvoidingView,
|
||||
Platform,
|
||||
SafeAreaView,
|
||||
TextInput,
|
||||
TouchableOpacity,
|
||||
|
@ -51,6 +52,11 @@ type Props = AbstractProps & {
|
|||
|
||||
type State = AbstractState & {
|
||||
|
||||
/**
|
||||
* State variable to keep track of the search field value.
|
||||
*/
|
||||
fieldValue: string,
|
||||
|
||||
/**
|
||||
* True if a search is in progress, false otherwise.
|
||||
*/
|
||||
|
@ -73,6 +79,7 @@ class AddPeopleDialog extends AbstractAddPeopleDialog<Props, State> {
|
|||
defaultState = {
|
||||
addToCallError: false,
|
||||
addToCallInProgress: false,
|
||||
fieldValue: '',
|
||||
inviteItems: [],
|
||||
searchInprogress: false,
|
||||
selectableItems: []
|
||||
|
@ -101,6 +108,7 @@ class AddPeopleDialog extends AbstractAddPeopleDialog<Props, State> {
|
|||
this._keyExtractor = this._keyExtractor.bind(this);
|
||||
this._renderItem = this._renderItem.bind(this);
|
||||
this._renderSeparator = this._renderSeparator.bind(this);
|
||||
this._onClearField = this._onClearField.bind(this);
|
||||
this._onCloseAddPeopleDialog = this._onCloseAddPeopleDialog.bind(this);
|
||||
this._onInvite = this._onInvite.bind(this);
|
||||
this._onPressItem = this._onPressItem.bind(this);
|
||||
|
@ -168,12 +176,15 @@ class AddPeopleDialog extends AbstractAddPeopleDialog<Props, State> {
|
|||
<TextInput
|
||||
autoCorrect = { false }
|
||||
autoFocus = { true }
|
||||
clearButtonMode = 'always' // iOS only
|
||||
onChangeText = { this._onTypeQuery }
|
||||
placeholder = {
|
||||
this.props.t(`inviteDialog.${placeholderKey}`)
|
||||
}
|
||||
ref = { this._setFieldRef }
|
||||
style = { styles.searchField } />
|
||||
style = { styles.searchField }
|
||||
value = { this.state.fieldValue } />
|
||||
{ this._renderAndroidClearButton() }
|
||||
</View>
|
||||
<FlatList
|
||||
ItemSeparatorComponent = { this._renderSeparator }
|
||||
|
@ -215,6 +226,22 @@ class AddPeopleDialog extends AbstractAddPeopleDialog<Props, State> {
|
|||
return item.type === 'user' ? item.id || item.user_id : item.number;
|
||||
}
|
||||
|
||||
_onClearField: () => void
|
||||
|
||||
/**
|
||||
* Callback to clear the text field.
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
_onClearField() {
|
||||
this.setState({
|
||||
fieldValue: ''
|
||||
});
|
||||
|
||||
// Clear search results
|
||||
this._onTypeQuery('');
|
||||
}
|
||||
|
||||
_onCloseAddPeopleDialog: () => void
|
||||
|
||||
/**
|
||||
|
@ -288,6 +315,10 @@ class AddPeopleDialog extends AbstractAddPeopleDialog<Props, State> {
|
|||
* @returns {void}
|
||||
*/
|
||||
_onTypeQuery(query) {
|
||||
this.setState({
|
||||
fieldValue: query
|
||||
});
|
||||
|
||||
clearTimeout(this.searchTimeout);
|
||||
this.searchTimeout = setTimeout(() => {
|
||||
this.setState({
|
||||
|
@ -342,6 +373,31 @@ class AddPeopleDialog extends AbstractAddPeopleDialog<Props, State> {
|
|||
|
||||
_renderItem: Object => ?React$Element<*>
|
||||
|
||||
/**
|
||||
* Renders a button to clear the text field on Android.
|
||||
*
|
||||
* NOTE: For the best platform experience we use the native solution on iOS.
|
||||
*
|
||||
* @returns {React#Element<*>}
|
||||
*/
|
||||
_renderAndroidClearButton() {
|
||||
if (Platform.OS !== 'android' || !this.state.fieldValue.length) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<TouchableOpacity
|
||||
onPress = { this._onClearField }
|
||||
style = { styles.clearButton }>
|
||||
<View style = { styles.clearIconContainer }>
|
||||
<Icon
|
||||
name = 'close'
|
||||
style = { styles.clearIcon } />
|
||||
</View>
|
||||
</TouchableOpacity>
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders a single item in the {@code FlatList}.
|
||||
*
|
||||
|
|
|
@ -7,6 +7,8 @@ export const DARK_GREY = 'rgb(28, 32, 37)';
|
|||
export const LIGHT_GREY = 'rgb(209, 219, 232)';
|
||||
export const ICON_SIZE = 15;
|
||||
|
||||
const FIELD_COLOR = 'rgb(240, 243, 247)';
|
||||
|
||||
export default {
|
||||
avatar: {
|
||||
backgroundColor: LIGHT_GREY
|
||||
|
@ -21,6 +23,27 @@ export default {
|
|||
flex: 1
|
||||
},
|
||||
|
||||
clearButton: {
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
marginLeft: 5
|
||||
},
|
||||
|
||||
clearIcon: {
|
||||
color: DARK_GREY,
|
||||
fontSize: 18,
|
||||
textAlign: 'center'
|
||||
},
|
||||
|
||||
clearIconContainer: {
|
||||
alignItems: 'center',
|
||||
backgroundColor: FIELD_COLOR,
|
||||
borderRadius: 12,
|
||||
justifyContent: 'center',
|
||||
height: 24,
|
||||
width: 24
|
||||
},
|
||||
|
||||
dialogWrapper: {
|
||||
alignItems: 'stretch',
|
||||
backgroundColor: ColorPalette.white,
|
||||
|
@ -56,7 +79,7 @@ export default {
|
|||
},
|
||||
|
||||
searchField: {
|
||||
backgroundColor: 'rgb(240, 243, 247)',
|
||||
backgroundColor: FIELD_COLOR,
|
||||
borderBottomRightRadius: 10,
|
||||
borderTopRightRadius: 10,
|
||||
color: DARK_GREY,
|
||||
|
@ -86,7 +109,7 @@ export default {
|
|||
|
||||
searchIconWrapper: {
|
||||
alignItems: 'center',
|
||||
backgroundColor: 'rgb(240, 243, 247)',
|
||||
backgroundColor: FIELD_COLOR,
|
||||
borderBottomLeftRadius: 10,
|
||||
borderTopLeftRadius: 10,
|
||||
flexDirection: 'row',
|
||||
|
|
Loading…
Reference in New Issue