@khanacademy/perseus 4.0.2 → 6.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (249) hide show
  1. package/CHANGELOG.md +57 -0
  2. package/dist/components/fixed-to-responsive.d.ts +27 -1
  3. package/dist/components/fixed-to-responsive.js.flow +27 -1
  4. package/dist/components/graph.d.ts +42 -26
  5. package/dist/components/graph.js.flow +42 -28
  6. package/dist/components/graphie.d.ts +34 -22
  7. package/dist/components/graphie.js.flow +37 -24
  8. package/dist/components/highlighting/highlightable-content.d.ts +4 -4
  9. package/dist/components/highlighting/highlightable-content.js.flow +4 -7
  10. package/dist/components/highlighting/ui/highlight-renderer.d.ts +6 -6
  11. package/dist/components/highlighting/ui/highlight-renderer.js.flow +6 -8
  12. package/dist/components/highlighting/ui/highlight-set-renderer.d.ts +5 -5
  13. package/dist/components/highlighting/ui/highlight-set-renderer.js.flow +5 -8
  14. package/dist/components/highlighting/ui/highlight-tooltip.d.ts +2 -2
  15. package/dist/components/highlighting/ui/highlight-tooltip.js.flow +2 -4
  16. package/dist/components/highlighting/ui/highlighting-ui.d.ts +2 -2
  17. package/dist/components/highlighting/ui/highlighting-ui.js.flow +2 -2
  18. package/dist/components/highlighting/ui/selection-tracker.d.ts +5 -5
  19. package/dist/components/highlighting/ui/selection-tracker.js.flow +5 -7
  20. package/dist/components/highlighting/word-indexer.d.ts +2 -2
  21. package/dist/components/highlighting/word-indexer.js.flow +2 -2
  22. package/dist/components/hud.d.ts +8 -14
  23. package/dist/components/hud.js.flow +7 -14
  24. package/dist/components/inline-icon.d.ts +27 -3
  25. package/dist/components/inline-icon.js.flow +26 -3
  26. package/dist/components/lint.d.ts +41 -13
  27. package/dist/components/lint.js.flow +42 -13
  28. package/dist/components/math-output.d.ts +15 -11
  29. package/dist/components/math-output.js.flow +15 -11
  30. package/dist/components/simple-keypad-input.d.ts +1 -1
  31. package/dist/components/simple-keypad-input.js.flow +1 -1
  32. package/dist/components/sortable.d.ts +17 -9
  33. package/dist/components/sortable.js.flow +22 -9
  34. package/dist/components/svg-image.d.ts +5 -3
  35. package/dist/components/svg-image.js.flow +5 -3
  36. package/dist/components/tex-buttons.d.ts +2 -2
  37. package/dist/components/tex-buttons.js.flow +2 -2
  38. package/dist/components/tooltip.d.ts +45 -4
  39. package/dist/components/tooltip.js.flow +44 -31
  40. package/dist/error-boundary.d.ts +4 -4
  41. package/dist/error-boundary.js.flow +4 -6
  42. package/dist/es/index.css +0 -3
  43. package/dist/es/index.js +484 -658
  44. package/dist/es/index.js.map +1 -1
  45. package/dist/index.css +0 -3
  46. package/dist/index.js +488 -655
  47. package/dist/index.js.map +1 -1
  48. package/dist/perseus-types.d.ts +11 -10
  49. package/dist/perseus-types.js.flow +11 -10
  50. package/dist/renderer.d.ts +2 -2
  51. package/dist/renderer.js.flow +1 -3
  52. package/dist/styles/shared.d.ts +0 -1
  53. package/dist/styles/shared.js.flow +0 -1
  54. package/dist/types.d.ts +0 -10
  55. package/dist/types.js.flow +0 -13
  56. package/dist/util/a11y.d.ts +0 -1
  57. package/dist/util/a11y.js.flow +0 -1
  58. package/dist/util/interactive.d.ts +2 -0
  59. package/dist/util/interactive.js.flow +2 -0
  60. package/dist/util.d.ts +3 -3
  61. package/dist/util.js.flow +4 -3
  62. package/dist/widgets/__stories__/test-keypad-context-wrapper.d.ts +2 -2
  63. package/dist/widgets/__stories__/test-keypad-context-wrapper.js.flow +2 -4
  64. package/dist/widgets/expression.d.ts +2 -2
  65. package/dist/widgets/expression.js.flow +2 -2
  66. package/dist/widgets/grapher.d.ts +1 -1
  67. package/dist/widgets/grapher.js.flow +12 -3
  68. package/dist/widgets/interaction/element-container.d.ts +5 -4
  69. package/dist/widgets/interaction/element-container.js.flow +6 -11
  70. package/dist/widgets/label-image/marker.d.ts +4 -4
  71. package/dist/widgets/label-image/marker.js.flow +4 -6
  72. package/dist/widgets/matcher.d.ts +7 -3
  73. package/dist/widgets/matcher.js.flow +7 -3
  74. package/dist/widgets/number-line.d.ts +1 -1
  75. package/dist/widgets/number-line.js.flow +1 -1
  76. package/dist/widgets/numeric-input.d.ts +0 -2
  77. package/dist/widgets/numeric-input.js.flow +0 -4
  78. package/dist/widgets/radio/base-radio.d.ts +7 -1
  79. package/dist/widgets/radio/base-radio.js.flow +7 -1
  80. package/dist/widgets/radio/choice-icon/choice-icon.d.ts +1 -1
  81. package/dist/widgets/radio/choice-icon/choice-icon.js.flow +1 -1
  82. package/dist/widgets/radio/choice-icon/cross-out-line.d.ts +2 -2
  83. package/dist/widgets/radio/choice-icon/cross-out-line.js.flow +2 -2
  84. package/dist/widgets/radio/focus-ring.d.ts +8 -1
  85. package/dist/widgets/radio/focus-ring.js.flow +8 -1
  86. package/dist/widgets/radio/option-status.d.ts +2 -2
  87. package/dist/widgets/radio/option-status.js.flow +2 -2
  88. package/dist/widgets/video-transcript-link.d.ts +1 -1
  89. package/dist/widgets/video-transcript-link.js.flow +1 -1
  90. package/package.json +4 -4
  91. package/src/__stories__/item-renderer.stories.tsx +2 -6
  92. package/src/__stories__/server-item-renderer.stories.tsx +2 -6
  93. package/src/__tests__/__snapshots__/item-renderer.test.tsx.snap +151 -159
  94. package/src/__tests__/__snapshots__/renderer.test.tsx.snap +358 -394
  95. package/src/__tests__/__snapshots__/server-item-renderer.test.tsx.snap +169 -189
  96. package/src/components/__stories__/button-group.stories.tsx +2 -6
  97. package/src/components/__stories__/fixed-to-responsive.stories.tsx +14 -16
  98. package/src/components/__stories__/graph.stories.tsx +3 -5
  99. package/src/components/__stories__/graphie.stories.tsx +3 -5
  100. package/src/components/__stories__/hud.stories.tsx +2 -6
  101. package/src/components/__stories__/icon.stories.tsx +1 -1
  102. package/src/components/__stories__/image-loader.stories.tsx +4 -4
  103. package/src/components/__stories__/info-tip.stories.tsx +2 -6
  104. package/src/components/__stories__/inline-icon.stories.tsx +4 -8
  105. package/src/components/__stories__/input-with-examples.stories.tsx +6 -10
  106. package/src/components/__stories__/lint.stories.tsx +62 -27
  107. package/src/components/__stories__/math-input.stories.tsx +4 -8
  108. package/src/components/__stories__/math-output.stories.tsx +3 -5
  109. package/src/components/__stories__/multi-button-group.stories.tsx +2 -6
  110. package/src/components/__stories__/number-input.stories.tsx +6 -8
  111. package/src/components/__stories__/prop-check-box.stories.tsx +9 -9
  112. package/src/components/__stories__/range-input.stories.tsx +4 -6
  113. package/src/components/__stories__/simple-keypad-input.stories.tsx +2 -4
  114. package/src/components/__stories__/sortable.stories.tsx +20 -20
  115. package/src/components/__stories__/stub-tag-editor.stories.tsx +5 -9
  116. package/src/components/__stories__/svg-image.stories.tsx +10 -18
  117. package/src/components/__stories__/tex.stories.tsx +1 -3
  118. package/src/components/__stories__/text-buttons.stories.tsx +10 -22
  119. package/src/components/__stories__/text-input.stories.tsx +4 -10
  120. package/src/components/__stories__/text-list-editor.stories.tsx +1 -3
  121. package/src/components/__stories__/tooltip.stories.tsx +52 -0
  122. package/src/components/__stories__/zoomable-tex.stories.tsx +6 -4
  123. package/src/components/__stories__/zoomable.stories.tsx +1 -3
  124. package/src/components/__tests__/__snapshots__/sortable.test.tsx.snap +114 -30
  125. package/src/components/__tests__/__snapshots__/sorter.test.tsx.snap +172 -204
  126. package/src/components/__tests__/sortable.test.tsx +54 -16
  127. package/src/components/__tests__/sorter.test.tsx +12 -9
  128. package/src/components/fixed-to-responsive.tsx +43 -38
  129. package/src/components/graph.tsx +95 -81
  130. package/src/components/graphie.tsx +62 -32
  131. package/src/components/highlighting/highlightable-content.tsx +4 -7
  132. package/src/components/highlighting/ui/highlight-renderer.tsx +6 -9
  133. package/src/components/highlighting/ui/highlight-set-renderer.tsx +5 -8
  134. package/src/components/highlighting/ui/highlight-tooltip.tsx +2 -2
  135. package/src/components/highlighting/ui/highlighting-ui.tsx +2 -2
  136. package/src/components/highlighting/ui/selection-tracker.tsx +5 -8
  137. package/src/components/highlighting/word-indexer.tsx +2 -2
  138. package/src/components/hud.tsx +104 -115
  139. package/src/components/inline-icon.tsx +17 -34
  140. package/src/components/input-with-examples.tsx +4 -4
  141. package/src/components/lint.tsx +47 -41
  142. package/src/components/math-output.tsx +17 -11
  143. package/src/components/simple-keypad-input.tsx +4 -4
  144. package/src/components/sortable.tsx +134 -94
  145. package/src/components/svg-image.tsx +10 -11
  146. package/src/components/tex-buttons.tsx +2 -2
  147. package/src/components/tooltip.tsx +189 -171
  148. package/src/components/visibility-observer/__stories__/visibility-observer.stories.tsx +1 -3
  149. package/src/error-boundary.tsx +4 -7
  150. package/src/interactive2/types.ts +2 -2
  151. package/src/multi-items/__stories__/multi-renderer.stories.tsx +1 -1
  152. package/src/multi-items/__tests__/__snapshots__/multi-renderer.test.tsx.snap +708 -764
  153. package/src/multi-items/__tests__/multi-renderer.test.tsx +2 -3
  154. package/src/perseus-types.ts +13 -12
  155. package/src/renderer.tsx +11 -22
  156. package/src/types.ts +0 -18
  157. package/src/util/graphie.ts +3 -3
  158. package/src/util/interactive.ts +18 -5
  159. package/src/util/tex.ts +13 -77
  160. package/src/util.ts +3 -4
  161. package/src/widgets/__stories__/categorizer.stories.tsx +1 -1
  162. package/src/widgets/__stories__/cs-program.stories.tsx +1 -1
  163. package/src/widgets/__stories__/definition.stories.tsx +3 -7
  164. package/src/widgets/__stories__/dropdown.stories.tsx +1 -1
  165. package/src/widgets/__stories__/explanation.stories.tsx +2 -2
  166. package/src/widgets/__stories__/expression.stories.tsx +5 -11
  167. package/src/widgets/__stories__/graded-group-set.stories.tsx +1 -1
  168. package/src/widgets/__stories__/graded-group.stories.tsx +1 -1
  169. package/src/widgets/__stories__/grapher.stories.tsx +7 -21
  170. package/src/widgets/__stories__/group.stories.tsx +1 -1
  171. package/src/widgets/__stories__/iframe.stories.tsx +1 -1
  172. package/src/widgets/__stories__/image.stories.tsx +1 -1
  173. package/src/widgets/__stories__/input-number.stories.tsx +3 -12
  174. package/src/widgets/__stories__/interaction.stories.tsx +1 -1
  175. package/src/widgets/__stories__/interactive-graph.stories.tsx +9 -9
  176. package/src/widgets/__stories__/matcher.stories.tsx +1 -1
  177. package/src/widgets/__stories__/matrix.stories.tsx +1 -1
  178. package/src/widgets/__stories__/number-line.stories.tsx +1 -1
  179. package/src/widgets/__stories__/numeric-input.stories.tsx +3 -5
  180. package/src/widgets/__stories__/orderer.stories.tsx +1 -1
  181. package/src/widgets/__stories__/passage-ref.stories.tsx +2 -2
  182. package/src/widgets/__stories__/passage.stories.tsx +3 -9
  183. package/src/widgets/__stories__/radio.stories.tsx +3 -5
  184. package/src/widgets/__stories__/sorter.stories.tsx +1 -1
  185. package/src/widgets/__stories__/test-keypad-context-wrapper.tsx +2 -4
  186. package/src/widgets/__stories__/transformer.stories.tsx +1 -1
  187. package/src/widgets/__stories__/unit.stories.tsx +1 -3
  188. package/src/widgets/__stories__/video-transcript-link.stories.tsx +2 -6
  189. package/src/widgets/__stories__/video.stories.tsx +1 -1
  190. package/src/widgets/__testdata__/group.testdata.ts +0 -2
  191. package/src/widgets/__tests__/__snapshots__/categorizer.test.ts.snap +717 -773
  192. package/src/widgets/__tests__/__snapshots__/cs-program.test.ts.snap +28 -36
  193. package/src/widgets/__tests__/__snapshots__/definition.test.ts.snap +52 -60
  194. package/src/widgets/__tests__/__snapshots__/dropdown.test.ts.snap +100 -108
  195. package/src/widgets/__tests__/__snapshots__/explanation.test.ts.snap +212 -260
  196. package/src/widgets/__tests__/__snapshots__/graded-group-set-jipt.test.ts.snap +613 -641
  197. package/src/widgets/__tests__/__snapshots__/graded-group-set.test.ts.snap +249 -261
  198. package/src/widgets/__tests__/__snapshots__/graded-group.test.ts.snap +671 -735
  199. package/src/widgets/__tests__/__snapshots__/grapher.test.ts.snap +2676 -2684
  200. package/src/widgets/__tests__/__snapshots__/group.test.tsx.snap +938 -1002
  201. package/src/widgets/__tests__/__snapshots__/iframe.test.ts.snap +28 -36
  202. package/src/widgets/__tests__/__snapshots__/image.test.ts.snap +227 -255
  203. package/src/widgets/__tests__/__snapshots__/input-number.test.ts.snap +353 -357
  204. package/src/widgets/__tests__/__snapshots__/interaction.test.ts.snap +255 -259
  205. package/src/widgets/__tests__/__snapshots__/interactive-graph.test.ts.snap +2401 -2433
  206. package/src/widgets/__tests__/__snapshots__/matcher.test.tsx.snap +600 -756
  207. package/src/widgets/__tests__/__snapshots__/matrix.test.ts.snap +420 -428
  208. package/src/widgets/__tests__/__snapshots__/number-line.test.ts.snap +762 -770
  209. package/src/widgets/__tests__/__snapshots__/numeric-input.test.ts.snap +373 -393
  210. package/src/widgets/__tests__/__snapshots__/orderer.test.ts.snap +116 -148
  211. package/src/widgets/__tests__/__snapshots__/passage-ref.test.ts.snap +289 -301
  212. package/src/widgets/__tests__/__snapshots__/passage.test.tsx.snap +1679 -1711
  213. package/src/widgets/__tests__/__snapshots__/radio.test.ts.snap +2692 -2960
  214. package/src/widgets/__tests__/__snapshots__/video.test.ts.snap +90 -98
  215. package/src/widgets/__tests__/group.test.tsx +0 -2
  216. package/src/widgets/__tests__/matcher.test.tsx +33 -9
  217. package/src/widgets/__tests__/radio/focus-ring.test.tsx +0 -1
  218. package/src/widgets/expression.tsx +12 -9
  219. package/src/widgets/grapher.tsx +3 -3
  220. package/src/widgets/image.tsx +2 -2
  221. package/src/widgets/interaction/element-container.tsx +7 -8
  222. package/src/widgets/interactive-graph.tsx +5 -5
  223. package/src/widgets/label-image/__stories__/answer-choices.stories.tsx +2 -4
  224. package/src/widgets/label-image/__stories__/marker.stories.tsx +9 -19
  225. package/src/widgets/label-image/marker.tsx +4 -4
  226. package/src/widgets/matcher.tsx +43 -24
  227. package/src/widgets/number-line.tsx +1 -1
  228. package/src/widgets/numeric-input.tsx +0 -3
  229. package/src/widgets/passage/passage-markdown.tsx +2 -2
  230. package/src/widgets/radio/__stories__/base-radio.stories.tsx +11 -19
  231. package/src/widgets/radio/__stories__/choice-icon.stories.tsx +9 -11
  232. package/src/widgets/radio/__stories__/choice-none-above.stories.tsx +1 -1
  233. package/src/widgets/radio/__stories__/choice.stories.tsx +4 -4
  234. package/src/widgets/radio/__stories__/focus-ring.stories.tsx +1 -1
  235. package/src/widgets/radio/__stories__/option-status.stories.tsx +2 -4
  236. package/src/widgets/radio/base-radio.tsx +1 -1
  237. package/src/widgets/radio/choice-icon/choice-icon.tsx +5 -5
  238. package/src/widgets/radio/choice-icon/cross-out-line.tsx +1 -3
  239. package/src/widgets/radio/choice-none-above.tsx +2 -2
  240. package/src/widgets/radio/choice.tsx +1 -3
  241. package/src/widgets/radio/focus-ring.tsx +1 -1
  242. package/src/widgets/radio/option-status.tsx +2 -4
  243. package/src/widgets/radio/widget.tsx +0 -1
  244. package/src/widgets/reaction-diagram.tsx +2 -2
  245. package/src/widgets/simulator.tsx +4 -6
  246. package/src/widgets/video-transcript-link.tsx +1 -1
  247. package/{tsconfig.json → tsconfig-build.json} +6 -6
  248. package/tsconfig-build.tsbuildinfo +1 -0
  249. package/tsconfig.tsbuildinfo +0 -1
