@khanacademy/perseus-editor 2.17.0 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,10 @@
1
+ import * as React from "react";
2
+ type Props = {
3
+ onChange: (options: any) => void;
4
+ };
5
+ declare class DeprecatedStandinEditor extends React.Component<Props> {
6
+ static widgetName: "deprecated-standin";
7
+ serialize(): any;
8
+ render(): React.ReactNode;
9
+ }
10
+ export default DeprecatedStandinEditor;
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "description": "Perseus editors",
4
4
  "author": "Khan Academy",
5
5
  "license": "MIT",
6
- "version": "2.17.0",
6
+ "version": "3.0.0",
7
7
  "publishConfig": {
8
8
  "access": "public"
9
9
  },
@@ -25,7 +25,7 @@
25
25
  "@khanacademy/kas": "^0.3.7",
26
26
  "@khanacademy/kmath": "^0.1.8",
27
27
  "@khanacademy/math-input": "^16.5.0",
28
- "@khanacademy/perseus": "^17.8.0",
28
+ "@khanacademy/perseus": "^18.0.0",
29
29
  "@khanacademy/perseus-core": "1.4.1"
30
30
  },
31
31
  "devDependencies": {
@@ -1,6 +1,7 @@
1
1
  import CategorizerEditor from "./widgets/categorizer-editor";
2
2
  import CSProgramEditor from "./widgets/cs-program-editor";
3
3
  import DefinitionEditor from "./widgets/definition-editor";
4
+ import DeprecatedStandinEditor from "./widgets/deprecated-standin-editor";
4
5
  import DropdownEditor from "./widgets/dropdown-editor";
5
6
  import ExampleGraphieWidgetEditor from "./widgets/example-graphie-widget-editor";
6
7
  import ExampleWidgetEditor from "./widgets/example-widget-editor";
@@ -80,4 +81,5 @@ export default [
80
81
  UnitEditor,
81
82
  VideoEditor,
82
83
  RadioEditor,
84
+ DeprecatedStandinEditor,
83
85
  ];
@@ -10,33 +10,33 @@ import _ from "underscore";
10
10
 
11
11
  import SectionControlButton from "./section-control-button";
12
12
 
13
- import type {Alignment, WidgetInfo} from "@khanacademy/perseus";
13
+ import type {Alignment, PerseusWidget} from "@khanacademy/perseus";
14
14
 
15
- const {InlineIcon, PropCheckBox} = components;
15
+ const {InlineIcon} = components;
16
16
  const {iconChevronDown, iconChevronRight, iconTrash} = icons;
17
17
 
18
18
  type WidgetEditorProps = {
19
19
  // Unserialized props
20
20
  id: string;
21
21
  onChange: (
22
- widgetInfo: WidgetInfo,
22
+ widgetInfo: PerseusWidget,
23
23
  cb?: () => unknown,
24
24
  silent?: boolean,
25
25
  ) => unknown;
26
26
  onRemove: () => unknown;
27
27
  apiOptions: any;
28
- } & WidgetInfo;
28
+ } & PerseusWidget;
29
29
 
30
30
  type WidgetEditorState = {
31
31
  showWidget: boolean;
32
- widgetInfo: WidgetInfo;
32
+ widgetInfo: PerseusWidget;
33
33
  };
34
34
 
35
- const _upgradeWidgetInfo = (props: WidgetEditorProps): React.ReactElement => {
35
+ const _upgradeWidgetInfo = (props: WidgetEditorProps): PerseusWidget => {
36
36
  // We can't call serialize here because this.refs.widget
37
37
  // doesn't exist before this component is mounted.
38
38
  const filteredProps = _.omit(props, WIDGET_PROP_DENYLIST);
39
- // @ts-expect-error - TS2322 - Type 'PerseusWidget' is not assignable to type 'ReactElement<any, string | JSXElementConstructor<any>>'. | TS2345 - Argument of type 'Partial<{ id: string; onChange: (widgetInfo: PerseusWidget, cb?: (() => unknown) | undefined, silent?: boolean | undefined) => unknown; onRemove: () => unknown; apiOptions: any; } & CategorizerWidget & { ...; }> | ... 38 more ... | Partial<...>' is not assignable to parameter of type 'PerseusWidget'.
39
+ // @ts-expect-error TS(2345) Type '"categorizer" | undefined' is not assignable to type '"deprecated-standin"'.
40
40
  return Widgets.upgradeWidgetInfoToLatestVersion(filteredProps);
41
41
  };
42
42
 
@@ -53,14 +53,12 @@ class WidgetEditor extends React.Component<
53
53
  super(props);
54
54
  this.state = {
55
55
  showWidget: false,
56
- // @ts-expect-error - TS2322 - Type 'ReactElement<any, any> | null' is not assignable to type 'PerseusWidget'.
57
56
  widgetInfo: _upgradeWidgetInfo(props),
58
57
  };
59
58
  }
60
59
 
61
60
  // eslint-disable-next-line react/no-unsafe
