MM-18455 Replace search bar component (#3998)
* Initiated basic migration to react-native-elements - Search bar receives all right props without custom animations being necessary - Need to test on different layouts and cases - May be possible to unify android and iOS components. Attempt later * Removing separated android/ios files - Adding implementation of android searchbar - updating test snapshots * WIP: Integrating leftComponent and adding focus animations * Adding animations to left component on focus and blur events * Removing repeated styles and useless props * Updating snapshots * Ensuring clearIcon renders when tapping search suggestions - Also makes sure it prioritizes custom color attributes over default values for the search input * Refactoring styles, removing clear icon animations - Also removed useless ternary operations since the library itself already checks whether the search input is empty * Replacing icon components with props whenever possible - Removing useless styles * memoizing styles, adding default props/values * Memoize searchBarStyle with params * Fixing backgroundColor * Removing minWidth for cancel button * Fixing styling issues on both iOS and android * Updating snapshots post merge * Making sure showCancel can be controlled by props * Updating snapshots * Fix clipped edges on iOS & cancel icon on Android * Fixed radius, memoized styles * Fixing styling issues found on Android Co-authored-by: Elias Nahum <nahumhbl@gmail.com>
This commit is contained in:
parent
55cac2e062
commit
a114b19ecc
23 changed files with 803 additions and 1076 deletions
|
|
@ -20,17 +20,23 @@ exports[`components/emoji_picker/EmojiPicker should match snapshot 1`] = `
|
|||
Array [
|
||||
Object {
|
||||
"backgroundColor": "rgba(61,60,64,0.2)",
|
||||
"height": 50,
|
||||
"paddingLeft": 8,
|
||||
"paddingVertical": 5,
|
||||
},
|
||||
null,
|
||||
]
|
||||
}
|
||||
>
|
||||
<SearchBarIos
|
||||
<Search
|
||||
autoCapitalize="none"
|
||||
backArrowSize={24}
|
||||
backgroundColor="transparent"
|
||||
blurOnSubmit={true}
|
||||
blurOnSubmit={false}
|
||||
cancelTitle="Cancel"
|
||||
containerHeight={40}
|
||||
deleteIconSize={20}
|
||||
editable={true}
|
||||
inputHeight={33}
|
||||
inputStyle={
|
||||
Object {
|
||||
|
|
@ -40,18 +46,20 @@ exports[`components/emoji_picker/EmojiPicker should match snapshot 1`] = `
|
|||
}
|
||||
}
|
||||
keyboardAppearance="light"
|
||||
leftComponent={null}
|
||||
keyboardShouldPersist={false}
|
||||
keyboardType="default"
|
||||
onAnimationComplete={[Function]}
|
||||
onBlur={[Function]}
|
||||
onCancelButtonPress={[Function]}
|
||||
onChangeText={[Function]}
|
||||
onFocus={[Function]}
|
||||
onSearchButtonPress={[Function]}
|
||||
onSelectionChange={[Function]}
|
||||
placeholder="Search"
|
||||
placeholderTextColor="rgba(61,60,64,0.5)"
|
||||
searchIconCollapsedMargin={10}
|
||||
searchIconExpandedMargin={10}
|
||||
returnKeyType="search"
|
||||
searchBarRightMargin={0}
|
||||
searchIconSize={24}
|
||||
showArrow={false}
|
||||
showCancel={true}
|
||||
tintColorDelete="rgba(61,60,64,0.5)"
|
||||
tintColorSearch="rgba(61,60,64,0.8)"
|
||||
titleCancelColor="#3d3c40"
|
||||
|
|
|
|||
|
|
@ -20,7 +20,6 @@ export default class EmojiPicker extends EmojiPickerBase {
|
|||
backgroundColor: theme.centerChannelBg,
|
||||
color: theme.centerChannelColor,
|
||||
fontSize: 13,
|
||||
marginBottom: -3,
|
||||
};
|
||||
|
||||
return (
|
||||
|
|
|
|||
|
|
@ -506,6 +506,12 @@ export const getStyleSheetFromTheme = makeStyleSheetFromTheme((theme) => {
|
|||
searchBar: {
|
||||
backgroundColor: changeOpacity(theme.centerChannelColor, 0.2),
|
||||
paddingVertical: 5,
|
||||
...Platform.select({
|
||||
ios: {
|
||||
paddingLeft: 8,
|
||||
},
|
||||
}),
|
||||
height: 50,
|
||||
},
|
||||
sectionList: {
|
||||
...Platform.select({
|
||||
|
|
|
|||
|
|
@ -1,276 +0,0 @@
|
|||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
import React, {PureComponent} from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import {
|
||||
InteractionManager,
|
||||
Keyboard,
|
||||
TextInput,
|
||||
TouchableWithoutFeedback,
|
||||
StyleSheet,
|
||||
View,
|
||||
} from 'react-native';
|
||||
import Icon from 'react-native-vector-icons/MaterialIcons';
|
||||
|
||||
import CustomPropTypes from 'app/constants/custom_prop_types';
|
||||
import {changeOpacity} from 'app/utils/theme';
|
||||
|
||||
export default class SearchBarAndroid extends PureComponent {
|
||||
static propTypes = {
|
||||
autoFocus: PropTypes.bool,
|
||||
backArrowSize: PropTypes.number,
|
||||
deleteIconSize: PropTypes.number,
|
||||
searchIconSize: PropTypes.number,
|
||||
onCancelButtonPress: PropTypes.func,
|
||||
onChangeText: PropTypes.func,
|
||||
onFocus: PropTypes.func,
|
||||
onBlur: PropTypes.func,
|
||||
onSearchButtonPress: PropTypes.func,
|
||||
onSelectionChange: PropTypes.func,
|
||||
backgroundColor: PropTypes.string,
|
||||
selectionColor: PropTypes.string,
|
||||
placeholderTextColor: PropTypes.string,
|
||||
titleCancelColor: PropTypes.string,
|
||||
tintColorSearch: PropTypes.string,
|
||||
tintColorDelete: PropTypes.string,
|
||||
inputStyle: CustomPropTypes.Style,
|
||||
placeholder: PropTypes.string,
|
||||
returnKeyType: PropTypes.string,
|
||||
keyboardType: PropTypes.string,
|
||||
autoCapitalize: PropTypes.string,
|
||||
inputHeight: PropTypes.number,
|
||||
inputBorderRadius: PropTypes.number,
|
||||
blurOnSubmit: PropTypes.bool,
|
||||
showArrow: PropTypes.bool,
|
||||
value: PropTypes.string,
|
||||
containerStyle: CustomPropTypes.Style,
|
||||
leftComponent: PropTypes.element,
|
||||
keyboardAppearance: PropTypes.string,
|
||||
};
|
||||
|
||||
static defaultProps = {
|
||||
backArrowSize: 24,
|
||||
deleteIconSize: 20,
|
||||
searchIconSize: 24,
|
||||
blurOnSubmit: true,
|
||||
placeholder: 'Search',
|
||||
showCancelButton: true,
|
||||
showArrow: true,
|
||||
placeholderTextColor: changeOpacity('#000', 0.5),
|
||||
containerStyle: {},
|
||||
onSearchButtonPress: () => true,
|
||||
onCancelButtonPress: () => true,
|
||||
onChangeText: () => true,
|
||||
onFocus: () => true,
|
||||
onBlur: () => true,
|
||||
onSelectionChange: () => true,
|
||||
value: '',
|
||||
leftComponent: null,
|
||||
};
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
isFocused: false,
|
||||
refocusInput: true,
|
||||
};
|
||||
}
|
||||
|
||||
setInputRef = (ref) => {
|
||||
this.inputRef = ref;
|
||||
}
|
||||
|
||||
cancel = () => {
|
||||
this.onCancelButtonPress();
|
||||
};
|
||||
|
||||
onBlur = () => {
|
||||
this.props.onBlur();
|
||||
};
|
||||
|
||||
onSearchButtonPress = () => {
|
||||
const {value} = this.props;
|
||||
this.setState({refocusInput: false}, () => {
|
||||
if (value) {
|
||||
this.props.onSearchButtonPress(value);
|
||||
}
|
||||
this.setState({refocusInput: true});
|
||||
});
|
||||
};
|
||||
|
||||
onCancelButtonPress = () => {
|
||||
Keyboard.dismiss();
|
||||
InteractionManager.runAfterInteractions(() => {
|
||||
this.setState({
|
||||
isFocused: false,
|
||||
}, () => {
|
||||
this.props.onCancelButtonPress();
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
onClearPress = () => {
|
||||
this.onChangeText('');
|
||||
};
|
||||
|
||||
onChangeText = (value) => {
|
||||
this.props.onChangeText(value);
|
||||
};
|
||||
|
||||
onSelectionChange = (event) => {
|
||||
this.props.onSelectionChange(event);
|
||||
};
|
||||
|
||||
onFocus = () => {
|
||||
this.setState({isFocused: true});
|
||||
this.props.onFocus();
|
||||
};
|
||||
|
||||
blur = () => {
|
||||
this.inputRef.blur();
|
||||
};
|
||||
|
||||
focus = () => {
|
||||
this.inputRef.focus();
|
||||
};
|
||||
|
||||
render() {
|
||||
const {
|
||||
autoCapitalize,
|
||||
backArrowSize,
|
||||
deleteIconSize,
|
||||
searchIconSize,
|
||||
backgroundColor,
|
||||
blurOnSubmit,
|
||||
inputHeight,
|
||||
inputStyle,
|
||||
keyboardType,
|
||||
placeholder,
|
||||
placeholderTextColor,
|
||||
selectionColor,
|
||||
returnKeyType,
|
||||
titleCancelColor,
|
||||
tintColorDelete,
|
||||
tintColorSearch,
|
||||
containerStyle,
|
||||
value,
|
||||
showArrow,
|
||||
keyboardAppearance,
|
||||
} = this.props;
|
||||
const {isFocused} = this.state;
|
||||
|
||||
const {
|
||||
backgroundColor: bgColor, //eslint-disable-line no-unused-vars
|
||||
...otherStyles
|
||||
} = inputStyle;
|
||||
|
||||
const inputNoBackground = otherStyles;
|
||||
|
||||
let inputColor = styles.searchBarInput.backgroundColor;
|
||||
if (inputStyle) {
|
||||
inputColor = inputStyle.backgroundColor;
|
||||
} else {
|
||||
inputNoBackground.backgroundColor = '#fff';
|
||||
}
|
||||
|
||||
return (
|
||||
<View
|
||||
style={[
|
||||
styles.container,
|
||||
containerStyle,
|
||||
{height: inputHeight},
|
||||
backgroundColor && {backgroundColor},
|
||||
]}
|
||||
>
|
||||
{!isFocused && this.props.leftComponent}
|
||||
<View
|
||||
style={[
|
||||
styles.searchBar,
|
||||
{
|
||||
backgroundColor: inputColor,
|
||||
height: inputHeight,
|
||||
paddingLeft: 7,
|
||||
},
|
||||
]}
|
||||
>
|
||||
{isFocused && showArrow ?
|
||||
<TouchableWithoutFeedback
|
||||
onPress={this.onCancelButtonPress}
|
||||
style={{paddingRight: 15}}
|
||||
>
|
||||
<Icon
|
||||
name='arrow-back'
|
||||
size={backArrowSize}
|
||||
color={titleCancelColor || placeholderTextColor}
|
||||
/>
|
||||
</TouchableWithoutFeedback> :
|
||||
<Icon
|
||||
name={'search'}
|
||||
size={searchIconSize}
|
||||
color={tintColorSearch || placeholderTextColor}
|
||||
/>
|
||||
}
|
||||
<TextInput
|
||||
ref={this.setInputRef}
|
||||
blurOnSubmit={blurOnSubmit}
|
||||
refocusInput={this.state.refocusInput}
|
||||
value={this.props.value}
|
||||
autoCapitalize={autoCapitalize}
|
||||
autoCorrect={false}
|
||||
returnKeyType={returnKeyType || 'search'}
|
||||
keyboardType={keyboardType || 'default'}
|
||||
onFocus={this.onFocus}
|
||||
onBlur={this.onBlur}
|
||||
onChangeText={this.onChangeText}
|
||||
onSubmitEditing={this.onSearchButtonPress}
|
||||
onSelectionChange={this.onSelectionChange}
|
||||
placeholder={placeholder}
|
||||
placeholderTextColor={placeholderTextColor}
|
||||
selectionColor={selectionColor}
|
||||
underlineColorAndroid='transparent'
|
||||
disableFullscreenUI={true}
|
||||
keyboardAppearance={keyboardAppearance}
|
||||
style={[
|
||||
styles.searchBarInput,
|
||||
inputNoBackground,
|
||||
]}
|
||||
/>
|
||||
{isFocused && value ?
|
||||
<TouchableWithoutFeedback onPress={this.onClearPress}>
|
||||
<Icon
|
||||
style={[{paddingRight: 7}]}
|
||||
name='close'
|
||||
size={deleteIconSize}
|
||||
color={tintColorDelete || placeholderTextColor}
|
||||
/>
|
||||
</TouchableWithoutFeedback> : null
|
||||
}
|
||||
</View>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
container: {
|
||||
backgroundColor: 'grey',
|
||||
flexDirection: 'row',
|
||||
justifyContent: 'flex-start',
|
||||
alignItems: 'center',
|
||||
},
|
||||
searchBar: {
|
||||
flex: 1,
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
},
|
||||
searchBarInput: {
|
||||
flex: 1,
|
||||
fontWeight: 'normal',
|
||||
textAlignVertical: 'center',
|
||||
fontSize: 15,
|
||||
includeFontPadding: true,
|
||||
},
|
||||
searchBarBlurredInput: {
|
||||
padding: 0,
|
||||
},
|
||||
});
|
||||
|
|
@ -1,126 +0,0 @@
|
|||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import PropTypes from 'prop-types';
|
||||
import React, {PureComponent} from 'react';
|
||||
import {InteractionManager, Keyboard} from 'react-native';
|
||||
|
||||
import CustomPropTypes from 'app/constants/custom_prop_types';
|
||||
|
||||
import Search from './search_box';
|
||||
|
||||
export default class SearchBarIos extends PureComponent {
|
||||
static propTypes = {
|
||||
onCancelButtonPress: PropTypes.func,
|
||||
onChangeText: PropTypes.func,
|
||||
onFocus: PropTypes.func,
|
||||
onBlur: PropTypes.func,
|
||||
onSearchButtonPress: PropTypes.func,
|
||||
onSelectionChange: PropTypes.func,
|
||||
backgroundColor: PropTypes.string,
|
||||
placeholderTextColor: PropTypes.string,
|
||||
titleCancelColor: PropTypes.string,
|
||||
tintColorSearch: PropTypes.string,
|
||||
tintColorDelete: PropTypes.string,
|
||||
cancelButtonStyle: CustomPropTypes.Style,
|
||||
inputStyle: CustomPropTypes.Style,
|
||||
placeholder: PropTypes.string,
|
||||
cancelTitle: PropTypes.oneOfType([
|
||||
PropTypes.string,
|
||||
PropTypes.object,
|
||||
]),
|
||||
returnKeyType: PropTypes.string,
|
||||
keyboardType: PropTypes.string,
|
||||
autoCapitalize: PropTypes.string,
|
||||
inputHeight: PropTypes.number,
|
||||
inputBorderRadius: PropTypes.number,
|
||||
blurOnSubmit: PropTypes.bool,
|
||||
value: PropTypes.string,
|
||||
leftComponent: PropTypes.element,
|
||||
searchIconCollapsedMargin: PropTypes.number,
|
||||
searchIconExpandedMargin: PropTypes.number,
|
||||
keyboardAppearance: PropTypes.string,
|
||||
onAnimationComplete: PropTypes.func,
|
||||
};
|
||||
|
||||
static defaultProps = {
|
||||
onSearchButtonPress: () => true,
|
||||
onCancelButtonPress: () => true,
|
||||
onChangeText: () => true,
|
||||
onFocus: () => true,
|
||||
onBlur: () => true,
|
||||
onSelectionChange: () => true,
|
||||
blurOnSubmit: true,
|
||||
leftComponent: null,
|
||||
searchIconCollapsedMargin: 10,
|
||||
searchIconExpandedMargin: 10,
|
||||
};
|
||||
|
||||
setSearchRef = (ref) => {
|
||||
this.searchRef = ref;
|
||||
}
|
||||
|
||||
cancel = () => {
|
||||
this.searchRef.onCancel();
|
||||
};
|
||||
|
||||
onBlur = () => {
|
||||
this.props.onBlur();
|
||||
};
|
||||
|
||||
onCancel = () => {
|
||||
Keyboard.dismiss();
|
||||
InteractionManager.runAfterInteractions(() => {
|
||||
this.props.onCancelButtonPress();
|
||||
});
|
||||
};
|
||||
|
||||
onChangeText = (text) => {
|
||||
this.props.onChangeText(text);
|
||||
};
|
||||
|
||||
onDelete = () => {
|
||||
this.props.onChangeText('', true);
|
||||
};
|
||||
|
||||
onFocus = () => {
|
||||
this.props.onFocus();
|
||||
};
|
||||
|
||||
onSearch = (text) => {
|
||||
if (text) {
|
||||
this.props.onSearchButtonPress(text);
|
||||
}
|
||||
};
|
||||
|
||||
onSelectionChange = (event) => {
|
||||
this.props.onSelectionChange(event);
|
||||
};
|
||||
|
||||
blur = () => {
|
||||
this.searchRef.blur();
|
||||
};
|
||||
|
||||
focus = () => {
|
||||
this.searchRef.focus();
|
||||
};
|
||||
|
||||
render() {
|
||||
return (
|
||||
<Search
|
||||
{...this.props}
|
||||
ref={this.setSearchRef}
|
||||
placeholderCollapsedMargin={33}
|
||||
placeholderExpandedMargin={33}
|
||||
shadowVisible={false}
|
||||
onCancel={this.onCancel}
|
||||
onChangeText={this.onChangeText}
|
||||
onFocus={this.onFocus}
|
||||
onBlur={this.onBlur}
|
||||
onSearch={this.onSearch}
|
||||
onSelectionChange={this.onSelectionChange}
|
||||
onDelete={this.onDelete}
|
||||
/>
|
||||
);
|
||||
}
|
||||
}
|
||||
453
app/components/search_bar/search_bar.js
Normal file
453
app/components/search_bar/search_bar.js
Normal file
|
|
@ -0,0 +1,453 @@
|
|||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import React, {PureComponent} from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import {
|
||||
Animated,
|
||||
InteractionManager,
|
||||
Keyboard,
|
||||
TouchableWithoutFeedback,
|
||||
StyleSheet,
|
||||
View,
|
||||
Platform,
|
||||
} from 'react-native';
|
||||
import {intlShape} from 'react-intl';
|
||||
|
||||
import MaterialIcon from 'react-native-vector-icons/MaterialIcons';
|
||||
import EvilIcon from 'react-native-vector-icons/EvilIcons';
|
||||
|
||||
import {SearchBar} from 'react-native-elements';
|
||||
|
||||
import {memoizeResult} from 'mattermost-redux/utils/helpers';
|
||||
|
||||
import CustomPropTypes from 'app/constants/custom_prop_types';
|
||||
|
||||
export default class Search extends PureComponent {
|
||||
static propTypes = {
|
||||
onBlur: PropTypes.func,
|
||||
onFocus: PropTypes.func,
|
||||
onSearchButtonPress: PropTypes.func,
|
||||
onChangeText: PropTypes.func,
|
||||
onCancelButtonPress: PropTypes.func,
|
||||
onSelectionChange: PropTypes.func,
|
||||
backgroundColor: PropTypes.string,
|
||||
placeholderTextColor: PropTypes.string,
|
||||
titleCancelColor: PropTypes.string,
|
||||
tintColorSearch: PropTypes.string,
|
||||
tintColorDelete: PropTypes.string,
|
||||
selectionColor: PropTypes.string,
|
||||
inputStyle: CustomPropTypes.Style,
|
||||
cancelButtonStyle: CustomPropTypes.Style,
|
||||
autoFocus: PropTypes.bool,
|
||||
placeholder: PropTypes.string,
|
||||
cancelTitle: PropTypes.oneOfType([
|
||||
PropTypes.string,
|
||||
PropTypes.object,
|
||||
]),
|
||||
returnKeyType: PropTypes.string,
|
||||
keyboardType: PropTypes.string,
|
||||
autoCapitalize: PropTypes.string,
|
||||
inputHeight: PropTypes.number,
|
||||
editable: PropTypes.bool,
|
||||
blurOnSubmit: PropTypes.bool,
|
||||
keyboardShouldPersist: PropTypes.bool,
|
||||
value: PropTypes.string,
|
||||
keyboardAppearance: PropTypes.string,
|
||||
showArrow: PropTypes.bool,
|
||||
searchBarRightMargin: PropTypes.number,
|
||||
leftComponent: PropTypes.element,
|
||||
searchIconSize: PropTypes.number,
|
||||
backArrowSize: PropTypes.number,
|
||||
deleteIconSize: PropTypes.number,
|
||||
showCancel: PropTypes.bool,
|
||||
containerHeight: PropTypes.number,
|
||||
};
|
||||
|
||||
static contextTypes = {
|
||||
intl: intlShape,
|
||||
};
|
||||
|
||||
static defaultProps = {
|
||||
onSelectionChange: () => true,
|
||||
onBlur: () => true,
|
||||
editable: true,
|
||||
blurOnSubmit: false,
|
||||
keyboardShouldPersist: false,
|
||||
placeholderTextColor: 'grey',
|
||||
value: '',
|
||||
showArrow: false,
|
||||
showCancel: true,
|
||||
searchIconSize: 24,
|
||||
backArrowSize: 24,
|
||||
deleteIconSize: 20,
|
||||
searchBarRightMargin: 0,
|
||||
returnKeyType: 'search',
|
||||
keyboardType: 'default',
|
||||
containerHeight: 40,
|
||||
};
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
leftComponentWidth: 0,
|
||||
};
|
||||
|
||||
this.leftComponentAnimated = new Animated.Value(0);
|
||||
this.searchContainerAnimated = new Animated.Value(0);
|
||||
}
|
||||
|
||||
setSearchContainerRef = (ref) => {
|
||||
this.searchContainerRef = ref;
|
||||
}
|
||||
|
||||
setInputKeywordRef = (ref) => {
|
||||
this.inputKeywordRef = ref;
|
||||
}
|
||||
|
||||
blur = () => {
|
||||
this.inputKeywordRef.blur();
|
||||
};
|
||||
|
||||
focus = () => {
|
||||
this.inputKeywordRef.focus();
|
||||
};
|
||||
|
||||
onBlur = async () => {
|
||||
if (this.props.leftComponent) {
|
||||
await this.collapseAnimation();
|
||||
}
|
||||
this.props.onBlur();
|
||||
};
|
||||
|
||||
onLeftComponentLayout = (event) => {
|
||||
const leftComponentWidth = event.nativeEvent.layout.width;
|
||||
this.setState({leftComponentWidth});
|
||||
};
|
||||
|
||||
onSearch = async () => {
|
||||
if (this.props.keyboardShouldPersist === false) {
|
||||
await Keyboard.dismiss();
|
||||
}
|
||||
|
||||
this.props.onSearchButtonPress(this.props.value);
|
||||
};
|
||||
|
||||
onChangeText = (text) => {
|
||||
if (this.props.onChangeText) {
|
||||
this.props.onChangeText(text);
|
||||
}
|
||||
};
|
||||
|
||||
onFocus = () => {
|
||||
InteractionManager.runAfterInteractions(async () => {
|
||||
if (this.props.leftComponent) {
|
||||
await this.expandAnimation();
|
||||
}
|
||||
|
||||
if (this.props.onFocus) {
|
||||
this.props.onFocus();
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
onClear = () => {
|
||||
this.focus();
|
||||
this.props.onChangeText('', true);
|
||||
};
|
||||
|
||||
onCancel = () => {
|
||||
Keyboard.dismiss();
|
||||
InteractionManager.runAfterInteractions(() => {
|
||||
if (this.props.onCancelButtonPress) {
|
||||
this.props.onCancelButtonPress();
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
onSelectionChange = (event) => {
|
||||
this.props.onSelectionChange(event);
|
||||
};
|
||||
|
||||
expandAnimation = () => {
|
||||
return new Promise((resolve) => {
|
||||
Animated.parallel([
|
||||
Animated.timing(
|
||||
this.leftComponentAnimated,
|
||||
{
|
||||
toValue: 100,
|
||||
duration: 200,
|
||||
},
|
||||
),
|
||||
Animated.timing(
|
||||
this.searchContainerAnimated,
|
||||
{
|
||||
toValue: this.state.leftComponentWidth * -1,
|
||||
duration: 200,
|
||||
},
|
||||
),
|
||||
]).start(resolve);
|
||||
});
|
||||
}
|
||||
|
||||
collapseAnimation = () => {
|
||||
return new Promise((resolve) => {
|
||||
Animated.parallel([
|
||||
Animated.timing(
|
||||
this.leftComponentAnimated,
|
||||
{
|
||||
toValue: 0,
|
||||
duration: 200,
|
||||
},
|
||||
),
|
||||
Animated.timing(
|
||||
this.searchContainerAnimated,
|
||||
{
|
||||
toValue: 0,
|
||||
duration: 200,
|
||||
},
|
||||
),
|
||||
]).start(resolve);
|
||||
});
|
||||
}
|
||||
|
||||
render() {
|
||||
const {backgroundColor, inputHeight, inputStyle, placeholderTextColor, tintColorSearch, cancelButtonStyle, tintColorDelete, titleCancelColor, searchBarRightMargin, containerHeight} = this.props;
|
||||
const searchBarStyle = getSearchBarStyle(
|
||||
backgroundColor,
|
||||
cancelButtonStyle,
|
||||
inputHeight,
|
||||
inputStyle,
|
||||
placeholderTextColor,
|
||||
tintColorDelete,
|
||||
tintColorSearch,
|
||||
titleCancelColor,
|
||||
searchBarRightMargin,
|
||||
containerHeight,
|
||||
);
|
||||
const {intl} = this.context;
|
||||
|
||||
let clearIcon = null;
|
||||
let searchIcon = null;
|
||||
let cancelIcon = null;
|
||||
|
||||
if (Platform.OS === 'ios') {
|
||||
clearIcon = {
|
||||
type: 'ionicon',
|
||||
name: 'ios-close-circle',
|
||||
size: 17,
|
||||
color: searchBarStyle.clearIconColorIos,
|
||||
};
|
||||
|
||||
searchIcon = (
|
||||
<EvilIcon
|
||||
name='search'
|
||||
size={24}
|
||||
style={[
|
||||
styles.fullWidth,
|
||||
searchBarStyle.searchIcon,
|
||||
]}
|
||||
/>
|
||||
);
|
||||
} else {
|
||||
searchIcon = this.props.showArrow ?
|
||||
(
|
||||
<TouchableWithoutFeedback onPress={this.onCancel}>
|
||||
<MaterialIcon
|
||||
name='arrow-back'
|
||||
size={this.props.backArrowSize}
|
||||
color={searchBarStyle.clearIconColorAndroid}
|
||||
/>
|
||||
</TouchableWithoutFeedback>
|
||||
) :
|
||||
{
|
||||
type: 'material',
|
||||
size: this.props.searchIconSize,
|
||||
color: searchBarStyle.searchIconColor,
|
||||
name: 'search',
|
||||
};
|
||||
|
||||
// Making sure the icon won't change depending on whether the input is in focus on Android devices
|
||||
cancelIcon = {
|
||||
type: 'material',
|
||||
size: 25,
|
||||
color: searchBarStyle.clearIconColorAndroid,
|
||||
name: 'arrow-back',
|
||||
};
|
||||
|
||||
clearIcon = {
|
||||
type: 'material',
|
||||
size: this.props.deleteIconSize,
|
||||
color: searchBarStyle.clearIconColorAndroid,
|
||||
name: 'close',
|
||||
};
|
||||
}
|
||||
|
||||
return (
|
||||
<View style={searchBarStyle.container}>
|
||||
{((this.props.leftComponent) ?
|
||||
<Animated.View
|
||||
style={{
|
||||
right: this.leftComponentAnimated,
|
||||
}}
|
||||
onLayout={this.onLeftComponentLayout}
|
||||
>
|
||||
{this.props.leftComponent}
|
||||
</Animated.View> :
|
||||
null
|
||||
)}
|
||||
<Animated.View
|
||||
style={[
|
||||
styles.fullWidth,
|
||||
searchBarStyle.searchBarWrapper,
|
||||
{
|
||||
marginLeft: this.searchContainerAnimated,
|
||||
},
|
||||
]}
|
||||
>
|
||||
<SearchBar
|
||||
ref={this.setInputKeywordRef}
|
||||
containerStyle={{
|
||||
...styles.searchContainer,
|
||||
...styles.fullWidth,
|
||||
...searchBarStyle.searchBarContainer,
|
||||
}}
|
||||
inputContainerStyle={{
|
||||
...styles.inputContainer,
|
||||
...searchBarStyle.inputContainer,
|
||||
}}
|
||||
inputStyle={{
|
||||
...styles.text,
|
||||
...styles.inputMargin,
|
||||
...searchBarStyle.inputStyle,
|
||||
}}
|
||||
leftIconContainerStyle={styles.leftIcon}
|
||||
placeholder={this.props.placeholder || intl.formatMessage({id: 'search_bar.search', defaultMessage: 'Search'})}
|
||||
placeholderTextColor={this.props.placeholderTextColor}
|
||||
selectionColor={this.props.selectionColor}
|
||||
autoCorrect={false}
|
||||
blurOnSubmit={this.props.blurOnSubmit}
|
||||
editable={this.props.editable}
|
||||
cancelButtonTitle={this.props.cancelTitle || intl.formatMessage({id: 'mobile.post.cancel', defaultMessage: 'Cancel'})}
|
||||
cancelButtonProps={{
|
||||
buttonTextStyle: {
|
||||
...styles.text,
|
||||
...searchBarStyle.cancelButtonText,
|
||||
},
|
||||
}}
|
||||
onChangeText={this.onChangeText}
|
||||
onSubmitEditing={this.onSearch}
|
||||
returnKeyType={this.props.returnKeyType}
|
||||
keyboardType={this.props.keyboardType}
|
||||
autoCapitalize={this.props.autoCapitalize}
|
||||
onBlur={this.onBlur}
|
||||
onFocus={this.onFocus}
|
||||
onCancel={this.onCancel}
|
||||
onClear={this.onClear}
|
||||
onSelectionChange={this.onSelectionChange}
|
||||
underlineColorAndroid='transparent'
|
||||
enablesReturnKeyAutomatically={true}
|
||||
keyboardAppearance={this.props.keyboardAppearance}
|
||||
autoFocus={this.props.autoFocus}
|
||||
showCancel={this.props.showCancel}
|
||||
value={this.props.value}
|
||||
platform={Platform.OS}
|
||||
clearIcon={clearIcon}
|
||||
searchIcon={searchIcon}
|
||||
cancelIcon={cancelIcon}
|
||||
/>
|
||||
</Animated.View>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const getSearchBarStyle = memoizeResult((
|
||||
backgroundColor,
|
||||
cancelButtonStyle,
|
||||
inputHeight,
|
||||
inputStyle,
|
||||
placeholderTextColor,
|
||||
tintColorDelete,
|
||||
tintColorSearch,
|
||||
titleCancelColor,
|
||||
searchBarRightMargin,
|
||||
containerHeight,
|
||||
) => ({
|
||||
cancelButtonText: {
|
||||
...cancelButtonStyle,
|
||||
color: titleCancelColor,
|
||||
},
|
||||
container: {
|
||||
flexDirection: 'row',
|
||||
justifyContent: 'flex-start',
|
||||
alignItems: 'center',
|
||||
height: containerHeight,
|
||||
flex: 1,
|
||||
},
|
||||
clearIconColorIos: tintColorDelete || styles.defaultColor.color,
|
||||
clearIconColorAndroid: titleCancelColor || placeholderTextColor,
|
||||
inputStyle: {
|
||||
...inputStyle,
|
||||
backgroundColor: 'transparent',
|
||||
height: inputHeight,
|
||||
},
|
||||
inputContainer: {
|
||||
backgroundColor: inputStyle.backgroundColor,
|
||||
height: inputHeight,
|
||||
},
|
||||
searchBarWrapper: {
|
||||
marginRight: searchBarRightMargin,
|
||||
height: Platform.select({
|
||||
ios: inputHeight || containerHeight - 10,
|
||||
android: inputHeight,
|
||||
}),
|
||||
},
|
||||
searchBarContainer: {
|
||||
backgroundColor,
|
||||
},
|
||||
searchIcon: {
|
||||
color: tintColorSearch || placeholderTextColor,
|
||||
top: 10,
|
||||
},
|
||||
searchIconColor: tintColorSearch || placeholderTextColor,
|
||||
}));
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
defaultColor: {
|
||||
color: 'grey',
|
||||
},
|
||||
fullWidth: {
|
||||
flex: 1,
|
||||
},
|
||||
inputContainer: {
|
||||
marginLeft: 0,
|
||||
borderRadius: Platform.select({
|
||||
ios: 2,
|
||||
android: 0,
|
||||
}),
|
||||
},
|
||||
inputMargin: {
|
||||
marginLeft: 4,
|
||||
paddingTop: 0,
|
||||
marginTop: Platform.select({
|
||||
ios: 0,
|
||||
android: 8,
|
||||
}),
|
||||
},
|
||||
leftIcon: {
|
||||
marginLeft: 4,
|
||||
},
|
||||
searchContainer: {
|
||||
paddingTop: 0,
|
||||
paddingBottom: 0,
|
||||
marginLeft: 0,
|
||||
},
|
||||
text: {
|
||||
fontSize: Platform.select({
|
||||
ios: 14,
|
||||
android: 15,
|
||||
}),
|
||||
color: '#fff',
|
||||
},
|
||||
});
|
||||
|
|
@ -1,578 +0,0 @@
|
|||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import React, {Component} from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import {
|
||||
Animated,
|
||||
Dimensions,
|
||||
InteractionManager,
|
||||
Keyboard,
|
||||
Text,
|
||||
TextInput,
|
||||
TouchableWithoutFeedback,
|
||||
StyleSheet,
|
||||
View,
|
||||
} from 'react-native';
|
||||
import EvilIcon from 'react-native-vector-icons/EvilIcons';
|
||||
import IonIcon from 'react-native-vector-icons/Ionicons';
|
||||
|
||||
import CustomPropTypes from 'app/constants/custom_prop_types';
|
||||
import {emptyFunction} from 'app/utils/general';
|
||||
|
||||
const AnimatedTextInput = Animated.createAnimatedComponent(TextInput);
|
||||
const AnimatedIonIcon = Animated.createAnimatedComponent(IonIcon);
|
||||
const AnimatedEvilcon = Animated.createAnimatedComponent(EvilIcon);
|
||||
const containerHeight = 40;
|
||||
const middleHeight = 20;
|
||||
|
||||
export default class Search extends Component {
|
||||
static propTypes = {
|
||||
onBlur: PropTypes.func,
|
||||
onFocus: PropTypes.func,
|
||||
onSearch: PropTypes.func,
|
||||
onChangeText: PropTypes.func,
|
||||
onCancel: PropTypes.func,
|
||||
onDelete: PropTypes.func,
|
||||
onSelectionChange: PropTypes.func,
|
||||
backgroundColor: PropTypes.string,
|
||||
placeholderTextColor: PropTypes.string,
|
||||
titleCancelColor: PropTypes.string,
|
||||
tintColorSearch: PropTypes.string,
|
||||
tintColorDelete: PropTypes.string,
|
||||
selectionColor: PropTypes.string,
|
||||
inputStyle: CustomPropTypes.Style,
|
||||
onLayout: PropTypes.func,
|
||||
cancelButtonStyle: CustomPropTypes.Style,
|
||||
autoFocus: PropTypes.bool,
|
||||
placeholder: PropTypes.string,
|
||||
cancelTitle: PropTypes.oneOfType([
|
||||
PropTypes.string,
|
||||
PropTypes.object,
|
||||
]),
|
||||
iconDelete: PropTypes.object,
|
||||
iconSearch: PropTypes.object,
|
||||
returnKeyType: PropTypes.string,
|
||||
keyboardType: PropTypes.string,
|
||||
autoCapitalize: PropTypes.string,
|
||||
inputHeight: PropTypes.number,
|
||||
inputBorderRadius: PropTypes.number,
|
||||
contentWidth: PropTypes.number,
|
||||
middleWidth: PropTypes.number,
|
||||
editable: PropTypes.bool,
|
||||
blurOnSubmit: PropTypes.bool,
|
||||
keyboardShouldPersist: PropTypes.bool,
|
||||
value: PropTypes.string,
|
||||
positionRightDelete: PropTypes.number,
|
||||
searchIconCollapsedMargin: PropTypes.number,
|
||||
searchIconExpandedMargin: PropTypes.number,
|
||||
placeholderCollapsedMargin: PropTypes.number,
|
||||
placeholderExpandedMargin: PropTypes.number,
|
||||
shadowOffsetHeightCollapsed: PropTypes.number,
|
||||
shadowOffsetHeightExpanded: PropTypes.number,
|
||||
shadowOffsetWidth: PropTypes.number,
|
||||
shadowColor: PropTypes.string,
|
||||
shadowOpacityCollapsed: PropTypes.number,
|
||||
shadowOpacityExpanded: PropTypes.number,
|
||||
shadowRadius: PropTypes.number,
|
||||
shadowVisible: PropTypes.bool,
|
||||
leftComponent: PropTypes.element,
|
||||
inputCollapsedMargin: PropTypes.number,
|
||||
keyboardAppearance: PropTypes.string,
|
||||
onAnimationComplete: PropTypes.func,
|
||||
};
|
||||
|
||||
static defaultProps = {
|
||||
onSelectionChange: () => true,
|
||||
onBlur: () => true,
|
||||
editable: true,
|
||||
blurOnSubmit: false,
|
||||
keyboardShouldPersist: false,
|
||||
placeholderTextColor: 'grey',
|
||||
searchIconCollapsedMargin: 25,
|
||||
searchIconExpandedMargin: 10,
|
||||
placeholderCollapsedMargin: 15,
|
||||
placeholderExpandedMargin: 20,
|
||||
shadowOffsetWidth: 0,
|
||||
shadowOffsetHeightCollapsed: 2,
|
||||
shadowOffsetHeightExpanded: 4,
|
||||
shadowColor: '#000',
|
||||
shadowOpacityCollapsed: 0.12,
|
||||
shadowOpacityExpanded: 0.24,
|
||||
shadowRadius: 4,
|
||||
shadowVisible: false,
|
||||
value: '',
|
||||
leftComponent: null,
|
||||
inputCollapsedMargin: 10,
|
||||
onAnimationComplete: emptyFunction,
|
||||
};
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
this.state = {
|
||||
expanded: false,
|
||||
leftComponentWidth: 0,
|
||||
};
|
||||
const {width} = Dimensions.get('window');
|
||||
this.contentWidth = width;
|
||||
this.middleWidth = width / 2;
|
||||
|
||||
this.iconSearchAnimated = new Animated.Value(this.props.searchIconCollapsedMargin);
|
||||
this.iconDeleteAnimated = new Animated.Value(0);
|
||||
this.leftComponentAnimated = new Animated.Value(0);
|
||||
this.inputFocusAnimated = new Animated.Value(0);
|
||||
this.inputFocusWidthAnimated = new Animated.Value(this.contentWidth - 10);
|
||||
this.inputFocusPlaceholderAnimated = new Animated.Value(this.props.placeholderCollapsedMargin);
|
||||
this.btnCancelAnimated = new Animated.Value(this.contentWidth);
|
||||
this.shadowOpacityAnimated = new Animated.Value(this.props.shadowOpacityCollapsed);
|
||||
|
||||
this.placeholder = this.props.placeholder || 'Search';
|
||||
this.cancelTitle = this.props.cancelTitle || 'Cancel';
|
||||
this.shadowHeight = this.props.shadowOffsetHeightCollapsed;
|
||||
}
|
||||
|
||||
componentDidUpdate(prevProps) {
|
||||
if (this.props.value !== prevProps.value) {
|
||||
if (this.props.value) {
|
||||
this.iconDeleteAnimated = new Animated.Value(1);
|
||||
} else {
|
||||
this.iconDeleteAnimated = new Animated.Value(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
setSearchContainerRef = (ref) => {
|
||||
this.searchContainerRef = ref;
|
||||
}
|
||||
|
||||
setInputKeywordRef = (ref) => {
|
||||
this.inputKeywordRef = ref;
|
||||
}
|
||||
|
||||
blur = () => {
|
||||
this.inputKeywordRef.getNode().blur();
|
||||
this.setState({expanded: false});
|
||||
this.collapseAnimation();
|
||||
};
|
||||
|
||||
focus = () => {
|
||||
InteractionManager.runAfterInteractions(() => {
|
||||
const input = this.inputKeywordRef.getNode();
|
||||
if (!input.isFocused()) {
|
||||
input.focus();
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
onBlur = () => {
|
||||
this.props.onBlur();
|
||||
};
|
||||
|
||||
onLayout = (event) => {
|
||||
const contentWidth = event.nativeEvent.layout.width;
|
||||
this.contentWidth = contentWidth;
|
||||
this.middleWidth = contentWidth / 2;
|
||||
if (this.state.expanded) {
|
||||
this.expandAnimation();
|
||||
} else {
|
||||
this.collapseAnimation();
|
||||
}
|
||||
};
|
||||
|
||||
onLeftComponentLayout = (event) => {
|
||||
const leftComponentWidth = event.nativeEvent.layout.width;
|
||||
this.setState({leftComponentWidth});
|
||||
};
|
||||
|
||||
onSearch = async () => {
|
||||
if (this.props.keyboardShouldPersist === false) {
|
||||
await Keyboard.dismiss();
|
||||
}
|
||||
|
||||
if (this.props.onSearch) {
|
||||
this.props.onSearch(this.props.value);
|
||||
}
|
||||
};
|
||||
|
||||
onChangeText = (text) => {
|
||||
Animated.timing(
|
||||
this.iconDeleteAnimated,
|
||||
{
|
||||
toValue: (text.length > 0) ? 1 : 0,
|
||||
duration: 200,
|
||||
useNativeDriver: true,
|
||||
},
|
||||
).start();
|
||||
|
||||
if (this.props.onChangeText) {
|
||||
this.props.onChangeText(text);
|
||||
}
|
||||
};
|
||||
|
||||
onFocus = () => {
|
||||
InteractionManager.runAfterInteractions(async () => {
|
||||
this.setState({expanded: true});
|
||||
await this.expandAnimation();
|
||||
|
||||
if (this.props.onFocus) {
|
||||
this.props.onFocus(this.props.value);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
onDelete = () => {
|
||||
Animated.timing(
|
||||
this.iconDeleteAnimated,
|
||||
{
|
||||
toValue: 0,
|
||||
duration: 200,
|
||||
useNativeDriver: true,
|
||||
},
|
||||
).start();
|
||||
this.focus();
|
||||
|
||||
if (this.props.onDelete) {
|
||||
this.props.onDelete();
|
||||
}
|
||||
};
|
||||
|
||||
onCancel = async () => {
|
||||
this.setState({expanded: false});
|
||||
await this.collapseAnimation(true);
|
||||
|
||||
if (this.props.onCancel) {
|
||||
this.props.onCancel();
|
||||
}
|
||||
};
|
||||
|
||||
onSelectionChange = (event) => {
|
||||
this.props.onSelectionChange(event);
|
||||
};
|
||||
|
||||
expandAnimation = () => {
|
||||
return new Promise((resolve) => {
|
||||
Animated.parallel([
|
||||
Animated.timing(
|
||||
this.inputFocusWidthAnimated,
|
||||
{
|
||||
toValue: this.contentWidth - 90,
|
||||
duration: 200,
|
||||
},
|
||||
),
|
||||
Animated.timing(
|
||||
this.inputFocusAnimated,
|
||||
{
|
||||
toValue: this.state.leftComponentWidth,
|
||||
duration: 200,
|
||||
},
|
||||
),
|
||||
Animated.timing(
|
||||
this.leftComponentAnimated,
|
||||
{
|
||||
toValue: this.contentWidth,
|
||||
duration: 200,
|
||||
},
|
||||
),
|
||||
Animated.timing(
|
||||
this.btnCancelAnimated,
|
||||
{
|
||||
toValue: this.state.leftComponentWidth ? 15 - this.state.leftComponentWidth : 5,
|
||||
duration: 200,
|
||||
},
|
||||
),
|
||||
Animated.timing(
|
||||
this.inputFocusPlaceholderAnimated,
|
||||
{
|
||||
toValue: this.props.placeholderExpandedMargin,
|
||||
duration: 200,
|
||||
},
|
||||
),
|
||||
Animated.timing(
|
||||
this.iconSearchAnimated,
|
||||
{
|
||||
toValue: this.props.searchIconExpandedMargin,
|
||||
duration: 200,
|
||||
},
|
||||
),
|
||||
Animated.timing(
|
||||
this.iconDeleteAnimated,
|
||||
{
|
||||
toValue: (this.props.value.length > 0) ? 1 : 0,
|
||||
duration: 200,
|
||||
useNativeDriver: true,
|
||||
},
|
||||
),
|
||||
Animated.timing(
|
||||
this.shadowOpacityAnimated,
|
||||
{
|
||||
toValue: this.props.shadowOpacityExpanded,
|
||||
duration: 200,
|
||||
useNativeDriver: true,
|
||||
},
|
||||
),
|
||||
]).start();
|
||||
this.shadowHeight = this.props.shadowOffsetHeightExpanded;
|
||||
resolve();
|
||||
});
|
||||
};
|
||||
|
||||
collapseAnimation = (isForceAnim = false) => {
|
||||
return new Promise((resolve) => {
|
||||
Animated.parallel([
|
||||
((this.props.keyboardShouldPersist === false) ? Keyboard.dismiss() : null),
|
||||
Animated.timing(
|
||||
this.inputFocusWidthAnimated,
|
||||
{
|
||||
toValue: this.contentWidth - this.state.leftComponentWidth - this.props.inputCollapsedMargin,
|
||||
duration: 200,
|
||||
},
|
||||
),
|
||||
Animated.timing(
|
||||
this.inputFocusAnimated,
|
||||
{
|
||||
toValue: 0,
|
||||
duration: 200,
|
||||
},
|
||||
),
|
||||
Animated.timing(
|
||||
this.leftComponentAnimated,
|
||||
{
|
||||
toValue: 0,
|
||||
duration: 200,
|
||||
},
|
||||
),
|
||||
Animated.timing(
|
||||
this.btnCancelAnimated,
|
||||
{
|
||||
toValue: this.contentWidth,
|
||||
duration: 200,
|
||||
},
|
||||
),
|
||||
((this.props.keyboardShouldPersist === false) ?
|
||||
Animated.timing(
|
||||
this.inputFocusPlaceholderAnimated,
|
||||
{
|
||||
toValue: this.props.placeholderCollapsedMargin,
|
||||
duration: 200,
|
||||
},
|
||||
) : null),
|
||||
((this.props.keyboardShouldPersist === false || isForceAnim === true) ?
|
||||
Animated.timing(
|
||||
this.iconSearchAnimated,
|
||||
{
|
||||
toValue: (this.props.searchIconCollapsedMargin + this.state.leftComponentWidth),
|
||||
duration: 200,
|
||||
},
|
||||
) : null),
|
||||
Animated.timing(
|
||||
this.iconDeleteAnimated,
|
||||
{
|
||||
toValue: 0,
|
||||
duration: 200,
|
||||
useNativeDriver: true,
|
||||
},
|
||||
),
|
||||
Animated.timing(
|
||||
this.shadowOpacityAnimated,
|
||||
{
|
||||
toValue: this.props.shadowOpacityCollapsed,
|
||||
duration: 200,
|
||||
useNativeDriver: true,
|
||||
},
|
||||
),
|
||||
]).start(({finished}) => this.props.onAnimationComplete(finished));
|
||||
this.shadowHeight = this.props.shadowOffsetHeightCollapsed;
|
||||
resolve();
|
||||
});
|
||||
};
|
||||
|
||||
render() {
|
||||
const {backgroundColor, ...restOfInputPropStyles} = this.props.inputStyle;
|
||||
|
||||
return (
|
||||
<Animated.View
|
||||
ref={this.setSearchContainerRef}
|
||||
style={[
|
||||
styles.container,
|
||||
this.props.backgroundColor && {backgroundColor: this.props.backgroundColor},
|
||||
this.state.leftComponentWidth && {padding: 0},
|
||||
]}
|
||||
onLayout={this.onLayout}
|
||||
>
|
||||
{((this.props.leftComponent) ?
|
||||
<Animated.View
|
||||
style={{right: this.leftComponentAnimated}}
|
||||
onLayout={this.onLeftComponentLayout}
|
||||
>
|
||||
{this.props.leftComponent}
|
||||
</Animated.View> :
|
||||
null
|
||||
)}
|
||||
<Animated.View style={{backgroundColor, right: this.inputFocusAnimated, borderRadius: 2}}>
|
||||
<AnimatedTextInput
|
||||
ref={this.setInputKeywordRef}
|
||||
style={[
|
||||
styles.input,
|
||||
this.props.placeholderTextColor && {color: this.props.placeholderTextColor},
|
||||
this.props.inputHeight && {height: this.props.inputHeight},
|
||||
this.props.inputBorderRadius && {borderRadius: this.props.inputBorderRadius},
|
||||
{
|
||||
width: this.inputFocusWidthAnimated,
|
||||
paddingLeft: this.inputFocusPlaceholderAnimated,
|
||||
},
|
||||
restOfInputPropStyles,
|
||||
this.props.shadowVisible && {
|
||||
shadowOffset: {width: this.props.shadowOffsetWidth, height: this.shadowHeight},
|
||||
shadowColor: this.props.shadowColor,
|
||||
shadowOpacity: this.shadowOpacityAnimated,
|
||||
shadowRadius: this.props.shadowRadius,
|
||||
},
|
||||
]}
|
||||
autoFocus={this.props.autoFocus}
|
||||
editable={this.props.editable}
|
||||
value={this.props.value}
|
||||
onChangeText={this.onChangeText}
|
||||
placeholder={this.placeholder}
|
||||
placeholderTextColor={this.props.placeholderTextColor}
|
||||
selectionColor={this.props.selectionColor}
|
||||
onSubmitEditing={this.onSearch}
|
||||
onSelectionChange={this.onSelectionChange}
|
||||
autoCorrect={false}
|
||||
blurOnSubmit={this.props.blurOnSubmit}
|
||||
returnKeyType={this.props.returnKeyType || 'search'}
|
||||
keyboardType={this.props.keyboardType || 'default'}
|
||||
autoCapitalize={this.props.autoCapitalize}
|
||||
onBlur={this.onBlur}
|
||||
onFocus={this.onFocus}
|
||||
underlineColorAndroid='transparent'
|
||||
enablesReturnKeyAutomatically={true}
|
||||
keyboardAppearance={this.props.keyboardAppearance}
|
||||
/>
|
||||
</Animated.View>
|
||||
<TouchableWithoutFeedback onPress={this.onFocus}>
|
||||
{((this.props.iconSearch) ?
|
||||
<Animated.View
|
||||
style={[
|
||||
styles.iconSearch,
|
||||
{left: this.iconSearchAnimated},
|
||||
]}
|
||||
>
|
||||
{this.props.iconSearch}
|
||||
</Animated.View> :
|
||||
<AnimatedEvilcon
|
||||
name='search'
|
||||
size={24}
|
||||
style={[
|
||||
styles.iconSearch,
|
||||
styles.iconSearchDefault,
|
||||
this.props.tintColorSearch && {color: this.props.tintColorSearch},
|
||||
{
|
||||
left: this.iconSearchAnimated,
|
||||
top: middleHeight - 10,
|
||||
},
|
||||
]}
|
||||
/>
|
||||
)}
|
||||
</TouchableWithoutFeedback>
|
||||
<TouchableWithoutFeedback onPress={this.onDelete}>
|
||||
{((this.props.iconDelete) ?
|
||||
<Animated.View
|
||||
style={[
|
||||
styles.iconDelete,
|
||||
this.props.positionRightDelete && {right: this.props.positionRightDelete},
|
||||
{opacity: this.iconDeleteAnimated},
|
||||
]}
|
||||
>
|
||||
{this.props.iconDelete}
|
||||
</Animated.View> :
|
||||
<View style={[styles.iconDelete, this.props.inputHeight && {height: this.props.inputHeight}]}>
|
||||
<AnimatedIonIcon
|
||||
name='ios-close-circle'
|
||||
size={17}
|
||||
style={[
|
||||
styles.iconDeleteDefault,
|
||||
this.props.tintColorDelete && {color: this.props.tintColorDelete},
|
||||
this.props.positionRightDelete && {right: this.props.positionRightDelete},
|
||||
{
|
||||
opacity: this.iconDeleteAnimated,
|
||||
},
|
||||
]}
|
||||
/>
|
||||
</View>
|
||||
)}
|
||||
</TouchableWithoutFeedback>
|
||||
<TouchableWithoutFeedback onPress={this.onCancel}>
|
||||
<Animated.View
|
||||
style={[
|
||||
styles.cancelButton,
|
||||
this.props.cancelButtonStyle && this.props.cancelButtonStyle,
|
||||
{left: this.btnCancelAnimated},
|
||||
]}
|
||||
>
|
||||
<Text
|
||||
style={[
|
||||
styles.cancelButtonText,
|
||||
this.props.titleCancelColor && {color: this.props.titleCancelColor},
|
||||
this.props.cancelButtonStyle && this.props.cancelButtonStyle,
|
||||
]}
|
||||
>
|
||||
{this.cancelTitle}
|
||||
</Text>
|
||||
</Animated.View>
|
||||
</TouchableWithoutFeedback>
|
||||
</Animated.View>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
container: {
|
||||
backgroundColor: 'grey',
|
||||
height: containerHeight,
|
||||
flexDirection: 'row',
|
||||
justifyContent: 'flex-start',
|
||||
alignItems: 'center',
|
||||
padding: 5,
|
||||
},
|
||||
input: {
|
||||
height: containerHeight - 10,
|
||||
paddingTop: 7,
|
||||
paddingBottom: 5,
|
||||
paddingRight: 32,
|
||||
borderColor: '#444',
|
||||
borderRadius: 5,
|
||||
fontSize: 15,
|
||||
},
|
||||
iconSearch: {
|
||||
flex: 1,
|
||||
position: 'absolute',
|
||||
},
|
||||
iconSearchDefault: {
|
||||
color: 'grey',
|
||||
},
|
||||
iconDelete: {
|
||||
alignItems: 'flex-start',
|
||||
justifyContent: 'center',
|
||||
position: 'absolute',
|
||||
paddingLeft: 1,
|
||||
paddingTop: 3,
|
||||
right: 80,
|
||||
width: 25,
|
||||
},
|
||||
iconDeleteDefault: {
|
||||
color: 'grey',
|
||||
},
|
||||
cancelButton: {
|
||||
flex: 1,
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
backgroundColor: 'transparent',
|
||||
minWidth: 75,
|
||||
height: 50,
|
||||
},
|
||||
cancelButtonText: {
|
||||
fontSize: 14,
|
||||
color: '#fff',
|
||||
},
|
||||
});
|
||||
|
|
@ -59,7 +59,7 @@ export default class ChannelsList extends PureComponent {
|
|||
|
||||
cancelSearch = () => {
|
||||
if (this.searchBarRef) {
|
||||
this.searchBarRef.cancel();
|
||||
this.searchBarRef.onCancel();
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -124,11 +124,6 @@ export default class ChannelsList extends PureComponent {
|
|||
backgroundColor: changeOpacity(theme.sidebarHeaderTextColor, 0.2),
|
||||
color: theme.sidebarHeaderTextColor,
|
||||
fontSize: 15,
|
||||
...Platform.select({
|
||||
android: {
|
||||
marginBottom: -5,
|
||||
},
|
||||
}),
|
||||
};
|
||||
|
||||
const title = (
|
||||
|
|
@ -137,7 +132,6 @@ export default class ChannelsList extends PureComponent {
|
|||
ref={this.setSearchBarRef}
|
||||
placeholder={intl.formatMessage({id: 'mobile.channel_drawer.search', defaultMessage: 'Jump to...'})}
|
||||
cancelTitle={intl.formatMessage({id: 'mobile.post.cancel', defaultMessage: 'Cancel'})}
|
||||
inputCollapsedMargin={0}
|
||||
backgroundColor='transparent'
|
||||
inputHeight={33}
|
||||
inputStyle={searchBarInput}
|
||||
|
|
@ -150,16 +144,15 @@ export default class ChannelsList extends PureComponent {
|
|||
onCancelButtonPress={this.onSearchCancel}
|
||||
onChangeText={this.onSearch}
|
||||
onFocus={this.onSearchFocused}
|
||||
searchIconCollapsedMargin={5}
|
||||
searchIconExpandedMargin={5}
|
||||
keyboardAppearance={getKeyboardAppearanceFromTheme(theme)}
|
||||
value={term}
|
||||
showCancel={Platform.OS === 'android'}
|
||||
leftComponentWidth={67}
|
||||
leftComponent={(
|
||||
<SwitchTeamsButton
|
||||
onShowTeams={onShowTeams}
|
||||
/>
|
||||
)}
|
||||
positionRightDelete={5}
|
||||
/>
|
||||
</View>
|
||||
);
|
||||
|
|
@ -228,10 +221,11 @@ const getStyleSheet = makeStyleSheetFromTheme((theme) => {
|
|||
},
|
||||
searchContainer: {
|
||||
flex: 1,
|
||||
paddingRight: 10,
|
||||
flexDirection: 'row',
|
||||
...Platform.select({
|
||||
android: {
|
||||
marginBottom: 1,
|
||||
paddingRight: 17,
|
||||
},
|
||||
ios: {
|
||||
marginBottom: 3,
|
||||
|
|
|
|||
|
|
@ -306,11 +306,6 @@ export default class ChannelAddMembers extends PureComponent {
|
|||
backgroundColor: changeOpacity(theme.centerChannelColor, 0.2),
|
||||
color: theme.centerChannelColor,
|
||||
fontSize: 15,
|
||||
...Platform.select({
|
||||
android: {
|
||||
marginBottom: -5,
|
||||
},
|
||||
}),
|
||||
};
|
||||
|
||||
let data;
|
||||
|
|
@ -385,6 +380,12 @@ const getStyleFromTheme = makeStyleSheetFromTheme((theme) => {
|
|||
},
|
||||
searchBar: {
|
||||
marginVertical: 5,
|
||||
height: 38,
|
||||
...Platform.select({
|
||||
ios: {
|
||||
paddingLeft: 8,
|
||||
},
|
||||
}),
|
||||
},
|
||||
loadingContainer: {
|
||||
alignItems: 'center',
|
||||
|
|
|
|||
|
|
@ -7,17 +7,23 @@ exports[`ChannelMembers should match snapshot 1`] = `
|
|||
style={
|
||||
Array [
|
||||
Object {
|
||||
"height": 38,
|
||||
"marginVertical": 5,
|
||||
"paddingLeft": 8,
|
||||
},
|
||||
null,
|
||||
]
|
||||
}
|
||||
>
|
||||
<SearchBarIos
|
||||
<Search
|
||||
autoCapitalize="none"
|
||||
backArrowSize={24}
|
||||
backgroundColor="transparent"
|
||||
blurOnSubmit={true}
|
||||
blurOnSubmit={false}
|
||||
cancelTitle="Cancel"
|
||||
containerHeight={40}
|
||||
deleteIconSize={20}
|
||||
editable={true}
|
||||
inputHeight={33}
|
||||
inputStyle={
|
||||
Object {
|
||||
|
|
@ -27,17 +33,20 @@ exports[`ChannelMembers should match snapshot 1`] = `
|
|||
}
|
||||
}
|
||||
keyboardAppearance="light"
|
||||
leftComponent={null}
|
||||
keyboardShouldPersist={false}
|
||||
keyboardType="default"
|
||||
onBlur={[Function]}
|
||||
onCancelButtonPress={[Function]}
|
||||
onChangeText={[Function]}
|
||||
onFocus={[Function]}
|
||||
onSearchButtonPress={[Function]}
|
||||
onSelectionChange={[Function]}
|
||||
placeholder="Search"
|
||||
placeholderTextColor="rgba(61,60,64,0.5)"
|
||||
searchIconCollapsedMargin={10}
|
||||
searchIconExpandedMargin={10}
|
||||
returnKeyType="search"
|
||||
searchBarRightMargin={0}
|
||||
searchIconSize={24}
|
||||
showArrow={false}
|
||||
showCancel={true}
|
||||
tintColorDelete="rgba(61,60,64,0.5)"
|
||||
tintColorSearch="rgba(61,60,64,0.5)"
|
||||
titleCancelColor="#3d3c40"
|
||||
|
|
|
|||
|
|
@ -338,11 +338,7 @@ export default class ChannelMembers extends PureComponent {
|
|||
backgroundColor: changeOpacity(theme.centerChannelColor, 0.2),
|
||||
color: theme.centerChannelColor,
|
||||
fontSize: 15,
|
||||
...Platform.select({
|
||||
android: {
|
||||
marginBottom: -5,
|
||||
},
|
||||
}),
|
||||
|
||||
};
|
||||
|
||||
let data;
|
||||
|
|
@ -413,6 +409,12 @@ const getStyleFromTheme = makeStyleSheetFromTheme((theme) => {
|
|||
},
|
||||
searchBar: {
|
||||
marginVertical: 5,
|
||||
height: 38,
|
||||
...Platform.select({
|
||||
ios: {
|
||||
paddingLeft: 8,
|
||||
},
|
||||
}),
|
||||
},
|
||||
loadingContainer: {
|
||||
alignItems: 'center',
|
||||
|
|
|
|||
|
|
@ -3,6 +3,8 @@
|
|||
|
||||
import React from 'react';
|
||||
import {Platform} from 'react-native';
|
||||
import {ThemeProvider} from 'react-native-elements';
|
||||
|
||||
import {Navigation} from 'react-native-navigation';
|
||||
import {gestureHandlerRootHOC} from 'react-native-gesture-handler';
|
||||
|
||||
|
|
@ -16,9 +18,11 @@ export function registerScreens(store, Provider) {
|
|||
|
||||
const wrapper = (Comp) => (props) => ( // eslint-disable-line react/display-name
|
||||
<Provider store={store}>
|
||||
<Root>
|
||||
<Comp {...props}/>
|
||||
</Root>
|
||||
<ThemeProvider>
|
||||
<Root>
|
||||
<Comp {...props}/>
|
||||
</Root>
|
||||
</ThemeProvider>
|
||||
</Provider>
|
||||
);
|
||||
|
||||
|
|
|
|||
|
|
@ -8,16 +8,22 @@ exports[`MoreChannels should match snapshot 1`] = `
|
|||
style={
|
||||
Array [
|
||||
Object {
|
||||
"height": 38,
|
||||
"marginVertical": 5,
|
||||
"paddingLeft": 8,
|
||||
},
|
||||
null,
|
||||
]
|
||||
}
|
||||
>
|
||||
<SearchBarIos
|
||||
<Search
|
||||
autoCapitalize="none"
|
||||
backArrowSize={24}
|
||||
backgroundColor="transparent"
|
||||
blurOnSubmit={true}
|
||||
blurOnSubmit={false}
|
||||
containerHeight={40}
|
||||
deleteIconSize={20}
|
||||
editable={true}
|
||||
inputHeight={33}
|
||||
inputStyle={
|
||||
Object {
|
||||
|
|
@ -27,16 +33,19 @@ exports[`MoreChannels should match snapshot 1`] = `
|
|||
}
|
||||
}
|
||||
keyboardAppearance="light"
|
||||
leftComponent={null}
|
||||
keyboardShouldPersist={false}
|
||||
keyboardType="default"
|
||||
onBlur={[Function]}
|
||||
onCancelButtonPress={[Function]}
|
||||
onChangeText={[Function]}
|
||||
onFocus={[Function]}
|
||||
onSearchButtonPress={[Function]}
|
||||
onSelectionChange={[Function]}
|
||||
placeholderTextColor="rgba(61,60,64,0.5)"
|
||||
searchIconCollapsedMargin={10}
|
||||
searchIconExpandedMargin={10}
|
||||
returnKeyType="search"
|
||||
searchBarRightMargin={0}
|
||||
searchIconSize={24}
|
||||
showArrow={false}
|
||||
showCancel={true}
|
||||
tintColorDelete="rgba(61,60,64,0.5)"
|
||||
tintColorSearch="rgba(61,60,64,0.5)"
|
||||
titleCancelColor="#3d3c40"
|
||||
|
|
|
|||
|
|
@ -423,11 +423,6 @@ export default class MoreChannels extends PureComponent {
|
|||
backgroundColor: changeOpacity(theme.centerChannelColor, 0.2),
|
||||
color: theme.centerChannelColor,
|
||||
fontSize: 15,
|
||||
...Platform.select({
|
||||
android: {
|
||||
marginBottom: -5,
|
||||
},
|
||||
}),
|
||||
};
|
||||
|
||||
let activeChannels = channels;
|
||||
|
|
@ -508,6 +503,12 @@ const getStyleFromTheme = makeStyleSheetFromTheme((theme) => {
|
|||
return {
|
||||
searchBar: {
|
||||
marginVertical: 5,
|
||||
height: 38,
|
||||
...Platform.select({
|
||||
ios: {
|
||||
paddingLeft: 8,
|
||||
},
|
||||
}),
|
||||
},
|
||||
loadingContainer: {
|
||||
alignItems: 'center',
|
||||
|
|
|
|||
|
|
@ -424,11 +424,6 @@ export default class MoreDirectMessages extends PureComponent {
|
|||
backgroundColor: changeOpacity(theme.centerChannelColor, 0.2),
|
||||
color: theme.centerChannelColor,
|
||||
fontSize: 15,
|
||||
...Platform.select({
|
||||
android: {
|
||||
marginBottom: -5,
|
||||
},
|
||||
}),
|
||||
};
|
||||
|
||||
let data;
|
||||
|
|
@ -508,6 +503,12 @@ const getStyleFromTheme = makeStyleSheetFromTheme((theme) => {
|
|||
},
|
||||
searchBar: {
|
||||
marginVertical: 5,
|
||||
height: 38,
|
||||
...Platform.select({
|
||||
ios: {
|
||||
paddingLeft: 8,
|
||||
},
|
||||
}),
|
||||
},
|
||||
loadingContainer: {
|
||||
alignItems: 'center',
|
||||
|
|
|
|||
|
|
@ -729,10 +729,12 @@ export default class Search extends PureComponent {
|
|||
onCancelButtonPress={this.cancelSearch}
|
||||
onSelectionChange={this.handleSelectionChange}
|
||||
autoCapitalize='none'
|
||||
showArrow={true}
|
||||
value={value}
|
||||
containerStyle={style.searchBarContainer}
|
||||
backArrowSize={28}
|
||||
keyboardAppearance={getKeyboardAppearanceFromTheme(theme)}
|
||||
containerHeight={33}
|
||||
/>
|
||||
</View>
|
||||
<SectionList
|
||||
|
|
@ -773,6 +775,8 @@ const getStyleFromTheme = makeStyleSheetFromTheme((theme) => {
|
|||
},
|
||||
ios: {
|
||||
height: 44,
|
||||
paddingLeft: 8,
|
||||
paddingBottom: 10,
|
||||
},
|
||||
}),
|
||||
},
|
||||
|
|
|
|||
|
|
@ -13,17 +13,23 @@ exports[`SelectorScreen should match snapshot for channels 1`] = `
|
|||
style={
|
||||
Array [
|
||||
Object {
|
||||
"height": 38,
|
||||
"marginVertical": 5,
|
||||
"paddingLeft": 8,
|
||||
},
|
||||
null,
|
||||
]
|
||||
}
|
||||
>
|
||||
<SearchBarIos
|
||||
<Search
|
||||
autoCapitalize="none"
|
||||
backArrowSize={24}
|
||||
backgroundColor="transparent"
|
||||
blurOnSubmit={true}
|
||||
blurOnSubmit={false}
|
||||
cancelTitle="Cancel"
|
||||
containerHeight={40}
|
||||
deleteIconSize={20}
|
||||
editable={true}
|
||||
inputHeight={33}
|
||||
inputStyle={
|
||||
Object {
|
||||
|
|
@ -33,17 +39,20 @@ exports[`SelectorScreen should match snapshot for channels 1`] = `
|
|||
}
|
||||
}
|
||||
keyboardAppearance="light"
|
||||
leftComponent={null}
|
||||
keyboardShouldPersist={false}
|
||||
keyboardType="default"
|
||||
onBlur={[Function]}
|
||||
onCancelButtonPress={[Function]}
|
||||
onChangeText={[Function]}
|
||||
onFocus={[Function]}
|
||||
onSearchButtonPress={[Function]}
|
||||
onSelectionChange={[Function]}
|
||||
placeholder="Search"
|
||||
placeholderTextColor="rgba(61,60,64,0.5)"
|
||||
searchIconCollapsedMargin={10}
|
||||
searchIconExpandedMargin={10}
|
||||
returnKeyType="search"
|
||||
searchBarRightMargin={0}
|
||||
searchIconSize={24}
|
||||
showArrow={false}
|
||||
showCancel={true}
|
||||
tintColorDelete="rgba(61,60,64,0.5)"
|
||||
tintColorSearch="rgba(61,60,64,0.5)"
|
||||
titleCancelColor="#3d3c40"
|
||||
|
|
@ -109,17 +118,23 @@ exports[`SelectorScreen should match snapshot for channels 2`] = `
|
|||
style={
|
||||
Array [
|
||||
Object {
|
||||
"height": 38,
|
||||
"marginVertical": 5,
|
||||
"paddingLeft": 8,
|
||||
},
|
||||
null,
|
||||
]
|
||||
}
|
||||
>
|
||||
<SearchBarIos
|
||||
<Search
|
||||
autoCapitalize="none"
|
||||
backArrowSize={24}
|
||||
backgroundColor="transparent"
|
||||
blurOnSubmit={true}
|
||||
blurOnSubmit={false}
|
||||
cancelTitle="Cancel"
|
||||
containerHeight={40}
|
||||
deleteIconSize={20}
|
||||
editable={true}
|
||||
inputHeight={33}
|
||||
inputStyle={
|
||||
Object {
|
||||
|
|
@ -129,17 +144,20 @@ exports[`SelectorScreen should match snapshot for channels 2`] = `
|
|||
}
|
||||
}
|
||||
keyboardAppearance="light"
|
||||
leftComponent={null}
|
||||
keyboardShouldPersist={false}
|
||||
keyboardType="default"
|
||||
onBlur={[Function]}
|
||||
onCancelButtonPress={[Function]}
|
||||
onChangeText={[Function]}
|
||||
onFocus={[Function]}
|
||||
onSearchButtonPress={[Function]}
|
||||
onSelectionChange={[Function]}
|
||||
placeholder="Search"
|
||||
placeholderTextColor="rgba(61,60,64,0.5)"
|
||||
searchIconCollapsedMargin={10}
|
||||
searchIconExpandedMargin={10}
|
||||
returnKeyType="search"
|
||||
searchBarRightMargin={0}
|
||||
searchIconSize={24}
|
||||
showArrow={false}
|
||||
showCancel={true}
|
||||
tintColorDelete="rgba(61,60,64,0.5)"
|
||||
tintColorSearch="rgba(61,60,64,0.5)"
|
||||
titleCancelColor="#3d3c40"
|
||||
|
|
@ -205,17 +223,23 @@ exports[`SelectorScreen should match snapshot for explicit options 1`] = `
|
|||
style={
|
||||
Array [
|
||||
Object {
|
||||
"height": 38,
|
||||
"marginVertical": 5,
|
||||
"paddingLeft": 8,
|
||||
},
|
||||
null,
|
||||
]
|
||||
}
|
||||
>
|
||||
<SearchBarIos
|
||||
<Search
|
||||
autoCapitalize="none"
|
||||
backArrowSize={24}
|
||||
backgroundColor="transparent"
|
||||
blurOnSubmit={true}
|
||||
blurOnSubmit={false}
|
||||
cancelTitle="Cancel"
|
||||
containerHeight={40}
|
||||
deleteIconSize={20}
|
||||
editable={true}
|
||||
inputHeight={33}
|
||||
inputStyle={
|
||||
Object {
|
||||
|
|
@ -225,17 +249,20 @@ exports[`SelectorScreen should match snapshot for explicit options 1`] = `
|
|||
}
|
||||
}
|
||||
keyboardAppearance="light"
|
||||
leftComponent={null}
|
||||
keyboardShouldPersist={false}
|
||||
keyboardType="default"
|
||||
onBlur={[Function]}
|
||||
onCancelButtonPress={[Function]}
|
||||
onChangeText={[Function]}
|
||||
onFocus={[Function]}
|
||||
onSearchButtonPress={[Function]}
|
||||
onSelectionChange={[Function]}
|
||||
placeholder="Search"
|
||||
placeholderTextColor="rgba(61,60,64,0.5)"
|
||||
searchIconCollapsedMargin={10}
|
||||
searchIconExpandedMargin={10}
|
||||
returnKeyType="search"
|
||||
searchBarRightMargin={0}
|
||||
searchIconSize={24}
|
||||
showArrow={false}
|
||||
showCancel={true}
|
||||
tintColorDelete="rgba(61,60,64,0.5)"
|
||||
tintColorSearch="rgba(61,60,64,0.5)"
|
||||
titleCancelColor="#3d3c40"
|
||||
|
|
@ -308,17 +335,23 @@ exports[`SelectorScreen should match snapshot for searching 1`] = `
|
|||
style={
|
||||
Array [
|
||||
Object {
|
||||
"height": 38,
|
||||
"marginVertical": 5,
|
||||
"paddingLeft": 8,
|
||||
},
|
||||
null,
|
||||
]
|
||||
}
|
||||
>
|
||||
<SearchBarIos
|
||||
<Search
|
||||
autoCapitalize="none"
|
||||
backArrowSize={24}
|
||||
backgroundColor="transparent"
|
||||
blurOnSubmit={true}
|
||||
blurOnSubmit={false}
|
||||
cancelTitle="Cancel"
|
||||
containerHeight={40}
|
||||
deleteIconSize={20}
|
||||
editable={true}
|
||||
inputHeight={33}
|
||||
inputStyle={
|
||||
Object {
|
||||
|
|
@ -328,17 +361,20 @@ exports[`SelectorScreen should match snapshot for searching 1`] = `
|
|||
}
|
||||
}
|
||||
keyboardAppearance="light"
|
||||
leftComponent={null}
|
||||
keyboardShouldPersist={false}
|
||||
keyboardType="default"
|
||||
onBlur={[Function]}
|
||||
onCancelButtonPress={[Function]}
|
||||
onChangeText={[Function]}
|
||||
onFocus={[Function]}
|
||||
onSearchButtonPress={[Function]}
|
||||
onSelectionChange={[Function]}
|
||||
placeholder="Search"
|
||||
placeholderTextColor="rgba(61,60,64,0.5)"
|
||||
searchIconCollapsedMargin={10}
|
||||
searchIconExpandedMargin={10}
|
||||
returnKeyType="search"
|
||||
searchBarRightMargin={0}
|
||||
searchIconSize={24}
|
||||
showArrow={false}
|
||||
showCancel={true}
|
||||
tintColorDelete="rgba(61,60,64,0.5)"
|
||||
tintColorSearch="rgba(61,60,64,0.5)"
|
||||
titleCancelColor="#3d3c40"
|
||||
|
|
@ -404,17 +440,23 @@ exports[`SelectorScreen should match snapshot for users 1`] = `
|
|||
style={
|
||||
Array [
|
||||
Object {
|
||||
"height": 38,
|
||||
"marginVertical": 5,
|
||||
"paddingLeft": 8,
|
||||
},
|
||||
null,
|
||||
]
|
||||
}
|
||||
>
|
||||
<SearchBarIos
|
||||
<Search
|
||||
autoCapitalize="none"
|
||||
backArrowSize={24}
|
||||
backgroundColor="transparent"
|
||||
blurOnSubmit={true}
|
||||
blurOnSubmit={false}
|
||||
cancelTitle="Cancel"
|
||||
containerHeight={40}
|
||||
deleteIconSize={20}
|
||||
editable={true}
|
||||
inputHeight={33}
|
||||
inputStyle={
|
||||
Object {
|
||||
|
|
@ -424,17 +466,20 @@ exports[`SelectorScreen should match snapshot for users 1`] = `
|
|||
}
|
||||
}
|
||||
keyboardAppearance="light"
|
||||
leftComponent={null}
|
||||
keyboardShouldPersist={false}
|
||||
keyboardType="default"
|
||||
onBlur={[Function]}
|
||||
onCancelButtonPress={[Function]}
|
||||
onChangeText={[Function]}
|
||||
onFocus={[Function]}
|
||||
onSearchButtonPress={[Function]}
|
||||
onSelectionChange={[Function]}
|
||||
placeholder="Search"
|
||||
placeholderTextColor="rgba(61,60,64,0.5)"
|
||||
searchIconCollapsedMargin={10}
|
||||
searchIconExpandedMargin={10}
|
||||
returnKeyType="search"
|
||||
searchBarRightMargin={0}
|
||||
searchIconSize={24}
|
||||
showArrow={false}
|
||||
showCancel={true}
|
||||
tintColorDelete="rgba(61,60,64,0.5)"
|
||||
tintColorSearch="rgba(61,60,64,0.5)"
|
||||
titleCancelColor="#3d3c40"
|
||||
|
|
@ -500,17 +545,23 @@ exports[`SelectorScreen should match snapshot for users 2`] = `
|
|||
style={
|
||||
Array [
|
||||
Object {
|
||||
"height": 38,
|
||||
"marginVertical": 5,
|
||||
"paddingLeft": 8,
|
||||
},
|
||||
null,
|
||||
]
|
||||
}
|
||||
>
|
||||
<SearchBarIos
|
||||
<Search
|
||||
autoCapitalize="none"
|
||||
backArrowSize={24}
|
||||
backgroundColor="transparent"
|
||||
blurOnSubmit={true}
|
||||
blurOnSubmit={false}
|
||||
cancelTitle="Cancel"
|
||||
containerHeight={40}
|
||||
deleteIconSize={20}
|
||||
editable={true}
|
||||
inputHeight={33}
|
||||
inputStyle={
|
||||
Object {
|
||||
|
|
@ -520,17 +571,20 @@ exports[`SelectorScreen should match snapshot for users 2`] = `
|
|||
}
|
||||
}
|
||||
keyboardAppearance="light"
|
||||
leftComponent={null}
|
||||
keyboardShouldPersist={false}
|
||||
keyboardType="default"
|
||||
onBlur={[Function]}
|
||||
onCancelButtonPress={[Function]}
|
||||
onChangeText={[Function]}
|
||||
onFocus={[Function]}
|
||||
onSearchButtonPress={[Function]}
|
||||
onSelectionChange={[Function]}
|
||||
placeholder="Search"
|
||||
placeholderTextColor="rgba(61,60,64,0.5)"
|
||||
searchIconCollapsedMargin={10}
|
||||
searchIconExpandedMargin={10}
|
||||
returnKeyType="search"
|
||||
searchBarRightMargin={0}
|
||||
searchIconSize={24}
|
||||
showArrow={false}
|
||||
showCancel={true}
|
||||
tintColorDelete="rgba(61,60,64,0.5)"
|
||||
tintColorSearch="rgba(61,60,64,0.5)"
|
||||
titleCancelColor="#3d3c40"
|
||||
|
|
|
|||
|
|
@ -300,11 +300,6 @@ export default class SelectorScreen extends PureComponent {
|
|||
backgroundColor: changeOpacity(theme.centerChannelColor, 0.2),
|
||||
color: theme.centerChannelColor,
|
||||
fontSize: 15,
|
||||
...Platform.select({
|
||||
android: {
|
||||
marginBottom: -5,
|
||||
},
|
||||
}),
|
||||
};
|
||||
|
||||
let rowComponent;
|
||||
|
|
@ -366,6 +361,12 @@ const getStyleFromTheme = makeStyleSheetFromTheme((theme) => {
|
|||
},
|
||||
searchBar: {
|
||||
marginVertical: 5,
|
||||
height: 38,
|
||||
...Platform.select({
|
||||
ios: {
|
||||
paddingLeft: 8,
|
||||
},
|
||||
}),
|
||||
},
|
||||
loadingContainer: {
|
||||
alignItems: 'center',
|
||||
|
|
|
|||
|
|
@ -157,6 +157,7 @@ const getStyleSheet = makeStyleSheetFromTheme((theme) => {
|
|||
},
|
||||
header: {
|
||||
backgroundColor: theme.sidebarHeaderBg,
|
||||
height: 38,
|
||||
width: '100%',
|
||||
...Platform.select({
|
||||
android: {
|
||||
|
|
@ -165,6 +166,7 @@ const getStyleSheet = makeStyleSheetFromTheme((theme) => {
|
|||
},
|
||||
ios: {
|
||||
height: 44,
|
||||
paddingLeft: 8,
|
||||
},
|
||||
}),
|
||||
},
|
||||
|
|
|
|||
102
package-lock.json
generated
102
package-lock.json
generated
|
|
@ -5302,6 +5302,23 @@
|
|||
"csstype": "^2.2.0"
|
||||
}
|
||||
},
|
||||
"@types/react-native": {
|
||||
"version": "0.61.23",
|
||||
"resolved": "https://registry.npmjs.org/@types/react-native/-/react-native-0.61.23.tgz",
|
||||
"integrity": "sha512-upHmySsrVBDBokWWhYIKkKnpvadsHdioSjbBTu4xl7fjN0yb94KR5ngUOBXsyqAYqQzF+hP6qpvobG9M7Jr6hw==",
|
||||
"requires": {
|
||||
"@types/react": "*"
|
||||
}
|
||||
},
|
||||
"@types/react-native-vector-icons": {
|
||||
"version": "6.4.5",
|
||||
"resolved": "https://registry.npmjs.org/@types/react-native-vector-icons/-/react-native-vector-icons-6.4.5.tgz",
|
||||
"integrity": "sha512-JBpcjWQE4n0GlE0p6HpDDclT+uXpFC453T5k4h+B38q0utlGJhvgNr8899BoJGc1xOktA2cgqFKmFMJd0h7YaA==",
|
||||
"requires": {
|
||||
"@types/react": "*",
|
||||
"@types/react-native": "*"
|
||||
}
|
||||
},
|
||||
"@types/stack-utils": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-1.0.1.tgz",
|
||||
|
|
@ -6804,6 +6821,15 @@
|
|||
"object-visit": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"color": {
|
||||
"version": "3.1.2",
|
||||
"resolved": "https://registry.npmjs.org/color/-/color-3.1.2.tgz",
|
||||
"integrity": "sha512-vXTJhHebByxZn3lDvDJYw4lR5+uB3vuoHsuYA5AKuxRVn5wzzIfQKGLBmgdVRHKTJYeK5rvJcHnrd0Li49CFpg==",
|
||||
"requires": {
|
||||
"color-convert": "^1.9.1",
|
||||
"color-string": "^1.5.2"
|
||||
}
|
||||
},
|
||||
"color-convert": {
|
||||
"version": "1.9.3",
|
||||
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
|
||||
|
|
@ -6817,6 +6843,15 @@
|
|||
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
|
||||
"integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU="
|
||||
},
|
||||
"color-string": {
|
||||
"version": "1.5.3",
|
||||
"resolved": "https://registry.npmjs.org/color-string/-/color-string-1.5.3.tgz",
|
||||
"integrity": "sha512-dC2C5qeWoYkxki5UAXapdjqO672AM4vZuPGRQfO8b5HKuKGBbKWpITyDYN7TOFKvRW7kOgAn3746clDBMDJyQw==",
|
||||
"requires": {
|
||||
"color-name": "^1.0.0",
|
||||
"simple-swizzle": "^0.2.2"
|
||||
}
|
||||
},
|
||||
"color-support": {
|
||||
"version": "1.1.3",
|
||||
"resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz",
|
||||
|
|
@ -9742,7 +9777,8 @@
|
|||
"dependencies": {
|
||||
"minimist": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "",
|
||||
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
|
||||
"integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
|
|
@ -18295,6 +18331,11 @@
|
|||
"is-wsl": "^1.1.0"
|
||||
}
|
||||
},
|
||||
"opencollective-postinstall": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/opencollective-postinstall/-/opencollective-postinstall-2.0.2.tgz",
|
||||
"integrity": "sha512-pVOEP16TrAO2/fjej1IdOyupJY8KDUM1CvsaScRbw6oddvpQoOfGk4ywha0HKKVAD6RkW4x6Q+tNBwhf3Bgpuw=="
|
||||
},
|
||||
"opn": {
|
||||
"version": "5.5.0",
|
||||
"resolved": "https://registry.npmjs.org/opn/-/opn-5.5.0.tgz",
|
||||
|
|
@ -19215,6 +19256,36 @@
|
|||
"resolved": "https://registry.npmjs.org/react-native-document-picker/-/react-native-document-picker-3.3.0.tgz",
|
||||
"integrity": "sha512-h/O8USFx1TWQT7Sx5Qj1OVpADabHawckVPDrEiGUf6qCJF2h5kKZs3ZuxZe7wHSZX4LgQE0agZqagQUK+HLIVQ=="
|
||||
},
|
||||
"react-native-elements": {
|
||||
"version": "1.2.7",
|
||||
"resolved": "https://registry.npmjs.org/react-native-elements/-/react-native-elements-1.2.7.tgz",
|
||||
"integrity": "sha512-0S+0R1cbItl15i64qrkWnyMztwpw60d0SUsZGVDKRAMf0Jvq9Clgyh/MzxJx2sr42mbedQP1sg5Et4fZM7Fp1w==",
|
||||
"requires": {
|
||||
"@types/react-native-vector-icons": "^6.4.4",
|
||||
"color": "^3.1.0",
|
||||
"deepmerge": "^3.1.0",
|
||||
"hoist-non-react-statics": "^3.1.0",
|
||||
"opencollective-postinstall": "^2.0.0",
|
||||
"prop-types": "^15.7.2",
|
||||
"react-native-ratings": "^6.3.0",
|
||||
"react-native-status-bar-height": "^2.2.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"deepmerge": {
|
||||
"version": "3.3.0",
|
||||
"resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-3.3.0.tgz",
|
||||
"integrity": "sha512-GRQOafGHwMHpjPx9iCvTgpu9NojZ49q794EEL94JVEw6VaeA8XTUyBKvAkOOjBX9oJNiV6G3P+T+tihFjo2TqA=="
|
||||
},
|
||||
"hoist-non-react-statics": {
|
||||
"version": "3.3.2",
|
||||
"resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz",
|
||||
"integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==",
|
||||
"requires": {
|
||||
"react-is": "^16.7.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"react-native-exception-handler": {
|
||||
"version": "2.10.8",
|
||||
"resolved": "https://registry.npmjs.org/react-native-exception-handler/-/react-native-exception-handler-2.10.8.tgz",
|
||||
|
|
@ -19352,6 +19423,15 @@
|
|||
"resolved": "https://registry.npmjs.org/react-native-permissions/-/react-native-permissions-2.0.10.tgz",
|
||||
"integrity": "sha512-oQmWgm4tqUYyWmMNtYzNO7U/+6+WHyKiRd5cwNeE1FCJTGh8cJ5HapjHw3d6ZVfhSLzNwWqgJy1P4NpTANYa/g=="
|
||||
},
|
||||
"react-native-ratings": {
|
||||
"version": "6.5.0",
|
||||
"resolved": "https://registry.npmjs.org/react-native-ratings/-/react-native-ratings-6.5.0.tgz",
|
||||
"integrity": "sha512-YMcfQ7UQCmXGEc/WPlukHSHs5yvckTwjq5fTRk1FG8gaO7fZCNygEUGPuw4Dbvvp3IlsCUn0bOQd63RYsb7NDQ==",
|
||||
"requires": {
|
||||
"lodash": "^4.17.4",
|
||||
"prop-types": "^15.5.10"
|
||||
}
|
||||
},
|
||||
"react-native-safe-area": {
|
||||
"version": "0.5.1",
|
||||
"resolved": "https://registry.npmjs.org/react-native-safe-area/-/react-native-safe-area-0.5.1.tgz",
|
||||
|
|
@ -19389,6 +19469,11 @@
|
|||
"prop-types": "^15.5.6"
|
||||
}
|
||||
},
|
||||
"react-native-status-bar-height": {
|
||||
"version": "2.4.0",
|
||||
"resolved": "https://registry.npmjs.org/react-native-status-bar-height/-/react-native-status-bar-height-2.4.0.tgz",
|
||||
"integrity": "sha512-pWvZFlyIHiuxLugLioq97vXiaGSovFXEyxt76wQtbq0gxv4dGXMPqYow46UmpwOgeJpBhqL1E0EKxnfJRrFz5w=="
|
||||
},
|
||||
"react-native-status-bar-size": {
|
||||
"version": "0.3.3",
|
||||
"resolved": "https://registry.npmjs.org/react-native-status-bar-size/-/react-native-status-bar-size-0.3.3.tgz",
|
||||
|
|
@ -20566,6 +20651,21 @@
|
|||
"plist": "^3.0.1"
|
||||
}
|
||||
},
|
||||
"simple-swizzle": {
|
||||
"version": "0.2.2",
|
||||
"resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz",
|
||||
"integrity": "sha1-pNprY1/8zMoz9w0Xy5JZLeleVXo=",
|
||||
"requires": {
|
||||
"is-arrayish": "^0.3.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"is-arrayish": {
|
||||
"version": "0.3.2",
|
||||
"resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz",
|
||||
"integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"sisteransi": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.4.tgz",
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@
|
|||
"react-native-device-info": "github:mattermost/react-native-device-info#f7175f10822d8f66b9806206e3313eaf2f4aabc6",
|
||||
"react-native-doc-viewer": "github:mattermost/react-native-doc-viewer#c913e54ec8e4a60753bc7dd39256fa4be8229d19",
|
||||
"react-native-document-picker": "3.3.0",
|
||||
"react-native-elements": "1.2.7",
|
||||
"react-native-exception-handler": "2.10.8",
|
||||
"react-native-fast-image": "8.1.5",
|
||||
"react-native-gesture-handler": "1.6.0",
|
||||
|
|
|
|||
51
patches/react-native-elements+1.2.7.patch
Normal file
51
patches/react-native-elements+1.2.7.patch
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
diff --git a/node_modules/react-native-elements/src/searchbar/SearchBar-android.js b/node_modules/react-native-elements/src/searchbar/SearchBar-android.js
|
||||
index eeaeb81..93f58de 100644
|
||||
--- a/node_modules/react-native-elements/src/searchbar/SearchBar-android.js
|
||||
+++ b/node_modules/react-native-elements/src/searchbar/SearchBar-android.js
|
||||
@@ -78,6 +78,12 @@ class SearchBar extends Component {
|
||||
};
|
||||
}
|
||||
|
||||
+ componentDidUpdate(prevProps) {
|
||||
+ if (this.props.value !== prevProps.value) {
|
||||
+ this.setState({isEmpty: this.props.value === ''});
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
render() {
|
||||
const {
|
||||
clearIcon,
|
||||
diff --git a/node_modules/react-native-elements/src/searchbar/SearchBar-ios.js b/node_modules/react-native-elements/src/searchbar/SearchBar-ios.js
|
||||
index 41ef6be..dbf727b 100644
|
||||
--- a/node_modules/react-native-elements/src/searchbar/SearchBar-ios.js
|
||||
+++ b/node_modules/react-native-elements/src/searchbar/SearchBar-ios.js
|
||||
@@ -41,6 +41,12 @@ class SearchBar extends Component {
|
||||
};
|
||||
}
|
||||
|
||||
+ componentDidUpdate(prevProps) {
|
||||
+ if (this.props.value !== prevProps.value) {
|
||||
+ this.setState({isEmpty: this.props.value === ''});
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
focus = () => {
|
||||
this.input.focus();
|
||||
};
|
||||
@@ -259,7 +265,6 @@ const styles = StyleSheet.create({
|
||||
paddingBottom: 13,
|
||||
paddingTop: 13,
|
||||
flexDirection: 'row',
|
||||
- overflow: 'hidden',
|
||||
alignItems: 'center',
|
||||
},
|
||||
input: {
|
||||
@@ -270,7 +275,7 @@ const styles = StyleSheet.create({
|
||||
borderBottomWidth: 0,
|
||||
backgroundColor: '#dcdce1',
|
||||
borderRadius: 9,
|
||||
- minHeight: 36,
|
||||
+ minHeight: 30,
|
||||
marginLeft: 8,
|
||||
marginRight: 8,
|
||||
},
|
||||
|
|
@ -10,6 +10,7 @@ import {
|
|||
SectionList,
|
||||
Text,
|
||||
View,
|
||||
Platform,
|
||||
} from 'react-native';
|
||||
|
||||
import {Preferences} from 'mattermost-redux/constants';
|
||||
|
|
@ -251,6 +252,12 @@ const getStyleSheet = makeStyleSheetFromTheme((theme) => {
|
|||
},
|
||||
searchContainer: {
|
||||
paddingBottom: 2,
|
||||
height: 38,
|
||||
...Platform.select({
|
||||
ios: {
|
||||
paddingLeft: 8,
|
||||
},
|
||||
}),
|
||||
},
|
||||
searchBarInput: {
|
||||
backgroundColor: '#fff',
|
||||
|
|
|
|||
Loading…
Reference in a new issue