1import Ionicons from '@expo/vector-icons/build/Ionicons';
2import React from 'react';
3import { StyleSheet, TextInput, TextStyle, TouchableOpacity, View, Platform } from 'react-native';
4
5import { Colors } from '../constants';
6
7export default function SearchBar({
8  selectionColor,
9  tintColor = Colors.tintColor,
10  placeholderTextColor = '#ccc',
11  underlineColorAndroid = '#ccc',
12  textColor,
13  onSubmit,
14  onChangeQuery,
15  initialValue = '',
16}: {
17  initialValue?: string;
18  selectionColor?: string;
19  tintColor: string;
20  placeholderTextColor?: string;
21  underlineColorAndroid?: string;
22  textColor?: string;
23  onSubmit?: (query: string) => void;
24  onChangeQuery?: (query: string) => void;
25}) {
26  const [text, setText] = React.useState(initialValue);
27  const _textInput = React.useRef<TextInput>(null);
28
29  React.useEffect(() => {
30    requestAnimationFrame(() => {
31      _textInput.current?.focus();
32    });
33  }, []);
34
35  const _handleClear = () => {
36    _handleChangeText('');
37  };
38  const _handleChangeText = (text: string) => {
39    setText(text);
40    onChangeQuery?.(text);
41  };
42
43  const _handleSubmit = () => {
44    onSubmit?.(text);
45    _textInput.current?.blur();
46  };
47
48  const searchInputStyle: TextStyle = {};
49  if (textColor) {
50    searchInputStyle.color = textColor;
51  }
52
53  return (
54    <View style={styles.container}>
55      <TextInput
56        ref={_textInput}
57        placeholder="Search"
58        placeholderTextColor={placeholderTextColor}
59        value={text}
60        autoCapitalize="none"
61        autoCorrect={false}
62        selectionColor={selectionColor}
63        underlineColorAndroid={underlineColorAndroid}
64        onSubmitEditing={_handleSubmit}
65        onChangeText={_handleChangeText}
66        style={[styles.searchInput, searchInputStyle]}
67      />
68      <View style={{ width: 50, alignItems: 'center', justifyContent: 'center' }}>
69        {text ? (
70          <TouchableOpacity
71            onPress={_handleClear}
72            hitSlop={{ top: 15, left: 10, right: 15, bottom: 15 }}
73            style={{ padding: 5 }}>
74            <Ionicons name="md-close" size={25} color={tintColor} />
75          </TouchableOpacity>
76        ) : null}
77      </View>
78    </View>
79  );
80}
81
82const styles = StyleSheet.create({
83  container: {
84    flex: 1,
85    flexDirection: 'row',
86  },
87  searchInput: {
88    flex: 1,
89    fontSize: 18,
90    marginBottom: 2,
91    paddingLeft: Platform.select({ web: 16, default: 5 }),
92    marginRight: 5,
93    ...Platform.select({
94      web: {
95        outlineColor: 'transparent',
96      },
97      default: {},
98    }),
99  },
100});
101