@khanacademy/math-input 4.3.1 → 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 (42) hide show
  1. package/CHANGELOG.md +19 -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 +173 -48
  17. package/dist/es/index.js.map +1 -1
  18. package/dist/index.js +173 -48
  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 +34 -6
  31. package/src/components/keypad/index.tsx +25 -2
  32. package/src/components/keypad/keypad-mathquill.stories.tsx +19 -0
  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/shared-keys.tsx +56 -8
  36. package/src/components/tabbar/__tests__/tabbar.test.tsx +54 -14
  37. package/src/components/tabbar/icons.tsx +34 -12
  38. package/src/components/tabbar/item.tsx +2 -0
  39. package/src/components/tabbar/tabbar.tsx +32 -12
  40. package/src/components/tabbar/types.ts +6 -1
  41. package/tsconfig-build.json +3 -1
  42. package/tsconfig-build.tsbuildinfo +1 -1
package/dist/index.js CHANGED
@@ -447,6 +447,12 @@ function createMathField(container, configCallback) {
447
447
  return mathQuillInstance.MathField(container, config);
448
448
  }
449
449
 
450
+ /**
451
+ * Editable math fields have all of the above methods in addition to
452
+ * the ones listed here.
453
+ * https://docs.mathquill.com/en/latest/Api_Methods/
454
+ */
455
+
450
456
  let MathFieldActionType = /*#__PURE__*/function (MathFieldActionType) {
451
457
  MathFieldActionType["WRITE"] = "write";
452
458
  MathFieldActionType["CMD"] = "cmd";
@@ -455,9 +461,11 @@ let MathFieldActionType = /*#__PURE__*/function (MathFieldActionType) {
455
461
  return MathFieldActionType;
456
462
  }({});
457
463
 
458
- // The MathQuill MathField Cursor
459
- // it's not part of the public API for MathQuill,
460
- // we reach into the internals to get it
464
+ /**
465
+ * The MathQuill MathField Cursor
466
+ * it's not part of the public API for MathQuill,
467
+ * we reach into the internals to get it
468
+ */
461
469
 
462
470
  const Numerals = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9"];
463
471
  const GreekLetters = ["\\theta", "\\pi"];
@@ -625,8 +633,13 @@ function maybeFindCommand(initialNode) {
625
633
  function maybeFindCommandBeforeParens(leftParenNode) {
626
634
  return maybeFindCommand(leftParenNode[mathQuillInstance.L]);
627
635
  }
628
- function contextForCursor(cursor) {
636
+ function getCursorContext(mathField) {
637
+ if (!mathField) {
638
+ return CursorContext.NONE;
639
+ }
640
+
629
641
  // First, try to find any fraction to the right, unimpeded.
642
+ const cursor = getCursor(mathField);
630
643
  let visitor = cursor;
631
644
  while (visitor[mathQuillInstance.R] !== MathFieldActionType.MQ_END) {
632
645
  if (isFraction(visitor[mathQuillInstance.R])) {
@@ -1048,7 +1061,7 @@ const KeysForJumpContext = {
1048
1061
  */
1049
1062
  function handleJumpOut(mathField, key) {
1050
1063
  const cursor = getCursor(mathField);
1051
- const context = contextForCursor(cursor);
1064
+ const context = getCursorContext(mathField);
1052
1065
 
1053
1066
  // Validate that the current cursor context matches the key's intent.
1054
1067
  if (KeysForJumpContext[context] !== key) {
@@ -1064,6 +1077,7 @@ function handleJumpOut(mathField, key) {
1064
1077
  // Insert at the end of the parentheses, and then navigate right
1065
1078
  // once more to get 'beyond' the parentheses.
1066
1079
  cursor.insRightOf(cursor.parent.parent);
1080
+ mathField.keystroke("Right");
1067
1081
  break;
1068
1082
  case CursorContext.BEFORE_FRACTION:
1069
1083
  // Find the nearest fraction to the right of the cursor.
@@ -1386,7 +1400,7 @@ class MathWrapper {
1386
1400
  // on the MathField, as that handler isn't triggered on navigation
1387
1401
  // events.
1388
1402
  return {
1389
- context: this.contextForCursor(cursor)
1403
+ context: this.contextForCursor()
1390
1404
  };
1391
1405
  }
1392
1406
 
@@ -1427,7 +1441,7 @@ class MathWrapper {
1427
1441
  }
1428
1442
  if (this.callbacks.onCursorMove) {
1429
1443
  this.callbacks.onCursorMove({
1430
- context: this.contextForCursor(cursor)
1444
+ context: this.contextForCursor()
1431
1445
  });
1432
1446
  }
1433
1447
  }
@@ -1441,8 +1455,8 @@ class MathWrapper {
1441
1455
 
1442
1456
  // note(Matthew): extracted this logic to keep this file focused,
1443
1457
  // but it's part of the public MathWrapper API
1444
- contextForCursor(cursor) {
1445
- return contextForCursor(cursor);
1458
+ contextForCursor() {
1459
+ return getCursorContext(this.mathField);
1446
1460
  }
1447
1461
  getSelection() {
1448
1462
  return this.getCursor().selection;
@@ -1797,7 +1811,7 @@ class MathInput extends React__namespace.Component {
1797
1811
  }
1798
1812
  // In that event, we need to update the cursor context ourselves.
1799
1813
  this.props.keypadElement && this.props.keypadElement.setCursor({
1800
- context: this.mathField.contextForCursor(cursor)
1814
+ context: this.mathField.contextForCursor()
1801
1815
  });
1802
1816
  });
1803
1817
  _defineProperty(this, "handleTouchStart", e => {
@@ -4941,26 +4955,44 @@ const IconAsset = function (_ref) {
4941
4955
  case "Extras":
4942
4956
  {
4943
4957
  return /*#__PURE__*/React__namespace.createElement("svg", {
4958
+ xmlns: "http://www.w3.org/2000/svg",
4944
4959
  width: "32",
4945
4960
  height: "32",
4946
- viewBox: "0 0 32 32",
4947
4961
  fill: "none",
4948
- xmlns: "http://www.w3.org/2000/svg"
4962
+ viewBox: "0 0 32 32"
4949
4963
  }, /*#__PURE__*/React__namespace.createElement("g", {
4950
- clipPath: "url(#clip0_4011_87172)",
4951
- fillRule: "evenodd",
4952
- clipRule: "evenodd",
4953
- fill: tintColor
4964
+ clipPath: "url(#a)"
4954
4965
  }, /*#__PURE__*/React__namespace.createElement("path", {
4955
- d: "M6.96605 10.5663c.21528-.0308.38682-.0477.50829-.0477.56911 0 1.09298.1467 1.56707.4407.38228.2296.68532.5084.90301.838.09208-.1207.15248-.2002.18138-.2387l.0047-.0063.0052-.0059c.5949-.6753 1.2944-1.0278 2.093-1.0278.6647 0 1.2196.1954 1.6441.6014.4361.3871.6588.8746.6588 1.45 0 .513-.1499.9563-.4578 1.3166-.3.3693-.7089.552-1.2051.552-.3307 0-.6179-.097-.8437-.304-.2288-.2097-.3392-.4865-.3392-.8103 0-.3888.1066-.7297.3291-1.0101.1474-.1857.3402-.3379.5729-.4597-.1089-.0413-.2631-.0674-.4734-.0674-.1874 0-.3034.0147-.3645.0334-.5098.2175-.9018.667-1.1616 1.3887l-.0009.0025c-.0181.0482-.0814.2776-.1937.7113-.1103.4259-.2644 1.0348-.46245 1.827-.398 1.5767-.60776 2.4474-.63636 2.6333l-.00136.0089c-.04319.2159-.06489.4313-.06489.6465 0 .3246.09331.559.26143.7271.16975.1698.39759.2614.70433.2614.5767 0 1.1059-.2376 1.5927-.7383.4978-.5273.8301-1.1009 1.0032-1.7212l.0011-.0037c.0246-.0819.0521-.156.0846-.2154.0241-.0443.0711-.1194.1545-.1578.0615-.0338.1345-.0465.1905-.0535.0726-.0091.1619-.013.2648-.013.1528 0 .2937.0152.4034.0614.0569.024.1156.0605.1606.1174.0474.0598.0703.1308.0703.2041 0 .022-.0038.0459-.0052.0547-.0023.015-.0055.0337-.0094.0554-.008.0436-.0197.104-.035.1806l-.0027.0138c-.2705.9863-.8277 1.8422-1.6623 2.5666l-.0072.0063c-.746.5872-1.5429.8884-2.3868.8884-1.03863 0-1.85432-.4315-2.43176-1.277-.43549.5807-.97515.9834-1.61932 1.1981l-.00979.0033-.01007.0022c-.15865.0353-.37406.0505-.63768.0505-.93641 0-1.63679-.3356-2.04681-1.0359C3.08287 19.9196 3 19.5787 3 19.1987c0-.5006.1515-.9365.45958-1.2959.31283-.365.71906-.5499 1.2033-.5499.35729 0 .6622.0872.87689.2969.21557.2106.30597.5111.30597.8631 0 .3146-.07482.5975-.23217.8402-.15675.2419-.38726.4314-.67931.5735-.00496.0025-.01055.0055-.01678.0089.15188.0606.31779.0917.49969.0917.44797 0 .86602-.2744 1.24399-.9286l.00246-.0043c.06785-.111.17746-.4008.32772-.9017.14728-.4909.32737-1.1618.5404-2.0139l.0005-.002c.09122-.3497.19011-.7376.29665-1.1637.10644-.4258.18171-.7498.22648-.9736l.00249-.0124c.05541-.2078.09408-.3468.11359-.4088.07445-.404.10861-.6812.10861-.8425 0-.3287-.08814-.5649-.2437-.7325-.15265-.1644-.36917-.2561-.67631-.2561-.62654 0-1.16936.2409-1.63736.7372l-.00199.0022c-.47891.4934-.81198 1.0647-1.00116 1.7162-.0166.0733-.03697.141-.06317.1987-.02519.0554-.06558.1237-.13399.1693l-.01036.0069-.01113.0056c-.03837.0192-.07945.0259-.09978.0289-.02704.0041-.05815.0069-.09148.009-.06706.0042-.15565.0061-.26391.0061h-.40284l-.05858-.0586c-.10441-.1044-.19572-.2369-.19572-.3929v-.0147l.00216-.0146c.06726-.454.32204-1.0087.73818-1.656l.00145-.0022c.74101-1.1194 1.68544-1.7837 2.83334-1.9616l.00234-.0003zM20.9726 10.5186h10.0353c.2631 0 .5155.1045.7016.2906.1861.1861.2906.4384.2906.7016s-.1045.5156-.2906.7016c-.1861.1861-.4385.2907-.7016.2907h-2.705v6.138c0 .2272.0902.445.2508.6056.1606.1606.3784.2508.6056.2508.2271 0 .4449-.0902.6055-.2508.1606-.1606.2508-.3784.2508-.6056 0-.2631.1045-.5155.2906-.7016.1861-.1861.4385-.2906.7017-.2906.2631 0 .5155.1045.7016.2906.1861.1861.2906.4385.2906.7016 0 .7535-.2993 1.4761-.8321 2.0088-.5327.5328-1.2553.8321-2.0087.8321-.7535 0-1.4761-.2993-2.0088-.8321-.5328-.5327-.8321-1.2553-.8321-2.0088v-6.138h-3.2972v7.9867c0 .2631-.1046.5155-.2906.7016-.1861.1861-.4385.2906-.7017.2906-.2631 0-.5155-.1045-.7016-.2906-.1861-.1861-.2906-.4385-.2906-.7016v-7.9867h-.0641c-.5773 0-1.131.2293-1.5392.6375-.4083.4083-.6376.9619-.6376 1.5393 0 .2631-.1045.5155-.2906.7016-.1861.1861-.4385.2906-.7017.2906-.2631 0-.5155-.1045-.7016-.2906-.1861-.1861-.2906-.4385-.2906-.7016.0013-1.1032.4401-2.1611 1.2201-2.9412.7801-.7801 1.838-1.2189 2.9412-1.2201z"
4966
+ fill: tintColor,
4967
+ fillRule: "evenodd",
4968
+ d: "M6.127 10.454c.224-.032.403-.05.53-.05.591 0 1.137.153 1.63.459.398.239.713.529.94.872l.188-.248.005-.007.006-.006c.619-.703 1.347-1.07 2.178-1.07.691 0 1.269.204 1.71.626.454.403.686.91.686 1.51 0 .533-.156.994-.476 1.37-.312.383-.738.574-1.254.574-.345 0-.643-.101-.878-.317a1.1 1.1 0 0 1-.353-.843c0-.405.11-.76.342-1.051.153-.193.354-.352.596-.479a1.416 1.416 0 0 0-.492-.07c-.195 0-.316.016-.38.035-.53.226-.938.694-1.208 1.445l-.001.003c-.02.05-.085.289-.202.74-.115.443-.275 1.077-.481 1.901-.414 1.641-.633 2.547-.662 2.74l-.002.01a3.423 3.423 0 0 0-.067.673c0 .337.097.581.272.756.176.177.413.272.733.272.6 0 1.15-.247 1.657-.768.518-.549.864-1.146 1.044-1.791l.001-.004a1.2 1.2 0 0 1 .088-.224.368.368 0 0 1 .161-.164.564.564 0 0 1 .198-.056 2.19 2.19 0 0 1 .276-.014c.159 0 .305.016.42.064.059.025.12.063.167.122.05.063.073.137.073.213 0 .023-.004.048-.005.057a12.52 12.52 0 0 1-.046.245l-.004.015c-.281 1.026-.86 1.917-1.73 2.67l-.007.007c-.776.611-1.605.925-2.484.925-1.08 0-1.93-.45-2.53-1.33-.453.605-1.015 1.024-1.685 1.248l-.01.003-.011.002a3.23 3.23 0 0 1-.664.053c-.974 0-1.703-.35-2.13-1.078A2.05 2.05 0 0 1 2 19.437c0-.52.158-.975.478-1.349.326-.38.749-.572 1.252-.572.372 0 .69.091.913.31.224.218.318.531.318.898 0 .327-.078.621-.241.874a1.706 1.706 0 0 1-.707.597l-.018.009c.158.063.331.095.52.095.467 0 .902-.285 1.295-.966l.002-.005c.071-.115.185-.417.341-.938.154-.51.341-1.209.563-2.096v-.002c.095-.364.198-.767.31-1.21.11-.444.188-.78.235-1.014l.002-.013c.058-.216.098-.36.119-.425.077-.42.113-.709.113-.877 0-.342-.092-.588-.254-.762-.159-.171-.384-.267-.704-.267-.652 0-1.217.251-1.704.768l-.002.002A4.215 4.215 0 0 0 3.79 14.28a1.084 1.084 0 0 1-.065.207.41.41 0 0 1-.14.176l-.01.007-.012.006a.35.35 0 0 1-.104.03 1.16 1.16 0 0 1-.095.01 5.04 5.04 0 0 1-.275.006H2.67l-.061-.061c-.109-.11-.204-.247-.204-.41v-.015l.003-.015c.07-.472.335-1.05.768-1.723l.001-.002c.771-1.165 1.754-1.857 2.949-2.042h.002Z",
4969
+ clipRule: "evenodd"
4970
+ }), /*#__PURE__*/React__namespace.createElement("path", {
4971
+ fill: tintColor,
4972
+ d: "M21.084 10.284c.932-.008 2.301-.013 4.107-.013 1.325 0 2.327.003 3.007.007a75.812 75.812 0 0 1 .99.013c.025 0 .047.002.065.003h.002c.01 0 .04.003.067.01l.01.002.011.004c.201.07.37.183.488.347a.966.966 0 0 1 .169.574c0 .3-.078.568-.248.79-.168.221-.411.377-.708.479h-.002a1.01 1.01 0 0 1-.221.034 8.213 8.213 0 0 1-.35.016c-.29.008-.696.012-1.219.012h-1.39l-.038.223v.001c-.198 1.185-.295 2.156-.295 2.916 0 1.446.251 2.746.75 3.905l.004.007c.059.153.105.284.137.393.03.103.053.205.053.29 0 .359-.16.68-.44.961-.278.296-.63.445-1.041.445-.255 0-.492-.03-.654-.139l-.009-.006-.008-.006c-.126-.101-.236-.274-.338-.477l-.006-.012c-.331-.768-.49-1.722-.49-2.852 0-.595.007-1.002.025-1.212v-.005c.118-1.157.377-2.551.776-4.18v-.002c.024-.096.045-.18.061-.25h-1.948c-.008.038-.02.086-.034.143l-.002.007a35.14 35.14 0 0 0-.146.537c-.05.232-.1.448-.15.648v.001a230.673 230.673 0 0 1-1.312 4.936 41.285 41.285 0 0 1-.411 1.384c-.104.322-.19.557-.256.681-.115.262-.28.473-.5.617-.225.146-.49.212-.783.212-.449 0-.807-.173-1.006-.549l-.006-.011-.005-.012a1.37 1.37 0 0 1-.067-.486v-.326l.346-.745c1.24-2.61 2.136-4.858 2.695-6.747l.002-.008.094-.281h-.463c-.662 0-1.105.025-1.346.07-.198.04-.47.173-.824.43l-.007.005-.007.005c-.366.228-.69.542-.97.947-.044.069-.085.13-.125.18a.651.651 0 0 1-.141.136l-.027.017-.03.01a.8.8 0 0 1-.19.03c-.07.005-.156.008-.258.008-.17 0-.335-.021-.465-.09a.437.437 0 0 1-.216-.546c.014-.042.034-.086.057-.132.047-.093.113-.208.198-.343l.003-.005c1.147-1.745 2.311-2.774 3.508-2.96a2.345 2.345 0 0 1 .158-.015 60.295 60.295 0 0 1 1.369-.026Z"
4956
4973
  })), /*#__PURE__*/React__namespace.createElement("defs", null, /*#__PURE__*/React__namespace.createElement("clipPath", {
4957
- id: "clip0_4011_87172"
4974
+ id: "a"
4958
4975
  }, /*#__PURE__*/React__namespace.createElement("path", {
4959
4976
  fill: "#fff",
4960
- transform: "translate(3 10.5186)",
4961
- d: "M0 0h29v10.9635H0z"
4977
+ d: "M0 0h28v11.457H0z",
4978
+ transform: "translate(2 10.271)"
4962
4979
  }))));
4963
4980
  }
4981
+ case "Dismiss":
4982
+ {
4983
+ return /*#__PURE__*/React__namespace.createElement("svg", {
4984
+ width: "44",
4985
+ height: "44",
4986
+ viewBox: "0 0 44 44",
4987
+ fill: "none",
4988
+ xmlns: "http://www.w3.org/2000/svg"
4989
+ }, /*#__PURE__*/React__namespace.createElement("path", {
4990
+ fillRule: "evenodd",
4991
+ clipRule: "evenodd",
4992
+ d: "M28.7071 15.2929C28.3166 14.9024 27.6834 14.9024 27.2929 15.2929L22 20.5858L16.7071 15.2929C16.3166 14.9024 15.6834 14.9024 15.2929 15.2929C14.9024 15.6834 14.9024 16.3166 15.2929 16.7071L20.5858 22L15.2929 27.2929C14.9024 27.6834 14.9024 28.3166 15.2929 28.7071C15.6834 29.0976 16.3166 29.0976 16.7071 28.7071L22 23.4142L27.2929 28.7071C27.6834 29.0976 28.3166 29.0976 28.7071 28.7071C29.0976 28.3166 29.0976 27.6834 28.7071 27.2929L23.4142 22L28.7071 16.7071C29.0976 16.3166 29.0976 15.6834 28.7071 15.2929Z",
4993
+ fill: tintColor
4994
+ }));
4995
+ }
4964
4996
  default:
4965
4997
  {
4966
4998
  // type as never;
@@ -5034,7 +5066,9 @@ class TabbarItem extends React__namespace.Component {
5034
5066
  return /*#__PURE__*/React__namespace.createElement(Clickable__default["default"], {
5035
5067
  onClick: onClick,
5036
5068
  disabled: itemState === "disabled",
5037
- "aria-label": itemType
5069
+ "aria-label": itemType,
5070
+ "aria-selected": itemState === "active",
5071
+ role: "tab"
5038
5072
  }, _ref => {
5039
5073
  let {
5040
5074
  hovered,
@@ -5062,19 +5096,28 @@ const styles$7 = aphrodite.StyleSheet.create({
5062
5096
  tabbar: {
5063
5097
  display: "flex",
5064
5098
  flexDirection: "row",
5099
+ justifyContent: "space-between",
5065
5100
  paddingTop: 2,
5066
5101
  paddingBottom: 2
5102
+ },
5103
+ pages: {
5104
+ display: "flex",
5105
+ flexDirection: "row"
5067
5106
  }
5068
5107
  });
5069
5108
  function Tabbar(props) {
5070
5109
  const {
5071
5110
  items,
5111
+ onClickClose,
5072
5112
  selectedItem,
5073
5113
  onSelectItem,
5074
5114
  style
5075
5115
  } = props;
5076
5116
  return /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, {
5077
- style: [styles$7.tabbar, style]
5117
+ style: [styles$7.tabbar, style],
5118
+ role: "tablist"
5119
+ }, /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, {
5120
+ style: [styles$7.pages]
5078
5121
  }, items.map(item => /*#__PURE__*/React__namespace.createElement(TabbarItem, {
5079
5122
  key: "tabbar-item-".concat(item),
5080
5123
  itemState: item === selectedItem ? "active" : "inactive",
@@ -5082,6 +5125,10 @@ function Tabbar(props) {
5082
5125
  onClick: () => {
5083
5126
  onSelectItem(item);
5084
5127
  }
5128
+ }))), /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, null, onClickClose && /*#__PURE__*/React__namespace.createElement(TabbarItem, {
5129
+ itemState: "inactive",
5130
+ itemType: "Dismiss",
5131
+ onClick: onClickClose
5085
5132
  })));
5086
5133
  }
5087
5134
 
@@ -8075,12 +8122,15 @@ function ButtonAsset(_ref) {
8075
8122
  case "PERCENT":
8076
8123
  return /*#__PURE__*/React__namespace.createElement("svg", {
8077
8124
  xmlns: "http://www.w3.org/2000/svg",
8078
- width: "20",
8079
- height: "20",
8080
- fill: "currentColor",
8081
- viewBox: "0 0 256 256"
8125
+ width: "40",
8126
+ height: "40",
8127
+ fill: "none",
8128
+ viewBox: "0 0 40 40"
8082
8129
  }, /*#__PURE__*/React__namespace.createElement("path", {
8083
- d: "M205.66,61.64l-144,144a8,8,0,0,1-11.32-11.32l144-144a8,8,0,0,1,11.32,11.31ZM50.54,101.44a36,36,0,0,1,50.92-50.91h0a36,36,0,0,1-50.92,50.91ZM56,76A20,20,0,1,0,90.14,61.84h0A20,20,0,0,0,56,76ZM216,180a36,36,0,1,1-10.54-25.46h0A35.76,35.76,0,0,1,216,180Zm-16,0a20,20,0,1,0-5.86,14.14A19.87,19.87,0,0,0,200,180Z"
8130
+ fill: "currentColor",
8131
+ fillRule: "evenodd",
8132
+ d: "M24.447 11.106a1 1 0 0 1 .447 1.341l-8 16a1 1 0 1 1-1.788-.894l8-16a1 1 0 0 1 1.341-.447ZM15 13a2 2 0 1 0 0 4 2 2 0 0 0 0-4Zm-4 2a4 4 0 1 1 8 0 4 4 0 0 1-8 0Zm12 10a2 2 0 1 1 4 0 2 2 0 0 1-4 0Zm2-4a4 4 0 1 0 0 8 4 4 0 0 0 0-8Z",
8133
+ clipRule: "evenodd"
8084
8134
  }));
8085
8135
  case "PI":
8086
8136
  return /*#__PURE__*/React__namespace.createElement("svg", {
@@ -8162,6 +8212,28 @@ function ButtonAsset(_ref) {
8162
8212
  d: "M9 9c-.55228 0-1 .44772-1 1v6c0 .5523.44772 1 1 1h6c.5523 0 1-.4477 1-1v-6c0-.55228-.4477-1-1-1H9zm5 2h-4v4h4v-4z",
8163
8213
  fill: "#21242C"
8164
8214
  }));
8215
+ case "JUMP_OUT_BASE":
8216
+ return /*#__PURE__*/React__namespace.createElement("svg", {
8217
+ width: "40",
8218
+ height: "40",
8219
+ viewBox: "0 0 40 40",
8220
+ fill: "none",
8221
+ style: {
8222
+ display: "block",
8223
+ transform: "scale(1,-1)"
8224
+ },
8225
+ xmlns: "http://www.w3.org/2000/svg"
8226
+ }, /*#__PURE__*/React__namespace.createElement("path", {
8227
+ fillRule: "evenodd",
8228
+ clipRule: "evenodd",
8229
+ d: "M18.2929 15.2929c.3905-.3905 1.0237-.3905 1.4142 0L26 21.5858V20c0-.5523.4477-1 1-1s1 .4477 1 1v4.003c-.0004.1345-.0273.2627-.0759.3798-.0477.1152-.1178.2234-.2105.3177a.809004.809004 0 01-.0131.0131c-.1797.1765-.4259.2856-.6975.2864H23c-.5523 0-1-.4477-1-1s.4477-1 1-1h1.5858l-6.2929-6.2929c-.3905-.3905-.3905-1.0237 0-1.4142zM31 33c-.5523 0-1-.4477-1-1V16c0-.5523.4477-1 1-1s1 .4477 1 1v16c0 .5523-.4477 1-1 1z",
8230
+ fill: "#1865F2"
8231
+ }), /*#__PURE__*/React__namespace.createElement("path", {
8232
+ fillRule: "evenodd",
8233
+ clipRule: "evenodd",
8234
+ d: "M9 9c-.55228 0-1 .44772-1 1v6c0 .5523.44772 1 1 1h6c.5523 0 1-.4477 1-1v-6c0-.55228-.4477-1-1-1H9zm5 2h-4v4h4v-4z",
8235
+ fill: "#21242C"
8236
+ }));
8165
8237
  case "JUMP_INTO_NUMERATOR":
8166
8238
  return /*#__PURE__*/React__namespace.createElement("svg", {
8167
8239
  width: "40",
@@ -8275,7 +8347,6 @@ function ButtonAsset(_ref) {
8275
8347
  case "DOWN":
8276
8348
  case "LEFT":
8277
8349
  case "RIGHT":
8278
- case "JUMP_OUT_BASE":
8279
8350
  case "PHI":
8280
8351
  case "NTHROOT3":
8281
8352
  case "POW":
@@ -8444,7 +8515,7 @@ const styles$1 = aphrodite.StyleSheet.create({
8444
8515
  }
8445
8516
  });
8446
8517
 
8447
- const columns = 4;
8518
+ const columns = 3;
8448
8519
  function ExtrasPage(props) {
8449
8520
  const {
8450
8521
  extraKeys,
@@ -8486,18 +8557,21 @@ function NumbersPage(props) {
8486
8557
  const {
8487
8558
  onClickKey
8488
8559
  } = props;
8560
+ // These keys are arranged sequentially so that tabbing follows numerical order. This
8561
+ // allows us to visually mimic a keypad without affecting a11y. The visual order of the
8562
+ // keys in the keypad is determined by their coordinates, not their order in the DOM.
8489
8563
  return /*#__PURE__*/React__namespace.createElement(React__namespace.Fragment, null, /*#__PURE__*/React__namespace.createElement(KeypadButton, {
8490
- keyConfig: KeyConfigs.NUM_7,
8564
+ keyConfig: KeyConfigs.NUM_1,
8491
8565
  onClickKey: onClickKey,
8492
- coord: [0, 0]
8566
+ coord: [0, 2]
8493
8567
  }), /*#__PURE__*/React__namespace.createElement(KeypadButton, {
8494
- keyConfig: KeyConfigs.NUM_8,
8568
+ keyConfig: KeyConfigs.NUM_2,
8495
8569
  onClickKey: onClickKey,
8496
- coord: [1, 0]
8570
+ coord: [1, 2]
8497
8571
  }), /*#__PURE__*/React__namespace.createElement(KeypadButton, {
8498
- keyConfig: KeyConfigs.NUM_9,
8572
+ keyConfig: KeyConfigs.NUM_3,
8499
8573
  onClickKey: onClickKey,
8500
- coord: [2, 0]
8574
+ coord: [2, 2]
8501
8575
  }), /*#__PURE__*/React__namespace.createElement(KeypadButton, {
8502
8576
  keyConfig: KeyConfigs.NUM_4,
8503
8577
  onClickKey: onClickKey,
@@ -8511,17 +8585,17 @@ function NumbersPage(props) {
8511
8585
  onClickKey: onClickKey,
8512
8586
  coord: [2, 1]
8513
8587
  }), /*#__PURE__*/React__namespace.createElement(KeypadButton, {
8514
- keyConfig: KeyConfigs.NUM_1,
8588
+ keyConfig: KeyConfigs.NUM_7,
8515
8589
  onClickKey: onClickKey,
8516
- coord: [0, 2]
8590
+ coord: [0, 0]
8517
8591
  }), /*#__PURE__*/React__namespace.createElement(KeypadButton, {
8518
- keyConfig: KeyConfigs.NUM_2,
8592
+ keyConfig: KeyConfigs.NUM_8,
8519
8593
  onClickKey: onClickKey,
8520
- coord: [1, 2]
8594
+ coord: [1, 0]
8521
8595
  }), /*#__PURE__*/React__namespace.createElement(KeypadButton, {
8522
- keyConfig: KeyConfigs.NUM_3,
8596
+ keyConfig: KeyConfigs.NUM_9,
8523
8597
  onClickKey: onClickKey,
8524
- coord: [2, 2]
8598
+ coord: [2, 0]
8525
8599
  }), /*#__PURE__*/React__namespace.createElement(KeypadButton, {
8526
8600
  keyConfig: KeyConfigs.NUM_0,
8527
8601
  onClickKey: onClickKey,
@@ -8534,6 +8608,11 @@ function NumbersPage(props) {
8534
8608
  keyConfig: KeyConfigs.NEGATIVE,
8535
8609
  onClickKey: onClickKey,
8536
8610
  coord: [2, 3]
8611
+ }), /*#__PURE__*/React__namespace.createElement(KeypadButton, {
8612
+ keyConfig: KeyConfigs.PERCENT,
8613
+ onClickKey: onClickKey,
8614
+ coord: [3, 0],
8615
+ secondary: true
8537
8616
  }));
8538
8617
  }
8539
8618
 
@@ -8600,12 +8679,39 @@ function OperatorsPage(props) {
8600
8679
  })));
8601
8680
  }
8602
8681
 
8682
+ function getCursorContextConfig(cursorContext) {
8683
+ if (!cursorContext) {
8684
+ return null;
8685
+ }
8686
+ switch (cursorContext) {
8687
+ case CursorContext.NONE:
8688
+ return null;
8689
+ case CursorContext.IN_PARENS:
8690
+ return KeyConfigs.JUMP_OUT_PARENTHESES;
8691
+ case CursorContext.IN_SUPER_SCRIPT:
8692
+ return KeyConfigs.JUMP_OUT_EXPONENT;
8693
+ case CursorContext.IN_SUB_SCRIPT:
8694
+ return KeyConfigs.JUMP_OUT_BASE;
8695
+ case CursorContext.IN_NUMERATOR:
8696
+ return KeyConfigs.JUMP_OUT_NUMERATOR;
8697
+ case CursorContext.IN_DENOMINATOR:
8698
+ return KeyConfigs.JUMP_OUT_DENOMINATOR;
8699
+ case CursorContext.BEFORE_FRACTION:
8700
+ return KeyConfigs.JUMP_INTO_NUMERATOR;
8701
+ }
8702
+ }
8603
8703
  function SharedKeys(props) {
8604
8704
  const {
8605
8705
  onClickKey,
8706
+ cursorContext,
8606
8707
  divisionKey,
8607
- multiplicationDot
8708
+ multiplicationDot,
8709
+ selectedPage
8608
8710
  } = props;
8711
+ const cursorKeyConfig = getCursorContextConfig(cursorContext);
8712
+
8713
+ // Fraction position depends on the page
8714
+ const fractionCoord = selectedPage === "Numbers" || selectedPage === "Operators" ? [3, 1] : [3, 0];
8609
8715
  return /*#__PURE__*/React__namespace.createElement(React__namespace.Fragment, null, /*#__PURE__*/React__namespace.createElement(KeypadButton, {
8610
8716
  keyConfig: KeyConfigs.PLUS,
8611
8717
  onClickKey: onClickKey,
@@ -8616,6 +8722,11 @@ function SharedKeys(props) {
8616
8722
  onClickKey: onClickKey,
8617
8723
  coord: [5, 0],
8618
8724
  secondary: true
8725
+ }), /*#__PURE__*/React__namespace.createElement(KeypadButton, {
8726
+ keyConfig: KeyConfigs.FRAC_INCLUSIVE,
8727
+ onClickKey: onClickKey,
8728
+ coord: fractionCoord,
8729
+ secondary: true
8619
8730
  }), /*#__PURE__*/React__namespace.createElement(KeypadButton, {
8620
8731
  keyConfig: multiplicationDot ? KeyConfigs.CDOT : KeyConfigs.TIMES,
8621
8732
  onClickKey: onClickKey,
@@ -8636,8 +8747,8 @@ function SharedKeys(props) {
8636
8747
  onClickKey: onClickKey,
8637
8748
  coord: [5, 2],
8638
8749
  secondary: true
8639
- }), /*#__PURE__*/React__namespace.createElement(KeypadButton, {
8640
- keyConfig: KeyConfigs.FRAC_INCLUSIVE,
8750
+ }), cursorKeyConfig && /*#__PURE__*/React__namespace.createElement(KeypadButton, {
8751
+ keyConfig: cursorKeyConfig,
8641
8752
  onClickKey: onClickKey,
8642
8753
  coord: [4, 3],
8643
8754
  secondary: true
@@ -8649,6 +8760,9 @@ function SharedKeys(props) {
8649
8760
  }));
8650
8761
  }
8651
8762
 
8763
+ const defaultProps = {
8764
+ extraKeys: []
8765
+ };
8652
8766
  function allPages(props) {
8653
8767
  var _props$extraKeys;
8654
8768
  const pages = ["Numbers"];
@@ -8665,12 +8779,16 @@ function allPages(props) {
8665
8779
  }
8666
8780
  return pages;
8667
8781
  }
8782
+
8783
+ // The main (v2) Keypad. Use this component to present an accessible, onscreen
8784
+ // keypad to learners for entering math expressions.
8668
8785
  function Keypad(props) {
8669
8786
  const [selectedPage, setSelectedPage] = React__namespace.useState("Numbers");
8670
8787
  const availablePages = allPages(props);
8671
8788
  const {
8672
8789
  onClickKey,
8673
- extraKeys = [],
8790
+ cursorContext,
8791
+ extraKeys,
8674
8792
  multiplicationDot,
8675
8793
  divisionKey,
8676
8794
  preAlgebra,
@@ -8684,9 +8802,13 @@ function Keypad(props) {
8684
8802
  onSelectItem: tabbarItem => {
8685
8803
  setSelectedPage(tabbarItem);
8686
8804
  },
8687
- style: styles.tabbar
8805
+ style: styles.tabbar,
8806
+ onClickClose: () => onClickKey("DISMISS")
8688
8807
  }), /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, {
8689
- style: styles.grid
8808
+ style: styles.grid,
8809
+ role: "grid",
8810
+ tabIndex: 0,
8811
+ "aria-label": "Keypad"
8690
8812
  }, selectedPage === "Numbers" && /*#__PURE__*/React__namespace.createElement(NumbersPage, {
8691
8813
  onClickKey: onClickKey
8692
8814
  }), selectedPage === "Extras" && /*#__PURE__*/React__namespace.createElement(ExtrasPage, {
@@ -8702,10 +8824,13 @@ function Keypad(props) {
8702
8824
  onClickKey: onClickKey
8703
8825
  }), /*#__PURE__*/React__namespace.createElement(SharedKeys, {
8704
8826
  onClickKey: onClickKey,
8827
+ cursorContext: cursorContext,
8705
8828
  multiplicationDot: multiplicationDot,
8706
- divisionKey: divisionKey
8829
+ divisionKey: divisionKey,
8830
+ selectedPage: selectedPage
8707
8831
  })));
8708
8832
  }
8833
+ Keypad.defaultProps = defaultProps;
8709
8834
  const styles = aphrodite.StyleSheet.create({
8710
8835
  tabbar: {
8711
8836
  background: Color__default["default"].white