@khanacademy/perseus-editor 44.0.1 → 44.0.3
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 -1
- package/dist/index.js +15 -16
- package/dist/index.js.map +1 -1
- package/dist/widgets/dropdown-editor/dropdown-editor.d.ts +0 -4
- package/dist/widgets/expression-editor/expression-editor.d.ts +11 -2
- package/dist/widgets/free-response-editor/free-response-editor.d.ts +7 -1
- package/dist/widgets/interaction-editor/constraint-editor.d.ts +7 -14
- package/dist/widgets/interaction-editor/function-editor.d.ts +6 -19
- package/dist/widgets/interaction-editor/interaction-editor.d.ts +10 -16
- package/dist/widgets/interaction-editor/label-editor.d.ts +6 -15
- package/dist/widgets/interaction-editor/line-editor.d.ts +6 -22
- package/dist/widgets/interaction-editor/movable-line-editor.d.ts +6 -23
- package/dist/widgets/interaction-editor/movable-point-editor.d.ts +6 -18
- package/dist/widgets/interaction-editor/parametric-editor.d.ts +6 -21
- package/dist/widgets/interaction-editor/point-editor.d.ts +6 -13
- package/dist/widgets/interaction-editor/rectangle-editor.d.ts +6 -17
- package/dist/widgets/interactive-graph-editor/components/interactive-graph-settings.d.ts +15 -14
- package/dist/widgets/interactive-graph-editor/interactive-graph-editor.d.ts +33 -95
- package/dist/widgets/label-image-editor/answer-choices.d.ts +1 -1
- package/dist/widgets/label-image-editor/select-image.d.ts +1 -1
- package/dist/widgets/numeric-input-editor/numeric-input-editor.d.ts +7 -1
- package/dist/widgets/table-editor/table-editor.d.ts +5 -7
- package/package.json +7 -7
- package/dist/testing/split-view.d.ts +0 -13
|
@@ -28,7 +28,7 @@ declare class WidgetEditor extends React.Component<Props, State> {
|
|
|
28
28
|
_handleAlignmentChange: (newAlignment: Alignment) => void;
|
|
29
29
|
getSaveWarnings: () => unknown;
|
|
30
30
|
serialize: () => {
|
|
31
|
-
type: "iframe" | "table" | "video" | "image" | "radio" | "definition" | "group" | "blank" | "categorizer" | "cs-program" | "dropdown" | "explanation" | "expression" | "fill-in-the-blank" | "free-response" | "grapher" | "graded-group-set" | "graded-group" | "input-number" | "interaction" | "interactive-graph" | "label-image" | "matcher" | "matrix" | "measurer" | "number-line" | "numeric-input" | "orderer" | "phet-simulation" | "python-program" | "plotter" | "sorter" | "
|
|
31
|
+
type: "iframe" | "table" | "video" | "image" | "radio" | "definition" | "group" | "blank" | "categorizer" | "cs-program" | "dropdown" | "explanation" | "expression" | "fill-in-the-blank" | "free-response" | "grapher" | "graded-group-set" | "graded-group" | "input-number" | "interaction" | "interactive-graph" | "label-image" | "matcher" | "matrix" | "measurer" | "number-line" | "numeric-input" | "orderer" | "phet-simulation" | "python-program" | "plotter" | "sorter" | "molecule-renderer" | "passage-ref-target" | "passage-ref" | "passage" | "lights-puzzle" | "sequence" | "simulator" | "transformer" | "mock-widget";
|
|
32
32
|
alignment: Alignment | undefined;
|
|
33
33
|
static: boolean | undefined;
|
|
34
34
|
graded: boolean | undefined;
|
package/dist/index.js
CHANGED
|
@@ -35,7 +35,6 @@ import { Checkbox as Checkbox$1, RadioGroup, Choice, TextField, LabeledTextField
|
|
|
35
35
|
import { StatefulKeypadContextProvider, KeypadContext } from '@khanacademy/keypad-context';
|
|
36
36
|
import { MobileKeypad, useMathInputI18n, createMathField } from '@khanacademy/math-input';
|
|
37
37
|
import { useActionScheduler } from '@khanacademy/wonder-blocks-timing';
|
|
38
|
-
import PropTypes from 'prop-types';
|
|
39
38
|
import * as KAS from '@khanacademy/kas';
|
|
40
39
|
import { LabeledField } from '@khanacademy/wonder-blocks-labeled-field';
|
|
41
40
|
import plusCircle from '@phosphor-icons/core/regular/plus-circle.svg';
|
|
@@ -67,7 +66,7 @@ import minusCircleIcon from '@phosphor-icons/core/bold/minus-circle-bold.svg';
|
|
|
67
66
|
import arrowDown from '@phosphor-icons/core/regular/arrow-down.svg';
|
|
68
67
|
import arrowUp from '@phosphor-icons/core/regular/arrow-up.svg';
|
|
69
68
|
|
|
70
|
-
const libName="@khanacademy/perseus-editor";const libVersion="44.0.
|
|
69
|
+
const libName="@khanacademy/perseus-editor";const libVersion="44.0.3";addLibraryVersionToPerseusDebug(libName,libVersion);
|
|
71
70
|
|
|
72
71
|
var jsxRuntime = {exports: {}};
|
|
73
72
|
|
|
@@ -1557,7 +1556,7 @@ const{TextInput: TextInput$5}=components;class DefinitionEditor extends React.Co
|
|
|
1557
1556
|
|
|
1558
1557
|
class DeprecatedStandinEditor extends React.Component{serialize(){return EditorJsonify.serialize.call(this)}render(){return jsxRuntimeExports.jsxs("div",{children:[jsxRuntimeExports.jsx("p",{children:"This widget has been deprecated and removed"}),jsxRuntimeExports.jsx("p",{children:"Learners will see a message and they will not be graded on this part. Please replace this widget with a supported one."})]})}}
|
|
1559
1558
|
|
|
1560
|
-
class DropdownEditor extends React.Component{handleChange(changed){this.props.onChange({choices:this.props.choices,placeholder:this.props.placeholder,visibleLabel:this.props.visibleLabel,ariaLabel:this.props.ariaLabel,...changed});}onCorrectChange(choiceIndex){const choices=this.props.choices.map(function(choice,i){return _.extend({},choice,{correct:i===choiceIndex})});this.handleChange({choices:choices});}onContentChange(choiceIndex,newContent){const choices=this.props.choices.slice();const choice=_.clone(choices[choiceIndex]);choice.content=newContent;choices[choiceIndex]=choice;this.handleChange({choices:choices});}render(){const dropdownGroupName=_.uniqueId("perseus_dropdown_");const editingDisabled=this.props.apiOptions?.editingDisabled??false;return jsxRuntimeExports.jsxs("div",{className:"perseus-widget-dropdown",children:[jsxRuntimeExports.jsxs("div",{className:"dropdown-info",children:[jsxRuntimeExports.jsx(BodyText,{size:"medium",weight:"bold",tag:"span",children:"Dropdown"}),jsxRuntimeExports.jsx(InfoTip,{children:jsxRuntimeExports.jsxs("p",{children:["The drop down is useful for making inequalities in a custom format. We normally use the symbols ","<",","," ",">",', ≤, ≥ (in that order) which you can copy into the choices. When possible, use the "multiple choice" answer type instead.']})})]}),jsxRuntimeExports.jsxs("div",{className:"dropdown-field",children:[jsxRuntimeExports.jsxs(BodyText,{tag:"label",children:["Visible label",jsxRuntimeExports.jsx(TextField,{value:this.props.visibleLabel??"",onChange:visibleLabel=>this.handleChange({visibleLabel})})]}),jsxRuntimeExports.jsx(InfoTip,{children:jsxRuntimeExports.jsx("p",{children:"Optional visible label"})})]}),jsxRuntimeExports.jsxs("div",{className:"dropdown-field",children:[jsxRuntimeExports.jsxs(BodyText,{tag:"label",children:["Aria label",jsxRuntimeExports.jsx(TextField,{value:this.props.ariaLabel??"",onChange:ariaLabel=>this.handleChange({ariaLabel}),type:"text"})]}),jsxRuntimeExports.jsx(InfoTip,{children:jsxRuntimeExports.jsxs("p",{children:["Label text that's read by screen readers. Highly recommend adding a label here to ensure your exercise is accessible. For more information on writing accessible labels, please see"," ",jsxRuntimeExports.jsx("a",{href:"https://www.w3.org/WAI/tips/designing/#ensure-that-form-elements-include-clearly-associated-labels",target:"_blank",rel:"noreferrer",children:"this article."})," ",'If left blank, the value will default to "Select an answer".']})})]}),jsxRuntimeExports.jsxs("div",{className:"dropdown-field",children:[jsxRuntimeExports.jsxs(BodyText,{tag:"label",children:["Placeholder",jsxRuntimeExports.jsx(TextField,{value:this.props.placeholder,onChange:placeholder=>this.handleChange({placeholder}),placeholder:"Placeholder value"})]}),jsxRuntimeExports.jsx(InfoTip,{children:jsxRuntimeExports.jsx("p",{children:"This value will appear as the drop down default. It should give the user some indication of the values available in the drop down itself, e.g., Yes/No/Maybe."})})]}),jsxRuntimeExports.jsx("div",{className:"clearfix"}),jsxRuntimeExports.jsx(BodyText,{children:"Choices"}),jsxRuntimeExports.jsx("ul",{className:"dropdown-choices",children:this.props.choices.map((choice,i)=>{const choiceBackgroundColor=choice.correct?semanticColor.core.background.success.subtle:semanticColor.core.background.critical.subtle;return jsxRuntimeExports.jsx("li",{children:jsxRuntimeExports.jsxs("div",{className:"dropdown-choice",children:[jsxRuntimeExports.jsx("input",{type:"radio",name:dropdownGroupName,checked:choice.correct,onChange:()=>this.onCorrectChange(i)}),jsxRuntimeExports.jsx(TextField,{value:choice.content,"aria-label":`Choice ${i+1} content`,disabled:editingDisabled,style:{backgroundColor:choiceBackgroundColor},onChange:newContent=>this.onContentChange(i,newContent)}),jsxRuntimeExports.jsx(IconButton,{icon:trashIcon,"aria-label":"Delete choice",disabled:editingDisabled,kind:"tertiary",size:"small",onClick:()=>this.removeChoice(i)})]})},""+i)},this)}),jsxRuntimeExports.jsx("div",{className:"add-choice-container",children:jsxRuntimeExports.jsx(Button,{kind:"secondary",disabled:editingDisabled,onClick:this.addChoice,startIcon:plusIcon,children:"Add a choice"})})]})}constructor(...args){super(...args),this.addChoice=()=>{const choices=this.props.choices;const blankChoice={content:"",correct:false};this.handleChange({choices:choices.concat([blankChoice])});},this.removeChoice=choiceIndex=>{const choices=[...this.props.choices];choices.splice(choiceIndex,1);this.handleChange({choices});},this.serialize=()=>{return EditorJsonify.serialize.call(this)};}}DropdownEditor.
|
|
1559
|
+
class DropdownEditor extends React.Component{handleChange(changed){this.props.onChange({choices:this.props.choices,placeholder:this.props.placeholder,visibleLabel:this.props.visibleLabel,ariaLabel:this.props.ariaLabel,...changed});}onCorrectChange(choiceIndex){const choices=this.props.choices.map(function(choice,i){return _.extend({},choice,{correct:i===choiceIndex})});this.handleChange({choices:choices});}onContentChange(choiceIndex,newContent){const choices=this.props.choices.slice();const choice=_.clone(choices[choiceIndex]);choice.content=newContent;choices[choiceIndex]=choice;this.handleChange({choices:choices});}render(){const dropdownGroupName=_.uniqueId("perseus_dropdown_");const editingDisabled=this.props.apiOptions?.editingDisabled??false;return jsxRuntimeExports.jsxs("div",{className:"perseus-widget-dropdown",children:[jsxRuntimeExports.jsxs("div",{className:"dropdown-info",children:[jsxRuntimeExports.jsx(BodyText,{size:"medium",weight:"bold",tag:"span",children:"Dropdown"}),jsxRuntimeExports.jsx(InfoTip,{children:jsxRuntimeExports.jsxs("p",{children:["The drop down is useful for making inequalities in a custom format. We normally use the symbols ","<",","," ",">",', ≤, ≥ (in that order) which you can copy into the choices. When possible, use the "multiple choice" answer type instead.']})})]}),jsxRuntimeExports.jsxs("div",{className:"dropdown-field",children:[jsxRuntimeExports.jsxs(BodyText,{tag:"label",children:["Visible label",jsxRuntimeExports.jsx(TextField,{value:this.props.visibleLabel??"",onChange:visibleLabel=>this.handleChange({visibleLabel})})]}),jsxRuntimeExports.jsx(InfoTip,{children:jsxRuntimeExports.jsx("p",{children:"Optional visible label"})})]}),jsxRuntimeExports.jsxs("div",{className:"dropdown-field",children:[jsxRuntimeExports.jsxs(BodyText,{tag:"label",children:["Aria label",jsxRuntimeExports.jsx(TextField,{value:this.props.ariaLabel??"",onChange:ariaLabel=>this.handleChange({ariaLabel}),type:"text"})]}),jsxRuntimeExports.jsx(InfoTip,{children:jsxRuntimeExports.jsxs("p",{children:["Label text that's read by screen readers. Highly recommend adding a label here to ensure your exercise is accessible. For more information on writing accessible labels, please see"," ",jsxRuntimeExports.jsx("a",{href:"https://www.w3.org/WAI/tips/designing/#ensure-that-form-elements-include-clearly-associated-labels",target:"_blank",rel:"noreferrer",children:"this article."})," ",'If left blank, the value will default to "Select an answer".']})})]}),jsxRuntimeExports.jsxs("div",{className:"dropdown-field",children:[jsxRuntimeExports.jsxs(BodyText,{tag:"label",children:["Placeholder",jsxRuntimeExports.jsx(TextField,{value:this.props.placeholder,onChange:placeholder=>this.handleChange({placeholder}),placeholder:"Placeholder value"})]}),jsxRuntimeExports.jsx(InfoTip,{children:jsxRuntimeExports.jsx("p",{children:"This value will appear as the drop down default. It should give the user some indication of the values available in the drop down itself, e.g., Yes/No/Maybe."})})]}),jsxRuntimeExports.jsx("div",{className:"clearfix"}),jsxRuntimeExports.jsx(BodyText,{children:"Choices"}),jsxRuntimeExports.jsx("ul",{className:"dropdown-choices",children:this.props.choices.map((choice,i)=>{const choiceBackgroundColor=choice.correct?semanticColor.core.background.success.subtle:semanticColor.core.background.critical.subtle;return jsxRuntimeExports.jsx("li",{children:jsxRuntimeExports.jsxs("div",{className:"dropdown-choice",children:[jsxRuntimeExports.jsx("input",{type:"radio",name:dropdownGroupName,checked:choice.correct,onChange:()=>this.onCorrectChange(i)}),jsxRuntimeExports.jsx(TextField,{value:choice.content,"aria-label":`Choice ${i+1} content`,disabled:editingDisabled,style:{backgroundColor:choiceBackgroundColor},onChange:newContent=>this.onContentChange(i,newContent)}),jsxRuntimeExports.jsx(IconButton,{icon:trashIcon,"aria-label":"Delete choice",disabled:editingDisabled,kind:"tertiary",size:"small",onClick:()=>this.removeChoice(i)})]})},""+i)},this)}),jsxRuntimeExports.jsx("div",{className:"add-choice-container",children:jsxRuntimeExports.jsx(Button,{kind:"secondary",disabled:editingDisabled,onClick:this.addChoice,startIcon:plusIcon,children:"Add a choice"})})]})}constructor(...args){super(...args),this.addChoice=()=>{const choices=this.props.choices;const blankChoice={content:"",correct:false};this.handleChange({choices:choices.concat([blankChoice])});},this.removeChoice=choiceIndex=>{const choices=[...this.props.choices];choices.splice(choiceIndex,1);this.handleChange({choices});},this.serialize=()=>{return EditorJsonify.serialize.call(this)};}}DropdownEditor.defaultProps=dropdownLogic.defaultWidgetOptions;
|
|
1561
1560
|
|
|
1562
1561
|
const{TextInput: TextInput$4}=components;class ExplanationEditor extends React.Component{handleChange(changes){this.props.onChange({showPrompt:this.props.showPrompt,hidePrompt:this.props.hidePrompt,explanation:this.props.explanation,widgets:this.props.widgets,...changes});}render(){return jsxRuntimeExports.jsxs("div",{className:"perseus-widget-explanation-editor",children:[jsxRuntimeExports.jsx("div",{className:"perseus-widget-row",children:jsxRuntimeExports.jsxs("label",{children:["Prompt to show explanation:"," ",jsxRuntimeExports.jsx(TextInput$4,{value:this.props.showPrompt,onChange:showPrompt=>this.handleChange({showPrompt})})]})}),jsxRuntimeExports.jsx("div",{className:"perseus-widget-row",children:jsxRuntimeExports.jsxs("label",{children:["Prompt to hide explanation:"," ",jsxRuntimeExports.jsx(TextInput$4,{value:this.props.hidePrompt,onChange:hidePrompt=>this.handleChange({hidePrompt})})]})}),jsxRuntimeExports.jsx("div",{className:"perseus-widget-row",children:jsxRuntimeExports.jsx(Editor,{apiOptions:this.props.apiOptions,content:this.props.explanation,widgets:this.props.widgets,widgetEnabled:true,onChange:props=>{const newProps={};if(_.has(props,"content")){newProps.explanation=props.content;}if(_.has(props,"widgets")){newProps.widgets=props.widgets;}this.handleChange(newProps);}})})]})}constructor(...args){super(...args),this.serialize=()=>{return EditorJsonify.serialize.call(this)};}}ExplanationEditor.defaultProps=explanationLogic.defaultWidgetOptions;
|
|
1563
1562
|
|
|
@@ -1628,27 +1627,27 @@ const{ButtonGroup: ButtonGroup$4}=components;class DashPicker extends React.Comp
|
|
|
1628
1627
|
|
|
1629
1628
|
function MathquillInput(props){const mathFieldWrapperRef=useRef(null);const mathFieldInstance=useRef();const{locale,strings}=useMathInputI18n();useEffect(()=>{if(mathFieldWrapperRef.current&&!mathFieldInstance.current){mathFieldInstance.current=createMathField(mathFieldWrapperRef.current,locale,strings,baseConfig=>({...baseConfig,handlers:{edit:mathField=>{let value=mathField.latex();value=value.replace(/<>/g,"\\ne");if(props.value!==value){props.onChange(value);}},upOutOf:mathField=>{mathField.typedText("^");}}}));}});return jsxRuntimeExports.jsx(View,{style:styles$F.outerWrapper,children:jsxRuntimeExports.jsx("span",{ref:mathFieldWrapperRef,className:"perseus-math-input mq-editable-field mq-math-mode"})})}const styles$F=StyleSheet.create({outerWrapper:{display:"inline-block",borderStyle:"solid",borderWidth:1,borderColor:semanticColor.core.border.neutral.default,borderRadius:3,background:semanticColor.core.background.base.default}});
|
|
1630
1629
|
|
|
1631
|
-
const{NumberInput: NumberInput$a}=components;class FunctionEditor extends React.Component{render(){const{TeX}=Dependencies.getDependencies();return jsxRuntimeExports.jsxs("div",{className:"graph-settings",children:[jsxRuntimeExports.jsxs("div",{className:"perseus-widget-row",children:[jsxRuntimeExports.jsx(TeX,{children:this.props.funcName+"(x)="})," ",jsxRuntimeExports.jsx(MathquillInput,{value:this.props.value,onChange:this.
|
|
1630
|
+
const{NumberInput: NumberInput$a}=components;class FunctionEditor extends React.Component{handleChange(changes){this.props.onChange({value:this.props.value,funcName:this.props.funcName,rangeMin:this.props.rangeMin,rangeMax:this.props.rangeMax,color:this.props.color,strokeDasharray:this.props.strokeDasharray,strokeWidth:this.props.strokeWidth,...changes});}render(){const{TeX}=Dependencies.getDependencies();return jsxRuntimeExports.jsxs("div",{className:"graph-settings",children:[jsxRuntimeExports.jsxs("div",{className:"perseus-widget-row",children:[jsxRuntimeExports.jsx(TeX,{children:this.props.funcName+"(x)="})," ",jsxRuntimeExports.jsx(MathquillInput,{value:this.props.value,onChange:value=>this.handleChange({value})})]}),jsxRuntimeExports.jsxs("div",{className:"perseus-widget-row",children:["Range: ",jsxRuntimeExports.jsx(TeX,{children:"\\Large("}),jsxRuntimeExports.jsx(MathquillInput,{value:this.props.rangeMin,onChange:rangeMin=>this.handleChange({rangeMin})}),jsxRuntimeExports.jsx(TeX,{children:","})," ",jsxRuntimeExports.jsx(MathquillInput,{value:this.props.rangeMax,onChange:rangeMax=>this.handleChange({rangeMax})}),jsxRuntimeExports.jsx(TeX,{children:"\\Large)"})]}),jsxRuntimeExports.jsx("div",{className:"perseus-widget-row",children:jsxRuntimeExports.jsx(ColorPicker,{value:this.props.color,onChange:color=>this.handleChange({color})})}),jsxRuntimeExports.jsx("div",{className:"perseus-widget-row",children:jsxRuntimeExports.jsx(DashPicker,{value:this.props.strokeDasharray,onChange:strokeDasharray=>this.handleChange({strokeDasharray})})}),jsxRuntimeExports.jsx("div",{className:"perseus-widget-row",children:jsxRuntimeExports.jsxs("div",{className:"perseus-widget-left-col",children:["Width:"," ",jsxRuntimeExports.jsx(NumberInput$a,{value:this.props.strokeWidth,placeholder:2,onChange:strokeWidth=>this.handleChange({strokeWidth})})]})})]})}}FunctionEditor.defaultProps={value:"x",funcName:"f",rangeMin:"-10",rangeMax:"10",color:KhanColors.BLUE,strokeDasharray:"",strokeWidth:2};
|
|
1632
1631
|
|
|
1633
|
-
const{TextInput: TextInput$1}=components;class LabelEditor extends React.Component{render(){const{TeX}=Dependencies.getDependencies();return jsxRuntimeExports.jsxs("div",{className:"graph-settings",children:[jsxRuntimeExports.jsx("div",{className:"perseus-widget-row",children:jsxRuntimeExports.jsx(TextInput$1,{value:this.props.label,onChange:this.
|
|
1632
|
+
const{TextInput: TextInput$1}=components;class LabelEditor extends React.Component{handleChange(changes){this.props.onChange({label:this.props.label,color:this.props.color,coordX:this.props.coordX,coordY:this.props.coordY,...changes});}render(){const{TeX}=Dependencies.getDependencies();return jsxRuntimeExports.jsxs("div",{className:"graph-settings",children:[jsxRuntimeExports.jsx("div",{className:"perseus-widget-row",children:jsxRuntimeExports.jsx(TextInput$1,{value:this.props.label,onChange:label=>this.handleChange({label}),style:{width:"100%"}})}),jsxRuntimeExports.jsxs("div",{className:"perseus-widget-row",children:["Location: ",jsxRuntimeExports.jsx(TeX,{children:"\\Large("}),jsxRuntimeExports.jsx(MathquillInput,{value:this.props.coordX,onChange:coordX=>this.handleChange({coordX})}),jsxRuntimeExports.jsx(TeX,{children:","})," ",jsxRuntimeExports.jsx(MathquillInput,{value:this.props.coordY,onChange:coordY=>this.handleChange({coordY})}),jsxRuntimeExports.jsx(TeX,{children:"\\Large)"})]}),jsxRuntimeExports.jsx("div",{className:"perseus-widget-row",children:jsxRuntimeExports.jsx(ColorPicker,{value:this.props.color,onChange:color=>this.handleChange({color})})})]})}}LabelEditor.defaultProps={coordX:"0",coordY:"0",color:KhanColors.BLACK,label:"\\phi"};
|
|
1634
1633
|
|
|
1635
1634
|
const{ButtonGroup: ButtonGroup$3}=components;class ArrowPicker extends React.Component{render(){return jsxRuntimeExports.jsx(ButtonGroup$3,{value:this.props.value,buttons:[{value:"",content:jsxRuntimeExports.jsx("span",{children:"—"})},{value:"->",content:jsxRuntimeExports.jsx("span",{children:"→"})}],onChange:this.props.onChange})}}ArrowPicker.defaultProps={value:""};
|
|
1636
1635
|
|
|
1637
|
-
const{NumberInput: NumberInput$9}=components;class LineEditor extends React.Component{render(){const{TeX}=Dependencies.getDependencies();return jsxRuntimeExports.jsxs("div",{className:"graph-settings",children:[jsxRuntimeExports.jsxs("div",{className:"perseus-widget-row",children:["Start: ",jsxRuntimeExports.jsx(TeX,{children:"\\Large("}),jsxRuntimeExports.jsx(MathquillInput,{value:this.props.startX,onChange:this.change("startX")}),jsxRuntimeExports.jsx(TeX,{children:","})," ",jsxRuntimeExports.jsx(MathquillInput,{value:this.props.startY,onChange:this.change("startY")}),jsxRuntimeExports.jsx(TeX,{children:"\\Large)"})]}),jsxRuntimeExports.jsxs("div",{className:"perseus-widget-row",children:["End: ",jsxRuntimeExports.jsx(TeX,{children:"\\Large("}),jsxRuntimeExports.jsx(MathquillInput,{value:this.props.endX,onChange:this.change("endX")}),jsxRuntimeExports.jsx(TeX,{children:","})," ",jsxRuntimeExports.jsx(MathquillInput,{value:this.props.endY,onChange:this.change("endY")}),jsxRuntimeExports.jsx(TeX,{children:"\\Large)"})]}),jsxRuntimeExports.jsx("div",{className:"perseus-widget-row",children:jsxRuntimeExports.jsx(ColorPicker,{value:this.props.color,onChange:this.change("color")})}),jsxRuntimeExports.jsxs("div",{className:"perseus-widget-row",children:[jsxRuntimeExports.jsx(DashPicker,{value:this.props.strokeDasharray,onChange:this.change("strokeDasharray")})," ",jsxRuntimeExports.jsx(ArrowPicker,{value:this.props.arrows,onChange:this.change("arrows")})]}),jsxRuntimeExports.jsx("div",{className:"perseus-widget-row",children:jsxRuntimeExports.jsxs("div",{className:"perseus-widget-left-col",children:["Width:"," ",jsxRuntimeExports.jsx(NumberInput$9,{value:this.props.strokeWidth,placeholder:2,onChange:this.change("strokeWidth")})]})})]})}constructor(...args){super(...args),this.change=(...args)=>{return deprecatedChangeableChange.apply(this,args)};}}LineEditor.defaultProps={startX:"-5",startY:"5",endX:"5",endY:"5",color:KhanColors.BLACK,strokeDasharray:"",arrows:"",strokeWidth:2};
|
|
1636
|
+
const{NumberInput: NumberInput$9}=components;class LineEditor extends React.Component{handleChange(changes){this.props.onChange({startX:this.props.startX,startY:this.props.startY,endX:this.props.endX,endY:this.props.endY,color:this.props.color,strokeDasharray:this.props.strokeDasharray,arrows:this.props.arrows,strokeWidth:this.props.strokeWidth,...changes});}render(){const{TeX}=Dependencies.getDependencies();return jsxRuntimeExports.jsxs("div",{className:"graph-settings",children:[jsxRuntimeExports.jsxs("div",{className:"perseus-widget-row",children:["Start: ",jsxRuntimeExports.jsx(TeX,{children:"\\Large("}),jsxRuntimeExports.jsx(MathquillInput,{value:this.props.startX,onChange:this.change("startX")}),jsxRuntimeExports.jsx(TeX,{children:","})," ",jsxRuntimeExports.jsx(MathquillInput,{value:this.props.startY,onChange:this.change("startY")}),jsxRuntimeExports.jsx(TeX,{children:"\\Large)"})]}),jsxRuntimeExports.jsxs("div",{className:"perseus-widget-row",children:["End: ",jsxRuntimeExports.jsx(TeX,{children:"\\Large("}),jsxRuntimeExports.jsx(MathquillInput,{value:this.props.endX,onChange:this.change("endX")}),jsxRuntimeExports.jsx(TeX,{children:","})," ",jsxRuntimeExports.jsx(MathquillInput,{value:this.props.endY,onChange:this.change("endY")}),jsxRuntimeExports.jsx(TeX,{children:"\\Large)"})]}),jsxRuntimeExports.jsx("div",{className:"perseus-widget-row",children:jsxRuntimeExports.jsx(ColorPicker,{value:this.props.color,onChange:this.change("color")})}),jsxRuntimeExports.jsxs("div",{className:"perseus-widget-row",children:[jsxRuntimeExports.jsx(DashPicker,{value:this.props.strokeDasharray,onChange:this.change("strokeDasharray")})," ",jsxRuntimeExports.jsx(ArrowPicker,{value:this.props.arrows,onChange:this.change("arrows")})]}),jsxRuntimeExports.jsx("div",{className:"perseus-widget-row",children:jsxRuntimeExports.jsxs("div",{className:"perseus-widget-left-col",children:["Width:"," ",jsxRuntimeExports.jsx(NumberInput$9,{value:this.props.strokeWidth,placeholder:2,onChange:this.change("strokeWidth")})]})})]})}constructor(...args){super(...args),this.change=(...args)=>{return deprecatedChangeableChange.apply(this,args)};}}LineEditor.defaultProps={startX:"-5",startY:"5",endX:"5",endY:"5",color:KhanColors.BLACK,strokeDasharray:"",arrows:"",strokeWidth:2};
|
|
1638
1637
|
|
|
1639
|
-
const{ButtonGroup: ButtonGroup$2,NumberInput: NumberInput$8}=components;class ConstraintEditor extends React.Component{render(){const{TeX}=Dependencies.getDependencies();return jsxRuntimeExports.jsxs("div",{children:[jsxRuntimeExports.jsxs("div",{className:"perseus-widget-row",children:["Constraint:"," ",jsxRuntimeExports.jsx(ButtonGroup$2,{value:this.props.constraint,buttons:[{value:"none",content:"None"},{value:"snap",content:"Snap"},{value:"x",content:"x="},{value:"y",content:"y="}],onChange:this.
|
|
1638
|
+
const{ButtonGroup: ButtonGroup$2,NumberInput: NumberInput$8}=components;class ConstraintEditor extends React.Component{handleChange(changes){this.props.onChange({constraint:this.props.constraint,constraintFn:this.props.constraintFn,constraintXMax:this.props.constraintXMax,constraintXMin:this.props.constraintXMin,constraintYMax:this.props.constraintYMax,constraintYMin:this.props.constraintYMin,snap:this.props.snap,...changes});}render(){const{TeX}=Dependencies.getDependencies();return jsxRuntimeExports.jsxs("div",{children:[jsxRuntimeExports.jsxs("div",{className:"perseus-widget-row",children:["Constraint:"," ",jsxRuntimeExports.jsx(ButtonGroup$2,{value:this.props.constraint,buttons:[{value:"none",content:"None"},{value:"snap",content:"Snap"},{value:"x",content:"x="},{value:"y",content:"y="}],onChange:constraint=>this.handleChange({constraint})})]}),this.props.constraint==="snap"&&jsxRuntimeExports.jsxs("div",{className:"perseus-widget-row",children:["Snap:"," ",jsxRuntimeExports.jsx(NumberInput$8,{value:this.props.snap,placeholder:0,onChange:snap=>this.handleChange({snap})})]}),this.props.constraint==="x"&&jsxRuntimeExports.jsx("div",{className:"graph-settings",children:jsxRuntimeExports.jsxs("div",{className:"perseus-widget-row",children:[jsxRuntimeExports.jsx(TeX,{children:"x="})," ",jsxRuntimeExports.jsx(MathquillInput,{value:this.props.constraintFn,onChange:constraintFn=>this.handleChange({constraintFn})})]})}),this.props.constraint==="y"&&jsxRuntimeExports.jsx("div",{className:"graph-settings",children:jsxRuntimeExports.jsxs("div",{className:"perseus-widget-row",children:[jsxRuntimeExports.jsx(TeX,{children:"y="})," ",jsxRuntimeExports.jsx(MathquillInput,{value:this.props.constraintFn,onChange:constraintFn=>this.handleChange({constraintFn})})]})}),"Ensure these are set so nothing can be dragged off the canvas:",jsxRuntimeExports.jsx("div",{className:"perseus-widget-row",children:jsxRuntimeExports.jsxs("div",{className:"perseus-widget-row",children:[jsxRuntimeExports.jsx(TeX,{children:"x \\in \\Large["})," ",jsxRuntimeExports.jsx(MathquillInput,{value:this.props.constraintXMin,onChange:constraintXMin=>this.handleChange({constraintXMin})}),jsxRuntimeExports.jsx(TeX,{children:", "})," ",jsxRuntimeExports.jsx(MathquillInput,{value:this.props.constraintXMax,onChange:constraintXMax=>this.handleChange({constraintXMax})})," ",jsxRuntimeExports.jsx(TeX,{children:"\\Large]"})]})}),jsxRuntimeExports.jsx("div",{className:"perseus-widget-row",children:jsxRuntimeExports.jsxs("div",{className:"perseus-widget-row",children:[jsxRuntimeExports.jsx(TeX,{children:"y \\in \\Large["})," ",jsxRuntimeExports.jsx(MathquillInput,{value:this.props.constraintYMin,onChange:constraintYMin=>this.handleChange({constraintYMin})}),jsxRuntimeExports.jsx(TeX,{children:", "})," ",jsxRuntimeExports.jsx(MathquillInput,{value:this.props.constraintYMax,onChange:constraintYMax=>this.handleChange({constraintYMax})})," ",jsxRuntimeExports.jsx(TeX,{children:"\\Large]"})]})})]})}}ConstraintEditor.defaultProps={constraint:"none",snap:.5,constraintFn:"0",constraintXMin:"-10",constraintXMax:"10",constraintYMin:"-10",constraintYMax:"10"};
|
|
1640
1639
|
|
|
1641
|
-
const{NumberInput: NumberInput$7}=components;class MovableLineEditor extends React.Component{render(){const{TeX}=Dependencies.getDependencies();return jsxRuntimeExports.jsxs("div",{className:"graph-settings",children:["Initial position:",jsxRuntimeExports.jsxs("div",{className:"perseus-widget-row",children:["Start: ",jsxRuntimeExports.jsx(TeX,{children:"\\Large("}),jsxRuntimeExports.jsx(MathquillInput,{value:this.props.startX,onChange:this.
|
|
1640
|
+
const{NumberInput: NumberInput$7}=components;class MovableLineEditor extends React.Component{handleChange(changes){this.props.onChange({startX:this.props.startX,startY:this.props.startY,endX:this.props.endX,endY:this.props.endY,constraint:this.props.constraint,snap:this.props.snap,constraintFn:this.props.constraintFn,constraintXMin:this.props.constraintXMin,constraintXMax:this.props.constraintXMax,constraintYMin:this.props.constraintYMin,constraintYMax:this.props.constraintYMax,startSubscript:this.props.startSubscript,endSubscript:this.props.endSubscript,...changes});}render(){const{TeX}=Dependencies.getDependencies();return jsxRuntimeExports.jsxs("div",{className:"graph-settings",children:["Initial position:",jsxRuntimeExports.jsxs("div",{className:"perseus-widget-row",children:["Start: ",jsxRuntimeExports.jsx(TeX,{children:"\\Large("}),jsxRuntimeExports.jsx(MathquillInput,{value:this.props.startX,onChange:startX=>this.handleChange({startX})}),jsxRuntimeExports.jsx(TeX,{children:","})," ",jsxRuntimeExports.jsx(MathquillInput,{value:this.props.startY,onChange:startY=>this.handleChange({startY})}),jsxRuntimeExports.jsx(TeX,{children:"\\Large)"})]}),jsxRuntimeExports.jsxs("div",{className:"perseus-widget-row",children:["End: ",jsxRuntimeExports.jsx(TeX,{children:"\\Large("}),jsxRuntimeExports.jsx(MathquillInput,{value:this.props.endX,onChange:endX=>this.handleChange({endX})}),jsxRuntimeExports.jsx(TeX,{children:","})," ",jsxRuntimeExports.jsx(MathquillInput,{value:this.props.endY,onChange:endY=>this.handleChange({endY})}),jsxRuntimeExports.jsx(TeX,{children:"\\Large)"})]}),jsxRuntimeExports.jsxs("div",{className:"perseus-widget-row",children:["Start updates ",jsxRuntimeExports.jsx(TeX,{children:"(x_n, y_n)"})," for ",jsxRuntimeExports.jsx(TeX,{children:"n ="}),jsxRuntimeExports.jsx(NumberInput$7,{value:this.props.startSubscript,placeholder:0,onChange:startSubscript=>this.handleChange({startSubscript})})]}),jsxRuntimeExports.jsxs("div",{className:"perseus-widget-row",children:["End updates ",jsxRuntimeExports.jsx(TeX,{children:"(x_m, y_m)"})," for ",jsxRuntimeExports.jsx(TeX,{children:"m ="}),jsxRuntimeExports.jsx(NumberInput$7,{value:this.props.endSubscript,placeholder:0,onChange:endSubscript=>this.handleChange({endSubscript})})]}),jsxRuntimeExports.jsx("div",{className:"perseus-widget-row",children:"All constraints are applied to the start point."}),jsxRuntimeExports.jsx(ConstraintEditor,{...this.props,onChange:constraint=>this.handleChange(constraint)})]})}}MovableLineEditor.defaultProps={startX:"-5",startY:"5",endX:"5",endY:"5",constraint:"none",snap:.5,constraintFn:"0",constraintXMin:"-10",constraintXMax:"10",constraintYMin:"-10",constraintYMax:"10",startSubscript:0,endSubscript:0};
|
|
1642
1641
|
|
|
1643
|
-
const{NumberInput: NumberInput$6}=components;class MovablePointEditor extends React.Component{render(){const{TeX}=Dependencies.getDependencies();return jsxRuntimeExports.jsxs("div",{className:"graph-settings",children:[jsxRuntimeExports.jsxs("div",{className:"perseus-widget-row",children:["Start: ",jsxRuntimeExports.jsx(TeX,{children:"\\Large("}),jsxRuntimeExports.jsx(MathquillInput,{value:this.props.startX,onChange:this.
|
|
1642
|
+
const{NumberInput: NumberInput$6}=components;class MovablePointEditor extends React.Component{handleChange(options){this.props.onChange({startX:this.props.startX,startY:this.props.startY,constraint:this.props.constraint,snap:this.props.snap,constraintFn:this.props.constraintFn,constraintXMin:this.props.constraintXMin,constraintXMax:this.props.constraintXMax,constraintYMin:this.props.constraintYMin,constraintYMax:this.props.constraintYMax,varSubscript:this.props.varSubscript,...options});}render(){const{TeX}=Dependencies.getDependencies();return jsxRuntimeExports.jsxs("div",{className:"graph-settings",children:[jsxRuntimeExports.jsxs("div",{className:"perseus-widget-row",children:["Start: ",jsxRuntimeExports.jsx(TeX,{children:"\\Large("}),jsxRuntimeExports.jsx(MathquillInput,{value:this.props.startX,onChange:startX=>this.handleChange({startX})}),jsxRuntimeExports.jsx(TeX,{children:","})," ",jsxRuntimeExports.jsx(MathquillInput,{value:this.props.startY,onChange:startY=>this.handleChange({startY})}),jsxRuntimeExports.jsx(TeX,{children:"\\Large)"})]}),jsxRuntimeExports.jsxs("div",{className:"perseus-widget-row",children:["Update ",jsxRuntimeExports.jsx(TeX,{children:"(x_n, y_n)"})," for ",jsxRuntimeExports.jsx(TeX,{children:"n ="})," ",jsxRuntimeExports.jsx(NumberInput$6,{value:this.props.varSubscript,placeholder:0,onChange:varSubscript=>this.handleChange({varSubscript})})]}),jsxRuntimeExports.jsx(ConstraintEditor,{...this.props,onChange:constraint=>this.handleChange(constraint)})]})}}MovablePointEditor.defaultProps={startX:"0",startY:"0",constraint:"none",snap:.5,constraintFn:"0",constraintXMin:"-10",constraintXMax:"10",constraintYMin:"-10",constraintYMax:"10",varSubscript:0};
|
|
1644
1643
|
|
|
1645
|
-
const{NumberInput: NumberInput$5}=components;class ParametricEditor extends React.Component{render(){const{TeX}=Dependencies.getDependencies();return jsxRuntimeExports.jsxs("div",{className:"graph-settings",children:[jsxRuntimeExports.jsxs("div",{className:"perseus-widget-row",children:[jsxRuntimeExports.jsx(TeX,{children:"X(t) ="})," ",jsxRuntimeExports.jsx(MathquillInput,{value:this.props.x,onChange:this.
|
|
1644
|
+
const{NumberInput: NumberInput$5}=components;class ParametricEditor extends React.Component{handleChange(changes){this.props.onChange({x:this.props.x,y:this.props.y,rangeMin:this.props.rangeMin,rangeMax:this.props.rangeMax,color:this.props.color,strokeDasharray:this.props.strokeDasharray,strokeWidth:this.props.strokeWidth,...changes});}render(){const{TeX}=Dependencies.getDependencies();return jsxRuntimeExports.jsxs("div",{className:"graph-settings",children:[jsxRuntimeExports.jsxs("div",{className:"perseus-widget-row",children:[jsxRuntimeExports.jsx(TeX,{children:"X(t) ="})," ",jsxRuntimeExports.jsx(MathquillInput,{value:this.props.x,onChange:x=>this.handleChange({x})})]}),jsxRuntimeExports.jsxs("div",{className:"perseus-widget-row",children:[jsxRuntimeExports.jsx(TeX,{children:"Y(t) ="})," ",jsxRuntimeExports.jsx(MathquillInput,{value:this.props.y,onChange:y=>this.handleChange({y})})]}),jsxRuntimeExports.jsxs("div",{className:"perseus-widget-row",children:["Range: ",jsxRuntimeExports.jsx(TeX,{children:"\\Large("}),jsxRuntimeExports.jsx(MathquillInput,{value:this.props.rangeMin,onChange:rangeMin=>this.handleChange({rangeMin})}),jsxRuntimeExports.jsx(TeX,{children:","})," ",jsxRuntimeExports.jsx(MathquillInput,{value:this.props.rangeMax,onChange:rangeMax=>this.handleChange({rangeMax})}),jsxRuntimeExports.jsx(TeX,{children:"\\Large)"})]}),jsxRuntimeExports.jsx("div",{className:"perseus-widget-row",children:jsxRuntimeExports.jsx(ColorPicker,{value:this.props.color,onChange:color=>this.handleChange({color})})}),jsxRuntimeExports.jsx("div",{className:"perseus-widget-row",children:jsxRuntimeExports.jsx(DashPicker,{value:this.props.strokeDasharray,onChange:strokeDasharray=>this.handleChange({strokeDasharray})})}),jsxRuntimeExports.jsx("div",{className:"perseus-widget-row",children:jsxRuntimeExports.jsxs("div",{className:"perseus-widget-left-col",children:["Width:"," ",jsxRuntimeExports.jsx(NumberInput$5,{value:this.props.strokeWidth,placeholder:2,onChange:strokeWidth=>this.handleChange({strokeWidth})})]})})]})}}ParametricEditor.defaultProps={x:"cos(t)",y:"sin(t)",rangeMin:"0",rangeMax:"2\\pi",color:KhanColors.BLUE,strokeDasharray:"",strokeWidth:2};
|
|
1646
1645
|
|
|
1647
|
-
class PointEditor extends React.Component{render(){const{TeX}=Dependencies.getDependencies();return jsxRuntimeExports.jsxs("div",{className:"graph-settings",children:[jsxRuntimeExports.jsxs("div",{className:"perseus-widget-row",children:["Coordinate: ",jsxRuntimeExports.jsx(TeX,{children:"\\Large("}),jsxRuntimeExports.jsx(MathquillInput,{value:this.props.coordX,onChange:this.
|
|
1646
|
+
class PointEditor extends React.Component{handleChange(changes){this.props.onChange({coordX:this.props.coordX,coordY:this.props.coordY,color:this.props.color,...changes});}render(){const{TeX}=Dependencies.getDependencies();return jsxRuntimeExports.jsxs("div",{className:"graph-settings",children:[jsxRuntimeExports.jsxs("div",{className:"perseus-widget-row",children:["Coordinate: ",jsxRuntimeExports.jsx(TeX,{children:"\\Large("}),jsxRuntimeExports.jsx(MathquillInput,{value:this.props.coordX,onChange:coordX=>this.handleChange({coordX})}),jsxRuntimeExports.jsx(TeX,{children:","})," ",jsxRuntimeExports.jsx(MathquillInput,{value:this.props.coordY,onChange:coordY=>this.handleChange({coordY})}),jsxRuntimeExports.jsx(TeX,{children:"\\Large)"})]}),jsxRuntimeExports.jsx("div",{className:"perseus-widget-row",children:jsxRuntimeExports.jsx(ColorPicker,{value:this.props.color,onChange:color=>this.handleChange({color})})})]})}}PointEditor.defaultProps={coordX:"0",coordY:"0",color:KhanColors.BLACK};
|
|
1648
1647
|
|
|
1649
|
-
class RectangleEditor extends React.Component{render(){const{TeX}=Dependencies.getDependencies();return jsxRuntimeExports.jsxs("div",{className:"graph-settings",children:[jsxRuntimeExports.jsxs("div",{className:"perseus-widget-row",children:["Bottom left: ",jsxRuntimeExports.jsx(TeX,{children:"\\Large("}),jsxRuntimeExports.jsx(MathquillInput,{value:this.props.coordX,onChange:this.
|
|
1648
|
+
class RectangleEditor extends React.Component{handleChange(changes){this.props.onChange({coordX:this.props.coordX,coordY:this.props.coordY,width:this.props.width,height:this.props.height,color:this.props.color,...changes});}render(){const{TeX}=Dependencies.getDependencies();return jsxRuntimeExports.jsxs("div",{className:"graph-settings",children:[jsxRuntimeExports.jsxs("div",{className:"perseus-widget-row",children:["Bottom left: ",jsxRuntimeExports.jsx(TeX,{children:"\\Large("}),jsxRuntimeExports.jsx(MathquillInput,{value:this.props.coordX,onChange:coordX=>this.handleChange({coordX})}),jsxRuntimeExports.jsx(TeX,{children:","})," ",jsxRuntimeExports.jsx(MathquillInput,{value:this.props.coordY,onChange:coordY=>this.handleChange({coordY})}),jsxRuntimeExports.jsx(TeX,{children:"\\Large)"})]}),jsxRuntimeExports.jsxs("div",{className:"perseus-widget-row",children:["Width:"," ",jsxRuntimeExports.jsx(MathquillInput,{value:this.props.width,onChange:width=>this.handleChange({width})})]}),jsxRuntimeExports.jsxs("div",{className:"perseus-widget-row",children:["Height:"," ",jsxRuntimeExports.jsx(MathquillInput,{value:this.props.height,onChange:height=>this.handleChange({height})})]}),jsxRuntimeExports.jsx("div",{className:"perseus-widget-row",children:jsxRuntimeExports.jsx(ColorPicker,{value:this.props.color,lightColors:true,onChange:color=>this.handleChange({color})})}),jsxRuntimeExports.jsx("div",{className:"perseus-widget-row",children:"You want a border? Sorry, draw your own."})]})}}RectangleEditor.defaultProps={coordX:"-5",coordY:"5",width:"2",height:"3",color:KhanColors.LIGHT_BLUE};
|
|
1650
1649
|
|
|
1651
|
-
const{unescapeMathMode}=Util;const defaultOptionsByElementType={point:PointEditor.defaultProps,line:LineEditor.defaultProps,"movable-point":MovablePointEditor.defaultProps,"movable-line":MovableLineEditor.defaultProps,function:FunctionEditor.defaultProps,parametric:ParametricEditor.defaultProps,label:LabelEditor.defaultProps,rectangle:RectangleEditor.defaultProps};class InteractionEditor extends React.Component{UNSAFE_componentWillReceiveProps(nextProps){this.setState({usedVarSubscripts:this._getAllVarSubscripts(nextProps.elements),usedFunctionNames:this._getAllFunctionNames(nextProps.elements)});}_getAllVarSubscripts(elements){const movableLines=elements.filter(element=>element.type==="movable-line");return elements.filter(element=>element.type==="movable-point").map(element=>element.options.varSubscript).concat(movableLines.map(element=>element.options.startSubscript)).concat(movableLines.map(element=>element.options.endSubscript))}_getAllFunctionNames(elements){return elements.filter(element=>element.type==="function").map(element=>element.options.funcName)}render(){const{TeX}=Dependencies.getDependencies();return jsxRuntimeExports.jsxs("div",{className:"perseus-widget-interaction-editor",children:[jsxRuntimeExports.jsxs(ElementContainer,{title:"Grid settings",children:[jsxRuntimeExports.jsx(GraphSettings,{editableSettings:["canvas","graph"],box:this.props.graph.box,labels:this.props.graph.labels,range:this.props.graph.range,step:this.props.graph.tickStep,gridStep:this.props.graph.gridStep,markings:this.props.graph.markings,onChange:this._updateGraphProps}),jsxRuntimeExports.jsx(jsxRuntimeExports.Fragment,{children:this.props.graph.valid!==true&&jsxRuntimeExports.jsx("div",{children:this.props.graph.valid})})]}),this.props.elements.map((element,n)=>{if(element.type==="movable-point"){return jsxRuntimeExports.jsx(ElementContainer,{title:jsxRuntimeExports.jsxs("span",{children:["Movable point"," ",jsxRuntimeExports.jsx(TeX,{children:"(x_{"+element.options.varSubscript+"}, y_{"+element.options.varSubscript+"})"})]}),onUp:n===0?null:()=>this._moveElementUp(n),onDown:n===this.props.elements.length-1?null:()=>this._moveElementDown(n),onDelete:()=>this._deleteElement(n),children:jsxRuntimeExports.jsx(MovablePointEditor,{...element.options,onChange:newProps=>{const elements=JSON.parse(JSON.stringify(this.props.elements));Object.assign(elements[n].options,newProps);this.props.onChange({elements:elements});}})},element.key)}if(element.type==="movable-line"){return jsxRuntimeExports.jsx(ElementContainer,{title:jsxRuntimeExports.jsxs("span",{children:["Movable line"," ",jsxRuntimeExports.jsx(TeX,{children:"(x_{"+element.options.startSubscript+"}, y_{"+element.options.startSubscript+"})"})," ","to"," ",jsxRuntimeExports.jsx(TeX,{children:"(x_{"+element.options.endSubscript+"}, y_{"+element.options.endSubscript+"})"})]}),onUp:n===0?null:()=>this._moveElementUp(n),onDown:n===this.props.elements.length-1?null:()=>this._moveElementDown(n),onDelete:()=>this._deleteElement(n),children:jsxRuntimeExports.jsx(MovableLineEditor,{...element.options,onChange:newProps=>{const elements=JSON.parse(JSON.stringify(this.props.elements));Object.assign(elements[n].options,newProps);this.props.onChange({elements:elements});}})},element.key)}if(element.type==="point"){return jsxRuntimeExports.jsx(ElementContainer,{title:jsxRuntimeExports.jsxs("span",{children:["Point"," ",jsxRuntimeExports.jsx(TeX,{children:"("+element.options.coordX+", "+element.options.coordY+")"})]}),onUp:n===0?null:()=>this._moveElementUp(n),onDown:n===this.props.elements.length-1?null:()=>this._moveElementDown(n),onDelete:()=>this._deleteElement(n),children:jsxRuntimeExports.jsx(PointEditor,{...element.options,onChange:newProps=>{const elements=JSON.parse(JSON.stringify(this.props.elements));Object.assign(elements[n].options,newProps);this.props.onChange({elements:elements});}})},element.key)}if(element.type==="line"){return jsxRuntimeExports.jsx(ElementContainer,{title:jsxRuntimeExports.jsxs("span",{children:["Line"," ",jsxRuntimeExports.jsx(TeX,{children:"("+element.options.startX+", "+element.options.startY+")"})," ","to"," ",jsxRuntimeExports.jsx(TeX,{children:"("+element.options.endX+", "+element.options.endY+")"})]}),onUp:n===0?null:()=>this._moveElementUp(n),onDown:n===this.props.elements.length-1?null:()=>this._moveElementDown(n),onDelete:()=>this._deleteElement(n),children:jsxRuntimeExports.jsx(LineEditor,{...element.options,onChange:newProps=>{const elements=JSON.parse(JSON.stringify(this.props.elements));Object.assign(elements[n].options,newProps);this.props.onChange({elements:elements});}})},element.key)}if(element.type==="function"){return jsxRuntimeExports.jsx(ElementContainer,{title:jsxRuntimeExports.jsxs("span",{children:["Function"," ",jsxRuntimeExports.jsx(TeX,{children:element.options.funcName+"(x) = "+element.options.value})]}),onUp:n===0?null:()=>this._moveElementUp(n),onDown:n===this.props.elements.length-1?null:()=>this._moveElementDown(n),onDelete:()=>this._deleteElement(n),children:jsxRuntimeExports.jsx(FunctionEditor,{...element.options,onChange:newProps=>{const elements=JSON.parse(JSON.stringify(this.props.elements));Object.assign(elements[n].options,newProps);this.props.onChange({elements:elements});}})},element.key)}if(element.type==="parametric"){return jsxRuntimeExports.jsx(ElementContainer,{title:jsxRuntimeExports.jsx("span",{children:"Parametric"}),onUp:n===0?null:()=>this._moveElementUp(n),onDown:n===this.props.elements.length-1?null:()=>this._moveElementDown(n),onDelete:()=>this._deleteElement(n),children:jsxRuntimeExports.jsx(ParametricEditor,{...element.options,onChange:newProps=>{const elements=JSON.parse(JSON.stringify(this.props.elements));Object.assign(elements[n].options,newProps);this.props.onChange({elements:elements});}})},element.key)}if(element.type==="label"){return jsxRuntimeExports.jsx(ElementContainer,{title:jsxRuntimeExports.jsxs("span",{children:["Label"," ",jsxRuntimeExports.jsx(TeX,{children:unescapeMathMode(element.options.label)})," "]}),onUp:n===0?null:()=>this._moveElementUp(n),onDown:n===this.props.elements.length-1?null:()=>this._moveElementDown(n),onDelete:()=>this._deleteElement(n),children:jsxRuntimeExports.jsx(LabelEditor,{...element.options,onChange:newProps=>{const elements=JSON.parse(JSON.stringify(this.props.elements));Object.assign(elements[n].options,newProps);this.props.onChange({elements:elements});}})},element.key)}if(element.type==="rectangle"){return jsxRuntimeExports.jsx(ElementContainer,{title:jsxRuntimeExports.jsxs("span",{children:["Rectangle"," ",jsxRuntimeExports.jsx(TeX,{children:"("+element.options.coordX+", "+element.options.coordY+")"})," — ",jsxRuntimeExports.jsx(TeX,{children:element.options.width+" \\times "+element.options.height})]}),onUp:n===0?null:()=>this._moveElementUp(n),onDown:n===this.props.elements.length-1?null:()=>this._moveElementDown(n),onDelete:()=>this._deleteElement(n),children:jsxRuntimeExports.jsx(RectangleEditor,{...element.options,onChange:newProps=>{const elements=JSON.parse(JSON.stringify(this.props.elements));Object.assign(elements[n].options,newProps);this.props.onChange({elements:elements});}})},element.key)}}),jsxRuntimeExports.jsx("div",{className:"perseus-widget-interaction-editor-select-element",children:jsxRuntimeExports.jsxs("select",{onChange:this._addNewElement,children:[jsxRuntimeExports.jsxs("option",{value:"",children:["Add an element","…"]}),jsxRuntimeExports.jsx("option",{disabled:true,children:"--"}),jsxRuntimeExports.jsx("option",{value:"point",children:"Point"}),jsxRuntimeExports.jsx("option",{value:"line",children:"Line segment"}),jsxRuntimeExports.jsx("option",{value:"function",children:"Function plot"}),jsxRuntimeExports.jsx("option",{value:"parametric",children:"Parametric plot"}),jsxRuntimeExports.jsx("option",{value:"label",children:"Label"}),jsxRuntimeExports.jsx("option",{value:"rectangle",children:"Rectangle"}),jsxRuntimeExports.jsx("option",{value:"movable-point",children:"★ Movable point"}),jsxRuntimeExports.jsx("option",{value:"movable-line",children:"★ Movable line segment"})]})})]})}constructor(...args){super(...args),this.state={usedVarSubscripts:this._getAllVarSubscripts(this.props.elements),usedFunctionNames:this._getAllFunctionNames(this.props.elements)},this._updateGraphProps=newProps=>{const{step,...rest}=newProps;this.props.onChange({graph:{...this.props.graph,...rest,tickStep:step}});},this._addNewElement=e=>{const elementType=e.target.value;if(elementType===""){return}e.target.value="";const newElement={type:elementType,key:elementType+"-"+(Math.random()*0xffffff<<0).toString(16),options:{...defaultOptionsByElementType[elementType]}};let nextSubscript;if(elementType==="movable-point"){nextSubscript=Math.max(...this.state.usedVarSubscripts,-1)+1;newElement.options.varSubscript=nextSubscript;}else if(elementType==="movable-line"){nextSubscript=Math.max(...this.state.usedVarSubscripts,-1)+1;newElement.options.startSubscript=nextSubscript;newElement.options.endSubscript=nextSubscript+1;}else if(elementType==="function"){const nextLetter=String.fromCharCode(Math.max(...this.state.usedFunctionNames.map(c=>c.charCodeAt(0)),"e".charCodeAt(0))+1);newElement.options.funcName=nextLetter;}this.props.onChange({elements:this.props.elements.concat(newElement)});},this._deleteElement=index=>{const element=this.props.elements[index];this.props.onChange({elements:this.props.elements.filter(e=>e!==element)});},this._moveElementUp=index=>{const element=this.props.elements[index];const newElements=this.props.elements.filter(e=>e!==element);newElements.splice(index-1,0,element);this.props.onChange({elements:newElements});},this._moveElementDown=index=>{const element=this.props.elements[index];const newElements=this.props.elements.filter(e=>e!==element);newElements.splice(index+1,0,element);this.props.onChange({elements:newElements});},this.serialize=()=>{return EditorJsonify.serialize.call(this)};}}InteractionEditor.defaultProps=interactionLogic.defaultWidgetOptions;
|
|
1650
|
+
const{unescapeMathMode}=Util;class InteractionEditor extends React.Component{UNSAFE_componentWillReceiveProps(nextProps){this.setState({usedVarSubscripts:this._getAllVarSubscripts(nextProps.elements),usedFunctionNames:this._getAllFunctionNames(nextProps.elements)});}handleChange(changes){this.props.onChange({graph:this.props.graph,elements:this.props.elements,...changes});}handleElementChange(n,newElement){const elementsCopy=[...this.props.elements];elementsCopy[n]=newElement;this.handleChange({elements:elementsCopy});}_getAllVarSubscripts(elements){const movableLines=elements.filter(element=>element.type==="movable-line");return elements.filter(element=>element.type==="movable-point").map(element=>element.options.varSubscript).concat(movableLines.map(element=>element.options.startSubscript)).concat(movableLines.map(element=>element.options.endSubscript))}_getAllFunctionNames(elements){return elements.filter(element=>element.type==="function").map(element=>element.options.funcName)}nextSubscript(){return Math.max(...this.state.usedVarSubscripts,-1)+1}nextFuncName(){return String.fromCharCode(Math.max(...this.state.usedFunctionNames.map(c=>c.charCodeAt(0)),"e".charCodeAt(0))+1)}createElement(elementType){switch(elementType){case "movable-point":return {type:"movable-point",key:`movable-point-${randomId()}`,options:{...MovablePointEditor.defaultProps,varSubscript:this.nextSubscript()}};case "movable-line":return {type:"movable-line",key:`movable-line-${randomId()}`,options:{...MovableLineEditor.defaultProps,startSubscript:this.nextSubscript(),endSubscript:this.nextSubscript()+1}};case "point":return {type:"point",key:`point-${randomId()}`,options:{...PointEditor.defaultProps}};case "line":return {type:"line",key:`line-${randomId()}`,options:{...LineEditor.defaultProps}};case "function":return {type:"function",key:`function-${randomId()}`,options:{...FunctionEditor.defaultProps,funcName:this.nextFuncName()}};case "parametric":return {type:"parametric",key:`parametric-${randomId()}`,options:{...ParametricEditor.defaultProps}};case "rectangle":return {type:"rectangle",key:`rectangle-${randomId()}`,options:{...RectangleEditor.defaultProps}};case "label":return {type:"label",key:`label-${randomId()}`,options:{...LabelEditor.defaultProps}};default:throw new Error(`Unrecognized element type: ${elementType}`)}}render(){const{TeX}=Dependencies.getDependencies();return jsxRuntimeExports.jsxs("div",{className:"perseus-widget-interaction-editor",children:[jsxRuntimeExports.jsxs(ElementContainer,{title:"Grid settings",children:[jsxRuntimeExports.jsx(GraphSettings,{editableSettings:["canvas","graph"],box:this.props.graph.box,labels:this.props.graph.labels,range:this.props.graph.range,step:this.props.graph.tickStep,gridStep:this.props.graph.gridStep,markings:this.props.graph.markings,onChange:this._updateGraphProps}),jsxRuntimeExports.jsx(jsxRuntimeExports.Fragment,{children:this.props.graph.valid!==true&&jsxRuntimeExports.jsx("div",{children:this.props.graph.valid})})]}),this.props.elements.map((element,n)=>{if(element.type==="movable-point"){return jsxRuntimeExports.jsx(ElementContainer,{title:jsxRuntimeExports.jsxs("span",{children:["Movable point"," ",jsxRuntimeExports.jsx(TeX,{children:"(x_{"+element.options.varSubscript+"}, y_{"+element.options.varSubscript+"})"})]}),onUp:n===0?null:()=>this._moveElementUp(n),onDown:n===this.props.elements.length-1?null:()=>this._moveElementDown(n),onDelete:()=>this._deleteElement(n),children:jsxRuntimeExports.jsx(MovablePointEditor,{...element.options,onChange:newOptions=>{this.handleElementChange(n,{...element,options:newOptions});}})},element.key)}if(element.type==="movable-line"){return jsxRuntimeExports.jsx(ElementContainer,{title:jsxRuntimeExports.jsxs("span",{children:["Movable line"," ",jsxRuntimeExports.jsx(TeX,{children:"(x_{"+element.options.startSubscript+"}, y_{"+element.options.startSubscript+"})"})," ","to"," ",jsxRuntimeExports.jsx(TeX,{children:"(x_{"+element.options.endSubscript+"}, y_{"+element.options.endSubscript+"})"})]}),onUp:n===0?null:()=>this._moveElementUp(n),onDown:n===this.props.elements.length-1?null:()=>this._moveElementDown(n),onDelete:()=>this._deleteElement(n),children:jsxRuntimeExports.jsx(MovableLineEditor,{...element.options,onChange:newOptions=>{this.handleElementChange(n,{...element,options:newOptions});}})},element.key)}if(element.type==="point"){return jsxRuntimeExports.jsx(ElementContainer,{title:jsxRuntimeExports.jsxs("span",{children:["Point"," ",jsxRuntimeExports.jsx(TeX,{children:"("+element.options.coordX+", "+element.options.coordY+")"})]}),onUp:n===0?null:()=>this._moveElementUp(n),onDown:n===this.props.elements.length-1?null:()=>this._moveElementDown(n),onDelete:()=>this._deleteElement(n),children:jsxRuntimeExports.jsx(PointEditor,{...element.options,onChange:newOptions=>{this.handleElementChange(n,{...element,options:newOptions});}})},element.key)}if(element.type==="line"){return jsxRuntimeExports.jsx(ElementContainer,{title:jsxRuntimeExports.jsxs("span",{children:["Line"," ",jsxRuntimeExports.jsx(TeX,{children:"("+element.options.startX+", "+element.options.startY+")"})," ","to"," ",jsxRuntimeExports.jsx(TeX,{children:"("+element.options.endX+", "+element.options.endY+")"})]}),onUp:n===0?null:()=>this._moveElementUp(n),onDown:n===this.props.elements.length-1?null:()=>this._moveElementDown(n),onDelete:()=>this._deleteElement(n),children:jsxRuntimeExports.jsx(LineEditor,{...element.options,onChange:newOptions=>{this.handleElementChange(n,{...element,options:newOptions});}})},element.key)}if(element.type==="function"){return jsxRuntimeExports.jsx(ElementContainer,{title:jsxRuntimeExports.jsxs("span",{children:["Function"," ",jsxRuntimeExports.jsx(TeX,{children:element.options.funcName+"(x) = "+element.options.value})]}),onUp:n===0?null:()=>this._moveElementUp(n),onDown:n===this.props.elements.length-1?null:()=>this._moveElementDown(n),onDelete:()=>this._deleteElement(n),children:jsxRuntimeExports.jsx(FunctionEditor,{...element.options,onChange:newOptions=>{this.handleElementChange(n,{...element,options:newOptions});}})},element.key)}if(element.type==="parametric"){return jsxRuntimeExports.jsx(ElementContainer,{title:jsxRuntimeExports.jsx("span",{children:"Parametric"}),onUp:n===0?null:()=>this._moveElementUp(n),onDown:n===this.props.elements.length-1?null:()=>this._moveElementDown(n),onDelete:()=>this._deleteElement(n),children:jsxRuntimeExports.jsx(ParametricEditor,{...element.options,onChange:newOptions=>{this.handleElementChange(n,{...element,options:newOptions});}})},element.key)}if(element.type==="label"){return jsxRuntimeExports.jsx(ElementContainer,{title:jsxRuntimeExports.jsxs("span",{children:["Label"," ",jsxRuntimeExports.jsx(TeX,{children:unescapeMathMode(element.options.label)})," "]}),onUp:n===0?null:()=>this._moveElementUp(n),onDown:n===this.props.elements.length-1?null:()=>this._moveElementDown(n),onDelete:()=>this._deleteElement(n),children:jsxRuntimeExports.jsx(LabelEditor,{...element.options,onChange:newOptions=>{this.handleElementChange(n,{...element,options:newOptions});}})},element.key)}if(element.type==="rectangle"){return jsxRuntimeExports.jsx(ElementContainer,{title:jsxRuntimeExports.jsxs("span",{children:["Rectangle"," ",jsxRuntimeExports.jsx(TeX,{children:"("+element.options.coordX+", "+element.options.coordY+")"})," — ",jsxRuntimeExports.jsx(TeX,{children:element.options.width+" \\times "+element.options.height})]}),onUp:n===0?null:()=>this._moveElementUp(n),onDown:n===this.props.elements.length-1?null:()=>this._moveElementDown(n),onDelete:()=>this._deleteElement(n),children:jsxRuntimeExports.jsx(RectangleEditor,{...element.options,onChange:newOptions=>{this.handleElementChange(n,{...element,options:newOptions});}})},element.key)}}),jsxRuntimeExports.jsx("div",{className:"perseus-widget-interaction-editor-select-element",children:jsxRuntimeExports.jsxs("select",{onChange:this._addNewElement,children:[jsxRuntimeExports.jsxs("option",{value:"",children:["Add an element","…"]}),jsxRuntimeExports.jsx("option",{disabled:true,children:"--"}),jsxRuntimeExports.jsx("option",{value:"point",children:"Point"}),jsxRuntimeExports.jsx("option",{value:"line",children:"Line segment"}),jsxRuntimeExports.jsx("option",{value:"function",children:"Function plot"}),jsxRuntimeExports.jsx("option",{value:"parametric",children:"Parametric plot"}),jsxRuntimeExports.jsx("option",{value:"label",children:"Label"}),jsxRuntimeExports.jsx("option",{value:"rectangle",children:"Rectangle"}),jsxRuntimeExports.jsx("option",{value:"movable-point",children:"★ Movable point"}),jsxRuntimeExports.jsx("option",{value:"movable-line",children:"★ Movable line segment"})]})})]})}constructor(...args){super(...args),this.state={usedVarSubscripts:this._getAllVarSubscripts(this.props.elements),usedFunctionNames:this._getAllFunctionNames(this.props.elements)},this._updateGraphProps=newProps=>{const{step,...rest}=newProps;this.handleChange({graph:{...this.props.graph,...rest,tickStep:step}});},this._addNewElement=e=>{const elementType=e.target.value;if(elementType===""){return}e.target.value="";this.handleChange({elements:this.props.elements.concat([this.createElement(elementType)])});},this._deleteElement=index=>{const element=this.props.elements[index];this.handleChange({elements:this.props.elements.filter(e=>e!==element)});},this._moveElementUp=index=>{const element=this.props.elements[index];const newElements=this.props.elements.filter(e=>e!==element);newElements.splice(index-1,0,element);this.handleChange({elements:newElements});},this._moveElementDown=index=>{const element=this.props.elements[index];const newElements=this.props.elements.filter(e=>e!==element);newElements.splice(index+1,0,element);this.handleChange({elements:newElements});},this.serialize=()=>{return EditorJsonify.serialize.call(this)};}}InteractionEditor.defaultProps=interactionLogic.defaultWidgetOptions;function randomId(){return (Math.random()*0xffffff<<0).toString(16)}
|
|
1652
1651
|
|
|
1653
1652
|
var styles$E = {"singleSelectShort":"perseus_wAZzFxEx","row":"perseus_6FquBkGo"};
|
|
1654
1653
|
|
|
@@ -1674,7 +1673,7 @@ function AxisTickSwitches(props){const{showAxisTicks,onChange,disabled}=props;re
|
|
|
1674
1673
|
|
|
1675
1674
|
var styles$B = {"backgroundUrlInput":"perseus_so0nIc4z","checkboxRow":"perseus_lfG1X93S","protractorSection":"perseus_thf-SEbO"};
|
|
1676
1675
|
|
|
1677
|
-
const{ButtonGroup: ButtonGroup$1,RangeInput: RangeInput$4}=components;const defaultBackgroundImage={url:null,width:0,height:0};function numSteps(range,step){return Math.floor((range[1]-range[0])/step)}class InteractiveGraphSettings extends React.Component{static stateFromProps(props){return {labelsTextbox:props.labels,labelLocation:props.labelLocation,gridStepTextbox:props.gridStep,snapStepTextbox:props.snapStep,stepTextbox:props.step,rangeTextbox:props.range,showAxisArrowsSwitches:props.showAxisArrows,showAxisTicksSwitches:props.showAxisTicks,backgroundImage:{...props.backgroundImage}}}componentDidMount(){this._isMounted=true;this.changeGraph=_.debounce(this.changeGraph,300);}UNSAFE_componentWillReceiveProps(nextProps){if(!_.isEqual(this.props.labels,nextProps.labels)||!_.isEqual(this.props.labelLocation,nextProps.labelLocation)||!_.isEqual(this.props.gridStep,nextProps.gridStep)||!_.isEqual(this.props.snapStep,nextProps.snapStep)||!_.isEqual(this.props.step,nextProps.step)||!_.isEqual(this.props.range,nextProps.range)||!_.isEqual(this.props.backgroundImage,nextProps.backgroundImage)){this.setState(InteractiveGraphSettings.stateFromProps(nextProps));}}componentWillUnmount(){this._isMounted=false;}render(){const editingDisabled=this.props.apiOptions?.editingDisabled??false;return jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:[jsxRuntimeExports.jsx(Heading,{title:"Common Graph Settings",isOpen:this.state.isExpanded,isCollapsible:true,onToggle:()=>this.setState({isExpanded:!this.state.isExpanded})}),this.state.isExpanded&&jsxRuntimeExports.jsxs(View,{children:[jsxRuntimeExports.jsxs("div",{className:"graph-settings",children:[jsxRuntimeExports.jsx("div",{className:"perseus-widget-row",children:jsxRuntimeExports.jsx(LabeledRow,{label:"Label Location",children:jsxRuntimeExports.jsx(ButtonGroup$1,{value:this.props.labelLocation,buttons:[{value:"onAxis",content:"On Axis"},{value:"alongEdge",content:"Along Graph Edge"}],onChange:this.change("labelLocation"),disabled:editingDisabled})})}),jsxRuntimeExports.jsxs("div",{className:"perseus-widget-row",children:[jsxRuntimeExports.jsx("div",{className:"perseus-widget-left-col",children:jsxRuntimeExports.jsx(LabeledRow,{label:"x Label",children:jsxRuntimeExports.jsx("input",{type:"text",className:"graph-settings-axis-label",ref:this.labelXRef,onChange:e=>this.changeLabel(0,e),value:this.state.labelsTextbox[0]||""})})}),jsxRuntimeExports.jsx("div",{className:"perseus-widget-right-col",children:jsxRuntimeExports.jsx(LabeledRow,{label:"y Label",children:jsxRuntimeExports.jsx("input",{type:"text",className:"graph-settings-axis-label",ref:this.labelYRef,onChange:e=>this.changeLabel(1,e),value:this.state.labelsTextbox[1]||""})})})]}),jsxRuntimeExports.jsxs("div",{className:"perseus-widget-row",children:[jsxRuntimeExports.jsx("div",{className:"perseus-widget-left-col",children:jsxRuntimeExports.jsx(LabeledRow,{label:"x Range",children:jsxRuntimeExports.jsx(RangeInput$4,{value:this.state.rangeTextbox[0],onChange:vals=>this.changeRange(0,vals),allowPiTruncation:true})})}),jsxRuntimeExports.jsx("div",{className:"perseus-widget-right-col",children:jsxRuntimeExports.jsx(LabeledRow,{label:"y Range",children:jsxRuntimeExports.jsx(RangeInput$4,{value:this.state.rangeTextbox[1],onChange:vals=>this.changeRange(1,vals),allowPiTruncation:true})})})]}),jsxRuntimeExports.jsx(AxisArrowSwitches,{showAxisArrows:this.state.showAxisArrowsSwitches,onChange:this.changeShowAxisArrows,disabled:this.props.apiOptions?.editingDisabled??false}),jsxRuntimeExports.jsx(AxisTickSwitches,{showAxisTicks:this.state.showAxisTicksSwitches,onChange:this.changeShowAxisTicks,disabled:this.props.apiOptions?.editingDisabled??false}),jsxRuntimeExports.jsxs("div",{className:"perseus-widget-row",children:[jsxRuntimeExports.jsx("div",{className:"perseus-widget-left-col",children:jsxRuntimeExports.jsx(LabeledRow,{label:"Tick Step",children:jsxRuntimeExports.jsx(RangeInput$4,{value:this.state.stepTextbox,onChange:this.changeStep,allowPiTruncation:true})})}),jsxRuntimeExports.jsx("div",{className:"perseus-widget-right-col",children:jsxRuntimeExports.jsx(LabeledRow,{label:"Grid Step",children:jsxRuntimeExports.jsx(RangeInput$4,{value:this.state.gridStepTextbox,onChange:this.changeGridStep,allowPiTruncation:true})})})]}),jsxRuntimeExports.jsxs("div",{className:"perseus-widget-row",children:[jsxRuntimeExports.jsx("div",{className:"perseus-widget-left-col",children:jsxRuntimeExports.jsx(LabeledRow,{label:"Snap Step",children:jsxRuntimeExports.jsx(RangeInput$4,{value:this.state.snapStepTextbox,onChange:this.changeSnapStep,allowPiTruncation:true})})}),jsxRuntimeExports.jsxs("div",{className:"perseus-widget-right-col",children:[jsxRuntimeExports.jsx(Button,{size:"small",kind:"tertiary",onClick:()=>{this.changeStepsBasedOnRange();},disabled:editingDisabled,children:"Auto-adjust steps"}),jsxRuntimeExports.jsxs(InfoTip,{children:[jsxRuntimeExports.jsx("p",{children:'Use the "Auto-adjust" steps button to update the tick step, grid step, and snap step to values that are valid for the current range.'}),jsxRuntimeExports.jsx("br",{}),jsxRuntimeExports.jsx("p",{children:"This is useful when the range is changed, and the graph errors due to the step sizes being too large or too small."})]})]})]}),jsxRuntimeExports.jsx("div",{className:"perseus-widget-row",children:jsxRuntimeExports.jsx(LabeledRow,{label:"Markings",children:jsxRuntimeExports.jsx(ButtonGroup$1,{value:this.props.markings,buttons:[{value:"axes",content:"Axes"},{value:"graph",content:"Graph"},{value:"grid",content:"Grid"},{value:"none",content:"None"}],onChange:this.change("markings"),disabled:editingDisabled})})}),jsxRuntimeExports.jsx("div",{className:"perseus-widget-left-col",children:jsxRuntimeExports.jsx(Checkbox$1,{label:"Show tooltips",checked:this.props.showTooltips,onChange:value=>{this.change({showTooltips:value});},disabled:editingDisabled})})]}),jsxRuntimeExports.jsxs(LabeledRow,{label:"Background image URL",style:{marginBlockStart:0},children:[jsxRuntimeExports.jsx("input",{type:"text",className:styles$B.backgroundUrlInput,ref:this.bgUrlRef,value:this.state.backgroundImage.url||"",onChange:e=>{const image={...this.props.backgroundImage};image.url=e.target.value;this.setState({backgroundImage:image});},onKeyPress:this.changeBackgroundUrl,onBlur:this.changeBackgroundUrl}),jsxRuntimeExports.jsx(InfoTip,{children:jsxRuntimeExports.jsx("p",{children:'Create an image in graphie, or use the "Add image" function to create a background.'})})]}),jsxRuntimeExports.jsxs(View,{className:styles$B.protractorSection,children:[jsxRuntimeExports.jsx(View,{className:styles$B.checkboxRow,children:jsxRuntimeExports.jsx(Checkbox$1,{label:"Show protractor",checked:this.props.showProtractor,onChange:value=>{this.change({showProtractor:value});},disabled:editingDisabled,style:{marginBlockStart:0}})}),this.props.showProtractor&&jsxRuntimeExports.jsx(Banner,{text:"The protractor is not accessible. Please consider an alternate approach.",kind:"warning"})]})]})]})}constructor(props){super(props),this._isMounted=false,this.bgUrlRef=React.createRef(),this.labelXRef=React.createRef(),this.labelYRef=React.createRef(),this.change=(...args)=>{return deprecatedChangeableChange.apply(this,args)},this.changeBackgroundUrl=e=>{if(e.type==="keypress"&&e.key!=="Enter"){return}const setUrl=(url,width,height)=>{const image={...this.props.backgroundImage};image.url=url;image.width=width;image.height=height;this.setState({backgroundImage:image},this.changeGraph);};const url=this.bgUrlRef.current?.value;if(url){Util.getImageSize(url,(width,height)=>{if(this._isMounted){setUrl(url,width,height);}});}else {setUrl(null,0,0);}},this.renderLabelChoices=choices=>{return choices.map(nameAndValue=>jsxRuntimeExports.jsx("option",{value:nameAndValue[1],children:nameAndValue[0]},nameAndValue[1]))},this.validRange=range=>{const numbers=_.every(range,function(num){return _.isFinite(num)});if(!numbers){return "Range must be a valid number"}if(range[0]>=range[1]){return "Range must have a higher number on the right"}return true},this.validateStepValue=settings=>{const{step,range,name,minTicks,maxTicks}=settings;const nSteps=numSteps(range,step);if(nSteps<minTicks){return name+" is too large, there must be at least "+minTicks+" ticks."}if(nSteps>maxTicks){return name+" is too small, there can be at most "+maxTicks+" ticks."}return true},this.validSnapStep=(step,range)=>{return this.validateStepValue({step:step,range:range,name:"Snap step",minTicks:5,maxTicks:60})},this.validGridStep=(step,range)=>{return this.validateStepValue({step:step,range:range,name:"Grid step",minTicks:3,maxTicks:60})},this.validStep=(step,range)=>{return this.validateStepValue({step:step,range:range,name:"Step",minTicks:3,maxTicks:20})},this.validBackgroundImageSize=image=>{if(!image.url){return true}const validSize=image.width<=450&&image.height<=450;if(!validSize){return "Image must be smaller than 450px x 450px."}return true},this.validateGraphSettings=(range,step,gridStep,snapStep,image)=>{const self=this;let msg;const goodRange=_.every(range,function(range){msg=self.validRange(range);return msg===true});if(!goodRange){return msg}const goodStep=_.every(step,function(step,i){msg=self.validStep(step,range[i]);return msg===true});if(!goodStep){return msg}const goodGridStep=_.every(gridStep,function(gridStep,i){msg=self.validGridStep(gridStep,range[i]);return msg===true});if(!goodGridStep){return msg}const goodSnapStep=_.every(snapStep,function(snapStep,i){msg=self.validSnapStep(snapStep,range[i]);return msg===true});if(!goodSnapStep){return msg}const goodImageSize=this.validBackgroundImageSize(image);if(goodImageSize!==true){msg=goodImageSize;return msg}return true},this.changeLabel=(i,e)=>{const val=e.target.value;const labels=this.state.labelsTextbox.slice();labels[i]=val;this.setState({labelsTextbox:labels},this.changeGraph);},this.changeRange=(i,values)=>{const ranges=this.state.rangeTextbox.slice();ranges[i]=values;this.setState({rangeTextbox:ranges},this.changeGraph);},this.changeShowAxisArrows=axis=>{const newShowAxisArrows={...this.state.showAxisArrowsSwitches};newShowAxisArrows[axis]=!newShowAxisArrows[axis];this.setState({showAxisArrowsSwitches:newShowAxisArrows},this.changeGraph);},this.changeShowAxisTicks=axis=>{const newShowAxisTicks={...this.state.showAxisTicksSwitches};newShowAxisTicks[axis]=!newShowAxisTicks[axis];this.setState({showAxisTicksSwitches:newShowAxisTicks},this.changeGraph);},this.changeStepsBasedOnRange=()=>{const ranges=this.state.rangeTextbox.slice();const step=this.state.stepTextbox.slice();const gridStep=this.state.gridStepTextbox.slice();const snapStep=this.state.snapStepTextbox.slice();const scaleX=Util.scaleFromExtent(ranges[0],this.props.box[0]);if(this.validRange(ranges[0])===true){step[0]=Util.tickStepFromExtent(ranges[0],this.props.box[0]);const gridStepValue=Util.gridStepFromTickStep(step[0],scaleX);if(gridStepValue){gridStep[0]=gridStepValue;}snapStep[0]=gridStep[0]/2;}const scaleY=Util.scaleFromExtent(ranges[1],this.props.box[1]);if(this.validRange(ranges[1])===true){step[1]=Util.tickStepFromExtent(ranges[1],this.props.box[1]);const gridStepValue=Util.gridStepFromTickStep(step[1],scaleY);if(gridStepValue){gridStep[1]=gridStepValue;}snapStep[1]=gridStep[1]/2;}this.setState({stepTextbox:step,gridStepTextbox:gridStep,snapStepTextbox:snapStep,rangeTextbox:ranges},this.changeGraph);},this.changeStep=step=>{this.setState({stepTextbox:step},this.changeGraph);},this.changeSnapStep=snapStep=>{this.setState({snapStepTextbox:snapStep},this.changeGraph);},this.changeGridStep=gridStep=>{this.setState({gridStepTextbox:gridStep,snapStepTextbox:gridStep.map(function(step){return step/2})},this.changeGraph);},this.changeGraph=()=>{const labels=this.state.labelsTextbox;const labelLocation=this.state.labelLocation;const range=this.state.rangeTextbox.map(range=>range.map(value=>Number(value)));const showAxisArrows=this.state.showAxisArrowsSwitches;const showAxisTicks=this.state.showAxisTicksSwitches;const step=this.state.stepTextbox.map(value=>Number(value));const gridStep=this.state.gridStepTextbox;const snapStep=this.state.snapStepTextbox;const image=this.state.backgroundImage;const validationResult=this.validateGraphSettings(range,step,gridStep,snapStep,image);if(validationResult===true){this.change({valid:true,labels:labels,labelLocation:labelLocation,range:range,showAxisArrows:showAxisArrows,showAxisTicks:showAxisTicks,step:step,gridStep:gridStep,snapStep:snapStep,backgroundImage:image});}else {this.change({valid:validationResult});}};this.state={isExpanded:true,...InteractiveGraphSettings.stateFromProps(props)};}}InteractiveGraphSettings.defaultProps={box:[interactiveSizes.defaultBoxSizeSmall,interactiveSizes.defaultBoxSizeSmall],labels:["$x$","$y$"],labelLocation:"onAxis",range:[[-10,10],[-10,10]],step:[1,1],gridStep:[1,1],snapStep:[1,1],valid:true,backgroundImage:defaultBackgroundImage,markings:"graph",showProtractor:false,showTooltips:false,showAxisArrows:{xMin:true,xMax:true,yMin:true,yMax:true},showAxisTicks:{x:true,y:true}};
|
|
1676
|
+
const{ButtonGroup: ButtonGroup$1,RangeInput: RangeInput$4}=components;const defaultBackgroundImage={url:null,width:0,height:0};function numSteps(range,step){return Math.floor((range[1]-range[0])/step)}class InteractiveGraphSettings extends React.Component{static stateFromProps(props){return {labelsTextbox:props.labels,labelLocation:props.labelLocation,gridStepTextbox:props.gridStep,snapStepTextbox:props.snapStep,stepTextbox:props.step,rangeTextbox:props.range,showAxisArrowsSwitches:props.showAxisArrows,showAxisTicksSwitches:props.showAxisTicks,backgroundImage:{...props.backgroundImage}}}componentDidMount(){this._isMounted=true;this.changeGraph=_.debounce(this.changeGraph,300);}UNSAFE_componentWillReceiveProps(nextProps){if(!_.isEqual(this.props.labels,nextProps.labels)||!_.isEqual(this.props.labelLocation,nextProps.labelLocation)||!_.isEqual(this.props.gridStep,nextProps.gridStep)||!_.isEqual(this.props.snapStep,nextProps.snapStep)||!_.isEqual(this.props.step,nextProps.step)||!_.isEqual(this.props.range,nextProps.range)||!_.isEqual(this.props.backgroundImage,nextProps.backgroundImage)){this.setState(InteractiveGraphSettings.stateFromProps(nextProps));}}componentWillUnmount(){this._isMounted=false;}handleChange(changes){this.props.onChange({labels:this.props.labels,labelLocation:this.props.labelLocation,range:this.props.range,showAxisArrows:this.props.showAxisArrows,showAxisTicks:this.props.showAxisTicks,step:this.props.step,gridStep:this.props.gridStep,snapStep:this.props.snapStep,valid:this.props.valid,backgroundImage:this.props.backgroundImage,markings:this.props.markings,showProtractor:this.props.showProtractor,showTooltips:this.props.showTooltips,...changes});}render(){const editingDisabled=this.props.apiOptions?.editingDisabled??false;return jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:[jsxRuntimeExports.jsx(Heading,{title:"Common Graph Settings",isOpen:this.state.isExpanded,isCollapsible:true,onToggle:()=>this.setState({isExpanded:!this.state.isExpanded})}),this.state.isExpanded&&jsxRuntimeExports.jsxs(View,{children:[jsxRuntimeExports.jsxs("div",{className:"graph-settings",children:[jsxRuntimeExports.jsx("div",{className:"perseus-widget-row",children:jsxRuntimeExports.jsx(LabeledRow,{label:"Label Location",children:jsxRuntimeExports.jsx(ButtonGroup$1,{value:this.props.labelLocation,buttons:[{value:"onAxis",content:"On Axis"},{value:"alongEdge",content:"Along Graph Edge"}],onChange:labelLocation=>this.handleChange({labelLocation}),disabled:editingDisabled})})}),jsxRuntimeExports.jsxs("div",{className:"perseus-widget-row",children:[jsxRuntimeExports.jsx("div",{className:"perseus-widget-left-col",children:jsxRuntimeExports.jsx(LabeledRow,{label:"x Label",children:jsxRuntimeExports.jsx("input",{type:"text",className:"graph-settings-axis-label",ref:this.labelXRef,onChange:e=>this.changeLabel(0,e),value:this.state.labelsTextbox[0]||""})})}),jsxRuntimeExports.jsx("div",{className:"perseus-widget-right-col",children:jsxRuntimeExports.jsx(LabeledRow,{label:"y Label",children:jsxRuntimeExports.jsx("input",{type:"text",className:"graph-settings-axis-label",ref:this.labelYRef,onChange:e=>this.changeLabel(1,e),value:this.state.labelsTextbox[1]||""})})})]}),jsxRuntimeExports.jsxs("div",{className:"perseus-widget-row",children:[jsxRuntimeExports.jsx("div",{className:"perseus-widget-left-col",children:jsxRuntimeExports.jsx(LabeledRow,{label:"x Range",children:jsxRuntimeExports.jsx(RangeInput$4,{value:this.state.rangeTextbox[0],onChange:vals=>this.changeRange(0,vals),allowPiTruncation:true})})}),jsxRuntimeExports.jsx("div",{className:"perseus-widget-right-col",children:jsxRuntimeExports.jsx(LabeledRow,{label:"y Range",children:jsxRuntimeExports.jsx(RangeInput$4,{value:this.state.rangeTextbox[1],onChange:vals=>this.changeRange(1,vals),allowPiTruncation:true})})})]}),jsxRuntimeExports.jsx(AxisArrowSwitches,{showAxisArrows:this.state.showAxisArrowsSwitches,onChange:this.changeShowAxisArrows,disabled:this.props.apiOptions?.editingDisabled??false}),jsxRuntimeExports.jsx(AxisTickSwitches,{showAxisTicks:this.state.showAxisTicksSwitches,onChange:this.changeShowAxisTicks,disabled:this.props.apiOptions?.editingDisabled??false}),jsxRuntimeExports.jsxs("div",{className:"perseus-widget-row",children:[jsxRuntimeExports.jsx("div",{className:"perseus-widget-left-col",children:jsxRuntimeExports.jsx(LabeledRow,{label:"Tick Step",children:jsxRuntimeExports.jsx(RangeInput$4,{value:this.state.stepTextbox,onChange:this.changeStep,allowPiTruncation:true})})}),jsxRuntimeExports.jsx("div",{className:"perseus-widget-right-col",children:jsxRuntimeExports.jsx(LabeledRow,{label:"Grid Step",children:jsxRuntimeExports.jsx(RangeInput$4,{value:this.state.gridStepTextbox,onChange:this.changeGridStep,allowPiTruncation:true})})})]}),jsxRuntimeExports.jsxs("div",{className:"perseus-widget-row",children:[jsxRuntimeExports.jsx("div",{className:"perseus-widget-left-col",children:jsxRuntimeExports.jsx(LabeledRow,{label:"Snap Step",children:jsxRuntimeExports.jsx(RangeInput$4,{value:this.state.snapStepTextbox,onChange:this.changeSnapStep,allowPiTruncation:true})})}),jsxRuntimeExports.jsxs("div",{className:"perseus-widget-right-col",children:[jsxRuntimeExports.jsx(Button,{size:"small",kind:"tertiary",onClick:()=>{this.changeStepsBasedOnRange();},disabled:editingDisabled,children:"Auto-adjust steps"}),jsxRuntimeExports.jsxs(InfoTip,{children:[jsxRuntimeExports.jsx("p",{children:'Use the "Auto-adjust" steps button to update the tick step, grid step, and snap step to values that are valid for the current range.'}),jsxRuntimeExports.jsx("br",{}),jsxRuntimeExports.jsx("p",{children:"This is useful when the range is changed, and the graph errors due to the step sizes being too large or too small."})]})]})]}),jsxRuntimeExports.jsx("div",{className:"perseus-widget-row",children:jsxRuntimeExports.jsx(LabeledRow,{label:"Markings",children:jsxRuntimeExports.jsx(ButtonGroup$1,{value:this.props.markings,buttons:[{value:"axes",content:"Axes"},{value:"graph",content:"Graph"},{value:"grid",content:"Grid"},{value:"none",content:"None"}],onChange:markings=>this.handleChange({markings}),disabled:editingDisabled})})}),jsxRuntimeExports.jsx("div",{className:"perseus-widget-left-col",children:jsxRuntimeExports.jsx(Checkbox$1,{label:"Show tooltips",checked:this.props.showTooltips,onChange:showTooltips=>{this.handleChange({showTooltips});},disabled:editingDisabled})})]}),jsxRuntimeExports.jsxs(LabeledRow,{label:"Background image URL",style:{marginBlockStart:0},children:[jsxRuntimeExports.jsx("input",{type:"text",className:styles$B.backgroundUrlInput,ref:this.bgUrlRef,value:this.state.backgroundImage.url||"",onChange:e=>{const image={...this.props.backgroundImage};image.url=e.target.value;this.setState({backgroundImage:image});},onKeyPress:this.changeBackgroundUrl,onBlur:this.changeBackgroundUrl}),jsxRuntimeExports.jsx(InfoTip,{children:jsxRuntimeExports.jsx("p",{children:'Create an image in graphie, or use the "Add image" function to create a background.'})})]}),jsxRuntimeExports.jsxs(View,{className:styles$B.protractorSection,children:[jsxRuntimeExports.jsx(View,{className:styles$B.checkboxRow,children:jsxRuntimeExports.jsx(Checkbox$1,{label:"Show protractor",checked:this.props.showProtractor,onChange:showProtractor=>{this.handleChange({showProtractor});},disabled:editingDisabled,style:{marginBlockStart:0}})}),this.props.showProtractor&&jsxRuntimeExports.jsx(Banner,{text:"The protractor is not accessible. Please consider an alternate approach.",kind:"warning"})]})]})]})}constructor(props){super(props),this._isMounted=false,this.bgUrlRef=React.createRef(),this.labelXRef=React.createRef(),this.labelYRef=React.createRef(),this.changeBackgroundUrl=e=>{if(e.type==="keypress"&&e.key!=="Enter"){return}const setUrl=(url,width,height)=>{const image={...this.props.backgroundImage};image.url=url;image.width=width;image.height=height;this.setState({backgroundImage:image},this.changeGraph);};const url=this.bgUrlRef.current?.value;if(url){Util.getImageSize(url,(width,height)=>{if(this._isMounted){setUrl(url,width,height);}});}else {setUrl(null,0,0);}},this.renderLabelChoices=choices=>{return choices.map(nameAndValue=>jsxRuntimeExports.jsx("option",{value:nameAndValue[1],children:nameAndValue[0]},nameAndValue[1]))},this.validRange=range=>{const numbers=_.every(range,function(num){return _.isFinite(num)});if(!numbers){return "Range must be a valid number"}if(range[0]>=range[1]){return "Range must have a higher number on the right"}return true},this.validateStepValue=settings=>{const{step,range,name,minTicks,maxTicks}=settings;const nSteps=numSteps(range,step);if(nSteps<minTicks){return name+" is too large, there must be at least "+minTicks+" ticks."}if(nSteps>maxTicks){return name+" is too small, there can be at most "+maxTicks+" ticks."}return true},this.validSnapStep=(step,range)=>{return this.validateStepValue({step:step,range:range,name:"Snap step",minTicks:5,maxTicks:60})},this.validGridStep=(step,range)=>{return this.validateStepValue({step:step,range:range,name:"Grid step",minTicks:3,maxTicks:60})},this.validStep=(step,range)=>{return this.validateStepValue({step:step,range:range,name:"Step",minTicks:3,maxTicks:20})},this.validBackgroundImageSize=image=>{if(!image.url){return true}const validSize=image.width<=450&&image.height<=450;if(!validSize){return "Image must be smaller than 450px x 450px."}return true},this.validateGraphSettings=(range,step,gridStep,snapStep,image)=>{const self=this;let msg;const goodRange=_.every(range,function(range){msg=self.validRange(range);return msg===true});if(!goodRange){return msg}const goodStep=_.every(step,function(step,i){msg=self.validStep(step,range[i]);return msg===true});if(!goodStep){return msg}const goodGridStep=_.every(gridStep,function(gridStep,i){msg=self.validGridStep(gridStep,range[i]);return msg===true});if(!goodGridStep){return msg}const goodSnapStep=_.every(snapStep,function(snapStep,i){msg=self.validSnapStep(snapStep,range[i]);return msg===true});if(!goodSnapStep){return msg}const goodImageSize=this.validBackgroundImageSize(image);if(goodImageSize!==true){msg=goodImageSize;return msg}return true},this.changeLabel=(i,e)=>{const val=e.target.value;const labels=this.state.labelsTextbox.slice();labels[i]=val;this.setState({labelsTextbox:labels},this.changeGraph);},this.changeRange=(i,values)=>{const ranges=this.state.rangeTextbox.slice();ranges[i]=values;this.setState({rangeTextbox:ranges},this.changeGraph);},this.changeShowAxisArrows=axis=>{const newShowAxisArrows={...this.state.showAxisArrowsSwitches};newShowAxisArrows[axis]=!newShowAxisArrows[axis];this.setState({showAxisArrowsSwitches:newShowAxisArrows},this.changeGraph);},this.changeShowAxisTicks=axis=>{const newShowAxisTicks={...this.state.showAxisTicksSwitches};newShowAxisTicks[axis]=!newShowAxisTicks[axis];this.setState({showAxisTicksSwitches:newShowAxisTicks},this.changeGraph);},this.changeStepsBasedOnRange=()=>{const ranges=this.state.rangeTextbox.slice();const step=this.state.stepTextbox.slice();const gridStep=this.state.gridStepTextbox.slice();const snapStep=this.state.snapStepTextbox.slice();const scaleX=Util.scaleFromExtent(ranges[0],this.props.box[0]);if(this.validRange(ranges[0])===true){step[0]=Util.tickStepFromExtent(ranges[0],this.props.box[0]);const gridStepValue=Util.gridStepFromTickStep(step[0],scaleX);if(gridStepValue){gridStep[0]=gridStepValue;}snapStep[0]=gridStep[0]/2;}const scaleY=Util.scaleFromExtent(ranges[1],this.props.box[1]);if(this.validRange(ranges[1])===true){step[1]=Util.tickStepFromExtent(ranges[1],this.props.box[1]);const gridStepValue=Util.gridStepFromTickStep(step[1],scaleY);if(gridStepValue){gridStep[1]=gridStepValue;}snapStep[1]=gridStep[1]/2;}this.setState({stepTextbox:step,gridStepTextbox:gridStep,snapStepTextbox:snapStep,rangeTextbox:ranges},this.changeGraph);},this.changeStep=step=>{this.setState({stepTextbox:step},this.changeGraph);},this.changeSnapStep=snapStep=>{this.setState({snapStepTextbox:snapStep},this.changeGraph);},this.changeGridStep=gridStep=>{this.setState({gridStepTextbox:gridStep,snapStepTextbox:gridStep.map(function(step){return step/2})},this.changeGraph);},this.changeGraph=()=>{const labels=this.state.labelsTextbox;const labelLocation=this.state.labelLocation;const range=this.state.rangeTextbox;const showAxisArrows=this.state.showAxisArrowsSwitches;const showAxisTicks=this.state.showAxisTicksSwitches;const step=this.state.stepTextbox;const gridStep=this.state.gridStepTextbox;const snapStep=this.state.snapStepTextbox;const image=this.state.backgroundImage;const validationResult=this.validateGraphSettings(range,step,gridStep,snapStep,image);if(validationResult===true){this.handleChange({valid:true,labels:labels,labelLocation:labelLocation,range:range,showAxisArrows:showAxisArrows,showAxisTicks:showAxisTicks,step:step,gridStep:gridStep,snapStep:snapStep,backgroundImage:image});}else {this.handleChange({valid:validationResult});}};this.state={isExpanded:true,...InteractiveGraphSettings.stateFromProps(props)};}}InteractiveGraphSettings.defaultProps={box:[interactiveSizes.defaultBoxSizeSmall,interactiveSizes.defaultBoxSizeSmall],labels:["$x$","$y$"],labelLocation:"onAxis",range:[[-10,10],[-10,10]],step:[1,1],gridStep:[1,1],snapStep:[1,1],valid:true,backgroundImage:defaultBackgroundImage,markings:"graph",showProtractor:false,showTooltips:false,showAxisArrows:{xMin:true,xMax:true,yMin:true,yMax:true},showAxisTicks:{x:true,y:true}};
|
|
1678
1677
|
|
|
1679
1678
|
var styles$A = {"treeList":"perseus_dM32KBSs","indentList":"perseus_0LO0xYxg","switchRow":"perseus_T8Wphznm"};
|
|
1680
1679
|
|
|
@@ -1805,7 +1804,7 @@ const StartCoordsSettingsInner=props=>{const{type,range,step,allowReflexAngles,o
|
|
|
1805
1804
|
|
|
1806
1805
|
function toTrio(pointLabels){return [pointLabels[0]??"",pointLabels[1]??"",pointLabels[2]??""]}function toPair(pointLabels){return [pointLabels[0]??"",pointLabels[1]??""]}function toArray(pointLabels){return [...pointLabels]}function reshapePointLabelsForGraphType(pointLabels,graph,correct){if(!graph?.type||!correct){return null}let nextGraph;let nextCorrect=correct;switch(graph.type){case "angle":case "quadratic":{const reshaped=toTrio(pointLabels);nextGraph={...graph,pointLabels:reshaped};if(correct.type===graph.type){nextCorrect={...correct,pointLabels:reshaped};}break}case "absolute-value":case "linear":case "ray":{const reshaped=toPair(pointLabels);nextGraph={...graph,pointLabels:reshaped};if(correct.type===graph.type){nextCorrect={...correct,pointLabels:reshaped};}break}case "circle":case "exponential":case "linear-system":case "logarithm":case "point":case "polygon":case "segment":case "sinusoid":case "tangent":{const reshaped=toArray(pointLabels);nextGraph={...graph,pointLabels:reshaped};if(correct.type===graph.type){nextCorrect={...correct,pointLabels:reshaped};}break}case "vector":case "none":return null}return {graph:nextGraph,correct:nextCorrect}}
|
|
1807
1806
|
|
|
1808
|
-
const InteractiveGraph=InteractiveGraphWidget.widget;class InteractiveGraphEditor extends React.Component{serialize(){const json=_.pick(this.props,"step","backgroundImage","markings","labels","labelLocation","showProtractor","showTooltips","range","showAxisArrows","showAxisTicks","gridStep","snapStep","lockedFigures","fullGraphAriaLabel","fullGraphAriaDescription");const graph=this.refs.graph;if(graph){const correct=graph&&graph.getUserInput();_.extend(json,{graph:{type:correct.type,startCoords:getStartCoords(this.props.graph),..."pointLabels"in this.props.graph&&this.props.graph.pointLabels?{pointLabels:this.props.graph.pointLabels}:{},..."showPointLabels"in this.props.graph&&this.props.graph.showPointLabels?{showPointLabels:this.props.graph.showPointLabels}:{}},correct:correct});_.each(["allowReflexAngles","angleOffsetDeg","numPoints","numSides","numSegments","showAngles","showSides","snapTo","snapDegrees"],function(key){if(_.has(correct,key)){json.graph[key]=correct[key];}});}else {_.extend(json,{graph:this.props.graph,correct:this.props.correct});}return json}render(){let graph;let equationString;const gridStep=this.props.gridStep||Util.getGridStep(this.props.range,this.props.step,interactiveSizes.defaultBoxSize);const snapStep=this.props.snapStep||Util.snapStepFromGridStep(gridStep);const sizeClass=containerSizeClass.SMALL;if(this.props.valid===true){const correct=this.props.correct.type===this.props.graph?.type?this.props.correct:this.props.graph;const graphProps={ref:"graph",options:{box:this.props.box,range:this.props.range,showAxisArrows:this.props.showAxisArrows,showAxisTicks:this.props.showAxisTicks,labels:this.props.labels,labelLocation:this.props.labelLocation,step:this.props.step,gridStep:gridStep,snapStep:snapStep,backgroundImage:this.props.backgroundImage,markings:this.props.markings,showProtractor:this.props.showProtractor,showTooltips:this.props.showTooltips,lockedFigures:this.props.lockedFigures,fullGraphAriaLabel:this.props.fullGraphAriaLabel,fullGraphAriaDescription:this.props.fullGraphAriaDescription},static:this.props.apiOptions?.editingDisabled??false,trackInteraction:function(){},userInput:this.props.static===true&&correct!=null&&"showPointLabels"in correct?{...correct,showPointLabels:false}:correct,handleUserInput:newGraph=>{let correct=this.props.correct;invariant(newGraph!=null);if(this.props.static===true&&newGraph!=null&&"showPointLabels"in newGraph){newGraph={...newGraph,showPointLabels:"showPointLabels"in correct?correct.showPointLabels:undefined};}if(correct.type===newGraph.type){correct=mergeGraphs(correct,newGraph);}else {correct=newGraph;}this.props.onChange({correct:correct,graph:this.props.graph});}};graph=jsxRuntimeExports.jsx(InteractiveGraph,{...graphProps,containerSizeClass:sizeClass,apiOptions:{...this.props.apiOptions,isMobile:false}});equationString=InteractiveGraph.getEquationString(graphProps);}else {graph=jsxRuntimeExports.jsx("div",{className:"perseus-error",children:this.props.valid});}return jsxRuntimeExports.jsx(Id,{children:graphId=>jsxRuntimeExports.jsxs(View,{children:[jsxRuntimeExports.jsx(LabeledRow,{label:"Answer type",labelSize:"medium",children:jsxRuntimeExports.jsx(GraphTypeSelector,{disabled:this.props.apiOptions?.editingDisabled??false,graphType:this.props.graph?.type??"none",onChange:type=>{this.props.onChange({graph:{type},correct:{type}});}})}),jsxRuntimeExports.jsx(InteractiveGraphDescription,{ariaLabelValue:this.props.fullGraphAriaLabel??"",ariaDescriptionValue:this.props.fullGraphAriaDescription??"",editingDisabled:this.props.apiOptions?.editingDisabled??false,onChange:this.props.onChange}),jsxRuntimeExports.jsx(InteractiveGraphCorrectAnswer,{id:graphId,equationString:equationString,children:graph}),this.props.correct?.type==="angle"&&jsxRuntimeExports.jsx(AngleAnswerOptions,{correct:this.props.correct,graph:this.props.graph,onChange:this.props.onChange}),this.props.correct?.type==="point"&&jsxRuntimeExports.jsx(GraphPointsCountSelector,{correct:this.props.correct,graph:this.props.graph,onChange:this.props.onChange}),this.props.correct?.type==="polygon"&&jsxRuntimeExports.jsx(PolygonAnswerOptions,{correct:this.props.correct,graph:this.props.graph,onChange:this.props.onChange}),this.props.correct?.type==="vector"&&jsxRuntimeExports.jsx(VectorAnswerOptions,{correct:this.props.correct,onChange:this.props.onChange}),this.props.correct?.type==="segment"&&jsxRuntimeExports.jsx(SegmentCountSelector,{correct:this.props.correct,graph:this.props.graph,onChange:this.props.onChange}),!this.props.static&&this.props.graph?.type&&this.props.graph.type!=="vector"&&this.props.graph.type!=="none"&&jsxRuntimeExports.jsx(ShowPointLabelsToggle,{showPointLabels:this.props.graph.showPointLabels===true,pointLabels:this.props.graph.pointLabels,onChange:this.changeShowPointLabels}),this.props.graph?.type&&shouldShowStartCoordsUI(this.props.graph,this.props.static)&&jsxRuntimeExports.jsx(StartCoordsSettings,{...this.props.graph,range:this.props.range,step:this.props.step,editingDisabled:this.props.apiOptions?.editingDisabled??false,onChange:this.changeStartCoords,onChangePointLabels:this.changePointLabels}),jsxRuntimeExports.jsx(InteractiveGraphSRTree,{graphId:graphId,correct:this.props.correct,fullGraphAriaLabel:this.props.fullGraphAriaLabel,fullGraphAriaDescription:this.props.fullGraphAriaDescription,lockedFigures:this.props.lockedFigures,editingDisabled:this.props.apiOptions?.editingDisabled??false}),jsxRuntimeExports.jsx(InteractiveGraphSettings,{box:getInteractiveBoxFromSizeClass(sizeClass),range:this.props.range,showAxisArrows:this.props.showAxisArrows,showAxisTicks:this.props.showAxisTicks,labels:this.props.labels,labelLocation:this.props.labelLocation,step:this.props.step,gridStep:gridStep,snapStep:snapStep,valid:this.props.valid,backgroundImage:this.props.backgroundImage,markings:this.props.markings,showProtractor:this.props.showProtractor,showTooltips:this.props.showTooltips,onChange:this.props.onChange,apiOptions:this.props.apiOptions}),jsxRuntimeExports.jsx(LockedFiguresSection,{figures:this.props.lockedFigures,onChange:this.props.onChange,apiOptions:this.props.apiOptions})]})})}constructor(...args){super(...args),this.displayName="InteractiveGraphEditor",this.className="perseus-widget-interactive-graph",this.changeStartCoords=coords=>{if(!this.props.graph?.type){return}const graph={...this.props.graph,startCoords:coords};this.props.onChange({graph:graph});},this.changePointLabels=pointLabels=>{const next=reshapePointLabelsForGraphType(pointLabels,this.props.graph,this.props.correct);if(next){this.props.onChange(next);}},this.changeShowPointLabels=showPointLabels=>{const{graph,correct}=this.props;if(graph===undefined||correct===undefined){return}const newGraph=withShowPointLabels(graph,showPointLabels);const newCorrect=withShowPointLabels(correct,showPointLabels);if(newGraph===undefined||newCorrect===undefined){return}this.props.onChange({graph:newGraph,correct:newCorrect});},this.getSaveWarnings=()=>{const issues=[];for(const figure of this.props.lockedFigures??[]){if(figure.type==="line"&&vector.equal(figure.points[0].coord,figure.points[1].coord)){issues.push("The line cannot have length 0.");}}if(this.props.graph?.type==="polygon"&&this.props.graph.numSides==="unlimited"&&this.props.graph.coords===null){issues.push("Polygon must be closed.");}if(this.props.graph?.type==="exponential"&&this.props.graph.startCoords!=null){const{coords,asymptote}=this.props.graph.startCoords;const asymptoteY=asymptote;const minY=Math.min(coords[0][1],coords[1][1]);const maxY=Math.max(coords[0][1],coords[1][1]);if(asymptoteY>=minY&&asymptoteY<=maxY){issues.push("The exponential start asymptote must not fall between or on the curve's start points.");}}if(this.props.graph?.type==="logarithm"&&this.props.graph.startCoords!=null){const{coords,asymptote}=this.props.graph.startCoords;const asymptoteX=asymptote;const minX=Math.min(coords[0][0],coords[1][0]);const maxX=Math.max(coords[0][0],coords[1][0]);if(asymptoteX>=minX&&asymptoteX<=maxX){issues.push("The logarithm start asymptote must not fall between or on the curve's start points.");}}return issues};}}InteractiveGraphEditor.bestPractices={url:"https://khanacademy.atlassian.net/wiki/spaces/LC/pages/3295281289/Interactive+Graph+Widget#Adding-a-new-Interactive-Graph-Widget",label:"Interactive Graph best practices"};InteractiveGraphEditor.defaultProps={...interactiveGraphLogic.defaultWidgetOptions,valid:true,lockedFigures:[]};function mergeGraphs(a,b){if(a.type!==b.type){throw new Error(`Cannot merge graphs with different types (${a.type} and ${b.type})`)}switch(a.type){case "angle":invariant(b.type==="angle");return {...a,...b};case "circle":invariant(b.type==="circle");return {...a,...b};case "linear":invariant(b.type==="linear");return {...a,...b};case "linear-system":invariant(b.type==="linear-system");return {...a,...b};case "none":invariant(b.type==="none");return {...a,...b};case "point":invariant(b.type==="point");return {...a,...b};case "polygon":invariant(b.type==="polygon");return {...a,...b};case "quadratic":invariant(b.type==="quadratic");return {...a,...b};case "ray":invariant(b.type==="ray");return {...a,...b};case "segment":invariant(b.type==="segment");return {...a,...b};case "sinusoid":invariant(b.type==="sinusoid");return {...a,...b};case "absolute-value":invariant(b.type==="absolute-value");return {...a,...b};case "exponential":invariant(b.type==="exponential");return {...a,...b};case "tangent":invariant(b.type==="tangent");return {...a,...b};case "logarithm":invariant(b.type==="logarithm");return {...a,...b};case "vector":invariant(b.type==="vector");return {...a,...b};default:throw new UnreachableCaseError(a)}}function withShowPointLabels(graph,showPointLabels){switch(graph.type){case "absolute-value":case "angle":case "circle":case "exponential":case "linear":case "linear-system":case "logarithm":case "point":case "polygon":case "quadratic":case "ray":case "segment":case "sinusoid":case "tangent":return {...graph,showPointLabels};case "none":case "vector":return undefined;default:throw new UnreachableCaseError(graph)}}
|
|
1807
|
+
const InteractiveGraph=InteractiveGraphWidget.widget;class InteractiveGraphEditor extends React.Component{handleChange(changes){this.props.onChange({step:this.props.step,gridStep:this.props.gridStep,snapStep:this.props.snapStep,backgroundImage:this.props.backgroundImage,markings:this.props.markings,labels:this.props.labels,labelLocation:this.props.labelLocation,showAxisArrows:this.props.showAxisArrows,showAxisTicks:this.props.showAxisTicks,showProtractor:this.props.showProtractor,showRuler:this.props.showRuler,showTooltips:this.props.showTooltips,rulerLabel:this.props.rulerLabel,rulerTicks:this.props.rulerTicks,range:this.props.range,graph:this.props.graph,correct:this.props.correct,lockedFigures:this.props.lockedFigures,fullGraphAriaLabel:this.props.fullGraphAriaLabel,fullGraphAriaDescription:this.props.fullGraphAriaDescription,...changes});}handleSettingsChange({valid,...settings}){this.setState({valid});if(valid===true){this.handleChange(settings);}}serialize(){const json=_.pick(this.props,"step","backgroundImage","markings","labels","labelLocation","showProtractor","showTooltips","range","showAxisArrows","showAxisTicks","gridStep","snapStep","lockedFigures","fullGraphAriaLabel","fullGraphAriaDescription");const graph=this.refs.graph;if(graph){const correct=graph&&graph.getUserInput();_.extend(json,{graph:{type:correct.type,startCoords:getStartCoords(this.props.graph),..."pointLabels"in this.props.graph&&this.props.graph.pointLabels?{pointLabels:this.props.graph.pointLabels}:{},..."showPointLabels"in this.props.graph&&this.props.graph.showPointLabels?{showPointLabels:this.props.graph.showPointLabels}:{}},correct:correct});_.each(["allowReflexAngles","angleOffsetDeg","numPoints","numSides","numSegments","showAngles","showSides","snapTo","snapDegrees"],function(key){if(_.has(correct,key)){json.graph[key]=correct[key];}});}else {_.extend(json,{graph:this.props.graph,correct:this.props.correct});}return json}render(){let graph;let equationString;const gridStep=this.props.gridStep||Util.getGridStep(this.props.range,this.props.step,interactiveSizes.defaultBoxSize);const snapStep=this.props.snapStep||Util.snapStepFromGridStep(gridStep);const sizeClass=containerSizeClass.SMALL;if(this.state.valid===true){const correct=this.props.correct.type===this.props.graph?.type?this.props.correct:this.props.graph;const graphProps={ref:"graph",options:{range:this.props.range,showAxisArrows:this.props.showAxisArrows,showAxisTicks:this.props.showAxisTicks,labels:this.props.labels,labelLocation:this.props.labelLocation,step:this.props.step,gridStep:gridStep,snapStep:snapStep,backgroundImage:this.props.backgroundImage,markings:this.props.markings,showProtractor:this.props.showProtractor,showTooltips:this.props.showTooltips,lockedFigures:this.props.lockedFigures,fullGraphAriaLabel:this.props.fullGraphAriaLabel,fullGraphAriaDescription:this.props.fullGraphAriaDescription},static:this.props.apiOptions?.editingDisabled??false,trackInteraction:function(){},userInput:this.props.static===true&&correct!=null&&"showPointLabels"in correct?{...correct,showPointLabels:false}:correct,handleUserInput:newGraph=>{let correct=this.props.correct;invariant(newGraph!=null);if(this.props.static===true&&newGraph!=null&&"showPointLabels"in newGraph){newGraph={...newGraph,showPointLabels:"showPointLabels"in correct?correct.showPointLabels:undefined};}if(correct.type===newGraph.type){correct=mergeGraphs(correct,newGraph);}else {correct=newGraph;}this.handleChange({correct:correct,graph:this.props.graph});}};graph=jsxRuntimeExports.jsx(InteractiveGraph,{...graphProps,containerSizeClass:sizeClass,apiOptions:{...this.props.apiOptions,isMobile:false}});equationString=InteractiveGraph.getEquationString(graphProps);}else {graph=jsxRuntimeExports.jsx("div",{className:"perseus-error",children:this.state.valid});}return jsxRuntimeExports.jsx(Id,{children:graphId=>jsxRuntimeExports.jsxs(View,{children:[jsxRuntimeExports.jsx(LabeledRow,{label:"Answer type",labelSize:"medium",children:jsxRuntimeExports.jsx(GraphTypeSelector,{disabled:this.props.apiOptions?.editingDisabled??false,graphType:this.props.graph?.type??"none",onChange:type=>{this.handleChange({graph:{type},correct:{type}});}})}),jsxRuntimeExports.jsx(InteractiveGraphDescription,{ariaLabelValue:this.props.fullGraphAriaLabel??"",ariaDescriptionValue:this.props.fullGraphAriaDescription??"",editingDisabled:this.props.apiOptions?.editingDisabled??false,onChange:options=>this.handleChange(options)}),jsxRuntimeExports.jsx(InteractiveGraphCorrectAnswer,{id:graphId,equationString:equationString,children:graph}),this.props.correct?.type==="angle"&&jsxRuntimeExports.jsx(AngleAnswerOptions,{correct:this.props.correct,graph:this.props.graph,onChange:options=>this.handleChange(options)}),this.props.correct?.type==="point"&&jsxRuntimeExports.jsx(GraphPointsCountSelector,{correct:this.props.correct,graph:this.props.graph,onChange:options=>this.handleChange(options)}),this.props.correct?.type==="polygon"&&jsxRuntimeExports.jsx(PolygonAnswerOptions,{correct:this.props.correct,graph:this.props.graph,onChange:options=>this.handleChange(options)}),this.props.correct?.type==="vector"&&jsxRuntimeExports.jsx(VectorAnswerOptions,{correct:this.props.correct,onChange:options=>this.handleChange(options)}),this.props.correct?.type==="segment"&&jsxRuntimeExports.jsx(SegmentCountSelector,{correct:this.props.correct,graph:this.props.graph,onChange:options=>this.handleChange(options)}),!this.props.static&&this.props.graph?.type&&this.props.graph.type!=="vector"&&this.props.graph.type!=="none"&&jsxRuntimeExports.jsx(ShowPointLabelsToggle,{showPointLabels:this.props.graph.showPointLabels===true,pointLabels:this.props.graph.pointLabels,onChange:this.changeShowPointLabels}),this.props.graph?.type&&shouldShowStartCoordsUI(this.props.graph,this.props.static)&&jsxRuntimeExports.jsx(StartCoordsSettings,{...this.props.graph,range:this.props.range,step:this.props.step,editingDisabled:this.props.apiOptions?.editingDisabled??false,onChange:this.changeStartCoords,onChangePointLabels:this.changePointLabels}),jsxRuntimeExports.jsx(InteractiveGraphSRTree,{graphId:graphId,correct:this.props.correct,fullGraphAriaLabel:this.props.fullGraphAriaLabel,fullGraphAriaDescription:this.props.fullGraphAriaDescription,lockedFigures:this.props.lockedFigures,editingDisabled:this.props.apiOptions?.editingDisabled??false}),jsxRuntimeExports.jsx(InteractiveGraphSettings,{box:getInteractiveBoxFromSizeClass(sizeClass),range:this.props.range,showAxisArrows:this.props.showAxisArrows,showAxisTicks:this.props.showAxisTicks,labels:this.props.labels,labelLocation:this.props.labelLocation,step:this.props.step,gridStep:gridStep,snapStep:snapStep,valid:this.state.valid,backgroundImage:this.props.backgroundImage,markings:this.props.markings,showProtractor:this.props.showProtractor,showTooltips:this.props.showTooltips,onChange:settings=>this.handleSettingsChange(settings),apiOptions:this.props.apiOptions}),jsxRuntimeExports.jsx(LockedFiguresSection,{figures:this.props.lockedFigures,onChange:options=>this.handleChange(options),apiOptions:this.props.apiOptions})]})})}constructor(...args){super(...args),this.displayName="InteractiveGraphEditor",this.className="perseus-widget-interactive-graph",this.state={valid:true},this.changeStartCoords=coords=>{if(!this.props.graph?.type){return}const graph={...this.props.graph,startCoords:coords};this.handleChange({graph:graph});},this.changePointLabels=pointLabels=>{const next=reshapePointLabelsForGraphType(pointLabels,this.props.graph,this.props.correct);if(next){this.handleChange(next);}},this.changeShowPointLabels=showPointLabels=>{const{graph,correct}=this.props;if(graph===undefined||correct===undefined){return}const newGraph=withShowPointLabels(graph,showPointLabels);const newCorrect=withShowPointLabels(correct,showPointLabels);if(newGraph===undefined||newCorrect===undefined){return}this.handleChange({graph:newGraph,correct:newCorrect});},this.getSaveWarnings=()=>{const issues=[];for(const figure of this.props.lockedFigures??[]){if(figure.type==="line"&&vector.equal(figure.points[0].coord,figure.points[1].coord)){issues.push("The line cannot have length 0.");}}if(this.props.graph?.type==="polygon"&&this.props.graph.numSides==="unlimited"&&this.props.graph.coords===null){issues.push("Polygon must be closed.");}if(this.props.graph?.type==="exponential"&&this.props.graph.startCoords!=null){const{coords,asymptote}=this.props.graph.startCoords;const asymptoteY=asymptote;const minY=Math.min(coords[0][1],coords[1][1]);const maxY=Math.max(coords[0][1],coords[1][1]);if(asymptoteY>=minY&&asymptoteY<=maxY){issues.push("The exponential start asymptote must not fall between or on the curve's start points.");}}if(this.props.graph?.type==="logarithm"&&this.props.graph.startCoords!=null){const{coords,asymptote}=this.props.graph.startCoords;const asymptoteX=asymptote;const minX=Math.min(coords[0][0],coords[1][0]);const maxX=Math.max(coords[0][0],coords[1][0]);if(asymptoteX>=minX&&asymptoteX<=maxX){issues.push("The logarithm start asymptote must not fall between or on the curve's start points.");}}return issues};}}InteractiveGraphEditor.bestPractices={url:"https://khanacademy.atlassian.net/wiki/spaces/LC/pages/3295281289/Interactive+Graph+Widget#Adding-a-new-Interactive-Graph-Widget",label:"Interactive Graph best practices"};InteractiveGraphEditor.defaultProps={...interactiveGraphLogic.defaultWidgetOptions};function mergeGraphs(a,b){if(a.type!==b.type){throw new Error(`Cannot merge graphs with different types (${a.type} and ${b.type})`)}switch(a.type){case "angle":invariant(b.type==="angle");return {...a,...b};case "circle":invariant(b.type==="circle");return {...a,...b};case "linear":invariant(b.type==="linear");return {...a,...b};case "linear-system":invariant(b.type==="linear-system");return {...a,...b};case "none":invariant(b.type==="none");return {...a,...b};case "point":invariant(b.type==="point");return {...a,...b};case "polygon":invariant(b.type==="polygon");return {...a,...b};case "quadratic":invariant(b.type==="quadratic");return {...a,...b};case "ray":invariant(b.type==="ray");return {...a,...b};case "segment":invariant(b.type==="segment");return {...a,...b};case "sinusoid":invariant(b.type==="sinusoid");return {...a,...b};case "absolute-value":invariant(b.type==="absolute-value");return {...a,...b};case "exponential":invariant(b.type==="exponential");return {...a,...b};case "tangent":invariant(b.type==="tangent");return {...a,...b};case "logarithm":invariant(b.type==="logarithm");return {...a,...b};case "vector":invariant(b.type==="vector");return {...a,...b};default:throw new UnreachableCaseError(a)}}function withShowPointLabels(graph,showPointLabels){switch(graph.type){case "absolute-value":case "angle":case "circle":case "exponential":case "linear":case "linear-system":case "logarithm":case "point":case "polygon":case "quadratic":case "ray":case "segment":case "sinusoid":case "tangent":return {...graph,showPointLabels};case "none":case "vector":return undefined;default:throw new UnreachableCaseError(graph)}}
|
|
1809
1808
|
|
|
1810
1809
|
const gray68="#888D93";const gray41="#626569";
|
|
1811
1810
|
|
|
@@ -1877,7 +1876,7 @@ var styles = {"editor":"perseus_nJ-Uq5eT","section":"perseus_vTiphIsj","cards":"
|
|
|
1877
1876
|
|
|
1878
1877
|
const minCards=2;const defaultOptions=sorterLogic.defaultWidgetOptions;const layoutOptions={horizontal:"Horizontal",vertical:"Vertical"};const SorterEditor=React.forwardRef(function SorterEditor({correct=defaultOptions.correct,layout=defaultOptions.layout,padding=defaultOptions.padding,onChange},ref){React.useImperativeHandle(ref,()=>({serialize:()=>{return {correct,layout,padding}},getSaveWarnings:()=>{const warnings=[];if(correct.length<minCards){warnings.push(`Sorter requires at least ${minCards} cards.`);}if(correct.some(card=>card.trim()==="")){warnings.push("Sorter cards cannot be blank.");}return warnings}}),[correct,layout,padding]);const onCardChange=(index,value)=>{const newCorrect=[...correct];newCorrect[index]=value;onChange({correct:newCorrect});};const onAddCard=()=>{if(correct.length>=SORTER_MAX_CARDS){return}onChange({correct:[...correct,""]});};const onMoveCard=(index,offset)=>{const newCorrect=[...correct];const newIndex=index+offset;[newCorrect[index],newCorrect[newIndex]]=[newCorrect[newIndex],newCorrect[index]];onChange({correct:newCorrect});};const onDeleteCard=index=>{onChange({correct:correct.filter((card,i)=>i!==index)});};return jsxRuntimeExports.jsxs(View,{className:styles.editor,children:[jsxRuntimeExports.jsxs(View,{className:styles.section,children:[jsxRuntimeExports.jsxs("div",{children:["Correct answer"," ",jsxRuntimeExports.jsxs(InfoTip,{children:[jsxRuntimeExports.jsx("p",{children:"Enter the correct answer (in the correct order) here. The preview on the right will have the cards in a randomized order, which is how the student will see them."}),jsxRuntimeExports.jsx("p",{children:"For horizontal orientation, the top input represents the leftmost card and the bottom input represents the rightmost card."})]})]}),jsxRuntimeExports.jsx(View,{tag:"ol",className:styles.cards,children:correct.map((card,i)=>jsxRuntimeExports.jsx(CardEditor,{index:i,value:card,isFirst:i===0,isLast:i===correct.length-1,onChange:value=>onCardChange(i,value),onMoveUp:()=>onMoveCard(i,-1),onMoveDown:()=>onMoveCard(i,1),onDelete:()=>onDeleteCard(i)},i))}),jsxRuntimeExports.jsx(Button,{kind:"tertiary",startIcon:plusCircle,className:styles.addCard,disabled:correct.length>=SORTER_MAX_CARDS,onClick:onAddCard,children:"Add a card"})]}),jsxRuntimeExports.jsx(LabeledField,{label:"Layout",field:jsxRuntimeExports.jsx(TypedSingleSelect,{options:layoutOptions,selectedValue:layout,onChange:newLayout=>onChange({layout:newLayout})}),contextLabel:jsxRuntimeExports.jsx(InfoTip,{children:jsxRuntimeExports.jsx("p",{children:"Use the horizontal layout for short text and small images. The vertical layout is best for longer text and larger images."})}),styles:{contextLabel:{marginInlineEnd:"auto"}}}),layout==="horizontal"&&correct.length>SORTER_MAX_HORIZONTAL_CARDS&&jsxRuntimeExports.jsx(Banner,{kind:"warning",text:`Sorter widget with more than ${SORTER_MAX_HORIZONTAL_CARDS} options will display vertically, even if the layout is set to horizontal.`}),jsxRuntimeExports.jsxs("div",{className:styles.row,children:[jsxRuntimeExports.jsx(Checkbox$1,{label:"Padding",checked:padding,onChange:value=>{onChange({padding:value});}}),jsxRuntimeExports.jsx(InfoTip,{children:jsxRuntimeExports.jsx("p",{children:"Padding is good for text, but not needed for images."})})]})]})});var SorterEditor$1 = Object.assign(SorterEditor,{defaultProps:defaultOptions});
|
|
1879
1878
|
|
|
1880
|
-
const{NumberInput}=components;const Table=TableWidget.widget;class TableEditor extends React.Component{render(){const tableProps={options:{headers:this.props.headers,rows:this.props.rows,columns:this.props.columns,answers:this.props.answers},onChange:this.props.onChange,userInput:this.props.answers,handleUserInput:userInput=>{if(this.props.apiOptions?.editingDisabled){return}this.props.onChange({answers:userInput});},apiOptions:this.props.apiOptions,editableHeaders:true,onFocus:()=>{},onBlur:()=>{},trackInteraction:()=>{},Editor:Editor};return jsxRuntimeExports.jsxs("div",{children:[jsxRuntimeExports.jsx("div",{className:"perseus-widget-row",children:jsxRuntimeExports.jsxs("label",{children:["Number of columns:"," ",jsxRuntimeExports.jsx(NumberInput,{ref:this.numberOfColumns,value:this.props.columns,onChange:val=>{if(val){this.onSizeInput(this.props.rows,val);}},useArrowKeys:true})]})}),jsxRuntimeExports.jsx("div",{className:"perseus-widget-row",children:jsxRuntimeExports.jsxs("label",{children:["Number of rows:"," ",jsxRuntimeExports.jsx(NumberInput,{ref:"numberOfRows",value:this.props.rows,onChange:val=>{if(val){this.onSizeInput(val,this.props.columns);}},useArrowKeys:true})]})}),jsxRuntimeExports.jsxs("div",{children:[" ","Table of answers:"," ",jsxRuntimeExports.jsx(InfoTip,{children:jsxRuntimeExports.jsx("p",{children:"The student has to fill out all cells in the table. For partially filled tables create a table using the template, and insert text input boxes as desired."})})]}),jsxRuntimeExports.jsx("div",{children:jsxRuntimeExports.jsx(Table,{...tableProps})})]})}constructor(...args){super(...args),this.numberOfColumns=React.createRef(),this.focus=()=>{this.numberOfColumns.current?.focus();},this.onSizeInput=(numRawRows,numRawColumns)=>{let rows=+numRawRows||0;let columns=+numRawColumns||0;rows=Math.min(Math.max(1,rows),30);columns=Math.min(Math.max(1,columns),6);const oldColumns=this.props.columns;const oldRows=this.props.rows;const answers=this.props.answers;if(rows<=oldRows){answers.length=rows;}else {_(rows-oldRows).times(function(){answers.push(Util.stringArrayOfSize(oldColumns));});}function fixColumnSizing(array){if(columns<=oldColumns){array.length=columns;}else {_(columns-oldColumns).times(function(){array.push("");});}}const headers=this.props.headers;fixColumnSizing(headers);_.each(answers,fixColumnSizing);this.props.onChange({rows:rows,columns:columns,answers:answers,headers:headers});},this.serialize=()=>{const json=_.pick(this.props,"headers","rows","columns");return _.extend({},json,{answers:this.props.answers.map(_.clone)})};}}TableEditor.
|
|
1879
|
+
const{NumberInput}=components;const Table=TableWidget.widget;class TableEditor extends React.Component{render(){const tableProps={options:{headers:this.props.headers,rows:this.props.rows,columns:this.props.columns,answers:this.props.answers},onChange:this.props.onChange,userInput:this.props.answers,handleUserInput:userInput=>{if(this.props.apiOptions?.editingDisabled){return}this.props.onChange({answers:userInput});},apiOptions:this.props.apiOptions,editableHeaders:true,onFocus:()=>{},onBlur:()=>{},trackInteraction:()=>{},Editor:Editor};return jsxRuntimeExports.jsxs("div",{children:[jsxRuntimeExports.jsx("div",{className:"perseus-widget-row",children:jsxRuntimeExports.jsxs("label",{children:["Number of columns:"," ",jsxRuntimeExports.jsx(NumberInput,{ref:this.numberOfColumns,value:this.props.columns,onChange:val=>{if(val){this.onSizeInput(this.props.rows,val);}},useArrowKeys:true})]})}),jsxRuntimeExports.jsx("div",{className:"perseus-widget-row",children:jsxRuntimeExports.jsxs("label",{children:["Number of rows:"," ",jsxRuntimeExports.jsx(NumberInput,{ref:"numberOfRows",value:this.props.rows,onChange:val=>{if(val){this.onSizeInput(val,this.props.columns);}},useArrowKeys:true})]})}),jsxRuntimeExports.jsxs("div",{children:[" ","Table of answers:"," ",jsxRuntimeExports.jsx(InfoTip,{children:jsxRuntimeExports.jsx("p",{children:"The student has to fill out all cells in the table. For partially filled tables create a table using the template, and insert text input boxes as desired."})})]}),jsxRuntimeExports.jsx("div",{children:jsxRuntimeExports.jsx(Table,{...tableProps})})]})}constructor(...args){super(...args),this.numberOfColumns=React.createRef(),this.focus=()=>{this.numberOfColumns.current?.focus();},this.onSizeInput=(numRawRows,numRawColumns)=>{let rows=+numRawRows||0;let columns=+numRawColumns||0;rows=Math.min(Math.max(1,rows),30);columns=Math.min(Math.max(1,columns),6);const oldColumns=this.props.columns;const oldRows=this.props.rows;const answers=this.props.answers;if(rows<=oldRows){answers.length=rows;}else {_(rows-oldRows).times(function(){answers.push(Util.stringArrayOfSize(oldColumns));});}function fixColumnSizing(array){if(columns<=oldColumns){array.length=columns;}else {_(columns-oldColumns).times(function(){array.push("");});}}const headers=this.props.headers;fixColumnSizing(headers);_.each(answers,fixColumnSizing);this.props.onChange({rows:rows,columns:columns,answers:answers,headers:headers});},this.serialize=()=>{const json=_.pick(this.props,"headers","rows","columns");return _.extend({},json,{answers:this.props.answers.map(_.clone)})};}}TableEditor.defaultProps=tableLogic.defaultWidgetOptions;
|
|
1881
1880
|
|
|
1882
1881
|
const KA_VIDEO_URL=/khanacademy\.org\/.*\/v\/(.*)$/;function getSlugFromUrl(url){const match=KA_VIDEO_URL.exec(url);if(match){return match[1]}return url}function VideoSettings(props){const[inputValue,setInputValue]=React.useState(props.location);function handleUrlChange(url){props.onChange({location:getSlugFromUrl(url)});}return jsxRuntimeExports.jsx(LabeledField,{label:"KA Video Slug",description:"KA video URLs will be converted to just the slug.",field:jsxRuntimeExports.jsx(TextArea,{value:inputValue,onChange:setInputValue,onBlur:e=>handleUrlChange(e.target.value),autoResize:true})})}
|
|
1883
1882
|
|