@khanacademy/perseus-editor 5.0.3 → 5.1.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.
- package/dist/components/locked-figure-select.d.ts +7 -0
- package/dist/components/locked-figure-settings.d.ts +11 -0
- package/dist/components/locked-figures-section.d.ts +9 -0
- package/dist/components/locked-point-settings.d.ts +8 -0
- package/dist/components/util.d.ts +3 -0
- package/dist/es/index.js +419 -137
- package/dist/es/index.js.map +1 -1
- package/dist/index.js +417 -132
- package/dist/index.js.map +1 -1
- package/dist/widgets/interactive-graph-editor.d.ts +466 -660
- package/package.json +4 -2
package/dist/index.js
CHANGED
|
@@ -26,6 +26,8 @@ var wonderBlocksForm = require('@khanacademy/wonder-blocks-form');
|
|
|
26
26
|
var Spacing = require('@khanacademy/wonder-blocks-spacing');
|
|
27
27
|
var wonderBlocksTypography = require('@khanacademy/wonder-blocks-typography');
|
|
28
28
|
var wonderBlocksTokens = require('@khanacademy/wonder-blocks-tokens');
|
|
29
|
+
var IconButton = require('@khanacademy/wonder-blocks-icon-button');
|
|
30
|
+
var trashIcon = require('@phosphor-icons/core/bold/trash-bold.svg');
|
|
29
31
|
var Button = require('@khanacademy/wonder-blocks-button');
|
|
30
32
|
var i18n$1 = require('@khanacademy/wonder-blocks-i18n');
|
|
31
33
|
|
|
@@ -61,12 +63,14 @@ var classNames__default = /*#__PURE__*/_interopDefaultLegacy(classNames);
|
|
|
61
63
|
var ReactDOM__default = /*#__PURE__*/_interopDefaultLegacy(ReactDOM);
|
|
62
64
|
var KAS__namespace = /*#__PURE__*/_interopNamespace(KAS);
|
|
63
65
|
var Spacing__default = /*#__PURE__*/_interopDefaultLegacy(Spacing);
|
|
66
|
+
var IconButton__default = /*#__PURE__*/_interopDefaultLegacy(IconButton);
|
|
67
|
+
var trashIcon__default = /*#__PURE__*/_interopDefaultLegacy(trashIcon);
|
|
64
68
|
var Button__default = /*#__PURE__*/_interopDefaultLegacy(Button);
|
|
65
69
|
var i18n__namespace = /*#__PURE__*/_interopNamespace(i18n$1);
|
|
66
70
|
|
|
67
71
|
// This file is processed by a Rollup plugin (replace) to inject the production
|
|
68
72
|
const libName = "@khanacademy/perseus-editor";
|
|
69
|
-
const libVersion = "5.
|
|
73
|
+
const libVersion = "5.1.1";
|
|
70
74
|
perseusCore.addLibraryVersionToPerseusDebug(libName, libVersion);
|
|
71
75
|
|
|
72
76
|
function _extends() {
|
|
@@ -260,13 +264,13 @@ class SectionControlButton extends React__namespace.Component {
|
|
|
260
264
|
role: "button",
|
|
261
265
|
hideDefaultFocusRing: true,
|
|
262
266
|
"aria-label": title,
|
|
263
|
-
style: styles$
|
|
267
|
+
style: styles$q.button
|
|
264
268
|
}, _ref => {
|
|
265
269
|
return /*#__PURE__*/React__namespace.createElement(InlineIcon$b, icon);
|
|
266
270
|
});
|
|
267
271
|
}
|
|
268
272
|
}
|
|
269
|
-
const styles$
|
|
273
|
+
const styles$q = aphrodite.StyleSheet.create({
|
|
270
274
|
button: {
|
|
271
275
|
backgroundColor: Color__default["default"].gold,
|
|
272
276
|
margin: 2,
|
|
@@ -20784,19 +20788,19 @@ class TexErrorView extends React__namespace.Component {
|
|
|
20784
20788
|
const {
|
|
20785
20789
|
showErrors
|
|
20786
20790
|
} = this.state;
|
|
20787
|
-
const iconStyle = showErrors ? styles$
|
|
20791
|
+
const iconStyle = showErrors ? styles$p.iconExpanded : styles$p.iconCollapsed;
|
|
20788
20792
|
return /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, {
|
|
20789
|
-
style: styles$
|
|
20793
|
+
style: styles$p.errorContainer
|
|
20790
20794
|
}, /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, {
|
|
20791
|
-
style: styles$
|
|
20795
|
+
style: styles$p.title,
|
|
20792
20796
|
onClick: this.handleToggleTexErrors
|
|
20793
20797
|
}, /*#__PURE__*/React__namespace.createElement(wonderBlocksIcon.PhosphorIcon, {
|
|
20794
20798
|
icon: caretRight__default["default"],
|
|
20795
20799
|
style: iconStyle
|
|
20796
20800
|
}), "\xA0 TeX Errors (", errorList.length, ")"), showErrors && /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, {
|
|
20797
|
-
style: styles$
|
|
20801
|
+
style: styles$p.errorExplanation
|
|
20798
20802
|
}, "If your math doesn't display correctly, these errors might help you troubleshoot. Message #content-kitchen for help."), showErrors && errorList.map((e, index) => /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, {
|
|
20799
|
-
style: styles$
|
|
20803
|
+
style: styles$p.error,
|
|
20800
20804
|
key: index
|
|
20801
20805
|
}, /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, {
|
|
20802
20806
|
style: {
|
|
@@ -20805,7 +20809,7 @@ class TexErrorView extends React__namespace.Component {
|
|
|
20805
20809
|
}, e.math), /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, null, e.message))));
|
|
20806
20810
|
}
|
|
20807
20811
|
}
|
|
20808
|
-
const styles$
|
|
20812
|
+
const styles$p = aphrodite.StyleSheet.create({
|
|
20809
20813
|
title: {
|
|
20810
20814
|
backgroundColor: "#eee",
|
|
20811
20815
|
fontSize: "1.25em",
|
|
@@ -24583,12 +24587,12 @@ class SimpleButton extends React__namespace.Component {
|
|
|
24583
24587
|
...otherProps
|
|
24584
24588
|
} = this.props;
|
|
24585
24589
|
return /*#__PURE__*/React__namespace.createElement("div", _extends({
|
|
24586
|
-
className: aphrodite.css(styles$
|
|
24590
|
+
className: aphrodite.css(styles$o.baseButton, color === "green" && styles$o.green, color === "orange" && styles$o.orange),
|
|
24587
24591
|
onClick: onClick
|
|
24588
24592
|
}, otherProps), children);
|
|
24589
24593
|
}
|
|
24590
24594
|
}
|
|
24591
|
-
const styles$
|
|
24595
|
+
const styles$o = aphrodite.StyleSheet.create({
|
|
24592
24596
|
baseButton: {
|
|
24593
24597
|
top: "0",
|
|
24594
24598
|
fontSize: "11px",
|
|
@@ -24801,23 +24805,23 @@ const LeafContainer = _ref2 => {
|
|
|
24801
24805
|
} = _ref2;
|
|
24802
24806
|
const hasPreviewHeading = shape.type === "content" || shape.type === "hint";
|
|
24803
24807
|
const previewHeading = hasPreviewHeading && /*#__PURE__*/React__namespace.createElement("div", {
|
|
24804
|
-
className: aphrodite.css(styles$
|
|
24808
|
+
className: aphrodite.css(styles$n.containerHeader)
|
|
24805
24809
|
}, /*#__PURE__*/React__namespace.createElement(Header, {
|
|
24806
24810
|
depth: path.length,
|
|
24807
|
-
className: aphrodite.css(styles$
|
|
24811
|
+
className: aphrodite.css(styles$n.containerTitle)
|
|
24808
24812
|
}, capitalize(name)));
|
|
24809
24813
|
return /*#__PURE__*/React__namespace.createElement("div", {
|
|
24810
|
-
className: aphrodite.css(styles$
|
|
24814
|
+
className: aphrodite.css(styles$n.container)
|
|
24811
24815
|
}, /*#__PURE__*/React__namespace.createElement("span", {
|
|
24812
|
-
className: aphrodite.css(styles$
|
|
24816
|
+
className: aphrodite.css(styles$n.row, styles$n.rowHeading)
|
|
24813
24817
|
}, /*#__PURE__*/React__namespace.createElement("div", {
|
|
24814
|
-
className: aphrodite.css(styles$
|
|
24818
|
+
className: aphrodite.css(styles$n.columnLeft)
|
|
24815
24819
|
}, /*#__PURE__*/React__namespace.createElement("div", {
|
|
24816
|
-
className: "pod-title " + aphrodite.css(styles$
|
|
24820
|
+
className: "pod-title " + aphrodite.css(styles$n.containerHeader)
|
|
24817
24821
|
}, /*#__PURE__*/React__namespace.createElement("div", {
|
|
24818
|
-
className: aphrodite.css(styles$
|
|
24822
|
+
className: aphrodite.css(styles$n.containerTitle)
|
|
24819
24823
|
}, capitalize(name)), controls)), /*#__PURE__*/React__namespace.createElement("div", {
|
|
24820
|
-
className: aphrodite.css(styles$
|
|
24824
|
+
className: aphrodite.css(styles$n.columnRight)
|
|
24821
24825
|
}, previewHeading)), children);
|
|
24822
24826
|
};
|
|
24823
24827
|
const ArrayContainer = props => {
|
|
@@ -24830,11 +24834,11 @@ const ArrayContainer = props => {
|
|
|
24830
24834
|
actions
|
|
24831
24835
|
} = props;
|
|
24832
24836
|
return /*#__PURE__*/React__namespace.createElement("div", {
|
|
24833
|
-
className: aphrodite.css(styles$
|
|
24837
|
+
className: aphrodite.css(styles$n.container)
|
|
24834
24838
|
}, controls && /*#__PURE__*/React__namespace.createElement("div", {
|
|
24835
|
-
className: aphrodite.css(styles$
|
|
24839
|
+
className: aphrodite.css(styles$n.columnLeft, styles$n.containerHeader)
|
|
24836
24840
|
}, controls), /*#__PURE__*/React__namespace.createElement("div", null, children), /*#__PURE__*/React__namespace.createElement("div", {
|
|
24837
|
-
className: aphrodite.css(styles$
|
|
24841
|
+
className: aphrodite.css(styles$n.columnLeft)
|
|
24838
24842
|
}, /*#__PURE__*/React__namespace.createElement("a", {
|
|
24839
24843
|
href: "javascript:void 0",
|
|
24840
24844
|
onClick: () => actions.addArrayElement(path, shape.elementShape)
|
|
@@ -24848,28 +24852,28 @@ const ObjectContainer = _ref3 => {
|
|
|
24848
24852
|
path
|
|
24849
24853
|
} = _ref3;
|
|
24850
24854
|
const headingEditor = /*#__PURE__*/React__namespace.createElement("div", {
|
|
24851
|
-
className: aphrodite.css(styles$
|
|
24855
|
+
className: aphrodite.css(styles$n.containerHeader)
|
|
24852
24856
|
}, /*#__PURE__*/React__namespace.createElement(Header, {
|
|
24853
24857
|
depth: path.length,
|
|
24854
|
-
className: aphrodite.css(styles$
|
|
24858
|
+
className: aphrodite.css(styles$n.containerTitle)
|
|
24855
24859
|
}, capitalize(name)), controls);
|
|
24856
24860
|
const headingPreview = (name || controls) && /*#__PURE__*/React__namespace.createElement("div", {
|
|
24857
|
-
className: aphrodite.css(styles$
|
|
24861
|
+
className: aphrodite.css(styles$n.containerHeader, styles$n.previewCollectionHeader)
|
|
24858
24862
|
}, /*#__PURE__*/React__namespace.createElement(Header, {
|
|
24859
24863
|
depth: path.length,
|
|
24860
|
-
className: aphrodite.css(styles$
|
|
24864
|
+
className: aphrodite.css(styles$n.containerTitle)
|
|
24861
24865
|
}, capitalize(name)));
|
|
24862
24866
|
const hasBothHeadings = headingEditor && headingPreview;
|
|
24863
24867
|
return /*#__PURE__*/React__namespace.createElement("div", {
|
|
24864
|
-
className: aphrodite.css(styles$
|
|
24868
|
+
className: aphrodite.css(styles$n.container)
|
|
24865
24869
|
}, hasBothHeadings && /*#__PURE__*/React__namespace.createElement("span", {
|
|
24866
|
-
className: aphrodite.css(styles$
|
|
24870
|
+
className: aphrodite.css(styles$n.row)
|
|
24867
24871
|
}, /*#__PURE__*/React__namespace.createElement("div", {
|
|
24868
|
-
className: aphrodite.css(styles$
|
|
24872
|
+
className: aphrodite.css(styles$n.columnLeft)
|
|
24869
24873
|
}, headingEditor), /*#__PURE__*/React__namespace.createElement("div", {
|
|
24870
|
-
className: aphrodite.css(styles$
|
|
24874
|
+
className: aphrodite.css(styles$n.columnRight)
|
|
24871
24875
|
}, headingPreview)), /*#__PURE__*/React__namespace.createElement("div", {
|
|
24872
|
-
className: aphrodite.css(path.length > 0 && styles$
|
|
24876
|
+
className: aphrodite.css(path.length > 0 && styles$n.contentIndent)
|
|
24873
24877
|
}, children));
|
|
24874
24878
|
};
|
|
24875
24879
|
|
|
@@ -24989,11 +24993,11 @@ const ItemNodeContent = withStickiness(props => {
|
|
|
24989
24993
|
className: "framework-perseus"
|
|
24990
24994
|
}, lens(renderers).get(path));
|
|
24991
24995
|
return /*#__PURE__*/React__namespace.createElement("span", null, /*#__PURE__*/React__namespace.createElement("div", {
|
|
24992
|
-
className: aphrodite.css(styles$
|
|
24996
|
+
className: aphrodite.css(styles$n.row)
|
|
24993
24997
|
}, /*#__PURE__*/React__namespace.createElement("div", {
|
|
24994
|
-
className: aphrodite.css(styles$
|
|
24998
|
+
className: aphrodite.css(styles$n.columnLeft)
|
|
24995
24999
|
}, /*#__PURE__*/React__namespace.createElement("div", {
|
|
24996
|
-
className: aphrodite.css(sticky && styles$
|
|
25000
|
+
className: aphrodite.css(sticky && styles$n.sticky)
|
|
24997
25001
|
},
|
|
24998
25002
|
/*#__PURE__*/
|
|
24999
25003
|
// @ts-expect-error - TS2769 - No overload matches this call.
|
|
@@ -25001,9 +25005,9 @@ const ItemNodeContent = withStickiness(props => {
|
|
|
25001
25005
|
onChange: newVal => actions.mergeValueAtPath(path, newVal),
|
|
25002
25006
|
apiOptions: apiOptions
|
|
25003
25007
|
})))), /*#__PURE__*/React__namespace.createElement("div", {
|
|
25004
|
-
className: aphrodite.css(styles$
|
|
25008
|
+
className: aphrodite.css(styles$n.columnRight)
|
|
25005
25009
|
}, /*#__PURE__*/React__namespace.createElement("div", {
|
|
25006
|
-
className: aphrodite.css(sticky && styles$
|
|
25010
|
+
className: aphrodite.css(sticky && styles$n.sticky)
|
|
25007
25011
|
}, preview))));
|
|
25008
25012
|
});
|
|
25009
25013
|
const HintNodeContent = withStickiness(props => {
|
|
@@ -25019,13 +25023,13 @@ const HintNodeContent = withStickiness(props => {
|
|
|
25019
25023
|
className: "framework-perseus"
|
|
25020
25024
|
}, lens(renderers).get(path));
|
|
25021
25025
|
return /*#__PURE__*/React__namespace.createElement("div", {
|
|
25022
|
-
className: aphrodite.css(styles$
|
|
25026
|
+
className: aphrodite.css(styles$n.row)
|
|
25023
25027
|
}, /*#__PURE__*/React__namespace.createElement("div", {
|
|
25024
|
-
className: aphrodite.css(styles$
|
|
25028
|
+
className: aphrodite.css(styles$n.columnLeft)
|
|
25025
25029
|
}, /*#__PURE__*/React__namespace.createElement("div", {
|
|
25026
|
-
className: aphrodite.css(sticky && styles$
|
|
25030
|
+
className: aphrodite.css(sticky && styles$n.sticky)
|
|
25027
25031
|
}, /*#__PURE__*/React__namespace.createElement(HintEditor, _extends({}, data, {
|
|
25028
|
-
className: aphrodite.css(styles$
|
|
25032
|
+
className: aphrodite.css(styles$n.hintEditor),
|
|
25029
25033
|
onChange: newVal => actions.mergeValueAtPath(path, newVal),
|
|
25030
25034
|
apiOptions: apiOptions,
|
|
25031
25035
|
showTitle: false,
|
|
@@ -25040,9 +25044,9 @@ const HintNodeContent = withStickiness(props => {
|
|
|
25040
25044
|
isFirst: true,
|
|
25041
25045
|
isLast: true
|
|
25042
25046
|
})))), /*#__PURE__*/React__namespace.createElement("div", {
|
|
25043
|
-
className: aphrodite.css(styles$
|
|
25047
|
+
className: aphrodite.css(styles$n.columnRight)
|
|
25044
25048
|
}, /*#__PURE__*/React__namespace.createElement("div", {
|
|
25045
|
-
className: aphrodite.css(sticky && styles$
|
|
25049
|
+
className: aphrodite.css(sticky && styles$n.sticky)
|
|
25046
25050
|
}, preview)));
|
|
25047
25051
|
});
|
|
25048
25052
|
const TagsNodeContent = props => {
|
|
@@ -25059,9 +25063,9 @@ const TagsNodeContent = props => {
|
|
|
25059
25063
|
return null;
|
|
25060
25064
|
}
|
|
25061
25065
|
return /*#__PURE__*/React__namespace.createElement("div", {
|
|
25062
|
-
className: aphrodite.css(styles$
|
|
25066
|
+
className: aphrodite.css(styles$n.columnLeft)
|
|
25063
25067
|
}, /*#__PURE__*/React__namespace.createElement("div", {
|
|
25064
|
-
className: aphrodite.css(styles$
|
|
25068
|
+
className: aphrodite.css(styles$n.tagsEditor)
|
|
25065
25069
|
}, /*#__PURE__*/React__namespace.createElement(GroupMetadataEditor, {
|
|
25066
25070
|
value: data,
|
|
25067
25071
|
onChange: newVal => actions.setValueAtPath(path, newVal),
|
|
@@ -25092,23 +25096,23 @@ const ArrayNodeContent = props => {
|
|
|
25092
25096
|
const subpath = path.concat(i);
|
|
25093
25097
|
const controls = [i > 0 && /*#__PURE__*/React__namespace.createElement("div", {
|
|
25094
25098
|
key: "moveArrayElementUp",
|
|
25095
|
-
className: aphrodite.css(styles$
|
|
25099
|
+
className: aphrodite.css(styles$n.control)
|
|
25096
25100
|
}, /*#__PURE__*/React__namespace.createElement(SimpleButton, {
|
|
25097
25101
|
color: "orange",
|
|
25098
25102
|
title: "Move up",
|
|
25099
25103
|
onClick: () => actions.moveArrayElementUp(subpath)
|
|
25100
25104
|
}, /*#__PURE__*/React__namespace.createElement("div", {
|
|
25101
|
-
className: aphrodite.css(styles$
|
|
25105
|
+
className: aphrodite.css(styles$n.verticalFlip)
|
|
25102
25106
|
}, /*#__PURE__*/React__namespace.createElement(InlineIcon$6, iconChevronDown)))), i < data.length - 1 && /*#__PURE__*/React__namespace.createElement("div", {
|
|
25103
25107
|
key: "moveArrayElementDown",
|
|
25104
|
-
className: aphrodite.css(styles$
|
|
25108
|
+
className: aphrodite.css(styles$n.control)
|
|
25105
25109
|
}, /*#__PURE__*/React__namespace.createElement(SimpleButton, {
|
|
25106
25110
|
color: "orange",
|
|
25107
25111
|
title: "Move down",
|
|
25108
25112
|
onClick: () => actions.moveArrayElementDown(subpath)
|
|
25109
25113
|
}, /*#__PURE__*/React__namespace.createElement(InlineIcon$6, iconChevronDown))), /*#__PURE__*/React__namespace.createElement("div", {
|
|
25110
25114
|
key: "removeArrayElement",
|
|
25111
|
-
className: aphrodite.css(styles$
|
|
25115
|
+
className: aphrodite.css(styles$n.control)
|
|
25112
25116
|
}, /*#__PURE__*/React__namespace.createElement(SimpleButton, {
|
|
25113
25117
|
color: "orange",
|
|
25114
25118
|
title: "Delete",
|
|
@@ -25116,7 +25120,7 @@ const ArrayNodeContent = props => {
|
|
|
25116
25120
|
}, /*#__PURE__*/React__namespace.createElement(InlineIcon$6, iconTrash$4)))];
|
|
25117
25121
|
return /*#__PURE__*/React__namespace.createElement("div", {
|
|
25118
25122
|
key: i,
|
|
25119
|
-
className: aphrodite.css(styles$
|
|
25123
|
+
className: aphrodite.css(styles$n.arrayElement, !elementIsLeaf && styles$n.arrayElementAndNotLeaf)
|
|
25120
25124
|
}, /*#__PURE__*/React__namespace.createElement(NodeContainer, _extends({}, otherProps, {
|
|
25121
25125
|
key: i,
|
|
25122
25126
|
shape: shape.elementShape,
|
|
@@ -25142,7 +25146,7 @@ const ObjectNodeContent = props => {
|
|
|
25142
25146
|
// made sense to the shape's author is the order in which we'll iterate :)
|
|
25143
25147
|
const children = Object.keys(shape.shape).map(subkey => /*#__PURE__*/React__namespace.createElement("div", {
|
|
25144
25148
|
key: subkey,
|
|
25145
|
-
className: aphrodite.css(styles$
|
|
25149
|
+
className: aphrodite.css(styles$n.objectElement)
|
|
25146
25150
|
}, /*#__PURE__*/React__namespace.createElement(NodeContainer, _extends({}, otherProps, {
|
|
25147
25151
|
shape: shape.shape[subkey],
|
|
25148
25152
|
data: data[subkey],
|
|
@@ -25311,7 +25315,7 @@ class MultiRendererEditor extends React__namespace.Component {
|
|
|
25311
25315
|
}, this._renderContent());
|
|
25312
25316
|
}
|
|
25313
25317
|
}
|
|
25314
|
-
const styles$
|
|
25318
|
+
const styles$n = aphrodite.StyleSheet.create({
|
|
25315
25319
|
// This is used in a number of places throughout this file.
|
|
25316
25320
|
container: {},
|
|
25317
25321
|
// eslint-disable-next-line react-native/no-unused-styles
|
|
@@ -25463,47 +25467,47 @@ const StatefulArticleEditor = createReactClass__default["default"]({
|
|
|
25463
25467
|
screen
|
|
25464
25468
|
} = this.state;
|
|
25465
25469
|
return /*#__PURE__*/React__namespace.createElement("div", null, /*#__PURE__*/React__namespace.createElement("div", {
|
|
25466
|
-
style: styles$
|
|
25470
|
+
style: styles$m.controlBar
|
|
25467
25471
|
}, /*#__PURE__*/React__namespace.createElement("span", {
|
|
25468
|
-
style: styles$
|
|
25472
|
+
style: styles$m.controls
|
|
25469
25473
|
}, "Mode:", " ", /*#__PURE__*/React__namespace.createElement("span", {
|
|
25470
25474
|
onClick: () => this.setState({
|
|
25471
25475
|
mode: "edit"
|
|
25472
25476
|
}),
|
|
25473
|
-
style: mode === "edit" ? styles$
|
|
25477
|
+
style: mode === "edit" ? styles$m.controlSelected : styles$m.control
|
|
25474
25478
|
}, "EDIT"), " | ", /*#__PURE__*/React__namespace.createElement("span", {
|
|
25475
25479
|
onClick: () => this.setState({
|
|
25476
25480
|
mode: "preview"
|
|
25477
25481
|
}),
|
|
25478
|
-
style: mode === "preview" ? styles$
|
|
25482
|
+
style: mode === "preview" ? styles$m.controlSelected : styles$m.control
|
|
25479
25483
|
}, "PREVIEW"), " | ", /*#__PURE__*/React__namespace.createElement("span", {
|
|
25480
25484
|
onClick: () => this.setState({
|
|
25481
25485
|
mode: "json"
|
|
25482
25486
|
}),
|
|
25483
|
-
style: mode === "json" ? styles$
|
|
25487
|
+
style: mode === "json" ? styles$m.controlSelected : styles$m.control
|
|
25484
25488
|
}, "JSON")), /*#__PURE__*/React__namespace.createElement("span", {
|
|
25485
|
-
style: styles$
|
|
25489
|
+
style: styles$m.controls
|
|
25486
25490
|
}, "Screen:", " ", /*#__PURE__*/React__namespace.createElement("span", {
|
|
25487
25491
|
onClick: () => this.setState({
|
|
25488
25492
|
screen: "phone"
|
|
25489
25493
|
}),
|
|
25490
|
-
style: screen === "phone" ? styles$
|
|
25494
|
+
style: screen === "phone" ? styles$m.controlSelected : styles$m.control
|
|
25491
25495
|
}, "PHONE"), " | ", /*#__PURE__*/React__namespace.createElement("span", {
|
|
25492
25496
|
onClick: () => this.setState({
|
|
25493
25497
|
screen: "tablet"
|
|
25494
25498
|
}),
|
|
25495
|
-
style: screen === "tablet" ? styles$
|
|
25499
|
+
style: screen === "tablet" ? styles$m.controlSelected : styles$m.control
|
|
25496
25500
|
}, "TABLET"), " | ", /*#__PURE__*/React__namespace.createElement("span", {
|
|
25497
25501
|
onClick: () => this.setState({
|
|
25498
25502
|
screen: "desktop"
|
|
25499
25503
|
}),
|
|
25500
|
-
style: screen === "desktop" ? styles$
|
|
25504
|
+
style: screen === "desktop" ? styles$m.controlSelected : styles$m.control
|
|
25501
25505
|
}, "DESKTOP"))), /*#__PURE__*/React__namespace.createElement("div", {
|
|
25502
|
-
style: styles$
|
|
25506
|
+
style: styles$m.editor
|
|
25503
25507
|
}, /*#__PURE__*/React__namespace.createElement(ArticleEditor, this.state)));
|
|
25504
25508
|
}
|
|
25505
25509
|
});
|
|
25506
|
-
const styles$
|
|
25510
|
+
const styles$m = {
|
|
25507
25511
|
controlBar: {
|
|
25508
25512
|
marginBottom: 25,
|
|
25509
25513
|
marginTop: 5
|
|
@@ -27041,10 +27045,10 @@ class GradedGroupEditor extends React__namespace.Component {
|
|
|
27041
27045
|
}, /*#__PURE__*/React__namespace.createElement("div", {
|
|
27042
27046
|
className: "perseus-widget-row"
|
|
27043
27047
|
}, /*#__PURE__*/React__namespace.createElement("label", {
|
|
27044
|
-
className: aphrodite.css(styles$
|
|
27048
|
+
className: aphrodite.css(styles$l.title)
|
|
27045
27049
|
}, "Title:", " ", /*#__PURE__*/React__namespace.createElement(TextInput$6, {
|
|
27046
27050
|
value: this.props.title,
|
|
27047
|
-
className: aphrodite.css(styles$
|
|
27051
|
+
className: aphrodite.css(styles$l.input)
|
|
27048
27052
|
// @ts-expect-error - TS2554 - Expected 3 arguments, but got 1.
|
|
27049
27053
|
,
|
|
27050
27054
|
onChange: this.change("title")
|
|
@@ -27069,7 +27073,7 @@ class GradedGroupEditor extends React__namespace.Component {
|
|
|
27069
27073
|
}, /*#__PURE__*/React__namespace.createElement(InlineIcon$4, iconPlus$1), " Add a hint"), this.props.hint && /*#__PURE__*/React__namespace.createElement("div", {
|
|
27070
27074
|
className: "perseus-hint-editor"
|
|
27071
27075
|
}, /*#__PURE__*/React__namespace.createElement("div", {
|
|
27072
|
-
className: aphrodite.css(styles$
|
|
27076
|
+
className: aphrodite.css(styles$l.hintsTitle)
|
|
27073
27077
|
}, "Hint"), /*#__PURE__*/React__namespace.createElement(Editor, {
|
|
27074
27078
|
ref: this.hintEditor,
|
|
27075
27079
|
content: this.props.hint ? this.props.hint.content : "",
|
|
@@ -27101,7 +27105,7 @@ class GradedGroupEditor extends React__namespace.Component {
|
|
|
27101
27105
|
};
|
|
27102
27106
|
};
|
|
27103
27107
|
}
|
|
27104
|
-
const styles$
|
|
27108
|
+
const styles$l = aphrodite.StyleSheet.create({
|
|
27105
27109
|
title: {
|
|
27106
27110
|
fontSize: 18,
|
|
27107
27111
|
fontWeight: "bold"
|
|
@@ -28464,13 +28468,13 @@ function MathquillInput(props) {
|
|
|
28464
28468
|
}
|
|
28465
28469
|
});
|
|
28466
28470
|
return /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, {
|
|
28467
|
-
style: styles$
|
|
28471
|
+
style: styles$k.outerWrapper
|
|
28468
28472
|
}, /*#__PURE__*/React__namespace.createElement("span", {
|
|
28469
28473
|
ref: mathFieldWrapperRef,
|
|
28470
28474
|
className: "perseus-math-input mq-editable-field mq-math-mode"
|
|
28471
28475
|
}));
|
|
28472
28476
|
}
|
|
28473
|
-
const styles$
|
|
28477
|
+
const styles$k = aphrodite.StyleSheet.create({
|
|
28474
28478
|
outerWrapper: {
|
|
28475
28479
|
display: "inline-block",
|
|
28476
28480
|
borderStyle: "solid",
|
|
@@ -29556,7 +29560,7 @@ const GraphPointsCountSelector = _ref => {
|
|
|
29556
29560
|
// Never uses placeholder, always has value
|
|
29557
29561
|
,
|
|
29558
29562
|
placeholder: "",
|
|
29559
|
-
style: styles$
|
|
29563
|
+
style: styles$j.singleSelectShort
|
|
29560
29564
|
}, [...[...Array(7).keys()].map(n => /*#__PURE__*/React__namespace.createElement(wonderBlocksDropdown.OptionItem, {
|
|
29561
29565
|
key: n,
|
|
29562
29566
|
value: `${n}`,
|
|
@@ -29566,7 +29570,7 @@ const GraphPointsCountSelector = _ref => {
|
|
|
29566
29570
|
label: "unlimited"
|
|
29567
29571
|
})]);
|
|
29568
29572
|
};
|
|
29569
|
-
const styles$
|
|
29573
|
+
const styles$j = aphrodite.StyleSheet.create({
|
|
29570
29574
|
singleSelectShort: {
|
|
29571
29575
|
// Non-standard spacing, but it's the smallest we can go
|
|
29572
29576
|
// without running into styling issues with the dropdown.
|
|
@@ -29579,7 +29583,7 @@ const GraphTypeSelector = props => {
|
|
|
29579
29583
|
selectedValue: props.graphType,
|
|
29580
29584
|
onChange: props.onChange,
|
|
29581
29585
|
placeholder: "Select a graph type",
|
|
29582
|
-
style: styles$
|
|
29586
|
+
style: styles$i.singleSelectShort
|
|
29583
29587
|
}, /*#__PURE__*/React__namespace.createElement(wonderBlocksDropdown.OptionItem, {
|
|
29584
29588
|
value: "linear",
|
|
29585
29589
|
label: "Linear function"
|
|
@@ -29612,7 +29616,7 @@ const GraphTypeSelector = props => {
|
|
|
29612
29616
|
label: "Angle"
|
|
29613
29617
|
}));
|
|
29614
29618
|
};
|
|
29615
|
-
const styles$
|
|
29619
|
+
const styles$i = aphrodite.StyleSheet.create({
|
|
29616
29620
|
singleSelectShort: {
|
|
29617
29621
|
// Non-standard spacing, but it's the smallest we can go
|
|
29618
29622
|
// without running into styling issues with the dropdown.
|
|
@@ -29628,19 +29632,25 @@ const LabeledRow = props => {
|
|
|
29628
29632
|
labelSide = "left",
|
|
29629
29633
|
style
|
|
29630
29634
|
} = props;
|
|
29631
|
-
return /*#__PURE__*/React__namespace.createElement("label",
|
|
29632
|
-
|
|
29635
|
+
return /*#__PURE__*/React__namespace.createElement("label", {
|
|
29636
|
+
className: aphrodite.css(styles$h.label)
|
|
29637
|
+
}, /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, {
|
|
29638
|
+
style: [styles$h.row, style]
|
|
29633
29639
|
}, labelSide === "start" || /*#__PURE__*/React__namespace.createElement(wonderBlocksTypography.LabelSmall, {
|
|
29634
|
-
style: styles$
|
|
29640
|
+
style: styles$h.spaceEnd
|
|
29635
29641
|
}, label), children, labelSide === "end" && /*#__PURE__*/React__namespace.createElement(wonderBlocksTypography.LabelSmall, {
|
|
29636
|
-
style: styles$
|
|
29642
|
+
style: styles$h.spaceStart
|
|
29637
29643
|
}, label)));
|
|
29638
29644
|
};
|
|
29639
|
-
const styles$
|
|
29645
|
+
const styles$h = aphrodite.StyleSheet.create({
|
|
29646
|
+
label: {
|
|
29647
|
+
width: "fit-content"
|
|
29648
|
+
},
|
|
29640
29649
|
row: {
|
|
29641
29650
|
flexDirection: "row",
|
|
29642
29651
|
marginTop: wonderBlocksTokens.spacing.xSmall_8,
|
|
29643
|
-
alignItems: "center"
|
|
29652
|
+
alignItems: "center",
|
|
29653
|
+
width: "fit-content"
|
|
29644
29654
|
},
|
|
29645
29655
|
spaceStart: {
|
|
29646
29656
|
marginInlineStart: wonderBlocksTokens.spacing.xSmall_8
|
|
@@ -30054,10 +30064,10 @@ class InteractiveGraphSettings extends React__namespace.Component {
|
|
|
30054
30064
|
onChange: this.change
|
|
30055
30065
|
}))), /*#__PURE__*/React__namespace.createElement(LabeledRow, {
|
|
30056
30066
|
label: "Background image URL:",
|
|
30057
|
-
style: styles$
|
|
30067
|
+
style: styles$g.resetSpaceTop
|
|
30058
30068
|
}, /*#__PURE__*/React__namespace.createElement("input", {
|
|
30059
30069
|
type: "text",
|
|
30060
|
-
className: aphrodite.css(styles$
|
|
30070
|
+
className: aphrodite.css(styles$g.backgroundUrlInput),
|
|
30061
30071
|
ref: this.bgUrlRef,
|
|
30062
30072
|
value: this.state.backgroundImage.url || "",
|
|
30063
30073
|
onChange: e => {
|
|
@@ -30073,24 +30083,24 @@ class InteractiveGraphSettings extends React__namespace.Component {
|
|
|
30073
30083
|
onKeyPress: this.changeBackgroundUrl,
|
|
30074
30084
|
onBlur: this.changeBackgroundUrl
|
|
30075
30085
|
}), /*#__PURE__*/React__namespace.createElement(InfoTip$c, null, /*#__PURE__*/React__namespace.createElement("p", null, "Create an image in graphie, or use the \"Add image\" function to create a background."))), /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, {
|
|
30076
|
-
style: styles$
|
|
30086
|
+
style: styles$g.rulerSection
|
|
30077
30087
|
}, /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, {
|
|
30078
|
-
style: styles$
|
|
30088
|
+
style: styles$g.checkboxRow
|
|
30079
30089
|
}, /*#__PURE__*/React__namespace.createElement(PropCheckBox$7, {
|
|
30080
30090
|
label: "Show ruler",
|
|
30081
30091
|
showRuler: this.props.showRuler,
|
|
30082
30092
|
onChange: this.change,
|
|
30083
|
-
style: styles$
|
|
30093
|
+
style: styles$g.resetSpaceTop
|
|
30084
30094
|
}), /*#__PURE__*/React__namespace.createElement(PropCheckBox$7, {
|
|
30085
30095
|
label: "Show protractor",
|
|
30086
30096
|
showProtractor: this.props.showProtractor,
|
|
30087
30097
|
onChange: this.change,
|
|
30088
|
-
style: styles$
|
|
30098
|
+
style: styles$g.resetSpaceTop
|
|
30089
30099
|
})), this.props.showRuler && /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, {
|
|
30090
|
-
style: styles$
|
|
30100
|
+
style: styles$g.spaceTop
|
|
30091
30101
|
}, /*#__PURE__*/React__namespace.createElement(LabeledRow, {
|
|
30092
30102
|
label: "Ruler label:",
|
|
30093
|
-
style: styles$
|
|
30103
|
+
style: styles$g.resetSpaceTop
|
|
30094
30104
|
}, /*#__PURE__*/React__namespace.createElement(wonderBlocksDropdown.SingleSelect, {
|
|
30095
30105
|
id: "ruler-label-select",
|
|
30096
30106
|
selectedValue: this.props.rulerLabel,
|
|
@@ -30100,7 +30110,7 @@ class InteractiveGraphSettings extends React__namespace.Component {
|
|
|
30100
30110
|
});
|
|
30101
30111
|
},
|
|
30102
30112
|
placeholder: "None",
|
|
30103
|
-
style: styles$
|
|
30113
|
+
style: styles$g.singleSelectShort
|
|
30104
30114
|
}, /*#__PURE__*/React__namespace.createElement(wonderBlocksDropdown.OptionItem, {
|
|
30105
30115
|
value: "",
|
|
30106
30116
|
label: "None",
|
|
@@ -30141,7 +30151,7 @@ class InteractiveGraphSettings extends React__namespace.Component {
|
|
|
30141
30151
|
});
|
|
30142
30152
|
},
|
|
30143
30153
|
placeholder: "10",
|
|
30144
|
-
style: styles$
|
|
30154
|
+
style: styles$g.singleSelectShort
|
|
30145
30155
|
}, [1, 2, 4, 8, 10, 16].map(value => /*#__PURE__*/React__namespace.createElement(wonderBlocksDropdown.OptionItem, {
|
|
30146
30156
|
key: value,
|
|
30147
30157
|
value: `${value}`,
|
|
@@ -30149,7 +30159,7 @@ class InteractiveGraphSettings extends React__namespace.Component {
|
|
|
30149
30159
|
})))))));
|
|
30150
30160
|
}
|
|
30151
30161
|
}
|
|
30152
|
-
const styles$
|
|
30162
|
+
const styles$g = aphrodite.StyleSheet.create({
|
|
30153
30163
|
resetSpaceTop: {
|
|
30154
30164
|
marginTop: 0
|
|
30155
30165
|
},
|
|
@@ -30180,6 +30190,315 @@ const styles$c = aphrodite.StyleSheet.create({
|
|
|
30180
30190
|
}
|
|
30181
30191
|
});
|
|
30182
30192
|
|
|
30193
|
+
/**
|
|
30194
|
+
* Dropdown for selecting a locked figure to add to an interactive graph.
|
|
30195
|
+
* Locked figures are elements (points, segmeents, etc.) that are not
|
|
30196
|
+
* interactive, just present in the graph's background.
|
|
30197
|
+
*
|
|
30198
|
+
* Used in the interactive graph editor's locked figures section.
|
|
30199
|
+
*/
|
|
30200
|
+
const LockedFigureSelect = props => {
|
|
30201
|
+
const {
|
|
30202
|
+
id,
|
|
30203
|
+
onChange
|
|
30204
|
+
} = props;
|
|
30205
|
+
return /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, {
|
|
30206
|
+
style: styles$f.container
|
|
30207
|
+
}, /*#__PURE__*/React__namespace.createElement(wonderBlocksDropdown.ActionMenu, {
|
|
30208
|
+
menuText: "Add element",
|
|
30209
|
+
style: styles$f.addElementSelect
|
|
30210
|
+
}, [/*#__PURE__*/React__namespace.createElement(wonderBlocksDropdown.ActionItem, {
|
|
30211
|
+
key: `${id}-point`,
|
|
30212
|
+
label: "Point",
|
|
30213
|
+
onClick: () => onChange("point")
|
|
30214
|
+
}, "Point")]));
|
|
30215
|
+
};
|
|
30216
|
+
const styles$f = aphrodite.StyleSheet.create({
|
|
30217
|
+
container: {
|
|
30218
|
+
marginTop: wonderBlocksTokens.spacing.medium_16
|
|
30219
|
+
},
|
|
30220
|
+
addElementSelect: {
|
|
30221
|
+
backgroundColor: wonderBlocksTokens.color.fadedBlue16,
|
|
30222
|
+
borderRadius: wonderBlocksTokens.spacing.xxxSmall_4
|
|
30223
|
+
}
|
|
30224
|
+
});
|
|
30225
|
+
|
|
30226
|
+
const mediaDefaultSpecLargeMarginWidth = wonderBlocksTokens.spacing.large_24;
|
|
30227
|
+
const MEDIA_DEFAULT_SPEC = {
|
|
30228
|
+
small: {
|
|
30229
|
+
query: "(max-width: 767px)",
|
|
30230
|
+
totalColumns: 4,
|
|
30231
|
+
gutterWidth: wonderBlocksTokens.spacing.medium_16,
|
|
30232
|
+
marginWidth: wonderBlocksTokens.spacing.medium_16
|
|
30233
|
+
},
|
|
30234
|
+
medium: {
|
|
30235
|
+
query: "(min-width: 768px) and (max-width: 1023px)",
|
|
30236
|
+
totalColumns: 8,
|
|
30237
|
+
gutterWidth: wonderBlocksTokens.spacing.xLarge_32,
|
|
30238
|
+
marginWidth: wonderBlocksTokens.spacing.large_24
|
|
30239
|
+
},
|
|
30240
|
+
large: {
|
|
30241
|
+
query: "(min-width: 1024px)",
|
|
30242
|
+
totalColumns: 12,
|
|
30243
|
+
gutterWidth: wonderBlocksTokens.spacing.xLarge_32,
|
|
30244
|
+
marginWidth: mediaDefaultSpecLargeMarginWidth,
|
|
30245
|
+
maxWidth: 1120 + mediaDefaultSpecLargeMarginWidth * 2
|
|
30246
|
+
}
|
|
30247
|
+
};
|
|
30248
|
+
({
|
|
30249
|
+
large: {
|
|
30250
|
+
query: "(min-width: 1px)",
|
|
30251
|
+
totalColumns: 12,
|
|
30252
|
+
gutterWidth: wonderBlocksTokens.spacing.xLarge_32,
|
|
30253
|
+
marginWidth: wonderBlocksTokens.spacing.medium_16
|
|
30254
|
+
}
|
|
30255
|
+
});
|
|
30256
|
+
({
|
|
30257
|
+
small: {
|
|
30258
|
+
query: "(max-width: 767px)",
|
|
30259
|
+
totalColumns: 4,
|
|
30260
|
+
gutterWidth: wonderBlocksTokens.spacing.medium_16,
|
|
30261
|
+
marginWidth: wonderBlocksTokens.spacing.medium_16
|
|
30262
|
+
},
|
|
30263
|
+
large: {
|
|
30264
|
+
query: "(min-width: 768px)",
|
|
30265
|
+
totalColumns: 12,
|
|
30266
|
+
gutterWidth: wonderBlocksTokens.spacing.xLarge_32,
|
|
30267
|
+
marginWidth: wonderBlocksTokens.spacing.xxLarge_48
|
|
30268
|
+
}
|
|
30269
|
+
});
|
|
30270
|
+
|
|
30271
|
+
const defaultContext = {
|
|
30272
|
+
ssrSize: "large",
|
|
30273
|
+
mediaSpec: MEDIA_DEFAULT_SPEC
|
|
30274
|
+
};
|
|
30275
|
+
const MediaLayoutContext = React__namespace.createContext(defaultContext);
|
|
30276
|
+
MediaLayoutContext.displayName = "MediaLayoutContext";
|
|
30277
|
+
|
|
30278
|
+
class Spring extends React__namespace.Component {
|
|
30279
|
+
render() {
|
|
30280
|
+
const {
|
|
30281
|
+
style
|
|
30282
|
+
} = this.props;
|
|
30283
|
+
return React__namespace.createElement(wonderBlocksCore.View, {
|
|
30284
|
+
"aria-hidden": "true",
|
|
30285
|
+
style: [styles$e.grow, style]
|
|
30286
|
+
});
|
|
30287
|
+
}
|
|
30288
|
+
}
|
|
30289
|
+
const styles$e = aphrodite.StyleSheet.create({
|
|
30290
|
+
grow: {
|
|
30291
|
+
flexGrow: 1
|
|
30292
|
+
}
|
|
30293
|
+
});
|
|
30294
|
+
|
|
30295
|
+
function focusWithChromeStickyFocusBugWorkaround(element) {
|
|
30296
|
+
// NOTE(marksandstrom) Chrome sticky focus bug.
|
|
30297
|
+
//
|
|
30298
|
+
// There is a bug in Chrome related to sticky positioning and
|
|
30299
|
+
// focus: When a child of an element with sticky positioning is
|
|
30300
|
+
// focused with the focus() method, the scrollable area
|
|
30301
|
+
// containing that element will scroll to the top (even though
|
|
30302
|
+
// the element is already visble on the page). For a dropdown
|
|
30303
|
+
// this means that the area will be scrolled to the top when
|
|
30304
|
+
// the user interacts with the dropdown (since we actively
|
|
30305
|
+
// manage dropdown header and option focus for keyboard users).
|
|
30306
|
+
//
|
|
30307
|
+
// To work around this bug the `preventScroll` focus option is
|
|
30308
|
+
// used.
|
|
30309
|
+
//
|
|
30310
|
+
// Using `focusOptions` is an experimental browser feature
|
|
30311
|
+
// "that should not be used in production code". However, since
|
|
30312
|
+
// Chrome is the only browser we support that exhibits this
|
|
30313
|
+
// buggy behavior and using `focusOptions` works around the
|
|
30314
|
+
// bug, it is perfectly reasonable to use the feature in this
|
|
30315
|
+
// case. We are not relying on the effect of the
|
|
30316
|
+
// `preventScroll` option otherwise.
|
|
30317
|
+
//
|
|
30318
|
+
// focusOptions documentation:
|
|
30319
|
+
//
|
|
30320
|
+
// https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/focus
|
|
30321
|
+
//
|
|
30322
|
+
// Note that there could be cases where we want default focus() behavior.
|
|
30323
|
+
// One that comes to mind is a dropdown with a long list of options that
|
|
30324
|
+
// might be rendered off screen when opened. With this workaround the
|
|
30325
|
+
// selected option would not be scrolled into view if the option is near
|
|
30326
|
+
// the end of the list. We're not aware of any uses of the dropdown where
|
|
30327
|
+
// this is an issue, however, so there isn't currently a way to out of the
|
|
30328
|
+
// `preventScroll` behavior.
|
|
30329
|
+
|
|
30330
|
+
// @ts-expect-error - TS2339 - Property 'focus' does not exist on type 'Element'.
|
|
30331
|
+
element.focus({
|
|
30332
|
+
preventScroll: true
|
|
30333
|
+
});
|
|
30334
|
+
}
|
|
30335
|
+
function getValidNumberFromString(value) {
|
|
30336
|
+
const parsed = parseInt(value);
|
|
30337
|
+
// If the value is not a number, return 0.
|
|
30338
|
+
return isNaN(parsed) ? 0 : parsed;
|
|
30339
|
+
}
|
|
30340
|
+
function getDefaultFigureForFigureType(type) {
|
|
30341
|
+
switch (type) {
|
|
30342
|
+
case "point":
|
|
30343
|
+
return {
|
|
30344
|
+
type: "point",
|
|
30345
|
+
coord: [0, 0]
|
|
30346
|
+
};
|
|
30347
|
+
}
|
|
30348
|
+
}
|
|
30349
|
+
|
|
30350
|
+
/**
|
|
30351
|
+
* LockedPointSettings is a component that allows the user to edit the
|
|
30352
|
+
* settings of specifically a locked point on the graph.
|
|
30353
|
+
*
|
|
30354
|
+
* Used in the interactive graph editor's locked figures section.
|
|
30355
|
+
*/
|
|
30356
|
+
const LockedPointSettings = props => {
|
|
30357
|
+
const {
|
|
30358
|
+
coord,
|
|
30359
|
+
onRemove,
|
|
30360
|
+
onChangeCoord
|
|
30361
|
+
} = props;
|
|
30362
|
+
const [coordState, setCoordState] = React__namespace.useState([
|
|
30363
|
+
// Using strings to make it easier to work with the text fields.
|
|
30364
|
+
coord[0].toString(), coord[1].toString()]);
|
|
30365
|
+
|
|
30366
|
+
// Generate unique IDs so that the programmatic labels can be associated
|
|
30367
|
+
// with their respective text fields.
|
|
30368
|
+
const ids = wonderBlocksCore.useUniqueIdWithMock();
|
|
30369
|
+
const xCoordId = ids.get("x-coord");
|
|
30370
|
+
const yCoordId = ids.get("y-coord");
|
|
30371
|
+
function handleBlur() {
|
|
30372
|
+
const validCoord = [getValidNumberFromString(coordState[0]), getValidNumberFromString(coordState[1])];
|
|
30373
|
+
|
|
30374
|
+
// Make the text field only show valid numbers after blur.
|
|
30375
|
+
setCoordState([validCoord[0].toString(), validCoord[1].toString()]);
|
|
30376
|
+
// Update the graph with the new coordinates.
|
|
30377
|
+
onChangeCoord(validCoord);
|
|
30378
|
+
}
|
|
30379
|
+
function handleChange(newValue, coordIndex) {
|
|
30380
|
+
const newCoord = [...coordState];
|
|
30381
|
+
newCoord[coordIndex] = newValue;
|
|
30382
|
+
setCoordState(newCoord);
|
|
30383
|
+
}
|
|
30384
|
+
return /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, {
|
|
30385
|
+
style: styles$d.container
|
|
30386
|
+
}, /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, {
|
|
30387
|
+
style: styles$d.row
|
|
30388
|
+
}, /*#__PURE__*/React__namespace.createElement(wonderBlocksTypography.LabelLarge, null, "Point"), /*#__PURE__*/React__namespace.createElement(Spring, null), /*#__PURE__*/React__namespace.createElement(IconButton__default["default"], {
|
|
30389
|
+
icon: trashIcon__default["default"],
|
|
30390
|
+
"aria-label": `Delete locked point at ${coordState[0]}, ${coordState[1]}`,
|
|
30391
|
+
onClick: onRemove
|
|
30392
|
+
})), /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, null, /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, {
|
|
30393
|
+
style: styles$d.row
|
|
30394
|
+
}, /*#__PURE__*/React__namespace.createElement(wonderBlocksTypography.LabelMedium, {
|
|
30395
|
+
htmlFor: xCoordId,
|
|
30396
|
+
style: styles$d.label,
|
|
30397
|
+
tag: "label"
|
|
30398
|
+
}, "x Coordinate"), /*#__PURE__*/React__namespace.createElement(wonderBlocksForm.TextField, {
|
|
30399
|
+
id: xCoordId,
|
|
30400
|
+
value: coordState[0],
|
|
30401
|
+
onChange: newValue => handleChange(newValue, 0),
|
|
30402
|
+
onBlur: handleBlur,
|
|
30403
|
+
style: styles$d.textField
|
|
30404
|
+
})), /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, {
|
|
30405
|
+
style: styles$d.row
|
|
30406
|
+
}, /*#__PURE__*/React__namespace.createElement(wonderBlocksTypography.LabelMedium, {
|
|
30407
|
+
htmlFor: yCoordId,
|
|
30408
|
+
style: styles$d.label,
|
|
30409
|
+
tag: "label"
|
|
30410
|
+
}, "y Coordinate"), /*#__PURE__*/React__namespace.createElement(wonderBlocksForm.TextField, {
|
|
30411
|
+
id: yCoordId,
|
|
30412
|
+
value: coordState[1],
|
|
30413
|
+
onChange: newValue => handleChange(newValue, 1),
|
|
30414
|
+
onBlur: handleBlur,
|
|
30415
|
+
style: styles$d.textField
|
|
30416
|
+
}))));
|
|
30417
|
+
};
|
|
30418
|
+
const styles$d = aphrodite.StyleSheet.create({
|
|
30419
|
+
container: {
|
|
30420
|
+
backgroundColor: wonderBlocksTokens.color.fadedBlue8,
|
|
30421
|
+
marginBottom: wonderBlocksTokens.spacing.xSmall_8,
|
|
30422
|
+
padding: wonderBlocksTokens.spacing.medium_16,
|
|
30423
|
+
borderRadius: wonderBlocksTokens.spacing.xSmall_8
|
|
30424
|
+
},
|
|
30425
|
+
row: {
|
|
30426
|
+
flexDirection: "row",
|
|
30427
|
+
alignItems: "center",
|
|
30428
|
+
marginBottom: wonderBlocksTokens.spacing.xSmall_8
|
|
30429
|
+
},
|
|
30430
|
+
label: {
|
|
30431
|
+
marginInlineEnd: wonderBlocksTokens.spacing.xSmall_8
|
|
30432
|
+
},
|
|
30433
|
+
textField: {
|
|
30434
|
+
width: wonderBlocksTokens.spacing.xxxLarge_64
|
|
30435
|
+
}
|
|
30436
|
+
});
|
|
30437
|
+
|
|
30438
|
+
/**
|
|
30439
|
+
* LockedFigureSettings takes in a figure and renders the
|
|
30440
|
+
* respective settings for that figure type.
|
|
30441
|
+
*
|
|
30442
|
+
* Used in the interactive graph editor's locked figures section.
|
|
30443
|
+
*/
|
|
30444
|
+
|
|
30445
|
+
// Union this type with other locked figure types when they are added.
|
|
30446
|
+
|
|
30447
|
+
const LockedFigureSettings = props => {
|
|
30448
|
+
switch (props.type) {
|
|
30449
|
+
case "point":
|
|
30450
|
+
return /*#__PURE__*/React__namespace.createElement(LockedPointSettings, props);
|
|
30451
|
+
}
|
|
30452
|
+
return null;
|
|
30453
|
+
};
|
|
30454
|
+
|
|
30455
|
+
const LockedFiguresSection = props => {
|
|
30456
|
+
const uniqueId = wonderBlocksCore.useUniqueIdWithMock().get("locked-figures-section");
|
|
30457
|
+
const {
|
|
30458
|
+
figures,
|
|
30459
|
+
onChange
|
|
30460
|
+
} = props;
|
|
30461
|
+
function addLockedFigure(newFigure) {
|
|
30462
|
+
const lockedFigures = figures || [];
|
|
30463
|
+
const newProps = {
|
|
30464
|
+
lockedFigures: [...lockedFigures, getDefaultFigureForFigureType(newFigure)]
|
|
30465
|
+
};
|
|
30466
|
+
onChange(newProps);
|
|
30467
|
+
}
|
|
30468
|
+
function removeLockedFigure(index) {
|
|
30469
|
+
const lockedFigures = figures || [];
|
|
30470
|
+
onChange({
|
|
30471
|
+
lockedFigures: [...lockedFigures.slice(0, index), ...lockedFigures.slice(index + 1)]
|
|
30472
|
+
});
|
|
30473
|
+
}
|
|
30474
|
+
function changeCoord(index, coord) {
|
|
30475
|
+
const lockedFigures = figures || [];
|
|
30476
|
+
const newProps = {
|
|
30477
|
+
lockedFigures: [...lockedFigures.slice(0, index), {
|
|
30478
|
+
...lockedFigures[index],
|
|
30479
|
+
coord
|
|
30480
|
+
}, ...lockedFigures.slice(index + 1)]
|
|
30481
|
+
};
|
|
30482
|
+
onChange(newProps);
|
|
30483
|
+
}
|
|
30484
|
+
return /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, {
|
|
30485
|
+
style: styles$c.container
|
|
30486
|
+
}, figures?.map((figure, index) => /*#__PURE__*/React__namespace.createElement(LockedFigureSettings, _extends({
|
|
30487
|
+
key: `${uniqueId}-locked-${figure}-${index}`
|
|
30488
|
+
}, figure, {
|
|
30489
|
+
onRemove: () => removeLockedFigure(index),
|
|
30490
|
+
onChangeCoord: coord => changeCoord(index, coord)
|
|
30491
|
+
}))), /*#__PURE__*/React__namespace.createElement(LockedFigureSelect, {
|
|
30492
|
+
id: `${uniqueId}-select`,
|
|
30493
|
+
onChange: addLockedFigure
|
|
30494
|
+
}));
|
|
30495
|
+
};
|
|
30496
|
+
const styles$c = aphrodite.StyleSheet.create({
|
|
30497
|
+
container: {
|
|
30498
|
+
paddingTop: wonderBlocksTokens.spacing.large_24
|
|
30499
|
+
}
|
|
30500
|
+
});
|
|
30501
|
+
|
|
30183
30502
|
const SegmentCountSelector = _ref => {
|
|
30184
30503
|
let {
|
|
30185
30504
|
numSegments = 1,
|
|
@@ -30288,6 +30607,7 @@ class InteractiveGraphEditor extends React__namespace.Component {
|
|
|
30288
30607
|
showTooltips: this.props.showTooltips,
|
|
30289
30608
|
rulerLabel: this.props.rulerLabel,
|
|
30290
30609
|
rulerTicks: this.props.rulerTicks,
|
|
30610
|
+
lockedFigures: this.props.lockedFigures,
|
|
30291
30611
|
trackInteraction: function () {},
|
|
30292
30612
|
onChange: newProps => {
|
|
30293
30613
|
let correct = this.props.correct;
|
|
@@ -30508,7 +30828,13 @@ class InteractiveGraphEditor extends React__namespace.Component {
|
|
|
30508
30828
|
borderStyle: "solid",
|
|
30509
30829
|
borderWidth: 1
|
|
30510
30830
|
}
|
|
30511
|
-
}, equationString), /*#__PURE__*/React__namespace.createElement(InfoTip$b, null, /*#__PURE__*/React__namespace.createElement("p", null, "Graph the correct answer in the graph below and ensure the equation or point coordinates displayed represent the correct answer."))), graph
|
|
30831
|
+
}, equationString), /*#__PURE__*/React__namespace.createElement(InfoTip$b, null, /*#__PURE__*/React__namespace.createElement("p", null, "Graph the correct answer in the graph below and ensure the equation or point coordinates displayed represent the correct answer."))), graph,
|
|
30832
|
+
// Only show the "Add element" dropdown if the graph is
|
|
30833
|
+
// using Mafs.
|
|
30834
|
+
this.props.graph && this.props.apiOptions?.flags?.["mafs"]?.[this.props.graph.type] && /*#__PURE__*/React__namespace.createElement(LockedFiguresSection, {
|
|
30835
|
+
figures: this.props.lockedFigures,
|
|
30836
|
+
onChange: this.props.onChange
|
|
30837
|
+
}));
|
|
30512
30838
|
}
|
|
30513
30839
|
changeMatchType = newValue => {
|
|
30514
30840
|
const correct = {
|
|
@@ -30520,7 +30846,7 @@ class InteractiveGraphEditor extends React__namespace.Component {
|
|
|
30520
30846
|
});
|
|
30521
30847
|
};
|
|
30522
30848
|
serialize() {
|
|
30523
|
-
const json = ___default["default"].pick(this.props, "step", "backgroundImage", "markings", "labels", "showProtractor", "showRuler", "showTooltips", "rulerLabel", "rulerTicks", "range", "gridStep", "snapStep");
|
|
30849
|
+
const json = ___default["default"].pick(this.props, "step", "backgroundImage", "markings", "labels", "showProtractor", "showRuler", "showTooltips", "rulerLabel", "rulerTicks", "range", "gridStep", "snapStep", "lockedFigures");
|
|
30524
30850
|
|
|
30525
30851
|
// eslint-disable-next-line react/no-string-refs
|
|
30526
30852
|
const graph = this.refs.graph;
|
|
@@ -31296,47 +31622,6 @@ const styles$5 = aphrodite.StyleSheet.create({
|
|
|
31296
31622
|
}
|
|
31297
31623
|
});
|
|
31298
31624
|
|
|
31299
|
-
function focusWithChromeStickyFocusBugWorkaround(element) {
|
|
31300
|
-
// NOTE(marksandstrom) Chrome sticky focus bug.
|
|
31301
|
-
//
|
|
31302
|
-
// There is a bug in Chrome related to sticky positioning and
|
|
31303
|
-
// focus: When a child of an element with sticky positioning is
|
|
31304
|
-
// focused with the focus() method, the scrollable area
|
|
31305
|
-
// containing that element will scroll to the top (even though
|
|
31306
|
-
// the element is already visble on the page). For a dropdown
|
|
31307
|
-
// this means that the area will be scrolled to the top when
|
|
31308
|
-
// the user interacts with the dropdown (since we actively
|
|
31309
|
-
// manage dropdown header and option focus for keyboard users).
|
|
31310
|
-
//
|
|
31311
|
-
// To work around this bug the `preventScroll` focus option is
|
|
31312
|
-
// used.
|
|
31313
|
-
//
|
|
31314
|
-
// Using `focusOptions` is an experimental browser feature
|
|
31315
|
-
// "that should not be used in production code". However, since
|
|
31316
|
-
// Chrome is the only browser we support that exhibits this
|
|
31317
|
-
// buggy behavior and using `focusOptions` works around the
|
|
31318
|
-
// bug, it is perfectly reasonable to use the feature in this
|
|
31319
|
-
// case. We are not relying on the effect of the
|
|
31320
|
-
// `preventScroll` option otherwise.
|
|
31321
|
-
//
|
|
31322
|
-
// focusOptions documentation:
|
|
31323
|
-
//
|
|
31324
|
-
// https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/focus
|
|
31325
|
-
//
|
|
31326
|
-
// Note that there could be cases where we want default focus() behavior.
|
|
31327
|
-
// One that comes to mind is a dropdown with a long list of options that
|
|
31328
|
-
// might be rendered off screen when opened. With this workaround the
|
|
31329
|
-
// selected option would not be scrolled into view if the option is near
|
|
31330
|
-
// the end of the list. We're not aware of any uses of the dropdown where
|
|
31331
|
-
// this is an issue, however, so there isn't currently a way to out of the
|
|
31332
|
-
// `preventScroll` behavior.
|
|
31333
|
-
|
|
31334
|
-
// @ts-expect-error - TS2339 - Property 'focus' does not exist on type 'Element'.
|
|
31335
|
-
element.focus({
|
|
31336
|
-
preventScroll: true
|
|
31337
|
-
});
|
|
31338
|
-
}
|
|
31339
|
-
|
|
31340
31625
|
/* eslint-disable @khanacademy/ts-no-error-suppressions */
|
|
31341
31626
|
const {
|
|
31342
31627
|
Icon
|