@khanacademy/math-input 0.7.2 → 1.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 (176) hide show
  1. package/CHANGELOG.md +10 -0
  2. package/dist/actions/index.d.ts +31 -0
  3. package/dist/actions/index.js.flow +40 -0
  4. package/dist/components/compute-layout-parameters.d.ts +38 -0
  5. package/dist/components/compute-layout-parameters.js.flow +49 -0
  6. package/dist/components/corner-decal.d.ts +12 -0
  7. package/dist/components/corner-decal.js.flow +15 -0
  8. package/dist/components/echo-manager.d.ts +26 -0
  9. package/dist/components/echo-manager.js.flow +29 -0
  10. package/dist/components/empty-keypad-button.d.ts +13 -0
  11. package/dist/components/empty-keypad-button.js.flow +23 -0
  12. package/dist/components/expression-keypad.d.ts +22 -0
  13. package/dist/components/expression-keypad.js.flow +32 -0
  14. package/dist/components/fraction-keypad.d.ts +21 -0
  15. package/dist/components/fraction-keypad.js.flow +30 -0
  16. package/dist/components/gesture-manager.d.ts +74 -0
  17. package/dist/components/gesture-manager.js.flow +82 -0
  18. package/dist/components/gesture-state-machine.d.ts +105 -0
  19. package/dist/components/gesture-state-machine.js.flow +118 -0
  20. package/dist/components/icon.d.ts +15 -0
  21. package/dist/components/icon.js.flow +18 -0
  22. package/dist/components/input/__tests__/test-math-wrapper.d.ts +8 -0
  23. package/dist/components/input/__tests__/test-math-wrapper.js.flow +14 -0
  24. package/dist/components/input/cursor-handle.d.ts +1 -1
  25. package/dist/components/input/cursor-handle.js.flow +1 -1
  26. package/dist/components/input/drag-listener.d.ts +13 -0
  27. package/dist/components/input/drag-listener.js.flow +19 -0
  28. package/dist/components/input/math-input.d.ts +5 -4
  29. package/dist/components/input/math-input.js.flow +5 -4
  30. package/dist/components/input/math-wrapper.d.ts +110 -0
  31. package/dist/components/input/math-wrapper.js.flow +125 -0
  32. package/dist/components/input/scroll-into-view.d.ts +11 -0
  33. package/dist/components/input/scroll-into-view.js.flow +20 -0
  34. package/dist/components/keypad/button-assets.d.ts +4 -3
  35. package/dist/components/keypad/button-assets.js.flow +3 -3
  36. package/dist/components/keypad/button.d.ts +1 -2
  37. package/dist/components/keypad/button.js.flow +1 -2
  38. package/dist/components/keypad/keypad-page-items.d.ts +15 -10
  39. package/dist/components/keypad/keypad-page-items.js.flow +20 -10
  40. package/dist/components/keypad-button.d.ts +52 -0
  41. package/dist/components/keypad-button.js.flow +79 -0
  42. package/dist/components/keypad-container.d.ts +40 -0
  43. package/dist/components/keypad-container.js.flow +58 -0
  44. package/dist/components/keypad.d.ts +31 -0
  45. package/dist/components/keypad.js.flow +40 -0
  46. package/dist/components/many-keypad-button.d.ts +15 -0
  47. package/dist/components/many-keypad-button.js.flow +17 -0
  48. package/dist/components/math-icon.d.ts +16 -0
  49. package/dist/components/math-icon.js.flow +19 -0
  50. package/dist/components/multi-symbol-grid.d.ts +14 -0
  51. package/dist/components/multi-symbol-grid.js.flow +16 -0
  52. package/dist/components/multi-symbol-popover.d.ts +12 -0
  53. package/dist/components/multi-symbol-popover.js.flow +15 -0
  54. package/dist/components/navigation-pad.d.ts +14 -0
  55. package/dist/components/navigation-pad.js.flow +16 -0
  56. package/dist/components/node-manager.d.ts +53 -0
  57. package/dist/components/node-manager.js.flow +65 -0
  58. package/dist/components/popover-manager.d.ts +13 -0
  59. package/dist/components/popover-manager.js.flow +15 -0
  60. package/dist/components/popover-state-machine.d.ts +75 -0
  61. package/dist/components/popover-state-machine.js.flow +83 -0
  62. package/dist/components/provided-keypad.d.ts +8 -7
  63. package/dist/components/provided-keypad.js.flow +8 -7
  64. package/dist/components/styles.d.ts +6 -0
  65. package/dist/components/styles.js.flow +13 -0
  66. package/dist/components/svg-icon.d.ts +12 -0
  67. package/dist/components/svg-icon.js.flow +15 -0
  68. package/dist/components/tabbar/icons.d.ts +3 -2
  69. package/dist/components/tabbar/icons.js.flow +3 -2
  70. package/dist/components/tabbar/item.d.ts +1 -2
  71. package/dist/components/tabbar/item.js.flow +1 -2
  72. package/dist/components/tabbar/tabbar.d.ts +3 -3
  73. package/dist/components/tabbar/tabbar.js.flow +3 -3
  74. package/dist/components/text-icon.d.ts +13 -0
  75. package/dist/components/text-icon.js.flow +16 -0
  76. package/dist/components/touchable-keypad-button.d.ts +30 -0
  77. package/dist/components/touchable-keypad-button.js.flow +35 -0
  78. package/dist/components/two-page-keypad.d.ts +20 -0
  79. package/dist/components/two-page-keypad.js.flow +30 -0
  80. package/dist/components/velocity-tracker.d.ts +48 -0
  81. package/dist/components/velocity-tracker.js.flow +54 -0
  82. package/dist/es/index.js +938 -1059
  83. package/dist/es/index.js.map +1 -1
  84. package/dist/fake-react-native-web/text.d.ts +2 -1
  85. package/dist/fake-react-native-web/text.js.flow +2 -1
  86. package/dist/fake-react-native-web/view.d.ts +3 -2
  87. package/dist/fake-react-native-web/view.js.flow +3 -2
  88. package/dist/index.d.ts +1 -1
  89. package/dist/index.js +988 -1089
  90. package/dist/index.js.flow +1 -4
  91. package/dist/index.js.map +1 -1
  92. package/dist/store/echo-reducer.d.ts +5 -0
  93. package/dist/store/echo-reducer.js.flow +14 -0
  94. package/dist/store/index.d.ts +46 -1
  95. package/dist/store/index.js.flow +64 -1
  96. package/dist/store/input-reducer.d.ts +7 -0
  97. package/dist/store/input-reducer.js.flow +16 -0
  98. package/dist/store/keypad-reducer.d.ts +9 -0
  99. package/dist/store/keypad-reducer.js.flow +18 -0
  100. package/dist/store/layout-reducer.d.ts +21 -0
  101. package/dist/store/layout-reducer.js.flow +30 -0
  102. package/dist/store/pager-reducer.d.ts +13 -0
  103. package/dist/store/pager-reducer.js.flow +22 -0
  104. package/dist/store/shared.d.ts +6 -0
  105. package/dist/store/shared.js.flow +13 -0
  106. package/dist/store/types.d.ts +57 -0
  107. package/dist/store/types.js.flow +63 -0
  108. package/dist/types.d.ts +50 -0
  109. package/dist/types.js.flow +61 -0
  110. package/package.json +1 -1
  111. package/src/actions/{index.js → index.ts} +5 -5
  112. package/src/components/__tests__/{gesture-state-machine_test.js → gesture-state-machine.test.ts} +5 -1
  113. package/src/components/__tests__/{two-page-keypad_test.js → two-page-keypad.test.tsx} +0 -2
  114. package/src/components/{corner-decal.js → corner-decal.tsx} +6 -5
  115. package/src/components/{echo-manager.js → echo-manager.tsx} +29 -24
  116. package/src/components/{empty-keypad-button.js → empty-keypad-button.tsx} +17 -10
  117. package/src/components/{expression-keypad.js → expression-keypad.tsx} +27 -25
  118. package/src/components/{fraction-keypad.js → fraction-keypad.tsx} +21 -16
  119. package/src/components/{gesture-manager.js → gesture-manager.tsx} +10 -4
  120. package/src/components/{gesture-state-machine.js → gesture-state-machine.ts} +49 -3
  121. package/src/components/{icon.js → icon.tsx} +12 -14
  122. package/src/components/input/cursor-handle.tsx +1 -1
  123. package/src/components/input/{drag-listener.js → drag-listener.ts} +4 -0
  124. package/src/components/input/math-input.tsx +10 -9
  125. package/src/components/input/{math-wrapper.js → math-wrapper.ts} +10 -6
  126. package/src/components/input/{scroll-into-view.js → scroll-into-view.ts} +5 -15
  127. package/src/components/keypad/button-assets.tsx +4 -5
  128. package/src/components/keypad/button.tsx +1 -2
  129. package/src/components/keypad/index.tsx +1 -1
  130. package/src/components/keypad/keypad-page-items.tsx +33 -10
  131. package/src/components/{keypad-button.js → keypad-button.tsx} +42 -37
  132. package/src/components/{keypad-container.js → keypad-container.tsx} +41 -23
  133. package/src/components/{keypad.js → keypad.tsx} +31 -23
  134. package/src/components/{many-keypad-button.js → many-keypad-button.tsx} +8 -6
  135. package/src/components/{math-icon.js → math-icon.tsx} +7 -6
  136. package/src/components/{multi-symbol-grid.js → multi-symbol-grid.tsx} +8 -8
  137. package/src/components/{multi-symbol-popover.js → multi-symbol-popover.tsx} +5 -6
  138. package/src/components/{navigation-pad.js → navigation-pad.tsx} +7 -6
  139. package/src/components/{node-manager.js → node-manager.ts} +16 -4
  140. package/src/components/{popover-manager.js → popover-manager.tsx} +13 -16
  141. package/src/components/{popover-state-machine.js → popover-state-machine.ts} +21 -2
  142. package/src/components/prop-types.js +1 -67
  143. package/src/components/provided-keypad.tsx +14 -12
  144. package/src/components/{svg-icon.js → svg-icon.tsx} +5 -6
  145. package/src/components/tabbar/icons.tsx +4 -2
  146. package/src/components/tabbar/item.tsx +1 -3
  147. package/src/components/tabbar/{tabbar.stories.js → tabbar.stories.tsx} +10 -1
  148. package/src/components/tabbar/tabbar.tsx +3 -3
  149. package/src/components/{text-icon.js → text-icon.tsx} +7 -6
  150. package/src/components/{touchable-keypad-button.js → touchable-keypad-button.tsx} +19 -16
  151. package/src/components/{two-page-keypad.js → two-page-keypad.tsx} +13 -9
  152. package/src/components/{velocity-tracker.js → velocity-tracker.ts} +14 -4
  153. package/src/fake-react-native-web/text.tsx +2 -1
  154. package/src/fake-react-native-web/view.tsx +3 -2
  155. package/src/index.ts +1 -4
  156. package/src/store/echo-reducer.ts +58 -0
  157. package/src/store/index.ts +14 -425
  158. package/src/store/input-reducer.ts +55 -0
  159. package/src/store/keypad-reducer.ts +62 -0
  160. package/src/store/layout-reducer.ts +133 -0
  161. package/src/store/pager-reducer.ts +141 -0
  162. package/src/store/shared.ts +12 -0
  163. package/src/store/types.ts +65 -0
  164. package/src/types.ts +69 -0
  165. package/tsconfig.tsbuildinfo +1 -1
  166. package/src/components/app.js +0 -73
  167. package/src/demo.js +0 -9
  168. package/src/native-app.js +0 -85
  169. /package/src/components/__tests__/{node-manager_test.js → node-manager.test.ts} +0 -0
  170. /package/src/components/{compute-layout-parameters.js → compute-layout-parameters.ts} +0 -0
  171. /package/src/components/input/__tests__/{context-tracking_test.js → context-tracking.test.ts} +0 -0
  172. /package/src/components/input/__tests__/{mathquill_test.js → mathquill.test.ts} +0 -0
  173. /package/src/components/input/__tests__/{test-math-wrapper.jsx → test-math-wrapper.ts} +0 -0
  174. /package/src/components/keypad/{button.stories.js → button.stories.tsx} +0 -0
  175. /package/src/components/{styles.js → styles.ts} +0 -0
  176. /package/src/components/tabbar/__tests__/{tabbar_test.js → tabbar.test.tsx} +0 -0
