diff --git a/.changeset/sour-coats-agree.md b/.changeset/sour-coats-agree.md new file mode 100644 index 0000000000..85ce763ea0 --- /dev/null +++ b/.changeset/sour-coats-agree.md @@ -0,0 +1,6 @@ +--- +"@khanacademy/perseus": patch +"@khanacademy/perseus-editor": patch +--- + +[Interactive Graph Editor] Add the M2b flag in preparation for locked graphs, labels, and polygon markings. diff --git a/packages/perseus-editor/src/__stories__/editor-page.stories.tsx b/packages/perseus-editor/src/__stories__/editor-page.stories.tsx index c31d566a0b..0af4a00cdd 100644 --- a/packages/perseus-editor/src/__stories__/editor-page.stories.tsx +++ b/packages/perseus-editor/src/__stories__/editor-page.stories.tsx @@ -95,6 +95,7 @@ export const MafsWithLockedFiguresCurrent = (): React.ReactElement => { mafs: { ...flags.mafs, "interactive-graph-locked-features-m2": false, + "interactive-graph-locked-features-m2b": false, }, }, }} @@ -152,7 +153,13 @@ export const MafsWithLockedFiguresM2Flag = (): React.ReactElement => { setPreviewDevice(newDevice)} @@ -192,6 +199,62 @@ MafsWithLockedFiguresM2Flag.parameters = { }, }; +export const MafsWithLockedFiguresM2bFlag = (): React.ReactElement => { + const [previewDevice, setPreviewDevice] = + React.useState("phone"); + const [jsonMode, setJsonMode] = React.useState(false); + const [answerArea, setAnswerArea] = React.useState< + PerseusAnswerArea | undefined | null + >(); + const [question, setQuestion] = React.useState( + segmentWithLockedFigures, + ); + const [hints, setHints] = React.useState | undefined>(); + + return ( + setPreviewDevice(newDevice)} + developerMode={true} + jsonMode={jsonMode} + answerArea={answerArea} + question={question} + hints={hints} + frameSource="about:blank" + previewURL="about:blank" + itemId="1" + onChange={(props) => { + onChangeAction(props); + + if ("jsonMode" in props) { + setJsonMode(props.jsonMode); + } + if ("answerArea" in props) { + setAnswerArea(props.answerArea); + } + if ("question" in props) { + setQuestion(props.question); + } + if ("hints" in props) { + setHints(props.hints); + } + }} + /> + ); +}; + +MafsWithLockedFiguresM2bFlag.parameters = { + chromatic: { + // Disabling because this isn't visually testing anything on the + // initial load of the editor page. + disable: true, + }, +}; + export const WithSaveWarnings = (): React.ReactElement => { const [previewDevice, setPreviewDevice] = React.useState("phone"); diff --git a/packages/perseus-editor/src/__stories__/flags-for-api-options.ts b/packages/perseus-editor/src/__stories__/flags-for-api-options.ts index 839cfe5b43..f3f9588120 100644 --- a/packages/perseus-editor/src/__stories__/flags-for-api-options.ts +++ b/packages/perseus-editor/src/__stories__/flags-for-api-options.ts @@ -11,6 +11,7 @@ export const flags = { "linear-system": true, ray: true, "interactive-graph-locked-features-m2": true, + "interactive-graph-locked-features-m2b": true, }, } satisfies APIOptions["flags"]; diff --git a/packages/perseus-editor/src/components/__stories__/locked-figures-section.stories.tsx b/packages/perseus-editor/src/components/__stories__/locked-figures-section.stories.tsx index b58d98f5a7..b09e7f3db8 100644 --- a/packages/perseus-editor/src/components/__stories__/locked-figures-section.stories.tsx +++ b/packages/perseus-editor/src/components/__stories__/locked-figures-section.stories.tsx @@ -33,6 +33,7 @@ export const Controlled: StoryComponentType = { return ( @@ -55,6 +56,7 @@ export const WithProdWidth: StoryComponentType = { diff --git a/packages/perseus-editor/src/components/__tests__/locked-figures-section.test.tsx b/packages/perseus-editor/src/components/__tests__/locked-figures-section.test.tsx index 3e39738eb9..f895e531ac 100644 --- a/packages/perseus-editor/src/components/__tests__/locked-figures-section.test.tsx +++ b/packages/perseus-editor/src/components/__tests__/locked-figures-section.test.tsx @@ -41,7 +41,11 @@ describe("LockedFiguresSection", () => { test("renders", () => { // Arrange, Act render( - , + , { wrapper: RenderStateRoot, }, @@ -54,7 +58,11 @@ describe("LockedFiguresSection", () => { test("renders no expand/collapse button when there are no figures", () => { // Arrange, Act render( - , + , { wrapper: RenderStateRoot, }, @@ -71,6 +79,7 @@ describe("LockedFiguresSection", () => { , { @@ -93,6 +102,7 @@ describe("LockedFiguresSection", () => { , { @@ -117,6 +127,7 @@ describe("LockedFiguresSection", () => { , { @@ -147,6 +158,7 @@ describe("LockedFiguresSection", () => { , { @@ -181,6 +193,7 @@ describe("LockedFiguresSection", () => { render( , @@ -207,6 +220,7 @@ describe("LockedFiguresSection", () => { render( void; }; diff --git a/packages/perseus-editor/src/components/locked-figure-settings.tsx b/packages/perseus-editor/src/components/locked-figure-settings.tsx index 9ca354b459..61fa313d88 100644 --- a/packages/perseus-editor/src/components/locked-figure-settings.tsx +++ b/packages/perseus-editor/src/components/locked-figure-settings.tsx @@ -24,6 +24,9 @@ export type LockedFigureSettingsCommonProps = { // Whether to show the M2 features in the locked figure settings. // TODO(LEMS-2016): Remove this prop once the M2 flag is fully rolled out. showM2Features?: boolean; + // Whether to show the M2b features in the locked figure settings. + // TODO(LEMS-2107): Remove this prop once the M2b flag is fully rolled out. + showM2bFeatures?: boolean; // Movement props /** diff --git a/packages/perseus-editor/src/components/locked-figures-section.tsx b/packages/perseus-editor/src/components/locked-figures-section.tsx index 7770cda492..21d1d3d4e0 100644 --- a/packages/perseus-editor/src/components/locked-figures-section.tsx +++ b/packages/perseus-editor/src/components/locked-figures-section.tsx @@ -22,6 +22,9 @@ type Props = { // Whether to show the M2 features in the locked figure settings. // TODO(LEMS-2016): Remove this prop once the M2 flag is fully rolled out. showM2Features: boolean; + // Whether to show the M2b features in the locked figure settings. + // TODO(LEMS-2107): Remove this prop once the M2b flag is fully rolled out. + showM2bFeatures: boolean; figures?: Array; onChange: (props: Partial) => void; }; @@ -151,6 +154,7 @@ const LockedFiguresSection = (props: Props) => { { const newExpanded = [...expandedStates]; @@ -169,6 +173,7 @@ const LockedFiguresSection = (props: Props) => { diff --git a/packages/perseus-editor/src/widgets/interactive-graph-editor.tsx b/packages/perseus-editor/src/widgets/interactive-graph-editor.tsx index 6a8e9efd21..580a860201 100644 --- a/packages/perseus-editor/src/widgets/interactive-graph-editor.tsx +++ b/packages/perseus-editor/src/widgets/interactive-graph-editor.tsx @@ -611,6 +611,11 @@ class InteractiveGraphEditor extends React.Component { "interactive-graph-locked-features-m2" ] } + showM2bFeatures={ + this.props.apiOptions?.flags?.mafs?.[ + "interactive-graph-locked-features-m2b" + ] + } figures={this.props.lockedFigures} onChange={this.props.onChange} /> diff --git a/packages/perseus/src/types.ts b/packages/perseus/src/types.ts index 733a06fd84..a9da4fb8e0 100644 --- a/packages/perseus/src/types.ts +++ b/packages/perseus/src/types.ts @@ -146,11 +146,16 @@ export const MafsGraphTypeFlags = [ export const InteractiveGraphLockedFeaturesFlags = [ /** - * Enables/Disables Milestone 2 locked features in the new Mafs - * interactive-graph widget (the rest of the figure types: - * ellipses, vectors, polygons, functions, labels). + * Enables/Disables inital Milestone 2 locked features in the new Mafs + * interactive-graph widget (ellipses, vectors, polygons). */ "interactive-graph-locked-features-m2", + /** + * Enables/Disables remaining Milestone 2 locked features in the new Mafs + * interactive-graph widget (the rest of the figure types: + * function plots, labels). + */ + "interactive-graph-locked-features-m2b", ] as const; /**