diff --git a/.changeset/plenty-crews-wink.md b/.changeset/plenty-crews-wink.md new file mode 100644 index 0000000000..9872383722 --- /dev/null +++ b/.changeset/plenty-crews-wink.md @@ -0,0 +1,6 @@ +--- +"@khanacademy/perseus": major +"@khanacademy/perseus-editor": major +--- + +Remove example widgets and their editors diff --git a/packages/perseus-editor/src/all-editors.ts b/packages/perseus-editor/src/all-editors.ts index 672251d673..d399412e74 100644 --- a/packages/perseus-editor/src/all-editors.ts +++ b/packages/perseus-editor/src/all-editors.ts @@ -3,8 +3,6 @@ import CSProgramEditor from "./widgets/cs-program-editor"; import DefinitionEditor from "./widgets/definition-editor"; import DeprecatedStandinEditor from "./widgets/deprecated-standin-editor"; import DropdownEditor from "./widgets/dropdown-editor"; -import ExampleGraphieWidgetEditor from "./widgets/example-graphie-widget-editor"; -import ExampleWidgetEditor from "./widgets/example-widget-editor"; import ExplanationEditor from "./widgets/explanation-editor"; import ExpressionEditor from "./widgets/expression-editor"; import GradedGroupEditor from "./widgets/graded-group-editor"; @@ -31,7 +29,6 @@ import PhetSimulationEditor from "./widgets/phet-simulation-editor"; import PlotterEditor from "./widgets/plotter-editor"; import PythonProgramEditor from "./widgets/python-program-editor"; import RadioEditor from "./widgets/radio/editor"; -import SimpleMarkdownTesterEditor from "./widgets/simple-markdown-tester-editor"; import SorterEditor from "./widgets/sorter-editor"; import TableEditor from "./widgets/table-editor"; import VideoEditor from "./widgets/video-editor"; @@ -41,8 +38,6 @@ export default [ CSProgramEditor, DefinitionEditor, DropdownEditor, - ExampleGraphieWidgetEditor, - ExampleWidgetEditor, ExplanationEditor, ExpressionEditor, GradedGroupEditor, @@ -68,7 +63,6 @@ export default [ PhetSimulationEditor, PlotterEditor, PythonProgramEditor, - SimpleMarkdownTesterEditor, SorterEditor, TableEditor, VideoEditor, diff --git a/packages/perseus-editor/src/all-widgets.ts b/packages/perseus-editor/src/all-widgets.ts deleted file mode 100644 index f517cdd099..0000000000 --- a/packages/perseus-editor/src/all-widgets.ts +++ /dev/null @@ -1,7 +0,0 @@ -import {widgets} from "@khanacademy/perseus"; - -import testingWidgets from "./testing-widgets"; - -import type {WidgetExports} from "@khanacademy/perseus"; - -export default [...widgets, ...testingWidgets] as ReadonlyArray; diff --git a/packages/perseus-editor/src/index.ts b/packages/perseus-editor/src/index.ts index 1f3114764c..14438825fe 100644 --- a/packages/perseus-editor/src/index.ts +++ b/packages/perseus-editor/src/index.ts @@ -16,14 +16,13 @@ export {default as StatefulEditorPage} from "./stateful-editor-page"; import "./styles/perseus-editor.less"; // eslint-disable-next-line import/order -import {Widgets} from "@khanacademy/perseus"; +import {Widgets, widgets} from "@khanacademy/perseus"; import AllEditors from "./all-editors"; -import AllWidgets from "./all-widgets"; Widgets.registerEditors(AllEditors); -Widgets.registerWidgets(AllWidgets); +Widgets.registerWidgets(widgets); Widgets.replaceDeprecatedWidgets(); Widgets.replaceDeprecatedEditors(); -export {AllEditors, AllWidgets}; +export {AllEditors, widgets}; diff --git a/packages/perseus-editor/src/testing-widgets.ts b/packages/perseus-editor/src/testing-widgets.ts deleted file mode 100644 index 7ab0c9fbcf..0000000000 --- a/packages/perseus-editor/src/testing-widgets.ts +++ /dev/null @@ -1,11 +0,0 @@ -import ExampleGraphieWidget from "./widgets/example-graphie-widget"; -import ExampleWidget from "./widgets/example-widget"; -import SimpleMarkdownTester from "./widgets/simple-markdown-tester"; - -import type {WidgetExports} from "@khanacademy/perseus"; - -export default [ - ExampleGraphieWidget, - ExampleWidget, - SimpleMarkdownTester, -] as ReadonlyArray; diff --git a/packages/perseus-editor/src/util/register-all-widgets-and-editors-for-testing.ts b/packages/perseus-editor/src/util/register-all-widgets-and-editors-for-testing.ts index 494ced47a0..25cdd06cd6 100644 --- a/packages/perseus-editor/src/util/register-all-widgets-and-editors-for-testing.ts +++ b/packages/perseus-editor/src/util/register-all-widgets-and-editors-for-testing.ts @@ -3,13 +3,12 @@ * in order for them to work. Requiring this file will register all of the * widgets and editors. */ -import {Widgets} from "@khanacademy/perseus"; +import {Widgets, widgets} from "@khanacademy/perseus"; import allEditors from "../all-editors"; -import allWidgets from "../all-widgets"; export const registerAllWidgetsAndEditorsForTesting = () => { - Widgets.registerWidgets(allWidgets); + Widgets.registerWidgets(widgets); Widgets.registerEditors(allEditors); Widgets.replaceDeprecatedWidgets(); diff --git a/packages/perseus-editor/src/widgets/example-graphie-widget-editor.tsx b/packages/perseus-editor/src/widgets/example-graphie-widget-editor.tsx deleted file mode 100644 index d5078c827b..0000000000 --- a/packages/perseus-editor/src/widgets/example-graphie-widget-editor.tsx +++ /dev/null @@ -1,70 +0,0 @@ -import {Changeable, EditorJsonify} from "@khanacademy/perseus"; -import * as React from "react"; - -import ExampleGraphie from "./example-graphie-widget"; - -const ExampleGraphieWidget = ExampleGraphie.widget; - -type Props = any; - -/** - * This is the widget's editor. This is what shows up on the left side - * of the screen in the demo page. Only the question writer sees this. - */ -class ExampleGraphieWidgetEditor extends React.Component { - static propTypes = { - ...Changeable.propTypes, - }; - - static widgetName = "example-graphie-widget" as const; - - static defaultProps: Props = { - correct: [4, 4], - graph: { - box: [340, 340], - labels: ["x", "y"], - range: [ - [-10, 10], - [-10, 10], - ], - step: [1, 1], - gridStep: [1, 1], - valid: true, - backgroundImage: null, - markings: "grid", - showProtractor: false, - }, - }; - - change: (arg1: any, arg2: any, arg3: any) => any = (...args) => { - return Changeable.change.apply(this, args); - }; - - handleChange: (arg1: any) => void = (newProps) => { - if (newProps.coord) { - // @ts-expect-error - TS2554 - Expected 3 arguments, but got 1. - this.change({ - correct: newProps.coord, - }); - } - }; - - serialize: () => any = () => { - return EditorJsonify.serialize.call(this); - }; - - render(): React.ReactNode { - return ( -
- -
- ); - } -} - -export default ExampleGraphieWidgetEditor; diff --git a/packages/perseus-editor/src/widgets/example-graphie-widget.tsx b/packages/perseus-editor/src/widgets/example-graphie-widget.tsx deleted file mode 100644 index 0ab751147a..0000000000 --- a/packages/perseus-editor/src/widgets/example-graphie-widget.tsx +++ /dev/null @@ -1,176 +0,0 @@ -/* eslint-disable @typescript-eslint/no-unused-vars, react/forbid-prop-types, react/sort-comp */ -/** - * This is an example graphie-using widget - * - * TODO(jack): Add more comments - */ - -import {number as knumber, point as kpoint} from "@khanacademy/kmath"; -import { - components, - Changeable, - Util, - WidgetJsonifyDeprecated, -} from "@khanacademy/perseus"; -import * as React from "react"; -import _ from "underscore"; - -import type { - Coord, - WidgetExports, - PerseusExampleGraphieWidgetOptions, - APIOptionsWithDefaults, -} from "@khanacademy/perseus"; - -const {Graphie} = components; - -// @ts-expect-error - TS2339 - Property 'MovablePoint' does not exist on type 'typeof Graphie'. -const MovablePoint = Graphie.MovablePoint; - -type Props = Changeable.ChangeableProps & { - apiOptions: APIOptionsWithDefaults; - graph: PerseusExampleGraphieWidgetOptions["graph"]; - coord: PerseusExampleGraphieWidgetOptions["coord"]; -}; - -type DefaultProps = { - graph: Props["graph"]; - coord: Props["coord"]; -}; - -/** - * This is the widget's renderer. It shows up in the right column - * in the demo, and is what is visible to users, and where - * users enter their answers. - */ -class ExampleGraphieWidget extends React.Component { - static defaultProps: DefaultProps = { - // We want to allow our coord to be null to test if the - // user has interacted with this widget yet when grading it - coord: null, - graph: { - box: [400, 400], - labels: ["x", "y"], - range: [ - [-10, 10], - [-10, 10], - ], - step: [1, 1], - gridStep: [1, 1], - valid: true, - backgroundImage: null, - markings: "grid", - showProtractor: false, - }, - }; - - /** - * This is the widget's grading function - */ - static validate(state: any, rubric: any): any { - if (state.coord == null) { - return { - type: "invalid", - message: null, - }; - } - if (kpoint.equal(state.coord, rubric.correct)) { - return { - type: "points", - earned: 1, - total: 1, - message: null, - }; - } - return { - type: "points", - earned: 0, - total: 1, - message: null, - }; - } - - getUserInput: () => any = () => { - return WidgetJsonifyDeprecated.getUserInput.call(this); - }; - - render(): React.ReactNode { - return ( - - - - ); - } - - change: (arg1: any, arg2: any, arg3: any) => any = (...args) => { - return Changeable.change.apply(this, args); - }; - - movePoint: (arg1: Coord) => void = (newCoord) => { - // @ts-expect-error - TS2554 - Expected 3 arguments, but got 1. - this.change({ - coord: newCoord, - }); - }; - - _getGridConfig: (arg1: any) => any = (options) => { - return _.map(options.step, function (step, i) { - return Util.gridDimensionConfig( - step, - options.range[i], - options.box[i], - options.gridStep[i], - ); - }); - }; - - setupGraphie: (arg1: any, arg2: any) => any = (graphie, options) => { - const gridConfig = this._getGridConfig(options); - graphie.graphInit({ - range: options.range, - scale: _.pluck(gridConfig, "scale"), - axisArrows: "<->", - labelFormat: function (s) { - return "\\small{" + s + "}"; - }, - gridStep: options.gridStep, - tickStep: _.pluck(gridConfig, "tickStep"), - labelStep: 1, - unityLabels: _.pluck(gridConfig, "unityLabel"), - }); - graphie.label([0, options.range[1][1]], options.labels[1], "above"); - }; - - simpleValidate: (arg1: any) => any = (rubric) => { - return ExampleGraphieWidget.validate(this.getUserInput(), rubric); - }; -} - -/** - * For this widget to work, we must export it. - * We also must import this file in src/all-widgets.js - */ -export default { - name: "example-graphie-widget", - displayName: "Example Graphie Widget", - hidden: true, // Hides this widget from the Perseus.Editor widget select - widget: ExampleGraphieWidget, -} as WidgetExports; diff --git a/packages/perseus-editor/src/widgets/example-widget-editor.tsx b/packages/perseus-editor/src/widgets/example-widget-editor.tsx deleted file mode 100644 index 76f2d53c06..0000000000 --- a/packages/perseus-editor/src/widgets/example-widget-editor.tsx +++ /dev/null @@ -1,62 +0,0 @@ -/* eslint-disable react/sort-comp */ -import {Changeable, EditorJsonify} from "@khanacademy/perseus"; -import * as React from "react"; - -type Props = any; - -/** - * This is the widget's editor. This is what shows up on the left side - * of the screen in the demo. Only the question writer sees this. - */ -class ExampleWidgetEditor extends React.Component { - static propTypes = { - ...Changeable.propTypes, - }; - - static widgetName = "example-widget" as const; - - static defaultProps: Props = { - correct: "", - }; - - input = React.createRef(); - - handleAnswerChange: (arg1: React.ChangeEvent) => void = ( - event, - ) => { - // @ts-expect-error - TS2554 - Expected 3 arguments, but got 1. - this.change({ - correct: event.target.value, - }); - }; - - render(): React.ReactNode { - return ( -
- -
- ); - } - - change: (arg1: any, arg2: any, arg3: any) => any = (...args) => { - return Changeable.change.apply(this, args); - }; - - focus: () => boolean = () => { - this.input.current?.focus(); - return true; - }; - - serialize: () => any = () => { - return EditorJsonify.serialize.call(this); - }; -} - -export default ExampleWidgetEditor; diff --git a/packages/perseus-editor/src/widgets/example-widget.tsx b/packages/perseus-editor/src/widgets/example-widget.tsx deleted file mode 100644 index 1028a6e721..0000000000 --- a/packages/perseus-editor/src/widgets/example-widget.tsx +++ /dev/null @@ -1,158 +0,0 @@ -/* eslint-disable @khanacademy/ts-no-error-suppressions */ -/* eslint-disable react/sort-comp */ -/** - * This is a simple number-entry widget - * It is not as powerful as number-input, but has a simpler, more - * representative structure as an example widget, and is easier to - * test new ideas on. - * - * TODO(jack): Add more comments - */ -import {Changeable} from "@khanacademy/perseus"; -import * as React from "react"; -import _ from "underscore"; - -import type { - WidgetExports, - PerseusExampleWidgetOptions, -} from "@khanacademy/perseus"; - -type Props = Changeable.ChangeableProps & { - value: PerseusExampleWidgetOptions["value"]; -}; - -class TextInput extends React.Component { - input = React.createRef(); - - render(): React.ReactNode { - return ( - - ); - } - - focus = () => { - this.input.current?.focus(); - return true; - }; - - changeValue = (e: any) => { - // Translating from the js event e to the value - // of the textbox to send to onChange - this.props.onChange(e.target.value); - }; -} - -type DefaultProps = { - value: Props["value"]; -}; -/** - * This is the widget's renderer. It shows up in the right column - * in the demo, and is what is visible to users, and where - * users enter their answers. - */ -class ExampleWidget extends React.Component { - static defaultProps: DefaultProps = { - value: "", - }; - - input = React.createRef(); - - /** - * This is the widget's grading function. simpleValidate generally - * defers to this function. - * - * value is usually the result of getUserInput on the widget - * rubric is the result of calling serialize() on the editor - */ - static validate(value: string, rubric: any): any { - if (value === "") { - return { - type: "invalid", - message: - "It looks like you haven't answered all of the " + - "question yet.", - }; - } - if (value === rubric.correct) { - return { - type: "points", - earned: 1, - total: 1, - message: null, - }; - } - return { - type: "points", - earned: 0, - total: 1, - message: null, - }; - } - - /** - * Tell our parent to update our props. - */ - change: (arg1: any, arg2: any, arg3: any) => any = (...args) => { - return Changeable.change.apply(this, args); - }; - - render(): React.ReactNode { - return ( - - ); - } - - getUserInput: () => string = () => { - return this.props.value; - }; - - /** - * Widgets that are focusable should add a focus method that returns - * true if focusing succeeded. The first such widget found will be - * focused on page load. - */ - focus: () => boolean = () => { - this.input.current?.focus(); - return true; - }; - - /** - * simpleValidate is called for grading. Rubric is the result of calling - * getUserInput() on the editor that created this widget. - * - * Should return an object representing the grading result, such as - * { - * type: "points", - * earned: 1, - * total: 1, - * message: null - * } - */ - simpleValidate: (arg1: any) => any = (rubric) => { - return ExampleWidget.validate(this.getUserInput(), rubric); - }; -} - -/** - * For this widget to work, we must import this file in src/all-widgets.js - */ -export default { - name: "example-widget", - displayName: "Example Widget", - - // Tell the renderer what type of `display:` style we would like - // for the component wrapping this one. - defaultAlignment: "inline-block", - - hidden: true, // Hides this widget from the Perseus.Editor widget select - widget: ExampleWidget, -} as WidgetExports; diff --git a/packages/perseus-editor/src/widgets/simple-markdown-tester-editor.tsx b/packages/perseus-editor/src/widgets/simple-markdown-tester-editor.tsx deleted file mode 100644 index db9bf05756..0000000000 --- a/packages/perseus-editor/src/widgets/simple-markdown-tester-editor.tsx +++ /dev/null @@ -1,86 +0,0 @@ -/* eslint-disable @khanacademy/ts-no-error-suppressions */ -/* eslint-disable react/sort-comp */ -/** - * This is the editor for the simple-markdown-tester widget. This is what shows - * up on the left side of the screen in the demo. Only the question writer - * sees this. - */ -import {Changeable, EditorJsonify} from "@khanacademy/perseus"; -import * as React from "react"; - -type TextAreaProps = any; - -class TextArea extends React.Component { - render(): React.ReactNode { - return ( -