@khanacademy/perseus 21.5.0 → 21.6.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/index.css CHANGED
@@ -3518,6 +3518,9 @@ body.mobile .framework-perseus table.perseus-widget-table-of-values.non-markdown
3518
3518
  font-size: 18px;
3519
3519
  }
3520
3520
  }
3521
+ .perseus-widget-editor-content .locked-figure-accordion h2 {
3522
+ padding-top: 0;
3523
+ }
3521
3524
  .keypad-input {
3522
3525
  outline: none !important;
3523
3526
  }
package/dist/index.d.ts CHANGED
@@ -51,7 +51,7 @@ export { default as KhanMath } from "./util/math";
51
51
  export { default as LoadingContext } from "./loading-context";
52
52
  export { default as mediaQueries } from "./styles/media-queries";
53
53
  export { default as PerseusMarkdown } from "./perseus-markdown";
54
- export { PerseusExpressionAnswerFormConsidered, plotterPlotTypes, ItemExtras, } from "./perseus-types";
54
+ export { PerseusExpressionAnswerFormConsidered, plotterPlotTypes, ItemExtras, lockedFigureColors, } from "./perseus-types";
55
55
  export { traverse } from "./traversal";
56
56
  export { isItemRenderableByVersion } from "./renderability";
57
57
  export { violatingWidgets } from "./a11y";
@@ -86,7 +86,7 @@ export type { ILogger, LogErrorOptions, ErrorKind } from "./logging/log";
86
86
  export type { ServerItemRenderer as ServerItemRendererComponent } from "./server-item-renderer";
87
87
  export type { Alignment, APIOptions, APIOptionsWithDefaults, ChangeHandler, DeviceType, DomInsertCheckFn, EditorMode, FocusPath, Hint, ImageDict, ImageUploader, JiptLabelStore, JiptRenderer, PerseusDependencies, PerseusScore, Version, VideoData, VideoKind, WidgetDict, WidgetExports, } from "./types";
88
88
  export type { ParsedValue } from "./util";
89
- export type { LockedFigure, LockedFigureType, LockedPoint, PerseusGraphType, PerseusAnswerArea, PerseusExpressionWidgetOptions, Range, Size, MathFormat, InputNumberWidget, // TODO(jeremy): remove?
89
+ export type { LockedFigure, LockedFigureColor, LockedFigureType, LockedPointType, LockedLineType, PerseusGraphType, PerseusAnswerArea, PerseusExpressionWidgetOptions, Range, Size, MathFormat, InputNumberWidget, // TODO(jeremy): remove?
90
90
  PerseusImageBackground, PerseusInputNumberWidgetOptions, PerseusInteractiveGraphWidgetOptions, PerseusItem, PerseusPlotterWidgetOptions, PerseusPythonProgramWidgetOptions, PerseusRadioWidgetOptions, PerseusExampleWidgetOptions, PerseusExampleGraphieWidgetOptions, PerseusSimpleMarkdownTesterWidgetOptions, PerseusRenderer, PerseusWidget, PerseusWidgetsMap, } from "./perseus-types";
91
91
  export type { Coord } from "./interactive2/types";
92
92
  export type { MarkerType } from "./widgets/label-image/types";
package/dist/index.js CHANGED
@@ -22853,7 +22853,7 @@ const FocusRing = function (props) {
22853
22853
  borderRadius
22854
22854
  };
22855
22855
  return /*#__PURE__*/React__namespace.createElement("span", {
22856
- "data-test-id": "focus-ring",
22856
+ "data-testid": "focus-ring",
22857
22857
  className: aphrodite.css(styles$z.ring),
22858
22858
  style: style
22859
22859
  }, children);
@@ -22924,7 +22924,7 @@ const CrossOutLine = function (props) {
22924
22924
  height: CROSS_OUT_LINE_SIZE,
22925
22925
  viewBox: `0 0 ${CROSS_OUT_LINE_SIZE} ${CROSS_OUT_LINE_SIZE}`,
22926
22926
  className: aphrodite.css(styles$x.crossOutLine),
22927
- "data-test-id": "choice-icon__cross-out-line"
22927
+ "data-testid": "choice-icon__cross-out-line"
22928
22928
  }, /*#__PURE__*/React__namespace.createElement("line", {
22929
22929
  // The line stretches from the bottom-left to top-right.
22930
22930
  // We don't quite go to the _very_ corner, because the cute
@@ -23027,7 +23027,7 @@ const ChoiceIcon = function (props) {
23027
23027
  }, /*#__PURE__*/React__namespace.createElement("div", {
23028
23028
  // @ts-expect-error - TS2322 - Type '{ backgroundColor: string | null | undefined; borderColor: string; color: string; borderRadius: number; }' is not assignable to type 'Properties<string | number, string & {}>'.
23029
23029
  style: dynamicStyles,
23030
- "data-test-id": "choice-icon__library-choice-icon",
23030
+ "data-testid": "choice-icon__library-choice-icon",
23031
23031
  className: aphrodite.css(styles$w.circle, showCorrectness && correct && styles$w.circleCorrect, showCorrectness && !correct && styles$w.circleIncorrect, showCorrectness && !correct && (checked || previouslyAnswered) && styles$w.circleIncorrectAnswered)
23032
23032
  // used in BaseRadio editMode to check
23033
23033
  // if we actually clicked on the radio icon
@@ -23383,7 +23383,7 @@ const Choice = function (props) {
23383
23383
  });
23384
23384
  })), showRationale && /*#__PURE__*/React__namespace.createElement("div", {
23385
23385
  className: rationaleClassName,
23386
- "data-test-id": `perseus-radio-rationale-content-${pos}`
23386
+ "data-testid": `perseus-radio-rationale-content-${pos}`
23387
23387
  }, rationale));
