@khanacademy/perseus 7.2.1 → 9.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 +47 -0
- package/dist/article-renderer.d.ts +27 -40
- package/dist/components/math-input.d.ts +1 -1
- package/dist/components/sortable.d.ts +1 -1
- package/dist/components/tex-buttons.d.ts +1 -1
- package/dist/dependencies.d.ts +7 -1
- package/dist/es/index.js +1205 -1218
- package/dist/es/index.js.map +1 -1
- package/dist/hints-renderer.d.ts +1 -1
- package/dist/index.js +1207 -1221
- package/dist/index.js.map +1 -1
- package/dist/interaction-tracker.d.ts +3 -3
- package/dist/item-renderer.d.ts +2 -1
- package/dist/mixins/provide-keypad.d.ts +15 -12
- package/dist/multi-items/multi-renderer.d.ts +2 -1
- package/dist/perseus-api.d.ts +2 -2
- package/dist/renderer.d.ts +1 -1
- package/dist/server-item-renderer.d.ts +3 -1
- package/dist/types.d.ts +32 -11
- package/dist/widgets/expression.d.ts +410 -13
- package/dist/widgets/graded-group.d.ts +3 -3
- package/dist/widgets/interactive-graph.d.ts +1 -1
- package/dist/widgets/sequence.d.ts +3 -3
- package/dist/widgets/table.d.ts +8 -1
- package/dist/widgets.d.ts +1 -1
- package/package.json +34 -34
- package/src/__stories__/article-renderer.stories.tsx +35 -2
- package/src/__testdata__/article-renderer.testdata.ts +74 -1
- package/src/__testdata__/item-renderer.testdata.ts +1 -1
- package/src/__testdata__/renderer.testdata.ts +1 -1
- package/src/__tests__/item-renderer.test.tsx +13 -2
- package/src/__tests__/mock-asset-loading-widget.tsx +1 -1
- package/src/__tests__/perseus-markdown.test.ts +17 -17
- package/src/__tests__/renderer-api.test.tsx +21 -21
- package/src/__tests__/renderer.test.tsx +13 -13
- package/src/__tests__/server-item-renderer.test.tsx +12 -4
- package/src/__tests__/tex-wrangler.test.ts +1 -1
- package/src/article-renderer.tsx +75 -66
- package/src/components/__tests__/number-input.test.tsx +4 -4
- package/src/components/__tests__/sortable.test.tsx +2 -2
- package/src/components/fixed-to-responsive.tsx +1 -1
- package/src/components/graph.tsx +11 -11
- package/src/components/graphie-classes.ts +7 -7
- package/src/components/graphie.tsx +14 -14
- package/src/components/highlighting/highlightable-content.tsx +1 -1
- package/src/components/highlighting/ui/highlight-renderer.tsx +1 -1
- package/src/components/highlighting/ui/util.ts +2 -2
- package/src/components/highlighting/word-indexer.tsx +4 -4
- package/src/components/icon.tsx +1 -1
- package/src/components/image-loader.tsx +4 -4
- package/src/components/input-with-examples.tsx +2 -2
- package/src/components/lint.tsx +1 -1
- package/src/components/math-input.tsx +5 -5
- package/src/components/math-output.tsx +1 -1
- package/src/components/multi-button-group.tsx +1 -1
- package/src/components/number-input.tsx +10 -10
- package/src/components/prop-check-box.tsx +1 -1
- package/src/components/simple-keypad-input.tsx +4 -4
- package/src/components/sortable.tsx +42 -41
- package/src/components/svg-image.tsx +12 -12
- package/src/components/tex-buttons.tsx +4 -3
- package/src/components/text-input.tsx +8 -8
- package/src/components/text-list-editor.tsx +11 -11
- package/src/components/visibility-observer/create-visibility-observer.ts +1 -1
- package/src/components/visibility-observer/visibility-observer.tsx +2 -2
- package/src/components/zoomable-tex.tsx +3 -3
- package/src/components/zoomable.tsx +8 -8
- package/src/dependencies.ts +16 -1
- package/src/hint-renderer.tsx +3 -3
- package/src/hints-renderer.tsx +11 -11
- package/src/init.ts +1 -1
- package/src/interaction-tracker.ts +7 -7
- package/src/interactive2/__tests__/movable-point.test.ts +1 -1
- package/src/interactive2/interactive-util.ts +6 -6
- package/src/interactive2/movable-helper-methods.ts +2 -2
- package/src/interactive2/movable-line-options.ts +37 -37
- package/src/interactive2/movable-line.ts +2 -2
- package/src/interactive2/movable-point-options.ts +29 -29
- package/src/interactive2/movable-point.tsx +2 -2
- package/src/interactive2/movable-polygon-options.ts +45 -45
- package/src/interactive2/movable-polygon.ts +2 -2
- package/src/interactive2/movable.ts +2 -2
- package/src/interactive2/objective_.ts +1 -1
- package/src/interactive2/wrapped-defaults.ts +2 -2
- package/src/interactive2/wrapped-ellipse.ts +9 -9
- package/src/interactive2/wrapped-line.ts +8 -8
- package/src/interactive2/wrapped-path.ts +5 -5
- package/src/item-renderer.tsx +66 -48
- package/src/mixins/changeable.ts +2 -2
- package/src/mixins/editor-jsonify.ts +1 -1
- package/src/mixins/provide-keypad.tsx +23 -37
- package/src/mixins/widget-jsonify-deprecated.ts +1 -1
- package/src/multi-items/__tests__/items.test.ts +1 -1
- package/src/multi-items/__tests__/multi-renderer.test.tsx +13 -8
- package/src/multi-items/__tests__/trees.test.ts +12 -12
- package/src/multi-items/item-types.ts +2 -2
- package/src/multi-items/items.ts +1 -1
- package/src/multi-items/multi-renderer.tsx +30 -18
- package/src/multi-items/prop-type-builders.ts +2 -2
- package/src/multi-items/tree-types.ts +4 -4
- package/src/multi-items/trees.ts +16 -16
- package/src/perseus-env.ts +2 -2
- package/src/perseus-markdown.tsx +5 -5
- package/src/renderer.tsx +39 -39
- package/src/server-item-renderer.tsx +26 -21
- package/src/sigfigs.ts +1 -1
- package/src/traversal.ts +1 -1
- package/src/types.ts +52 -16
- package/src/util/answer-types.ts +14 -14
- package/src/util/geometry.ts +7 -7
- package/src/util/graphie.ts +32 -32
- package/src/util/interactive.ts +118 -118
- package/src/util/math.ts +4 -4
- package/src/util/react-render.tsx +1 -1
- package/src/util/scroll-utils.ts +2 -2
- package/src/util/tex.ts +3 -3
- package/src/util.ts +15 -15
- package/src/widget-container.tsx +1 -1
- package/src/widgets/__stories__/definition.stories.tsx +8 -1
- package/src/widgets/__stories__/expression.stories.tsx +2 -2
- package/src/widgets/__stories__/test-keypad-context-wrapper.tsx +3 -3
- package/src/widgets/__testdata__/numeric-input.testdata.ts +1 -1
- package/src/widgets/__tests__/__snapshots__/video.test.ts.snap +2 -2
- package/src/widgets/__tests__/{expression.test.ts → expression.test.tsx} +77 -11
- package/src/widgets/__tests__/grapher.cypress.ts +32 -32
- package/src/widgets/__tests__/group.test.tsx +1 -1
- package/src/widgets/__tests__/interactive-graph.cypress.ts +40 -40
- package/src/widgets/__tests__/interactive-graph.test.ts +1 -1
- package/src/widgets/__tests__/numeric-input.test.ts +1 -1
- package/src/widgets/__tests__/passage.test.tsx +2 -2
- package/src/widgets/__tests__/plotter.test.tsx +2 -1
- package/src/widgets/__tests__/radio/base-radio.test.tsx +7 -7
- package/src/widgets/__tests__/renderQuestion.tsx +29 -21
- package/src/widgets/categorizer.tsx +4 -4
- package/src/widgets/cs-program.tsx +2 -2
- package/src/widgets/dropdown.tsx +1 -1
- package/src/widgets/expression.tsx +92 -57
- package/src/widgets/graded-group-set.tsx +5 -5
- package/src/widgets/graded-group.tsx +29 -21
- package/src/widgets/grapher/util.tsx +6 -6
- package/src/widgets/grapher.tsx +10 -10
- package/src/widgets/group.tsx +3 -3
- package/src/widgets/iframe.tsx +2 -2
- package/src/widgets/image.tsx +1 -1
- package/src/widgets/input-number.tsx +4 -4
- package/src/widgets/interaction.tsx +77 -77
- package/src/widgets/interactive-graph.tsx +109 -107
- package/src/widgets/label-image/marker.tsx +2 -2
- package/src/widgets/label-image.test.ts +1 -1
- package/src/widgets/label-image.tsx +7 -7
- package/src/widgets/lights-puzzle.tsx +2 -2
- package/src/widgets/matcher.tsx +6 -6
- package/src/widgets/matrix.tsx +20 -20
- package/src/widgets/measurer.tsx +3 -3
- package/src/widgets/molecule/__tests__/layout.test.ts +4 -4
- package/src/widgets/molecule/__tests__/parser.test.ts +14 -14
- package/src/widgets/molecule/smiles-parser.ts +3 -3
- package/src/widgets/molecule.tsx +4 -4
- package/src/widgets/number-line.tsx +11 -11
- package/src/widgets/numeric-input.tsx +11 -11
- package/src/widgets/orderer.tsx +38 -38
- package/src/widgets/passage/__tests__/passage-markdown.test.ts +1 -1
- package/src/widgets/passage/passage-markdown.tsx +4 -4
- package/src/widgets/passage-ref-target.tsx +1 -1
- package/src/widgets/passage-ref.tsx +4 -6
- package/src/widgets/passage.tsx +11 -11
- package/src/widgets/plotter.tsx +9 -9
- package/src/widgets/radio/base-radio.tsx +11 -11
- package/src/widgets/radio/choice-icon/choice-icon.tsx +2 -2
- package/src/widgets/radio/choice.tsx +1 -1
- package/src/widgets/radio/option-status.tsx +1 -1
- package/src/widgets/radio/widget.tsx +6 -6
- package/src/widgets/radio.ts +1 -1
- package/src/widgets/reaction-diagram.tsx +8 -8
- package/src/widgets/sequence.tsx +12 -4
- package/src/widgets/simulator.tsx +14 -14
- package/src/widgets/sorter.tsx +4 -4
- package/src/widgets/table.tsx +8 -8
- package/src/widgets/transformer.tsx +92 -92
- package/src/widgets/unit.tsx +17 -17
- package/src/widgets/video-transcript-link.test.tsx +3 -3
- package/src/widgets/video-transcript-link.tsx +1 -1
- package/src/widgets/video.tsx +1 -1
- package/src/widgets.ts +5 -5
- package/src/zoom.ts +22 -22
- package/tsconfig-build.tsbuildinfo +1 -1
- package/dist/a11y.js.flow +0 -11
- package/dist/all-widgets.js.flow +0 -33
- package/dist/article-renderer.js.flow +0 -73
- package/dist/asset-context.js.flow +0 -15
- package/dist/basic-widgets.js.flow +0 -33
- package/dist/components/button-group.js.flow +0 -33
- package/dist/components/constants.js.flow +0 -13
- package/dist/components/fixed-to-responsive.js.flow +0 -34
- package/dist/components/graph.js.flow +0 -66
- package/dist/components/graphie-classes.js.flow +0 -19
- package/dist/components/graphie-movables.js.flow +0 -22
- package/dist/components/graphie.js.flow +0 -69
- package/dist/components/highlighting/highlightable-content.js.flow +0 -56
- package/dist/components/highlighting/highlights.js.flow +0 -54
- package/dist/components/highlighting/ranges.js.flow +0 -60
- package/dist/components/highlighting/types.js.flow +0 -70
- package/dist/components/highlighting/ui/highlight-renderer.js.flow +0 -43
- package/dist/components/highlighting/ui/highlight-set-renderer.js.flow +0 -41
- package/dist/components/highlighting/ui/highlight-tooltip.js.flow +0 -22
- package/dist/components/highlighting/ui/highlighting-ui.js.flow +0 -30
- package/dist/components/highlighting/ui/selection-tracker.js.flow +0 -54
- package/dist/components/highlighting/ui/types.js.flow +0 -22
- package/dist/components/highlighting/ui/util.js.flow +0 -42
- package/dist/components/highlighting/word-indexer.js.flow +0 -21
- package/dist/components/hud.js.flow +0 -14
- package/dist/components/icon.js.flow +0 -31
- package/dist/components/image-loader.js.flow +0 -49
- package/dist/components/info-tip/info-tip.js.flow +0 -20
- package/dist/components/info-tip.js.flow +0 -18
- package/dist/components/inline-icon.js.flow +0 -39
- package/dist/components/input-with-examples.js.flow +0 -58
- package/dist/components/lint.js.flow +0 -58
- package/dist/components/math-input.js.flow +0 -49
- package/dist/components/math-output.js.flow +0 -33
- package/dist/components/multi-button-group.js.flow +0 -35
- package/dist/components/number-input.js.flow +0 -42
- package/dist/components/prop-check-box.js.flow +0 -8
- package/dist/components/range-input.js.flow +0 -20
- package/dist/components/simple-keypad-input.js.flow +0 -16
- package/dist/components/sortable.js.flow +0 -91
- package/dist/components/stub-tag-editor.js.flow +0 -18
- package/dist/components/svg-image.js.flow +0 -85
- package/dist/components/tex-buttons.js.flow +0 -26
- package/dist/components/tex.js.flow +0 -25
- package/dist/components/text-input.js.flow +0 -39
- package/dist/components/text-list-editor.js.flow +0 -22
- package/dist/components/tooltip.js.flow +0 -51
- package/dist/components/visibility-observer/create-visibility-observer.js.flow +0 -23
- package/dist/components/visibility-observer/get-scroll-parent.js.flow +0 -7
- package/dist/components/visibility-observer/visibility-observer.js.flow +0 -36
- package/dist/components/zoomable-tex.js.flow +0 -18
- package/dist/components/zoomable.js.flow +0 -70
- package/dist/components.js.flow +0 -22
- package/dist/definition-context.js.flow +0 -25
- package/dist/dependencies.js.flow +0 -9
- package/dist/error-boundary.js.flow +0 -19
- package/dist/extra-widgets.js.flow +0 -33
- package/dist/hint-renderer.js.flow +0 -32
- package/dist/hints-renderer.js.flow +0 -41
- package/dist/icon-paths.js.flow +0 -123
- package/dist/index.js.flow +0 -134
- package/dist/init.js.flow +0 -20
- package/dist/interaction-tracker.js.flow +0 -35
- package/dist/interactive2/interactive-util.js.flow +0 -50
- package/dist/interactive2/movable-helper-methods.js.flow +0 -15
- package/dist/interactive2/movable-line-options.js.flow +0 -44
- package/dist/interactive2/movable-line.js.flow +0 -8
- package/dist/interactive2/movable-point-options.js.flow +0 -44
- package/dist/interactive2/movable-point.js.flow +0 -8
- package/dist/interactive2/movable-polygon-options.js.flow +0 -47
- package/dist/interactive2/movable-polygon.js.flow +0 -8
- package/dist/interactive2/movable.js.flow +0 -8
- package/dist/interactive2/objective_.js.flow +0 -25
- package/dist/interactive2/types.js.flow +0 -8
- package/dist/interactive2/wrapped-defaults.js.flow +0 -11
- package/dist/interactive2/wrapped-ellipse.js.flow +0 -14
- package/dist/interactive2/wrapped-line.js.flow +0 -14
- package/dist/interactive2/wrapped-path.js.flow +0 -13
- package/dist/interactive2.js.flow +0 -16
- package/dist/item-renderer.js.flow +0 -132
- package/dist/item-version.js.flow +0 -11
- package/dist/jipt-paragraphs.js.flow +0 -14
- package/dist/loading-context.js.flow +0 -12
- package/dist/logging/log.js.flow +0 -62
- package/dist/mixins/changeable.js.flow +0 -33
- package/dist/mixins/editor-jsonify.js.flow +0 -10
- package/dist/mixins/provide-keypad.js.flow +0 -33
- package/dist/mixins/widget-jsonify-deprecated.js.flow +0 -11
- package/dist/mixins/widget-prop-denylist.js.flow +0 -20
- package/dist/multi-items/item-types.js.flow +0 -55
- package/dist/multi-items/items.js.flow +0 -66
- package/dist/multi-items/multi-renderer.js.flow +0 -213
- package/dist/multi-items/prop-type-builders.js.flow +0 -22
- package/dist/multi-items/shape-types.js.flow +0 -60
- package/dist/multi-items/shapes.js.flow +0 -25
- package/dist/multi-items/tree-types.js.flow +0 -45
- package/dist/multi-items/trees.js.flow +0 -147
- package/dist/multi-items.js.flow +0 -36
- package/dist/perseus-api.js.flow +0 -151
- package/dist/perseus-env.js.flow +0 -6
- package/dist/perseus-error.js.flow +0 -16
- package/dist/perseus-markdown.js.flow +0 -20
- package/dist/perseus-types.js.flow +0 -1041
- package/dist/question-paragraph.js.flow +0 -17
- package/dist/renderability.js.flow +0 -19
- package/dist/renderer.js.flow +0 -325
- package/dist/server-item-renderer.js.flow +0 -132
- package/dist/sigfigs.js.flow +0 -41
- package/dist/styles/constants.js.flow +0 -62
- package/dist/styles/global-constants.js.flow +0 -348
- package/dist/styles/global-styles.js.flow +0 -53
- package/dist/styles/media-queries.js.flow +0 -35
- package/dist/styles/shared.js.flow +0 -8
- package/dist/tex-wrangler.js.flow +0 -13
- package/dist/translation-linter.js.flow +0 -32
- package/dist/traversal.js.flow +0 -26
- package/dist/types.js.flow +0 -318
- package/dist/util/a11y.js.flow +0 -8
- package/dist/util/answer-types.js.flow +0 -49
- package/dist/util/colors.js.flow +0 -95
- package/dist/util/fix-passage-refs.js.flow +0 -8
- package/dist/util/geometry.js.flow +0 -37
- package/dist/util/graph-utils.js.flow +0 -9
- package/dist/util/graphie.js.flow +0 -8
- package/dist/util/interactive.js.flow +0 -11
- package/dist/util/katex-preprocess.js.flow +0 -12
- package/dist/util/math.js.flow +0 -62
- package/dist/util/mobile-native-utils.js.flow +0 -12
- package/dist/util/react-render.js.flow +0 -12
- package/dist/util/register-all-widgets-for-testing.js.flow +0 -7
- package/dist/util/scroll-utils.js.flow +0 -19
- package/dist/util/sizing-utils.js.flow +0 -20
- package/dist/util/tex.js.flow +0 -17
- package/dist/util/url-utils.js.flow +0 -11
- package/dist/util.graphie.js.flow +0 -14
- package/dist/util.js.flow +0 -319
- package/dist/version.js.flow +0 -17
- package/dist/widget-container.js.flow +0 -33
- package/dist/widgets/categorizer.js.flow +0 -70
- package/dist/widgets/cs-program.js.flow +0 -54
- package/dist/widgets/definition.js.flow +0 -57
- package/dist/widgets/dropdown.js.flow +0 -63
- package/dist/widgets/explanation.js.flow +0 -58
- package/dist/widgets/expression.js.flow +0 -116
- package/dist/widgets/graded-group-answer-bar.js.flow +0 -24
- package/dist/widgets/graded-group-set.js.flow +0 -65
- package/dist/widgets/graded-group.js.flow +0 -78
- package/dist/widgets/grapher/util.js.flow +0 -38
- package/dist/widgets/grapher.js.flow +0 -102
- package/dist/widgets/group.js.flow +0 -60
- package/dist/widgets/iframe.js.flow +0 -53
- package/dist/widgets/image.js.flow +0 -73
- package/dist/widgets/input-number.js.flow +0 -94
- package/dist/widgets/interaction/arrow-picker.js.flow +0 -21
- package/dist/widgets/interaction/color-picker.js.flow +0 -23
- package/dist/widgets/interaction/dash-picker.js.flow +0 -21
- package/dist/widgets/interaction/element-container.js.flow +0 -28
- package/dist/widgets/interaction.js.flow +0 -60
- package/dist/widgets/interactive-graph.js.flow +0 -239
- package/dist/widgets/label-image/answer-choices.js.flow +0 -55
- package/dist/widgets/label-image/marker.js.flow +0 -31
- package/dist/widgets/label-image/types.js.flow +0 -23
- package/dist/widgets/label-image.js.flow +0 -142
- package/dist/widgets/lights-puzzle.js.flow +0 -58
- package/dist/widgets/matcher.js.flow +0 -106
- package/dist/widgets/matrix.js.flow +0 -80
- package/dist/widgets/measurer.js.flow +0 -30
- package/dist/widgets/molecule/molecule-drawing.js.flow +0 -11
- package/dist/widgets/molecule/molecule-layout.js.flow +0 -96
- package/dist/widgets/molecule/smiles-parser.js.flow +0 -26
- package/dist/widgets/molecule.js.flow +0 -60
- package/dist/widgets/number-line.js.flow +0 -102
- package/dist/widgets/numeric-input.js.flow +0 -105
- package/dist/widgets/orderer.js.flow +0 -81
- package/dist/widgets/passage/passage-markdown.js.flow +0 -33
- package/dist/widgets/passage-ref-target.js.flow +0 -52
- package/dist/widgets/passage-ref.js.flow +0 -85
- package/dist/widgets/passage.js.flow +0 -157
- package/dist/widgets/plotter.js.flow +0 -112
- package/dist/widgets/radio/base-radio.js.flow +0 -50
- package/dist/widgets/radio/choice-a11y-text.js.flow +0 -14
- package/dist/widgets/radio/choice-icon/choice-icon.js.flow +0 -22
- package/dist/widgets/radio/choice-icon/cross-out-line.js.flow +0 -16
- package/dist/widgets/radio/choice-icon/shared-styles.js.flow +0 -11
- package/dist/widgets/radio/choice-none-above.js.flow +0 -16
- package/dist/widgets/radio/choice.js.flow +0 -29
- package/dist/widgets/radio/choice.jsx.fixture.js.flow +0 -7
- package/dist/widgets/radio/focus-ring.js.flow +0 -22
- package/dist/widgets/radio/option-status.js.flow +0 -16
- package/dist/widgets/radio/util.js.flow +0 -12
- package/dist/widgets/radio/widget.js.flow +0 -80
- package/dist/widgets/radio.js.flow +0 -31
- package/dist/widgets/reaction-diagram.js.flow +0 -46
- package/dist/widgets/sequence.js.flow +0 -53
- package/dist/widgets/simulator.js.flow +0 -107
- package/dist/widgets/sorter.js.flow +0 -102
- package/dist/widgets/table.js.flow +0 -67
- package/dist/widgets/transformer.js.flow +0 -127
- package/dist/widgets/unit.js.flow +0 -93
- package/dist/widgets/video-transcript-link.js.flow +0 -15
- package/dist/widgets/video.js.flow +0 -57
- package/dist/widgets.js.flow +0 -108
- package/dist/zoom.js.flow +0 -7
- package/src/multi-items/item-types.js.flow +0 -55
|
@@ -143,7 +143,7 @@ describe("passage widget", () => {
|
|
|
143
143
|
const {renderer} = renderQuestion(question2, apiOptions);
|
|
144
144
|
jest.runOnlyPendingTimers();
|
|
145
145
|
|
|
146
|
-
// @ts-expect-error
|
|
146
|
+
// @ts-expect-error - TS2503 - Cannot find namespace 'PassageWidgetExport'
|
|
147
147
|
const [passage1]: [PassageWidgetExport.widget] =
|
|
148
148
|
renderer.findWidgets("passage 1");
|
|
149
149
|
|
|
@@ -167,7 +167,7 @@ describe("passage widget", () => {
|
|
|
167
167
|
const {renderer} = renderQuestion(question2, apiOptions);
|
|
168
168
|
jest.runOnlyPendingTimers();
|
|
169
169
|
|
|
170
|
-
// @ts-expect-error
|
|
170
|
+
// @ts-expect-error - TS2503 - Cannot find namespace 'PassageWidgetExport'
|
|
171
171
|
const [passage1]: [PassageWidgetExport.widget] =
|
|
172
172
|
renderer.findWidgets("passage 1");
|
|
173
173
|
|
|
@@ -4,12 +4,13 @@ import React from "react";
|
|
|
4
4
|
|
|
5
5
|
import {testDependencies} from "../../../../../testing/test-dependencies";
|
|
6
6
|
import {setDependencies} from "../../dependencies";
|
|
7
|
-
import {APIOptions} from "../../types";
|
|
8
7
|
import {question1} from "../__testdata__/plotter.testdata";
|
|
9
8
|
import {Plotter} from "../plotter";
|
|
10
9
|
|
|
11
10
|
import {renderQuestion} from "./renderQuestion";
|
|
12
11
|
|
|
12
|
+
import type {APIOptions} from "../../types";
|
|
13
|
+
|
|
13
14
|
describe("plotter widget", () => {
|
|
14
15
|
beforeEach(() => {
|
|
15
16
|
setDependencies(testDependencies);
|
|
@@ -87,7 +87,7 @@ describe("base-radio", () => {
|
|
|
87
87
|
checked: ReadonlyArray<boolean>;
|
|
88
88
|
crossedOut: ReadonlyArray<boolean>;
|
|
89
89
|
}) => {
|
|
90
|
-
// @ts-expect-error
|
|
90
|
+
// @ts-expect-error - TS2322 - Type '{ checked: readonly boolean[]; crossedOut: readonly boolean[]; }' is not assignable to type 'null'.
|
|
91
91
|
updatedValues = newValues;
|
|
92
92
|
};
|
|
93
93
|
|
|
@@ -142,7 +142,7 @@ describe("base-radio", () => {
|
|
|
142
142
|
checked: ReadonlyArray<boolean>;
|
|
143
143
|
crossedOut: ReadonlyArray<boolean>;
|
|
144
144
|
}) => {
|
|
145
|
-
// @ts-expect-error
|
|
145
|
+
// @ts-expect-error - TS2322 - Type '{ checked: readonly boolean[]; crossedOut: readonly boolean[]; }' is not assignable to type 'null'.
|
|
146
146
|
updatedValues = newValues;
|
|
147
147
|
};
|
|
148
148
|
|
|
@@ -173,7 +173,7 @@ describe("base-radio", () => {
|
|
|
173
173
|
checked: ReadonlyArray<boolean>;
|
|
174
174
|
crossedOut: ReadonlyArray<boolean>;
|
|
175
175
|
}) => {
|
|
176
|
-
// @ts-expect-error
|
|
176
|
+
// @ts-expect-error - TS2322 - Type '{ checked: readonly boolean[]; crossedOut: readonly boolean[]; }' is not assignable to type 'null'.
|
|
177
177
|
updatedValues = newValues;
|
|
178
178
|
};
|
|
179
179
|
|
|
@@ -208,7 +208,7 @@ describe("base-radio", () => {
|
|
|
208
208
|
checked: ReadonlyArray<boolean>;
|
|
209
209
|
crossedOut: ReadonlyArray<boolean>;
|
|
210
210
|
}) => {
|
|
211
|
-
// @ts-expect-error
|
|
211
|
+
// @ts-expect-error - TS2322 - Type '{ checked: readonly boolean[]; crossedOut: readonly boolean[]; }' is not assignable to type 'null'.
|
|
212
212
|
updatedValues = newValues;
|
|
213
213
|
};
|
|
214
214
|
|
|
@@ -259,7 +259,7 @@ describe("base-radio", () => {
|
|
|
259
259
|
checked: ReadonlyArray<boolean>;
|
|
260
260
|
crossedOut: ReadonlyArray<boolean>;
|
|
261
261
|
}) => {
|
|
262
|
-
// @ts-expect-error
|
|
262
|
+
// @ts-expect-error - TS2322 - Type '{ checked: readonly boolean[]; crossedOut: readonly boolean[]; }' is not assignable to type 'null'.
|
|
263
263
|
updatedValues = newValues;
|
|
264
264
|
};
|
|
265
265
|
|
|
@@ -308,7 +308,7 @@ describe("base-radio", () => {
|
|
|
308
308
|
checked: ReadonlyArray<boolean>;
|
|
309
309
|
crossedOut: ReadonlyArray<boolean>;
|
|
310
310
|
}) => {
|
|
311
|
-
// @ts-expect-error
|
|
311
|
+
// @ts-expect-error - TS2322 - Type '{ checked: readonly boolean[]; crossedOut: readonly boolean[]; }' is not assignable to type 'null'.
|
|
312
312
|
updatedValues = newValues;
|
|
313
313
|
};
|
|
314
314
|
|
|
@@ -358,7 +358,7 @@ describe("base-radio", () => {
|
|
|
358
358
|
checked: ReadonlyArray<boolean>;
|
|
359
359
|
crossedOut: ReadonlyArray<boolean>;
|
|
360
360
|
}) => {
|
|
361
|
-
// @ts-expect-error
|
|
361
|
+
// @ts-expect-error - TS2322 - Type '{ checked: readonly boolean[]; crossedOut: readonly boolean[]; }' is not assignable to type 'null'.
|
|
362
362
|
updatedValues = newValues;
|
|
363
363
|
};
|
|
364
364
|
|
|
@@ -2,6 +2,9 @@ import {RenderStateRoot} from "@khanacademy/wonder-blocks-core";
|
|
|
2
2
|
import {render} from "@testing-library/react";
|
|
3
3
|
import * as React from "react";
|
|
4
4
|
|
|
5
|
+
// eslint-disable-next-line import/no-relative-packages
|
|
6
|
+
import {testDependenciesV2} from "../../../../../testing/test-dependencies";
|
|
7
|
+
import {DependenciesContext} from "../../dependencies";
|
|
5
8
|
import * as Perseus from "../../index";
|
|
6
9
|
import {registerAllWidgetsForTesting} from "../../util/register-all-widgets-for-testing";
|
|
7
10
|
|
|
@@ -15,7 +18,7 @@ export const renderQuestion = (
|
|
|
15
18
|
apiOptions: APIOptions = Object.freeze({}),
|
|
16
19
|
extraProps?: JSX.LibraryManagedAttributes<
|
|
17
20
|
typeof Perseus.Renderer,
|
|
18
|
-
// @ts-expect-error
|
|
21
|
+
// @ts-expect-error - TS2344 - Type 'typeof Renderer' does not satisfy the constraint 'keyof IntrinsicElements | JSXElementConstructor<any>'.
|
|
19
22
|
React.ComponentProps<typeof Perseus.Renderer>
|
|
20
23
|
>,
|
|
21
24
|
): {
|
|
@@ -25,25 +28,28 @@ export const renderQuestion = (
|
|
|
25
28
|
question: PerseusRenderer,
|
|
26
29
|
extraProps?: JSX.LibraryManagedAttributes<
|
|
27
30
|
typeof Perseus.Renderer,
|
|
28
|
-
// @ts-expect-error
|
|
31
|
+
// @ts-expect-error - TS2344 - Type 'typeof Renderer' does not satisfy the constraint 'keyof IntrinsicElements | JSXElementConstructor<any>'.
|
|
29
32
|
React.ComponentProps<typeof Perseus.Renderer>
|
|
30
33
|
>,
|
|
31
34
|
) => void;
|
|
32
35
|
unmount: RenderResult["unmount"];
|
|
33
36
|
} => {
|
|
34
37
|
registerAllWidgetsForTesting();
|
|
38
|
+
|
|
35
39
|
let renderer: Perseus.Renderer | null = null;
|
|
36
40
|
const {container, rerender, unmount} = render(
|
|
37
41
|
<RenderStateRoot>
|
|
38
|
-
<
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
42
|
+
<DependenciesContext.Provider value={testDependenciesV2}>
|
|
43
|
+
<Perseus.Renderer
|
|
44
|
+
ref={(node) => (renderer = node)}
|
|
45
|
+
content={question.content}
|
|
46
|
+
images={question.images}
|
|
47
|
+
widgets={question.widgets}
|
|
48
|
+
problemNum={0}
|
|
49
|
+
apiOptions={apiOptions}
|
|
50
|
+
{...extraProps}
|
|
51
|
+
/>
|
|
52
|
+
</DependenciesContext.Provider>
|
|
47
53
|
</RenderStateRoot>,
|
|
48
54
|
);
|
|
49
55
|
if (!renderer) {
|
|
@@ -51,20 +57,22 @@ export const renderQuestion = (
|
|
|
51
57
|
}
|
|
52
58
|
const renderAgain = (
|
|
53
59
|
question: PerseusRenderer,
|
|
54
|
-
// @ts-expect-error
|
|
60
|
+
// @ts-expect-error - TS2344 - Type 'typeof Renderer' does not satisfy the constraint 'keyof IntrinsicElements | JSXElementConstructor<any>'.
|
|
55
61
|
extraProps: undefined | React.ComponentProps<typeof Perseus.Renderer>,
|
|
56
62
|
) => {
|
|
57
63
|
rerender(
|
|
58
64
|
<RenderStateRoot>
|
|
59
|
-
<
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
65
|
+
<DependenciesContext.Provider value={testDependenciesV2}>
|
|
66
|
+
<Perseus.Renderer
|
|
67
|
+
ref={(node) => (renderer = node)}
|
|
68
|
+
content={question.content}
|
|
69
|
+
images={question.images}
|
|
70
|
+
widgets={question.widgets}
|
|
71
|
+
problemNum={0}
|
|
72
|
+
apiOptions={apiOptions}
|
|
73
|
+
{...extraProps}
|
|
74
|
+
/>
|
|
75
|
+
</DependenciesContext.Provider>
|
|
68
76
|
</RenderStateRoot>,
|
|
69
77
|
);
|
|
70
78
|
if (!renderer) {
|
|
@@ -52,7 +52,7 @@ export class Categorizer extends React.Component<Props, State> {
|
|
|
52
52
|
};
|
|
53
53
|
|
|
54
54
|
change: (...args: ReadonlyArray<unknown>) => any = (...args) => {
|
|
55
|
-
// @ts-expect-error
|
|
55
|
+
// @ts-expect-error - TS2345 - Argument of type 'readonly unknown[]' is not assignable to parameter of type 'any[]'.
|
|
56
56
|
return Changeable.change.apply(this, args);
|
|
57
57
|
};
|
|
58
58
|
|
|
@@ -68,7 +68,7 @@ export class Categorizer extends React.Component<Props, State> {
|
|
|
68
68
|
const isMobile = this.props.apiOptions.isMobile;
|
|
69
69
|
let indexedItems = this.props.items.map((item, n) => [item, n]);
|
|
70
70
|
if (this.props.randomizeItems) {
|
|
71
|
-
// @ts-expect-error
|
|
71
|
+
// @ts-expect-error - TS4104 - The type 'readonly (string | number)[][]' is 'readonly' and cannot be assigned to the mutable type '(string | number)[][]'. | TS2345 - Argument of type 'number | null | undefined' is not assignable to parameter of type 'number | RNG'.
|
|
72
72
|
indexedItems = Util.shuffle(indexedItems, this.props.problemNum);
|
|
73
73
|
}
|
|
74
74
|
|
|
@@ -103,7 +103,7 @@ export class Categorizer extends React.Component<Props, State> {
|
|
|
103
103
|
<tr key={itemNum}>
|
|
104
104
|
<td>
|
|
105
105
|
<Renderer
|
|
106
|
-
// @ts-expect-error
|
|
106
|
+
// @ts-expect-error - TS2322 - Type 'string | number' is not assignable to type 'string | undefined'.
|
|
107
107
|
content={item}
|
|
108
108
|
linterContext={this.props.linterContext}
|
|
109
109
|
/>
|
|
@@ -212,7 +212,7 @@ export class Categorizer extends React.Component<Props, State> {
|
|
|
212
212
|
|
|
213
213
|
onChange: (arg1: number, arg2: number) => void = (itemNum, catNum) => {
|
|
214
214
|
const values = [...this.props.values];
|
|
215
|
-
// @ts-expect-error
|
|
215
|
+
// @ts-expect-error - TS2322 - Type 'number' is not assignable to type 'never'.
|
|
216
216
|
values[itemNum] = catNum;
|
|
217
217
|
this.change("values", values);
|
|
218
218
|
this.props.trackInteraction();
|
|
@@ -117,7 +117,7 @@ class CSProgram extends React.Component<any> {
|
|
|
117
117
|
};
|
|
118
118
|
|
|
119
119
|
change: (...args: ReadonlyArray<unknown>) => any = (...args) => {
|
|
120
|
-
// @ts-expect-error
|
|
120
|
+
// @ts-expect-error - TS2345 - Argument of type 'readonly unknown[]' is not assignable to parameter of type 'any[]'.
|
|
121
121
|
return Changeable.change.apply(this, args);
|
|
122
122
|
};
|
|
123
123
|
|
|
@@ -159,7 +159,7 @@ class CSProgram extends React.Component<any> {
|
|
|
159
159
|
url += "&buttons=yes";
|
|
160
160
|
// Matches templates/scratchpads/embed_script.js
|
|
161
161
|
// Toolbar height is 66, border height is 1 pixel
|
|
162
|
-
// @ts-expect-error
|
|
162
|
+
// @ts-expect-error - TS2540 - Cannot assign to 'height' because it is a read-only property.
|
|
163
163
|
style.height += 67;
|
|
164
164
|
} else {
|
|
165
165
|
url += "&buttons=no";
|
package/src/widgets/dropdown.tsx
CHANGED
|
@@ -53,7 +53,7 @@ class Dropdown extends React.Component<Props> {
|
|
|
53
53
|
// TODO(LP-10797): This focus() call doesn't do anything because our
|
|
54
54
|
// root element is a <div> and that cannot be focused without a
|
|
55
55
|
// tabIndex.
|
|
56
|
-
// @ts-expect-error
|
|
56
|
+
// @ts-expect-error - TS2531 - Object is possibly 'null'. | TS2339 - Property 'focus' does not exist on type 'Element | Text'.
|
|
57
57
|
ReactDOM.findDOMNode(this).focus();
|
|
58
58
|
return true;
|
|
59
59
|
};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as KAS from "@khanacademy/kas";
|
|
2
|
-
import {KeypadInput, KeypadType
|
|
2
|
+
import {KeypadInput, KeypadType} from "@khanacademy/math-input";
|
|
3
3
|
import {linterContextDefault} from "@khanacademy/perseus-linter";
|
|
4
4
|
import * as i18n from "@khanacademy/wonder-blocks-i18n";
|
|
5
5
|
import classNames from "classnames";
|
|
@@ -12,7 +12,7 @@ import Tooltip, {
|
|
|
12
12
|
HorizontalDirection,
|
|
13
13
|
VerticalDirection,
|
|
14
14
|
} from "../components/tooltip";
|
|
15
|
-
import {
|
|
15
|
+
import {useDependencies} from "../dependencies";
|
|
16
16
|
import {iconExclamationSign} from "../icon-paths";
|
|
17
17
|
import {Errors as PerseusErrors, Log} from "../logging/log";
|
|
18
18
|
import * as Changeable from "../mixins/changeable";
|
|
@@ -23,18 +23,13 @@ import type {
|
|
|
23
23
|
PerseusExpressionWidgetOptions,
|
|
24
24
|
PerseusExpressionAnswerForm,
|
|
25
25
|
} from "../perseus-types";
|
|
26
|
-
import type {
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
payload: {
|
|
34
|
-
result,
|
|
35
|
-
},
|
|
36
|
-
});
|
|
37
|
-
};
|
|
26
|
+
import type {
|
|
27
|
+
APIOptions,
|
|
28
|
+
PerseusScore,
|
|
29
|
+
WidgetExports,
|
|
30
|
+
WidgetProps,
|
|
31
|
+
} from "../types";
|
|
32
|
+
import type {Keys as Key} from "@khanacademy/math-input";
|
|
38
33
|
|
|
39
34
|
type InputPath = ReadonlyArray<string>;
|
|
40
35
|
|
|
@@ -62,20 +57,43 @@ const insertBraces = (value) => {
|
|
|
62
57
|
return value.replace(/([_^])([^{])/g, "$1{$2}");
|
|
63
58
|
};
|
|
64
59
|
|
|
60
|
+
const deriveKeypadVersion = (apiOptions: APIOptions) => {
|
|
61
|
+
// We can derive which version of the keypad is in use. This is
|
|
62
|
+
// a bit tricky, but this code will be relatively short-lived
|
|
63
|
+
// as we coalesce onto the new, v2 Keypad, at which point we
|
|
64
|
+
// can remove this `virtualKeypadVersion` field entirely.
|
|
65
|
+
return apiOptions.nativeKeypadProxy != null
|
|
66
|
+
? "REACT_NATIVE_KEYPAD"
|
|
67
|
+
: apiOptions.customKeypad === true
|
|
68
|
+
? apiOptions.useV2Keypad === true
|
|
69
|
+
? "MATH_INPUT_KEYPAD_V2"
|
|
70
|
+
: "MATH_INPUT_KEYPAD_V1"
|
|
71
|
+
: "PERSEUS_MATH_INPUT";
|
|
72
|
+
};
|
|
73
|
+
|
|
65
74
|
type Rubric = PerseusExpressionWidgetOptions;
|
|
66
75
|
|
|
76
|
+
type RenderProps = {
|
|
77
|
+
buttonSets: PerseusExpressionWidgetOptions["buttonSets"];
|
|
78
|
+
buttonsVisible?: PerseusExpressionWidgetOptions["buttonsVisible"];
|
|
79
|
+
functions: PerseusExpressionWidgetOptions["functions"];
|
|
80
|
+
times: PerseusExpressionWidgetOptions["times"];
|
|
81
|
+
keypadConfiguration: ReturnType<typeof keypadConfigurationForProps>;
|
|
82
|
+
};
|
|
83
|
+
|
|
67
84
|
type ExternalProps = WidgetProps<RenderProps, Rubric>;
|
|
68
85
|
|
|
69
|
-
export type Props = ExternalProps &
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
86
|
+
export type Props = ExternalProps &
|
|
87
|
+
ReturnType<typeof useDependencies> & {
|
|
88
|
+
apiOptions: NonNullable<ExternalProps["apiOptions"]>;
|
|
89
|
+
buttonSets: NonNullable<ExternalProps["buttonSets"]>;
|
|
90
|
+
functions: NonNullable<ExternalProps["functions"]>;
|
|
91
|
+
linterContext: NonNullable<ExternalProps["linterContext"]>;
|
|
92
|
+
onBlur: NonNullable<ExternalProps["onBlur"]>;
|
|
93
|
+
onFocus: NonNullable<ExternalProps["onFocus"]>;
|
|
94
|
+
times: NonNullable<ExternalProps["times"]>;
|
|
95
|
+
value: string;
|
|
96
|
+
};
|
|
79
97
|
|
|
80
98
|
export type ExpressionState = {
|
|
81
99
|
showErrorTooltip: boolean;
|
|
@@ -126,7 +144,7 @@ export class Expression extends React.Component<Props, ExpressionState> {
|
|
|
126
144
|
static validate(
|
|
127
145
|
userInput: string,
|
|
128
146
|
rubric: Rubric,
|
|
129
|
-
// @ts-expect-error
|
|
147
|
+
// @ts-expect-error - TS2322 - Type '() => void' is not assignable to type 'OnInputErrorFunctionType'.
|
|
130
148
|
onInputError: OnInputErrorFunctionType = function () {},
|
|
131
149
|
): PerseusScore {
|
|
132
150
|
const options = _.clone(rubric);
|
|
@@ -210,8 +228,6 @@ export class Expression extends React.Component<Props, ExpressionState> {
|
|
|
210
228
|
// we did, whether it's considered correct, incorrect, or ungraded
|
|
211
229
|
if (!matchingAnswerForm) {
|
|
212
230
|
if (firstUngradedResult) {
|
|
213
|
-
sendExpressionEvaluatedEvent("invalid");
|
|
214
|
-
|
|
215
231
|
// While we didn't directly match with any answer form, we
|
|
216
232
|
// did at some point get an "ungraded" validation result,
|
|
217
233
|
// which might indicate e.g. a mismatch in variable casing.
|
|
@@ -226,8 +242,6 @@ export class Expression extends React.Component<Props, ExpressionState> {
|
|
|
226
242
|
};
|
|
227
243
|
}
|
|
228
244
|
if (allEmpty) {
|
|
229
|
-
sendExpressionEvaluatedEvent("invalid");
|
|
230
|
-
|
|
231
245
|
// If everything graded as empty, it's invalid.
|
|
232
246
|
return {
|
|
233
247
|
type: "invalid",
|
|
@@ -236,7 +250,6 @@ export class Expression extends React.Component<Props, ExpressionState> {
|
|
|
236
250
|
}
|
|
237
251
|
// We fell through all the possibilities and we're not empty,
|
|
238
252
|
// so the answer is considered incorrect.
|
|
239
|
-
sendExpressionEvaluatedEvent("incorrect");
|
|
240
253
|
return {
|
|
241
254
|
type: "points",
|
|
242
255
|
earned: 0,
|
|
@@ -251,7 +264,6 @@ export class Expression extends React.Component<Props, ExpressionState> {
|
|
|
251
264
|
userInput,
|
|
252
265
|
matchMessage,
|
|
253
266
|
);
|
|
254
|
-
sendExpressionEvaluatedEvent("invalid");
|
|
255
267
|
return {
|
|
256
268
|
type: "invalid",
|
|
257
269
|
message: apiResult === false ? null : matchMessage,
|
|
@@ -263,12 +275,6 @@ export class Expression extends React.Component<Props, ExpressionState> {
|
|
|
263
275
|
// TODO(eater): Seems silly to translate result to this
|
|
264
276
|
// invalid/points thing and immediately translate it back in
|
|
265
277
|
// ItemRenderer.scoreInput()
|
|
266
|
-
sendExpressionEvaluatedEvent(
|
|
267
|
-
matchingAnswerForm.considered === "correct"
|
|
268
|
-
? "correct"
|
|
269
|
-
: "incorrect",
|
|
270
|
-
);
|
|
271
|
-
|
|
272
278
|
return {
|
|
273
279
|
type: "points",
|
|
274
280
|
earned: matchingAnswerForm.considered === "correct" ? 1 : 0,
|
|
@@ -329,7 +335,7 @@ export class Expression extends React.Component<Props, ExpressionState> {
|
|
|
329
335
|
) {
|
|
330
336
|
// TODO(jeff, CP-3128): Use Wonder Blocks Timing API.
|
|
331
337
|
// eslint-disable-next-line no-restricted-syntax
|
|
332
|
-
// @ts-expect-error
|
|
338
|
+
// @ts-expect-error - TS2769 - No overload matches this call.
|
|
333
339
|
clearTimeout(this.errorTimeout);
|
|
334
340
|
|
|
335
341
|
if (this.parse(this.props.value, this.props).parsed) {
|
|
@@ -339,7 +345,7 @@ export class Expression extends React.Component<Props, ExpressionState> {
|
|
|
339
345
|
// Store timeout ID so that we can clear it above
|
|
340
346
|
// TODO(jeff, CP-3128): Use Wonder Blocks Timing API.
|
|
341
347
|
// eslint-disable-next-line no-restricted-syntax
|
|
342
|
-
// @ts-expect-error
|
|
348
|
+
// @ts-expect-error - TS2322 - Type 'Timeout' is not assignable to type 'number'.
|
|
343
349
|
this.errorTimeout = setTimeout(() => {
|
|
344
350
|
const apiResult = this.props.apiOptions.onInputError(
|
|
345
351
|
null, // reserved for some widget identifier
|
|
@@ -357,7 +363,7 @@ export class Expression extends React.Component<Props, ExpressionState> {
|
|
|
357
363
|
componentWillUnmount: () => void = () => {
|
|
358
364
|
// TODO(jeff, CP-3128): Use Wonder Blocks Timing API.
|
|
359
365
|
// eslint-disable-next-line no-restricted-syntax
|
|
360
|
-
// @ts-expect-error
|
|
366
|
+
// @ts-expect-error - TS2769 - No overload matches this call.
|
|
361
367
|
clearTimeout(this.errorTimeout);
|
|
362
368
|
|
|
363
369
|
this._isMounted = false;
|
|
@@ -368,7 +374,21 @@ export class Expression extends React.Component<Props, ExpressionState> {
|
|
|
368
374
|
onInputError: OnInputErrorFunctionType,
|
|
369
375
|
) => PerseusScore = (rubric, onInputError) => {
|
|
370
376
|
onInputError = onInputError || function () {};
|
|
371
|
-
|
|
377
|
+
const result = Expression.validate(
|
|
378
|
+
this.getUserInput(),
|
|
379
|
+
rubric,
|
|
380
|
+
onInputError,
|
|
381
|
+
);
|
|
382
|
+
|
|
383
|
+
this.sendExpressionEvaluatedEvent(
|
|
384
|
+
result.type === "invalid"
|
|
385
|
+
? "invalid"
|
|
386
|
+
: result.earned === result.total
|
|
387
|
+
? "correct"
|
|
388
|
+
: "incorrect",
|
|
389
|
+
);
|
|
390
|
+
|
|
391
|
+
return result;
|
|
372
392
|
};
|
|
373
393
|
|
|
374
394
|
getUserInput: () => string = () => {
|
|
@@ -413,7 +433,7 @@ export class Expression extends React.Component<Props, ExpressionState> {
|
|
|
413
433
|
focus: () => boolean = () => {
|
|
414
434
|
if (this.props.apiOptions.customKeypad) {
|
|
415
435
|
// eslint-disable-next-line react/no-string-refs
|
|
416
|
-
// @ts-expect-error
|
|
436
|
+
// @ts-expect-error - TS2339 - Property 'focus' does not exist on type 'ReactInstance'.
|
|
417
437
|
this.refs.input.focus();
|
|
418
438
|
} else {
|
|
419
439
|
// The buttons are often on top of text you're trying to read, so
|
|
@@ -425,20 +445,20 @@ export class Expression extends React.Component<Props, ExpressionState> {
|
|
|
425
445
|
|
|
426
446
|
focusInputPath: (inputPath: InputPath) => void = (inputPath: InputPath) => {
|
|
427
447
|
// eslint-disable-next-line react/no-string-refs
|
|
428
|
-
// @ts-expect-error
|
|
448
|
+
// @ts-expect-error - TS2339 - Property 'focus' does not exist on type 'ReactInstance'.
|
|
429
449
|
this.refs.input.focus();
|
|
430
450
|
};
|
|
431
451
|
|
|
432
452
|
blurInputPath: (inputPath: InputPath) => void = (inputPath: InputPath) => {
|
|
433
453
|
// eslint-disable-next-line react/no-string-refs
|
|
434
|
-
// @ts-expect-error
|
|
454
|
+
// @ts-expect-error - TS2339 - Property 'blur' does not exist on type 'ReactInstance'.
|
|
435
455
|
this.refs.input.blur();
|
|
436
456
|
};
|
|
437
457
|
|
|
438
458
|
// HACK(joel)
|
|
439
459
|
insert(keyPressed: Key) {
|
|
440
460
|
// eslint-disable-next-line react/no-string-refs
|
|
441
|
-
// @ts-expect-error
|
|
461
|
+
// @ts-expect-error - TS2339 - Property 'insert' does not exist on type 'ReactInstance'.
|
|
442
462
|
this.refs.input.insert(keyPressed);
|
|
443
463
|
}
|
|
444
464
|
|
|
@@ -470,6 +490,18 @@ export class Expression extends React.Component<Props, ExpressionState> {
|
|
|
470
490
|
);
|
|
471
491
|
};
|
|
472
492
|
|
|
493
|
+
sendExpressionEvaluatedEvent(result: "correct" | "incorrect" | "invalid") {
|
|
494
|
+
this.props.analytics.onAnalyticsEvent({
|
|
495
|
+
type: "perseus:expression-evaluated",
|
|
496
|
+
payload: {
|
|
497
|
+
result,
|
|
498
|
+
virtualKeypadVersion: deriveKeypadVersion(
|
|
499
|
+
this.props.apiOptions,
|
|
500
|
+
),
|
|
501
|
+
},
|
|
502
|
+
});
|
|
503
|
+
}
|
|
504
|
+
|
|
473
505
|
render():
|
|
474
506
|
| React.ReactNode
|
|
475
507
|
| React.ReactElement<React.ComponentProps<"div">> {
|
|
@@ -639,22 +671,25 @@ const propUpgrades = {
|
|
|
639
671
|
}),
|
|
640
672
|
} as const;
|
|
641
673
|
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
674
|
+
const ExpressionWithDependencies = React.forwardRef<
|
|
675
|
+
Expression,
|
|
676
|
+
Omit<
|
|
677
|
+
JSX.LibraryManagedAttributes<
|
|
678
|
+
typeof Expression,
|
|
679
|
+
React.ComponentProps<typeof Expression>
|
|
680
|
+
>,
|
|
681
|
+
keyof ReturnType<typeof useDependencies>
|
|
682
|
+
>
|
|
683
|
+
>((props, ref) => {
|
|
684
|
+
const deps = useDependencies();
|
|
685
|
+
return <Expression ref={ref} analytics={deps.analytics} {...props} />;
|
|
686
|
+
});
|
|
652
687
|
|
|
653
688
|
export default {
|
|
654
689
|
name: "expression",
|
|
655
690
|
displayName: "Expression / Equation",
|
|
656
691
|
defaultAlignment: "inline-block",
|
|
657
|
-
widget:
|
|
692
|
+
widget: ExpressionWithDependencies,
|
|
658
693
|
transform: (widgetOptions: PerseusExpressionWidgetOptions): RenderProps => {
|
|
659
694
|
const {times, functions, buttonSets, buttonsVisible} = widgetOptions;
|
|
660
695
|
return {
|
|
@@ -670,4 +705,4 @@ export default {
|
|
|
670
705
|
|
|
671
706
|
// For use by the editor
|
|
672
707
|
isLintable: true,
|
|
673
|
-
} as WidgetExports<typeof
|
|
708
|
+
} as WidgetExports<typeof ExpressionWithDependencies>;
|
|
@@ -87,7 +87,7 @@ type State = {
|
|
|
87
87
|
// TODO(jared): find a better name for this :) and for GradedGroup; the names
|
|
88
88
|
// are currently a little confusing.
|
|
89
89
|
class GradedGroupSet extends React.Component<Props, State> {
|
|
90
|
-
// @ts-expect-error
|
|
90
|
+
// @ts-expect-error - TS2564 - Property '_childGroup' has no initializer and is not definitely assigned in the constructor.
|
|
91
91
|
_childGroup: GradedGroup;
|
|
92
92
|
|
|
93
93
|
static defaultProps: DefaultProps = {
|
|
@@ -105,7 +105,7 @@ class GradedGroupSet extends React.Component<Props, State> {
|
|
|
105
105
|
}
|
|
106
106
|
|
|
107
107
|
change: (...args: ReadonlyArray<unknown>) => any = (...args) => {
|
|
108
|
-
// @ts-expect-error
|
|
108
|
+
// @ts-expect-error - TS2345 - Argument of type 'readonly unknown[]' is not assignable to parameter of type 'any[]'.
|
|
109
109
|
return Changeable.change.apply(this, args);
|
|
110
110
|
};
|
|
111
111
|
|
|
@@ -157,7 +157,7 @@ class GradedGroupSet extends React.Component<Props, State> {
|
|
|
157
157
|
return (
|
|
158
158
|
// TODO(jeremy): Don't spread this.props, instead
|
|
159
159
|
// pass in all props GradedGroup needs explicilty
|
|
160
|
-
// @ts-expect-error
|
|
160
|
+
// @ts-expect-error - TS2769 - No overload matches this call.
|
|
161
161
|
<GradedGroup
|
|
162
162
|
key={i}
|
|
163
163
|
{...this.props}
|
|
@@ -200,10 +200,10 @@ class GradedGroupSet extends React.Component<Props, State> {
|
|
|
200
200
|
</div>
|
|
201
201
|
{/* TODO(jeremy): Don't spread this.props, instead
|
|
202
202
|
pass in all props GradedGroup needs explicitly */}
|
|
203
|
-
{/* @ts-expect-error
|
|
203
|
+
{/* @ts-expect-error - TS2769 - No overload matches this call. */}
|
|
204
204
|
<GradedGroup
|
|
205
205
|
key={this.state.currentGroup}
|
|
206
|
-
// @ts-expect-error
|
|
206
|
+
// @ts-expect-error - TS2322 - Type 'GradedGroup | null' is not assignable to type 'GradedGroup'.
|
|
207
207
|
// Type 'null' is not assignable to type 'GradedGroup'.
|
|
208
208
|
ref={(comp) => (this._childGroup = comp)}
|
|
209
209
|
// We should pass in the set of props explicitly
|