@khanacademy/perseus 49.0.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/es/index.js +108 -100
- package/dist/es/index.js.map +1 -1
- package/dist/index.js +110 -98
- package/dist/index.js.map +1 -1
- package/dist/widgets/interactive-graphs/graphs/utils.d.ts +2 -0
- package/package.json +1 -1
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,41 +27635,33 @@ class Dropdown extends React__namespace.Component {
|
|
|
27638
27635
|
value: String(i + 1),
|
|
27639
27636
|
label: choice
|
|
27640
27637
|
}))];
|
|
27641
|
-
return (
|
|
27642
|
-
|
|
27643
|
-
|
|
27644
|
-
|
|
27645
|
-
|
|
27646
|
-
|
|
27647
|
-
|
|
27648
|
-
|
|
27649
|
-
|
|
27650
|
-
|
|
27651
|
-
|
|
27652
|
-
|
|
27653
|
-
|
|
27654
|
-
|
|
27655
|
-
|
|
27656
|
-
|
|
27657
|
-
|
|
27658
|
-
|
|
27659
|
-
|
|
27660
|
-
|
|
27661
|
-
|
|
27662
|
-
|
|
27663
|
-
|
|
27664
|
-
|
|
27665
|
-
|
|
27666
|
-
|
|
27667
|
-
|
|
27668
|
-
// This is currently necessary for SRs to read the labels properly.
|
|
27669
|
-
// However, WB is working on a change to add the "combobox" role to
|
|
27670
|
-
// all dropdowns.
|
|
27671
|
-
// See https://khanacademy.atlassian.net/browse/WB-1671
|
|
27672
|
-
,
|
|
27673
|
-
role: "combobox"
|
|
27674
|
-
}, children)))
|
|
27675
|
-
);
|
|
27638
|
+
return /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.Id, null, dropdownId => /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View
|
|
27639
|
+
// NOTE(jared): These are required to prevent weird behavior
|
|
27640
|
+
// When there's a dropdown in a zoomable table.
|
|
27641
|
+
, {
|
|
27642
|
+
onClick: e => {
|
|
27643
|
+
e.stopPropagation();
|
|
27644
|
+
},
|
|
27645
|
+
onTouchStart: e => {
|
|
27646
|
+
e.stopPropagation();
|
|
27647
|
+
}
|
|
27648
|
+
}, this.props.visibleLabel && /*#__PURE__*/React__namespace.createElement(wonderBlocksTypography.LabelLarge, {
|
|
27649
|
+
tag: "label",
|
|
27650
|
+
htmlFor: dropdownId
|
|
27651
|
+
}, this.props.visibleLabel), /*#__PURE__*/React__namespace.createElement(wonderBlocksDropdown.SingleSelect, {
|
|
27652
|
+
id: dropdownId,
|
|
27653
|
+
placeholder: "",
|
|
27654
|
+
onChange: value => this._handleChange(parseInt(value)),
|
|
27655
|
+
selectedValue: String(this.props.selected),
|
|
27656
|
+
disabled: this.props.apiOptions.readOnly,
|
|
27657
|
+
"aria-label": this.props.ariaLabel || this.props.visibleLabel || this.context.strings.selectAnAnswer
|
|
27658
|
+
// This is currently necessary for SRs to read the labels properly.
|
|
27659
|
+
// However, WB is working on a change to add the "combobox" role to
|
|
27660
|
+
// all dropdowns.
|
|
27661
|
+
// See https://khanacademy.atlassian.net/browse/WB-1671
|
|
27662
|
+
,
|
|
27663
|
+
role: "combobox"
|
|
27664
|
+
}, children)));
|
|
27676
27665
|
}
|
|
27677
27666
|
}
|
|
27678
27667
|
const optionsTransform = widgetOptions => {
|
|
@@ -27780,37 +27769,29 @@ class Explanation extends React__namespace.Component {
|
|
|
27780
27769
|
"white-space": "normal"
|
|
27781
27770
|
};
|
|
27782
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)];
|
|
27783
|
-
return (
|
|
27784
|
-
|
|
27785
|
-
|
|
27786
|
-
|
|
27787
|
-
|
|
27788
|
-
|
|
27789
|
-
|
|
27790
|
-
|
|
27791
|
-
|
|
27792
|
-
|
|
27793
|
-
|
|
27794
|
-
|
|
27795
|
-
|
|
27796
|
-
|
|
27797
|
-
|
|
27798
|
-
|
|
27799
|
-
|
|
27800
|
-
|
|
27801
|
-
|
|
27802
|
-
|
|
27803
|
-
|
|
27804
|
-
|
|
27805
|
-
|
|
27806
|
-
}, /*#__PURE__*/React__namespace.createElement(Renderer, {
|
|
27807
|
-
apiOptions: this.props.apiOptions,
|
|
27808
|
-
content: this.props.explanation,
|
|
27809
|
-
widgets: this.props.widgets,
|
|
27810
|
-
linterContext: this.props.linterContext,
|
|
27811
|
-
strings: this.context.strings
|
|
27812
|
-
})))))
|
|
27813
|
-
);
|
|
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"], {
|
|
27773
|
+
"aria-expanded": this.state.expanded,
|
|
27774
|
+
"aria-controls": contentId,
|
|
27775
|
+
endIcon: caretIcon,
|
|
27776
|
+
kind: "tertiary",
|
|
27777
|
+
labelStyle: labelStyle,
|
|
27778
|
+
onClick: this._onClick,
|
|
27779
|
+
size: "small",
|
|
27780
|
+
style: buttonStyleOverrides
|
|
27781
|
+
}, promptText), /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, {
|
|
27782
|
+
id: contentId,
|
|
27783
|
+
style: contentStyling,
|
|
27784
|
+
"aria-hidden": !this.state.expanded,
|
|
27785
|
+
testId: "content-container"
|
|
27786
|
+
}, /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, {
|
|
27787
|
+
style: styles$k.contentWrapper
|
|
27788
|
+
}, /*#__PURE__*/React__namespace.createElement(Renderer, {
|
|
27789
|
+
apiOptions: this.props.apiOptions,
|
|
27790
|
+
content: this.props.explanation,
|
|
27791
|
+
widgets: this.props.widgets,
|
|
27792
|
+
linterContext: this.props.linterContext,
|
|
27793
|
+
strings: this.context.strings
|
|
27794
|
+
})))));
|
|
27814
27795
|
}
|
|
27815
27796
|
}
|
|
27816
27797
|
const leftBorderSpacing = 23;
|
|
@@ -32998,6 +32979,20 @@ const getIntersectionOfRayWithBox = (initialPoint, throughPoint, box) => {
|
|
|
32998
32979
|
function isBetween(x, low, high) {
|
|
32999
32980
|
return x >= low && x <= high;
|
|
33000
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
|
+
}
|
|
33001
32996
|
|
|
33002
32997
|
const LockedLine = props => {
|
|
33003
32998
|
const {
|
|
@@ -34424,6 +34419,13 @@ function getGradableGraph(state, initialGraph) {
|
|
|
34424
34419
|
};
|
|
34425
34420
|
}
|
|
34426
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
|
+
}
|
|
34427
34429
|
return {
|
|
34428
34430
|
...initialGraph,
|
|
34429
34431
|
coords: state.coords
|
|
@@ -34944,6 +34946,15 @@ const PolygonGraph = props => {
|
|
|
34944
34946
|
pointsRef.current[focusedIndex]?.focus();
|
|
34945
34947
|
}
|
|
34946
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
|
+
}, []);
|
|
34947
34958
|
const statefulProps = {
|
|
34948
34959
|
...props,
|
|
34949
34960
|
graphConfig,
|
|
@@ -35087,7 +35098,16 @@ const UnlimitedPolygonGraph = statefulProps => {
|
|
|
35087
35098
|
} = graphConfig;
|
|
35088
35099
|
const widthPx = graphDimensionsInPixels[0];
|
|
35089
35100
|
const heightPx = graphDimensionsInPixels[1];
|
|
35090
|
-
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", {
|
|
35091
35111
|
style: {
|
|
35092
35112
|
fill: "rgba(0,0,0,0)",
|
|
35093
35113
|
cursor: "crosshair"
|
|
@@ -35103,15 +35123,6 @@ const UnlimitedPolygonGraph = statefulProps => {
|
|
|
35103
35123
|
const graphCoordinates = pixelsToVectors([[x, y]], graphConfig);
|
|
35104
35124
|
dispatch(actions.polygon.addPoint(graphCoordinates[0]));
|
|
35105
35125
|
}
|
|
35106
|
-
}), /*#__PURE__*/React__namespace.createElement(mafs.Polyline, {
|
|
35107
|
-
points: [...points],
|
|
35108
|
-
color: "var(--movable-line-stroke-color)",
|
|
35109
|
-
svgPolylineProps: {
|
|
35110
|
-
strokeWidth: "var(--movable-line-stroke-weight)",
|
|
35111
|
-
style: {
|
|
35112
|
-
fill: "transparent"
|
|
35113
|
-
}
|
|
35114
|
-
}
|
|
35115
35126
|
}), coords.map((point, i) => /*#__PURE__*/React__namespace.createElement(MovablePoint$1, {
|
|
35116
35127
|
key: i,
|
|
35117
35128
|
point: point,
|
|
@@ -35125,9 +35136,10 @@ const UnlimitedPolygonGraph = statefulProps => {
|
|
|
35125
35136
|
},
|
|
35126
35137
|
onClick: () => {
|
|
35127
35138
|
// If the point being clicked is the first point and
|
|
35128
|
-
// there's enough points to form
|
|
35129
|
-
//
|
|
35130
|
-
|
|
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) {
|
|
35131
35143
|
dispatch(actions.polygon.closePolygon());
|
|
35132
35144
|
}
|
|
35133
35145
|
dispatch(actions.polygon.clickPoint(i));
|
|
@@ -35746,7 +35758,7 @@ const renderPolygonGraphControls = props => {
|
|
|
35746
35758
|
|
|
35747
35759
|
// We want to disable the closePolygon button when
|
|
35748
35760
|
// there are not enough coords to make a polygon
|
|
35749
|
-
const disableCloseButton = coords.length < 3;
|
|
35761
|
+
const disableCloseButton = getArrayWithoutDuplicates(coords).length < 3;
|
|
35750
35762
|
|
|
35751
35763
|
// If polygon is closed, show open button.
|
|
35752
35764
|
// If polygon is open, show close button.
|
|
@@ -36471,8 +36483,14 @@ function doClickPoint(state, action) {
|
|
|
36471
36483
|
}
|
|
36472
36484
|
function doClosePolygon(state) {
|
|
36473
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);
|
|
36474
36491
|
return {
|
|
36475
36492
|
...state,
|
|
36493
|
+
coords: noDupedPoints,
|
|
36476
36494
|
closedPolygon: true
|
|
36477
36495
|
};
|
|
36478
36496
|
}
|
|
@@ -39261,11 +39279,8 @@ const AnswerChoices = props => {
|
|
|
39261
39279
|
};
|
|
39262
39280
|
|
|
39263
39281
|
const HideAnswersToggle = props => {
|
|
39264
|
-
|
|
39265
|
-
|
|
39266
|
-
const idFactory = wonderBlocksCore.useUniqueIdWithMock();
|
|
39267
|
-
const switchId = idFactory.get("hide-answers-toggle");
|
|
39268
|
-
const labelId = idFactory.get("hide-answers-label");
|
|
39282
|
+
const switchId = React.useId();
|
|
39283
|
+
const labelId = React.useId();
|
|
39269
39284
|
const {
|
|
39270
39285
|
strings
|
|
39271
39286
|
} = usePerseusI18n();
|
|
@@ -39308,10 +39323,7 @@ const AnswerPill = props => {
|
|
|
39308
39323
|
focused,
|
|
39309
39324
|
hovered
|
|
39310
39325
|
} = props;
|
|
39311
|
-
|
|
39312
|
-
// TODO(WB-1812, somewhatabstract): Migrate to Id or useId
|
|
39313
|
-
// eslint-disable-next-line no-restricted-syntax
|
|
39314
|
-
const idFactory = wonderBlocksCore.useUniqueIdWithMock();
|
|
39326
|
+
const pillId = React.useId();
|
|
39315
39327
|
const {
|
|
39316
39328
|
strings
|
|
39317
39329
|
} = usePerseusI18n();
|
|
@@ -39340,7 +39352,7 @@ const AnswerPill = props => {
|
|
|
39340
39352
|
return /*#__PURE__*/React__namespace.createElement(Pill__default["default"], {
|
|
39341
39353
|
size: "large",
|
|
39342
39354
|
kind: "accent",
|
|
39343
|
-
id:
|
|
39355
|
+
id: pillId,
|
|
39344
39356
|
onClick: correct ? undefined : onClick,
|
|
39345
39357
|
ref: ref,
|
|
39346
39358
|
style: [style, popperStyle, styles$b.pill, correct && styles$b.correct, incorrect && styles$b.incorrect, (focused || hovered) && BringToFront]
|
|
@@ -45658,7 +45670,7 @@ const init = function () {
|
|
|
45658
45670
|
|
|
45659
45671
|
// This file is processed by a Rollup plugin (replace) to inject the production
|
|
45660
45672
|
const libName = "@khanacademy/perseus";
|
|
45661
|
-
const libVersion = "49.0.
|
|
45673
|
+
const libVersion = "49.0.1";
|
|
45662
45674
|
perseusCore.addLibraryVersionToPerseusDebug(libName, libVersion);
|
|
45663
45675
|
|
|
45664
45676
|
const apiVersion = {
|