@khanacademy/perseus 77.0.3 → 77.2.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.
Files changed (42) hide show
  1. package/dist/es/index.css +3 -3
  2. package/dist/es/index.css.map +1 -1
  3. package/dist/es/index.js +32 -32
  4. package/dist/es/index.js.map +1 -1
  5. package/dist/es/strings.js +1 -1
  6. package/dist/es/strings.js.map +1 -1
  7. package/dist/index.css +3 -3
  8. package/dist/index.css.map +1 -1
  9. package/dist/index.d.ts +1 -1
  10. package/dist/index.js +30 -29
  11. package/dist/index.js.map +1 -1
  12. package/dist/strings.d.ts +50 -0
  13. package/dist/strings.js +1 -1
  14. package/dist/strings.js.map +1 -1
  15. package/dist/types.d.ts +0 -6
  16. package/dist/widget-ai-utils/interactive-graph/interactive-graph-ai-utils.d.ts +12 -2
  17. package/dist/widget-ai-utils/radio/radio-ai-utils.d.ts +1 -1
  18. package/dist/widgets/dropdown/dropdown.d.ts +0 -1
  19. package/dist/widgets/expression/expression.d.ts +0 -2
  20. package/dist/widgets/image/utils.d.ts +6 -0
  21. package/dist/widgets/interactive-graphs/graphs/exponential.d.ts +2 -2
  22. package/dist/widgets/interactive-graphs/graphs/logarithm.d.ts +12 -0
  23. package/dist/widgets/interactive-graphs/graphs/utils.d.ts +25 -0
  24. package/dist/widgets/interactive-graphs/interactive-graph-question-builder.d.ts +6 -0
  25. package/dist/widgets/interactive-graphs/interactive-graph.d.ts +5 -2
  26. package/dist/widgets/interactive-graphs/reducer/initialize-graph-state.d.ts +5 -1
  27. package/dist/widgets/interactive-graphs/reducer/interactive-graph-action.d.ts +4 -0
  28. package/dist/widgets/interactive-graphs/types.d.ts +7 -1
  29. package/dist/widgets/label-image/label-image.d.ts +0 -1
  30. package/dist/widgets/mock-widgets/mock-widget.d.ts +0 -1
  31. package/dist/widgets/numeric-input/numeric-input.class.d.ts +0 -1
  32. package/dist/widgets/numeric-input/numeric-input.d.ts +0 -1
  33. package/dist/widgets/radio/index.d.ts +16 -1
  34. package/dist/widgets/radio/{multiple-choice-component.d.ts → radio-component.d.ts} +7 -7
  35. package/dist/widgets/radio/radio-widget.d.ts +49 -0
  36. package/dist/widgets/radio/util.d.ts +1 -1
  37. package/dist/widgets/radio/utils/general-utils.d.ts +1 -1
  38. package/dist/widgets/table/table.d.ts +0 -1
  39. package/package.json +19 -19
  40. package/dist/widgets/radio/multiple-choice-widget.d.ts +0 -110
  41. package/dist/widgets/radio/radio.d.ts +0 -16
  42. package/dist/widgets/radio/radio.ff.d.ts +0 -112
@@ -56,7 +56,6 @@ export declare const Expression: React.ForwardRefExoticComponent<PerseusExpressi
56
56
  showAlignmentOptions: NonNullable<import("../..").APIOptions["showAlignmentOptions"]>;
57
57
  }>;
58
58
  keypadElement?: any;
59
- questionCompleted?: boolean;
60
59
  onFocus: (blurPath: FocusPath) => void;
61
60
  onBlur: (blurPath: FocusPath) => void;
62
61
  findWidgets: (criterion: import("../../types").FilterCriterion) => ReadonlyArray<Widget>;
@@ -136,7 +135,6 @@ declare const _default: {
136
135
  showAlignmentOptions: NonNullable<import("../..").APIOptions["showAlignmentOptions"]>;
137
136
  }>;
138
137
  keypadElement?: any;
139
- questionCompleted?: boolean;
140
138
  onFocus: (blurPath: FocusPath) => void;
141
139
  onBlur: (blurPath: FocusPath) => void;
142
140
  findWidgets: (criterion: import("../../types").FilterCriterion) => ReadonlyArray<Widget>;
@@ -30,7 +30,13 @@ export declare const graphieImage: {
30
30
  width: number;
31
31
  height: number;
32
32
  };
33
+ export declare const graphieImage2: {
34
+ url: string;
35
+ width: number;
36
+ height: number;
37
+ };
33
38
  export declare const graphieImageAlt = "An array of isosceles triangles. A triangle has height A. Two smaller triangle, one with height B and one with height C, have approximately the same combined height as A.";
