@khanacademy/perseus 5.0.0 → 6.0.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 +42 -0
- package/dist/components/fixed-to-responsive.d.ts +27 -1
- package/dist/components/fixed-to-responsive.js.flow +27 -1
- package/dist/components/graph.d.ts +42 -26
- package/dist/components/graph.js.flow +42 -28
- package/dist/components/graphie.d.ts +34 -22
- package/dist/components/graphie.js.flow +37 -24
- package/dist/components/hud.d.ts +8 -14
- package/dist/components/hud.js.flow +7 -14
- package/dist/components/inline-icon.d.ts +9 -19
- package/dist/components/inline-icon.js.flow +26 -13
- package/dist/components/lint.d.ts +41 -13
- package/dist/components/lint.js.flow +42 -13
- package/dist/components/math-output.d.ts +15 -11
- package/dist/components/math-output.js.flow +15 -11
- package/dist/components/sortable.d.ts +17 -9
- package/dist/components/sortable.js.flow +22 -9
- package/dist/components/svg-image.d.ts +5 -3
- package/dist/components/svg-image.js.flow +5 -3
- package/dist/components/tooltip.d.ts +45 -4
- package/dist/components/tooltip.js.flow +44 -31
- package/dist/es/index.css +0 -3
- package/dist/es/index.js +477 -648
- package/dist/es/index.js.map +1 -1
- package/dist/index.css +0 -3
- package/dist/index.js +481 -645
- package/dist/index.js.map +1 -1
- package/dist/perseus-types.d.ts +11 -9
- package/dist/perseus-types.js.flow +11 -9
- package/dist/renderer.d.ts +2 -2
- package/dist/renderer.js.flow +1 -3
- package/dist/styles/shared.d.ts +0 -1
- package/dist/styles/shared.js.flow +0 -1
- package/dist/types.d.ts +0 -10
- package/dist/types.js.flow +0 -13
- package/dist/util/a11y.d.ts +0 -1
- package/dist/util/a11y.js.flow +0 -1
- package/dist/util/interactive.d.ts +2 -0
- package/dist/util/interactive.js.flow +2 -0
- package/dist/util.d.ts +3 -3
- package/dist/util.js.flow +4 -3
- package/dist/widgets/grapher.d.ts +1 -1
- package/dist/widgets/grapher.js.flow +12 -3
- package/dist/widgets/matcher.d.ts +7 -3
- package/dist/widgets/matcher.js.flow +7 -3
- package/dist/widgets/number-line.d.ts +1 -1
- package/dist/widgets/number-line.js.flow +1 -1
- package/package.json +2 -2
- package/src/__tests__/__snapshots__/item-renderer.test.tsx.snap +151 -159
- package/src/__tests__/__snapshots__/renderer.test.tsx.snap +358 -394
- package/src/__tests__/__snapshots__/server-item-renderer.test.tsx.snap +169 -189
- package/src/components/__stories__/lint.stories.tsx +56 -21
- package/src/components/__stories__/sortable.stories.tsx +5 -5
- package/src/components/__stories__/tooltip.stories.tsx +52 -0
- package/src/components/__tests__/__snapshots__/sortable.test.tsx.snap +114 -30
- package/src/components/__tests__/__snapshots__/sorter.test.tsx.snap +172 -204
- package/src/components/__tests__/sortable.test.tsx +54 -16
- package/src/components/__tests__/sorter.test.tsx +12 -9
- package/src/components/fixed-to-responsive.tsx +43 -38
- package/src/components/graph.tsx +95 -81
- package/src/components/graphie.tsx +62 -32
- package/src/components/hud.tsx +104 -115
- package/src/components/inline-icon.tsx +15 -32
- package/src/components/input-with-examples.tsx +4 -4
- package/src/components/lint.tsx +47 -41
- package/src/components/math-output.tsx +17 -11
- package/src/components/simple-keypad-input.tsx +2 -2
- package/src/components/sortable.tsx +134 -94
- package/src/components/svg-image.tsx +10 -11
- package/src/components/tooltip.tsx +189 -171
- package/src/interactive2/types.ts +2 -2
- package/src/multi-items/__tests__/__snapshots__/multi-renderer.test.tsx.snap +708 -764
- package/src/perseus-types.ts +13 -9
- package/src/renderer.tsx +11 -22
- package/src/types.ts +0 -18
- package/src/util/interactive.ts +18 -5
- package/src/util/tex.ts +13 -77
- package/src/util.ts +3 -4
- package/src/widgets/__tests__/__snapshots__/categorizer.test.ts.snap +717 -773
- package/src/widgets/__tests__/__snapshots__/cs-program.test.ts.snap +28 -36
- package/src/widgets/__tests__/__snapshots__/definition.test.ts.snap +52 -60
- package/src/widgets/__tests__/__snapshots__/dropdown.test.ts.snap +100 -108
- package/src/widgets/__tests__/__snapshots__/explanation.test.ts.snap +212 -260
- package/src/widgets/__tests__/__snapshots__/graded-group-set-jipt.test.ts.snap +613 -641
- package/src/widgets/__tests__/__snapshots__/graded-group-set.test.ts.snap +249 -261
- package/src/widgets/__tests__/__snapshots__/graded-group.test.ts.snap +671 -735
- package/src/widgets/__tests__/__snapshots__/grapher.test.ts.snap +2676 -2684
- package/src/widgets/__tests__/__snapshots__/group.test.tsx.snap +938 -1002
- package/src/widgets/__tests__/__snapshots__/iframe.test.ts.snap +28 -36
- package/src/widgets/__tests__/__snapshots__/image.test.ts.snap +227 -255
- package/src/widgets/__tests__/__snapshots__/input-number.test.ts.snap +353 -357
- package/src/widgets/__tests__/__snapshots__/interaction.test.ts.snap +255 -259
- package/src/widgets/__tests__/__snapshots__/interactive-graph.test.ts.snap +2401 -2433
- package/src/widgets/__tests__/__snapshots__/matcher.test.tsx.snap +600 -756
- package/src/widgets/__tests__/__snapshots__/matrix.test.ts.snap +420 -428
- package/src/widgets/__tests__/__snapshots__/number-line.test.ts.snap +762 -770
- package/src/widgets/__tests__/__snapshots__/numeric-input.test.ts.snap +373 -393
- package/src/widgets/__tests__/__snapshots__/orderer.test.ts.snap +116 -148
- package/src/widgets/__tests__/__snapshots__/passage-ref.test.ts.snap +289 -301
- package/src/widgets/__tests__/__snapshots__/passage.test.tsx.snap +1679 -1711
- package/src/widgets/__tests__/__snapshots__/radio.test.ts.snap +2692 -2960
- package/src/widgets/__tests__/__snapshots__/video.test.ts.snap +90 -98
- package/src/widgets/__tests__/matcher.test.tsx +33 -9
- package/src/widgets/expression.tsx +9 -6
- package/src/widgets/grapher.tsx +3 -3
- package/src/widgets/image.tsx +2 -2
- package/src/widgets/interactive-graph.tsx +5 -5
- package/src/widgets/matcher.tsx +43 -24
- package/src/widgets/number-line.tsx +1 -1
- package/src/widgets/simulator.tsx +4 -6
- package/{tsconfig.json → tsconfig-build.json} +6 -6
- package/tsconfig-build.tsbuildinfo +1 -0
- package/tsconfig.tsbuildinfo +0 -1
|
@@ -2,160 +2,152 @@
|
|
|
2
2
|
|
|
3
3
|
exports[`video widget should snapshot on mobile: first mobile render 1`] = `
|
|
4
4
|
<div>
|
|
5
|
-
<
|
|
6
|
-
class="
|
|
5
|
+
<div
|
|
6
|
+
class="perseus-renderer perseus-renderer-responsive"
|
|
7
7
|
>
|
|
8
8
|
<div
|
|
9
|
-
class="
|
|
9
|
+
class="paragraph"
|
|
10
|
+
data-perseus-paragraph-index="0"
|
|
10
11
|
>
|
|
11
12
|
<div
|
|
12
13
|
class="paragraph"
|
|
13
|
-
data-perseus-paragraph-index="0"
|
|
14
14
|
>
|
|
15
|
-
|
|
16
|
-
class="paragraph"
|
|
17
|
-
>
|
|
18
|
-
Watch the Biogeography: Where Life Lives video to find the answer.
|
|
19
|
-
</div>
|
|
15
|
+
Watch the Biogeography: Where Life Lives video to find the answer.
|
|
20
16
|
</div>
|
|
17
|
+
</div>
|
|
18
|
+
<div
|
|
19
|
+
class="paragraph"
|
|
20
|
+
data-perseus-paragraph-index="1"
|
|
21
|
+
>
|
|
21
22
|
<div
|
|
22
23
|
class="paragraph"
|
|
23
|
-
data-perseus-paragraph-index="1"
|
|
24
24
|
>
|
|
25
25
|
<div
|
|
26
|
-
class="
|
|
26
|
+
class="perseus-widget-container widget-nohighlight widget-block"
|
|
27
27
|
>
|
|
28
28
|
<div
|
|
29
|
-
class="
|
|
29
|
+
class="default_xu2jcg"
|
|
30
30
|
>
|
|
31
31
|
<div
|
|
32
|
-
class="
|
|
32
|
+
class="fixed-to-responsive"
|
|
33
|
+
style="max-width: 1280px; max-height: 720px;"
|
|
33
34
|
>
|
|
34
35
|
<div
|
|
35
|
-
|
|
36
|
-
|
|
36
|
+
style="padding-bottom: 56.25%;"
|
|
37
|
+
/>
|
|
38
|
+
<div
|
|
39
|
+
class="default_xu2jcg-o_O-srOnly_19bpjuy"
|
|
37
40
|
>
|
|
38
|
-
|
|
39
|
-
style="padding-bottom: 56.25%;"
|
|
40
|
-
/>
|
|
41
|
-
<div
|
|
42
|
-
class="default_xu2jcg-o_O-srOnly_19bpjuy"
|
|
43
|
-
>
|
|
44
|
-
Khan Academy video wrapper
|
|
45
|
-
</div>
|
|
46
|
-
<iframe
|
|
47
|
-
allowfullscreen=""
|
|
48
|
-
class="perseus-video-widget"
|
|
49
|
-
height="720"
|
|
50
|
-
sandbox="allow-same-origin allow-scripts"
|
|
51
|
-
src="https://www.khanacademy.org/embed_video?slug=biogeography-where-life-lives&internal_video_only=1"
|
|
52
|
-
width="1280"
|
|
53
|
-
/>
|
|
41
|
+
Khan Academy video wrapper
|
|
54
42
|
</div>
|
|
43
|
+
<iframe
|
|
44
|
+
allowfullscreen=""
|
|
45
|
+
class="perseus-video-widget"
|
|
46
|
+
height="720"
|
|
47
|
+
sandbox="allow-same-origin allow-scripts"
|
|
48
|
+
src="https://www.khanacademy.org/embed_video?slug=biogeography-where-life-lives&internal_video_only=1"
|
|
49
|
+
width="1280"
|
|
50
|
+
/>
|
|
51
|
+
</div>
|
|
52
|
+
<div
|
|
53
|
+
class="default_xu2jcg-o_O-transcriptLink_18xwqfz"
|
|
54
|
+
>
|
|
55
|
+
<span
|
|
56
|
+
class="text_f1191h"
|
|
57
|
+
/>
|
|
55
58
|
<div
|
|
56
|
-
|
|
59
|
+
aria-hidden="true"
|
|
60
|
+
class="default_xu2jcg-o_O-inlineStyles_sc01dy"
|
|
61
|
+
/>
|
|
62
|
+
<a
|
|
63
|
+
class="shared_htyo3s-o_O-resting_nelfll visited-no-recolor"
|
|
64
|
+
href="/transcript/videoNotFound"
|
|
65
|
+
rel="noopener noreferrer"
|
|
66
|
+
target="_blank"
|
|
57
67
|
>
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
/>
|
|
61
|
-
<div
|
|
62
|
-
aria-hidden="true"
|
|
63
|
-
class="default_xu2jcg-o_O-inlineStyles_sc01dy"
|
|
64
|
-
/>
|
|
65
|
-
<a
|
|
66
|
-
class="shared_htyo3s-o_O-resting_nelfll visited-no-recolor"
|
|
67
|
-
href="/transcript/videoNotFound"
|
|
68
|
-
rel="noopener noreferrer"
|
|
69
|
-
target="_blank"
|
|
70
|
-
>
|
|
71
|
-
See video transcript
|
|
72
|
-
</a>
|
|
73
|
-
</div>
|
|
68
|
+
See video transcript
|
|
69
|
+
</a>
|
|
74
70
|
</div>
|
|
75
71
|
</div>
|
|
76
72
|
</div>
|
|
77
73
|
</div>
|
|
78
74
|
</div>
|
|
79
|
-
</
|
|
75
|
+
</div>
|
|
80
76
|
</div>
|
|
81
77
|
`;
|
|
82
78
|
|
|
83
79
|
exports[`video widget should snapshot: first render 1`] = `
|
|
84
80
|
<div>
|
|
85
|
-
<
|
|
86
|
-
class="
|
|
81
|
+
<div
|
|
82
|
+
class="perseus-renderer perseus-renderer-responsive"
|
|
87
83
|
>
|
|
88
84
|
<div
|
|
89
|
-
class="
|
|
85
|
+
class="paragraph"
|
|
86
|
+
data-perseus-paragraph-index="0"
|
|
90
87
|
>
|
|
91
88
|
<div
|
|
92
89
|
class="paragraph"
|
|
93
|
-
data-perseus-paragraph-index="0"
|
|
94
90
|
>
|
|
95
|
-
|
|
96
|
-
class="paragraph"
|
|
97
|
-
>
|
|
98
|
-
Watch the Biogeography: Where Life Lives video to find the answer.
|
|
99
|
-
</div>
|
|
91
|
+
Watch the Biogeography: Where Life Lives video to find the answer.
|
|
100
92
|
</div>
|
|
93
|
+
</div>
|
|
94
|
+
<div
|
|
95
|
+
class="paragraph"
|
|
96
|
+
data-perseus-paragraph-index="1"
|
|
97
|
+
>
|
|
101
98
|
<div
|
|
102
99
|
class="paragraph"
|
|
103
|
-
data-perseus-paragraph-index="1"
|
|
104
100
|
>
|
|
105
101
|
<div
|
|
106
|
-
class="
|
|
102
|
+
class="perseus-widget-container widget-nohighlight widget-block"
|
|
107
103
|
>
|
|
108
104
|
<div
|
|
109
|
-
class="
|
|
105
|
+
class="default_xu2jcg"
|
|
110
106
|
>
|
|
111
107
|
<div
|
|
112
|
-
class="
|
|
108
|
+
class="fixed-to-responsive"
|
|
109
|
+
style="max-width: 1280px; max-height: 720px;"
|
|
113
110
|
>
|
|
114
111
|
<div
|
|
115
|
-
|
|
116
|
-
|
|
112
|
+
style="padding-bottom: 56.25%;"
|
|
113
|
+
/>
|
|
114
|
+
<div
|
|
115
|
+
class="default_xu2jcg-o_O-srOnly_19bpjuy"
|
|
117
116
|
>
|
|
118
|
-
|
|
119
|
-
style="padding-bottom: 56.25%;"
|
|
120
|
-
/>
|
|
121
|
-
<div
|
|
122
|
-
class="default_xu2jcg-o_O-srOnly_19bpjuy"
|
|
123
|
-
>
|
|
124
|
-
Khan Academy video wrapper
|
|
125
|
-
</div>
|
|
126
|
-
<iframe
|
|
127
|
-
allowfullscreen=""
|
|
128
|
-
class="perseus-video-widget"
|
|
129
|
-
height="720"
|
|
130
|
-
sandbox="allow-same-origin allow-scripts"
|
|
131
|
-
src="https://www.khanacademy.org/embed_video?slug=biogeography-where-life-lives&internal_video_only=1"
|
|
132
|
-
width="1280"
|
|
133
|
-
/>
|
|
117
|
+
Khan Academy video wrapper
|
|
134
118
|
</div>
|
|
119
|
+
<iframe
|
|
120
|
+
allowfullscreen=""
|
|
121
|
+
class="perseus-video-widget"
|
|
122
|
+
height="720"
|
|
123
|
+
sandbox="allow-same-origin allow-scripts"
|
|
124
|
+
src="https://www.khanacademy.org/embed_video?slug=biogeography-where-life-lives&internal_video_only=1"
|
|
125
|
+
width="1280"
|
|
126
|
+
/>
|
|
127
|
+
</div>
|
|
128
|
+
<div
|
|
129
|
+
class="default_xu2jcg-o_O-transcriptLink_18xwqfz"
|
|
130
|
+
>
|
|
131
|
+
<span
|
|
132
|
+
class="text_f1191h"
|
|
133
|
+
/>
|
|
135
134
|
<div
|
|
136
|
-
|
|
135
|
+
aria-hidden="true"
|
|
136
|
+
class="default_xu2jcg-o_O-inlineStyles_sc01dy"
|
|
137
|
+
/>
|
|
138
|
+
<a
|
|
139
|
+
class="shared_htyo3s-o_O-resting_nelfll visited-no-recolor"
|
|
140
|
+
href="/transcript/videoNotFound"
|
|
141
|
+
rel="noopener noreferrer"
|
|
142
|
+
target="_blank"
|
|
137
143
|
>
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
/>
|
|
141
|
-
<div
|
|
142
|
-
aria-hidden="true"
|
|
143
|
-
class="default_xu2jcg-o_O-inlineStyles_sc01dy"
|
|
144
|
-
/>
|
|
145
|
-
<a
|
|
146
|
-
class="shared_htyo3s-o_O-resting_nelfll visited-no-recolor"
|
|
147
|
-
href="/transcript/videoNotFound"
|
|
148
|
-
rel="noopener noreferrer"
|
|
149
|
-
target="_blank"
|
|
150
|
-
>
|
|
151
|
-
See video transcript
|
|
152
|
-
</a>
|
|
153
|
-
</div>
|
|
144
|
+
See video transcript
|
|
145
|
+
</a>
|
|
154
146
|
</div>
|
|
155
147
|
</div>
|
|
156
148
|
</div>
|
|
157
149
|
</div>
|
|
158
150
|
</div>
|
|
159
|
-
</
|
|
151
|
+
</div>
|
|
160
152
|
</div>
|
|
161
153
|
`;
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import getRenderA11yString from "katex/dist/contrib/render-a11y-string";
|
|
2
1
|
import * as React from "react";
|
|
3
2
|
import "@testing-library/jest-dom";
|
|
4
3
|
|
|
@@ -26,15 +25,18 @@ describe("matcher widget", () => {
|
|
|
26
25
|
|
|
27
26
|
jest.spyOn(Dependencies, "getDependencies").mockReturnValue({
|
|
28
27
|
...testDependencies,
|
|
29
|
-
|
|
30
|
-
|
|
28
|
+
TeX: ({
|
|
29
|
+
children,
|
|
30
|
+
onRender: onLoad,
|
|
31
|
+
}: {
|
|
32
|
+
children: React.ReactNode;
|
|
33
|
+
onRender?: () => unknown;
|
|
34
|
+
}) => {
|
|
35
|
+
React.useLayoutEffect(() => {
|
|
36
|
+
onLoad?.();
|
|
37
|
+
}, [onLoad]);
|
|
38
|
+
return <span className="tex-mock">{children}</span>;
|
|
31
39
|
},
|
|
32
|
-
TeX: ({children}: {children: React.ReactNode}) => (
|
|
33
|
-
<span className="tex-mock">{children}</span>
|
|
34
|
-
),
|
|
35
|
-
// @ts-expect-error [FEI-5003] - TS2322 - Type 'Promise<any>' is not assignable to type '() => Promise<katexA11y>'.
|
|
36
|
-
getRenderA11yString: Promise.resolve(getRenderA11yString),
|
|
37
|
-
shouldUseFutureKaTeX: (flag: boolean) => {},
|
|
38
40
|
});
|
|
39
41
|
});
|
|
40
42
|
|
|
@@ -149,4 +151,26 @@ describe("matcher widget", () => {
|
|
|
149
151
|
// Assert
|
|
150
152
|
expect(renderer).toHaveBeenAnsweredIncorrectly();
|
|
151
153
|
});
|
|
154
|
+
|
|
155
|
+
it("is scored incorrect if the math renderer hasn't loaded yet", () => {
|
|
156
|
+
// Arrange: stub the TeX renderer to never call its onRender prop,
|
|
157
|
+
// which is how the matcher knows the math renderer is ready.
|
|
158
|
+
jest.spyOn(Dependencies, "getDependencies").mockReturnValue({
|
|
159
|
+
...testDependencies,
|
|
160
|
+
TeX: () => {
|
|
161
|
+
return null;
|
|
162
|
+
},
|
|
163
|
+
});
|
|
164
|
+
|
|
165
|
+
const apiOptions: APIOptions = {
|
|
166
|
+
isMobile: false,
|
|
167
|
+
};
|
|
168
|
+
const {renderer} = renderQuestion(question1, apiOptions);
|
|
169
|
+
|
|
170
|
+
// Act
|
|
171
|
+
renderer.guessAndScore();
|
|
172
|
+
|
|
173
|
+
// Assert
|
|
174
|
+
expect(renderer).toHaveBeenAnsweredIncorrectly();
|
|
175
|
+
});
|
|
152
176
|
});
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/* eslint-disable react/prop-types */
|
|
2
2
|
import * as KAS from "@khanacademy/kas";
|
|
3
|
-
import {KeypadInput,
|
|
3
|
+
import {KeypadInput, KeypadType} from "@khanacademy/math-input";
|
|
4
4
|
import {linterContextDefault} from "@khanacademy/perseus-linter";
|
|
5
5
|
import * as i18n from "@khanacademy/wonder-blocks-i18n";
|
|
6
6
|
import classNames from "classnames";
|
|
@@ -9,7 +9,10 @@ import _ from "underscore";
|
|
|
9
9
|
|
|
10
10
|
import InlineIcon from "../components/inline-icon";
|
|
11
11
|
import MathInput from "../components/math-input";
|
|
12
|
-
import Tooltip
|
|
12
|
+
import Tooltip, {
|
|
13
|
+
HorizontalDirection,
|
|
14
|
+
VerticalDirection,
|
|
15
|
+
} from "../components/tooltip";
|
|
13
16
|
import {iconExclamationSign} from "../icon-paths";
|
|
14
17
|
import {Errors as PerseusErrors, Log} from "../logging/log";
|
|
15
18
|
import * as Changeable from "../mixins/changeable";
|
|
@@ -478,9 +481,9 @@ export class Expression extends React.Component<Props, ExpressionState> {
|
|
|
478
481
|
<span className="error-tooltip" role="tooltip">
|
|
479
482
|
<Tooltip
|
|
480
483
|
className="error-text-container"
|
|
481
|
-
horizontalPosition=
|
|
482
|
-
horizontalAlign=
|
|
483
|
-
verticalPosition=
|
|
484
|
+
horizontalPosition={HorizontalDirection.Right}
|
|
485
|
+
horizontalAlign={HorizontalDirection.Left}
|
|
486
|
+
verticalPosition={VerticalDirection.Top}
|
|
484
487
|
arrowSize={10}
|
|
485
488
|
borderColor="#fcc335"
|
|
486
489
|
show={this.state.showErrorText}
|
|
@@ -549,7 +552,7 @@ const keypadConfigurationForProps = (
|
|
|
549
552
|
) => {
|
|
550
553
|
// Always use the Expression keypad, regardless of the button sets that have
|
|
551
554
|
// been enabled.
|
|
552
|
-
const keypadType =
|
|
555
|
+
const keypadType = KeypadType.EXPRESSION;
|
|
553
556
|
|
|
554
557
|
// Extract any and all variables and constants from the answer forms.
|
|
555
558
|
const uniqueExtraVariables: Record<string, any> = {};
|
package/src/widgets/grapher.tsx
CHANGED
|
@@ -476,15 +476,15 @@ class Grapher extends React.Component<Props> {
|
|
|
476
476
|
_calculateMobileTickStep(
|
|
477
477
|
gridStep: JSX.LibraryManagedAttributes<
|
|
478
478
|
typeof Graphie,
|
|
479
|
-
React.ComponentProps<typeof Graphie
|
|
479
|
+
Required<React.ComponentProps<typeof Graphie>>
|
|
480
480
|
>["gridStep"],
|
|
481
481
|
step: JSX.LibraryManagedAttributes<
|
|
482
482
|
typeof Graphie,
|
|
483
|
-
React.ComponentProps<typeof Graphie
|
|
483
|
+
Required<React.ComponentProps<typeof Graphie>>
|
|
484
484
|
>["step"],
|
|
485
485
|
ranges: JSX.LibraryManagedAttributes<
|
|
486
486
|
typeof Graphie,
|
|
487
|
-
React.ComponentProps<typeof Graphie
|
|
487
|
+
Required<React.ComponentProps<typeof Graphie>>
|
|
488
488
|
>["ranges"],
|
|
489
489
|
): any {
|
|
490
490
|
const tickStep = Util.constrainedTickStepsFromTickSteps(step, ranges);
|
package/src/widgets/image.tsx
CHANGED
|
@@ -12,7 +12,7 @@ import Renderer from "../renderer";
|
|
|
12
12
|
import {baseUnitPx} from "../styles/constants";
|
|
13
13
|
import mediaQueries from "../styles/media-queries";
|
|
14
14
|
|
|
15
|
-
import type {PerseusImageWidgetOptions} from "../perseus-types";
|
|
15
|
+
import type {Range, PerseusImageWidgetOptions} from "../perseus-types";
|
|
16
16
|
import type {
|
|
17
17
|
ChangeFn,
|
|
18
18
|
PerseusScore,
|
|
@@ -21,7 +21,7 @@ import type {
|
|
|
21
21
|
} from "../types";
|
|
22
22
|
|
|
23
23
|
const defaultBoxSize = 400;
|
|
24
|
-
const defaultRange = [0, 10];
|
|
24
|
+
const defaultRange: Range = [0, 10];
|
|
25
25
|
const defaultBackgroundImage = {
|
|
26
26
|
url: null,
|
|
27
27
|
width: 0,
|
|
@@ -43,7 +43,7 @@ const TRASH_ICON_URI =
|
|
|
43
43
|
|
|
44
44
|
const defaultBackgroundImage = {
|
|
45
45
|
url: null,
|
|
46
|
-
}
|
|
46
|
+
};
|
|
47
47
|
|
|
48
48
|
const eq = Util.eq;
|
|
49
49
|
const deepEq = Util.deepEq;
|
|
@@ -417,7 +417,6 @@ class InteractiveGraph extends React.Component<Props, State> {
|
|
|
417
417
|
[-10, 10],
|
|
418
418
|
],
|
|
419
419
|
step: [1, 1],
|
|
420
|
-
// @ts-expect-error [FEI-5003] - TS2739 - Type '{ readonly url: null; }' is missing the following properties from type 'PerseusImageBackground': width, height
|
|
421
420
|
backgroundImage: defaultBackgroundImage,
|
|
422
421
|
markings: "graph",
|
|
423
422
|
showTooltips: false,
|
|
@@ -1984,9 +1983,10 @@ class InteractiveGraph extends React.Component<Props, State> {
|
|
|
1984
1983
|
instructions = undefined;
|
|
1985
1984
|
}
|
|
1986
1985
|
|
|
1987
|
-
|
|
1988
|
-
|
|
1989
|
-
|
|
1986
|
+
let onMouseDown;
|
|
1987
|
+
if (this.isClickToAddPoints()) {
|
|
1988
|
+
onMouseDown = this.handleAddPointsMouseDown;
|
|
1989
|
+
}
|
|
1990
1990
|
|
|
1991
1991
|
const gridStep =
|
|
1992
1992
|
this.props.gridStep ||
|
package/src/widgets/matcher.tsx
CHANGED
|
@@ -9,7 +9,7 @@ import PropTypes from "prop-types";
|
|
|
9
9
|
import * as React from "react";
|
|
10
10
|
import _ from "underscore";
|
|
11
11
|
|
|
12
|
-
import Sortable from "../components/sortable";
|
|
12
|
+
import Sortable, {Layout} from "../components/sortable";
|
|
13
13
|
import {getDependencies} from "../dependencies";
|
|
14
14
|
import {ApiOptions} from "../perseus-api";
|
|
15
15
|
import Renderer from "../renderer";
|
|
@@ -21,6 +21,12 @@ import type {WidgetExports} from "../types";
|
|
|
21
21
|
const {shuffle, seededRNG} = Util;
|
|
22
22
|
const HACKY_CSS_CLASSNAME = "perseus-widget-matcher";
|
|
23
23
|
|
|
24
|
+
type State = {
|
|
25
|
+
leftHeight: number;
|
|
26
|
+
rightHeight: number;
|
|
27
|
+
texRendererLoaded: boolean;
|
|
28
|
+
};
|
|
29
|
+
|
|
24
30
|
class Matcher extends React.Component<any, any> {
|
|
25
31
|
static propTypes = {
|
|
26
32
|
apiOptions: ApiOptions.propTypes,
|
|
@@ -46,27 +52,40 @@ class Matcher extends React.Component<any, any> {
|
|
|
46
52
|
linterContext: linterContextDefault,
|
|
47
53
|
};
|
|
48
54
|
|
|
49
|
-
state:
|
|
55
|
+
state: State = {
|
|
50
56
|
leftHeight: 0,
|
|
51
57
|
rightHeight: 0,
|
|
52
|
-
|
|
58
|
+
texRendererLoaded: false,
|
|
53
59
|
};
|
|
54
60
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
//
|
|
63
|
-
//
|
|
64
|
-
// we
|
|
65
|
-
//
|
|
66
|
-
//
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
return
|
|
61
|
+
render(): React.ReactElement {
|
|
62
|
+
// To minimize layout shift, we display a spinner until our math
|
|
63
|
+
// renderer is ready to render the math inside the matcher. To
|
|
64
|
+
// do this, we:
|
|
65
|
+
// - render a dummy TeX component to force the math renderer to load
|
|
66
|
+
// - display a spinner until the TeX component calls its onRender
|
|
67
|
+
// callback, signifying that the math is rendered (from which we can
|
|
68
|
+
// infer that the math renderer has loaded)
|
|
69
|
+
//
|
|
70
|
+
// If we didn't do this, the user might see a matcher with empty
|
|
71
|
+
// columns on first render, and then the math would pop in a few
|
|
72
|
+
// moments later once the rendering library loaded.
|
|
73
|
+
if (!this.state.texRendererLoaded) {
|
|
74
|
+
const {TeX} = getDependencies();
|
|
75
|
+
return (
|
|
76
|
+
<>
|
|
77
|
+
<CircularSpinner />
|
|
78
|
+
<div style={{display: "none"}}>
|
|
79
|
+
<TeX
|
|
80
|
+
onRender={() => {
|
|
81
|
+
this.setState({texRendererLoaded: true});
|
|
82
|
+
}}
|
|
83
|
+
>
|
|
84
|
+
1
|
|
85
|
+
</TeX>
|
|
86
|
+
</div>
|
|
87
|
+
</>
|
|
88
|
+
);
|
|
70
89
|
}
|
|
71
90
|
|
|
72
91
|
// Use the same random() function to shuffle both columns sequentially
|
|
@@ -123,7 +142,7 @@ class Matcher extends React.Component<any, any> {
|
|
|
123
142
|
<td className={css(styles.column)}>
|
|
124
143
|
<Sortable
|
|
125
144
|
options={left}
|
|
126
|
-
layout=
|
|
145
|
+
layout={Layout.VERTICAL}
|
|
127
146
|
padding={this.props.padding}
|
|
128
147
|
disabled={!this.props.orderMatters}
|
|
129
148
|
constraints={constraints}
|
|
@@ -139,7 +158,7 @@ class Matcher extends React.Component<any, any> {
|
|
|
139
158
|
<Sortable
|
|
140
159
|
// @ts-expect-error [FEI-5003] - TS2322 - Type 'readonly unknown[]' is not assignable to type 'readonly string[]'.
|
|
141
160
|
options={right}
|
|
142
|
-
layout=
|
|
161
|
+
layout={Layout.VERTICAL}
|
|
143
162
|
padding={this.props.padding}
|
|
144
163
|
constraints={constraints}
|
|
145
164
|
onMeasure={this.onMeasureRight}
|
|
@@ -172,10 +191,10 @@ class Matcher extends React.Component<any, any> {
|
|
|
172
191
|
};
|
|
173
192
|
|
|
174
193
|
getUserInput: () => any = () => {
|
|
175
|
-
// If
|
|
176
|
-
// of the sortables on the left and right, so we just return
|
|
177
|
-
// arrays until we render for the first time.
|
|
178
|
-
if (!this.state.
|
|
194
|
+
// If the math renderer hasn't loaded then we won't be able to get the
|
|
195
|
+
// contents of the sortables on the left and right, so we just return
|
|
196
|
+
// empty arrays until we render for the first time.
|
|
197
|
+
if (!this.state.texRendererLoaded) {
|
|
179
198
|
return {
|
|
180
199
|
left: [],
|
|
181
200
|
right: [],
|
|
@@ -192,7 +192,7 @@ const TickMarks: any = Graphie.createSimpleClass((graphie, props) => {
|
|
|
192
192
|
});
|
|
193
193
|
|
|
194
194
|
type Props = ChangeableProps & {
|
|
195
|
-
range:
|
|
195
|
+
range: [number, number];
|
|
196
196
|
labelRange: ReadonlyArray<number | null>;
|
|
197
197
|
labelStyle: string;
|
|
198
198
|
labelTicks: boolean;
|
|
@@ -8,7 +8,6 @@ import _ from "underscore";
|
|
|
8
8
|
|
|
9
9
|
import Graphie from "../components/graphie";
|
|
10
10
|
import InfoTip from "../components/info-tip";
|
|
11
|
-
import MathOutput from "../components/math-output";
|
|
12
11
|
import NumberInput from "../components/number-input";
|
|
13
12
|
import InteractiveUtil from "../interactive2/interactive-util";
|
|
14
13
|
import * as Changeable from "../mixins/changeable";
|
|
@@ -17,6 +16,7 @@ import Util from "../util";
|
|
|
17
16
|
import KhanColors from "../util/colors";
|
|
18
17
|
import KhanMath from "../util/math";
|
|
19
18
|
|
|
19
|
+
import type {Range} from "../perseus-types";
|
|
20
20
|
import type {WidgetExports} from "../types";
|
|
21
21
|
|
|
22
22
|
const {assert} = InteractiveUtil;
|
|
@@ -231,9 +231,7 @@ class Histogram extends React.Component<any, any> {
|
|
|
231
231
|
range: range,
|
|
232
232
|
data: data,
|
|
233
233
|
scale: [
|
|
234
|
-
// @ts-expect-error [FEI-5003] - TS2345 - Argument of type 'any[]' is not assignable to parameter of type 'Coordinates'.
|
|
235
234
|
Util.scaleFromExtent(range[0], this.props.box[0]),
|
|
236
|
-
// @ts-expect-error [FEI-5003] - TS2345 - Argument of type 'any[]' is not assignable to parameter of type 'Coordinates'.
|
|
237
235
|
Util.scaleFromExtent(range[1], this.props.box[1]),
|
|
238
236
|
],
|
|
239
237
|
} as const;
|
|
@@ -352,8 +350,8 @@ class Histogram extends React.Component<any, any> {
|
|
|
352
350
|
};
|
|
353
351
|
|
|
354
352
|
/* Convenience functions that help calculate props based on other props. */
|
|
355
|
-
_range = (props) => {
|
|
356
|
-
const defaultRange = [
|
|
353
|
+
_range = (props): [Range, Range] => {
|
|
354
|
+
const defaultRange: [Range, Range] = [
|
|
357
355
|
[0, 100],
|
|
358
356
|
[-1, 10],
|
|
359
357
|
];
|
|
@@ -361,7 +359,7 @@ class Histogram extends React.Component<any, any> {
|
|
|
361
359
|
return props.data ? this._getRangeForData(props.data) : defaultRange;
|
|
362
360
|
};
|
|
363
361
|
|
|
364
|
-
_getRangeForData = (data: any) => {
|
|
362
|
+
_getRangeForData = (data: any): [Range, Range] => {
|
|
365
363
|
// Find first/last non-zero entry and add some padding
|
|
366
364
|
const padding = 10;
|
|
367
365
|
const firstIndex = _.indexOf(
|
|
@@ -15,11 +15,11 @@
|
|
|
15
15
|
}
|
|
16
16
|
},
|
|
17
17
|
"references": [
|
|
18
|
-
{"path": "../kas"},
|
|
19
|
-
{"path": "../kmath"},
|
|
20
|
-
{"path": "../math-input"},
|
|
21
|
-
{"path": "../perseus-linter"},
|
|
22
|
-
{"path": "../pure-markdown"},
|
|
23
|
-
{"path": "../simple-markdown"},
|
|
18
|
+
{"path": "../kas/tsconfig-build.json"},
|
|
19
|
+
{"path": "../kmath/tsconfig-build.json"},
|
|
20
|
+
{"path": "../math-input/tsconfig-build.json"},
|
|
21
|
+
{"path": "../perseus-linter/tsconfig-build.json"},
|
|
22
|
+
{"path": "../pure-markdown/tsconfig-build.json"},
|
|
23
|
+
{"path": "../simple-markdown/tsconfig-build.json"},
|
|
24
24
|
]
|
|
25
25
|
}
|