UNPKG

terriajs

Version:

Geospatial data visualization platform.

111 lines (94 loc) 3.61 kB
import React from 'react'; import PropTypes from 'prop-types'; import createReactClass from 'create-react-class'; import debounce from 'lodash.debounce'; import Icon from "../Icon.jsx"; import Styles from './search-box.scss'; const DEBOUNCE_INTERVAL = 2000; /** * Simple dumb search box component that leaves the actual execution of searches to the component that renders it. Note * that just like an input, this calls onSearchTextChanged when the value is changed, and expects that its parent * component will listen for this and update searchText with the new value. */ export default createReactClass({ displayName: 'SearchBox', propTypes: { /** Called when the search changes, after a debounce of {@link DEBOUNCE_INTERVAL} ms */ onSearchTextChanged: PropTypes.func.isRequired, /** Called when an actual search is triggered, either by clicking the button or pressing Enter */ onDoSearch: PropTypes.func.isRequired, /** The search text to display in the search box */ searchText: PropTypes.string.isRequired, /** Called when the search box receives focus */ onFocus: PropTypes.func, placeholder: PropTypes.string, onClear: PropTypes.func, alwaysShowClear: PropTypes.bool, autoFocus: PropTypes.bool }, getDefaultProps() { return { placeholder: 'Search', alwaysShowClear: false, autoFocus: false }; }, /* eslint-disable-next-line camelcase */ UNSAFE_componentWillMount() { this.searchWithDebounce = debounce(this.search, DEBOUNCE_INTERVAL); }, componentWillUnmount() { this.removeDebounce(); }, hasValue() { return this.props.searchText.length > 0; }, search() { this.removeDebounce(); this.props.onDoSearch(); }, removeDebounce() { this.searchWithDebounce.cancel(); }, handleChange(event) { const value = event.target.value; this.props.onSearchTextChanged(value); this.searchWithDebounce(); }, clearSearch() { this.props.onSearchTextChanged(''); this.search(); if (this.props.onClear) { this.props.onClear(); } }, onKeyDown(event) { if (event.keyCode === 13) { this.search(); } }, render() { const clearButton = ( <button type='button' className={Styles.searchClear} onClick={this.clearSearch}><Icon glyph={Icon.GLYPHS.close}/></button> ); return ( <form className={Styles.searchData} autoComplete='off' onSubmit={event => event.preventDefault()}> <label htmlFor='search' className={Styles.formLabel}> <Icon glyph={Icon.GLYPHS.search}/> </label> <input id='search' type='text' name='search' value={this.props.searchText} onChange={this.handleChange} onFocus={this.props.onFocus} onKeyDown={this.onKeyDown} className={Styles.searchField} placeholder={this.props.placeholder} autoComplete='off' autoFocus={this.props.autoFocus} /> {(this.props.alwaysShowClear || this.hasValue()) && clearButton} </form> ); } });