@khanacademy/perseus 7.2.0 → 7.2.1

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.
Files changed (68) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/dist/es/index.css +61 -61
  3. package/dist/es/index.js +50 -119
  4. package/dist/es/index.js.map +1 -1
  5. package/dist/index.css +61 -61
  6. package/dist/index.js +39 -77
  7. package/dist/index.js.map +1 -1
  8. package/dist/widgets/plotter.d.ts +47 -13
  9. package/dist/widgets/plotter.js.flow +47 -13
  10. package/package.json +2 -2
  11. package/src/__tests__/item-renderer.test.tsx +1 -1
  12. package/src/components/__stories__/image-loader.stories.tsx +1 -0
  13. package/src/components/graph.tsx +1 -0
  14. package/src/components/icon.tsx +1 -0
  15. package/src/components/image-loader.tsx +1 -0
  16. package/src/components/number-input.tsx +1 -0
  17. package/src/components/sortable.tsx +1 -0
  18. package/src/components/svg-image.tsx +1 -0
  19. package/src/components/tex-buttons.tsx +1 -0
  20. package/src/components/text-input.tsx +1 -0
  21. package/src/components/text-list-editor.tsx +1 -0
  22. package/src/components/zoomable.tsx +1 -0
  23. package/src/hints-renderer.tsx +1 -0
  24. package/src/index.ts +1 -0
  25. package/src/item-renderer.tsx +1 -0
  26. package/src/mixins/provide-keypad.tsx +1 -0
  27. package/src/multi-items/multi-renderer.tsx +1 -0
  28. package/src/renderer.tsx +1 -0
  29. package/src/server-item-renderer.tsx +1 -0
  30. package/src/styles/articles.less +8 -4
  31. package/src/styles/perseus-renderer.less +47 -38
  32. package/src/styles/util.less +1 -1
  33. package/src/styles/variables.boostrap.less +158 -182
  34. package/src/styles/variables.less +20 -20
  35. package/src/styles/variables.shared.less +162 -168
  36. package/src/styles/widgets/categorizer.less +1 -2
  37. package/src/styles/widgets/expression.less +7 -4
  38. package/src/styles/widgets/grapher.less +2 -1
  39. package/src/styles/widgets/image.less +3 -2
  40. package/src/styles/widgets/interactive-graph.less +4 -2
  41. package/src/styles/widgets/label-image.less +2 -1
  42. package/src/styles/widgets/matrix.less +11 -7
  43. package/src/styles/widgets/orderer.less +2 -1
  44. package/src/styles/widgets/passage.less +2 -1
  45. package/src/styles/widgets/plotter.less +4 -3
  46. package/src/styles/widgets/radio.less +4 -2
  47. package/src/styles/widgets/sortable.less +1 -1
  48. package/src/styles/widgets/table.less +2 -1
  49. package/src/styles/widgets/transformer.less +2 -1
  50. package/src/styles/widgets/unit.less +2 -1
  51. package/src/widgets/__stories__/plotter.stories.tsx +27 -0
  52. package/src/widgets/__testdata__/plotter.testdata.ts +36 -0
  53. package/src/widgets/__tests__/__snapshots__/plotter.test.tsx.snap +863 -0
  54. package/src/widgets/__tests__/plotter.test.tsx +65 -0
  55. package/src/widgets/categorizer.tsx +1 -0
  56. package/src/widgets/graded-group-set.tsx +1 -0
  57. package/src/widgets/graded-group.tsx +1 -0
  58. package/src/widgets/interaction.tsx +1 -0
  59. package/src/widgets/label-image/marker.tsx +1 -0
  60. package/src/widgets/matcher.tsx +1 -0
  61. package/src/widgets/orderer.tsx +1 -0
  62. package/src/widgets/passage-ref-target.tsx +1 -0
  63. package/src/widgets/plotter.tsx +108 -98
  64. package/src/widgets/radio/base-radio.tsx +1 -0
  65. package/src/widgets/radio/choice-icon/choice-icon.tsx +1 -0
  66. package/src/widgets/sorter.tsx +1 -0
  67. package/src/widgets/transformer.tsx +1 -0
  68. package/tsconfig-build.tsbuildinfo +1 -1
