@khanacademy/perseus-editor 5.2.3 → 5.2.4

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.
@@ -1,15 +1,11 @@
1
1
  /**
2
2
  * A component that displays its contents inside a device frame.
3
3
  */
4
- import PropTypes from "prop-types";
5
4
  import * as React from "react";
6
- type Props = any;
7
- declare class DeviceFramer extends React.Component<Props> {
8
- static propTypes: {
9
- children: PropTypes.Validator<PropTypes.ReactElementLike>;
10
- deviceType: PropTypes.Validator<NonNullable<"phone" | "tablet" | "desktop">>;
11
- nochrome: PropTypes.Requireable<boolean>;
12
- };
13
- render(): React.ReactNode;
14
- }
5
+ import type { DeviceType } from "@khanacademy/perseus";
6
+ type Props = React.PropsWithChildren<{
7
+ deviceType?: DeviceType;
8
+ nochrome: boolean;
9
+ }>;
10
+ declare const DeviceFramer: ({ children, deviceType, nochrome, }: Props) => React.ReactElement;
15
11
  export default DeviceFramer;
@@ -1,16 +1,13 @@
1
- import PropTypes from "prop-types";
2
- import * as React from "react";
1
+ /// <reference types="react" />
3
2
  import type { DeviceType } from "@khanacademy/perseus";
4
3
  type Props = {
4
+ /** The current device type that is selected. */
5
5
  deviceType: DeviceType;
6
- onViewportSizeChanged: (arg1: DeviceType) => unknown;
6
+ /**
7
+ * A callback that is passed (width, height) as the dimensions of the
8
+ * viewport to resize to.
9
+ */
10
+ onViewportSizeChanged: (deviceType: DeviceType) => unknown;
7
11
  };
8
- declare class ViewportResizer extends React.Component<Props> {
9
- static propTypes: {
10
- deviceType: PropTypes.Validator<string>;
11
- onViewportSizeChanged: PropTypes.Validator<(...args: any[]) => any>;
12
- };
13
- handleChange: (value: DeviceType) => void;
14
- render(): React.ReactNode;
15
- }
12
+ declare const ViewportResizer: (props: Props) => JSX.Element;
16
13
  export default ViewportResizer;
