@khanacademy/math-input 4.3.0 → 5.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 (43) hide show
  1. package/CHANGELOG.md +25 -0
  2. package/dist/components/input/math-wrapper.d.ts +2 -2
  3. package/dist/components/input/math-wrapper.js.flow +2 -4
  4. package/dist/components/input/mathquill-helpers.d.ts +1 -1
  5. package/dist/components/input/mathquill-helpers.js.flow +2 -2
  6. package/dist/components/input/mathquill-types.d.ts +270 -10
  7. package/dist/components/input/mathquill-types.js.flow +312 -10
  8. package/dist/components/keypad/index.d.ts +11 -1
  9. package/dist/components/keypad/index.js.flow +14 -1
  10. package/dist/components/keypad/shared-keys.d.ts +4 -0
  11. package/dist/components/keypad/shared-keys.js.flow +4 -0
  12. package/dist/components/tabbar/tabbar.d.ts +1 -0
  13. package/dist/components/tabbar/tabbar.js.flow +1 -0
  14. package/dist/components/tabbar/types.d.ts +1 -1
  15. package/dist/components/tabbar/types.js.flow +6 -1
  16. package/dist/es/index.js +607 -409
  17. package/dist/es/index.js.map +1 -1
  18. package/dist/index.js +607 -409
  19. package/dist/index.js.map +1 -1
  20. package/package.json +2 -1
  21. package/src/components/input/__tests__/mathquill-helpers.test.ts +105 -0
  22. package/src/components/input/math-input.tsx +1 -1
  23. package/src/components/input/math-wrapper.ts +6 -10
  24. package/src/components/input/mathquill-helpers.ts +8 -1
  25. package/src/components/input/mathquill-types.ts +308 -40
  26. package/src/components/key-handlers/__tests__/handle-jump-out.test.ts +94 -0
  27. package/src/components/key-handlers/handle-jump-out.ts +3 -2
  28. package/src/components/keypad/__tests__/keypad-v2-mathquill.test.tsx +42 -39
  29. package/src/components/keypad/__tests__/keypad.test.tsx +42 -0
  30. package/src/components/keypad/button-assets.tsx +540 -316
  31. package/src/components/keypad/index.tsx +25 -2
  32. package/src/components/keypad/keypad-mathquill.stories.tsx +20 -1
  33. package/src/components/keypad/keypad-pages/extras-page.tsx +1 -1
  34. package/src/components/keypad/keypad-pages/numbers-page.tsx +25 -16
  35. package/src/components/keypad/keypad.stories.tsx +11 -0
  36. package/src/components/keypad/shared-keys.tsx +56 -8
  37. package/src/components/tabbar/__tests__/tabbar.test.tsx +54 -14
  38. package/src/components/tabbar/icons.tsx +48 -8
  39. package/src/components/tabbar/item.tsx +2 -0
  40. package/src/components/tabbar/tabbar.tsx +32 -12
  41. package/src/components/tabbar/types.ts +6 -1
  42. package/tsconfig-build.json +3 -1
  43. package/tsconfig-build.tsbuildinfo +1 -1
@@ -3,7 +3,7 @@ import {CursorContext} from "../input/cursor-contexts";
3
3
  import {
4
4
  isFraction,
5
5
  isParens,
6
- contextForCursor,
6
+ getCursorContext,
7
7
  getCursor,
8
8
  } from "../input/mathquill-helpers";
9
9
  import {mathQuillInstance} from "../input/mathquill-instance";
