Skip to content

Commit

Permalink
feat(controls): Add Checkbox component for settings (#1376)
Browse files Browse the repository at this point in the history
* feat(controls): Add Checkbox component for settings

* chore: pr comments

* chore: pr comments

Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
  • Loading branch information
Conrad Chan and mergify[bot] authored May 11, 2021
1 parent 16a1dc4 commit b103cd5
Show file tree
Hide file tree
Showing 4 changed files with 88 additions and 0 deletions.
2 changes: 2 additions & 0 deletions src/lib/viewers/controls/settings/Settings.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import React from 'react';
import classNames from 'classnames';
import SettingsCheckboxItem from './SettingsCheckboxItem';
import SettingsContext, { Menu, Rect } from './SettingsContext';
import SettingsFlyout from './SettingsFlyout';
import SettingsGearToggle, { Ref as SettingsToggleRef } from './SettingsToggle';
Expand Down Expand Up @@ -92,6 +93,7 @@ export default function Settings({
);
}

Settings.CheckboxItem = SettingsCheckboxItem;
Settings.Context = SettingsContext;
Settings.Menu = SettingsMenu;
Settings.MenuBack = SettingsMenuBack;
Expand Down
18 changes: 18 additions & 0 deletions src/lib/viewers/controls/settings/SettingsCheckboxItem.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
@import './styles';

$bp-SettingsCheckboxItem-spacing: 6px;

.bp-SettingsCheckboxItem {
color: $bdl-gray-62;
white-space: nowrap;
}

.bp-SettingsCheckboxItem-input,
.bp-SettingsCheckboxItem-label {
padding: $bp-SettingsCheckboxItem-spacing;
user-select: none;
}

.bp-SettingsCheckboxItem-input {
margin: $bp-SettingsCheckboxItem-spacing 0;
}
32 changes: 32 additions & 0 deletions src/lib/viewers/controls/settings/SettingsCheckboxItem.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import React from 'react';
import uniqueId from 'lodash/uniqueId';
import './SettingsCheckboxItem.scss';

export type Props = {
isChecked: boolean;
label: string;
onChange: (isChecked: boolean) => void;
};

export default function SettingsCheckboxItem({ isChecked, label, onChange }: Props): JSX.Element {
const { current: id } = React.useRef(uniqueId('bp-SettingsCheckboxItem_'));

const handleChange = (event: React.ChangeEvent<HTMLInputElement>): void => {
onChange(event.target.checked);
};

return (
<div className="bp-SettingsCheckboxItem">
<input
checked={isChecked}
className="bp-SettingsCheckboxItem-input"
id={id}
onChange={handleChange}
type="checkbox"
/>
<label className="bp-SettingsCheckboxItem-label" htmlFor={id}>
{label}
</label>
</div>
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import React from 'react';
import { shallow, ShallowWrapper } from 'enzyme';
import SettingsCheckboxItem from '../SettingsCheckboxItem';

describe('SettingsCheckboxItem', () => {
const getWrapper = (props = {}): ShallowWrapper =>
shallow(<SettingsCheckboxItem isChecked label="label" onChange={jest.fn()} {...props} />);

describe('onChange()', () => {
test.each([true, false])('should call onChange with the new checked value when initially %s', isChecked => {
const nextIsChecked = !isChecked;
const onChange = jest.fn();
const wrapper = getWrapper({ isChecked, onChange });

wrapper.find('input').simulate('change', { target: { checked: nextIsChecked } });

expect(onChange).toBeCalledWith(nextIsChecked);
});
});

describe('render', () => {
test('should return a valid wrapper', () => {
const wrapper = getWrapper({ label: 'foo' });

expect(wrapper.hasClass('bp-SettingsCheckboxItem')).toBe(true);
expect(wrapper.exists('input')).toBe(true);
expect(wrapper.find('label').text()).toBe('foo');
});

test.each([true, false])('should set checked attribute as when specified as %s', isChecked => {
const wrapper = getWrapper({ isChecked });

expect(wrapper.find('input').prop('checked')).toBe(isChecked);
});
});
});

0 comments on commit b103cd5

Please sign in to comment.