@khanacademy/perseus-editor 2.13.0 → 2.14.1
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 +25 -0
- package/dist/es/index.js +30 -12
- package/dist/es/index.js.map +1 -1
- package/dist/index.js +30 -12
- package/dist/index.js.map +1 -1
- package/dist/item-extras-editor.d.ts +12 -12
- package/dist/widgets/label-image/behavior.d.ts +4 -1
- package/package.json +9 -9
- package/src/__tests__/items-extras-editors.test.tsx +68 -0
- package/src/item-extras-editor.tsx +17 -13
- package/src/widgets/label-image/__stories__/behavior.stories.tsx +1 -1
- package/src/widgets/label-image/behavior.tsx +32 -0
- package/src/widgets/label-image-editor.tsx +1 -0
- package/tsconfig-build.tsbuildinfo +1 -1
|
@@ -1,17 +1,17 @@
|
|
|
1
|
-
import PropTypes from "prop-types";
|
|
2
1
|
import * as React from "react";
|
|
3
|
-
type
|
|
2
|
+
type ItemExtrasProps = {
|
|
3
|
+
calculator: boolean;
|
|
4
|
+
chi2Table: boolean;
|
|
5
|
+
periodicTable: boolean;
|
|
6
|
+
periodicTableWithKey: boolean;
|
|
7
|
+
tTable: boolean;
|
|
8
|
+
zTable: boolean;
|
|
9
|
+
};
|
|
10
|
+
type Props = ItemExtrasProps & {
|
|
11
|
+
onChange: (props: Partial<ItemExtrasProps>) => void;
|
|
12
|
+
};
|
|
4
13
|
declare class ItemExtrasEditor extends React.Component<Props> {
|
|
5
|
-
static
|
|
6
|
-
calculator: PropTypes.Requireable<boolean>;
|
|
7
|
-
chi2Table: PropTypes.Requireable<boolean>;
|
|
8
|
-
onChange: PropTypes.Validator<(...args: any[]) => any>;
|
|
9
|
-
periodicTable: PropTypes.Requireable<boolean>;
|
|
10
|
-
periodicTableWithKey: PropTypes.Requireable<boolean>;
|
|
11
|
-
tTable: PropTypes.Requireable<boolean>;
|
|
12
|
-
zTable: PropTypes.Requireable<boolean>;
|
|
13
|
-
};
|
|
14
|
-
static defaultProps: Props;
|
|
14
|
+
static defaultProps: ItemExtrasProps;
|
|
15
15
|
serialize: () => any;
|
|
16
16
|
render(): React.ReactNode;
|
|
17
17
|
}
|
|
@@ -2,13 +2,16 @@
|
|
|
2
2
|
* Controlled component to display and change widget options.
|
|
3
3
|
*/
|
|
4
4
|
import * as React from "react";
|
|
5
|
+
export type PreferredPopoverDirection = "NONE" | "UP" | "DOWN" | "LEFT" | "RIGHT";
|
|
5
6
|
type Props = {
|
|
6
7
|
multipleAnswers: boolean;
|
|
7
8
|
hideChoicesFromInstructions: boolean;
|
|
9
|
+
preferredPopoverDirection: PreferredPopoverDirection;
|
|
8
10
|
onChange: (options: {
|
|
9
11
|
multipleAnswers?: boolean;
|
|
10
12
|
hideChoicesFromInstructions?: boolean;
|
|
13
|
+
preferredPopoverDirection?: PreferredPopoverDirection;
|
|
11
14
|
}) => void;
|
|
12
15
|
};
|
|
13
|
-
declare const Behavior: ({ multipleAnswers, hideChoicesFromInstructions, onChange, }: Props) => React.ReactElement;
|
|
16
|
+
declare const Behavior: ({ multipleAnswers, hideChoicesFromInstructions, preferredPopoverDirection, onChange, }: Props) => React.ReactElement;
|
|
14
17
|
export default Behavior;
|
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.
|
|
6
|
+
"version": "2.14.1",
|
|
7
7
|
"publishConfig": {
|
|
8
8
|
"access": "public"
|
|
9
9
|
},
|
|
@@ -22,18 +22,18 @@
|
|
|
22
22
|
"test": "bash -c 'yarn --silent --cwd \"../..\" test ${@:0} $($([[ ${@: -1} = -* ]] || [[ ${@: -1} = bash ]]) && echo $PWD)'"
|
|
23
23
|
},
|
|
24
24
|
"dependencies": {
|
|
25
|
-
"@khanacademy/kas": "^0.3.
|
|
26
|
-
"@khanacademy/kmath": "^0.1.
|
|
27
|
-
"@khanacademy/perseus": "^17.
|
|
28
|
-
"@khanacademy/perseus-core": "1.4.
|
|
25
|
+
"@khanacademy/kas": "^0.3.7",
|
|
26
|
+
"@khanacademy/kmath": "^0.1.8",
|
|
27
|
+
"@khanacademy/perseus": "^17.1.1",
|
|
28
|
+
"@khanacademy/perseus-core": "1.4.1"
|
|
29
29
|
},
|
|
30
30
|
"devDependencies": {
|
|
31
|
-
"@khanacademy/wonder-blocks-button": "^6.2.
|
|
31
|
+
"@khanacademy/wonder-blocks-button": "^6.2.4",
|
|
32
32
|
"@khanacademy/wonder-blocks-clickable": "^4.0.11",
|
|
33
33
|
"@khanacademy/wonder-blocks-color": "^3.0.0",
|
|
34
34
|
"@khanacademy/wonder-blocks-core": "^6.3.0",
|
|
35
|
-
"@khanacademy/wonder-blocks-icon": "2.2.1",
|
|
36
35
|
"@khanacademy/wonder-blocks-i18n": "^2.0.2",
|
|
36
|
+
"@khanacademy/wonder-blocks-icon": "4.0.0",
|
|
37
37
|
"@khanacademy/wonder-blocks-spacing": "^4.0.1",
|
|
38
38
|
"@khanacademy/wonder-blocks-typography": "^2.1.9",
|
|
39
39
|
"@khanacademy/wonder-stuff-core": "^1.5.1",
|
|
@@ -50,12 +50,12 @@
|
|
|
50
50
|
"underscore": "^1.4.4"
|
|
51
51
|
},
|
|
52
52
|
"peerDependencies": {
|
|
53
|
-
"@khanacademy/wonder-blocks-button": "^6.2.
|
|
53
|
+
"@khanacademy/wonder-blocks-button": "^6.2.4",
|
|
54
54
|
"@khanacademy/wonder-blocks-clickable": "^4.0.11",
|
|
55
55
|
"@khanacademy/wonder-blocks-color": "^3.0.0",
|
|
56
56
|
"@khanacademy/wonder-blocks-core": "^6.3.0",
|
|
57
|
-
"@khanacademy/wonder-blocks-icon": "2.2.1",
|
|
58
57
|
"@khanacademy/wonder-blocks-i18n": "^2.0.2",
|
|
58
|
+
"@khanacademy/wonder-blocks-icon": "4.0.0",
|
|
59
59
|
"@khanacademy/wonder-blocks-spacing": "^4.0.1",
|
|
60
60
|
"@khanacademy/wonder-blocks-typography": "^2.1.9",
|
|
61
61
|
"@khanacademy/wonder-stuff-core": "^1.5.1",
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import "@testing-library/jest-dom";
|
|
2
|
+
import {render, screen} from "@testing-library/react";
|
|
3
|
+
import userEvent from "@testing-library/user-event";
|
|
4
|
+
import React from "react";
|
|
5
|
+
|
|
6
|
+
import ItemExtrasEditor from "../item-extras-editor";
|
|
7
|
+
|
|
8
|
+
describe("ItemExtrasEditor", () => {
|
|
9
|
+
it("should render correctly with default props", () => {
|
|
10
|
+
// Act
|
|
11
|
+
render(<ItemExtrasEditor onChange={() => {}} />);
|
|
12
|
+
|
|
13
|
+
// Assert
|
|
14
|
+
expect(screen.getByLabelText("Show calculator:")).not.toBeChecked();
|
|
15
|
+
expect(screen.getByLabelText("Show periodic table:")).not.toBeChecked();
|
|
16
|
+
expect(
|
|
17
|
+
screen.queryByText("Include key/legend with periodic table:"),
|
|
18
|
+
).not.toBeInTheDocument();
|
|
19
|
+
expect(
|
|
20
|
+
screen.getByLabelText("Show z table (statistics):"),
|
|
21
|
+
).not.toBeChecked();
|
|
22
|
+
expect(
|
|
23
|
+
screen.getByLabelText("Show t table (statistics):"),
|
|
24
|
+
).not.toBeChecked();
|
|
25
|
+
expect(
|
|
26
|
+
screen.getByLabelText("Show chi-squared table (statistics):"),
|
|
27
|
+
).not.toBeChecked();
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
it("should call onChange with updated calculator value", () => {
|
|
31
|
+
// Arrange
|
|
32
|
+
const onChangeMock = jest.fn();
|
|
33
|
+
render(<ItemExtrasEditor calculator={false} onChange={onChangeMock} />);
|
|
34
|
+
const checkbox = screen.getByLabelText("Show calculator:");
|
|
35
|
+
|
|
36
|
+
// Act
|
|
37
|
+
userEvent.click(checkbox);
|
|
38
|
+
|
|
39
|
+
// Assert
|
|
40
|
+
expect(onChangeMock).toHaveBeenCalledWith({calculator: true});
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
it("should call onChange with updated periodicTableWithKey value when periodicTable is unchecked", () => {
|
|
44
|
+
// Arrange
|
|
45
|
+
const onChangeMock = jest.fn();
|
|
46
|
+
render(
|
|
47
|
+
<ItemExtrasEditor
|
|
48
|
+
periodicTable={true}
|
|
49
|
+
periodicTableWithKey={true}
|
|
50
|
+
onChange={onChangeMock}
|
|
51
|
+
/>,
|
|
52
|
+
);
|
|
53
|
+
const checkbox = screen.getByLabelText("Show periodic table:");
|
|
54
|
+
|
|
55
|
+
// Act
|
|
56
|
+
userEvent.click(checkbox);
|
|
57
|
+
|
|
58
|
+
// Assert
|
|
59
|
+
// visible when periodicTable is checked
|
|
60
|
+
expect(
|
|
61
|
+
screen.getByText("Include key/legend with periodic table:"),
|
|
62
|
+
).toBeInTheDocument();
|
|
63
|
+
expect(onChangeMock).toHaveBeenCalledWith({
|
|
64
|
+
periodicTable: false,
|
|
65
|
+
periodicTableWithKey: false,
|
|
66
|
+
});
|
|
67
|
+
});
|
|
68
|
+
});
|
|
@@ -1,23 +1,23 @@
|
|
|
1
1
|
import {components} from "@khanacademy/perseus";
|
|
2
|
-
import PropTypes from "prop-types";
|
|
3
2
|
import * as React from "react";
|
|
4
3
|
|
|
5
4
|
const {InfoTip} = components;
|
|
6
5
|
|
|
7
|
-
type
|
|
6
|
+
type ItemExtrasProps = {
|
|
7
|
+
calculator: boolean;
|
|
8
|
+
chi2Table: boolean;
|
|
9
|
+
periodicTable: boolean;
|
|
10
|
+
periodicTableWithKey: boolean;
|
|
11
|
+
tTable: boolean;
|
|
12
|
+
zTable: boolean;
|
|
13
|
+
};
|
|
8
14
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
chi2Table: PropTypes.bool,
|
|
13
|
-
onChange: PropTypes.func.isRequired,
|
|
14
|
-
periodicTable: PropTypes.bool,
|
|
15
|
-
periodicTableWithKey: PropTypes.bool,
|
|
16
|
-
tTable: PropTypes.bool,
|
|
17
|
-
zTable: PropTypes.bool,
|
|
18
|
-
};
|
|
15
|
+
type Props = ItemExtrasProps & {
|
|
16
|
+
onChange: (props: Partial<ItemExtrasProps>) => void;
|
|
17
|
+
};
|
|
19
18
|
|
|
20
|
-
|
|
19
|
+
class ItemExtrasEditor extends React.Component<Props> {
|
|
20
|
+
static defaultProps: ItemExtrasProps = {
|
|
21
21
|
calculator: false,
|
|
22
22
|
chi2Table: false,
|
|
23
23
|
periodicTable: false,
|
|
@@ -71,6 +71,10 @@ class ItemExtrasEditor extends React.Component<Props> {
|
|
|
71
71
|
onChange={(e) => {
|
|
72
72
|
this.props.onChange({
|
|
73
73
|
periodicTable: e.target.checked,
|
|
74
|
+
// If the periodic table is unchecked,
|
|
75
|
+
// this needs to be reset. If table is
|
|
76
|
+
// checked, it should already be false.
|
|
77
|
+
periodicTableWithKey: false,
|
|
74
78
|
});
|
|
75
79
|
}}
|
|
76
80
|
/>
|
|
@@ -10,21 +10,32 @@ import Checkbox from "../../components/checkbox";
|
|
|
10
10
|
|
|
11
11
|
const {colors, typography} = globalStyles;
|
|
12
12
|
|
|
13
|
+
export type PreferredPopoverDirection =
|
|
14
|
+
| "NONE"
|
|
15
|
+
| "UP"
|
|
16
|
+
| "DOWN"
|
|
17
|
+
| "LEFT"
|
|
18
|
+
| "RIGHT";
|
|
19
|
+
|
|
13
20
|
type Props = {
|
|
14
21
|
// Whether multiple answer choices may be selected for markers.
|
|
15
22
|
multipleAnswers: boolean;
|
|
16
23
|
// Whether to hide answer choices from user instructions.
|
|
17
24
|
hideChoicesFromInstructions: boolean;
|
|
25
|
+
|
|
26
|
+
preferredPopoverDirection: PreferredPopoverDirection;
|
|
18
27
|
// Callback for when widget options change.
|
|
19
28
|
onChange: (options: {
|
|
20
29
|
multipleAnswers?: boolean;
|
|
21
30
|
hideChoicesFromInstructions?: boolean;
|
|
31
|
+
preferredPopoverDirection?: PreferredPopoverDirection;
|
|
22
32
|
}) => void;
|
|
23
33
|
};
|
|
24
34
|
|
|
25
35
|
const Behavior = ({
|
|
26
36
|
multipleAnswers,
|
|
27
37
|
hideChoicesFromInstructions,
|
|
38
|
+
preferredPopoverDirection,
|
|
28
39
|
onChange,
|
|
29
40
|
}: Props): React.ReactElement => (
|
|
30
41
|
<div>
|
|
@@ -59,6 +70,27 @@ const Behavior = ({
|
|
|
59
70
|
Do not display answer choices in instructions
|
|
60
71
|
</span>
|
|
61
72
|
</li>
|
|
73
|
+
|
|
74
|
+
<li className={css(styles.option)}>
|
|
75
|
+
<span className={css(styles.label)}>
|
|
76
|
+
Preferred pop-over direction
|
|
77
|
+
</span>
|
|
78
|
+
<select
|
|
79
|
+
value={preferredPopoverDirection}
|
|
80
|
+
onChange={(e) => {
|
|
81
|
+
onChange({
|
|
82
|
+
preferredPopoverDirection: e.target
|
|
83
|
+
.value as PreferredPopoverDirection,
|
|
84
|
+
});
|
|
85
|
+
}}
|
|
86
|
+
>
|
|
87
|
+
<option value="NONE"> No Preference </option>
|
|
88
|
+
<option value="UP"> Up </option>
|
|
89
|
+
<option value="DOWN"> Down </option>
|
|
90
|
+
<option value="LEFT"> Left </option>
|
|
91
|
+
<option value="RIGHT"> Right </option>
|
|
92
|
+
</select>
|
|
93
|
+
</li>
|
|
62
94
|
</ul>
|
|
63
95
|
</div>
|
|
64
96
|
);
|
|
@@ -229,6 +229,7 @@ class LabelImageEditor extends React.Component<Props> {
|
|
|
229
229
|
<div className={css(styles.largeSpacer)} />
|
|
230
230
|
|
|
231
231
|
<Behavior
|
|
232
|
+
preferredPopoverDirection="NONE"
|
|
232
233
|
multipleAnswers={multipleAnswers}
|
|
233
234
|
hideChoicesFromInstructions={hideChoicesFromInstructions}
|
|
234
235
|
onChange={this.handleBehaviorChange}
|