@khanacademy/perseus-editor 35.2.1 → 35.3.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 (39) hide show
  1. package/dist/components/a11y-context.d.ts +24 -0
  2. package/dist/components/info-tip/index.d.ts +19 -0
  3. package/dist/components/info-tip/info-tip-base.d.ts +6 -0
  4. package/dist/components/issues-panel.d.ts +38 -6
  5. package/dist/components/show-me-issue.d.ts +8 -3
  6. package/dist/components/text-list-editor.d.ts +15 -0
  7. package/dist/components/widget-editor.d.ts +1 -1
  8. package/dist/editor-page.d.ts +12 -7
  9. package/dist/es/index.js +87 -73
  10. package/dist/es/index.js.map +1 -1
  11. package/dist/index.js +86 -71
  12. package/dist/index.js.map +1 -1
  13. package/dist/item-editor.d.ts +9 -5
  14. package/dist/item-extras-editor.d.ts +1 -0
  15. package/dist/preview/a11y/map-axe-results.d.ts +13 -0
  16. package/dist/preview/a11y/overlays.d.ts +22 -0
  17. package/dist/preview/message-types.d.ts +75 -4
  18. package/dist/preview/use-preview-controller.d.ts +21 -0
  19. package/dist/preview/use-preview-presenter.d.ts +19 -1
  20. package/dist/preview-with-iframe.d.ts +15 -0
  21. package/dist/util/derive-device-api-options.d.ts +14 -0
  22. package/dist/util/derive-question-preview-content.d.ts +23 -0
  23. package/dist/widgets/interaction-editor/arrow-picker.d.ts +2 -2
  24. package/dist/widgets/interaction-editor/color-picker.d.ts +2 -2
  25. package/dist/widgets/interaction-editor/dash-picker.d.ts +2 -2
  26. package/dist/widgets/interaction-editor/element-container.d.ts +3 -3
  27. package/dist/widgets/interaction-editor/function-editor.d.ts +0 -1
  28. package/dist/widgets/interaction-editor/label-editor.d.ts +0 -1
  29. package/dist/widgets/interaction-editor/line-editor.d.ts +0 -1
  30. package/dist/widgets/interaction-editor/movable-line-editor.d.ts +0 -1
  31. package/dist/widgets/interaction-editor/movable-point-editor.d.ts +0 -1
  32. package/dist/widgets/interaction-editor/parametric-editor.d.ts +0 -1
  33. package/dist/widgets/interaction-editor/point-editor.d.ts +0 -1
  34. package/dist/widgets/interaction-editor/rectangle-editor.d.ts +0 -1
  35. package/dist/widgets/interactive-graph-editor/interactive-graph-editor.d.ts +30 -43
  36. package/dist/widgets/interactive-graph-editor/locked-figures/locked-label-settings.d.ts +7 -0
  37. package/package.json +44 -44
  38. package/dist/util/a11y-checker.d.ts +0 -1
  39. /package/dist/{util → preview/a11y}/a11y-issues-list.d.ts +0 -0
@@ -1,12 +1,10 @@
1
1
  import * as React from "react";
2
+ import { A11yContext } from "./components/a11y-context";
2
3
  import Editor from "./editor";
3
4
  import ItemExtrasEditor from "./item-extras-editor";
4
- import type { PreviewContent } from "./preview/message-types";
5
+ import type { A11yReport } from "./preview/use-preview-controller";
5
6
  import type { APIOptions, ImageUploader, ChangeHandler, DeviceType } from "@khanacademy/perseus";
6
7
  import type { PerseusAnswerArea, PerseusRenderer, PerseusItem } from "@khanacademy/perseus-core";
