@khanacademy/perseus-editor 0.0.1 → 0.1.2

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 (127) hide show
  1. package/.babelrc.js +1 -1
  2. package/CHANGELOG.md +26 -0
  3. package/dist/es/index.css +1020 -0
  4. package/dist/es/index.js +9 -1
  5. package/dist/es/index.js.map +1 -1
  6. package/dist/index.css +1020 -0
  7. package/dist/index.js +9 -1
  8. package/dist/index.js.map +1 -1
  9. package/dist/strings.js +6 -1
  10. package/package.json +16 -4
  11. package/src/README.md +7 -0
  12. package/src/__stories__/editor.stories.js +33 -0
  13. package/src/__stories__/section-control-button.stories.jsx +27 -0
  14. package/src/__testdata__/input-number_testdata.js +28 -0
  15. package/src/__tests__/editor_test.jsx +123 -0
  16. package/src/__tests__/i18n_test.jsx +585 -0
  17. package/src/__tests__/traversal_test.jsx +378 -0
  18. package/src/all-editors.js +85 -0
  19. package/src/all-editors_test.js +17 -0
  20. package/src/all-widgets.js +10 -0
  21. package/src/article-editor.jsx +437 -0
  22. package/src/components/__stories__/blur-input.stories.jsx +24 -0
  23. package/src/components/blur-input.jsx +62 -0
  24. package/src/components/checkbox.jsx +194 -0
  25. package/src/components/device-framer.jsx +91 -0
  26. package/src/components/drag-target.jsx +88 -0
  27. package/src/components/dropdown-option.jsx +318 -0
  28. package/src/components/form-wrapped-text-field.jsx +248 -0
  29. package/src/components/graph-settings.jsx +631 -0
  30. package/src/components/hover-behavior.jsx +178 -0
  31. package/src/components/json-editor.jsx +121 -0
  32. package/src/components/link.jsx +173 -0
  33. package/src/components/simple-button.jsx +86 -0
  34. package/src/components/sortable.jsx +186 -0
  35. package/src/components/util.js +39 -0
  36. package/src/components/viewport-resizer.jsx +73 -0
  37. package/src/diffs/__stories__/perseus-diff-wrapper.jsx +8 -0
  38. package/src/diffs/__stories__/structured-item-diff.stories.jsx +855 -0
  39. package/src/diffs/__stories__/tags-diff.stories.jsx +38 -0
  40. package/src/diffs/__stories__/text-diff.stories.jsx +37 -0
  41. package/src/diffs/__tests__/split-diff_test.js +34 -0
  42. package/src/diffs/__tests__/string-array-diff_test.js +74 -0
  43. package/src/diffs/__tests__/structured-item-diff_test.js +432 -0
  44. package/src/diffs/__tests__/widget-diff-performer_test.js +44 -0
  45. package/src/diffs/article-diff.jsx +70 -0
  46. package/src/diffs/item-diff.jsx +77 -0
  47. package/src/diffs/renderer-diff.jsx +143 -0
  48. package/src/diffs/split-diff.jsx +30 -0
  49. package/src/diffs/string-array-diff.jsx +75 -0
  50. package/src/diffs/structured-item-diff.jsx +269 -0
  51. package/src/diffs/tags-diff.jsx +50 -0
  52. package/src/diffs/text-diff.jsx +194 -0
  53. package/src/diffs/widget-diff-performer.jsx +74 -0
  54. package/src/diffs/widget-diff.jsx +291 -0
  55. package/src/editor-page.jsx +351 -0
  56. package/src/editor.jsx +1364 -0
  57. package/src/hint-editor.jsx +447 -0
  58. package/src/i18n.jsx +139 -0
  59. package/src/iframe-content-renderer.jsx +201 -0
  60. package/src/index.js +27 -8
  61. package/src/item-editor.jsx +159 -0
  62. package/src/item-extras-editor.jsx +150 -0
  63. package/src/katex-error-view.jsx +87 -0
  64. package/src/multirenderer-editor.jsx +1074 -0
  65. package/src/section-control-button.jsx +53 -0
  66. package/src/stateful-article-editor.jsx +176 -0
  67. package/src/stateful-editor-page.jsx +90 -0
  68. package/src/styles/perseus-editor.less +1339 -0
  69. package/src/testing-widgets.js +12 -0
  70. package/src/util/register-all-widgets-and-editors-for-testing.js +15 -0
  71. package/src/util/register-all-widgets-and-editors-for-testing_test.js +18 -0
  72. package/src/widgets/__stories__/label-image-editor.stories.jsx +97 -0
  73. package/src/widgets/categorizer-editor.jsx +103 -0
  74. package/src/widgets/cs-program-editor.jsx +258 -0
  75. package/src/widgets/definition-editor.jsx +75 -0
  76. package/src/widgets/dropdown-editor.jsx +201 -0
  77. package/src/widgets/example-graphie-widget-editor.jsx +70 -0
  78. package/src/widgets/example-graphie-widget.jsx +175 -0
  79. package/src/widgets/example-widget-editor.jsx +60 -0
  80. package/src/widgets/example-widget.jsx +153 -0
  81. package/src/widgets/explanation-editor.jsx +89 -0
  82. package/src/widgets/expression-editor.jsx +560 -0
  83. package/src/widgets/graded-group-editor.jsx +162 -0
  84. package/src/widgets/graded-group-set-editor.jsx +101 -0
  85. package/src/widgets/grapher-editor.jsx +154 -0
  86. package/src/widgets/group-editor.jsx +83 -0
  87. package/src/widgets/iframe-editor.jsx +200 -0
  88. package/src/widgets/image-editor.jsx +326 -0
  89. package/src/widgets/input-number-editor.jsx +269 -0
  90. package/src/widgets/interaction/constraint-editor.jsx +147 -0
  91. package/src/widgets/interaction-editor.jsx +1389 -0
  92. package/src/widgets/interactive-graph-editor.jsx +322 -0
  93. package/src/widgets/label-image/__stories__/answer-choices.stories.jsx +81 -0
  94. package/src/widgets/label-image/__stories__/behavior.stories.jsx +32 -0
  95. package/src/widgets/label-image/__stories__/marker.stories.jsx +76 -0
  96. package/src/widgets/label-image/__stories__/question-markers.stories.jsx +106 -0
  97. package/src/widgets/label-image/__stories__/select-image.stories.jsx +60 -0
  98. package/src/widgets/label-image/answer-choices.jsx +231 -0
  99. package/src/widgets/label-image/behavior.jsx +92 -0
  100. package/src/widgets/label-image/marker.jsx +292 -0
  101. package/src/widgets/label-image/question-markers.jsx +181 -0
  102. package/src/widgets/label-image/select-image.jsx +86 -0
  103. package/src/widgets/label-image-editor.jsx +257 -0
  104. package/src/widgets/lights-puzzle-editor.jsx +267 -0
  105. package/src/widgets/matcher-editor.jsx +147 -0
  106. package/src/widgets/matrix-editor.jsx +155 -0
  107. package/src/widgets/measurer-editor.jsx +245 -0
  108. package/src/widgets/molecule-editor.jsx +63 -0
  109. package/src/widgets/number-line-editor.jsx +498 -0
  110. package/src/widgets/numeric-input-editor.jsx +554 -0
  111. package/src/widgets/orderer-editor.jsx +166 -0
  112. package/src/widgets/passage-editor.jsx +115 -0
  113. package/src/widgets/passage-ref-editor.jsx +77 -0
  114. package/src/widgets/passage-ref-target-editor.jsx +47 -0
  115. package/src/widgets/plotter-editor.jsx +537 -0
  116. package/src/widgets/radio/editor.jsx +398 -0
  117. package/src/widgets/reaction-diagram-editor.jsx +127 -0
  118. package/src/widgets/sequence-editor.jsx +205 -0
  119. package/src/widgets/simple-markdown-tester-editor.jsx +84 -0
  120. package/src/widgets/simple-markdown-tester.jsx +91 -0
  121. package/src/widgets/simulator-editor.jsx +144 -0
  122. package/src/widgets/sorter-editor.jsx +100 -0
  123. package/src/widgets/table-editor.jsx +164 -0
  124. package/src/widgets/transformer-editor.jsx +1006 -0
  125. package/src/widgets/unit-editor.jsx +293 -0
  126. package/src/widgets/video-editor.jsx +74 -0
  127. package/src/__tests__/index.test.js +0 -15
