outsource filterbutton to new file
make addtag popup filterable
This commit is contained in:
64
src/elements/FilterButton/FilterButton.test.js
Normal file
64
src/elements/FilterButton/FilterButton.test.js
Normal file
@@ -0,0 +1,64 @@
|
||||
import {shallow} from 'enzyme';
|
||||
import React from 'react';
|
||||
import FilterButton from './FilterButton';
|
||||
import RandomPage from "../../pages/RandomPage/RandomPage";
|
||||
import {callAPI} from "../../utils/Api";
|
||||
|
||||
describe('<FilterButton/>', function () {
|
||||
it('renders without crashing ', function () {
|
||||
const wrapper = shallow(<FilterButton onFilterChange={() => {}}/>);
|
||||
wrapper.unmount();
|
||||
});
|
||||
|
||||
it('test initial render ', function () {
|
||||
const wrapper = shallow(<FilterButton onFilterChange={() => {}}/>);
|
||||
expect(wrapper.find('input')).toHaveLength(0);
|
||||
});
|
||||
|
||||
it('test clicking', function () {
|
||||
const wrapper = shallow(<FilterButton onFilterChange={() => {}}/>);
|
||||
wrapper.simulate('click');
|
||||
|
||||
expect(wrapper.find('input')).toHaveLength(1);
|
||||
});
|
||||
|
||||
it('test call of callback on textfield change', function () {
|
||||
let val = '';
|
||||
const func = jest.fn((vali => {val = vali}));
|
||||
|
||||
const wrapper = shallow(<FilterButton onFilterChange={func}/>);
|
||||
wrapper.simulate('click');
|
||||
|
||||
wrapper.find('input').simulate('change', {target: {value: 'test'}});
|
||||
|
||||
expect(func).toHaveBeenCalledTimes(1);
|
||||
expect(val).toBe('test')
|
||||
});
|
||||
|
||||
it('test closing on x button click', function () {
|
||||
const wrapper = shallow(<FilterButton onFilterChange={() => {}}/>);
|
||||
wrapper.simulate('click');
|
||||
|
||||
expect(wrapper.find('input')).toHaveLength(1);
|
||||
|
||||
wrapper.find('Button').simulate('click');
|
||||
|
||||
expect(wrapper.find('input')).toHaveLength(0);
|
||||
});
|
||||
|
||||
it('test shortkey press', function () {
|
||||
let events = [];
|
||||
document.addEventListener = jest.fn((event, cb) => {
|
||||
events[event] = cb;
|
||||
});
|
||||
|
||||
shallow(<RandomPage/>);
|
||||
|
||||
const wrapper = shallow(<FilterButton onFilterChange={() => {}}/>);
|
||||
expect(wrapper.find('input')).toHaveLength(0);
|
||||
// trigger the keypress event
|
||||
events.keyup({key: 'f'});
|
||||
|
||||
expect(wrapper.find('input')).toHaveLength(1);
|
||||
});
|
||||
});
|
99
src/elements/FilterButton/FilterButton.tsx
Normal file
99
src/elements/FilterButton/FilterButton.tsx
Normal file
@@ -0,0 +1,99 @@
|
||||
import React from "react";
|
||||
import style from "../Popups/AddActorPopup/AddActorPopup.module.css";
|
||||
import {Button} from "../GPElements/Button";
|
||||
import {FontAwesomeIcon} from "@fortawesome/react-fontawesome";
|
||||
import {faFilter, faTimes} from "@fortawesome/free-solid-svg-icons";
|
||||
import {addKeyHandler, removeKeyHandler} from "../../utils/ShortkeyHandler";
|
||||
|
||||
interface props {
|
||||
onFilterChange: (filter: string) => void
|
||||
}
|
||||
|
||||
interface state {
|
||||
filtervisible: boolean;
|
||||
filter: string;
|
||||
}
|
||||
|
||||
class FilterButton extends React.Component<props, state> {
|
||||
// filterfield anchor, needed to focus after filter btn click
|
||||
private filterfield: HTMLInputElement | null | undefined;
|
||||
|
||||
|
||||
constructor(props: props) {
|
||||
super(props);
|
||||
|
||||
this.state = {
|
||||
filtervisible: false,
|
||||
filter: ''
|
||||
}
|
||||
|
||||
this.keypress = this.keypress.bind(this);
|
||||
this.enableFilterField = this.enableFilterField.bind(this);
|
||||
}
|
||||
|
||||
componentWillUnmount(): void {
|
||||
removeKeyHandler(this.keypress);
|
||||
}
|
||||
|
||||
componentDidMount(): void {
|
||||
addKeyHandler(this.keypress);
|
||||
}
|
||||
|
||||
render(): JSX.Element {
|
||||
if (this.state.filtervisible) {
|
||||
return (
|
||||
<>
|
||||
<input className={'form-control mr-sm-2 ' + style.searchinput}
|
||||
type='text' placeholder='Filter' value={this.state.filter}
|
||||
onChange={(e): void => {
|
||||
this.props.onFilterChange(e.target.value);
|
||||
this.setState({filter: e.target.value});
|
||||
}}
|
||||
ref={(input): void => {
|
||||
this.filterfield = input;
|
||||
}}/>
|
||||
<Button title={<FontAwesomeIcon style={{
|
||||
verticalAlign: 'middle',
|
||||
lineHeight: '130px'
|
||||
}} icon={faTimes} size='1x'/>} color={{backgroundColor: 'red'}} onClick={(): void => {
|
||||
this.setState({filter: '', filtervisible: false});
|
||||
}}/>
|
||||
</>
|
||||
);
|
||||
} else {
|
||||
return (<Button
|
||||
title={<span>Filter <FontAwesomeIcon
|
||||
style={{
|
||||
verticalAlign: 'middle',
|
||||
lineHeight: '130px'
|
||||
}}
|
||||
icon={faFilter}
|
||||
size='1x'/></span>}
|
||||
color={{backgroundColor: 'cornflowerblue', color: 'white'}}
|
||||
onClick={this.enableFilterField}/>)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* enable filterfield and focus into searchbar
|
||||
*/
|
||||
private enableFilterField(): void {
|
||||
this.setState({filtervisible: true}, () => {
|
||||
// focus filterfield after state update
|
||||
this.filterfield?.focus();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* key event handling
|
||||
* @param event keyevent
|
||||
*/
|
||||
private keypress(event: KeyboardEvent): void {
|
||||
// hide if escape is pressed
|
||||
if (event.key === 'f') {
|
||||
this.enableFilterField();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default FilterButton;
|
Reference in New Issue
Block a user