@khanacademy/perseus-editor 6.10.0 → 6.12.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/components/{coordinate-pair-input.d.ts → graph-locked-figures/coordinate-pair-input.d.ts} +2 -0
- package/dist/components/{defining-point-settings.d.ts → graph-locked-figures/defining-point-settings.d.ts} +9 -2
- package/dist/components/{ellipse-swatch.d.ts → graph-locked-figures/ellipse-swatch.d.ts} +2 -2
- package/dist/components/{locked-ellipse-settings.d.ts → graph-locked-figures/locked-ellipse-settings.d.ts} +2 -6
- package/dist/components/{locked-figure-select.d.ts → graph-locked-figures/locked-figure-select.d.ts} +1 -0
- package/dist/components/graph-locked-figures/locked-figure-settings-actions.d.ts +11 -0
- package/dist/components/{locked-figure-settings.d.ts → graph-locked-figures/locked-figure-settings.d.ts} +13 -2
- package/dist/components/{locked-figures-section.d.ts → graph-locked-figures/locked-figures-section.d.ts} +2 -1
- package/dist/components/{locked-line-settings.d.ts → graph-locked-figures/locked-line-settings.d.ts} +2 -6
- package/dist/components/{locked-point-settings.d.ts → graph-locked-figures/locked-point-settings.d.ts} +2 -6
- package/dist/components/graph-locked-figures/locked-polygon-settings.d.ts +11 -0
- package/dist/components/{locked-vector-settings.d.ts → graph-locked-figures/locked-vector-settings.d.ts} +2 -6
- package/dist/components/graph-locked-figures/polygon-swatch.d.ts +9 -0
- package/dist/components/util.d.ts +5 -2
- package/dist/es/index.js +2000 -1701
- package/dist/es/index.js.map +1 -1
- package/dist/index.js +2051 -1746
- package/dist/index.js.map +1 -1
- package/dist/widgets/interactive-graph-editor.d.ts +402 -233
- package/package.json +2 -2
- package/dist/components/locked-figure-settings-actions.d.ts +0 -7
- /package/dist/components/{color-select.d.ts → graph-locked-figures/color-select.d.ts} +0 -0
- /package/dist/components/{color-swatch.d.ts → graph-locked-figures/color-swatch.d.ts} +0 -0
- /package/dist/components/{labeled-row.d.ts → graph-locked-figures/labeled-row.d.ts} +0 -0
- /package/dist/components/{labeled-switch.d.ts → graph-locked-figures/labeled-switch.d.ts} +0 -0
- /package/dist/components/{line-swatch.d.ts → graph-locked-figures/line-swatch.d.ts} +0 -0
- /package/dist/components/{locked-figure-settings-accordion.d.ts → graph-locked-figures/locked-figure-settings-accordion.d.ts} +0 -0
package/dist/index.js
CHANGED
|
@@ -24,11 +24,18 @@ var mathInput = require('@khanacademy/math-input');
|
|
|
24
24
|
var wonderBlocksDropdown = require('@khanacademy/wonder-blocks-dropdown');
|
|
25
25
|
var wonderBlocksForm = require('@khanacademy/wonder-blocks-form');
|
|
26
26
|
var wonderBlocksTypography = require('@khanacademy/wonder-blocks-typography');
|
|
27
|
-
var Banner = require('@khanacademy/wonder-blocks-banner');
|
|
28
27
|
var Button = require('@khanacademy/wonder-blocks-button');
|
|
29
|
-
var Switch = require('@khanacademy/wonder-blocks-switch');
|
|
30
28
|
var wonderBlocksAccordion = require('@khanacademy/wonder-blocks-accordion');
|
|
29
|
+
var IconButton = require('@khanacademy/wonder-blocks-icon-button');
|
|
30
|
+
var caretDoubleDownIcon = require('@phosphor-icons/core/bold/caret-double-down-bold.svg');
|
|
31
|
+
var caretDoubleUpIcon = require('@phosphor-icons/core/bold/caret-double-up-bold.svg');
|
|
32
|
+
var caretDownIcon = require('@phosphor-icons/core/bold/caret-down-bold.svg');
|
|
33
|
+
var caretUpIcon = require('@phosphor-icons/core/bold/caret-up-bold.svg');
|
|
31
34
|
var trashIcon = require('@phosphor-icons/core/bold/trash-bold.svg');
|
|
35
|
+
var Switch = require('@khanacademy/wonder-blocks-switch');
|
|
36
|
+
var minusCircle = require('@phosphor-icons/core/regular/minus-circle.svg');
|
|
37
|
+
var plusCircle = require('@phosphor-icons/core/regular/plus-circle.svg');
|
|
38
|
+
var Banner = require('@khanacademy/wonder-blocks-banner');
|
|
32
39
|
|
|
33
40
|
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
|
|
34
41
|
|
|
@@ -60,14 +67,21 @@ var caretRight__default = /*#__PURE__*/_interopDefaultLegacy(caretRight);
|
|
|
60
67
|
var classNames__default = /*#__PURE__*/_interopDefaultLegacy(classNames);
|
|
61
68
|
var ReactDOM__default = /*#__PURE__*/_interopDefaultLegacy(ReactDOM);
|
|
62
69
|
var KAS__namespace = /*#__PURE__*/_interopNamespace(KAS);
|
|
63
|
-
var Banner__default = /*#__PURE__*/_interopDefaultLegacy(Banner);
|
|
64
70
|
var Button__default = /*#__PURE__*/_interopDefaultLegacy(Button);
|
|
65
|
-
var
|
|
71
|
+
var IconButton__default = /*#__PURE__*/_interopDefaultLegacy(IconButton);
|
|
72
|
+
var caretDoubleDownIcon__default = /*#__PURE__*/_interopDefaultLegacy(caretDoubleDownIcon);
|
|
73
|
+
var caretDoubleUpIcon__default = /*#__PURE__*/_interopDefaultLegacy(caretDoubleUpIcon);
|
|
74
|
+
var caretDownIcon__default = /*#__PURE__*/_interopDefaultLegacy(caretDownIcon);
|
|
75
|
+
var caretUpIcon__default = /*#__PURE__*/_interopDefaultLegacy(caretUpIcon);
|
|
66
76
|
var trashIcon__default = /*#__PURE__*/_interopDefaultLegacy(trashIcon);
|
|
77
|
+
var Switch__default = /*#__PURE__*/_interopDefaultLegacy(Switch);
|
|
78
|
+
var minusCircle__default = /*#__PURE__*/_interopDefaultLegacy(minusCircle);
|
|
79
|
+
var plusCircle__default = /*#__PURE__*/_interopDefaultLegacy(plusCircle);
|
|
80
|
+
var Banner__default = /*#__PURE__*/_interopDefaultLegacy(Banner);
|
|
67
81
|
|
|
68
82
|
// This file is processed by a Rollup plugin (replace) to inject the production
|
|
69
83
|
const libName = "@khanacademy/perseus-editor";
|
|
70
|
-
const libVersion = "6.
|
|
84
|
+
const libVersion = "6.12.0";
|
|
71
85
|
perseusCore.addLibraryVersionToPerseusDebug(libName, libVersion);
|
|
72
86
|
|
|
73
87
|
function _extends() {
|
|
@@ -262,13 +276,13 @@ class SectionControlButton extends React__namespace.Component {
|
|
|
262
276
|
role: "button",
|
|
263
277
|
hideDefaultFocusRing: true,
|
|
264
278
|
"aria-label": title,
|
|
265
|
-
style: styles$
|
|
279
|
+
style: styles$G.button
|
|
266
280
|
}, _ref => {
|
|
267
281
|
return /*#__PURE__*/React__namespace.createElement(InlineIcon$b, icon);
|
|
268
282
|
});
|
|
269
283
|
}
|
|
270
284
|
}
|
|
271
|
-
const styles$
|
|
285
|
+
const styles$G = aphrodite.StyleSheet.create({
|
|
272
286
|
button: {
|
|
273
287
|
backgroundColor: wonderBlocksTokens.color.gold,
|
|
274
288
|
margin: 2,
|
|
@@ -20773,13 +20787,13 @@ class WidgetSelect extends React__namespace.Component {
|
|
|
20773
20787
|
* that collapse a region.
|
|
20774
20788
|
*/
|
|
20775
20789
|
function ToggleableCaret(props) {
|
|
20776
|
-
const iconStyle = props.isExpanded ? styles$
|
|
20790
|
+
const iconStyle = props.isExpanded ? styles$F.expanded : styles$F.collapsed;
|
|
20777
20791
|
return /*#__PURE__*/React__namespace.createElement(wonderBlocksIcon.PhosphorIcon, {
|
|
20778
20792
|
icon: caretRight__default["default"],
|
|
20779
20793
|
style: iconStyle
|
|
20780
20794
|
});
|
|
20781
20795
|
}
|
|
20782
|
-
const styles$
|
|
20796
|
+
const styles$F = aphrodite.StyleSheet.create({
|
|
20783
20797
|
collapsed: {
|
|
20784
20798
|
transition: ".15s"
|
|
20785
20799
|
},
|
|
@@ -20809,16 +20823,16 @@ class TexErrorView extends React__namespace.Component {
|
|
|
20809
20823
|
showErrors
|
|
20810
20824
|
} = this.state;
|
|
20811
20825
|
return /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, {
|
|
20812
|
-
style: styles$
|
|
20826
|
+
style: styles$E.errorContainer
|
|
20813
20827
|
}, /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, {
|
|
20814
|
-
style: styles$
|
|
20828
|
+
style: styles$E.title,
|
|
20815
20829
|
onClick: this.handleToggleTexErrors
|
|
20816
20830
|
}, /*#__PURE__*/React__namespace.createElement(ToggleableCaret, {
|
|
20817
20831
|
isExpanded: showErrors
|
|
20818
20832
|
}), "\xA0 TeX Errors (", errorList.length, ")"), showErrors && /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, {
|
|
20819
|
-
style: styles$
|
|
20833
|
+
style: styles$E.errorExplanation
|
|
20820
20834
|
}, "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, {
|
|
20821
|
-
style: styles$
|
|
20835
|
+
style: styles$E.error,
|
|
20822
20836
|
key: index
|
|
20823
20837
|
}, /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, {
|
|
20824
20838
|
style: {
|
|
@@ -20827,7 +20841,7 @@ class TexErrorView extends React__namespace.Component {
|
|
|
20827
20841
|
}, e.math), /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, null, e.message))));
|
|
20828
20842
|
}
|
|
20829
20843
|
}
|
|
20830
|
-
const styles$
|
|
20844
|
+
const styles$E = aphrodite.StyleSheet.create({
|
|
20831
20845
|
title: {
|
|
20832
20846
|
backgroundColor: "#eee",
|
|
20833
20847
|
fontSize: "1.25em",
|
|
@@ -23464,7 +23478,7 @@ class StructuredItemDiff extends React__namespace.Component {
|
|
|
23464
23478
|
|
|
23465
23479
|
/* eslint-disable @khanacademy/ts-no-error-suppressions */
|
|
23466
23480
|
const {
|
|
23467
|
-
InfoTip: InfoTip$
|
|
23481
|
+
InfoTip: InfoTip$m,
|
|
23468
23482
|
InlineIcon: InlineIcon$7
|
|
23469
23483
|
} = perseus.components;
|
|
23470
23484
|
const {
|
|
@@ -23538,7 +23552,7 @@ class HintEditor extends React__namespace.Component {
|
|
|
23538
23552
|
type: "button",
|
|
23539
23553
|
className: this.props.isFirst ? "hidden" : "",
|
|
23540
23554
|
onClick: ___default["default"].partial(this.props.onMove, -1)
|
|
23541
|
-
}, /*#__PURE__*/React__namespace.createElement(InlineIcon$7, iconCircleArrowUp)), " ", this.props.isLast && /*#__PURE__*/React__namespace.createElement(InfoTip$
|
|
23555
|
+
}, /*#__PURE__*/React__namespace.createElement(InlineIcon$7, iconCircleArrowUp)), " ", this.props.isLast && /*#__PURE__*/React__namespace.createElement(InfoTip$m, null, /*#__PURE__*/React__namespace.createElement("p", null, "The last hint is automatically bolded."))), /*#__PURE__*/React__namespace.createElement("input", {
|
|
23542
23556
|
type: "checkbox"
|
|
23543
23557
|
// @ts-expect-error - TS2322 - Type 'boolean | null | undefined' is not assignable to type 'boolean | undefined'.
|
|
23544
23558
|
,
|
|
@@ -23773,7 +23787,7 @@ class CombinedHintsEditor extends React__namespace.Component {
|
|
|
23773
23787
|
}
|
|
23774
23788
|
|
|
23775
23789
|
const {
|
|
23776
|
-
InfoTip: InfoTip$
|
|
23790
|
+
InfoTip: InfoTip$l
|
|
23777
23791
|
} = perseus.components;
|
|
23778
23792
|
class ItemExtrasEditor extends React__namespace.Component {
|
|
23779
23793
|
static defaultProps = {
|
|
@@ -23918,7 +23932,7 @@ const ItemExtraCheckbox = props => /*#__PURE__*/React__namespace.createElement("
|
|
|
23918
23932
|
type: "checkbox",
|
|
23919
23933
|
checked: props.checked,
|
|
23920
23934
|
onChange: props.onChange
|
|
23921
|
-
})), /*#__PURE__*/React__namespace.createElement(InfoTip$
|
|
23935
|
+
})), /*#__PURE__*/React__namespace.createElement(InfoTip$l, null, props.infoTip));
|
|
23922
23936
|
|
|
23923
23937
|
const ITEM_DATA_VERSION = perseus.itemDataVersion;
|
|
23924
23938
|
class ItemEditor extends React__namespace.Component {
|
|
@@ -24577,12 +24591,12 @@ class SimpleButton extends React__namespace.Component {
|
|
|
24577
24591
|
...otherProps
|
|
24578
24592
|
} = this.props;
|
|
24579
24593
|
return /*#__PURE__*/React__namespace.createElement("div", _extends({
|
|
24580
|
-
className: aphrodite.css(styles$
|
|
24594
|
+
className: aphrodite.css(styles$D.baseButton, color === "green" && styles$D.green, color === "orange" && styles$D.orange),
|
|
24581
24595
|
onClick: onClick
|
|
24582
24596
|
}, otherProps), children);
|
|
24583
24597
|
}
|
|
24584
24598
|
}
|
|
24585
|
-
const styles$
|
|
24599
|
+
const styles$D = aphrodite.StyleSheet.create({
|
|
24586
24600
|
baseButton: {
|
|
24587
24601
|
top: "0",
|
|
24588
24602
|
fontSize: "11px",
|
|
@@ -24795,23 +24809,23 @@ const LeafContainer = _ref2 => {
|
|
|
24795
24809
|
} = _ref2;
|
|
24796
24810
|
const hasPreviewHeading = shape.type === "content" || shape.type === "hint";
|
|
24797
24811
|
const previewHeading = hasPreviewHeading && /*#__PURE__*/React__namespace.createElement("div", {
|
|
24798
|
-
className: aphrodite.css(styles$
|
|
24812
|
+
className: aphrodite.css(styles$C.containerHeader)
|
|
24799
24813
|
}, /*#__PURE__*/React__namespace.createElement(Header, {
|
|
24800
24814
|
depth: path.length,
|
|
24801
|
-
className: aphrodite.css(styles$
|
|
24815
|
+
className: aphrodite.css(styles$C.containerTitle)
|
|
24802
24816
|
}, capitalize(name)));
|
|
24803
24817
|
return /*#__PURE__*/React__namespace.createElement("div", {
|
|
24804
|
-
className: aphrodite.css(styles$
|
|
24818
|
+
className: aphrodite.css(styles$C.container)
|
|
24805
24819
|
}, /*#__PURE__*/React__namespace.createElement("span", {
|
|
24806
|
-
className: aphrodite.css(styles$
|
|
24820
|
+
className: aphrodite.css(styles$C.row, styles$C.rowHeading)
|
|
24807
24821
|
}, /*#__PURE__*/React__namespace.createElement("div", {
|
|
24808
|
-
className: aphrodite.css(styles$
|
|
24822
|
+
className: aphrodite.css(styles$C.columnLeft)
|
|
24809
24823
|
}, /*#__PURE__*/React__namespace.createElement("div", {
|
|
24810
|
-
className: "pod-title " + aphrodite.css(styles$
|
|
24824
|
+
className: "pod-title " + aphrodite.css(styles$C.containerHeader)
|
|
24811
24825
|
}, /*#__PURE__*/React__namespace.createElement("div", {
|
|
24812
|
-
className: aphrodite.css(styles$
|
|
24826
|
+
className: aphrodite.css(styles$C.containerTitle)
|
|
24813
24827
|
}, capitalize(name)), controls)), /*#__PURE__*/React__namespace.createElement("div", {
|
|
24814
|
-
className: aphrodite.css(styles$
|
|
24828
|
+
className: aphrodite.css(styles$C.columnRight)
|
|
24815
24829
|
}, previewHeading)), children);
|
|
24816
24830
|
};
|
|
24817
24831
|
const ArrayContainer = props => {
|
|
@@ -24824,11 +24838,11 @@ const ArrayContainer = props => {
|
|
|
24824
24838
|
actions
|
|
24825
24839
|
} = props;
|
|
24826
24840
|
return /*#__PURE__*/React__namespace.createElement("div", {
|
|
24827
|
-
className: aphrodite.css(styles$
|
|
24841
|
+
className: aphrodite.css(styles$C.container)
|
|
24828
24842
|
}, controls && /*#__PURE__*/React__namespace.createElement("div", {
|
|
24829
|
-
className: aphrodite.css(styles$
|
|
24843
|
+
className: aphrodite.css(styles$C.columnLeft, styles$C.containerHeader)
|
|
24830
24844
|
}, controls), /*#__PURE__*/React__namespace.createElement("div", null, children), /*#__PURE__*/React__namespace.createElement("div", {
|
|
24831
|
-
className: aphrodite.css(styles$
|
|
24845
|
+
className: aphrodite.css(styles$C.columnLeft)
|
|
24832
24846
|
}, /*#__PURE__*/React__namespace.createElement("a", {
|
|
24833
24847
|
href: "javascript:void 0",
|
|
24834
24848
|
onClick: () => actions.addArrayElement(path, shape.elementShape)
|
|
@@ -24842,28 +24856,28 @@ const ObjectContainer = _ref3 => {
|
|
|
24842
24856
|
path
|
|
24843
24857
|
} = _ref3;
|
|
24844
24858
|
const headingEditor = /*#__PURE__*/React__namespace.createElement("div", {
|
|
24845
|
-
className: aphrodite.css(styles$
|
|
24859
|
+
className: aphrodite.css(styles$C.containerHeader)
|
|
24846
24860
|
}, /*#__PURE__*/React__namespace.createElement(Header, {
|
|
24847
24861
|
depth: path.length,
|
|
24848
|
-
className: aphrodite.css(styles$
|
|
24862
|
+
className: aphrodite.css(styles$C.containerTitle)
|
|
24849
24863
|
}, capitalize(name)), controls);
|
|
24850
24864
|
const headingPreview = (name || controls) && /*#__PURE__*/React__namespace.createElement("div", {
|
|
24851
|
-
className: aphrodite.css(styles$
|
|
24865
|
+
className: aphrodite.css(styles$C.containerHeader, styles$C.previewCollectionHeader)
|
|
24852
24866
|
}, /*#__PURE__*/React__namespace.createElement(Header, {
|
|
24853
24867
|
depth: path.length,
|
|
24854
|
-
className: aphrodite.css(styles$
|
|
24868
|
+
className: aphrodite.css(styles$C.containerTitle)
|
|
24855
24869
|
}, capitalize(name)));
|
|
24856
24870
|
const hasBothHeadings = headingEditor && headingPreview;
|
|
24857
24871
|
return /*#__PURE__*/React__namespace.createElement("div", {
|
|
24858
|
-
className: aphrodite.css(styles$
|
|
24872
|
+
className: aphrodite.css(styles$C.container)
|
|
24859
24873
|
}, hasBothHeadings && /*#__PURE__*/React__namespace.createElement("span", {
|
|
24860
|
-
className: aphrodite.css(styles$
|
|
24874
|
+
className: aphrodite.css(styles$C.row)
|
|
24861
24875
|
}, /*#__PURE__*/React__namespace.createElement("div", {
|
|
24862
|
-
className: aphrodite.css(styles$
|
|
24876
|
+
className: aphrodite.css(styles$C.columnLeft)
|
|
24863
24877
|
}, headingEditor), /*#__PURE__*/React__namespace.createElement("div", {
|
|
24864
|
-
className: aphrodite.css(styles$
|
|
24878
|
+
className: aphrodite.css(styles$C.columnRight)
|
|
24865
24879
|
}, headingPreview)), /*#__PURE__*/React__namespace.createElement("div", {
|
|
24866
|
-
className: aphrodite.css(path.length > 0 && styles$
|
|
24880
|
+
className: aphrodite.css(path.length > 0 && styles$C.contentIndent)
|
|
24867
24881
|
}, children));
|
|
24868
24882
|
};
|
|
24869
24883
|
|
|
@@ -24983,11 +24997,11 @@ const ItemNodeContent = withStickiness(props => {
|
|
|
24983
24997
|
className: "framework-perseus"
|
|
24984
24998
|
}, lens(renderers).get(path));
|
|
24985
24999
|
return /*#__PURE__*/React__namespace.createElement("span", null, /*#__PURE__*/React__namespace.createElement("div", {
|
|
24986
|
-
className: aphrodite.css(styles$
|
|
25000
|
+
className: aphrodite.css(styles$C.row)
|
|
24987
25001
|
}, /*#__PURE__*/React__namespace.createElement("div", {
|
|
24988
|
-
className: aphrodite.css(styles$
|
|
25002
|
+
className: aphrodite.css(styles$C.columnLeft)
|
|
24989
25003
|
}, /*#__PURE__*/React__namespace.createElement("div", {
|
|
24990
|
-
className: aphrodite.css(sticky && styles$
|
|
25004
|
+
className: aphrodite.css(sticky && styles$C.sticky)
|
|
24991
25005
|
},
|
|
24992
25006
|
/*#__PURE__*/
|
|
24993
25007
|
// @ts-expect-error - TS2769 - No overload matches this call.
|
|
@@ -24995,9 +25009,9 @@ const ItemNodeContent = withStickiness(props => {
|
|
|
24995
25009
|
onChange: newVal => actions.mergeValueAtPath(path, newVal),
|
|
24996
25010
|
apiOptions: apiOptions
|
|
24997
25011
|
})))), /*#__PURE__*/React__namespace.createElement("div", {
|
|
24998
|
-
className: aphrodite.css(styles$
|
|
25012
|
+
className: aphrodite.css(styles$C.columnRight)
|
|
24999
25013
|
}, /*#__PURE__*/React__namespace.createElement("div", {
|
|
25000
|
-
className: aphrodite.css(sticky && styles$
|
|
25014
|
+
className: aphrodite.css(sticky && styles$C.sticky)
|
|
25001
25015
|
}, preview))));
|
|
25002
25016
|
});
|
|
25003
25017
|
const HintNodeContent = withStickiness(props => {
|
|
@@ -25013,13 +25027,13 @@ const HintNodeContent = withStickiness(props => {
|
|
|
25013
25027
|
className: "framework-perseus"
|
|
25014
25028
|
}, lens(renderers).get(path));
|
|
25015
25029
|
return /*#__PURE__*/React__namespace.createElement("div", {
|
|
25016
|
-
className: aphrodite.css(styles$
|
|
25030
|
+
className: aphrodite.css(styles$C.row)
|
|
25017
25031
|
}, /*#__PURE__*/React__namespace.createElement("div", {
|
|
25018
|
-
className: aphrodite.css(styles$
|
|
25032
|
+
className: aphrodite.css(styles$C.columnLeft)
|
|
25019
25033
|
}, /*#__PURE__*/React__namespace.createElement("div", {
|
|
25020
|
-
className: aphrodite.css(sticky && styles$
|
|
25034
|
+
className: aphrodite.css(sticky && styles$C.sticky)
|
|
25021
25035
|
}, /*#__PURE__*/React__namespace.createElement(HintEditor, _extends({}, data, {
|
|
25022
|
-
className: aphrodite.css(styles$
|
|
25036
|
+
className: aphrodite.css(styles$C.hintEditor),
|
|
25023
25037
|
onChange: newVal => actions.mergeValueAtPath(path, newVal),
|
|
25024
25038
|
apiOptions: apiOptions,
|
|
25025
25039
|
showTitle: false,
|
|
@@ -25034,9 +25048,9 @@ const HintNodeContent = withStickiness(props => {
|
|
|
25034
25048
|
isFirst: true,
|
|
25035
25049
|
isLast: true
|
|
25036
25050
|
})))), /*#__PURE__*/React__namespace.createElement("div", {
|
|
25037
|
-
className: aphrodite.css(styles$
|
|
25051
|
+
className: aphrodite.css(styles$C.columnRight)
|
|
25038
25052
|
}, /*#__PURE__*/React__namespace.createElement("div", {
|
|
25039
|
-
className: aphrodite.css(sticky && styles$
|
|
25053
|
+
className: aphrodite.css(sticky && styles$C.sticky)
|
|
25040
25054
|
}, preview)));
|
|
25041
25055
|
});
|
|
25042
25056
|
const TagsNodeContent = props => {
|
|
@@ -25053,9 +25067,9 @@ const TagsNodeContent = props => {
|
|
|
25053
25067
|
return null;
|
|
25054
25068
|
}
|
|
25055
25069
|
return /*#__PURE__*/React__namespace.createElement("div", {
|
|
25056
|
-
className: aphrodite.css(styles$
|
|
25070
|
+
className: aphrodite.css(styles$C.columnLeft)
|
|
25057
25071
|
}, /*#__PURE__*/React__namespace.createElement("div", {
|
|
25058
|
-
className: aphrodite.css(styles$
|
|
25072
|
+
className: aphrodite.css(styles$C.tagsEditor)
|
|
25059
25073
|
}, /*#__PURE__*/React__namespace.createElement(GroupMetadataEditor, {
|
|
25060
25074
|
value: data,
|
|
25061
25075
|
onChange: newVal => actions.setValueAtPath(path, newVal),
|
|
@@ -25086,23 +25100,23 @@ const ArrayNodeContent = props => {
|
|
|
25086
25100
|
const subpath = path.concat(i);
|
|
25087
25101
|
const controls = [i > 0 && /*#__PURE__*/React__namespace.createElement("div", {
|
|
25088
25102
|
key: "moveArrayElementUp",
|
|
25089
|
-
className: aphrodite.css(styles$
|
|
25103
|
+
className: aphrodite.css(styles$C.control)
|
|
25090
25104
|
}, /*#__PURE__*/React__namespace.createElement(SimpleButton, {
|
|
25091
25105
|
color: "orange",
|
|
25092
25106
|
title: "Move up",
|
|
25093
25107
|
onClick: () => actions.moveArrayElementUp(subpath)
|
|
25094
25108
|
}, /*#__PURE__*/React__namespace.createElement("div", {
|
|
25095
|
-
className: aphrodite.css(styles$
|
|
25109
|
+
className: aphrodite.css(styles$C.verticalFlip)
|
|
25096
25110
|
}, /*#__PURE__*/React__namespace.createElement(InlineIcon$6, iconChevronDown)))), i < data.length - 1 && /*#__PURE__*/React__namespace.createElement("div", {
|
|
25097
25111
|
key: "moveArrayElementDown",
|
|
25098
|
-
className: aphrodite.css(styles$
|
|
25112
|
+
className: aphrodite.css(styles$C.control)
|
|
25099
25113
|
}, /*#__PURE__*/React__namespace.createElement(SimpleButton, {
|
|
25100
25114
|
color: "orange",
|
|
25101
25115
|
title: "Move down",
|
|
25102
25116
|
onClick: () => actions.moveArrayElementDown(subpath)
|
|
25103
25117
|
}, /*#__PURE__*/React__namespace.createElement(InlineIcon$6, iconChevronDown))), /*#__PURE__*/React__namespace.createElement("div", {
|
|
25104
25118
|
key: "removeArrayElement",
|
|
25105
|
-
className: aphrodite.css(styles$
|
|
25119
|
+
className: aphrodite.css(styles$C.control)
|
|
25106
25120
|
}, /*#__PURE__*/React__namespace.createElement(SimpleButton, {
|
|
25107
25121
|
color: "orange",
|
|
25108
25122
|
title: "Delete",
|
|
@@ -25110,7 +25124,7 @@ const ArrayNodeContent = props => {
|
|
|
25110
25124
|
}, /*#__PURE__*/React__namespace.createElement(InlineIcon$6, iconTrash$4)))];
|
|
25111
25125
|
return /*#__PURE__*/React__namespace.createElement("div", {
|
|
25112
25126
|
key: i,
|
|
25113
|
-
className: aphrodite.css(styles$
|
|
25127
|
+
className: aphrodite.css(styles$C.arrayElement, !elementIsLeaf && styles$C.arrayElementAndNotLeaf)
|
|
25114
25128
|
}, /*#__PURE__*/React__namespace.createElement(NodeContainer, _extends({}, otherProps, {
|
|
25115
25129
|
key: i,
|
|
25116
25130
|
shape: shape.elementShape,
|
|
@@ -25136,7 +25150,7 @@ const ObjectNodeContent = props => {
|
|
|
25136
25150
|
// made sense to the shape's author is the order in which we'll iterate :)
|
|
25137
25151
|
const children = Object.keys(shape.shape).map(subkey => /*#__PURE__*/React__namespace.createElement("div", {
|
|
25138
25152
|
key: subkey,
|
|
25139
|
-
className: aphrodite.css(styles$
|
|
25153
|
+
className: aphrodite.css(styles$C.objectElement)
|
|
25140
25154
|
}, /*#__PURE__*/React__namespace.createElement(NodeContainer, _extends({}, otherProps, {
|
|
25141
25155
|
shape: shape.shape[subkey],
|
|
25142
25156
|
data: data[subkey],
|
|
@@ -25306,7 +25320,7 @@ class MultiRendererEditor extends React__namespace.Component {
|
|
|
25306
25320
|
}, this._renderContent());
|
|
25307
25321
|
}
|
|
25308
25322
|
}
|
|
25309
|
-
const styles$
|
|
25323
|
+
const styles$C = aphrodite.StyleSheet.create({
|
|
25310
25324
|
// This is used in a number of places throughout this file.
|
|
25311
25325
|
container: {},
|
|
25312
25326
|
// eslint-disable-next-line react-native/no-unused-styles
|
|
@@ -25458,47 +25472,47 @@ const StatefulArticleEditor = createReactClass__default["default"]({
|
|
|
25458
25472
|
screen
|
|
25459
25473
|
} = this.state;
|
|
25460
25474
|
return /*#__PURE__*/React__namespace.createElement("div", null, /*#__PURE__*/React__namespace.createElement("div", {
|
|
25461
|
-
style: styles$
|
|
25475
|
+
style: styles$B.controlBar
|
|
25462
25476
|
}, /*#__PURE__*/React__namespace.createElement("span", {
|
|
25463
|
-
style: styles$
|
|
25477
|
+
style: styles$B.controls
|
|
25464
25478
|
}, "Mode:", " ", /*#__PURE__*/React__namespace.createElement("span", {
|
|
25465
25479
|
onClick: () => this.setState({
|
|
25466
25480
|
mode: "edit"
|
|
25467
25481
|
}),
|
|
25468
|
-
style: mode === "edit" ? styles$
|
|
25482
|
+
style: mode === "edit" ? styles$B.controlSelected : styles$B.control
|
|
25469
25483
|
}, "EDIT"), " | ", /*#__PURE__*/React__namespace.createElement("span", {
|
|
25470
25484
|
onClick: () => this.setState({
|
|
25471
25485
|
mode: "preview"
|
|
25472
25486
|
}),
|
|
25473
|
-
style: mode === "preview" ? styles$
|
|
25487
|
+
style: mode === "preview" ? styles$B.controlSelected : styles$B.control
|
|
25474
25488
|
}, "PREVIEW"), " | ", /*#__PURE__*/React__namespace.createElement("span", {
|
|
25475
25489
|
onClick: () => this.setState({
|
|
25476
25490
|
mode: "json"
|
|
25477
25491
|
}),
|
|
25478
|
-
style: mode === "json" ? styles$
|
|
25492
|
+
style: mode === "json" ? styles$B.controlSelected : styles$B.control
|
|
25479
25493
|
}, "JSON")), /*#__PURE__*/React__namespace.createElement("span", {
|
|
25480
|
-
style: styles$
|
|
25494
|
+
style: styles$B.controls
|
|
25481
25495
|
}, "Screen:", " ", /*#__PURE__*/React__namespace.createElement("span", {
|
|
25482
25496
|
onClick: () => this.setState({
|
|
25483
25497
|
screen: "phone"
|
|
25484
25498
|
}),
|
|
25485
|
-
style: screen === "phone" ? styles$
|
|
25499
|
+
style: screen === "phone" ? styles$B.controlSelected : styles$B.control
|
|
25486
25500
|
}, "PHONE"), " | ", /*#__PURE__*/React__namespace.createElement("span", {
|
|
25487
25501
|
onClick: () => this.setState({
|
|
25488
25502
|
screen: "tablet"
|
|
25489
25503
|
}),
|
|
25490
|
-
style: screen === "tablet" ? styles$
|
|
25504
|
+
style: screen === "tablet" ? styles$B.controlSelected : styles$B.control
|
|
25491
25505
|
}, "TABLET"), " | ", /*#__PURE__*/React__namespace.createElement("span", {
|
|
25492
25506
|
onClick: () => this.setState({
|
|
25493
25507
|
screen: "desktop"
|
|
25494
25508
|
}),
|
|
25495
|
-
style: screen === "desktop" ? styles$
|
|
25509
|
+
style: screen === "desktop" ? styles$B.controlSelected : styles$B.control
|
|
25496
25510
|
}, "DESKTOP"))), /*#__PURE__*/React__namespace.createElement("div", {
|
|
25497
|
-
style: styles$
|
|
25511
|
+
style: styles$B.editor
|
|
25498
25512
|
}, /*#__PURE__*/React__namespace.createElement(ArticleEditor, this.state)));
|
|
25499
25513
|
}
|
|
25500
25514
|
});
|
|
25501
|
-
const styles$
|
|
25515
|
+
const styles$B = {
|
|
25502
25516
|
controlBar: {
|
|
25503
25517
|
marginBottom: 25,
|
|
25504
25518
|
marginTop: 5
|
|
@@ -25713,7 +25727,7 @@ class BlurInput extends React__namespace.Component {
|
|
|
25713
25727
|
|
|
25714
25728
|
/* eslint-disable no-useless-escape */
|
|
25715
25729
|
const {
|
|
25716
|
-
InfoTip: InfoTip$
|
|
25730
|
+
InfoTip: InfoTip$k,
|
|
25717
25731
|
PropCheckBox: PropCheckBox$b
|
|
25718
25732
|
} = perseus.components;
|
|
25719
25733
|
const DEFAULT_WIDTH = 400;
|
|
@@ -25901,7 +25915,7 @@ class CSProgramEditor extends React__namespace.Component {
|
|
|
25901
25915
|
label: "Show Editor",
|
|
25902
25916
|
showEditor: this.props.showEditor,
|
|
25903
25917
|
onChange: this.props.onChange
|
|
25904
|
-
}), /*#__PURE__*/React__namespace.createElement(InfoTip$
|
|
25918
|
+
}), /*#__PURE__*/React__namespace.createElement(InfoTip$k, null, "If you show the editor, you should use the \"full-width\" alignment to make room for the width of the editor."), /*#__PURE__*/React__namespace.createElement("br", null), /*#__PURE__*/React__namespace.createElement(PropCheckBox$b, {
|
|
25905
25919
|
label: "Show Buttons",
|
|
25906
25920
|
showButtons: this.props.showButtons,
|
|
25907
25921
|
onChange: this.props.onChange
|
|
@@ -25909,7 +25923,7 @@ class CSProgramEditor extends React__namespace.Component {
|
|
|
25909
25923
|
name: "settings",
|
|
25910
25924
|
pairs: this.props.settings,
|
|
25911
25925
|
onChange: this._handleSettingsChange
|
|
25912
|
-
}), /*#__PURE__*/React__namespace.createElement(InfoTip$
|
|
25926
|
+
}), /*#__PURE__*/React__namespace.createElement(InfoTip$k, null, "Settings that you add here are available to the program as an object returned by ", /*#__PURE__*/React__namespace.createElement("code", null, "Program.settings()"))));
|
|
25913
25927
|
}
|
|
25914
25928
|
}
|
|
25915
25929
|
|
|
@@ -25986,7 +26000,7 @@ class DeprecatedStandinEditor extends React__namespace.Component {
|
|
|
25986
26000
|
|
|
25987
26001
|
/* eslint-disable @khanacademy/ts-no-error-suppressions */
|
|
25988
26002
|
const {
|
|
25989
|
-
InfoTip: InfoTip$
|
|
26003
|
+
InfoTip: InfoTip$j,
|
|
25990
26004
|
InlineIcon: InlineIcon$5
|
|
25991
26005
|
} = perseus.components;
|
|
25992
26006
|
const {
|
|
@@ -26067,14 +26081,14 @@ class DropdownEditor extends React__namespace.Component {
|
|
|
26067
26081
|
className: "perseus-widget-dropdown"
|
|
26068
26082
|
}, /*#__PURE__*/React__namespace.createElement("div", {
|
|
26069
26083
|
className: "dropdown-info"
|
|
26070
|
-
}, "Dropdown", /*#__PURE__*/React__namespace.createElement(InfoTip$
|
|
26084
|
+
}, "Dropdown", /*#__PURE__*/React__namespace.createElement(InfoTip$j, null, /*#__PURE__*/React__namespace.createElement("p", null, "The drop down is useful for making inequalities in a custom format. We normally use the symbols ", "<", ",", " ", ">", ", \u2264, \u2265 (in that order) which you can copy into the choices. When possible, use the \"multiple choice\" answer type instead."))), /*#__PURE__*/React__namespace.createElement("div", {
|
|
26071
26085
|
className: "dropdown-placeholder"
|
|
26072
26086
|
}, /*#__PURE__*/React__namespace.createElement("input", {
|
|
26073
26087
|
type: "text",
|
|
26074
26088
|
placeholder: "Placeholder value",
|
|
26075
26089
|
value: this.props.placeholder,
|
|
26076
26090
|
onChange: this.onPlaceholderChange
|
|
26077
|
-
}), /*#__PURE__*/React__namespace.createElement(InfoTip$
|
|
26091
|
+
}), /*#__PURE__*/React__namespace.createElement(InfoTip$j, null, /*#__PURE__*/React__namespace.createElement("p", null, "This value will appear as the drop down default. It should give the user some indication of the values available in the drop down itself, e.g., Yes/No/Maybe."))), /*#__PURE__*/React__namespace.createElement("div", {
|
|
26078
26092
|
className: "clearfix"
|
|
26079
26093
|
}), /*#__PURE__*/React__namespace.createElement("ul", {
|
|
26080
26094
|
className: "dropdown-choices"
|
|
@@ -26608,7 +26622,7 @@ const SortableItem = createReactClass__default["default"]({
|
|
|
26608
26622
|
});
|
|
26609
26623
|
|
|
26610
26624
|
const {
|
|
26611
|
-
InfoTip: InfoTip$
|
|
26625
|
+
InfoTip: InfoTip$i,
|
|
26612
26626
|
PropCheckBox: PropCheckBox$a
|
|
26613
26627
|
} = perseus.components;
|
|
26614
26628
|
|
|
@@ -26734,11 +26748,11 @@ class ExpressionEditor extends React__namespace.Component {
|
|
|
26734
26748
|
onChange: this.props.onChange,
|
|
26735
26749
|
labelAlignment: "right",
|
|
26736
26750
|
label: "Use \xD7 for rendering multiplication instead of a center dot."
|
|
26737
|
-
}), /*#__PURE__*/React__namespace.createElement(InfoTip$
|
|
26751
|
+
}), /*#__PURE__*/React__namespace.createElement(InfoTip$i, null, /*#__PURE__*/React__namespace.createElement("p", null, "For pre-algebra problems this option displays multiplication as \\times instead of \\cdot in both the rendered output and the acceptable formats examples."))), /*#__PURE__*/React__namespace.createElement("div", null, /*#__PURE__*/React__namespace.createElement("label", null, "Function variables: ", /*#__PURE__*/React__namespace.createElement("input", {
|
|
26738
26752
|
type: "text",
|
|
26739
26753
|
defaultValue: this.props.functions.join(" "),
|
|
26740
26754
|
onChange: this.handleFunctions
|
|
26741
|
-
})), /*#__PURE__*/React__namespace.createElement(InfoTip$
|
|
26755
|
+
})), /*#__PURE__*/React__namespace.createElement(InfoTip$i, null, /*#__PURE__*/React__namespace.createElement("p", null, "Single-letter variables listed here will be interpreted as functions. This let us know that f(x) means \"f of x\" and not \"f times x\"."))), /*#__PURE__*/React__namespace.createElement("div", null, /*#__PURE__*/React__namespace.createElement("div", null, "Button sets:"), buttonSetChoices), /*#__PURE__*/React__namespace.createElement("h3", {
|
|
26742
26756
|
className: "expression-editor-h3"
|
|
26743
26757
|
}, "Answers"), /*#__PURE__*/React__namespace.createElement("p", {
|
|
26744
26758
|
style: {
|
|
@@ -26952,14 +26966,14 @@ class AnswerOption extends React__namespace.Component {
|
|
|
26952
26966
|
onChange: this.props.onChange,
|
|
26953
26967
|
labelAlignment: "right",
|
|
26954
26968
|
label: "Answer expression must have the same form."
|
|
26955
|
-
}), /*#__PURE__*/React__namespace.createElement(InfoTip$
|
|
26969
|
+
}), /*#__PURE__*/React__namespace.createElement(InfoTip$i, null, /*#__PURE__*/React__namespace.createElement("p", null, "The student's answer must be in the same form. Commutativity and excess negative signs are ignored."))), /*#__PURE__*/React__namespace.createElement("div", {
|
|
26956
26970
|
className: "answer-option"
|
|
26957
26971
|
}, /*#__PURE__*/React__namespace.createElement(PropCheckBox$a, {
|
|
26958
26972
|
simplify: this.props.simplify,
|
|
26959
26973
|
onChange: this.props.onChange,
|
|
26960
26974
|
labelAlignment: "right",
|
|
26961
26975
|
label: "Answer expression must be fully expanded and simplified."
|
|
26962
|
-
}), /*#__PURE__*/React__namespace.createElement(InfoTip$
|
|
26976
|
+
}), /*#__PURE__*/React__namespace.createElement(InfoTip$i, null, /*#__PURE__*/React__namespace.createElement("p", null, "The student's answer must be fully expanded and simplified. Answering this equation (x^2+2x+1) with this factored equation (x+1)^2 will render this response \"Your answer is not fully expanded and simplified.\""))), /*#__PURE__*/React__namespace.createElement("div", {
|
|
26963
26977
|
className: "remove-container"
|
|
26964
26978
|
}, removeButton)));
|
|
26965
26979
|
}
|
|
@@ -27037,10 +27051,10 @@ class GradedGroupEditor extends React__namespace.Component {
|
|
|
27037
27051
|
}, /*#__PURE__*/React__namespace.createElement("div", {
|
|
27038
27052
|
className: "perseus-widget-row"
|
|
27039
27053
|
}, /*#__PURE__*/React__namespace.createElement("label", {
|
|
27040
|
-
className: aphrodite.css(styles$
|
|
27054
|
+
className: aphrodite.css(styles$A.title)
|
|
27041
27055
|
}, "Title:", " ", /*#__PURE__*/React__namespace.createElement(TextInput$6, {
|
|
27042
27056
|
value: this.props.title,
|
|
27043
|
-
className: aphrodite.css(styles$
|
|
27057
|
+
className: aphrodite.css(styles$A.input)
|
|
27044
27058
|
// @ts-expect-error - TS2554 - Expected 3 arguments, but got 1.
|
|
27045
27059
|
,
|
|
27046
27060
|
onChange: this.change("title")
|
|
@@ -27065,7 +27079,7 @@ class GradedGroupEditor extends React__namespace.Component {
|
|
|
27065
27079
|
}, /*#__PURE__*/React__namespace.createElement(InlineIcon$4, iconPlus$1), " Add a hint"), this.props.hint && /*#__PURE__*/React__namespace.createElement("div", {
|
|
27066
27080
|
className: "perseus-hint-editor"
|
|
27067
27081
|
}, /*#__PURE__*/React__namespace.createElement("div", {
|
|
27068
|
-
className: aphrodite.css(styles$
|
|
27082
|
+
className: aphrodite.css(styles$A.hintsTitle)
|
|
27069
27083
|
}, "Hint"), /*#__PURE__*/React__namespace.createElement(Editor, {
|
|
27070
27084
|
ref: this.hintEditor,
|
|
27071
27085
|
content: this.props.hint ? this.props.hint.content : "",
|
|
@@ -27097,7 +27111,7 @@ class GradedGroupEditor extends React__namespace.Component {
|
|
|
27097
27111
|
};
|
|
27098
27112
|
};
|
|
27099
27113
|
}
|
|
27100
|
-
const styles$
|
|
27114
|
+
const styles$A = aphrodite.StyleSheet.create({
|
|
27101
27115
|
title: {
|
|
27102
27116
|
fontSize: 18,
|
|
27103
27117
|
fontWeight: "bold"
|
|
@@ -27184,7 +27198,7 @@ const setArrayItem = (list, i, value) => [...list.slice(0, i), value, ...list.sl
|
|
|
27184
27198
|
/* eslint-disable react/forbid-prop-types, react/no-unsafe */
|
|
27185
27199
|
const {
|
|
27186
27200
|
ButtonGroup: ButtonGroup$4,
|
|
27187
|
-
InfoTip: InfoTip$
|
|
27201
|
+
InfoTip: InfoTip$h,
|
|
27188
27202
|
PropCheckBox: PropCheckBox$9,
|
|
27189
27203
|
RangeInput: RangeInput$6
|
|
27190
27204
|
} = perseus.components;
|
|
@@ -27645,7 +27659,7 @@ const GraphSettings = createReactClass__default["default"]({
|
|
|
27645
27659
|
},
|
|
27646
27660
|
onKeyPress: this.changeBackgroundUrl,
|
|
27647
27661
|
onBlur: this.changeBackgroundUrl
|
|
27648
|
-
}), /*#__PURE__*/React__namespace.createElement(InfoTip$
|
|
27662
|
+
}), /*#__PURE__*/React__namespace.createElement(InfoTip$h, null, /*#__PURE__*/React__namespace.createElement("p", null, "Create an image in graphie, or use the \"Add image\" function to create a background.")))), ___default["default"].contains(this.props.editableSettings, "measure") && /*#__PURE__*/React__namespace.createElement("div", {
|
|
27649
27663
|
className: "misc-settings"
|
|
27650
27664
|
}, /*#__PURE__*/React__namespace.createElement("div", {
|
|
27651
27665
|
className: "perseus-widget-row"
|
|
@@ -27683,7 +27697,7 @@ const GraphSettings = createReactClass__default["default"]({
|
|
|
27683
27697
|
});
|
|
27684
27698
|
|
|
27685
27699
|
const {
|
|
27686
|
-
InfoTip: InfoTip$
|
|
27700
|
+
InfoTip: InfoTip$g,
|
|
27687
27701
|
MultiButtonGroup: MultiButtonGroup$1
|
|
27688
27702
|
} = perseus.components;
|
|
27689
27703
|
const {
|
|
@@ -27757,7 +27771,7 @@ class GrapherEditor extends React__namespace.Component {
|
|
|
27757
27771
|
className: "perseus-error"
|
|
27758
27772
|
}, this.props.graph.valid);
|
|
27759
27773
|
}
|
|
27760
|
-
return /*#__PURE__*/React__namespace.createElement("div", null, /*#__PURE__*/React__namespace.createElement("div", null, "Correct answer", " ", /*#__PURE__*/React__namespace.createElement(InfoTip$
|
|
27774
|
+
return /*#__PURE__*/React__namespace.createElement("div", null, /*#__PURE__*/React__namespace.createElement("div", null, "Correct answer", " ", /*#__PURE__*/React__namespace.createElement(InfoTip$g, 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.")), " ", ": ", equationString), /*#__PURE__*/React__namespace.createElement(GraphSettings, {
|
|
27761
27775
|
editableSettings: ["graph", "snap", "image"],
|
|
27762
27776
|
box: getInteractiveBoxFromSizeClass$1(sizeClass),
|
|
27763
27777
|
range: this.props.graph.range,
|
|
@@ -28032,7 +28046,7 @@ class IframeEditor extends React__namespace.Component {
|
|
|
28032
28046
|
|
|
28033
28047
|
/* eslint-disable jsx-a11y/anchor-is-valid, react/sort-comp */
|
|
28034
28048
|
const {
|
|
28035
|
-
InfoTip: InfoTip$
|
|
28049
|
+
InfoTip: InfoTip$f,
|
|
28036
28050
|
InlineIcon: InlineIcon$3,
|
|
28037
28051
|
RangeInput: RangeInput$5
|
|
28038
28052
|
} = perseus.components;
|
|
@@ -28089,7 +28103,7 @@ class ImageEditor extends React__namespace.Component {
|
|
|
28089
28103
|
style: {
|
|
28090
28104
|
width: "100%"
|
|
28091
28105
|
}
|
|
28092
|
-
}))), /*#__PURE__*/React__namespace.createElement("div", null, /*#__PURE__*/React__namespace.createElement("label", null, /*#__PURE__*/React__namespace.createElement("div", null, "Dimensions:"), /*#__PURE__*/React__namespace.createElement("p", null, backgroundImage.width, "x", backgroundImage.height))), /*#__PURE__*/React__namespace.createElement("div", null, /*#__PURE__*/React__namespace.createElement("label", null, /*#__PURE__*/React__namespace.createElement("div", null, "Alt text:", /*#__PURE__*/React__namespace.createElement(InfoTip$
|
|
28106
|
+
}))), /*#__PURE__*/React__namespace.createElement("div", null, /*#__PURE__*/React__namespace.createElement("label", null, /*#__PURE__*/React__namespace.createElement("div", null, "Dimensions:"), /*#__PURE__*/React__namespace.createElement("p", null, backgroundImage.width, "x", backgroundImage.height))), /*#__PURE__*/React__namespace.createElement("div", null, /*#__PURE__*/React__namespace.createElement("label", null, /*#__PURE__*/React__namespace.createElement("div", null, "Alt text:", /*#__PURE__*/React__namespace.createElement(InfoTip$f, null, "This is important for screenreaders. The content of this alt text will be formatted as markdown (tables, emphasis, etc. are supported).")), /*#__PURE__*/React__namespace.createElement(Editor, {
|
|
28093
28107
|
apiOptions: this.props.apiOptions,
|
|
28094
28108
|
content: this.props.alt,
|
|
28095
28109
|
onChange: props => {
|
|
@@ -28113,7 +28127,7 @@ class ImageEditor extends React__namespace.Component {
|
|
|
28113
28127
|
}, this.state.backgroundImageError);
|
|
28114
28128
|
return /*#__PURE__*/React__namespace.createElement("div", {
|
|
28115
28129
|
className: "perseus-image-editor"
|
|
28116
|
-
}, /*#__PURE__*/React__namespace.createElement("label", null, "Image url:", /*#__PURE__*/React__namespace.createElement(InfoTip$
|
|
28130
|
+
}, /*#__PURE__*/React__namespace.createElement("label", null, "Image url:", /*#__PURE__*/React__namespace.createElement(InfoTip$f, null, "Paste an image or graphie image URL."), this.state.backgroundImageError && backgroundImageErrorText, /*#__PURE__*/React__namespace.createElement(BlurInput, {
|
|
28117
28131
|
value: backgroundImage.url || "",
|
|
28118
28132
|
style: {
|
|
28119
28133
|
width: 332
|
|
@@ -28269,7 +28283,7 @@ class ImageEditor extends React__namespace.Component {
|
|
|
28269
28283
|
|
|
28270
28284
|
/* eslint-disable react/sort-comp */
|
|
28271
28285
|
const {
|
|
28272
|
-
InfoTip: InfoTip$
|
|
28286
|
+
InfoTip: InfoTip$e
|
|
28273
28287
|
} = perseus.components;
|
|
28274
28288
|
const answerTypes = {
|
|
28275
28289
|
number: {
|
|
@@ -28349,7 +28363,7 @@ class InputNumberEditor extends React__namespace.Component {
|
|
|
28349
28363
|
value: "optional"
|
|
28350
28364
|
}, "will be accepted"), /*#__PURE__*/React__namespace.createElement("option", {
|
|
28351
28365
|
value: "enforced"
|
|
28352
|
-
}, "will be marked wrong"))), /*#__PURE__*/React__namespace.createElement(InfoTip$
|
|
28366
|
+
}, "will be marked wrong"))), /*#__PURE__*/React__namespace.createElement(InfoTip$e, null, /*#__PURE__*/React__namespace.createElement("p", null, "Normally select \"will not be graded\". This will give the user a message saying the answer is correct but not simplified. The user will then have to simplify it and re-enter, but will not be penalized. (5th grade and anything after)"), /*#__PURE__*/React__namespace.createElement("p", null, "Select \"will be accepted\" only if the user is not expected to know how to simplify fractions yet. (Anything prior to 5th grade)"), /*#__PURE__*/React__namespace.createElement("p", null, "Select \"will be marked wrong\" only if we are specifically assessing the ability to simplify."))), /*#__PURE__*/React__namespace.createElement("div", null, /*#__PURE__*/React__namespace.createElement("label", null, /*#__PURE__*/React__namespace.createElement("input", {
|
|
28353
28367
|
type: "checkbox",
|
|
28354
28368
|
checked: this.props.inexact,
|
|
28355
28369
|
onChange: e => {
|
|
@@ -28385,7 +28399,7 @@ class InputNumberEditor extends React__namespace.Component {
|
|
|
28385
28399
|
});
|
|
28386
28400
|
},
|
|
28387
28401
|
"aria-label": "Answer type"
|
|
28388
|
-
}, answerTypeOptions), /*#__PURE__*/React__namespace.createElement(InfoTip$
|
|
28402
|
+
}, answerTypeOptions), /*#__PURE__*/React__namespace.createElement(InfoTip$e, null, /*#__PURE__*/React__namespace.createElement("p", null, "Use the default \"Numbers\" unless the answer must be in a specific form (e.g., question is about converting decimals to fractions)."))), /*#__PURE__*/React__namespace.createElement("div", null, /*#__PURE__*/React__namespace.createElement("label", null, "Width", " ", /*#__PURE__*/React__namespace.createElement("select", {
|
|
28389
28403
|
value: this.props.size,
|
|
28390
28404
|
onChange: e => {
|
|
28391
28405
|
// @ts-expect-error - TS2322 - Type 'string' is not assignable to type '"small" | "normal" | undefined'.
|
|
@@ -28397,7 +28411,7 @@ class InputNumberEditor extends React__namespace.Component {
|
|
|
28397
28411
|
value: "normal"
|
|
28398
28412
|
}, "Normal (80px)"), /*#__PURE__*/React__namespace.createElement("option", {
|
|
28399
28413
|
value: "small"
|
|
28400
|
-
}, "Small (40px)"))), /*#__PURE__*/React__namespace.createElement(InfoTip$
|
|
28414
|
+
}, "Small (40px)"))), /*#__PURE__*/React__namespace.createElement(InfoTip$e, null, /*#__PURE__*/React__namespace.createElement("p", null, "Use size \"Normal\" for all text boxes, unless there are multiple text boxes in one line and the answer area is too narrow to fit them."))), /*#__PURE__*/React__namespace.createElement("div", null, /*#__PURE__*/React__namespace.createElement("label", null, /*#__PURE__*/React__namespace.createElement("input", {
|
|
28401
28415
|
type: "checkbox",
|
|
28402
28416
|
checked: this.props.rightAlign,
|
|
28403
28417
|
onChange: e => {
|
|
@@ -28468,13 +28482,13 @@ function MathquillInput(props) {
|
|
|
28468
28482
|
}
|
|
28469
28483
|
});
|
|
28470
28484
|
return /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, {
|
|
28471
|
-
style: styles$
|
|
28485
|
+
style: styles$z.outerWrapper
|
|
28472
28486
|
}, /*#__PURE__*/React__namespace.createElement("span", {
|
|
28473
28487
|
ref: mathFieldWrapperRef,
|
|
28474
28488
|
className: "perseus-math-input mq-editable-field mq-math-mode"
|
|
28475
28489
|
}));
|
|
28476
28490
|
}
|
|
28477
|
-
const styles$
|
|
28491
|
+
const styles$z = aphrodite.StyleSheet.create({
|
|
28478
28492
|
outerWrapper: {
|
|
28479
28493
|
display: "inline-block",
|
|
28480
28494
|
borderStyle: "solid",
|
|
@@ -29535,96 +29549,6 @@ class InteractionEditor extends React__namespace.Component {
|
|
|
29535
29549
|
}
|
|
29536
29550
|
}
|
|
29537
29551
|
|
|
29538
|
-
const UNLIMITED = "unlimited";
|
|
29539
|
-
// Parses a string (ostensibly from some UI element that only supports string
|
|
29540
|
-
// types, such as a <select />) into a numeric point count or the special sigil
|
|
29541
|
-
// "unlimited". Note that 0 is a special case, and means "unlimited".
|
|
29542
|
-
const parsePointCount = points => {
|
|
29543
|
-
const parsed = parseInt(points, 10);
|
|
29544
|
-
if (isNaN(parsed)) {
|
|
29545
|
-
return UNLIMITED;
|
|
29546
|
-
}
|
|
29547
|
-
return parsed === 0 ? UNLIMITED : parsed;
|
|
29548
|
-
};
|
|
29549
|
-
|
|
29550
|
-
const GraphPointsCountSelector = _ref => {
|
|
29551
|
-
let {
|
|
29552
|
-
numPoints = 1,
|
|
29553
|
-
onChange
|
|
29554
|
-
} = _ref;
|
|
29555
|
-
return /*#__PURE__*/React__namespace.createElement(wonderBlocksDropdown.SingleSelect, {
|
|
29556
|
-
selectedValue: `${numPoints}`,
|
|
29557
|
-
onChange: newValue => {
|
|
29558
|
-
onChange(parsePointCount(newValue));
|
|
29559
|
-
}
|
|
29560
|
-
// Never uses placeholder, always has value
|
|
29561
|
-
,
|
|
29562
|
-
placeholder: "",
|
|
29563
|
-
style: styles$v.singleSelectShort
|
|
29564
|
-
}, [...[...Array(7).keys()].map(n => /*#__PURE__*/React__namespace.createElement(wonderBlocksDropdown.OptionItem, {
|
|
29565
|
-
key: n,
|
|
29566
|
-
value: `${n}`,
|
|
29567
|
-
label: `${n} point${n > 1 ? "s" : ""}`
|
|
29568
|
-
})), /*#__PURE__*/React__namespace.createElement(wonderBlocksDropdown.OptionItem, {
|
|
29569
|
-
key: "unlimited",
|
|
29570
|
-
value: UNLIMITED,
|
|
29571
|
-
label: "unlimited"
|
|
29572
|
-
})]);
|
|
29573
|
-
};
|
|
29574
|
-
const styles$v = aphrodite.StyleSheet.create({
|
|
29575
|
-
singleSelectShort: {
|
|
29576
|
-
// Non-standard spacing, but it's the smallest we can go
|
|
29577
|
-
// without running into styling issues with the dropdown.
|
|
29578
|
-
height: 26
|
|
29579
|
-
}
|
|
29580
|
-
});
|
|
29581
|
-
|
|
29582
|
-
const GraphTypeSelector = props => {
|
|
29583
|
-
return /*#__PURE__*/React__namespace.createElement(wonderBlocksDropdown.SingleSelect, {
|
|
29584
|
-
selectedValue: props.graphType,
|
|
29585
|
-
onChange: props.onChange,
|
|
29586
|
-
placeholder: "Select a graph type",
|
|
29587
|
-
style: styles$u.singleSelectShort
|
|
29588
|
-
}, /*#__PURE__*/React__namespace.createElement(wonderBlocksDropdown.OptionItem, {
|
|
29589
|
-
value: "linear",
|
|
29590
|
-
label: "Linear function"
|
|
29591
|
-
}), /*#__PURE__*/React__namespace.createElement(wonderBlocksDropdown.OptionItem, {
|
|
29592
|
-
value: "quadratic",
|
|
29593
|
-
label: "Quadratic function"
|
|
29594
|
-
}), /*#__PURE__*/React__namespace.createElement(wonderBlocksDropdown.OptionItem, {
|
|
29595
|
-
value: "sinusoid",
|
|
29596
|
-
label: "Sinusoid function"
|
|
29597
|
-
}), /*#__PURE__*/React__namespace.createElement(wonderBlocksDropdown.OptionItem, {
|
|
29598
|
-
value: "circle",
|
|
29599
|
-
label: "Circle"
|
|
29600
|
-
}), /*#__PURE__*/React__namespace.createElement(wonderBlocksDropdown.OptionItem, {
|
|
29601
|
-
value: "point",
|
|
29602
|
-
label: "Point(s)"
|
|
29603
|
-
}), /*#__PURE__*/React__namespace.createElement(wonderBlocksDropdown.OptionItem, {
|
|
29604
|
-
value: "linear-system",
|
|
29605
|
-
label: "Linear System"
|
|
29606
|
-
}), /*#__PURE__*/React__namespace.createElement(wonderBlocksDropdown.OptionItem, {
|
|
29607
|
-
value: "polygon",
|
|
29608
|
-
label: "Polygon"
|
|
29609
|
-
}), /*#__PURE__*/React__namespace.createElement(wonderBlocksDropdown.OptionItem, {
|
|
29610
|
-
value: "segment",
|
|
29611
|
-
label: "Line Segment(s)"
|
|
29612
|
-
}), /*#__PURE__*/React__namespace.createElement(wonderBlocksDropdown.OptionItem, {
|
|
29613
|
-
value: "ray",
|
|
29614
|
-
label: "Ray"
|
|
29615
|
-
}), /*#__PURE__*/React__namespace.createElement(wonderBlocksDropdown.OptionItem, {
|
|
29616
|
-
value: "angle",
|
|
29617
|
-
label: "Angle"
|
|
29618
|
-
}));
|
|
29619
|
-
};
|
|
29620
|
-
const styles$u = aphrodite.StyleSheet.create({
|
|
29621
|
-
singleSelectShort: {
|
|
29622
|
-
// Non-standard spacing, but it's the smallest we can go
|
|
29623
|
-
// without running into styling issues with the dropdown.
|
|
29624
|
-
height: 26
|
|
29625
|
-
}
|
|
29626
|
-
});
|
|
29627
|
-
|
|
29628
29552
|
// Renders the given children in a View laid out horizontally.
|
|
29629
29553
|
const LabeledRow = props => {
|
|
29630
29554
|
const {
|
|
@@ -29634,16 +29558,16 @@ const LabeledRow = props => {
|
|
|
29634
29558
|
style
|
|
29635
29559
|
} = props;
|
|
29636
29560
|
return /*#__PURE__*/React__namespace.createElement("label", {
|
|
29637
|
-
className: aphrodite.css(styles$
|
|
29561
|
+
className: aphrodite.css(styles$y.label)
|
|
29638
29562
|
}, /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, {
|
|
29639
|
-
style: [styles$
|
|
29563
|
+
style: [styles$y.row, style]
|
|
29640
29564
|
}, labelSide === "start" || /*#__PURE__*/React__namespace.createElement(wonderBlocksTypography.LabelSmall, {
|
|
29641
|
-
style: styles$
|
|
29565
|
+
style: styles$y.spaceEnd
|
|
29642
29566
|
}, label), children, labelSide === "end" && /*#__PURE__*/React__namespace.createElement(wonderBlocksTypography.LabelSmall, {
|
|
29643
|
-
style: styles$
|
|
29567
|
+
style: styles$y.spaceStart
|
|
29644
29568
|
}, label)));
|
|
29645
29569
|
};
|
|
29646
|
-
const styles$
|
|
29570
|
+
const styles$y = aphrodite.StyleSheet.create({
|
|
29647
29571
|
label: {
|
|
29648
29572
|
width: "fit-content"
|
|
29649
29573
|
},
|
|
@@ -29661,903 +29585,1044 @@ const styles$t = aphrodite.StyleSheet.create({
|
|
|
29661
29585
|
}
|
|
29662
29586
|
});
|
|
29663
29587
|
|
|
29664
|
-
|
|
29665
|
-
const {
|
|
29666
|
-
|
|
29667
|
-
|
|
29668
|
-
|
|
29669
|
-
|
|
29670
|
-
|
|
29671
|
-
|
|
29672
|
-
|
|
29673
|
-
|
|
29674
|
-
|
|
29588
|
+
const mediaDefaultSpecLargeMarginWidth = wonderBlocksTokens.spacing.large_24;
|
|
29589
|
+
const MEDIA_DEFAULT_SPEC = {
|
|
29590
|
+
small: {
|
|
29591
|
+
query: "(max-width: 767px)",
|
|
29592
|
+
totalColumns: 4,
|
|
29593
|
+
gutterWidth: wonderBlocksTokens.spacing.medium_16,
|
|
29594
|
+
marginWidth: wonderBlocksTokens.spacing.medium_16
|
|
29595
|
+
},
|
|
29596
|
+
medium: {
|
|
29597
|
+
query: "(min-width: 768px) and (max-width: 1023px)",
|
|
29598
|
+
totalColumns: 8,
|
|
29599
|
+
gutterWidth: wonderBlocksTokens.spacing.xLarge_32,
|
|
29600
|
+
marginWidth: wonderBlocksTokens.spacing.large_24
|
|
29601
|
+
},
|
|
29602
|
+
large: {
|
|
29603
|
+
query: "(min-width: 1024px)",
|
|
29604
|
+
totalColumns: 12,
|
|
29605
|
+
gutterWidth: wonderBlocksTokens.spacing.xLarge_32,
|
|
29606
|
+
marginWidth: mediaDefaultSpecLargeMarginWidth,
|
|
29607
|
+
maxWidth: 1120 + mediaDefaultSpecLargeMarginWidth * 2
|
|
29608
|
+
}
|
|
29675
29609
|
};
|
|
29676
|
-
|
|
29677
|
-
|
|
29678
|
-
|
|
29679
|
-
|
|
29680
|
-
|
|
29681
|
-
|
|
29682
|
-
isOpen,
|
|
29683
|
-
onToggle
|
|
29684
|
-
} = _ref;
|
|
29685
|
-
return /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, {
|
|
29686
|
-
style: {
|
|
29687
|
-
flexDirection: "row",
|
|
29688
|
-
justifyContent: "space-between",
|
|
29689
|
-
backgroundColor: wonderBlocksTokens.color.offBlack8,
|
|
29690
|
-
padding: wonderBlocksTokens.spacing.xSmall_8,
|
|
29691
|
-
marginTop: wonderBlocksTokens.spacing.small_12,
|
|
29692
|
-
// NOTE(jeremy): This is the inverse of the @editorPadding CSS
|
|
29693
|
-
// variable found in perseus-editor.less. For now, it must
|
|
29694
|
-
// match otherwise there's a gap from this header to the edge
|
|
29695
|
-
// of the editor borders.
|
|
29696
|
-
marginInline: -10,
|
|
29697
|
-
cursor: "pointer"
|
|
29698
|
-
},
|
|
29699
|
-
onClick: () => onToggle?.(!isOpen)
|
|
29700
|
-
}, /*#__PURE__*/React__namespace.createElement(wonderBlocksTypography.LabelSmall, null, title), /*#__PURE__*/React__namespace.createElement(ToggleableCaret, {
|
|
29701
|
-
isExpanded: isOpen
|
|
29702
|
-
}));
|
|
29703
|
-
}
|
|
29704
|
-
class InteractiveGraphSettings extends React__namespace.Component {
|
|
29705
|
-
_isMounted = false;
|
|
29706
|
-
bgUrlRef = /*#__PURE__*/React__namespace.createRef();
|
|
29707
|
-
labelXRef = /*#__PURE__*/React__namespace.createRef();
|
|
29708
|
-
labelYRef = /*#__PURE__*/React__namespace.createRef();
|
|
29709
|
-
static stateFromProps(props) {
|
|
29710
|
-
return {
|
|
29711
|
-
labelsTextbox: props.labels,
|
|
29712
|
-
gridStepTextbox: props.gridStep,
|
|
29713
|
-
snapStepTextbox: props.snapStep,
|
|
29714
|
-
stepTextbox: props.step,
|
|
29715
|
-
rangeTextbox: props.range,
|
|
29716
|
-
// Shallow-copied clone
|
|
29717
|
-
backgroundImage: {
|
|
29718
|
-
...props.backgroundImage
|
|
29719
|
-
}
|
|
29720
|
-
};
|
|
29610
|
+
({
|
|
29611
|
+
large: {
|
|
29612
|
+
query: "(min-width: 1px)",
|
|
29613
|
+
totalColumns: 12,
|
|
29614
|
+
gutterWidth: wonderBlocksTokens.spacing.xLarge_32,
|
|
29615
|
+
marginWidth: wonderBlocksTokens.spacing.medium_16
|
|
29721
29616
|
}
|
|
29722
|
-
|
|
29723
|
-
|
|
29724
|
-
|
|
29725
|
-
|
|
29726
|
-
|
|
29727
|
-
|
|
29617
|
+
});
|
|
29618
|
+
({
|
|
29619
|
+
small: {
|
|
29620
|
+
query: "(max-width: 767px)",
|
|
29621
|
+
totalColumns: 4,
|
|
29622
|
+
gutterWidth: wonderBlocksTokens.spacing.medium_16,
|
|
29623
|
+
marginWidth: wonderBlocksTokens.spacing.medium_16
|
|
29624
|
+
},
|
|
29625
|
+
large: {
|
|
29626
|
+
query: "(min-width: 768px)",
|
|
29627
|
+
totalColumns: 12,
|
|
29628
|
+
gutterWidth: wonderBlocksTokens.spacing.xLarge_32,
|
|
29629
|
+
marginWidth: wonderBlocksTokens.spacing.xxLarge_48
|
|
29728
29630
|
}
|
|
29729
|
-
|
|
29730
|
-
|
|
29731
|
-
|
|
29732
|
-
|
|
29733
|
-
|
|
29734
|
-
|
|
29735
|
-
|
|
29736
|
-
|
|
29737
|
-
|
|
29738
|
-
|
|
29739
|
-
|
|
29740
|
-
|
|
29741
|
-
|
|
29742
|
-
|
|
29743
|
-
|
|
29744
|
-
|
|
29745
|
-
|
|
29746
|
-
|
|
29747
|
-
// this.isMounted() but is still considered an anti-pattern.
|
|
29748
|
-
this._isMounted = true;
|
|
29749
|
-
this.changeGraph = ___default["default"].debounce(this.changeGraph, 300);
|
|
29631
|
+
});
|
|
29632
|
+
|
|
29633
|
+
const defaultContext = {
|
|
29634
|
+
ssrSize: "large",
|
|
29635
|
+
mediaSpec: MEDIA_DEFAULT_SPEC
|
|
29636
|
+
};
|
|
29637
|
+
const MediaLayoutContext = React__namespace.createContext(defaultContext);
|
|
29638
|
+
MediaLayoutContext.displayName = "MediaLayoutContext";
|
|
29639
|
+
|
|
29640
|
+
class Spring extends React__namespace.Component {
|
|
29641
|
+
render() {
|
|
29642
|
+
const {
|
|
29643
|
+
style
|
|
29644
|
+
} = this.props;
|
|
29645
|
+
return React__namespace.createElement(wonderBlocksCore.View, {
|
|
29646
|
+
"aria-hidden": "true",
|
|
29647
|
+
style: [styles$x.grow, style]
|
|
29648
|
+
});
|
|
29750
29649
|
}
|
|
29751
|
-
|
|
29752
|
-
|
|
29753
|
-
|
|
29754
|
-
|
|
29755
|
-
this.setState(InteractiveGraphSettings.stateFromProps(nextProps));
|
|
29756
|
-
}
|
|
29757
|
-
}
|
|
29758
|
-
componentWillUnmount() {
|
|
29759
|
-
this._isMounted = false;
|
|
29650
|
+
}
|
|
29651
|
+
const styles$x = aphrodite.StyleSheet.create({
|
|
29652
|
+
grow: {
|
|
29653
|
+
flexGrow: 1
|
|
29760
29654
|
}
|
|
29761
|
-
|
|
29762
|
-
var _this = this;
|
|
29763
|
-
return function () {
|
|
29764
|
-
for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
|
|
29765
|
-
args[_key] = arguments[_key];
|
|
29766
|
-
}
|
|
29767
|
-
return perseus.Changeable.change.apply(_this, args);
|
|
29768
|
-
};
|
|
29769
|
-
})();
|
|
29655
|
+
});
|
|
29770
29656
|
|
|
29771
|
-
|
|
29772
|
-
|
|
29773
|
-
changeRulerLabel = e => {
|
|
29774
|
-
this.change({
|
|
29775
|
-
rulerLabel: e.target.value
|
|
29776
|
-
});
|
|
29777
|
-
};
|
|
29778
|
-
changeRulerTicks = e => {
|
|
29779
|
-
this.change({
|
|
29780
|
-
rulerTicks: +e.target.value
|
|
29781
|
-
});
|
|
29782
|
-
};
|
|
29783
|
-
changeBackgroundUrl = e => {
|
|
29784
|
-
// Only continue on blur or "enter"
|
|
29785
|
-
if (e.type === "keypress" && e.key !== "Enter") {
|
|
29786
|
-
return;
|
|
29787
|
-
}
|
|
29788
|
-
const setUrl = (url, width, height) => {
|
|
29789
|
-
// Shallow-copied clone
|
|
29790
|
-
const image = {
|
|
29791
|
-
...this.props.backgroundImage
|
|
29792
|
-
};
|
|
29793
|
-
image.url = url;
|
|
29794
|
-
image.width = width;
|
|
29795
|
-
image.height = height;
|
|
29796
|
-
this.setState({
|
|
29797
|
-
backgroundImage: image
|
|
29798
|
-
}, this.changeGraph);
|
|
29799
|
-
};
|
|
29800
|
-
const url = this.bgUrlRef.current?.value;
|
|
29801
|
-
if (url) {
|
|
29802
|
-
perseus.Util.getImageSize(url, (width, height) => {
|
|
29803
|
-
if (this._isMounted) {
|
|
29804
|
-
setUrl(url, width, height);
|
|
29805
|
-
}
|
|
29806
|
-
});
|
|
29807
|
-
} else {
|
|
29808
|
-
setUrl(null, 0, 0);
|
|
29809
|
-
}
|
|
29810
|
-
};
|
|
29811
|
-
renderLabelChoices = choices => {
|
|
29812
|
-
return choices.map(nameAndValue => /*#__PURE__*/React__namespace.createElement("option", {
|
|
29813
|
-
key: nameAndValue[1],
|
|
29814
|
-
value: nameAndValue[1]
|
|
29815
|
-
}, nameAndValue[0]));
|
|
29816
|
-
};
|
|
29817
|
-
validRange = range => {
|
|
29818
|
-
const numbers = ___default["default"].every(range, function (num) {
|
|
29819
|
-
return ___default["default"].isFinite(num);
|
|
29820
|
-
});
|
|
29821
|
-
if (!numbers) {
|
|
29822
|
-
return "Range must be a valid number";
|
|
29823
|
-
}
|
|
29824
|
-
if (range[0] >= range[1]) {
|
|
29825
|
-
return "Range must have a higher number on the right";
|
|
29826
|
-
}
|
|
29827
|
-
return true;
|
|
29828
|
-
};
|
|
29829
|
-
validateStepValue = settings => {
|
|
29657
|
+
class Strut extends React__namespace.Component {
|
|
29658
|
+
render() {
|
|
29830
29659
|
const {
|
|
29831
|
-
|
|
29832
|
-
|
|
29833
|
-
|
|
29834
|
-
|
|
29835
|
-
|
|
29836
|
-
|
|
29837
|
-
const nSteps = numSteps(range, step);
|
|
29838
|
-
if (nSteps < minTicks) {
|
|
29839
|
-
return name + " is too large, there must be at least " + minTicks + " ticks.";
|
|
29840
|
-
}
|
|
29841
|
-
if (nSteps > maxTicks) {
|
|
29842
|
-
return name + " is too small, there can be at most " + maxTicks + " ticks.";
|
|
29843
|
-
}
|
|
29844
|
-
return true;
|
|
29845
|
-
};
|
|
29846
|
-
validSnapStep = (step, range) => {
|
|
29847
|
-
return this.validateStepValue({
|
|
29848
|
-
step: step,
|
|
29849
|
-
range: range,
|
|
29850
|
-
name: "Snap step",
|
|
29851
|
-
minTicks: 5,
|
|
29852
|
-
maxTicks: 60
|
|
29853
|
-
});
|
|
29854
|
-
};
|
|
29855
|
-
validGridStep = (step, range) => {
|
|
29856
|
-
return this.validateStepValue({
|
|
29857
|
-
step: step,
|
|
29858
|
-
range: range,
|
|
29859
|
-
name: "Grid step",
|
|
29860
|
-
minTicks: 3,
|
|
29861
|
-
maxTicks: 60
|
|
29862
|
-
});
|
|
29863
|
-
};
|
|
29864
|
-
validStep = (step, range) => {
|
|
29865
|
-
return this.validateStepValue({
|
|
29866
|
-
step: step,
|
|
29867
|
-
range: range,
|
|
29868
|
-
name: "Step",
|
|
29869
|
-
minTicks: 3,
|
|
29870
|
-
maxTicks: 20
|
|
29871
|
-
});
|
|
29872
|
-
};
|
|
29873
|
-
validBackgroundImageSize = image => {
|
|
29874
|
-
// Ignore empty images
|
|
29875
|
-
if (!image.url) {
|
|
29876
|
-
return true;
|
|
29877
|
-
}
|
|
29878
|
-
const validSize = image.width <= 450 && image.height <= 450;
|
|
29879
|
-
if (!validSize) {
|
|
29880
|
-
return "Image must be smaller than 450px x 450px.";
|
|
29881
|
-
}
|
|
29882
|
-
return true;
|
|
29883
|
-
};
|
|
29884
|
-
validateGraphSettings = (range, step, gridStep, snapStep, image) => {
|
|
29885
|
-
const self = this;
|
|
29886
|
-
let msg;
|
|
29887
|
-
const goodRange = ___default["default"].every(range, function (range) {
|
|
29888
|
-
msg = self.validRange(range);
|
|
29889
|
-
return msg === true;
|
|
29890
|
-
});
|
|
29891
|
-
if (!goodRange) {
|
|
29892
|
-
return msg;
|
|
29893
|
-
}
|
|
29894
|
-
const goodStep = ___default["default"].every(step, function (step, i) {
|
|
29895
|
-
msg = self.validStep(step, range[i]);
|
|
29896
|
-
return msg === true;
|
|
29897
|
-
});
|
|
29898
|
-
if (!goodStep) {
|
|
29899
|
-
return msg;
|
|
29900
|
-
}
|
|
29901
|
-
const goodGridStep = ___default["default"].every(gridStep, function (gridStep, i) {
|
|
29902
|
-
msg = self.validGridStep(gridStep, range[i]);
|
|
29903
|
-
return msg === true;
|
|
29904
|
-
});
|
|
29905
|
-
if (!goodGridStep) {
|
|
29906
|
-
return msg;
|
|
29907
|
-
}
|
|
29908
|
-
const goodSnapStep = ___default["default"].every(snapStep, function (snapStep, i) {
|
|
29909
|
-
msg = self.validSnapStep(snapStep, range[i]);
|
|
29910
|
-
return msg === true;
|
|
29660
|
+
size,
|
|
29661
|
+
style
|
|
29662
|
+
} = this.props;
|
|
29663
|
+
return React__namespace.createElement(wonderBlocksCore.View, {
|
|
29664
|
+
"aria-hidden": "true",
|
|
29665
|
+
style: [strutStyle(size), style]
|
|
29911
29666
|
});
|
|
29912
|
-
|
|
29913
|
-
|
|
29914
|
-
|
|
29915
|
-
|
|
29916
|
-
|
|
29917
|
-
|
|
29918
|
-
|
|
29919
|
-
|
|
29920
|
-
|
|
29921
|
-
|
|
29922
|
-
changeLabel = (i, e) => {
|
|
29923
|
-
const val = e.target.value;
|
|
29924
|
-
const labels = this.state.labelsTextbox.slice();
|
|
29925
|
-
labels[i] = val;
|
|
29926
|
-
this.setState({
|
|
29927
|
-
labelsTextbox: labels
|
|
29928
|
-
}, this.changeGraph);
|
|
29929
|
-
};
|
|
29930
|
-
changeRange = (i, values) => {
|
|
29931
|
-
const ranges = this.state.rangeTextbox.slice();
|
|
29932
|
-
ranges[i] = values;
|
|
29933
|
-
const step = this.state.stepTextbox.slice();
|
|
29934
|
-
const gridStep = this.state.gridStepTextbox.slice();
|
|
29935
|
-
const snapStep = this.state.snapStepTextbox.slice();
|
|
29936
|
-
const scale = perseus.Util.scaleFromExtent(ranges[i], this.props.box[i]);
|
|
29937
|
-
if (this.validRange(ranges[i]) === true) {
|
|
29938
|
-
step[i] = perseus.Util.tickStepFromExtent(ranges[i], this.props.box[i]);
|
|
29939
|
-
const gridStepValue = perseus.Util.gridStepFromTickStep(step[i], scale);
|
|
29940
|
-
if (gridStepValue) {
|
|
29941
|
-
gridStep[i] = gridStepValue;
|
|
29942
|
-
}
|
|
29943
|
-
snapStep[i] = gridStep[i] / 2;
|
|
29944
|
-
}
|
|
29945
|
-
this.setState({
|
|
29946
|
-
stepTextbox: step,
|
|
29947
|
-
gridStepTextbox: gridStep,
|
|
29948
|
-
snapStepTextbox: snapStep,
|
|
29949
|
-
rangeTextbox: ranges
|
|
29950
|
-
}, this.changeGraph);
|
|
29951
|
-
};
|
|
29952
|
-
changeStep = step => {
|
|
29953
|
-
this.setState({
|
|
29954
|
-
stepTextbox: step
|
|
29955
|
-
}, this.changeGraph);
|
|
29956
|
-
};
|
|
29957
|
-
changeSnapStep = snapStep => {
|
|
29958
|
-
this.setState({
|
|
29959
|
-
snapStepTextbox: snapStep
|
|
29960
|
-
}, this.changeGraph);
|
|
29961
|
-
};
|
|
29962
|
-
changeGridStep = gridStep => {
|
|
29963
|
-
this.setState({
|
|
29964
|
-
gridStepTextbox: gridStep,
|
|
29965
|
-
snapStepTextbox: ___default["default"].map(gridStep, function (step) {
|
|
29966
|
-
return step / 2;
|
|
29967
|
-
})
|
|
29968
|
-
}, this.changeGraph);
|
|
29667
|
+
}
|
|
29668
|
+
}
|
|
29669
|
+
const strutStyle = size => {
|
|
29670
|
+
return {
|
|
29671
|
+
width: size,
|
|
29672
|
+
MsFlexBasis: size,
|
|
29673
|
+
MsFlexPreferredSize: size,
|
|
29674
|
+
WebkitFlexBasis: size,
|
|
29675
|
+
flexBasis: size,
|
|
29676
|
+
flexShrink: 0
|
|
29969
29677
|
};
|
|
29970
|
-
|
|
29971
|
-
const labels = this.state.labelsTextbox;
|
|
29972
|
-
const range = ___default["default"].map(this.state.rangeTextbox, function (range) {
|
|
29973
|
-
return ___default["default"].map(range, Number);
|
|
29974
|
-
});
|
|
29975
|
-
const step = ___default["default"].map(this.state.stepTextbox, Number);
|
|
29976
|
-
const gridStep = this.state.gridStepTextbox;
|
|
29977
|
-
const snapStep = this.state.snapStepTextbox;
|
|
29978
|
-
const image = this.state.backgroundImage;
|
|
29678
|
+
};
|
|
29979
29679
|
|
|
29980
|
-
|
|
29981
|
-
|
|
29982
|
-
|
|
29983
|
-
|
|
29984
|
-
|
|
29985
|
-
|
|
29986
|
-
|
|
29987
|
-
|
|
29988
|
-
|
|
29989
|
-
|
|
29990
|
-
|
|
29991
|
-
|
|
29992
|
-
|
|
29993
|
-
|
|
29994
|
-
|
|
29995
|
-
|
|
29996
|
-
|
|
29997
|
-
|
|
29998
|
-
|
|
29999
|
-
|
|
30000
|
-
|
|
29680
|
+
function focusWithChromeStickyFocusBugWorkaround(element) {
|
|
29681
|
+
// NOTE(marksandstrom) Chrome sticky focus bug.
|
|
29682
|
+
//
|
|
29683
|
+
// There is a bug in Chrome related to sticky positioning and
|
|
29684
|
+
// focus: When a child of an element with sticky positioning is
|
|
29685
|
+
// focused with the focus() method, the scrollable area
|
|
29686
|
+
// containing that element will scroll to the top (even though
|
|
29687
|
+
// the element is already visble on the page). For a dropdown
|
|
29688
|
+
// this means that the area will be scrolled to the top when
|
|
29689
|
+
// the user interacts with the dropdown (since we actively
|
|
29690
|
+
// manage dropdown header and option focus for keyboard users).
|
|
29691
|
+
//
|
|
29692
|
+
// To work around this bug the `preventScroll` focus option is
|
|
29693
|
+
// used.
|
|
29694
|
+
//
|
|
29695
|
+
// Using `focusOptions` is an experimental browser feature
|
|
29696
|
+
// "that should not be used in production code". However, since
|
|
29697
|
+
// Chrome is the only browser we support that exhibits this
|
|
29698
|
+
// buggy behavior and using `focusOptions` works around the
|
|
29699
|
+
// bug, it is perfectly reasonable to use the feature in this
|
|
29700
|
+
// case. We are not relying on the effect of the
|
|
29701
|
+
// `preventScroll` option otherwise.
|
|
29702
|
+
//
|
|
29703
|
+
// focusOptions documentation:
|
|
29704
|
+
//
|
|
29705
|
+
// https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/focus
|
|
29706
|
+
//
|
|
29707
|
+
// Note that there could be cases where we want default focus() behavior.
|
|
29708
|
+
// One that comes to mind is a dropdown with a long list of options that
|
|
29709
|
+
// might be rendered off screen when opened. With this workaround the
|
|
29710
|
+
// selected option would not be scrolled into view if the option is near
|
|
29711
|
+
// the end of the list. We're not aware of any uses of the dropdown where
|
|
29712
|
+
// this is an issue, however, so there isn't currently a way to out of the
|
|
29713
|
+
// `preventScroll` behavior.
|
|
29714
|
+
|
|
29715
|
+
// @ts-expect-error - TS2339 - Property 'focus' does not exist on type 'Element'.
|
|
29716
|
+
element.focus({
|
|
29717
|
+
preventScroll: true
|
|
29718
|
+
});
|
|
29719
|
+
}
|
|
29720
|
+
const DEFAULT_COLOR = "grayH";
|
|
29721
|
+
function getDefaultFigureForType(type) {
|
|
29722
|
+
switch (type) {
|
|
29723
|
+
case "point":
|
|
29724
|
+
return {
|
|
29725
|
+
type: "point",
|
|
29726
|
+
coord: [0, 0],
|
|
29727
|
+
color: DEFAULT_COLOR,
|
|
29728
|
+
filled: true
|
|
29729
|
+
};
|
|
29730
|
+
case "line":
|
|
29731
|
+
return {
|
|
29732
|
+
type: "line",
|
|
29733
|
+
kind: "line",
|
|
29734
|
+
points: [getDefaultFigureForType("point"), {
|
|
29735
|
+
...getDefaultFigureForType("point"),
|
|
29736
|
+
coord: [2, 2]
|
|
29737
|
+
}],
|
|
29738
|
+
color: DEFAULT_COLOR,
|
|
29739
|
+
lineStyle: "solid",
|
|
29740
|
+
showPoint1: false,
|
|
29741
|
+
showPoint2: false
|
|
29742
|
+
};
|
|
29743
|
+
case "vector":
|
|
29744
|
+
return {
|
|
29745
|
+
type: "vector",
|
|
29746
|
+
points: [[0, 0], [2, 2]],
|
|
29747
|
+
color: DEFAULT_COLOR
|
|
29748
|
+
};
|
|
29749
|
+
case "ellipse":
|
|
29750
|
+
return {
|
|
29751
|
+
type: "ellipse",
|
|
29752
|
+
center: [0, 0],
|
|
29753
|
+
radius: [1, 1],
|
|
29754
|
+
angle: 0,
|
|
29755
|
+
color: DEFAULT_COLOR,
|
|
29756
|
+
fillStyle: "none",
|
|
29757
|
+
strokeStyle: "solid"
|
|
29758
|
+
};
|
|
29759
|
+
case "polygon":
|
|
29760
|
+
return {
|
|
29761
|
+
type: "polygon",
|
|
29762
|
+
points: [[0, 2], [-1, 0], [1, 0]],
|
|
29763
|
+
color: DEFAULT_COLOR,
|
|
29764
|
+
showVertices: false,
|
|
29765
|
+
fillStyle: "none",
|
|
29766
|
+
strokeStyle: "solid"
|
|
29767
|
+
};
|
|
29768
|
+
default:
|
|
29769
|
+
throw new wonderStuffCore.UnreachableCaseError(type);
|
|
29770
|
+
}
|
|
29771
|
+
}
|
|
29772
|
+
function degreeToRadian(degrees) {
|
|
29773
|
+
return degrees / 180 * Math.PI;
|
|
29774
|
+
}
|
|
29775
|
+
function radianToDegree(radians) {
|
|
29776
|
+
return radians / Math.PI * 180;
|
|
29777
|
+
}
|
|
29778
|
+
|
|
29779
|
+
/**
|
|
29780
|
+
* Dropdown for selecting a locked figure to add to an interactive graph.
|
|
29781
|
+
* Locked figures are elements (points, segmeents, etc.) that are not
|
|
29782
|
+
* interactive, just present in the graph's background.
|
|
29783
|
+
*
|
|
29784
|
+
* Used in the interactive graph editor's locked figures section.
|
|
29785
|
+
*/
|
|
29786
|
+
const LockedFigureSelect = props => {
|
|
29787
|
+
const {
|
|
29788
|
+
id,
|
|
29789
|
+
onChange
|
|
29790
|
+
} = props;
|
|
29791
|
+
const figureTypes = props.showM2Features ? ["point", "line", "vector", "ellipse", "polygon"] : ["point", "line"];
|
|
29792
|
+
return /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, {
|
|
29793
|
+
style: styles$w.container
|
|
29794
|
+
}, /*#__PURE__*/React__namespace.createElement(wonderBlocksDropdown.ActionMenu, {
|
|
29795
|
+
menuText: "Add locked figure",
|
|
29796
|
+
style: styles$w.addElementSelect
|
|
29797
|
+
}, figureTypes.map(figureType => /*#__PURE__*/React__namespace.createElement(wonderBlocksDropdown.ActionItem, {
|
|
29798
|
+
key: `${id}-${figureType}`,
|
|
29799
|
+
label: figureType,
|
|
29800
|
+
onClick: () => onChange(figureType)
|
|
29801
|
+
}, figureType))));
|
|
29802
|
+
};
|
|
29803
|
+
const styles$w = aphrodite.StyleSheet.create({
|
|
29804
|
+
container: {
|
|
29805
|
+
marginTop: wonderBlocksTokens.spacing.xSmall_8
|
|
29806
|
+
},
|
|
29807
|
+
addElementSelect: {
|
|
29808
|
+
backgroundColor: wonderBlocksTokens.color.fadedBlue8,
|
|
29809
|
+
borderRadius: wonderBlocksTokens.spacing.xxxSmall_4
|
|
29810
|
+
}
|
|
29811
|
+
});
|
|
29812
|
+
|
|
29813
|
+
const AngleInput = props => {
|
|
29814
|
+
const {
|
|
29815
|
+
angle,
|
|
29816
|
+
onChange
|
|
29817
|
+
} = props;
|
|
29818
|
+
const [angleInput, setAngleInput] = React__namespace.useState(radianToDegree(angle).toString());
|
|
29819
|
+
function handleAngleChange(newValue) {
|
|
29820
|
+
// Update the local state (update the input field value).
|
|
29821
|
+
setAngleInput(newValue);
|
|
29822
|
+
|
|
29823
|
+
// If the new value is not a number, don't update the props.
|
|
29824
|
+
// If it's empty, keep the props the same value instead of setting to 0.
|
|
29825
|
+
if (isNaN(+newValue) || newValue === "") {
|
|
29826
|
+
return;
|
|
30001
29827
|
}
|
|
30002
|
-
};
|
|
30003
29828
|
|
|
30004
|
-
|
|
30005
|
-
|
|
30006
|
-
|
|
30007
|
-
|
|
30008
|
-
|
|
30009
|
-
|
|
30010
|
-
|
|
30011
|
-
|
|
30012
|
-
|
|
30013
|
-
|
|
30014
|
-
|
|
30015
|
-
|
|
30016
|
-
|
|
30017
|
-
|
|
30018
|
-
|
|
30019
|
-
|
|
30020
|
-
|
|
30021
|
-
|
|
30022
|
-
|
|
30023
|
-
|
|
30024
|
-
|
|
30025
|
-
|
|
30026
|
-
|
|
30027
|
-
|
|
30028
|
-
|
|
30029
|
-
|
|
30030
|
-
|
|
30031
|
-
|
|
30032
|
-
|
|
30033
|
-
|
|
30034
|
-
|
|
30035
|
-
|
|
30036
|
-
|
|
30037
|
-
|
|
30038
|
-
|
|
30039
|
-
|
|
30040
|
-
|
|
30041
|
-
},
|
|
30042
|
-
|
|
30043
|
-
|
|
30044
|
-
|
|
30045
|
-
|
|
30046
|
-
|
|
30047
|
-
|
|
30048
|
-
|
|
30049
|
-
|
|
30050
|
-
|
|
30051
|
-
|
|
30052
|
-
|
|
30053
|
-
|
|
30054
|
-
|
|
30055
|
-
|
|
30056
|
-
|
|
30057
|
-
|
|
30058
|
-
|
|
30059
|
-
|
|
30060
|
-
|
|
30061
|
-
|
|
30062
|
-
|
|
30063
|
-
|
|
30064
|
-
|
|
30065
|
-
|
|
30066
|
-
|
|
30067
|
-
|
|
30068
|
-
|
|
30069
|
-
|
|
30070
|
-
|
|
30071
|
-
|
|
30072
|
-
|
|
30073
|
-
|
|
30074
|
-
|
|
30075
|
-
|
|
30076
|
-
|
|
30077
|
-
|
|
30078
|
-
|
|
30079
|
-
|
|
30080
|
-
|
|
30081
|
-
|
|
30082
|
-
|
|
30083
|
-
|
|
30084
|
-
|
|
30085
|
-
|
|
30086
|
-
|
|
30087
|
-
|
|
30088
|
-
|
|
30089
|
-
|
|
30090
|
-
|
|
30091
|
-
|
|
30092
|
-
|
|
30093
|
-
|
|
30094
|
-
|
|
30095
|
-
|
|
30096
|
-
|
|
30097
|
-
|
|
30098
|
-
|
|
30099
|
-
|
|
30100
|
-
|
|
30101
|
-
|
|
30102
|
-
|
|
30103
|
-
|
|
30104
|
-
|
|
30105
|
-
|
|
30106
|
-
|
|
30107
|
-
|
|
30108
|
-
|
|
30109
|
-
|
|
30110
|
-
|
|
30111
|
-
|
|
30112
|
-
|
|
30113
|
-
|
|
30114
|
-
|
|
30115
|
-
|
|
30116
|
-
|
|
30117
|
-
|
|
30118
|
-
|
|
30119
|
-
|
|
30120
|
-
|
|
30121
|
-
|
|
30122
|
-
|
|
30123
|
-
|
|
30124
|
-
|
|
30125
|
-
|
|
30126
|
-
|
|
30127
|
-
onChange: this.change,
|
|
30128
|
-
style: styles$s.resetSpaceTop
|
|
30129
|
-
}), /*#__PURE__*/React__namespace.createElement(PropCheckBox$7, {
|
|
30130
|
-
label: "Show protractor",
|
|
30131
|
-
showProtractor: this.props.showProtractor,
|
|
30132
|
-
onChange: this.change,
|
|
30133
|
-
style: styles$s.resetSpaceTop
|
|
30134
|
-
})), (this.props.showRuler || this.props.showProtractor) && /*#__PURE__*/React__namespace.createElement(Banner__default["default"], {
|
|
30135
|
-
layout: "floating",
|
|
30136
|
-
text: "The ruler and protractor are not accessible. Please consider an alternate approach.",
|
|
30137
|
-
kind: "warning"
|
|
30138
|
-
}), this.props.showRuler && /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, {
|
|
30139
|
-
style: styles$s.spaceTop
|
|
30140
|
-
}, /*#__PURE__*/React__namespace.createElement(LabeledRow, {
|
|
30141
|
-
label: "Ruler label:",
|
|
30142
|
-
style: styles$s.resetSpaceTop
|
|
30143
|
-
}, /*#__PURE__*/React__namespace.createElement(wonderBlocksDropdown.SingleSelect, {
|
|
30144
|
-
id: "ruler-label-select",
|
|
30145
|
-
selectedValue: this.props.rulerLabel,
|
|
30146
|
-
onChange: newValue => {
|
|
30147
|
-
this.change({
|
|
30148
|
-
rulerLabel: newValue
|
|
30149
|
-
});
|
|
30150
|
-
},
|
|
30151
|
-
placeholder: "None",
|
|
30152
|
-
style: styles$s.singleSelectShort
|
|
30153
|
-
}, /*#__PURE__*/React__namespace.createElement(wonderBlocksDropdown.OptionItem, {
|
|
30154
|
-
value: "",
|
|
30155
|
-
label: "None",
|
|
30156
|
-
horizontalRule: "full-width"
|
|
30157
|
-
}), /*#__PURE__*/React__namespace.createElement(wonderBlocksDropdown.OptionItem, {
|
|
30158
|
-
value: "mm",
|
|
30159
|
-
label: "Milimeters"
|
|
30160
|
-
}), /*#__PURE__*/React__namespace.createElement(wonderBlocksDropdown.OptionItem, {
|
|
30161
|
-
value: "cm",
|
|
30162
|
-
label: "Centimeters"
|
|
30163
|
-
}), /*#__PURE__*/React__namespace.createElement(wonderBlocksDropdown.OptionItem, {
|
|
30164
|
-
value: "m",
|
|
30165
|
-
label: "Meters"
|
|
30166
|
-
}), /*#__PURE__*/React__namespace.createElement(wonderBlocksDropdown.OptionItem, {
|
|
30167
|
-
value: "km",
|
|
30168
|
-
label: "Kilometers",
|
|
30169
|
-
horizontalRule: "full-width"
|
|
30170
|
-
}), /*#__PURE__*/React__namespace.createElement(wonderBlocksDropdown.OptionItem, {
|
|
30171
|
-
value: "in",
|
|
30172
|
-
label: "Inches"
|
|
30173
|
-
}), /*#__PURE__*/React__namespace.createElement(wonderBlocksDropdown.OptionItem, {
|
|
30174
|
-
value: "ft",
|
|
30175
|
-
label: "Feet"
|
|
30176
|
-
}), /*#__PURE__*/React__namespace.createElement(wonderBlocksDropdown.OptionItem, {
|
|
30177
|
-
value: "yd",
|
|
30178
|
-
label: "Yards"
|
|
30179
|
-
}), /*#__PURE__*/React__namespace.createElement(wonderBlocksDropdown.OptionItem, {
|
|
30180
|
-
value: "mi",
|
|
30181
|
-
label: "Miles"
|
|
30182
|
-
}))), /*#__PURE__*/React__namespace.createElement(LabeledRow, {
|
|
30183
|
-
label: "Ruler ticks:"
|
|
30184
|
-
}, /*#__PURE__*/React__namespace.createElement(wonderBlocksDropdown.SingleSelect, {
|
|
30185
|
-
id: "ruler-ticks-select",
|
|
30186
|
-
selectedValue: `${this.props.rulerTicks}`,
|
|
30187
|
-
onChange: newValue => {
|
|
30188
|
-
this.change({
|
|
30189
|
-
rulerTicks: newValue
|
|
30190
|
-
});
|
|
30191
|
-
},
|
|
30192
|
-
placeholder: "10",
|
|
30193
|
-
style: styles$s.singleSelectShort
|
|
30194
|
-
}, [1, 2, 4, 8, 10, 16].map(value => /*#__PURE__*/React__namespace.createElement(wonderBlocksDropdown.OptionItem, {
|
|
30195
|
-
key: value,
|
|
30196
|
-
value: `${value}`,
|
|
30197
|
-
label: `${value}`
|
|
30198
|
-
}))))))));
|
|
29829
|
+
// Update the graph.
|
|
29830
|
+
onChange(degreeToRadian(newValue));
|
|
29831
|
+
}
|
|
29832
|
+
return /*#__PURE__*/React__namespace.createElement(wonderBlocksTypography.LabelMedium, {
|
|
29833
|
+
tag: "label",
|
|
29834
|
+
style: styles$v.row
|
|
29835
|
+
}, "angle (degrees)", /*#__PURE__*/React__namespace.createElement(Strut, {
|
|
29836
|
+
size: wonderBlocksTokens.spacing.xxSmall_6
|
|
29837
|
+
}), /*#__PURE__*/React__namespace.createElement(wonderBlocksForm.TextField, {
|
|
29838
|
+
type: "number",
|
|
29839
|
+
value: angleInput,
|
|
29840
|
+
onChange: handleAngleChange,
|
|
29841
|
+
style: styles$v.textField
|
|
29842
|
+
}), /*#__PURE__*/React__namespace.createElement(Strut, {
|
|
29843
|
+
size: wonderBlocksTokens.spacing.xxSmall_6
|
|
29844
|
+
}));
|
|
29845
|
+
};
|
|
29846
|
+
const styles$v = aphrodite.StyleSheet.create({
|
|
29847
|
+
row: {
|
|
29848
|
+
display: "flex",
|
|
29849
|
+
flexDirection: "row",
|
|
29850
|
+
alignItems: "center"
|
|
29851
|
+
},
|
|
29852
|
+
textField: {
|
|
29853
|
+
width: wonderBlocksTokens.spacing.xxxLarge_64
|
|
29854
|
+
}
|
|
29855
|
+
});
|
|
29856
|
+
|
|
29857
|
+
const ColorSwatch = props => {
|
|
29858
|
+
const {
|
|
29859
|
+
color,
|
|
29860
|
+
filled = true,
|
|
29861
|
+
decorative = false
|
|
29862
|
+
} = props;
|
|
29863
|
+
return /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, {
|
|
29864
|
+
"aria-label":
|
|
29865
|
+
// Don't include an aria label for decorative circles.
|
|
29866
|
+
!decorative ? `${color}, ${filled ? "filled" : "open"}` : undefined,
|
|
29867
|
+
style: [styles$u.colorSwatch, {
|
|
29868
|
+
border: `4px solid ${perseus.lockedFigureColors[color]}`,
|
|
29869
|
+
backgroundColor: filled ? perseus.lockedFigureColors[color] : wonderBlocksTokens.color.white
|
|
29870
|
+
}]
|
|
29871
|
+
});
|
|
29872
|
+
};
|
|
29873
|
+
const styles$u = aphrodite.StyleSheet.create({
|
|
29874
|
+
colorSwatch: {
|
|
29875
|
+
// Add a white outline so that the color swatch is visible when
|
|
29876
|
+
// the dropdown option is highlighted with its blue background.
|
|
29877
|
+
outline: `2px solid ${wonderBlocksTokens.color.offWhite}`,
|
|
29878
|
+
borderRadius: "50%",
|
|
29879
|
+
width: wonderBlocksTokens.spacing.large_24,
|
|
29880
|
+
height: wonderBlocksTokens.spacing.large_24
|
|
29881
|
+
}
|
|
29882
|
+
});
|
|
29883
|
+
|
|
29884
|
+
const possibleColors = Object.keys(perseus.lockedFigureColors);
|
|
29885
|
+
const ColorSelect = props => {
|
|
29886
|
+
const {
|
|
29887
|
+
selectedValue,
|
|
29888
|
+
style,
|
|
29889
|
+
onChange
|
|
29890
|
+
} = props;
|
|
29891
|
+
return /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, {
|
|
29892
|
+
style: [styles$t.row, style]
|
|
29893
|
+
}, /*#__PURE__*/React__namespace.createElement(wonderBlocksTypography.LabelMedium, {
|
|
29894
|
+
tag: "label",
|
|
29895
|
+
style: styles$t.row
|
|
29896
|
+
}, "color", /*#__PURE__*/React__namespace.createElement(Strut, {
|
|
29897
|
+
size: wonderBlocksTokens.spacing.xxSmall_6
|
|
29898
|
+
}), /*#__PURE__*/React__namespace.createElement(wonderBlocksDropdown.SingleSelect, {
|
|
29899
|
+
selectedValue: selectedValue,
|
|
29900
|
+
onChange: onChange
|
|
29901
|
+
// Placeholder is required, but never gets used.
|
|
29902
|
+
,
|
|
29903
|
+
placeholder: ""
|
|
29904
|
+
}, possibleColors.map(colorName => /*#__PURE__*/React__namespace.createElement(wonderBlocksDropdown.OptionItem, {
|
|
29905
|
+
key: colorName,
|
|
29906
|
+
value: colorName,
|
|
29907
|
+
label: colorName,
|
|
29908
|
+
leftAccessory: /*#__PURE__*/React__namespace.createElement(ColorSwatch, {
|
|
29909
|
+
color: colorName,
|
|
29910
|
+
decorative: true
|
|
29911
|
+
})
|
|
29912
|
+
}, colorName)))));
|
|
29913
|
+
};
|
|
29914
|
+
const styles$t = aphrodite.StyleSheet.create({
|
|
29915
|
+
row: {
|
|
29916
|
+
display: "flex",
|
|
29917
|
+
flexDirection: "row",
|
|
29918
|
+
alignItems: "center"
|
|
29919
|
+
}
|
|
29920
|
+
});
|
|
29921
|
+
|
|
29922
|
+
const CoordinatePairInput = props => {
|
|
29923
|
+
const {
|
|
29924
|
+
coord,
|
|
29925
|
+
labels,
|
|
29926
|
+
error,
|
|
29927
|
+
style,
|
|
29928
|
+
onChange
|
|
29929
|
+
} = props;
|
|
29930
|
+
|
|
29931
|
+
// Keep track of the coordinates via state as the user is editing them,
|
|
29932
|
+
// before they are updated in the props as a valid number.
|
|
29933
|
+
const [coordState, setCoordState] = React__namespace.useState([
|
|
29934
|
+
// Using strings to make it easier to work with the text fields.
|
|
29935
|
+
coord[0].toString(), coord[1].toString()]);
|
|
29936
|
+
function handleCoordChange(newValue, coordIndex) {
|
|
29937
|
+
// Update the local state (update the input field value).
|
|
29938
|
+
const newCoordState = [...coordState];
|
|
29939
|
+
newCoordState[coordIndex] = newValue;
|
|
29940
|
+
setCoordState(newCoordState);
|
|
29941
|
+
|
|
29942
|
+
// If the new value is not a number, don't update the props.
|
|
29943
|
+
// If it's empty, keep the props the same value instead of setting to 0.
|
|
29944
|
+
if (isNaN(+newValue) || newValue === "") {
|
|
29945
|
+
return;
|
|
29946
|
+
}
|
|
29947
|
+
|
|
29948
|
+
// Update the props (update the graph).
|
|
29949
|
+
const newCoords = [...coord];
|
|
29950
|
+
newCoords[coordIndex] = +newValue;
|
|
29951
|
+
onChange(newCoords);
|
|
30199
29952
|
}
|
|
30200
|
-
|
|
29953
|
+
return /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, {
|
|
29954
|
+
style: [styles$s.row, style]
|
|
29955
|
+
}, /*#__PURE__*/React__namespace.createElement(wonderBlocksTypography.LabelMedium, {
|
|
29956
|
+
tag: "label",
|
|
29957
|
+
style: styles$s.row
|
|
29958
|
+
}, labels ? labels[0] : "x coord", /*#__PURE__*/React__namespace.createElement(Strut, {
|
|
29959
|
+
size: wonderBlocksTokens.spacing.xxSmall_6
|
|
29960
|
+
}), /*#__PURE__*/React__namespace.createElement(wonderBlocksForm.TextField, {
|
|
29961
|
+
type: "number",
|
|
29962
|
+
value: coordState[0],
|
|
29963
|
+
onChange: newValue => handleCoordChange(newValue, 0),
|
|
29964
|
+
style: [styles$s.textField, error ? styles$s.errorField : undefined]
|
|
29965
|
+
})), /*#__PURE__*/React__namespace.createElement(Strut, {
|
|
29966
|
+
size: wonderBlocksTokens.spacing.medium_16
|
|
29967
|
+
}), /*#__PURE__*/React__namespace.createElement(wonderBlocksTypography.LabelMedium, {
|
|
29968
|
+
tag: "label",
|
|
29969
|
+
style: styles$s.row
|
|
29970
|
+
}, labels ? labels[1] : "y coord", /*#__PURE__*/React__namespace.createElement(Strut, {
|
|
29971
|
+
size: wonderBlocksTokens.spacing.xxSmall_6
|
|
29972
|
+
}), /*#__PURE__*/React__namespace.createElement(wonderBlocksForm.TextField, {
|
|
29973
|
+
type: "number",
|
|
29974
|
+
value: coordState[1],
|
|
29975
|
+
onChange: newValue => handleCoordChange(newValue, 1),
|
|
29976
|
+
style: [styles$s.textField, error ? styles$s.errorField : undefined]
|
|
29977
|
+
})));
|
|
29978
|
+
};
|
|
30201
29979
|
const styles$s = aphrodite.StyleSheet.create({
|
|
30202
|
-
|
|
30203
|
-
|
|
29980
|
+
row: {
|
|
29981
|
+
display: "flex",
|
|
29982
|
+
flexDirection: "row",
|
|
29983
|
+
alignItems: "center"
|
|
30204
29984
|
},
|
|
30205
|
-
|
|
30206
|
-
|
|
29985
|
+
textField: {
|
|
29986
|
+
width: wonderBlocksTokens.spacing.xxxLarge_64
|
|
30207
29987
|
},
|
|
30208
|
-
|
|
30209
|
-
|
|
30210
|
-
|
|
30211
|
-
|
|
29988
|
+
errorField: {
|
|
29989
|
+
borderColor: wonderBlocksTokens.color.red,
|
|
29990
|
+
backgroundColor: wonderBlocksTokens.color.fadedRed8
|
|
29991
|
+
}
|
|
29992
|
+
});
|
|
29993
|
+
|
|
29994
|
+
const EllipseSwatch = props => {
|
|
29995
|
+
const {
|
|
29996
|
+
color,
|
|
29997
|
+
fillStyle,
|
|
29998
|
+
strokeStyle
|
|
29999
|
+
} = props;
|
|
30000
|
+
return /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, {
|
|
30001
|
+
"aria-label": `${color}, stroke ${strokeStyle}, fill ${fillStyle}`,
|
|
30002
|
+
style: [styles$r.container, {
|
|
30003
|
+
border: `4px ${strokeStyle} ${perseus.lockedFigureColors[color]}`
|
|
30004
|
+
}]
|
|
30005
|
+
}, /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, {
|
|
30006
|
+
style: [styles$r.innerCircle, {
|
|
30007
|
+
backgroundColor: perseus.lockedFigureColors[color],
|
|
30008
|
+
opacity: perseus.lockedFigureFillStyles[fillStyle]
|
|
30009
|
+
}]
|
|
30010
|
+
}));
|
|
30011
|
+
};
|
|
30012
|
+
const styles$r = aphrodite.StyleSheet.create({
|
|
30013
|
+
container: {
|
|
30014
|
+
// Add a white outline so that the color swatch is visible when
|
|
30015
|
+
// the dropdown option is highlighted with its blue background.
|
|
30016
|
+
outline: `2px solid ${wonderBlocksTokens.color.offWhite}`,
|
|
30017
|
+
borderRadius: "50%",
|
|
30018
|
+
width: wonderBlocksTokens.spacing.xLarge_32,
|
|
30019
|
+
height: wonderBlocksTokens.spacing.large_24,
|
|
30020
|
+
backgroundColor: wonderBlocksTokens.color.white,
|
|
30021
|
+
alignItems: "center",
|
|
30022
|
+
justifyContent: "center"
|
|
30212
30023
|
},
|
|
30213
|
-
|
|
30214
|
-
|
|
30215
|
-
|
|
30216
|
-
|
|
30024
|
+
innerCircle: {
|
|
30025
|
+
width: 28,
|
|
30026
|
+
height: 20,
|
|
30027
|
+
borderRadius: "50%"
|
|
30028
|
+
}
|
|
30029
|
+
});
|
|
30030
|
+
|
|
30031
|
+
const LockedFigureSettingsAccordion = props => {
|
|
30032
|
+
const {
|
|
30033
|
+
children,
|
|
30034
|
+
header,
|
|
30035
|
+
expanded,
|
|
30036
|
+
containerStyle,
|
|
30037
|
+
panelStyle,
|
|
30038
|
+
onToggle
|
|
30039
|
+
} = props;
|
|
30040
|
+
return /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View
|
|
30041
|
+
// More specificity so that we can override the default
|
|
30042
|
+
// .heading > h2 > .header styles from the articles.less
|
|
30043
|
+
// file (which is imported in perseus-renderer.less).
|
|
30044
|
+
, {
|
|
30045
|
+
className: "locked-figure-accordion"
|
|
30046
|
+
}, /*#__PURE__*/React__namespace.createElement(wonderBlocksAccordion.AccordionSection, {
|
|
30047
|
+
expanded: expanded,
|
|
30048
|
+
onToggle: onToggle,
|
|
30049
|
+
style: [styles$q.container, containerStyle],
|
|
30050
|
+
headerStyle: styles$q.accordionHeader,
|
|
30051
|
+
header: header
|
|
30052
|
+
}, /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, {
|
|
30053
|
+
style: [styles$q.accordionPanel, panelStyle]
|
|
30054
|
+
}, children)));
|
|
30055
|
+
};
|
|
30056
|
+
const styles$q = aphrodite.StyleSheet.create({
|
|
30057
|
+
container: {
|
|
30058
|
+
backgroundColor: wonderBlocksTokens.color.fadedBlue8,
|
|
30059
|
+
marginTop: wonderBlocksTokens.spacing.xSmall_8
|
|
30217
30060
|
},
|
|
30218
|
-
|
|
30219
|
-
|
|
30220
|
-
|
|
30221
|
-
|
|
30222
|
-
|
|
30061
|
+
accordionHeader: {
|
|
30062
|
+
padding: wonderBlocksTokens.spacing.small_12,
|
|
30063
|
+
// Don't move the dropdown caret.
|
|
30064
|
+
paddingInlineEnd: 0,
|
|
30065
|
+
// Fixed height so the addition of the color swatch doesn't
|
|
30066
|
+
// change the height of the header when toggling.
|
|
30067
|
+
height: wonderBlocksTokens.spacing.xxLarge_48
|
|
30223
30068
|
},
|
|
30224
|
-
|
|
30225
|
-
|
|
30226
|
-
|
|
30227
|
-
|
|
30228
|
-
|
|
30229
|
-
borderBottom: `1px solid ${wonderBlocksTokens.color.offBlack16}`
|
|
30069
|
+
accordionPanel: {
|
|
30070
|
+
paddingTop: wonderBlocksTokens.spacing.xxSmall_6,
|
|
30071
|
+
paddingBottom: wonderBlocksTokens.spacing.xxxSmall_4,
|
|
30072
|
+
paddingLeft: wonderBlocksTokens.spacing.small_12,
|
|
30073
|
+
paddingRight: wonderBlocksTokens.spacing.small_12
|
|
30230
30074
|
}
|
|
30231
30075
|
});
|
|
30232
30076
|
|
|
30233
|
-
|
|
30234
|
-
|
|
30235
|
-
|
|
30236
|
-
|
|
30237
|
-
|
|
30238
|
-
|
|
30239
|
-
|
|
30077
|
+
/**
|
|
30078
|
+
* The part of a locked figure settings panel that contains actions
|
|
30079
|
+
* for this panel and its associated locked figure, including
|
|
30080
|
+
* the delete button.
|
|
30081
|
+
*/
|
|
30082
|
+
const LockedFigureSettingsActions = props => {
|
|
30083
|
+
const {
|
|
30084
|
+
figureType,
|
|
30085
|
+
onMove,
|
|
30086
|
+
onRemove
|
|
30087
|
+
} = props;
|
|
30088
|
+
return /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, {
|
|
30089
|
+
style: styles$p.container
|
|
30090
|
+
}, /*#__PURE__*/React__namespace.createElement(Button__default["default"], {
|
|
30091
|
+
startIcon: trashIcon__default["default"],
|
|
30092
|
+
"aria-label": `Delete locked ${figureType}`,
|
|
30093
|
+
onClick: onRemove,
|
|
30094
|
+
kind: "tertiary",
|
|
30095
|
+
style: styles$p.deleteButton
|
|
30096
|
+
}, "Delete"), /*#__PURE__*/React__namespace.createElement(Spring, null), props.showM2Features && /*#__PURE__*/React__namespace.createElement(React__namespace.Fragment, null, /*#__PURE__*/React__namespace.createElement(IconButton__default["default"], {
|
|
30097
|
+
icon: caretDoubleUpIcon__default["default"],
|
|
30098
|
+
size: "small",
|
|
30099
|
+
"aria-label": `Move locked ${figureType} to the back`,
|
|
30100
|
+
onClick: () => onMove("back"),
|
|
30101
|
+
style: styles$p.iconButton
|
|
30102
|
+
}), /*#__PURE__*/React__namespace.createElement(IconButton__default["default"], {
|
|
30103
|
+
icon: caretUpIcon__default["default"],
|
|
30104
|
+
size: "small",
|
|
30105
|
+
"aria-label": `Move locked ${figureType} backward`,
|
|
30106
|
+
onClick: () => onMove("backward"),
|
|
30107
|
+
style: styles$p.iconButton
|
|
30108
|
+
}), /*#__PURE__*/React__namespace.createElement(IconButton__default["default"], {
|
|
30109
|
+
icon: caretDownIcon__default["default"],
|
|
30110
|
+
size: "small",
|
|
30111
|
+
"aria-label": `Move locked ${figureType} forward`,
|
|
30112
|
+
onClick: () => onMove("forward"),
|
|
30113
|
+
style: styles$p.iconButton
|
|
30114
|
+
}), /*#__PURE__*/React__namespace.createElement(IconButton__default["default"], {
|
|
30115
|
+
icon: caretDoubleDownIcon__default["default"],
|
|
30116
|
+
size: "small",
|
|
30117
|
+
"aria-label": `Move locked ${figureType} to the front`,
|
|
30118
|
+
onClick: () => onMove("front"),
|
|
30119
|
+
style: styles$p.iconButton
|
|
30120
|
+
})));
|
|
30121
|
+
};
|
|
30122
|
+
const styles$p = aphrodite.StyleSheet.create({
|
|
30123
|
+
container: {
|
|
30124
|
+
width: "100%",
|
|
30125
|
+
flexDirection: "row",
|
|
30126
|
+
alignItems: "center",
|
|
30127
|
+
marginTop: wonderBlocksTokens.spacing.xxxSmall_4
|
|
30240
30128
|
},
|
|
30241
|
-
|
|
30242
|
-
|
|
30243
|
-
|
|
30244
|
-
gutterWidth: wonderBlocksTokens.spacing.xLarge_32,
|
|
30245
|
-
marginWidth: wonderBlocksTokens.spacing.large_24
|
|
30129
|
+
deleteButton: {
|
|
30130
|
+
// Line up the delete icon with the rest of the content.
|
|
30131
|
+
marginInlineStart: -wonderBlocksTokens.spacing.xxxSmall_4
|
|
30246
30132
|
},
|
|
30247
|
-
|
|
30248
|
-
|
|
30249
|
-
|
|
30250
|
-
|
|
30251
|
-
|
|
30252
|
-
|
|
30133
|
+
iconButton: {
|
|
30134
|
+
// Reset the margin because the icon buttons
|
|
30135
|
+
// overlap each other otherwise.
|
|
30136
|
+
margin: 0
|
|
30137
|
+
}
|
|
30138
|
+
});
|
|
30139
|
+
|
|
30140
|
+
const {
|
|
30141
|
+
InfoTip: InfoTip$d
|
|
30142
|
+
} = perseus.components;
|
|
30143
|
+
const LockedEllipseSettings = props => {
|
|
30144
|
+
const {
|
|
30145
|
+
center,
|
|
30146
|
+
radius,
|
|
30147
|
+
angle,
|
|
30148
|
+
color,
|
|
30149
|
+
fillStyle,
|
|
30150
|
+
strokeStyle,
|
|
30151
|
+
expanded,
|
|
30152
|
+
onToggle,
|
|
30153
|
+
onChangeProps,
|
|
30154
|
+
onMove,
|
|
30155
|
+
onRemove
|
|
30156
|
+
} = props;
|
|
30157
|
+
function handleColorChange(newValue) {
|
|
30158
|
+
onChangeProps({
|
|
30159
|
+
color: newValue
|
|
30160
|
+
});
|
|
30253
30161
|
}
|
|
30162
|
+
return /*#__PURE__*/React__namespace.createElement(LockedFigureSettingsAccordion, {
|
|
30163
|
+
expanded: expanded,
|
|
30164
|
+
onToggle: onToggle,
|
|
30165
|
+
header:
|
|
30166
|
+
/*#__PURE__*/
|
|
30167
|
+
// Summary: Ellipse, center, radius, color (opacity, dashed)
|
|
30168
|
+
React__namespace.createElement(wonderBlocksCore.View, {
|
|
30169
|
+
style: styles$o.row
|
|
30170
|
+
}, /*#__PURE__*/React__namespace.createElement(wonderBlocksTypography.LabelLarge, null, `Ellipse (${center[0]}, ${center[1]}), radius ${radius[0]}, ${radius[1]}`), /*#__PURE__*/React__namespace.createElement(Strut, {
|
|
30171
|
+
size: wonderBlocksTokens.spacing.xSmall_8
|
|
30172
|
+
}), /*#__PURE__*/React__namespace.createElement(EllipseSwatch, {
|
|
30173
|
+
color: props.color,
|
|
30174
|
+
fillStyle: fillStyle,
|
|
30175
|
+
strokeStyle: strokeStyle
|
|
30176
|
+
}))
|
|
30177
|
+
}, /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, {
|
|
30178
|
+
style: styles$o.row
|
|
30179
|
+
}, /*#__PURE__*/React__namespace.createElement(CoordinatePairInput, {
|
|
30180
|
+
coord: center,
|
|
30181
|
+
style: styles$o.spaceUnder,
|
|
30182
|
+
onChange: newCoords => onChangeProps({
|
|
30183
|
+
center: newCoords
|
|
30184
|
+
})
|
|
30185
|
+
}), /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, {
|
|
30186
|
+
style: styles$o.spaceUnder
|
|
30187
|
+
}, /*#__PURE__*/React__namespace.createElement(InfoTip$d, null, "The coordinates for the center of the ellipse."))), /*#__PURE__*/React__namespace.createElement(CoordinatePairInput, {
|
|
30188
|
+
coord: radius,
|
|
30189
|
+
labels: ["x radius", "y radius"],
|
|
30190
|
+
style: styles$o.spaceUnder,
|
|
30191
|
+
onChange: newCoords => onChangeProps({
|
|
30192
|
+
radius: newCoords
|
|
30193
|
+
})
|
|
30194
|
+
}), /*#__PURE__*/React__namespace.createElement(AngleInput, {
|
|
30195
|
+
angle: angle,
|
|
30196
|
+
onChange: newAngle => onChangeProps({
|
|
30197
|
+
angle: newAngle
|
|
30198
|
+
})
|
|
30199
|
+
}), /*#__PURE__*/React__namespace.createElement(Strut, {
|
|
30200
|
+
size: wonderBlocksTokens.spacing.xSmall_8
|
|
30201
|
+
}), /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, {
|
|
30202
|
+
style: [styles$o.row, styles$o.spaceUnder]
|
|
30203
|
+
}, /*#__PURE__*/React__namespace.createElement(ColorSelect, {
|
|
30204
|
+
selectedValue: color,
|
|
30205
|
+
onChange: handleColorChange
|
|
30206
|
+
}), /*#__PURE__*/React__namespace.createElement(Strut, {
|
|
30207
|
+
size: wonderBlocksTokens.spacing.medium_16
|
|
30208
|
+
}), /*#__PURE__*/React__namespace.createElement(wonderBlocksTypography.LabelMedium, {
|
|
30209
|
+
tag: "label",
|
|
30210
|
+
style: styles$o.row
|
|
30211
|
+
}, "fill", /*#__PURE__*/React__namespace.createElement(Strut, {
|
|
30212
|
+
size: wonderBlocksTokens.spacing.xxSmall_6
|
|
30213
|
+
}), /*#__PURE__*/React__namespace.createElement(wonderBlocksDropdown.SingleSelect, {
|
|
30214
|
+
selectedValue: fillStyle,
|
|
30215
|
+
onChange: value => onChangeProps({
|
|
30216
|
+
fillStyle: value
|
|
30217
|
+
})
|
|
30218
|
+
// Placeholder is required, but never gets used.
|
|
30219
|
+
,
|
|
30220
|
+
placeholder: ""
|
|
30221
|
+
}, Object.keys(perseus.lockedFigureFillStyles).map(option => /*#__PURE__*/React__namespace.createElement(wonderBlocksDropdown.OptionItem, {
|
|
30222
|
+
key: option,
|
|
30223
|
+
value: option,
|
|
30224
|
+
label: option
|
|
30225
|
+
}, option))))), /*#__PURE__*/React__namespace.createElement(wonderBlocksTypography.LabelMedium, {
|
|
30226
|
+
tag: "label",
|
|
30227
|
+
style: styles$o.row
|
|
30228
|
+
}, "stroke", /*#__PURE__*/React__namespace.createElement(Strut, {
|
|
30229
|
+
size: wonderBlocksTokens.spacing.xxSmall_6
|
|
30230
|
+
}), /*#__PURE__*/React__namespace.createElement(wonderBlocksDropdown.SingleSelect, {
|
|
30231
|
+
selectedValue: strokeStyle,
|
|
30232
|
+
onChange: value => onChangeProps({
|
|
30233
|
+
strokeStyle: value
|
|
30234
|
+
})
|
|
30235
|
+
// Placeholder is required, but never gets used.
|
|
30236
|
+
,
|
|
30237
|
+
placeholder: ""
|
|
30238
|
+
}, /*#__PURE__*/React__namespace.createElement(wonderBlocksDropdown.OptionItem, {
|
|
30239
|
+
value: "solid",
|
|
30240
|
+
label: "solid"
|
|
30241
|
+
}, "solid"), /*#__PURE__*/React__namespace.createElement(wonderBlocksDropdown.OptionItem, {
|
|
30242
|
+
value: "dashed",
|
|
30243
|
+
label: "dashed"
|
|
30244
|
+
}, "dashed"))), /*#__PURE__*/React__namespace.createElement(LockedFigureSettingsActions, {
|
|
30245
|
+
showM2Features: props.showM2Features,
|
|
30246
|
+
figureType: props.type,
|
|
30247
|
+
onMove: onMove,
|
|
30248
|
+
onRemove: onRemove
|
|
30249
|
+
}));
|
|
30254
30250
|
};
|
|
30255
|
-
({
|
|
30256
|
-
|
|
30257
|
-
|
|
30258
|
-
|
|
30259
|
-
|
|
30260
|
-
marginWidth: wonderBlocksTokens.spacing.medium_16
|
|
30261
|
-
}
|
|
30262
|
-
});
|
|
30263
|
-
({
|
|
30264
|
-
small: {
|
|
30265
|
-
query: "(max-width: 767px)",
|
|
30266
|
-
totalColumns: 4,
|
|
30267
|
-
gutterWidth: wonderBlocksTokens.spacing.medium_16,
|
|
30268
|
-
marginWidth: wonderBlocksTokens.spacing.medium_16
|
|
30251
|
+
const styles$o = aphrodite.StyleSheet.create({
|
|
30252
|
+
row: {
|
|
30253
|
+
display: "flex",
|
|
30254
|
+
flexDirection: "row",
|
|
30255
|
+
alignItems: "center"
|
|
30269
30256
|
},
|
|
30270
|
-
|
|
30271
|
-
|
|
30272
|
-
totalColumns: 12,
|
|
30273
|
-
gutterWidth: wonderBlocksTokens.spacing.xLarge_32,
|
|
30274
|
-
marginWidth: wonderBlocksTokens.spacing.xxLarge_48
|
|
30257
|
+
spaceUnder: {
|
|
30258
|
+
marginBottom: wonderBlocksTokens.spacing.xSmall_8
|
|
30275
30259
|
}
|
|
30276
30260
|
});
|
|
30277
30261
|
|
|
30278
|
-
const
|
|
30279
|
-
|
|
30280
|
-
|
|
30262
|
+
const LabeledSwitch = props => {
|
|
30263
|
+
const {
|
|
30264
|
+
checked,
|
|
30265
|
+
label,
|
|
30266
|
+
style,
|
|
30267
|
+
onChange
|
|
30268
|
+
} = props;
|
|
30269
|
+
const ids = wonderBlocksCore.useUniqueIdWithMock();
|
|
30270
|
+
const switchId = ids.get("switch");
|
|
30271
|
+
return /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, {
|
|
30272
|
+
style: [styles$n.row, style]
|
|
30273
|
+
}, /*#__PURE__*/React__namespace.createElement(Switch__default["default"], {
|
|
30274
|
+
id: switchId,
|
|
30275
|
+
checked: checked,
|
|
30276
|
+
onChange: onChange
|
|
30277
|
+
}), /*#__PURE__*/React__namespace.createElement(Strut, {
|
|
30278
|
+
size: wonderBlocksTokens.spacing.xSmall_8
|
|
30279
|
+
}), /*#__PURE__*/React__namespace.createElement(wonderBlocksTypography.LabelMedium, {
|
|
30280
|
+
tag: "label",
|
|
30281
|
+
htmlFor: switchId
|
|
30282
|
+
}, label));
|
|
30281
30283
|
};
|
|
30282
|
-
const
|
|
30283
|
-
|
|
30284
|
-
|
|
30285
|
-
|
|
30286
|
-
flexGrow: 1
|
|
30284
|
+
const styles$n = aphrodite.StyleSheet.create({
|
|
30285
|
+
row: {
|
|
30286
|
+
flexDirection: "row",
|
|
30287
|
+
alignItems: "center"
|
|
30287
30288
|
}
|
|
30288
30289
|
});
|
|
30289
30290
|
|
|
30290
|
-
class Strut extends React__namespace.Component {
|
|
30291
|
-
render() {
|
|
30292
|
-
const {
|
|
30293
|
-
size,
|
|
30294
|
-
style
|
|
30295
|
-
} = this.props;
|
|
30296
|
-
return React__namespace.createElement(wonderBlocksCore.View, {
|
|
30297
|
-
"aria-hidden": "true",
|
|
30298
|
-
style: [strutStyle(size), style]
|
|
30299
|
-
});
|
|
30300
|
-
}
|
|
30301
|
-
}
|
|
30302
|
-
const strutStyle = size => {
|
|
30303
|
-
return {
|
|
30304
|
-
width: size,
|
|
30305
|
-
MsFlexBasis: size,
|
|
30306
|
-
MsFlexPreferredSize: size,
|
|
30307
|
-
WebkitFlexBasis: size,
|
|
30308
|
-
flexBasis: size,
|
|
30309
|
-
flexShrink: 0
|
|
30310
|
-
};
|
|
30311
|
-
};
|
|
30312
|
-
|
|
30313
30291
|
/**
|
|
30314
|
-
*
|
|
30315
|
-
*
|
|
30316
|
-
* interactive, just present in the graph's background.
|
|
30292
|
+
* DefiningPointSettings is a component that allows the user to edit the
|
|
30293
|
+
* settings of a point that defines a locked figure (ex. line) on the graph.
|
|
30317
30294
|
*
|
|
30318
30295
|
* Used in the interactive graph editor's locked figures section.
|
|
30319
30296
|
*/
|
|
30320
|
-
const
|
|
30297
|
+
const DefiningPointSettings = props => {
|
|
30321
30298
|
const {
|
|
30322
|
-
|
|
30323
|
-
|
|
30299
|
+
coord,
|
|
30300
|
+
color: pointColor,
|
|
30301
|
+
filled = true,
|
|
30302
|
+
label,
|
|
30303
|
+
showPoint = "false",
|
|
30304
|
+
error,
|
|
30305
|
+
onChangeProps,
|
|
30306
|
+
onTogglePoint,
|
|
30307
|
+
expanded,
|
|
30308
|
+
onToggle
|
|
30324
30309
|
} = props;
|
|
30325
|
-
|
|
30326
|
-
|
|
30327
|
-
|
|
30328
|
-
|
|
30329
|
-
menuText: "Add locked figure",
|
|
30330
|
-
style: styles$r.addElementSelect
|
|
30331
|
-
}, figureTypes.map(figureType => /*#__PURE__*/React__namespace.createElement(wonderBlocksDropdown.ActionItem, {
|
|
30332
|
-
key: `${id}-${figureType}`,
|
|
30333
|
-
label: figureType,
|
|
30334
|
-
onClick: () => onChange(figureType)
|
|
30335
|
-
}, figureType))));
|
|
30336
|
-
};
|
|
30337
|
-
const styles$r = aphrodite.StyleSheet.create({
|
|
30338
|
-
container: {
|
|
30339
|
-
marginTop: wonderBlocksTokens.spacing.xSmall_8
|
|
30340
|
-
},
|
|
30341
|
-
addElementSelect: {
|
|
30342
|
-
backgroundColor: wonderBlocksTokens.color.fadedBlue8,
|
|
30343
|
-
borderRadius: wonderBlocksTokens.spacing.xxxSmall_4
|
|
30310
|
+
function handleColorChange(newValue) {
|
|
30311
|
+
onChangeProps({
|
|
30312
|
+
color: newValue
|
|
30313
|
+
});
|
|
30344
30314
|
}
|
|
30345
|
-
|
|
30346
|
-
|
|
30347
|
-
|
|
30348
|
-
|
|
30349
|
-
|
|
30350
|
-
|
|
30351
|
-
|
|
30352
|
-
|
|
30353
|
-
|
|
30354
|
-
|
|
30355
|
-
|
|
30356
|
-
|
|
30357
|
-
|
|
30358
|
-
|
|
30359
|
-
|
|
30360
|
-
|
|
30361
|
-
|
|
30362
|
-
|
|
30363
|
-
|
|
30364
|
-
|
|
30365
|
-
|
|
30366
|
-
|
|
30367
|
-
|
|
30368
|
-
|
|
30369
|
-
onChange(degreeToRadian(evaluatedAngle));
|
|
30370
|
-
} else {
|
|
30371
|
-
onChange(evaluatedAngle);
|
|
30372
|
-
}
|
|
30373
|
-
} catch (e) {
|
|
30374
|
-
// The user likely has not finished typing the expression.
|
|
30375
|
-
// Do nothing.
|
|
30376
|
-
return;
|
|
30315
|
+
return /*#__PURE__*/React__namespace.createElement(LockedFigureSettingsAccordion, {
|
|
30316
|
+
expanded: expanded,
|
|
30317
|
+
onToggle: onToggle,
|
|
30318
|
+
containerStyle: styles$m.container,
|
|
30319
|
+
panelStyle: styles$m.accordionPanel,
|
|
30320
|
+
header:
|
|
30321
|
+
/*#__PURE__*/
|
|
30322
|
+
// Summary: Point, coords, color (filled/open)
|
|
30323
|
+
React__namespace.createElement(wonderBlocksCore.View, {
|
|
30324
|
+
style: styles$m.row
|
|
30325
|
+
}, /*#__PURE__*/React__namespace.createElement(wonderBlocksTypography.LabelLarge, null, `${label || "Point"} (${coord[0]}, ${coord[1]})`), /*#__PURE__*/React__namespace.createElement(Strut, {
|
|
30326
|
+
size: wonderBlocksTokens.spacing.xSmall_8
|
|
30327
|
+
}), showPoint && /*#__PURE__*/React__namespace.createElement(ColorSwatch, {
|
|
30328
|
+
color: pointColor,
|
|
30329
|
+
filled: filled
|
|
30330
|
+
}))
|
|
30331
|
+
}, /*#__PURE__*/React__namespace.createElement(CoordinatePairInput, {
|
|
30332
|
+
coord: coord,
|
|
30333
|
+
error: !!error,
|
|
30334
|
+
style: styles$m.spaceUnder,
|
|
30335
|
+
onChange: newCoords => {
|
|
30336
|
+
onChangeProps({
|
|
30337
|
+
coord: newCoords
|
|
30338
|
+
});
|
|
30377
30339
|
}
|
|
30378
|
-
}
|
|
30379
|
-
|
|
30380
|
-
|
|
30381
|
-
|
|
30382
|
-
|
|
30383
|
-
|
|
30384
|
-
|
|
30385
|
-
|
|
30386
|
-
|
|
30387
|
-
|
|
30388
|
-
|
|
30389
|
-
|
|
30390
|
-
|
|
30391
|
-
|
|
30392
|
-
|
|
30393
|
-
|
|
30394
|
-
|
|
30395
|
-
|
|
30396
|
-
style: styles$q.textField
|
|
30397
|
-
})), /*#__PURE__*/React__namespace.createElement(Strut, {
|
|
30398
|
-
size: wonderBlocksTokens.spacing.xxSmall_6
|
|
30399
|
-
}), /*#__PURE__*/React__namespace.createElement(wonderBlocksTypography.LabelSmall, null, "radians"), /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, {
|
|
30400
|
-
style: styles$q.switch
|
|
30401
|
-
}, /*#__PURE__*/React__namespace.createElement(Switch__default["default"], {
|
|
30402
|
-
onChange: handleAngleTypeChange,
|
|
30403
|
-
checked: isInDegrees
|
|
30404
|
-
})), /*#__PURE__*/React__namespace.createElement(wonderBlocksTypography.LabelSmall, null, "degrees"), /*#__PURE__*/React__namespace.createElement(InfoTip$d, null, /*#__PURE__*/React__namespace.createElement("p", null, "The angle of rotation for the ellipse (if the x radius and y radius are different)."), /*#__PURE__*/React__namespace.createElement("p", null, "Expressions will be evaluted (e.g. \"pi/2\" or \"5pi/4\").")));
|
|
30340
|
+
}), onTogglePoint && /*#__PURE__*/React__namespace.createElement(LabeledSwitch, {
|
|
30341
|
+
label: "show point on graph",
|
|
30342
|
+
checked: !!showPoint,
|
|
30343
|
+
style: showPoint && styles$m.spaceUnder,
|
|
30344
|
+
onChange: onTogglePoint
|
|
30345
|
+
}), showPoint && /*#__PURE__*/React__namespace.createElement(React__namespace.Fragment, null, /*#__PURE__*/React__namespace.createElement(ColorSelect, {
|
|
30346
|
+
selectedValue: pointColor,
|
|
30347
|
+
onChange: handleColorChange,
|
|
30348
|
+
style: styles$m.spaceUnder
|
|
30349
|
+
}), /*#__PURE__*/React__namespace.createElement(LabeledSwitch, {
|
|
30350
|
+
label: "open point",
|
|
30351
|
+
checked: !filled,
|
|
30352
|
+
onChange: newValue => {
|
|
30353
|
+
onChangeProps({
|
|
30354
|
+
filled: !newValue
|
|
30355
|
+
});
|
|
30356
|
+
}
|
|
30357
|
+
})));
|
|
30405
30358
|
};
|
|
30406
|
-
const styles$
|
|
30359
|
+
const styles$m = aphrodite.StyleSheet.create({
|
|
30360
|
+
container: {
|
|
30361
|
+
marginTop: wonderBlocksTokens.spacing.xSmall_8,
|
|
30362
|
+
marginBottom: 0,
|
|
30363
|
+
marginLeft: -wonderBlocksTokens.spacing.xxxSmall_4,
|
|
30364
|
+
marginRight: -wonderBlocksTokens.spacing.xxxSmall_4,
|
|
30365
|
+
backgroundColor: wonderBlocksTokens.color.white
|
|
30366
|
+
},
|
|
30367
|
+
accordionPanel: {
|
|
30368
|
+
// Need more space since we don't have the actions' margins.
|
|
30369
|
+
paddingBottom: wonderBlocksTokens.spacing.medium_16
|
|
30370
|
+
},
|
|
30407
30371
|
row: {
|
|
30408
|
-
display: "flex",
|
|
30409
30372
|
flexDirection: "row",
|
|
30410
30373
|
alignItems: "center"
|
|
30411
30374
|
},
|
|
30412
|
-
|
|
30413
|
-
|
|
30414
|
-
marginRight: wonderBlocksTokens.spacing.xxSmall_6
|
|
30415
|
-
},
|
|
30416
|
-
textField: {
|
|
30417
|
-
maxWidth: wonderBlocksTokens.spacing.xxxLarge_64
|
|
30375
|
+
spaceUnder: {
|
|
30376
|
+
marginBottom: wonderBlocksTokens.spacing.xSmall_8
|
|
30418
30377
|
}
|
|
30419
30378
|
});
|
|
30420
30379
|
|
|
30421
|
-
const
|
|
30380
|
+
const LineSwatch = props => {
|
|
30422
30381
|
const {
|
|
30423
30382
|
color,
|
|
30424
|
-
|
|
30425
|
-
decorative = false
|
|
30383
|
+
lineStyle
|
|
30426
30384
|
} = props;
|
|
30427
30385
|
return /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, {
|
|
30428
|
-
|
|
30429
|
-
|
|
30430
|
-
|
|
30431
|
-
style: [styles$
|
|
30432
|
-
border: `
|
|
30433
|
-
backgroundColor: filled ? perseus.lockedFigureColors[color] : wonderBlocksTokens.color.white
|
|
30386
|
+
style: styles$l.container
|
|
30387
|
+
}, /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, {
|
|
30388
|
+
"aria-label": `${color}, ${lineStyle}`,
|
|
30389
|
+
style: [styles$l.lineSwatch, {
|
|
30390
|
+
border: `5px ${lineStyle} ${perseus.lockedFigureColors[color]}`
|
|
30434
30391
|
}]
|
|
30435
|
-
});
|
|
30392
|
+
}));
|
|
30436
30393
|
};
|
|
30437
|
-
const styles$
|
|
30438
|
-
|
|
30439
|
-
|
|
30440
|
-
|
|
30441
|
-
|
|
30442
|
-
borderRadius:
|
|
30443
|
-
|
|
30444
|
-
|
|
30394
|
+
const styles$l = aphrodite.StyleSheet.create({
|
|
30395
|
+
container: {
|
|
30396
|
+
backgroundColor: wonderBlocksTokens.color.white,
|
|
30397
|
+
justifyContent: "center",
|
|
30398
|
+
padding: wonderBlocksTokens.spacing.xSmall_8,
|
|
30399
|
+
borderRadius: wonderBlocksTokens.spacing.xxxSmall_4
|
|
30400
|
+
},
|
|
30401
|
+
lineSwatch: {
|
|
30402
|
+
width: 40
|
|
30445
30403
|
}
|
|
30446
30404
|
});
|
|
30447
30405
|
|
|
30448
|
-
const
|
|
30449
|
-
const
|
|
30406
|
+
const lengthZeroStr = "The line cannot have length 0.";
|
|
30407
|
+
const LockedLineSettings = props => {
|
|
30450
30408
|
const {
|
|
30451
|
-
|
|
30452
|
-
|
|
30453
|
-
|
|
30409
|
+
kind,
|
|
30410
|
+
points,
|
|
30411
|
+
color: lineColor,
|
|
30412
|
+
lineStyle = "solid",
|
|
30413
|
+
showPoint1,
|
|
30414
|
+
showPoint2,
|
|
30415
|
+
onChangeProps,
|
|
30416
|
+
onMove,
|
|
30417
|
+
onRemove
|
|
30454
30418
|
} = props;
|
|
30455
|
-
|
|
30456
|
-
|
|
30419
|
+
const [point1, point2] = points;
|
|
30420
|
+
const capitalizeKind = kind.charAt(0).toUpperCase() + kind.slice(1);
|
|
30421
|
+
const lineLabel = `${capitalizeKind} (${point1.coord[0]},
|
|
30422
|
+
${point1.coord[1]}), (${point2.coord[0]}, ${point2.coord[1]})`;
|
|
30423
|
+
|
|
30424
|
+
// Check if the line has length 0.
|
|
30425
|
+
const isInvalid = kmath.vector.equal(point1.coord, point2.coord);
|
|
30426
|
+
function handleChangePoint(newPointProps, index) {
|
|
30427
|
+
const newPoints = [...points];
|
|
30428
|
+
newPoints[index] = {
|
|
30429
|
+
...points[index],
|
|
30430
|
+
...newPointProps
|
|
30431
|
+
};
|
|
30432
|
+
onChangeProps({
|
|
30433
|
+
points: newPoints
|
|
30434
|
+
});
|
|
30435
|
+
}
|
|
30436
|
+
function handleColorChange(newColor) {
|
|
30437
|
+
onChangeProps({
|
|
30438
|
+
color: newColor,
|
|
30439
|
+
// Keep the line's points' colors in sync with the line color.
|
|
30440
|
+
points: [{
|
|
30441
|
+
...point1,
|
|
30442
|
+
color: newColor
|
|
30443
|
+
}, {
|
|
30444
|
+
...point2,
|
|
30445
|
+
color: newColor
|
|
30446
|
+
}]
|
|
30447
|
+
});
|
|
30448
|
+
}
|
|
30449
|
+
return /*#__PURE__*/React__namespace.createElement(LockedFigureSettingsAccordion, {
|
|
30450
|
+
expanded: props.expanded,
|
|
30451
|
+
onToggle: props.onToggle,
|
|
30452
|
+
header: /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, {
|
|
30453
|
+
style: styles$k.row
|
|
30454
|
+
}, /*#__PURE__*/React__namespace.createElement(wonderBlocksTypography.LabelLarge, null, lineLabel), /*#__PURE__*/React__namespace.createElement(Strut, {
|
|
30455
|
+
size: wonderBlocksTokens.spacing.xSmall_8
|
|
30456
|
+
}), /*#__PURE__*/React__namespace.createElement(LineSwatch, {
|
|
30457
|
+
color: lineColor,
|
|
30458
|
+
lineStyle: lineStyle
|
|
30459
|
+
}))
|
|
30457
30460
|
}, /*#__PURE__*/React__namespace.createElement(wonderBlocksTypography.LabelMedium, {
|
|
30458
30461
|
tag: "label",
|
|
30459
|
-
style: styles$
|
|
30460
|
-
}, "
|
|
30461
|
-
size: wonderBlocksTokens.spacing.
|
|
30462
|
+
style: [styles$k.row, styles$k.spaceUnder]
|
|
30463
|
+
}, "kind", /*#__PURE__*/React__namespace.createElement(Strut, {
|
|
30464
|
+
size: wonderBlocksTokens.spacing.xxxSmall_4
|
|
30462
30465
|
}), /*#__PURE__*/React__namespace.createElement(wonderBlocksDropdown.SingleSelect, {
|
|
30463
|
-
selectedValue:
|
|
30464
|
-
onChange:
|
|
30466
|
+
selectedValue: kind,
|
|
30467
|
+
onChange: value => onChangeProps({
|
|
30468
|
+
kind: value
|
|
30469
|
+
})
|
|
30465
30470
|
// Placeholder is required, but never gets used.
|
|
30466
30471
|
,
|
|
30467
30472
|
placeholder: ""
|
|
30468
|
-
},
|
|
30469
|
-
|
|
30470
|
-
|
|
30471
|
-
|
|
30472
|
-
|
|
30473
|
-
|
|
30474
|
-
|
|
30473
|
+
}, /*#__PURE__*/React__namespace.createElement(wonderBlocksDropdown.OptionItem, {
|
|
30474
|
+
value: "line",
|
|
30475
|
+
label: "line"
|
|
30476
|
+
}), /*#__PURE__*/React__namespace.createElement(wonderBlocksDropdown.OptionItem, {
|
|
30477
|
+
value: "ray",
|
|
30478
|
+
label: "ray"
|
|
30479
|
+
}), /*#__PURE__*/React__namespace.createElement(wonderBlocksDropdown.OptionItem, {
|
|
30480
|
+
value: "segment",
|
|
30481
|
+
label: "segment"
|
|
30482
|
+
}))), /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, {
|
|
30483
|
+
style: styles$k.row
|
|
30484
|
+
}, /*#__PURE__*/React__namespace.createElement(ColorSelect, {
|
|
30485
|
+
selectedValue: lineColor,
|
|
30486
|
+
onChange: handleColorChange
|
|
30487
|
+
}), /*#__PURE__*/React__namespace.createElement(Strut, {
|
|
30488
|
+
size: wonderBlocksTokens.spacing.small_12
|
|
30489
|
+
}), /*#__PURE__*/React__namespace.createElement(wonderBlocksTypography.LabelMedium, {
|
|
30490
|
+
tag: "label",
|
|
30491
|
+
style: styles$k.row
|
|
30492
|
+
}, "style", /*#__PURE__*/React__namespace.createElement(Strut, {
|
|
30493
|
+
size: wonderBlocksTokens.spacing.xxxSmall_4
|
|
30494
|
+
}), /*#__PURE__*/React__namespace.createElement(wonderBlocksDropdown.SingleSelect, {
|
|
30495
|
+
selectedValue: lineStyle,
|
|
30496
|
+
onChange: value => onChangeProps({
|
|
30497
|
+
lineStyle: value
|
|
30475
30498
|
})
|
|
30476
|
-
|
|
30499
|
+
// Placeholder is required, but never gets used.
|
|
30500
|
+
,
|
|
30501
|
+
placeholder: "",
|
|
30502
|
+
style: styles$k.selectMarginOffset
|
|
30503
|
+
}, /*#__PURE__*/React__namespace.createElement(wonderBlocksDropdown.OptionItem, {
|
|
30504
|
+
value: "solid",
|
|
30505
|
+
label: "solid"
|
|
30506
|
+
}), /*#__PURE__*/React__namespace.createElement(wonderBlocksDropdown.OptionItem, {
|
|
30507
|
+
value: "dashed",
|
|
30508
|
+
label: "dashed"
|
|
30509
|
+
})))), isInvalid && /*#__PURE__*/React__namespace.createElement(wonderBlocksTypography.LabelMedium, {
|
|
30510
|
+
style: styles$k.errorText
|
|
30511
|
+
}, lengthZeroStr), /*#__PURE__*/React__namespace.createElement(DefiningPointSettings, _extends({
|
|
30512
|
+
label: "Point 1",
|
|
30513
|
+
showPoint: showPoint1,
|
|
30514
|
+
error: isInvalid ? lengthZeroStr : null
|
|
30515
|
+
}, point1, {
|
|
30516
|
+
onTogglePoint: newValue => onChangeProps({
|
|
30517
|
+
showPoint1: newValue
|
|
30518
|
+
}),
|
|
30519
|
+
onChangeProps: newProps => handleChangePoint(newProps, 0)
|
|
30520
|
+
})), /*#__PURE__*/React__namespace.createElement(DefiningPointSettings, _extends({
|
|
30521
|
+
label: "Point 2",
|
|
30522
|
+
showPoint: showPoint2,
|
|
30523
|
+
error: isInvalid ? lengthZeroStr : null
|
|
30524
|
+
}, point2, {
|
|
30525
|
+
onTogglePoint: newValue => onChangeProps({
|
|
30526
|
+
showPoint2: newValue
|
|
30527
|
+
}),
|
|
30528
|
+
onChangeProps: newProps => handleChangePoint(newProps, 1)
|
|
30529
|
+
})), /*#__PURE__*/React__namespace.createElement(LockedFigureSettingsActions, {
|
|
30530
|
+
showM2Features: props.showM2Features,
|
|
30531
|
+
figureType: props.type,
|
|
30532
|
+
onMove: onMove,
|
|
30533
|
+
onRemove: onRemove
|
|
30534
|
+
}));
|
|
30477
30535
|
};
|
|
30478
|
-
const styles$
|
|
30536
|
+
const styles$k = aphrodite.StyleSheet.create({
|
|
30479
30537
|
row: {
|
|
30480
30538
|
display: "flex",
|
|
30481
30539
|
flexDirection: "row",
|
|
30482
30540
|
alignItems: "center"
|
|
30541
|
+
},
|
|
30542
|
+
spaceUnder: {
|
|
30543
|
+
marginBottom: wonderBlocksTokens.spacing.xSmall_8
|
|
30544
|
+
},
|
|
30545
|
+
selectMarginOffset: {
|
|
30546
|
+
// Align with the point settings accordions.
|
|
30547
|
+
marginInlineEnd: -wonderBlocksTokens.spacing.xxxSmall_4
|
|
30548
|
+
},
|
|
30549
|
+
errorText: {
|
|
30550
|
+
color: wonderBlocksTokens.color.red
|
|
30483
30551
|
}
|
|
30484
30552
|
});
|
|
30485
30553
|
|
|
30486
|
-
|
|
30554
|
+
/**
|
|
30555
|
+
* LockedPointSettings is a component that allows the user to edit the
|
|
30556
|
+
* settings of specifically a locked point on the graph.
|
|
30557
|
+
*
|
|
30558
|
+
* Used in the interactive graph editor's locked figures section.
|
|
30559
|
+
*/
|
|
30560
|
+
const LockedPointSettings = props => {
|
|
30487
30561
|
const {
|
|
30488
30562
|
coord,
|
|
30489
|
-
|
|
30490
|
-
|
|
30491
|
-
|
|
30563
|
+
color: pointColor,
|
|
30564
|
+
filled = true,
|
|
30565
|
+
onChangeProps,
|
|
30566
|
+
onMove,
|
|
30567
|
+
onRemove
|
|
30492
30568
|
} = props;
|
|
30493
|
-
|
|
30494
|
-
|
|
30495
|
-
|
|
30496
|
-
|
|
30497
|
-
// Using strings to make it easier to work with the text fields.
|
|
30498
|
-
coord[0].toString(), coord[1].toString()]);
|
|
30499
|
-
function handleCoordChange(newValue, coordIndex) {
|
|
30500
|
-
// Update the local state (update the input field value).
|
|
30501
|
-
const newCoordState = [...coordState];
|
|
30502
|
-
newCoordState[coordIndex] = newValue;
|
|
30503
|
-
setCoordState(newCoordState);
|
|
30504
|
-
|
|
30505
|
-
// If the new value is not a number, don't update the props.
|
|
30506
|
-
// If it's empty, keep the props the same value instead of setting to 0.
|
|
30507
|
-
if (isNaN(+newValue) || newValue === "") {
|
|
30508
|
-
return;
|
|
30509
|
-
}
|
|
30510
|
-
|
|
30511
|
-
// Update the props (update the graph).
|
|
30512
|
-
const newCoords = [...coord];
|
|
30513
|
-
newCoords[coordIndex] = +newValue;
|
|
30514
|
-
onChange(newCoords);
|
|
30569
|
+
function handleColorChange(newValue) {
|
|
30570
|
+
onChangeProps({
|
|
30571
|
+
color: newValue
|
|
30572
|
+
});
|
|
30515
30573
|
}
|
|
30516
|
-
return /*#__PURE__*/React__namespace.createElement(
|
|
30517
|
-
|
|
30518
|
-
|
|
30519
|
-
|
|
30520
|
-
|
|
30521
|
-
|
|
30522
|
-
|
|
30523
|
-
|
|
30524
|
-
|
|
30525
|
-
|
|
30526
|
-
|
|
30527
|
-
|
|
30528
|
-
|
|
30529
|
-
|
|
30530
|
-
}
|
|
30531
|
-
|
|
30532
|
-
style: styles$
|
|
30533
|
-
|
|
30534
|
-
|
|
30535
|
-
|
|
30536
|
-
|
|
30537
|
-
|
|
30538
|
-
|
|
30539
|
-
|
|
30540
|
-
|
|
30574
|
+
return /*#__PURE__*/React__namespace.createElement(LockedFigureSettingsAccordion, {
|
|
30575
|
+
expanded: props.expanded,
|
|
30576
|
+
onToggle: props.onToggle,
|
|
30577
|
+
header:
|
|
30578
|
+
/*#__PURE__*/
|
|
30579
|
+
// Summary: Point, coords, color (filled/open)
|
|
30580
|
+
React__namespace.createElement(wonderBlocksCore.View, {
|
|
30581
|
+
style: styles$j.row
|
|
30582
|
+
}, /*#__PURE__*/React__namespace.createElement(wonderBlocksTypography.LabelLarge, null, `Point (${coord[0]}, ${coord[1]})`), /*#__PURE__*/React__namespace.createElement(Strut, {
|
|
30583
|
+
size: wonderBlocksTokens.spacing.xSmall_8
|
|
30584
|
+
}), /*#__PURE__*/React__namespace.createElement(ColorSwatch, {
|
|
30585
|
+
color: pointColor,
|
|
30586
|
+
filled: filled
|
|
30587
|
+
}))
|
|
30588
|
+
}, /*#__PURE__*/React__namespace.createElement(CoordinatePairInput, {
|
|
30589
|
+
coord: coord,
|
|
30590
|
+
style: styles$j.spaceUnder,
|
|
30591
|
+
onChange: newCoord => {
|
|
30592
|
+
onChangeProps({
|
|
30593
|
+
coord: newCoord
|
|
30594
|
+
});
|
|
30595
|
+
}
|
|
30596
|
+
}), /*#__PURE__*/React__namespace.createElement(ColorSelect, {
|
|
30597
|
+
selectedValue: pointColor,
|
|
30598
|
+
onChange: handleColorChange,
|
|
30599
|
+
style: styles$j.spaceUnder
|
|
30600
|
+
}), /*#__PURE__*/React__namespace.createElement(LabeledSwitch, {
|
|
30601
|
+
label: "open point",
|
|
30602
|
+
checked: !filled,
|
|
30603
|
+
onChange: newValue => {
|
|
30604
|
+
onChangeProps({
|
|
30605
|
+
filled: !newValue
|
|
30606
|
+
});
|
|
30607
|
+
}
|
|
30608
|
+
}), /*#__PURE__*/React__namespace.createElement(LockedFigureSettingsActions, {
|
|
30609
|
+
showM2Features: props.showM2Features,
|
|
30610
|
+
figureType: props.type,
|
|
30611
|
+
onMove: onMove,
|
|
30612
|
+
onRemove: onRemove
|
|
30613
|
+
}));
|
|
30541
30614
|
};
|
|
30542
|
-
const styles$
|
|
30615
|
+
const styles$j = aphrodite.StyleSheet.create({
|
|
30543
30616
|
row: {
|
|
30544
|
-
display: "flex",
|
|
30545
30617
|
flexDirection: "row",
|
|
30546
30618
|
alignItems: "center"
|
|
30547
30619
|
},
|
|
30548
30620
|
spaceUnder: {
|
|
30549
30621
|
marginBottom: wonderBlocksTokens.spacing.xSmall_8
|
|
30550
|
-
},
|
|
30551
|
-
textField: {
|
|
30552
|
-
width: wonderBlocksTokens.spacing.xxxLarge_64
|
|
30553
|
-
},
|
|
30554
|
-
errorField: {
|
|
30555
|
-
borderColor: wonderBlocksTokens.color.red,
|
|
30556
|
-
backgroundColor: wonderBlocksTokens.color.fadedRed8
|
|
30557
30622
|
}
|
|
30558
30623
|
});
|
|
30559
30624
|
|
|
30560
|
-
const
|
|
30625
|
+
const PolygonSwatch = props => {
|
|
30561
30626
|
const {
|
|
30562
30627
|
color,
|
|
30563
30628
|
fillStyle,
|
|
@@ -30565,128 +30630,44 @@ const EllipseSwatch = props => {
|
|
|
30565
30630
|
} = props;
|
|
30566
30631
|
return /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, {
|
|
30567
30632
|
"aria-label": `${color}, stroke ${strokeStyle}, fill ${fillStyle}`,
|
|
30568
|
-
style: [styles$
|
|
30633
|
+
style: [styles$i.container, {
|
|
30569
30634
|
border: `4px ${strokeStyle} ${perseus.lockedFigureColors[color]}`
|
|
30570
30635
|
}]
|
|
30571
30636
|
}, /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, {
|
|
30572
|
-
style: [styles$
|
|
30637
|
+
style: [styles$i.innerSquare, {
|
|
30573
30638
|
backgroundColor: perseus.lockedFigureColors[color],
|
|
30574
|
-
opacity: perseus.
|
|
30639
|
+
opacity: perseus.lockedFigureFillStyles[fillStyle]
|
|
30575
30640
|
}]
|
|
30576
30641
|
}));
|
|
30577
30642
|
};
|
|
30578
|
-
const styles$
|
|
30643
|
+
const styles$i = aphrodite.StyleSheet.create({
|
|
30579
30644
|
container: {
|
|
30580
30645
|
// Add a white outline so that the color swatch is visible when
|
|
30581
30646
|
// the dropdown option is highlighted with its blue background.
|
|
30582
30647
|
outline: `2px solid ${wonderBlocksTokens.color.offWhite}`,
|
|
30583
|
-
|
|
30584
|
-
width: wonderBlocksTokens.spacing.xLarge_32,
|
|
30648
|
+
width: wonderBlocksTokens.spacing.large_24,
|
|
30585
30649
|
height: wonderBlocksTokens.spacing.large_24,
|
|
30586
30650
|
backgroundColor: wonderBlocksTokens.color.white,
|
|
30587
30651
|
alignItems: "center",
|
|
30588
30652
|
justifyContent: "center"
|
|
30589
30653
|
},
|
|
30590
|
-
|
|
30591
|
-
width:
|
|
30592
|
-
height: 20
|
|
30593
|
-
borderRadius: "50%"
|
|
30594
|
-
}
|
|
30595
|
-
});
|
|
30596
|
-
|
|
30597
|
-
const LockedFigureSettingsAccordion = props => {
|
|
30598
|
-
const {
|
|
30599
|
-
children,
|
|
30600
|
-
header,
|
|
30601
|
-
expanded,
|
|
30602
|
-
containerStyle,
|
|
30603
|
-
panelStyle,
|
|
30604
|
-
onToggle
|
|
30605
|
-
} = props;
|
|
30606
|
-
return /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View
|
|
30607
|
-
// More specificity so that we can override the default
|
|
30608
|
-
// .heading > h2 > .header styles from the articles.less
|
|
30609
|
-
// file (which is imported in perseus-renderer.less).
|
|
30610
|
-
, {
|
|
30611
|
-
className: "locked-figure-accordion"
|
|
30612
|
-
}, /*#__PURE__*/React__namespace.createElement(wonderBlocksAccordion.AccordionSection, {
|
|
30613
|
-
expanded: expanded,
|
|
30614
|
-
onToggle: onToggle,
|
|
30615
|
-
style: [styles$l.container, containerStyle],
|
|
30616
|
-
headerStyle: styles$l.accordionHeader,
|
|
30617
|
-
header: header
|
|
30618
|
-
}, /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, {
|
|
30619
|
-
style: [styles$l.accordionPanel, panelStyle]
|
|
30620
|
-
}, children)));
|
|
30621
|
-
};
|
|
30622
|
-
const styles$l = aphrodite.StyleSheet.create({
|
|
30623
|
-
container: {
|
|
30624
|
-
backgroundColor: wonderBlocksTokens.color.fadedBlue8,
|
|
30625
|
-
marginTop: wonderBlocksTokens.spacing.xSmall_8
|
|
30626
|
-
},
|
|
30627
|
-
accordionHeader: {
|
|
30628
|
-
padding: wonderBlocksTokens.spacing.small_12,
|
|
30629
|
-
// Don't move the dropdown caret.
|
|
30630
|
-
paddingInlineEnd: 0,
|
|
30631
|
-
// Fixed height so the addition of the color swatch doesn't
|
|
30632
|
-
// change the height of the header when toggling.
|
|
30633
|
-
height: wonderBlocksTokens.spacing.xxLarge_48
|
|
30634
|
-
},
|
|
30635
|
-
accordionPanel: {
|
|
30636
|
-
paddingTop: wonderBlocksTokens.spacing.xxSmall_6,
|
|
30637
|
-
paddingBottom: wonderBlocksTokens.spacing.xxxSmall_4,
|
|
30638
|
-
paddingLeft: wonderBlocksTokens.spacing.small_12,
|
|
30639
|
-
paddingRight: wonderBlocksTokens.spacing.small_12
|
|
30640
|
-
}
|
|
30641
|
-
});
|
|
30642
|
-
|
|
30643
|
-
/**
|
|
30644
|
-
* The part of a locked figure settings panel that contains actions
|
|
30645
|
-
* for this panel and its associated locked figure, including
|
|
30646
|
-
* the delete button.
|
|
30647
|
-
*/
|
|
30648
|
-
const LockedFigureSettingsActions = props => {
|
|
30649
|
-
const {
|
|
30650
|
-
onRemove,
|
|
30651
|
-
figureAriaLabel
|
|
30652
|
-
} = props;
|
|
30653
|
-
return /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, {
|
|
30654
|
-
style: styles$k.container
|
|
30655
|
-
}, /*#__PURE__*/React__namespace.createElement(Button__default["default"], {
|
|
30656
|
-
startIcon: trashIcon__default["default"],
|
|
30657
|
-
"aria-label": `Delete ${figureAriaLabel}`,
|
|
30658
|
-
onClick: onRemove,
|
|
30659
|
-
kind: "tertiary",
|
|
30660
|
-
style: styles$k.deleteButton
|
|
30661
|
-
}, "Delete"));
|
|
30662
|
-
};
|
|
30663
|
-
const styles$k = aphrodite.StyleSheet.create({
|
|
30664
|
-
container: {
|
|
30665
|
-
width: "100%",
|
|
30666
|
-
flexDirection: "row",
|
|
30667
|
-
alignItems: "center",
|
|
30668
|
-
marginTop: wonderBlocksTokens.spacing.xxxSmall_4
|
|
30669
|
-
},
|
|
30670
|
-
deleteButton: {
|
|
30671
|
-
// Line up the delete icon with the rest of the content.
|
|
30672
|
-
marginInlineStart: -wonderBlocksTokens.spacing.xxxSmall_4
|
|
30654
|
+
innerSquare: {
|
|
30655
|
+
width: 20,
|
|
30656
|
+
height: 20
|
|
30673
30657
|
}
|
|
30674
30658
|
});
|
|
30675
30659
|
|
|
30676
|
-
const {
|
|
30677
|
-
InfoTip: InfoTip$c
|
|
30678
|
-
} = perseus.components;
|
|
30679
|
-
const LockedEllipseSettings = props => {
|
|
30660
|
+
const LockedPolygonSettings = props => {
|
|
30680
30661
|
const {
|
|
30681
|
-
|
|
30682
|
-
radius,
|
|
30683
|
-
angle,
|
|
30662
|
+
points,
|
|
30684
30663
|
color,
|
|
30664
|
+
showVertices,
|
|
30685
30665
|
fillStyle,
|
|
30686
30666
|
strokeStyle,
|
|
30687
30667
|
expanded,
|
|
30688
30668
|
onToggle,
|
|
30689
30669
|
onChangeProps,
|
|
30670
|
+
onMove,
|
|
30690
30671
|
onRemove
|
|
30691
30672
|
} = props;
|
|
30692
30673
|
function handleColorChange(newValue) {
|
|
@@ -30699,40 +30680,18 @@ const LockedEllipseSettings = props => {
|
|
|
30699
30680
|
onToggle: onToggle,
|
|
30700
30681
|
header:
|
|
30701
30682
|
/*#__PURE__*/
|
|
30702
|
-
// Summary:
|
|
30683
|
+
// Summary: Polygon, number of sides, style swatch
|
|
30703
30684
|
React__namespace.createElement(wonderBlocksCore.View, {
|
|
30704
|
-
style: styles$
|
|
30705
|
-
}, /*#__PURE__*/React__namespace.createElement(wonderBlocksTypography.LabelLarge, null, `
|
|
30685
|
+
style: styles$h.row
|
|
30686
|
+
}, /*#__PURE__*/React__namespace.createElement(wonderBlocksTypography.LabelLarge, null, `Polygon, ${points.length} sides`), /*#__PURE__*/React__namespace.createElement(Strut, {
|
|
30706
30687
|
size: wonderBlocksTokens.spacing.xSmall_8
|
|
30707
|
-
}), /*#__PURE__*/React__namespace.createElement(
|
|
30708
|
-
color:
|
|
30688
|
+
}), /*#__PURE__*/React__namespace.createElement(PolygonSwatch, {
|
|
30689
|
+
color: color,
|
|
30709
30690
|
fillStyle: fillStyle,
|
|
30710
30691
|
strokeStyle: strokeStyle
|
|
30711
30692
|
}))
|
|
30712
30693
|
}, /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, {
|
|
30713
|
-
style: styles$
|
|
30714
|
-
}, /*#__PURE__*/React__namespace.createElement(CoordinatePairInput, {
|
|
30715
|
-
coord: center,
|
|
30716
|
-
onChange: newCoords => onChangeProps({
|
|
30717
|
-
center: newCoords
|
|
30718
|
-
})
|
|
30719
|
-
}), /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, {
|
|
30720
|
-
style: styles$j.spaceUnder
|
|
30721
|
-
}, /*#__PURE__*/React__namespace.createElement(InfoTip$c, null, "The coordinates for the center of the ellipse."))), /*#__PURE__*/React__namespace.createElement(CoordinatePairInput, {
|
|
30722
|
-
coord: radius,
|
|
30723
|
-
labels: ["x radius", "y radius"],
|
|
30724
|
-
onChange: newCoords => onChangeProps({
|
|
30725
|
-
radius: newCoords
|
|
30726
|
-
})
|
|
30727
|
-
}), /*#__PURE__*/React__namespace.createElement(AngleInput, {
|
|
30728
|
-
angle: angle,
|
|
30729
|
-
onChange: newAngle => onChangeProps({
|
|
30730
|
-
angle: newAngle
|
|
30731
|
-
})
|
|
30732
|
-
}), /*#__PURE__*/React__namespace.createElement(Strut, {
|
|
30733
|
-
size: wonderBlocksTokens.spacing.xSmall_8
|
|
30734
|
-
}), /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, {
|
|
30735
|
-
style: [styles$j.row, styles$j.spaceUnder]
|
|
30694
|
+
style: [styles$h.row, styles$h.spaceUnder]
|
|
30736
30695
|
}, /*#__PURE__*/React__namespace.createElement(ColorSelect, {
|
|
30737
30696
|
selectedValue: color,
|
|
30738
30697
|
onChange: handleColorChange
|
|
@@ -30740,7 +30699,7 @@ const LockedEllipseSettings = props => {
|
|
|
30740
30699
|
size: wonderBlocksTokens.spacing.medium_16
|
|
30741
30700
|
}), /*#__PURE__*/React__namespace.createElement(wonderBlocksTypography.LabelMedium, {
|
|
30742
30701
|
tag: "label",
|
|
30743
|
-
style: styles$
|
|
30702
|
+
style: styles$h.row
|
|
30744
30703
|
}, "fill", /*#__PURE__*/React__namespace.createElement(Strut, {
|
|
30745
30704
|
size: wonderBlocksTokens.spacing.xxSmall_6
|
|
30746
30705
|
}), /*#__PURE__*/React__namespace.createElement(wonderBlocksDropdown.SingleSelect, {
|
|
@@ -30751,13 +30710,13 @@ const LockedEllipseSettings = props => {
|
|
|
30751
30710
|
// Placeholder is required, but never gets used.
|
|
30752
30711
|
,
|
|
30753
30712
|
placeholder: ""
|
|
30754
|
-
}, Object.keys(perseus.
|
|
30713
|
+
}, Object.keys(perseus.lockedFigureFillStyles).map(option => /*#__PURE__*/React__namespace.createElement(wonderBlocksDropdown.OptionItem, {
|
|
30755
30714
|
key: option,
|
|
30756
30715
|
value: option,
|
|
30757
30716
|
label: option
|
|
30758
30717
|
}, option))))), /*#__PURE__*/React__namespace.createElement(wonderBlocksTypography.LabelMedium, {
|
|
30759
30718
|
tag: "label",
|
|
30760
|
-
style: styles$
|
|
30719
|
+
style: [styles$h.row, styles$h.spaceUnder]
|
|
30761
30720
|
}, "stroke", /*#__PURE__*/React__namespace.createElement(Strut, {
|
|
30762
30721
|
size: wonderBlocksTokens.spacing.xxSmall_6
|
|
30763
30722
|
}), /*#__PURE__*/React__namespace.createElement(wonderBlocksDropdown.SingleSelect, {
|
|
@@ -30774,683 +30733,1020 @@ const LockedEllipseSettings = props => {
|
|
|
30774
30733
|
}, "solid"), /*#__PURE__*/React__namespace.createElement(wonderBlocksDropdown.OptionItem, {
|
|
30775
30734
|
value: "dashed",
|
|
30776
30735
|
label: "dashed"
|
|
30777
|
-
}, "dashed"))), /*#__PURE__*/React__namespace.createElement(
|
|
30778
|
-
|
|
30779
|
-
|
|
30780
|
-
|
|
30781
|
-
|
|
30782
|
-
|
|
30783
|
-
row: {
|
|
30784
|
-
display: "flex",
|
|
30785
|
-
flexDirection: "row",
|
|
30786
|
-
alignItems: "center"
|
|
30787
|
-
},
|
|
30788
|
-
spaceUnder: {
|
|
30789
|
-
marginBottom: wonderBlocksTokens.spacing.xSmall_8
|
|
30790
|
-
}
|
|
30791
|
-
});
|
|
30792
|
-
|
|
30793
|
-
const LabeledSwitch = props => {
|
|
30794
|
-
const {
|
|
30795
|
-
checked,
|
|
30796
|
-
label,
|
|
30797
|
-
style,
|
|
30798
|
-
onChange
|
|
30799
|
-
} = props;
|
|
30800
|
-
const ids = wonderBlocksCore.useUniqueIdWithMock();
|
|
30801
|
-
const switchId = ids.get("switch");
|
|
30802
|
-
return /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, {
|
|
30803
|
-
style: [styles$i.row, style]
|
|
30804
|
-
}, /*#__PURE__*/React__namespace.createElement(Switch__default["default"], {
|
|
30805
|
-
id: switchId,
|
|
30806
|
-
checked: checked,
|
|
30807
|
-
onChange: onChange
|
|
30808
|
-
}), /*#__PURE__*/React__namespace.createElement(Strut, {
|
|
30809
|
-
size: wonderBlocksTokens.spacing.xSmall_8
|
|
30810
|
-
}), /*#__PURE__*/React__namespace.createElement(wonderBlocksTypography.LabelMedium, {
|
|
30811
|
-
tag: "label",
|
|
30812
|
-
htmlFor: switchId
|
|
30813
|
-
}, label));
|
|
30814
|
-
};
|
|
30815
|
-
const styles$i = aphrodite.StyleSheet.create({
|
|
30816
|
-
row: {
|
|
30817
|
-
flexDirection: "row",
|
|
30818
|
-
alignItems: "center"
|
|
30819
|
-
}
|
|
30820
|
-
});
|
|
30821
|
-
|
|
30822
|
-
/**
|
|
30823
|
-
* DefiningPointSettings is a component that allows the user to edit the
|
|
30824
|
-
* settings of a point that defines a locked figure (ex. line) on the graph.
|
|
30825
|
-
*
|
|
30826
|
-
* Used in the interactive graph editor's locked figures section.
|
|
30827
|
-
*/
|
|
30828
|
-
const DefiningPointSettings = props => {
|
|
30829
|
-
const {
|
|
30830
|
-
coord,
|
|
30831
|
-
color: pointColor,
|
|
30832
|
-
filled = true,
|
|
30833
|
-
label,
|
|
30834
|
-
showPoint = "false",
|
|
30835
|
-
error,
|
|
30836
|
-
onChangeProps,
|
|
30837
|
-
onTogglePoint
|
|
30838
|
-
} = props;
|
|
30839
|
-
function handleColorChange(newValue) {
|
|
30840
|
-
onChangeProps({
|
|
30841
|
-
color: newValue
|
|
30842
|
-
});
|
|
30843
|
-
}
|
|
30844
|
-
return /*#__PURE__*/React__namespace.createElement(LockedFigureSettingsAccordion, {
|
|
30845
|
-
expanded: props.expanded,
|
|
30846
|
-
onToggle: props.onToggle,
|
|
30847
|
-
containerStyle: styles$h.container,
|
|
30848
|
-
panelStyle: styles$h.accordionPanel,
|
|
30849
|
-
header:
|
|
30850
|
-
/*#__PURE__*/
|
|
30851
|
-
// Summary: Point, coords, color (filled/open)
|
|
30852
|
-
React__namespace.createElement(wonderBlocksCore.View, {
|
|
30853
|
-
style: styles$h.row
|
|
30854
|
-
}, /*#__PURE__*/React__namespace.createElement(wonderBlocksTypography.LabelLarge, null, `${label || "Point"} (${coord[0]}, ${coord[1]})`), /*#__PURE__*/React__namespace.createElement(Strut, {
|
|
30855
|
-
size: wonderBlocksTokens.spacing.xSmall_8
|
|
30856
|
-
}), showPoint && /*#__PURE__*/React__namespace.createElement(ColorSwatch, {
|
|
30857
|
-
color: pointColor,
|
|
30858
|
-
filled: filled
|
|
30859
|
-
}))
|
|
30860
|
-
}, /*#__PURE__*/React__namespace.createElement(CoordinatePairInput, {
|
|
30861
|
-
coord: coord,
|
|
30862
|
-
error: !!error,
|
|
30863
|
-
onChange: newCoords => {
|
|
30864
|
-
onChangeProps({
|
|
30865
|
-
coord: newCoords
|
|
30866
|
-
});
|
|
30867
|
-
}
|
|
30868
|
-
}), onTogglePoint && /*#__PURE__*/React__namespace.createElement(LabeledSwitch, {
|
|
30869
|
-
label: "show point on graph",
|
|
30870
|
-
checked: !!showPoint,
|
|
30871
|
-
style: showPoint && styles$h.spaceUnder,
|
|
30872
|
-
onChange: onTogglePoint
|
|
30873
|
-
}), showPoint && /*#__PURE__*/React__namespace.createElement(React__namespace.Fragment, null, /*#__PURE__*/React__namespace.createElement(ColorSelect, {
|
|
30874
|
-
selectedValue: pointColor,
|
|
30875
|
-
onChange: handleColorChange,
|
|
30736
|
+
}, "dashed"))), /*#__PURE__*/React__namespace.createElement(LabeledSwitch, {
|
|
30737
|
+
label: "show vertices",
|
|
30738
|
+
checked: showVertices,
|
|
30739
|
+
onChange: newValue => onChangeProps({
|
|
30740
|
+
showVertices: newValue
|
|
30741
|
+
}),
|
|
30876
30742
|
style: styles$h.spaceUnder
|
|
30877
|
-
}), /*#__PURE__*/React__namespace.createElement(
|
|
30878
|
-
|
|
30879
|
-
|
|
30880
|
-
|
|
30881
|
-
|
|
30882
|
-
|
|
30883
|
-
|
|
30884
|
-
|
|
30885
|
-
|
|
30886
|
-
|
|
30887
|
-
|
|
30888
|
-
|
|
30889
|
-
|
|
30890
|
-
|
|
30891
|
-
|
|
30892
|
-
|
|
30893
|
-
|
|
30894
|
-
|
|
30895
|
-
|
|
30896
|
-
|
|
30897
|
-
|
|
30898
|
-
|
|
30899
|
-
|
|
30900
|
-
|
|
30901
|
-
|
|
30902
|
-
|
|
30903
|
-
|
|
30904
|
-
|
|
30905
|
-
|
|
30906
|
-
|
|
30907
|
-
|
|
30908
|
-
const
|
|
30909
|
-
|
|
30910
|
-
|
|
30911
|
-
|
|
30912
|
-
|
|
30913
|
-
|
|
30914
|
-
|
|
30915
|
-
|
|
30916
|
-
|
|
30917
|
-
|
|
30918
|
-
|
|
30919
|
-
|
|
30743
|
+
}), /*#__PURE__*/React__namespace.createElement(LockedFigureSettingsAccordion, {
|
|
30744
|
+
header: /*#__PURE__*/React__namespace.createElement(wonderBlocksTypography.LabelLarge, null, "Points"),
|
|
30745
|
+
expanded: true,
|
|
30746
|
+
containerStyle: styles$h.pointAccordionContainer,
|
|
30747
|
+
panelStyle: styles$h.pointAccordionPanel
|
|
30748
|
+
}, points.map((point, index) => {
|
|
30749
|
+
const pointLabel = String.fromCharCode(65 + index);
|
|
30750
|
+
return /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, {
|
|
30751
|
+
key: `locked-polygon-point-${point[0]}-${point[1]}-index-${index}`,
|
|
30752
|
+
style: [styles$h.row, styles$h.spaceUnder]
|
|
30753
|
+
}, /*#__PURE__*/React__namespace.createElement(wonderBlocksTypography.LabelLarge, null, `${pointLabel}:`), /*#__PURE__*/React__namespace.createElement(Strut, {
|
|
30754
|
+
size: wonderBlocksTokens.spacing.medium_16
|
|
30755
|
+
}), /*#__PURE__*/React__namespace.createElement(CoordinatePairInput, {
|
|
30756
|
+
coord: point,
|
|
30757
|
+
labels: ["x", "y"],
|
|
30758
|
+
onChange: newValue => {
|
|
30759
|
+
const newPoints = [...points];
|
|
30760
|
+
newPoints[index] = newValue;
|
|
30761
|
+
props.onChangeProps({
|
|
30762
|
+
points: newPoints
|
|
30763
|
+
});
|
|
30764
|
+
}
|
|
30765
|
+
}),
|
|
30766
|
+
// Only show the minus (delete) buttons if there are
|
|
30767
|
+
// more than 3 points. 3 points is the minimum number
|
|
30768
|
+
// of points for a polygon (triangle).
|
|
30769
|
+
points.length > 3 && /*#__PURE__*/React__namespace.createElement(IconButton__default["default"], {
|
|
30770
|
+
"aria-label": `Delete polygon point ${pointLabel}`,
|
|
30771
|
+
icon: minusCircle__default["default"],
|
|
30772
|
+
color: "destructive",
|
|
30773
|
+
onClick: () => {
|
|
30774
|
+
const newPoints = [...points];
|
|
30775
|
+
newPoints.splice(index, 1);
|
|
30776
|
+
props.onChangeProps({
|
|
30777
|
+
points: newPoints
|
|
30778
|
+
});
|
|
30779
|
+
},
|
|
30780
|
+
style: styles$h.icon
|
|
30781
|
+
}));
|
|
30782
|
+
}), /*#__PURE__*/React__namespace.createElement(Button__default["default"], {
|
|
30783
|
+
kind: "tertiary",
|
|
30784
|
+
startIcon: plusCircle__default["default"],
|
|
30785
|
+
onClick: () => {
|
|
30786
|
+
props.onChangeProps({
|
|
30787
|
+
points: [...points, [0, 0]]
|
|
30788
|
+
});
|
|
30789
|
+
}
|
|
30790
|
+
}, "Add point")), /*#__PURE__*/React__namespace.createElement(LockedFigureSettingsActions, {
|
|
30791
|
+
showM2Features: props.showM2Features,
|
|
30792
|
+
figureType: props.type,
|
|
30793
|
+
onMove: onMove,
|
|
30794
|
+
onRemove: onRemove
|
|
30920
30795
|
}));
|
|
30921
30796
|
};
|
|
30922
|
-
const styles$
|
|
30923
|
-
|
|
30924
|
-
|
|
30925
|
-
|
|
30926
|
-
|
|
30927
|
-
borderRadius: wonderBlocksTokens.spacing.xxxSmall_4
|
|
30797
|
+
const styles$h = aphrodite.StyleSheet.create({
|
|
30798
|
+
row: {
|
|
30799
|
+
display: "flex",
|
|
30800
|
+
flexDirection: "row",
|
|
30801
|
+
alignItems: "center"
|
|
30928
30802
|
},
|
|
30929
|
-
|
|
30930
|
-
|
|
30803
|
+
pointAccordionContainer: {
|
|
30804
|
+
backgroundColor: wonderBlocksTokens.color.white
|
|
30805
|
+
},
|
|
30806
|
+
pointAccordionPanel: {
|
|
30807
|
+
alignItems: "start"
|
|
30808
|
+
},
|
|
30809
|
+
icon: {
|
|
30810
|
+
marginInlineStart: wonderBlocksTokens.spacing.xxxSmall_4
|
|
30811
|
+
},
|
|
30812
|
+
spaceUnder: {
|
|
30813
|
+
marginBottom: wonderBlocksTokens.spacing.xSmall_8
|
|
30931
30814
|
}
|
|
30932
30815
|
});
|
|
30933
30816
|
|
|
30934
|
-
|
|
30935
|
-
|
|
30817
|
+
/**
|
|
30818
|
+
* LockedVectorSettings is a component that allows the user to edit the
|
|
30819
|
+
* settings of specifically a locked vector on the graph.
|
|
30820
|
+
*
|
|
30821
|
+
* Used in the interactive graph editor's locked figures section.
|
|
30822
|
+
*/
|
|
30823
|
+
const lengthErrorMessage = "The vector cannot have length 0.";
|
|
30824
|
+
const LockedVectorSettings = props => {
|
|
30936
30825
|
const {
|
|
30937
|
-
kind,
|
|
30938
30826
|
points,
|
|
30939
30827
|
color: lineColor,
|
|
30940
|
-
lineStyle = "solid",
|
|
30941
|
-
showPoint1,
|
|
30942
|
-
showPoint2,
|
|
30943
30828
|
onChangeProps,
|
|
30829
|
+
onMove,
|
|
30944
30830
|
onRemove
|
|
30945
30831
|
} = props;
|
|
30946
|
-
const [
|
|
30947
|
-
const
|
|
30948
|
-
const lineLabel = `${capitalizeKind} (${point1.coord[0]},
|
|
30949
|
-
${point1.coord[1]}), (${point2.coord[0]}, ${point2.coord[1]})`;
|
|
30832
|
+
const [tail, tip] = points;
|
|
30833
|
+
const lineLabel = `Vector (${tail[0]}, ${tail[1]}), (${tip[0]}, ${tip[1]})`;
|
|
30950
30834
|
|
|
30951
30835
|
// Check if the line has length 0.
|
|
30952
|
-
const isInvalid = kmath.vector.equal(
|
|
30953
|
-
function handleChangePoint(
|
|
30954
|
-
|
|
30955
|
-
|
|
30956
|
-
|
|
30957
|
-
|
|
30958
|
-
|
|
30959
|
-
|
|
30960
|
-
|
|
30961
|
-
});
|
|
30836
|
+
const isInvalid = kmath.vector.equal(tail, tip);
|
|
30837
|
+
function handleChangePoint(newCoord, index) {
|
|
30838
|
+
if (typeof newCoord !== "undefined") {
|
|
30839
|
+
const newPoints = [...points];
|
|
30840
|
+
newPoints[index] = [...newCoord];
|
|
30841
|
+
onChangeProps({
|
|
30842
|
+
points: newPoints
|
|
30843
|
+
});
|
|
30844
|
+
}
|
|
30962
30845
|
}
|
|
30963
30846
|
function handleColorChange(newColor) {
|
|
30964
30847
|
onChangeProps({
|
|
30965
|
-
color: newColor
|
|
30966
|
-
// Keep the line's points' colors in sync with the line color.
|
|
30967
|
-
points: [{
|
|
30968
|
-
...point1,
|
|
30969
|
-
color: newColor
|
|
30970
|
-
}, {
|
|
30971
|
-
...point2,
|
|
30972
|
-
color: newColor
|
|
30973
|
-
}]
|
|
30848
|
+
color: newColor
|
|
30974
30849
|
});
|
|
30975
30850
|
}
|
|
30976
30851
|
return /*#__PURE__*/React__namespace.createElement(LockedFigureSettingsAccordion, {
|
|
30977
30852
|
expanded: props.expanded,
|
|
30978
30853
|
onToggle: props.onToggle,
|
|
30979
30854
|
header: /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, {
|
|
30980
|
-
style: styles$
|
|
30855
|
+
style: styles$g.row
|
|
30981
30856
|
}, /*#__PURE__*/React__namespace.createElement(wonderBlocksTypography.LabelLarge, null, lineLabel), /*#__PURE__*/React__namespace.createElement(Strut, {
|
|
30982
30857
|
size: wonderBlocksTokens.spacing.xSmall_8
|
|
30983
30858
|
}), /*#__PURE__*/React__namespace.createElement(LineSwatch, {
|
|
30984
30859
|
color: lineColor,
|
|
30985
|
-
lineStyle:
|
|
30860
|
+
lineStyle: "solid"
|
|
30986
30861
|
}))
|
|
30987
|
-
}, /*#__PURE__*/React__namespace.createElement(
|
|
30988
|
-
|
|
30989
|
-
style: [styles$f.row, styles$f.spaceUnder]
|
|
30990
|
-
}, "kind", /*#__PURE__*/React__namespace.createElement(Strut, {
|
|
30991
|
-
size: wonderBlocksTokens.spacing.xxxSmall_4
|
|
30992
|
-
}), /*#__PURE__*/React__namespace.createElement(wonderBlocksDropdown.SingleSelect, {
|
|
30993
|
-
selectedValue: kind,
|
|
30994
|
-
onChange: value => onChangeProps({
|
|
30995
|
-
kind: value
|
|
30996
|
-
})
|
|
30997
|
-
// Placeholder is required, but never gets used.
|
|
30998
|
-
,
|
|
30999
|
-
placeholder: ""
|
|
31000
|
-
}, /*#__PURE__*/React__namespace.createElement(wonderBlocksDropdown.OptionItem, {
|
|
31001
|
-
value: "line",
|
|
31002
|
-
label: "line"
|
|
31003
|
-
}), /*#__PURE__*/React__namespace.createElement(wonderBlocksDropdown.OptionItem, {
|
|
31004
|
-
value: "ray",
|
|
31005
|
-
label: "ray"
|
|
31006
|
-
}), /*#__PURE__*/React__namespace.createElement(wonderBlocksDropdown.OptionItem, {
|
|
31007
|
-
value: "segment",
|
|
31008
|
-
label: "segment"
|
|
31009
|
-
}))), /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, {
|
|
31010
|
-
style: styles$f.row
|
|
30862
|
+
}, /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, {
|
|
30863
|
+
style: [styles$g.row, styles$g.spaceUnder]
|
|
31011
30864
|
}, /*#__PURE__*/React__namespace.createElement(ColorSelect, {
|
|
31012
30865
|
selectedValue: lineColor,
|
|
31013
30866
|
onChange: handleColorChange
|
|
30867
|
+
})), isInvalid && /*#__PURE__*/React__namespace.createElement(wonderBlocksTypography.LabelMedium, {
|
|
30868
|
+
style: styles$g.errorText
|
|
30869
|
+
}, lengthErrorMessage), /*#__PURE__*/React__namespace.createElement(LockedFigureSettingsAccordion, {
|
|
30870
|
+
expanded: true // Initial state is expanded
|
|
30871
|
+
,
|
|
30872
|
+
containerStyle: styles$g.container,
|
|
30873
|
+
panelStyle: styles$g.accordionPanel,
|
|
30874
|
+
header: /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, {
|
|
30875
|
+
style: styles$g.row
|
|
30876
|
+
}, /*#__PURE__*/React__namespace.createElement(wonderBlocksTypography.LabelLarge, null, `Tail (${tail[0]}, ${tail[1]})`))
|
|
30877
|
+
}, /*#__PURE__*/React__namespace.createElement(CoordinatePairInput, {
|
|
30878
|
+
coord: tail,
|
|
30879
|
+
error: isInvalid,
|
|
30880
|
+
onChange: newProps => {
|
|
30881
|
+
handleChangePoint(newProps, 0);
|
|
30882
|
+
}
|
|
30883
|
+
})), /*#__PURE__*/React__namespace.createElement(LockedFigureSettingsAccordion, {
|
|
30884
|
+
expanded: true // Initial state is expanded
|
|
30885
|
+
,
|
|
30886
|
+
containerStyle: styles$g.container,
|
|
30887
|
+
panelStyle: styles$g.accordionPanel,
|
|
30888
|
+
header: /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, {
|
|
30889
|
+
style: styles$g.row
|
|
30890
|
+
}, /*#__PURE__*/React__namespace.createElement(wonderBlocksTypography.LabelLarge, null, `Tip (${tip[0]}, ${tip[1]})`))
|
|
30891
|
+
}, /*#__PURE__*/React__namespace.createElement(CoordinatePairInput, {
|
|
30892
|
+
coord: tip,
|
|
30893
|
+
error: isInvalid,
|
|
30894
|
+
onChange: newProps => {
|
|
30895
|
+
handleChangePoint(newProps, 1);
|
|
30896
|
+
}
|
|
30897
|
+
})), /*#__PURE__*/React__namespace.createElement(LockedFigureSettingsActions, {
|
|
30898
|
+
showM2Features: props.showM2Features,
|
|
30899
|
+
figureType: props.type,
|
|
30900
|
+
onMove: onMove,
|
|
30901
|
+
onRemove: onRemove
|
|
30902
|
+
}));
|
|
30903
|
+
};
|
|
30904
|
+
const styles$g = aphrodite.StyleSheet.create({
|
|
30905
|
+
accordionPanel: {
|
|
30906
|
+
paddingBottom: wonderBlocksTokens.spacing.medium_16
|
|
30907
|
+
},
|
|
30908
|
+
container: {
|
|
30909
|
+
marginTop: wonderBlocksTokens.spacing.xSmall_8,
|
|
30910
|
+
marginBottom: 0,
|
|
30911
|
+
marginLeft: -wonderBlocksTokens.spacing.xxxSmall_4,
|
|
30912
|
+
marginRight: -wonderBlocksTokens.spacing.xxxSmall_4,
|
|
30913
|
+
backgroundColor: wonderBlocksTokens.color.white
|
|
30914
|
+
},
|
|
30915
|
+
errorText: {
|
|
30916
|
+
color: wonderBlocksTokens.color.red,
|
|
30917
|
+
marginTop: wonderBlocksTokens.spacing.xSmall_8
|
|
30918
|
+
},
|
|
30919
|
+
row: {
|
|
30920
|
+
flexDirection: "row",
|
|
30921
|
+
alignItems: "center"
|
|
30922
|
+
}
|
|
30923
|
+
});
|
|
30924
|
+
|
|
30925
|
+
/**
|
|
30926
|
+
* LockedFigureSettings takes in a figure and renders the
|
|
30927
|
+
* respective settings for that figure type.
|
|
30928
|
+
*
|
|
30929
|
+
* Used in the interactive graph editor's locked figures section.
|
|
30930
|
+
*/
|
|
30931
|
+
|
|
30932
|
+
// Union this type with other locked figure types when they are added.
|
|
30933
|
+
|
|
30934
|
+
const LockedFigureSettings = props => {
|
|
30935
|
+
switch (props.type) {
|
|
30936
|
+
case "point":
|
|
30937
|
+
return /*#__PURE__*/React__namespace.createElement(LockedPointSettings, props);
|
|
30938
|
+
case "line":
|
|
30939
|
+
return /*#__PURE__*/React__namespace.createElement(LockedLineSettings, props);
|
|
30940
|
+
case "vector":
|
|
30941
|
+
if (props.showM2Features) {
|
|
30942
|
+
return /*#__PURE__*/React__namespace.createElement(LockedVectorSettings, props);
|
|
30943
|
+
}
|
|
30944
|
+
break;
|
|
30945
|
+
case "ellipse":
|
|
30946
|
+
if (props.showM2Features) {
|
|
30947
|
+
return /*#__PURE__*/React__namespace.createElement(LockedEllipseSettings, props);
|
|
30948
|
+
}
|
|
30949
|
+
break;
|
|
30950
|
+
case "polygon":
|
|
30951
|
+
if (props.showM2Features) {
|
|
30952
|
+
return /*#__PURE__*/React__namespace.createElement(LockedPolygonSettings, props);
|
|
30953
|
+
}
|
|
30954
|
+
}
|
|
30955
|
+
return null;
|
|
30956
|
+
};
|
|
30957
|
+
|
|
30958
|
+
const LockedFiguresSection = props => {
|
|
30959
|
+
// Keep track of all figures' accordions' expanded states for the
|
|
30960
|
+
// expand/collapse all button. Set the whole array to false initially.
|
|
30961
|
+
const collapsedStateArray = Array((props.figures ?? []).length).fill(false);
|
|
30962
|
+
const [expandedStates, setExpandedStates] = React__namespace.useState(collapsedStateArray);
|
|
30963
|
+
const uniqueId = wonderBlocksCore.useUniqueIdWithMock().get("locked-figures-section");
|
|
30964
|
+
const {
|
|
30965
|
+
figures,
|
|
30966
|
+
onChange
|
|
30967
|
+
} = props;
|
|
30968
|
+
function addLockedFigure(newFigure) {
|
|
30969
|
+
const lockedFigures = figures || [];
|
|
30970
|
+
const newProps = {
|
|
30971
|
+
lockedFigures: [...lockedFigures, getDefaultFigureForType(newFigure)]
|
|
30972
|
+
};
|
|
30973
|
+
onChange(newProps);
|
|
30974
|
+
setExpandedStates([...expandedStates, true]);
|
|
30975
|
+
}
|
|
30976
|
+
function moveLockedFigure(index, movement) {
|
|
30977
|
+
// Don't allow moving the first figure up or the last figure down.
|
|
30978
|
+
if (index === 0 && (movement === "back" || movement === "backward")) {
|
|
30979
|
+
return;
|
|
30980
|
+
}
|
|
30981
|
+
if (figures && index === figures.length - 1 && (movement === "front" || movement === "forward")) {
|
|
30982
|
+
return;
|
|
30983
|
+
}
|
|
30984
|
+
const lockedFigures = figures || [];
|
|
30985
|
+
const newFigures = [...lockedFigures];
|
|
30986
|
+
const newExpandedStates = [...expandedStates];
|
|
30987
|
+
|
|
30988
|
+
// First, remove the figure from its current position
|
|
30989
|
+
// in the figures array and the expanded states array.
|
|
30990
|
+
const [removedFigure] = newFigures.splice(index, 1);
|
|
30991
|
+
newExpandedStates.splice(index, 1);
|
|
30992
|
+
|
|
30993
|
+
// Then, add it back in the new position. Add "true" to the
|
|
30994
|
+
// expanded states array for the new position (it must already
|
|
30995
|
+
// be open since the button to move it is being pressed from there).
|
|
30996
|
+
switch (movement) {
|
|
30997
|
+
case "back":
|
|
30998
|
+
newFigures.unshift(removedFigure);
|
|
30999
|
+
newExpandedStates.unshift(true);
|
|
31000
|
+
break;
|
|
31001
|
+
case "backward":
|
|
31002
|
+
newFigures.splice(index - 1, 0, removedFigure);
|
|
31003
|
+
newExpandedStates.splice(index - 1, 0, true);
|
|
31004
|
+
break;
|
|
31005
|
+
case "forward":
|
|
31006
|
+
newFigures.splice(index + 1, 0, removedFigure);
|
|
31007
|
+
newExpandedStates.splice(index + 1, 0, true);
|
|
31008
|
+
break;
|
|
31009
|
+
case "front":
|
|
31010
|
+
newFigures.push(removedFigure);
|
|
31011
|
+
newExpandedStates.push(true);
|
|
31012
|
+
break;
|
|
31013
|
+
}
|
|
31014
|
+
onChange({
|
|
31015
|
+
lockedFigures: newFigures
|
|
31016
|
+
});
|
|
31017
|
+
setExpandedStates(newExpandedStates);
|
|
31018
|
+
}
|
|
31019
|
+
function removeLockedFigure(index) {
|
|
31020
|
+
// eslint-disable-next-line no-alert
|
|
31021
|
+
if (window.confirm("Are you sure you want to delete this figure?")) {
|
|
31022
|
+
const lockedFigures = figures || [];
|
|
31023
|
+
onChange({
|
|
31024
|
+
lockedFigures: [...lockedFigures.slice(0, index), ...lockedFigures.slice(index + 1)]
|
|
31025
|
+
});
|
|
31026
|
+
|
|
31027
|
+
// Update expanded states
|
|
31028
|
+
const newExpandedStates = [...expandedStates];
|
|
31029
|
+
newExpandedStates.splice(index, 1);
|
|
31030
|
+
setExpandedStates(newExpandedStates);
|
|
31031
|
+
}
|
|
31032
|
+
}
|
|
31033
|
+
function changeProps(index,
|
|
31034
|
+
// Omit the type from the figure props so it doesn't think
|
|
31035
|
+
// we're trying to pass in the props for the wrong type.
|
|
31036
|
+
figureProps) {
|
|
31037
|
+
const lockedFigures = figures || [];
|
|
31038
|
+
const newFigures = {
|
|
31039
|
+
lockedFigures: [...lockedFigures.slice(0, index), {
|
|
31040
|
+
...lockedFigures[index],
|
|
31041
|
+
...figureProps
|
|
31042
|
+
}, ...lockedFigures.slice(index + 1)]
|
|
31043
|
+
};
|
|
31044
|
+
onChange(newFigures);
|
|
31045
|
+
}
|
|
31046
|
+
function toggleExpanded(newValue) {
|
|
31047
|
+
setExpandedStates(Array(figures?.length).fill(newValue));
|
|
31048
|
+
}
|
|
31049
|
+
const allCollapsed = expandedStates.every(value => !value);
|
|
31050
|
+
const buttonLabel = allCollapsed ? "Expand all" : "Collapse all";
|
|
31051
|
+
const showExpandButton = !!figures?.length;
|
|
31052
|
+
return /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, null, figures?.map((figure, index) => {
|
|
31053
|
+
return /*#__PURE__*/React__namespace.createElement(LockedFigureSettings, _extends({
|
|
31054
|
+
key: `${uniqueId}-locked-${figure}-${index}`,
|
|
31055
|
+
showM2Features: props.showM2Features,
|
|
31056
|
+
showM2bFeatures: props.showM2bFeatures,
|
|
31057
|
+
expanded: expandedStates[index],
|
|
31058
|
+
onToggle: newValue => {
|
|
31059
|
+
const newExpanded = [...expandedStates];
|
|
31060
|
+
newExpanded[index] = newValue;
|
|
31061
|
+
setExpandedStates(newExpanded);
|
|
31062
|
+
}
|
|
31063
|
+
}, figure, {
|
|
31064
|
+
onChangeProps: newProps => changeProps(index, newProps),
|
|
31065
|
+
onMove: movement => moveLockedFigure(index, movement),
|
|
31066
|
+
onRemove: () => removeLockedFigure(index)
|
|
31067
|
+
}));
|
|
31068
|
+
}), /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, {
|
|
31069
|
+
style: styles$f.buttonContainer
|
|
31070
|
+
}, /*#__PURE__*/React__namespace.createElement(LockedFigureSelect, {
|
|
31071
|
+
showM2Features: props.showM2Features,
|
|
31072
|
+
showM2bFeatures: props.showM2bFeatures,
|
|
31073
|
+
id: `${uniqueId}-select`,
|
|
31074
|
+
onChange: addLockedFigure
|
|
31014
31075
|
}), /*#__PURE__*/React__namespace.createElement(Strut, {
|
|
31015
31076
|
size: wonderBlocksTokens.spacing.small_12
|
|
31016
|
-
}), /*#__PURE__*/React__namespace.createElement(
|
|
31017
|
-
|
|
31018
|
-
|
|
31019
|
-
|
|
31020
|
-
|
|
31021
|
-
}), /*#__PURE__*/React__namespace.createElement(wonderBlocksDropdown.SingleSelect, {
|
|
31022
|
-
selectedValue: lineStyle,
|
|
31023
|
-
onChange: value => onChangeProps({
|
|
31024
|
-
lineStyle: value
|
|
31025
|
-
})
|
|
31026
|
-
// Placeholder is required, but never gets used.
|
|
31027
|
-
,
|
|
31028
|
-
placeholder: "",
|
|
31029
|
-
style: styles$f.selectMarginOffset
|
|
31030
|
-
}, /*#__PURE__*/React__namespace.createElement(wonderBlocksDropdown.OptionItem, {
|
|
31031
|
-
value: "solid",
|
|
31032
|
-
label: "solid"
|
|
31033
|
-
}), /*#__PURE__*/React__namespace.createElement(wonderBlocksDropdown.OptionItem, {
|
|
31034
|
-
value: "dashed",
|
|
31035
|
-
label: "dashed"
|
|
31036
|
-
})))), isInvalid && /*#__PURE__*/React__namespace.createElement(wonderBlocksTypography.LabelMedium, {
|
|
31037
|
-
style: styles$f.errorText
|
|
31038
|
-
}, lengthZeroStr), /*#__PURE__*/React__namespace.createElement(DefiningPointSettings, _extends({
|
|
31039
|
-
label: "Point 1",
|
|
31040
|
-
showPoint: showPoint1,
|
|
31041
|
-
error: isInvalid ? lengthZeroStr : null
|
|
31042
|
-
}, point1, {
|
|
31043
|
-
onTogglePoint: newValue => onChangeProps({
|
|
31044
|
-
showPoint1: newValue
|
|
31045
|
-
}),
|
|
31046
|
-
onChangeProps: newProps => handleChangePoint(newProps, 0)
|
|
31047
|
-
})), /*#__PURE__*/React__namespace.createElement(DefiningPointSettings, _extends({
|
|
31048
|
-
label: "Point 2",
|
|
31049
|
-
showPoint: showPoint2,
|
|
31050
|
-
error: isInvalid ? lengthZeroStr : null
|
|
31051
|
-
}, point2, {
|
|
31052
|
-
onTogglePoint: newValue => onChangeProps({
|
|
31053
|
-
showPoint2: newValue
|
|
31054
|
-
}),
|
|
31055
|
-
onChangeProps: newProps => handleChangePoint(newProps, 1)
|
|
31056
|
-
})), /*#__PURE__*/React__namespace.createElement(LockedFigureSettingsActions, {
|
|
31057
|
-
onRemove: onRemove,
|
|
31058
|
-
figureAriaLabel: `locked line defined by
|
|
31059
|
-
${point1.coord[0]}, ${point1.coord[1]} and
|
|
31060
|
-
${point2.coord[0]}, ${point2.coord[1]}.`
|
|
31061
|
-
}));
|
|
31077
|
+
}), showExpandButton && /*#__PURE__*/React__namespace.createElement(Button__default["default"], {
|
|
31078
|
+
kind: "secondary",
|
|
31079
|
+
onClick: () => toggleExpanded(allCollapsed),
|
|
31080
|
+
style: styles$f.button
|
|
31081
|
+
}, buttonLabel)));
|
|
31062
31082
|
};
|
|
31063
31083
|
const styles$f = aphrodite.StyleSheet.create({
|
|
31064
|
-
|
|
31084
|
+
buttonContainer: {
|
|
31065
31085
|
flexDirection: "row",
|
|
31066
31086
|
alignItems: "center"
|
|
31067
31087
|
},
|
|
31068
|
-
|
|
31069
|
-
|
|
31070
|
-
|
|
31071
|
-
selectMarginOffset: {
|
|
31072
|
-
// Align with the point settings accordions.
|
|
31073
|
-
marginInlineEnd: -wonderBlocksTokens.spacing.xxxSmall_4
|
|
31074
|
-
},
|
|
31075
|
-
errorText: {
|
|
31076
|
-
color: wonderBlocksTokens.color.red
|
|
31088
|
+
button: {
|
|
31089
|
+
marginTop: wonderBlocksTokens.spacing.xSmall_8,
|
|
31090
|
+
flexGrow: 1
|
|
31077
31091
|
}
|
|
31078
31092
|
});
|
|
31079
31093
|
|
|
31080
|
-
|
|
31081
|
-
|
|
31082
|
-
|
|
31083
|
-
|
|
31084
|
-
|
|
31085
|
-
|
|
31086
|
-
|
|
31087
|
-
|
|
31088
|
-
coord,
|
|
31089
|
-
color: pointColor,
|
|
31090
|
-
filled = true,
|
|
31091
|
-
onChangeProps,
|
|
31092
|
-
onRemove
|
|
31093
|
-
} = props;
|
|
31094
|
-
function handleColorChange(newValue) {
|
|
31095
|
-
onChangeProps({
|
|
31096
|
-
color: newValue
|
|
31097
|
-
});
|
|
31094
|
+
const UNLIMITED = "unlimited";
|
|
31095
|
+
// Parses a string (ostensibly from some UI element that only supports string
|
|
31096
|
+
// types, such as a <select />) into a numeric point count or the special sigil
|
|
31097
|
+
// "unlimited". Note that 0 is a special case, and means "unlimited".
|
|
31098
|
+
const parsePointCount = points => {
|
|
31099
|
+
const parsed = parseInt(points, 10);
|
|
31100
|
+
if (isNaN(parsed)) {
|
|
31101
|
+
return UNLIMITED;
|
|
31098
31102
|
}
|
|
31099
|
-
return
|
|
31100
|
-
|
|
31101
|
-
|
|
31102
|
-
|
|
31103
|
-
|
|
31104
|
-
|
|
31105
|
-
|
|
31106
|
-
|
|
31107
|
-
|
|
31108
|
-
|
|
31109
|
-
}), /*#__PURE__*/React__namespace.createElement(ColorSwatch, {
|
|
31110
|
-
color: pointColor,
|
|
31111
|
-
filled: filled
|
|
31112
|
-
}))
|
|
31113
|
-
}, /*#__PURE__*/React__namespace.createElement(CoordinatePairInput, {
|
|
31114
|
-
coord: coord,
|
|
31115
|
-
onChange: newCoord => {
|
|
31116
|
-
onChangeProps({
|
|
31117
|
-
coord: newCoord
|
|
31118
|
-
});
|
|
31119
|
-
}
|
|
31120
|
-
}), /*#__PURE__*/React__namespace.createElement(ColorSelect, {
|
|
31121
|
-
selectedValue: pointColor,
|
|
31122
|
-
onChange: handleColorChange,
|
|
31123
|
-
style: styles$e.spaceUnder
|
|
31124
|
-
}), /*#__PURE__*/React__namespace.createElement(LabeledSwitch, {
|
|
31125
|
-
label: "open point",
|
|
31126
|
-
checked: !filled,
|
|
31103
|
+
return parsed === 0 ? UNLIMITED : parsed;
|
|
31104
|
+
};
|
|
31105
|
+
|
|
31106
|
+
const GraphPointsCountSelector = _ref => {
|
|
31107
|
+
let {
|
|
31108
|
+
numPoints = 1,
|
|
31109
|
+
onChange
|
|
31110
|
+
} = _ref;
|
|
31111
|
+
return /*#__PURE__*/React__namespace.createElement(wonderBlocksDropdown.SingleSelect, {
|
|
31112
|
+
selectedValue: `${numPoints}`,
|
|
31127
31113
|
onChange: newValue => {
|
|
31128
|
-
|
|
31129
|
-
|
|
31130
|
-
|
|
31114
|
+
onChange(parsePointCount(newValue));
|
|
31115
|
+
}
|
|
31116
|
+
// Never uses placeholder, always has value
|
|
31117
|
+
,
|
|
31118
|
+
placeholder: "",
|
|
31119
|
+
style: styles$e.singleSelectShort
|
|
31120
|
+
}, [...[...Array(7).keys()].map(n => /*#__PURE__*/React__namespace.createElement(wonderBlocksDropdown.OptionItem, {
|
|
31121
|
+
key: n,
|
|
31122
|
+
value: `${n}`,
|
|
31123
|
+
label: `${n} point${n > 1 ? "s" : ""}`
|
|
31124
|
+
})), /*#__PURE__*/React__namespace.createElement(wonderBlocksDropdown.OptionItem, {
|
|
31125
|
+
key: "unlimited",
|
|
31126
|
+
value: UNLIMITED,
|
|
31127
|
+
label: "unlimited"
|
|
31128
|
+
})]);
|
|
31129
|
+
};
|
|
31130
|
+
const styles$e = aphrodite.StyleSheet.create({
|
|
31131
|
+
singleSelectShort: {
|
|
31132
|
+
// Non-standard spacing, but it's the smallest we can go
|
|
31133
|
+
// without running into styling issues with the dropdown.
|
|
31134
|
+
height: 26
|
|
31135
|
+
}
|
|
31136
|
+
});
|
|
31137
|
+
|
|
31138
|
+
const GraphTypeSelector = props => {
|
|
31139
|
+
return /*#__PURE__*/React__namespace.createElement(wonderBlocksDropdown.SingleSelect, {
|
|
31140
|
+
selectedValue: props.graphType,
|
|
31141
|
+
onChange: props.onChange,
|
|
31142
|
+
placeholder: "Select a graph type",
|
|
31143
|
+
style: styles$d.singleSelectShort
|
|
31144
|
+
}, /*#__PURE__*/React__namespace.createElement(wonderBlocksDropdown.OptionItem, {
|
|
31145
|
+
value: "linear",
|
|
31146
|
+
label: "Linear function"
|
|
31147
|
+
}), /*#__PURE__*/React__namespace.createElement(wonderBlocksDropdown.OptionItem, {
|
|
31148
|
+
value: "quadratic",
|
|
31149
|
+
label: "Quadratic function"
|
|
31150
|
+
}), /*#__PURE__*/React__namespace.createElement(wonderBlocksDropdown.OptionItem, {
|
|
31151
|
+
value: "sinusoid",
|
|
31152
|
+
label: "Sinusoid function"
|
|
31153
|
+
}), /*#__PURE__*/React__namespace.createElement(wonderBlocksDropdown.OptionItem, {
|
|
31154
|
+
value: "circle",
|
|
31155
|
+
label: "Circle"
|
|
31156
|
+
}), /*#__PURE__*/React__namespace.createElement(wonderBlocksDropdown.OptionItem, {
|
|
31157
|
+
value: "point",
|
|
31158
|
+
label: "Point(s)"
|
|
31159
|
+
}), /*#__PURE__*/React__namespace.createElement(wonderBlocksDropdown.OptionItem, {
|
|
31160
|
+
value: "linear-system",
|
|
31161
|
+
label: "Linear System"
|
|
31162
|
+
}), /*#__PURE__*/React__namespace.createElement(wonderBlocksDropdown.OptionItem, {
|
|
31163
|
+
value: "polygon",
|
|
31164
|
+
label: "Polygon"
|
|
31165
|
+
}), /*#__PURE__*/React__namespace.createElement(wonderBlocksDropdown.OptionItem, {
|
|
31166
|
+
value: "segment",
|
|
31167
|
+
label: "Line Segment(s)"
|
|
31168
|
+
}), /*#__PURE__*/React__namespace.createElement(wonderBlocksDropdown.OptionItem, {
|
|
31169
|
+
value: "ray",
|
|
31170
|
+
label: "Ray"
|
|
31171
|
+
}), /*#__PURE__*/React__namespace.createElement(wonderBlocksDropdown.OptionItem, {
|
|
31172
|
+
value: "angle",
|
|
31173
|
+
label: "Angle"
|
|
31174
|
+
}));
|
|
31175
|
+
};
|
|
31176
|
+
const styles$d = aphrodite.StyleSheet.create({
|
|
31177
|
+
singleSelectShort: {
|
|
31178
|
+
// Non-standard spacing, but it's the smallest we can go
|
|
31179
|
+
// without running into styling issues with the dropdown.
|
|
31180
|
+
height: 26
|
|
31181
|
+
}
|
|
31182
|
+
});
|
|
31183
|
+
|
|
31184
|
+
/* eslint-disable react/forbid-prop-types, react/no-unsafe */
|
|
31185
|
+
const {
|
|
31186
|
+
ButtonGroup: ButtonGroup$2,
|
|
31187
|
+
InfoTip: InfoTip$c,
|
|
31188
|
+
PropCheckBox: PropCheckBox$7,
|
|
31189
|
+
RangeInput: RangeInput$4
|
|
31190
|
+
} = perseus.components;
|
|
31191
|
+
const defaultBackgroundImage$1 = {
|
|
31192
|
+
url: null,
|
|
31193
|
+
width: 0,
|
|
31194
|
+
height: 0
|
|
31195
|
+
};
|
|
31196
|
+
function numSteps(range, step) {
|
|
31197
|
+
return Math.floor((range[1] - range[0]) / step);
|
|
31198
|
+
}
|
|
31199
|
+
function Heading(_ref) {
|
|
31200
|
+
let {
|
|
31201
|
+
title,
|
|
31202
|
+
isOpen,
|
|
31203
|
+
onToggle
|
|
31204
|
+
} = _ref;
|
|
31205
|
+
return /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, {
|
|
31206
|
+
style: {
|
|
31207
|
+
flexDirection: "row",
|
|
31208
|
+
justifyContent: "space-between",
|
|
31209
|
+
backgroundColor: wonderBlocksTokens.color.offBlack8,
|
|
31210
|
+
padding: wonderBlocksTokens.spacing.xSmall_8,
|
|
31211
|
+
marginTop: wonderBlocksTokens.spacing.small_12,
|
|
31212
|
+
// NOTE(jeremy): This is the inverse of the @editorPadding CSS
|
|
31213
|
+
// variable found in perseus-editor.less. For now, it must
|
|
31214
|
+
// match otherwise there's a gap from this header to the edge
|
|
31215
|
+
// of the editor borders.
|
|
31216
|
+
marginInline: -10,
|
|
31217
|
+
cursor: "pointer"
|
|
31218
|
+
},
|
|
31219
|
+
onClick: () => onToggle?.(!isOpen)
|
|
31220
|
+
}, /*#__PURE__*/React__namespace.createElement(wonderBlocksTypography.LabelSmall, null, title), /*#__PURE__*/React__namespace.createElement(ToggleableCaret, {
|
|
31221
|
+
isExpanded: isOpen
|
|
31222
|
+
}));
|
|
31223
|
+
}
|
|
31224
|
+
class InteractiveGraphSettings extends React__namespace.Component {
|
|
31225
|
+
_isMounted = false;
|
|
31226
|
+
bgUrlRef = /*#__PURE__*/React__namespace.createRef();
|
|
31227
|
+
labelXRef = /*#__PURE__*/React__namespace.createRef();
|
|
31228
|
+
labelYRef = /*#__PURE__*/React__namespace.createRef();
|
|
31229
|
+
static stateFromProps(props) {
|
|
31230
|
+
return {
|
|
31231
|
+
labelsTextbox: props.labels,
|
|
31232
|
+
gridStepTextbox: props.gridStep,
|
|
31233
|
+
snapStepTextbox: props.snapStep,
|
|
31234
|
+
stepTextbox: props.step,
|
|
31235
|
+
rangeTextbox: props.range,
|
|
31236
|
+
// Shallow-copied clone
|
|
31237
|
+
backgroundImage: {
|
|
31238
|
+
...props.backgroundImage
|
|
31239
|
+
}
|
|
31240
|
+
};
|
|
31241
|
+
}
|
|
31242
|
+
constructor(props) {
|
|
31243
|
+
super(props);
|
|
31244
|
+
this.state = {
|
|
31245
|
+
isExpanded: true,
|
|
31246
|
+
...InteractiveGraphSettings.stateFromProps(props)
|
|
31247
|
+
};
|
|
31248
|
+
}
|
|
31249
|
+
static defaultProps = {
|
|
31250
|
+
box: [perseus.interactiveSizes.defaultBoxSizeSmall, perseus.interactiveSizes.defaultBoxSizeSmall],
|
|
31251
|
+
labels: ["x", "y"],
|
|
31252
|
+
range: [[-10, 10], [-10, 10]],
|
|
31253
|
+
step: [1, 1],
|
|
31254
|
+
gridStep: [1, 1],
|
|
31255
|
+
snapStep: [1, 1],
|
|
31256
|
+
valid: true,
|
|
31257
|
+
backgroundImage: defaultBackgroundImage$1,
|
|
31258
|
+
markings: "graph",
|
|
31259
|
+
showProtractor: false,
|
|
31260
|
+
showRuler: false,
|
|
31261
|
+
showTooltips: false,
|
|
31262
|
+
rulerLabel: "",
|
|
31263
|
+
rulerTicks: 10
|
|
31264
|
+
};
|
|
31265
|
+
componentDidMount() {
|
|
31266
|
+
// TODO(scottgrant): This is a hack to remove the deprecated call to
|
|
31267
|
+
// this.isMounted() but is still considered an anti-pattern.
|
|
31268
|
+
this._isMounted = true;
|
|
31269
|
+
this.changeGraph = ___default["default"].debounce(this.changeGraph, 300);
|
|
31270
|
+
}
|
|
31271
|
+
UNSAFE_componentWillReceiveProps(nextProps) {
|
|
31272
|
+
// Make sure that state updates when switching
|
|
31273
|
+
// between different items in a multi-item editor.
|
|
31274
|
+
if (!___default["default"].isEqual(this.props.labels, nextProps.labels) || !___default["default"].isEqual(this.props.gridStep, nextProps.gridStep) || !___default["default"].isEqual(this.props.snapStep, nextProps.snapStep) || !___default["default"].isEqual(this.props.step, nextProps.step) || !___default["default"].isEqual(this.props.range, nextProps.range) || !___default["default"].isEqual(this.props.backgroundImage, nextProps.backgroundImage)) {
|
|
31275
|
+
this.setState(InteractiveGraphSettings.stateFromProps(nextProps));
|
|
31131
31276
|
}
|
|
31132
|
-
}), /*#__PURE__*/React__namespace.createElement(LockedFigureSettingsActions, {
|
|
31133
|
-
onRemove: onRemove,
|
|
31134
|
-
figureAriaLabel: `locked point at ${coord[0]}, ${coord[1]}`
|
|
31135
|
-
}));
|
|
31136
|
-
};
|
|
31137
|
-
const styles$e = aphrodite.StyleSheet.create({
|
|
31138
|
-
row: {
|
|
31139
|
-
flexDirection: "row",
|
|
31140
|
-
alignItems: "center"
|
|
31141
|
-
},
|
|
31142
|
-
spaceUnder: {
|
|
31143
|
-
marginBottom: wonderBlocksTokens.spacing.xSmall_8
|
|
31144
31277
|
}
|
|
31145
|
-
|
|
31146
|
-
|
|
31147
|
-
|
|
31148
|
-
|
|
31149
|
-
|
|
31150
|
-
|
|
31151
|
-
|
|
31152
|
-
|
|
31153
|
-
|
|
31154
|
-
|
|
31155
|
-
|
|
31156
|
-
|
|
31157
|
-
color: lineColor,
|
|
31158
|
-
onChangeProps,
|
|
31159
|
-
onRemove
|
|
31160
|
-
} = props;
|
|
31161
|
-
const [tail, tip] = points;
|
|
31162
|
-
const lineLabel = `Vector (${tail[0]}, ${tail[1]}), (${tip[0]}, ${tip[1]})`;
|
|
31278
|
+
componentWillUnmount() {
|
|
31279
|
+
this._isMounted = false;
|
|
31280
|
+
}
|
|
31281
|
+
change = (() => {
|
|
31282
|
+
var _this = this;
|
|
31283
|
+
return function () {
|
|
31284
|
+
for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
|
|
31285
|
+
args[_key] = arguments[_key];
|
|
31286
|
+
}
|
|
31287
|
+
return perseus.Changeable.change.apply(_this, args);
|
|
31288
|
+
};
|
|
31289
|
+
})();
|
|
31163
31290
|
|
|
31164
|
-
//
|
|
31165
|
-
|
|
31166
|
-
|
|
31167
|
-
|
|
31168
|
-
|
|
31169
|
-
|
|
31170
|
-
|
|
31171
|
-
|
|
31291
|
+
// TODO(aria): Make either a wrapper for standard events to work
|
|
31292
|
+
// with this.change, or make these use some TextInput/NumberInput box
|
|
31293
|
+
changeRulerLabel = e => {
|
|
31294
|
+
this.change({
|
|
31295
|
+
rulerLabel: e.target.value
|
|
31296
|
+
});
|
|
31297
|
+
};
|
|
31298
|
+
changeRulerTicks = e => {
|
|
31299
|
+
this.change({
|
|
31300
|
+
rulerTicks: +e.target.value
|
|
31301
|
+
});
|
|
31302
|
+
};
|
|
31303
|
+
changeBackgroundUrl = e => {
|
|
31304
|
+
// Only continue on blur or "enter"
|
|
31305
|
+
if (e.type === "keypress" && e.key !== "Enter") {
|
|
31306
|
+
return;
|
|
31307
|
+
}
|
|
31308
|
+
const setUrl = (url, width, height) => {
|
|
31309
|
+
// Shallow-copied clone
|
|
31310
|
+
const image = {
|
|
31311
|
+
...this.props.backgroundImage
|
|
31312
|
+
};
|
|
31313
|
+
image.url = url;
|
|
31314
|
+
image.width = width;
|
|
31315
|
+
image.height = height;
|
|
31316
|
+
this.setState({
|
|
31317
|
+
backgroundImage: image
|
|
31318
|
+
}, this.changeGraph);
|
|
31319
|
+
};
|
|
31320
|
+
const url = this.bgUrlRef.current?.value;
|
|
31321
|
+
if (url) {
|
|
31322
|
+
perseus.Util.getImageSize(url, (width, height) => {
|
|
31323
|
+
if (this._isMounted) {
|
|
31324
|
+
setUrl(url, width, height);
|
|
31325
|
+
}
|
|
31172
31326
|
});
|
|
31327
|
+
} else {
|
|
31328
|
+
setUrl(null, 0, 0);
|
|
31173
31329
|
}
|
|
31174
|
-
}
|
|
31175
|
-
|
|
31176
|
-
|
|
31177
|
-
|
|
31330
|
+
};
|
|
31331
|
+
renderLabelChoices = choices => {
|
|
31332
|
+
return choices.map(nameAndValue => /*#__PURE__*/React__namespace.createElement("option", {
|
|
31333
|
+
key: nameAndValue[1],
|
|
31334
|
+
value: nameAndValue[1]
|
|
31335
|
+
}, nameAndValue[0]));
|
|
31336
|
+
};
|
|
31337
|
+
validRange = range => {
|
|
31338
|
+
const numbers = ___default["default"].every(range, function (num) {
|
|
31339
|
+
return ___default["default"].isFinite(num);
|
|
31178
31340
|
});
|
|
31179
|
-
|
|
31180
|
-
|
|
31181
|
-
expanded: props.expanded,
|
|
31182
|
-
onToggle: props.onToggle,
|
|
31183
|
-
header: /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, {
|
|
31184
|
-
style: styles$d.row
|
|
31185
|
-
}, /*#__PURE__*/React__namespace.createElement(wonderBlocksTypography.LabelLarge, null, lineLabel), /*#__PURE__*/React__namespace.createElement(Strut, {
|
|
31186
|
-
size: wonderBlocksTokens.spacing.xSmall_8
|
|
31187
|
-
}), /*#__PURE__*/React__namespace.createElement(LineSwatch, {
|
|
31188
|
-
color: lineColor,
|
|
31189
|
-
lineStyle: "solid"
|
|
31190
|
-
}))
|
|
31191
|
-
}, /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, {
|
|
31192
|
-
style: [styles$d.row, styles$d.spaceUnder]
|
|
31193
|
-
}, /*#__PURE__*/React__namespace.createElement(ColorSelect, {
|
|
31194
|
-
selectedValue: lineColor,
|
|
31195
|
-
onChange: handleColorChange
|
|
31196
|
-
})), isInvalid && /*#__PURE__*/React__namespace.createElement(wonderBlocksTypography.LabelMedium, {
|
|
31197
|
-
style: styles$d.errorText
|
|
31198
|
-
}, lengthErrorMessage), /*#__PURE__*/React__namespace.createElement(LockedFigureSettingsAccordion, {
|
|
31199
|
-
expanded: true // Initial state is expanded
|
|
31200
|
-
,
|
|
31201
|
-
containerStyle: styles$d.container,
|
|
31202
|
-
panelStyle: styles$d.accordionPanel,
|
|
31203
|
-
header: /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, {
|
|
31204
|
-
style: styles$d.row
|
|
31205
|
-
}, /*#__PURE__*/React__namespace.createElement(wonderBlocksTypography.LabelLarge, null, `Tail (${tail[0]}, ${tail[1]})`))
|
|
31206
|
-
}, /*#__PURE__*/React__namespace.createElement(CoordinatePairInput, {
|
|
31207
|
-
coord: tail,
|
|
31208
|
-
error: isInvalid,
|
|
31209
|
-
onChange: newProps => {
|
|
31210
|
-
handleChangePoint(newProps, 0);
|
|
31341
|
+
if (!numbers) {
|
|
31342
|
+
return "Range must be a valid number";
|
|
31211
31343
|
}
|
|
31212
|
-
|
|
31213
|
-
|
|
31214
|
-
|
|
31215
|
-
|
|
31216
|
-
|
|
31217
|
-
|
|
31218
|
-
|
|
31219
|
-
|
|
31220
|
-
|
|
31221
|
-
|
|
31222
|
-
|
|
31223
|
-
|
|
31224
|
-
|
|
31344
|
+
if (range[0] >= range[1]) {
|
|
31345
|
+
return "Range must have a higher number on the right";
|
|
31346
|
+
}
|
|
31347
|
+
return true;
|
|
31348
|
+
};
|
|
31349
|
+
validateStepValue = settings => {
|
|
31350
|
+
const {
|
|
31351
|
+
step,
|
|
31352
|
+
range,
|
|
31353
|
+
name,
|
|
31354
|
+
minTicks,
|
|
31355
|
+
maxTicks
|
|
31356
|
+
} = settings;
|
|
31357
|
+
const nSteps = numSteps(range, step);
|
|
31358
|
+
if (nSteps < minTicks) {
|
|
31359
|
+
return name + " is too large, there must be at least " + minTicks + " ticks.";
|
|
31360
|
+
}
|
|
31361
|
+
if (nSteps > maxTicks) {
|
|
31362
|
+
return name + " is too small, there can be at most " + maxTicks + " ticks.";
|
|
31363
|
+
}
|
|
31364
|
+
return true;
|
|
31365
|
+
};
|
|
31366
|
+
validSnapStep = (step, range) => {
|
|
31367
|
+
return this.validateStepValue({
|
|
31368
|
+
step: step,
|
|
31369
|
+
range: range,
|
|
31370
|
+
name: "Snap step",
|
|
31371
|
+
minTicks: 5,
|
|
31372
|
+
maxTicks: 60
|
|
31373
|
+
});
|
|
31374
|
+
};
|
|
31375
|
+
validGridStep = (step, range) => {
|
|
31376
|
+
return this.validateStepValue({
|
|
31377
|
+
step: step,
|
|
31378
|
+
range: range,
|
|
31379
|
+
name: "Grid step",
|
|
31380
|
+
minTicks: 3,
|
|
31381
|
+
maxTicks: 60
|
|
31382
|
+
});
|
|
31383
|
+
};
|
|
31384
|
+
validStep = (step, range) => {
|
|
31385
|
+
return this.validateStepValue({
|
|
31386
|
+
step: step,
|
|
31387
|
+
range: range,
|
|
31388
|
+
name: "Step",
|
|
31389
|
+
minTicks: 3,
|
|
31390
|
+
maxTicks: 20
|
|
31391
|
+
});
|
|
31392
|
+
};
|
|
31393
|
+
validBackgroundImageSize = image => {
|
|
31394
|
+
// Ignore empty images
|
|
31395
|
+
if (!image.url) {
|
|
31396
|
+
return true;
|
|
31397
|
+
}
|
|
31398
|
+
const validSize = image.width <= 450 && image.height <= 450;
|
|
31399
|
+
if (!validSize) {
|
|
31400
|
+
return "Image must be smaller than 450px x 450px.";
|
|
31401
|
+
}
|
|
31402
|
+
return true;
|
|
31403
|
+
};
|
|
31404
|
+
validateGraphSettings = (range, step, gridStep, snapStep, image) => {
|
|
31405
|
+
const self = this;
|
|
31406
|
+
let msg;
|
|
31407
|
+
const goodRange = ___default["default"].every(range, function (range) {
|
|
31408
|
+
msg = self.validRange(range);
|
|
31409
|
+
return msg === true;
|
|
31410
|
+
});
|
|
31411
|
+
if (!goodRange) {
|
|
31412
|
+
return msg;
|
|
31413
|
+
}
|
|
31414
|
+
const goodStep = ___default["default"].every(step, function (step, i) {
|
|
31415
|
+
msg = self.validStep(step, range[i]);
|
|
31416
|
+
return msg === true;
|
|
31417
|
+
});
|
|
31418
|
+
if (!goodStep) {
|
|
31419
|
+
return msg;
|
|
31420
|
+
}
|
|
31421
|
+
const goodGridStep = ___default["default"].every(gridStep, function (gridStep, i) {
|
|
31422
|
+
msg = self.validGridStep(gridStep, range[i]);
|
|
31423
|
+
return msg === true;
|
|
31424
|
+
});
|
|
31425
|
+
if (!goodGridStep) {
|
|
31426
|
+
return msg;
|
|
31427
|
+
}
|
|
31428
|
+
const goodSnapStep = ___default["default"].every(snapStep, function (snapStep, i) {
|
|
31429
|
+
msg = self.validSnapStep(snapStep, range[i]);
|
|
31430
|
+
return msg === true;
|
|
31431
|
+
});
|
|
31432
|
+
if (!goodSnapStep) {
|
|
31433
|
+
return msg;
|
|
31225
31434
|
}
|
|
31226
|
-
|
|
31227
|
-
|
|
31228
|
-
|
|
31229
|
-
|
|
31230
|
-
|
|
31231
|
-
|
|
31232
|
-
};
|
|
31233
|
-
|
|
31234
|
-
|
|
31235
|
-
|
|
31236
|
-
|
|
31237
|
-
|
|
31238
|
-
|
|
31239
|
-
|
|
31240
|
-
|
|
31241
|
-
|
|
31242
|
-
|
|
31243
|
-
|
|
31244
|
-
|
|
31245
|
-
|
|
31246
|
-
|
|
31247
|
-
|
|
31248
|
-
|
|
31249
|
-
|
|
31250
|
-
|
|
31251
|
-
|
|
31252
|
-
|
|
31253
|
-
|
|
31254
|
-
/**
|
|
31255
|
-
* LockedFigureSettings takes in a figure and renders the
|
|
31256
|
-
* respective settings for that figure type.
|
|
31257
|
-
*
|
|
31258
|
-
* Used in the interactive graph editor's locked figures section.
|
|
31259
|
-
*/
|
|
31260
|
-
|
|
31261
|
-
// Union this type with other locked figure types when they are added.
|
|
31262
|
-
|
|
31263
|
-
const LockedFigureSettings = props => {
|
|
31264
|
-
switch (props.type) {
|
|
31265
|
-
case "point":
|
|
31266
|
-
return /*#__PURE__*/React__namespace.createElement(LockedPointSettings, props);
|
|
31267
|
-
case "line":
|
|
31268
|
-
return /*#__PURE__*/React__namespace.createElement(LockedLineSettings, props);
|
|
31269
|
-
case "ellipse":
|
|
31270
|
-
if (props.showM2Features) {
|
|
31271
|
-
return /*#__PURE__*/React__namespace.createElement(LockedEllipseSettings, props);
|
|
31272
|
-
}
|
|
31273
|
-
break;
|
|
31274
|
-
case "vector":
|
|
31275
|
-
if (props.showM2Features) {
|
|
31276
|
-
return /*#__PURE__*/React__namespace.createElement(LockedVectorSettings, props);
|
|
31435
|
+
const goodImageSize = this.validBackgroundImageSize(image);
|
|
31436
|
+
if (goodImageSize !== true) {
|
|
31437
|
+
msg = goodImageSize;
|
|
31438
|
+
return msg;
|
|
31439
|
+
}
|
|
31440
|
+
return true;
|
|
31441
|
+
};
|
|
31442
|
+
changeLabel = (i, e) => {
|
|
31443
|
+
const val = e.target.value;
|
|
31444
|
+
const labels = this.state.labelsTextbox.slice();
|
|
31445
|
+
labels[i] = val;
|
|
31446
|
+
this.setState({
|
|
31447
|
+
labelsTextbox: labels
|
|
31448
|
+
}, this.changeGraph);
|
|
31449
|
+
};
|
|
31450
|
+
changeRange = (i, values) => {
|
|
31451
|
+
const ranges = this.state.rangeTextbox.slice();
|
|
31452
|
+
ranges[i] = values;
|
|
31453
|
+
const step = this.state.stepTextbox.slice();
|
|
31454
|
+
const gridStep = this.state.gridStepTextbox.slice();
|
|
31455
|
+
const snapStep = this.state.snapStepTextbox.slice();
|
|
31456
|
+
const scale = perseus.Util.scaleFromExtent(ranges[i], this.props.box[i]);
|
|
31457
|
+
if (this.validRange(ranges[i]) === true) {
|
|
31458
|
+
step[i] = perseus.Util.tickStepFromExtent(ranges[i], this.props.box[i]);
|
|
31459
|
+
const gridStepValue = perseus.Util.gridStepFromTickStep(step[i], scale);
|
|
31460
|
+
if (gridStepValue) {
|
|
31461
|
+
gridStep[i] = gridStepValue;
|
|
31277
31462
|
}
|
|
31278
|
-
|
|
31279
|
-
|
|
31280
|
-
|
|
31281
|
-
|
|
31463
|
+
snapStep[i] = gridStep[i] / 2;
|
|
31464
|
+
}
|
|
31465
|
+
this.setState({
|
|
31466
|
+
stepTextbox: step,
|
|
31467
|
+
gridStepTextbox: gridStep,
|
|
31468
|
+
snapStepTextbox: snapStep,
|
|
31469
|
+
rangeTextbox: ranges
|
|
31470
|
+
}, this.changeGraph);
|
|
31471
|
+
};
|
|
31472
|
+
changeStep = step => {
|
|
31473
|
+
this.setState({
|
|
31474
|
+
stepTextbox: step
|
|
31475
|
+
}, this.changeGraph);
|
|
31476
|
+
};
|
|
31477
|
+
changeSnapStep = snapStep => {
|
|
31478
|
+
this.setState({
|
|
31479
|
+
snapStepTextbox: snapStep
|
|
31480
|
+
}, this.changeGraph);
|
|
31481
|
+
};
|
|
31482
|
+
changeGridStep = gridStep => {
|
|
31483
|
+
this.setState({
|
|
31484
|
+
gridStepTextbox: gridStep,
|
|
31485
|
+
snapStepTextbox: ___default["default"].map(gridStep, function (step) {
|
|
31486
|
+
return step / 2;
|
|
31487
|
+
})
|
|
31488
|
+
}, this.changeGraph);
|
|
31489
|
+
};
|
|
31490
|
+
changeGraph = () => {
|
|
31491
|
+
const labels = this.state.labelsTextbox;
|
|
31492
|
+
const range = ___default["default"].map(this.state.rangeTextbox, function (range) {
|
|
31493
|
+
return ___default["default"].map(range, Number);
|
|
31494
|
+
});
|
|
31495
|
+
const step = ___default["default"].map(this.state.stepTextbox, Number);
|
|
31496
|
+
const gridStep = this.state.gridStepTextbox;
|
|
31497
|
+
const snapStep = this.state.snapStepTextbox;
|
|
31498
|
+
const image = this.state.backgroundImage;
|
|
31282
31499
|
|
|
31283
|
-
|
|
31284
|
-
|
|
31285
|
-
|
|
31286
|
-
|
|
31287
|
-
|
|
31288
|
-
|
|
31289
|
-
|
|
31290
|
-
|
|
31291
|
-
|
|
31292
|
-
|
|
31293
|
-
|
|
31294
|
-
|
|
31295
|
-
|
|
31296
|
-
|
|
31297
|
-
|
|
31298
|
-
|
|
31299
|
-
|
|
31300
|
-
|
|
31301
|
-
|
|
31302
|
-
|
|
31303
|
-
|
|
31304
|
-
|
|
31305
|
-
|
|
31306
|
-
// focusOptions documentation:
|
|
31307
|
-
//
|
|
31308
|
-
// https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/focus
|
|
31309
|
-
//
|
|
31310
|
-
// Note that there could be cases where we want default focus() behavior.
|
|
31311
|
-
// One that comes to mind is a dropdown with a long list of options that
|
|
31312
|
-
// might be rendered off screen when opened. With this workaround the
|
|
31313
|
-
// selected option would not be scrolled into view if the option is near
|
|
31314
|
-
// the end of the list. We're not aware of any uses of the dropdown where
|
|
31315
|
-
// this is an issue, however, so there isn't currently a way to out of the
|
|
31316
|
-
// `preventScroll` behavior.
|
|
31500
|
+
// validationResult is either:
|
|
31501
|
+
// true -> the settings are valid
|
|
31502
|
+
// a string -> the settings are invalid, and the explanation
|
|
31503
|
+
// is contained in the string
|
|
31504
|
+
// TODO(aria): Refactor this to not be confusing
|
|
31505
|
+
const validationResult = this.validateGraphSettings(range, step, gridStep, snapStep, image);
|
|
31506
|
+
if (validationResult === true) {
|
|
31507
|
+
// either true or a string
|
|
31508
|
+
this.change({
|
|
31509
|
+
valid: true,
|
|
31510
|
+
labels: labels,
|
|
31511
|
+
range: range,
|
|
31512
|
+
step: step,
|
|
31513
|
+
gridStep: gridStep,
|
|
31514
|
+
snapStep: snapStep,
|
|
31515
|
+
backgroundImage: image
|
|
31516
|
+
});
|
|
31517
|
+
} else {
|
|
31518
|
+
this.change({
|
|
31519
|
+
valid: validationResult // a string message, not false
|
|
31520
|
+
});
|
|
31521
|
+
}
|
|
31522
|
+
};
|
|
31317
31523
|
|
|
31318
|
-
|
|
31319
|
-
|
|
31320
|
-
|
|
31321
|
-
|
|
31322
|
-
|
|
31323
|
-
|
|
31324
|
-
|
|
31325
|
-
|
|
31326
|
-
|
|
31327
|
-
|
|
31328
|
-
|
|
31329
|
-
|
|
31330
|
-
|
|
31331
|
-
|
|
31332
|
-
|
|
31333
|
-
|
|
31334
|
-
|
|
31335
|
-
|
|
31336
|
-
|
|
31337
|
-
|
|
31338
|
-
|
|
31339
|
-
|
|
31340
|
-
|
|
31341
|
-
|
|
31342
|
-
|
|
31343
|
-
|
|
31344
|
-
|
|
31345
|
-
|
|
31346
|
-
|
|
31347
|
-
|
|
31348
|
-
|
|
31349
|
-
|
|
31350
|
-
|
|
31351
|
-
|
|
31352
|
-
|
|
31353
|
-
|
|
31354
|
-
|
|
31355
|
-
|
|
31356
|
-
|
|
31357
|
-
|
|
31358
|
-
|
|
31359
|
-
|
|
31360
|
-
|
|
31361
|
-
|
|
31362
|
-
|
|
31363
|
-
|
|
31524
|
+
render() {
|
|
31525
|
+
return /*#__PURE__*/React__namespace.createElement(React__namespace.Fragment, null, /*#__PURE__*/React__namespace.createElement(Heading, {
|
|
31526
|
+
title: "Common Graph Settings",
|
|
31527
|
+
isOpen: this.state.isExpanded,
|
|
31528
|
+
onToggle: () => this.setState({
|
|
31529
|
+
isExpanded: !this.state.isExpanded
|
|
31530
|
+
})
|
|
31531
|
+
}), this.state.isExpanded && /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, null, /*#__PURE__*/React__namespace.createElement("div", {
|
|
31532
|
+
className: "graph-settings"
|
|
31533
|
+
}, /*#__PURE__*/React__namespace.createElement("div", {
|
|
31534
|
+
className: "perseus-widget-row"
|
|
31535
|
+
}, /*#__PURE__*/React__namespace.createElement("div", {
|
|
31536
|
+
className: "perseus-widget-left-col"
|
|
31537
|
+
}, /*#__PURE__*/React__namespace.createElement(LabeledRow, {
|
|
31538
|
+
label: "x Label"
|
|
31539
|
+
}, /*#__PURE__*/React__namespace.createElement("input", {
|
|
31540
|
+
type: "text",
|
|
31541
|
+
className: "graph-settings-axis-label",
|
|
31542
|
+
ref: this.labelXRef,
|
|
31543
|
+
onChange: e => this.changeLabel(0, e),
|
|
31544
|
+
value: this.state.labelsTextbox[0] || ""
|
|
31545
|
+
}))), /*#__PURE__*/React__namespace.createElement("div", {
|
|
31546
|
+
className: "perseus-widget-right-col"
|
|
31547
|
+
}, /*#__PURE__*/React__namespace.createElement(LabeledRow, {
|
|
31548
|
+
label: "y Label"
|
|
31549
|
+
}, /*#__PURE__*/React__namespace.createElement("input", {
|
|
31550
|
+
type: "text",
|
|
31551
|
+
className: "graph-settings-axis-label",
|
|
31552
|
+
ref: this.labelYRef,
|
|
31553
|
+
onChange: e => this.changeLabel(1, e),
|
|
31554
|
+
value: this.state.labelsTextbox[1] || ""
|
|
31555
|
+
})))), /*#__PURE__*/React__namespace.createElement("div", {
|
|
31556
|
+
className: "perseus-widget-row"
|
|
31557
|
+
}, /*#__PURE__*/React__namespace.createElement("div", {
|
|
31558
|
+
className: "perseus-widget-left-col"
|
|
31559
|
+
}, /*#__PURE__*/React__namespace.createElement(LabeledRow, {
|
|
31560
|
+
label: "x Range"
|
|
31561
|
+
}, /*#__PURE__*/React__namespace.createElement(RangeInput$4, {
|
|
31562
|
+
value: this.state.rangeTextbox[0],
|
|
31563
|
+
onChange: vals => this.changeRange(0, vals)
|
|
31564
|
+
}))), /*#__PURE__*/React__namespace.createElement("div", {
|
|
31565
|
+
className: "perseus-widget-right-col"
|
|
31566
|
+
}, /*#__PURE__*/React__namespace.createElement(LabeledRow, {
|
|
31567
|
+
label: "y Range"
|
|
31568
|
+
}, /*#__PURE__*/React__namespace.createElement(RangeInput$4, {
|
|
31569
|
+
value: this.state.rangeTextbox[1],
|
|
31570
|
+
onChange: vals => this.changeRange(1, vals)
|
|
31571
|
+
})))), /*#__PURE__*/React__namespace.createElement("div", {
|
|
31572
|
+
className: "perseus-widget-row"
|
|
31573
|
+
}, /*#__PURE__*/React__namespace.createElement("div", {
|
|
31574
|
+
className: "perseus-widget-left-col"
|
|
31575
|
+
}, /*#__PURE__*/React__namespace.createElement(LabeledRow, {
|
|
31576
|
+
label: "Tick Step"
|
|
31577
|
+
}, /*#__PURE__*/React__namespace.createElement(RangeInput$4, {
|
|
31578
|
+
value: this.state.stepTextbox,
|
|
31579
|
+
onChange: this.changeStep
|
|
31580
|
+
}))), /*#__PURE__*/React__namespace.createElement("div", {
|
|
31581
|
+
className: "perseus-widget-right-col"
|
|
31582
|
+
}, /*#__PURE__*/React__namespace.createElement(LabeledRow, {
|
|
31583
|
+
label: "Grid Step"
|
|
31584
|
+
}, /*#__PURE__*/React__namespace.createElement(RangeInput$4, {
|
|
31585
|
+
value: this.state.gridStepTextbox,
|
|
31586
|
+
onChange: this.changeGridStep
|
|
31587
|
+
})))), /*#__PURE__*/React__namespace.createElement("div", {
|
|
31588
|
+
className: "perseus-widget-row"
|
|
31589
|
+
}, /*#__PURE__*/React__namespace.createElement("div", {
|
|
31590
|
+
className: "perseus-widget-left-col"
|
|
31591
|
+
}, /*#__PURE__*/React__namespace.createElement(LabeledRow, {
|
|
31592
|
+
label: "Snap Step"
|
|
31593
|
+
}, /*#__PURE__*/React__namespace.createElement(RangeInput$4, {
|
|
31594
|
+
value: this.state.snapStepTextbox,
|
|
31595
|
+
onChange: this.changeSnapStep
|
|
31596
|
+
})))), /*#__PURE__*/React__namespace.createElement("div", {
|
|
31597
|
+
className: "perseus-widget-row"
|
|
31598
|
+
}, /*#__PURE__*/React__namespace.createElement(LabeledRow, {
|
|
31599
|
+
label: "Markings:"
|
|
31600
|
+
}, /*#__PURE__*/React__namespace.createElement(ButtonGroup$2, {
|
|
31601
|
+
value: this.props.markings,
|
|
31602
|
+
allowEmpty: false,
|
|
31603
|
+
buttons: [{
|
|
31604
|
+
value: "graph",
|
|
31605
|
+
content: "Graph"
|
|
31606
|
+
}, {
|
|
31607
|
+
value: "grid",
|
|
31608
|
+
content: "Grid"
|
|
31609
|
+
}, {
|
|
31610
|
+
value: "none",
|
|
31611
|
+
content: "None"
|
|
31612
|
+
}],
|
|
31613
|
+
onChange: this.change("markings")
|
|
31614
|
+
}))), /*#__PURE__*/React__namespace.createElement("div", {
|
|
31615
|
+
className: "perseus-widget-left-col"
|
|
31616
|
+
}, /*#__PURE__*/React__namespace.createElement(PropCheckBox$7, {
|
|
31617
|
+
label: "Show tooltips",
|
|
31618
|
+
showTooltips: this.props.showTooltips,
|
|
31619
|
+
onChange: this.change
|
|
31620
|
+
}))), /*#__PURE__*/React__namespace.createElement(LabeledRow, {
|
|
31621
|
+
label: "Background image URL:",
|
|
31622
|
+
style: styles$c.resetSpaceTop
|
|
31623
|
+
}, /*#__PURE__*/React__namespace.createElement("input", {
|
|
31624
|
+
type: "text",
|
|
31625
|
+
className: aphrodite.css(styles$c.backgroundUrlInput),
|
|
31626
|
+
ref: this.bgUrlRef,
|
|
31627
|
+
value: this.state.backgroundImage.url || "",
|
|
31628
|
+
onChange: e => {
|
|
31629
|
+
// Shallow-copied clone
|
|
31630
|
+
const image = {
|
|
31631
|
+
...this.props.backgroundImage
|
|
31632
|
+
};
|
|
31633
|
+
image.url = e.target.value;
|
|
31634
|
+
this.setState({
|
|
31635
|
+
backgroundImage: image
|
|
31636
|
+
});
|
|
31637
|
+
},
|
|
31638
|
+
onKeyPress: this.changeBackgroundUrl,
|
|
31639
|
+
onBlur: this.changeBackgroundUrl
|
|
31640
|
+
}), /*#__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, {
|
|
31641
|
+
style: styles$c.rulerSection
|
|
31642
|
+
}, /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, {
|
|
31643
|
+
style: styles$c.checkboxRow
|
|
31644
|
+
}, /*#__PURE__*/React__namespace.createElement(PropCheckBox$7, {
|
|
31645
|
+
label: "Show ruler",
|
|
31646
|
+
showRuler: this.props.showRuler,
|
|
31647
|
+
onChange: this.change,
|
|
31648
|
+
style: styles$c.resetSpaceTop
|
|
31649
|
+
}), /*#__PURE__*/React__namespace.createElement(PropCheckBox$7, {
|
|
31650
|
+
label: "Show protractor",
|
|
31651
|
+
showProtractor: this.props.showProtractor,
|
|
31652
|
+
onChange: this.change,
|
|
31653
|
+
style: styles$c.resetSpaceTop
|
|
31654
|
+
})), (this.props.showRuler || this.props.showProtractor) && /*#__PURE__*/React__namespace.createElement(Banner__default["default"], {
|
|
31655
|
+
layout: "floating",
|
|
31656
|
+
text: "The ruler and protractor are not accessible. Please consider an alternate approach.",
|
|
31657
|
+
kind: "warning"
|
|
31658
|
+
}), this.props.showRuler && /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, {
|
|
31659
|
+
style: styles$c.spaceTop
|
|
31660
|
+
}, /*#__PURE__*/React__namespace.createElement(LabeledRow, {
|
|
31661
|
+
label: "Ruler label:",
|
|
31662
|
+
style: styles$c.resetSpaceTop
|
|
31663
|
+
}, /*#__PURE__*/React__namespace.createElement(wonderBlocksDropdown.SingleSelect, {
|
|
31664
|
+
id: "ruler-label-select",
|
|
31665
|
+
selectedValue: this.props.rulerLabel,
|
|
31666
|
+
onChange: newValue => {
|
|
31667
|
+
this.change({
|
|
31668
|
+
rulerLabel: newValue
|
|
31669
|
+
});
|
|
31670
|
+
},
|
|
31671
|
+
placeholder: "None",
|
|
31672
|
+
style: styles$c.singleSelectShort
|
|
31673
|
+
}, /*#__PURE__*/React__namespace.createElement(wonderBlocksDropdown.OptionItem, {
|
|
31674
|
+
value: "",
|
|
31675
|
+
label: "None",
|
|
31676
|
+
horizontalRule: "full-width"
|
|
31677
|
+
}), /*#__PURE__*/React__namespace.createElement(wonderBlocksDropdown.OptionItem, {
|
|
31678
|
+
value: "mm",
|
|
31679
|
+
label: "Milimeters"
|
|
31680
|
+
}), /*#__PURE__*/React__namespace.createElement(wonderBlocksDropdown.OptionItem, {
|
|
31681
|
+
value: "cm",
|
|
31682
|
+
label: "Centimeters"
|
|
31683
|
+
}), /*#__PURE__*/React__namespace.createElement(wonderBlocksDropdown.OptionItem, {
|
|
31684
|
+
value: "m",
|
|
31685
|
+
label: "Meters"
|
|
31686
|
+
}), /*#__PURE__*/React__namespace.createElement(wonderBlocksDropdown.OptionItem, {
|
|
31687
|
+
value: "km",
|
|
31688
|
+
label: "Kilometers",
|
|
31689
|
+
horizontalRule: "full-width"
|
|
31690
|
+
}), /*#__PURE__*/React__namespace.createElement(wonderBlocksDropdown.OptionItem, {
|
|
31691
|
+
value: "in",
|
|
31692
|
+
label: "Inches"
|
|
31693
|
+
}), /*#__PURE__*/React__namespace.createElement(wonderBlocksDropdown.OptionItem, {
|
|
31694
|
+
value: "ft",
|
|
31695
|
+
label: "Feet"
|
|
31696
|
+
}), /*#__PURE__*/React__namespace.createElement(wonderBlocksDropdown.OptionItem, {
|
|
31697
|
+
value: "yd",
|
|
31698
|
+
label: "Yards"
|
|
31699
|
+
}), /*#__PURE__*/React__namespace.createElement(wonderBlocksDropdown.OptionItem, {
|
|
31700
|
+
value: "mi",
|
|
31701
|
+
label: "Miles"
|
|
31702
|
+
}))), /*#__PURE__*/React__namespace.createElement(LabeledRow, {
|
|
31703
|
+
label: "Ruler ticks:"
|
|
31704
|
+
}, /*#__PURE__*/React__namespace.createElement(wonderBlocksDropdown.SingleSelect, {
|
|
31705
|
+
id: "ruler-ticks-select",
|
|
31706
|
+
selectedValue: `${this.props.rulerTicks}`,
|
|
31707
|
+
onChange: newValue => {
|
|
31708
|
+
this.change({
|
|
31709
|
+
rulerTicks: newValue
|
|
31710
|
+
});
|
|
31711
|
+
},
|
|
31712
|
+
placeholder: "10",
|
|
31713
|
+
style: styles$c.singleSelectShort
|
|
31714
|
+
}, [1, 2, 4, 8, 10, 16].map(value => /*#__PURE__*/React__namespace.createElement(wonderBlocksDropdown.OptionItem, {
|
|
31715
|
+
key: value,
|
|
31716
|
+
value: `${value}`,
|
|
31717
|
+
label: `${value}`
|
|
31718
|
+
}))))))));
|
|
31364
31719
|
}
|
|
31365
31720
|
}
|
|
31366
|
-
|
|
31367
|
-
const LockedFiguresSection = props => {
|
|
31368
|
-
// Keep track of all figures' accordions' expanded states for the
|
|
31369
|
-
// expand/collapse all button. Set the whole array to false initially.
|
|
31370
|
-
const collapsedStateArray = Array((props.figures ?? []).length).fill(false);
|
|
31371
|
-
const [expandedStates, setExpandedStates] = React__namespace.useState(collapsedStateArray);
|
|
31372
|
-
const uniqueId = wonderBlocksCore.useUniqueIdWithMock().get("locked-figures-section");
|
|
31373
|
-
const {
|
|
31374
|
-
figures,
|
|
31375
|
-
onChange
|
|
31376
|
-
} = props;
|
|
31377
|
-
function addLockedFigure(newFigure) {
|
|
31378
|
-
const lockedFigures = figures || [];
|
|
31379
|
-
const newProps = {
|
|
31380
|
-
lockedFigures: [...lockedFigures, getDefaultFigureForType(newFigure)]
|
|
31381
|
-
};
|
|
31382
|
-
onChange(newProps);
|
|
31383
|
-
setExpandedStates([...expandedStates, true]);
|
|
31384
|
-
}
|
|
31385
|
-
function removeLockedFigure(index) {
|
|
31386
|
-
// eslint-disable-next-line no-alert
|
|
31387
|
-
if (window.confirm("Are you sure you want to delete this figure?")) {
|
|
31388
|
-
const lockedFigures = figures || [];
|
|
31389
|
-
onChange({
|
|
31390
|
-
lockedFigures: [...lockedFigures.slice(0, index), ...lockedFigures.slice(index + 1)]
|
|
31391
|
-
});
|
|
31392
|
-
|
|
31393
|
-
// Update expanded states
|
|
31394
|
-
const newExpandedStates = [...expandedStates];
|
|
31395
|
-
newExpandedStates.splice(index, 1);
|
|
31396
|
-
setExpandedStates(newExpandedStates);
|
|
31397
|
-
}
|
|
31398
|
-
}
|
|
31399
|
-
function changeProps(index,
|
|
31400
|
-
// Omit the type from the figure props so it doesn't think
|
|
31401
|
-
// we're trying to pass in the props for the wrong type.
|
|
31402
|
-
figureProps) {
|
|
31403
|
-
const lockedFigures = figures || [];
|
|
31404
|
-
const newFigures = {
|
|
31405
|
-
lockedFigures: [...lockedFigures.slice(0, index), {
|
|
31406
|
-
...lockedFigures[index],
|
|
31407
|
-
...figureProps
|
|
31408
|
-
}, ...lockedFigures.slice(index + 1)]
|
|
31409
|
-
};
|
|
31410
|
-
onChange(newFigures);
|
|
31411
|
-
}
|
|
31412
|
-
function toggleExpanded(newValue) {
|
|
31413
|
-
setExpandedStates(Array(figures?.length).fill(newValue));
|
|
31414
|
-
}
|
|
31415
|
-
const allCollapsed = expandedStates.every(value => !value);
|
|
31416
|
-
const buttonLabel = allCollapsed ? "Expand all" : "Collapse all";
|
|
31417
|
-
const showExpandButton = !!figures?.length;
|
|
31418
|
-
return /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, null, figures?.map((figure, index) => {
|
|
31419
|
-
return /*#__PURE__*/React__namespace.createElement(LockedFigureSettings, _extends({
|
|
31420
|
-
key: `${uniqueId}-locked-${figure}-${index}`,
|
|
31421
|
-
showM2Features: props.showM2Features,
|
|
31422
|
-
expanded: expandedStates[index],
|
|
31423
|
-
onToggle: newValue => {
|
|
31424
|
-
const newExpanded = [...expandedStates];
|
|
31425
|
-
newExpanded[index] = newValue;
|
|
31426
|
-
setExpandedStates(newExpanded);
|
|
31427
|
-
}
|
|
31428
|
-
}, figure, {
|
|
31429
|
-
onChangeProps: newProps => changeProps(index, newProps),
|
|
31430
|
-
onRemove: () => removeLockedFigure(index)
|
|
31431
|
-
}));
|
|
31432
|
-
}), /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, {
|
|
31433
|
-
style: styles$c.buttonContainer
|
|
31434
|
-
}, /*#__PURE__*/React__namespace.createElement(LockedFigureSelect, {
|
|
31435
|
-
showM2Features: props.showM2Features,
|
|
31436
|
-
id: `${uniqueId}-select`,
|
|
31437
|
-
onChange: addLockedFigure
|
|
31438
|
-
}), /*#__PURE__*/React__namespace.createElement(Strut, {
|
|
31439
|
-
size: wonderBlocksTokens.spacing.small_12
|
|
31440
|
-
}), showExpandButton && /*#__PURE__*/React__namespace.createElement(Button__default["default"], {
|
|
31441
|
-
kind: "secondary",
|
|
31442
|
-
onClick: () => toggleExpanded(allCollapsed),
|
|
31443
|
-
style: styles$c.button
|
|
31444
|
-
}, buttonLabel)));
|
|
31445
|
-
};
|
|
31446
31721
|
const styles$c = aphrodite.StyleSheet.create({
|
|
31447
|
-
|
|
31722
|
+
resetSpaceTop: {
|
|
31723
|
+
marginTop: 0
|
|
31724
|
+
},
|
|
31725
|
+
spaceTop: {
|
|
31726
|
+
marginTop: wonderBlocksTokens.spacing.xSmall_8
|
|
31727
|
+
},
|
|
31728
|
+
singleSelectShort: {
|
|
31729
|
+
// Non-standard spacing, but it's the smallest we can go
|
|
31730
|
+
// without running into styling issues with the dropdown.
|
|
31731
|
+
height: 26
|
|
31732
|
+
},
|
|
31733
|
+
backgroundUrlInput: {
|
|
31734
|
+
border: `1px solid ${wonderBlocksTokens.color.offBlack32}`,
|
|
31735
|
+
borderRadius: wonderBlocksTokens.spacing.xxxSmall_4,
|
|
31736
|
+
padding: wonderBlocksTokens.spacing.xxxSmall_4
|
|
31737
|
+
},
|
|
31738
|
+
checkboxRow: {
|
|
31448
31739
|
flexDirection: "row",
|
|
31449
|
-
alignItems: "center"
|
|
31740
|
+
alignItems: "center",
|
|
31741
|
+
justifyContent: "space-between",
|
|
31742
|
+
marginBottom: wonderBlocksTokens.spacing.xSmall_8
|
|
31450
31743
|
},
|
|
31451
|
-
|
|
31744
|
+
rulerSection: {
|
|
31452
31745
|
marginTop: wonderBlocksTokens.spacing.xSmall_8,
|
|
31453
|
-
|
|
31746
|
+
borderTop: `1px solid ${wonderBlocksTokens.color.offBlack16}`,
|
|
31747
|
+
paddingTop: wonderBlocksTokens.spacing.xSmall_8,
|
|
31748
|
+
paddingBottom: wonderBlocksTokens.spacing.xSmall_8,
|
|
31749
|
+
borderBottom: `1px solid ${wonderBlocksTokens.color.offBlack16}`
|
|
31454
31750
|
}
|
|
31455
31751
|
});
|
|
31456
31752
|
|
|
@@ -31538,6 +31834,15 @@ class InteractiveGraphEditor extends React__namespace.Component {
|
|
|
31538
31834
|
UNSAFE_componentWillMount() {
|
|
31539
31835
|
DeprecationMixin.UNSAFE_componentWillMount.call(this);
|
|
31540
31836
|
}
|
|
31837
|
+
static buildGraphKey(correct) {
|
|
31838
|
+
const testGraphKey = [];
|
|
31839
|
+
for (const key in correct) {
|
|
31840
|
+
if (correct[key]) {
|
|
31841
|
+
typeof correct[key] === "number" || typeof correct[key] === "string" || typeof correct[key] === "boolean" ? testGraphKey.push(correct[key]) : testGraphKey.push(0);
|
|
31842
|
+
}
|
|
31843
|
+
}
|
|
31844
|
+
return testGraphKey.join(":");
|
|
31845
|
+
}
|
|
31541
31846
|
render() {
|
|
31542
31847
|
let graph;
|
|
31543
31848
|
let equationString;
|
|
@@ -31580,10 +31885,9 @@ class InteractiveGraphEditor extends React__namespace.Component {
|
|
|
31580
31885
|
});
|
|
31581
31886
|
}
|
|
31582
31887
|
};
|
|
31583
|
-
|
|
31584
31888
|
// This is used to force a remount of the graph component
|
|
31585
31889
|
// when there's a significant change
|
|
31586
|
-
const graphKey =
|
|
31890
|
+
const graphKey = InteractiveGraphEditor.buildGraphKey(correct);
|
|
31587
31891
|
graph =
|
|
31588
31892
|
/*#__PURE__*/
|
|
31589
31893
|
// There are a bunch of props that renderer.jsx passes to widgets via
|
|
@@ -31796,6 +32100,7 @@ class InteractiveGraphEditor extends React__namespace.Component {
|
|
|
31796
32100
|
// is using Mafs.
|
|
31797
32101
|
this.props.graph && this.props.apiOptions?.flags?.mafs?.[this.props.graph.type] && /*#__PURE__*/React__namespace.createElement(LockedFiguresSection, {
|
|
31798
32102
|
showM2Features: this.props.apiOptions?.flags?.mafs?.["interactive-graph-locked-features-m2"],
|
|
32103
|
+
showM2bFeatures: this.props.apiOptions?.flags?.mafs?.["interactive-graph-locked-features-m2b"],
|
|
31799
32104
|
figures: this.props.lockedFigures,
|
|
31800
32105
|
onChange: this.props.onChange
|
|
31801
32106
|
}));
|