@khanacademy/perseus 20.4.1 → 20.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.d.ts CHANGED
@@ -68,6 +68,7 @@ export * as SizingUtils from "./util/sizing-utils";
68
68
  export { getAnswersFromWidgets, injectWidgets, } from "./util/extract-perseus-data";
69
69
  export { parsePerseusItem } from "./util/parse-perseus-json";
70
70
  export { generateTestPerseusItem, genericPerseusItemData, } from "./util/test-utils";
71
+ export { convertWidgetNameToEnum, getWidgetTypeFromWidgetId, } from "./util/widget-enum-utils";
71
72
  /**
72
73
  * Mixins
73
74
  */
package/dist/index.js CHANGED
@@ -33,6 +33,7 @@ var caretDown = require('@phosphor-icons/core/assets/regular/caret-down.svg');
33
33
  var caretUp = require('@phosphor-icons/core/assets/regular/caret-up.svg');
34
34
  var debounce$1 = require('lodash.debounce');
35
35
  var mafs = require('mafs');
36
+ var wonderBlocksTokens = require('@khanacademy/wonder-blocks-tokens');
36
37
  var wonderBlocksIcon = require('@khanacademy/wonder-blocks-icon');
37
38
  var questionIcon = require('@phosphor-icons/core/regular/question.svg');
38
39
  var wonderBlocksTypography = require('@khanacademy/wonder-blocks-typography');