@@ -6,7 +6,7 @@ type WidgetEditorProps = {
6
6
  onChange: (widgetInfo: PerseusWidget, cb?: () => unknown, silent?: boolean) => unknown;
7
7
  onRemove: () => unknown;
8
8
  apiOptions: any;
9
- } & PerseusWidget;
9
+ } & Omit<PerseusWidget, "key">;
10
10
  type WidgetEditorState = {
11
11
  showWidget: boolean;
12
12
  widgetInfo: PerseusWidget;
package/dist/es/index.js CHANGED
@@ -3,12 +3,12 @@ import { constants, components, Widgets, icons, WIDGET_PROP_DENYLIST, Util, Log,
3
3
  import * as React from 'react';
4
4
  import { useRef, useEffect } from 'react';
5
5
  import _ from 'underscore';
6
- import PropTypes from 'prop-types';
7
6
  import createReactClass from 'create-react-class';
8
7
  import Clickable from '@khanacademy/wonder-blocks-clickable';
9
- import Color from '@khanacademy/wonder-blocks-color';
8
+ import { color, spacing } from '@khanacademy/wonder-blocks-tokens';
10
9
  import { StyleSheet, css } from 'aphrodite';
11
10
  import $ from 'jquery';
11
+ import PropTypes from 'prop-types';
12
12
  import { View, useUniqueIdWithMock } from '@khanacademy/wonder-blocks-core';
13
13
  import { PhosphorIcon } from '@khanacademy/wonder-blocks-icon';
14
14
  import caretRight from '@phosphor-icons/core/bold/caret-right-bold.svg';
@@ -20,9 +20,7 @@ import { isTruthy } from '@khanacademy/wonder-stuff-core';
20
20
  import { createMathField } from '@khanacademy/math-input';
21
21
  import { SingleSelect, OptionItem, ActionMenu, ActionItem } from '@khanacademy/wonder-blocks-dropdown';
22
22
  import { TextField, Checkbox as Checkbox$1 } from '@khanacademy/wonder-blocks-form';
23
- import Spacing from '@khanacademy/wonder-blocks-spacing';
24
23
  import { LabelSmall, LabelLarge, LabelMedium, BodyMonospace } from '@khanacademy/wonder-blocks-typography';
25
- import { spacing, color } from '@khanacademy/wonder-blocks-tokens';
26
24
  import IconButton from '@khanacademy/wonder-blocks-icon-button';
27
25
  import trashIcon from '@phosphor-icons/core/bold/trash-bold.svg';
28
26
  import Button from '@khanacademy/wonder-blocks-button';
@@ -30,7 +28,7 @@ import * as i18n$1 from '@khanacademy/wonder-blocks-i18n';
30
28
 
31
29
  // This file is processed by a Rollup plugin (replace) to inject the production
32
30
  const libName = "@khanacademy/perseus-editor";
33
- const libVersion = "5.2.3";
31
+ const libVersion = "5.2.4";
34
32
  addLibraryVersionToPerseusDebug(libName, libVersion);
35
33
 
36
34
  function _extends() {
@@ -50,9 +48,6 @@ function _extends() {
50
48
  return _extends.apply(this, arguments);
51
49
  }
52
50
 
53
- /**
54
- * A component that displays its contents inside a device frame.
55
- */
56
51
  const SCREEN_SIZES = {
57
52
  phone: {
58
53
  width: 320,
@@ -70,47 +65,46 @@ const SCREEN_SIZES = {
70
65
  framedWidth: 688
71
66
  }
72
67
  };
73
- class DeviceFramer extends React.Component {
74
- render() {
75
- const deviceType = this.props.deviceType;
76
- if (this.props.nochrome) {
77
- // Render content inside a variable height iframe. Used on the
78
- // "edit" table of the content editor. In this mode, PerseusFrame
79
- // will draw the border and reserve space on the right for
80
- // lint indicators.
81
- return /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("div", {
82
- key: "screen",
83
- style: {
84
- width: SCREEN_SIZES[deviceType].framedWidth + 2 * constants.perseusFrameBorderWidth + constants.lintGutterWidth
85
- }
86
- }, /*#__PURE__*/React.createElement("div", null, this.props.children)));
87
- }
88
- const scale = SCREEN_SIZES[deviceType].framedWidth / SCREEN_SIZES[deviceType].width;
89
-
90
- // In this mode we draw our own border and don't reserve
91
- // space for a lint gutter.
92
- const screenStyle = {
93
- backgroundColor: "white",
94
- color: "black",
95
- textAlign: "left",
96
- width: SCREEN_SIZES[deviceType].width,
97
- height: SCREEN_SIZES[deviceType].height,
98
- border: "solid 1px #CCC",
99
- margin: 8,
100
- zoom: scale
101
- };
68
+ const DeviceFramer = ({
69
+ children,
70
+ deviceType: _deviceType = "phone",
71
+ nochrome
72
+ }) => {
73
+ const scale = React.useMemo(() => SCREEN_SIZES[_deviceType].framedWidth / SCREEN_SIZES[_deviceType].width, [_deviceType]);
74
+
75
+ // In this mode we draw our own border and don't reserve
76
+ // space for a lint gutter.
77
+ const withChromeStyle = React.useMemo(() => ({
78
+ backgroundColor: "white",
79
+ overflow: "scroll",
80
+ color: "black",
81
+ textAlign: "left",
82
+ width: SCREEN_SIZES[_deviceType].width,
83
+ height: SCREEN_SIZES[_deviceType].height,
84
+ border: "solid 1px #CCC",
85
+ margin: 8,
86
+ zoom: scale
87
+ }), [_deviceType, scale]);
88
+ if (nochrome) {
89
+ // Render content inside a variable height iframe. Used on the
90
+ // "edit" table of the content editor. In this mode, PerseusFrame
91
+ // will draw the border and reserve space on the right for
92
+ // lint indicators.
102
93
  return /*#__PURE__*/React.createElement("div", {
103
94
  key: "screen",
104
- className: "screen",
105
- style: screenStyle
106
- }, this.props.children);
95
+ style: {
96
+ overflow: "scroll",
97
+ width: SCREEN_SIZES[_deviceType].framedWidth + 2 * constants.perseusFrameBorderWidth + constants.lintGutterWidth
98
+ }
99
+ }, /*#__PURE__*/React.createElement("div", null, children));
107
100
  }
108
- }
109
- DeviceFramer.propTypes = {
110
- children: PropTypes.element.isRequired,
111
- deviceType: PropTypes.oneOf([constants.devices.PHONE, constants.devices.TABLET, constants.devices.DESKTOP]).isRequired,
112
- // TODO(kevinb) rename to variableHeight
113
- nochrome: PropTypes.bool
101
+ return /*#__PURE__*/React.createElement("div", {
102
+ key: "screen",
103
+ className: "screen",
104
+ style: _extends({}, withChromeStyle, {
105
+ textAlign: "start"
106
+ })
107
+ }, children);
114
108
  };
115
109
 
116
110
  /* eslint-disable @babel/no-invalid-this */
@@ -236,7 +230,7 @@ class SectionControlButton extends React.Component {
236
230
  }
237
231
  const styles$q = StyleSheet.create({
238
232
  button: {
239
- backgroundColor: Color.gold,
233
+ backgroundColor: color.gold,
240
234
  margin: 2,
241
235
  paddingRight: 10,
242
236
  paddingLeft: 10,
@@ -21421,7 +21415,8 @@ class Editor extends React.Component {
21421
21415
  }
21422
21416
  return /*#__PURE__*/React.createElement(WidgetEditor, _extends({
21423
21417
  ref: id,
21424
- id: id
21418
+ id: id,
21419
+ key: id
21425
21420
  // eslint-disable-next-line react/jsx-no-bind
21426
21421
  ,
21427
21422
  onChange: this._handleWidgetEditorChange.bind(this, id)
@@ -22086,44 +22081,29 @@ const {
22086
22081
  iconMobilePhone,
22087
22082
  iconTablet
22088
22083
  } = icons;
22089
- class ViewportResizer extends React.Component {
22090
- constructor(...args) {
22091
- super(...args);
22092
- this.handleChange = value => {
22093
- this.props.onViewportSizeChanged(value);
22094
- };
22095
- }
22096
- render() {
22097
- const phoneButtonContents = /*#__PURE__*/React.createElement("span", null, /*#__PURE__*/React.createElement(InlineIcon$8, iconMobilePhone), " Phone");
22098
- const tabletButtonContents = /*#__PURE__*/React.createElement("span", null, /*#__PURE__*/React.createElement(InlineIcon$8, iconTablet), " Tablet");
22099
- const desktopButtonContents = /*#__PURE__*/React.createElement("span", null, /*#__PURE__*/React.createElement(InlineIcon$8, iconDesktop), " Desktop");
22100
-
22101
- // TODO(david): Allow input of custom viewport sizes.
22102
- return /*#__PURE__*/React.createElement("span", {
22103
- className: "viewport-resizer"
22104
- }, "Viewport:", " ", /*#__PURE__*/React.createElement(ButtonGroup$5, {
22105
- value: this.props.deviceType,
22106
- allowEmpty: false,
22107
- buttons: [{
22108
- value: devices.PHONE,
22109
- content: phoneButtonContents
22110
- }, {
22111
- value: devices.TABLET,
22112
- content: tabletButtonContents
22113
- }, {
22114
- value: devices.DESKTOP,
22115
- content: desktopButtonContents
22116
- }],
22117
- onChange: this.handleChange
22118
- }));
22119
- }
22120
- }
22121
- ViewportResizer.propTypes = {
22122
- // The current device type that is selected.
22123
- deviceType: PropTypes.string.isRequired,
22124
- // A callback that is passed (width, height) as the dimensions of the
22125
- // viewport to resize to.
22126
- onViewportSizeChanged: PropTypes.func.isRequired
22084
+ const ViewportResizer = props => {
22085
+ const phoneButtonContents = /*#__PURE__*/React.createElement("span", null, /*#__PURE__*/React.createElement(InlineIcon$8, iconMobilePhone), " Phone");
22086
+ const tabletButtonContents = /*#__PURE__*/React.createElement("span", null, /*#__PURE__*/React.createElement(InlineIcon$8, iconTablet), " Tablet");
22087
+ const desktopButtonContents = /*#__PURE__*/React.createElement("span", null, /*#__PURE__*/React.createElement(InlineIcon$8, iconDesktop), " Desktop");
22088
+
22089
+ // TODO(david): Allow input of custom viewport sizes.
22090
+ return /*#__PURE__*/React.createElement("span", {
22091
+ className: "viewport-resizer"
22092
+ }, "Viewport:", " ", /*#__PURE__*/React.createElement(ButtonGroup$5, {
22093
+ value: props.deviceType,
22094
+ allowEmpty: false,
22095
+ buttons: [{
22096
+ value: devices.PHONE,
22097
+ content: phoneButtonContents
22098
+ }, {
22099
+ value: devices.TABLET,
22100
+ content: tabletButtonContents
22101
+ }, {
22102
+ value: devices.DESKTOP,
22103
+ content: desktopButtonContents
22104
+ }],
22105
+ onChange: props.onViewportSizeChanged
22106
+ }));
22127
22107
  };
22128
22108
 
22129
22109
  /*
@@ -26816,6 +26796,7 @@ class ExpressionEditor extends React.Component {
26816
26796
  widgetId: this.props.widgetId + "-" + ans.key
26817
26797
  };
26818
26798
  return lens(ans).merge([], {
26799
+ key,
26819
26800
  draggable: true,
26820
26801
  onChange: props => {
26821
26802
  var _ans$key;
@@ -27299,10 +27280,11 @@ const GraphSettings = createReactClass({
27299
27280
  }
27300
27281
  },
27301
27282
  renderLabelChoices: function (choices) {
27302
- return _.map(choices, function (nameAndValue) {
27283
+ return _.map(choices, function ([name, value]) {
27303
27284
  return /*#__PURE__*/React.createElement("option", {
27304
- value: nameAndValue[1]
27305
- }, nameAndValue[0]);
27285
+ key: value,
27286
+ value: value
27287
+ }, name);
27306
27288
  });
27307
27289
  },
27308
27290
  validRange: function (range) {
@@ -27662,6 +27644,7 @@ const GraphSettings = createReactClass({
27662
27644
  value: this.props.rulerTicks
27663
27645
  }, _.map([1, 2, 4, 8, 10, 16], function (n) {
27664
27646
  return /*#__PURE__*/React.createElement("option", {
27647
+ key: n,
27665
27648
  value: n
27666
27649
  }, n);
27667
27650
  })))))));
@@ -28442,9 +28425,9 @@ const styles$k = StyleSheet.create({
28442
28425
  display: "inline-block",
28443
28426
  borderStyle: "solid",
28444
28427
  borderWidth: 1,
28445
- borderColor: Color.offBlack50,
28428
+ borderColor: color.offBlack50,
28446
28429
  borderRadius: 3,
28447
- background: Color.white
28430
+ background: color.white
28448
28431
  }
28449
28432
  });
