@khanacademy/perseus 65.1.3 → 65.3.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.
@@ -117,18 +117,6 @@ declare class Renderer extends React.Component<Props, State> implements GetPromp
117
117
  [id: string]: any;
118
118
  };
119
119
  restoreSerializedState: (serializedState: SerializedState, callback?: () => void) => void;
120
- /**
121
- * Tell each of the radio widgets to show rationales for each of the
122
- * currently selected choices inside of them. If the widget is correct, it
123
- * shows rationales for all of the choices. This also disables interaction
124
- * with the choices that we show rationales for.
125
- */
126
- showRationalesForCurrentlySelectedChoices: () => void;
127
- /**
128
- * Tells each of the radio widgets to deselect any of the incorrect choices
129
- * that are currently selected (leaving correct choices still selected).
130
- */
131
- deselectIncorrectSelectedChoices: () => void;
132
120
  /**
133
121
  * Allows inter-widget communication.
134
122
  *
@@ -111,8 +111,6 @@ export declare class ServerItemRenderer extends React.Component<Props, State> im
111
111
  */
112
112
  getSerializedState(): SerializedState;
113
113
  restoreSerializedState(state: SerializedState, callback?: () => void): void;
114
- showRationalesForCurrentlySelectedChoices(): void;
115
- deselectIncorrectSelectedChoices(): void;
116
114
  setAssetStatus: (assetKey: string, status: boolean) => void;
117
115
  render(): React.ReactNode;
118
116
  }
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, PerseusFeatureFlags, PerseusWidget, PerseusWidgetsMap, AnalyticsEventHandlerFn, Version, Rubric, UserInput, UserInputArray, UserInputMap, Relationship, LabelImageMarkerPublicData, PerseusLabelImageMarker } from "@khanacademy/perseus-core";
6
+ import type { Hint, PerseusAnswerArea, PerseusGraphType, PerseusFeatureFlags, PerseusWidget, PerseusWidgetsMap, AnalyticsEventHandlerFn, Version, Rubric, UserInput, UserInputArray, UserInputMap, Relationship, LabelImageMarkerPublicData, PerseusLabelImageMarker, ShowSolutions } 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";
@@ -42,7 +42,6 @@ export interface Widget {
42
42
  path: FocusPath;
43
43
  } | boolean;
44
44
  getDOMNodeForPath?: (path: FocusPath) => Element | Text | null;
