|
1 | 1 | # react-navigation-addon-search-layout |
2 | 2 |
|
3 | | -Note: this currently depends on the Expo environment being present. I |
4 | | -may fix this in the future, a PR is welcome though. It also only |
5 | | -explicitly supports portrait mode, ymmv with landscape. |
| 3 | +A plain but perfectly acceptable search layout screen that looks good on |
| 4 | +iOS and Android. |
6 | 5 |
|
7 | | -[Try it on Snack](https://snack.expo.io/HJXlZ7TuW) |
| 6 | +## Installation |
| 7 | + |
| 8 | +``` |
| 9 | +npm install react-navigation-addon-search-layout |
| 10 | +``` |
| 11 | + |
| 12 | +This requires that you have `react-native-vector-icons` installed in |
| 13 | +your project, it uses the `Ionicons` font family. If you use the Expo |
| 14 | +managed workflow, it will work out of the box as that comes preinstalled |
| 15 | +and is available through `@expo/vector-icons`'. |
| 16 | + |
| 17 | +## Usage |
| 18 | + |
| 19 | +Here's an example of how you can use this: |
| 20 | + |
| 21 | +```js |
| 22 | +import * as React from 'react'; |
| 23 | +import { |
| 24 | + Animated, |
| 25 | + Button, |
| 26 | + Platform, |
| 27 | + Text, |
| 28 | + StyleSheet, |
| 29 | + View, |
| 30 | +} from 'react-native'; |
| 31 | +import { |
| 32 | + createAppContainer, |
| 33 | + createStackNavigator, |
| 34 | + StackViewTransitionConfigs, |
| 35 | +} from 'react-navigation'; |
| 36 | +import { RectButton, BorderlessButton } from 'react-native-gesture-handler'; |
| 37 | +import SearchLayout from 'react-navigation-addon-search-layout'; |
| 38 | +import { Ionicons } from '@expo/vector-icons'; |
| 39 | + |
| 40 | +class HomeScreen extends React.Component { |
| 41 | + static navigationOptions = ({ navigation }) => ({ |
| 42 | + title: 'Home', |
| 43 | + headerRight: ( |
| 44 | + <BorderlessButton |
| 45 | + onPress={() => navigation.navigate('Search')} |
| 46 | + style={{ marginRight: 15 }}> |
| 47 | + <Ionicons |
| 48 | + name="md-search" |
| 49 | + size={Platform.OS === 'ios' ? 22 : 25} |
| 50 | + color={SearchLayout.DefaultTintColor} |
| 51 | + /> |
| 52 | + </BorderlessButton> |
| 53 | + ), |
| 54 | + }); |
| 55 | + |
| 56 | + render() { |
| 57 | + return ( |
| 58 | + <View style={styles.container}> |
| 59 | + <Text>Hello there!</Text> |
| 60 | + </View> |
| 61 | + ); |
| 62 | + } |
| 63 | +} |
| 64 | + |
| 65 | +class ResultScreen extends React.Component { |
| 66 | + static navigationOptions = { |
| 67 | + title: 'Result', |
| 68 | + }; |
| 69 | + |
| 70 | + render() { |
| 71 | + return ( |
| 72 | + <View style={styles.container}> |
| 73 | + <Text>{this.props.navigation.getParam('text')} result!</Text> |
| 74 | + </View> |
| 75 | + ); |
| 76 | + } |
| 77 | +} |
| 78 | + |
| 79 | +class SearchScreen extends React.Component { |
| 80 | + static navigationOptions = { |
| 81 | + header: null, |
| 82 | + }; |
| 83 | + |
| 84 | + state = { |
| 85 | + searchText: null, |
| 86 | + }; |
| 87 | + |
| 88 | + _handleQueryChange = searchText => { |
| 89 | + this.setState({ searchText }); |
| 90 | + }; |
| 91 | + |
| 92 | + _executeSearch = () => { |
| 93 | + alert('do search!'); |
| 94 | + }; |
| 95 | + |
| 96 | + render() { |
| 97 | + let { searchText } = this.state; |
| 98 | + |
| 99 | + return ( |
| 100 | + <SearchLayout |
| 101 | + onChangeQuery={this._handleQueryChange} |
| 102 | + onSubmit={this._executeSearch}> |
| 103 | + {searchText ? ( |
| 104 | + <RectButton |
| 105 | + style={{ |
| 106 | + borderBottomWidth: StyleSheet.hairlineWidth, |
| 107 | + borderBottomColor: '#eee', |
| 108 | + paddingVertical: 20, |
| 109 | + paddingHorizontal: 15, |
| 110 | + }} |
| 111 | + onPress={() => |
| 112 | + this.props.navigation.navigate('Result', { |
| 113 | + text: this.state.searchText, |
| 114 | + }) |
| 115 | + }> |
| 116 | + <Text style={{ fontSize: 14 }}>{searchText}!</Text> |
| 117 | + </RectButton> |
| 118 | + ) : null} |
| 119 | + </SearchLayout> |
| 120 | + ); |
| 121 | + } |
| 122 | +} |
| 123 | + |
| 124 | +let SearchStack = createStackNavigator( |
| 125 | + { |
| 126 | + Home: HomeScreen, |
| 127 | + Search: SearchScreen, |
| 128 | + }, |
| 129 | + { |
| 130 | + transitionConfig: () => StackViewTransitionConfigs.NoAnimation, |
| 131 | + navigationOptions: { |
| 132 | + header: null, |
| 133 | + }, |
| 134 | + defaultNavigationOptions: { |
| 135 | + gesturesEnabled: false, |
| 136 | + }, |
| 137 | + } |
| 138 | +); |
| 139 | + |
| 140 | +let MainStack = createStackNavigator({ |
| 141 | + Feed: SearchStack, |
| 142 | + Result: ResultScreen, |
| 143 | +}); |
| 144 | + |
| 145 | +export default createAppContainer(MainStack); |
| 146 | + |
| 147 | +const styles = StyleSheet.create({ |
| 148 | + container: { |
| 149 | + flex: 1, |
| 150 | + alignItems: 'center', |
| 151 | + justifyContent: 'center', |
| 152 | + }, |
| 153 | +}); |
| 154 | +``` |
0 commit comments