@khanacademy/perseus 33.1.0 → 33.2.1
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/es/index.js +117 -41
- package/dist/es/index.js.map +1 -1
- package/dist/index.js +117 -41
- package/dist/index.js.map +1 -1
- package/dist/util/colors.d.ts +5 -13
- package/dist/widgets/interactive-graphs/types.d.ts +1 -0
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -8780,10 +8780,10 @@ var Raphael$1 = (function () {
|
|
|
8780
8780
|
* provided on KhanUtil.
|
|
8781
8781
|
*/
|
|
8782
8782
|
const KhanColors = {
|
|
8783
|
-
BLUE:
|
|
8783
|
+
BLUE: wonderBlocksTokens.color.blue,
|
|
8784
8784
|
ORANGE: "#FFA500",
|
|
8785
8785
|
PINK: "#FF00AF",
|
|
8786
|
-
GREEN:
|
|
8786
|
+
GREEN: wonderBlocksTokens.color.green,
|
|
8787
8787
|
PURPLE: "#9D38BD",
|
|
8788
8788
|
RED: "#DF0030",
|
|
8789
8789
|
GRAY: "gray",
|
|
@@ -8859,11 +8859,9 @@ const KhanColors = {
|
|
|
8859
8859
|
// of any redesigns.
|
|
8860
8860
|
_BACKGROUND: "#FDFDFD",
|
|
8861
8861
|
// TODO(eater): Get rid of this altogether.
|
|
8862
|
-
INTERACTING:
|
|
8863
|
-
|
|
8864
|
-
|
|
8865
|
-
// KA_GREEN
|
|
8866
|
-
DYNAMIC: "#6495ED" // BLUE
|
|
8862
|
+
INTERACTING: wonderBlocksTokens.color.green,
|
|
8863
|
+
INTERACTIVE: wonderBlocksTokens.color.green,
|
|
8864
|
+
DYNAMIC: wonderBlocksTokens.color.blue
|
|
8867
8865
|
};
|
|
8868
8866
|
|
|
8869
8867
|
// DrawingTransform is responsible for transforming from "math coordinates"
|
|
@@ -10147,21 +10145,50 @@ const setLabelMargins = function (span, size) {
|
|
|
10147
10145
|
marginTop: -height / 2 - y * scale
|
|
10148
10146
|
});
|
|
10149
10147
|
} else {
|
|
10150
|
-
|
|
10148
|
+
// We are using jQuery to collect information and calculate a scale
|
|
10149
|
+
// since we don't have a way to pass it to this function.
|
|
10150
|
+
// We need the width of the container in order to calculate the scale to apply to the label.
|
|
10151
|
+
// Unfortunately, the DOM tree leading to the label is not consistent.
|
|
10152
|
+
// Therefore, we need to check different elements and different style properties to get the width of the container.
|
|
10153
|
+
// Some graphie labels exist within an ".svg-image" container, and others do not.
|
|
10154
|
+
// All graphie labels have a ".graphie" container.
|
|
10155
|
+
// When a label has an ".svg-image" container,
|
|
10156
|
+
// the width information in the ".graphie" element is expressed as a percentage instead of pixels,
|
|
10157
|
+
// so we can't use it.
|
|
10158
|
+
// Instead, the ".svg-image" container can be used to get the width information.
|
|
10159
|
+
// The following lines determine which container element to use for the width measurement.
|
|
10160
|
+
const $svgImage = $span.closest(".svg-image");
|
|
10161
|
+
const $graphie = $span.closest(".graphie");
|
|
10162
|
+
// If an ".svg-image" container exists in the DOM tree, then use it, otherwise use the ".graphie" container.
|
|
10163
|
+
const $container = $svgImage.length > 0 ? $svgImage : $graphie;
|
|
10164
|
+
|
|
10151
10165
|
// Ensuring that the line-height of the text doesn't throw off placement of the text element.
|
|
10152
10166
|
// Inherited line-height values can really mess up placement.
|
|
10153
10167
|
$container.css("line-height", "normal");
|
|
10154
10168
|
|
|
10155
|
-
// The
|
|
10156
|
-
//
|
|
10157
|
-
const
|
|
10169
|
+
// The expected width of the graphie is found in the "max-width" property on ".svg-image" containers,
|
|
10170
|
+
// and is found in the "width" property on ".graphie" containers.
|
|
10171
|
+
const widthValues = $container.css(["max-width", "width"]) ?? {
|
|
10172
|
+
// The browser will always return a value, but tests won't, so ensuring something is returned.
|
|
10173
|
+
"max-width": "0px"
|
|
10174
|
+
};
|
|
10175
|
+
const expectedWidth =
|
|
10176
|
+
// Verified in Chrome, Firefox, and Safari - all return the same "none" value if the property does not exist.
|
|
10177
|
+
widthValues["max-width"] !== "none" ? widthValues["max-width"] : widthValues["width"];
|
|
10158
10178
|
// We can calculate the true scale of the graphie by taking actual width and dividing by the expected width.
|
|
10159
|
-
// NOTE: Using '
|
|
10160
|
-
|
|
10179
|
+
// NOTE: Using 'replace' to remove the "px" unit from the end of the expected width value.
|
|
10180
|
+
let scale = ($container.width() ?? 0) / parseInt(expectedWidth.replace(/px$/, "")) * 100;
|
|
10181
|
+
// If something failed in the calculation, then default to 100% scale.
|
|
10182
|
+
if (isNaN(scale)) {
|
|
10183
|
+
scale = 100;
|
|
10184
|
+
} else if (scale === 0) {
|
|
10185
|
+
scale = 100;
|
|
10186
|
+
}
|
|
10161
10187
|
|
|
10162
10188
|
// Any padding needs to be scaled accordingly.
|
|
10163
|
-
const
|
|
10164
|
-
const
|
|
10189
|
+
const padding = $span.css("padding") ?? "0px";
|
|
10190
|
+
const currentPadding = padding !== "none" ? padding : "0px";
|
|
10191
|
+
const newPadding = Math.round(parseInt(currentPadding.replace(/px$/, "")) * scale) / 100;
|
|
10165
10192
|
|
|
10166
10193
|
// "multipliers" basically move the position of the text by using 1, 0, -1
|
|
10167
10194
|
// 'margin-left' and 'margin-top' are used to position the text.
|
|
@@ -29953,7 +29980,8 @@ function LockedLabel(props) {
|
|
|
29953
29980
|
left: x,
|
|
29954
29981
|
top: y,
|
|
29955
29982
|
color: lockedFigureColors[color],
|
|
29956
|
-
fontSize: wonderBlocksTokens.font.size[size]
|
|
29983
|
+
fontSize: wonderBlocksTokens.font.size[size],
|
|
29984
|
+
backgroundColor: "rgba(255, 255, 255, 0.8)"
|
|
29957
29985
|
}
|
|
29958
29986
|
}, /*#__PURE__*/React__namespace.createElement(TeX, null, text));
|
|
29959
29987
|
}
|
|
@@ -31990,7 +32018,8 @@ function UnlimitedPointGraph(props) {
|
|
|
31990
32018
|
const [[left, top]] = useTransformVectorsToPixels([minX, maxY]);
|
|
31991
32019
|
return /*#__PURE__*/React__namespace.createElement(React__namespace.Fragment, null, /*#__PURE__*/React__namespace.createElement("rect", {
|
|
31992
32020
|
style: {
|
|
31993
|
-
fill: "rgba(0,0,0,0)"
|
|
32021
|
+
fill: "rgba(0,0,0,0)",
|
|
32022
|
+
cursor: "crosshair"
|
|
31994
32023
|
},
|
|
31995
32024
|
width: widthPx,
|
|
31996
32025
|
height: heightPx,
|
|
@@ -32160,6 +32189,17 @@ function useDraggablePx(args) {
|
|
|
32160
32189
|
});
|
|
32161
32190
|
}
|
|
32162
32191
|
|
|
32192
|
+
/**
|
|
32193
|
+
* Render the Mafs graph with the specified background and graph elements.
|
|
32194
|
+
*
|
|
32195
|
+
* Render order (back to front):
|
|
32196
|
+
* - Grid
|
|
32197
|
+
* - Axis Ticks, Axis Arrows, and Axis Labels
|
|
32198
|
+
* - Locked Figures
|
|
32199
|
+
* - Locked Labels
|
|
32200
|
+
* - Protractor
|
|
32201
|
+
* - Interactive Graph Elements
|
|
32202
|
+
*/
|
|
32163
32203
|
const MafsGraph = props => {
|
|
32164
32204
|
const {
|
|
32165
32205
|
state,
|
|
@@ -32238,8 +32278,6 @@ const MafsGraph = props => {
|
|
|
32238
32278
|
}, fullGraphAriaDescription), /*#__PURE__*/React__namespace.createElement(LegacyGrid, {
|
|
32239
32279
|
box: props.box,
|
|
32240
32280
|
backgroundImage: props.backgroundImage
|
|
32241
|
-
}), props.showLabelsFlag && props.lockedFigures && /*#__PURE__*/React__namespace.createElement(GraphLockedLabelsLayer, {
|
|
32242
|
-
lockedFigures: props.lockedFigures
|
|
32243
32281
|
}), /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, {
|
|
32244
32282
|
style: {
|
|
32245
32283
|
position: "absolute",
|
|
@@ -32269,28 +32307,64 @@ const MafsGraph = props => {
|
|
|
32269
32307
|
props.markings === "graph" && /*#__PURE__*/React__namespace.createElement(React__namespace.Fragment, null, /*#__PURE__*/React__namespace.createElement(AxisTicks, null), /*#__PURE__*/React__namespace.createElement(AxisArrows, null)), /*#__PURE__*/React__namespace.createElement("svg", nestedSVGAttributes, props.lockedFigures && /*#__PURE__*/React__namespace.createElement(GraphLockedLayer, {
|
|
32270
32308
|
lockedFigures: props.lockedFigures,
|
|
32271
32309
|
range: state.range
|
|
32272
|
-
}), props.
|
|
32310
|
+
}))), props.showLabelsFlag && props.lockedFigures && /*#__PURE__*/React__namespace.createElement(GraphLockedLabelsLayer, {
|
|
32311
|
+
lockedFigures: props.lockedFigures
|
|
32312
|
+
}), /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, {
|
|
32313
|
+
style: {
|
|
32314
|
+
position: "absolute"
|
|
32315
|
+
}
|
|
32316
|
+
}, /*#__PURE__*/React__namespace.createElement(mafs.Mafs, {
|
|
32317
|
+
preserveAspectRatio: false,
|
|
32318
|
+
viewBox: {
|
|
32319
|
+
x: state.range[X],
|
|
32320
|
+
y: state.range[Y],
|
|
32321
|
+
padding: 0
|
|
32322
|
+
},
|
|
32323
|
+
pan: false,
|
|
32324
|
+
zoom: false,
|
|
32325
|
+
width: width,
|
|
32326
|
+
height: height
|
|
32327
|
+
}, props.showProtractor && /*#__PURE__*/React__namespace.createElement(Protractor, null), renderGraph({
|
|
32273
32328
|
state,
|
|
32274
32329
|
dispatch
|
|
32275
32330
|
}))))), renderGraphControls({
|
|
32276
32331
|
state,
|
|
32277
|
-
dispatch
|
|
32332
|
+
dispatch,
|
|
32333
|
+
width
|
|
32278
32334
|
})));
|
|
32279
32335
|
};
|
|
32280
|
-
const renderPointGraphControls = props => /*#__PURE__*/React__namespace.createElement(
|
|
32336
|
+
const renderPointGraphControls = props => /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, {
|
|
32337
|
+
style: {
|
|
32338
|
+
flexDirection: "row",
|
|
32339
|
+
width: props.width
|
|
32340
|
+
}
|
|
32341
|
+
}, /*#__PURE__*/React__namespace.createElement(Button__default["default"], {
|
|
32281
32342
|
kind: "secondary",
|
|
32282
32343
|
style: {
|
|
32283
32344
|
width: "100%",
|
|
32284
32345
|
marginLeft: "20px"
|
|
32285
32346
|
},
|
|
32347
|
+
tabIndex: 0,
|
|
32286
32348
|
onClick: () => {
|
|
32287
32349
|
props.dispatch(actions.pointGraph.addPoint([0, 0]));
|
|
32288
32350
|
}
|
|
32289
|
-
}, "Add Point")
|
|
32351
|
+
}, "Add Point"), (props.state.focusedPointIndex !== null || props.state.previouslyFocusedPointIndex !== null) && /*#__PURE__*/React__namespace.createElement(Button__default["default"], {
|
|
32352
|
+
kind: "secondary",
|
|
32353
|
+
color: "destructive",
|
|
32354
|
+
tabIndex: 0,
|
|
32355
|
+
style: {
|
|
32356
|
+
width: "100%",
|
|
32357
|
+
marginLeft: "20px"
|
|
32358
|
+
},
|
|
32359
|
+
onClick: event => {
|
|
32360
|
+
props.dispatch(actions.pointGraph.removePoint(props.state.previouslyFocusedPointIndex));
|
|
32361
|
+
}
|
|
32362
|
+
}, "Remove Point"));
|
|
32290
32363
|
const renderGraphControls = props => {
|
|
32291
32364
|
const {
|
|
32292
32365
|
state,
|
|
32293
|
-
dispatch
|
|
32366
|
+
dispatch,
|
|
32367
|
+
width
|
|
32294
32368
|
} = props;
|
|
32295
32369
|
const {
|
|
32296
32370
|
type
|
|
@@ -32300,7 +32374,8 @@ const renderGraphControls = props => {
|
|
|
32300
32374
|
if (state.numPoints === "unlimited") {
|
|
32301
32375
|
return renderPointGraphControls({
|
|
32302
32376
|
state,
|
|
32303
|
-
dispatch
|
|
32377
|
+
dispatch,
|
|
32378
|
+
width
|
|
32304
32379
|
});
|
|
32305
32380
|
}
|
|
32306
32381
|
return null;
|
|
@@ -32474,7 +32549,8 @@ function initializeGraphState(params) {
|
|
|
32474
32549
|
type: graph.type,
|
|
32475
32550
|
coords: getPointCoords(graph, range, step),
|
|
32476
32551
|
numPoints: graph.numPoints || 0,
|
|
32477
|
-
focusedPointIndex: null
|
|
32552
|
+
focusedPointIndex: null,
|
|
32553
|
+
previouslyFocusedPointIndex: null
|
|
32478
32554
|
};
|
|
32479
32555
|
case "circle":
|
|
32480
32556
|
return {
|
|
@@ -32771,6 +32847,7 @@ function doBlurPoint(state, action) {
|
|
|
32771
32847
|
case "point":
|
|
32772
32848
|
return {
|
|
32773
32849
|
...state,
|
|
32850
|
+
previouslyFocusedPointIndex: state.focusedPointIndex,
|
|
32774
32851
|
focusedPointIndex: null
|
|
32775
32852
|
};
|
|
32776
32853
|
default:
|
|
@@ -32817,7 +32894,6 @@ function doMovePointInFigure(state, action) {
|
|
|
32817
32894
|
}
|
|
32818
32895
|
case "angle":
|
|
32819
32896
|
case "circle":
|
|
32820
|
-
throw new Error("FIXME implement circle reducer");
|
|
32821
32897
|
case "point":
|
|
32822
32898
|
case "polygon":
|
|
32823
32899
|
case "quadratic":
|
|
@@ -33143,7 +33219,8 @@ function doRemovePoint(state, action) {
|
|
|
33143
33219
|
return {
|
|
33144
33220
|
...state,
|
|
33145
33221
|
coords: state.coords.filter((_, i) => i !== action.index),
|
|
33146
|
-
focusedPointIndex: null
|
|
33222
|
+
focusedPointIndex: null,
|
|
33223
|
+
previouslyFocusedPointIndex: null
|
|
33147
33224
|
};
|
|
33148
33225
|
}
|
|
33149
33226
|
const getDeltaVertex = (maxMoves, minMoves, delta) => {
|
|
@@ -39967,15 +40044,15 @@ const TickMarks = Graphie.createSimpleClass((graphie, props) => {
|
|
|
39967
40044
|
|
|
39968
40045
|
// Render the text labels
|
|
39969
40046
|
results.push(graphie.style(props.isMobile ? {
|
|
39970
|
-
color: KhanColors.
|
|
40047
|
+
color: KhanColors.BLUE
|
|
39971
40048
|
} : {}, () => _label(graphie, props.labelStyle, leftLabel, leftLabel, base)));
|
|
39972
40049
|
results.push(graphie.style(props.isMobile ? {
|
|
39973
|
-
color: KhanColors.
|
|
40050
|
+
color: KhanColors.BLUE
|
|
39974
40051
|
} : {}, () => _label(graphie, props.labelStyle, rightLabel, rightLabel, base)));
|
|
39975
40052
|
|
|
39976
40053
|
// Render the labels' lines
|
|
39977
40054
|
graphie.style({
|
|
39978
|
-
stroke:
|
|
40055
|
+
stroke: KhanColors.BLUE,
|
|
39979
40056
|
strokeWidth: 3.5
|
|
39980
40057
|
}, () => {
|
|
39981
40058
|
results.push(graphie.line([leftLabel, -0.2], [leftLabel, 0.2]));
|
|
@@ -40162,21 +40239,21 @@ class NumberLine extends React__namespace.Component {
|
|
|
40162
40239
|
if (isOpen) {
|
|
40163
40240
|
fill = KhanColors._BACKGROUND;
|
|
40164
40241
|
} else if (props.static) {
|
|
40165
|
-
fill = KhanColors.
|
|
40242
|
+
fill = KhanColors.BLUE;
|
|
40166
40243
|
} else {
|
|
40167
|
-
fill = KhanColors.
|
|
40244
|
+
fill = KhanColors.GREEN;
|
|
40168
40245
|
}
|
|
40169
40246
|
const normalStyle = {
|
|
40170
40247
|
fill: fill,
|
|
40171
|
-
stroke: props.static ? KhanColors.
|
|
40248
|
+
stroke: props.static ? KhanColors.BLUE : KhanColors.GREEN,
|
|
40172
40249
|
"stroke-width": isOpen ? 3 : 1
|
|
40173
40250
|
};
|
|
40174
40251
|
const highlightStyle = {
|
|
40175
|
-
fill: isOpen ? KhanColors._BACKGROUND : KhanColors.
|
|
40252
|
+
fill: isOpen ? KhanColors._BACKGROUND : KhanColors.GREEN,
|
|
40176
40253
|
"stroke-width": isOpen ? 3 : 1
|
|
40177
40254
|
};
|
|
40178
40255
|
const mobileDotStyle = props.isInequality ? {
|
|
40179
|
-
stroke: KhanColors.
|
|
40256
|
+
stroke: KhanColors.GREEN,
|
|
40180
40257
|
"fill-opacity": isOpen ? 0 : 1
|
|
40181
40258
|
} : {};
|
|
40182
40259
|
return /*#__PURE__*/React__namespace.createElement(MovablePoint
|
|
@@ -40236,7 +40313,7 @@ class NumberLine extends React__namespace.Component {
|
|
|
40236
40313
|
const end = this._getInequalityEndpoint(props);
|
|
40237
40314
|
const style = {
|
|
40238
40315
|
arrows: "->",
|
|
40239
|
-
stroke: this.props.apiOptions.isMobile ? KhanColors.
|
|
40316
|
+
stroke: this.props.apiOptions.isMobile ? KhanColors.GREEN : KhanColors.BLUE,
|
|
40240
40317
|
strokeWidth: 3.5
|
|
40241
40318
|
};
|
|
40242
40319
|
const isGreater = ["ge", "gt"].includes(props.rel);
|
|
@@ -43409,7 +43486,7 @@ class PhetSimulation extends React__namespace.Component {
|
|
|
43409
43486
|
className: aphrodite.css(styles$6.iframeResponsive),
|
|
43410
43487
|
src: this.state.url?.toString(),
|
|
43411
43488
|
allow: "fullscreen"
|
|
43412
|
-
})), /*#__PURE__*/React__namespace.createElement(IconButton__default["default"], {
|
|
43489
|
+
})), this.state.url !== null && /*#__PURE__*/React__namespace.createElement(IconButton__default["default"], {
|
|
43413
43490
|
icon: cornersOutIcon__default["default"],
|
|
43414
43491
|
onClick: () => {
|
|
43415
43492
|
this.iframeRef.current?.requestFullscreen();
|
|
@@ -43420,8 +43497,7 @@ class PhetSimulation extends React__namespace.Component {
|
|
|
43420
43497
|
marginTop: 5,
|
|
43421
43498
|
marginBottom: 5,
|
|
43422
43499
|
alignSelf: "flex-end"
|
|
43423
|
-
}
|
|
43424
|
-
disabled: this.state.url === null
|
|
43500
|
+
}
|
|
43425
43501
|
}));
|
|
43426
43502
|
}
|
|
43427
43503
|
}
|
|
@@ -44972,7 +45048,7 @@ const init = function (options) {
|
|
|
44972
45048
|
|
|
44973
45049
|
// This file is processed by a Rollup plugin (replace) to inject the production
|
|
44974
45050
|
const libName = "@khanacademy/perseus";
|
|
44975
|
-
const libVersion = "33.1
|
|
45051
|
+
const libVersion = "33.2.1";
|
|
44976
45052
|
perseusCore.addLibraryVersionToPerseusDebug(libName, libVersion);
|
|
44977
45053
|
|
|
44978
45054
|
const apiVersion = {
|