@khanacademy/perseus-editor 6.10.0 → 6.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/{coordinate-pair-input.d.ts → graph-locked-figures/coordinate-pair-input.d.ts} +2 -0
- package/dist/components/{defining-point-settings.d.ts → graph-locked-figures/defining-point-settings.d.ts} +9 -2
- package/dist/components/{ellipse-swatch.d.ts → graph-locked-figures/ellipse-swatch.d.ts} +2 -2
- package/dist/components/{locked-ellipse-settings.d.ts → graph-locked-figures/locked-ellipse-settings.d.ts} +2 -6
- package/dist/components/{locked-figure-select.d.ts → graph-locked-figures/locked-figure-select.d.ts} +1 -0
- package/dist/components/graph-locked-figures/locked-figure-settings-actions.d.ts +11 -0
- package/dist/components/{locked-figure-settings.d.ts → graph-locked-figures/locked-figure-settings.d.ts} +13 -2
- package/dist/components/{locked-figures-section.d.ts → graph-locked-figures/locked-figures-section.d.ts} +2 -1
- package/dist/components/{locked-line-settings.d.ts → graph-locked-figures/locked-line-settings.d.ts} +2 -6
- package/dist/components/{locked-point-settings.d.ts → graph-locked-figures/locked-point-settings.d.ts} +2 -6
- package/dist/components/graph-locked-figures/locked-polygon-settings.d.ts +11 -0
- package/dist/components/{locked-vector-settings.d.ts → graph-locked-figures/locked-vector-settings.d.ts} +2 -6
- package/dist/components/graph-locked-figures/polygon-swatch.d.ts +9 -0
- package/dist/components/util.d.ts +5 -2
- package/dist/es/index.js +2000 -1701
- package/dist/es/index.js.map +1 -1
- package/dist/index.js +2051 -1746
- package/dist/index.js.map +1 -1
- package/dist/widgets/interactive-graph-editor.d.ts +402 -233
- package/package.json +2 -2
- package/dist/components/locked-figure-settings-actions.d.ts +0 -7
- /package/dist/components/{color-select.d.ts → graph-locked-figures/color-select.d.ts} +0 -0
- /package/dist/components/{color-swatch.d.ts → graph-locked-figures/color-swatch.d.ts} +0 -0
- /package/dist/components/{labeled-row.d.ts → graph-locked-figures/labeled-row.d.ts} +0 -0
- /package/dist/components/{labeled-switch.d.ts → graph-locked-figures/labeled-switch.d.ts} +0 -0
- /package/dist/components/{line-swatch.d.ts → graph-locked-figures/line-swatch.d.ts} +0 -0
- /package/dist/components/{locked-figure-settings-accordion.d.ts → graph-locked-figures/locked-figure-settings-accordion.d.ts} +0 -0
package/dist/es/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { addLibraryVersionToPerseusDebug } from '@khanacademy/perseus-core';
|
|
2
|
-
import { constants, components, Widgets, icons, WIDGET_PROP_DENYLIST, Util, Log, PerseusError, Errors, PerseusMarkdown, preprocessTex, ApiOptions, buildMapper, itemToTree, buildEmptyItemTreeForShape, shapes, ItemExtras, itemDataVersion, ClassNames, MultiItems, traverse, Categorizer as Categorizer$1, Changeable, EditorJsonify, Dependencies, WidgetJsonifyDeprecated, PerseusExpressionAnswerFormConsidered, Expression, interactiveSizes, KhanMath, GrapherWidget, GrapherUtil, SizingUtils, PerseusI18nContext, KhanColors, ColorPicker, DashPicker, ArrowPicker, ElementContainer, lockedFigureColors,
|
|
2
|
+
import { constants, components, Widgets, icons, WIDGET_PROP_DENYLIST, Util, Log, PerseusError, Errors, PerseusMarkdown, preprocessTex, ApiOptions, buildMapper, itemToTree, buildEmptyItemTreeForShape, shapes, ItemExtras, itemDataVersion, ClassNames, MultiItems, traverse, Categorizer as Categorizer$1, Changeable, EditorJsonify, Dependencies, WidgetJsonifyDeprecated, PerseusExpressionAnswerFormConsidered, Expression, interactiveSizes, KhanMath, GrapherWidget, GrapherUtil, SizingUtils, PerseusI18nContext, KhanColors, ColorPicker, DashPicker, ArrowPicker, ElementContainer, lockedFigureColors, lockedFigureFillStyles, InteractiveGraphWidget, globalStyles, globalConstants, MatrixWidget, PlotterWidget, plotterPlotTypes, BaseRadio, TableWidget, displaySigFigs, widgets } from '@khanacademy/perseus';
|
|
3
3
|
import * as React from 'react';
|
|
4
4
|
import { useRef, useEffect } from 'react';
|
|
5
5
|
import _ from 'underscore';
|
|
@@ -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
|
-
import Switch from '@khanacademy/wonder-blocks-switch';
|
|
27
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';
|
|
28
31
|
import trashIcon from '@phosphor-icons/core/bold/trash-bold.svg';
|
|
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",
|
|
@@ -23445,7 +23452,7 @@ class StructuredItemDiff extends React.Component {
|
|
|
23445
23452
|
|
|
23446
23453
|
/* eslint-disable @khanacademy/ts-no-error-suppressions */
|
|
23447
23454
|
const {
|
|
23448
|
-
InfoTip: InfoTip$
|
|
23455
|
+
InfoTip: InfoTip$m,
|
|
23449
23456
|
InlineIcon: InlineIcon$7
|
|
23450
23457
|
} = components;
|
|
23451
23458
|
const {
|
|
@@ -23517,7 +23524,7 @@ class HintEditor extends React.Component {
|
|
|
23517
23524
|
type: "button",
|
|
23518
23525
|
className: this.props.isFirst ? "hidden" : "",
|
|
23519
23526
|
onClick: _.partial(this.props.onMove, -1)
|
|
23520
|
-
}, /*#__PURE__*/React.createElement(InlineIcon$7, iconCircleArrowUp)), " ", this.props.isLast && /*#__PURE__*/React.createElement(InfoTip$
|
|
23527
|
+
}, /*#__PURE__*/React.createElement(InlineIcon$7, iconCircleArrowUp)), " ", this.props.isLast && /*#__PURE__*/React.createElement(InfoTip$m, null, /*#__PURE__*/React.createElement("p", null, "The last hint is automatically bolded."))), /*#__PURE__*/React.createElement("input", {
|
|
23521
23528
|
type: "checkbox"
|
|
23522
23529
|
// @ts-expect-error - TS2322 - Type 'boolean | null | undefined' is not assignable to type 'boolean | undefined'.
|
|
23523
23530
|
,
|
|
@@ -23770,7 +23777,7 @@ CombinedHintsEditor.defaultProps = {
|
|
|
23770
23777
|
};
|
|
23771
23778
|
|
|
23772
23779
|
const {
|
|
23773
|
-
InfoTip: InfoTip$
|
|
23780
|
+
InfoTip: InfoTip$l
|
|
23774
23781
|
} = components;
|
|
23775
23782
|
class ItemExtrasEditor extends React.Component {
|
|
23776
23783
|
constructor(...args) {
|
|
@@ -23916,7 +23923,7 @@ const ItemExtraCheckbox = props => /*#__PURE__*/React.createElement("div", {
|
|
|
23916
23923
|
type: "checkbox",
|
|
23917
23924
|
checked: props.checked,
|
|
23918
23925
|
onChange: props.onChange
|
|
23919
|
-
})), /*#__PURE__*/React.createElement(InfoTip$
|
|
23926
|
+
})), /*#__PURE__*/React.createElement(InfoTip$l, null, props.infoTip));
|
|
23920
23927
|
|
|
23921
23928
|
const ITEM_DATA_VERSION = itemDataVersion;
|
|
23922
23929
|
class ItemEditor extends React.Component {
|
|
@@ -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
|
|
@@ -25731,7 +25738,7 @@ class BlurInput extends React.Component {
|
|
|
25731
25738
|
}
|
|
25732
25739
|
|
|
25733
25740
|
const {
|
|
25734
|
-
InfoTip: InfoTip$
|
|
25741
|
+
InfoTip: InfoTip$k,
|
|
25735
25742
|
PropCheckBox: PropCheckBox$b
|
|
25736
25743
|
} = components;
|
|
25737
25744
|
const DEFAULT_WIDTH = 400;
|
|
@@ -25892,7 +25899,7 @@ class CSProgramEditor extends React.Component {
|
|
|
25892
25899
|
label: "Show Editor",
|
|
25893
25900
|
showEditor: this.props.showEditor,
|
|
25894
25901
|
onChange: this.props.onChange
|
|
25895
|
-
}), /*#__PURE__*/React.createElement(InfoTip$
|
|
25902
|
+
}), /*#__PURE__*/React.createElement(InfoTip$k, null, "If you show the editor, you should use the \"full-width\" alignment to make room for the width of the editor."), /*#__PURE__*/React.createElement("br", null), /*#__PURE__*/React.createElement(PropCheckBox$b, {
|
|
25896
25903
|
label: "Show Buttons",
|
|
25897
25904
|
showButtons: this.props.showButtons,
|
|
25898
25905
|
onChange: this.props.onChange
|
|
@@ -25900,7 +25907,7 @@ class CSProgramEditor extends React.Component {
|
|
|
25900
25907
|
name: "settings",
|
|
25901
25908
|
pairs: this.props.settings,
|
|
25902
25909
|
onChange: this._handleSettingsChange
|
|
25903
|
-
}), /*#__PURE__*/React.createElement(InfoTip$
|
|
25910
|
+
}), /*#__PURE__*/React.createElement(InfoTip$k, null, "Settings that you add here are available to the program as an object returned by ", /*#__PURE__*/React.createElement("code", null, "Program.settings()"))));
|
|
25904
25911
|
}
|
|
25905
25912
|
}
|
|
25906
25913
|
CSProgramEditor.propTypes = _extends({}, Changeable.propTypes);
|
|
@@ -25986,7 +25993,7 @@ DeprecatedStandinEditor.widgetName = "deprecated-standin";
|
|
|
25986
25993
|
|
|
25987
25994
|
/* eslint-disable @khanacademy/ts-no-error-suppressions */
|
|
25988
25995
|
const {
|
|
25989
|
-
InfoTip: InfoTip$
|
|
25996
|
+
InfoTip: InfoTip$j,
|
|
25990
25997
|
InlineIcon: InlineIcon$5
|
|
25991
25998
|
} = components;
|
|
25992
25999
|
const {
|
|
@@ -26055,14 +26062,14 @@ class DropdownEditor extends React.Component {
|
|
|
26055
26062
|
className: "perseus-widget-dropdown"
|
|
26056
26063
|
}, /*#__PURE__*/React.createElement("div", {
|
|
26057
26064
|
className: "dropdown-info"
|
|
26058
|
-
}, "Dropdown", /*#__PURE__*/React.createElement(InfoTip$
|
|
26065
|
+
}, "Dropdown", /*#__PURE__*/React.createElement(InfoTip$j, null, /*#__PURE__*/React.createElement("p", null, "The drop down is useful for making inequalities in a custom format. We normally use the symbols ", "<", ",", " ", ">", ", \u2264, \u2265 (in that order) which you can copy into the choices. When possible, use the \"multiple choice\" answer type instead."))), /*#__PURE__*/React.createElement("div", {
|
|
26059
26066
|
className: "dropdown-placeholder"
|
|
26060
26067
|
}, /*#__PURE__*/React.createElement("input", {
|
|
26061
26068
|
type: "text",
|
|
26062
26069
|
placeholder: "Placeholder value",
|
|
26063
26070
|
value: this.props.placeholder,
|
|
26064
26071
|
onChange: this.onPlaceholderChange
|
|
26065
|
-
}), /*#__PURE__*/React.createElement(InfoTip$
|
|
26072
|
+
}), /*#__PURE__*/React.createElement(InfoTip$j, null, /*#__PURE__*/React.createElement("p", null, "This value will appear as the drop down default. It should give the user some indication of the values available in the drop down itself, e.g., Yes/No/Maybe."))), /*#__PURE__*/React.createElement("div", {
|
|
26066
26073
|
className: "clearfix"
|
|
26067
26074
|
}), /*#__PURE__*/React.createElement("ul", {
|
|
26068
26075
|
className: "dropdown-choices"
|
|
@@ -26593,7 +26600,7 @@ const SortableItem = createReactClass({
|
|
|
26593
26600
|
});
|
|
26594
26601
|
|
|
26595
26602
|
const {
|
|
26596
|
-
InfoTip: InfoTip$
|
|
26603
|
+
InfoTip: InfoTip$i,
|
|
26597
26604
|
PropCheckBox: PropCheckBox$a
|
|
26598
26605
|
} = components;
|
|
26599
26606
|
|
|
@@ -26847,11 +26854,11 @@ class ExpressionEditor extends React.Component {
|
|
|
26847
26854
|
onChange: this.props.onChange,
|
|
26848
26855
|
labelAlignment: "right",
|
|
26849
26856
|
label: "Use \xD7 for rendering multiplication instead of a center dot."
|
|
26850
|
-
}), /*#__PURE__*/React.createElement(InfoTip$
|
|
26857
|
+
}), /*#__PURE__*/React.createElement(InfoTip$i, null, /*#__PURE__*/React.createElement("p", null, "For pre-algebra problems this option displays multiplication as \\times instead of \\cdot in both the rendered output and the acceptable formats examples."))), /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("label", null, "Function variables: ", /*#__PURE__*/React.createElement("input", {
|
|
26851
26858
|
type: "text",
|
|
26852
26859
|
defaultValue: this.props.functions.join(" "),
|
|
26853
26860
|
onChange: this.handleFunctions
|
|
26854
|
-
})), /*#__PURE__*/React.createElement(InfoTip$
|
|
26861
|
+
})), /*#__PURE__*/React.createElement(InfoTip$i, null, /*#__PURE__*/React.createElement("p", null, "Single-letter variables listed here will be interpreted as functions. This let us know that f(x) means \"f of x\" and not \"f times x\"."))), /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("div", null, "Button sets:"), buttonSetChoices), /*#__PURE__*/React.createElement("h3", {
|
|
26855
26862
|
className: "expression-editor-h3"
|
|
26856
26863
|
}, "Answers"), /*#__PURE__*/React.createElement("p", {
|
|
26857
26864
|
style: {
|
|
@@ -26946,14 +26953,14 @@ class AnswerOption extends React.Component {
|
|
|
26946
26953
|
onChange: this.props.onChange,
|
|
26947
26954
|
labelAlignment: "right",
|
|
26948
26955
|
label: "Answer expression must have the same form."
|
|
26949
|
-
}), /*#__PURE__*/React.createElement(InfoTip$
|
|
26956
|
+
}), /*#__PURE__*/React.createElement(InfoTip$i, null, /*#__PURE__*/React.createElement("p", null, "The student's answer must be in the same form. Commutativity and excess negative signs are ignored."))), /*#__PURE__*/React.createElement("div", {
|
|
26950
26957
|
className: "answer-option"
|
|
26951
26958
|
}, /*#__PURE__*/React.createElement(PropCheckBox$a, {
|
|
26952
26959
|
simplify: this.props.simplify,
|
|
26953
26960
|
onChange: this.props.onChange,
|
|
26954
26961
|
labelAlignment: "right",
|
|
26955
26962
|
label: "Answer expression must be fully expanded and simplified."
|
|
26956
|
-
}), /*#__PURE__*/React.createElement(InfoTip$
|
|
26963
|
+
}), /*#__PURE__*/React.createElement(InfoTip$i, null, /*#__PURE__*/React.createElement("p", null, "The student's answer must be fully expanded and simplified. Answering this equation (x^2+2x+1) with this factored equation (x+1)^2 will render this response \"Your answer is not fully expanded and simplified.\""))), /*#__PURE__*/React.createElement("div", {
|
|
26957
26964
|
className: "remove-container"
|
|
26958
26965
|
}, removeButton)));
|
|
26959
26966
|
}
|
|
@@ -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"
|
|
@@ -27153,7 +27160,7 @@ const setArrayItem = (list, i, value) => [...list.slice(0, i), value, ...list.sl
|
|
|
27153
27160
|
|
|
27154
27161
|
const {
|
|
27155
27162
|
ButtonGroup: ButtonGroup$4,
|
|
27156
|
-
InfoTip: InfoTip$
|
|
27163
|
+
InfoTip: InfoTip$h,
|
|
27157
27164
|
PropCheckBox: PropCheckBox$9,
|
|
27158
27165
|
RangeInput: RangeInput$6
|
|
27159
27166
|
} = components;
|
|
@@ -27609,7 +27616,7 @@ const GraphSettings = createReactClass({
|
|
|
27609
27616
|
},
|
|
27610
27617
|
onKeyPress: this.changeBackgroundUrl,
|
|
27611
27618
|
onBlur: this.changeBackgroundUrl
|
|
27612
|
-
}), /*#__PURE__*/React.createElement(InfoTip$
|
|
27619
|
+
}), /*#__PURE__*/React.createElement(InfoTip$h, null, /*#__PURE__*/React.createElement("p", null, "Create an image in graphie, or use the \"Add image\" function to create a background.")))), _.contains(this.props.editableSettings, "measure") && /*#__PURE__*/React.createElement("div", {
|
|
27613
27620
|
className: "misc-settings"
|
|
27614
27621
|
}, /*#__PURE__*/React.createElement("div", {
|
|
27615
27622
|
className: "perseus-widget-row"
|
|
@@ -27647,7 +27654,7 @@ const GraphSettings = createReactClass({
|
|
|
27647
27654
|
});
|
|
27648
27655
|
|
|
27649
27656
|
const {
|
|
27650
|
-
InfoTip: InfoTip$
|
|
27657
|
+
InfoTip: InfoTip$g,
|
|
27651
27658
|
MultiButtonGroup: MultiButtonGroup$1
|
|
27652
27659
|
} = components;
|
|
27653
27660
|
const {
|
|
@@ -27730,7 +27737,7 @@ class GrapherEditor extends React.Component {
|
|
|
27730
27737
|
className: "perseus-error"
|
|
27731
27738
|
}, this.props.graph.valid);
|
|
27732
27739
|
}
|
|
27733
|
-
return /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("div", null, "Correct answer", " ", /*#__PURE__*/React.createElement(InfoTip$
|
|
27740
|
+
return /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("div", null, "Correct answer", " ", /*#__PURE__*/React.createElement(InfoTip$g, null, /*#__PURE__*/React.createElement("p", null, "Graph the correct answer in the graph below and ensure the equation or point coordinates displayed represent the correct answer.")), " ", ": ", equationString), /*#__PURE__*/React.createElement(GraphSettings, {
|
|
27734
27741
|
editableSettings: ["graph", "snap", "image"],
|
|
27735
27742
|
box: getInteractiveBoxFromSizeClass$1(sizeClass),
|
|
27736
27743
|
range: this.props.graph.range,
|
|
@@ -27975,7 +27982,7 @@ IframeEditor.defaultProps = {
|
|
|
27975
27982
|
|
|
27976
27983
|
/* eslint-disable jsx-a11y/anchor-is-valid, react/sort-comp */
|
|
27977
27984
|
const {
|
|
27978
|
-
InfoTip: InfoTip$
|
|
27985
|
+
InfoTip: InfoTip$f,
|
|
27979
27986
|
InlineIcon: InlineIcon$3,
|
|
27980
27987
|
RangeInput: RangeInput$5
|
|
27981
27988
|
} = components;
|
|
@@ -28024,7 +28031,7 @@ class ImageEditor extends React.Component {
|
|
|
28024
28031
|
style: {
|
|
28025
28032
|
width: "100%"
|
|
28026
28033
|
}
|
|
28027
|
-
}))), /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("label", null, /*#__PURE__*/React.createElement("div", null, "Dimensions:"), /*#__PURE__*/React.createElement("p", null, backgroundImage.width, "x", backgroundImage.height))), /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("label", null, /*#__PURE__*/React.createElement("div", null, "Alt text:", /*#__PURE__*/React.createElement(InfoTip$
|
|
28034
|
+
}))), /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("label", null, /*#__PURE__*/React.createElement("div", null, "Dimensions:"), /*#__PURE__*/React.createElement("p", null, backgroundImage.width, "x", backgroundImage.height))), /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("label", null, /*#__PURE__*/React.createElement("div", null, "Alt text:", /*#__PURE__*/React.createElement(InfoTip$f, null, "This is important for screenreaders. The content of this alt text will be formatted as markdown (tables, emphasis, etc. are supported).")), /*#__PURE__*/React.createElement(Editor, {
|
|
28028
28035
|
apiOptions: this.props.apiOptions,
|
|
28029
28036
|
content: this.props.alt,
|
|
28030
28037
|
onChange: props => {
|
|
@@ -28048,7 +28055,7 @@ class ImageEditor extends React.Component {
|
|
|
28048
28055
|
}, this.state.backgroundImageError);
|
|
28049
28056
|
return /*#__PURE__*/React.createElement("div", {
|
|
28050
28057
|
className: "perseus-image-editor"
|
|
28051
|
-
}, /*#__PURE__*/React.createElement("label", null, "Image url:", /*#__PURE__*/React.createElement(InfoTip$
|
|
28058
|
+
}, /*#__PURE__*/React.createElement("label", null, "Image url:", /*#__PURE__*/React.createElement(InfoTip$f, null, "Paste an image or graphie image URL."), this.state.backgroundImageError && backgroundImageErrorText, /*#__PURE__*/React.createElement(BlurInput, {
|
|
28052
28059
|
value: backgroundImage.url || "",
|
|
28053
28060
|
style: {
|
|
28054
28061
|
width: 332
|
|
@@ -28212,7 +28219,7 @@ ImageEditor.defaultProps = {
|
|
|
28212
28219
|
|
|
28213
28220
|
/* eslint-disable react/sort-comp */
|
|
28214
28221
|
const {
|
|
28215
|
-
InfoTip: InfoTip$
|
|
28222
|
+
InfoTip: InfoTip$e
|
|
28216
28223
|
} = components;
|
|
28217
28224
|
const answerTypes = {
|
|
28218
28225
|
number: {
|
|
@@ -28298,7 +28305,7 @@ class InputNumberEditor extends React.Component {
|
|
|
28298
28305
|
value: "optional"
|
|
28299
28306
|
}, "will be accepted"), /*#__PURE__*/React.createElement("option", {
|
|
28300
28307
|
value: "enforced"
|
|
28301
|
-
}, "will be marked wrong"))), /*#__PURE__*/React.createElement(InfoTip$
|
|
28308
|
+
}, "will be marked wrong"))), /*#__PURE__*/React.createElement(InfoTip$e, null, /*#__PURE__*/React.createElement("p", null, "Normally select \"will not be graded\". This will give the user a message saying the answer is correct but not simplified. The user will then have to simplify it and re-enter, but will not be penalized. (5th grade and anything after)"), /*#__PURE__*/React.createElement("p", null, "Select \"will be accepted\" only if the user is not expected to know how to simplify fractions yet. (Anything prior to 5th grade)"), /*#__PURE__*/React.createElement("p", null, "Select \"will be marked wrong\" only if we are specifically assessing the ability to simplify."))), /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("label", null, /*#__PURE__*/React.createElement("input", {
|
|
28302
28309
|
type: "checkbox",
|
|
28303
28310
|
checked: this.props.inexact,
|
|
28304
28311
|
onChange: e => {
|
|
@@ -28334,7 +28341,7 @@ class InputNumberEditor extends React.Component {
|
|
|
28334
28341
|
});
|
|
28335
28342
|
},
|
|
28336
28343
|
"aria-label": "Answer type"
|
|
28337
|
-
}, answerTypeOptions), /*#__PURE__*/React.createElement(InfoTip$
|
|
28344
|
+
}, answerTypeOptions), /*#__PURE__*/React.createElement(InfoTip$e, null, /*#__PURE__*/React.createElement("p", null, "Use the default \"Numbers\" unless the answer must be in a specific form (e.g., question is about converting decimals to fractions)."))), /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("label", null, "Width", " ", /*#__PURE__*/React.createElement("select", {
|
|
28338
28345
|
value: this.props.size,
|
|
28339
28346
|
onChange: e => {
|
|
28340
28347
|
// @ts-expect-error - TS2322 - Type 'string' is not assignable to type '"small" | "normal" | undefined'.
|
|
@@ -28346,7 +28353,7 @@ class InputNumberEditor extends React.Component {
|
|
|
28346
28353
|
value: "normal"
|
|
28347
28354
|
}, "Normal (80px)"), /*#__PURE__*/React.createElement("option", {
|
|
28348
28355
|
value: "small"
|
|
28349
|
-
}, "Small (40px)"))), /*#__PURE__*/React.createElement(InfoTip$
|
|
28356
|
+
}, "Small (40px)"))), /*#__PURE__*/React.createElement(InfoTip$e, null, /*#__PURE__*/React.createElement("p", null, "Use size \"Normal\" for all text boxes, unless there are multiple text boxes in one line and the answer area is too narrow to fit them."))), /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("label", null, /*#__PURE__*/React.createElement("input", {
|
|
28350
28357
|
type: "checkbox",
|
|
28351
28358
|
checked: this.props.rightAlign,
|
|
28352
28359
|
onChange: e => {
|
|
@@ -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,886 +29500,1038 @@ 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$e, 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)))));
|
|
30105
29827
|
};
|
|
30106
|
-
const styles$
|
|
30107
|
-
|
|
30108
|
-
|
|
30109
|
-
},
|
|
30110
|
-
spaceTop: {
|
|
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
|
|
30117
|
-
},
|
|
30118
|
-
backgroundUrlInput: {
|
|
30119
|
-
border: `1px solid ${color.offBlack32}`,
|
|
30120
|
-
borderRadius: spacing.xxxSmall_4,
|
|
30121
|
-
padding: spacing.xxxSmall_4
|
|
30122
|
-
},
|
|
30123
|
-
checkboxRow: {
|
|
29828
|
+
const styles$t = StyleSheet.create({
|
|
29829
|
+
row: {
|
|
29830
|
+
display: "flex",
|
|
30124
29831
|
flexDirection: "row",
|
|
30125
|
-
alignItems: "center"
|
|
30126
|
-
justifyContent: "space-between",
|
|
30127
|
-
marginBottom: spacing.xSmall_8
|
|
30128
|
-
},
|
|
30129
|
-
rulerSection: {
|
|
30130
|
-
marginTop: spacing.xSmall_8,
|
|
30131
|
-
borderTop: `1px solid ${color.offBlack16}`,
|
|
30132
|
-
paddingTop: spacing.xSmall_8,
|
|
30133
|
-
paddingBottom: spacing.xSmall_8,
|
|
30134
|
-
borderBottom: `1px solid ${color.offBlack16}`
|
|
29832
|
+
alignItems: "center"
|
|
30135
29833
|
}
|
|
30136
29834
|
});
|
|
30137
29835
|
|
|
30138
|
-
const
|
|
30139
|
-
const
|
|
30140
|
-
|
|
30141
|
-
|
|
30142
|
-
|
|
30143
|
-
|
|
30144
|
-
|
|
30145
|
-
}
|
|
30146
|
-
|
|
30147
|
-
|
|
30148
|
-
|
|
30149
|
-
|
|
30150
|
-
|
|
30151
|
-
|
|
30152
|
-
|
|
30153
|
-
|
|
30154
|
-
|
|
30155
|
-
|
|
30156
|
-
|
|
30157
|
-
|
|
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);
|
|
30158
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
|
+
})));
|
|
30159
29892
|
};
|
|
30160
|
-
({
|
|
30161
|
-
|
|
30162
|
-
|
|
30163
|
-
|
|
30164
|
-
|
|
30165
|
-
|
|
29893
|
+
const styles$s = StyleSheet.create({
|
|
29894
|
+
row: {
|
|
29895
|
+
display: "flex",
|
|
29896
|
+
flexDirection: "row",
|
|
29897
|
+
alignItems: "center"
|
|
29898
|
+
},
|
|
29899
|
+
textField: {
|
|
29900
|
+
width: spacing.xxxLarge_64
|
|
29901
|
+
},
|
|
29902
|
+
errorField: {
|
|
29903
|
+
borderColor: color.red,
|
|
29904
|
+
backgroundColor: color.fadedRed8
|
|
30166
29905
|
}
|
|
30167
29906
|
});
|
|
30168
|
-
|
|
30169
|
-
|
|
30170
|
-
|
|
30171
|
-
|
|
30172
|
-
|
|
30173
|
-
|
|
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,
|
|
29935
|
+
alignItems: "center",
|
|
29936
|
+
justifyContent: "center"
|
|
30174
29937
|
},
|
|
30175
|
-
|
|
30176
|
-
|
|
30177
|
-
|
|
30178
|
-
|
|
30179
|
-
marginWidth: spacing.xxLarge_48
|
|
29938
|
+
innerCircle: {
|
|
29939
|
+
width: 28,
|
|
29940
|
+
height: 20,
|
|
29941
|
+
borderRadius: "50%"
|
|
30180
29942
|
}
|
|
30181
29943
|
});
|
|
30182
29944
|
|
|
30183
|
-
const
|
|
30184
|
-
|
|
30185
|
-
|
|
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)));
|
|
30186
29969
|
};
|
|
30187
|
-
const
|
|
30188
|
-
|
|
30189
|
-
|
|
30190
|
-
|
|
30191
|
-
|
|
29970
|
+
const styles$q = StyleSheet.create({
|
|
29971
|
+
container: {
|
|
29972
|
+
backgroundColor: color.fadedBlue8,
|
|
29973
|
+
marginTop: spacing.xSmall_8
|
|
29974
|
+
},
|
|
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
|
|
29982
|
+
},
|
|
29983
|
+
accordionPanel: {
|
|
29984
|
+
paddingTop: spacing.xxSmall_6,
|
|
29985
|
+
paddingBottom: spacing.xxxSmall_4,
|
|
29986
|
+
paddingLeft: spacing.small_12,
|
|
29987
|
+
paddingRight: spacing.small_12
|
|
30192
29988
|
}
|
|
30193
29989
|
});
|
|
30194
29990
|
|
|
30195
|
-
class Strut extends React.Component {
|
|
30196
|
-
render() {
|
|
30197
|
-
const {
|
|
30198
|
-
size,
|
|
30199
|
-
style
|
|
30200
|
-
} = this.props;
|
|
30201
|
-
return React.createElement(View, {
|
|
30202
|
-
"aria-hidden": "true",
|
|
30203
|
-
style: [strutStyle(size), style]
|
|
30204
|
-
});
|
|
30205
|
-
}
|
|
30206
|
-
}
|
|
30207
|
-
const strutStyle = size => {
|
|
30208
|
-
return {
|
|
30209
|
-
width: size,
|
|
30210
|
-
MsFlexBasis: size,
|
|
30211
|
-
MsFlexPreferredSize: size,
|
|
30212
|
-
WebkitFlexBasis: size,
|
|
30213
|
-
flexBasis: size,
|
|
30214
|
-
flexShrink: 0
|
|
30215
|
-
};
|
|
30216
|
-
};
|
|
30217
|
-
|
|
30218
29991
|
/**
|
|
30219
|
-
*
|
|
30220
|
-
*
|
|
30221
|
-
*
|
|
30222
|
-
*
|
|
30223
|
-
* Used in the interactive graph editor's locked figures section.
|
|
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.
|
|
30224
29995
|
*/
|
|
30225
|
-
const
|
|
29996
|
+
const LockedFigureSettingsActions = props => {
|
|
30226
29997
|
const {
|
|
30227
|
-
|
|
30228
|
-
|
|
29998
|
+
figureType,
|
|
29999
|
+
onMove,
|
|
30000
|
+
onRemove
|
|
30229
30001
|
} = props;
|
|
30230
|
-
const figureTypes = props.showM2Features ? ["point", "line", "ellipse", "vector"] : ["point", "line"];
|
|
30231
30002
|
return /*#__PURE__*/React.createElement(View, {
|
|
30232
|
-
style: styles$
|
|
30233
|
-
}, /*#__PURE__*/React.createElement(
|
|
30234
|
-
|
|
30235
|
-
|
|
30236
|
-
|
|
30237
|
-
|
|
30238
|
-
|
|
30239
|
-
|
|
30240
|
-
|
|
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
|
+
})));
|
|
30241
30035
|
};
|
|
30242
|
-
const styles$
|
|
30036
|
+
const styles$p = StyleSheet.create({
|
|
30243
30037
|
container: {
|
|
30244
|
-
|
|
30038
|
+
width: "100%",
|
|
30039
|
+
flexDirection: "row",
|
|
30040
|
+
alignItems: "center",
|
|
30041
|
+
marginTop: spacing.xxxSmall_4
|
|
30245
30042
|
},
|
|
30246
|
-
|
|
30247
|
-
|
|
30248
|
-
|
|
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
|
|
30249
30051
|
}
|
|
30250
30052
|
});
|
|
30251
30053
|
|
|
30252
30054
|
const {
|
|
30253
30055
|
InfoTip: InfoTip$d
|
|
30254
30056
|
} = components;
|
|
30255
|
-
const
|
|
30256
|
-
return degrees / 180 * Math.PI;
|
|
30257
|
-
};
|
|
30258
|
-
const AngleInput = props => {
|
|
30057
|
+
const LockedEllipseSettings = props => {
|
|
30259
30058
|
const {
|
|
30059
|
+
center,
|
|
30060
|
+
radius,
|
|
30260
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
|
+
}));
|
|
30164
|
+
};
|
|
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
|
|
30173
|
+
}
|
|
30174
|
+
});
|
|
30175
|
+
|
|
30176
|
+
const LabeledSwitch = props => {
|
|
30177
|
+
const {
|
|
30178
|
+
checked,
|
|
30179
|
+
label,
|
|
30180
|
+
style,
|
|
30261
30181
|
onChange
|
|
30262
30182
|
} = props;
|
|
30263
|
-
const
|
|
30264
|
-
const
|
|
30265
|
-
|
|
30266
|
-
|
|
30267
|
-
|
|
30268
|
-
|
|
30269
|
-
|
|
30270
|
-
|
|
30271
|
-
|
|
30272
|
-
|
|
30273
|
-
|
|
30274
|
-
|
|
30275
|
-
|
|
30276
|
-
|
|
30277
|
-
|
|
30278
|
-
|
|
30279
|
-
|
|
30280
|
-
|
|
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));
|
|
30197
|
+
};
|
|
30198
|
+
const styles$n = StyleSheet.create({
|
|
30199
|
+
row: {
|
|
30200
|
+
flexDirection: "row",
|
|
30201
|
+
alignItems: "center"
|
|
30202
|
+
}
|
|
30203
|
+
});
|
|
30204
|
+
|
|
30205
|
+
/**
|
|
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.
|
|
30208
|
+
*
|
|
30209
|
+
* Used in the interactive graph editor's locked figures section.
|
|
30210
|
+
*/
|
|
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
|
+
});
|
|
30281
30270
|
}
|
|
30282
|
-
}
|
|
30283
|
-
function handleAngleTypeChange() {
|
|
30284
|
-
// Change the angle based on the new angle type.
|
|
30285
|
-
handleAngleChange(angleInput, !isInDegrees);
|
|
30286
|
-
|
|
30287
|
-
// Update the angle to the new type.
|
|
30288
|
-
setIsInDegrees(usingDegrees => !usingDegrees);
|
|
30289
|
-
}
|
|
30290
|
-
return /*#__PURE__*/React.createElement(View, {
|
|
30291
|
-
style: [styles$q.row, styles$q.spaceUnder]
|
|
30292
|
-
}, /*#__PURE__*/React.createElement(LabelMedium, {
|
|
30293
|
-
tag: "label",
|
|
30294
|
-
style: styles$q.row
|
|
30295
|
-
}, "angle", /*#__PURE__*/React.createElement(Strut, {
|
|
30296
|
-
size: spacing.xxSmall_6
|
|
30297
|
-
}), /*#__PURE__*/React.createElement(TextField, {
|
|
30298
|
-
value: angleInput,
|
|
30299
|
-
onChange: handleAngleChange,
|
|
30300
|
-
style: styles$q.textField
|
|
30301
|
-
})), /*#__PURE__*/React.createElement(Strut, {
|
|
30302
|
-
size: spacing.xxSmall_6
|
|
30303
|
-
}), /*#__PURE__*/React.createElement(LabelSmall, null, "radians"), /*#__PURE__*/React.createElement(View, {
|
|
30304
|
-
style: styles$q.switch
|
|
30305
|
-
}, /*#__PURE__*/React.createElement(Switch, {
|
|
30306
|
-
onChange: handleAngleTypeChange,
|
|
30307
|
-
checked: isInDegrees
|
|
30308
|
-
})), /*#__PURE__*/React.createElement(LabelSmall, null, "degrees"), /*#__PURE__*/React.createElement(InfoTip$d, null, /*#__PURE__*/React.createElement("p", null, "The angle of rotation for the ellipse (if the x radius and y radius are different)."), /*#__PURE__*/React.createElement("p", null, "Expressions will be evaluted (e.g. \"pi/2\" or \"5pi/4\").")));
|
|
30271
|
+
})));
|
|
30309
30272
|
};
|
|
30310
|
-
const styles$
|
|
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
|
+
},
|
|
30311
30285
|
row: {
|
|
30312
|
-
display: "flex",
|
|
30313
30286
|
flexDirection: "row",
|
|
30314
30287
|
alignItems: "center"
|
|
30315
30288
|
},
|
|
30316
|
-
|
|
30317
|
-
|
|
30318
|
-
marginRight: spacing.xxSmall_6
|
|
30319
|
-
},
|
|
30320
|
-
textField: {
|
|
30321
|
-
maxWidth: spacing.xxxLarge_64
|
|
30289
|
+
spaceUnder: {
|
|
30290
|
+
marginBottom: spacing.xSmall_8
|
|
30322
30291
|
}
|
|
30323
30292
|
});
|
|
30324
30293
|
|
|
30325
|
-
const
|
|
30294
|
+
const LineSwatch = props => {
|
|
30326
30295
|
const {
|
|
30327
|
-
color
|
|
30328
|
-
|
|
30329
|
-
decorative = false
|
|
30296
|
+
color,
|
|
30297
|
+
lineStyle
|
|
30330
30298
|
} = props;
|
|
30331
30299
|
return /*#__PURE__*/React.createElement(View, {
|
|
30332
|
-
|
|
30333
|
-
|
|
30334
|
-
|
|
30335
|
-
style: [styles$
|
|
30336
|
-
border: `
|
|
30337
|
-
backgroundColor: filled ? lockedFigureColors[color$1] : color.white
|
|
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]}`
|
|
30338
30305
|
}]
|
|
30339
|
-
});
|
|
30306
|
+
}));
|
|
30340
30307
|
};
|
|
30341
|
-
const styles$
|
|
30342
|
-
|
|
30343
|
-
|
|
30344
|
-
|
|
30345
|
-
|
|
30346
|
-
borderRadius:
|
|
30347
|
-
|
|
30348
|
-
|
|
30308
|
+
const styles$l = StyleSheet.create({
|
|
30309
|
+
container: {
|
|
30310
|
+
backgroundColor: color.white,
|
|
30311
|
+
justifyContent: "center",
|
|
30312
|
+
padding: spacing.xSmall_8,
|
|
30313
|
+
borderRadius: spacing.xxxSmall_4
|
|
30314
|
+
},
|
|
30315
|
+
lineSwatch: {
|
|
30316
|
+
width: 40
|
|
30349
30317
|
}
|
|
30350
30318
|
});
|
|
30351
30319
|
|
|
30352
|
-
const
|
|
30353
|
-
const
|
|
30320
|
+
const lengthZeroStr = "The line cannot have length 0.";
|
|
30321
|
+
const LockedLineSettings = props => {
|
|
30354
30322
|
const {
|
|
30355
|
-
|
|
30356
|
-
|
|
30357
|
-
|
|
30323
|
+
kind,
|
|
30324
|
+
points,
|
|
30325
|
+
color: lineColor,
|
|
30326
|
+
lineStyle = "solid",
|
|
30327
|
+
showPoint1,
|
|
30328
|
+
showPoint2,
|
|
30329
|
+
onChangeProps,
|
|
30330
|
+
onMove,
|
|
30331
|
+
onRemove
|
|
30358
30332
|
} = props;
|
|
30359
|
-
|
|
30360
|
-
|
|
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]})`;
|
|
30337
|
+
|
|
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
|
+
});
|
|
30346
|
+
}
|
|
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
|
+
}))
|
|
30361
30369
|
}, /*#__PURE__*/React.createElement(LabelMedium, {
|
|
30362
30370
|
tag: "label",
|
|
30363
|
-
style: styles$
|
|
30364
|
-
}, "
|
|
30365
|
-
size: spacing.
|
|
30371
|
+
style: [styles$k.row, styles$k.spaceUnder]
|
|
30372
|
+
}, "kind", /*#__PURE__*/React.createElement(Strut, {
|
|
30373
|
+
size: spacing.xxxSmall_4
|
|
30366
30374
|
}), /*#__PURE__*/React.createElement(SingleSelect, {
|
|
30367
|
-
selectedValue:
|
|
30368
|
-
onChange:
|
|
30375
|
+
selectedValue: kind,
|
|
30376
|
+
onChange: value => onChangeProps({
|
|
30377
|
+
kind: value
|
|
30378
|
+
})
|
|
30369
30379
|
// Placeholder is required, but never gets used.
|
|
30370
30380
|
,
|
|
30371
30381
|
placeholder: ""
|
|
30372
|
-
},
|
|
30373
|
-
|
|
30374
|
-
|
|
30375
|
-
|
|
30376
|
-
|
|
30377
|
-
|
|
30378
|
-
|
|
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
|
|
30379
30407
|
})
|
|
30380
|
-
|
|
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
|
+
}));
|
|
30381
30444
|
};
|
|
30382
|
-
const styles$
|
|
30445
|
+
const styles$k = StyleSheet.create({
|
|
30383
30446
|
row: {
|
|
30384
30447
|
display: "flex",
|
|
30385
30448
|
flexDirection: "row",
|
|
30386
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
|
|
30387
30460
|
}
|
|
30388
30461
|
});
|
|
30389
30462
|
|
|
30390
|
-
|
|
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 => {
|
|
30391
30470
|
const {
|
|
30392
30471
|
coord,
|
|
30393
|
-
|
|
30394
|
-
|
|
30395
|
-
|
|
30472
|
+
color: pointColor,
|
|
30473
|
+
filled = true,
|
|
30474
|
+
onChangeProps,
|
|
30475
|
+
onMove,
|
|
30476
|
+
onRemove
|
|
30396
30477
|
} = props;
|
|
30397
|
-
|
|
30398
|
-
|
|
30399
|
-
|
|
30400
|
-
|
|
30401
|
-
|
|
30402
|
-
|
|
30403
|
-
|
|
30404
|
-
|
|
30405
|
-
|
|
30406
|
-
|
|
30407
|
-
|
|
30408
|
-
|
|
30409
|
-
|
|
30410
|
-
|
|
30411
|
-
|
|
30412
|
-
|
|
30478
|
+
function handleColorChange(newValue) {
|
|
30479
|
+
onChangeProps({
|
|
30480
|
+
color: newValue
|
|
30481
|
+
});
|
|
30482
|
+
}
|
|
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
|
+
});
|
|
30413
30504
|
}
|
|
30414
|
-
|
|
30415
|
-
|
|
30416
|
-
|
|
30417
|
-
|
|
30418
|
-
|
|
30419
|
-
|
|
30420
|
-
|
|
30421
|
-
|
|
30422
|
-
|
|
30423
|
-
|
|
30424
|
-
|
|
30425
|
-
|
|
30426
|
-
|
|
30427
|
-
|
|
30428
|
-
|
|
30429
|
-
|
|
30430
|
-
|
|
30431
|
-
|
|
30432
|
-
})), /*#__PURE__*/React.createElement(Strut, {
|
|
30433
|
-
size: spacing.medium_16
|
|
30434
|
-
}), /*#__PURE__*/React.createElement(LabelMedium, {
|
|
30435
|
-
tag: "label",
|
|
30436
|
-
style: styles$n.row
|
|
30437
|
-
}, labels ? labels[1] : "y coord", /*#__PURE__*/React.createElement(Strut, {
|
|
30438
|
-
size: spacing.xxSmall_6
|
|
30439
|
-
}), /*#__PURE__*/React.createElement(TextField, {
|
|
30440
|
-
type: "number",
|
|
30441
|
-
value: coordState[1],
|
|
30442
|
-
onChange: newValue => handleCoordChange(newValue, 1),
|
|
30443
|
-
style: [styles$n.textField, error ? styles$n.errorField : undefined]
|
|
30444
|
-
}))));
|
|
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
|
|
30522
|
+
}));
|
|
30445
30523
|
};
|
|
30446
|
-
const styles$
|
|
30524
|
+
const styles$j = StyleSheet.create({
|
|
30447
30525
|
row: {
|
|
30448
|
-
display: "flex",
|
|
30449
30526
|
flexDirection: "row",
|
|
30450
30527
|
alignItems: "center"
|
|
30451
30528
|
},
|
|
30452
30529
|
spaceUnder: {
|
|
30453
30530
|
marginBottom: spacing.xSmall_8
|
|
30454
|
-
},
|
|
30455
|
-
textField: {
|
|
30456
|
-
width: spacing.xxxLarge_64
|
|
30457
|
-
},
|
|
30458
|
-
errorField: {
|
|
30459
|
-
borderColor: color.red,
|
|
30460
|
-
backgroundColor: color.fadedRed8
|
|
30461
30531
|
}
|
|
30462
30532
|
});
|
|
30463
30533
|
|
|
30464
|
-
const
|
|
30534
|
+
const PolygonSwatch = props => {
|
|
30465
30535
|
const {
|
|
30466
30536
|
color,
|
|
30467
30537
|
fillStyle,
|
|
@@ -30469,128 +30539,44 @@ const EllipseSwatch = props => {
|
|
|
30469
30539
|
} = props;
|
|
30470
30540
|
return /*#__PURE__*/React.createElement(View, {
|
|
30471
30541
|
"aria-label": `${color}, stroke ${strokeStyle}, fill ${fillStyle}`,
|
|
30472
|
-
style: [styles$
|
|
30542
|
+
style: [styles$i.container, {
|
|
30473
30543
|
border: `4px ${strokeStyle} ${lockedFigureColors[color]}`
|
|
30474
30544
|
}]
|
|
30475
30545
|
}, /*#__PURE__*/React.createElement(View, {
|
|
30476
|
-
style: [styles$
|
|
30546
|
+
style: [styles$i.innerSquare, {
|
|
30477
30547
|
backgroundColor: lockedFigureColors[color],
|
|
30478
|
-
opacity:
|
|
30548
|
+
opacity: lockedFigureFillStyles[fillStyle]
|
|
30479
30549
|
}]
|
|
30480
30550
|
}));
|
|
30481
30551
|
};
|
|
30482
|
-
const styles$
|
|
30552
|
+
const styles$i = StyleSheet.create({
|
|
30483
30553
|
container: {
|
|
30484
30554
|
// Add a white outline so that the color swatch is visible when
|
|
30485
30555
|
// the dropdown option is highlighted with its blue background.
|
|
30486
30556
|
outline: `2px solid ${color.offWhite}`,
|
|
30487
|
-
|
|
30488
|
-
width: spacing.xLarge_32,
|
|
30557
|
+
width: spacing.large_24,
|
|
30489
30558
|
height: spacing.large_24,
|
|
30490
30559
|
backgroundColor: color.white,
|
|
30491
30560
|
alignItems: "center",
|
|
30492
30561
|
justifyContent: "center"
|
|
30493
30562
|
},
|
|
30494
|
-
|
|
30495
|
-
width:
|
|
30496
|
-
height: 20
|
|
30497
|
-
borderRadius: "50%"
|
|
30498
|
-
}
|
|
30499
|
-
});
|
|
30500
|
-
|
|
30501
|
-
const LockedFigureSettingsAccordion = props => {
|
|
30502
|
-
const {
|
|
30503
|
-
children,
|
|
30504
|
-
header,
|
|
30505
|
-
expanded,
|
|
30506
|
-
containerStyle,
|
|
30507
|
-
panelStyle,
|
|
30508
|
-
onToggle
|
|
30509
|
-
} = props;
|
|
30510
|
-
return /*#__PURE__*/React.createElement(View
|
|
30511
|
-
// More specificity so that we can override the default
|
|
30512
|
-
// .heading > h2 > .header styles from the articles.less
|
|
30513
|
-
// file (which is imported in perseus-renderer.less).
|
|
30514
|
-
, {
|
|
30515
|
-
className: "locked-figure-accordion"
|
|
30516
|
-
}, /*#__PURE__*/React.createElement(AccordionSection, {
|
|
30517
|
-
expanded: expanded,
|
|
30518
|
-
onToggle: onToggle,
|
|
30519
|
-
style: [styles$l.container, containerStyle],
|
|
30520
|
-
headerStyle: styles$l.accordionHeader,
|
|
30521
|
-
header: header
|
|
30522
|
-
}, /*#__PURE__*/React.createElement(View, {
|
|
30523
|
-
style: [styles$l.accordionPanel, panelStyle]
|
|
30524
|
-
}, children)));
|
|
30525
|
-
};
|
|
30526
|
-
const styles$l = StyleSheet.create({
|
|
30527
|
-
container: {
|
|
30528
|
-
backgroundColor: color.fadedBlue8,
|
|
30529
|
-
marginTop: spacing.xSmall_8
|
|
30530
|
-
},
|
|
30531
|
-
accordionHeader: {
|
|
30532
|
-
padding: spacing.small_12,
|
|
30533
|
-
// Don't move the dropdown caret.
|
|
30534
|
-
paddingInlineEnd: 0,
|
|
30535
|
-
// Fixed height so the addition of the color swatch doesn't
|
|
30536
|
-
// change the height of the header when toggling.
|
|
30537
|
-
height: spacing.xxLarge_48
|
|
30538
|
-
},
|
|
30539
|
-
accordionPanel: {
|
|
30540
|
-
paddingTop: spacing.xxSmall_6,
|
|
30541
|
-
paddingBottom: spacing.xxxSmall_4,
|
|
30542
|
-
paddingLeft: spacing.small_12,
|
|
30543
|
-
paddingRight: spacing.small_12
|
|
30544
|
-
}
|
|
30545
|
-
});
|
|
30546
|
-
|
|
30547
|
-
/**
|
|
30548
|
-
* The part of a locked figure settings panel that contains actions
|
|
30549
|
-
* for this panel and its associated locked figure, including
|
|
30550
|
-
* the delete button.
|
|
30551
|
-
*/
|
|
30552
|
-
const LockedFigureSettingsActions = props => {
|
|
30553
|
-
const {
|
|
30554
|
-
onRemove,
|
|
30555
|
-
figureAriaLabel
|
|
30556
|
-
} = props;
|
|
30557
|
-
return /*#__PURE__*/React.createElement(View, {
|
|
30558
|
-
style: styles$k.container
|
|
30559
|
-
}, /*#__PURE__*/React.createElement(Button, {
|
|
30560
|
-
startIcon: trashIcon,
|
|
30561
|
-
"aria-label": `Delete ${figureAriaLabel}`,
|
|
30562
|
-
onClick: onRemove,
|
|
30563
|
-
kind: "tertiary",
|
|
30564
|
-
style: styles$k.deleteButton
|
|
30565
|
-
}, "Delete"));
|
|
30566
|
-
};
|
|
30567
|
-
const styles$k = StyleSheet.create({
|
|
30568
|
-
container: {
|
|
30569
|
-
width: "100%",
|
|
30570
|
-
flexDirection: "row",
|
|
30571
|
-
alignItems: "center",
|
|
30572
|
-
marginTop: spacing.xxxSmall_4
|
|
30573
|
-
},
|
|
30574
|
-
deleteButton: {
|
|
30575
|
-
// Line up the delete icon with the rest of the content.
|
|
30576
|
-
marginInlineStart: -spacing.xxxSmall_4
|
|
30563
|
+
innerSquare: {
|
|
30564
|
+
width: 20,
|
|
30565
|
+
height: 20
|
|
30577
30566
|
}
|
|
30578
30567
|
});
|
|
30579
30568
|
|
|
30580
|
-
const {
|
|
30581
|
-
InfoTip: InfoTip$c
|
|
30582
|
-
} = components;
|
|
30583
|
-
const LockedEllipseSettings = props => {
|
|
30569
|
+
const LockedPolygonSettings = props => {
|
|
30584
30570
|
const {
|
|
30585
|
-
|
|
30586
|
-
radius,
|
|
30587
|
-
angle,
|
|
30571
|
+
points,
|
|
30588
30572
|
color,
|
|
30573
|
+
showVertices,
|
|
30589
30574
|
fillStyle,
|
|
30590
30575
|
strokeStyle,
|
|
30591
30576
|
expanded,
|
|
30592
30577
|
onToggle,
|
|
30593
30578
|
onChangeProps,
|
|
30579
|
+
onMove,
|
|
30594
30580
|
onRemove
|
|
30595
30581
|
} = props;
|
|
30596
30582
|
function handleColorChange(newValue) {
|
|
@@ -30603,40 +30589,18 @@ const LockedEllipseSettings = props => {
|
|
|
30603
30589
|
onToggle: onToggle,
|
|
30604
30590
|
header:
|
|
30605
30591
|
/*#__PURE__*/
|
|
30606
|
-
// Summary:
|
|
30592
|
+
// Summary: Polygon, number of sides, style swatch
|
|
30607
30593
|
React.createElement(View, {
|
|
30608
|
-
style: styles$
|
|
30609
|
-
}, /*#__PURE__*/React.createElement(LabelLarge, null, `
|
|
30594
|
+
style: styles$h.row
|
|
30595
|
+
}, /*#__PURE__*/React.createElement(LabelLarge, null, `Polygon, ${points.length} sides`), /*#__PURE__*/React.createElement(Strut, {
|
|
30610
30596
|
size: spacing.xSmall_8
|
|
30611
|
-
}), /*#__PURE__*/React.createElement(
|
|
30612
|
-
color:
|
|
30597
|
+
}), /*#__PURE__*/React.createElement(PolygonSwatch, {
|
|
30598
|
+
color: color,
|
|
30613
30599
|
fillStyle: fillStyle,
|
|
30614
30600
|
strokeStyle: strokeStyle
|
|
30615
30601
|
}))
|
|
30616
30602
|
}, /*#__PURE__*/React.createElement(View, {
|
|
30617
|
-
style: styles$
|
|
30618
|
-
}, /*#__PURE__*/React.createElement(CoordinatePairInput, {
|
|
30619
|
-
coord: center,
|
|
30620
|
-
onChange: newCoords => onChangeProps({
|
|
30621
|
-
center: newCoords
|
|
30622
|
-
})
|
|
30623
|
-
}), /*#__PURE__*/React.createElement(View, {
|
|
30624
|
-
style: styles$j.spaceUnder
|
|
30625
|
-
}, /*#__PURE__*/React.createElement(InfoTip$c, null, "The coordinates for the center of the ellipse."))), /*#__PURE__*/React.createElement(CoordinatePairInput, {
|
|
30626
|
-
coord: radius,
|
|
30627
|
-
labels: ["x radius", "y radius"],
|
|
30628
|
-
onChange: newCoords => onChangeProps({
|
|
30629
|
-
radius: newCoords
|
|
30630
|
-
})
|
|
30631
|
-
}), /*#__PURE__*/React.createElement(AngleInput, {
|
|
30632
|
-
angle: angle,
|
|
30633
|
-
onChange: newAngle => onChangeProps({
|
|
30634
|
-
angle: newAngle
|
|
30635
|
-
})
|
|
30636
|
-
}), /*#__PURE__*/React.createElement(Strut, {
|
|
30637
|
-
size: spacing.xSmall_8
|
|
30638
|
-
}), /*#__PURE__*/React.createElement(View, {
|
|
30639
|
-
style: [styles$j.row, styles$j.spaceUnder]
|
|
30603
|
+
style: [styles$h.row, styles$h.spaceUnder]
|
|
30640
30604
|
}, /*#__PURE__*/React.createElement(ColorSelect, {
|
|
30641
30605
|
selectedValue: color,
|
|
30642
30606
|
onChange: handleColorChange
|
|
@@ -30644,7 +30608,7 @@ const LockedEllipseSettings = props => {
|
|
|
30644
30608
|
size: spacing.medium_16
|
|
30645
30609
|
}), /*#__PURE__*/React.createElement(LabelMedium, {
|
|
30646
30610
|
tag: "label",
|
|
30647
|
-
style: styles$
|
|
30611
|
+
style: styles$h.row
|
|
30648
30612
|
}, "fill", /*#__PURE__*/React.createElement(Strut, {
|
|
30649
30613
|
size: spacing.xxSmall_6
|
|
30650
30614
|
}), /*#__PURE__*/React.createElement(SingleSelect, {
|
|
@@ -30655,13 +30619,13 @@ const LockedEllipseSettings = props => {
|
|
|
30655
30619
|
// Placeholder is required, but never gets used.
|
|
30656
30620
|
,
|
|
30657
30621
|
placeholder: ""
|
|
30658
|
-
}, Object.keys(
|
|
30622
|
+
}, Object.keys(lockedFigureFillStyles).map(option => /*#__PURE__*/React.createElement(OptionItem, {
|
|
30659
30623
|
key: option,
|
|
30660
30624
|
value: option,
|
|
30661
30625
|
label: option
|
|
30662
30626
|
}, option))))), /*#__PURE__*/React.createElement(LabelMedium, {
|
|
30663
30627
|
tag: "label",
|
|
30664
|
-
style: styles$
|
|
30628
|
+
style: [styles$h.row, styles$h.spaceUnder]
|
|
30665
30629
|
}, "stroke", /*#__PURE__*/React.createElement(Strut, {
|
|
30666
30630
|
size: spacing.xxSmall_6
|
|
30667
30631
|
}), /*#__PURE__*/React.createElement(SingleSelect, {
|
|
@@ -30678,117 +30642,178 @@ const LockedEllipseSettings = props => {
|
|
|
30678
30642
|
}, "solid"), /*#__PURE__*/React.createElement(OptionItem, {
|
|
30679
30643
|
value: "dashed",
|
|
30680
30644
|
label: "dashed"
|
|
30681
|
-
}, "dashed"))), /*#__PURE__*/React.createElement(
|
|
30682
|
-
|
|
30683
|
-
|
|
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
|
|
30684
30704
|
}));
|
|
30685
30705
|
};
|
|
30686
|
-
const styles$
|
|
30706
|
+
const styles$h = StyleSheet.create({
|
|
30687
30707
|
row: {
|
|
30688
30708
|
display: "flex",
|
|
30689
30709
|
flexDirection: "row",
|
|
30690
30710
|
alignItems: "center"
|
|
30691
30711
|
},
|
|
30712
|
+
pointAccordionContainer: {
|
|
30713
|
+
backgroundColor: color.white
|
|
30714
|
+
},
|
|
30715
|
+
pointAccordionPanel: {
|
|
30716
|
+
alignItems: "start"
|
|
30717
|
+
},
|
|
30718
|
+
icon: {
|
|
30719
|
+
marginInlineStart: spacing.xxxSmall_4
|
|
30720
|
+
},
|
|
30692
30721
|
spaceUnder: {
|
|
30693
30722
|
marginBottom: spacing.xSmall_8
|
|
30694
30723
|
}
|
|
30695
30724
|
});
|
|
30696
30725
|
|
|
30697
|
-
const LabeledSwitch = props => {
|
|
30698
|
-
const {
|
|
30699
|
-
checked,
|
|
30700
|
-
label,
|
|
30701
|
-
style,
|
|
30702
|
-
onChange
|
|
30703
|
-
} = props;
|
|
30704
|
-
const ids = useUniqueIdWithMock();
|
|
30705
|
-
const switchId = ids.get("switch");
|
|
30706
|
-
return /*#__PURE__*/React.createElement(View, {
|
|
30707
|
-
style: [styles$i.row, style]
|
|
30708
|
-
}, /*#__PURE__*/React.createElement(Switch, {
|
|
30709
|
-
id: switchId,
|
|
30710
|
-
checked: checked,
|
|
30711
|
-
onChange: onChange
|
|
30712
|
-
}), /*#__PURE__*/React.createElement(Strut, {
|
|
30713
|
-
size: spacing.xSmall_8
|
|
30714
|
-
}), /*#__PURE__*/React.createElement(LabelMedium, {
|
|
30715
|
-
tag: "label",
|
|
30716
|
-
htmlFor: switchId
|
|
30717
|
-
}, label));
|
|
30718
|
-
};
|
|
30719
|
-
const styles$i = StyleSheet.create({
|
|
30720
|
-
row: {
|
|
30721
|
-
flexDirection: "row",
|
|
30722
|
-
alignItems: "center"
|
|
30723
|
-
}
|
|
30724
|
-
});
|
|
30725
|
-
|
|
30726
30726
|
/**
|
|
30727
|
-
*
|
|
30728
|
-
* settings of
|
|
30727
|
+
* LockedVectorSettings is a component that allows the user to edit the
|
|
30728
|
+
* settings of specifically a locked vector on the graph.
|
|
30729
30729
|
*
|
|
30730
30730
|
* Used in the interactive graph editor's locked figures section.
|
|
30731
30731
|
*/
|
|
30732
|
-
const
|
|
30732
|
+
const lengthErrorMessage = "The vector cannot have length 0.";
|
|
30733
|
+
const LockedVectorSettings = props => {
|
|
30733
30734
|
const {
|
|
30734
|
-
|
|
30735
|
-
color:
|
|
30736
|
-
filled = true,
|
|
30737
|
-
label,
|
|
30738
|
-
showPoint = "false",
|
|
30739
|
-
error,
|
|
30735
|
+
points,
|
|
30736
|
+
color: lineColor,
|
|
30740
30737
|
onChangeProps,
|
|
30741
|
-
|
|
30738
|
+
onMove,
|
|
30739
|
+
onRemove
|
|
30742
30740
|
} = props;
|
|
30743
|
-
|
|
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) {
|
|
30744
30756
|
onChangeProps({
|
|
30745
|
-
color:
|
|
30757
|
+
color: newColor
|
|
30746
30758
|
});
|
|
30747
30759
|
}
|
|
30748
30760
|
return /*#__PURE__*/React.createElement(LockedFigureSettingsAccordion, {
|
|
30749
30761
|
expanded: props.expanded,
|
|
30750
30762
|
onToggle: props.onToggle,
|
|
30751
|
-
|
|
30752
|
-
|
|
30753
|
-
|
|
30754
|
-
/*#__PURE__*/
|
|
30755
|
-
// Summary: Point, coords, color (filled/open)
|
|
30756
|
-
React.createElement(View, {
|
|
30757
|
-
style: styles$h.row
|
|
30758
|
-
}, /*#__PURE__*/React.createElement(LabelLarge, null, `${label || "Point"} (${coord[0]}, ${coord[1]})`), /*#__PURE__*/React.createElement(Strut, {
|
|
30763
|
+
header: /*#__PURE__*/React.createElement(View, {
|
|
30764
|
+
style: styles$g.row
|
|
30765
|
+
}, /*#__PURE__*/React.createElement(LabelLarge, null, lineLabel), /*#__PURE__*/React.createElement(Strut, {
|
|
30759
30766
|
size: spacing.xSmall_8
|
|
30760
|
-
}),
|
|
30761
|
-
color:
|
|
30762
|
-
|
|
30767
|
+
}), /*#__PURE__*/React.createElement(LineSwatch, {
|
|
30768
|
+
color: lineColor,
|
|
30769
|
+
lineStyle: "solid"
|
|
30763
30770
|
}))
|
|
30771
|
+
}, /*#__PURE__*/React.createElement(View, {
|
|
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]})`))
|
|
30764
30786
|
}, /*#__PURE__*/React.createElement(CoordinatePairInput, {
|
|
30765
|
-
coord:
|
|
30766
|
-
error:
|
|
30767
|
-
onChange:
|
|
30768
|
-
|
|
30769
|
-
coord: newCoords
|
|
30770
|
-
});
|
|
30787
|
+
coord: tail,
|
|
30788
|
+
error: isInvalid,
|
|
30789
|
+
onChange: newProps => {
|
|
30790
|
+
handleChangePoint(newProps, 0);
|
|
30771
30791
|
}
|
|
30772
|
-
}),
|
|
30773
|
-
|
|
30774
|
-
|
|
30775
|
-
|
|
30776
|
-
|
|
30777
|
-
|
|
30778
|
-
|
|
30779
|
-
|
|
30780
|
-
|
|
30781
|
-
|
|
30782
|
-
|
|
30783
|
-
|
|
30784
|
-
|
|
30785
|
-
onChangeProps({
|
|
30786
|
-
filled: !newValue
|
|
30787
|
-
});
|
|
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);
|
|
30788
30805
|
}
|
|
30789
|
-
}))
|
|
30806
|
+
})), /*#__PURE__*/React.createElement(LockedFigureSettingsActions, {
|
|
30807
|
+
showM2Features: props.showM2Features,
|
|
30808
|
+
figureType: props.type,
|
|
30809
|
+
onMove: onMove,
|
|
30810
|
+
onRemove: onRemove
|
|
30811
|
+
}));
|
|
30790
30812
|
};
|
|
30791
|
-
const styles$
|
|
30813
|
+
const styles$g = StyleSheet.create({
|
|
30814
|
+
accordionPanel: {
|
|
30815
|
+
paddingBottom: spacing.medium_16
|
|
30816
|
+
},
|
|
30792
30817
|
container: {
|
|
30793
30818
|
marginTop: spacing.xSmall_8,
|
|
30794
30819
|
marginBottom: 0,
|
|
@@ -30796,557 +30821,822 @@ const styles$h = StyleSheet.create({
|
|
|
30796
30821
|
marginRight: -spacing.xxxSmall_4,
|
|
30797
30822
|
backgroundColor: color.white
|
|
30798
30823
|
},
|
|
30799
|
-
|
|
30800
|
-
|
|
30801
|
-
|
|
30824
|
+
errorText: {
|
|
30825
|
+
color: color.red,
|
|
30826
|
+
marginTop: spacing.xSmall_8
|
|
30802
30827
|
},
|
|
30803
30828
|
row: {
|
|
30804
30829
|
flexDirection: "row",
|
|
30805
30830
|
alignItems: "center"
|
|
30806
|
-
},
|
|
30807
|
-
spaceUnder: {
|
|
30808
|
-
marginBottom: spacing.xSmall_8
|
|
30809
30831
|
}
|
|
30810
30832
|
});
|
|
30811
30833
|
|
|
30812
|
-
|
|
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");
|
|
30813
30874
|
const {
|
|
30814
|
-
|
|
30815
|
-
|
|
30875
|
+
figures,
|
|
30876
|
+
onChange
|
|
30816
30877
|
} = props;
|
|
30817
|
-
|
|
30818
|
-
|
|
30819
|
-
|
|
30820
|
-
|
|
30821
|
-
|
|
30822
|
-
|
|
30823
|
-
|
|
30824
|
-
}
|
|
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);
|
|
30952
|
+
}
|
|
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)));
|
|
30825
30989
|
};
|
|
30826
|
-
const styles$
|
|
30827
|
-
|
|
30828
|
-
|
|
30829
|
-
|
|
30830
|
-
padding: spacing.xSmall_8,
|
|
30831
|
-
borderRadius: spacing.xxxSmall_4
|
|
30990
|
+
const styles$f = StyleSheet.create({
|
|
30991
|
+
buttonContainer: {
|
|
30992
|
+
flexDirection: "row",
|
|
30993
|
+
alignItems: "center"
|
|
30832
30994
|
},
|
|
30833
|
-
|
|
30834
|
-
|
|
30995
|
+
button: {
|
|
30996
|
+
marginTop: spacing.xSmall_8,
|
|
30997
|
+
flexGrow: 1
|
|
30998
|
+
}
|
|
30999
|
+
});
|
|
31000
|
+
|
|
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;
|
|
31009
|
+
}
|
|
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
|
|
31023
|
+
,
|
|
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
|
+
})]);
|
|
31035
|
+
};
|
|
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
|
|
30835
31041
|
}
|
|
30836
31042
|
});
|
|
30837
31043
|
|
|
30838
|
-
const
|
|
30839
|
-
|
|
30840
|
-
|
|
30841
|
-
|
|
30842
|
-
|
|
30843
|
-
|
|
30844
|
-
lineStyle = "solid",
|
|
30845
|
-
showPoint1,
|
|
30846
|
-
showPoint2,
|
|
30847
|
-
onChangeProps,
|
|
30848
|
-
onRemove
|
|
30849
|
-
} = props;
|
|
30850
|
-
const [point1, point2] = points;
|
|
30851
|
-
const capitalizeKind = kind.charAt(0).toUpperCase() + kind.slice(1);
|
|
30852
|
-
const lineLabel = `${capitalizeKind} (${point1.coord[0]},
|
|
30853
|
-
${point1.coord[1]}), (${point2.coord[0]}, ${point2.coord[1]})`;
|
|
30854
|
-
|
|
30855
|
-
// Check if the line has length 0.
|
|
30856
|
-
const isInvalid = vector.equal(point1.coord, point2.coord);
|
|
30857
|
-
function handleChangePoint(newPointProps, index) {
|
|
30858
|
-
const newPoints = [...points];
|
|
30859
|
-
newPoints[index] = _extends({}, points[index], newPointProps);
|
|
30860
|
-
onChangeProps({
|
|
30861
|
-
points: newPoints
|
|
30862
|
-
});
|
|
30863
|
-
}
|
|
30864
|
-
function handleColorChange(newColor) {
|
|
30865
|
-
onChangeProps({
|
|
30866
|
-
color: newColor,
|
|
30867
|
-
// Keep the line's points' colors in sync with the line color.
|
|
30868
|
-
points: [_extends({}, point1, {
|
|
30869
|
-
color: newColor
|
|
30870
|
-
}), _extends({}, point2, {
|
|
30871
|
-
color: newColor
|
|
30872
|
-
})]
|
|
30873
|
-
});
|
|
30874
|
-
}
|
|
30875
|
-
return /*#__PURE__*/React.createElement(LockedFigureSettingsAccordion, {
|
|
30876
|
-
expanded: props.expanded,
|
|
30877
|
-
onToggle: props.onToggle,
|
|
30878
|
-
header: /*#__PURE__*/React.createElement(View, {
|
|
30879
|
-
style: styles$f.row
|
|
30880
|
-
}, /*#__PURE__*/React.createElement(LabelLarge, null, lineLabel), /*#__PURE__*/React.createElement(Strut, {
|
|
30881
|
-
size: spacing.xSmall_8
|
|
30882
|
-
}), /*#__PURE__*/React.createElement(LineSwatch, {
|
|
30883
|
-
color: lineColor,
|
|
30884
|
-
lineStyle: lineStyle
|
|
30885
|
-
}))
|
|
30886
|
-
}, /*#__PURE__*/React.createElement(LabelMedium, {
|
|
30887
|
-
tag: "label",
|
|
30888
|
-
style: [styles$f.row, styles$f.spaceUnder]
|
|
30889
|
-
}, "kind", /*#__PURE__*/React.createElement(Strut, {
|
|
30890
|
-
size: spacing.xxxSmall_4
|
|
30891
|
-
}), /*#__PURE__*/React.createElement(SingleSelect, {
|
|
30892
|
-
selectedValue: kind,
|
|
30893
|
-
onChange: value => onChangeProps({
|
|
30894
|
-
kind: value
|
|
30895
|
-
})
|
|
30896
|
-
// Placeholder is required, but never gets used.
|
|
30897
|
-
,
|
|
30898
|
-
placeholder: ""
|
|
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
|
|
30899
31050
|
}, /*#__PURE__*/React.createElement(OptionItem, {
|
|
30900
|
-
value: "
|
|
30901
|
-
label: "
|
|
31051
|
+
value: "linear",
|
|
31052
|
+
label: "Linear function"
|
|
30902
31053
|
}), /*#__PURE__*/React.createElement(OptionItem, {
|
|
30903
|
-
value: "
|
|
30904
|
-
label: "
|
|
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"
|
|
30905
31071
|
}), /*#__PURE__*/React.createElement(OptionItem, {
|
|
30906
31072
|
value: "segment",
|
|
30907
|
-
label: "
|
|
30908
|
-
}))), /*#__PURE__*/React.createElement(View, {
|
|
30909
|
-
style: styles$f.row
|
|
30910
|
-
}, /*#__PURE__*/React.createElement(ColorSelect, {
|
|
30911
|
-
selectedValue: lineColor,
|
|
30912
|
-
onChange: handleColorChange
|
|
30913
|
-
}), /*#__PURE__*/React.createElement(Strut, {
|
|
30914
|
-
size: spacing.small_12
|
|
30915
|
-
}), /*#__PURE__*/React.createElement(LabelMedium, {
|
|
30916
|
-
tag: "label",
|
|
30917
|
-
style: styles$f.row
|
|
30918
|
-
}, "style", /*#__PURE__*/React.createElement(Strut, {
|
|
30919
|
-
size: spacing.xxxSmall_4
|
|
30920
|
-
}), /*#__PURE__*/React.createElement(SingleSelect, {
|
|
30921
|
-
selectedValue: lineStyle,
|
|
30922
|
-
onChange: value => onChangeProps({
|
|
30923
|
-
lineStyle: value
|
|
30924
|
-
})
|
|
30925
|
-
// Placeholder is required, but never gets used.
|
|
30926
|
-
,
|
|
30927
|
-
placeholder: "",
|
|
30928
|
-
style: styles$f.selectMarginOffset
|
|
30929
|
-
}, /*#__PURE__*/React.createElement(OptionItem, {
|
|
30930
|
-
value: "solid",
|
|
30931
|
-
label: "solid"
|
|
31073
|
+
label: "Line Segment(s)"
|
|
30932
31074
|
}), /*#__PURE__*/React.createElement(OptionItem, {
|
|
30933
|
-
value: "
|
|
30934
|
-
label: "
|
|
30935
|
-
})
|
|
30936
|
-
|
|
30937
|
-
|
|
30938
|
-
label: "Point 1",
|
|
30939
|
-
showPoint: showPoint1,
|
|
30940
|
-
error: isInvalid ? lengthZeroStr : null
|
|
30941
|
-
}, point1, {
|
|
30942
|
-
onTogglePoint: newValue => onChangeProps({
|
|
30943
|
-
showPoint1: newValue
|
|
30944
|
-
}),
|
|
30945
|
-
onChangeProps: newProps => handleChangePoint(newProps, 0)
|
|
30946
|
-
})), /*#__PURE__*/React.createElement(DefiningPointSettings, _extends({
|
|
30947
|
-
label: "Point 2",
|
|
30948
|
-
showPoint: showPoint2,
|
|
30949
|
-
error: isInvalid ? lengthZeroStr : null
|
|
30950
|
-
}, point2, {
|
|
30951
|
-
onTogglePoint: newValue => onChangeProps({
|
|
30952
|
-
showPoint2: newValue
|
|
30953
|
-
}),
|
|
30954
|
-
onChangeProps: newProps => handleChangePoint(newProps, 1)
|
|
30955
|
-
})), /*#__PURE__*/React.createElement(LockedFigureSettingsActions, {
|
|
30956
|
-
onRemove: onRemove,
|
|
30957
|
-
figureAriaLabel: `locked line defined by
|
|
30958
|
-
${point1.coord[0]}, ${point1.coord[1]} and
|
|
30959
|
-
${point2.coord[0]}, ${point2.coord[1]}.`
|
|
31075
|
+
value: "ray",
|
|
31076
|
+
label: "Ray"
|
|
31077
|
+
}), /*#__PURE__*/React.createElement(OptionItem, {
|
|
31078
|
+
value: "angle",
|
|
31079
|
+
label: "Angle"
|
|
30960
31080
|
}));
|
|
30961
31081
|
};
|
|
30962
|
-
const styles$
|
|
30963
|
-
|
|
30964
|
-
|
|
30965
|
-
|
|
30966
|
-
|
|
30967
|
-
spaceUnder: {
|
|
30968
|
-
marginBottom: spacing.xSmall_8
|
|
30969
|
-
},
|
|
30970
|
-
selectMarginOffset: {
|
|
30971
|
-
// Align with the point settings accordions.
|
|
30972
|
-
marginInlineEnd: -spacing.xxxSmall_4
|
|
30973
|
-
},
|
|
30974
|
-
errorText: {
|
|
30975
|
-
color: color.red
|
|
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
|
|
30976
31087
|
}
|
|
30977
31088
|
});
|
|
30978
31089
|
|
|
30979
|
-
|
|
30980
|
-
|
|
30981
|
-
|
|
30982
|
-
|
|
30983
|
-
|
|
30984
|
-
|
|
30985
|
-
const
|
|
30986
|
-
|
|
30987
|
-
|
|
30988
|
-
|
|
30989
|
-
|
|
30990
|
-
|
|
30991
|
-
|
|
30992
|
-
|
|
30993
|
-
|
|
30994
|
-
|
|
30995
|
-
|
|
30996
|
-
|
|
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
|
+
};
|
|
30997
31139
|
}
|
|
30998
|
-
|
|
30999
|
-
|
|
31000
|
-
|
|
31001
|
-
|
|
31002
|
-
/*#__PURE__*/
|
|
31003
|
-
|
|
31004
|
-
|
|
31005
|
-
|
|
31006
|
-
}
|
|
31007
|
-
|
|
31008
|
-
|
|
31009
|
-
|
|
31010
|
-
|
|
31011
|
-
|
|
31012
|
-
}, /*#__PURE__*/React.createElement(CoordinatePairInput, {
|
|
31013
|
-
coord: coord,
|
|
31014
|
-
onChange: newCoord => {
|
|
31015
|
-
onChangeProps({
|
|
31016
|
-
coord: newCoord
|
|
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
|
|
31017
31154
|
});
|
|
31018
|
-
}
|
|
31019
|
-
|
|
31020
|
-
|
|
31021
|
-
|
|
31022
|
-
style: styles$e.spaceUnder
|
|
31023
|
-
}), /*#__PURE__*/React.createElement(LabeledSwitch, {
|
|
31024
|
-
label: "open point",
|
|
31025
|
-
checked: !filled,
|
|
31026
|
-
onChange: newValue => {
|
|
31027
|
-
onChangeProps({
|
|
31028
|
-
filled: !newValue
|
|
31155
|
+
};
|
|
31156
|
+
this.changeRulerTicks = e => {
|
|
31157
|
+
this.change({
|
|
31158
|
+
rulerTicks: +e.target.value
|
|
31029
31159
|
});
|
|
31030
|
-
}
|
|
31031
|
-
|
|
31032
|
-
|
|
31033
|
-
|
|
31034
|
-
|
|
31035
|
-
|
|
31036
|
-
|
|
31037
|
-
|
|
31038
|
-
|
|
31039
|
-
|
|
31040
|
-
|
|
31041
|
-
|
|
31042
|
-
|
|
31043
|
-
|
|
31044
|
-
|
|
31045
|
-
|
|
31046
|
-
|
|
31047
|
-
|
|
31048
|
-
|
|
31049
|
-
|
|
31050
|
-
|
|
31051
|
-
|
|
31052
|
-
|
|
31053
|
-
|
|
31054
|
-
|
|
31055
|
-
|
|
31056
|
-
|
|
31057
|
-
|
|
31058
|
-
|
|
31059
|
-
|
|
31060
|
-
|
|
31061
|
-
|
|
31062
|
-
|
|
31063
|
-
|
|
31064
|
-
|
|
31065
|
-
|
|
31066
|
-
|
|
31067
|
-
const newPoints = [...points];
|
|
31068
|
-
newPoints[index] = [...newCoord];
|
|
31069
|
-
onChangeProps({
|
|
31070
|
-
points: newPoints
|
|
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);
|
|
31071
31197
|
});
|
|
31072
|
-
|
|
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;
|
|
31288
|
+
});
|
|
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;
|
|
31356
|
+
|
|
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));
|
|
31073
31383
|
}
|
|
31074
|
-
|
|
31075
|
-
|
|
31076
|
-
|
|
31077
|
-
|
|
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);
|
|
31078
31389
|
}
|
|
31079
|
-
|
|
31080
|
-
|
|
31081
|
-
|
|
31082
|
-
|
|
31083
|
-
|
|
31084
|
-
}, /*#__PURE__*/React.createElement(LabelLarge, null, lineLabel), /*#__PURE__*/React.createElement(Strut, {
|
|
31085
|
-
size: spacing.xSmall_8
|
|
31086
|
-
}), /*#__PURE__*/React.createElement(LineSwatch, {
|
|
31087
|
-
color: lineColor,
|
|
31088
|
-
lineStyle: "solid"
|
|
31089
|
-
}))
|
|
31090
|
-
}, /*#__PURE__*/React.createElement(View, {
|
|
31091
|
-
style: [styles$d.row, styles$d.spaceUnder]
|
|
31092
|
-
}, /*#__PURE__*/React.createElement(ColorSelect, {
|
|
31093
|
-
selectedValue: lineColor,
|
|
31094
|
-
onChange: handleColorChange
|
|
31095
|
-
})), isInvalid && /*#__PURE__*/React.createElement(LabelMedium, {
|
|
31096
|
-
style: styles$d.errorText
|
|
31097
|
-
}, lengthErrorMessage), /*#__PURE__*/React.createElement(LockedFigureSettingsAccordion, {
|
|
31098
|
-
expanded: true // Initial state is expanded
|
|
31099
|
-
,
|
|
31100
|
-
containerStyle: styles$d.container,
|
|
31101
|
-
panelStyle: styles$d.accordionPanel,
|
|
31102
|
-
header: /*#__PURE__*/React.createElement(View, {
|
|
31103
|
-
style: styles$d.row
|
|
31104
|
-
}, /*#__PURE__*/React.createElement(LabelLarge, null, `Tail (${tail[0]}, ${tail[1]})`))
|
|
31105
|
-
}, /*#__PURE__*/React.createElement(CoordinatePairInput, {
|
|
31106
|
-
coord: tail,
|
|
31107
|
-
error: isInvalid,
|
|
31108
|
-
onChange: newProps => {
|
|
31109
|
-
handleChangePoint(newProps, 0);
|
|
31110
|
-
}
|
|
31111
|
-
})), /*#__PURE__*/React.createElement(LockedFigureSettingsAccordion, {
|
|
31112
|
-
expanded: true // Initial state is expanded
|
|
31113
|
-
,
|
|
31114
|
-
containerStyle: styles$d.container,
|
|
31115
|
-
panelStyle: styles$d.accordionPanel,
|
|
31116
|
-
header: /*#__PURE__*/React.createElement(View, {
|
|
31117
|
-
style: styles$d.row
|
|
31118
|
-
}, /*#__PURE__*/React.createElement(LabelLarge, null, `Tip (${tip[0]}, ${tip[1]})`))
|
|
31119
|
-
}, /*#__PURE__*/React.createElement(CoordinatePairInput, {
|
|
31120
|
-
coord: tip,
|
|
31121
|
-
error: isInvalid,
|
|
31122
|
-
onChange: newProps => {
|
|
31123
|
-
handleChangePoint(newProps, 1);
|
|
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));
|
|
31124
31395
|
}
|
|
31125
|
-
})), /*#__PURE__*/React.createElement(LockedFigureSettingsActions, {
|
|
31126
|
-
onRemove: onRemove,
|
|
31127
|
-
figureAriaLabel: `locked vector defined by starting point
|
|
31128
|
-
${tail[0]}, ${tail[1]} and extending to
|
|
31129
|
-
${tip[0]}, ${tip[1]}.`
|
|
31130
|
-
}));
|
|
31131
|
-
};
|
|
31132
|
-
const styles$d = StyleSheet.create({
|
|
31133
|
-
accordionPanel: {
|
|
31134
|
-
paddingBottom: spacing.medium_16
|
|
31135
|
-
},
|
|
31136
|
-
container: {
|
|
31137
|
-
marginTop: spacing.xSmall_8,
|
|
31138
|
-
marginBottom: 0,
|
|
31139
|
-
marginLeft: -spacing.xxxSmall_4,
|
|
31140
|
-
marginRight: -spacing.xxxSmall_4,
|
|
31141
|
-
backgroundColor: color.white
|
|
31142
|
-
},
|
|
31143
|
-
errorText: {
|
|
31144
|
-
color: color.red,
|
|
31145
|
-
marginTop: spacing.xSmall_8
|
|
31146
|
-
},
|
|
31147
|
-
row: {
|
|
31148
|
-
flexDirection: "row",
|
|
31149
|
-
alignItems: "center"
|
|
31150
31396
|
}
|
|
31151
|
-
|
|
31152
|
-
|
|
31153
|
-
/**
|
|
31154
|
-
* LockedFigureSettings takes in a figure and renders the
|
|
31155
|
-
* respective settings for that figure type.
|
|
31156
|
-
*
|
|
31157
|
-
* Used in the interactive graph editor's locked figures section.
|
|
31158
|
-
*/
|
|
31159
|
-
|
|
31160
|
-
// Union this type with other locked figure types when they are added.
|
|
31161
|
-
|
|
31162
|
-
const LockedFigureSettings = props => {
|
|
31163
|
-
switch (props.type) {
|
|
31164
|
-
case "point":
|
|
31165
|
-
return /*#__PURE__*/React.createElement(LockedPointSettings, props);
|
|
31166
|
-
case "line":
|
|
31167
|
-
return /*#__PURE__*/React.createElement(LockedLineSettings, props);
|
|
31168
|
-
case "ellipse":
|
|
31169
|
-
if (props.showM2Features) {
|
|
31170
|
-
return /*#__PURE__*/React.createElement(LockedEllipseSettings, props);
|
|
31171
|
-
}
|
|
31172
|
-
break;
|
|
31173
|
-
case "vector":
|
|
31174
|
-
if (props.showM2Features) {
|
|
31175
|
-
return /*#__PURE__*/React.createElement(LockedVectorSettings, props);
|
|
31176
|
-
}
|
|
31177
|
-
break;
|
|
31397
|
+
componentWillUnmount() {
|
|
31398
|
+
this._isMounted = false;
|
|
31178
31399
|
}
|
|
31179
|
-
|
|
31180
|
-
|
|
31181
|
-
|
|
31182
|
-
|
|
31183
|
-
|
|
31184
|
-
|
|
31185
|
-
|
|
31186
|
-
|
|
31187
|
-
|
|
31188
|
-
|
|
31189
|
-
|
|
31190
|
-
|
|
31191
|
-
|
|
31192
|
-
|
|
31193
|
-
|
|
31194
|
-
|
|
31195
|
-
|
|
31196
|
-
|
|
31197
|
-
|
|
31198
|
-
|
|
31199
|
-
|
|
31200
|
-
|
|
31201
|
-
|
|
31202
|
-
|
|
31203
|
-
|
|
31204
|
-
|
|
31205
|
-
|
|
31206
|
-
|
|
31207
|
-
|
|
31208
|
-
|
|
31209
|
-
|
|
31210
|
-
|
|
31211
|
-
|
|
31212
|
-
|
|
31213
|
-
|
|
31214
|
-
|
|
31215
|
-
|
|
31216
|
-
|
|
31217
|
-
|
|
31218
|
-
|
|
31219
|
-
|
|
31220
|
-
|
|
31221
|
-
}
|
|
31222
|
-
|
|
31223
|
-
|
|
31224
|
-
|
|
31225
|
-
|
|
31226
|
-
|
|
31227
|
-
|
|
31228
|
-
|
|
31229
|
-
|
|
31230
|
-
|
|
31231
|
-
|
|
31232
|
-
|
|
31233
|
-
|
|
31234
|
-
|
|
31235
|
-
|
|
31236
|
-
|
|
31237
|
-
|
|
31238
|
-
|
|
31239
|
-
|
|
31240
|
-
|
|
31241
|
-
|
|
31242
|
-
|
|
31243
|
-
|
|
31244
|
-
|
|
31245
|
-
|
|
31246
|
-
|
|
31247
|
-
|
|
31248
|
-
|
|
31249
|
-
|
|
31250
|
-
|
|
31251
|
-
|
|
31252
|
-
|
|
31253
|
-
|
|
31254
|
-
|
|
31255
|
-
|
|
31256
|
-
|
|
31257
|
-
|
|
31258
|
-
|
|
31259
|
-
|
|
31260
|
-
|
|
31261
|
-
|
|
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
|
+
}))))))));
|
|
31262
31593
|
}
|
|
31263
31594
|
}
|
|
31264
|
-
|
|
31265
|
-
|
|
31266
|
-
|
|
31267
|
-
|
|
31268
|
-
|
|
31269
|
-
|
|
31270
|
-
|
|
31271
|
-
|
|
31272
|
-
|
|
31273
|
-
|
|
31274
|
-
|
|
31275
|
-
|
|
31276
|
-
|
|
31277
|
-
|
|
31278
|
-
|
|
31279
|
-
lockedFigures: [...lockedFigures, getDefaultFigureForType(newFigure)]
|
|
31280
|
-
};
|
|
31281
|
-
onChange(newProps);
|
|
31282
|
-
setExpandedStates([...expandedStates, true]);
|
|
31283
|
-
}
|
|
31284
|
-
function removeLockedFigure(index) {
|
|
31285
|
-
// eslint-disable-next-line no-alert
|
|
31286
|
-
if (window.confirm("Are you sure you want to delete this figure?")) {
|
|
31287
|
-
const lockedFigures = figures || [];
|
|
31288
|
-
onChange({
|
|
31289
|
-
lockedFigures: [...lockedFigures.slice(0, index), ...lockedFigures.slice(index + 1)]
|
|
31290
|
-
});
|
|
31291
|
-
|
|
31292
|
-
// Update expanded states
|
|
31293
|
-
const newExpandedStates = [...expandedStates];
|
|
31294
|
-
newExpandedStates.splice(index, 1);
|
|
31295
|
-
setExpandedStates(newExpandedStates);
|
|
31296
|
-
}
|
|
31297
|
-
}
|
|
31298
|
-
function changeProps(index,
|
|
31299
|
-
// Omit the type from the figure props so it doesn't think
|
|
31300
|
-
// we're trying to pass in the props for the wrong type.
|
|
31301
|
-
figureProps) {
|
|
31302
|
-
const lockedFigures = figures || [];
|
|
31303
|
-
const newFigures = {
|
|
31304
|
-
lockedFigures: [...lockedFigures.slice(0, index), _extends({}, lockedFigures[index], figureProps), ...lockedFigures.slice(index + 1)]
|
|
31305
|
-
};
|
|
31306
|
-
onChange(newFigures);
|
|
31307
|
-
}
|
|
31308
|
-
function toggleExpanded(newValue) {
|
|
31309
|
-
setExpandedStates(Array(figures == null ? void 0 : figures.length).fill(newValue));
|
|
31310
|
-
}
|
|
31311
|
-
const allCollapsed = expandedStates.every(value => !value);
|
|
31312
|
-
const buttonLabel = allCollapsed ? "Expand all" : "Collapse all";
|
|
31313
|
-
const showExpandButton = !!(figures != null && figures.length);
|
|
31314
|
-
return /*#__PURE__*/React.createElement(View, null, figures == null ? void 0 : figures.map((figure, index) => {
|
|
31315
|
-
return /*#__PURE__*/React.createElement(LockedFigureSettings, _extends({
|
|
31316
|
-
key: `${uniqueId}-locked-${figure}-${index}`,
|
|
31317
|
-
showM2Features: props.showM2Features,
|
|
31318
|
-
expanded: expandedStates[index],
|
|
31319
|
-
onToggle: newValue => {
|
|
31320
|
-
const newExpanded = [...expandedStates];
|
|
31321
|
-
newExpanded[index] = newValue;
|
|
31322
|
-
setExpandedStates(newExpanded);
|
|
31323
|
-
}
|
|
31324
|
-
}, figure, {
|
|
31325
|
-
onChangeProps: newProps => changeProps(index, newProps),
|
|
31326
|
-
onRemove: () => removeLockedFigure(index)
|
|
31327
|
-
}));
|
|
31328
|
-
}), /*#__PURE__*/React.createElement(View, {
|
|
31329
|
-
style: styles$c.buttonContainer
|
|
31330
|
-
}, /*#__PURE__*/React.createElement(LockedFigureSelect, {
|
|
31331
|
-
showM2Features: props.showM2Features,
|
|
31332
|
-
id: `${uniqueId}-select`,
|
|
31333
|
-
onChange: addLockedFigure
|
|
31334
|
-
}), /*#__PURE__*/React.createElement(Strut, {
|
|
31335
|
-
size: spacing.small_12
|
|
31336
|
-
}), showExpandButton && /*#__PURE__*/React.createElement(Button, {
|
|
31337
|
-
kind: "secondary",
|
|
31338
|
-
onClick: () => toggleExpanded(allCollapsed),
|
|
31339
|
-
style: styles$c.button
|
|
31340
|
-
}, buttonLabel)));
|
|
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
|
|
31341
31610
|
};
|
|
31342
31611
|
const styles$c = StyleSheet.create({
|
|
31343
|
-
|
|
31612
|
+
resetSpaceTop: {
|
|
31613
|
+
marginTop: 0
|
|
31614
|
+
},
|
|
31615
|
+
spaceTop: {
|
|
31616
|
+
marginTop: spacing.xSmall_8
|
|
31617
|
+
},
|
|
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: {
|
|
31344
31629
|
flexDirection: "row",
|
|
31345
|
-
alignItems: "center"
|
|
31630
|
+
alignItems: "center",
|
|
31631
|
+
justifyContent: "space-between",
|
|
31632
|
+
marginBottom: spacing.xSmall_8
|
|
31346
31633
|
},
|
|
31347
|
-
|
|
31634
|
+
rulerSection: {
|
|
31348
31635
|
marginTop: spacing.xSmall_8,
|
|
31349
|
-
|
|
31636
|
+
borderTop: `1px solid ${color.offBlack16}`,
|
|
31637
|
+
paddingTop: spacing.xSmall_8,
|
|
31638
|
+
paddingBottom: spacing.xSmall_8,
|
|
31639
|
+
borderBottom: `1px solid ${color.offBlack16}`
|
|
31350
31640
|
}
|
|
31351
31641
|
});
|
|
31352
31642
|
|
|
@@ -31441,8 +31731,17 @@ class InteractiveGraphEditor extends React.Component {
|
|
|
31441
31731
|
UNSAFE_componentWillMount() {
|
|
31442
31732
|
DeprecationMixin.UNSAFE_componentWillMount.call(this);
|
|
31443
31733
|
}
|
|
31734
|
+
static buildGraphKey(correct) {
|
|
31735
|
+
const testGraphKey = [];
|
|
31736
|
+
for (const key in correct) {
|
|
31737
|
+
if (correct[key]) {
|
|
31738
|
+
typeof correct[key] === "number" || typeof correct[key] === "string" || typeof correct[key] === "boolean" ? testGraphKey.push(correct[key]) : testGraphKey.push(0);
|
|
31739
|
+
}
|
|
31740
|
+
}
|
|
31741
|
+
return testGraphKey.join(":");
|
|
31742
|
+
}
|
|
31444
31743
|
render() {
|
|
31445
|
-
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;
|
|
31446
31745
|
let graph;
|
|
31447
31746
|
let equationString;
|
|
31448
31747
|
const gridStep = this.props.gridStep || Util.getGridStep(this.props.range, this.props.step, interactiveSizes.defaultBoxSize);
|
|
@@ -31484,10 +31783,9 @@ class InteractiveGraphEditor extends React.Component {
|
|
|
31484
31783
|
});
|
|
31485
31784
|
}
|
|
31486
31785
|
};
|
|
31487
|
-
|
|
31488
31786
|
// This is used to force a remount of the graph component
|
|
31489
31787
|
// when there's a significant change
|
|
31490
|
-
const graphKey =
|
|
31788
|
+
const graphKey = InteractiveGraphEditor.buildGraphKey(correct);
|
|
31491
31789
|
graph =
|
|
31492
31790
|
/*#__PURE__*/
|
|
31493
31791
|
// There are a bunch of props that renderer.jsx passes to widgets via
|
|
@@ -31695,6 +31993,7 @@ class InteractiveGraphEditor extends React.Component {
|
|
|
31695
31993
|
// is using Mafs.
|
|
31696
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, {
|
|
31697
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"],
|
|
31698
31997
|
figures: this.props.lockedFigures,
|
|
31699
31998
|
onChange: this.props.onChange
|
|
31700
31999
|
}));
|