62
61
  UNSAFE_componentWillReceiveProps(nextProps: WidgetEditorProps) {
63
- // @ts-expect-error - TS2322 - Type 'ReactElement<any, any> | null' is not assignable to type 'PerseusWidget'.
64
62
  this.setState({widgetInfo: _upgradeWidgetInfo(nextProps)});
65
63
  }
66
64
 
@@ -77,7 +75,7 @@ class WidgetEditor extends React.Component<
77
75
  const newWidgetInfo = Object.assign(
78
76
  {},
79
77
  this.state.widgetInfo,
80
- ) as WidgetInfo;
78
+ ) as PerseusWidget;
81
79
  newWidgetInfo.options = Object.assign(
82
80
  // eslint-disable-next-line react/no-string-refs
83
81
  // @ts-expect-error - TS2339 - Property 'serialize' does not exist on type 'ReactInstance'.
@@ -91,7 +89,7 @@ class WidgetEditor extends React.Component<
91
89
  e.preventDefault();
92
90
  const newWidgetInfo = Object.assign({}, this.state.widgetInfo, {
93
91
  static: !this.state.widgetInfo.static,
94
- }) as WidgetInfo;
92
+ }) as PerseusWidget;
95
93
  this.props.onChange(newWidgetInfo);
96
94
  };
97
95
 
@@ -100,7 +98,7 @@ class WidgetEditor extends React.Component<
100
98
  const newWidgetInfo = Object.assign(
101
99
  {},
102
100
  this.state.widgetInfo,
103
- ) as WidgetInfo;
101
+ ) as PerseusWidget;
104
102
  newWidgetInfo.alignment = newAlignment;
105
103
  this.props.onChange(newWidgetInfo);
106
104
  };
@@ -145,15 +143,6 @@ class WidgetEditor extends React.Component<
145
143
 
146
144
  const supportsStaticMode = Widgets.supportsStaticMode(widgetInfo.type);
147
145
 
148
- const isUngradedEnabled = widgetInfo.type === "transformer";
149
- const gradedPropBox = (
150
- <PropCheckBox
151
- label="Graded:"
152
- graded={widgetInfo.graded}
153
- onChange={this.props.onChange}
154
- />
155
- );
156
-
157
146
  return (
158
147
  <div className="perseus-widget-editor">
159
148
  <div
@@ -214,7 +203,6 @@ class WidgetEditor extends React.Component<
214
203
  (this.state.showWidget ? "enter" : "leave")
215
204
  }
216
205
  >
