@khanacademy/perseus-editor 5.2.3 → 5.2.5
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/components/device-framer.d.ts +6 -10
- package/dist/components/viewport-resizer.d.ts +8 -11
- package/dist/components/widget-editor.d.ts +1 -1
- package/dist/es/index.js +85 -97
- package/dist/es/index.js.map +1 -1
- package/dist/index.js +88 -93
- package/dist/index.js.map +1 -1
- package/dist/item-editor.d.ts +2 -2
- package/dist/widgets/interactive-graph-editor.d.ts +9 -5
- package/package.json +3 -7
|
@@ -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
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
|
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.
|
|
31
|
+
const libVersion = "5.2.5";
|
|
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
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
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
|
-
|
|
105
|
-
|
|
106
|
-
|
|
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
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
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:
|
|
233
|
+
backgroundColor: color.gold,
|
|
240
234
|
margin: 2,
|
|
241
235
|
paddingRight: 10,
|
|
242
236
|
paddingLeft: 10,
|
|
@@ -21163,6 +21157,9 @@ class Editor extends React.Component {
|
|
|
21163
21157
|
// eg. If there is an "image 2" already present in the editor and we're
|
|
21164
21158
|
// about to paste in two new images, return
|
|
21165
21159
|
// { "image 1": "image 3", "image 2": "image 4" }
|
|
21160
|
+
//
|
|
21161
|
+
// TODO switch to UUIDs rather than these fragile IDs
|
|
21162
|
+
// see: LEMS-1845
|
|
21166
21163
|
|
|
21167
21164
|
// List of widgets about to be pasted as [[name, number], ...]
|
|
21168
21165
|
const widgets = _.keys(widgetData).map(name => name.split(" "));
|
|
@@ -21421,7 +21418,8 @@ class Editor extends React.Component {
|
|
|
21421
21418
|
}
|
|
21422
21419
|
return /*#__PURE__*/React.createElement(WidgetEditor, _extends({
|
|
21423
21420
|
ref: id,
|
|
21424
|
-
id: id
|
|
21421
|
+
id: id,
|
|
21422
|
+
key: id
|
|
21425
21423
|
// eslint-disable-next-line react/jsx-no-bind
|
|
21426
21424
|
,
|
|
21427
21425
|
onChange: this._handleWidgetEditorChange.bind(this, id)
|
|
@@ -22086,44 +22084,29 @@ const {
|
|
|
22086
22084
|
iconMobilePhone,
|
|
22087
22085
|
iconTablet
|
|
22088
22086
|
} = icons;
|
|
22089
|
-
|
|
22090
|
-
|
|
22091
|
-
|
|
22092
|
-
|
|
22093
|
-
|
|
22094
|
-
|
|
22095
|
-
|
|
22096
|
-
|
|
22097
|
-
|
|
22098
|
-
|
|
22099
|
-
|
|
22100
|
-
|
|
22101
|
-
|
|
22102
|
-
|
|
22103
|
-
|
|
22104
|
-
|
|
22105
|
-
|
|
22106
|
-
|
|
22107
|
-
|
|
22108
|
-
|
|
22109
|
-
|
|
22110
|
-
|
|
22111
|
-
|
|
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
|
|
22087
|
+
const ViewportResizer = props => {
|
|
22088
|
+
const phoneButtonContents = /*#__PURE__*/React.createElement("span", null, /*#__PURE__*/React.createElement(InlineIcon$8, iconMobilePhone), " Phone");
|
|
22089
|
+
const tabletButtonContents = /*#__PURE__*/React.createElement("span", null, /*#__PURE__*/React.createElement(InlineIcon$8, iconTablet), " Tablet");
|
|
22090
|
+
const desktopButtonContents = /*#__PURE__*/React.createElement("span", null, /*#__PURE__*/React.createElement(InlineIcon$8, iconDesktop), " Desktop");
|
|
22091
|
+
|
|
22092
|
+
// TODO(david): Allow input of custom viewport sizes.
|
|
22093
|
+
return /*#__PURE__*/React.createElement("span", {
|
|
22094
|
+
className: "viewport-resizer"
|
|
22095
|
+
}, "Viewport:", " ", /*#__PURE__*/React.createElement(ButtonGroup$5, {
|
|
22096
|
+
value: props.deviceType,
|
|
22097
|
+
allowEmpty: false,
|
|
22098
|
+
buttons: [{
|
|
22099
|
+
value: devices.PHONE,
|
|
22100
|
+
content: phoneButtonContents
|
|
22101
|
+
}, {
|
|
22102
|
+
value: devices.TABLET,
|
|
22103
|
+
content: tabletButtonContents
|
|
22104
|
+
}, {
|
|
22105
|
+
value: devices.DESKTOP,
|
|
22106
|
+
content: desktopButtonContents
|
|
22107
|
+
}],
|
|
22108
|
+
onChange: props.onViewportSizeChanged
|
|
22109
|
+
}));
|
|
22127
22110
|
};
|
|
22128
22111
|
|
|
22129
22112
|
/*
|
|
@@ -26816,6 +26799,7 @@ class ExpressionEditor extends React.Component {
|
|
|
26816
26799
|
widgetId: this.props.widgetId + "-" + ans.key
|
|
26817
26800
|
};
|
|
26818
26801
|
return lens(ans).merge([], {
|
|
26802
|
+
key,
|
|
26819
26803
|
draggable: true,
|
|
26820
26804
|
onChange: props => {
|
|
26821
26805
|
var _ans$key;
|
|
@@ -27299,10 +27283,11 @@ const GraphSettings = createReactClass({
|
|
|
27299
27283
|
}
|
|
27300
27284
|
},
|
|
27301
27285
|
renderLabelChoices: function (choices) {
|
|
27302
|
-
return _.map(choices, function (
|
|
27286
|
+
return _.map(choices, function ([name, value]) {
|
|
27303
27287
|
return /*#__PURE__*/React.createElement("option", {
|
|
27304
|
-
|
|
27305
|
-
|
|
27288
|
+
key: value,
|
|
27289
|
+
value: value
|
|
27290
|
+
}, name);
|
|
27306
27291
|
});
|
|
27307
27292
|
},
|
|
27308
27293
|
validRange: function (range) {
|
|
@@ -27662,6 +27647,7 @@ const GraphSettings = createReactClass({
|
|
|
27662
27647
|
value: this.props.rulerTicks
|
|
27663
27648
|
}, _.map([1, 2, 4, 8, 10, 16], function (n) {
|
|
27664
27649
|
return /*#__PURE__*/React.createElement("option", {
|
|
27650
|
+
key: n,
|
|
27665
27651
|
value: n
|
|
27666
27652
|
}, n);
|
|
27667
27653
|
})))))));
|
|
@@ -28442,9 +28428,9 @@ const styles$k = StyleSheet.create({
|
|
|
28442
28428
|
display: "inline-block",
|
|
28443
28429
|
borderStyle: "solid",
|
|
28444
28430
|
borderWidth: 1,
|
|
28445
|
-
borderColor:
|
|
28431
|
+
borderColor: color.offBlack50,
|
|
28446
28432
|
borderRadius: 3,
|
|
28447
|
-
background:
|
|
28433
|
+
background: color.white
|
|
28448
28434
|
}
|
|
28449
28435
|
});
|
|
28450
28436
|
|
|
@@ -29504,6 +29490,7 @@ const GraphPointsCountSelector = ({
|
|
|
29504
29490
|
value: `${n}`,
|
|
29505
29491
|
label: `${n} point${n > 1 ? "s" : ""}`
|
|
29506
29492
|
})), /*#__PURE__*/React.createElement(OptionItem, {
|
|
29493
|
+
key: "unlimited",
|
|
29507
29494
|
value: UNLIMITED,
|
|
29508
29495
|
label: "unlimited"
|
|
29509
29496
|
})]);
|
|
@@ -30657,6 +30644,7 @@ class InteractiveGraphEditor extends React.Component {
|
|
|
30657
30644
|
},
|
|
30658
30645
|
style: styles$a.singleSelectShort
|
|
30659
30646
|
}, [...POLYGON_SIDES, /*#__PURE__*/React.createElement(OptionItem, {
|
|
30647
|
+
key: "unlimited",
|
|
30660
30648
|
value: "unlimited",
|
|
30661
30649
|
label: "unlimited sides"
|
|
30662
30650
|
})])), /*#__PURE__*/React.createElement(LabeledRow, {
|
|
@@ -30784,7 +30772,7 @@ class InteractiveGraphEditor extends React.Component {
|
|
|
30784
30772
|
style: {
|
|
30785
30773
|
fontSize: 12,
|
|
30786
30774
|
backgroundColor: "#eee",
|
|
30787
|
-
paddingInline:
|
|
30775
|
+
paddingInline: spacing.xxSmall_6,
|
|
30788
30776
|
borderColor: "#ccc",
|
|
30789
30777
|
borderStyle: "solid",
|
|
30790
30778
|
borderWidth: 1
|
|
@@ -30840,7 +30828,7 @@ const styles$a = StyleSheet.create({
|
|
|
30840
30828
|
},
|
|
30841
30829
|
row: {
|
|
30842
30830
|
flexDirection: "row",
|
|
30843
|
-
marginTop:
|
|
30831
|
+
marginTop: spacing.xSmall_8,
|
|
30844
30832
|
alignItems: "center"
|
|
30845
30833
|
}
|
|
30846
30834
|
});
|
|
@@ -30885,7 +30873,7 @@ class FormWrappedTextField extends React.Component {
|
|
|
30885
30873
|
backgroundColor,
|
|
30886
30874
|
focusBorderColor,
|
|
30887
30875
|
borderColor,
|
|
30888
|
-
color,
|
|
30876
|
+
color: color$1,
|
|
30889
30877
|
onSubmit,
|
|
30890
30878
|
leftSideIcon,
|
|
30891
30879
|
id,
|
|
@@ -30915,10 +30903,10 @@ class FormWrappedTextField extends React.Component {
|
|
|
30915
30903
|
}
|
|
30916
30904
|
|
|
30917
30905
|
// Add text color if specified.
|
|
30918
|
-
if (color) {
|
|
30919
|
-
extraStyles.color = color;
|
|
30906
|
+
if (color$1) {
|
|
30907
|
+
extraStyles.color = color$1;
|
|
30920
30908
|
}
|
|
30921
|
-
const borderColorStyle = focused ? focusBorderColor ||
|
|
30909
|
+
const borderColorStyle = focused ? focusBorderColor || color.blue : borderColor || color.offBlack16;
|
|
30922
30910
|
extraStyles.border = `1px solid ${borderColorStyle}`;
|
|
30923
30911
|
const wrappedIcon = icon && /*#__PURE__*/React.createElement("span", {
|
|
30924
30912
|
className: css(styles$9.icon)
|