@khanacademy/perseus 19.1.5 → 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.
Files changed (478) hide show
  1. package/dist/es/index.js +1 -1
  2. package/dist/index.js +1 -1
  3. package/package.json +11 -8
  4. package/.babelrc.js +0 -8
  5. package/.eslintrc.js +0 -12
  6. package/CHANGELOG.md +0 -1432
  7. package/src/__stories__/article-renderer.stories.tsx +0 -100
  8. package/src/__stories__/hints-renderer.stories.tsx +0 -55
  9. package/src/__stories__/server-item-renderer.stories.tsx +0 -44
  10. package/src/__testdata__/article-renderer.testdata.ts +0 -212
  11. package/src/__testdata__/graphie.testdata.ts +0 -51
  12. package/src/__testdata__/renderer.testdata.ts +0 -274
  13. package/src/__testdata__/server-item-renderer.testdata.ts +0 -171
  14. package/src/__tests__/__snapshots__/perseus-markdown.test.ts.snap +0 -507
  15. package/src/__tests__/__snapshots__/renderer.test.tsx.snap +0 -525
  16. package/src/__tests__/__snapshots__/server-item-renderer.test.tsx.snap +0 -285
  17. package/src/__tests__/a11y.test.ts +0 -303
  18. package/src/__tests__/article-renderer.test.tsx +0 -130
  19. package/src/__tests__/error-boundary.test.tsx +0 -76
  20. package/src/__tests__/extract-perseus-data.test.ts +0 -1027
  21. package/src/__tests__/init.test.ts +0 -10
  22. package/src/__tests__/jipt-paragraphs.test.ts +0 -32
  23. package/src/__tests__/mock-asset-loading-widget.tsx +0 -53
  24. package/src/__tests__/mock-widget.tsx +0 -33
  25. package/src/__tests__/perseus-markdown.test.ts +0 -764
  26. package/src/__tests__/renderability.test.ts +0 -480
  27. package/src/__tests__/renderer-api.test.tsx +0 -302
  28. package/src/__tests__/renderer.test.tsx +0 -1816
  29. package/src/__tests__/server-item-renderer.test.tsx +0 -582
  30. package/src/__tests__/test-items/image-item.ts +0 -24
  31. package/src/__tests__/test-items/input-number-1-item.ts +0 -26
  32. package/src/__tests__/test-items/input-number-2-item.ts +0 -38
  33. package/src/__tests__/test-items/table-item.ts +0 -29
  34. package/src/__tests__/tex-wrangler.test.ts +0 -82
  35. package/src/__tests__/util.test.ts +0 -40
  36. package/src/__tests__/widget-container.test.tsx +0 -126
  37. package/src/__tests__/widgets.test.ts +0 -91
  38. package/src/a11y.ts +0 -45
  39. package/src/all-widgets.ts +0 -9
  40. package/src/article-renderer.tsx +0 -237
  41. package/src/asset-context.ts +0 -30
  42. package/src/basic-widgets.ts +0 -16
  43. package/src/components/__stories__/button-group.stories.tsx +0 -55
  44. package/src/components/__stories__/fixed-to-responsive.stories.tsx +0 -141
  45. package/src/components/__stories__/graph.stories.tsx +0 -28
  46. package/src/components/__stories__/graphie.stories.tsx +0 -33
  47. package/src/components/__stories__/hud.stories.tsx +0 -35
  48. package/src/components/__stories__/icon.stories.tsx +0 -63
  49. package/src/components/__stories__/image-loader.stories.tsx +0 -63
  50. package/src/components/__stories__/info-tip.stories.tsx +0 -31
  51. package/src/components/__stories__/inline-icon.stories.tsx +0 -40
  52. package/src/components/__stories__/input-with-examples.stories.tsx +0 -53
  53. package/src/components/__stories__/lint.stories.tsx +0 -86
  54. package/src/components/__stories__/math-input.stories.tsx +0 -43
  55. package/src/components/__stories__/math-output.stories.tsx +0 -23
  56. package/src/components/__stories__/multi-button-group.stories.tsx +0 -66
  57. package/src/components/__stories__/number-input.stories.tsx +0 -41
  58. package/src/components/__stories__/prop-check-box.stories.tsx +0 -65
  59. package/src/components/__stories__/range-input.stories.tsx +0 -29
  60. package/src/components/__stories__/simple-keypad-input.stories.tsx +0 -27
  61. package/src/components/__stories__/sortable.stories.tsx +0 -77
  62. package/src/components/__stories__/stub-tag-editor.stories.tsx +0 -45
  63. package/src/components/__stories__/svg-image.stories.tsx +0 -74
  64. package/src/components/__stories__/tex.stories.tsx +0 -23
  65. package/src/components/__stories__/text-input.stories.tsx +0 -33
  66. package/src/components/__stories__/text-list-editor.stories.tsx +0 -32
  67. package/src/components/__stories__/tooltip.stories.tsx +0 -52
  68. package/src/components/__stories__/zoomable-tex.stories.tsx +0 -41
  69. package/src/components/__stories__/zoomable.stories.tsx +0 -49
  70. package/src/components/__testdata__/sorter.testdata.ts +0 -19
  71. package/src/components/__tests__/__snapshots__/sortable.test.tsx.snap +0 -163
  72. package/src/components/__tests__/__snapshots__/sorter.test.tsx.snap +0 -265
  73. package/src/components/__tests__/math-input.test.tsx +0 -147
  74. package/src/components/__tests__/number-input.test.tsx +0 -128
  75. package/src/components/__tests__/sortable.test.tsx +0 -269
  76. package/src/components/__tests__/sorter.test.tsx +0 -114
  77. package/src/components/__tests__/zoomable.test.tsx +0 -399
  78. package/src/components/button-group.tsx +0 -130
  79. package/src/components/constants.ts +0 -14
  80. package/src/components/fixed-to-responsive.tsx +0 -169
  81. package/src/components/graph.tsx +0 -444
  82. package/src/components/graphie-classes.ts +0 -153
  83. package/src/components/graphie-movables.ts +0 -338
  84. package/src/components/graphie.tsx +0 -400
  85. package/src/components/highlighting/highlightable-content.tsx +0 -240
  86. package/src/components/highlighting/highlights.ts +0 -207
  87. package/src/components/highlighting/ranges.ts +0 -304
  88. package/src/components/highlighting/types.ts +0 -73
  89. package/src/components/highlighting/ui/highlight-renderer.tsx +0 -172
  90. package/src/components/highlighting/ui/highlight-set-renderer.tsx +0 -185
  91. package/src/components/highlighting/ui/highlight-tooltip.tsx +0 -141
  92. package/src/components/highlighting/ui/highlighting-ui.tsx +0 -143
  93. package/src/components/highlighting/ui/selection-tracker.tsx +0 -186
  94. package/src/components/highlighting/ui/types.ts +0 -21
  95. package/src/components/highlighting/ui/util.ts +0 -165
  96. package/src/components/highlighting/word-indexer.tsx +0 -152
  97. package/src/components/hud.tsx +0 -167
  98. package/src/components/icon.tsx +0 -141
  99. package/src/components/image-loader.tsx +0 -177
  100. package/src/components/info-tip/info-tip.tsx +0 -144
  101. package/src/components/info-tip.tsx +0 -39
  102. package/src/components/inline-icon.tsx +0 -60
  103. package/src/components/input-with-examples.tsx +0 -249
  104. package/src/components/lint.tsx +0 -459
  105. package/src/components/math-input.tsx +0 -474
  106. package/src/components/math-output.tsx +0 -134
  107. package/src/components/multi-button-group.tsx +0 -135
  108. package/src/components/number-input.tsx +0 -249
  109. package/src/components/prop-check-box.tsx +0 -79
  110. package/src/components/range-input.tsx +0 -60
  111. package/src/components/simple-keypad-input.tsx +0 -88
  112. package/src/components/sortable.tsx +0 -958
  113. package/src/components/stub-tag-editor.tsx +0 -53
  114. package/src/components/svg-image.tsx +0 -779
  115. package/src/components/tex.tsx +0 -67
  116. package/src/components/text-input.tsx +0 -129
  117. package/src/components/text-list-editor.tsx +0 -166
  118. package/src/components/tooltip.tsx +0 -410
  119. package/src/components/visibility-observer/__stories__/visibility-observer.stories.tsx +0 -141
  120. package/src/components/visibility-observer/create-visibility-observer.ts +0 -108
  121. package/src/components/visibility-observer/get-scroll-parent.ts +0 -46
  122. package/src/components/visibility-observer/visibility-observer.tsx +0 -124
  123. package/src/components/zoomable-tex.tsx +0 -78
  124. package/src/components/zoomable.tsx +0 -304
  125. package/src/components.ts +0 -15
  126. package/src/definition-context.tsx +0 -59
  127. package/src/dependencies.ts +0 -40
  128. package/src/error-boundary.tsx +0 -70
  129. package/src/extra-widgets.ts +0 -75
  130. package/src/hint-renderer.tsx +0 -151
  131. package/src/hints-renderer.tsx +0 -372
  132. package/src/icon-paths.ts +0 -119
  133. package/src/index.ts +0 -171
  134. package/src/init.ts +0 -56
  135. package/src/interaction-tracker.ts +0 -62
  136. package/src/interactive2/__tests__/movable-mock.ts +0 -55
  137. package/src/interactive2/__tests__/movable-point.test.ts +0 -144
  138. package/src/interactive2/interactive-util.test.ts +0 -93
  139. package/src/interactive2/interactive-util.ts +0 -159
  140. package/src/interactive2/movable-helper-methods.ts +0 -166
  141. package/src/interactive2/movable-line-options.ts +0 -419
  142. package/src/interactive2/movable-line.ts +0 -307
  143. package/src/interactive2/movable-point-options.ts +0 -224
  144. package/src/interactive2/movable-point.tsx +0 -585
  145. package/src/interactive2/movable-polygon-options.ts +0 -389
  146. package/src/interactive2/movable-polygon.ts +0 -360
  147. package/src/interactive2/movable.test.ts +0 -249
  148. package/src/interactive2/movable.ts +0 -437
  149. package/src/interactive2/objective_.ts +0 -79
  150. package/src/interactive2/types.ts +0 -17
  151. package/src/interactive2/wrapped-defaults.ts +0 -87
  152. package/src/interactive2/wrapped-ellipse.ts +0 -94
  153. package/src/interactive2/wrapped-line.ts +0 -116
  154. package/src/interactive2/wrapped-path.ts +0 -51
  155. package/src/interactive2.ts +0 -70
  156. package/src/item-version.ts +0 -10
  157. package/src/jipt-paragraphs.ts +0 -49
  158. package/src/jquery.mobile.vmouse.js +0 -545
  159. package/src/loading-context.ts +0 -21
  160. package/src/logging/log.test.ts +0 -39
  161. package/src/logging/log.ts +0 -97
  162. package/src/mixins/__tests__/widget-prop-denylist.test.ts +0 -21
  163. package/src/mixins/changeable.ts +0 -133
  164. package/src/mixins/editor-jsonify.ts +0 -13
  165. package/src/mixins/widget-jsonify-deprecated.ts +0 -23
  166. package/src/mixins/widget-prop-denylist.ts +0 -48
  167. package/src/multi-items/__stories__/multi-renderer.stories.tsx +0 -83
  168. package/src/multi-items/__testdata__/multi-renderer.testdata.ts +0 -172
  169. package/src/multi-items/__tests__/__snapshots__/multi-renderer.test.tsx.snap +0 -1164
  170. package/src/multi-items/__tests__/items.test.ts +0 -240
  171. package/src/multi-items/__tests__/multi-renderer.test.tsx +0 -914
  172. package/src/multi-items/__tests__/prop-type-builders.test.ts +0 -133
  173. package/src/multi-items/__tests__/shapes.test.ts +0 -43
  174. package/src/multi-items/__tests__/trees.test.ts +0 -317
  175. package/src/multi-items/item-types.ts +0 -56
  176. package/src/multi-items/items.ts +0 -176
  177. package/src/multi-items/multi-renderer.tsx +0 -569
  178. package/src/multi-items/prop-type-builders.ts +0 -106
  179. package/src/multi-items/shape-types.ts +0 -52
  180. package/src/multi-items/shapes.ts +0 -52
  181. package/src/multi-items/tree-types.ts +0 -47
  182. package/src/multi-items/trees.ts +0 -360
  183. package/src/multi-items.ts +0 -75
  184. package/src/perseus-api.tsx +0 -188
  185. package/src/perseus-env.ts +0 -27
  186. package/src/perseus-error.ts +0 -17
  187. package/src/perseus-markdown.tsx +0 -405
  188. package/src/perseus-types.ts +0 -1366
  189. package/src/perseus-version.ts +0 -9
  190. package/src/question-paragraph.tsx +0 -34
  191. package/src/renderability.ts +0 -109
  192. package/src/renderer.tsx +0 -2000
  193. package/src/server-item-renderer.tsx +0 -495
  194. package/src/sigfigs.ts +0 -490
  195. package/src/styles/articles.less +0 -749
  196. package/src/styles/constants.ts +0 -94
  197. package/src/styles/global-constants.ts +0 -343
  198. package/src/styles/global-styles.ts +0 -306
  199. package/src/styles/khan-exercise.css +0 -1468
  200. package/src/styles/media-queries.ts +0 -47
  201. package/src/styles/perseus-renderer.less +0 -732
  202. package/src/styles/shared.ts +0 -130
  203. package/src/styles/util.less +0 -47
  204. package/src/styles/variables.boostrap.less +0 -277
  205. package/src/styles/variables.less +0 -56
  206. package/src/styles/variables.shared.less +0 -340
  207. package/src/styles/widgets/categorizer.less +0 -38
  208. package/src/styles/widgets/dropdown.less +0 -3
  209. package/src/styles/widgets/expression.less +0 -65
  210. package/src/styles/widgets/graded-group.less +0 -36
  211. package/src/styles/widgets/grapher.less +0 -12
  212. package/src/styles/widgets/group.less +0 -19
  213. package/src/styles/widgets/image.less +0 -54
  214. package/src/styles/widgets/interactive-graph.less +0 -64
  215. package/src/styles/widgets/label-image.less +0 -57
  216. package/src/styles/widgets/matcher.less +0 -8
  217. package/src/styles/widgets/matrix.less +0 -126
  218. package/src/styles/widgets/measurer.less +0 -20
  219. package/src/styles/widgets/orderer.less +0 -98
  220. package/src/styles/widgets/passage.less +0 -154
  221. package/src/styles/widgets/plotter.less +0 -31
  222. package/src/styles/widgets/radio.less +0 -58
  223. package/src/styles/widgets/reaction-diagram.less +0 -35
  224. package/src/styles/widgets/sequence.less +0 -5
  225. package/src/styles/widgets/sortable.less +0 -113
  226. package/src/styles/widgets/table.less +0 -57
  227. package/src/styles/widgets/unit.less +0 -15
  228. package/src/tex-wrangler.ts +0 -182
  229. package/src/translation-linter.ts +0 -126
  230. package/src/traversal.ts +0 -138
  231. package/src/types.ts +0 -513
  232. package/src/util/a11y.ts +0 -23
  233. package/src/util/answer-types.test.ts +0 -114
  234. package/src/util/answer-types.ts +0 -876
  235. package/src/util/colors.ts +0 -93
  236. package/src/util/drawing-transform.test.ts +0 -67
  237. package/src/util/drawing-transform.ts +0 -102
  238. package/src/util/extract-perseus-data.ts +0 -539
  239. package/src/util/fix-passage-refs.ts +0 -121
  240. package/src/util/geometry.test.ts +0 -75
  241. package/src/util/geometry.ts +0 -312
  242. package/src/util/graph-bounds.ts +0 -23
  243. package/src/util/graph-utils.ts +0 -15
  244. package/src/util/graphie.test.ts +0 -1277
  245. package/src/util/graphie.ts +0 -1576
  246. package/src/util/interactive.ts +0 -4174
  247. package/src/util/interval.ts +0 -4
  248. package/src/util/katex-preprocess.ts +0 -14
  249. package/src/util/math.test.ts +0 -11
  250. package/src/util/math.ts +0 -294
  251. package/src/util/mobile-native-utils.test.ts +0 -22
  252. package/src/util/mobile-native-utils.ts +0 -12
  253. package/src/util/parse-perseus-json.test.ts +0 -10
  254. package/src/util/parse-perseus-json.ts +0 -13
  255. package/src/util/react-render.tsx +0 -27
  256. package/src/util/register-all-widgets-for-testing.ts +0 -13
  257. package/src/util/scroll-utils.ts +0 -155
  258. package/src/util/sizing-utils.ts +0 -46
  259. package/src/util/tex.ts +0 -73
  260. package/src/util/url-utils.ts +0 -34
  261. package/src/util.graphie.test.ts +0 -45
  262. package/src/util.graphie.ts +0 -59
  263. package/src/util.ts +0 -966
  264. package/src/version.ts +0 -10
  265. package/src/widget-container.tsx +0 -199
  266. package/src/widgets/__stories__/categorizer.stories.tsx +0 -14
  267. package/src/widgets/__stories__/cs-program.stories.tsx +0 -14
  268. package/src/widgets/__stories__/definition.stories.tsx +0 -114
  269. package/src/widgets/__stories__/dropdown.stories.tsx +0 -14
  270. package/src/widgets/__stories__/explanation.stories.tsx +0 -18
  271. package/src/widgets/__stories__/expression.stories.tsx +0 -145
  272. package/src/widgets/__stories__/graded-group-set.stories.tsx +0 -31
  273. package/src/widgets/__stories__/graded-group.stories.tsx +0 -31
  274. package/src/widgets/__stories__/grapher.stories.tsx +0 -46
  275. package/src/widgets/__stories__/group.stories.tsx +0 -14
  276. package/src/widgets/__stories__/iframe.stories.tsx +0 -14
  277. package/src/widgets/__stories__/image.stories.tsx +0 -85
  278. package/src/widgets/__stories__/input-number.stories.tsx +0 -101
  279. package/src/widgets/__stories__/interaction.stories.tsx +0 -14
  280. package/src/widgets/__stories__/interactive-graph.stories.tsx +0 -60
  281. package/src/widgets/__stories__/label-image.stories.tsx +0 -130
  282. package/src/widgets/__stories__/matcher.stories.tsx +0 -14
  283. package/src/widgets/__stories__/matrix.stories.tsx +0 -14
  284. package/src/widgets/__stories__/number-line.stories.tsx +0 -14
  285. package/src/widgets/__stories__/numeric-input.stories.tsx +0 -105
  286. package/src/widgets/__stories__/orderer.stories.tsx +0 -18
  287. package/src/widgets/__stories__/passage-ref.stories.tsx +0 -33
  288. package/src/widgets/__stories__/passage.stories.tsx +0 -39
  289. package/src/widgets/__stories__/plotter.stories.tsx +0 -27
  290. package/src/widgets/__stories__/radio.stories.tsx +0 -86
  291. package/src/widgets/__stories__/random-widgets.stories.tsx +0 -59
  292. package/src/widgets/__stories__/sorter.stories.tsx +0 -14
  293. package/src/widgets/__stories__/test-keypad-context-wrapper.tsx +0 -66
  294. package/src/widgets/__stories__/unit.stories.tsx +0 -28
  295. package/src/widgets/__stories__/video-transcript-link.stories.tsx +0 -23
  296. package/src/widgets/__stories__/video.stories.tsx +0 -22
  297. package/src/widgets/__testdata__/base-radio.testdata.ts +0 -21
  298. package/src/widgets/__testdata__/categorizer.testdata.ts +0 -89
  299. package/src/widgets/__testdata__/cs-program.testdata.ts +0 -27
  300. package/src/widgets/__testdata__/dropdown.testdata.ts +0 -71
  301. package/src/widgets/__testdata__/explanation.testdata.ts +0 -85
  302. package/src/widgets/__testdata__/expression.testdata.ts +0 -198
  303. package/src/widgets/__testdata__/graded-group-set.testdata.ts +0 -356
  304. package/src/widgets/__testdata__/graded-group.testdata.ts +0 -77
  305. package/src/widgets/__testdata__/grapher.testdata.ts +0 -374
  306. package/src/widgets/__testdata__/group.testdata.ts +0 -153
  307. package/src/widgets/__testdata__/iframe.testdata.ts +0 -35
  308. package/src/widgets/__testdata__/image.testdata.ts +0 -36
  309. package/src/widgets/__testdata__/input-number.testdata.ts +0 -72
  310. package/src/widgets/__testdata__/interaction.testdata.ts +0 -262
  311. package/src/widgets/__testdata__/interactive-graph-random.testdata.ts +0 -269
  312. package/src/widgets/__testdata__/interactive-graph.testdata.ts +0 -644
  313. package/src/widgets/__testdata__/label-image.testdata.ts +0 -308
  314. package/src/widgets/__testdata__/matcher.testdata.ts +0 -33
  315. package/src/widgets/__testdata__/matrix.testdata.ts +0 -28
  316. package/src/widgets/__testdata__/number-line.testdata.ts +0 -30
  317. package/src/widgets/__testdata__/numeric-input.testdata.ts +0 -265
  318. package/src/widgets/__testdata__/orderer.testdata.ts +0 -123
  319. package/src/widgets/__testdata__/passage-ref.testdata.ts +0 -101
  320. package/src/widgets/__testdata__/passage.testdata.ts +0 -95
  321. package/src/widgets/__testdata__/plotter.testdata.ts +0 -36
  322. package/src/widgets/__testdata__/radio.testdata.ts +0 -324
  323. package/src/widgets/__testdata__/randomizers.ts +0 -51
  324. package/src/widgets/__testdata__/sorter.testdata.ts +0 -19
  325. package/src/widgets/__testdata__/video.testdata.ts +0 -61
  326. package/src/widgets/__tests__/__snapshots__/categorizer.test.ts.snap +0 -940
  327. package/src/widgets/__tests__/__snapshots__/cs-program.test.ts.snap +0 -67
  328. package/src/widgets/__tests__/__snapshots__/definition.test.ts.snap +0 -97
  329. package/src/widgets/__tests__/__snapshots__/dropdown.test.ts.snap +0 -133
  330. package/src/widgets/__tests__/__snapshots__/explanation.test.ts.snap +0 -425
  331. package/src/widgets/__tests__/__snapshots__/graded-group-set-jipt.test.ts.snap +0 -729
  332. package/src/widgets/__tests__/__snapshots__/graded-group-set.test.ts.snap +0 -339
  333. package/src/widgets/__tests__/__snapshots__/graded-group.test.ts.snap +0 -801
  334. package/src/widgets/__tests__/__snapshots__/grapher.test.ts.snap +0 -2673
  335. package/src/widgets/__tests__/__snapshots__/group.test.tsx.snap +0 -1211
  336. package/src/widgets/__tests__/__snapshots__/iframe.test.ts.snap +0 -61
  337. package/src/widgets/__tests__/__snapshots__/image.test.ts.snap +0 -378
  338. package/src/widgets/__tests__/__snapshots__/input-number.test.ts.snap +0 -495
  339. package/src/widgets/__tests__/__snapshots__/interaction.test.ts.snap +0 -292
  340. package/src/widgets/__tests__/__snapshots__/interactive-graph.test.ts.snap +0 -2889
  341. package/src/widgets/__tests__/__snapshots__/matcher.test.tsx.snap +0 -883
  342. package/src/widgets/__tests__/__snapshots__/matrix.test.ts.snap +0 -514
  343. package/src/widgets/__tests__/__snapshots__/number-line.test.ts.snap +0 -814
  344. package/src/widgets/__tests__/__snapshots__/numeric-input.test.ts.snap +0 -470
  345. package/src/widgets/__tests__/__snapshots__/orderer.test.ts.snap +0 -243
  346. package/src/widgets/__tests__/__snapshots__/passage-ref.test.ts.snap +0 -434
  347. package/src/widgets/__tests__/__snapshots__/passage.test.tsx.snap +0 -1956
  348. package/src/widgets/__tests__/__snapshots__/plotter.test.tsx.snap +0 -827
  349. package/src/widgets/__tests__/__snapshots__/radio.test.ts.snap +0 -4237
  350. package/src/widgets/__tests__/__snapshots__/unit.test.tsx.snap +0 -20
  351. package/src/widgets/__tests__/__snapshots__/video.test.ts.snap +0 -153
  352. package/src/widgets/__tests__/categorizer.test.ts +0 -203
  353. package/src/widgets/__tests__/cs-program.test.ts +0 -43
  354. package/src/widgets/__tests__/definition.test.ts +0 -136
  355. package/src/widgets/__tests__/dropdown.test.ts +0 -105
  356. package/src/widgets/__tests__/explanation.test.ts +0 -198
  357. package/src/widgets/__tests__/expression-mobile.test.tsx +0 -363
  358. package/src/widgets/__tests__/expression.test.tsx +0 -484
  359. package/src/widgets/__tests__/graded-group-set-jipt.test.ts +0 -30
  360. package/src/widgets/__tests__/graded-group-set.test.ts +0 -288
  361. package/src/widgets/__tests__/graded-group.test.ts +0 -232
  362. package/src/widgets/__tests__/grapher.cypress.ts +0 -576
  363. package/src/widgets/__tests__/grapher.test.ts +0 -33
  364. package/src/widgets/__tests__/group.test.tsx +0 -510
  365. package/src/widgets/__tests__/iframe.test.ts +0 -45
  366. package/src/widgets/__tests__/image.test.ts +0 -62
  367. package/src/widgets/__tests__/input-number.test.ts +0 -354
  368. package/src/widgets/__tests__/interaction.test.ts +0 -31
  369. package/src/widgets/__tests__/interactive-graph.cypress.ts +0 -815
  370. package/src/widgets/__tests__/interactive-graph.test.ts +0 -106
  371. package/src/widgets/__tests__/matcher.test.tsx +0 -176
  372. package/src/widgets/__tests__/matrix.test.ts +0 -82
  373. package/src/widgets/__tests__/number-line.test.ts +0 -79
  374. package/src/widgets/__tests__/numeric-input.test.ts +0 -575
  375. package/src/widgets/__tests__/orderer.test.ts +0 -73
  376. package/src/widgets/__tests__/passage-ref.test.ts +0 -168
  377. package/src/widgets/__tests__/passage.test.tsx +0 -224
  378. package/src/widgets/__tests__/plotter.test.tsx +0 -69
  379. package/src/widgets/__tests__/radio/base-radio.test.tsx +0 -470
  380. package/src/widgets/__tests__/radio/choice-icon.test.tsx +0 -90
  381. package/src/widgets/__tests__/radio/choice.test.tsx +0 -310
  382. package/src/widgets/__tests__/radio/focus-ring.test.tsx +0 -22
  383. package/src/widgets/__tests__/radio/option-status.test.tsx +0 -77
  384. package/src/widgets/__tests__/radio.test.ts +0 -807
  385. package/src/widgets/__tests__/randomizers.test.ts +0 -53
  386. package/src/widgets/__tests__/renderQuestion.tsx +0 -101
  387. package/src/widgets/__tests__/unit.test.tsx +0 -168
  388. package/src/widgets/__tests__/video.test.ts +0 -69
  389. package/src/widgets/categorizer.tsx +0 -344
  390. package/src/widgets/cs-program.tsx +0 -227
  391. package/src/widgets/definition.tsx +0 -121
  392. package/src/widgets/deprecated-standin/__stories__/deprecated-standin.stories.tsx +0 -30
  393. package/src/widgets/deprecated-standin/__tests__/__snapshots__/deprecated-standin.test.ts.snap +0 -70
  394. package/src/widgets/deprecated-standin/__tests__/deprecated-standin.test.ts +0 -93
  395. package/src/widgets/deprecated-standin/index.tsx +0 -58
  396. package/src/widgets/dropdown.tsx +0 -142
  397. package/src/widgets/explanation.tsx +0 -317
  398. package/src/widgets/expression.tsx +0 -707
  399. package/src/widgets/graded-group-answer-bar.tsx +0 -142
  400. package/src/widgets/graded-group-set.tsx +0 -338
  401. package/src/widgets/graded-group.tsx +0 -471
  402. package/src/widgets/grapher/util.tsx +0 -799
  403. package/src/widgets/grapher.tsx +0 -660
  404. package/src/widgets/group.tsx +0 -195
  405. package/src/widgets/iframe.tsx +0 -195
  406. package/src/widgets/image.tsx +0 -312
  407. package/src/widgets/input-number.tsx +0 -412
  408. package/src/widgets/interaction/arrow-picker.tsx +0 -38
  409. package/src/widgets/interaction/color-picker.tsx +0 -69
  410. package/src/widgets/interaction/dash-picker.tsx +0 -45
  411. package/src/widgets/interaction/element-container.tsx +0 -100
  412. package/src/widgets/interaction.tsx +0 -826
  413. package/src/widgets/interactive-graph.tsx +0 -2597
  414. package/src/widgets/label-image/__stories__/answer-choices.stories.tsx +0 -91
  415. package/src/widgets/label-image/__stories__/answer-pill.stories.tsx +0 -62
  416. package/src/widgets/label-image/__stories__/marker.stories.tsx +0 -171
  417. package/src/widgets/label-image/__tests__/answer-pill.test.tsx +0 -75
  418. package/src/widgets/label-image/__tests__/hide-answers-toggle.test.tsx +0 -39
  419. package/src/widgets/label-image/answer-choices.tsx +0 -88
  420. package/src/widgets/label-image/answer-pill.tsx +0 -103
  421. package/src/widgets/label-image/hide-answers-toggle.tsx +0 -40
  422. package/src/widgets/label-image/marker.tsx +0 -268
  423. package/src/widgets/label-image/strings.ts +0 -5
  424. package/src/widgets/label-image/types.ts +0 -27
  425. package/src/widgets/label-image.test.ts +0 -928
  426. package/src/widgets/label-image.tsx +0 -819
  427. package/src/widgets/lights-puzzle.tsx +0 -359
  428. package/src/widgets/matcher.tsx +0 -298
  429. package/src/widgets/matrix.tsx +0 -634
  430. package/src/widgets/measurer.tsx +0 -222
  431. package/src/widgets/molecule/__tests__/layout.test.ts +0 -162
  432. package/src/widgets/molecule/__tests__/parser.test.ts +0 -155
  433. package/src/widgets/molecule/molecule-drawing.ts +0 -173
  434. package/src/widgets/molecule/molecule-layout.ts +0 -362
  435. package/src/widgets/molecule/smiles-parser.ts +0 -296
  436. package/src/widgets/molecule.tsx +0 -172
  437. package/src/widgets/number-line.tsx +0 -862
  438. package/src/widgets/numeric-input.tsx +0 -576
  439. package/src/widgets/orderer.tsx +0 -786
  440. package/src/widgets/passage/__tests__/passage-markdown.test.ts +0 -376
  441. package/src/widgets/passage/passage-markdown.tsx +0 -475
  442. package/src/widgets/passage-ref-target.tsx +0 -76
  443. package/src/widgets/passage-ref.tsx +0 -213
  444. package/src/widgets/passage.tsx +0 -582
  445. package/src/widgets/plotter.tsx +0 -1194
  446. package/src/widgets/radio/__stories__/base-radio.stories.tsx +0 -196
  447. package/src/widgets/radio/__stories__/choice-icon.stories.tsx +0 -166
  448. package/src/widgets/radio/__stories__/choice-none-above.stories.tsx +0 -40
  449. package/src/widgets/radio/__stories__/choice.stories.tsx +0 -137
  450. package/src/widgets/radio/__stories__/focus-ring.stories.tsx +0 -43
  451. package/src/widgets/radio/__stories__/option-status.stories.tsx +0 -103
  452. package/src/widgets/radio/base-radio.tsx +0 -511
  453. package/src/widgets/radio/choice-a11y-text.ts +0 -61
  454. package/src/widgets/radio/choice-icon/choice-icon.tsx +0 -218
  455. package/src/widgets/radio/choice-icon/cross-out-line.tsx +0 -51
  456. package/src/widgets/radio/choice-icon/shared-styles.ts +0 -15
  457. package/src/widgets/radio/choice-none-above.tsx +0 -56
  458. package/src/widgets/radio/choice.jsx.fixture.ts +0 -45
  459. package/src/widgets/radio/choice.tsx +0 -359
  460. package/src/widgets/radio/focus-ring.tsx +0 -57
  461. package/src/widgets/radio/option-status.tsx +0 -98
  462. package/src/widgets/radio/util.test.ts +0 -18
  463. package/src/widgets/radio/util.ts +0 -31
  464. package/src/widgets/radio/widget.tsx +0 -520
  465. package/src/widgets/radio.ts +0 -157
  466. package/src/widgets/reaction-diagram.tsx +0 -144
  467. package/src/widgets/sequence.tsx +0 -142
  468. package/src/widgets/simulator.tsx +0 -829
  469. package/src/widgets/sorter.tsx +0 -155
  470. package/src/widgets/table.tsx +0 -393
  471. package/src/widgets/unit.tsx +0 -374
  472. package/src/widgets/video-transcript-link.test.tsx +0 -213
  473. package/src/widgets/video-transcript-link.tsx +0 -84
  474. package/src/widgets/video.tsx +0 -135
  475. package/src/widgets.ts +0 -489
  476. package/src/zoom.ts +0 -555
  477. package/tsconfig-build.json +0 -26
  478. package/tsconfig-build.tsbuildinfo +0 -1
