@khanacademy/perseus 6.1.0 → 6.2.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 +25 -0
- package/dist/components/math-input.d.ts +1 -1
- package/dist/components/math-input.js.flow +1 -1
- package/dist/components/sortable.d.ts +1 -1
- package/dist/components/sortable.js.flow +1 -1
- package/dist/components/tex-buttons.d.ts +3 -3
- package/dist/components/tex-buttons.js.flow +3 -3
- package/dist/es/index.js +56 -61
- package/dist/es/index.js.map +1 -1
- package/dist/index.js +56 -60
- package/dist/index.js.map +1 -1
- package/dist/perseus-types.d.ts +1 -1
- package/dist/perseus-types.js.flow +1 -1
- package/dist/widgets/definition.d.ts +1 -1
- package/dist/widgets/definition.js.flow +1 -1
- package/dist/widgets/explanation.d.ts +1 -1
- package/dist/widgets/explanation.js.flow +1 -1
- package/dist/widgets/expression.d.ts +2 -1
- package/dist/widgets/expression.js.flow +2 -1
- package/package.json +2 -2
- package/src/__tests__/item-renderer.test.tsx +1 -1
- package/src/components/__tests__/sortable.test.tsx +0 -3
- package/src/components/math-input.tsx +27 -1
- package/src/components/sortable.tsx +6 -4
- package/src/components/tex-buttons.tsx +27 -77
- package/src/perseus-types.ts +1 -1
- package/src/widgets/definition.tsx +1 -1
- package/src/widgets/explanation.tsx +1 -1
- package/src/widgets/expression.tsx +4 -4
- package/tsconfig-build.tsbuildinfo +1 -1
package/dist/perseus-types.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { Coord } from "./interactive2/types";
|
|
2
2
|
export type Range = [number, number];
|
|
3
3
|
export type Size = [number, number];
|
|
4
|
-
type Empty = Record<
|
|
4
|
+
type Empty = Record<never, never>;
|
|
5
5
|
export type PerseusItem = {
|
|
6
6
|
question: PerseusRenderer;
|
|
7
7
|
hints: ReadonlyArray<PerseusRenderer>;
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
import type { Coord } from "./interactive2/types";
|
|
8
8
|
export type Range = [number, number];
|
|
9
9
|
export type Size = [number, number];
|
|
10
|
-
declare type Empty = { [key:
|
|
10
|
+
declare type Empty = { [key: empty]: empty };
|
|
11
11
|
export type PerseusItem = {|
|
|
12
12
|
question: PerseusRenderer,
|
|
13
13
|
hints: $ReadOnlyArray<PerseusRenderer>,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
2
|
import type { PerseusRenderer, PerseusDefinitionWidgetOptions } from "../perseus-types";
|
|
3
3
|
import type { PerseusScore, WidgetProps } from "../types";
|
|
4
|
-
type Empty = Record<
|
|
4
|
+
type Empty = Record<never, never>;
|
|
5
5
|
type RenderProps = PerseusDefinitionWidgetOptions;
|
|
6
6
|
type Rubric = PerseusDefinitionWidgetOptions;
|
|
7
7
|
type UserInput = Empty;
|
|
@@ -11,7 +11,7 @@ import type {
|
|
|
11
11
|
PerseusDefinitionWidgetOptions,
|
|
12
12
|
} from "../perseus-types";
|
|
13
13
|
import type { PerseusScore, WidgetProps } from "../types";
|
|
14
|
-
declare type Empty = { [key:
|
|
14
|
+
declare type Empty = { [key: empty]: empty };
|
|
15
15
|
declare type RenderProps = PerseusDefinitionWidgetOptions;
|
|
16
16
|
declare type Rubric = PerseusDefinitionWidgetOptions;
|
|
17
17
|
declare type UserInput = Empty;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
2
|
import type { PerseusExplanationWidgetOptions } from "../perseus-types";
|
|
3
3
|
import type { PerseusScore, WidgetProps } from "../types";
|
|
4
|
-
type Empty = Record<
|
|
4
|
+
type Empty = Record<never, never>;
|
|
5
5
|
type RenderProps = PerseusExplanationWidgetOptions;
|
|
6
6
|
type Rubric = PerseusExplanationWidgetOptions;
|
|
7
7
|
type UserInput = Empty;
|
|
@@ -8,7 +8,7 @@ import * as $Flowgen$Import$_2e__2e__2f_types from "../types";
|
|
|
8
8
|
import * as React from "react";
|
|
9
9
|
import type { PerseusExplanationWidgetOptions } from "../perseus-types";
|
|
10
10
|
import type { PerseusScore, WidgetProps } from "../types";
|
|
11
|
-
declare type Empty = { [key:
|
|
11
|
+
declare type Empty = { [key: empty]: empty };
|
|
12
12
|
declare type RenderProps = PerseusExplanationWidgetOptions;
|
|
13
13
|
declare type Rubric = PerseusExplanationWidgetOptions;
|
|
14
14
|
declare type UserInput = Empty;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { Keys as Key } from "@khanacademy/math-input";
|
|
1
2
|
import * as React from "react";
|
|
2
3
|
import type { PerseusExpressionWidgetOptions } from "../perseus-types";
|
|
3
4
|
import type { PerseusScore, WidgetProps } from "../types";
|
|
@@ -51,7 +52,7 @@ export declare class Expression extends React.Component<Props, ExpressionState>
|
|
|
51
52
|
focus: () => boolean;
|
|
52
53
|
focusInputPath: (inputPath: InputPath) => void;
|
|
53
54
|
blurInputPath: (inputPath: InputPath) => void;
|
|
54
|
-
insert
|
|
55
|
+
insert(keyPressed: Key): void;
|
|
55
56
|
getInputPaths: () => ReadonlyArray<ReadonlyArray<any>>;
|
|
56
57
|
getGrammarTypeForPath: (inputPath: string) => string;
|
|
57
58
|
setInputValue: (path: string, newValue: string, cb: () => void) => void;
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
* @flow
|
|
6
6
|
*/
|
|
7
7
|
import * as $Flowgen$Import$_2e__2e__2f_types from "../types";
|
|
8
|
+
import { Keys as Key } from "@khanacademy/math-input";
|
|
8
9
|
import * as React from "react";
|
|
9
10
|
import type { PerseusExpressionWidgetOptions } from "../perseus-types";
|
|
10
11
|
import type { PerseusScore, WidgetProps } from "../types";
|
|
@@ -74,7 +75,7 @@ declare export class Expression
|
|
|
74
75
|
focus: () => boolean;
|
|
75
76
|
focusInputPath: (inputPath: InputPath) => void;
|
|
76
77
|
blurInputPath: (inputPath: InputPath) => void;
|
|
77
|
-
insert
|
|
78
|
+
insert(keyPressed: Key): void;
|
|
78
79
|
getInputPaths: () => $ReadOnlyArray<$ReadOnlyArray<any>>;
|
|
79
80
|
getGrammarTypeForPath: (inputPath: string) => string;
|
|
80
81
|
setInputValue: (path: string, newValue: string, cb: () => void) => void;
|
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"description": "Core Perseus API (includes renderers and widgets)",
|
|
4
4
|
"author": "Khan Academy",
|
|
5
5
|
"license": "MIT",
|
|
6
|
-
"version": "6.1
|
|
6
|
+
"version": "6.2.1",
|
|
7
7
|
"publishConfig": {
|
|
8
8
|
"access": "public"
|
|
9
9
|
},
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
"dependencies": {
|
|
24
24
|
"@khanacademy/kas": "^0.3.1",
|
|
25
25
|
"@khanacademy/kmath": "^0.1.1",
|
|
26
|
-
"@khanacademy/math-input": "^
|
|
26
|
+
"@khanacademy/math-input": "^4.1.0",
|
|
27
27
|
"@khanacademy/perseus-linter": "^0.3.1",
|
|
28
28
|
"@khanacademy/pure-markdown": "^0.2.3",
|
|
29
29
|
"@khanacademy/simple-markdown": "^0.9.3",
|
|
@@ -2,7 +2,7 @@ import {RenderStateRoot} from "@khanacademy/wonder-blocks-core";
|
|
|
2
2
|
import {fireEvent, render, screen} from "@testing-library/react";
|
|
3
3
|
import userEvent from "@testing-library/user-event";
|
|
4
4
|
import * as React from "react";
|
|
5
|
-
import "@testing-library/jest-dom"; // Imports custom
|
|
5
|
+
import "@testing-library/jest-dom"; // Imports custom matchers
|
|
6
6
|
|
|
7
7
|
import {testDependencies} from "../../../../testing/test-dependencies";
|
|
8
8
|
import {
|
|
@@ -181,7 +181,6 @@ describe("Sortable.itemsFromProps", () => {
|
|
|
181
181
|
expect(items).toMatchInlineSnapshot(`
|
|
182
182
|
[
|
|
183
183
|
{
|
|
184
|
-
"endPosition": {},
|
|
185
184
|
"height": 0,
|
|
186
185
|
"key": 0,
|
|
187
186
|
"option": "a",
|
|
@@ -189,7 +188,6 @@ describe("Sortable.itemsFromProps", () => {
|
|
|
189
188
|
"width": 0,
|
|
190
189
|
},
|
|
191
190
|
{
|
|
192
|
-
"endPosition": {},
|
|
193
191
|
"height": 0,
|
|
194
192
|
"key": 1,
|
|
195
193
|
"option": "b",
|
|
@@ -197,7 +195,6 @@ describe("Sortable.itemsFromProps", () => {
|
|
|
197
195
|
"width": 0,
|
|
198
196
|
},
|
|
199
197
|
{
|
|
200
|
-
"endPosition": {},
|
|
201
198
|
"height": 0,
|
|
202
199
|
"key": 2,
|
|
203
200
|
"option": "c",
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import {keyTranslator} from "@khanacademy/math-input";
|
|
1
2
|
import classNames from "classnames";
|
|
2
3
|
import $ from "jquery";
|
|
3
4
|
import MathQuill from "mathquill";
|
|
@@ -33,6 +34,20 @@ type State = {
|
|
|
33
34
|
focused: boolean;
|
|
34
35
|
};
|
|
35
36
|
|
|
37
|
+
const customKeyTranslator = {
|
|
38
|
+
...keyTranslator,
|
|
39
|
+
// If there's something in the input that can become part of a
|
|
40
|
+
// fraction, typing "/" puts it in the numerator. If not, typing
|
|
41
|
+
// "/" does nothing. In that case, enter a \frac.
|
|
42
|
+
FRAC: (mathQuill) => {
|
|
43
|
+
const contents = mathQuill.latex();
|
|
44
|
+
mathQuill.typedText("/");
|
|
45
|
+
if (mathQuill.latex() === contents) {
|
|
46
|
+
mathQuill.cmd("\\frac");
|
|
47
|
+
}
|
|
48
|
+
},
|
|
49
|
+
};
|
|
50
|
+
|
|
36
51
|
// A WYSIWYG math input that calls `onChange(LaTeX-string)`
|
|
37
52
|
class MathInput extends React.Component<Props, State> {
|
|
38
53
|
// @ts-expect-error [FEI-5003] - TS2564 - Property 'mouseDown' has no initializer and is not definitely assigned in the constructor.
|
|
@@ -208,9 +223,20 @@ class MathInput extends React.Component<Props, State> {
|
|
|
208
223
|
return this.state.focused;
|
|
209
224
|
};
|
|
210
225
|
|
|
211
|
-
insert: (
|
|
226
|
+
insert: (value: any) => void = (value) => {
|
|
212
227
|
// @ts-expect-error [FEI-5003] - TS2554 - Expected 1 arguments, but got 0.
|
|
213
228
|
const input = this.mathField();
|
|
229
|
+
const inputModifier = customKeyTranslator[value];
|
|
230
|
+
if (inputModifier) {
|
|
231
|
+
inputModifier(input, value);
|
|
232
|
+
input.focus();
|
|
233
|
+
return;
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
// note(Matthew): I'm not sure this is still being used
|
|
237
|
+
// but it fails tests when I remove it and the way we call
|
|
238
|
+
// methods directly on components makes it difficult to confirm
|
|
239
|
+
// if it's dead code
|
|
214
240
|
if (_(value).isFunction()) {
|
|
215
241
|
value(input);
|
|
216
242
|
} else if (value[0] === "\\") {
|
|
@@ -72,7 +72,7 @@ class Placeholder extends React.Component<PlaceholderProps> {
|
|
|
72
72
|
|
|
73
73
|
type DraggableProps = {
|
|
74
74
|
content: string;
|
|
75
|
-
endPosition
|
|
75
|
+
endPosition?: {left: number; top: number};
|
|
76
76
|
includePadding: boolean;
|
|
77
77
|
layout: Layout;
|
|
78
78
|
width?: number;
|
|
@@ -251,7 +251,10 @@ class Draggable extends React.Component<DraggableProps, DraggableState> {
|
|
|
251
251
|
return;
|
|
252
252
|
}
|
|
253
253
|
|
|
254
|
-
if (
|
|
254
|
+
if (
|
|
255
|
+
this.props.state === ItemState.ANIMATING &&
|
|
256
|
+
this.props.endPosition
|
|
257
|
+
) {
|
|
255
258
|
// Start animating
|
|
256
259
|
const current = this.getCurrentPosition();
|
|
257
260
|
const duration =
|
|
@@ -433,7 +436,7 @@ type SortableItem = {
|
|
|
433
436
|
option: SortableOption;
|
|
434
437
|
key: number;
|
|
435
438
|
state: ItemState;
|
|
436
|
-
endPosition
|
|
439
|
+
endPosition?: Position;
|
|
437
440
|
width: number;
|
|
438
441
|
height: number;
|
|
439
442
|
};
|
|
@@ -513,7 +516,6 @@ class Sortable extends React.Component<SortableProps, SortableState> {
|
|
|
513
516
|
option: option,
|
|
514
517
|
key: i,
|
|
515
518
|
state,
|
|
516
|
-
endPosition: {},
|
|
517
519
|
width: 0,
|
|
518
520
|
height: 0,
|
|
519
521
|
};
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import {Keys} from "@khanacademy/math-input";
|
|
1
2
|
import * as i18n from "@khanacademy/wonder-blocks-i18n";
|
|
2
3
|
import PropTypes from "prop-types";
|
|
3
4
|
import * as React from "react";
|
|
@@ -9,8 +10,7 @@ const prettyBig = {fontSize: "150%"} as const;
|
|
|
9
10
|
const slightlyBig = {fontSize: "120%"} as const;
|
|
10
11
|
const symbStyle = {fontSize: "130%"} as const;
|
|
11
12
|
|
|
12
|
-
type
|
|
13
|
-
type ButtonSet = (props: any) => [React.ReactNode, Inserter];
|
|
13
|
+
type ButtonSet = (props: any) => [React.ReactNode, Keys];
|
|
14
14
|
|
|
15
15
|
type ButtonSets = {
|
|
16
16
|
readonly [key: string]: ReadonlyArray<ButtonSet>;
|
|
@@ -26,13 +26,13 @@ const basic: ReadonlyArray<ButtonSet> = [
|
|
|
26
26
|
<span key="plus" style={slightlyBig}>
|
|
27
27
|
+
|
|
28
28
|
</span>,
|
|
29
|
-
"
|
|
29
|
+
"PLUS",
|
|
30
30
|
],
|
|
31
31
|
() => [
|
|
32
32
|
<span key="minus" style={prettyBig}>
|
|
33
33
|
-
|
|
34
34
|
</span>,
|
|
35
|
-
"
|
|
35
|
+
"MINUS",
|
|
36
36
|
],
|
|
37
37
|
|
|
38
38
|
// TODO(joel) - display as \cdot when appropriate
|
|
@@ -43,14 +43,14 @@ const basic: ReadonlyArray<ButtonSet> = [
|
|
|
43
43
|
<TeX key="times" style={prettyBig}>
|
|
44
44
|
{i18n.doNotTranslate("\\times")}
|
|
45
45
|
</TeX>,
|
|
46
|
-
"
|
|
46
|
+
"TIMES",
|
|
47
47
|
];
|
|
48
48
|
}
|
|
49
49
|
return [
|
|
50
50
|
<TeX key="times" style={prettyBig}>
|
|
51
51
|
{i18n.doNotTranslate("\\cdot")}
|
|
52
52
|
</TeX>,
|
|
53
|
-
"
|
|
53
|
+
"CDOT",
|
|
54
54
|
];
|
|
55
55
|
},
|
|
56
56
|
() => {
|
|
@@ -59,17 +59,7 @@ const basic: ReadonlyArray<ButtonSet> = [
|
|
|
59
59
|
<TeX key="frac" style={prettyBig}>
|
|
60
60
|
{i18n.doNotTranslate("\\frac{x}{y}")}
|
|
61
61
|
</TeX>,
|
|
62
|
-
|
|
63
|
-
// If there's something in the input that can become part of a
|
|
64
|
-
// fraction, typing "/" puts it in the numerator. If not, typing
|
|
65
|
-
// "/" does nothing. In that case, enter a \frac.
|
|
66
|
-
(input: any) => {
|
|
67
|
-
const contents = input.latex();
|
|
68
|
-
input.typedText("/");
|
|
69
|
-
if (input.latex() === contents) {
|
|
70
|
-
input.cmd("\\frac");
|
|
71
|
-
}
|
|
72
|
-
},
|
|
62
|
+
"FRAC",
|
|
73
63
|
];
|
|
74
64
|
},
|
|
75
65
|
];
|
|
@@ -82,7 +72,7 @@ const buttonSets: ButtonSets = {
|
|
|
82
72
|
const {TeX} = getDependencies();
|
|
83
73
|
return [
|
|
84
74
|
<TeX key="div">{i18n.doNotTranslate("\\div")}</TeX>,
|
|
85
|
-
"
|
|
75
|
+
"DIVIDE",
|
|
86
76
|
];
|
|
87
77
|
},
|
|
88
78
|
]),
|
|
@@ -90,24 +80,15 @@ const buttonSets: ButtonSets = {
|
|
|
90
80
|
trig: [
|
|
91
81
|
() => {
|
|
92
82
|
const {TeX} = getDependencies();
|
|
93
|
-
return [
|
|
94
|
-
<TeX key="sin">{i18n.doNotTranslate("\\sin")}</TeX>,
|
|
95
|
-
"\\sin",
|
|
96
|
-
];
|
|
83
|
+
return [<TeX key="sin">{i18n.doNotTranslate("\\sin")}</TeX>, "SIN"];
|
|
97
84
|
},
|
|
98
85
|
() => {
|
|
99
86
|
const {TeX} = getDependencies();
|
|
100
|
-
return [
|
|
101
|
-
<TeX key="cos">{i18n.doNotTranslate("\\cos")}</TeX>,
|
|
102
|
-
"\\cos",
|
|
103
|
-
];
|
|
87
|
+
return [<TeX key="cos">{i18n.doNotTranslate("\\cos")}</TeX>, "COS"];
|
|
104
88
|
},
|
|
105
89
|
() => {
|
|
106
90
|
const {TeX} = getDependencies();
|
|
107
|
-
return [
|
|
108
|
-
<TeX key="tan">{i18n.doNotTranslate("\\tan")}</TeX>,
|
|
109
|
-
"\\tan",
|
|
110
|
-
];
|
|
91
|
+
return [<TeX key="tan">{i18n.doNotTranslate("\\tan")}</TeX>, "TAN"];
|
|
111
92
|
},
|
|
112
93
|
() => {
|
|
113
94
|
const {TeX} = getDependencies();
|
|
@@ -115,7 +96,7 @@ const buttonSets: ButtonSets = {
|
|
|
115
96
|
<TeX key="theta" style={symbStyle}>
|
|
116
97
|
{i18n.doNotTranslate("\\theta")}
|
|
117
98
|
</TeX>,
|
|
118
|
-
"
|
|
99
|
+
"THETA",
|
|
119
100
|
];
|
|
120
101
|
},
|
|
121
102
|
() => {
|
|
@@ -130,7 +111,7 @@ const buttonSets: ButtonSets = {
|
|
|
130
111
|
{i18n.doNotTranslate("\\phi")}
|
|
131
112
|
</TeX>
|
|
132
113
|
</span>,
|
|
133
|
-
"
|
|
114
|
+
"PHI",
|
|
134
115
|
];
|
|
135
116
|
},
|
|
136
117
|
],
|
|
@@ -140,7 +121,7 @@ const buttonSets: ButtonSets = {
|
|
|
140
121
|
const {TeX} = getDependencies();
|
|
141
122
|
return [
|
|
142
123
|
<TeX key="sqrt">{i18n.doNotTranslate("\\sqrt{x}")}</TeX>,
|
|
143
|
-
"
|
|
124
|
+
"SQRT",
|
|
144
125
|
];
|
|
145
126
|
},
|
|
146
127
|
// TODO(joel) - how does desmos do this?
|
|
@@ -148,10 +129,7 @@ const buttonSets: ButtonSets = {
|
|
|
148
129
|
const {TeX} = getDependencies();
|
|
149
130
|
return [
|
|
150
131
|
<TeX key="nthroot">{i18n.doNotTranslate("\\sqrt[3]{x}")}</TeX>,
|
|
151
|
-
|
|
152
|
-
input.typedText("nthroot3");
|
|
153
|
-
input.keystroke("Right");
|
|
154
|
-
},
|
|
132
|
+
"NTHROOT3",
|
|
155
133
|
];
|
|
156
134
|
},
|
|
157
135
|
() => {
|
|
@@ -160,17 +138,7 @@ const buttonSets: ButtonSets = {
|
|
|
160
138
|
<TeX key="pow" style={slightlyBig}>
|
|
161
139
|
{i18n.doNotTranslate("a^b")}
|
|
162
140
|
</TeX>,
|
|
163
|
-
|
|
164
|
-
const contents = input.latex();
|
|
165
|
-
input.typedText("^");
|
|
166
|
-
|
|
167
|
-
// If the input hasn't changed (for example, if we're
|
|
168
|
-
// attempting to add an exponent on an empty input or an empty
|
|
169
|
-
// denominator), insert our own "a^b"
|
|
170
|
-
if (input.latex() === contents) {
|
|
171
|
-
input.typedText("a^b");
|
|
172
|
-
}
|
|
173
|
-
},
|
|
141
|
+
"POW",
|
|
174
142
|
];
|
|
175
143
|
},
|
|
176
144
|
() => {
|
|
@@ -179,7 +147,7 @@ const buttonSets: ButtonSets = {
|
|
|
179
147
|
<TeX key="pi" style={slightlyBig}>
|
|
180
148
|
{i18n.doNotTranslate("\\pi")}
|
|
181
149
|
</TeX>,
|
|
182
|
-
"
|
|
150
|
+
"PI",
|
|
183
151
|
];
|
|
184
152
|
},
|
|
185
153
|
],
|
|
@@ -187,26 +155,17 @@ const buttonSets: ButtonSets = {
|
|
|
187
155
|
logarithms: [
|
|
188
156
|
() => {
|
|
189
157
|
const {TeX} = getDependencies();
|
|
190
|
-
return [
|
|
191
|
-
<TeX key="log">{i18n.doNotTranslate("\\log")}</TeX>,
|
|
192
|
-
"\\log",
|
|
193
|
-
];
|
|
158
|
+
return [<TeX key="log">{i18n.doNotTranslate("\\log")}</TeX>, "LOG"];
|
|
194
159
|
},
|
|
195
160
|
() => {
|
|
196
161
|
const {TeX} = getDependencies();
|
|
197
|
-
return [<TeX key="ln">{i18n.doNotTranslate("\\ln")}</TeX>, "
|
|
162
|
+
return [<TeX key="ln">{i18n.doNotTranslate("\\ln")}</TeX>, "LN"];
|
|
198
163
|
},
|
|
199
164
|
() => {
|
|
200
165
|
const {TeX} = getDependencies();
|
|
201
166
|
return [
|
|
202
167
|
<TeX key="log_b">{i18n.doNotTranslate("\\log_b")}</TeX>,
|
|
203
|
-
|
|
204
|
-
input.typedText("log_");
|
|
205
|
-
input.keystroke("Right");
|
|
206
|
-
input.typedText("(");
|
|
207
|
-
input.keystroke("Left");
|
|
208
|
-
input.keystroke("Left");
|
|
209
|
-
},
|
|
168
|
+
"LOG_B",
|
|
210
169
|
];
|
|
211
170
|
},
|
|
212
171
|
],
|
|
@@ -214,39 +173,30 @@ const buttonSets: ButtonSets = {
|
|
|
214
173
|
"basic relations": [
|
|
215
174
|
() => {
|
|
216
175
|
const {TeX} = getDependencies();
|
|
217
|
-
return [<TeX key="eq">{"="}</TeX>, "
|
|
176
|
+
return [<TeX key="eq">{"="}</TeX>, "EQUAL"];
|
|
218
177
|
},
|
|
219
178
|
() => {
|
|
220
179
|
const {TeX} = getDependencies();
|
|
221
|
-
return [<TeX key="lt">{i18n.doNotTranslate("\\lt")}</TeX>, "
|
|
180
|
+
return [<TeX key="lt">{i18n.doNotTranslate("\\lt")}</TeX>, "LT"];
|
|
222
181
|
},
|
|
223
182
|
() => {
|
|
224
183
|
const {TeX} = getDependencies();
|
|
225
|
-
return [<TeX key="gt">{i18n.doNotTranslate("\\gt")}</TeX>, "
|
|
184
|
+
return [<TeX key="gt">{i18n.doNotTranslate("\\gt")}</TeX>, "GT"];
|
|
226
185
|
},
|
|
227
186
|
],
|
|
228
187
|
|
|
229
188
|
"advanced relations": [
|
|
230
189
|
() => {
|
|
231
190
|
const {TeX} = getDependencies();
|
|
232
|
-
return [
|
|
233
|
-
<TeX key="neq">{i18n.doNotTranslate("\\neq")}</TeX>,
|
|
234
|
-
"\\neq",
|
|
235
|
-
];
|
|
191
|
+
return [<TeX key="neq">{i18n.doNotTranslate("\\neq")}</TeX>, "NEQ"];
|
|
236
192
|
},
|
|
237
193
|
() => {
|
|
238
194
|
const {TeX} = getDependencies();
|
|
239
|
-
return [
|
|
240
|
-
<TeX key="leq">{i18n.doNotTranslate("\\leq")}</TeX>,
|
|
241
|
-
"\\leq",
|
|
242
|
-
];
|
|
195
|
+
return [<TeX key="leq">{i18n.doNotTranslate("\\leq")}</TeX>, "LEQ"];
|
|
243
196
|
},
|
|
244
197
|
() => {
|
|
245
198
|
const {TeX} = getDependencies();
|
|
246
|
-
return [
|
|
247
|
-
<TeX key="geq">{i18n.doNotTranslate("\\geq")}</TeX>,
|
|
248
|
-
"\\geq",
|
|
249
|
-
];
|
|
199
|
+
return [<TeX key="geq">{i18n.doNotTranslate("\\geq")}</TeX>, "GEQ"];
|
|
250
200
|
},
|
|
251
201
|
],
|
|
252
202
|
};
|
|
@@ -255,7 +205,7 @@ export type ButtonSetsType = ReadonlyArray<keyof typeof buttonSets>;
|
|
|
255
205
|
|
|
256
206
|
type Props = {
|
|
257
207
|
sets: ButtonSetsType;
|
|
258
|
-
onInsert: (
|
|
208
|
+
onInsert: (key: Keys) => void;
|
|
259
209
|
className?: string;
|
|
260
210
|
convertDotToTimes?: boolean;
|
|
261
211
|
};
|
package/src/perseus-types.ts
CHANGED
|
@@ -7,7 +7,7 @@ export type Range = [number, number];
|
|
|
7
7
|
export type Size = [number, number];
|
|
8
8
|
|
|
9
9
|
// TODO(FEI-5054): Figure out how to get global .d.ts files working with monorepos
|
|
10
|
-
type Empty = Record<
|
|
10
|
+
type Empty = Record<never, never>;
|
|
11
11
|
|
|
12
12
|
export type PerseusItem = {
|
|
13
13
|
// The details of the question being asked to the user.
|
|
@@ -13,7 +13,7 @@ import type {
|
|
|
13
13
|
import type {PerseusScore, WidgetExports, WidgetProps} from "../types";
|
|
14
14
|
|
|
15
15
|
// TODO(FEI-5054): Figure out how to get global .d.ts files working with monorepos
|
|
16
|
-
type Empty = Record<
|
|
16
|
+
type Empty = Record<never, never>;
|
|
17
17
|
|
|
18
18
|
type RenderProps = PerseusDefinitionWidgetOptions;
|
|
19
19
|
|
|
@@ -13,7 +13,7 @@ import type {PerseusExplanationWidgetOptions} from "../perseus-types";
|
|
|
13
13
|
import type {PerseusScore, WidgetExports, WidgetProps} from "../types";
|
|
14
14
|
|
|
15
15
|
// TODO(FEI-5054): Figure out how to get global .d.ts files working with monorepos
|
|
16
|
-
type Empty = Record<
|
|
16
|
+
type Empty = Record<never, never>;
|
|
17
17
|
|
|
18
18
|
type RenderProps = PerseusExplanationWidgetOptions; // transform = _.identity
|
|
19
19
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/* eslint-disable react/prop-types */
|
|
2
2
|
import * as KAS from "@khanacademy/kas";
|
|
3
|
-
import {KeypadInput, KeypadType} from "@khanacademy/math-input";
|
|
3
|
+
import {KeypadInput, KeypadType, Keys as Key} from "@khanacademy/math-input";
|
|
4
4
|
import {linterContextDefault} from "@khanacademy/perseus-linter";
|
|
5
5
|
import * as i18n from "@khanacademy/wonder-blocks-i18n";
|
|
6
6
|
import classNames from "classnames";
|
|
@@ -413,11 +413,11 @@ export class Expression extends React.Component<Props, ExpressionState> {
|
|
|
413
413
|
};
|
|
414
414
|
|
|
415
415
|
// HACK(joel)
|
|
416
|
-
insert
|
|
416
|
+
insert(keyPressed: Key) {
|
|
417
417
|
// eslint-disable-next-line react/no-string-refs
|
|
418
418
|
// @ts-expect-error [FEI-5003] - TS2339 - Property 'insert' does not exist on type 'ReactInstance'.
|
|
419
|
-
this.refs.input.insert(
|
|
420
|
-
}
|
|
419
|
+
this.refs.input.insert(keyPressed);
|
|
420
|
+
}
|
|
421
421
|
|
|
422
422
|
getInputPaths: () => ReadonlyArray<ReadonlyArray<any>> = () => {
|
|
423
423
|
// The widget itself is an input, so we return a single empty list to
|