28450
28433
 
@@ -29504,6 +29487,7 @@ const GraphPointsCountSelector = ({
29504
29487
  value: `${n}`,
29505
29488
  label: `${n} point${n > 1 ? "s" : ""}`
29506
29489
  })), /*#__PURE__*/React.createElement(OptionItem, {
29490
+ key: "unlimited",
29507
29491
  value: UNLIMITED,
29508
29492
  label: "unlimited"
29509
29493
  })]);
@@ -30657,6 +30641,7 @@ class InteractiveGraphEditor extends React.Component {
30657
30641
  },
30658
30642
  style: styles$a.singleSelectShort
30659
30643
  }, [...POLYGON_SIDES, /*#__PURE__*/React.createElement(OptionItem, {
30644
+ key: "unlimited",
30660
30645
  value: "unlimited",
30661
30646
  label: "unlimited sides"
30662
30647
  })])), /*#__PURE__*/React.createElement(LabeledRow, {
@@ -30784,7 +30769,7 @@ class InteractiveGraphEditor extends React.Component {
30784
30769
  style: {
30785
30770
  fontSize: 12,
30786
30771
  backgroundColor: "#eee",
30787
- paddingInline: Spacing.xxSmall_6,
30772
+ paddingInline: spacing.xxSmall_6,
30788
30773
  borderColor: "#ccc",
30789
30774
  borderStyle: "solid",
30790
30775
  borderWidth: 1
@@ -30840,7 +30825,7 @@ const styles$a = StyleSheet.create({
30840
30825
  },
30841
30826
  row: {
30842
30827
  flexDirection: "row",
30843
- marginTop: Spacing.xSmall_8,
30828
+ marginTop: spacing.xSmall_8,
30844
30829
  alignItems: "center"
30845
30830
  }
30846
30831
  });
@@ -30885,7 +30870,7 @@ class FormWrappedTextField extends React.Component {
30885
30870
  backgroundColor,
30886
30871
  focusBorderColor,
30887
30872
  borderColor,
30888
- color,
30873
+ color: color$1,
30889
30874
  onSubmit,
30890
30875
  leftSideIcon,
30891
30876
  id,
@@ -30915,10 +30900,10 @@ class FormWrappedTextField extends React.Component {
30915
30900
  }
30916
30901
 
30917
30902
  // Add text color if specified.
30918
- if (color) {
30919
- extraStyles.color = color;
30903
+ if (color$1) {
30904
+ extraStyles.color = color$1;
30920
30905
  }
30921
- const borderColorStyle = focused ? focusBorderColor || Color.blue : borderColor || Color.offBlack16;
30906
+ const borderColorStyle = focused ? focusBorderColor || color.blue : borderColor || color.offBlack16;
30922
30907
  extraStyles.border = `1px solid ${borderColorStyle}`;
30923
30908
  const wrappedIcon = icon && /*#__PURE__*/React.createElement("span", {
30924
30909
  className: css(styles$9.icon)