@khanacademy/math-input 16.3.0 → 16.4.1

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/index.js CHANGED
@@ -48,7 +48,7 @@ var PropTypes__default = /*#__PURE__*/_interopDefaultLegacy(PropTypes);
48
48
 
49
49
  // This file is processed by a Rollup plugin (replace) to inject the production
50
50
  const libName = "@khanacademy/math-input";
51
- const libVersion = "16.3.0";
51
+ const libVersion = "16.4.1";
52
52
  perseusCore.addLibraryVersionToPerseusDebug(libName, libVersion);
53
53
 
54
54
  function _extends() {
@@ -131,6 +131,49 @@ class View extends React__namespace.Component {
131
131
  }
132
132
  }
133
133
 
134
+ /**
135
+ * KeypadContext provides a way to the Keypad and Perseus Renderers to
136
+ * communicate.
137
+ *
138
+ * The StatefulKeypadContextProvider wraps the application
139
+ * while KeypadContext.Consumer wraps things that need this state:
140
+ * - mobile keypad usages
141
+ * - Perseus Renderers (Server/Item/Article)
142
+ */
143
+ // @ts-expect-error - TS2322 - Type 'Context<{ setKeypadElement: (keypadElement: HTMLElement | null | undefined) => void; keypadElement: null; setRenderer: (renderer: RendererInterface | null | undefined) => void; renderer: null; setScrollableElement: (scrollableElement: HTMLElement | ... 1 more ... | undefined) => void; scrollableElement: null; }>' is not assignable to type 'Context<KeypadContext>'.
144
+ const KeypadContext = /*#__PURE__*/React__namespace.createContext({
145
+ setKeypadActive: keypadActive => {},
146
+ keypadActive: false,
147
+ setKeypadElement: keypadElement => {},
148
+ keypadElement: null,
149
+ setRenderer: renderer => {},
150
+ renderer: null,
151
+ setScrollableElement: scrollableElement => {},
152
+ scrollableElement: null
153
+ });
154
+ function StatefulKeypadContextProvider(props) {
155
+ // whether or not to display the keypad
156
+ const [keypadActive, setKeypadActive] = React.useState(false);
157
+ // used to communicate between the keypad and the Renderer
158
+ const [keypadElement, setKeypadElement] = React.useState();
159
+ // this is a KeypadContextRendererInterface from Perseus
160
+ const [renderer, setRenderer] = React.useState();
161
+ const [scrollableElement, setScrollableElement] = React.useState();
162
+ const memoizedValue = React.useMemo(() => ({
163
+ keypadActive,
164
+ setKeypadActive,
165
+ keypadElement,
166
+ setKeypadElement,
167
+ renderer,
168
+ setRenderer,
169
+ scrollableElement,
170
+ setScrollableElement
171
+ }), [keypadActive, setKeypadActive, keypadElement, setKeypadElement, renderer, setRenderer, scrollableElement, setScrollableElement]);
172
+ return /*#__PURE__*/React__namespace.createElement(KeypadContext.Provider, {
173
+ value: memoizedValue
174
+ }, props.children);
175
+ }
176
+
134
177
  /**
135
178
  * Common parameters used to style components.
136
179
  */
