@khanacademy/perseus 49.0.2 → 49.1.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 +197 -12
- package/dist/es/index.js.map +1 -1
- package/dist/es/strings.js +97 -1
- package/dist/es/strings.js.map +1 -1
- package/dist/index.js +221 -11
- package/dist/index.js.map +1 -1
- package/dist/strings.d.ts +43 -0
- package/dist/strings.js +117 -0
- package/dist/strings.js.map +1 -1
- package/dist/widgets/interactive-graphs/graphs/components/movable-line.d.ts +7 -2
- package/package.json +10 -10
package/dist/index.js
CHANGED
|
@@ -420,6 +420,70 @@ const mockStrings = {
|
|
|
420
420
|
point4Y
|
|
421
421
|
} = _ref32;
|
|
422
422
|
return `Points on the circle at ${point1X} comma ${point1Y}, ${point2X} comma ${point2Y}, ${point3X} comma ${point3Y}, ${point4X} comma ${point4Y}.`;
|
|
423
|
+
},
|
|
424
|
+
srLinearGraph: "A line on a coordinate plane.",
|
|
425
|
+
srLinearGraphPoints: _ref33 => {
|
|
426
|
+
let {
|
|
427
|
+
point1X,
|
|
428
|
+
point1Y,
|
|
429
|
+
point2X,
|
|
430
|
+
point2Y
|
|
431
|
+
} = _ref33;
|
|
432
|
+
return `The line has two points, point 1 at ${point1X} comma ${point1Y} and point 2 at ${point2X} comma ${point2Y}.`;
|
|
433
|
+
},
|
|
434
|
+
srLinearGraphSlopeIncreasing: "Its slope increases from left to right.",
|
|
435
|
+
srLinearGraphSlopeDecreasing: "Its slope decreases from left to right.",
|
|
436
|
+
srLinearGraphSlopeHorizontal: "Its slope is zero.",
|
|
437
|
+
srLinearGraphSlopeVertical: "Its slope is undefined.",
|
|
438
|
+
srLinearGraphXOnlyIntercept: _ref34 => {
|
|
439
|
+
let {
|
|
440
|
+
xIntercept
|
|
441
|
+
} = _ref34;
|
|
442
|
+
return `The line crosses the X-axis at ${xIntercept} comma 0.`;
|
|
443
|
+
},
|
|
444
|
+
srLinearGraphYOnlyIntercept: _ref35 => {
|
|
445
|
+
let {
|
|
446
|
+
yIntercept
|
|
447
|
+
} = _ref35;
|
|
448
|
+
return `The line crosses the Y-axis at 0 comma ${yIntercept}.`;
|
|
449
|
+
},
|
|
450
|
+
srLinearGraphBothIntercepts: _ref36 => {
|
|
451
|
+
let {
|
|
452
|
+
xIntercept,
|
|
453
|
+
yIntercept
|
|
454
|
+
} = _ref36;
|
|
455
|
+
return `The line crosses the X-axis at ${xIntercept} comma 0 and the Y-axis at 0 comma ${yIntercept}.`;
|
|
456
|
+
},
|
|
457
|
+
srLinearGraphOriginIntercept: "The line crosses the x and y axes at the graph's origin.",
|
|
458
|
+
srAngleSideAtCoordinates: _ref37 => {
|
|
459
|
+
let {
|
|
460
|
+
point,
|
|
461
|
+
side,
|
|
462
|
+
x,
|
|
463
|
+
y
|
|
464
|
+
} = _ref37;
|
|
465
|
+
return `Point ${point}, ${side} at ${x} comma ${y}`;
|
|
466
|
+
},
|
|
467
|
+
srAngleVertexAtCoordinatesWithAngleMeasure: _ref38 => {
|
|
468
|
+
let {
|
|
469
|
+
x,
|
|
470
|
+
y,
|
|
471
|
+
angleMeasure
|
|
472
|
+
} = _ref38;
|
|
473
|
+
return `Point 2, vertex at ${x} comma ${y}. Angle ${angleMeasure} degrees`;
|
|
474
|
+
},
|
|
475
|
+
srAngleGraphAriaLabel: "An angle on a coordinate plane.",
|
|
476
|
+
srAngleGraphAriaDescription: _ref39 => {
|
|
477
|
+
let {
|
|
478
|
+
angleMeasure,
|
|
479
|
+
vertexX,
|
|
480
|
+
vertexY,
|
|
481
|
+
isX,
|
|
482
|
+
isY,
|
|
483
|
+
tsX,
|
|
484
|
+
tsY
|
|
485
|
+
} = _ref39;
|
|
486
|
+
return `The angle measure is ${angleMeasure} degrees with a vertex at ${vertexX} comma ${vertexY}, a point on the initial side at ${isX} comma ${isY} and a point on the terminal side at ${tsX} comma ${tsY}.`;
|
|
423
487
|
}
|
|
424
488
|
// The above strings are used for interactive graph SR descriptions.
|
|
425
489
|
};
|
|
@@ -27629,11 +27693,21 @@ class Dropdown extends React__namespace.Component {
|
|
|
27629
27693
|
key: "placeholder",
|
|
27630
27694
|
value: "0",
|
|
27631
27695
|
disabled: true,
|
|
27632
|
-
label:
|
|
27696
|
+
label: /*#__PURE__*/React__namespace.createElement(Renderer, {
|
|
27697
|
+
content: this.props.placeholder,
|
|
27698
|
+
strings: this.context.strings,
|
|
27699
|
+
inline: true
|
|
27700
|
+
}),
|
|
27701
|
+
labelAsText: this.props.placeholder
|
|
27633
27702
|
}), ...this.props.choices.map((choice, i) => /*#__PURE__*/React__namespace.createElement(wonderBlocksDropdown.OptionItem, {
|
|
27634
27703
|
key: String(i + 1),
|
|
27635
27704
|
value: String(i + 1),
|
|
27636
|
-
label:
|
|
27705
|
+
label: /*#__PURE__*/React__namespace.createElement(Renderer, {
|
|
27706
|
+
content: choice,
|
|
27707
|
+
strings: this.context.strings,
|
|
27708
|
+
inline: true
|
|
27709
|
+
}),
|
|
27710
|
+
labelAsText: choice
|
|
27637
27711
|
}))];
|
|
27638
27712
|
return /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.Id, null, dropdownId => /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View
|
|
27639
27713
|
// NOTE(jared): These are required to prevent weird behavior
|
|
@@ -27660,7 +27734,8 @@ class Dropdown extends React__namespace.Component {
|
|
|
27660
27734
|
// all dropdowns.
|
|
27661
27735
|
// See https://khanacademy.atlassian.net/browse/WB-1671
|
|
27662
27736
|
,
|
|
27663
|
-
role: "combobox"
|
|
27737
|
+
role: "combobox",
|
|
27738
|
+
showOpenerLabelAsText: false
|
|
27664
27739
|
}, children)));
|
|
27665
27740
|
}
|
|
27666
27741
|
}
|
|
@@ -34119,6 +34194,8 @@ const noop$1 = () => {};
|
|
|
34119
34194
|
|
|
34120
34195
|
const MovableLine = props => {
|
|
34121
34196
|
const {
|
|
34197
|
+
ariaLabels,
|
|
34198
|
+
ariaDescribedBy,
|
|
34122
34199
|
onMoveLine = () => {},
|
|
34123
34200
|
onMovePoint = () => {},
|
|
34124
34201
|
color,
|
|
@@ -34141,6 +34218,8 @@ const MovableLine = props => {
|
|
|
34141
34218
|
visiblePoint: visiblePoint1,
|
|
34142
34219
|
focusableHandle: focusableHandle1
|
|
34143
34220
|
} = useControlPoint({
|
|
34221
|
+
ariaLabel: ariaLabels?.point1AriaLabel,
|
|
34222
|
+
ariaDescribedBy: ariaDescribedBy,
|
|
34144
34223
|
point: start,
|
|
34145
34224
|
sequenceNumber: 1,
|
|
34146
34225
|
color,
|
|
@@ -34150,6 +34229,8 @@ const MovableLine = props => {
|
|
|
34150
34229
|
visiblePoint: visiblePoint2,
|
|
34151
34230
|
focusableHandle: focusableHandle2
|
|
34152
34231
|
} = useControlPoint({
|
|
34232
|
+
ariaLabel: ariaLabels?.point2AriaLabel,
|
|
34233
|
+
ariaDescribedBy: ariaDescribedBy,
|
|
34153
34234
|
point: end,
|
|
34154
34235
|
sequenceNumber: 2,
|
|
34155
34236
|
color,
|
|
@@ -34330,23 +34411,82 @@ function AngleGraph(props) {
|
|
|
34330
34411
|
showAngles: showAngles || false // Whether to show the angle or not
|
|
34331
34412
|
};
|
|
34332
34413
|
|
|
34414
|
+
const {
|
|
34415
|
+
strings,
|
|
34416
|
+
locale
|
|
34417
|
+
} = usePerseusI18n();
|
|
34418
|
+
const angleMeasure = srFormatNumber(getClockwiseAngle([endPoints[0], centerPoint, endPoints[1]], allowReflexAngles), locale);
|
|
34419
|
+
const wholeAngleAriaLabel = strings.srAngleGraphAriaLabel;
|
|
34420
|
+
const wholeAngleDescription = strings.srAngleGraphAriaDescription({
|
|
34421
|
+
angleMeasure,
|
|
34422
|
+
vertexX: srFormatNumber(coords[1][X], locale),
|
|
34423
|
+
vertexY: srFormatNumber(coords[1][Y], locale),
|
|
34424
|
+
isX: srFormatNumber(coords[2][X], locale),
|
|
34425
|
+
isY: srFormatNumber(coords[2][Y], locale),
|
|
34426
|
+
tsX: srFormatNumber(coords[0][X], locale),
|
|
34427
|
+
tsY: srFormatNumber(coords[0][Y], locale)
|
|
34428
|
+
});
|
|
34429
|
+
const formatCoordinates = (x, y) => ({
|
|
34430
|
+
x: srFormatNumber(x, locale),
|
|
34431
|
+
y: srFormatNumber(y, locale)
|
|
34432
|
+
});
|
|
34433
|
+
const formatSideAriaLabel = (side, newPoint) => {
|
|
34434
|
+
const formattedCoordinates = formatCoordinates(newPoint[X], newPoint[Y]);
|
|
34435
|
+
const label = side === "terminal" ? strings.srAngleSideAtCoordinates({
|
|
34436
|
+
point: 1,
|
|
34437
|
+
side: "terminal side",
|
|
34438
|
+
...formattedCoordinates
|
|
34439
|
+
}) : strings.srAngleSideAtCoordinates({
|
|
34440
|
+
point: 3,
|
|
34441
|
+
side: "initial side",
|
|
34442
|
+
...formattedCoordinates
|
|
34443
|
+
});
|
|
34444
|
+
return label;
|
|
34445
|
+
};
|
|
34446
|
+
const formatVertexAriaLabel = newPoint => {
|
|
34447
|
+
const formattedVertexCoordinates = formatCoordinates(newPoint[X], newPoint[Y]);
|
|
34448
|
+
const label = showAngles ? strings.srAngleVertexAtCoordinatesWithAngleMeasure({
|
|
34449
|
+
...formattedVertexCoordinates,
|
|
34450
|
+
angleMeasure: angleMeasure
|
|
34451
|
+
}) : strings.srAngleSideAtCoordinates({
|
|
34452
|
+
point: 2,
|
|
34453
|
+
side: "vertex",
|
|
34454
|
+
...formattedVertexCoordinates
|
|
34455
|
+
});
|
|
34456
|
+
return label;
|
|
34457
|
+
};
|
|
34458
|
+
const initialSideAriaLabel = formatSideAriaLabel("initial", coords[2]);
|
|
34459
|
+
const terminalSideAriaLabel = formatSideAriaLabel("terminal", coords[0]);
|
|
34460
|
+
const vertexAriaLabel = formatVertexAriaLabel(coords[1]);
|
|
34461
|
+
|
|
34333
34462
|
// Render the lines, angle, and then movable points
|
|
34334
|
-
return /*#__PURE__*/React__namespace.createElement(
|
|
34463
|
+
return /*#__PURE__*/React__namespace.createElement("g", {
|
|
34464
|
+
"aria-label": wholeAngleAriaLabel,
|
|
34465
|
+
"aria-describedby": "angle-description"
|
|
34466
|
+
}, svgLines, /*#__PURE__*/React__namespace.createElement(Angle, angleParams), /*#__PURE__*/React__namespace.createElement(MovablePoint$1, {
|
|
34335
34467
|
point: coords[1],
|
|
34336
34468
|
sequenceNumber: 1,
|
|
34337
34469
|
constrain: p => p,
|
|
34338
|
-
onMove: destination => dispatch(actions.angle.movePoint(1, destination))
|
|
34470
|
+
onMove: destination => dispatch(actions.angle.movePoint(1, destination)),
|
|
34471
|
+
ariaLabel: vertexAriaLabel
|
|
34339
34472
|
}), /*#__PURE__*/React__namespace.createElement(MovablePoint$1, {
|
|
34340
34473
|
point: coords[0],
|
|
34341
34474
|
sequenceNumber: 2,
|
|
34342
34475
|
constrain: getAngleSideConstraint(coords[0], coords[1], snapDegrees || 1),
|
|
34343
|
-
onMove: destination => dispatch(actions.angle.movePoint(0, destination))
|
|
34476
|
+
onMove: destination => dispatch(actions.angle.movePoint(0, destination)),
|
|
34477
|
+
ariaLabel: terminalSideAriaLabel
|
|
34344
34478
|
}), /*#__PURE__*/React__namespace.createElement(MovablePoint$1, {
|
|
34345
34479
|
point: coords[2],
|
|
34346
34480
|
sequenceNumber: 3,
|
|
34347
34481
|
constrain: getAngleSideConstraint(coords[2], coords[1], snapDegrees || 1),
|
|
34348
|
-
onMove: destination => dispatch(actions.angle.movePoint(2, destination))
|
|
34349
|
-
|
|
34482
|
+
onMove: destination => dispatch(actions.angle.movePoint(2, destination)),
|
|
34483
|
+
ariaLabel: initialSideAriaLabel
|
|
34484
|
+
}), /*#__PURE__*/React__namespace.createElement("g", {
|
|
34485
|
+
id: "angle-description",
|
|
34486
|
+
style: {
|
|
34487
|
+
display: "hidden"
|
|
34488
|
+
}
|
|
34489
|
+
}, wholeAngleDescription));
|
|
34350
34490
|
}
|
|
34351
34491
|
const positiveX = [1, 0];
|
|
34352
34492
|
const negativeX = [-1, 0];
|
|
@@ -34704,12 +34844,67 @@ const LinearGraph = (props, key) => {
|
|
|
34704
34844
|
const {
|
|
34705
34845
|
coords: line
|
|
34706
34846
|
} = props.graphState;
|
|
34847
|
+
const {
|
|
34848
|
+
strings,
|
|
34849
|
+
locale
|
|
34850
|
+
} = usePerseusI18n();
|
|
34851
|
+
const id = React__namespace.useId();
|
|
34852
|
+
const pointsDescriptionId = id + "-points";
|
|
34853
|
+
const interceptDescriptionId = id + "-intercept";
|
|
34854
|
+
const slopeDescriptionId = id + "-slope";
|
|
34855
|
+
|
|
34856
|
+
// Aria label strings
|
|
34857
|
+
const linearGraphPointsDescription = strings.srLinearGraphPoints({
|
|
34858
|
+
point1X: srFormatNumber(line[0][0], locale),
|
|
34859
|
+
point1Y: srFormatNumber(line[0][1], locale),
|
|
34860
|
+
point2X: srFormatNumber(line[1][0], locale),
|
|
34861
|
+
point2Y: srFormatNumber(line[1][1], locale)
|
|
34862
|
+
});
|
|
34863
|
+
|
|
34864
|
+
// Slope description
|
|
34865
|
+
const slope = (line[1][1] - line[0][1]) / (line[1][0] - line[0][0]);
|
|
34866
|
+
let slopeString = "";
|
|
34867
|
+
if (slope === Infinity || slope === -Infinity) {
|
|
34868
|
+
slopeString = strings.srLinearGraphSlopeVertical;
|
|
34869
|
+
} else if (slope === 0) {
|
|
34870
|
+
slopeString = strings.srLinearGraphSlopeHorizontal;
|
|
34871
|
+
} else {
|
|
34872
|
+
slopeString = slope > 0 ? strings.srLinearGraphSlopeIncreasing : strings.srLinearGraphSlopeDecreasing;
|
|
34873
|
+
}
|
|
34874
|
+
|
|
34875
|
+
// Intersection description
|
|
34876
|
+
const xIntercept = (0 - line[0][1]) / slope + line[0][0];
|
|
34877
|
+
const yIntercept = line[0][1] - slope * line[0][0];
|
|
34878
|
+
const hasXIntercept = xIntercept !== Infinity && xIntercept !== -Infinity;
|
|
34879
|
+
const hasYIntercept = yIntercept !== Infinity && yIntercept !== -Infinity;
|
|
34880
|
+
let interceptString;
|
|
34881
|
+
if (hasXIntercept && hasYIntercept) {
|
|
34882
|
+
// Describe both intercepts in the same sentence.
|
|
34883
|
+
interceptString = xIntercept === 0 && yIntercept === 0 ? strings.srLinearGraphOriginIntercept : strings.srLinearGraphBothIntercepts({
|
|
34884
|
+
xIntercept: srFormatNumber(xIntercept, locale),
|
|
34885
|
+
yIntercept: srFormatNumber(yIntercept, locale)
|
|
34886
|
+
});
|
|
34887
|
+
} else {
|
|
34888
|
+
// Describe only one intercept.
|
|
34889
|
+
interceptString = hasXIntercept ? strings.srLinearGraphXOnlyIntercept({
|
|
34890
|
+
xIntercept: srFormatNumber(xIntercept, locale)
|
|
34891
|
+
}) : strings.srLinearGraphYOnlyIntercept({
|
|
34892
|
+
yIntercept: srFormatNumber(yIntercept, locale)
|
|
34893
|
+
});
|
|
34894
|
+
}
|
|
34707
34895
|
|
|
34708
34896
|
// Linear graphs only have one line
|
|
34709
34897
|
// (LEMS-2050): Update the reducer so that we have a separate action for moving one line
|
|
34710
34898
|
// and another action for moving multiple lines
|
|
34711
|
-
return /*#__PURE__*/React__namespace.createElement(
|
|
34899
|
+
return /*#__PURE__*/React__namespace.createElement("g", {
|
|
34900
|
+
className: "linear-graph-container"
|
|
34901
|
+
// Outer line minimal description
|
|
34902
|
+
,
|
|
34903
|
+
"aria-label": strings.srLinearGraph,
|
|
34904
|
+
"aria-describedby": `${pointsDescriptionId} ${interceptDescriptionId} ${slopeDescriptionId}`
|
|
34905
|
+
}, /*#__PURE__*/React__namespace.createElement(MovableLine, {
|
|
34712
34906
|
key: 0,
|
|
34907
|
+
ariaDescribedBy: `${interceptDescriptionId} ${slopeDescriptionId}`,
|
|
34713
34908
|
points: line,
|
|
34714
34909
|
onMoveLine: delta => {
|
|
34715
34910
|
dispatch(actions.linear.moveLine(delta));
|
|
@@ -34720,7 +34915,22 @@ const LinearGraph = (props, key) => {
|
|
|
34720
34915
|
},
|
|
34721
34916
|
onMovePoint: (endpointIndex, destination) => dispatch(actions.linear.movePoint(endpointIndex, destination)),
|
|
34722
34917
|
color: "var(--movable-line-stroke-color)"
|
|
34723
|
-
})
|
|
34918
|
+
}), /*#__PURE__*/React__namespace.createElement("g", {
|
|
34919
|
+
id: pointsDescriptionId,
|
|
34920
|
+
style: {
|
|
34921
|
+
display: "hidden"
|
|
34922
|
+
}
|
|
34923
|
+
}, linearGraphPointsDescription), /*#__PURE__*/React__namespace.createElement("g", {
|
|
34924
|
+
id: interceptDescriptionId,
|
|
34925
|
+
style: {
|
|
34926
|
+
display: "hidden"
|
|
34927
|
+
}
|
|
34928
|
+
}, interceptString), /*#__PURE__*/React__namespace.createElement("g", {
|
|
34929
|
+
id: slopeDescriptionId,
|
|
34930
|
+
style: {
|
|
34931
|
+
display: "hidden"
|
|
34932
|
+
}
|
|
34933
|
+
}, slopeString));
|
|
34724
34934
|
};
|
|
34725
34935
|
|
|
34726
34936
|
function renderLinearSystemGraph(state, dispatch) {
|
|
@@ -45678,7 +45888,7 @@ const init = function () {
|
|
|
45678
45888
|
|
|
45679
45889
|
// This file is processed by a Rollup plugin (replace) to inject the production
|
|
45680
45890
|
const libName = "@khanacademy/perseus";
|
|
45681
|
-
const libVersion = "49.
|
|
45891
|
+
const libVersion = "49.1.1";
|
|
45682
45892
|
perseusCore.addLibraryVersionToPerseusDebug(libName, libVersion);
|
|
45683
45893
|
|
|
45684
45894
|
const apiVersion = {
|