@@ -0,0 +1,164 @@
1
+ /* eslint-disable react/sort-comp */
2
+ // @flow
3
+ import {components, TableWidget, Util} from "@khanacademy/perseus";
4
+ import PropTypes from "prop-types";
5
+ import * as React from "react";
6
+ import ReactDOM from "react-dom";
7
+ import _ from "underscore";
8
+
9
+ import Editor from "../editor.jsx";
10
+
11
+ const {InfoTip, NumberInput} = components;
12
+ const Table = TableWidget.widget;
13
+
14
+ type Props = $FlowFixMe;
15
+
16
+ class TableEditor extends React.Component<Props> {
17
+ static propTypes = {
18
+ rows: PropTypes.number,
19
+ columns: PropTypes.number,
20
+ headers: PropTypes.arrayOf(PropTypes.string),
21
+ answers: PropTypes.arrayOf(PropTypes.arrayOf(PropTypes.string)),
22
+ };
23
+
24
+ static widgetName: "table" = "table";
25
+
26
+ static defaultProps: Props = (function () {
27
+ const defaultRows = 4;
28
+ const defaultColumns = 1;
29
+ const blankAnswers = _(defaultRows).times(function () {
30
+ return Util.stringArrayOfSize(defaultColumns);
31
+ });
32
+ return {
33
+ headers: [""],
34
+ rows: defaultRows,
35
+ columns: defaultColumns,
36
+ answers: blankAnswers,
37
+ };
38
+ })();
39
+
40
+ focus: () => void = () => {
41
+ // $FlowFixMe[incompatible-use]
42
+ // $FlowFixMe[prop-missing]
43
+ ReactDOM.findDOMNode(this.refs.numberOfColumns).focus(); // eslint-disable-line react/no-string-refs
44
+ };
45
+
46
+ render(): React.Node {
47
+ const tableProps = _.pick(
48
+ this.props,
49
+ "headers",
50
+ "answers",
51
+ "onChange",
52
+ "apiOptions",
53
+ );
54
+ _.extend(tableProps, {
55
+ editableHeaders: true,
56
+ Editor,
57
+ onFocus: () => {},
58
+ onBlur: () => {},
59
+ trackInteraction: () => {},
60
+ });
61
+
62
+ return (
63
+ <div>
64
+ <div className="perseus-widget-row">
65
+ <label>
66
+ Number of columns:{" "}
67
+ <NumberInput
68
+ // eslint-disable-next-line react/no-string-refs
69
+ ref="numberOfColumns"
70
+ value={this.props.columns}
71
+ onChange={(val) => {
72
+ if (val) {
73
+ this.onSizeInput(this.props.rows, val);
74
+ }
75
+ }}
76
+ useArrowKeys={true}
77
+ />
78
+ </label>
79
+ </div>
80
+ <div className="perseus-widget-row">
81
+ <label>
82
+ Number of rows:{" "}
83
+ <NumberInput
84
+ // eslint-disable-next-line react/no-string-refs
85
+ ref="numberOfRows"
86
+ value={this.props.rows}
87
+ onChange={(val) => {
88
+ if (val) {
89
+ this.onSizeInput(val, this.props.columns);
90
+ }
91
+ }}
92
+ useArrowKeys={true}
93
+ />
94
+ </label>
95
+ </div>
96
+ <div>
97
+ {" "}
98
+ Table of answers:{" "}
99
+ <InfoTip>
100
+ <p>
101
+ The student has to fill out all cells in the table.
102
+ For partially filled tables create a table using the
103
+ template, and insert text input boxes as desired.
104
+ </p>
105
+ </InfoTip>
106
+ </div>
107
+ <div>
108
+ <Table {...tableProps} />
109
+ </div>
110
+ </div>
111
+ );
112
+ }
113
+
114
+ onSizeInput: (number, number) => void = (numRawRows, numRawColumns) => {
115
+ let rows = +numRawRows || 0;
116
+ let columns = +numRawColumns || 0;
117
+ rows = Math.min(Math.max(1, rows), 30);
118
+ columns = Math.min(Math.max(1, columns), 6);
119
+ const oldColumns = this.props.columns;
120
+ const oldRows = this.props.rows;
121
+
122
+ const answers = this.props.answers;
123
+ // Truncate if necessary; else, append
124
+ if (rows <= oldRows) {
125
+ answers.length = rows;
126
+ } else {
127
+ _(rows - oldRows).times(function () {
128
+ answers.push(Util.stringArrayOfSize(oldColumns));
129
+ });
130
+ }
131
+
132
+ function fixColumnSizing(array) {
133
+ // Truncate if necessary; else, append
134
+ if (columns <= oldColumns) {
135
+ array.length = columns;
136
+ } else {
137
+ _(columns - oldColumns).times(function () {
138
+ array.push("");
139
+ });
140
+ }
141
+ }
142
+
143
+ const headers = this.props.headers;
144
+ fixColumnSizing(headers);
145
+ _.each(answers, fixColumnSizing);
146
+
147
+ this.props.onChange({
148
+ rows: rows,
149
+ columns: columns,
150
+ answers: answers,
151
+ headers: headers,
152
+ });
153
+ };
154
+
155
+ serialize: () => $FlowFixMe = () => {
156
+ const json = _.pick(this.props, "headers", "rows", "columns");
157
+
158
+ return _.extend({}, json, {
159
+ answers: _.map(this.props.answers, _.clone),
160
+ });
161
+ };
162
+ }
163
+
164
+ export default TableEditor;