package/dist/es/index.js CHANGED
@@ -120,6 +120,7 @@ var dependencies = /*#__PURE__*/Object.freeze({
120
120
  getDependencies: getDependencies
121
121
  });
122
122
 
123
+ /* eslint-disable @khanacademy/ts-no-error-suppressions */
123
124
  const prettyBig = {
124
125
  fontSize: "150%"
125
126
  };
@@ -1176,7 +1177,7 @@ var changeable = /*#__PURE__*/Object.freeze({
1176
1177
  propTypes: propTypes
1177
1178
  });
1178
1179
 
1179
- /* eslint-disable @babel/no-invalid-this, react/forbid-prop-types, react/no-unsafe, react/sort-comp */
1180
+ /* eslint-disable @khanacademy/ts-no-error-suppressions */
1180
1181
  const textWidthCache = {};
1181
1182
  function getTextWidth(text) {
1182
1183
  if (!textWidthCache[text]) {
@@ -20691,7 +20692,7 @@ MathOutput.defaultProps = {
20691
20692
  onBlur: function () {}
20692
20693
  };
20693
20694
 
20694
- /* eslint-disable react/sort-comp */
20695
+ /* eslint-disable @khanacademy/ts-no-error-suppressions */
20695
20696
  let lastId = 0;
20696
20697
  function uniqueIdForInput(prefix = "input-") {
20697
20698
  lastId++;
@@ -22141,36 +22142,7 @@ const scrollElementIntoView = (element, callback) => {
22141
22142
  }, 0);
22142
22143
  };
22143
22144
 
22144
- /**
22145
- * SVG Icon React Component
22146
- *
22147
- * This component is designed to take in SVG paths and render icons based upon
22148
- * them. If you are looking for an icon that we've used before you should look
22149
- * in `icon-paths.js` which is a reference file for all the SVG paths that
22150
- * we've used. You'll need to copy the object from that file into whichever
22151
- * file you're using the icon and explicitly pass it in to the <Icon/> React
22152
- * component.
22153
- *
22154
- * Sample usage:
22155
- *
22156
- * const dropdownIcon = `M5,6L0,0L10,0`;
22157
- * <Icon icon={dropdownIcon} />
22158
- *
22159
- * Or:
22160
- *
22161
- * const dropdownIcon = {
22162
- * path: `M5,6L0,0L10,0`,
22163
- * height: 10,
22164
- * width: 10,
22165
- * };
22166
- * <Icon icon={dropdownIcon} size={20} />
22167
- *
22168
- * A full list of all the existing icons can be seen here:
22169
- * http://localhost:8080/react-sandbox/shared-styles-package/icon.jsx.fixture.js
22170
- *
22171
- * If you want to add an entirely new icon please read the note inside
22172
- * the `icon-paths.js` file.
22173
- */
22145
+ /* eslint-disable @khanacademy/ts-no-error-suppressions */
22174
22146
  // WARNING: This determines the *viewport* width and height, so a change here
22175
22147
  // requires scaling the values of every SVG path passed in as a string
22176
22148
  // without corresponding `width` and `height` values.
@@ -23770,7 +23742,7 @@ const WidgetJsonifyDeprecated = {
23770
23742
  }
23771
23743
  };
23772
23744
 