217
- {isUngradedEnabled && gradedPropBox}
218
206
  {Ed && (
219
207
  <Ed
220
208
  // eslint-disable-next-line react/no-string-refs
package/src/editor.tsx CHANGED
@@ -25,7 +25,7 @@ import WidgetEditor from "./components/widget-editor";
25
25
  import WidgetSelect from "./components/widget-select";
26
26
  import TexErrorView from "./tex-error-view";
27
27
 
28
- import type {ChangeHandler, WidgetInfo} from "@khanacademy/perseus";
28
+ import type {ChangeHandler, PerseusWidget} from "@khanacademy/perseus";
29
29
 
30
30
  // like [[snowman input-number 1]]
31
31
  const widgetPlaceholder = "[[\u2603 {id}]]";
@@ -114,7 +114,7 @@ type Props = Readonly<{
114
114
  replace?: any;
115
115
  placeholder: string;
116
116
  widgets: {
117
- [name: string]: WidgetInfo;
117
+ [name: string]: PerseusWidget;
118
118
  };
119
119
  images: any;
120
120
  disabled: boolean;
@@ -141,7 +141,7 @@ type DefaultProps = {
141
141
  warnNoWidgets: boolean;
142
142
  widgetEnabled: boolean;
143
143
  widgets: {
144
- [name: string]: WidgetInfo;
144
+ [name: string]: PerseusWidget;
145
145
  };
146
146
  };
147
147
 
@@ -245,37 +245,35 @@ class Editor extends React.Component<Props, State> {
245
245
  clearTimeout(this.deferredChange);
246
246
  }
247
247
 
248
- getWidgetEditor: (id: string, type: string) => undefined | React.ReactNode =
249
- (id: string, type: string) => {
250
- if (!Widgets.getEditor(type)) {
251
- return;
252
- }
253
- return (
254
- <WidgetEditor
255
- // @ts-expect-error - TS2322 - Type 'string' is not assignable to type 'number | undefined'.
256
- key={id}
257
- ref={id}
258
- id={id}
259
- // @ts-expect-error - TS2783 - 'type' is specified more than once, so this usage will be overwritten.
260
- type={type}
261
- // eslint-disable-next-line react/jsx-no-bind
262
- onChange={this._handleWidgetEditorChange.bind(this, id)}
263
- // eslint-disable-next-line react/jsx-no-bind
264
- onRemove={this._handleWidgetEditorRemove.bind(this, id)}
265
- apiOptions={this.props.apiOptions}
266
- {...this.props.widgets[id]}
267
- />
268
- );
269
- };
248
+ getWidgetEditor(
249
+ id: string,
250
+ type: PerseusWidget["type"],
251
+ ): undefined | React.ReactNode {
252
+ if (!Widgets.getEditor(type)) {
253
+ return;
254
+ }
255
+ return (
256
+ <WidgetEditor
257
+ ref={id}
258
+ id={id}
259
+ // eslint-disable-next-line react/jsx-no-bind
260
+ onChange={this._handleWidgetEditorChange.bind(this, id)}
261
+ // eslint-disable-next-line react/jsx-no-bind
262
+ onRemove={this._handleWidgetEditorRemove.bind(this, id)}
263
+ apiOptions={this.props.apiOptions}
264
+ {...this.props.widgets[id]}
265
+ />
266
+ );
267
+ }
270
268
 
271
269
  _handleWidgetEditorChange: (
272
270
  id: string,
273
- newWidgetInfo: WidgetInfo,
271
+ newWidgetInfo: PerseusWidget,
274
272
  cb?: () => unknown,
275
273
  silent?: boolean,
276
274
  ) => void = (
277
275
  id: string,
278
- newWidgetInfo: WidgetInfo,
276
+ newWidgetInfo: PerseusWidget,
279
277
  cb?: () => unknown,
280
278
  silent?: boolean,
281
279
  ) => {
@@ -685,14 +683,13 @@ class Editor extends React.Component<Props, State> {
685
683
  const newContent = newPrelude + widgetContent + newPostlude;
686
684
 
687
685
  const newWidgets = _.clone(this.props.widgets);
686
+ // @ts-expect-error TS(2345) Type '"categorizer" | undefined' is not assignable to type '"deprecated-standin"'.
688
687
  newWidgets[id] = {
689
688
  options: Widgets.getEditor(widgetType)?.defaultProps,
690
- // @ts-expect-error - TS2322 - Type 'string' is not assignable to type '"video" | "image" | "iframe" | "table" | "radio" | "definition" | "group" | "matrix" | "categorizer" | "cs-program" | "dropdown" | "example-graphie-widget" | "example-widget" | ... 26 more ... | "unit-input"'.
691
- type: widgetType,
689
+ type: widgetType as PerseusWidget["type"],
692
690
  // Track widget version on creation, so that a widget editor
693
691
  // without a valid version prop can only possibly refer to a
694
692
  // pre-versioning creation time.
695
- // @ts-expect-error - TS2322 - Type 'Version | null | undefined' is not assignable to type 'Version | undefined'.
696
693
  version: Widgets.getVersion(widgetType),
697
694
  };
698
695
 
@@ -940,7 +937,7 @@ class Editor extends React.Component<Props, State> {
940
937
  const match = Util.rWidgetParts.exec(pieces[i]);
941
938
  if (match != null) {
942
939
  const id = match[1];
943
- const type = match[2];
940
+ const type = match[2] as PerseusWidget["type"];
944
941
 
945
942
  const selected = false;
946
943
  // TODO(alpert):
package/src/index.ts CHANGED
@@ -24,4 +24,8 @@ import AllWidgets from "./all-widgets";
24
24
  Widgets.registerEditors(AllEditors);
25
25
  Widgets.registerWidgets(AllWidgets);
26
26
 
27
+ // When it's time to ship transformer's deprecation uncomment
28
+ // Widgets.replaceEditor("transformer", "deprecated-standin");
29
+ // Widgets.replaceWidget("transformer", "deprecatd-standin");
30
+
27
31
  export {AllEditors, AllWidgets};
@@ -11,4 +11,8 @@ import allWidgets from "../all-widgets";
11
11
  export const registerAllWidgetsAndEditorsForTesting = () => {
12
12
  Widgets.registerWidgets(allWidgets);
13
13
  Widgets.registerEditors(allEditors);
14
+
15
+ // When it's time to ship transformer's deprecation uncomment
16
+ // Widgets.replaceEditor("transformer", "deprecated-standin");
17
+ // Widgets.replaceWidget("transformer", "deprecatd-standin");
14
18
  };
@@ -0,0 +1,29 @@
1
+ import {EditorJsonify} from "@khanacademy/perseus";
2
+ import * as React from "react";
3
+
4
+ type Props = {
5
+ // Callback for when a widget prop is changed.
6
+ onChange: (options: any) => void;
7
+ };
8
+
9
+ class DeprecatedStandinEditor extends React.Component<Props> {
10
+ static widgetName = "deprecated-standin" as const;
11
+
12
+ serialize(): any {
13
+ return EditorJsonify.serialize.call(this);
14
+ }
15
+
16
+ render(): React.ReactNode {
17
+ return (
18
+ <div>
19
+ <p>This widget has been deprecated and removed</p>
20
+ <p>
21
+ Learners will see a message and they will not be graded on
22
+ this part. Please replace this widget with a supported one.
23
+ </p>
24
+ </div>
25
+ );
26
+ }
27
+ }
28
+
29
+ export default DeprecatedStandinEditor;