@khanacademy/perseus-editor 2.0.2 → 2.1.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.
Files changed (61) hide show
  1. package/CHANGELOG.md +52 -0
  2. package/dist/article-editor.d.ts +2 -2
  3. package/dist/article-editor.js.flow +2 -2
  4. package/dist/components/dropdown-option.d.ts +2 -2
  5. package/dist/components/dropdown-option.js.flow +2 -2
  6. package/dist/components/link.d.ts +2 -2
  7. package/dist/components/link.js.flow +2 -2
  8. package/dist/diffs/__stories__/perseus-diff-wrapper.d.ts +3 -2
  9. package/dist/diffs/__stories__/perseus-diff-wrapper.js.flow +3 -2
  10. package/dist/editor.d.ts +7 -10
  11. package/dist/editor.js.flow +7 -10
  12. package/dist/es/index.js +17430 -45
  13. package/dist/es/index.js.map +1 -1
  14. package/dist/index.js +17429 -44
  15. package/dist/index.js.map +1 -1
  16. package/dist/section-control-button.d.ts +7 -1
  17. package/dist/section-control-button.js.flow +7 -2
  18. package/dist/widgets/label-image/answer-choices.d.ts +1 -1
  19. package/dist/widgets/label-image/answer-choices.js.flow +1 -1
  20. package/dist/widgets/label-image/behavior.d.ts +2 -2
  21. package/dist/widgets/label-image/behavior.js.flow +2 -2
  22. package/dist/widgets/label-image/marker.d.ts +5 -5
  23. package/dist/widgets/label-image/marker.js.flow +5 -7
  24. package/dist/widgets/label-image/question-markers.d.ts +2 -2
  25. package/dist/widgets/label-image/question-markers.js.flow +2 -4
  26. package/dist/widgets/label-image/select-image.d.ts +2 -2
  27. package/dist/widgets/label-image/select-image.js.flow +2 -2
  28. package/dist/widgets/label-image-editor.d.ts +3 -3
  29. package/dist/widgets/label-image-editor.js.flow +3 -3
  30. package/dist/widgets/unit-editor.d.ts +1 -1
  31. package/dist/widgets/unit-editor.js.flow +1 -1
  32. package/package.json +2 -2
  33. package/src/__stories__/editor.stories.tsx +1 -2
  34. package/src/__stories__/section-control-button.stories.tsx +3 -3
  35. package/src/__tests__/editor.test.tsx +4 -4
  36. package/src/article-editor.tsx +13 -21
  37. package/src/components/dropdown-option.tsx +2 -2
  38. package/src/components/link.ts +2 -2
  39. package/src/diffs/__stories__/perseus-diff-wrapper.tsx +4 -2
  40. package/src/diffs/__stories__/structured-item-diff.stories.tsx +5 -9
  41. package/src/diffs/__stories__/tags-diff.stories.tsx +1 -1
  42. package/src/diffs/__stories__/text-diff.stories.tsx +1 -1
  43. package/src/editor.tsx +9 -26
  44. package/src/multirenderer-editor.tsx +6 -12
  45. package/src/widgets/__stories__/label-image-editor.stories.tsx +1 -1
  46. package/src/widgets/__stories__/radio-editor.stories.tsx +1 -1
  47. package/src/widgets/label-image/__stories__/answer-choices.stories.tsx +3 -7
  48. package/src/widgets/label-image/__stories__/behavior.stories.tsx +1 -1
  49. package/src/widgets/label-image/__stories__/marker.stories.tsx +2 -2
  50. package/src/widgets/label-image/__stories__/question-markers.stories.tsx +3 -3
  51. package/src/widgets/label-image/__stories__/select-image.stories.tsx +3 -3
  52. package/src/widgets/label-image/answer-choices.tsx +5 -5
  53. package/src/widgets/label-image/behavior.tsx +3 -3
  54. package/src/widgets/label-image/marker.tsx +5 -5
  55. package/src/widgets/label-image/question-markers.tsx +2 -2
  56. package/src/widgets/label-image/select-image.tsx +2 -5
  57. package/src/widgets/label-image-editor.tsx +3 -3
  58. package/src/widgets/numeric-input-editor.tsx +0 -20
  59. package/{tsconfig.json → tsconfig-build.json} +3 -3
  60. package/tsconfig-build.tsbuildinfo +1 -0
  61. package/tsconfig.tsbuildinfo +0 -1
@@ -141,13 +141,9 @@ type HeaderProps = {
141
141
  depth: number;
142
142
  };
