@pie-lib/math-toolbar 3.0.3-next.36 → 3.0.3-next.38
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/dist/done-button.d.ts +30 -0
- package/dist/done-button.js +34 -0
- package/dist/editor-and-pad.d.ts +47 -0
- package/dist/editor-and-pad.js +352 -0
- package/dist/index.d.ts +90 -0
- package/dist/index.js +158 -0
- package/dist/math-preview.d.ts +22 -0
- package/dist/math-preview.js +125 -0
- package/dist/utils.d.ts +9 -0
- package/dist/utils.js +9 -0
- package/package.json +31 -25
- package/CHANGELOG.json +0 -17
- package/CHANGELOG.md +0 -1049
- package/LICENSE.md +0 -5
- package/lib/done-button.js +0 -51
- package/lib/done-button.js.map +0 -1
- package/lib/editor-and-pad.js +0 -528
- package/lib/editor-and-pad.js.map +0 -1
- package/lib/index.js +0 -241
- package/lib/index.js.map +0 -1
- package/lib/math-preview.js +0 -192
- package/lib/math-preview.js.map +0 -1
- package/lib/utils.js +0 -17
- package/lib/utils.js.map +0 -1
- package/src/__tests__/editor-and-pad.test.js +0 -16
- package/src/__tests__/index.test.js +0 -21
- package/src/__tests__/math-preview.test.js +0 -18
- package/src/done-button.jsx +0 -36
- package/src/editor-and-pad.jsx +0 -498
- package/src/index.jsx +0 -220
- package/src/math-preview.jsx +0 -162
- package/src/utils.js +0 -11
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
import { RawPureToolbar } from '../index';
|
|
2
|
-
import { render } from '@testing-library/react';
|
|
3
|
-
import React from 'react';
|
|
4
|
-
|
|
5
|
-
describe('RawPureToolbar', () => {
|
|
6
|
-
const defaultProps = {
|
|
7
|
-
classes: {},
|
|
8
|
-
controlledKeypad: true,
|
|
9
|
-
showKeypad: true,
|
|
10
|
-
};
|
|
11
|
-
|
|
12
|
-
it('renders with DONE button if hideDoneButton is not defined', () => {
|
|
13
|
-
const { container } = render(<RawPureToolbar {...defaultProps} />);
|
|
14
|
-
expect(container.firstChild).toBeInTheDocument();
|
|
15
|
-
});
|
|
16
|
-
|
|
17
|
-
it('renders without DONE button if hideDoneButton value is true', () => {
|
|
18
|
-
const { container } = render(<RawPureToolbar {...defaultProps} hideDoneButton={true} />);
|
|
19
|
-
expect(container.firstChild).toBeInTheDocument();
|
|
20
|
-
});
|
|
21
|
-
});
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import { render } from '@testing-library/react';
|
|
3
|
-
import MathPreview from '../math-preview';
|
|
4
|
-
|
|
5
|
-
describe('MathPreview', () => {
|
|
6
|
-
const defaultProps = {
|
|
7
|
-
latex: 'sqrt(5)',
|
|
8
|
-
classes: {},
|
|
9
|
-
isSelected: false,
|
|
10
|
-
onFocus: jest.fn(),
|
|
11
|
-
onBlur: jest.fn(),
|
|
12
|
-
};
|
|
13
|
-
|
|
14
|
-
it('renders with default props', () => {
|
|
15
|
-
const { container } = render(<MathPreview {...defaultProps} />);
|
|
16
|
-
expect(container.firstChild).toBeInTheDocument();
|
|
17
|
-
});
|
|
18
|
-
});
|
package/src/done-button.jsx
DELETED
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
|
|
3
|
-
import IconButton from '@mui/material/IconButton';
|
|
4
|
-
import Check from '@mui/icons-material/Check';
|
|
5
|
-
import { styled } from '@mui/material/styles';
|
|
6
|
-
import PropTypes from 'prop-types';
|
|
7
|
-
|
|
8
|
-
const StyledIconButton = styled(IconButton)(({ theme, hideBackground }) => ({
|
|
9
|
-
verticalAlign: 'top',
|
|
10
|
-
width: '28px',
|
|
11
|
-
height: '28px',
|
|
12
|
-
color: '#00bb00',
|
|
13
|
-
...(hideBackground && {
|
|
14
|
-
backgroundColor: theme.palette.common.white,
|
|
15
|
-
'&:hover': {
|
|
16
|
-
backgroundColor: theme.palette.grey[200],
|
|
17
|
-
},
|
|
18
|
-
}),
|
|
19
|
-
'& .MuiIconButton-label': {
|
|
20
|
-
position: 'absolute',
|
|
21
|
-
top: '2px',
|
|
22
|
-
},
|
|
23
|
-
}));
|
|
24
|
-
|
|
25
|
-
export const RawDoneButton = ({ onClick, hideBackground }) => (
|
|
26
|
-
<StyledIconButton aria-label="Done" onClick={onClick} hideBackground={hideBackground} size="large">
|
|
27
|
-
<Check />
|
|
28
|
-
</StyledIconButton>
|
|
29
|
-
);
|
|
30
|
-
|
|
31
|
-
RawDoneButton.propTypes = {
|
|
32
|
-
onClick: PropTypes.func,
|
|
33
|
-
hideBackground: PropTypes.bool,
|
|
34
|
-
};
|
|
35
|
-
|
|
36
|
-
export const DoneButton = RawDoneButton;
|
package/src/editor-and-pad.jsx
DELETED
|
@@ -1,498 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import debug from 'debug';
|
|
3
|
-
import PropTypes from 'prop-types';
|
|
4
|
-
import Button from '@mui/material/Button';
|
|
5
|
-
import { styled } from '@mui/material/styles';
|
|
6
|
-
import MenuItem from '@mui/material/MenuItem';
|
|
7
|
-
import Select from '@mui/material/Select';
|
|
8
|
-
import { isEqual } from 'lodash-es';
|
|
9
|
-
import FormControl from '@mui/material/FormControl';
|
|
10
|
-
import InputLabel from '@mui/material/InputLabel';
|
|
11
|
-
|
|
12
|
-
import { HorizontalKeypad, mq, updateSpans } from '@pie-lib/math-input';
|
|
13
|
-
import { color } from '@pie-lib/render-ui';
|
|
14
|
-
import { markFractionBaseSuperscripts } from './utils';
|
|
15
|
-
|
|
16
|
-
const { commonMqFontStyles, commonMqKeyboardStyles, longdivStyles, supsubStyles } = mq.CommonMqStyles;
|
|
17
|
-
const log = debug('@pie-lib:math-toolbar:editor-and-pad');
|
|
18
|
-
|
|
19
|
-
const decimalRegex = /\.|,/g;
|
|
20
|
-
|
|
21
|
-
const MathToolbarContainer = styled('div')(({ theme }) => ({
|
|
22
|
-
zIndex: 9,
|
|
23
|
-
position: 'relative',
|
|
24
|
-
textAlign: 'center',
|
|
25
|
-
width: 'auto',
|
|
26
|
-
'& > .mq-math-mode': {
|
|
27
|
-
border: 'solid 1px lightgrey',
|
|
28
|
-
},
|
|
29
|
-
'& > .mq-focused': {
|
|
30
|
-
outline: 'none',
|
|
31
|
-
boxShadow: 'none',
|
|
32
|
-
border: `dotted 1px ${theme.palette.primary.main}`,
|
|
33
|
-
borderRadius: '0px',
|
|
34
|
-
},
|
|
35
|
-
'& .mq-overarrow-inner': {
|
|
36
|
-
border: 'none !important',
|
|
37
|
-
paddingTop: '0 !important',
|
|
38
|
-
},
|
|
39
|
-
'& .mq-overarrow-inner-right': {
|
|
40
|
-
display: 'none !important',
|
|
41
|
-
},
|
|
42
|
-
'& .mq-overarrow-inner-left': {
|
|
43
|
-
display: 'none !important',
|
|
44
|
-
},
|
|
45
|
-
'& .mq-longdiv-inner': {
|
|
46
|
-
borderTop: '1px solid !important',
|
|
47
|
-
paddingTop: '1.5px !important',
|
|
48
|
-
},
|
|
49
|
-
'& .mq-overarrow.mq-arrow-both': {
|
|
50
|
-
top: '7.8px',
|
|
51
|
-
marginTop: '0px',
|
|
52
|
-
minWidth: '1.23em',
|
|
53
|
-
},
|
|
54
|
-
'& .mq-parallelogram': {
|
|
55
|
-
lineHeight: 0.85,
|
|
56
|
-
},
|
|
57
|
-
}));
|
|
58
|
-
|
|
59
|
-
const InputAndTypeContainer = styled('div')(({ theme, hide }) => ({
|
|
60
|
-
display: hide ? 'none' : 'flex',
|
|
61
|
-
alignItems: 'center',
|
|
62
|
-
'& .mq-editable-field .mq-cursor': {
|
|
63
|
-
top: '-4px',
|
|
64
|
-
},
|
|
65
|
-
'& .mq-math-mode .mq-selection, .mq-editable-field .mq-selection': {
|
|
66
|
-
paddingTop: '18px',
|
|
67
|
-
},
|
|
68
|
-
'& .mq-math-mode .mq-overarrow': {
|
|
69
|
-
fontFamily: 'Roboto, Helvetica, Arial, sans-serif !important',
|
|
70
|
-
},
|
|
71
|
-
'& .mq-math-mode .mq-overline .mq-overline-inner': {
|
|
72
|
-
paddingTop: '0.4em !important',
|
|
73
|
-
},
|
|
74
|
-
'& .mq-overarrow.mq-arrow-both': {
|
|
75
|
-
minWidth: '1.23em',
|
|
76
|
-
'& *': {
|
|
77
|
-
lineHeight: '1 !important',
|
|
78
|
-
},
|
|
79
|
-
'&:before': {
|
|
80
|
-
top: '-0.45em',
|
|
81
|
-
left: '-1px',
|
|
82
|
-
},
|
|
83
|
-
'&:after': {
|
|
84
|
-
position: 'absolute !important',
|
|
85
|
-
top: '0px !important',
|
|
86
|
-
right: '-2px',
|
|
87
|
-
},
|
|
88
|
-
'&.mq-empty:after': {
|
|
89
|
-
top: '-0.45em',
|
|
90
|
-
},
|
|
91
|
-
},
|
|
92
|
-
'& .mq-overarrow.mq-arrow-right': {
|
|
93
|
-
'&:before': {
|
|
94
|
-
top: '-0.4em',
|
|
95
|
-
right: '-1px',
|
|
96
|
-
},
|
|
97
|
-
},
|
|
98
|
-
'& *': {
|
|
99
|
-
...commonMqFontStyles,
|
|
100
|
-
...supsubStyles,
|
|
101
|
-
...longdivStyles,
|
|
102
|
-
'& .mq-math-mode .mq-sqrt-prefix': {
|
|
103
|
-
verticalAlign: 'baseline !important',
|
|
104
|
-
top: '1px !important',
|
|
105
|
-
left: '-0.1em !important',
|
|
106
|
-
},
|
|
107
|
-
'& .mq-math-mode .mq-overarc ': {
|
|
108
|
-
paddingTop: '0.45em !important',
|
|
109
|
-
},
|
|
110
|
-
'& .mq-math-mode .mq-empty': {
|
|
111
|
-
padding: '9px 1px !important',
|
|
112
|
-
},
|
|
113
|
-
'& .mq-math-mode .mq-root-block': {
|
|
114
|
-
paddingTop: '10px',
|
|
115
|
-
},
|
|
116
|
-
'& .mq-scaled .mq-sqrt-prefix': {
|
|
117
|
-
top: '0 !important',
|
|
118
|
-
},
|
|
119
|
-
'& .mq-math-mode .mq-longdiv .mq-longdiv-inner': {
|
|
120
|
-
marginLeft: '4px !important',
|
|
121
|
-
paddingTop: '6px !important',
|
|
122
|
-
paddingLeft: '6px !important',
|
|
123
|
-
},
|
|
124
|
-
'& .mq-math-mode .mq-paren': {
|
|
125
|
-
verticalAlign: 'top !important',
|
|
126
|
-
padding: '1px 0.1em !important',
|
|
127
|
-
},
|
|
128
|
-
'& .mq-math-mode .mq-sqrt-stem': {
|
|
129
|
-
borderTop: '0.07em solid',
|
|
130
|
-
marginLeft: '-1.5px',
|
|
131
|
-
marginTop: '-2px !important',
|
|
132
|
-
paddingTop: '5px !important',
|
|
133
|
-
},
|
|
134
|
-
'& .mq-math-mode .mq-denominator': {
|
|
135
|
-
marginTop: '-5px !important',
|
|
136
|
-
padding: '0.5em 0.1em 0.1em !important',
|
|
137
|
-
},
|
|
138
|
-
'& .mq-math-mode .mq-numerator, .mq-math-mode .mq-over': {
|
|
139
|
-
padding: '0 0.1em !important',
|
|
140
|
-
paddingBottom: '0 !important',
|
|
141
|
-
marginBottom: '-2px',
|
|
142
|
-
},
|
|
143
|
-
},
|
|
144
|
-
'& span[data-prime="true"]': {
|
|
145
|
-
fontFamily: 'Roboto, Helvetica, Arial, sans-serif !important',
|
|
146
|
-
},
|
|
147
|
-
}));
|
|
148
|
-
|
|
149
|
-
const StyledFormControl = styled(FormControl)({
|
|
150
|
-
flex: 'initial',
|
|
151
|
-
width: '25%',
|
|
152
|
-
minWidth: '100px',
|
|
153
|
-
marginLeft: '15px',
|
|
154
|
-
marginTop: '5px',
|
|
155
|
-
marginBottom: '5px',
|
|
156
|
-
marginRight: '5px',
|
|
157
|
-
'& label': {
|
|
158
|
-
fontFamily: 'Roboto, Helvetica, Arial, sans-serif !important',
|
|
159
|
-
},
|
|
160
|
-
'& div': {
|
|
161
|
-
fontFamily: 'Roboto, Helvetica, Arial, sans-serif !important',
|
|
162
|
-
},
|
|
163
|
-
});
|
|
164
|
-
|
|
165
|
-
const StyledInputLabel = styled(InputLabel)(() => ({
|
|
166
|
-
backgroundColor: 'transparent',
|
|
167
|
-
}));
|
|
168
|
-
|
|
169
|
-
const InputContainerDiv = styled('div')(({ theme, error }) => ({
|
|
170
|
-
minWidth: '500px',
|
|
171
|
-
maxWidth: '900px',
|
|
172
|
-
minHeight: '30px',
|
|
173
|
-
width: '100%',
|
|
174
|
-
display: 'flex',
|
|
175
|
-
marginTop: theme.spacing(1),
|
|
176
|
-
marginBottom: theme.spacing(1),
|
|
177
|
-
...(error && {
|
|
178
|
-
border: '2px solid red',
|
|
179
|
-
}),
|
|
180
|
-
'& .mq-sqrt-prefix .mq-scaled': {
|
|
181
|
-
verticalAlign: 'middle !important',
|
|
182
|
-
},
|
|
183
|
-
}));
|
|
184
|
-
|
|
185
|
-
const MathEditor = styled(mq.Input)(({ controlledKeypadMode }) => ({
|
|
186
|
-
maxWidth: controlledKeypadMode ? '400px' : '500px',
|
|
187
|
-
color: color.text(),
|
|
188
|
-
backgroundColor: color.background(),
|
|
189
|
-
padding: '2px',
|
|
190
|
-
}));
|
|
191
|
-
|
|
192
|
-
const AddAnswerBlockButton = styled(Button)({
|
|
193
|
-
position: 'absolute',
|
|
194
|
-
right: '12px',
|
|
195
|
-
border: '1px solid lightgrey',
|
|
196
|
-
color: color.text(),
|
|
197
|
-
});
|
|
198
|
-
|
|
199
|
-
const StyledHr = styled('hr')(({ theme }) => ({
|
|
200
|
-
padding: 0,
|
|
201
|
-
margin: 0,
|
|
202
|
-
height: '1px',
|
|
203
|
-
border: 'none',
|
|
204
|
-
borderBottom: `solid 1px ${theme.palette.primary.main}`,
|
|
205
|
-
}));
|
|
206
|
-
|
|
207
|
-
const KeyboardContainer = styled(HorizontalKeypad)(({ mode }) => ({
|
|
208
|
-
...commonMqKeyboardStyles,
|
|
209
|
-
...(mode === 'language' && {
|
|
210
|
-
'& *': {
|
|
211
|
-
fontFamily: 'Roboto, Helvetica, Arial, sans-serif !important',
|
|
212
|
-
},
|
|
213
|
-
}),
|
|
214
|
-
}));
|
|
215
|
-
|
|
216
|
-
const toNodeData = (data) => {
|
|
217
|
-
if (!data) {
|
|
218
|
-
return;
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
const { type, value } = data;
|
|
222
|
-
|
|
223
|
-
if (type === 'command' || type === 'cursor') {
|
|
224
|
-
return data;
|
|
225
|
-
} else if (type === 'answer') {
|
|
226
|
-
return { type: 'answer', ...data };
|
|
227
|
-
} else if (value === 'clear') {
|
|
228
|
-
return { type: 'clear' };
|
|
229
|
-
} else {
|
|
230
|
-
return { type: 'write', value };
|
|
231
|
-
}
|
|
232
|
-
};
|
|
233
|
-
|
|
234
|
-
export class EditorAndPad extends React.Component {
|
|
235
|
-
static propTypes = {
|
|
236
|
-
classNames: PropTypes.object,
|
|
237
|
-
keypadMode: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
|
|
238
|
-
autoFocus: PropTypes.bool,
|
|
239
|
-
allowAnswerBlock: PropTypes.bool,
|
|
240
|
-
showKeypad: PropTypes.bool,
|
|
241
|
-
controlledKeypad: PropTypes.bool,
|
|
242
|
-
controlledKeypadMode: PropTypes.bool,
|
|
243
|
-
error: PropTypes.string,
|
|
244
|
-
noDecimal: PropTypes.bool,
|
|
245
|
-
hideInput: PropTypes.bool,
|
|
246
|
-
noLatexHandling: PropTypes.bool,
|
|
247
|
-
layoutForKeyPad: PropTypes.object,
|
|
248
|
-
maxResponseAreas: PropTypes.number,
|
|
249
|
-
additionalKeys: PropTypes.array,
|
|
250
|
-
latex: PropTypes.string.isRequired,
|
|
251
|
-
onAnswerBlockAdd: PropTypes.func,
|
|
252
|
-
onFocus: PropTypes.func,
|
|
253
|
-
onBlur: PropTypes.func,
|
|
254
|
-
onChange: PropTypes.func.isRequired,
|
|
255
|
-
setKeypadInteraction: PropTypes.func,
|
|
256
|
-
};
|
|
257
|
-
|
|
258
|
-
constructor(props) {
|
|
259
|
-
super(props);
|
|
260
|
-
|
|
261
|
-
this.state = { equationEditor: 'item-authoring', addDisabled: false };
|
|
262
|
-
}
|
|
263
|
-
|
|
264
|
-
componentDidMount() {
|
|
265
|
-
if (this.input && this.props.autoFocus) {
|
|
266
|
-
this.input.focus();
|
|
267
|
-
}
|
|
268
|
-
}
|
|
269
|
-
|
|
270
|
-
onClick = (data) => {
|
|
271
|
-
const { noDecimal, noLatexHandling, onChange } = this.props;
|
|
272
|
-
const c = toNodeData(data);
|
|
273
|
-
log('mathChange: ', c);
|
|
274
|
-
|
|
275
|
-
if (noLatexHandling) {
|
|
276
|
-
onChange(c.value);
|
|
277
|
-
return;
|
|
278
|
-
}
|
|
279
|
-
|
|
280
|
-
// if decimals are not allowed for this response, we discard the input
|
|
281
|
-
if (noDecimal && (c.value === '.' || c.value === ',')) {
|
|
282
|
-
return;
|
|
283
|
-
}
|
|
284
|
-
|
|
285
|
-
if (!c) {
|
|
286
|
-
return;
|
|
287
|
-
}
|
|
288
|
-
|
|
289
|
-
if (c.type === 'clear') {
|
|
290
|
-
log('call clear...');
|
|
291
|
-
this.input.clear();
|
|
292
|
-
} else if (c.type === 'command') {
|
|
293
|
-
this.input.command(c.value);
|
|
294
|
-
} else if (c.type === 'cursor') {
|
|
295
|
-
this.input.keystroke(c.value);
|
|
296
|
-
} else if (c.type === 'answer') {
|
|
297
|
-
this.input.write('%response%');
|
|
298
|
-
} else {
|
|
299
|
-
this.input.write(c.value);
|
|
300
|
-
}
|
|
301
|
-
};
|
|
302
|
-
|
|
303
|
-
updateDisable = (isEdit) => {
|
|
304
|
-
const { maxResponseAreas } = this.props;
|
|
305
|
-
|
|
306
|
-
if (maxResponseAreas) {
|
|
307
|
-
const shouldDisable = this.checkResponseAreasNumber(maxResponseAreas, isEdit);
|
|
308
|
-
|
|
309
|
-
this.setState({ addDisabled: shouldDisable });
|
|
310
|
-
}
|
|
311
|
-
};
|
|
312
|
-
|
|
313
|
-
onAnswerBlockClick = () => {
|
|
314
|
-
this.props.onAnswerBlockAdd();
|
|
315
|
-
this.onClick({
|
|
316
|
-
type: 'answer',
|
|
317
|
-
});
|
|
318
|
-
|
|
319
|
-
this.updateDisable(true);
|
|
320
|
-
};
|
|
321
|
-
|
|
322
|
-
onEditorChange = (latex) => {
|
|
323
|
-
const { onChange, noDecimal } = this.props;
|
|
324
|
-
|
|
325
|
-
updateSpans();
|
|
326
|
-
markFractionBaseSuperscripts();
|
|
327
|
-
|
|
328
|
-
this.updateDisable(true);
|
|
329
|
-
|
|
330
|
-
// if no decimals are allowed and the last change is a decimal dot, discard the change
|
|
331
|
-
if (noDecimal && (latex.indexOf('.') !== -1 || latex.indexOf(',') !== -1) && this.input) {
|
|
332
|
-
this.input.clear();
|
|
333
|
-
this.input.write(latex.replace(decimalRegex, ''));
|
|
334
|
-
return;
|
|
335
|
-
}
|
|
336
|
-
|
|
337
|
-
// eslint-disable-next-line no-useless-escape
|
|
338
|
-
const regexMatch = latex.match(/[0-9]\\ \\frac\{[^\{]*\}\{ \}/);
|
|
339
|
-
|
|
340
|
-
if (this.input && regexMatch && regexMatch?.length) {
|
|
341
|
-
try {
|
|
342
|
-
this.input.mathField.__controller.cursor.insLeftOf(this.input.mathField.__controller.cursor.parent[-1].parent);
|
|
343
|
-
this.input.mathField.el().dispatchEvent(new KeyboardEvent('keydown', { keyCode: 8 }));
|
|
344
|
-
} catch (e) {
|
|
345
|
-
// eslint-disable-next-line no-console
|
|
346
|
-
console.error(e.toString());
|
|
347
|
-
}
|
|
348
|
-
|
|
349
|
-
return;
|
|
350
|
-
}
|
|
351
|
-
|
|
352
|
-
onChange(latex);
|
|
353
|
-
};
|
|
354
|
-
|
|
355
|
-
/** Only render if the mathquill instance's latex is different
|
|
356
|
-
* or the keypad state changed from one state to the other (shown / hidden) */
|
|
357
|
-
shouldComponentUpdate(nextProps, nextState) {
|
|
358
|
-
const inputIsDifferent = this.input.mathField.latex() !== nextProps.latex;
|
|
359
|
-
log('[shouldComponentUpdate] ', 'inputIsDifferent: ', inputIsDifferent);
|
|
360
|
-
|
|
361
|
-
if (!isEqual(this.props.error, nextProps.error)) {
|
|
362
|
-
return true;
|
|
363
|
-
}
|
|
364
|
-
|
|
365
|
-
if (!inputIsDifferent && this.props.keypadMode !== nextProps.keypadMode) {
|
|
366
|
-
return true;
|
|
367
|
-
}
|
|
368
|
-
|
|
369
|
-
if (!inputIsDifferent && this.props.noDecimal !== nextProps.noDecimal) {
|
|
370
|
-
return true;
|
|
371
|
-
}
|
|
372
|
-
|
|
373
|
-
if (!inputIsDifferent && this.state.equationEditor !== nextState.equationEditor) {
|
|
374
|
-
return true;
|
|
375
|
-
}
|
|
376
|
-
|
|
377
|
-
if (!inputIsDifferent && this.props.controlledKeypad) {
|
|
378
|
-
return this.props.showKeypad !== nextProps.showKeypad;
|
|
379
|
-
}
|
|
380
|
-
|
|
381
|
-
return inputIsDifferent;
|
|
382
|
-
}
|
|
383
|
-
|
|
384
|
-
onEditorTypeChange = (evt) => {
|
|
385
|
-
this.setState({ equationEditor: evt.target.value });
|
|
386
|
-
};
|
|
387
|
-
|
|
388
|
-
checkResponseAreasNumber = (maxResponseAreas, isEdit) => {
|
|
389
|
-
const { latex } = (this.input && this.input.props) || {};
|
|
390
|
-
|
|
391
|
-
if (latex) {
|
|
392
|
-
const count = (latex.match(/answerBlock/g) || []).length;
|
|
393
|
-
|
|
394
|
-
return isEdit ? count === maxResponseAreas - 1 : count === maxResponseAreas;
|
|
395
|
-
}
|
|
396
|
-
|
|
397
|
-
return false;
|
|
398
|
-
};
|
|
399
|
-
|
|
400
|
-
render() {
|
|
401
|
-
const {
|
|
402
|
-
classNames,
|
|
403
|
-
keypadMode,
|
|
404
|
-
allowAnswerBlock,
|
|
405
|
-
additionalKeys,
|
|
406
|
-
controlledKeypad,
|
|
407
|
-
controlledKeypadMode,
|
|
408
|
-
showKeypad,
|
|
409
|
-
setKeypadInteraction,
|
|
410
|
-
noDecimal,
|
|
411
|
-
hideInput,
|
|
412
|
-
layoutForKeyPad,
|
|
413
|
-
latex,
|
|
414
|
-
onFocus,
|
|
415
|
-
onBlur,
|
|
416
|
-
error,
|
|
417
|
-
} = this.props;
|
|
418
|
-
const shouldShowKeypad = !controlledKeypad || (controlledKeypad && showKeypad);
|
|
419
|
-
const { addDisabled } = this.state;
|
|
420
|
-
|
|
421
|
-
log('[render]', latex);
|
|
422
|
-
|
|
423
|
-
return (
|
|
424
|
-
<MathToolbarContainer className={classNames.mathToolbar}>
|
|
425
|
-
<InputAndTypeContainer hide={hideInput}>
|
|
426
|
-
{controlledKeypadMode && (
|
|
427
|
-
<StyledFormControl variant={'standard'}>
|
|
428
|
-
<StyledInputLabel id="equation-editor-label">{'Equation Editor'}</StyledInputLabel>
|
|
429
|
-
<Select
|
|
430
|
-
labelId="equation-editor-label"
|
|
431
|
-
id="equation-editor-select"
|
|
432
|
-
name="equationEditor"
|
|
433
|
-
label={'Equation Editor'}
|
|
434
|
-
onChange={this.onEditorTypeChange}
|
|
435
|
-
value={this.state.equationEditor}
|
|
436
|
-
MenuProps={{ transitionDuration: { enter: 225, exit: 195 } }}
|
|
437
|
-
>
|
|
438
|
-
<MenuItem value="non-negative-integers">Numeric - Non-Negative Integers</MenuItem>
|
|
439
|
-
<MenuItem value="integers">Numeric - Integers</MenuItem>
|
|
440
|
-
<MenuItem value="decimals">Numeric - Decimals</MenuItem>
|
|
441
|
-
<MenuItem value="fractions">Numeric - Fractions</MenuItem>
|
|
442
|
-
<MenuItem value={1}>Grade 1 - 2</MenuItem>
|
|
443
|
-
<MenuItem value={3}>Grade 3 - 5</MenuItem>
|
|
444
|
-
<MenuItem value={6}>Grade 6 - 7</MenuItem>
|
|
445
|
-
<MenuItem value={8}>Grade 8 - HS</MenuItem>
|
|
446
|
-
<MenuItem value={'geometry'}>Geometry</MenuItem>
|
|
447
|
-
<MenuItem value={'advanced-algebra'}>Advanced Algebra</MenuItem>
|
|
448
|
-
<MenuItem value={'statistics'}>Statistics</MenuItem>
|
|
449
|
-
<MenuItem value={'item-authoring'}>Item Authoring</MenuItem>
|
|
450
|
-
</Select>
|
|
451
|
-
</StyledFormControl>
|
|
452
|
-
)}
|
|
453
|
-
<InputContainerDiv error={error}>
|
|
454
|
-
<MathEditor
|
|
455
|
-
onFocus={() => {
|
|
456
|
-
onFocus && onFocus();
|
|
457
|
-
this.updateDisable(false);
|
|
458
|
-
}}
|
|
459
|
-
onBlur={(event) => {
|
|
460
|
-
this.updateDisable(false);
|
|
461
|
-
onBlur && onBlur(event);
|
|
462
|
-
}}
|
|
463
|
-
className={(classNames && classNames.editor) || ''}
|
|
464
|
-
controlledKeypadMode={controlledKeypadMode}
|
|
465
|
-
ref={(r) => (this.input = r)}
|
|
466
|
-
latex={latex}
|
|
467
|
-
onChange={this.onEditorChange}
|
|
468
|
-
/>
|
|
469
|
-
</InputContainerDiv>
|
|
470
|
-
</InputAndTypeContainer>
|
|
471
|
-
{allowAnswerBlock && (
|
|
472
|
-
<AddAnswerBlockButton
|
|
473
|
-
type="primary"
|
|
474
|
-
style={{ bottom: shouldShowKeypad ? '320px' : '20px' }}
|
|
475
|
-
onClick={this.onAnswerBlockClick}
|
|
476
|
-
disabled={addDisabled}
|
|
477
|
-
>
|
|
478
|
-
+ Response Area
|
|
479
|
-
</AddAnswerBlockButton>
|
|
480
|
-
)}
|
|
481
|
-
<StyledHr />
|
|
482
|
-
{shouldShowKeypad && (
|
|
483
|
-
<KeyboardContainer
|
|
484
|
-
mode={controlledKeypadMode ? this.state.equationEditor : keypadMode}
|
|
485
|
-
controlledKeypadMode={controlledKeypadMode}
|
|
486
|
-
layoutForKeyPad={layoutForKeyPad}
|
|
487
|
-
additionalKeys={additionalKeys}
|
|
488
|
-
onClick={this.onClick}
|
|
489
|
-
noDecimal={noDecimal}
|
|
490
|
-
setKeypadInteraction={setKeypadInteraction}
|
|
491
|
-
/>
|
|
492
|
-
)}
|
|
493
|
-
</MathToolbarContainer>
|
|
494
|
-
);
|
|
495
|
-
}
|
|
496
|
-
}
|
|
497
|
-
|
|
498
|
-
export default EditorAndPad;
|