@khanacademy/perseus 32.0.1 → 33.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/index.d.ts CHANGED
@@ -30,10 +30,6 @@ export { default as MatrixWidget } from "./widgets/matrix";
30
30
  export { default as TableWidget } from "./widgets/table";
31
31
  export { default as PlotterWidget } from "./widgets/plotter";
32
32
  export { default as GrapherWidget } from "./widgets/grapher";
33
- export { default as ArrowPicker } from "./widgets/interaction/arrow-picker";
34
- export { default as ColorPicker } from "./widgets/interaction/color-picker";
35
- export { default as DashPicker } from "./widgets/interaction/dash-picker";
36
- export { default as ElementContainer } from "./widgets/interaction/element-container";
37
33
  export * as GrapherUtil from "./widgets/grapher/util";
38
34
  /**
39
35
  * Misc
package/dist/index.js CHANGED
@@ -10147,11 +10147,35 @@ const setLabelMargins = function (span, size) {
10147
10147
  marginTop: -height / 2 - y * scale
10148
10148
  });
10149
10149
  } else {
10150
+ const $container = $span.closest(".svg-image");
10151
+ // Ensuring that the line-height of the text doesn't throw off placement of the text element.
10152
+ // Inherited line-height values can really mess up placement.
10153
+ $container.css("line-height", "normal");
10154
+
10155
+ // The 'max-width' value is the same as the expected (100% scale) width of the graphie.
10156
+ // We are using jQuery to get this information since we don't have a way to pass it to this function.
10157
+ const expectedWidth = $container.css("max-width") ?? "0px";
10158
+ // We can calculate the true scale of the graphie by taking actual width and dividing by the expected width.
10159
+ // NOTE: Using 'slice' to remove the "px" unit from the end of the expected width value.
10160
+ const scale = ($container.width() ?? 0) / parseInt(expectedWidth.replace(/px$/, "")) * 100;
10161
+
10162
+ // Any padding needs to be scaled accordingly.
10163
+ const currentPadding = $span.css("padding") ?? "0px";
10164
+ const newPadding = Math.round(parseInt(currentPadding.slice(0, -2)) * scale) / 100;
10165
+
10166
+ // "multipliers" basically move the position of the text by using 1, 0, -1
10167
+ // 'margin-left' and 'margin-top' are used to position the text.
10168
+ // Margin and font size need to be scaled accordingly.
10150
10169
  const multipliers = labelDirections[direction || "center"];
10151
- $span.css({
10152
- marginLeft: Math.round(width * multipliers[0]),
10153
- marginTop: Math.round(height * multipliers[1])
10154
- });
10170
+ const styling = {
10171
+ marginLeft: Math.round(width * multipliers[0] * scale) / 100,
10172
+ marginTop: Math.round(height * multipliers[1] * scale) / 100,
10173
+ padding: `${newPadding}px`
10174
+ };
10175
+ if (scale !== 1) {
10176
+ styling["fontSize"] = `${Math.round(scale * 100) / 100}%`;
10177
+ }
10178
+ $span.css(styling);
10155
10179
  }
10156
10180
  };
10157
10181
  const GraphUtils = {
@@ -17536,9 +17560,16 @@ class SvgImage extends React__namespace.Component {
17536
17560
  // without coordinates. They don't seem to have any content, so
17537
17561
  // it seems fine to just ignore them (rather than error), but
17538
17562
  // we should figure out why this is happening.
17539
- const label = graphie.label(labelData.coordinates, labelData.content, labelData.alignment, labelData.typesetAsMath, {
17563
+
17564
+ // 'styling' - When a default scale (1) is used,
17565
+ // setting the font size to 100% is redundant.
17566
+ // Also, setting the font size to 100% can counteract other scale-based styling.
17567
+ // Therefore, when the scale is not applicable,
17568
+ // we set the value to 'null' so that no additional styling will be set.
17569
+ const styling = this.props.scale !== 1 ? {
17540
17570
  "font-size": 100 * this.props.scale + "%"
17541
- });
17571
+ } : null;
17572
+ const label = graphie.label(labelData.coordinates, labelData.content, labelData.alignment, labelData.typesetAsMath, styling);
17542
17573
 
17543
17574
  // Convert absolute positioning css from pixels to percentages
17544
17575
  // TODO(alex): Dynamically resize font-size as well. This
@@ -32330,10 +32361,14 @@ const MafsGraph = props => {
32330
32361
  state,
32331
32362
  dispatch,
32332
32363
  labels,
32333
- readOnly
32364
+ readOnly,
32365
+ fullGraphAriaLabel,
32366
+ fullGraphAriaDescription
32334
32367
  } = props;
32335
32368
  const [width, height] = props.box;
32336
32369
  const tickStep = props.step;
32370
+ const uniqueId = React__namespace.useId();
32371
+ const descriptionId = `interactive-graph-description-${uniqueId}`;
32337
32372
  const graphRef = React__namespace.useRef(null);
32338
32373
  return /*#__PURE__*/React__namespace.createElement(GraphConfigContext.Provider, {
32339
32374
  value: {
@@ -32368,9 +32403,19 @@ const MafsGraph = props => {
32368
32403
  graphRef.current?.focus();
32369
32404
  }
32370
32405
  },
32406
+ "aria-label": fullGraphAriaLabel,
32407
+ "aria-describedby": fullGraphAriaDescription ? descriptionId : undefined,
32371
32408
  ref: graphRef,
32372
32409
  tabIndex: 0
32373
- }, /*#__PURE__*/React__namespace.createElement(LegacyGrid, {
32410
+ }, fullGraphAriaDescription && /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, {
32411
+ id: descriptionId,
32412
+ tabIndex: -1,
32413
+ style: {
32414
+ width: 0,
32415
+ height: 0,
32416
+ overflow: "hidden"
32417
+ }
32418
+ }, fullGraphAriaDescription), /*#__PURE__*/React__namespace.createElement(LegacyGrid, {
32374
32419
  box: props.box,
32375
32420
  backgroundImage: props.backgroundImage
32376
32421
  }), props.showLabelsFlag && props.lockedFigures && /*#__PURE__*/React__namespace.createElement(GraphLockedLabelsLayer, {
@@ -45054,7 +45099,7 @@ const init = function (options) {
45054
45099
 
45055
45100
  // This file is processed by a Rollup plugin (replace) to inject the production
45056
45101
  const libName = "@khanacademy/perseus";
45057
- const libVersion = "32.0.1";
45102
+ const libVersion = "33.0.0";
45058
45103
  perseusCore.addLibraryVersionToPerseusDebug(libName, libVersion);
45059
45104
 
45060
45105
  const apiVersion = {
@@ -45948,128 +45993,6 @@ const ref = /*#__PURE__*/React__namespace.forwardRef((props, ref) => /*#__PURE__
45948
45993
  }));
45949
45994
  }));
45950
45995
 
45951
- class ArrowPicker extends React__namespace.Component {
45952
- static defaultProps = {
45953
- value: ""
45954
- };
45955
- render() {
45956
- return /*#__PURE__*/React__namespace.createElement(ButtonGroup, {
45957
- value: this.props.value,
45958
- allowEmpty: false,
45959
- buttons: [{
45960
- value: "",
45961
- content: /*#__PURE__*/React__namespace.createElement("span", null, "\u2014")
45962
- }, {
45963
- value: "->",
45964
- content: /*#__PURE__*/React__namespace.createElement("span", null, "\u2192")
45965
- }
45966
- /*
45967
- TODO(eater): fix khan-exercises so these are supported
45968
- {value: "<-", content: <span>&#x2190;</span>},
45969
- {value: "<->", content: <span>&#x2194;</span>}
45970
- */],
45971
-
45972
- onChange: this.props.onChange
45973
- });
45974
- }
45975
- }
45976
-
45977
- const COLORS = [KhanColors.BLACK, KhanColors.BLUE, KhanColors.GREEN, KhanColors.PINK, KhanColors.PURPLE, KhanColors.RED, KhanColors.GRAY];
45978
- const LIGHT_COLORS = [KhanColors.LIGHT_BLUE, KhanColors.LIGHT_ORANGE, KhanColors.LIGHT_PINK, KhanColors.LIGHT_GREEN, KhanColors.LIGHT_PURPLE, KhanColors.LIGHT_RED, "#fff"];
45979
- class ColorPicker extends React__namespace.Component {
45980
- static defaultProps = {
45981
- value: KhanColors.BLACK,
45982
- lightColors: false
45983
- };
45984
- render() {
45985
- const colors = this.props.lightColors ? LIGHT_COLORS : COLORS;
45986
- return /*#__PURE__*/React__namespace.createElement(ButtonGroup, {
45987
- value: this.props.value,
45988
- allowEmpty: false,
45989
- buttons: ___default["default"].map(colors, color => {
45990
- return {
45991
- value: color,
45992
- content: /*#__PURE__*/React__namespace.createElement("span", null, /*#__PURE__*/React__namespace.createElement("span", {
45993
- className: "colorpicker-circle",
45994
- style: {
45995
- background: color
45996
- }
45997
- }), "\xA0")
45998
- };
45999
- }),
46000
- onChange: this.props.onChange
46001
- });
46002
- }
46003
- }
46004
-
46005
- class DashPicker extends React__namespace.Component {
46006
- static defaultProps = {
46007
- value: ""
46008
- };
46009
- render() {
46010
- return /*#__PURE__*/React__namespace.createElement(ButtonGroup, {
46011
- value: this.props.value,
46012
- allowEmpty: false,
46013
- buttons: [{
46014
- value: "",
46015
- content: /*#__PURE__*/React__namespace.createElement("span", null, "\u2014")
46016
- }, {
46017
- value: "-",
46018
- content: /*#__PURE__*/React__namespace.createElement("span", null, "\u2013\u2013\u2013")
46019
- }, {
46020
- value: "- ",
46021
- content: /*#__PURE__*/React__namespace.createElement("span", null, "\u2013\xA0\xA0\u2013")
46022
- }, {
46023
- value: ".",
46024
- content: /*#__PURE__*/React__namespace.createElement("span", null, "\xB7\xB7\xB7\xB7")
46025
- }, {
46026
- value: ". ",
46027
- content: /*#__PURE__*/React__namespace.createElement("span", null, "\xB7 \xB7 \xB7")
46028
- }],
46029
- onChange: this.props.onChange
46030
- });
46031
- }
46032
- }
46033
-
46034
- /* eslint-disable jsx-a11y/anchor-is-valid */
46035
- class ElementContainer extends React__namespace.Component {
46036
- static defaultProps = {
46037
- initiallyVisible: false,
46038
- title: "More"
46039
- };
46040
- constructor(props) {
46041
- super(props);
46042
- this.state = {
46043
- show: props.initiallyVisible
46044
- };
46045
- }
46046
- toggle = e => {
46047
- e.preventDefault();
46048
- this.setState({
46049
- show: !this.state.show
46050
- });
46051
- };
46052
- render() {
46053
- return /*#__PURE__*/React__namespace.createElement("div", {
46054
- className: "perseus-interaction-element"
46055
- }, /*#__PURE__*/React__namespace.createElement("a", {
46056
- href: "#",
46057
- className: "perseus-interaction-element-title " + (this.state.show ? "open" : "closed"),
46058
- onClick: this.toggle
46059
- }, this.state.show ? /*#__PURE__*/React__namespace.createElement(InlineIcon, iconChevronDown) : /*#__PURE__*/React__namespace.createElement(InlineIcon, iconChevronRight), this.props.title), /*#__PURE__*/React__namespace.createElement("div", {
46060
- className: "perseus-interaction-element-content " + (this.state.show ? "enter" : "leave")
46061
- }, this.props.children, (this.props.onUp != null || this.props.onDown != null || this.props.onDelete != null) && /*#__PURE__*/React__namespace.createElement("div", {
46062
- className: "edit-controls"
46063
- }, this.props.onUp != null && /*#__PURE__*/React__namespace.createElement("button", {
46064
- onClick: this.props.onUp
46065
- }, /*#__PURE__*/React__namespace.createElement(InlineIcon, iconCircleArrowUp)), this.props.onDown != null && /*#__PURE__*/React__namespace.createElement("button", {
46066
- onClick: this.props.onDown
46067
- }, /*#__PURE__*/React__namespace.createElement(InlineIcon, iconCircleArrowDown)), this.props.onDelete != null && /*#__PURE__*/React__namespace.createElement("button", {
46068
- onClick: this.props.onDelete
46069
- }, /*#__PURE__*/React__namespace.createElement(InlineIcon, iconTrash)))));
46070
- }
46071
- }
46072
-
46073
45996
  const devices = {
46074
45997
  PHONE: "phone",
46075
45998
  TABLET: "tablet",
@@ -48655,17 +48578,13 @@ const EditorJsonify = {
48655
48578
  };
48656
48579
 
48657
48580
  exports.ApiOptions = ApiOptions;
48658
- exports.ArrowPicker = ArrowPicker;
48659
48581
  exports.ArticleRenderer = ArticleRenderer;
48660
48582
  exports.BaseRadio = BaseRadio;
48661
48583
  exports.Categorizer = Categorizer$1;
48662
48584
  exports.Changeable = changeable;
48663
48585
  exports.ClassNames = ClassNames;
48664
- exports.ColorPicker = ColorPicker;
48665
- exports.DashPicker = DashPicker;
48666
48586
  exports.Dependencies = dependencies;
48667
48587
  exports.EditorJsonify = EditorJsonify;
48668
- exports.ElementContainer = ElementContainer;
48669
48588
  exports.Expression = Expression;
48670
48589
  exports.GrapherUtil = util;
48671
48590
  exports.GrapherWidget = Grapher$1;