@khanacademy/perseus 48.2.0 → 49.0.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/index.js
CHANGED
|
@@ -8993,13 +8993,10 @@ const reactRootCache = new WeakMap();
|
|
|
8993
8993
|
*/
|
|
8994
8994
|
function render(element, container) {
|
|
8995
8995
|
/**
|
|
8996
|
-
* `RenderStateRoot` is responsible for tracking whether it's
|
|
8997
|
-
*
|
|
8998
|
-
*
|
|
8999
|
-
*
|
|
9000
|
-
* high up in the render tree as possible to ensure that any
|
|
9001
|
-
* components using that hook or those components will function
|
|
9002
|
-
* correctly.
|
|
8996
|
+
* `RenderStateRoot` is responsible for tracking whether it's the initial
|
|
8997
|
+
* render or subsequent renders. It's used by `WithSSRPlaceholder`. We're
|
|
8998
|
+
* placing it as high up in the render tree as possible to ensure that any
|
|
8999
|
+
* components using that hook or those components will function correctly.
|
|
9003
9000
|
*/
|
|
9004
9001
|
const children = /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.RenderStateRoot, {
|
|
9005
9002
|
throwIfNested: false
|
|
@@ -27638,10 +27635,7 @@ class Dropdown extends React__namespace.Component {
|
|
|
27638
27635
|
value: String(i + 1),
|
|
27639
27636
|
label: choice
|
|
27640
27637
|
}))];
|
|
27641
|
-
return /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.
|
|
27642
|
-
scope: "dropdown-widget",
|
|
27643
|
-
mockOnFirstRender: true
|
|
27644
|
-
}, ids => /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View
|
|
27638
|
+
return /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.Id, null, dropdownId => /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View
|
|
27645
27639
|
// NOTE(jared): These are required to prevent weird behavior
|
|
27646
27640
|
// When there's a dropdown in a zoomable table.
|
|
27647
27641
|
, {
|
|
@@ -27653,9 +27647,9 @@ class Dropdown extends React__namespace.Component {
|
|
|
27653
27647
|
}
|
|
27654
27648
|
}, this.props.visibleLabel && /*#__PURE__*/React__namespace.createElement(wonderBlocksTypography.LabelLarge, {
|
|
27655
27649
|
tag: "label",
|
|
27656
|
-
htmlFor:
|
|
27650
|
+
htmlFor: dropdownId
|
|
27657
27651
|
}, this.props.visibleLabel), /*#__PURE__*/React__namespace.createElement(wonderBlocksDropdown.SingleSelect, {
|
|
27658
|
-
id:
|
|
27652
|
+
id: dropdownId,
|
|
27659
27653
|
placeholder: "",
|
|
27660
27654
|
onChange: value => this._handleChange(parseInt(value)),
|
|
27661
27655
|
selectedValue: String(this.props.selected),
|
|
@@ -27775,12 +27769,9 @@ class Explanation extends React__namespace.Component {
|
|
|
27775
27769
|
"white-space": "normal"
|
|
27776
27770
|
};
|
|
27777
27771
|
const contentStyling = [styles$k.content, this.state.expanded ? styles$k.contentExpanded : styles$k.contentCollapsed, allowTransition && (this.state.expanded ? styles$k.transitionExpanded : styles$k.transitionCollapsed)];
|
|
27778
|
-
return /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.
|
|
27779
|
-
mockOnFirstRender: true,
|
|
27780
|
-
scope: "explanation-widget"
|
|
27781
|
-
}, ids => /*#__PURE__*/React__namespace.createElement(React__namespace.Fragment, null, /*#__PURE__*/React__namespace.createElement(Button__default["default"], {
|
|
27772
|
+
return /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.Id, null, contentId => /*#__PURE__*/React__namespace.createElement(React__namespace.Fragment, null, /*#__PURE__*/React__namespace.createElement(Button__default["default"], {
|
|
27782
27773
|
"aria-expanded": this.state.expanded,
|
|
27783
|
-
"aria-controls":
|
|
27774
|
+
"aria-controls": contentId,
|
|
27784
27775
|
endIcon: caretIcon,
|
|
27785
27776
|
kind: "tertiary",
|
|
27786
27777
|
labelStyle: labelStyle,
|
|
@@ -27788,7 +27779,7 @@ class Explanation extends React__namespace.Component {
|
|
|
27788
27779
|
size: "small",
|
|
27789
27780
|
style: buttonStyleOverrides
|
|
27790
27781
|
}, promptText), /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, {
|
|
27791
|
-
id:
|
|
27782
|
+
id: contentId,
|
|
27792
27783
|
style: contentStyling,
|
|
27793
27784
|
"aria-hidden": !this.state.expanded,
|
|
27794
27785
|
testId: "content-container"
|
|
@@ -32988,6 +32979,20 @@ const getIntersectionOfRayWithBox = (initialPoint, throughPoint, box) => {
|
|
|
32988
32979
|
function isBetween(x, low, high) {
|
|
32989
32980
|
return x >= low && x <= high;
|
|
32990
32981
|
}
|
|
32982
|
+
function getArrayWithoutDuplicates(array) {
|
|
32983
|
+
const returnArray = [];
|
|
32984
|
+
for (const coordPair of array) {
|
|
32985
|
+
if (
|
|
32986
|
+
// Check if the coordPair is not already in the returnArray
|
|
32987
|
+
!returnArray.some(_ref => {
|
|
32988
|
+
let [x, y] = _ref;
|
|
32989
|
+
return x === coordPair[0] && y === coordPair[1];
|
|
32990
|
+
})) {
|
|
32991
|
+
returnArray.push(coordPair);
|
|
32992
|
+
}
|
|
32993
|
+
}
|
|
32994
|
+
return returnArray;
|
|
32995
|
+
}
|
|
32991
32996
|
|
|
32992
32997
|
const LockedLine = props => {
|
|
32993
32998
|
const {
|
|
@@ -34414,6 +34419,13 @@ function getGradableGraph(state, initialGraph) {
|
|
|
34414
34419
|
};
|
|
34415
34420
|
}
|
|
34416
34421
|
if (state.type === "polygon" && initialGraph.type === "polygon") {
|
|
34422
|
+
// Unless the polygon is closed it is not considered score-able.
|
|
34423
|
+
if (state.numSides === "unlimited" && !state.closedPolygon) {
|
|
34424
|
+
return {
|
|
34425
|
+
...initialGraph,
|
|
34426
|
+
coords: null
|
|
34427
|
+
};
|
|
34428
|
+
}
|
|
34417
34429
|
return {
|
|
34418
34430
|
...initialGraph,
|
|
34419
34431
|
coords: state.coords
|
|
@@ -34934,6 +34946,15 @@ const PolygonGraph = props => {
|
|
|
34934
34946
|
pointsRef.current[focusedIndex]?.focus();
|
|
34935
34947
|
}
|
|
34936
34948
|
}, [props.graphState.focusedPointIndex, pointsRef]);
|
|
34949
|
+
|
|
34950
|
+
// If the unlimited polygon is rendered with 3 or more coordinates
|
|
34951
|
+
// Close the polygon, but only on first render.
|
|
34952
|
+
React__namespace.useEffect(() => {
|
|
34953
|
+
if (numSides === "unlimited" && props.graphState.coords.length > 2) {
|
|
34954
|
+
dispatch(actions.polygon.closePolygon());
|
|
34955
|
+
}
|
|
34956
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
34957
|
+
}, []);
|
|
34937
34958
|
const statefulProps = {
|
|
34938
34959
|
...props,
|
|
34939
34960
|
graphConfig,
|
|
@@ -35077,7 +35098,16 @@ const UnlimitedPolygonGraph = statefulProps => {
|
|
|
35077
35098
|
} = graphConfig;
|
|
35078
35099
|
const widthPx = graphDimensionsInPixels[0];
|
|
35079
35100
|
const heightPx = graphDimensionsInPixels[1];
|
|
35080
|
-
return /*#__PURE__*/React__namespace.createElement(React__namespace.Fragment, null, /*#__PURE__*/React__namespace.createElement(
|
|
35101
|
+
return /*#__PURE__*/React__namespace.createElement(React__namespace.Fragment, null, /*#__PURE__*/React__namespace.createElement(mafs.Polyline, {
|
|
35102
|
+
points: [...points],
|
|
35103
|
+
color: "var(--movable-line-stroke-color)",
|
|
35104
|
+
svgPolylineProps: {
|
|
35105
|
+
strokeWidth: "var(--movable-line-stroke-weight)",
|
|
35106
|
+
style: {
|
|
35107
|
+
fill: "transparent"
|
|
35108
|
+
}
|
|
35109
|
+
}
|
|
35110
|
+
}), /*#__PURE__*/React__namespace.createElement("rect", {
|
|
35081
35111
|
style: {
|
|
35082
35112
|
fill: "rgba(0,0,0,0)",
|
|
35083
35113
|
cursor: "crosshair"
|
|
@@ -35093,15 +35123,6 @@ const UnlimitedPolygonGraph = statefulProps => {
|
|
|
35093
35123
|
const graphCoordinates = pixelsToVectors([[x, y]], graphConfig);
|
|
35094
35124
|
dispatch(actions.polygon.addPoint(graphCoordinates[0]));
|
|
35095
35125
|
}
|
|
35096
|
-
}), /*#__PURE__*/React__namespace.createElement(mafs.Polyline, {
|
|
35097
|
-
points: [...points],
|
|
35098
|
-
color: "var(--movable-line-stroke-color)",
|
|
35099
|
-
svgPolylineProps: {
|
|
35100
|
-
strokeWidth: "var(--movable-line-stroke-weight)",
|
|
35101
|
-
style: {
|
|
35102
|
-
fill: "transparent"
|
|
35103
|
-
}
|
|
35104
|
-
}
|
|
35105
35126
|
}), coords.map((point, i) => /*#__PURE__*/React__namespace.createElement(MovablePoint$1, {
|
|
35106
35127
|
key: i,
|
|
35107
35128
|
point: point,
|
|
@@ -35115,9 +35136,10 @@ const UnlimitedPolygonGraph = statefulProps => {
|
|
|
35115
35136
|
},
|
|
35116
35137
|
onClick: () => {
|
|
35117
35138
|
// If the point being clicked is the first point and
|
|
35118
|
-
// there's enough points to form
|
|
35119
|
-
//
|
|
35120
|
-
|
|
35139
|
+
// there's enough non-duplicated points to form
|
|
35140
|
+
// a polygon (3 or more), close the shape before
|
|
35141
|
+
// setting focus.
|
|
35142
|
+
if (i === 0 && getArrayWithoutDuplicates(coords).length >= 3) {
|
|
35121
35143
|
dispatch(actions.polygon.closePolygon());
|
|
35122
35144
|
}
|
|
35123
35145
|
dispatch(actions.polygon.clickPoint(i));
|
|
@@ -35736,7 +35758,7 @@ const renderPolygonGraphControls = props => {
|
|
|
35736
35758
|
|
|
35737
35759
|
// We want to disable the closePolygon button when
|
|
35738
35760
|
// there are not enough coords to make a polygon
|
|
35739
|
-
const disableCloseButton = coords.length < 3;
|
|
35761
|
+
const disableCloseButton = getArrayWithoutDuplicates(coords).length < 3;
|
|
35740
35762
|
|
|
35741
35763
|
// If polygon is closed, show open button.
|
|
35742
35764
|
// If polygon is open, show close button.
|
|
@@ -36461,8 +36483,14 @@ function doClickPoint(state, action) {
|
|
|
36461
36483
|
}
|
|
36462
36484
|
function doClosePolygon(state) {
|
|
36463
36485
|
if (isUnlimitedGraphState(state) && state.type === "polygon") {
|
|
36486
|
+
// We want to remove any duplicate points when closing the polygon to
|
|
36487
|
+
// (1) prevent the polygon from sides with length zero, and
|
|
36488
|
+
// (2) make sure the question is can be marked correct if the polygon
|
|
36489
|
+
// LOOKS correct, even if two of the points are at the same coords.
|
|
36490
|
+
const noDupedPoints = getArrayWithoutDuplicates(state.coords);
|
|
36464
36491
|
return {
|
|
36465
36492
|
...state,
|
|
36493
|
+
coords: noDupedPoints,
|
|
36466
36494
|
closedPolygon: true
|
|
36467
36495
|
};
|
|
36468
36496
|
}
|
|
@@ -39251,9 +39279,8 @@ const AnswerChoices = props => {
|
|
|
39251
39279
|
};
|
|
39252
39280
|
|
|
39253
39281
|
const HideAnswersToggle = props => {
|
|
39254
|
-
const
|
|
39255
|
-
const
|
|
39256
|
-
const labelId = idFactory.get("hide-answers-label");
|
|
39282
|
+
const switchId = React.useId();
|
|
39283
|
+
const labelId = React.useId();
|
|
39257
39284
|
const {
|
|
39258
39285
|
strings
|
|
39259
39286
|
} = usePerseusI18n();
|
|
@@ -39296,7 +39323,7 @@ const AnswerPill = props => {
|
|
|
39296
39323
|
focused,
|
|
39297
39324
|
hovered
|
|
39298
39325
|
} = props;
|
|
39299
|
-
const
|
|
39326
|
+
const pillId = React.useId();
|
|
39300
39327
|
const {
|
|
39301
39328
|
strings
|
|
39302
39329
|
} = usePerseusI18n();
|
|
@@ -39325,7 +39352,7 @@ const AnswerPill = props => {
|
|
|
39325
39352
|
return /*#__PURE__*/React__namespace.createElement(Pill__default["default"], {
|
|
39326
39353
|
size: "large",
|
|
39327
39354
|
kind: "accent",
|
|
39328
|
-
id:
|
|
39355
|
+
id: pillId,
|
|
39329
39356
|
onClick: correct ? undefined : onClick,
|
|
39330
39357
|
ref: ref,
|
|
39331
39358
|
style: [style, popperStyle, styles$b.pill, correct && styles$b.correct, incorrect && styles$b.incorrect, (focused || hovered) && BringToFront]
|
|
@@ -45643,7 +45670,7 @@ const init = function () {
|
|
|
45643
45670
|
|
|
45644
45671
|
// This file is processed by a Rollup plugin (replace) to inject the production
|
|
45645
45672
|
const libName = "@khanacademy/perseus";
|
|
45646
|
-
const libVersion = "
|
|
45673
|
+
const libVersion = "49.0.1";
|
|
45647
45674
|
perseusCore.addLibraryVersionToPerseusDebug(libName, libVersion);
|
|
45648
45675
|
|
|
45649
45676
|
const apiVersion = {
|