@@ -1546,6 +1589,7 @@ class MathInput extends React__namespace.Component {
1546
1589
  if (!this._container.contains(evt.target)) {
1547
1590
  if (this.props.keypadElement && this.props.keypadElement.getDOMNode()) {
1548
1591
  const [x, y] = [evt.clientX, evt.clientY];
1592
+
1549
1593
  // We only want to blur if the click is above the keypad,
1550
1594
  // to the left of the keypad, or to the right of the keypad.
1551
1595
  // The reasoning for not blurring for any clicks below the keypad is
@@ -1870,7 +1914,7 @@ class MathInput extends React__namespace.Component {
1870
1914
  context: this.mathField.contextForCursor()
1871
1915
  });
1872
1916
  };
1873
- handleTouchStart = e => {
1917
+ handleTouchStart = (e, keypadActive, setKeypadActive) => {
1874
1918
  e.stopPropagation();
1875
1919
 
1876
1920
  // Hide the cursor handle on touch start, if the handle itself isn't
@@ -1889,6 +1933,11 @@ class MathInput extends React__namespace.Component {
1889
1933
  this._insertCursorAtClosestNode(touch.clientX, touch.clientY);
1890
1934
  }
1891
1935
 
1936
+ // If we're already focused, but the keypad isn't active, activate it.
1937
+ if (this.state.focused && !keypadActive) {
1938
+ setKeypadActive(true);
1939
+ }
1940
+
1892
1941
  // Trigger a focus event, if we're not already focused.
1893
1942
  if (!this.state.focused) {
1894
1943
  this.focus();
@@ -1898,7 +1947,7 @@ class MathInput extends React__namespace.Component {
1898
1947
  // We want to allow the user to be able to focus the input via click
1899
1948
  // when using ChromeOS third-party browsers that use mobile user agents,
1900
1949
  // but don't actually simulate touch events.
1901
- handleClick = e => {
1950
+ handleClick = (e, keypadActive, setKeypadActive) => {
1902
1951
  e.stopPropagation();
1903
1952
 
1904
1953
  // Hide the cursor handle on click
@@ -1915,6 +1964,11 @@ class MathInput extends React__namespace.Component {
1915
1964
  this._insertCursorAtClosestNode(e.clientX, e.clientY);
1916
1965
  }
1917
1966
 
1967
+ // If we're already focused, but the keypad isn't active, activate it.
1968
+ if (this.state.focused && !keypadActive) {
1969
+ setKeypadActive(true);
1970
+ }
1971
+
1918
1972
  // Trigger a focus event, if we're not already focused.
1919
1973
  if (!this.state.focused) {
1920
1974
  this.focus();
@@ -2138,34 +2192,44 @@ class MathInput extends React__namespace.Component {
2138
2192
  // TODO(diedra): Fix the bug that is causing Android to require a two finger tap
2139
2193
  // to the open the keyboard, and then remove the second half of this label.
2140
2194
  const ariaLabel = i18n__namespace._("Math input box") + " " + i18n__namespace._("Tap with one or two fingers to open keyboard");
2141
- return /*#__PURE__*/React__namespace.createElement(View, {
2142
- style: styles$7.input,
2143
- onTouchStart: this.handleTouchStart,
2144
- onTouchMove: this.handleTouchMove,
2145
- onTouchEnd: this.handleTouchEnd,
2146
- onClick: this.handleClick,
2147
- role: "textbox",
2148
- ariaLabel: ariaLabel
2149
- }, /*#__PURE__*/React__namespace.createElement("div", {
2150
- className: "keypad-input"
2151
- // @ts-expect-error - TS2322 - Type 'string' is not assignable to type 'number | undefined'.
2152
- ,
2153
- tabIndex: "0",
2154
- ref: node => {
2155
- this.inputRef = node;
2156
- },
2157
- onKeyUp: this.handleKeyUp
2158
- }, /*#__PURE__*/React__namespace.createElement("div", {
2159
- ref: node => {
2160
- this._mathContainer = ReactDOM__default["default"].findDOMNode(node);
2161
- },
2162
- style: innerStyle
2163
- })), focused && handle.visible && /*#__PURE__*/React__namespace.createElement(CursorHandle, _extends({}, handle, {
2164
- onTouchStart: this.onCursorHandleTouchStart,
2165
- onTouchMove: this.onCursorHandleTouchMove,
2166
- onTouchEnd: this.onCursorHandleTouchEnd,
2167
- onTouchCancel: this.onCursorHandleTouchCancel
2168
- })));
2195
+ return /*#__PURE__*/React__namespace.createElement(KeypadContext.Consumer, null, _ref => {
2196
+ let {
2197
+ keypadActive,
2198
+ setKeypadActive
2199
+ } = _ref;
2200
+ return /*#__PURE__*/React__namespace.createElement(View, {
2201
+ style: styles$7.input,
2202
+ onTouchStart: e => {
2203
+ this.handleTouchStart(e, keypadActive, setKeypadActive);
2204
+ },
2205
+ onTouchMove: this.handleTouchMove,
2206
+ onTouchEnd: this.handleTouchEnd,
2207
+ onClick: e => {
2208
+ this.handleClick(e, keypadActive, setKeypadActive);
2209
+ },
2210
+ role: "textbox",
2211
+ ariaLabel: ariaLabel
2212
+ }, /*#__PURE__*/React__namespace.createElement("div", {
2213
+ className: "keypad-input"
2214
+ // @ts-expect-error - TS2322 - Type 'string' is not assignable to type 'number | undefined'.
2215
+ ,
2216
+ tabIndex: "0",
2217
+ ref: node => {
2218
+ this.inputRef = node;
2219
+ },
2220
+ onKeyUp: this.handleKeyUp
2221
+ }, /*#__PURE__*/React__namespace.createElement("div", {
2222
+ ref: node => {
2223
+ this._mathContainer = ReactDOM__default["default"].findDOMNode(node);
2224
+ },
2225
+ style: innerStyle
2226
+ })), focused && handle.visible && /*#__PURE__*/React__namespace.createElement(CursorHandle, _extends({}, handle, {
2227
+ onTouchStart: this.onCursorHandleTouchStart,
2228
+ onTouchMove: this.onCursorHandleTouchMove,
2229
+ onTouchEnd: this.onCursorHandleTouchEnd,
2230
+ onTouchCancel: this.onCursorHandleTouchCancel
2231
+ })));
2232
+ });
2169
2233
  }
2170
2234
  }
2171
2235
  const fontSizePt = 18;
@@ -5373,49 +5437,6 @@ const styles$1 = aphrodite.StyleSheet.create({
5373
5437
  }
5374
5438
  });
5375
5439
 
5376
- /**
5377
- * KeypadContext provides a way to the Keypad and Perseus Renderers to
5378
- * communicate.
5379
- *
5380
- * The StatefulKeypadContextProvider wraps the application
5381
- * while KeypadContext.Consumer wraps things that need this state:
5382
- * - mobile keypad usages
5383
- * - Perseus Renderers (Server/Item/Article)
5384
- */
5385
- // @ts-expect-error - TS2322 - Type 'Context<{ setKeypadElement: (keypadElement: HTMLElement | null | undefined) => void; keypadElement: null; setRenderer: (renderer: RendererInterface | null | undefined) => void; renderer: null; setScrollableElement: (scrollableElement: HTMLElement | ... 1 more ... | undefined) => void; scrollableElement: null; }>' is not assignable to type 'Context<KeypadContext>'.
5386
- const KeypadContext = /*#__PURE__*/React__namespace.createContext({
5387
- setKeypadActive: keypadActive => {},
5388
- keypadActive: false,
5389
- setKeypadElement: keypadElement => {},
5390
- keypadElement: null,
5391
- setRenderer: renderer => {},
5392
- renderer: null,
5393
- setScrollableElement: scrollableElement => {},
5394
- scrollableElement: null
5395
- });
5396
- function StatefulKeypadContextProvider(props) {
5397
- // whether or not to display the keypad
5398
- const [keypadActive, setKeypadActive] = React.useState(false);
5399
- // used to communicate between the keypad and the Renderer
5400
- const [keypadElement, setKeypadElement] = React.useState();
5401
- // this is a KeypadContextRendererInterface from Perseus
5402
- const [renderer, setRenderer] = React.useState();
5403
- const [scrollableElement, setScrollableElement] = React.useState();
5404
- const memoizedValue = React.useMemo(() => ({
5405
- keypadActive,
5406
- setKeypadActive,
5407
- keypadElement,
5408
- setKeypadElement,
5409
- renderer,
5410
- setRenderer,
5411
- scrollableElement,
5412
- setScrollableElement
5413
- }), [keypadActive, setKeypadActive, keypadElement, setKeypadElement, renderer, setRenderer, scrollableElement, setScrollableElement]);
5414
- return /*#__PURE__*/React__namespace.createElement(KeypadContext.Provider, {
5415
- value: memoizedValue
5416
- }, props.children);
5417
- }
5418
-
5419
5440
  function flatten(list) {
5420
5441
  const result = [];
5421
5442
  if (!list) {