Skip to content

Commit

Permalink
Merge pull request #178 from hypothesis/checkbox-props
Browse files Browse the repository at this point in the history
Add support for extra CSS classes to Checkbox components
  • Loading branch information
lyzadanger authored Sep 23, 2021
2 parents 81e5c79 + 46c9a16 commit 2cf9a01
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 4 deletions.
27 changes: 23 additions & 4 deletions src/components/Checkbox.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
// @ts-ignore
import checkboxIcon from '../../images/icons/checkbox.svg';
import classnames from 'classnames';

import { registerIcons, SvgIcon } from './SvgIcon';

// Register the checkbox icon for use
Expand All @@ -9,6 +11,7 @@ registerIcons({

/**
* @typedef CheckboxBaseProps
* @prop {string} [classes] - Additional CSS classes to apply to the <input>
* @prop {string} name - The `name` of the checkbox.
* @prop {import('preact').Ref<HTMLInputElement>} [inputRef] - Access to the input
* element in case a parent element wants for example to focus on it.
Expand All @@ -26,6 +29,8 @@ registerIcons({
/**
* @typedef LabeledCheckboxBaseProps
* @prop {import('preact').ComponentChildren} children - Label text or elements
* @prop {string} [containerClasses] - Optional additional classes for the container
* <label> element
*
* @typedef {Omit<CheckboxProps, 'children'> & LabeledCheckboxBaseProps} LabeledCheckboxProps
*/
Expand All @@ -38,7 +43,13 @@ registerIcons({
*
* @param {CheckboxProps} props
*/
export function Checkbox({ inputRef, onToggle, onClick, ...restProps }) {
export function Checkbox({
classes = '',
inputRef,
onToggle,
onClick,
...restProps
}) {
/**
* @param {import('preact').JSX.TargetedMouseEvent<HTMLInputElement>} event
* @this HTMLInputElement
Expand All @@ -54,7 +65,7 @@ export function Checkbox({ inputRef, onToggle, onClick, ...restProps }) {
return (
<>
<input
className="Hyp-Checkbox"
className={classnames('Hyp-Checkbox', classes)}
ref={inputRef}
type="checkbox"
onClick={onPressed}
Expand All @@ -70,10 +81,18 @@ export function Checkbox({ inputRef, onToggle, onClick, ...restProps }) {
*
* @param {LabeledCheckboxProps} props
*/
export function LabeledCheckbox({ children, id, ...restProps }) {
export function LabeledCheckbox({
children,
id,
containerClasses = '',
...restProps
}) {
id ??= restProps.name;
return (
<label htmlFor={id} className="Hyp-LabeledCheckbox">
<label
htmlFor={id}
className={classnames('Hyp-LabeledCheckbox', containerClasses)}
>
<Checkbox id={id} {...restProps} />
<span data-testid="label-text">{children}</span>
</label>
Expand Down
16 changes: 16 additions & 0 deletions src/components/test/Checkbox-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,14 @@ describe('Checkbox', () => {
inputRef.current.click();
assert.calledOnce(onClick);
});

it('applies extra classes', () => {
const wrapper = createComponent({ classes: 'foo bar' });
assert.deepEqual(
[...wrapper.find('input.foo.bar').getDOMNode().classList.values()],
['Hyp-Checkbox', 'foo', 'bar']
);
});
});

describe('LabeledCheckbox', () => {
Expand Down Expand Up @@ -84,6 +92,14 @@ describe('LabeledCheckbox', () => {
onToggle.reset();
});

it('applies extra container classes', () => {
const wrapper = createComponent({ containerClasses: 'foo bar' });
assert.deepEqual(
[...wrapper.find('label.foo.bar').getDOMNode().classList.values()],
['Hyp-LabeledCheckbox', 'foo', 'bar']
);
});

it(
'should pass a11y checks',
checkAccessibility({
Expand Down

0 comments on commit 2cf9a01

Please sign in to comment.