7
- type QuestionPreviewData = Extract<PreviewContent, {
8
- type: "question";
9
- }>;
10
8
  type Props = {
11
9
  /** Additional templates that the host application would like to display
12
10
  * within the Perseus Editor.
@@ -32,6 +30,8 @@ type Props = {
32
30
  problemNum?: number;
33
31
  };
34
32
  declare class ItemEditor extends React.Component<Props> {
33
+ static contextType: React.Context<import("./components/a11y-context").A11yContextValue | null>;
34
+ context: React.ContextType<typeof A11yContext>;
35
35
  static defaultProps: {
36
36
  answerArea: Record<any, any>;
37
37
  onChange: () => void;
@@ -39,15 +39,19 @@ declare class ItemEditor extends React.Component<Props> {
39
39
  };
40
40
  questionEditor: React.RefObject<Editor>;
41
41
  itemExtrasEditor: React.RefObject<ItemExtrasEditor>;
42
+ derivePreviewContent: (inputs: import("./util/derive-question-preview-content").DerivePreviewContentInputs) => {
43
+ type: "question";
44
+ data: import("./preview/message-types").QuestionPreviewData;
45
+ } | null;
42
46
  updateProps: (newProps: Partial<PerseusItem>) => void;
43
47
  handleEditorChange: ChangeHandler;
44
48
  handleItemExtrasChange: (newProps: Partial<PerseusAnswerArea>) => void;
45
49
  getSaveWarnings: () => any;
50
+ handleA11yReport: (report: A11yReport | null) => void;
46
51
  serialize(): {
47
52
  answerArea: PerseusAnswerArea;
48
53
  question: PerseusRenderer;
49
54
  };
50
- _derivePreviewContent(): QuestionPreviewData | null;
51
55
  render(): React.ReactNode;
52
56
  }
53
57
  export default ItemEditor;
@@ -10,6 +10,7 @@ declare class ItemExtrasEditor extends React.Component<Props> {
10
10
  static defaultProps: PerseusAnswerArea;
11
11
  shouldShowCalculatorVariants(): boolean;
12
12
  shouldShowFinancialCalculatorOptions(): boolean;
13
+ handleVariantChange: (newVariant: string) => void;
13
14
  serialize(): PerseusAnswerArea;
14
15
  render(): React.ReactNode;
15
16
  }
@@ -0,0 +1,13 @@
1
+ import type { A11yIssue, IssueImpact } from "../../components/issues-panel";
2
+ import type axe from "axe-core";
3
+ export declare const assistanceNeededMessage = "Developer assistance needed - Please send this exercise and warning info to the LEMS team for review.";
4
+ /**
5
+ * Maps a scan's axe results (one category at a time) to both an issues list
6
+ * and an `instanceId → elements` map, in a single pass.
7
+ */
8
+ export declare const mapAxeResults: (results: axe.Result[], type: "Warning" | "Alert") => {
9
+ issues: A11yIssue[];
10
+ elementMap: Map<string, Element[]>;
11
+ };
12
+ export declare const getIssueMessage: (nodes: axe.NodeResult[]) => string;
13
+ export declare const convertAxeImpactToIssueImpact: (impact?: axe.ImpactValue) => IssueImpact;
@@ -0,0 +1,22 @@
1
+ import * as React from "react";
2
+ type Props = {
3
+ targets: ReadonlyArray<Element>;
4
+ container: HTMLElement | null;
5
+ };
6
+ type Rect = Pick<DOMRect, "top" | "left" | "width" | "height">;
7
+ /**
8
+ * Computes an overlay rect placed over a target, relative to its container.
9
+ */
10
+ export declare function getOverlayRect(targetRect: Rect, containerRect: Pick<DOMRect, "top" | "left">): Rect;
11
+ /**
12
+ * Renders outline overlays over the given target elements.
13
+ *
14
+ * Requirements on `container`:
15
+ * - Must be `position: relative` (or otherwise positioned) — overlays are
16
+ * `position: absolute` and measured against its box.
17
+ * - Must be the actual DOM ancestor that scrolls `targets` (not just any
18
+ * positioned ancestor) — that's what lets the overlays scroll natively
19
+ * with the content, with no scroll listener needed.
20
+ */
21
+ export declare function A11yOverlays({ targets, container }: Props): React.JSX.Element | null;
22
+ export {};
@@ -3,6 +3,7 @@
3
3
  * the preview iframe.
4
4
  */
5
5
  import type { SerializableApiOptions } from "./sanitize-api-options";
6
+ import type { A11yIssue } from "../components/issues-panel";
6
7
  import type { Hint, PerseusItem, PerseusRenderer } from "@khanacademy/perseus-core";
7
8
  /**
8
9
  * The subset of `LinterContextProps` that's meaningful to send across the
@@ -20,9 +21,21 @@ export declare const PREVIEW_MESSAGE_SOURCE: "perseus-preview";
20
21
  /**
21
22
  * Base type for all preview messages
22
23
  */
23
- interface PreviewMessageBase {
24
+ export interface PreviewMessageBase {
24
25
  source: typeof PREVIEW_MESSAGE_SOURCE;
25
26
  }
27
+ /**
28
+ * Base type for messages tied to a specific version of the preview content.
29
+ *
30
+ * `contentVersion` is a monotonic counter owned by the parent controller,
31
+ * stamped onto every content update and echoed back on the scan report and
32
+ * highlight commands it produces. It lets both sides discard results computed
33
+ * against content that has since been superseded by a newer edit — see the
34
+ * gating in `use-preview-controller.ts` / `use-preview-presenter.ts`.
35
+ */
36
+ interface PreviewMessageVersioned extends PreviewMessageBase {
37
+ contentVersion: number;
38
+ }
26
39
  /**
27
40
  * Data for the read-only question preview shown while editing an exercise.
28
41
  *
@@ -101,14 +114,54 @@ export type PreviewContent = {
101
114
  /**
102
115
  * Message from parent sending content data to iframe
103
116
  */
104
- interface PreviewDataMessage extends PreviewMessageBase {
117
+ interface PreviewDataMessage extends PreviewMessageVersioned {
105
118
  type: "content-data";
106
119
  content: PreviewContent;
107
120
  }
121
+ /**
122
+ * Reply from parent to the iframe's `iframe-ready` handshake, carrying the
123
+ * full current preview state in one message. Sent once per `iframe-ready`
124
+ * (including a genuine reload, which re-announces readiness) — this way a
125
+ * freshly (re)loaded iframe never has to rely on messages sent before it was
126
+ * listening.
127
+ */
128
+ interface PreviewIframeInitMessage extends PreviewMessageVersioned {
129
+ type: "iframe-init";
130
+ content: PreviewContent | null;
131
+ a11yScanningEnabled: boolean;
132
+ }
133
+ export declare function createPreviewIframeInitMessage(content: PreviewContent | null, a11yScanningEnabled: boolean, contentVersion: number): PreviewIframeInitMessage;
134
+ /**
135
+ * Command from parent telling the iframe to enable or disable axe-core
136
+ * accessibility scanning. When enabled, the iframe runs scans and reports back;
137
+ * when disabled, it neither imports nor runs axe-core.
138
+ */
139
+ interface PreviewSetA11yScanningEnabledMessage extends PreviewMessageBase {
140
+ type: "set-a11y-scanning-enabled";
141
+ enabled: boolean;
142
+ }
143
+ export declare function createPreviewSetA11yScanningEnabledMessage(enabled: boolean): PreviewSetA11yScanningEnabledMessage;
144
+ /**
145
+ * Command from parent telling the iframe to highlight the elements for the
146
+ * given instanceIds (the "Show Me" overlays drawn inside the iframe).
147
+ */
148
+ interface PreviewHighlightIssuesMessage extends PreviewMessageVersioned {
149
+ type: "highlight-issues";
150
+ instanceIds: string[];
151
+ }
152
+ export declare function createPreviewHighlightIssuesMessage(instanceIds: string[], contentVersion: number): PreviewHighlightIssuesMessage;
153
+ /**
154
+ * Command from parent telling the iframe to remove any "Show Me" highlight
155
+ * overlays it is currently drawing.
156
+ */
157
+ interface PreviewClearHighlightsMessage extends PreviewMessageBase {
158
+ type: "clear-highlights";
159
+ }
160
+ export declare function createPreviewClearHighlightsMessage(): PreviewClearHighlightsMessage;
108
161
  /**
109
162
  * Union of all messages sent from parent to iframe
110
163
  */
111
- export type ParentToIframeMessage = PreviewDataMessage;
164
+ export type ParentToIframeMessage = PreviewDataMessage | PreviewIframeInitMessage | PreviewSetA11yScanningEnabledMessage | PreviewHighlightIssuesMessage | PreviewClearHighlightsMessage;
112
165
  /**
113
166
  * Message from iframe to parent telling it the iframe is ready
114
167
  */
@@ -122,9 +175,27 @@ interface PreviewHeightUpdateMessage extends PreviewMessageBase {
122
175
  type: "height-update";
123
176
  height: number;
124
177
  }
178
+ /**
179
+ * Message from iframe reporting axe-core accessibility scan results back to the
180
+ * parent.
181
+ */
182
+ interface PreviewA11yReportMessage extends PreviewMessageVersioned {
183
+ type: "a11y-report";
184
+ /** Violations are issues that are confirmed by the a11y scanner. **/
185
+ violations: A11yIssue[];
186
+ /**
187
+ * NeedsReview are issues that the scanner cannot definitively say is a
188
+ * violation or not. Requires manual review.
189
+ */
190
+ needsReview: A11yIssue[];
191
+ }
125
192
  /**
126
193
  * Union of all messages sent from iframe to parent
127
194
  */
128
- export type IframeToParentMessage = PreviewIframeReadyMessage | PreviewHeightUpdateMessage;
195
+ export type IframeToParentMessage = PreviewIframeReadyMessage | PreviewHeightUpdateMessage | PreviewA11yReportMessage;
129
196
  export declare function createPreviewIframeReadyMessage(): PreviewIframeReadyMessage;
197
+ /**
198
+ * @public just to appease knip until the next PR.
199
+ */
200
+ export declare function createPreviewA11yReportMessage(violations: A11yIssue[], needsReview: A11yIssue[], contentVersion: number): PreviewA11yReportMessage;
130
201
  export {};
@@ -1,5 +1,10 @@
1
1
  import * as React from "react";
2
2
  import type { PreviewContent } from "./message-types";
3
+ import type { A11yIssue } from "../components/issues-panel";
4
+ export type A11yReport = {
5
+ violations: A11yIssue[];
6
+ needsReview: A11yIssue[];
7
+ };
3
8
  type UsePreviewControllerResult = {
4
9
  /**
5
10
  * Send preview content data to the iframe
@@ -9,6 +14,22 @@ type UsePreviewControllerResult = {
9
14
  * Current height of the iframe content (null if not yet reported)
10
15
  */
11
16
  height: number | null;
17
+ /**
18
+ * Enable or disable axe-core accessibility scanning in the iframe
19
+ */
20
+ setA11yScanningEnabled: (enabled: boolean) => void;
21
+ /**
22
+ * Highlight the elements for the given instanceIds in the iframe
23
+ */
24
+ highlightIssues: (instanceIds: string[]) => void;
25
+ /**
26
+ * Clear any highlighted elements currently shown in the iframe
27
+ */
28
+ clearHighlights: () => void;
29
+ /**
30
+ * The latest accessibility report received from the iframe (null if none)
31
+ */
32
+ a11yReport: A11yReport | null;
12
33
  };
13
34
  /**
14
35
  * Hook for parent/editor to send data to preview iframe and receive updates.
@@ -1,4 +1,12 @@
1
+ import * as React from "react";
1
2
  import type { PreviewContent } from "./message-types";
3
+ type UsePreviewPresenterOptions = {
4
+ /**
5
+ * Ref to the element containing the rendered preview content. Used as
6
+ * the root for axe-core accessibility scans.
7
+ */
8
+ contentContainerRef?: React.RefObject<HTMLElement | null>;
9
+ };
2
10
  type UsePreviewPresenterResult = {
3
11
  /**
4
12
  * The preview content received from the parent, or null if not yet loaded
@@ -16,6 +24,16 @@ type UsePreviewPresenterResult = {
16
24
  * Function to report the current height of the iframe content to the parent
17
25
  */
18
26
  reportHeight: (height: number) => void;
27
+ /**
28
+ * Whether axe-core accessibility scanning is enabled
29
+ */
30
+ a11yScanningEnabled: boolean;
31
+ /**
32
+ * Elements to draw "Show Me" highlight overlays over, resolved from the
33
+ * latest scan's element map via the instanceIds in a highlight-issues
34
+ * message.
35
+ */
36
+ highlightTargets: Element[];
19
37
  };
20
38
  /**
21
39
  * Hook for preview iframe to receive data from parent and send updates back.
@@ -46,5 +64,5 @@ type UsePreviewPresenterResult = {
46
64
  * }
47
65
  * ```
48
66
  */
49
- export declare function usePreviewPresenter(): UsePreviewPresenterResult;
67
+ export declare function usePreviewPresenter(options?: UsePreviewPresenterOptions): UsePreviewPresenterResult;
50
68
  export {};
@@ -1,5 +1,6 @@
1
1
  import * as React from "react";
2
2
  import type { PreviewContent } from "./preview/message-types";
3
+ import type { A11yReport } from "./preview/use-preview-controller";
3
4
  type Props = {
4
5
  /**
5
6
  * The URL that the iframe should load
@@ -19,6 +20,20 @@ type Props = {
19
20
  * been provided yet and the iframe should render an empty placeholder.
20
21
  */
21
22
  content: PreviewContent | null;
23
+ /**
24
+ * Whether the iframe should run axe-core accessibility scans.
25
+ */
26
+ a11yScanningEnabled?: boolean;
27
+ /**
28
+ * instanceIds of the issues to draw "Show Me" highlight overlays over in
29
+ * the iframe. Empty clears any highlights.
30
+ */
31
+ highlightInstanceIds?: string[];
32
+ /**
33
+ * Called whenever the iframe reports a new accessibility scan result (or
34
+ * `null` if scanning is disabled).
35
+ */
36
+ onA11yReport?: (report: A11yReport | null) => void;
22
37
  };
23
38
  /**
24
39
  * Displays content in an iframe, isolating it from the parent page and
@@ -0,0 +1,14 @@
1
+ import type { APIOptions, APIOptionsWithDefaults } from "@khanacademy/perseus";
2
+ export type DeviceApiOptionsInputs = {
3
+ apiOptions: APIOptions | undefined;
4
+ touch: boolean;
5
+ };
6
+ /**
7
+ * Returns a memoized deriver for the preview's device-adjusted apiOptions.
8
+ * It returns the same object reference across calls while neither `apiOptions`
9
+ * (by reference) nor `touch` (by value) changes, so EditorPage's per-render
10
+ * rebuild doesn't hand a fresh object to <ItemEditor>'s content memo — which
11
+ * would defeat it and, with axe-core scanning on, loop scan -> report ->
12
+ * re-render -> resend. (This is the class-component stand-in for `useMemo`.)
13
+ */
14
+ export declare function createDeviceApiOptionsDeriver(): (inputs: DeviceApiOptionsInputs) => APIOptionsWithDefaults;
@@ -0,0 +1,23 @@
1
+ import type { PreviewContent } from "../preview/message-types";
2
+ import type { APIOptions, DeviceType } from "@khanacademy/perseus";
3
+ import type { PerseusRenderer } from "@khanacademy/perseus-core";
4
+ type QuestionPreview = Extract<PreviewContent, {
5
+ type: "question";
6
+ }>;
7
+ export type DerivePreviewContentInputs = {
8
+ question: PerseusRenderer | undefined;
9
+ apiOptions: APIOptions | undefined;
10
+ deviceType: DeviceType;
11
+ highlightLint: boolean;
12
+ problemNum: number | undefined;
13
+ legacyPerseusLint: ReadonlyArray<string>;
14
+ };
15
+ /**
16
+ * Returns a `derivePreviewContent` function that returns the same object
17
+ * reference across calls when none of its inputs have actually changed.
18
+ * `legacyPerseusLint` is rebuilt as a fresh array by the underlying editor on
19
+ * every call, so it's compared by value rather than by reference — otherwise
20
+ * every call would look "changed" and defeat the memoization.
21
+ */
22
+ export declare function createPreviewContentDeriver(): (inputs: DerivePreviewContentInputs) => QuestionPreview | null;
23
+ export {};
@@ -1,8 +1,8 @@
1
1
  import * as React from "react";
2
- import type { Changeable } from "@khanacademy/perseus";
3
2
  type Props = {
4
3
  value?: string;
5
- } & Changeable.ChangeableProps;
4
+ onChange: (value: string) => void;
5
+ };
6
6
  declare class ArrowPicker extends React.Component<Props> {
7
7
  static defaultProps: {
8
8
  value: string;
@@ -1,9 +1,9 @@
1
1
  import * as React from "react";
2
- import type { Changeable } from "@khanacademy/perseus";
3
2
  type Props = {
4
3
  lightColors?: boolean;
5
4
  value?: string;
6
- } & Changeable.ChangeableProps;
5
+ onChange: (value: string) => void;
6
+ };
7
7
  declare class ColorPicker extends React.Component<Props> {
8
8
  static defaultProps: {
9
9
  lightColors: boolean;
@@ -1,8 +1,8 @@
1
1
  import * as React from "react";
2
- import type { Changeable } from "@khanacademy/perseus";
3
2
  type Props = {
4
3
  value?: string;
5
- } & Changeable.ChangeableProps;
4
+ onChange: (value: string) => void;
5
+ };
6
6
  declare class DashPicker extends React.Component<Props> {
7
7
  static defaultProps: {
8
8
  value: string;
@@ -2,9 +2,9 @@ import * as React from "react";
2
2
  type Props = {
3
3
  children: React.ReactElement<any> | ReadonlyArray<React.ReactElement<any>>;
4
4
  initiallyVisible: boolean;
5
- onDelete?: () => void | null | undefined;
6
- onDown?: () => void | null | undefined;
7
- onUp?: () => void | null | undefined;
5
+ onDelete?: (() => void) | null;
6
+ onDown?: (() => void) | null;
7
+ onUp?: (() => void) | null;
8
8
  title: string | React.ReactElement<any>;
9
9
  };
10
10
  type State = {
@@ -19,7 +19,6 @@ type DefaultProps = {
19
19
  declare class FunctionEditor extends React.Component<Props> {
20
20
  static defaultProps: DefaultProps;
21
21
  change: (arg1: any, arg2?: any, arg3?: any) => any;
22
- serialize: () => any;
23
22
  render(): React.ReactNode;
24
23
  }
25
24
  export default FunctionEditor;
@@ -15,7 +15,6 @@ type DefaultProps = {
15
15
  declare class LabelEditor extends React.Component<Props> {
16
16
  static defaultProps: DefaultProps;
17
17
  change: (arg1: any, arg2?: any, arg3?: any) => any;
18
- serialize: () => any;
19
18
  render(): React.ReactNode;
20
19
  }
21
20
  export default LabelEditor;
@@ -23,7 +23,6 @@ type DefaultProps = {
23
23
  declare class LineEditor extends React.Component<Props> {
24
24
  static defaultProps: DefaultProps;
25
25
  change: (arg1: any, arg2?: any, arg3?: any) => any;
26
- serialize: () => any;
27
26
  render(): React.ReactNode;
28
27
  }
29
28
  export default LineEditor;
@@ -24,7 +24,6 @@ type DefaultProps = {
24
24
  declare class MovableLineEditor extends React.Component<Props> {
25
25
  static defaultProps: DefaultProps;
26
26
  change: ChangeFn;
27
- serialize: () => any;
28
27
  render(): React.ReactNode;
29
28
  }
30
29
  export default MovableLineEditor;
@@ -19,7 +19,6 @@ type DefaultProps = {
19
19
  declare class MovablePointEditor extends React.Component<Props> {
20
20
  static defaultProps: DefaultProps;
21
21
  change: ChangeFn;
22
- serialize: () => any;
23
22
  render(): React.ReactNode;
24
23
  }
25
24
  export default MovablePointEditor;
@@ -21,7 +21,6 @@ type DefaultProps = {
21
21
  declare class ParametricEditor extends React.Component<Props> {
22
22
  static defaultProps: DefaultProps;
23
23
  change: (arg1: any, arg2?: any, arg3?: any) => any;
24
- serialize: () => any;
25
24
  render(): React.ReactNode;
26
25
  }
27
26
  export default ParametricEditor;
@@ -13,7 +13,6 @@ type DefaultProps = {
13
13
  declare class PointEditor extends React.Component<Props> {
14
14
  static defaultProps: DefaultProps;
15
15
  change: (arg1: any, arg2?: any, arg3?: any) => any;
16
- serialize: () => any;
17
16
  render(): React.ReactNode;
18
17
  }
19
18
  export default PointEditor;
@@ -17,7 +17,6 @@ type DefaultProps = {
17
17
  declare class RectangleEditor extends React.Component<Props> {
18
18
  static defaultProps: DefaultProps;
19
19
  change: (arg1: any, arg2?: any, arg3?: any) => any;
20
- serialize: () => any;
21
20
  render(): React.ReactNode;
22
21
  }
23
22
  export default RectangleEditor;
@@ -13,20 +13,20 @@ declare const InteractiveGraph: {
13
13
  step: [number, number];
14
14
  gridStep?: [x: number, y: number];
15
15
  snapStep?: [x: number, y: number];
16
- backgroundImage?: PerseusImageBackground;
17
- markings: MarkingsType;
16
+ backgroundImage: import("@khanacademy/perseus-core").PerseusImageBackground;
17
+ markings: import("@khanacademy/perseus-core").MarkingsType;
18
18
  labels: string[];
19
- labelLocation: AxisLabelLocation;
19
+ labelLocation: import("@khanacademy/perseus-core").AxisLabelLocation;
20
+ showAxisArrows: import("@khanacademy/perseus-core").ShowAxisArrows;
21
+ showAxisTicks: import("@khanacademy/perseus-core").ShowAxisTicks;
20
22
  showProtractor: boolean;
21
23
  showRuler?: boolean;
22
- showTooltips?: boolean;
24
+ showTooltips: boolean;
23
25
  rulerLabel?: string;
24
26
  rulerTicks?: number;
25
27
  range: import("@khanacademy/perseus-core").GraphRange;
26
- showAxisArrows: ShowAxisArrows;
27
- showAxisTicks: ShowAxisTicks;
28
- correct?: PerseusGraphType;
29
- lockedFigures: LockedFigure[];
28
+ correct: PerseusGraphType;
29
+ lockedFigures: import("@khanacademy/perseus-core").LockedFigure[];
30
30
  fullGraphAriaLabel?: string;
31
31
  fullGraphAriaDescription?: string;
32
32
  trackInteraction: (extraData?: Empty | undefined) => void;
@@ -309,25 +309,25 @@ declare const InteractiveGraph: {
309
309
  containerSizeClass: import("../../../../perseus/src/util/sizing-utils").SizeClass;
310
310
  };
311
311
  render(): React.JSX.Element;
312
- setState<K extends string | number | symbol>(state: any, callback?: (() => void) | undefined): void;
312
+ setState<K extends never>(state: {} | ((prevState: Readonly<{}>, props: Readonly<import("../../../../perseus/src/widgets/interactive-graphs/interactive-graph").Props>) => {} | Pick<{}, K> | null) | Pick<{}, K> | null, callback?: (() => void) | undefined): void;
313
313
  forceUpdate(callback?: (() => void) | undefined): void;
314
314
  readonly props: Readonly<import("../../../../perseus/src/widgets/interactive-graphs/interactive-graph").Props>;
315
- state: Readonly<any>;
315
+ state: Readonly<{}>;
316
316
  refs: {
317
317
  [key: string]: React.ReactInstance;
318
318
  };
319
319
  componentDidMount?(): void;
320
- shouldComponentUpdate?(nextProps: Readonly<import("../../../../perseus/src/widgets/interactive-graphs/interactive-graph").Props>, nextState: Readonly<any>, nextContext: any): boolean;
320
+ shouldComponentUpdate?(nextProps: Readonly<import("../../../../perseus/src/widgets/interactive-graphs/interactive-graph").Props>, nextState: Readonly<{}>, nextContext: any): boolean;
321
321
  componentWillUnmount?(): void;
322
322
  componentDidCatch?(error: Error, errorInfo: React.ErrorInfo): void;
323
- getSnapshotBeforeUpdate?(prevProps: Readonly<import("../../../../perseus/src/widgets/interactive-graphs/interactive-graph").Props>, prevState: Readonly<any>): any;
324
- componentDidUpdate?(prevProps: Readonly<import("../../../../perseus/src/widgets/interactive-graphs/interactive-graph").Props>, prevState: Readonly<any>, snapshot?: any): void;
323
+ getSnapshotBeforeUpdate?(prevProps: Readonly<import("../../../../perseus/src/widgets/interactive-graphs/interactive-graph").Props>, prevState: Readonly<{}>): any;
324
+ componentDidUpdate?(prevProps: Readonly<import("../../../../perseus/src/widgets/interactive-graphs/interactive-graph").Props>, prevState: Readonly<{}>, snapshot?: any): void;
325
325
  componentWillMount?(): void;
326
326
  UNSAFE_componentWillMount?(): void;
327
327
  componentWillReceiveProps?(nextProps: Readonly<import("../../../../perseus/src/widgets/interactive-graphs/interactive-graph").Props>, nextContext: any): void;
328
328
  UNSAFE_componentWillReceiveProps?(nextProps: Readonly<import("../../../../perseus/src/widgets/interactive-graphs/interactive-graph").Props>, nextContext: any): void;
329
- componentWillUpdate?(nextProps: Readonly<import("../../../../perseus/src/widgets/interactive-graphs/interactive-graph").Props>, nextState: Readonly<any>, nextContext: any): void;
330
- UNSAFE_componentWillUpdate?(nextProps: Readonly<import("../../../../perseus/src/widgets/interactive-graphs/interactive-graph").Props>, nextState: Readonly<any>, nextContext: any): void;
329
+ componentWillUpdate?(nextProps: Readonly<import("../../../../perseus/src/widgets/interactive-graphs/interactive-graph").Props>, nextState: Readonly<{}>, nextContext: any): void;
330
+ UNSAFE_componentWillUpdate?(nextProps: Readonly<import("../../../../perseus/src/widgets/interactive-graphs/interactive-graph").Props>, nextState: Readonly<{}>, nextContext: any): void;
331
331
  };
332
332
  new (props: import("../../../../perseus/src/widgets/interactive-graphs/interactive-graph").Props, context: any): {
333
333
  context: React.ContextType<typeof import("@khanacademy/perseus").PerseusI18nContext>;
@@ -339,20 +339,20 @@ declare const InteractiveGraph: {
339
339
  step: [number, number];
340
340
  gridStep?: [x: number, y: number];
341
341
  snapStep?: [x: number, y: number];
342
- backgroundImage?: PerseusImageBackground;
343
- markings: MarkingsType;
342
+ backgroundImage: import("@khanacademy/perseus-core").PerseusImageBackground;
343
+ markings: import("@khanacademy/perseus-core").MarkingsType;
344
344
  labels: string[];
345
- labelLocation: AxisLabelLocation;
345
+ labelLocation: import("@khanacademy/perseus-core").AxisLabelLocation;
346
+ showAxisArrows: import("@khanacademy/perseus-core").ShowAxisArrows;
347
+ showAxisTicks: import("@khanacademy/perseus-core").ShowAxisTicks;
346
348
  showProtractor: boolean;
347
349
  showRuler?: boolean;
348
- showTooltips?: boolean;
350
+ showTooltips: boolean;
349
351
  rulerLabel?: string;
350
352
  rulerTicks?: number;
351
353
  range: import("@khanacademy/perseus-core").GraphRange;
352
- showAxisArrows: ShowAxisArrows;
353
- showAxisTicks: ShowAxisTicks;
354
- correct?: PerseusGraphType;
355
- lockedFigures: LockedFigure[];
354
+ correct: PerseusGraphType;
355
+ lockedFigures: import("@khanacademy/perseus-core").LockedFigure[];
356
356
  fullGraphAriaLabel?: string;
357
357
  fullGraphAriaDescription?: string;
358
358
  trackInteraction: (extraData?: Empty | undefined) => void;
@@ -635,40 +635,27 @@ declare const InteractiveGraph: {
635
635
  containerSizeClass: import("../../../../perseus/src/util/sizing-utils").SizeClass;
636
636
  };
637
637
  render(): React.JSX.Element;
638
- setState<K extends string | number | symbol>(state: any, callback?: (() => void) | undefined): void;
638
+ setState<K extends never>(state: {} | ((prevState: Readonly<{}>, props: Readonly<import("../../../../perseus/src/widgets/interactive-graphs/interactive-graph").Props>) => {} | Pick<{}, K> | null) | Pick<{}, K> | null, callback?: (() => void) | undefined): void;
639
639
  forceUpdate(callback?: (() => void) | undefined): void;
640
640
  readonly props: Readonly<import("../../../../perseus/src/widgets/interactive-graphs/interactive-graph").Props>;
641
- state: Readonly<any>;
641
+ state: Readonly<{}>;
642
642
  refs: {
643
643
  [key: string]: React.ReactInstance;
644
644
  };
645
645
  componentDidMount?(): void;
646
- shouldComponentUpdate?(nextProps: Readonly<import("../../../../perseus/src/widgets/interactive-graphs/interactive-graph").Props>, nextState: Readonly<any>, nextContext: any): boolean;
646
+ shouldComponentUpdate?(nextProps: Readonly<import("../../../../perseus/src/widgets/interactive-graphs/interactive-graph").Props>, nextState: Readonly<{}>, nextContext: any): boolean;
647
647
  componentWillUnmount?(): void;
648
648
  componentDidCatch?(error: Error, errorInfo: React.ErrorInfo): void;
649
- getSnapshotBeforeUpdate?(prevProps: Readonly<import("../../../../perseus/src/widgets/interactive-graphs/interactive-graph").Props>, prevState: Readonly<any>): any;
650
- componentDidUpdate?(prevProps: Readonly<import("../../../../perseus/src/widgets/interactive-graphs/interactive-graph").Props>, prevState: Readonly<any>, snapshot?: any): void;
649
+ getSnapshotBeforeUpdate?(prevProps: Readonly<import("../../../../perseus/src/widgets/interactive-graphs/interactive-graph").Props>, prevState: Readonly<{}>): any;
650
+ componentDidUpdate?(prevProps: Readonly<import("../../../../perseus/src/widgets/interactive-graphs/interactive-graph").Props>, prevState: Readonly<{}>, snapshot?: any): void;
651
651
  componentWillMount?(): void;
652
652
  UNSAFE_componentWillMount?(): void;
653
653
  componentWillReceiveProps?(nextProps: Readonly<import("../../../../perseus/src/widgets/interactive-graphs/interactive-graph").Props>, nextContext: any): void;
654
654
  UNSAFE_componentWillReceiveProps?(nextProps: Readonly<import("../../../../perseus/src/widgets/interactive-graphs/interactive-graph").Props>, nextContext: any): void;
655
- componentWillUpdate?(nextProps: Readonly<import("../../../../perseus/src/widgets/interactive-graphs/interactive-graph").Props>, nextState: Readonly<any>, nextContext: any): void;
656
- UNSAFE_componentWillUpdate?(nextProps: Readonly<import("../../../../perseus/src/widgets/interactive-graphs/interactive-graph").Props>, nextState: Readonly<any>, nextContext: any): void;
655
+ componentWillUpdate?(nextProps: Readonly<import("../../../../perseus/src/widgets/interactive-graphs/interactive-graph").Props>, nextState: Readonly<{}>, nextContext: any): void;
656
+ UNSAFE_componentWillUpdate?(nextProps: Readonly<import("../../../../perseus/src/widgets/interactive-graphs/interactive-graph").Props>, nextState: Readonly<{}>, nextContext: any): void;
657
657
  };
658
658
  contextType: React.Context<import("../../../../perseus/src/components/i18n-context").I18nContextType>;
659
- defaultProps: {
660
- labels: string[];
661
- labelLocation: import("../../../../perseus/src/widgets/interactive-graphs/interactive-graph").Props["labelLocation"];
662
- range: import("../../../../perseus/src/widgets/interactive-graphs/interactive-graph").Props["range"];
663
- showAxisArrows: import("../../../../perseus/src/widgets/interactive-graphs/interactive-graph").Props["showAxisArrows"];
664
- showAxisTicks: import("../../../../perseus/src/widgets/interactive-graphs/interactive-graph").Props["showAxisTicks"];
665
- step: import("../../../../perseus/src/widgets/interactive-graphs/interactive-graph").Props["step"];
666
- backgroundImage: import("../../../../perseus/src/widgets/interactive-graphs/interactive-graph").Props["backgroundImage"];
667
- markings: import("../../../../perseus/src/widgets/interactive-graphs/interactive-graph").Props["markings"];
668
- showTooltips: import("../../../../perseus/src/widgets/interactive-graphs/interactive-graph").Props["showTooltips"];
669
- showProtractor: import("../../../../perseus/src/widgets/interactive-graphs/interactive-graph").Props["showProtractor"];
670
- userInput: import("../../../../perseus/src/widgets/interactive-graphs/interactive-graph").Props["userInput"];
671
- };
672
659
  getEquationString(props: import("../../../../perseus/src/widgets/interactive-graphs/interactive-graph").Props): string;
673
660
  };
674
661
  type InteractiveGraphProps = PropsFor<typeof InteractiveGraph>;
@@ -1,3 +1,10 @@
1
+ /**
2
+ * LockedLabelSettings is a component that allows the user to edit the
3
+ * settings of specifically a locked label on the graph within the
4
+ * Interactive Graph widget.
5
+ *
6
+ * Used in the interactive graph editor's locked figures section.
7
+ */
1
8
  import { type LockedLabelType } from "@khanacademy/perseus-core";
2
9
  import * as React from "react";
3
10
  import type { LockedFigureSettingsMovementType } from "./locked-figure-settings-actions";