@khanacademy/perseus 20.5.0 → 20.7.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/icon.d.ts +1 -0
  2. package/dist/es/index.css +19 -6
  3. package/dist/es/index.js +750 -269
  4. package/dist/es/index.js.map +1 -1
  5. package/dist/index.css +19 -6
  6. package/dist/index.d.ts +2 -0
  7. package/dist/index.js +853 -358
  8. package/dist/index.js.map +1 -1
  9. package/dist/interactive2/movable.d.ts +1 -1
  10. package/dist/interactive2/objective_.d.ts +2 -2
  11. package/dist/styles/global-styles.d.ts +1 -0
  12. package/dist/styles/shared.d.ts +1 -0
  13. package/dist/types.d.ts +102 -0
  14. package/dist/util/a11y.d.ts +1 -0
  15. package/dist/util/extract-perseus-data.d.ts +8 -1
  16. package/dist/util/snowman-utils.d.ts +90 -0
  17. package/dist/util/widget-enum-utils.d.ts +11 -0
  18. package/dist/util.d.ts +1 -1
  19. package/dist/widgets/interactive-graph.d.ts +9 -2
  20. package/dist/widgets/interactive-graphs/graphs/index.d.ts +1 -0
  21. package/dist/widgets/interactive-graphs/graphs/polygon.d.ts +5 -0
  22. package/dist/widgets/interactive-graphs/mafs-graph.d.ts +1 -1
  23. package/dist/widgets/interactive-graphs/reducer/interactive-graph-action.d.ts +27 -0
  24. package/dist/widgets/interactive-graphs/reducer/interactive-graph-reducer.d.ts +3 -0
  25. package/dist/widgets/interactive-graphs/{interactive-graph-state.d.ts → reducer/interactive-graph-state.d.ts} +2 -2
  26. package/dist/widgets/interactive-graphs/types.d.ts +12 -6
  27. package/dist/widgets/interactive-graphs/utils.d.ts +5 -0
  28. package/dist/widgets/label-image/answer-pill.d.ts +1 -0
  29. package/dist/widgets/label-image/marker.d.ts +1 -0
  30. package/dist/widgets/radio/choice-icon/shared-styles.d.ts +1 -0
  31. package/dist/widgets/radio.d.ts +1 -1
  32. package/package.json +4 -6
  33. package/dist/widgets/interactive-graphs/interactive-graph-action.d.ts +0 -17
  34. package/dist/widgets/interactive-graphs/interactive-graph-reducer.d.ts +0 -3
  35. /package/dist/widgets/radio/{widget.d.ts → radio.d.ts} +0 -0
