Skip to content
This repository has been archived by the owner on Jan 31, 2024. It is now read-only.

Commit

Permalink
0.4.1 - Add Boolean Input
Browse files Browse the repository at this point in the history
  • Loading branch information
jducro committed Jun 27, 2018
1 parent a40e9fb commit 63f5e0d
Show file tree
Hide file tree
Showing 9 changed files with 353 additions and 5 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## 0.4.1 - 2018-06-27

* Add Boolean input

## 0.4.0 - 2018-06-22

* Double stage delete on tokens
Expand Down
2 changes: 1 addition & 1 deletion npm-shrinkwrap.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@deskpro/token-field",
"version": "0.4.0",
"version": "0.4.1",
"description": "",
"main": "dist/index.js",
"private": false,
Expand Down
169 changes: 169 additions & 0 deletions src/Components/Input/BooleanInput.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,169 @@
import React from 'react';
import PropTypes from 'prop-types';
import classNames from 'classnames/bind';
import { List, ListElement, Scrollbar } from '@deskpro/react-components';
import styles from 'styles/style.css';
import TokenInput from './TokenInput';

export default class BooleanInput extends TokenInput {
constructor(props) {
super(props);
this.detached = true;

this.state = {
...this.state,
selectedOption: null,
};

this.cx = classNames.bind(styles);
}

componentWillUnmount() {
window.document.removeEventListener('keydown', this.handleKeyDown);
}

onFocus = () => {
this.props.onFocus();
window.document.addEventListener('keydown', this.handleKeyDown);
};

onBlur = () => {
this.props.onBlur();
window.document.removeEventListener('keydown', this.handleKeyDown);
};

handleChange = (option) => {
let value;
if (option) {
value = option.id === 1;
} else {
value = null;
}
this.setState({
value,
});
this.props.onChange(value);
this.disableEditMode();
};

handleKeyDown = (e) => {
switch (e.key) {
case 'ArrowDown':
case 'ArrowUp': {
const index = this.options.findIndex((option) => {
if (this.state.selectedOption) {
return option.id === this.state.selectedOption.id;
}
return false;
});
if (e.key === 'ArrowDown' && index < this.options.length - 1) {
this.setState({
selectedOption: this.options[index + 1]
});
}
if (e.key === 'ArrowUp' && index > 0) {
this.setState({
selectedOption: this.options[index - 1]
});
}
break;
}
case 'Escape':
this.setState({
value: this.props.token.value
});
this.disableEditMode();
break;
case 'Tab':
if (e.shiftKey) {
this.props.selectPreviousToken();
} else {
this.handleChange(this.state.selectedOption);
this.props.selectNextToken();
}
this.disableEditMode();
break;
case ' ':
case 'Enter':
this.handleChange(this.state.selectedOption);
this.props.selectNextToken();
break;
default:
return true;
}
e.stopPropagation();
e.preventDefault();
return true;
};

renderInput = () => (
<div className="dp-select">
<div className="dp-select__content">
<Scrollbar>
<List className="dp-selectable-list">
{this.renderOptions()}
</List>
</Scrollbar>
</div>
</div>
);

renderOptions = () => {
const { value, selectedOption } = this.state;
const { translations } = this.props;
this.options = [
{
id: 1,
label: translations.true,
},
{
id: 0,
label: translations.false,
}
];
return (
this.options.map((option) => {
const key = option.id;
const currentValue = key === parseInt(value, 10) ? styles['current-value'] : '';
const selected = (selectedOption && option.id === selectedOption.id) ? styles.selected : '';
return (
<ListElement
key={key}
className={this.cx(currentValue, selected, 'option')}
onClick={() => this.handleChange(option)}
>
{option.label}
</ListElement>
);
}));
};

renderValue = () => {
if (this.state.value === true) {
return this.props.translations.true;
} else if (this.state.value === false) {
return this.props.translations.false;
}
return '________';
};
}

BooleanInput.propTypes = {
...TokenInput.propTypes,
token: PropTypes.shape({
type: PropTypes.string,
value: PropTypes.bool,
}).isRequired,
translations: PropTypes.shape({
true: PropTypes.string,
false: PropTypes.string
})
};

