@khanacademy/perseus 19.1.4 → 19.1.6
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/dist/components/graphie.d.ts +9 -1
- package/dist/es/index.js +255 -122
- package/dist/es/index.js.map +1 -1
- package/dist/index.js +261 -126
- package/dist/index.js.map +1 -1
- package/dist/interactive2/interactive-util.d.ts +1 -1
- package/dist/interactive2/movable-point-options.d.ts +5 -4
- package/dist/interactive2/movable.d.ts +90 -13
- package/dist/interactive2/types.d.ts +6 -0
- package/dist/util/graphie.d.ts +5 -0
- package/dist/widgets/expression.d.ts +4 -4
- package/package.json +11 -8
- package/.babelrc.js +0 -8
- package/.eslintrc.js +0 -12
- package/CHANGELOG.md +0 -1422
- package/src/__stories__/article-renderer.stories.tsx +0 -100
- package/src/__stories__/hints-renderer.stories.tsx +0 -55
- package/src/__stories__/server-item-renderer.stories.tsx +0 -44
- package/src/__testdata__/article-renderer.testdata.ts +0 -212
- package/src/__testdata__/graphie.testdata.ts +0 -51
- package/src/__testdata__/renderer.testdata.ts +0 -274
- package/src/__testdata__/server-item-renderer.testdata.ts +0 -171
- package/src/__tests__/__snapshots__/perseus-markdown.test.ts.snap +0 -507
- package/src/__tests__/__snapshots__/renderer.test.tsx.snap +0 -525
- package/src/__tests__/__snapshots__/server-item-renderer.test.tsx.snap +0 -285
- package/src/__tests__/a11y.test.ts +0 -303
- package/src/__tests__/article-renderer.test.tsx +0 -130
- package/src/__tests__/error-boundary.test.tsx +0 -76
- package/src/__tests__/extract-perseus-data.test.ts +0 -1027
- package/src/__tests__/init.test.ts +0 -10
- package/src/__tests__/jipt-paragraphs.test.ts +0 -32
- package/src/__tests__/mock-asset-loading-widget.tsx +0 -53
- package/src/__tests__/mock-widget.tsx +0 -33
- package/src/__tests__/perseus-markdown.test.ts +0 -764
- package/src/__tests__/renderability.test.ts +0 -480
- package/src/__tests__/renderer-api.test.tsx +0 -302
- package/src/__tests__/renderer.test.tsx +0 -1816
- package/src/__tests__/server-item-renderer.test.tsx +0 -582
- package/src/__tests__/test-items/image-item.ts +0 -24
- package/src/__tests__/test-items/input-number-1-item.ts +0 -26
- package/src/__tests__/test-items/input-number-2-item.ts +0 -38
- package/src/__tests__/test-items/table-item.ts +0 -29
- package/src/__tests__/tex-wrangler.test.ts +0 -82
- package/src/__tests__/util.test.ts +0 -40
- package/src/__tests__/widget-container.test.tsx +0 -126
- package/src/__tests__/widgets.test.ts +0 -91
- package/src/a11y.ts +0 -45
- package/src/all-widgets.ts +0 -9
- package/src/article-renderer.tsx +0 -237
- package/src/asset-context.ts +0 -30
- package/src/basic-widgets.ts +0 -16
- package/src/components/__stories__/button-group.stories.tsx +0 -55
- package/src/components/__stories__/fixed-to-responsive.stories.tsx +0 -141
- package/src/components/__stories__/graph.stories.tsx +0 -28
- package/src/components/__stories__/graphie.stories.tsx +0 -33
- package/src/components/__stories__/hud.stories.tsx +0 -35
- package/src/components/__stories__/icon.stories.tsx +0 -63
- package/src/components/__stories__/image-loader.stories.tsx +0 -63
- package/src/components/__stories__/info-tip.stories.tsx +0 -31
- package/src/components/__stories__/inline-icon.stories.tsx +0 -40
- package/src/components/__stories__/input-with-examples.stories.tsx +0 -53
- package/src/components/__stories__/lint.stories.tsx +0 -86
- package/src/components/__stories__/math-input.stories.tsx +0 -43
- package/src/components/__stories__/math-output.stories.tsx +0 -23
- package/src/components/__stories__/multi-button-group.stories.tsx +0 -66
- package/src/components/__stories__/number-input.stories.tsx +0 -41
- package/src/components/__stories__/prop-check-box.stories.tsx +0 -65
- package/src/components/__stories__/range-input.stories.tsx +0 -29
- package/src/components/__stories__/simple-keypad-input.stories.tsx +0 -27
- package/src/components/__stories__/sortable.stories.tsx +0 -77
- package/src/components/__stories__/stub-tag-editor.stories.tsx +0 -45
- package/src/components/__stories__/svg-image.stories.tsx +0 -74
- package/src/components/__stories__/tex.stories.tsx +0 -23
- package/src/components/__stories__/text-input.stories.tsx +0 -33
- package/src/components/__stories__/text-list-editor.stories.tsx +0 -32
- package/src/components/__stories__/tooltip.stories.tsx +0 -52
- package/src/components/__stories__/zoomable-tex.stories.tsx +0 -41
- package/src/components/__stories__/zoomable.stories.tsx +0 -49
- package/src/components/__testdata__/sorter.testdata.ts +0 -19
- package/src/components/__tests__/__snapshots__/sortable.test.tsx.snap +0 -163
- package/src/components/__tests__/__snapshots__/sorter.test.tsx.snap +0 -265
- package/src/components/__tests__/math-input.test.tsx +0 -147
- package/src/components/__tests__/number-input.test.tsx +0 -128
- package/src/components/__tests__/sortable.test.tsx +0 -269
- package/src/components/__tests__/sorter.test.tsx +0 -114
- package/src/components/__tests__/zoomable.test.tsx +0 -399
- package/src/components/button-group.tsx +0 -130
- package/src/components/constants.ts +0 -14
- package/src/components/fixed-to-responsive.tsx +0 -169
- package/src/components/graph.tsx +0 -444
- package/src/components/graphie-classes.ts +0 -153
- package/src/components/graphie-movables.ts +0 -338
- package/src/components/graphie.tsx +0 -392
- package/src/components/highlighting/highlightable-content.tsx +0 -240
- package/src/components/highlighting/highlights.ts +0 -207
- package/src/components/highlighting/ranges.ts +0 -304
- package/src/components/highlighting/types.ts +0 -73
- package/src/components/highlighting/ui/highlight-renderer.tsx +0 -172
- package/src/components/highlighting/ui/highlight-set-renderer.tsx +0 -185
- package/src/components/highlighting/ui/highlight-tooltip.tsx +0 -141
- package/src/components/highlighting/ui/highlighting-ui.tsx +0 -143
- package/src/components/highlighting/ui/selection-tracker.tsx +0 -186
- package/src/components/highlighting/ui/types.ts +0 -21
- package/src/components/highlighting/ui/util.ts +0 -165
- package/src/components/highlighting/word-indexer.tsx +0 -152
- package/src/components/hud.tsx +0 -167
- package/src/components/icon.tsx +0 -141
- package/src/components/image-loader.tsx +0 -177
- package/src/components/info-tip/info-tip.tsx +0 -144
- package/src/components/info-tip.tsx +0 -39
- package/src/components/inline-icon.tsx +0 -60
- package/src/components/input-with-examples.tsx +0 -249
- package/src/components/lint.tsx +0 -459
- package/src/components/math-input.tsx +0 -474
- package/src/components/math-output.tsx +0 -134
- package/src/components/multi-button-group.tsx +0 -135
- package/src/components/number-input.tsx +0 -249
- package/src/components/prop-check-box.tsx +0 -79
- package/src/components/range-input.tsx +0 -60
- package/src/components/simple-keypad-input.tsx +0 -88
- package/src/components/sortable.tsx +0 -958
- package/src/components/stub-tag-editor.tsx +0 -53
- package/src/components/svg-image.tsx +0 -779
- package/src/components/tex.tsx +0 -67
- package/src/components/text-input.tsx +0 -129
- package/src/components/text-list-editor.tsx +0 -166
- package/src/components/tooltip.tsx +0 -410
- package/src/components/visibility-observer/__stories__/visibility-observer.stories.tsx +0 -141
- package/src/components/visibility-observer/create-visibility-observer.ts +0 -108
- package/src/components/visibility-observer/get-scroll-parent.ts +0 -46
- package/src/components/visibility-observer/visibility-observer.tsx +0 -124
- package/src/components/zoomable-tex.tsx +0 -78
- package/src/components/zoomable.tsx +0 -304
- package/src/components.ts +0 -15
- package/src/definition-context.tsx +0 -59
- package/src/dependencies.ts +0 -40
- package/src/error-boundary.tsx +0 -70
- package/src/extra-widgets.ts +0 -75
- package/src/hint-renderer.tsx +0 -151
- package/src/hints-renderer.tsx +0 -372
- package/src/icon-paths.ts +0 -119
- package/src/index.ts +0 -171
- package/src/init.ts +0 -56
- package/src/interaction-tracker.ts +0 -62
- package/src/interactive2/__tests__/movable-mock.ts +0 -43
- package/src/interactive2/__tests__/movable-point.test.ts +0 -144
- package/src/interactive2/__tests__/movable.test.ts +0 -157
- package/src/interactive2/interactive-util.test.ts +0 -93
- package/src/interactive2/interactive-util.ts +0 -159
- package/src/interactive2/movable-helper-methods.ts +0 -166
- package/src/interactive2/movable-line-options.ts +0 -419
- package/src/interactive2/movable-line.ts +0 -307
- package/src/interactive2/movable-point-options.ts +0 -212
- package/src/interactive2/movable-point.tsx +0 -585
- package/src/interactive2/movable-polygon-options.ts +0 -389
- package/src/interactive2/movable-polygon.ts +0 -360
- package/src/interactive2/movable.ts +0 -279
- package/src/interactive2/objective_.ts +0 -79
- package/src/interactive2/types.ts +0 -2
- package/src/interactive2/wrapped-defaults.ts +0 -87
- package/src/interactive2/wrapped-ellipse.ts +0 -94
- package/src/interactive2/wrapped-line.ts +0 -116
- package/src/interactive2/wrapped-path.ts +0 -51
- package/src/interactive2.ts +0 -70
- package/src/item-version.ts +0 -10
- package/src/jipt-paragraphs.ts +0 -49
- package/src/jquery.mobile.vmouse.js +0 -545
- package/src/loading-context.ts +0 -21
- package/src/logging/log.test.ts +0 -39
- package/src/logging/log.ts +0 -97
- package/src/mixins/__tests__/widget-prop-denylist.test.ts +0 -21
- package/src/mixins/changeable.ts +0 -133
- package/src/mixins/editor-jsonify.ts +0 -13
- package/src/mixins/widget-jsonify-deprecated.ts +0 -23
- package/src/mixins/widget-prop-denylist.ts +0 -48
- package/src/multi-items/__stories__/multi-renderer.stories.tsx +0 -83
- package/src/multi-items/__testdata__/multi-renderer.testdata.ts +0 -172
- package/src/multi-items/__tests__/__snapshots__/multi-renderer.test.tsx.snap +0 -1164
- package/src/multi-items/__tests__/items.test.ts +0 -240
- package/src/multi-items/__tests__/multi-renderer.test.tsx +0 -914
- package/src/multi-items/__tests__/prop-type-builders.test.ts +0 -133
- package/src/multi-items/__tests__/shapes.test.ts +0 -43
- package/src/multi-items/__tests__/trees.test.ts +0 -317
- package/src/multi-items/item-types.ts +0 -56
- package/src/multi-items/items.ts +0 -176
- package/src/multi-items/multi-renderer.tsx +0 -569
- package/src/multi-items/prop-type-builders.ts +0 -106
- package/src/multi-items/shape-types.ts +0 -52
- package/src/multi-items/shapes.ts +0 -52
- package/src/multi-items/tree-types.ts +0 -47
- package/src/multi-items/trees.ts +0 -360
- package/src/multi-items.ts +0 -75
- package/src/perseus-api.tsx +0 -188
- package/src/perseus-env.ts +0 -27
- package/src/perseus-error.ts +0 -17
- package/src/perseus-markdown.tsx +0 -405
- package/src/perseus-types.ts +0 -1366
- package/src/perseus-version.ts +0 -9
- package/src/question-paragraph.tsx +0 -34
- package/src/renderability.ts +0 -109
- package/src/renderer.tsx +0 -2000
- package/src/server-item-renderer.tsx +0 -495
- package/src/sigfigs.ts +0 -490
- package/src/styles/articles.less +0 -749
- package/src/styles/constants.ts +0 -94
- package/src/styles/global-constants.ts +0 -343
- package/src/styles/global-styles.ts +0 -306
- package/src/styles/khan-exercise.css +0 -1468
- package/src/styles/media-queries.ts +0 -47
- package/src/styles/perseus-renderer.less +0 -732
- package/src/styles/shared.ts +0 -130
- package/src/styles/util.less +0 -47
- package/src/styles/variables.boostrap.less +0 -277
- package/src/styles/variables.less +0 -56
- package/src/styles/variables.shared.less +0 -340
- package/src/styles/widgets/categorizer.less +0 -38
- package/src/styles/widgets/dropdown.less +0 -3
- package/src/styles/widgets/expression.less +0 -65
- package/src/styles/widgets/graded-group.less +0 -36
- package/src/styles/widgets/grapher.less +0 -12
- package/src/styles/widgets/group.less +0 -19
- package/src/styles/widgets/image.less +0 -54
- package/src/styles/widgets/interactive-graph.less +0 -64
- package/src/styles/widgets/label-image.less +0 -57
- package/src/styles/widgets/matcher.less +0 -8
- package/src/styles/widgets/matrix.less +0 -126
- package/src/styles/widgets/measurer.less +0 -20
- package/src/styles/widgets/orderer.less +0 -98
- package/src/styles/widgets/passage.less +0 -154
- package/src/styles/widgets/plotter.less +0 -31
- package/src/styles/widgets/radio.less +0 -58
- package/src/styles/widgets/reaction-diagram.less +0 -35
- package/src/styles/widgets/sequence.less +0 -5
- package/src/styles/widgets/sortable.less +0 -113
- package/src/styles/widgets/table.less +0 -57
- package/src/styles/widgets/unit.less +0 -15
- package/src/tex-wrangler.ts +0 -182
- package/src/translation-linter.ts +0 -126
- package/src/traversal.ts +0 -138
- package/src/types.ts +0 -513
- package/src/util/a11y.ts +0 -23
- package/src/util/answer-types.test.ts +0 -114
- package/src/util/answer-types.ts +0 -876
- package/src/util/colors.ts +0 -93
- package/src/util/drawing-transform.test.ts +0 -67
- package/src/util/drawing-transform.ts +0 -102
- package/src/util/extract-perseus-data.ts +0 -539
- package/src/util/fix-passage-refs.ts +0 -121
- package/src/util/geometry.test.ts +0 -75
- package/src/util/geometry.ts +0 -312
- package/src/util/graph-bounds.ts +0 -23
- package/src/util/graph-utils.ts +0 -15
- package/src/util/graphie.test.ts +0 -1277
- package/src/util/graphie.ts +0 -1566
- package/src/util/interactive.ts +0 -4172
- package/src/util/interval.ts +0 -4
- package/src/util/katex-preprocess.ts +0 -14
- package/src/util/math.test.ts +0 -11
- package/src/util/math.ts +0 -294
- package/src/util/mobile-native-utils.test.ts +0 -22
- package/src/util/mobile-native-utils.ts +0 -12
- package/src/util/parse-perseus-json.test.ts +0 -10
- package/src/util/parse-perseus-json.ts +0 -13
- package/src/util/react-render.tsx +0 -27
- package/src/util/register-all-widgets-for-testing.ts +0 -13
- package/src/util/scroll-utils.ts +0 -155
- package/src/util/sizing-utils.ts +0 -46
- package/src/util/tex.ts +0 -73
- package/src/util/url-utils.ts +0 -34
- package/src/util.graphie.test.ts +0 -45
- package/src/util.graphie.ts +0 -59
- package/src/util.ts +0 -966
- package/src/version.ts +0 -10
- package/src/widget-container.tsx +0 -199
- package/src/widgets/__stories__/categorizer.stories.tsx +0 -14
- package/src/widgets/__stories__/cs-program.stories.tsx +0 -14
- package/src/widgets/__stories__/definition.stories.tsx +0 -114
- package/src/widgets/__stories__/dropdown.stories.tsx +0 -14
- package/src/widgets/__stories__/explanation.stories.tsx +0 -18
- package/src/widgets/__stories__/expression.stories.tsx +0 -145
- package/src/widgets/__stories__/graded-group-set.stories.tsx +0 -31
- package/src/widgets/__stories__/graded-group.stories.tsx +0 -31
- package/src/widgets/__stories__/grapher.stories.tsx +0 -46
- package/src/widgets/__stories__/group.stories.tsx +0 -14
- package/src/widgets/__stories__/iframe.stories.tsx +0 -14
- package/src/widgets/__stories__/image.stories.tsx +0 -85
- package/src/widgets/__stories__/input-number.stories.tsx +0 -101
- package/src/widgets/__stories__/interaction.stories.tsx +0 -14
- package/src/widgets/__stories__/interactive-graph.stories.tsx +0 -60
- package/src/widgets/__stories__/label-image.stories.tsx +0 -130
- package/src/widgets/__stories__/matcher.stories.tsx +0 -14
- package/src/widgets/__stories__/matrix.stories.tsx +0 -14
- package/src/widgets/__stories__/number-line.stories.tsx +0 -14
- package/src/widgets/__stories__/numeric-input.stories.tsx +0 -105
- package/src/widgets/__stories__/orderer.stories.tsx +0 -18
- package/src/widgets/__stories__/passage-ref.stories.tsx +0 -33
- package/src/widgets/__stories__/passage.stories.tsx +0 -39
- package/src/widgets/__stories__/plotter.stories.tsx +0 -27
- package/src/widgets/__stories__/radio.stories.tsx +0 -86
- package/src/widgets/__stories__/random-widgets.stories.tsx +0 -59
- package/src/widgets/__stories__/sorter.stories.tsx +0 -14
- package/src/widgets/__stories__/test-keypad-context-wrapper.tsx +0 -66
- package/src/widgets/__stories__/unit.stories.tsx +0 -28
- package/src/widgets/__stories__/video-transcript-link.stories.tsx +0 -23
- package/src/widgets/__stories__/video.stories.tsx +0 -22
- package/src/widgets/__testdata__/base-radio.testdata.ts +0 -21
- package/src/widgets/__testdata__/categorizer.testdata.ts +0 -89
- package/src/widgets/__testdata__/cs-program.testdata.ts +0 -27
- package/src/widgets/__testdata__/dropdown.testdata.ts +0 -71
- package/src/widgets/__testdata__/explanation.testdata.ts +0 -85
- package/src/widgets/__testdata__/expression.testdata.ts +0 -198
- package/src/widgets/__testdata__/graded-group-set.testdata.ts +0 -356
- package/src/widgets/__testdata__/graded-group.testdata.ts +0 -77
- package/src/widgets/__testdata__/grapher.testdata.ts +0 -374
- package/src/widgets/__testdata__/group.testdata.ts +0 -153
- package/src/widgets/__testdata__/iframe.testdata.ts +0 -35
- package/src/widgets/__testdata__/image.testdata.ts +0 -36
- package/src/widgets/__testdata__/input-number.testdata.ts +0 -72
- package/src/widgets/__testdata__/interaction.testdata.ts +0 -262
- package/src/widgets/__testdata__/interactive-graph-random.testdata.ts +0 -269
- package/src/widgets/__testdata__/interactive-graph.testdata.ts +0 -644
- package/src/widgets/__testdata__/label-image.testdata.ts +0 -308
- package/src/widgets/__testdata__/matcher.testdata.ts +0 -33
- package/src/widgets/__testdata__/matrix.testdata.ts +0 -28
- package/src/widgets/__testdata__/number-line.testdata.ts +0 -30
- package/src/widgets/__testdata__/numeric-input.testdata.ts +0 -265
- package/src/widgets/__testdata__/orderer.testdata.ts +0 -123
- package/src/widgets/__testdata__/passage-ref.testdata.ts +0 -101
- package/src/widgets/__testdata__/passage.testdata.ts +0 -95
- package/src/widgets/__testdata__/plotter.testdata.ts +0 -36
- package/src/widgets/__testdata__/radio.testdata.ts +0 -324
- package/src/widgets/__testdata__/randomizers.ts +0 -51
- package/src/widgets/__testdata__/sorter.testdata.ts +0 -19
- package/src/widgets/__testdata__/video.testdata.ts +0 -61
- package/src/widgets/__tests__/__snapshots__/categorizer.test.ts.snap +0 -940
- package/src/widgets/__tests__/__snapshots__/cs-program.test.ts.snap +0 -67
- package/src/widgets/__tests__/__snapshots__/definition.test.ts.snap +0 -97
- package/src/widgets/__tests__/__snapshots__/dropdown.test.ts.snap +0 -133
- package/src/widgets/__tests__/__snapshots__/explanation.test.ts.snap +0 -425
- package/src/widgets/__tests__/__snapshots__/graded-group-set-jipt.test.ts.snap +0 -729
- package/src/widgets/__tests__/__snapshots__/graded-group-set.test.ts.snap +0 -339
- package/src/widgets/__tests__/__snapshots__/graded-group.test.ts.snap +0 -801
- package/src/widgets/__tests__/__snapshots__/grapher.test.ts.snap +0 -2673
- package/src/widgets/__tests__/__snapshots__/group.test.tsx.snap +0 -1211
- package/src/widgets/__tests__/__snapshots__/iframe.test.ts.snap +0 -61
- package/src/widgets/__tests__/__snapshots__/image.test.ts.snap +0 -378
- package/src/widgets/__tests__/__snapshots__/input-number.test.ts.snap +0 -495
- package/src/widgets/__tests__/__snapshots__/interaction.test.ts.snap +0 -292
- package/src/widgets/__tests__/__snapshots__/interactive-graph.test.ts.snap +0 -2889
- package/src/widgets/__tests__/__snapshots__/matcher.test.tsx.snap +0 -883
- package/src/widgets/__tests__/__snapshots__/matrix.test.ts.snap +0 -514
- package/src/widgets/__tests__/__snapshots__/number-line.test.ts.snap +0 -814
- package/src/widgets/__tests__/__snapshots__/numeric-input.test.ts.snap +0 -470
- package/src/widgets/__tests__/__snapshots__/orderer.test.ts.snap +0 -243
- package/src/widgets/__tests__/__snapshots__/passage-ref.test.ts.snap +0 -434
- package/src/widgets/__tests__/__snapshots__/passage.test.tsx.snap +0 -1956
- package/src/widgets/__tests__/__snapshots__/plotter.test.tsx.snap +0 -827
- package/src/widgets/__tests__/__snapshots__/radio.test.ts.snap +0 -4237
- package/src/widgets/__tests__/__snapshots__/unit.test.tsx.snap +0 -20
- package/src/widgets/__tests__/__snapshots__/video.test.ts.snap +0 -153
- package/src/widgets/__tests__/categorizer.test.ts +0 -203
- package/src/widgets/__tests__/cs-program.test.ts +0 -43
- package/src/widgets/__tests__/definition.test.ts +0 -136
- package/src/widgets/__tests__/dropdown.test.ts +0 -105
- package/src/widgets/__tests__/explanation.test.ts +0 -198
- package/src/widgets/__tests__/expression-mobile.test.tsx +0 -363
- package/src/widgets/__tests__/expression.test.tsx +0 -484
- package/src/widgets/__tests__/graded-group-set-jipt.test.ts +0 -30
- package/src/widgets/__tests__/graded-group-set.test.ts +0 -288
- package/src/widgets/__tests__/graded-group.test.ts +0 -232
- package/src/widgets/__tests__/grapher.cypress.ts +0 -576
- package/src/widgets/__tests__/grapher.test.ts +0 -33
- package/src/widgets/__tests__/group.test.tsx +0 -510
- package/src/widgets/__tests__/iframe.test.ts +0 -45
- package/src/widgets/__tests__/image.test.ts +0 -62
- package/src/widgets/__tests__/input-number.test.ts +0 -354
- package/src/widgets/__tests__/interaction.test.ts +0 -31
- package/src/widgets/__tests__/interactive-graph.cypress.ts +0 -815
- package/src/widgets/__tests__/interactive-graph.test.ts +0 -106
- package/src/widgets/__tests__/matcher.test.tsx +0 -176
- package/src/widgets/__tests__/matrix.test.ts +0 -82
- package/src/widgets/__tests__/number-line.test.ts +0 -79
- package/src/widgets/__tests__/numeric-input.test.ts +0 -575
- package/src/widgets/__tests__/orderer.test.ts +0 -73
- package/src/widgets/__tests__/passage-ref.test.ts +0 -168
- package/src/widgets/__tests__/passage.test.tsx +0 -224
- package/src/widgets/__tests__/plotter.test.tsx +0 -69
- package/src/widgets/__tests__/radio/base-radio.test.tsx +0 -470
- package/src/widgets/__tests__/radio/choice-icon.test.tsx +0 -90
- package/src/widgets/__tests__/radio/choice.test.tsx +0 -310
- package/src/widgets/__tests__/radio/focus-ring.test.tsx +0 -22
- package/src/widgets/__tests__/radio/option-status.test.tsx +0 -77
- package/src/widgets/__tests__/radio.test.ts +0 -807
- package/src/widgets/__tests__/randomizers.test.ts +0 -53
- package/src/widgets/__tests__/renderQuestion.tsx +0 -101
- package/src/widgets/__tests__/unit.test.tsx +0 -168
- package/src/widgets/__tests__/video.test.ts +0 -69
- package/src/widgets/categorizer.tsx +0 -344
- package/src/widgets/cs-program.tsx +0 -227
- package/src/widgets/definition.tsx +0 -121
- package/src/widgets/deprecated-standin/__stories__/deprecated-standin.stories.tsx +0 -30
- package/src/widgets/deprecated-standin/__tests__/__snapshots__/deprecated-standin.test.ts.snap +0 -70
- package/src/widgets/deprecated-standin/__tests__/deprecated-standin.test.ts +0 -93
- package/src/widgets/deprecated-standin/index.tsx +0 -58
- package/src/widgets/dropdown.tsx +0 -142
- package/src/widgets/explanation.tsx +0 -317
- package/src/widgets/expression.tsx +0 -707
- package/src/widgets/graded-group-answer-bar.tsx +0 -142
- package/src/widgets/graded-group-set.tsx +0 -338
- package/src/widgets/graded-group.tsx +0 -471
- package/src/widgets/grapher/util.tsx +0 -799
- package/src/widgets/grapher.tsx +0 -660
- package/src/widgets/group.tsx +0 -195
- package/src/widgets/iframe.tsx +0 -195
- package/src/widgets/image.tsx +0 -312
- package/src/widgets/input-number.tsx +0 -412
- package/src/widgets/interaction/arrow-picker.tsx +0 -38
- package/src/widgets/interaction/color-picker.tsx +0 -69
- package/src/widgets/interaction/dash-picker.tsx +0 -45
- package/src/widgets/interaction/element-container.tsx +0 -100
- package/src/widgets/interaction.tsx +0 -826
- package/src/widgets/interactive-graph.tsx +0 -2597
- package/src/widgets/label-image/__stories__/answer-choices.stories.tsx +0 -91
- package/src/widgets/label-image/__stories__/answer-pill.stories.tsx +0 -62
- package/src/widgets/label-image/__stories__/marker.stories.tsx +0 -171
- package/src/widgets/label-image/__tests__/answer-pill.test.tsx +0 -75
- package/src/widgets/label-image/__tests__/hide-answers-toggle.test.tsx +0 -39
- package/src/widgets/label-image/answer-choices.tsx +0 -88
- package/src/widgets/label-image/answer-pill.tsx +0 -103
- package/src/widgets/label-image/hide-answers-toggle.tsx +0 -40
- package/src/widgets/label-image/marker.tsx +0 -268
- package/src/widgets/label-image/strings.ts +0 -5
- package/src/widgets/label-image/types.ts +0 -27
- package/src/widgets/label-image.test.ts +0 -928
- package/src/widgets/label-image.tsx +0 -819
- package/src/widgets/lights-puzzle.tsx +0 -359
- package/src/widgets/matcher.tsx +0 -298
- package/src/widgets/matrix.tsx +0 -634
- package/src/widgets/measurer.tsx +0 -222
- package/src/widgets/molecule/__tests__/layout.test.ts +0 -162
- package/src/widgets/molecule/__tests__/parser.test.ts +0 -155
- package/src/widgets/molecule/molecule-drawing.ts +0 -173
- package/src/widgets/molecule/molecule-layout.ts +0 -362
- package/src/widgets/molecule/smiles-parser.ts +0 -296
- package/src/widgets/molecule.tsx +0 -172
- package/src/widgets/number-line.tsx +0 -862
- package/src/widgets/numeric-input.tsx +0 -576
- package/src/widgets/orderer.tsx +0 -786
- package/src/widgets/passage/__tests__/passage-markdown.test.ts +0 -376
- package/src/widgets/passage/passage-markdown.tsx +0 -475
- package/src/widgets/passage-ref-target.tsx +0 -76
- package/src/widgets/passage-ref.tsx +0 -213
- package/src/widgets/passage.tsx +0 -582
- package/src/widgets/plotter.tsx +0 -1194
- package/src/widgets/radio/__stories__/base-radio.stories.tsx +0 -196
- package/src/widgets/radio/__stories__/choice-icon.stories.tsx +0 -166
- package/src/widgets/radio/__stories__/choice-none-above.stories.tsx +0 -40
- package/src/widgets/radio/__stories__/choice.stories.tsx +0 -137
- package/src/widgets/radio/__stories__/focus-ring.stories.tsx +0 -43
- package/src/widgets/radio/__stories__/option-status.stories.tsx +0 -103
- package/src/widgets/radio/base-radio.tsx +0 -511
- package/src/widgets/radio/choice-a11y-text.ts +0 -61
- package/src/widgets/radio/choice-icon/choice-icon.tsx +0 -218
- package/src/widgets/radio/choice-icon/cross-out-line.tsx +0 -51
- package/src/widgets/radio/choice-icon/shared-styles.ts +0 -15
- package/src/widgets/radio/choice-none-above.tsx +0 -56
- package/src/widgets/radio/choice.jsx.fixture.ts +0 -45
- package/src/widgets/radio/choice.tsx +0 -359
- package/src/widgets/radio/focus-ring.tsx +0 -57
- package/src/widgets/radio/option-status.tsx +0 -98
- package/src/widgets/radio/util.test.ts +0 -18
- package/src/widgets/radio/util.ts +0 -31
- package/src/widgets/radio/widget.tsx +0 -520
- package/src/widgets/radio.ts +0 -157
- package/src/widgets/reaction-diagram.tsx +0 -144
- package/src/widgets/sequence.tsx +0 -142
- package/src/widgets/simulator.tsx +0 -829
- package/src/widgets/sorter.tsx +0 -155
- package/src/widgets/table.tsx +0 -393
- package/src/widgets/unit.tsx +0 -374
- package/src/widgets/video-transcript-link.test.tsx +0 -213
- package/src/widgets/video-transcript-link.tsx +0 -84
- package/src/widgets/video.tsx +0 -135
- package/src/widgets.ts +0 -489
- package/src/zoom.ts +0 -555
- package/tsconfig-build.json +0 -26
- package/tsconfig-build.tsbuildinfo +0 -1
package/src/widgets/unit.tsx
DELETED
|
@@ -1,374 +0,0 @@
|
|
|
1
|
-
// TODO(joel): teach KAS how to accept an answer only if it's expressed in
|
|
2
|
-
// terms of a certain type.
|
|
3
|
-
// TODO(joel): Allow sigfigs within a range rather than an exact expected
|
|
4
|
-
// value?
|
|
5
|
-
import * as KAS from "@khanacademy/kas";
|
|
6
|
-
import * as i18n from "@khanacademy/wonder-blocks-i18n";
|
|
7
|
-
// eslint-disable-next-line import/no-extraneous-dependencies
|
|
8
|
-
import lens from "hubble";
|
|
9
|
-
import $ from "jquery";
|
|
10
|
-
import * as React from "react";
|
|
11
|
-
import ReactDOM from "react-dom";
|
|
12
|
-
import _ from "underscore";
|
|
13
|
-
|
|
14
|
-
import * as Changeable from "../mixins/changeable";
|
|
15
|
-
import {ClassNames as ApiClassNames, ApiOptions} from "../perseus-api";
|
|
16
|
-
import {SignificantFigures, displaySigFigs} from "../sigfigs";
|
|
17
|
-
|
|
18
|
-
import type {
|
|
19
|
-
APIOptions,
|
|
20
|
-
ChangeHandler,
|
|
21
|
-
FocusPath,
|
|
22
|
-
WidgetExports,
|
|
23
|
-
} from "../types";
|
|
24
|
-
|
|
25
|
-
const ALL = "all";
|
|
26
|
-
const MAX_SIGFIGS = 10;
|
|
27
|
-
|
|
28
|
-
export const countSigfigs = function (value: string): number {
|
|
29
|
-
return new SignificantFigures(value).sigFigs;
|
|
30
|
-
};
|
|
31
|
-
|
|
32
|
-
export const sigfigPrint = function (num: number, sigfigs: number): string {
|
|
33
|
-
return displaySigFigs(num, sigfigs, -MAX_SIGFIGS, false);
|
|
34
|
-
};
|
|
35
|
-
|
|
36
|
-
type Rubric =
|
|
37
|
-
| {
|
|
38
|
-
value: string;
|
|
39
|
-
sigfigs: number;
|
|
40
|
-
accepting: "all";
|
|
41
|
-
}
|
|
42
|
-
| {
|
|
43
|
-
value: string;
|
|
44
|
-
sigfigs: number;
|
|
45
|
-
accepting: "some";
|
|
46
|
-
acceptingUnits: ReadonlyArray<string>;
|
|
47
|
-
};
|
|
48
|
-
|
|
49
|
-
type ValidationResult =
|
|
50
|
-
| {
|
|
51
|
-
type: "points";
|
|
52
|
-
earned: 1 | 0;
|
|
53
|
-
message: string | null | undefined;
|
|
54
|
-
total: number;
|
|
55
|
-
}
|
|
56
|
-
| {
|
|
57
|
-
type: "invalid";
|
|
58
|
-
message: string | null | undefined;
|
|
59
|
-
};
|
|
60
|
-
|
|
61
|
-
type Props = {
|
|
62
|
-
apiOptions: APIOptions;
|
|
63
|
-
onChange: ChangeHandler;
|
|
64
|
-
value: string;
|
|
65
|
-
onBlur: (arg1: FocusPath) => unknown;
|
|
66
|
-
onFocus: (arg1: FocusPath) => unknown;
|
|
67
|
-
};
|
|
68
|
-
|
|
69
|
-
type DefaultProps = {
|
|
70
|
-
apiOptions: Props["apiOptions"];
|
|
71
|
-
value: Props["value"];
|
|
72
|
-
};
|
|
73
|
-
|
|
74
|
-
/* I just wrote this, but it's old by analogy to `OldExpression`, in that it's
|
|
75
|
-
* the version that non-mathquill platforms get stuck with. Constructed with an
|
|
76
|
-
* <input>, a parser, popsicle sticks, and glue.
|
|
77
|
-
*
|
|
78
|
-
* In the same way as OldExpression, this parses continuously as you type, then
|
|
79
|
-
* shows and hides an error buddy. The error message is only shown after a
|
|
80
|
-
* rolling two second delay, but hidden immediately on further typing.
|
|
81
|
-
*/
|
|
82
|
-
export class OldUnitInput extends React.Component<Props> {
|
|
83
|
-
_errorTimeout: number | null | undefined;
|
|
84
|
-
|
|
85
|
-
static defaultProps: DefaultProps = {
|
|
86
|
-
apiOptions: ApiOptions.defaults,
|
|
87
|
-
value: "",
|
|
88
|
-
};
|
|
89
|
-
|
|
90
|
-
static validate(userInput: string, rubric: Rubric): ValidationResult {
|
|
91
|
-
const answer = KAS.unitParse(rubric.value).expr;
|
|
92
|
-
const guess = KAS.unitParse(userInput);
|
|
93
|
-
if (!guess.parsed) {
|
|
94
|
-
return {
|
|
95
|
-
type: "invalid",
|
|
96
|
-
message: i18n._("I couldn't understand those units."),
|
|
97
|
-
};
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
// Note: we check sigfigs, then numerical correctness, then units, so
|
|
101
|
-
// the most significant things come last, that way the user will see
|
|
102
|
-
// the most important message.
|
|
103
|
-
let message = null;
|
|
104
|
-
|
|
105
|
-
// did the user specify the right number of sigfigs?
|
|
106
|
-
// TODO(joel) - add a grading mode where the wrong number of sigfigs
|
|
107
|
-
// isn't marked wrong
|
|
108
|
-
const sigfigs = rubric.sigfigs;
|
|
109
|
-
const sigfigsCorrect = countSigfigs(guess.coefficient) === sigfigs;
|
|
110
|
-
if (!sigfigsCorrect) {
|
|
111
|
-
// @ts-expect-error - TS2322 - Type 'string' is not assignable to type 'null'.
|
|
112
|
-
message = i18n._("Check your significant figures.");
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
// now we need to check that the answer is correct to the precision we
|
|
116
|
-
// require.
|
|
117
|
-
let numericallyCorrect;
|
|
118
|
-
try {
|
|
119
|
-
const x = new KAS.Var("x");
|
|
120
|
-
const equality = new KAS.Eq(
|
|
121
|
-
answer.simplify(),
|
|
122
|
-
"=",
|
|
123
|
-
new KAS.Mul(x, guess.expr.simplify()),
|
|
124
|
-
);
|
|
125
|
-
|
|
126
|
-
const conversion = equality.solveLinearEquationForVariable(x);
|
|
127
|
-
|
|
128
|
-
// Make sure the conversion factor between the user's input answer
|
|
129
|
-
// and the canonical answer is 1, to sigfig places.
|
|
130
|
-
// TODO(joel) is this sound?
|
|
131
|
-
numericallyCorrect =
|
|
132
|
-
Number(conversion.eval()).toPrecision(sigfigs) ===
|
|
133
|
-
Number(1).toPrecision(sigfigs);
|
|
134
|
-
} catch (e: any) {
|
|
135
|
-
numericallyCorrect = false;
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
if (!numericallyCorrect) {
|
|
139
|
-
// @ts-expect-error - TS2322 - Type 'string' is not assignable to type 'null'.
|
|
140
|
-
message = i18n._("That answer is numerically incorrect.");
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
let kasCorrect;
|
|
144
|
-
const guessUnit = primUnits(guess.expr.simplify());
|
|
145
|
-
const answerUnit = primUnits(answer.simplify());
|
|
146
|
-
|
|
147
|
-
if (rubric.accepting === ALL) {
|
|
148
|
-
// We're accepting all units - KAS does the hard work of figuring
|
|
149
|
-
// out if the user's unit is equivalent to the author's unit.
|
|
150
|
-
kasCorrect = KAS.compare(guessUnit, answerUnit).equal;
|
|
151
|
-
} else {
|
|
152
|
-
// Are any of the accepted units the same as what the user entered?
|
|
153
|
-
kasCorrect = _(rubric.acceptingUnits).any((unit) => {
|
|
154
|
-
const thisAnswerUnit = primUnits(
|
|
155
|
-
KAS.unitParse(unit).unit.simplify(),
|
|
156
|
-
);
|
|
157
|
-
return KAS.compare(
|
|
158
|
-
thisAnswerUnit,
|
|
159
|
-
guessUnit,
|
|
160
|
-
// TODO(joel) - make this work as intended.
|
|
161
|
-
// { form: true }
|
|
162
|
-
).equal;
|
|
163
|
-
});
|
|
164
|
-
}
|
|
165
|
-
if (!kasCorrect) {
|
|
166
|
-
// @ts-expect-error - TS2322 - Type 'string' is not assignable to type 'null'.
|
|
167
|
-
message = i18n._("Check your units.");
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
const correct = kasCorrect && numericallyCorrect && sigfigsCorrect;
|
|
171
|
-
|
|
172
|
-
return {
|
|
173
|
-
type: "points",
|
|
174
|
-
earned: correct ? 1 : 0,
|
|
175
|
-
total: 1,
|
|
176
|
-
message,
|
|
177
|
-
};
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
componentDidUpdate() {
|
|
181
|
-
// TODO(jeff, CP-3128): Use Wonder Blocks Timing API.
|
|
182
|
-
// eslint-disable-next-line no-restricted-syntax
|
|
183
|
-
// @ts-expect-error - TS2769 - No overload matches this call.
|
|
184
|
-
clearTimeout(this._errorTimeout);
|
|
185
|
-
if (KAS.unitParse(this.props.value).parsed) {
|
|
186
|
-
this._hideError();
|
|
187
|
-
} else {
|
|
188
|
-
// TODO(jeff, CP-3128): Use Wonder Blocks Timing API.
|
|
189
|
-
// eslint-disable-next-line no-restricted-syntax
|
|
190
|
-
// @ts-expect-error - TS2322 - Type 'Timeout' is not assignable to type 'number'.
|
|
191
|
-
this._errorTimeout = setTimeout(this._showError, 2000);
|
|
192
|
-
}
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
componentWillUnmount() {
|
|
196
|
-
// TODO(jeff, CP-3128): Use Wonder Blocks Timing API.
|
|
197
|
-
// eslint-disable-next-line no-restricted-syntax
|
|
198
|
-
// @ts-expect-error - TS2769 - No overload matches this call.
|
|
199
|
-
clearTimeout(this._errorTimeout);
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
_showError: () => void = () => {
|
|
203
|
-
if (this.props.value === "") {
|
|
204
|
-
return;
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
// eslint-disable-next-line react/no-string-refs
|
|
208
|
-
// @ts-expect-error - TS2769 - No overload matches this call.
|
|
209
|
-
const $error = $(ReactDOM.findDOMNode(this.refs.error));
|
|
210
|
-
// @ts-expect-error - TS2339 - Property 'is' does not exist on type 'JQueryStatic'.
|
|
211
|
-
if (!$error.is(":visible")) {
|
|
212
|
-
$error
|
|
213
|
-
// @ts-expect-error - TS2554 - Expected 2 arguments, but got 1.
|
|
214
|
-
.css({top: 50, opacity: 0.1})
|
|
215
|
-
.show()
|
|
216
|
-
.animate({top: 0, opacity: 1.0}, 300);
|
|
217
|
-
}
|
|
218
|
-
};
|
|
219
|
-
|
|
220
|
-
_hideError: () => void = () => {
|
|
221
|
-
// eslint-disable-next-line react/no-string-refs
|
|
222
|
-
// @ts-expect-error - TS2769 - No overload matches this call.
|
|
223
|
-
const $error = $(ReactDOM.findDOMNode(this.refs.error));
|
|
224
|
-
// @ts-expect-error - TS2339 - Property 'is' does not exist on type 'JQueryStatic'.
|
|
225
|
-
if ($error.is(":visible")) {
|
|
226
|
-
// @ts-expect-error - TS2339 - Property 'animate' does not exist on type 'JQueryStatic'.
|
|
227
|
-
$error.animate({top: 50, opacity: 0.1}, 300, function () {
|
|
228
|
-
// eslint-disable-next-line @babel/no-invalid-this
|
|
229
|
-
// @ts-expect-error - TS2683 - 'this' implicitly has type 'any' because it does not have a type annotation.
|
|
230
|
-
// eslint-disable-next-line @babel/no-invalid-this
|
|
231
|
-
$(this).hide();
|
|
232
|
-
});
|
|
233
|
-
}
|
|
234
|
-
};
|
|
235
|
-
|
|
236
|
-
change: (...args: ReadonlyArray<any>) => any | null | undefined = (
|
|
237
|
-
...args
|
|
238
|
-
) => {
|
|
239
|
-
// @ts-expect-error - TS2345 - Argument of type 'readonly any[]' is not assignable to parameter of type 'any[]'.
|
|
240
|
-
return Changeable.change.apply(this, args);
|
|
241
|
-
};
|
|
242
|
-
|
|
243
|
-
handleBlur: () => void = () => {
|
|
244
|
-
this.props.onBlur([]);
|
|
245
|
-
// TODO(jeff, CP-3128): Use Wonder Blocks Timing API.
|
|
246
|
-
// eslint-disable-next-line no-restricted-syntax
|
|
247
|
-
// @ts-expect-error - TS2769 - No overload matches this call.
|
|
248
|
-
clearTimeout(this._errorTimeout);
|
|
249
|
-
if (!KAS.unitParse(this.props.value).parsed) {
|
|
250
|
-
this._showError();
|
|
251
|
-
}
|
|
252
|
-
};
|
|
253
|
-
|
|
254
|
-
handleChange: (event: React.ChangeEvent<HTMLInputElement>) => void = (
|
|
255
|
-
event: React.ChangeEvent<HTMLInputElement>,
|
|
256
|
-
) => {
|
|
257
|
-
this._hideError();
|
|
258
|
-
this.props.onChange({value: event.target.value});
|
|
259
|
-
};
|
|
260
|
-
|
|
261
|
-
simpleValidate: (
|
|
262
|
-
rubric: Rubric,
|
|
263
|
-
onInputError?: () => unknown,
|
|
264
|
-
) => ValidationResult = (rubric: Rubric, onInputError?: () => unknown) => {
|
|
265
|
-
onInputError = onInputError || function () {};
|
|
266
|
-
return OldUnitInput.validate(this.getUserInput(), rubric);
|
|
267
|
-
};
|
|
268
|
-
|
|
269
|
-
getUserInput: () => string = () => {
|
|
270
|
-
return this.props.value;
|
|
271
|
-
};
|
|
272
|
-
|
|
273
|
-
// begin mobile stuff
|
|
274
|
-
|
|
275
|
-
getInputPaths: () => ReadonlyArray<ReadonlyArray<any>> = () => {
|
|
276
|
-
// The widget itself is an input, so we return a single empty list to
|
|
277
|
-
// indicate this.
|
|
278
|
-
return [[]];
|
|
279
|
-
};
|
|
280
|
-
|
|
281
|
-
focusInputPath: (inputPath: FocusPath) => void = (inputPath: FocusPath) => {
|
|
282
|
-
// eslint-disable-next-line react/no-string-refs
|
|
283
|
-
const input = ReactDOM.findDOMNode(this.refs.input);
|
|
284
|
-
if (input) {
|
|
285
|
-
/**
|
|
286
|
-
* TODO(somewhatabstract, JIRA-XXXX):
|
|
287
|
-
* Change to using a ref callback so that focus() can be
|
|
288
|
-
* accessed.
|
|
289
|
-
*/
|
|
290
|
-
// @ts-expect-error - TS2339 - Property 'focus' does not exist on type 'Element | Text'.
|
|
291
|
-
input.focus();
|
|
292
|
-
}
|
|
293
|
-
};
|
|
294
|
-
|
|
295
|
-
handleFocus: () => void = () => {
|
|
296
|
-
this.props.onFocus([]);
|
|
297
|
-
};
|
|
298
|
-
|
|
299
|
-
blurInputPath: (inputPath: FocusPath) => void = (inputPath: FocusPath) => {
|
|
300
|
-
// eslint-disable-next-line react/no-string-refs
|
|
301
|
-
const input = ReactDOM.findDOMNode(this.refs.input);
|
|
302
|
-
if (input) {
|
|
303
|
-
/**
|
|
304
|
-
* TODO(somewhatabstract, JIRA-XXXX):
|
|
305
|
-
* Change to using a ref callback so that focus() can be
|
|
306
|
-
* accessed.
|
|
307
|
-
*/
|
|
308
|
-
// @ts-expect-error - TS2339 - Property 'blur' does not exist on type 'Element | Text'.
|
|
309
|
-
input.blur();
|
|
310
|
-
}
|
|
311
|
-
};
|
|
312
|
-
|
|
313
|
-
setInputValue: (
|
|
314
|
-
path: FocusPath,
|
|
315
|
-
newValue: string,
|
|
316
|
-
cb: () => unknown,
|
|
317
|
-
) => void = (path: FocusPath, newValue: string, cb: () => unknown) => {
|
|
318
|
-
this.props.onChange(
|
|
319
|
-
{
|
|
320
|
-
value: newValue,
|
|
321
|
-
},
|
|
322
|
-
cb,
|
|
323
|
-
);
|
|
324
|
-
};
|
|
325
|
-
|
|
326
|
-
getDOMNodeForPath: () => null | Element | Text = () => {
|
|
327
|
-
// eslint-disable-next-line react/no-string-refs
|
|
328
|
-
return ReactDOM.findDOMNode(this.refs.input);
|
|
329
|
-
};
|
|
330
|
-
|
|
331
|
-
getGrammarTypeForPath: (inputPath: FocusPath) => string = (
|
|
332
|
-
inputPath: FocusPath,
|
|
333
|
-
) => {
|
|
334
|
-
return "unit";
|
|
335
|
-
};
|
|
336
|
-
|
|
337
|
-
// end mobile stuff
|
|
338
|
-
|
|
339
|
-
// TODO(joel) think about showing the error buddy
|
|
340
|
-
render(): React.ReactNode {
|
|
341
|
-
return (
|
|
342
|
-
<div className="old-unit-input">
|
|
343
|
-
<input
|
|
344
|
-
onChange={this.handleChange}
|
|
345
|
-
ref="input" // eslint-disable-line react/no-string-refs
|
|
346
|
-
className={ApiClassNames.INTERACTIVE}
|
|
347
|
-
value={this.props.value}
|
|
348
|
-
onFocus={this.handleFocus}
|
|
349
|
-
onBlur={this.handleBlur}
|
|
350
|
-
/>
|
|
351
|
-
{/* eslint-disable-next-line react/no-string-refs */}
|
|
352
|
-
<div ref="error" className="error" style={{display: "none"}}>
|
|
353
|
-
{i18n._("I don't understand that")}
|
|
354
|
-
</div>
|
|
355
|
-
</div>
|
|
356
|
-
);
|
|
357
|
-
}
|
|
358
|
-
}
|
|
359
|
-
|
|
360
|
-
// Extract the primitive units from a unit expression. This first simplifies
|
|
361
|
-
// `expr` to a `Mul` like "5 kg m / s^2" then removes the first term.
|
|
362
|
-
const primUnits = function (expr) {
|
|
363
|
-
return expr.simplify().asMul().partition()[1].flatten().simplify();
|
|
364
|
-
};
|
|
365
|
-
|
|
366
|
-
export default {
|
|
367
|
-
name: "unit-input",
|
|
368
|
-
displayName: "Unit input",
|
|
369
|
-
defaultAlignment: "inline-block",
|
|
370
|
-
widget: OldUnitInput,
|
|
371
|
-
transform: (x: any): any => lens(x).del(["value"]).freeze(),
|
|
372
|
-
version: {major: 0, minor: 1},
|
|
373
|
-
hidden: true,
|
|
374
|
-
} as WidgetExports<typeof OldUnitInput>;
|
|
@@ -1,213 +0,0 @@
|
|
|
1
|
-
import {render, screen} from "@testing-library/react";
|
|
2
|
-
import * as React from "react";
|
|
3
|
-
import "@testing-library/jest-dom/extend-expect";
|
|
4
|
-
|
|
5
|
-
import {testDependencies} from "../../../../testing/test-dependencies";
|
|
6
|
-
import * as Dependencies from "../dependencies";
|
|
7
|
-
|
|
8
|
-
import VideoTranscriptLink from "./video-transcript-link";
|
|
9
|
-
|
|
10
|
-
describe("VideoTranscriptLink", () => {
|
|
11
|
-
beforeEach(() => {
|
|
12
|
-
jest.spyOn(Dependencies, "getDependencies").mockReturnValue({
|
|
13
|
-
...testDependencies,
|
|
14
|
-
useVideo: (videoId, kind) => {
|
|
15
|
-
if (videoId === "5qap5aO4i9A") {
|
|
16
|
-
return {
|
|
17
|
-
status: "success",
|
|
18
|
-
data: {
|
|
19
|
-
video: {
|
|
20
|
-
id: "YoutubeVideo",
|
|
21
|
-
title: "Youtube Video Title",
|
|
22
|
-
youtubeId: "5qap5aO4i9A",
|
|
23
|
-
contentId: "contentId",
|
|
24
|
-
__typename: "Video",
|
|
25
|
-
},
|
|
26
|
-
},
|
|
27
|
-
};
|
|
28
|
-
}
|
|
29
|
-
if (videoId === "slug-video-id") {
|
|
30
|
-
return {
|
|
31
|
-
status: "success",
|
|
32
|
-
data: {
|
|
33
|
-
video: {
|
|
34
|
-
id: "VideoId",
|
|
35
|
-
title: "Slug Video Title",
|
|
36
|
-
youtubeId: "YoutubeId",
|
|
37
|
-
contentId: "contentId",
|
|
38
|
-
__typename: "Video",
|
|
39
|
-
},
|
|
40
|
-
},
|
|
41
|
-
};
|
|
42
|
-
}
|
|
43
|
-
return {status: "loading"};
|
|
44
|
-
},
|
|
45
|
-
});
|
|
46
|
-
});
|
|
47
|
-
|
|
48
|
-
it("renders the title with youtube video name when given a youtube link", async () => {
|
|
49
|
-
// Arrange
|
|
50
|
-
render(
|
|
51
|
-
<VideoTranscriptLink location="https://www.youtube.com/watch?v=5qap5aO4i9A" />,
|
|
52
|
-
);
|
|
53
|
-
|
|
54
|
-
// Assert
|
|
55
|
-
// Find by Text test will fail if the indicated text is missing
|
|
56
|
-
await screen.findByText("Youtube Video Title");
|
|
57
|
-
});
|
|
58
|
-
|
|
59
|
-
it("renders the title with slug video name when provided a slug-id", async () => {
|
|
60
|
-
// Arrange
|
|
61
|
-
render(<VideoTranscriptLink location="slug-video-id" />);
|
|
62
|
-
|
|
63
|
-
// Assert
|
|
64
|
-
await screen.findByText("Slug Video Title");
|
|
65
|
-
});
|
|
66
|
-
|
|
67
|
-
it("renders the button with the correct link", async () => {
|
|
68
|
-
// Act
|
|
69
|
-
render(<VideoTranscriptLink location="slug-video-id" />);
|
|
70
|
-
|
|
71
|
-
// Assert
|
|
72
|
-
await screen.findByText("Slug Video Title");
|
|
73
|
-
await expect(screen.getByRole("link")).toHaveAttribute(
|
|
74
|
-
"href",
|
|
75
|
-
"/transcript/contentId",
|
|
76
|
-
);
|
|
77
|
-
});
|
|
78
|
-
|
|
79
|
-
it("can parse a youtube URL with feature text", async () => {
|
|
80
|
-
// Act
|
|
81
|
-
render(
|
|
82
|
-
<VideoTranscriptLink location="http://www.youtube.com/watch?v=5qap5aO4i9A&feature=feedrec_grec_index" />,
|
|
83
|
-
);
|
|
84
|
-
|
|
85
|
-
// Assert
|
|
86
|
-
await screen.findByText("Youtube Video Title");
|
|
87
|
-
});
|
|
88
|
-
|
|
89
|
-
it("can parse a youtube URL with userID text", async () => {
|
|
90
|
-
// Act
|
|
91
|
-
render(
|
|
92
|
-
<VideoTranscriptLink location="http://www.youtube.com/user/IngridMichaelsonVEVO#p/a/u/1/5qap5aO4i9A" />,
|
|
93
|
-
);
|
|
94
|
-
|
|
95
|
-
// Assert
|
|
96
|
-
await screen.findByText("Youtube Video Title");
|
|
97
|
-
});
|
|
98
|
-
|
|
99
|
-
it("can parse a youtube URL with location/language text", async () => {
|
|
100
|
-
// Act
|
|
101
|
-
render(
|
|
102
|
-
<VideoTranscriptLink location="http://www.youtube.com/v/5qap5aO4i9A?fs=1&hl=en_US&rel=0" />,
|
|
103
|
-
);
|
|
104
|
-
|
|
105
|
-
// Assert
|
|
106
|
-
await screen.findByText("Youtube Video Title");
|
|
107
|
-
});
|
|
108
|
-
|
|
109
|
-
it("can parse a youtube URL with a time stamp", async () => {
|
|
110
|
-
// Act
|
|
111
|
-
render(
|
|
112
|
-
<VideoTranscriptLink location="http://www.youtube.com/watch?v=5qap5aO4i9A#t=0m10s" />,
|
|
113
|
-
);
|
|
114
|
-
|
|
115
|
-
// Assert
|
|
116
|
-
await screen.findByText("Youtube Video Title");
|
|
117
|
-
});
|
|
118
|
-
|
|
119
|
-
it("can parse an embed youtube URL", async () => {
|
|
120
|
-
// Act
|
|
121
|
-
render(
|
|
122
|
-
<VideoTranscriptLink location="http://www.youtube.com/embed/5qap5aO4i9A?rel=0" />,
|
|
123
|
-
);
|
|
124
|
-
|
|
125
|
-
// Assert
|
|
126
|
-
await screen.findByText("Youtube Video Title");
|
|
127
|
-
});
|
|
128
|
-
|
|
129
|
-
it("can parse a shorthand youtube URL", async () => {
|
|
130
|
-
// Act
|
|
131
|
-
render(<VideoTranscriptLink location="http://youtu.be/5qap5aO4i9A" />);
|
|
132
|
-
|
|
133
|
-
// Assert
|
|
134
|
-
await screen.findByText("Youtube Video Title");
|
|
135
|
-
});
|
|
136
|
-
|
|
137
|
-
it("should link to /transcript/videoNotFound if the URL is not a youtube URL", () => {
|
|
138
|
-
// Arrange
|
|
139
|
-
jest.spyOn(Dependencies, "getDependencies").mockReturnValue({
|
|
140
|
-
...testDependencies,
|
|
141
|
-
// @ts-expect-error - TS2322 - Type '(videoId: string, kind: VideoKind) => { status: "success"; data: {}; }' is not assignable to type '(id: string, kind: VideoKind) => Result<{ video: VideoData | null | undefined; }>'.
|
|
142
|
-
useVideo: (videoId, kind) => {
|
|
143
|
-
return {status: "success", data: {}};
|
|
144
|
-
},
|
|
145
|
-
});
|
|
146
|
-
|
|
147
|
-
render(<VideoTranscriptLink location="http://stackoverflow.com" />);
|
|
148
|
-
|
|
149
|
-
expect(
|
|
150
|
-
screen.getByRole("link", {name: "See video transcript"}),
|
|
151
|
-
).toHaveAttribute("href", "/transcript/videoNotFound");
|
|
152
|
-
});
|
|
153
|
-
|
|
154
|
-
it("should handle a success state", () => {
|
|
155
|
-
// Arrange
|
|
156
|
-
jest.spyOn(Dependencies, "getDependencies").mockReturnValue({
|
|
157
|
-
...testDependencies,
|
|
158
|
-
useVideo: (videoId, kind) => {
|
|
159
|
-
return {status: "loading"};
|
|
160
|
-
},
|
|
161
|
-
});
|
|
162
|
-
|
|
163
|
-
render(<VideoTranscriptLink location="regula-1" />);
|
|
164
|
-
|
|
165
|
-
expect(screen.getByText("Loading...")).toBeInTheDocument();
|
|
166
|
-
});
|
|
167
|
-
|
|
168
|
-
it("should link to /transcript/videoNotFound if there's no data", () => {
|
|
169
|
-
// Arrange
|
|
170
|
-
jest.spyOn(Dependencies, "getDependencies").mockReturnValue({
|
|
171
|
-
...testDependencies,
|
|
172
|
-
// @ts-expect-error - TS2322 - Type '(videoId: string, kind: VideoKind) => { status: "success"; data: {}; }' is not assignable to type '(id: string, kind: VideoKind) => Result<{ video: VideoData | null | undefined; }>'.
|
|
173
|
-
useVideo: (videoId, kind) => {
|
|
174
|
-
return {status: "success", data: {}};
|
|
175
|
-
},
|
|
176
|
-
});
|
|
177
|
-
|
|
178
|
-
render(<VideoTranscriptLink location="regula-1" />);
|
|
179
|
-
|
|
180
|
-
expect(
|
|
181
|
-
screen.getByRole("link", {name: "See video transcript"}),
|
|
182
|
-
).toHaveAttribute("href", "/transcript/videoNotFound");
|
|
183
|
-
});
|
|
184
|
-
|
|
185
|
-
it("should handle an error state", () => {
|
|
186
|
-
// Arrange
|
|
187
|
-
jest.spyOn(Dependencies, "getDependencies").mockReturnValue({
|
|
188
|
-
...testDependencies,
|
|
189
|
-
// @ts-expect-error - TS2322 - Type '(videoId: string, kind: VideoKind) => { status: "error"; }' is not assignable to type '(id: string, kind: VideoKind) => Result<{ video: VideoData | null | undefined; }>'.
|
|
190
|
-
useVideo: (videoId, kind) => {
|
|
191
|
-
return {status: "error"};
|
|
192
|
-
},
|
|
193
|
-
});
|
|
194
|
-
|
|
195
|
-
render(<VideoTranscriptLink location="regula-1" />);
|
|
196
|
-
|
|
197
|
-
expect(screen.getByText("Something went wrong.")).toBeInTheDocument();
|
|
198
|
-
});
|
|
199
|
-
|
|
200
|
-
it("should handle an aborted state", () => {
|
|
201
|
-
// Arrange
|
|
202
|
-
jest.spyOn(Dependencies, "getDependencies").mockReturnValue({
|
|
203
|
-
...testDependencies,
|
|
204
|
-
useVideo: (videoId, kind) => {
|
|
205
|
-
return {status: "aborted"};
|
|
206
|
-
},
|
|
207
|
-
});
|
|
208
|
-
|
|
209
|
-
render(<VideoTranscriptLink location="regula-1" />);
|
|
210
|
-
|
|
211
|
-
expect(screen.getByText("Something went wrong.")).toBeInTheDocument();
|
|
212
|
-
});
|
|
213
|
-
});
|
|
@@ -1,84 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* This is a component that adds a link to the transcript for embedded videos in articles.
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
import {View, Text} from "@khanacademy/wonder-blocks-core";
|
|
6
|
-
import * as i18n from "@khanacademy/wonder-blocks-i18n";
|
|
7
|
-
import {Strut} from "@khanacademy/wonder-blocks-layout";
|
|
8
|
-
import Link from "@khanacademy/wonder-blocks-link";
|
|
9
|
-
import {StyleSheet} from "aphrodite";
|
|
10
|
-
import * as React from "react";
|
|
11
|
-
|
|
12
|
-
import {getDependencies} from "../dependencies";
|
|
13
|
-
|
|
14
|
-
const IS_URL = /^https?:\/\//;
|
|
15
|
-
|
|
16
|
-
const getYoutubeId = (url: string): string => {
|
|
17
|
-
const regExp =
|
|
18
|
-
/^.*((youtu.be\/)|(v\/)|(\/u\/\w\/)|(embed\/)|(watch\?))\??v?=?([^#&?]*).*/;
|
|
19
|
-
const match = url.match(regExp);
|
|
20
|
-
if (match && match[7].length === 11) {
|
|
21
|
-
return match[7];
|
|
22
|
-
}
|
|
23
|
-
return "videoNotFound";
|
|
24
|
-
};
|
|
25
|
-
|
|
26
|
-
// will accept a youtube link or a video's slug name from embedded video and then query accordingly.
|
|
27
|
-
type Props = {
|
|
28
|
-
location: string;
|
|
29
|
-
};
|
|
30
|
-
|
|
31
|
-
/**
|
|
32
|
-
* Video Transcript Link Component.
|
|
33
|
-
*/
|
|
34
|
-
const VideoTranscriptLink = (props: Props): React.ReactElement => {
|
|
35
|
-
const {location} = props;
|
|
36
|
-
const {useVideo} = getDependencies();
|
|
37
|
-
const [id, kind] = IS_URL.test(location)
|
|
38
|
-
? [getYoutubeId(location), "YOUTUBE_ID"]
|
|
39
|
-
: [location, "READABLE_ID"];
|
|
40
|
-
// The result value conforms to the wonder-blocks-data `Result` type
|
|
41
|
-
// which is used by our GraphQL framework.
|
|
42
|
-
// @ts-expect-error - TS2345 - Argument of type 'string' is not assignable to parameter of type 'VideoKind'.
|
|
43
|
-
const result = useVideo(id, kind);
|
|
44
|
-
|
|
45
|
-
switch (result.status) {
|
|
46
|
-
case "loading":
|
|
47
|
-
return <View>{i18n._("Loading...")}</View>;
|
|
48
|
-
case "success": {
|
|
49
|
-
const video = result.data?.video;
|
|
50
|
-
return (
|
|
51
|
-
<View style={styles.transcriptLink}>
|
|
52
|
-
<Text>{video?.title}</Text>
|
|
53
|
-
<Strut size={10} />
|
|
54
|
-
<Link
|
|
55
|
-
href={
|
|
56
|
-
"/transcript/" +
|
|
57
|
-
(video?.contentId || "videoNotFound")
|
|
58
|
-
}
|
|
59
|
-
target="_blank"
|
|
60
|
-
className="visited-no-recolor"
|
|
61
|
-
>
|
|
62
|
-
{i18n._("See video transcript")}
|
|
63
|
-
</Link>
|
|
64
|
-
</View>
|
|
65
|
-
);
|
|
66
|
-
}
|
|
67
|
-
case "error":
|
|
68
|
-
return <View>{i18n._("Something went wrong.")}</View>;
|
|
69
|
-
case "aborted":
|
|
70
|
-
return <View>{i18n._("Something went wrong.")}</View>;
|
|
71
|
-
default:
|
|
72
|
-
return <View>{i18n._("Something went wrong.")}</View>;
|
|
73
|
-
}
|
|
74
|
-
};
|
|
75
|
-
|
|
76
|
-
const styles = StyleSheet.create({
|
|
77
|
-
transcriptLink: {
|
|
78
|
-
flexDirection: "row",
|
|
79
|
-
width: "100%",
|
|
80
|
-
justifyContent: "center",
|
|
81
|
-
},
|
|
82
|
-
});
|
|
83
|
-
|
|
84
|
-
export default VideoTranscriptLink;
|