@@ -1,172 +0,0 @@
1
- /* eslint-disable react/no-unsafe */
2
- /**
3
- * This component, given a single DOMHighlight, draws highlight rectangles in
4
- * the same absolute position as the highlighted content, as computed via
5
- * `getClientRects`.
6
- *
7
- * TODO(mdr): Many things can affect the correct positioning of highlighting,
8
- * and this component does not attempt to anticipate them. If we start
9
- * using this highlighting library on content with a more dynamic layout,
10
- * we should add a hook to allow the parent to `forceUpdate` the
11
- * `HighlightRenderer`.
12
- */
13
- import {StyleSheet, css} from "aphrodite";
14
- import * as React from "react";
15
-
16
- import {
17
- getClientRectsForTextInRange,
18
- getRelativePosition,
19
- getRelativeRect,
20
- } from "./util";
21
-
22
- import type {DOMHighlight, Position, Rect, ZIndexes} from "./types";
23
-
24
- type Props = {
25
- // The DOMHighlight to render.
26
- highlight: DOMHighlight;
27
- // A unique key corresponding to the given `highlight`.
28
- highlightKey: string;
29
- // This component's `offsetParent` element, which is the nearest ancestor
30
- // with `position: relative`. This will enable us to choose the correct
31
- // CSS coordinates to align highlights and tooltips with the target
32
- // content.
33
- offsetParent: Element;
34
- // The z-indexes to use when rendering tooltips above content, and
35
- // highlights below content.
36
- zIndexes: ZIndexes;
37
- };
38
-
39
- type State = {
40
- // The set of rectangles that cover this highlight's content, relative to
41
- // the offset parent. This cache is updated on mount and on changes to
42
- // the `highlight` and `offsetParent` props.
43
- //
44
- // We perform this caching because HighlightSetRenderer uses this
45
- // component's `isHovered` function to access the rectangles every time the
46
- // user's mouse moves, in order to check the hover state, and recomputing
47
- // them on every mousemove seems like it could be expensive on older
48
- // devices (though tbf that's just a gut instinct, not the result of
49
- // testing on older devices).
50
- cachedHighlightRects: ReadonlyArray<Rect>;
51
- };
52
-
53
- class HighlightRenderer extends React.PureComponent<Props, State> {
54
- state: State = {
55
- cachedHighlightRects: this._computeRects(this.props),
56
- // @ts-expect-error - TS2322 - Type '{ cachedHighlightRects: readonly Rect[]; tooltipIsHovered: boolean; }' is not assignable to type 'HighlightRendererState'.
57
- tooltipIsHovered: false,
58
- };
59
-
60
- UNSAFE_componentWillReceiveProps(nextProps: Props) {
61
- if (
62
- this.props.highlight !== nextProps.highlight ||
63
- this.props.offsetParent !== nextProps.offsetParent
64
- ) {
65
- this.setState({
66
- cachedHighlightRects: this._computeRects(nextProps),
67
- });
68
- }
69
- }
70
-
71
- /**
72
- * Compute the set of rectangles that cover the highlighted content, with
73
- * coordinates relative to the offset parent. That way, we can use them
74
- * for CSS positioning.
75
- */
76
- _computeRects(props: Props): ReadonlyArray<Rect> {
77
- const {highlight, offsetParent} = props;
78
-
79
- // Get the set of rectangles that covers the range's text, relative to
80
- // the offset parent.
81
- const clientRects = getClientRectsForTextInRange(highlight.domRange);
82
- const {left, top} = offsetParent.getBoundingClientRect();
83
- const relativeRects = clientRects.map((rect) =>
84
- getRelativeRect(rect, {left, top}),
85
- );
86
-
87
- return relativeRects;
88
- }
89
-
90
- /**
91
- * Return whether the given mouse position (coordinates relative to this
92
- * component's offset parent) is hovering over the given rectangle
93
- * (coordinates also relative to this component's offset parent).
94
- */
95
- _rectIsHovered(rect: Rect, mouseOffsetPosition: Position): boolean {
96
- const positionWithinRect = getRelativePosition(mouseOffsetPosition, {
97
- left: rect.left,
98
- top: rect.top,
99
- });
100
-
101
- return (
102
- 0 <= positionWithinRect.left &&
103
- positionWithinRect.left < rect.width &&
104
- 0 <= positionWithinRect.top &&
105
- positionWithinRect.top < rect.height
106
- );
107
- }
108
-
109
- /**
110
- * Return whether the given mouse position (coordinates relative to the
111
- * viewport) is hovering over this highlight.
112
- */
113
- isHovered(mouseClientPosition?: Position | null): boolean {
114
- if (!mouseClientPosition) {
115
- return false;
116
- }
117
-
118
- const {offsetParent} = this.props;
119
- const {cachedHighlightRects} = this.state;
120
-
121
- // Convert the client-relative mouse coordinates to be relative to the
122
- // offset parent. That way, we can compare them to the cached highlight
123
- // rectangles.
124
- const {left, top} = offsetParent.getBoundingClientRect();
125
- const mouseOffsetPosition = getRelativePosition(mouseClientPosition, {
126
- left,
127
- top,
128
- });
129
-
130
- return cachedHighlightRects.some((rect) =>
131
- this._rectIsHovered(rect, mouseOffsetPosition),
132
- );
133
- }
134
-
135
- render(): React.ReactNode {
136
- const rects = this.state.cachedHighlightRects;
137
-
138
- return (
139
- <div>
140
- {rects.map((rect, index) => (
141
- <div
142
- key={index}
143
- className={css(styles.highlightRect)}
144
- style={{
145
- // NOTE(mdr): We apply `position: absolute` here
146
- // rather than in Aphrodite styles, because
147
- // Aphrodite styles are delayed. If this
148
- // element temporarily has `position: static`,
149
- // then it'll displace the content, and other
150
- // highlights rendering during this update will
151
- // measure the displaced content instead, oops!
152
- position: "absolute",
153
- width: rect.width,
154
- height: rect.height,
155
- top: rect.top,
156
- left: rect.left,
157
- zIndex: this.props.zIndexes.belowContent,
158
- }}
159
- />
160
- ))}
161
- </div>
162
- );
163
- }
164
- }
165
-
166
- const styles = StyleSheet.create({
167
- highlightRect: {
168
- background: "#fffabe", // highlighter yellow :)
169
- },
170
- });
171
-
172
- export default HighlightRenderer;
@@ -1,185 +0,0 @@
1
- /* eslint-disable react/no-unsafe */
2
- /**
3
- * Render a set of highlights. See HighlightRenderer for more details about how
4
- * each highlight is rendered.
5
- *
6
- * This component manages the state of the "Remove highlight" tooltip. To
7
- * determine the currently-hovered highlight, it calls the `isHovered` method
8
- * on each HighlightRenderer.
9
- */
10
- import * as i18n from "@khanacademy/wonder-blocks-i18n";
11
- import * as React from "react";
12
-
13
- import HighlightRenderer from "./highlight-renderer";
14
- import HighlightTooltip from "./highlight-tooltip";
15
-
16
- import type {DOMHighlightSet, Position, ZIndexes} from "./types";
17
-
18
- type Props = {
19
- // Whether the highlights are user-editable. If false, highlights are
20
- // read-only.
21
- editable: boolean;
22
- // A set of highlights to render.
23
- highlights: DOMHighlightSet;
24
- // This component's `offsetParent` element, which is the nearest ancestor
25
- // with `position: relative`. This will enable us to choose the correct
26
- // CSS coordinates to align highlights and tooltips with the target
27
- // content.
28
- offsetParent: Element;
29
- // A callback indicating that the user would like to remove the highlight
30
- // with the given key.
31
- onRemoveHighlight: (highlightKey: string) => unknown;
32
- // The z-indexes to use when rendering tooltips above content, and
33
- // highlights below content.
34
- zIndexes: ZIndexes;
35
- };
36
- type State = {
37
- // If the user is currently hovering over a highlight, this field contains
38
- // its key.
39
- hoveredHighlightKey: string | null | undefined;
40
- // If the user is currently hovering over the "Remove highlight" tooltip,
41
- // this field contains the key of the corresponding highlight.
42
- hoveringTooltipFor: string | null | undefined;
43
- };
44
-
45
- class HighlightSetRenderer extends React.PureComponent<Props, State> {
46
- state: State = {
47
- hoveredHighlightKey: null,
48
- hoveringTooltipFor: null,
49
- };
50
-
51
- // eslint-disable-next-line react/sort-comp
52
- _highlightRenderers: {
53
- [highlightKey: string]: HighlightRenderer;
54
- } = {};
55
-
56
- componentDidMount() {
57
- this._updateEditListeners(false, this.props.editable);
58
- }
59
-
60
- UNSAFE_componentWillReceiveProps(nextProps: Props) {
61
- this._updateEditListeners(this.props.editable, nextProps.editable);
62
-
63
- // If we were previously hovering over a highlight that has been
64
- // removed, reset the hover state accordingly.
65
- if (
66
- this.state.hoveredHighlightKey != null &&
67
- !(this.state.hoveredHighlightKey in nextProps.highlights)
68
- ) {
69
- this.setState({hoveredHighlightKey: null});
70
- }
71
-
72
- // Similarly, if we were previously hovering over the tooltip for a
73
- // highlight that has been removed, reset the hover state accordingly.
74
- if (
75
- this.state.hoveringTooltipFor != null &&
76
- !(this.state.hoveringTooltipFor in nextProps.highlights)
77
- ) {
78
- this.setState({hoveringTooltipFor: null});
79
- }
80
- }
81
-
82
- componentWillUnmount() {
83
- this._updateEditListeners(this.props.editable, false);
84
- }
85
-
86
- /**
87
- * Given whether we were previously listening to mousemove events, and
88
- * whether we will now listen to mousemove events, add or remove the
89
- * listener accordingly.
90
- */
91
- _updateEditListeners(wasListening: boolean, willListen: boolean) {
92
- if (!wasListening && willListen) {
93
- window.addEventListener("mousemove", this._handleMouseMove);
94
- } else if (wasListening && !willListen) {
95
- window.removeEventListener("mousemove", this._handleMouseMove);
96
-
97
- // Additionally, reset the hover state, to ensure that we don't
98
- // keep old hover state around.
99
- this.setState({
100
- hoveredHighlightKey: null,
101
- hoveringTooltipFor: null,
102
- });
103
- }
104
- }
105
-
106
- _handleMouseMove: (e: MouseEvent) => void = (e: MouseEvent) => {
107
- const mouseClientPosition = {left: e.clientX, top: e.clientY} as const;
108
- const hoveredHighlightKey =
109
- this._getHoveredHighlightKey(mouseClientPosition);
110
- this.setState({hoveredHighlightKey});
111
- };
112
-
113
- _getHoveredHighlightKey(
114
- mouseClientPosition: Position,
115
- ): string | null | undefined {
116
- // If we're hovering over the tooltip, the hovered highlight is the
117
- // highlight that the tooltip is pointing to.
118
- const {hoveringTooltipFor} = this.state;
119
- if (typeof hoveringTooltipFor === "string") {
120
- return hoveringTooltipFor;
121
- }
122
-
123
- // Otherwise, check each highlight renderer to see whether the current
124
- // mouse position intersects any of the highlight rectangles.
125
- const highlightKeys = Object.keys(this.props.highlights);
126
- return highlightKeys.find((key) => {
127
- const highlightRenderer = this._highlightRenderers[key];
128
- return (
129
- highlightRenderer &&
130
- highlightRenderer.isHovered(mouseClientPosition)
131
- );
132
- });
133
- }
134
-
135
- _renderTooltip(): null | React.ReactNode {
136
- const {hoveredHighlightKey} = this.state;
137
- if (hoveredHighlightKey == null) {
138
- return null;
139
- }
140
-
141
- const hoveredHighlight = this.props.highlights[hoveredHighlightKey];
142
-
143
- return (
144
- <HighlightTooltip
145
- label={i18n._("Remove highlight")}
146
- focusNode={hoveredHighlight.domRange.endContainer}
147
- focusOffset={hoveredHighlight.domRange.endOffset}
148
- offsetParent={this.props.offsetParent}
149
- onClick={() =>
150
- this.props.onRemoveHighlight(hoveredHighlightKey)
151
- }
152
- onMouseEnter={() =>
153
- this.setState({hoveringTooltipFor: hoveredHighlightKey})
154
- }
155
- onMouseLeave={() => this.setState({hoveringTooltipFor: null})}
156
- />
157
- );
158
- }
159
-
160
- render(): React.ReactNode {
161
- return (
162
- <div>
163
- {Object.keys(this.props.highlights).map((key) => (
164
- <HighlightRenderer
165
- ref={(r) => {
166
- if (r) {
167
- this._highlightRenderers[key] = r;
168
- } else {
169
- delete this._highlightRenderers[key];
170
- }
171
- }}
172
- key={key}
173
- highlight={this.props.highlights[key]}
174
- highlightKey={key}
175
- offsetParent={this.props.offsetParent}
176
- zIndexes={this.props.zIndexes}
177
- />
178
- ))}
179
- {this.props.editable && this._renderTooltip()}
180
- </div>
181
- );
182
- }
183
- }
184
-
185
- export default HighlightSetRenderer;
@@ -1,141 +0,0 @@
1
- /**
2
- * A tooltip to point to the focus of a highlight.
3
- *
4
- * We use the NewTooltip component, which positions itself not by coordinate,
5
- * but by watching the position of a target DOM element. So, we render a 0x0
6
- * DOM element, absolute-position it to the position of the the highlight
7
- * focus, and point the tooltip at that 0x0 element.
8
- *
9
- * This technique enables NewTooltip to use its existing visibility-watching
10
- * and scroll-tracking logic to effectively "watch" the focus of this
11
- * highlight. So, we get lots of the repositioning logic for free! But we _do_
12
- * still have to notify the tooltip to remeasure itself when the highlight
13
- * focus _changes_.
14
- */
15
- import Spacing from "@khanacademy/wonder-blocks-spacing";
16
- import Tooltip from "@khanacademy/wonder-blocks-tooltip";
17
- import {StyleSheet, css} from "aphrodite";
18
- import * as React from "react";
19
-
20
- import {Log} from "../../../logging/log";
21
-
22
- import {getRelativeRect} from "./util";
23
-
24
- import type {Rect} from "./types";
25
-
26
- type Props = {
27
- label: string;
28
- onClick: () => unknown;
29
- onMouseEnter?: () => unknown;
30
- onMouseLeave?: () => unknown;
31
- focusNode: Node;
32
- focusOffset: number;
33
- offsetParent: Element;
34
- };
35
-
36
- class HighlightTooltip extends React.PureComponent<Props> {
37
- _getFocusRect(): Rect | null | undefined {
38
- const {focusNode, focusOffset, offsetParent} = this.props;
39
-
40
- // Get a range of *just* the focus point of the selection.
41
- const focusRange = document.createRange();
42
- focusRange.setStart(focusNode, focusOffset);
43
- focusRange.setEnd(focusNode, focusOffset);
44
-
45
- // Then, get the bounding box of the collapsed range. This will be a
46
- // zero-width rectangle, but still have positioning information, which
47
- // we can use the position the tooltip.
48
- //
49
- // NOTE(mdr): If we used getClientBoundingRect here instead, Safari
50
- // would return an unpositioned rect. But all tested browsers at
51
- // time of writing (latest Chrome, Firefox, Safari) return at least
52
- // one rectangle from getClientRects, and it's well-positioned.
53
- const focusRect = focusRange.getClientRects()[0];
54
-
55
- // NOTE(mdr): ...except in the case where the focus is between two
56
- // paragraphs, in which case the focus range has no client rects?
57
- // Not sure why, or in what browsers (only noticed in Chrome 60),
58
- // but let's catch that case and bail out.
59
- // TODO(mdr): Instead, we should somehow walk back the range until we
60
- // find an appropriate position for the tooltip. Sounds tricky!
61
- if (!focusRect) {
62
- Log.log(
63
- "[Highlighting] Known bug: Could not determine the focus " +
64
- 'position, so did not show an "Add Highlight" tooltip. ' +
65
- "https://app.asana.com/0/329800276300868/413878480039713 " +
66
- "(see also /r/asana-links)",
67
- );
68
- return null;
69
- }
70
-
71
- // Compute the desired position of the tooltip relative to the offset
72
- // parent.
73
- const {left, top} = offsetParent.getBoundingClientRect();
74
- const relativeFocusRect = getRelativeRect(
75
- {
76
- left: focusRect.left,
77
- top: focusRect.top,
78
- width: focusRect.width,
79
- height: focusRect.height,
80
- },
81
- {left, top},
82
- );
83
-
84
- return relativeFocusRect;
85
- }
86
-
87
- render(): null | React.ReactNode {
88
- const focusRect = this._getFocusRect();
89
- if (!focusRect) {
90
- return null;
91
- }
92
-
93
- // using div instead of TooltipContent because
94
- // TooltipContent wouldn't let me overwrite
95
- // user-select and onClick
96
- const content: any = (
97
- <div
98
- className={css(styles.tooltipLabel)}
99
- onClick={this.props.onClick}
100
- >
101
- {this.props.label}
102
- </div>
103
- );
104
-
105
- const style = {
106
- position: "absolute",
107
- left: focusRect.left,
108
- // offset the spacing WB provides around tooltips
109
- top: `calc(${Math.round(focusRect.top)}px + 0.95em)`,
110
- height: 0,
111
- } as const;
112
-
113
- return (
114
- <div
115
- style={style}
116
- onMouseEnter={this.props.onMouseEnter}
117
- onMouseLeave={this.props.onMouseLeave}
118
- >
119
- <Tooltip content={content} opened={true}>
120
- <div />
121
- </Tooltip>
122
- </div>
123
- );
124
- }
125
- }
126
-
127
- const styles = StyleSheet.create({
128
- tooltipLabel: {
129
- // Unlike most tooltip contents, we don't want this label to be
130
- // selectable. Selecting it is not only unhelpful, but dangerous: if
131
- // the user accidentally selects the "Add highlight" tooltip text, then
132
- // we lose our reference to the _actual_ text they want to highlight,
133
- // and the "Add highlight" action fails.
134
- userSelect: "none",
135
- fontFamily: `"Lato", sans-serif`,
136
- padding: `10px ${Spacing.medium_16}px`,
137
- cursor: "pointer",
138
- },
139
- });
140
-
141
- export default HighlightTooltip;
@@ -1,143 +0,0 @@
1
- /**
2
- * This component, given a set of DOMHighlights, draws highlight rectangles in
3
- * the same absolute position as the highlighted content, as computed by the
4
- * range's `getClientRects` method.
5
- *
6
- * TODO(mdr): Many things can affect the correct positioning of highlighting,
7
- * and this component does not attempt to anticipate them. If we start
8
- * using this highlighting library on content with a more dynamic layout,
9
- * we should add a hook to allow the parent to `forceUpdate` the
10
- * `HighlightingUI`.
11
- */
12
- import * as i18n from "@khanacademy/wonder-blocks-i18n";
13
- import * as React from "react";
14
-
15
- import {rangesOverlap} from "../ranges";
16
-
17
- import HighlightSetRenderer from "./highlight-set-renderer";
18
- import HighlightTooltip from "./highlight-tooltip";
19
- import SelectionTracker from "./selection-tracker";
20
-
21
- import type {TrackedSelection} from "./selection-tracker";
22
- import type {DOMHighlight, DOMHighlightSet, DOMRange, ZIndexes} from "./types";
23
-
24
- type Props = {
25
- // A function that builds a DOMHighlight from the given DOMRange, if
26
- // possible. If it would not currently be valid to add a highlight over the
27
- // given DOMRange, returns null.
28
- buildHighlight: (range: DOMRange) => DOMHighlight | null | undefined;
29
- // A Node that contains the highlightable content.
30
- contentNode: Node;
31
- // Whether the highlights are user-editable. If false, highlights are
32
- // read-only.
33
- editable: boolean;
34
- // A set of highlights to render.
35
- highlights: DOMHighlightSet;
36
- // This component's `offsetParent` element, which is the nearest ancestor
37
- // with `position: relative`. This will enable us to choose the correct
38
- // CSS coordinates to align highlights and tooltips with the target
39
- // content.
40
- offsetParent: Element;
41
- // A callback indicating that the user would like to add the given
42
- // highlight to the current set of highlights.
43
- onAddHighlight: (range: DOMHighlight) => unknown;
44
- // A callback indicating that the user would like to remove the highlight
45
- // with the given key.
46
- onRemoveHighlight: (highlightKey: string) => unknown;
47
- // The z-indexes to use when rendering tooltips above content, and
48
- // highlights below content.
49
- zIndexes: ZIndexes;
50
- };
51
-
52
- class HighlightingUI extends React.PureComponent<Props> {
53
- _handleAddHighlight(highlightToAdd: DOMHighlight) {
54
- this.props.onAddHighlight(highlightToAdd);
55
-
56
- // Deselect the newly-highlighted text, by collapsing the selection
57
- // to the end of the range.
58
- const selection = document.getSelection();
59
- if (selection) {
60
- selection.collapseToEnd();
61
- }
62
- }
63
-
64
- _selectionIsValid(
65
- trackedSelection?: TrackedSelection | null,
66
- ): trackedSelection is TrackedSelection {
67
- if (!trackedSelection) {
68
- return false;
69
- }
70
-
71
- const {contentNode} = this.props;
72
-
73
- // Create a range over the content node.
74
- const contentRange = new Range();
75
- contentRange.selectNodeContents(contentNode);
76
-
77
- // Create a range over the focus position.
78
- const focusRange = new Range();
79
- focusRange.setStart(
80
- trackedSelection.focusNode,
81
- trackedSelection.focusOffset,
82
- );
83
- focusRange.collapse(true /* to start */);
84
-
85
- // Determine whether the content range contains the focus, by checking
86
- // whether they intersect. Because the focus range is a single point,
87
- // intersection is equivalent to being fully contained.
88
- const contentContainsFocus = rangesOverlap(contentRange, focusRange);
89
-
90
- // If the content contains the focus, this is a valid selection. Some
91
- // parts of the range might go beyond the content, but that's okay; the
92
- // corresponding DOMHighlight is already trimmed to only contain valid
93
- // words. We're just checking that the tooltip we render will be inside
94
- // the content, because rendering a tooltip outside the content would
95
- // be weird.
96
- const selectionIsValid = contentContainsFocus;
97
-
98
- return selectionIsValid;
99
- }
100
-
101
- render(): React.ReactNode {
102
- return (
103
- <SelectionTracker
104
- buildHighlight={this.props.buildHighlight}
105
- enabled={this.props.editable}
106
- >
107
- {(trackedSelection, userIsMouseSelecting) => (
108
- <div>
109
- <HighlightSetRenderer
110
- editable={
111
- /* An existing highlight is editable when the
112
- * component is in editable mode, and there's no
113
- * selection in progress. */
114
- this.props.editable &&
115
- !this._selectionIsValid(trackedSelection)
116
- }
117
- highlights={this.props.highlights}
118
- offsetParent={this.props.offsetParent}
119
- onRemoveHighlight={this.props.onRemoveHighlight}
120
- zIndexes={this.props.zIndexes}
121
- />
122
- {this._selectionIsValid(trackedSelection) &&
123
- !userIsMouseSelecting && (
124
- <HighlightTooltip
125
- label={i18n._("Add highlight")}
126
- onClick={() =>
127
- this._handleAddHighlight(
128
- trackedSelection.proposedHighlight,
129
- )
130
- }
131
- focusNode={trackedSelection.focusNode}
132
- focusOffset={trackedSelection.focusOffset}
133
- offsetParent={this.props.offsetParent}
134
- />
135
- )}
136
- </div>
137
- )}
138
- </SelectionTracker>
139
- );
140
- }
141
- }
142
-
143
- export default HighlightingUI;