@khanacademy/perseus 66.5.0 → 67.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. package/dist/components/scrollable-view.d.ts +12 -3
  2. package/dist/es/index.css +7 -5
  3. package/dist/es/index.css.map +1 -1
  4. package/dist/es/index.js +19 -17
  5. package/dist/es/index.js.map +1 -1
  6. package/dist/index.css +7 -5
  7. package/dist/index.css.map +1 -1
  8. package/dist/index.d.ts +1 -1
  9. package/dist/index.js +19 -16
  10. package/dist/index.js.map +1 -1
  11. package/dist/server-item-renderer.d.ts +0 -1
  12. package/dist/types.d.ts +0 -10
  13. package/dist/user-input-manager.d.ts +1 -1
  14. package/dist/widget-ai-utils/image/image-ai-utils.d.ts +1 -1
  15. package/dist/widget-ai-utils/radio/radio-ai-utils.d.ts +1 -1
  16. package/dist/widgets/expression/expression.d.ts +0 -2
  17. package/dist/widgets/grapher/grapher.d.ts +0 -1
  18. package/dist/widgets/image/image.class.d.ts +43 -0
  19. package/dist/widgets/image/image.d.ts +2 -42
  20. package/dist/widgets/image/index.d.ts +1 -1
  21. package/dist/widgets/interactive-graphs/interactive-graph.d.ts +0 -1
  22. package/dist/widgets/mock-widgets/mock-widget.d.ts +0 -1
  23. package/dist/widgets/number-line/number-line.d.ts +0 -1
  24. package/dist/widgets/numeric-input/numeric-input.class.d.ts +0 -1
  25. package/dist/widgets/numeric-input/numeric-input.d.ts +0 -1
  26. package/dist/widgets/plotter/plotter.d.ts +0 -1
  27. package/dist/widgets/radio/base-radio.d.ts +1 -3
  28. package/dist/widgets/radio/multiple-choice-component.new.d.ts +1 -1
  29. package/dist/widgets/radio/multiple-choice-widget.new.d.ts +2 -79
  30. package/dist/widgets/radio/radio-component.d.ts +1 -3
  31. package/dist/widgets/radio/radio-question-builder.d.ts +4 -0
  32. package/dist/widgets/radio/radio.d.ts +2 -2
  33. package/dist/widgets/radio/radio.ff.d.ts +0 -1
  34. package/dist/widgets/table/table.d.ts +0 -1
  35. package/package.json +45 -45
@@ -159,7 +159,6 @@ declare const _default: React.ForwardRefExoticComponent<Omit<Pick<SharedRenderer
159
159
  canScrollPage?: boolean;
160
160
  editorChangeDelay?: number;
161
161
  flags?: Record<"new-radio-widget", boolean>;
162
- onWidgetStartProps?: (widgets: import("@khanacademy/perseus-core").PerseusWidgetsMap) => void;
163
162
  }> | undefined;
164
163
  linterContext?: PerseusLinter.LinterContextProps | undefined;
165
164
  onRendered?: ((isRendered: boolean) => void) | undefined;
package/dist/types.d.ts CHANGED
@@ -224,16 +224,6 @@ export type APIOptions = Readonly<{
224
224
  * Define the feature flag name in packages/perseus-core/src/feature-flags.ts
225
225
  */
226
226
  flags?: Record<(typeof PerseusFeatureFlags)[number], boolean>;
227
- /**
228
- * This is a callback function that returns all of the Widget props
229
- * after they have been transformed by the widget's transform function.
230
- * This is useful for when we need to know how a widget has shuffled its
231
- * the available choices.
232
- *
233
- * @deprecated [LEMS-3185] this is externalizing an internal implementation
234
- * detail similar to serialized state
235
- */
236
- onWidgetStartProps?: (widgets: PerseusWidgetsMap) => void;
237
227
  }>;
