@khanacademy/math-input 8.1.3 → 9.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.
- package/CHANGELOG.md +14 -1
- package/dist/components/input/cursor-contexts.d.ts +9 -9
- package/dist/components/input/math-wrapper.d.ts +4 -4
- package/dist/components/input/mathquill-helpers.d.ts +1 -1
- package/dist/components/input/mathquill-instance.d.ts +1 -1
- package/dist/components/input/mathquill-types.d.ts +1 -1
- package/dist/components/key-handlers/handle-arrow.d.ts +2 -2
- package/dist/components/key-handlers/handle-backspace.d.ts +1 -1
- package/dist/components/key-handlers/handle-exponent.d.ts +2 -2
- package/dist/components/key-handlers/handle-jump-out.d.ts +2 -2
- package/dist/components/key-handlers/key-translator.d.ts +2 -2
- package/dist/components/keypad/button-assets.d.ts +1 -1
- package/dist/components/keypad/keypad-button.d.ts +1 -1
- package/dist/components/keypad/keypad-pages/extras-page.d.ts +2 -2
- package/dist/components/keypad/keypad-pages/fractions-page.d.ts +9 -0
- package/dist/components/keypad/keypad-pages/geometry-page.d.ts +1 -1
- package/dist/components/keypad/keypad-pages/numbers-page.d.ts +1 -1
- package/dist/components/keypad/keypad-pages/operators-page.d.ts +1 -1
- package/dist/components/keypad/keypad.d.ts +4 -3
- package/dist/components/keypad/mobile-keypad.d.ts +1 -1
- package/dist/components/keypad/shared-keys.d.ts +3 -3
- package/dist/components/keypad/utils.d.ts +2 -0
- package/dist/components/keypad-legacy/compute-layout-parameters.d.ts +1 -1
- package/dist/components/keypad-legacy/empty-keypad-button.d.ts +1 -1
- package/dist/components/keypad-legacy/gesture-manager.d.ts +3 -3
- package/dist/components/keypad-legacy/gesture-state-machine.d.ts +1 -1
- package/dist/components/keypad-legacy/keypad-button.d.ts +2 -1
- package/dist/components/keypad-legacy/multi-symbol-grid.d.ts +1 -1
- package/dist/components/keypad-legacy/multi-symbol-popover.d.ts +1 -1
- package/dist/components/keypad-legacy/node-manager.d.ts +1 -1
- package/dist/components/keypad-legacy/store/actions.d.ts +1 -1
- package/dist/components/keypad-legacy/store/types.d.ts +3 -3
- package/dist/components/keypad-legacy/touchable-keypad-button.d.ts +3 -3
- package/dist/components/keypad-switch.d.ts +1 -1
- package/dist/components/tabbar/tabbar.d.ts +2 -2
- package/dist/components/tabbar/types.d.ts +1 -1
- package/dist/data/key-configs.d.ts +2 -2
- package/dist/es/index.js +847 -240
- package/dist/es/index.js.map +1 -1
- package/dist/index.js +847 -240
- package/dist/index.js.map +1 -1
- package/dist/types.d.ts +6 -5
- package/package.json +6 -6
- package/src/components/input/cursor-contexts.ts +9 -9
- package/src/components/input/math-input.tsx +12 -12
- package/src/components/input/math-wrapper.ts +7 -3
- package/src/components/input/mathquill-helpers.ts +3 -5
- package/src/components/input/mathquill-instance.ts +1 -1
- package/src/components/input/mathquill-types.ts +1 -1
- package/src/components/key-handlers/handle-arrow.ts +4 -3
- package/src/components/key-handlers/handle-backspace.ts +3 -2
- package/src/components/key-handlers/handle-exponent.ts +4 -5
- package/src/components/key-handlers/handle-jump-out.ts +4 -5
- package/src/components/key-handlers/key-translator.ts +6 -5
- package/src/components/keypad/__tests__/keypad-button.test.tsx +44 -3
- package/src/components/keypad/__tests__/keypad-v2-mathquill.test.tsx +4 -3
- package/src/components/keypad/__tests__/keypad-v2.cypress.ts +2 -32
- package/src/components/keypad/__tests__/keypad.test.tsx +46 -0
- package/src/components/keypad/__tests__/test-data-tabs.ts +21 -0
- package/src/components/keypad/button-assets.tsx +761 -60
- package/src/components/keypad/keypad-button.stories.tsx +4 -2
- package/src/components/keypad/keypad-button.tsx +2 -3
- package/src/components/keypad/keypad-mathquill.stories.tsx +3 -2
- package/src/components/keypad/keypad-pages/extras-page.tsx +3 -2
- package/src/components/keypad/keypad-pages/fractions-page.tsx +125 -0
- package/src/components/keypad/keypad-pages/geometry-page.tsx +2 -1
- package/src/components/keypad/keypad-pages/numbers-page.tsx +2 -1
- package/src/components/keypad/keypad-pages/operators-page.tsx +2 -1
- package/src/components/keypad/keypad.stories.tsx +17 -2
- package/src/components/keypad/keypad.tsx +56 -22
- package/src/components/keypad/mobile-keypad.tsx +2 -1
- package/src/components/keypad/shared-keys.tsx +5 -28
- package/src/components/keypad/utils.ts +30 -0
- package/src/components/keypad-context.ts +1 -1
- package/src/components/keypad-legacy/compute-layout-parameters.ts +1 -1
- package/src/components/keypad-legacy/echo-manager.tsx +1 -1
- package/src/components/keypad-legacy/empty-keypad-button.tsx +1 -1
- package/src/components/keypad-legacy/gesture-manager.ts +4 -4
- package/src/components/keypad-legacy/gesture-state-machine.ts +1 -1
- package/src/components/keypad-legacy/keypad-button.tsx +2 -1
- package/src/components/keypad-legacy/many-keypad-button.tsx +2 -1
- package/src/components/keypad-legacy/multi-symbol-grid.tsx +2 -1
- package/src/components/keypad-legacy/multi-symbol-popover.tsx +2 -1
- package/src/components/keypad-legacy/node-manager.ts +1 -1
- package/src/components/keypad-legacy/store/actions.ts +1 -2
- package/src/components/keypad-legacy/store/index.ts +1 -1
- package/src/components/keypad-legacy/store/types.ts +3 -4
- package/src/components/keypad-legacy/touchable-keypad-button.tsx +3 -3
- package/src/components/keypad-legacy/two-page-keypad.tsx +1 -1
- package/src/components/keypad-switch.tsx +2 -1
- package/src/components/tabbar/tabbar.tsx +4 -2
- package/src/components/tabbar/types.ts +1 -0
- package/src/data/key-configs.ts +4 -3
- package/src/full-math-input.stories.tsx +35 -3
- package/src/types.ts +6 -6
- package/tsconfig-build.tsbuildinfo +1 -1
- package/dist/components/common-style.js.flow +0 -27
- package/dist/components/input/cursor-contexts.js.flow +0 -26
- package/dist/components/input/cursor-handle.js.flow +0 -28
- package/dist/components/input/drag-listener.js.flow +0 -19
- package/dist/components/input/math-input.js.flow +0 -153
- package/dist/components/input/math-wrapper.js.flow +0 -54
- package/dist/components/input/mathquill-helpers.js.flow +0 -56
- package/dist/components/input/mathquill-instance.js.flow +0 -24
- package/dist/components/input/mathquill-types.js.flow +0 -365
- package/dist/components/input/scroll-into-view.js.flow +0 -20
- package/dist/components/key-handlers/handle-arrow.js.flow +0 -12
- package/dist/components/key-handlers/handle-backspace.js.flow +0 -14
- package/dist/components/key-handlers/handle-exponent.js.flow +0 -12
- package/dist/components/key-handlers/handle-jump-out.js.flow +0 -14
- package/dist/components/key-handlers/key-translator.js.flow +0 -10
- package/dist/components/keypad/button-assets.js.flow +0 -12
- package/dist/components/keypad/index.js.flow +0 -8
- package/dist/components/keypad/keypad-button.js.flow +0 -18
- package/dist/components/keypad/keypad-pages/extras-page.js.flow +0 -13
- package/dist/components/keypad/keypad-pages/geometry-page.js.flow +0 -11
- package/dist/components/keypad/keypad-pages/numbers-page.js.flow +0 -11
- package/dist/components/keypad/keypad-pages/operators-page.js.flow +0 -15
- package/dist/components/keypad/keypad.js.flow +0 -37
- package/dist/components/keypad/mobile-keypad.js.flow +0 -57
- package/dist/components/keypad/shared-keys.js.flow +0 -20
- package/dist/components/keypad-context.js.flow +0 -18
- package/dist/components/keypad-legacy/compute-layout-parameters.js.flow +0 -21
- package/dist/components/keypad-legacy/corner-decal.js.flow +0 -15
- package/dist/components/keypad-legacy/echo-manager.js.flow +0 -20
- package/dist/components/keypad-legacy/empty-keypad-button.js.flow +0 -23
- package/dist/components/keypad-legacy/expression-keypad.js.flow +0 -34
- package/dist/components/keypad-legacy/fraction-keypad.js.flow +0 -33
- package/dist/components/keypad-legacy/gesture-manager.js.flow +0 -97
- package/dist/components/keypad-legacy/gesture-state-machine.js.flow +0 -118
- package/dist/components/keypad-legacy/icon.js.flow +0 -18
- package/dist/components/keypad-legacy/index.js.flow +0 -7
- package/dist/components/keypad-legacy/keypad-button.js.flow +0 -80
- package/dist/components/keypad-legacy/keypad-container.js.flow +0 -63
- package/dist/components/keypad-legacy/keypad.js.flow +0 -40
- package/dist/components/keypad-legacy/many-keypad-button.js.flow +0 -17
- package/dist/components/keypad-legacy/math-icon.js.flow +0 -19
- package/dist/components/keypad-legacy/multi-symbol-grid.js.flow +0 -16
- package/dist/components/keypad-legacy/multi-symbol-popover.js.flow +0 -15
- package/dist/components/keypad-legacy/navigation-pad.js.flow +0 -16
- package/dist/components/keypad-legacy/node-manager.js.flow +0 -60
- package/dist/components/keypad-legacy/popover-manager.js.flow +0 -15
- package/dist/components/keypad-legacy/popover-state-machine.js.flow +0 -77
- package/dist/components/keypad-legacy/provided-keypad.js.flow +0 -38
- package/dist/components/keypad-legacy/store/actions.js.flow +0 -90
- package/dist/components/keypad-legacy/store/echo-reducer.js.flow +0 -10
- package/dist/components/keypad-legacy/store/index.js.flow +0 -22
- package/dist/components/keypad-legacy/store/input-reducer.js.flow +0 -13
- package/dist/components/keypad-legacy/store/keypad-reducer.js.flow +0 -13
- package/dist/components/keypad-legacy/store/layout-reducer.js.flow +0 -13
- package/dist/components/keypad-legacy/store/shared.js.flow +0 -14
- package/dist/components/keypad-legacy/store/types.js.flow +0 -53
- package/dist/components/keypad-legacy/styles.js.flow +0 -11
- package/dist/components/keypad-legacy/svg-icon.js.flow +0 -15
- package/dist/components/keypad-legacy/text-icon.js.flow +0 -16
- package/dist/components/keypad-legacy/touchable-keypad-button.js.flow +0 -59
- package/dist/components/keypad-legacy/two-page-keypad.js.flow +0 -31
- package/dist/components/keypad-legacy/z-indexes.js.flow +0 -13
- package/dist/components/keypad-switch.js.flow +0 -15
- package/dist/components/prop-types.js.flow +0 -17
- package/dist/components/tabbar/icons.js.flow +0 -14
- package/dist/components/tabbar/index.js.flow +0 -8
- package/dist/components/tabbar/item.js.flow +0 -19
- package/dist/components/tabbar/tabbar.js.flow +0 -18
- package/dist/components/tabbar/types.js.flow +0 -12
- package/dist/data/key-configs.js.flow +0 -10
- package/dist/data/keys.js.flow +0 -122
- package/dist/enums.js.flow +0 -54
- package/dist/fake-react-native-web/index.js.flow +0 -8
- package/dist/fake-react-native-web/text.js.flow +0 -19
- package/dist/fake-react-native-web/view.js.flow +0 -29
- package/dist/index.js.flow +0 -25
- package/dist/types.js.flow +0 -91
- package/dist/utils.js.flow +0 -7
package/dist/types.d.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
3
|
-
import
|
|
4
|
-
import
|
|
1
|
+
import type { CursorContext } from "./components/input/cursor-contexts";
|
|
2
|
+
import type Key from "./data/keys";
|
|
3
|
+
import type { BorderDirection, EchoAnimationType, IconType, KeyType, KeypadType } from "./enums";
|
|
4
|
+
import type * as React from "react";
|
|
5
|
+
import type ReactDOM from "react-dom";
|
|
5
6
|
export type Border = Partial<ReadonlyArray<BorderDirection>>;
|
|
6
7
|
export interface Bound {
|
|
7
8
|
top: number;
|
|
@@ -62,7 +63,7 @@ export type ActiveNodesObj = {
|
|
|
62
63
|
export type LayoutProps = {
|
|
63
64
|
initialBounds: Bound;
|
|
64
65
|
};
|
|
65
|
-
export type ClickKeyCallback = (key: Key) => void;
|
|
66
|
+
export type ClickKeyCallback = (key: Key, event?: React.SyntheticEvent) => void;
|
|
66
67
|
export interface KeypadAPI {
|
|
67
68
|
activate: () => void;
|
|
68
69
|
dismiss: () => void;
|
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"description": "Khan Academy's new expression editor for the mobile web.",
|
|
4
4
|
"author": "Khan Academy",
|
|
5
5
|
"license": "MIT",
|
|
6
|
-
"version": "
|
|
6
|
+
"version": "9.0.0",
|
|
7
7
|
"publishConfig": {
|
|
8
8
|
"access": "public"
|
|
9
9
|
},
|
|
@@ -24,16 +24,16 @@
|
|
|
24
24
|
"performance-now": "^0.2.0"
|
|
25
25
|
},
|
|
26
26
|
"devDependencies": {
|
|
27
|
-
"@khanacademy/wonder-blocks-clickable": "^
|
|
27
|
+
"@khanacademy/wonder-blocks-clickable": "^4.0.0",
|
|
28
28
|
"@khanacademy/wonder-blocks-color": "^2.0.1",
|
|
29
|
-
"@khanacademy/wonder-blocks-core": "^
|
|
29
|
+
"@khanacademy/wonder-blocks-core": "^6.0.0",
|
|
30
30
|
"@khanacademy/wonder-blocks-i18n": "^2.0.2",
|
|
31
31
|
"@khanacademy/wonder-blocks-popover": "^2.0.11",
|
|
32
32
|
"@khanacademy/wonder-stuff-core": "^1.2.2",
|
|
33
33
|
"aphrodite": "^1.1.0",
|
|
34
34
|
"jquery": "^2.1.1",
|
|
35
35
|
"katex": "^0.11.1",
|
|
36
|
-
"perseus-build-settings": "^0.
|
|
36
|
+
"perseus-build-settings": "^0.2.0",
|
|
37
37
|
"prop-types": "15.6.1",
|
|
38
38
|
"react": "^16.8.0",
|
|
39
39
|
"react-dom": "^16.8.0",
|
|
@@ -44,9 +44,9 @@
|
|
|
44
44
|
"redux": "^4.0.0"
|
|
45
45
|
},
|
|
46
46
|
"peerDependencies": {
|
|
47
|
-
"@khanacademy/wonder-blocks-clickable": "^
|
|
47
|
+
"@khanacademy/wonder-blocks-clickable": "^4.0.0",
|
|
48
48
|
"@khanacademy/wonder-blocks-color": "^2.0.1",
|
|
49
|
-
"@khanacademy/wonder-blocks-core": "^
|
|
49
|
+
"@khanacademy/wonder-blocks-core": "^6.0.0",
|
|
50
50
|
"@khanacademy/wonder-blocks-i18n": "^2.0.2",
|
|
51
51
|
"@khanacademy/wonder-stuff-core": "^1.2.2",
|
|
52
52
|
"aphrodite": "^1.1.0",
|
|
@@ -10,28 +10,28 @@
|
|
|
10
10
|
* the radical.
|
|
11
11
|
*/
|
|
12
12
|
|
|
13
|
-
export
|
|
13
|
+
export enum CursorContext {
|
|
14
14
|
// The cursor is not in any of the other viable contexts.
|
|
15
|
-
NONE
|
|
15
|
+
NONE = "NONE",
|
|
16
16
|
|
|
17
17
|
// The cursor is within a set of parentheses.
|
|
18
|
-
IN_PARENS
|
|
18
|
+
IN_PARENS = "IN_PARENS",
|
|
19
19
|
|
|
20
20
|
// The cursor is within a superscript (e.g., an exponent).
|
|
21
|
-
IN_SUPER_SCRIPT
|
|
21
|
+
IN_SUPER_SCRIPT = "IN_SUPER_SCRIPT",
|
|
22
22
|
|
|
23
23
|
// The cursor is within a subscript (e.g., the base of a custom logarithm).
|
|
24
|
-
IN_SUB_SCRIPT
|
|
24
|
+
IN_SUB_SCRIPT = "IN_SUB_SCRIPT",
|
|
25
25
|
|
|
26
26
|
// The cursor is in the numerator of a fraction.
|
|
27
|
-
IN_NUMERATOR
|
|
27
|
+
IN_NUMERATOR = "IN_NUMERATOR",
|
|
28
28
|
|
|
29
29
|
// The cursor is in the denominator of a fraction.
|
|
30
|
-
IN_DENOMINATOR
|
|
30
|
+
IN_DENOMINATOR = "IN_DENOMINATOR",
|
|
31
31
|
|
|
32
32
|
// The cursor is sitting before a fraction; that is, the cursor is within
|
|
33
33
|
// what looks to be a mixed number preceding a fraction. This will only be
|
|
34
34
|
// the case when the only math between the cursor and the fraction to its
|
|
35
35
|
// write is non-leaf math (numbers and variables).
|
|
36
|
-
BEFORE_FRACTION
|
|
37
|
-
}
|
|
36
|
+
BEFORE_FRACTION = "BEFORE_FRACTION",
|
|
37
|
+
}
|
|
@@ -54,18 +54,18 @@ class MathInput extends React.Component<Props, State> {
|
|
|
54
54
|
didTouchOutside: boolean | null | undefined;
|
|
55
55
|
didScroll: boolean | null | undefined;
|
|
56
56
|
mathField: any;
|
|
57
|
-
// @ts-expect-error
|
|
57
|
+
// @ts-expect-error - TS2564 - Property 'recordTouchStartOutside' has no initializer and is not definitely assigned in the constructor.
|
|
58
58
|
recordTouchStartOutside: (arg1: any) => void;
|
|
59
|
-
// @ts-expect-error
|
|
59
|
+
// @ts-expect-error - TS2564 - Property 'blurOnTouchEndOutside' has no initializer and is not definitely assigned in the constructor.
|
|
60
60
|
blurOnTouchEndOutside: (arg1: any) => void;
|
|
61
61
|
dragListener: any;
|
|
62
62
|
inputRef: HTMLDivElement | null | undefined;
|
|
63
63
|
_isMounted: boolean | null | undefined;
|
|
64
64
|
_mathContainer: any;
|
|
65
|
-
// @ts-expect-error
|
|
65
|
+
// @ts-expect-error - TS2564 - Property '_container' has no initializer and is not definitely assigned in the constructor.
|
|
66
66
|
_container: HTMLDivElement;
|
|
67
67
|
_root: any;
|
|
68
|
-
// @ts-expect-error
|
|
68
|
+
// @ts-expect-error - TS2564 - Property '_containerBounds' has no initializer and is not definitely assigned in the constructor.
|
|
69
69
|
_containerBounds: ClientRect;
|
|
70
70
|
_keypadBounds: ClientRect | null | undefined;
|
|
71
71
|
|
|
@@ -235,11 +235,11 @@ class MathInput extends React.Component<Props, State> {
|
|
|
235
235
|
window.removeEventListener("touchstart", this.recordTouchStartOutside);
|
|
236
236
|
window.removeEventListener("touchend", this.blurOnTouchEndOutside);
|
|
237
237
|
window.removeEventListener("touchcancel", this.blurOnTouchEndOutside);
|
|
238
|
-
// @ts-expect-error
|
|
238
|
+
// @ts-expect-error - TS2769 - No overload matches this call.
|
|
239
239
|
window.removeEventListener("resize", this._clearKeypadBoundsCache());
|
|
240
240
|
window.removeEventListener(
|
|
241
241
|
"orientationchange",
|
|
242
|
-
// @ts-expect-error
|
|
242
|
+
// @ts-expect-error - TS2769 - No overload matches this call.
|
|
243
243
|
this._clearKeypadBoundsCache(),
|
|
244
244
|
);
|
|
245
245
|
}
|
|
@@ -430,7 +430,7 @@ class MathInput extends React.Component<Props, State> {
|
|
|
430
430
|
];
|
|
431
431
|
|
|
432
432
|
const elements = points
|
|
433
|
-
// @ts-expect-error
|
|
433
|
+
// @ts-expect-error - TS2556 - A spread argument must either have a tuple type or be passed to a rest parameter.
|
|
434
434
|
.map((point) => document.elementFromPoint(...point))
|
|
435
435
|
// We exclude the root container itself and any nodes marked
|
|
436
436
|
// as non-leaf which are fractions, parens, and roots. The
|
|
@@ -468,16 +468,16 @@ class MathInput extends React.Component<Props, State> {
|
|
|
468
468
|
const elementsById: Record<string, any> = {};
|
|
469
469
|
|
|
470
470
|
for (const element of elements) {
|
|
471
|
-
// @ts-expect-error
|
|
471
|
+
// @ts-expect-error - TS2531 - Object is possibly 'null'.
|
|
472
472
|
const id = element.getAttribute("mathquill-command-id");
|
|
473
473
|
if (id != null) {
|
|
474
|
-
// @ts-expect-error
|
|
474
|
+
// @ts-expect-error - TS2345 - Argument of type 'Element | null' is not assignable to parameter of type 'HTMLElement | null'.
|
|
475
475
|
leafElements.push(element);
|
|
476
476
|
|
|
477
477
|
counts[id] = (counts[id] || 0) + 1;
|
|
478
478
|
elementsById[id] = element;
|
|
479
479
|
} else {
|
|
480
|
-
// @ts-expect-error
|
|
480
|
+
// @ts-expect-error - TS2345 - Argument of type 'Element | null' is not assignable to parameter of type 'HTMLElement | null'.
|
|
481
481
|
nonLeafElements.push(element);
|
|
482
482
|
}
|
|
483
483
|
}
|
|
@@ -506,7 +506,7 @@ class MathInput extends React.Component<Props, State> {
|
|
|
506
506
|
// hit count in the situation should not have serious effects on
|
|
507
507
|
// the overall accuracy of the algorithm.
|
|
508
508
|
if (hitNode == null && nonLeafElements.length > 0) {
|
|
509
|
-
// @ts-expect-error
|
|
509
|
+
// @ts-expect-error - TS2322 - Type 'HTMLElement | null' is not assignable to type 'null'.
|
|
510
510
|
hitNode = nonLeafElements[0];
|
|
511
511
|
}
|
|
512
512
|
|
|
@@ -908,7 +908,7 @@ class MathInput extends React.Component<Props, State> {
|
|
|
908
908
|
overrides.css. */}
|
|
909
909
|
<div
|
|
910
910
|
className="keypad-input"
|
|
911
|
-
// @ts-expect-error
|
|
911
|
+
// @ts-expect-error - TS2322 - Type 'string' is not assignable to type 'number | undefined'.
|
|
912
912
|
tabIndex={"0"}
|
|
913
913
|
ref={(node) => {
|
|
914
914
|
this.inputRef = node;
|
|
@@ -16,8 +16,6 @@
|
|
|
16
16
|
|
|
17
17
|
import $ from "jquery";
|
|
18
18
|
|
|
19
|
-
import Key from "../../data/keys";
|
|
20
|
-
import {Cursor} from "../../types";
|
|
21
19
|
import handleBackspace from "../key-handlers/handle-backspace";
|
|
22
20
|
import keyTranslator from "../key-handlers/key-translator";
|
|
23
21
|
|
|
@@ -27,7 +25,13 @@ import {
|
|
|
27
25
|
maybeFindCommand,
|
|
28
26
|
} from "./mathquill-helpers";
|
|
29
27
|
import {createMathField, mathQuillInstance} from "./mathquill-instance";
|
|
30
|
-
|
|
28
|
+
|
|
29
|
+
import type Key from "../../data/keys";
|
|
30
|
+
import type {Cursor} from "../../types";
|
|
31
|
+
import type {
|
|
32
|
+
MathFieldInterface,
|
|
33
|
+
MathFieldUpdaterCallback,
|
|
34
|
+
} from "./mathquill-types";
|
|
31
35
|
|
|
32
36
|
const mobileKeyTranslator: Record<Key, MathFieldUpdaterCallback> = {
|
|
33
37
|
...keyTranslator,
|
|
@@ -1,10 +1,8 @@
|
|
|
1
1
|
import {CursorContext} from "./cursor-contexts";
|
|
2
2
|
import {mathQuillInstance} from "./mathquill-instance";
|
|
3
|
-
import {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
MathFieldInterface,
|
|
7
|
-
} from "./mathquill-types";
|
|
3
|
+
import {MathFieldActionType} from "./mathquill-types";
|
|
4
|
+
|
|
5
|
+
import type {MathFieldCursor, MathFieldInterface} from "./mathquill-types";
|
|
8
6
|
|
|
9
7
|
const Numerals = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9"];
|
|
10
8
|
const GreekLetters = ["\\theta", "\\pi"];
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import MathQuill from "mathquill";
|
|
2
2
|
|
|
3
|
-
import {MathQuillInterface, MathFieldConfig} from "./mathquill-types";
|
|
3
|
+
import type {MathQuillInterface, MathFieldConfig} from "./mathquill-types";
|
|
4
4
|
|
|
5
5
|
// We only need one MathQuill instance (referred to as MQ in the docs)
|
|
6
6
|
// and that contains some MQ constants and the MathField constructor
|
|
@@ -1,13 +1,14 @@
|
|
|
1
|
-
import Key from "../../data/keys";
|
|
2
1
|
import {
|
|
3
2
|
maybeFindCommand,
|
|
4
3
|
maybeFindCommandBeforeParens,
|
|
5
4
|
getCursor,
|
|
6
5
|
} from "../input/mathquill-helpers";
|
|
7
6
|
import {mathQuillInstance} from "../input/mathquill-instance";
|
|
8
|
-
import {
|
|
7
|
+
import {MathFieldActionType} from "../input/mathquill-types";
|
|
8
|
+
|
|
9
|
+
import type Key from "../../data/keys";
|
|
10
|
+
import type {
|
|
9
11
|
MathFieldInterface,
|
|
10
|
-
MathFieldActionType,
|
|
11
12
|
MathFieldCursor,
|
|
12
13
|
} from "../input/mathquill-types";
|
|
13
14
|
|
|
@@ -10,8 +10,9 @@ import {
|
|
|
10
10
|
maybeFindCommandBeforeParens,
|
|
11
11
|
} from "../input/mathquill-helpers";
|
|
12
12
|
import {mathQuillInstance} from "../input/mathquill-instance";
|
|
13
|
-
import {
|
|
14
|
-
|
|
13
|
+
import {MathFieldActionType} from "../input/mathquill-types";
|
|
14
|
+
|
|
15
|
+
import type {
|
|
15
16
|
MathFieldInterface,
|
|
16
17
|
MathFieldCursor,
|
|
17
18
|
} from "../input/mathquill-types";
|
|
@@ -1,10 +1,9 @@
|
|
|
1
|
-
import Key from "../../data/keys";
|
|
2
1
|
import {getCursor} from "../input/mathquill-helpers";
|
|
3
2
|
import {mathQuillInstance} from "../input/mathquill-instance";
|
|
4
|
-
import {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
} from "../input/mathquill-types";
|
|
3
|
+
import {MathFieldActionType} from "../input/mathquill-types";
|
|
4
|
+
|
|
5
|
+
import type Key from "../../data/keys";
|
|
6
|
+
import type {MathFieldInterface} from "../input/mathquill-types";
|
|
8
7
|
|
|
9
8
|
const ArithmeticOperators = ["+", "-", "\\cdot", "\\times", "\\div"];
|
|
10
9
|
const EqualityOperators = ["=", "\\neq", "<", "\\leq", ">", "\\geq"];
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import Key from "../../data/keys";
|
|
2
1
|
import {CursorContext} from "../input/cursor-contexts";
|
|
3
2
|
import {
|
|
4
3
|
isFraction,
|
|
@@ -7,10 +6,10 @@ import {
|
|
|
7
6
|
getCursor,
|
|
8
7
|
} from "../input/mathquill-helpers";
|
|
9
8
|
import {mathQuillInstance} from "../input/mathquill-instance";
|
|
10
|
-
import {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
} from "../input/mathquill-types";
|
|
9
|
+
import {MathFieldActionType} from "../input/mathquill-types";
|
|
10
|
+
|
|
11
|
+
import type Key from "../../data/keys";
|
|
12
|
+
import type {MathFieldInterface} from "../input/mathquill-types";
|
|
14
13
|
|
|
15
14
|
const KeysForJumpContext = {
|
|
16
15
|
[CursorContext.IN_PARENS]: "JUMP_OUT_PARENTHESES",
|
|
@@ -1,16 +1,17 @@
|
|
|
1
|
-
import Key from "../../data/keys";
|
|
2
1
|
import {DecimalSeparator} from "../../enums";
|
|
3
2
|
import {decimalSeparator} from "../../utils";
|
|
4
3
|
import {mathQuillInstance} from "../input/mathquill-instance";
|
|
5
|
-
import {
|
|
6
|
-
MathFieldInterface,
|
|
7
|
-
MathFieldUpdaterCallback,
|
|
8
|
-
} from "../input/mathquill-types";
|
|
9
4
|
|
|
10
5
|
import handleArrow from "./handle-arrow";
|
|
11
6
|
import handleExponent from "./handle-exponent";
|
|
12
7
|
import handleJumpOut from "./handle-jump-out";
|
|
13
8
|
|
|
9
|
+
import type Key from "../../data/keys";
|
|
10
|
+
import type {
|
|
11
|
+
MathFieldInterface,
|
|
12
|
+
MathFieldUpdaterCallback,
|
|
13
|
+
} from "../input/mathquill-types";
|
|
14
|
+
|
|
14
15
|
enum ActionType {
|
|
15
16
|
WRITE = "write",
|
|
16
17
|
CMD = "cmd",
|
|
@@ -23,9 +23,10 @@ describe("<KeypadButton />", () => {
|
|
|
23
23
|
).toBeInTheDocument();
|
|
24
24
|
});
|
|
25
25
|
|
|
26
|
-
it("handles onClickKey callback", () => {
|
|
26
|
+
it("handles onClickKey callback with click", () => {
|
|
27
27
|
// Arrange
|
|
28
|
-
|
|
28
|
+
// persist event to prevent React from releasing/nullifying before assertion
|
|
29
|
+
const mockClickKeyCallback = jest.fn((_, event) => event.persist());
|
|
29
30
|
render(
|
|
30
31
|
<KeypadButton
|
|
31
32
|
onClickKey={mockClickKeyCallback}
|
|
@@ -38,6 +39,46 @@ describe("<KeypadButton />", () => {
|
|
|
38
39
|
userEvent.click(screen.getByRole("button", {name: "Left parenthesis"}));
|
|
39
40
|
|
|
40
41
|
// Assert
|
|
41
|
-
expect(mockClickKeyCallback).toHaveBeenCalledWith(
|
|
42
|
+
expect(mockClickKeyCallback).toHaveBeenCalledWith(
|
|
43
|
+
"LEFT_PAREN",
|
|
44
|
+
expect.objectContaining({
|
|
45
|
+
type: "click",
|
|
46
|
+
detail: 1,
|
|
47
|
+
}),
|
|
48
|
+
);
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
it("handles onClickKey callback with keyboard press", () => {
|
|
52
|
+
// Arrange
|
|
53
|
+
// persist event to prevent React from releasing/nullifying before assertion
|
|
54
|
+
const mockClickKeyCallback = jest.fn((_, event) => event.persist());
|
|
55
|
+
render(
|
|
56
|
+
<KeypadButton
|
|
57
|
+
onClickKey={mockClickKeyCallback}
|
|
58
|
+
keyConfig={Keys.RIGHT_PAREN}
|
|
59
|
+
coord={[0, 0]}
|
|
60
|
+
/>,
|
|
61
|
+
);
|
|
62
|
+
|
|
63
|
+
// Act
|
|
64
|
+
screen.getByRole("button", {name: "Right parenthesis"}).focus();
|
|
65
|
+
userEvent.keyboard("{enter}");
|
|
66
|
+
|
|
67
|
+
// Assert
|
|
68
|
+
expect(mockClickKeyCallback).toHaveBeenCalledWith(
|
|
69
|
+
"RIGHT_PAREN",
|
|
70
|
+
// In the browser, "enter" and "space" trigger a click event with detail 0.
|
|
71
|
+
// However, there is a bug in this version (13.5) of RTL that prevents
|
|
72
|
+
// "keypress" from being fired, which handles the click event.
|
|
73
|
+
// https://github.com/testing-library/user-event/blob/5d946d51d643f0ef7e7730fa527b7ca96e330907/src/keyboard/plugins/functional.ts#L99
|
|
74
|
+
// https://github.com/testing-library/user-event/issues/766
|
|
75
|
+
// The only event fired is `keyDown`, which is inconsistent with the
|
|
76
|
+
// browser. If you're reading this and we have upgraded to 14+, please
|
|
77
|
+
// uncomment the `type` assertion below.
|
|
78
|
+
expect.objectContaining({
|
|
79
|
+
// type: "click",
|
|
80
|
+
detail: 0,
|
|
81
|
+
}),
|
|
82
|
+
);
|
|
42
83
|
});
|
|
43
84
|
});
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import {PerseusAnalyticsEvent} from "@khanacademy/perseus-core";
|
|
2
1
|
import Color from "@khanacademy/wonder-blocks-color";
|
|
3
2
|
import {Popover} from "@khanacademy/wonder-blocks-popover";
|
|
4
3
|
import {render, screen} from "@testing-library/react";
|
|
@@ -7,12 +6,14 @@ import * as React from "react";
|
|
|
7
6
|
|
|
8
7
|
import "@testing-library/jest-dom";
|
|
9
8
|
|
|
10
|
-
import Key from "../../../data/keys";
|
|
11
9
|
import {createMathField} from "../../input/mathquill-instance";
|
|
12
|
-
import {MathFieldInterface} from "../../input/mathquill-types";
|
|
13
10
|
import keyTranslator from "../../key-handlers/key-translator";
|
|
14
11
|
import Keypad from "../index";
|
|
15
12
|
|
|
13
|
+
import type Key from "../../../data/keys";
|
|
14
|
+
import type {MathFieldInterface} from "../../input/mathquill-types";
|
|
15
|
+
import type {PerseusAnalyticsEvent} from "@khanacademy/perseus-core";
|
|
16
|
+
|
|
16
17
|
type Props = {
|
|
17
18
|
onChangeMathInput: (mathInputTex: string) => void;
|
|
18
19
|
keypadClosed?: boolean;
|
|
@@ -1,46 +1,16 @@
|
|
|
1
1
|
import renderSingleKeypad from "../../../../../../testing/render-keypad-with-cypress";
|
|
2
|
-
import KeyConfigs from "../../../data/key-configs";
|
|
3
2
|
|
|
4
|
-
|
|
5
|
-
{
|
|
6
|
-
name: "Operators",
|
|
7
|
-
specialButton: "EXP_2",
|
|
8
|
-
label: KeyConfigs["EXP_2"].ariaLabel,
|
|
9
|
-
},
|
|
10
|
-
{name: "Extras", specialButton: "PI", label: KeyConfigs["PI"].ariaLabel},
|
|
11
|
-
|
|
12
|
-
{
|
|
13
|
-
name: "Geometry",
|
|
14
|
-
specialButton: "COS",
|
|
15
|
-
label: KeyConfigs["COS"].ariaLabel,
|
|
16
|
-
},
|
|
17
|
-
{
|
|
18
|
-
name: "Numbers",
|
|
19
|
-
specialButton: "NUM_7",
|
|
20
|
-
label: KeyConfigs["NUM_7"].ariaLabel,
|
|
21
|
-
},
|
|
22
|
-
];
|
|
3
|
+
import tabs from "./test-data-tabs";
|
|
23
4
|
|
|
24
5
|
describe("Keypad v2", () => {
|
|
25
6
|
tabs.forEach((tab) => {
|
|
26
7
|
it(`switches to the correct tab: ${tab.name}`, () => {
|
|
27
|
-
renderSingleKeypad(
|
|
8
|
+
renderSingleKeypad();
|
|
28
9
|
|
|
29
10
|
// currently clicking on the bottom left due to button re-rendering
|
|
30
11
|
// after mousedown but before mouseup (only in Cypress)
|
|
31
12
|
cy.get('[aria-label="' + tab.name + '"]').click("bottomLeft");
|
|
32
13
|
cy.get('[aria-label="' + tab.label + '"]').should("exist");
|
|
33
14
|
});
|
|
34
|
-
|
|
35
|
-
it(`calls ${tab.specialButton} key callback in ${tab.name} tab`, () => {
|
|
36
|
-
const onClickKeySpy = cy.spy().as("onClickKeySpy");
|
|
37
|
-
renderSingleKeypad(onClickKeySpy);
|
|
38
|
-
cy.get('[aria-label="' + tab.name + '"]').click();
|
|
39
|
-
cy.get('[aria-label="' + tab.label + '"]').click();
|
|
40
|
-
cy.get("@onClickKeySpy").should(
|
|
41
|
-
"have.been.calledOnceWithExactly",
|
|
42
|
-
tab.specialButton,
|
|
43
|
-
);
|
|
44
|
-
});
|
|
45
15
|
});
|
|
46
16
|
});
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import {render, screen} from "@testing-library/react";
|
|
2
|
+
import userEvent from "@testing-library/user-event";
|
|
2
3
|
import * as React from "react";
|
|
3
4
|
import "@testing-library/jest-dom";
|
|
4
5
|
|
|
@@ -6,6 +7,8 @@ import keyConfigs from "../../../data/key-configs";
|
|
|
6
7
|
import {CursorContext} from "../../input/cursor-contexts";
|
|
7
8
|
import Keypad from "../index";
|
|
8
9
|
|
|
10
|
+
import tabs from "./test-data-tabs";
|
|
11
|
+
|
|
9
12
|
const contextToKeyAria = {
|
|
10
13
|
[CursorContext.IN_PARENS]: keyConfigs.JUMP_OUT_PARENTHESES.ariaLabel,
|
|
11
14
|
[CursorContext.IN_SUPER_SCRIPT]: keyConfigs.JUMP_OUT_EXPONENT.ariaLabel,
|
|
@@ -74,4 +77,47 @@ describe("keypad", () => {
|
|
|
74
77
|
}),
|
|
75
78
|
).not.toBeInTheDocument();
|
|
76
79
|
});
|
|
80
|
+
|
|
81
|
+
it(`hides the tabs if providing the Fraction Keypad`, () => {
|
|
82
|
+
// Arrange
|
|
83
|
+
// Act
|
|
84
|
+
render(
|
|
85
|
+
<Keypad
|
|
86
|
+
onClickKey={() => {}}
|
|
87
|
+
fractionsOnly={true}
|
|
88
|
+
sendEvent={async () => {}}
|
|
89
|
+
/>,
|
|
90
|
+
);
|
|
91
|
+
|
|
92
|
+
// Assert
|
|
93
|
+
expect(screen.queryByRole("tab")).not.toBeInTheDocument();
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
it(`clicking tab triggers callback`, () => {
|
|
97
|
+
// Arrange
|
|
98
|
+
const onClickKey = jest.fn();
|
|
99
|
+
|
|
100
|
+
// Act
|
|
101
|
+
render(
|
|
102
|
+
<Keypad
|
|
103
|
+
onClickKey={onClickKey}
|
|
104
|
+
preAlgebra
|
|
105
|
+
trigonometry
|
|
106
|
+
extraKeys={["PI"]}
|
|
107
|
+
sendEvent={async () => {}}
|
|
108
|
+
/>,
|
|
109
|
+
);
|
|
110
|
+
|
|
111
|
+
for (const tabData of tabs) {
|
|
112
|
+
const tab = screen.getByLabelText(tabData.name);
|
|
113
|
+
expect(tab).toBeInTheDocument();
|
|
114
|
+
userEvent.click(tab);
|
|
115
|
+
const key = screen.getByLabelText(tabData.label);
|
|
116
|
+
expect(key).toBeInTheDocument();
|
|
117
|
+
userEvent.click(key);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
// Assert
|
|
121
|
+
expect(onClickKey).toHaveBeenCalledTimes(tabs.length);
|
|
122
|
+
});
|
|
77
123
|
});
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import KeyConfigs from "../../../data/key-configs";
|
|
2
|
+
|
|
3
|
+
export default [
|
|
4
|
+
{
|
|
5
|
+
name: "Operators",
|
|
6
|
+
specialButton: "EXP_2",
|
|
7
|
+
label: KeyConfigs["EXP_2"].ariaLabel,
|
|
8
|
+
},
|
|
9
|
+
{name: "Extras", specialButton: "PI", label: KeyConfigs["PI"].ariaLabel},
|
|
10
|
+
|
|
11
|
+
{
|
|
12
|
+
name: "Geometry",
|
|
13
|
+
specialButton: "COS",
|
|
14
|
+
label: KeyConfigs["COS"].ariaLabel,
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
name: "Numbers",
|
|
18
|
+
specialButton: "NUM_7",
|
|
19
|
+
label: KeyConfigs["NUM_7"].ariaLabel,
|
|
20
|
+
},
|
|
21
|
+
];
|