Skip to content

Commit

Permalink
Revert "Input Number Deprecation and Conversion into Numeric Input (#…
Browse files Browse the repository at this point in the history
…1731)"

This reverts commit 27126aa.
  • Loading branch information
SonicScrewdriver committed Nov 22, 2024
1 parent fbcea00 commit fd7caeb
Show file tree
Hide file tree
Showing 42 changed files with 2,476 additions and 2,784 deletions.
40 changes: 2 additions & 38 deletions packages/perseus-editor/src/__stories__/article-editor.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,50 +5,14 @@ import {useRef, useState} from "react";
import ArticleEditor from "../article-editor";
import {registerAllWidgetsAndEditorsForTesting} from "../util/register-all-widgets-and-editors-for-testing";

import type {PerseusRenderer} from "@khanacademy/perseus";

registerAllWidgetsAndEditorsForTesting();

export default {
title: "PerseusEditor/ArticleEditor",
};
const articleSectionWithInputNumber: PerseusRenderer = {
content:
"### Practice Problem\n\n$8\\cdot(11i+2)=$ [[☃ input-number 1]]. Also [[☃ input-number 2]] \n*.*",
images: {},
widgets: {
"input-number 1": {
type: "input-number",
graded: true,
alignment: "default",
options: {
maxError: 0.1,
inexact: false,
value: 0.4,
simplify: "optional",
answerType: "rational",
size: "normal",
},
version: {major: 1, minor: 0},
},
"input-number 2": {
type: "input-number",
graded: true,
alignment: "default",
options: {
maxError: 0.1,
inexact: false,
value: 0.5,
simplify: "optional",
answerType: "rational",
size: "normal",
},
version: {major: 1, minor: 0},
},
},
};

