@khanacademy/perseus-editor 6.11.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/{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/es/index.js +2082 -1784
- package/dist/es/index.js.map +1 -1
- package/dist/index.js +2004 -1699
- package/dist/index.js.map +1 -1
- package/dist/widgets/interactive-graph-editor.d.ts +202 -162
- 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/{ellipse-swatch.d.ts → graph-locked-figures/ellipse-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/es/index.js
CHANGED
|
@@ -18,18 +18,25 @@ import { point, vector, number } from '@khanacademy/kmath';
|
|
|
18
18
|
import * as KAS from '@khanacademy/kas';
|
|
19
19
|
import { isTruthy, UnreachableCaseError } from '@khanacademy/wonder-stuff-core';
|
|
20
20
|
import { useMathInputI18n, createMathField } from '@khanacademy/math-input';
|
|
21
|
-
import {
|
|
21
|
+
import { ActionMenu, ActionItem, SingleSelect, OptionItem } from '@khanacademy/wonder-blocks-dropdown';
|
|
22
22
|
import { TextField, Checkbox as Checkbox$1 } from '@khanacademy/wonder-blocks-form';
|
|
23
23
|
import { LabelSmall, LabelMedium, LabelLarge, BodyMonospace } from '@khanacademy/wonder-blocks-typography';
|
|
24
|
-
import Banner from '@khanacademy/wonder-blocks-banner';
|
|
25
24
|
import Button from '@khanacademy/wonder-blocks-button';
|
|
26
25
|
import { AccordionSection } from '@khanacademy/wonder-blocks-accordion';
|
|
26
|
+
import IconButton from '@khanacademy/wonder-blocks-icon-button';
|
|
27
|
+
import caretDoubleDownIcon from '@phosphor-icons/core/bold/caret-double-down-bold.svg';
|
|
28
|
+
import caretDoubleUpIcon from '@phosphor-icons/core/bold/caret-double-up-bold.svg';
|
|
29
|
+
import caretDownIcon from '@phosphor-icons/core/bold/caret-down-bold.svg';
|
|
30
|
+
import caretUpIcon from '@phosphor-icons/core/bold/caret-up-bold.svg';
|
|
27
31
|
import trashIcon from '@phosphor-icons/core/bold/trash-bold.svg';
|
|
28
32
|
import Switch from '@khanacademy/wonder-blocks-switch';
|
|
33
|
+
import minusCircle from '@phosphor-icons/core/regular/minus-circle.svg';
|
|
34
|
+
import plusCircle from '@phosphor-icons/core/regular/plus-circle.svg';
|
|
35
|
+
import Banner from '@khanacademy/wonder-blocks-banner';
|
|
29
36
|
|
|
30
37
|
// This file is processed by a Rollup plugin (replace) to inject the production
|
|
31
38
|
const libName = "@khanacademy/perseus-editor";
|
|
32
|
-
const libVersion = "6.
|
|
39
|
+
const libVersion = "6.12.0";
|
|
33
40
|
addLibraryVersionToPerseusDebug(libName, libVersion);
|
|
34
41
|
|
|
35
42
|
function _extends() {
|
|
@@ -219,7 +226,7 @@ class SectionControlButton extends React.Component {
|
|
|
219
226
|
role: "button",
|
|
220
227
|
hideDefaultFocusRing: true,
|
|
221
228
|
"aria-label": title,
|
|
222
|
-
style: styles$
|
|
229
|
+
style: styles$G.button
|
|
223
230
|
}, ({
|
|
224
231
|
hovered,
|
|
225
232
|
focused,
|
|
@@ -227,7 +234,7 @@ class SectionControlButton extends React.Component {
|
|
|
227
234
|
}) => /*#__PURE__*/React.createElement(InlineIcon$b, icon));
|
|
228
235
|
}
|
|
229
236
|
}
|
|
230
|
-
const styles$
|
|
237
|
+
const styles$G = StyleSheet.create({
|
|
231
238
|
button: {
|
|
232
239
|
backgroundColor: color.gold,
|
|
233
240
|
margin: 2,
|
|
@@ -20732,13 +20739,13 @@ class WidgetSelect extends React.Component {
|
|
|
20732
20739
|
* that collapse a region.
|
|
20733
20740
|
*/
|
|
20734
20741
|
function ToggleableCaret(props) {
|
|
20735
|
-
const iconStyle = props.isExpanded ? styles$
|
|
20742
|
+
const iconStyle = props.isExpanded ? styles$F.expanded : styles$F.collapsed;
|
|
20736
20743
|
return /*#__PURE__*/React.createElement(PhosphorIcon, {
|
|
20737
20744
|
icon: caretRight,
|
|
20738
20745
|
style: iconStyle
|
|
20739
20746
|
});
|
|
20740
20747
|
}
|
|
20741
|
-
const styles$
|
|
20748
|
+
const styles$F = StyleSheet.create({
|
|
20742
20749
|
collapsed: {
|
|
20743
20750
|
transition: ".15s"
|
|
20744
20751
|
},
|
|
@@ -20771,16 +20778,16 @@ class TexErrorView extends React.Component {
|
|
|
20771
20778
|
showErrors
|
|
20772
20779
|
} = this.state;
|
|
20773
20780
|
return /*#__PURE__*/React.createElement(View, {
|
|
20774
|
-
style: styles$
|
|
20781
|
+
style: styles$E.errorContainer
|
|
20775
20782
|
}, /*#__PURE__*/React.createElement(View, {
|
|
20776
|
-
style: styles$
|
|
20783
|
+
style: styles$E.title,
|
|
20777
20784
|
onClick: this.handleToggleTexErrors
|
|
20778
20785
|
}, /*#__PURE__*/React.createElement(ToggleableCaret, {
|
|
20779
20786
|
isExpanded: showErrors
|
|
20780
20787
|
}), "\xA0 TeX Errors (", errorList.length, ")"), showErrors && /*#__PURE__*/React.createElement(View, {
|
|
20781
|
-
style: styles$
|
|
20788
|
+
style: styles$E.errorExplanation
|
|
20782
20789
|
}, "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.createElement(View, {
|
|
20783
|
-
style: styles$
|
|
20790
|
+
style: styles$E.error,
|
|
20784
20791
|
key: index
|
|
20785
20792
|
}, /*#__PURE__*/React.createElement(View, {
|
|
20786
20793
|
style: {
|
|
@@ -20789,7 +20796,7 @@ class TexErrorView extends React.Component {
|
|
|
20789
20796
|
}, e.math), /*#__PURE__*/React.createElement(View, null, e.message))));
|
|
20790
20797
|
}
|
|
20791
20798
|
}
|
|
20792
|
-
const styles$
|
|
20799
|
+
const styles$E = StyleSheet.create({
|
|
20793
20800
|
title: {
|
|
20794
20801
|
backgroundColor: "#eee",
|
|
20795
20802
|
fontSize: "1.25em",
|
|
@@ -24583,7 +24590,7 @@ class SimpleButton extends React.Component {
|
|
|
24583
24590
|
} = _this$props,
|
|
24584
24591
|
otherProps = _objectWithoutPropertiesLoose(_this$props, _excluded$3);
|
|
24585
24592
|
return /*#__PURE__*/React.createElement("div", _extends({
|
|
24586
|
-
className: css(styles$
|
|
24593
|
+
className: css(styles$D.baseButton, color === "green" && styles$D.green, color === "orange" && styles$D.orange),
|
|
24587
24594
|
onClick: onClick
|
|
24588
24595
|
}, otherProps), children);
|
|
24589
24596
|
}
|
|
@@ -24598,7 +24605,7 @@ SimpleButton.defaultProps = {
|
|
|
24598
24605
|
color: "green",
|
|
24599
24606
|
onClick: () => {}
|
|
24600
24607
|
};
|
|
24601
|
-
const styles$
|
|
24608
|
+
const styles$D = StyleSheet.create({
|
|
24602
24609
|
baseButton: {
|
|
24603
24610
|
top: "0",
|
|
24604
24611
|
fontSize: "11px",
|
|
@@ -24818,23 +24825,23 @@ const LeafContainer = ({
|
|
|
24818
24825
|
}) => {
|
|
24819
24826
|
const hasPreviewHeading = shape.type === "content" || shape.type === "hint";
|
|
24820
24827
|
const previewHeading = hasPreviewHeading && /*#__PURE__*/React.createElement("div", {
|
|
24821
|
-
className: css(styles$
|
|
24828
|
+
className: css(styles$C.containerHeader)
|
|
24822
24829
|
}, /*#__PURE__*/React.createElement(Header, {
|
|
24823
24830
|
depth: path.length,
|
|
24824
|
-
className: css(styles$
|
|
24831
|
+
className: css(styles$C.containerTitle)
|
|
24825
24832
|
}, capitalize(name)));
|
|
24826
24833
|
return /*#__PURE__*/React.createElement("div", {
|
|
24827
|
-
className: css(styles$
|
|
24834
|
+
className: css(styles$C.container)
|
|
24828
24835
|
}, /*#__PURE__*/React.createElement("span", {
|
|
24829
|
-
className: css(styles$
|
|
24836
|
+
className: css(styles$C.row, styles$C.rowHeading)
|
|
24830
24837
|
}, /*#__PURE__*/React.createElement("div", {
|
|
24831
|
-
className: css(styles$
|
|
24838
|
+
className: css(styles$C.columnLeft)
|
|
24832
24839
|
}, /*#__PURE__*/React.createElement("div", {
|
|
24833
|
-
className: "pod-title " + css(styles$
|
|
24840
|
+
className: "pod-title " + css(styles$C.containerHeader)
|
|
24834
24841
|
}, /*#__PURE__*/React.createElement("div", {
|
|
24835
|
-
className: css(styles$
|
|
24842
|
+
className: css(styles$C.containerTitle)
|
|
24836
24843
|
}, capitalize(name)), controls)), /*#__PURE__*/React.createElement("div", {
|
|
24837
|
-
className: css(styles$
|
|
24844
|
+
className: css(styles$C.columnRight)
|
|
24838
24845
|
}, previewHeading)), children);
|
|
24839
24846
|
};
|
|
24840
24847
|
const ArrayContainer = props => {
|
|
@@ -24847,11 +24854,11 @@ const ArrayContainer = props => {
|
|
|
24847
24854
|
actions
|
|
24848
24855
|
} = props;
|
|
24849
24856
|
return /*#__PURE__*/React.createElement("div", {
|
|
24850
|
-
className: css(styles$
|
|
24857
|
+
className: css(styles$C.container)
|
|
24851
24858
|
}, controls && /*#__PURE__*/React.createElement("div", {
|
|
24852
|
-
className: css(styles$
|
|
24859
|
+
className: css(styles$C.columnLeft, styles$C.containerHeader)
|
|
24853
24860
|
}, controls), /*#__PURE__*/React.createElement("div", null, children), /*#__PURE__*/React.createElement("div", {
|
|
24854
|
-
className: css(styles$
|
|
24861
|
+
className: css(styles$C.columnLeft)
|
|
24855
24862
|
}, /*#__PURE__*/React.createElement("a", {
|
|
24856
24863
|
href: "javascript:void 0",
|
|
24857
24864
|
onClick: () => actions.addArrayElement(path, shape.elementShape)
|
|
@@ -24864,28 +24871,28 @@ const ObjectContainer = ({
|
|
|
24864
24871
|
path
|
|
24865
24872
|
}) => {
|
|
24866
24873
|
const headingEditor = /*#__PURE__*/React.createElement("div", {
|
|
24867
|
-
className: css(styles$
|
|
24874
|
+
className: css(styles$C.containerHeader)
|
|
24868
24875
|
}, /*#__PURE__*/React.createElement(Header, {
|
|
24869
24876
|
depth: path.length,
|
|
24870
|
-
className: css(styles$
|
|
24877
|
+
className: css(styles$C.containerTitle)
|
|
24871
24878
|
}, capitalize(name)), controls);
|
|
24872
24879
|
const headingPreview = (name || controls) && /*#__PURE__*/React.createElement("div", {
|
|
24873
|
-
className: css(styles$
|
|
24880
|
+
className: css(styles$C.containerHeader, styles$C.previewCollectionHeader)
|
|
24874
24881
|
}, /*#__PURE__*/React.createElement(Header, {
|
|
24875
24882
|
depth: path.length,
|
|
24876
|
-
className: css(styles$
|
|
24883
|
+
className: css(styles$C.containerTitle)
|
|
24877
24884
|
}, capitalize(name)));
|
|
24878
24885
|
const hasBothHeadings = headingEditor && headingPreview;
|
|
24879
24886
|
return /*#__PURE__*/React.createElement("div", {
|
|
24880
|
-
className: css(styles$
|
|
24887
|
+
className: css(styles$C.container)
|
|
24881
24888
|
}, hasBothHeadings && /*#__PURE__*/React.createElement("span", {
|
|
24882
|
-
className: css(styles$
|
|
24889
|
+
className: css(styles$C.row)
|
|
24883
24890
|
}, /*#__PURE__*/React.createElement("div", {
|
|
24884
|
-
className: css(styles$
|
|
24891
|
+
className: css(styles$C.columnLeft)
|
|
24885
24892
|
}, headingEditor), /*#__PURE__*/React.createElement("div", {
|
|
24886
|
-
className: css(styles$
|
|
24893
|
+
className: css(styles$C.columnRight)
|
|
24887
24894
|
}, headingPreview)), /*#__PURE__*/React.createElement("div", {
|
|
24888
|
-
className: css(path.length > 0 && styles$
|
|
24895
|
+
className: css(path.length > 0 && styles$C.contentIndent)
|
|
24889
24896
|
}, children));
|
|
24890
24897
|
};
|
|
24891
24898
|
|
|
@@ -25008,11 +25015,11 @@ const ItemNodeContent = withStickiness(props => {
|
|
|
25008
25015
|
className: "framework-perseus"
|
|
25009
25016
|
}, lens(renderers).get(path));
|
|
25010
25017
|
return /*#__PURE__*/React.createElement("span", null, /*#__PURE__*/React.createElement("div", {
|
|
25011
|
-
className: css(styles$
|
|
25018
|
+
className: css(styles$C.row)
|
|
25012
25019
|
}, /*#__PURE__*/React.createElement("div", {
|
|
25013
|
-
className: css(styles$
|
|
25020
|
+
className: css(styles$C.columnLeft)
|
|
25014
25021
|
}, /*#__PURE__*/React.createElement("div", {
|
|
25015
|
-
className: css(sticky && styles$
|
|
25022
|
+
className: css(sticky && styles$C.sticky)
|
|
25016
25023
|
},
|
|
25017
25024
|
/*#__PURE__*/
|
|
25018
25025
|
// @ts-expect-error - TS2769 - No overload matches this call.
|
|
@@ -25020,9 +25027,9 @@ const ItemNodeContent = withStickiness(props => {
|
|
|
25020
25027
|
onChange: newVal => actions.mergeValueAtPath(path, newVal),
|
|
25021
25028
|
apiOptions: apiOptions
|
|
25022
25029
|
})))), /*#__PURE__*/React.createElement("div", {
|
|
25023
|
-
className: css(styles$
|
|
25030
|
+
className: css(styles$C.columnRight)
|
|
25024
25031
|
}, /*#__PURE__*/React.createElement("div", {
|
|
25025
|
-
className: css(sticky && styles$
|
|
25032
|
+
className: css(sticky && styles$C.sticky)
|
|
25026
25033
|
}, preview))));
|
|
25027
25034
|
});
|
|
25028
25035
|
const HintNodeContent = withStickiness(props => {
|
|
@@ -25038,13 +25045,13 @@ const HintNodeContent = withStickiness(props => {
|
|
|
25038
25045
|
className: "framework-perseus"
|
|
25039
25046
|
}, lens(renderers).get(path));
|
|
25040
25047
|
return /*#__PURE__*/React.createElement("div", {
|
|
25041
|
-
className: css(styles$
|
|
25048
|
+
className: css(styles$C.row)
|
|
25042
25049
|
}, /*#__PURE__*/React.createElement("div", {
|
|
25043
|
-
className: css(styles$
|
|
25050
|
+
className: css(styles$C.columnLeft)
|
|
25044
25051
|
}, /*#__PURE__*/React.createElement("div", {
|
|
25045
|
-
className: css(sticky && styles$
|
|
25052
|
+
className: css(sticky && styles$C.sticky)
|
|
25046
25053
|
}, /*#__PURE__*/React.createElement(HintEditor, _extends({}, data, {
|
|
25047
|
-
className: css(styles$
|
|
25054
|
+
className: css(styles$C.hintEditor),
|
|
25048
25055
|
onChange: newVal => actions.mergeValueAtPath(path, newVal),
|
|
25049
25056
|
apiOptions: apiOptions,
|
|
25050
25057
|
showTitle: false,
|
|
@@ -25059,9 +25066,9 @@ const HintNodeContent = withStickiness(props => {
|
|
|
25059
25066
|
isFirst: true,
|
|
25060
25067
|
isLast: true
|
|
25061
25068
|
})))), /*#__PURE__*/React.createElement("div", {
|
|
25062
|
-
className: css(styles$
|
|
25069
|
+
className: css(styles$C.columnRight)
|
|
25063
25070
|
}, /*#__PURE__*/React.createElement("div", {
|
|
25064
|
-
className: css(sticky && styles$
|
|
25071
|
+
className: css(sticky && styles$C.sticky)
|
|
25065
25072
|
}, preview)));
|
|
25066
25073
|
});
|
|
25067
25074
|
const TagsNodeContent = props => {
|
|
@@ -25078,9 +25085,9 @@ const TagsNodeContent = props => {
|
|
|
25078
25085
|
return null;
|
|
25079
25086
|
}
|
|
25080
25087
|
return /*#__PURE__*/React.createElement("div", {
|
|
25081
|
-
className: css(styles$
|
|
25088
|
+
className: css(styles$C.columnLeft)
|
|
25082
25089
|
}, /*#__PURE__*/React.createElement("div", {
|
|
25083
|
-
className: css(styles$
|
|
25090
|
+
className: css(styles$C.tagsEditor)
|
|
25084
25091
|
}, /*#__PURE__*/React.createElement(GroupMetadataEditor, {
|
|
25085
25092
|
value: data,
|
|
25086
25093
|
onChange: newVal => actions.setValueAtPath(path, newVal),
|
|
@@ -25111,23 +25118,23 @@ const ArrayNodeContent = props => {
|
|
|
25111
25118
|
const subpath = path.concat(i);
|
|
25112
25119
|
const controls = [i > 0 && /*#__PURE__*/React.createElement("div", {
|
|
25113
25120
|
key: "moveArrayElementUp",
|
|
25114
|
-
className: css(styles$
|
|
25121
|
+
className: css(styles$C.control)
|
|
25115
25122
|
}, /*#__PURE__*/React.createElement(SimpleButton, {
|
|
25116
25123
|
color: "orange",
|
|
25117
25124
|
title: "Move up",
|
|
25118
25125
|
onClick: () => actions.moveArrayElementUp(subpath)
|
|
25119
25126
|
}, /*#__PURE__*/React.createElement("div", {
|
|
25120
|
-
className: css(styles$
|
|
25127
|
+
className: css(styles$C.verticalFlip)
|
|
25121
25128
|
}, /*#__PURE__*/React.createElement(InlineIcon$6, iconChevronDown)))), i < data.length - 1 && /*#__PURE__*/React.createElement("div", {
|
|
25122
25129
|
key: "moveArrayElementDown",
|
|
25123
|
-
className: css(styles$
|
|
25130
|
+
className: css(styles$C.control)
|
|
25124
25131
|
}, /*#__PURE__*/React.createElement(SimpleButton, {
|
|
25125
25132
|
color: "orange",
|
|
25126
25133
|
title: "Move down",
|
|
25127
25134
|
onClick: () => actions.moveArrayElementDown(subpath)
|
|
25128
25135
|
}, /*#__PURE__*/React.createElement(InlineIcon$6, iconChevronDown))), /*#__PURE__*/React.createElement("div", {
|
|
25129
25136
|
key: "removeArrayElement",
|
|
25130
|
-
className: css(styles$
|
|
25137
|
+
className: css(styles$C.control)
|
|
25131
25138
|
}, /*#__PURE__*/React.createElement(SimpleButton, {
|
|
25132
25139
|
color: "orange",
|
|
25133
25140
|
title: "Delete",
|
|
@@ -25135,7 +25142,7 @@ const ArrayNodeContent = props => {
|
|
|
25135
25142
|
}, /*#__PURE__*/React.createElement(InlineIcon$6, iconTrash$4)))];
|
|
25136
25143
|
return /*#__PURE__*/React.createElement("div", {
|
|
25137
25144
|
key: i,
|
|
25138
|
-
className: css(styles$
|
|
25145
|
+
className: css(styles$C.arrayElement, !elementIsLeaf && styles$C.arrayElementAndNotLeaf)
|
|
25139
25146
|
}, /*#__PURE__*/React.createElement(NodeContainer, _extends({}, otherProps, {
|
|
25140
25147
|
key: i,
|
|
25141
25148
|
shape: shape.elementShape,
|
|
@@ -25161,7 +25168,7 @@ const ObjectNodeContent = props => {
|
|
|
25161
25168
|
// made sense to the shape's author is the order in which we'll iterate :)
|
|
25162
25169
|
const children = Object.keys(shape.shape).map(subkey => /*#__PURE__*/React.createElement("div", {
|
|
25163
25170
|
key: subkey,
|
|
25164
|
-
className: css(styles$
|
|
25171
|
+
className: css(styles$C.objectElement)
|
|
25165
25172
|
}, /*#__PURE__*/React.createElement(NodeContainer, _extends({}, otherProps, {
|
|
25166
25173
|
shape: shape.shape[subkey],
|
|
25167
25174
|
data: data[subkey],
|
|
@@ -25328,7 +25335,7 @@ class MultiRendererEditor extends React.Component {
|
|
|
25328
25335
|
}, this._renderContent());
|
|
25329
25336
|
}
|
|
25330
25337
|
}
|
|
25331
|
-
const styles$
|
|
25338
|
+
const styles$C = StyleSheet.create({
|
|
25332
25339
|
// This is used in a number of places throughout this file.
|
|
25333
25340
|
container: {},
|
|
25334
25341
|
// eslint-disable-next-line react-native/no-unused-styles
|
|
@@ -25480,47 +25487,47 @@ const StatefulArticleEditor = createReactClass({
|
|
|
25480
25487
|
screen
|
|
25481
25488
|
} = this.state;
|
|
25482
25489
|
return /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("div", {
|
|
25483
|
-
style: styles$
|
|
25490
|
+
style: styles$B.controlBar
|
|
25484
25491
|
}, /*#__PURE__*/React.createElement("span", {
|
|
25485
|
-
style: styles$
|
|
25492
|
+
style: styles$B.controls
|
|
25486
25493
|
}, "Mode:", " ", /*#__PURE__*/React.createElement("span", {
|
|
25487
25494
|
onClick: () => this.setState({
|
|
25488
25495
|
mode: "edit"
|
|
25489
25496
|
}),
|
|
25490
|
-
style: mode === "edit" ? styles$
|
|
25497
|
+
style: mode === "edit" ? styles$B.controlSelected : styles$B.control
|
|
25491
25498
|
}, "EDIT"), " | ", /*#__PURE__*/React.createElement("span", {
|
|
25492
25499
|
onClick: () => this.setState({
|
|
25493
25500
|
mode: "preview"
|
|
25494
25501
|
}),
|
|
25495
|
-
style: mode === "preview" ? styles$
|
|
25502
|
+
style: mode === "preview" ? styles$B.controlSelected : styles$B.control
|
|
25496
25503
|
}, "PREVIEW"), " | ", /*#__PURE__*/React.createElement("span", {
|
|
25497
25504
|
onClick: () => this.setState({
|
|
25498
25505
|
mode: "json"
|
|
25499
25506
|
}),
|
|
25500
|
-
style: mode === "json" ? styles$
|
|
25507
|
+
style: mode === "json" ? styles$B.controlSelected : styles$B.control
|
|
25501
25508
|
}, "JSON")), /*#__PURE__*/React.createElement("span", {
|
|
25502
|
-
style: styles$
|
|
25509
|
+
style: styles$B.controls
|
|
25503
25510
|
}, "Screen:", " ", /*#__PURE__*/React.createElement("span", {
|
|
25504
25511
|
onClick: () => this.setState({
|
|
25505
25512
|
screen: "phone"
|
|
25506
25513
|
}),
|
|
25507
|
-
style: screen === "phone" ? styles$
|
|
25514
|
+
style: screen === "phone" ? styles$B.controlSelected : styles$B.control
|
|
25508
25515
|
}, "PHONE"), " | ", /*#__PURE__*/React.createElement("span", {
|
|
25509
25516
|
onClick: () => this.setState({
|
|
25510
25517
|
screen: "tablet"
|
|
25511
25518
|
}),
|
|
25512
|
-
style: screen === "tablet" ? styles$
|
|
25519
|
+
style: screen === "tablet" ? styles$B.controlSelected : styles$B.control
|
|
25513
25520
|
}, "TABLET"), " | ", /*#__PURE__*/React.createElement("span", {
|
|
25514
25521
|
onClick: () => this.setState({
|
|
25515
25522
|
screen: "desktop"
|
|
25516
25523
|
}),
|
|
25517
|
-
style: screen === "desktop" ? styles$
|
|
25524
|
+
style: screen === "desktop" ? styles$B.controlSelected : styles$B.control
|
|
25518
25525
|
}, "DESKTOP"))), /*#__PURE__*/React.createElement("div", {
|
|
25519
|
-
style: styles$
|
|
25526
|
+
style: styles$B.editor
|
|
25520
25527
|
}, /*#__PURE__*/React.createElement(ArticleEditor, this.state)));
|
|
25521
25528
|
}
|
|
25522
25529
|
});
|
|
25523
|
-
const styles$
|
|
25530
|
+
const styles$B = {
|
|
25524
25531
|
controlBar: {
|
|
25525
25532
|
marginBottom: 25,
|
|
25526
25533
|
marginTop: 5
|
|
@@ -27010,10 +27017,10 @@ class GradedGroupEditor extends React.Component {
|
|
|
27010
27017
|
}, /*#__PURE__*/React.createElement("div", {
|
|
27011
27018
|
className: "perseus-widget-row"
|
|
27012
27019
|
}, /*#__PURE__*/React.createElement("label", {
|
|
27013
|
-
className: css(styles$
|
|
27020
|
+
className: css(styles$A.title)
|
|
27014
27021
|
}, "Title:", " ", /*#__PURE__*/React.createElement(TextInput$6, {
|
|
27015
27022
|
value: this.props.title,
|
|
27016
|
-
className: css(styles$
|
|
27023
|
+
className: css(styles$A.input)
|
|
27017
27024
|
// @ts-expect-error - TS2554 - Expected 3 arguments, but got 1.
|
|
27018
27025
|
,
|
|
27019
27026
|
onChange: this.change("title")
|
|
@@ -27038,7 +27045,7 @@ class GradedGroupEditor extends React.Component {
|
|
|
27038
27045
|
}, /*#__PURE__*/React.createElement(InlineIcon$4, iconPlus$1), " Add a hint"), this.props.hint && /*#__PURE__*/React.createElement("div", {
|
|
27039
27046
|
className: "perseus-hint-editor"
|
|
27040
27047
|
}, /*#__PURE__*/React.createElement("div", {
|
|
27041
|
-
className: css(styles$
|
|
27048
|
+
className: css(styles$A.hintsTitle)
|
|
27042
27049
|
}, "Hint"), /*#__PURE__*/React.createElement(Editor, {
|
|
27043
27050
|
ref: this.hintEditor,
|
|
27044
27051
|
content: this.props.hint ? this.props.hint.content : "",
|
|
@@ -27075,7 +27082,7 @@ GradedGroupEditor.defaultProps = {
|
|
|
27075
27082
|
images: {},
|
|
27076
27083
|
hint: null
|
|
27077
27084
|
};
|
|
27078
|
-
const styles$
|
|
27085
|
+
const styles$A = StyleSheet.create({
|
|
27079
27086
|
title: {
|
|
27080
27087
|
fontSize: 18,
|
|
27081
27088
|
fontWeight: "bold"
|
|
@@ -28414,13 +28421,13 @@ function MathquillInput(props) {
|
|
|
28414
28421
|
}
|
|
28415
28422
|
});
|
|
28416
28423
|
return /*#__PURE__*/React.createElement(View, {
|
|
28417
|
-
style: styles$
|
|
28424
|
+
style: styles$z.outerWrapper
|
|
28418
28425
|
}, /*#__PURE__*/React.createElement("span", {
|
|
28419
28426
|
ref: mathFieldWrapperRef,
|
|
28420
28427
|
className: "perseus-math-input mq-editable-field mq-math-mode"
|
|
28421
28428
|
}));
|
|
28422
28429
|
}
|
|
28423
|
-
const styles$
|
|
28430
|
+
const styles$z = StyleSheet.create({
|
|
28424
28431
|
outerWrapper: {
|
|
28425
28432
|
display: "inline-block",
|
|
28426
28433
|
borderStyle: "solid",
|
|
@@ -29457,95 +29464,6 @@ class InteractionEditor extends React.Component {
|
|
|
29457
29464
|
InteractionEditor.widgetName = "interaction";
|
|
29458
29465
|
InteractionEditor.defaultProps = defaultInteractionProps;
|
|
29459
29466
|
|
|
29460
|
-
const UNLIMITED = "unlimited";
|
|
29461
|
-
// Parses a string (ostensibly from some UI element that only supports string
|
|
29462
|
-
// types, such as a <select />) into a numeric point count or the special sigil
|
|
29463
|
-
// "unlimited". Note that 0 is a special case, and means "unlimited".
|
|
29464
|
-
const parsePointCount = points => {
|
|
29465
|
-
const parsed = parseInt(points, 10);
|
|
29466
|
-
if (isNaN(parsed)) {
|
|
29467
|
-
return UNLIMITED;
|
|
29468
|
-
}
|
|
29469
|
-
return parsed === 0 ? UNLIMITED : parsed;
|
|
29470
|
-
};
|
|
29471
|
-
|
|
29472
|
-
const GraphPointsCountSelector = ({
|
|
29473
|
-
numPoints: _numPoints = 1,
|
|
29474
|
-
onChange
|
|
29475
|
-
}) => {
|
|
29476
|
-
return /*#__PURE__*/React.createElement(SingleSelect, {
|
|
29477
|
-
selectedValue: `${_numPoints}`,
|
|
29478
|
-
onChange: newValue => {
|
|
29479
|
-
onChange(parsePointCount(newValue));
|
|
29480
|
-
}
|
|
29481
|
-
// Never uses placeholder, always has value
|
|
29482
|
-
,
|
|
29483
|
-
placeholder: "",
|
|
29484
|
-
style: styles$v.singleSelectShort
|
|
29485
|
-
}, [...[...Array(7).keys()].map(n => /*#__PURE__*/React.createElement(OptionItem, {
|
|
29486
|
-
key: n,
|
|
29487
|
-
value: `${n}`,
|
|
29488
|
-
label: `${n} point${n > 1 ? "s" : ""}`
|
|
29489
|
-
})), /*#__PURE__*/React.createElement(OptionItem, {
|
|
29490
|
-
key: "unlimited",
|
|
29491
|
-
value: UNLIMITED,
|
|
29492
|
-
label: "unlimited"
|
|
29493
|
-
})]);
|
|
29494
|
-
};
|
|
29495
|
-
const styles$v = StyleSheet.create({
|
|
29496
|
-
singleSelectShort: {
|
|
29497
|
-
// Non-standard spacing, but it's the smallest we can go
|
|
29498
|
-
// without running into styling issues with the dropdown.
|
|
29499
|
-
height: 26
|
|
29500
|
-
}
|
|
29501
|
-
});
|
|
29502
|
-
|
|
29503
|
-
const GraphTypeSelector = props => {
|
|
29504
|
-
return /*#__PURE__*/React.createElement(SingleSelect, {
|
|
29505
|
-
selectedValue: props.graphType,
|
|
29506
|
-
onChange: props.onChange,
|
|
29507
|
-
placeholder: "Select a graph type",
|
|
29508
|
-
style: styles$u.singleSelectShort
|
|
29509
|
-
}, /*#__PURE__*/React.createElement(OptionItem, {
|
|
29510
|
-
value: "linear",
|
|
29511
|
-
label: "Linear function"
|
|
29512
|
-
}), /*#__PURE__*/React.createElement(OptionItem, {
|
|
29513
|
-
value: "quadratic",
|
|
29514
|
-
label: "Quadratic function"
|
|
29515
|
-
}), /*#__PURE__*/React.createElement(OptionItem, {
|
|
29516
|
-
value: "sinusoid",
|
|
29517
|
-
label: "Sinusoid function"
|
|
29518
|
-
}), /*#__PURE__*/React.createElement(OptionItem, {
|
|
29519
|
-
value: "circle",
|
|
29520
|
-
label: "Circle"
|
|
29521
|
-
}), /*#__PURE__*/React.createElement(OptionItem, {
|
|
29522
|
-
value: "point",
|
|
29523
|
-
label: "Point(s)"
|
|
29524
|
-
}), /*#__PURE__*/React.createElement(OptionItem, {
|
|
29525
|
-
value: "linear-system",
|
|
29526
|
-
label: "Linear System"
|
|
29527
|
-
}), /*#__PURE__*/React.createElement(OptionItem, {
|
|
29528
|
-
value: "polygon",
|
|
29529
|
-
label: "Polygon"
|
|
29530
|
-
}), /*#__PURE__*/React.createElement(OptionItem, {
|
|
29531
|
-
value: "segment",
|
|
29532
|
-
label: "Line Segment(s)"
|
|
29533
|
-
}), /*#__PURE__*/React.createElement(OptionItem, {
|
|
29534
|
-
value: "ray",
|
|
29535
|
-
label: "Ray"
|
|
29536
|
-
}), /*#__PURE__*/React.createElement(OptionItem, {
|
|
29537
|
-
value: "angle",
|
|
29538
|
-
label: "Angle"
|
|
29539
|
-
}));
|
|
29540
|
-
};
|
|
29541
|
-
const styles$u = StyleSheet.create({
|
|
29542
|
-
singleSelectShort: {
|
|
29543
|
-
// Non-standard spacing, but it's the smallest we can go
|
|
29544
|
-
// without running into styling issues with the dropdown.
|
|
29545
|
-
height: 26
|
|
29546
|
-
}
|
|
29547
|
-
});
|
|
29548
|
-
|
|
29549
29467
|
// Renders the given children in a View laid out horizontally.
|
|
29550
29468
|
const LabeledRow = props => {
|
|
29551
29469
|
const {
|
|
@@ -29555,16 +29473,16 @@ const LabeledRow = props => {
|
|
|
29555
29473
|
style
|
|
29556
29474
|
} = props;
|
|
29557
29475
|
return /*#__PURE__*/React.createElement("label", {
|
|
29558
|
-
className: css(styles$
|
|
29476
|
+
className: css(styles$y.label)
|
|
29559
29477
|
}, /*#__PURE__*/React.createElement(View, {
|
|
29560
|
-
style: [styles$
|
|
29478
|
+
style: [styles$y.row, style]
|
|
29561
29479
|
}, labelSide === "start" || /*#__PURE__*/React.createElement(LabelSmall, {
|
|
29562
|
-
style: styles$
|
|
29480
|
+
style: styles$y.spaceEnd
|
|
29563
29481
|
}, label), children, labelSide === "end" && /*#__PURE__*/React.createElement(LabelSmall, {
|
|
29564
|
-
style: styles$
|
|
29482
|
+
style: styles$y.spaceStart
|
|
29565
29483
|
}, label)));
|
|
29566
29484
|
};
|
|
29567
|
-
const styles$
|
|
29485
|
+
const styles$y = StyleSheet.create({
|
|
29568
29486
|
label: {
|
|
29569
29487
|
width: "fit-content"
|
|
29570
29488
|
},
|
|
@@ -29582,1764 +29500,2143 @@ const styles$t = StyleSheet.create({
|
|
|
29582
29500
|
}
|
|
29583
29501
|
});
|
|
29584
29502
|
|
|
29585
|
-
const
|
|
29586
|
-
|
|
29587
|
-
|
|
29588
|
-
|
|
29589
|
-
|
|
29590
|
-
|
|
29591
|
-
|
|
29592
|
-
|
|
29593
|
-
|
|
29594
|
-
|
|
29503
|
+
const mediaDefaultSpecLargeMarginWidth = spacing.large_24;
|
|
29504
|
+
const MEDIA_DEFAULT_SPEC = {
|
|
29505
|
+
small: {
|
|
29506
|
+
query: "(max-width: 767px)",
|
|
29507
|
+
totalColumns: 4,
|
|
29508
|
+
gutterWidth: spacing.medium_16,
|
|
29509
|
+
marginWidth: spacing.medium_16
|
|
29510
|
+
},
|
|
29511
|
+
medium: {
|
|
29512
|
+
query: "(min-width: 768px) and (max-width: 1023px)",
|
|
29513
|
+
totalColumns: 8,
|
|
29514
|
+
gutterWidth: spacing.xLarge_32,
|
|
29515
|
+
marginWidth: spacing.large_24
|
|
29516
|
+
},
|
|
29517
|
+
large: {
|
|
29518
|
+
query: "(min-width: 1024px)",
|
|
29519
|
+
totalColumns: 12,
|
|
29520
|
+
gutterWidth: spacing.xLarge_32,
|
|
29521
|
+
marginWidth: mediaDefaultSpecLargeMarginWidth,
|
|
29522
|
+
maxWidth: 1120 + mediaDefaultSpecLargeMarginWidth * 2
|
|
29523
|
+
}
|
|
29595
29524
|
};
|
|
29596
|
-
|
|
29597
|
-
|
|
29598
|
-
|
|
29599
|
-
|
|
29600
|
-
|
|
29601
|
-
|
|
29602
|
-
|
|
29603
|
-
})
|
|
29604
|
-
|
|
29605
|
-
|
|
29606
|
-
|
|
29607
|
-
|
|
29608
|
-
|
|
29609
|
-
|
|
29610
|
-
|
|
29611
|
-
|
|
29612
|
-
|
|
29613
|
-
|
|
29614
|
-
|
|
29615
|
-
|
|
29616
|
-
|
|
29617
|
-
|
|
29618
|
-
|
|
29619
|
-
|
|
29620
|
-
|
|
29621
|
-
|
|
29525
|
+
({
|
|
29526
|
+
large: {
|
|
29527
|
+
query: "(min-width: 1px)",
|
|
29528
|
+
totalColumns: 12,
|
|
29529
|
+
gutterWidth: spacing.xLarge_32,
|
|
29530
|
+
marginWidth: spacing.medium_16
|
|
29531
|
+
}
|
|
29532
|
+
});
|
|
29533
|
+
({
|
|
29534
|
+
small: {
|
|
29535
|
+
query: "(max-width: 767px)",
|
|
29536
|
+
totalColumns: 4,
|
|
29537
|
+
gutterWidth: spacing.medium_16,
|
|
29538
|
+
marginWidth: spacing.medium_16
|
|
29539
|
+
},
|
|
29540
|
+
large: {
|
|
29541
|
+
query: "(min-width: 768px)",
|
|
29542
|
+
totalColumns: 12,
|
|
29543
|
+
gutterWidth: spacing.xLarge_32,
|
|
29544
|
+
marginWidth: spacing.xxLarge_48
|
|
29545
|
+
}
|
|
29546
|
+
});
|
|
29547
|
+
|
|
29548
|
+
const defaultContext = {
|
|
29549
|
+
ssrSize: "large",
|
|
29550
|
+
mediaSpec: MEDIA_DEFAULT_SPEC
|
|
29551
|
+
};
|
|
29552
|
+
const MediaLayoutContext = React.createContext(defaultContext);
|
|
29553
|
+
MediaLayoutContext.displayName = "MediaLayoutContext";
|
|
29554
|
+
|
|
29555
|
+
class Spring extends React.Component {
|
|
29556
|
+
render() {
|
|
29557
|
+
const {
|
|
29558
|
+
style
|
|
29559
|
+
} = this.props;
|
|
29560
|
+
return React.createElement(View, {
|
|
29561
|
+
"aria-hidden": "true",
|
|
29562
|
+
style: [styles$x.grow, style]
|
|
29563
|
+
});
|
|
29564
|
+
}
|
|
29622
29565
|
}
|
|
29623
|
-
|
|
29624
|
-
|
|
29625
|
-
|
|
29626
|
-
labelsTextbox: props.labels,
|
|
29627
|
-
gridStepTextbox: props.gridStep,
|
|
29628
|
-
snapStepTextbox: props.snapStep,
|
|
29629
|
-
stepTextbox: props.step,
|
|
29630
|
-
rangeTextbox: props.range,
|
|
29631
|
-
// Shallow-copied clone
|
|
29632
|
-
backgroundImage: _extends({}, props.backgroundImage)
|
|
29633
|
-
};
|
|
29566
|
+
const styles$x = StyleSheet.create({
|
|
29567
|
+
grow: {
|
|
29568
|
+
flexGrow: 1
|
|
29634
29569
|
}
|
|
29635
|
-
|
|
29636
|
-
super(props);
|
|
29637
|
-
this._isMounted = false;
|
|
29638
|
-
this.bgUrlRef = /*#__PURE__*/React.createRef();
|
|
29639
|
-
this.labelXRef = /*#__PURE__*/React.createRef();
|
|
29640
|
-
this.labelYRef = /*#__PURE__*/React.createRef();
|
|
29641
|
-
this.change = (...args) => {
|
|
29642
|
-
return Changeable.change.apply(this, args);
|
|
29643
|
-
};
|
|
29644
|
-
// TODO(aria): Make either a wrapper for standard events to work
|
|
29645
|
-
// with this.change, or make these use some TextInput/NumberInput box
|
|
29646
|
-
this.changeRulerLabel = e => {
|
|
29647
|
-
this.change({
|
|
29648
|
-
rulerLabel: e.target.value
|
|
29649
|
-
});
|
|
29650
|
-
};
|
|
29651
|
-
this.changeRulerTicks = e => {
|
|
29652
|
-
this.change({
|
|
29653
|
-
rulerTicks: +e.target.value
|
|
29654
|
-
});
|
|
29655
|
-
};
|
|
29656
|
-
this.changeBackgroundUrl = e => {
|
|
29657
|
-
var _this$bgUrlRef$curren;
|
|
29658
|
-
// Only continue on blur or "enter"
|
|
29659
|
-
if (e.type === "keypress" && e.key !== "Enter") {
|
|
29660
|
-
return;
|
|
29661
|
-
}
|
|
29662
|
-
const setUrl = (url, width, height) => {
|
|
29663
|
-
// Shallow-copied clone
|
|
29664
|
-
const image = _extends({}, this.props.backgroundImage);
|
|
29665
|
-
image.url = url;
|
|
29666
|
-
image.width = width;
|
|
29667
|
-
image.height = height;
|
|
29668
|
-
this.setState({
|
|
29669
|
-
backgroundImage: image
|
|
29670
|
-
}, this.changeGraph);
|
|
29671
|
-
};
|
|
29672
|
-
const url = (_this$bgUrlRef$curren = this.bgUrlRef.current) == null ? void 0 : _this$bgUrlRef$curren.value;
|
|
29673
|
-
if (url) {
|
|
29674
|
-
Util.getImageSize(url, (width, height) => {
|
|
29675
|
-
if (this._isMounted) {
|
|
29676
|
-
setUrl(url, width, height);
|
|
29677
|
-
}
|
|
29678
|
-
});
|
|
29679
|
-
} else {
|
|
29680
|
-
setUrl(null, 0, 0);
|
|
29681
|
-
}
|
|
29682
|
-
};
|
|
29683
|
-
this.renderLabelChoices = choices => {
|
|
29684
|
-
return choices.map(nameAndValue => /*#__PURE__*/React.createElement("option", {
|
|
29685
|
-
key: nameAndValue[1],
|
|
29686
|
-
value: nameAndValue[1]
|
|
29687
|
-
}, nameAndValue[0]));
|
|
29688
|
-
};
|
|
29689
|
-
this.validRange = range => {
|
|
29690
|
-
const numbers = _.every(range, function (num) {
|
|
29691
|
-
return _.isFinite(num);
|
|
29692
|
-
});
|
|
29693
|
-
if (!numbers) {
|
|
29694
|
-
return "Range must be a valid number";
|
|
29695
|
-
}
|
|
29696
|
-
if (range[0] >= range[1]) {
|
|
29697
|
-
return "Range must have a higher number on the right";
|
|
29698
|
-
}
|
|
29699
|
-
return true;
|
|
29700
|
-
};
|
|
29701
|
-
this.validateStepValue = settings => {
|
|
29702
|
-
const {
|
|
29703
|
-
step,
|
|
29704
|
-
range,
|
|
29705
|
-
name,
|
|
29706
|
-
minTicks,
|
|
29707
|
-
maxTicks
|
|
29708
|
-
} = settings;
|
|
29709
|
-
const nSteps = numSteps(range, step);
|
|
29710
|
-
if (nSteps < minTicks) {
|
|
29711
|
-
return name + " is too large, there must be at least " + minTicks + " ticks.";
|
|
29712
|
-
}
|
|
29713
|
-
if (nSteps > maxTicks) {
|
|
29714
|
-
return name + " is too small, there can be at most " + maxTicks + " ticks.";
|
|
29715
|
-
}
|
|
29716
|
-
return true;
|
|
29717
|
-
};
|
|
29718
|
-
this.validSnapStep = (step, range) => {
|
|
29719
|
-
return this.validateStepValue({
|
|
29720
|
-
step: step,
|
|
29721
|
-
range: range,
|
|
29722
|
-
name: "Snap step",
|
|
29723
|
-
minTicks: 5,
|
|
29724
|
-
maxTicks: 60
|
|
29725
|
-
});
|
|
29726
|
-
};
|
|
29727
|
-
this.validGridStep = (step, range) => {
|
|
29728
|
-
return this.validateStepValue({
|
|
29729
|
-
step: step,
|
|
29730
|
-
range: range,
|
|
29731
|
-
name: "Grid step",
|
|
29732
|
-
minTicks: 3,
|
|
29733
|
-
maxTicks: 60
|
|
29734
|
-
});
|
|
29735
|
-
};
|
|
29736
|
-
this.validStep = (step, range) => {
|
|
29737
|
-
return this.validateStepValue({
|
|
29738
|
-
step: step,
|
|
29739
|
-
range: range,
|
|
29740
|
-
name: "Step",
|
|
29741
|
-
minTicks: 3,
|
|
29742
|
-
maxTicks: 20
|
|
29743
|
-
});
|
|
29744
|
-
};
|
|
29745
|
-
this.validBackgroundImageSize = image => {
|
|
29746
|
-
// Ignore empty images
|
|
29747
|
-
if (!image.url) {
|
|
29748
|
-
return true;
|
|
29749
|
-
}
|
|
29750
|
-
const validSize = image.width <= 450 && image.height <= 450;
|
|
29751
|
-
if (!validSize) {
|
|
29752
|
-
return "Image must be smaller than 450px x 450px.";
|
|
29753
|
-
}
|
|
29754
|
-
return true;
|
|
29755
|
-
};
|
|
29756
|
-
this.validateGraphSettings = (range, step, gridStep, snapStep, image) => {
|
|
29757
|
-
const self = this;
|
|
29758
|
-
let msg;
|
|
29759
|
-
const goodRange = _.every(range, function (range) {
|
|
29760
|
-
msg = self.validRange(range);
|
|
29761
|
-
return msg === true;
|
|
29762
|
-
});
|
|
29763
|
-
if (!goodRange) {
|
|
29764
|
-
return msg;
|
|
29765
|
-
}
|
|
29766
|
-
const goodStep = _.every(step, function (step, i) {
|
|
29767
|
-
msg = self.validStep(step, range[i]);
|
|
29768
|
-
return msg === true;
|
|
29769
|
-
});
|
|
29770
|
-
if (!goodStep) {
|
|
29771
|
-
return msg;
|
|
29772
|
-
}
|
|
29773
|
-
const goodGridStep = _.every(gridStep, function (gridStep, i) {
|
|
29774
|
-
msg = self.validGridStep(gridStep, range[i]);
|
|
29775
|
-
return msg === true;
|
|
29776
|
-
});
|
|
29777
|
-
if (!goodGridStep) {
|
|
29778
|
-
return msg;
|
|
29779
|
-
}
|
|
29780
|
-
const goodSnapStep = _.every(snapStep, function (snapStep, i) {
|
|
29781
|
-
msg = self.validSnapStep(snapStep, range[i]);
|
|
29782
|
-
return msg === true;
|
|
29783
|
-
});
|
|
29784
|
-
if (!goodSnapStep) {
|
|
29785
|
-
return msg;
|
|
29786
|
-
}
|
|
29787
|
-
const goodImageSize = this.validBackgroundImageSize(image);
|
|
29788
|
-
if (goodImageSize !== true) {
|
|
29789
|
-
msg = goodImageSize;
|
|
29790
|
-
return msg;
|
|
29791
|
-
}
|
|
29792
|
-
return true;
|
|
29793
|
-
};
|
|
29794
|
-
this.changeLabel = (i, e) => {
|
|
29795
|
-
const val = e.target.value;
|
|
29796
|
-
const labels = this.state.labelsTextbox.slice();
|
|
29797
|
-
labels[i] = val;
|
|
29798
|
-
this.setState({
|
|
29799
|
-
labelsTextbox: labels
|
|
29800
|
-
}, this.changeGraph);
|
|
29801
|
-
};
|
|
29802
|
-
this.changeRange = (i, values) => {
|
|
29803
|
-
const ranges = this.state.rangeTextbox.slice();
|
|
29804
|
-
ranges[i] = values;
|
|
29805
|
-
const step = this.state.stepTextbox.slice();
|
|
29806
|
-
const gridStep = this.state.gridStepTextbox.slice();
|
|
29807
|
-
const snapStep = this.state.snapStepTextbox.slice();
|
|
29808
|
-
const scale = Util.scaleFromExtent(ranges[i], this.props.box[i]);
|
|
29809
|
-
if (this.validRange(ranges[i]) === true) {
|
|
29810
|
-
step[i] = Util.tickStepFromExtent(ranges[i], this.props.box[i]);
|
|
29811
|
-
const gridStepValue = Util.gridStepFromTickStep(step[i], scale);
|
|
29812
|
-
if (gridStepValue) {
|
|
29813
|
-
gridStep[i] = gridStepValue;
|
|
29814
|
-
}
|
|
29815
|
-
snapStep[i] = gridStep[i] / 2;
|
|
29816
|
-
}
|
|
29817
|
-
this.setState({
|
|
29818
|
-
stepTextbox: step,
|
|
29819
|
-
gridStepTextbox: gridStep,
|
|
29820
|
-
snapStepTextbox: snapStep,
|
|
29821
|
-
rangeTextbox: ranges
|
|
29822
|
-
}, this.changeGraph);
|
|
29823
|
-
};
|
|
29824
|
-
this.changeStep = step => {
|
|
29825
|
-
this.setState({
|
|
29826
|
-
stepTextbox: step
|
|
29827
|
-
}, this.changeGraph);
|
|
29828
|
-
};
|
|
29829
|
-
this.changeSnapStep = snapStep => {
|
|
29830
|
-
this.setState({
|
|
29831
|
-
snapStepTextbox: snapStep
|
|
29832
|
-
}, this.changeGraph);
|
|
29833
|
-
};
|
|
29834
|
-
this.changeGridStep = gridStep => {
|
|
29835
|
-
this.setState({
|
|
29836
|
-
gridStepTextbox: gridStep,
|
|
29837
|
-
snapStepTextbox: _.map(gridStep, function (step) {
|
|
29838
|
-
return step / 2;
|
|
29839
|
-
})
|
|
29840
|
-
}, this.changeGraph);
|
|
29841
|
-
};
|
|
29842
|
-
this.changeGraph = () => {
|
|
29843
|
-
const labels = this.state.labelsTextbox;
|
|
29844
|
-
const range = _.map(this.state.rangeTextbox, function (range) {
|
|
29845
|
-
return _.map(range, Number);
|
|
29846
|
-
});
|
|
29847
|
-
const step = _.map(this.state.stepTextbox, Number);
|
|
29848
|
-
const gridStep = this.state.gridStepTextbox;
|
|
29849
|
-
const snapStep = this.state.snapStepTextbox;
|
|
29850
|
-
const image = this.state.backgroundImage;
|
|
29570
|
+
});
|
|
29851
29571
|
|
|
29852
|
-
|
|
29853
|
-
|
|
29854
|
-
|
|
29855
|
-
|
|
29856
|
-
|
|
29857
|
-
|
|
29858
|
-
|
|
29859
|
-
|
|
29860
|
-
|
|
29861
|
-
|
|
29862
|
-
labels: labels,
|
|
29863
|
-
range: range,
|
|
29864
|
-
step: step,
|
|
29865
|
-
gridStep: gridStep,
|
|
29866
|
-
snapStep: snapStep,
|
|
29867
|
-
backgroundImage: image
|
|
29868
|
-
});
|
|
29869
|
-
} else {
|
|
29870
|
-
this.change({
|
|
29871
|
-
valid: validationResult // a string message, not false
|
|
29872
|
-
});
|
|
29873
|
-
}
|
|
29874
|
-
};
|
|
29875
|
-
this.state = _extends({
|
|
29876
|
-
isExpanded: true
|
|
29877
|
-
}, InteractiveGraphSettings.stateFromProps(props));
|
|
29572
|
+
class Strut extends React.Component {
|
|
29573
|
+
render() {
|
|
29574
|
+
const {
|
|
29575
|
+
size,
|
|
29576
|
+
style
|
|
29577
|
+
} = this.props;
|
|
29578
|
+
return React.createElement(View, {
|
|
29579
|
+
"aria-hidden": "true",
|
|
29580
|
+
style: [strutStyle(size), style]
|
|
29581
|
+
});
|
|
29878
29582
|
}
|
|
29879
|
-
|
|
29880
|
-
|
|
29881
|
-
|
|
29882
|
-
|
|
29883
|
-
|
|
29583
|
+
}
|
|
29584
|
+
const strutStyle = size => {
|
|
29585
|
+
return {
|
|
29586
|
+
width: size,
|
|
29587
|
+
MsFlexBasis: size,
|
|
29588
|
+
MsFlexPreferredSize: size,
|
|
29589
|
+
WebkitFlexBasis: size,
|
|
29590
|
+
flexBasis: size,
|
|
29591
|
+
flexShrink: 0
|
|
29592
|
+
};
|
|
29593
|
+
};
|
|
29594
|
+
|
|
29595
|
+
function focusWithChromeStickyFocusBugWorkaround(element) {
|
|
29596
|
+
// NOTE(marksandstrom) Chrome sticky focus bug.
|
|
29597
|
+
//
|
|
29598
|
+
// There is a bug in Chrome related to sticky positioning and
|
|
29599
|
+
// focus: When a child of an element with sticky positioning is
|
|
29600
|
+
// focused with the focus() method, the scrollable area
|
|
29601
|
+
// containing that element will scroll to the top (even though
|
|
29602
|
+
// the element is already visble on the page). For a dropdown
|
|
29603
|
+
// this means that the area will be scrolled to the top when
|
|
29604
|
+
// the user interacts with the dropdown (since we actively
|
|
29605
|
+
// manage dropdown header and option focus for keyboard users).
|
|
29606
|
+
//
|
|
29607
|
+
// To work around this bug the `preventScroll` focus option is
|
|
29608
|
+
// used.
|
|
29609
|
+
//
|
|
29610
|
+
// Using `focusOptions` is an experimental browser feature
|
|
29611
|
+
// "that should not be used in production code". However, since
|
|
29612
|
+
// Chrome is the only browser we support that exhibits this
|
|
29613
|
+
// buggy behavior and using `focusOptions` works around the
|
|
29614
|
+
// bug, it is perfectly reasonable to use the feature in this
|
|
29615
|
+
// case. We are not relying on the effect of the
|
|
29616
|
+
// `preventScroll` option otherwise.
|
|
29617
|
+
//
|
|
29618
|
+
// focusOptions documentation:
|
|
29619
|
+
//
|
|
29620
|
+
// https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/focus
|
|
29621
|
+
//
|
|
29622
|
+
// Note that there could be cases where we want default focus() behavior.
|
|
29623
|
+
// One that comes to mind is a dropdown with a long list of options that
|
|
29624
|
+
// might be rendered off screen when opened. With this workaround the
|
|
29625
|
+
// selected option would not be scrolled into view if the option is near
|
|
29626
|
+
// the end of the list. We're not aware of any uses of the dropdown where
|
|
29627
|
+
// this is an issue, however, so there isn't currently a way to out of the
|
|
29628
|
+
// `preventScroll` behavior.
|
|
29629
|
+
|
|
29630
|
+
// @ts-expect-error - TS2339 - Property 'focus' does not exist on type 'Element'.
|
|
29631
|
+
element.focus({
|
|
29632
|
+
preventScroll: true
|
|
29633
|
+
});
|
|
29634
|
+
}
|
|
29635
|
+
const DEFAULT_COLOR = "grayH";
|
|
29636
|
+
function getDefaultFigureForType(type) {
|
|
29637
|
+
switch (type) {
|
|
29638
|
+
case "point":
|
|
29639
|
+
return {
|
|
29640
|
+
type: "point",
|
|
29641
|
+
coord: [0, 0],
|
|
29642
|
+
color: DEFAULT_COLOR,
|
|
29643
|
+
filled: true
|
|
29644
|
+
};
|
|
29645
|
+
case "line":
|
|
29646
|
+
return {
|
|
29647
|
+
type: "line",
|
|
29648
|
+
kind: "line",
|
|
29649
|
+
points: [getDefaultFigureForType("point"), _extends({}, getDefaultFigureForType("point"), {
|
|
29650
|
+
coord: [2, 2]
|
|
29651
|
+
})],
|
|
29652
|
+
color: DEFAULT_COLOR,
|
|
29653
|
+
lineStyle: "solid",
|
|
29654
|
+
showPoint1: false,
|
|
29655
|
+
showPoint2: false
|
|
29656
|
+
};
|
|
29657
|
+
case "vector":
|
|
29658
|
+
return {
|
|
29659
|
+
type: "vector",
|
|
29660
|
+
points: [[0, 0], [2, 2]],
|
|
29661
|
+
color: DEFAULT_COLOR
|
|
29662
|
+
};
|
|
29663
|
+
case "ellipse":
|
|
29664
|
+
return {
|
|
29665
|
+
type: "ellipse",
|
|
29666
|
+
center: [0, 0],
|
|
29667
|
+
radius: [1, 1],
|
|
29668
|
+
angle: 0,
|
|
29669
|
+
color: DEFAULT_COLOR,
|
|
29670
|
+
fillStyle: "none",
|
|
29671
|
+
strokeStyle: "solid"
|
|
29672
|
+
};
|
|
29673
|
+
case "polygon":
|
|
29674
|
+
return {
|
|
29675
|
+
type: "polygon",
|
|
29676
|
+
points: [[0, 2], [-1, 0], [1, 0]],
|
|
29677
|
+
color: DEFAULT_COLOR,
|
|
29678
|
+
showVertices: false,
|
|
29679
|
+
fillStyle: "none",
|
|
29680
|
+
strokeStyle: "solid"
|
|
29681
|
+
};
|
|
29682
|
+
default:
|
|
29683
|
+
throw new UnreachableCaseError(type);
|
|
29684
|
+
}
|
|
29685
|
+
}
|
|
29686
|
+
function degreeToRadian(degrees) {
|
|
29687
|
+
return degrees / 180 * Math.PI;
|
|
29688
|
+
}
|
|
29689
|
+
function radianToDegree(radians) {
|
|
29690
|
+
return radians / Math.PI * 180;
|
|
29691
|
+
}
|
|
29692
|
+
|
|
29693
|
+
/**
|
|
29694
|
+
* Dropdown for selecting a locked figure to add to an interactive graph.
|
|
29695
|
+
* Locked figures are elements (points, segmeents, etc.) that are not
|
|
29696
|
+
* interactive, just present in the graph's background.
|
|
29697
|
+
*
|
|
29698
|
+
* Used in the interactive graph editor's locked figures section.
|
|
29699
|
+
*/
|
|
29700
|
+
const LockedFigureSelect = props => {
|
|
29701
|
+
const {
|
|
29702
|
+
id,
|
|
29703
|
+
onChange
|
|
29704
|
+
} = props;
|
|
29705
|
+
const figureTypes = props.showM2Features ? ["point", "line", "vector", "ellipse", "polygon"] : ["point", "line"];
|
|
29706
|
+
return /*#__PURE__*/React.createElement(View, {
|
|
29707
|
+
style: styles$w.container
|
|
29708
|
+
}, /*#__PURE__*/React.createElement(ActionMenu, {
|
|
29709
|
+
menuText: "Add locked figure",
|
|
29710
|
+
style: styles$w.addElementSelect
|
|
29711
|
+
}, figureTypes.map(figureType => /*#__PURE__*/React.createElement(ActionItem, {
|
|
29712
|
+
key: `${id}-${figureType}`,
|
|
29713
|
+
label: figureType,
|
|
29714
|
+
onClick: () => onChange(figureType)
|
|
29715
|
+
}, figureType))));
|
|
29716
|
+
};
|
|
29717
|
+
const styles$w = StyleSheet.create({
|
|
29718
|
+
container: {
|
|
29719
|
+
marginTop: spacing.xSmall_8
|
|
29720
|
+
},
|
|
29721
|
+
addElementSelect: {
|
|
29722
|
+
backgroundColor: color.fadedBlue8,
|
|
29723
|
+
borderRadius: spacing.xxxSmall_4
|
|
29884
29724
|
}
|
|
29885
|
-
|
|
29886
|
-
|
|
29887
|
-
|
|
29888
|
-
|
|
29889
|
-
|
|
29725
|
+
});
|
|
29726
|
+
|
|
29727
|
+
const AngleInput = props => {
|
|
29728
|
+
const {
|
|
29729
|
+
angle,
|
|
29730
|
+
onChange
|
|
29731
|
+
} = props;
|
|
29732
|
+
const [angleInput, setAngleInput] = React.useState(radianToDegree(angle).toString());
|
|
29733
|
+
function handleAngleChange(newValue) {
|
|
29734
|
+
// Update the local state (update the input field value).
|
|
29735
|
+
setAngleInput(newValue);
|
|
29736
|
+
|
|
29737
|
+
// If the new value is not a number, don't update the props.
|
|
29738
|
+
// If it's empty, keep the props the same value instead of setting to 0.
|
|
29739
|
+
if (isNaN(+newValue) || newValue === "") {
|
|
29740
|
+
return;
|
|
29890
29741
|
}
|
|
29742
|
+
|
|
29743
|
+
// Update the graph.
|
|
29744
|
+
onChange(degreeToRadian(newValue));
|
|
29891
29745
|
}
|
|
29892
|
-
|
|
29893
|
-
|
|
29746
|
+
return /*#__PURE__*/React.createElement(LabelMedium, {
|
|
29747
|
+
tag: "label",
|
|
29748
|
+
style: styles$v.row
|
|
29749
|
+
}, "angle (degrees)", /*#__PURE__*/React.createElement(Strut, {
|
|
29750
|
+
size: spacing.xxSmall_6
|
|
29751
|
+
}), /*#__PURE__*/React.createElement(TextField, {
|
|
29752
|
+
type: "number",
|
|
29753
|
+
value: angleInput,
|
|
29754
|
+
onChange: handleAngleChange,
|
|
29755
|
+
style: styles$v.textField
|
|
29756
|
+
}), /*#__PURE__*/React.createElement(Strut, {
|
|
29757
|
+
size: spacing.xxSmall_6
|
|
29758
|
+
}));
|
|
29759
|
+
};
|
|
29760
|
+
const styles$v = StyleSheet.create({
|
|
29761
|
+
row: {
|
|
29762
|
+
display: "flex",
|
|
29763
|
+
flexDirection: "row",
|
|
29764
|
+
alignItems: "center"
|
|
29765
|
+
},
|
|
29766
|
+
textField: {
|
|
29767
|
+
width: spacing.xxxLarge_64
|
|
29894
29768
|
}
|
|
29895
|
-
|
|
29896
|
-
|
|
29897
|
-
|
|
29898
|
-
|
|
29899
|
-
|
|
29900
|
-
|
|
29901
|
-
|
|
29902
|
-
|
|
29903
|
-
|
|
29904
|
-
|
|
29905
|
-
|
|
29906
|
-
},
|
|
29907
|
-
|
|
29908
|
-
|
|
29909
|
-
|
|
29910
|
-
}
|
|
29911
|
-
|
|
29912
|
-
|
|
29913
|
-
|
|
29914
|
-
|
|
29915
|
-
|
|
29916
|
-
|
|
29917
|
-
|
|
29918
|
-
|
|
29919
|
-
|
|
29920
|
-
|
|
29921
|
-
type: "text",
|
|
29922
|
-
className: "graph-settings-axis-label",
|
|
29923
|
-
ref: this.labelYRef,
|
|
29924
|
-
onChange: e => this.changeLabel(1, e),
|
|
29925
|
-
value: this.state.labelsTextbox[1] || ""
|
|
29926
|
-
})))), /*#__PURE__*/React.createElement("div", {
|
|
29927
|
-
className: "perseus-widget-row"
|
|
29928
|
-
}, /*#__PURE__*/React.createElement("div", {
|
|
29929
|
-
className: "perseus-widget-left-col"
|
|
29930
|
-
}, /*#__PURE__*/React.createElement(LabeledRow, {
|
|
29931
|
-
label: "x Range"
|
|
29932
|
-
}, /*#__PURE__*/React.createElement(RangeInput$4, {
|
|
29933
|
-
value: this.state.rangeTextbox[0],
|
|
29934
|
-
onChange: vals => this.changeRange(0, vals)
|
|
29935
|
-
}))), /*#__PURE__*/React.createElement("div", {
|
|
29936
|
-
className: "perseus-widget-right-col"
|
|
29937
|
-
}, /*#__PURE__*/React.createElement(LabeledRow, {
|
|
29938
|
-
label: "y Range"
|
|
29939
|
-
}, /*#__PURE__*/React.createElement(RangeInput$4, {
|
|
29940
|
-
value: this.state.rangeTextbox[1],
|
|
29941
|
-
onChange: vals => this.changeRange(1, vals)
|
|
29942
|
-
})))), /*#__PURE__*/React.createElement("div", {
|
|
29943
|
-
className: "perseus-widget-row"
|
|
29944
|
-
}, /*#__PURE__*/React.createElement("div", {
|
|
29945
|
-
className: "perseus-widget-left-col"
|
|
29946
|
-
}, /*#__PURE__*/React.createElement(LabeledRow, {
|
|
29947
|
-
label: "Tick Step"
|
|
29948
|
-
}, /*#__PURE__*/React.createElement(RangeInput$4, {
|
|
29949
|
-
value: this.state.stepTextbox,
|
|
29950
|
-
onChange: this.changeStep
|
|
29951
|
-
}))), /*#__PURE__*/React.createElement("div", {
|
|
29952
|
-
className: "perseus-widget-right-col"
|
|
29953
|
-
}, /*#__PURE__*/React.createElement(LabeledRow, {
|
|
29954
|
-
label: "Grid Step"
|
|
29955
|
-
}, /*#__PURE__*/React.createElement(RangeInput$4, {
|
|
29956
|
-
value: this.state.gridStepTextbox,
|
|
29957
|
-
onChange: this.changeGridStep
|
|
29958
|
-
})))), /*#__PURE__*/React.createElement("div", {
|
|
29959
|
-
className: "perseus-widget-row"
|
|
29960
|
-
}, /*#__PURE__*/React.createElement("div", {
|
|
29961
|
-
className: "perseus-widget-left-col"
|
|
29962
|
-
}, /*#__PURE__*/React.createElement(LabeledRow, {
|
|
29963
|
-
label: "Snap Step"
|
|
29964
|
-
}, /*#__PURE__*/React.createElement(RangeInput$4, {
|
|
29965
|
-
value: this.state.snapStepTextbox,
|
|
29966
|
-
onChange: this.changeSnapStep
|
|
29967
|
-
})))), /*#__PURE__*/React.createElement("div", {
|
|
29968
|
-
className: "perseus-widget-row"
|
|
29969
|
-
}, /*#__PURE__*/React.createElement(LabeledRow, {
|
|
29970
|
-
label: "Markings:"
|
|
29971
|
-
}, /*#__PURE__*/React.createElement(ButtonGroup$2, {
|
|
29972
|
-
value: this.props.markings,
|
|
29973
|
-
allowEmpty: false,
|
|
29974
|
-
buttons: [{
|
|
29975
|
-
value: "graph",
|
|
29976
|
-
content: "Graph"
|
|
29977
|
-
}, {
|
|
29978
|
-
value: "grid",
|
|
29979
|
-
content: "Grid"
|
|
29980
|
-
}, {
|
|
29981
|
-
value: "none",
|
|
29982
|
-
content: "None"
|
|
29983
|
-
}],
|
|
29984
|
-
onChange: this.change("markings")
|
|
29985
|
-
}))), /*#__PURE__*/React.createElement("div", {
|
|
29986
|
-
className: "perseus-widget-left-col"
|
|
29987
|
-
}, /*#__PURE__*/React.createElement(PropCheckBox$7, {
|
|
29988
|
-
label: "Show tooltips",
|
|
29989
|
-
showTooltips: this.props.showTooltips,
|
|
29990
|
-
onChange: this.change
|
|
29991
|
-
}))), /*#__PURE__*/React.createElement(LabeledRow, {
|
|
29992
|
-
label: "Background image URL:",
|
|
29993
|
-
style: styles$s.resetSpaceTop
|
|
29994
|
-
}, /*#__PURE__*/React.createElement("input", {
|
|
29995
|
-
type: "text",
|
|
29996
|
-
className: css(styles$s.backgroundUrlInput),
|
|
29997
|
-
ref: this.bgUrlRef,
|
|
29998
|
-
value: this.state.backgroundImage.url || "",
|
|
29999
|
-
onChange: e => {
|
|
30000
|
-
// Shallow-copied clone
|
|
30001
|
-
const image = _extends({}, this.props.backgroundImage);
|
|
30002
|
-
image.url = e.target.value;
|
|
30003
|
-
this.setState({
|
|
30004
|
-
backgroundImage: image
|
|
30005
|
-
});
|
|
30006
|
-
},
|
|
30007
|
-
onKeyPress: this.changeBackgroundUrl,
|
|
30008
|
-
onBlur: this.changeBackgroundUrl
|
|
30009
|
-
}), /*#__PURE__*/React.createElement(InfoTip$d, null, /*#__PURE__*/React.createElement("p", null, "Create an image in graphie, or use the \"Add image\" function to create a background."))), /*#__PURE__*/React.createElement(View, {
|
|
30010
|
-
style: styles$s.rulerSection
|
|
30011
|
-
}, /*#__PURE__*/React.createElement(View, {
|
|
30012
|
-
style: styles$s.checkboxRow
|
|
30013
|
-
}, /*#__PURE__*/React.createElement(PropCheckBox$7, {
|
|
30014
|
-
label: "Show ruler",
|
|
30015
|
-
showRuler: this.props.showRuler,
|
|
30016
|
-
onChange: this.change,
|
|
30017
|
-
style: styles$s.resetSpaceTop
|
|
30018
|
-
}), /*#__PURE__*/React.createElement(PropCheckBox$7, {
|
|
30019
|
-
label: "Show protractor",
|
|
30020
|
-
showProtractor: this.props.showProtractor,
|
|
30021
|
-
onChange: this.change,
|
|
30022
|
-
style: styles$s.resetSpaceTop
|
|
30023
|
-
})), (this.props.showRuler || this.props.showProtractor) && /*#__PURE__*/React.createElement(Banner, {
|
|
30024
|
-
layout: "floating",
|
|
30025
|
-
text: "The ruler and protractor are not accessible. Please consider an alternate approach.",
|
|
30026
|
-
kind: "warning"
|
|
30027
|
-
}), this.props.showRuler && /*#__PURE__*/React.createElement(View, {
|
|
30028
|
-
style: styles$s.spaceTop
|
|
30029
|
-
}, /*#__PURE__*/React.createElement(LabeledRow, {
|
|
30030
|
-
label: "Ruler label:",
|
|
30031
|
-
style: styles$s.resetSpaceTop
|
|
30032
|
-
}, /*#__PURE__*/React.createElement(SingleSelect, {
|
|
30033
|
-
id: "ruler-label-select",
|
|
30034
|
-
selectedValue: this.props.rulerLabel,
|
|
30035
|
-
onChange: newValue => {
|
|
30036
|
-
this.change({
|
|
30037
|
-
rulerLabel: newValue
|
|
30038
|
-
});
|
|
30039
|
-
},
|
|
30040
|
-
placeholder: "None",
|
|
30041
|
-
style: styles$s.singleSelectShort
|
|
30042
|
-
}, /*#__PURE__*/React.createElement(OptionItem, {
|
|
30043
|
-
value: "",
|
|
30044
|
-
label: "None",
|
|
30045
|
-
horizontalRule: "full-width"
|
|
30046
|
-
}), /*#__PURE__*/React.createElement(OptionItem, {
|
|
30047
|
-
value: "mm",
|
|
30048
|
-
label: "Milimeters"
|
|
30049
|
-
}), /*#__PURE__*/React.createElement(OptionItem, {
|
|
30050
|
-
value: "cm",
|
|
30051
|
-
label: "Centimeters"
|
|
30052
|
-
}), /*#__PURE__*/React.createElement(OptionItem, {
|
|
30053
|
-
value: "m",
|
|
30054
|
-
label: "Meters"
|
|
30055
|
-
}), /*#__PURE__*/React.createElement(OptionItem, {
|
|
30056
|
-
value: "km",
|
|
30057
|
-
label: "Kilometers",
|
|
30058
|
-
horizontalRule: "full-width"
|
|
30059
|
-
}), /*#__PURE__*/React.createElement(OptionItem, {
|
|
30060
|
-
value: "in",
|
|
30061
|
-
label: "Inches"
|
|
30062
|
-
}), /*#__PURE__*/React.createElement(OptionItem, {
|
|
30063
|
-
value: "ft",
|
|
30064
|
-
label: "Feet"
|
|
30065
|
-
}), /*#__PURE__*/React.createElement(OptionItem, {
|
|
30066
|
-
value: "yd",
|
|
30067
|
-
label: "Yards"
|
|
30068
|
-
}), /*#__PURE__*/React.createElement(OptionItem, {
|
|
30069
|
-
value: "mi",
|
|
30070
|
-
label: "Miles"
|
|
30071
|
-
}))), /*#__PURE__*/React.createElement(LabeledRow, {
|
|
30072
|
-
label: "Ruler ticks:"
|
|
30073
|
-
}, /*#__PURE__*/React.createElement(SingleSelect, {
|
|
30074
|
-
id: "ruler-ticks-select",
|
|
30075
|
-
selectedValue: `${this.props.rulerTicks}`,
|
|
30076
|
-
onChange: newValue => {
|
|
30077
|
-
this.change({
|
|
30078
|
-
rulerTicks: newValue
|
|
30079
|
-
});
|
|
30080
|
-
},
|
|
30081
|
-
placeholder: "10",
|
|
30082
|
-
style: styles$s.singleSelectShort
|
|
30083
|
-
}, [1, 2, 4, 8, 10, 16].map(value => /*#__PURE__*/React.createElement(OptionItem, {
|
|
30084
|
-
key: value,
|
|
30085
|
-
value: `${value}`,
|
|
30086
|
-
label: `${value}`
|
|
30087
|
-
}))))))));
|
|
29769
|
+
});
|
|
29770
|
+
|
|
29771
|
+
const ColorSwatch = props => {
|
|
29772
|
+
const {
|
|
29773
|
+
color: color$1,
|
|
29774
|
+
filled = true,
|
|
29775
|
+
decorative = false
|
|
29776
|
+
} = props;
|
|
29777
|
+
return /*#__PURE__*/React.createElement(View, {
|
|
29778
|
+
"aria-label":
|
|
29779
|
+
// Don't include an aria label for decorative circles.
|
|
29780
|
+
!decorative ? `${color$1}, ${filled ? "filled" : "open"}` : undefined,
|
|
29781
|
+
style: [styles$u.colorSwatch, {
|
|
29782
|
+
border: `4px solid ${lockedFigureColors[color$1]}`,
|
|
29783
|
+
backgroundColor: filled ? lockedFigureColors[color$1] : color.white
|
|
29784
|
+
}]
|
|
29785
|
+
});
|
|
29786
|
+
};
|
|
29787
|
+
const styles$u = StyleSheet.create({
|
|
29788
|
+
colorSwatch: {
|
|
29789
|
+
// Add a white outline so that the color swatch is visible when
|
|
29790
|
+
// the dropdown option is highlighted with its blue background.
|
|
29791
|
+
outline: `2px solid ${color.offWhite}`,
|
|
29792
|
+
borderRadius: "50%",
|
|
29793
|
+
width: spacing.large_24,
|
|
29794
|
+
height: spacing.large_24
|
|
30088
29795
|
}
|
|
30089
|
-
}
|
|
30090
|
-
|
|
30091
|
-
|
|
30092
|
-
|
|
30093
|
-
|
|
30094
|
-
|
|
30095
|
-
|
|
30096
|
-
|
|
30097
|
-
|
|
30098
|
-
|
|
30099
|
-
|
|
30100
|
-
|
|
30101
|
-
|
|
30102
|
-
|
|
30103
|
-
|
|
30104
|
-
|
|
29796
|
+
});
|
|
29797
|
+
|
|
29798
|
+
const possibleColors = Object.keys(lockedFigureColors);
|
|
29799
|
+
const ColorSelect = props => {
|
|
29800
|
+
const {
|
|
29801
|
+
selectedValue,
|
|
29802
|
+
style,
|
|
29803
|
+
onChange
|
|
29804
|
+
} = props;
|
|
29805
|
+
return /*#__PURE__*/React.createElement(View, {
|
|
29806
|
+
style: [styles$t.row, style]
|
|
29807
|
+
}, /*#__PURE__*/React.createElement(LabelMedium, {
|
|
29808
|
+
tag: "label",
|
|
29809
|
+
style: styles$t.row
|
|
29810
|
+
}, "color", /*#__PURE__*/React.createElement(Strut, {
|
|
29811
|
+
size: spacing.xxSmall_6
|
|
29812
|
+
}), /*#__PURE__*/React.createElement(SingleSelect, {
|
|
29813
|
+
selectedValue: selectedValue,
|
|
29814
|
+
onChange: onChange
|
|
29815
|
+
// Placeholder is required, but never gets used.
|
|
29816
|
+
,
|
|
29817
|
+
placeholder: ""
|
|
29818
|
+
}, possibleColors.map(colorName => /*#__PURE__*/React.createElement(OptionItem, {
|
|
29819
|
+
key: colorName,
|
|
29820
|
+
value: colorName,
|
|
29821
|
+
label: colorName,
|
|
29822
|
+
leftAccessory: /*#__PURE__*/React.createElement(ColorSwatch, {
|
|
29823
|
+
color: colorName,
|
|
29824
|
+
decorative: true
|
|
29825
|
+
})
|
|
29826
|
+
}, colorName)))));
|
|
29827
|
+
};
|
|
29828
|
+
const styles$t = StyleSheet.create({
|
|
29829
|
+
row: {
|
|
29830
|
+
display: "flex",
|
|
29831
|
+
flexDirection: "row",
|
|
29832
|
+
alignItems: "center"
|
|
29833
|
+
}
|
|
29834
|
+
});
|
|
29835
|
+
|
|
29836
|
+
const CoordinatePairInput = props => {
|
|
29837
|
+
const {
|
|
29838
|
+
coord,
|
|
29839
|
+
labels,
|
|
29840
|
+
error,
|
|
29841
|
+
style,
|
|
29842
|
+
onChange
|
|
29843
|
+
} = props;
|
|
29844
|
+
|
|
29845
|
+
// Keep track of the coordinates via state as the user is editing them,
|
|
29846
|
+
// before they are updated in the props as a valid number.
|
|
29847
|
+
const [coordState, setCoordState] = React.useState([
|
|
29848
|
+
// Using strings to make it easier to work with the text fields.
|
|
29849
|
+
coord[0].toString(), coord[1].toString()]);
|
|
29850
|
+
function handleCoordChange(newValue, coordIndex) {
|
|
29851
|
+
// Update the local state (update the input field value).
|
|
29852
|
+
const newCoordState = [...coordState];
|
|
29853
|
+
newCoordState[coordIndex] = newValue;
|
|
29854
|
+
setCoordState(newCoordState);
|
|
29855
|
+
|
|
29856
|
+
// If the new value is not a number, don't update the props.
|
|
29857
|
+
// If it's empty, keep the props the same value instead of setting to 0.
|
|
29858
|
+
if (isNaN(+newValue) || newValue === "") {
|
|
29859
|
+
return;
|
|
29860
|
+
}
|
|
29861
|
+
|
|
29862
|
+
// Update the props (update the graph).
|
|
29863
|
+
const newCoords = [...coord];
|
|
29864
|
+
newCoords[coordIndex] = +newValue;
|
|
29865
|
+
onChange(newCoords);
|
|
29866
|
+
}
|
|
29867
|
+
return /*#__PURE__*/React.createElement(View, {
|
|
29868
|
+
style: [styles$s.row, style]
|
|
29869
|
+
}, /*#__PURE__*/React.createElement(LabelMedium, {
|
|
29870
|
+
tag: "label",
|
|
29871
|
+
style: styles$s.row
|
|
29872
|
+
}, labels ? labels[0] : "x coord", /*#__PURE__*/React.createElement(Strut, {
|
|
29873
|
+
size: spacing.xxSmall_6
|
|
29874
|
+
}), /*#__PURE__*/React.createElement(TextField, {
|
|
29875
|
+
type: "number",
|
|
29876
|
+
value: coordState[0],
|
|
29877
|
+
onChange: newValue => handleCoordChange(newValue, 0),
|
|
29878
|
+
style: [styles$s.textField, error ? styles$s.errorField : undefined]
|
|
29879
|
+
})), /*#__PURE__*/React.createElement(Strut, {
|
|
29880
|
+
size: spacing.medium_16
|
|
29881
|
+
}), /*#__PURE__*/React.createElement(LabelMedium, {
|
|
29882
|
+
tag: "label",
|
|
29883
|
+
style: styles$s.row
|
|
29884
|
+
}, labels ? labels[1] : "y coord", /*#__PURE__*/React.createElement(Strut, {
|
|
29885
|
+
size: spacing.xxSmall_6
|
|
29886
|
+
}), /*#__PURE__*/React.createElement(TextField, {
|
|
29887
|
+
type: "number",
|
|
29888
|
+
value: coordState[1],
|
|
29889
|
+
onChange: newValue => handleCoordChange(newValue, 1),
|
|
29890
|
+
style: [styles$s.textField, error ? styles$s.errorField : undefined]
|
|
29891
|
+
})));
|
|
30105
29892
|
};
|
|
30106
29893
|
const styles$s = StyleSheet.create({
|
|
30107
|
-
|
|
30108
|
-
|
|
30109
|
-
|
|
30110
|
-
|
|
30111
|
-
marginTop: spacing.xSmall_8
|
|
30112
|
-
},
|
|
30113
|
-
singleSelectShort: {
|
|
30114
|
-
// Non-standard spacing, but it's the smallest we can go
|
|
30115
|
-
// without running into styling issues with the dropdown.
|
|
30116
|
-
height: 26
|
|
29894
|
+
row: {
|
|
29895
|
+
display: "flex",
|
|
29896
|
+
flexDirection: "row",
|
|
29897
|
+
alignItems: "center"
|
|
30117
29898
|
},
|
|
30118
|
-
|
|
30119
|
-
|
|
30120
|
-
borderRadius: spacing.xxxSmall_4,
|
|
30121
|
-
padding: spacing.xxxSmall_4
|
|
29899
|
+
textField: {
|
|
29900
|
+
width: spacing.xxxLarge_64
|
|
30122
29901
|
},
|
|
30123
|
-
|
|
30124
|
-
|
|
29902
|
+
errorField: {
|
|
29903
|
+
borderColor: color.red,
|
|
29904
|
+
backgroundColor: color.fadedRed8
|
|
29905
|
+
}
|
|
29906
|
+
});
|
|
29907
|
+
|
|
29908
|
+
const EllipseSwatch = props => {
|
|
29909
|
+
const {
|
|
29910
|
+
color,
|
|
29911
|
+
fillStyle,
|
|
29912
|
+
strokeStyle
|
|
29913
|
+
} = props;
|
|
29914
|
+
return /*#__PURE__*/React.createElement(View, {
|
|
29915
|
+
"aria-label": `${color}, stroke ${strokeStyle}, fill ${fillStyle}`,
|
|
29916
|
+
style: [styles$r.container, {
|
|
29917
|
+
border: `4px ${strokeStyle} ${lockedFigureColors[color]}`
|
|
29918
|
+
}]
|
|
29919
|
+
}, /*#__PURE__*/React.createElement(View, {
|
|
29920
|
+
style: [styles$r.innerCircle, {
|
|
29921
|
+
backgroundColor: lockedFigureColors[color],
|
|
29922
|
+
opacity: lockedFigureFillStyles[fillStyle]
|
|
29923
|
+
}]
|
|
29924
|
+
}));
|
|
29925
|
+
};
|
|
29926
|
+
const styles$r = StyleSheet.create({
|
|
29927
|
+
container: {
|
|
29928
|
+
// Add a white outline so that the color swatch is visible when
|
|
29929
|
+
// the dropdown option is highlighted with its blue background.
|
|
29930
|
+
outline: `2px solid ${color.offWhite}`,
|
|
29931
|
+
borderRadius: "50%",
|
|
29932
|
+
width: spacing.xLarge_32,
|
|
29933
|
+
height: spacing.large_24,
|
|
29934
|
+
backgroundColor: color.white,
|
|
30125
29935
|
alignItems: "center",
|
|
30126
|
-
justifyContent: "
|
|
30127
|
-
marginBottom: spacing.xSmall_8
|
|
29936
|
+
justifyContent: "center"
|
|
30128
29937
|
},
|
|
30129
|
-
|
|
30130
|
-
|
|
30131
|
-
|
|
30132
|
-
|
|
30133
|
-
paddingBottom: spacing.xSmall_8,
|
|
30134
|
-
borderBottom: `1px solid ${color.offBlack16}`
|
|
29938
|
+
innerCircle: {
|
|
29939
|
+
width: 28,
|
|
29940
|
+
height: 20,
|
|
29941
|
+
borderRadius: "50%"
|
|
30135
29942
|
}
|
|
30136
29943
|
});
|
|
30137
29944
|
|
|
30138
|
-
const
|
|
30139
|
-
const
|
|
30140
|
-
|
|
30141
|
-
|
|
30142
|
-
|
|
30143
|
-
|
|
30144
|
-
|
|
29945
|
+
const LockedFigureSettingsAccordion = props => {
|
|
29946
|
+
const {
|
|
29947
|
+
children,
|
|
29948
|
+
header,
|
|
29949
|
+
expanded,
|
|
29950
|
+
containerStyle,
|
|
29951
|
+
panelStyle,
|
|
29952
|
+
onToggle
|
|
29953
|
+
} = props;
|
|
29954
|
+
return /*#__PURE__*/React.createElement(View
|
|
29955
|
+
// More specificity so that we can override the default
|
|
29956
|
+
// .heading > h2 > .header styles from the articles.less
|
|
29957
|
+
// file (which is imported in perseus-renderer.less).
|
|
29958
|
+
, {
|
|
29959
|
+
className: "locked-figure-accordion"
|
|
29960
|
+
}, /*#__PURE__*/React.createElement(AccordionSection, {
|
|
29961
|
+
expanded: expanded,
|
|
29962
|
+
onToggle: onToggle,
|
|
29963
|
+
style: [styles$q.container, containerStyle],
|
|
29964
|
+
headerStyle: styles$q.accordionHeader,
|
|
29965
|
+
header: header
|
|
29966
|
+
}, /*#__PURE__*/React.createElement(View, {
|
|
29967
|
+
style: [styles$q.accordionPanel, panelStyle]
|
|
29968
|
+
}, children)));
|
|
29969
|
+
};
|
|
29970
|
+
const styles$q = StyleSheet.create({
|
|
29971
|
+
container: {
|
|
29972
|
+
backgroundColor: color.fadedBlue8,
|
|
29973
|
+
marginTop: spacing.xSmall_8
|
|
30145
29974
|
},
|
|
30146
|
-
|
|
30147
|
-
|
|
30148
|
-
|
|
30149
|
-
|
|
30150
|
-
|
|
29975
|
+
accordionHeader: {
|
|
29976
|
+
padding: spacing.small_12,
|
|
29977
|
+
// Don't move the dropdown caret.
|
|
29978
|
+
paddingInlineEnd: 0,
|
|
29979
|
+
// Fixed height so the addition of the color swatch doesn't
|
|
29980
|
+
// change the height of the header when toggling.
|
|
29981
|
+
height: spacing.xxLarge_48
|
|
30151
29982
|
},
|
|
30152
|
-
|
|
30153
|
-
|
|
30154
|
-
|
|
30155
|
-
|
|
30156
|
-
|
|
30157
|
-
maxWidth: 1120 + mediaDefaultSpecLargeMarginWidth * 2
|
|
30158
|
-
}
|
|
30159
|
-
};
|
|
30160
|
-
({
|
|
30161
|
-
large: {
|
|
30162
|
-
query: "(min-width: 1px)",
|
|
30163
|
-
totalColumns: 12,
|
|
30164
|
-
gutterWidth: spacing.xLarge_32,
|
|
30165
|
-
marginWidth: spacing.medium_16
|
|
29983
|
+
accordionPanel: {
|
|
29984
|
+
paddingTop: spacing.xxSmall_6,
|
|
29985
|
+
paddingBottom: spacing.xxxSmall_4,
|
|
29986
|
+
paddingLeft: spacing.small_12,
|
|
29987
|
+
paddingRight: spacing.small_12
|
|
30166
29988
|
}
|
|
30167
29989
|
});
|
|
30168
|
-
|
|
30169
|
-
|
|
30170
|
-
|
|
30171
|
-
|
|
30172
|
-
|
|
30173
|
-
|
|
29990
|
+
|
|
29991
|
+
/**
|
|
29992
|
+
* The part of a locked figure settings panel that contains actions
|
|
29993
|
+
* for this panel and its associated locked figure, including
|
|
29994
|
+
* the delete button.
|
|
29995
|
+
*/
|
|
29996
|
+
const LockedFigureSettingsActions = props => {
|
|
29997
|
+
const {
|
|
29998
|
+
figureType,
|
|
29999
|
+
onMove,
|
|
30000
|
+
onRemove
|
|
30001
|
+
} = props;
|
|
30002
|
+
return /*#__PURE__*/React.createElement(View, {
|
|
30003
|
+
style: styles$p.container
|
|
30004
|
+
}, /*#__PURE__*/React.createElement(Button, {
|
|
30005
|
+
startIcon: trashIcon,
|
|
30006
|
+
"aria-label": `Delete locked ${figureType}`,
|
|
30007
|
+
onClick: onRemove,
|
|
30008
|
+
kind: "tertiary",
|
|
30009
|
+
style: styles$p.deleteButton
|
|
30010
|
+
}, "Delete"), /*#__PURE__*/React.createElement(Spring, null), props.showM2Features && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(IconButton, {
|
|
30011
|
+
icon: caretDoubleUpIcon,
|
|
30012
|
+
size: "small",
|
|
30013
|
+
"aria-label": `Move locked ${figureType} to the back`,
|
|
30014
|
+
onClick: () => onMove("back"),
|
|
30015
|
+
style: styles$p.iconButton
|
|
30016
|
+
}), /*#__PURE__*/React.createElement(IconButton, {
|
|
30017
|
+
icon: caretUpIcon,
|
|
30018
|
+
size: "small",
|
|
30019
|
+
"aria-label": `Move locked ${figureType} backward`,
|
|
30020
|
+
onClick: () => onMove("backward"),
|
|
30021
|
+
style: styles$p.iconButton
|
|
30022
|
+
}), /*#__PURE__*/React.createElement(IconButton, {
|
|
30023
|
+
icon: caretDownIcon,
|
|
30024
|
+
size: "small",
|
|
30025
|
+
"aria-label": `Move locked ${figureType} forward`,
|
|
30026
|
+
onClick: () => onMove("forward"),
|
|
30027
|
+
style: styles$p.iconButton
|
|
30028
|
+
}), /*#__PURE__*/React.createElement(IconButton, {
|
|
30029
|
+
icon: caretDoubleDownIcon,
|
|
30030
|
+
size: "small",
|
|
30031
|
+
"aria-label": `Move locked ${figureType} to the front`,
|
|
30032
|
+
onClick: () => onMove("front"),
|
|
30033
|
+
style: styles$p.iconButton
|
|
30034
|
+
})));
|
|
30035
|
+
};
|
|
30036
|
+
const styles$p = StyleSheet.create({
|
|
30037
|
+
container: {
|
|
30038
|
+
width: "100%",
|
|
30039
|
+
flexDirection: "row",
|
|
30040
|
+
alignItems: "center",
|
|
30041
|
+
marginTop: spacing.xxxSmall_4
|
|
30174
30042
|
},
|
|
30175
|
-
|
|
30176
|
-
|
|
30177
|
-
|
|
30178
|
-
|
|
30179
|
-
|
|
30043
|
+
deleteButton: {
|
|
30044
|
+
// Line up the delete icon with the rest of the content.
|
|
30045
|
+
marginInlineStart: -spacing.xxxSmall_4
|
|
30046
|
+
},
|
|
30047
|
+
iconButton: {
|
|
30048
|
+
// Reset the margin because the icon buttons
|
|
30049
|
+
// overlap each other otherwise.
|
|
30050
|
+
margin: 0
|
|
30180
30051
|
}
|
|
30181
30052
|
});
|
|
30182
30053
|
|
|
30183
|
-
const
|
|
30184
|
-
|
|
30185
|
-
|
|
30054
|
+
const {
|
|
30055
|
+
InfoTip: InfoTip$d
|
|
30056
|
+
} = components;
|
|
30057
|
+
const LockedEllipseSettings = props => {
|
|
30058
|
+
const {
|
|
30059
|
+
center,
|
|
30060
|
+
radius,
|
|
30061
|
+
angle,
|
|
30062
|
+
color,
|
|
30063
|
+
fillStyle,
|
|
30064
|
+
strokeStyle,
|
|
30065
|
+
expanded,
|
|
30066
|
+
onToggle,
|
|
30067
|
+
onChangeProps,
|
|
30068
|
+
onMove,
|
|
30069
|
+
onRemove
|
|
30070
|
+
} = props;
|
|
30071
|
+
function handleColorChange(newValue) {
|
|
30072
|
+
onChangeProps({
|
|
30073
|
+
color: newValue
|
|
30074
|
+
});
|
|
30075
|
+
}
|
|
30076
|
+
return /*#__PURE__*/React.createElement(LockedFigureSettingsAccordion, {
|
|
30077
|
+
expanded: expanded,
|
|
30078
|
+
onToggle: onToggle,
|
|
30079
|
+
header:
|
|
30080
|
+
/*#__PURE__*/
|
|
30081
|
+
// Summary: Ellipse, center, radius, color (opacity, dashed)
|
|
30082
|
+
React.createElement(View, {
|
|
30083
|
+
style: styles$o.row
|
|
30084
|
+
}, /*#__PURE__*/React.createElement(LabelLarge, null, `Ellipse (${center[0]}, ${center[1]}), radius ${radius[0]}, ${radius[1]}`), /*#__PURE__*/React.createElement(Strut, {
|
|
30085
|
+
size: spacing.xSmall_8
|
|
30086
|
+
}), /*#__PURE__*/React.createElement(EllipseSwatch, {
|
|
30087
|
+
color: props.color,
|
|
30088
|
+
fillStyle: fillStyle,
|
|
30089
|
+
strokeStyle: strokeStyle
|
|
30090
|
+
}))
|
|
30091
|
+
}, /*#__PURE__*/React.createElement(View, {
|
|
30092
|
+
style: styles$o.row
|
|
30093
|
+
}, /*#__PURE__*/React.createElement(CoordinatePairInput, {
|
|
30094
|
+
coord: center,
|
|
30095
|
+
style: styles$o.spaceUnder,
|
|
30096
|
+
onChange: newCoords => onChangeProps({
|
|
30097
|
+
center: newCoords
|
|
30098
|
+
})
|
|
30099
|
+
}), /*#__PURE__*/React.createElement(View, {
|
|
30100
|
+
style: styles$o.spaceUnder
|
|
30101
|
+
}, /*#__PURE__*/React.createElement(InfoTip$d, null, "The coordinates for the center of the ellipse."))), /*#__PURE__*/React.createElement(CoordinatePairInput, {
|
|
30102
|
+
coord: radius,
|
|
30103
|
+
labels: ["x radius", "y radius"],
|
|
30104
|
+
style: styles$o.spaceUnder,
|
|
30105
|
+
onChange: newCoords => onChangeProps({
|
|
30106
|
+
radius: newCoords
|
|
30107
|
+
})
|
|
30108
|
+
}), /*#__PURE__*/React.createElement(AngleInput, {
|
|
30109
|
+
angle: angle,
|
|
30110
|
+
onChange: newAngle => onChangeProps({
|
|
30111
|
+
angle: newAngle
|
|
30112
|
+
})
|
|
30113
|
+
}), /*#__PURE__*/React.createElement(Strut, {
|
|
30114
|
+
size: spacing.xSmall_8
|
|
30115
|
+
}), /*#__PURE__*/React.createElement(View, {
|
|
30116
|
+
style: [styles$o.row, styles$o.spaceUnder]
|
|
30117
|
+
}, /*#__PURE__*/React.createElement(ColorSelect, {
|
|
30118
|
+
selectedValue: color,
|
|
30119
|
+
onChange: handleColorChange
|
|
30120
|
+
}), /*#__PURE__*/React.createElement(Strut, {
|
|
30121
|
+
size: spacing.medium_16
|
|
30122
|
+
}), /*#__PURE__*/React.createElement(LabelMedium, {
|
|
30123
|
+
tag: "label",
|
|
30124
|
+
style: styles$o.row
|
|
30125
|
+
}, "fill", /*#__PURE__*/React.createElement(Strut, {
|
|
30126
|
+
size: spacing.xxSmall_6
|
|
30127
|
+
}), /*#__PURE__*/React.createElement(SingleSelect, {
|
|
30128
|
+
selectedValue: fillStyle,
|
|
30129
|
+
onChange: value => onChangeProps({
|
|
30130
|
+
fillStyle: value
|
|
30131
|
+
})
|
|
30132
|
+
// Placeholder is required, but never gets used.
|
|
30133
|
+
,
|
|
30134
|
+
placeholder: ""
|
|
30135
|
+
}, Object.keys(lockedFigureFillStyles).map(option => /*#__PURE__*/React.createElement(OptionItem, {
|
|
30136
|
+
key: option,
|
|
30137
|
+
value: option,
|
|
30138
|
+
label: option
|
|
30139
|
+
}, option))))), /*#__PURE__*/React.createElement(LabelMedium, {
|
|
30140
|
+
tag: "label",
|
|
30141
|
+
style: styles$o.row
|
|
30142
|
+
}, "stroke", /*#__PURE__*/React.createElement(Strut, {
|
|
30143
|
+
size: spacing.xxSmall_6
|
|
30144
|
+
}), /*#__PURE__*/React.createElement(SingleSelect, {
|
|
30145
|
+
selectedValue: strokeStyle,
|
|
30146
|
+
onChange: value => onChangeProps({
|
|
30147
|
+
strokeStyle: value
|
|
30148
|
+
})
|
|
30149
|
+
// Placeholder is required, but never gets used.
|
|
30150
|
+
,
|
|
30151
|
+
placeholder: ""
|
|
30152
|
+
}, /*#__PURE__*/React.createElement(OptionItem, {
|
|
30153
|
+
value: "solid",
|
|
30154
|
+
label: "solid"
|
|
30155
|
+
}, "solid"), /*#__PURE__*/React.createElement(OptionItem, {
|
|
30156
|
+
value: "dashed",
|
|
30157
|
+
label: "dashed"
|
|
30158
|
+
}, "dashed"))), /*#__PURE__*/React.createElement(LockedFigureSettingsActions, {
|
|
30159
|
+
showM2Features: props.showM2Features,
|
|
30160
|
+
figureType: props.type,
|
|
30161
|
+
onMove: onMove,
|
|
30162
|
+
onRemove: onRemove
|
|
30163
|
+
}));
|
|
30186
30164
|
};
|
|
30187
|
-
const
|
|
30188
|
-
|
|
30189
|
-
|
|
30190
|
-
|
|
30191
|
-
|
|
30165
|
+
const styles$o = StyleSheet.create({
|
|
30166
|
+
row: {
|
|
30167
|
+
display: "flex",
|
|
30168
|
+
flexDirection: "row",
|
|
30169
|
+
alignItems: "center"
|
|
30170
|
+
},
|
|
30171
|
+
spaceUnder: {
|
|
30172
|
+
marginBottom: spacing.xSmall_8
|
|
30192
30173
|
}
|
|
30193
30174
|
});
|
|
30194
30175
|
|
|
30195
|
-
|
|
30196
|
-
|
|
30197
|
-
|
|
30198
|
-
|
|
30199
|
-
|
|
30200
|
-
|
|
30201
|
-
|
|
30202
|
-
|
|
30203
|
-
|
|
30204
|
-
|
|
30205
|
-
|
|
30206
|
-
}
|
|
30207
|
-
|
|
30208
|
-
|
|
30209
|
-
|
|
30210
|
-
|
|
30211
|
-
|
|
30212
|
-
|
|
30213
|
-
|
|
30214
|
-
|
|
30215
|
-
};
|
|
30176
|
+
const LabeledSwitch = props => {
|
|
30177
|
+
const {
|
|
30178
|
+
checked,
|
|
30179
|
+
label,
|
|
30180
|
+
style,
|
|
30181
|
+
onChange
|
|
30182
|
+
} = props;
|
|
30183
|
+
const ids = useUniqueIdWithMock();
|
|
30184
|
+
const switchId = ids.get("switch");
|
|
30185
|
+
return /*#__PURE__*/React.createElement(View, {
|
|
30186
|
+
style: [styles$n.row, style]
|
|
30187
|
+
}, /*#__PURE__*/React.createElement(Switch, {
|
|
30188
|
+
id: switchId,
|
|
30189
|
+
checked: checked,
|
|
30190
|
+
onChange: onChange
|
|
30191
|
+
}), /*#__PURE__*/React.createElement(Strut, {
|
|
30192
|
+
size: spacing.xSmall_8
|
|
30193
|
+
}), /*#__PURE__*/React.createElement(LabelMedium, {
|
|
30194
|
+
tag: "label",
|
|
30195
|
+
htmlFor: switchId
|
|
30196
|
+
}, label));
|
|
30216
30197
|
};
|
|
30198
|
+
const styles$n = StyleSheet.create({
|
|
30199
|
+
row: {
|
|
30200
|
+
flexDirection: "row",
|
|
30201
|
+
alignItems: "center"
|
|
30202
|
+
}
|
|
30203
|
+
});
|
|
30217
30204
|
|
|
30218
30205
|
/**
|
|
30219
|
-
*
|
|
30220
|
-
*
|
|
30221
|
-
* interactive, just present in the graph's background.
|
|
30206
|
+
* DefiningPointSettings is a component that allows the user to edit the
|
|
30207
|
+
* settings of a point that defines a locked figure (ex. line) on the graph.
|
|
30222
30208
|
*
|
|
30223
30209
|
* Used in the interactive graph editor's locked figures section.
|
|
30224
30210
|
*/
|
|
30225
|
-
const
|
|
30211
|
+
const DefiningPointSettings = props => {
|
|
30212
|
+
const {
|
|
30213
|
+
coord,
|
|
30214
|
+
color: pointColor,
|
|
30215
|
+
filled = true,
|
|
30216
|
+
label,
|
|
30217
|
+
showPoint = "false",
|
|
30218
|
+
error,
|
|
30219
|
+
onChangeProps,
|
|
30220
|
+
onTogglePoint,
|
|
30221
|
+
expanded,
|
|
30222
|
+
onToggle
|
|
30223
|
+
} = props;
|
|
30224
|
+
function handleColorChange(newValue) {
|
|
30225
|
+
onChangeProps({
|
|
30226
|
+
color: newValue
|
|
30227
|
+
});
|
|
30228
|
+
}
|
|
30229
|
+
return /*#__PURE__*/React.createElement(LockedFigureSettingsAccordion, {
|
|
30230
|
+
expanded: expanded,
|
|
30231
|
+
onToggle: onToggle,
|
|
30232
|
+
containerStyle: styles$m.container,
|
|
30233
|
+
panelStyle: styles$m.accordionPanel,
|
|
30234
|
+
header:
|
|
30235
|
+
/*#__PURE__*/
|
|
30236
|
+
// Summary: Point, coords, color (filled/open)
|
|
30237
|
+
React.createElement(View, {
|
|
30238
|
+
style: styles$m.row
|
|
30239
|
+
}, /*#__PURE__*/React.createElement(LabelLarge, null, `${label || "Point"} (${coord[0]}, ${coord[1]})`), /*#__PURE__*/React.createElement(Strut, {
|
|
30240
|
+
size: spacing.xSmall_8
|
|
30241
|
+
}), showPoint && /*#__PURE__*/React.createElement(ColorSwatch, {
|
|
30242
|
+
color: pointColor,
|
|
30243
|
+
filled: filled
|
|
30244
|
+
}))
|
|
30245
|
+
}, /*#__PURE__*/React.createElement(CoordinatePairInput, {
|
|
30246
|
+
coord: coord,
|
|
30247
|
+
error: !!error,
|
|
30248
|
+
style: styles$m.spaceUnder,
|
|
30249
|
+
onChange: newCoords => {
|
|
30250
|
+
onChangeProps({
|
|
30251
|
+
coord: newCoords
|
|
30252
|
+
});
|
|
30253
|
+
}
|
|
30254
|
+
}), onTogglePoint && /*#__PURE__*/React.createElement(LabeledSwitch, {
|
|
30255
|
+
label: "show point on graph",
|
|
30256
|
+
checked: !!showPoint,
|
|
30257
|
+
style: showPoint && styles$m.spaceUnder,
|
|
30258
|
+
onChange: onTogglePoint
|
|
30259
|
+
}), showPoint && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(ColorSelect, {
|
|
30260
|
+
selectedValue: pointColor,
|
|
30261
|
+
onChange: handleColorChange,
|
|
30262
|
+
style: styles$m.spaceUnder
|
|
30263
|
+
}), /*#__PURE__*/React.createElement(LabeledSwitch, {
|
|
30264
|
+
label: "open point",
|
|
30265
|
+
checked: !filled,
|
|
30266
|
+
onChange: newValue => {
|
|
30267
|
+
onChangeProps({
|
|
30268
|
+
filled: !newValue
|
|
30269
|
+
});
|
|
30270
|
+
}
|
|
30271
|
+
})));
|
|
30272
|
+
};
|
|
30273
|
+
const styles$m = StyleSheet.create({
|
|
30274
|
+
container: {
|
|
30275
|
+
marginTop: spacing.xSmall_8,
|
|
30276
|
+
marginBottom: 0,
|
|
30277
|
+
marginLeft: -spacing.xxxSmall_4,
|
|
30278
|
+
marginRight: -spacing.xxxSmall_4,
|
|
30279
|
+
backgroundColor: color.white
|
|
30280
|
+
},
|
|
30281
|
+
accordionPanel: {
|
|
30282
|
+
// Need more space since we don't have the actions' margins.
|
|
30283
|
+
paddingBottom: spacing.medium_16
|
|
30284
|
+
},
|
|
30285
|
+
row: {
|
|
30286
|
+
flexDirection: "row",
|
|
30287
|
+
alignItems: "center"
|
|
30288
|
+
},
|
|
30289
|
+
spaceUnder: {
|
|
30290
|
+
marginBottom: spacing.xSmall_8
|
|
30291
|
+
}
|
|
30292
|
+
});
|
|
30293
|
+
|
|
30294
|
+
const LineSwatch = props => {
|
|
30226
30295
|
const {
|
|
30227
|
-
|
|
30228
|
-
|
|
30296
|
+
color,
|
|
30297
|
+
lineStyle
|
|
30229
30298
|
} = props;
|
|
30230
|
-
const figureTypes = props.showM2Features ? ["point", "line", "ellipse", "vector"] : ["point", "line"];
|
|
30231
30299
|
return /*#__PURE__*/React.createElement(View, {
|
|
30232
|
-
style: styles$
|
|
30233
|
-
}, /*#__PURE__*/React.createElement(
|
|
30234
|
-
|
|
30235
|
-
style: styles$
|
|
30236
|
-
|
|
30237
|
-
|
|
30238
|
-
|
|
30239
|
-
onClick: () => onChange(figureType)
|
|
30240
|
-
}, figureType))));
|
|
30300
|
+
style: styles$l.container
|
|
30301
|
+
}, /*#__PURE__*/React.createElement(View, {
|
|
30302
|
+
"aria-label": `${color}, ${lineStyle}`,
|
|
30303
|
+
style: [styles$l.lineSwatch, {
|
|
30304
|
+
border: `5px ${lineStyle} ${lockedFigureColors[color]}`
|
|
30305
|
+
}]
|
|
30306
|
+
}));
|
|
30241
30307
|
};
|
|
30242
|
-
const styles$
|
|
30308
|
+
const styles$l = StyleSheet.create({
|
|
30243
30309
|
container: {
|
|
30244
|
-
|
|
30245
|
-
|
|
30246
|
-
|
|
30247
|
-
backgroundColor: color.fadedBlue8,
|
|
30310
|
+
backgroundColor: color.white,
|
|
30311
|
+
justifyContent: "center",
|
|
30312
|
+
padding: spacing.xSmall_8,
|
|
30248
30313
|
borderRadius: spacing.xxxSmall_4
|
|
30314
|
+
},
|
|
30315
|
+
lineSwatch: {
|
|
30316
|
+
width: 40
|
|
30249
30317
|
}
|
|
30250
30318
|
});
|
|
30251
30319
|
|
|
30252
|
-
|
|
30253
|
-
|
|
30254
|
-
|
|
30255
|
-
|
|
30256
|
-
|
|
30257
|
-
|
|
30258
|
-
|
|
30259
|
-
|
|
30260
|
-
|
|
30261
|
-
|
|
30262
|
-
|
|
30263
|
-
|
|
30264
|
-
|
|
30265
|
-
|
|
30266
|
-
|
|
30267
|
-
|
|
30268
|
-
|
|
30269
|
-
// Chrome is the only browser we support that exhibits this
|
|
30270
|
-
// buggy behavior and using `focusOptions` works around the
|
|
30271
|
-
// bug, it is perfectly reasonable to use the feature in this
|
|
30272
|
-
// case. We are not relying on the effect of the
|
|
30273
|
-
// `preventScroll` option otherwise.
|
|
30274
|
-
//
|
|
30275
|
-
// focusOptions documentation:
|
|
30276
|
-
//
|
|
30277
|
-
// https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/focus
|
|
30278
|
-
//
|
|
30279
|
-
// Note that there could be cases where we want default focus() behavior.
|
|
30280
|
-
// One that comes to mind is a dropdown with a long list of options that
|
|
30281
|
-
// might be rendered off screen when opened. With this workaround the
|
|
30282
|
-
// selected option would not be scrolled into view if the option is near
|
|
30283
|
-
// the end of the list. We're not aware of any uses of the dropdown where
|
|
30284
|
-
// this is an issue, however, so there isn't currently a way to out of the
|
|
30285
|
-
// `preventScroll` behavior.
|
|
30320
|
+
const lengthZeroStr = "The line cannot have length 0.";
|
|
30321
|
+
const LockedLineSettings = props => {
|
|
30322
|
+
const {
|
|
30323
|
+
kind,
|
|
30324
|
+
points,
|
|
30325
|
+
color: lineColor,
|
|
30326
|
+
lineStyle = "solid",
|
|
30327
|
+
showPoint1,
|
|
30328
|
+
showPoint2,
|
|
30329
|
+
onChangeProps,
|
|
30330
|
+
onMove,
|
|
30331
|
+
onRemove
|
|
30332
|
+
} = props;
|
|
30333
|
+
const [point1, point2] = points;
|
|
30334
|
+
const capitalizeKind = kind.charAt(0).toUpperCase() + kind.slice(1);
|
|
30335
|
+
const lineLabel = `${capitalizeKind} (${point1.coord[0]},
|
|
30336
|
+
${point1.coord[1]}), (${point2.coord[0]}, ${point2.coord[1]})`;
|
|
30286
30337
|
|
|
30287
|
-
//
|
|
30288
|
-
|
|
30289
|
-
|
|
30290
|
-
|
|
30291
|
-
}
|
|
30292
|
-
|
|
30293
|
-
|
|
30294
|
-
|
|
30295
|
-
case "point":
|
|
30296
|
-
return {
|
|
30297
|
-
type: "point",
|
|
30298
|
-
coord: [0, 0],
|
|
30299
|
-
color: DEFAULT_COLOR,
|
|
30300
|
-
filled: true
|
|
30301
|
-
};
|
|
30302
|
-
case "line":
|
|
30303
|
-
return {
|
|
30304
|
-
type: "line",
|
|
30305
|
-
kind: "line",
|
|
30306
|
-
points: [getDefaultFigureForType("point"), _extends({}, getDefaultFigureForType("point"), {
|
|
30307
|
-
coord: [2, 2]
|
|
30308
|
-
})],
|
|
30309
|
-
color: DEFAULT_COLOR,
|
|
30310
|
-
lineStyle: "solid",
|
|
30311
|
-
showPoint1: false,
|
|
30312
|
-
showPoint2: false
|
|
30313
|
-
};
|
|
30314
|
-
case "vector":
|
|
30315
|
-
return {
|
|
30316
|
-
type: "vector",
|
|
30317
|
-
points: [[0, 0], [2, 2]],
|
|
30318
|
-
color: DEFAULT_COLOR
|
|
30319
|
-
};
|
|
30320
|
-
case "ellipse":
|
|
30321
|
-
return {
|
|
30322
|
-
type: "ellipse",
|
|
30323
|
-
center: [0, 0],
|
|
30324
|
-
radius: [1, 1],
|
|
30325
|
-
angle: 0,
|
|
30326
|
-
color: DEFAULT_COLOR,
|
|
30327
|
-
fillStyle: "none",
|
|
30328
|
-
strokeStyle: "solid"
|
|
30329
|
-
};
|
|
30330
|
-
case "polygon":
|
|
30331
|
-
return {
|
|
30332
|
-
type: "polygon",
|
|
30333
|
-
points: [[0, 2], [-1, 0], [1, 0]],
|
|
30334
|
-
color: DEFAULT_COLOR,
|
|
30335
|
-
showVertices: false,
|
|
30336
|
-
fillStyle: "none",
|
|
30337
|
-
strokeStyle: "solid"
|
|
30338
|
-
};
|
|
30339
|
-
default:
|
|
30340
|
-
throw new UnreachableCaseError(type);
|
|
30338
|
+
// Check if the line has length 0.
|
|
30339
|
+
const isInvalid = vector.equal(point1.coord, point2.coord);
|
|
30340
|
+
function handleChangePoint(newPointProps, index) {
|
|
30341
|
+
const newPoints = [...points];
|
|
30342
|
+
newPoints[index] = _extends({}, points[index], newPointProps);
|
|
30343
|
+
onChangeProps({
|
|
30344
|
+
points: newPoints
|
|
30345
|
+
});
|
|
30341
30346
|
}
|
|
30342
|
-
|
|
30343
|
-
|
|
30344
|
-
|
|
30345
|
-
|
|
30346
|
-
|
|
30347
|
-
|
|
30348
|
-
}
|
|
30347
|
+
function handleColorChange(newColor) {
|
|
30348
|
+
onChangeProps({
|
|
30349
|
+
color: newColor,
|
|
30350
|
+
// Keep the line's points' colors in sync with the line color.
|
|
30351
|
+
points: [_extends({}, point1, {
|
|
30352
|
+
color: newColor
|
|
30353
|
+
}), _extends({}, point2, {
|
|
30354
|
+
color: newColor
|
|
30355
|
+
})]
|
|
30356
|
+
});
|
|
30357
|
+
}
|
|
30358
|
+
return /*#__PURE__*/React.createElement(LockedFigureSettingsAccordion, {
|
|
30359
|
+
expanded: props.expanded,
|
|
30360
|
+
onToggle: props.onToggle,
|
|
30361
|
+
header: /*#__PURE__*/React.createElement(View, {
|
|
30362
|
+
style: styles$k.row
|
|
30363
|
+
}, /*#__PURE__*/React.createElement(LabelLarge, null, lineLabel), /*#__PURE__*/React.createElement(Strut, {
|
|
30364
|
+
size: spacing.xSmall_8
|
|
30365
|
+
}), /*#__PURE__*/React.createElement(LineSwatch, {
|
|
30366
|
+
color: lineColor,
|
|
30367
|
+
lineStyle: lineStyle
|
|
30368
|
+
}))
|
|
30369
|
+
}, /*#__PURE__*/React.createElement(LabelMedium, {
|
|
30370
|
+
tag: "label",
|
|
30371
|
+
style: [styles$k.row, styles$k.spaceUnder]
|
|
30372
|
+
}, "kind", /*#__PURE__*/React.createElement(Strut, {
|
|
30373
|
+
size: spacing.xxxSmall_4
|
|
30374
|
+
}), /*#__PURE__*/React.createElement(SingleSelect, {
|
|
30375
|
+
selectedValue: kind,
|
|
30376
|
+
onChange: value => onChangeProps({
|
|
30377
|
+
kind: value
|
|
30378
|
+
})
|
|
30379
|
+
// Placeholder is required, but never gets used.
|
|
30380
|
+
,
|
|
30381
|
+
placeholder: ""
|
|
30382
|
+
}, /*#__PURE__*/React.createElement(OptionItem, {
|
|
30383
|
+
value: "line",
|
|
30384
|
+
label: "line"
|
|
30385
|
+
}), /*#__PURE__*/React.createElement(OptionItem, {
|
|
30386
|
+
value: "ray",
|
|
30387
|
+
label: "ray"
|
|
30388
|
+
}), /*#__PURE__*/React.createElement(OptionItem, {
|
|
30389
|
+
value: "segment",
|
|
30390
|
+
label: "segment"
|
|
30391
|
+
}))), /*#__PURE__*/React.createElement(View, {
|
|
30392
|
+
style: styles$k.row
|
|
30393
|
+
}, /*#__PURE__*/React.createElement(ColorSelect, {
|
|
30394
|
+
selectedValue: lineColor,
|
|
30395
|
+
onChange: handleColorChange
|
|
30396
|
+
}), /*#__PURE__*/React.createElement(Strut, {
|
|
30397
|
+
size: spacing.small_12
|
|
30398
|
+
}), /*#__PURE__*/React.createElement(LabelMedium, {
|
|
30399
|
+
tag: "label",
|
|
30400
|
+
style: styles$k.row
|
|
30401
|
+
}, "style", /*#__PURE__*/React.createElement(Strut, {
|
|
30402
|
+
size: spacing.xxxSmall_4
|
|
30403
|
+
}), /*#__PURE__*/React.createElement(SingleSelect, {
|
|
30404
|
+
selectedValue: lineStyle,
|
|
30405
|
+
onChange: value => onChangeProps({
|
|
30406
|
+
lineStyle: value
|
|
30407
|
+
})
|
|
30408
|
+
// Placeholder is required, but never gets used.
|
|
30409
|
+
,
|
|
30410
|
+
placeholder: "",
|
|
30411
|
+
style: styles$k.selectMarginOffset
|
|
30412
|
+
}, /*#__PURE__*/React.createElement(OptionItem, {
|
|
30413
|
+
value: "solid",
|
|
30414
|
+
label: "solid"
|
|
30415
|
+
}), /*#__PURE__*/React.createElement(OptionItem, {
|
|
30416
|
+
value: "dashed",
|
|
30417
|
+
label: "dashed"
|
|
30418
|
+
})))), isInvalid && /*#__PURE__*/React.createElement(LabelMedium, {
|
|
30419
|
+
style: styles$k.errorText
|
|
30420
|
+
}, lengthZeroStr), /*#__PURE__*/React.createElement(DefiningPointSettings, _extends({
|
|
30421
|
+
label: "Point 1",
|
|
30422
|
+
showPoint: showPoint1,
|
|
30423
|
+
error: isInvalid ? lengthZeroStr : null
|
|
30424
|
+
}, point1, {
|
|
30425
|
+
onTogglePoint: newValue => onChangeProps({
|
|
30426
|
+
showPoint1: newValue
|
|
30427
|
+
}),
|
|
30428
|
+
onChangeProps: newProps => handleChangePoint(newProps, 0)
|
|
30429
|
+
})), /*#__PURE__*/React.createElement(DefiningPointSettings, _extends({
|
|
30430
|
+
label: "Point 2",
|
|
30431
|
+
showPoint: showPoint2,
|
|
30432
|
+
error: isInvalid ? lengthZeroStr : null
|
|
30433
|
+
}, point2, {
|
|
30434
|
+
onTogglePoint: newValue => onChangeProps({
|
|
30435
|
+
showPoint2: newValue
|
|
30436
|
+
}),
|
|
30437
|
+
onChangeProps: newProps => handleChangePoint(newProps, 1)
|
|
30438
|
+
})), /*#__PURE__*/React.createElement(LockedFigureSettingsActions, {
|
|
30439
|
+
showM2Features: props.showM2Features,
|
|
30440
|
+
figureType: props.type,
|
|
30441
|
+
onMove: onMove,
|
|
30442
|
+
onRemove: onRemove
|
|
30443
|
+
}));
|
|
30444
|
+
};
|
|
30445
|
+
const styles$k = StyleSheet.create({
|
|
30446
|
+
row: {
|
|
30447
|
+
display: "flex",
|
|
30448
|
+
flexDirection: "row",
|
|
30449
|
+
alignItems: "center"
|
|
30450
|
+
},
|
|
30451
|
+
spaceUnder: {
|
|
30452
|
+
marginBottom: spacing.xSmall_8
|
|
30453
|
+
},
|
|
30454
|
+
selectMarginOffset: {
|
|
30455
|
+
// Align with the point settings accordions.
|
|
30456
|
+
marginInlineEnd: -spacing.xxxSmall_4
|
|
30457
|
+
},
|
|
30458
|
+
errorText: {
|
|
30459
|
+
color: color.red
|
|
30460
|
+
}
|
|
30461
|
+
});
|
|
30349
30462
|
|
|
30350
|
-
|
|
30463
|
+
/**
|
|
30464
|
+
* LockedPointSettings is a component that allows the user to edit the
|
|
30465
|
+
* settings of specifically a locked point on the graph.
|
|
30466
|
+
*
|
|
30467
|
+
* Used in the interactive graph editor's locked figures section.
|
|
30468
|
+
*/
|
|
30469
|
+
const LockedPointSettings = props => {
|
|
30351
30470
|
const {
|
|
30352
|
-
|
|
30353
|
-
|
|
30471
|
+
coord,
|
|
30472
|
+
color: pointColor,
|
|
30473
|
+
filled = true,
|
|
30474
|
+
onChangeProps,
|
|
30475
|
+
onMove,
|
|
30476
|
+
onRemove
|
|
30354
30477
|
} = props;
|
|
30355
|
-
|
|
30356
|
-
|
|
30357
|
-
|
|
30358
|
-
|
|
30359
|
-
|
|
30360
|
-
// If the new value is not a number, don't update the props.
|
|
30361
|
-
// If it's empty, keep the props the same value instead of setting to 0.
|
|
30362
|
-
if (isNaN(+newValue) || newValue === "") {
|
|
30363
|
-
return;
|
|
30364
|
-
}
|
|
30365
|
-
|
|
30366
|
-
// Update the graph.
|
|
30367
|
-
onChange(degreeToRadian(newValue));
|
|
30478
|
+
function handleColorChange(newValue) {
|
|
30479
|
+
onChangeProps({
|
|
30480
|
+
color: newValue
|
|
30481
|
+
});
|
|
30368
30482
|
}
|
|
30369
|
-
return /*#__PURE__*/React.createElement(
|
|
30370
|
-
|
|
30371
|
-
|
|
30372
|
-
|
|
30373
|
-
|
|
30374
|
-
|
|
30375
|
-
|
|
30376
|
-
|
|
30377
|
-
|
|
30378
|
-
|
|
30379
|
-
|
|
30380
|
-
|
|
30483
|
+
return /*#__PURE__*/React.createElement(LockedFigureSettingsAccordion, {
|
|
30484
|
+
expanded: props.expanded,
|
|
30485
|
+
onToggle: props.onToggle,
|
|
30486
|
+
header:
|
|
30487
|
+
/*#__PURE__*/
|
|
30488
|
+
// Summary: Point, coords, color (filled/open)
|
|
30489
|
+
React.createElement(View, {
|
|
30490
|
+
style: styles$j.row
|
|
30491
|
+
}, /*#__PURE__*/React.createElement(LabelLarge, null, `Point (${coord[0]}, ${coord[1]})`), /*#__PURE__*/React.createElement(Strut, {
|
|
30492
|
+
size: spacing.xSmall_8
|
|
30493
|
+
}), /*#__PURE__*/React.createElement(ColorSwatch, {
|
|
30494
|
+
color: pointColor,
|
|
30495
|
+
filled: filled
|
|
30496
|
+
}))
|
|
30497
|
+
}, /*#__PURE__*/React.createElement(CoordinatePairInput, {
|
|
30498
|
+
coord: coord,
|
|
30499
|
+
style: styles$j.spaceUnder,
|
|
30500
|
+
onChange: newCoord => {
|
|
30501
|
+
onChangeProps({
|
|
30502
|
+
coord: newCoord
|
|
30503
|
+
});
|
|
30504
|
+
}
|
|
30505
|
+
}), /*#__PURE__*/React.createElement(ColorSelect, {
|
|
30506
|
+
selectedValue: pointColor,
|
|
30507
|
+
onChange: handleColorChange,
|
|
30508
|
+
style: styles$j.spaceUnder
|
|
30509
|
+
}), /*#__PURE__*/React.createElement(LabeledSwitch, {
|
|
30510
|
+
label: "open point",
|
|
30511
|
+
checked: !filled,
|
|
30512
|
+
onChange: newValue => {
|
|
30513
|
+
onChangeProps({
|
|
30514
|
+
filled: !newValue
|
|
30515
|
+
});
|
|
30516
|
+
}
|
|
30517
|
+
}), /*#__PURE__*/React.createElement(LockedFigureSettingsActions, {
|
|
30518
|
+
showM2Features: props.showM2Features,
|
|
30519
|
+
figureType: props.type,
|
|
30520
|
+
onMove: onMove,
|
|
30521
|
+
onRemove: onRemove
|
|
30381
30522
|
}));
|
|
30382
30523
|
};
|
|
30383
|
-
const styles$
|
|
30524
|
+
const styles$j = StyleSheet.create({
|
|
30384
30525
|
row: {
|
|
30385
|
-
display: "flex",
|
|
30386
30526
|
flexDirection: "row",
|
|
30387
30527
|
alignItems: "center"
|
|
30388
30528
|
},
|
|
30389
|
-
|
|
30390
|
-
|
|
30529
|
+
spaceUnder: {
|
|
30530
|
+
marginBottom: spacing.xSmall_8
|
|
30391
30531
|
}
|
|
30392
30532
|
});
|
|
30393
30533
|
|
|
30394
|
-
const
|
|
30534
|
+
const PolygonSwatch = props => {
|
|
30395
30535
|
const {
|
|
30396
|
-
color
|
|
30397
|
-
|
|
30398
|
-
|
|
30536
|
+
color,
|
|
30537
|
+
fillStyle,
|
|
30538
|
+
strokeStyle
|
|
30399
30539
|
} = props;
|
|
30400
30540
|
return /*#__PURE__*/React.createElement(View, {
|
|
30401
|
-
"aria-label":
|
|
30402
|
-
|
|
30403
|
-
|
|
30404
|
-
style: [styles$p.colorSwatch, {
|
|
30405
|
-
border: `4px solid ${lockedFigureColors[color$1]}`,
|
|
30406
|
-
backgroundColor: filled ? lockedFigureColors[color$1] : color.white
|
|
30541
|
+
"aria-label": `${color}, stroke ${strokeStyle}, fill ${fillStyle}`,
|
|
30542
|
+
style: [styles$i.container, {
|
|
30543
|
+
border: `4px ${strokeStyle} ${lockedFigureColors[color]}`
|
|
30407
30544
|
}]
|
|
30408
|
-
}
|
|
30545
|
+
}, /*#__PURE__*/React.createElement(View, {
|
|
30546
|
+
style: [styles$i.innerSquare, {
|
|
30547
|
+
backgroundColor: lockedFigureColors[color],
|
|
30548
|
+
opacity: lockedFigureFillStyles[fillStyle]
|
|
30549
|
+
}]
|
|
30550
|
+
}));
|
|
30409
30551
|
};
|
|
30410
|
-
const styles$
|
|
30411
|
-
|
|
30552
|
+
const styles$i = StyleSheet.create({
|
|
30553
|
+
container: {
|
|
30412
30554
|
// Add a white outline so that the color swatch is visible when
|
|
30413
30555
|
// the dropdown option is highlighted with its blue background.
|
|
30414
30556
|
outline: `2px solid ${color.offWhite}`,
|
|
30415
|
-
borderRadius: "50%",
|
|
30416
30557
|
width: spacing.large_24,
|
|
30417
|
-
height: spacing.large_24
|
|
30558
|
+
height: spacing.large_24,
|
|
30559
|
+
backgroundColor: color.white,
|
|
30560
|
+
alignItems: "center",
|
|
30561
|
+
justifyContent: "center"
|
|
30562
|
+
},
|
|
30563
|
+
innerSquare: {
|
|
30564
|
+
width: 20,
|
|
30565
|
+
height: 20
|
|
30418
30566
|
}
|
|
30419
30567
|
});
|
|
30420
30568
|
|
|
30421
|
-
const
|
|
30422
|
-
const ColorSelect = props => {
|
|
30569
|
+
const LockedPolygonSettings = props => {
|
|
30423
30570
|
const {
|
|
30424
|
-
|
|
30425
|
-
|
|
30426
|
-
|
|
30571
|
+
points,
|
|
30572
|
+
color,
|
|
30573
|
+
showVertices,
|
|
30574
|
+
fillStyle,
|
|
30575
|
+
strokeStyle,
|
|
30576
|
+
expanded,
|
|
30577
|
+
onToggle,
|
|
30578
|
+
onChangeProps,
|
|
30579
|
+
onMove,
|
|
30580
|
+
onRemove
|
|
30427
30581
|
} = props;
|
|
30428
|
-
|
|
30429
|
-
|
|
30430
|
-
|
|
30582
|
+
function handleColorChange(newValue) {
|
|
30583
|
+
onChangeProps({
|
|
30584
|
+
color: newValue
|
|
30585
|
+
});
|
|
30586
|
+
}
|
|
30587
|
+
return /*#__PURE__*/React.createElement(LockedFigureSettingsAccordion, {
|
|
30588
|
+
expanded: expanded,
|
|
30589
|
+
onToggle: onToggle,
|
|
30590
|
+
header:
|
|
30591
|
+
/*#__PURE__*/
|
|
30592
|
+
// Summary: Polygon, number of sides, style swatch
|
|
30593
|
+
React.createElement(View, {
|
|
30594
|
+
style: styles$h.row
|
|
30595
|
+
}, /*#__PURE__*/React.createElement(LabelLarge, null, `Polygon, ${points.length} sides`), /*#__PURE__*/React.createElement(Strut, {
|
|
30596
|
+
size: spacing.xSmall_8
|
|
30597
|
+
}), /*#__PURE__*/React.createElement(PolygonSwatch, {
|
|
30598
|
+
color: color,
|
|
30599
|
+
fillStyle: fillStyle,
|
|
30600
|
+
strokeStyle: strokeStyle
|
|
30601
|
+
}))
|
|
30602
|
+
}, /*#__PURE__*/React.createElement(View, {
|
|
30603
|
+
style: [styles$h.row, styles$h.spaceUnder]
|
|
30604
|
+
}, /*#__PURE__*/React.createElement(ColorSelect, {
|
|
30605
|
+
selectedValue: color,
|
|
30606
|
+
onChange: handleColorChange
|
|
30607
|
+
}), /*#__PURE__*/React.createElement(Strut, {
|
|
30608
|
+
size: spacing.medium_16
|
|
30609
|
+
}), /*#__PURE__*/React.createElement(LabelMedium, {
|
|
30431
30610
|
tag: "label",
|
|
30432
|
-
style: styles$
|
|
30433
|
-
}, "
|
|
30611
|
+
style: styles$h.row
|
|
30612
|
+
}, "fill", /*#__PURE__*/React.createElement(Strut, {
|
|
30434
30613
|
size: spacing.xxSmall_6
|
|
30435
30614
|
}), /*#__PURE__*/React.createElement(SingleSelect, {
|
|
30436
|
-
selectedValue:
|
|
30437
|
-
onChange:
|
|
30615
|
+
selectedValue: fillStyle,
|
|
30616
|
+
onChange: value => onChangeProps({
|
|
30617
|
+
fillStyle: value
|
|
30618
|
+
})
|
|
30438
30619
|
// Placeholder is required, but never gets used.
|
|
30439
30620
|
,
|
|
30440
30621
|
placeholder: ""
|
|
30441
|
-
},
|
|
30442
|
-
key:
|
|
30443
|
-
value:
|
|
30444
|
-
label:
|
|
30445
|
-
|
|
30446
|
-
color: colorName,
|
|
30447
|
-
decorative: true
|
|
30448
|
-
})
|
|
30449
|
-
}, colorName)))));
|
|
30450
|
-
};
|
|
30451
|
-
const styles$o = StyleSheet.create({
|
|
30452
|
-
row: {
|
|
30453
|
-
display: "flex",
|
|
30454
|
-
flexDirection: "row",
|
|
30455
|
-
alignItems: "center"
|
|
30456
|
-
}
|
|
30457
|
-
});
|
|
30458
|
-
|
|
30459
|
-
const CoordinatePairInput = props => {
|
|
30460
|
-
const {
|
|
30461
|
-
coord,
|
|
30462
|
-
labels,
|
|
30463
|
-
error,
|
|
30464
|
-
onChange
|
|
30465
|
-
} = props;
|
|
30466
|
-
|
|
30467
|
-
// Keep track of the coordinates via state as the user is editing them,
|
|
30468
|
-
// before they are updated in the props as a valid number.
|
|
30469
|
-
const [coordState, setCoordState] = React.useState([
|
|
30470
|
-
// Using strings to make it easier to work with the text fields.
|
|
30471
|
-
coord[0].toString(), coord[1].toString()]);
|
|
30472
|
-
function handleCoordChange(newValue, coordIndex) {
|
|
30473
|
-
// Update the local state (update the input field value).
|
|
30474
|
-
const newCoordState = [...coordState];
|
|
30475
|
-
newCoordState[coordIndex] = newValue;
|
|
30476
|
-
setCoordState(newCoordState);
|
|
30477
|
-
|
|
30478
|
-
// If the new value is not a number, don't update the props.
|
|
30479
|
-
// If it's empty, keep the props the same value instead of setting to 0.
|
|
30480
|
-
if (isNaN(+newValue) || newValue === "") {
|
|
30481
|
-
return;
|
|
30482
|
-
}
|
|
30483
|
-
|
|
30484
|
-
// Update the props (update the graph).
|
|
30485
|
-
const newCoords = [...coord];
|
|
30486
|
-
newCoords[coordIndex] = +newValue;
|
|
30487
|
-
onChange(newCoords);
|
|
30488
|
-
}
|
|
30489
|
-
return /*#__PURE__*/React.createElement(View, null, /*#__PURE__*/React.createElement(View, {
|
|
30490
|
-
style: [styles$n.row, styles$n.spaceUnder]
|
|
30491
|
-
}, /*#__PURE__*/React.createElement(LabelMedium, {
|
|
30492
|
-
tag: "label",
|
|
30493
|
-
style: styles$n.row
|
|
30494
|
-
}, labels ? labels[0] : "x coord", /*#__PURE__*/React.createElement(Strut, {
|
|
30495
|
-
size: spacing.xxSmall_6
|
|
30496
|
-
}), /*#__PURE__*/React.createElement(TextField, {
|
|
30497
|
-
type: "number",
|
|
30498
|
-
value: coordState[0],
|
|
30499
|
-
onChange: newValue => handleCoordChange(newValue, 0),
|
|
30500
|
-
style: [styles$n.textField, error ? styles$n.errorField : undefined]
|
|
30501
|
-
})), /*#__PURE__*/React.createElement(Strut, {
|
|
30502
|
-
size: spacing.medium_16
|
|
30503
|
-
}), /*#__PURE__*/React.createElement(LabelMedium, {
|
|
30622
|
+
}, Object.keys(lockedFigureFillStyles).map(option => /*#__PURE__*/React.createElement(OptionItem, {
|
|
30623
|
+
key: option,
|
|
30624
|
+
value: option,
|
|
30625
|
+
label: option
|
|
30626
|
+
}, option))))), /*#__PURE__*/React.createElement(LabelMedium, {
|
|
30504
30627
|
tag: "label",
|
|
30505
|
-
style: styles$
|
|
30506
|
-
},
|
|
30628
|
+
style: [styles$h.row, styles$h.spaceUnder]
|
|
30629
|
+
}, "stroke", /*#__PURE__*/React.createElement(Strut, {
|
|
30507
30630
|
size: spacing.xxSmall_6
|
|
30508
|
-
}), /*#__PURE__*/React.createElement(
|
|
30509
|
-
|
|
30510
|
-
|
|
30511
|
-
|
|
30512
|
-
|
|
30513
|
-
|
|
30631
|
+
}), /*#__PURE__*/React.createElement(SingleSelect, {
|
|
30632
|
+
selectedValue: strokeStyle,
|
|
30633
|
+
onChange: value => onChangeProps({
|
|
30634
|
+
strokeStyle: value
|
|
30635
|
+
})
|
|
30636
|
+
// Placeholder is required, but never gets used.
|
|
30637
|
+
,
|
|
30638
|
+
placeholder: ""
|
|
30639
|
+
}, /*#__PURE__*/React.createElement(OptionItem, {
|
|
30640
|
+
value: "solid",
|
|
30641
|
+
label: "solid"
|
|
30642
|
+
}, "solid"), /*#__PURE__*/React.createElement(OptionItem, {
|
|
30643
|
+
value: "dashed",
|
|
30644
|
+
label: "dashed"
|
|
30645
|
+
}, "dashed"))), /*#__PURE__*/React.createElement(LabeledSwitch, {
|
|
30646
|
+
label: "show vertices",
|
|
30647
|
+
checked: showVertices,
|
|
30648
|
+
onChange: newValue => onChangeProps({
|
|
30649
|
+
showVertices: newValue
|
|
30650
|
+
}),
|
|
30651
|
+
style: styles$h.spaceUnder
|
|
30652
|
+
}), /*#__PURE__*/React.createElement(LockedFigureSettingsAccordion, {
|
|
30653
|
+
header: /*#__PURE__*/React.createElement(LabelLarge, null, "Points"),
|
|
30654
|
+
expanded: true,
|
|
30655
|
+
containerStyle: styles$h.pointAccordionContainer,
|
|
30656
|
+
panelStyle: styles$h.pointAccordionPanel
|
|
30657
|
+
}, points.map((point, index) => {
|
|
30658
|
+
const pointLabel = String.fromCharCode(65 + index);
|
|
30659
|
+
return /*#__PURE__*/React.createElement(View, {
|
|
30660
|
+
key: `locked-polygon-point-${point[0]}-${point[1]}-index-${index}`,
|
|
30661
|
+
style: [styles$h.row, styles$h.spaceUnder]
|
|
30662
|
+
}, /*#__PURE__*/React.createElement(LabelLarge, null, `${pointLabel}:`), /*#__PURE__*/React.createElement(Strut, {
|
|
30663
|
+
size: spacing.medium_16
|
|
30664
|
+
}), /*#__PURE__*/React.createElement(CoordinatePairInput, {
|
|
30665
|
+
coord: point,
|
|
30666
|
+
labels: ["x", "y"],
|
|
30667
|
+
onChange: newValue => {
|
|
30668
|
+
const newPoints = [...points];
|
|
30669
|
+
newPoints[index] = newValue;
|
|
30670
|
+
props.onChangeProps({
|
|
30671
|
+
points: newPoints
|
|
30672
|
+
});
|
|
30673
|
+
}
|
|
30674
|
+
}),
|
|
30675
|
+
// Only show the minus (delete) buttons if there are
|
|
30676
|
+
// more than 3 points. 3 points is the minimum number
|
|
30677
|
+
// of points for a polygon (triangle).
|
|
30678
|
+
points.length > 3 && /*#__PURE__*/React.createElement(IconButton, {
|
|
30679
|
+
"aria-label": `Delete polygon point ${pointLabel}`,
|
|
30680
|
+
icon: minusCircle,
|
|
30681
|
+
color: "destructive",
|
|
30682
|
+
onClick: () => {
|
|
30683
|
+
const newPoints = [...points];
|
|
30684
|
+
newPoints.splice(index, 1);
|
|
30685
|
+
props.onChangeProps({
|
|
30686
|
+
points: newPoints
|
|
30687
|
+
});
|
|
30688
|
+
},
|
|
30689
|
+
style: styles$h.icon
|
|
30690
|
+
}));
|
|
30691
|
+
}), /*#__PURE__*/React.createElement(Button, {
|
|
30692
|
+
kind: "tertiary",
|
|
30693
|
+
startIcon: plusCircle,
|
|
30694
|
+
onClick: () => {
|
|
30695
|
+
props.onChangeProps({
|
|
30696
|
+
points: [...points, [0, 0]]
|
|
30697
|
+
});
|
|
30698
|
+
}
|
|
30699
|
+
}, "Add point")), /*#__PURE__*/React.createElement(LockedFigureSettingsActions, {
|
|
30700
|
+
showM2Features: props.showM2Features,
|
|
30701
|
+
figureType: props.type,
|
|
30702
|
+
onMove: onMove,
|
|
30703
|
+
onRemove: onRemove
|
|
30704
|
+
}));
|
|
30514
30705
|
};
|
|
30515
|
-
const styles$
|
|
30706
|
+
const styles$h = StyleSheet.create({
|
|
30516
30707
|
row: {
|
|
30517
30708
|
display: "flex",
|
|
30518
30709
|
flexDirection: "row",
|
|
30519
30710
|
alignItems: "center"
|
|
30520
30711
|
},
|
|
30521
|
-
|
|
30522
|
-
|
|
30712
|
+
pointAccordionContainer: {
|
|
30713
|
+
backgroundColor: color.white
|
|
30523
30714
|
},
|
|
30524
|
-
|
|
30525
|
-
|
|
30715
|
+
pointAccordionPanel: {
|
|
30716
|
+
alignItems: "start"
|
|
30526
30717
|
},
|
|
30527
|
-
|
|
30528
|
-
|
|
30529
|
-
|
|
30718
|
+
icon: {
|
|
30719
|
+
marginInlineStart: spacing.xxxSmall_4
|
|
30720
|
+
},
|
|
30721
|
+
spaceUnder: {
|
|
30722
|
+
marginBottom: spacing.xSmall_8
|
|
30530
30723
|
}
|
|
30531
30724
|
});
|
|
30532
30725
|
|
|
30533
|
-
|
|
30726
|
+
/**
|
|
30727
|
+
* LockedVectorSettings is a component that allows the user to edit the
|
|
30728
|
+
* settings of specifically a locked vector on the graph.
|
|
30729
|
+
*
|
|
30730
|
+
* Used in the interactive graph editor's locked figures section.
|
|
30731
|
+
*/
|
|
30732
|
+
const lengthErrorMessage = "The vector cannot have length 0.";
|
|
30733
|
+
const LockedVectorSettings = props => {
|
|
30534
30734
|
const {
|
|
30535
|
-
|
|
30536
|
-
|
|
30537
|
-
|
|
30735
|
+
points,
|
|
30736
|
+
color: lineColor,
|
|
30737
|
+
onChangeProps,
|
|
30738
|
+
onMove,
|
|
30739
|
+
onRemove
|
|
30538
30740
|
} = props;
|
|
30539
|
-
|
|
30540
|
-
|
|
30541
|
-
|
|
30542
|
-
|
|
30543
|
-
|
|
30741
|
+
const [tail, tip] = points;
|
|
30742
|
+
const lineLabel = `Vector (${tail[0]}, ${tail[1]}), (${tip[0]}, ${tip[1]})`;
|
|
30743
|
+
|
|
30744
|
+
// Check if the line has length 0.
|
|
30745
|
+
const isInvalid = vector.equal(tail, tip);
|
|
30746
|
+
function handleChangePoint(newCoord, index) {
|
|
30747
|
+
if (typeof newCoord !== "undefined") {
|
|
30748
|
+
const newPoints = [...points];
|
|
30749
|
+
newPoints[index] = [...newCoord];
|
|
30750
|
+
onChangeProps({
|
|
30751
|
+
points: newPoints
|
|
30752
|
+
});
|
|
30753
|
+
}
|
|
30754
|
+
}
|
|
30755
|
+
function handleColorChange(newColor) {
|
|
30756
|
+
onChangeProps({
|
|
30757
|
+
color: newColor
|
|
30758
|
+
});
|
|
30759
|
+
}
|
|
30760
|
+
return /*#__PURE__*/React.createElement(LockedFigureSettingsAccordion, {
|
|
30761
|
+
expanded: props.expanded,
|
|
30762
|
+
onToggle: props.onToggle,
|
|
30763
|
+
header: /*#__PURE__*/React.createElement(View, {
|
|
30764
|
+
style: styles$g.row
|
|
30765
|
+
}, /*#__PURE__*/React.createElement(LabelLarge, null, lineLabel), /*#__PURE__*/React.createElement(Strut, {
|
|
30766
|
+
size: spacing.xSmall_8
|
|
30767
|
+
}), /*#__PURE__*/React.createElement(LineSwatch, {
|
|
30768
|
+
color: lineColor,
|
|
30769
|
+
lineStyle: "solid"
|
|
30770
|
+
}))
|
|
30544
30771
|
}, /*#__PURE__*/React.createElement(View, {
|
|
30545
|
-
style: [styles$
|
|
30546
|
-
|
|
30547
|
-
|
|
30548
|
-
|
|
30772
|
+
style: [styles$g.row, styles$g.spaceUnder]
|
|
30773
|
+
}, /*#__PURE__*/React.createElement(ColorSelect, {
|
|
30774
|
+
selectedValue: lineColor,
|
|
30775
|
+
onChange: handleColorChange
|
|
30776
|
+
})), isInvalid && /*#__PURE__*/React.createElement(LabelMedium, {
|
|
30777
|
+
style: styles$g.errorText
|
|
30778
|
+
}, lengthErrorMessage), /*#__PURE__*/React.createElement(LockedFigureSettingsAccordion, {
|
|
30779
|
+
expanded: true // Initial state is expanded
|
|
30780
|
+
,
|
|
30781
|
+
containerStyle: styles$g.container,
|
|
30782
|
+
panelStyle: styles$g.accordionPanel,
|
|
30783
|
+
header: /*#__PURE__*/React.createElement(View, {
|
|
30784
|
+
style: styles$g.row
|
|
30785
|
+
}, /*#__PURE__*/React.createElement(LabelLarge, null, `Tail (${tail[0]}, ${tail[1]})`))
|
|
30786
|
+
}, /*#__PURE__*/React.createElement(CoordinatePairInput, {
|
|
30787
|
+
coord: tail,
|
|
30788
|
+
error: isInvalid,
|
|
30789
|
+
onChange: newProps => {
|
|
30790
|
+
handleChangePoint(newProps, 0);
|
|
30791
|
+
}
|
|
30792
|
+
})), /*#__PURE__*/React.createElement(LockedFigureSettingsAccordion, {
|
|
30793
|
+
expanded: true // Initial state is expanded
|
|
30794
|
+
,
|
|
30795
|
+
containerStyle: styles$g.container,
|
|
30796
|
+
panelStyle: styles$g.accordionPanel,
|
|
30797
|
+
header: /*#__PURE__*/React.createElement(View, {
|
|
30798
|
+
style: styles$g.row
|
|
30799
|
+
}, /*#__PURE__*/React.createElement(LabelLarge, null, `Tip (${tip[0]}, ${tip[1]})`))
|
|
30800
|
+
}, /*#__PURE__*/React.createElement(CoordinatePairInput, {
|
|
30801
|
+
coord: tip,
|
|
30802
|
+
error: isInvalid,
|
|
30803
|
+
onChange: newProps => {
|
|
30804
|
+
handleChangePoint(newProps, 1);
|
|
30805
|
+
}
|
|
30806
|
+
})), /*#__PURE__*/React.createElement(LockedFigureSettingsActions, {
|
|
30807
|
+
showM2Features: props.showM2Features,
|
|
30808
|
+
figureType: props.type,
|
|
30809
|
+
onMove: onMove,
|
|
30810
|
+
onRemove: onRemove
|
|
30549
30811
|
}));
|
|
30550
30812
|
};
|
|
30551
|
-
const styles$
|
|
30813
|
+
const styles$g = StyleSheet.create({
|
|
30814
|
+
accordionPanel: {
|
|
30815
|
+
paddingBottom: spacing.medium_16
|
|
30816
|
+
},
|
|
30552
30817
|
container: {
|
|
30553
|
-
|
|
30554
|
-
|
|
30555
|
-
|
|
30556
|
-
|
|
30557
|
-
|
|
30558
|
-
height: spacing.large_24,
|
|
30559
|
-
backgroundColor: color.white,
|
|
30560
|
-
alignItems: "center",
|
|
30561
|
-
justifyContent: "center"
|
|
30818
|
+
marginTop: spacing.xSmall_8,
|
|
30819
|
+
marginBottom: 0,
|
|
30820
|
+
marginLeft: -spacing.xxxSmall_4,
|
|
30821
|
+
marginRight: -spacing.xxxSmall_4,
|
|
30822
|
+
backgroundColor: color.white
|
|
30562
30823
|
},
|
|
30563
|
-
|
|
30564
|
-
|
|
30565
|
-
|
|
30566
|
-
|
|
30824
|
+
errorText: {
|
|
30825
|
+
color: color.red,
|
|
30826
|
+
marginTop: spacing.xSmall_8
|
|
30827
|
+
},
|
|
30828
|
+
row: {
|
|
30829
|
+
flexDirection: "row",
|
|
30830
|
+
alignItems: "center"
|
|
30567
30831
|
}
|
|
30568
30832
|
});
|
|
30569
30833
|
|
|
30570
|
-
|
|
30834
|
+
/**
|
|
30835
|
+
* LockedFigureSettings takes in a figure and renders the
|
|
30836
|
+
* respective settings for that figure type.
|
|
30837
|
+
*
|
|
30838
|
+
* Used in the interactive graph editor's locked figures section.
|
|
30839
|
+
*/
|
|
30840
|
+
|
|
30841
|
+
// Union this type with other locked figure types when they are added.
|
|
30842
|
+
|
|
30843
|
+
const LockedFigureSettings = props => {
|
|
30844
|
+
switch (props.type) {
|
|
30845
|
+
case "point":
|
|
30846
|
+
return /*#__PURE__*/React.createElement(LockedPointSettings, props);
|
|
30847
|
+
case "line":
|
|
30848
|
+
return /*#__PURE__*/React.createElement(LockedLineSettings, props);
|
|
30849
|
+
case "vector":
|
|
30850
|
+
if (props.showM2Features) {
|
|
30851
|
+
return /*#__PURE__*/React.createElement(LockedVectorSettings, props);
|
|
30852
|
+
}
|
|
30853
|
+
break;
|
|
30854
|
+
case "ellipse":
|
|
30855
|
+
if (props.showM2Features) {
|
|
30856
|
+
return /*#__PURE__*/React.createElement(LockedEllipseSettings, props);
|
|
30857
|
+
}
|
|
30858
|
+
break;
|
|
30859
|
+
case "polygon":
|
|
30860
|
+
if (props.showM2Features) {
|
|
30861
|
+
return /*#__PURE__*/React.createElement(LockedPolygonSettings, props);
|
|
30862
|
+
}
|
|
30863
|
+
}
|
|
30864
|
+
return null;
|
|
30865
|
+
};
|
|
30866
|
+
|
|
30867
|
+
const LockedFiguresSection = props => {
|
|
30868
|
+
var _props$figures;
|
|
30869
|
+
// Keep track of all figures' accordions' expanded states for the
|
|
30870
|
+
// expand/collapse all button. Set the whole array to false initially.
|
|
30871
|
+
const collapsedStateArray = Array(((_props$figures = props.figures) != null ? _props$figures : []).length).fill(false);
|
|
30872
|
+
const [expandedStates, setExpandedStates] = React.useState(collapsedStateArray);
|
|
30873
|
+
const uniqueId = useUniqueIdWithMock().get("locked-figures-section");
|
|
30571
30874
|
const {
|
|
30572
|
-
|
|
30573
|
-
|
|
30574
|
-
expanded,
|
|
30575
|
-
containerStyle,
|
|
30576
|
-
panelStyle,
|
|
30577
|
-
onToggle
|
|
30875
|
+
figures,
|
|
30876
|
+
onChange
|
|
30578
30877
|
} = props;
|
|
30579
|
-
|
|
30580
|
-
|
|
30581
|
-
|
|
30582
|
-
|
|
30583
|
-
|
|
30584
|
-
|
|
30585
|
-
|
|
30586
|
-
|
|
30587
|
-
|
|
30588
|
-
|
|
30589
|
-
|
|
30590
|
-
|
|
30591
|
-
|
|
30592
|
-
|
|
30593
|
-
|
|
30594
|
-
}
|
|
30595
|
-
const
|
|
30596
|
-
|
|
30597
|
-
|
|
30598
|
-
|
|
30599
|
-
|
|
30600
|
-
|
|
30601
|
-
|
|
30602
|
-
|
|
30603
|
-
|
|
30604
|
-
//
|
|
30605
|
-
//
|
|
30606
|
-
|
|
30607
|
-
|
|
30608
|
-
|
|
30609
|
-
|
|
30610
|
-
|
|
30611
|
-
|
|
30612
|
-
|
|
30878
|
+
function addLockedFigure(newFigure) {
|
|
30879
|
+
const lockedFigures = figures || [];
|
|
30880
|
+
const newProps = {
|
|
30881
|
+
lockedFigures: [...lockedFigures, getDefaultFigureForType(newFigure)]
|
|
30882
|
+
};
|
|
30883
|
+
onChange(newProps);
|
|
30884
|
+
setExpandedStates([...expandedStates, true]);
|
|
30885
|
+
}
|
|
30886
|
+
function moveLockedFigure(index, movement) {
|
|
30887
|
+
// Don't allow moving the first figure up or the last figure down.
|
|
30888
|
+
if (index === 0 && (movement === "back" || movement === "backward")) {
|
|
30889
|
+
return;
|
|
30890
|
+
}
|
|
30891
|
+
if (figures && index === figures.length - 1 && (movement === "front" || movement === "forward")) {
|
|
30892
|
+
return;
|
|
30893
|
+
}
|
|
30894
|
+
const lockedFigures = figures || [];
|
|
30895
|
+
const newFigures = [...lockedFigures];
|
|
30896
|
+
const newExpandedStates = [...expandedStates];
|
|
30897
|
+
|
|
30898
|
+
// First, remove the figure from its current position
|
|
30899
|
+
// in the figures array and the expanded states array.
|
|
30900
|
+
const [removedFigure] = newFigures.splice(index, 1);
|
|
30901
|
+
newExpandedStates.splice(index, 1);
|
|
30902
|
+
|
|
30903
|
+
// Then, add it back in the new position. Add "true" to the
|
|
30904
|
+
// expanded states array for the new position (it must already
|
|
30905
|
+
// be open since the button to move it is being pressed from there).
|
|
30906
|
+
switch (movement) {
|
|
30907
|
+
case "back":
|
|
30908
|
+
newFigures.unshift(removedFigure);
|
|
30909
|
+
newExpandedStates.unshift(true);
|
|
30910
|
+
break;
|
|
30911
|
+
case "backward":
|
|
30912
|
+
newFigures.splice(index - 1, 0, removedFigure);
|
|
30913
|
+
newExpandedStates.splice(index - 1, 0, true);
|
|
30914
|
+
break;
|
|
30915
|
+
case "forward":
|
|
30916
|
+
newFigures.splice(index + 1, 0, removedFigure);
|
|
30917
|
+
newExpandedStates.splice(index + 1, 0, true);
|
|
30918
|
+
break;
|
|
30919
|
+
case "front":
|
|
30920
|
+
newFigures.push(removedFigure);
|
|
30921
|
+
newExpandedStates.push(true);
|
|
30922
|
+
break;
|
|
30923
|
+
}
|
|
30924
|
+
onChange({
|
|
30925
|
+
lockedFigures: newFigures
|
|
30926
|
+
});
|
|
30927
|
+
setExpandedStates(newExpandedStates);
|
|
30928
|
+
}
|
|
30929
|
+
function removeLockedFigure(index) {
|
|
30930
|
+
// eslint-disable-next-line no-alert
|
|
30931
|
+
if (window.confirm("Are you sure you want to delete this figure?")) {
|
|
30932
|
+
const lockedFigures = figures || [];
|
|
30933
|
+
onChange({
|
|
30934
|
+
lockedFigures: [...lockedFigures.slice(0, index), ...lockedFigures.slice(index + 1)]
|
|
30935
|
+
});
|
|
30936
|
+
|
|
30937
|
+
// Update expanded states
|
|
30938
|
+
const newExpandedStates = [...expandedStates];
|
|
30939
|
+
newExpandedStates.splice(index, 1);
|
|
30940
|
+
setExpandedStates(newExpandedStates);
|
|
30941
|
+
}
|
|
30942
|
+
}
|
|
30943
|
+
function changeProps(index,
|
|
30944
|
+
// Omit the type from the figure props so it doesn't think
|
|
30945
|
+
// we're trying to pass in the props for the wrong type.
|
|
30946
|
+
figureProps) {
|
|
30947
|
+
const lockedFigures = figures || [];
|
|
30948
|
+
const newFigures = {
|
|
30949
|
+
lockedFigures: [...lockedFigures.slice(0, index), _extends({}, lockedFigures[index], figureProps), ...lockedFigures.slice(index + 1)]
|
|
30950
|
+
};
|
|
30951
|
+
onChange(newFigures);
|
|
30613
30952
|
}
|
|
30614
|
-
|
|
30615
|
-
|
|
30616
|
-
|
|
30617
|
-
|
|
30618
|
-
|
|
30619
|
-
|
|
30620
|
-
*/
|
|
30621
|
-
|
|
30622
|
-
|
|
30623
|
-
|
|
30624
|
-
|
|
30625
|
-
|
|
30626
|
-
|
|
30627
|
-
|
|
30628
|
-
|
|
30629
|
-
|
|
30630
|
-
|
|
30631
|
-
|
|
30632
|
-
|
|
30633
|
-
|
|
30634
|
-
|
|
30953
|
+
function toggleExpanded(newValue) {
|
|
30954
|
+
setExpandedStates(Array(figures == null ? void 0 : figures.length).fill(newValue));
|
|
30955
|
+
}
|
|
30956
|
+
const allCollapsed = expandedStates.every(value => !value);
|
|
30957
|
+
const buttonLabel = allCollapsed ? "Expand all" : "Collapse all";
|
|
30958
|
+
const showExpandButton = !!(figures != null && figures.length);
|
|
30959
|
+
return /*#__PURE__*/React.createElement(View, null, figures == null ? void 0 : figures.map((figure, index) => {
|
|
30960
|
+
return /*#__PURE__*/React.createElement(LockedFigureSettings, _extends({
|
|
30961
|
+
key: `${uniqueId}-locked-${figure}-${index}`,
|
|
30962
|
+
showM2Features: props.showM2Features,
|
|
30963
|
+
showM2bFeatures: props.showM2bFeatures,
|
|
30964
|
+
expanded: expandedStates[index],
|
|
30965
|
+
onToggle: newValue => {
|
|
30966
|
+
const newExpanded = [...expandedStates];
|
|
30967
|
+
newExpanded[index] = newValue;
|
|
30968
|
+
setExpandedStates(newExpanded);
|
|
30969
|
+
}
|
|
30970
|
+
}, figure, {
|
|
30971
|
+
onChangeProps: newProps => changeProps(index, newProps),
|
|
30972
|
+
onMove: movement => moveLockedFigure(index, movement),
|
|
30973
|
+
onRemove: () => removeLockedFigure(index)
|
|
30974
|
+
}));
|
|
30975
|
+
}), /*#__PURE__*/React.createElement(View, {
|
|
30976
|
+
style: styles$f.buttonContainer
|
|
30977
|
+
}, /*#__PURE__*/React.createElement(LockedFigureSelect, {
|
|
30978
|
+
showM2Features: props.showM2Features,
|
|
30979
|
+
showM2bFeatures: props.showM2bFeatures,
|
|
30980
|
+
id: `${uniqueId}-select`,
|
|
30981
|
+
onChange: addLockedFigure
|
|
30982
|
+
}), /*#__PURE__*/React.createElement(Strut, {
|
|
30983
|
+
size: spacing.small_12
|
|
30984
|
+
}), showExpandButton && /*#__PURE__*/React.createElement(Button, {
|
|
30985
|
+
kind: "secondary",
|
|
30986
|
+
onClick: () => toggleExpanded(allCollapsed),
|
|
30987
|
+
style: styles$f.button
|
|
30988
|
+
}, buttonLabel)));
|
|
30635
30989
|
};
|
|
30636
|
-
const styles$
|
|
30637
|
-
|
|
30638
|
-
width: "100%",
|
|
30990
|
+
const styles$f = StyleSheet.create({
|
|
30991
|
+
buttonContainer: {
|
|
30639
30992
|
flexDirection: "row",
|
|
30640
|
-
alignItems: "center"
|
|
30641
|
-
marginTop: spacing.xxxSmall_4
|
|
30993
|
+
alignItems: "center"
|
|
30642
30994
|
},
|
|
30643
|
-
|
|
30644
|
-
|
|
30645
|
-
|
|
30995
|
+
button: {
|
|
30996
|
+
marginTop: spacing.xSmall_8,
|
|
30997
|
+
flexGrow: 1
|
|
30646
30998
|
}
|
|
30647
30999
|
});
|
|
30648
31000
|
|
|
30649
|
-
const
|
|
30650
|
-
|
|
30651
|
-
|
|
30652
|
-
|
|
30653
|
-
|
|
30654
|
-
|
|
30655
|
-
|
|
30656
|
-
|
|
30657
|
-
color,
|
|
30658
|
-
fillStyle,
|
|
30659
|
-
strokeStyle,
|
|
30660
|
-
expanded,
|
|
30661
|
-
onToggle,
|
|
30662
|
-
onChangeProps,
|
|
30663
|
-
onRemove
|
|
30664
|
-
} = props;
|
|
30665
|
-
function handleColorChange(newValue) {
|
|
30666
|
-
onChangeProps({
|
|
30667
|
-
color: newValue
|
|
30668
|
-
});
|
|
31001
|
+
const UNLIMITED = "unlimited";
|
|
31002
|
+
// Parses a string (ostensibly from some UI element that only supports string
|
|
31003
|
+
// types, such as a <select />) into a numeric point count or the special sigil
|
|
31004
|
+
// "unlimited". Note that 0 is a special case, and means "unlimited".
|
|
31005
|
+
const parsePointCount = points => {
|
|
31006
|
+
const parsed = parseInt(points, 10);
|
|
31007
|
+
if (isNaN(parsed)) {
|
|
31008
|
+
return UNLIMITED;
|
|
30669
31009
|
}
|
|
30670
|
-
return
|
|
30671
|
-
|
|
30672
|
-
|
|
30673
|
-
|
|
30674
|
-
|
|
30675
|
-
|
|
30676
|
-
|
|
30677
|
-
|
|
30678
|
-
|
|
30679
|
-
|
|
30680
|
-
|
|
30681
|
-
|
|
30682
|
-
|
|
30683
|
-
strokeStyle: strokeStyle
|
|
30684
|
-
}))
|
|
30685
|
-
}, /*#__PURE__*/React.createElement(View, {
|
|
30686
|
-
style: styles$j.row
|
|
30687
|
-
}, /*#__PURE__*/React.createElement(CoordinatePairInput, {
|
|
30688
|
-
coord: center,
|
|
30689
|
-
onChange: newCoords => onChangeProps({
|
|
30690
|
-
center: newCoords
|
|
30691
|
-
})
|
|
30692
|
-
}), /*#__PURE__*/React.createElement(View, {
|
|
30693
|
-
style: styles$j.spaceUnder
|
|
30694
|
-
}, /*#__PURE__*/React.createElement(InfoTip$c, null, "The coordinates for the center of the ellipse."))), /*#__PURE__*/React.createElement(CoordinatePairInput, {
|
|
30695
|
-
coord: radius,
|
|
30696
|
-
labels: ["x radius", "y radius"],
|
|
30697
|
-
onChange: newCoords => onChangeProps({
|
|
30698
|
-
radius: newCoords
|
|
30699
|
-
})
|
|
30700
|
-
}), /*#__PURE__*/React.createElement(AngleInput, {
|
|
30701
|
-
angle: angle,
|
|
30702
|
-
onChange: newAngle => onChangeProps({
|
|
30703
|
-
angle: newAngle
|
|
30704
|
-
})
|
|
30705
|
-
}), /*#__PURE__*/React.createElement(Strut, {
|
|
30706
|
-
size: spacing.xSmall_8
|
|
30707
|
-
}), /*#__PURE__*/React.createElement(View, {
|
|
30708
|
-
style: [styles$j.row, styles$j.spaceUnder]
|
|
30709
|
-
}, /*#__PURE__*/React.createElement(ColorSelect, {
|
|
30710
|
-
selectedValue: color,
|
|
30711
|
-
onChange: handleColorChange
|
|
30712
|
-
}), /*#__PURE__*/React.createElement(Strut, {
|
|
30713
|
-
size: spacing.medium_16
|
|
30714
|
-
}), /*#__PURE__*/React.createElement(LabelMedium, {
|
|
30715
|
-
tag: "label",
|
|
30716
|
-
style: styles$j.row
|
|
30717
|
-
}, "fill", /*#__PURE__*/React.createElement(Strut, {
|
|
30718
|
-
size: spacing.xxSmall_6
|
|
30719
|
-
}), /*#__PURE__*/React.createElement(SingleSelect, {
|
|
30720
|
-
selectedValue: fillStyle,
|
|
30721
|
-
onChange: value => onChangeProps({
|
|
30722
|
-
fillStyle: value
|
|
30723
|
-
})
|
|
30724
|
-
// Placeholder is required, but never gets used.
|
|
30725
|
-
,
|
|
30726
|
-
placeholder: ""
|
|
30727
|
-
}, Object.keys(lockedFigureFillStyles).map(option => /*#__PURE__*/React.createElement(OptionItem, {
|
|
30728
|
-
key: option,
|
|
30729
|
-
value: option,
|
|
30730
|
-
label: option
|
|
30731
|
-
}, option))))), /*#__PURE__*/React.createElement(LabelMedium, {
|
|
30732
|
-
tag: "label",
|
|
30733
|
-
style: styles$j.row
|
|
30734
|
-
}, "stroke", /*#__PURE__*/React.createElement(Strut, {
|
|
30735
|
-
size: spacing.xxSmall_6
|
|
30736
|
-
}), /*#__PURE__*/React.createElement(SingleSelect, {
|
|
30737
|
-
selectedValue: strokeStyle,
|
|
30738
|
-
onChange: value => onChangeProps({
|
|
30739
|
-
strokeStyle: value
|
|
30740
|
-
})
|
|
30741
|
-
// Placeholder is required, but never gets used.
|
|
31010
|
+
return parsed === 0 ? UNLIMITED : parsed;
|
|
31011
|
+
};
|
|
31012
|
+
|
|
31013
|
+
const GraphPointsCountSelector = ({
|
|
31014
|
+
numPoints: _numPoints = 1,
|
|
31015
|
+
onChange
|
|
31016
|
+
}) => {
|
|
31017
|
+
return /*#__PURE__*/React.createElement(SingleSelect, {
|
|
31018
|
+
selectedValue: `${_numPoints}`,
|
|
31019
|
+
onChange: newValue => {
|
|
31020
|
+
onChange(parsePointCount(newValue));
|
|
31021
|
+
}
|
|
31022
|
+
// Never uses placeholder, always has value
|
|
30742
31023
|
,
|
|
30743
|
-
placeholder: ""
|
|
30744
|
-
|
|
30745
|
-
|
|
30746
|
-
|
|
30747
|
-
|
|
30748
|
-
|
|
30749
|
-
|
|
30750
|
-
|
|
30751
|
-
|
|
30752
|
-
|
|
30753
|
-
}));
|
|
31024
|
+
placeholder: "",
|
|
31025
|
+
style: styles$e.singleSelectShort
|
|
31026
|
+
}, [...[...Array(7).keys()].map(n => /*#__PURE__*/React.createElement(OptionItem, {
|
|
31027
|
+
key: n,
|
|
31028
|
+
value: `${n}`,
|
|
31029
|
+
label: `${n} point${n > 1 ? "s" : ""}`
|
|
31030
|
+
})), /*#__PURE__*/React.createElement(OptionItem, {
|
|
31031
|
+
key: "unlimited",
|
|
31032
|
+
value: UNLIMITED,
|
|
31033
|
+
label: "unlimited"
|
|
31034
|
+
})]);
|
|
30754
31035
|
};
|
|
30755
|
-
const styles$
|
|
30756
|
-
|
|
30757
|
-
|
|
30758
|
-
|
|
30759
|
-
|
|
30760
|
-
},
|
|
30761
|
-
spaceUnder: {
|
|
30762
|
-
marginBottom: spacing.xSmall_8
|
|
31036
|
+
const styles$e = StyleSheet.create({
|
|
31037
|
+
singleSelectShort: {
|
|
31038
|
+
// Non-standard spacing, but it's the smallest we can go
|
|
31039
|
+
// without running into styling issues with the dropdown.
|
|
31040
|
+
height: 26
|
|
30763
31041
|
}
|
|
30764
31042
|
});
|
|
30765
31043
|
|
|
30766
|
-
const
|
|
30767
|
-
|
|
30768
|
-
|
|
30769
|
-
|
|
30770
|
-
|
|
30771
|
-
|
|
30772
|
-
}
|
|
30773
|
-
|
|
30774
|
-
|
|
30775
|
-
|
|
30776
|
-
|
|
30777
|
-
|
|
30778
|
-
|
|
30779
|
-
|
|
30780
|
-
|
|
30781
|
-
}), /*#__PURE__*/React.createElement(
|
|
30782
|
-
|
|
30783
|
-
|
|
30784
|
-
|
|
30785
|
-
|
|
30786
|
-
|
|
31044
|
+
const GraphTypeSelector = props => {
|
|
31045
|
+
return /*#__PURE__*/React.createElement(SingleSelect, {
|
|
31046
|
+
selectedValue: props.graphType,
|
|
31047
|
+
onChange: props.onChange,
|
|
31048
|
+
placeholder: "Select a graph type",
|
|
31049
|
+
style: styles$d.singleSelectShort
|
|
31050
|
+
}, /*#__PURE__*/React.createElement(OptionItem, {
|
|
31051
|
+
value: "linear",
|
|
31052
|
+
label: "Linear function"
|
|
31053
|
+
}), /*#__PURE__*/React.createElement(OptionItem, {
|
|
31054
|
+
value: "quadratic",
|
|
31055
|
+
label: "Quadratic function"
|
|
31056
|
+
}), /*#__PURE__*/React.createElement(OptionItem, {
|
|
31057
|
+
value: "sinusoid",
|
|
31058
|
+
label: "Sinusoid function"
|
|
31059
|
+
}), /*#__PURE__*/React.createElement(OptionItem, {
|
|
31060
|
+
value: "circle",
|
|
31061
|
+
label: "Circle"
|
|
31062
|
+
}), /*#__PURE__*/React.createElement(OptionItem, {
|
|
31063
|
+
value: "point",
|
|
31064
|
+
label: "Point(s)"
|
|
31065
|
+
}), /*#__PURE__*/React.createElement(OptionItem, {
|
|
31066
|
+
value: "linear-system",
|
|
31067
|
+
label: "Linear System"
|
|
31068
|
+
}), /*#__PURE__*/React.createElement(OptionItem, {
|
|
31069
|
+
value: "polygon",
|
|
31070
|
+
label: "Polygon"
|
|
31071
|
+
}), /*#__PURE__*/React.createElement(OptionItem, {
|
|
31072
|
+
value: "segment",
|
|
31073
|
+
label: "Line Segment(s)"
|
|
31074
|
+
}), /*#__PURE__*/React.createElement(OptionItem, {
|
|
31075
|
+
value: "ray",
|
|
31076
|
+
label: "Ray"
|
|
31077
|
+
}), /*#__PURE__*/React.createElement(OptionItem, {
|
|
31078
|
+
value: "angle",
|
|
31079
|
+
label: "Angle"
|
|
31080
|
+
}));
|
|
30787
31081
|
};
|
|
30788
|
-
const styles$
|
|
30789
|
-
|
|
30790
|
-
|
|
30791
|
-
|
|
31082
|
+
const styles$d = StyleSheet.create({
|
|
31083
|
+
singleSelectShort: {
|
|
31084
|
+
// Non-standard spacing, but it's the smallest we can go
|
|
31085
|
+
// without running into styling issues with the dropdown.
|
|
31086
|
+
height: 26
|
|
30792
31087
|
}
|
|
30793
31088
|
});
|
|
30794
31089
|
|
|
30795
|
-
|
|
30796
|
-
|
|
30797
|
-
|
|
30798
|
-
|
|
30799
|
-
|
|
30800
|
-
|
|
30801
|
-
const
|
|
30802
|
-
|
|
30803
|
-
|
|
30804
|
-
|
|
30805
|
-
|
|
30806
|
-
|
|
30807
|
-
|
|
30808
|
-
|
|
30809
|
-
|
|
30810
|
-
|
|
30811
|
-
|
|
30812
|
-
|
|
30813
|
-
|
|
30814
|
-
|
|
30815
|
-
|
|
31090
|
+
const {
|
|
31091
|
+
ButtonGroup: ButtonGroup$2,
|
|
31092
|
+
InfoTip: InfoTip$c,
|
|
31093
|
+
PropCheckBox: PropCheckBox$7,
|
|
31094
|
+
RangeInput: RangeInput$4
|
|
31095
|
+
} = components;
|
|
31096
|
+
const defaultBackgroundImage$1 = {
|
|
31097
|
+
url: null,
|
|
31098
|
+
width: 0,
|
|
31099
|
+
height: 0
|
|
31100
|
+
};
|
|
31101
|
+
function numSteps(range, step) {
|
|
31102
|
+
return Math.floor((range[1] - range[0]) / step);
|
|
31103
|
+
}
|
|
31104
|
+
function Heading({
|
|
31105
|
+
title,
|
|
31106
|
+
isOpen,
|
|
31107
|
+
onToggle
|
|
31108
|
+
}) {
|
|
31109
|
+
return /*#__PURE__*/React.createElement(View, {
|
|
31110
|
+
style: {
|
|
31111
|
+
flexDirection: "row",
|
|
31112
|
+
justifyContent: "space-between",
|
|
31113
|
+
backgroundColor: color.offBlack8,
|
|
31114
|
+
padding: spacing.xSmall_8,
|
|
31115
|
+
marginTop: spacing.small_12,
|
|
31116
|
+
// NOTE(jeremy): This is the inverse of the @editorPadding CSS
|
|
31117
|
+
// variable found in perseus-editor.less. For now, it must
|
|
31118
|
+
// match otherwise there's a gap from this header to the edge
|
|
31119
|
+
// of the editor borders.
|
|
31120
|
+
marginInline: -10,
|
|
31121
|
+
cursor: "pointer"
|
|
31122
|
+
},
|
|
31123
|
+
onClick: () => onToggle == null ? void 0 : onToggle(!isOpen)
|
|
31124
|
+
}, /*#__PURE__*/React.createElement(LabelSmall, null, title), /*#__PURE__*/React.createElement(ToggleableCaret, {
|
|
31125
|
+
isExpanded: isOpen
|
|
31126
|
+
}));
|
|
31127
|
+
}
|
|
31128
|
+
class InteractiveGraphSettings extends React.Component {
|
|
31129
|
+
static stateFromProps(props) {
|
|
31130
|
+
return {
|
|
31131
|
+
labelsTextbox: props.labels,
|
|
31132
|
+
gridStepTextbox: props.gridStep,
|
|
31133
|
+
snapStepTextbox: props.snapStep,
|
|
31134
|
+
stepTextbox: props.step,
|
|
31135
|
+
rangeTextbox: props.range,
|
|
31136
|
+
// Shallow-copied clone
|
|
31137
|
+
backgroundImage: _extends({}, props.backgroundImage)
|
|
31138
|
+
};
|
|
30816
31139
|
}
|
|
30817
|
-
|
|
30818
|
-
|
|
30819
|
-
|
|
30820
|
-
|
|
30821
|
-
|
|
30822
|
-
|
|
30823
|
-
|
|
30824
|
-
|
|
30825
|
-
|
|
30826
|
-
|
|
30827
|
-
|
|
30828
|
-
|
|
30829
|
-
|
|
30830
|
-
|
|
30831
|
-
filled: filled
|
|
30832
|
-
}))
|
|
30833
|
-
}, /*#__PURE__*/React.createElement(CoordinatePairInput, {
|
|
30834
|
-
coord: coord,
|
|
30835
|
-
error: !!error,
|
|
30836
|
-
onChange: newCoords => {
|
|
30837
|
-
onChangeProps({
|
|
30838
|
-
coord: newCoords
|
|
31140
|
+
constructor(props) {
|
|
31141
|
+
super(props);
|
|
31142
|
+
this._isMounted = false;
|
|
31143
|
+
this.bgUrlRef = /*#__PURE__*/React.createRef();
|
|
31144
|
+
this.labelXRef = /*#__PURE__*/React.createRef();
|
|
31145
|
+
this.labelYRef = /*#__PURE__*/React.createRef();
|
|
31146
|
+
this.change = (...args) => {
|
|
31147
|
+
return Changeable.change.apply(this, args);
|
|
31148
|
+
};
|
|
31149
|
+
// TODO(aria): Make either a wrapper for standard events to work
|
|
31150
|
+
// with this.change, or make these use some TextInput/NumberInput box
|
|
31151
|
+
this.changeRulerLabel = e => {
|
|
31152
|
+
this.change({
|
|
31153
|
+
rulerLabel: e.target.value
|
|
30839
31154
|
});
|
|
30840
|
-
}
|
|
30841
|
-
|
|
30842
|
-
|
|
30843
|
-
|
|
30844
|
-
|
|
30845
|
-
|
|
30846
|
-
|
|
30847
|
-
|
|
30848
|
-
|
|
30849
|
-
|
|
30850
|
-
|
|
30851
|
-
|
|
30852
|
-
|
|
30853
|
-
|
|
30854
|
-
|
|
30855
|
-
|
|
31155
|
+
};
|
|
31156
|
+
this.changeRulerTicks = e => {
|
|
31157
|
+
this.change({
|
|
31158
|
+
rulerTicks: +e.target.value
|
|
31159
|
+
});
|
|
31160
|
+
};
|
|
31161
|
+
this.changeBackgroundUrl = e => {
|
|
31162
|
+
var _this$bgUrlRef$curren;
|
|
31163
|
+
// Only continue on blur or "enter"
|
|
31164
|
+
if (e.type === "keypress" && e.key !== "Enter") {
|
|
31165
|
+
return;
|
|
31166
|
+
}
|
|
31167
|
+
const setUrl = (url, width, height) => {
|
|
31168
|
+
// Shallow-copied clone
|
|
31169
|
+
const image = _extends({}, this.props.backgroundImage);
|
|
31170
|
+
image.url = url;
|
|
31171
|
+
image.width = width;
|
|
31172
|
+
image.height = height;
|
|
31173
|
+
this.setState({
|
|
31174
|
+
backgroundImage: image
|
|
31175
|
+
}, this.changeGraph);
|
|
31176
|
+
};
|
|
31177
|
+
const url = (_this$bgUrlRef$curren = this.bgUrlRef.current) == null ? void 0 : _this$bgUrlRef$curren.value;
|
|
31178
|
+
if (url) {
|
|
31179
|
+
Util.getImageSize(url, (width, height) => {
|
|
31180
|
+
if (this._isMounted) {
|
|
31181
|
+
setUrl(url, width, height);
|
|
31182
|
+
}
|
|
31183
|
+
});
|
|
31184
|
+
} else {
|
|
31185
|
+
setUrl(null, 0, 0);
|
|
31186
|
+
}
|
|
31187
|
+
};
|
|
31188
|
+
this.renderLabelChoices = choices => {
|
|
31189
|
+
return choices.map(nameAndValue => /*#__PURE__*/React.createElement("option", {
|
|
31190
|
+
key: nameAndValue[1],
|
|
31191
|
+
value: nameAndValue[1]
|
|
31192
|
+
}, nameAndValue[0]));
|
|
31193
|
+
};
|
|
31194
|
+
this.validRange = range => {
|
|
31195
|
+
const numbers = _.every(range, function (num) {
|
|
31196
|
+
return _.isFinite(num);
|
|
31197
|
+
});
|
|
31198
|
+
if (!numbers) {
|
|
31199
|
+
return "Range must be a valid number";
|
|
31200
|
+
}
|
|
31201
|
+
if (range[0] >= range[1]) {
|
|
31202
|
+
return "Range must have a higher number on the right";
|
|
31203
|
+
}
|
|
31204
|
+
return true;
|
|
31205
|
+
};
|
|
31206
|
+
this.validateStepValue = settings => {
|
|
31207
|
+
const {
|
|
31208
|
+
step,
|
|
31209
|
+
range,
|
|
31210
|
+
name,
|
|
31211
|
+
minTicks,
|
|
31212
|
+
maxTicks
|
|
31213
|
+
} = settings;
|
|
31214
|
+
const nSteps = numSteps(range, step);
|
|
31215
|
+
if (nSteps < minTicks) {
|
|
31216
|
+
return name + " is too large, there must be at least " + minTicks + " ticks.";
|
|
31217
|
+
}
|
|
31218
|
+
if (nSteps > maxTicks) {
|
|
31219
|
+
return name + " is too small, there can be at most " + maxTicks + " ticks.";
|
|
31220
|
+
}
|
|
31221
|
+
return true;
|
|
31222
|
+
};
|
|
31223
|
+
this.validSnapStep = (step, range) => {
|
|
31224
|
+
return this.validateStepValue({
|
|
31225
|
+
step: step,
|
|
31226
|
+
range: range,
|
|
31227
|
+
name: "Snap step",
|
|
31228
|
+
minTicks: 5,
|
|
31229
|
+
maxTicks: 60
|
|
31230
|
+
});
|
|
31231
|
+
};
|
|
31232
|
+
this.validGridStep = (step, range) => {
|
|
31233
|
+
return this.validateStepValue({
|
|
31234
|
+
step: step,
|
|
31235
|
+
range: range,
|
|
31236
|
+
name: "Grid step",
|
|
31237
|
+
minTicks: 3,
|
|
31238
|
+
maxTicks: 60
|
|
31239
|
+
});
|
|
31240
|
+
};
|
|
31241
|
+
this.validStep = (step, range) => {
|
|
31242
|
+
return this.validateStepValue({
|
|
31243
|
+
step: step,
|
|
31244
|
+
range: range,
|
|
31245
|
+
name: "Step",
|
|
31246
|
+
minTicks: 3,
|
|
31247
|
+
maxTicks: 20
|
|
31248
|
+
});
|
|
31249
|
+
};
|
|
31250
|
+
this.validBackgroundImageSize = image => {
|
|
31251
|
+
// Ignore empty images
|
|
31252
|
+
if (!image.url) {
|
|
31253
|
+
return true;
|
|
31254
|
+
}
|
|
31255
|
+
const validSize = image.width <= 450 && image.height <= 450;
|
|
31256
|
+
if (!validSize) {
|
|
31257
|
+
return "Image must be smaller than 450px x 450px.";
|
|
31258
|
+
}
|
|
31259
|
+
return true;
|
|
31260
|
+
};
|
|
31261
|
+
this.validateGraphSettings = (range, step, gridStep, snapStep, image) => {
|
|
31262
|
+
const self = this;
|
|
31263
|
+
let msg;
|
|
31264
|
+
const goodRange = _.every(range, function (range) {
|
|
31265
|
+
msg = self.validRange(range);
|
|
31266
|
+
return msg === true;
|
|
31267
|
+
});
|
|
31268
|
+
if (!goodRange) {
|
|
31269
|
+
return msg;
|
|
31270
|
+
}
|
|
31271
|
+
const goodStep = _.every(step, function (step, i) {
|
|
31272
|
+
msg = self.validStep(step, range[i]);
|
|
31273
|
+
return msg === true;
|
|
31274
|
+
});
|
|
31275
|
+
if (!goodStep) {
|
|
31276
|
+
return msg;
|
|
31277
|
+
}
|
|
31278
|
+
const goodGridStep = _.every(gridStep, function (gridStep, i) {
|
|
31279
|
+
msg = self.validGridStep(gridStep, range[i]);
|
|
31280
|
+
return msg === true;
|
|
31281
|
+
});
|
|
31282
|
+
if (!goodGridStep) {
|
|
31283
|
+
return msg;
|
|
31284
|
+
}
|
|
31285
|
+
const goodSnapStep = _.every(snapStep, function (snapStep, i) {
|
|
31286
|
+
msg = self.validSnapStep(snapStep, range[i]);
|
|
31287
|
+
return msg === true;
|
|
30856
31288
|
});
|
|
30857
|
-
|
|
30858
|
-
|
|
30859
|
-
}
|
|
30860
|
-
const
|
|
30861
|
-
|
|
30862
|
-
|
|
30863
|
-
|
|
30864
|
-
|
|
30865
|
-
|
|
30866
|
-
|
|
30867
|
-
|
|
30868
|
-
|
|
30869
|
-
|
|
30870
|
-
|
|
30871
|
-
|
|
30872
|
-
|
|
30873
|
-
|
|
30874
|
-
|
|
30875
|
-
|
|
30876
|
-
|
|
30877
|
-
|
|
30878
|
-
|
|
30879
|
-
|
|
30880
|
-
|
|
30881
|
-
const
|
|
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
|
-
|
|
30909
|
-
|
|
30910
|
-
|
|
30911
|
-
|
|
30912
|
-
|
|
30913
|
-
|
|
30914
|
-
|
|
30915
|
-
|
|
30916
|
-
|
|
30917
|
-
|
|
30918
|
-
|
|
30919
|
-
|
|
30920
|
-
|
|
30921
|
-
|
|
30922
|
-
|
|
31289
|
+
if (!goodSnapStep) {
|
|
31290
|
+
return msg;
|
|
31291
|
+
}
|
|
31292
|
+
const goodImageSize = this.validBackgroundImageSize(image);
|
|
31293
|
+
if (goodImageSize !== true) {
|
|
31294
|
+
msg = goodImageSize;
|
|
31295
|
+
return msg;
|
|
31296
|
+
}
|
|
31297
|
+
return true;
|
|
31298
|
+
};
|
|
31299
|
+
this.changeLabel = (i, e) => {
|
|
31300
|
+
const val = e.target.value;
|
|
31301
|
+
const labels = this.state.labelsTextbox.slice();
|
|
31302
|
+
labels[i] = val;
|
|
31303
|
+
this.setState({
|
|
31304
|
+
labelsTextbox: labels
|
|
31305
|
+
}, this.changeGraph);
|
|
31306
|
+
};
|
|
31307
|
+
this.changeRange = (i, values) => {
|
|
31308
|
+
const ranges = this.state.rangeTextbox.slice();
|
|
31309
|
+
ranges[i] = values;
|
|
31310
|
+
const step = this.state.stepTextbox.slice();
|
|
31311
|
+
const gridStep = this.state.gridStepTextbox.slice();
|
|
31312
|
+
const snapStep = this.state.snapStepTextbox.slice();
|
|
31313
|
+
const scale = Util.scaleFromExtent(ranges[i], this.props.box[i]);
|
|
31314
|
+
if (this.validRange(ranges[i]) === true) {
|
|
31315
|
+
step[i] = Util.tickStepFromExtent(ranges[i], this.props.box[i]);
|
|
31316
|
+
const gridStepValue = Util.gridStepFromTickStep(step[i], scale);
|
|
31317
|
+
if (gridStepValue) {
|
|
31318
|
+
gridStep[i] = gridStepValue;
|
|
31319
|
+
}
|
|
31320
|
+
snapStep[i] = gridStep[i] / 2;
|
|
31321
|
+
}
|
|
31322
|
+
this.setState({
|
|
31323
|
+
stepTextbox: step,
|
|
31324
|
+
gridStepTextbox: gridStep,
|
|
31325
|
+
snapStepTextbox: snapStep,
|
|
31326
|
+
rangeTextbox: ranges
|
|
31327
|
+
}, this.changeGraph);
|
|
31328
|
+
};
|
|
31329
|
+
this.changeStep = step => {
|
|
31330
|
+
this.setState({
|
|
31331
|
+
stepTextbox: step
|
|
31332
|
+
}, this.changeGraph);
|
|
31333
|
+
};
|
|
31334
|
+
this.changeSnapStep = snapStep => {
|
|
31335
|
+
this.setState({
|
|
31336
|
+
snapStepTextbox: snapStep
|
|
31337
|
+
}, this.changeGraph);
|
|
31338
|
+
};
|
|
31339
|
+
this.changeGridStep = gridStep => {
|
|
31340
|
+
this.setState({
|
|
31341
|
+
gridStepTextbox: gridStep,
|
|
31342
|
+
snapStepTextbox: _.map(gridStep, function (step) {
|
|
31343
|
+
return step / 2;
|
|
31344
|
+
})
|
|
31345
|
+
}, this.changeGraph);
|
|
31346
|
+
};
|
|
31347
|
+
this.changeGraph = () => {
|
|
31348
|
+
const labels = this.state.labelsTextbox;
|
|
31349
|
+
const range = _.map(this.state.rangeTextbox, function (range) {
|
|
31350
|
+
return _.map(range, Number);
|
|
31351
|
+
});
|
|
31352
|
+
const step = _.map(this.state.stepTextbox, Number);
|
|
31353
|
+
const gridStep = this.state.gridStepTextbox;
|
|
31354
|
+
const snapStep = this.state.snapStepTextbox;
|
|
31355
|
+
const image = this.state.backgroundImage;
|
|
30923
31356
|
|
|
30924
|
-
|
|
30925
|
-
|
|
30926
|
-
|
|
30927
|
-
|
|
30928
|
-
|
|
30929
|
-
|
|
30930
|
-
|
|
30931
|
-
|
|
30932
|
-
|
|
30933
|
-
|
|
30934
|
-
|
|
30935
|
-
|
|
30936
|
-
|
|
30937
|
-
|
|
30938
|
-
|
|
30939
|
-
|
|
30940
|
-
|
|
30941
|
-
}
|
|
30942
|
-
|
|
30943
|
-
|
|
30944
|
-
|
|
30945
|
-
|
|
30946
|
-
|
|
30947
|
-
|
|
30948
|
-
|
|
30949
|
-
},
|
|
30950
|
-
size: spacing.xSmall_8
|
|
30951
|
-
}), /*#__PURE__*/React.createElement(LineSwatch, {
|
|
30952
|
-
color: lineColor,
|
|
30953
|
-
lineStyle: lineStyle
|
|
30954
|
-
}))
|
|
30955
|
-
}, /*#__PURE__*/React.createElement(LabelMedium, {
|
|
30956
|
-
tag: "label",
|
|
30957
|
-
style: [styles$f.row, styles$f.spaceUnder]
|
|
30958
|
-
}, "kind", /*#__PURE__*/React.createElement(Strut, {
|
|
30959
|
-
size: spacing.xxxSmall_4
|
|
30960
|
-
}), /*#__PURE__*/React.createElement(SingleSelect, {
|
|
30961
|
-
selectedValue: kind,
|
|
30962
|
-
onChange: value => onChangeProps({
|
|
30963
|
-
kind: value
|
|
30964
|
-
})
|
|
30965
|
-
// Placeholder is required, but never gets used.
|
|
30966
|
-
,
|
|
30967
|
-
placeholder: ""
|
|
30968
|
-
}, /*#__PURE__*/React.createElement(OptionItem, {
|
|
30969
|
-
value: "line",
|
|
30970
|
-
label: "line"
|
|
30971
|
-
}), /*#__PURE__*/React.createElement(OptionItem, {
|
|
30972
|
-
value: "ray",
|
|
30973
|
-
label: "ray"
|
|
30974
|
-
}), /*#__PURE__*/React.createElement(OptionItem, {
|
|
30975
|
-
value: "segment",
|
|
30976
|
-
label: "segment"
|
|
30977
|
-
}))), /*#__PURE__*/React.createElement(View, {
|
|
30978
|
-
style: styles$f.row
|
|
30979
|
-
}, /*#__PURE__*/React.createElement(ColorSelect, {
|
|
30980
|
-
selectedValue: lineColor,
|
|
30981
|
-
onChange: handleColorChange
|
|
30982
|
-
}), /*#__PURE__*/React.createElement(Strut, {
|
|
30983
|
-
size: spacing.small_12
|
|
30984
|
-
}), /*#__PURE__*/React.createElement(LabelMedium, {
|
|
30985
|
-
tag: "label",
|
|
30986
|
-
style: styles$f.row
|
|
30987
|
-
}, "style", /*#__PURE__*/React.createElement(Strut, {
|
|
30988
|
-
size: spacing.xxxSmall_4
|
|
30989
|
-
}), /*#__PURE__*/React.createElement(SingleSelect, {
|
|
30990
|
-
selectedValue: lineStyle,
|
|
30991
|
-
onChange: value => onChangeProps({
|
|
30992
|
-
lineStyle: value
|
|
30993
|
-
})
|
|
30994
|
-
// Placeholder is required, but never gets used.
|
|
30995
|
-
,
|
|
30996
|
-
placeholder: "",
|
|
30997
|
-
style: styles$f.selectMarginOffset
|
|
30998
|
-
}, /*#__PURE__*/React.createElement(OptionItem, {
|
|
30999
|
-
value: "solid",
|
|
31000
|
-
label: "solid"
|
|
31001
|
-
}), /*#__PURE__*/React.createElement(OptionItem, {
|
|
31002
|
-
value: "dashed",
|
|
31003
|
-
label: "dashed"
|
|
31004
|
-
})))), isInvalid && /*#__PURE__*/React.createElement(LabelMedium, {
|
|
31005
|
-
style: styles$f.errorText
|
|
31006
|
-
}, lengthZeroStr), /*#__PURE__*/React.createElement(DefiningPointSettings, _extends({
|
|
31007
|
-
label: "Point 1",
|
|
31008
|
-
showPoint: showPoint1,
|
|
31009
|
-
error: isInvalid ? lengthZeroStr : null
|
|
31010
|
-
}, point1, {
|
|
31011
|
-
onTogglePoint: newValue => onChangeProps({
|
|
31012
|
-
showPoint1: newValue
|
|
31013
|
-
}),
|
|
31014
|
-
onChangeProps: newProps => handleChangePoint(newProps, 0)
|
|
31015
|
-
})), /*#__PURE__*/React.createElement(DefiningPointSettings, _extends({
|
|
31016
|
-
label: "Point 2",
|
|
31017
|
-
showPoint: showPoint2,
|
|
31018
|
-
error: isInvalid ? lengthZeroStr : null
|
|
31019
|
-
}, point2, {
|
|
31020
|
-
onTogglePoint: newValue => onChangeProps({
|
|
31021
|
-
showPoint2: newValue
|
|
31022
|
-
}),
|
|
31023
|
-
onChangeProps: newProps => handleChangePoint(newProps, 1)
|
|
31024
|
-
})), /*#__PURE__*/React.createElement(LockedFigureSettingsActions, {
|
|
31025
|
-
onRemove: onRemove,
|
|
31026
|
-
figureAriaLabel: `locked line defined by
|
|
31027
|
-
${point1.coord[0]}, ${point1.coord[1]} and
|
|
31028
|
-
${point2.coord[0]}, ${point2.coord[1]}.`
|
|
31029
|
-
}));
|
|
31030
|
-
};
|
|
31031
|
-
const styles$f = StyleSheet.create({
|
|
31032
|
-
row: {
|
|
31033
|
-
display: "flex",
|
|
31034
|
-
flexDirection: "row",
|
|
31035
|
-
alignItems: "center"
|
|
31036
|
-
},
|
|
31037
|
-
spaceUnder: {
|
|
31038
|
-
marginBottom: spacing.xSmall_8
|
|
31039
|
-
},
|
|
31040
|
-
selectMarginOffset: {
|
|
31041
|
-
// Align with the point settings accordions.
|
|
31042
|
-
marginInlineEnd: -spacing.xxxSmall_4
|
|
31043
|
-
},
|
|
31044
|
-
errorText: {
|
|
31045
|
-
color: color.red
|
|
31357
|
+
// validationResult is either:
|
|
31358
|
+
// true -> the settings are valid
|
|
31359
|
+
// a string -> the settings are invalid, and the explanation
|
|
31360
|
+
// is contained in the string
|
|
31361
|
+
// TODO(aria): Refactor this to not be confusing
|
|
31362
|
+
const validationResult = this.validateGraphSettings(range, step, gridStep, snapStep, image);
|
|
31363
|
+
if (validationResult === true) {
|
|
31364
|
+
// either true or a string
|
|
31365
|
+
this.change({
|
|
31366
|
+
valid: true,
|
|
31367
|
+
labels: labels,
|
|
31368
|
+
range: range,
|
|
31369
|
+
step: step,
|
|
31370
|
+
gridStep: gridStep,
|
|
31371
|
+
snapStep: snapStep,
|
|
31372
|
+
backgroundImage: image
|
|
31373
|
+
});
|
|
31374
|
+
} else {
|
|
31375
|
+
this.change({
|
|
31376
|
+
valid: validationResult // a string message, not false
|
|
31377
|
+
});
|
|
31378
|
+
}
|
|
31379
|
+
};
|
|
31380
|
+
this.state = _extends({
|
|
31381
|
+
isExpanded: true
|
|
31382
|
+
}, InteractiveGraphSettings.stateFromProps(props));
|
|
31046
31383
|
}
|
|
31047
|
-
|
|
31048
|
-
|
|
31049
|
-
|
|
31050
|
-
|
|
31051
|
-
|
|
31052
|
-
*
|
|
31053
|
-
* Used in the interactive graph editor's locked figures section.
|
|
31054
|
-
*/
|
|
31055
|
-
const LockedPointSettings = props => {
|
|
31056
|
-
const {
|
|
31057
|
-
coord,
|
|
31058
|
-
color: pointColor,
|
|
31059
|
-
filled = true,
|
|
31060
|
-
onChangeProps,
|
|
31061
|
-
onRemove
|
|
31062
|
-
} = props;
|
|
31063
|
-
function handleColorChange(newValue) {
|
|
31064
|
-
onChangeProps({
|
|
31065
|
-
color: newValue
|
|
31066
|
-
});
|
|
31384
|
+
componentDidMount() {
|
|
31385
|
+
// TODO(scottgrant): This is a hack to remove the deprecated call to
|
|
31386
|
+
// this.isMounted() but is still considered an anti-pattern.
|
|
31387
|
+
this._isMounted = true;
|
|
31388
|
+
this.changeGraph = _.debounce(this.changeGraph, 300);
|
|
31067
31389
|
}
|
|
31068
|
-
|
|
31069
|
-
|
|
31070
|
-
|
|
31071
|
-
|
|
31072
|
-
|
|
31073
|
-
// Summary: Point, coords, color (filled/open)
|
|
31074
|
-
React.createElement(View, {
|
|
31075
|
-
style: styles$e.row
|
|
31076
|
-
}, /*#__PURE__*/React.createElement(LabelLarge, null, `Point (${coord[0]}, ${coord[1]})`), /*#__PURE__*/React.createElement(Strut, {
|
|
31077
|
-
size: spacing.xSmall_8
|
|
31078
|
-
}), /*#__PURE__*/React.createElement(ColorSwatch, {
|
|
31079
|
-
color: pointColor,
|
|
31080
|
-
filled: filled
|
|
31081
|
-
}))
|
|
31082
|
-
}, /*#__PURE__*/React.createElement(CoordinatePairInput, {
|
|
31083
|
-
coord: coord,
|
|
31084
|
-
onChange: newCoord => {
|
|
31085
|
-
onChangeProps({
|
|
31086
|
-
coord: newCoord
|
|
31087
|
-
});
|
|
31088
|
-
}
|
|
31089
|
-
}), /*#__PURE__*/React.createElement(ColorSelect, {
|
|
31090
|
-
selectedValue: pointColor,
|
|
31091
|
-
onChange: handleColorChange,
|
|
31092
|
-
style: styles$e.spaceUnder
|
|
31093
|
-
}), /*#__PURE__*/React.createElement(LabeledSwitch, {
|
|
31094
|
-
label: "open point",
|
|
31095
|
-
checked: !filled,
|
|
31096
|
-
onChange: newValue => {
|
|
31097
|
-
onChangeProps({
|
|
31098
|
-
filled: !newValue
|
|
31099
|
-
});
|
|
31390
|
+
UNSAFE_componentWillReceiveProps(nextProps) {
|
|
31391
|
+
// Make sure that state updates when switching
|
|
31392
|
+
// between different items in a multi-item editor.
|
|
31393
|
+
if (!_.isEqual(this.props.labels, nextProps.labels) || !_.isEqual(this.props.gridStep, nextProps.gridStep) || !_.isEqual(this.props.snapStep, nextProps.snapStep) || !_.isEqual(this.props.step, nextProps.step) || !_.isEqual(this.props.range, nextProps.range) || !_.isEqual(this.props.backgroundImage, nextProps.backgroundImage)) {
|
|
31394
|
+
this.setState(InteractiveGraphSettings.stateFromProps(nextProps));
|
|
31100
31395
|
}
|
|
31101
|
-
}), /*#__PURE__*/React.createElement(LockedFigureSettingsActions, {
|
|
31102
|
-
onRemove: onRemove,
|
|
31103
|
-
figureAriaLabel: `locked point at ${coord[0]}, ${coord[1]}`
|
|
31104
|
-
}));
|
|
31105
|
-
};
|
|
31106
|
-
const styles$e = StyleSheet.create({
|
|
31107
|
-
row: {
|
|
31108
|
-
flexDirection: "row",
|
|
31109
|
-
alignItems: "center"
|
|
31110
|
-
},
|
|
31111
|
-
spaceUnder: {
|
|
31112
|
-
marginBottom: spacing.xSmall_8
|
|
31113
31396
|
}
|
|
31114
|
-
|
|
31115
|
-
|
|
31116
|
-
/**
|
|
31117
|
-
* LockedVectorSettings is a component that allows the user to edit the
|
|
31118
|
-
* settings of specifically a locked vector on the graph.
|
|
31119
|
-
*
|
|
31120
|
-
* Used in the interactive graph editor's locked figures section.
|
|
31121
|
-
*/
|
|
31122
|
-
const lengthErrorMessage = "The vector cannot have length 0.";
|
|
31123
|
-
const LockedVectorSettings = props => {
|
|
31124
|
-
const {
|
|
31125
|
-
points,
|
|
31126
|
-
color: lineColor,
|
|
31127
|
-
onChangeProps,
|
|
31128
|
-
onRemove
|
|
31129
|
-
} = props;
|
|
31130
|
-
const [tail, tip] = points;
|
|
31131
|
-
const lineLabel = `Vector (${tail[0]}, ${tail[1]}), (${tip[0]}, ${tip[1]})`;
|
|
31132
|
-
|
|
31133
|
-
// Check if the line has length 0.
|
|
31134
|
-
const isInvalid = vector.equal(tail, tip);
|
|
31135
|
-
function handleChangePoint(newCoord, index) {
|
|
31136
|
-
if (typeof newCoord !== "undefined") {
|
|
31137
|
-
const newPoints = [...points];
|
|
31138
|
-
newPoints[index] = [...newCoord];
|
|
31139
|
-
onChangeProps({
|
|
31140
|
-
points: newPoints
|
|
31141
|
-
});
|
|
31142
|
-
}
|
|
31397
|
+
componentWillUnmount() {
|
|
31398
|
+
this._isMounted = false;
|
|
31143
31399
|
}
|
|
31144
|
-
|
|
31145
|
-
|
|
31146
|
-
|
|
31147
|
-
|
|
31400
|
+
render() {
|
|
31401
|
+
return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(Heading, {
|
|
31402
|
+
title: "Common Graph Settings",
|
|
31403
|
+
isOpen: this.state.isExpanded,
|
|
31404
|
+
onToggle: () => this.setState({
|
|
31405
|
+
isExpanded: !this.state.isExpanded
|
|
31406
|
+
})
|
|
31407
|
+
}), this.state.isExpanded && /*#__PURE__*/React.createElement(View, null, /*#__PURE__*/React.createElement("div", {
|
|
31408
|
+
className: "graph-settings"
|
|
31409
|
+
}, /*#__PURE__*/React.createElement("div", {
|
|
31410
|
+
className: "perseus-widget-row"
|
|
31411
|
+
}, /*#__PURE__*/React.createElement("div", {
|
|
31412
|
+
className: "perseus-widget-left-col"
|
|
31413
|
+
}, /*#__PURE__*/React.createElement(LabeledRow, {
|
|
31414
|
+
label: "x Label"
|
|
31415
|
+
}, /*#__PURE__*/React.createElement("input", {
|
|
31416
|
+
type: "text",
|
|
31417
|
+
className: "graph-settings-axis-label",
|
|
31418
|
+
ref: this.labelXRef,
|
|
31419
|
+
onChange: e => this.changeLabel(0, e),
|
|
31420
|
+
value: this.state.labelsTextbox[0] || ""
|
|
31421
|
+
}))), /*#__PURE__*/React.createElement("div", {
|
|
31422
|
+
className: "perseus-widget-right-col"
|
|
31423
|
+
}, /*#__PURE__*/React.createElement(LabeledRow, {
|
|
31424
|
+
label: "y Label"
|
|
31425
|
+
}, /*#__PURE__*/React.createElement("input", {
|
|
31426
|
+
type: "text",
|
|
31427
|
+
className: "graph-settings-axis-label",
|
|
31428
|
+
ref: this.labelYRef,
|
|
31429
|
+
onChange: e => this.changeLabel(1, e),
|
|
31430
|
+
value: this.state.labelsTextbox[1] || ""
|
|
31431
|
+
})))), /*#__PURE__*/React.createElement("div", {
|
|
31432
|
+
className: "perseus-widget-row"
|
|
31433
|
+
}, /*#__PURE__*/React.createElement("div", {
|
|
31434
|
+
className: "perseus-widget-left-col"
|
|
31435
|
+
}, /*#__PURE__*/React.createElement(LabeledRow, {
|
|
31436
|
+
label: "x Range"
|
|
31437
|
+
}, /*#__PURE__*/React.createElement(RangeInput$4, {
|
|
31438
|
+
value: this.state.rangeTextbox[0],
|
|
31439
|
+
onChange: vals => this.changeRange(0, vals)
|
|
31440
|
+
}))), /*#__PURE__*/React.createElement("div", {
|
|
31441
|
+
className: "perseus-widget-right-col"
|
|
31442
|
+
}, /*#__PURE__*/React.createElement(LabeledRow, {
|
|
31443
|
+
label: "y Range"
|
|
31444
|
+
}, /*#__PURE__*/React.createElement(RangeInput$4, {
|
|
31445
|
+
value: this.state.rangeTextbox[1],
|
|
31446
|
+
onChange: vals => this.changeRange(1, vals)
|
|
31447
|
+
})))), /*#__PURE__*/React.createElement("div", {
|
|
31448
|
+
className: "perseus-widget-row"
|
|
31449
|
+
}, /*#__PURE__*/React.createElement("div", {
|
|
31450
|
+
className: "perseus-widget-left-col"
|
|
31451
|
+
}, /*#__PURE__*/React.createElement(LabeledRow, {
|
|
31452
|
+
label: "Tick Step"
|
|
31453
|
+
}, /*#__PURE__*/React.createElement(RangeInput$4, {
|
|
31454
|
+
value: this.state.stepTextbox,
|
|
31455
|
+
onChange: this.changeStep
|
|
31456
|
+
}))), /*#__PURE__*/React.createElement("div", {
|
|
31457
|
+
className: "perseus-widget-right-col"
|
|
31458
|
+
}, /*#__PURE__*/React.createElement(LabeledRow, {
|
|
31459
|
+
label: "Grid Step"
|
|
31460
|
+
}, /*#__PURE__*/React.createElement(RangeInput$4, {
|
|
31461
|
+
value: this.state.gridStepTextbox,
|
|
31462
|
+
onChange: this.changeGridStep
|
|
31463
|
+
})))), /*#__PURE__*/React.createElement("div", {
|
|
31464
|
+
className: "perseus-widget-row"
|
|
31465
|
+
}, /*#__PURE__*/React.createElement("div", {
|
|
31466
|
+
className: "perseus-widget-left-col"
|
|
31467
|
+
}, /*#__PURE__*/React.createElement(LabeledRow, {
|
|
31468
|
+
label: "Snap Step"
|
|
31469
|
+
}, /*#__PURE__*/React.createElement(RangeInput$4, {
|
|
31470
|
+
value: this.state.snapStepTextbox,
|
|
31471
|
+
onChange: this.changeSnapStep
|
|
31472
|
+
})))), /*#__PURE__*/React.createElement("div", {
|
|
31473
|
+
className: "perseus-widget-row"
|
|
31474
|
+
}, /*#__PURE__*/React.createElement(LabeledRow, {
|
|
31475
|
+
label: "Markings:"
|
|
31476
|
+
}, /*#__PURE__*/React.createElement(ButtonGroup$2, {
|
|
31477
|
+
value: this.props.markings,
|
|
31478
|
+
allowEmpty: false,
|
|
31479
|
+
buttons: [{
|
|
31480
|
+
value: "graph",
|
|
31481
|
+
content: "Graph"
|
|
31482
|
+
}, {
|
|
31483
|
+
value: "grid",
|
|
31484
|
+
content: "Grid"
|
|
31485
|
+
}, {
|
|
31486
|
+
value: "none",
|
|
31487
|
+
content: "None"
|
|
31488
|
+
}],
|
|
31489
|
+
onChange: this.change("markings")
|
|
31490
|
+
}))), /*#__PURE__*/React.createElement("div", {
|
|
31491
|
+
className: "perseus-widget-left-col"
|
|
31492
|
+
}, /*#__PURE__*/React.createElement(PropCheckBox$7, {
|
|
31493
|
+
label: "Show tooltips",
|
|
31494
|
+
showTooltips: this.props.showTooltips,
|
|
31495
|
+
onChange: this.change
|
|
31496
|
+
}))), /*#__PURE__*/React.createElement(LabeledRow, {
|
|
31497
|
+
label: "Background image URL:",
|
|
31498
|
+
style: styles$c.resetSpaceTop
|
|
31499
|
+
}, /*#__PURE__*/React.createElement("input", {
|
|
31500
|
+
type: "text",
|
|
31501
|
+
className: css(styles$c.backgroundUrlInput),
|
|
31502
|
+
ref: this.bgUrlRef,
|
|
31503
|
+
value: this.state.backgroundImage.url || "",
|
|
31504
|
+
onChange: e => {
|
|
31505
|
+
// Shallow-copied clone
|
|
31506
|
+
const image = _extends({}, this.props.backgroundImage);
|
|
31507
|
+
image.url = e.target.value;
|
|
31508
|
+
this.setState({
|
|
31509
|
+
backgroundImage: image
|
|
31510
|
+
});
|
|
31511
|
+
},
|
|
31512
|
+
onKeyPress: this.changeBackgroundUrl,
|
|
31513
|
+
onBlur: this.changeBackgroundUrl
|
|
31514
|
+
}), /*#__PURE__*/React.createElement(InfoTip$c, null, /*#__PURE__*/React.createElement("p", null, "Create an image in graphie, or use the \"Add image\" function to create a background."))), /*#__PURE__*/React.createElement(View, {
|
|
31515
|
+
style: styles$c.rulerSection
|
|
31516
|
+
}, /*#__PURE__*/React.createElement(View, {
|
|
31517
|
+
style: styles$c.checkboxRow
|
|
31518
|
+
}, /*#__PURE__*/React.createElement(PropCheckBox$7, {
|
|
31519
|
+
label: "Show ruler",
|
|
31520
|
+
showRuler: this.props.showRuler,
|
|
31521
|
+
onChange: this.change,
|
|
31522
|
+
style: styles$c.resetSpaceTop
|
|
31523
|
+
}), /*#__PURE__*/React.createElement(PropCheckBox$7, {
|
|
31524
|
+
label: "Show protractor",
|
|
31525
|
+
showProtractor: this.props.showProtractor,
|
|
31526
|
+
onChange: this.change,
|
|
31527
|
+
style: styles$c.resetSpaceTop
|
|
31528
|
+
})), (this.props.showRuler || this.props.showProtractor) && /*#__PURE__*/React.createElement(Banner, {
|
|
31529
|
+
layout: "floating",
|
|
31530
|
+
text: "The ruler and protractor are not accessible. Please consider an alternate approach.",
|
|
31531
|
+
kind: "warning"
|
|
31532
|
+
}), this.props.showRuler && /*#__PURE__*/React.createElement(View, {
|
|
31533
|
+
style: styles$c.spaceTop
|
|
31534
|
+
}, /*#__PURE__*/React.createElement(LabeledRow, {
|
|
31535
|
+
label: "Ruler label:",
|
|
31536
|
+
style: styles$c.resetSpaceTop
|
|
31537
|
+
}, /*#__PURE__*/React.createElement(SingleSelect, {
|
|
31538
|
+
id: "ruler-label-select",
|
|
31539
|
+
selectedValue: this.props.rulerLabel,
|
|
31540
|
+
onChange: newValue => {
|
|
31541
|
+
this.change({
|
|
31542
|
+
rulerLabel: newValue
|
|
31543
|
+
});
|
|
31544
|
+
},
|
|
31545
|
+
placeholder: "None",
|
|
31546
|
+
style: styles$c.singleSelectShort
|
|
31547
|
+
}, /*#__PURE__*/React.createElement(OptionItem, {
|
|
31548
|
+
value: "",
|
|
31549
|
+
label: "None",
|
|
31550
|
+
horizontalRule: "full-width"
|
|
31551
|
+
}), /*#__PURE__*/React.createElement(OptionItem, {
|
|
31552
|
+
value: "mm",
|
|
31553
|
+
label: "Milimeters"
|
|
31554
|
+
}), /*#__PURE__*/React.createElement(OptionItem, {
|
|
31555
|
+
value: "cm",
|
|
31556
|
+
label: "Centimeters"
|
|
31557
|
+
}), /*#__PURE__*/React.createElement(OptionItem, {
|
|
31558
|
+
value: "m",
|
|
31559
|
+
label: "Meters"
|
|
31560
|
+
}), /*#__PURE__*/React.createElement(OptionItem, {
|
|
31561
|
+
value: "km",
|
|
31562
|
+
label: "Kilometers",
|
|
31563
|
+
horizontalRule: "full-width"
|
|
31564
|
+
}), /*#__PURE__*/React.createElement(OptionItem, {
|
|
31565
|
+
value: "in",
|
|
31566
|
+
label: "Inches"
|
|
31567
|
+
}), /*#__PURE__*/React.createElement(OptionItem, {
|
|
31568
|
+
value: "ft",
|
|
31569
|
+
label: "Feet"
|
|
31570
|
+
}), /*#__PURE__*/React.createElement(OptionItem, {
|
|
31571
|
+
value: "yd",
|
|
31572
|
+
label: "Yards"
|
|
31573
|
+
}), /*#__PURE__*/React.createElement(OptionItem, {
|
|
31574
|
+
value: "mi",
|
|
31575
|
+
label: "Miles"
|
|
31576
|
+
}))), /*#__PURE__*/React.createElement(LabeledRow, {
|
|
31577
|
+
label: "Ruler ticks:"
|
|
31578
|
+
}, /*#__PURE__*/React.createElement(SingleSelect, {
|
|
31579
|
+
id: "ruler-ticks-select",
|
|
31580
|
+
selectedValue: `${this.props.rulerTicks}`,
|
|
31581
|
+
onChange: newValue => {
|
|
31582
|
+
this.change({
|
|
31583
|
+
rulerTicks: newValue
|
|
31584
|
+
});
|
|
31585
|
+
},
|
|
31586
|
+
placeholder: "10",
|
|
31587
|
+
style: styles$c.singleSelectShort
|
|
31588
|
+
}, [1, 2, 4, 8, 10, 16].map(value => /*#__PURE__*/React.createElement(OptionItem, {
|
|
31589
|
+
key: value,
|
|
31590
|
+
value: `${value}`,
|
|
31591
|
+
label: `${value}`
|
|
31592
|
+
}))))))));
|
|
31148
31593
|
}
|
|
31149
|
-
|
|
31150
|
-
|
|
31151
|
-
|
|
31152
|
-
|
|
31153
|
-
|
|
31154
|
-
|
|
31155
|
-
|
|
31156
|
-
|
|
31157
|
-
|
|
31158
|
-
|
|
31159
|
-
|
|
31160
|
-
|
|
31161
|
-
|
|
31162
|
-
|
|
31163
|
-
|
|
31164
|
-
|
|
31165
|
-
})), isInvalid && /*#__PURE__*/React.createElement(LabelMedium, {
|
|
31166
|
-
style: styles$d.errorText
|
|
31167
|
-
}, lengthErrorMessage), /*#__PURE__*/React.createElement(LockedFigureSettingsAccordion, {
|
|
31168
|
-
expanded: true // Initial state is expanded
|
|
31169
|
-
,
|
|
31170
|
-
containerStyle: styles$d.container,
|
|
31171
|
-
panelStyle: styles$d.accordionPanel,
|
|
31172
|
-
header: /*#__PURE__*/React.createElement(View, {
|
|
31173
|
-
style: styles$d.row
|
|
31174
|
-
}, /*#__PURE__*/React.createElement(LabelLarge, null, `Tail (${tail[0]}, ${tail[1]})`))
|
|
31175
|
-
}, /*#__PURE__*/React.createElement(CoordinatePairInput, {
|
|
31176
|
-
coord: tail,
|
|
31177
|
-
error: isInvalid,
|
|
31178
|
-
onChange: newProps => {
|
|
31179
|
-
handleChangePoint(newProps, 0);
|
|
31180
|
-
}
|
|
31181
|
-
})), /*#__PURE__*/React.createElement(LockedFigureSettingsAccordion, {
|
|
31182
|
-
expanded: true // Initial state is expanded
|
|
31183
|
-
,
|
|
31184
|
-
containerStyle: styles$d.container,
|
|
31185
|
-
panelStyle: styles$d.accordionPanel,
|
|
31186
|
-
header: /*#__PURE__*/React.createElement(View, {
|
|
31187
|
-
style: styles$d.row
|
|
31188
|
-
}, /*#__PURE__*/React.createElement(LabelLarge, null, `Tip (${tip[0]}, ${tip[1]})`))
|
|
31189
|
-
}, /*#__PURE__*/React.createElement(CoordinatePairInput, {
|
|
31190
|
-
coord: tip,
|
|
31191
|
-
error: isInvalid,
|
|
31192
|
-
onChange: newProps => {
|
|
31193
|
-
handleChangePoint(newProps, 1);
|
|
31194
|
-
}
|
|
31195
|
-
})), /*#__PURE__*/React.createElement(LockedFigureSettingsActions, {
|
|
31196
|
-
onRemove: onRemove,
|
|
31197
|
-
figureAriaLabel: `locked vector defined by starting point
|
|
31198
|
-
${tail[0]}, ${tail[1]} and extending to
|
|
31199
|
-
${tip[0]}, ${tip[1]}.`
|
|
31200
|
-
}));
|
|
31594
|
+
}
|
|
31595
|
+
InteractiveGraphSettings.defaultProps = {
|
|
31596
|
+
box: [interactiveSizes.defaultBoxSizeSmall, interactiveSizes.defaultBoxSizeSmall],
|
|
31597
|
+
labels: ["x", "y"],
|
|
31598
|
+
range: [[-10, 10], [-10, 10]],
|
|
31599
|
+
step: [1, 1],
|
|
31600
|
+
gridStep: [1, 1],
|
|
31601
|
+
snapStep: [1, 1],
|
|
31602
|
+
valid: true,
|
|
31603
|
+
backgroundImage: defaultBackgroundImage$1,
|
|
31604
|
+
markings: "graph",
|
|
31605
|
+
showProtractor: false,
|
|
31606
|
+
showRuler: false,
|
|
31607
|
+
showTooltips: false,
|
|
31608
|
+
rulerLabel: "",
|
|
31609
|
+
rulerTicks: 10
|
|
31201
31610
|
};
|
|
31202
|
-
const styles$
|
|
31203
|
-
|
|
31204
|
-
|
|
31205
|
-
},
|
|
31206
|
-
container: {
|
|
31207
|
-
marginTop: spacing.xSmall_8,
|
|
31208
|
-
marginBottom: 0,
|
|
31209
|
-
marginLeft: -spacing.xxxSmall_4,
|
|
31210
|
-
marginRight: -spacing.xxxSmall_4,
|
|
31211
|
-
backgroundColor: color.white
|
|
31611
|
+
const styles$c = StyleSheet.create({
|
|
31612
|
+
resetSpaceTop: {
|
|
31613
|
+
marginTop: 0
|
|
31212
31614
|
},
|
|
31213
|
-
|
|
31214
|
-
color: color.red,
|
|
31615
|
+
spaceTop: {
|
|
31215
31616
|
marginTop: spacing.xSmall_8
|
|
31216
31617
|
},
|
|
31217
|
-
|
|
31218
|
-
|
|
31219
|
-
|
|
31220
|
-
|
|
31221
|
-
}
|
|
31222
|
-
|
|
31223
|
-
|
|
31224
|
-
|
|
31225
|
-
|
|
31226
|
-
|
|
31227
|
-
|
|
31228
|
-
*/
|
|
31229
|
-
|
|
31230
|
-
// Union this type with other locked figure types when they are added.
|
|
31231
|
-
|
|
31232
|
-
const LockedFigureSettings = props => {
|
|
31233
|
-
switch (props.type) {
|
|
31234
|
-
case "point":
|
|
31235
|
-
return /*#__PURE__*/React.createElement(LockedPointSettings, props);
|
|
31236
|
-
case "line":
|
|
31237
|
-
return /*#__PURE__*/React.createElement(LockedLineSettings, props);
|
|
31238
|
-
case "ellipse":
|
|
31239
|
-
if (props.showM2Features) {
|
|
31240
|
-
return /*#__PURE__*/React.createElement(LockedEllipseSettings, props);
|
|
31241
|
-
}
|
|
31242
|
-
break;
|
|
31243
|
-
case "vector":
|
|
31244
|
-
if (props.showM2Features) {
|
|
31245
|
-
return /*#__PURE__*/React.createElement(LockedVectorSettings, props);
|
|
31246
|
-
}
|
|
31247
|
-
break;
|
|
31248
|
-
}
|
|
31249
|
-
return null;
|
|
31250
|
-
};
|
|
31251
|
-
|
|
31252
|
-
const LockedFiguresSection = props => {
|
|
31253
|
-
var _props$figures;
|
|
31254
|
-
// Keep track of all figures' accordions' expanded states for the
|
|
31255
|
-
// expand/collapse all button. Set the whole array to false initially.
|
|
31256
|
-
const collapsedStateArray = Array(((_props$figures = props.figures) != null ? _props$figures : []).length).fill(false);
|
|
31257
|
-
const [expandedStates, setExpandedStates] = React.useState(collapsedStateArray);
|
|
31258
|
-
const uniqueId = useUniqueIdWithMock().get("locked-figures-section");
|
|
31259
|
-
const {
|
|
31260
|
-
figures,
|
|
31261
|
-
onChange
|
|
31262
|
-
} = props;
|
|
31263
|
-
function addLockedFigure(newFigure) {
|
|
31264
|
-
const lockedFigures = figures || [];
|
|
31265
|
-
const newProps = {
|
|
31266
|
-
lockedFigures: [...lockedFigures, getDefaultFigureForType(newFigure)]
|
|
31267
|
-
};
|
|
31268
|
-
onChange(newProps);
|
|
31269
|
-
setExpandedStates([...expandedStates, true]);
|
|
31270
|
-
}
|
|
31271
|
-
function removeLockedFigure(index) {
|
|
31272
|
-
// eslint-disable-next-line no-alert
|
|
31273
|
-
if (window.confirm("Are you sure you want to delete this figure?")) {
|
|
31274
|
-
const lockedFigures = figures || [];
|
|
31275
|
-
onChange({
|
|
31276
|
-
lockedFigures: [...lockedFigures.slice(0, index), ...lockedFigures.slice(index + 1)]
|
|
31277
|
-
});
|
|
31278
|
-
|
|
31279
|
-
// Update expanded states
|
|
31280
|
-
const newExpandedStates = [...expandedStates];
|
|
31281
|
-
newExpandedStates.splice(index, 1);
|
|
31282
|
-
setExpandedStates(newExpandedStates);
|
|
31283
|
-
}
|
|
31284
|
-
}
|
|
31285
|
-
function changeProps(index,
|
|
31286
|
-
// Omit the type from the figure props so it doesn't think
|
|
31287
|
-
// we're trying to pass in the props for the wrong type.
|
|
31288
|
-
figureProps) {
|
|
31289
|
-
const lockedFigures = figures || [];
|
|
31290
|
-
const newFigures = {
|
|
31291
|
-
lockedFigures: [...lockedFigures.slice(0, index), _extends({}, lockedFigures[index], figureProps), ...lockedFigures.slice(index + 1)]
|
|
31292
|
-
};
|
|
31293
|
-
onChange(newFigures);
|
|
31294
|
-
}
|
|
31295
|
-
function toggleExpanded(newValue) {
|
|
31296
|
-
setExpandedStates(Array(figures == null ? void 0 : figures.length).fill(newValue));
|
|
31297
|
-
}
|
|
31298
|
-
const allCollapsed = expandedStates.every(value => !value);
|
|
31299
|
-
const buttonLabel = allCollapsed ? "Expand all" : "Collapse all";
|
|
31300
|
-
const showExpandButton = !!(figures != null && figures.length);
|
|
31301
|
-
return /*#__PURE__*/React.createElement(View, null, figures == null ? void 0 : figures.map((figure, index) => {
|
|
31302
|
-
if (figure.type === "polygon") {
|
|
31303
|
-
// TODO(LEMS-1943): Implement locked polygon settings.
|
|
31304
|
-
// Remove this block once locked polygon settings are
|
|
31305
|
-
// implemented.
|
|
31306
|
-
return;
|
|
31307
|
-
}
|
|
31308
|
-
return /*#__PURE__*/React.createElement(LockedFigureSettings, _extends({
|
|
31309
|
-
key: `${uniqueId}-locked-${figure}-${index}`,
|
|
31310
|
-
showM2Features: props.showM2Features,
|
|
31311
|
-
expanded: expandedStates[index],
|
|
31312
|
-
onToggle: newValue => {
|
|
31313
|
-
const newExpanded = [...expandedStates];
|
|
31314
|
-
newExpanded[index] = newValue;
|
|
31315
|
-
setExpandedStates(newExpanded);
|
|
31316
|
-
}
|
|
31317
|
-
}, figure, {
|
|
31318
|
-
onChangeProps: newProps => changeProps(index, newProps),
|
|
31319
|
-
onRemove: () => removeLockedFigure(index)
|
|
31320
|
-
}));
|
|
31321
|
-
}), /*#__PURE__*/React.createElement(View, {
|
|
31322
|
-
style: styles$c.buttonContainer
|
|
31323
|
-
}, /*#__PURE__*/React.createElement(LockedFigureSelect, {
|
|
31324
|
-
showM2Features: props.showM2Features,
|
|
31325
|
-
id: `${uniqueId}-select`,
|
|
31326
|
-
onChange: addLockedFigure
|
|
31327
|
-
}), /*#__PURE__*/React.createElement(Strut, {
|
|
31328
|
-
size: spacing.small_12
|
|
31329
|
-
}), showExpandButton && /*#__PURE__*/React.createElement(Button, {
|
|
31330
|
-
kind: "secondary",
|
|
31331
|
-
onClick: () => toggleExpanded(allCollapsed),
|
|
31332
|
-
style: styles$c.button
|
|
31333
|
-
}, buttonLabel)));
|
|
31334
|
-
};
|
|
31335
|
-
const styles$c = StyleSheet.create({
|
|
31336
|
-
buttonContainer: {
|
|
31618
|
+
singleSelectShort: {
|
|
31619
|
+
// Non-standard spacing, but it's the smallest we can go
|
|
31620
|
+
// without running into styling issues with the dropdown.
|
|
31621
|
+
height: 26
|
|
31622
|
+
},
|
|
31623
|
+
backgroundUrlInput: {
|
|
31624
|
+
border: `1px solid ${color.offBlack32}`,
|
|
31625
|
+
borderRadius: spacing.xxxSmall_4,
|
|
31626
|
+
padding: spacing.xxxSmall_4
|
|
31627
|
+
},
|
|
31628
|
+
checkboxRow: {
|
|
31337
31629
|
flexDirection: "row",
|
|
31338
|
-
alignItems: "center"
|
|
31630
|
+
alignItems: "center",
|
|
31631
|
+
justifyContent: "space-between",
|
|
31632
|
+
marginBottom: spacing.xSmall_8
|
|
31339
31633
|
},
|
|
31340
|
-
|
|
31634
|
+
rulerSection: {
|
|
31341
31635
|
marginTop: spacing.xSmall_8,
|
|
31342
|
-
|
|
31636
|
+
borderTop: `1px solid ${color.offBlack16}`,
|
|
31637
|
+
paddingTop: spacing.xSmall_8,
|
|
31638
|
+
paddingBottom: spacing.xSmall_8,
|
|
31639
|
+
borderBottom: `1px solid ${color.offBlack16}`
|
|
31343
31640
|
}
|
|
31344
31641
|
});
|
|
31345
31642
|
|
|
@@ -31444,7 +31741,7 @@ class InteractiveGraphEditor extends React.Component {
|
|
|
31444
31741
|
return testGraphKey.join(":");
|
|
31445
31742
|
}
|
|
31446
31743
|
render() {
|
|
31447
|
-
var _this$props$graph$typ, _this$props$graph, _this$props$correct, _this$props$correct2, _this$props$correct3, _this$props$correct4, _this$props$correct5, _this$props$correct6, _this$props$correct7, _this$props$correct8, _this$props$correct9, _this$props$correct10, _this$props$correct11, _this$props$apiOption, _this$props$apiOption2;
|
|
31744
|
+
var _this$props$graph$typ, _this$props$graph, _this$props$correct, _this$props$correct2, _this$props$correct3, _this$props$correct4, _this$props$correct5, _this$props$correct6, _this$props$correct7, _this$props$correct8, _this$props$correct9, _this$props$correct10, _this$props$correct11, _this$props$apiOption, _this$props$apiOption2, _this$props$apiOption3;
|
|
31448
31745
|
let graph;
|
|
31449
31746
|
let equationString;
|
|
31450
31747
|
const gridStep = this.props.gridStep || Util.getGridStep(this.props.range, this.props.step, interactiveSizes.defaultBoxSize);
|
|
@@ -31696,6 +31993,7 @@ class InteractiveGraphEditor extends React.Component {
|
|
|
31696
31993
|
// is using Mafs.
|
|
31697
31994
|
this.props.graph && ((_this$props$apiOption = this.props.apiOptions) == null || (_this$props$apiOption = _this$props$apiOption.flags) == null || (_this$props$apiOption = _this$props$apiOption.mafs) == null ? void 0 : _this$props$apiOption[this.props.graph.type]) && /*#__PURE__*/React.createElement(LockedFiguresSection, {
|
|
31698
31995
|
showM2Features: (_this$props$apiOption2 = this.props.apiOptions) == null || (_this$props$apiOption2 = _this$props$apiOption2.flags) == null || (_this$props$apiOption2 = _this$props$apiOption2.mafs) == null ? void 0 : _this$props$apiOption2["interactive-graph-locked-features-m2"],
|
|
31996
|
+
showM2bFeatures: (_this$props$apiOption3 = this.props.apiOptions) == null || (_this$props$apiOption3 = _this$props$apiOption3.flags) == null || (_this$props$apiOption3 = _this$props$apiOption3.mafs) == null ? void 0 : _this$props$apiOption3["interactive-graph-locked-features-m2b"],
|
|
31699
31997
|
figures: this.props.lockedFigures,
|
|
31700
31998
|
onChange: this.props.onChange
|
|
31701
31999
|
}));
|