BooleanInput.defaultProps = {
...TokenInput.defaultProps,
translations: {
true: 'Yes',
false: 'No',
}
};
2 changes: 2 additions & 0 deletions src/Components/Input/index.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import BooleanInput from './BooleanInput';
import DateTimeInput from './DateTimeInput';
import DurationInput from './DurationInput';
import NumericRangeInput from './NumericRangeInput';
import SelectInput from './SelectInput';
import TextInput from './TextInput';

export {
BooleanInput,
DateTimeInput,
DurationInput,
NumericRangeInput,
Expand Down
79 changes: 79 additions & 0 deletions tests/jest/components/__snapshots__/testBooleanInput.jsx.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`+++capturing Snapshot of BooleanInput with empty value 1`] = `
<div
className="token test"
>
<div>
<div
className="dp-code label"
>
:
</div>
<span
className="value"
onClick={[Function]}
>
________
</span>
</div>
<div
className="token-remove remove"
onClick={[Function]}
>
X
</div>
</div>
`;

exports[`+++capturing Snapshot of BooleanInput with false set 1`] = `
<div
className="token test"
>
<div>
<div
className="dp-code label"
>
:
</div>
<span
className="value"
onClick={[Function]}
>
No
</span>
</div>
<div
className="token-remove remove"
onClick={[Function]}
>
X
</div>
</div>
`;

exports[`+++capturing Snapshot of BooleanInput with true set 1`] = `
<div
className="token test"
>
<div>
<div
className="dp-code label"
>
:
</div>
<span
className="value"
onClick={[Function]}
>
Yes
</span>
</div>
<div
className="token-remove remove"
onClick={[Function]}
>
X
</div>
</div>
`;
57 changes: 57 additions & 0 deletions tests/jest/components/testBooleanInput.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import React from 'react';
import Enzyme from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';
import renderer from 'react-test-renderer';
import BooleanInput from 'Components/Input/BooleanInput';
import { noop } from '@deskpro/react-components/dist/utils';

Enzyme.configure({ adapter: new Adapter() });

it('+++capturing Snapshot of BooleanInput with true set', () => {
const token = {
type: 'user-message',
value: true
};
const renderedValue = renderer.create(
<BooleanInput
token={token}
className="test"
selectPreviousToken={noop}
selectNextToken={noop}
removeToken={noop}
/>
).toJSON();
expect(renderedValue).toMatchSnapshot();
});
it('+++capturing Snapshot of BooleanInput with false set', () => {
const token = {
type: 'user-message',
value: false
};
const renderedValue = renderer.create(
<BooleanInput
token={token}
className="test"
selectPreviousToken={noop}
selectNextToken={noop}
removeToken={noop}
/>
).toJSON();
expect(renderedValue).toMatchSnapshot();
});
it('+++capturing Snapshot of BooleanInput with empty value', () => {
const token = {
type: 'user-message',
value: null
};
const renderedValue = renderer.create(
<BooleanInput
token={token}
className="test"
selectPreviousToken={noop}
selectNextToken={noop}
removeToken={noop}
/>
).toJSON();
expect(renderedValue).toMatchSnapshot();
});
36 changes: 36 additions & 0 deletions tests/storybook/components/input/BooleanInput.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import React from 'react';
import { storiesOf } from '@storybook/react';
import { action } from '@storybook/addon-actions';
import BooleanInput from 'Components/Input/BooleanInput';

const textToken = {
type: 'user-message',
value: true
};
const textTokenEmpty = {
type: 'person-email',
value: null
};

storiesOf('Inputs', module)
.add('BooleanInput', () => (
<div>
<BooleanInput
token={textToken}
label="user-message"
selectPreviousToken={action('SelectPreviousToken')}
selectNextToken={action('selectNextToken')}
removeToken={action('removeToken')}
className="test"
/>
<BooleanInput
token={textTokenEmpty}
label="person-email"
selectPreviousToken={action('SelectPreviousToken')}
selectNextToken={action('selectNextToken')}
removeToken={action('removeToken')}
className="test"
/>
</div>
))
;
7 changes: 4 additions & 3 deletions tests/storybook/index.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import '../../src/styles/deskpro-components.scss';
import './components/TokenField';
import './components/input/TextInput';
import './components/input/NumericRangeInput';
import './components/input/SelectInput';
import './components/input/BooleanInput';
import './components/input/DateTimeInput';
import './components/input/DurationInput';
import './components/input/NumericRangeInput';
import './components/input/SelectInput';
import './components/input/TextInput';

0 comments on commit 63f5e0d

Please sign in to comment.