@khanacademy/perseus 56.2.0 → 57.0.0

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
@@ -16542,7 +16542,7 @@ Zoomable.defaultProps = {
16542
16542
  * measurements.
16543
16543
  */
16544
16544
  const computeMathBounds = (parentNode, parentBounds) => {
16545
- const textElement = parentNode.querySelector(".katex-html") || parentNode.querySelector(".MathJax");
16545
+ const textElement = parentNode.querySelector(".MathJax");
16546
16546
  const textBounds = {
16547
16547
  // @ts-expect-error - TS2531 - Object is possibly 'null'. | TS2339 - Property 'offsetWidth' does not exist on type 'Element'.
16548
16548
  width: textElement.offsetWidth,
@@ -18625,14 +18625,7 @@ class Renderer extends React.Component {
18625
18625
  }, content)))));
18626
18626
  }
18627
18627
  if (node.type === "math") {
18628
- // Replace uses of \begin{align}...\end{align} which KaTeX doesn't
18629
- // support (yet) with \begin{aligned}...\end{aligned} which renders
18630
- // the same is supported by KaTeX. It does the same for align*.
18631
- // TODO(kevinb) update content to use aligned instead of align.
18632
- // TODO(LEMS-1608) Remove this replacement as MathJax supports the
18633
- // "align" macro correctly (and, in fact, it is not synonymous with
18634
- // "aligned").
18635
- const tex = node.content.replace(/\{align[*]?\}/g, "{aligned}");
18628
+ const tex = node.content;
18636
18629
 
18637
18630
  // We render math here instead of in perseus-markdown.jsx
18638
18631
  // because we need to pass it our onRender callback.
@@ -24014,7 +24007,8 @@ const _choiceTransform = (widgetOptions, strings, problemNum) => {
24014
24007
  // Add meta-information to choices
24015
24008
  const choices = widgetOptions.choices.map((choice, i) => {
24016
24009
  return _extends({}, choice, {
24017
- originalIndex: i
24010
+ originalIndex: i,
24011
+ correct: Boolean(choice.correct)
24018
24012
  });
24019
24013
  });
24020
24014
 
@@ -25004,7 +24998,7 @@ class GradedGroupAnswerBar extends React.Component {
25004
24998
  }
25005
24999
  }
25006
25000
  GradedGroupAnswerBar.contextType = PerseusI18nContext;
25007
- const fontSize = 17;
25001
+ const fontSize$1 = 17;
25008
25002
  const styles$j = {
25009
25003
  answerBar: {
25010
25004
  display: "flex",
@@ -25029,7 +25023,7 @@ const styles$j = {
25029
25023
  flexDirection: "row",
25030
25024
  alignItems: "center",
25031
25025
  fontWeight: "bold",
25032
- fontSize: fontSize
25026
+ fontSize: fontSize$1
25033
25027
  }
25034
25028
  };
25035
25029
 
@@ -27685,6 +27679,7 @@ const defaultGraphConfig = {
27685
27679
  width: 0,
27686
27680
  height: 0,
27687
27681
  labels: [],
27682
+ labelLocation: "onAxis",
27688
27683
  disableKeyboardInteraction: false,
27689
27684
  interactiveColor: "var(--mafs-blue)"
27690
27685
  };
@@ -27900,6 +27895,8 @@ function escapeIfUnescaped(character) {
27900
27895
  }
27901
27896
  }
27902
27897
 
27898
+ // Exported for testing purposes
27899
+ const fontSize = 14;
27903
27900
  function AxisLabels({
27904
27901
  i18n
27905
27902
  }) {
@@ -27907,24 +27904,26 @@ function AxisLabels({
27907
27904
  range,
27908
27905
  labels,
27909
27906
  width,
27910
- height
27907
+ height,
27908
+ labelLocation
27911
27909
  } = useGraphConfig();
27912
27910
  const {
27913
27911
  strings
27914
27912
  } = i18n;
27915
- const yAxisLabelLocation = [0, range[Y][MAX]];
27916
- const xAxisLabelLocation = [range[X][MAX], 0];
27917
- const [xAxisLabelText, yAxisLabelText] = labels;
27918
27913
  const graphInfo = {
27919
27914
  range,
27920
27915
  width,
27921
27916
  height
27922
27917
  };
27923
- const [x1, y1] = pointToPixel(xAxisLabelLocation, graphInfo);
27924
- // The default location for the y-axis-label is at the maximum y point
27925
- // This is just underneath the tick line for that point. The -24 moves the
27926
- // label up one grid square, so it sits on top of the graph
27927
- const [x2, y2] = vec.add(pointToPixel(yAxisLabelLocation, graphInfo), [0, -24]);
27918
+
27919
+ // Get the position of the main axis labels
27920
+ const [xAxisLabelLocation, yAxisLabelLocation] = getLabelPosition(graphInfo, labelLocation);
27921
+ const [xAxisLabelText, yAxisLabelText] = labels;
27922
+
27923
+ // If the labels are rotated, we need to center the
27924
+ // x-axis label along the bottom of the graph.
27925
+ const xLabelTransform = labelLocation === "onAxis" ? "translate(7px, -50%)" : "translate(-50%, -50%)";
27926
+ const yLabelTransform = labelLocation === "onAxis" ? "translate(-50%, 0px)" : "translate(-50%, 0px) rotate(-90deg)";
27928
27927
  const {
27929
27928
  TeX
27930
27929
  } = getDependencies();
@@ -27932,22 +27931,53 @@ function AxisLabels({
27932
27931
  "aria-label": strings.xAxis,
27933
27932
  style: {
27934
27933
  position: "absolute",
27935
- left: x1,
27936
- top: y1,
27937
- fontSize: "14px",
27938
- transform: "translate(7px, -50%)"
27934
+ left: xAxisLabelLocation[X],
27935
+ top: xAxisLabelLocation[Y],
27936
+ fontSize: fontSize + "px",
27937
+ transform: xLabelTransform
27939
27938
  }
27940
27939
  }, /*#__PURE__*/React__default.createElement(TeX, null, replaceOutsideTeX(xAxisLabelText))), /*#__PURE__*/React__default.createElement("span", {
27941
27940
  "aria-label": strings.yAxis,
27942
27941
  style: {
27943
27942
  position: "absolute",
27944
- left: x2,
27945
- top: y2,
27946
- fontSize: "14px",
27947
- transform: "translate(-50%, 0px)"
27943
+ left: yAxisLabelLocation[X],
27944
+ top: yAxisLabelLocation[Y],
27945
+ fontSize: fontSize + "px",
27946
+ transform: yLabelTransform
27948
27947
  }
27949
27948
  }, /*#__PURE__*/React__default.createElement(TeX, null, replaceOutsideTeX(yAxisLabelText))));
27950
27949
  }
27950
+ const getLabelPosition = (graphInfo, labelLocation) => {
27951
+ // If the labels are placed along the edge of the graph, we need to place them at the
27952
+ // center of the graph, which is the average of the min and max values of the axes.
27953
+ if (labelLocation === "alongEdge") {
27954
+ // Offset the labels by a certain amount based on the range of the graph, to ensure that
27955
+ // the labels do not overlap with the axis tick if they are out of the graph bounds.
27956
+ const xAxisLabelOffset = graphInfo.range[Y][MIN] >= 0 ? [0, fontSize * 3] // Move the label down by 3 font sizes if the y-axis min is positive
27957
+ : [0, fontSize]; // Move the label down by 1 font size if the y-axis min is negative
27958
+ const yAxisLabelOffset = graphInfo.range[X][MIN] >= 0 ? [-fontSize * 3, -fontSize] // Move the label left by 3 font sizes if the x-axis min is positive
27959
+ : [-fontSize, -fontSize]; // Move the label left by 1 font size if the x-axis min is negative
27960
+
27961
+ // Calculate the location of the labels to be halfway between the min and max values of the axes
27962
+ const xAxisLabelLocation = [(graphInfo.range[X][MIN] + graphInfo.range[X][MAX]) / 2, graphInfo.range[Y][MIN]];
27963
+ const yAxisLabelLocation = [graphInfo.range[X][MIN], (graphInfo.range[Y][MIN] + graphInfo.range[Y][MAX]) / 2];
27964
+
27965
+ // Convert the Vector2 coordinates to pixel coordinates and add the offsets
27966
+ const _xLabel = vec.add(pointToPixel(xAxisLabelLocation, graphInfo), xAxisLabelOffset);
27967
+ const _yLabel = vec.add(pointToPixel(yAxisLabelLocation, graphInfo), yAxisLabelOffset);
27968
+ return [_xLabel, _yLabel];
27969
+ }
27970
+
27971
+ // Otherwise, the labels are placed on the axes (default), and we need to
27972
+ // place them at the end of the axis, which is the maximum value of the axis.
27973
+ const xLabelInitial = [graphInfo.range[X][MAX], 0];
27974
+ const yLabelInitial = [0, graphInfo.range[Y][MAX]];
27975
+ const yLabelOffset = [0, -fontSize * 2]; // Move the y-axis label up by 2 font sizes
27976
+
27977
+ const xLabel = pointToPixel(xLabelInitial, graphInfo);
27978
+ const yLabel = vec.add(pointToPixel(yLabelInitial, graphInfo), yLabelOffset);
27979
+ return [xLabel, yLabel];
27980
+ };
27951
27981
 
27952
27982
  // The size of the ticks and labels in pixels
27953
27983
  const tickSize = 10;
@@ -34197,6 +34227,7 @@ const MafsGraph = props => {
34197
34227
  state,
34198
34228
  dispatch,
34199
34229
  labels,
34230
+ labelLocation,
34200
34231
  readOnly,
34201
34232
  fullGraphAriaLabel,
34202
34233
  fullGraphAriaDescription
@@ -34277,6 +34308,7 @@ const MafsGraph = props => {
34277
34308
  width,
34278
34309
  height,
34279
34310
  labels,
34311
+ labelLocation,
34280
34312
  disableKeyboardInteraction: disableInteraction,
34281
34313
  // If the graph is read-only or static, we want to make it
34282
34314
  // visually clear that the graph is no longer interactive.
@@ -41388,7 +41420,7 @@ const addLibraryVersionToPerseusDebug = (libraryName, libraryVersion) => {
41388
41420
 
41389
41421
  // This file is processed by a Rollup plugin (replace) to inject the production
41390
41422
  const libName = "@khanacademy/perseus";
41391
- const libVersion = "56.2.0";
41423
+ const libVersion = "57.0.0";
41392
41424
  addLibraryVersionToPerseusDebug(libName, libVersion);
41393
41425
 
41394
41426
  const apiVersion = {