Sticky focus on off-screen filter (#83)

This commit is contained in:
Maciej Hirsz
2018-10-10 16:13:10 +02:00
committed by GitHub
parent 491b70fae9
commit aa5bbba1bf
3 changed files with 30 additions and 13 deletions
@@ -18,7 +18,6 @@ const MAP_HEIGHT_ADJUST = 400 / 350;
const HEADER = 148;
const ESCAPE_KEY = 27;
const BACKSPACE_KEY = 8;
import './Chain.css';
@@ -74,12 +73,12 @@ export class Chain extends React.Component<Chain.Props, Chain.State> {
this.calculateMapDimensions();
window.addEventListener('resize', this.calculateMapDimensions);
window.addEventListener('keyup', this.onKeyPress);
window.addEventListener('keyup', this.onKeyUp);
}
public componentWillUnmount() {
window.removeEventListener('resize', this.calculateMapDimensions);
window.removeEventListener('keyup', this.onKeyPress);
window.removeEventListener('keyup', this.onKeyUp);
}
public render() {
@@ -252,20 +251,18 @@ export class Chain extends React.Component<Chain.Props, Chain.State> {
this.setState({ map: { top, left, width, height }});
}
private onKeyPress = (event: KeyboardEvent) => {
private onKeyUp = (event: KeyboardEvent) => {
if (event.ctrlKey) {
return;
}
const { filter } = this.state;
const key = event.key;
const code = event.keyCode;
const escape = filter != null && code === ESCAPE_KEY;
const backspace = filter === '' && code === BACKSPACE_KEY;
const escape = filter != null && event.keyCode === ESCAPE_KEY;
const singleChar = filter == null && key.length === 1;
if (escape || backspace) {
if (escape) {
this.setState({ filter: null });
} else if (singleChar) {
this.setState({ filter: key });
@@ -9,13 +9,19 @@ import './Filter.css';
export namespace Filter {
export interface Props {
value: Maybe<string>;
onChange: (value: string) => void;
onChange: (value: Maybe<string>) => void;
}
}
const ESCAPE_KEY = 27;
export class Filter extends React.Component<Filter.Props, {}> {
private filterInput: HTMLInputElement;
public componentDidMount() {
this.filterInput.focus();
}
public shouldComponentUpdate(nextProps: Filter.Props): boolean {
if (this.props.value === nextProps.value && this.props.onChange === nextProps.onChange) {
return false;
@@ -40,7 +46,7 @@ export class Filter extends React.Component<Filter.Props, {}> {
return (
<div className={className}>
<Icon src={searchIcon} />
<input ref={this.onRef} value={value || ''} onChange={this.onChange} />
<input ref={this.onRef} value={value || ''} onChange={this.onChange} onKeyUp={this.onKeyUp} onBlur={this.onBlur} />
</div>
);
}
@@ -52,6 +58,20 @@ export class Filter extends React.Component<Filter.Props, {}> {
private onChange = () => {
const { value } = this.filterInput;
this.props.onChange(value);
this.props.onChange(value === '' ? null : value);
}
private onKeyUp = (event: React.KeyboardEvent<HTMLInputElement>) => {
event.stopPropagation();
if (event.keyCode === ESCAPE_KEY) {
this.props.onChange(null);
}
}
private onBlur = (event: React.FocusEvent<HTMLInputElement>) => {
if (this.props.value == null) {
this.filterInput.focus();
}
}
}
+2 -2
View File
@@ -22,13 +22,13 @@ export class Setting extends React.Component<Setting.Props, {}> {
const className = checked ? "Setting Setting-on" : "Setting";
return (
<p className={className} onClick={this.toggle}>
<div className={className} onClick={this.toggle}>
<Icon src={icon} alt={label} />
{label}
<span className="Setting-switch">
<span className="Setting-knob" />
</span>
</p>
</div>
);
}