@khanacademy/math-input 11.0.0 → 12.1.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/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "description": "Khan Academy's new expression editor for the mobile web.",
4
4
  "author": "Khan Academy",
5
5
  "license": "MIT",
6
- "version": "11.0.0",
6
+ "version": "12.1.0",
7
7
  "publishConfig": {
8
8
  "access": "public"
9
9
  },
@@ -30,7 +30,7 @@
30
30
  "@khanacademy/wonder-blocks-core": "^6.0.0",
31
31
  "@khanacademy/wonder-blocks-i18n": "^2.0.2",
32
32
  "@khanacademy/wonder-blocks-popover": "^2.0.11",
33
- "@khanacademy/wonder-stuff-core": "^1.2.2",
33
+ "@khanacademy/wonder-stuff-core": "^1.5.1",
34
34
  "aphrodite": "^1.1.0",
35
35
  "jquery": "^2.1.1",
36
36
  "katex": "^0.11.1",
@@ -49,7 +49,7 @@
49
49
  "@khanacademy/wonder-blocks-color": "^2.0.1",
50
50
  "@khanacademy/wonder-blocks-core": "^6.0.0",
51
51
  "@khanacademy/wonder-blocks-i18n": "^2.0.2",
52
- "@khanacademy/wonder-stuff-core": "^1.2.2",
52
+ "@khanacademy/wonder-stuff-core": "^1.5.1",
53
53
  "aphrodite": "^1.1.0",
54
54
  "jquery": "^2.1.1",
55
55
  "katex": "^0.11.1",
@@ -13,6 +13,7 @@ import type {
13
13
  KeyHandler,
14
14
  KeypadAPI,
15
15
  } from "../../types";
16
+ import type {AnalyticsEventHandlerFn} from "@khanacademy/perseus-core";
16
17
  import type {StyleType} from "@khanacademy/wonder-blocks-core";
17
18
 
18
19
  import Keypad from "./index";
@@ -32,6 +33,7 @@ type Props = {
32
33
  onElementMounted?: (arg1: any) => void;
33
34
  onDismiss?: () => void;
34
35
  style?: StyleType;
36
+ onAnalyticsEvent: AnalyticsEventHandlerFn;
35
37
  };
36
38
 
37
39
  type State = {
@@ -62,12 +64,18 @@ class MobileKeypad extends React.Component<Props, State> implements KeypadAPI {
62
64
  this._throttleResizeHandler,
63
65
  );
64
66
 
65
- this._containerResizeObserver = new ResizeObserver(
66
- this._throttleResizeHandler,
67
- );
68
-
69
- if (this._containerRef.current) {
70
- this._containerResizeObserver.observe(this._containerRef.current);
67
+ // LC-1213: some common older browsers (as of 2023-09-07)
68
+ // don't support ResizeObserver
69
+ if ("ResizeObserver" in window) {
70
+ this._containerResizeObserver = new window.ResizeObserver(
71
+ this._throttleResizeHandler,
72
+ );
73
+
74
+ if (this._containerRef.current) {
75
+ this._containerResizeObserver.observe(
76
+ this._containerRef.current,
77
+ );
78
+ }
71
79
  }
72
80
  }
73
81
 
@@ -190,8 +198,7 @@ class MobileKeypad extends React.Component<Props, State> implements KeypadAPI {
190
198
  }}
191
199
  >
192
200
  <Keypad
193
- // TODO(jeremy)
194
- onAnalyticsEvent={async () => {}}
201
+ onAnalyticsEvent={this.props.onAnalyticsEvent}
195
202
  extraKeys={keypadConfig?.extraKeys}
196
203
  onClickKey={(key) => this._handleClickKey(key)}
197
204
  cursorContext={cursor?.context}
@@ -79,12 +79,18 @@ class KeypadContainer extends React.Component<Props, State> {
79
79
  this._throttleResizeHandler,
80
80
  );
81
81
 
82
- this._containerResizeObserver = new ResizeObserver(
83
- this._throttleResizeHandler,
84
- );
82
+ // LC-1213: some common older browsers (as of 2023-09-07)
83
+ // don't support ResizeObserver
84
+ if ("ResizeObserver" in window) {
85
+ this._containerResizeObserver = new window.ResizeObserver(
86
+ this._throttleResizeHandler,
87
+ );
85
88
 
86
- if (this._containerRef.current) {
87
- this._containerResizeObserver.observe(this._containerRef.current);
89
+ if (this._containerRef.current) {
90
+ this._containerResizeObserver.observe(
91
+ this._containerRef.current,
92
+ );
93
+ }
88
94
  }
89
95
  }
