@khanacademy/perseus 49.1.1 → 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 CHANGED
@@ -304,6 +304,12 @@ const mockStrings = {
304
304
  yIntercept
305
305
  }) => `The line crosses the X-axis at ${xIntercept} comma 0 and the Y-axis at 0 comma ${yIntercept}.`,
306
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}.`,
307
313
  srAngleSideAtCoordinates: ({
308
314
  point,
309
315
  side,
@@ -33871,15 +33877,21 @@ const noop$1 = () => {};
33871
33877
 
33872
33878
  const MovableLine = props => {
33873
33879
  const {
33880
+ points: [start, end],
33874
33881
  ariaLabels,
33875
33882
  ariaDescribedBy,
33876
- onMoveLine = () => {},
33877
- onMovePoint = () => {},
33878
33883
  color,
33879
- points: [start, end],
33880
- extend
33884
+ extend,
33885
+ onMoveLine = () => {},
33886
+ onMovePoint = () => {}
33881
33887
  } = props;
33882
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
+
33883
33895
  // We use separate focusableHandle elements, instead of letting the movable
33884
33896
  // points themselves be focusable, to allow the tab order of the points to
33885
33897
  // be different from the rendering order. We had to solve for the following
@@ -33897,10 +33909,14 @@ const MovableLine = props => {
33897
33909
  } = useControlPoint({
33898
33910
  ariaLabel: ariaLabels == null ? void 0 : ariaLabels.point1AriaLabel,
33899
33911
  ariaDescribedBy: ariaDescribedBy,
33912
+ ariaLive: ariaLives[0],
33900
33913
  point: start,
33901
33914
  sequenceNumber: 1,
33902
33915
  color,
33903
- onMove: p => onMovePoint(0, p)
33916
+ onMove: p => {
33917
+ setAriaLives(["polite", "off", "off"]);
33918
+ onMovePoint(0, p);
33919
+ }
33904
33920
  });
33905
33921
  const {
33906
33922
  visiblePoint: visiblePoint2,
@@ -33908,17 +33924,27 @@ const MovableLine = props => {
33908
33924
  } = useControlPoint({
33909
33925
  ariaLabel: ariaLabels == null ? void 0 : ariaLabels.point2AriaLabel,
33910
33926
  ariaDescribedBy: ariaDescribedBy,
33927
+ ariaLive: ariaLives[1],
33911
33928
  point: end,
33912
33929
  sequenceNumber: 2,
33913
33930
  color,
33914
- onMove: p => onMovePoint(1, p)
33931
+ onMove: p => {
33932
+ setAriaLives(["off", "polite", "off"]);
33933
+ onMovePoint(1, p);
33934
+ }
33915
33935
  });
33916
33936
  const line = /*#__PURE__*/React.createElement(Line$1, {
33937
+ ariaLabel: ariaLabels == null ? void 0 : ariaLabels.grabHandleAriaLabel,
33938
+ ariaDescribedBy: ariaDescribedBy,
33939
+ ariaLive: ariaLives[2],
33917
33940
  start: start,
33918
33941
  end: end,
33919
33942
  stroke: color,
33920
33943
  extend: extend,
33921
- onMove: onMoveLine
33944
+ onMove: delta => {
33945
+ setAriaLives(["off", "off", "polite"]);
33946
+ onMoveLine(delta);
33947
+ }
33922
33948
  });
33923
33949
  return /*#__PURE__*/React.createElement(React.Fragment, null, focusableHandle1, line, focusableHandle2, visiblePoint1, visiblePoint2);
33924
33950
  };
@@ -33927,9 +33953,12 @@ const Line$1 = props => {
33927
33953
  const {
33928
33954
  start,
33929
33955
  end,
33930
- onMove,
33956
+ ariaLabel,
33957
+ ariaDescribedBy,
33958
+ ariaLive,
33931
33959
  extend,
33932
- stroke = defaultStroke
33960
+ stroke = defaultStroke,
33961
+ onMove
33933
33962
  } = props;
33934
33963
  const [startPtPx, endPtPx] = useTransformVectorsToPixels(start, end);
33935
33964
  const {
@@ -33959,11 +33988,19 @@ const Line$1 = props => {
33959
33988
  return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("g", {
33960
33989
  ref: line,
33961
33990
  tabIndex: disableKeyboardInteraction ? -1 : 0,
33991
+ "aria-label": ariaLabel,
33992
+ "aria-describedby": ariaDescribedBy,
33993
+ "aria-live": ariaLive,
33962
33994
  className: "movable-line",
33963
33995
  "data-testid": "movable-line",
33964
33996
  style: {
33965
33997
  cursor: dragging ? "grabbing" : "grab"
33966
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"
33967
34004
  }, /*#__PURE__*/React.createElement(SVGLine, {
33968
34005
  start: startPtPx,
33969
34006
  end: endPtPx,
@@ -34518,6 +34555,12 @@ const LinearGraph = (props, key) => {
34518
34555
  point2X: srFormatNumber(line[1][0], locale),
34519
34556
  point2Y: srFormatNumber(line[1][1], locale)
34520
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
+ });
34521
34564
 
34522
34565
  // Slope description
34523
34566
  const slope = (line[1][1] - line[0][1]) / (line[1][0] - line[0][0]);
@@ -34559,9 +34602,13 @@ const LinearGraph = (props, key) => {
34559
34602
  // Outer line minimal description
34560
34603
  ,
34561
34604
  "aria-label": strings.srLinearGraph,
34562
- "aria-describedby": `${pointsDescriptionId} ${interceptDescriptionId} ${slopeDescriptionId}`
34605
+ "aria-describedby": `${pointsDescriptionId} ${interceptDescriptionId} ${slopeDescriptionId}`,
34606
+ role: "figure"
34563
34607
  }, /*#__PURE__*/React.createElement(MovableLine, {
34564
34608
  key: 0,
34609
+ ariaLabels: {
34610
+ grabHandleAriaLabel: grabHandleAriaLabel
34611
+ },
34565
34612
  ariaDescribedBy: `${interceptDescriptionId} ${slopeDescriptionId}`,
34566
34613
  points: line,
34567
34614
  onMoveLine: delta => {
@@ -45507,7 +45554,7 @@ const init = function init() {
45507
45554
 
45508
45555
  // This file is processed by a Rollup plugin (replace) to inject the production
45509
45556
  const libName = "@khanacademy/perseus";
45510
- const libVersion = "49.1.1";
45557
+ const libVersion = "49.1.2";
45511
45558
  addLibraryVersionToPerseusDebug(libName, libVersion);
45512
45559
 
45513
45560
  const apiVersion = {