1 | var __rest = (this && this.__rest) || function (s, e) {
|
2 | var t = {};
|
3 | for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
4 | t[p] = s[p];
|
5 | if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
6 | for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
7 | if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
8 | t[p[i]] = s[p[i]];
|
9 | }
|
10 | return t;
|
11 | };
|
12 | import React, { Component } from 'react';
|
13 | import { StyleSheet, View, ActivityIndicator, Keyboard, } from 'react-native';
|
14 | import { renderNode } from '../helpers';
|
15 | import Input from '../input/Input';
|
16 | import Icon from '../icons/Icon';
|
17 | const defaultSearchIcon = (theme) => {
|
18 | var _a, _b, _c;
|
19 | return ({
|
20 | type: 'material',
|
21 | size: 25,
|
22 | color: (_c = (_b = (_a = theme === null || theme === void 0 ? void 0 : theme.colors) === null || _a === void 0 ? void 0 : _a.platform) === null || _b === void 0 ? void 0 : _b.android) === null || _c === void 0 ? void 0 : _c.grey,
|
23 | name: 'search',
|
24 | });
|
25 | };
|
26 | const defaultCancelIcon = (theme) => {
|
27 | var _a, _b, _c;
|
28 | return ({
|
29 | type: 'material',
|
30 | size: 25,
|
31 | color: (_c = (_b = (_a = theme === null || theme === void 0 ? void 0 : theme.colors) === null || _a === void 0 ? void 0 : _a.platform) === null || _b === void 0 ? void 0 : _b.android) === null || _c === void 0 ? void 0 : _c.grey,
|
32 | name: 'arrow-back',
|
33 | });
|
34 | };
|
35 | const defaultClearIcon = (theme) => {
|
36 | var _a, _b, _c;
|
37 | return ({
|
38 | type: 'material',
|
39 | size: 25,
|
40 | color: (_c = (_b = (_a = theme === null || theme === void 0 ? void 0 : theme.colors) === null || _a === void 0 ? void 0 : _a.platform) === null || _b === void 0 ? void 0 : _b.android) === null || _c === void 0 ? void 0 : _c.grey,
|
41 | name: 'clear',
|
42 | });
|
43 | };
|
44 | class SearchBar extends Component {
|
45 | constructor(props) {
|
46 | super(props);
|
47 | this.focus = () => {
|
48 | this.input.focus();
|
49 | };
|
50 | this.blur = () => {
|
51 | this.input.blur();
|
52 | };
|
53 | this.clear = () => {
|
54 | this.input.clear();
|
55 | this.onChangeText('');
|
56 | this.props.onClear();
|
57 | };
|
58 | this.cancel = () => {
|
59 | this.blur();
|
60 | this.props.onCancel();
|
61 | };
|
62 | this.onFocus = (event) => {
|
63 | this.props.onFocus(event);
|
64 | this.setState({
|
65 | hasFocus: true,
|
66 | isEmpty: this.props.value === '',
|
67 | });
|
68 | };
|
69 | this.onBlur = (event) => {
|
70 | this.props.onBlur(event);
|
71 | this.setState({ hasFocus: false });
|
72 | };
|
73 | this.onChangeText = (text) => {
|
74 | this.props.onChangeText(text);
|
75 | this.setState({ isEmpty: text === '' });
|
76 | };
|
77 | this._keyboardDidHide = () => {
|
78 | this.cancel();
|
79 | };
|
80 | const { value = '' } = props;
|
81 | this.state = {
|
82 | hasFocus: false,
|
83 | isEmpty: value ? value === '' : true,
|
84 | };
|
85 | Keyboard.addListener('keyboardDidHide', this._keyboardDidHide);
|
86 | }
|
87 | componentWillUnmount() {
|
88 | Keyboard.removeListener('keyboardDidHide', this._keyboardDidHide);
|
89 | }
|
90 | render() {
|
91 | var _a;
|
92 | const _b = this.props, { theme, clearIcon = { name: 'clear' }, containerStyle, leftIconContainerStyle, rightIconContainerStyle, inputContainerStyle, inputStyle, searchIcon = { name: 'search' }, cancelIcon = { name: 'arrow-back' }, showLoading = false, loadingProps = {} } = _b, attributes = __rest(_b, ["theme", "clearIcon", "containerStyle", "leftIconContainerStyle", "rightIconContainerStyle", "inputContainerStyle", "inputStyle", "searchIcon", "cancelIcon", "showLoading", "loadingProps"]);
|
93 | const { hasFocus, isEmpty } = this.state;
|
94 | const { style: loadingStyle } = loadingProps, otherLoadingProps = __rest(loadingProps, ["style"]);
|
95 | return (<View style={StyleSheet.flatten([
|
96 | {
|
97 | backgroundColor: (_a = theme === null || theme === void 0 ? void 0 : theme.colors) === null || _a === void 0 ? void 0 : _a.white,
|
98 | paddingTop: 8,
|
99 | paddingBottom: 8,
|
100 | },
|
101 | containerStyle,
|
102 | ])}>
|
103 | <Input testID="searchInput" renderErrorMessage={false} {...attributes} onFocus={this.onFocus} onBlur={this.onBlur} onChangeText={this.onChangeText} ref={(input) => {
|
104 | this.input = input;
|
105 | }} containerStyle={{ paddingHorizontal: 0 }} inputStyle={StyleSheet.flatten([styles.input, inputStyle])} inputContainerStyle={StyleSheet.flatten([
|
106 | styles.inputContainer,
|
107 | inputContainerStyle,
|
108 | ])} leftIcon={hasFocus
|
109 | ? renderNode(Icon, cancelIcon, Object.assign(Object.assign({}, defaultCancelIcon(theme)), { onPress: this.cancel }))
|
110 | : renderNode(Icon, searchIcon, defaultSearchIcon(theme))} leftIconContainerStyle={StyleSheet.flatten([
|
111 | styles.leftIconContainerStyle,
|
112 | leftIconContainerStyle,
|
113 | ])} rightIcon={<View style={{ flexDirection: 'row' }}>
|
114 | {showLoading && (<ActivityIndicator key="loading" style={StyleSheet.flatten([{ marginRight: 5 }, loadingStyle])} {...otherLoadingProps}/>)}
|
115 | {!isEmpty &&
|
116 | renderNode(Icon, clearIcon, Object.assign(Object.assign({}, defaultClearIcon(theme)), { key: 'cancel', onPress: this.clear }))}
|
117 | </View>} rightIconContainerStyle={StyleSheet.flatten([
|
118 | styles.rightIconContainerStyle,
|
119 | rightIconContainerStyle,
|
120 | ])}/>
|
121 | </View>);
|
122 | }
|
123 | }
|
124 | SearchBar.defaultProps = {
|
125 | onClear: () => null,
|
126 | onCancel: () => null,
|
127 | onFocus: () => null,
|
128 | onBlur: () => null,
|
129 | onChangeText: () => null,
|
130 | };
|
131 | const styles = StyleSheet.create({
|
132 | input: {
|
133 | marginLeft: 24,
|
134 | marginRight: 8,
|
135 | },
|
136 | inputContainer: {
|
137 | borderBottomWidth: 0,
|
138 | width: '100%',
|
139 | },
|
140 | rightIconContainerStyle: {
|
141 | marginRight: 8,
|
142 | },
|
143 | leftIconContainerStyle: {
|
144 | marginLeft: 8,
|
145 | },
|
146 | });
|
147 | export default SearchBar;
|