@@ -22,7 +22,7 @@ export type TrackedSelection = {
22
22
  proposedHighlight: DOMHighlight;
23
23
  };
24
24
 
25
- type SelectionTrackerProps = {
25
+ type Props = {
26
26
  // A function that builds a DOMHighlight from the given DOMRange, if
27
27
  // possible. If it would not currently be valid to add a highlight over the
28
28
  // given DOMRange, returns null.
@@ -38,7 +38,7 @@ type SelectionTrackerProps = {
38
38
  enabled: boolean;
39
39
  };
40
40
 
41
- type SelectionTrackerState = {
41
+ type State = {
42
42
  // The current state of the mouse button. We distinguish between down,
43
43
  // down and the selection has changed since going down, and up.
44
44
  mouseState: "down" | "down-and-selecting" | "up";
@@ -46,11 +46,8 @@ type SelectionTrackerState = {
46
46
  trackedSelection: TrackedSelection | null | undefined;
47
47
  };
48
48
 
49
- class SelectionTracker extends React.PureComponent<
50
- SelectionTrackerProps,
51
- SelectionTrackerState
52
- > {
53
- state: SelectionTrackerState = {
49
+ class SelectionTracker extends React.PureComponent<Props, State> {
50
+ state: State = {
54
51
  mouseState: "up",
55
52
  trackedSelection: null,
56
53
  };
@@ -59,7 +56,7 @@ class SelectionTracker extends React.PureComponent<
59
56
  this._updateListeners(false, this.props.enabled);
60
57
  }
61
58
 
62
- componentDidUpdate(prevProps: SelectionTrackerProps) {
59
+ componentDidUpdate(prevProps: Props) {
63
60
  if (this.props.buildHighlight !== prevProps.buildHighlight) {
64
61
  // The highlight-building function changed, so the
65
62
  // proposedHighlight we built with it might be different, or no
@@ -18,7 +18,7 @@ import {PerseusError} from "../../perseus-error";
18
18
 
19
19
  import type {DOMRange} from "./types";
20
20
 
21
- type WordIndexerProps = {
21
+ type Props = {
22
22
  // The content to display and traverse in search of words.
23
23
  children?: React.ReactElement<any>;
24
24
  // After each mount and update, this callback is called with the list of
@@ -26,7 +26,7 @@ type WordIndexerProps = {
26
26
  onWordsUpdate: (wordRanges: ReadonlyArray<DOMRange>) => unknown;
27
27
  };
28
28
 
29
- class WordIndexer extends React.PureComponent<WordIndexerProps> {
29
+ class WordIndexer extends React.PureComponent<Props> {
30
30
  _container: HTMLElement | null | undefined;
31
31
  /* eslint-enable react/sort-comp */
32
32
 
@@ -1,127 +1,116 @@
1
1
  import {StyleSheet, css} from "aphrodite";
2
- import PropTypes from "prop-types";
3
2
  import * as React from "react";
4
3
 
5
4
  import * as constants from "../styles/constants";
6
5
 
7
- class HUD extends React.Component<any> {
8
- static propTypes = {
9
- message: PropTypes.string.isRequired,
10
- enabled: PropTypes.bool.isRequired,
11
- onClick: PropTypes.func.isRequired,
12
- fixedPosition: PropTypes.bool,
13
- };
6
+ // Displays a stylized open eye: lint warnings are visible
7
+ const VisibleIcon = () => (
8
+ <svg
9
+ width="24"
10
+ height="24"
11
+ viewBox="0 0 24 24"
12
+ className={css(styles.icon)}
13
+ >
14
+ <defs>
15
+ <path
16
+ id="a"
17
+ d={
18
+ "M7.401 10.035c-1.424.748-2.599 1.905-3.544 " +
19
+ "3.48a1 1 0 0 1-1.714-1.03C4.325 8.849 7.652 7 " +
20
+ "12 7c4.348 0 7.675 1.848 9.857 5.486a1 1 0 0 " +
21
+ "1-1.714 1.028c-.945-1.574-2.12-2.73-3.544-" +
22
+ "3.48a5 5 0 1 1-9.198 0zM12 15a3 3 0 1 0 0-6 3 3 " +
23
+ "0 0 0 0 6z"
24
+ }
25
+ />
26
+ </defs>
27
+ <g fill="none" fillRule="evenodd">
28
+ <path fill="none" d="M0 0h24v24H0z" />
29
+ <mask id="b" fill="#fff">
30
+ <use href="#a" />
31
+ </mask>
32
+ <use fill="#fff" fillRule="nonzero" href="#a" />
33
+ <g fill="#fff" mask="url(#b)">
34
+ <path d="M0 0h24v24H0z" />
35
+ </g>
36
+ </g>
37
+ </svg>
38
+ );
14
39
 
15
- static defaultProps: any = {
16
- fixedPosition: true,
17
- };
40
+ // Displays a stylized eye with a line through it: I don't want to see lint
41
+ const HiddenIcon = () => (
42
+ <svg
43
+ width="24"
44
+ height="24"
45
+ viewBox="0 0 24 24"
46
+ className={css(styles.icon)}
47
+ >
48
+ <defs>
49
+ <path
50
+ id="a"
51
+ d={
52
+ "M8.794 7.38C9.791 7.127 10.86 7 12 7c4.348 0 " +
53
+ "7.675 1.848 9.857 5.486a1 1 0 0 1-1.714 " +
54
+ "1.028c-.945-1.574-2.12-2.73-3.544-3.48.258." +
55
+ "604.401 1.268.401 1.966 0 1.02-.305 " +
56
+ "1.967-.828 2.757l2.535 2.536a1 1 0 0 " +
57
+ "1-1.414 1.414l-12-12a1 1 0 0 1 " +
58
+ "1.414-1.414L8.794 7.38zm5.914 5.913a3 3 0 0 " +
59
+ "0-4.001-4.001l4 4.001zM6.072 8.486l2.976 " +
60
+ "2.976a3 3 0 0 0 3.49 3.49l1.579 1.58A5 5 0 " +
61
+ "0 1 7.4 10.035c-1.424.747-2.599 1.904-3.544 " +
62
+ "3.478a1 1 0 0 1-1.714-1.028c1.049-1.75 " +
63
+ "2.363-3.085 3.929-4z"
64
+ }
65
+ />
66
+ </defs>
67
+ <g fill="none" fillRule="evenodd">
68
+ <path fill="none" d="M0 0h24v24H0z" />
69
+ <mask id="b" fill="#fff">
70
+ <use href="#a" />
71
+ </mask>
72
+ <use fill="#fff" fillRule="nonzero" href="#a" />
73
+ <g fill="#fff" mask="url(#b)">
74
+ <path d="M0 0h24v24H0z" />
75
+ </g>
76
+ </g>
77
+ </svg>
78
+ );
18
79
 
19
- // Displays a stylized open eye: lint warnings are visible
20
- renderVisibleIcon: () => React.ReactElement = () => {
21
- return (
22
- <svg
23
- width="24"
24
- height="24"
25
- viewBox="0 0 24 24"
26
- className={css(styles.icon)}
27
- >
28
- <defs>
29
- <path
30
- id="a"
31
- d={
32
- "M7.401 10.035c-1.424.748-2.599 1.905-3.544 " +
33
- "3.48a1 1 0 0 1-1.714-1.03C4.325 8.849 7.652 7 " +
34
- "12 7c4.348 0 7.675 1.848 9.857 5.486a1 1 0 0 " +
35
- "1-1.714 1.028c-.945-1.574-2.12-2.73-3.544-" +
36
- "3.48a5 5 0 1 1-9.198 0zM12 15a3 3 0 1 0 0-6 3 3 " +
37
- "0 0 0 0 6z"
38
- }
39
- />
40
- </defs>
41
- <g fill="none" fillRule="evenodd">
42
- <path fill="none" d="M0 0h24v24H0z" />
43
- <mask id="b" fill="#fff">
44
- <use href="#a" />
45
- </mask>
46
- <use fill="#fff" fillRule="nonzero" href="#a" />
47
- <g fill="#fff" mask="url(#b)">
48
- <path d="M0 0h24v24H0z" />
49
- </g>
50
- </g>
51
- </svg>
52
- );
53
- };
80
+ type Props = {
81
+ message: string;
82
+ enabled: boolean;
83
+ onClick: () => void;
84
+ fixedPosition?: boolean;
85
+ };
54
86
 
55
- // Displays a stylized eye with a line through it: I don't want to see lint
56
- renderHiddenIcon: () => React.ReactElement = () => {
57
- return (
58
- <svg
59
- width="24"
60
- height="24"
61
- viewBox="0 0 24 24"
62
- className={css(styles.icon)}
63
- >
64
- <defs>
65
- <path
66
- id="a"
67
- d={
68
- "M8.794 7.38C9.791 7.127 10.86 7 12 7c4.348 0 " +
69
- "7.675 1.848 9.857 5.486a1 1 0 0 1-1.714 " +
70
- "1.028c-.945-1.574-2.12-2.73-3.544-3.48.258." +
71
- "604.401 1.268.401 1.966 0 1.02-.305 " +
72
- "1.967-.828 2.757l2.535 2.536a1 1 0 0 " +
73
- "1-1.414 1.414l-12-12a1 1 0 0 1 " +
74
- "1.414-1.414L8.794 7.38zm5.914 5.913a3 3 0 0 " +
75
- "0-4.001-4.001l4 4.001zM6.072 8.486l2.976 " +
76
- "2.976a3 3 0 0 0 3.49 3.49l1.579 1.58A5 5 0 " +
77
- "0 1 7.4 10.035c-1.424.747-2.599 1.904-3.544 " +
78
- "3.478a1 1 0 0 1-1.714-1.028c1.049-1.75 " +
79
- "2.363-3.085 3.929-4z"
80
- }
81
- />
82
- </defs>
83
- <g fill="none" fillRule="evenodd">
84
- <path fill="none" d="M0 0h24v24H0z" />
85
- <mask id="b" fill="#fff">
86
- <use href="#a" />
87
- </mask>
88
- <use fill="#fff" fillRule="nonzero" href="#a" />
89
- <g fill="#fff" mask="url(#b)">
90
- <path d="M0 0h24v24H0z" />
91
- </g>
92
- </g>
93
- </svg>
94
- );
95
- };
96
-
97
- render(): React.ReactNode {
98
- let state;
99
- let icon;
100
- if (this.props.enabled) {
101
- state = styles.enabled;
102
- icon = this.renderVisibleIcon();
103
- } else {
104
- state = styles.disabled;
105
- icon = this.renderHiddenIcon();
106
- }
107
-
108
- return (
109
- <button
110
- className={css(
111
- styles.hud,
112
- this.props.fixedPosition && styles.hudFixedPosition,
113
- state,
114
- )}
115
- onClick={(e) => {
116
- this.props.onClick();
117
- }}
118
- >
119
- {icon}
120
- {this.props.message}
121
- </button>
122
- );
87
+ const HUD = ({message, enabled, onClick, fixedPosition = true}: Props) => {
88
+ let state;
89
+ let icon;
90
+ if (enabled) {
91
+ state = styles.enabled;
92
+ icon = <VisibleIcon />;
93
+ } else {
94
+ state = styles.disabled;
95
+ icon = <HiddenIcon />;
123
96
  }
124
- }
97
+
98
+ return (
99
+ <button
100
+ className={css(
101
+ styles.hud,
102
+ fixedPosition && styles.hudFixedPosition,
103
+ state,
104
+ )}
105
+ onClick={(e) => {
106
+ onClick();
107
+ }}
108
+ >
109
+ {icon}
110
+ {message}
111
+ </button>
112
+ );
113
+ };
125
114
 
126
115
  const styles = StyleSheet.create({
127
116
  hud: {
@@ -1,4 +1,18 @@
1
- /* eslint-disable react/forbid-prop-types */
1
+ import * as React from "react";
2
+
3
+ type InlineIconProps = {
4
+ // An SVG path to render.
5
+ path: string;
6
+ // The path's viewBox dimensions.
7
+ // We set the viewport height to 1em and scale the width accordingly.
8
+ height: number;
9
+ width: number;
10
+ style?: React.CSSProperties;
11
+ // A11y description for this icon. If absent, icon is marked
12
+ // aria-hidden=true
13
+ title?: string;
14
+ };
15
+
2
16
  /**
3
17
  * A stripped version of Icon.jsx from webapp. Takes an SVG icon and renders it
4
18
  * inline like Font Awesome did.
@@ -23,16 +37,13 @@
23
37
  * <InlineIcon {...editIcon} />
24
38
  *
25
39
  */
26
- import PropTypes from "prop-types";
27
- import * as React from "react";
28
-
29
- const InlineIcon: React.FC<InlineIconProps> = ({
40
+ const InlineIcon = ({
30
41
  path,
31
42
  width,
32
43
  height,
33
44
  style = {},
34
45
  title,
35
- }): React.ReactElement => (
46
+ }: InlineIconProps): React.ReactElement => (
36
47
  <svg
37
48
  role="img"
38
49
  aria-hidden={!title}
@@ -46,32 +57,4 @@ const InlineIcon: React.FC<InlineIconProps> = ({
46
57
  </svg>
47
58
  );
48
59
 
49
- InlineIcon.propTypes = {
50
- // An SVG path to render.
51
- path: PropTypes.string.isRequired,
52
-
53
- // The path's viewBox dimensions.
54
- // We set the viewport height to 1em and scale the width accordingly.
55
- height: PropTypes.number.isRequired,
56
- width: PropTypes.number.isRequired,
57
-
58
- style: PropTypes.object,
59
-
60
- // A11y description for this icon. If absent, icon is marked
61
- // aria-hidden=true
62
- title: PropTypes.string,
63
- };
64
- export type InlineIconProps = {
65
- // An SVG path to render.
66
- path: string;
67
- // The path's viewBox dimensions.
68
- // We set the viewport height to 1em and scale the width accordingly.
69
- height: number;
70
- width: number;
71
- style?: any;
72
- // A11y description for this icon. If absent, icon is marked
73
- // aria-hidden=true
74
- title?: string;
75
- };
76
-
77
60
  export default InlineIcon;
@@ -10,7 +10,7 @@ import Util from "../util";
10
10
  import MathInput from "./math-input";
11
11
  import MathOutput from "./math-output";
12
12
  import TextInput from "./text-input";
13
- import Tooltip from "./tooltip";
13
+ import Tooltip, {HorizontalDirection, VerticalDirection} from "./tooltip";
14
14
 
15
15
  import type {LinterContextProps} from "../types";
16
16
  import type {StyleType} from "@khanacademy/wonder-blocks-core";
@@ -184,9 +184,9 @@ class InputWithExamples extends React.Component<Props, State> {
184
184
  // eslint-disable-next-line react/no-string-refs
185
185
  ref="tooltip"
186
186
  className="perseus-formats-tooltip preview-measure"
187
- horizontalPosition="left"
188
- horizontalAlign="left"
189
- verticalPosition="bottom"
187
+ horizontalPosition={HorizontalDirection.Left}
188
+ horizontalAlign={HorizontalDirection.Left}
189
+ verticalPosition={VerticalDirection.Bottom}
190
190
  arrowSize={10}
191
191
  borderColor="#ccc"
192
192
  show={showExamples}
@@ -1,3 +1,47 @@
1
+ import {StyleSheet, css} from "aphrodite";
2
+ import * as React from "react";
3
+ import ReactDOM from "react-dom";
4
+
5
+ import * as constants from "../styles/constants";
6
+
7
+ import InlineIcon from "./inline-icon";
8
+
9
+ const exclamationIcon = {
10
+ path: "M6 11a1 1 0 1 1 0-2 1 1 0 0 1 0 2zm0-9a1 1 0 0 1 1 1v4a1 1 0 1 1-2 0V3a1 1 0 0 1 1-1z",
11
+ height: 12,
12
+ width: 12,
13
+ } as const;
14
+
15
+ enum Severity {
16
+ Error = 1,
17
+ Warning = 2,
18
+ Recommendation = 3,
19
+ OfflineReportingOnly = 4,
20
+ }
21
+
22
+ type Props = {
23
+ // The children are the linty content we're highlighting
24
+ children: React.ReactNode;
25
+ // Inline lint is highlighted differently than block lint.
26
+ inline?: boolean;
27
+ // This is the text that appears in the tooltip
28
+ message: string;
29
+ // This is used as the fragment id (hash) in the URL of the link
30
+ ruleName: string;
31
+ // Lint warnings inside tables are handled specially
32
+ insideTable: boolean;
33
+ // Should lint highlighting be rendered as a block to the left of
34
+ // the lint instead of on the right gutter?
35
+ blockHighlight?: boolean;
36
+ // How important this lint message is for the editor. Severity goes
37
+ // from 1 (indicating an error) to 4 (offline reporting only)
38
+ severity?: Severity;
39
+ };
40
+
41
+ type State = {
42
+ tooltipAbove: boolean;
43
+ };
44
+
1
45
  /**
2
46
  * This component renders "lint" nodes in a markdown parse tree. Lint nodes
3
47
  * are inserted into the tree by the Perseus linter (see
@@ -20,45 +64,8 @@
20
64
  * that has a right margin (like anything blockquoted) the circle will appear
21
65
  * to the left of where it belongs. And if there is more
22
66
  **/
23
- import {StyleSheet, css} from "aphrodite";
24
- import PropTypes from "prop-types";
25
- import * as React from "react";
26
- import ReactDOM from "react-dom";
27
-
28
- import * as constants from "../styles/constants";
29
-
30
- import InlineIcon from "./inline-icon";
31
-
32
- const exclamationIcon = {
33
- path: "M6 11a1 1 0 1 1 0-2 1 1 0 0 1 0 2zm0-9a1 1 0 0 1 1 1v4a1 1 0 1 1-2 0V3a1 1 0 0 1 1-1z",
34
- height: 12,
35
- width: 12,
36
- } as const;
37
-
38
- type Props = any;
39
- type State = any;
40
-
41
67
  class Lint extends React.Component<Props, State> {
42
- _positionTimeout: number | null | undefined;
43
-
44
- static propTypes = {
45
- // The children are the linty content we're highlighting
46
- children: PropTypes.node,
47
- // Inline lint is highlighted differently than block lint.
48
- inline: PropTypes.bool,
49
- // This is the text that appears in the tooltip
50
- message: PropTypes.string.isRequired,
51
- // This is used as the fragment id (hash) in the URL of the link
52
- ruleName: PropTypes.string.isRequired,
53
- // Lint warnings inside tables are handled specially
54
- insideTable: PropTypes.bool.isRequired,
55
- // Should lint highlighting be rendered as a block to the left of
56
- // the lint instead of on the right gutter?
57
- blockHighlight: PropTypes.bool,
58
- // How important this lint message is for the editor. Severity goes
59
- // from 1 (indicating an error) to 4 (offline reporting only)
60
- severity: PropTypes.number,
61
- };
68
+ _positionTimeout: number | undefined;
62
69
 
63
70
  state: State = {
64
71
  tooltipAbove: true,
@@ -73,7 +80,6 @@ class Lint extends React.Component<Props, State> {
73
80
  componentWillUnmount() {
74
81
  // TODO(somewhatabstract): Use WB timing
75
82
  // eslint-disable-next-line no-restricted-syntax
76
- // @ts-expect-error [FEI-5003] - TS2769 - No overload matches this call.
77
83
  window.clearTimeout(this._positionTimeout);
78
84
  }
79
85
 
@@ -98,11 +104,11 @@ class Lint extends React.Component<Props, State> {
98
104
  let severityStyle;
99
105
  let warningText;
100
106
  let warningTextStyle;
101
- if (this.props.severity === 1) {
107
+ if (this.props.severity === Severity.Error) {
102
108
  severityStyle = styles.indicatorError;
103
109
  warningText = "Error";
104
110
  warningTextStyle = styles.publishBlockingError;
105
- } else if (this.props.severity === 2) {
111
+ } else if (this.props.severity === Severity.Warning) {
106
112
  severityStyle = styles.indicatorWarning;
107
113
  warningText = "Warning";
108
114
  warningTextStyle = styles.warning;
@@ -1,6 +1,5 @@
1
1
  /* eslint-disable react/sort-comp */
2
2
  import $ from "jquery";
3
- import PropTypes from "prop-types";
4
3
  import * as React from "react";
5
4
  import ReactDOM from "react-dom";
6
5
  import _ from "underscore";
@@ -11,22 +10,29 @@ import TexWrangler from "../tex-wrangler";
11
10
 
12
11
  const ModifyTex = TexWrangler.modifyTex;
13
12
 
14
- class MathOutput extends React.Component<any, any> {
15
- static propTypes = {
16
- value: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
17
- className: PropTypes.string,
18
- labelText: PropTypes.string,
19
- onFocus: PropTypes.func,
20
- onBlur: PropTypes.func,
21
- };
13
+ type Props = {
14
+ value: string | number;
15
+ className?: string;
16
+ labelText?: string;
17
+ onFocus: () => void;
18
+ onBlur: () => void;
19
+ };
20
+
21
+ type DefaultProps = Pick<Props, "value" | "onFocus" | "onBlur">;
22
+
23
+ type State = {
24
+ focused: boolean;
25
+ selectorNamespace: string;
26
+ };
22
27
 
23
- static defaultProps: any = {
28
+ class MathOutput extends React.Component<Props, State> {
29
+ static defaultProps: DefaultProps = {
24
30
  value: "",
25
31
  onFocus: function () {},
26
32
  onBlur: function () {},
27
33
  };
28
34
 
29
- state: any = {
35
+ state: State = {
30
36
  focused: false,
31
37
  selectorNamespace: _.uniqueId("math-output"),
32
38
  };
@@ -10,13 +10,15 @@
10
10
 
11
11
  import {
12
12
  KeypadInput,
13
- KeypadTypes,
13
+ KeypadType,
14
14
  keypadElementPropType,
15
15
  } from "@khanacademy/math-input";
16
16
  import PropTypes from "prop-types";
17
17
  import * as React from "react";
18
18
 
19
19
  export default class SimpleKeypadInput extends React.Component<any> {
20
+ _isMounted = false;
21
+
20
22
  componentDidMount() {
21
23
  // TODO(scottgrant): This is a hack to remove the deprecated call to
22
24
  // this.isMounted() but is still considered an anti-pattern.
@@ -27,8 +29,6 @@ export default class SimpleKeypadInput extends React.Component<any> {
27
29
  this._isMounted = false;
28
30
  }
29
31
 
30
- _isMounted = false;
31
-
32
32
  focus() {
33
33
  // @ts-expect-error [FEI-5003] - TS2339 - Property 'focus' does not exist on type 'ReactInstance'.
34
34
  this.refs.input.focus(); // eslint-disable-line react/no-string-refs
@@ -61,7 +61,7 @@ export default class SimpleKeypadInput extends React.Component<any> {
61
61
  if (keypadElement) {
62
62
  keypadElement.configure(
63
63
  {
64
- keypadType: KeypadTypes.FRACTION,
64
+ keypadType: KeypadType.FRACTION,
65
65
  },
66
66
  () => {
67
67
  if (_this._isMounted) {