Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit de80629

Browse filesBrowse files
committed
fix(Switch): checked derived state, keyboard accessibility
- fix(Switch): checked props and state out of sync - thanks @gravitymedianet @jinixx - fix(Switch): does not provide any keyboard accessibility - thanks @roastery-zz close coreui#44
1 parent 2adf1f8 commit de80629
Copy full SHA for de80629

File tree

Expand file treeCollapse file tree

2 files changed

+42
-13
lines changed
Filter options
Expand file treeCollapse file tree

2 files changed

+42
-13
lines changed

‎src/Switch.js

Copy file name to clipboardExpand all lines: src/Switch.js
+40-11Lines changed: 40 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -45,35 +45,53 @@ const defaultProps = {
4545
class AppSwitch extends Component {
4646
constructor(props) {
4747
super(props);
48-
this.onChange = this.onChange.bind(this);
48+
this.handleChange = this.handleChange.bind(this);
49+
this.handleKeyDown = this.handleKeyDown.bind(this);
50+
this.handleKeyUp = this.handleKeyUp.bind(this);
4951
this.state = {
5052
checked: this.props.defaultChecked || this.props.checked,
5153
selected: []
5254
};
5355
}
5456

55-
onChange(event) {
56-
const target = event.target;
57+
toggleState(check) {
5758
this.setState({
58-
checked: target.checked,
59+
checked: check
5960
})
61+
}
62+
63+
handleChange(event) {
64+
const target = event.target;
65+
this.toggleState(target.checked)
6066

6167
if (this.props.onChange) {
6268
this.props.onChange(event);
6369
}
6470
}
6571

66-
componentDidUpdate(prevProps) {
67-
if (this.props.checked !== prevProps.checked) {
68-
this.setState({
69-
checked: this.props.checked
70-
})
72+
handleKeyDown(event) {
73+
if (event.key === ' ') {
74+
event.preventDefault();
75+
}
76+
}
77+
78+
handleKeyUp(event) {
79+
if (event.key === 'Enter' || event.key === ' ') {
80+
this.toggleState(!this.state.checked);
81+
}
82+
}
83+
84+
componentDidUpdate(prevProps, prevState) {
85+
if (this.props.checked !== prevState.checked) {
86+
this.toggleState(this.props.checked)
7187
}
7288
}
7389

7490
render() {
7591
const { className, disabled, color, name, label, outline, size, required, type, value, dataOn, dataOff, variant, ...attributes } = this.props;
7692

93+
const tabindex = attributes.tabIndex
94+
delete attributes.tabIndex
7795
delete attributes.checked
7896
delete attributes.defaultChecked
7997
delete attributes.onChange
@@ -98,8 +116,19 @@ class AppSwitch extends Component {
98116
);
99117

100118
return (
101-
<label className={classes}>
102-
<input type={type} className={inputClasses} onChange={this.onChange} checked={this.state.checked} name={name} required={required} disabled={disabled} value={value} {...attributes} />
119+
<label className={classes} tabIndex={tabindex} onKeyUp={this.handleKeyUp} onKeyDown={this.handleKeyDown}>
120+
<input type={type}
121+
className={inputClasses}
122+
onChange={this.handleChange}
123+
checked={this.state.checked}
124+
name={name}
125+
required={required}
126+
disabled={disabled}
127+
value={value}
128+
aria-checked={this.state.checked}
129+
aria-disabled={disabled}
130+
aria-readonly={disabled}
131+
{...attributes} />
103132
<span className={sliderClasses} data-checked={dataOn} data-unchecked={dataOff}></span>
104133
</label>
105134
);

‎tests/Switch.test.js

Copy file name to clipboardExpand all lines: tests/Switch.test.js
+2-2Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,8 +60,8 @@ describe('AppSwitch', () => {
6060
expect(onChangeMock.called).toBe(true);
6161
});
6262

63-
it('should call onChange()', () => {
64-
const onChange = spy(AppSwitch.prototype, 'onChange');
63+
it('should call handleChange()', () => {
64+
const onChange = spy(AppSwitch.prototype, 'handleChange');
6565
const event = { target: { checked: true } };
6666
const wrapper = shallow(<AppSwitch label size="lg" />);
6767
expect(wrapper.find('input').props().checked).toBe(false);

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.