@khanacademy/perseus 10.1.0 → 11.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/CHANGELOG.md +12 -0
- package/dist/article-renderer.d.ts +5 -7
- package/dist/es/index.js +81 -89
- package/dist/es/index.js.map +1 -1
- package/dist/index.js +81 -89
- package/dist/index.js.map +1 -1
- package/dist/perseus-api.d.ts +2 -2
- package/dist/server-item-renderer.d.ts +5 -4
- package/dist/types.d.ts +2 -1
- package/dist/widgets/expression.d.ts +12 -12
- package/package.json +5 -4
- package/src/__stories__/article-renderer.stories.tsx +22 -0
- package/src/__testdata__/article-renderer.testdata.ts +28 -0
- package/src/__tests__/server-item-renderer.test.tsx +12 -4
- package/src/article-renderer.tsx +14 -27
- package/src/server-item-renderer.tsx +10 -7
- package/src/types.ts +2 -4
- package/src/widgets/__stories__/expression.stories.tsx +3 -3
- package/tsconfig-build.tsbuildinfo +1 -1
package/dist/index.js
CHANGED
|
@@ -44146,80 +44146,10 @@ registerWidgets(allWidgets);
|
|
|
44146
44146
|
const ItemVersion = getVersionVector();
|
|
44147
44147
|
ItemVersion["::renderer::"] = version.itemDataVersion;
|
|
44148
44148
|
|
|
44149
|
-
/* eslint-disable @khanacademy/ts-no-error-suppressions */
|
|
44150
|
-
// NOTE: This is not a real component. It's a collection of methods used to
|
|
44151
|
-
// create and manage a Keypad instances.
|
|
44152
|
-
// TODO(LP-10789): replace this with a React Context object to pass information
|
|
44153
|
-
// between Perseus and the Keypad.
|
|
44154
|
-
const ProvideKeypad = {
|
|
44155
|
-
getInitialState() {
|
|
44156
|
-
const _this = this;
|
|
44157
|
-
let keypadElement = null;
|
|
44158
|
-
if (_this.props.apiOptions && _this.props.apiOptions.customKeypad && _this.props.apiOptions.nativeKeypadProxy) {
|
|
44159
|
-
keypadElement = _this.props.apiOptions.nativeKeypadProxy(
|
|
44160
|
-
// @ts-expect-error - TS2339 - Property 'blur' does not exist on type '{ readonly propTypes: { readonly apiOptions: React.PropType<{ customKeypad?: boolean | undefined; nativeKeypadProxy?: ((...a: readonly any[]) => unknown) | undefined; }>; readonly keypadStyle: Requireable<any>; }; readonly getInitialState: () => { ...; }; readonly componentDidMount: () => void; readonly componentWil...'. | TS2339 - Property 'blur' does not exist on type '{ readonly propTypes: { readonly apiOptions: React.PropType<{ customKeypad?: boolean | undefined; nativeKeypadProxy?: ((...a: readonly any[]) => unknown) | undefined; }>; readonly keypadStyle: Requireable<any>; }; readonly getInitialState: () => { ...; }; readonly componentDidMount: () => void; readonly componentWil...'.
|
|
44161
|
-
() => _this.blur && _this.blur());
|
|
44162
|
-
}
|
|
44163
|
-
return {
|
|
44164
|
-
keypadElement
|
|
44165
|
-
};
|
|
44166
|
-
},
|
|
44167
|
-
componentDidMount() {
|
|
44168
|
-
const _this = this;
|
|
44169
|
-
const apiOptions = _this.props.apiOptions;
|
|
44170
|
-
if (apiOptions && apiOptions.customKeypad && !apiOptions.nativeKeypadProxy) {
|
|
44171
|
-
var _document$body;
|
|
44172
|
-
// TODO(charlie): Render this and the wrapped component in the same
|
|
44173
|
-
// React tree. We may also want to add this keypad asynchronously
|
|
44174
|
-
// or on-demand in the future.
|
|
44175
|
-
_this._keypadContainer = document.createElement("div");
|
|
44176
|
-
(_document$body = document.body) === null || _document$body === void 0 ? void 0 : _document$body.appendChild(_this._keypadContainer);
|
|
44177
|
-
render( /*#__PURE__*/React__namespace.createElement(mathInput.MobileKeypad, {
|
|
44178
|
-
onElementMounted: element => {
|
|
44179
|
-
// NOTE(kevinb): The reason why this setState works is
|
|
44180
|
-
// b/c we're calling it manually from item-renderer.jsx
|
|
44181
|
-
// and we're manually setting the 'this' by using 'call'
|
|
44182
|
-
// @ts-expect-error - TS2339 - Property 'setState' does not exist on type '{ readonly propTypes: { readonly apiOptions: React.PropType<{ customKeypad?: boolean | undefined; nativeKeypadProxy?: ((...a: readonly any[]) => unknown) | undefined; }>; readonly keypadStyle: Requireable<any>; }; readonly getInitialState: () => { ...; }; readonly componentDidMount: () => void; readonly componentWil...'.
|
|
44183
|
-
_this.setState({
|
|
44184
|
-
keypadElement: element
|
|
44185
|
-
});
|
|
44186
|
-
},
|
|
44187
|
-
onDismiss: () => {
|
|
44188
|
-
// @ts-expect-error - TS2339 - Property 'blur' does not exist on type '{ readonly propTypes: { readonly apiOptions: React.PropType<{ customKeypad?: boolean | undefined; nativeKeypadProxy?: ((...a: readonly any[]) => unknown) | undefined; }>; readonly keypadStyle: Requireable<any>; }; readonly getInitialState: () => { ...; }; readonly componentDidMount: () => void; readonly componentWil...'. | TS2339 - Property 'blur' does not exist on type '{ readonly propTypes: { readonly apiOptions: React.PropType<{ customKeypad?: boolean | undefined; nativeKeypadProxy?: ((...a: readonly any[]) => unknown) | undefined; }>; readonly keypadStyle: Requireable<any>; }; readonly getInitialState: () => { ...; }; readonly componentDidMount: () => void; readonly componentWil...'.
|
|
44189
|
-
_this.blur && _this.blur();
|
|
44190
|
-
}
|
|
44191
|
-
// @ts-expect-error - TS2339 - Property 'props' does not exist on type '{ readonly propTypes: { readonly apiOptions: React.PropType<{ customKeypad?: boolean | undefined; nativeKeypadProxy?: ((...a: readonly any[]) => unknown) | undefined; }>; readonly keypadStyle: Requireable<any>; }; readonly getInitialState: () => { ...; }; readonly componentDidMount: () => void; readonly componentWil...'.
|
|
44192
|
-
,
|
|
44193
|
-
style: _this.props.keypadStyle,
|
|
44194
|
-
useV2Keypad: apiOptions.useV2Keypad
|
|
44195
|
-
}), _this._keypadContainer);
|
|
44196
|
-
}
|
|
44197
|
-
},
|
|
44198
|
-
componentWillUnmount() {
|
|
44199
|
-
const _this = this;
|
|
44200
|
-
if (_this._keypadContainer) {
|
|
44201
|
-
ReactDOM__default["default"].unmountComponentAtNode(_this._keypadContainer);
|
|
44202
|
-
if (_this._keypadContainer.parentNode) {
|
|
44203
|
-
// Note ChildNode.remove() isn't available in older Android
|
|
44204
|
-
// webviews.
|
|
44205
|
-
_this._keypadContainer.parentNode.removeChild(_this._keypadContainer);
|
|
44206
|
-
}
|
|
44207
|
-
_this._keypadContainer = null;
|
|
44208
|
-
}
|
|
44209
|
-
},
|
|
44210
|
-
keypadElement() {
|
|
44211
|
-
const _this = this;
|
|
44212
|
-
return _this.state.keypadElement;
|
|
44213
|
-
}
|
|
44214
|
-
};
|
|
44215
|
-
|
|
44216
44149
|
class ArticleRenderer extends React__namespace.Component {
|
|
44217
44150
|
constructor(props) {
|
|
44218
44151
|
super(props);
|
|
44219
44152
|
_defineProperty(this, "_currentFocus", void 0);
|
|
44220
|
-
_defineProperty(this, "keypadElement", () => {
|
|
44221
|
-
return ProvideKeypad.keypadElement.call(this);
|
|
44222
|
-
});
|
|
44223
44153
|
_defineProperty(this, "_handleFocusChange", (newFocusPath, oldFocusPath) => {
|
|
44224
44154
|
// TODO(charlie): DRY this up--some of this logic is repeated in
|
|
44225
44155
|
// ItemRenderer.
|
|
@@ -44230,7 +44160,13 @@ class ArticleRenderer extends React__namespace.Component {
|
|
|
44230
44160
|
}
|
|
44231
44161
|
});
|
|
44232
44162
|
_defineProperty(this, "_setCurrentFocus", newFocusPath => {
|
|
44233
|
-
const
|
|
44163
|
+
const {
|
|
44164
|
+
keypadElement,
|
|
44165
|
+
apiOptions
|
|
44166
|
+
} = this.props;
|
|
44167
|
+
const {
|
|
44168
|
+
isMobile
|
|
44169
|
+
} = apiOptions;
|
|
44234
44170
|
const prevFocusPath = this._currentFocus;
|
|
44235
44171
|
this._currentFocus = newFocusPath;
|
|
44236
44172
|
|
|
@@ -44248,18 +44184,12 @@ class ArticleRenderer extends React__namespace.Component {
|
|
|
44248
44184
|
});
|
|
44249
44185
|
}
|
|
44250
44186
|
if (this.props.apiOptions.onFocusChange != null) {
|
|
44251
|
-
this.props.apiOptions.onFocusChange(this._currentFocus, prevFocusPath,
|
|
44252
|
-
// @ts-expect-error - TS2339 - Property 'getDOMNode' does not exist on type 'never'.
|
|
44253
|
-
didFocusInput && keypadElement && keypadElement.getDOMNode());
|
|
44187
|
+
this.props.apiOptions.onFocusChange(this._currentFocus, prevFocusPath, didFocusInput ? keypadElement === null || keypadElement === void 0 ? void 0 : keypadElement.getDOMNode() : null);
|
|
44254
44188
|
}
|
|
44255
|
-
|
|
44256
|
-
// @ts-expect-error - TS1345 - An expression of type 'void' cannot be tested for truthiness.
|
|
44257
|
-
if (keypadElement) {
|
|
44189
|
+
if (keypadElement && isMobile) {
|
|
44258
44190
|
if (didFocusInput) {
|
|
44259
|
-
// @ts-expect-error - TS2339 - Property 'activate' does not exist on type 'never'.
|
|
44260
44191
|
keypadElement.activate();
|
|
44261
44192
|
} else {
|
|
44262
|
-
// @ts-expect-error - TS2339 - Property 'dismiss' does not exist on type 'never'.
|
|
44263
44193
|
keypadElement.dismiss();
|
|
44264
44194
|
}
|
|
44265
44195
|
}
|
|
@@ -44295,17 +44225,12 @@ class ArticleRenderer extends React__namespace.Component {
|
|
|
44295
44225
|
_defineProperty(this, "_sections", () => {
|
|
44296
44226
|
return Array.isArray(this.props.json) ? this.props.json : [this.props.json];
|
|
44297
44227
|
});
|
|
44298
|
-
this.state = ProvideKeypad.getInitialState.call(this);
|
|
44299
44228
|
}
|
|
44300
44229
|
componentDidMount() {
|
|
44301
|
-
ProvideKeypad.componentDidMount.call(this);
|
|
44302
44230
|
this._currentFocus = null;
|
|
44303
44231
|
}
|
|
44304
|
-
shouldComponentUpdate(nextProps
|
|
44305
|
-
return nextProps !== this.props
|
|
44306
|
-
}
|
|
44307
|
-
componentWillUnmount() {
|
|
44308
|
-
ProvideKeypad.componentWillUnmount.call(this);
|
|
44232
|
+
shouldComponentUpdate(nextProps) {
|
|
44233
|
+
return nextProps !== this.props;
|
|
44309
44234
|
}
|
|
44310
44235
|
render() {
|
|
44311
44236
|
const apiOptions = {
|
|
@@ -44333,7 +44258,7 @@ class ArticleRenderer extends React__namespace.Component {
|
|
|
44333
44258
|
ref: refForSection,
|
|
44334
44259
|
key: i,
|
|
44335
44260
|
key_: i,
|
|
44336
|
-
keypadElement: this.keypadElement
|
|
44261
|
+
keypadElement: this.props.keypadElement,
|
|
44337
44262
|
apiOptions: {
|
|
44338
44263
|
...apiOptions,
|
|
44339
44264
|
onFocusChange: (newFocusPath, oldFocusPath) => {
|
|
@@ -44705,6 +44630,73 @@ const styles$4 = aphrodite.StyleSheet.create({
|
|
|
44705
44630
|
}
|
|
44706
44631
|
});
|
|
44707
44632
|
|
|
44633
|
+
/* eslint-disable @khanacademy/ts-no-error-suppressions */
|
|
44634
|
+
// NOTE: This is not a real component. It's a collection of methods used to
|
|
44635
|
+
// create and manage a Keypad instances.
|
|
44636
|
+
// TODO(LP-10789): replace this with a React Context object to pass information
|
|
44637
|
+
// between Perseus and the Keypad.
|
|
44638
|
+
const ProvideKeypad = {
|
|
44639
|
+
getInitialState() {
|
|
44640
|
+
const _this = this;
|
|
44641
|
+
let keypadElement = null;
|
|
44642
|
+
if (_this.props.apiOptions && _this.props.apiOptions.customKeypad && _this.props.apiOptions.nativeKeypadProxy) {
|
|
44643
|
+
keypadElement = _this.props.apiOptions.nativeKeypadProxy(
|
|
44644
|
+
// @ts-expect-error - TS2339 - Property 'blur' does not exist on type '{ readonly propTypes: { readonly apiOptions: React.PropType<{ customKeypad?: boolean | undefined; nativeKeypadProxy?: ((...a: readonly any[]) => unknown) | undefined; }>; readonly keypadStyle: Requireable<any>; }; readonly getInitialState: () => { ...; }; readonly componentDidMount: () => void; readonly componentWil...'. | TS2339 - Property 'blur' does not exist on type '{ readonly propTypes: { readonly apiOptions: React.PropType<{ customKeypad?: boolean | undefined; nativeKeypadProxy?: ((...a: readonly any[]) => unknown) | undefined; }>; readonly keypadStyle: Requireable<any>; }; readonly getInitialState: () => { ...; }; readonly componentDidMount: () => void; readonly componentWil...'.
|
|
44645
|
+
() => _this.blur && _this.blur());
|
|
44646
|
+
}
|
|
44647
|
+
return {
|
|
44648
|
+
keypadElement
|
|
44649
|
+
};
|
|
44650
|
+
},
|
|
44651
|
+
componentDidMount() {
|
|
44652
|
+
const _this = this;
|
|
44653
|
+
const apiOptions = _this.props.apiOptions;
|
|
44654
|
+
if (apiOptions && apiOptions.customKeypad && !apiOptions.nativeKeypadProxy) {
|
|
44655
|
+
var _document$body;
|
|
44656
|
+
// TODO(charlie): Render this and the wrapped component in the same
|
|
44657
|
+
// React tree. We may also want to add this keypad asynchronously
|
|
44658
|
+
// or on-demand in the future.
|
|
44659
|
+
_this._keypadContainer = document.createElement("div");
|
|
44660
|
+
(_document$body = document.body) === null || _document$body === void 0 ? void 0 : _document$body.appendChild(_this._keypadContainer);
|
|
44661
|
+
render( /*#__PURE__*/React__namespace.createElement(mathInput.MobileKeypad, {
|
|
44662
|
+
onElementMounted: element => {
|
|
44663
|
+
// NOTE(kevinb): The reason why this setState works is
|
|
44664
|
+
// b/c we're calling it manually from item-renderer.jsx
|
|
44665
|
+
// and we're manually setting the 'this' by using 'call'
|
|
44666
|
+
// @ts-expect-error - TS2339 - Property 'setState' does not exist on type '{ readonly propTypes: { readonly apiOptions: React.PropType<{ customKeypad?: boolean | undefined; nativeKeypadProxy?: ((...a: readonly any[]) => unknown) | undefined; }>; readonly keypadStyle: Requireable<any>; }; readonly getInitialState: () => { ...; }; readonly componentDidMount: () => void; readonly componentWil...'.
|
|
44667
|
+
_this.setState({
|
|
44668
|
+
keypadElement: element
|
|
44669
|
+
});
|
|
44670
|
+
},
|
|
44671
|
+
onDismiss: () => {
|
|
44672
|
+
// @ts-expect-error - TS2339 - Property 'blur' does not exist on type '{ readonly propTypes: { readonly apiOptions: React.PropType<{ customKeypad?: boolean | undefined; nativeKeypadProxy?: ((...a: readonly any[]) => unknown) | undefined; }>; readonly keypadStyle: Requireable<any>; }; readonly getInitialState: () => { ...; }; readonly componentDidMount: () => void; readonly componentWil...'. | TS2339 - Property 'blur' does not exist on type '{ readonly propTypes: { readonly apiOptions: React.PropType<{ customKeypad?: boolean | undefined; nativeKeypadProxy?: ((...a: readonly any[]) => unknown) | undefined; }>; readonly keypadStyle: Requireable<any>; }; readonly getInitialState: () => { ...; }; readonly componentDidMount: () => void; readonly componentWil...'.
|
|
44673
|
+
_this.blur && _this.blur();
|
|
44674
|
+
}
|
|
44675
|
+
// @ts-expect-error - TS2339 - Property 'props' does not exist on type '{ readonly propTypes: { readonly apiOptions: React.PropType<{ customKeypad?: boolean | undefined; nativeKeypadProxy?: ((...a: readonly any[]) => unknown) | undefined; }>; readonly keypadStyle: Requireable<any>; }; readonly getInitialState: () => { ...; }; readonly componentDidMount: () => void; readonly componentWil...'.
|
|
44676
|
+
,
|
|
44677
|
+
style: _this.props.keypadStyle,
|
|
44678
|
+
useV2Keypad: apiOptions.useV2Keypad
|
|
44679
|
+
}), _this._keypadContainer);
|
|
44680
|
+
}
|
|
44681
|
+
},
|
|
44682
|
+
componentWillUnmount() {
|
|
44683
|
+
const _this = this;
|
|
44684
|
+
if (_this._keypadContainer) {
|
|
44685
|
+
ReactDOM__default["default"].unmountComponentAtNode(_this._keypadContainer);
|
|
44686
|
+
if (_this._keypadContainer.parentNode) {
|
|
44687
|
+
// Note ChildNode.remove() isn't available in older Android
|
|
44688
|
+
// webviews.
|
|
44689
|
+
_this._keypadContainer.parentNode.removeChild(_this._keypadContainer);
|
|
44690
|
+
}
|
|
44691
|
+
_this._keypadContainer = null;
|
|
44692
|
+
}
|
|
44693
|
+
},
|
|
44694
|
+
keypadElement() {
|
|
44695
|
+
const _this = this;
|
|
44696
|
+
return _this.state.keypadElement;
|
|
44697
|
+
}
|
|
44698
|
+
};
|
|
44699
|
+
|
|
44708
44700
|
const {
|
|
44709
44701
|
mapObject: mapObject$1
|
|
44710
44702
|
} = objective_;
|
|
@@ -45201,8 +45193,8 @@ class ServerItemRenderer extends React__namespace.Component {
|
|
|
45201
45193
|
return Util.inputPathsEqual(inputPath, this._currentFocus);
|
|
45202
45194
|
});
|
|
45203
45195
|
if (onFocusChange != null) {
|
|
45204
|
-
onFocusChange(this._currentFocus, prevFocus, didFocusInput
|
|
45205
|
-
// @ts-expect-error - TS2345 - Argument of type 'false | Element | Text | null | undefined' is not assignable to parameter of type 'HTMLElement | undefined'.
|
|
45196
|
+
onFocusChange(this._currentFocus, prevFocus, didFocusInput ? keypadElement === null || keypadElement === void 0 ? void 0 : keypadElement.getDOMNode() : null,
|
|
45197
|
+
// @ts-expect-error [FEI-5003] - TS2345 - Argument of type 'false | Element | Text | null | undefined' is not assignable to parameter of type 'HTMLElement | undefined'.
|
|
45206
45198
|
didFocusInput && this.questionRenderer.getDOMNodeForPath(newFocus));
|
|
45207
45199
|
}
|
|
45208
45200
|
if (keypadElement && isMobile) {
|