23388
23388
  };
23389
23389
  const styles$u = aphrodite.StyleSheet.create({
@@ -28322,44 +28322,99 @@ class Graph extends React__namespace.Component {
28322
28322
  }
28323
28323
  }
28324
28324
 
28325
- /**
28326
- * Takes a style object with color names and converts them to actual
28327
- * Wonder Blocks color values. This way, we can use colors and their
28328
- * names in the editor UI without having to convert them back and forth.
28329
- */
28330
- function convertStyle(style) {
28331
- return {
28332
- ...style,
28333
- stroke: wonderBlocksTokens.color[style?.stroke || "blue"],
28334
- fill: wonderBlocksTokens.color[style?.fill || "blue"]
28335
- };
28336
- }
28325
+ const LockedLine = props => {
28326
+ const {
28327
+ color,
28328
+ lineStyle,
28329
+ kind,
28330
+ points,
28331
+ showStartPoint,
28332
+ showEndPoint
28333
+ } = props;
28334
+ const [point1, point2] = points;
28335
+ let line;
28336
+ if (kind === "line" || kind === "segment") {
28337
+ const LineType = kind === "segment" ? mafs.Line.Segment : mafs.Line.ThroughPoints;
28338
+ line = /*#__PURE__*/React__namespace.createElement(LineType, {
28339
+ point1: point1.coord,
28340
+ point2: point2.coord,
28341
+ color: wonderBlocksTokens.color[color],
28342
+ style: lineStyle
28343
+ });
28344
+ } else {
28345
+ // TODO(LEMS-1928): Implement rays
28346
+ return null;
28347
+ }
28348
+ return /*#__PURE__*/React__namespace.createElement("g", {
28349
+ className: "locked-line"
28350
+ }, line, showStartPoint && /*#__PURE__*/React__namespace.createElement(mafs.Point, {
28351
+ x: point1.coord[0],
28352
+ y: point1.coord[1],
28353
+ svgCircleProps: {
28354
+ style: {
28355
+ fill: point1.filled ? wonderBlocksTokens.color[point1.color] : wonderBlocksTokens.color.white,
28356
+ stroke: wonderBlocksTokens.color[point1.color],
28357
+ strokeWidth: wonderBlocksTokens.spacing.xxxxSmall_2
28358
+ }
28359
+ }
28360
+ }), showEndPoint && /*#__PURE__*/React__namespace.createElement(mafs.Point, {
28361
+ x: point2.coord[0],
28362
+ y: point2.coord[1],
28363
+ svgCircleProps: {
28364
+ style: {
28365
+ fill: point2.filled ? wonderBlocksTokens.color[point2.color] : wonderBlocksTokens.color.white,
28366
+ stroke: wonderBlocksTokens.color[point2.color],
28367
+ strokeWidth: wonderBlocksTokens.spacing.xxxxSmall_2
28368
+ }
28369
+ }
28370
+ }));
28371
+ };
28372
+
28373
+ const LockedPoint = props => {
28374
+ const {
28375
+ color,
28376
+ coord,
28377
+ filled
28378
+ } = props;
28379
+ const [x, y] = coord;
28380
+ return /*#__PURE__*/React__namespace.createElement(mafs.Point, {
28381
+ x: x,
28382
+ y: y,
28383
+ svgCircleProps: {
28384
+ style: {
28385
+ fill: filled ? wonderBlocksTokens.color[color] : wonderBlocksTokens.color.white,
28386
+ stroke: wonderBlocksTokens.color[color],
28387
+ strokeWidth: wonderBlocksTokens.spacing.xxxxSmall_2
28388
+ }
28389
+ }
28390
+ });
28391
+ };
28392
+
28337
28393
  const GraphLockedLayer = props => {
28338
28394
  const {
28339
28395
  lockedFigures
28340
28396
  } = props;
28341
28397
  return /*#__PURE__*/React__namespace.createElement(React__namespace.Fragment, null, lockedFigures.map((figure, index) => {
28398
+ let Figure;
28342
28399
  switch (figure.type) {
28343
28400
  case "point":
28344
- const [x, y] = figure.coord;
28345
- return /*#__PURE__*/React__namespace.createElement(mafs.Point, {
28346
- key: `${figure.type}-${index}`,
28347
- x: x,
28348
- y: y,
28349
- svgCircleProps: {
28350
- style: convertStyle(figure.style)
28351
- }
28352
- });
28353
- }
28354
-
28355
- /**
28356
- * Devlopment-time future-proofing: This `never` should
28357
- * fail during type-checking if we add a new locked
28358
- * shape type and forget to handle it in any other
28359
- * switch case here.
28360
- */
28361
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
28362
- throw new wonderStuffCore.UnreachableCaseError(figure.type);
28401
+ Figure = LockedPoint;
28402
+ break;
28403
+ case "line":
28404
+ Figure = LockedLine;
28405
+ break;
28406
+ default:
28407
+ /**
28408
+ * Devlopment-time future-proofing: This should
28409
+ * fail during type-checking if we add a new locked
28410
+ * shape type and forget to handle it in any other
28411
+ * switch case here.
28412
+ */
28413
+ throw new wonderStuffCore.UnreachableCaseError(figure);
28414
+ }
28415
+ return /*#__PURE__*/React__namespace.createElement(Figure, _extends({
28416
+ key: `${figure.type}-${index}`
28417
+ }, figure));
28363
28418
  }));
28364
28419
  };
