@khanacademy/perseus-editor 14.3.0 → 14.5.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/widget-editor.d.ts +1 -0
- package/dist/editor-page.d.ts +2 -0
- package/dist/editor.d.ts +1 -0
- package/dist/es/index.js +1212 -944
- package/dist/es/index.js.map +1 -1
- package/dist/index.js +930 -649
- package/dist/index.js.map +1 -1
- package/dist/item-editor.d.ts +1 -0
- package/dist/widgets/categorizer-editor.d.ts +0 -1
- package/dist/widgets/graded-group-editor.d.ts +0 -1
- package/dist/widgets/graded-group-set-editor.d.ts +0 -1
- package/dist/widgets/group-editor.d.ts +0 -1
- package/dist/widgets/interactive-graph-editor/interactive-graph-editor.d.ts +328 -222
- package/dist/widgets/interactive-graph-editor/locked-figures/locked-label-settings.d.ts +2 -0
- package/dist/widgets/interactive-graph-editor/locked-figures/locked-point-settings.d.ts +40 -3
- package/dist/widgets/radio/editor.d.ts +0 -1
- package/package.json +4 -3
- package/dist/widgets/interactive-graph-editor/locked-figures/defining-point-settings.d.ts +0 -35
package/dist/es/index.js
CHANGED
|
@@ -25,6 +25,7 @@ import { useMathInputI18n, createMathField } from '@khanacademy/math-input';
|
|
|
25
25
|
import { vector, number } from '@khanacademy/kmath';
|
|
26
26
|
import { SingleSelect, OptionItem, ActionMenu, ActionItem } from '@khanacademy/wonder-blocks-dropdown';
|
|
27
27
|
import Banner from '@khanacademy/wonder-blocks-banner';
|
|
28
|
+
import plusCircle from '@phosphor-icons/core/regular/plus-circle.svg';
|
|
28
29
|
import { AccordionSection } from '@khanacademy/wonder-blocks-accordion';
|
|
29
30
|
import IconButton from '@khanacademy/wonder-blocks-icon-button';
|
|
30
31
|
import caretDoubleDownIcon from '@phosphor-icons/core/bold/caret-double-down-bold.svg';
|
|
@@ -34,7 +35,7 @@ import caretUpIcon from '@phosphor-icons/core/bold/caret-up-bold.svg';
|
|
|
34
35
|
import trashIcon from '@phosphor-icons/core/bold/trash-bold.svg';
|
|
35
36
|
import copyIcon from '@phosphor-icons/core/assets/regular/copy.svg';
|
|
36
37
|
import autoPasteIcon from '@phosphor-icons/core/assets/regular/note-pencil.svg';
|
|
37
|
-
import
|
|
38
|
+
import { vec } from 'mafs';
|
|
38
39
|
import arrowFatDown from '@phosphor-icons/core/regular/arrow-fat-down.svg';
|
|
39
40
|
import arrowFatLeft from '@phosphor-icons/core/regular/arrow-fat-left.svg';
|
|
40
41
|
import arrowFatRight from '@phosphor-icons/core/regular/arrow-fat-right.svg';
|
|
@@ -44,7 +45,7 @@ import arrowCounterClockwise from '@phosphor-icons/core/bold/arrow-counter-clock
|
|
|
44
45
|
|
|
45
46
|
// This file is processed by a Rollup plugin (replace) to inject the production
|
|
46
47
|
const libName = "@khanacademy/perseus-editor";
|
|
47
|
-
const libVersion = "14.
|
|
48
|
+
const libVersion = "14.5.0";
|
|
48
49
|
addLibraryVersionToPerseusDebug(libName, libVersion);
|
|
49
50
|
|
|
50
51
|
function _extends() {
|
|
@@ -229,7 +230,7 @@ class SectionControlButton extends React.Component {
|
|
|
229
230
|
role: "button",
|
|
230
231
|
hideDefaultFocusRing: true,
|
|
231
232
|
"aria-label": title,
|
|
232
|
-
style: styles$
|
|
233
|
+
style: styles$T.button
|
|
233
234
|
}, ({
|
|
234
235
|
hovered,
|
|
235
236
|
focused,
|
|
@@ -237,7 +238,7 @@ class SectionControlButton extends React.Component {
|
|
|
237
238
|
}) => /*#__PURE__*/React.createElement(InlineIcon$b, icon));
|
|
238
239
|
}
|
|
239
240
|
}
|
|
240
|
-
const styles$
|
|
241
|
+
const styles$T = StyleSheet.create({
|
|
241
242
|
button: {
|
|
242
243
|
backgroundColor: color.gold,
|
|
243
244
|
margin: 2,
|
|
@@ -20628,11 +20629,11 @@ class Spring extends React.Component {
|
|
|
20628
20629
|
} = this.props;
|
|
20629
20630
|
return React.createElement(View, {
|
|
20630
20631
|
"aria-hidden": "true",
|
|
20631
|
-
style: [styles$
|
|
20632
|
+
style: [styles$S.grow, style]
|
|
20632
20633
|
});
|
|
20633
20634
|
}
|
|
20634
20635
|
}
|
|
20635
|
-
const styles$
|
|
20636
|
+
const styles$S = StyleSheet.create({
|
|
20636
20637
|
grow: {
|
|
20637
20638
|
flexGrow: 1
|
|
20638
20639
|
}
|
|
@@ -20698,6 +20699,7 @@ const _upgradeWidgetInfo = props => {
|
|
|
20698
20699
|
// eslint-disable-next-line react/no-unsafe
|
|
20699
20700
|
class WidgetEditor extends React.Component {
|
|
20700
20701
|
constructor(props) {
|
|
20702
|
+
var _props$widgetIsOpen;
|
|
20701
20703
|
super(props);
|
|
20702
20704
|
this.widget = void 0;
|
|
20703
20705
|
this._toggleWidget = e => {
|
|
@@ -20751,7 +20753,7 @@ class WidgetEditor extends React.Component {
|
|
|
20751
20753
|
};
|
|
20752
20754
|
};
|
|
20753
20755
|
this.state = {
|
|
20754
|
-
showWidget:
|
|
20756
|
+
showWidget: (_props$widgetIsOpen = props.widgetIsOpen) != null ? _props$widgetIsOpen : true,
|
|
20755
20757
|
widgetInfo: _upgradeWidgetInfo(props)
|
|
20756
20758
|
};
|
|
20757
20759
|
this.widget = /*#__PURE__*/React.createRef();
|
|
@@ -20762,6 +20764,12 @@ class WidgetEditor extends React.Component {
|
|
|
20762
20764
|
this.setState({
|
|
20763
20765
|
widgetInfo: _upgradeWidgetInfo(nextProps)
|
|
20764
20766
|
});
|
|
20767
|
+
// user can update internal state while the widget is handled globally
|
|
20768
|
+
if (nextProps.widgetIsOpen != null && nextProps.widgetIsOpen !== this.props.widgetIsOpen) {
|
|
20769
|
+
this.setState({
|
|
20770
|
+
showWidget: nextProps.widgetIsOpen
|
|
20771
|
+
});
|
|
20772
|
+
}
|
|
20765
20773
|
}
|
|
20766
20774
|
render() {
|
|
20767
20775
|
const widgetInfo = this.state.widgetInfo;
|
|
@@ -20869,13 +20877,13 @@ class WidgetSelect extends React.Component {
|
|
|
20869
20877
|
* that collapse a region.
|
|
20870
20878
|
*/
|
|
20871
20879
|
function ToggleableCaret(props) {
|
|
20872
|
-
const iconStyle = props.isExpanded ? styles$
|
|
20880
|
+
const iconStyle = props.isExpanded ? styles$R.expanded : styles$R.collapsed;
|
|
20873
20881
|
return /*#__PURE__*/React.createElement(PhosphorIcon, {
|
|
20874
20882
|
icon: caretRight,
|
|
20875
20883
|
style: iconStyle
|
|
20876
20884
|
});
|
|
20877
20885
|
}
|
|
20878
|
-
const styles$
|
|
20886
|
+
const styles$R = StyleSheet.create({
|
|
20879
20887
|
collapsed: {
|
|
20880
20888
|
transition: ".15s"
|
|
20881
20889
|
},
|
|
@@ -20908,16 +20916,16 @@ class TexErrorView extends React.Component {
|
|
|
20908
20916
|
showErrors
|
|
20909
20917
|
} = this.state;
|
|
20910
20918
|
return /*#__PURE__*/React.createElement(View, {
|
|
20911
|
-
style: styles$
|
|
20919
|
+
style: styles$Q.errorContainer
|
|
20912
20920
|
}, /*#__PURE__*/React.createElement(View, {
|
|
20913
|
-
style: styles$
|
|
20921
|
+
style: styles$Q.title,
|
|
20914
20922
|
onClick: this.handleToggleTexErrors
|
|
20915
20923
|
}, /*#__PURE__*/React.createElement(ToggleableCaret, {
|
|
20916
20924
|
isExpanded: showErrors
|
|
20917
20925
|
}), "\xA0 TeX Errors (", errorList.length, ")"), showErrors && /*#__PURE__*/React.createElement(View, {
|
|
20918
|
-
style: styles$
|
|
20926
|
+
style: styles$Q.errorExplanation
|
|
20919
20927
|
}, "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, {
|
|
20920
|
-
style: styles$
|
|
20928
|
+
style: styles$Q.error,
|
|
20921
20929
|
key: index
|
|
20922
20930
|
}, /*#__PURE__*/React.createElement(View, {
|
|
20923
20931
|
style: {
|
|
@@ -20926,7 +20934,7 @@ class TexErrorView extends React.Component {
|
|
|
20926
20934
|
}, e.math), /*#__PURE__*/React.createElement(View, null, e.message))));
|
|
20927
20935
|
}
|
|
20928
20936
|
}
|
|
20929
|
-
const styles$
|
|
20937
|
+
const styles$Q = StyleSheet.create({
|
|
20930
20938
|
title: {
|
|
20931
20939
|
backgroundColor: "#eee",
|
|
20932
20940
|
fontSize: "1.25em",
|
|
@@ -21574,7 +21582,8 @@ class Editor extends React.Component {
|
|
|
21574
21582
|
// eslint-disable-next-line react/jsx-no-bind
|
|
21575
21583
|
,
|
|
21576
21584
|
onRemove: this._handleWidgetEditorRemove.bind(this, id),
|
|
21577
|
-
apiOptions: this.props.apiOptions
|
|
21585
|
+
apiOptions: this.props.apiOptions,
|
|
21586
|
+
widgetIsOpen: this.props.widgetIsOpen
|
|
21578
21587
|
}, this.props.widgets[id]));
|
|
21579
21588
|
}
|
|
21580
21589
|
render() {
|
|
@@ -21895,8 +21904,7 @@ class IframeContentRenderer extends React.Component {
|
|
|
21895
21904
|
this._lastData = data;
|
|
21896
21905
|
|
|
21897
21906
|
// We can't use JSON.stringify/parse for this because the apiOptions
|
|
21898
|
-
// includes the functions GroupMetadataEditor, groupAnnotator,
|
|
21899
|
-
// onFocusChange, and onInputError.
|
|
21907
|
+
// includes the functions GroupMetadataEditor, groupAnnotator, and onFocusChange.
|
|
21900
21908
|
// @ts-expect-error - TS2339 - Property 'iframeDataStore' does not exist on type 'Window & typeof globalThis'.
|
|
21901
21909
|
window.iframeDataStore[this.iframeID] = data;
|
|
21902
21910
|
frame.contentWindow.postMessage(this.iframeID, "*");
|
|
@@ -24039,7 +24047,7 @@ ItemExtrasEditor.defaultProps = {
|
|
|
24039
24047
|
zTable: false
|
|
24040
24048
|
};
|
|
24041
24049
|
const ItemExtraCheckbox = props => /*#__PURE__*/React.createElement(View, {
|
|
24042
|
-
style: [styles$
|
|
24050
|
+
style: [styles$P.checkbox, props.indent ? styles$P.indented : undefined]
|
|
24043
24051
|
}, /*#__PURE__*/React.createElement(Checkbox$1, {
|
|
24044
24052
|
label: /*#__PURE__*/React.createElement(View, {
|
|
24045
24053
|
style: {
|
|
@@ -24049,7 +24057,7 @@ const ItemExtraCheckbox = props => /*#__PURE__*/React.createElement(View, {
|
|
|
24049
24057
|
checked: props.checked,
|
|
24050
24058
|
onChange: newCheckedState => props.onChange(newCheckedState)
|
|
24051
24059
|
}));
|
|
24052
|
-
const styles$
|
|
24060
|
+
const styles$P = StyleSheet.create({
|
|
24053
24061
|
indented: {
|
|
24054
24062
|
marginInlineStart: spacing.large_24
|
|
24055
24063
|
}
|
|
@@ -24119,7 +24127,8 @@ class ItemEditor extends React.Component {
|
|
|
24119
24127
|
imageUploader: this.props.imageUploader,
|
|
24120
24128
|
onChange: this.handleEditorChange,
|
|
24121
24129
|
apiOptions: this.props.apiOptions,
|
|
24122
|
-
showWordCount: true
|
|
24130
|
+
showWordCount: true,
|
|
24131
|
+
widgetIsOpen: this.props.widgetIsOpen
|
|
24123
24132
|
}, this.props.question))), /*#__PURE__*/React.createElement("div", {
|
|
24124
24133
|
className: "perseus-editor-right-cell"
|
|
24125
24134
|
}, /*#__PURE__*/React.createElement("div", {
|
|
@@ -24167,6 +24176,7 @@ const {
|
|
|
24167
24176
|
} = components;
|
|
24168
24177
|
class EditorPage extends React.Component {
|
|
24169
24178
|
constructor(props) {
|
|
24179
|
+
var _this$props$widgetsAr;
|
|
24170
24180
|
super(props);
|
|
24171
24181
|
this._isMounted = void 0;
|
|
24172
24182
|
this.renderer = void 0;
|
|
@@ -24199,7 +24209,8 @@ class EditorPage extends React.Component {
|
|
|
24199
24209
|
json: _.pick(this.props, "question", "answerArea", "hints", "itemDataVersion"),
|
|
24200
24210
|
gradeMessage: "",
|
|
24201
24211
|
wasAnswered: false,
|
|
24202
|
-
highlightLint: true
|
|
24212
|
+
highlightLint: true,
|
|
24213
|
+
widgetsAreOpen: (_this$props$widgetsAr = this.props.widgetsAreOpen) != null ? _this$props$widgetsAr : true
|
|
24203
24214
|
};
|
|
24204
24215
|
this._isMounted = false;
|
|
24205
24216
|
}
|
|
@@ -24327,6 +24338,7 @@ class EditorPage extends React.Component {
|
|
|
24327
24338
|
wasAnswered: this.state.wasAnswered,
|
|
24328
24339
|
gradeMessage: this.state.gradeMessage,
|
|
24329
24340
|
deviceType: this.props.previewDevice,
|
|
24341
|
+
widgetIsOpen: this.state.widgetsAreOpen,
|
|
24330
24342
|
apiOptions: deviceBasedApiOptions,
|
|
24331
24343
|
previewURL: this.props.previewURL
|
|
24332
24344
|
}), (!this.props.developerMode || !this.props.jsonMode) && /*#__PURE__*/React.createElement(CombinedHintsEditor, {
|
|
@@ -24707,7 +24719,7 @@ class SimpleButton extends React.Component {
|
|
|
24707
24719
|
} = _this$props,
|
|
24708
24720
|
otherProps = _objectWithoutPropertiesLoose(_this$props, _excluded$3);
|
|
24709
24721
|
return /*#__PURE__*/React.createElement("div", _extends({
|
|
24710
|
-
className: css(styles$
|
|
24722
|
+
className: css(styles$O.baseButton, color === "green" && styles$O.green, color === "orange" && styles$O.orange),
|
|
24711
24723
|
onClick: onClick
|
|
24712
24724
|
}, otherProps), children);
|
|
24713
24725
|
}
|
|
@@ -24722,7 +24734,7 @@ SimpleButton.defaultProps = {
|
|
|
24722
24734
|
color: "green",
|
|
24723
24735
|
onClick: () => {}
|
|
24724
24736
|
};
|
|
24725
|
-
const styles$
|
|
24737
|
+
const styles$O = StyleSheet.create({
|
|
24726
24738
|
baseButton: {
|
|
24727
24739
|
top: "0",
|
|
24728
24740
|
fontSize: "11px",
|
|
@@ -24942,23 +24954,23 @@ const LeafContainer = ({
|
|
|
24942
24954
|
}) => {
|
|
24943
24955
|
const hasPreviewHeading = shape.type === "content" || shape.type === "hint";
|
|
24944
24956
|
const previewHeading = hasPreviewHeading && /*#__PURE__*/React.createElement("div", {
|
|
24945
|
-
className: css(styles$
|
|
24957
|
+
className: css(styles$N.containerHeader)
|
|
24946
24958
|
}, /*#__PURE__*/React.createElement(Header, {
|
|
24947
24959
|
depth: path.length,
|
|
24948
|
-
className: css(styles$
|
|
24960
|
+
className: css(styles$N.containerTitle)
|
|
24949
24961
|
}, capitalize(name)));
|
|
24950
24962
|
return /*#__PURE__*/React.createElement("div", {
|
|
24951
|
-
className: css(styles$
|
|
24963
|
+
className: css(styles$N.container)
|
|
24952
24964
|
}, /*#__PURE__*/React.createElement("span", {
|
|
24953
|
-
className: css(styles$
|
|
24965
|
+
className: css(styles$N.row, styles$N.rowHeading)
|
|
24954
24966
|
}, /*#__PURE__*/React.createElement("div", {
|
|
24955
|
-
className: css(styles$
|
|
24967
|
+
className: css(styles$N.columnLeft)
|
|
24956
24968
|
}, /*#__PURE__*/React.createElement("div", {
|
|
24957
|
-
className: "pod-title " + css(styles$
|
|
24969
|
+
className: "pod-title " + css(styles$N.containerHeader)
|
|
24958
24970
|
}, /*#__PURE__*/React.createElement("div", {
|
|
24959
|
-
className: css(styles$
|
|
24971
|
+
className: css(styles$N.containerTitle)
|
|
24960
24972
|
}, capitalize(name)), controls)), /*#__PURE__*/React.createElement("div", {
|
|
24961
|
-
className: css(styles$
|
|
24973
|
+
className: css(styles$N.columnRight)
|
|
24962
24974
|
}, previewHeading)), children);
|
|
24963
24975
|
};
|
|
24964
24976
|
const ArrayContainer = props => {
|
|
@@ -24971,11 +24983,11 @@ const ArrayContainer = props => {
|
|
|
24971
24983
|
actions
|
|
24972
24984
|
} = props;
|
|
24973
24985
|
return /*#__PURE__*/React.createElement("div", {
|
|
24974
|
-
className: css(styles$
|
|
24986
|
+
className: css(styles$N.container)
|
|
24975
24987
|
}, controls && /*#__PURE__*/React.createElement("div", {
|
|
24976
|
-
className: css(styles$
|
|
24988
|
+
className: css(styles$N.columnLeft, styles$N.containerHeader)
|
|
24977
24989
|
}, controls), /*#__PURE__*/React.createElement("div", null, children), /*#__PURE__*/React.createElement("div", {
|
|
24978
|
-
className: css(styles$
|
|
24990
|
+
className: css(styles$N.columnLeft)
|
|
24979
24991
|
}, /*#__PURE__*/React.createElement("a", {
|
|
24980
24992
|
href: "javascript:void 0",
|
|
24981
24993
|
onClick: () => actions.addArrayElement(path, shape.elementShape)
|
|
@@ -24988,28 +25000,28 @@ const ObjectContainer = ({
|
|
|
24988
25000
|
path
|
|
24989
25001
|
}) => {
|
|
24990
25002
|
const headingEditor = /*#__PURE__*/React.createElement("div", {
|
|
24991
|
-
className: css(styles$
|
|
25003
|
+
className: css(styles$N.containerHeader)
|
|
24992
25004
|
}, /*#__PURE__*/React.createElement(Header, {
|
|
24993
25005
|
depth: path.length,
|
|
24994
|
-
className: css(styles$
|
|
25006
|
+
className: css(styles$N.containerTitle)
|
|
24995
25007
|
}, capitalize(name)), controls);
|
|
24996
25008
|
const headingPreview = (name || controls) && /*#__PURE__*/React.createElement("div", {
|
|
24997
|
-
className: css(styles$
|
|
25009
|
+
className: css(styles$N.containerHeader, styles$N.previewCollectionHeader)
|
|
24998
25010
|
}, /*#__PURE__*/React.createElement(Header, {
|
|
24999
25011
|
depth: path.length,
|
|
25000
|
-
className: css(styles$
|
|
25012
|
+
className: css(styles$N.containerTitle)
|
|
25001
25013
|
}, capitalize(name)));
|
|
25002
25014
|
const hasBothHeadings = headingEditor && headingPreview;
|
|
25003
25015
|
return /*#__PURE__*/React.createElement("div", {
|
|
25004
|
-
className: css(styles$
|
|
25016
|
+
className: css(styles$N.container)
|
|
25005
25017
|
}, hasBothHeadings && /*#__PURE__*/React.createElement("span", {
|
|
25006
|
-
className: css(styles$
|
|
25018
|
+
className: css(styles$N.row)
|
|
25007
25019
|
}, /*#__PURE__*/React.createElement("div", {
|
|
25008
|
-
className: css(styles$
|
|
25020
|
+
className: css(styles$N.columnLeft)
|
|
25009
25021
|
}, headingEditor), /*#__PURE__*/React.createElement("div", {
|
|
25010
|
-
className: css(styles$
|
|
25022
|
+
className: css(styles$N.columnRight)
|
|
25011
25023
|
}, headingPreview)), /*#__PURE__*/React.createElement("div", {
|
|
25012
|
-
className: css(path.length > 0 && styles$
|
|
25024
|
+
className: css(path.length > 0 && styles$N.contentIndent)
|
|
25013
25025
|
}, children));
|
|
25014
25026
|
};
|
|
25015
25027
|
|
|
@@ -25132,11 +25144,11 @@ const ItemNodeContent = withStickiness(props => {
|
|
|
25132
25144
|
className: "framework-perseus"
|
|
25133
25145
|
}, lens(renderers).get(path));
|
|
25134
25146
|
return /*#__PURE__*/React.createElement("span", null, /*#__PURE__*/React.createElement("div", {
|
|
25135
|
-
className: css(styles$
|
|
25147
|
+
className: css(styles$N.row)
|
|
25136
25148
|
}, /*#__PURE__*/React.createElement("div", {
|
|
25137
|
-
className: css(styles$
|
|
25149
|
+
className: css(styles$N.columnLeft)
|
|
25138
25150
|
}, /*#__PURE__*/React.createElement("div", {
|
|
25139
|
-
className: css(sticky && styles$
|
|
25151
|
+
className: css(sticky && styles$N.sticky)
|
|
25140
25152
|
},
|
|
25141
25153
|
/*#__PURE__*/
|
|
25142
25154
|
// @ts-expect-error - TS2769 - No overload matches this call.
|
|
@@ -25144,9 +25156,9 @@ const ItemNodeContent = withStickiness(props => {
|
|
|
25144
25156
|
onChange: newVal => actions.mergeValueAtPath(path, newVal),
|
|
25145
25157
|
apiOptions: apiOptions
|
|
25146
25158
|
})))), /*#__PURE__*/React.createElement("div", {
|
|
25147
|
-
className: css(styles$
|
|
25159
|
+
className: css(styles$N.columnRight)
|
|
25148
25160
|
}, /*#__PURE__*/React.createElement("div", {
|
|
25149
|
-
className: css(sticky && styles$
|
|
25161
|
+
className: css(sticky && styles$N.sticky)
|
|
25150
25162
|
}, preview))));
|
|
25151
25163
|
});
|
|
25152
25164
|
const HintNodeContent = withStickiness(props => {
|
|
@@ -25162,13 +25174,13 @@ const HintNodeContent = withStickiness(props => {
|
|
|
25162
25174
|
className: "framework-perseus"
|
|
25163
25175
|
}, lens(renderers).get(path));
|
|
25164
25176
|
return /*#__PURE__*/React.createElement("div", {
|
|
25165
|
-
className: css(styles$
|
|
25177
|
+
className: css(styles$N.row)
|
|
25166
25178
|
}, /*#__PURE__*/React.createElement("div", {
|
|
25167
|
-
className: css(styles$
|
|
25179
|
+
className: css(styles$N.columnLeft)
|
|
25168
25180
|
}, /*#__PURE__*/React.createElement("div", {
|
|
25169
|
-
className: css(sticky && styles$
|
|
25181
|
+
className: css(sticky && styles$N.sticky)
|
|
25170
25182
|
}, /*#__PURE__*/React.createElement(HintEditor, _extends({}, data, {
|
|
25171
|
-
className: css(styles$
|
|
25183
|
+
className: css(styles$N.hintEditor),
|
|
25172
25184
|
onChange: newVal => actions.mergeValueAtPath(path, newVal),
|
|
25173
25185
|
apiOptions: apiOptions,
|
|
25174
25186
|
showTitle: false,
|
|
@@ -25183,9 +25195,9 @@ const HintNodeContent = withStickiness(props => {
|
|
|
25183
25195
|
isFirst: true,
|
|
25184
25196
|
isLast: true
|
|
25185
25197
|
})))), /*#__PURE__*/React.createElement("div", {
|
|
25186
|
-
className: css(styles$
|
|
25198
|
+
className: css(styles$N.columnRight)
|
|
25187
25199
|
}, /*#__PURE__*/React.createElement("div", {
|
|
25188
|
-
className: css(sticky && styles$
|
|
25200
|
+
className: css(sticky && styles$N.sticky)
|
|
25189
25201
|
}, preview)));
|
|
25190
25202
|
});
|
|
25191
25203
|
const TagsNodeContent = props => {
|
|
@@ -25202,9 +25214,9 @@ const TagsNodeContent = props => {
|
|
|
25202
25214
|
return null;
|
|
25203
25215
|
}
|
|
25204
25216
|
return /*#__PURE__*/React.createElement("div", {
|
|
25205
|
-
className: css(styles$
|
|
25217
|
+
className: css(styles$N.columnLeft)
|
|
25206
25218
|
}, /*#__PURE__*/React.createElement("div", {
|
|
25207
|
-
className: css(styles$
|
|
25219
|
+
className: css(styles$N.tagsEditor)
|
|
25208
25220
|
}, /*#__PURE__*/React.createElement(GroupMetadataEditor, {
|
|
25209
25221
|
value: data,
|
|
25210
25222
|
onChange: newVal => actions.setValueAtPath(path, newVal),
|
|
@@ -25235,23 +25247,23 @@ const ArrayNodeContent = props => {
|
|
|
25235
25247
|
const subpath = path.concat(i);
|
|
25236
25248
|
const controls = [i > 0 && /*#__PURE__*/React.createElement("div", {
|
|
25237
25249
|
key: "moveArrayElementUp",
|
|
25238
|
-
className: css(styles$
|
|
25250
|
+
className: css(styles$N.control)
|
|
25239
25251
|
}, /*#__PURE__*/React.createElement(SimpleButton, {
|
|
25240
25252
|
color: "orange",
|
|
25241
25253
|
title: "Move up",
|
|
25242
25254
|
onClick: () => actions.moveArrayElementUp(subpath)
|
|
25243
25255
|
}, /*#__PURE__*/React.createElement("div", {
|
|
25244
|
-
className: css(styles$
|
|
25256
|
+
className: css(styles$N.verticalFlip)
|
|
25245
25257
|
}, /*#__PURE__*/React.createElement(InlineIcon$6, iconChevronDown)))), i < data.length - 1 && /*#__PURE__*/React.createElement("div", {
|
|
25246
25258
|
key: "moveArrayElementDown",
|
|
25247
|
-
className: css(styles$
|
|
25259
|
+
className: css(styles$N.control)
|
|
25248
25260
|
}, /*#__PURE__*/React.createElement(SimpleButton, {
|
|
25249
25261
|
color: "orange",
|
|
25250
25262
|
title: "Move down",
|
|
25251
25263
|
onClick: () => actions.moveArrayElementDown(subpath)
|
|
25252
25264
|
}, /*#__PURE__*/React.createElement(InlineIcon$6, iconChevronDown))), /*#__PURE__*/React.createElement("div", {
|
|
25253
25265
|
key: "removeArrayElement",
|
|
25254
|
-
className: css(styles$
|
|
25266
|
+
className: css(styles$N.control)
|
|
25255
25267
|
}, /*#__PURE__*/React.createElement(SimpleButton, {
|
|
25256
25268
|
color: "orange",
|
|
25257
25269
|
title: "Delete",
|
|
@@ -25259,7 +25271,7 @@ const ArrayNodeContent = props => {
|
|
|
25259
25271
|
}, /*#__PURE__*/React.createElement(InlineIcon$6, iconTrash$4)))];
|
|
25260
25272
|
return /*#__PURE__*/React.createElement("div", {
|
|
25261
25273
|
key: i,
|
|
25262
|
-
className: css(styles$
|
|
25274
|
+
className: css(styles$N.arrayElement, !elementIsLeaf && styles$N.arrayElementAndNotLeaf)
|
|
25263
25275
|
}, /*#__PURE__*/React.createElement(NodeContainer, _extends({}, otherProps, {
|
|
25264
25276
|
key: i,
|
|
25265
25277
|
shape: shape.elementShape,
|
|
@@ -25285,7 +25297,7 @@ const ObjectNodeContent = props => {
|
|
|
25285
25297
|
// made sense to the shape's author is the order in which we'll iterate :)
|
|
25286
25298
|
const children = Object.keys(shape.shape).map(subkey => /*#__PURE__*/React.createElement("div", {
|
|
25287
25299
|
key: subkey,
|
|
25288
|
-
className: css(styles$
|
|
25300
|
+
className: css(styles$N.objectElement)
|
|
25289
25301
|
}, /*#__PURE__*/React.createElement(NodeContainer, _extends({}, otherProps, {
|
|
25290
25302
|
shape: shape.shape[subkey],
|
|
25291
25303
|
data: data[subkey],
|
|
@@ -25452,7 +25464,7 @@ class MultiRendererEditor extends React.Component {
|
|
|
25452
25464
|
}, this._renderContent());
|
|
25453
25465
|
}
|
|
25454
25466
|
}
|
|
25455
|
-
const styles$
|
|
25467
|
+
const styles$N = StyleSheet.create({
|
|
25456
25468
|
// This is used in a number of places throughout this file.
|
|
25457
25469
|
container: {},
|
|
25458
25470
|
// eslint-disable-next-line react-native/no-unused-styles
|
|
@@ -26398,7 +26410,7 @@ const SortableItem = createReactClass({
|
|
|
26398
26410
|
}
|
|
26399
26411
|
return /*#__PURE__*/React.createElement("li", {
|
|
26400
26412
|
draggable: this.props.draggable,
|
|
26401
|
-
className: [dragState, css(styles$
|
|
26413
|
+
className: [dragState, css(styles$M.sortableListItem)].join(" "),
|
|
26402
26414
|
onDragStart: this.handleDragStart,
|
|
26403
26415
|
onDrop: this.handleDrop,
|
|
26404
26416
|
onDragEnter: this.handleDragEnter,
|
|
@@ -26406,7 +26418,7 @@ const SortableItem = createReactClass({
|
|
|
26406
26418
|
}, this.props.component);
|
|
26407
26419
|
}
|
|
26408
26420
|
});
|
|
26409
|
-
const styles$
|
|
26421
|
+
const styles$M = StyleSheet.create({
|
|
26410
26422
|
sortableListItem: {
|
|
26411
26423
|
margin: "5px 0"
|
|
26412
26424
|
}
|
|
@@ -26654,13 +26666,13 @@ class ExpressionEditor extends React.Component {
|
|
|
26654
26666
|
onChange: this.handleToggleDiv
|
|
26655
26667
|
}));
|
|
26656
26668
|
return /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement(HeadingSmall, null, "Global Options"), /*#__PURE__*/React.createElement("div", {
|
|
26657
|
-
className: css(styles$
|
|
26669
|
+
className: css(styles$L.paddedY)
|
|
26658
26670
|
}, /*#__PURE__*/React.createElement(LabeledTextField, {
|
|
26659
26671
|
label: "Visible label",
|
|
26660
26672
|
value: this.props.visibleLabel || "",
|
|
26661
26673
|
onChange: this.change("visibleLabel")
|
|
26662
26674
|
}), /*#__PURE__*/React.createElement(InfoTip$i, null, /*#__PURE__*/React.createElement("p", null, "Optional visible text; strongly encouraged to help learners using dictation software, but can be omitted if the surrounding content provides enough context."))), /*#__PURE__*/React.createElement("div", {
|
|
26663
|
-
className: css(styles$
|
|
26675
|
+
className: css(styles$L.paddedY)
|
|
26664
26676
|
}, /*#__PURE__*/React.createElement(LabeledTextField, {
|
|
26665
26677
|
label: "Aria label",
|
|
26666
26678
|
value: this.props.ariaLabel || "",
|
|
@@ -26669,13 +26681,13 @@ class ExpressionEditor extends React.Component {
|
|
|
26669
26681
|
href: "https://www.w3.org/WAI/tips/designing/#ensure-that-form-elements-include-clearly-associated-labels",
|
|
26670
26682
|
target: "_blank"
|
|
26671
26683
|
}, "this article.")))), /*#__PURE__*/React.createElement("div", {
|
|
26672
|
-
className: css(styles$
|
|
26684
|
+
className: css(styles$L.paddedY)
|
|
26673
26685
|
}, /*#__PURE__*/React.createElement(LabeledTextField, {
|
|
26674
26686
|
label: "Function variables",
|
|
26675
26687
|
value: this.state.functionsInternal,
|
|
26676
26688
|
onChange: this.handleFunctions
|
|
26677
26689
|
}), /*#__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", {
|
|
26678
|
-
className: css(styles$
|
|
26690
|
+
className: css(styles$L.paddedY)
|
|
26679
26691
|
}, /*#__PURE__*/React.createElement(Checkbox$1, {
|
|
26680
26692
|
label: "Use \xD7 instead of \u22C5 for multiplication",
|
|
26681
26693
|
checked: this.props.times,
|
|
@@ -26685,7 +26697,7 @@ class ExpressionEditor extends React.Component {
|
|
|
26685
26697
|
});
|
|
26686
26698
|
}
|
|
26687
26699
|
}), /*#__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", {
|
|
26688
|
-
className: css(styles$
|
|
26700
|
+
className: css(styles$L.paddedY)
|
|
26689
26701
|
}, /*#__PURE__*/React.createElement(HeadingXSmall, null, "Button Sets"), buttonSetChoices), /*#__PURE__*/React.createElement(HeadingSmall, null, "Answers"), /*#__PURE__*/React.createElement("p", {
|
|
26690
26702
|
style: {
|
|
26691
26703
|
margin: "4px 0"
|
|
@@ -26756,18 +26768,18 @@ class AnswerOption extends React.Component {
|
|
|
26756
26768
|
color: "destructive",
|
|
26757
26769
|
light: true
|
|
26758
26770
|
}, "Delete");
|
|
26759
|
-
const answerStatusCss = css(styles$
|
|
26771
|
+
const answerStatusCss = css(styles$L.answerStatus, this.props.considered === "wrong" && styles$L.answerStatusWrong, this.props.considered === "correct" && styles$L.answerStatusCorrect, this.props.considered === "ungraded" && styles$L.answerStatusUngraded);
|
|
26760
26772
|
return /*#__PURE__*/React.createElement("div", {
|
|
26761
|
-
className: css(styles$
|
|
26773
|
+
className: css(styles$L.answerOption)
|
|
26762
26774
|
}, /*#__PURE__*/React.createElement("div", {
|
|
26763
|
-
className: css(styles$
|
|
26775
|
+
className: css(styles$L.answerHandle)
|
|
26764
26776
|
}), /*#__PURE__*/React.createElement("div", {
|
|
26765
|
-
className: css(styles$
|
|
26777
|
+
className: css(styles$L.answerBody)
|
|
26766
26778
|
}, /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("button", {
|
|
26767
26779
|
onClick: this.toggleConsidered,
|
|
26768
26780
|
className: answerStatusCss
|
|
26769
26781
|
}, this.props.considered), /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement(Expression, this.props.expressionProps))), /*#__PURE__*/React.createElement("div", {
|
|
26770
|
-
className: css(styles$
|
|
26782
|
+
className: css(styles$L.paddedY, styles$L.paddedX)
|
|
26771
26783
|
}, /*#__PURE__*/React.createElement(Checkbox$1, {
|
|
26772
26784
|
label: "Answer expression must have the same form.",
|
|
26773
26785
|
checked: this.props.form,
|
|
@@ -26777,7 +26789,7 @@ class AnswerOption extends React.Component {
|
|
|
26777
26789
|
});
|
|
26778
26790
|
}
|
|
26779
26791
|
}), /*#__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", {
|
|
26780
|
-
className: css(styles$
|
|
26792
|
+
className: css(styles$L.paddedY, styles$L.paddedX)
|
|
26781
26793
|
}, /*#__PURE__*/React.createElement(Checkbox$1, {
|
|
26782
26794
|
label: "Answer expression must be fully expanded and simplified.",
|
|
26783
26795
|
checked: this.props.simplify,
|
|
@@ -26787,11 +26799,11 @@ class AnswerOption extends React.Component {
|
|
|
26787
26799
|
});
|
|
26788
26800
|
}
|
|
26789
26801
|
}), /*#__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", {
|
|
26790
|
-
className: css(styles$
|
|
26802
|
+
className: css(styles$L.buttonRow, styles$L.paddedY)
|
|
26791
26803
|
}, removeButton)));
|
|
26792
26804
|
}
|
|
26793
26805
|
}
|
|
26794
|
-
const styles$
|
|
26806
|
+
const styles$L = StyleSheet.create({
|
|
26795
26807
|
paddedX: {
|
|
26796
26808
|
paddingLeft: spacing.xSmall_8,
|
|
26797
26809
|
paddingRight: spacing.xSmall_8
|
|
@@ -26886,10 +26898,10 @@ class GradedGroupEditor extends React.Component {
|
|
|
26886
26898
|
}, /*#__PURE__*/React.createElement("div", {
|
|
26887
26899
|
className: "perseus-widget-row"
|
|
26888
26900
|
}, /*#__PURE__*/React.createElement("label", {
|
|
26889
|
-
className: css(styles$
|
|
26901
|
+
className: css(styles$K.title)
|
|
26890
26902
|
}, "Title:", " ", /*#__PURE__*/React.createElement(TextInput$5, {
|
|
26891
26903
|
value: this.props.title,
|
|
26892
|
-
className: css(styles$
|
|
26904
|
+
className: css(styles$K.input)
|
|
26893
26905
|
// @ts-expect-error - TS2554 - Expected 3 arguments, but got 1.
|
|
26894
26906
|
,
|
|
26895
26907
|
onChange: this.change("title")
|
|
@@ -26914,7 +26926,7 @@ class GradedGroupEditor extends React.Component {
|
|
|
26914
26926
|
}, /*#__PURE__*/React.createElement(InlineIcon$4, iconPlus$1), " Add a hint"), this.props.hint && /*#__PURE__*/React.createElement("div", {
|
|
26915
26927
|
className: "perseus-hint-editor"
|
|
26916
26928
|
}, /*#__PURE__*/React.createElement("div", {
|
|
26917
|
-
className: css(styles$
|
|
26929
|
+
className: css(styles$K.hintsTitle)
|
|
26918
26930
|
}, "Hint"), /*#__PURE__*/React.createElement(Editor, {
|
|
26919
26931
|
ref: this.hintEditor,
|
|
26920
26932
|
content: this.props.hint ? this.props.hint.content : "",
|
|
@@ -26951,7 +26963,7 @@ GradedGroupEditor.defaultProps = {
|
|
|
26951
26963
|
images: {},
|
|
26952
26964
|
hint: null
|
|
26953
26965
|
};
|
|
26954
|
-
const styles$
|
|
26966
|
+
const styles$K = StyleSheet.create({
|
|
26955
26967
|
title: {
|
|
26956
26968
|
fontSize: 18,
|
|
26957
26969
|
fontWeight: "bold"
|
|
@@ -28410,13 +28422,13 @@ function MathquillInput(props) {
|
|
|
28410
28422
|
}
|
|
28411
28423
|
});
|
|
28412
28424
|
return /*#__PURE__*/React.createElement(View, {
|
|
28413
|
-
style: styles$
|
|
28425
|
+
style: styles$J.outerWrapper
|
|
28414
28426
|
}, /*#__PURE__*/React.createElement("span", {
|
|
28415
28427
|
ref: mathFieldWrapperRef,
|
|
28416
28428
|
className: "perseus-math-input mq-editable-field mq-math-mode"
|
|
28417
28429
|
}));
|
|
28418
28430
|
}
|
|
28419
|
-
const styles$
|
|
28431
|
+
const styles$J = StyleSheet.create({
|
|
28420
28432
|
outerWrapper: {
|
|
28421
28433
|
display: "inline-block",
|
|
28422
28434
|
borderStyle: "solid",
|
|
@@ -29520,7 +29532,7 @@ const GraphPointsCountSelector = ({
|
|
|
29520
29532
|
// Never uses placeholder, always has value
|
|
29521
29533
|
,
|
|
29522
29534
|
placeholder: "",
|
|
29523
|
-
style: styles$
|
|
29535
|
+
style: styles$I.singleSelectShort
|
|
29524
29536
|
}, [...[...Array(7).keys()].map(n => /*#__PURE__*/React.createElement(OptionItem, {
|
|
29525
29537
|
key: n,
|
|
29526
29538
|
value: `${n}`,
|
|
@@ -29531,7 +29543,7 @@ const GraphPointsCountSelector = ({
|
|
|
29531
29543
|
label: "unlimited"
|
|
29532
29544
|
})]);
|
|
29533
29545
|
};
|
|
29534
|
-
const styles$
|
|
29546
|
+
const styles$I = StyleSheet.create({
|
|
29535
29547
|
singleSelectShort: {
|
|
29536
29548
|
// Non-standard spacing, but it's the smallest we can go
|
|
29537
29549
|
// without running into styling issues with the dropdown.
|
|
@@ -29544,7 +29556,7 @@ const GraphTypeSelector = props => {
|
|
|
29544
29556
|
selectedValue: props.graphType,
|
|
29545
29557
|
onChange: props.onChange,
|
|
29546
29558
|
placeholder: "Select an answer type",
|
|
29547
|
-
style: styles$
|
|
29559
|
+
style: styles$H.singleSelectShort
|
|
29548
29560
|
}, props.showNoneOption && /*#__PURE__*/React.createElement(OptionItem, {
|
|
29549
29561
|
value: "none",
|
|
29550
29562
|
label: "None"
|
|
@@ -29580,7 +29592,7 @@ const GraphTypeSelector = props => {
|
|
|
29580
29592
|
label: "Angle"
|
|
29581
29593
|
}));
|
|
29582
29594
|
};
|
|
29583
|
-
const styles$
|
|
29595
|
+
const styles$H = StyleSheet.create({
|
|
29584
29596
|
singleSelectShort: {
|
|
29585
29597
|
// Non-standard spacing, but it's the smallest we can go
|
|
29586
29598
|
// without running into styling issues with the dropdown.
|
|
@@ -29595,11 +29607,11 @@ function Heading({
|
|
|
29595
29607
|
onToggle
|
|
29596
29608
|
}) {
|
|
29597
29609
|
return /*#__PURE__*/React.createElement(Clickable, {
|
|
29598
|
-
style: [styles$
|
|
29610
|
+
style: [styles$G.container, !isCollapsible && styles$G.notClickable],
|
|
29599
29611
|
disabled: !isCollapsible,
|
|
29600
29612
|
onClick: () => isCollapsible && (onToggle == null ? void 0 : onToggle(!isOpen))
|
|
29601
29613
|
}, () => /*#__PURE__*/React.createElement(View, {
|
|
29602
|
-
style: styles$
|
|
29614
|
+
style: styles$G.heading
|
|
29603
29615
|
}, /*#__PURE__*/React.createElement(LabelLarge, {
|
|
29604
29616
|
style: {
|
|
29605
29617
|
fontSize: 14,
|
|
@@ -29609,7 +29621,7 @@ function Heading({
|
|
|
29609
29621
|
isExpanded: isOpen
|
|
29610
29622
|
})));
|
|
29611
29623
|
}
|
|
29612
|
-
const styles$
|
|
29624
|
+
const styles$G = StyleSheet.create({
|
|
29613
29625
|
container: {
|
|
29614
29626
|
marginTop: spacing.small_12,
|
|
29615
29627
|
// NOTE(jeremy): This is the inverse of the @editorPadding CSS
|
|
@@ -29669,15 +29681,18 @@ function InteractiveGraphDescription(props) {
|
|
|
29669
29681
|
isOpen: isOpen,
|
|
29670
29682
|
onToggle: setIsOpen
|
|
29671
29683
|
}), isOpen && /*#__PURE__*/React.createElement(View, null, /*#__PURE__*/React.createElement(LabelXSmall, {
|
|
29672
|
-
style: styles$
|
|
29684
|
+
style: styles$F.caption
|
|
29673
29685
|
}, "Use these fields to describe the graph as a whole. These are used by screen readers to describe content to users who are visually impaired."), /*#__PURE__*/React.createElement(LabelLarge, {
|
|
29674
29686
|
tag: "label"
|
|
29675
29687
|
}, "Title", /*#__PURE__*/React.createElement(TextField, {
|
|
29676
29688
|
value: ariaLabelValue,
|
|
29677
29689
|
onChange: newValue => onChange({
|
|
29678
|
-
fullGraphAriaLabel:
|
|
29690
|
+
fullGraphAriaLabel:
|
|
29691
|
+
// Save as undefined if the new value
|
|
29692
|
+
// is an empty string.
|
|
29693
|
+
newValue || undefined
|
|
29679
29694
|
}),
|
|
29680
|
-
style: styles$
|
|
29695
|
+
style: styles$F.spaceAbove
|
|
29681
29696
|
})), /*#__PURE__*/React.createElement(Strut, {
|
|
29682
29697
|
size: spacing.small_12
|
|
29683
29698
|
}), /*#__PURE__*/React.createElement(LabelLarge, {
|
|
@@ -29687,12 +29702,15 @@ function InteractiveGraphDescription(props) {
|
|
|
29687
29702
|
resizeType: "vertical",
|
|
29688
29703
|
value: ariaDescriptionValue,
|
|
29689
29704
|
onChange: newValue => onChange({
|
|
29690
|
-
fullGraphAriaDescription:
|
|
29705
|
+
fullGraphAriaDescription:
|
|
29706
|
+
// Save as undefined if the new value
|
|
29707
|
+
// is an empty string.
|
|
29708
|
+
newValue || undefined
|
|
29691
29709
|
}),
|
|
29692
|
-
style: styles$
|
|
29710
|
+
style: styles$F.spaceAbove
|
|
29693
29711
|
}))));
|
|
29694
29712
|
}
|
|
29695
|
-
const styles$
|
|
29713
|
+
const styles$F = StyleSheet.create({
|
|
29696
29714
|
caption: {
|
|
29697
29715
|
color: color.offBlack64,
|
|
29698
29716
|
paddingTop: spacing.xxSmall_6,
|
|
@@ -29712,16 +29730,16 @@ const LabeledRow = props => {
|
|
|
29712
29730
|
style
|
|
29713
29731
|
} = props;
|
|
29714
29732
|
return /*#__PURE__*/React.createElement("label", {
|
|
29715
|
-
className: css(styles$
|
|
29733
|
+
className: css(styles$E.label)
|
|
29716
29734
|
}, /*#__PURE__*/React.createElement(View, {
|
|
29717
|
-
style: [styles$
|
|
29735
|
+
style: [styles$E.row, style]
|
|
29718
29736
|
}, labelSide === "start" || /*#__PURE__*/React.createElement(LabelSmall, {
|
|
29719
|
-
style: styles$
|
|
29737
|
+
style: styles$E.spaceEnd
|
|
29720
29738
|
}, label), children, labelSide === "end" && /*#__PURE__*/React.createElement(LabelSmall, {
|
|
29721
|
-
style: styles$
|
|
29739
|
+
style: styles$E.spaceStart
|
|
29722
29740
|
}, label)));
|
|
29723
29741
|
};
|
|
29724
|
-
const styles$
|
|
29742
|
+
const styles$E = StyleSheet.create({
|
|
29725
29743
|
label: {
|
|
29726
29744
|
width: "fit-content"
|
|
29727
29745
|
},
|
|
@@ -30115,10 +30133,10 @@ class InteractiveGraphSettings extends React.Component {
|
|
|
30115
30133
|
}
|
|
30116
30134
|
}))), /*#__PURE__*/React.createElement(LabeledRow, {
|
|
30117
30135
|
label: "Background image URL:",
|
|
30118
|
-
style: styles$
|
|
30136
|
+
style: styles$D.resetSpaceTop
|
|
30119
30137
|
}, /*#__PURE__*/React.createElement("input", {
|
|
30120
30138
|
type: "text",
|
|
30121
|
-
className: css(styles$
|
|
30139
|
+
className: css(styles$D.backgroundUrlInput),
|
|
30122
30140
|
ref: this.bgUrlRef,
|
|
30123
30141
|
value: this.state.backgroundImage.url || "",
|
|
30124
30142
|
onChange: e => {
|
|
@@ -30132,9 +30150,9 @@ class InteractiveGraphSettings extends React.Component {
|
|
|
30132
30150
|
onKeyPress: this.changeBackgroundUrl,
|
|
30133
30151
|
onBlur: this.changeBackgroundUrl
|
|
30134
30152
|
}), /*#__PURE__*/React.createElement(InfoTip$d, null, /*#__PURE__*/React.createElement("p", null, "Create an image in graphie, or use the \"Add image\" function to create a background."))), /*#__PURE__*/React.createElement(View, {
|
|
30135
|
-
style: styles$
|
|
30153
|
+
style: styles$D.protractorSection
|
|
30136
30154
|
}, /*#__PURE__*/React.createElement(View, {
|
|
30137
|
-
style: styles$
|
|
30155
|
+
style: styles$D.checkboxRow
|
|
30138
30156
|
}, /*#__PURE__*/React.createElement(Checkbox$1, {
|
|
30139
30157
|
label: "Show protractor",
|
|
30140
30158
|
checked: this.props.showProtractor,
|
|
@@ -30143,7 +30161,7 @@ class InteractiveGraphSettings extends React.Component {
|
|
|
30143
30161
|
showProtractor: value
|
|
30144
30162
|
});
|
|
30145
30163
|
},
|
|
30146
|
-
style: styles$
|
|
30164
|
+
style: styles$D.resetSpaceTop
|
|
30147
30165
|
})), this.props.showProtractor && /*#__PURE__*/React.createElement(Banner, {
|
|
30148
30166
|
layout: "floating",
|
|
30149
30167
|
text: "The protractor is not accessible. Please consider an alternate approach.",
|
|
@@ -30164,7 +30182,7 @@ InteractiveGraphSettings.defaultProps = {
|
|
|
30164
30182
|
showProtractor: false,
|
|
30165
30183
|
showTooltips: false
|
|
30166
30184
|
};
|
|
30167
|
-
const styles$
|
|
30185
|
+
const styles$D = StyleSheet.create({
|
|
30168
30186
|
resetSpaceTop: {
|
|
30169
30187
|
marginTop: 0
|
|
30170
30188
|
},
|
|
@@ -30201,13 +30219,13 @@ const SegmentCountSelector = ({
|
|
|
30201
30219
|
const num = +newValue;
|
|
30202
30220
|
onChange(num);
|
|
30203
30221
|
},
|
|
30204
|
-
style: styles$
|
|
30222
|
+
style: styles$C.singleSelectShort
|
|
30205
30223
|
}, _.range(1, 7).map(n => /*#__PURE__*/React.createElement(OptionItem, {
|
|
30206
30224
|
key: n,
|
|
30207
30225
|
value: `${n}`,
|
|
30208
30226
|
label: `${n} segment${n > 1 ? "s" : ""}`
|
|
30209
30227
|
})));
|
|
30210
|
-
const styles$
|
|
30228
|
+
const styles$C = StyleSheet.create({
|
|
30211
30229
|
singleSelectShort: {
|
|
30212
30230
|
// Non-standard spacing, but it's the smallest we can go
|
|
30213
30231
|
// without running into styling issues with the dropdown.
|
|
@@ -30232,17 +30250,17 @@ const LockedFigureSelect = props => {
|
|
|
30232
30250
|
figureTypes.push("label");
|
|
30233
30251
|
}
|
|
30234
30252
|
return /*#__PURE__*/React.createElement(View, {
|
|
30235
|
-
style: styles$
|
|
30253
|
+
style: styles$B.container
|
|
30236
30254
|
}, /*#__PURE__*/React.createElement(ActionMenu, {
|
|
30237
30255
|
menuText: "Add locked figure",
|
|
30238
|
-
style: styles$
|
|
30256
|
+
style: styles$B.addElementSelect
|
|
30239
30257
|
}, figureTypes.map(figureType => /*#__PURE__*/React.createElement(ActionItem, {
|
|
30240
30258
|
key: `${id}-${figureType}`,
|
|
30241
30259
|
label: figureType,
|
|
30242
30260
|
onClick: () => onChange(figureType)
|
|
30243
30261
|
}))));
|
|
30244
30262
|
};
|
|
30245
|
-
const styles$
|
|
30263
|
+
const styles$B = StyleSheet.create({
|
|
30246
30264
|
container: {
|
|
30247
30265
|
marginTop: spacing.xSmall_8
|
|
30248
30266
|
},
|
|
@@ -30359,18 +30377,18 @@ const AngleInput = props => {
|
|
|
30359
30377
|
}
|
|
30360
30378
|
return /*#__PURE__*/React.createElement(LabelMedium, {
|
|
30361
30379
|
tag: "label",
|
|
30362
|
-
style: styles$
|
|
30380
|
+
style: styles$A.row
|
|
30363
30381
|
}, "angle (degrees)", /*#__PURE__*/React.createElement(Strut, {
|
|
30364
30382
|
size: spacing.xxSmall_6
|
|
30365
30383
|
}), /*#__PURE__*/React.createElement(ScrolllessNumberTextField, {
|
|
30366
30384
|
value: angleInput,
|
|
30367
30385
|
onChange: handleAngleChange,
|
|
30368
|
-
style: styles$
|
|
30386
|
+
style: styles$A.textField
|
|
30369
30387
|
}), /*#__PURE__*/React.createElement(Strut, {
|
|
30370
30388
|
size: spacing.xxSmall_6
|
|
30371
30389
|
}));
|
|
30372
30390
|
};
|
|
30373
|
-
const styles$
|
|
30391
|
+
const styles$A = StyleSheet.create({
|
|
30374
30392
|
row: {
|
|
30375
30393
|
display: "flex",
|
|
30376
30394
|
flexDirection: "row",
|
|
@@ -30419,30 +30437,30 @@ const CoordinatePairInput = props => {
|
|
|
30419
30437
|
onChange(newCoords);
|
|
30420
30438
|
}
|
|
30421
30439
|
return /*#__PURE__*/React.createElement(View, {
|
|
30422
|
-
style: [styles$
|
|
30440
|
+
style: [styles$z.row, style]
|
|
30423
30441
|
}, /*#__PURE__*/React.createElement(LabelMedium, {
|
|
30424
30442
|
tag: "label",
|
|
30425
|
-
style: styles$
|
|
30443
|
+
style: styles$z.row
|
|
30426
30444
|
}, labels ? labels[0] : "x coord", /*#__PURE__*/React.createElement(Strut, {
|
|
30427
30445
|
size: spacing.xxSmall_6
|
|
30428
30446
|
}), /*#__PURE__*/React.createElement(ScrolllessNumberTextField, {
|
|
30429
30447
|
value: coordState[0],
|
|
30430
30448
|
onChange: newValue => handleCoordChange(newValue, 0),
|
|
30431
|
-
style: [styles$
|
|
30449
|
+
style: [styles$z.textField, error ? styles$z.errorField : undefined]
|
|
30432
30450
|
})), /*#__PURE__*/React.createElement(Strut, {
|
|
30433
30451
|
size: spacing.medium_16
|
|
30434
30452
|
}), /*#__PURE__*/React.createElement(LabelMedium, {
|
|
30435
30453
|
tag: "label",
|
|
30436
|
-
style: styles$
|
|
30454
|
+
style: styles$z.row
|
|
30437
30455
|
}, labels ? labels[1] : "y coord", /*#__PURE__*/React.createElement(Strut, {
|
|
30438
30456
|
size: spacing.xxSmall_6
|
|
30439
30457
|
}), /*#__PURE__*/React.createElement(ScrolllessNumberTextField, {
|
|
30440
30458
|
value: coordState[1],
|
|
30441
30459
|
onChange: newValue => handleCoordChange(newValue, 1),
|
|
30442
|
-
style: [styles$
|
|
30460
|
+
style: [styles$z.textField, error ? styles$z.errorField : undefined]
|
|
30443
30461
|
})));
|
|
30444
30462
|
};
|
|
30445
|
-
const styles$
|
|
30463
|
+
const styles$z = StyleSheet.create({
|
|
30446
30464
|
row: {
|
|
30447
30465
|
display: "flex",
|
|
30448
30466
|
flexDirection: "row",
|
|
@@ -30475,14 +30493,14 @@ const PerseusEditorAccordion = props => {
|
|
|
30475
30493
|
}, /*#__PURE__*/React.createElement(AccordionSection, {
|
|
30476
30494
|
expanded: expanded,
|
|
30477
30495
|
onToggle: onToggle,
|
|
30478
|
-
style: [styles$
|
|
30479
|
-
headerStyle: styles$
|
|
30496
|
+
style: [styles$y.container, containerStyle],
|
|
30497
|
+
headerStyle: styles$y.accordionHeader,
|
|
30480
30498
|
header: header
|
|
30481
30499
|
}, /*#__PURE__*/React.createElement(View, {
|
|
30482
|
-
style: [styles$
|
|
30500
|
+
style: [styles$y.accordionPanel, panelStyle]
|
|
30483
30501
|
}, children)));
|
|
30484
30502
|
};
|
|
30485
|
-
const styles$
|
|
30503
|
+
const styles$y = StyleSheet.create({
|
|
30486
30504
|
container: {
|
|
30487
30505
|
backgroundColor: color.fadedBlue8,
|
|
30488
30506
|
marginTop: spacing.xSmall_8
|
|
@@ -30513,13 +30531,13 @@ const ColorSwatch = props => {
|
|
|
30513
30531
|
"aria-label":
|
|
30514
30532
|
// Don't include an aria label for decorative circles.
|
|
30515
30533
|
!decorative ? `${color$1}, ${filled ? "filled" : "open"}` : undefined,
|
|
30516
|
-
style: [styles$
|
|
30534
|
+
style: [styles$x.colorSwatch, {
|
|
30517
30535
|
border: `4px solid ${lockedFigureColors[color$1]}`,
|
|
30518
30536
|
backgroundColor: filled ? lockedFigureColors[color$1] : color.white
|
|
30519
30537
|
}]
|
|
30520
30538
|
});
|
|
30521
30539
|
};
|
|
30522
|
-
const styles$
|
|
30540
|
+
const styles$x = StyleSheet.create({
|
|
30523
30541
|
colorSwatch: {
|
|
30524
30542
|
// Add a white outline so that the color swatch is visible when
|
|
30525
30543
|
// the dropdown option is highlighted with its blue background.
|
|
@@ -30538,10 +30556,10 @@ const ColorSelect = props => {
|
|
|
30538
30556
|
onChange
|
|
30539
30557
|
} = props;
|
|
30540
30558
|
return /*#__PURE__*/React.createElement(View, {
|
|
30541
|
-
style: [styles$
|
|
30559
|
+
style: [styles$w.row, style]
|
|
30542
30560
|
}, /*#__PURE__*/React.createElement(LabelMedium, {
|
|
30543
30561
|
tag: "label",
|
|
30544
|
-
style: styles$
|
|
30562
|
+
style: styles$w.row
|
|
30545
30563
|
}, "color", /*#__PURE__*/React.createElement(Strut, {
|
|
30546
30564
|
size: spacing.xxSmall_6
|
|
30547
30565
|
}), /*#__PURE__*/React.createElement(SingleSelect, {
|
|
@@ -30560,7 +30578,7 @@ const ColorSelect = props => {
|
|
|
30560
30578
|
})
|
|
30561
30579
|
})))));
|
|
30562
30580
|
};
|
|
30563
|
-
const styles$
|
|
30581
|
+
const styles$w = StyleSheet.create({
|
|
30564
30582
|
row: {
|
|
30565
30583
|
display: "flex",
|
|
30566
30584
|
flexDirection: "row",
|
|
@@ -30579,17 +30597,17 @@ const EllipseSwatch = props => {
|
|
|
30579
30597
|
} = props;
|
|
30580
30598
|
return /*#__PURE__*/React.createElement(View, {
|
|
30581
30599
|
"aria-label": `${color}, stroke ${strokeStyle}, fill ${fillStyle}`,
|
|
30582
|
-
style: [styles$
|
|
30600
|
+
style: [styles$v.container, {
|
|
30583
30601
|
border: `4px ${strokeStyle} ${lockedFigureColors[color]}`
|
|
30584
30602
|
}]
|
|
30585
30603
|
}, /*#__PURE__*/React.createElement(View, {
|
|
30586
|
-
style: [styles$
|
|
30604
|
+
style: [styles$v.innerCircle, {
|
|
30587
30605
|
backgroundColor: lockedFigureColors[color],
|
|
30588
30606
|
opacity: fillStyle === "white" ? 0 : lockedFigureFillStyles[fillStyle]
|
|
30589
30607
|
}]
|
|
30590
30608
|
}));
|
|
30591
30609
|
};
|
|
30592
|
-
const styles$
|
|
30610
|
+
const styles$v = StyleSheet.create({
|
|
30593
30611
|
container: {
|
|
30594
30612
|
// Add a white outline so that the color swatch is visible when
|
|
30595
30613
|
// the dropdown option is highlighted with its blue background.
|
|
@@ -30615,7 +30633,7 @@ const LineStrokeSelect = props => {
|
|
|
30615
30633
|
} = props;
|
|
30616
30634
|
return /*#__PURE__*/React.createElement(LabelMedium, {
|
|
30617
30635
|
tag: "label",
|
|
30618
|
-
style: styles$
|
|
30636
|
+
style: styles$u.lineStrokeSelect
|
|
30619
30637
|
}, "stroke", /*#__PURE__*/React.createElement(Strut, {
|
|
30620
30638
|
size: spacing.xxxSmall_4
|
|
30621
30639
|
}), /*#__PURE__*/React.createElement(SingleSelect, {
|
|
@@ -30632,7 +30650,7 @@ const LineStrokeSelect = props => {
|
|
|
30632
30650
|
label: "dashed"
|
|
30633
30651
|
})));
|
|
30634
30652
|
};
|
|
30635
|
-
const styles$
|
|
30653
|
+
const styles$u = StyleSheet.create({
|
|
30636
30654
|
lineStrokeSelect: {
|
|
30637
30655
|
display: "flex",
|
|
30638
30656
|
flexDirection: "row",
|
|
@@ -30654,40 +30672,40 @@ const LockedFigureSettingsActions = props => {
|
|
|
30654
30672
|
onRemove
|
|
30655
30673
|
} = props;
|
|
30656
30674
|
return /*#__PURE__*/React.createElement(View, {
|
|
30657
|
-
style: styles$
|
|
30675
|
+
style: styles$t.container
|
|
30658
30676
|
}, /*#__PURE__*/React.createElement(Button, {
|
|
30659
30677
|
startIcon: trashIcon,
|
|
30660
30678
|
"aria-label": `Delete locked ${figureType}`,
|
|
30661
30679
|
onClick: onRemove,
|
|
30662
30680
|
kind: "tertiary",
|
|
30663
|
-
style: styles$
|
|
30681
|
+
style: styles$t.deleteButton
|
|
30664
30682
|
}, "Delete"), onMove && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(Spring, null), /*#__PURE__*/React.createElement(IconButton, {
|
|
30665
30683
|
icon: caretDoubleUpIcon,
|
|
30666
30684
|
size: "small",
|
|
30667
30685
|
"aria-label": `Move locked ${figureType} to the back`,
|
|
30668
30686
|
onClick: () => onMove("back"),
|
|
30669
|
-
style: styles$
|
|
30687
|
+
style: styles$t.iconButton
|
|
30670
30688
|
}), /*#__PURE__*/React.createElement(IconButton, {
|
|
30671
30689
|
icon: caretUpIcon,
|
|
30672
30690
|
size: "small",
|
|
30673
30691
|
"aria-label": `Move locked ${figureType} backward`,
|
|
30674
30692
|
onClick: () => onMove("backward"),
|
|
30675
|
-
style: styles$
|
|
30693
|
+
style: styles$t.iconButton
|
|
30676
30694
|
}), /*#__PURE__*/React.createElement(IconButton, {
|
|
30677
30695
|
icon: caretDownIcon,
|
|
30678
30696
|
size: "small",
|
|
30679
30697
|
"aria-label": `Move locked ${figureType} forward`,
|
|
30680
30698
|
onClick: () => onMove("forward"),
|
|
30681
|
-
style: styles$
|
|
30699
|
+
style: styles$t.iconButton
|
|
30682
30700
|
}), /*#__PURE__*/React.createElement(IconButton, {
|
|
30683
30701
|
icon: caretDoubleDownIcon,
|
|
30684
30702
|
size: "small",
|
|
30685
30703
|
"aria-label": `Move locked ${figureType} to the front`,
|
|
30686
30704
|
onClick: () => onMove("front"),
|
|
30687
|
-
style: styles$
|
|
30705
|
+
style: styles$t.iconButton
|
|
30688
30706
|
})));
|
|
30689
30707
|
};
|
|
30690
|
-
const styles$
|
|
30708
|
+
const styles$t = StyleSheet.create({
|
|
30691
30709
|
container: {
|
|
30692
30710
|
width: "100%",
|
|
30693
30711
|
flexDirection: "row",
|
|
@@ -30705,907 +30723,839 @@ const styles$u = StyleSheet.create({
|
|
|
30705
30723
|
}
|
|
30706
30724
|
});
|
|
30707
30725
|
|
|
30708
|
-
|
|
30709
|
-
|
|
30710
|
-
|
|
30711
|
-
|
|
30726
|
+
/**
|
|
30727
|
+
* LockedLabelSettings is a component that allows the user to edit the
|
|
30728
|
+
* settings of specifically a locked label on the graph within the
|
|
30729
|
+
* Interactive Graph widget.
|
|
30730
|
+
*
|
|
30731
|
+
* Used in the interactive graph editor's locked figures section.
|
|
30732
|
+
*/
|
|
30733
|
+
function LockedLabelSettings(props) {
|
|
30712
30734
|
const {
|
|
30713
|
-
|
|
30714
|
-
|
|
30715
|
-
|
|
30716
|
-
|
|
30717
|
-
|
|
30718
|
-
strokeStyle,
|
|
30735
|
+
type,
|
|
30736
|
+
coord,
|
|
30737
|
+
color: color$1,
|
|
30738
|
+
size,
|
|
30739
|
+
text,
|
|
30719
30740
|
expanded,
|
|
30720
|
-
onToggle,
|
|
30721
30741
|
onChangeProps,
|
|
30722
30742
|
onMove,
|
|
30723
|
-
onRemove
|
|
30743
|
+
onRemove,
|
|
30744
|
+
onToggle,
|
|
30745
|
+
containerStyle
|
|
30724
30746
|
} = props;
|
|
30725
|
-
function handleColorChange(newValue) {
|
|
30726
|
-
onChangeProps({
|
|
30727
|
-
color: newValue
|
|
30728
|
-
});
|
|
30729
|
-
}
|
|
30730
30747
|
return /*#__PURE__*/React.createElement(PerseusEditorAccordion, {
|
|
30731
30748
|
expanded: expanded,
|
|
30732
30749
|
onToggle: onToggle,
|
|
30733
|
-
header:
|
|
30734
|
-
|
|
30735
|
-
|
|
30736
|
-
React.createElement(View, {
|
|
30737
|
-
style: styles$t.row
|
|
30738
|
-
}, /*#__PURE__*/React.createElement(LabelLarge, null, `Ellipse (${center[0]}, ${center[1]}), radius ${radius[0]}, ${radius[1]}`), /*#__PURE__*/React.createElement(Strut, {
|
|
30750
|
+
header: /*#__PURE__*/React.createElement(View, {
|
|
30751
|
+
style: [styles$s.row, styles$s.accordionHeaderContainer]
|
|
30752
|
+
}, /*#__PURE__*/React.createElement(LabelLarge, null, "Label (", coord[0], ", ", coord[1], ")"), /*#__PURE__*/React.createElement(Strut, {
|
|
30739
30753
|
size: spacing.xSmall_8
|
|
30740
|
-
}), /*#__PURE__*/React.createElement(
|
|
30741
|
-
|
|
30742
|
-
|
|
30743
|
-
|
|
30744
|
-
|
|
30745
|
-
|
|
30746
|
-
|
|
30754
|
+
}), text !== "" && /*#__PURE__*/React.createElement(LabelLarge, {
|
|
30755
|
+
style: [{
|
|
30756
|
+
backgroundColor: color.white,
|
|
30757
|
+
color: lockedFigureColors[color$1]
|
|
30758
|
+
}, styles$s.accordionHeader]
|
|
30759
|
+
}, text)),
|
|
30760
|
+
containerStyle: containerStyle
|
|
30747
30761
|
}, /*#__PURE__*/React.createElement(CoordinatePairInput, {
|
|
30748
|
-
coord:
|
|
30749
|
-
|
|
30750
|
-
|
|
30751
|
-
|
|
30752
|
-
|
|
30753
|
-
|
|
30754
|
-
style: styles$
|
|
30755
|
-
}
|
|
30756
|
-
|
|
30757
|
-
|
|
30758
|
-
|
|
30759
|
-
onChange: newCoords => onChangeProps({
|
|
30760
|
-
radius: newCoords
|
|
30761
|
-
})
|
|
30762
|
-
}), /*#__PURE__*/React.createElement(AngleInput, {
|
|
30763
|
-
angle: angle,
|
|
30764
|
-
onChange: newAngle => onChangeProps({
|
|
30765
|
-
angle: newAngle
|
|
30766
|
-
})
|
|
30767
|
-
}), /*#__PURE__*/React.createElement(Strut, {
|
|
30762
|
+
coord: coord,
|
|
30763
|
+
onChange: newCoords => {
|
|
30764
|
+
onChangeProps({
|
|
30765
|
+
coord: newCoords
|
|
30766
|
+
});
|
|
30767
|
+
},
|
|
30768
|
+
style: styles$s.spaceUnder
|
|
30769
|
+
}), /*#__PURE__*/React.createElement(LabelMedium, {
|
|
30770
|
+
tag: "label",
|
|
30771
|
+
style: [styles$s.row, styles$s.spaceUnder]
|
|
30772
|
+
}, "TeX", /*#__PURE__*/React.createElement(Strut, {
|
|
30768
30773
|
size: spacing.xSmall_8
|
|
30769
|
-
}), /*#__PURE__*/React.createElement(
|
|
30770
|
-
|
|
30771
|
-
|
|
30772
|
-
|
|
30773
|
-
|
|
30774
|
+
}), /*#__PURE__*/React.createElement(TextField, {
|
|
30775
|
+
value: text,
|
|
30776
|
+
placeholder: "ex. x^2 or \\frac{1}{2}",
|
|
30777
|
+
onChange: newValue => onChangeProps({
|
|
30778
|
+
text: newValue
|
|
30779
|
+
})
|
|
30780
|
+
})), /*#__PURE__*/React.createElement(View, {
|
|
30781
|
+
style: styles$s.row
|
|
30782
|
+
}, onMove && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(ColorSelect, {
|
|
30783
|
+
selectedValue: color$1,
|
|
30784
|
+
onChange: newColor => {
|
|
30785
|
+
onChangeProps({
|
|
30786
|
+
color: newColor
|
|
30787
|
+
});
|
|
30788
|
+
},
|
|
30789
|
+
style: styles$s.spaceUnder
|
|
30774
30790
|
}), /*#__PURE__*/React.createElement(Strut, {
|
|
30775
30791
|
size: spacing.medium_16
|
|
30776
|
-
}), /*#__PURE__*/React.createElement(LabelMedium, {
|
|
30792
|
+
})), /*#__PURE__*/React.createElement(LabelMedium, {
|
|
30777
30793
|
tag: "label",
|
|
30778
|
-
style:
|
|
30779
|
-
}, "
|
|
30780
|
-
size: spacing.
|
|
30794
|
+
style: styles$s.row
|
|
30795
|
+
}, "size", /*#__PURE__*/React.createElement(Strut, {
|
|
30796
|
+
size: spacing.xSmall_8
|
|
30781
30797
|
}), /*#__PURE__*/React.createElement(SingleSelect, {
|
|
30782
|
-
selectedValue:
|
|
30783
|
-
onChange:
|
|
30784
|
-
|
|
30798
|
+
selectedValue: size,
|
|
30799
|
+
onChange: newValue => onChangeProps({
|
|
30800
|
+
size: newValue
|
|
30785
30801
|
})
|
|
30786
|
-
// Placeholder is required, but never gets used
|
|
30802
|
+
// Placeholder is required, but never gets used since
|
|
30803
|
+
// we have a label for the select.
|
|
30787
30804
|
,
|
|
30788
30805
|
placeholder: ""
|
|
30789
|
-
},
|
|
30790
|
-
|
|
30791
|
-
|
|
30792
|
-
|
|
30793
|
-
|
|
30794
|
-
|
|
30795
|
-
|
|
30796
|
-
|
|
30797
|
-
|
|
30798
|
-
}), /*#__PURE__*/React.createElement(LockedFigureSettingsActions, {
|
|
30799
|
-
figureType:
|
|
30806
|
+
}, /*#__PURE__*/React.createElement(OptionItem, {
|
|
30807
|
+
value: "small",
|
|
30808
|
+
label: "small"
|
|
30809
|
+
}), /*#__PURE__*/React.createElement(OptionItem, {
|
|
30810
|
+
value: "medium",
|
|
30811
|
+
label: "medium"
|
|
30812
|
+
}), /*#__PURE__*/React.createElement(OptionItem, {
|
|
30813
|
+
value: "large",
|
|
30814
|
+
label: "large"
|
|
30815
|
+
})))), /*#__PURE__*/React.createElement(LockedFigureSettingsActions, {
|
|
30816
|
+
figureType: type,
|
|
30800
30817
|
onMove: onMove,
|
|
30801
30818
|
onRemove: onRemove
|
|
30802
30819
|
}));
|
|
30803
|
-
}
|
|
30804
|
-
const styles$
|
|
30820
|
+
}
|
|
30821
|
+
const styles$s = StyleSheet.create({
|
|
30822
|
+
accordionHeaderContainer: {
|
|
30823
|
+
// Stop the label summary from wrapping.
|
|
30824
|
+
whiteSpace: "nowrap"
|
|
30825
|
+
},
|
|
30826
|
+
accordionHeader: {
|
|
30827
|
+
padding: spacing.xxxSmall_4,
|
|
30828
|
+
marginInlineEnd: spacing.xSmall_8,
|
|
30829
|
+
borderRadius: spacing.xxxSmall_4,
|
|
30830
|
+
textOverflow: "ellipsis",
|
|
30831
|
+
overflow: "hidden"
|
|
30832
|
+
},
|
|
30805
30833
|
row: {
|
|
30806
30834
|
display: "flex",
|
|
30807
30835
|
flexDirection: "row",
|
|
30808
|
-
alignItems: "center"
|
|
30809
|
-
},
|
|
30810
|
-
spaceUnder: {
|
|
30811
|
-
marginBottom: spacing.xSmall_8
|
|
30812
|
-
},
|
|
30813
|
-
truncatedWidth: {
|
|
30836
|
+
alignItems: "center",
|
|
30814
30837
|
// Allow truncation, stop bleeding over the edge.
|
|
30815
30838
|
minWidth: 0
|
|
30816
|
-
}
|
|
30817
|
-
});
|
|
30818
|
-
|
|
30819
|
-
const LineSwatch = props => {
|
|
30820
|
-
const {
|
|
30821
|
-
color,
|
|
30822
|
-
lineStyle
|
|
30823
|
-
} = props;
|
|
30824
|
-
return /*#__PURE__*/React.createElement(View, {
|
|
30825
|
-
style: styles$s.container
|
|
30826
|
-
}, /*#__PURE__*/React.createElement(View, {
|
|
30827
|
-
"aria-label": `${color}, ${lineStyle}`,
|
|
30828
|
-
style: [styles$s.lineSwatch, {
|
|
30829
|
-
border: `5px ${lineStyle} ${lockedFigureColors[color]}`
|
|
30830
|
-
}]
|
|
30831
|
-
}));
|
|
30832
|
-
};
|
|
30833
|
-
const styles$s = StyleSheet.create({
|
|
30834
|
-
container: {
|
|
30835
|
-
backgroundColor: color.white,
|
|
30836
|
-
justifyContent: "center",
|
|
30837
|
-
padding: spacing.xSmall_8,
|
|
30838
|
-
borderRadius: spacing.xxxSmall_4
|
|
30839
30839
|
},
|
|
30840
|
-
|
|
30841
|
-
|
|
30840
|
+
spaceUnder: {
|
|
30841
|
+
marginBottom: spacing.xSmall_8
|
|
30842
30842
|
}
|
|
30843
30843
|
});
|
|
30844
30844
|
|
|
30845
|
-
const
|
|
30846
|
-
|
|
30847
|
-
|
|
30848
|
-
|
|
30849
|
-
|
|
30850
|
-
|
|
30851
|
-
|
|
30852
|
-
|
|
30853
|
-
|
|
30854
|
-
|
|
30855
|
-
|
|
30856
|
-
|
|
30857
|
-
|
|
30858
|
-
|
|
30859
|
-
|
|
30845
|
+
const DEFAULT_COLOR = "grayH";
|
|
30846
|
+
function getDefaultFigureForType(type) {
|
|
30847
|
+
switch (type) {
|
|
30848
|
+
case "point":
|
|
30849
|
+
return {
|
|
30850
|
+
type: "point",
|
|
30851
|
+
coord: [0, 0],
|
|
30852
|
+
color: DEFAULT_COLOR,
|
|
30853
|
+
filled: true
|
|
30854
|
+
};
|
|
30855
|
+
case "line":
|
|
30856
|
+
return {
|
|
30857
|
+
type: "line",
|
|
30858
|
+
kind: "line",
|
|
30859
|
+
points: [getDefaultFigureForType("point"), _extends({}, getDefaultFigureForType("point"), {
|
|
30860
|
+
coord: [2, 2]
|
|
30861
|
+
})],
|
|
30862
|
+
color: DEFAULT_COLOR,
|
|
30863
|
+
lineStyle: "solid",
|
|
30864
|
+
showPoint1: false,
|
|
30865
|
+
showPoint2: false
|
|
30866
|
+
};
|
|
30867
|
+
case "vector":
|
|
30868
|
+
return {
|
|
30869
|
+
type: "vector",
|
|
30870
|
+
points: [[0, 0], [2, 2]],
|
|
30871
|
+
color: DEFAULT_COLOR
|
|
30872
|
+
};
|
|
30873
|
+
case "ellipse":
|
|
30874
|
+
return {
|
|
30875
|
+
type: "ellipse",
|
|
30876
|
+
center: [0, 0],
|
|
30877
|
+
radius: [1, 1],
|
|
30878
|
+
angle: 0,
|
|
30879
|
+
color: DEFAULT_COLOR,
|
|
30880
|
+
fillStyle: "none",
|
|
30881
|
+
strokeStyle: "solid"
|
|
30882
|
+
};
|
|
30883
|
+
case "polygon":
|
|
30884
|
+
return {
|
|
30885
|
+
type: "polygon",
|
|
30886
|
+
points: [[0, 2], [-1, 0], [1, 0]],
|
|
30887
|
+
color: DEFAULT_COLOR,
|
|
30888
|
+
showVertices: false,
|
|
30889
|
+
fillStyle: "none",
|
|
30890
|
+
strokeStyle: "solid"
|
|
30891
|
+
};
|
|
30892
|
+
case "function":
|
|
30893
|
+
return {
|
|
30894
|
+
type: "function",
|
|
30895
|
+
color: DEFAULT_COLOR,
|
|
30896
|
+
strokeStyle: "solid",
|
|
30897
|
+
equation: "x^2",
|
|
30898
|
+
directionalAxis: "x"
|
|
30899
|
+
};
|
|
30900
|
+
case "label":
|
|
30901
|
+
return {
|
|
30902
|
+
type: "label",
|
|
30903
|
+
coord: [0, 0],
|
|
30904
|
+
text: "",
|
|
30905
|
+
color: DEFAULT_COLOR,
|
|
30906
|
+
size: "medium"
|
|
30907
|
+
};
|
|
30908
|
+
default:
|
|
30909
|
+
throw new UnreachableCaseError(type);
|
|
30910
|
+
}
|
|
30911
|
+
}
|
|
30912
|
+
|
|
30913
|
+
const {
|
|
30914
|
+
InfoTip: InfoTip$c
|
|
30915
|
+
} = components;
|
|
30916
|
+
const LockedEllipseSettings = props => {
|
|
30917
|
+
var _flags$mafs;
|
|
30918
|
+
const {
|
|
30919
|
+
flags,
|
|
30920
|
+
center,
|
|
30921
|
+
radius,
|
|
30922
|
+
angle,
|
|
30923
|
+
color,
|
|
30924
|
+
labels,
|
|
30925
|
+
fillStyle,
|
|
30860
30926
|
strokeStyle,
|
|
30861
|
-
|
|
30862
|
-
|
|
30863
|
-
domain,
|
|
30927
|
+
expanded,
|
|
30928
|
+
onToggle,
|
|
30864
30929
|
onChangeProps,
|
|
30865
30930
|
onMove,
|
|
30866
30931
|
onRemove
|
|
30867
30932
|
} = props;
|
|
30868
|
-
|
|
30869
|
-
|
|
30870
|
-
|
|
30871
|
-
|
|
30872
|
-
|
|
30873
|
-
|
|
30874
|
-
// This variable is used when specifying the values of the input fields.
|
|
30875
|
-
const [domainEntries, setDomainEntries] = useState([domain && domain[0] !== -Infinity ? domain[0].toString() : "", domain && domain[1] !== Infinity ? domain[1].toString() : ""]);
|
|
30876
|
-
const [exampleCategory, setExampleCategory] = useState("");
|
|
30877
|
-
useEffect(() => {
|
|
30878
|
-
// "useEffect" used to maintain parity between domain/range constraints and their string representation.
|
|
30879
|
-
setDomainEntries([domain && domain[0] !== -Infinity ? domain[0].toString() : "", domain && domain[1] !== Infinity ? domain[1].toString() : ""]);
|
|
30880
|
-
}, [domain]);
|
|
30933
|
+
function handleCenterChange(newCoord) {
|
|
30934
|
+
const xOffset = newCoord[0] - center[0];
|
|
30935
|
+
const yOffset = newCoord[1] - center[1];
|
|
30936
|
+
const newProps = {
|
|
30937
|
+
center: newCoord
|
|
30938
|
+
};
|
|
30881
30939
|
|
|
30882
|
-
|
|
30883
|
-
|
|
30884
|
-
|
|
30885
|
-
|
|
30886
|
-
onChangeProps(
|
|
30940
|
+
// Update the coord by the same amount as the point for all labels
|
|
30941
|
+
newProps.labels = labels == null ? void 0 : labels.map(label => _extends({}, label, {
|
|
30942
|
+
coord: [label.coord[0] + xOffset, label.coord[1] + yOffset]
|
|
30943
|
+
}));
|
|
30944
|
+
onChangeProps(newProps);
|
|
30887
30945
|
}
|
|
30946
|
+
function handleColorChange(newValue) {
|
|
30947
|
+
const newProps = {
|
|
30948
|
+
color: newValue
|
|
30949
|
+
};
|
|
30888
30950
|
|
|
30889
|
-
|
|
30890
|
-
|
|
30891
|
-
|
|
30892
|
-
|
|
30893
|
-
|
|
30894
|
-
|
|
30895
|
-
function
|
|
30896
|
-
|
|
30897
|
-
|
|
30898
|
-
setDomainEntries(newDomainEntries);
|
|
30899
|
-
const newDomain = domain ? [...domain] : [-Infinity, Infinity];
|
|
30900
|
-
let newValue = parseFloat(newValueString);
|
|
30901
|
-
if (newValueString === "" && limitIndex === 0) {
|
|
30902
|
-
newValue = -Infinity;
|
|
30903
|
-
} else if (newValueString === "" && limitIndex === 1) {
|
|
30904
|
-
newValue = Infinity;
|
|
30951
|
+
// Update the color of the all labels to match the point
|
|
30952
|
+
newProps.labels = labels == null ? void 0 : labels.map(label => _extends({}, label, {
|
|
30953
|
+
color: newValue
|
|
30954
|
+
}));
|
|
30955
|
+
onChangeProps(newProps);
|
|
30956
|
+
}
|
|
30957
|
+
function handleLabelChange(updatedLabel, labelIndex) {
|
|
30958
|
+
if (!labels) {
|
|
30959
|
+
return;
|
|
30905
30960
|
}
|
|
30906
|
-
|
|
30961
|
+
const updatedLabels = [...labels];
|
|
30962
|
+
updatedLabels[labelIndex] = _extends({}, labels[labelIndex], updatedLabel);
|
|
30907
30963
|
onChangeProps({
|
|
30908
|
-
|
|
30964
|
+
labels: updatedLabels
|
|
30965
|
+
});
|
|
30966
|
+
}
|
|
30967
|
+
function handleLabelRemove(labelIndex) {
|
|
30968
|
+
if (!labels) {
|
|
30969
|
+
return;
|
|
30970
|
+
}
|
|
30971
|
+
const updatedLabels = labels.filter((_, index) => index !== labelIndex);
|
|
30972
|
+
onChangeProps({
|
|
30973
|
+
labels: updatedLabels
|
|
30909
30974
|
});
|
|
30910
30975
|
}
|
|
30911
|
-
const exampleCategories = Object.keys(examples);
|
|
30912
|
-
const exampleCategorySelected = exampleCategory !== "";
|
|
30913
|
-
const exampleContent = exampleCategorySelected ? examples[exampleCategory] : ["Select category to see example equations"];
|
|
30914
30976
|
return /*#__PURE__*/React.createElement(PerseusEditorAccordion, {
|
|
30915
|
-
expanded:
|
|
30916
|
-
onToggle:
|
|
30917
|
-
header:
|
|
30977
|
+
expanded: expanded,
|
|
30978
|
+
onToggle: onToggle,
|
|
30979
|
+
header:
|
|
30980
|
+
/*#__PURE__*/
|
|
30981
|
+
// Summary: Ellipse, center, radius, color (opacity, dashed)
|
|
30982
|
+
React.createElement(View, {
|
|
30918
30983
|
style: styles$r.row
|
|
30919
|
-
}, /*#__PURE__*/React.createElement(LabelLarge, {
|
|
30920
|
-
style: styles$r.accordionHeader
|
|
30921
|
-
}, lineLabel), /*#__PURE__*/React.createElement(Strut, {
|
|
30984
|
+
}, /*#__PURE__*/React.createElement(LabelLarge, null, `Ellipse (${center[0]}, ${center[1]}), radius ${radius[0]}, ${radius[1]}`), /*#__PURE__*/React.createElement(Strut, {
|
|
30922
30985
|
size: spacing.xSmall_8
|
|
30923
|
-
}), /*#__PURE__*/React.createElement(
|
|
30924
|
-
color:
|
|
30925
|
-
|
|
30986
|
+
}), /*#__PURE__*/React.createElement(EllipseSwatch, {
|
|
30987
|
+
color: props.color,
|
|
30988
|
+
fillStyle: fillStyle,
|
|
30989
|
+
strokeStyle: strokeStyle
|
|
30926
30990
|
}))
|
|
30927
30991
|
}, /*#__PURE__*/React.createElement(View, {
|
|
30992
|
+
style: styles$r.row
|
|
30993
|
+
}, /*#__PURE__*/React.createElement(CoordinatePairInput, {
|
|
30994
|
+
coord: center,
|
|
30995
|
+
style: styles$r.spaceUnder,
|
|
30996
|
+
onChange: handleCenterChange
|
|
30997
|
+
}), /*#__PURE__*/React.createElement(View, {
|
|
30998
|
+
style: styles$r.spaceUnder
|
|
30999
|
+
}, /*#__PURE__*/React.createElement(InfoTip$c, null, "The coordinates for the center of the ellipse."))), /*#__PURE__*/React.createElement(CoordinatePairInput, {
|
|
31000
|
+
coord: radius,
|
|
31001
|
+
labels: ["x radius", "y radius"],
|
|
31002
|
+
style: styles$r.spaceUnder,
|
|
31003
|
+
onChange: newCoords => onChangeProps({
|
|
31004
|
+
radius: newCoords
|
|
31005
|
+
})
|
|
31006
|
+
}), /*#__PURE__*/React.createElement(AngleInput, {
|
|
31007
|
+
angle: angle,
|
|
31008
|
+
onChange: newAngle => onChangeProps({
|
|
31009
|
+
angle: newAngle
|
|
31010
|
+
})
|
|
31011
|
+
}), /*#__PURE__*/React.createElement(Strut, {
|
|
31012
|
+
size: spacing.xSmall_8
|
|
31013
|
+
}), /*#__PURE__*/React.createElement(View, {
|
|
30928
31014
|
style: [styles$r.row, styles$r.spaceUnder]
|
|
30929
31015
|
}, /*#__PURE__*/React.createElement(ColorSelect, {
|
|
30930
|
-
selectedValue:
|
|
30931
|
-
onChange:
|
|
30932
|
-
handlePropChange("color", newValue);
|
|
30933
|
-
}
|
|
31016
|
+
selectedValue: color,
|
|
31017
|
+
onChange: handleColorChange
|
|
30934
31018
|
}), /*#__PURE__*/React.createElement(Strut, {
|
|
30935
|
-
size: spacing.small_12
|
|
30936
|
-
}), /*#__PURE__*/React.createElement(LineStrokeSelect, {
|
|
30937
|
-
selectedValue: strokeStyle,
|
|
30938
|
-
onChange: newValue => {
|
|
30939
|
-
handlePropChange("strokeStyle", newValue);
|
|
30940
|
-
}
|
|
30941
|
-
})), /*#__PURE__*/React.createElement(View, {
|
|
30942
|
-
style: [styles$r.row, styles$r.rowSpace]
|
|
30943
|
-
}, /*#__PURE__*/React.createElement(SingleSelect, {
|
|
30944
|
-
selectedValue: directionalAxis,
|
|
30945
|
-
onChange: newValue => {
|
|
30946
|
-
handlePropChange("directionalAxis", newValue);
|
|
30947
|
-
},
|
|
30948
|
-
"aria-label": "equation prefix",
|
|
30949
|
-
style: [styles$r.dropdownLabel, styles$r.axisMenu]
|
|
30950
|
-
// Placeholder is required, but never gets used.
|
|
30951
|
-
,
|
|
30952
|
-
placeholder: ""
|
|
30953
|
-
}, /*#__PURE__*/React.createElement(OptionItem, {
|
|
30954
|
-
value: "x",
|
|
30955
|
-
label: "y ="
|
|
30956
|
-
}), /*#__PURE__*/React.createElement(OptionItem, {
|
|
30957
|
-
value: "y",
|
|
30958
|
-
label: "x ="
|
|
30959
|
-
})), /*#__PURE__*/React.createElement(Strut, {
|
|
30960
|
-
size: spacing.xSmall_8
|
|
30961
|
-
}), /*#__PURE__*/React.createElement(TextField, {
|
|
30962
|
-
type: "text",
|
|
30963
|
-
"aria-label": "equation",
|
|
30964
|
-
value: equation,
|
|
30965
|
-
onChange: newValue => {
|
|
30966
|
-
handlePropChange("equation", newValue);
|
|
30967
|
-
},
|
|
30968
|
-
style: [styles$r.textField]
|
|
30969
|
-
})), /*#__PURE__*/React.createElement(View, {
|
|
30970
|
-
style: [styles$r.row, styles$r.rowSpace]
|
|
30971
|
-
}, /*#__PURE__*/React.createElement(LabelMedium, {
|
|
30972
|
-
tag: "label",
|
|
30973
|
-
style: [styles$r.dropdownLabel, styles$r.domainMin]
|
|
30974
|
-
}, `${domainRangeText} min`, /*#__PURE__*/React.createElement(Strut, {
|
|
30975
|
-
size: spacing.xxSmall_6
|
|
30976
|
-
}), /*#__PURE__*/React.createElement(TextField, {
|
|
30977
|
-
type: "number",
|
|
30978
|
-
style: styles$r.domainMinField,
|
|
30979
|
-
value: domainEntries[0],
|
|
30980
|
-
onChange: newValue => {
|
|
30981
|
-
handleDomainChange(0, newValue);
|
|
30982
|
-
}
|
|
30983
|
-
})), /*#__PURE__*/React.createElement(Strut, {
|
|
30984
31019
|
size: spacing.medium_16
|
|
30985
31020
|
}), /*#__PURE__*/React.createElement(LabelMedium, {
|
|
30986
31021
|
tag: "label",
|
|
30987
|
-
|
|
30988
|
-
|
|
30989
|
-
}, "max", /*#__PURE__*/React.createElement(Strut, {
|
|
30990
|
-
size: spacing.xxSmall_6
|
|
30991
|
-
}), /*#__PURE__*/React.createElement(TextField, {
|
|
30992
|
-
type: "number",
|
|
30993
|
-
style: styles$r.domainMaxField,
|
|
30994
|
-
value: domainEntries[1],
|
|
30995
|
-
onChange: newValue => {
|
|
30996
|
-
handleDomainChange(1, newValue);
|
|
30997
|
-
}
|
|
30998
|
-
}))), /*#__PURE__*/React.createElement(PerseusEditorAccordion, {
|
|
30999
|
-
header: /*#__PURE__*/React.createElement(LabelLarge, null, "Example Functions"),
|
|
31000
|
-
expanded: false,
|
|
31001
|
-
containerStyle: styles$r.exampleWorkspace,
|
|
31002
|
-
panelStyle: styles$r.exampleAccordionPanel
|
|
31003
|
-
}, /*#__PURE__*/React.createElement(LabelMedium, {
|
|
31004
|
-
tag: "label",
|
|
31005
|
-
style: styles$r.dropdownLabel
|
|
31006
|
-
}, "Choose a category", /*#__PURE__*/React.createElement(Strut, {
|
|
31022
|
+
style: [styles$r.row, styles$r.truncatedWidth]
|
|
31023
|
+
}, "fill", /*#__PURE__*/React.createElement(Strut, {
|
|
31007
31024
|
size: spacing.xxSmall_6
|
|
31008
31025
|
}), /*#__PURE__*/React.createElement(SingleSelect, {
|
|
31009
|
-
selectedValue:
|
|
31010
|
-
onChange:
|
|
31011
|
-
|
|
31012
|
-
|
|
31013
|
-
|
|
31014
|
-
|
|
31015
|
-
|
|
31016
|
-
|
|
31017
|
-
|
|
31018
|
-
|
|
31019
|
-
|
|
31020
|
-
},
|
|
31021
|
-
|
|
31022
|
-
|
|
31023
|
-
|
|
31024
|
-
|
|
31025
|
-
})))
|
|
31026
|
+
selectedValue: fillStyle,
|
|
31027
|
+
onChange: value => onChangeProps({
|
|
31028
|
+
fillStyle: value
|
|
31029
|
+
})
|
|
31030
|
+
// Placeholder is required, but never gets used.
|
|
31031
|
+
,
|
|
31032
|
+
placeholder: ""
|
|
31033
|
+
}, Object.keys(lockedFigureFillStyles).map(option => /*#__PURE__*/React.createElement(OptionItem, {
|
|
31034
|
+
key: option,
|
|
31035
|
+
value: option,
|
|
31036
|
+
label: option
|
|
31037
|
+
}))))), /*#__PURE__*/React.createElement(LineStrokeSelect, {
|
|
31038
|
+
selectedValue: strokeStyle,
|
|
31039
|
+
onChange: value => onChangeProps({
|
|
31040
|
+
strokeStyle: value
|
|
31041
|
+
})
|
|
31042
|
+
}), (flags == null || (_flags$mafs = flags["mafs"]) == null ? void 0 : _flags$mafs["locked-ellipse-labels"]) && /*#__PURE__*/React.createElement(React.Fragment, null, labels == null ? void 0 : labels.map((label, labelIndex) => /*#__PURE__*/React.createElement(LockedLabelSettings, _extends({}, label, {
|
|
31043
|
+
expanded: true,
|
|
31044
|
+
onChangeProps: newLabel => {
|
|
31045
|
+
handleLabelChange(newLabel, labelIndex);
|
|
31046
|
+
},
|
|
31047
|
+
onRemove: () => {
|
|
31048
|
+
handleLabelRemove(labelIndex);
|
|
31049
|
+
},
|
|
31050
|
+
containerStyle: styles$r.labelContainer
|
|
31051
|
+
}))), /*#__PURE__*/React.createElement(Button, {
|
|
31052
|
+
kind: "tertiary",
|
|
31053
|
+
startIcon: plusCircle,
|
|
31054
|
+
onClick: () => {
|
|
31055
|
+
var _labels$length;
|
|
31056
|
+
const newLabel = _extends({}, getDefaultFigureForType("label"), {
|
|
31057
|
+
coord: [center[0],
|
|
31058
|
+
// Additional vertical offset for each
|
|
31059
|
+
// label so they don't overlap.
|
|
31060
|
+
center[1] - ((_labels$length = labels == null ? void 0 : labels.length) != null ? _labels$length : 0)],
|
|
31061
|
+
// Default to the same color as the ellipse
|
|
31062
|
+
color: color
|
|
31063
|
+
});
|
|
31064
|
+
onChangeProps({
|
|
31065
|
+
labels: [...(labels != null ? labels : []), newLabel]
|
|
31066
|
+
});
|
|
31067
|
+
},
|
|
31068
|
+
style: styles$r.addButton
|
|
31069
|
+
}, "Add visible label")), /*#__PURE__*/React.createElement(LockedFigureSettingsActions, {
|
|
31026
31070
|
figureType: props.type,
|
|
31027
31071
|
onMove: onMove,
|
|
31028
31072
|
onRemove: onRemove
|
|
31029
31073
|
}));
|
|
31030
31074
|
};
|
|
31031
|
-
const ExampleItem = props => {
|
|
31032
|
-
const {
|
|
31033
|
-
category,
|
|
31034
|
-
example,
|
|
31035
|
-
index,
|
|
31036
|
-
pasteEquationFn
|
|
31037
|
-
} = props;
|
|
31038
|
-
const exampleId = useId();
|
|
31039
|
-
return /*#__PURE__*/React.createElement("li", {
|
|
31040
|
-
key: `${category}-${index}`,
|
|
31041
|
-
className: css(styles$r.exampleRow)
|
|
31042
|
-
}, /*#__PURE__*/React.createElement(IconButton, {
|
|
31043
|
-
icon: autoPasteIcon,
|
|
31044
|
-
"aria-label": "paste example",
|
|
31045
|
-
"aria-describedby": exampleId,
|
|
31046
|
-
onClick: () => pasteEquationFn("equation", example),
|
|
31047
|
-
size: "medium",
|
|
31048
|
-
style: styles$r.copyPasteButton
|
|
31049
|
-
}), /*#__PURE__*/React.createElement(IconButton, {
|
|
31050
|
-
icon: copyIcon,
|
|
31051
|
-
"aria-label": "copy example",
|
|
31052
|
-
"aria-describedby": exampleId,
|
|
31053
|
-
onClick: () => navigator.clipboard.writeText(example),
|
|
31054
|
-
size: "medium",
|
|
31055
|
-
style: styles$r.copyPasteButton
|
|
31056
|
-
}), /*#__PURE__*/React.createElement(Strut, {
|
|
31057
|
-
size: spacing.xxxSmall_4
|
|
31058
|
-
}), /*#__PURE__*/React.createElement(View, {
|
|
31059
|
-
style: styles$r.exampleContent,
|
|
31060
|
-
id: exampleId
|
|
31061
|
-
}, example));
|
|
31062
|
-
};
|
|
31063
31075
|
const styles$r = StyleSheet.create({
|
|
31064
|
-
|
|
31065
|
-
textOverflow: "ellipsis",
|
|
31066
|
-
// A maximum width needs to be specified in order for the ellipsis to work.
|
|
31067
|
-
// The 64px in the calculation accounts for the line swatch (56px) and the preceding strut (8px).
|
|
31068
|
-
// Margin and padding won't work here because they would create space between the header text and the swatch.
|
|
31069
|
-
maxWidth: "calc(100% - 64px)",
|
|
31070
|
-
overflow: "hidden",
|
|
31071
|
-
whiteSpace: "nowrap"
|
|
31072
|
-
},
|
|
31073
|
-
axisMenu: {
|
|
31074
|
-
minWidth: "auto"
|
|
31075
|
-
},
|
|
31076
|
-
copyPasteButton: {
|
|
31077
|
-
flexShrink: "0",
|
|
31078
|
-
margin: "0 2px"
|
|
31079
|
-
},
|
|
31080
|
-
domainMin: {
|
|
31081
|
-
justifyContent: "space-between",
|
|
31082
|
-
// The 'width' property is applied to the label, which wraps the text and the input field.
|
|
31083
|
-
// The width of the input fields (min/max) should be the same (to have a consistent look),
|
|
31084
|
-
// so the following calculation distributes the space accordingly.
|
|
31085
|
-
// For the "domain/range min" block, the text is 82.7px, and the strut is 6px (88.7px total).
|
|
31086
|
-
// The "domain/range max" block is 30.23px, and the strut is 6px (36.23px total).
|
|
31087
|
-
// The calculation takes the remain space after the text & struts (141px total) are removed,
|
|
31088
|
-
// and divides it between the two input fields equally.
|
|
31089
|
-
// The calculation reads: "Take 1/2 of the non-text space, and add the required space for this label's text"
|
|
31090
|
-
width: "calc(((100% - 141px) / 2) + 88.7px)",
|
|
31091
|
-
// @ts-expect-error // TS2353: textWrap does not exist in type CSSProperties
|
|
31092
|
-
textWrap: "nowrap"
|
|
31093
|
-
},
|
|
31094
|
-
domainMinField: {
|
|
31095
|
-
width: "calc(100% - 88.7px)" // make room for the label
|
|
31096
|
-
},
|
|
31097
|
-
|
|
31098
|
-
domainMax: {
|
|
31099
|
-
// See explanation for "domainMin" for the calculation below.
|
|
31100
|
-
width: "calc(((100% - 141px) / 2) + 36.2px)"
|
|
31101
|
-
},
|
|
31102
|
-
domainMaxField: {
|
|
31103
|
-
width: "calc(100% - 36.2px)" // make room for the label
|
|
31104
|
-
},
|
|
31105
|
-
|
|
31106
|
-
dropdownLabel: {
|
|
31107
|
-
alignItems: "center",
|
|
31108
|
-
display: "flex"
|
|
31109
|
-
},
|
|
31110
|
-
exampleAccordionPanel: {
|
|
31111
|
-
alignItems: "start",
|
|
31112
|
-
paddingBottom: "12px",
|
|
31113
|
-
flexDirection: "row",
|
|
31114
|
-
flexWrap: "wrap"
|
|
31115
|
-
},
|
|
31116
|
-
exampleContainer: {
|
|
31117
|
-
background: "white",
|
|
31118
|
-
border: `1px solid ${color.fadedOffBlack16}`,
|
|
31119
|
-
borderRadius: "4px",
|
|
31120
|
-
flexGrow: "1",
|
|
31121
|
-
listStyleType: "none",
|
|
31122
|
-
// Nothing special about the maxHeight value,
|
|
31123
|
-
// just a good height to partially show a 3rd example in the list
|
|
31124
|
-
// to hint at scrollable content.
|
|
31125
|
-
maxHeight: "88px",
|
|
31126
|
-
margin: "8px 0 0 0",
|
|
31127
|
-
overflowY: "scroll",
|
|
31128
|
-
padding: "4px 12px 4px 4px"
|
|
31129
|
-
},
|
|
31130
|
-
exampleContent: {
|
|
31131
|
-
fontFamily: `"Lato", sans-serif`,
|
|
31132
|
-
flexGrow: "1",
|
|
31133
|
-
color: color.offBlack
|
|
31134
|
-
},
|
|
31135
|
-
exampleRow: {
|
|
31136
|
-
alignItems: "center",
|
|
31076
|
+
row: {
|
|
31137
31077
|
display: "flex",
|
|
31138
31078
|
flexDirection: "row",
|
|
31139
|
-
|
|
31079
|
+
alignItems: "center"
|
|
31140
31080
|
},
|
|
31141
|
-
|
|
31142
|
-
|
|
31081
|
+
spaceUnder: {
|
|
31082
|
+
marginBottom: spacing.xSmall_8
|
|
31143
31083
|
},
|
|
31144
|
-
|
|
31145
|
-
|
|
31084
|
+
truncatedWidth: {
|
|
31085
|
+
// Allow truncation, stop bleeding over the edge.
|
|
31086
|
+
minWidth: 0
|
|
31146
31087
|
},
|
|
31147
|
-
|
|
31148
|
-
|
|
31149
|
-
flexDirection: "row",
|
|
31150
|
-
alignItems: "center"
|
|
31088
|
+
addButton: {
|
|
31089
|
+
alignSelf: "start"
|
|
31151
31090
|
},
|
|
31152
|
-
|
|
31153
|
-
|
|
31091
|
+
labelContainer: {
|
|
31092
|
+
backgroundColor: color.white
|
|
31154
31093
|
}
|
|
31155
31094
|
});
|
|
31156
31095
|
|
|
31157
|
-
|
|
31158
|
-
* LockedLabelSettings is a component that allows the user to edit the
|
|
31159
|
-
* settings of specifically a locked label on the graph within the
|
|
31160
|
-
* Interactive Graph widget.
|
|
31161
|
-
*
|
|
31162
|
-
* Used in the interactive graph editor's locked figures section.
|
|
31163
|
-
*/
|
|
31164
|
-
function LockedLabelSettings(props) {
|
|
31096
|
+
const LineSwatch = props => {
|
|
31165
31097
|
const {
|
|
31166
|
-
|
|
31167
|
-
|
|
31168
|
-
|
|
31169
|
-
|
|
31170
|
-
|
|
31171
|
-
|
|
31098
|
+
color,
|
|
31099
|
+
lineStyle
|
|
31100
|
+
} = props;
|
|
31101
|
+
return /*#__PURE__*/React.createElement(View, {
|
|
31102
|
+
style: styles$q.container
|
|
31103
|
+
}, /*#__PURE__*/React.createElement(View, {
|
|
31104
|
+
"aria-label": `${color}, ${lineStyle}`,
|
|
31105
|
+
style: [styles$q.lineSwatch, {
|
|
31106
|
+
border: `5px ${lineStyle} ${lockedFigureColors[color]}`
|
|
31107
|
+
}]
|
|
31108
|
+
}));
|
|
31109
|
+
};
|
|
31110
|
+
const styles$q = StyleSheet.create({
|
|
31111
|
+
container: {
|
|
31112
|
+
backgroundColor: color.white,
|
|
31113
|
+
justifyContent: "center",
|
|
31114
|
+
padding: spacing.xSmall_8,
|
|
31115
|
+
borderRadius: spacing.xxxSmall_4
|
|
31116
|
+
},
|
|
31117
|
+
lineSwatch: {
|
|
31118
|
+
width: 40
|
|
31119
|
+
}
|
|
31120
|
+
});
|
|
31121
|
+
|
|
31122
|
+
const examples = {
|
|
31123
|
+
linear: ["x + 5", "1/2x - 2"],
|
|
31124
|
+
polynomial: ["1/2x^2 + 3x - 4", "(1/3)x^3 - 2x^2 + 3x - 4"],
|
|
31125
|
+
trigonometric: ["sin(x) * 3", "arctan(2x) + 4"]
|
|
31126
|
+
};
|
|
31127
|
+
|
|
31128
|
+
const LockedFunctionSettings = props => {
|
|
31129
|
+
var _flags$mafs;
|
|
31130
|
+
const {
|
|
31131
|
+
flags,
|
|
31132
|
+
color: lineColor,
|
|
31133
|
+
strokeStyle,
|
|
31134
|
+
equation,
|
|
31135
|
+
directionalAxis,
|
|
31136
|
+
domain,
|
|
31137
|
+
labels,
|
|
31172
31138
|
onChangeProps,
|
|
31173
31139
|
onMove,
|
|
31174
|
-
onRemove
|
|
31175
|
-
onToggle
|
|
31140
|
+
onRemove
|
|
31176
31141
|
} = props;
|
|
31177
|
-
|
|
31178
|
-
|
|
31179
|
-
|
|
31180
|
-
header: /*#__PURE__*/React.createElement(View, {
|
|
31181
|
-
style: [styles$q.row, styles$q.accordionHeaderContainer]
|
|
31182
|
-
}, /*#__PURE__*/React.createElement(LabelLarge, null, "Label (", coord[0], ", ", coord[1], ")"), /*#__PURE__*/React.createElement(Strut, {
|
|
31183
|
-
size: spacing.xSmall_8
|
|
31184
|
-
}), text !== "" && /*#__PURE__*/React.createElement(LabelLarge, {
|
|
31185
|
-
style: [{
|
|
31186
|
-
backgroundColor: color.white,
|
|
31187
|
-
color: lockedFigureColors[color$1]
|
|
31188
|
-
}, styles$q.accordionHeader]
|
|
31189
|
-
}, text)),
|
|
31190
|
-
containerStyle: !onMove && styles$q.innerLabelAccordionPanel
|
|
31191
|
-
}, /*#__PURE__*/React.createElement(CoordinatePairInput, {
|
|
31192
|
-
coord: coord,
|
|
31193
|
-
onChange: newCoords => {
|
|
31194
|
-
onChangeProps({
|
|
31195
|
-
coord: newCoords
|
|
31196
|
-
});
|
|
31197
|
-
},
|
|
31198
|
-
style: styles$q.spaceUnder
|
|
31199
|
-
}), /*#__PURE__*/React.createElement(LabelMedium, {
|
|
31200
|
-
tag: "label",
|
|
31201
|
-
style: [styles$q.row, styles$q.spaceUnder]
|
|
31202
|
-
}, "TeX", /*#__PURE__*/React.createElement(Strut, {
|
|
31203
|
-
size: spacing.xSmall_8
|
|
31204
|
-
}), /*#__PURE__*/React.createElement(TextField, {
|
|
31205
|
-
value: text,
|
|
31206
|
-
placeholder: "ex. x^2 or \\frac{1}{2}",
|
|
31207
|
-
onChange: newValue => onChangeProps({
|
|
31208
|
-
text: newValue
|
|
31209
|
-
})
|
|
31210
|
-
})), /*#__PURE__*/React.createElement(View, {
|
|
31211
|
-
style: styles$q.row
|
|
31212
|
-
}, onMove && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(ColorSelect, {
|
|
31213
|
-
selectedValue: color$1,
|
|
31214
|
-
onChange: newColor => {
|
|
31215
|
-
onChangeProps({
|
|
31216
|
-
color: newColor
|
|
31217
|
-
});
|
|
31218
|
-
},
|
|
31219
|
-
style: styles$q.spaceUnder
|
|
31220
|
-
}), /*#__PURE__*/React.createElement(Strut, {
|
|
31221
|
-
size: spacing.medium_16
|
|
31222
|
-
})), /*#__PURE__*/React.createElement(LabelMedium, {
|
|
31223
|
-
tag: "label",
|
|
31224
|
-
style: styles$q.row
|
|
31225
|
-
}, "size", /*#__PURE__*/React.createElement(Strut, {
|
|
31226
|
-
size: spacing.xSmall_8
|
|
31227
|
-
}), /*#__PURE__*/React.createElement(SingleSelect, {
|
|
31228
|
-
selectedValue: size,
|
|
31229
|
-
onChange: newValue => onChangeProps({
|
|
31230
|
-
size: newValue
|
|
31231
|
-
})
|
|
31232
|
-
// Placeholder is required, but never gets used since
|
|
31233
|
-
// we have a label for the select.
|
|
31234
|
-
,
|
|
31235
|
-
placeholder: ""
|
|
31236
|
-
}, /*#__PURE__*/React.createElement(OptionItem, {
|
|
31237
|
-
value: "small",
|
|
31238
|
-
label: "small"
|
|
31239
|
-
}), /*#__PURE__*/React.createElement(OptionItem, {
|
|
31240
|
-
value: "medium",
|
|
31241
|
-
label: "medium"
|
|
31242
|
-
}), /*#__PURE__*/React.createElement(OptionItem, {
|
|
31243
|
-
value: "large",
|
|
31244
|
-
label: "large"
|
|
31245
|
-
})))), /*#__PURE__*/React.createElement(LockedFigureSettingsActions, {
|
|
31246
|
-
figureType: type,
|
|
31247
|
-
onMove: onMove,
|
|
31248
|
-
onRemove: onRemove
|
|
31249
|
-
}));
|
|
31250
|
-
}
|
|
31251
|
-
const styles$q = StyleSheet.create({
|
|
31252
|
-
accordionHeaderContainer: {
|
|
31253
|
-
// Stop the label summary from wrapping.
|
|
31254
|
-
whiteSpace: "nowrap"
|
|
31255
|
-
},
|
|
31256
|
-
accordionHeader: {
|
|
31257
|
-
padding: spacing.xxxSmall_4,
|
|
31258
|
-
marginInlineEnd: spacing.xSmall_8,
|
|
31259
|
-
borderRadius: spacing.xxxSmall_4,
|
|
31260
|
-
textOverflow: "ellipsis",
|
|
31261
|
-
overflow: "hidden"
|
|
31262
|
-
},
|
|
31263
|
-
row: {
|
|
31264
|
-
display: "flex",
|
|
31265
|
-
flexDirection: "row",
|
|
31266
|
-
alignItems: "center",
|
|
31267
|
-
// Allow truncation, stop bleeding over the edge.
|
|
31268
|
-
minWidth: 0
|
|
31269
|
-
},
|
|
31270
|
-
spaceUnder: {
|
|
31271
|
-
marginBottom: spacing.xSmall_8
|
|
31272
|
-
},
|
|
31273
|
-
innerLabelAccordionPanel: {
|
|
31274
|
-
backgroundColor: color.white
|
|
31275
|
-
}
|
|
31276
|
-
});
|
|
31142
|
+
const equationPrefix = directionalAxis === "x" ? "y=" : "x=";
|
|
31143
|
+
const domainRangeText = directionalAxis === "x" ? "domain" : "range";
|
|
31144
|
+
const lineLabel = `Function (${equationPrefix}${equation})`;
|
|
31277
31145
|
|
|
31278
|
-
|
|
31279
|
-
|
|
31280
|
-
|
|
31281
|
-
|
|
31282
|
-
|
|
31283
|
-
|
|
31284
|
-
|
|
31285
|
-
|
|
31286
|
-
|
|
31287
|
-
|
|
31288
|
-
|
|
31289
|
-
|
|
31290
|
-
|
|
31291
|
-
|
|
31292
|
-
|
|
31293
|
-
}), /*#__PURE__*/React.createElement(Strut, {
|
|
31294
|
-
size: spacing.xSmall_8
|
|
31295
|
-
}), /*#__PURE__*/React.createElement(LabelMedium, {
|
|
31296
|
-
tag: "label",
|
|
31297
|
-
htmlFor: switchId
|
|
31298
|
-
}, label));
|
|
31299
|
-
};
|
|
31300
|
-
const styles$p = StyleSheet.create({
|
|
31301
|
-
row: {
|
|
31302
|
-
flexDirection: "row",
|
|
31303
|
-
alignItems: "center"
|
|
31146
|
+
// Tracking the string value of domain/range constraints to handle interim state of
|
|
31147
|
+
// entering a negative value, as well as representing Infinity as an empty string.
|
|
31148
|
+
// This variable is used when specifying the values of the input fields.
|
|
31149
|
+
const [domainEntries, setDomainEntries] = useState([domain && domain[0] !== -Infinity ? domain[0].toString() : "", domain && domain[1] !== Infinity ? domain[1].toString() : ""]);
|
|
31150
|
+
const [exampleCategory, setExampleCategory] = useState("");
|
|
31151
|
+
useEffect(() => {
|
|
31152
|
+
// "useEffect" used to maintain parity between domain/range constraints and their string representation.
|
|
31153
|
+
setDomainEntries([domain && domain[0] !== -Infinity ? domain[0].toString() : "", domain && domain[1] !== Infinity ? domain[1].toString() : ""]);
|
|
31154
|
+
}, [domain]);
|
|
31155
|
+
|
|
31156
|
+
// Generic function for handling property changes (except for 'domain/range')
|
|
31157
|
+
function handlePropChange(property, newValue) {
|
|
31158
|
+
const updatedProps = {};
|
|
31159
|
+
updatedProps[property] = newValue;
|
|
31160
|
+
onChangeProps(updatedProps);
|
|
31304
31161
|
}
|
|
31305
|
-
});
|
|
31306
31162
|
|
|
31307
|
-
|
|
31308
|
-
|
|
31309
|
-
|
|
31310
|
-
|
|
31311
|
-
|
|
31312
|
-
|
|
31313
|
-
|
|
31314
|
-
|
|
31315
|
-
|
|
31316
|
-
|
|
31317
|
-
|
|
31318
|
-
|
|
31319
|
-
|
|
31320
|
-
|
|
31321
|
-
|
|
31322
|
-
|
|
31323
|
-
|
|
31324
|
-
|
|
31325
|
-
} = props;
|
|
31326
|
-
function handleColorChange(newValue) {
|
|
31163
|
+
/*
|
|
31164
|
+
Reason for having a separate 'propChange' function for 'domain/range':
|
|
31165
|
+
Domain/Range entries are optional. Their default value is +/- Infinity.
|
|
31166
|
+
Since input fields that are empty evaluate to zero, there needs to be
|
|
31167
|
+
dedicated code to convert empty to Infinity.
|
|
31168
|
+
*/
|
|
31169
|
+
function handleDomainChange(limitIndex, newValueString) {
|
|
31170
|
+
const newDomainEntries = [...domainEntries];
|
|
31171
|
+
newDomainEntries[limitIndex] = newValueString;
|
|
31172
|
+
setDomainEntries(newDomainEntries);
|
|
31173
|
+
const newDomain = domain ? [...domain] : [-Infinity, Infinity];
|
|
31174
|
+
let newValue = parseFloat(newValueString);
|
|
31175
|
+
if (newValueString === "" && limitIndex === 0) {
|
|
31176
|
+
newValue = -Infinity;
|
|
31177
|
+
} else if (newValueString === "" && limitIndex === 1) {
|
|
31178
|
+
newValue = Infinity;
|
|
31179
|
+
}
|
|
31180
|
+
newDomain[limitIndex] = newValue;
|
|
31327
31181
|
onChangeProps({
|
|
31182
|
+
domain: newDomain
|
|
31183
|
+
});
|
|
31184
|
+
}
|
|
31185
|
+
const exampleCategories = Object.keys(examples);
|
|
31186
|
+
const exampleCategorySelected = exampleCategory !== "";
|
|
31187
|
+
const exampleContent = exampleCategorySelected ? examples[exampleCategory] : ["Select category to see example equations"];
|
|
31188
|
+
function handleColorChange(newValue) {
|
|
31189
|
+
const newProps = {
|
|
31190
|
+
color: newValue
|
|
31191
|
+
};
|
|
31192
|
+
|
|
31193
|
+
// Update the color of the all labels to match the point
|
|
31194
|
+
newProps.labels = labels == null ? void 0 : labels.map(label => _extends({}, label, {
|
|
31328
31195
|
color: newValue
|
|
31196
|
+
}));
|
|
31197
|
+
onChangeProps(newProps);
|
|
31198
|
+
}
|
|
31199
|
+
function handleLabelChange(updatedLabel, labelIndex) {
|
|
31200
|
+
if (!labels) {
|
|
31201
|
+
return;
|
|
31202
|
+
}
|
|
31203
|
+
const updatedLabels = [...labels];
|
|
31204
|
+
updatedLabels[labelIndex] = _extends({}, labels[labelIndex], updatedLabel);
|
|
31205
|
+
onChangeProps({
|
|
31206
|
+
labels: updatedLabels
|
|
31207
|
+
});
|
|
31208
|
+
}
|
|
31209
|
+
function handleLabelRemove(labelIndex) {
|
|
31210
|
+
if (!labels) {
|
|
31211
|
+
return;
|
|
31212
|
+
}
|
|
31213
|
+
const updatedLabels = labels.filter((_, index) => index !== labelIndex);
|
|
31214
|
+
onChangeProps({
|
|
31215
|
+
labels: updatedLabels
|
|
31329
31216
|
});
|
|
31330
31217
|
}
|
|
31331
31218
|
return /*#__PURE__*/React.createElement(PerseusEditorAccordion, {
|
|
31332
|
-
expanded: expanded,
|
|
31333
|
-
onToggle: onToggle,
|
|
31334
|
-
|
|
31335
|
-
|
|
31336
|
-
|
|
31337
|
-
|
|
31338
|
-
|
|
31339
|
-
React.createElement(View, {
|
|
31340
|
-
style: styles$o.row
|
|
31341
|
-
}, /*#__PURE__*/React.createElement(LabelLarge, null, `${label || "Point"} (${coord[0]}, ${coord[1]})`), /*#__PURE__*/React.createElement(Strut, {
|
|
31219
|
+
expanded: props.expanded,
|
|
31220
|
+
onToggle: props.onToggle,
|
|
31221
|
+
header: /*#__PURE__*/React.createElement(View, {
|
|
31222
|
+
style: styles$p.row
|
|
31223
|
+
}, /*#__PURE__*/React.createElement(LabelLarge, {
|
|
31224
|
+
style: styles$p.accordionHeader
|
|
31225
|
+
}, lineLabel), /*#__PURE__*/React.createElement(Strut, {
|
|
31342
31226
|
size: spacing.xSmall_8
|
|
31343
|
-
}),
|
|
31344
|
-
color:
|
|
31345
|
-
|
|
31227
|
+
}), /*#__PURE__*/React.createElement(LineSwatch, {
|
|
31228
|
+
color: lineColor,
|
|
31229
|
+
lineStyle: strokeStyle
|
|
31346
31230
|
}))
|
|
31347
|
-
}, /*#__PURE__*/React.createElement(
|
|
31348
|
-
|
|
31349
|
-
|
|
31350
|
-
|
|
31351
|
-
onChange:
|
|
31352
|
-
|
|
31353
|
-
|
|
31354
|
-
|
|
31231
|
+
}, /*#__PURE__*/React.createElement(View, {
|
|
31232
|
+
style: [styles$p.row, styles$p.spaceUnder]
|
|
31233
|
+
}, /*#__PURE__*/React.createElement(ColorSelect, {
|
|
31234
|
+
selectedValue: lineColor,
|
|
31235
|
+
onChange: handleColorChange
|
|
31236
|
+
}), /*#__PURE__*/React.createElement(Strut, {
|
|
31237
|
+
size: spacing.small_12
|
|
31238
|
+
}), /*#__PURE__*/React.createElement(LineStrokeSelect, {
|
|
31239
|
+
selectedValue: strokeStyle,
|
|
31240
|
+
onChange: newValue => {
|
|
31241
|
+
handlePropChange("strokeStyle", newValue);
|
|
31355
31242
|
}
|
|
31356
|
-
}),
|
|
31357
|
-
|
|
31358
|
-
|
|
31359
|
-
|
|
31360
|
-
onChange: onTogglePoint
|
|
31361
|
-
}), showPoint && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(ColorSelect, {
|
|
31362
|
-
selectedValue: pointColor,
|
|
31363
|
-
onChange: handleColorChange,
|
|
31364
|
-
style: styles$o.spaceUnder
|
|
31365
|
-
}), /*#__PURE__*/React.createElement(LabeledSwitch, {
|
|
31366
|
-
label: "open point",
|
|
31367
|
-
checked: !filled,
|
|
31243
|
+
})), /*#__PURE__*/React.createElement(View, {
|
|
31244
|
+
style: [styles$p.row, styles$p.rowSpace]
|
|
31245
|
+
}, /*#__PURE__*/React.createElement(SingleSelect, {
|
|
31246
|
+
selectedValue: directionalAxis,
|
|
31368
31247
|
onChange: newValue => {
|
|
31248
|
+
handlePropChange("directionalAxis", newValue);
|
|
31249
|
+
},
|
|
31250
|
+
"aria-label": "equation prefix",
|
|
31251
|
+
style: [styles$p.dropdownLabel, styles$p.axisMenu]
|
|
31252
|
+
// Placeholder is required, but never gets used.
|
|
31253
|
+
,
|
|
31254
|
+
placeholder: ""
|
|
31255
|
+
}, /*#__PURE__*/React.createElement(OptionItem, {
|
|
31256
|
+
value: "x",
|
|
31257
|
+
label: "y ="
|
|
31258
|
+
}), /*#__PURE__*/React.createElement(OptionItem, {
|
|
31259
|
+
value: "y",
|
|
31260
|
+
label: "x ="
|
|
31261
|
+
})), /*#__PURE__*/React.createElement(Strut, {
|
|
31262
|
+
size: spacing.xSmall_8
|
|
31263
|
+
}), /*#__PURE__*/React.createElement(TextField, {
|
|
31264
|
+
type: "text",
|
|
31265
|
+
"aria-label": "equation",
|
|
31266
|
+
value: equation,
|
|
31267
|
+
onChange: newValue => {
|
|
31268
|
+
handlePropChange("equation", newValue);
|
|
31269
|
+
},
|
|
31270
|
+
style: [styles$p.textField]
|
|
31271
|
+
})), /*#__PURE__*/React.createElement(View, {
|
|
31272
|
+
style: [styles$p.row, styles$p.rowSpace]
|
|
31273
|
+
}, /*#__PURE__*/React.createElement(LabelMedium, {
|
|
31274
|
+
tag: "label",
|
|
31275
|
+
style: [styles$p.dropdownLabel, styles$p.domainMin]
|
|
31276
|
+
}, `${domainRangeText} min`, /*#__PURE__*/React.createElement(Strut, {
|
|
31277
|
+
size: spacing.xxSmall_6
|
|
31278
|
+
}), /*#__PURE__*/React.createElement(TextField, {
|
|
31279
|
+
type: "number",
|
|
31280
|
+
style: styles$p.domainMinField,
|
|
31281
|
+
value: domainEntries[0],
|
|
31282
|
+
onChange: newValue => {
|
|
31283
|
+
handleDomainChange(0, newValue);
|
|
31284
|
+
}
|
|
31285
|
+
})), /*#__PURE__*/React.createElement(Strut, {
|
|
31286
|
+
size: spacing.medium_16
|
|
31287
|
+
}), /*#__PURE__*/React.createElement(LabelMedium, {
|
|
31288
|
+
tag: "label",
|
|
31289
|
+
"aria-label": `${domainRangeText} max`,
|
|
31290
|
+
style: [styles$p.dropdownLabel, styles$p.domainMax]
|
|
31291
|
+
}, "max", /*#__PURE__*/React.createElement(Strut, {
|
|
31292
|
+
size: spacing.xxSmall_6
|
|
31293
|
+
}), /*#__PURE__*/React.createElement(TextField, {
|
|
31294
|
+
type: "number",
|
|
31295
|
+
style: styles$p.domainMaxField,
|
|
31296
|
+
value: domainEntries[1],
|
|
31297
|
+
onChange: newValue => {
|
|
31298
|
+
handleDomainChange(1, newValue);
|
|
31299
|
+
}
|
|
31300
|
+
}))), /*#__PURE__*/React.createElement(PerseusEditorAccordion, {
|
|
31301
|
+
header: /*#__PURE__*/React.createElement(LabelLarge, null, "Example Functions"),
|
|
31302
|
+
expanded: false,
|
|
31303
|
+
containerStyle: styles$p.exampleWorkspace,
|
|
31304
|
+
panelStyle: styles$p.exampleAccordionPanel
|
|
31305
|
+
}, /*#__PURE__*/React.createElement(LabelMedium, {
|
|
31306
|
+
tag: "label",
|
|
31307
|
+
style: styles$p.dropdownLabel
|
|
31308
|
+
}, "Choose a category", /*#__PURE__*/React.createElement(Strut, {
|
|
31309
|
+
size: spacing.xxSmall_6
|
|
31310
|
+
}), /*#__PURE__*/React.createElement(SingleSelect, {
|
|
31311
|
+
selectedValue: exampleCategory,
|
|
31312
|
+
onChange: setExampleCategory,
|
|
31313
|
+
placeholder: "examples"
|
|
31314
|
+
}, exampleCategories.map(category => {
|
|
31315
|
+
return /*#__PURE__*/React.createElement(OptionItem, {
|
|
31316
|
+
key: category,
|
|
31317
|
+
value: category,
|
|
31318
|
+
label: category
|
|
31319
|
+
});
|
|
31320
|
+
}))), exampleCategorySelected && /*#__PURE__*/React.createElement("ul", {
|
|
31321
|
+
className: css(styles$p.exampleContainer)
|
|
31322
|
+
}, exampleContent.map((example, index) => /*#__PURE__*/React.createElement(ExampleItem, {
|
|
31323
|
+
category: exampleCategory,
|
|
31324
|
+
example: example,
|
|
31325
|
+
index: index,
|
|
31326
|
+
pasteEquationFn: handlePropChange
|
|
31327
|
+
})))), (flags == null || (_flags$mafs = flags["mafs"]) == null ? void 0 : _flags$mafs["locked-function-labels"]) && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(View, {
|
|
31328
|
+
style: styles$p.horizontalRule
|
|
31329
|
+
}), labels == null ? void 0 : labels.map((label, labelIndex) => /*#__PURE__*/React.createElement(LockedLabelSettings, _extends({}, label, {
|
|
31330
|
+
expanded: true,
|
|
31331
|
+
onChangeProps: newLabel => {
|
|
31332
|
+
handleLabelChange(newLabel, labelIndex);
|
|
31333
|
+
},
|
|
31334
|
+
onRemove: () => {
|
|
31335
|
+
handleLabelRemove(labelIndex);
|
|
31336
|
+
},
|
|
31337
|
+
containerStyle: styles$p.labelContainer
|
|
31338
|
+
}))), /*#__PURE__*/React.createElement(Button, {
|
|
31339
|
+
kind: "tertiary",
|
|
31340
|
+
startIcon: plusCircle,
|
|
31341
|
+
onClick: () => {
|
|
31342
|
+
var _labels$length;
|
|
31343
|
+
const newLabel = _extends({}, getDefaultFigureForType("label"), {
|
|
31344
|
+
// Vertical offset for each label so they
|
|
31345
|
+
// don't overlap.
|
|
31346
|
+
coord: [0, -((_labels$length = labels == null ? void 0 : labels.length) != null ? _labels$length : 0)],
|
|
31347
|
+
// Default to the same color as the function
|
|
31348
|
+
color: lineColor
|
|
31349
|
+
});
|
|
31369
31350
|
onChangeProps({
|
|
31370
|
-
|
|
31351
|
+
labels: [...(labels != null ? labels : []), newLabel]
|
|
31371
31352
|
});
|
|
31372
|
-
}
|
|
31373
|
-
|
|
31353
|
+
},
|
|
31354
|
+
style: styles$p.addButton
|
|
31355
|
+
}, "Add visible label")), /*#__PURE__*/React.createElement(LockedFigureSettingsActions, {
|
|
31356
|
+
figureType: props.type,
|
|
31357
|
+
onMove: onMove,
|
|
31358
|
+
onRemove: onRemove
|
|
31359
|
+
}));
|
|
31374
31360
|
};
|
|
31375
|
-
const
|
|
31376
|
-
|
|
31377
|
-
|
|
31378
|
-
|
|
31379
|
-
|
|
31380
|
-
|
|
31381
|
-
|
|
31361
|
+
const ExampleItem = props => {
|
|
31362
|
+
const {
|
|
31363
|
+
category,
|
|
31364
|
+
example,
|
|
31365
|
+
index,
|
|
31366
|
+
pasteEquationFn
|
|
31367
|
+
} = props;
|
|
31368
|
+
const exampleId = useId();
|
|
31369
|
+
return /*#__PURE__*/React.createElement("li", {
|
|
31370
|
+
key: `${category}-${index}`,
|
|
31371
|
+
className: css(styles$p.exampleRow)
|
|
31372
|
+
}, /*#__PURE__*/React.createElement(IconButton, {
|
|
31373
|
+
icon: autoPasteIcon,
|
|
31374
|
+
"aria-label": "paste example",
|
|
31375
|
+
"aria-describedby": exampleId,
|
|
31376
|
+
onClick: () => pasteEquationFn("equation", example),
|
|
31377
|
+
size: "medium",
|
|
31378
|
+
style: styles$p.copyPasteButton
|
|
31379
|
+
}), /*#__PURE__*/React.createElement(IconButton, {
|
|
31380
|
+
icon: copyIcon,
|
|
31381
|
+
"aria-label": "copy example",
|
|
31382
|
+
"aria-describedby": exampleId,
|
|
31383
|
+
onClick: () => navigator.clipboard.writeText(example),
|
|
31384
|
+
size: "medium",
|
|
31385
|
+
style: styles$p.copyPasteButton
|
|
31386
|
+
}), /*#__PURE__*/React.createElement(Strut, {
|
|
31387
|
+
size: spacing.xxxSmall_4
|
|
31388
|
+
}), /*#__PURE__*/React.createElement(View, {
|
|
31389
|
+
style: styles$p.exampleContent,
|
|
31390
|
+
id: exampleId
|
|
31391
|
+
}, example));
|
|
31392
|
+
};
|
|
31393
|
+
const styles$p = StyleSheet.create({
|
|
31394
|
+
accordionHeader: {
|
|
31395
|
+
textOverflow: "ellipsis",
|
|
31396
|
+
// A maximum width needs to be specified in order for the ellipsis to work.
|
|
31397
|
+
// The 64px in the calculation accounts for the line swatch (56px) and the preceding strut (8px).
|
|
31398
|
+
// Margin and padding won't work here because they would create space between the header text and the swatch.
|
|
31399
|
+
maxWidth: "calc(100% - 64px)",
|
|
31400
|
+
overflow: "hidden",
|
|
31401
|
+
whiteSpace: "nowrap"
|
|
31402
|
+
},
|
|
31403
|
+
axisMenu: {
|
|
31404
|
+
minWidth: "auto"
|
|
31405
|
+
},
|
|
31406
|
+
copyPasteButton: {
|
|
31407
|
+
flexShrink: "0",
|
|
31408
|
+
margin: "0 2px"
|
|
31409
|
+
},
|
|
31410
|
+
domainMin: {
|
|
31411
|
+
justifyContent: "space-between",
|
|
31412
|
+
// The 'width' property is applied to the label, which wraps the text and the input field.
|
|
31413
|
+
// The width of the input fields (min/max) should be the same (to have a consistent look),
|
|
31414
|
+
// so the following calculation distributes the space accordingly.
|
|
31415
|
+
// For the "domain/range min" block, the text is 82.7px, and the strut is 6px (88.7px total).
|
|
31416
|
+
// The "domain/range max" block is 30.23px, and the strut is 6px (36.23px total).
|
|
31417
|
+
// The calculation takes the remain space after the text & struts (141px total) are removed,
|
|
31418
|
+
// and divides it between the two input fields equally.
|
|
31419
|
+
// The calculation reads: "Take 1/2 of the non-text space, and add the required space for this label's text"
|
|
31420
|
+
width: "calc(((100% - 141px) / 2) + 88.7px)",
|
|
31421
|
+
// @ts-expect-error // TS2353: textWrap does not exist in type CSSProperties
|
|
31422
|
+
textWrap: "nowrap"
|
|
31423
|
+
},
|
|
31424
|
+
domainMinField: {
|
|
31425
|
+
width: "calc(100% - 88.7px)" // make room for the label
|
|
31426
|
+
},
|
|
31427
|
+
|
|
31428
|
+
domainMax: {
|
|
31429
|
+
// See explanation for "domainMin" for the calculation below.
|
|
31430
|
+
width: "calc(((100% - 141px) / 2) + 36.2px)"
|
|
31382
31431
|
},
|
|
31383
|
-
|
|
31384
|
-
|
|
31385
|
-
|
|
31432
|
+
domainMaxField: {
|
|
31433
|
+
width: "calc(100% - 36.2px)" // make room for the label
|
|
31434
|
+
},
|
|
31435
|
+
|
|
31436
|
+
dropdownLabel: {
|
|
31437
|
+
alignItems: "center",
|
|
31438
|
+
display: "flex"
|
|
31439
|
+
},
|
|
31440
|
+
exampleAccordionPanel: {
|
|
31441
|
+
alignItems: "start",
|
|
31442
|
+
paddingBottom: "12px",
|
|
31443
|
+
flexDirection: "row",
|
|
31444
|
+
flexWrap: "wrap"
|
|
31445
|
+
},
|
|
31446
|
+
exampleContainer: {
|
|
31447
|
+
background: "white",
|
|
31448
|
+
border: `1px solid ${color.fadedOffBlack16}`,
|
|
31449
|
+
borderRadius: "4px",
|
|
31450
|
+
flexGrow: "1",
|
|
31451
|
+
listStyleType: "none",
|
|
31452
|
+
// Nothing special about the maxHeight value,
|
|
31453
|
+
// just a good height to partially show a 3rd example in the list
|
|
31454
|
+
// to hint at scrollable content.
|
|
31455
|
+
maxHeight: "88px",
|
|
31456
|
+
margin: "8px 0 0 0",
|
|
31457
|
+
overflowY: "scroll",
|
|
31458
|
+
padding: "4px 12px 4px 4px"
|
|
31459
|
+
},
|
|
31460
|
+
exampleContent: {
|
|
31461
|
+
fontFamily: `"Lato", sans-serif`,
|
|
31462
|
+
flexGrow: "1",
|
|
31463
|
+
color: color.offBlack
|
|
31464
|
+
},
|
|
31465
|
+
exampleRow: {
|
|
31466
|
+
alignItems: "center",
|
|
31467
|
+
display: "flex",
|
|
31468
|
+
flexDirection: "row",
|
|
31469
|
+
minHeight: "44px"
|
|
31470
|
+
},
|
|
31471
|
+
exampleWorkspace: {
|
|
31472
|
+
background: color.white50
|
|
31473
|
+
},
|
|
31474
|
+
rowSpace: {
|
|
31475
|
+
marginTop: spacing.xSmall_8
|
|
31386
31476
|
},
|
|
31387
31477
|
row: {
|
|
31478
|
+
display: "flex",
|
|
31388
31479
|
flexDirection: "row",
|
|
31389
31480
|
alignItems: "center"
|
|
31390
31481
|
},
|
|
31391
|
-
|
|
31392
|
-
|
|
31482
|
+
textField: {
|
|
31483
|
+
flexGrow: "1"
|
|
31484
|
+
},
|
|
31485
|
+
// Label settings styles
|
|
31486
|
+
addButton: {
|
|
31487
|
+
alignSelf: "start"
|
|
31488
|
+
},
|
|
31489
|
+
horizontalRule: {
|
|
31490
|
+
marginTop: spacing.small_12,
|
|
31491
|
+
marginBottom: spacing.xxxSmall_4,
|
|
31492
|
+
height: 1,
|
|
31493
|
+
backgroundColor: color.offBlack16
|
|
31494
|
+
},
|
|
31495
|
+
labelContainer: {
|
|
31496
|
+
backgroundColor: color.white
|
|
31393
31497
|
}
|
|
31394
31498
|
});
|
|
31395
31499
|
|
|
31396
|
-
const
|
|
31397
|
-
const LockedLineSettings = props => {
|
|
31500
|
+
const LabeledSwitch = props => {
|
|
31398
31501
|
const {
|
|
31399
|
-
|
|
31400
|
-
|
|
31401
|
-
|
|
31402
|
-
|
|
31403
|
-
showPoint1,
|
|
31404
|
-
showPoint2,
|
|
31405
|
-
onChangeProps,
|
|
31406
|
-
onMove,
|
|
31407
|
-
onRemove
|
|
31502
|
+
checked,
|
|
31503
|
+
label,
|
|
31504
|
+
style,
|
|
31505
|
+
onChange
|
|
31408
31506
|
} = props;
|
|
31409
|
-
const
|
|
31410
|
-
const
|
|
31411
|
-
|
|
31412
|
-
|
|
31413
|
-
|
|
31414
|
-
|
|
31415
|
-
|
|
31416
|
-
|
|
31417
|
-
const newPoints = [...points];
|
|
31418
|
-
newPoints[index] = _extends({}, points[index], newPointProps);
|
|
31419
|
-
onChangeProps({
|
|
31420
|
-
points: newPoints
|
|
31421
|
-
});
|
|
31422
|
-
}
|
|
31423
|
-
function handleColorChange(newColor) {
|
|
31424
|
-
onChangeProps({
|
|
31425
|
-
color: newColor,
|
|
31426
|
-
// Keep the line's points' colors in sync with the line color.
|
|
31427
|
-
points: [_extends({}, point1, {
|
|
31428
|
-
color: newColor
|
|
31429
|
-
}), _extends({}, point2, {
|
|
31430
|
-
color: newColor
|
|
31431
|
-
})]
|
|
31432
|
-
});
|
|
31433
|
-
}
|
|
31434
|
-
return /*#__PURE__*/React.createElement(PerseusEditorAccordion, {
|
|
31435
|
-
expanded: props.expanded,
|
|
31436
|
-
onToggle: props.onToggle,
|
|
31437
|
-
header: /*#__PURE__*/React.createElement(View, {
|
|
31438
|
-
style: styles$n.row
|
|
31439
|
-
}, /*#__PURE__*/React.createElement(LabelLarge, null, lineLabel), /*#__PURE__*/React.createElement(Strut, {
|
|
31440
|
-
size: spacing.xSmall_8
|
|
31441
|
-
}), /*#__PURE__*/React.createElement(LineSwatch, {
|
|
31442
|
-
color: lineColor,
|
|
31443
|
-
lineStyle: lineStyle
|
|
31444
|
-
}))
|
|
31445
|
-
}, /*#__PURE__*/React.createElement(LabelMedium, {
|
|
31446
|
-
tag: "label",
|
|
31447
|
-
style: [styles$n.row, styles$n.spaceUnder]
|
|
31448
|
-
}, "kind", /*#__PURE__*/React.createElement(Strut, {
|
|
31449
|
-
size: spacing.xxxSmall_4
|
|
31450
|
-
}), /*#__PURE__*/React.createElement(SingleSelect, {
|
|
31451
|
-
selectedValue: kind,
|
|
31452
|
-
onChange: value => onChangeProps({
|
|
31453
|
-
kind: value
|
|
31454
|
-
})
|
|
31455
|
-
// Placeholder is required, but never gets used.
|
|
31456
|
-
,
|
|
31457
|
-
placeholder: ""
|
|
31458
|
-
}, /*#__PURE__*/React.createElement(OptionItem, {
|
|
31459
|
-
value: "line",
|
|
31460
|
-
label: "line"
|
|
31461
|
-
}), /*#__PURE__*/React.createElement(OptionItem, {
|
|
31462
|
-
value: "ray",
|
|
31463
|
-
label: "ray"
|
|
31464
|
-
}), /*#__PURE__*/React.createElement(OptionItem, {
|
|
31465
|
-
value: "segment",
|
|
31466
|
-
label: "segment"
|
|
31467
|
-
}))), /*#__PURE__*/React.createElement(View, {
|
|
31468
|
-
style: styles$n.row
|
|
31469
|
-
}, /*#__PURE__*/React.createElement(ColorSelect, {
|
|
31470
|
-
selectedValue: lineColor,
|
|
31471
|
-
onChange: handleColorChange
|
|
31507
|
+
const ids = useUniqueIdWithMock();
|
|
31508
|
+
const switchId = ids.get("switch");
|
|
31509
|
+
return /*#__PURE__*/React.createElement(View, {
|
|
31510
|
+
style: [styles$o.row, style]
|
|
31511
|
+
}, /*#__PURE__*/React.createElement(Switch, {
|
|
31512
|
+
id: switchId,
|
|
31513
|
+
checked: checked,
|
|
31514
|
+
onChange: onChange
|
|
31472
31515
|
}), /*#__PURE__*/React.createElement(Strut, {
|
|
31473
|
-
size: spacing.
|
|
31474
|
-
}), /*#__PURE__*/React.createElement(
|
|
31475
|
-
|
|
31476
|
-
|
|
31477
|
-
|
|
31478
|
-
})
|
|
31479
|
-
})), isInvalid && /*#__PURE__*/React.createElement(LabelMedium, {
|
|
31480
|
-
style: styles$n.errorText
|
|
31481
|
-
}, lengthZeroStr), /*#__PURE__*/React.createElement(DefiningPointSettings, _extends({
|
|
31482
|
-
label: "Point 1",
|
|
31483
|
-
showPoint: showPoint1,
|
|
31484
|
-
error: isInvalid ? lengthZeroStr : null
|
|
31485
|
-
}, point1, {
|
|
31486
|
-
onTogglePoint: newValue => onChangeProps({
|
|
31487
|
-
showPoint1: newValue
|
|
31488
|
-
}),
|
|
31489
|
-
onChangeProps: newProps => handleChangePoint(newProps, 0)
|
|
31490
|
-
})), /*#__PURE__*/React.createElement(DefiningPointSettings, _extends({
|
|
31491
|
-
label: "Point 2",
|
|
31492
|
-
showPoint: showPoint2,
|
|
31493
|
-
error: isInvalid ? lengthZeroStr : null
|
|
31494
|
-
}, point2, {
|
|
31495
|
-
onTogglePoint: newValue => onChangeProps({
|
|
31496
|
-
showPoint2: newValue
|
|
31497
|
-
}),
|
|
31498
|
-
onChangeProps: newProps => handleChangePoint(newProps, 1)
|
|
31499
|
-
})), /*#__PURE__*/React.createElement(LockedFigureSettingsActions, {
|
|
31500
|
-
figureType: props.type,
|
|
31501
|
-
onMove: onMove,
|
|
31502
|
-
onRemove: onRemove
|
|
31503
|
-
}));
|
|
31516
|
+
size: spacing.xSmall_8
|
|
31517
|
+
}), /*#__PURE__*/React.createElement(LabelMedium, {
|
|
31518
|
+
tag: "label",
|
|
31519
|
+
htmlFor: switchId
|
|
31520
|
+
}, label));
|
|
31504
31521
|
};
|
|
31505
|
-
const styles$
|
|
31522
|
+
const styles$o = StyleSheet.create({
|
|
31506
31523
|
row: {
|
|
31507
|
-
display: "flex",
|
|
31508
31524
|
flexDirection: "row",
|
|
31509
31525
|
alignItems: "center"
|
|
31510
|
-
},
|
|
31511
|
-
spaceUnder: {
|
|
31512
|
-
marginBottom: spacing.xSmall_8
|
|
31513
|
-
},
|
|
31514
|
-
errorText: {
|
|
31515
|
-
color: color.red
|
|
31516
31526
|
}
|
|
31517
31527
|
});
|
|
31518
31528
|
|
|
31519
|
-
const DEFAULT_COLOR = "grayH";
|
|
31520
|
-
function getDefaultFigureForType(type) {
|
|
31521
|
-
switch (type) {
|
|
31522
|
-
case "point":
|
|
31523
|
-
return {
|
|
31524
|
-
type: "point",
|
|
31525
|
-
coord: [0, 0],
|
|
31526
|
-
color: DEFAULT_COLOR,
|
|
31527
|
-
filled: true,
|
|
31528
|
-
labels: []
|
|
31529
|
-
};
|
|
31530
|
-
case "line":
|
|
31531
|
-
return {
|
|
31532
|
-
type: "line",
|
|
31533
|
-
kind: "line",
|
|
31534
|
-
points: [getDefaultFigureForType("point"), _extends({}, getDefaultFigureForType("point"), {
|
|
31535
|
-
coord: [2, 2]
|
|
31536
|
-
})],
|
|
31537
|
-
color: DEFAULT_COLOR,
|
|
31538
|
-
lineStyle: "solid",
|
|
31539
|
-
showPoint1: false,
|
|
31540
|
-
showPoint2: false
|
|
31541
|
-
};
|
|
31542
|
-
case "vector":
|
|
31543
|
-
return {
|
|
31544
|
-
type: "vector",
|
|
31545
|
-
points: [[0, 0], [2, 2]],
|
|
31546
|
-
color: DEFAULT_COLOR
|
|
31547
|
-
};
|
|
31548
|
-
case "ellipse":
|
|
31549
|
-
return {
|
|
31550
|
-
type: "ellipse",
|
|
31551
|
-
center: [0, 0],
|
|
31552
|
-
radius: [1, 1],
|
|
31553
|
-
angle: 0,
|
|
31554
|
-
color: DEFAULT_COLOR,
|
|
31555
|
-
fillStyle: "none",
|
|
31556
|
-
strokeStyle: "solid"
|
|
31557
|
-
};
|
|
31558
|
-
case "polygon":
|
|
31559
|
-
return {
|
|
31560
|
-
type: "polygon",
|
|
31561
|
-
points: [[0, 2], [-1, 0], [1, 0]],
|
|
31562
|
-
color: DEFAULT_COLOR,
|
|
31563
|
-
showVertices: false,
|
|
31564
|
-
fillStyle: "none",
|
|
31565
|
-
strokeStyle: "solid"
|
|
31566
|
-
};
|
|
31567
|
-
case "function":
|
|
31568
|
-
return {
|
|
31569
|
-
type: "function",
|
|
31570
|
-
color: DEFAULT_COLOR,
|
|
31571
|
-
strokeStyle: "solid",
|
|
31572
|
-
equation: "x^2",
|
|
31573
|
-
directionalAxis: "x"
|
|
31574
|
-
};
|
|
31575
|
-
case "label":
|
|
31576
|
-
return {
|
|
31577
|
-
type: "label",
|
|
31578
|
-
coord: [0, 0],
|
|
31579
|
-
text: "",
|
|
31580
|
-
color: DEFAULT_COLOR,
|
|
31581
|
-
size: "medium"
|
|
31582
|
-
};
|
|
31583
|
-
default:
|
|
31584
|
-
throw new UnreachableCaseError(type);
|
|
31585
|
-
}
|
|
31586
|
-
}
|
|
31587
|
-
|
|
31588
31529
|
const LockedPointSettings = props => {
|
|
31589
|
-
var _flags$mafs;
|
|
31530
|
+
var _flags$mafs, _flags$mafs2;
|
|
31590
31531
|
const {
|
|
31591
31532
|
flags,
|
|
31533
|
+
headerLabel,
|
|
31592
31534
|
coord,
|
|
31593
31535
|
color: pointColor,
|
|
31594
31536
|
filled = true,
|
|
31595
31537
|
labels,
|
|
31596
31538
|
onChangeProps,
|
|
31597
31539
|
onMove,
|
|
31598
|
-
onRemove
|
|
31540
|
+
onRemove,
|
|
31541
|
+
// defining point props
|
|
31542
|
+
showPoint,
|
|
31543
|
+
expanded,
|
|
31544
|
+
onTogglePoint,
|
|
31545
|
+
onToggle
|
|
31599
31546
|
} = props;
|
|
31547
|
+
const isDefiningPoint = !onMove && !onRemove;
|
|
31600
31548
|
function handleColorChange(newValue) {
|
|
31601
31549
|
const newProps = {
|
|
31602
31550
|
color: newValue
|
|
31603
31551
|
};
|
|
31604
31552
|
|
|
31605
31553
|
// Update the color of the all labels to match the point
|
|
31606
|
-
|
|
31607
|
-
|
|
31608
|
-
|
|
31554
|
+
if (labels) {
|
|
31555
|
+
newProps.labels = labels.map(label => _extends({}, label, {
|
|
31556
|
+
color: newValue
|
|
31557
|
+
}));
|
|
31558
|
+
}
|
|
31609
31559
|
onChangeProps(newProps);
|
|
31610
31560
|
}
|
|
31611
31561
|
function handleCoordChange(newCoord) {
|
|
@@ -31616,12 +31566,17 @@ const LockedPointSettings = props => {
|
|
|
31616
31566
|
};
|
|
31617
31567
|
|
|
31618
31568
|
// Update the coord by the same amount as the point for all labels
|
|
31619
|
-
|
|
31620
|
-
|
|
31621
|
-
|
|
31569
|
+
if (labels) {
|
|
31570
|
+
newProps.labels = labels.map(label => _extends({}, label, {
|
|
31571
|
+
coord: [label.coord[0] + xOffset, label.coord[1] + yOffset]
|
|
31572
|
+
}));
|
|
31573
|
+
}
|
|
31622
31574
|
onChangeProps(newProps);
|
|
31623
31575
|
}
|
|
31624
31576
|
function handleLabelChange(updatedLabel, labelIndex) {
|
|
31577
|
+
if (!labels) {
|
|
31578
|
+
return;
|
|
31579
|
+
}
|
|
31625
31580
|
const updatedLabels = [...labels];
|
|
31626
31581
|
updatedLabels[labelIndex] = _extends({}, labels[labelIndex], updatedLabel);
|
|
31627
31582
|
onChangeProps({
|
|
@@ -31629,20 +31584,25 @@ const LockedPointSettings = props => {
|
|
|
31629
31584
|
});
|
|
31630
31585
|
}
|
|
31631
31586
|
function handleLabelRemove(labelIndex) {
|
|
31587
|
+
if (!labels) {
|
|
31588
|
+
return;
|
|
31589
|
+
}
|
|
31632
31590
|
const updatedLabels = labels.filter((_, index) => index !== labelIndex);
|
|
31633
31591
|
onChangeProps({
|
|
31634
31592
|
labels: updatedLabels
|
|
31635
31593
|
});
|
|
31636
31594
|
}
|
|
31637
31595
|
return /*#__PURE__*/React.createElement(PerseusEditorAccordion, {
|
|
31638
|
-
expanded:
|
|
31639
|
-
onToggle:
|
|
31596
|
+
expanded: expanded,
|
|
31597
|
+
onToggle: onToggle,
|
|
31598
|
+
containerStyle: isDefiningPoint ? styles$n.definingContainer : undefined,
|
|
31599
|
+
panelStyle: isDefiningPoint ? styles$n.definingPanel : undefined,
|
|
31640
31600
|
header:
|
|
31641
31601
|
/*#__PURE__*/
|
|
31642
31602
|
// Summary: Point, coords, color (filled/open)
|
|
31643
31603
|
React.createElement(View, {
|
|
31644
|
-
style: styles$
|
|
31645
|
-
}, /*#__PURE__*/React.createElement(LabelLarge, null,
|
|
31604
|
+
style: styles$n.row
|
|
31605
|
+
}, /*#__PURE__*/React.createElement(LabelLarge, null, `${headerLabel || "Point"} (${coord[0]}, ${coord[1]})`), /*#__PURE__*/React.createElement(Strut, {
|
|
31646
31606
|
size: spacing.xSmall_8
|
|
31647
31607
|
}), /*#__PURE__*/React.createElement(ColorSwatch, {
|
|
31648
31608
|
color: pointColor,
|
|
@@ -31650,12 +31610,17 @@ const LockedPointSettings = props => {
|
|
|
31650
31610
|
}))
|
|
31651
31611
|
}, /*#__PURE__*/React.createElement(CoordinatePairInput, {
|
|
31652
31612
|
coord: coord,
|
|
31653
|
-
style: styles$
|
|
31613
|
+
style: styles$n.spaceUnder,
|
|
31654
31614
|
onChange: handleCoordChange
|
|
31655
|
-
}), /*#__PURE__*/React.createElement(
|
|
31615
|
+
}), onTogglePoint && /*#__PURE__*/React.createElement(LabeledSwitch, {
|
|
31616
|
+
label: "show point on graph",
|
|
31617
|
+
checked: !!showPoint,
|
|
31618
|
+
style: showPoint && styles$n.spaceUnder,
|
|
31619
|
+
onChange: onTogglePoint
|
|
31620
|
+
}), (!isDefiningPoint || showPoint) && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(ColorSelect, {
|
|
31656
31621
|
selectedValue: pointColor,
|
|
31657
31622
|
onChange: handleColorChange,
|
|
31658
|
-
style: styles$
|
|
31623
|
+
style: styles$n.spaceUnder
|
|
31659
31624
|
}), /*#__PURE__*/React.createElement(LabeledSwitch, {
|
|
31660
31625
|
label: "open point",
|
|
31661
31626
|
checked: !filled,
|
|
@@ -31663,9 +31628,9 @@ const LockedPointSettings = props => {
|
|
|
31663
31628
|
onChangeProps({
|
|
31664
31629
|
filled: !newValue
|
|
31665
31630
|
});
|
|
31666
|
-
}
|
|
31667
|
-
|
|
31668
|
-
|
|
31631
|
+
}
|
|
31632
|
+
})), (!isDefiningPoint && (flags == null || (_flags$mafs = flags["mafs"]) == null ? void 0 : _flags$mafs["locked-point-labels"]) || isDefiningPoint && (flags == null || (_flags$mafs2 = flags["mafs"]) == null ? void 0 : _flags$mafs2["locked-line-labels"])) && /*#__PURE__*/React.createElement(React.Fragment, null, labels == null ? void 0 : labels.map((label, labelIndex) => /*#__PURE__*/React.createElement(LockedLabelSettings, _extends({}, label, {
|
|
31633
|
+
containerStyle: !isDefiningPoint && styles$n.lockedPointLabelContainer,
|
|
31669
31634
|
expanded: true,
|
|
31670
31635
|
onChangeProps: newLabel => {
|
|
31671
31636
|
handleLabelChange(newLabel, labelIndex);
|
|
@@ -31677,6 +31642,7 @@ const LockedPointSettings = props => {
|
|
|
31677
31642
|
kind: "tertiary",
|
|
31678
31643
|
startIcon: plusCircle,
|
|
31679
31644
|
onClick: () => {
|
|
31645
|
+
var _labels$length;
|
|
31680
31646
|
const newLabel = _extends({}, getDefaultFigureForType("label"), {
|
|
31681
31647
|
// Place the label at the same position
|
|
31682
31648
|
// as the point. Add a small offset to
|
|
@@ -31684,12 +31650,228 @@ const LockedPointSettings = props => {
|
|
|
31684
31650
|
coord: [coord[0] + 0.5,
|
|
31685
31651
|
// Additional offset for each label so
|
|
31686
31652
|
// they don't overlap.
|
|
31687
|
-
coord[1] - 1 * (labels == null ? void 0 : labels.length)],
|
|
31653
|
+
coord[1] - 1 * ((_labels$length = labels == null ? void 0 : labels.length) != null ? _labels$length : 0)],
|
|
31688
31654
|
// Default to the same color as the point
|
|
31689
31655
|
color: pointColor
|
|
31690
31656
|
});
|
|
31691
31657
|
onChangeProps({
|
|
31692
|
-
labels: [...labels, newLabel]
|
|
31658
|
+
labels: [...(labels != null ? labels : []), newLabel]
|
|
31659
|
+
});
|
|
31660
|
+
},
|
|
31661
|
+
style: styles$n.addButton
|
|
31662
|
+
}, "Add visible label")), onRemove && /*#__PURE__*/React.createElement(LockedFigureSettingsActions, {
|
|
31663
|
+
figureType: props.type,
|
|
31664
|
+
onMove: onMove,
|
|
31665
|
+
onRemove: onRemove
|
|
31666
|
+
}));
|
|
31667
|
+
};
|
|
31668
|
+
const styles$n = StyleSheet.create({
|
|
31669
|
+
definingContainer: {
|
|
31670
|
+
marginTop: spacing.xSmall_8,
|
|
31671
|
+
marginBottom: 0,
|
|
31672
|
+
marginLeft: -spacing.xxxSmall_4,
|
|
31673
|
+
marginRight: -spacing.xxxSmall_4,
|
|
31674
|
+
backgroundColor: color.white
|
|
31675
|
+
},
|
|
31676
|
+
definingPanel: {
|
|
31677
|
+
// Need more space since we don't have the actions' margins.
|
|
31678
|
+
paddingBottom: spacing.xxSmall_6
|
|
31679
|
+
},
|
|
31680
|
+
// A regular point (NOT a defining point) has label
|
|
31681
|
+
// accordions with white backgrounds.
|
|
31682
|
+
lockedPointLabelContainer: {
|
|
31683
|
+
backgroundColor: color.white
|
|
31684
|
+
},
|
|
31685
|
+
row: {
|
|
31686
|
+
flexDirection: "row",
|
|
31687
|
+
alignItems: "center"
|
|
31688
|
+
},
|
|
31689
|
+
spaceUnder: {
|
|
31690
|
+
marginBottom: spacing.xSmall_8
|
|
31691
|
+
},
|
|
31692
|
+
addButton: {
|
|
31693
|
+
alignSelf: "start"
|
|
31694
|
+
}
|
|
31695
|
+
});
|
|
31696
|
+
|
|
31697
|
+
const lengthZeroStr = "The line cannot have length 0.";
|
|
31698
|
+
const LockedLineSettings = props => {
|
|
31699
|
+
var _flags$mafs;
|
|
31700
|
+
const {
|
|
31701
|
+
flags,
|
|
31702
|
+
kind,
|
|
31703
|
+
points,
|
|
31704
|
+
color: lineColor,
|
|
31705
|
+
lineStyle = "solid",
|
|
31706
|
+
showPoint1,
|
|
31707
|
+
showPoint2,
|
|
31708
|
+
labels,
|
|
31709
|
+
onChangeProps,
|
|
31710
|
+
onMove,
|
|
31711
|
+
onRemove
|
|
31712
|
+
} = props;
|
|
31713
|
+
const [point1, point2] = points;
|
|
31714
|
+
const capitalizeKind = kind.charAt(0).toUpperCase() + kind.slice(1);
|
|
31715
|
+
const lineLabel = `${capitalizeKind} (${point1.coord[0]},
|
|
31716
|
+
${point1.coord[1]}), (${point2.coord[0]}, ${point2.coord[1]})`;
|
|
31717
|
+
|
|
31718
|
+
// Check if the line has length 0.
|
|
31719
|
+
const isInvalid = vector.equal(point1.coord, point2.coord);
|
|
31720
|
+
function handleChangePoint(newPointProps, index) {
|
|
31721
|
+
const newPoints = [...points];
|
|
31722
|
+
newPoints[index] = _extends({}, points[index], newPointProps);
|
|
31723
|
+
|
|
31724
|
+
// Update labels to be centered between the two points,
|
|
31725
|
+
// retaining existing offset.
|
|
31726
|
+
const oldMidpoint = vec.midpoint(points[0].coord, points[1].coord);
|
|
31727
|
+
const newMidpoint = vec.midpoint(newPoints[0].coord, newPoints[1].coord);
|
|
31728
|
+
const offset = [newMidpoint[0] - oldMidpoint[0], newMidpoint[1] - oldMidpoint[1]];
|
|
31729
|
+
const newLabels = labels == null ? void 0 : labels.map((label, labelIndex) => _extends({}, label, {
|
|
31730
|
+
coord: [label.coord[0] + offset[0], label.coord[1] + offset[1]]
|
|
31731
|
+
}));
|
|
31732
|
+
onChangeProps({
|
|
31733
|
+
points: newPoints,
|
|
31734
|
+
labels: newLabels
|
|
31735
|
+
});
|
|
31736
|
+
}
|
|
31737
|
+
function handleColorChange(newColor) {
|
|
31738
|
+
var _point1$labels, _point2$labels;
|
|
31739
|
+
const newLabels = labels == null ? void 0 : labels.map(label => _extends({}, label, {
|
|
31740
|
+
color: newColor
|
|
31741
|
+
}));
|
|
31742
|
+
onChangeProps({
|
|
31743
|
+
color: newColor,
|
|
31744
|
+
// Keep the line's points' colors in sync with the line color.
|
|
31745
|
+
points: [_extends({}, point1, {
|
|
31746
|
+
color: newColor,
|
|
31747
|
+
labels: (_point1$labels = point1.labels) == null ? void 0 : _point1$labels.map(label => _extends({}, label, {
|
|
31748
|
+
color: newColor
|
|
31749
|
+
}))
|
|
31750
|
+
}), _extends({}, point2, {
|
|
31751
|
+
color: newColor,
|
|
31752
|
+
labels: (_point2$labels = point2.labels) == null ? void 0 : _point2$labels.map(label => _extends({}, label, {
|
|
31753
|
+
color: newColor
|
|
31754
|
+
}))
|
|
31755
|
+
})],
|
|
31756
|
+
// Keep the line's labels' colors in sync with the line color.
|
|
31757
|
+
labels: newLabels
|
|
31758
|
+
});
|
|
31759
|
+
}
|
|
31760
|
+
function handleLabelChange(updatedLabel, labelIndex) {
|
|
31761
|
+
if (!labels) {
|
|
31762
|
+
return;
|
|
31763
|
+
}
|
|
31764
|
+
const updatedLabels = [...labels];
|
|
31765
|
+
updatedLabels[labelIndex] = _extends({}, labels[labelIndex], updatedLabel);
|
|
31766
|
+
onChangeProps({
|
|
31767
|
+
labels: updatedLabels
|
|
31768
|
+
});
|
|
31769
|
+
}
|
|
31770
|
+
function handleLabelRemove(labelIndex) {
|
|
31771
|
+
if (!labels) {
|
|
31772
|
+
return;
|
|
31773
|
+
}
|
|
31774
|
+
const updatedLabels = labels.filter((_, index) => index !== labelIndex);
|
|
31775
|
+
onChangeProps({
|
|
31776
|
+
labels: updatedLabels
|
|
31777
|
+
});
|
|
31778
|
+
}
|
|
31779
|
+
return /*#__PURE__*/React.createElement(PerseusEditorAccordion, {
|
|
31780
|
+
expanded: props.expanded,
|
|
31781
|
+
onToggle: props.onToggle,
|
|
31782
|
+
header: /*#__PURE__*/React.createElement(View, {
|
|
31783
|
+
style: styles$m.row
|
|
31784
|
+
}, /*#__PURE__*/React.createElement(LabelLarge, null, lineLabel), /*#__PURE__*/React.createElement(Strut, {
|
|
31785
|
+
size: spacing.xSmall_8
|
|
31786
|
+
}), /*#__PURE__*/React.createElement(LineSwatch, {
|
|
31787
|
+
color: lineColor,
|
|
31788
|
+
lineStyle: lineStyle
|
|
31789
|
+
}))
|
|
31790
|
+
}, /*#__PURE__*/React.createElement(LabelMedium, {
|
|
31791
|
+
tag: "label",
|
|
31792
|
+
style: [styles$m.row, styles$m.spaceUnder]
|
|
31793
|
+
}, "kind", /*#__PURE__*/React.createElement(Strut, {
|
|
31794
|
+
size: spacing.xxxSmall_4
|
|
31795
|
+
}), /*#__PURE__*/React.createElement(SingleSelect, {
|
|
31796
|
+
selectedValue: kind,
|
|
31797
|
+
onChange: value => onChangeProps({
|
|
31798
|
+
kind: value
|
|
31799
|
+
})
|
|
31800
|
+
// Placeholder is required, but never gets used.
|
|
31801
|
+
,
|
|
31802
|
+
placeholder: ""
|
|
31803
|
+
}, /*#__PURE__*/React.createElement(OptionItem, {
|
|
31804
|
+
value: "line",
|
|
31805
|
+
label: "line"
|
|
31806
|
+
}), /*#__PURE__*/React.createElement(OptionItem, {
|
|
31807
|
+
value: "ray",
|
|
31808
|
+
label: "ray"
|
|
31809
|
+
}), /*#__PURE__*/React.createElement(OptionItem, {
|
|
31810
|
+
value: "segment",
|
|
31811
|
+
label: "segment"
|
|
31812
|
+
}))), /*#__PURE__*/React.createElement(View, {
|
|
31813
|
+
style: styles$m.row
|
|
31814
|
+
}, /*#__PURE__*/React.createElement(ColorSelect, {
|
|
31815
|
+
selectedValue: lineColor,
|
|
31816
|
+
onChange: handleColorChange
|
|
31817
|
+
}), /*#__PURE__*/React.createElement(Strut, {
|
|
31818
|
+
size: spacing.small_12
|
|
31819
|
+
}), /*#__PURE__*/React.createElement(LineStrokeSelect, {
|
|
31820
|
+
selectedValue: lineStyle,
|
|
31821
|
+
onChange: value => onChangeProps({
|
|
31822
|
+
lineStyle: value
|
|
31823
|
+
})
|
|
31824
|
+
})), isInvalid && /*#__PURE__*/React.createElement(LabelMedium, {
|
|
31825
|
+
style: styles$m.errorText
|
|
31826
|
+
}, lengthZeroStr), /*#__PURE__*/React.createElement(LockedPointSettings, _extends({
|
|
31827
|
+
flags: flags,
|
|
31828
|
+
headerLabel: "Point 1",
|
|
31829
|
+
expanded: true,
|
|
31830
|
+
showPoint: showPoint1,
|
|
31831
|
+
error: isInvalid ? lengthZeroStr : null
|
|
31832
|
+
}, point1, {
|
|
31833
|
+
onTogglePoint: newValue => onChangeProps({
|
|
31834
|
+
showPoint1: newValue
|
|
31835
|
+
}),
|
|
31836
|
+
onChangeProps: newProps => handleChangePoint(newProps, 0)
|
|
31837
|
+
})), /*#__PURE__*/React.createElement(LockedPointSettings, _extends({
|
|
31838
|
+
flags: flags,
|
|
31839
|
+
headerLabel: "Point 2",
|
|
31840
|
+
expanded: true,
|
|
31841
|
+
showPoint: showPoint2,
|
|
31842
|
+
error: isInvalid ? lengthZeroStr : null
|
|
31843
|
+
}, point2, {
|
|
31844
|
+
onTogglePoint: newValue => onChangeProps({
|
|
31845
|
+
showPoint2: newValue
|
|
31846
|
+
}),
|
|
31847
|
+
onChangeProps: newProps => handleChangePoint(newProps, 1)
|
|
31848
|
+
})), (flags == null || (_flags$mafs = flags["mafs"]) == null ? void 0 : _flags$mafs["locked-line-labels"]) && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(View, {
|
|
31849
|
+
style: styles$m.horizontalRule
|
|
31850
|
+
}), labels == null ? void 0 : labels.map((label, labelIndex) => /*#__PURE__*/React.createElement(LockedLabelSettings, _extends({}, label, {
|
|
31851
|
+
expanded: true,
|
|
31852
|
+
onChangeProps: newLabel => {
|
|
31853
|
+
handleLabelChange(newLabel, labelIndex);
|
|
31854
|
+
},
|
|
31855
|
+
onRemove: () => {
|
|
31856
|
+
handleLabelRemove(labelIndex);
|
|
31857
|
+
},
|
|
31858
|
+
containerStyle: styles$m.labelContainer
|
|
31859
|
+
}))), /*#__PURE__*/React.createElement(Button, {
|
|
31860
|
+
kind: "tertiary",
|
|
31861
|
+
startIcon: plusCircle,
|
|
31862
|
+
onClick: () => {
|
|
31863
|
+
var _labels$length;
|
|
31864
|
+
// Additional vertical offset for each label so
|
|
31865
|
+
// they don't overlap.
|
|
31866
|
+
const offsetPerLabel = [0, -1];
|
|
31867
|
+
const labelLocation = vec.add(vec.scale(offsetPerLabel, (_labels$length = labels == null ? void 0 : labels.length) != null ? _labels$length : 0), vec.midpoint(points[0].coord, points[1].coord));
|
|
31868
|
+
const newLabel = _extends({}, getDefaultFigureForType("label"), {
|
|
31869
|
+
coord: labelLocation,
|
|
31870
|
+
// Default to the same color as the line
|
|
31871
|
+
color: lineColor
|
|
31872
|
+
});
|
|
31873
|
+
onChangeProps({
|
|
31874
|
+
labels: [...(labels != null ? labels : []), newLabel]
|
|
31693
31875
|
});
|
|
31694
31876
|
},
|
|
31695
31877
|
style: styles$m.addButton
|
|
@@ -31701,14 +31883,27 @@ const LockedPointSettings = props => {
|
|
|
31701
31883
|
};
|
|
31702
31884
|
const styles$m = StyleSheet.create({
|
|
31703
31885
|
row: {
|
|
31886
|
+
display: "flex",
|
|
31704
31887
|
flexDirection: "row",
|
|
31705
31888
|
alignItems: "center"
|
|
31706
31889
|
},
|
|
31707
31890
|
spaceUnder: {
|
|
31708
31891
|
marginBottom: spacing.xSmall_8
|
|
31709
31892
|
},
|
|
31893
|
+
errorText: {
|
|
31894
|
+
color: color.red
|
|
31895
|
+
},
|
|
31710
31896
|
addButton: {
|
|
31711
31897
|
alignSelf: "start"
|
|
31898
|
+
},
|
|
31899
|
+
horizontalRule: {
|
|
31900
|
+
marginTop: spacing.small_12,
|
|
31901
|
+
marginBottom: spacing.xxxSmall_4,
|
|
31902
|
+
height: 1,
|
|
31903
|
+
backgroundColor: color.offBlack16
|
|
31904
|
+
},
|
|
31905
|
+
labelContainer: {
|
|
31906
|
+
backgroundColor: color.white
|
|
31712
31907
|
}
|
|
31713
31908
|
});
|
|
31714
31909
|
|
|
@@ -31959,17 +32154,14 @@ const styles$k = StyleSheet.create({
|
|
|
31959
32154
|
}
|
|
31960
32155
|
});
|
|
31961
32156
|
|
|
31962
|
-
/**
|
|
31963
|
-
* LockedVectorSettings is a component that allows the user to edit the
|
|
31964
|
-
* settings of specifically a locked vector on the graph.
|
|
31965
|
-
*
|
|
31966
|
-
* Used in the interactive graph editor's locked figures section.
|
|
31967
|
-
*/
|
|
31968
32157
|
const lengthErrorMessage = "The vector cannot have length 0.";
|
|
31969
32158
|
const LockedVectorSettings = props => {
|
|
32159
|
+
var _flags$mafs;
|
|
31970
32160
|
const {
|
|
32161
|
+
flags,
|
|
31971
32162
|
points,
|
|
31972
32163
|
color: lineColor,
|
|
32164
|
+
labels,
|
|
31973
32165
|
onChangeProps,
|
|
31974
32166
|
onMove,
|
|
31975
32167
|
onRemove
|
|
@@ -31983,14 +32175,48 @@ const LockedVectorSettings = props => {
|
|
|
31983
32175
|
if (typeof newCoord !== "undefined") {
|
|
31984
32176
|
const newPoints = [...points];
|
|
31985
32177
|
newPoints[index] = [...newCoord];
|
|
32178
|
+
|
|
32179
|
+
// Update labels to match the new points
|
|
32180
|
+
const oldMidpoint = vec.midpoint(tail, tip);
|
|
32181
|
+
const newMidpoint = vec.midpoint(newPoints[0], newPoints[1]);
|
|
32182
|
+
const offset = vec.sub(newMidpoint, oldMidpoint);
|
|
32183
|
+
const newLabels = labels == null ? void 0 : labels.map(label => _extends({}, label, {
|
|
32184
|
+
coord: vec.add(label.coord, offset)
|
|
32185
|
+
}));
|
|
31986
32186
|
onChangeProps({
|
|
31987
|
-
points: newPoints
|
|
32187
|
+
points: newPoints,
|
|
32188
|
+
labels: newLabels
|
|
31988
32189
|
});
|
|
31989
32190
|
}
|
|
31990
32191
|
}
|
|
31991
32192
|
function handleColorChange(newColor) {
|
|
31992
|
-
|
|
32193
|
+
const newProps = {
|
|
32194
|
+
color: newColor
|
|
32195
|
+
};
|
|
32196
|
+
|
|
32197
|
+
// Update the color of the all labels to match the point
|
|
32198
|
+
newProps.labels = labels == null ? void 0 : labels.map(label => _extends({}, label, {
|
|
31993
32199
|
color: newColor
|
|
32200
|
+
}));
|
|
32201
|
+
onChangeProps(newProps);
|
|
32202
|
+
}
|
|
32203
|
+
function handleLabelChange(updatedLabel, labelIndex) {
|
|
32204
|
+
if (!labels) {
|
|
32205
|
+
return;
|
|
32206
|
+
}
|
|
32207
|
+
const updatedLabels = [...labels];
|
|
32208
|
+
updatedLabels[labelIndex] = _extends({}, labels[labelIndex], updatedLabel);
|
|
32209
|
+
onChangeProps({
|
|
32210
|
+
labels: updatedLabels
|
|
32211
|
+
});
|
|
32212
|
+
}
|
|
32213
|
+
function handleLabelRemove(labelIndex) {
|
|
32214
|
+
if (!labels) {
|
|
32215
|
+
return;
|
|
32216
|
+
}
|
|
32217
|
+
const updatedLabels = labels.filter((_, index) => index !== labelIndex);
|
|
32218
|
+
onChangeProps({
|
|
32219
|
+
labels: updatedLabels
|
|
31994
32220
|
});
|
|
31995
32221
|
}
|
|
31996
32222
|
return /*#__PURE__*/React.createElement(PerseusEditorAccordion, {
|
|
@@ -32039,7 +32265,37 @@ const LockedVectorSettings = props => {
|
|
|
32039
32265
|
onChange: newProps => {
|
|
32040
32266
|
handleChangePoint(newProps, 1);
|
|
32041
32267
|
}
|
|
32042
|
-
})), /*#__PURE__*/React.createElement(
|
|
32268
|
+
})), (flags == null || (_flags$mafs = flags["mafs"]) == null ? void 0 : _flags$mafs["locked-vector-labels"]) && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(View, {
|
|
32269
|
+
style: styles$j.horizontalRule
|
|
32270
|
+
}), labels == null ? void 0 : labels.map((label, labelIndex) => /*#__PURE__*/React.createElement(LockedLabelSettings, _extends({}, label, {
|
|
32271
|
+
expanded: true,
|
|
32272
|
+
onChangeProps: newLabel => {
|
|
32273
|
+
handleLabelChange(newLabel, labelIndex);
|
|
32274
|
+
},
|
|
32275
|
+
onRemove: () => {
|
|
32276
|
+
handleLabelRemove(labelIndex);
|
|
32277
|
+
},
|
|
32278
|
+
containerStyle: styles$j.labelContainer
|
|
32279
|
+
}))), /*#__PURE__*/React.createElement(Button, {
|
|
32280
|
+
kind: "tertiary",
|
|
32281
|
+
startIcon: plusCircle,
|
|
32282
|
+
onClick: () => {
|
|
32283
|
+
var _labels$length;
|
|
32284
|
+
// Additional vertical offset for each label so
|
|
32285
|
+
// they don't overlap.
|
|
32286
|
+
const offsetPerLabel = [0, -1];
|
|
32287
|
+
const labelLocation = vec.add(vec.scale(offsetPerLabel, (_labels$length = labels == null ? void 0 : labels.length) != null ? _labels$length : 0), vec.midpoint(tail, tip));
|
|
32288
|
+
const newLabel = _extends({}, getDefaultFigureForType("label"), {
|
|
32289
|
+
coord: labelLocation,
|
|
32290
|
+
// Default to the same color as the vector
|
|
32291
|
+
color: lineColor
|
|
32292
|
+
});
|
|
32293
|
+
onChangeProps({
|
|
32294
|
+
labels: [...(labels != null ? labels : []), newLabel]
|
|
32295
|
+
});
|
|
32296
|
+
},
|
|
32297
|
+
style: styles$j.addButton
|
|
32298
|
+
}, "Add visible label")), /*#__PURE__*/React.createElement(LockedFigureSettingsActions, {
|
|
32043
32299
|
figureType: props.type,
|
|
32044
32300
|
onMove: onMove,
|
|
32045
32301
|
onRemove: onRemove
|
|
@@ -32063,6 +32319,18 @@ const styles$j = StyleSheet.create({
|
|
|
32063
32319
|
row: {
|
|
32064
32320
|
flexDirection: "row",
|
|
32065
32321
|
alignItems: "center"
|
|
32322
|
+
},
|
|
32323
|
+
addButton: {
|
|
32324
|
+
alignSelf: "start"
|
|
32325
|
+
},
|
|
32326
|
+
horizontalRule: {
|
|
32327
|
+
marginTop: spacing.small_12,
|
|
32328
|
+
marginBottom: spacing.xxxSmall_4,
|
|
32329
|
+
height: 1,
|
|
32330
|
+
backgroundColor: color.offBlack16
|
|
32331
|
+
},
|
|
32332
|
+
labelContainer: {
|
|
32333
|
+
backgroundColor: color.white
|
|
32066
32334
|
}
|
|
32067
32335
|
});
|
|
32068
32336
|
|