@khanacademy/perseus 20.8.1 → 21.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.
- package/dist/es/index.js +716 -359
- package/dist/es/index.js.map +1 -1
- package/dist/index.d.ts +5 -4
- package/dist/index.js +739 -366
- package/dist/index.js.map +1 -1
- package/dist/types.d.ts +2 -0
- package/dist/util/extract-perseus-data.d.ts +7 -8
- package/dist/util/snowman-utils.d.ts +0 -72
- package/dist/util/test-utils.d.ts +37 -2
- package/dist/util/widget-enum-utils.d.ts +1 -3
- package/dist/widget-type-utils.d.ts +64 -0
- package/dist/widgets/interactive-graph.d.ts +3 -3
- package/dist/widgets/interactive-graphs/axis-arrows.d.ts +2 -0
- package/dist/widgets/interactive-graphs/graphs/components/angle.d.ts +12 -2
- package/dist/widgets/interactive-graphs/graphs/components/css-transform-wrapper.d.ts +7 -0
- package/dist/widgets/interactive-graphs/graphs/components/text-label.d.ts +6 -0
- package/dist/widgets/interactive-graphs/graphs/point.d.ts +5 -0
- package/dist/widgets/interactive-graphs/graphs/utils.d.ts +2 -0
- package/dist/widgets/interactive-graphs/mafs-graph.d.ts +15 -74
- package/dist/widgets/interactive-graphs/mafs-supported-graph-types.d.ts +1 -1
- package/dist/widgets/interactive-graphs/reducer/interactive-graph-action.d.ts +10 -3
- package/dist/widgets/interactive-graphs/reducer/interactive-graph-reducer.d.ts +1 -1
- package/dist/widgets/interactive-graphs/reducer/interactive-graph-state.d.ts +1 -1
- package/dist/widgets/interactive-graphs/reducer/use-graph-state.d.ts +11 -0
- package/dist/widgets/interactive-graphs/types.d.ts +30 -9
- package/dist/widgets/interactive-graphs/utils.d.ts +2 -2
- package/package.json +1 -1
package/dist/types.d.ts
CHANGED
|
@@ -2,6 +2,7 @@ import type { ILogger } from "./logging/log";
|
|
|
2
2
|
import type { Item } from "./multi-items/item-types";
|
|
3
3
|
import type { PerseusAnswerArea, PerseusRenderer, PerseusWidget, PerseusWidgetsMap } from "./perseus-types";
|
|
4
4
|
import type { SizeClass } from "./util/sizing-utils";
|
|
5
|
+
import type { InteractiveGraphState } from "./widgets/interactive-graphs/types";
|
|
5
6
|
import type { KeypadAPI } from "@khanacademy/math-input";
|
|
6
7
|
import type { AnalyticsEventHandlerFn } from "@khanacademy/perseus-core";
|
|
7
8
|
import type { LinterContextProps } from "@khanacademy/perseus-linter";
|
|
@@ -65,6 +66,7 @@ export type ChangeHandler = (arg1: {
|
|
|
65
66
|
currentValue?: string;
|
|
66
67
|
selected?: number;
|
|
67
68
|
plot?: any;
|
|
69
|
+
graph?: InteractiveGraphState;
|
|
68
70
|
}, callback?: () => unknown | null | undefined, silent?: boolean) => unknown;
|
|
69
71
|
export type ImageUploader = (file: string, callback: (url: string) => unknown) => unknown;
|
|
70
72
|
export type WidgetSize = "normal" | "small" | "mini";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { PerseusItem, PerseusRenderer } from "../perseus-types";
|
|
1
|
+
import type { PerseusItem, PerseusWidgetsMap, PerseusRenderer } from "../perseus-types";
|
|
2
2
|
/**
|
|
3
3
|
* This function extracts the answers from the widgets.
|
|
4
4
|
*
|
|
@@ -22,12 +22,11 @@ declare function getAnswersFromWidgets(widgets: PerseusRenderer["widgets"]): Rea
|
|
|
22
22
|
* @param {PerseusRenderer["widgets"]} widgets
|
|
23
23
|
* @returns
|
|
24
24
|
*/
|
|
25
|
-
declare function injectWidgets(content: string, widgets: PerseusRenderer["widgets"]): string;
|
|
26
|
-
export declare const
|
|
27
|
-
export declare const
|
|
28
|
-
export declare const shouldHaveIndividualAnswer: (widgetKey: string) => boolean;
|
|
25
|
+
declare function injectWidgets(content: string, widgets: PerseusRenderer["widgets"], widgetProps?: PerseusWidgetsMap): string;
|
|
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
|
|
31
|
-
export declare const
|
|
32
|
-
export declare const
|
|
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:
|
|
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;
|
|
@@ -2,7 +2,7 @@ import * as React from "react";
|
|
|
2
2
|
import type { Coord } from "../interactive2/types";
|
|
3
3
|
import type { PerseusGraphType, PerseusGraphTypeAngle, PerseusGraphTypePoint, PerseusGraphTypePolygon, PerseusGraphTypeSegment, PerseusInteractiveGraphWidgetOptions } from "../perseus-types";
|
|
4
4
|
import type { Widget } from "../renderer";
|
|
5
|
-
import type { PerseusScore, WidgetProps } from "../types";
|
|
5
|
+
import type { ChangeHandler, PerseusScore, WidgetProps } from "../types";
|
|
6
6
|
import type { QuadraticCoefficient, SineCoefficient, Range } from "../util/geometry";
|
|
7
7
|
type RenderProps = PerseusInteractiveGraphWidgetOptions;
|
|
8
8
|
type Rubric = PerseusInteractiveGraphWidgetOptions;
|
|
@@ -81,7 +81,7 @@ declare class LegacyInteractiveGraph extends React.Component<Props, State> {
|
|
|
81
81
|
createPointForPolygonType: (arg1: Coord, arg2: number) => any;
|
|
82
82
|
updateCoordsFromPoints: () => void;
|
|
83
83
|
clearCoords: () => void;
|
|
84
|
-
onChange:
|
|
84
|
+
onChange: ChangeHandler;
|
|
85
85
|
addPointControls: () => void;
|
|
86
86
|
removePointControls: () => void;
|
|
87
87
|
addSegmentControls: () => void;
|
|
@@ -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(
|
|
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
|
-
|
|
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,
|
|
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[];
|
|
@@ -1,80 +1,21 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
|
+
import type { InteractiveGraphProps } from "./types";
|
|
2
3
|
import type { Widget } from "../../renderer";
|
|
3
4
|
import "mafs/core.css";
|
|
4
5
|
import "./mafs-styles.css";
|
|
5
|
-
export
|
|
6
|
-
widgetId: string;
|
|
7
|
-
alignment: string | null | undefined;
|
|
8
|
-
static: boolean | null | undefined;
|
|
9
|
-
problemNum: number | null | undefined;
|
|
10
|
-
apiOptions: Readonly<Readonly<{
|
|
11
|
-
isArticle?: boolean | undefined;
|
|
12
|
-
onInputError?: ((widgetId: any, value: string, message?: string | null | undefined) => unknown) | undefined;
|
|
13
|
-
onFocusChange?: ((newFocusPath: import("../..").FocusPath, oldFocusPath: import("../..").FocusPath, keypadHeight?: number | undefined, focusedElement?: HTMLElement | undefined) => unknown) | undefined;
|
|
14
|
-
GroupMetadataEditor?: React.ComponentType<any> | undefined;
|
|
15
|
-
showAlignmentOptions?: boolean | undefined;
|
|
16
|
-
readOnly?: boolean | undefined;
|
|
17
|
-
answerableCallback?: ((arg1: boolean) => unknown) | undefined;
|
|
18
|
-
getAnotherHint?: (() => unknown) | undefined;
|
|
19
|
-
interactionCallback?: ((widgetData: {
|
|
20
|
-
[widgetId: string]: any;
|
|
21
|
-
}) => void) | undefined;
|
|
22
|
-
groupAnnotator?: ((groupNumber: number, widgetId: string) => React.ReactNode) | undefined;
|
|
23
|
-
imagePlaceholder?: React.ReactNode;
|
|
24
|
-
widgetPlaceholder?: React.ReactNode;
|
|
25
|
-
baseElements?: {
|
|
26
|
-
Link: React.ComponentType<any>;
|
|
27
|
-
} | undefined;
|
|
28
|
-
imagePreloader?: ((dimensions: import("../../types").Dimensions) => React.ReactNode) | undefined;
|
|
29
|
-
trackInteraction?: ((args: {
|
|
30
|
-
type: string;
|
|
31
|
-
id: string;
|
|
32
|
-
correct?: boolean | undefined;
|
|
33
|
-
} & Partial<import("../../types").TrackingGradedGroupExtraArguments> & Partial<import("../../types").TrackingSequenceExtraArguments>) => void) | undefined;
|
|
34
|
-
customKeypad?: boolean | undefined;
|
|
35
|
-
nativeKeypadProxy?: ((blur: () => void) => import("@khanacademy/math-input").KeypadAPI) | undefined;
|
|
36
|
-
isMobile?: boolean | undefined;
|
|
37
|
-
setDrawingAreaAvailable?: ((arg1: boolean) => unknown) | undefined;
|
|
38
|
-
useDraftEditor?: boolean | undefined;
|
|
39
|
-
hintProgressColor?: string | undefined;
|
|
40
|
-
canScrollPage?: boolean | undefined;
|
|
41
|
-
inModal?: boolean | undefined;
|
|
42
|
-
crossOutEnabled?: boolean | undefined;
|
|
43
|
-
editorChangeDelay?: number | undefined;
|
|
44
|
-
flags?: Record<string, boolean | Record<string, boolean>> | undefined;
|
|
45
|
-
onWidgetStartProps?: ((widgets: import("../..").PerseusWidgetsMap) => import("../..").PerseusWidgetsMap) | undefined;
|
|
46
|
-
}> & {
|
|
47
|
-
GroupMetadataEditor: NonNullable<React.ComponentType<any> | undefined>;
|
|
48
|
-
baseElements: {
|
|
49
|
-
Link: React.ComponentType<any>;
|
|
50
|
-
};
|
|
51
|
-
canScrollPage: NonNullable<boolean | undefined>;
|
|
52
|
-
crossOutEnabled: NonNullable<boolean | undefined>;
|
|
53
|
-
editorChangeDelay: number;
|
|
54
|
-
groupAnnotator: (groupNumber: number, widgetId: string) => React.ReactNode;
|
|
55
|
-
inModal: NonNullable<boolean | undefined>;
|
|
56
|
-
isArticle: NonNullable<boolean | undefined>;
|
|
57
|
-
isMobile: NonNullable<boolean | undefined>;
|
|
58
|
-
onFocusChange: (newFocusPath: import("../..").FocusPath, oldFocusPath: import("../..").FocusPath, keypadHeight?: number | undefined, focusedElement?: HTMLElement | undefined) => unknown;
|
|
59
|
-
onInputError: (widgetId: any, value: string, message?: string | null | undefined) => unknown;
|
|
60
|
-
readOnly: NonNullable<boolean | undefined>;
|
|
61
|
-
setDrawingAreaAvailable: (arg1: boolean) => unknown;
|
|
62
|
-
showAlignmentOptions: NonNullable<boolean | undefined>;
|
|
63
|
-
useDraftEditor: NonNullable<boolean | undefined>;
|
|
64
|
-
}>;
|
|
65
|
-
keypadElement?: any;
|
|
66
|
-
questionCompleted?: boolean | undefined;
|
|
67
|
-
onFocus: (blurPath: import("../..").FocusPath) => void;
|
|
68
|
-
onBlur: (blurPath: import("../..").FocusPath) => void;
|
|
69
|
-
findWidgets: (arg1: import("../../types").FilterCriterion) => readonly any[];
|
|
70
|
-
reviewModeRubric: import("../..").PerseusInteractiveGraphWidgetOptions;
|
|
71
|
-
onChange: import("../..").ChangeHandler;
|
|
72
|
-
trackInteraction: (extraData?: {} | undefined) => void;
|
|
73
|
-
isLastUsedWidget: boolean;
|
|
74
|
-
linterContext: import("@khanacademy/perseus-linter").LinterContextProps;
|
|
75
|
-
containerSizeClass: import("../../util/sizing-utils").SizeClass;
|
|
76
|
-
} & {
|
|
77
|
-
children?: React.ReactNode;
|
|
78
|
-
} & {
|
|
6
|
+
export type MafsWrapperProps = {
|
|
79
7
|
box: [number, number];
|
|
8
|
+
backgroundImage?: InteractiveGraphProps["backgroundImage"];
|
|
9
|
+
graph: InteractiveGraphProps["graph"];
|
|
10
|
+
lockedFigures?: InteractiveGraphProps["lockedFigures"];
|
|
11
|
+
range: InteractiveGraphProps["range"];
|
|
12
|
+
snapStep: InteractiveGraphProps["snapStep"];
|
|
13
|
+
step: InteractiveGraphProps["step"];
|
|
14
|
+
gridStep: InteractiveGraphProps["gridStep"];
|
|
15
|
+
containerSizeClass: InteractiveGraphProps["containerSizeClass"];
|
|
16
|
+
markings: InteractiveGraphProps["markings"];
|
|
17
|
+
onChange: InteractiveGraphProps["onChange"];
|
|
18
|
+
};
|
|
19
|
+
export declare const MafsGraph: React.ForwardRefExoticComponent<MafsWrapperProps & {
|
|
20
|
+
children?: React.ReactNode;
|
|
80
21
|
} & React.RefAttributes<Partial<Widget>>>;
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export declare const mafsSupportedGraphTypes: readonly ["segment", "linear", "linear-system", "ray", "polygon"];
|
|
1
|
+
export declare const mafsSupportedGraphTypes: readonly ["segment", "linear", "linear-system", "ray", "polygon", "point"];
|
|
2
2
|
export type MafsSupportedGraphType = (typeof mafsSupportedGraphTypes)[number];
|
|
3
3
|
export declare const trueForAllMafsSupportedGraphTypes: Record<MafsSupportedGraphType, true>;
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import type { vec } from "mafs";
|
|
2
|
-
export type InteractiveGraphAction = MoveControlPoint | MoveLine | MoveAll;
|
|
2
|
+
export type InteractiveGraphAction = MoveControlPoint | MoveLine | MoveAll | MovePoint;
|
|
3
3
|
export declare const MOVE_CONTROL_POINT = "move-control-point";
|
|
4
4
|
export interface MoveControlPoint {
|
|
5
5
|
type: typeof MOVE_CONTROL_POINT;
|
|
6
|
-
itemIndex
|
|
6
|
+
itemIndex: number;
|
|
7
7
|
pointIndex: number;
|
|
8
8
|
destination: vec.Vector2;
|
|
9
9
|
}
|
|
10
|
-
export declare function moveControlPoint(pointIndex: number, destination: vec.Vector2, itemIndex
|
|
10
|
+
export declare function moveControlPoint(pointIndex: number, destination: vec.Vector2, itemIndex: number): MoveControlPoint;
|
|
11
11
|
export declare const MOVE_ALL = "move-all";
|
|
12
12
|
export declare const MOVE_LINE = "move-line";
|
|
13
13
|
interface MoveItem {
|
|
@@ -24,4 +24,11 @@ export interface MoveAll extends MoveItem {
|
|
|
24
24
|
export declare function moveLine(itemIndex: number, delta: vec.Vector2): MoveLine;
|
|
25
25
|
/** This action assumes a flat array of vectors */
|
|
26
26
|
export declare const moveAll: (delta: vec.Vector2) => MoveAll;
|
|
27
|
+
export declare const MOVE_POINT = "move-point";
|
|
28
|
+
export interface MovePoint {
|
|
29
|
+
type: typeof MOVE_POINT;
|
|
30
|
+
index: number;
|
|
31
|
+
destination: vec.Vector2;
|
|
32
|
+
}
|
|
33
|
+
export declare function movePoint(index: number, destination: vec.Vector2): MovePoint;
|
|
27
34
|
export {};
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import { type InteractiveGraphAction } from "./interactive-graph-action";
|
|
2
2
|
import type { InteractiveGraphState } from "../types";
|
|
3
|
-
export declare function interactiveGraphReducer
|
|
3
|
+
export declare function interactiveGraphReducer(state: InteractiveGraphState, action: InteractiveGraphAction): InteractiveGraphState;
|
|
@@ -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
|
|
10
|
+
export declare function getGradableGraph(state: InteractiveGraphState, initialGraph: PerseusGraphType): PerseusGraphType;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import type { InteractiveGraphAction } from "./interactive-graph-action";
|
|
3
|
+
import type { InteractiveGraphState } from "../types";
|
|
4
|
+
export declare const GraphStateContext: React.Context<{
|
|
5
|
+
state: InteractiveGraphState;
|
|
6
|
+
dispatch: React.Dispatch<InteractiveGraphAction>;
|
|
7
|
+
}>;
|
|
8
|
+
export default function useGraphState(): {
|
|
9
|
+
state: InteractiveGraphState;
|
|
10
|
+
dispatch: React.Dispatch<InteractiveGraphAction>;
|
|
11
|
+
};
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { InteractiveGraphAction } from "./reducer/interactive-graph-action";
|
|
2
|
-
import type {
|
|
2
|
+
import type { PerseusGraphType, PerseusInteractiveGraphWidgetOptions } from "../../perseus-types";
|
|
3
3
|
import type { WidgetProps } from "../../types";
|
|
4
|
+
import type { Coord } from "@khanacademy/perseus";
|
|
4
5
|
import type { Interval, vec } from "mafs";
|
|
5
6
|
export type InteractiveGraphProps = WidgetProps<PerseusInteractiveGraphWidgetOptions, PerseusInteractiveGraphWidgetOptions>;
|
|
6
7
|
export type MafsGraphProps<T extends InteractiveGraphState> = {
|
|
@@ -12,17 +13,37 @@ export interface InitializeGraphStateParams<T extends PerseusGraphType> {
|
|
|
12
13
|
range: [Interval, Interval];
|
|
13
14
|
step: vec.Vector2;
|
|
14
15
|
}
|
|
15
|
-
export type InteractiveGraphState = SegmentGraphState | LinearGraphState | RayGraphState | PolygonGraphState;
|
|
16
|
+
export type InteractiveGraphState = SegmentGraphState | LinearGraphState | RayGraphState | PolygonGraphState | PointGraphState | CircleGraphState;
|
|
16
17
|
export interface InteractiveGraphStateCommon {
|
|
17
18
|
hasBeenInteractedWith: boolean;
|
|
18
19
|
range: [Interval, Interval];
|
|
19
20
|
snapStep: vec.Vector2;
|
|
20
21
|
}
|
|
21
|
-
export
|
|
22
|
-
|
|
22
|
+
export interface SegmentGraphState extends InteractiveGraphStateCommon {
|
|
23
|
+
type: "segment";
|
|
24
|
+
coords: PairOfPoints[];
|
|
25
|
+
}
|
|
26
|
+
export interface LinearGraphState extends InteractiveGraphStateCommon {
|
|
23
27
|
type: "linear" | "linear-system";
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
28
|
+
coords: PairOfPoints[];
|
|
29
|
+
}
|
|
30
|
+
export interface PointGraphState extends InteractiveGraphStateCommon {
|
|
31
|
+
type: "point";
|
|
32
|
+
coords: Coord[];
|
|
33
|
+
}
|
|
34
|
+
export interface RayGraphState extends InteractiveGraphStateCommon {
|
|
35
|
+
type: "ray";
|
|
36
|
+
coords: PairOfPoints[];
|
|
37
|
+
}
|
|
38
|
+
export interface PolygonGraphState extends InteractiveGraphStateCommon {
|
|
39
|
+
type: "polygon";
|
|
40
|
+
showAngles: boolean;
|
|
41
|
+
showSides: boolean;
|
|
42
|
+
coords: Coord[];
|
|
43
|
+
}
|
|
44
|
+
export interface CircleGraphState extends InteractiveGraphStateCommon {
|
|
45
|
+
type: "circle";
|
|
46
|
+
center: Coord;
|
|
47
|
+
radius: number;
|
|
48
|
+
}
|
|
49
|
+
export type PairOfPoints = [Coord, Coord];
|
|
@@ -5,5 +5,5 @@ import type { PerseusInteractiveGraphWidgetOptions } from "../../perseus-types";
|
|
|
5
5
|
* https://www.w3.org/WAI/WCAG21/Understanding/target-size.html
|
|
6
6
|
*/
|
|
7
7
|
export declare const TARGET_SIZE = 44;
|
|
8
|
-
export declare const normalizePoints: <A extends
|
|
9
|
-
export declare const normalizeCoords: <A extends
|
|
8
|
+
export declare const normalizePoints: <A extends Coord[]>(range: PerseusInteractiveGraphWidgetOptions["range"], step: PerseusInteractiveGraphWidgetOptions["step"], coordsList: A, noSnap?: boolean) => A;
|
|
9
|
+
export declare const normalizeCoords: <A extends Coord[]>(coordsList: A, ranges: PerseusInteractiveGraphWidgetOptions["range"]) => A;
|