@@ -4,7 +4,6 @@
4
4
  */
5
5
 
6
6
  import {StyleSheet} from "aphrodite";
7
- import PropTypes from "prop-types";
8
7
  import * as React from "react";
9
8
 
10
9
  import {BorderStyles} from "../consts";
@@ -20,14 +19,16 @@ import {
20
19
  import Styles from "./styles";
21
20
  import TouchableKeypadButton from "./touchable-keypad-button";
22
21
 
22
+ import type {StyleType} from "@khanacademy/wonder-blocks-core";
23
+
23
24
  const {row, column, centered, stretch, roundedTopLeft} = Styles;
24
25
 
25
- class NavigationPad extends React.Component {
26
- static propTypes = {
27
- roundTopLeft: PropTypes.bool,
28
- style: PropTypes.any,
29
- };
26
+ type Props = {
27
+ roundTopLeft: boolean;
28
+ style: StyleType;
29
+ };
30
30
 
31
+ class NavigationPad extends React.Component<Props> {
31
32
  render() {
32
33
  // TODO(charlie): Disable the navigational arrows depending on the
33
34
  // cursor context.
@@ -1,3 +1,4 @@
1
+ import type {Border} from "../types";
1
2
  /**
2
3
  * A manager for our node-to-ID system. In particular, this class is
3
4
  * responsible for maintaing a mapping between DOM nodes and node IDs, and
@@ -7,6 +8,11 @@
7
8
  */
8
9
 
9
10
  class NodeManager {
11
+ _nodesById: Record<string, HTMLElement>;
12
+ _bordersById: Record<string, Border>;
13
+ _orderedIds: ReadonlyArray<string>;
14
+ _cachedBoundingBoxesById: Record<string, DOMRect>;
15
+
10
16
  constructor() {
11
17
  // A mapping from IDs to DOM nodes.
12
18
  this._nodesById = {};
@@ -43,7 +49,12 @@ class NodeManager {
43
49
  * @param {node} domNode - the DOM node linked to the identifier
44
50
  * @param {object} borders - an opaque object describing the node's borders
45
51
  */
46
- registerDOMNode(id, domNode, childIds, borders) {
52
+ registerDOMNode(
53
+ id: string,
54
+ domNode: HTMLElement,
55
+ childIds: ReadonlyArray<string>,
56
+ borders: Border,
57
+ ) {
47
58
  this._nodesById[id] = domNode;
48
59
  this._bordersById[id] = borders;
49
60
 
@@ -57,6 +68,7 @@ class NodeManager {
57
68
  const seenIds = {};
58
69
  for (const id of allIds) {
59
70
  if (!seenIds[id]) {
71
+ // @ts-expect-error TS2345
60
72
  orderedIds.push(id);
61
73
  seenIds[id] = true;
62
74
  }
@@ -70,7 +82,7 @@ class NodeManager {
70
82
  *
71
83
  * @param {string} id - the identifier of the node to unregister
72
84
  */
73
- unregisterDOMNode(id) {
85
+ unregisterDOMNode(id: string) {
74
86
  delete this._nodesById[id];
75
87
  }
76
88
 
@@ -83,7 +95,7 @@ class NodeManager {
83
95
  * @returns {null|string} - null or the identifier of the topmost node at
84
96
  * the given coordinates
85
97
  */
86
- idForCoords(x, y) {
98
+ idForCoords(x: number, y: number): string | void {
87
99
  for (const id of this._orderedIds) {
88
100
  const domNode = this._nodesById[id];
89
101
  if (domNode) {
@@ -110,7 +122,7 @@ class NodeManager {
110
122
  * @returns {object} - the bounding client rect for the given node, along
111
123
  * with its borders
112
124
  */
113
- layoutPropsForId(id) {
125
+ layoutPropsForId(id: string): {initialBounds: DOMRect; borders: Border} {
114
126
  if (!this._cachedBoundingBoxesById[id]) {
115
127
  const node = this._nodesById[id];
116
128
 
@@ -3,32 +3,29 @@
3
3
  * multi-functional keys.
4
4
  */
5
5
 
6
- import PropTypes from "prop-types";
7
6
  import * as React from "react";
8
7
  import {CSSTransition} from "react-transition-group";
9
8
 
10
9
  import KeyConfigs from "../data/key-configs";
11
10
 
12
11
  import MultiSymbolPopover from "./multi-symbol-popover";
13
- import {
14
- boundingBoxPropType,
15
- keyConfigPropType,
16
- popoverPropType,
17
- } from "./prop-types";
12
+
13
+ import type {Popover, KeyConfig} from "../types";
18
14
 
19
15
  // NOTE(charlie): These must be kept in sync with the transition durations and
20
16
  // classnames specified in popover.less.
21
17
  const animationTransitionName = "popover";
22
18
  const animationDurationMs = 200;
23
19
 
20
+ type Props = {
21
+ // TODO(matthewc) should be something like Bound, but couldn't fix errors
22
+ bounds: any;
23
+ childKeys: ReadonlyArray<KeyConfig>;
24
+ };
25
+
24
26
  // A container component used to position a popover absolutely at a specific
25
27
  // position.
26
- class PopoverContainer extends React.Component {
27
- static propTypes = {
28
- bounds: boundingBoxPropType.isRequired,
29
- childKeys: PropTypes.arrayOf(keyConfigPropType).isRequired,
30
- };
31
-
28
+ class PopoverContainer extends React.Component<Props> {
32
29
  render() {
33
30
  const {bounds, childKeys} = this.props;
34
31
 
@@ -45,11 +42,11 @@ class PopoverContainer extends React.Component {
45
42
  }
46
43
  }
47
44
 
48
- class PopoverManager extends React.Component {
49
- static propTypes = {
50
- popover: popoverPropType,
51
- };
45
+ type PopoverManagerProps = {
46
+ popover: Popover | null;
47
+ };
52
48
 
49
+ class PopoverManager extends React.Component<PopoverManagerProps> {
53
50
  render() {
54
51
  const {popover} = this.props;
55
52
 
@@ -5,7 +5,26 @@
5
5
  * is present.
6
6
  */
7
7
 
8
+ type ActiveNodesObjPopover = {
9
+ parentId: string;
10
+ childIds: ReadonlyArray<string>;
11
+ };
12
+
13
+ type ActiveNodesObj = {
14
+ popover: ActiveNodesObjPopover | null;
15
+ focus: string | null;
16
+ };
17
+
18
+ type Handlers = {
19
+ onActiveNodesChanged: (activeNodes: ActiveNodesObj) => void;
20
+ onClick: (keyId: string, domNodeId: string, inPopover: boolean) => void;
21
+ };
22
+
8
23
  class PopoverStateMachine {
24
+ handlers: Handlers;
25
+ popovers: Record<string, ReadonlyArray<string>>;
26
+ activePopover: string | null;
27
+
9
28
  constructor(handlers) {
10
29
  this.handlers = handlers;
11
30
 
@@ -104,8 +123,8 @@ class PopoverStateMachine {
104
123
  this.activePopover = id;
105
124
  this.handlers.onActiveNodesChanged({
106
125
  popover: {
107
- parentId: this.activePopover,
108
- childIds: this.popovers[this.activePopover],
126
+ parentId: id,
127
+ childIds: this.popovers[id],
109
128
  },
110
129
  focus: this._defaultNodeForPopover(this.activePopover),
111
130
  });
@@ -4,38 +4,8 @@
4
4
 
5
5
  import PropTypes from "prop-types";
6
6
 
7
- import {
8
- BorderDirections,
9
- EchoAnimationTypes,
10
- IconTypes,
11
- KeyTypes,
12
- KeypadTypes,
13
- } from "../consts";
14
- import KeyConfigs from "../data/key-configs";
15
-
16
- import * as CursorContexts from "./input/cursor-contexts";
17
-
18
- export const iconPropType = PropTypes.shape({
19
- type: PropTypes.oneOf(Object.keys(IconTypes)).isRequired,
20
- data: PropTypes.string.isRequired,
21
- });
22
-
23
- export const keyIdPropType = PropTypes.oneOf(Object.keys(KeyConfigs));
24
-
25
- export const keyConfigPropType = PropTypes.shape({
26
- ariaLabel: PropTypes.string,
27
- id: keyIdPropType.isRequired,
28
- type: PropTypes.oneOf(Object.keys(KeyTypes)).isRequired,
29
- childKeyIds: PropTypes.arrayOf(keyIdPropType),
30
- icon: iconPropType.isRequired,
31
- });
32
-
33
- export const keypadConfigurationPropType = PropTypes.shape({
34
- keypadType: PropTypes.oneOf(Object.keys(KeypadTypes)).isRequired,
35
- extraKeys: PropTypes.arrayOf(keyIdPropType),
36
- });
37
-
38
7
  // NOTE(jared): This is no longer guaranteed to be React element
8
+ // NOTE(matthewc): only seems to be used in Perseus
39
9
  export const keypadElementPropType = PropTypes.shape({
40
10
  activate: PropTypes.func.isRequired,
41
11
  dismiss: PropTypes.func.isRequired,
@@ -44,39 +14,3 @@ export const keypadElementPropType = PropTypes.shape({
44
14
  setKeyHandler: PropTypes.func.isRequired,
45
15
  getDOMNode: PropTypes.func.isRequired,
46
16
  });
47
-
48
- export const bordersPropType = PropTypes.arrayOf(
49
- PropTypes.oneOf(Object.keys(BorderDirections)),
50
- );
51
-
52
- export const boundingBoxPropType = PropTypes.shape({
53
- height: PropTypes.number,
54
- width: PropTypes.number,
55
- top: PropTypes.number,
56
- right: PropTypes.number,
57
- bottom: PropTypes.number,
58
- left: PropTypes.number,
59
- });
60
-
61
- export const echoPropType = PropTypes.shape({
62
- animationId: PropTypes.string.isRequired,
63
- animationType: PropTypes.oneOf(Object.keys(EchoAnimationTypes)).isRequired,
64
- borders: bordersPropType,
65
- id: keyIdPropType.isRequired,
66
- initialBounds: boundingBoxPropType.isRequired,
67
- });
68
-
69
- export const cursorContextPropType = PropTypes.oneOf(
70
- Object.keys(CursorContexts),
71
- );
72
-
73
- export const popoverPropType = PropTypes.shape({
74
- parentId: keyIdPropType.isRequired,
75
- bounds: boundingBoxPropType.isRequired,
76
- childKeyIds: PropTypes.arrayOf(keyIdPropType).isRequired,
77
- });
78
-
79
- export const childrenPropType = PropTypes.oneOfType([
80
- PropTypes.arrayOf(PropTypes.node),
81
- PropTypes.node,
82
- ]);
@@ -14,17 +14,17 @@ import {createStore} from "../store/index";
14
14
 
15
15
  import KeypadContainer from "./keypad-container";
16
16
 
17
- import type {CSSProperties} from "aphrodite";
17
+ import type {Cursor, KeypadConfiguration, KeyHandler} from "../types";
18
+ import type {StyleType} from "@khanacademy/wonder-blocks-core";
18
19
 
19
20
  type Props = {
20
21
  onElementMounted?: (arg1: any) => void;
21
- onDismiss?: () => unknown;
22
- style?: CSSProperties;
22
+ onDismiss?: () => void;
23
+ style?: StyleType;
23
24
  };
24
25
 
25
26
  class ProvidedKeypad extends React.Component<Props> {
26
- // @ts-expect-error [FEI-5003] - TS2564 - Property 'mounted' has no initializer and is not definitely assigned in the constructor.
27
- mounted: boolean;
27
+ mounted?: boolean;
28
28
  store: any;
29
29
 
30
30
  UNSAFE_componentWillMount() {
@@ -47,8 +47,10 @@ class ProvidedKeypad extends React.Component<Props> {
47
47
  this.store.dispatch(dismissKeypad());
48
48
  };
49
49
 
50
- // @ts-expect-error [FEI-5003] - TS2322 - Type '(configuration: any, cb: any) => void' is not assignable to type '() => void'.
51
- configure: () => void = (configuration, cb) => {
50
+ configure: (configuration: KeypadConfiguration, cb: () => void) => void = (
51
+ configuration,
52
+ cb,
53
+ ) => {
52
54
  this.store.dispatch(configureKeypad(configuration));
53
55
 
54
56
  // HACK(charlie): In Perseus, triggering a focus causes the keypad to
@@ -61,12 +63,11 @@ class ProvidedKeypad extends React.Component<Props> {
61
63
  setTimeout(() => cb && cb());
62
64
  };
63
65
 
64
- // @ts-expect-error [FEI-5003] - TS2322 - Type '(cursor: any) => void' is not assignable to type '() => void'.
65
- setCursor: () => void = (cursor) => {
66
+ setCursor: (cursor: Cursor) => void = (cursor) => {
66
67
  this.store.dispatch(setCursor(cursor));
67
68
  };
68
69
 
69
- setKeyHandler: (keyHandler: any) => void = (keyHandler) => {
70
+ setKeyHandler: (keyHandler: KeyHandler) => void = (keyHandler) => {
70
71
  this.store.dispatch(setKeyHandler(keyHandler));
71
72
  };
72
73
 
@@ -75,7 +76,7 @@ class ProvidedKeypad extends React.Component<Props> {
75
76
  };
76
77
 
77
78
  render(): React.ReactNode {
78
- const {onElementMounted, ...rest} = this.props;
79
+ const {onElementMounted, onDismiss, style} = this.props;
79
80
 
80
81
  return (
81
82
  <Provider store={this.store}>
@@ -95,7 +96,8 @@ class ProvidedKeypad extends React.Component<Props> {
95
96
  onElementMounted &&
96
97
  onElementMounted(elementWithDispatchMethods);
97
98
  }}
98
- {...rest}
99
+ onDismiss={onDismiss}
100
+ style={style}
99
101
  />
100
102
  </Provider>
101
103
  );
@@ -2,17 +2,16 @@
2
2
  * A component that renders a single SVG icon.
3
3
  */
4
4
 
5
- import PropTypes from "prop-types";
6
5
  import * as React from "react";
7
6
 
8
7
  import * as Iconography from "./iconography/index";
9
8
 
10
- class SvgIcon extends React.Component {
11
- static propTypes = {
12
- color: PropTypes.string.isRequired,
13
- name: PropTypes.string.isRequired,
14
- };
9
+ type Props = {
10
+ color: string;
11
+ name: string;
12
+ };
15
13
 
14
+ class SvgIcon extends React.Component<Props> {
16
15
  render() {
17
16
  const {color, name} = this.props;
18
17
 
@@ -2,10 +2,12 @@ import * as React from "react";
2
2
 
3
3
  import type {TabbarItemType} from "./types";
4
4
 
5
- const IconAsset: React.FC<{
5
+ type Props = {
6
6
  tintColor: string;
7
7
  type: TabbarItemType;
8
- }> = function ({tintColor, type}): React.ReactElement {
8
+ };
9
+
10
+ const IconAsset = function ({tintColor, type}: Props): React.ReactElement {
9
11
  if (type === "Geometry") {
10
12
  return (
11
13
  <svg
@@ -76,9 +76,7 @@ type Props = {
76
76
  itemType: TabbarItemType;
77
77
  };
78
78
 
79
- type State = Record<any, any>;
80
-
81
- class TabbarItem extends React.Component<Props, State> {
79
+ class TabbarItem extends React.Component<Props> {
82
80
  render(): React.ReactNode {
83
81
  const {onClick, itemType, itemState} = this.props;
84
82
  return (
@@ -5,6 +5,8 @@ import * as React from "react";
5
5
  import {TabbarItemForTesting as TabbarItem} from "./item";
6
6
  import Tabbar from "./tabbar";
7
7
 
8
+ import type {TabbarItemType} from "./types";
9
+
8
10
  export default {title: "Tab Bar", decorators: [withKnobs]};
9
11
 
10
12
  export const InactiveBarItem = () => (
@@ -49,12 +51,19 @@ export const DisabledBarItem = () => (
49
51
  "Numbers",
50
52
  )}
51
53
  itemState="disabled"
54
+ onClick={action("onClick")}
52
55
  />
53
56
  );
54
57
 
55
58
  export const FullTabbar = () => (
56
59
  <Tabbar
57
- items={array("items", ["Numbers", "Geometry", "Operators"])}
60
+ items={
61
+ array("items", [
62
+ "Numbers",
63
+ "Geometry",
64
+ "Operators",
65
+ ]) as ReadonlyArray<TabbarItemType>
66
+ }
58
67
  onSelect={action("selected-item")}
59
68
  />
60
69
  );
@@ -23,12 +23,12 @@ type TabbarState = {
23
23
  selectedItem: number;
24
24
  };
25
25
 
26
- type TabbarProps = {
27
- items: Array<TabbarItemType>;
26
+ type Props = {
27
+ items: ReadonlyArray<TabbarItemType>;
28
28
  onSelect: (item: TabbarItemType) => void;
29
29
  };
30
30
 
31
- class Tabbar extends React.Component<TabbarProps, TabbarState> {
31
+ class Tabbar extends React.Component<Props, TabbarState> {
32
32
  state: TabbarState = {
33
33
  selectedItem: 0,
34
34
  };
@@ -3,7 +3,6 @@
3
3
  */
4
4
 
5
5
  import {StyleSheet} from "aphrodite";
6
- import PropTypes from "prop-types";
7
6
  import * as React from "react";
8
7
 
9
8
  import {View, Text} from "../fake-react-native-web/index";
@@ -11,14 +10,16 @@ import {View, Text} from "../fake-react-native-web/index";
11
10
  import {iconSizeHeightPx, iconSizeWidthPx} from "./common-style";
12
11
  import Styles from "./styles";
13
12
 
13
+ import type {StyleType} from "@khanacademy/wonder-blocks-core";
14
+
14
15
  const {row, centered} = Styles;
15
16
 
16
- class TextIcon extends React.Component {
17
- static propTypes = {
18
- character: PropTypes.string.isRequired,
19
- style: PropTypes.any,
20
- };
17
+ type Props = {
18
+ character: string;
19
+ style?: StyleType;
20
+ };
21
21
 
22
+ class TextIcon extends React.Component<Props> {
22
23
  render() {
23
24
  const {character, style} = this.props;
24
25
 
@@ -5,31 +5,34 @@
5
5
  */
6
6
 
7
7
  import {StyleSheet} from "aphrodite";
8
- import PropTypes from "prop-types";
9
8
  import * as React from "react";
10
9
  import ReactDOM from "react-dom";
11
10
  import {connect} from "react-redux";
12
11
 
13
- import {KeyTypes} from "../consts";
12
+ import {KeyType, KeyTypes} from "../consts";
14
13
  import KeyConfigs from "../data/key-configs";
15
14
 
16
15
  import GestureManager from "./gesture-manager";
17
16
  import KeypadButton from "./keypad-button";
18
- import {bordersPropType, keyIdPropType} from "./prop-types";
19
-
20
- class TouchableKeypadButton extends React.Component {
21
- static propTypes = {
22
- borders: bordersPropType,
23
- childKeyIds: PropTypes.arrayOf(keyIdPropType),
24
- disabled: PropTypes.bool,
25
- focused: PropTypes.bool,
26
- gestureManager: PropTypes.instanceOf(GestureManager),
27
- id: keyIdPropType.isRequired,
28
- popoverEnabled: PropTypes.bool,
29
- style: PropTypes.any,
30
- type: PropTypes.oneOf(Object.keys(KeyTypes)).isRequired,
31
- };
32
17
 
18
+ import type {Key} from "../data/keys";
19
+ import type {Border, Icon} from "../types";
20
+ import type {StyleType} from "@khanacademy/wonder-blocks-core";
21
+
22
+ type Props = {
23
+ borders: Border;
24
+ childKeyIds: ReadonlyArray<Key>;
25
+ disabled: boolean;
26
+ focused: boolean;
27
+ gestureManager: GestureManager;
28
+ id: Key;
29
+ popoverEnabled: boolean;
30
+ style: StyleType;
31
+ type: KeyType;
32
+ icon: Icon;
33
+ };
34
+
35
+ class TouchableKeypadButton extends React.Component<Props> {
33
36
  shouldComponentUpdate(newProps) {
34
37
  // We take advantage of a few different properties of our key
35
38
  // configuration system. Namely, we know that the other props flow
@@ -3,7 +3,6 @@
3
3
  */
4
4
 
5
5
  import {StyleSheet} from "aphrodite";
6
- import PropTypes from "prop-types";
7
6
  import * as React from "react";
8
7
  import {connect} from "react-redux";
9
8
 
@@ -19,16 +18,21 @@ import Keypad from "./keypad";
19
18
  import Styles from "./styles";
20
19
  import Tabbar from "./tabbar/tabbar";
21
20
 
21
+ import type {State} from "../store/types";
22
+
22
23
  const {column, row, fullWidth} = Styles;
23
24
 
24
- class TwoPageKeypad extends React.Component {
25
- static propTypes = {
26
- currentPage: PropTypes.oneOf([0, 1]).isRequired,
27
- leftPage: PropTypes.node.isRequired,
28
- paginationEnabled: PropTypes.bool.isRequired,
29
- rightPage: PropTypes.node.isRequired,
30
- };
25
+ interface ReduxProps {
26
+ paginationEnabled: boolean;
27
+ }
28
+
29
+ interface Props extends ReduxProps {
30
+ currentPage: number;
31
+ leftPage: React.ReactNode;
32
+ rightPage: React.ReactNode;
33
+ }
31
34
 
35
+ class TwoPageKeypad extends React.Component<Props> {
32
36
  state = {
33
37
  selectedPage: "Numbers",
34
38
  };
@@ -88,7 +92,7 @@ const styles = StyleSheet.create({
88
92
  },
89
93
  });
90
94
 
91
- const mapStateToProps = (state) => {
95
+ const mapStateToProps = (state: State): ReduxProps => {
92
96
  return {
93
97
  paginationEnabled: state.layout.paginationEnabled,
94
98
  };
@@ -7,8 +7,18 @@
7
7
 
8
8
  import now from "performance-now";
9
9
 
10
+ type Event = {
11
+ x: number;
12
+ t: number;
13
+ };
14
+
10
15
  class VelocityTracker {
11
- constructor(options) {
16
+ options: {
17
+ velocityTimeout: number;
18
+ };
19
+ _events: Array<Event>;
20
+
21
+ constructor(options?) {
12
22
  this.options = {
13
23
  velocityTimeout: 100,
14
24
  ...options,
@@ -24,7 +34,7 @@ class VelocityTracker {
24
34
  *
25
35
  * @param {number} x - the cumulative displacement of the event
26
36
  */
27
- push(x) {
37
+ push(x: number) {
28
38
  this._events.push({
29
39
  x,
30
40
  t: now(),
@@ -42,7 +52,7 @@ class VelocityTracker {
42
52
  *
43
53
  * @returns {number} the velocity associated with the tracker
44
54
  */
45
- getVelocity() {
55
+ getVelocity(): number {
46
56
  const events = this._getEvents();
47
57
 
48
58
  if (events.length < 2) {
@@ -63,7 +73,7 @@ class VelocityTracker {
63
73
  * that occurred in the past `velocityTimeout`
64
74
  * milliseconds
65
75
  */
66
- _getEvents() {
76
+ _getEvents(): ReadonlyArray<Event> {
67
77
  const threshold = now() - this.options.velocityTimeout;
68
78
  const recentEvents = this._events.filter((event) => {
69
79
  return event.t > threshold;
@@ -1,6 +1,7 @@
1
1
  import {StyleSheet, css} from "aphrodite";
2
2
  import * as React from "react";
3
3
 
4
+ import type {StyleType} from "@khanacademy/wonder-blocks-core";
4
5
  import type {CSSProperties} from "aphrodite";
5
6
 
6
7
  type Props = {
@@ -11,7 +12,7 @@ type Props = {
11
12
  // a StyleSheet.
12
13
  dynamicStyle?: CSSProperties;
13
14
  numberOfLines?: number;
14
- style?: CSSProperties;
15
+ style?: StyleType;
15
16
  };
16
17
 
17
18
  class Text extends React.Component<Props> {
@@ -1,11 +1,12 @@
1
1
  import {StyleSheet, css} from "aphrodite";
2
2
  import * as React from "react";
3
3
 
4
+ import type {StyleType} from "@khanacademy/wonder-blocks-core";
4
5
  import type {CSSProperties} from "aphrodite";
5
6
 
6
7
  type Props = {
7
8
  ariaLabel?: string;
8
- children: React.ReactNode;
9
+ children?: React.ReactNode;
9
10
  // The `dynamicStyle` prop is provided for animating dynamic
10
11
  // properties, as creating Aphrodite StyleSheets in animation loops is
11
12
  // expensive. `dynamicStyle` should be a raw style object, rather than
@@ -24,7 +25,7 @@ type Props = {
24
25
  onTouchMove?: (arg1: React.TouchEvent<HTMLDivElement>) => void;
25
26
  onTouchStart?: (arg1: React.TouchEvent<HTMLDivElement>) => void;
26
27
  role?: string;
27
- style?: CSSProperties;
28
+ style?: StyleType;
28
29
  };
29
30
 
30
31
  class View extends React.Component<Props> {
package/src/index.ts CHANGED
@@ -5,10 +5,7 @@
5
5
  import "../less/main.less";
6
6
 
7
7
  export {default as KeypadInput} from "./components/input/math-input";
8
- export {
9
- keypadConfigurationPropType,
10
- keypadElementPropType,
11
- } from "./components/prop-types";
8
+ export {keypadElementPropType} from "./components/prop-types";
12
9
  export {default as Keypad} from "./components/provided-keypad";
13
10
  export {KeypadTypes} from "./consts";
14
11
  export {default as KeyConfigs} from "./data/key-configs";