@khanacademy/perseus 21.0.0 → 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/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, PerseusWidgetsMap } 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,7 +22,7 @@ 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;
25
+ declare function injectWidgets(content: string, widgets: PerseusRenderer["widgets"], widgetProps?: PerseusWidgetsMap): string;
26
26
  export declare const isWrongAnswerSupported: (widgetIds: Array<string>, widgetMap: PerseusWidgetsMap) => boolean;
27
27
  export declare const shouldHaveIndividualAnswer: (widgetId: string, widgetMap: PerseusWidgetsMap) => boolean;
28
28
  export declare const getAnswerFromUserInput: (widgetType: string, userInput: any) => any;
@@ -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: (arg1: any) => void;
84
+ onChange: ChangeHandler;
85
85
  addPointControls: () => void;
86
86
  removePointControls: () => void;
87
87
  addSegmentControls: () => void;
@@ -0,0 +1,2 @@
1
+ /// <reference types="react" />
2
+ export default function AxisArrows(): JSX.Element;
@@ -0,0 +1,5 @@
1
+ /// <reference types="react" />
2
+ import type { PointGraphState, MafsGraphProps } from "../types";
3
+ type PointGraphProps = MafsGraphProps<PointGraphState>;
4
+ export declare function PointGraph(props: PointGraphProps): JSX.Element;
5
+ export {};
@@ -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 declare const MafsGraph: React.ForwardRefExoticComponent<import("../..").PerseusInteractiveGraphWidgetOptions & {
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?: number;
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?: number): MoveControlPoint;
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<GraphState extends InteractiveGraphState>(state: Readonly<GraphState>, action: InteractiveGraphAction): GraphState;
3
+ export declare function interactiveGraphReducer(state: InteractiveGraphState, action: InteractiveGraphAction): InteractiveGraphState;
@@ -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 { CollinearTuple, PerseusGraphType, PerseusGraphTypeLinearSystem, PerseusGraphTypePolygon, PerseusGraphTypeRay, PerseusGraphTypeSegment, PerseusInteractiveGraphWidgetOptions } from "../../perseus-types";
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 type SegmentGraphState = InteractiveGraphStateCommon & Omit<PerseusGraphTypeSegment, "numSegments">;
22
- export type LinearGraphState = InteractiveGraphStateCommon & Omit<PerseusGraphTypeLinearSystem, "type"> & {
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
- export type RayGraphState = InteractiveGraphStateCommon & Omit<PerseusGraphTypeRay, "coords"> & {
26
- coords: readonly CollinearTuple[];
27
- };
28
- export type PolygonGraphState = InteractiveGraphStateCommon & PerseusGraphTypePolygon;
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 readonly Coord[]>(range: PerseusInteractiveGraphWidgetOptions["range"], step: PerseusInteractiveGraphWidgetOptions["step"], coordsList: A, noSnap?: boolean) => A;
9
- export declare const normalizeCoords: <A extends readonly Coord[]>(coordsList: A, ranges: PerseusInteractiveGraphWidgetOptions["range"]) => A;
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;
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": "21.0.0",
6
+ "version": "21.1.0",
7
7
  "publishConfig": {
8
8
  "access": "public"
9
9
  },