@khanacademy/perseus 44.0.0 → 45.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/dist/components/text-input.d.ts +1 -0
- package/dist/es/index.css +169 -12
- package/dist/es/index.js +473 -286
- package/dist/es/index.js.map +1 -1
- package/dist/index.css +169 -12
- package/dist/index.d.ts +3 -1
- package/dist/index.js +475 -281
- package/dist/index.js.map +1 -1
- package/dist/interactive2/objective_.d.ts +27 -6
- package/dist/perseus-types.d.ts +123 -72
- package/dist/renderer-util.d.ts +4 -2
- package/dist/renderer.d.ts +13 -11
- package/dist/server-item-renderer.d.ts +32 -1
- package/dist/types.d.ts +63 -16
- package/dist/util/parse-perseus-json/general-purpose-parsers/string-to-number.d.ts +2 -0
- package/dist/validation.types.d.ts +8 -3
- package/dist/widgets/deprecated-standin/deprecated-standin.d.ts +1 -1
- package/dist/widgets/expression/expression.d.ts +1 -1
- package/dist/widgets/group/group.d.ts +3 -1
- package/dist/widgets/group/score-group.d.ts +5 -0
- package/dist/widgets/interactive-graph.d.ts +96 -3
- package/dist/widgets/interactive-graphs/mafs-graph.d.ts +2 -2
- package/dist/widgets/interactive-graphs/stateful-mafs-graph.d.ts +3 -3
- package/dist/widgets/number-line/score-number-line.d.ts +2 -2
- package/dist/widgets/number-line/validate-number-line.d.ts +12 -0
- package/dist/widgets/numeric-input/numeric-input.d.ts +2 -1
- package/package.json +1 -1
|
@@ -5,9 +5,30 @@
|
|
|
5
5
|
*
|
|
6
6
|
* TODO(aria): Move this out of interactive2
|
|
7
7
|
*/
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
8
|
+
/**
|
|
9
|
+
* Does a pluck on keys inside objects in an object
|
|
10
|
+
*
|
|
11
|
+
* Ex:
|
|
12
|
+
* tools = {
|
|
13
|
+
* translation: {
|
|
14
|
+
* enabled: true
|
|
15
|
+
* },
|
|
16
|
+
* rotation: {
|
|
17
|
+
* enabled: false
|
|
18
|
+
* }
|
|
19
|
+
* };
|
|
20
|
+
* pluckObject(tools, "enabled") returns {
|
|
21
|
+
* translation: true
|
|
22
|
+
* rotation: false
|
|
23
|
+
* }
|
|
24
|
+
*/
|
|
25
|
+
export declare const pluck: (table: any, subKey: string) => any;
|
|
26
|
+
/**
|
|
27
|
+
* Maps an object to an object
|
|
28
|
+
*
|
|
29
|
+
* > mapObject({a: '1', b: '2'}, (value, key) => {
|
|
30
|
+
* return value + 1;
|
|
31
|
+
* });
|
|
32
|
+
* {a: 2, b: 3}
|
|
33
|
+
*/
|
|
34
|
+
export declare const mapObject: <K extends string, V, U>(obj: Record<K, V>, lambda: (arg1: V, arg2: K) => U) => Record<K, U>;
|
package/dist/perseus-types.d.ts
CHANGED
|
@@ -4,72 +4,99 @@ export type Range = Interval;
|
|
|
4
4
|
export type Size = [number, number];
|
|
5
5
|
export type CollinearTuple = [vec.Vector2, vec.Vector2];
|
|
6
6
|
export type ShowSolutions = "all" | "selected" | "none";
|
|
7
|
+
/**
|
|
8
|
+
* Our core set of Perseus widgets.
|
|
9
|
+
*
|
|
10
|
+
* This interface is the basis for "registering" all Perseus widget types.
|
|
11
|
+
* There should be one key/value pair for each supported widget. If you create
|
|
12
|
+
* a new widget, an entry should be added to this interface. Note that this
|
|
13
|
+
* only registers the widget options type, you'll also need to register the
|
|
14
|
+
* widget so that it's available at runtime (@see
|
|
15
|
+
* {@link file://./widgets.ts#registerWidget}).
|
|
16
|
+
*
|
|
17
|
+
* Importantly, the key should be the name that is used in widget IDs. For most
|
|
18
|
+
* widgets that is the same as the widget option's `type` field. In cases where
|
|
19
|
+
* a widget has been deprecated and replaced with the deprecated-standin
|
|
20
|
+
* widget, it should be the original widget type!
|
|
21
|
+
*
|
|
22
|
+
* If you define the widget outside of this package, you can still add the new
|
|
23
|
+
* widget to this interface by writing the following in that package that
|
|
24
|
+
* contains the widget. TypeScript will merge that definition of the
|
|
25
|
+
* `PerseusWidgets` with the one defined below.
|
|
26
|
+
*
|
|
27
|
+
* ```typescript
|
|
28
|
+
* declare module "@khanacademy/perseus" {
|
|
29
|
+
* interface PerseusWidgetTypes {
|
|
30
|
+
* // A new widget
|
|
31
|
+
* "new-awesomeness": MyAwesomeNewWidget;
|
|
32
|
+
*
|
|
33
|
+
* // A deprecated widget
|
|
34
|
+
* "super-old-widget": AutoCorrectWidget;
|
|
35
|
+
* }
|
|
36
|
+
* }
|
|
37
|
+
*
|
|
38
|
+
* // The new widget's options definition
|
|
39
|
+
* type MyAwesomeNewWidget = WidgetOptions<'new-awesomeness', MyAwesomeNewWidgetOptions>;
|
|
40
|
+
*
|
|
41
|
+
* // The deprecated widget's options definition
|
|
42
|
+
* type SuperOldWidget = WidgetOptions<'super-old-widget', object>;
|
|
43
|
+
* ```
|
|
44
|
+
*
|
|
45
|
+
* This interface can be extended through the magic of TypeScript "Declaration
|
|
46
|
+
* merging". Specifically, we augment this module and extend this interface.
|
|
47
|
+
*
|
|
48
|
+
* @see {@link https://www.typescriptlang.org/docs/handbook/declaration-merging.html#module-augmentation}
|
|
49
|
+
*/
|
|
50
|
+
export interface PerseusWidgetTypes {
|
|
51
|
+
categorizer: CategorizerWidget;
|
|
52
|
+
"cs-program": CSProgramWidget;
|
|
53
|
+
definition: DefinitionWidget;
|
|
54
|
+
dropdown: DropdownWidget;
|
|
55
|
+
explanation: ExplanationWidget;
|
|
56
|
+
expression: ExpressionWidget;
|
|
57
|
+
grapher: GrapherWidget;
|
|
58
|
+
"graded-group-set": GradedGroupSetWidget;
|
|
59
|
+
"graded-group": GradedGroupWidget;
|
|
60
|
+
group: GroupWidget;
|
|
61
|
+
iframe: IFrameWidget;
|
|
62
|
+
image: ImageWidget;
|
|
63
|
+
"input-number": InputNumberWidget;
|
|
64
|
+
interaction: InteractionWidget;
|
|
65
|
+
"interactive-graph": InteractiveGraphWidget;
|
|
66
|
+
"label-image": LabelImageWidget;
|
|
67
|
+
matcher: MatcherWidget;
|
|
68
|
+
matrix: MatrixWidget;
|
|
69
|
+
measurer: MeasurerWidget;
|
|
70
|
+
"molecule-renderer": MoleculeRendererWidget;
|
|
71
|
+
"number-line": NumberLineWidget;
|
|
72
|
+
"numeric-input": NumericInputWidget;
|
|
73
|
+
orderer: OrdererWidget;
|
|
74
|
+
"passage-ref-target": RefTargetWidget;
|
|
75
|
+
"passage-ref": PassageRefWidget;
|
|
76
|
+
passage: PassageWidget;
|
|
77
|
+
"phet-simulation": PhetSimulationWidget;
|
|
78
|
+
"python-program": PythonProgramWidget;
|
|
79
|
+
plotter: PlotterWidget;
|
|
80
|
+
radio: RadioWidget;
|
|
81
|
+
sorter: SorterWidget;
|
|
82
|
+
table: TableWidget;
|
|
83
|
+
video: VideoWidget;
|
|
84
|
+
sequence: AutoCorrectWidget;
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* A map of widget IDs to widget options. This is most often used as the type
|
|
88
|
+
* for a set of widgets defined in a `PerseusItem` but can also be useful to
|
|
89
|
+
* represent a function parameter where only `widgets` from a `PerseusItem` are
|
|
90
|
+
* needed. Today Widget IDs are made up of the widget type and an incrementing
|
|
91
|
+
* integer (eg. `interactive-graph 1` or `radio 3`). It is suggested to avoid
|
|
92
|
+
* reading/parsing the widget id to derive any information from it, except in
|
|
93
|
+
* the case of this map.
|
|
94
|
+
*
|
|
95
|
+
* @see {@link PerseusWidgetTypes} additional widgets can be added to this map type
|
|
96
|
+
* by augmenting the PerseusWidgetTypes with new widget types!
|
|
97
|
+
*/
|
|
7
98
|
export type PerseusWidgetsMap = {
|
|
8
|
-
[
|
|
9
|
-
} & {
|
|
10
|
-
[key in `cs-program ${number}`]: CSProgramWidget;
|
|
11
|
-
} & {
|
|
12
|
-
[key in `definition ${number}`]: DefinitionWidget;
|
|
13
|
-
} & {
|
|
14
|
-
[key in `dropdown ${number}`]: DropdownWidget;
|
|
15
|
-
} & {
|
|
16
|
-
[key in `explanation ${number}`]: ExplanationWidget;
|
|
17
|
-
} & {
|
|
18
|
-
[key in `expression ${number}`]: ExpressionWidget;
|
|
19
|
-
} & {
|
|
20
|
-
[key in `grapher ${number}`]: GrapherWidget;
|
|
21
|
-
} & {
|
|
22
|
-
[key in `group ${number}`]: GroupWidget;
|
|
23
|
-
} & {
|
|
24
|
-
[key in `graded-group ${number}`]: GradedGroupWidget;
|
|
25
|
-
} & {
|
|
26
|
-
[key in `graded-group-set ${number}`]: GradedGroupSetWidget;
|
|
27
|
-
} & {
|
|
28
|
-
[key in `iframe ${number}`]: IFrameWidget;
|
|
29
|
-
} & {
|
|
30
|
-
[key in `image ${number}`]: ImageWidget;
|
|
31
|
-
} & {
|
|
32
|
-
[key in `input-number ${number}`]: InputNumberWidget;
|
|
33
|
-
} & {
|
|
34
|
-
[key in `interaction ${number}`]: InteractionWidget;
|
|
35
|
-
} & {
|
|
36
|
-
[key in `interactive-graph ${number}`]: InteractiveGraphWidget;
|
|
37
|
-
} & {
|
|
38
|
-
[key in `label-image ${number}`]: LabelImageWidget;
|
|
39
|
-
} & {
|
|
40
|
-
[key in `matcher ${number}`]: MatcherWidget;
|
|
41
|
-
} & {
|
|
42
|
-
[key in `matrix ${number}`]: MatrixWidget;
|
|
43
|
-
} & {
|
|
44
|
-
[key in `measurer ${number}`]: MeasurerWidget;
|
|
45
|
-
} & {
|
|
46
|
-
[key in `molecule-renderer ${number}`]: MoleculeRendererWidget;
|
|
47
|
-
} & {
|
|
48
|
-
[key in `number-line ${number}`]: NumberLineWidget;
|
|
49
|
-
} & {
|
|
50
|
-
[key in `numeric-input ${number}`]: NumericInputWidget;
|
|
51
|
-
} & {
|
|
52
|
-
[key in `orderer ${number}`]: OrdererWidget;
|
|
53
|
-
} & {
|
|
54
|
-
[key in `passage ${number}`]: PassageWidget;
|
|
55
|
-
} & {
|
|
56
|
-
[key in `passage-ref ${number}`]: PassageRefWidget;
|
|
57
|
-
} & {
|
|
58
|
-
[key in `passage-ref-target ${number}`]: PassageRefWidget;
|
|
59
|
-
} & {
|
|
60
|
-
[key in `phet-simulation ${number}`]: PhetSimulationWidget;
|
|
61
|
-
} & {
|
|
62
|
-
[key in `plotter ${number}`]: PlotterWidget;
|
|
63
|
-
} & {
|
|
64
|
-
[key in `python-program ${number}`]: PythonProgramWidget;
|
|
65
|
-
} & {
|
|
66
|
-
[key in `radio ${number}`]: RadioWidget;
|
|
67
|
-
} & {
|
|
68
|
-
[key in `sorter ${number}`]: SorterWidget;
|
|
69
|
-
} & {
|
|
70
|
-
[key in `table ${number}`]: TableWidget;
|
|
71
|
-
} & {
|
|
72
|
-
[key in `video ${number}`]: VideoWidget;
|
|
99
|
+
[Property in keyof PerseusWidgetTypes as `${Property} ${number}`]: PerseusWidgetTypes[Property];
|
|
73
100
|
};
|
|
74
101
|
/**
|
|
75
102
|
* A "PerseusItem" is a classic Perseus item. It is rendered by the
|
|
@@ -101,6 +128,9 @@ export type PerseusArticle = PerseusRenderer | ReadonlyArray<PerseusRenderer>;
|
|
|
101
128
|
* A "MultiItem" is an advanced Perseus item. It is rendered by the
|
|
102
129
|
* `MultiRenderer` and you can control the layout of individual parts of the
|
|
103
130
|
* item.
|
|
131
|
+
*
|
|
132
|
+
* @deprecated MultiItem support is slated for removal in a future Perseus
|
|
133
|
+
* release.
|
|
104
134
|
*/
|
|
105
135
|
export type MultiItem = {
|
|
106
136
|
_multi: any;
|
|
@@ -110,11 +140,25 @@ export type Version = {
|
|
|
110
140
|
minor: number;
|
|
111
141
|
};
|
|
112
142
|
export type PerseusRenderer = {
|
|
143
|
+
/**
|
|
144
|
+
* Translatable Markdown content to be rendered. May include references to
|
|
145
|
+
* widgets (as [[☃ widgetName]]) or images (as ).
|
|
146
|
+
* For each image found in this content, there can be an entry in the
|
|
147
|
+
* `images` dict (below) with the key being the image's url which defines
|
|
148
|
+
* additional attributes for the image.
|
|
149
|
+
*/
|
|
113
150
|
content: string;
|
|
151
|
+
/**
|
|
152
|
+
* A dictionary of {[widgetName]: Widget} to be referenced from the content
|
|
153
|
+
* field.
|
|
154
|
+
*/
|
|
114
155
|
widgets: PerseusWidgetsMap;
|
|
115
156
|
metadata?: ReadonlyArray<string>;
|
|
157
|
+
/**
|
|
158
|
+
* A dictionary of {[imageUrl]: PerseusImageDetail}.
|
|
159
|
+
*/
|
|
116
160
|
images: {
|
|
117
|
-
[
|
|
161
|
+
[imageUrl: string]: PerseusImageDetail;
|
|
118
162
|
};
|
|
119
163
|
};
|
|
120
164
|
export type Hint = PerseusRenderer & {
|
|
@@ -131,6 +175,10 @@ export type PerseusImageDetail = {
|
|
|
131
175
|
};
|
|
132
176
|
export declare const ItemExtras: readonly ["calculator", "chi2Table", "financialCalculatorMonthlyPayment", "financialCalculatorTotalAmount", "financialCalculatorTimeToPayOff", "periodicTable", "periodicTableWithKey", "tTable", "zTable"];
|
|
133
177
|
export type PerseusAnswerArea = Record<(typeof ItemExtras)[number], boolean>;
|
|
178
|
+
/**
|
|
179
|
+
* The type representing the common structure of all widget's options. The
|
|
180
|
+
* `Options` generic type represents the widget-specific option data.
|
|
181
|
+
*/
|
|
134
182
|
export type WidgetOptions<Type extends string, Options> = {
|
|
135
183
|
type: Type;
|
|
136
184
|
static?: boolean;
|
|
@@ -173,8 +221,11 @@ export type InputNumberWidget = WidgetOptions<'input-number', PerseusInputNumber
|
|
|
173
221
|
export type MoleculeRendererWidget = WidgetOptions<'molecule-renderer', PerseusMoleculeRendererWidgetOptions>;
|
|
174
222
|
export type RefTargetWidget = WidgetOptions<'passage-ref-target', PerseusPassageRefTargetWidgetOptions>;
|
|
175
223
|
export type VideoWidget = WidgetOptions<'video', PerseusVideoWidgetOptions>;
|
|
176
|
-
export type AutoCorrectWidget = WidgetOptions<'deprecated-standin',
|
|
224
|
+
export type AutoCorrectWidget = WidgetOptions<'deprecated-standin', object>;
|
|
177
225
|
export type PerseusWidget = CategorizerWidget | CSProgramWidget | DefinitionWidget | DropdownWidget | ExplanationWidget | ExpressionWidget | GradedGroupSetWidget | GradedGroupWidget | GrapherWidget | GroupWidget | IFrameWidget | ImageWidget | InputNumberWidget | InteractionWidget | InteractiveGraphWidget | LabelImageWidget | MatcherWidget | MatrixWidget | MeasurerWidget | MoleculeRendererWidget | NumberLineWidget | NumericInputWidget | OrdererWidget | PassageRefWidget | PassageWidget | PhetSimulationWidget | PlotterWidget | PythonProgramWidget | RadioWidget | RefTargetWidget | SorterWidget | TableWidget | VideoWidget | AutoCorrectWidget;
|
|
226
|
+
/**
|
|
227
|
+
* A background image applied to various widgets.
|
|
228
|
+
*/
|
|
178
229
|
export type PerseusImageBackground = {
|
|
179
230
|
url: string | null | undefined;
|
|
180
231
|
width?: number;
|
|
@@ -334,8 +385,8 @@ export type PerseusImageLabel = {
|
|
|
334
385
|
};
|
|
335
386
|
export type PerseusInteractiveGraphWidgetOptions = {
|
|
336
387
|
step: [number, number];
|
|
337
|
-
gridStep:
|
|
338
|
-
snapStep:
|
|
388
|
+
gridStep?: [x: number, y: number];
|
|
389
|
+
snapStep?: [x: number, y: number];
|
|
339
390
|
backgroundImage?: PerseusImageBackground;
|
|
340
391
|
/**
|
|
341
392
|
* The type of markings to display on the graph.
|
|
@@ -344,7 +395,7 @@ export type PerseusInteractiveGraphWidgetOptions = {
|
|
|
344
395
|
* - none: shows no markings
|
|
345
396
|
*/
|
|
346
397
|
markings: "graph" | "grid" | "none";
|
|
347
|
-
labels
|
|
398
|
+
labels?: ReadonlyArray<string>;
|
|
348
399
|
showProtractor: boolean;
|
|
349
400
|
/**
|
|
350
401
|
* Whether to show the Ruler tool overlayed on top of the graph.
|
|
@@ -621,7 +672,7 @@ export type PerseusNumericInputAnswerForm = {
|
|
|
621
672
|
};
|
|
622
673
|
export type PerseusNumericInputWidgetOptions = {
|
|
623
674
|
answers: ReadonlyArray<PerseusNumericInputAnswer>;
|
|
624
|
-
labelText
|
|
675
|
+
labelText?: string | undefined;
|
|
625
676
|
size: string;
|
|
626
677
|
coefficient: boolean;
|
|
627
678
|
rightAlign?: boolean;
|
|
@@ -630,7 +681,7 @@ export type PerseusNumericInputWidgetOptions = {
|
|
|
630
681
|
};
|
|
631
682
|
export type PerseusNumericInputAnswer = {
|
|
632
683
|
message: string;
|
|
633
|
-
value
|
|
684
|
+
value?: number;
|
|
634
685
|
status: string;
|
|
635
686
|
answerForms?: ReadonlyArray<MathFormat>;
|
|
636
687
|
strict: boolean;
|
package/dist/renderer-util.d.ts
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
|
-
import type { PerseusWidgetsMap } from "./perseus-types";
|
|
1
|
+
import type { PerseusRenderer, PerseusWidgetsMap } from "./perseus-types";
|
|
2
2
|
import type { PerseusStrings } from "./strings";
|
|
3
3
|
import type { PerseusScore } from "./types";
|
|
4
4
|
import type { UserInputMap } from "./validation.types";
|
|
5
|
+
export declare function getUpgradedWidgetOptions(oldWidgetOptions: PerseusWidgetsMap): PerseusWidgetsMap;
|
|
5
6
|
export declare function emptyWidgetsFunctional(widgets: PerseusWidgetsMap, widgetIds: Array<string>, userInputMap: UserInputMap, strings: PerseusStrings, locale: string): ReadonlyArray<string>;
|
|
6
|
-
export declare function
|
|
7
|
+
export declare function scorePerseusItem(perseusRenderData: PerseusRenderer, userInputMap: UserInputMap, strings: PerseusStrings, locale: string): PerseusScore;
|
|
8
|
+
export declare function scoreWidgetsFunctional(widgets: PerseusWidgetsMap, widgetIds: ReadonlyArray<string>, userInputMap: UserInputMap, strings: PerseusStrings, locale: string): {
|
|
7
9
|
[widgetId: string]: PerseusScore;
|
|
8
10
|
};
|
package/dist/renderer.d.ts
CHANGED
|
@@ -103,7 +103,6 @@ declare class Renderer extends React.Component<Props, State> implements GetPromp
|
|
|
103
103
|
widgetInfo: State["widgetInfo"];
|
|
104
104
|
widgetProps: State["widgetProps"];
|
|
105
105
|
};
|
|
106
|
-
_getAllWidgetsInfo: (props: Props) => PerseusWidgetsMap;
|
|
107
106
|
_getAllWidgetsStartProps: (allWidgetInfo: PerseusWidgetsMap, props: Props) => PerseusWidgetsMap;
|
|
108
107
|
_getDefaultWidgetInfo: (widgetId: string) => any;
|
|
109
108
|
_getWidgetInfo: (widgetId: string) => PerseusWidget;
|
|
@@ -193,9 +192,15 @@ declare class Renderer extends React.Component<Props, State> implements GetPromp
|
|
|
193
192
|
blurPath: (path: FocusPath) => void;
|
|
194
193
|
blur: () => void;
|
|
195
194
|
serialize: () => Record<any, any>;
|
|
195
|
+
/**
|
|
196
|
+
* Returns an array of widget ids that are empty (meaning widgets where the
|
|
197
|
+
* learner has not interacted with the widget yet or has not filled in all
|
|
198
|
+
* fields). For example, the `interactive-graph` widget is considered
|
|
199
|
+
* empty if the graph is in the starting state.
|
|
200
|
+
*/
|
|
196
201
|
emptyWidgets(): ReadonlyArray<string>;
|
|
197
202
|
_setWidgetProps: SetWidgetPropsFn;
|
|
198
|
-
setInputValue: (path: FocusPath, newValue: string,
|
|
203
|
+
setInputValue: (path: FocusPath, newValue: string, cb?: () => void) => void;
|
|
199
204
|
/**
|
|
200
205
|
* Returns an array of the widget `.getUserInput()` results
|
|
201
206
|
*
|
|
@@ -218,18 +223,15 @@ declare class Renderer extends React.Component<Props, State> implements GetPromp
|
|
|
218
223
|
*/
|
|
219
224
|
getPromptJSON(): RendererPromptJSON;
|
|
220
225
|
/**
|
|
221
|
-
*
|
|
222
|
-
*
|
|
223
|
-
*
|
|
226
|
+
* Scores the content.
|
|
227
|
+
*
|
|
228
|
+
* @deprecated use scorePerseusItem
|
|
224
229
|
*/
|
|
225
|
-
|
|
226
|
-
[widgetId: string]: PerseusScore;
|
|
227
|
-
};
|
|
230
|
+
score(): PerseusScore;
|
|
228
231
|
/**
|
|
229
|
-
*
|
|
232
|
+
* @deprecated use scorePerseusItem
|
|
230
233
|
*/
|
|
231
|
-
|
|
232
|
-
guessAndScore(): [UserInputArray, PerseusScore];
|
|
234
|
+
guessAndScore: () => [UserInputArray, PerseusScore];
|
|
233
235
|
examples: () => ReadonlyArray<string> | null | undefined;
|
|
234
236
|
handletranslationLintErrors: (lintErrors: ReadonlyArray<string>) => void;
|
|
235
237
|
render(): React.ReactNode;
|
|
@@ -12,12 +12,14 @@ import { PerseusI18nContext } from "./components/i18n-context";
|
|
|
12
12
|
import Renderer from "./renderer";
|
|
13
13
|
import type { PerseusItem, ShowSolutions } from "./perseus-types";
|
|
14
14
|
import type { FocusPath, PerseusDependenciesV2, SharedRendererProps } from "./types";
|
|
15
|
+
import type { UserInputArray, UserInputMap } from "./validation.types";
|
|
15
16
|
import type { GetPromptJSONInterface, RendererPromptJSON } from "./widget-ai-utils/prompt-types";
|
|
16
17
|
import type { KeypadAPI } from "@khanacademy/math-input";
|
|
17
18
|
import type { KeypadContextRendererInterface, RendererInterface, KEScore } from "@khanacademy/perseus-core";
|
|
18
19
|
type OwnProps = {
|
|
19
20
|
hintsVisible?: number;
|
|
20
21
|
item: PerseusItem;
|
|
22
|
+
score?: KEScore | null;
|
|
21
23
|
problemNum?: number;
|
|
22
24
|
reviewMode?: boolean;
|
|
23
25
|
keypadElement?: KeypadAPI | null | undefined;
|
|
@@ -30,8 +32,23 @@ type HOCProps = {
|
|
|
30
32
|
type Props = SharedRendererProps & OwnProps & HOCProps;
|
|
31
33
|
type DefaultProps = Required<Pick<Props, "apiOptions" | "onRendered" | "linterContext">>;
|
|
32
34
|
type State = {
|
|
35
|
+
/**
|
|
36
|
+
* questionCompleted is used to signal that a learner has attempted
|
|
37
|
+
* the exercise. This is used when widgets want to show things like
|
|
38
|
+
* rationale or partial correctness.
|
|
39
|
+
*/
|
|
33
40
|
questionCompleted: boolean;
|
|
34
|
-
|
|
41
|
+
/**
|
|
42
|
+
* As far as I can tell, this is used to highlight empty widgets
|
|
43
|
+
* after a learner has clicked the "check" button. I don't think this could
|
|
44
|
+
* still be used though, because the "check" button is disabled while there
|
|
45
|
+
* are empty widgets.
|
|
46
|
+
*/
|
|
47
|
+
questionHighlightedWidgets: ReadonlyArray<string>;
|
|
48
|
+
/**
|
|
49
|
+
* Keeps track of whether each asset (SvgImage or TeX) rendered by
|
|
50
|
+
* the questionRenderer has finished loading or rendering.
|
|
51
|
+
*/
|
|
35
52
|
assetStatuses: {
|
|
36
53
|
[assetKey: string]: boolean;
|
|
37
54
|
};
|
|
@@ -76,8 +93,22 @@ export declare class ServerItemRenderer extends React.Component<Props, State> im
|
|
|
76
93
|
blur(): void;
|
|
77
94
|
getNumHints(): number;
|
|
78
95
|
getPromptJSON(): RendererPromptJSON;
|
|
96
|
+
/**
|
|
97
|
+
* Returns an array of the widget `.getUserInput()` results
|
|
98
|
+
*
|
|
99
|
+
* TODO: can we remove this? Seems to be just for backwards
|
|
100
|
+
* compatibility with old Perseus Chrome logging
|
|
101
|
+
* @deprecated use getUserInput
|
|
102
|
+
*/
|
|
103
|
+
getUserInputLegacy(): UserInputArray;
|
|
104
|
+
/**
|
|
105
|
+
* Returns an object of the widget `.getUserInput()` results
|
|
106
|
+
*/
|
|
107
|
+
getUserInput(): UserInputMap;
|
|
79
108
|
/**
|
|
80
109
|
* Grades the item.
|
|
110
|
+
*
|
|
111
|
+
* @deprecated use scorePerseusItem
|
|
81
112
|
*/
|
|
82
113
|
scoreInput(): KEScore;
|
|
83
114
|
/**
|
package/dist/types.d.ts
CHANGED
|
@@ -46,6 +46,12 @@ export interface Widget {
|
|
|
46
46
|
} | boolean;
|
|
47
47
|
getDOMNodeForPath?: (path: FocusPath) => Element | Text | null;
|
|
48
48
|
deselectIncorrectSelectedChoices?: () => void;
|
|
49
|
+
/**
|
|
50
|
+
* Returns widget state that can be passed back to `restoreSerializedState`
|
|
51
|
+
* to put the widget back into exactly the same state. If the widget does
|
|
52
|
+
* not implement this function, the renderer simply returns all of the
|
|
53
|
+
* widget's props.
|
|
54
|
+
*/
|
|
49
55
|
getSerializedState?: () => SerializedState;
|
|
50
56
|
restoreSerializedState?: (props: any, callback: () => void) => any;
|
|
51
57
|
blurInputPath?: (path: FocusPath) => void;
|
|
@@ -103,7 +109,7 @@ export type ChangeHandler = (arg1: {
|
|
|
103
109
|
selected?: number;
|
|
104
110
|
plot?: any;
|
|
105
111
|
graph?: PerseusGraphType;
|
|
106
|
-
}, callback?: () =>
|
|
112
|
+
}, callback?: () => void, silent?: boolean) => unknown;
|
|
107
113
|
export type ImageUploader = (file: File, callback: (url: string) => unknown) => unknown;
|
|
108
114
|
export type Path = ReadonlyArray<string>;
|
|
109
115
|
type StubTagEditorType = any;
|
|
@@ -297,6 +303,17 @@ type InitialRequestUrlInterface = {
|
|
|
297
303
|
protocol: string;
|
|
298
304
|
};
|
|
299
305
|
export type VideoKind = "YOUTUBE_ID" | "READABLE_ID";
|
|
306
|
+
/**
|
|
307
|
+
* An object for dependency injection, to allow different clients
|
|
308
|
+
* to provide different methods for logging, translation, network
|
|
309
|
+
* requests, etc.
|
|
310
|
+
*
|
|
311
|
+
* NOTE: You should avoid adding new dependencies here as this type was added
|
|
312
|
+
* as a quick fix to get around the fact that some of the dependencies Perseus
|
|
313
|
+
* needs are used in places where neither `APIOptions` nor a React Context
|
|
314
|
+
* could be used. Aim to shrink the footprint of PerseusDependencies and try to
|
|
315
|
+
* use alternative methods where possible.
|
|
316
|
+
*/
|
|
300
317
|
export type PerseusDependencies = {
|
|
301
318
|
JIPT: JIPT;
|
|
302
319
|
graphieMovablesJiptLabels: JiptLabelStore;
|
|
@@ -353,6 +370,11 @@ type TrackingSequenceExtraArguments = {
|
|
|
353
370
|
};
|
|
354
371
|
export type Alignment = "default" | "block" | "inline-block" | "inline" | "float-left" | "float-right" | "full-width";
|
|
355
372
|
type WidgetOptions = any;
|
|
373
|
+
/**
|
|
374
|
+
* A transform that maps the WidgetOptions (sometimes referred to as
|
|
375
|
+
* EditorProps) to the props used to render the widget. Often this is an
|
|
376
|
+
* identity transform.
|
|
377
|
+
*/
|
|
356
378
|
export type WidgetTransform = (arg1: WidgetOptions, strings: PerseusStrings, problemNumber?: number) => any;
|
|
357
379
|
export type WidgetScorerFunction = (userInput: UserInput, rubric: Rubric, string?: PerseusStrings, locale?: string) => PerseusScore;
|
|
358
380
|
export type WidgetExports<T extends React.ComponentType<any> & Widget = React.ComponentType<any>> = Readonly<{
|
|
@@ -364,11 +386,12 @@ export type WidgetExports<T extends React.ComponentType<any> & Widget = React.Co
|
|
|
364
386
|
/** Supresses widget from showing up in the dropdown in the content editor */
|
|
365
387
|
hidden?: boolean;
|
|
366
388
|
/**
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
389
|
+
* The widget version. Any time the _major_ version changes, the widget
|
|
390
|
+
* should provide a new entry in the propUpgrades map to migrate from the
|
|
391
|
+
* older version to the current (new) version. Minor version changes must
|
|
392
|
+
* be backwards compatible with previous minor versions widget options.
|
|
393
|
+
*
|
|
394
|
+
* This key defaults to `{major: 0, minor: 0}` if not provided.
|
|
372
395
|
*/
|
|
373
396
|
version?: Version;
|
|
374
397
|
supportedAlignments?: ReadonlyArray<Alignment>;
|
|
@@ -377,25 +400,44 @@ export type WidgetExports<T extends React.ComponentType<any> & Widget = React.Co
|
|
|
377
400
|
isLintable?: boolean;
|
|
378
401
|
tracking?: Tracking;
|
|
379
402
|
traverseChildWidgets?: any;
|
|
380
|
-
/**
|
|
403
|
+
/**
|
|
404
|
+
* Transforms the widget options to the props used to render the widget.
|
|
405
|
+
*/
|
|
381
406
|
transform?: WidgetTransform;
|
|
382
|
-
/**
|
|
383
|
-
|
|
407
|
+
/**
|
|
408
|
+
* Transforms the widget options to the props used to render the widget for
|
|
409
|
+
* static renders.
|
|
410
|
+
*/
|
|
384
411
|
staticTransform?: WidgetTransform;
|
|
412
|
+
/**
|
|
413
|
+
* A function that scores user input (the guess) for the widget.
|
|
414
|
+
*/
|
|
385
415
|
scorer?: WidgetScorerFunction;
|
|
386
416
|
getOneCorrectAnswerFromRubric?: (rubric: Rubric) => string | null | undefined;
|
|
387
417
|
/**
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
418
|
+
* A map of major version numbers (as a string, eg "1") to a function that
|
|
419
|
+
* migrates from the _previous_ major version.
|
|
420
|
+
*
|
|
421
|
+
* Example:
|
|
422
|
+
* ```
|
|
423
|
+
* propUpgrades: {'1': (options) => ({...options})}
|
|
424
|
+
* ```
|
|
425
|
+
*
|
|
426
|
+
* This configuration would migrate options from major version 0 to 1.
|
|
427
|
+
*/
|
|
394
428
|
propUpgrades?: {
|
|
395
|
-
[
|
|
429
|
+
[targetMajorVersion: string]: (arg1: any) => any;
|
|
396
430
|
};
|
|
397
431
|
}>;
|
|
398
432
|
export type FilterCriterion = string | ((id: string, widgetInfo: PerseusWidget, widget?: Widget | null | undefined) => boolean);
|
|
433
|
+
/**
|
|
434
|
+
* The full set of props provided to all widgets when they are rendered. The
|
|
435
|
+
* `RenderProps` generic argument are the widget-specific props that originate
|
|
436
|
+
* from the stored PerseusItem. Note that they may not match the serialized
|
|
437
|
+
* widget options exactly as they are the result of running the options through
|
|
438
|
+
* any `propUpgrades` the widget defines as well as its `transform` or
|
|
439
|
+
* `staticTransform` functions (depending on the options `static` flag).
|
|
440
|
+
*/
|
|
399
441
|
export type WidgetProps<RenderProps, Rubric = Empty, TrackingExtraArgs = Empty> = RenderProps & {
|
|
400
442
|
widgetId: string;
|
|
401
443
|
alignment: string | null | undefined;
|
|
@@ -403,6 +445,11 @@ export type WidgetProps<RenderProps, Rubric = Empty, TrackingExtraArgs = Empty>
|
|
|
403
445
|
problemNum: number | null | undefined;
|
|
404
446
|
apiOptions: APIOptionsWithDefaults;
|
|
405
447
|
keypadElement?: any;
|
|
448
|
+
/**
|
|
449
|
+
* questionCompleted is used to signal that a learner has attempted
|
|
450
|
+
* the exercise. This is used when widgets want to show things like
|
|
451
|
+
* rationale or partial correctness.
|
|
452
|
+
*/
|
|
406
453
|
questionCompleted?: boolean;
|
|
407
454
|
onFocus: (blurPath: FocusPath) => void;
|
|
408
455
|
onBlur: (blurPath: FocusPath) => void;
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
* } & Perseus<Widget>ValidationData;
|
|
28
28
|
* ```
|
|
29
29
|
*/
|
|
30
|
-
import type { GrapherAnswerTypes, PerseusDropdownChoice, PerseusExpressionAnswerForm, PerseusGradedGroupSetWidgetOptions, PerseusGradedGroupWidgetOptions, PerseusGraphType, PerseusGroupWidgetOptions, PerseusMatcherWidgetOptions, PerseusMatrixWidgetAnswers,
|
|
30
|
+
import type { GrapherAnswerTypes, PerseusDropdownChoice, PerseusExpressionAnswerForm, PerseusGradedGroupSetWidgetOptions, PerseusGradedGroupWidgetOptions, PerseusGraphType, PerseusGroupWidgetOptions, PerseusMatcherWidgetOptions, PerseusMatrixWidgetAnswers, PerseusNumericInputAnswer, PerseusOrdererWidgetOptions, PerseusRadioChoice, PerseusGraphCorrectType } from "./perseus-types";
|
|
31
31
|
import type { InteractiveMarkerType } from "./widgets/label-image/types";
|
|
32
32
|
import type { Relationship } from "./widgets/number-line/number-line";
|
|
33
33
|
export type UserInputStatus = "correct" | "incorrect" | "incomplete";
|
|
@@ -57,6 +57,7 @@ export type PerseusExpressionRubric = {
|
|
|
57
57
|
};
|
|
58
58
|
export type PerseusExpressionUserInput = string;
|
|
59
59
|
export type PerseusGroupRubric = PerseusGroupWidgetOptions;
|
|
60
|
+
export type PerseusGroupUserInput = UserInputMap;
|
|
60
61
|
export type PerseusGradedGroupRubric = PerseusGradedGroupWidgetOptions;
|
|
61
62
|
export type PerseusGradedGroupSetRubric = PerseusGradedGroupSetWidgetOptions;
|
|
62
63
|
export type PerseusGrapherRubric = {
|
|
@@ -99,7 +100,11 @@ export type PerseusMatrixValidationData = Empty;
|
|
|
99
100
|
export type PerseusMatrixUserInput = {
|
|
100
101
|
answers: PerseusMatrixRubric["answers"];
|
|
101
102
|
};
|
|
102
|
-
export type
|
|
103
|
+
export type PerseusNumberLineScoringData = {
|
|
104
|
+
correctRel: string | null | undefined;
|
|
105
|
+
correctX: number;
|
|
106
|
+
range: ReadonlyArray<number>;
|
|
107
|
+
initialX: number | null | undefined;
|
|
103
108
|
isInequality: boolean;
|
|
104
109
|
};
|
|
105
110
|
export type PerseusNumberLineUserInput = {
|
|
@@ -144,7 +149,7 @@ export type PerseusTableRubric = {
|
|
|
144
149
|
answers: ReadonlyArray<ReadonlyArray<string>>;
|
|
145
150
|
};
|
|
146
151
|
export type PerseusTableUserInput = ReadonlyArray<ReadonlyArray<string>>;
|
|
147
|
-
export type Rubric = PerseusCategorizerScoringData | PerseusCSProgramRubric | PerseusDropdownRubric | PerseusExpressionRubric | PerseusGroupRubric | PerseusGradedGroupRubric | PerseusGradedGroupSetRubric | PerseusGrapherRubric | PerseusIFrameRubric | PerseusInputNumberRubric | PerseusInteractiveGraphRubric | PerseusLabelImageRubric | PerseusMatcherRubric | PerseusMatrixRubric |
|
|
152
|
+
export type Rubric = PerseusCategorizerScoringData | PerseusCSProgramRubric | PerseusDropdownRubric | PerseusExpressionRubric | PerseusGroupRubric | PerseusGradedGroupRubric | PerseusGradedGroupSetRubric | PerseusGrapherRubric | PerseusIFrameRubric | PerseusInputNumberRubric | PerseusInteractiveGraphRubric | PerseusLabelImageRubric | PerseusMatcherRubric | PerseusMatrixRubric | PerseusNumberLineScoringData | PerseusNumericInputRubric | PerseusOrdererRubric | PerseusPlotterScoringData | PerseusRadioRubric | PerseusSorterRubric | PerseusTableRubric;
|
|
148
153
|
export type UserInput = PerseusCategorizerUserInput | PerseusCSProgramUserInput | PerseusDropdownUserInput | PerseusExpressionUserInput | PerseusGrapherUserInput | PerseusIFrameUserInput | PerseusInputNumberUserInput | PerseusInteractiveGraphUserInput | PerseusLabelImageUserInput | PerseusMatcherUserInput | PerseusMatrixUserInput | PerseusNumberLineUserInput | PerseusNumericInputUserInput | PerseusOrdererUserInput | PerseusPlotterUserInput | PerseusRadioUserInput | PerseusSorterUserInput | PerseusTableUserInput;
|
|
149
154
|
export type UserInputMap = {
|
|
150
155
|
[widgetId: string]: UserInput | UserInputMap;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import React from "react";
|
|
2
2
|
import { PerseusI18nContext } from "../../components/i18n-context";
|
|
3
3
|
import type { Widget } from "../../types";
|
|
4
|
-
type Props =
|
|
4
|
+
type Props = object;
|
|
5
5
|
declare class DeprecatedStandin extends React.Component<Props> implements Widget {
|
|
6
6
|
static contextType: React.Context<{
|
|
7
7
|
strings: import("../../strings").PerseusStrings;
|
|
@@ -172,7 +172,7 @@ declare const _default: {
|
|
|
172
172
|
visibleLabel: PerseusExpressionWidgetOptions["visibleLabel"];
|
|
173
173
|
ariaLabel: PerseusExpressionWidgetOptions["ariaLabel"];
|
|
174
174
|
value: string;
|
|
175
|
-
}, "ariaLabel" | "static" | "onChange" | "keypadElement" | "containerSizeClass" | "widgetId" | "problemNum" | "questionCompleted" | "findWidgets" | "trackInteraction" | "reviewMode" | keyof import("../..").PerseusDependenciesV2 | "
|
|
175
|
+
}, "ariaLabel" | "static" | "onChange" | "keypadElement" | "containerSizeClass" | "widgetId" | "problemNum" | "questionCompleted" | "findWidgets" | "trackInteraction" | "alignment" | "reviewMode" | keyof import("../..").PerseusDependenciesV2 | "reviewModeRubric" | "isLastUsedWidget" | "visibleLabel" | "buttonsVisible" | "keypadConfiguration"> & {
|
|
176
176
|
value?: string | undefined;
|
|
177
177
|
onFocus?: ((blurPath: FocusPath) => void) | undefined;
|
|
178
178
|
onBlur?: ((blurPath: FocusPath) => void) | undefined;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
2
|
import { PerseusI18nContext } from "../../components/i18n-context";
|
|
3
3
|
import Renderer from "../../renderer";
|
|
4
|
+
import scoreGroup from "./score-group";
|
|
4
5
|
import type { PerseusGroupWidgetOptions } from "../../perseus-types";
|
|
5
6
|
import type { ChangeFn, FocusPath, Widget, WidgetProps } from "../../types";
|
|
6
7
|
import type { PerseusGroupRubric, UserInputArray } from "../../validation.types";
|
|
@@ -23,7 +24,7 @@ declare class Group extends React.Component<Props> implements Widget {
|
|
|
23
24
|
static defaultProps: DefaultProps;
|
|
24
25
|
componentDidMount(): void;
|
|
25
26
|
change: ChangeFn;
|
|
26
|
-
getUserInputMap(): import("
|
|
27
|
+
getUserInputMap(): import("../..").UserInputMap | undefined;
|
|
27
28
|
/**
|
|
28
29
|
* @deprecated getUserInputMap should be used for Groups
|
|
29
30
|
*/
|
|
@@ -44,6 +45,7 @@ declare const _default: {
|
|
|
44
45
|
displayName: string;
|
|
45
46
|
widget: typeof Group;
|
|
46
47
|
traverseChildWidgets: (props: any, traverseRenderer: any) => any;
|
|
48
|
+
scorer: typeof scoreGroup;
|
|
47
49
|
hidden: true;
|
|
48
50
|
isLintable: true;
|
|
49
51
|
};
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { PerseusStrings } from "../../strings";
|
|
2
|
+
import type { PerseusScore } from "../../types";
|
|
3
|
+
import type { PerseusGroupRubric, PerseusGroupUserInput } from "../../validation.types";
|
|
4
|
+
declare function scoreGroup(userInput: PerseusGroupUserInput, options: PerseusGroupRubric, strings: PerseusStrings, locale: string): PerseusScore;
|
|
5
|
+
export default scoreGroup;
|