@khanacademy/perseus-editor 14.4.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/es/index.js +497 -264
- package/dist/es/index.js.map +1 -1
- package/dist/index.js +513 -272
- package/dist/index.js.map +1 -1
- 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 +267 -222
- package/dist/widgets/radio/editor.d.ts +0 -1
- package/package.json +2 -2
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,6 @@ 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 plusCircle from '@phosphor-icons/core/regular/plus-circle.svg';
|
|
38
38
|
import { vec } from 'mafs';
|
|
39
39
|
import arrowFatDown from '@phosphor-icons/core/regular/arrow-fat-down.svg';
|
|
40
40
|
import arrowFatLeft from '@phosphor-icons/core/regular/arrow-fat-left.svg';
|
|
@@ -45,7 +45,7 @@ import arrowCounterClockwise from '@phosphor-icons/core/bold/arrow-counter-clock
|
|
|
45
45
|
|
|
46
46
|
// This file is processed by a Rollup plugin (replace) to inject the production
|
|
47
47
|
const libName = "@khanacademy/perseus-editor";
|
|
48
|
-
const libVersion = "14.
|
|
48
|
+
const libVersion = "14.5.0";
|
|
49
49
|
addLibraryVersionToPerseusDebug(libName, libVersion);
|
|
50
50
|
|
|
51
51
|
function _extends() {
|
|
@@ -21904,8 +21904,7 @@ class IframeContentRenderer extends React.Component {
|
|
|
21904
21904
|
this._lastData = data;
|
|
21905
21905
|
|
|
21906
21906
|
// We can't use JSON.stringify/parse for this because the apiOptions
|
|
21907
|
-
// includes the functions GroupMetadataEditor, groupAnnotator,
|
|
21908
|
-
// onFocusChange, and onInputError.
|
|
21907
|
+
// includes the functions GroupMetadataEditor, groupAnnotator, and onFocusChange.
|
|
21909
21908
|
// @ts-expect-error - TS2339 - Property 'iframeDataStore' does not exist on type 'Window & typeof globalThis'.
|
|
21910
21909
|
window.iframeDataStore[this.iframeID] = data;
|
|
21911
21910
|
frame.contentWindow.postMessage(this.iframeID, "*");
|
|
@@ -29688,7 +29687,10 @@ function InteractiveGraphDescription(props) {
|
|
|
29688
29687
|
}, "Title", /*#__PURE__*/React.createElement(TextField, {
|
|
29689
29688
|
value: ariaLabelValue,
|
|
29690
29689
|
onChange: newValue => onChange({
|
|
29691
|
-
fullGraphAriaLabel:
|
|
29690
|
+
fullGraphAriaLabel:
|
|
29691
|
+
// Save as undefined if the new value
|
|
29692
|
+
// is an empty string.
|
|
29693
|
+
newValue || undefined
|
|
29692
29694
|
}),
|
|
29693
29695
|
style: styles$F.spaceAbove
|
|
29694
29696
|
})), /*#__PURE__*/React.createElement(Strut, {
|
|
@@ -29700,7 +29702,10 @@ function InteractiveGraphDescription(props) {
|
|
|
29700
29702
|
resizeType: "vertical",
|
|
29701
29703
|
value: ariaDescriptionValue,
|
|
29702
29704
|
onChange: newValue => onChange({
|
|
29703
|
-
fullGraphAriaDescription:
|
|
29705
|
+
fullGraphAriaDescription:
|
|
29706
|
+
// Save as undefined if the new value
|
|
29707
|
+
// is an empty string.
|
|
29708
|
+
newValue || undefined
|
|
29704
29709
|
}),
|
|
29705
29710
|
style: styles$F.spaceAbove
|
|
29706
29711
|
}))));
|
|
@@ -30718,15 +30723,205 @@ const styles$t = StyleSheet.create({
|
|
|
30718
30723
|
}
|
|
30719
30724
|
});
|
|
30720
30725
|
|
|
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) {
|
|
30734
|
+
const {
|
|
30735
|
+
type,
|
|
30736
|
+
coord,
|
|
30737
|
+
color: color$1,
|
|
30738
|
+
size,
|
|
30739
|
+
text,
|
|
30740
|
+
expanded,
|
|
30741
|
+
onChangeProps,
|
|
30742
|
+
onMove,
|
|
30743
|
+
onRemove,
|
|
30744
|
+
onToggle,
|
|
30745
|
+
containerStyle
|
|
30746
|
+
} = props;
|
|
30747
|
+
return /*#__PURE__*/React.createElement(PerseusEditorAccordion, {
|
|
30748
|
+
expanded: expanded,
|
|
30749
|
+
onToggle: onToggle,
|
|
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, {
|
|
30753
|
+
size: spacing.xSmall_8
|
|
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
|
|
30761
|
+
}, /*#__PURE__*/React.createElement(CoordinatePairInput, {
|
|
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, {
|
|
30773
|
+
size: spacing.xSmall_8
|
|
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
|
|
30790
|
+
}), /*#__PURE__*/React.createElement(Strut, {
|
|
30791
|
+
size: spacing.medium_16
|
|
30792
|
+
})), /*#__PURE__*/React.createElement(LabelMedium, {
|
|
30793
|
+
tag: "label",
|
|
30794
|
+
style: styles$s.row
|
|
30795
|
+
}, "size", /*#__PURE__*/React.createElement(Strut, {
|
|
30796
|
+
size: spacing.xSmall_8
|
|
30797
|
+
}), /*#__PURE__*/React.createElement(SingleSelect, {
|
|
30798
|
+
selectedValue: size,
|
|
30799
|
+
onChange: newValue => onChangeProps({
|
|
30800
|
+
size: newValue
|
|
30801
|
+
})
|
|
30802
|
+
// Placeholder is required, but never gets used since
|
|
30803
|
+
// we have a label for the select.
|
|
30804
|
+
,
|
|
30805
|
+
placeholder: ""
|
|
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,
|
|
30817
|
+
onMove: onMove,
|
|
30818
|
+
onRemove: onRemove
|
|
30819
|
+
}));
|
|
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
|
+
},
|
|
30833
|
+
row: {
|
|
30834
|
+
display: "flex",
|
|
30835
|
+
flexDirection: "row",
|
|
30836
|
+
alignItems: "center",
|
|
30837
|
+
// Allow truncation, stop bleeding over the edge.
|
|
30838
|
+
minWidth: 0
|
|
30839
|
+
},
|
|
30840
|
+
spaceUnder: {
|
|
30841
|
+
marginBottom: spacing.xSmall_8
|
|
30842
|
+
}
|
|
30843
|
+
});
|
|
30844
|
+
|
|
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
|
+
|
|
30721
30913
|
const {
|
|
30722
30914
|
InfoTip: InfoTip$c
|
|
30723
30915
|
} = components;
|
|
30724
30916
|
const LockedEllipseSettings = props => {
|
|
30917
|
+
var _flags$mafs;
|
|
30725
30918
|
const {
|
|
30919
|
+
flags,
|
|
30726
30920
|
center,
|
|
30727
30921
|
radius,
|
|
30728
30922
|
angle,
|
|
30729
30923
|
color,
|
|
30924
|
+
labels,
|
|
30730
30925
|
fillStyle,
|
|
30731
30926
|
strokeStyle,
|
|
30732
30927
|
expanded,
|
|
@@ -30735,9 +30930,47 @@ const LockedEllipseSettings = props => {
|
|
|
30735
30930
|
onMove,
|
|
30736
30931
|
onRemove
|
|
30737
30932
|
} = props;
|
|
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
|
+
};
|
|
30939
|
+
|
|
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);
|
|
30945
|
+
}
|
|
30738
30946
|
function handleColorChange(newValue) {
|
|
30739
|
-
|
|
30947
|
+
const newProps = {
|
|
30948
|
+
color: newValue
|
|
30949
|
+
};
|
|
30950
|
+
|
|
30951
|
+
// Update the color of the all labels to match the point
|
|
30952
|
+
newProps.labels = labels == null ? void 0 : labels.map(label => _extends({}, label, {
|
|
30740
30953
|
color: newValue
|
|
30954
|
+
}));
|
|
30955
|
+
onChangeProps(newProps);
|
|
30956
|
+
}
|
|
30957
|
+
function handleLabelChange(updatedLabel, labelIndex) {
|
|
30958
|
+
if (!labels) {
|
|
30959
|
+
return;
|
|
30960
|
+
}
|
|
30961
|
+
const updatedLabels = [...labels];
|
|
30962
|
+
updatedLabels[labelIndex] = _extends({}, labels[labelIndex], updatedLabel);
|
|
30963
|
+
onChangeProps({
|
|
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
|
|
30741
30974
|
});
|
|
30742
30975
|
}
|
|
30743
30976
|
return /*#__PURE__*/React.createElement(PerseusEditorAccordion, {
|
|
@@ -30747,7 +30980,7 @@ const LockedEllipseSettings = props => {
|
|
|
30747
30980
|
/*#__PURE__*/
|
|
30748
30981
|
// Summary: Ellipse, center, radius, color (opacity, dashed)
|
|
30749
30982
|
React.createElement(View, {
|
|
30750
|
-
style: styles$
|
|
30983
|
+
style: styles$r.row
|
|
30751
30984
|
}, /*#__PURE__*/React.createElement(LabelLarge, null, `Ellipse (${center[0]}, ${center[1]}), radius ${radius[0]}, ${radius[1]}`), /*#__PURE__*/React.createElement(Strut, {
|
|
30752
30985
|
size: spacing.xSmall_8
|
|
30753
30986
|
}), /*#__PURE__*/React.createElement(EllipseSwatch, {
|
|
@@ -30756,19 +30989,17 @@ const LockedEllipseSettings = props => {
|
|
|
30756
30989
|
strokeStyle: strokeStyle
|
|
30757
30990
|
}))
|
|
30758
30991
|
}, /*#__PURE__*/React.createElement(View, {
|
|
30759
|
-
style: styles$
|
|
30992
|
+
style: styles$r.row
|
|
30760
30993
|
}, /*#__PURE__*/React.createElement(CoordinatePairInput, {
|
|
30761
30994
|
coord: center,
|
|
30762
|
-
style: styles$
|
|
30763
|
-
onChange:
|
|
30764
|
-
center: newCoords
|
|
30765
|
-
})
|
|
30995
|
+
style: styles$r.spaceUnder,
|
|
30996
|
+
onChange: handleCenterChange
|
|
30766
30997
|
}), /*#__PURE__*/React.createElement(View, {
|
|
30767
|
-
style: styles$
|
|
30998
|
+
style: styles$r.spaceUnder
|
|
30768
30999
|
}, /*#__PURE__*/React.createElement(InfoTip$c, null, "The coordinates for the center of the ellipse."))), /*#__PURE__*/React.createElement(CoordinatePairInput, {
|
|
30769
31000
|
coord: radius,
|
|
30770
31001
|
labels: ["x radius", "y radius"],
|
|
30771
|
-
style: styles$
|
|
31002
|
+
style: styles$r.spaceUnder,
|
|
30772
31003
|
onChange: newCoords => onChangeProps({
|
|
30773
31004
|
radius: newCoords
|
|
30774
31005
|
})
|
|
@@ -30780,7 +31011,7 @@ const LockedEllipseSettings = props => {
|
|
|
30780
31011
|
}), /*#__PURE__*/React.createElement(Strut, {
|
|
30781
31012
|
size: spacing.xSmall_8
|
|
30782
31013
|
}), /*#__PURE__*/React.createElement(View, {
|
|
30783
|
-
style: [styles$
|
|
31014
|
+
style: [styles$r.row, styles$r.spaceUnder]
|
|
30784
31015
|
}, /*#__PURE__*/React.createElement(ColorSelect, {
|
|
30785
31016
|
selectedValue: color,
|
|
30786
31017
|
onChange: handleColorChange
|
|
@@ -30788,7 +31019,7 @@ const LockedEllipseSettings = props => {
|
|
|
30788
31019
|
size: spacing.medium_16
|
|
30789
31020
|
}), /*#__PURE__*/React.createElement(LabelMedium, {
|
|
30790
31021
|
tag: "label",
|
|
30791
|
-
style: [styles$
|
|
31022
|
+
style: [styles$r.row, styles$r.truncatedWidth]
|
|
30792
31023
|
}, "fill", /*#__PURE__*/React.createElement(Strut, {
|
|
30793
31024
|
size: spacing.xxSmall_6
|
|
30794
31025
|
}), /*#__PURE__*/React.createElement(SingleSelect, {
|
|
@@ -30808,13 +31039,40 @@ const LockedEllipseSettings = props => {
|
|
|
30808
31039
|
onChange: value => onChangeProps({
|
|
30809
31040
|
strokeStyle: value
|
|
30810
31041
|
})
|
|
30811
|
-
}), /*#__PURE__*/React.createElement(
|
|
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, {
|
|
30812
31070
|
figureType: props.type,
|
|
30813
31071
|
onMove: onMove,
|
|
30814
31072
|
onRemove: onRemove
|
|
30815
31073
|
}));
|
|
30816
31074
|
};
|
|
30817
|
-
const styles$
|
|
31075
|
+
const styles$r = StyleSheet.create({
|
|
30818
31076
|
row: {
|
|
30819
31077
|
display: "flex",
|
|
30820
31078
|
flexDirection: "row",
|
|
@@ -30826,6 +31084,12 @@ const styles$s = StyleSheet.create({
|
|
|
30826
31084
|
truncatedWidth: {
|
|
30827
31085
|
// Allow truncation, stop bleeding over the edge.
|
|
30828
31086
|
minWidth: 0
|
|
31087
|
+
},
|
|
31088
|
+
addButton: {
|
|
31089
|
+
alignSelf: "start"
|
|
31090
|
+
},
|
|
31091
|
+
labelContainer: {
|
|
31092
|
+
backgroundColor: color.white
|
|
30829
31093
|
}
|
|
30830
31094
|
});
|
|
30831
31095
|
|
|
@@ -30835,15 +31099,15 @@ const LineSwatch = props => {
|
|
|
30835
31099
|
lineStyle
|
|
30836
31100
|
} = props;
|
|
30837
31101
|
return /*#__PURE__*/React.createElement(View, {
|
|
30838
|
-
style: styles$
|
|
31102
|
+
style: styles$q.container
|
|
30839
31103
|
}, /*#__PURE__*/React.createElement(View, {
|
|
30840
31104
|
"aria-label": `${color}, ${lineStyle}`,
|
|
30841
|
-
style: [styles$
|
|
31105
|
+
style: [styles$q.lineSwatch, {
|
|
30842
31106
|
border: `5px ${lineStyle} ${lockedFigureColors[color]}`
|
|
30843
31107
|
}]
|
|
30844
31108
|
}));
|
|
30845
31109
|
};
|
|
30846
|
-
const styles$
|
|
31110
|
+
const styles$q = StyleSheet.create({
|
|
30847
31111
|
container: {
|
|
30848
31112
|
backgroundColor: color.white,
|
|
30849
31113
|
justifyContent: "center",
|
|
@@ -30861,19 +31125,16 @@ const examples = {
|
|
|
30861
31125
|
trigonometric: ["sin(x) * 3", "arctan(2x) + 4"]
|
|
30862
31126
|
};
|
|
30863
31127
|
|
|
30864
|
-
/**
|
|
30865
|
-
* LockedFunctionSettings is a component that allows the user to edit the
|
|
30866
|
-
* settings of specifically a locked function on the graph.
|
|
30867
|
-
*
|
|
30868
|
-
* Used in the interactive graph editor's locked figures section.
|
|
30869
|
-
*/
|
|
30870
31128
|
const LockedFunctionSettings = props => {
|
|
31129
|
+
var _flags$mafs;
|
|
30871
31130
|
const {
|
|
31131
|
+
flags,
|
|
30872
31132
|
color: lineColor,
|
|
30873
31133
|
strokeStyle,
|
|
30874
31134
|
equation,
|
|
30875
31135
|
directionalAxis,
|
|
30876
31136
|
domain,
|
|
31137
|
+
labels,
|
|
30877
31138
|
onChangeProps,
|
|
30878
31139
|
onMove,
|
|
30879
31140
|
onRemove
|
|
@@ -30924,13 +31185,43 @@ const LockedFunctionSettings = props => {
|
|
|
30924
31185
|
const exampleCategories = Object.keys(examples);
|
|
30925
31186
|
const exampleCategorySelected = exampleCategory !== "";
|
|
30926
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, {
|
|
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
|
|
31216
|
+
});
|
|
31217
|
+
}
|
|
30927
31218
|
return /*#__PURE__*/React.createElement(PerseusEditorAccordion, {
|
|
30928
31219
|
expanded: props.expanded,
|
|
30929
31220
|
onToggle: props.onToggle,
|
|
30930
31221
|
header: /*#__PURE__*/React.createElement(View, {
|
|
30931
|
-
style: styles$
|
|
31222
|
+
style: styles$p.row
|
|
30932
31223
|
}, /*#__PURE__*/React.createElement(LabelLarge, {
|
|
30933
|
-
style: styles$
|
|
31224
|
+
style: styles$p.accordionHeader
|
|
30934
31225
|
}, lineLabel), /*#__PURE__*/React.createElement(Strut, {
|
|
30935
31226
|
size: spacing.xSmall_8
|
|
30936
31227
|
}), /*#__PURE__*/React.createElement(LineSwatch, {
|
|
@@ -30938,12 +31229,10 @@ const LockedFunctionSettings = props => {
|
|
|
30938
31229
|
lineStyle: strokeStyle
|
|
30939
31230
|
}))
|
|
30940
31231
|
}, /*#__PURE__*/React.createElement(View, {
|
|
30941
|
-
style: [styles$
|
|
31232
|
+
style: [styles$p.row, styles$p.spaceUnder]
|
|
30942
31233
|
}, /*#__PURE__*/React.createElement(ColorSelect, {
|
|
30943
31234
|
selectedValue: lineColor,
|
|
30944
|
-
onChange:
|
|
30945
|
-
handlePropChange("color", newValue);
|
|
30946
|
-
}
|
|
31235
|
+
onChange: handleColorChange
|
|
30947
31236
|
}), /*#__PURE__*/React.createElement(Strut, {
|
|
30948
31237
|
size: spacing.small_12
|
|
30949
31238
|
}), /*#__PURE__*/React.createElement(LineStrokeSelect, {
|
|
@@ -30952,14 +31241,14 @@ const LockedFunctionSettings = props => {
|
|
|
30952
31241
|
handlePropChange("strokeStyle", newValue);
|
|
30953
31242
|
}
|
|
30954
31243
|
})), /*#__PURE__*/React.createElement(View, {
|
|
30955
|
-
style: [styles$
|
|
31244
|
+
style: [styles$p.row, styles$p.rowSpace]
|
|
30956
31245
|
}, /*#__PURE__*/React.createElement(SingleSelect, {
|
|
30957
31246
|
selectedValue: directionalAxis,
|
|
30958
31247
|
onChange: newValue => {
|
|
30959
31248
|
handlePropChange("directionalAxis", newValue);
|
|
30960
31249
|
},
|
|
30961
31250
|
"aria-label": "equation prefix",
|
|
30962
|
-
style: [styles$
|
|
31251
|
+
style: [styles$p.dropdownLabel, styles$p.axisMenu]
|
|
30963
31252
|
// Placeholder is required, but never gets used.
|
|
30964
31253
|
,
|
|
30965
31254
|
placeholder: ""
|
|
@@ -30978,17 +31267,17 @@ const LockedFunctionSettings = props => {
|
|
|
30978
31267
|
onChange: newValue => {
|
|
30979
31268
|
handlePropChange("equation", newValue);
|
|
30980
31269
|
},
|
|
30981
|
-
style: [styles$
|
|
31270
|
+
style: [styles$p.textField]
|
|
30982
31271
|
})), /*#__PURE__*/React.createElement(View, {
|
|
30983
|
-
style: [styles$
|
|
31272
|
+
style: [styles$p.row, styles$p.rowSpace]
|
|
30984
31273
|
}, /*#__PURE__*/React.createElement(LabelMedium, {
|
|
30985
31274
|
tag: "label",
|
|
30986
|
-
style: [styles$
|
|
31275
|
+
style: [styles$p.dropdownLabel, styles$p.domainMin]
|
|
30987
31276
|
}, `${domainRangeText} min`, /*#__PURE__*/React.createElement(Strut, {
|
|
30988
31277
|
size: spacing.xxSmall_6
|
|
30989
31278
|
}), /*#__PURE__*/React.createElement(TextField, {
|
|
30990
31279
|
type: "number",
|
|
30991
|
-
style: styles$
|
|
31280
|
+
style: styles$p.domainMinField,
|
|
30992
31281
|
value: domainEntries[0],
|
|
30993
31282
|
onChange: newValue => {
|
|
30994
31283
|
handleDomainChange(0, newValue);
|
|
@@ -30998,12 +31287,12 @@ const LockedFunctionSettings = props => {
|
|
|
30998
31287
|
}), /*#__PURE__*/React.createElement(LabelMedium, {
|
|
30999
31288
|
tag: "label",
|
|
31000
31289
|
"aria-label": `${domainRangeText} max`,
|
|
31001
|
-
style: [styles$
|
|
31290
|
+
style: [styles$p.dropdownLabel, styles$p.domainMax]
|
|
31002
31291
|
}, "max", /*#__PURE__*/React.createElement(Strut, {
|
|
31003
31292
|
size: spacing.xxSmall_6
|
|
31004
31293
|
}), /*#__PURE__*/React.createElement(TextField, {
|
|
31005
31294
|
type: "number",
|
|
31006
|
-
style: styles$
|
|
31295
|
+
style: styles$p.domainMaxField,
|
|
31007
31296
|
value: domainEntries[1],
|
|
31008
31297
|
onChange: newValue => {
|
|
31009
31298
|
handleDomainChange(1, newValue);
|
|
@@ -31011,11 +31300,11 @@ const LockedFunctionSettings = props => {
|
|
|
31011
31300
|
}))), /*#__PURE__*/React.createElement(PerseusEditorAccordion, {
|
|
31012
31301
|
header: /*#__PURE__*/React.createElement(LabelLarge, null, "Example Functions"),
|
|
31013
31302
|
expanded: false,
|
|
31014
|
-
containerStyle: styles$
|
|
31015
|
-
panelStyle: styles$
|
|
31303
|
+
containerStyle: styles$p.exampleWorkspace,
|
|
31304
|
+
panelStyle: styles$p.exampleAccordionPanel
|
|
31016
31305
|
}, /*#__PURE__*/React.createElement(LabelMedium, {
|
|
31017
31306
|
tag: "label",
|
|
31018
|
-
style: styles$
|
|
31307
|
+
style: styles$p.dropdownLabel
|
|
31019
31308
|
}, "Choose a category", /*#__PURE__*/React.createElement(Strut, {
|
|
31020
31309
|
size: spacing.xxSmall_6
|
|
31021
31310
|
}), /*#__PURE__*/React.createElement(SingleSelect, {
|
|
@@ -31029,13 +31318,41 @@ const LockedFunctionSettings = props => {
|
|
|
31029
31318
|
label: category
|
|
31030
31319
|
});
|
|
31031
31320
|
}))), exampleCategorySelected && /*#__PURE__*/React.createElement("ul", {
|
|
31032
|
-
className: css(styles$
|
|
31321
|
+
className: css(styles$p.exampleContainer)
|
|
31033
31322
|
}, exampleContent.map((example, index) => /*#__PURE__*/React.createElement(ExampleItem, {
|
|
31034
31323
|
category: exampleCategory,
|
|
31035
31324
|
example: example,
|
|
31036
31325
|
index: index,
|
|
31037
31326
|
pasteEquationFn: handlePropChange
|
|
31038
|
-
})))), /*#__PURE__*/React.createElement(
|
|
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
|
+
});
|
|
31350
|
+
onChangeProps({
|
|
31351
|
+
labels: [...(labels != null ? labels : []), newLabel]
|
|
31352
|
+
});
|
|
31353
|
+
},
|
|
31354
|
+
style: styles$p.addButton
|
|
31355
|
+
}, "Add visible label")), /*#__PURE__*/React.createElement(LockedFigureSettingsActions, {
|
|
31039
31356
|
figureType: props.type,
|
|
31040
31357
|
onMove: onMove,
|
|
31041
31358
|
onRemove: onRemove
|
|
@@ -31051,29 +31368,29 @@ const ExampleItem = props => {
|
|
|
31051
31368
|
const exampleId = useId();
|
|
31052
31369
|
return /*#__PURE__*/React.createElement("li", {
|
|
31053
31370
|
key: `${category}-${index}`,
|
|
31054
|
-
className: css(styles$
|
|
31371
|
+
className: css(styles$p.exampleRow)
|
|
31055
31372
|
}, /*#__PURE__*/React.createElement(IconButton, {
|
|
31056
31373
|
icon: autoPasteIcon,
|
|
31057
31374
|
"aria-label": "paste example",
|
|
31058
31375
|
"aria-describedby": exampleId,
|
|
31059
31376
|
onClick: () => pasteEquationFn("equation", example),
|
|
31060
31377
|
size: "medium",
|
|
31061
|
-
style: styles$
|
|
31378
|
+
style: styles$p.copyPasteButton
|
|
31062
31379
|
}), /*#__PURE__*/React.createElement(IconButton, {
|
|
31063
31380
|
icon: copyIcon,
|
|
31064
31381
|
"aria-label": "copy example",
|
|
31065
31382
|
"aria-describedby": exampleId,
|
|
31066
31383
|
onClick: () => navigator.clipboard.writeText(example),
|
|
31067
31384
|
size: "medium",
|
|
31068
|
-
style: styles$
|
|
31385
|
+
style: styles$p.copyPasteButton
|
|
31069
31386
|
}), /*#__PURE__*/React.createElement(Strut, {
|
|
31070
31387
|
size: spacing.xxxSmall_4
|
|
31071
31388
|
}), /*#__PURE__*/React.createElement(View, {
|
|
31072
|
-
style: styles$
|
|
31389
|
+
style: styles$p.exampleContent,
|
|
31073
31390
|
id: exampleId
|
|
31074
31391
|
}, example));
|
|
31075
31392
|
};
|
|
31076
|
-
const styles$
|
|
31393
|
+
const styles$p = StyleSheet.create({
|
|
31077
31394
|
accordionHeader: {
|
|
31078
31395
|
textOverflow: "ellipsis",
|
|
31079
31396
|
// A maximum width needs to be specified in order for the ellipsis to work.
|
|
@@ -31164,125 +31481,19 @@ const styles$q = StyleSheet.create({
|
|
|
31164
31481
|
},
|
|
31165
31482
|
textField: {
|
|
31166
31483
|
flexGrow: "1"
|
|
31167
|
-
}
|
|
31168
|
-
});
|
|
31169
|
-
|
|
31170
|
-
/**
|
|
31171
|
-
* LockedLabelSettings is a component that allows the user to edit the
|
|
31172
|
-
* settings of specifically a locked label on the graph within the
|
|
31173
|
-
* Interactive Graph widget.
|
|
31174
|
-
*
|
|
31175
|
-
* Used in the interactive graph editor's locked figures section.
|
|
31176
|
-
*/
|
|
31177
|
-
function LockedLabelSettings(props) {
|
|
31178
|
-
const {
|
|
31179
|
-
type,
|
|
31180
|
-
coord,
|
|
31181
|
-
color: color$1,
|
|
31182
|
-
size,
|
|
31183
|
-
text,
|
|
31184
|
-
expanded,
|
|
31185
|
-
onChangeProps,
|
|
31186
|
-
onMove,
|
|
31187
|
-
onRemove,
|
|
31188
|
-
onToggle,
|
|
31189
|
-
containerStyle
|
|
31190
|
-
} = props;
|
|
31191
|
-
return /*#__PURE__*/React.createElement(PerseusEditorAccordion, {
|
|
31192
|
-
expanded: expanded,
|
|
31193
|
-
onToggle: onToggle,
|
|
31194
|
-
header: /*#__PURE__*/React.createElement(View, {
|
|
31195
|
-
style: [styles$p.row, styles$p.accordionHeaderContainer]
|
|
31196
|
-
}, /*#__PURE__*/React.createElement(LabelLarge, null, "Label (", coord[0], ", ", coord[1], ")"), /*#__PURE__*/React.createElement(Strut, {
|
|
31197
|
-
size: spacing.xSmall_8
|
|
31198
|
-
}), text !== "" && /*#__PURE__*/React.createElement(LabelLarge, {
|
|
31199
|
-
style: [{
|
|
31200
|
-
backgroundColor: color.white,
|
|
31201
|
-
color: lockedFigureColors[color$1]
|
|
31202
|
-
}, styles$p.accordionHeader]
|
|
31203
|
-
}, text)),
|
|
31204
|
-
containerStyle: containerStyle
|
|
31205
|
-
}, /*#__PURE__*/React.createElement(CoordinatePairInput, {
|
|
31206
|
-
coord: coord,
|
|
31207
|
-
onChange: newCoords => {
|
|
31208
|
-
onChangeProps({
|
|
31209
|
-
coord: newCoords
|
|
31210
|
-
});
|
|
31211
|
-
},
|
|
31212
|
-
style: styles$p.spaceUnder
|
|
31213
|
-
}), /*#__PURE__*/React.createElement(LabelMedium, {
|
|
31214
|
-
tag: "label",
|
|
31215
|
-
style: [styles$p.row, styles$p.spaceUnder]
|
|
31216
|
-
}, "TeX", /*#__PURE__*/React.createElement(Strut, {
|
|
31217
|
-
size: spacing.xSmall_8
|
|
31218
|
-
}), /*#__PURE__*/React.createElement(TextField, {
|
|
31219
|
-
value: text,
|
|
31220
|
-
placeholder: "ex. x^2 or \\frac{1}{2}",
|
|
31221
|
-
onChange: newValue => onChangeProps({
|
|
31222
|
-
text: newValue
|
|
31223
|
-
})
|
|
31224
|
-
})), /*#__PURE__*/React.createElement(View, {
|
|
31225
|
-
style: styles$p.row
|
|
31226
|
-
}, onMove && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(ColorSelect, {
|
|
31227
|
-
selectedValue: color$1,
|
|
31228
|
-
onChange: newColor => {
|
|
31229
|
-
onChangeProps({
|
|
31230
|
-
color: newColor
|
|
31231
|
-
});
|
|
31232
|
-
},
|
|
31233
|
-
style: styles$p.spaceUnder
|
|
31234
|
-
}), /*#__PURE__*/React.createElement(Strut, {
|
|
31235
|
-
size: spacing.medium_16
|
|
31236
|
-
})), /*#__PURE__*/React.createElement(LabelMedium, {
|
|
31237
|
-
tag: "label",
|
|
31238
|
-
style: styles$p.row
|
|
31239
|
-
}, "size", /*#__PURE__*/React.createElement(Strut, {
|
|
31240
|
-
size: spacing.xSmall_8
|
|
31241
|
-
}), /*#__PURE__*/React.createElement(SingleSelect, {
|
|
31242
|
-
selectedValue: size,
|
|
31243
|
-
onChange: newValue => onChangeProps({
|
|
31244
|
-
size: newValue
|
|
31245
|
-
})
|
|
31246
|
-
// Placeholder is required, but never gets used since
|
|
31247
|
-
// we have a label for the select.
|
|
31248
|
-
,
|
|
31249
|
-
placeholder: ""
|
|
31250
|
-
}, /*#__PURE__*/React.createElement(OptionItem, {
|
|
31251
|
-
value: "small",
|
|
31252
|
-
label: "small"
|
|
31253
|
-
}), /*#__PURE__*/React.createElement(OptionItem, {
|
|
31254
|
-
value: "medium",
|
|
31255
|
-
label: "medium"
|
|
31256
|
-
}), /*#__PURE__*/React.createElement(OptionItem, {
|
|
31257
|
-
value: "large",
|
|
31258
|
-
label: "large"
|
|
31259
|
-
})))), /*#__PURE__*/React.createElement(LockedFigureSettingsActions, {
|
|
31260
|
-
figureType: type,
|
|
31261
|
-
onMove: onMove,
|
|
31262
|
-
onRemove: onRemove
|
|
31263
|
-
}));
|
|
31264
|
-
}
|
|
31265
|
-
const styles$p = StyleSheet.create({
|
|
31266
|
-
accordionHeaderContainer: {
|
|
31267
|
-
// Stop the label summary from wrapping.
|
|
31268
|
-
whiteSpace: "nowrap"
|
|
31269
31484
|
},
|
|
31270
|
-
|
|
31271
|
-
|
|
31272
|
-
|
|
31273
|
-
borderRadius: spacing.xxxSmall_4,
|
|
31274
|
-
textOverflow: "ellipsis",
|
|
31275
|
-
overflow: "hidden"
|
|
31485
|
+
// Label settings styles
|
|
31486
|
+
addButton: {
|
|
31487
|
+
alignSelf: "start"
|
|
31276
31488
|
},
|
|
31277
|
-
|
|
31278
|
-
|
|
31279
|
-
|
|
31280
|
-
|
|
31281
|
-
|
|
31282
|
-
minWidth: 0
|
|
31489
|
+
horizontalRule: {
|
|
31490
|
+
marginTop: spacing.small_12,
|
|
31491
|
+
marginBottom: spacing.xxxSmall_4,
|
|
31492
|
+
height: 1,
|
|
31493
|
+
backgroundColor: color.offBlack16
|
|
31283
31494
|
},
|
|
31284
|
-
|
|
31285
|
-
|
|
31495
|
+
labelContainer: {
|
|
31496
|
+
backgroundColor: color.white
|
|
31286
31497
|
}
|
|
31287
31498
|
});
|
|
31288
31499
|
|
|
@@ -31315,76 +31526,6 @@ const styles$o = StyleSheet.create({
|
|
|
31315
31526
|
}
|
|
31316
31527
|
});
|
|
31317
31528
|
|
|
31318
|
-
const DEFAULT_COLOR = "grayH";
|
|
31319
|
-
function getDefaultFigureForType(type) {
|
|
31320
|
-
switch (type) {
|
|
31321
|
-
case "point":
|
|
31322
|
-
return {
|
|
31323
|
-
type: "point",
|
|
31324
|
-
coord: [0, 0],
|
|
31325
|
-
color: DEFAULT_COLOR,
|
|
31326
|
-
filled: true,
|
|
31327
|
-
labels: []
|
|
31328
|
-
};
|
|
31329
|
-
case "line":
|
|
31330
|
-
return {
|
|
31331
|
-
type: "line",
|
|
31332
|
-
kind: "line",
|
|
31333
|
-
points: [getDefaultFigureForType("point"), _extends({}, getDefaultFigureForType("point"), {
|
|
31334
|
-
coord: [2, 2]
|
|
31335
|
-
})],
|
|
31336
|
-
color: DEFAULT_COLOR,
|
|
31337
|
-
lineStyle: "solid",
|
|
31338
|
-
showPoint1: false,
|
|
31339
|
-
showPoint2: false,
|
|
31340
|
-
labels: []
|
|
31341
|
-
};
|
|
31342
|
-
case "vector":
|
|
31343
|
-
return {
|
|
31344
|
-
type: "vector",
|
|
31345
|
-
points: [[0, 0], [2, 2]],
|
|
31346
|
-
color: DEFAULT_COLOR
|
|
31347
|
-
};
|
|
31348
|
-
case "ellipse":
|
|
31349
|
-
return {
|
|
31350
|
-
type: "ellipse",
|
|
31351
|
-
center: [0, 0],
|
|
31352
|
-
radius: [1, 1],
|
|
31353
|
-
angle: 0,
|
|
31354
|
-
color: DEFAULT_COLOR,
|
|
31355
|
-
fillStyle: "none",
|
|
31356
|
-
strokeStyle: "solid"
|
|
31357
|
-
};
|
|
31358
|
-
case "polygon":
|
|
31359
|
-
return {
|
|
31360
|
-
type: "polygon",
|
|
31361
|
-
points: [[0, 2], [-1, 0], [1, 0]],
|
|
31362
|
-
color: DEFAULT_COLOR,
|
|
31363
|
-
showVertices: false,
|
|
31364
|
-
fillStyle: "none",
|
|
31365
|
-
strokeStyle: "solid"
|
|
31366
|
-
};
|
|
31367
|
-
case "function":
|
|
31368
|
-
return {
|
|
31369
|
-
type: "function",
|
|
31370
|
-
color: DEFAULT_COLOR,
|
|
31371
|
-
strokeStyle: "solid",
|
|
31372
|
-
equation: "x^2",
|
|
31373
|
-
directionalAxis: "x"
|
|
31374
|
-
};
|
|
31375
|
-
case "label":
|
|
31376
|
-
return {
|
|
31377
|
-
type: "label",
|
|
31378
|
-
coord: [0, 0],
|
|
31379
|
-
text: "",
|
|
31380
|
-
color: DEFAULT_COLOR,
|
|
31381
|
-
size: "medium"
|
|
31382
|
-
};
|
|
31383
|
-
default:
|
|
31384
|
-
throw new UnreachableCaseError(type);
|
|
31385
|
-
}
|
|
31386
|
-
}
|
|
31387
|
-
|
|
31388
31529
|
const LockedPointSettings = props => {
|
|
31389
31530
|
var _flags$mafs, _flags$mafs2;
|
|
31390
31531
|
const {
|
|
@@ -31410,9 +31551,11 @@ const LockedPointSettings = props => {
|
|
|
31410
31551
|
};
|
|
31411
31552
|
|
|
31412
31553
|
// Update the color of the all labels to match the point
|
|
31413
|
-
|
|
31414
|
-
|
|
31415
|
-
|
|
31554
|
+
if (labels) {
|
|
31555
|
+
newProps.labels = labels.map(label => _extends({}, label, {
|
|
31556
|
+
color: newValue
|
|
31557
|
+
}));
|
|
31558
|
+
}
|
|
31416
31559
|
onChangeProps(newProps);
|
|
31417
31560
|
}
|
|
31418
31561
|
function handleCoordChange(newCoord) {
|
|
@@ -31423,12 +31566,17 @@ const LockedPointSettings = props => {
|
|
|
31423
31566
|
};
|
|
31424
31567
|
|
|
31425
31568
|
// Update the coord by the same amount as the point for all labels
|
|
31426
|
-
|
|
31427
|
-
|
|
31428
|
-
|
|
31569
|
+
if (labels) {
|
|
31570
|
+
newProps.labels = labels.map(label => _extends({}, label, {
|
|
31571
|
+
coord: [label.coord[0] + xOffset, label.coord[1] + yOffset]
|
|
31572
|
+
}));
|
|
31573
|
+
}
|
|
31429
31574
|
onChangeProps(newProps);
|
|
31430
31575
|
}
|
|
31431
31576
|
function handleLabelChange(updatedLabel, labelIndex) {
|
|
31577
|
+
if (!labels) {
|
|
31578
|
+
return;
|
|
31579
|
+
}
|
|
31432
31580
|
const updatedLabels = [...labels];
|
|
31433
31581
|
updatedLabels[labelIndex] = _extends({}, labels[labelIndex], updatedLabel);
|
|
31434
31582
|
onChangeProps({
|
|
@@ -31436,6 +31584,9 @@ const LockedPointSettings = props => {
|
|
|
31436
31584
|
});
|
|
31437
31585
|
}
|
|
31438
31586
|
function handleLabelRemove(labelIndex) {
|
|
31587
|
+
if (!labels) {
|
|
31588
|
+
return;
|
|
31589
|
+
}
|
|
31439
31590
|
const updatedLabels = labels.filter((_, index) => index !== labelIndex);
|
|
31440
31591
|
onChangeProps({
|
|
31441
31592
|
labels: updatedLabels
|
|
@@ -31478,7 +31629,7 @@ const LockedPointSettings = props => {
|
|
|
31478
31629
|
filled: !newValue
|
|
31479
31630
|
});
|
|
31480
31631
|
}
|
|
31481
|
-
})), (!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.map((label, labelIndex) => /*#__PURE__*/React.createElement(LockedLabelSettings, _extends({}, label, {
|
|
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, {
|
|
31482
31633
|
containerStyle: !isDefiningPoint && styles$n.lockedPointLabelContainer,
|
|
31483
31634
|
expanded: true,
|
|
31484
31635
|
onChangeProps: newLabel => {
|
|
@@ -31491,6 +31642,7 @@ const LockedPointSettings = props => {
|
|
|
31491
31642
|
kind: "tertiary",
|
|
31492
31643
|
startIcon: plusCircle,
|
|
31493
31644
|
onClick: () => {
|
|
31645
|
+
var _labels$length;
|
|
31494
31646
|
const newLabel = _extends({}, getDefaultFigureForType("label"), {
|
|
31495
31647
|
// Place the label at the same position
|
|
31496
31648
|
// as the point. Add a small offset to
|
|
@@ -31498,12 +31650,12 @@ const LockedPointSettings = props => {
|
|
|
31498
31650
|
coord: [coord[0] + 0.5,
|
|
31499
31651
|
// Additional offset for each label so
|
|
31500
31652
|
// they don't overlap.
|
|
31501
|
-
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)],
|
|
31502
31654
|
// Default to the same color as the point
|
|
31503
31655
|
color: pointColor
|
|
31504
31656
|
});
|
|
31505
31657
|
onChangeProps({
|
|
31506
|
-
labels: [...labels, newLabel]
|
|
31658
|
+
labels: [...(labels != null ? labels : []), newLabel]
|
|
31507
31659
|
});
|
|
31508
31660
|
},
|
|
31509
31661
|
style: styles$n.addButton
|
|
@@ -31574,7 +31726,7 @@ const LockedLineSettings = props => {
|
|
|
31574
31726
|
const oldMidpoint = vec.midpoint(points[0].coord, points[1].coord);
|
|
31575
31727
|
const newMidpoint = vec.midpoint(newPoints[0].coord, newPoints[1].coord);
|
|
31576
31728
|
const offset = [newMidpoint[0] - oldMidpoint[0], newMidpoint[1] - oldMidpoint[1]];
|
|
31577
|
-
const newLabels = labels.map((label, labelIndex) => _extends({}, label, {
|
|
31729
|
+
const newLabels = labels == null ? void 0 : labels.map((label, labelIndex) => _extends({}, label, {
|
|
31578
31730
|
coord: [label.coord[0] + offset[0], label.coord[1] + offset[1]]
|
|
31579
31731
|
}));
|
|
31580
31732
|
onChangeProps({
|
|
@@ -31583,7 +31735,8 @@ const LockedLineSettings = props => {
|
|
|
31583
31735
|
});
|
|
31584
31736
|
}
|
|
31585
31737
|
function handleColorChange(newColor) {
|
|
31586
|
-
|
|
31738
|
+
var _point1$labels, _point2$labels;
|
|
31739
|
+
const newLabels = labels == null ? void 0 : labels.map(label => _extends({}, label, {
|
|
31587
31740
|
color: newColor
|
|
31588
31741
|
}));
|
|
31589
31742
|
onChangeProps({
|
|
@@ -31591,12 +31744,12 @@ const LockedLineSettings = props => {
|
|
|
31591
31744
|
// Keep the line's points' colors in sync with the line color.
|
|
31592
31745
|
points: [_extends({}, point1, {
|
|
31593
31746
|
color: newColor,
|
|
31594
|
-
labels: point1.labels.map(label => _extends({}, label, {
|
|
31747
|
+
labels: (_point1$labels = point1.labels) == null ? void 0 : _point1$labels.map(label => _extends({}, label, {
|
|
31595
31748
|
color: newColor
|
|
31596
31749
|
}))
|
|
31597
31750
|
}), _extends({}, point2, {
|
|
31598
31751
|
color: newColor,
|
|
31599
|
-
labels: point2.labels.map(label => _extends({}, label, {
|
|
31752
|
+
labels: (_point2$labels = point2.labels) == null ? void 0 : _point2$labels.map(label => _extends({}, label, {
|
|
31600
31753
|
color: newColor
|
|
31601
31754
|
}))
|
|
31602
31755
|
})],
|
|
@@ -31605,6 +31758,9 @@ const LockedLineSettings = props => {
|
|
|
31605
31758
|
});
|
|
31606
31759
|
}
|
|
31607
31760
|
function handleLabelChange(updatedLabel, labelIndex) {
|
|
31761
|
+
if (!labels) {
|
|
31762
|
+
return;
|
|
31763
|
+
}
|
|
31608
31764
|
const updatedLabels = [...labels];
|
|
31609
31765
|
updatedLabels[labelIndex] = _extends({}, labels[labelIndex], updatedLabel);
|
|
31610
31766
|
onChangeProps({
|
|
@@ -31612,6 +31768,9 @@ const LockedLineSettings = props => {
|
|
|
31612
31768
|
});
|
|
31613
31769
|
}
|
|
31614
31770
|
function handleLabelRemove(labelIndex) {
|
|
31771
|
+
if (!labels) {
|
|
31772
|
+
return;
|
|
31773
|
+
}
|
|
31615
31774
|
const updatedLabels = labels.filter((_, index) => index !== labelIndex);
|
|
31616
31775
|
onChangeProps({
|
|
31617
31776
|
labels: updatedLabels
|
|
@@ -31688,7 +31847,7 @@ const LockedLineSettings = props => {
|
|
|
31688
31847
|
onChangeProps: newProps => handleChangePoint(newProps, 1)
|
|
31689
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, {
|
|
31690
31849
|
style: styles$m.horizontalRule
|
|
31691
|
-
}), labels.map((label, labelIndex) => /*#__PURE__*/React.createElement(LockedLabelSettings, _extends({}, label, {
|
|
31850
|
+
}), labels == null ? void 0 : labels.map((label, labelIndex) => /*#__PURE__*/React.createElement(LockedLabelSettings, _extends({}, label, {
|
|
31692
31851
|
expanded: true,
|
|
31693
31852
|
onChangeProps: newLabel => {
|
|
31694
31853
|
handleLabelChange(newLabel, labelIndex);
|
|
@@ -31701,17 +31860,18 @@ const LockedLineSettings = props => {
|
|
|
31701
31860
|
kind: "tertiary",
|
|
31702
31861
|
startIcon: plusCircle,
|
|
31703
31862
|
onClick: () => {
|
|
31863
|
+
var _labels$length;
|
|
31704
31864
|
// Additional vertical offset for each label so
|
|
31705
31865
|
// they don't overlap.
|
|
31706
31866
|
const offsetPerLabel = [0, -1];
|
|
31707
|
-
const labelLocation = vec.add(vec.scale(offsetPerLabel, labels.length), vec.midpoint(points[0].coord, points[1].coord));
|
|
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));
|
|
31708
31868
|
const newLabel = _extends({}, getDefaultFigureForType("label"), {
|
|
31709
31869
|
coord: labelLocation,
|
|
31710
|
-
// Default to the same color as the
|
|
31870
|
+
// Default to the same color as the line
|
|
31711
31871
|
color: lineColor
|
|
31712
31872
|
});
|
|
31713
31873
|
onChangeProps({
|
|
31714
|
-
labels: [...labels, newLabel]
|
|
31874
|
+
labels: [...(labels != null ? labels : []), newLabel]
|
|
31715
31875
|
});
|
|
31716
31876
|
},
|
|
31717
31877
|
style: styles$m.addButton
|
|
@@ -31994,17 +32154,14 @@ const styles$k = StyleSheet.create({
|
|
|
31994
32154
|
}
|
|
31995
32155
|
});
|
|
31996
32156
|
|
|
31997
|
-
/**
|
|
31998
|
-
* LockedVectorSettings is a component that allows the user to edit the
|
|
31999
|
-
* settings of specifically a locked vector on the graph.
|
|
32000
|
-
*
|
|
32001
|
-
* Used in the interactive graph editor's locked figures section.
|
|
32002
|
-
*/
|
|
32003
32157
|
const lengthErrorMessage = "The vector cannot have length 0.";
|
|
32004
32158
|
const LockedVectorSettings = props => {
|
|
32159
|
+
var _flags$mafs;
|
|
32005
32160
|
const {
|
|
32161
|
+
flags,
|
|
32006
32162
|
points,
|
|
32007
32163
|
color: lineColor,
|
|
32164
|
+
labels,
|
|
32008
32165
|
onChangeProps,
|
|
32009
32166
|
onMove,
|
|
32010
32167
|
onRemove
|
|
@@ -32018,14 +32175,48 @@ const LockedVectorSettings = props => {
|
|
|
32018
32175
|
if (typeof newCoord !== "undefined") {
|
|
32019
32176
|
const newPoints = [...points];
|
|
32020
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
|
+
}));
|
|
32021
32186
|
onChangeProps({
|
|
32022
|
-
points: newPoints
|
|
32187
|
+
points: newPoints,
|
|
32188
|
+
labels: newLabels
|
|
32023
32189
|
});
|
|
32024
32190
|
}
|
|
32025
32191
|
}
|
|
32026
32192
|
function handleColorChange(newColor) {
|
|
32027
|
-
|
|
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, {
|
|
32028
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
|
|
32029
32220
|
});
|
|
32030
32221
|
}
|
|
32031
32222
|
return /*#__PURE__*/React.createElement(PerseusEditorAccordion, {
|
|
@@ -32074,7 +32265,37 @@ const LockedVectorSettings = props => {
|
|
|
32074
32265
|
onChange: newProps => {
|
|
32075
32266
|
handleChangePoint(newProps, 1);
|
|
32076
32267
|
}
|
|
32077
|
-
})), /*#__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, {
|
|
32078
32299
|
figureType: props.type,
|
|
32079
32300
|
onMove: onMove,
|
|
32080
32301
|
onRemove: onRemove
|
|
@@ -32098,6 +32319,18 @@ const styles$j = StyleSheet.create({
|
|
|
32098
32319
|
row: {
|
|
32099
32320
|
flexDirection: "row",
|
|
32100
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
|
|
32101
32334
|
}
|
|
32102
32335
|
});
|
|
32103
32336
|
|