@khanacademy/perseus 17.6.0 → 17.6.2
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 +17 -0
- package/dist/es/index.js +402 -606
- package/dist/es/index.js.map +1 -1
- package/dist/index.js +411 -603
- package/dist/index.js.map +1 -1
- package/dist/perseus-types.d.ts +2 -1
- package/dist/strings.js +1 -0
- package/dist/widgets/deprecated-standin/index.d.ts +32 -0
- package/dist/widgets/label-image/answer-choices.d.ts +8 -40
- package/dist/widgets/label-image/answer-pill.d.ts +3 -1
- package/dist/widgets/label-image/marker.d.ts +10 -5
- package/dist/widgets/label-image.d.ts +1 -8
- package/dist/widgets.d.ts +9 -0
- package/package.json +34 -33
- package/src/__tests__/widgets.test.ts +20 -0
- package/src/extra-widgets.ts +2 -0
- package/src/init.ts +5 -0
- package/src/perseus-types.ts +4 -1
- package/src/util/register-all-widgets-for-testing.ts +4 -0
- package/src/widgets/__stories__/orderer.stories.tsx +5 -1
- package/src/widgets/__testdata__/orderer.testdata.ts +66 -0
- package/src/widgets/deprecated-standin/__stories__/deprecated-standin.stories.tsx +34 -0
- package/src/widgets/deprecated-standin/__tests__/__snapshots__/deprecated-standin.test.ts.snap +71 -0
- package/src/widgets/deprecated-standin/__tests__/deprecated-standin.test.ts +93 -0
- package/src/widgets/deprecated-standin/index.tsx +57 -0
- package/src/widgets/label-image/__stories__/answer-choices.stories.tsx +29 -34
- package/src/widgets/label-image/__tests__/answer-pill.test.tsx +2 -10
- package/src/widgets/label-image/answer-choices.tsx +60 -278
- package/src/widgets/label-image/answer-pill.tsx +22 -13
- package/src/widgets/label-image/marker.tsx +103 -146
- package/src/widgets/label-image.test.ts +0 -2
- package/src/widgets/label-image.tsx +94 -195
- package/src/widgets.ts +24 -0
- package/tsconfig-build.tsbuildinfo +1 -1
package/dist/perseus-types.d.ts
CHANGED
|
@@ -81,7 +81,8 @@ export type ReactionDiagramWidget = Widget<'reaction-diagtram', PerseusReactionD
|
|
|
81
81
|
export type SimpleMarkdownTesterWidget = Widget<'simple-markdown-tester', PerseusSimpleMarkdownTesterWidgetOptions>;
|
|
82
82
|
export type UnitInputWidget = Widget<'unit-input', PerseusUnitInputWidgetOptions>;
|
|
83
83
|
export type VideoWidget = Widget<'video', PerseusVideoWidgetOptions>;
|
|
84
|
-
export type
|
|
84
|
+
export type AutoCorrectWidget = Widget<'deprecated-standin', PerseusWidgetOptions>;
|
|
85
|
+
export type PerseusWidget = CategorizerWidget | CSProgramWidget | DefinitionWidget | DropdownWidget | ExampleGraphieWidget | ExampleWidget | ExplanationWidget | ExpressionWidget | GradedGroupSetWidget | GradedGroupWidget | GrapherWidget | GroupWidget | IFrameWidget | ImageWidget | InputNumberWidget | InteractionWidget | InteractiveGraphWidget | LabelImageWidget | LightsPuzzleWidget | MatcherWidget | MatrixWidget | MeasurerWidget | MoleculeRendererWidget | NumberLineWidget | NumericInputWidget | OrdererWidget | PassageRefWidget | PassageWidget | PlotterWidget | RadioWidget | ReactionDiagramWidget | RefTargetWidget | SequenceWidget | SimpleMarkdownTesterWidget | SimulatorWidget | SorterWidget | TableWidget | TransformerWidget | UnitInputWidget | VideoWidget | AutoCorrectWidget;
|
|
85
86
|
export type PerseusImageBackground = {
|
|
86
87
|
url: string | null | undefined;
|
|
87
88
|
width?: number;
|
package/dist/strings.js
CHANGED
|
@@ -130,6 +130,7 @@ module.exports = [
|
|
|
130
130
|
i18n._("This controls the proportion or percentage that will be used in your simulation.", {}),
|
|
131
131
|
i18n._("This controls the sample size that will be used in your simulation. For example, if you set this to 100, then for each trial, responses from 100 participants will be simulated.", {}),
|
|
132
132
|
i18n._("This is the number of trials used in the simulation. For example, if set to 50, then the survey will be conducted 50 times.", {}),
|
|
133
|
+
i18n._("This part of the question is no-longer available. You will not be graded on this part.", {}),
|
|
133
134
|
// I18N: As in the command, "Translate the polygon"
|
|
134
135
|
i18n._("Translate", {}),
|
|
135
136
|
i18n._("translation", {}),
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import type { PerseusScore } from "../../types";
|
|
3
|
+
type AutoCorrectProps = any;
|
|
4
|
+
type Rubric = any;
|
|
5
|
+
type UserInput = Empty;
|
|
6
|
+
declare class AutoCorrect extends React.Component<AutoCorrectProps> {
|
|
7
|
+
static validate(userInput: UserInput, rubric: Rubric): PerseusScore;
|
|
8
|
+
getUserInput: () => UserInput;
|
|
9
|
+
simpleValidate: (arg1: Rubric) => PerseusScore;
|
|
10
|
+
render(): JSX.Element;
|
|
11
|
+
}
|
|
12
|
+
declare const _default: Readonly<{
|
|
13
|
+
name: string;
|
|
14
|
+
displayName: string;
|
|
15
|
+
getWidget?: (() => typeof AutoCorrect) | undefined;
|
|
16
|
+
accessible?: boolean | ((props: any) => boolean) | undefined;
|
|
17
|
+
hidden?: boolean | undefined;
|
|
18
|
+
version?: import("../../types").Version | undefined;
|
|
19
|
+
supportedAlignments?: readonly import("../../types").Alignment[] | undefined;
|
|
20
|
+
defaultAlignment?: import("../../types").Alignment | undefined;
|
|
21
|
+
getDefaultAlignment?: (() => import("../../types").Alignment) | undefined;
|
|
22
|
+
isLintable?: boolean | undefined;
|
|
23
|
+
tracking?: import("../../types").Tracking | undefined;
|
|
24
|
+
traverseChildWidgets?: any;
|
|
25
|
+
transform?: import("../../types").WidgetTransform | undefined;
|
|
26
|
+
staticTransform?: import("../../types").WidgetTransform | undefined;
|
|
27
|
+
propUpgrades?: {
|
|
28
|
+
[key: string]: (arg1: any) => any;
|
|
29
|
+
} | undefined;
|
|
30
|
+
widget: typeof AutoCorrect;
|
|
31
|
+
}>;
|
|
32
|
+
export default _default;
|
|
@@ -1,51 +1,19 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
* Enables single or multiple answers selection, using radio or checkbox input
|
|
5
|
-
* types, respectively.
|
|
2
|
+
* Enables single or multiple answers selection using WonderBlocks dropdowns.
|
|
6
3
|
*/
|
|
7
|
-
|
|
4
|
+
/// <reference types="react" />
|
|
5
|
+
import { SingleSelect } from "@khanacademy/wonder-blocks-dropdown";
|
|
8
6
|
export type AnswerType = {
|
|
9
7
|
content: string;
|
|
10
8
|
checked: boolean;
|
|
11
9
|
};
|
|
12
|
-
type AnswerProps = AnswerType & {
|
|
13
|
-
inputType: "checkbox" | "radio";
|
|
14
|
-
groupName: string;
|
|
15
|
-
index: number;
|
|
16
|
-
onChange: (checked: boolean) => void;
|
|
17
|
-
onFocusPrevAnswer: () => void;
|
|
18
|
-
onFocusNextAnswer: () => void;
|
|
19
|
-
};
|
|
20
|
-
type AnswerState = {
|
|
21
|
-
isInputFocused: boolean;
|
|
22
|
-
};
|
|
23
10
|
type AnswerChoicesProps = {
|
|
24
11
|
choices: ReadonlyArray<AnswerType>;
|
|
25
12
|
multipleSelect: boolean;
|
|
26
13
|
onChange: (selection: ReadonlyArray<boolean>) => void;
|
|
14
|
+
opener: SingleSelect["props"]["opener"];
|
|
15
|
+
onToggle: (opened: boolean) => unknown;
|
|
16
|
+
disabled: boolean;
|
|
27
17
|
};
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
};
|
|
31
|
-
declare class AnswerChoice extends React.Component<AnswerProps, AnswerState> {
|
|
32
|
-
_input: HTMLInputElement | null | undefined;
|
|
33
|
-
state: AnswerState;
|
|
34
|
-
focusInput(): void;
|
|
35
|
-
handleClick(e: React.MouseEvent<HTMLDivElement>): void;
|
|
36
|
-
handleKeyDown(e: React.KeyboardEvent<HTMLDivElement>): void;
|
|
37
|
-
handleInputChange(e: React.SyntheticEvent<HTMLInputElement>): void;
|
|
38
|
-
handleInputFocus(): void;
|
|
39
|
-
handleInputBlur(): void;
|
|
40
|
-
renderCheckmark(): React.ReactNode;
|
|
41
|
-
render(): React.ReactNode;
|
|
42
|
-
}
|
|
43
|
-
export default class AnswerChoices extends React.Component<AnswerChoicesProps, AnswerChoicesState> {
|
|
44
|
-
_choices: Array<AnswerChoice | null | undefined>;
|
|
45
|
-
constructor(props: AnswerChoicesProps);
|
|
46
|
-
focusAnswer(index?: number): void;
|
|
47
|
-
onAnswerChange(index: number, checked: boolean): void;
|
|
48
|
-
onFocusAnswer(index: number): void;
|
|
49
|
-
render(): React.ReactNode;
|
|
50
|
-
}
|
|
51
|
-
export {};
|
|
18
|
+
declare const AnswerChoices: (props: AnswerChoicesProps) => JSX.Element;
|
|
19
|
+
export default AnswerChoices;
|
|
@@ -5,6 +5,8 @@ export declare const AnswerPill: (props: {
|
|
|
5
5
|
showCorrectness?: "correct" | "incorrect";
|
|
6
6
|
markerRef?: HTMLElement;
|
|
7
7
|
side: "top" | "bottom" | "left" | "right";
|
|
8
|
-
onClick: () => void;
|
|
9
8
|
style?: CSSProperties;
|
|
9
|
+
hovered?: boolean;
|
|
10
|
+
focused?: boolean;
|
|
11
|
+
onClick?: () => void;
|
|
10
12
|
}) => JSX.Element;
|
|
@@ -5,21 +5,26 @@
|
|
|
5
5
|
*/
|
|
6
6
|
import * as React from "react";
|
|
7
7
|
import type { InteractiveMarkerType } from "./types";
|
|
8
|
+
import type { AnalyticsEventHandlerFn } from "@khanacademy/perseus-core";
|
|
9
|
+
import type { CSSProperties } from "aphrodite";
|
|
8
10
|
type Props = InteractiveMarkerType & {
|
|
9
11
|
showSelected: boolean;
|
|
10
12
|
showPulsate: boolean;
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
13
|
+
answerSide: "top" | "bottom" | "left" | "right";
|
|
14
|
+
answerStyles?: CSSProperties;
|
|
15
|
+
showAnswer?: boolean;
|
|
16
|
+
analytics?: {
|
|
17
|
+
onAnalyticsEvent: AnalyticsEventHandlerFn;
|
|
18
|
+
};
|
|
15
19
|
focused: boolean;
|
|
20
|
+
hovered: boolean;
|
|
16
21
|
};
|
|
17
22
|
export default class Marker extends React.Component<Props> {
|
|
18
23
|
_icon: HTMLElement | null | undefined;
|
|
19
24
|
static defaultProps: {
|
|
20
25
|
selected: ReadonlyArray<any>;
|
|
21
26
|
};
|
|
22
|
-
renderIcon():
|
|
27
|
+
renderIcon(): JSX.Element;
|
|
23
28
|
render(): React.ReactNode;
|
|
24
29
|
}
|
|
25
30
|
export {};
|
|
@@ -5,9 +5,7 @@
|
|
|
5
5
|
* that involve the use of images, and enable learners to demonstrate their
|
|
6
6
|
* knowledge by directly interacting with the image.
|
|
7
7
|
*/
|
|
8
|
-
import { Popover } from "@khanacademy/wonder-blocks-popover";
|
|
9
8
|
import * as React from "react";
|
|
10
|
-
import AnswerChoices from "./label-image/answer-choices";
|
|
11
9
|
import Marker from "./label-image/marker";
|
|
12
10
|
import type { InteractiveMarkerType, InteractiveMarkerScore } from "./label-image/types";
|
|
13
11
|
import type { DependencyProps } from "../dependencies";
|
|
@@ -51,13 +49,10 @@ type LabelImageProps = ChangeableProps & DependencyProps & {
|
|
|
51
49
|
type LabelImageState = {
|
|
52
50
|
activeMarkerIndex: number;
|
|
53
51
|
markersInteracted: boolean;
|
|
54
|
-
focusedMarkerIndex: number;
|
|
55
52
|
hideAnswers: boolean;
|
|
56
53
|
};
|
|
57
54
|
export declare class LabelImage extends React.Component<LabelImageProps, LabelImageState> {
|
|
58
55
|
_markers: Array<Marker | null | undefined>;
|
|
59
|
-
_selectedMarkerPopup: Popover | null | undefined;
|
|
60
|
-
_answerChoices: AnswerChoices | null | undefined;
|
|
61
56
|
static gradeMarker(marker: InteractiveMarkerType): InteractiveMarkerScore;
|
|
62
57
|
static validate(state: MarkersState, rubric?: LabelImageProps): PerseusScore;
|
|
63
58
|
/**
|
|
@@ -81,12 +76,10 @@ export declare class LabelImage extends React.Component<LabelImageProps, LabelIm
|
|
|
81
76
|
simpleValidate(rubric: LabelImageProps): PerseusScore;
|
|
82
77
|
getUserInput(): MarkersState;
|
|
83
78
|
showRationalesForCurrentlySelectedChoices(rubric: LabelImageProps): void;
|
|
84
|
-
dismissMarkerPopup(): void;
|
|
85
79
|
handleMarkerChange(index: number, marker: InteractiveMarkerType): void;
|
|
86
|
-
activateMarker(index: number): void;
|
|
80
|
+
activateMarker(index: number, opened: boolean): void;
|
|
87
81
|
handleMarkerKeyDown(index: number, e: React.KeyboardEvent): void;
|
|
88
82
|
handleAnswerChoicesChangeForMarker(index: number, selection: ReadonlyArray<boolean>): void;
|
|
89
|
-
renderAnswerChoicesForMarker(index: number, marker: InteractiveMarkerType): React.ReactElement<React.ComponentProps<"div">>;
|
|
90
83
|
renderMarkers(): ReadonlyArray<React.ReactNode>;
|
|
91
84
|
renderInstructions(): React.ReactNode;
|
|
92
85
|
render(): React.ReactNode;
|
package/dist/widgets.d.ts
CHANGED
|
@@ -3,6 +3,15 @@ import type * as React from "react";
|
|
|
3
3
|
type Editor = any;
|
|
4
4
|
export declare const registerWidget: (name: string, widget: WidgetExports) => void;
|
|
5
5
|
export declare const registerWidgets: (widgets: ReadonlyArray<WidgetExports>) => void;
|
|
6
|
+
/**
|
|
7
|
+
*
|
|
8
|
+
* @param name - the widget that you are trying to replace
|
|
9
|
+
* @param replacementName - the name of the widget that takes its place
|
|
10
|
+
*
|
|
11
|
+
* e.g. replaceWidget("transformer", "always-correct") will make it so the
|
|
12
|
+
* transformer widget is replaced by the always correct widget
|
|
13
|
+
*/
|
|
14
|
+
export declare const replaceWidget: (name: string, replacementName: string) => void;
|
|
6
15
|
export declare const registerEditors: (editorsToRegister: ReadonlyArray<Editor>) => void;
|
|
7
16
|
export declare const getWidget: (name: string) => React.ComponentType<any> | null | undefined;
|
|
8
17
|
export declare const getEditor: (name: string) => Editor | null | undefined;
|
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": "17.6.
|
|
6
|
+
"version": "17.6.2",
|
|
7
7
|
"publishConfig": {
|
|
8
8
|
"access": "public"
|
|
9
9
|
},
|
|
@@ -24,31 +24,32 @@
|
|
|
24
24
|
"dependencies": {
|
|
25
25
|
"@khanacademy/kas": "^0.3.7",
|
|
26
26
|
"@khanacademy/kmath": "^0.1.8",
|
|
27
|
-
"@khanacademy/math-input": "^16.4.
|
|
27
|
+
"@khanacademy/math-input": "^16.4.1",
|
|
28
28
|
"@khanacademy/perseus-core": "1.4.1",
|
|
29
29
|
"@khanacademy/perseus-linter": "^0.3.10",
|
|
30
30
|
"@khanacademy/pure-markdown": "^0.2.13",
|
|
31
|
-
"@khanacademy/simple-markdown": "^0.11.2"
|
|
31
|
+
"@khanacademy/simple-markdown": "^0.11.2",
|
|
32
|
+
"@khanacademy/wonder-blocks-banner": "^3.0.33"
|
|
32
33
|
},
|
|
33
34
|
"devDependencies": {
|
|
34
|
-
"@khanacademy/wonder-blocks-button": "^6.2.
|
|
35
|
-
"@khanacademy/wonder-blocks-clickable": "^4.0.
|
|
35
|
+
"@khanacademy/wonder-blocks-button": "^6.2.5",
|
|
36
|
+
"@khanacademy/wonder-blocks-clickable": "^4.0.12",
|
|
36
37
|
"@khanacademy/wonder-blocks-color": "^3.0.0",
|
|
37
|
-
"@khanacademy/wonder-blocks-core": "^6.3.
|
|
38
|
-
"@khanacademy/wonder-blocks-data": "^13.0.
|
|
39
|
-
"@khanacademy/wonder-blocks-dropdown": "^
|
|
40
|
-
"@khanacademy/wonder-blocks-form": "^4.3.
|
|
38
|
+
"@khanacademy/wonder-blocks-core": "^6.3.1",
|
|
39
|
+
"@khanacademy/wonder-blocks-data": "^13.0.6",
|
|
40
|
+
"@khanacademy/wonder-blocks-dropdown": "^5.1.0",
|
|
41
|
+
"@khanacademy/wonder-blocks-form": "^4.3.19",
|
|
41
42
|
"@khanacademy/wonder-blocks-i18n": "^2.0.2",
|
|
42
|
-
"@khanacademy/wonder-blocks-layout": "^2.0.
|
|
43
|
-
"@khanacademy/wonder-blocks-link": "^6.0.
|
|
44
|
-
"@khanacademy/wonder-blocks-modal": "^4.0
|
|
45
|
-
"@khanacademy/wonder-blocks-pill": "^1.0.
|
|
46
|
-
"@khanacademy/wonder-blocks-popover": "^3.0.
|
|
47
|
-
"@khanacademy/wonder-blocks-progress-spinner": "^2.0.
|
|
43
|
+
"@khanacademy/wonder-blocks-layout": "^2.0.25",
|
|
44
|
+
"@khanacademy/wonder-blocks-link": "^6.0.5",
|
|
45
|
+
"@khanacademy/wonder-blocks-modal": "^4.2.0",
|
|
46
|
+
"@khanacademy/wonder-blocks-pill": "^1.0.15",
|
|
47
|
+
"@khanacademy/wonder-blocks-popover": "^3.0.22",
|
|
48
|
+
"@khanacademy/wonder-blocks-progress-spinner": "^2.0.25",
|
|
48
49
|
"@khanacademy/wonder-blocks-spacing": "^4.0.1",
|
|
49
|
-
"@khanacademy/wonder-blocks-switch": "^1.1.
|
|
50
|
-
"@khanacademy/wonder-blocks-tooltip": "^2.1.
|
|
51
|
-
"@khanacademy/wonder-blocks-typography": "^2.1.
|
|
50
|
+
"@khanacademy/wonder-blocks-switch": "^1.1.9",
|
|
51
|
+
"@khanacademy/wonder-blocks-tooltip": "^2.1.24",
|
|
52
|
+
"@khanacademy/wonder-blocks-typography": "^2.1.10",
|
|
52
53
|
"@khanacademy/wonder-stuff-core": "^1.5.1",
|
|
53
54
|
"@phosphor-icons/core": "^2.0.2",
|
|
54
55
|
"@popperjs/core": "^2.10.1",
|
|
@@ -70,24 +71,24 @@
|
|
|
70
71
|
"underscore": "^1.4.4"
|
|
71
72
|
},
|
|
72
73
|
"peerDependencies": {
|
|
73
|
-
"@khanacademy/wonder-blocks-button": "^6.2.
|
|
74
|
-
"@khanacademy/wonder-blocks-clickable": "^4.0.
|
|
74
|
+
"@khanacademy/wonder-blocks-button": "^6.2.5",
|
|
75
|
+
"@khanacademy/wonder-blocks-clickable": "^4.0.12",
|
|
75
76
|
"@khanacademy/wonder-blocks-color": "^3.0.0",
|
|
76
|
-
"@khanacademy/wonder-blocks-core": "^6.3.
|
|
77
|
-
"@khanacademy/wonder-blocks-data": "^13.0.
|
|
78
|
-
"@khanacademy/wonder-blocks-dropdown": "^
|
|
79
|
-
"@khanacademy/wonder-blocks-form": "^4.3.
|
|
77
|
+
"@khanacademy/wonder-blocks-core": "^6.3.1",
|
|
78
|
+
"@khanacademy/wonder-blocks-data": "^13.0.6",
|
|
79
|
+
"@khanacademy/wonder-blocks-dropdown": "^5.1.0",
|
|
80
|
+
"@khanacademy/wonder-blocks-form": "^4.3.19",
|
|
80
81
|
"@khanacademy/wonder-blocks-i18n": "^2.0.2",
|
|
81
|
-
"@khanacademy/wonder-blocks-layout": "^2.0.
|
|
82
|
-
"@khanacademy/wonder-blocks-link": "^6.0.
|
|
83
|
-
"@khanacademy/wonder-blocks-modal": "^4.0
|
|
84
|
-
"@khanacademy/wonder-blocks-pill": "^1.0.
|
|
85
|
-
"@khanacademy/wonder-blocks-popover": "^3.0.
|
|
86
|
-
"@khanacademy/wonder-blocks-progress-spinner": "^2.0.
|
|
82
|
+
"@khanacademy/wonder-blocks-layout": "^2.0.25",
|
|
83
|
+
"@khanacademy/wonder-blocks-link": "^6.0.5",
|
|
84
|
+
"@khanacademy/wonder-blocks-modal": "^4.2.0",
|
|
85
|
+
"@khanacademy/wonder-blocks-pill": "^1.0.15",
|
|
86
|
+
"@khanacademy/wonder-blocks-popover": "^3.0.22",
|
|
87
|
+
"@khanacademy/wonder-blocks-progress-spinner": "^2.0.25",
|
|
87
88
|
"@khanacademy/wonder-blocks-spacing": "^4.0.1",
|
|
88
|
-
"@khanacademy/wonder-blocks-switch": "^1.1.
|
|
89
|
-
"@khanacademy/wonder-blocks-tooltip": "^2.1.
|
|
90
|
-
"@khanacademy/wonder-blocks-typography": "^2.1.
|
|
89
|
+
"@khanacademy/wonder-blocks-switch": "^1.1.9",
|
|
90
|
+
"@khanacademy/wonder-blocks-tooltip": "^2.1.24",
|
|
91
|
+
"@khanacademy/wonder-blocks-typography": "^2.1.10",
|
|
91
92
|
"@khanacademy/wonder-stuff-core": "^1.5.1",
|
|
92
93
|
"@phosphor-icons/core": "^2.0.2",
|
|
93
94
|
"@popperjs/core": "^2.10.1",
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import {testDependencies} from "../../../../testing/test-dependencies";
|
|
2
|
+
import {setDependencies} from "../dependencies";
|
|
1
3
|
import {registerAllWidgetsForTesting} from "../util/register-all-widgets-for-testing";
|
|
2
4
|
import * as Widgets from "../widgets";
|
|
3
5
|
|
|
@@ -10,6 +12,7 @@ describe("Widget API support", () => {
|
|
|
10
12
|
// validate function. Not all widgets support this function so even though
|
|
11
13
|
// this list looks exhaustive, it's not!
|
|
12
14
|
it.each([
|
|
15
|
+
"deprecated-standin",
|
|
13
16
|
"radio",
|
|
14
17
|
"input-number",
|
|
15
18
|
"numeric-input",
|
|
@@ -71,3 +74,20 @@ describe("Widget API support", () => {
|
|
|
71
74
|
},
|
|
72
75
|
);
|
|
73
76
|
});
|
|
77
|
+
|
|
78
|
+
describe("replaceWidget", () => {
|
|
79
|
+
beforeEach(() => {
|
|
80
|
+
setDependencies(testDependencies);
|
|
81
|
+
registerAllWidgetsForTesting();
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
it("replaces an existing widget", () => {
|
|
85
|
+
Widgets.replaceWidget("transformer", "radio");
|
|
86
|
+
expect(Widgets.getWidget("transformer")?.name).toBe("Radio");
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
it("Does nothing when the replacement isn't available", () => {
|
|
90
|
+
Widgets.replaceWidget("radio", "dog-cat");
|
|
91
|
+
expect(Widgets.getWidget("radio")?.name).toBe("Radio");
|
|
92
|
+
});
|
|
93
|
+
});
|
package/src/extra-widgets.ts
CHANGED
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
import Categorizer from "./widgets/categorizer";
|
|
6
6
|
import CSProgram from "./widgets/cs-program";
|
|
7
7
|
import Definition from "./widgets/definition";
|
|
8
|
+
import DeprecatedStandin from "./widgets/deprecated-standin";
|
|
8
9
|
import Dropdown from "./widgets/dropdown";
|
|
9
10
|
import Explanation from "./widgets/explanation";
|
|
10
11
|
import GradedGroup from "./widgets/graded-group";
|
|
@@ -72,4 +73,5 @@ export default [
|
|
|
72
73
|
Transformer,
|
|
73
74
|
Unit,
|
|
74
75
|
Video,
|
|
76
|
+
DeprecatedStandin,
|
|
75
77
|
] as ReadonlyArray<WidgetExports>;
|
package/src/init.ts
CHANGED
|
@@ -21,6 +21,11 @@ const init = function (options: PerseusOptions): Promise<undefined> {
|
|
|
21
21
|
Widgets.registerWidgets(basicWidgets);
|
|
22
22
|
Widgets.registerWidgets(extraWidgets);
|
|
23
23
|
|
|
24
|
+
// This section replaces widgets
|
|
25
|
+
// When it's time to replace the transformer widget
|
|
26
|
+
// uncomment this line
|
|
27
|
+
// Widgets.replaceWidget("transformer", "always-correct");
|
|
28
|
+
|
|
24
29
|
// Pass skipMathJax: true if MathJax is already loaded and configured.
|
|
25
30
|
const skipMathJax = options.skipMathJax;
|
|
26
31
|
|
package/src/perseus-types.ts
CHANGED
|
@@ -187,6 +187,8 @@ export type SimpleMarkdownTesterWidget = Widget<'simple-markdown-tester', Perseu
|
|
|
187
187
|
export type UnitInputWidget = Widget<'unit-input', PerseusUnitInputWidgetOptions>;
|
|
188
188
|
// prettier-ignore
|
|
189
189
|
export type VideoWidget = Widget<'video', PerseusVideoWidgetOptions>;
|
|
190
|
+
//prettier-ignore
|
|
191
|
+
export type AutoCorrectWidget = Widget<'deprecated-standin', PerseusWidgetOptions>;
|
|
190
192
|
|
|
191
193
|
export type PerseusWidget =
|
|
192
194
|
| CategorizerWidget
|
|
@@ -228,7 +230,8 @@ export type PerseusWidget =
|
|
|
228
230
|
| TableWidget
|
|
229
231
|
| TransformerWidget
|
|
230
232
|
| UnitInputWidget
|
|
231
|
-
| VideoWidget
|
|
233
|
+
| VideoWidget
|
|
234
|
+
| AutoCorrectWidget;
|
|
232
235
|
|
|
233
236
|
// A background image applied to various widgets.
|
|
234
237
|
export type PerseusImageBackground = {
|
|
@@ -8,4 +8,8 @@ import * as Widgets from "../widgets";
|
|
|
8
8
|
|
|
9
9
|
export const registerAllWidgetsForTesting = () => {
|
|
10
10
|
Widgets.registerWidgets(allWidgets);
|
|
11
|
+
|
|
12
|
+
// When it's time to replace the transformer widget
|
|
13
|
+
// uncomment this line
|
|
14
|
+
// Widgets.replaceWidget("transformer", "deprecated-standin");
|
|
11
15
|
};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
2
|
|
|
3
3
|
import {RendererWithDebugUI} from "../../../../../testing/renderer-with-debug-ui";
|
|
4
|
-
import {question1} from "../__testdata__/orderer.testdata";
|
|
4
|
+
import {question1, questionWithImages} from "../__testdata__/orderer.testdata";
|
|
5
5
|
|
|
6
6
|
export default {
|
|
7
7
|
title: "Perseus/Widgets/Orderer",
|
|
@@ -12,3 +12,7 @@ type StoryArgs = Record<any, any>;
|
|
|
12
12
|
export const Question1 = (args: StoryArgs): React.ReactElement => {
|
|
13
13
|
return <RendererWithDebugUI question={question1} />;
|
|
14
14
|
};
|
|
15
|
+
|
|
16
|
+
export const QuestionWithImages = (args: StoryArgs): React.ReactElement => {
|
|
17
|
+
return <RendererWithDebugUI question={questionWithImages} />;
|
|
18
|
+
};
|
|
@@ -55,3 +55,69 @@ export const question2: PerseusRenderer = {
|
|
|
55
55
|
},
|
|
56
56
|
},
|
|
57
57
|
};
|
|
58
|
+
|
|
59
|
+
export const questionWithImages: PerseusRenderer = {
|
|
60
|
+
content: "**Put $6$ flowers in the box.**\n\n[[☃ orderer 1]]",
|
|
61
|
+
images: {},
|
|
62
|
+
widgets: {
|
|
63
|
+
"orderer 1": {
|
|
64
|
+
graded: true,
|
|
65
|
+
options: {
|
|
66
|
+
correctOptions: [
|
|
67
|
+
{
|
|
68
|
+
content:
|
|
69
|
+
"",
|
|
70
|
+
widgets: {},
|
|
71
|
+
images: {},
|
|
72
|
+
},
|
|
73
|
+
{
|
|
74
|
+
content:
|
|
75
|
+
"",
|
|
76
|
+
widgets: {},
|
|
77
|
+
images: {},
|
|
78
|
+
},
|
|
79
|
+
{
|
|
80
|
+
content:
|
|
81
|
+
"",
|
|
82
|
+
widgets: {},
|
|
83
|
+
images: {},
|
|
84
|
+
},
|
|
85
|
+
{
|
|
86
|
+
content:
|
|
87
|
+
"",
|
|
88
|
+
widgets: {},
|
|
89
|
+
images: {},
|
|
90
|
+
},
|
|
91
|
+
{
|
|
92
|
+
content:
|
|
93
|
+
"",
|
|
94
|
+
widgets: {},
|
|
95
|
+
images: {},
|
|
96
|
+
},
|
|
97
|
+
{
|
|
98
|
+
content:
|
|
99
|
+
"",
|
|
100
|
+
widgets: {},
|
|
101
|
+
images: {},
|
|
102
|
+
},
|
|
103
|
+
],
|
|
104
|
+
height: "auto",
|
|
105
|
+
layout: "horizontal",
|
|
106
|
+
options: [
|
|
107
|
+
{
|
|
108
|
+
content:
|
|
109
|
+
"",
|
|
110
|
+
widgets: {},
|
|
111
|
+
images: {},
|
|
112
|
+
},
|
|
113
|
+
],
|
|
114
|
+
otherOptions: [],
|
|
115
|
+
},
|
|
116
|
+
type: "orderer",
|
|
117
|
+
version: {
|
|
118
|
+
major: 0,
|
|
119
|
+
minor: 0,
|
|
120
|
+
},
|
|
121
|
+
},
|
|
122
|
+
},
|
|
123
|
+
};
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
|
|
3
|
+
import {RendererWithDebugUI} from "../../../../../../testing/renderer-with-debug-ui";
|
|
4
|
+
|
|
5
|
+
export default {
|
|
6
|
+
title: "Perseus/Widgets/Deprecated Standin",
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
const question1 = {
|
|
10
|
+
content:
|
|
11
|
+
"Read the excerpt and answer the question below. \n\nThe Governor and Council of the Massachusetts had much conference many days; and at last . . . . concluded a peace and friendship with [[\u2603 definition 1]], upon these conditions.",
|
|
12
|
+
images: {},
|
|
13
|
+
widgets: {
|
|
14
|
+
"definition 1": {
|
|
15
|
+
graded: true,
|
|
16
|
+
version: {
|
|
17
|
+
major: 0,
|
|
18
|
+
minor: 0,
|
|
19
|
+
},
|
|
20
|
+
static: false,
|
|
21
|
+
type: "deprecated-standin",
|
|
22
|
+
options: {
|
|
23
|
+
static: false,
|
|
24
|
+
},
|
|
25
|
+
alignment: "default",
|
|
26
|
+
},
|
|
27
|
+
},
|
|
28
|
+
} as const;
|
|
29
|
+
|
|
30
|
+
type StoryArgs = Record<any, any>;
|
|
31
|
+
|
|
32
|
+
export const Question1 = (args: StoryArgs): React.ReactElement => {
|
|
33
|
+
return <RendererWithDebugUI question={question1} />;
|
|
34
|
+
};
|
package/src/widgets/deprecated-standin/__tests__/__snapshots__/deprecated-standin.test.ts.snap
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
|
2
|
+
|
|
3
|
+
exports[`Deprecated Standin widget should have a default snapshot: first render 1`] = `
|
|
4
|
+
<div>
|
|
5
|
+
<div
|
|
6
|
+
class="perseus-renderer perseus-renderer-responsive"
|
|
7
|
+
>
|
|
8
|
+
<div
|
|
9
|
+
class="paragraph"
|
|
10
|
+
data-perseus-paragraph-index="0"
|
|
11
|
+
>
|
|
12
|
+
<div
|
|
13
|
+
class="paragraph"
|
|
14
|
+
>
|
|
15
|
+
Read the excerpt and answer the question below.
|
|
16
|
+
</div>
|
|
17
|
+
</div>
|
|
18
|
+
<div
|
|
19
|
+
class="paragraph"
|
|
20
|
+
data-perseus-paragraph-index="1"
|
|
21
|
+
>
|
|
22
|
+
<div
|
|
23
|
+
class="paragraph"
|
|
24
|
+
>
|
|
25
|
+
The Governor and Council of the Massachusetts had much conference many days; and at last . . . . concluded a peace and friendship with
|
|
26
|
+
<div
|
|
27
|
+
class="perseus-widget-container widget-nohighlight widget-block"
|
|
28
|
+
>
|
|
29
|
+
<div
|
|
30
|
+
style="padding-top: 8px; padding-bottom: 8px;"
|
|
31
|
+
>
|
|
32
|
+
<div
|
|
33
|
+
aria-live="polite"
|
|
34
|
+
class="default_xu2jcg-o_O-containerOuter_xu9ezy-o_O-inlineStyles_1ozd0sx"
|
|
35
|
+
role="alert"
|
|
36
|
+
>
|
|
37
|
+
<div
|
|
38
|
+
class="default_xu2jcg-o_O-backgroundColor_10s9e9d-o_O-inlineStyles_tkl0uy"
|
|
39
|
+
/>
|
|
40
|
+
<div
|
|
41
|
+
class="default_xu2jcg-o_O-containerInner_mm2xcu"
|
|
42
|
+
>
|
|
43
|
+
<span
|
|
44
|
+
aria-label="warning"
|
|
45
|
+
class="svg_1q6jc65-o_O-icon_1521uiv-o_O-icon_16tp01m-o_O-inlineStyles_g0hdza"
|
|
46
|
+
data-test-id="banner-kind-icon"
|
|
47
|
+
role="img"
|
|
48
|
+
/>
|
|
49
|
+
<div
|
|
50
|
+
class="default_xu2jcg-o_O-labelAndButtonsContainer_14rogkt"
|
|
51
|
+
>
|
|
52
|
+
<div
|
|
53
|
+
class="default_xu2jcg-o_O-labelContainer_1fjq5ke"
|
|
54
|
+
>
|
|
55
|
+
<span
|
|
56
|
+
class="text_f1191h-o_O-LabelSmall_hl4zs1"
|
|
57
|
+
>
|
|
58
|
+
This part of the question is no-longer available. You will not be graded on this part.
|
|
59
|
+
</span>
|
|
60
|
+
</div>
|
|
61
|
+
</div>
|
|
62
|
+
</div>
|
|
63
|
+
</div>
|
|
64
|
+
</div>
|
|
65
|
+
</div>
|
|
66
|
+
, upon these conditions.
|
|
67
|
+
</div>
|
|
68
|
+
</div>
|
|
69
|
+
</div>
|
|
70
|
+
</div>
|
|
71
|
+
`;
|