Add clear button to sidebar filter (Closes #989)

This commit is contained in:
Gregory Schier 2018-06-29 14:50:08 -04:00
parent 145d566a65
commit 8ef0b03d9f
2 changed files with 80 additions and 32 deletions

View File

@ -1,5 +1,5 @@
import React, { PureComponent } from 'react';
import PropTypes from 'prop-types';
// @flow
import * as React from 'react';
import autobind from 'autobind-decorator';
import {
Dropdown,
@ -11,22 +11,37 @@ import { DEBOUNCE_MILLIS } from '../../../common/constants';
import KeydownBinder from '../keydown-binder';
import * as hotkeys from '../../../common/hotkeys';
type Props = {
onChange: string => void,
requestCreate: () => void,
requestGroupCreate: () => void,
filter: string
};
@autobind
class SidebarFilter extends PureComponent {
_setInputRef(n) {
class SidebarFilter extends React.PureComponent<Props> {
_input: ?HTMLInputElement;
_triggerTimeout: TimeoutID;
_setInputRef(n: ?HTMLInputElement) {
this._input = n;
}
_handleOnChange(e) {
const value = e.target.value;
_handleClearFilter(e: SyntheticEvent<HTMLButtonElement>) {
this.props.onChange('');
if (this._input) {
this._input.value = '';
this._input.focus();
}
}
_handleOnChange(e: SyntheticEvent<HTMLInputElement>) {
const value = e.currentTarget.value;
clearTimeout(this._triggerTimeout);
this._triggerTimeout = setTimeout(() => {
this.props.onChange(value);
}, DEBOUNCE_MILLIS);
// So we don't track on every keystroke, give analytics a longer timeout
clearTimeout(this._analyticsTimeout);
}
_handleRequestGroupCreate() {
@ -37,24 +52,32 @@ class SidebarFilter extends PureComponent {
this.props.requestCreate();
}
_handleKeydown(e) {
_handleKeydown(e: KeyboardEvent) {
hotkeys.executeHotKey(e, hotkeys.FOCUS_FILTER, () => {
this._input && this._input.focus();
});
}
render() {
const { filter } = this.props;
return (
<KeydownBinder onKeydown={this._handleKeydown}>
<div className="sidebar__filter">
<div className="form-control form-control--outlined">
<div className="form-control form-control--outlined form-control--btn-right">
<input
ref={this._setInputRef}
type="text"
placeholder="Filter"
defaultValue={this.props.filter}
defaultValue={filter}
onChange={this._handleOnChange}
/>
{filter && (
<button
className="form-control__right"
onClick={this._handleClearFilter}>
<i className="fa fa-times-circle" />
</button>
)}
</div>
<Dropdown right>
<DropdownButton className="btn btn--compact">
@ -76,12 +99,4 @@ class SidebarFilter extends PureComponent {
}
}
SidebarFilter.propTypes = {
// Required
onChange: PropTypes.func.isRequired,
requestCreate: PropTypes.func.isRequired,
requestGroupCreate: PropTypes.func.isRequired,
filter: PropTypes.string.isRequired
};
export default SidebarFilter;

View File

@ -8,6 +8,34 @@
width: 100%;
box-sizing: border-box;
&.form-control--btn-right {
position: relative;
input {
padding-right: 2em;
}
&:hover .form-control__right {
opacity: 0.8;
}
.form-control__right {
position: absolute;
right: 0;
top: 0;
padding: 0 @padding-sm;
height: 100%;
display: flex;
align-items: center;
margin: 0;
opacity: 0.5;
&:hover {
opacity: 1;
}
}
}
.input,
input,
textarea,
@ -21,13 +49,13 @@
}
button,
input[type="radio"],
input[type="checkbox"] {
input[type='radio'],
input[type='checkbox'] {
width: auto;
}
input[type="radio"],
input[type="checkbox"] {
input[type='radio'],
input[type='checkbox'] {
height: 1rem;
float: left;
margin-top: @padding-xxs;
@ -82,7 +110,7 @@
}
}
.input[data-focused="on"],
.input[data-focused='on'],
textarea:focus,
select:focus,
input:focus {
@ -91,7 +119,7 @@
}
}
&.form-control--underlined .input[data-focused="on"],
&.form-control--underlined .input[data-focused='on'],
&.form-control--underlined input:focus,
&.form-control--underlined textarea:focus {
border-color: var(--hl);
@ -255,7 +283,11 @@
}
}
textarea, input, .input, button, select {
textarea,
input,
.input,
button,
select {
transition: all 130ms ease-out;
box-sizing: border-box;
text-align: left;
@ -273,11 +305,12 @@ textarea, input, .input, button, select {
}
}
input[type=number]::-webkit-inner-spin-button {
input[type='number']::-webkit-inner-spin-button {
opacity: 0.8;
}
input.input--error, .input.input--error {
input.input--error,
.input.input--error {
border-color: var(--color-danger) !important;
}
@ -297,7 +330,7 @@ textarea.no-resize {
resize: none;
}
input[type="color"] {
input[type='color'] {
height: @line-height-xs !important;
padding: @padding-xxs !important;
}
@ -307,8 +340,8 @@ label {
position: relative;
z-index: 1;
input[type="checkbox"]:focus,
input[type="radio"]:focus {
input[type='checkbox']:focus,
input[type='radio']:focus {
&::before {
z-index: -1;
content: ' ';