39
+ export declare const graphieImage2Alt = "A picture graph shows the horizontal axis labeled Number of insects and the vertical axis labeled Types of insects. Each type of insect is listed along the vertical axis from bottom to top as follows: Beetle, Cricket, Ant, Mosquito, and Bee. The number of insects for each type of insect is represented by the number of pictures of ladybugs plotted on the graph. Beetle is represented by 5 pictures of ladybugs, Cricket is represented by 4 pictures of ladybugs, Ant is represented by 3 pictures of ladybugs, Mosquito is represented by 6 pictures of ladybugs, and Bee is represented by 3 pictures of ladybugs.";
34
40
  export declare const gifImage: {
35
41
  url: string;
36
42
  width: number;
@@ -1,10 +1,10 @@
1
- import { vec } from "mafs";
2
1
  import { type I18nContextType } from "../../../components/i18n-context";
3
2
  import type { ExponentialGraphState, Dispatch, InteractiveGraphElementSuite } from "../types";
4
3
  import type { Coord } from "@khanacademy/perseus-core";
4
+ import type { Interval, vec } from "mafs";
5
5
  export declare function renderExponentialGraph(state: ExponentialGraphState, dispatch: Dispatch, i18n: I18nContextType): InteractiveGraphElementSuite;
6
6
  export declare const constrainAsymptoteKeyboard: (p: vec.Vector2, coords: ReadonlyArray<Coord>, snapStep: vec.Vector2) => vec.Vector2;
7
- export declare const getExponentialKeyboardConstraint: (coords: ReadonlyArray<Coord>, asymptote: number, snapStep: vec.Vector2, pointIndex: number) => {
7
+ export declare const getExponentialKeyboardConstraint: (coords: ReadonlyArray<Coord>, asymptote: number, snapStep: vec.Vector2, pointIndex: number, range: [Interval, Interval]) => {
8
8
  up: vec.Vector2;
9
9
  down: vec.Vector2;
10
10
  left: vec.Vector2;
@@ -0,0 +1,12 @@
1
+ import { type I18nContextType } from "../../../components/i18n-context";
2
+ import type { LogarithmGraphState, Dispatch, InteractiveGraphElementSuite } from "../types";
3
+ import type { Coord } from "@khanacademy/perseus-core";
4
+ import type { Interval, vec } from "mafs";
5
+ export declare function renderLogarithmGraph(state: LogarithmGraphState, dispatch: Dispatch, i18n: I18nContextType): InteractiveGraphElementSuite;
6
+ export declare const constrainAsymptoteKeyboard: (p: vec.Vector2, coords: ReadonlyArray<Coord>, snapStep: vec.Vector2) => vec.Vector2;
7
+ export declare const getLogarithmKeyboardConstraint: (coords: ReadonlyArray<Coord>, asymptote: number, snapStep: vec.Vector2, pointIndex: number, range: [Interval, Interval]) => {
8
+ up: vec.Vector2;
9
+ down: vec.Vector2;
10
+ left: vec.Vector2;
11
+ right: vec.Vector2;
12
+ };
@@ -36,3 +36,28 @@ export declare function getPolygonSideString(sideLength: number, pointIndex: num
36
36
  * The radius scales with the range so it's visible at all graph sizes.
37
37
  */
38
38
  export declare function calculateScaledRadius(range: [Interval, Interval]): number;
39
+ /**
40
+ * Shared keyboard constraint logic for asymptote-based graph points
41
+ * (exponential, logarithm). Computes the next valid position for each
42
+ * arrow-key direction, skipping up to 3 snap steps to avoid positions
43
+ * rejected by the caller's `isValidPosition` predicate.
44
+ *
45
+ * The per-graph validity rules differ (exponential checks Y vs asymptote and
46
+ * X vs other point; logarithm checks X vs asymptote and Y vs other point),
47
+ * so they are injected via the callback.
48
+ */
49
+ export declare function getAsymptoteGraphKeyboardConstraint(coords: ReadonlyArray<Coord>, snapStep: vec.Vector2, pointIndex: number, isValidPosition: (coord: vec.Vector2) => boolean): {
50
+ up: vec.Vector2;
51
+ down: vec.Vector2;
52
+ left: vec.Vector2;
53
+ right: vec.Vector2;
54
+ };
55
+ /**
56
+ * Shared keyboard constraint for asymptote movement (exponential, logarithm).
57
+ * When the next snapped position would land between or on the curve points,
58
+ * snaps past all of them in the direction of travel using a midpoint heuristic.
59
+ *
60
+ * @param orientation - "horizontal" for exponential (asymptote moves on Y-axis),
61
+ * "vertical" for logarithm (asymptote moves on X-axis).
62
+ */
63
+ export declare function constrainAsymptoteKeyboardMovement(p: vec.Vector2, coords: ReadonlyArray<Coord>, snapStep: vec.Vector2, orientation: "horizontal" | "vertical"): vec.Vector2;
@@ -130,6 +130,12 @@ declare class InteractiveGraphQuestionBuilder {
130
130
  snapDegrees?: number;
131
131
  match?: "congruent";
132
132
  }): InteractiveGraphQuestionBuilder;
133
+ withLogarithm(options?: {
134
+ coords?: [Coord, Coord];
135
+ asymptote?: number;
136
+ startCoords?: [Coord, Coord];
137
+ startAsymptote?: number;
138
+ }): InteractiveGraphQuestionBuilder;
133
139
  withAbsoluteValue(options?: {
134
140
  coords?: [Coord, Coord];
135
141
  startCoords?: [Coord, Coord];
@@ -161,7 +161,9 @@ declare class InteractiveGraph extends React.Component<Props, State> {
161
161
  problemNum: number | null | undefined;
162
162
  apiOptions: Readonly<Readonly<{
163
163
  isArticle?: boolean;
164
- onFocusChange?: (newFocusPath: import("../..").FocusPath, oldFocusPath: import("../..").FocusPath, keypadHeight?: number, focusedElement?: HTMLElement) => unknown;
164
+ onFocusChange?: (newFocusPath: import("../..").FocusPath, oldFocusPath: import("../..").FocusPath, keypadHeight?: number, focusedElement? /**
165
+ * Whether to show the arrows on the axis.
166
+ */: HTMLElement) => unknown;
165
167
  showAlignmentOptions?: boolean;
166
168
  readOnly?: boolean;
167
169
  editingDisabled?: boolean;
@@ -206,7 +208,6 @@ declare class InteractiveGraph extends React.Component<Props, State> {
206
208
  showAlignmentOptions: NonNullable<import("../..").APIOptions["showAlignmentOptions"]>;
207
209
  }>;
208
210
  keypadElement?: any;
209
- questionCompleted?: boolean;
210
211
  onFocus: (blurPath: import("../..").FocusPath) => void;
211
212
  onBlur: (blurPath: import("../..").FocusPath) => void;
212
213
  findWidgets: (criterion: import("../../types").FilterCriterion) => ReadonlyArray<import("../../types").Widget>;
@@ -260,6 +261,8 @@ declare class InteractiveGraph extends React.Component<Props, State> {
260
261
  static getSinusoidEquationString(props: Props): string;
261
262
  static defaultExponentialCoords(props: Props): Coord[];
262
263
  static getExponentialEquationString(props: Props): string;
264
+ static defaultLogarithmCoords(props: Props): Coord[];
265
+ static getLogarithmEquationString(props: Props): string;
263
266
  static getAbsoluteValueEquationString(props: Props): string;
264
267
  static getCurrentTangentCoefficients(props: Props): TangentCoefficient;
265
268
  static defaultTangentCoords(props: Props): Coord[];
@@ -1,6 +1,6 @@
1
1
  import type { Coord } from "../../../interactive2/types";
2
2
  import type { InteractiveGraphState, PairOfPoints } from "../types";
3
- import type { PerseusGraphType, PerseusGraphTypeAbsoluteValue, PerseusGraphTypeAngle, PerseusGraphTypeCircle, PerseusGraphTypeLinear, PerseusGraphTypeLinearSystem, PerseusGraphTypePoint, PerseusGraphTypePolygon, PerseusGraphTypeQuadratic, PerseusGraphTypeRay, PerseusGraphTypeSegment, PerseusGraphTypeSinusoid, PerseusGraphTypeExponential, PerseusGraphTypeTangent } from "@khanacademy/perseus-core";
3
+ import type { PerseusGraphType, PerseusGraphTypeAbsoluteValue, PerseusGraphTypeAngle, PerseusGraphTypeCircle, PerseusGraphTypeLinear, PerseusGraphTypeLinearSystem, PerseusGraphTypePoint, PerseusGraphTypePolygon, PerseusGraphTypeQuadratic, PerseusGraphTypeRay, PerseusGraphTypeSegment, PerseusGraphTypeSinusoid, PerseusGraphTypeExponential, PerseusGraphTypeTangent, PerseusGraphTypeLogarithm } from "@khanacademy/perseus-core";
4
4
  import type { Interval } from "mafs";
5
5
  export type InitializeGraphStateParams = {
6
6
  range: [x: Interval, y: Interval];
@@ -26,6 +26,10 @@ export declare function getExponentialCoords(graph: PerseusGraphTypeExponential,
26
26
  coords: [Coord, Coord];
27
27
  asymptote: number;
28
28
  };
29
+ export declare function getLogarithmCoords(graph: PerseusGraphTypeLogarithm, range: [x: Interval, y: Interval], step: [x: number, y: number]): {
30
+ coords: [Coord, Coord];
31
+ asymptote: number;
32
+ };
29
33
  export declare const getAngleCoords: (params: {
30
34
  graph: PerseusGraphTypeAngle;
31
35
  range: [x: Interval, y: Interval];
@@ -60,6 +60,10 @@ export declare const actions: {
60
60
  movePoint: typeof movePoint;
61
61
  moveCenter: typeof moveCenter;
62
62
  };
63
+ logarithm: {
64
+ movePoint: typeof movePoint;
65
+ moveCenter: typeof moveCenter;
66
+ };
63
67
  absoluteValue: {
64
68
  movePoint: typeof movePoint;
65
69
  };
@@ -15,7 +15,7 @@ export type InteractiveGraphElementSuite = {
15
15
  graph: ReactNode;
16
16
  interactiveElementsDescription: ReactNode;
17
17
  };
18
- export type InteractiveGraphState = AbsoluteValueGraphState | AngleGraphState | SegmentGraphState | LinearSystemGraphState | LinearGraphState | RayGraphState | NoneGraphState | PolygonGraphState | PointGraphState | CircleGraphState | QuadraticGraphState | SinusoidGraphState | ExponentialGraphState | TangentGraphState;
18
+ export type InteractiveGraphState = AbsoluteValueGraphState | AngleGraphState | SegmentGraphState | LinearSystemGraphState | LinearGraphState | RayGraphState | NoneGraphState | PolygonGraphState | PointGraphState | CircleGraphState | QuadraticGraphState | SinusoidGraphState | ExponentialGraphState | TangentGraphState | LogarithmGraphState;
19
19
  export type UnlimitedGraphState = PointGraphState | PolygonGraphState;
20
20
  export interface InteractiveGraphStateCommon {
21
21
  hasBeenInteractedWith: boolean;
@@ -91,6 +91,12 @@ export interface TangentGraphState extends InteractiveGraphStateCommon {
91
91
  type: "tangent";
92
92
  coords: [vec.Vector2, vec.Vector2];
93
93
  }
94
+ export interface LogarithmGraphState extends InteractiveGraphStateCommon {
95
+ type: "logarithm";
96
+ coords: [vec.Vector2, vec.Vector2];
97
+ /** The x-value of the vertical asymptote (x = asymptote). */
98
+ asymptote: number;
99
+ }
94
100
  export interface AngleGraphState extends InteractiveGraphStateCommon {
95
101
  type: "angle";
96
102
  showAngles?: boolean;
@@ -165,7 +165,6 @@ declare const _default: {
165
165
  showAlignmentOptions: NonNullable<import("../..").APIOptions["showAlignmentOptions"]>;
166
166
  }>;
167
167
  keypadElement?: any;
168
- questionCompleted?: boolean;
169
168
  onFocus: (blurPath: import("../..").FocusPath) => void;
170
169
  onBlur: (blurPath: import("../..").FocusPath) => void;
171
170
  findWidgets: (criterion: import("../../types").FilterCriterion) => ReadonlyArray<Widget>;
@@ -89,7 +89,6 @@ declare class MockWidgetComponent extends React.Component<Props> implements Widg
89
89
  showAlignmentOptions: NonNullable<import("../..").APIOptions["showAlignmentOptions"]>;
90
90
  }>;
91
91
  keypadElement?: any;
92
- questionCompleted?: boolean;
93
92
  onFocus: (blurPath: import("../..").FocusPath) => void;
94
93
  onBlur: (blurPath: import("../..").FocusPath) => void;
95
94
  findWidgets: (criterion: import("../../types").FilterCriterion) => ReadonlyArray<Widget>;
@@ -96,7 +96,6 @@ export declare class NumericInput extends React.Component<NumericInputProps> imp
96
96
  showAlignmentOptions: NonNullable<import("../..").APIOptions["showAlignmentOptions"]>;
97
97
  }>;
98
98
  keypadElement?: any;
99
- questionCompleted?: boolean;
100
99
  onFocus: (blurPath: import("../..").FocusPath) => void;
101
100
  onBlur: (blurPath: import("../..").FocusPath) => void;
102
101
  findWidgets: (criterion: import("../../types").FilterCriterion) => ReadonlyArray<Widget>;
@@ -59,7 +59,6 @@ export declare const NumericInputComponent: React.ForwardRefExoticComponent<impo
59
59
  showAlignmentOptions: NonNullable<import("../..").APIOptions["showAlignmentOptions"]>;
60
60
  }>;
61
61
  keypadElement?: any;
62
- questionCompleted?: boolean;
63
62
  onFocus: (blurPath: import("../..").FocusPath) => void;
64
63
  onBlur: (blurPath: import("../..").FocusPath) => void;
65
64
  findWidgets: (criterion: import("../../types").FilterCriterion) => ReadonlyArray<import("../../types").Widget>;
@@ -1 +1,16 @@
1
- export { default } from "./radio";
1
+ import Radio from "./radio-widget";
2
+ import type { PerseusRadioUserInput } from "@khanacademy/perseus-core";
3
+ declare function getStartUserInput(): PerseusRadioUserInput;
4
+ declare const _default: {
5
+ name: string;
6
+ displayName: string;
7
+ widget: typeof Radio;
8
+ getStartUserInput: typeof getStartUserInput;
9
+ version: import("@khanacademy/perseus-core").Version | undefined;
10
+ isLintable: true;
11
+ /**
12
+ * @deprecated - do not use in new code.
13
+ */
14
+ getUserInputFromSerializedState: (serializedState: unknown) => PerseusRadioUserInput;
15
+ };
16
+ export default _default;
@@ -1,9 +1,9 @@
1
1
  import React from "react";
2
- import type { ChoiceType } from "./multiple-choice-widget";
2
+ import type { ChoiceType } from "./radio-widget";
3
3
  /**
4
- * Props for the MultipleChoiceComponent
4
+ * Props for the RadioComponent
5
5
  */
6
- export interface MultipleChoiceComponentProps {
6
+ export interface RadioComponentProps {
7
7
  choices: ReadonlyArray<ChoiceType>;
8
8
  countChoices: boolean | null | undefined;
9
9
  multipleSelect?: boolean;
@@ -12,10 +12,10 @@ export interface MultipleChoiceComponentProps {
12
12
  reviewMode: boolean;
13
13
  }
14
14
  /**
15
- * The MultipleChoiceComponent renders the UI for multiple choice questions.
15
+ * The RadioComponent renders the UI for multiple choice questions.
16
16
  *
17
17
  * This component handles the presentation of choices, user interactions,
18
- * and accessibility features, while the MultipleChoiceWidget manages the
18
+ * and accessibility features, while the RadioWidget manages the
19
19
  * underlying logic and state.
20
20
  *
21
21
  * Supports both radio button (single select) and checkbox (multiple select) modes.
@@ -49,5 +49,5 @@ export interface MultipleChoiceComponentProps {
49
49
  *
50
50
  * Created as part of the Radio Revitalization Project (LEMS-2933).
51
51
  */
52
- declare const MultipleChoiceComponent: ({ choices, countChoices, multipleSelect, numCorrect, onChoiceChange, reviewMode, }: MultipleChoiceComponentProps) => React.ReactElement;
53
- export default MultipleChoiceComponent;
52
+ declare const RadioComponent: ({ choices, countChoices, multipleSelect, numCorrect, onChoiceChange, reviewMode, }: RadioComponentProps) => React.ReactElement;
53
+ export default RadioComponent;
@@ -0,0 +1,49 @@
1
+ import * as React from "react";
2
+ import type { WidgetProps, ChoiceState, Widget } from "../../types";
3
+ import type { RadioPromptJSON } from "../../widget-ai-utils/radio/radio-ai-utils";
4
+ import type { PerseusRadioChoice, PerseusRadioRubric, PerseusRadioUserInput } from "@khanacademy/perseus-core";
5
+ /**
6
+ * Represents a single choice in the RadioComponent
7
+ */
8
+ export interface ChoiceType {
9
+ id: string;
10
+ checked: boolean;
11
+ content: React.ReactNode;
12
+ rationale: React.ReactNode;
13
+ hasRationale: boolean;
14
+ correct: boolean;
15
+ isNoneOfTheAbove: boolean;
16
+ }
17
+ export type RadioProps = {
18
+ numCorrect: number;
19
+ hasNoneOfTheAbove?: boolean;
20
+ multipleSelect?: boolean;
21
+ countChoices?: boolean;
22
+ deselectEnabled?: boolean;
23
+ choices: RadioChoiceWithMetadata[];
24
+ choiceStates?: ChoiceState[];
25
+ randomize?: boolean;
26
+ };
27
+ type RadioWidgetHandle = {
28
+ getSerializedState(): any;
29
+ getPromptJSON(): RadioPromptJSON;
30
+ };
31
+ /**
32
+ * RadioChoiceWithMetadata is used for server-side scoring
33
+ */
34
+ export interface RadioChoiceWithMetadata extends PerseusRadioChoice {
35
+ originalIndex: number;
36
+ correct?: boolean;
37
+ }
38
+ type Props = WidgetProps<RadioProps, PerseusRadioUserInput, PerseusRadioRubric>;
39
+ declare class Radio extends React.Component<Props> implements Widget {
40
+ radioRef: React.RefObject<RadioWidgetHandle>;
41
+ /**
42
+ * @deprecated and likely very broken API
43
+ * [LEMS-3185] do not trust serializedState
44
+ */
45
+ getSerializedState(): any;
46
+ getPromptJSON(): RadioPromptJSON;
47
+ render(): React.ReactNode;
48
+ }
49
+ export default Radio;
@@ -1,5 +1,5 @@
1
1
  import { type PerseusRadioUserInput, type PerseusRadioWidgetOptions } from "@khanacademy/perseus-core";
2
- import type { RadioChoiceWithMetadata } from "./multiple-choice-widget";
2
+ import type { RadioChoiceWithMetadata } from "./radio-widget";
3
3
  import type { PerseusStrings } from "../../strings";
4
4
  /**
5
5
  * Given a choice's position in the radio widget, return the corresponding
@@ -1,5 +1,5 @@
1
1
  import type { ChoiceState } from "../../../types";
2
- import type { RadioChoiceWithMetadata } from "../multiple-choice-widget";
2
+ import type { RadioChoiceWithMetadata } from "../radio-widget";
3
3
  import type { ShowSolutions } from "@khanacademy/perseus-core";
4
4
  interface GetChoiceStatesProps {
5
5
  choices: ReadonlyArray<RadioChoiceWithMetadata>;
@@ -97,7 +97,6 @@ declare class Table extends React.Component<Props> implements Widget {
97
97
  showAlignmentOptions: NonNullable<import("../..").APIOptions["showAlignmentOptions"]>;
98
98
  }>;
99
99
  keypadElement?: any;
100
- questionCompleted?: boolean;
101
100
  onFocus: (blurPath: FocusPath) => void;
102
101
  onBlur: (blurPath: FocusPath) => void;
103
102
  findWidgets: (criterion: import("../../types").FilterCriterion) => ReadonlyArray<Widget>;
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": "77.0.3",
6
+ "version": "77.2.0",
7
7
  "publishConfig": {
8
8
  "access": "public"
9
9
  },
@@ -42,38 +42,38 @@
42
42
  "tiny-invariant": "1.3.1",
43
43
  "uuid": "^10.0.0",
44
44
  "@khanacademy/kas": "2.2.1",
45
- "@khanacademy/keypad-context": "3.2.41",
46
- "@khanacademy/math-input": "26.4.11",
47
- "@khanacademy/perseus-core": "24.0.0",
48
- "@khanacademy/kmath": "2.3.1",
49
- "@khanacademy/perseus-linter": "4.9.1",
45
+ "@khanacademy/keypad-context": "3.2.42",
46
+ "@khanacademy/kmath": "2.4.0",
47
+ "@khanacademy/math-input": "26.4.13",
48
+ "@khanacademy/perseus-core": "24.1.0",
49
+ "@khanacademy/perseus-linter": "4.9.2",
50
+ "@khanacademy/perseus-score": "8.6.0",
50
51
  "@khanacademy/perseus-utils": "2.1.5",
51
52
  "@khanacademy/pure-markdown": "2.2.7",
52
- "@khanacademy/simple-markdown": "2.2.2",
53
- "@khanacademy/perseus-score": "8.5.0"
53
+ "@khanacademy/simple-markdown": "2.2.2"
54
54
  },
55
55
  "devDependencies": {
56
- "@khanacademy/wonder-blocks-announcer": "1.0.6",
56
+ "@khanacademy/wonder-blocks-announcer": "1.1.0",
57
57
  "@khanacademy/wonder-blocks-banner": "5.0.18",
58
58
  "@khanacademy/wonder-blocks-button": "11.4.2",
59
59
  "@khanacademy/wonder-blocks-clickable": "8.1.5",
60
60
  "@khanacademy/wonder-blocks-core": "12.4.3",
61
61
  "@khanacademy/wonder-blocks-data": "15.0.1",
62
- "@khanacademy/wonder-blocks-dropdown": "10.8.2",
62
+ "@khanacademy/wonder-blocks-dropdown": "10.8.3",
63
63
  "@khanacademy/wonder-blocks-form": "7.5.6",
64
64
  "@khanacademy/wonder-blocks-icon-button": "11.1.6",
65
65
  "@khanacademy/wonder-blocks-icon": "5.3.9",
66
66
  "@khanacademy/wonder-blocks-labeled-field": "4.0.16",
67
67
  "@khanacademy/wonder-blocks-layout": "3.1.46",
68
68
  "@khanacademy/wonder-blocks-link": "10.1.7",
69
- "@khanacademy/wonder-blocks-modal": "8.5.17",
69
+ "@khanacademy/wonder-blocks-modal": "8.6.0",
70
70
  "@khanacademy/wonder-blocks-pill": "3.1.57",
71
- "@khanacademy/wonder-blocks-popover": "6.1.55",
71
+ "@khanacademy/wonder-blocks-popover": "6.1.56",
72
72
  "@khanacademy/wonder-blocks-progress-spinner": "3.1.46",
73
73
  "@khanacademy/wonder-blocks-switch": "3.3.30",
74
74
  "@khanacademy/wonder-blocks-timing": "7.0.4",
75
75
  "@khanacademy/wonder-blocks-tokens": "16.1.0",
76
- "@khanacademy/wonder-blocks-tooltip": "4.1.68",
76
+ "@khanacademy/wonder-blocks-tooltip": "4.1.69",
77
77
  "@khanacademy/wonder-blocks-typography": "4.2.31",
78
78
  "@khanacademy/wonder-stuff-core": "3.0.0",
79
79
  "@phosphor-icons/core": "2.0.2",
@@ -90,27 +90,27 @@
90
90
  "raphael": "1.5.4"
91
91
  },
92
92
  "peerDependencies": {
93
- "@khanacademy/wonder-blocks-announcer": "^1.0.6",
93
+ "@khanacademy/wonder-blocks-announcer": "^1.1.0",
94
94
  "@khanacademy/wonder-blocks-banner": "^5.0.18",
95
95
  "@khanacademy/wonder-blocks-button": "^11.4.2",
96
96
  "@khanacademy/wonder-blocks-clickable": "^8.1.5",
97
97
  "@khanacademy/wonder-blocks-core": "^12.4.3",
98
98
  "@khanacademy/wonder-blocks-data": "^15.0.1",
99
- "@khanacademy/wonder-blocks-dropdown": "^10.8.2",
99
+ "@khanacademy/wonder-blocks-dropdown": "^10.8.3",
100
100
  "@khanacademy/wonder-blocks-form": "^7.5.6",
101
101
  "@khanacademy/wonder-blocks-icon": "^5.3.9",
102
102
  "@khanacademy/wonder-blocks-icon-button": "^11.1.6",
103
103
  "@khanacademy/wonder-blocks-labeled-field": "^4.0.16",
104
104
  "@khanacademy/wonder-blocks-layout": "^3.1.46",
105
105
  "@khanacademy/wonder-blocks-link": "^10.1.7",
106
- "@khanacademy/wonder-blocks-modal": "^8.5.17",
106
+ "@khanacademy/wonder-blocks-modal": "^8.6.0",
107
107
  "@khanacademy/wonder-blocks-pill": "^3.1.57",
108
- "@khanacademy/wonder-blocks-popover": "^6.1.55",
108
+ "@khanacademy/wonder-blocks-popover": "^6.1.56",
109
109
  "@khanacademy/wonder-blocks-progress-spinner": "^3.1.46",
110
110
  "@khanacademy/wonder-blocks-switch": "^3.3.30",
111
111
  "@khanacademy/wonder-blocks-timing": "^7.0.4",
112
112
  "@khanacademy/wonder-blocks-tokens": "^16.1.0",
113
- "@khanacademy/wonder-blocks-tooltip": "^4.1.68",
113
+ "@khanacademy/wonder-blocks-tooltip": "^4.1.69",
114
114
  "@khanacademy/wonder-blocks-typography": "^4.2.31",
115
115
  "@khanacademy/wonder-stuff-core": "^3.0.0",
116
116
  "@phosphor-icons/core": "^2.0.2",
@@ -126,7 +126,7 @@
126
126
  },
127
127
  "keywords": [],
128
128
  "khan": {
129
- "catalogHash": "f59b84a1576ddc86"
129
+ "catalogHash": "a1f429536c944326"
130
130
  },
131
131
  "scripts": {}
132
132
  }
@@ -1,110 +0,0 @@
1
- import * as React from "react";
2
- import type { ChoiceState } from "../../types";
3
- import type { RadioPromptJSON } from "../../widget-ai-utils/radio/radio-ai-utils";
4
- import type { PerseusRadioChoice, PerseusRadioRubric, PerseusRadioUserInput } from "@khanacademy/perseus-core";
5
- import type { LinterContextProps } from "@khanacademy/perseus-linter";
6
- /**
7
- * Represents a single choice in the MultipleChoiceComponent
8
- */
9
- export interface ChoiceType {
10
- id: string;
11
- checked: boolean;
12
- content: React.ReactNode;
13
- rationale: React.ReactNode;
14
- hasRationale: boolean;
15
- showRationale: boolean;
16
- showCorrectness: boolean;
17
- correct: boolean;
18
- isNoneOfTheAbove: boolean;
19
- previouslyAnswered: boolean;
20
- revealNoneOfTheAbove: boolean;
21
- disabled: boolean;
22
- }
23
- export type RadioProps = {
24
- numCorrect: number;
25
- hasNoneOfTheAbove?: boolean;
26
- multipleSelect?: boolean;
27
- countChoices?: boolean;
28
- deselectEnabled?: boolean;
29
- choices: RadioChoiceWithMetadata[];
30
- choiceStates?: ChoiceState[];
31
- editMode?: boolean;
32
- labelWrap?: boolean;
33
- randomize?: boolean;
34
- };
35
- export type RadioWidgetHandle = {
36
- getPromptJSON(): RadioPromptJSON;
37
- };
38
- /**
39
- * RadioChoiceWithMetadata is used for server-side scoring
40
- */
41
- export interface RadioChoiceWithMetadata extends PerseusRadioChoice {
42
- originalIndex: number;
43
- correct?: boolean;
44
- }
45
- declare const Radio: React.ForwardRefExoticComponent<RadioProps & {
46
- trackInteraction: (extraData?: PerseusRadioRubric | undefined) => void;
47
- widgetId: string;
48
- widgetIndex: number;
49
- alignment: string | null | undefined;
50
- static: boolean | null | undefined;
51
- problemNum: number | null | undefined;
52
- apiOptions: Readonly<Readonly<{
53
- isArticle?: boolean;
54
- onFocusChange?: (newFocusPath: import("../..").FocusPath, oldFocusPath: import("../..").FocusPath, keypadHeight?: number, focusedElement?: HTMLElement) => unknown;
55
- showAlignmentOptions?: boolean;
56
- readOnly?: boolean;
57
- editingDisabled?: boolean;
58
- answerableCallback?: (arg1: boolean) => unknown;
59
- getAnotherHint?: () => unknown;
60
- interactionCallback?: (widgetData: {
61
- [widgetId: string]: any;
62
- }) => void;
63
- imagePlaceholder?: React.ReactNode;
64
- widgetPlaceholder?: React.ReactNode;
65
- baseElements?: {
66
- Link: React.ComponentType<any>;
67
- };
68
- imagePreloader?: (dimensions: import("../../types").Dimensions) => React.ReactNode;
69
- trackInteraction?: (args: {
70
- type: string;
71
- id: string;
72
- correct?: boolean;
73
- } & Partial<import("../../types").TrackingGradedGroupExtraArguments> & Partial<{
74
- visible: number;
75
- }>) => void;
76
- customKeypad?: boolean;
77
- nativeKeypadProxy?: (blur: () => void) => import("@khanacademy/math-input").KeypadAPI;
78
- isMobile?: boolean;
79
- isMobileApp?: boolean;
80
- setDrawingAreaAvailable?: (arg1: boolean) => unknown;
81
- hintProgressColor?: string;
82
- canScrollPage?: boolean;
83
- editorChangeDelay?: number;
84
- flags?: Record<"new-radio-widget" | "image-widget-upgrade-gif-controls" | "image-widget-upgrade-scale" | "interactive-graph-absolute-value" | "interactive-graph-tangent" | "interactive-graph-logarithm" | "interactive-graph-exponent" | "interactive-graph-vector", boolean>;
85
- }> & {
86
- baseElements: NonNullable<import("../..").APIOptions["baseElements"]>;
87
- canScrollPage: NonNullable<import("../..").APIOptions["canScrollPage"]>;
88
- editorChangeDelay: NonNullable<import("../..").APIOptions["editorChangeDelay"]>;
89
- isArticle: NonNullable<import("../..").APIOptions["isArticle"]>;
90
- isMobile: NonNullable<import("../..").APIOptions["isMobile"]>;
91
- isMobileApp: NonNullable<import("../..").APIOptions["isMobileApp"]>;
92
- editingDisabled: NonNullable<import("../..").APIOptions["editingDisabled"]>;
93
- onFocusChange: NonNullable<import("../..").APIOptions["onFocusChange"]>;
94
- readOnly: NonNullable<import("../..").APIOptions["readOnly"]>;
95
- setDrawingAreaAvailable: NonNullable<import("../..").APIOptions["setDrawingAreaAvailable"]>;
96
- showAlignmentOptions: NonNullable<import("../..").APIOptions["showAlignmentOptions"]>;
97
- }>;
98
- keypadElement?: any;
99
- questionCompleted?: boolean;
100
- onFocus: (blurPath: import("../..").FocusPath) => void;
101
- onBlur: (blurPath: import("../..").FocusPath) => void;
102
- findWidgets: (criterion: import("../../types").FilterCriterion) => ReadonlyArray<import("../../types").Widget>;
103
- reviewMode: boolean;
104
- showSolutions?: import("@khanacademy/perseus-core").ShowSolutions;
105
- handleUserInput: (newUserInput: PerseusRadioUserInput, cb?: () => void, silent?: boolean) => void;
106
- userInput: PerseusRadioUserInput;
107
- linterContext: LinterContextProps;
108
- containerSizeClass: import("../../util/sizing-utils").SizeClass;
109
- } & React.RefAttributes<RadioWidgetHandle>>;
110
- export default Radio;
@@ -1,16 +0,0 @@
1
- import Radio from "./radio.ff";
2
- import type { PerseusRadioUserInput } from "@khanacademy/perseus-core";
3
- declare function getStartUserInput(): PerseusRadioUserInput;
4
- declare const _default: {
5
- name: string;
6
- displayName: string;
7
- widget: typeof Radio;
8
- getStartUserInput: typeof getStartUserInput;
9
- version: import("@khanacademy/perseus-core").Version | undefined;
10
- isLintable: true;
11
- /**
12
- * @deprecated - do not use in new code.
13
- */
14
- getUserInputFromSerializedState: (serializedState: unknown) => PerseusRadioUserInput;
15
- };
16
- export default _default;