@khanacademy/perseus 60.0.1 → 61.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/dist/es/index.js +43 -27
- package/dist/es/index.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.js +43 -30
- package/dist/index.js.map +1 -1
- package/dist/perseus-version.d.ts +0 -4
- package/dist/server-item-renderer.d.ts +1 -1
- package/dist/types.d.ts +2 -3
- package/dist/util/test-utils.d.ts +1 -12
- package/dist/util.d.ts +5 -0
- package/dist/widgets/expression/expression.d.ts +4 -4
- package/dist/widgets/graded-group/graded-group.d.ts +2 -2
- package/dist/widgets/graded-group-set/graded-group-set.d.ts +2 -2
- package/dist/widgets/grapher/grapher.d.ts +2 -2
- package/dist/widgets/group/group.d.ts +2 -2
- package/dist/widgets/input-number/input-number.d.ts +3 -3
- package/dist/widgets/interactive-graph.d.ts +2 -2
- package/dist/widgets/interactive-graphs/types.d.ts +1 -1
- package/dist/widgets/matcher/matcher.d.ts +2 -2
- package/dist/widgets/matrix/matrix.d.ts +2 -2
- package/dist/widgets/measurer/measurer.d.ts +1 -1
- package/dist/widgets/mock-widgets/mock-widget.d.ts +2 -2
- package/dist/widgets/numeric-input/numeric-input.class.d.ts +1 -1
- package/dist/widgets/numeric-input/numeric-input.d.ts +3 -3
- package/dist/widgets/orderer/orderer.d.ts +2 -2
- package/dist/widgets/phet-simulation/phet-simulation.d.ts +1 -1
- package/dist/widgets/plotter/plotter.d.ts +2 -2
- package/dist/widgets/radio/base-radio.new.d.ts +49 -0
- package/dist/widgets/radio/choice-a11y-text.new.d.ts +14 -0
- package/dist/widgets/radio/choice-icon/choice-icon.new.d.ts +23 -0
- package/dist/widgets/radio/choice-none-above.new.d.ts +6 -0
- package/dist/widgets/radio/choice.new.d.ts +23 -0
- package/dist/widgets/radio/focus-ring.new.d.ts +19 -0
- package/dist/widgets/radio/option-status.new.d.ts +24 -0
- package/dist/widgets/radio/radio-component.new.d.ts +63 -0
- package/dist/widgets/radio/radio.d.ts +1 -1
- package/dist/widgets/radio/radio.ff.d.ts +24 -0
- package/dist/widgets/sorter/sorter.d.ts +2 -2
- package/dist/widgets/table/table.d.ts +23 -17
- package/dist/widgets/table/test-util.d.ts +2 -0
- package/package.json +11 -11
|
@@ -149,7 +149,7 @@ declare const ref: React.ForwardRefExoticComponent<Omit<Pick<SharedRendererProps
|
|
|
149
149
|
canScrollPage?: boolean;
|
|
150
150
|
crossOutEnabled?: boolean;
|
|
151
151
|
editorChangeDelay?: number;
|
|
152
|
-
flags?: Record<
|
|
152
|
+
flags?: Record<"new-radio-widget", boolean>;
|
|
153
153
|
onWidgetStartProps?: (widgets: import("@khanacademy/perseus-core").PerseusWidgetsMap) => void;
|
|
154
154
|
}> | undefined;
|
|
155
155
|
linterContext?: PerseusLinter.LinterContextProps | undefined;
|
package/dist/types.d.ts
CHANGED
|
@@ -3,7 +3,7 @@ import type { PerseusStrings } from "./strings";
|
|
|
3
3
|
import type { SizeClass } from "./util/sizing-utils";
|
|
4
4
|
import type { WidgetPromptJSON } from "./widget-ai-utils/prompt-types";
|
|
5
5
|
import type { KeypadAPI } from "@khanacademy/math-input";
|
|
6
|
-
import type { Hint, PerseusAnswerArea, PerseusGraphType, PerseusWidget, PerseusWidgetsMap, AnalyticsEventHandlerFn, Version, WidgetOptionsUpgradeMap, Rubric, UserInput, UserInputArray, UserInputMap } from "@khanacademy/perseus-core";
|
|
6
|
+
import type { Hint, PerseusAnswerArea, PerseusGraphType, PerseusFeatureFlags, PerseusWidget, PerseusWidgetsMap, AnalyticsEventHandlerFn, Version, WidgetOptionsUpgradeMap, Rubric, UserInput, UserInputArray, UserInputMap } from "@khanacademy/perseus-core";
|
|
7
7
|
import type { LinterContextProps } from "@khanacademy/perseus-linter";
|
|
8
8
|
import type { Result } from "@khanacademy/wonder-blocks-data";
|
|
9
9
|
import type * as React from "react";
|
|
@@ -81,7 +81,6 @@ export type ChangeHandler = (arg1: {
|
|
|
81
81
|
images?: ImageDict;
|
|
82
82
|
question?: any;
|
|
83
83
|
answerArea?: PerseusAnswerArea | null;
|
|
84
|
-
itemDataVersion?: Version;
|
|
85
84
|
editorMode?: EditorMode;
|
|
86
85
|
jsonMode?: boolean;
|
|
87
86
|
value?: any;
|
|
@@ -225,7 +224,7 @@ export type APIOptions = Readonly<{
|
|
|
225
224
|
* Feature flags that can be passed from consuming application.
|
|
226
225
|
* Define the feature flag name in packages/perseus-core/src/feature-flags.ts
|
|
227
226
|
*/
|
|
228
|
-
flags?: Record<
|
|
227
|
+
flags?: Record<(typeof PerseusFeatureFlags)[number], boolean>;
|
|
229
228
|
/**
|
|
230
229
|
* This is a callback function that returns all of the Widget props
|
|
231
230
|
* after they have been transformed by the widget's transform function.
|
|
@@ -1,19 +1,8 @@
|
|
|
1
|
-
import type { CategorizerWidget, ExpressionWidget, InteractiveGraphWidget, NumericInputWidget,
|
|
2
|
-
export declare const genericPerseusItemData: PerseusItem;
|
|
1
|
+
import type { CategorizerWidget, ExpressionWidget, InteractiveGraphWidget, NumericInputWidget, PerseusRenderer, RadioWidget, PerseusScore, UserInputMap } from "@khanacademy/perseus-core";
|
|
3
2
|
/**
|
|
4
3
|
* Thin wrapper around scorePerseusItem for internal testing
|
|
5
4
|
*/
|
|
6
5
|
export declare function scorePerseusItemTesting(perseusRenderData: PerseusRenderer, userInputMap: UserInputMap): PerseusScore;
|
|
7
|
-
/**
|
|
8
|
-
* Generate a Perseus item object for testing purposes.
|
|
9
|
-
*
|
|
10
|
-
* In order to better type Perseus objects used in testing, this function
|
|
11
|
-
* uses a basic Perseus object and updates it with custom values as needed.
|
|
12
|
-
*
|
|
13
|
-
* @param {Partial<PerseusItem>} customFields
|
|
14
|
-
* @returns {PerseusItem}
|
|
15
|
-
*/
|
|
16
|
-
export declare function generateTestPerseusItem(customFields?: Partial<PerseusItem>): PerseusItem;
|
|
17
6
|
/**
|
|
18
7
|
* Creates an object with the bare amount
|
|
19
8
|
* of data to be a properly typed RadioWidget
|
package/dist/util.d.ts
CHANGED
|
@@ -41,6 +41,10 @@ declare function inputPathsEqual(a?: ReadonlyArray<string> | null, b?: ReadonlyA
|
|
|
41
41
|
*/
|
|
42
42
|
declare function firstNumericalParse(text: string): ParsedValue | null | undefined;
|
|
43
43
|
declare function stringArrayOfSize(size: number): ReadonlyArray<string>;
|
|
44
|
+
declare function stringArrayOfSize2D(opt: {
|
|
45
|
+
rows: number;
|
|
46
|
+
columns: number;
|
|
47
|
+
}): ReadonlyArray<ReadonlyArray<string>>;
|
|
44
48
|
/**
|
|
45
49
|
* For a graph's x or y dimension, given the tick step,
|
|
46
50
|
* the ranges extent (e.g. [-10, 10]), the pixel dimension constraint,
|
|
@@ -166,6 +170,7 @@ declare const Util: {
|
|
|
166
170
|
readonly split: (str: string, r: RegExp) => ReadonlyArray<string>;
|
|
167
171
|
readonly firstNumericalParse: typeof firstNumericalParse;
|
|
168
172
|
readonly stringArrayOfSize: typeof stringArrayOfSize;
|
|
173
|
+
readonly stringArrayOfSize2D: typeof stringArrayOfSize2D;
|
|
169
174
|
readonly gridDimensionConfig: typeof gridDimensionConfig;
|
|
170
175
|
readonly getGridStep: typeof getGridStep;
|
|
171
176
|
readonly snapStepFromGridStep: typeof snapStepFromGridStep;
|
|
@@ -14,7 +14,7 @@ type RenderProps = {
|
|
|
14
14
|
ariaLabel: PerseusExpressionWidgetOptions["ariaLabel"];
|
|
15
15
|
keypadConfiguration: KeypadConfiguration;
|
|
16
16
|
};
|
|
17
|
-
type ExternalProps = WidgetProps<RenderProps
|
|
17
|
+
type ExternalProps = WidgetProps<RenderProps>;
|
|
18
18
|
type Props = ExternalProps & Partial<React.ContextType<typeof DependenciesContext>> & {
|
|
19
19
|
apiOptions: NonNullable<ExternalProps["apiOptions"]>;
|
|
20
20
|
buttonSets: NonNullable<ExternalProps["buttonSets"]>;
|
|
@@ -112,7 +112,7 @@ declare const _default: {
|
|
|
112
112
|
canScrollPage?: boolean;
|
|
113
113
|
crossOutEnabled?: boolean;
|
|
114
114
|
editorChangeDelay?: number;
|
|
115
|
-
flags?: Record<
|
|
115
|
+
flags?: Record<"new-radio-widget", boolean>;
|
|
116
116
|
onWidgetStartProps?: (widgets: import("@khanacademy/perseus-core").PerseusWidgetsMap) => void;
|
|
117
117
|
}> & {
|
|
118
118
|
baseElements: NonNullable<import("../..").APIOptions["baseElements"]>;
|
|
@@ -132,7 +132,7 @@ declare const _default: {
|
|
|
132
132
|
onFocus: (blurPath: FocusPath) => void;
|
|
133
133
|
onBlur: (blurPath: FocusPath) => void;
|
|
134
134
|
findWidgets: (criterion: import("../../types").FilterCriterion) => ReadonlyArray<Widget>;
|
|
135
|
-
reviewModeRubric?:
|
|
135
|
+
reviewModeRubric?: Empty | null | undefined;
|
|
136
136
|
reviewMode: boolean;
|
|
137
137
|
onChange: import("../..").ChangeHandler;
|
|
138
138
|
trackInteraction: (extraData?: Empty | undefined) => void;
|
|
@@ -185,7 +185,7 @@ declare const _default: {
|
|
|
185
185
|
canScrollPage?: boolean;
|
|
186
186
|
crossOutEnabled?: boolean;
|
|
187
187
|
editorChangeDelay?: number;
|
|
188
|
-
flags?: Record<
|
|
188
|
+
flags?: Record<"new-radio-widget", boolean>;
|
|
189
189
|
onWidgetStartProps?: (widgets: import("@khanacademy/perseus-core").PerseusWidgetsMap) => void;
|
|
190
190
|
}> & {
|
|
191
191
|
baseElements: NonNullable<import("../..").APIOptions["baseElements"]>;
|
|
@@ -4,7 +4,7 @@ import Renderer from "../../renderer";
|
|
|
4
4
|
import type { ANSWER_BAR_STATES } from "./graded-group-answer-bar";
|
|
5
5
|
import type { FocusPath, TrackingGradedGroupExtraArguments, Widget, WidgetProps } from "../../types";
|
|
6
6
|
import type { GradedGroupPromptJSON } from "../../widget-ai-utils/graded-group/graded-group-ai-utils";
|
|
7
|
-
import type { PerseusGradedGroupWidgetOptions
|
|
7
|
+
import type { PerseusGradedGroupWidgetOptions } from "@khanacademy/perseus-core";
|
|
8
8
|
declare const GRADING_STATUSES: {
|
|
9
9
|
readonly ungraded: "ungraded";
|
|
10
10
|
readonly correct: "correct";
|
|
@@ -12,7 +12,7 @@ declare const GRADING_STATUSES: {
|
|
|
12
12
|
readonly invalid: "invalid";
|
|
13
13
|
};
|
|
14
14
|
type RenderProps = PerseusGradedGroupWidgetOptions;
|
|
15
|
-
type Props = WidgetProps<RenderProps,
|
|
15
|
+
type Props = WidgetProps<RenderProps, undefined, TrackingGradedGroupExtraArguments> & {
|
|
16
16
|
inGradedGroupSet?: boolean;
|
|
17
17
|
onNextQuestion?: () => unknown;
|
|
18
18
|
};
|
|
@@ -3,9 +3,9 @@ import * as Changeable from "../../mixins/changeable";
|
|
|
3
3
|
import { GradedGroup } from "../graded-group/graded-group";
|
|
4
4
|
import type { FocusPath, Widget, WidgetProps } from "../../types";
|
|
5
5
|
import type { GradedGroupSetPromptJSON } from "../../widget-ai-utils/graded-group-set/graded-group-set-ai-utils";
|
|
6
|
-
import type { PerseusGradedGroupSetWidgetOptions
|
|
6
|
+
import type { PerseusGradedGroupSetWidgetOptions } from "@khanacademy/perseus-core";
|
|
7
7
|
type RenderProps = PerseusGradedGroupSetWidgetOptions;
|
|
8
|
-
type Props = Changeable.ChangeableProps & WidgetProps<RenderProps
|
|
8
|
+
type Props = Changeable.ChangeableProps & WidgetProps<RenderProps> & {
|
|
9
9
|
trackInteraction: () => void;
|
|
10
10
|
};
|
|
11
11
|
type DefaultProps = {
|
|
@@ -4,14 +4,14 @@ import type { Coord } from "../../interactive2/types";
|
|
|
4
4
|
import type { Widget, WidgetProps } from "../../types";
|
|
5
5
|
import type { GridDimensions } from "../../util";
|
|
6
6
|
import type { GrapherPromptJSON } from "../../widget-ai-utils/grapher/grapher-ai-utils";
|
|
7
|
-
import type { MarkingsType, PerseusGrapherWidgetOptions,
|
|
7
|
+
import type { MarkingsType, PerseusGrapherWidgetOptions, PerseusGrapherUserInput } from "@khanacademy/perseus-core";
|
|
8
8
|
import type { PropsFor } from "@khanacademy/wonder-blocks-core";
|
|
9
9
|
type RenderProps = {
|
|
10
10
|
availableTypes: PerseusGrapherWidgetOptions["availableTypes"];
|
|
11
11
|
graph: PerseusGrapherWidgetOptions["graph"];
|
|
12
12
|
plot?: any;
|
|
13
13
|
};
|
|
14
|
-
type ExternalProps = WidgetProps<RenderProps
|
|
14
|
+
type ExternalProps = WidgetProps<RenderProps>;
|
|
15
15
|
type Props = ExternalProps & {
|
|
16
16
|
plot: NonNullable<RenderProps["plot"]>;
|
|
17
17
|
markings: MarkingsType;
|
|
@@ -3,9 +3,9 @@ import { PerseusI18nContext } from "../../components/i18n-context";
|
|
|
3
3
|
import Renderer from "../../renderer";
|
|
4
4
|
import type { ChangeFn, FocusPath, Widget, WidgetProps } from "../../types";
|
|
5
5
|
import type { GroupPromptJSON } from "../../widget-ai-utils/group/group-ai-utils";
|
|
6
|
-
import type { PerseusGroupWidgetOptions,
|
|
6
|
+
import type { PerseusGroupWidgetOptions, UserInputArray, UserInputMap } from "@khanacademy/perseus-core";
|
|
7
7
|
type RenderProps = PerseusGroupWidgetOptions;
|
|
8
|
-
type Props = WidgetProps<RenderProps
|
|
8
|
+
type Props = WidgetProps<RenderProps>;
|
|
9
9
|
type DefaultProps = {
|
|
10
10
|
content: Props["content"];
|
|
11
11
|
widgets: Props["widgets"];
|
|
@@ -2,21 +2,21 @@ import * as React from "react";
|
|
|
2
2
|
import { PerseusI18nContext } from "../../components/i18n-context";
|
|
3
3
|
import type { Path, Widget, WidgetProps } from "../../types";
|
|
4
4
|
import type { InputNumberPromptJSON } from "../../widget-ai-utils/input-number/input-number-ai-utils";
|
|
5
|
-
import type { PerseusInputNumberWidgetOptions,
|
|
5
|
+
import type { PerseusInputNumberWidgetOptions, PerseusInputNumberUserInput } from "@khanacademy/perseus-core";
|
|
6
6
|
type RenderProps = {
|
|
7
7
|
simplify: PerseusInputNumberWidgetOptions["simplify"];
|
|
8
8
|
size: PerseusInputNumberWidgetOptions["size"];
|
|
9
9
|
answerType: PerseusInputNumberWidgetOptions["answerType"];
|
|
10
10
|
rightAlign: PerseusInputNumberWidgetOptions["rightAlign"];
|
|
11
11
|
};
|
|
12
|
-
type ExternalProps = WidgetProps<RenderProps
|
|
12
|
+
type ExternalProps = WidgetProps<RenderProps>;
|
|
13
13
|
type Props = ExternalProps & {
|
|
14
14
|
apiOptions: NonNullable<ExternalProps["apiOptions"]>;
|
|
15
15
|
linterContext: NonNullable<ExternalProps["linterContext"]>;
|
|
16
16
|
rightAlign: NonNullable<ExternalProps["rightAlign"]>;
|
|
17
17
|
size: NonNullable<ExternalProps["size"]>;
|
|
18
18
|
currentValue: string;
|
|
19
|
-
answerType: NonNullable<
|
|
19
|
+
answerType: NonNullable<ExternalProps["answerType"]>;
|
|
20
20
|
};
|
|
21
21
|
type DefaultProps = {
|
|
22
22
|
answerType: Props["answerType"];
|
|
@@ -6,7 +6,7 @@ import type { WidgetProps } from "../types";
|
|
|
6
6
|
import type { InteractiveGraphPromptJSON } from "../widget-ai-utils/interactive-graph/interactive-graph-ai-utils";
|
|
7
7
|
import type { UnsupportedWidgetPromptJSON } from "../widget-ai-utils/unsupported-widget";
|
|
8
8
|
import type { QuadraticCoefficient, SineCoefficient, Range } from "@khanacademy/kmath";
|
|
9
|
-
import type { PerseusGraphType, PerseusGraphTypeAngle, PerseusGraphTypePoint, PerseusGraphTypeSegment, GraphRange, LockedFigure, PerseusImageBackground, MarkingsType,
|
|
9
|
+
import type { PerseusGraphType, PerseusGraphTypeAngle, PerseusGraphTypePoint, PerseusGraphTypeSegment, GraphRange, LockedFigure, PerseusImageBackground, MarkingsType, PerseusInteractiveGraphUserInput } from "@khanacademy/perseus-core";
|
|
10
10
|
type RenderProps = {
|
|
11
11
|
/**
|
|
12
12
|
* Where the little black axis lines & labels (ticks) should render.
|
|
@@ -104,7 +104,7 @@ type RenderProps = {
|
|
|
104
104
|
*/
|
|
105
105
|
fullGraphAriaDescription?: string;
|
|
106
106
|
};
|
|
107
|
-
type Props = WidgetProps<RenderProps
|
|
107
|
+
type Props = WidgetProps<RenderProps>;
|
|
108
108
|
type State = any;
|
|
109
109
|
type DefaultProps = {
|
|
110
110
|
labels: ReadonlyArray<string>;
|
|
@@ -5,7 +5,7 @@ import type { QuadraticCoords } from "@khanacademy/kmath";
|
|
|
5
5
|
import type { PerseusInteractiveGraphWidgetOptions } from "@khanacademy/perseus-core";
|
|
6
6
|
import type { Interval, vec } from "mafs";
|
|
7
7
|
import type { ReactNode } from "react";
|
|
8
|
-
export type InteractiveGraphProps = WidgetProps<PerseusInteractiveGraphWidgetOptions
|
|
8
|
+
export type InteractiveGraphProps = WidgetProps<PerseusInteractiveGraphWidgetOptions>;
|
|
9
9
|
export type Dispatch = (action: InteractiveGraphAction) => unknown;
|
|
10
10
|
export type MafsGraphProps<T extends InteractiveGraphState> = {
|
|
11
11
|
graphState: T;
|
|
@@ -3,9 +3,9 @@ import { PerseusI18nContext } from "../../components/i18n-context";
|
|
|
3
3
|
import type { SortableOption } from "../../components/sortable";
|
|
4
4
|
import type { WidgetProps, Widget } from "../../types";
|
|
5
5
|
import type { MatcherPromptJSON } from "../../widget-ai-utils/matcher/matcher-ai-utils";
|
|
6
|
-
import type { PerseusMatcherWidgetOptions,
|
|
6
|
+
import type { PerseusMatcherWidgetOptions, PerseusMatcherUserInput } from "@khanacademy/perseus-core";
|
|
7
7
|
type RenderProps = PerseusMatcherWidgetOptions;
|
|
8
|
-
type Props = WidgetProps<RenderProps
|
|
8
|
+
type Props = WidgetProps<RenderProps>;
|
|
9
9
|
type DefaultProps = {
|
|
10
10
|
left: Props["left"];
|
|
11
11
|
right: Props["right"];
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type
|
|
1
|
+
import { type PerseusMatrixUserInput, type PerseusMatrixWidgetAnswers } from "@khanacademy/perseus-core";
|
|
2
2
|
import * as React from "react";
|
|
3
3
|
import { PerseusI18nContext } from "../../components/i18n-context";
|
|
4
4
|
import type { FocusPath, Widget, WidgetProps } from "../../types";
|
|
@@ -10,7 +10,7 @@ type ExternalProps = WidgetProps<{
|
|
|
10
10
|
cursorPosition: ReadonlyArray<number>;
|
|
11
11
|
matrixBoardSize: ReadonlyArray<number>;
|
|
12
12
|
static?: boolean | undefined;
|
|
13
|
-
}
|
|
13
|
+
}>;
|
|
14
14
|
type Props = ExternalProps & {
|
|
15
15
|
onChange: (arg1: {
|
|
16
16
|
cursorPosition?: ReadonlyArray<number>;
|
|
@@ -2,7 +2,7 @@ import { type PerseusMeasurerWidgetOptions } from "@khanacademy/perseus-core";
|
|
|
2
2
|
import * as React from "react";
|
|
3
3
|
import type { Widget, WidgetProps } from "../../types";
|
|
4
4
|
import type { UnsupportedWidgetPromptJSON } from "../../widget-ai-utils/unsupported-widget";
|
|
5
|
-
type Props = WidgetProps<PerseusMeasurerWidgetOptions
|
|
5
|
+
type Props = WidgetProps<PerseusMeasurerWidgetOptions> & {
|
|
6
6
|
protractorX: number;
|
|
7
7
|
protractorY: number;
|
|
8
8
|
};
|
|
@@ -2,8 +2,8 @@ import * as React from "react";
|
|
|
2
2
|
import type { MockWidgetOptions } from "./mock-widget-types";
|
|
3
3
|
import type { WidgetProps, Widget, FocusPath } from "../../types";
|
|
4
4
|
import type { MockWidgetPromptJSON } from "../../widget-ai-utils/mock-widget/prompt-utils";
|
|
5
|
-
import type {
|
|
6
|
-
type ExternalProps = WidgetProps<MockWidgetOptions
|
|
5
|
+
import type { PerseusMockWidgetUserInput } from "@khanacademy/perseus-score";
|
|
6
|
+
type ExternalProps = WidgetProps<MockWidgetOptions>;
|
|
7
7
|
type DefaultProps = {
|
|
8
8
|
currentValue: Props["currentValue"];
|
|
9
9
|
};
|
|
@@ -2,7 +2,7 @@ import * as React from "react";
|
|
|
2
2
|
import type { FocusPath, Widget, WidgetProps } from "../../types";
|
|
3
3
|
import type { NumericInputPromptJSON } from "../../widget-ai-utils/numeric-input/prompt-utils";
|
|
4
4
|
import type { PerseusNumericInputWidgetOptions, PerseusNumericInputAnswerForm, PerseusNumericInputRubric, PerseusNumericInputUserInput } from "@khanacademy/perseus-core";
|
|
5
|
-
type ExternalProps = WidgetProps<PerseusNumericInputWidgetOptions
|
|
5
|
+
type ExternalProps = WidgetProps<PerseusNumericInputWidgetOptions>;
|
|
6
6
|
export type NumericInputProps = ExternalProps & {
|
|
7
7
|
size: NonNullable<ExternalProps["size"]>;
|
|
8
8
|
rightAlign: NonNullable<ExternalProps["rightAlign"]>;
|
|
@@ -42,7 +42,7 @@ export declare const NumericInputComponent: React.ForwardRefExoticComponent<impo
|
|
|
42
42
|
canScrollPage?: boolean;
|
|
43
43
|
crossOutEnabled?: boolean;
|
|
44
44
|
editorChangeDelay?: number;
|
|
45
|
-
flags?: Record<
|
|
45
|
+
flags?: Record<"new-radio-widget", boolean>;
|
|
46
46
|
onWidgetStartProps?: (widgets: import("@khanacademy/perseus-core").PerseusWidgetsMap) => void;
|
|
47
47
|
}> & {
|
|
48
48
|
baseElements: NonNullable<import("../..").APIOptions["baseElements"]>;
|
|
@@ -62,7 +62,7 @@ export declare const NumericInputComponent: React.ForwardRefExoticComponent<impo
|
|
|
62
62
|
onFocus: (blurPath: import("../..").FocusPath) => void;
|
|
63
63
|
onBlur: (blurPath: import("../..").FocusPath) => void;
|
|
64
64
|
findWidgets: (criterion: import("../../types").FilterCriterion) => ReadonlyArray<import("../../types").Widget>;
|
|
65
|
-
reviewModeRubric?:
|
|
65
|
+
reviewModeRubric?: Empty | null | undefined;
|
|
66
66
|
reviewMode: boolean;
|
|
67
67
|
onChange: import("../..").ChangeHandler;
|
|
68
68
|
trackInteraction: (extraData?: Empty | undefined) => void;
|
|
@@ -105,7 +105,7 @@ export declare const NumericInputComponent: React.ForwardRefExoticComponent<impo
|
|
|
105
105
|
canScrollPage?: boolean;
|
|
106
106
|
crossOutEnabled?: boolean;
|
|
107
107
|
editorChangeDelay?: number;
|
|
108
|
-
flags?: Record<
|
|
108
|
+
flags?: Record<"new-radio-widget", boolean>;
|
|
109
109
|
onWidgetStartProps?: (widgets: import("@khanacademy/perseus-core").PerseusWidgetsMap) => void;
|
|
110
110
|
}> & {
|
|
111
111
|
baseElements: NonNullable<import("../..").APIOptions["baseElements"]>;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
2
|
import type { Widget, WidgetProps } from "../../types";
|
|
3
3
|
import type { OrdererPromptJSON } from "../../widget-ai-utils/orderer/orderer-ai-utils";
|
|
4
|
-
import type { PerseusOrdererWidgetOptions,
|
|
4
|
+
import type { PerseusOrdererWidgetOptions, PerseusOrdererUserInput } from "@khanacademy/perseus-core";
|
|
5
5
|
type Position = {
|
|
6
6
|
left: number;
|
|
7
7
|
top: number;
|
|
@@ -9,7 +9,7 @@ type Position = {
|
|
|
9
9
|
type RenderProps = PerseusOrdererWidgetOptions & {
|
|
10
10
|
current: any;
|
|
11
11
|
};
|
|
12
|
-
type OrdererProps = WidgetProps<RenderProps
|
|
12
|
+
type OrdererProps = WidgetProps<RenderProps>;
|
|
13
13
|
type OrdererDefaultProps = {
|
|
14
14
|
current: OrdererProps["current"];
|
|
15
15
|
options: OrdererProps["options"];
|
|
@@ -8,7 +8,7 @@ import type { WidgetProps, Widget } from "../../types";
|
|
|
8
8
|
import type { UnsupportedWidgetPromptJSON } from "../../widget-ai-utils/unsupported-widget";
|
|
9
9
|
import type { PerseusPhetSimulationWidgetOptions } from "@khanacademy/perseus-core";
|
|
10
10
|
type RenderProps = PerseusPhetSimulationWidgetOptions;
|
|
11
|
-
type Props = WidgetProps<RenderProps
|
|
11
|
+
type Props = WidgetProps<RenderProps>;
|
|
12
12
|
type State = {
|
|
13
13
|
banner: {
|
|
14
14
|
message: string;
|
|
@@ -2,9 +2,9 @@ import * as React from "react";
|
|
|
2
2
|
import { PerseusI18nContext } from "../../components/i18n-context";
|
|
3
3
|
import type { Widget, WidgetProps } from "../../types";
|
|
4
4
|
import type { UnsupportedWidgetPromptJSON } from "../../widget-ai-utils/unsupported-widget";
|
|
5
|
-
import type { PerseusPlotterWidgetOptions,
|
|
5
|
+
import type { PerseusPlotterWidgetOptions, PerseusPlotterUserInput } from "@khanacademy/perseus-core";
|
|
6
6
|
type RenderProps = PerseusPlotterWidgetOptions;
|
|
7
|
-
type Props = WidgetProps<RenderProps
|
|
7
|
+
type Props = WidgetProps<RenderProps> & {
|
|
8
8
|
labelInterval: NonNullable<PerseusPlotterWidgetOptions["labelInterval"]>;
|
|
9
9
|
picSize: NonNullable<PerseusPlotterWidgetOptions["picSize"]>;
|
|
10
10
|
};
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { type PerseusRadioWidgetOptions } from "@khanacademy/perseus-core";
|
|
2
|
+
import * as React from "react";
|
|
3
|
+
import type { APIOptions } from "../../types";
|
|
4
|
+
export type ChoiceType = {
|
|
5
|
+
checked: boolean;
|
|
6
|
+
crossedOut: boolean;
|
|
7
|
+
content: React.ReactNode;
|
|
8
|
+
rationale: React.ReactNode;
|
|
9
|
+
hasRationale: boolean;
|
|
10
|
+
showRationale: boolean;
|
|
11
|
+
showCorrectness: boolean;
|
|
12
|
+
correct: boolean;
|
|
13
|
+
isNoneOfTheAbove: boolean;
|
|
14
|
+
highlighted: boolean;
|
|
15
|
+
previouslyAnswered: boolean;
|
|
16
|
+
revealNoneOfTheAbove: boolean;
|
|
17
|
+
disabled: boolean;
|
|
18
|
+
};
|
|
19
|
+
export type FocusFunction = (choiceIndex?: number | null | undefined) => boolean;
|
|
20
|
+
type Props = {
|
|
21
|
+
apiOptions: APIOptions;
|
|
22
|
+
choices: ReadonlyArray<ChoiceType>;
|
|
23
|
+
deselectEnabled?: boolean;
|
|
24
|
+
editMode?: boolean;
|
|
25
|
+
labelWrap: boolean;
|
|
26
|
+
countChoices: boolean | null | undefined;
|
|
27
|
+
numCorrect: number;
|
|
28
|
+
multipleSelect?: boolean;
|
|
29
|
+
reviewModeRubric?: PerseusRadioWidgetOptions | null;
|
|
30
|
+
reviewMode: boolean;
|
|
31
|
+
onChange: (newValues: {
|
|
32
|
+
checked: ReadonlyArray<boolean>;
|
|
33
|
+
crossedOut: ReadonlyArray<boolean>;
|
|
34
|
+
}) => void;
|
|
35
|
+
registerFocusFunction?: (arg1: FocusFunction) => void;
|
|
36
|
+
isLastUsedWidget?: boolean;
|
|
37
|
+
};
|
|
38
|
+
/**
|
|
39
|
+
* The BaseRadio component is the core component for the radio widget.
|
|
40
|
+
* It is responsible for rendering the radio choices and handling user interactions.
|
|
41
|
+
*
|
|
42
|
+
* This component is a duplicate of the BaseRadio component in base-radio.tsx for the
|
|
43
|
+
* Radio Revitalization Project. (LEMS-2933) This component will eventually replace
|
|
44
|
+
* base-radio.tsx when the feature flag is no longer needed.
|
|
45
|
+
*
|
|
46
|
+
* TODO(LEMS-2994): Clean up this file.
|
|
47
|
+
*/
|
|
48
|
+
declare const BaseRadio: ({ apiOptions, reviewModeRubric, reviewMode, choices, editMode, multipleSelect, labelWrap, countChoices, numCorrect, isLastUsedWidget, onChange, registerFocusFunction, }: Props) => React.ReactElement;
|
|
49
|
+
export default BaseRadio;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { PerseusStrings } from "../../strings";
|
|
2
|
+
/**
|
|
3
|
+
* This function is used to generate the a11y text for the radio widget.
|
|
4
|
+
* It is used in the radio-component.tsx file to generate the a11y text for the radio widget.
|
|
5
|
+
*
|
|
6
|
+
* This function is a duplicate of the getA11yText function in choice-a11y-text.ts
|
|
7
|
+
* for the Radio Revitalization Project. (LEMS-2933)
|
|
8
|
+
*
|
|
9
|
+
* This function will eventually replace choice-a11y-text.ts when the feature flag is no longer needed.
|
|
10
|
+
*
|
|
11
|
+
* TODO(LEMS-2994): Clean up this file.
|
|
12
|
+
*/
|
|
13
|
+
declare function getA11yText(letter: string, checked: boolean, correct: boolean, crossedOut: boolean, showCorrectness: boolean, strings: PerseusStrings): string;
|
|
14
|
+
export default getA11yText;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
type ChoiceIconProps = {
|
|
3
|
+
pos: number;
|
|
4
|
+
checked: boolean;
|
|
5
|
+
crossedOut: boolean;
|
|
6
|
+
focused: boolean;
|
|
7
|
+
hovered: boolean;
|
|
8
|
+
pressed: boolean;
|
|
9
|
+
correct: boolean;
|
|
10
|
+
showCorrectness: boolean;
|
|
11
|
+
multipleSelect: boolean;
|
|
12
|
+
reviewMode: boolean;
|
|
13
|
+
previouslyAnswered: boolean;
|
|
14
|
+
};
|
|
15
|
+
/**
|
|
16
|
+
* This component is a duplicate of the ChoiceIcon component in choice-icon.tsx
|
|
17
|
+
* for the Radio Revitalization Project. (LEMS-2933)
|
|
18
|
+
* This component will eventually replace choice-icon.tsx when the feature flag is no longer needed.
|
|
19
|
+
*
|
|
20
|
+
* TODO(LEMS-2994): Clean up this file.
|
|
21
|
+
*/
|
|
22
|
+
declare const ChoiceIcon: (props: ChoiceIconProps) => React.ReactElement;
|
|
23
|
+
export default ChoiceIcon;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import type { APIOptions } from "../../types";
|
|
3
|
+
export type ChoiceProps = {
|
|
4
|
+
apiOptions?: APIOptions;
|
|
5
|
+
checked?: boolean;
|
|
6
|
+
rationale: React.ReactNode;
|
|
7
|
+
content: React.ReactNode;
|
|
8
|
+
correct?: boolean;
|
|
9
|
+
disabled?: boolean;
|
|
10
|
+
pos: number;
|
|
11
|
+
reviewMode: boolean;
|
|
12
|
+
showRationale: boolean;
|
|
13
|
+
showCorrectness: boolean;
|
|
14
|
+
multipleSelect: boolean;
|
|
15
|
+
crossedOut: boolean;
|
|
16
|
+
previouslyAnswered?: boolean;
|
|
17
|
+
onChange?: (newValues: {
|
|
18
|
+
checked: boolean;
|
|
19
|
+
crossedOut: boolean;
|
|
20
|
+
}) => void;
|
|
21
|
+
};
|
|
22
|
+
declare const _default: React.ForwardRefExoticComponent<ChoiceProps & React.RefAttributes<HTMLButtonElement>>;
|
|
23
|
+
export default _default;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Renders a circular selection ring around the child.
|
|
3
|
+
*/
|
|
4
|
+
import * as React from "react";
|
|
5
|
+
type Props = {
|
|
6
|
+
children?: React.ReactNode;
|
|
7
|
+
visible?: boolean;
|
|
8
|
+
color?: string;
|
|
9
|
+
multipleSelect?: boolean;
|
|
10
|
+
};
|
|
11
|
+
/**
|
|
12
|
+
* This component is a duplicate of the FocusRing component in focus-ring.tsx
|
|
13
|
+
* for the Radio Revitalization Project. (LEMS-2933)
|
|
14
|
+
* This component will eventually replace focus-ring.tsx when the feature flag is no longer needed.
|
|
15
|
+
*
|
|
16
|
+
* TODO(LEMS-2994): Clean up this file.
|
|
17
|
+
*/
|
|
18
|
+
declare const FocusRing: ({ visible, color, multipleSelect, children, }: Props) => React.ReactElement;
|
|
19
|
+
export default FocusRing;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Renders text indicating whether the choice was correct or
|
|
3
|
+
* not and whether the choice was selected or not.
|
|
4
|
+
* This information is redundant with that provided in the
|
|
5
|
+
* ChoiceIcon visualizations but is meant to make the distinctions
|
|
6
|
+
* between the states more immediately clear to users.
|
|
7
|
+
*/
|
|
8
|
+
import * as React from "react";
|
|
9
|
+
type Props = {
|
|
10
|
+
correct: boolean;
|
|
11
|
+
checked: boolean;
|
|
12
|
+
crossedOut: boolean;
|
|
13
|
+
previouslyAnswered: boolean;
|
|
14
|
+
reviewMode: boolean;
|
|
15
|
+
};
|
|
16
|
+
/**
|
|
17
|
+
* This component is a duplicate of the OptionStatus component in option-status.tsx
|
|
18
|
+
* for the Radio Revitalization Project. (LEMS-2933)
|
|
19
|
+
* This component will eventually replace option-status.tsx when the feature flag is no longer needed.
|
|
20
|
+
*
|
|
21
|
+
* TODO(LEMS-2994): Clean up this file.
|
|
22
|
+
*/
|
|
23
|
+
declare const OptionStatus: (props: Props) => React.ReactElement;
|
|
24
|
+
export default OptionStatus;
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import { PerseusI18nContext } from "../../components/i18n-context";
|
|
3
|
+
import type { FocusFunction } from "./base-radio.new";
|
|
4
|
+
import type { WidgetProps, ChoiceState, Widget } from "../../types";
|
|
5
|
+
import type { RadioPromptJSON } from "../../widget-ai-utils/radio/radio-ai-utils";
|
|
6
|
+
import type { PerseusRadioChoice, PerseusRadioWidgetOptions, ShowSolutions, PerseusRadioRubric, PerseusRadioUserInput } from "@khanacademy/perseus-core";
|
|
7
|
+
export type RenderProps = {
|
|
8
|
+
numCorrect: number;
|
|
9
|
+
hasNoneOfTheAbove?: boolean;
|
|
10
|
+
multipleSelect?: boolean;
|
|
11
|
+
countChoices?: boolean;
|
|
12
|
+
deselectEnabled?: boolean;
|
|
13
|
+
choices: ReadonlyArray<RadioChoiceWithMetadata>;
|
|
14
|
+
selectedChoices: ReadonlyArray<PerseusRadioChoice["correct"]>;
|
|
15
|
+
showSolutions?: ShowSolutions;
|
|
16
|
+
choiceStates?: ReadonlyArray<ChoiceState>;
|
|
17
|
+
values?: ReadonlyArray<boolean>;
|
|
18
|
+
};
|
|
19
|
+
type Props = WidgetProps<RenderProps, PerseusRadioRubric>;
|
|
20
|
+
type DefaultProps = Required<Pick<Props, "choices" | "multipleSelect" | "countChoices" | "deselectEnabled" | "linterContext" | "showSolutions">>;
|
|
21
|
+
export type RadioChoiceWithMetadata = PerseusRadioChoice & {
|
|
22
|
+
originalIndex: number;
|
|
23
|
+
correct?: boolean;
|
|
24
|
+
};
|
|
25
|
+
/**
|
|
26
|
+
* This component is a duplicate of the Radio component in radio.tsx
|
|
27
|
+
* for the Radio Revitalization Project. (LEMS-2933)
|
|
28
|
+
* This component will be split up to move the rendering logic to a new functional component.
|
|
29
|
+
* This file will be renamed to radio.class.tsx and will supercede radio-component.tsx when
|
|
30
|
+
* the feature flag is no longer needed.
|
|
31
|
+
*
|
|
32
|
+
* TODO(LEMS-2994): Clean up this file.
|
|
33
|
+
*/
|
|
34
|
+
declare class Radio extends React.Component<Props> implements Widget {
|
|
35
|
+
static contextType: React.Context<import("../../components/i18n-context").I18nContextType>;
|
|
36
|
+
context: React.ContextType<typeof PerseusI18nContext>;
|
|
37
|
+
focusFunction: FocusFunction;
|
|
38
|
+
static defaultProps: DefaultProps;
|
|
39
|
+
static getUserInputFromProps(props: Props, unshuffle?: boolean): PerseusRadioUserInput;
|
|
40
|
+
componentDidUpdate(prevProps: Props): void;
|
|
41
|
+
_renderRenderer: (content?: string) => React.ReactElement;
|
|
42
|
+
focus(choiceIndex?: number | null): boolean;
|
|
43
|
+
registerFocusFunction(fun: FocusFunction): void;
|
|
44
|
+
updateChoices: (newValueLists: Readonly<{
|
|
45
|
+
checked: ReadonlyArray<boolean>;
|
|
46
|
+
crossedOut: ReadonlyArray<boolean>;
|
|
47
|
+
}>) => void;
|
|
48
|
+
getUserInput(): PerseusRadioUserInput;
|
|
49
|
+
getPromptJSON(): RadioPromptJSON;
|
|
50
|
+
/**
|
|
51
|
+
* Turn on rationale display for the currently selected choices. Note that
|
|
52
|
+
* this leaves rationales on for choices that are already showing
|
|
53
|
+
* rationales.
|
|
54
|
+
* @deprecated Internal only. Use `showSolutions` prop instead.
|
|
55
|
+
*/
|
|
56
|
+
showRationalesForCurrentlySelectedChoices: (arg1: PerseusRadioWidgetOptions) => void;
|
|
57
|
+
/**
|
|
58
|
+
* Deselects any currently-selected choices that are not correct choices.
|
|
59
|
+
*/
|
|
60
|
+
deselectIncorrectSelectedChoices: () => void;
|
|
61
|
+
render(): React.ReactNode;
|
|
62
|
+
}
|
|
63
|
+
export default Radio;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import RadioOld from "./radio-component";
|
|
3
|
+
import RadioNew from "./radio-component.new";
|
|
4
|
+
import type { RenderProps } from "./radio-component";
|
|
5
|
+
import type { WidgetProps } from "../../types";
|
|
6
|
+
import type { PerseusRadioRubric } from "@khanacademy/perseus-core";
|
|
7
|
+
type Props = WidgetProps<RenderProps, PerseusRadioRubric>;
|
|
8
|
+
/**
|
|
9
|
+
* This is a wrapper around the old radio widget that allows us to
|
|
10
|
+
* conditionally render the new radio widget when the feature flag is on.
|
|
11
|
+
*
|
|
12
|
+
* This is necessary to ensure that we do not interrupt the assessment studies
|
|
13
|
+
* that are currently running.
|
|
14
|
+
*
|
|
15
|
+
* TODO(LEMS-2994): Clean up this file.
|
|
16
|
+
*/
|
|
17
|
+
declare class Radio extends RadioOld {
|
|
18
|
+
ffIsOn: boolean;
|
|
19
|
+
radioRef: React.RefObject<RadioOld | RadioNew>;
|
|
20
|
+
constructor(props: Props);
|
|
21
|
+
focus(choiceIndex?: number | null): boolean;
|
|
22
|
+
render(): React.ReactNode;
|
|
23
|
+
}
|
|
24
|
+
export default Radio;
|