@khanacademy/math-input 11.0.0 → 12.0.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/CHANGELOG.md CHANGED
@@ -1,5 +1,26 @@
1
1
  # @khanacademy/math-input
2
2
 
3
+ ## 12.0.1
4
+
5
+ ### Patch Changes
6
+
7
+ - a383823d: Bump @khanacademy/wonder-stuff-core to v1.5.1 (which adds needed support for `isTruthy` helper function)
8
+
9
+ ## 12.0.0
10
+
11
+ ### Major Changes
12
+
13
+ - fa5f463b: Added onAnalyticsEvent prop to the LegacyKeypad (aka ProvidedKeypad). You must now pass in this prop, which is a function, to handle analytics events originating from the legacy keypad.
14
+ - 6d8ede65: Added `onAnalyticsEvent` prop to MobileKeypad to pipe out Perseus analytics
15
+
16
+ ### Minor Changes
17
+
18
+ - fa1bb6b4: Implemented some focus management fixes and improved the full-math-input story.
19
+
20
+ ### Patch Changes
21
+
22
+ - 3afc0da2: Check for ResizeObserver before using it
23
+
3
24
  ## 11.0.0
4
25
 
5
26
  ### Major Changes
@@ -50,7 +50,7 @@ declare class MathInput extends React.Component<Props, State> {
50
50
  _updateCursorHandle: (arg1?: boolean) => void;
51
51
  _hideCursorHandle: () => void;
52
52
  _handleScroll: () => void;
53
- blur: () => void;
53
+ blur: (callPropsOnBlur: boolean) => void;
54
54
  focus: () => void;
55
55
  /**
56
56
  * Tries to determine which DOM node to place the cursor next to based on
@@ -2,6 +2,7 @@ import * as React from "react";
2
2
  import ReactDOM from "react-dom";
3
3
  import type Key from "../../data/keys";
4
4
  import type { Cursor, KeypadConfiguration, KeyHandler, KeypadAPI } from "../../types";
5
+ import type { AnalyticsEventHandlerFn } from "@khanacademy/perseus-core";
5
6
  import type { StyleType } from "@khanacademy/wonder-blocks-core";
6
7
  /**
7
8
  * This is the v2 equivalent of v1's ProvidedKeypad. It follows the same
@@ -17,6 +18,7 @@ type Props = {
17
18
  onElementMounted?: (arg1: any) => void;
18
19
  onDismiss?: () => void;
19
20
  style?: StyleType;
21
+ onAnalyticsEvent: AnalyticsEventHandlerFn;
20
22
  };
21
23
  type State = {
22
24
  active: boolean;
@@ -1,11 +1,13 @@
1
1
  import * as React from "react";
2
2
  import ReactDOM from "react-dom";
3
3
  import type { Cursor, KeypadConfiguration, KeyHandler, KeypadAPI } from "../../types";
4
+ import type { AnalyticsEventHandlerFn } from "@khanacademy/perseus-core";
4
5
  import type { StyleType } from "@khanacademy/wonder-blocks-core";
5
6
  type Props = {
6
7
  onElementMounted?: (arg1: any) => void;
7
8
  onDismiss?: () => void;
8
9
  style?: StyleType;
10
+ onAnalyticsEvent: AnalyticsEventHandlerFn;
9
11
  };
10
12
  declare class ProvidedKeypad extends React.Component<Props> implements KeypadAPI {
11
13
  store: any;
@@ -1,10 +1,12 @@
1
1
  /// <reference types="react" />
2
+ import type { AnalyticsEventHandlerFn } from "@khanacademy/perseus-core";
2
3
  import type { StyleType } from "@khanacademy/wonder-blocks-core";
3
4
  type Props = {
4
5
  onElementMounted?: (arg1: any) => void;
5
6
  onDismiss?: () => void;
6
7
  style?: StyleType;
7
8
  useV2Keypad?: boolean;
9
+ onAnalyticsEvent: AnalyticsEventHandlerFn;
8
10
  };
9
11
  declare function KeypadSwitch(props: Props): JSX.Element;
10
12
  export default KeypadSwitch;
package/dist/es/index.js CHANGED
@@ -1553,9 +1553,11 @@ class MathInput extends React.Component {
1553
1553
  this._hideCursorHandle();
1554
1554
  }
1555
1555
  };
1556
- this.blur = () => {
1556
+ this.blur = callPropsOnBlur => {
1557
1557
  this.mathField.blur();
1558
- this.props.onBlur && this.props.onBlur();
1558
+ if (callPropsOnBlur) {
1559
+ this.props.onBlur && this.props.onBlur();
1560
+ }
1559
1561
  this.setState({
1560
1562
  focused: false,
1561
1563
  handle: {
@@ -2012,7 +2014,7 @@ class MathInput extends React.Component {
2012
2014
  // dismissal. This code needs to be generalized to handle
2013
2015
  // multi-touch.
2014
2016
  if (this.state.focused && this.didTouchOutside && !this.didScroll) {
2015
- this.blur();
2017
+ this.blur(true);
2016
2018
  }
2017
2019
  this.didTouchOutside = false;
2018
2020
  this.didScroll = false;
@@ -2088,13 +2090,18 @@ class MathInput extends React.Component {
2088
2090
  role: "textbox",
2089
2091
  ariaLabel: ariaLabel
2090
2092
  }, /*#__PURE__*/React.createElement("div", {
2091
- className: "keypad-input"
2092
- // @ts-expect-error - TS2322 - Type 'string' is not assignable to type 'number | undefined'.
2093
- ,
2094
- tabIndex: "0",
2093
+ className: "keypad-input",
2094
+ tabIndex: 0,
2095
2095
  ref: node => {
2096
2096
  this.inputRef = node;
2097
2097
  },
2098
+ onFocus: () => {
2099
+ this.focus();
2100
+ },
2101
+ onBlur: () => {
2102
+ this._hideCursorHandle();
2103
+ this.blur(false);
2104
+ },
2098
2105
  onKeyUp: this.handleKeyUp
2099
2106
  }, /*#__PURE__*/React.createElement("div", {
2100
2107
  ref: node => {
@@ -5121,17 +5128,21 @@ class MobileKeypad extends React.Component {
5121
5128
  }, 100);
5122
5129
  };
5123
5130
  this.activate = () => {
5124
- this.setState({
5125
- active: true
5126
- });
5131
+ if (!this.state.active) {
5132
+ this.setState({
5133
+ active: true
5134
+ });
5135
+ }
5127
5136
  };
5128
5137
  this.dismiss = () => {
5129
- this.setState({
5130
- active: false
5131
- }, () => {
5132
- var _this$props$onDismiss, _this$props;
5133
- (_this$props$onDismiss = (_this$props = this.props).onDismiss) == null ? void 0 : _this$props$onDismiss.call(_this$props);
5134
- });
5138
+ if (this.state.active) {
5139
+ this.setState({
5140
+ active: false
5141
+ }, () => {
5142
+ var _this$props$onDismiss, _this$props;
5143
+ (_this$props$onDismiss = (_this$props = this.props).onDismiss) == null ? void 0 : _this$props$onDismiss.call(_this$props);
5144
+ });
5145
+ }
5135
5146
  };
5136
5147
  this.configure = (configuration, cb) => {
5137
5148
  this.setState({
@@ -5167,9 +5178,14 @@ class MobileKeypad extends React.Component {
5167
5178
  this._resize();
5168
5179
  window.addEventListener("resize", this._throttleResizeHandler);
5169
5180
  window.addEventListener("orientationchange", this._throttleResizeHandler);
5170
- this._containerResizeObserver = new ResizeObserver(this._throttleResizeHandler);
5171
- if (this._containerRef.current) {
5172
- this._containerResizeObserver.observe(this._containerRef.current);
5181
+
5182
+ // LC-1213: some common older browsers (as of 2023-09-07)
5183
+ // don't support ResizeObserver
5184
+ if ("ResizeObserver" in window) {
5185
+ this._containerResizeObserver = new window.ResizeObserver(this._throttleResizeHandler);
5186
+ if (this._containerRef.current) {
5187
+ this._containerResizeObserver.observe(this._containerRef.current);
5188
+ }
5173
5189
  }
5174
5190
  }
5175
5191
  componentWillUnMount() {
@@ -5227,10 +5243,8 @@ class MobileKeypad extends React.Component {
5227
5243
  (_this$props$onElement = (_this$props2 = this.props).onElementMounted) == null ? void 0 : _this$props$onElement.call(_this$props2, elementWithDispatchMethods);
5228
5244
  }
5229
5245
  }
5230
- }, /*#__PURE__*/React.createElement(Keypad$2
5231
- // TODO(jeremy)
5232
- , {
5233
- onAnalyticsEvent: async function () {},
5246
+ }, /*#__PURE__*/React.createElement(Keypad$2, {
5247
+ onAnalyticsEvent: this.props.onAnalyticsEvent,
5234
5248
  extraKeys: keypadConfig == null ? void 0 : keypadConfig.extraKeys,
5235
5249
  onClickKey: key => this._handleClickKey(key),
5236
5250
  cursorContext: cursor == null ? void 0 : cursor.context,
@@ -8345,9 +8359,14 @@ class KeypadContainer extends React.Component {
8345
8359
  // And update it on resize.
8346
8360
  window.addEventListener("resize", this._throttleResizeHandler);
8347
8361
  window.addEventListener("orientationchange", this._throttleResizeHandler);
8348
- this._containerResizeObserver = new ResizeObserver(this._throttleResizeHandler);
8349
- if (this._containerRef.current) {
8350
- this._containerResizeObserver.observe(this._containerRef.current);
8362
+
8363
+ // LC-1213: some common older browsers (as of 2023-09-07)
8364
+ // don't support ResizeObserver
8365
+ if ("ResizeObserver" in window) {
8366
+ this._containerResizeObserver = new window.ResizeObserver(this._throttleResizeHandler);
8367
+ if (this._containerRef.current) {
8368
+ this._containerResizeObserver.observe(this._containerRef.current);
8369
+ }
8351
8370
  }
8352
8371
  }
8353
8372
  UNSAFE_componentWillReceiveProps(nextProps) {
@@ -9695,6 +9714,13 @@ class ProvidedKeypad extends React.Component {
9695
9714
  store: this.store
9696
9715
  }, /*#__PURE__*/React.createElement(KeypadContainer$1, {
9697
9716
  onElementMounted: element => {
9717
+ this.props.onAnalyticsEvent({
9718
+ type: "math-input:keypad-opened",
9719
+ payload: {
9720
+ virtualKeypadVersion: "MATH_INPUT_KEYPAD_V1"
9721
+ }
9722
+ });
9723
+
9698
9724
  // Append the dispatch methods that we want to expose
9699
9725
  // externally to the returned React element.
9700
9726
  const elementWithDispatchMethods = _extends({}, element, {
@@ -9705,9 +9731,17 @@ class ProvidedKeypad extends React.Component {
9705
9731
  setKeyHandler: this.setKeyHandler,
9706
9732
  getDOMNode: this.getDOMNode
9707
9733
  });
9708
- onElementMounted && onElementMounted(elementWithDispatchMethods);
9734
+ onElementMounted == null ? void 0 : onElementMounted(elementWithDispatchMethods);
9735
+ },
9736
+ onDismiss: () => {
9737
+ this.props.onAnalyticsEvent({
9738
+ type: "math-input:keypad-closed",
9739
+ payload: {
9740
+ virtualKeypadVersion: "MATH_INPUT_KEYPAD_V1"
9741
+ }
9742
+ });
9743
+ onDismiss == null ? void 0 : onDismiss();
9709
9744
  },
9710
- onDismiss: onDismiss,
9711
9745
  style: style
9712
9746
  }));
9713
9747
  }
@@ -9720,6 +9754,10 @@ function KeypadSwitch(props) {
9720
9754
  } = props,
9721
9755
  rest = _objectWithoutPropertiesLoose(props, _excluded);
9722
9756
  const KeypadComponent = useV2Keypad ? MobileKeypad : ProvidedKeypad;
9757
+
9758
+ // Note: Although we pass the "onAnalyticsEvent" to both keypad components,
9759
+ // only the current one uses it. There's no point in instrumenting the
9760
+ // legacy keypad given that it's on its way out the door.
9723
9761
  return /*#__PURE__*/React.createElement(KeypadComponent, rest);
9724
9762
  }
9725
9763