28365
28420
 
@@ -28511,7 +28566,7 @@ function SVGLine(props) {
28511
28566
  y2: end[1],
28512
28567
  style: style,
28513
28568
  className: `${className}`,
28514
- "data-test-id": testId
28569
+ "data-testid": testId
28515
28570
  });
28516
28571
  }
28517
28572
 
@@ -28640,7 +28695,7 @@ const MovableLine = props => {
28640
28695
  ref: line,
28641
28696
  tabIndex: 0,
28642
28697
  className: "movable-line",
28643
- "data-test-id": "movable-line",
28698
+ "data-testid": "movable-line",
28644
28699
  style: {
28645
28700
  cursor: dragging ? "grabbing" : "grab"
28646
28701
  }
@@ -28742,7 +28797,7 @@ const StyledMovablePoint = props => {
28742
28797
  style: {
28743
28798
  "--movable-point-color": color
28744
28799
  },
28745
- "data-test-id": "movable-point"
28800
+ "data-testid": "movable-point"
28746
28801
  }, /*#__PURE__*/React__namespace.createElement("circle", {
28747
28802
  className: "movable-point-hitbox",
28748
28803
  r: hitboxSizePx / 2,
@@ -28767,7 +28822,7 @@ const StyledMovablePoint = props => {
28767
28822
  style: {
28768
28823
  fill: color
28769
28824
  },
28770
- "data-test-id": "movable-point__center"
28825
+ "data-testid": "movable-point__center"
28771
28826
  })));