238
228
  type TeXProps = {
239
229
  children: string;
@@ -33,7 +33,7 @@ export declare function sharedInitializeUserInput(widgetOptions: PerseusWidgetsM
33
33
  *
34
34
  * @deprecated - do not use in new code.
35
35
  */
36
- export declare function sharedRestoreUserInputFromSerializedState(serializedState: unknown, widgetsMap: PerseusWidgetsMap): UserInputMap;
36
+ export declare function deriveUserInputFromSerializedState(serializedState: unknown, widgetsMap: PerseusWidgetsMap): UserInputMap;
37
37
  /**
38
38
  * UserInputManager is a stateful wrapper for handling and storing user input.
39
39
  * Ideally we'll get to a place where widgets are functional components
@@ -1,4 +1,4 @@
1
- import type image from "../../widgets/image/image";
1
+ import type image from "../../widgets/image/image.class";
2
2
  import type React from "react";
3
3
  export type ImagePromptJSON = {
4
4
  type: "image";
@@ -10,7 +10,7 @@ export type RadioPromptJSON = {
10
10
  hasNoneOfTheAbove: boolean;
11
11
  options: BasicOption[];
12
12
  userInput: {
13
- selectedOptions: ReadonlyArray<boolean>;
13
+ selectedOptions: ReadonlyArray<string>;
14
14
  };
15
15
  };
16
16
  export declare const getPromptJSON: (renderProps: RecursiveReadonly<React.ComponentProps<typeof radio.widget>>, userInput: RecursiveReadonly<PerseusRadioUserInput>) => RadioPromptJSON;
@@ -101,7 +101,6 @@ export declare class Expression extends React.Component<Props> implements Widget
101
101
  canScrollPage?: boolean;
102
102
  editorChangeDelay?: number;
103
103
  flags?: Record<"new-radio-widget", boolean>;
104
- onWidgetStartProps?: (widgets: import("@khanacademy/perseus-core").PerseusWidgetsMap) => void;
105
104
  }> & {
106
105
  baseElements: NonNullable<import("../..").APIOptions["baseElements"]>;
107
106
  canScrollPage: NonNullable<import("../..").APIOptions["canScrollPage"]>;
@@ -194,7 +193,6 @@ declare const _default: {
194
193
  canScrollPage?: boolean;
195
194
  editorChangeDelay?: number;
196
195
  flags?: Record<"new-radio-widget", boolean>;
197
- onWidgetStartProps?: (widgets: import("@khanacademy/perseus-core").PerseusWidgetsMap) => void;
198
196
  }> & {
199
197
  baseElements: NonNullable<import("../..").APIOptions["baseElements"]>;
200
198
  canScrollPage: NonNullable<import("../..").APIOptions["canScrollPage"]>;
@@ -92,7 +92,6 @@ declare class Grapher extends React.Component<Props> implements Widget {
92
92
  canScrollPage?: boolean;
93
93
  editorChangeDelay?: number;
94
94
  flags?: Record<"new-radio-widget", boolean>;
95
- onWidgetStartProps?: (widgets: import("@khanacademy/perseus-core").PerseusWidgetsMap) => void;
96
95
  }> & {
97
96
  baseElements: NonNullable<import("../..").APIOptions["baseElements"]>;
98
97
  canScrollPage: NonNullable<import("../..").APIOptions["canScrollPage"]>;
@@ -0,0 +1,43 @@
1
+ import * as React from "react";
2
+ import { PerseusI18nContext } from "../../components/i18n-context";
3
+ import type { WidgetProps, Widget } from "../../types";
4
+ import type { ImagePromptJSON } from "../../widget-ai-utils/image/image-ai-utils";
5
+ import type { PerseusImageWidgetOptions } from "@khanacademy/perseus-core";
6
+ type ExternalProps = WidgetProps<PerseusImageWidgetOptions>;
7
+ export interface Props extends ExternalProps {
8
+ alignment: NonNullable<ExternalProps["alignment"]>;
9
+ title: NonNullable<ExternalProps["title"]>;
10
+ range: NonNullable<ExternalProps["range"]>;
11
+ box: NonNullable<ExternalProps["box"]>;
12
+ backgroundImage: NonNullable<ExternalProps["backgroundImage"]>;
13
+ labels: NonNullable<ExternalProps["labels"]>;
14
+ alt: NonNullable<ExternalProps["alt"]>;
15
+ caption: NonNullable<ExternalProps["caption"]>;
16
+ linterContext: NonNullable<ExternalProps["linterContext"]>;
17
+ }
18
+ interface DefaultProps extends Partial<Props> {
19
+ alignment: Props["alignment"];
20
+ title: Props["title"];
21
+ range: Props["range"];
22
+ box: Props["box"];
23
+ backgroundImage: Props["backgroundImage"];
24
+ labels: Props["labels"];
25
+ alt: Props["alt"];
26
+ caption: Props["caption"];
27
+ linterContext: Props["linterContext"];
28
+ }
29
+ declare class ImageWidget extends React.Component<Props> implements Widget {
30
+ static contextType: React.Context<import("../../components/i18n-context").I18nContextType>;
31
+ context: React.ContextType<typeof PerseusI18nContext>;
32
+ static defaultProps: DefaultProps;
33
+ isWidget: true;
34
+ getPromptJSON(): ImagePromptJSON;
35
+ render(): React.ReactNode;
36
+ }
37
+ declare const _default: {
38
+ name: string;
39
+ displayName: string;
40
+ widget: typeof ImageWidget;
41
+ isLintable: true;
42
+ };
43
+ export default _default;
@@ -1,43 +1,3 @@
1
1
  import * as React from "react";
2
- import { PerseusI18nContext } from "../../components/i18n-context";
3
- import type { WidgetProps, Widget } from "../../types";
4
- import type { ImagePromptJSON } from "../../widget-ai-utils/image/image-ai-utils";
5
- import type { PerseusImageWidgetOptions } from "@khanacademy/perseus-core";
6
- type ExternalProps = WidgetProps<PerseusImageWidgetOptions>;
7
- type Props = ExternalProps & {
8
- alignment: NonNullable<ExternalProps["alignment"]>;
9
- title: NonNullable<ExternalProps["title"]>;
10
- range: NonNullable<ExternalProps["range"]>;
11
- box: NonNullable<ExternalProps["box"]>;
12
- backgroundImage: NonNullable<ExternalProps["backgroundImage"]>;
13
- labels: NonNullable<ExternalProps["labels"]>;
14
- alt: NonNullable<ExternalProps["alt"]>;
15
- caption: NonNullable<ExternalProps["caption"]>;
16
- linterContext: NonNullable<ExternalProps["linterContext"]>;
17
- };
18
- type DefaultProps = {
19
- alignment: Props["alignment"];
20
- title: Props["title"];
21
- range: Props["range"];
22
- box: Props["box"];
23
- backgroundImage: Props["backgroundImage"];
24
- labels: Props["labels"];
25
- alt: Props["alt"];
26
- caption: Props["caption"];
27
- linterContext: Props["linterContext"];
28
- };
29
- declare class ImageWidget extends React.Component<Props> implements Widget {
30
- static contextType: React.Context<import("../../components/i18n-context").I18nContextType>;
31
- context: React.ContextType<typeof PerseusI18nContext>;
32
- static defaultProps: DefaultProps;
33
- isWidget: true;
34
- getPromptJSON(): ImagePromptJSON;
35
- render(): React.ReactNode;
36
- }
37
- declare const _default: {
38
- name: string;
39
- displayName: string;
40
- widget: typeof ImageWidget;
41
- isLintable: true;
42
- };
43
- export default _default;
2
+ import type { Props } from "./image.class";
3
+ export declare const ImageComponent: ({ apiOptions, alt, backgroundImage, box, caption, linterContext, labels, range, title, trackInteraction, }: Props) => React.JSX.Element;
@@ -1 +1 @@
1
- export { default } from "./image";
1
+ export { default } from "./image.class";
@@ -193,7 +193,6 @@ declare class InteractiveGraph extends React.Component<Props, State> {
193
193
  canScrollPage?: boolean;
194
194
  editorChangeDelay?: number;
195
195
  flags?: Record<"new-radio-widget", boolean>;
196
- onWidgetStartProps?: (widgets: import("@khanacademy/perseus-core").PerseusWidgetsMap) => void;
197
196
  }> & {
198
197
  baseElements: NonNullable<import("../..").APIOptions["baseElements"]>;
199
198
  canScrollPage: NonNullable<import("../..").APIOptions["canScrollPage"]>;
@@ -76,7 +76,6 @@ declare class MockWidgetComponent extends React.Component<Props> implements Widg
76
76
  canScrollPage?: boolean;
77
77
  editorChangeDelay?: number;
78
78
  flags?: Record<"new-radio-widget", boolean>;
79
- onWidgetStartProps?: (widgets: import("@khanacademy/perseus-core").PerseusWidgetsMap) => void;
80
79
  }> & {
81
80
  baseElements: NonNullable<import("../..").APIOptions["baseElements"]>;
82
81
  canScrollPage: NonNullable<import("../..").APIOptions["canScrollPage"]>;
@@ -121,7 +121,6 @@ declare class NumberLine extends React.Component<Props, State> implements Widget
121
121
  canScrollPage?: boolean;
122
122
  editorChangeDelay?: number;
123
123
  flags?: Record<"new-radio-widget", boolean>;
124
- onWidgetStartProps?: (widgets: import("@khanacademy/perseus-core").PerseusWidgetsMap) => void;
125
124
  }> & {
126
125
  baseElements: NonNullable<import("../..").APIOptions["baseElements"]>;
127
126
  canScrollPage: NonNullable<import("../..").APIOptions["canScrollPage"]>;
@@ -83,7 +83,6 @@ export declare class NumericInput extends React.Component<NumericInputProps> imp
83
83
  canScrollPage?: boolean;
84
84
  editorChangeDelay?: number;
85
85
  flags?: Record<"new-radio-widget", boolean>;
86
- onWidgetStartProps?: (widgets: import("@khanacademy/perseus-core").PerseusWidgetsMap) => void;
87
86
  }> & {
88
87
  baseElements: NonNullable<import("../..").APIOptions["baseElements"]>;
89
88
  canScrollPage: NonNullable<import("../..").APIOptions["canScrollPage"]>;
@@ -42,7 +42,6 @@ export declare const NumericInputComponent: React.ForwardRefExoticComponent<impo
42
42
  canScrollPage?: boolean;
43
43
  editorChangeDelay?: number;
44
44
  flags?: Record<"new-radio-widget", boolean>;
45
- onWidgetStartProps?: (widgets: import("@khanacademy/perseus-core").PerseusWidgetsMap) => void;
46
45
  }> & {
47
46
  baseElements: NonNullable<import("../..").APIOptions["baseElements"]>;
48
47
  canScrollPage: NonNullable<import("../..").APIOptions["canScrollPage"]>;
@@ -130,7 +130,6 @@ export declare class Plotter extends React.Component<Props, State> implements Wi
130
130
  canScrollPage?: boolean;
131
131
  editorChangeDelay?: number;
132
132
  flags?: Record<"new-radio-widget", boolean>;
133
- onWidgetStartProps?: (widgets: import("@khanacademy/perseus-core").PerseusWidgetsMap) => void;
134
133
  }> & {
135
134
  baseElements: NonNullable<import("../..").APIOptions["baseElements"]>;
136
135
  canScrollPage: NonNullable<import("../..").APIOptions["canScrollPage"]>;
@@ -28,9 +28,7 @@ type Props = {
28
28
  multipleSelect?: boolean;
29
29
  reviewModeRubric?: PerseusRadioWidgetOptions | null;
30
30
  reviewMode: boolean;
31
- onChange: (newValues: {
32
- checked: ReadonlyArray<boolean>;
33
- }) => void;
31
+ onChange: (checkedChoiceIds: ReadonlyArray<string>) => void;
34
32
  registerFocusFunction?: (arg1: FocusFunction) => void;
35
33
  isLastUsedWidget?: boolean;
36
34
  };
@@ -8,7 +8,7 @@ export interface MultipleChoiceComponentProps {
8
8
  countChoices: boolean | null | undefined;
9
9
  multipleSelect?: boolean;
10
10
  numCorrect: number;
11
- onChoiceChange: (choiceIndex: number, newCheckedState: boolean) => void;
11
+ onChoiceChange: (choiceId: string, newCheckedState: boolean) => void;
12
12
  reviewMode: boolean;
13
13
  }
14
14
  /**
@@ -1,7 +1,6 @@
1
1
  import * as React from "react";
2
2
  import type { PerseusStrings } from "../../strings";
3
- import type { WidgetProps, ChoiceState, Widget } from "../../types";
4
- import type { RadioPromptJSON } from "../../widget-ai-utils/radio/radio-ai-utils";
3
+ import type { ChoiceState, Widget } from "../../types";
5
4
  import type { PerseusRadioChoice, PerseusRadioRubric, PerseusRadioUserInput } from "@khanacademy/perseus-core";
6
5
  /**
7
6
  * Represents a single choice in the MultipleChoiceComponent
@@ -41,81 +40,5 @@ export interface RadioChoiceWithMetadata extends PerseusRadioChoice {
41
40
  originalIndex: number;
42
41
  correct?: boolean;
43
42
  }
44
- type Props = WidgetProps<RenderProps, PerseusRadioUserInput, PerseusRadioRubric>;
45
- type DefaultProps = Required<Pick<Props, "choices" | "multipleSelect" | "countChoices" | "deselectEnabled" | "linterContext" | "showSolutions">>;
46
- /**
47
- * MultipleChoiceWidget implements the Widget interface for multiple choice questions.
48
- *
49
- * It handles Perseus-specific logic and state management while delegating
50
- * UI rendering to the MultipleChoiceComponent.
51
- *
52
- * This class is exported as "Radio" for backwards compatibility with existing content,
53
- * though it supports both radio-button (single select) and checkbox (multiple select) modes.
54
- * Eventually, when Content Backfills are set up, we will officially rename the Radio Widget to MultipleChoiceWidget.
55
- *
56
- * Created as part of the Radio Revitalization Project (LEMS-2933).
57
- */
58
- declare class MultipleChoiceWidget extends React.Component<Props> implements Widget {
59
- static defaultProps: DefaultProps;
60
- /**
61
- * Gets the JSON representation of the User Input for AI assistance.
62
- *
63
- * This method is used to provide structured data about the widget's state
64
- * to AI systems that can help users with answering questions.
65
- *
66
- * @returns A structured JSON object representing the widget's prompt
67
- */
68
- getPromptJSON(): RadioPromptJSON;
69
- /**
70
- * Renders content that may contain nested widgets (currently only passage-refs).
71
- * Parses the content, extracts any widgets, and returns a Renderer component
72
- * configured with the appropriate context.
73
- *
74
- * @param content - The content to render (defaults to empty string)
75
- * @returns A React element with the rendered content
76
- */
77
- renderContent: (content?: string) => React.ReactNode;
78
- /**
79
- * Handles a user's selection of a choice.
80
- *
81
- * Updates choice states based on the selection, handles single/multiple
82
- * selection logic, and notifies Perseus of the interaction.
83
- *
84
- * @param choiceIndex - The index of the choice that changed
85
- * @param newCheckedState - Whether the choice is now selected
86
- */
87
- handleChoiceChange: (choiceIndex: number, newCheckedState: boolean) => void;
88
- /**
89
- * Transforms choice states into component-ready props for the MultipleChoiceComponent.
90
- *
91
- * This method:
92
- * 1. Processes each choice's content
93
- * 2. Maps state properties (selected, rationaleShown, etc.) to component props
94
- * 3. Renders content and rationales with nested widget support
95
- * 4. Determines correctness display based on choice data or review rubric
96
- *
97
- * @param choiceStates - The current state of each choice
98
- * @returns An array of formatted choice props ready for the MultipleChoiceComponent
99
- */
100
- buildChoiceProps: (choiceStates: ReadonlyArray<ChoiceState>) => ReadonlyArray<ChoiceType>;
101
- /**
102
- * Prepares the choice props for rendering in the MultipleChoiceComponent.
103
- *
104
- * This method:
105
- * 1. Uses getChoiceStates() to determine the appropriate state for each choice
106
- * based on widget mode (review/static) and user selections
107
- * 2. Transforms these states into component props via buildChoiceProps(),
108
- * including rendered content, correctness indicators, and rationales
109
- *
110
- * @returns An array of choice props ready for the component
111
- */
112
- prepareChoicesProps: () => readonly ChoiceType[];
113
- /**
114
- * Renders the MultipleChoiceComponent with the current props.
115
- *
116
- * @returns The rendered React component
117
- */
118
- render(): React.ReactNode;
119
- }
120
- declare const Radio: typeof MultipleChoiceWidget;
43
+ declare const Radio: React.ForwardRefExoticComponent<RenderProps & import("../../types").UniversalWidgetProps<PerseusRadioRubric, PerseusRadioUserInput, Empty> & React.RefAttributes<Widget>>;
121
44
  export default Radio;
@@ -30,9 +30,7 @@ declare class Radio extends React.Component<Props> implements Widget {
30
30
  _renderRenderer: (content?: string) => React.ReactElement;
31
31
  focus(choiceIndex?: number | null): boolean;
32
32
  registerFocusFunction(fun: FocusFunction): void;
33
- updateChoices: (newValueLists: Readonly<{
34
- checked: ReadonlyArray<boolean>;
35
- }>) => void;
33
+ updateChoices: (checkedChoiceIds: ReadonlyArray<string>) => void;
36
34
  getPromptJSON(): RadioPromptJSON;
37
35
  render(): React.ReactNode;
38
36
  }
@@ -7,12 +7,16 @@ declare class RadioQuestionBuilder {
7
7
  private hasNoneOfTheAbove?;
8
8
  private multipleSelect?;
9
9
  private randomize?;
10
+ private static?;
11
+ private numCorrect?;
10
12
  build(): PerseusRenderer;
11
13
  withContent(content: string): RadioQuestionBuilder;
12
14
  withCountChoices(countChoices: boolean): RadioQuestionBuilder;
13
15
  withHasNoneOfTheAbove(hasNoneOfTheAbove: boolean): RadioQuestionBuilder;
14
16
  withMultipleSelect(multipleSelect: boolean): RadioQuestionBuilder;
15
17
  withRandomize(randomize: boolean): RadioQuestionBuilder;
18
+ withStatic(isStatic: boolean): RadioQuestionBuilder;
19
+ withNumCorrect(numCorrect: number): RadioQuestionBuilder;
16
20
  addChoice(content: string, options?: {
17
21
  correct?: boolean;
18
22
  rationale?: string;
@@ -1,8 +1,8 @@
1
1
  import Radio from "./radio.ff";
2
2
  import type { RenderProps } from "./radio-component";
3
3
  import type { PerseusStrings } from "../../strings";
4
- import type { PerseusRadioUserInput, PerseusRadioWidgetOptions, RadioPublicWidgetOptions } from "@khanacademy/perseus-core";
5
- declare function getStartUserInput(options: RadioPublicWidgetOptions): PerseusRadioUserInput;
4
+ import type { PerseusRadioUserInput, PerseusRadioWidgetOptions } from "@khanacademy/perseus-core";
5
+ declare function getStartUserInput(): PerseusRadioUserInput;
6
6
  declare function getCorrectUserInput(options: PerseusRadioWidgetOptions): PerseusRadioUserInput;
7
7
  declare const _default: {
8
8
  name: string;
@@ -78,7 +78,6 @@ declare class Radio extends RadioOld {
78
78
  canScrollPage?: boolean;
79
79
  editorChangeDelay?: number;
80
80
  flags?: Record<"new-radio-widget", boolean>;
81
- onWidgetStartProps?: (widgets: import("@khanacademy/perseus-core").PerseusWidgetsMap) => void;
82
81
  }> & {
83
82
  baseElements: NonNullable<import("../..").APIOptions["baseElements"]>;
84
83
  canScrollPage: NonNullable<import("../..").APIOptions["canScrollPage"]>;
@@ -85,7 +85,6 @@ declare class Table extends React.Component<Props> implements Widget {
85
85
  canScrollPage?: boolean;
86
86
  editorChangeDelay?: number;
87
87
  flags?: Record<"new-radio-widget", boolean>;
88
- onWidgetStartProps?: (widgets: import("@khanacademy/perseus-core").PerseusWidgetsMap) => void;
89
88
  }> & {
90
89
  baseElements: NonNullable<import("../..").APIOptions["baseElements"]>;
91
90
  canScrollPage: NonNullable<import("../..").APIOptions["canScrollPage"]>;
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": "66.5.0",
6
+ "version": "67.1.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.1.0",
45
- "@khanacademy/keypad-context": "3.1.4",
46
- "@khanacademy/kmath": "2.1.4",
47
- "@khanacademy/math-input": "26.1.5",
48
- "@khanacademy/perseus-core": "18.7.0",
49
- "@khanacademy/perseus-linter": "4.2.4",
45
+ "@khanacademy/keypad-context": "3.2.0",
46
+ "@khanacademy/kmath": "2.2.0",
47
+ "@khanacademy/math-input": "26.2.0",
48
+ "@khanacademy/perseus-core": "18.9.0",
49
+ "@khanacademy/perseus-linter": "4.3.0",
50
+ "@khanacademy/perseus-score": "7.7.0",
50
51
  "@khanacademy/perseus-utils": "2.1.0",
51
52
  "@khanacademy/pure-markdown": "2.2.0",
52
- "@khanacademy/perseus-score": "7.6.1",
53
53
  "@khanacademy/simple-markdown": "2.1.0"
54
54
  },
55
55
  "devDependencies": {
56
- "@khanacademy/wonder-blocks-banner": "4.2.14",
57
- "@khanacademy/wonder-blocks-button": "11.0.0",
58
- "@khanacademy/wonder-blocks-clickable": "7.1.20",
59
- "@khanacademy/wonder-blocks-core": "12.3.0",
60
- "@khanacademy/wonder-blocks-data": "14.1.4",
61
- "@khanacademy/wonder-blocks-dropdown": "10.3.2",
62
- "@khanacademy/wonder-blocks-form": "7.3.2",
63
- "@khanacademy/wonder-blocks-icon-button": "10.3.15",
64
- "@khanacademy/wonder-blocks-icon": "5.2.14",
65
- "@khanacademy/wonder-blocks-labeled-field": "4.0.0",
66
- "@khanacademy/wonder-blocks-layout": "3.1.31",
67
- "@khanacademy/wonder-blocks-link": "9.1.20",
68
- "@khanacademy/wonder-blocks-pill": "3.1.35",
69
- "@khanacademy/wonder-blocks-popover": "6.1.24",
70
- "@khanacademy/wonder-blocks-progress-spinner": "3.1.31",
71
- "@khanacademy/wonder-blocks-switch": "3.3.13",
72
- "@khanacademy/wonder-blocks-tokens": "12.0.2",
73
- "@khanacademy/wonder-blocks-tooltip": "4.1.38",
74
- "@khanacademy/wonder-blocks-typography": "4.2.16",
56
+ "@khanacademy/wonder-blocks-banner": "4.3.2",
57
+ "@khanacademy/wonder-blocks-button": "11.0.3",
58
+ "@khanacademy/wonder-blocks-clickable": "7.1.23",
59
+ "@khanacademy/wonder-blocks-core": "12.4.0",
60
+ "@khanacademy/wonder-blocks-data": "14.1.5",
61
+ "@khanacademy/wonder-blocks-dropdown": "10.3.7",
62
+ "@khanacademy/wonder-blocks-form": "7.3.5",
63
+ "@khanacademy/wonder-blocks-icon-button": "10.4.0",
64
+ "@khanacademy/wonder-blocks-icon": "5.2.17",
65
+ "@khanacademy/wonder-blocks-labeled-field": "4.0.3",
66
+ "@khanacademy/wonder-blocks-layout": "3.1.34",
67
+ "@khanacademy/wonder-blocks-link": "9.2.1",
68
+ "@khanacademy/wonder-blocks-pill": "3.1.38",
69
+ "@khanacademy/wonder-blocks-popover": "6.1.28",
70
+ "@khanacademy/wonder-blocks-progress-spinner": "3.1.34",
71
+ "@khanacademy/wonder-blocks-switch": "3.3.16",
72
+ "@khanacademy/wonder-blocks-tokens": "12.2.0",
73
+ "@khanacademy/wonder-blocks-tooltip": "4.1.42",
74
+ "@khanacademy/wonder-blocks-typography": "4.2.19",
75
75
  "@khanacademy/wonder-stuff-core": "1.5.5",
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.2.14",
94
- "@khanacademy/wonder-blocks-button": "^11.0.0",
95
- "@khanacademy/wonder-blocks-clickable": "^7.1.20",
96
- "@khanacademy/wonder-blocks-core": "^12.3.0",
97
- "@khanacademy/wonder-blocks-data": "^14.1.4",
98
- "@khanacademy/wonder-blocks-dropdown": "^10.3.2",
99
- "@khanacademy/wonder-blocks-form": "^7.3.2",
100
- "@khanacademy/wonder-blocks-icon": "^5.2.14",
101
- "@khanacademy/wonder-blocks-icon-button": "^10.3.15",
102
- "@khanacademy/wonder-blocks-labeled-field": "^4.0.0",
103
- "@khanacademy/wonder-blocks-layout": "^3.1.31",
104
- "@khanacademy/wonder-blocks-link": "^9.1.20",
105
- "@khanacademy/wonder-blocks-pill": "^3.1.35",
106
- "@khanacademy/wonder-blocks-popover": "^6.1.24",
107
- "@khanacademy/wonder-blocks-progress-spinner": "^3.1.31",
108
- "@khanacademy/wonder-blocks-switch": "^3.3.13",
109
- "@khanacademy/wonder-blocks-tokens": "^12.0.2",
110
- "@khanacademy/wonder-blocks-tooltip": "^4.1.38",
111
- "@khanacademy/wonder-blocks-typography": "^4.2.16",
93
+ "@khanacademy/wonder-blocks-banner": "^4.3.2",
94
+ "@khanacademy/wonder-blocks-button": "^11.0.3",
95
+ "@khanacademy/wonder-blocks-clickable": "^7.1.23",
96
+ "@khanacademy/wonder-blocks-core": "^12.4.0",
97
+ "@khanacademy/wonder-blocks-data": "^14.1.5",
98
+ "@khanacademy/wonder-blocks-dropdown": "^10.3.7",
99
+ "@khanacademy/wonder-blocks-form": "^7.3.5",
100
+ "@khanacademy/wonder-blocks-icon": "^5.2.17",
101
+ "@khanacademy/wonder-blocks-icon-button": "^10.4.0",
102
+ "@khanacademy/wonder-blocks-labeled-field": "^4.0.3",
103
+ "@khanacademy/wonder-blocks-layout": "^3.1.34",
104
+ "@khanacademy/wonder-blocks-link": "^9.2.1",
105
+ "@khanacademy/wonder-blocks-pill": "^3.1.38",
106
+ "@khanacademy/wonder-blocks-popover": "^6.1.28",
107
+ "@khanacademy/wonder-blocks-progress-spinner": "^3.1.34",
108
+ "@khanacademy/wonder-blocks-switch": "^3.3.16",
109
+ "@khanacademy/wonder-blocks-tokens": "^12.2.0",
110
+ "@khanacademy/wonder-blocks-tooltip": "^4.1.42",
111
+ "@khanacademy/wonder-blocks-typography": "^4.2.19",
112
112
  "@khanacademy/wonder-stuff-core": "^1.5.5",
113
113
  "@phosphor-icons/core": "^2.0.2",
114
114
  "@popperjs/core": "^2.10.2",