@khanacademy/perseus 22.0.1 → 22.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/components/info-tip/info-tip.d.ts +2 -10
- package/dist/components/math-input.d.ts +1 -0
- package/dist/es/index.css +14 -1
- package/dist/es/index.js +196 -160
- package/dist/es/index.js.map +1 -1
- package/dist/index.css +14 -1
- package/dist/index.js +190 -152
- package/dist/index.js.map +1 -1
- package/dist/widgets/interactive-graph.d.ts +3 -3
- package/dist/widgets/interactive-graphs/axis-labels.d.ts +2 -0
- package/dist/widgets/interactive-graphs/graphs/components/arrowhead.d.ts +2 -2
- package/dist/widgets/interactive-graphs/graphs/components/movable-line.d.ts +1 -0
- package/dist/widgets/interactive-graphs/graphs/use-transform.d.ts +9 -2
- package/dist/widgets/interactive-graphs/graphs/utils.d.ts +6 -4
- package/dist/widgets/interactive-graphs/mafs-graph.d.ts +1 -0
- package/dist/widgets/interactive-graphs/reducer/use-graph-config.d.ts +4 -0
- package/package.json +2 -2
package/dist/index.css
CHANGED
|
@@ -2470,7 +2470,10 @@ img.zoom-img {
|
|
|
2470
2470
|
padding-top: 5px;
|
|
2471
2471
|
}
|
|
2472
2472
|
.framework-perseus .svg-image {
|
|
2473
|
-
display:
|
|
2473
|
+
display: block;
|
|
2474
|
+
margin: 0 auto;
|
|
2475
|
+
margin-inline-start: auto;
|
|
2476
|
+
margin-inline-end: auto;
|
|
2474
2477
|
}
|
|
2475
2478
|
.framework-perseus .unresponsive-svg-image,
|
|
2476
2479
|
.framework-perseus .perseus-rendered-radio .unresponsive-svg-image {
|
|
@@ -2750,6 +2753,16 @@ body.mobile .categorizer-container td.category input[type="radio"] + span:active
|
|
|
2750
2753
|
.perseus-image-editor .graph-settings {
|
|
2751
2754
|
margin-top: 5px;
|
|
2752
2755
|
}
|
|
2756
|
+
.perseus-image-widget {
|
|
2757
|
+
margin-inline-start: auto;
|
|
2758
|
+
margin-inline-end: auto;
|
|
2759
|
+
}
|
|
2760
|
+
.perseus-hint-renderer .perseus-image-widget {
|
|
2761
|
+
margin-inline-start: 0;
|
|
2762
|
+
}
|
|
2763
|
+
.perseus-hint-renderer .svg-image {
|
|
2764
|
+
margin-inline-start: 0;
|
|
2765
|
+
}
|
|
2753
2766
|
.perseus-widget-interactive-graph {
|
|
2754
2767
|
box-sizing: content-box;
|
|
2755
2768
|
padding: 25px 25px 0 0;
|
package/dist/index.js
CHANGED
|
@@ -32,8 +32,8 @@ var caretUp = require('@phosphor-icons/core/assets/regular/caret-up.svg');
|
|
|
32
32
|
var debounce$1 = require('lodash.debounce');
|
|
33
33
|
var mafs = require('mafs');
|
|
34
34
|
var wonderBlocksIcon = require('@khanacademy/wonder-blocks-icon');
|
|
35
|
-
var questionIcon = require('@phosphor-icons/core/regular/question.svg');
|
|
36
35
|
var wonderBlocksTypography = require('@khanacademy/wonder-blocks-typography');
|
|
36
|
+
var questionIcon = require('@phosphor-icons/core/regular/question.svg');
|
|
37
37
|
var createReactClass = require('create-react-class');
|
|
38
38
|
var Switch = require('@khanacademy/wonder-blocks-switch');
|
|
39
39
|
var Pill = require('@khanacademy/wonder-blocks-pill');
|
|
@@ -649,6 +649,9 @@ class InnerMathInput extends React__namespace.Component {
|
|
|
649
649
|
class MathInput extends React__namespace.Component {
|
|
650
650
|
static contextType = mathInput.MathInputI18nContext;
|
|
651
651
|
inputRef = /*#__PURE__*/React__namespace.createRef();
|
|
652
|
+
blur() {
|
|
653
|
+
this.inputRef.current?.blur();
|
|
654
|
+
}
|
|
652
655
|
focus() {
|
|
653
656
|
this.inputRef.current?.focus();
|
|
654
657
|
}
|
|
@@ -2594,7 +2597,11 @@ class Expression extends React__namespace.Component {
|
|
|
2594
2597
|
blurInputPath = inputPath => {
|
|
2595
2598
|
// eslint-disable-next-line react/no-string-refs
|
|
2596
2599
|
// @ts-expect-error - TS2339 - Property 'blur' does not exist on type 'ReactInstance'.
|
|
2597
|
-
this.refs.input?.blur
|
|
2600
|
+
if (typeof this.refs.input?.blur === "function") {
|
|
2601
|
+
// eslint-disable-next-line react/no-string-refs
|
|
2602
|
+
// @ts-expect-error - TS2339 - Property 'blur' does not exist on type 'ReactInstance'.
|
|
2603
|
+
this.refs.input?.blur();
|
|
2604
|
+
}
|
|
2598
2605
|
};
|
|
2599
2606
|
|
|
2600
2607
|
// HACK(joel)
|
|
@@ -21944,10 +21951,14 @@ class SimpleKeypadInput extends React__namespace.Component {
|
|
|
21944
21951
|
}
|
|
21945
21952
|
|
|
21946
21953
|
blur() {
|
|
21954
|
+
// eslint-disable-next-line react/no-string-refs
|
|
21947
21955
|
// @ts-expect-error - TS2339 - Property 'blur' does not exist on type 'ReactInstance'.
|
|
21948
|
-
this.refs.input?.blur
|
|
21956
|
+
if (typeof this.refs.input?.blur === "function") {
|
|
21957
|
+
// eslint-disable-next-line react/no-string-refs
|
|
21958
|
+
// @ts-expect-error - TS2339 - Property 'blur' does not exist on type 'ReactInstance'.
|
|
21959
|
+
this.refs.input?.blur();
|
|
21960
|
+
}
|
|
21949
21961
|
}
|
|
21950
|
-
|
|
21951
21962
|
getValue() {
|
|
21952
21963
|
return this.props.value;
|
|
21953
21964
|
}
|
|
@@ -22152,7 +22163,11 @@ class InputNumber extends React__namespace.Component {
|
|
|
22152
22163
|
blurInputPath = inputPath => {
|
|
22153
22164
|
// eslint-disable-next-line react/no-string-refs
|
|
22154
22165
|
// @ts-expect-error - TS2339 - Property 'blur' does not exist on type 'ReactInstance'.
|
|
22155
|
-
this.refs.input?.blur
|
|
22166
|
+
if (typeof this.refs.input?.blur === "function") {
|
|
22167
|
+
// eslint-disable-next-line react/no-string-refs
|
|
22168
|
+
// @ts-expect-error - TS2339 - Property 'blur' does not exist on type 'ReactInstance'.
|
|
22169
|
+
this.refs.input?.blur();
|
|
22170
|
+
}
|
|
22156
22171
|
};
|
|
22157
22172
|
getInputPaths = () => {
|
|
22158
22173
|
// The widget itself is an input, so we return a single empty list to
|
|
@@ -28746,6 +28761,93 @@ class Graph extends React__namespace.Component {
|
|
|
28746
28761
|
}
|
|
28747
28762
|
}
|
|
28748
28763
|
|
|
28764
|
+
const defaultGraphConfig = {
|
|
28765
|
+
range: [[0, 1], [0, 1]],
|
|
28766
|
+
snapStep: [1, 1],
|
|
28767
|
+
markings: "none",
|
|
28768
|
+
showTooltips: false,
|
|
28769
|
+
graphDimensionsInPixels: [1, 1],
|
|
28770
|
+
width: 0,
|
|
28771
|
+
height: 0,
|
|
28772
|
+
labels: []
|
|
28773
|
+
};
|
|
28774
|
+
const GraphConfigContext = /*#__PURE__*/React.createContext(defaultGraphConfig);
|
|
28775
|
+
function useGraphConfig() {
|
|
28776
|
+
return React__default["default"].useContext(GraphConfigContext);
|
|
28777
|
+
}
|
|
28778
|
+
|
|
28779
|
+
const matrixBuilder = mafs.vec.matrixBuilder;
|
|
28780
|
+
// When converting vectors, we don't need to translate because a vector
|
|
28781
|
+
// is like a pair of x and y distances, which are not bound to specific graph locations.
|
|
28782
|
+
function vectorsToPixels(vectors, graphState) {
|
|
28783
|
+
let translation = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : [0, 0];
|
|
28784
|
+
const {
|
|
28785
|
+
range,
|
|
28786
|
+
width,
|
|
28787
|
+
height
|
|
28788
|
+
} = graphState;
|
|
28789
|
+
const [[xMin, xMax], [yMin, yMax]] = range;
|
|
28790
|
+
const transformToPx = matrixBuilder().translate(...translation).scale(width / (xMax - xMin), -height / (yMax - yMin)).get();
|
|
28791
|
+
return vectors.map(p => mafs.vec.transform(p, transformToPx));
|
|
28792
|
+
}
|
|
28793
|
+
|
|
28794
|
+
// When converting points, we translate so the pixel point ends up in the right location.
|
|
28795
|
+
// This is because points are specific locations on graphs, unlike vectors.
|
|
28796
|
+
function pointToPixel(point, graphState) {
|
|
28797
|
+
const [[xMin], [, yMax]] = graphState.range;
|
|
28798
|
+
const [a, b] = [-xMin, -yMax];
|
|
28799
|
+
return vectorsToPixels([point], graphState, [a, b])[0];
|
|
28800
|
+
}
|
|
28801
|
+
const useTransformVectorsToPixels = function () {
|
|
28802
|
+
const graphState = useGraphConfig();
|
|
28803
|
+
for (var _len = arguments.length, vectors = new Array(_len), _key = 0; _key < _len; _key++) {
|
|
28804
|
+
vectors[_key] = arguments[_key];
|
|
28805
|
+
}
|
|
28806
|
+
return vectorsToPixels(vectors, graphState);
|
|
28807
|
+
};
|
|
28808
|
+
|
|
28809
|
+
function AxisLabels() {
|
|
28810
|
+
const {
|
|
28811
|
+
range,
|
|
28812
|
+
labels,
|
|
28813
|
+
width,
|
|
28814
|
+
height
|
|
28815
|
+
} = useGraphConfig();
|
|
28816
|
+
const yAxisLabelLocation = [0, range[1][1]];
|
|
28817
|
+
const xAxisLabelLocation = [range[0][1], 0];
|
|
28818
|
+
const [xAxisLabelText, yAxisLabelText] = labels;
|
|
28819
|
+
const graphInfo = {
|
|
28820
|
+
range,
|
|
28821
|
+
width,
|
|
28822
|
+
height
|
|
28823
|
+
};
|
|
28824
|
+
const [x1, y1] = pointToPixel(xAxisLabelLocation, graphInfo);
|
|
28825
|
+
// The default location for the y-axis-label is at the maximum y point
|
|
28826
|
+
// This is just underneath the tick line for that point. The -24 moves the
|
|
28827
|
+
// label up one grid square, so it sits on top of the graph
|
|
28828
|
+
const [x2, y2] = mafs.vec.add(pointToPixel(yAxisLabelLocation, graphInfo), [0, -24]);
|
|
28829
|
+
const {
|
|
28830
|
+
TeX
|
|
28831
|
+
} = getDependencies();
|
|
28832
|
+
return /*#__PURE__*/React__default["default"].createElement(React__default["default"].Fragment, null, /*#__PURE__*/React__default["default"].createElement("span", {
|
|
28833
|
+
style: {
|
|
28834
|
+
position: "absolute",
|
|
28835
|
+
left: x1,
|
|
28836
|
+
top: y1,
|
|
28837
|
+
fontSize: "14px",
|
|
28838
|
+
transform: "translate(7px, -50%)"
|
|
28839
|
+
}
|
|
28840
|
+
}, /*#__PURE__*/React__default["default"].createElement(TeX, null, xAxisLabelText)), /*#__PURE__*/React__default["default"].createElement("span", {
|
|
28841
|
+
style: {
|
|
28842
|
+
position: "absolute",
|
|
28843
|
+
left: x2,
|
|
28844
|
+
top: y2,
|
|
28845
|
+
fontSize: "14px",
|
|
28846
|
+
transform: "translate(-50%, 0px)"
|
|
28847
|
+
}
|
|
28848
|
+
}, /*#__PURE__*/React__default["default"].createElement(TeX, null, yAxisLabelText)));
|
|
28849
|
+
}
|
|
28850
|
+
|
|
28749
28851
|
// TODO(FEI-4010): Remove `Perseus` prefix for all types here
|
|
28750
28852
|
// TODO(FEI-4011): Use types generated by https://github.com/jaredly/generate-perseus-flowtypes
|
|
28751
28853
|
|
|
@@ -29037,29 +29139,17 @@ function snap(snapStep, point) {
|
|
|
29037
29139
|
return [Math.round(requestedX / snapX) * snapX, Math.round(requestedY / snapY) * snapY];
|
|
29038
29140
|
}
|
|
29039
29141
|
|
|
29040
|
-
const useTransform = function () {
|
|
29041
|
-
const {
|
|
29042
|
-
viewTransform,
|
|
29043
|
-
userTransform
|
|
29044
|
-
} = mafs.useTransformContext();
|
|
29045
|
-
const transformToPx = mafs.vec.matrixMult(viewTransform, userTransform);
|
|
29046
|
-
for (var _len = arguments.length, points = new Array(_len), _key = 0; _key < _len; _key++) {
|
|
29047
|
-
points[_key] = arguments[_key];
|
|
29048
|
-
}
|
|
29049
|
-
const transformedPoints = points.map(point => mafs.vec.transform(point, transformToPx));
|
|
29050
|
-
return transformedPoints;
|
|
29051
|
-
};
|
|
29052
|
-
|
|
29053
29142
|
/**
|
|
29054
|
-
* Given
|
|
29055
|
-
*
|
|
29056
|
-
* @param
|
|
29143
|
+
* Given a ray and a rectangular box, find the point where the ray intersects
|
|
29144
|
+
* the edge of the box. Assumes the `initialPoint` is inside the box.
|
|
29145
|
+
* @param initialPoint - The starting point of the ray.
|
|
29146
|
+
* @param throughPoint - A point that the ray passes through. Must be different from initialPoint.
|
|
29147
|
+
* @param box - The box with which to intersect the ray, in the form [[xMin, xMax], [yMin, yMax]]
|
|
29057
29148
|
*/
|
|
29058
|
-
const
|
|
29059
|
-
|
|
29060
|
-
const [
|
|
29061
|
-
const [
|
|
29062
|
-
const [bX, bY] = extendFrom;
|
|
29149
|
+
const getIntersectionOfRayWithBox = (initialPoint, throughPoint, box) => {
|
|
29150
|
+
const [[xMin, xMax], [yMin, yMax]] = box;
|
|
29151
|
+
const [aX, aY] = throughPoint;
|
|
29152
|
+
const [bX, bY] = initialPoint;
|
|
29063
29153
|
const yDiff = bY - aY;
|
|
29064
29154
|
const xDiff = bX - aX;
|
|
29065
29155
|
const slope = yDiff / xDiff;
|
|
@@ -29161,7 +29251,7 @@ function scaleCommandBy(scaleFactor) {
|
|
|
29161
29251
|
// don't want that.
|
|
29162
29252
|
const arrowPath = pathBuilder().move(-3, 4).curve(-2.75, 2.5, 0, 0.25, 0.75, 0).curve(0, -0.25, -2.75, -2.5, -3, -4).scale(1.4).build();
|
|
29163
29253
|
function Arrowhead(props) {
|
|
29164
|
-
const [point] =
|
|
29254
|
+
const [point] = useTransformVectorsToPixels(props.tip);
|
|
29165
29255
|
return /*#__PURE__*/React__namespace.createElement("g", {
|
|
29166
29256
|
transform: `translate(${point[0]} ${point[1]}) rotate(${-props.angle})`
|
|
29167
29257
|
}, /*#__PURE__*/React__namespace.createElement("g", {
|
|
@@ -29183,7 +29273,7 @@ function Vector(props) {
|
|
|
29183
29273
|
tip,
|
|
29184
29274
|
color
|
|
29185
29275
|
} = props;
|
|
29186
|
-
const [tailPx, tipPx] =
|
|
29276
|
+
const [tailPx, tipPx] = useTransformVectorsToPixels(tail, tip);
|
|
29187
29277
|
const direction = mafs.vec.sub(tip, tail);
|
|
29188
29278
|
return /*#__PURE__*/React__namespace.createElement("g", {
|
|
29189
29279
|
style: {
|
|
@@ -29194,8 +29284,7 @@ function Vector(props) {
|
|
|
29194
29284
|
start: tailPx,
|
|
29195
29285
|
end: tipPx
|
|
29196
29286
|
}), /*#__PURE__*/React__namespace.createElement(Arrowhead, {
|
|
29197
|
-
|
|
29198
|
-
y: tip[1],
|
|
29287
|
+
tip: tip,
|
|
29199
29288
|
angle: angleDegrees(direction)
|
|
29200
29289
|
}));
|
|
29201
29290
|
}
|
|
@@ -29214,12 +29303,16 @@ const MovableLine = props => {
|
|
|
29214
29303
|
stroke = defaultStroke
|
|
29215
29304
|
} = props;
|
|
29216
29305
|
const midpoint = mafs.vec.midpoint(start, end);
|
|
29217
|
-
const [startPtPx, endPtPx] =
|
|
29306
|
+
const [startPtPx, endPtPx] = useTransformVectorsToPixels(start, end);
|
|
29307
|
+
const {
|
|
29308
|
+
graphDimensionsInPixels
|
|
29309
|
+
} = useGraphConfig();
|
|
29218
29310
|
let startExtend = undefined;
|
|
29219
29311
|
let endExtend = undefined;
|
|
29220
29312
|
if (extend) {
|
|
29221
|
-
|
|
29222
|
-
|
|
29313
|
+
const trimmedRange = trimRange(extend.range, graphDimensionsInPixels);
|
|
29314
|
+
startExtend = extend.start ? getIntersectionOfRayWithBox(start, end, trimmedRange) : undefined;
|
|
29315
|
+
endExtend = extend.end ? getIntersectionOfRayWithBox(end, start, trimmedRange) : undefined;
|
|
29223
29316
|
}
|
|
29224
29317
|
const line = React.useRef(null);
|
|
29225
29318
|
const {
|
|
@@ -29276,16 +29369,24 @@ const MovableLine = props => {
|
|
|
29276
29369
|
color: stroke
|
|
29277
29370
|
}));
|
|
29278
29371
|
};
|
|
29279
|
-
|
|
29280
|
-
const
|
|
29281
|
-
|
|
29282
|
-
|
|
29283
|
-
|
|
29284
|
-
|
|
29285
|
-
|
|
29286
|
-
const
|
|
29287
|
-
|
|
29288
|
-
|
|
29372
|
+
function trimRange(range, graphDimensionsInPixels) {
|
|
29373
|
+
const pixelsToTrim = 4;
|
|
29374
|
+
const [xRange, yRange] = range;
|
|
29375
|
+
const [pixelsWide, pixelsTall] = graphDimensionsInPixels;
|
|
29376
|
+
const graphUnitsPerPixelX = size(xRange) / pixelsWide;
|
|
29377
|
+
const graphUnitsPerPixelY = size(yRange) / pixelsTall;
|
|
29378
|
+
const graphUnitsToTrimX = pixelsToTrim * graphUnitsPerPixelX;
|
|
29379
|
+
const graphUnitsToTrimY = pixelsToTrim * graphUnitsPerPixelY;
|
|
29380
|
+
return [trim(xRange, graphUnitsToTrimX), trim(yRange, graphUnitsToTrimY)];
|
|
29381
|
+
}
|
|
29382
|
+
function trim(interval, amount) {
|
|
29383
|
+
if (size(interval) < amount * 2) {
|
|
29384
|
+
return [0, 0];
|
|
29385
|
+
}
|
|
29386
|
+
return [interval[0] + amount, interval[1] - amount];
|
|
29387
|
+
}
|
|
29388
|
+
function size(interval) {
|
|
29389
|
+
return interval[1] - interval[0];
|
|
29289
29390
|
}
|
|
29290
29391
|
|
|
29291
29392
|
// The hitbox size of 48px by 48px is preserved from the legacy interactive
|
|
@@ -29320,13 +29421,13 @@ const StyledMovablePoint = props => {
|
|
|
29320
29421
|
constrain: p => snap(snapStep, p)
|
|
29321
29422
|
});
|
|
29322
29423
|
const pointClasses = `movable-point ${dragging ? "movable-point--dragging" : ""}`;
|
|
29323
|
-
const [[x, y]] =
|
|
29424
|
+
const [[x, y]] = useTransformVectorsToPixels(point);
|
|
29324
29425
|
const [xMin, xMax] = range[0];
|
|
29325
29426
|
const [yMin, yMax] = range[1];
|
|
29326
|
-
const [[verticalStartX]] =
|
|
29327
|
-
const [[verticalEndX]] =
|
|
29328
|
-
const [[_, horizontalStartY]] =
|
|
29329
|
-
const [[__, horizontalEndY]] =
|
|
29427
|
+
const [[verticalStartX]] = useTransformVectorsToPixels([xMin, 0]);
|
|
29428
|
+
const [[verticalEndX]] = useTransformVectorsToPixels([xMax, 0]);
|
|
29429
|
+
const [[_, horizontalStartY]] = useTransformVectorsToPixels([0, yMin]);
|
|
29430
|
+
const [[__, horizontalEndY]] = useTransformVectorsToPixels([0, yMax]);
|
|
29330
29431
|
const showHairlines = dragging && markings !== "none";
|
|
29331
29432
|
const hairlines = /*#__PURE__*/React__namespace.createElement("g", null, /*#__PURE__*/React__namespace.createElement("line", {
|
|
29332
29433
|
x1: verticalStartX,
|
|
@@ -29654,7 +29755,7 @@ const isRightAngle = angle => Math.abs(angle - Math.PI / 2) < 0.01;
|
|
|
29654
29755
|
*/
|
|
29655
29756
|
const shouldDrawArcOutside = (midpoint, vertex, range, polygonLines) => {
|
|
29656
29757
|
// Create a ray from the midpoint (inside angle) to the edge of the range
|
|
29657
|
-
const rangeIntersectionPoint =
|
|
29758
|
+
const rangeIntersectionPoint = getIntersectionOfRayWithBox(vertex, midpoint, range);
|
|
29658
29759
|
let lineIntersectionCount = 0;
|
|
29659
29760
|
polygonLines.forEach(line => linesIntersect([vertex, rangeIntersectionPoint], line) && lineIntersectionCount++);
|
|
29660
29761
|
|
|
@@ -29779,23 +29880,19 @@ function AxisArrows() {
|
|
|
29779
29880
|
const axisColor = "var(--mafs-fg)";
|
|
29780
29881
|
return /*#__PURE__*/React__default["default"].createElement(React__default["default"].Fragment, null, /*#__PURE__*/React__default["default"].createElement(Arrowhead, {
|
|
29781
29882
|
color: axisColor,
|
|
29782
|
-
|
|
29783
|
-
y: 0,
|
|
29883
|
+
tip: [xMin, 0],
|
|
29784
29884
|
angle: 180
|
|
29785
29885
|
}), /*#__PURE__*/React__default["default"].createElement(Arrowhead, {
|
|
29786
29886
|
color: axisColor,
|
|
29787
|
-
|
|
29788
|
-
y: 0,
|
|
29887
|
+
tip: [xMax, 0],
|
|
29789
29888
|
angle: 0
|
|
29790
29889
|
}), /*#__PURE__*/React__default["default"].createElement(Arrowhead, {
|
|
29791
29890
|
color: axisColor,
|
|
29792
|
-
|
|
29793
|
-
y: yMin,
|
|
29891
|
+
tip: [0, yMin],
|
|
29794
29892
|
angle: 270
|
|
29795
29893
|
}), /*#__PURE__*/React__default["default"].createElement(Arrowhead, {
|
|
29796
29894
|
color: axisColor,
|
|
29797
|
-
|
|
29798
|
-
y: yMax,
|
|
29895
|
+
tip: [0, yMax],
|
|
29799
29896
|
angle: 90
|
|
29800
29897
|
}));
|
|
29801
29898
|
}
|
|
@@ -29821,7 +29918,7 @@ const YGridTick = _ref => {
|
|
|
29821
29918
|
tickStep
|
|
29822
29919
|
} = _ref;
|
|
29823
29920
|
const pointOnAxis = [0, y];
|
|
29824
|
-
const [[xPosition, yPosition]] =
|
|
29921
|
+
const [[xPosition, yPosition]] = useTransformVectorsToPixels(pointOnAxis);
|
|
29825
29922
|
return /*#__PURE__*/React__namespace.createElement("g", {
|
|
29826
29923
|
className: "y-axis-ticks"
|
|
29827
29924
|
}, /*#__PURE__*/React__namespace.createElement("line", {
|
|
@@ -29845,7 +29942,7 @@ const XGridTick = _ref2 => {
|
|
|
29845
29942
|
tickStep
|
|
29846
29943
|
} = _ref2;
|
|
29847
29944
|
const pointOnAxis = [x, 0];
|
|
29848
|
-
const [[xPosition, yPosition]] =
|
|
29945
|
+
const [[xPosition, yPosition]] = useTransformVectorsToPixels(pointOnAxis);
|
|
29849
29946
|
return /*#__PURE__*/React__namespace.createElement("g", {
|
|
29850
29947
|
className: "x-axis-ticks"
|
|
29851
29948
|
}, /*#__PURE__*/React__namespace.createElement("line", {
|
|
@@ -30067,96 +30164,26 @@ const styles$k = aphrodite.StyleSheet.create({
|
|
|
30067
30164
|
}
|
|
30068
30165
|
});
|
|
30069
30166
|
|
|
30070
|
-
const
|
|
30071
|
-
|
|
30072
|
-
|
|
30073
|
-
|
|
30074
|
-
}
|
|
30075
|
-
|
|
30076
|
-
|
|
30077
|
-
|
|
30078
|
-
|
|
30079
|
-
|
|
30080
|
-
|
|
30081
|
-
top: "0",
|
|
30082
|
-
width: "0"
|
|
30167
|
+
const InfoTip$1 = props => {
|
|
30168
|
+
return /*#__PURE__*/React__namespace.createElement(Tooltip__default["default"], {
|
|
30169
|
+
content: /*#__PURE__*/React__namespace.createElement(wonderBlocksTypography.Body, {
|
|
30170
|
+
style: styles$j.body
|
|
30171
|
+
}, props.children),
|
|
30172
|
+
placement: "right"
|
|
30173
|
+
}, /*#__PURE__*/React__namespace.createElement(wonderBlocksIcon.PhosphorIcon, {
|
|
30174
|
+
size: "small",
|
|
30175
|
+
icon: questionIcon__default["default"],
|
|
30176
|
+
style: styles$j.spacingLeft
|
|
30177
|
+
}));
|
|
30083
30178
|
};
|
|
30084
30179
|
const styles$j = aphrodite.StyleSheet.create({
|
|
30085
|
-
|
|
30086
|
-
|
|
30087
|
-
marginLeft: "5px",
|
|
30088
|
-
position: "relative"
|
|
30089
|
-
},
|
|
30090
|
-
infoTipContainer: {
|
|
30091
|
-
position: "absolute",
|
|
30092
|
-
top: "-12px",
|
|
30093
|
-
left: "22px",
|
|
30094
|
-
zIndex: 1000
|
|
30095
|
-
},
|
|
30096
|
-
infoTipTriangle: {
|
|
30097
|
-
height: "10px",
|
|
30098
|
-
left: "0",
|
|
30099
|
-
position: "absolute",
|
|
30100
|
-
top: "8px",
|
|
30101
|
-
width: "0",
|
|
30102
|
-
zIndex: 1,
|
|
30103
|
-
":before": {
|
|
30104
|
-
...triangleBeforeAfter,
|
|
30105
|
-
borderRight: "9px solid #bbb",
|
|
30106
|
-
right: "0"
|
|
30107
|
-
},
|
|
30108
|
-
":after": {
|
|
30109
|
-
...triangleBeforeAfter,
|
|
30110
|
-
borderRight: `9px solid ${colors$1.white}`,
|
|
30111
|
-
right: "-1px"
|
|
30112
|
-
}
|
|
30113
|
-
},
|
|
30114
|
-
verticalShadow: {
|
|
30115
|
-
border: `1px solid ${colors$1.basicBorderColor}`,
|
|
30116
|
-
boxShadow: `0 1px 3px ${colors$1.basicBorderColor}`,
|
|
30117
|
-
borderBottom: `1px solid ${colors$1.grayLight}`
|
|
30180
|
+
spacingLeft: {
|
|
30181
|
+
marginInlineStart: wonderBlocksTokens.spacing.xxxSmall_4
|
|
30118
30182
|
},
|
|
30119
|
-
|
|
30120
|
-
|
|
30121
|
-
padding: "5px 10px",
|
|
30122
|
-
width: "240px"
|
|
30183
|
+
body: {
|
|
30184
|
+
padding: wonderBlocksTokens.spacing.medium_16
|
|
30123
30185
|
}
|
|
30124
30186
|
});
|
|
30125
|
-
class InfoTip$1 extends React__namespace.Component {
|
|
30126
|
-
state = {
|
|
30127
|
-
hover: false
|
|
30128
|
-
};
|
|
30129
|
-
handleMouseEnter = () => {
|
|
30130
|
-
this.setState({
|
|
30131
|
-
hover: true
|
|
30132
|
-
});
|
|
30133
|
-
};
|
|
30134
|
-
handleMouseLeave = () => {
|
|
30135
|
-
this.setState({
|
|
30136
|
-
hover: false
|
|
30137
|
-
});
|
|
30138
|
-
};
|
|
30139
|
-
render() {
|
|
30140
|
-
return /*#__PURE__*/React__namespace.createElement("div", {
|
|
30141
|
-
className: aphrodite.css(styles$j.infoTip)
|
|
30142
|
-
}, /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, {
|
|
30143
|
-
onMouseEnter: this.handleMouseEnter,
|
|
30144
|
-
onMouseLeave: this.handleMouseLeave
|
|
30145
|
-
}, /*#__PURE__*/React__namespace.createElement(wonderBlocksIcon.PhosphorIcon, {
|
|
30146
|
-
size: "small",
|
|
30147
|
-
icon: questionIcon__default["default"]
|
|
30148
|
-
})), /*#__PURE__*/React__namespace.createElement("div", {
|
|
30149
|
-
className: aphrodite.css(styles$j.infoTipContainer),
|
|
30150
|
-
style: {
|
|
30151
|
-
display: this.state.hover ? "block" : "none"
|
|
30152
|
-
}
|
|
30153
|
-
}, /*#__PURE__*/React__namespace.createElement("div", {
|
|
30154
|
-
className: aphrodite.css(styles$j.infoTipTriangle)
|
|
30155
|
-
}), /*#__PURE__*/React__namespace.createElement("div", {
|
|
30156
|
-
className: aphrodite.css(styles$j.verticalShadow, styles$j.infoTipContentContainer)
|
|
30157
|
-
}, this.props.children)));
|
|
30158
|
-
}
|
|
30159
|
-
}
|
|
30160
30187
|
|
|
30161
30188
|
/**
|
|
30162
30189
|
* A wrapper around info-tip/info-tip.jsx that can be rendered on the
|
|
@@ -31013,7 +31040,7 @@ const getDefaultPoints = _ref => {
|
|
|
31013
31040
|
function getGradableGraph(state, initialGraph) {
|
|
31014
31041
|
if (!state.hasBeenInteractedWith) {
|
|
31015
31042
|
return {
|
|
31016
|
-
|
|
31043
|
+
...initialGraph
|
|
31017
31044
|
};
|
|
31018
31045
|
}
|
|
31019
31046
|
if (initialGraph.type === "linear-system" && state.type === "linear-system") {
|
|
@@ -31180,7 +31207,8 @@ const StatefulMafsGraph = /*#__PURE__*/React__namespace.forwardRef((props, ref)
|
|
|
31180
31207
|
const MafsGraph = props => {
|
|
31181
31208
|
const {
|
|
31182
31209
|
state,
|
|
31183
|
-
dispatch
|
|
31210
|
+
dispatch,
|
|
31211
|
+
labels
|
|
31184
31212
|
} = props;
|
|
31185
31213
|
const [width, height] = props.box;
|
|
31186
31214
|
const prevState = React.useRef(state);
|
|
@@ -31209,7 +31237,11 @@ const MafsGraph = props => {
|
|
|
31209
31237
|
range: state.range,
|
|
31210
31238
|
snapStep: state.snapStep,
|
|
31211
31239
|
markings: props.markings,
|
|
31212
|
-
showTooltips: !!props.showTooltips
|
|
31240
|
+
showTooltips: !!props.showTooltips,
|
|
31241
|
+
graphDimensionsInPixels: props.box,
|
|
31242
|
+
width,
|
|
31243
|
+
height,
|
|
31244
|
+
labels
|
|
31213
31245
|
}
|
|
31214
31246
|
}, /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, {
|
|
31215
31247
|
style: {
|
|
@@ -31228,7 +31260,7 @@ const MafsGraph = props => {
|
|
|
31228
31260
|
bottom: 0,
|
|
31229
31261
|
left: 0
|
|
31230
31262
|
}
|
|
31231
|
-
}, /*#__PURE__*/React__namespace.createElement(mafs.Mafs, {
|
|
31263
|
+
}, props.markings === "graph" && /*#__PURE__*/React__namespace.createElement(AxisLabels, null), /*#__PURE__*/React__namespace.createElement(mafs.Mafs, {
|
|
31232
31264
|
preserveAspectRatio: false,
|
|
31233
31265
|
viewBox: {
|
|
31234
31266
|
x: props.range[0],
|
|
@@ -32455,8 +32487,12 @@ class LegacyInteractiveGraph extends React__namespace.Component {
|
|
|
32455
32487
|
graph: graph
|
|
32456
32488
|
});
|
|
32457
32489
|
};
|
|
32458
|
-
getUserInput
|
|
32459
|
-
|
|
32490
|
+
getUserInput() {
|
|
32491
|
+
return InteractiveGraph.getUserInputFromProps(this.props);
|
|
32492
|
+
}
|
|
32493
|
+
simpleValidate(rubric) {
|
|
32494
|
+
return InteractiveGraph.validate(this.getUserInput(), rubric, this);
|
|
32495
|
+
}
|
|
32460
32496
|
focus = $__default["default"].noop;
|
|
32461
32497
|
render() {
|
|
32462
32498
|
const box = getInteractiveBoxFromSizeClass(this.props.containerSizeClass);
|
|
@@ -32535,7 +32571,9 @@ class InteractiveGraph extends React__namespace.Component {
|
|
|
32535
32571
|
}
|
|
32536
32572
|
throw new PerseusError("Cannot getUserInput from a graph that has never rendered", Errors.NotAllowed);
|
|
32537
32573
|
};
|
|
32538
|
-
simpleValidate
|
|
32574
|
+
simpleValidate(rubric) {
|
|
32575
|
+
return InteractiveGraph.validate(this.getUserInput?.(), rubric, this);
|
|
32576
|
+
}
|
|
32539
32577
|
render() {
|
|
32540
32578
|
// Mafs shim
|
|
32541
32579
|
if (this.props.apiOptions?.flags?.["mafs"]?.[this.props.graph.type]) {
|
|
@@ -43336,7 +43374,7 @@ const init = function (options) {
|
|
|
43336
43374
|
|
|
43337
43375
|
// This file is processed by a Rollup plugin (replace) to inject the production
|
|
43338
43376
|
const libName = "@khanacademy/perseus";
|
|
43339
|
-
const libVersion = "22.0
|
|
43377
|
+
const libVersion = "22.1.0";
|
|
43340
43378
|
perseusCore.addLibraryVersionToPerseusDebug(libName, libVersion);
|
|
43341
43379
|
|
|
43342
43380
|
const apiVersion = {
|