@khanacademy/math-input 17.5.0 → 18.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/dist/es/index.js CHANGED
@@ -1,11 +1,9 @@
1
1
  import { addLibraryVersionToPerseusDebug } from '@khanacademy/perseus-core';
2
- import * as i18n from '@khanacademy/wonder-blocks-i18n';
3
- import { getDecimalSeparator, getLocale } from '@khanacademy/wonder-blocks-i18n';
4
2
  import { color } from '@khanacademy/wonder-blocks-tokens';
5
3
  import { entries } from '@khanacademy/wonder-stuff-core';
6
4
  import { StyleSheet, css } from 'aphrodite';
7
5
  import * as React from 'react';
8
- import { useState, useMemo, useEffect } from 'react';
6
+ import { useContext, useState, useMemo, useEffect } from 'react';
9
7
  import ReactDOM from 'react-dom';
10
8
  import { SpeechRuleEngine } from '@khanacademy/mathjax-renderer';
11
9
  import MathQuill from 'mathquill';
@@ -17,7 +15,7 @@ import PropTypes from 'prop-types';
17
15
 
18
16
  // This file is processed by a Rollup plugin (replace) to inject the production
19
17
  const libName = "@khanacademy/math-input";
20
- const libVersion = "17.5.0";
18
+ const libVersion = "18.0.0";
21
19
  addLibraryVersionToPerseusDebug(libName, libVersion);
22
20
 
23
21
  function _extends() {
@@ -100,6 +98,117 @@ View.styles = StyleSheet.create({
100
98
  }
101
99
  });
102
100
 
101
+ /**
102
+ * The translated strings that are used to render the Math Input.
103
+ */
104
+
105
+ /**
106
+ * Mock strings for the Math Input package, to be used for tests and Storybook.
107
+ */
108
+ const mockStrings = {
109
+ mathInputBox: "Math input box",
110
+ fingerTap: "Tap with one or two fingers to open keyboard",
111
+ before: ({
112
+ obj
113
+ }) => `before ${obj}`,
114
+ after: ({
115
+ obj
116
+ }) => `after ${obj}`,
117
+ "beginning of": ({
118
+ obj
119
+ }) => `beginning of ${obj}`,
120
+ "end of": ({
121
+ obj
122
+ }) => `end of ${obj}`,
123
+ Baseline: "Baseline",
124
+ Superscript: "Superscript",
125
+ selected: ({
126
+ obj
127
+ }) => `${obj} selected`,
128
+ "no answer": "no answer",
129
+ "nothing selected": "nothing selected",
130
+ "nothing to the right": "nothing to the right",
131
+ "nothing to the left": "nothing to the left",
132
+ "block is empty": "block is empty",
133
+ "nothing above": "nothing above",
134
+ labelValue: ({
135
+ label,
136
+ value
137
+ }) => `${label}: ${value}`,
138
+ plus: "Plus",
139
+ minus: "Minus",
140
+ negative: "Negative",
141
+ times: "Multiply",
142
+ divide: "Divide",
143
+ decimal: "Decimal",
144
+ percent: "Percent",
145
+ cdot: "Multiply",
146
+ equalsSign: "Equals sign",
147
+ notEqualsSign: "Not-equals sign",
148
+ greaterThanSign: "Greater than sign",
149
+ lessThanSign: "Less than sign",
150
+ greaterThanOrEqualToSign: "Greater than or equal to sign",
151
+ lessThanOrEqualSign: "Less than or equal to sign",
152
+ fractionExpressionInNumerator: "Fraction, with current expression in numerator",
153
+ fractionExcludingExpression: "Fraction, excluding the current expression",
154
+ customExponent: "Custom exponent",
155
+ square: "Square",
156
+ cube: "Cube",
157
+ squareRoot: "Square root",
158
+ cubeRoot: "Cube root",
159
+ radicalWithCustomRoot: "Radical with custom root",
160
+ leftParenthesis: "Left parenthesis",
161
+ rightParenthesis: "Right parenthesis",
162
+ naturalLog: "Natural logarithm",
163
+ logBase10: "Logarithm with base 10",
164
+ logCustomBase: "Logarithm with custom base",
165
+ sine: "Sine",
166
+ cosine: "Cosine",
167
+ tangent: "Tangent",
168
+ pi: "Pi",
169
+ theta: "Theta",
170
+ upArrow: "Up arrow",
171
+ rightArrow: "Right arrow",
172
+ downArrow: "Down arrow",
173
+ leftArrow: "Left arrow",
174
+ navOutOfParentheses: "Navigate right out of a set of parentheses",
175
+ navOutOfExponent: "Navigate right out of an exponent",
176
+ navOutOfBase: "Navigate right out of a base",
177
+ navIntoNumerator: "Navigate right into the numerator of a fraction",
178
+ navOutOfNumeratorIntoDenominator: "Navigate right out of the numerator and into the denominator",
179
+ navOutOfDenominator: "Navigate right out of the denominator of a fraction",
180
+ delete: "Delete",
181
+ dismiss: "Dismiss"
182
+ };
183
+
184
+ /**
185
+ * MathInputI18nContext provides a way to set the strings and locale that are
186
+ * used inside the Math Input package.
187
+ *
188
+ */
189
+ // @ts-expect-error - TS2322 - Type 'Context<{ strings: {}; locale: string; }>' is not assignable to type 'Context<I18nContextType>'.
190
+ const MathInputI18nContext = /*#__PURE__*/React.createContext(process.env.NODE_ENV === "test" || process.env.STORYBOOK ? {
191
+ strings: mockStrings,
192
+ locale: "en"
193
+ } :
194
+ // We want to return null here, not an empty object, so that we
195
+ // are will throw an error when attempting to access the
196
+ // undefined locale or strings, making it easier to debug.
197
+ null);
198
+ function MathInputI18nContextProvider({
199
+ children,
200
+ strings,
201
+ locale
202
+ }) {
203
+ return /*#__PURE__*/React.createElement(MathInputI18nContext.Provider, {
204
+ value: {
205
+ strings,
206
+ locale
207
+ }
208
+ }, children);
209
+ }
210
+ const useMathInputI18n = () => useContext(MathInputI18nContext);
211
+
103
212
  /**
104
213
  * KeypadContext provides a way to the Keypad and Perseus Renderers to
105
214
  * communicate.
@@ -345,13 +454,34 @@ const DecimalSeparator = {
345
454
  PERIOD: "."
346
455
  };
347
456
 
348
- // NOTES(kevinb):
349
- // - In order to get the correct decimal separator for the current locale,
350
- // the locale must bet set using `setLocale(kaLocale)` which can be
351
- // imported from wonder-blocks-i18n.
352
- // - Some languages/locales use different decimal separators than the ones
353
- // listed here. Much of the Arab world uses U+066C.
354
- const decimalSeparator = getDecimalSeparator() === "," ? DecimalSeparator.COMMA : DecimalSeparator.PERIOD;
457
+ /**
458
+ * Get the character used for separating decimals.
459
+ */
460
+ const getDecimalSeparator = locale => {
461
+ var _match$;
462
+ let separator = DecimalSeparator.PERIOD;
463
+ switch (locale) {
464
+ // TODO(somewhatabstract): Remove this when Chrome supports the `ka`
465
+ // locale properly.
466
+ // https://github.com/formatjs/formatjs/issues/1526#issuecomment-559891201
467
+ //
468
+ // Supported locales in Chrome:
469
+ // https://source.chromium.org/chromium/chromium/src/+/master:third_party/icu/scripts/chrome_ui_languages.list
470
+ case "ka":
471
+ separator = ",";
472
+ break;
473
+ default:
474
+ const numberWithDecimalSeparator = 1.1;
475
+ // TODO(FEI-3647): Update to use .formatToParts() once we no longer have to
476
+ // support Safari 12.
477
+ const match = new Intl.NumberFormat(locale).format(numberWithDecimalSeparator)
478
+ // 0x661 is ARABIC-INDIC DIGIT ONE
479
+ // 0x6F1 is EXTENDED ARABIC-INDIC DIGIT ONE
480
+ .match(/[^\d\u0661\u06F1]/);
481
+ separator = (_match$ = match == null ? void 0 : match[0]) != null ? _match$ : ".";
482
+ }
483
+ return separator === "," ? DecimalSeparator.COMMA : DecimalSeparator.PERIOD;
484
+ };
355
485
  const CDOT_ONLY = ["az", "cs", "da", "de", "hu", "hy", "kk", "ky", "lt", "lv", "nb", "sk", "sr", "sv", "uz"];