143
143
 
144
- const Header: React.FC<HeaderProps> = ({
145
- depth,
146
- ...props
147
- }): React.ReactElement => {
144
+ const Header = ({depth, ...props}: HeaderProps): React.ReactElement => {
148
145
  const headerLevel = Math.min(depth, 5) + 1;
149
146
  const HeaderTag = `h${headerLevel}`;
150
- // @ts-expect-error [FEI-5003] - TS2559 - Type '{ children?: ReactNode; }' has no properties in common with type 'IntrinsicAttributes'.
151
147
  return <HeaderTag {...props} />;
152
148
  };
153
149
 
@@ -268,13 +264,13 @@ type LeafContainerProps = {
268
264
  path: Path;
269
265
  shape: Shape;
270
266
  };
271
- const LeafContainer: React.FC<LeafContainerProps> = ({
267
+ const LeafContainer = ({
272
268
  name,
273
269
  controls,
274
270
  children,
275
271
  path,
276
272
  shape,
277
- }): React.ReactElement => {
273
+ }: LeafContainerProps): React.ReactElement => {
278
274
  const hasPreviewHeading = shape.type === "content" || shape.type === "hint";
279
275
  const previewHeading = hasPreviewHeading && (
280
276
  <div className={css(styles.containerHeader)}>
@@ -314,9 +310,7 @@ type ArrayContainerProps = {
314
310
  shape: ArrayShape;
315
311
  actions: ArrayContainerActions;
316
312
  };
317
- const ArrayContainer: React.FC<ArrayContainerProps> = (
318
- props,
319
- ): React.ReactElement => {
313
+ const ArrayContainer = (props: ArrayContainerProps): React.ReactElement => {
320
314
  const {name, controls, children, path, shape, actions} = props;
321
315
  return (
322
316
  <div className={css(styles.container)}>
@@ -347,12 +341,12 @@ type ObjectContainerProps = {
347
341
  children?: React.ReactNode;
348
342
  path: Path;
349
343
  };
350
- const ObjectContainer: React.FC<ObjectContainerProps> = ({
344
+ const ObjectContainer = ({
351
345
  name,
352
346
  controls,
353
347
  children,
354
348
  path,
355
- }): React.ReactElement => {
349
+ }: ObjectContainerProps): React.ReactElement => {
356
350
  const headingEditor = (
357
351
  <div className={css(styles.containerHeader)}>
358
352
  {/* @ts-expect-error [FEI-5003] - TS2322 - Type '{ children: string; depth: number; className: string; }' is not assignable to type 'IntrinsicAttributes & HeaderProps & { children?: ReactNode; }'. */}
@@ -93,6 +93,6 @@ class WithState extends React.Component<Empty, State> {
93
93
  }
94
94
  }
95
95
 
96
- export const Default: React.FC<StoryArgs> = (args): React.ReactElement => {
96
+ export const Default = (args: StoryArgs): React.ReactElement => {
97
97
  return <WithState />;
98
98
  };
@@ -110,6 +110,6 @@ class WithState extends React.Component<Empty, PerseusRadioWidgetOptions> {
110
110
  }
111
111
  }
112
112
 
113
- export const Default: React.FC<StoryArgs> = (args): React.ReactElement => {
113
+ export const Default = (args: StoryArgs): React.ReactElement => {
114
114
  return <WithState />;
115
115
  };
@@ -57,16 +57,12 @@ class WithState extends React.Component<
57
57
  }
58
58
  }
59
59
 
60
- export const EmptyNonInteractive: React.FC<StoryArgs> = (
61
- args,
62
- ): React.ReactElement => {
60
+ export const EmptyNonInteractive = (args: StoryArgs): React.ReactElement => {
63
61
  const props = {choices: [], onChange: (...args) => {}} as const;
64
62
  return <Wrapper {...props} />;
65
63
  };
66
64
 
67
- export const FilledNonInteractive: React.FC<StoryArgs> = (
68
- args,
69
- ): React.ReactElement => {
65
+ export const FilledNonInteractive = (args: StoryArgs): React.ReactElement => {
70
66
  const props = {
71
67
  choices: [
72
68
  "Lamborghini",
@@ -81,6 +77,6 @@ export const FilledNonInteractive: React.FC<StoryArgs> = (
81
77
  return <Wrapper {...props} />;
82
78
  };
83
79
 
84
- export const Interactive: React.FC<StoryArgs> = (args): React.ReactElement => {
80
+ export const Interactive = (args: StoryArgs): React.ReactElement => {
85
81
  return <WithState />;
86
82
  };
@@ -13,7 +13,7 @@ export default {
13
13
  title: "Perseus/Editor/Widgets/Label Image/Behavior",
14
14
  } as Story;
15
15
 
16
- export const Default: React.FC<StoryArgs> = (args): React.ReactElement => {
16
+ export const Default = (args: StoryArgs): React.ReactElement => {
17
17
  const [state, setState] = React.useState({
18
18
  multipleAnswers: false,
19
19
  hideChoicesFromInstructions: false,
@@ -33,7 +33,7 @@ const Wrapper = (props) => (
33
33
  </div>
34
34
  );
35
35
 
36
- export const Empty: React.FC<StoryArgs> = (args): React.ReactElement => {
36
+ export const Empty = (args: StoryArgs): React.ReactElement => {
37
37
  const props = {
38
38
  answers: [],
39
39
  choices: [],
@@ -50,7 +50,7 @@ export const Empty: React.FC<StoryArgs> = (args): React.ReactElement => {
50
50
  return <Wrapper {...props} />;
51
51
  };
52
52
 
53
- export const WithAnswers: React.FC<StoryArgs> = (args): React.ReactElement => {
53
+ export const WithAnswers = (args: StoryArgs): React.ReactElement => {
54
54
  const props = {
55
55
  answers: ["BMW", "Ferrari"],
56
56
  choices: [
@@ -70,7 +70,7 @@ class WithState extends React.Component<
70
70
  }
71
71
  }
72
72
 
73
- export const Empty: React.FC<StoryArgs> = (args): React.ReactElement => {
73
+ export const Empty = (args: StoryArgs): React.ReactElement => {
74
74
  const props = {
75
75
  choices: [],
76
76
  imageUrl: "",
@@ -82,7 +82,7 @@ export const Empty: React.FC<StoryArgs> = (args): React.ReactElement => {
82
82
  return <Wrapper {...props} />;
83
83
  };
84
84
 
85
- export const Filled: React.FC<StoryArgs> = (args): React.ReactElement => {
85
+ export const Filled = (args: StoryArgs): React.ReactElement => {
86
86
  const props = {
87
87
  choices: [],
88
88
  imageUrl:
@@ -102,6 +102,6 @@ export const Filled: React.FC<StoryArgs> = (args): React.ReactElement => {
102
102
  return <Wrapper {...props} />;
103
103
  };
104
104
 
105
- export const Interactive: React.FC<StoryArgs> = (args): React.ReactElement => {
105
+ export const Interactive = (args: StoryArgs): React.ReactElement => {
106
106
  return <WithState />;
107
107
  };
@@ -36,7 +36,7 @@ const WithState = () => {
36
36
  );
37
37
  };
38
38
 
39
- export const Empty: React.FC<StoryArgs> = (args): React.ReactElement => {
39
+ export const Empty = (args: StoryArgs): React.ReactElement => {
40
40
  const props = {
41
41
  url: "",
42
42
  onChange: () => {},
@@ -45,7 +45,7 @@ export const Empty: React.FC<StoryArgs> = (args): React.ReactElement => {
45
45
  return <Wrapper {...props} />;
46
46
  };
47
47
 
48
- export const Filled: React.FC<StoryArgs> = (args): React.ReactElement => {
48
+ export const Filled = (args: StoryArgs): React.ReactElement => {
49
49
  const props = {
50
50
  url: "https://ka-perseus-images.s3.amazonaws.com/2ee5fc32e35c5178373b39fd304b325b2994c913.png",
51
51
  onChange: () => {},
@@ -54,6 +54,6 @@ export const Filled: React.FC<StoryArgs> = (args): React.ReactElement => {
54
54
  return <Wrapper {...props} />;
55
55
  };
56
56
 
57
- export const Interactive: React.FC<StoryArgs> = (args): React.ReactElement => {
57
+ export const Interactive = (args: StoryArgs): React.ReactElement => {
58
58
  return <WithState />;
59
59
  };
@@ -89,7 +89,7 @@ const DraggableGripIcon = () => (
89
89
  /**
90
90
  * A button link to add a new answer.
91
91
  */
92
- const AddAnswer: React.FC<AddAnswerProps> = ({onClick}): React.ReactElement => (
92
+ const AddAnswer = ({onClick}: AddAnswerProps): React.ReactElement => (
93
93
  <Link
94
94
  className={css(styles.addAnswer, editorStyles.addAnswer)}
95
95
  onClick={onClick}
@@ -105,11 +105,11 @@ const AddAnswer: React.FC<AddAnswerProps> = ({onClick}): React.ReactElement => (
105
105
  *
106
106
  * TODO(michaelpolyak): Implement answer reordering, CP-117
107
107
  */
108
- const Answer: React.FC<AnswerProps> = ({
108
+ const Answer = ({
109
109
  answer,
110
110
  onChange,
111
111
  onRemove,
112
- }): React.ReactElement => (
112
+ }: AnswerProps): React.ReactElement => (
113
113
  <li className={css(styles.answer)}>
114
114
  <Link onClick={onRemove}>
115
115
  <Icon icon={removeIcon} size={24} color="#D92916" />
@@ -137,10 +137,10 @@ const Answer: React.FC<AnswerProps> = ({
137
137
  /**
138
138
  * The list of choices, handles adding, removing and reording of answers.
139
139
  */
140
- const AnswerChoices: React.FC<AnswerChoicesProps> = ({
140
+ const AnswerChoices = ({
141
141
  choices,
142
142
  onChange,
143
- }): React.ReactElement => (
143
+ }: AnswerChoicesProps): React.ReactElement => (
144
144
  <div>
145
145
  <div className={css(styles.title)}>Answer Choices</div>
146
146
 
@@ -10,7 +10,7 @@ import Checkbox from "../../components/checkbox";
10
10
 
11
11
  const {colors, typography} = globalStyles;
12
12
 
13
- type BehaviorProps = {
13
+ type Props = {
14
14
  // Whether multiple answer choices may be selected for markers.
15
15
  multipleAnswers: boolean;
16
16
  // Whether to hide answer choices from user instructions.
@@ -22,11 +22,11 @@ type BehaviorProps = {
22
22
  }) => void;
23
23
  };
24
24
 
25
- const Behavior: React.FC<BehaviorProps> = ({
25
+ const Behavior = ({
26
26
  multipleAnswers,
27
27
  hideChoicesFromInstructions,
28
28
  onChange,
29
- }): React.ReactElement => (
29
+ }: Props): React.ReactElement => (
30
30
  <div>
31
31
  <div className={css(styles.title)}>Behavior</div>
32
32
 
@@ -17,7 +17,7 @@ import type {MarkerType} from "@khanacademy/perseus";
17
17
 
18
18
  const {colors, borderRadius} = globalStyles;
19
19
 
20
- type MarkerProps = MarkerType & {
20
+ type Props = MarkerType & {
21
21
  // The list of possible answer choices.
22
22
  choices: ReadonlyArray<string>;
23
23
  // Callback for when any of the marker props are changed.
@@ -26,16 +26,16 @@ type MarkerProps = MarkerType & {
26
26
  onRemove: () => void;
27
27
  };
28
28
 
29
- type MarkerState = {
29
+ type State = {
30
30
  // Whether answer choices dropdown is shown, controlled by the user clicking
31
31
  // on the marker icon.
32
32
  showDropdown: boolean;
33
33
  };
34
34
 
35
- export default class Marker extends React.Component<MarkerProps, MarkerState> {
35
+ export default class Marker extends React.Component<Props, State> {
36
36
  _marker: HTMLElement | null | undefined;
37
37
 
38
- constructor(props: MarkerProps) {
38
+ constructor(props: Props) {
39
39
  super(props);
40
40
 
41
41
  this.state = {
@@ -47,7 +47,7 @@ export default class Marker extends React.Component<MarkerProps, MarkerState> {
47
47
  document.addEventListener("click", this.handleClick, true);
48
48
  }
49
49
 
50
- UNSAFE_componentWillReceiveProps(nextProps: MarkerProps) {
50
+ UNSAFE_componentWillReceiveProps(nextProps: Props) {
51
51
  const {answers} = this.props;
52
52
 
53
53
  // Exclude those answers that are no longer present in choices.
@@ -13,7 +13,7 @@ import type {MarkerType} from "@khanacademy/perseus";
13
13
 
14
14
  const {colors, typography} = globalStyles;
15
15
 
16
- type QuestionMarkersProps = {
16
+ type Props = {
17
17
  // The list of possible answers in a specific order.
18
18
  choices: ReadonlyArray<string>;
19
19
  // The question image properties.
@@ -26,7 +26,7 @@ type QuestionMarkersProps = {
26
26
  onChange: (markers: ReadonlyArray<MarkerType>) => void;
27
27
  };
28
28
 
29
- export default class QuestionMarkers extends React.Component<QuestionMarkersProps> {
29
+ export default class QuestionMarkers extends React.Component<Props> {
30
30
  _markers: Array<Marker | null | undefined> = [];
31
31
 
32
32
  openDropdownForMarkerIndices(indices: ReadonlyArray<number>) {
@@ -11,17 +11,14 @@ import FormWrappedTextField from "../../components/form-wrapped-text-field";
11
11
 
12
12
  const {colors, typography} = globalStyles;
13
13
 
14
- type SelectImageProps = {
14
+ type Props = {
15
15
  // Callback for when image URL is changed.
16
16
  onChange: (url: string) => void;
17
17
  // The selected image URL.
18
18
  url: string;
19
19
  };
20
20
 
21
- const SelectImage: React.FC<SelectImageProps> = ({
22
- onChange,
23
- url,
24
- }): React.ReactElement => (
21
+ const SelectImage = ({onChange, url}: Props): React.ReactElement => (
25
22
  <div>
26
23
  <div className={css(styles.title)}>Image</div>
27
24
 
@@ -19,7 +19,7 @@ import SelectImage from "./label-image/select-image";
19
19
 
20
20
  import type {MarkerType} from "@khanacademy/perseus";
21
21
 
22
- type LabelImageEditorProps = {
22
+ type Props = {
23
23
  // List of answer choices to label question image with.
24
24
  choices: ReadonlyArray<string>;
25
25
  // The question image properties.
@@ -37,7 +37,7 @@ type LabelImageEditorProps = {
37
37
  onChange: (options: any) => void;
38
38
  };
39
39
 
40
- class LabelImageEditor extends React.Component<LabelImageEditorProps> {
40
+ class LabelImageEditor extends React.Component<Props> {
41
41
  _questionMarkers: QuestionMarkers | null | undefined;
42
42
 
43
43
  static defaultProps: {
@@ -62,7 +62,7 @@ class LabelImageEditor extends React.Component<LabelImageEditorProps> {
62
62
 
63
63
  static widgetName = "label-image" as const;
64
64
 
65
- componentDidUpdate(prevProps: LabelImageEditorProps) {
65
+ componentDidUpdate(prevProps: Props) {
66
66
  const coordsToMarkers: Record<string, any> = {};
67
67
 
68
68
  prevProps.markers.forEach(
@@ -66,7 +66,6 @@ const NumericInputEditor: any = createReactClass({
66
66
  size: "normal",
67
67
  coefficient: false,
68
68
  labelText: "",
69
- multipleNumberInput: false,
70
69
  rightAlign: false,
71
70
  };
72
71
  },
@@ -417,16 +416,6 @@ const NumericInputEditor: any = createReactClass({
417
416
 
418
417
  return (
419
418
  <div className="perseus-input-number-editor">
420
- <div ref={(e) => (this.multInputOption = e)}>
421
- <select onChange={this.onMultipleInputChange}>
422
- <option value="simple-numeric-input">
423
- Ask for one correct solution
424
- </option>
425
- <option value="multiple-numeric-input">
426
- Ask for all correct solutions
427
- </option>
428
- </select>
429
- </div>
430
419
  <div className="ui-title">User input</div>
431
420
  <div className="msg-title">
432
421
  Message shown to user on attempt
@@ -480,15 +469,6 @@ const NumericInputEditor: any = createReactClass({
480
469
  });
481
470
  },
482
471
 
483
- onMultipleInputChange: function (event) {
484
- const newOption = event.target.value;
485
- if (newOption === "multiple-numeric-input") {
486
- this.props.onChange({multipleNumberInput: true});
487
- } else {
488
- this.props.onChange({multipleNumberInput: false});
489
- }
490
- },
491
-
492
472
  updateAnswer: function (choiceIndex, update) {
493
473
  if (!_.isObject(update)) {
494
474
  return _.partial(
@@ -15,8 +15,8 @@
15
15
  }
16
16
  },
17
17
  "references": [
18
- {"path": "../kas"},
19
- {"path": "../kmath"},
20
- {"path": "../perseus"},
18
+ {"path": "../kas/tsconfig-build.json"},
19
+ {"path": "../kmath/tsconfig-build.json"},
20
+ {"path": "../perseus/tsconfig-build.json"},
21
21
  ]
22
22
  }