@khanacademy/perseus 20.8.1 → 21.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.
@@ -1,4 +1,4 @@
1
- import type { PerseusItem, PerseusRenderer } from "../perseus-types";
1
+ import type { PerseusItem, PerseusRenderer, PerseusWidgetsMap } from "../perseus-types";
2
2
  /**
3
3
  * This function extracts the answers from the widgets.
4
4
  *
@@ -23,11 +23,10 @@ declare function getAnswersFromWidgets(widgets: PerseusRenderer["widgets"]): Rea
23
23
  * @returns
24
24
  */
25
25
  declare function injectWidgets(content: string, widgets: PerseusRenderer["widgets"]): string;
26
- export declare const getWidgetTypeFromWidgetKey: (widgetKey: string) => string;
27
- export declare const isWrongAnswerSupported: (widgetKeys: Array<string>) => boolean;
28
- export declare const shouldHaveIndividualAnswer: (widgetKey: string) => boolean;
26
+ export declare const isWrongAnswerSupported: (widgetIds: Array<string>, widgetMap: PerseusWidgetsMap) => boolean;
27
+ export declare const shouldHaveIndividualAnswer: (widgetId: string, widgetMap: PerseusWidgetsMap) => boolean;
29
28
  export declare const getAnswerFromUserInput: (widgetType: string, userInput: any) => any;
30
- export declare const getCorrectAnswerForWidgetKey: (widgetKey: string, itemData: PerseusItem) => string | undefined;
31
- export declare const isWidgetKeyInContent: (perseusItem: PerseusItem, widgetKey: string) => boolean;
32
- export declare const getValidWidgetKeys: (perseusItem: PerseusItem) => Array<string>;
29
+ export declare const getCorrectAnswerForWidgetId: (widgetId: string, itemData: PerseusItem) => string | undefined;
30
+ export declare const isWidgetIdInContent: (perseusItem: PerseusItem, widgetId: string) => boolean;
31
+ export declare const getValidWidgetIds: (perseusItem: PerseusItem) => Array<string>;
33
32
  export { getAnswersFromWidgets, injectWidgets };
@@ -1,43 +1,3 @@
1
- export declare enum WidgetType {
2
- Categorizer = "categorizer",
3
- CSProgram = "cs-program",
4
- Definition = "definition",
5
- Dropdown = "dropdown",
6
- Explanation = "explanation",
7
- Expression = "expression",
8
- GradedGroup = "graded-group",
9
- GradedGroupAnswerBar = "graded-group-answer-bar",
10
- GradedGroupSet = "graded-group-set",
11
- Grapher = "grapher",
12
- Group = "group",
13
- Iframe = "iframe",
14
- Image = "image",
15
- InputNumber = "input-number",
16
- Interaction = "interaction",
17
- InteractiveGraph = "interactive-graph",
18
- InteractiveNumberLine = "interactive-number-line",
19
- LabelImage = "label-image",
20
- Matcher = "matcher",
21
- Matrix = "matrix",
22
- Measurer = "measurer",
23
- Molecule = "molecule",
24
- NumberLine = "number-line",
25
- NumericInput = "numeric-input",
26
- Orderer = "orderer",
27
- Passage = "passage",
28
- PassageRef = "passage-ref",
29
- PassageRefTarget = "passage-ref-target",
30
- Plotter = "plotter",
31
- Protractor = "protractor",
32
- PythonProgram = "python-program",
33
- Radio = "radio",
34
- Sorter = "sorter",
35
- Table = "table",
36
- Unit = "unit",
37
- Video = "video",
38
- VideoTranscriptLink = "video-transcript-link"
39
- }
40
- export type WidgetId = `${WidgetType} ${number}`;
41
1
  export declare const QUESTION_WIDGETS: ReadonlyArray<string>;
42
2
  /**
43
3
  * Regex for widget placeholders in a string.
@@ -55,35 +15,3 @@ export declare function getWidgetRegex(): RegExp;
55
15
  * @returns {string}
56
16
  */
57
17
  export declare function addWidget(id: string): string;
