@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/es/index.js
CHANGED
|
@@ -281,7 +281,50 @@ const mockStrings = {
|
|
|
281
281
|
point3Y,
|
|
282
282
|
point4X,
|
|
283
283
|
point4Y
|
|
284
|
-
}) => `Points on the circle at ${point1X} comma ${point1Y}, ${point2X} comma ${point2Y}, ${point3X} comma ${point3Y}, ${point4X} comma ${point4Y}
|
|
284
|
+
}) => `Points on the circle at ${point1X} comma ${point1Y}, ${point2X} comma ${point2Y}, ${point3X} comma ${point3Y}, ${point4X} comma ${point4Y}.`,
|
|
285
|
+
srLinearGraph: "A line on a coordinate plane.",
|
|
286
|
+
srLinearGraphPoints: ({
|
|
287
|
+
point1X,
|
|
288
|
+
point1Y,
|
|
289
|
+
point2X,
|
|
290
|
+
point2Y
|
|
291
|
+
}) => `The line has two points, point 1 at ${point1X} comma ${point1Y} and point 2 at ${point2X} comma ${point2Y}.`,
|
|
292
|
+
srLinearGraphSlopeIncreasing: "Its slope increases from left to right.",
|
|
293
|
+
srLinearGraphSlopeDecreasing: "Its slope decreases from left to right.",
|
|
294
|
+
srLinearGraphSlopeHorizontal: "Its slope is zero.",
|
|
295
|
+
srLinearGraphSlopeVertical: "Its slope is undefined.",
|
|
296
|
+
srLinearGraphXOnlyIntercept: ({
|
|
297
|
+
xIntercept
|
|
298
|
+
}) => `The line crosses the X-axis at ${xIntercept} comma 0.`,
|
|
299
|
+
srLinearGraphYOnlyIntercept: ({
|
|
300
|
+
yIntercept
|
|
301
|
+
}) => `The line crosses the Y-axis at 0 comma ${yIntercept}.`,
|
|
302
|
+
srLinearGraphBothIntercepts: ({
|
|
303
|
+
xIntercept,
|
|
304
|
+
yIntercept
|
|
305
|
+
}) => `The line crosses the X-axis at ${xIntercept} comma 0 and the Y-axis at 0 comma ${yIntercept}.`,
|
|
306
|
+
srLinearGraphOriginIntercept: "The line crosses the x and y axes at the graph's origin.",
|
|
307
|
+
srAngleSideAtCoordinates: ({
|
|
308
|
+
point,
|
|
309
|
+
side,
|
|
310
|
+
x,
|
|
311
|
+
y
|
|
312
|
+
}) => `Point ${point}, ${side} at ${x} comma ${y}`,
|
|
313
|
+
srAngleVertexAtCoordinatesWithAngleMeasure: ({
|
|
314
|
+
x,
|
|
315
|
+
y,
|
|
316
|
+
angleMeasure
|
|
317
|
+
}) => `Point 2, vertex at ${x} comma ${y}. Angle ${angleMeasure} degrees`,
|
|
318
|
+
srAngleGraphAriaLabel: "An angle on a coordinate plane.",
|
|
319
|
+
srAngleGraphAriaDescription: ({
|
|
320
|
+
angleMeasure,
|
|
321
|
+
vertexX,
|
|
322
|
+
vertexY,
|
|
323
|
+
isX,
|
|
324
|
+
isY,
|
|
325
|
+
tsX,
|
|
326
|
+
tsY
|
|
327
|
+
}) => `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}.`
|
|
285
328
|
// The above strings are used for interactive graph SR descriptions.
|
|
286
329
|
};
|
|
287
330
|
|
|
@@ -27376,11 +27419,21 @@ class Dropdown extends React.Component {
|
|
|
27376
27419
|
key: "placeholder",
|
|
27377
27420
|
value: "0",
|
|
27378
27421
|
disabled: true,
|
|
27379
|
-
label:
|
|
27422
|
+
label: /*#__PURE__*/React.createElement(Renderer, {
|
|
27423
|
+
content: this.props.placeholder,
|
|
27424
|
+
strings: this.context.strings,
|
|
27425
|
+
inline: true
|
|
27426
|
+
}),
|
|
27427
|
+
labelAsText: this.props.placeholder
|
|
27380
27428
|
}), ...this.props.choices.map((choice, i) => /*#__PURE__*/React.createElement(OptionItem, {
|
|
27381
27429
|
key: String(i + 1),
|
|
27382
27430
|
value: String(i + 1),
|
|
27383
|
-
label:
|
|
27431
|
+
label: /*#__PURE__*/React.createElement(Renderer, {
|
|
27432
|
+
content: choice,
|
|
27433
|
+
strings: this.context.strings,
|
|
27434
|
+
inline: true
|
|
27435
|
+
}),
|
|
27436
|
+
labelAsText: choice
|
|
27384
27437
|
}))];
|
|
27385
27438
|
return /*#__PURE__*/React.createElement(Id, null, dropdownId => /*#__PURE__*/React.createElement(View
|
|
27386
27439
|
// NOTE(jared): These are required to prevent weird behavior
|
|
@@ -27407,7 +27460,8 @@ class Dropdown extends React.Component {
|
|
|
27407
27460
|
// all dropdowns.
|
|
27408
27461
|
// See https://khanacademy.atlassian.net/browse/WB-1671
|
|
27409
27462
|
,
|
|
27410
|
-
role: "combobox"
|
|
27463
|
+
role: "combobox",
|
|
27464
|
+
showOpenerLabelAsText: false
|
|
27411
27465
|
}, children)));
|
|
27412
27466
|
}
|
|
27413
27467
|
}
|
|
@@ -33817,6 +33871,8 @@ const noop$1 = () => {};
|
|
|
33817
33871
|
|
|
33818
33872
|
const MovableLine = props => {
|
|
33819
33873
|
const {
|
|
33874
|
+
ariaLabels,
|
|
33875
|
+
ariaDescribedBy,
|
|
33820
33876
|
onMoveLine = () => {},
|
|
33821
33877
|
onMovePoint = () => {},
|
|
33822
33878
|
color,
|
|
@@ -33839,6 +33895,8 @@ const MovableLine = props => {
|
|
|
33839
33895
|
visiblePoint: visiblePoint1,
|
|
33840
33896
|
focusableHandle: focusableHandle1
|
|
33841
33897
|
} = useControlPoint({
|
|
33898
|
+
ariaLabel: ariaLabels == null ? void 0 : ariaLabels.point1AriaLabel,
|
|
33899
|
+
ariaDescribedBy: ariaDescribedBy,
|
|
33842
33900
|
point: start,
|
|
33843
33901
|
sequenceNumber: 1,
|
|
33844
33902
|
color,
|
|
@@ -33848,6 +33906,8 @@ const MovableLine = props => {
|
|
|
33848
33906
|
visiblePoint: visiblePoint2,
|
|
33849
33907
|
focusableHandle: focusableHandle2
|
|
33850
33908
|
} = useControlPoint({
|
|
33909
|
+
ariaLabel: ariaLabels == null ? void 0 : ariaLabels.point2AriaLabel,
|
|
33910
|
+
ariaDescribedBy: ariaDescribedBy,
|
|
33851
33911
|
point: end,
|
|
33852
33912
|
sequenceNumber: 2,
|
|
33853
33913
|
color,
|
|
@@ -34026,23 +34086,78 @@ function AngleGraph(props) {
|
|
|
34026
34086
|
showAngles: showAngles || false // Whether to show the angle or not
|
|
34027
34087
|
};
|
|
34028
34088
|
|
|
34089
|
+
const {
|
|
34090
|
+
strings,
|
|
34091
|
+
locale
|
|
34092
|
+
} = usePerseusI18n();
|
|
34093
|
+
const angleMeasure = srFormatNumber(getClockwiseAngle([endPoints[0], centerPoint, endPoints[1]], allowReflexAngles), locale);
|
|
34094
|
+
const wholeAngleAriaLabel = strings.srAngleGraphAriaLabel;
|
|
34095
|
+
const wholeAngleDescription = strings.srAngleGraphAriaDescription({
|
|
34096
|
+
angleMeasure,
|
|
34097
|
+
vertexX: srFormatNumber(coords[1][X], locale),
|
|
34098
|
+
vertexY: srFormatNumber(coords[1][Y], locale),
|
|
34099
|
+
isX: srFormatNumber(coords[2][X], locale),
|
|
34100
|
+
isY: srFormatNumber(coords[2][Y], locale),
|
|
34101
|
+
tsX: srFormatNumber(coords[0][X], locale),
|
|
34102
|
+
tsY: srFormatNumber(coords[0][Y], locale)
|
|
34103
|
+
});
|
|
34104
|
+
const formatCoordinates = (x, y) => ({
|
|
34105
|
+
x: srFormatNumber(x, locale),
|
|
34106
|
+
y: srFormatNumber(y, locale)
|
|
34107
|
+
});
|
|
34108
|
+
const formatSideAriaLabel = (side, newPoint) => {
|
|
34109
|
+
const formattedCoordinates = formatCoordinates(newPoint[X], newPoint[Y]);
|
|
34110
|
+
const label = side === "terminal" ? strings.srAngleSideAtCoordinates(_extends({
|
|
34111
|
+
point: 1,
|
|
34112
|
+
side: "terminal side"
|
|
34113
|
+
}, formattedCoordinates)) : strings.srAngleSideAtCoordinates(_extends({
|
|
34114
|
+
point: 3,
|
|
34115
|
+
side: "initial side"
|
|
34116
|
+
}, formattedCoordinates));
|
|
34117
|
+
return label;
|
|
34118
|
+
};
|
|
34119
|
+
const formatVertexAriaLabel = newPoint => {
|
|
34120
|
+
const formattedVertexCoordinates = formatCoordinates(newPoint[X], newPoint[Y]);
|
|
34121
|
+
const label = showAngles ? strings.srAngleVertexAtCoordinatesWithAngleMeasure(_extends({}, formattedVertexCoordinates, {
|
|
34122
|
+
angleMeasure: angleMeasure
|
|
34123
|
+
})) : strings.srAngleSideAtCoordinates(_extends({
|
|
34124
|
+
point: 2,
|
|
34125
|
+
side: "vertex"
|
|
34126
|
+
}, formattedVertexCoordinates));
|
|
34127
|
+
return label;
|
|
34128
|
+
};
|
|
34129
|
+
const initialSideAriaLabel = formatSideAriaLabel("initial", coords[2]);
|
|
34130
|
+
const terminalSideAriaLabel = formatSideAriaLabel("terminal", coords[0]);
|
|
34131
|
+
const vertexAriaLabel = formatVertexAriaLabel(coords[1]);
|
|
34132
|
+
|
|
34029
34133
|
// Render the lines, angle, and then movable points
|
|
34030
|
-
return /*#__PURE__*/React.createElement(
|
|
34134
|
+
return /*#__PURE__*/React.createElement("g", {
|
|
34135
|
+
"aria-label": wholeAngleAriaLabel,
|
|
34136
|
+
"aria-describedby": "angle-description"
|
|
34137
|
+
}, svgLines, /*#__PURE__*/React.createElement(Angle, angleParams), /*#__PURE__*/React.createElement(MovablePoint$1, {
|
|
34031
34138
|
point: coords[1],
|
|
34032
34139
|
sequenceNumber: 1,
|
|
34033
34140
|
constrain: p => p,
|
|
34034
|
-
onMove: destination => dispatch(actions.angle.movePoint(1, destination))
|
|
34141
|
+
onMove: destination => dispatch(actions.angle.movePoint(1, destination)),
|
|
34142
|
+
ariaLabel: vertexAriaLabel
|
|
34035
34143
|
}), /*#__PURE__*/React.createElement(MovablePoint$1, {
|
|
34036
34144
|
point: coords[0],
|
|
34037
34145
|
sequenceNumber: 2,
|
|
34038
34146
|
constrain: getAngleSideConstraint(coords[0], coords[1], snapDegrees || 1),
|
|
34039
|
-
onMove: destination => dispatch(actions.angle.movePoint(0, destination))
|
|
34147
|
+
onMove: destination => dispatch(actions.angle.movePoint(0, destination)),
|
|
34148
|
+
ariaLabel: terminalSideAriaLabel
|
|
34040
34149
|
}), /*#__PURE__*/React.createElement(MovablePoint$1, {
|
|
34041
34150
|
point: coords[2],
|
|
34042
34151
|
sequenceNumber: 3,
|
|
34043
34152
|
constrain: getAngleSideConstraint(coords[2], coords[1], snapDegrees || 1),
|
|
34044
|
-
onMove: destination => dispatch(actions.angle.movePoint(2, destination))
|
|
34045
|
-
|
|
34153
|
+
onMove: destination => dispatch(actions.angle.movePoint(2, destination)),
|
|
34154
|
+
ariaLabel: initialSideAriaLabel
|
|
34155
|
+
}), /*#__PURE__*/React.createElement("g", {
|
|
34156
|
+
id: "angle-description",
|
|
34157
|
+
style: {
|
|
34158
|
+
display: "hidden"
|
|
34159
|
+
}
|
|
34160
|
+
}, wholeAngleDescription));
|
|
34046
34161
|
}
|
|
34047
34162
|
const positiveX = [1, 0];
|
|
34048
34163
|
const negativeX = [-1, 0];
|
|
@@ -34387,12 +34502,67 @@ const LinearGraph = (props, key) => {
|
|
|
34387
34502
|
const {
|
|
34388
34503
|
coords: line
|
|
34389
34504
|
} = props.graphState;
|
|
34505
|
+
const {
|
|
34506
|
+
strings,
|
|
34507
|
+
locale
|
|
34508
|
+
} = usePerseusI18n();
|
|
34509
|
+
const id = React.useId();
|
|
34510
|
+
const pointsDescriptionId = id + "-points";
|
|
34511
|
+
const interceptDescriptionId = id + "-intercept";
|
|
34512
|
+
const slopeDescriptionId = id + "-slope";
|
|
34513
|
+
|
|
34514
|
+
// Aria label strings
|
|
34515
|
+
const linearGraphPointsDescription = strings.srLinearGraphPoints({
|
|
34516
|
+
point1X: srFormatNumber(line[0][0], locale),
|
|
34517
|
+
point1Y: srFormatNumber(line[0][1], locale),
|
|
34518
|
+
point2X: srFormatNumber(line[1][0], locale),
|
|
34519
|
+
point2Y: srFormatNumber(line[1][1], locale)
|
|
34520
|
+
});
|
|
34521
|
+
|
|
34522
|
+
// Slope description
|
|
34523
|
+
const slope = (line[1][1] - line[0][1]) / (line[1][0] - line[0][0]);
|
|
34524
|
+
let slopeString = "";
|
|
34525
|
+
if (slope === Infinity || slope === -Infinity) {
|
|
34526
|
+
slopeString = strings.srLinearGraphSlopeVertical;
|
|
34527
|
+
} else if (slope === 0) {
|
|
34528
|
+
slopeString = strings.srLinearGraphSlopeHorizontal;
|
|
34529
|
+
} else {
|
|
34530
|
+
slopeString = slope > 0 ? strings.srLinearGraphSlopeIncreasing : strings.srLinearGraphSlopeDecreasing;
|
|
34531
|
+
}
|
|
34532
|
+
|
|
34533
|
+
// Intersection description
|
|
34534
|
+
const xIntercept = (0 - line[0][1]) / slope + line[0][0];
|
|
34535
|
+
const yIntercept = line[0][1] - slope * line[0][0];
|
|
34536
|
+
const hasXIntercept = xIntercept !== Infinity && xIntercept !== -Infinity;
|
|
34537
|
+
const hasYIntercept = yIntercept !== Infinity && yIntercept !== -Infinity;
|
|
34538
|
+
let interceptString;
|
|
34539
|
+
if (hasXIntercept && hasYIntercept) {
|
|
34540
|
+
// Describe both intercepts in the same sentence.
|
|
34541
|
+
interceptString = xIntercept === 0 && yIntercept === 0 ? strings.srLinearGraphOriginIntercept : strings.srLinearGraphBothIntercepts({
|
|
34542
|
+
xIntercept: srFormatNumber(xIntercept, locale),
|
|
34543
|
+
yIntercept: srFormatNumber(yIntercept, locale)
|
|
34544
|
+
});
|
|
34545
|
+
} else {
|
|
34546
|
+
// Describe only one intercept.
|
|
34547
|
+
interceptString = hasXIntercept ? strings.srLinearGraphXOnlyIntercept({
|
|
34548
|
+
xIntercept: srFormatNumber(xIntercept, locale)
|
|
34549
|
+
}) : strings.srLinearGraphYOnlyIntercept({
|
|
34550
|
+
yIntercept: srFormatNumber(yIntercept, locale)
|
|
34551
|
+
});
|
|
34552
|
+
}
|
|
34390
34553
|
|
|
34391
34554
|
// Linear graphs only have one line
|
|
34392
34555
|
// (LEMS-2050): Update the reducer so that we have a separate action for moving one line
|
|
34393
34556
|
// and another action for moving multiple lines
|
|
34394
|
-
return /*#__PURE__*/React.createElement(
|
|
34557
|
+
return /*#__PURE__*/React.createElement("g", {
|
|
34558
|
+
className: "linear-graph-container"
|
|
34559
|
+
// Outer line minimal description
|
|
34560
|
+
,
|
|
34561
|
+
"aria-label": strings.srLinearGraph,
|
|
34562
|
+
"aria-describedby": `${pointsDescriptionId} ${interceptDescriptionId} ${slopeDescriptionId}`
|
|
34563
|
+
}, /*#__PURE__*/React.createElement(MovableLine, {
|
|
34395
34564
|
key: 0,
|
|
34565
|
+
ariaDescribedBy: `${interceptDescriptionId} ${slopeDescriptionId}`,
|
|
34396
34566
|
points: line,
|
|
34397
34567
|
onMoveLine: delta => {
|
|
34398
34568
|
dispatch(actions.linear.moveLine(delta));
|
|
@@ -34403,7 +34573,22 @@ const LinearGraph = (props, key) => {
|
|
|
34403
34573
|
},
|
|
34404
34574
|
onMovePoint: (endpointIndex, destination) => dispatch(actions.linear.movePoint(endpointIndex, destination)),
|
|
34405
34575
|
color: "var(--movable-line-stroke-color)"
|
|
34406
|
-
})
|
|
34576
|
+
}), /*#__PURE__*/React.createElement("g", {
|
|
34577
|
+
id: pointsDescriptionId,
|
|
34578
|
+
style: {
|
|
34579
|
+
display: "hidden"
|
|
34580
|
+
}
|
|
34581
|
+
}, linearGraphPointsDescription), /*#__PURE__*/React.createElement("g", {
|
|
34582
|
+
id: interceptDescriptionId,
|
|
34583
|
+
style: {
|
|
34584
|
+
display: "hidden"
|
|
34585
|
+
}
|
|
34586
|
+
}, interceptString), /*#__PURE__*/React.createElement("g", {
|
|
34587
|
+
id: slopeDescriptionId,
|
|
34588
|
+
style: {
|
|
34589
|
+
display: "hidden"
|
|
34590
|
+
}
|
|
34591
|
+
}, slopeString));
|
|
34407
34592
|
};
|
|
34408
34593
|
|
|
34409
34594
|
function renderLinearSystemGraph(state, dispatch) {
|
|
@@ -45322,7 +45507,7 @@ const init = function init() {
|
|
|
45322
45507
|
|
|
45323
45508
|
// This file is processed by a Rollup plugin (replace) to inject the production
|
|
45324
45509
|
const libName = "@khanacademy/perseus";
|
|
45325
|
-
const libVersion = "49.
|
|
45510
|
+
const libVersion = "49.1.1";
|
|
45326
45511
|
addLibraryVersionToPerseusDebug(libName, libVersion);
|
|
45327
45512
|
|
|
45328
45513
|
const apiVersion = {
|