All files / app/components SearchInput.tsx

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112                                          4x         4x               4x           4x                 4x 3x           3x 3x       3x 3x 1x         4x                 7x 7x                         8x                   3x 1x 1x 1x     3x 1x      
import React from 'react';
import { style } from 'app/styles';
 
import { debounce } from 'app/utilities/debounce';
import { SearchIcon } from 'app/components/SearchIcon';
 
export interface SearchInputProps {
  value: string;
  onChange: (value) => void;
  onClear: () => void;
  onFocus?: (evt) => void;
  onBlur?: (evt) => void;
  onKeyDown?: (evt) => void;
  placeholder?: string;
  style?: object;
}
 
interface SearchInputState {
  value: string;
}
 
const containerStyle = {
  _extends: ['flexRow', 'borderedPanel', 'normalText', 'selectable'],
  position: 'relative',
  padding: 5,
};
const searchInputStyle = {
  flexGrow: 1,
  border: 'none',
  fontSize: 14,
  margin: '0px 5px',
  color: '@colors.inputForeground',
  backgroundColor: '@colors.inputBackground',
};
const clearIconStyle = {
  _extends: ['smallerText'],
  paddingTop: 3,
  flexGrow: 0,
  cursor: 'pointer',
};
const searchIconStyle = {
  marginTop: 2,
  fill: '@colors.text',
};
 
export class SearchInput extends React.Component<
  SearchInputProps,
  SearchInputState
> {
  static displayName = 'SearchInput';
  readonly state: SearchInputState = { value: '' };
 
  private inputRef;
  private debouncedCallChangeCallback;
 
  constructor(props) {
    super(props);
    this.debouncedCallChangeCallback = debounce(this.callChangeCallback, 750);
  }
 
  componentDidMount() {
    this.inputRef && this.inputRef.focus();
    if (this.props.value !== this.state.value) {
      this.setState({ value: this.props.value });
    }
  }
 
  componentDidUpdate(prevProps) {
    Iif (
      prevProps.value !== this.props.value &&
      this.props.value !== this.state.value
    ) {
      this.setState({ value: this.props.value });
    }
  }
 
  render() {
    const { onClear, onFocus, onBlur, onKeyDown, placeholder } = this.props;
    return (
      <div style={style(containerStyle, this.props.style)}>
        <SearchIcon height={16} width={16} style={style(searchIconStyle)} />
        <input
          type="text"
          style={style(searchInputStyle)}
          value={this.state.value || ''}
          placeholder={placeholder}
          onChange={this.onInputChange}
          onFocus={onFocus}
          onBlur={onBlur}
          onKeyDown={onKeyDown}
          ref={input => {
            this.inputRef = input;
          }}
        />
        <div style={style(clearIconStyle)} onClick={onClear}>
          X
        </div>
      </div>
    );
  }
 
  onInputChange = evt => {
    const newValue = evt.target.value;
    this.setState({ value: newValue });
    this.debouncedCallChangeCallback(newValue);
  };
 
  callChangeCallback = value => {
    this.props.onChange(value);
  };
}