58
- /**
59
- * Extract all widget IDs, which includes the widget type and instance number.
60
- * example output: ['radio 1', 'categorizer 1', 'categorizor 2']
61
- *
62
- * Content should contain Perseus widget placeholders,
63
- * which look like: '[[☃ radio 1]]'.
64
- *
65
- * @param {string} content
66
- * @returns {Array<WidgetId>} widgets
67
- */
68
- export declare function getAllWidgetIds(content: string): Array<WidgetId>;
69
- /**
70
- * Extract all widget types from a Perseus JSON content string.
71
- * This does not include the instance number and prevents duplicates.
72
- * example output: ['radio', 'categorizer']
73
- *
74
- * @param {string} content
75
- * @returns {Array<WidgetId>}
76
- */
77
- export declare function getAllWidgetTypes(content: string): Array<WidgetId>;
78
- /**
79
- * Extract the widget IDs of all widgets considered question widgets. Widget IDs
80
- * include widget type and instance number.
81
- * example output: ['radio 1', 'categorizer 1']
82
- *
83
- * Content should contain Perseus widget placeholders,
84
- * which look like: '[[☃ radio 1]]'.
85
- *
86
- * @param {string} content
87
- * @returns Array<WidgetId>
88
- */
89
- export declare function getQuestionWidgetIds(content: string): Array<WidgetId>;
@@ -1,4 +1,4 @@
1
- import type { PerseusItem } from "../perseus-types";
1
+ import type { CategorizerWidget, ExpressionWidget, InteractiveGraphWidget, NumericInputWidget, PerseusItem, RadioWidget } from "../perseus-types";
2
2
  export declare const genericPerseusItemData: PerseusItem;
3
3
  /**
4
4
  * Generate a Perseus item object for testing purposes.
@@ -7,6 +7,41 @@ export declare const genericPerseusItemData: PerseusItem;
7
7
  * uses a basic Perseus object and updates it with custom values as needed.
8
8
  *
9
9
  * @param {Partial<PerseusItem>} customFields
10
- * @returns PerseusItem
10
+ * @returns {PerseusItem}
11
11
  */
12
12
  export declare function generateTestPerseusItem(customFields?: Partial<PerseusItem>): PerseusItem;
13
+ /**
14
+ * Creates an object with the bare amount
15
+ * of data to be a properly typed RadioWidget
16
+ *
17
+ * @returns {RadioWidget} skeleton RadioWidget for testing
18
+ */
19
+ export declare function generateTestRadioWidget(): RadioWidget;
20
+ /**
21
+ * Creates an object with the bare amount
22
+ * of data to be a properly typed InteractiveGraphWidget
23
+ *
24
+ * @returns {InteractiveGraphWidget} skeleton InteractiveGraphWidget for testing
25
+ */
26
+ export declare function generateTestInteractiveGraphWidget(): InteractiveGraphWidget;
27
+ /**
28
+ * Creates an object with the bare amount
29
+ * of data to be a properly typed InteractiveGraphWidget
30
+ *
31
+ * @returns {InteractiveGraphWidget} skeleton InteractiveGraphWidget for testing
32
+ */
33
+ export declare function generateTestCategorizerWidget(): CategorizerWidget;
34
+ /**
35
+ * Creates an object with the bare amount
36
+ * of data to be a properly typed ExpressionWidget
37
+ *
38
+ * @returns {ExpressionWidget} skeleton ExpressionWidget for testing
39
+ */
40
+ export declare function generateTestExpressionWidget(): ExpressionWidget;
41
+ /**
42
+ * Creates an object with the bare amount
43
+ * of data to be a properly typed NumericInputWidget
44
+ *
45
+ * @returns {NumericInputWidget} skeleton NumericInputWidget for testing
46
+ */
47
+ export declare function generateTestNumericInputWidget(): NumericInputWidget;
@@ -4,8 +4,6 @@
4
4
  * PerseusWidgetUsedInProblemAttempt CEDAR event, we needed
5
5
  * to: get the type and convert that to an enum value.
6
6
  */
7
- type WidgetName = "categorizer" | "cs-program" | "definition" | "deprecated-standin" | "dropdown" | "explanation" | "expression" | "graded-group-set" | "graded-group" | "grapher" | "group" | "iframe" | "image" | "input-number" | "interaction" | "interactive-graph" | "label-image" | "lights-puzzle" | "matcher" | "matrix" | "measurer" | "molecule-renderer" | "number-line" | "numeric-input" | "orderer" | "passage" | "passage-ref" | "passage-ref-target" | "plotter" | "python-program" | "reaction-diagram" | "radio" | "sequence" | "simulator" | "sorter" | "table" | "unit-input" | "video";
8
7
  type WidgetEnum = "CATEGORIZER" | "CS_PROGRAM" | "DEFINITION" | "DEPRECATED_STANDIN" | "DROPDOWN" | "EXPLANATION" | "EXPRESSION" | "GRADED_GROUP" | "GRADED_GROUP_SET" | "GRAPHER" | "GROUP" | "IFRAME" | "IMAGE" | "INPUT_NUMBER" | "INTERACTIVE" | "INTERACTIVE_GRAPH" | "LABEL_IMAGE" | "LIGHTS_PUZZLE" | "MATCHER" | "MATRIX" | "MEASURER" | "MOLECULE" | "NUMBER_LINE" | "NUMERIC_INPUT" | "ORDERER" | "PASSAGE" | "PASSAGE_REF" | "PASSAGE_REF_TARGET" | "PLOTTER" | "PYTHON_PROGRAM" | "REACTION_DIAGRAM" | "RADIO" | "SEQUENCE" | "SIMULATOR" | "SORTER" | "TABLE" | "UNIT" | "VIDEO";