23773
- /* eslint-disable react/sort-comp */
23745
+ /* eslint-disable @khanacademy/ts-no-error-suppressions */
23774
23746
  class Categorizer extends React.Component {
23775
23747
  constructor(..._args) {
23776
23748
  super(..._args);
@@ -26783,7 +26755,7 @@ var Image$1 = {
26783
26755
  isLintable: true
26784
26756
  };
26785
26757
 
26786
- /* eslint-disable @babel/no-invalid-this, react/no-unsafe, react/sort-comp */
26758
+ /* eslint-disable @khanacademy/ts-no-error-suppressions */
26787
26759
  // @ts-expect-error [FEI-5003] - TS2339 - Property 'Label' does not exist on type 'typeof Graphie'.
26788
26760
  const Label$1 = Graphie.Label;
26789
26761
  // @ts-expect-error [FEI-5003] - TS2339 - Property 'Line' does not exist on type 'typeof Graphie'.
@@ -27385,7 +27357,7 @@ var Interactive = {
27385
27357
  hidden: true
27386
27358
  };
27387
27359
 
27388
- /* eslint-disable react/no-unsafe */
27360
+ /* eslint-disable @khanacademy/ts-no-error-suppressions */
27389
27361
  const defaultBackgroundImage$2 = {
27390
27362
  url: null
27391
27363
  };
@@ -30921,11 +30893,7 @@ const styles$h = StyleSheet.create({
30921
30893
  }
30922
30894
  });
30923
30895
 
30924
- /**
30925
- * Controlled question image marker, rendered as a styled button element.
30926
- *
30927
- * The target for labeling question image with answers.
30928
- */
30896
+ /* eslint-disable @khanacademy/ts-no-error-suppressions */
30929
30897
  class Marker extends React.Component {
30930
30898
  constructor(...args) {
30931
30899
  super(...args);
@@ -32791,7 +32759,7 @@ const styles$e = StyleSheet.create({
32791
32759
  }
32792
32760
  });
32793
32761
 
32794
- /* eslint-disable react/forbid-prop-types, react/sort-comp */
32762
+ /* eslint-disable @khanacademy/ts-no-error-suppressions */
32795
32763
  const {
32796
32764
  shuffle: shuffle$1,
32797
32765
  seededRNG
@@ -38103,30 +38071,15 @@ var PassageRefTarget$1 = {
38103
38071
  isLintable: true
38104
38072
  };
38105
38073
 
38106
- /* eslint-disable @babel/no-invalid-this, @typescript-eslint/no-unused-vars, one-var, react/no-unsafe, react/sort-comp */
38074
+ /* eslint-disable react/no-unsafe */
38107
38075
  const {
38108
38076
  deepEq: deepEq$1
38109
38077
  } = Util;
38110
- const BAR = "bar",
38111
- LINE = "line",
38112
- PIC = "pic",
38113
- HISTOGRAM = "histogram",
38114
- DOTPLOT = "dotplot";
38115
- ({
38116
- type: PropTypes.oneOf([BAR, LINE, PIC, HISTOGRAM, DOTPLOT]),
38117
- labels: PropTypes.arrayOf(PropTypes.string),
38118
- categories: PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.number, PropTypes.string])),
38119
- scaleY: PropTypes.number,
38120
- maxY: PropTypes.number,
38121
- snapsPerLine: PropTypes.number,
38122
- picSize: PropTypes.number,
38123
- pixBoxHeight: PropTypes.number,
38124
- picUrl: PropTypes.string,
38125
- plotDimensions: PropTypes.arrayOf(PropTypes.number),
38126
- labelInterval: PropTypes.number,
38127
- starting: PropTypes.arrayOf(PropTypes.number),
38128
- static: PropTypes.bool
38129
- });
38078
+ const BAR = "bar";
38079
+ const LINE = "line";
38080
+ const PIC = "pic";
38081
+ const HISTOGRAM = "histogram";
38082
+ const DOTPLOT = "dotplot";
38130
38083
  class Plotter extends React.Component {
38131
38084
  constructor(..._args) {
38132
38085
  super(..._args);
@@ -38165,11 +38118,11 @@ class Plotter extends React.Component {
38165
38118
  self.graphie = graphie;
38166
38119
  self.graphie.pics = [];
38167
38120
  self.graphie.dotTicks = [];
38168
- const isBar = self.props.type === BAR,
38169
- isLine = self.props.type === LINE,
38170
- isPic = self.props.type === PIC,
38171
- isHistogram = self.props.type === HISTOGRAM,
38172
- isDotplot = self.props.type === DOTPLOT;
38121
+ const isBar = self.props.type === BAR;
38122
+ const isLine = self.props.type === LINE;
38123
+ const isPic = self.props.type === PIC;
38124
+ const isHistogram = self.props.type === HISTOGRAM;
38125
+ const isDotplot = self.props.type === DOTPLOT;
38173
38126
  const isTiledPlot = isPic || isDotplot;
38174
38127
  const config = {};
38175
38128
  const c = config; // c for short
@@ -38230,9 +38183,7 @@ class Plotter extends React.Component {
38230
38183
 
38231
38184
  // TODO(michaelpolyak): Handle other plot types: Dot, Histogram, Line.
38232
38185
  if (isMobile && (isBar || isTiledPlot)) {
38233
- const maxCategoryHeight = Math.max(0,
38234
- // @ts-expect-error [FEI-5003] - TS2345 - Argument of type 'unknown' is not assignable to parameter of type 'number'.
38235
- ...Object.values(self.state.categoryHeights));
38186
+ const maxCategoryHeight = Math.max(0, ...Object.values(self.state.categoryHeights));
38236
38187
  if (maxCategoryHeight) {
38237
38188
  // Account for bottom label position, height.
38238
38189
  let offsetY = 25;
@@ -38285,7 +38236,7 @@ class Plotter extends React.Component {
38285
38236
  });
38286
38237
  }
38287
38238
  }
38288
- if ((isBar || isLine) && isMobile) {
38239
+ if ((isBar || isLine) && isMobile && !this.props.static) {
38289
38240
  self.graphie.dragPrompt = graphie.label([c.dimX / 2, c.dimY / 2], i18n._("Drag handles to make graph"), "center", false).css("font-weight", "bold").css("color", KhanColors.KA_GREEN).css("display", "none");
38290
38241
  }
38291
38242
  self.setupCategories(config);
@@ -38534,8 +38485,8 @@ class Plotter extends React.Component {
38534
38485
  config.graph.bars[i].scale(1, Math.max(isMobile ? 0.2 : 0.01, height / config.scaleY), center[0], center[1]);
38535
38486
  if (isHistogram) {
38536
38487
  // Scale dividers between buckets
38537
- const leftDivider = config.graph.dividers[i - 1],
38538
- rightDivider = config.graph.dividers[i];
38488
+ const leftDivider = config.graph.dividers[i - 1];
38489
+ const rightDivider = config.graph.dividers[i];
38539
38490
  if (leftDivider) {
38540
38491
  const divHeight = Math.min(self.state.values[i - 1], height);
38541
38492
  leftDivider.scale(1, Math.max(0.01, divHeight / config.scaleY), center[0], center[1]);
@@ -38860,38 +38811,13 @@ class Plotter extends React.Component {
38860
38811
  return Plotter.validate(this.getUserInput(), rubric);
38861
38812
  };
38862
38813
  }
38863
- render() {
38864
- // TODO(kevinb) actually compute the size of the graphie correctly and
38865
- // make it that size so we don't have to add extra padding. The value
38866
- // was determined by eye-balling the layout. :(
38867
- const paddingForBottomLabel = 75;
38868
- const style = {
38869
- marginBottom: this.props.labels[0] ? paddingForBottomLabel : 0
38870
- };
38871
- return /*#__PURE__*/React.createElement("div", {
38872
- className: "perseus-widget-plotter graphie " + ClassNames.INTERACTIVE
38873
- // eslint-disable-next-line react/no-string-refs
38874
- ,
38875
- ref: "graphieDiv",
38876
- style: style
38877
- });
38878
- }
38879
- componentDidUpdate(prevProps, prevState) {
38880
- this.shouldSetupGraphie = this.shouldSetupGraphie || !_.isEqual(this.state.categoryHeights, prevState.categoryHeights);
38881
- if (this.shouldSetupGraphie) {
38882
- this.setupGraphie(prevState);
38883
- }
38884
- }
38885
38814
  componentDidMount() {
38886
38815
  this._isMounted = true;
38887
38816
  this.setupGraphie(this.state);
38888
38817
  }
38889
38818
  UNSAFE_componentWillReceiveProps(nextProps) {
38890
38819
  const props = ["type", "labels", "categories", "scaleY", "maxY", "snapsPerLine", "picUrl", "labelInterval", "static"];
38891
- this.shouldSetupGraphie = _.any(props, function (prop) {
38892
- // @ts-expect-error [FEI-5003] - TS2683 - 'this' implicitly has type 'any' because it does not have a type annotation.
38893
- return !_.isEqual(this.props[prop], nextProps[prop]);
38894
- }, this);
38820
+ this.shouldSetupGraphie = _.any(props, prop => !_.isEqual(this.props[prop], nextProps[prop]), this);
38895
38821
  if (!_.isEqual(this.props.starting, nextProps.starting) && !_.isEqual(this.state.values, nextProps.starting)) {
38896
38822
  this.shouldSetupGraphie = true;
38897
38823
  this.setState({
@@ -38899,16 +38825,32 @@ class Plotter extends React.Component {
38899
38825
  });
38900
38826
  }
38901
38827
  }
38828
+ componentDidUpdate(prevProps, prevState) {
38829
+ this.shouldSetupGraphie = this.shouldSetupGraphie || !_.isEqual(this.state.categoryHeights, prevState.categoryHeights);
38830
+ if (this.shouldSetupGraphie) {
38831
+ this.setupGraphie(prevState);
38832
+ }
38833
+ }
38902
38834
  componentWillUnmount() {
38903
38835
  this._isMounted = false;
38904
38836
  }
38837
+ render() {
38838
+ // TODO(kevinb) actually compute the size of the graphie correctly and
38839
+ // make it that size so we don't have to add extra padding. The value
38840
+ // was determined by eye-balling the layout. :(
38841
+ const paddingForBottomLabel = 75;
38842
+ const style = {
38843
+ marginBottom: this.props.labels[0] ? paddingForBottomLabel : 0
38844
+ };
38845
+ return /*#__PURE__*/React.createElement("div", {
38846
+ className: "perseus-widget-plotter graphie " + ClassNames.INTERACTIVE
38847
+ // eslint-disable-next-line react/no-string-refs
38848
+ ,
38849
+ ref: "graphieDiv",
38850
+ style: style
38851
+ });
38852
+ }
38905
38853
  }
38906
- Plotter.propTypes = {
38907
- onChange: PropTypes.func.isRequired,
38908
- trackInteraction: PropTypes.func.isRequired
38909
- // TODO(alex): Figure out why lint chokes on this line
38910
- // ...widgetPropTypes,
38911
- };
38912
38854
  Plotter.defaultProps = {
38913
38855
  type: BAR,
38914
38856
  labels: ["", ""],
@@ -39879,6 +39821,7 @@ var Simulator$1 = {
39879
39821
  hidden: true
39880
39822
  };
39881
39823
 
39824
+ /* eslint-disable @khanacademy/ts-no-error-suppressions */
39882
39825
  const {
39883
39826
  shuffle
39884
39827
  } = Util;
@@ -43914,17 +43857,7 @@ registerWidgets(allWidgets);
43914
43857
  const ItemVersion = getVersionVector();
43915
43858
  ItemVersion["::renderer::"] = version.itemDataVersion;
43916
43859
 
43917
- /**
43918
- * A mixin that renders a custom software keypad in additional to the base
43919
- * component. The base component will receive blur events when the keypad is
43920
- * dismissed and can access the keypad element itself so as to manage its
43921
- * activation and dismissal.
43922
- *
43923
- * TODO(charlie): This would make a nicer higher-order component, except that
43924
- * we need to expose methods on the base component (i.e., `ItemRenderer`). When
43925
- * `ItemRenderer` and friends are written as ES6 Classes, we can have them
43926
- * extend a `ProvideKeypad` component instead of using this mixin.
43927
- */
43860
+ /* eslint-disable @khanacademy/ts-no-error-suppressions */
43928
43861
  // NOTE: This is not a real component. It's a collection of methods used to
43929
43862
  // create and manage a Keypad instances.
43930
43863
  // TODO(LP-10789): replace this with a React Context object to pass information
@@ -46874,9 +46807,7 @@ const EditorJsonify = {
46874
46807
  }
46875
46808
  };
46876
46809
 
46877
- /**
46878
- * Main entry point
46879
- */
46810
+ /* eslint-disable @khanacademy/ts-no-error-suppressions */
46880
46811
  const apiVersion = version.apiVersion;
46881
46812
  const itemDataVersion = version.itemDataVersion;
46882
46813