@khanacademy/wonder-blocks-form 4.0.9 → 4.1.0
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 +6 -0
- package/dist/components/checkbox-core.d.ts +3 -0
- package/dist/components/checkbox-core.js.flow +3 -0
- package/dist/components/checkbox.d.ts +3 -2
- package/dist/components/checkbox.js.flow +3 -2
- package/dist/components/choice-internal.d.ts +1 -2
- package/dist/components/choice-internal.js.flow +1 -2
- package/dist/es/index.js +39 -12
- package/dist/index.js +39 -12
- package/dist/util/types.d.ts +2 -1
- package/dist/util/types.js.flow +2 -1
- package/package.json +1 -1
- package/src/__tests__/__snapshots__/custom-snapshot.test.tsx.snap +308 -0
- package/src/__tests__/custom-snapshot.test.tsx +1 -1
- package/src/components/checkbox-core.tsx +54 -15
- package/src/components/checkbox.tsx +4 -2
- package/src/components/choice-internal.tsx +1 -3
- package/src/components/radio-core.tsx +4 -3
- package/src/util/types.ts +4 -1
- package/tsconfig.tsbuildinfo +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,9 @@ import type { ChoiceCoreProps } from "../util/types";
|
|
|
4
4
|
* The internal stateless ☑️ Checkbox
|
|
5
5
|
*/
|
|
6
6
|
export default class CheckboxCore extends React.Component<ChoiceCoreProps> {
|
|
7
|
+
componentDidMount(): void;
|
|
8
|
+
componentDidUpdate(prevProps: Readonly<ChoiceCoreProps>): void;
|
|
9
|
+
inputRef: React.RefObject<HTMLInputElement>;
|
|
7
10
|
handleChange: () => void;
|
|
8
11
|
render(): React.ReactNode;
|
|
9
12
|
}
|
|
@@ -13,6 +13,9 @@ import type { ChoiceCoreProps } from "../util/types";
|
|
|
13
13
|
declare export default class CheckboxCore
|
|
14
14
|
extends React.Component<ChoiceCoreProps>
|
|
15
15
|
{
|
|
16
|
+
componentDidMount(): void;
|
|
17
|
+
componentDidUpdate(prevProps: $ReadOnly<ChoiceCoreProps>): void;
|
|
18
|
+
inputRef: React.RefObject<HTMLInputElement>;
|
|
16
19
|
handleChange: () => void;
|
|
17
20
|
render(): React.Node;
|
|
18
21
|
}
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
2
|
import type { AriaProps, StyleType } from "@khanacademy/wonder-blocks-core";
|
|
3
|
+
import type { Checked } from "../util/types";
|
|
3
4
|
type ChoiceComponentProps = AriaProps & {
|
|
4
5
|
/**
|
|
5
|
-
* Whether this component is checked
|
|
6
|
+
* Whether this component is checked or indeterminate
|
|
6
7
|
*/
|
|
7
|
-
checked:
|
|
8
|
+
checked: Checked;
|
|
8
9
|
/**
|
|
9
10
|
* Whether this component is disabled
|
|
10
11
|
*/
|
|
@@ -6,13 +6,14 @@
|
|
|
6
6
|
*/
|
|
7
7
|
import * as React from "react";
|
|
8
8
|
import type { AriaProps, StyleType } from "@khanacademy/wonder-blocks-core";
|
|
9
|
+
import type { Checked } from "../util/types";
|
|
9
10
|
declare type ChoiceComponentProps = {|
|
|
10
11
|
...AriaProps,
|
|
11
12
|
...{|
|
|
12
13
|
/**
|
|
13
|
-
* Whether this component is checked
|
|
14
|
+
* Whether this component is checked or indeterminate
|
|
14
15
|
*/
|
|
15
|
-
checked:
|
|
16
|
+
checked: Checked,
|
|
16
17
|
|
|
17
18
|
/**
|
|
18
19
|
* Whether this component is disabled
|
|
@@ -4,7 +4,7 @@ import CheckboxCore from "./checkbox-core";
|
|
|
4
4
|
import RadioCore from "./radio-core";
|
|
5
5
|
type Props = AriaProps & {
|
|
6
6
|
/** Whether this choice is checked. */
|
|
7
|
-
checked: boolean;
|
|
7
|
+
checked: boolean | null | undefined;
|
|
8
8
|
/** Whether this choice option is disabled. */
|
|
9
9
|
disabled: boolean;
|
|
10
10
|
/** Whether this choice is in error mode. */
|
|
@@ -40,7 +40,6 @@ type Props = AriaProps & {
|
|
|
40
40
|
variant: "radio" | "checkbox";
|
|
41
41
|
};
|
|
42
42
|
type DefaultProps = {
|
|
43
|
-
checked: Props["checked"];
|
|
44
43
|
disabled: Props["disabled"];
|
|
45
44
|
error: Props["error"];
|
|
46
45
|
};
|
|
@@ -14,7 +14,7 @@ declare type Props = {|
|
|
|
14
14
|
/**
|
|
15
15
|
* Whether this choice is checked.
|
|
16
16
|
*/
|
|
17
|
-
checked: boolean,
|
|
17
|
+
checked: boolean | null | void,
|
|
18
18
|
|
|
19
19
|
/**
|
|
20
20
|
* Whether this choice option is disabled.
|
|
@@ -74,7 +74,6 @@ declare type Props = {|
|
|
|
74
74
|
|},
|
|
75
75
|
|};
|
|
76
76
|
declare type DefaultProps = {|
|
|
77
|
-
checked: $PropertyType<Props, "checked">,
|
|
78
77
|
disabled: $PropertyType<Props, "disabled">,
|
|
79
78
|
error: $PropertyType<Props, "error">,
|
|
80
79
|
|};
|
package/dist/es/index.js
CHANGED
|
@@ -36,6 +36,16 @@ function _objectWithoutPropertiesLoose(source, excluded) {
|
|
|
36
36
|
}
|
|
37
37
|
|
|
38
38
|
const _excluded$4 = ["checked", "disabled", "error", "groupName", "id", "testId"];
|
|
39
|
+
function mapCheckedToAriaChecked(value) {
|
|
40
|
+
switch (value) {
|
|
41
|
+
case true:
|
|
42
|
+
return "true";
|
|
43
|
+
case false:
|
|
44
|
+
return "false";
|
|
45
|
+
default:
|
|
46
|
+
return "mixed";
|
|
47
|
+
}
|
|
48
|
+
}
|
|
39
49
|
const {
|
|
40
50
|
blue: blue$1,
|
|
41
51
|
red: red$1,
|
|
@@ -46,16 +56,30 @@ const {
|
|
|
46
56
|
offBlack50: offBlack50$1
|
|
47
57
|
} = Color;
|
|
48
58
|
const StyledInput$2 = addStyle("input");
|
|
49
|
-
const
|
|
59
|
+
const checkPath = {
|
|
50
60
|
small: "M11.263 4.324a1 1 0 1 1 1.474 1.352l-5.5 6a1 1 0 0 1-1.505-.036l-2.5-3a1 1 0 1 1 1.536-1.28L6.536 9.48l4.727-5.157z"
|
|
51
61
|
};
|
|
62
|
+
const indeterminatePath = {
|
|
63
|
+
small: "M3 8C3 7.44772 3.44772 7 4 7H12C12.5523 7 13 7.44772 13 8C13 8.55228 12.5523 9 12 9H4C3.44772 9 3 8.55228 3 8Z"
|
|
64
|
+
};
|
|
52
65
|
class CheckboxCore extends React.Component {
|
|
53
66
|
constructor(...args) {
|
|
54
67
|
super(...args);
|
|
68
|
+
this.inputRef = React.createRef();
|
|
55
69
|
this.handleChange = () => {
|
|
56
70
|
return;
|
|
57
71
|
};
|
|
58
72
|
}
|
|
73
|
+
componentDidMount() {
|
|
74
|
+
if (this.props.checked == null && this.inputRef.current != null) {
|
|
75
|
+
this.inputRef.current.indeterminate = true;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
componentDidUpdate(prevProps) {
|
|
79
|
+
if (this.inputRef.current != null) {
|
|
80
|
+
this.inputRef.current.indeterminate = this.props.checked == null;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
59
83
|
render() {
|
|
60
84
|
const _this$props = this.props,
|
|
61
85
|
{
|
|
@@ -72,21 +96,25 @@ class CheckboxCore extends React.Component {
|
|
|
72
96
|
const props = {
|
|
73
97
|
"data-test-id": testId
|
|
74
98
|
};
|
|
99
|
+
const checkboxIcon = React.createElement(Icon, {
|
|
100
|
+
color: disabled ? offBlack32$1 : white$1,
|
|
101
|
+
icon: checked ? checkPath : indeterminatePath,
|
|
102
|
+
size: "small",
|
|
103
|
+
style: sharedStyles$1.checkboxIcon
|
|
104
|
+
});
|
|
105
|
+
const ariaChecked = mapCheckedToAriaChecked(checked);
|
|
75
106
|
return React.createElement(React.Fragment, null, React.createElement(StyledInput$2, _extends({}, sharedProps, {
|
|
107
|
+
ref: this.inputRef,
|
|
76
108
|
type: "checkbox",
|
|
109
|
+
"aria-checked": ariaChecked,
|
|
77
110
|
"aria-invalid": error,
|
|
78
|
-
checked: checked,
|
|
111
|
+
checked: checked != null ? checked : undefined,
|
|
79
112
|
disabled: disabled,
|
|
80
113
|
id: id,
|
|
81
114
|
name: groupName,
|
|
82
115
|
onChange: this.handleChange,
|
|
83
116
|
style: defaultStyle
|
|
84
|
-
}, props)), checked
|
|
85
|
-
color: disabled ? offBlack32$1 : white$1,
|
|
86
|
-
icon: checkboxCheck,
|
|
87
|
-
size: "small",
|
|
88
|
-
style: sharedStyles$1.checkIcon
|
|
89
|
-
}));
|
|
117
|
+
}, props)), checked || checked == null ? checkboxIcon : React.createElement(React.Fragment, null));
|
|
90
118
|
}
|
|
91
119
|
}
|
|
92
120
|
const size$1 = 16;
|
|
@@ -114,7 +142,7 @@ const sharedStyles$1 = StyleSheet.create({
|
|
|
114
142
|
borderColor: offBlack16$1,
|
|
115
143
|
borderWidth: 1
|
|
116
144
|
},
|
|
117
|
-
|
|
145
|
+
checkboxIcon: {
|
|
118
146
|
position: "absolute",
|
|
119
147
|
pointerEvents: "none"
|
|
120
148
|
}
|
|
@@ -143,7 +171,7 @@ const _generateStyles$1 = (checked, error) => {
|
|
|
143
171
|
}
|
|
144
172
|
const palette = error ? colors$1.error : colors$1.default;
|
|
145
173
|
let newStyles = {};
|
|
146
|
-
if (checked) {
|
|
174
|
+
if (checked || checked == null) {
|
|
147
175
|
newStyles = {
|
|
148
176
|
default: {
|
|
149
177
|
backgroundColor: palette.base,
|
|
@@ -224,7 +252,7 @@ class RadioCore extends React.Component {
|
|
|
224
252
|
return React.createElement(React.Fragment, null, React.createElement(StyledInput$1, _extends({}, sharedProps, {
|
|
225
253
|
type: "radio",
|
|
226
254
|
"aria-invalid": error,
|
|
227
|
-
checked: checked,
|
|
255
|
+
checked: checked != null ? checked : undefined,
|
|
228
256
|
disabled: disabled,
|
|
229
257
|
id: id,
|
|
230
258
|
name: groupName,
|
|
@@ -416,7 +444,6 @@ class ChoiceInternal extends React.Component {
|
|
|
416
444
|
}
|
|
417
445
|
}
|
|
418
446
|
ChoiceInternal.defaultProps = {
|
|
419
|
-
checked: false,
|
|
420
447
|
disabled: false,
|
|
421
448
|
error: false
|
|
422
449
|
};
|
package/dist/index.js
CHANGED
|
@@ -65,6 +65,16 @@ function _objectWithoutPropertiesLoose(source, excluded) {
|
|
|
65
65
|
}
|
|
66
66
|
|
|
67
67
|
const _excluded$4 = ["checked", "disabled", "error", "groupName", "id", "testId"];
|
|
68
|
+
function mapCheckedToAriaChecked(value) {
|
|
69
|
+
switch (value) {
|
|
70
|
+
case true:
|
|
71
|
+
return "true";
|
|
72
|
+
case false:
|
|
73
|
+
return "false";
|
|
74
|
+
default:
|
|
75
|
+
return "mixed";
|
|
76
|
+
}
|
|
77
|
+
}
|
|
68
78
|
const {
|
|
69
79
|
blue: blue$1,
|
|
70
80
|
red: red$1,
|
|
@@ -75,16 +85,30 @@ const {
|
|
|
75
85
|
offBlack50: offBlack50$1
|
|
76
86
|
} = Color__default["default"];
|
|
77
87
|
const StyledInput$2 = wonderBlocksCore.addStyle("input");
|
|
78
|
-
const
|
|
88
|
+
const checkPath = {
|
|
79
89
|
small: "M11.263 4.324a1 1 0 1 1 1.474 1.352l-5.5 6a1 1 0 0 1-1.505-.036l-2.5-3a1 1 0 1 1 1.536-1.28L6.536 9.48l4.727-5.157z"
|
|
80
90
|
};
|
|
91
|
+
const indeterminatePath = {
|
|
92
|
+
small: "M3 8C3 7.44772 3.44772 7 4 7H12C12.5523 7 13 7.44772 13 8C13 8.55228 12.5523 9 12 9H4C3.44772 9 3 8.55228 3 8Z"
|
|
93
|
+
};
|
|
81
94
|
class CheckboxCore extends React__namespace.Component {
|
|
82
95
|
constructor(...args) {
|
|
83
96
|
super(...args);
|
|
97
|
+
this.inputRef = React__namespace.createRef();
|
|
84
98
|
this.handleChange = () => {
|
|
85
99
|
return;
|
|
86
100
|
};
|
|
87
101
|
}
|
|
102
|
+
componentDidMount() {
|
|
103
|
+
if (this.props.checked == null && this.inputRef.current != null) {
|
|
104
|
+
this.inputRef.current.indeterminate = true;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
componentDidUpdate(prevProps) {
|
|
108
|
+
if (this.inputRef.current != null) {
|
|
109
|
+
this.inputRef.current.indeterminate = this.props.checked == null;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
88
112
|
render() {
|
|
89
113
|
const _this$props = this.props,
|
|
90
114
|
{
|
|
@@ -101,21 +125,25 @@ class CheckboxCore extends React__namespace.Component {
|
|
|
101
125
|
const props = {
|
|
102
126
|
"data-test-id": testId
|
|
103
127
|
};
|
|
128
|
+
const checkboxIcon = React__namespace.createElement(Icon__default["default"], {
|
|
129
|
+
color: disabled ? offBlack32$1 : white$1,
|
|
130
|
+
icon: checked ? checkPath : indeterminatePath,
|
|
131
|
+
size: "small",
|
|
132
|
+
style: sharedStyles$1.checkboxIcon
|
|
133
|
+
});
|
|
134
|
+
const ariaChecked = mapCheckedToAriaChecked(checked);
|
|
104
135
|
return React__namespace.createElement(React__namespace.Fragment, null, React__namespace.createElement(StyledInput$2, _extends({}, sharedProps, {
|
|
136
|
+
ref: this.inputRef,
|
|
105
137
|
type: "checkbox",
|
|
138
|
+
"aria-checked": ariaChecked,
|
|
106
139
|
"aria-invalid": error,
|
|
107
|
-
checked: checked,
|
|
140
|
+
checked: checked != null ? checked : undefined,
|
|
108
141
|
disabled: disabled,
|
|
109
142
|
id: id,
|
|
110
143
|
name: groupName,
|
|
111
144
|
onChange: this.handleChange,
|
|
112
145
|
style: defaultStyle
|
|
113
|
-
}, props)), checked
|
|
114
|
-
color: disabled ? offBlack32$1 : white$1,
|
|
115
|
-
icon: checkboxCheck,
|
|
116
|
-
size: "small",
|
|
117
|
-
style: sharedStyles$1.checkIcon
|
|
118
|
-
}));
|
|
146
|
+
}, props)), checked || checked == null ? checkboxIcon : React__namespace.createElement(React__namespace.Fragment, null));
|
|
119
147
|
}
|
|
120
148
|
}
|
|
121
149
|
const size$1 = 16;
|
|
@@ -143,7 +171,7 @@ const sharedStyles$1 = aphrodite.StyleSheet.create({
|
|
|
143
171
|
borderColor: offBlack16$1,
|
|
144
172
|
borderWidth: 1
|
|
145
173
|
},
|
|
146
|
-
|
|
174
|
+
checkboxIcon: {
|
|
147
175
|
position: "absolute",
|
|
148
176
|
pointerEvents: "none"
|
|
149
177
|
}
|
|
@@ -172,7 +200,7 @@ const _generateStyles$1 = (checked, error) => {
|
|
|
172
200
|
}
|
|
173
201
|
const palette = error ? colors$1.error : colors$1.default;
|
|
174
202
|
let newStyles = {};
|
|
175
|
-
if (checked) {
|
|
203
|
+
if (checked || checked == null) {
|
|
176
204
|
newStyles = {
|
|
177
205
|
default: {
|
|
178
206
|
backgroundColor: palette.base,
|
|
@@ -253,7 +281,7 @@ class RadioCore extends React__namespace.Component {
|
|
|
253
281
|
return React__namespace.createElement(React__namespace.Fragment, null, React__namespace.createElement(StyledInput$1, _extends({}, sharedProps, {
|
|
254
282
|
type: "radio",
|
|
255
283
|
"aria-invalid": error,
|
|
256
|
-
checked: checked,
|
|
284
|
+
checked: checked != null ? checked : undefined,
|
|
257
285
|
disabled: disabled,
|
|
258
286
|
id: id,
|
|
259
287
|
name: groupName,
|
|
@@ -445,7 +473,6 @@ class ChoiceInternal extends React__namespace.Component {
|
|
|
445
473
|
}
|
|
446
474
|
}
|
|
447
475
|
ChoiceInternal.defaultProps = {
|
|
448
|
-
checked: false,
|
|
449
476
|
disabled: false,
|
|
450
477
|
error: false
|
|
451
478
|
};
|
package/dist/util/types.d.ts
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import type { AriaProps, StyleType } from "@khanacademy/wonder-blocks-core";
|
|
2
2
|
import Choice from "../components/choice";
|
|
3
|
+
export type Checked = boolean | null | undefined;
|
|
3
4
|
export type ChoiceCoreProps = AriaProps & {
|
|
4
5
|
/** Whether this component is checked */
|
|
5
|
-
checked:
|
|
6
|
+
checked: Checked;
|
|
6
7
|
/** Whether this component is disabled */
|
|
7
8
|
disabled: boolean;
|
|
8
9
|
/** Whether this component should show an error state */
|
package/dist/util/types.js.flow
CHANGED
|
@@ -6,13 +6,14 @@
|
|
|
6
6
|
*/
|
|
7
7
|
import type { AriaProps, StyleType } from "@khanacademy/wonder-blocks-core";
|
|
8
8
|
import Choice from "../components/choice";
|
|
9
|
+
export type Checked = boolean | null | void;
|
|
9
10
|
export type ChoiceCoreProps = {|
|
|
10
11
|
...AriaProps,
|
|
11
12
|
...{|
|
|
12
13
|
/**
|
|
13
14
|
* Whether this component is checked
|
|
14
15
|
*/
|
|
15
|
-
checked:
|
|
16
|
+
checked: Checked,
|
|
16
17
|
|
|
17
18
|
/**
|
|
18
19
|
* Whether this component is disabled
|