@@ -19559,7 +19560,6 @@ class Renderer extends React__namespace.Component {
19559
19560
 
19560
19561
  // @ts-expect-error - TS2322 - Type '(props: Props) => Partial<Record<string, CategorizerWidget | CSProgramWidget | DefinitionWidget | DropdownWidget | ... 35 more ... | VideoWidget>>' is not assignable to type '(props: Props) => { [key: string]: PerseusWidget; }'.
19561
19562
  _getAllWidgetsInfo = props => {
19562
- // @ts-expect-error - TS2345 - Argument of type '{ [key: string]: PerseusWidget; }' is not assignable to parameter of type 'Partial<Record<string, CategorizerWidget>>'.
19563
19563
  return mapObject$1(props.widgets, (widgetInfo, widgetId) => {
19564
19564
  if (!widgetInfo.type || !widgetInfo.alignment) {
19565
19565
  const newValues = {};
@@ -28278,6 +28278,18 @@ class Graph extends React__namespace.Component {
28278
28278
  }
28279
28279
  }
28280
28280
 
28281
+ /**
28282
+ * Takes a style object with color names and converts them to actual
28283
+ * Wonder Blocks color values. This way, we can use colors and their
28284
+ * names in the editor UI without having to convert them back and forth.
28285
+ */
28286
+ function convertStyle(style) {
28287
+ return {
28288
+ ...style,
28289
+ stroke: wonderBlocksTokens.color[style?.stroke || "blue"],
28290
+ fill: wonderBlocksTokens.color[style?.fill || "blue"]
28291
+ };
28292
+ }
28281
28293
  const GraphLockedLayer = props => {
28282
28294
  const {
28283
28295
  lockedFigures
@@ -28291,7 +28303,7 @@ const GraphLockedLayer = props => {
28291
28303
  x: x,
28292
28304
  y: y,
28293
28305
  svgCircleProps: {
28294
- style: figure.style
28306
+ style: convertStyle(figure.style)
28295
28307
  }
28296
28308
  });
28297
28309
  }
@@ -29690,7 +29702,7 @@ const makeInvalidTypeError = (functionName, graphType) => {
29690
29702
 
29691
29703
  // There's no transform function in exports
29692
29704
 
29693
- class InteractiveGraph extends React__namespace.Component {
29705
+ class LegacyInteractiveGraph extends React__namespace.Component {
29694
29706
  // @ts-expect-error - TS2564 - Property 'points' has no initializer and is not definitely assigned in the constructor.
29695
29707
 
29696
29708
  // @ts-expect-error - TS2564 - Property 'shouldResetGraphie' has no initializer and is not definitely assigned in the constructor.
@@ -29710,7 +29722,6 @@ class InteractiveGraph extends React__namespace.Component {
29710
29722
  type: "linear"
29711
29723
  }
29712
29724
  };
29713
- mafsRef = /*#__PURE__*/React__namespace.createRef();
29714
29725
  state = {
29715
29726
  shouldShowInstructions: _getShouldShowInstructions(this.props)
29716
29727
  };
@@ -30821,26 +30832,13 @@ class InteractiveGraph extends React__namespace.Component {
30821
30832
  graph: graph
30822
30833
  });
30823
30834
  };
30824
- getUserInput = () => this.mafsRef.current?.getUserInput?.() ?? InteractiveGraph.getUserInputFromProps(this.props);
30835
+ getUserInput = () => InteractiveGraph.getUserInputFromProps(this.props);
30825
30836
  simpleValidate = rubric => InteractiveGraph.validate(this.getUserInput(), rubric, this);
30826
30837
  focus = $__default["default"].noop;
30827
-
30828
- // const segment: boolean = useFeatureIsOn("mafs-segment-graph");
30829
- // <Renderer apiOptions={{flags: {mafs: {segment}}}}
30830
30838
  render() {
30831
30839
  const box = getInteractiveBoxFromSizeClass(this.props.containerSizeClass);
30832
30840
  const gridStep = this.props.gridStep || Util.getGridStep(this.props.range, this.props.step, box[0]);
30833
30841
  const snapStep = this.props.snapStep || Util.snapStepFromGridStep(gridStep);
30834
-
30835
- // Mafs shim
30836
- if (this.props.apiOptions?.flags?.["mafs"]?.[this.props.graph.type]) {
30837
- return /*#__PURE__*/React__namespace.createElement(MafsGraph, _extends({}, this.props, {
30838
- ref: this.mafsRef,
30839
- gridStep: gridStep,
30840
- snapStep: snapStep,
30841
- box: box
30842
- }));
30843
- }
30844
30842
  let instructions;
30845
30843
  // isClickToAddPoints() only applies to points and polygons
30846
30844
  if (this.isClickToAddPoints() && this.state.shouldShowInstructions) {
@@ -30886,6 +30884,52 @@ class InteractiveGraph extends React__namespace.Component {
30886
30884
  isMobile: isMobile
30887
30885
  }));
30888
30886
  }
30887
+ }
30888
+ class InteractiveGraph extends React__namespace.Component {
30889
+ legacyGraphRef = /*#__PURE__*/React__namespace.createRef();
30890
+ mafsRef = /*#__PURE__*/React__namespace.createRef();
30891
+ static defaultProps = {
30892
+ labels: ["x", "y"],
30893
+ range: [[-10, 10], [-10, 10]],
30894
+ step: [1, 1],
30895
+ backgroundImage: defaultBackgroundImage,
30896
+ markings: "graph",
30897
+ showTooltips: false,
30898
+ showProtractor: false,
30899
+ showRuler: false,
30900
+ rulerLabel: "",
30901
+ rulerTicks: 10,
30902
+ graph: {
30903
+ type: "linear"
30904
+ }
30905
+ };
30906
+ getUserInput = () => {
30907
+ if (this.mafsRef.current) {
30908
+ return this.mafsRef.current.getUserInput?.();
30909
+ }
30910
+ if (this.legacyGraphRef.current) {
30911
+ return this.legacyGraphRef.current.getUserInput();
30912
+ }
30913
+ throw new PerseusError("Cannot getUserInput from a graph that has never rendered", Errors.NotAllowed);
30914
+ };
30915
+ simpleValidate = rubric => InteractiveGraph.validate(this.getUserInput?.(), rubric, this);
30916
+ render() {
30917
+ // Mafs shim
30918
+ if (this.props.apiOptions?.flags?.["mafs"]?.[this.props.graph.type]) {
30919
+ const box = getInteractiveBoxFromSizeClass(this.props.containerSizeClass);
30920
+ const gridStep = this.props.gridStep || Util.getGridStep(this.props.range, this.props.step, box[0]);
30921
+ const snapStep = this.props.snapStep || Util.snapStepFromGridStep(gridStep);
30922
+ return /*#__PURE__*/React__namespace.createElement(MafsGraph, _extends({}, this.props, {
30923
+ ref: this.mafsRef,
30924
+ gridStep: gridStep,
30925
+ snapStep: snapStep,
30926
+ box: box
30927
+ }));
30928
+ }
30929
+ return /*#__PURE__*/React__namespace.createElement(LegacyInteractiveGraph, _extends({
30930
+ ref: this.legacyGraphRef
30931
+ }, this.props));
30932
+ }
30889
30933
  static getQuadraticCoefficients(coords) {
30890
30934
  const p1 = coords[0];
30891
30935
  const p2 = coords[1];
@@ -41605,7 +41649,7 @@ const init = function (options) {
41605
41649
 
41606
41650
  // This file is processed by a Rollup plugin (replace) to inject the production
41607
41651
  const libName = "@khanacademy/perseus";
41608
- const libVersion = "20.4.1";
41652
+ const libVersion = "20.6.0";
41609
41653
  perseusCore.addLibraryVersionToPerseusDebug(libName, libVersion);
41610
41654
 
41611
41655
  const apiVersion = {
@@ -42377,7 +42421,6 @@ class ServerItemRenderer extends React__namespace.Component {
42377
42421
  const qScore = this.questionRenderer.scoreWidgets();
42378
42422
  const qGuess = this.questionRenderer.getUserInputForWidgets();
42379
42423
  const state = this.questionRenderer.getSerializedState();
42380
- // @ts-expect-error - TS2322 - Type 'Partial<Record<string, KEScore>>' is not assignable to type '{ [key: string]: KEScore; }'. | TS2345 - Argument of type '{ [widgetId: string]: PerseusScore; }' is not assignable to parameter of type 'Partial<Record<string, { type: "invalid"; message?: string | null | undefined; suppressAlmostThere?: boolean | null | undefined; }>>'.
42381
42424
  return mapObject(qScore, (score, id) => {
42382
42425
  return Util.keScoreFromPerseusScore(score, qGuess[id], state);
42383
42426
  });
@@ -44309,6 +44352,71 @@ function generateTestPerseusItem() {
44309
44352
  };
44310
44353
  }
44311
44354
 
44355
+ /**
44356
+ * Some helpers for CEDAR logging. CEDAR convention dictates
44357
+ * that enum values should be upper case. Ex: for the
44358
+ * PerseusWidgetUsedInProblemAttempt CEDAR event, we needed
44359
+ * to: get the type and convert that to an enum value.
44360
+ */
44361
+
44362
+ const widgetNameToEnum = {
44363
+ categorizer: "CATEGORIZER",
44364
+ "cs-program": "CS_PROGRAM",
44365
+ definition: "DEFINITION",
44366
+ "deprecated-standin": "DEPRECATED_STANDIN",
44367
+ dropdown: "DROPDOWN",
44368
+ explanation: "EXPLANATION",
44369
+ expression: "EXPRESSION",
44370
+ "graded-group-set": "GRADED_GROUP_SET",
44371
+ "graded-group": "GRADED_GROUP",
44372
+ grapher: "GRAPHER",
44373
+ group: "GROUP",
44374
+ iframe: "IFRAME",
44375
+ image: "IMAGE",
44376
+ "input-number": "INPUT_NUMBER",
44377
+ interaction: "INTERACTIVE",
44378
+ "interactive-graph": "INTERACTIVE_GRAPH",
44379
+ "label-image": "LABEL_IMAGE",
44380
+ "lights-puzzle": "LIGHTS_PUZZLE",
44381
+ matcher: "MATCHER",
44382
+ matrix: "MATRIX",
44383
+ measurer: "MEASURER",
44384
+ "molecule-renderer": "MOLECULE",
44385
+ "number-line": "NUMBER_LINE",
44386
+ "numeric-input": "NUMERIC_INPUT",
44387
+ orderer: "ORDERER",
44388
+ passage: "PASSAGE",
44389
+ "passage-ref": "PASSAGE_REF",
44390
+ "passage-ref-target": "PASSAGE_REF_TARGET",
44391
+ plotter: "PLOTTER",
44392
+ "python-program": "PYTHON_PROGRAM",
44393
+ "reaction-diagram": "REACTION_DIAGRAM",
44394
+ radio: "RADIO",
44395
+ sequence: "SEQUENCE",
44396
+ simulator: "SIMULATOR",
44397
+ sorter: "SORTER",
44398
+ table: "TABLE",
44399
+ "unit-input": "UNIT",
44400
+ video: "VIDEO"
44401
+ };
44402
+ function convertWidgetNameToEnum(name) {
44403
+ const widgetEnum = widgetNameToEnum[name];
44404
+ if (!widgetEnum) {
44405
+ throw new Error(`Unknown widget name: ${name}`);
44406
+ }
44407
+ return widgetEnum;
44408
+ }
44409
+ function getWidgetTypeFromWidgetId(widgetId) {
44410
+ const [widgetType, widgetNumber] = widgetId.split(" ");
44411
+ if (!widgetNumber) {
44412
+ throw new Error(`Incorrect format for widget ID: ${widgetId}`);
44413
+ }
44414
+ if (!widgetNameToEnum[widgetType]) {
44415
+ throw new Error(`Unknown widget type (${widgetType}) in widget ID: ${widgetId}`);
44416
+ }
44417
+ return widgetType;
44418
+ }
44419
+
44312
44420
  const EditorJsonify = {
44313
44421
  serialize: function () {
44314
44422
  // Omit props that get passed to all widgets
@@ -44364,10 +44472,12 @@ exports.buildEmptyItemTreeForShape = buildEmptyItemTreeForShape;
44364
44472
  exports.buildMapper = buildMapper;
44365
44473
  exports.components = components;
44366
44474
  exports.constants = constants;
44475
+ exports.convertWidgetNameToEnum = convertWidgetNameToEnum;
44367
44476
  exports.displaySigFigs = displaySigFigs;
44368
44477
  exports.generateTestPerseusItem = generateTestPerseusItem;
44369
44478
  exports.genericPerseusItemData = genericPerseusItemData;
44370
44479
  exports.getAnswersFromWidgets = getAnswersFromWidgets;
44480
+ exports.getWidgetTypeFromWidgetId = getWidgetTypeFromWidgetId;
44371
44481
  exports.globalConstants = globalConstants;
44372
44482
  exports.globalStyles = globalStyles;
44373
44483
  exports.icons = iconPaths;