@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.
- package/CHANGELOG.md +52 -0
- package/dist/article-editor.d.ts +2 -2
- package/dist/article-editor.js.flow +2 -2
- package/dist/components/dropdown-option.d.ts +2 -2
- package/dist/components/dropdown-option.js.flow +2 -2
- package/dist/components/link.d.ts +2 -2
- package/dist/components/link.js.flow +2 -2
- package/dist/diffs/__stories__/perseus-diff-wrapper.d.ts +3 -2
- package/dist/diffs/__stories__/perseus-diff-wrapper.js.flow +3 -2
- package/dist/editor.d.ts +7 -10
- package/dist/editor.js.flow +7 -10
- package/dist/es/index.js +17430 -45
- package/dist/es/index.js.map +1 -1
- package/dist/index.js +17429 -44
- package/dist/index.js.map +1 -1
- package/dist/section-control-button.d.ts +7 -1
- package/dist/section-control-button.js.flow +7 -2
- package/dist/widgets/label-image/answer-choices.d.ts +1 -1
- package/dist/widgets/label-image/answer-choices.js.flow +1 -1
- package/dist/widgets/label-image/behavior.d.ts +2 -2
- package/dist/widgets/label-image/behavior.js.flow +2 -2
- package/dist/widgets/label-image/marker.d.ts +5 -5
- package/dist/widgets/label-image/marker.js.flow +5 -7
- package/dist/widgets/label-image/question-markers.d.ts +2 -2
- package/dist/widgets/label-image/question-markers.js.flow +2 -4
- package/dist/widgets/label-image/select-image.d.ts +2 -2
- package/dist/widgets/label-image/select-image.js.flow +2 -2
- package/dist/widgets/label-image-editor.d.ts +3 -3
- package/dist/widgets/label-image-editor.js.flow +3 -3
- package/dist/widgets/unit-editor.d.ts +1 -1
- package/dist/widgets/unit-editor.js.flow +1 -1
- package/package.json +2 -2
- package/src/__stories__/editor.stories.tsx +1 -2
- package/src/__stories__/section-control-button.stories.tsx +3 -3
- package/src/__tests__/editor.test.tsx +4 -4
- package/src/article-editor.tsx +13 -21
- package/src/components/dropdown-option.tsx +2 -2
- package/src/components/link.ts +2 -2
- package/src/diffs/__stories__/perseus-diff-wrapper.tsx +4 -2
- package/src/diffs/__stories__/structured-item-diff.stories.tsx +5 -9
- package/src/diffs/__stories__/tags-diff.stories.tsx +1 -1
- package/src/diffs/__stories__/text-diff.stories.tsx +1 -1
- package/src/editor.tsx +9 -26
- package/src/multirenderer-editor.tsx +6 -12
- package/src/widgets/__stories__/label-image-editor.stories.tsx +1 -1
- package/src/widgets/__stories__/radio-editor.stories.tsx +1 -1
- package/src/widgets/label-image/__stories__/answer-choices.stories.tsx +3 -7
- package/src/widgets/label-image/__stories__/behavior.stories.tsx +1 -1
- package/src/widgets/label-image/__stories__/marker.stories.tsx +2 -2
- package/src/widgets/label-image/__stories__/question-markers.stories.tsx +3 -3
- package/src/widgets/label-image/__stories__/select-image.stories.tsx +3 -3
- package/src/widgets/label-image/answer-choices.tsx +5 -5
- package/src/widgets/label-image/behavior.tsx +3 -3
- package/src/widgets/label-image/marker.tsx +5 -5
- package/src/widgets/label-image/question-markers.tsx +2 -2
- package/src/widgets/label-image/select-image.tsx +2 -5
- package/src/widgets/label-image-editor.tsx +3 -3
- package/src/widgets/numeric-input-editor.tsx +0 -20
- package/{tsconfig.json → tsconfig-build.json} +3 -3
- package/tsconfig-build.tsbuildinfo +1 -0
- package/tsconfig.tsbuildinfo +0 -1
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
|
-
declare const InlineIcon:
|
|
2
|
+
declare const InlineIcon: ({ path, width, height, style, title, }: {
|
|
3
|
+
path: string;
|
|
4
|
+
height: number;
|
|
5
|
+
width: number;
|
|
6
|
+
style?: React.CSSProperties | undefined;
|
|
7
|
+
title?: string | undefined;
|
|
8
|
+
}) => React.ReactElement<any, string | React.JSXElementConstructor<any>>;
|
|
3
9
|
type InlineIconProps = JSX.LibraryManagedAttributes<typeof InlineIcon, React.ComponentProps<typeof InlineIcon>>;
|
|
4
10
|
type SectionControlButtonProps = {
|
|
5
11
|
icon: InlineIconProps;
|
|
@@ -4,9 +4,14 @@
|
|
|
4
4
|
* Flowgen v1.21.0
|
|
5
5
|
* @flow
|
|
6
6
|
*/
|
|
7
|
-
import * as $Flowgen$Import$_2e__2e__2f__2e__2e__2f_perseus_2f_src_2f_components_2f_inline_2d_icon from "../../perseus/src/components/inline-icon";
|
|
8
7
|
import * as React from "react";
|
|
9
|
-
declare var InlineIcon:
|
|
8
|
+
declare var InlineIcon: (x: {|
|
|
9
|
+
path: string,
|
|
10
|
+
height: number,
|
|
11
|
+
width: number,
|
|
12
|
+
style?: React.CSSProperties | void,
|
|
13
|
+
title?: string | void,
|
|
14
|
+
|}) => React.Element<any, string | React.JSXElementConstructor<any>>;
|
|
10
15
|
declare type InlineIconProps = React.ElementConfig<typeof InlineIcon>;
|
|
11
16
|
declare type SectionControlButtonProps = {|
|
|
12
17
|
icon: InlineIconProps,
|
|
@@ -9,5 +9,5 @@ type AnswerChoicesProps = {
|
|
|
9
9
|
/**
|
|
10
10
|
* The list of choices, handles adding, removing and reording of answers.
|
|
11
11
|
*/
|
|
12
|
-
declare const AnswerChoices: React.
|
|
12
|
+
declare const AnswerChoices: ({ choices, onChange, }: AnswerChoicesProps) => React.ReactElement;
|
|
13
13
|
export default AnswerChoices;
|
|
@@ -12,5 +12,5 @@ declare type AnswerChoicesProps = {|
|
|
|
12
12
|
/**
|
|
13
13
|
* The list of choices, handles adding, removing and reording of answers.
|
|
14
14
|
*/
|
|
15
|
-
declare var AnswerChoices: React.
|
|
15
|
+
declare var AnswerChoices: (x: AnswerChoicesProps) => React.Element<any>;
|
|
16
16
|
declare export default typeof AnswerChoices;
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Controlled component to display and change widget options.
|
|
3
3
|
*/
|
|
4
4
|
import * as React from "react";
|
|
5
|
-
type
|
|
5
|
+
type Props = {
|
|
6
6
|
multipleAnswers: boolean;
|
|
7
7
|
hideChoicesFromInstructions: boolean;
|
|
8
8
|
onChange: (options: {
|
|
@@ -10,5 +10,5 @@ type BehaviorProps = {
|
|
|
10
10
|
hideChoicesFromInstructions?: boolean;
|
|
11
11
|
}) => void;
|
|
12
12
|
};
|
|
13
|
-
declare const Behavior: React.
|
|
13
|
+
declare const Behavior: ({ multipleAnswers, hideChoicesFromInstructions, onChange, }: Props) => React.ReactElement;
|
|
14
14
|
export default Behavior;
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* @flow
|
|
6
6
|
*/
|
|
7
7
|
import * as React from "react";
|
|
8
|
-
declare type
|
|
8
|
+
declare type Props = {|
|
|
9
9
|
multipleAnswers: boolean,
|
|
10
10
|
hideChoicesFromInstructions: boolean,
|
|
11
11
|
onChange: (options: {|
|
|
@@ -13,5 +13,5 @@ declare type BehaviorProps = {|
|
|
|
13
13
|
hideChoicesFromInstructions?: boolean,
|
|
14
14
|
|}) => void,
|
|
15
15
|
|};
|
|
16
|
-
declare var Behavior: React.
|
|
16
|
+
declare var Behavior: (x: Props) => React.Element<any>;
|
|
17
17
|
declare export default typeof Behavior;
|
|
@@ -6,19 +6,19 @@
|
|
|
6
6
|
*/
|
|
7
7
|
import * as React from "react";
|
|
8
8
|
import type { MarkerType } from "@khanacademy/perseus";
|
|
9
|
-
type
|
|
9
|
+
type Props = MarkerType & {
|
|
10
10
|
choices: ReadonlyArray<string>;
|
|
11
11
|
onChange: (marker: MarkerType) => void;
|
|
12
12
|
onRemove: () => void;
|
|
13
13
|
};
|
|
14
|
-
type
|
|
14
|
+
type State = {
|
|
15
15
|
showDropdown: boolean;
|
|
16
16
|
};
|
|
17
|
-
export default class Marker extends React.Component<
|
|
17
|
+
export default class Marker extends React.Component<Props, State> {
|
|
18
18
|
_marker: HTMLElement | null | undefined;
|
|
19
|
-
constructor(props:
|
|
19
|
+
constructor(props: Props);
|
|
20
20
|
componentDidMount(): void;
|
|
21
|
-
UNSAFE_componentWillReceiveProps(nextProps:
|
|
21
|
+
UNSAFE_componentWillReceiveProps(nextProps: Props): void;
|
|
22
22
|
componentWillUnmount(): void;
|
|
23
23
|
openDropdown(): void;
|
|
24
24
|
updateMarker(props: any): void;
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
*/
|
|
7
7
|
import * as React from "react";
|
|
8
8
|
import type { MarkerType } from "@khanacademy/perseus";
|
|
9
|
-
declare type
|
|
9
|
+
declare type Props = {|
|
|
10
10
|
...MarkerType,
|
|
11
11
|
...{|
|
|
12
12
|
choices: $ReadOnlyArray<string>,
|
|
@@ -14,16 +14,14 @@ declare type MarkerProps = {|
|
|
|
14
14
|
onRemove: () => void,
|
|
15
15
|
|},
|
|
16
16
|
|};
|
|
17
|
-
declare type
|
|
17
|
+
declare type State = {|
|
|
18
18
|
showDropdown: boolean,
|
|
19
19
|
|};
|
|
20
|
-
declare export default class Marker
|
|
21
|
-
extends React.Component<MarkerProps, MarkerState>
|
|
22
|
-
{
|
|
20
|
+
declare export default class Marker extends React.Component<Props, State> {
|
|
23
21
|
_marker: HTMLElement | null | void;
|
|
24
|
-
constructor(props:
|
|
22
|
+
constructor(props: Props): this;
|
|
25
23
|
componentDidMount(): void;
|
|
26
|
-
UNSAFE_componentWillReceiveProps(nextProps:
|
|
24
|
+
UNSAFE_componentWillReceiveProps(nextProps: Props): void;
|
|
27
25
|
componentWillUnmount(): void;
|
|
28
26
|
openDropdown(): void;
|
|
29
27
|
updateMarker(props: any): void;
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
import * as React from "react";
|
|
6
6
|
import Marker from "./marker";
|
|
7
7
|
import type { MarkerType } from "@khanacademy/perseus";
|
|
8
|
-
type
|
|
8
|
+
type Props = {
|
|
9
9
|
choices: ReadonlyArray<string>;
|
|
10
10
|
imageUrl: string;
|
|
11
11
|
imageWidth: number;
|
|
@@ -13,7 +13,7 @@ type QuestionMarkersProps = {
|
|
|
13
13
|
markers: ReadonlyArray<MarkerType>;
|
|
14
14
|
onChange: (markers: ReadonlyArray<MarkerType>) => void;
|
|
15
15
|
};
|
|
16
|
-
export default class QuestionMarkers extends React.Component<
|
|
16
|
+
export default class QuestionMarkers extends React.Component<Props> {
|
|
17
17
|
_markers: Array<Marker | null | undefined>;
|
|
18
18
|
openDropdownForMarkerIndices(indices: ReadonlyArray<number>): void;
|
|
19
19
|
handleImageDoubleClick: (e: React.MouseEvent) => void;
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
import * as React from "react";
|
|
8
8
|
import Marker from "./marker";
|
|
9
9
|
import type { MarkerType } from "@khanacademy/perseus";
|
|
10
|
-
declare type
|
|
10
|
+
declare type Props = {|
|
|
11
11
|
choices: $ReadOnlyArray<string>,
|
|
12
12
|
imageUrl: string,
|
|
13
13
|
imageWidth: number,
|
|
@@ -15,9 +15,7 @@ declare type QuestionMarkersProps = {|
|
|
|
15
15
|
markers: $ReadOnlyArray<MarkerType>,
|
|
16
16
|
onChange: (markers: $ReadOnlyArray<MarkerType>) => void,
|
|
17
17
|
|};
|
|
18
|
-
declare export default class QuestionMarkers
|
|
19
|
-
extends React.Component<QuestionMarkersProps>
|
|
20
|
-
{
|
|
18
|
+
declare export default class QuestionMarkers extends React.Component<Props> {
|
|
21
19
|
_markers: Array<Marker | null | void>;
|
|
22
20
|
openDropdownForMarkerIndices(indices: $ReadOnlyArray<number>): void;
|
|
23
21
|
handleImageDoubleClick: (e: SyntheticMouseEvent<>) => void;
|
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
* Controlled component for selecting the question image, for answer labeling.
|
|
3
3
|
*/
|
|
4
4
|
import * as React from "react";
|
|
5
|
-
type
|
|
5
|
+
type Props = {
|
|
6
6
|
onChange: (url: string) => void;
|
|
7
7
|
url: string;
|
|
8
8
|
};
|
|
9
|
-
declare const SelectImage: React.
|
|
9
|
+
declare const SelectImage: ({ onChange, url }: Props) => React.ReactElement;
|
|
10
10
|
export default SelectImage;
|
|
@@ -5,9 +5,9 @@
|
|
|
5
5
|
* @flow
|
|
6
6
|
*/
|
|
7
7
|
import * as React from "react";
|
|
8
|
-
declare type
|
|
8
|
+
declare type Props = {|
|
|
9
9
|
onChange: (url: string) => void,
|
|
10
10
|
url: string,
|
|
11
11
|
|};
|
|
12
|
-
declare var SelectImage: React.
|
|
12
|
+
declare var SelectImage: (x: Props) => React.Element<any>;
|
|
13
13
|
declare export default typeof SelectImage;
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
import * as React from "react";
|
|
9
9
|
import QuestionMarkers from "./label-image/question-markers";
|
|
10
10
|
import type { MarkerType } from "@khanacademy/perseus";
|
|
11
|
-
type
|
|
11
|
+
type Props = {
|
|
12
12
|
choices: ReadonlyArray<string>;
|
|
13
13
|
imageAlt: string;
|
|
14
14
|
imageUrl: string;
|
|
@@ -19,7 +19,7 @@ type LabelImageEditorProps = {
|
|
|
19
19
|
hideChoicesFromInstructions: boolean;
|
|
20
20
|
onChange: (options: any) => void;
|
|
21
21
|
};
|
|
22
|
-
declare class LabelImageEditor extends React.Component<
|
|
22
|
+
declare class LabelImageEditor extends React.Component<Props> {
|
|
23
23
|
_questionMarkers: QuestionMarkers | null | undefined;
|
|
24
24
|
static defaultProps: {
|
|
25
25
|
choices: ReadonlyArray<any>;
|
|
@@ -32,7 +32,7 @@ declare class LabelImageEditor extends React.Component<LabelImageEditorProps> {
|
|
|
32
32
|
multipleAnswers: boolean;
|
|
33
33
|
};
|
|
34
34
|
static widgetName: "label-image";
|
|
35
|
-
componentDidUpdate(prevProps:
|
|
35
|
+
componentDidUpdate(prevProps: Props): void;
|
|
36
36
|
getSaveWarnings: () => ReadonlyArray<any | string>;
|
|
37
37
|
serialize(): any;
|
|
38
38
|
handleImageChange: (url: string) => void;
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
import * as React from "react";
|
|
8
8
|
import QuestionMarkers from "./label-image/question-markers";
|
|
9
9
|
import type { MarkerType } from "@khanacademy/perseus";
|
|
10
|
-
declare type
|
|
10
|
+
declare type Props = {|
|
|
11
11
|
choices: $ReadOnlyArray<string>,
|
|
12
12
|
imageAlt: string,
|
|
13
13
|
imageUrl: string,
|
|
@@ -18,7 +18,7 @@ declare type LabelImageEditorProps = {|
|
|
|
18
18
|
hideChoicesFromInstructions: boolean,
|
|
19
19
|
onChange: (options: any) => void,
|
|
20
20
|
|};
|
|
21
|
-
declare class LabelImageEditor extends React.Component<
|
|
21
|
+
declare class LabelImageEditor extends React.Component<Props> {
|
|
22
22
|
_questionMarkers: QuestionMarkers | null | void;
|
|
23
23
|
static defaultProps: {|
|
|
24
24
|
choices: $ReadOnlyArray<any>,
|
|
@@ -31,7 +31,7 @@ declare class LabelImageEditor extends React.Component<LabelImageEditorProps> {
|
|
|
31
31
|
multipleAnswers: boolean,
|
|
32
32
|
|};
|
|
33
33
|
static widgetName: "label-image";
|
|
34
|
-
componentDidUpdate(prevProps:
|
|
34
|
+
componentDidUpdate(prevProps: Props): void;
|
|
35
35
|
getSaveWarnings: () => $ReadOnlyArray<any | string>;
|
|
36
36
|
serialize(): any;
|
|
37
37
|
handleImageChange: (url: string) => void;
|
|
@@ -11,7 +11,7 @@ declare class UnitInputEditor extends React.Component<UnitInputEditorProps> {
|
|
|
11
11
|
static propTypes: {
|
|
12
12
|
value: PropTypes.Requireable<string>;
|
|
13
13
|
acceptingUnits: PropTypes.Requireable<(string | null | undefined)[]>;
|
|
14
|
-
accepting: PropTypes.Requireable<"
|
|
14
|
+
accepting: PropTypes.Requireable<"some" | "all">;
|
|
15
15
|
sigfigs: PropTypes.Requireable<number>;
|
|
16
16
|
onChange: PropTypes.Validator<(...args: any[]) => any>;
|
|
17
17
|
};
|
|
@@ -17,7 +17,7 @@ declare class UnitInputEditor extends React.Component<UnitInputEditorProps> {
|
|
|
17
17
|
static propTypes: {|
|
|
18
18
|
value: PropTypes.Requireable<string>,
|
|
19
19
|
acceptingUnits: PropTypes.Requireable<(string | null | void)[]>,
|
|
20
|
-
accepting: PropTypes.Requireable<"
|
|
20
|
+
accepting: PropTypes.Requireable<"some" | "all">,
|
|
21
21
|
sigfigs: PropTypes.Requireable<number>,
|
|
22
22
|
onChange: PropTypes.Validator<(...args: any[]) => any>,
|
|
23
23
|
|};
|
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.0
|
|
6
|
+
"version": "2.1.0",
|
|
7
7
|
"publishConfig": {
|
|
8
8
|
"access": "public"
|
|
9
9
|
},
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
"dependencies": {
|
|
24
24
|
"@khanacademy/kas": "^0.3.1",
|
|
25
25
|
"@khanacademy/kmath": "^0.1.1",
|
|
26
|
-
"@khanacademy/perseus": "^
|
|
26
|
+
"@khanacademy/perseus": "^6.0.0"
|
|
27
27
|
},
|
|
28
28
|
"devDependencies": {
|
|
29
29
|
"@khanacademy/wonder-blocks-button": "^4.0.8",
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {ApiOptions
|
|
1
|
+
import {ApiOptions} from "@khanacademy/perseus";
|
|
2
2
|
import * as React from "react";
|
|
3
3
|
|
|
4
4
|
import {question1} from "../__testdata__/input-number.testdata";
|
|
@@ -11,7 +11,6 @@ export default {
|
|
|
11
11
|
|
|
12
12
|
export const Rational = (): React.ReactElement => {
|
|
13
13
|
registerAllWidgetsAndEditorsForTesting();
|
|
14
|
-
Dependencies.getDependencies().shouldUseFutureKaTeX(false);
|
|
15
14
|
|
|
16
15
|
return (
|
|
17
16
|
<Editor
|
|
@@ -13,9 +13,9 @@ export default {
|
|
|
13
13
|
title: "Perseus Editor/Widgets/Section Control Button",
|
|
14
14
|
} as Story;
|
|
15
15
|
|
|
16
|
-
export const ButtonForEditingSectionsOfContentWithInArticleEditor
|
|
17
|
-
StoryArgs
|
|
18
|
-
|
|
16
|
+
export const ButtonForEditingSectionsOfContentWithInArticleEditor = (
|
|
17
|
+
args: StoryArgs,
|
|
18
|
+
): React.ReactElement => {
|
|
19
19
|
return (
|
|
20
20
|
<SectionControlButton
|
|
21
21
|
icon={icons.iconTrash}
|
|
@@ -5,6 +5,7 @@ import * as React from "react";
|
|
|
5
5
|
import "@testing-library/jest-dom"; // Imports custom mathers
|
|
6
6
|
|
|
7
7
|
import {testDependencies} from "../../../../testing/test-dependencies";
|
|
8
|
+
import {wait} from "../../../../testing/wait";
|
|
8
9
|
import {question1} from "../__testdata__/input-number.testdata";
|
|
9
10
|
import Editor from "../editor";
|
|
10
11
|
|
|
@@ -23,11 +24,11 @@ describe("Editor", () => {
|
|
|
23
24
|
]);
|
|
24
25
|
Widgets.registerWidgets([InputNumberWidget]);
|
|
25
26
|
Widgets.registerEditors([InputNumberEditor]);
|
|
27
|
+
jest.useRealTimers();
|
|
26
28
|
});
|
|
27
29
|
|
|
28
30
|
test("clicking on the widget editor should open it", async () => {
|
|
29
31
|
// Arrange
|
|
30
|
-
testDependencies.shouldUseFutureKaTeX(false);
|
|
31
32
|
render(
|
|
32
33
|
<Editor
|
|
33
34
|
apiOptions={ApiOptions.defaults}
|
|
@@ -44,7 +45,7 @@ describe("Editor", () => {
|
|
|
44
45
|
onChange={(props) => {}}
|
|
45
46
|
/>,
|
|
46
47
|
);
|
|
47
|
-
await
|
|
48
|
+
await wait();
|
|
48
49
|
|
|
49
50
|
// Act
|
|
50
51
|
const widgetDisclosure = screen.getByRole("link", {
|
|
@@ -60,7 +61,6 @@ describe("Editor", () => {
|
|
|
60
61
|
it("should update values", async () => {
|
|
61
62
|
// Arrange
|
|
62
63
|
const changeFn = jest.fn();
|
|
63
|
-
testDependencies.shouldUseFutureKaTeX(false);
|
|
64
64
|
render(
|
|
65
65
|
<Editor
|
|
66
66
|
apiOptions={ApiOptions.defaults}
|
|
@@ -77,7 +77,7 @@ describe("Editor", () => {
|
|
|
77
77
|
onChange={changeFn}
|
|
78
78
|
/>,
|
|
79
79
|
);
|
|
80
|
-
await
|
|
80
|
+
await wait();
|
|
81
81
|
|
|
82
82
|
// Act
|
|
83
83
|
const widgetDisclosure = screen.getByRole("link", {
|
package/src/article-editor.tsx
CHANGED
|
@@ -9,7 +9,6 @@ import {
|
|
|
9
9
|
icons,
|
|
10
10
|
ApiOptions,
|
|
11
11
|
Changeable,
|
|
12
|
-
Dependencies,
|
|
13
12
|
Errors,
|
|
14
13
|
PerseusError,
|
|
15
14
|
} from "@khanacademy/perseus";
|
|
@@ -44,7 +43,7 @@ type DefaultProps = {
|
|
|
44
43
|
) => React.ReactElement<React.ComponentProps<"span">>;
|
|
45
44
|
useNewStyles: boolean;
|
|
46
45
|
};
|
|
47
|
-
type
|
|
46
|
+
type Props = DefaultProps & {
|
|
48
47
|
apiOptions?: APIOptions;
|
|
49
48
|
imageUploader?: (arg1: string, arg2: (arg1: string) => unknown) => unknown;
|
|
50
49
|
// URL of the route to show on initial load of the preview frames.
|
|
@@ -54,10 +53,7 @@ type PerseusArticleEditorProps = DefaultProps & {
|
|
|
54
53
|
type State = {
|
|
55
54
|
highlightLint: boolean;
|
|
56
55
|
};
|
|
57
|
-
export default class ArticleEditor extends React.Component<
|
|
58
|
-
PerseusArticleEditorProps,
|
|
59
|
-
State
|
|
60
|
-
> {
|
|
56
|
+
export default class ArticleEditor extends React.Component<Props, State> {
|
|
61
57
|
static defaultProps: DefaultProps = {
|
|
62
58
|
contentPaths: [],
|
|
63
59
|
json: [{}],
|
|
@@ -144,8 +140,6 @@ export default class ArticleEditor extends React.Component<
|
|
|
144
140
|
isArticle: true,
|
|
145
141
|
} as const;
|
|
146
142
|
|
|
147
|
-
const {KatexProvider} = Dependencies.getDependencies();
|
|
148
|
-
|
|
149
143
|
const sections = this._sections();
|
|
150
144
|
|
|
151
145
|
return (
|
|
@@ -212,19 +206,17 @@ export default class ArticleEditor extends React.Component<
|
|
|
212
206
|
/>
|
|
213
207
|
</div>
|
|
214
208
|
</div>
|
|
215
|
-
<
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
/>
|
|
227
|
-
</KatexProvider>
|
|
209
|
+
<Editor
|
|
210
|
+
{...section}
|
|
211
|
+
apiOptions={apiOptions}
|
|
212
|
+
imageUploader={imageUploader}
|
|
213
|
+
onChange={_.partial(
|
|
214
|
+
this._handleEditorChange,
|
|
215
|
+
i,
|
|
216
|
+
)}
|
|
217
|
+
placeholder="Type your section text here..."
|
|
218
|
+
ref={"editor" + i}
|
|
219
|
+
/>
|
|
228
220
|
</div>
|
|
229
221
|
|
|
230
222
|
<div className="editor-preview">
|
|
@@ -31,7 +31,7 @@ const findAndFocusElement = (component?: Element | null) => {
|
|
|
31
31
|
}
|
|
32
32
|
};
|
|
33
33
|
|
|
34
|
-
type
|
|
34
|
+
type Props = {
|
|
35
35
|
// The value to use when the option is selected
|
|
36
36
|
value: string;
|
|
37
37
|
// The display of the option
|
|
@@ -65,7 +65,7 @@ const check = `M10,3.8C10,4,9.9,4.2,9.8,4.3L5.1,8.9L4.3,9.8C4.2,9.9,4,10,3.8,10
|
|
|
65
65
|
|
|
66
66
|
export const optionHeight = 30;
|
|
67
67
|
|
|
68
|
-
class Option extends React.Component<
|
|
68
|
+
class Option extends React.Component<Props> {
|
|
69
69
|
// @ts-expect-error [FEI-5003] - TS2564 - Property 'node' has no initializer and is not definitely assigned in the constructor.
|
|
70
70
|
node: HTMLDivElement;
|
|
71
71
|
|
package/src/components/link.ts
CHANGED
|
@@ -24,7 +24,7 @@ type DefaultProps = {
|
|
|
24
24
|
style: CSSProperties | Array<CSSProperties>;
|
|
25
25
|
};
|
|
26
26
|
|
|
27
|
-
type
|
|
27
|
+
type Props = DefaultProps & {
|
|
28
28
|
children?: React.ReactNode;
|
|
29
29
|
// An additional class name to add. This is supported so-as to allow
|
|
30
30
|
// Perseus to add class-based styles to links when using this
|
|
@@ -66,7 +66,7 @@ type LinkProps = DefaultProps & {
|
|
|
66
66
|
/**
|
|
67
67
|
* A wrapper that creates an anchor tag with normalized styles
|
|
68
68
|
*/
|
|
69
|
-
class Link extends React.Component<
|
|
69
|
+
class Link extends React.Component<Props> {
|
|
70
70
|
static defaultProps: DefaultProps = {
|
|
71
71
|
highlighted: false,
|
|
72
72
|
href: DEFAULT_HREF,
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
type Props = {
|
|
4
4
|
children: React.ReactNode;
|
|
5
|
-
}
|
|
5
|
+
};
|
|
6
|
+
|
|
7
|
+
const Wrapper = ({children}: Props): React.ReactElement => {
|
|
6
8
|
return <div className="perseus-diff">{children}</div>;
|
|
7
9
|
};
|
|
8
10
|
|
|
@@ -33,7 +33,7 @@ const tags = {
|
|
|
33
33
|
c: "c tag",
|
|
34
34
|
} as const;
|
|
35
35
|
|
|
36
|
-
export const ContentAdded
|
|
36
|
+
export const ContentAdded = (args: StoryArgs): React.ReactElement => {
|
|
37
37
|
const props = {
|
|
38
38
|
before: {
|
|
39
39
|
_multi: {
|
|
@@ -175,8 +175,8 @@ export const ContentAdded: React.FC<StoryArgs> = (args): React.ReactElement => {
|
|
|
175
175
|
};
|
|
176
176
|
|
|
177
177
|
// second instance
|
|
178
|
-
export const ContentAddedRemovedAndChanged
|
|
179
|
-
args,
|
|
178
|
+
export const ContentAddedRemovedAndChanged = (
|
|
179
|
+
args: StoryArgs,
|
|
180
180
|
): React.ReactElement => {
|
|
181
181
|
const props = {
|
|
182
182
|
before: {
|
|
@@ -383,9 +383,7 @@ export const ContentAddedRemovedAndChanged: React.FC<StoryArgs> = (
|
|
|
383
383
|
};
|
|
384
384
|
|
|
385
385
|
// third instance
|
|
386
|
-
export const MiscContentChanges: React.
|
|
387
|
-
args,
|
|
388
|
-
): React.ReactElement => {
|
|
386
|
+
export const MiscContentChanges = (args: StoryArgs): React.ReactElement => {
|
|
389
387
|
const props = {
|
|
390
388
|
before: {
|
|
391
389
|
_multi: {
|
|
@@ -681,9 +679,7 @@ export const MiscContentChanges: React.FC<StoryArgs> = (
|
|
|
681
679
|
};
|
|
682
680
|
|
|
683
681
|
// fourth
|
|
684
|
-
export const ContentRemoved: React.
|
|
685
|
-
args,
|
|
686
|
-
): React.ReactElement => {
|
|
682
|
+
export const ContentRemoved = (args: StoryArgs): React.ReactElement => {
|
|
687
683
|
const props = {
|
|
688
684
|
before: {
|
|
689
685
|
_multi: {
|
package/src/editor.tsx
CHANGED
|
@@ -2,7 +2,6 @@ import {
|
|
|
2
2
|
components,
|
|
3
3
|
icons,
|
|
4
4
|
preprocessTex,
|
|
5
|
-
Dependencies,
|
|
6
5
|
Errors,
|
|
7
6
|
Log,
|
|
8
7
|
PerseusError,
|
|
@@ -127,9 +126,7 @@ type WidgetEditorState = {
|
|
|
127
126
|
widgetInfo: WidgetInfo;
|
|
128
127
|
};
|
|
129
128
|
|
|
130
|
-
const _upgradeWidgetInfo: React.
|
|
131
|
-
props,
|
|
132
|
-
): React.ReactElement => {
|
|
129
|
+
const _upgradeWidgetInfo = (props: WidgetEditorProps): React.ReactElement => {
|
|
133
130
|
// We can't call serialize here because this.refs.widget
|
|
134
131
|
// doesn't exist before this component is mounted.
|
|
135
132
|
const filteredProps = _.omit(props, WIDGET_PROP_DENYLIST);
|
|
@@ -368,7 +365,7 @@ const imageUrlsFromContent = function (content: string) {
|
|
|
368
365
|
return _.map(allMatches(IMAGE_REGEX, content), (capture) => capture[1]);
|
|
369
366
|
};
|
|
370
367
|
|
|
371
|
-
type
|
|
368
|
+
type Props = Readonly<{
|
|
372
369
|
apiOptions: any;
|
|
373
370
|
className?: string;
|
|
374
371
|
content: string;
|
|
@@ -406,14 +403,12 @@ type DeafultProps = {
|
|
|
406
403
|
};
|
|
407
404
|
};
|
|
408
405
|
|
|
409
|
-
type
|
|
410
|
-
showKatexErrors: boolean;
|
|
406
|
+
type State = {
|
|
411
407
|
textAreaValue: string;
|
|
412
|
-
katex?: katex;
|
|
413
408
|
};
|
|
414
409
|
|
|
415
410
|
// eslint-disable-next-line react/no-unsafe
|
|
416
|
-
class Editor extends React.Component<
|
|
411
|
+
class Editor extends React.Component<Props, State> {
|
|
417
412
|
lastUserValue: string | null | undefined;
|
|
418
413
|
deferredChange: any | null | undefined;
|
|
419
414
|
widgetIds: any | null | undefined;
|
|
@@ -431,9 +426,7 @@ class Editor extends React.Component<EditorProps, EditorState> {
|
|
|
431
426
|
warnNoWidgets: false,
|
|
432
427
|
};
|
|
433
428
|
|
|
434
|
-
state:
|
|
435
|
-
katex: undefined,
|
|
436
|
-
showKatexErrors: false,
|
|
429
|
+
state: State = {
|
|
437
430
|
textAreaValue: this.props.content,
|
|
438
431
|
};
|
|
439
432
|
|
|
@@ -452,24 +445,16 @@ class Editor extends React.Component<EditorProps, EditorState> {
|
|
|
452
445
|
// @ts-expect-error [FEI-5003] - TS2339 - Property 'on' does not exist on type 'JQueryStatic'.
|
|
453
446
|
.on("copy cut", this._maybeCopyWidgets)
|
|
454
447
|
.on("paste", this._maybePasteWidgets);
|
|
455
|
-
|
|
456
|
-
Dependencies.getDependencies()
|
|
457
|
-
.getKaTeX()
|
|
458
|
-
.then((katex) => {
|
|
459
|
-
this.setState({
|
|
460
|
-
katex,
|
|
461
|
-
});
|
|
462
|
-
});
|
|
463
448
|
}
|
|
464
449
|
|
|
465
450
|
// TODO(arun): This is a deprecated method, use the appropriate replacement
|
|
466
|
-
UNSAFE_componentWillReceiveProps(nextProps:
|
|
451
|
+
UNSAFE_componentWillReceiveProps(nextProps: Props) {
|
|
467
452
|
if (this.props.content !== nextProps.content) {
|
|
468
453
|
this.setState({textAreaValue: nextProps.content});
|
|
469
454
|
}
|
|
470
455
|
}
|
|
471
456
|
|
|
472
|
-
componentDidUpdate(prevProps:
|
|
457
|
+
componentDidUpdate(prevProps: Props) {
|
|
473
458
|
// TODO(alpert): Maybe fix React so this isn't necessary
|
|
474
459
|
// eslint-disable-next-line react/no-string-refs
|
|
475
460
|
const textarea = ReactDOM.findDOMNode(this.refs.textarea);
|
|
@@ -574,7 +559,7 @@ class Editor extends React.Component<EditorProps, EditorState> {
|
|
|
574
559
|
* Calculate the size of all the images in props.content, and send
|
|
575
560
|
* those sizes to this.props.images using props.onChange.
|
|
576
561
|
*/
|
|
577
|
-
_sizeImages: (props:
|
|
562
|
+
_sizeImages: (props: Props) => void = (props: Props) => {
|
|
578
563
|
const imageUrls = imageUrlsFromContent(props.content);
|
|
579
564
|
|
|
580
565
|
// Discard any images in our dimension table that no
|
|
@@ -1194,9 +1179,7 @@ class Editor extends React.Component<EditorProps, EditorState> {
|
|
|
1194
1179
|
);
|
|
1195
1180
|
}
|
|
1196
1181
|
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
if (this.props.widgetEnabled && katex) {
|
|
1182
|
+
if (this.props.widgetEnabled) {
|
|
1200
1183
|
pieces = Util.split(this.props.content, rWidgetSplit);
|
|
1201
1184
|
widgets = {};
|
|
1202
1185
|
underlayPieces = [];
|