export const Base = (): React.ReactElement => {
const [state, setState] = useState(articleSectionWithInputNumber);
const [state, setState] = useState();
const articleEditorRef = useRef();

function handleChange(value) {
Expand Down
38 changes: 0 additions & 38 deletions packages/perseus-editor/src/__stories__/editor-page.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,50 +4,12 @@ import {registerAllWidgetsAndEditorsForTesting} from "../util/register-all-widge

import EditorPageWithStorybookPreview from "./editor-page-with-storybook-preview";

import type {InputNumberWidget, PerseusRenderer} from "@khanacademy/perseus";

registerAllWidgetsAndEditorsForTesting(); // SIDE_EFFECTY!!!! :cry:

export default {
title: "PerseusEditor/EditorPage",
};

const question1: PerseusRenderer = {
content:
"Denis baked a peach pie and cut it into $3$ equal-sized pieces. Denis's dad eats $1$ section of the pie. \n\n**What fraction of the pie did Denis's dad eat?** \n![](https://ka-perseus-graphie.s3.amazonaws.com/74a2b7583a2c26ebfb3ad714e29867541253fc97.png) \n[[\u2603 input-number 1]] \n\n\n\n",
images: {
"https://ka-perseus-graphie.s3.amazonaws.com/74a2b7583a2c26ebfb3ad714e29867541253fc97.png":
{
width: 200,
height: 200,
},
},
widgets: {
"input-number 1": {
version: {
major: 0,
minor: 0,
},
type: "input-number",
graded: true,
alignment: "default",
options: {
maxError: 0.1,
inexact: false,
value: 0.5,
simplify: "optional",
answerType: "rational",
size: "normal",
},
} as InputNumberWidget,
},
};

export const Demo = (): React.ReactElement => {
return <EditorPageWithStorybookPreview />;
};

// Used to test that Input Numbers are being automatically converted to Numeric Inputs
export const InputNumberDemo = (): React.ReactElement => {
return <EditorPageWithStorybookPreview question={question1} />;
};
37 changes: 15 additions & 22 deletions packages/perseus-editor/src/__tests__/traversal.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,31 +35,24 @@ const missingOptions = {
const clonedMissingOptions = JSON.parse(JSON.stringify(missingOptions));

const sampleOptions = {
content: "[[☃ numeric-input 1]]",
content: "[[☃ input-number 1]]",
images: {},
widgets: {
"numeric-input 1": {
type: "numeric-input",
"input-number 1": {
type: "input-number",
graded: true,
static: false,
options: {
answers: [
{
value: 0,
status: "correct",
message: "",
simplify: "required",
strict: true,
maxError: 0.1,
},
],
value: "0",
simplify: "required",
size: "normal",
coefficient: false,
labelText: "",
inexact: false,
maxError: 0.1,
answerType: "number",
rightAlign: false,
},
static: false,
version: {
major: 1,
major: 0,
minor: 0,
},
alignment: "default",
Expand Down Expand Up @@ -265,7 +258,7 @@ describe("Traversal", () => {
readContent = content;
});

expect(readContent).toBe("[[☃ numeric-input 1]]");
expect(readContent).toBe("[[☃ input-number 1]]");
assertNonMutative();
});

Expand All @@ -287,7 +280,7 @@ describe("Traversal", () => {
widgetMap[widgetInfo.type] = (widgetMap[widgetInfo.type] || 0) + 1;
});
expect(widgetMap).toEqual({
"numeric-input": 1,
"input-number": 1,
});
assertNonMutative();
});
Expand All @@ -301,9 +294,9 @@ describe("Traversal", () => {
expect(newOptions).toEqual(
_.extend({}, sampleOptions, {
widgets: {
"numeric-input 1": _.extend(
"input-number 1": _.extend(
{},
sampleOptions.widgets["numeric-input 1"],
sampleOptions.widgets["input-number 1"],
{graded: false},
),
},
Expand All @@ -319,7 +312,7 @@ describe("Traversal", () => {
});
});
expect(newOptions.content).toBe(
"[[☃ numeric-input 1]]\n\nnew content!",
"[[☃ input-number 1]]\n\nnew content!",
);
expect(newOptions.widgets).toEqual(sampleOptions.widgets);
assertNonMutative();
Expand Down
59 changes: 27 additions & 32 deletions packages/perseus-editor/src/article-editor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,18 +19,18 @@ import {
iconCircleArrowUp,
iconPlus,
} from "./styles/icon-paths";
import {convertDeprecatedWidgets} from "./util/deprecated-widgets/modernize-widgets-utils";

import type {
APIOptions,
Changeable,
ImageUploader,
PerseusRenderer,
} from "@khanacademy/perseus";
import type {APIOptions, Changeable, ImageUploader} from "@khanacademy/perseus";

const {HUD, InlineIcon} = components;

type JsonType = PerseusRenderer | PerseusRenderer[];
type RendererProps = {
content?: string;
widgets?: any;
images?: any;
};

type JsonType = RendererProps | ReadonlyArray<RendererProps>;
type DefaultProps = {
contentPaths?: ReadonlyArray<string>;
json: JsonType;
Expand All @@ -50,27 +50,20 @@ type Props = DefaultProps & {

type State = {
highlightLint: boolean;
json: JsonType;
};
export default class ArticleEditor extends React.Component<Props, State> {
static defaultProps: DefaultProps = {
contentPaths: [],
json: [],
json: [{}],
mode: "edit",
screen: "desktop",
sectionImageUploadGenerator: () => <span />,
useNewStyles: false,
};

constructor(props: Props) {
super(props);
this.state = {
highlightLint: true,
json: Array.isArray(props.json)
? props.json.map(convertDeprecatedWidgets)
: convertDeprecatedWidgets(props.json as PerseusRenderer),
};
}
state: State = {
highlightLint: true,
};

componentDidMount() {
this._updatePreviewFrames();
Expand Down Expand Up @@ -102,7 +95,7 @@ export default class ArticleEditor extends React.Component<Props, State> {
}
}

_apiOptionsForSection(section: PerseusRenderer, sectionIndex: number): any {
_apiOptionsForSection(section: RendererProps, sectionIndex: number): any {
// eslint-disable-next-line react/no-string-refs
const editor = this.refs[`editor${sectionIndex}`];
return {
Expand All @@ -127,13 +120,10 @@ export default class ArticleEditor extends React.Component<Props, State> {
};
}

_sections(): PerseusRenderer[] {
const sections = Array.isArray(this.state.json)
? this.state.json
: [this.state.json];
return sections.filter(
(section): section is PerseusRenderer => section !== null,
);
_sections(): ReadonlyArray<RendererProps> {
return Array.isArray(this.props.json)
? this.props.json
: [this.props.json];
}

_renderEditor(): React.ReactElement<React.ComponentProps<"div">> {
Expand Down Expand Up @@ -310,13 +300,13 @@ export default class ArticleEditor extends React.Component<Props, State> {
this.props.onChange({json: newJson});
};

_handleEditorChange: (i: number, newProps: PerseusRenderer) => void = (
_handleEditorChange: (i: number, newProps: RendererProps) => void = (
i,
newProps,
) => {
const sections = _.clone(this._sections());
// @ts-expect-error - TS2542 - Index signature in type 'readonly RendererProps[]' only permits reading.
sections[i] = _.extend({}, sections[i], newProps);
this.setState({json: sections});
this.props.onChange({json: sections});
};

Expand All @@ -326,7 +316,9 @@ export default class ArticleEditor extends React.Component<Props, State> {
}
const sections = _.clone(this._sections());
const section = sections[i];
// @ts-expect-error - TS2551 - Property 'splice' does not exist on type 'readonly RendererProps[]'. Did you mean 'slice'?
sections.splice(i, 1);
// @ts-expect-error - TS2551 - Property 'splice' does not exist on type 'readonly RendererProps[]'. Did you mean 'slice'?
sections.splice(i - 1, 0, section);
this.props.onChange({
json: sections,
Expand All @@ -339,7 +331,9 @@ export default class ArticleEditor extends React.Component<Props, State> {
return;
}
const section = sections[i];
// @ts-expect-error - TS2551 - Property 'splice' does not exist on type 'readonly RendererProps[]'. Did you mean 'slice'?
sections.splice(i, 1);
// @ts-expect-error - TS2551 - Property 'splice' does not exist on type 'readonly RendererProps[]'. Did you mean 'slice'?
sections.splice(i + 1, 0, section);
this.props.onChange({
json: sections,
Expand Down Expand Up @@ -371,6 +365,7 @@ export default class ArticleEditor extends React.Component<Props, State> {

_handleRemoveSection(i: number) {
const sections = _.clone(this._sections());
// @ts-expect-error - TS2551 - Property 'splice' does not exist on type 'readonly RendererProps[]'. Did you mean 'slice'?
sections.splice(i, 1);
this.props.onChange({
json: sections,
Expand All @@ -386,7 +381,7 @@ export default class ArticleEditor extends React.Component<Props, State> {
});
}
if (this.props.mode === "preview" || this.props.mode === "json") {
return this.state.json;
return this.props.json;
}
throw new PerseusError(
"Could not serialize; mode " + this.props.mode + " not found",
Expand All @@ -400,7 +395,7 @@ export default class ArticleEditor extends React.Component<Props, State> {
*
* This function can currently only be called in edit mode.
*/
getSaveWarnings(): ReadonlyArray<PerseusRenderer> {
getSaveWarnings(): ReadonlyArray<RendererProps> {
if (this.props.mode !== "edit") {
// TODO(joshuan): We should be able to get save warnings in
// preview mode.
Expand Down Expand Up @@ -435,7 +430,7 @@ export default class ArticleEditor extends React.Component<Props, State> {
<JsonEditor
multiLine={true}
onChange={this._handleJsonChange}
value={this.state.json}
value={this.props.json}
/>
</div>
)}
Expand Down
Loading

0 comments on commit fd7caeb

Please sign in to comment.