@khanacademy/perseus 21.2.2 → 21.3.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.css +50 -3
- package/dist/es/index.js +77 -56
- package/dist/es/index.js.map +1 -1
- package/dist/index.css +50 -3
- package/dist/index.js +76 -55
- package/dist/index.js.map +1 -1
- package/dist/perseus-api.d.ts +9 -1
- package/dist/perseus-types.d.ts +0 -21
- package/dist/server-item-renderer.d.ts +9 -1
- package/dist/strings.js +0 -4
- package/dist/types.d.ts +11 -1
- package/dist/widgets/expression.d.ts +54 -6
- package/dist/widgets/interactive-graphs/index.d.ts +1 -1
- package/dist/widgets/interactive-graphs/mafs-graph.d.ts +9 -4
- package/dist/widgets/label-image.d.ts +18 -2
- package/package.json +1 -1
- package/dist/widgets/lights-puzzle.d.ts +0 -53
- package/dist/widgets/reaction-diagram.d.ts +0 -42
package/dist/es/index.css
CHANGED
|
@@ -4291,9 +4291,13 @@ html body .mq-editable-field .mq-selection .mq-nthroot-container * {
|
|
|
4291
4291
|
--movable-line-stroke-weight-active: 4px;
|
|
4292
4292
|
}
|
|
4293
4293
|
|
|
4294
|
-
.MafsView
|
|
4294
|
+
.MafsView > svg {
|
|
4295
|
+
/* Chrome/Safari bugfix for LEMS-1906 */
|
|
4296
|
+
display: block;
|
|
4297
|
+
}
|
|
4298
|
+
|
|
4299
|
+
.MafsView .movable-line:hover,
|
|
4295
4300
|
.movable-dragging {
|
|
4296
|
-
outline: none;
|
|
4297
4301
|
--movable-line-stroke-weight: var(--movable-line-stroke-weight-active);
|
|
4298
4302
|
}
|
|
4299
4303
|
|
|
@@ -4302,6 +4306,36 @@ html body .mq-editable-field .mq-selection .mq-nthroot-container * {
|
|
|
4302
4306
|
outline: none;
|
|
4303
4307
|
}
|
|
4304
4308
|
|
|
4309
|
+
.MafsView
|
|
4310
|
+
.movable-line
|
|
4311
|
+
:is(.movable-line-focus-outline, .movable-line-focus-outline-gap) {
|
|
4312
|
+
stroke: transparent;
|
|
4313
|
+
}
|
|
4314
|
+
|
|
4315
|
+
.MafsView .movable-line:focus-visible .movable-line-focus-outline {
|
|
4316
|
+
stroke: var(--mafs-blue);
|
|
4317
|
+
stroke-width: 10px;
|
|
4318
|
+
}
|
|
4319
|
+
|
|
4320
|
+
.MafsView .movable-line:focus-visible .movable-line-focus-outline-gap {
|
|
4321
|
+
stroke: white;
|
|
4322
|
+
stroke-width: 6px;
|
|
4323
|
+
}
|
|
4324
|
+
|
|
4325
|
+
.MafsView .movable-point {
|
|
4326
|
+
cursor: grab;
|
|
4327
|
+
touch-action: none;
|
|
4328
|
+
outline: none;
|
|
4329
|
+
}
|
|
4330
|
+
|
|
4331
|
+
.MafsView .movable-point.movable-point--dragging {
|
|
4332
|
+
cursor: grabbing;
|
|
4333
|
+
}
|
|
4334
|
+
|
|
4335
|
+
.MafsView .movable-point.movable-point--dragging .movable-point-halo {
|
|
4336
|
+
opacity: 0;
|
|
4337
|
+
}
|
|
4338
|
+
|
|
4305
4339
|
.MafsView .movable-point-hitbox {
|
|
4306
4340
|
fill: transparent;
|
|
4307
4341
|
}
|
|
@@ -4313,7 +4347,9 @@ html body .mq-editable-field .mq-selection .mq-nthroot-container * {
|
|
|
4313
4347
|
.movable-point-halo,
|
|
4314
4348
|
.movable-point-focus-outline
|
|
4315
4349
|
) {
|
|
4316
|
-
transition:
|
|
4350
|
+
transition:
|
|
4351
|
+
r 0.15s ease-out,
|
|
4352
|
+
opacity 0.15s ease-out;
|
|
4317
4353
|
}
|
|
4318
4354
|
|
|
4319
4355
|
.MafsView .movable-point-center {
|
|
@@ -4372,3 +4408,14 @@ html body .mq-editable-field .mq-selection .mq-nthroot-container * {
|
|
|
4372
4408
|
.MafsView .movable-point:focus-visible .movable-point-focus-outline {
|
|
4373
4409
|
visibility: visible;
|
|
4374
4410
|
}
|
|
4411
|
+
|
|
4412
|
+
@font-face {
|
|
4413
|
+
font-family: Mafs-MJXTEX;
|
|
4414
|
+
src: url("https://cdn.kastatic.org/fonts/mathjax/MathJax_Main-Regular.woff")
|
|
4415
|
+
format("woff");
|
|
4416
|
+
}
|
|
4417
|
+
|
|
4418
|
+
.MafsView .axis-ticks text {
|
|
4419
|
+
font-size: 14px;
|
|
4420
|
+
font-family: "Mafs-MJXTEX";
|
|
4421
|
+
}
|
package/dist/es/index.js
CHANGED
|
@@ -7,7 +7,7 @@ import * as i18n from '@khanacademy/wonder-blocks-i18n';
|
|
|
7
7
|
import Tooltip$1 from '@khanacademy/wonder-blocks-tooltip';
|
|
8
8
|
import classNames from 'classnames';
|
|
9
9
|
import * as React from 'react';
|
|
10
|
-
import React__default, { useState, useEffect, useRef, createContext } from 'react';
|
|
10
|
+
import React__default, { useState, useEffect, useRef, createContext, useImperativeHandle } from 'react';
|
|
11
11
|
import _, { debounce as debounce$1 } from 'underscore';
|
|
12
12
|
import Clickable from '@khanacademy/wonder-blocks-clickable';
|
|
13
13
|
import { Popover, PopoverContentCore, PopoverContent } from '@khanacademy/wonder-blocks-popover';
|
|
@@ -28239,14 +28239,6 @@ function changeRange(range) {
|
|
|
28239
28239
|
};
|
|
28240
28240
|
}
|
|
28241
28241
|
|
|
28242
|
-
const GraphStateContext = /*#__PURE__*/createContext({
|
|
28243
|
-
state: {},
|
|
28244
|
-
dispatch: () => {}
|
|
28245
|
-
});
|
|
28246
|
-
function useGraphState() {
|
|
28247
|
-
return React__default.useContext(GraphStateContext);
|
|
28248
|
-
}
|
|
28249
|
-
|
|
28250
28242
|
/**
|
|
28251
28243
|
* 44 is touch best practice and AAA compliant for WCAG
|
|
28252
28244
|
* https://www.w3.org/WAI/WCAG21/Understanding/target-size.html
|
|
@@ -28332,9 +28324,6 @@ const getLines = points => points.map((point, i) => {
|
|
|
28332
28324
|
|
|
28333
28325
|
const defaultStroke = "var(--movable-line-stroke-color)";
|
|
28334
28326
|
const MovableLine = props => {
|
|
28335
|
-
const {
|
|
28336
|
-
state
|
|
28337
|
-
} = useGraphState();
|
|
28338
28327
|
const {
|
|
28339
28328
|
start,
|
|
28340
28329
|
end,
|
|
@@ -28359,12 +28348,13 @@ const MovableLine = props => {
|
|
|
28359
28348
|
onMove: newPoint => {
|
|
28360
28349
|
onMove(vec.sub(newPoint, midpoint));
|
|
28361
28350
|
},
|
|
28362
|
-
constrain: p =>
|
|
28351
|
+
constrain: p => p
|
|
28363
28352
|
});
|
|
28364
28353
|
return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("g", {
|
|
28365
28354
|
ref: line,
|
|
28366
28355
|
tabIndex: 0,
|
|
28367
28356
|
className: "movable-line",
|
|
28357
|
+
"data-test-id": "movable-line",
|
|
28368
28358
|
style: {
|
|
28369
28359
|
cursor: dragging ? "grabbing" : "grab"
|
|
28370
28360
|
}
|
|
@@ -28375,6 +28365,16 @@ const MovableLine = props => {
|
|
|
28375
28365
|
stroke: "transparent",
|
|
28376
28366
|
strokeWidth: TARGET_SIZE
|
|
28377
28367
|
}
|
|
28368
|
+
}), /*#__PURE__*/React.createElement(SVGLine, {
|
|
28369
|
+
start: startPtPx,
|
|
28370
|
+
end: endPtPx,
|
|
28371
|
+
className: "movable-line-focus-outline",
|
|
28372
|
+
style: {}
|
|
28373
|
+
}), /*#__PURE__*/React.createElement(SVGLine, {
|
|
28374
|
+
start: startPtPx,
|
|
28375
|
+
end: endPtPx,
|
|
28376
|
+
className: "movable-line-focus-outline-gap",
|
|
28377
|
+
style: {}
|
|
28378
28378
|
}), /*#__PURE__*/React.createElement(SVGLine, {
|
|
28379
28379
|
start: startPtPx,
|
|
28380
28380
|
end: endPtPx,
|
|
@@ -28382,7 +28382,8 @@ const MovableLine = props => {
|
|
|
28382
28382
|
stroke,
|
|
28383
28383
|
strokeWidth: "var(--movable-line-stroke-weight)"
|
|
28384
28384
|
},
|
|
28385
|
-
dragging: dragging
|
|
28385
|
+
dragging: dragging,
|
|
28386
|
+
testId: "movable-line__line"
|
|
28386
28387
|
})), startExtend && /*#__PURE__*/React.createElement(Vector, {
|
|
28387
28388
|
tail: start,
|
|
28388
28389
|
tip: startExtend,
|
|
@@ -28398,18 +28399,30 @@ function SVGLine(props) {
|
|
|
28398
28399
|
start,
|
|
28399
28400
|
end,
|
|
28400
28401
|
style,
|
|
28401
|
-
dragging
|
|
28402
|
+
dragging,
|
|
28403
|
+
className,
|
|
28404
|
+
testId
|
|
28402
28405
|
} = props;
|
|
28406
|
+
const draggingClass = dragging ? "movable-dragging" : "";
|
|
28403
28407
|
return /*#__PURE__*/React.createElement("line", {
|
|
28404
28408
|
x1: start[0],
|
|
28405
28409
|
y1: start[1],
|
|
28406
28410
|
x2: end[0],
|
|
28407
28411
|
y2: end[1],
|
|
28408
28412
|
style: style,
|
|
28409
|
-
className:
|
|
28413
|
+
className: `${className} ${draggingClass}`,
|
|
28414
|
+
"data-test-id": testId
|
|
28410
28415
|
});
|
|
28411
28416
|
}
|
|
28412
28417
|
|
|
28418
|
+
const GraphStateContext = /*#__PURE__*/createContext({
|
|
28419
|
+
state: {},
|
|
28420
|
+
dispatch: () => {}
|
|
28421
|
+
});
|
|
28422
|
+
function useGraphState() {
|
|
28423
|
+
return React__default.useContext(GraphStateContext);
|
|
28424
|
+
}
|
|
28425
|
+
|
|
28413
28426
|
// The hitbox size of 48px by 48px is preserved from the legacy interactive
|
|
28414
28427
|
// graph.
|
|
28415
28428
|
const hitboxSizePx = 48;
|
|
@@ -28431,17 +28444,16 @@ const StyledMovablePoint = props => {
|
|
|
28431
28444
|
onMove,
|
|
28432
28445
|
constrain: p => snap(state.snapStep, p)
|
|
28433
28446
|
});
|
|
28447
|
+
const pointClasses = `movable-point ${dragging ? "movable-point--dragging" : ""}`;
|
|
28434
28448
|
const [[x, y]] = useTransform(point);
|
|
28435
28449
|
return /*#__PURE__*/React.createElement("g", {
|
|
28436
28450
|
ref: hitboxRef,
|
|
28437
|
-
className:
|
|
28451
|
+
className: pointClasses,
|
|
28438
28452
|
tabIndex: 0,
|
|
28439
28453
|
style: {
|
|
28440
|
-
cursor: dragging ? "grabbing" : "grab",
|
|
28441
|
-
touchAction: "none",
|
|
28442
|
-
outline: "none",
|
|
28443
28454
|
"--movable-point-color": color$1
|
|
28444
|
-
}
|
|
28455
|
+
},
|
|
28456
|
+
"data-test-id": "movable-point"
|
|
28445
28457
|
}, /*#__PURE__*/React.createElement("circle", {
|
|
28446
28458
|
className: "movable-point-hitbox",
|
|
28447
28459
|
r: hitboxSizePx / 2,
|
|
@@ -28465,7 +28477,8 @@ const StyledMovablePoint = props => {
|
|
|
28465
28477
|
cy: y,
|
|
28466
28478
|
style: {
|
|
28467
28479
|
fill: color$1
|
|
28468
|
-
}
|
|
28480
|
+
},
|
|
28481
|
+
"data-test-id": "movable-point__center"
|
|
28469
28482
|
}));
|
|
28470
28483
|
};
|
|
28471
28484
|
|
|
@@ -28922,7 +28935,13 @@ const YGridTick = ({
|
|
|
28922
28935
|
x2: xPosition + tickSize / 2,
|
|
28923
28936
|
y2: yPosition,
|
|
28924
28937
|
style: tickStyle
|
|
28925
|
-
})
|
|
28938
|
+
}), y !== -1 && /*#__PURE__*/React.createElement("text", {
|
|
28939
|
+
height: 20,
|
|
28940
|
+
width: 50,
|
|
28941
|
+
textAnchor: "end",
|
|
28942
|
+
x: xPosition - 10,
|
|
28943
|
+
y: yPosition + 5
|
|
28944
|
+
}, y.toString()));
|
|
28926
28945
|
};
|
|
28927
28946
|
const XGridTick = ({
|
|
28928
28947
|
x
|
|
@@ -28937,13 +28956,23 @@ const XGridTick = ({
|
|
|
28937
28956
|
x2: xPosition,
|
|
28938
28957
|
y2: yPosition - tickSize / 2,
|
|
28939
28958
|
style: tickStyle
|
|
28940
|
-
})
|
|
28959
|
+
}), x !== -1 && /*#__PURE__*/React.createElement("text", {
|
|
28960
|
+
height: 20,
|
|
28961
|
+
width: 50,
|
|
28962
|
+
textAnchor: "middle",
|
|
28963
|
+
x: xPosition,
|
|
28964
|
+
y: yPosition + 25
|
|
28965
|
+
}, x.toString()));
|
|
28941
28966
|
};
|
|
28942
28967
|
function generateTickLocations(tickStep, min, max) {
|
|
28943
28968
|
const ticks = [];
|
|
28969
|
+
|
|
28970
|
+
// Add ticks in the positive direction
|
|
28944
28971
|
for (let i = 0 + tickStep; i < max; i += tickStep) {
|
|
28945
28972
|
ticks.push(i);
|
|
28946
28973
|
}
|
|
28974
|
+
|
|
28975
|
+
// Add ticks in the negative direction
|
|
28947
28976
|
for (let i = 0 - tickStep; i > min; i -= tickStep) {
|
|
28948
28977
|
ticks.push(i);
|
|
28949
28978
|
}
|
|
@@ -28972,24 +29001,6 @@ const AxisTicks = props => {
|
|
|
28972
29001
|
}));
|
|
28973
29002
|
};
|
|
28974
29003
|
|
|
28975
|
-
/**
|
|
28976
|
-
* lineLabelText get the text that should
|
|
28977
|
-
* be displayed for a specific tick place
|
|
28978
|
-
*
|
|
28979
|
-
* @param {number} n the tick number
|
|
28980
|
-
* @param {number} tickStep how frequently a label should appear
|
|
28981
|
-
* @param {vec.Vector2} range the min/max range on the axis
|
|
28982
|
-
*/
|
|
28983
|
-
const lineLabelText = (n, tickStep, range) => {
|
|
28984
|
-
const [min, max] = range;
|
|
28985
|
-
const isOnStep = n % tickStep === 0;
|
|
28986
|
-
const isNegativeOne = n === -1;
|
|
28987
|
-
const isMin = n === min;
|
|
28988
|
-
const isMax = n === max;
|
|
28989
|
-
const shouldRender = isOnStep && !isNegativeOne && !isMin && !isMax;
|
|
28990
|
-
return shouldRender ? `${n}` : "";
|
|
28991
|
-
};
|
|
28992
|
-
|
|
28993
29004
|
/**
|
|
28994
29005
|
* axisOptions determine axis options for Mafs
|
|
28995
29006
|
*
|
|
@@ -29001,12 +29012,10 @@ const lineLabelText = (n, tickStep, range) => {
|
|
|
29001
29012
|
* @param {number} axisIndex which axis we're getting options for
|
|
29002
29013
|
*/
|
|
29003
29014
|
const axisOptions = (props, axisIndex) => {
|
|
29004
|
-
const axisStep = props.tickStep[axisIndex];
|
|
29005
|
-
const axisRange = props.range[axisIndex];
|
|
29006
29015
|
return {
|
|
29007
29016
|
axis: props.markings === "graph",
|
|
29008
29017
|
lines: props.gridStep[axisIndex],
|
|
29009
|
-
labels:
|
|
29018
|
+
labels: false
|
|
29010
29019
|
};
|
|
29011
29020
|
};
|
|
29012
29021
|
const Grid = props => {
|
|
@@ -30234,9 +30243,22 @@ const renderGraph = props => {
|
|
|
30234
30243
|
return new UnreachableCaseError(type);
|
|
30235
30244
|
}
|
|
30236
30245
|
};
|
|
30237
|
-
const
|
|
30238
|
-
const [width, height] = props.box;
|
|
30246
|
+
const StatefulMafsGraph = /*#__PURE__*/React.forwardRef((props, ref) => {
|
|
30239
30247
|
const [state, dispatch] = React.useReducer(interactiveGraphReducer, props, initializeGraphState);
|
|
30248
|
+
useImperativeHandle(ref, () => ({
|
|
30249
|
+
getUserInput: () => getGradableGraph(state, props.graph)
|
|
30250
|
+
}));
|
|
30251
|
+
return /*#__PURE__*/React.createElement(MafsGraph, _extends({
|
|
30252
|
+
state: state,
|
|
30253
|
+
dispatch: dispatch
|
|
30254
|
+
}, props));
|
|
30255
|
+
});
|
|
30256
|
+
const MafsGraph = props => {
|
|
30257
|
+
const {
|
|
30258
|
+
state,
|
|
30259
|
+
dispatch
|
|
30260
|
+
} = props;
|
|
30261
|
+
const [width, height] = props.box;
|
|
30240
30262
|
const prevState = useRef(state);
|
|
30241
30263
|
useEffect(() => {
|
|
30242
30264
|
if (prevState.current !== state) {
|
|
@@ -30251,16 +30273,13 @@ const MafsGraph = /*#__PURE__*/React.forwardRef((props, ref) => {
|
|
|
30251
30273
|
const [xSnap, ySnap] = props.snapStep;
|
|
30252
30274
|
useEffect(() => {
|
|
30253
30275
|
dispatch(changeSnapStep([xSnap, ySnap]));
|
|
30254
|
-
}, [xSnap, ySnap]);
|
|
30276
|
+
}, [dispatch, xSnap, ySnap]);
|
|
30255
30277
|
|
|
30256
30278
|
// Destructuring first to keep useEffect from making excess calls
|
|
30257
30279
|
const [[xMinRange, xMaxRange], [yMinRange, yMaxRange]] = props.range;
|
|
30258
30280
|
useEffect(() => {
|
|
30259
30281
|
dispatch(changeRange([[xMinRange, xMaxRange], [yMinRange, yMaxRange]]));
|
|
30260
|
-
}, [xMinRange, xMaxRange, yMinRange, yMaxRange]);
|
|
30261
|
-
React.useImperativeHandle(ref, () => ({
|
|
30262
|
-
getUserInput: () => getGradableGraph(state, props.graph)
|
|
30263
|
-
}));
|
|
30282
|
+
}, [dispatch, xMinRange, xMaxRange, yMinRange, yMaxRange]);
|
|
30264
30283
|
return /*#__PURE__*/React.createElement(GraphStateContext.Provider, {
|
|
30265
30284
|
value: {
|
|
30266
30285
|
state,
|
|
@@ -30270,7 +30289,9 @@ const MafsGraph = /*#__PURE__*/React.forwardRef((props, ref) => {
|
|
|
30270
30289
|
style: {
|
|
30271
30290
|
width,
|
|
30272
30291
|
height,
|
|
30273
|
-
position: "relative"
|
|
30292
|
+
position: "relative",
|
|
30293
|
+
padding: "25px 25px 0 0",
|
|
30294
|
+
boxSizing: "content-box"
|
|
30274
30295
|
}
|
|
30275
30296
|
}, /*#__PURE__*/React.createElement(LegacyGrid, {
|
|
30276
30297
|
box: props.box,
|
|
@@ -30304,7 +30325,7 @@ const MafsGraph = /*#__PURE__*/React.forwardRef((props, ref) => {
|
|
|
30304
30325
|
state,
|
|
30305
30326
|
dispatch
|
|
30306
30327
|
})))));
|
|
30307
|
-
}
|
|
30328
|
+
};
|
|
30308
30329
|
|
|
30309
30330
|
const {
|
|
30310
30331
|
DeprecationMixin
|
|
@@ -31608,7 +31629,7 @@ class InteractiveGraph extends React.Component {
|
|
|
31608
31629
|
const box = getInteractiveBoxFromSizeClass(this.props.containerSizeClass);
|
|
31609
31630
|
const gridStep = this.props.gridStep || Util.getGridStep(this.props.range, this.props.step, box[0]);
|
|
31610
31631
|
const snapStep = this.props.snapStep || Util.snapStepFromGridStep(gridStep);
|
|
31611
|
-
return /*#__PURE__*/React.createElement(
|
|
31632
|
+
return /*#__PURE__*/React.createElement(StatefulMafsGraph, _extends({}, this.props, {
|
|
31612
31633
|
ref: this.mafsRef,
|
|
31613
31634
|
gridStep: gridStep,
|
|
31614
31635
|
snapStep: snapStep,
|
|
@@ -42347,7 +42368,7 @@ const init = function init(options) {
|
|
|
42347
42368
|
|
|
42348
42369
|
// This file is processed by a Rollup plugin (replace) to inject the production
|
|
42349
42370
|
const libName = "@khanacademy/perseus";
|
|
42350
|
-
const libVersion = "21.
|
|
42371
|
+
const libVersion = "21.3.1";
|
|
42351
42372
|
addLibraryVersionToPerseusDebug(libName, libVersion);
|
|
42352
42373
|
|
|
42353
42374
|
const apiVersion = {
|