@khanacademy/perseus 19.1.5 → 19.1.7
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/graph.d.ts +0 -1
- package/dist/components/graphie.d.ts +0 -1
- package/dist/es/index.js +319 -212
- package/dist/es/index.js.map +1 -1
- package/dist/index.js +338 -222
- package/dist/index.js.map +1 -1
- package/dist/interactive2/movable-point.d.ts +195 -1
- package/dist/interactive2/movable.d.ts +1 -1
- package/dist/interactive2/types.d.ts +4 -2
- package/dist/interactive2.d.ts +2 -1
- package/dist/server-item-renderer.d.ts +2 -2
- package/dist/util/graphie.d.ts +12 -2
- package/dist/widgets/expression.d.ts +6 -6
- package/package.json +11 -8
- package/.babelrc.js +0 -8
- package/.eslintrc.js +0 -12
- package/CHANGELOG.md +0 -1432
- 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 -400
- 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 -55
- package/src/interactive2/__tests__/movable-point.test.ts +0 -144
- 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 -224
- 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.test.ts +0 -249
- package/src/interactive2/movable.ts +0 -437
- package/src/interactive2/objective_.ts +0 -79
- package/src/interactive2/types.ts +0 -17
- 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 -1576
- package/src/util/interactive.ts +0 -4174
- 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
|
@@ -1,958 +0,0 @@
|
|
|
1
|
-
/* eslint-disable @khanacademy/ts-no-error-suppressions */
|
|
2
|
-
/* eslint-disable @babel/no-invalid-this, react/no-unsafe, react/sort-comp */
|
|
3
|
-
import * as PerseusLinter from "@khanacademy/perseus-linter";
|
|
4
|
-
import {CircularSpinner} from "@khanacademy/wonder-blocks-progress-spinner";
|
|
5
|
-
import {StyleSheet, css} from "aphrodite";
|
|
6
|
-
import $ from "jquery";
|
|
7
|
-
import * as React from "react";
|
|
8
|
-
import ReactDOM from "react-dom";
|
|
9
|
-
import _ from "underscore";
|
|
10
|
-
|
|
11
|
-
import {getDependencies} from "../dependencies";
|
|
12
|
-
import {ClassNames as ApiClassNames} from "../perseus-api";
|
|
13
|
-
import Renderer from "../renderer";
|
|
14
|
-
import Util from "../util";
|
|
15
|
-
|
|
16
|
-
import type {Position} from "../util";
|
|
17
|
-
import type {LinterContextProps} from "@khanacademy/perseus-linter";
|
|
18
|
-
|
|
19
|
-
export enum Layout {
|
|
20
|
-
HORIZONTAL = "horizontal",
|
|
21
|
-
VERTICAL = "vertical",
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
enum ItemState {
|
|
25
|
-
STATIC = "static",
|
|
26
|
-
DRAGGING = "dragging",
|
|
27
|
-
ANIMATING = "animating",
|
|
28
|
-
DISABLED = "disabled",
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
// Augment the given position with the scroll position of the offset parent.
|
|
32
|
-
const addOffsetParentScroll = ($el: any, position: any) => {
|
|
33
|
-
// NOTE(slim): $(el).offsetParent() is NOT equivalent to $el[0].offsetParent.
|
|
34
|
-
// Specifically, when `el` is not positioned, then the native HTMLElement.offsetParent
|
|
35
|
-
// returns the closest table element, which in this case is the <td> rendered by the
|
|
36
|
-
// Perseus Matcher widget.
|
|
37
|
-
// Conversely, jQuery's offsetParent() always returns the closest positioned ancestor,
|
|
38
|
-
// even when the element is not positioned.
|
|
39
|
-
const $offsetParent = $el.offsetParent();
|
|
40
|
-
return {
|
|
41
|
-
top: position.top + $offsetParent.scrollTop(),
|
|
42
|
-
left: position.left + $offsetParent.scrollLeft(),
|
|
43
|
-
};
|
|
44
|
-
};
|
|
45
|
-
|
|
46
|
-
type PlaceholderProps = {
|
|
47
|
-
layout: Layout;
|
|
48
|
-
width: number;
|
|
49
|
-
height: number;
|
|
50
|
-
margin?: string;
|
|
51
|
-
};
|
|
52
|
-
|
|
53
|
-
// A placeholder that appears in the sortable whenever an item is dragged.
|
|
54
|
-
class Placeholder extends React.Component<PlaceholderProps> {
|
|
55
|
-
render(): React.ReactNode {
|
|
56
|
-
const {layout} = this.props;
|
|
57
|
-
const className = css(
|
|
58
|
-
styles.card,
|
|
59
|
-
styles.placeholder,
|
|
60
|
-
layout === Layout.HORIZONTAL && styles.horizontalCard,
|
|
61
|
-
);
|
|
62
|
-
const style: any = {
|
|
63
|
-
width: this.props.width,
|
|
64
|
-
height: this.props.height,
|
|
65
|
-
};
|
|
66
|
-
|
|
67
|
-
if (this.props.margin != null) {
|
|
68
|
-
style.margin = this.props.margin;
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
return <li className={className} style={style} />;
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
type DraggableProps = {
|
|
76
|
-
content: string;
|
|
77
|
-
endPosition?: {left: number; top: number};
|
|
78
|
-
includePadding: boolean;
|
|
79
|
-
layout: Layout;
|
|
80
|
-
width?: number;
|
|
81
|
-
height?: number;
|
|
82
|
-
margin?: string;
|
|
83
|
-
onAnimationEnd: () => void;
|
|
84
|
-
onMouseDown: () => void;
|
|
85
|
-
onMouseMove: () => void;
|
|
86
|
-
onMouseUp: () => void;
|
|
87
|
-
onRender: () => void;
|
|
88
|
-
state: ItemState;
|
|
89
|
-
linterContext: LinterContextProps;
|
|
90
|
-
};
|
|
91
|
-
|
|
92
|
-
type DefaultDraggableProps = {
|
|
93
|
-
includePadding: DraggableProps["includePadding"];
|
|
94
|
-
type: DraggableProps["state"];
|
|
95
|
-
linterContext: DraggableProps["linterContext"];
|
|
96
|
-
};
|
|
97
|
-
|
|
98
|
-
type DraggableState = {
|
|
99
|
-
startPosition: Position;
|
|
100
|
-
startMouse: Position;
|
|
101
|
-
mouse: Position;
|
|
102
|
-
dragging?: boolean;
|
|
103
|
-
};
|
|
104
|
-
|
|
105
|
-
// A draggable item in the sortable. Can be in one of four states:
|
|
106
|
-
// Static: The item is not being interacted with.
|
|
107
|
-
// Dragging: The item is being dragged.
|
|
108
|
-
// Animating: The item has been released, and is moving to its destination.
|
|
109
|
-
// Disabled: The item cannot be interacted with.
|
|
110
|
-
//
|
|
111
|
-
// Usual flow: Static -> Dragging -> Animating -> Static
|
|
112
|
-
// [Dis|en]abling: Static|Dragging|Animating -> Disabled -> Static
|
|
113
|
-
class Draggable extends React.Component<DraggableProps, DraggableState> {
|
|
114
|
-
// Handler returned by requestAnimationFrame.
|
|
115
|
-
animationFrameRequest = null;
|
|
116
|
-
// @ts-expect-error - TS2564 - Property 'isMouseMoveUpBound' has no initializer and is not definitely assigned in the constructor.
|
|
117
|
-
isMouseMoveUpBound: boolean;
|
|
118
|
-
// @ts-expect-error - TS2564 - Property '_mounted' has no initializer and is not definitely assigned in the constructor.
|
|
119
|
-
_mounted: boolean;
|
|
120
|
-
|
|
121
|
-
static defaultProps: DefaultDraggableProps = {
|
|
122
|
-
includePadding: true,
|
|
123
|
-
type: ItemState.STATIC,
|
|
124
|
-
linterContext: PerseusLinter.linterContextDefault,
|
|
125
|
-
};
|
|
126
|
-
|
|
127
|
-
state: DraggableState = {
|
|
128
|
-
startPosition: {left: 0, top: 0},
|
|
129
|
-
startMouse: {left: 0, top: 0},
|
|
130
|
-
mouse: {left: 0, top: 0},
|
|
131
|
-
dragging: false,
|
|
132
|
-
};
|
|
133
|
-
|
|
134
|
-
componentDidMount() {
|
|
135
|
-
this._mounted = true;
|
|
136
|
-
this.isMouseMoveUpBound = false;
|
|
137
|
-
|
|
138
|
-
// On touch devices, we set up our own touchmove handler because React
|
|
139
|
-
// all event subscriptions using `OnTouchMove` props are non-passive.
|
|
140
|
-
// See: https://github.com/facebook/react/issues/6436
|
|
141
|
-
// Also, we can't subscribe to `ontouchmove` within the `ontouchstart`
|
|
142
|
-
// handler because of a WebKit bug:
|
|
143
|
-
// https://github.com/atlassian/react-beautiful-dnd/issues/413 and
|
|
144
|
-
// https://bugs.webkit.org/show_bug.cgi?id=184250
|
|
145
|
-
document.addEventListener(
|
|
146
|
-
"touchmove",
|
|
147
|
-
this.onMouseMove,
|
|
148
|
-
// Not all browsers support passive events, and when they don't
|
|
149
|
-
// this third paramter is just a boolean. If we pass the "options"
|
|
150
|
-
// object, it's interpreted as `capture=true` (which we don't want!)
|
|
151
|
-
Util.supportsPassiveEvents() ? {passive: false} : false,
|
|
152
|
-
);
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
componentWillUnmount() {
|
|
156
|
-
this._mounted = false;
|
|
157
|
-
// Event handlers should be unbound before component unmounting, but
|
|
158
|
-
// just in case...
|
|
159
|
-
if (this.isMouseMoveUpBound) {
|
|
160
|
-
this.unbindMouseMoveUp();
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
if (this.animationFrameRequest) {
|
|
164
|
-
// TODO(jeff, CP-3128): Use Wonder Blocks Timing API.
|
|
165
|
-
// eslint-disable-next-line no-restricted-syntax
|
|
166
|
-
cancelAnimationFrame(this.animationFrameRequest);
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
document.removeEventListener("touchmove", this.onMouseMove);
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
getCurrentPosition = () => {
|
|
173
|
-
return {
|
|
174
|
-
left:
|
|
175
|
-
this.state.startPosition.left +
|
|
176
|
-
this.state.mouse.left -
|
|
177
|
-
this.state.startMouse.left,
|
|
178
|
-
top:
|
|
179
|
-
this.state.startPosition.top +
|
|
180
|
-
this.state.mouse.top -
|
|
181
|
-
this.state.startMouse.top,
|
|
182
|
-
};
|
|
183
|
-
};
|
|
184
|
-
|
|
185
|
-
render(): React.ReactNode {
|
|
186
|
-
const {includePadding, layout, state: type} = this.props;
|
|
187
|
-
|
|
188
|
-
// We need to keep backwards compatbility with rules specified directly
|
|
189
|
-
// in CSS. Hence the hacky tacking on of manual classNames.
|
|
190
|
-
// See sortable.less for details.
|
|
191
|
-
let className =
|
|
192
|
-
css(
|
|
193
|
-
styles.card,
|
|
194
|
-
styles.draggable,
|
|
195
|
-
layout === Layout.HORIZONTAL && styles.horizontalCard,
|
|
196
|
-
layout === Layout.VERTICAL && styles.verticalCard,
|
|
197
|
-
type === ItemState.DRAGGING && styles.dragging,
|
|
198
|
-
type === ItemState.DISABLED && styles.disabled,
|
|
199
|
-
!includePadding && styles.unpaddedCard,
|
|
200
|
-
) +
|
|
201
|
-
" " +
|
|
202
|
-
ApiClassNames.INTERACTIVE +
|
|
203
|
-
" perseus-sortable-draggable";
|
|
204
|
-
|
|
205
|
-
if (!includePadding) {
|
|
206
|
-
className += " perseus-sortable-draggable-unpadded";
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
const style: any = {
|
|
210
|
-
position: "static",
|
|
211
|
-
};
|
|
212
|
-
|
|
213
|
-
if (
|
|
214
|
-
this.props.state === ItemState.DRAGGING ||
|
|
215
|
-
this.props.state === ItemState.ANIMATING
|
|
216
|
-
) {
|
|
217
|
-
_.extend(style, {position: "absolute"}, this.getCurrentPosition());
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
if (this.props.width) {
|
|
221
|
-
style.width = this.props.width + 1; // Fix for non-integer widths
|
|
222
|
-
}
|
|
223
|
-
if (this.props.height) {
|
|
224
|
-
style.height = this.props.height;
|
|
225
|
-
}
|
|
226
|
-
if (this.props.margin != null) {
|
|
227
|
-
style.margin = this.props.margin;
|
|
228
|
-
}
|
|
229
|
-
return (
|
|
230
|
-
<li
|
|
231
|
-
className={className}
|
|
232
|
-
style={style}
|
|
233
|
-
onMouseDown={this.onMouseDown}
|
|
234
|
-
onTouchStart={this.onMouseDown}
|
|
235
|
-
onTouchMove={this.onMouseMove}
|
|
236
|
-
onTouchEnd={this.onMouseUp}
|
|
237
|
-
onTouchCancel={this.onMouseUp}
|
|
238
|
-
>
|
|
239
|
-
<Renderer
|
|
240
|
-
content={this.props.content}
|
|
241
|
-
linterContext={PerseusLinter.pushContextStack(
|
|
242
|
-
this.props.linterContext,
|
|
243
|
-
"draggable",
|
|
244
|
-
)}
|
|
245
|
-
onRender={this.props.onRender}
|
|
246
|
-
/>
|
|
247
|
-
</li>
|
|
248
|
-
);
|
|
249
|
-
}
|
|
250
|
-
|
|
251
|
-
componentDidUpdate(prevProps: DraggableProps) {
|
|
252
|
-
if (this.props.state === prevProps.state) {
|
|
253
|
-
return;
|
|
254
|
-
}
|
|
255
|
-
|
|
256
|
-
if (
|
|
257
|
-
this.props.state === ItemState.ANIMATING &&
|
|
258
|
-
this.props.endPosition
|
|
259
|
-
) {
|
|
260
|
-
// Start animating
|
|
261
|
-
const current = this.getCurrentPosition();
|
|
262
|
-
const duration =
|
|
263
|
-
15 *
|
|
264
|
-
Math.sqrt(
|
|
265
|
-
Math.sqrt(
|
|
266
|
-
Math.pow(
|
|
267
|
-
this.props.endPosition.left - current.left,
|
|
268
|
-
2,
|
|
269
|
-
) +
|
|
270
|
-
Math.pow(
|
|
271
|
-
this.props.endPosition.top - current.top,
|
|
272
|
-
2,
|
|
273
|
-
),
|
|
274
|
-
),
|
|
275
|
-
);
|
|
276
|
-
|
|
277
|
-
// @ts-expect-error - TS2769 - No overload matches this call. | TS2339 - Property 'animate' does not exist on type 'JQueryStatic'.
|
|
278
|
-
$(ReactDOM.findDOMNode(this)).animate(this.props.endPosition, {
|
|
279
|
-
duration: Math.max(duration, 1),
|
|
280
|
-
// Animating -> Static
|
|
281
|
-
complete: this.props.onAnimationEnd,
|
|
282
|
-
});
|
|
283
|
-
} else if (this.props.state === ItemState.STATIC) {
|
|
284
|
-
// Ensure that any animations are done
|
|
285
|
-
// @ts-expect-error - TS2769 - No overload matches this call. | TS2339 - Property 'finish' does not exist on type 'JQueryStatic'.
|
|
286
|
-
$(ReactDOM.findDOMNode(this)).finish();
|
|
287
|
-
}
|
|
288
|
-
}
|
|
289
|
-
|
|
290
|
-
bindMouseMoveUp = () => {
|
|
291
|
-
this.isMouseMoveUpBound = true;
|
|
292
|
-
$(document).on("mousemove", this.onMouseMove);
|
|
293
|
-
$(document).on("mouseup", this.onMouseUp);
|
|
294
|
-
};
|
|
295
|
-
|
|
296
|
-
unbindMouseMoveUp = () => {
|
|
297
|
-
this.isMouseMoveUpBound = false;
|
|
298
|
-
$(document).off("mousemove", this.onMouseMove);
|
|
299
|
-
$(document).off("mouseup", this.onMouseUp);
|
|
300
|
-
};
|
|
301
|
-
|
|
302
|
-
onMouseDown = (event) => {
|
|
303
|
-
if (this.props.state !== ItemState.STATIC) {
|
|
304
|
-
return;
|
|
305
|
-
}
|
|
306
|
-
|
|
307
|
-
if (
|
|
308
|
-
!(
|
|
309
|
-
event.button === 0 ||
|
|
310
|
-
(event.touches != null && event.touches.length === 1)
|
|
311
|
-
)
|
|
312
|
-
) {
|
|
313
|
-
return;
|
|
314
|
-
}
|
|
315
|
-
|
|
316
|
-
event.preventDefault();
|
|
317
|
-
const loc = Util.extractPointerLocation(event);
|
|
318
|
-
|
|
319
|
-
// TODO(jeff, CP-3128): Use Wonder Blocks Timing API.
|
|
320
|
-
// eslint-disable-next-line no-restricted-syntax
|
|
321
|
-
// @ts-expect-error - TS2322 - Type 'number' is not assignable to type 'null'.
|
|
322
|
-
this.animationFrameRequest = requestAnimationFrame(() => {
|
|
323
|
-
// @ts-expect-error - TS2769 - No overload matches this call.
|
|
324
|
-
const $el = $(ReactDOM.findDOMNode(this));
|
|
325
|
-
|
|
326
|
-
// jQuery.position() gets the position of the element wrt its offset parent,
|
|
327
|
-
// but subtracts the scroll position of the parent. We need to add that back.
|
|
328
|
-
// @ts-expect-error - TS2339 - Property 'position' does not exist on type 'JQueryStatic'.
|
|
329
|
-
const position = $el.position();
|
|
330
|
-
const startPosition = addOffsetParentScroll($el, position);
|
|
331
|
-
|
|
332
|
-
if (loc && this._mounted) {
|
|
333
|
-
this.setState(
|
|
334
|
-
{
|
|
335
|
-
startPosition,
|
|
336
|
-
// NOTE(slim): We don't bother adjusting `loc` because we only keep track of (mouse - startMouse) in
|
|
337
|
-
// this.getCurrentPosition(). Adjusting `loc` here requires us to also change how `loc` is used in
|
|
338
|
-
// onMouseMove and onMouseUp, and this requires reading from the DOM each time to measure the parent's scrollTop.
|
|
339
|
-
startMouse: loc,
|
|
340
|
-
mouse: loc,
|
|
341
|
-
dragging: true,
|
|
342
|
-
},
|
|
343
|
-
function () {
|
|
344
|
-
// @ts-expect-error - TS2683 - 'this' implicitly has type 'any' because it does not have a type annotation.
|
|
345
|
-
this.bindMouseMoveUp();
|
|
346
|
-
|
|
347
|
-
// Static -> Dragging
|
|
348
|
-
// @ts-expect-error - TS2683 - 'this' implicitly has type 'any' because it does not have a type annotation.
|
|
349
|
-
this.props.onMouseDown();
|
|
350
|
-
},
|
|
351
|
-
);
|
|
352
|
-
}
|
|
353
|
-
});
|
|
354
|
-
};
|
|
355
|
-
|
|
356
|
-
onMouseMove: (arg1: any) => void = (event) => {
|
|
357
|
-
const notDragging =
|
|
358
|
-
this.props.state !== ItemState.DRAGGING || !this.state.dragging;
|
|
359
|
-
|
|
360
|
-
if (notDragging) {
|
|
361
|
-
return;
|
|
362
|
-
}
|
|
363
|
-
|
|
364
|
-
event.preventDefault();
|
|
365
|
-
const loc = Util.extractPointerLocation(event);
|
|
366
|
-
|
|
367
|
-
if (loc) {
|
|
368
|
-
// TODO(jeff, CP-3128): Use Wonder Blocks Timing API.
|
|
369
|
-
// eslint-disable-next-line no-restricted-syntax
|
|
370
|
-
// @ts-expect-error - TS2322 - Type 'number' is not assignable to type 'null'.
|
|
371
|
-
this.animationFrameRequest = requestAnimationFrame(() => {
|
|
372
|
-
this.setState(
|
|
373
|
-
{
|
|
374
|
-
mouse: loc,
|
|
375
|
-
},
|
|
376
|
-
this.props.onMouseMove,
|
|
377
|
-
);
|
|
378
|
-
});
|
|
379
|
-
}
|
|
380
|
-
};
|
|
381
|
-
|
|
382
|
-
onMouseUp: (arg1: any) => void = (event) => {
|
|
383
|
-
const notDragging =
|
|
384
|
-
this.props.state !== ItemState.DRAGGING || !this.state.dragging;
|
|
385
|
-
|
|
386
|
-
if (notDragging) {
|
|
387
|
-
return;
|
|
388
|
-
}
|
|
389
|
-
|
|
390
|
-
event.preventDefault();
|
|
391
|
-
const loc = Util.extractPointerLocation(event);
|
|
392
|
-
if (loc) {
|
|
393
|
-
this.setState({dragging: false});
|
|
394
|
-
this.unbindMouseMoveUp();
|
|
395
|
-
|
|
396
|
-
// Dragging -> Animating
|
|
397
|
-
this.props.onMouseUp();
|
|
398
|
-
}
|
|
399
|
-
};
|
|
400
|
-
}
|
|
401
|
-
|
|
402
|
-
export type SortableOption = string;
|
|
403
|
-
|
|
404
|
-
type SortableProps = {
|
|
405
|
-
constraints:
|
|
406
|
-
| {
|
|
407
|
-
width: number;
|
|
408
|
-
height: number;
|
|
409
|
-
}
|
|
410
|
-
| Record<any, any>;
|
|
411
|
-
disabled: boolean;
|
|
412
|
-
layout: Layout;
|
|
413
|
-
margin: number;
|
|
414
|
-
onChange: (arg1: any) => void;
|
|
415
|
-
onMeasure: (arg1: {
|
|
416
|
-
widths: ReadonlyArray<number>;
|
|
417
|
-
heights: ReadonlyArray<number>;
|
|
418
|
-
}) => void;
|
|
419
|
-
padding: boolean;
|
|
420
|
-
linterContext: LinterContextProps;
|
|
421
|
-
options: ReadonlyArray<SortableOption>;
|
|
422
|
-
waitForTexRendererToLoad: boolean;
|
|
423
|
-
};
|
|
424
|
-
|
|
425
|
-
type DefaultProps = {
|
|
426
|
-
constraints: SortableProps["constraints"];
|
|
427
|
-
disabled: SortableProps["disabled"];
|
|
428
|
-
layout: SortableProps["layout"];
|
|
429
|
-
margin: SortableProps["margin"];
|
|
430
|
-
onChange: SortableProps["onChange"];
|
|
431
|
-
onMeasure: SortableProps["onMeasure"];
|
|
432
|
-
padding: SortableProps["padding"];
|
|
433
|
-
linterContext: SortableProps["linterContext"];
|
|
434
|
-
waitForTexRendererToLoad: SortableProps["waitForTexRendererToLoad"];
|
|
435
|
-
};
|
|
436
|
-
|
|
437
|
-
type SortableItem = {
|
|
438
|
-
option: SortableOption;
|
|
439
|
-
key: number;
|
|
440
|
-
state: ItemState;
|
|
441
|
-
endPosition?: Position;
|
|
442
|
-
width: number;
|
|
443
|
-
height: number;
|
|
444
|
-
};
|
|
445
|
-
|
|
446
|
-
type SortableState = {
|
|
447
|
-
items: ReadonlyArray<SortableItem>;
|
|
448
|
-
texRendererLoaded: boolean;
|
|
449
|
-
};
|
|
450
|
-
class Sortable extends React.Component<SortableProps, SortableState> {
|
|
451
|
-
static defaultProps: DefaultProps = {
|
|
452
|
-
layout: Layout.HORIZONTAL,
|
|
453
|
-
padding: true,
|
|
454
|
-
disabled: false,
|
|
455
|
-
constraints: {},
|
|
456
|
-
onMeasure: function () {},
|
|
457
|
-
margin: 5,
|
|
458
|
-
onChange: function () {},
|
|
459
|
-
linterContext: PerseusLinter.linterContextDefault,
|
|
460
|
-
waitForTexRendererToLoad: true,
|
|
461
|
-
};
|
|
462
|
-
|
|
463
|
-
constructor(props: SortableProps) {
|
|
464
|
-
super(props);
|
|
465
|
-
// Don't call this.setState() here!
|
|
466
|
-
this.state = {
|
|
467
|
-
items: Sortable.itemsFromProps(this.props),
|
|
468
|
-
texRendererLoaded: false,
|
|
469
|
-
};
|
|
470
|
-
}
|
|
471
|
-
|
|
472
|
-
UNSAFE_componentWillReceiveProps(nextProps: SortableProps) {
|
|
473
|
-
const prevProps = this.props;
|
|
474
|
-
|
|
475
|
-
if (!_.isEqual(nextProps.options, prevProps.options)) {
|
|
476
|
-
// Regenerate items
|
|
477
|
-
this.setState({
|
|
478
|
-
items: Sortable.itemsFromProps(nextProps),
|
|
479
|
-
});
|
|
480
|
-
} else if (
|
|
481
|
-
nextProps.layout !== prevProps.layout ||
|
|
482
|
-
nextProps.padding !== prevProps.padding ||
|
|
483
|
-
nextProps.disabled !== prevProps.disabled ||
|
|
484
|
-
!_.isEqual(nextProps.constraints, prevProps.constraints)
|
|
485
|
-
) {
|
|
486
|
-
// Clear item measurements
|
|
487
|
-
this.setState({
|
|
488
|
-
items: Sortable.clearItemMeasurements(this.state.items),
|
|
489
|
-
});
|
|
490
|
-
}
|
|
491
|
-
}
|
|
492
|
-
|
|
493
|
-
componentDidUpdate() {
|
|
494
|
-
// Measure items if their dimensions have been reset
|
|
495
|
-
if (
|
|
496
|
-
this.state.items.length &&
|
|
497
|
-
!this.state.items[0].width &&
|
|
498
|
-
!this.state.items[0].height
|
|
499
|
-
) {
|
|
500
|
-
// Measure on the next frame to allow items size to settle.
|
|
501
|
-
// TODO(jeff, CP-3128): Use Wonder Blocks Timing API.
|
|
502
|
-
// eslint-disable-next-line no-restricted-syntax
|
|
503
|
-
setTimeout(() => {
|
|
504
|
-
this.measureItems();
|
|
505
|
-
}, 0);
|
|
506
|
-
}
|
|
507
|
-
}
|
|
508
|
-
|
|
509
|
-
static itemsFromProps(props: {
|
|
510
|
-
disabled: boolean;
|
|
511
|
-
options: ReadonlyArray<SortableOption>;
|
|
512
|
-
}): ReadonlyArray<SortableItem> {
|
|
513
|
-
const state: ItemState = props.disabled
|
|
514
|
-
? ItemState.DISABLED
|
|
515
|
-
: ItemState.STATIC;
|
|
516
|
-
return props.options.map((option: SortableOption, i) => {
|
|
517
|
-
return {
|
|
518
|
-
option: option,
|
|
519
|
-
key: i,
|
|
520
|
-
state,
|
|
521
|
-
width: 0,
|
|
522
|
-
height: 0,
|
|
523
|
-
};
|
|
524
|
-
});
|
|
525
|
-
}
|
|
526
|
-
|
|
527
|
-
static clearItemMeasurements(
|
|
528
|
-
items: ReadonlyArray<SortableItem>,
|
|
529
|
-
): ReadonlyArray<SortableItem> {
|
|
530
|
-
return items.map((item) => {
|
|
531
|
-
return {
|
|
532
|
-
...item,
|
|
533
|
-
width: 0,
|
|
534
|
-
height: 0,
|
|
535
|
-
};
|
|
536
|
-
});
|
|
537
|
-
}
|
|
538
|
-
|
|
539
|
-
measureItems() {
|
|
540
|
-
// Measure all items and cache what their dimensions should be, taking
|
|
541
|
-
// into account constraints and the current layout. This allows syncing
|
|
542
|
-
// widths and heights for pretty rows/columns. Note that dimensions are
|
|
543
|
-
// explictly set on Draggables - this prevents them from changing size
|
|
544
|
-
// or shape while being dragged.
|
|
545
|
-
|
|
546
|
-
let items: ReadonlyArray<SortableItem> = [...this.state.items];
|
|
547
|
-
|
|
548
|
-
// Fetches a jQuery list of elements for each item
|
|
549
|
-
const $items = _.map(
|
|
550
|
-
items,
|
|
551
|
-
function (item) {
|
|
552
|
-
// eslint-disable-next-line react/no-string-refs
|
|
553
|
-
// @ts-expect-error - TS2769 - No overload matches this call. | TS2683 - 'this' implicitly has type 'any' because it does not have a type annotation.
|
|
554
|
-
return $(ReactDOM.findDOMNode(this.refs[item.key]));
|
|
555
|
-
},
|
|
556
|
-
this,
|
|
557
|
-
);
|
|
558
|
-
|
|
559
|
-
const widths: ReadonlyArray<number> = _.invoke($items, "outerWidth");
|
|
560
|
-
const heights: ReadonlyArray<number> = _.invoke($items, "outerHeight");
|
|
561
|
-
|
|
562
|
-
const {constraints, layout} = this.props;
|
|
563
|
-
|
|
564
|
-
let syncWidth: number | null = null;
|
|
565
|
-
if (constraints?.width) {
|
|
566
|
-
// Items must be at least as wide as the specified constraint
|
|
567
|
-
syncWidth = _.max(widths.concat(constraints.width));
|
|
568
|
-
} else if (layout === Layout.VERTICAL) {
|
|
569
|
-
// Sync widths to get a clean column
|
|
570
|
-
syncWidth = _.max(widths);
|
|
571
|
-
}
|
|
572
|
-
|
|
573
|
-
let syncHeight: number | null = null;
|
|
574
|
-
if (constraints?.height) {
|
|
575
|
-
// Items must be at least as high as the specified constraint
|
|
576
|
-
syncHeight = _.max(heights.concat(constraints.height));
|
|
577
|
-
} else if (layout === Layout.HORIZONTAL) {
|
|
578
|
-
// Sync widths to get a clean row
|
|
579
|
-
syncHeight = _.max(heights);
|
|
580
|
-
}
|
|
581
|
-
|
|
582
|
-
items = _.map(items, function (item, i) {
|
|
583
|
-
item.width = syncWidth || widths[i];
|
|
584
|
-
item.height = syncHeight || heights[i];
|
|
585
|
-
return item;
|
|
586
|
-
});
|
|
587
|
-
|
|
588
|
-
this.setState({items}, () => {
|
|
589
|
-
this.props.onMeasure &&
|
|
590
|
-
this.props.onMeasure({widths: widths, heights: heights});
|
|
591
|
-
});
|
|
592
|
-
}
|
|
593
|
-
|
|
594
|
-
remeasureItems: () => void = _.debounce(() => {
|
|
595
|
-
this.setState({
|
|
596
|
-
// Clear item measurements
|
|
597
|
-
items: Sortable.clearItemMeasurements(this.state.items),
|
|
598
|
-
});
|
|
599
|
-
}, 20);
|
|
600
|
-
|
|
601
|
-
render(): React.ReactNode {
|
|
602
|
-
// To minimize layout shift, we display a spinner until our math
|
|
603
|
-
// renderer is ready to render the math inside the sortable. To
|
|
604
|
-
// do this, we:
|
|
605
|
-
// - render a dummy TeX component to force the math renderer to load
|
|
606
|
-
// - display a spinner until the TeX component calls its onRender
|
|
607
|
-
// callback, signifying that the math is rendered (from which we can
|
|
608
|
-
// infer that the math renderer has loaded)
|
|
609
|
-
//
|
|
610
|
-
// If we didn't do this, the user might see a sortable with empty
|
|
611
|
-
// cells on first render, and then the math would pop in a few moments
|
|
612
|
-
// later once the rendering library loaded.
|
|
613
|
-
if (
|
|
614
|
-
this.props.waitForTexRendererToLoad &&
|
|
615
|
-
!this.state.texRendererLoaded
|
|
616
|
-
) {
|
|
617
|
-
const {TeX} = getDependencies();
|
|
618
|
-
return (
|
|
619
|
-
<>
|
|
620
|
-
<CircularSpinner />
|
|
621
|
-
<div style={{display: "none"}}>
|
|
622
|
-
<TeX
|
|
623
|
-
onRender={() =>
|
|
624
|
-
this.setState({texRendererLoaded: true})
|
|
625
|
-
}
|
|
626
|
-
>
|
|
627
|
-
1
|
|
628
|
-
</TeX>
|
|
629
|
-
</div>
|
|
630
|
-
</>
|
|
631
|
-
);
|
|
632
|
-
}
|
|
633
|
-
|
|
634
|
-
const cards: Array<
|
|
635
|
-
| React.ReactElement<React.ComponentProps<typeof Placeholder>>
|
|
636
|
-
| React.ReactElement<React.ComponentProps<typeof Draggable>>
|
|
637
|
-
> = [];
|
|
638
|
-
|
|
639
|
-
const {layout} = this.props;
|
|
640
|
-
// We need to keep backwards compatbility with rules specified directly
|
|
641
|
-
// in CSS. See sortable.less for details.
|
|
642
|
-
const className = css(styles.sortable) + " perseus-sortable";
|
|
643
|
-
|
|
644
|
-
const syncWidth =
|
|
645
|
-
this.props.constraints?.width || layout === Layout.VERTICAL;
|
|
646
|
-
const syncHeight =
|
|
647
|
-
this.props.constraints?.height || layout === Layout.HORIZONTAL;
|
|
648
|
-
|
|
649
|
-
_.each(
|
|
650
|
-
this.state.items,
|
|
651
|
-
function (item, i, items) {
|
|
652
|
-
const isLast = i === items.length - 1;
|
|
653
|
-
const isStatic =
|
|
654
|
-
item.state === ItemState.STATIC ||
|
|
655
|
-
item.state === ItemState.DISABLED;
|
|
656
|
-
let margin;
|
|
657
|
-
|
|
658
|
-
// @ts-expect-error - TS2683 - 'this' implicitly has type 'any' because it does not have a type annotation.
|
|
659
|
-
if (this.props.layout === Layout.HORIZONTAL) {
|
|
660
|
-
// @ts-expect-error - TS2683 - 'this' implicitly has type 'any' because it does not have a type annotation.
|
|
661
|
-
margin = "0 " + this.props.margin + "px 0 0"; // right
|
|
662
|
-
// @ts-expect-error - TS2683 - 'this' implicitly has type 'any' because it does not have a type annotation.
|
|
663
|
-
} else if (this.props.layout === Layout.VERTICAL) {
|
|
664
|
-
// @ts-expect-error - TS2683 - 'this' implicitly has type 'any' because it does not have a type annotation.
|
|
665
|
-
margin = "0 0 " + this.props.margin + "px 0"; // bottom
|
|
666
|
-
}
|
|
667
|
-
|
|
668
|
-
cards.push(
|
|
669
|
-
<Draggable
|
|
670
|
-
content={item.option}
|
|
671
|
-
key={item.key}
|
|
672
|
-
state={item.state}
|
|
673
|
-
// @ts-expect-error - TS2769 - No overload matches this call.
|
|
674
|
-
ref={item.key}
|
|
675
|
-
width={syncWidth ? item.width : undefined}
|
|
676
|
-
height={syncHeight ? item.height : undefined}
|
|
677
|
-
layout={layout}
|
|
678
|
-
// @ts-expect-error - TS2683 - 'this' implicitly has type 'any' because it does not have a type annotation.
|
|
679
|
-
includePadding={this.props.padding}
|
|
680
|
-
margin={isLast && isStatic ? 0 : margin}
|
|
681
|
-
endPosition={item.endPosition}
|
|
682
|
-
linterContext={PerseusLinter.pushContextStack(
|
|
683
|
-
// @ts-expect-error - TS2683 - 'this' implicitly has type 'any' because it does not have a type annotation.
|
|
684
|
-
this.props.linterContext,
|
|
685
|
-
"sortable",
|
|
686
|
-
)}
|
|
687
|
-
// @ts-expect-error - TS2683 - 'this' implicitly has type 'any' because it does not have a type annotation.
|
|
688
|
-
onRender={this.remeasureItems}
|
|
689
|
-
// eslint-disable-next-line react/jsx-no-bind
|
|
690
|
-
// @ts-expect-error - TS2683 - 'this' implicitly has type 'any' because it does not have a type annotation. | TS2683 - 'this' implicitly has type 'any' because it does not have a type annotation.
|
|
691
|
-
onMouseDown={this.onMouseDown.bind(this, item.key)}
|
|
692
|
-
// eslint-disable-next-line react/jsx-no-bind
|
|
693
|
-
// @ts-expect-error - TS2683 - 'this' implicitly has type 'any' because it does not have a type annotation. | TS2683 - 'this' implicitly has type 'any' because it does not have a type annotation.
|
|
694
|
-
onMouseMove={this.onMouseMove.bind(this, item.key)}
|
|
695
|
-
// eslint-disable-next-line react/jsx-no-bind
|
|
696
|
-
// @ts-expect-error - TS2683 - 'this' implicitly has type 'any' because it does not have a type annotation. | TS2683 - 'this' implicitly has type 'any' because it does not have a type annotation.
|
|
697
|
-
onMouseUp={this.onMouseUp.bind(this, item.key)}
|
|
698
|
-
// eslint-disable-next-line react/jsx-no-bind
|
|
699
|
-
// @ts-expect-error - TS2683 - 'this' implicitly has type 'any' because it does not have a type annotation. | TS2683 - 'this' implicitly has type 'any' because it does not have a type annotation.
|
|
700
|
-
onTouchMove={this.onMouseMove.bind(this, item.key)}
|
|
701
|
-
// eslint-disable-next-line react/jsx-no-bind
|
|
702
|
-
// @ts-expect-error - TS2683 - 'this' implicitly has type 'any' because it does not have a type annotation. | TS2683 - 'this' implicitly has type 'any' because it does not have a type annotation.
|
|
703
|
-
onTouchEnd={this.onMouseUp.bind(this, item.key)}
|
|
704
|
-
// eslint-disable-next-line react/jsx-no-bind
|
|
705
|
-
// @ts-expect-error - TS2683 - 'this' implicitly has type 'any' because it does not have a type annotation. | TS2683 - 'this' implicitly has type 'any' because it does not have a type annotation.
|
|
706
|
-
onTouchCancel={this.onMouseUp.bind(this, item.key)}
|
|
707
|
-
// eslint-disable-next-line react/jsx-no-bind
|
|
708
|
-
// @ts-expect-error - TS2683 - 'this' implicitly has type 'any' because it does not have a type annotation.
|
|
709
|
-
onAnimationEnd={this.onAnimationEnd.bind(
|
|
710
|
-
// @ts-expect-error - TS2683 - 'this' implicitly has type 'any' because it does not have a type annotation.
|
|
711
|
-
this,
|
|
712
|
-
item.key,
|
|
713
|
-
)}
|
|
714
|
-
/>,
|
|
715
|
-
);
|
|
716
|
-
|
|
717
|
-
if (
|
|
718
|
-
item.state === ItemState.DRAGGING ||
|
|
719
|
-
item.state === ItemState.ANIMATING
|
|
720
|
-
) {
|
|
721
|
-
cards.push(
|
|
722
|
-
<Placeholder
|
|
723
|
-
key={"placeholder_" + item.key}
|
|
724
|
-
ref={"placeholder_" + item.key}
|
|
725
|
-
width={item.width}
|
|
726
|
-
height={item.height}
|
|
727
|
-
layout={layout}
|
|
728
|
-
margin={isLast ? 0 : margin}
|
|
729
|
-
/>,
|
|
730
|
-
);
|
|
731
|
-
}
|
|
732
|
-
},
|
|
733
|
-
this,
|
|
734
|
-
);
|
|
735
|
-
|
|
736
|
-
return <ul className={className}>{cards}</ul>;
|
|
737
|
-
}
|
|
738
|
-
|
|
739
|
-
onMouseDown(key: SortableItem["key"]) {
|
|
740
|
-
// Static -> Dragging
|
|
741
|
-
const items = _.map(this.state.items, function (item) {
|
|
742
|
-
if (item.key === key) {
|
|
743
|
-
item.state = ItemState.DRAGGING;
|
|
744
|
-
}
|
|
745
|
-
return item;
|
|
746
|
-
});
|
|
747
|
-
|
|
748
|
-
this.setState({items: items});
|
|
749
|
-
}
|
|
750
|
-
|
|
751
|
-
// This is public API and it's ok for components that use
|
|
752
|
-
// this sortable to call this.
|
|
753
|
-
// moveOptionToIndex takes an option and a desired index and
|
|
754
|
-
// will move that item to the desired index. This is useful
|
|
755
|
-
// for testing and other cases where dragging and dropping may
|
|
756
|
-
// not be available
|
|
757
|
-
moveOptionToIndex(option: SortableOption, index: number) {
|
|
758
|
-
const {items} = this.state;
|
|
759
|
-
|
|
760
|
-
if (index < 0 || index > items.length) {
|
|
761
|
-
throw new Error(`index ${index} out of bounds`);
|
|
762
|
-
}
|
|
763
|
-
|
|
764
|
-
const nextItems = _.clone(items);
|
|
765
|
-
|
|
766
|
-
const item = items.filter((item: SortableItem) => {
|
|
767
|
-
return item.option === option;
|
|
768
|
-
})[0];
|
|
769
|
-
|
|
770
|
-
if (item == null) {
|
|
771
|
-
throw new Error(`option ${option} not found`);
|
|
772
|
-
}
|
|
773
|
-
|
|
774
|
-
const currentIndex = items.findIndex((i: SortableItem) => {
|
|
775
|
-
return i.key === item.key;
|
|
776
|
-
});
|
|
777
|
-
|
|
778
|
-
// @ts-expect-error - TS2551 - Property 'splice' does not exist on type 'readonly SortableItem[]'. Did you mean 'slice'?
|
|
779
|
-
nextItems.splice(currentIndex, 1);
|
|
780
|
-
// @ts-expect-error - TS2551 - Property 'splice' does not exist on type 'readonly SortableItem[]'. Did you mean 'slice'?
|
|
781
|
-
nextItems.splice(index, 0, item);
|
|
782
|
-
|
|
783
|
-
this.setState({items: nextItems});
|
|
784
|
-
this.props.onChange && this.props.onChange({});
|
|
785
|
-
}
|
|
786
|
-
|
|
787
|
-
onMouseMove(key: SortableItem["key"]) {
|
|
788
|
-
// Dragging: Rearrange items based on draggable's position
|
|
789
|
-
// eslint-disable-next-line react/no-string-refs
|
|
790
|
-
// @ts-expect-error - TS2769 - No overload matches this call.
|
|
791
|
-
const $draggable = $(ReactDOM.findDOMNode(this.refs[key]));
|
|
792
|
-
// @ts-expect-error - TS2769 - No overload matches this call.
|
|
793
|
-
const $sortable = $(ReactDOM.findDOMNode(this));
|
|
794
|
-
const items = _.clone(this.state.items);
|
|
795
|
-
const item = _.findWhere(this.state.items, {key: key});
|
|
796
|
-
const margin = this.props.margin || 0;
|
|
797
|
-
// @ts-expect-error - TS2345 - Argument of type 'SortableItem | undefined' is not assignable to parameter of type 'SortableItem'.
|
|
798
|
-
const currentIndex = _.indexOf(items, item);
|
|
799
|
-
let newIndex = 0;
|
|
800
|
-
|
|
801
|
-
// @ts-expect-error - TS2551 - Property 'splice' does not exist on type 'readonly SortableItem[]'. Did you mean 'slice'?
|
|
802
|
-
items.splice(currentIndex, 1);
|
|
803
|
-
|
|
804
|
-
if (this.props.layout === Layout.HORIZONTAL) {
|
|
805
|
-
// @ts-expect-error - TS2339 - Property 'offset' does not exist on type 'JQueryStatic'. | TS2339 - Property 'offset' does not exist on type 'JQueryStatic'.
|
|
806
|
-
const midWidth = $draggable.offset().left - $sortable.offset().left;
|
|
807
|
-
let sumWidth = 0;
|
|
808
|
-
let cardWidth;
|
|
809
|
-
|
|
810
|
-
_.each(items, function (item) {
|
|
811
|
-
cardWidth = item.width;
|
|
812
|
-
if (midWidth > sumWidth + cardWidth / 2) {
|
|
813
|
-
newIndex += 1;
|
|
814
|
-
}
|
|
815
|
-
sumWidth += cardWidth + margin;
|
|
816
|
-
});
|
|
817
|
-
} else {
|
|
818
|
-
// @ts-expect-error - TS2339 - Property 'offset' does not exist on type 'JQueryStatic'. | TS2339 - Property 'offset' does not exist on type 'JQueryStatic'.
|
|
819
|
-
const midHeight = $draggable.offset().top - $sortable.offset().top;
|
|
820
|
-
let sumHeight = 0;
|
|
821
|
-
let cardHeight;
|
|
822
|
-
|
|
823
|
-
_.each(items, function (item) {
|
|
824
|
-
cardHeight = item.height;
|
|
825
|
-
if (midHeight > sumHeight + cardHeight / 2) {
|
|
826
|
-
newIndex += 1;
|
|
827
|
-
}
|
|
828
|
-
sumHeight += cardHeight + margin;
|
|
829
|
-
});
|
|
830
|
-
}
|
|
831
|
-
|
|
832
|
-
if (newIndex !== currentIndex) {
|
|
833
|
-
// @ts-expect-error - TS2551 - Property 'splice' does not exist on type 'readonly SortableItem[]'. Did you mean 'slice'?
|
|
834
|
-
items.splice(newIndex, 0, item);
|
|
835
|
-
this.setState({items: items});
|
|
836
|
-
}
|
|
837
|
-
}
|
|
838
|
-
|
|
839
|
-
onMouseUp(key: SortableItem["key"]) {
|
|
840
|
-
// Dragging -> Animating
|
|
841
|
-
// TODO(jeff, CP-3128): Use Wonder Blocks Timing API.
|
|
842
|
-
// eslint-disable-next-line no-restricted-syntax
|
|
843
|
-
const nextAnimationFrame = requestAnimationFrame(() => {
|
|
844
|
-
const items = _.map(
|
|
845
|
-
this.state.items,
|
|
846
|
-
function (item) {
|
|
847
|
-
if (item.key === key) {
|
|
848
|
-
item.state = ItemState.ANIMATING;
|
|
849
|
-
const $placeholder = $(
|
|
850
|
-
// @ts-expect-error - TS2769 - No overload matches this call.
|
|
851
|
-
ReactDOM.findDOMNode(
|
|
852
|
-
// eslint-disable-next-line react/no-string-refs
|
|
853
|
-
// @ts-expect-error - TS2683 - 'this' implicitly has type 'any' because it does not have a type annotation.
|
|
854
|
-
this.refs["placeholder_" + key],
|
|
855
|
-
),
|
|
856
|
-
);
|
|
857
|
-
// @ts-expect-error - TS2339 - Property 'position' does not exist on type 'JQueryStatic'.
|
|
858
|
-
const position = $placeholder.position();
|
|
859
|
-
const endPosition = addOffsetParentScroll(
|
|
860
|
-
$placeholder,
|
|
861
|
-
position,
|
|
862
|
-
);
|
|
863
|
-
item.endPosition = endPosition;
|
|
864
|
-
}
|
|
865
|
-
return item;
|
|
866
|
-
},
|
|
867
|
-
this,
|
|
868
|
-
);
|
|
869
|
-
|
|
870
|
-
this.setState({items: items});
|
|
871
|
-
// HACK: We need to know *that* the widget changed, but currently it's
|
|
872
|
-
// not set up in a nice way to tell us *how* it changed, since the
|
|
873
|
-
// permutation of the items is stored in state.
|
|
874
|
-
this.props.onChange && this.props.onChange({});
|
|
875
|
-
});
|
|
876
|
-
|
|
877
|
-
// @ts-expect-error - TS2339 - Property 'animationFrameRequest' does not exist on type 'Sortable'.
|
|
878
|
-
this.animationFrameRequest = nextAnimationFrame;
|
|
879
|
-
}
|
|
880
|
-
|
|
881
|
-
onAnimationEnd(key: SortableItem["key"]) {
|
|
882
|
-
// Animating -> Static
|
|
883
|
-
const items = _.map(this.state.items, function (item) {
|
|
884
|
-
if (item.key === key) {
|
|
885
|
-
item.state = ItemState.STATIC;
|
|
886
|
-
}
|
|
887
|
-
return item;
|
|
888
|
-
});
|
|
889
|
-
|
|
890
|
-
this.setState({items: items});
|
|
891
|
-
}
|
|
892
|
-
|
|
893
|
-
getOptions(): ReadonlyArray<SortableOption> {
|
|
894
|
-
return _.pluck(this.state.items, "option");
|
|
895
|
-
}
|
|
896
|
-
}
|
|
897
|
-
|
|
898
|
-
const styles = StyleSheet.create({
|
|
899
|
-
sortable: {
|
|
900
|
-
boxSizing: "border-box",
|
|
901
|
-
float: "left",
|
|
902
|
-
|
|
903
|
-
padding: 0,
|
|
904
|
-
margin: 0,
|
|
905
|
-
},
|
|
906
|
-
|
|
907
|
-
card: {
|
|
908
|
-
boxSizing: "border-box",
|
|
909
|
-
background: "#fff",
|
|
910
|
-
border: "1px solid #ddd",
|
|
911
|
-
borderRadius: 4,
|
|
912
|
-
cursor: "pointer",
|
|
913
|
-
minWidth: 25,
|
|
914
|
-
minHeight: 44,
|
|
915
|
-
padding: 10,
|
|
916
|
-
|
|
917
|
-
listStyleType: "none",
|
|
918
|
-
|
|
919
|
-
userSelect: "none",
|
|
920
|
-
touchAction: "none",
|
|
921
|
-
},
|
|
922
|
-
|
|
923
|
-
placeholder: {
|
|
924
|
-
background: "#ddd",
|
|
925
|
-
border: "1px solid #ccc",
|
|
926
|
-
},
|
|
927
|
-
|
|
928
|
-
draggable: {
|
|
929
|
-
textAlign: "center",
|
|
930
|
-
},
|
|
931
|
-
|
|
932
|
-
horizontalCard: {
|
|
933
|
-
float: "left",
|
|
934
|
-
cursor: "ew-resize",
|
|
935
|
-
},
|
|
936
|
-
|
|
937
|
-
verticalCard: {
|
|
938
|
-
maxWidth: "100%",
|
|
939
|
-
cursor: "ns-resize",
|
|
940
|
-
},
|
|
941
|
-
|
|
942
|
-
unpaddedCard: {
|
|
943
|
-
padding: 0,
|
|
944
|
-
},
|
|
945
|
-
|
|
946
|
-
dragging: {
|
|
947
|
-
background: "#ffedcd",
|
|
948
|
-
opacity: 0.8,
|
|
949
|
-
},
|
|
950
|
-
|
|
951
|
-
disabled: {
|
|
952
|
-
backgroundColor: "inherit",
|
|
953
|
-
border: "1px solid transparent",
|
|
954
|
-
cursor: "default",
|
|
955
|
-
},
|
|
956
|
-
});
|
|
957
|
-
|
|
958
|
-
export default Sortable;
|