@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/es/index.js CHANGED
@@ -10035,11 +10035,36 @@ const setLabelMargins = function setLabelMargins(span, size) {
10035
10035
  marginTop: -height / 2 - y * scale
10036
10036
  });
10037
10037
  } else {
10038
+ var _$container$css, _$container$width, _$span$css;
10039
+ const $container = $span.closest(".svg-image");
10040
+ // Ensuring that the line-height of the text doesn't throw off placement of the text element.
10041
+ // Inherited line-height values can really mess up placement.
10042
+ $container.css("line-height", "normal");
10043
+
10044
+ // The 'max-width' value is the same as the expected (100% scale) width of the graphie.
10045
+ // We are using jQuery to get this information since we don't have a way to pass it to this function.
10046
+ const expectedWidth = (_$container$css = $container.css("max-width")) != null ? _$container$css : "0px";
10047
+ // We can calculate the true scale of the graphie by taking actual width and dividing by the expected width.
10048
+ // NOTE: Using 'slice' to remove the "px" unit from the end of the expected width value.
10049
+ const scale = ((_$container$width = $container.width()) != null ? _$container$width : 0) / parseInt(expectedWidth.replace(/px$/, "")) * 100;
10050
+
10051
+ // Any padding needs to be scaled accordingly.
10052
+ const currentPadding = (_$span$css = $span.css("padding")) != null ? _$span$css : "0px";
10053
+ const newPadding = Math.round(parseInt(currentPadding.slice(0, -2)) * scale) / 100;
10054
+
10055
+ // "multipliers" basically move the position of the text by using 1, 0, -1
10056
+ // 'margin-left' and 'margin-top' are used to position the text.
10057
+ // Margin and font size need to be scaled accordingly.
10038
10058
  const multipliers = labelDirections[direction || "center"];
10039
- $span.css({
10040
- marginLeft: Math.round(width * multipliers[0]),
10041
- marginTop: Math.round(height * multipliers[1])
10042
- });
10059
+ const styling = {
10060
+ marginLeft: Math.round(width * multipliers[0] * scale) / 100,
10061
+ marginTop: Math.round(height * multipliers[1] * scale) / 100,
10062
+ padding: `${newPadding}px`
10063
+ };
10064
+ if (scale !== 1) {
10065
+ styling["fontSize"] = `${Math.round(scale * 100) / 100}%`;
10066
+ }
10067
+ $span.css(styling);
10043
10068
  }
10044
10069
  };
