Skip to content

Commit

Permalink
feat: readonly checkbox (#12398)
Browse files Browse the repository at this point in the history
* feat: readonly checkbox

* fix: propagate onClick

* chore: remove scss var border-readonly

* chore: cache files

* chore: convert to typescript

* fix: readonly cursor and text selection

Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
  • Loading branch information
lee-chase and kodiakhq[bot] committed Nov 14, 2022
1 parent d5390eb commit baa7fd5
Show file tree
Hide file tree
Showing 13 changed files with 84 additions and 7 deletions.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
3 changes: 3 additions & 0 deletions packages/react/__tests__/__snapshots__/PublicAPI-test.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -475,6 +475,9 @@ Map {
"onChange": Object {
"type": "func",
},
"readOnly": Object {
"type": "bool",
},
"title": Object {
"type": "string",
},
Expand Down
34 changes: 32 additions & 2 deletions packages/react/src/components/Checkbox/Checkbox.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,11 @@ export interface CheckboxProps
evt: React.ChangeEvent<HTMLInputElement>,
data: { checked: boolean; id: string }
) => void;

/**
* Provide an optional onClick handler that is called on click
*/
onClick?: (evt: React.MouseEvent<HTMLInputElement>) => void;
}

const Checkbox = React.forwardRef(
Expand All @@ -67,8 +72,10 @@ const Checkbox = React.forwardRef(
id,
labelText,
onChange,
onClick,
indeterminate,
hideLabel,
readOnly,
title = '',
...other
}: CheckboxProps,
Expand All @@ -78,7 +85,10 @@ const Checkbox = React.forwardRef(
const wrapperClasses = classNames(
`${prefix}--form-item`,
`${prefix}--checkbox-wrapper`,
[className]
className,
{
[`${prefix}--checkbox-wrapper--readonly`]: readOnly,
}
);
const innerLabelClasses = classNames(`${prefix}--checkbox-label-text`, {
[`${prefix}--visually-hidden`]: hideLabel,
Expand All @@ -90,7 +100,9 @@ const Checkbox = React.forwardRef(
{...other}
type="checkbox"
onChange={(evt) => {
onChange && onChange(evt, { checked: evt.target.checked, id });
if (!readOnly && onChange) {
onChange(evt, { checked: evt.target.checked, id });
}
}}
className={`${prefix}--checkbox`}
id={id}
Expand All @@ -104,6 +116,19 @@ const Checkbox = React.forwardRef(
ref.current = el;
}
}}
// readonly attribute not applicable to type="checkbox"
// see - https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/checkbox
aria-readonly={readOnly}
onClick={(evt) => {
if (readOnly) {
// prevent default stops the checkbox being updated
evt.preventDefault();
}
// pass onClick event on to the user even if readonly
if (onClick) {
onClick(evt);
}
}}
/>
<label
htmlFor={id}
Expand Down Expand Up @@ -165,6 +190,11 @@ Checkbox.propTypes = {
*/
onChange: PropTypes.func,

/**
* Specify whether the Checkbox is read-only
*/
readOnly: PropTypes.bool,

/**
* Specify a title for the <label> node for the Checkbox
*/
Expand Down
23 changes: 18 additions & 5 deletions packages/react/src/components/Checkbox/__tests__/Checkbox-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -78,10 +78,23 @@ describe('Checkbox', () => {
);
});

describe('indeterminate', () => {
it('should set the indeterminate attribute of the <input> to true', () => {
render(<Checkbox id="test" indeterminate labelText="test-label" />);
expect(screen.getByRole('checkbox').indeterminate).toBe(true);
});
it('should NOT call the `onChange` prop when readonly', () => {
const onChange = jest.fn();
const onClick = jest.fn();
render(
<Checkbox
id="test"
labelText="test-label"
onChange={onChange}
onClick={onClick}
checked={false}
readOnly={true}
/>
);

userEvent.click(screen.getByLabelText('test-label'));
userEvent.click(screen.getByRole('checkbox'));
expect(onClick).toHaveBeenCalled();
expect(onChange).not.toHaveBeenCalled();
});
});
31 changes: 31 additions & 0 deletions packages/styles/scss/components/checkbox/_checkbox.scss
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,37 @@
background-color: $icon-disabled;
}

//----------------------------------------------
// Read-only
// ---------------------------------------------
.#{$prefix}--checkbox-wrapper--readonly .#{$prefix}--checkbox-label {
cursor: default;
}

.#{$prefix}--checkbox-wrapper--readonly .#{$prefix}--checkbox-label-text {
cursor: text;
user-select: text;
}

.#{$prefix}--checkbox-wrapper--readonly
.#{$prefix}--checkbox
+ .#{$prefix}--checkbox-label::before {
border-color: $icon-disabled;
}

.#{$prefix}--checkbox-wrapper--readonly
.#{$prefix}--checkbox:checked
+ .#{$prefix}--checkbox-label::before {
border: 1px solid $icon-disabled;
background: transparent;
}

.#{$prefix}--checkbox-wrapper--readonly
.#{$prefix}--checkbox:checked
+ .#{$prefix}--checkbox-label::after {
border-color: $text-primary;
}

//-----------------------------------------------
// Skeleton
//-----------------------------------------------
Expand Down

0 comments on commit baa7fd5

Please sign in to comment.