@khanacademy/perseus 1.1.1 → 1.2.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 +20 -0
- package/dist/es/index.css +2 -2
- package/dist/es/index.js +14997 -15079
- package/dist/es/index.js.map +1 -1
- package/dist/index.css +2 -2
- package/dist/index.js +15033 -15113
- package/dist/index.js.map +1 -1
- package/dist/strings.js +1 -0
- package/package.json +7 -7
- package/src/__stories__/hints-renderer.stories.jsx +52 -0
- package/src/__tests__/__snapshots__/renderer_test.jsx.snap +21 -3
- package/src/components/highlighting/ui/highlight-tooltip.jsx +29 -23
- package/src/components/highlighting/ui/selection-tracker.jsx +17 -28
- package/src/hints-renderer.jsx +13 -4
- package/src/mixins/__tests__/widget-prop-blacklist_test.js +23 -0
- package/src/mixins/widget-prop-blacklist.js +15 -1
- package/src/multi-items/__tests__/__snapshots__/multi-renderer_test.js.snap +30 -10
- package/src/styles/articles.less +0 -2
- package/src/styles/perseus-renderer.less +1 -1
- package/src/styles/widgets/passage.less +1 -0
- package/src/types.js +1 -1
- package/src/widgets/__tests__/__snapshots__/dropdown_test.jsx.snap +16 -2
- package/src/widgets/__tests__/__snapshots__/graded-group-set-jipt_test.jsx.snap +3 -3
- package/src/widgets/__tests__/__snapshots__/graded-group-set_test.jsx.snap +7 -1
- package/src/widgets/__tests__/__snapshots__/graded-group_test.jsx.snap +2 -2
- package/src/widgets/__tests__/__snapshots__/group_test.jsx.snap +30 -10
- package/src/widgets/__tests__/__snapshots__/passage-ref_test.jsx.snap +3 -3
- package/src/widgets/__tests__/__snapshots__/passage_test.jsx.snap +6 -6
- package/src/widgets/__tests__/__snapshots__/radio_test.jsx.snap +300 -218
- package/src/widgets/__tests__/radio/base-radio_test.jsx +90 -6
- package/src/widgets/__tests__/radio/choice-icon_test.jsx +74 -0
- package/src/widgets/__tests__/radio/choice_test.jsx +39 -30
- package/src/widgets/__tests__/radio_test.jsx +228 -22
- package/src/widgets/graded-group-set.jsx +8 -1
- package/src/widgets/graded-group.jsx +2 -1
- package/src/widgets/passage-ref.jsx +21 -5
- package/src/widgets/passage.jsx +3 -1
- package/src/widgets/radio/__stories__/base-radio.stories.jsx +7 -3
- package/src/widgets/radio/base-radio.jsx +3 -1
- package/src/widgets/radio/choice-icon/cross-out-line.jsx +3 -2
- package/src/widgets/radio/choice-icon/library-choice-icon.jsx +17 -6
- package/src/widgets/radio/choice.jsx +2 -1
- package/src/components/new-tooltip/README.md +0 -3
- package/src/components/new-tooltip/__stories__/new-tooltip.stories.jsx +0 -665
- package/src/components/new-tooltip/__tests__/style-constants_test.js +0 -8
- package/src/components/new-tooltip/new-tooltip.jsx +0 -155
- package/src/components/new-tooltip/style-constants.js +0 -13
- package/src/components/new-tooltip/types.js +0 -183
package/dist/strings.js
CHANGED
|
@@ -52,6 +52,7 @@ module.exports = [
|
|
|
52
52
|
i18n._("Correct (but you crossed it out)", {}),
|
|
53
53
|
i18n._("Correct (selected)", {}),
|
|
54
54
|
i18n._("Correct!", {}),
|
|
55
|
+
i18n._("Current", {}),
|
|
55
56
|
// I18N: As in the command, "Dilate the polygon"
|
|
56
57
|
i18n._("Dilate", {}),
|
|
57
58
|
i18n._("dilation", {}),
|
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"description": "Core Perseus API (includes renderers and widgets)",
|
|
4
4
|
"author": "Khan Academy",
|
|
5
5
|
"license": "MIT",
|
|
6
|
-
"version": "1.
|
|
6
|
+
"version": "1.2.0",
|
|
7
7
|
"publishConfig": {
|
|
8
8
|
"access": "public"
|
|
9
9
|
},
|
|
@@ -35,16 +35,16 @@
|
|
|
35
35
|
"@khanacademy/wonder-blocks-color": "^1.1.20",
|
|
36
36
|
"@khanacademy/wonder-blocks-core": "^4.3.0",
|
|
37
37
|
"@khanacademy/wonder-blocks-data": "^7.0.0",
|
|
38
|
-
"@khanacademy/wonder-blocks-dropdown": "^2.
|
|
38
|
+
"@khanacademy/wonder-blocks-dropdown": "^2.10.1",
|
|
39
39
|
"@khanacademy/wonder-blocks-form": "^2.4.5",
|
|
40
40
|
"@khanacademy/wonder-blocks-i18n": "^1.2.3",
|
|
41
41
|
"@khanacademy/wonder-blocks-layout": "^1.4.9",
|
|
42
42
|
"@khanacademy/wonder-blocks-link": "^3.8.5",
|
|
43
43
|
"@khanacademy/wonder-blocks-modal": "^2.3.1",
|
|
44
|
-
"@khanacademy/wonder-blocks-popover": "^1.1.
|
|
44
|
+
"@khanacademy/wonder-blocks-popover": "^1.1.24",
|
|
45
45
|
"@khanacademy/wonder-blocks-progress-spinner": "^1.1.31",
|
|
46
46
|
"@khanacademy/wonder-blocks-spacing": "^3.0.5",
|
|
47
|
-
"@khanacademy/wonder-blocks-tooltip": "^1.
|
|
47
|
+
"@khanacademy/wonder-blocks-tooltip": "^1.4.0",
|
|
48
48
|
"@khanacademy/wonder-blocks-typography": "^1.1.31",
|
|
49
49
|
"@khanacademy/wonder-stuff-core": "^0.1.2",
|
|
50
50
|
"aphrodite": "^1.2.5",
|
|
@@ -68,16 +68,16 @@
|
|
|
68
68
|
"@khanacademy/wonder-blocks-color": "^1.1.20",
|
|
69
69
|
"@khanacademy/wonder-blocks-core": "^4.3.0",
|
|
70
70
|
"@khanacademy/wonder-blocks-data": "^7.0.0",
|
|
71
|
-
"@khanacademy/wonder-blocks-dropdown": "^2.
|
|
71
|
+
"@khanacademy/wonder-blocks-dropdown": "^2.10.1",
|
|
72
72
|
"@khanacademy/wonder-blocks-form": "^2.4.5",
|
|
73
73
|
"@khanacademy/wonder-blocks-i18n": "^1.2.3",
|
|
74
74
|
"@khanacademy/wonder-blocks-layout": "^1.4.9",
|
|
75
75
|
"@khanacademy/wonder-blocks-link": "^3.8.5",
|
|
76
76
|
"@khanacademy/wonder-blocks-modal": "^2.3.1",
|
|
77
|
-
"@khanacademy/wonder-blocks-popover": "^1.1.
|
|
77
|
+
"@khanacademy/wonder-blocks-popover": "^1.1.24",
|
|
78
78
|
"@khanacademy/wonder-blocks-progress-spinner": "^1.1.31",
|
|
79
79
|
"@khanacademy/wonder-blocks-spacing": "^3.0.5",
|
|
80
|
-
"@khanacademy/wonder-blocks-tooltip": "^1.
|
|
80
|
+
"@khanacademy/wonder-blocks-tooltip": "^1.4.0",
|
|
81
81
|
"@khanacademy/wonder-blocks-typography": "^1.1.31",
|
|
82
82
|
"@khanacademy/wonder-stuff-core": "^0.1.2",
|
|
83
83
|
"aphrodite": "^1.2.5",
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
// @flow
|
|
2
|
+
|
|
3
|
+
import React from "react";
|
|
4
|
+
|
|
5
|
+
import HintsRenderer from "../hints-renderer.jsx";
|
|
6
|
+
|
|
7
|
+
type StoryArgs = {|
|
|
8
|
+
hints: $ReadOnlyArray<$FlowFixMe>,
|
|
9
|
+
hintsVisible: number,
|
|
10
|
+
|};
|
|
11
|
+
|
|
12
|
+
type Story = {|
|
|
13
|
+
title: string,
|
|
14
|
+
argTypes: $FlowFixMe,
|
|
15
|
+
|};
|
|
16
|
+
|
|
17
|
+
export default ({
|
|
18
|
+
title: "Perseus/Renderers/Hints Renderer",
|
|
19
|
+
argTypes: {
|
|
20
|
+
hints: {
|
|
21
|
+
control: "object",
|
|
22
|
+
defaultValue: [
|
|
23
|
+
{
|
|
24
|
+
content: "this is hint 1",
|
|
25
|
+
images: {},
|
|
26
|
+
replace: false,
|
|
27
|
+
widgets: {},
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
content: "this is hint 2",
|
|
31
|
+
images: {},
|
|
32
|
+
replace: false,
|
|
33
|
+
widgets: {},
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
content: "this is hint 3",
|
|
37
|
+
images: {},
|
|
38
|
+
replace: false,
|
|
39
|
+
widgets: {},
|
|
40
|
+
},
|
|
41
|
+
],
|
|
42
|
+
},
|
|
43
|
+
hintsVisible: {
|
|
44
|
+
control: {type: "number", min: 0},
|
|
45
|
+
defaultValue: 3,
|
|
46
|
+
},
|
|
47
|
+
},
|
|
48
|
+
}: Story);
|
|
49
|
+
|
|
50
|
+
export const Interactive = (args: StoryArgs): $FlowFixMe => {
|
|
51
|
+
return <HintsRenderer {...args} />;
|
|
52
|
+
};
|
|
@@ -385,11 +385,17 @@ exports[`renderer snapshots correct answer: correct answer 1`] = `
|
|
|
385
385
|
<div
|
|
386
386
|
class="default_xu2jcg-o_O-menuWrapper_wvrnr4"
|
|
387
387
|
>
|
|
388
|
+
<span
|
|
389
|
+
aria-atomic="true"
|
|
390
|
+
aria-live="polite"
|
|
391
|
+
aria-relevant="additions text"
|
|
392
|
+
class="srOnly_19bpjuy"
|
|
393
|
+
data-test-id="dropdown-live-region"
|
|
394
|
+
/>
|
|
388
395
|
<button
|
|
389
396
|
aria-expanded="false"
|
|
390
397
|
aria-haspopup="listbox"
|
|
391
398
|
class="button_vr44p2-o_O-shared_u51dsh-o_O-default_kjzwx1-o_O-focus_1qpi544"
|
|
392
|
-
tabindex="0"
|
|
393
399
|
type="button"
|
|
394
400
|
>
|
|
395
401
|
<span
|
|
@@ -456,11 +462,17 @@ exports[`renderer snapshots incorrect answer: incorrect answer 1`] = `
|
|
|
456
462
|
<div
|
|
457
463
|
class="default_xu2jcg-o_O-menuWrapper_wvrnr4"
|
|
458
464
|
>
|
|
465
|
+
<span
|
|
466
|
+
aria-atomic="true"
|
|
467
|
+
aria-live="polite"
|
|
468
|
+
aria-relevant="additions text"
|
|
469
|
+
class="srOnly_19bpjuy"
|
|
470
|
+
data-test-id="dropdown-live-region"
|
|
471
|
+
/>
|
|
459
472
|
<button
|
|
460
473
|
aria-expanded="false"
|
|
461
474
|
aria-haspopup="listbox"
|
|
462
475
|
class="button_vr44p2-o_O-shared_u51dsh-o_O-default_kjzwx1-o_O-focus_1qpi544"
|
|
463
|
-
tabindex="0"
|
|
464
476
|
type="button"
|
|
465
477
|
>
|
|
466
478
|
<span
|
|
@@ -527,11 +539,17 @@ exports[`renderer snapshots initial render: initial render 1`] = `
|
|
|
527
539
|
<div
|
|
528
540
|
class="default_xu2jcg-o_O-menuWrapper_wvrnr4"
|
|
529
541
|
>
|
|
542
|
+
<span
|
|
543
|
+
aria-atomic="true"
|
|
544
|
+
aria-live="polite"
|
|
545
|
+
aria-relevant="additions text"
|
|
546
|
+
class="srOnly_19bpjuy"
|
|
547
|
+
data-test-id="dropdown-live-region"
|
|
548
|
+
/>
|
|
530
549
|
<button
|
|
531
550
|
aria-expanded="false"
|
|
532
551
|
aria-haspopup="listbox"
|
|
533
552
|
class="button_vr44p2-o_O-shared_u51dsh-o_O-default_kjzwx1"
|
|
534
|
-
tabindex="0"
|
|
535
553
|
type="button"
|
|
536
554
|
>
|
|
537
555
|
<span
|
|
@@ -13,12 +13,12 @@
|
|
|
13
13
|
* still have to notify the tooltip to remeasure itself when the highlight
|
|
14
14
|
* focus _changes_.
|
|
15
15
|
*/
|
|
16
|
+
import Spacing from "@khanacademy/wonder-blocks-spacing";
|
|
17
|
+
import Tooltip from "@khanacademy/wonder-blocks-tooltip";
|
|
16
18
|
import {StyleSheet, css} from "aphrodite";
|
|
17
19
|
import * as React from "react";
|
|
18
20
|
|
|
19
21
|
import {Log} from "../../../logging/log.js";
|
|
20
|
-
import {colors} from "../../../styles/global-styles.js";
|
|
21
|
-
import NewTooltip from "../../new-tooltip/new-tooltip.jsx";
|
|
22
22
|
|
|
23
23
|
import {getRelativeRect} from "./util.js";
|
|
24
24
|
|
|
@@ -36,8 +36,6 @@ type HighlightTooltipProps = {|
|
|
|
36
36
|
|};
|
|
37
37
|
|
|
38
38
|
class HighlightTooltip extends React.PureComponent<HighlightTooltipProps> {
|
|
39
|
-
_tooltip: ?React.ElementRef<typeof NewTooltip>;
|
|
40
|
-
|
|
41
39
|
_getFocusRect(): ?Rect {
|
|
42
40
|
const {focusNode, focusOffset, offsetParent} = this.props;
|
|
43
41
|
|
|
@@ -94,31 +92,36 @@ class HighlightTooltip extends React.PureComponent<HighlightTooltipProps> {
|
|
|
94
92
|
return null;
|
|
95
93
|
}
|
|
96
94
|
|
|
97
|
-
|
|
98
|
-
|
|
95
|
+
// using div instead of TooltipContent because
|
|
96
|
+
// TooltipContent wouldn't let me overwrite
|
|
97
|
+
// user-select and onClick
|
|
98
|
+
const content: $FlowFixMe = (
|
|
99
|
+
<div
|
|
100
|
+
className={css(styles.tooltipLabel)}
|
|
101
|
+
onClick={this.props.onClick}
|
|
102
|
+
>
|
|
103
|
+
{this.props.label}
|
|
104
|
+
</div>
|
|
99
105
|
);
|
|
100
106
|
|
|
107
|
+
const style = {
|
|
108
|
+
position: "absolute",
|
|
109
|
+
left: focusRect.left,
|
|
110
|
+
// offset the spacing WB provides around tooltips
|
|
111
|
+
top: `calc(${Math.round(focusRect.top)}px + 0.95em)`,
|
|
112
|
+
height: 0,
|
|
113
|
+
};
|
|
114
|
+
|
|
101
115
|
return (
|
|
102
|
-
<
|
|
103
|
-
|
|
104
|
-
color={colors.kaBlue}
|
|
105
|
-
inverted={true}
|
|
106
|
-
onClick={this.props.onClick}
|
|
116
|
+
<div
|
|
117
|
+
style={style}
|
|
107
118
|
onMouseEnter={this.props.onMouseEnter}
|
|
108
119
|
onMouseLeave={this.props.onMouseLeave}
|
|
109
|
-
toggleOnHover={false}
|
|
110
|
-
showOnMount={true}
|
|
111
|
-
ref={(e) => (this._tooltip = e)}
|
|
112
120
|
>
|
|
113
|
-
<
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
top: focusRect.top,
|
|
118
|
-
height: focusRect.height,
|
|
119
|
-
}}
|
|
120
|
-
/>
|
|
121
|
-
</NewTooltip>
|
|
121
|
+
<Tooltip content={content} opened={true}>
|
|
122
|
+
<div />
|
|
123
|
+
</Tooltip>
|
|
124
|
+
</div>
|
|
122
125
|
);
|
|
123
126
|
}
|
|
124
127
|
}
|
|
@@ -131,6 +134,9 @@ const styles = StyleSheet.create({
|
|
|
131
134
|
// we lose our reference to the _actual_ text they want to highlight,
|
|
132
135
|
// and the "Add highlight" action fails.
|
|
133
136
|
userSelect: "none",
|
|
137
|
+
fontFamily: `"Lato", sans-serif`,
|
|
138
|
+
padding: `10px ${Spacing.medium_16}px`,
|
|
139
|
+
cursor: "pointer",
|
|
134
140
|
},
|
|
135
141
|
});
|
|
136
142
|
|
|
@@ -24,7 +24,7 @@ export type TrackedSelection = {|
|
|
|
24
24
|
proposedHighlight: DOMHighlight,
|
|
25
25
|
|};
|
|
26
26
|
|
|
27
|
-
type SelectionTrackerProps = {
|
|
27
|
+
type SelectionTrackerProps = {|
|
|
28
28
|
// A function that builds a DOMHighlight from the given DOMRange, if
|
|
29
29
|
// possible. If it would not currently be valid to add a highlight over the
|
|
30
30
|
// given DOMRange, returns null.
|
|
@@ -38,17 +38,15 @@ type SelectionTrackerProps = {
|
|
|
38
38
|
) => React.Element<any>,
|
|
39
39
|
// If false, will not track selections.
|
|
40
40
|
enabled: boolean,
|
|
41
|
-
|
|
42
|
-
};
|
|
41
|
+
|};
|
|
43
42
|
|
|
44
|
-
type SelectionTrackerState = {
|
|
43
|
+
type SelectionTrackerState = {|
|
|
45
44
|
// The current state of the mouse button. We distinguish between down,
|
|
46
45
|
// down and the selection has changed since going down, and up.
|
|
47
46
|
mouseState: "down" | "down-and-selecting" | "up",
|
|
48
47
|
// The current TrackedSelection, if any.
|
|
49
48
|
trackedSelection: ?TrackedSelection,
|
|
50
|
-
|
|
51
|
-
};
|
|
49
|
+
|};
|
|
52
50
|
|
|
53
51
|
class SelectionTracker extends React.PureComponent<
|
|
54
52
|
SelectionTrackerProps,
|
|
@@ -63,15 +61,15 @@ class SelectionTracker extends React.PureComponent<
|
|
|
63
61
|
this._updateListeners(false, this.props.enabled);
|
|
64
62
|
}
|
|
65
63
|
|
|
66
|
-
|
|
67
|
-
if (this.props.buildHighlight !==
|
|
64
|
+
componentDidUpdate(prevProps: SelectionTrackerProps) {
|
|
65
|
+
if (this.props.buildHighlight !== prevProps.buildHighlight) {
|
|
68
66
|
// The highlight-building function changed, so the
|
|
69
67
|
// proposedHighlight we built with it might be different, or no
|
|
70
68
|
// longer be valid. Update accordingly.
|
|
71
|
-
this._updateTrackedSelection(
|
|
69
|
+
this._updateTrackedSelection();
|
|
72
70
|
}
|
|
73
71
|
|
|
74
|
-
this._updateListeners(
|
|
72
|
+
this._updateListeners(prevProps.enabled, this.props.enabled);
|
|
75
73
|
}
|
|
76
74
|
|
|
77
75
|
componentWillUnmount() {
|
|
@@ -133,37 +131,28 @@ class SelectionTracker extends React.PureComponent<
|
|
|
133
131
|
}
|
|
134
132
|
|
|
135
133
|
/**
|
|
136
|
-
* Compute the
|
|
134
|
+
* Compute and update the TrackedSelection to reflect the document state.
|
|
137
135
|
*/
|
|
138
|
-
|
|
139
|
-
buildHighlight: (domRange: DOMRange) => ?DOMHighlight,
|
|
140
|
-
): ?TrackedSelection {
|
|
136
|
+
_updateTrackedSelection(): void {
|
|
141
137
|
const focusAndRange = this._computeFocusAndRange();
|
|
142
138
|
if (!focusAndRange) {
|
|
143
|
-
|
|
139
|
+
this.setState({trackedSelection: null});
|
|
140
|
+
return;
|
|
144
141
|
}
|
|
145
142
|
|
|
146
143
|
const {focusNode, focusOffset, range} = focusAndRange;
|
|
147
|
-
const proposedHighlight = buildHighlight(range);
|
|
144
|
+
const proposedHighlight = this.props.buildHighlight(range);
|
|
148
145
|
if (!proposedHighlight) {
|
|
149
|
-
|
|
146
|
+
this.setState({trackedSelection: null});
|
|
147
|
+
return;
|
|
150
148
|
}
|
|
151
149
|
|
|
152
|
-
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
/**
|
|
156
|
-
* Update the TrackedSelection to reflect the document state.
|
|
157
|
-
*/
|
|
158
|
-
_updateTrackedSelection(
|
|
159
|
-
buildHighlight: (domRange: DOMRange) => ?DOMHighlight,
|
|
160
|
-
) {
|
|
161
|
-
const trackedSelection = this._computeTrackedSelection(buildHighlight);
|
|
150
|
+
const trackedSelection = {focusNode, focusOffset, proposedHighlight};
|
|
162
151
|
this.setState({trackedSelection});
|
|
163
152
|
}
|
|
164
153
|
|
|
165
154
|
_handleSelectionChange: () => void = () => {
|
|
166
|
-
this._updateTrackedSelection(
|
|
155
|
+
this._updateTrackedSelection();
|
|
167
156
|
|
|
168
157
|
if (this.state.mouseState === "down") {
|
|
169
158
|
this.setState({
|
package/src/hints-renderer.jsx
CHANGED
|
@@ -26,6 +26,8 @@ import type {APIOptionsWithDefaults} from "./types.js";
|
|
|
26
26
|
type Props = {|
|
|
27
27
|
...React.ElementConfig<Renderer>,
|
|
28
28
|
className?: string,
|
|
29
|
+
// note (mcurtis): I think this should be $ReadOnlyArray<PerseusRenderer>,
|
|
30
|
+
// but things spiraled out of control when I tried to change it
|
|
29
31
|
hints: $ReadOnlyArray<$FlowFixMe>,
|
|
30
32
|
hintsVisible?: number,
|
|
31
33
|
|};
|
|
@@ -72,11 +74,18 @@ class HintsRenderer extends React.Component<Props, State> {
|
|
|
72
74
|
this._cacheHintImages();
|
|
73
75
|
}
|
|
74
76
|
|
|
77
|
+
// Force number to make Flow happy
|
|
78
|
+
const prevHintsVisible = prevProps.hintsVisible || 0;
|
|
79
|
+
const nextHintsVisible = this.props.hintsVisible || 0;
|
|
80
|
+
|
|
75
81
|
// When a new hint is displayed we immediately focus it
|
|
76
|
-
//
|
|
77
|
-
if (
|
|
78
|
-
|
|
79
|
-
|
|
82
|
+
// (keeping within the boundaries of hint count)
|
|
83
|
+
if (
|
|
84
|
+
prevHintsVisible < nextHintsVisible &&
|
|
85
|
+
nextHintsVisible <= this.props.hints.length &&
|
|
86
|
+
nextHintsVisible >= 0
|
|
87
|
+
) {
|
|
88
|
+
const pos = nextHintsVisible - 1;
|
|
80
89
|
// $FlowFixMe[prop-missing]
|
|
81
90
|
// $FlowFixMe[incompatible-use]
|
|
82
91
|
ReactDOM.findDOMNode(this.refs["hintRenderer" + pos]).focus(); // eslint-disable-line react/no-string-refs
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
// @flow
|
|
2
|
+
|
|
3
|
+
import {removeDenylistProps} from "../widget-prop-blacklist.js";
|
|
4
|
+
|
|
5
|
+
describe("removeDenylistProps", () => {
|
|
6
|
+
it("removes props that are in denylist from input", () => {
|
|
7
|
+
// Arrange
|
|
8
|
+
const props = {
|
|
9
|
+
// These props are not on the denylist
|
|
10
|
+
foo: "bar",
|
|
11
|
+
gandalf: "awesome",
|
|
12
|
+
// These props are on the denylist
|
|
13
|
+
key: "f-sharp",
|
|
14
|
+
id: 42,
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
// Act
|
|
18
|
+
const result = removeDenylistProps(props);
|
|
19
|
+
|
|
20
|
+
// Assert
|
|
21
|
+
expect(result).toStrictEqual({foo: "bar", gandalf: "awesome"});
|
|
22
|
+
});
|
|
23
|
+
});
|
|
@@ -9,8 +9,10 @@
|
|
|
9
9
|
* circular JSON structures sometimes).
|
|
10
10
|
*
|
|
11
11
|
* This blacklists things that we know don't need to be serialized.
|
|
12
|
+
*
|
|
13
|
+
* TODO(TB): Go through and update usage of BLACKLIST to DENYLIST: https://khanacademy.atlassian.net/browse/LP-13149?atlOrigin=eyJpIjoiNTI0Y2UwNzQ0MzA4NDYzOGI1YWRmNjEwY2E5YzZlZWUiLCJwIjoiaiJ9
|
|
12
14
|
*/
|
|
13
|
-
|
|
15
|
+
const denylist = [
|
|
14
16
|
// standard props "added" by react
|
|
15
17
|
// (technically the renderer still adds them)
|
|
16
18
|
"key",
|
|
@@ -34,3 +36,15 @@ export default [
|
|
|
34
36
|
"trackInteraction",
|
|
35
37
|
"keypadElement",
|
|
36
38
|
];
|
|
39
|
+
|
|
40
|
+
export const removeDenylistProps = (props: Object): Object => {
|
|
41
|
+
const newProps = {...props};
|
|
42
|
+
for (const prop of denylist) {
|
|
43
|
+
if (prop in newProps) {
|
|
44
|
+
delete newProps[prop];
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
return newProps;
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
export default denylist;
|
|
@@ -218,7 +218,7 @@ exports[`multi-item renderer should snapshot: initial render 1`] = `
|
|
|
218
218
|
type="button"
|
|
219
219
|
>
|
|
220
220
|
<div
|
|
221
|
-
style="display: flex; flex-direction: row; justify-content: center; align-content: center; padding-top: 8px; padding-bottom: 8px;"
|
|
221
|
+
style="display: flex; flex-direction: row; justify-content: center; align-content: center; padding-top: 8px; padding-bottom: 8px; padding-left: 8px;"
|
|
222
222
|
>
|
|
223
223
|
<div
|
|
224
224
|
class="iconWrapper_17y0hv9"
|
|
@@ -234,7 +234,11 @@ exports[`multi-item renderer should snapshot: initial render 1`] = `
|
|
|
234
234
|
data-test-id="choice-icon__library-choice-icon"
|
|
235
235
|
style="border-color: rgba(33,36,44,0.64); color: rgba(33, 36, 44, 0.64); border-radius: 24px;"
|
|
236
236
|
>
|
|
237
|
-
|
|
237
|
+
<div
|
|
238
|
+
class="innerWrapper_177sg8x"
|
|
239
|
+
>
|
|
240
|
+
A
|
|
241
|
+
</div>
|
|
238
242
|
</div>
|
|
239
243
|
</span>
|
|
240
244
|
</div>
|
|
@@ -389,7 +393,7 @@ exports[`multi-item renderer should snapshot: initial render 1`] = `
|
|
|
389
393
|
type="button"
|
|
390
394
|
>
|
|
391
395
|
<div
|
|
392
|
-
style="display: flex; flex-direction: row; justify-content: center; align-content: center; padding-top: 8px; padding-bottom: 8px;"
|
|
396
|
+
style="display: flex; flex-direction: row; justify-content: center; align-content: center; padding-top: 8px; padding-bottom: 8px; padding-left: 8px;"
|
|
393
397
|
>
|
|
394
398
|
<div
|
|
395
399
|
class="iconWrapper_17y0hv9"
|
|
@@ -405,7 +409,11 @@ exports[`multi-item renderer should snapshot: initial render 1`] = `
|
|
|
405
409
|
data-test-id="choice-icon__library-choice-icon"
|
|
406
410
|
style="border-color: rgba(33,36,44,0.64); color: rgba(33, 36, 44, 0.64); border-radius: 24px;"
|
|
407
411
|
>
|
|
408
|
-
|
|
412
|
+
<div
|
|
413
|
+
class="innerWrapper_177sg8x"
|
|
414
|
+
>
|
|
415
|
+
B
|
|
416
|
+
</div>
|
|
409
417
|
</div>
|
|
410
418
|
</span>
|
|
411
419
|
</div>
|
|
@@ -560,7 +568,7 @@ exports[`multi-item renderer should snapshot: initial render 1`] = `
|
|
|
560
568
|
type="button"
|
|
561
569
|
>
|
|
562
570
|
<div
|
|
563
|
-
style="display: flex; flex-direction: row; justify-content: center; align-content: center; padding-top: 8px; padding-bottom: 8px;"
|
|
571
|
+
style="display: flex; flex-direction: row; justify-content: center; align-content: center; padding-top: 8px; padding-bottom: 8px; padding-left: 8px;"
|
|
564
572
|
>
|
|
565
573
|
<div
|
|
566
574
|
class="iconWrapper_17y0hv9"
|
|
@@ -576,7 +584,11 @@ exports[`multi-item renderer should snapshot: initial render 1`] = `
|
|
|
576
584
|
data-test-id="choice-icon__library-choice-icon"
|
|
577
585
|
style="border-color: rgba(33,36,44,0.64); color: rgba(33, 36, 44, 0.64); border-radius: 24px;"
|
|
578
586
|
>
|
|
579
|
-
|
|
587
|
+
<div
|
|
588
|
+
class="innerWrapper_177sg8x"
|
|
589
|
+
>
|
|
590
|
+
C
|
|
591
|
+
</div>
|
|
580
592
|
</div>
|
|
581
593
|
</span>
|
|
582
594
|
</div>
|
|
@@ -731,7 +743,7 @@ exports[`multi-item renderer should snapshot: initial render 1`] = `
|
|
|
731
743
|
type="button"
|
|
732
744
|
>
|
|
733
745
|
<div
|
|
734
|
-
style="display: flex; flex-direction: row; justify-content: center; align-content: center; padding-top: 8px; padding-bottom: 8px;"
|
|
746
|
+
style="display: flex; flex-direction: row; justify-content: center; align-content: center; padding-top: 8px; padding-bottom: 8px; padding-left: 8px;"
|
|
735
747
|
>
|
|
736
748
|
<div
|
|
737
749
|
class="iconWrapper_17y0hv9"
|
|
@@ -747,7 +759,11 @@ exports[`multi-item renderer should snapshot: initial render 1`] = `
|
|
|
747
759
|
data-test-id="choice-icon__library-choice-icon"
|
|
748
760
|
style="border-color: rgba(33,36,44,0.64); color: rgba(33, 36, 44, 0.64); border-radius: 24px;"
|
|
749
761
|
>
|
|
750
|
-
|
|
762
|
+
<div
|
|
763
|
+
class="innerWrapper_177sg8x"
|
|
764
|
+
>
|
|
765
|
+
D
|
|
766
|
+
</div>
|
|
751
767
|
</div>
|
|
752
768
|
</span>
|
|
753
769
|
</div>
|
|
@@ -902,7 +918,7 @@ exports[`multi-item renderer should snapshot: initial render 1`] = `
|
|
|
902
918
|
type="button"
|
|
903
919
|
>
|
|
904
920
|
<div
|
|
905
|
-
style="display: flex; flex-direction: row; justify-content: center; align-content: center; padding-top: 8px; padding-bottom: 8px;"
|
|
921
|
+
style="display: flex; flex-direction: row; justify-content: center; align-content: center; padding-top: 8px; padding-bottom: 8px; padding-left: 8px;"
|
|
906
922
|
>
|
|
907
923
|
<div
|
|
908
924
|
class="iconWrapper_17y0hv9"
|
|
@@ -918,7 +934,11 @@ exports[`multi-item renderer should snapshot: initial render 1`] = `
|
|
|
918
934
|
data-test-id="choice-icon__library-choice-icon"
|
|
919
935
|
style="border-color: rgba(33,36,44,0.64); color: rgba(33, 36, 44, 0.64); border-radius: 24px;"
|
|
920
936
|
>
|
|
921
|
-
|
|
937
|
+
<div
|
|
938
|
+
class="innerWrapper_177sg8x"
|
|
939
|
+
>
|
|
940
|
+
E
|
|
941
|
+
</div>
|
|
922
942
|
</div>
|
|
923
943
|
</span>
|
|
924
944
|
</div>
|
package/src/styles/articles.less
CHANGED
package/src/types.js
CHANGED
|
@@ -491,7 +491,7 @@ export type WidgetProps<RenderProps, Rubric> = {|
|
|
|
491
491
|
questionCompleted?: boolean,
|
|
492
492
|
onFocus: (blurPath: FocusPath) => void,
|
|
493
493
|
onBlur: (blurPath: FocusPath) => void,
|
|
494
|
-
findWidgets: (FilterCriterion) =>
|
|
494
|
+
findWidgets: (FilterCriterion) => $ReadOnlyArray<Widget>,
|
|
495
495
|
reviewModeRubric: Rubric,
|
|
496
496
|
onChange: ChangeHandler,
|
|
497
497
|
trackInteraction: (extraData?: any) => void,
|
|
@@ -23,11 +23,19 @@ exports[`Dropdown widget should snapshot when opened: dropdown open 1`] = `
|
|
|
23
23
|
<div
|
|
24
24
|
class="default_xu2jcg-o_O-menuWrapper_wvrnr4"
|
|
25
25
|
>
|
|
26
|
+
<span
|
|
27
|
+
aria-atomic="true"
|
|
28
|
+
aria-live="polite"
|
|
29
|
+
aria-relevant="additions text"
|
|
30
|
+
class="srOnly_19bpjuy"
|
|
31
|
+
data-test-id="dropdown-live-region"
|
|
32
|
+
>
|
|
33
|
+
3 items
|
|
34
|
+
</span>
|
|
26
35
|
<button
|
|
27
36
|
aria-expanded="true"
|
|
28
37
|
aria-haspopup="listbox"
|
|
29
38
|
class="button_vr44p2-o_O-shared_u51dsh-o_O-default_kjzwx1-o_O-focus_1qpi544"
|
|
30
|
-
tabindex="0"
|
|
31
39
|
type="button"
|
|
32
40
|
>
|
|
33
41
|
<span
|
|
@@ -94,11 +102,17 @@ exports[`Dropdown widget should snapshot: initial render 1`] = `
|
|
|
94
102
|
<div
|
|
95
103
|
class="default_xu2jcg-o_O-menuWrapper_wvrnr4"
|
|
96
104
|
>
|
|
105
|
+
<span
|
|
106
|
+
aria-atomic="true"
|
|
107
|
+
aria-live="polite"
|
|
108
|
+
aria-relevant="additions text"
|
|
109
|
+
class="srOnly_19bpjuy"
|
|
110
|
+
data-test-id="dropdown-live-region"
|
|
111
|
+
/>
|
|
97
112
|
<button
|
|
98
113
|
aria-expanded="false"
|
|
99
114
|
aria-haspopup="listbox"
|
|
100
115
|
class="button_vr44p2-o_O-shared_u51dsh-o_O-default_kjzwx1"
|
|
101
|
-
tabindex="0"
|
|
102
116
|
type="button"
|
|
103
117
|
>
|
|
104
118
|
<span
|
|
@@ -33,7 +33,7 @@ exports[`graded-group-set should render all graded groups 1`] = `
|
|
|
33
33
|
class="perseus-graded-group"
|
|
34
34
|
>
|
|
35
35
|
<div
|
|
36
|
-
class="
|
|
36
|
+
class="title_1lagzkb"
|
|
37
37
|
>
|
|
38
38
|
Problem 1a
|
|
39
39
|
</div>
|
|
@@ -270,7 +270,7 @@ exports[`graded-group-set should render all graded groups 1`] = `
|
|
|
270
270
|
class="perseus-graded-group"
|
|
271
271
|
>
|
|
272
272
|
<div
|
|
273
|
-
class="
|
|
273
|
+
class="title_1lagzkb"
|
|
274
274
|
>
|
|
275
275
|
Problem 1b
|
|
276
276
|
</div>
|
|
@@ -507,7 +507,7 @@ exports[`graded-group-set should render all graded groups 1`] = `
|
|
|
507
507
|
class="perseus-graded-group"
|
|
508
508
|
>
|
|
509
509
|
<div
|
|
510
|
-
class="
|
|
510
|
+
class="title_1lagzkb"
|
|
511
511
|
>
|
|
512
512
|
Problem 1c
|
|
513
513
|
</div>
|