@khanacademy/perseus 77.3.1 → 77.3.2

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.
@@ -10,6 +10,14 @@ export declare const getLabelTransform: (labelLocation: GraphConfig["labelLocati
10
10
  yLabelTransform: string;
11
11
  };
12
12
  export declare const getLabelPosition: (graphInfo: GraphDimensions, labelLocation: GraphConfig["labelLocation"], tickStep: GraphConfig["tickStep"]) => vec.Vector2[];
13
+ /**
14
+ * Calculate the bottom margin needed for the graph container to prevent the
15
+ * x-axis label from overlapping with content below the graph.
16
+ *
17
+ * When the y-range starts at or above 0, the x-axis label can extend below
18
+ * the graph content area. This function calculates the extra margin needed.
19
+ */
20
+ export declare const getGraphBottomMargin: (xAxisLabelLocationY: number, graphHeight: number, hasXAxisLabel: boolean, showsAxisLabels: boolean) => number;
13
21
  export declare const shouldShowLabel: (currentTick: number, range: [Interval, Interval], tickStep: number) => boolean;
14
22
  export declare function generateTickLocations(tickStep: number, min: number, max: number, otherAxisMin: number): number[];
15
23
  export declare const countSignificantDecimals: (number: number) => number;
@@ -3,7 +3,6 @@ import type { ExponentialGraphState, Dispatch, InteractiveGraphElementSuite } fr
3
3
  import type { Coord } from "@khanacademy/perseus-core";
4
4
  import type { Interval, vec } from "mafs";
5
5
  export declare function renderExponentialGraph(state: ExponentialGraphState, dispatch: Dispatch, i18n: I18nContextType): InteractiveGraphElementSuite;
6
- export declare const constrainAsymptoteKeyboard: (p: vec.Vector2, coords: ReadonlyArray<Coord>, snapStep: vec.Vector2) => vec.Vector2;
7
6
  export declare const getExponentialKeyboardConstraint: (coords: ReadonlyArray<Coord>, asymptote: number, snapStep: vec.Vector2, pointIndex: number, range: [Interval, Interval]) => {
8
7
  up: vec.Vector2;
9
8
  down: vec.Vector2;
@@ -3,7 +3,6 @@ import type { LogarithmGraphState, Dispatch, InteractiveGraphElementSuite } from
3
3
  import type { Coord } from "@khanacademy/perseus-core";
4
4
  import type { Interval, vec } from "mafs";
5
5
  export declare function renderLogarithmGraph(state: LogarithmGraphState, dispatch: Dispatch, i18n: I18nContextType): InteractiveGraphElementSuite;
6
- export declare const constrainAsymptoteKeyboard: (p: vec.Vector2, coords: ReadonlyArray<Coord>, snapStep: vec.Vector2) => vec.Vector2;
7
6
  export declare const getLogarithmKeyboardConstraint: (coords: ReadonlyArray<Coord>, asymptote: number, snapStep: vec.Vector2, pointIndex: number, range: [Interval, Interval]) => {
8
7
  up: vec.Vector2;
9
8
  down: vec.Vector2;
@@ -53,11 +53,19 @@ export declare function getAsymptoteGraphKeyboardConstraint(coords: ReadonlyArra
53
53
  right: vec.Vector2;
54
54
  };
55
55
  /**
56
- * Shared keyboard constraint for asymptote movement (exponential, logarithm).
57
- * When the next snapped position would land between or on the curve points,
58
- * snaps past all of them in the direction of travel using a midpoint heuristic.
59
- *
60
- * @param orientation - "horizontal" for exponential (asymptote moves on Y-axis),
61
- * "vertical" for logarithm (asymptote moves on X-axis).
56
+ * Position of the asymptote's drag handle in graph-space. For a horizontal
57
+ * asymptote (exponential), this sits at the midpoint of the x-range on
58
+ * the asymptote's y-value. For a vertical asymptote (logarithm), it sits
59
+ * on the asymptote's x-value at the midpoint of the y-range.
60
+ */
61
+ export declare function getAsymptoteHandleCoord(orientation: "horizontal" | "vertical", range: [Interval, Interval], asymptote: number): vec.Vector2;
62
+ /**
63
+ * Keyboard snap + skip for the asymptote drag handle. `useDraggable`'s
64
+ * function-form constraint expects the returned point to be snap-aligned;
65
+ * it searches along the direction of travel until the returned point is
66
+ * far enough from the current asymptote to register as a move. After
67
+ * snapping, if the proposed position would put the handle on one of the
68
+ * curve points, we step further in the direction of travel until we find
69
+ * a valid position (up to 3 attempts).
62
70
  */
63
- export declare function constrainAsymptoteKeyboardMovement(p: vec.Vector2, coords: ReadonlyArray<Coord>, snapStep: vec.Vector2, orientation: "horizontal" | "vertical"): vec.Vector2;
71
+ export declare function skipAsymptoteKeyboardOverPoint(proposed: vec.Vector2, currentAsymptote: number, coords: ReadonlyArray<Coord>, handleCoord: vec.Vector2, snapStep: vec.Vector2, orientation: "horizontal" | "vertical"): vec.Vector2;
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": "77.3.1",
6
+ "version": "77.3.2",
7
7
  "publishConfig": {
8
8
  "access": "public"
9
9
  },
@@ -43,12 +43,12 @@
43
43
  "tiny-invariant": "1.3.1",
44
44
  "uuid": "^10.0.0",
45
45
  "@khanacademy/kas": "2.2.2",
46
- "@khanacademy/keypad-context": "3.2.44",
47
- "@khanacademy/kmath": "2.4.2",
48
- "@khanacademy/math-input": "26.4.16",
49
- "@khanacademy/perseus-core": "25.0.0",
50
- "@khanacademy/perseus-linter": "4.9.5",
51
- "@khanacademy/perseus-score": "8.7.0",
46
+ "@khanacademy/keypad-context": "3.2.45",
47
+ "@khanacademy/kmath": "2.4.3",
48
+ "@khanacademy/math-input": "26.4.17",
49
+ "@khanacademy/perseus-core": "26.0.0",
50
+ "@khanacademy/perseus-linter": "5.0.0",
51
+ "@khanacademy/perseus-score": "8.7.1",
52
52
  "@khanacademy/perseus-utils": "2.1.5",
53
53
  "@khanacademy/pure-markdown": "2.2.7",
54
54
  "@khanacademy/simple-markdown": "2.2.2"
@@ -1,196 +0,0 @@
1
- import { vec } from "mafs";
2
- import type { SnapTo } from "./types";
3
- import type { Coord } from "../../interactive2/types";
4
- import type { AxisLabelLocation, CollinearTuple, LockedFigureColor, LockedFigureFillType, LockedLineStyle, MarkingsType, PerseusRenderer, StrokeWeight } from "@khanacademy/perseus-core";
5
- export type LockedFunctionOptions = {
6
- color?: LockedFigureColor;
7
- strokeStyle?: LockedLineStyle;
8
- weight?: StrokeWeight;
9
- directionalAxis?: "x" | "y";
10
- domain?: [min: number, max: number];
11
- labels?: LockedFigureLabelOptions[];
12
- ariaLabel?: string;
13
- };
14
- type LockedFigureLabelOptions = {
15
- text: string;
16
- coord?: Coord;
17
- size?: "small" | "medium" | "large";
18
- };
19
- export declare function interactiveGraphQuestionBuilder(): InteractiveGraphQuestionBuilder;
20
- declare class InteractiveGraphQuestionBuilder {
21
- private content;
22
- private fullGraphAriaLabel?;
23
- private fullGraphAriaDescription?;
24
- private backgroundImage?;
25
- private gridStep;
26
- private labels;
27
- private labelLocation;
28
- private markings;
29
- private xRange;
30
- private yRange;
31
- private showAxisArrows;
32
- private snapStep;
33
- private tickStep;
34
- private showProtractor;
35
- private showTooltips;
36
- private interactiveFigureConfig;
37
- private lockedFigures;
38
- private snapTo;
39
- private staticMode;
40
- build(): PerseusRenderer;
41
- withContent(content: string): InteractiveGraphQuestionBuilder;
42
- withFullGraphAriaLabel(label: string): InteractiveGraphQuestionBuilder;
43
- withFullGraphAriaDescription(description: string): InteractiveGraphQuestionBuilder;
44
- withTooltips(showTooltips: boolean): InteractiveGraphQuestionBuilder;
45
- withStaticMode(staticMode: boolean): InteractiveGraphQuestionBuilder;
46
- withBackgroundImage(url: string, height: number, width: number, options?: {
47
- scale?: number;
48
- bottom?: number;
49
- left?: number;
50
- right?: number;
51
- top?: number;
52
- }): InteractiveGraphQuestionBuilder;
53
- withGridStep(x: number, y: number): InteractiveGraphQuestionBuilder;
54
- withAxisLabels(x: string, y: string): InteractiveGraphQuestionBuilder;
55
- withLabelLocation(labelLocation: AxisLabelLocation): InteractiveGraphQuestionBuilder;
56
- withMarkings(markings: MarkingsType): InteractiveGraphQuestionBuilder;
57
- withXRange(min: number, max: number): InteractiveGraphQuestionBuilder;
58
- withYRange(min: number, max: number): InteractiveGraphQuestionBuilder;
59
- withShowAxisArrows({ xMin, xMax, yMin, yMax, }: {
60
- xMin?: boolean;
61
- xMax?: boolean;
62
- yMin?: boolean;
63
- yMax?: boolean;
64
- }): InteractiveGraphQuestionBuilder;
65
- withSnapStep(x: number, y: number): InteractiveGraphQuestionBuilder;
66
- withTickStep(x: number, y: number): InteractiveGraphQuestionBuilder;
67
- withProtractor(): InteractiveGraphQuestionBuilder;
68
- withSegments(options?: {
69
- numSegments?: number;
70
- startCoords?: CollinearTuple[];
71
- coords?: CollinearTuple[];
72
- }): InteractiveGraphQuestionBuilder;
73
- withNoInteractiveFigure(): this;
74
- withLinear(options?: {
75
- coords?: CollinearTuple;
76
- startCoords?: CollinearTuple;
77
- }): InteractiveGraphQuestionBuilder;
78
- withLinearSystem(options?: {
79
- coords?: CollinearTuple[];
80
- startCoords?: CollinearTuple[];
81
- }): InteractiveGraphQuestionBuilder;
82
- withRay(options?: {
83
- coords?: CollinearTuple;
84
- startCoords?: CollinearTuple;
85
- }): InteractiveGraphQuestionBuilder;
86
- withVector(options?: {
87
- coords?: CollinearTuple;
88
- startCoords?: CollinearTuple;
89
- }): InteractiveGraphQuestionBuilder;
90
- withCircle(options?: {
91
- center?: Coord;
92
- radius?: number;
93
- startCoords?: {
94
- center: Coord;
95
- radius: number;
96
- };
97
- }): InteractiveGraphQuestionBuilder;
98
- withQuadratic(options?: {
99
- coords?: [Coord, Coord, Coord];
100
- startCoords?: [Coord, Coord, Coord];
101
- }): InteractiveGraphQuestionBuilder;
102
- withSinusoid(options?: {
103
- coords?: [Coord, Coord];
104
- startCoords?: [Coord, Coord];
105
- }): InteractiveGraphQuestionBuilder;
106
- withExponential(options?: {
107
- coords?: [Coord, Coord];
108
- asymptote?: number;
109
- startCoords?: [Coord, Coord];
110
- startAsymptote?: number;
111
- }): InteractiveGraphQuestionBuilder;
112
- withTangent(options?: {
113
- coords?: [Coord, Coord];
114
- startCoords?: [Coord, Coord];
115
- }): InteractiveGraphQuestionBuilder;
116
- withPolygon(snapTo?: SnapTo, options?: {
117
- match?: "similar" | "congruent" | "approx";
118
- numSides?: number | "unlimited";
119
- showAngles?: boolean;
120
- showSides?: boolean;
121
- coords?: Coord[];
122
- startCoords?: Coord[];
123
- }): InteractiveGraphQuestionBuilder;
124
- withPoints(numPoints: number | "unlimited", options?: {
125
- coords?: Coord[];
126
- startCoords?: Coord[];
127
- }): InteractiveGraphQuestionBuilder;
128
- withAngle(options?: {
129
- coords?: [Coord, Coord, Coord];
130
- startCoords?: [Coord, Coord, Coord];
131
- showAngles?: boolean;
132
- allowReflexAngles?: boolean;
133
- angleOffsetDeg?: number;
134
- snapDegrees?: number;
135
- match?: "congruent";
136
- }): InteractiveGraphQuestionBuilder;
137
- withLogarithm(options?: {
138
- coords?: [Coord, Coord];
139
- asymptote?: number;
140
- startCoords?: [Coord, Coord];
141
- startAsymptote?: number;
142
- }): InteractiveGraphQuestionBuilder;
143
- withAbsoluteValue(options?: {
144
- coords?: [Coord, Coord];
145
- startCoords?: [Coord, Coord];
146
- }): InteractiveGraphQuestionBuilder;
147
- addLockedPointAt(x: number, y: number, options?: {
148
- color?: LockedFigureColor;
149
- filled?: boolean;
150
- labels?: LockedFigureLabelOptions[];
151
- ariaLabel?: string;
152
- }): InteractiveGraphQuestionBuilder;
153
- addLockedLine(point1: vec.Vector2, point2: vec.Vector2, options?: {
154
- kind?: "line" | "ray" | "segment";
155
- lineStyle?: LockedLineStyle;
156
- color?: LockedFigureColor;
157
- filled?: [boolean, boolean];
158
- showPoint1?: boolean;
159
- showPoint2?: boolean;
160
- weight?: StrokeWeight;
161
- labels?: LockedFigureLabelOptions[];
162
- ariaLabel?: string;
163
- }): InteractiveGraphQuestionBuilder;
164
- addLockedVector(tail: vec.Vector2, tip: vec.Vector2, options?: {
165
- color?: LockedFigureColor;
166
- labels?: LockedFigureLabelOptions[];
167
- weight?: StrokeWeight;
168
- ariaLabel?: string;
169
- }): InteractiveGraphQuestionBuilder;
170
- addLockedEllipse(center: vec.Vector2, radius: [x: number, y: number], options?: {
171
- angle?: number;
172
- color?: LockedFigureColor;
173
- fillStyle?: LockedFigureFillType;
174
- strokeStyle?: "solid" | "dashed";
175
- weight?: StrokeWeight;
176
- labels?: LockedFigureLabelOptions[];
177
- ariaLabel?: string;
178
- }): InteractiveGraphQuestionBuilder;
179
- addLockedPolygon(points: vec.Vector2[], options?: {
180
- color?: LockedFigureColor;
181
- showVertices?: boolean;
182
- fillStyle?: LockedFigureFillType;
183
- strokeStyle?: LockedLineStyle;
184
- weight?: StrokeWeight;
185
- labels?: LockedFigureLabelOptions[];
186
- ariaLabel?: string;
187
- }): InteractiveGraphQuestionBuilder;
188
- addLockedFunction(equation: string, options?: LockedFunctionOptions): this;
189
- addLockedLabel(text: string, coord: Coord, options?: {
190
- color?: LockedFigureColor;
191
- size?: "small" | "medium" | "large";
192
- }): this;
193
- private createLockedPoint;
194
- private addLockedFigure;
195
- }
196
- export {};