Skip to content
This repository was archived by the owner on Jan 14, 2025. It is now read-only.

Commit ed14f2c

Browse files
committed
fix(checkbox): upgrade mdc-web to v1
1 parent f69db2e commit ed14f2c

File tree

5 files changed

+92
-51
lines changed

5 files changed

+92
-51
lines changed

package-lock.json

Lines changed: 52 additions & 20 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@
6464
"@material/base": "^1.0.0",
6565
"@material/button": "^0.43.0",
6666
"@material/card": "^0.41.0",
67-
"@material/checkbox": "^0.41.0",
67+
"@material/checkbox": "^1.0.0",
6868
"@material/chips": "^1.0.0",
6969
"@material/dialog": "^0.43.0",
7070
"@material/dom": "^0.41.0",

packages/checkbox/index.tsx

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,8 @@
2222

2323
import * as React from 'react';
2424
import classnames from 'classnames';
25-
// @ts-ignore no mdc .d.ts file
26-
import {MDCCheckboxFoundation, MDCCheckboxAdapter} from '@material/checkbox/dist/mdc.checkbox';
25+
import {MDCCheckboxFoundation} from '@material/checkbox/foundation';
26+
import {MDCCheckboxAdapter} from '@material/checkbox/adapter';
2727
import * as Ripple from '@material/react-ripple';
2828

2929
import NativeControl from './NativeControl';
@@ -45,20 +45,22 @@ interface CheckboxState {
4545
checked?: boolean;
4646
indeterminate?: boolean;
4747
classList: Set<string>;
48-
'aria-checked': boolean;
48+
'aria-checked': string;
49+
disabled: boolean;
4950
};
5051

