@khanacademy/perseus-editor 4.1.5 → 4.1.6

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 (175) hide show
  1. package/dist/es/index.js +1 -1
  2. package/dist/index.js +1 -1
  3. package/package.json +9 -6
  4. package/.babelrc.js +0 -8
  5. package/.eslintrc.js +0 -12
  6. package/CHANGELOG.md +0 -1155
  7. package/src/README.md +0 -7
  8. package/src/__stories__/editor-page.stories.tsx +0 -65
  9. package/src/__stories__/editor.stories.tsx +0 -134
  10. package/src/__stories__/item-editor.stories.tsx +0 -41
  11. package/src/__stories__/tex-error-view.stories.tsx +0 -26
  12. package/src/__testdata__/input-number.testdata.ts +0 -27
  13. package/src/__tests__/editor.test.tsx +0 -142
  14. package/src/__tests__/hint-editor.test.tsx +0 -83
  15. package/src/__tests__/i18n.test.ts +0 -501
  16. package/src/__tests__/integration.test.ts +0 -5
  17. package/src/__tests__/item-extras-editor.test.tsx +0 -85
  18. package/src/__tests__/traversal.test.ts +0 -377
  19. package/src/all-editors.test.ts +0 -16
  20. package/src/all-editors.ts +0 -83
  21. package/src/all-widgets.ts +0 -7
  22. package/src/article-editor.tsx +0 -438
  23. package/src/components/__stories__/blur-input.stories.tsx +0 -22
  24. package/src/components/__stories__/section-control-button.stories.tsx +0 -26
  25. package/src/components/__tests__/blur-input.test.tsx +0 -67
  26. package/src/components/blur-input.tsx +0 -69
  27. package/src/components/checkbox.tsx +0 -194
  28. package/src/components/device-framer.tsx +0 -90
  29. package/src/components/drag-target.tsx +0 -87
  30. package/src/components/dropdown-option.tsx +0 -311
  31. package/src/components/form-wrapped-text-field.tsx +0 -245
  32. package/src/components/graph-points-count-selector.tsx +0 -31
  33. package/src/components/graph-settings.tsx +0 -627
  34. package/src/components/graph-type-selector.tsx +0 -31
  35. package/src/components/hover-behavior.ts +0 -177
  36. package/src/components/json-editor.tsx +0 -121
  37. package/src/components/link.ts +0 -173
  38. package/src/components/section-control-button.tsx +0 -53
  39. package/src/components/segment-count-selector.tsx +0 -27
  40. package/src/components/simple-button.tsx +0 -85
  41. package/src/components/sortable.tsx +0 -187
  42. package/src/components/util.ts +0 -38
  43. package/src/components/viewport-resizer.tsx +0 -72
  44. package/src/components/widget-editor.tsx +0 -222
  45. package/src/components/widget-select.tsx +0 -48
  46. package/src/diffs/__stories__/perseus-diff-wrapper.tsx +0 -11
  47. package/src/diffs/__stories__/structured-item-diff.stories.tsx +0 -855
  48. package/src/diffs/__stories__/tags-diff.stories.tsx +0 -36
  49. package/src/diffs/__stories__/text-diff.stories.tsx +0 -35
  50. package/src/diffs/__tests__/split-diff.test.ts +0 -33
  51. package/src/diffs/__tests__/string-array-diff.test.ts +0 -73
  52. package/src/diffs/__tests__/structured-item-diff.test.ts +0 -433
  53. package/src/diffs/__tests__/widget-diff-performer.test.ts +0 -43
  54. package/src/diffs/article-diff.tsx +0 -69
  55. package/src/diffs/item-diff.tsx +0 -76
  56. package/src/diffs/renderer-diff.tsx +0 -137
  57. package/src/diffs/split-diff.ts +0 -31
  58. package/src/diffs/string-array-diff.ts +0 -74
  59. package/src/diffs/structured-item-diff.tsx +0 -275
  60. package/src/diffs/tags-diff.tsx +0 -49
  61. package/src/diffs/text-diff.tsx +0 -193
  62. package/src/diffs/widget-diff-performer.ts +0 -69
  63. package/src/diffs/widget-diff.tsx +0 -290
  64. package/src/editor-page.tsx +0 -325
  65. package/src/editor.tsx +0 -1099
  66. package/src/hint-editor.tsx +0 -469
  67. package/src/i18n.ts +0 -140
  68. package/src/iframe-content-renderer.tsx +0 -188
  69. package/src/index.ts +0 -30
  70. package/src/item-editor.tsx +0 -158
  71. package/src/item-extras-editor.tsx +0 -230
  72. package/src/katex-mhchem/index.js +0 -73
  73. package/src/katex-mhchem/parser.js +0 -2659
  74. package/src/multirenderer-editor.tsx +0 -1061
  75. package/src/stateful-article-editor.tsx +0 -173
  76. package/src/stateful-editor-page.tsx +0 -88
  77. package/src/styles/perseus-editor.less +0 -1321
  78. package/src/testing-widgets.ts +0 -11
  79. package/src/tex-error-view.tsx +0 -90
  80. package/src/util/points.test.ts +0 -24
  81. package/src/util/points.ts +0 -13
  82. package/src/util/register-all-widgets-and-editors-for-testing.test.ts +0 -17
  83. package/src/util/register-all-widgets-and-editors-for-testing.ts +0 -17
  84. package/src/version.ts +0 -10
  85. package/src/widgets/__stories__/categorizer-editor.stories.tsx +0 -24
  86. package/src/widgets/__stories__/definition-editor.stories.tsx +0 -18
  87. package/src/widgets/__stories__/dropdown-editor.stories.tsx +0 -18
  88. package/src/widgets/__stories__/explanation-editor.stories.tsx +0 -18
  89. package/src/widgets/__stories__/expression-editor.stories.tsx +0 -122
  90. package/src/widgets/__stories__/image-editor.stories.tsx +0 -72
  91. package/src/widgets/__stories__/input-number-editor.stories.tsx +0 -18
  92. package/src/widgets/__stories__/interaction-editor.stories.tsx +0 -37
  93. package/src/widgets/__stories__/label-image-editor.stories.tsx +0 -99
  94. package/src/widgets/__stories__/matcher-editor.stories.tsx +0 -18
  95. package/src/widgets/__stories__/number-line-editor.stories.tsx +0 -18
  96. package/src/widgets/__stories__/numeric-input-editor.stories.tsx +0 -18
  97. package/src/widgets/__stories__/radio-editor.stories.tsx +0 -116
  98. package/src/widgets/__stories__/sorter-editor.stories.tsx +0 -18
  99. package/src/widgets/__tests__/categorizer-editor.test.tsx +0 -51
  100. package/src/widgets/__tests__/definition-editor.test.tsx +0 -41
  101. package/src/widgets/__tests__/dropdown-editor.test.tsx +0 -57
  102. package/src/widgets/__tests__/explanation-editor.test.tsx +0 -59
  103. package/src/widgets/__tests__/expression-editor.test.tsx +0 -403
  104. package/src/widgets/__tests__/input-number-editor.test.tsx +0 -128
  105. package/src/widgets/__tests__/matcher-editor.test.tsx +0 -47
  106. package/src/widgets/__tests__/number-line-editor.test.tsx +0 -144
  107. package/src/widgets/__tests__/numeric-input-editor.test.tsx +0 -177
  108. package/src/widgets/__tests__/radio-editor.test.tsx +0 -118
  109. package/src/widgets/__tests__/sorter-editor.test.tsx +0 -55
  110. package/src/widgets/categorizer-editor.tsx +0 -104
  111. package/src/widgets/cs-program-editor.tsx +0 -256
  112. package/src/widgets/definition-editor.tsx +0 -77
  113. package/src/widgets/deprecated-standin-editor.tsx +0 -29
  114. package/src/widgets/dropdown-editor.tsx +0 -211
  115. package/src/widgets/example-graphie-widget-editor.tsx +0 -70
  116. package/src/widgets/example-graphie-widget.tsx +0 -172
  117. package/src/widgets/example-widget-editor.tsx +0 -62
  118. package/src/widgets/example-widget.tsx +0 -154
  119. package/src/widgets/explanation-editor.tsx +0 -92
  120. package/src/widgets/expression-editor.tsx +0 -557
  121. package/src/widgets/graded-group-editor.tsx +0 -161
  122. package/src/widgets/graded-group-set-editor.tsx +0 -104
  123. package/src/widgets/grapher-editor.tsx +0 -155
  124. package/src/widgets/group-editor.tsx +0 -83
  125. package/src/widgets/iframe-editor.tsx +0 -202
  126. package/src/widgets/image-editor.tsx +0 -367
  127. package/src/widgets/input-number-editor.tsx +0 -288
  128. package/src/widgets/interaction-editor/constraint-editor.tsx +0 -134
  129. package/src/widgets/interaction-editor/function-editor.tsx +0 -108
  130. package/src/widgets/interaction-editor/index.ts +0 -3
  131. package/src/widgets/interaction-editor/interaction-editor.tsx +0 -749
  132. package/src/widgets/interaction-editor/label-editor.tsx +0 -87
  133. package/src/widgets/interaction-editor/line-editor.tsx +0 -125
  134. package/src/widgets/interaction-editor/mathquill-input.tsx +0 -81
  135. package/src/widgets/interaction-editor/movable-line-editor.tsx +0 -121
  136. package/src/widgets/interaction-editor/movable-point-editor.tsx +0 -89
  137. package/src/widgets/interaction-editor/parametric-editor.tsx +0 -117
  138. package/src/widgets/interaction-editor/point-editor.tsx +0 -72
  139. package/src/widgets/interaction-editor/rectangle-editor.tsx +0 -96
  140. package/src/widgets/interactive-graph-editor.tsx +0 -571
  141. package/src/widgets/label-image/__stories__/answer-choices.stories.tsx +0 -82
  142. package/src/widgets/label-image/__stories__/behavior.stories.tsx +0 -31
  143. package/src/widgets/label-image/__stories__/marker.stories.tsx +0 -75
  144. package/src/widgets/label-image/__stories__/question-markers.stories.tsx +0 -107
  145. package/src/widgets/label-image/__stories__/select-image.stories.tsx +0 -59
  146. package/src/widgets/label-image/answer-choices.tsx +0 -231
  147. package/src/widgets/label-image/behavior.tsx +0 -122
  148. package/src/widgets/label-image/marker.tsx +0 -290
  149. package/src/widgets/label-image/question-markers.tsx +0 -176
  150. package/src/widgets/label-image/select-image.tsx +0 -81
  151. package/src/widgets/label-image-editor.tsx +0 -252
  152. package/src/widgets/lights-puzzle-editor.tsx +0 -278
  153. package/src/widgets/matcher-editor.tsx +0 -149
  154. package/src/widgets/matrix-editor.tsx +0 -156
  155. package/src/widgets/measurer-editor.tsx +0 -253
  156. package/src/widgets/molecule-editor.tsx +0 -64
  157. package/src/widgets/number-line-editor.tsx +0 -512
  158. package/src/widgets/numeric-input-editor.tsx +0 -536
  159. package/src/widgets/orderer-editor.tsx +0 -172
  160. package/src/widgets/passage-editor.tsx +0 -117
  161. package/src/widgets/passage-ref-editor.tsx +0 -80
  162. package/src/widgets/passage-ref-target-editor.tsx +0 -49
  163. package/src/widgets/plotter-editor.tsx +0 -542
  164. package/src/widgets/radio/editor.tsx +0 -398
  165. package/src/widgets/reaction-diagram-editor.tsx +0 -131
  166. package/src/widgets/sequence-editor.tsx +0 -205
  167. package/src/widgets/simple-markdown-tester-editor.tsx +0 -86
  168. package/src/widgets/simple-markdown-tester.tsx +0 -92
  169. package/src/widgets/simulator-editor.tsx +0 -146
  170. package/src/widgets/sorter-editor.tsx +0 -103
  171. package/src/widgets/table-editor.tsx +0 -164
  172. package/src/widgets/unit-editor.tsx +0 -299
  173. package/src/widgets/video-editor.tsx +0 -73
  174. package/tsconfig-build.json +0 -22
  175. package/tsconfig-build.tsbuildinfo +0 -1
