├── .gitignore ├── LICENSE ├── README.md ├── SearchBar.js └── package.json /.gitignore: -------------------------------------------------------------------------------- 1 | !default.mode1v3 2 | !default.mode2v3 3 | !default.pbxuser 4 | !default.perspectivev3 5 | *.hmap 6 | *.ipa 7 | *.jsbundle 8 | *.mode1v3 9 | *.mode2v3 10 | *.moved-aside 11 | *.pbxuser 12 | *.perspectivev3 13 | *.sublime-workspace 14 | *.xccheckout 15 | *.xcuserstate 16 | .DS_Store 17 | .firebaserc 18 | .gradle 19 | .idea 20 | DerivedData 21 | \.buckd/ 22 | android/app/libs 23 | android/keystores/debug.keystore 24 | buck-out/ 25 | build/ 26 | firebase-debug.log 27 | firebase/rules.json 28 | local.properties 29 | node_modules/ 30 | npm-debug.log 31 | project.xcworkspace 32 | src/common/config.json 33 | src/native/initialState.js 34 | webpack-assets.json 35 | xcuserdata 36 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2016 ananddayalan 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # react-native-material-design-searchbar 2 | A React Native Material Design SearchBar 3 | 4 | 5 | 6 | 7 | # Setup 8 | 9 | Install the SearchBar from npm with `npm i -S react-native-material-design-searchbar`. Then, require it from your app's JavaScript files with `import SearchBar from 'react-native-material-design-searchbar'`. 10 | This library depends on [react-native-vector-icons](https://github.com/oblador/react-native-vector-icons). Please link it by following their installation guide. 11 | 12 | # Usage 13 | 14 | All props are optional except height. 15 | 16 | ```js 17 | import React, { Component } from 'react'; 18 | import SearchBar from 'react-native-material-design-searchbar'; 19 | 20 | export default class ExampleComponent extends Component { 21 | render() { 22 | return ( 23 | console.log('On Search Change')} 25 | height={50} 26 | onFocus={() => console.log('On Focus')} 27 | onBlur={() => console.log('On Blur')} 28 | placeholder={'Search...'} 29 | autoCorrect={false} 30 | padding={5} 31 | returnKeyType={'search'} 32 | /> 33 | ); 34 | } 35 | }; 36 | 37 | ``` 38 | 39 | # Available Props 40 | 41 | - `onSearchChange`: Callback on search change 42 | - `onClear`: Callback when the 'X' button is pressed. This also calls `onSearchChange` with an empty string. 43 | - `searchValue`: Initializes the input field. Changing this prop does not change the input value. 44 | - `onBackPress`: Optional function, Callback on back icon pressed 45 | - `alwaysShowBackButton`: Optional bool, use if you want to always show the back button instead of search, default is `false` 46 | - `iconCloseName`: Optional string, use it to customize the close icon 47 | - `iconSearchName`: Optional string, use it to customize the search icon 48 | - `iconBackName`: Optional string, use it to customize the back icon 49 | - `iconCloseComponent`: Optional object, custom component for the close icon (overrides iconCloseName) 50 | - `iconSearchComponent`: Optional object, custom component for the search icon (overrides iconSearchName) 51 | - `iconBackComponent`: Optional object, custom component for the back icon (overrides iconBackName) 52 | - `iconColor`: Optional string, use it to define a different padding size, default is `#737373` 53 | - `placeholder`: Optional string, use it to customize the placeholder text, default is `eSearch...` 54 | - `placeholderColor`: Optional string, use it to define a different placeholder color, default is `#bdbdbd` 55 | - `returnKeyType`: Optional string, use it to customize the return key type 56 | - `padding`: Optional string, use it to define a different padding size, default is `5` 57 | - `inputStyle`: Optional string, use it to pass your style to the containing `View` 58 | - `inputProps`: Optional object, use it to pass additional props to the `TextInput`, for example `{autoFocus: true}` 59 | - `textStyle`: Optional string, use it to pass your style to the `TextInput` 60 | 61 | 62 | The React packager will include the SearchBar component in your app's JS package and make it available for your app to use. 63 | 64 | 65 | # Contributing 66 | 67 | Contributions are welcome. 68 | 69 | # LICENSE 70 | 71 | MIT 72 | -------------------------------------------------------------------------------- /SearchBar.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import PropTypes from 'prop-types' 3 | import { 4 | TextInput, 5 | StyleSheet, 6 | View, 7 | TouchableOpacity, 8 | ActivityIndicator, 9 | Text, 10 | Keyboard, 11 | } from 'react-native'; 12 | import Icon from 'react-native-vector-icons/Ionicons'; 13 | 14 | const styles = StyleSheet.create({ 15 | searchBar: { 16 | flexDirection: 'row', 17 | alignItems: 'center', 18 | backgroundColor: 'transparent', 19 | borderColor: '#b6b6b6', 20 | borderStyle: 'solid', 21 | borderWidth: 1, 22 | }, 23 | searchBarInput: { 24 | flex: 1, 25 | fontWeight: 'normal', 26 | color: '#212121', 27 | backgroundColor: 'transparent', 28 | }, 29 | }); 30 | 31 | export default class SearchBar extends React.Component { 32 | static propTypes = { 33 | height: PropTypes.number.isRequired, 34 | autoCorrect: PropTypes.bool, 35 | returnKeyType: PropTypes.string, 36 | onSearchChange: PropTypes.func, 37 | onEndEditing: PropTypes.func, 38 | onSubmitEditing: PropTypes.func, 39 | placeholder: PropTypes.string, 40 | padding: PropTypes.number, 41 | inputStyle: PropTypes.oneOfType([PropTypes.object, PropTypes.array]), 42 | iconCloseComponent: PropTypes.object, 43 | iconSearchComponent: PropTypes.object, 44 | iconBackComponent: PropTypes.object, 45 | iconCloseName: PropTypes.string, 46 | iconSearchName: PropTypes.string, 47 | iconBackName: PropTypes.string, 48 | placeholderColor: PropTypes.string, 49 | iconColor: PropTypes.string, 50 | textStyle: PropTypes.oneOfType([PropTypes.object, PropTypes.array]), 51 | inputProps: PropTypes.object, 52 | onBackPress: PropTypes.func, 53 | alwaysShowBackButton: PropTypes.bool, 54 | }; 55 | 56 | static defaultProps = { 57 | onSearchChange: () => {}, 58 | onEndEditing: () => {}, 59 | onSubmitEditing: () => {}, 60 | inputStyle: {}, 61 | iconCloseName: 'md-close', 62 | iconSearchName: 'md-search', 63 | iconBackName: 'md-arrow-back', 64 | placeholder: 'Search...', 65 | returnKeyType: 'search', 66 | padding: 5, 67 | placeholderColor: '#bdbdbd', 68 | iconColor: '#737373', 69 | textStyle: {}, 70 | alwaysShowBackButton: false, 71 | searchValue: '', 72 | }; 73 | 74 | constructor(props) { 75 | super(props); 76 | this.state = { 77 | isOnFocus: false, 78 | wait: true, 79 | searchValue: props.searchValue, 80 | }; 81 | this._onSearchChange = this._onSearchChange.bind(this); 82 | this._onClear = this._onClear.bind(this); 83 | this._onFocus = this._onFocus.bind(this); 84 | this._onBlur = this._onBlur.bind(this); 85 | } 86 | 87 | _onSearchChange(searchValue) { 88 | this.setState({searchValue}); 89 | this.props.onSearchChange && this.props.onSearchChange(searchValue); 90 | } 91 | 92 | _onClear() { 93 | this._onSearchChange(''); 94 | this.props.onClear && this.props.onClear(); 95 | } 96 | 97 | _onFocus() { 98 | this.setState({isOnFocus: true}); 99 | if (this.props.onFocus) { 100 | this.props.onFocus(); 101 | } 102 | } 103 | 104 | _onBlur() { 105 | this.setState({isOnFocus: false}); 106 | if (this.props.onBlur) { 107 | this.props.onBlur(); 108 | } 109 | Keyboard.dismiss(); 110 | } 111 | 112 | _backPressed() { 113 | Keyboard.dismiss() 114 | if(this.props.onBackPress) { 115 | this.props.onBackPress() 116 | } 117 | } 118 | 119 | setText(text, focus) { 120 | this._textInput.setNativeProps({ text: text }); 121 | if (focus) { 122 | this._onFocus(); 123 | } 124 | } 125 | 126 | render() { 127 | const { 128 | height, 129 | autoCorrect, 130 | returnKeyType, 131 | placeholder, 132 | padding, 133 | inputStyle, 134 | iconColor, 135 | iconCloseComponent, 136 | iconSearchComponent, 137 | iconBackComponent, 138 | iconBackName, 139 | iconSearchName, 140 | iconCloseName, 141 | placeholderColor, 142 | textStyle, 143 | } = this.props; 144 | 145 | let { iconSize, iconPadding } = this.props 146 | 147 | iconSize = typeof iconSize !== 'undefined' ? iconSize : height * 0.5 148 | iconPadding = typeof iconPadding !== 'undefined' ? iconPadding : height * 0.25 149 | 150 | return ( 151 | 155 | 167 | {this.state.isOnFocus || this.props.alwaysShowBackButton 168 | ? 169 | { iconBackComponent ? 170 | iconBackComponent 171 | : 172 | 177 | } 178 | 179 | : 180 | ( iconSearchComponent ? 181 | iconSearchComponent 182 | : 183 | 188 | ) 189 | } 190 | this._textInput = c} 194 | returnKeyType={returnKeyType} 195 | onFocus={this._onFocus} 196 | onBlur={this._onBlur} 197 | onChangeText={this._onSearchChange} 198 | onEndEditing={this.props.onEndEditing} 199 | onSubmitEditing={this.props.onSubmitEditing} 200 | placeholder={placeholder} 201 | placeholderTextColor={placeholderColor} 202 | underlineColorAndroid="transparent" 203 | style={ 204 | [styles.searchBarInput, 205 | { 206 | paddingLeft: iconPadding, 207 | fontSize: height * 0.4, 208 | }, 209 | textStyle 210 | ] 211 | } 212 | {...this.props.inputProps} 213 | /> 214 | {this.state.isOnFocus ? 215 | 216 | { iconCloseComponent ? 217 | iconCloseComponent 218 | : 219 | 224 | } 225 | 226 | : null 227 | } 228 | 229 | 230 | ); 231 | } 232 | } 233 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "react-native-material-design-searchbar", 3 | "version": "1.8.0", 4 | "description": "A React Native Material Design SearchBar", 5 | "main": "SearchBar.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "repository": { 10 | "type": "git", 11 | "url": "https://github.com/ananddayalan/react-native-material-design-searchbar.git" 12 | }, 13 | "keywords": [ 14 | "react-native", 15 | "Search", 16 | "component", 17 | "SearchBar", 18 | "Material Design" 19 | ], 20 | "dependencies": { 21 | "prop-types": "^15.5.10", 22 | "react-native-vector-icons": "^4.2.0" 23 | }, 24 | "author": "Anand Dayalan", 25 | "license": "MIT", 26 | "bugs": { 27 | "url": "https://github.com/ananddayalan/react-native-material-design-searchbar/issues" 28 | }, 29 | "homepage": "https://github.com/ananddayalan/react-native-material-design-searchbar" 30 | } 31 | --------------------------------------------------------------------------------