28772
28827
  };
28773
28828
 
@@ -28786,8 +28841,7 @@ const SegmentGraph = props => {
28786
28841
  },
28787
28842
  onMovePoint: (endpointIndex, destination) => {
28788
28843
  dispatch(moveControlPoint(endpointIndex, destination, i));
28789
- },
28790
- "data-testid": "segment" + i
28844
+ }
28791
28845
  })));
28792
28846
  };
28793
28847
  const SegmentView = props => {
@@ -28817,8 +28871,7 @@ const LinearGraph = props => {
28817
28871
  dispatch
28818
28872
  } = props;
28819
28873
  const {
28820
- coords: lines,
28821
- type
28874
+ coords: lines
28822
28875
  } = props.graphState;
28823
28876
  const colors = ["var(--movable-line-stroke-color)", "var(--mafs-violet)"];
28824
28877
  return /*#__PURE__*/React__namespace.createElement(React__namespace.Fragment, null, lines?.map((line, i) => /*#__PURE__*/React__namespace.createElement(LineView, {
@@ -28827,10 +28880,7 @@ const LinearGraph = props => {
28827
28880
  onMoveLine: delta => {
28828
28881
  dispatch(moveLine(i, delta));
28829
28882
  },
28830
- onMovePoint: (endpointIndex, destination) => dispatch(moveControlPoint(endpointIndex, destination, i))
28831
- // "linear" or "linear-system" + index
28832
- ,
28833
- "data-testid": type + i,
28883
+ onMovePoint: (endpointIndex, destination) => dispatch(moveControlPoint(endpointIndex, destination, i)),
28834
28884
  stroke: colors[i]
28835
28885
  })));
28836
28886
  };
@@ -29077,7 +29127,6 @@ const PolygonGraph = props => {
29077
29127
  } = props;
29078
29128
  const {
29079
29129
  coords,
29080
- type,
29081
29130
  showAngles,
29082
29131
  showSides,
29083
29132
  range,
@@ -29149,8 +29198,7 @@ const PolygonGraph = props => {
29149
29198
  }), points.map((point, i) => /*#__PURE__*/React__namespace.createElement(StyledMovablePoint, {
29150
29199
  key: "point-" + i,
29151
29200
  point: point,
29152
- onMove: destination => dispatch(movePoint(i, destination)),
29153
- "data-testid": type + i
29201
+ onMove: destination => dispatch(movePoint(i, destination))
29154
29202
  })));
29155
29203
  };
29156
29204
 
@@ -42644,7 +42692,7 @@ const init = function (options) {
42644
42692
 
42645
42693
  // This file is processed by a Rollup plugin (replace) to inject the production
42646
42694
  const libName = "@khanacademy/perseus";
42647
- const libVersion = "21.5.0";
42695
+ const libVersion = "21.6.0";
42648
42696
  perseusCore.addLibraryVersionToPerseusDebug(libName, libVersion);
42649
42697
 
42650
42698
  const apiVersion = {
@@ -43777,6 +43825,7 @@ const PerseusExpressionAnswerFormConsidered = ["correct", "wrong", "ungraded"];
43777
43825
 
43778
43826
  // 2D range: xMin, xMax, yMin, yMax
43779
43827
 
43828
+ const lockedFigureColors = ["purple", "blue", "teal", "green", "gold", "red", "pink"];
43780
43829
  const plotterPlotTypes = ["bar", "line", "pic", "histogram", "dotplot"];
43781
43830
 
43782
43831
  /**
@@ -45823,6 +45872,7 @@ exports.itemDataVersion = itemDataVersion;
45823
45872
  exports.itemToTree = itemToTree;
45824
45873
  exports.itemVersion = ItemVersion;
45825
45874
  exports.libVersion = libVersion;
45875
+ exports.lockedFigureColors = lockedFigureColors;
45826
45876
  exports.mediaQueries = mediaQueries;
45827
45877
  exports.parsePerseusItem = parsePerseusItem;
45828
45878
  exports.plotterPlotTypes = plotterPlotTypes;