45
- deselectIncorrectSelectedChoices?: () => void;
46
45
  /**
47
46
  * Returns widget state that can be passed back to `restoreSerializedState`
48
47
  * to put the widget back into exactly the same state. If the widget does
@@ -57,7 +56,6 @@ export interface Widget {
57
56
  setInputValue?: (path: FocusPath, newValue: string, focus?: () => unknown) => void;
58
57
  getUserInputMap?: () => UserInputMap | undefined;
59
58
  getUserInput?: () => UserInputArray | UserInput | undefined;
60
- showRationalesForCurrentlySelectedChoices?: (options?: any) => void;
61
59
  getPromptJSON?: () => WidgetPromptJSON;
62
60
  }
63
61
  export type ImageDict = {
@@ -405,6 +403,7 @@ export type UniversalWidgetProps<ReviewModeRubric = Empty, TrackingExtraArgs = E
405
403
  onBlur: (blurPath: FocusPath) => void;
406
404
  findWidgets: (criterion: FilterCriterion) => ReadonlyArray<Widget>;
407
405
  reviewMode: boolean;
406
+ showSolutions?: ShowSolutions;
408
407
  onChange: ChangeHandler;
409
408
  isLastUsedWidget: boolean;
410
409
  linterContext: LinterContextProps;
@@ -84,7 +84,7 @@ declare const _default: {
84
84
  visibleLabel: PerseusExpressionWidgetOptions["visibleLabel"];
85
85
  ariaLabel: PerseusExpressionWidgetOptions["ariaLabel"];
86
86
  value: string;
87
- }, "static" | "onChange" | "ariaLabel" | "buttonsVisible" | "containerSizeClass" | "widgetId" | "problemNum" | "questionCompleted" | "findWidgets" | "trackInteraction" | "keypadElement" | "reviewMode" | keyof import("../..").PerseusDependenciesV2 | "reviewModeRubric" | "alignment" | "isLastUsedWidget" | "visibleLabel" | "keypadConfiguration"> & {
87
+ }, "static" | "onChange" | "ariaLabel" | "buttonsVisible" | "containerSizeClass" | "widgetId" | "problemNum" | "questionCompleted" | "findWidgets" | "trackInteraction" | "keypadElement" | "showSolutions" | "reviewMode" | keyof import("../..").PerseusDependenciesV2 | "reviewModeRubric" | "alignment" | "isLastUsedWidget" | "visibleLabel" | "keypadConfiguration"> & {
88
88
  value?: string | undefined;
89
89
  buttonSets?: import("@khanacademy/perseus-core").LegacyButtonSets | undefined;
90
90
  onFocus?: ((blurPath: FocusPath) => void) | undefined;
@@ -40,7 +40,6 @@ declare class Group extends React.Component<Props> implements Widget {
40
40
  focus(): boolean;
41
41
  focusInputPath: (arg1: FocusPath) => void;
42
42
  blurInputPath: (arg1: FocusPath) => void;
43
- showRationalesForCurrentlySelectedChoices: () => void;
44
43
  render(): React.ReactNode;
45
44
  }
46
45
  declare const _default: {
@@ -11,7 +11,7 @@ import Marker from "./marker";
11
11
  import type { DependencyProps } from "../../dependencies";
12
12
  import type { Widget, WidgetProps } from "../../types";
13
13
  import type { LabelImagePromptJSON } from "../../widget-ai-utils/label-image/label-image-ai-utils";
14
- import type { InteractiveMarkerType, PerseusLabelImageWidgetOptions, PerseusLabelImageUserInput } from "@khanacademy/perseus-core";
14
+ import type { InteractiveMarkerType, PerseusLabelImageWidgetOptions, PerseusLabelImageUserInput, ShowSolutions } from "@khanacademy/perseus-core";
15
15
  type PreferredPopoverDirection = "NONE" | "UP" | "DOWN" | "LEFT" | "RIGHT";
16
16
  /**
17
17
  * Represents a direction vector.
@@ -45,6 +45,15 @@ type LabelImageState = {
45
45
  markersInteracted: boolean;
46
46
  hideAnswers: boolean;
47
47
  };
48
+ /**
49
+ * Get marker with the appropriate selection state for current display mode.
50
+ * When showing solutions, it auto-selects correct answers, or clears
51
+ * selections for markers without answers.
52
+ *
53
+ * @param marker - The marker to update.
54
+ * @returns The updated marker state.
55
+ */
56
+ export declare function getUpdatedMarkerState(marker: OptionalAnswersMarkerType, reviewMode: boolean, showSolutions?: ShowSolutions): OptionalAnswersMarkerType;
48
57
  export declare class LabelImage extends React.Component<Props, LabelImageState> implements Widget {
49
58
  static contextType: React.Context<import("../../components/i18n-context").I18nContextType>;
50
59
  context: React.ContextType<typeof PerseusI18nContext>;
@@ -76,7 +85,6 @@ export declare class LabelImage extends React.Component<Props, LabelImageState>
76
85
  componentWillUnmount(): void;
77
86
  getUserInput(): PerseusLabelImageUserInput;
78
87
  getPromptJSON(): LabelImagePromptJSON;
79
- showRationalesForCurrentlySelectedChoices(): void;
80
88
  handleMarkerChange(index: number, marker: Props["markers"][number]): void;
81
89
  activateMarker(index: number, opened: boolean): void;
82
90
  handleMarkerKeyDown(index: number, e: React.KeyboardEvent): void;
@@ -3,7 +3,7 @@ import { PerseusI18nContext } from "../../components/i18n-context";
3
3
  import type { FocusFunction } from "./base-radio";
4
4
  import type { WidgetProps, ChoiceState, Widget } from "../../types";
5
5
  import type { RadioPromptJSON } from "../../widget-ai-utils/radio/radio-ai-utils";
6
- import type { PerseusRadioChoice, PerseusRadioWidgetOptions, ShowSolutions, PerseusRadioRubric, PerseusRadioUserInput } from "@khanacademy/perseus-core";
6
+ import type { PerseusRadioChoice, ShowSolutions, PerseusRadioRubric, PerseusRadioUserInput } from "@khanacademy/perseus-core";
7
7
  export type RenderProps = {
8
8
  numCorrect: number;
9
9
  hasNoneOfTheAbove?: boolean;
@@ -28,7 +28,6 @@ declare class Radio extends React.Component<Props> implements Widget {
28
28
  focusFunction: FocusFunction;
29
29
  static defaultProps: DefaultProps;
30
30
  static getUserInputFromProps(props: Props, unshuffle?: boolean): PerseusRadioUserInput;
31
- componentDidUpdate(prevProps: Props): void;
32
31
  _renderRenderer: (content?: string) => React.ReactElement;
33
32
  focus(choiceIndex?: number | null): boolean;
34
33
  registerFocusFunction(fun: FocusFunction): void;
@@ -37,17 +36,6 @@ declare class Radio extends React.Component<Props> implements Widget {
37
36
  }>) => void;
38
37
  getUserInput(): PerseusRadioUserInput;
39
38
  getPromptJSON(): RadioPromptJSON;
40
- /**
41
- * Turn on rationale display for the currently selected choices. Note that
42
- * this leaves rationales on for choices that are already showing
43
- * rationales.
44
- * @deprecated Internal only. Use `showSolutions` prop instead.
45
- */
46
- showRationalesForCurrentlySelectedChoices: (arg1: PerseusRadioWidgetOptions) => void;
47
- /**
48
- * Deselects any currently-selected choices that are not correct choices.
49
- */
50
- deselectIncorrectSelectedChoices: () => void;
51
39
  render(): React.ReactNode;
52
40
  }
53
41
  export default Radio;
@@ -0,0 +1,22 @@
1
+ import type { PerseusRenderer } from "@khanacademy/perseus-core";
2
+ export declare function radioQuestionBuilder(): RadioQuestionBuilder;
3
+ declare class RadioQuestionBuilder {
4
+ private content;
5
+ private choices;
6
+ private countChoices?;
7
+ private hasNoneOfTheAbove?;
8
+ private multipleSelect?;
9
+ private randomize?;
10
+ build(): PerseusRenderer;
11
+ withContent(content: string): RadioQuestionBuilder;
12
+ withCountChoices(countChoices: boolean): RadioQuestionBuilder;
13
+ withHasNoneOfTheAbove(hasNoneOfTheAbove: boolean): RadioQuestionBuilder;
14
+ withMultipleSelect(multipleSelect: boolean): RadioQuestionBuilder;
15
+ withRandomize(randomize: boolean): RadioQuestionBuilder;
16
+ addChoice(content: string, options?: {
17
+ correct?: boolean;
18
+ rationale?: string;
19
+ isNoneOfTheAbove?: boolean;
20
+ }): RadioQuestionBuilder;
21
+ }
22
+ export {};
@@ -1,7 +1,7 @@
1
1
  import * as React from "react";
2
2
  import type { WidgetProps, ChoiceState, Widget } from "../../types";
3
3
  import type { RadioPromptJSON } from "../../widget-ai-utils/radio/radio-ai-utils";
4
- import type { PerseusRadioChoice, ShowSolutions, PerseusRadioRubric, PerseusRadioUserInput, PerseusRadioWidgetOptions } from "@khanacademy/perseus-core";
4
+ import type { PerseusRadioChoice, PerseusRadioRubric, PerseusRadioUserInput } from "@khanacademy/perseus-core";
5
5
  export type RenderProps = {
6
6
  numCorrect: number;
7
7
  hasNoneOfTheAbove?: boolean;
@@ -10,7 +10,6 @@ export type RenderProps = {
10
10
  deselectEnabled?: boolean;
11
11
  choices: ReadonlyArray<RadioChoiceWithMetadata>;
12
12
  selectedChoices: ReadonlyArray<PerseusRadioChoice["correct"]>;
13
- showSolutions?: ShowSolutions;
14
13
  choiceStates?: ReadonlyArray<ChoiceState>;
15
14
  values?: ReadonlyArray<boolean>;
16
15
  };
@@ -33,18 +32,6 @@ declare class Radio extends React.Component<Props> implements Widget {
33
32
  static getUserInputFromProps(props: Props, unshuffle?: boolean): PerseusRadioUserInput;
34
33
  getUserInput(): PerseusRadioUserInput;
35
34
  getPromptJSON(): RadioPromptJSON;
36
- /**
37
- * Turn on rationale display for the currently selected choices. Note that
38
- * this leaves rationales on for choices that are already showing
39
- * rationales.
40
- * TODO: LEMS-3077 Remove deprecated class function
41
- * @deprecated Internal only. Use `showSolutions` prop instead.
42
- */
43
- showRationalesForCurrentlySelectedChoices: (arg1: PerseusRadioWidgetOptions) => void;
44
- /**
45
- * Deselects any currently-selected choices that are not correct choices.
46
- */
47
- deselectIncorrectSelectedChoices: () => void;
48
35
  render(): React.ReactNode;
49
36
  }
50
37
  export default Radio;
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": "65.1.3",
6
+ "version": "65.3.0",
7
7
  "publishConfig": {
8
8
  "access": "public"
9
9
  },
@@ -42,36 +42,36 @@
42
42
  "tiny-invariant": "1.3.1",
43
43
  "uuid": "^10.0.0",
44
44
  "@khanacademy/kas": "2.0.7",
45
- "@khanacademy/keypad-context": "3.0.16",
46
- "@khanacademy/kmath": "2.0.16",
47
- "@khanacademy/math-input": "26.0.5",
48
- "@khanacademy/perseus-core": "14.0.3",
49
- "@khanacademy/perseus-linter": "4.0.3",
50
- "@khanacademy/perseus-score": "7.1.3",
45
+ "@khanacademy/keypad-context": "3.0.17",
46
+ "@khanacademy/kmath": "2.0.17",
47
+ "@khanacademy/math-input": "26.0.6",
48
+ "@khanacademy/perseus-core": "14.1.0",
49
+ "@khanacademy/perseus-linter": "4.0.4",
50
+ "@khanacademy/perseus-score": "7.1.4",
51
51
  "@khanacademy/perseus-utils": "2.0.4",
52
52
  "@khanacademy/pure-markdown": "2.0.7",
53
53
  "@khanacademy/simple-markdown": "2.0.7"
54
54
  },
55
55
  "devDependencies": {
56
- "@khanacademy/wonder-blocks-banner": "4.1.21",
57
- "@khanacademy/wonder-blocks-button": "10.0.5",
58
- "@khanacademy/wonder-blocks-clickable": "7.1.5",
56
+ "@khanacademy/wonder-blocks-banner": "4.1.24",
57
+ "@khanacademy/wonder-blocks-button": "10.2.1",
58
+ "@khanacademy/wonder-blocks-clickable": "7.1.6",
59
59
  "@khanacademy/wonder-blocks-core": "12.3.0",
60
60
  "@khanacademy/wonder-blocks-data": "14.1.4",
61
- "@khanacademy/wonder-blocks-dropdown": "10.1.5",
62
- "@khanacademy/wonder-blocks-form": "7.1.18",
63
- "@khanacademy/wonder-blocks-icon-button": "10.2.1",
64
- "@khanacademy/wonder-blocks-icon": "5.1.4",
65
- "@khanacademy/wonder-blocks-labeled-field": "3.0.13",
66
- "@khanacademy/wonder-blocks-layout": "3.1.16",
67
- "@khanacademy/wonder-blocks-link": "9.1.5",
68
- "@khanacademy/wonder-blocks-pill": "3.1.18",
69
- "@khanacademy/wonder-blocks-popover": "6.1.6",
70
- "@khanacademy/wonder-blocks-progress-spinner": "3.1.16",
71
- "@khanacademy/wonder-blocks-switch": "3.2.9",
72
- "@khanacademy/wonder-blocks-tokens": "10.4.0",
73
- "@khanacademy/wonder-blocks-tooltip": "4.1.20",
74
- "@khanacademy/wonder-blocks-typography": "4.2.0",
61
+ "@khanacademy/wonder-blocks-dropdown": "10.1.7",
62
+ "@khanacademy/wonder-blocks-form": "7.1.19",
63
+ "@khanacademy/wonder-blocks-icon-button": "10.3.0",
64
+ "@khanacademy/wonder-blocks-icon": "5.2.0",
65
+ "@khanacademy/wonder-blocks-labeled-field": "3.0.14",
66
+ "@khanacademy/wonder-blocks-layout": "3.1.17",
67
+ "@khanacademy/wonder-blocks-link": "9.1.6",
68
+ "@khanacademy/wonder-blocks-pill": "3.1.19",
69
+ "@khanacademy/wonder-blocks-popover": "6.1.8",
70
+ "@khanacademy/wonder-blocks-progress-spinner": "3.1.17",
71
+ "@khanacademy/wonder-blocks-switch": "3.2.10",
72
+ "@khanacademy/wonder-blocks-tokens": "10.5.0",
73
+ "@khanacademy/wonder-blocks-tooltip": "4.1.22",
74
+ "@khanacademy/wonder-blocks-typography": "4.2.1",
75
75
  "@khanacademy/wonder-stuff-core": "1.5.4",
76
76
  "@phosphor-icons/core": "2.0.2",
77
77
  "@popperjs/core": "2.10.2",
@@ -90,25 +90,25 @@
90
90
  "raphael": "1.5.4"
91
91
  },
92
92
  "peerDependencies": {
93
- "@khanacademy/wonder-blocks-banner": "^4.1.21",
94
- "@khanacademy/wonder-blocks-button": "^10.0.5",
95
- "@khanacademy/wonder-blocks-clickable": "^7.1.5",
93
+ "@khanacademy/wonder-blocks-banner": "^4.1.24",
94
+ "@khanacademy/wonder-blocks-button": "^10.2.1",
95
+ "@khanacademy/wonder-blocks-clickable": "^7.1.6",
96
96
  "@khanacademy/wonder-blocks-core": "^12.3.0",
97
97
  "@khanacademy/wonder-blocks-data": "^14.1.4",
98
- "@khanacademy/wonder-blocks-dropdown": "^10.1.5",
99
- "@khanacademy/wonder-blocks-form": "^7.1.18",
100
- "@khanacademy/wonder-blocks-icon": "^5.1.4",
101
- "@khanacademy/wonder-blocks-icon-button": "^10.2.1",
102
- "@khanacademy/wonder-blocks-labeled-field": "^3.0.13",
103
- "@khanacademy/wonder-blocks-layout": "^3.1.16",
104
- "@khanacademy/wonder-blocks-link": "^9.1.5",
105
- "@khanacademy/wonder-blocks-pill": "^3.1.18",
106
- "@khanacademy/wonder-blocks-popover": "^6.1.6",
107
- "@khanacademy/wonder-blocks-progress-spinner": "^3.1.16",
108
- "@khanacademy/wonder-blocks-switch": "^3.2.9",
109
- "@khanacademy/wonder-blocks-tokens": "^10.4.0",
110
- "@khanacademy/wonder-blocks-tooltip": "^4.1.20",
111
- "@khanacademy/wonder-blocks-typography": "^4.2.0",
98
+ "@khanacademy/wonder-blocks-dropdown": "^10.1.7",
99
+ "@khanacademy/wonder-blocks-form": "^7.1.19",
100
+ "@khanacademy/wonder-blocks-icon": "^5.2.0",
101
+ "@khanacademy/wonder-blocks-icon-button": "^10.3.0",
102
+ "@khanacademy/wonder-blocks-labeled-field": "^3.0.14",
103
+ "@khanacademy/wonder-blocks-layout": "^3.1.17",
104
+ "@khanacademy/wonder-blocks-link": "^9.1.6",
105
+ "@khanacademy/wonder-blocks-pill": "^3.1.19",
106
+ "@khanacademy/wonder-blocks-popover": "^6.1.8",
107
+ "@khanacademy/wonder-blocks-progress-spinner": "^3.1.17",
108
+ "@khanacademy/wonder-blocks-switch": "^3.2.10",
109
+ "@khanacademy/wonder-blocks-tokens": "^10.5.0",
110
+ "@khanacademy/wonder-blocks-tooltip": "^4.1.22",
111
+ "@khanacademy/wonder-blocks-typography": "^4.2.1",
112
112
  "@khanacademy/wonder-stuff-core": "^1.5.4",
113
113
  "@phosphor-icons/core": "^2.0.2",
114
114
  "@popperjs/core": "^2.10.2",