Skip to content

Commit 9896317

Browse files
Merge pull request #1369 from Shopify/fix-checkbox-click-disabled
[Checkbox] Fix being clicked while disabled
2 parents ddb0f72 + 2829abe commit 9896317

File tree

5 files changed

+61
-1
lines changed

5 files changed

+61
-1
lines changed

UNRELEASED.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ Use [the changelog guidelines](https://git.io/polaris-changelog-guidelines) to f
1818

1919
### Bug fixes
2020

21+
- Fixed `Checkbox` being toggled when disabled ([#1369](https://github.com/Shopify/polaris-react/pull/1369))
2122
- Fixed `DropZone.FileUpload` from incorrectly displaying action hint and title when the default is used and removed ([#1233](https://github.com/Shopify/polaris-react/pull/1233))
2223
- Fixed `ResourceList.Item` interaction states from being incorrectly applied ([#1312](https://github.com/Shopify/polaris-react/pull/1312)
2324
- Fixed selected state for date picker in windows high contrast mode ([#1342](https://github.com/Shopify/polaris-react/pull/1342))

src/components/Checkbox/Checkbox.tsx

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,23 @@ const getUniqueID = createUniqueIDFactory('Checkbox');
4545
class Checkbox extends React.PureComponent<CombinedProps, never> {
4646
private inputNode = React.createRef<HTMLInputElement>();
4747

48+
componentDidMount() {
49+
const {checked, disabled} = this.props;
50+
51+
if (checked && disabled) this.handleInput();
52+
}
53+
54+
componentDidUpdate({disabled: prevDisabled}: Props) {
55+
if (
56+
this.props.disabled &&
57+
!prevDisabled !== true &&
58+
this.inputNode.current &&
59+
this.inputNode.current.checked
60+
) {
61+
this.handleInput();
62+
}
63+
}
64+
4865
handleInput = () => {
4966
const {onChange, id} = this.props;
5067

src/components/Checkbox/tests/Checkbox.test.tsx

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,33 @@ describe('<Checkbox />', () => {
7878
checkbox.simulate('click');
7979
expect(checkbox.find('input').instance()).toBe(document.activeElement);
8080
});
81+
82+
it('is not called when disabled', () => {
83+
const spy = jest.fn();
84+
const checkbox = mountWithAppProvider(
85+
<Checkbox label="label" disabled onChange={spy} />,
86+
);
87+
checkbox.find('input').simulate('click');
88+
expect(spy).not.toHaveBeenCalled();
89+
});
90+
91+
it('is called when disabled and checked are both true on load', () => {
92+
const spy = jest.fn();
93+
mountWithAppProvider(
94+
<Checkbox label="label" id="id" disabled onChange={spy} checked />,
95+
);
96+
expect(spy).toHaveBeenCalledWith(false, 'id');
97+
});
98+
99+
it('it is called when disabled and checked are both true after initial load', () => {
100+
const spy = jest.fn();
101+
const checkbox = mountWithAppProvider(
102+
<Checkbox label="label" disabled onChange={spy} id="id" />,
103+
);
104+
105+
checkbox.setProps({checked: true});
106+
expect(spy).toHaveBeenCalledWith(false, 'id');
107+
});
81108
});
82109

83110
describe('onFocus()', () => {

src/components/Choice/Choice.tsx

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,14 +35,20 @@ export default function Choice({
3535
helpText,
3636
onClick,
3737
}: Props) {
38+
function handleClick() {
39+
if (disabled || !onClick) return;
40+
41+
onClick();
42+
}
43+
3844
const className = classNames(
3945
styles.Choice,
4046
labelHidden && styles.labelHidden,
4147
disabled && styles.disabled,
4248
);
4349

4450
const labelMarkup = (
45-
<label className={className} htmlFor={id} onClick={onClick}>
51+
<label className={className} htmlFor={id} onClick={handleClick}>
4652
<span className={styles.Control}>{children}</span>
4753
<span className={styles.Label}>{label}</span>
4854
</label>

src/components/Choice/tests/Choice.test.tsx

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,4 +86,13 @@ describe('<Choice />', () => {
8686
expect(label.find(blockLevelElements[i])).toHaveLength(0);
8787
}
8888
});
89+
90+
it('does not fire an onClick event when disabled is true', () => {
91+
const spy = jest.fn();
92+
const choice = mountWithAppProvider(
93+
<Choice id="id" label="Label" onClick={spy} disabled />,
94+
);
95+
choice.find('label').simulate('click');
96+
expect(spy).not.toHaveBeenCalled();
97+
});
8998
});

0 commit comments

Comments
 (0)