5152
export class Checkbox extends React.Component<CheckboxProps, CheckboxState> {
5253
inputElement: React.RefObject<HTMLInputElement> = React.createRef();
53-
foundation = MDCCheckboxFoundation;
54+
foundation!: MDCCheckboxFoundation;
5455

5556
constructor(props: CheckboxProps) {
5657
super(props);
5758
this.state = {
5859
'checked': props.checked,
5960
'indeterminate': props.indeterminate,
6061
'classList': new Set(),
61-
'aria-checked': false,
62+
'aria-checked': 'false',
63+
'disabled': props.disabled!,
6264
};
6365
}
6466

@@ -74,7 +76,7 @@ export class Checkbox extends React.Component<CheckboxProps, CheckboxState> {
7476
componentDidMount() {
7577
this.foundation = new MDCCheckboxFoundation(this.adapter);
7678
this.foundation.init();
77-
this.foundation.setDisabled(this.props.disabled);
79+
this.foundation.setDisabled(this.props.disabled!);
7880
// indeterminate property on checkboxes is not supported:
7981
// https://github.com/facebook/react/issues/1798#issuecomment-333414857
8082
if (this.inputElement.current) {
@@ -91,7 +93,10 @@ export class Checkbox extends React.Component<CheckboxProps, CheckboxState> {
9193
this.handleChange(checked!, indeterminate!);
9294
}
9395
if (disabled !== prevProps.disabled) {
94-
this.foundation.setDisabled(disabled);
96+
this.setState({
97+
disabled: disabled!,
98+
});
99+
this.foundation.setDisabled(disabled!);
95100
}
96101
}
97102

@@ -146,10 +151,12 @@ export class Checkbox extends React.Component<CheckboxProps, CheckboxState> {
146151
// isAttachedToDOM will likely be removed
147152
// https://github.com/material-components/material-components-web/issues/3691
148153
isAttachedToDOM: () => true,
149-
isChecked: () => this.state.checked,
150-
isIndeterminate: () => this.state.indeterminate,
154+
isChecked: () => this.state.checked!,
155+
isIndeterminate: () => this.state.indeterminate!,
151156
setNativeControlAttr: this.updateState,
157+
setNativeControlDisabled: (disabled) => this.updateState('disabled', disabled),
152158
removeNativeControlAttr: this.removeState,
159+
forceLayout: () => null,
153160
};
154161
}
155162

@@ -187,7 +194,7 @@ export class Checkbox extends React.Component<CheckboxProps, CheckboxState> {
187194
id={nativeControlId}
188195
checked={this.state.checked}
189196
disabled={disabled}
190-
aria-checked={this.state['aria-checked'] || this.state.checked}
197+
aria-checked={(this.state['aria-checked'] || this.state.checked!.toString()) as ('true' | 'false')}
191198
name={name}
192199
onChange={this.onChange}
193200
rippleActivatorRef={this.inputElement}

packages/checkbox/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
"url": "https://github.com/material-components/material-components-web-react.git"
1717
},
1818
"dependencies": {
19-
"@material/checkbox": "^0.41.0",
19+
"@material/checkbox": "^1.0.0",
2020
"@material/react-ripple": "^0.11.0",
2121
"classnames": "^2.2.6",
2222
"react": "^16.3.2"

test/unit/checkbox/index.test.tsx

Lines changed: 21 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,16 @@ import {assert} from 'chai';
33
import {shallow} from 'enzyme';
44
import * as td from 'testdouble';
55
import {Checkbox} from '../../../packages/checkbox/index';
6+
import {MDCCheckboxAdapter} from '@material/checkbox/adapter';
67
import {coerceForTesting} from '../helpers/types';
78

89
suite('Checkbox');
910

11+
const getAdapter = (instance: Checkbox): MDCCheckboxAdapter => {
12+
// @ts-ignore adapter_ is a protected property, we need to override it
13+
return instance.foundation.adapter_;
14+
};
15+
1016
test('creates foundation', () => {
1117
const wrapper = shallow<Checkbox>(<Checkbox />);
1218
assert.exists(wrapper.instance().foundation);
@@ -48,84 +54,80 @@ test('native control props.checked is true when props.checked is true', () => {
4854

4955
test('#foundation.handleChange gets called when prop.checked updates', () => {
5056
const wrapper = shallow<Checkbox>(<Checkbox />);
51-
wrapper.instance().foundation.handleChange = td.func();
57+
wrapper.instance().foundation.handleChange = td.func<() => null>();
5258
wrapper.setProps({checked: true});
5359
td.verify(wrapper.instance().foundation.handleChange(), {times: 1});
5460
});
5561

5662
test('#foundation.handleChange gets called when prop.indeterminate updates', () => {
5763
const wrapper = shallow<Checkbox>(<Checkbox />);
58-
wrapper.instance().foundation.handleChange = td.func();
64+
wrapper.instance().foundation.handleChange = td.func<() => null>();
5965
wrapper.setProps({indeterminate: true});
6066
td.verify(wrapper.instance().foundation.handleChange(), {times: 1});
6167
});
6268

6369
test('#foundation.setDisabled gets called when prop.disabled updates', () => {
6470
const wrapper = shallow<Checkbox>(<Checkbox />);
65-
wrapper.instance().foundation.setDisabled = td.func();
71+
wrapper.instance().foundation.setDisabled = td.func<(disabled: boolean) => null>();
6672
wrapper.setProps({disabled: true});
6773
td.verify(wrapper.instance().foundation.setDisabled(true), {times: 1});
6874
});
6975

7076
test('#componentWillUnmount destroys foundation', () => {
7177
const wrapper = shallow<Checkbox>(<Checkbox />);
7278
const foundation = wrapper.instance().foundation;
73-
foundation.destroy = td.func();
79+
foundation.destroy = td.func<() => void>();
7480
wrapper.unmount();
7581
td.verify(foundation.destroy(), {times: 1});
7682
});
7783

7884
test('#adapter.addClass adds class to state.classList', () => {
7985
const wrapper = shallow<Checkbox>(<Checkbox />);
80-
wrapper.instance().foundation.adapter_.addClass('test-class-name');
86+
getAdapter(wrapper.instance()).addClass('test-class-name');
8187
assert.isTrue(wrapper.state().classList.has('test-class-name'));
8288
});
8389

8490
test('#adapter.removeClass removes class from state.classList', () => {
8591
const wrapper = shallow<Checkbox>(<Checkbox />);
8692
wrapper.setState({classList: new Set(['test-class-name'])});
87-
wrapper.instance().foundation.adapter_.removeClass('test-class-name');
93+
getAdapter(wrapper.instance()).removeClass('test-class-name');
8894
assert.isFalse(wrapper.state().classList.has('test-class-name'));
8995
});
9096

9197
test('#adapter.isChecked returns state.checked if true', () => {
9298
const wrapper = shallow<Checkbox>(<Checkbox />);
9399
wrapper.setState({checked: true});
94-
assert.isTrue(wrapper.instance().foundation.adapter_.isChecked());
100+
assert.isTrue(getAdapter(wrapper.instance()).isChecked());
95101
});
96102

97103
test('#adapter.isChecked returns state.checked if false', () => {
98104
const wrapper = shallow<Checkbox>(<Checkbox />);
99105
wrapper.setState({checked: false});
100-
assert.isFalse(wrapper.instance().foundation.adapter_.isChecked());
106+
assert.isFalse(getAdapter(wrapper.instance()).isChecked());
101107
});
102108

103109
test('#adapter.isIndeterminate returns state.indeterminate if true', () => {
104110
const wrapper = shallow<Checkbox>(<Checkbox />);
105111
wrapper.setState({indeterminate: true});
106-
assert.isTrue(wrapper.instance().foundation.adapter_.isIndeterminate());
112+
assert.isTrue(getAdapter(wrapper.instance()).isIndeterminate());
107113
});
108114

109115
test('#adapter.isIndeterminate returns state.indeterminate if false', () => {
110116
const wrapper = shallow<Checkbox>(<Checkbox />);
111117
wrapper.setState({indeterminate: false});
112-
assert.isFalse(wrapper.instance().foundation.adapter_.isIndeterminate());
118+
assert.isFalse(getAdapter(wrapper.instance()).isIndeterminate());
113119
});
114120

115121
test('#adapter.setNativeControlAttr sets aria-checked state', () => {
116122
const wrapper = shallow<Checkbox>(<Checkbox />);
117-
wrapper
118-
.instance()
119-
.foundation.adapter_.setNativeControlAttr('aria-checked', true);
120-
assert.isTrue(wrapper.state()['aria-checked']);
123+
getAdapter(wrapper.instance()).setNativeControlAttr('aria-checked', 'true');
124+
assert.equal(wrapper.state()['aria-checked'], 'true');
121125
});
122126

123127
test('#adapter.removeNativeControlAttr sets aria-checked state as false', () => {
124128
const wrapper = shallow<Checkbox>(<Checkbox />);
125-
wrapper.setState({'aria-checked': true});
126-
wrapper
127-
.instance()
128-
.foundation.adapter_.removeNativeControlAttr('aria-checked');
129+
wrapper.setState({'aria-checked': 'true'});
130+
getAdapter(wrapper.instance()).removeNativeControlAttr('aria-checked');
129131
assert.isFalse(wrapper.state()['aria-checked']);
130132
});
131133

@@ -148,7 +150,7 @@ test('calls foundation.handleChange in native control props.onChange', () => {
148150
indeterminate: false,
149151
},
150152
};
151-
wrapper.instance().foundation.handleChange = td.func();
153+
wrapper.instance().foundation.handleChange = td.func<() => void>();
152154
nativeControl.simulate('change', mockEvt);
153155
td.verify(wrapper.instance().foundation.handleChange(), {times: 1});
154156
});

0 commit comments

Comments
 (0)