@@ -26,7 +26,7 @@ const KeysForJumpContext = {
26
26
  */
27
27
  function handleJumpOut(mathField: MathFieldInterface, key: Key): void {
28
28
  const cursor = getCursor(mathField);
29
- const context = contextForCursor(cursor);
29
+ const context = getCursorContext(mathField);
30
30
 
31
31
  // Validate that the current cursor context matches the key's intent.
32
32
  if (KeysForJumpContext[context] !== key) {
@@ -43,6 +43,7 @@ function handleJumpOut(mathField: MathFieldInterface, key: Key): void {
43
43
  // Insert at the end of the parentheses, and then navigate right
44
44
  // once more to get 'beyond' the parentheses.
45
45
  cursor.insRightOf(cursor.parent.parent);
46
+ mathField.keystroke("Right");
46
47
  break;
47
48
 
48
49
  case CursorContext.BEFORE_FRACTION:
@@ -65,6 +65,7 @@ function V2KeypadWithMathquill(props: Props) {
65
65
  multiplicationDot
66
66
  preAlgebra
67
67
  trigonometry
68
+ sendEvent={async () => {}}
68
69
  />
69
70
  </div>
70
71
  }
@@ -95,26 +96,26 @@ describe("Keypad v2 with MathQuill", () => {
95
96
  // Act
96
97
 
97
98
  // a^2
98
- userEvent.click(screen.getByRole("button", {name: "Extras"}));
99
+ userEvent.click(screen.getByRole("tab", {name: "Extras"}));
99
100
  userEvent.click(screen.getByRole("button", {name: "a"}));
100
- userEvent.click(screen.getByRole("button", {name: "Operators"}));
101
+ userEvent.click(screen.getByRole("tab", {name: "Operators"}));
101
102
  userEvent.click(screen.getByRole("button", {name: "Square"}));
102
103
 
103
104
  // +
104
- userEvent.click(screen.getByRole("button", {name: "Numbers"}));
105
+ userEvent.click(screen.getByRole("tab", {name: "Numbers"}));
105
106
  userEvent.click(screen.getByRole("button", {name: "Plus"}));
106
107
 
107
108
  // b^2 =
108
- userEvent.click(screen.getByRole("button", {name: "Extras"}));
109
+ userEvent.click(screen.getByRole("tab", {name: "Extras"}));
109
110
  userEvent.click(screen.getByRole("button", {name: "b"}));
110
- userEvent.click(screen.getByRole("button", {name: "Operators"}));
111
+ userEvent.click(screen.getByRole("tab", {name: "Operators"}));
111
112
  userEvent.click(screen.getByRole("button", {name: "Square"}));
112
113
  userEvent.click(screen.getByRole("button", {name: "Equals sign"}));
113
114
 
114
115
  // c^2
115
- userEvent.click(screen.getByRole("button", {name: "Extras"}));
116
+ userEvent.click(screen.getByRole("tab", {name: "Extras"}));
116
117
  userEvent.click(screen.getByRole("button", {name: "c"}));
117
- userEvent.click(screen.getByRole("button", {name: "Operators"}));
118
+ userEvent.click(screen.getByRole("tab", {name: "Operators"}));
118
119
  userEvent.click(screen.getByRole("button", {name: "Square"}));
119
120
 
120
121
  // Assert
@@ -131,26 +132,26 @@ describe("Keypad v2 with MathQuill", () => {
131
132
  // Act
132
133
 
133
134
  // c = /Square root
134
- userEvent.click(screen.getByRole("button", {name: "Extras"}));
135
+ userEvent.click(screen.getByRole("tab", {name: "Extras"}));
135
136
  userEvent.click(screen.getByRole("button", {name: "c"}));
136
- userEvent.click(screen.getByRole("button", {name: "Operators"}));
137
+ userEvent.click(screen.getByRole("tab", {name: "Operators"}));
137
138
  userEvent.click(screen.getByRole("button", {name: "Equals sign"}));
138
139
  userEvent.click(screen.getByRole("button", {name: "Square root"}));
139
140
 
140
141
  // a^2
141
- userEvent.click(screen.getByRole("button", {name: "Extras"}));
142
+ userEvent.click(screen.getByRole("tab", {name: "Extras"}));
142
143
  userEvent.click(screen.getByRole("button", {name: "a"}));
143
- userEvent.click(screen.getByRole("button", {name: "Operators"}));
144
+ userEvent.click(screen.getByRole("tab", {name: "Operators"}));
144
145
  userEvent.click(screen.getByRole("button", {name: "Square"}));
145
146
 
146
147
  // +
147
- userEvent.click(screen.getByRole("button", {name: "Numbers"}));
148
+ userEvent.click(screen.getByRole("tab", {name: "Numbers"}));
148
149
  userEvent.click(screen.getByRole("button", {name: "Plus"}));
149
150
 
150
151
  // b^2
151
- userEvent.click(screen.getByRole("button", {name: "Extras"}));
152
+ userEvent.click(screen.getByRole("tab", {name: "Extras"}));
152
153
  userEvent.click(screen.getByRole("button", {name: "b"}));
153
- userEvent.click(screen.getByRole("button", {name: "Operators"}));
154
+ userEvent.click(screen.getByRole("tab", {name: "Operators"}));
154
155
  userEvent.click(screen.getByRole("button", {name: "Square"}));
155
156
 
156
157
  // Assert
@@ -170,15 +171,15 @@ describe("Keypad v2 with MathQuill", () => {
170
171
 
171
172
  // Argument is empty because mathquill generates textarea w/o label
172
173
  userEvent.type(screen.getByRole("textbox"), "a");
173
- userEvent.click(screen.getByRole("button", {name: "Operators"}));
174
+ userEvent.click(screen.getByRole("tab", {name: "Operators"}));
174
175
  userEvent.click(screen.getByRole("button", {name: "Square"}));
175
176
 
176
177
  userEvent.type(screen.getByRole("textbox"), "+");
177
178
 
178
179
  // b^2
179
- userEvent.click(screen.getByRole("button", {name: "Extras"}));
180
+ userEvent.click(screen.getByRole("tab", {name: "Extras"}));
180
181
  userEvent.click(screen.getByRole("button", {name: "b"}));
181
- userEvent.click(screen.getByRole("button", {name: "Operators"}));
182
+ userEvent.click(screen.getByRole("tab", {name: "Operators"}));
182
183
  userEvent.click(screen.getByRole("button", {name: "Square"}));
183
184
  userEvent.type(screen.getByRole("textbox"), "=c^2");
184
185
 
@@ -194,33 +195,35 @@ describe("Keypad v2 with MathQuill", () => {
194
195
  );
195
196
 
196
197
  // Act
197
- // Write `a^2+b^2=c^2` using the keypad
198
- const buttonPressesForFormula = [
199
- "Extras",
200
- "a",
201
- "Operators",
202
- "Square",
203
- "Numbers",
204
- "Plus",
205
- "Extras",
206
- "b",
207
- "Operators",
208
- "Square",
209
- "Equals sign",
210
- "Extras",
211
- "c",
212
- "Operators",
213
- "Square",
214
- ];
215
- buttonPressesForFormula.forEach((button) => {
216
- userEvent.click(screen.getByRole("button", {name: button}));
217
- });
198
+
199
+ // a^2
200
+ userEvent.click(screen.getByRole("tab", {name: "Extras"}));
201
+ userEvent.click(screen.getByRole("button", {name: "a"}));
202
+ userEvent.click(screen.getByRole("tab", {name: "Operators"}));
203
+ userEvent.click(screen.getByRole("button", {name: "Square"}));
204
+
205
+ // +
206
+ userEvent.click(screen.getByRole("tab", {name: "Numbers"}));
207
+ userEvent.click(screen.getByRole("button", {name: "Plus"}));
208
+
209
+ // b^2
210
+ userEvent.click(screen.getByRole("tab", {name: "Extras"}));
211
+ userEvent.click(screen.getByRole("button", {name: "b"}));
212
+ userEvent.click(screen.getByRole("tab", {name: "Operators"}));
213
+ userEvent.click(screen.getByRole("button", {name: "Square"}));
214
+
215
+ // =c^2
216
+ userEvent.click(screen.getByRole("button", {name: "Equals sign"}));
217
+ userEvent.click(screen.getByRole("tab", {name: "Extras"}));
218
+ userEvent.click(screen.getByRole("button", {name: "c"}));
219
+ userEvent.click(screen.getByRole("tab", {name: "Operators"}));
220
+ userEvent.click(screen.getByRole("button", {name: "Square"}));
218
221
 
219
222
  // Assert
220
223
  // make sure the formula was typed correctly
221
224
  expect(mockMathInputCallback).toHaveBeenLastCalledWith("a^2+b^2=c^2");
222
225
 
223
- userEvent.click(screen.getByRole("button", {name: "Numbers"}));
226
+ userEvent.click(screen.getByRole("tab", {name: "Numbers"}));
224
227
  // delete: need 14 backspaces in MathQuill to delete `a^2+b^2=c^2`
225
228
  for (let i = 0; i < 14; i++) {
226
229
  userEvent.click(screen.getByRole("button", {name: "Delete"}));
@@ -0,0 +1,42 @@
1
+ import {render, screen} from "@testing-library/react";
2
+ import * as React from "react";
3
+
4
+ import keyConfigs from "../../../data/key-configs";
5
+ import {CursorContext} from "../../input/cursor-contexts";
6
+ import Keypad from "../index";
7
+
8
+ const contextToKeyAria = {
9
+ [CursorContext.IN_PARENS]: keyConfigs.JUMP_OUT_PARENTHESES.ariaLabel,
10
+ [CursorContext.IN_SUPER_SCRIPT]: keyConfigs.JUMP_OUT_EXPONENT.ariaLabel,
11
+ [CursorContext.IN_SUB_SCRIPT]: keyConfigs.JUMP_OUT_BASE.ariaLabel,
12
+ [CursorContext.IN_NUMERATOR]: keyConfigs.JUMP_OUT_NUMERATOR.ariaLabel,
13
+ [CursorContext.IN_DENOMINATOR]: keyConfigs.JUMP_OUT_DENOMINATOR.ariaLabel,
14
+ [CursorContext.BEFORE_FRACTION]: keyConfigs.JUMP_INTO_NUMERATOR.ariaLabel,
15
+ };
16
+
17
+ describe("keypad", () => {
18
+ describe("shows navigation buttons", () => {
19
+ Object.entries(contextToKeyAria).forEach(([context, ariaLabel]) => {
20
+ it(`shows button for ${context}`, () => {
21
+ // Arrange
22
+ // Act
23
+ render(
24
+ <Keypad
25
+ onClickKey={() => {}}
26
+ cursorContext={context as CursorContext}
27
+ sendEvent={async () => {
28
+ /* TODO: verify correct analytics event sent */
29
+ }}
30
+ />,
31
+ );
32
+
33
+ // Assert
34
+ expect(
35
+ screen.getByRole("button", {
36
+ name: ariaLabel,
37
+ }),
38
+ );
39
+ });
40
+ });
41
+ });
42
+ });