@@ -57,7 +57,7 @@ export declare class Movable<Options extends Record<string, any>> {
57
57
  * Simulates a mouse grab event on the movable object.
58
58
  */
59
59
  grab(coord: Coord): void;
60
- _applyConstraints(current: Coord, previous: Coord, extraOptions?: ConstraintCallbacks): false | [number, number];
60
+ _applyConstraints(current: Coord, previous: Coord, extraOptions?: ConstraintCallbacks): false | Coord;
61
61
  toBack(): void;
62
62
  toFront(): void;
63
63
  /**
@@ -7,7 +7,7 @@
7
7
  */
8
8
  declare const _default: {
9
9
  pluck: (table: any, subKey: string) => any;
10
- mapObject: <K extends string, V, U>(obj: Partial<Record<K, V>>, lambda: (arg1: V, arg2: K) => U) => Partial<Record<K, U>>;
11
- mapObjectFromArray: <K_1 extends string, V_1>(arr: readonly K_1[], lambda: (arg1: K_1) => V_1) => Partial<Record<K_1, V_1>>;
10
+ mapObject: <K extends string, V, U>(obj: Record<K, V>, lambda: (arg1: V, arg2: K) => U) => Record<K, U>;
11
+ mapObjectFromArray: <K_1 extends string, V_1>(arr: readonly K_1[], lambda: (arg1: K_1) => V_1) => Record<K_1, V_1>;
12
12
  };
13
13
  export default _default;
@@ -1,3 +1,4 @@
1
+ /// <reference path="../../types/aphrodite.d.ts" />
1
2
  import type { StyleDeclaration } from "aphrodite";
2
3
  export declare const colors: {
3
4
  readonly white: "#FFFFFF";
@@ -1,3 +1,4 @@
1
+ /// <reference path="../../types/aphrodite.d.ts" />
1
2
  import type { StyleDeclaration } from "aphrodite";
2
3
  declare const _default: StyleDeclaration;
3
4
  export default _default;
package/dist/types.d.ts CHANGED
@@ -75,6 +75,11 @@ type TrackInteractionArgs = {
75
75
  id: string;
76
76
  correct?: boolean;
77
77
  } & Partial<TrackingGradedGroupExtraArguments> & Partial<TrackingSequenceExtraArguments>;
78
+ /**
79
+ * APIOptions provides different ways to customize the behaviour of Perseus.
80
+ *
81
+ * @see APIOptionsWithDefaults
82
+ */
78
83
  export type APIOptions = Readonly<{
79
84
  isArticle?: boolean;
80
85
  onInputError?: (widgetId: any, value: string, message?: string | null | undefined) => unknown;
@@ -87,25 +92,117 @@ export type APIOptions = Readonly<{
87
92
  interactionCallback?: (widgetData: {
88
93
  [widgetId: string]: any;
89
94
  }) => void;
95
+ /**
96
+ * A function that takes in the relative problem number (starts at
97
+ * 0 and is incremented for each group widget), and the ID of the
98
+ * group widget, then returns a react component that will be added
99
+ * immediately above the renderer in the group widget. If the
100
+ * function returns null, no annotation will be added.
101
+ */
90
102
  groupAnnotator?: (groupNumber: number, widgetId: string) => React.ReactNode;
103
+ /**
104
+ * If imagePlaceholder is set, Perseus will render the placeholder instead
105
+ * of the image node.
106
+ */
91
107
  imagePlaceholder?: React.ReactNode;
108
+ /**
109
+ * If widgetPlaceholder is set, Perseus will render the placeholder instead
110
+ * of the widget node.
111
+ */
92
112
  widgetPlaceholder?: React.ReactNode;
113
+ /**
114
+ * Base React elements that can be used in place of the standard DOM
115
+ * DOM elements. For example, when provided, <Link /> will be used
116
+ * in place of <a />. This allows clients to provide pre-styled
117
+ * components or components with custom behavior.
118
+ */
93
119
  baseElements?: {
120
+ /**
121
+ * The <Link /> component provided here must adhere to the same
122
+ * interface as React's base <a /> component.
123
+ */
94
124
  Link: React.ComponentType<any>;
95
125
  };
126
+ /**
127
+ * Function that takes dimensions and returns a React component
128
+ * to display while an image is loading.
129
+ */
96
130
  imagePreloader?: (dimensions: Dimensions) => React.ReactNode;
131
+ /**
132
+ * A function that is called when the user has interacted with a widget. It
133
+ * also includes any extra parameters that the originating widget provided.
134
+ * This is used for keeping track of widget interactions.
135
+ */
97
136
  trackInteraction?: (args: TrackInteractionArgs) => void;
137
+ /**
138
+ * A boolean that indicates whether or not a custom keypad is
139
+ * being used. For mobile web this will be the ProvidedKeypad
140
+ * component. In this situation we use the MathInput component
141
+ * from the math-input repo instead of the existing perseus math
142
+ * input components.
143
+ */
98
144
  customKeypad?: boolean;
145
+ /**
146
+ * If this is provided, it is called instead of appending an instance
147
+ * of `math-input`'s keypad to the body. This is used by the native
148
+ * apps so they can have the keypad be defined on the native side.
149
+ * It is called with an function that, when called, blurs the input,
150
+ * and is expected to return an object of the shape
151
+ * keypadElementPropType from math-input/src/prop-types.js.
152
+ */
99
153
  nativeKeypadProxy?: (blur: () => void) => KeypadAPI;
154
+ /** Indicates whether or not to use mobile styling. */
100
155
  isMobile?: boolean;
156
+ /** A function, called with a bool indicating whether use of the
157
+ * drawing area (scratchpad) should be allowed/disallowed.
158
+ *
159
+ * Previously handled by `Khan.scratchpad.enable/disable`
160
+ */
101
161
  setDrawingAreaAvailable?: (arg1: boolean) => unknown;
162
+ /** Whether to use the Draft.js editor or the legacy textarea */
102
163
  useDraftEditor?: boolean;
164
+ /** The color used for the hint progress indicator (eg. 1 / 3) */
103
165
  hintProgressColor?: string;
166
+ /**
167
+ * Whether this Renderer is allowed to auto-scroll the rest of the
168
+ * page. For example, if this is enabled, the most recently used
169
+ * radio widget will attempt to keep the "selected" answer in view
170
+ * after entering review mode.
171
+ *
172
+ * Defaults to `false`.
173
+ */
104
174
  canScrollPage?: boolean;
175
+ /** Whether or not we are rendering content inside of a modal. */
105
176
  inModal?: boolean;
177
+ /**
178
+ * Whether to enable the cross-out feature on multiple-choice radio
179
+ * widgets. This allows users to note which answers they believe to
180
+ * be incorrect, to find the answer by process of elimination.
181
+ *
182
+ * We plan to roll this out to all call sites eventually, but for
183
+ * now we have this flag, to add it to Generalized Test Prep first.
184
+ */
106
185
  crossOutEnabled?: boolean;
186
+ /**
187
+ * The value in milliseconds by which the local state of content
188
+ * in a editor is delayed before propagated to a prop. For example,
189
+ * when text is typed in the text area of an Editor component,
190
+ * there will be a delay equal to the value of `editorChangeDelay`
191
+ * before the change is propagated. This is added for better
192
+ * responsiveness of the editor when used in certain contexts such
193
+ * as StructuredItem exercises where constant re-rendering for each
194
+ * keystroke caused text typed in the text area to appear in it
195
+ * only after a good few seconds.
196
+ */
107
197
  editorChangeDelay?: number;
198
+ /** Feature flags that can be passed from consuming application. */
108
199
  flags?: Record<string, boolean | Record<string, boolean>>;
200
+ /**
201
+ * This is a callback function that returns all of the Widget props
202
+ * after they have been transformed by the widget's transform function.
203
+ * This is useful for when we need to know how a widget has shuffled its
204
+ * the available choices.
205
+ */
109
206
  onWidgetStartProps?: (widgets: PerseusWidgetsMap) => PerseusWidgetsMap;
110
207
  }>;
111
208
  type TeXProps = {
@@ -181,6 +278,11 @@ export type PerseusDependenciesV2 = {
181
278
  onAnalyticsEvent: AnalyticsEventHandlerFn;
182
279
  };
183
280
  };
281
+ /**
282
+ * APIOptionsWithDefaults represents the type that is provided to all widgets.
283
+ * The Renderer fills in these defaults when providing APIOptions to any
284
+ * widget.
285
+ */
184
286
  export type APIOptionsWithDefaults = Readonly<APIOptions & {
185
287
  GroupMetadataEditor: NonNullable<APIOptions["GroupMetadataEditor"]>;
186
288
  baseElements: NonNullable<APIOptions["baseElements"]>;
@@ -1,3 +1,4 @@
1
+ /// <reference path="../../types/aphrodite.d.ts" />
1
2
  import type { StyleDeclaration } from "aphrodite";
2
3
  declare const _default: StyleDeclaration;
3
4
  export default _default;
@@ -1,4 +1,4 @@
1
- import type { PerseusRenderer } from "../perseus-types";
1
+ import type { PerseusItem, PerseusRenderer } from "../perseus-types";
2
2
  /**
3
3
  * This function extracts the answers from the widgets.
4
4
  *
@@ -23,4 +23,11 @@ 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;
29
+ 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>;
26
33
  export { getAnswersFromWidgets, injectWidgets };
@@ -0,0 +1,90 @@
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
+ export declare const QUESTION_WIDGETS: ReadonlyArray<string>;
42
+ /**
43
+ * Regex for widget placeholders in a string.
44
+ *
45
+ * First capture group is the widget ID (ex. 'radio 1')
46
+ * Second capture group is the widget type (ex. "radio)
47
+ * exec return will look like: ['[[☃ radio 1]]', 'radio 1', 'radio']
48
+ */
49
+ export declare function getWidgetRegex(): RegExp;
50
+ /**
51
+ * Add a widget placeholder using the provided widget type and instance number.
52
+ * ex. addWidget(WidgetType.Radio, 1) => "[[☃ radio 1]]"
53
+ *
54
+ * @param {WidgetType} widgetType
55
+ * @param {number} instance
56
+ * @returns {string}
57
+ */
58
+ export declare function addWidget(widgetType: WidgetType, instance: number): string;
59
+ /**
60
+ * Extract all widget IDs, which includes the widget type and instance number.
61
+ * example output: ['radio 1', 'categorizer 1', 'categorizor 2']
62
+ *
63
+ * Content should contain Perseus widget placeholders,
64
+ * which look like: '[[☃ radio 1]]'.
65
+ *
66
+ * @param {string} content
67
+ * @returns {Array<WidgetId>} widgets
68
+ */
69
+ export declare function getAllWidgetIds(content: string): Array<WidgetId>;
70
+ /**
71
+ * Extract all widget types from a Perseus JSON content string.
72
+ * This does not include the instance number and prevents duplicates.
73
+ * example output: ['radio', 'categorizer']
74
+ *
75
+ * @param {string} content
76
+ * @returns {Array<WidgetId>}
77
+ */
78
+ export declare function getAllWidgetTypes(content: string): Array<WidgetId>;
79
+ /**
80
+ * Extract the widget IDs of all widgets considered question widgets. Widget IDs
81
+ * include widget type and instance number.
82
+ * example output: ['radio 1', 'categorizer 1']
83
+ *
84
+ * Content should contain Perseus widget placeholders,
85
+ * which look like: '[[☃ radio 1]]'.
86
+ *
87
+ * @param {string} content
88
+ * @returns Array<WidgetId>
89
+ */
90
+ export declare function getQuestionWidgetIds(content: string): Array<WidgetId>;
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Some helpers for CEDAR logging. CEDAR convention dictates
3
+ * that enum values should be upper case. Ex: for the
4
+ * PerseusWidgetUsedInProblemAttempt CEDAR event, we needed
5
+ * to: get the type and convert that to an enum value.
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
+ 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;
11
+ export {};
package/dist/util.d.ts CHANGED
@@ -190,7 +190,7 @@ declare function getWordBeforeCursor(textarea: HTMLTextAreaElement): WordAndPosi
190
190
  declare function moveCursor(textarea: HTMLTextAreaElement, pos: number): void;
191
191
  declare const Util: {
192
192
  readonly inputPathsEqual: typeof inputPathsEqual;
193
- readonly nestedMap: <T, M>(children: T | readonly T[], func: (arg1: T) => M, context: unknown) => M | readonly M[];
193
+ readonly nestedMap: <T, M>(children: T | ReadonlyArray<T>, func: (arg1: T) => M, context: unknown) => M | ReadonlyArray<M>;
194
194
  readonly rWidgetRule: RegExp;
195
195
  readonly rTypeFromWidgetId: RegExp;
196
196
  readonly rWidgetParts: RegExp;
@@ -21,7 +21,7 @@ type DefaultProps = {
21
21
  rulerTicks: Props["rulerTicks"];
22
22
  graph: Props["graph"];
23
23
  };
24
- declare class InteractiveGraph extends React.Component<Props, State> {
24
+ declare class LegacyInteractiveGraph extends React.Component<Props, State> {
25
25
  angle: any | null | undefined;
26
26
  circle: any | null | undefined;
27
27
  graphie: any | null | undefined;
@@ -39,7 +39,6 @@ declare class InteractiveGraph extends React.Component<Props, State> {
39
39
  trashCan: any | null | undefined;
40
40
  vertHairline: any | null | undefined;
41
41
  static defaultProps: DefaultProps;
42
- mafsRef: React.RefObject<Widget>;
43
42
  state: State;
44
43
  UNSAFE_componentWillMount(): void;
45
44
  componentDidMount(): void;
@@ -99,6 +98,14 @@ declare class InteractiveGraph extends React.Component<Props, State> {
99
98
  simpleValidate: (rubric: Rubric) => PerseusScore;
100
99
  focus: () => void;
101
100
  render(): React.ReactNode;
101
+ }
102
+ declare class InteractiveGraph extends React.Component<Props, State> {
103
+ legacyGraphRef: React.RefObject<LegacyInteractiveGraph>;
104
+ mafsRef: React.RefObject<Widget>;
105
+ static defaultProps: DefaultProps;
106
+ getUserInput: Widget["getUserInput"];
107
+ simpleValidate: (rubric: Rubric) => PerseusScore;
108
+ render(): JSX.Element;
102
109
  static getQuadraticCoefficients(coords: ReadonlyArray<Coord>): QuadraticCoefficient;
103
110
  static getSinusoidCoefficients(coords: ReadonlyArray<Coord>): SineCoefficient;
104
111
  /**
@@ -1,3 +1,4 @@
1
1
  export { SegmentGraph } from "./segment";
2
2
  export { LinearGraph } from "./linear";
3
3
  export { RayGraph } from "./ray";
4
+ export { PolygonGraph } from "./polygon";
@@ -0,0 +1,5 @@
1
+ /// <reference types="react" />
2
+ import type { MafsGraphProps, PolygonGraphState } from "../types";
3
+ type Props = MafsGraphProps<PolygonGraphState>;
4
+ export declare const PolygonGraph: (props: Props) => JSX.Element;
5
+ export {};
@@ -71,7 +71,7 @@ export declare const MafsGraph: React.ForwardRefExoticComponent<import("../..").
71
71
  onChange: import("../..").ChangeHandler;
72
72
  trackInteraction: (extraData?: {} | undefined) => void;
73
73
  isLastUsedWidget: boolean;
74
- linterContext: import("../../../../perseus-linter/src").LinterContextProps;
74
+ linterContext: import("@khanacademy/perseus-linter").LinterContextProps;
75
75
  containerSizeClass: import("../../util/sizing-utils").SizeClass;
76
76
  } & {
77
77
  children?: React.ReactNode;
@@ -0,0 +1,27 @@
1
+ import type { vec } from "mafs";
2
+ export type InteractiveGraphAction = MoveControlPoint | MoveLine | MoveAll;
3
+ export declare const MOVE_CONTROL_POINT = "move-control-point";
4
+ export interface MoveControlPoint {
5
+ type: typeof MOVE_CONTROL_POINT;
6
+ itemIndex?: number;
7
+ pointIndex: number;
8
+ destination: vec.Vector2;
9
+ }
10
+ export declare function moveControlPoint(pointIndex: number, destination: vec.Vector2, itemIndex?: number): MoveControlPoint;
11
+ export declare const MOVE_ALL = "move-all";
12
+ export declare const MOVE_LINE = "move-line";
13
+ interface MoveItem {
14
+ delta: vec.Vector2;
15
+ itemIndex?: number;
16
+ }
17
+ export interface MoveLine extends MoveItem {
18
+ type: typeof MOVE_LINE;
19
+ }
20
+ export interface MoveAll extends MoveItem {
21
+ type: typeof MOVE_ALL;
22
+ }
23
+ /** This action assumes the state.coords holds an array of collinear tuples that define lines */
24
+ export declare function moveLine(itemIndex: number, delta: vec.Vector2): MoveLine;
25
+ /** This action assumes a flat array of vectors */
26
+ export declare const moveAll: (delta: vec.Vector2) => MoveAll;
27
+ export {};
@@ -0,0 +1,3 @@
1
+ import { type InteractiveGraphAction } from "./interactive-graph-action";
2
+ import type { InteractiveGraphState } from "../types";
3
+ export declare function interactiveGraphReducer<GraphState extends InteractiveGraphState>(state: Readonly<GraphState>, action: InteractiveGraphAction): GraphState;
@@ -1,5 +1,5 @@
1
- import type { InteractiveGraphState } from "./types";
2
- import type { PerseusGraphType } from "../../perseus-types";
1
+ import type { PerseusGraphType } from "../../../perseus-types";
2
+ import type { InteractiveGraphState } from "../types";
3
3
  import type { Interval, vec } from "mafs";
4
4
  export declare function initializeGraphState(params: {
5
5
  range: [Interval, Interval];
@@ -1,5 +1,5 @@
1
- import type { InteractiveGraphAction } from "./interactive-graph-action";
2
- import type { CollinearTuple, PerseusGraphTypeLinearSystem, PerseusGraphTypeRay, PerseusGraphTypeSegment, PerseusInteractiveGraphWidgetOptions } from "../../perseus-types";
1
+ import type { InteractiveGraphAction } from "./reducer/interactive-graph-action";
2
+ import type { CollinearTuple, PerseusGraphType, PerseusGraphTypeLinearSystem, PerseusGraphTypePolygon, PerseusGraphTypeRay, PerseusGraphTypeSegment, PerseusInteractiveGraphWidgetOptions } from "../../perseus-types";
3
3
  import type { WidgetProps } from "../../types";
4
4
  import type { Interval, vec } from "mafs";
5
5
  export type InteractiveGraphProps = WidgetProps<PerseusInteractiveGraphWidgetOptions, PerseusInteractiveGraphWidgetOptions>;
@@ -7,16 +7,22 @@ export type MafsGraphProps<T extends InteractiveGraphState> = {
7
7
  graphState: T;
8
8
  dispatch: (action: InteractiveGraphAction) => unknown;
9
9
  };
10
- export type InteractiveGraphState = SegmentGraphState | LinearGraphState | RayGraphState;
10
+ export interface InitializeGraphStateParams<T extends PerseusGraphType> {
11
+ graph: T;
12
+ range: [Interval, Interval];
13
+ step: vec.Vector2;
14
+ }
15
+ export type InteractiveGraphState = SegmentGraphState | LinearGraphState | RayGraphState | PolygonGraphState;
11
16
  export interface InteractiveGraphStateCommon {
12
17
  hasBeenInteractedWith: boolean;
13
18
  range: [Interval, Interval];
14
19
  snapStep: vec.Vector2;
15
20
  }
16
- export type SegmentGraphState = InteractiveGraphStateCommon & Pick<PerseusGraphTypeSegment, "type" | "coords">;
17
- export type LinearGraphState = InteractiveGraphStateCommon & Pick<PerseusGraphTypeLinearSystem, "coords"> & {
21
+ export type SegmentGraphState = InteractiveGraphStateCommon & Omit<PerseusGraphTypeSegment, "numSegments">;
22
+ export type LinearGraphState = InteractiveGraphStateCommon & Omit<PerseusGraphTypeLinearSystem, "type"> & {
18
23
  type: "linear" | "linear-system";
19
24
  };
20
- export type RayGraphState = InteractiveGraphStateCommon & Pick<PerseusGraphTypeRay, "type"> & {
25
+ export type RayGraphState = InteractiveGraphStateCommon & Omit<PerseusGraphTypeRay, "coords"> & {
21
26
  coords: readonly CollinearTuple[];
22
27
  };
28
+ export type PolygonGraphState = InteractiveGraphStateCommon & PerseusGraphTypePolygon;
@@ -1,4 +1,9 @@
1
1
  import type { Coord } from "../../interactive2/types";
2
2
  import type { PerseusInteractiveGraphWidgetOptions } from "../../perseus-types";
3
+ /**
4
+ * 44 is touch best practice and AAA compliant for WCAG
5
+ * https://www.w3.org/WAI/WCAG21/Understanding/target-size.html
6
+ */
7
+ export declare const TARGET_SIZE = 44;
3
8
  export declare const normalizePoints: <A extends readonly Coord[]>(range: PerseusInteractiveGraphWidgetOptions["range"], step: PerseusInteractiveGraphWidgetOptions["step"], coordsList: A, noSnap?: boolean) => A;
4
9
  export declare const normalizeCoords: <A extends readonly Coord[]>(coordsList: A, ranges: PerseusInteractiveGraphWidgetOptions["range"]) => A;
@@ -1,3 +1,4 @@
1
+ /// <reference path="../../../types/aphrodite.d.ts" />
1
2
  /// <reference types="react" />
2
3
  import { type CSSProperties } from "aphrodite";
3
4
  export declare const AnswerPill: (props: {
@@ -3,6 +3,7 @@
3
3
  *
4
4
  * The target for labeling question image with answers.
5
5
  */
6
+ /// <reference path="../../../types/aphrodite.d.ts" />
6
7
  import * as React from "react";
7
8
  import type { InteractiveMarkerType } from "./types";
8
9
  import type { AnalyticsEventHandlerFn } from "@khanacademy/perseus-core";
@@ -1,3 +1,4 @@
1
+ /// <reference path="../../../../types/aphrodite.d.ts" />
1
2
  import type { StyleDeclaration } from "aphrodite";
2
3
  declare const CHOICE_ICON_SIZE = 24;
3
4
  declare const styles: StyleDeclaration;
@@ -1,4 +1,4 @@
1
- import Radio from "./radio/widget";
1
+ import Radio from "./radio/radio";
2
2
  declare const _default: Readonly<{
3
3
  name: string;
4
4
  displayName: string;
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.5.0",
6
+ "version": "20.7.0",
7
7
  "publishConfig": {
8
8
  "access": "public"
9
9
  },
@@ -25,13 +25,13 @@
25
25
  "test": "bash -c 'yarn --silent --cwd \"../..\" test ${@:0} $($([[ ${@: -1} = -* ]] || [[ ${@: -1} = bash ]]) && echo $PWD)'"
26
26
  },
27
27
  "dependencies": {
28
- "@khanacademy/kas": "^0.3.8",
28
+ "@khanacademy/kas": "^0.3.9",
29
29
  "@khanacademy/kmath": "^0.1.12",
30
30
  "@khanacademy/math-input": "^17.3.0",
31
31
  "@khanacademy/perseus-core": "1.4.2",
32
32
  "@khanacademy/perseus-linter": "^0.3.12",
33
- "@khanacademy/pure-markdown": "^0.3.0",
34
- "@khanacademy/simple-markdown": "^0.11.3",
33
+ "@khanacademy/pure-markdown": "^0.3.1",
34
+ "@khanacademy/simple-markdown": "^0.11.4",
35
35
  "@khanacademy/wonder-blocks-banner": "^3.0.33",
36
36
  "mafs": "https://github.com/Khan/mafs/releases/download/v0.18.1%2Bbuild-cd8b2467893342ba0b02100073fe21f93f8b1125/mafs-0.18.1.tgz"
37
37
  },
@@ -62,8 +62,6 @@
62
62
  "aphrodite": "^1.2.5",
63
63
  "classnames": "^1.1.4",
64
64
  "create-react-class": "^15.6.3",
65
- "eslint-import-resolver-alias": "^1.1.2",
66
- "eslint-plugin-import": "^2.26.0",
67
65
  "intersection-observer": "^0.12.0",
68
66
  "jquery": "^2.1.1",
69
67
  "katex": "^0.11.1",
@@ -1,17 +0,0 @@
1
- import type { vec } from "mafs";
2
- export type InteractiveGraphAction = MoveControlPoint | MoveSegment;
3
- export declare const MOVE_CONTROL_POINT = "move-control-point";
4
- export interface MoveControlPoint {
5
- type: typeof MOVE_CONTROL_POINT;
6
- objectIndex: number;
7
- pointIndex: number;
8
- destination: vec.Vector2;
9
- }
10
- export declare function moveControlPoint(objectIndex: number, pointIndex: number, destination: vec.Vector2): MoveControlPoint;
11
- export declare const MOVE_LINE = "move-line";
12
- export interface MoveSegment {
13
- type: typeof MOVE_LINE;
14
- lineIndex: number;
15
- delta: vec.Vector2;
16
- }
17
- export declare function moveSegment(lineIndex: number, delta: vec.Vector2): MoveSegment;
@@ -1,3 +0,0 @@
1
- import { type InteractiveGraphAction } from "./interactive-graph-action";
2
- import type { InteractiveGraphState } from "./types";
3
- export declare function interactiveGraphReducer(state: Readonly<InteractiveGraphState>, action: InteractiveGraphAction): InteractiveGraphState;
File without changes