@@ -1,82 +0,0 @@
1
- import {action} from "@storybook/addon-actions";
2
- import {StyleSheet, css} from "aphrodite";
3
- import * as React from "react";
4
-
5
- import AnswerChoices from "../answer-choices";
6
-
7
- type StoryArgs = Record<any, any>;
8
-
9
- type Story = {
10
- title: string;
11
- };
12
-
13
- export default {
14
- title: "Perseus/Editor/Widgets/Label Image/Answer Choices",
15
- } as Story;
16
-
17
- const styles = StyleSheet.create({
18
- wrapper: {
19
- // The maximum width of a widget in the editor.
20
- width: 338,
21
- },
22
- });
23
-
24
- const Wrapper = (props: any) => {
25
- return (
26
- <div className={css(styles.wrapper)}>
27
- <AnswerChoices
28
- {...props}
29
- onChange={(...args) => {
30
- action("onChange")(...args);
31
- props.onChange(...args);
32
- }}
33
- />
34
- </div>
35
- );
36
- };
37
-
38
- class WithState extends React.Component<
39
- Record<any, any>,
40
- {
41
- choices: ReadonlyArray<string>;
42
- }
43
- > {
44
- state = {
45
- choices: [],
46
- };
47
-
48
- render(): React.ReactNode {
49
- const {choices} = this.state;
50
-
51
- return (
52
- <Wrapper
53
- choices={choices}
54
- onChange={(choices) => this.setState({choices})}
55
- />
56
- );
57
- }
58
- }
59
-
60
- export const EmptyNonInteractive = (args: StoryArgs): React.ReactElement => {
61
- const props = {choices: [], onChange: (...args) => {}} as const;
62
- return <Wrapper {...props} />;
63
- };
64
-
65
- export const FilledNonInteractive = (args: StoryArgs): React.ReactElement => {
66
- const props = {
67
- choices: [
68
- "Lamborghini",
69
- "BMW",
70
- "Volkswagen",
71
- "Fiat",
72
- "Porsche",
73
- "Ferrari",
74
- ],
75
- onChange: (...args) => {},
76
- } as const;
77
- return <Wrapper {...props} />;
78
- };
79
-
80
- export const Interactive = (args: StoryArgs): React.ReactElement => {
81
- return <WithState />;
82
- };
@@ -1,31 +0,0 @@
1
- import {action} from "@storybook/addon-actions";
2
- import * as React from "react";
3
-
4
- import Behavior from "../behavior";
5
-
6
- type StoryArgs = Record<any, any>;
7
-
8
- type Story = {
9
- title: string;
10
- };
11
-
12
- export default {
13
- title: "Perseus/Editor/Widgets/Label Image/Behavior",
14
- } as Story;
15
-
16
- export const Default = (args: StoryArgs): React.ReactElement => {
17
- const [state, setState] = React.useState({
18
- multipleAnswers: false,
19
- hideChoicesFromInstructions: false,
20
- });
21
-
22
- const props = {
23
- multipleAnswers: state.multipleAnswers,
24
- hideChoicesFromInstructions: state.hideChoicesFromInstructions,
25
- onChange: (newState) => {
26
- action("onChange")(newState);
27
- setState({...state, ...newState});
28
- },
29
- } as const;
30
- return <Behavior preferredPopoverDirection="NONE" {...props} />;
31
- };
@@ -1,75 +0,0 @@
1
- import {action} from "@storybook/addon-actions";
2
- import {StyleSheet, css} from "aphrodite";
3
- import * as React from "react";
4
-
5
- import Marker from "../marker";
6
-
7
- type StoryArgs = Record<any, any>;
8
-
9
- type Story = {
10
- title: string;
11
- };
12
-
13
- export default {
14
- title: "Perseus/Editor/Widgets/Label Image/Marker",
15
- } as Story;
16
-
17
- const styles = StyleSheet.create({
18
- wrapper: {
19
- // Push the component down as the popover that displays the choices
20
- // doesn't properly pop over everything.
21
- marginTop: 150,
22
-
23
- position: "relative",
24
-
25
- width: 32,
26
- height: 32,
27
- },
28
- });
29
-
30
- const Wrapper = (props) => (
31
- <div className={css(styles.wrapper)}>
32
- <Marker {...props} />
33
- </div>
34
- );
35
-
36
- export const Empty = (args: StoryArgs): React.ReactElement => {
37
- const props = {
38
- answers: [],
39
- choices: [],
40
- label: "",
41
- onChange: (...args) => {
42
- action("onChange")(...args);
43
- },
44
- onRemove: (...args) => {
45
- action("onRemove")(...args);
46
- },
47
- x: 50,
48
- y: 50,
49
- } as const;
50
- return <Wrapper {...props} />;
51
- };
52
-
53
- export const WithAnswers = (args: StoryArgs): React.ReactElement => {
54
- const props = {
55
- answers: ["BMW", "Ferrari"],
56
- choices: [
57
- "Lamborghini",
58
- "BMW",
59
- "Volkswagen",
60
- "Fiat",
61
- "Porsche",
62
- "Ferrari",
63
- ],
64
- label: "Automotive",
65
- onChange: (...args) => {
66
- action("onChange")(...args);
67
- },
68
- onRemove: (...args) => {
69
- action("onRemove")(...args);
70
- },
71
- x: 50,
72
- y: 50,
73
- } as const;
74
- return <Wrapper {...props} />;
75
- };
@@ -1,107 +0,0 @@
1
- import {StyleSheet, css} from "aphrodite";
2
- import * as React from "react";
3
-
4
- import QuestionMarkers from "../question-markers";
5
-
6
- import type {MarkerType} from "@khanacademy/perseus";
7
-
8
- type StoryArgs = Record<any, any>;
9
-
10
- type Story = {
11
- title: string;
12
- };
13
-
14
- export default {
15
- title: "Perseus/Editor/Widgets/Label Image/Question Markers",
16
- } as Story;
17
-
18
- const styles = StyleSheet.create({
19
- wrapper: {
20
- // The maximum width of a widget in the editor.
21
- width: 338,
22
- },
23
- });
24
-
25
- const Wrapper = (props) => (
26
- <div className={css(styles.wrapper)}>
27
- <QuestionMarkers {...props} />
28
- </div>
29
- );
30
-
31
- class WithState extends React.Component<
32
- Record<any, any>,
33
- {
34
- markers: ReadonlyArray<MarkerType>;
35
- }
36
- > {
37
- state = {
38
- markers: [
39
- {
40
- answers: [],
41
- label: "",
42
- x: 50,
43
- y: 50,
44
- },
45
- ],
46
- };
47
-
48
- render(): React.ReactNode {
49
- const {markers} = this.state;
50
-
51
- return (
52
- <div className={css(styles.wrapper)}>
53
- <QuestionMarkers
54
- choices={[
55
- "Lamborghini",
56
- "BMW",
57
- "Volkswagen",
58
- "Fiat",
59
- "Porsche",
60
- "Ferrari",
61
- ]}
62
- imageUrl="https://ka-perseus-images.s3.amazonaws.com/2ee5fc32e35c5178373b39fd304b325b2994c913.png"
63
- imageWidth={1280}
64
- imageHeight={1024}
65
- markers={markers}
66
- onChange={(markers) => this.setState({markers})}
67
- />
68
- </div>
69
- );
70
- }
71
- }
72
-
73
- export const Empty = (args: StoryArgs): React.ReactElement => {
74
- const props = {
75
- choices: [],
76
- imageUrl: "",
77
- imageWidth: 0,
78
- imageHeight: 0,
79
- markers: [],
80
- onChange: () => {},
81
- } as const;
82
- return <Wrapper {...props} />;
83
- };
84
-
85
- export const Filled = (args: StoryArgs): React.ReactElement => {
86
- const props = {
87
- choices: [],
88
- imageUrl:
89
- "https://ka-perseus-images.s3.amazonaws.com/2ee5fc32e35c5178373b39fd304b325b2994c913.png",
90
- imageWidth: 1280,
91
- imageHeight: 1024,
92
- markers: [
93
- {
94
- answers: [],
95
- label: "",
96
- x: 50,
97
- y: 50,
98
- },
99
- ],
100
- onChange: () => {},
101
- } as const;
102
- return <Wrapper {...props} />;
103
- };
104
-
105
- export const Interactive = (args: StoryArgs): React.ReactElement => {
106
- return <WithState />;
107
- };
@@ -1,59 +0,0 @@
1
- import {StyleSheet, css} from "aphrodite";
2
- import * as React from "react";
3
-
4
- import SelectImage from "../select-image";
5
-
6
- type StoryArgs = Record<any, any>;
7
-
8
- type Story = {
9
- title: string;
10
- };
11
-
12
- export default {
13
- title: "Perseus/Editor/Widgets/Label Image/Select Image",
14
- } as Story;
15
-
16
- const styles = StyleSheet.create({
17
- wrapper: {
18
- // The maximum width of a widget in the editor.
19
- width: 338,
20
- },
21
- });
22
-
23
- const Wrapper = (props) => (
24
- <div className={css(styles.wrapper)}>
25
- <SelectImage {...props} />
26
- </div>
27
- );
28
-
29
- const WithState = () => {
30
- const [url, setUrl] = React.useState("");
31
-
32
- return (
33
- <div className={css(styles.wrapper)}>
34
- <SelectImage onChange={(url) => setUrl(url)} url={url} />
35
- </div>
36
- );
37
- };
38
-
39
- export const Empty = (args: StoryArgs): React.ReactElement => {
40
- const props = {
41
- url: "",
42
- onChange: () => {},
43
- } as const;
44
-
45
- return <Wrapper {...props} />;
46
- };
47
-
48
- export const Filled = (args: StoryArgs): React.ReactElement => {
49
- const props = {
50
- url: "https://ka-perseus-images.s3.amazonaws.com/2ee5fc32e35c5178373b39fd304b325b2994c913.png",
51
- onChange: () => {},
52
- } as const;
53
-
54
- return <Wrapper {...props} />;
55
- };
56
-
57
- export const Interactive = (args: StoryArgs): React.ReactElement => {
58
- return <WithState />;
59
- };
@@ -1,231 +0,0 @@
1
- /**
2
- * Controlled list of answer choices, handles adding and removing answers.
3
- */
4
-
5
- import {components, globalStyles} from "@khanacademy/perseus";
6
- import {StyleSheet, css} from "aphrodite";
7
- import * as React from "react";
8
-
9
- import FormWrappedTextField from "../../components/form-wrapped-text-field";
10
- import Link from "../../components/link";
11
-
12
- const {colors, typography} = globalStyles;
13
- const {Icon} = components;
14
-
15
- type AddAnswerProps = {
16
- // Callback to add new answer choice.
17
- onClick: () => void;
18
- };
19
-
20
- type AnswerProps = {
21
- // The answer string, can be plain text or a KaTeX expression.
22
- answer: string;
23
- // Callback for when an answer is changed.
24
- onChange: (answer: string) => void;
25
- // Callback to remove answer from list of choices.
26
- onRemove: () => void;
27
- };
28
-
29
- type AnswerChoicesProps = {
30
- // The list of possible answers in a specific order.
31
- choices: ReadonlyArray<string>;
32
- // Callback for when answers change.
33
- onChange: (choices: ReadonlyArray<string>) => void;
34
- };
35
-
36
- const addIcon = {
37
- path: "M11 11V7a1 1 0 0 1 2 0v4h4a1 1 0 0 1 0 2h-4v4a1 1 0 0 1-2 0v-4H7a1 1 0 0 1 0-2h4zm1 13C5.373 24 0 18.627 0 12S5.373 0 12 0s12 5.373 12 12-5.373 12-12 12zm0-2c5.523 0 10-4.477 10-10S17.523 2 12 2 2 6.477 2 12s4.477 10 10 10z",
38
- width: 24,
39
- height: 24,
40
- } as const;
41
-
42
- const removeIcon = {
43
- path: "M12 24C5.373 24 0 18.627 0 12S5.373 0 12 0s12 5.373 12 12-5.373 12-12 12zm0-2c5.523 0 10-4.477 10-10S17.523 2 12 2 2 6.477 2 12s4.477 10 10 10zm-5-9a1 1 0 0 1 0-2h10a1 1 0 0 1 0 2H7z",
44
- width: 24,
45
- height: 24,
46
- } as const;
47
-
48
- const DraggableGripIcon = () => (
49
- <svg width="16" height="16" viewBox="0 0 16 16">
50
- <filter
51
- id="draggable-grip-shadow"
52
- width="112.5%"
53
- height="116.7%"
54
- x="-6.2%"
55
- y="-8.3%"
56
- filterUnits="objectBoundingBox"
57
- >
58
- <feGaussianBlur
59
- in="SourceAlpha"
60
- stdDeviation=".5"
61
- result="shadowBlurInner"
62
- />
63
-
64
- <feOffset in="shadowBlurInner" dy="1" result="shadowOffsetInner" />
65
-
66
- <feComposite
67
- in="shadowOffsetInner"
68
- in2="SourceAlpha"
69
- k2="-1"
70
- k3="1"
71
- operator="arithmetic"
72
- result="shadowInnerInner"
73
- />
74
-
75
- <feColorMatrix
76
- in="shadowInnerInner"
77
- values="0 0 0 0 0.129411765 0 0 0 0 0.141176471 0 0 0 0 0.17254902 0 0 0 0.2 0"
78
- />
79
- </filter>
80
-
81
- <path
82
- d="M1 4a1 1 0 1 1 0-2h14a1 1 0 0 1 0 2H1zm0 10a1 1 0 0 1 0-2h14a1 1 0 0 1 0 2H1zm0-5a1 1 0 1 1 0-2h14a1 1 0 0 1 0 2H1z"
83
- fill={colors.gray17}
84
- filter="url(#draggable-grip-shadow)"
85
- />
86
- </svg>
87
- );
88
-
89
- /**
90
- * A button link to add a new answer.
91
- */
92
- const AddAnswer = ({onClick}: AddAnswerProps): React.ReactElement => (
93
- <Link
94
- className={css(styles.addAnswer, editorStyles.addAnswer)}
95
- onClick={onClick}
96
- >
97
- <Icon icon={addIcon} size={24} />
98
- <div className={css(styles.spacer)} />
99
- Add an answer choice
100
- </Link>
101
- );
102
-
103
- /**
104
- * An answer item in the choices list.
105
- *
106
- * TODO(michaelpolyak): Implement answer reordering, CP-117
107
- */
108
- const Answer = ({
109
- answer,
110
- onChange,
111
- onRemove,
112
- }: AnswerProps): React.ReactElement => (
113
- <li className={css(styles.answer)}>
114
- <Link onClick={onRemove}>
115
- <Icon icon={removeIcon} size={24} color="#D92916" />
116
- </Link>
117
-
118
- <div className={css(styles.spacer)} />
119
-
120
- <FormWrappedTextField
121
- grow={1}
122
- onChange={(e) => onChange(e.target.value)}
123
- value={answer}
124
- />
125
-
126
- <div className={css(styles.spacer)} />
127
-
128
- <Link
129
- style={[styles.disabled]}
130
- title="Answer reordering is not implemented."
131
- >
132
- <DraggableGripIcon />
133
- </Link>
134
- </li>
135
- );
136
-
137
- /**
138
- * The list of choices, handles adding, removing and reording of answers.
139
- */
140
- const AnswerChoices = ({
141
- choices,
142
- onChange,
143
- }: AnswerChoicesProps): React.ReactElement => (
144
- <div>
145
- <div className={css(styles.title)}>Answer Choices</div>
146
-
147
- <ul className={css(styles.answers)}>
148
- {choices.map((answer, index) => (
149
- <Answer
150
- answer={answer}
151
- // TODO(michaelpolyak): When answer reording is implemented,
152
- // key by index may not re-render correctly, CP-117
153
- key={index}
154
- // Update answer for choice.
155
- onChange={(answer) =>
156
- onChange([
157
- ...choices.slice(0, index),
158
- answer,
159
- ...choices.slice(index + 1),
160
- ])
161
- }
162
- // Remove answer from choices.
163
- onRemove={() =>
164
- onChange([
165
- ...choices.slice(0, index),
166
- ...choices.slice(index + 1),
167
- ])
168
- }
169
- />
170
- ))}
171
- </ul>
172
-
173
- <AddAnswer
174
- // Append a new empty answer to choices.
175
- onClick={() => onChange([...choices, ""])}
176
- />
177
- </div>
178
- );
179
-
180
- const styles = StyleSheet.create({
181
- title: {
182
- ...typography.bodyXsmallBold,
183
-
184
- marginBottom: 6,
185
-
186
- color: colors.gray17,
187
- },
188
-
189
- answers: {
190
- marginTop: 12,
191
- marginBottom: 12,
192
- },
193
-
194
- answer: {
195
- display: "flex",
196
- flexDirection: "row",
197
- alignItems: "center",
198
-
199
- ":not(:first-child)": {
200
- marginTop: 12,
201
- },
202
- },
203
-
204
- addAnswer: {
205
- ...typography.bodyXsmallBold,
206
-
207
- display: "flex",
208
- flexDirection: "row",
209
- alignItems: "center",
210
-
211
- color: "#1865f2",
212
- },
213
-
214
- spacer: {
215
- width: 16,
216
- },
217
-
218
- disabled: {
219
- cursor: "not-allowed",
220
- },
221
- });
222
-
223
- const editorStyles = StyleSheet.create({
224
- addAnswer: {
225
- ":link": {
226
- color: "#1865f2",
227
- },
228
- },
229
- });
230
-
231
- export default AnswerChoices;
@@ -1,122 +0,0 @@
1
- /**
2
- * Controlled component to display and change widget options.
3
- */
4
-
5
- import {globalStyles} from "@khanacademy/perseus";
6
- import {StyleSheet, css} from "aphrodite";
7
- import * as React from "react";
8
-
9
- import Checkbox from "../../components/checkbox";
10
-
11
- const {colors, typography} = globalStyles;
12
-
13
- export type PreferredPopoverDirection =
14
- | "NONE"
15
- | "UP"
16
- | "DOWN"
17
- | "LEFT"
18
- | "RIGHT";
19
-
20
- type Props = {
21
- // Whether multiple answer choices may be selected for markers.
22
- multipleAnswers: boolean;
23
- // Whether to hide answer choices from user instructions.
24
- hideChoicesFromInstructions: boolean;
25
-
26
- preferredPopoverDirection: PreferredPopoverDirection;
27
- // Callback for when widget options change.
28
- onChange: (options: {
29
- multipleAnswers?: boolean;
30
- hideChoicesFromInstructions?: boolean;
31
- preferredPopoverDirection?: PreferredPopoverDirection;
32
- }) => void;
33
- };
34
-
35
- const Behavior = ({
36
- multipleAnswers,
37
- hideChoicesFromInstructions,
38
- preferredPopoverDirection,
39
- onChange,
40
- }: Props): React.ReactElement => (
41
- <div>
42
- <div className={css(styles.title)}>Behavior</div>
43
-
44
- <ul>
45
- <li className={css(styles.option)}>
46
- <Checkbox
47
- checked={multipleAnswers}
48
- onChange={() =>
49
- onChange({multipleAnswers: !multipleAnswers})
50
- }
51
- />
52
-
53
- <span className={css(styles.label)}>
54
- Allow multiple answers per marker
55
- </span>
56
- </li>
57
-
58
- <li className={css(styles.option)}>
59
- <Checkbox
60
- checked={hideChoicesFromInstructions}
61
- onChange={() =>
62
- onChange({
63
- hideChoicesFromInstructions:
64
- !hideChoicesFromInstructions,
65
- })
66
- }
67
- />
68
-
69
- <span className={css(styles.label)}>
70
- Do not display answer choices in instructions
71
- </span>
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>
94
- </ul>
95
- </div>
96
- );
97
-
98
- const styles = StyleSheet.create({
99
- title: {
100
- ...typography.bodyXsmallBold,
101
-
102
- marginBottom: 6,
103
-
104
- color: colors.gray17,
105
- },
106
-
107
- option: {
108
- display: "flex",
109
-
110
- padding: "6px 0",
111
- },
112
-
113
- label: {
114
- ...typography.smallSubheadingMobile,
115
-
116
- marginLeft: 16,
117
-
118
- color: colors.gray17,
119
- },
120
- });
121
-
122
- export default Behavior;