@khanacademy/perseus 49.0.3 → 49.1.2
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 +140 -17
- package/dist/es/index.js.map +1 -1
- package/dist/es/strings.js +45 -1
- package/dist/es/strings.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.js +156 -17
- package/dist/index.js.map +1 -1
- package/dist/strings.d.ts +27 -0
- package/dist/strings.js +57 -1
- package/dist/strings.js.map +1 -1
- package/dist/widgets/interactive-graphs/graphs/components/movable-line.d.ts +1 -0
- package/package.json +12 -13
package/dist/es/index.js
CHANGED
|
@@ -303,7 +303,34 @@ const mockStrings = {
|
|
|
303
303
|
xIntercept,
|
|
304
304
|
yIntercept
|
|
305
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."
|
|
306
|
+
srLinearGraphOriginIntercept: "The line crosses the x and y axes at the graph's origin.",
|
|
307
|
+
srLinearGrabHandle: ({
|
|
308
|
+
point1X,
|
|
309
|
+
point1Y,
|
|
310
|
+
point2X,
|
|
311
|
+
point2Y
|
|
312
|
+
}) => `Line from ${point1X} comma ${point1Y} to ${point2X} comma ${point2Y}.`,
|
|
313
|
+
srAngleSideAtCoordinates: ({
|
|
314
|
+
point,
|
|
315
|
+
side,
|
|
316
|
+
x,
|
|
317
|
+
y
|
|
318
|
+
}) => `Point ${point}, ${side} at ${x} comma ${y}`,
|
|
319
|
+
srAngleVertexAtCoordinatesWithAngleMeasure: ({
|
|
320
|
+
x,
|
|
321
|
+
y,
|
|
322
|
+
angleMeasure
|
|
323
|
+
}) => `Point 2, vertex at ${x} comma ${y}. Angle ${angleMeasure} degrees`,
|
|
324
|
+
srAngleGraphAriaLabel: "An angle on a coordinate plane.",
|
|
325
|
+
srAngleGraphAriaDescription: ({
|
|
326
|
+
angleMeasure,
|
|
327
|
+
vertexX,
|
|
328
|
+
vertexY,
|
|
329
|
+
isX,
|
|
330
|
+
isY,
|
|
331
|
+
tsX,
|
|
332
|
+
tsY
|
|
333
|
+
}) => `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}.`
|
|
307
334
|
// The above strings are used for interactive graph SR descriptions.
|
|
308
335
|
};
|
|
309
336
|
|
|
@@ -33850,15 +33877,21 @@ const noop$1 = () => {};
|
|
|
33850
33877
|
|
|
33851
33878
|
const MovableLine = props => {
|
|
33852
33879
|
const {
|
|
33880
|
+
points: [start, end],
|
|
33853
33881
|
ariaLabels,
|
|
33854
33882
|
ariaDescribedBy,
|
|
33855
|
-
onMoveLine = () => {},
|
|
33856
|
-
onMovePoint = () => {},
|
|
33857
33883
|
color,
|
|
33858
|
-
|
|
33859
|
-
|
|
33884
|
+
extend,
|
|
33885
|
+
onMoveLine = () => {},
|
|
33886
|
+
onMovePoint = () => {}
|
|
33860
33887
|
} = props;
|
|
33861
33888
|
|
|
33889
|
+
// Aria live states for (0) point 1, (1) point 2, and (2) grab handle.
|
|
33890
|
+
// When moving an element, set its aria live to "polite" and the others
|
|
33891
|
+
// to "off". Otherwise, other connected elements that move at the same
|
|
33892
|
+
// time might override the currently focused element's aria live.
|
|
33893
|
+
const [ariaLives, setAriaLives] = React.useState(["off", "off", "off"]);
|
|
33894
|
+
|
|
33862
33895
|
// We use separate focusableHandle elements, instead of letting the movable
|
|
33863
33896
|
// points themselves be focusable, to allow the tab order of the points to
|
|
33864
33897
|
// be different from the rendering order. We had to solve for the following
|
|
@@ -33876,10 +33909,14 @@ const MovableLine = props => {
|
|
|
33876
33909
|
} = useControlPoint({
|
|
33877
33910
|
ariaLabel: ariaLabels == null ? void 0 : ariaLabels.point1AriaLabel,
|
|
33878
33911
|
ariaDescribedBy: ariaDescribedBy,
|
|
33912
|
+
ariaLive: ariaLives[0],
|
|
33879
33913
|
point: start,
|
|
33880
33914
|
sequenceNumber: 1,
|
|
33881
33915
|
color,
|
|
33882
|
-
onMove: p =>
|
|
33916
|
+
onMove: p => {
|
|
33917
|
+
setAriaLives(["polite", "off", "off"]);
|
|
33918
|
+
onMovePoint(0, p);
|
|
33919
|
+
}
|
|
33883
33920
|
});
|
|
33884
33921
|
const {
|
|
33885
33922
|
visiblePoint: visiblePoint2,
|
|
@@ -33887,17 +33924,27 @@ const MovableLine = props => {
|
|
|
33887
33924
|
} = useControlPoint({
|
|
33888
33925
|
ariaLabel: ariaLabels == null ? void 0 : ariaLabels.point2AriaLabel,
|
|
33889
33926
|
ariaDescribedBy: ariaDescribedBy,
|
|
33927
|
+
ariaLive: ariaLives[1],
|
|
33890
33928
|
point: end,
|
|
33891
33929
|
sequenceNumber: 2,
|
|
33892
33930
|
color,
|
|
33893
|
-
onMove: p =>
|
|
33931
|
+
onMove: p => {
|
|
33932
|
+
setAriaLives(["off", "polite", "off"]);
|
|
33933
|
+
onMovePoint(1, p);
|
|
33934
|
+
}
|
|
33894
33935
|
});
|
|
33895
33936
|
const line = /*#__PURE__*/React.createElement(Line$1, {
|
|
33937
|
+
ariaLabel: ariaLabels == null ? void 0 : ariaLabels.grabHandleAriaLabel,
|
|
33938
|
+
ariaDescribedBy: ariaDescribedBy,
|
|
33939
|
+
ariaLive: ariaLives[2],
|
|
33896
33940
|
start: start,
|
|
33897
33941
|
end: end,
|
|
33898
33942
|
stroke: color,
|
|
33899
33943
|
extend: extend,
|
|
33900
|
-
onMove:
|
|
33944
|
+
onMove: delta => {
|
|
33945
|
+
setAriaLives(["off", "off", "polite"]);
|
|
33946
|
+
onMoveLine(delta);
|
|
33947
|
+
}
|
|
33901
33948
|
});
|
|
33902
33949
|
return /*#__PURE__*/React.createElement(React.Fragment, null, focusableHandle1, line, focusableHandle2, visiblePoint1, visiblePoint2);
|
|
33903
33950
|
};
|
|
@@ -33906,9 +33953,12 @@ const Line$1 = props => {
|
|
|
33906
33953
|
const {
|
|
33907
33954
|
start,
|
|
33908
33955
|
end,
|
|
33909
|
-
|
|
33956
|
+
ariaLabel,
|
|
33957
|
+
ariaDescribedBy,
|
|
33958
|
+
ariaLive,
|
|
33910
33959
|
extend,
|
|
33911
|
-
stroke = defaultStroke
|
|
33960
|
+
stroke = defaultStroke,
|
|
33961
|
+
onMove
|
|
33912
33962
|
} = props;
|
|
33913
33963
|
const [startPtPx, endPtPx] = useTransformVectorsToPixels(start, end);
|
|
33914
33964
|
const {
|
|
@@ -33938,11 +33988,19 @@ const Line$1 = props => {
|
|
|
33938
33988
|
return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("g", {
|
|
33939
33989
|
ref: line,
|
|
33940
33990
|
tabIndex: disableKeyboardInteraction ? -1 : 0,
|
|
33991
|
+
"aria-label": ariaLabel,
|
|
33992
|
+
"aria-describedby": ariaDescribedBy,
|
|
33993
|
+
"aria-live": ariaLive,
|
|
33941
33994
|
className: "movable-line",
|
|
33942
33995
|
"data-testid": "movable-line",
|
|
33943
33996
|
style: {
|
|
33944
33997
|
cursor: dragging ? "grabbing" : "grab"
|
|
33945
33998
|
}
|
|
33999
|
+
// Indicate that this element is interactive.
|
|
34000
|
+
// As a bonus, giving this group a non-group role makes
|
|
34001
|
+
// the screen reader skip over its empty children.
|
|
34002
|
+
,
|
|
34003
|
+
role: "button"
|
|
33946
34004
|
}, /*#__PURE__*/React.createElement(SVGLine, {
|
|
33947
34005
|
start: startPtPx,
|
|
33948
34006
|
end: endPtPx,
|
|
@@ -34065,23 +34123,78 @@ function AngleGraph(props) {
|
|
|
34065
34123
|
showAngles: showAngles || false // Whether to show the angle or not
|
|
34066
34124
|
};
|
|
34067
34125
|
|
|
34126
|
+
const {
|
|
34127
|
+
strings,
|
|
34128
|
+
locale
|
|
34129
|
+
} = usePerseusI18n();
|
|
34130
|
+
const angleMeasure = srFormatNumber(getClockwiseAngle([endPoints[0], centerPoint, endPoints[1]], allowReflexAngles), locale);
|
|
34131
|
+
const wholeAngleAriaLabel = strings.srAngleGraphAriaLabel;
|
|
34132
|
+
const wholeAngleDescription = strings.srAngleGraphAriaDescription({
|
|
34133
|
+
angleMeasure,
|
|
34134
|
+
vertexX: srFormatNumber(coords[1][X], locale),
|
|
34135
|
+
vertexY: srFormatNumber(coords[1][Y], locale),
|
|
34136
|
+
isX: srFormatNumber(coords[2][X], locale),
|
|
34137
|
+
isY: srFormatNumber(coords[2][Y], locale),
|
|
34138
|
+
tsX: srFormatNumber(coords[0][X], locale),
|
|
34139
|
+
tsY: srFormatNumber(coords[0][Y], locale)
|
|
34140
|
+
});
|
|
34141
|
+
const formatCoordinates = (x, y) => ({
|
|
34142
|
+
x: srFormatNumber(x, locale),
|
|
34143
|
+
y: srFormatNumber(y, locale)
|
|
34144
|
+
});
|
|
34145
|
+
const formatSideAriaLabel = (side, newPoint) => {
|
|
34146
|
+
const formattedCoordinates = formatCoordinates(newPoint[X], newPoint[Y]);
|
|
34147
|
+
const label = side === "terminal" ? strings.srAngleSideAtCoordinates(_extends({
|
|
34148
|
+
point: 1,
|
|
34149
|
+
side: "terminal side"
|
|
34150
|
+
}, formattedCoordinates)) : strings.srAngleSideAtCoordinates(_extends({
|
|
34151
|
+
point: 3,
|
|
34152
|
+
side: "initial side"
|
|
34153
|
+
}, formattedCoordinates));
|
|
34154
|
+
return label;
|
|
34155
|
+
};
|
|
34156
|
+
const formatVertexAriaLabel = newPoint => {
|
|
34157
|
+
const formattedVertexCoordinates = formatCoordinates(newPoint[X], newPoint[Y]);
|
|
34158
|
+
const label = showAngles ? strings.srAngleVertexAtCoordinatesWithAngleMeasure(_extends({}, formattedVertexCoordinates, {
|
|
34159
|
+
angleMeasure: angleMeasure
|
|
34160
|
+
})) : strings.srAngleSideAtCoordinates(_extends({
|
|
34161
|
+
point: 2,
|
|
34162
|
+
side: "vertex"
|
|
34163
|
+
}, formattedVertexCoordinates));
|
|
34164
|
+
return label;
|
|
34165
|
+
};
|
|
34166
|
+
const initialSideAriaLabel = formatSideAriaLabel("initial", coords[2]);
|
|
34167
|
+
const terminalSideAriaLabel = formatSideAriaLabel("terminal", coords[0]);
|
|
34168
|
+
const vertexAriaLabel = formatVertexAriaLabel(coords[1]);
|
|
34169
|
+
|
|
34068
34170
|
// Render the lines, angle, and then movable points
|
|
34069
|
-
return /*#__PURE__*/React.createElement(
|
|
34171
|
+
return /*#__PURE__*/React.createElement("g", {
|
|
34172
|
+
"aria-label": wholeAngleAriaLabel,
|
|
34173
|
+
"aria-describedby": "angle-description"
|
|
34174
|
+
}, svgLines, /*#__PURE__*/React.createElement(Angle, angleParams), /*#__PURE__*/React.createElement(MovablePoint$1, {
|
|
34070
34175
|
point: coords[1],
|
|
34071
34176
|
sequenceNumber: 1,
|
|
34072
34177
|
constrain: p => p,
|
|
34073
|
-
onMove: destination => dispatch(actions.angle.movePoint(1, destination))
|
|
34178
|
+
onMove: destination => dispatch(actions.angle.movePoint(1, destination)),
|
|
34179
|
+
ariaLabel: vertexAriaLabel
|
|
34074
34180
|
}), /*#__PURE__*/React.createElement(MovablePoint$1, {
|
|
34075
34181
|
point: coords[0],
|
|
34076
34182
|
sequenceNumber: 2,
|
|
34077
34183
|
constrain: getAngleSideConstraint(coords[0], coords[1], snapDegrees || 1),
|
|
34078
|
-
onMove: destination => dispatch(actions.angle.movePoint(0, destination))
|
|
34184
|
+
onMove: destination => dispatch(actions.angle.movePoint(0, destination)),
|
|
34185
|
+
ariaLabel: terminalSideAriaLabel
|
|
34079
34186
|
}), /*#__PURE__*/React.createElement(MovablePoint$1, {
|
|
34080
34187
|
point: coords[2],
|
|
34081
34188
|
sequenceNumber: 3,
|
|
34082
34189
|
constrain: getAngleSideConstraint(coords[2], coords[1], snapDegrees || 1),
|
|
34083
|
-
onMove: destination => dispatch(actions.angle.movePoint(2, destination))
|
|
34084
|
-
|
|
34190
|
+
onMove: destination => dispatch(actions.angle.movePoint(2, destination)),
|
|
34191
|
+
ariaLabel: initialSideAriaLabel
|
|
34192
|
+
}), /*#__PURE__*/React.createElement("g", {
|
|
34193
|
+
id: "angle-description",
|
|
34194
|
+
style: {
|
|
34195
|
+
display: "hidden"
|
|
34196
|
+
}
|
|
34197
|
+
}, wholeAngleDescription));
|
|
34085
34198
|
}
|
|
34086
34199
|
const positiveX = [1, 0];
|
|
34087
34200
|
const negativeX = [-1, 0];
|
|
@@ -34442,6 +34555,12 @@ const LinearGraph = (props, key) => {
|
|
|
34442
34555
|
point2X: srFormatNumber(line[1][0], locale),
|
|
34443
34556
|
point2Y: srFormatNumber(line[1][1], locale)
|
|
34444
34557
|
});
|
|
34558
|
+
const grabHandleAriaLabel = strings.srLinearGrabHandle({
|
|
34559
|
+
point1X: srFormatNumber(line[0][0], locale),
|
|
34560
|
+
point1Y: srFormatNumber(line[0][1], locale),
|
|
34561
|
+
point2X: srFormatNumber(line[1][0], locale),
|
|
34562
|
+
point2Y: srFormatNumber(line[1][1], locale)
|
|
34563
|
+
});
|
|
34445
34564
|
|
|
34446
34565
|
// Slope description
|
|
34447
34566
|
const slope = (line[1][1] - line[0][1]) / (line[1][0] - line[0][0]);
|
|
@@ -34483,9 +34602,13 @@ const LinearGraph = (props, key) => {
|
|
|
34483
34602
|
// Outer line minimal description
|
|
34484
34603
|
,
|
|
34485
34604
|
"aria-label": strings.srLinearGraph,
|
|
34486
|
-
"aria-describedby": `${pointsDescriptionId} ${interceptDescriptionId} ${slopeDescriptionId}
|
|
34605
|
+
"aria-describedby": `${pointsDescriptionId} ${interceptDescriptionId} ${slopeDescriptionId}`,
|
|
34606
|
+
role: "figure"
|
|
34487
34607
|
}, /*#__PURE__*/React.createElement(MovableLine, {
|
|
34488
34608
|
key: 0,
|
|
34609
|
+
ariaLabels: {
|
|
34610
|
+
grabHandleAriaLabel: grabHandleAriaLabel
|
|
34611
|
+
},
|
|
34489
34612
|
ariaDescribedBy: `${interceptDescriptionId} ${slopeDescriptionId}`,
|
|
34490
34613
|
points: line,
|
|
34491
34614
|
onMoveLine: delta => {
|
|
@@ -45431,7 +45554,7 @@ const init = function init() {
|
|
|
45431
45554
|
|
|
45432
45555
|
// This file is processed by a Rollup plugin (replace) to inject the production
|
|
45433
45556
|
const libName = "@khanacademy/perseus";
|
|
45434
|
-
const libVersion = "49.
|
|
45557
|
+
const libVersion = "49.1.2";
|
|
45435
45558
|
addLibraryVersionToPerseusDebug(libName, libVersion);
|
|
45436
45559
|
|
|
45437
45560
|
const apiVersion = {
|