10045
10070
  const GraphUtils = {
@@ -17231,9 +17256,16 @@ class SvgImage extends React.Component {
17231
17256
  // without coordinates. They don't seem to have any content, so
17232
17257
  // it seems fine to just ignore them (rather than error), but
17233
17258
  // we should figure out why this is happening.
17234
- const label = graphie.label(labelData.coordinates, labelData.content, labelData.alignment, labelData.typesetAsMath, {
17259
+
17260
+ // 'styling' - When a default scale (1) is used,
17261
+ // setting the font size to 100% is redundant.
17262
+ // Also, setting the font size to 100% can counteract other scale-based styling.
17263
+ // Therefore, when the scale is not applicable,
17264
+ // we set the value to 'null' so that no additional styling will be set.
17265
+ const styling = this.props.scale !== 1 ? {
17235
17266
  "font-size": 100 * this.props.scale + "%"
17236
- });
17267
+ } : null;
17268
+ const label = graphie.label(labelData.coordinates, labelData.content, labelData.alignment, labelData.typesetAsMath, styling);
17237
17269
 
17238
17270
  // Convert absolute positioning css from pixels to percentages
17239
17271
  // TODO(alex): Dynamically resize font-size as well. This
@@ -31994,10 +32026,14 @@ const MafsGraph = props => {
31994
32026
  state,
31995
32027
  dispatch,
31996
32028
  labels,
31997
- readOnly
32029
+ readOnly,
32030
+ fullGraphAriaLabel,
32031
+ fullGraphAriaDescription
31998
32032
  } = props;
31999
32033
  const [width, height] = props.box;
32000
32034
  const tickStep = props.step;
32035
+ const uniqueId = React.useId();
32036
+ const descriptionId = `interactive-graph-description-${uniqueId}`;
32001
32037
  const graphRef = React.useRef(null);
32002
32038
  return /*#__PURE__*/React.createElement(GraphConfigContext.Provider, {
32003
32039
  value: {
@@ -32033,9 +32069,19 @@ const MafsGraph = props => {
32033
32069
  (_graphRef$current = graphRef.current) == null || _graphRef$current.focus();
32034
32070
  }
32035
32071
  },
32072
+ "aria-label": fullGraphAriaLabel,
32073
+ "aria-describedby": fullGraphAriaDescription ? descriptionId : undefined,
32036
32074
  ref: graphRef,
32037
32075
  tabIndex: 0
32038
- }, /*#__PURE__*/React.createElement(LegacyGrid, {
32076
+ }, fullGraphAriaDescription && /*#__PURE__*/React.createElement(View, {
32077
+ id: descriptionId,
32078
+ tabIndex: -1,
32079
+ style: {
32080
+ width: 0,
32081
+ height: 0,
32082
+ overflow: "hidden"
32083
+ }
32084
+ }, fullGraphAriaDescription), /*#__PURE__*/React.createElement(LegacyGrid, {
32039
32085
  box: props.box,
32040
32086
  backgroundImage: props.backgroundImage
32041
32087
  }), props.showLabelsFlag && props.lockedFigures && /*#__PURE__*/React.createElement(GraphLockedLabelsLayer, {
@@ -44695,7 +44741,7 @@ const init = function init(options) {
44695
44741
 
44696
44742
  // This file is processed by a Rollup plugin (replace) to inject the production
44697
44743
  const libName = "@khanacademy/perseus";
44698
- const libVersion = "32.0.1";
44744
+ const libVersion = "33.0.0";
44699
44745
  addLibraryVersionToPerseusDebug(libName, libVersion);
44700
44746
 
44701
44747
  const apiVersion = {
@@ -45579,128 +45625,6 @@ const ref = /*#__PURE__*/React.forwardRef((props, ref) => /*#__PURE__*/React.cre
45579
45625
  ref: ref
45580
45626
  }))));
45581
45627
 
45582
- class ArrowPicker extends React.Component {
45583
- render() {
45584
- return /*#__PURE__*/React.createElement(ButtonGroup, {
45585
- value: this.props.value,
45586
- allowEmpty: false,
45587
- buttons: [{
45588
- value: "",
45589
- content: /*#__PURE__*/React.createElement("span", null, "\u2014")
45590
- }, {
45591
- value: "->",
45592
- content: /*#__PURE__*/React.createElement("span", null, "\u2192")
45593
- }
45594
- /*
45595
- TODO(eater): fix khan-exercises so these are supported
45596
- {value: "<-", content: <span>&#x2190;</span>},
45597
- {value: "<->", content: <span>&#x2194;</span>}
45598
- */],
45599
-
45600
- onChange: this.props.onChange
45601
- });
45602
- }
45603
- }
45604
- ArrowPicker.defaultProps = {
45605
- value: ""
45606
- };
45607
-
45608
- const COLORS = [KhanColors.BLACK, KhanColors.BLUE, KhanColors.GREEN, KhanColors.PINK, KhanColors.PURPLE, KhanColors.RED, KhanColors.GRAY];
45609
- const LIGHT_COLORS = [KhanColors.LIGHT_BLUE, KhanColors.LIGHT_ORANGE, KhanColors.LIGHT_PINK, KhanColors.LIGHT_GREEN, KhanColors.LIGHT_PURPLE, KhanColors.LIGHT_RED, "#fff"];
45610
- class ColorPicker extends React.Component {
45611
- render() {
45612
- const colors = this.props.lightColors ? LIGHT_COLORS : COLORS;
45613
- return /*#__PURE__*/React.createElement(ButtonGroup, {
45614
- value: this.props.value,
45615
- allowEmpty: false,
45616
- buttons: _.map(colors, color => {
45617
- return {
45618
- value: color,
45619
- content: /*#__PURE__*/React.createElement("span", null, /*#__PURE__*/React.createElement("span", {
45620
- className: "colorpicker-circle",
45621
- style: {
45622
- background: color
45623
- }
45624
- }), "\xA0")
45625
- };
45626
- }),
45627
- onChange: this.props.onChange
45628
- });
45629
- }
45630
- }
45631
- ColorPicker.defaultProps = {
45632
- value: KhanColors.BLACK,
45633
- lightColors: false
45634
- };
45635
-
45636
- class DashPicker extends React.Component {
45637
- render() {
45638
- return /*#__PURE__*/React.createElement(ButtonGroup, {
45639
- value: this.props.value,
45640
- allowEmpty: false,
45641
- buttons: [{
45642
- value: "",
45643
- content: /*#__PURE__*/React.createElement("span", null, "\u2014")
45644
- }, {
45645
- value: "-",
45646
- content: /*#__PURE__*/React.createElement("span", null, "\u2013\u2013\u2013")
45647
- }, {
45648
- value: "- ",
45649
- content: /*#__PURE__*/React.createElement("span", null, "\u2013\xA0\xA0\u2013")
45650
- }, {
45651
- value: ".",
45652
- content: /*#__PURE__*/React.createElement("span", null, "\xB7\xB7\xB7\xB7")
45653
- }, {
45654
- value: ". ",
45655
- content: /*#__PURE__*/React.createElement("span", null, "\xB7 \xB7 \xB7")
45656
- }],
45657
- onChange: this.props.onChange
45658
- });
45659
- }
45660
- }
45661
- DashPicker.defaultProps = {
45662
- value: ""
45663
- };
45664
-
45665
- /* eslint-disable jsx-a11y/anchor-is-valid */
45666
- class ElementContainer extends React.Component {
45667
- constructor(props) {
45668
- super(props);
45669
- this.toggle = e => {
45670
- e.preventDefault();
45671
- this.setState({
45672
- show: !this.state.show
45673
- });
45674
- };
45675
- this.state = {
45676
- show: props.initiallyVisible
45677
- };
45678
- }
45679
- render() {
45680
- return /*#__PURE__*/React.createElement("div", {
45681
- className: "perseus-interaction-element"
45682
- }, /*#__PURE__*/React.createElement("a", {
45683
- href: "#",
45684
- className: "perseus-interaction-element-title " + (this.state.show ? "open" : "closed"),
45685
- onClick: this.toggle
45686
- }, this.state.show ? /*#__PURE__*/React.createElement(InlineIcon, iconChevronDown) : /*#__PURE__*/React.createElement(InlineIcon, iconChevronRight), this.props.title), /*#__PURE__*/React.createElement("div", {
45687
- className: "perseus-interaction-element-content " + (this.state.show ? "enter" : "leave")
45688
- }, this.props.children, (this.props.onUp != null || this.props.onDown != null || this.props.onDelete != null) && /*#__PURE__*/React.createElement("div", {
45689
- className: "edit-controls"
45690
- }, this.props.onUp != null && /*#__PURE__*/React.createElement("button", {
45691
- onClick: this.props.onUp
45692
- }, /*#__PURE__*/React.createElement(InlineIcon, iconCircleArrowUp)), this.props.onDown != null && /*#__PURE__*/React.createElement("button", {
45693
- onClick: this.props.onDown
45694
- }, /*#__PURE__*/React.createElement(InlineIcon, iconCircleArrowDown)), this.props.onDelete != null && /*#__PURE__*/React.createElement("button", {
45695
- onClick: this.props.onDelete
45696
- }, /*#__PURE__*/React.createElement(InlineIcon, iconTrash)))));
45697
- }
45698
- }
45699
- ElementContainer.defaultProps = {
45700
- initiallyVisible: false,
45701
- title: "More"
45702
- };
45703
-
45704
45628
  const devices = {
45705
45629
  PHONE: "phone",
45706
45630
  TABLET: "tablet",
@@ -48280,5 +48204,5 @@ const EditorJsonify = {
48280
48204
  }
48281
48205
  };
48282
48206
 
48283
- export { ApiOptions, ArrowPicker, ArticleRenderer, BaseRadio, Categorizer$1 as Categorizer, changeable as Changeable, ClassNames, ColorPicker, DashPicker, dependencies as Dependencies, EditorJsonify, ElementContainer, Expression, util as GrapherUtil, Grapher$1 as GrapherWidget, HintRenderer, HintsRenderer, InputNumber$1 as InputNumber, InteractiveGraph$1 as InteractiveGraphWidget, ItemExtras, JiptParagraphs, KhanColors, KhanMath, context as LoadingContext, Log, Matrix$1 as MatrixWidget, MultiItems, NumericInput$1 as NumericInput, PerseusExpressionAnswerFormConsidered, PerseusI18nContext, PerseusI18nContextProvider, PerseusMarkdown, Plotter$1 as PlotterWidget, QUESTION_WIDGETS, Radio, Renderer, ref as ServerItemRenderer, sizingUtils as SizingUtils, Table$1 as TableWidget, Util, denylist as WIDGET_PROP_DENYLIST, WidgetJsonifyDeprecated, widgets$1 as Widgets, addWidget, apiVersion, buildEmptyItemTreeForShape, buildMapper, components, constants, contentHasWidgetType, convertWidgetNameToEnum, displaySigFigs, generateTestCategorizerWidget, generateTestExpressionWidget, generateTestInteractiveGraphWidget, generateTestNumericInputWidget, generateTestPerseusItem, generateTestRadioWidget, genericPerseusItemData, getAngleCoords, getAnswerFromUserInput, getAnswersFromWidgets, getCircleCoords, getCorrectAnswerForWidgetId, getLineCoords, getLinearSystemCoords, getPointCoords, getPolygonCoords, getQuadraticCoords, getSegmentCoords, getSinusoidCoords, getValidWidgetIds, getWidgetFromWidgetMap, getWidgetIdsFromContent, getWidgetIdsFromContentByType, getWidgetTypeByWidgetId, getWidgetsFromWidgetMap, getWidgetsMapFromItemData, globalConstants, globalStyles, iconPaths as icons, init, injectWidgets, interactiveSizes$1 as interactiveSizes, isItemRenderableByVersion, isWidgetIdInContent, isWrongAnswerSupported, itemDataVersion, itemToTree, ItemVersion as itemVersion, libVersion, lockedFigureColors, lockedFigureFillStyles, makeSafeUrl, mediaQueries, parsePerseusItem, plotterPlotTypes, preprocessTex, registerAllWidgetsForTesting, shapes, shouldHaveIndividualAnswer, traverse, usePerseusI18n, violatingWidgets, allWidgets as widgets };
48207
+ export { ApiOptions, ArticleRenderer, BaseRadio, Categorizer$1 as Categorizer, changeable as Changeable, ClassNames, dependencies as Dependencies, EditorJsonify, Expression, util as GrapherUtil, Grapher$1 as GrapherWidget, HintRenderer, HintsRenderer, InputNumber$1 as InputNumber, InteractiveGraph$1 as InteractiveGraphWidget, ItemExtras, JiptParagraphs, KhanColors, KhanMath, context as LoadingContext, Log, Matrix$1 as MatrixWidget, MultiItems, NumericInput$1 as NumericInput, PerseusExpressionAnswerFormConsidered, PerseusI18nContext, PerseusI18nContextProvider, PerseusMarkdown, Plotter$1 as PlotterWidget, QUESTION_WIDGETS, Radio, Renderer, ref as ServerItemRenderer, sizingUtils as SizingUtils, Table$1 as TableWidget, Util, denylist as WIDGET_PROP_DENYLIST, WidgetJsonifyDeprecated, widgets$1 as Widgets, addWidget, apiVersion, buildEmptyItemTreeForShape, buildMapper, components, constants, contentHasWidgetType, convertWidgetNameToEnum, displaySigFigs, generateTestCategorizerWidget, generateTestExpressionWidget, generateTestInteractiveGraphWidget, generateTestNumericInputWidget, generateTestPerseusItem, generateTestRadioWidget, genericPerseusItemData, getAngleCoords, getAnswerFromUserInput, getAnswersFromWidgets, getCircleCoords, getCorrectAnswerForWidgetId, getLineCoords, getLinearSystemCoords, getPointCoords, getPolygonCoords, getQuadraticCoords, getSegmentCoords, getSinusoidCoords, getValidWidgetIds, getWidgetFromWidgetMap, getWidgetIdsFromContent, getWidgetIdsFromContentByType, getWidgetTypeByWidgetId, getWidgetsFromWidgetMap, getWidgetsMapFromItemData, globalConstants, globalStyles, iconPaths as icons, init, injectWidgets, interactiveSizes$1 as interactiveSizes, isItemRenderableByVersion, isWidgetIdInContent, isWrongAnswerSupported, itemDataVersion, itemToTree, ItemVersion as itemVersion, libVersion, lockedFigureColors, lockedFigureFillStyles, makeSafeUrl, mediaQueries, parsePerseusItem, plotterPlotTypes, preprocessTex, registerAllWidgetsForTesting, shapes, shouldHaveIndividualAnswer, traverse, usePerseusI18n, violatingWidgets, allWidgets as widgets };
48284
48208
  //# sourceMappingURL=index.js.map