90
96
 
@@ -18,12 +18,15 @@ import type {
18
18
  KeyHandler,
19
19
  KeypadAPI,
20
20
  } from "../../types";
21
+ import type {AnalyticsEventHandlerFn} from "@khanacademy/perseus-core";
21
22
  import type {StyleType} from "@khanacademy/wonder-blocks-core";
22
23
 
23
24
  type Props = {
24
25
  onElementMounted?: (arg1: any) => void;
25
26
  onDismiss?: () => void;
26
27
  style?: StyleType;
28
+
29
+ onAnalyticsEvent: AnalyticsEventHandlerFn;
27
30
  };
28
31
 
29
32
  class ProvidedKeypad extends React.Component<Props> implements KeypadAPI {
@@ -77,6 +80,13 @@ class ProvidedKeypad extends React.Component<Props> implements KeypadAPI {
77
80
  <Provider store={this.store}>
78
81
  <KeypadContainer
79
82
  onElementMounted={(element) => {
83
+ this.props.onAnalyticsEvent({
84
+ type: "math-input:keypad-opened",
85
+ payload: {
86
+ virtualKeypadVersion: "MATH_INPUT_KEYPAD_V1",
87
+ },
88
+ });
89
+
80
90
  // Append the dispatch methods that we want to expose
81
91
  // externally to the returned React element.
82
92
  const elementWithDispatchMethods = {
@@ -88,10 +98,18 @@ class ProvidedKeypad extends React.Component<Props> implements KeypadAPI {
88
98
  setKeyHandler: this.setKeyHandler,
89
99
  getDOMNode: this.getDOMNode,
90
100
  } as const;
91
- onElementMounted &&
92
- onElementMounted(elementWithDispatchMethods);
101
+ onElementMounted?.(elementWithDispatchMethods);
102
+ }}
103
+ onDismiss={() => {
104
+ this.props.onAnalyticsEvent({
105
+ type: "math-input:keypad-closed",
106
+ payload: {
107
+ virtualKeypadVersion: "MATH_INPUT_KEYPAD_V1",
108
+ },
109
+ });
110
+
111
+ onDismiss?.();
93
112
  }}
94
- onDismiss={onDismiss}
95
113
  style={style}
96
114
  />
97
115
  </Provider>
@@ -3,6 +3,7 @@ import * as React from "react";
3
3
  import {MobileKeypad} from "./keypad";
4
4
  import LegacyKeypad from "./keypad-legacy";
5
5
 
6
+ import type {AnalyticsEventHandlerFn} from "@khanacademy/perseus-core";
6
7
  import type {StyleType} from "@khanacademy/wonder-blocks-core";
7
8
 
8
9
  type Props = {
@@ -11,6 +12,7 @@ type Props = {
11
12
  style?: StyleType;
12
13
 
13
14
  useV2Keypad?: boolean;
15
+ onAnalyticsEvent: AnalyticsEventHandlerFn;
14
16
  };
15
17
 
16
18
  function KeypadSwitch(props: Props) {
@@ -18,6 +20,9 @@ function KeypadSwitch(props: Props) {
18
20
 
19
21
  const KeypadComponent = useV2Keypad ? MobileKeypad : LegacyKeypad;
20
22
 
23
+ // Note: Although we pass the "onAnalyticsEvent" to both keypad components,
24
+ // only the current one uses it. There's no point in instrumenting the
25
+ // legacy keypad given that it's on its way out the door.
21
26
  return <KeypadComponent {...rest} />;
22
27
  }
23
28
 
@@ -1,3 +1,4 @@
1
+ import {action} from "@storybook/addon-actions";
1
2
  import * as React from "react";
2
3
 
3
4
  import type {KeypadAPI} from "./types";
@@ -93,6 +94,7 @@ export const Basic = () => {
93
94
  }
94
95
  }}
95
96
  useV2Keypad={v2Keypad}
97
+ onAnalyticsEvent={async (e) => action("onAnalyticsEvent")(e)}
96
98
  />
97
99
  </div>
98
100
  );