356
486
  const TIMES_ONLY = ["fr", "tr", "pt-pt"];
357
487
 
@@ -366,8 +496,7 @@ const TIMES_ONLY = ["fr", "tr", "pt-pt"];
366
496
  * @param {boolean} convertDotToTimes - the setting set by content creators
367
497
  * @returns {boolean} - true to convert to × (TIMES), false to use · (CDOT)
368
498
  */
369
- function convertDotToTimesByLocale(convertDotToTimes) {
370
- const locale = getLocale();
499
+ function convertDotToTimesByLocale(locale, convertDotToTimes) {
371
500
  if (CDOT_ONLY.includes(locale)) {
372
501
  return false;
373
502
  }
@@ -383,39 +512,6 @@ function convertDotToTimesByLocale(convertDotToTimes) {
383
512
  const inJest = typeof process !== "undefined" && !!((_process = process) != null && (_process = _process.env) != null && _process.JEST_WORKER_ID);
384
513
  // Explicitly checking for undefined because Cypress throws an error
385
514
 
386
- const mathQuillStrings = {
387
- mathInputBox: i18n._("Math input box"),
388
- ariaStaticStringsMap: {
389
- before: obj => i18n._("before %(obj)s", {
390
- obj
391
- }),
392
- after: obj => i18n._("after %(obj)s", {
393
- obj
394
- }),
395
- "beginning of": obj => i18n._("beginning of %(obj)s", {
396
- obj
397
- }),
398
- "end of": obj => i18n._("end of %(obj)s", {
399
- obj
400
- }),
401
- Baseline: i18n._("Baseline"),
402
- Superscript: i18n._("Superscript"),
403
- selected: obj => i18n._("%(obj)s selected", {
404
- obj
405
- }),
406
- "no answer": i18n._("no answer"),
407
- "nothing selected": i18n._("nothing selected"),
408
- "nothing to the right": i18n._("nothing to the right"),
409
- "nothing to the left": i18n._("nothing to the left"),
410
- "block is empty": i18n._("block is empty"),
411
- "nothing above": i18n._("nothing above"),
412
- labelValue: (label, value) => i18n._("%(label)s: %(value)s", {
413
- label,
414
- value
415
- })
416
- }
417
- };
418
-
419
515
  // We only need one MathQuill instance (referred to as MQ in the docs)
420
516
  // and that contains some MQ constants and the MathField constructor
421
517
  const mathQuillInstance = MathQuill.getInterface(3);
@@ -461,10 +557,38 @@ const createBaseConfig = () => ({
461
557
  * This allows callers to do minimal configuration as only configs
462
558
  * that vary from the default need to be provided.
463
559
  */
464
- function createMathField(container, configCallback) {
560
+ function createMathField(container, strings, configCallback) {
465
561
  const baseConfig = createBaseConfig();
466
562
  const config = configCallback ? configCallback(baseConfig) : baseConfig;
467
- const mathField = mathQuillInstance.MathField(container, config).setAriaLabel(mathQuillStrings.mathInputBox).setAriaStringsOverrideMap(mathQuillStrings.ariaStaticStringsMap);
563
+ const mathField = mathQuillInstance.MathField(container, config).setAriaLabel(strings.mathInputBox).setAriaStringsOverrideMap({
564
+ before: obj => strings.before({
565
+ obj
566
+ }),
567
+ after: obj => strings.after({
568
+ obj
569
+ }),
570
+ "beginning of": obj => strings["beginning of"]({
571
+ obj
572
+ }),
573
+ "end of": obj => strings["end of"]({
574
+ obj
575
+ }),
576
+ Baseline: strings.Baseline,
577
+ Superscript: strings.Superscript,
578
+ selected: obj => strings.selected({
579
+ obj
580
+ }),
581
+ "no answer": strings["no answer"],
582
+ "nothing selected": strings["nothing selected"],
583
+ "nothing to the right": strings["nothing to the right"],
584
+ "nothing to the left": strings["nothing to the left"],
585
+ "block is empty": strings["block is empty"],
586
+ "nothing above": strings["nothing above"],
587
+ labelValue: (label, value) => strings.labelValue({
588
+ label,
589
+ value
590
+ })
591
+ });
468
592
 
469
593
  // We should avoid running SpeechRuleEngine.setup() in Jest. It makes an
470
594
  // HTTP request to fetch non-english speech rules, and cannot be easily
@@ -1113,7 +1237,7 @@ function buildNormalFunctionCallback(command) {
1113
1237
  mathField.keystroke("Left");
1114
1238
  };
1115
1239
  }
1116
- const keyToMathquillMap = {
1240
+ const getKeyTranslator = locale => ({
1117
1241
  EXP: handleExponent,
1118
1242
  EXP_2: handleExponent,
1119
1243
  EXP_3: handleExponent,
@@ -1131,7 +1255,7 @@ const keyToMathquillMap = {
1131
1255
  COS: buildNormalFunctionCallback("cos"),
1132
1256
  TAN: buildNormalFunctionCallback("tan"),
1133
1257
  CDOT: buildGenericCallback("\\cdot"),
1134
- DECIMAL: buildGenericCallback(decimalSeparator),
1258
+ DECIMAL: buildGenericCallback(getDecimalSeparator(locale)),
1135
1259
  DIVIDE: buildGenericCallback("\\div"),
1136
1260
  EQUAL: buildGenericCallback("="),
1137
1261
  GEQ: buildGenericCallback("\\geq"),
@@ -1270,16 +1394,6 @@ const keyToMathquillMap = {
1270
1394
  X: buildGenericCallback("X"),
1271
1395
  Y: buildGenericCallback("Y"),
1272
1396
  Z: buildGenericCallback("Z")
1273
- };
1274
-
1275
- const mobileKeyTranslator = _extends({}, keyToMathquillMap, {
1276
- // note(Matthew): our mobile backspace logic is really complicated
1277
- // and for some reason doesn't really work in the desktop experience.
1278
- // So we default to the basic backspace functionality in the
1279
- // key translator and overwrite it with the complicated logic here
1280
- // until we can unify the experiences (if we even want to).
1281
- // https://khanacademy.atlassian.net/browse/LC-906
1282
- BACKSPACE: handleBackspace
1283
1397
  });
1284
1398
 
1285
1399
  /**
@@ -1288,11 +1402,12 @@ const mobileKeyTranslator = _extends({}, keyToMathquillMap, {
1288
1402
  * from MathQuill changes.
1289
1403
  */
1290
1404
  class MathWrapper {
1291
- constructor(element, callbacks = {}) {
1405
+ constructor(element, strings, locale, callbacks = {}) {
1292
1406
  this.mathField = void 0;
1293
1407
  // MathQuill MathField input
1294
1408
  this.callbacks = void 0;
1295
- this.mathField = createMathField(element, () => {
1409
+ this.mobileKeyTranslator = void 0;
1410
+ this.mathField = createMathField(element, strings, () => {
1296
1411
  return {
1297
1412
  // use a span instead of a textarea so that we don't bring up the
1298
1413
  // native keyboard on mobile when selecting the input
@@ -1302,6 +1417,15 @@ class MathWrapper {
1302
1417
  };
1303
1418
  });
1304
1419
  this.callbacks = callbacks;
1420
+ this.mobileKeyTranslator = _extends({}, getKeyTranslator(locale), {
1421
+ // note(Matthew): our mobile backspace logic is really complicated
1422
+ // and for some reason doesn't really work in the desktop experience.
1423
+ // So we default to the basic backspace functionality in the
1424
+ // key translator and overwrite it with the complicated logic here
1425
+ // until we can unify the experiences (if we even want to).
1426
+ // https://khanacademy.atlassian.net/browse/LC-906
1427
+ BACKSPACE: handleBackspace
1428
+ });
1305
1429
  }
1306
1430
  focus() {
1307
1431
  // HACK(charlie): We shouldn't reaching into MathQuill internals like
@@ -1327,7 +1451,7 @@ class MathWrapper {
1327
1451
  */
1328
1452
  pressKey(key) {
1329
1453
  const cursor = this.getCursor();
1330
- const translator = mobileKeyTranslator[key];
1454
+ const translator = this.mobileKeyTranslator[key];
1331
1455
  if (translator) {
1332
1456
  translator(this.mathField, key);
1333
1457
  }
@@ -2055,7 +2179,7 @@ class MathInput extends React.Component {
2055
2179
  }
2056
2180
  componentDidMount() {
2057
2181
  this._isMounted = true;
2058
- this.mathField = new MathWrapper(this._mathContainer, {
2182
+ this.mathField = new MathWrapper(this._mathContainer, this.context.strings, this.context.locale, {
2059
2183
  onCursorMove: cursor => {
2060
2184
  // TODO(charlie): It's not great that there is so much coupling
2061
2185
  // between this keypad and the input behavior. We should wrap
@@ -2213,7 +2337,7 @@ class MathInput extends React.Component {
2213
2337
  // keyboard appear. It should only require one finger, which is how iOS works.
2214
2338
  // TODO(diedra): Fix the bug that is causing Android to require a two finger tap
2215
2339
  // to the open the keyboard, and then remove the second half of this label.
2216
- const ariaLabel = mathQuillStrings.mathInputBox + " " + i18n._("Tap with one or two fingers to open keyboard");
2340
+ const ariaLabel = this.context.strings.mathInputBox + " " + this.context.strings.fingerTap;
2217
2341
  return /*#__PURE__*/React.createElement(KeypadContext.Consumer, null, ({
2218
2342
  keypadActive,
2219
2343
  setKeypadActive
@@ -2255,10 +2379,12 @@ class MathInput extends React.Component {
2255
2379
  }))));
2256
2380
  }
2257
2381
  }
2382
+ MathInput.contextType = MathInputI18nContext;
2258
2383
  MathInput.defaultProps = {
2259
2384
  style: {},
2260
2385
  value: ""
2261
2386
  };
2387
+ MathInput.contextType = MathInputI18nContext;
2262
2388
  const fontSizePt = 18;
2263
2389
  const inputMaxWidth = 128;
2264
2390
 
@@ -2549,6 +2675,10 @@ function Tabbar(props) {
2549
2675
  })));
2550
2676
  }
2551
2677
 
2678
+ /**
2679
+ * This file contains configuration settings for the buttons in the keypad.
2680
+ */
2681
+
2552
2682
  const getDefaultOperatorFields = ({
2553
2683
  key,
2554
2684
  keyType: _keyType = "OPERATOR",
@@ -2588,38 +2718,32 @@ const getDefaultNumberFields = ({
2588
2718
  data: _data3
2589
2719
  }
2590
2720
  });
2591
- const KeyConfigs = {
2721
+ const KeyConfigs = strings => ({
2592
2722
  // Basic math
2593
2723
  PLUS: _extends({}, getDefaultOperatorFields({
2594
2724
  key: "PLUS",
2595
- // I18N: A label for a 'plus' sign.
2596
- ariaLabel: i18n._("Plus")
2725
+ ariaLabel: strings.plus
2597
2726
  })),
2598
2727
  MINUS: _extends({}, getDefaultOperatorFields({
2599
2728
  key: "MINUS",
2600
- // I18N: A label for a 'minus' sign.
2601
- ariaLabel: i18n._("Minus")
2729
+ ariaLabel: strings.minus
2602
2730
  })),
2603
2731
  NEGATIVE: _extends({}, getDefaultOperatorFields({
2604
2732
  key: "NEGATIVE",
2605
- // I18N: A label for a 'negative' sign.
2606
- ariaLabel: i18n._("Negative")
2733
+ ariaLabel: strings.negative
2607
2734
  })),
2608
2735
  TIMES: _extends({}, getDefaultOperatorFields({
2609
2736
  key: "TIMES",
2610
- // I18N: A label for a 'multiply' sign.
2611
- ariaLabel: i18n._("Multiply")
2737
+ ariaLabel: strings.times
2612
2738
  })),
2613
2739
  DIVIDE: _extends({}, getDefaultOperatorFields({
2614
2740
  key: "DIVIDE",
2615
- // I18N: A label for a 'divide' sign.
2616
- ariaLabel: i18n._("Divide")
2741
+ ariaLabel: strings.divide
2617
2742
  })),
2618
2743
  DECIMAL: _extends({}, getDefaultOperatorFields({
2619
2744
  key: "DECIMAL",
2620
2745
  keyType: "VALUE",
2621
- // I18N: A label for a 'decimal' sign (represented as '.' or ',').
2622
- ariaLabel: i18n._("Decimal")
2746
+ ariaLabel: strings.decimal
2623
2747
  })),
2624
2748
  PERIOD: _extends({}, getDefaultOperatorFields({
2625
2749
  key: "PERIOD",
@@ -2628,162 +2752,116 @@ const KeyConfigs = {
2628
2752
  })),
2629
2753
  PERCENT: _extends({}, getDefaultOperatorFields({
2630
2754
  key: "PERCENT",
2631
- // I18N: A label for a 'percent' sign (represented as '%').
2632
- ariaLabel: i18n._("Percent")
2755
+ ariaLabel: strings.percent
2633
2756
  })),
2634
2757
  CDOT: _extends({}, getDefaultOperatorFields({
2635
2758
  key: "CDOT",
2636
- // I18N: A label for a 'centered dot' multiplication sign (represented as '⋅').
2637
- ariaLabel: i18n._("Multiply")
2759
+ ariaLabel: strings.cdot
2638
2760
  })),
2639
2761
  EQUAL: _extends({}, getDefaultOperatorFields({
2640
2762
  key: "EQUAL",
2641
- // I18N: A label for an 'equals' sign (represented as '=').
2642
- ariaLabel: i18n._("Equals sign")
2763
+ ariaLabel: strings.equalsSign
2643
2764
  })),
2644
2765
  NEQ: _extends({}, getDefaultOperatorFields({
2645
2766
  key: "NEQ",
2646
- // I18N: A label for a 'not-equals' sign (represented as '≠').
2647
- ariaLabel: i18n._("Not-equals sign")
2767
+ ariaLabel: strings.notEqualsSign
2648
2768
  })),
2649
2769
  GT: _extends({}, getDefaultOperatorFields({
2650
2770
  key: "GT",
2651
- // I18N: A label for a 'greater than' sign (represented as '>').
2652
- ariaLabel: i18n._("Greater than sign")
2771
+ ariaLabel: strings.greaterThanSign
2653
2772
  })),
2654
2773
  LT: _extends({}, getDefaultOperatorFields({
2655
2774
  key: "LT",
2656
- // I18N: A label for a 'less than' sign (represented as '<').
2657
- ariaLabel: i18n._("Less than sign")
2775
+ ariaLabel: strings.lessThanSign
2658
2776
  })),
2659
2777
  GEQ: _extends({}, getDefaultOperatorFields({
2660
2778
  key: "GEQ",
2661
- // I18N: A label for a 'greater than or equal to' sign (represented as '≥').
2662
- ariaLabel: i18n._("Greater than or equal to sign")
2779
+ ariaLabel: strings.greaterThanOrEqualToSign
2663
2780
  })),
2664
2781
  LEQ: _extends({}, getDefaultOperatorFields({
2665
2782
  key: "LEQ",
2666
- // I18N: A label for a 'less than or equal to' sign (represented as '≤').
2667
- ariaLabel: i18n._("Less than or equal to sign")
2783
+ ariaLabel: strings.lessThanOrEqualSign
2668
2784
  })),
2669
2785
  // mobile native
2670
2786
  FRAC_INCLUSIVE: _extends({}, getDefaultOperatorFields({
2671
2787
  key: "FRAC_INCLUSIVE",
2672
- // I18N: A label for a button that creates a new fraction and puts the
2673
- // current expression in the numerator of that fraction.
2674
- ariaLabel: i18n._("Fraction, with current expression in numerator")
2788
+ ariaLabel: strings.fractionExpressionInNumerator
2675
2789
  })),
2676
2790
  // mobile native
2677
2791
  FRAC_EXCLUSIVE: _extends({}, getDefaultOperatorFields({
2678
2792
  key: "FRAC_EXCLUSIVE",
2679
- // I18N: A label for a button that creates a new fraction next to the
2680
- // cursor.
2681
- ariaLabel: i18n._("Fraction, excluding the current expression")
2793
+ ariaLabel: strings.fractionExcludingExpression
2682
2794
  })),
2683
2795
  // mobile web
2684
2796
  FRAC: _extends({}, getDefaultOperatorFields({
2685
2797
  key: "FRAC",
2686
- // I18N: A label for a button that creates a new fraction next to the
2687
- // cursor.
2688
- ariaLabel: i18n._("Fraction, excluding the current expression")
2798
+ ariaLabel: strings.fractionExcludingExpression
2689
2799
  })),
2690
2800
  EXP: _extends({}, getDefaultOperatorFields({
2691
2801
  key: "EXP",
2692
- // I18N: A label for a button that will allow the user to input a
2693
- // custom exponent.
2694
- ariaLabel: i18n._("Custom exponent")
2802
+ ariaLabel: strings.customExponent
2695
2803
  })),
2696
2804
  EXP_2: _extends({}, getDefaultOperatorFields({
2697
2805
  key: "EXP_2",
2698
- // I18N: A label for a button that will square (take to the second
2699
- // power) some math.
2700
- ariaLabel: i18n._("Square")
2806
+ ariaLabel: strings.square
2701
2807
  })),
2702
2808
  EXP_3: _extends({}, getDefaultOperatorFields({
2703
2809
  key: "EXP_3",
2704
- // I18N: A label for a button that will cube (take to the third power)
2705
- // some math.
2706
- ariaLabel: i18n._("Cube")
2810
+ ariaLabel: strings.cube
2707
2811
  })),
2708
2812
  SQRT: _extends({}, getDefaultOperatorFields({
2709
2813
  key: "SQRT",
2710
- // I18N: A label for a button that will allow the user to input a
2711
- // square root.
2712
- ariaLabel: i18n._("Square root")
2814
+ ariaLabel: strings.squareRoot
2713
2815
  })),
2714
2816
  CUBE_ROOT: _extends({}, getDefaultOperatorFields({
2715
2817
  key: "CUBE_ROOT",
2716
- // I18N: A label for a button that will allow the user to input a
2717
- // cube root.
2718
- ariaLabel: i18n._("Cube root")
2818
+ ariaLabel: strings.cubeRoot
2719
2819
  })),
2720
2820
  RADICAL: _extends({}, getDefaultOperatorFields({
2721
2821
  key: "RADICAL",
2722
- // I18N: A label for a button that will allow the user to input a
2723
- // radical with a custom root.
2724
- ariaLabel: i18n._("Radical with custom root")
2822
+ ariaLabel: strings.radicalWithCustomRoot
2725
2823
  })),
2726
2824
  LEFT_PAREN: _extends({}, getDefaultOperatorFields({
2727
2825
  key: "LEFT_PAREN",
2728
- // I18N: A label for a button that will allow the user to input a
2729
- // left parenthesis (i.e. '(')
2730
- ariaLabel: i18n._("Left parenthesis")
2826
+ ariaLabel: strings.leftParenthesis
2731
2827
  })),
2732
2828
  RIGHT_PAREN: _extends({}, getDefaultOperatorFields({
2733
2829
  key: "RIGHT_PAREN",
2734
- // I18N: A label for a button that will allow the user to input a
2735
- // right parenthesis (i.e. ')')
2736
- ariaLabel: i18n._("Right parenthesis")
2830
+ ariaLabel: strings.rightParenthesis
2737
2831
  })),
2738
2832
  LN: _extends({}, getDefaultOperatorFields({
2739
2833
  key: "LN",
2740
- // I18N: A label for a button that will allow the user to input a
2741
- // natural logarithm.
2742
- ariaLabel: i18n._("Natural logarithm")
2834
+ ariaLabel: strings.naturalLog
2743
2835
  })),
2744
2836
  LOG: _extends({}, getDefaultOperatorFields({
2745
2837
  key: "LOG",
2746
- // I18N: A label for a button that will allow the user to input a
2747
- // logarithm with base 10.
2748
- ariaLabel: i18n._("Logarithm with base 10")
2838
+ ariaLabel: strings.logBase10
2749
2839
  })),
2750
2840
  LOG_N: _extends({}, getDefaultOperatorFields({
2751
2841
  key: "LOG_N",
2752
- // I18N: A label for a button that will allow the user to input a
2753
- // logarithm with a custom base.
2754
- ariaLabel: i18n._("Logarithm with custom base")
2842
+ ariaLabel: strings.logCustomBase
2755
2843
  })),
2756
2844
  SIN: _extends({}, getDefaultOperatorFields({
2757
2845
  key: "SIN",
2758
- // I18N: A label for a button that will allow the user to input a
2759
- // sine function.
2760
- ariaLabel: i18n._("Sine")
2846
+ ariaLabel: strings.sine
2761
2847
  })),
2762
2848
  COS: _extends({}, getDefaultOperatorFields({
2763
2849
  key: "COS",
2764
- // I18N: A label for a button that will allow the user to input a
2765
- // cosine function.
2766
- ariaLabel: i18n._("Cosine")
2850
+ ariaLabel: strings.cosine
2767
2851
  })),
2768
2852
  TAN: _extends({}, getDefaultOperatorFields({
2769
2853
  key: "TAN",
2770
- // I18N: A label for a button that will allow the user to input a
2771
- // tangent function.
2772
- ariaLabel: i18n._("Tangent")
2854
+ ariaLabel: strings.tangent
2773
2855
  })),
2774
2856
  PI: _extends({}, getDefaultValueFields({
2775
2857
  key: "PI",
2776
2858
  data: "\\pi",
2777
- // I18N: A label for a button that will allow the user to input the
2778
- // mathematical constant pi (i.e., π)
2779
- ariaLabel: i18n._("Pi")
2859
+ ariaLabel: strings.pi
2780
2860
  })),
2781
2861
  THETA: _extends({}, getDefaultValueFields({
2782
2862
  key: "THETA",
2783
2863
  data: "\\theta",
2784
- // I18N: A label for a button that will allow the user to input the
2785
- // mathematical constant theta (i.e., θ)
2786
- ariaLabel: i18n._("Theta")
2864
+ ariaLabel: strings.theta
2787
2865
  })),
2788
2866
  NOOP: _extends({}, getDefaultOperatorFields({
2789
2867
  key: "NOOP",
@@ -2793,64 +2871,63 @@ const KeyConfigs = {
2793
2871
  UP: _extends({}, getDefaultOperatorFields({
2794
2872
  key: "UP",
2795
2873
  keyType: "INPUT_NAVIGATION",
2796
- ariaLabel: i18n._("Up arrow")
2874
+ ariaLabel: strings.upArrow
2797
2875
  })),
2798
2876
  RIGHT: _extends({}, getDefaultOperatorFields({
2799
2877
  key: "RIGHT",
2800
2878
  keyType: "INPUT_NAVIGATION",
2801
- ariaLabel: i18n._("Right arrow")
2879
+ ariaLabel: strings.rightArrow
2802
2880
  })),
2803
2881
  DOWN: _extends({}, getDefaultOperatorFields({
2804
2882
  key: "DOWN",
2805
2883
  keyType: "INPUT_NAVIGATION",
2806
- ariaLabel: i18n._("Down arrow")
2884
+ ariaLabel: strings.downArrow
2807
2885
  })),
2808
2886
  LEFT: _extends({}, getDefaultOperatorFields({
2809
2887
  key: "LEFT",
2810
2888
  keyType: "INPUT_NAVIGATION",
2811
- ariaLabel: i18n._("Left arrow")
2889
+ ariaLabel: strings.leftArrow
2812
2890
  })),
2813
2891
  JUMP_OUT_PARENTHESES: _extends({}, getDefaultOperatorFields({
2814
2892
  key: "JUMP_OUT_PARENTHESES",
2815
2893
  keyType: "INPUT_NAVIGATION",
2816
- ariaLabel: i18n._("Navigate right out of a set of parentheses")
2894
+ ariaLabel: strings.navOutOfParentheses
2817
2895
  })),
2818
2896
  JUMP_OUT_EXPONENT: _extends({}, getDefaultOperatorFields({
2819
2897
  key: "JUMP_OUT_EXPONENT",
2820
2898
  keyType: "INPUT_NAVIGATION",
2821
- ariaLabel: i18n._("Navigate right out of an exponent")
2899
+ ariaLabel: strings.navOutOfExponent
2822
2900
  })),
2823
2901
  JUMP_OUT_BASE: _extends({}, getDefaultOperatorFields({
2824
2902
  key: "JUMP_OUT_BASE",
2825
2903
  keyType: "INPUT_NAVIGATION",
2826
- ariaLabel: i18n._("Navigate right out of a base")
2904
+ ariaLabel: strings.navOutOfBase
2827
2905
  })),
2828
2906
  JUMP_INTO_NUMERATOR: _extends({}, getDefaultOperatorFields({
2829
2907
  key: "JUMP_INTO_NUMERATOR",
2830
2908
  keyType: "INPUT_NAVIGATION",
2831
- ariaLabel: i18n._("Navigate right into the numerator of a fraction")
2909
+ ariaLabel: strings.navIntoNumerator
2832
2910
  })),
2833
2911
  JUMP_OUT_NUMERATOR: _extends({}, getDefaultOperatorFields({
2834
2912
  key: "JUMP_OUT_NUMERATOR",
2835
2913
  keyType: "INPUT_NAVIGATION",
2836
- ariaLabel: i18n._("Navigate right out of the numerator and into the denominator")
2914
+ ariaLabel: strings.navOutOfNumeratorIntoDenominator
2837
2915
  })),
2838
2916
  JUMP_OUT_DENOMINATOR: _extends({}, getDefaultOperatorFields({
2839
2917
  key: "JUMP_OUT_DENOMINATOR",
2840
2918
  keyType: "INPUT_NAVIGATION",
2841
- ariaLabel: i18n._("Navigate right out of the denominator of a fraction")
2919
+ ariaLabel: strings.navOutOfDenominator
2842
2920
  })),
2843
2921
  BACKSPACE: _extends({}, getDefaultOperatorFields({
2844
2922
  key: "BACKSPACE",
2845
2923
  keyType: "INPUT_NAVIGATION",
2846
- ariaLabel: i18n._("Delete")
2924
+ ariaLabel: strings.delete
2847
2925
  })),
2848
2926
  // Keypad navigation
2849
2927
  DISMISS: _extends({}, getDefaultOperatorFields({
2850
2928
  key: "DISMISS",
2851
2929
  keyType: "KEYPAD_NAVIGATION",
2852
- // I18N: A label for a button that will dismiss/hide a keypad.
2853
- ariaLabel: i18n._("Dismiss")
2930
+ ariaLabel: strings.dismiss
2854
2931
  })),
2855
2932
  // TODO(charlie): Use the numeral color for the 'Many' key.
2856
2933
  MANY: _extends({}, getDefaultOperatorFields({
@@ -3057,7 +3134,7 @@ const KeyConfigs = {
3057
3134
  LOG_B: _extends({}, getDefaultValueFields({
3058
3135
  key: "LOG_B"
3059
3136
  }))
3060
- };
3137
+ });
3061
3138
 
3062
3139
  /*
3063
3140
  The SVGs in this file should be treated as binary assets. If, in the future,
@@ -3074,6 +3151,9 @@ no copying and pasting is necessary.
3074
3151
  function ButtonAsset({
3075
3152
  id
3076
3153
  }) {
3154
+ const {
3155
+ locale
3156
+ } = useMathInputI18n();
3077
3157
  switch (id) {
3078
3158
  case "NUM_0":
3079
3159
  return /*#__PURE__*/React.createElement("svg", {
@@ -3189,7 +3269,7 @@ function ButtonAsset({
3189
3269
  case "PERIOD":
3190
3270
  // Different locales use different symbols for the decimal separator
3191
3271
  // (, vs .)
3192
- if (id === "DECIMAL" && decimalSeparator === DecimalSeparator.COMMA) {
3272
+ if (id === "DECIMAL" && getDecimalSeparator(locale) === DecimalSeparator.COMMA) {
3193
3273
  // comma decimal separator
3194
3274
  return /*#__PURE__*/React.createElement("svg", {
3195
3275
  width: "40",
@@ -4602,13 +4682,17 @@ function ExtrasPage(props) {
4602
4682
  extraKeys,
4603
4683
  onClickKey
4604
4684
  } = props;
4685
+ const {
4686
+ strings
4687
+ } = useMathInputI18n();
4688
+ const Keys = KeyConfigs(strings);
4605
4689
  return /*#__PURE__*/React.createElement(React.Fragment, null, extraKeys.map((key, i) => {
4606
4690
  // Map 1D array to Cartesian coordinates
4607
4691
  const coordX = i % columns;
4608
4692
  const coordY = i / columns;
4609
4693
  return /*#__PURE__*/React.createElement(KeypadButton, {
4610
4694
  key: key,
4611
- keyConfig: KeyConfigs[key],
4695
+ keyConfig: Keys[key],
4612
4696
  onClickKey: onClickKey,
4613
4697
  coord: [coordX, coordY]
4614
4698
  });
@@ -4622,7 +4706,7 @@ const expandedViewThreshold = 500;
4622
4706
  // This is a helper function that returns the correct context for the cursor
4623
4707
  // based on the cursorContext prop. It is used in the keypad to determine
4624
4708
  // which key to render as the "jump out" key.
4625
- function getCursorContextConfig(cursorContext) {
4709
+ function getCursorContextConfig(strings, cursorContext) {
4626
4710
  if (!cursorContext) {
4627
4711
  return null;
4628
4712
  }
@@ -4630,17 +4714,17 @@ function getCursorContextConfig(cursorContext) {
4630
4714
  case CursorContext.NONE:
4631
4715
  return null;
4632
4716
  case CursorContext.IN_PARENS:
4633
- return KeyConfigs.JUMP_OUT_PARENTHESES;
4717
+ return KeyConfigs(strings).JUMP_OUT_PARENTHESES;
4634
4718
  case CursorContext.IN_SUPER_SCRIPT:
4635
- return KeyConfigs.JUMP_OUT_EXPONENT;
4719
+ return KeyConfigs(strings).JUMP_OUT_EXPONENT;
4636
4720
  case CursorContext.IN_SUB_SCRIPT:
4637
- return KeyConfigs.JUMP_OUT_BASE;
4721
+ return KeyConfigs(strings).JUMP_OUT_BASE;
4638
4722
  case CursorContext.IN_NUMERATOR:
4639
- return KeyConfigs.JUMP_OUT_NUMERATOR;
4723
+ return KeyConfigs(strings).JUMP_OUT_NUMERATOR;
4640
4724
  case CursorContext.IN_DENOMINATOR:
4641
- return KeyConfigs.JUMP_OUT_DENOMINATOR;
4725
+ return KeyConfigs(strings).JUMP_OUT_DENOMINATOR;
4642
4726
  case CursorContext.BEFORE_FRACTION:
4643
- return KeyConfigs.JUMP_INTO_NUMERATOR;
4727
+ return KeyConfigs(strings).JUMP_INTO_NUMERATOR;
4644
4728
  }
4645
4729
  }
4646
4730
 
@@ -4649,70 +4733,74 @@ function FractionsPage(props) {
4649
4733
  onClickKey,
4650
4734
  cursorContext
4651
4735
  } = props;
4652
- const cursorKeyConfig = getCursorContextConfig(cursorContext);
4736
+ const {
4737
+ strings
4738
+ } = useMathInputI18n();
4739
+ const cursorKeyConfig = getCursorContextConfig(strings, cursorContext);
4653
4740
  // These keys are arranged sequentially so that tabbing follows numerical order. This
4654
4741
  // allows us to visually mimic a keypad without affecting a11y. The visual order of the
4655
4742
  // keys in the keypad is determined by their coordinates, not their order in the DOM.
4743
+ const Keys = KeyConfigs(strings);
4656
4744
  return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(KeypadButton, {
4657
- keyConfig: KeyConfigs.NUM_1,
4745
+ keyConfig: Keys.NUM_1,
4658
4746
  onClickKey: onClickKey,
4659
4747
  coord: [0, 2]
4660
4748
  }), /*#__PURE__*/React.createElement(KeypadButton, {
4661
- keyConfig: KeyConfigs.NUM_2,
4749
+ keyConfig: Keys.NUM_2,
4662
4750
  onClickKey: onClickKey,
4663
4751
  coord: [1, 2]
4664
4752
  }), /*#__PURE__*/React.createElement(KeypadButton, {
4665
- keyConfig: KeyConfigs.NUM_3,
4753
+ keyConfig: Keys.NUM_3,
4666
4754
  onClickKey: onClickKey,
4667
4755
  coord: [2, 2]
4668
4756
  }), /*#__PURE__*/React.createElement(KeypadButton, {
4669
- keyConfig: KeyConfigs.NUM_4,
4757
+ keyConfig: Keys.NUM_4,
4670
4758
  onClickKey: onClickKey,
4671
4759
  coord: [0, 1]
4672
4760
  }), /*#__PURE__*/React.createElement(KeypadButton, {
4673
- keyConfig: KeyConfigs.NUM_5,
4761
+ keyConfig: Keys.NUM_5,
4674
4762
  onClickKey: onClickKey,
4675
4763
  coord: [1, 1]
4676
4764
  }), /*#__PURE__*/React.createElement(KeypadButton, {
4677
- keyConfig: KeyConfigs.NUM_6,
4765
+ keyConfig: Keys.NUM_6,
4678
4766
  onClickKey: onClickKey,
4679
4767
  coord: [2, 1]
4680
4768
  }), /*#__PURE__*/React.createElement(KeypadButton, {
4681
- keyConfig: KeyConfigs.NUM_7,
4769
+ keyConfig: Keys.NUM_7,
4682
4770
  onClickKey: onClickKey,
4683
4771
  coord: [0, 0]
4684
4772
  }), /*#__PURE__*/React.createElement(KeypadButton, {
4685
- keyConfig: KeyConfigs.NUM_8,
4773
+ keyConfig: Keys.NUM_8,
4686
4774
  onClickKey: onClickKey,
4687
4775
  coord: [1, 0]
4688
4776
  }), /*#__PURE__*/React.createElement(KeypadButton, {
4689
- keyConfig: KeyConfigs.NUM_9,
4777
+ keyConfig: Keys.NUM_9,
4690
4778
  onClickKey: onClickKey,
4691
4779
  coord: [2, 0]
4692
4780
  }), /*#__PURE__*/React.createElement(KeypadButton, {
4693
- keyConfig: KeyConfigs.NUM_0,
4781
+ keyConfig: Keys.NUM_0,
4694
4782
  onClickKey: onClickKey,
4695
4783
  coord: [0, 3]
4696
4784
  }), /*#__PURE__*/React.createElement(KeypadButton, {
4697
- keyConfig: KeyConfigs.DECIMAL,
4785
+ keyConfig: Keys.DECIMAL,
4698
4786
  onClickKey: onClickKey,
4699
4787
  coord: [1, 3]
4700
4788
  }), /*#__PURE__*/React.createElement(KeypadButton, {
4701
- keyConfig: KeyConfigs.NEGATIVE,
4789
+ keyConfig: Keys.NEGATIVE,
4702
4790
  onClickKey: onClickKey,
4703
4791
  coord: [2, 3]
4704
4792
  }), /*#__PURE__*/React.createElement(KeypadButton, {
4705
- keyConfig: KeyConfigs.PERCENT,
4793
+ keyConfig: Keys.PERCENT,
4706
4794
  onClickKey: onClickKey,
4707
4795
  coord: [3, 0],
4708
4796
  secondary: true
4709
4797
  }), /*#__PURE__*/React.createElement(KeypadButton, {
4710
- keyConfig: KeyConfigs.PI,
4798
+ keyConfig: Keys.PI,
4711
4799
  onClickKey: onClickKey,
4712
4800
  coord: [3, 1],
4713
4801
  secondary: true
4714
4802
  }), /*#__PURE__*/React.createElement(KeypadButton, {
4715
- keyConfig: KeyConfigs.FRAC,
4803
+ keyConfig: Keys.FRAC,
4716
4804
  onClickKey: onClickKey,
4717
4805
  coord: [3, 2],
4718
4806
  secondary: true
@@ -4722,7 +4810,7 @@ function FractionsPage(props) {
4722
4810
  coord: [3, 3],
4723
4811
  secondary: true
4724
4812
  }), /*#__PURE__*/React.createElement(KeypadButton, {
4725
- keyConfig: KeyConfigs.BACKSPACE,
4813
+ keyConfig: Keys.BACKSPACE,
4726
4814
  onClickKey: onClickKey,
4727
4815
  coord: [4, 3],
4728
4816
  action: true
@@ -4733,16 +4821,20 @@ function GeometryPage(props) {
4733
4821
  const {
4734
4822
  onClickKey
4735
4823
  } = props;
4824
+ const {
4825
+ strings
4826
+ } = useMathInputI18n();
4827
+ const Keys = KeyConfigs(strings);
4736
4828
  return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(KeypadButton, {
4737
- keyConfig: KeyConfigs.SIN,
4829
+ keyConfig: Keys.SIN,
4738
4830
  onClickKey: onClickKey,
4739
4831
  coord: [0, 0]
4740
4832
  }), /*#__PURE__*/React.createElement(KeypadButton, {
4741
- keyConfig: KeyConfigs.COS,
4833
+ keyConfig: Keys.COS,
4742
4834
  onClickKey: onClickKey,
4743
4835
  coord: [1, 0]
4744
4836
  }), /*#__PURE__*/React.createElement(KeypadButton, {
4745
- keyConfig: KeyConfigs.TAN,
4837
+ keyConfig: Keys.TAN,
4746
4838
  onClickKey: onClickKey,
4747
4839
  coord: [2, 0]
4748
4840
  }));
@@ -4752,59 +4844,63 @@ function NumbersPage(props) {
4752
4844
  const {
4753
4845
  onClickKey
4754
4846
  } = props;
4847
+ const {
4848
+ strings
4849
+ } = useMathInputI18n();
4850
+ const Keys = KeyConfigs(strings);
4755
4851
  // These keys are arranged sequentially so that tabbing follows numerical order. This
4756
4852
  // allows us to visually mimic a keypad without affecting a11y. The visual order of the
4757
4853
  // keys in the keypad is determined by their coordinates, not their order in the DOM.
4758
4854
  return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(KeypadButton, {
4759
- keyConfig: KeyConfigs.NUM_1,
4855
+ keyConfig: Keys.NUM_1,
4760
4856
  onClickKey: onClickKey,
4761
4857
  coord: [0, 2]
4762
4858
  }), /*#__PURE__*/React.createElement(KeypadButton, {
4763
- keyConfig: KeyConfigs.NUM_2,
4859
+ keyConfig: Keys.NUM_2,
4764
4860
  onClickKey: onClickKey,
4765
4861
  coord: [1, 2]
4766
4862
  }), /*#__PURE__*/React.createElement(KeypadButton, {
4767
- keyConfig: KeyConfigs.NUM_3,
4863
+ keyConfig: Keys.NUM_3,
4768
4864
  onClickKey: onClickKey,
4769
4865
  coord: [2, 2]
4770
4866
  }), /*#__PURE__*/React.createElement(KeypadButton, {
4771
- keyConfig: KeyConfigs.NUM_4,
4867
+ keyConfig: Keys.NUM_4,
4772
4868
  onClickKey: onClickKey,
4773
4869
  coord: [0, 1]
4774
4870
  }), /*#__PURE__*/React.createElement(KeypadButton, {
4775
- keyConfig: KeyConfigs.NUM_5,
4871
+ keyConfig: Keys.NUM_5,
4776
4872
  onClickKey: onClickKey,
4777
4873
  coord: [1, 1]
4778
4874
  }), /*#__PURE__*/React.createElement(KeypadButton, {
4779
- keyConfig: KeyConfigs.NUM_6,
4875
+ keyConfig: Keys.NUM_6,
4780
4876
  onClickKey: onClickKey,
4781
4877
  coord: [2, 1]
4782
4878
  }), /*#__PURE__*/React.createElement(KeypadButton, {
4783
- keyConfig: KeyConfigs.NUM_7,
4879
+ keyConfig: Keys.NUM_7,
4784
4880
  onClickKey: onClickKey,
4785
4881
  coord: [0, 0]
4786
4882
  }), /*#__PURE__*/React.createElement(KeypadButton, {
4787
- keyConfig: KeyConfigs.NUM_8,
4883
+ keyConfig: Keys.NUM_8,
4788
4884
  onClickKey: onClickKey,
4789
4885
  coord: [1, 0]
4790
4886
  }), /*#__PURE__*/React.createElement(KeypadButton, {
4791
- keyConfig: KeyConfigs.NUM_9,
4887
+ keyConfig: Keys.NUM_9,
4792
4888
  onClickKey: onClickKey,
4793
4889
  coord: [2, 0]
4794
4890
  }), /*#__PURE__*/React.createElement(KeypadButton, {
4795
- keyConfig: KeyConfigs.NUM_0,
4891
+ keyConfig: Keys.NUM_0,
4796
4892
  onClickKey: onClickKey,
4797
4893
  coord: [0, 3]
4798
4894
  }), /*#__PURE__*/React.createElement(KeypadButton, {
4799
- keyConfig: KeyConfigs.DECIMAL,
4895
+ keyConfig: Keys.DECIMAL,
4800
4896
  onClickKey: onClickKey,
4801
4897
  coord: [1, 3]
4802
4898
  }), /*#__PURE__*/React.createElement(KeypadButton, {
4803
- keyConfig: KeyConfigs.NEGATIVE,
4899
+ keyConfig: Keys.NEGATIVE,
4804
4900
  onClickKey: onClickKey,
4805
4901
  coord: [2, 3]
4806
4902
  }), /*#__PURE__*/React.createElement(KeypadButton, {
4807
- keyConfig: KeyConfigs.PERCENT,
4903
+ keyConfig: Keys.PERCENT,
4808
4904
  onClickKey: onClickKey,
4809
4905
  coord: [3, 0],
4810
4906
  secondary: true
@@ -4819,56 +4915,60 @@ function OperatorsPage(props) {
4819
4915
  basicRelations,
4820
4916
  advancedRelations
4821
4917
  } = props;
4918
+ const {
4919
+ strings
4920
+ } = useMathInputI18n();
4921
+ const Keys = KeyConfigs(strings);
4822
4922
  return /*#__PURE__*/React.createElement(React.Fragment, null, preAlgebra && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(KeypadButton, {
4823
- keyConfig: KeyConfigs.EXP_2,
4923
+ keyConfig: Keys.EXP_2,
4824
4924
  onClickKey: onClickKey,
4825
4925
  coord: [0, 0]
4826
4926
  }), /*#__PURE__*/React.createElement(KeypadButton, {
4827
- keyConfig: KeyConfigs.EXP,
4927
+ keyConfig: Keys.EXP,
4828
4928
  onClickKey: onClickKey,
4829
4929
  coord: [1, 0]
4830
4930
  }), /*#__PURE__*/React.createElement(KeypadButton, {
4831
- keyConfig: KeyConfigs.SQRT,
4931
+ keyConfig: Keys.SQRT,
4832
4932
  onClickKey: onClickKey,
4833
4933
  coord: [2, 0]
4834
4934
  }), /*#__PURE__*/React.createElement(KeypadButton, {
4835
- keyConfig: KeyConfigs.RADICAL,
4935
+ keyConfig: Keys.RADICAL,
4836
4936
  onClickKey: onClickKey,
4837
4937
  coord: [3, 0]
4838
4938
  })), logarithms && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(KeypadButton, {
4839
- keyConfig: KeyConfigs.LOG,
4939
+ keyConfig: Keys.LOG,
4840
4940
  onClickKey: onClickKey,
4841
4941
  coord: [0, 1]
4842
4942
  }), /*#__PURE__*/React.createElement(KeypadButton, {
4843
- keyConfig: KeyConfigs.LOG_N,
4943
+ keyConfig: Keys.LOG_N,
4844
4944
  onClickKey: onClickKey,
4845
4945
  coord: [1, 1]
4846
4946
  }), /*#__PURE__*/React.createElement(KeypadButton, {
4847
- keyConfig: KeyConfigs.LN,
4947
+ keyConfig: Keys.LN,
4848
4948
  onClickKey: onClickKey,
4849
4949
  coord: [2, 1]
4850
4950
  })), basicRelations && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(KeypadButton, {
4851
- keyConfig: KeyConfigs.EQUAL,
4951
+ keyConfig: Keys.EQUAL,
4852
4952
  onClickKey: onClickKey,
4853
4953
  coord: [0, 2]
4854
4954
  }), /*#__PURE__*/React.createElement(KeypadButton, {
4855
- keyConfig: KeyConfigs.LT,
4955
+ keyConfig: Keys.LT,
4856
4956
  onClickKey: onClickKey,
4857
4957
  coord: [1, 2]
4858
4958
  }), /*#__PURE__*/React.createElement(KeypadButton, {
4859
- keyConfig: KeyConfigs.GT,
4959
+ keyConfig: Keys.GT,
4860
4960
  onClickKey: onClickKey,
4861
4961
  coord: [2, 2]
4862
4962
  })), advancedRelations && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(KeypadButton, {
4863
- keyConfig: KeyConfigs.NEQ,
4963
+ keyConfig: Keys.NEQ,
4864
4964
  onClickKey: onClickKey,
4865
4965
  coord: [0, 3]
4866
4966
  }), /*#__PURE__*/React.createElement(KeypadButton, {
4867
- keyConfig: KeyConfigs.LEQ,
4967
+ keyConfig: Keys.LEQ,
4868
4968
  onClickKey: onClickKey,
4869
4969
  coord: [1, 3]
4870
4970
  }), /*#__PURE__*/React.createElement(KeypadButton, {
4871
- keyConfig: KeyConfigs.GEQ,
4971
+ keyConfig: Keys.GEQ,
4872
4972
  onClickKey: onClickKey,
4873
4973
  coord: [2, 3]
4874
4974
  })));
@@ -4973,24 +5073,28 @@ function NavigationPad(props) {
4973
5073
  const {
4974
5074
  onClickKey
4975
5075
  } = props;
5076
+ const {
5077
+ strings
5078
+ } = useMathInputI18n();
5079
+ const Keys = KeyConfigs(strings);
4976
5080
  return /*#__PURE__*/React.createElement(View$1, {
4977
5081
  style: styles$2.container
4978
5082
  }, /*#__PURE__*/React.createElement(View$1, {
4979
5083
  style: styles$2.grid
4980
5084
  }, /*#__PURE__*/React.createElement(NavigationButton, {
4981
- keyConfig: KeyConfigs.UP,
5085
+ keyConfig: Keys.UP,
4982
5086
  onClickKey: onClickKey,
4983
5087
  coord: [1, 0]
4984
5088
  }), /*#__PURE__*/React.createElement(NavigationButton, {
4985
- keyConfig: KeyConfigs.RIGHT,
5089
+ keyConfig: Keys.RIGHT,
4986
5090
  onClickKey: onClickKey,
4987
5091
  coord: [2, 1]
4988
5092
  }), /*#__PURE__*/React.createElement(NavigationButton, {
4989
- keyConfig: KeyConfigs.DOWN,
5093
+ keyConfig: Keys.DOWN,
4990
5094
  onClickKey: onClickKey,
4991
5095
  coord: [1, 2]
4992
5096
  }), /*#__PURE__*/React.createElement(NavigationButton, {
4993
- keyConfig: KeyConfigs.LEFT,
5097
+ keyConfig: Keys.LEFT,
4994
5098
  onClickKey: onClickKey,
4995
5099
  coord: [0, 1]
4996
5100
  }), /*#__PURE__*/React.createElement(View$1, {
@@ -5026,42 +5130,47 @@ function SharedKeys(props) {
5026
5130
  convertDotToTimes,
5027
5131
  selectedPage
5028
5132
  } = props;
5029
- const cursorKeyConfig = getCursorContextConfig(cursorContext);
5133
+ const {
5134
+ strings,
5135
+ locale
5136
+ } = useMathInputI18n();
5137
+ const cursorKeyConfig = getCursorContextConfig(strings, cursorContext);
5138
+ const Keys = KeyConfigs(strings);
5030
5139
 
5031
5140
  // Fraction position depends on the page
5032
5141
  const fractionCoord = selectedPage === "Numbers" || selectedPage === "Operators" ? [3, 1] : [3, 0];
5033
5142
  return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(KeypadButton, {
5034
- keyConfig: KeyConfigs.FRAC,
5143
+ keyConfig: Keys.FRAC,
5035
5144
  onClickKey: onClickKey,
5036
5145
  coord: fractionCoord,
5037
5146
  secondary: true
5038
5147
  }), /*#__PURE__*/React.createElement(KeypadButton, {
5039
- keyConfig: KeyConfigs.PLUS,
5148
+ keyConfig: Keys.PLUS,
5040
5149
  onClickKey: onClickKey,
5041
5150
  coord: [4, 0],
5042
5151
  secondary: true
5043
5152
  }), /*#__PURE__*/React.createElement(KeypadButton, {
5044
- keyConfig: KeyConfigs.MINUS,
5153
+ keyConfig: Keys.MINUS,
5045
5154
  onClickKey: onClickKey,
5046
5155
  coord: [5, 0],
5047
5156
  secondary: true
5048
5157
  }), /*#__PURE__*/React.createElement(KeypadButton, {
5049
- keyConfig: convertDotToTimesByLocale(!!convertDotToTimes) ? KeyConfigs.TIMES : KeyConfigs.CDOT,
5158
+ keyConfig: convertDotToTimesByLocale(locale, !!convertDotToTimes) ? Keys.TIMES : Keys.CDOT,
5050
5159
  onClickKey: onClickKey,
5051
5160
  coord: [4, 1],
5052
5161
  secondary: true
5053
5162
  }), divisionKey && /*#__PURE__*/React.createElement(KeypadButton, {
5054
- keyConfig: KeyConfigs.DIVIDE,
5163
+ keyConfig: Keys.DIVIDE,
5055
5164
  onClickKey: onClickKey,
5056
5165
  coord: [5, 1],
5057
5166
  secondary: true
5058
5167
  }), /*#__PURE__*/React.createElement(KeypadButton, {
5059
- keyConfig: KeyConfigs.LEFT_PAREN,
5168
+ keyConfig: Keys.LEFT_PAREN,
5060
5169
  onClickKey: onClickKey,
5061
5170
  coord: [4, 2],
5062
5171
  secondary: true
5063
5172
  }), /*#__PURE__*/React.createElement(KeypadButton, {
5064
- keyConfig: KeyConfigs.RIGHT_PAREN,
5173
+ keyConfig: Keys.RIGHT_PAREN,
5065
5174
  onClickKey: onClickKey,
5066
5175
  coord: [5, 2],
5067
5176
  secondary: true
@@ -5071,7 +5180,7 @@ function SharedKeys(props) {
5071
5180
  coord: [4, 3],
5072
5181
  secondary: true
5073
5182
  }), /*#__PURE__*/React.createElement(KeypadButton, {
5074
- keyConfig: KeyConfigs.BACKSPACE,
5183
+ keyConfig: Keys.BACKSPACE,
5075
5184
  onClickKey: onClickKey,
5076
5185
  coord: [5, 3],
5077
5186
  action: true
@@ -5743,5 +5852,5 @@ let KeypadType = /*#__PURE__*/function (KeypadType) {
5743
5852
  return KeypadType;
5744
5853
  }({});
5745
5854
 
5746
- export { CursorContext, Keypad as DesktopKeypad, KeyArray, KeyConfigs, KeypadContext, MathInput as KeypadInput, KeypadType, MobileKeypad, StatefulKeypadContextProvider, convertDotToTimesByLocale, createMathField, getCursorContext, keyToMathquillMap as keyTranslator, keypadElementPropType, libVersion, mathQuillInstance };
5855
+ export { CursorContext, Keypad as DesktopKeypad, KeyArray, KeyConfigs, KeypadContext, MathInput as KeypadInput, KeypadType, MathInputI18nContext, MathInputI18nContextProvider, MobileKeypad, StatefulKeypadContextProvider, convertDotToTimesByLocale, createMathField, getCursorContext, getKeyTranslator, keypadElementPropType, libVersion, mathQuillInstance, useMathInputI18n };
5747
5856
  //# sourceMappingURL=index.js.map