@khanacademy/wonder-blocks-clickable 2.2.2 → 2.2.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +21 -1
- package/dist/es/index.js +11 -6
- package/dist/index.js +11 -6
- package/package.json +3 -3
- package/src/__tests__/__snapshots__/generated-snapshot.test.js.snap +2 -2
- package/src/components/__tests__/clickable-behavior.test.js +2 -2
- package/src/components/__tests__/clickable.test.js +43 -0
- package/src/components/clickable-behavior.js +9 -5
- package/src/components/clickable.js +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,6 +1,26 @@
|
|
|
1
1
|
# @khanacademy/wonder-blocks-clickable
|
|
2
2
|
|
|
3
|
+
## 2.2.5
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Updated dependencies [246a921d]
|
|
8
|
+
- @khanacademy/wonder-blocks-core@4.3.0
|
|
9
|
+
|
|
10
|
+
## 2.2.4
|
|
11
|
+
|
|
12
|
+
### Patch Changes
|
|
13
|
+
|
|
14
|
+
- 166ecc97: Use `aria-disabled` instead of disabled, fix focused + disabled styles.
|
|
15
|
+
|
|
16
|
+
## 2.2.3
|
|
17
|
+
|
|
18
|
+
### Patch Changes
|
|
19
|
+
|
|
20
|
+
- @khanacademy/wonder-blocks-core@4.2.1
|
|
21
|
+
|
|
3
22
|
## 2.2.2
|
|
23
|
+
|
|
4
24
|
### Patch Changes
|
|
5
25
|
|
|
6
|
-
-
|
|
26
|
+
- 901bfe82: Change disabled tabindex from -1 to 0
|
package/dist/es/index.js
CHANGED
|
@@ -50,8 +50,6 @@ const disabledHandlers = {
|
|
|
50
50
|
onTouchCancel: () => void 0,
|
|
51
51
|
onKeyDown: () => void 0,
|
|
52
52
|
onKeyUp: () => void 0,
|
|
53
|
-
onFocus: () => void 0,
|
|
54
|
-
onBlur: () => void 0,
|
|
55
53
|
// Clickable components should still be tabbable so they can
|
|
56
54
|
// be used as anchors.
|
|
57
55
|
tabIndex: 0
|
|
@@ -147,9 +145,12 @@ const startState = {
|
|
|
147
145
|
|
|
148
146
|
class ClickableBehavior extends React.Component {
|
|
149
147
|
static getDerivedStateFromProps(props, state) {
|
|
150
|
-
// If new props are disabled, reset the hovered/
|
|
148
|
+
// If new props are disabled, reset the hovered/pressed states
|
|
151
149
|
if (props.disabled) {
|
|
152
|
-
|
|
150
|
+
// Keep the focused state for enabling keyboard navigation.
|
|
151
|
+
return _extends({}, startState, {
|
|
152
|
+
focused: state.focused
|
|
153
|
+
});
|
|
153
154
|
} else {
|
|
154
155
|
// Cannot return undefined
|
|
155
156
|
return null;
|
|
@@ -463,7 +464,11 @@ class ClickableBehavior extends React.Component {
|
|
|
463
464
|
}
|
|
464
465
|
|
|
465
466
|
render() {
|
|
466
|
-
const childrenProps = this.props.disabled ? disabledHandlers
|
|
467
|
+
const childrenProps = this.props.disabled ? _extends({}, disabledHandlers, {
|
|
468
|
+
// Keep these handlers for keyboard accessibility.
|
|
469
|
+
onFocus: this.handleFocus,
|
|
470
|
+
onBlur: this.handleBlur
|
|
471
|
+
}) : {
|
|
467
472
|
onClick: this.handleClick,
|
|
468
473
|
onMouseEnter: this.handleMouseEnter,
|
|
469
474
|
onMouseLeave: this.handleMouseLeave,
|
|
@@ -602,7 +607,7 @@ class Clickable extends React.Component {
|
|
|
602
607
|
} else {
|
|
603
608
|
return /*#__PURE__*/React.createElement(StyledButton, _extends({}, commonProps, {
|
|
604
609
|
type: "button",
|
|
605
|
-
disabled: this.props.disabled
|
|
610
|
+
"aria-disabled": this.props.disabled
|
|
606
611
|
}), this.props.children(clickableState));
|
|
607
612
|
}
|
|
608
613
|
};
|
package/dist/index.js
CHANGED
|
@@ -164,8 +164,6 @@ const disabledHandlers = {
|
|
|
164
164
|
onTouchCancel: () => void 0,
|
|
165
165
|
onKeyDown: () => void 0,
|
|
166
166
|
onKeyUp: () => void 0,
|
|
167
|
-
onFocus: () => void 0,
|
|
168
|
-
onBlur: () => void 0,
|
|
169
167
|
// Clickable components should still be tabbable so they can
|
|
170
168
|
// be used as anchors.
|
|
171
169
|
tabIndex: 0
|
|
@@ -261,9 +259,12 @@ const startState = {
|
|
|
261
259
|
|
|
262
260
|
class ClickableBehavior extends react__WEBPACK_IMPORTED_MODULE_0__["Component"] {
|
|
263
261
|
static getDerivedStateFromProps(props, state) {
|
|
264
|
-
// If new props are disabled, reset the hovered/
|
|
262
|
+
// If new props are disabled, reset the hovered/pressed states
|
|
265
263
|
if (props.disabled) {
|
|
266
|
-
|
|
264
|
+
// Keep the focused state for enabling keyboard navigation.
|
|
265
|
+
return { ...startState,
|
|
266
|
+
focused: state.focused
|
|
267
|
+
};
|
|
267
268
|
} else {
|
|
268
269
|
// Cannot return undefined
|
|
269
270
|
return null;
|
|
@@ -577,7 +578,11 @@ class ClickableBehavior extends react__WEBPACK_IMPORTED_MODULE_0__["Component"]
|
|
|
577
578
|
}
|
|
578
579
|
|
|
579
580
|
render() {
|
|
580
|
-
const childrenProps = this.props.disabled ? disabledHandlers
|
|
581
|
+
const childrenProps = this.props.disabled ? { ...disabledHandlers,
|
|
582
|
+
// Keep these handlers for keyboard accessibility.
|
|
583
|
+
onFocus: this.handleFocus,
|
|
584
|
+
onBlur: this.handleBlur
|
|
585
|
+
} : {
|
|
581
586
|
onClick: this.handleClick,
|
|
582
587
|
onMouseEnter: this.handleMouseEnter,
|
|
583
588
|
onMouseLeave: this.handleMouseLeave,
|
|
@@ -1214,7 +1219,7 @@ class Clickable extends react__WEBPACK_IMPORTED_MODULE_0__["Component"] {
|
|
|
1214
1219
|
} else {
|
|
1215
1220
|
return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__["createElement"](StyledButton, _extends({}, commonProps, {
|
|
1216
1221
|
type: "button",
|
|
1217
|
-
disabled: this.props.disabled
|
|
1222
|
+
"aria-disabled": this.props.disabled
|
|
1218
1223
|
}), this.props.children(clickableState));
|
|
1219
1224
|
}
|
|
1220
1225
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@khanacademy/wonder-blocks-clickable",
|
|
3
|
-
"version": "2.2.
|
|
3
|
+
"version": "2.2.5",
|
|
4
4
|
"design": "v1",
|
|
5
5
|
"description": "Clickable component for Wonder-Blocks.",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
},
|
|
17
17
|
"dependencies": {
|
|
18
18
|
"@babel/runtime": "^7.16.3",
|
|
19
|
-
"@khanacademy/wonder-blocks-core": "^4.
|
|
19
|
+
"@khanacademy/wonder-blocks-core": "^4.3.0"
|
|
20
20
|
},
|
|
21
21
|
"peerDependencies": {
|
|
22
22
|
"aphrodite": "^1.2.5",
|
|
@@ -26,6 +26,6 @@
|
|
|
26
26
|
"react-router-dom": "5.3.0"
|
|
27
27
|
},
|
|
28
28
|
"devDependencies": {
|
|
29
|
-
"wb-dev-build-settings": "^0.
|
|
29
|
+
"wb-dev-build-settings": "^0.3.0"
|
|
30
30
|
}
|
|
31
31
|
}
|
|
@@ -21,9 +21,9 @@ exports[`wonder-blocks-clickable example 1 1`] = `
|
|
|
21
21
|
}
|
|
22
22
|
>
|
|
23
23
|
<button
|
|
24
|
+
aria-disabled={false}
|
|
24
25
|
aria-label=""
|
|
25
26
|
className=""
|
|
26
|
-
disabled={false}
|
|
27
27
|
onBlur={[Function]}
|
|
28
28
|
onClick={[Function]}
|
|
29
29
|
onDragStart={[Function]}
|
|
@@ -128,9 +128,9 @@ exports[`wonder-blocks-clickable example 2 1`] = `
|
|
|
128
128
|
}
|
|
129
129
|
>
|
|
130
130
|
<button
|
|
131
|
+
aria-disabled={false}
|
|
131
132
|
aria-label=""
|
|
132
133
|
className=""
|
|
133
|
-
disabled={false}
|
|
134
134
|
onBlur={[Function]}
|
|
135
135
|
onClick={[Function]}
|
|
136
136
|
onDragStart={[Function]}
|
|
@@ -378,7 +378,7 @@ describe("ClickableBehavior", () => {
|
|
|
378
378
|
expect(button.state("pressed")).toEqual(false);
|
|
379
379
|
|
|
380
380
|
button.simulate("focus");
|
|
381
|
-
expect(button.state("focused")).toEqual(
|
|
381
|
+
expect(button.state("focused")).toEqual(true);
|
|
382
382
|
|
|
383
383
|
const anchor = shallow(
|
|
384
384
|
<ClickableBehavior
|
|
@@ -464,7 +464,7 @@ describe("ClickableBehavior", () => {
|
|
|
464
464
|
|
|
465
465
|
expect(button.state("hovered")).toEqual(false);
|
|
466
466
|
expect(button.state("pressed")).toEqual(false);
|
|
467
|
-
expect(button.state("focused")).toEqual(
|
|
467
|
+
expect(button.state("focused")).toEqual(true);
|
|
468
468
|
});
|
|
469
469
|
|
|
470
470
|
describe("full page load navigation", () => {
|
|
@@ -3,6 +3,8 @@ import * as React from "react";
|
|
|
3
3
|
import {MemoryRouter, Route, Switch} from "react-router-dom";
|
|
4
4
|
import {mount} from "enzyme";
|
|
5
5
|
import "jest-enzyme";
|
|
6
|
+
import {render, screen} from "@testing-library/react";
|
|
7
|
+
import userEvent from "@testing-library/user-event";
|
|
6
8
|
|
|
7
9
|
import {View} from "@khanacademy/wonder-blocks-core";
|
|
8
10
|
import Clickable from "../clickable.js";
|
|
@@ -452,6 +454,47 @@ describe("Clickable", () => {
|
|
|
452
454
|
);
|
|
453
455
|
});
|
|
454
456
|
|
|
457
|
+
test("should add aria-disabled if disabled is set", () => {
|
|
458
|
+
// Arrange
|
|
459
|
+
|
|
460
|
+
// Act
|
|
461
|
+
render(
|
|
462
|
+
<Clickable testId="clickable-button" disabled={true}>
|
|
463
|
+
{(eventState) => <h1>Click Me!</h1>}
|
|
464
|
+
</Clickable>,
|
|
465
|
+
);
|
|
466
|
+
|
|
467
|
+
const button = screen.getByTestId("clickable-button");
|
|
468
|
+
|
|
469
|
+
// Assert
|
|
470
|
+
expect(button).toHaveAttribute("aria-disabled", "true");
|
|
471
|
+
});
|
|
472
|
+
|
|
473
|
+
test("allow keyboard navigation when disabled is set", () => {
|
|
474
|
+
// Arrange
|
|
475
|
+
render(
|
|
476
|
+
<div>
|
|
477
|
+
<button>First focusable button</button>
|
|
478
|
+
<Clickable testId="clickable-button" disabled={true}>
|
|
479
|
+
{(eventState) => <h1>Click Me!</h1>}
|
|
480
|
+
</Clickable>
|
|
481
|
+
</div>,
|
|
482
|
+
);
|
|
483
|
+
|
|
484
|
+
// Act
|
|
485
|
+
// RTL's focuses on `document.body` by default, so we need to focus on
|
|
486
|
+
// the first button
|
|
487
|
+
userEvent.tab();
|
|
488
|
+
|
|
489
|
+
// Then we focus on our Clickable button.
|
|
490
|
+
userEvent.tab();
|
|
491
|
+
|
|
492
|
+
const button = screen.getByTestId("clickable-button");
|
|
493
|
+
|
|
494
|
+
// Assert
|
|
495
|
+
expect(button).toHaveFocus();
|
|
496
|
+
});
|
|
497
|
+
|
|
455
498
|
describe("raw events", () => {
|
|
456
499
|
/**
|
|
457
500
|
* Clickable expect a function as children so we create a simple wrapper to
|
|
@@ -221,8 +221,6 @@ const disabledHandlers = {
|
|
|
221
221
|
onTouchCancel: () => void 0,
|
|
222
222
|
onKeyDown: () => void 0,
|
|
223
223
|
onKeyUp: () => void 0,
|
|
224
|
-
onFocus: () => void 0,
|
|
225
|
-
onBlur: () => void 0,
|
|
226
224
|
// Clickable components should still be tabbable so they can
|
|
227
225
|
// be used as anchors.
|
|
228
226
|
tabIndex: 0,
|
|
@@ -334,9 +332,10 @@ export default class ClickableBehavior extends React.Component<
|
|
|
334
332
|
props: Props,
|
|
335
333
|
state: ClickableState,
|
|
336
334
|
): ?Partial<ClickableState> {
|
|
337
|
-
// If new props are disabled, reset the hovered/
|
|
335
|
+
// If new props are disabled, reset the hovered/pressed states
|
|
338
336
|
if (props.disabled) {
|
|
339
|
-
|
|
337
|
+
// Keep the focused state for enabling keyboard navigation.
|
|
338
|
+
return {...startState, focused: state.focused};
|
|
340
339
|
} else {
|
|
341
340
|
// Cannot return undefined
|
|
342
341
|
return null;
|
|
@@ -610,7 +609,12 @@ export default class ClickableBehavior extends React.Component<
|
|
|
610
609
|
|
|
611
610
|
render(): React.Node {
|
|
612
611
|
const childrenProps: ChildrenProps = this.props.disabled
|
|
613
|
-
?
|
|
612
|
+
? {
|
|
613
|
+
...disabledHandlers,
|
|
614
|
+
// Keep these handlers for keyboard accessibility.
|
|
615
|
+
onFocus: this.handleFocus,
|
|
616
|
+
onBlur: this.handleBlur,
|
|
617
|
+
}
|
|
614
618
|
: {
|
|
615
619
|
onClick: this.handleClick,
|
|
616
620
|
onMouseEnter: this.handleMouseEnter,
|
|
@@ -252,7 +252,7 @@ export default class Clickable extends React.Component<Props> {
|
|
|
252
252
|
<StyledButton
|
|
253
253
|
{...commonProps}
|
|
254
254
|
type="button"
|
|
255
|
-
disabled={this.props.disabled}
|
|
255
|
+
aria-disabled={this.props.disabled}
|
|
256
256
|
>
|
|
257
257
|
{this.props.children(clickableState)}
|
|
258
258
|
</StyledButton>
|