9
- export declare function convertWidgetNameToEnum(name: WidgetName): WidgetEnum;
10
- export declare function getWidgetTypeFromWidgetId(widgetId: string): WidgetName;
8
+ export declare function convertWidgetNameToEnum(name: string): WidgetEnum;
11
9
  export {};
@@ -0,0 +1,64 @@
1
+ import type { PerseusItem, PerseusWidget, PerseusWidgetsMap } from "./perseus-types";
2
+ /**
3
+ * Get a widget type by a widget's ID
4
+ * (please don't derive type from ID)
5
+ *
6
+ * @param {string} widgetId the ID of the widget
7
+ * @param {PerseusWidgetsMap} widgetMap widget ID to widget map
8
+ * @returns {string} the widget type (ie "radio")
9
+ */
10
+ export declare function getWidgetTypeByWidgetId(WidgetId: string, widgetMap: PerseusWidgetsMap): string | null;
11
+ /**
12
+ * Does the content have a specific type of widget?
13
+ *
14
+ * @param {string} type the type of the widget in question (ie "radio")
15
+ * @param {string} content the string to search through
16
+ * @param {PerseusWidgetsMap} widgetMap widget ID to widget map
17
+ * @returns {boolean} if the content includes the widget type
18
+ */
19
+ export declare function contentHasWidgetType(type: string, content: string, widgetMap: PerseusWidgetsMap): boolean;
20
+ /**
21
+ * Extract all widget IDs, which includes the widget type and instance number.
22
+ * example output: ['radio 1', 'categorizer 1', 'categorizor 2']
23
+ *
24
+ * Content should contain Perseus widget placeholders,
25
+ * which look like: '[[☃ radio 1]]'.
26
+ *
27
+ * @param {string} content
28
+ * @returns {ReadonlyArray<string>} widgetIds
29
+ */
30
+ export declare function getWidgetIdsFromContent(content: string): ReadonlyArray<string>;
31
+ /**
32
+ * Get a list of widget IDs from content,
33
+ * but only for specific widget types
34
+ *
35
+ * @param {string} type the type of widget (ie "radio")
36
+ * @param {string} content the string to parse
37
+ * @param {PerseusWidgetsMap} widgetMap widget ID to widget map
38
+ * @returns {ReadonlyArray<string>} the widget type (ie "radio")
39
+ */
40
+ export declare function getWidgetIdsFromContentByType(type: string, content: string, widgetMap: PerseusWidgetsMap): ReadonlyArray<string>;
41
+ /**
42
+ * Pull the widget map out of ItemData
43
+ *
44
+ * @param {PerseusItem} PerseusItem containing a widgetMap
45
+ * @returns {WidgetMap} the widget map in the PerseusItem
46
+ */
47
+ export declare function getWidgetsMapFromItemData(itemData: PerseusItem): PerseusWidgetsMap;
48
+ /**
49
+ * Get the widget information from a WidgetMap
50
+ *
51
+ * @param {string} widgetId the ID of the widget
52
+ * @returns {PerseusWidget | null} the widget data if it exists, otherwise null
53
+ */
54
+ export declare function getWidgetFromWidgetMap(widgetId: string, widgetMap: PerseusWidgetsMap): PerseusWidget | null;
55
+ /**
56
+ * Get select widgets from a widget map.
57
+ * Useful for multi-items that needs to split
58
+ * one PerseusItem into several
59
+ *
60
+ * @param {ReadonlyArray<string>} widgetIds to extract
61
+ * @param {PerseusWidgetsMap} widgetMap to extract from
62
+ * @return {PerseusWidgetsMap} a new widget map with requested widgets
63
+ */
64
+ export declare function getWidgetsFromWidgetMap(widgetIds: ReadonlyArray<string>, widgetMap: PerseusWidgetsMap): PerseusWidgetsMap;
@@ -155,7 +155,7 @@ declare class InteractiveGraph extends React.Component<Props, State> {
155
155
  static getRayEquationString(props: Props): string;
156
156
  static getPolygonEquationString(props: Props): string;
157
157
  static getAngleEquationString(props: Props): string;
158
- static validate(state: PerseusGraphType, rubric: Rubric, component: any): PerseusScore;
158
+ static validate(userInput: PerseusGraphType, rubric: Rubric, component: any): PerseusScore;
159
159
  static getUserInputFromProps(props: Props): PerseusGraphType;
160
160
  }
