@khanacademy/perseus 17.4.0 → 17.6.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/CHANGELOG.md +21 -0
- package/dist/es/index.css +1 -1
- package/dist/es/index.js +38 -28
- package/dist/es/index.js.map +1 -1
- package/dist/index.css +1 -1
- package/dist/index.js +38 -28
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/__stories__/article-renderer.stories.tsx +2 -0
- package/src/__tests__/server-item-renderer.test.tsx +15 -18
- package/src/article-renderer.tsx +20 -15
- package/src/server-item-renderer.tsx +23 -20
- package/src/styles/perseus-renderer.less +1 -1
- package/src/styles/variables.less +1 -0
- package/src/widgets/iframe.tsx +1 -1
- package/src/widgets/input-number.tsx +1 -1
- package/src/widgets/lights-puzzle.tsx +1 -1
- package/src/widgets/matcher.tsx +1 -1
- package/src/widgets/numeric-input.tsx +1 -1
- package/src/widgets/radio.ts +1 -1
- package/src/widgets/reaction-diagram.tsx +1 -1
- package/src/widgets/sequence.tsx +1 -1
- package/src/widgets/simulator.tsx +1 -1
- package/src/widgets/table.tsx +1 -1
- package/src/widgets/transformer.tsx +2 -1
- package/src/widgets/unit.tsx +1 -1
- package/tsconfig-build.tsbuildinfo +1 -1
package/package.json
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import {KeypadContext} from "@khanacademy/math-input";
|
|
2
|
+
import {action} from "@storybook/addon-actions";
|
|
2
3
|
import React from "react";
|
|
3
4
|
|
|
4
5
|
import {storybookDependenciesV2} from "../../../../testing/test-dependencies";
|
|
@@ -67,6 +68,7 @@ export const ExpressionArticle = ({useNewStyles}): any => (
|
|
|
67
68
|
apiOptions={{
|
|
68
69
|
isMobile: true,
|
|
69
70
|
customKeypad: true,
|
|
71
|
+
onFocusChange: action("onFocusChange"),
|
|
70
72
|
}}
|
|
71
73
|
keypadElement={keypadElement}
|
|
72
74
|
/>
|
|
@@ -326,9 +326,9 @@ describe("server item renderer", () => {
|
|
|
326
326
|
|
|
327
327
|
// Act
|
|
328
328
|
const gotFocus = renderer.focus();
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
jest.
|
|
329
|
+
|
|
330
|
+
// We have some async processes that need to be resolved here
|
|
331
|
+
jest.runAllTimers();
|
|
332
332
|
|
|
333
333
|
// Assert
|
|
334
334
|
expect(gotFocus).toBeTrue();
|
|
@@ -370,9 +370,9 @@ describe("server item renderer", () => {
|
|
|
370
370
|
|
|
371
371
|
// Act
|
|
372
372
|
const gotFocus = renderer.focus();
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
jest.
|
|
373
|
+
|
|
374
|
+
// We have some async processes that need to be resolved here
|
|
375
|
+
jest.runAllTimers();
|
|
376
376
|
|
|
377
377
|
// Assert
|
|
378
378
|
expect(keypadElement.activate).toHaveBeenCalled();
|
|
@@ -392,15 +392,12 @@ describe("server item renderer", () => {
|
|
|
392
392
|
onFocusChange,
|
|
393
393
|
});
|
|
394
394
|
renderer.focus();
|
|
395
|
-
// We have _two_ different async processes that need to be resolved here
|
|
396
|
-
jest.runOnlyPendingTimers();
|
|
397
|
-
jest.runOnlyPendingTimers();
|
|
398
395
|
|
|
399
396
|
// Act
|
|
400
397
|
renderer.blur();
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
jest.
|
|
398
|
+
|
|
399
|
+
// We have some async processes that need to be resolved here
|
|
400
|
+
jest.runAllTimers();
|
|
404
401
|
|
|
405
402
|
// Assert
|
|
406
403
|
expect(onFocusChange).toHaveBeenCalledTimes(2);
|
|
@@ -440,15 +437,12 @@ describe("server item renderer", () => {
|
|
|
440
437
|
{keypadElement},
|
|
441
438
|
);
|
|
442
439
|
renderer.focus();
|
|
443
|
-
// We have _two_ different async processes that need to be resolved here
|
|
444
|
-
jest.runOnlyPendingTimers();
|
|
445
|
-
jest.runOnlyPendingTimers();
|
|
446
440
|
|
|
447
441
|
// Act
|
|
448
442
|
renderer.blur();
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
jest.
|
|
443
|
+
|
|
444
|
+
// We have some async processes that need to be resolved here
|
|
445
|
+
jest.runAllTimers();
|
|
452
446
|
|
|
453
447
|
// Assert
|
|
454
448
|
expect(keypadElement.dismiss).toHaveBeenCalled();
|
|
@@ -471,6 +465,9 @@ describe("server item renderer", () => {
|
|
|
471
465
|
// Act
|
|
472
466
|
renderer.focusPath(["input-number 1"]);
|
|
473
467
|
|
|
468
|
+
// We have some async processes that need to be resolved here
|
|
469
|
+
jest.runAllTimers();
|
|
470
|
+
|
|
474
471
|
// Assert
|
|
475
472
|
expect(onFocusChange).toHaveBeenCalledWith(
|
|
476
473
|
["input-number 1"],
|
package/src/article-renderer.tsx
CHANGED
|
@@ -104,6 +104,26 @@ class ArticleRenderer
|
|
|
104
104
|
);
|
|
105
105
|
}
|
|
106
106
|
|
|
107
|
+
const {onFocusChange} = this.props.apiOptions;
|
|
108
|
+
if (onFocusChange) {
|
|
109
|
+
// Wait for the keypad to mount before getting the height
|
|
110
|
+
setTimeout(() => {
|
|
111
|
+
const keypadDomNode =
|
|
112
|
+
keypadElement?.getDOMNode() as HTMLElement;
|
|
113
|
+
const keypadHeight =
|
|
114
|
+
keypadDomNode && didFocusInput
|
|
115
|
+
? keypadDomNode.getBoundingClientRect().height
|
|
116
|
+
: 0;
|
|
117
|
+
|
|
118
|
+
onFocusChange(
|
|
119
|
+
this._currentFocus,
|
|
120
|
+
prevFocusPath,
|
|
121
|
+
keypadHeight,
|
|
122
|
+
didFocusInput ? focusedInput : null,
|
|
123
|
+
);
|
|
124
|
+
}, 0);
|
|
125
|
+
}
|
|
126
|
+
|
|
107
127
|
if (keypadElement && isMobile) {
|
|
108
128
|
if (didFocusInput) {
|
|
109
129
|
keypadElement.activate();
|
|
@@ -111,21 +131,6 @@ class ArticleRenderer
|
|
|
111
131
|
keypadElement.dismiss();
|
|
112
132
|
}
|
|
113
133
|
}
|
|
114
|
-
|
|
115
|
-
if (this.props.apiOptions.onFocusChange != null) {
|
|
116
|
-
const keypadDomNode = keypadElement?.getDOMNode() as HTMLElement;
|
|
117
|
-
const keypadHeight =
|
|
118
|
-
keypadDomNode && didFocusInput
|
|
119
|
-
? keypadDomNode.getBoundingClientRect().height
|
|
120
|
-
: 0;
|
|
121
|
-
|
|
122
|
-
this.props.apiOptions.onFocusChange(
|
|
123
|
-
this._currentFocus,
|
|
124
|
-
prevFocusPath,
|
|
125
|
-
keypadHeight,
|
|
126
|
-
didFocusInput ? focusedInput : null,
|
|
127
|
-
);
|
|
128
|
-
}
|
|
129
134
|
};
|
|
130
135
|
|
|
131
136
|
_onRendererBlur: (arg1: any) => void = (blurPath) => {
|
|
@@ -180,6 +180,29 @@ export class ServerItemRenderer
|
|
|
180
180
|
return Util.inputPathsEqual(inputPath, this._currentFocus);
|
|
181
181
|
});
|
|
182
182
|
|
|
183
|
+
if (onFocusChange != null) {
|
|
184
|
+
// Wait for the keypad to mount before getting the height
|
|
185
|
+
setTimeout(() => {
|
|
186
|
+
// First, calculate the current keypad height
|
|
187
|
+
const keypadDomNode: HTMLElement =
|
|
188
|
+
keypadElement?.getDOMNode() as HTMLElement;
|
|
189
|
+
const keypadHeight =
|
|
190
|
+
keypadDomNode && didFocusInput
|
|
191
|
+
? keypadDomNode.getBoundingClientRect().height
|
|
192
|
+
: 0;
|
|
193
|
+
|
|
194
|
+
// Then call the callback
|
|
195
|
+
onFocusChange(
|
|
196
|
+
this._currentFocus,
|
|
197
|
+
prevFocus,
|
|
198
|
+
keypadHeight,
|
|
199
|
+
// @ts-expect-error [FEI-5003] - TS2345 - Argument of type 'false | Element | Text | null | undefined' is not assignable to parameter of type 'HTMLElement | undefined'.
|
|
200
|
+
didFocusInput &&
|
|
201
|
+
this.questionRenderer.getDOMNodeForPath(newFocus),
|
|
202
|
+
);
|
|
203
|
+
}, 0);
|
|
204
|
+
}
|
|
205
|
+
|
|
183
206
|
if (keypadElement && isMobile) {
|
|
184
207
|
if (didFocusInput) {
|
|
185
208
|
keypadElement.activate();
|
|
@@ -187,26 +210,6 @@ export class ServerItemRenderer
|
|
|
187
210
|
keypadElement.dismiss();
|
|
188
211
|
}
|
|
189
212
|
}
|
|
190
|
-
|
|
191
|
-
if (onFocusChange != null) {
|
|
192
|
-
// First, calculate the current keypad height
|
|
193
|
-
const keypadDomNode: HTMLElement =
|
|
194
|
-
keypadElement?.getDOMNode() as HTMLElement;
|
|
195
|
-
const keypadHeight =
|
|
196
|
-
keypadDomNode && didFocusInput
|
|
197
|
-
? keypadDomNode.getBoundingClientRect().height
|
|
198
|
-
: 0;
|
|
199
|
-
|
|
200
|
-
// Then call the callback
|
|
201
|
-
onFocusChange(
|
|
202
|
-
this._currentFocus,
|
|
203
|
-
prevFocus,
|
|
204
|
-
keypadHeight,
|
|
205
|
-
// @ts-expect-error [FEI-5003] - TS2345 - Argument of type 'false | Element | Text | null | undefined' is not assignable to parameter of type 'HTMLElement | undefined'.
|
|
206
|
-
didFocusInput &&
|
|
207
|
-
this.questionRenderer.getDOMNodeForPath(newFocus),
|
|
208
|
-
);
|
|
209
|
-
}
|
|
210
213
|
}
|
|
211
214
|
|
|
212
215
|
_onRendererBlur(blurPath: FocusPath) {
|
package/src/widgets/iframe.tsx
CHANGED
|
@@ -403,7 +403,7 @@ const propTransform = (
|
|
|
403
403
|
|
|
404
404
|
export default {
|
|
405
405
|
name: "input-number",
|
|
406
|
-
displayName: "
|
|
406
|
+
displayName: "Input number (deprecated - use numeric input instead)",
|
|
407
407
|
defaultAlignment: "inline-block",
|
|
408
408
|
hidden: true,
|
|
409
409
|
widget: InputNumber,
|
|
@@ -352,7 +352,7 @@ const transformProps: (arg1: any) => any = function (editorProps) {
|
|
|
352
352
|
|
|
353
353
|
export default {
|
|
354
354
|
name: "lights-puzzle",
|
|
355
|
-
displayName: "Lights
|
|
355
|
+
displayName: "Lights puzzle (deprecated)",
|
|
356
356
|
hidden: true,
|
|
357
357
|
widget: LightsPuzzle,
|
|
358
358
|
transform: transformProps,
|
package/src/widgets/matcher.tsx
CHANGED
package/src/widgets/radio.ts
CHANGED
|
@@ -138,7 +138,7 @@ class ReactionDiagramWidget extends React.Component<any> {
|
|
|
138
138
|
|
|
139
139
|
export default {
|
|
140
140
|
name: "reaction-diagram",
|
|
141
|
-
displayName: "Chemical reaction",
|
|
141
|
+
displayName: "Chemical reaction diagram (deprecated)",
|
|
142
142
|
hidden: true,
|
|
143
143
|
widget: ReactionDiagramWidget,
|
|
144
144
|
} as WidgetExports<typeof ReactionDiagramWidget>;
|
package/src/widgets/sequence.tsx
CHANGED
|
@@ -133,7 +133,7 @@ const traverseChildWidgets = function (props: any, traverseRenderer: any): any {
|
|
|
133
133
|
|
|
134
134
|
export default {
|
|
135
135
|
name: "sequence",
|
|
136
|
-
displayName: "Graded
|
|
136
|
+
displayName: "Graded sequence (deprecated)",
|
|
137
137
|
widget: Sequence,
|
|
138
138
|
traverseChildWidgets: traverseChildWidgets,
|
|
139
139
|
tracking: "all",
|
|
@@ -822,7 +822,7 @@ const propTransform: (arg1: any) => any = (editorProps) => {
|
|
|
822
822
|
|
|
823
823
|
export default {
|
|
824
824
|
name: "simulator",
|
|
825
|
-
displayName: "Simulator",
|
|
825
|
+
displayName: "Simulator (deprecated)",
|
|
826
826
|
widget: Simulator,
|
|
827
827
|
transform: propTransform,
|
|
828
828
|
hidden: true,
|
package/src/widgets/table.tsx
CHANGED
|
@@ -384,7 +384,7 @@ const propTransform: (arg1: any) => any = (editorProps) => {
|
|
|
384
384
|
|
|
385
385
|
export default {
|
|
386
386
|
name: "table",
|
|
387
|
-
displayName: "Table
|
|
387
|
+
displayName: "Table (deprecated - use markdown table instead)",
|
|
388
388
|
accessible: true,
|
|
389
389
|
widget: Table,
|
|
390
390
|
transform: propTransform,
|
|
@@ -2930,6 +2930,7 @@ class Transformer extends React.Component<Props> {
|
|
|
2930
2930
|
|
|
2931
2931
|
export default {
|
|
2932
2932
|
name: "transformer",
|
|
2933
|
-
displayName: "Transformer",
|
|
2933
|
+
displayName: "Transformer (deprecated)",
|
|
2934
|
+
hidden: true,
|
|
2934
2935
|
widget: Transformer,
|
|
2935
2936
|
} as WidgetExports<typeof Transformer>;
|
package/src/widgets/unit.tsx
CHANGED
|
@@ -365,7 +365,7 @@ const primUnits = function (expr) {
|
|
|
365
365
|
|
|
366
366
|
export default {
|
|
367
367
|
name: "unit-input",
|
|
368
|
-
displayName: "Unit",
|
|
368
|
+
displayName: "Unit input",
|
|
369
369
|
defaultAlignment: "inline-block",
|
|
370
370
|
widget: OldUnitInput,
|
|
371
371
|
transform: (x: any): any => lens(x).del(["value"]).freeze(),
|