161
161
  declare const _default: Readonly<{
@@ -1,13 +1,23 @@
1
1
  /// <reference types="react" />
2
2
  import { vec } from "mafs";
3
+ import type { CollinearTuple } from "../../../../perseus-types";
3
4
  import type { Interval } from "mafs";
4
5
  interface Props {
5
6
  centerPoint: vec.Vector2;
6
7
  endPoints: [vec.Vector2, vec.Vector2];
7
- polygonPoints: readonly vec.Vector2[];
8
+ polygonLines: readonly CollinearTuple[];
8
9
  active: boolean;
9
10
  range: [Interval, Interval];
10
11
  showAngles: boolean;
11
12
  }
12
- export declare const Angle: ({ centerPoint, endPoints, range, polygonPoints, showAngles, }: Props) => JSX.Element | null;
13
+ export declare const Angle: ({ centerPoint, endPoints, range, polygonLines, showAngles, }: Props) => JSX.Element | null;
14
+ /**
15
+ * Determines if an angle is an inside (false) or outside (true) angle.
16
+ * They way, we know to flip the `largeArc` and `sweepArc` flags.
17
+ * Uses the priciple that a ray from a point inside a polygon will intersect
18
+ * with an odd number of lines, while a ray from a point outside the polygon
19
+ * will intersect with an even number of lines.
20
+ * https://stackoverflow.com/questions/217578/how-can-i-determine-whether-a-2d-point-is-within-a-polygon
21
+ */
22
+ export declare const shouldDrawArcOutside: (midpoint: vec.Vector2, vertex: vec.Vector2, range: [Interval, Interval], polygonLines: readonly CollinearTuple[]) => boolean;
13
23
  export {};
@@ -0,0 +1,7 @@
1
+ import * as React from "react";
2
+ /**
3
+ * Wrapper with Mafs transform styles for SVG elements.
4
+ * Scales and translates the SVG element to match the Mafs view.
5
+ * Use if you do not need/want to use the hook in `use-transform.ts`.
6
+ */
7
+ export declare const MafsCssTransformWrapper: ({ children, }: React.PropsWithChildren<unknown>) => JSX.Element;
@@ -0,0 +1,6 @@
1
+ import type { TextProps } from "mafs";
2
+ import type { PropsWithChildren } from "react";
3
+ type Props = PropsWithChildren<Pick<TextProps, "x" | "y" | "attach" | "attachDistance">>;
4
+ export declare const TextLabel: ({ children, ...rest }: Props) => JSX.Element;
5
+ export declare const SvgDefs: () => JSX.Element;
6
+ export {};
@@ -1,3 +1,4 @@
1
+ import type { CollinearTuple } from "../../../perseus-types";
1
2
  import type { Interval, vec } from "mafs";
2
3
  /**
3
4
  * Given two points, find the tips that extends through the points to the edge of the range.
@@ -5,3 +6,4 @@ import type { Interval, vec } from "mafs";
5
6
  * @param extendFrom - The point that the line extends from to the edge of the graph.
6
7
  */
7
8
  export declare const getRayIntersectionCoords: (collinearPoint: vec.Vector2, extendFrom: vec.Vector2, range: [Interval, Interval]) => [number, number];
9
+ export declare const getLines: (points: readonly vec.Vector2[]) => CollinearTuple[];
@@ -7,4 +7,4 @@ export declare function initializeGraphState(params: {
7
7
  snapStep: vec.Vector2;
8
8
  graph: PerseusGraphType;
9
9
  }): InteractiveGraphState;
10
- export declare function getGradableGraph<GraphType extends PerseusGraphType>(state: InteractiveGraphState, initialGraph: GraphType): GraphType;
10
+ export declare function getGradableGraph(state: InteractiveGraphState, initialGraph: PerseusGraphType): PerseusGraphType;
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": "20.8.1",
6
+ "version": "21.0.0",
7
7
  "publishConfig": {
8
8
  "access": "public"
9
9
  },