@pie-element/math-templated 5.0.2-esm.0 → 5.2.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/esm/element.js DELETED
@@ -1,900 +0,0 @@
1
- import React from 'react';
2
- import ReactDOM from 'react-dom';
3
- import { SessionChangedEvent, ModelSetEvent } from '@pie-framework/pie-player-events';
4
- import PropTypes from 'prop-types';
5
- import cx from 'classnames';
6
- import isEqual from 'lodash/isEqual';
7
- import isEmpty from 'lodash/isEmpty';
8
- import { withStyles } from '@material-ui/core/styles';
9
- import Tooltip from '@material-ui/core/Tooltip';
10
- import { updateSpans, mq, HorizontalKeypad } from '@pie-lib/math-input';
11
- import { hasText, hasMedia, Collapsible, UiLayout, PreviewPrompt, Readable, color } from '@pie-lib/render-ui';
12
- import { renderMath } from '@pie-lib/math-rendering';
13
- import MathQuill from '@pie-framework/mathquill';
14
- import { Customizable } from '@pie-lib/mask-markup';
15
- import CorrectAnswerToggle from '@pie-lib/correct-answer-toggle';
16
- import _ from 'lodash';
17
-
18
- function _extends() {
19
- _extends = Object.assign || function (target) {
20
- for (var i = 1; i < arguments.length; i++) {
21
- var source = arguments[i];
22
-
23
- for (var key in source) {
24
- if (Object.prototype.hasOwnProperty.call(source, key)) {
25
- target[key] = source[key];
26
- }
27
- }
28
- }
29
-
30
- return target;
31
- };
32
-
33
- return _extends.apply(this, arguments);
34
- }
35
-
36
- let registered = false; // Define a regex pattern to match {{number}}
37
-
38
- const REGEX = /(\{\{\d+\}\})/gm;
39
- const DEFAULT_KEYPAD_VARIANT = 6; // !!! If you're using Chrome but have selected the "iPad" device in Chrome Developer Tools, the navigator.userAgent string may still report as
40
- // Safari because Chrome on iOS actually uses the Safari rendering engine under the hood due to Apple's restrictions on third-party browser engines.
41
- // When you select the "iPad" device in Chrome Developer Tools, you're essentially emulating the behavior of Safari on an iPad, including the user agent string.
42
- // Therefore, even though you're using Chrome, the user agent string will resemble that of Safari on an iPad.
43
- // Since the regular expression /^((?!chrome|android).)*safari/i checks for the presence of "safari" in the user agent string while excluding "chrome" and "android",
44
- // it will return true in this case because "safari" is present in the user agent string emulated by Chrome when in iPad mode.
45
-
46
- const IS_SAFARI = /^((?!chrome|android).)*safari/i.test(navigator.userAgent);
47
-
48
- function generateAdditionalKeys(keyData = []) {
49
- return keyData.map(key => ({
50
- name: key,
51
- latex: key,
52
- write: key,
53
- label: key
54
- }));
55
- }
56
-
57
- function getKeyPadWidth(additionalKeys = [], equationEditor) {
58
- return Math.floor(additionalKeys.length / 5) * 30 + (equationEditor === 'miscellaneous' ? 600 : 500);
59
- }
60
-
61
- function splitByParts(text) {
62
- // Use the regex pattern to split the text
63
- const parts = text.split(REGEX); // Filter out empty strings that might result from splitting
64
-
65
- return parts.filter(part => part);
66
- }
67
-
68
- function prepareForStatic(model, state) {
69
- const {
70
- responses,
71
- disabled,
72
- markup,
73
- printMode,
74
- alwaysShowCorrect
75
- } = model || {};
76
-
77
- if (markup) {
78
- if (state.showCorrect) {
79
- return Object.keys(responses || {}).reduce((acc, responseKey) => {
80
- var _responses$responseKe;
81
-
82
- acc[responseKey] = responses == null ? void 0 : (_responses$responseKe = responses[responseKey]) == null ? void 0 : _responses$responseKe.answer;
83
- return acc;
84
- }, {});
85
- }
86
-
87
- const splitted = splitByParts(markup);
88
- return splitted.reduce((acc, split) => {
89
- if (split.match(REGEX)) {
90
- const responseKey = Main.getResponseKey(split);
91
- const answer = state.session.answers[`r${responseKey}`];
92
-
93
- if (printMode && !alwaysShowCorrect) {
94
- const blankSpace = '\\ \\ '.repeat(30) + '\\embed{newLine}[] ';
95
- return _extends({}, acc, {
96
- [responseKey]: `\\MathQuillMathField[r${responseKey}]{${blankSpace.repeat(3)}}`
97
- });
98
- }
99
-
100
- if (disabled) {
101
- return _extends({}, acc, {
102
- [responseKey]: `\\embed{answerBlock}[r${responseKey}]`
103
- });
104
- }
105
-
106
- return _extends({}, acc, {
107
- [responseKey]: `\\MathQuillMathField[r${responseKey}]{${answer && answer.value || ''}}`
108
- });
109
- }
110
-
111
- return acc;
112
- }, {});
113
- }
114
- }
115
-
116
- class Main extends React.Component {
117
- // removes {{ and }} and returns only key response. Eg: {{0}} => 0
118
- constructor(props) {
119
- super(props);
120
-
121
- this.handleAnswerBlockDomUpdate = () => {
122
- const {
123
- model,
124
- classes
125
- } = this.props;
126
- const {
127
- session,
128
- showCorrect
129
- } = this.state;
130
- const answers = session.answers;
131
-
132
- if (this.root && model.disabled && !showCorrect) {
133
- Object.keys(answers).forEach(answerId => {
134
- const el = this.root.querySelector(`#${answerId}`);
135
- const indexEl = this.root.querySelector(`#${answerId}Index`);
136
-
137
- if (el) {
138
- let MQ = MathQuill.getInterface(2);
139
- const answer = answers[answerId];
140
- el.textContent = answer && answer.value || '';
141
-
142
- if (model.view) {
143
- el.parentElement.parentElement.classList.remove(classes.correct);
144
- el.parentElement.parentElement.classList.remove(classes.incorrect);
145
- }
146
-
147
- MQ.StaticMath(el);
148
- indexEl.textContent = 'R';
149
- }
150
- });
151
- }
152
-
153
- renderMath(this.root);
154
- };
155
-
156
- this.onSubFieldFocus = id => {
157
- this.setState({
158
- activeAnswerBlock: id
159
- });
160
- };
161
-
162
- this.toNodeData = data => {
163
- if (!data) {
164
- return;
165
- }
166
-
167
- const {
168
- type,
169
- value
170
- } = data;
171
- if (type === 'command' || type === 'cursor') return data;
172
- if (type === 'answer') return _extends({
173
- type: 'answer'
174
- }, data);
175
- if (value === 'clear') return {
176
- type: 'clear'
177
- };
178
- return {
179
- type: 'write',
180
- value
181
- };
182
- };
183
-
184
- this.setInput = input => {
185
- this.input = input;
186
- };
187
-
188
- this.onClick = data => {
189
- const c = this.toNodeData(data);
190
-
191
- if (c.type === 'clear') {
192
- this.input.clear();
193
- } else if (c.type === 'command') {
194
- if (Array.isArray(c.value)) {
195
- c.value.forEach(vv => {
196
- this.input.cmd(vv);
197
- });
198
- } else {
199
- this.input.cmd(c.value);
200
- }
201
- } else if (c.type === 'cursor') {
202
- this.input.keystroke(c.value);
203
- } else {
204
- this.input.write(c.value);
205
- }
206
-
207
- this.input.focus();
208
- };
209
-
210
- this.callOnSessionChange = () => {
211
- const {
212
- onSessionChange
213
- } = this.props;
214
-
215
- if (onSessionChange) {
216
- onSessionChange(this.state.session);
217
- }
218
- };
219
-
220
- this.toggleShowCorrect = show => {
221
- this.setState({
222
- showCorrect: show
223
- }, this.handleAnswerBlockDomUpdate);
224
- };
225
-
226
- this.subFieldChanged = (name, subfieldValue) => {
227
- updateSpans();
228
-
229
- if (name) {
230
- this.setState(state => ({
231
- session: _extends({}, state.session, {
232
- answers: _extends({}, state.session.answers, {
233
- [name]: {
234
- value: subfieldValue
235
- }
236
- })
237
- })
238
- }), this.callOnSessionChange);
239
- }
240
- };
241
-
242
- this.getFieldName = (changeField, fields) => {
243
- const {
244
- answers
245
- } = this.state.session;
246
-
247
- if (Object.keys(answers || {}).length) {
248
- const keys = Object.keys(answers);
249
- return keys.find(k => {
250
- const tf = fields[k];
251
- return tf && tf.id == changeField.id;
252
- });
253
- }
254
- };
255
-
256
- this.onBlur = e => {
257
- const {
258
- relatedTarget,
259
- currentTarget
260
- } = e || {};
261
-
262
- function getParentWithRoleTooltip(element, depth = 0) {
263
- // only run this max 16 times
264
- if (!element || depth >= 16) return null;
265
- const parent = element.offsetParent;
266
- if (!parent) return null;
267
-
268
- if (parent.getAttribute('role') === 'tooltip') {
269
- return parent;
270
- }
271
-
272
- return getParentWithRoleTooltip(parent, depth + 1);
273
- }
274
-
275
- function getDeepChildDataKeypad(element, depth = 0) {
276
- var _element$children;
277
-
278
- // only run this max 4 times
279
- if (!element || depth >= 4) return null;
280
- const child = element == null ? void 0 : (_element$children = element.children) == null ? void 0 : _element$children[0];
281
- if (!child) return null;
282
-
283
- if (child.attributes && child.attributes['data-keypad']) {
284
- return child;
285
- }
286
-
287
- return getDeepChildDataKeypad(child, depth + 1);
288
- }
289
-
290
- const parentWithTooltipRole = getParentWithRoleTooltip(relatedTarget);
291
- const childWithDataKeypad = parentWithTooltipRole ? getDeepChildDataKeypad(parentWithTooltipRole) : null;
292
-
293
- if (!relatedTarget || !currentTarget || !(childWithDataKeypad != null && childWithDataKeypad.attributes['data-keypad'])) {
294
- this.setState({
295
- activeAnswerBlock: ''
296
- });
297
- }
298
- };
299
-
300
- this.renderTeacherInstructions = () => {
301
- const {
302
- model,
303
- classes
304
- } = this.props;
305
- const {
306
- teacherInstructions,
307
- animationsDisabled
308
- } = model || {};
309
- const showTeacherInstructions = teacherInstructions && (hasText(teacherInstructions) || hasMedia(teacherInstructions));
310
- const teacherInstructionsDiv = /*#__PURE__*/React.createElement(PreviewPrompt, {
311
- defaultClassName: "teacher-instructions",
312
- prompt: teacherInstructions
313
- });
314
- return showTeacherInstructions && /*#__PURE__*/React.createElement("div", {
315
- className: classes.collapsible
316
- }, !animationsDisabled ? /*#__PURE__*/React.createElement(Collapsible, {
317
- labels: {
318
- hidden: 'Show Teacher Instructions',
319
- visible: 'Hide Teacher Instructions'
320
- }
321
- }, teacherInstructionsDiv) : teacherInstructionsDiv);
322
- };
323
-
324
- this.renderRationale = () => {
325
- const {
326
- model,
327
- classes
328
- } = this.props;
329
- const {
330
- rationale,
331
- animationsDisabled
332
- } = model || {};
333
- const rationaleDiv = /*#__PURE__*/React.createElement(PreviewPrompt, {
334
- prompt: rationale
335
- });
336
- const showRationale = rationale && (hasText(rationale) || hasMedia(rationale));
337
- return showRationale && /*#__PURE__*/React.createElement("div", {
338
- className: classes.collapsible
339
- }, !animationsDisabled ? /*#__PURE__*/React.createElement(Collapsible, {
340
- labels: {
341
- hidden: 'Show Rationale',
342
- visible: 'Hide Rationale'
343
- }
344
- }, rationaleDiv) : rationaleDiv);
345
- };
346
-
347
- this.renderPlayerContent = () => {
348
- const {
349
- model,
350
- classes
351
- } = this.props;
352
- const {
353
- activeAnswerBlock,
354
- showCorrect,
355
- session
356
- } = this.state;
357
- const {
358
- correctness,
359
- disabled,
360
- view,
361
- responses,
362
- equationEditor,
363
- customKeys,
364
- feedback,
365
- env: {
366
- mode
367
- } = {},
368
- printMode,
369
- alwaysShowCorrect
370
- } = model || {};
371
- const emptyResponse = isEmpty(responses);
372
- const additionalKeys = generateAdditionalKeys(customKeys);
373
- const statics = prepareForStatic(model, this.state) || '';
374
- const studentPrintMode = printMode && !alwaysShowCorrect;
375
- return /*#__PURE__*/React.createElement("div", {
376
- className: classes.inputAndKeypadContainer
377
- }, /*#__PURE__*/React.createElement(Customizable, {
378
- disabled: disabled,
379
- markup: model.markup // TODO remove the need of value?
380
- ,
381
- value: {},
382
- customMarkMarkupComponent: id => {
383
- const responseIsCorrect = mode === 'evaluate' && feedback && feedback[id];
384
- const MQStatic = /*#__PURE__*/React.createElement(mq.Static, {
385
- className: classes.static,
386
- ref: mqStatic => {
387
- this.mqStatic = mqStatic || this.mqStatic;
388
- },
389
- latex: statics[id],
390
- onSubFieldChange: this.subFieldChanged,
391
- getFieldName: this.getFieldName,
392
- setInput: this.setInput,
393
- onSubFieldFocus: this.onSubFieldFocus,
394
- onBlur: this.onBlur
395
- });
396
- return /*#__PURE__*/React.createElement("div", {
397
- className: cx(classes.expression, {
398
- [classes.incorrect]: !emptyResponse && !responseIsCorrect && !showCorrect,
399
- [classes.correct]: !emptyResponse && (responseIsCorrect || showCorrect),
400
- [classes.showCorrectness]: !emptyResponse && disabled && correctness && !view,
401
- [classes.correctAnswerShown]: showCorrect
402
- })
403
- }, /*#__PURE__*/React.createElement(Tooltip, {
404
- ref: ref => this.setTooltipRef(ref),
405
- enterTouchDelay: 0,
406
- interactive: true,
407
- open: activeAnswerBlock === `r${id}`,
408
- classes: {
409
- tooltip: classes.keypadTooltip,
410
- popper: classes.keypadTooltipPopper
411
- },
412
- title: Object.keys(session.answers).map(answerId => answerId === activeAnswerBlock && !(showCorrect || disabled) && /*#__PURE__*/React.createElement("div", {
413
- "data-keypad": true,
414
- key: answerId,
415
- className: classes.responseContainer,
416
- style: {
417
- width: getKeyPadWidth(additionalKeys, equationEditor)
418
- }
419
- }, /*#__PURE__*/React.createElement(HorizontalKeypad, {
420
- additionalKeys: additionalKeys,
421
- mode: equationEditor || DEFAULT_KEYPAD_VARIANT,
422
- onClick: this.onClick
423
- })) || null)
424
- }, studentPrintMode ? /*#__PURE__*/React.createElement("div", {
425
- className: classes.printContainer
426
- }, MQStatic) : MQStatic));
427
- }
428
- }));
429
- };
430
-
431
- const _answers = {};
432
- const {
433
- model: _model,
434
- session: _session
435
- } = props || {};
436
- const {
437
- markup,
438
- alwaysShowCorrect: _alwaysShowCorrect
439
- } = _model || {};
440
- const {
441
- answers: sessionAnswers
442
- } = _session || {};
443
-
444
- if (markup) {
445
- // build out local state model using responses declared in markup
446
- (markup || '').replace(REGEX, response => {
447
- const responseKey = Main.getResponseKey(response);
448
- const sessionAnswerForResponse = sessionAnswers && sessionAnswers[`r${responseKey}`];
449
- _answers[`r${responseKey}`] = {
450
- value: (sessionAnswerForResponse == null ? void 0 : sessionAnswerForResponse.value) || ''
451
- };
452
- });
453
- }
454
-
455
- this.state = {
456
- session: _extends({}, props.session, {
457
- answers: _answers
458
- }),
459
- activeAnswerBlock: '',
460
- showCorrect: _alwaysShowCorrect || false
461
- };
462
- }
463
-
464
- UNSAFE_componentWillMount() {
465
- const {
466
- classes
467
- } = this.props;
468
-
469
- if (typeof window !== 'undefined') {
470
- let MQ = MathQuill.getInterface(2);
471
-
472
- if (!registered) {
473
- MQ.registerEmbed('answerBlock', data => ({
474
- htmlString: `<div class="${classes.blockContainer}">
475
- <div class="${classes.blockResponse}" id="${data}Index">R</div>
476
- <div class="${classes.blockMath}">
477
- <span id="${data}"></span>
478
- </div>
479
- </div>`,
480
- text: () => 'text',
481
- latex: () => `\\embed{answerBlock}[${data}]`
482
- }));
483
- registered = true;
484
- }
485
- }
486
- }
487
-
488
- UNSAFE_componentWillReceiveProps(nextProps) {
489
- const {
490
- model
491
- } = this.props;
492
- const {
493
- model: nextModel = {}
494
- } = nextProps || {};
495
- const {
496
- markup = '',
497
- env = {}
498
- } = model || {};
499
- const {
500
- markup: nextMarkup = '',
501
- env: nextEnv = {},
502
- alwaysShowCorrect: nextAlwaysShowCorrect = false
503
- } = nextModel;
504
-
505
- const isEvaluateMode = env => env && env.mode === 'evaluate';
506
-
507
- if (!isEvaluateMode(env) || !isEvaluateMode(nextEnv)) {
508
- this.setState(prevState => _extends({}, prevState.session, {
509
- showCorrect: false
510
- }));
511
- }
512
-
513
- if (nextAlwaysShowCorrect) {
514
- this.setState({
515
- showCorrect: true
516
- });
517
- }
518
-
519
- const matches = markup.match(REGEX);
520
- const nextMatches = nextMarkup.match(REGEX); // If markup changed, and we no longer have the same response area, the session needs to be updated
521
-
522
- if (!isEqual(matches, nextMatches)) {
523
- const newAnswers = {};
524
- const answers = this.state.session.answers;
525
- (nextMatches || []).forEach(nextMatch => {
526
- const responseKey = Main.getResponseKey(nextMatch);
527
- const sessionAnswerForResponse = answers && answers[`r${responseKey}`]; // build out local state model using responses declared in markup
528
-
529
- newAnswers[`r${responseKey}`] = {
530
- value: (sessionAnswerForResponse == null ? void 0 : sessionAnswerForResponse.value) || ''
531
- };
532
- });
533
- this.setState(state => ({
534
- session: _extends({}, state.session, {
535
- answers: newAnswers
536
- })
537
- }), () => {
538
- this.props.onSessionChange(this.state.session);
539
- this.handleAnswerBlockDomUpdate();
540
- });
541
- }
542
- }
543
-
544
- shouldComponentUpdate(nextProps, nextState) {
545
- const sameModel = isEqual(this.props.model, nextProps.model);
546
- const sameState = isEqual(this.state, nextState);
547
- return !sameModel || !sameState;
548
- }
549
-
550
- componentDidMount() {
551
- this.handleAnswerBlockDomUpdate();
552
- setTimeout(() => renderMath(this.root), 100);
553
- }
554
-
555
- componentDidUpdate() {
556
- this.handleAnswerBlockDomUpdate();
557
- }
558
-
559
- // function for tooltip
560
- setTooltipRef(ref) {
561
- // Safari Hack: https://stackoverflow.com/a/42764495/5757635
562
- setTimeout(() => {
563
- if (ref && IS_SAFARI) {
564
- const div = document.querySelector("[role='tooltip']");
565
-
566
- if (div) {
567
- const el = div.firstChild;
568
- el.setAttribute('tabindex', '-1');
569
- }
570
- }
571
- }, 1);
572
- }
573
-
574
- render() {
575
- const {
576
- model,
577
- classes
578
- } = this.props;
579
- const {
580
- showCorrect
581
- } = this.state;
582
- const {
583
- prompt,
584
- env: {
585
- mode,
586
- role
587
- } = {},
588
- extraCSSRules,
589
- correctness,
590
- responses,
591
- language,
592
- showNote,
593
- note
594
- } = model || {};
595
- const emptyResponse = isEmpty(responses);
596
- const showCorrectAnswerToggle = !emptyResponse && correctness && correctness.correctness !== 'correct';
597
- const displayNote = (showCorrect || mode === 'view' && role === 'instructor') && showNote && note;
598
- return /*#__PURE__*/React.createElement(UiLayout, {
599
- extraCSSRules: extraCSSRules,
600
- className: classes.mainContainer,
601
- ref: r => {
602
- // eslint-disable-next-line react/no-find-dom-node
603
- const domNode = ReactDOM.findDOMNode(r);
604
- this.root = domNode || this.root;
605
- }
606
- }, /*#__PURE__*/React.createElement("div", {
607
- className: classes.main
608
- }, mode === 'gather' && /*#__PURE__*/React.createElement("h2", {
609
- className: classes.srOnly
610
- }, "Math Equation Response Question"), /*#__PURE__*/React.createElement("div", {
611
- className: classes.main
612
- }, showCorrectAnswerToggle && /*#__PURE__*/React.createElement(CorrectAnswerToggle, {
613
- language: language,
614
- className: classes.toggle,
615
- show: true,
616
- toggled: showCorrect,
617
- onToggle: this.toggleShowCorrect
618
- })), this.renderTeacherInstructions(), prompt && /*#__PURE__*/React.createElement("div", {
619
- className: classes.promptContainer
620
- }, /*#__PURE__*/React.createElement(PreviewPrompt, {
621
- prompt: prompt
622
- })), /*#__PURE__*/React.createElement(Readable, {
623
- false: true
624
- }, this.renderPlayerContent()), displayNote && /*#__PURE__*/React.createElement("div", {
625
- className: cx(classes.note, 'note'),
626
- dangerouslySetInnerHTML: {
627
- __html: note
628
- }
629
- }), this.renderRationale()));
630
- }
631
-
632
- }
633
-
634
- Main.getResponseKey = response => (response || '').replaceAll('{{', '').replaceAll('}}', '');
635
-
636
- Main.propTypes = {
637
- classes: PropTypes.object,
638
- session: PropTypes.object.isRequired,
639
- onSessionChange: PropTypes.func,
640
- model: PropTypes.object.isRequired
641
- };
642
-
643
- const styles = theme => ({
644
- mainContainer: {
645
- color: color.text(),
646
- backgroundColor: color.background(),
647
- display: 'inline-block'
648
- },
649
- tooltip: {
650
- background: `${color.primaryLight()} !important`,
651
- color: color.text(),
652
- padding: theme.spacing.unit * 2,
653
- border: `1px solid ${color.secondary()}`,
654
- fontSize: '16px',
655
- '& :not(.MathJax) > table tr': {
656
- '&:nth-child(2n)': {
657
- backgroundColor: 'unset !important'
658
- }
659
- }
660
- },
661
- tooltipPopper: {
662
- opacity: 1
663
- },
664
- keypadTooltip: {
665
- fontSize: 'initial',
666
- background: 'transparent',
667
- width: '600px',
668
- marginTop: 0,
669
- paddingTop: 0
670
- },
671
- keypadTooltipPopper: {
672
- background: 'transparent',
673
- width: '650px',
674
- opacity: 1
675
- },
676
- promptContainer: {
677
- marginBottom: theme.spacing.unit * 2
678
- },
679
- main: {
680
- width: '100%',
681
- position: 'relative',
682
- backgroundColor: color.background(),
683
- color: color.text()
684
- },
685
- title: {
686
- fontSize: '1.1rem',
687
- display: 'block',
688
- marginTop: theme.spacing.unit * 2,
689
- marginBottom: theme.spacing.unit
690
- },
691
- collapsible: {
692
- marginBottom: theme.spacing.unit * 2
693
- },
694
- responseContainer: {
695
- zIndex: 10,
696
- minWidth: '400px',
697
- marginTop: theme.spacing.unit * 2
698
- },
699
- expression: {
700
- maxWidth: 'fit-content',
701
- '& > .mq-math-mode': {
702
- '& > .mq-root-block': {
703
- '& > .mq-editable-field': {
704
- minWidth: '10px',
705
- padding: theme.spacing.unit / 4
706
- }
707
- },
708
- '& sup': {
709
- top: 0
710
- }
711
- }
712
- },
713
- static: {
714
- '& > .mq-root-block': {
715
- '& > .mq-editable-field': {
716
- borderColor: color.text()
717
- }
718
- }
719
- },
720
- inputAndKeypadContainer: {
721
- position: 'relative',
722
- '& > div > div': {
723
- display: 'flex',
724
- alignItems: 'baseline',
725
- flexWrap: 'wrap'
726
- },
727
- '& .mq-overarrow-inner': {
728
- border: 'none !important',
729
- padding: '0 !important'
730
- },
731
- '& .mq-overarrow-inner-right': {
732
- display: 'none !important'
733
- },
734
- '& .mq-overarrow-inner-left': {
735
- display: 'none !important'
736
- },
737
- '& .mq-overarrow.mq-arrow-both': {
738
- minWidth: '1.23em',
739
- '& *': {
740
- lineHeight: '1 !important'
741
- },
742
- '&:before': {
743
- top: '-0.4em',
744
- left: '-1px'
745
- },
746
- '&:after': {
747
- top: '-2.4em',
748
- right: '-1px'
749
- },
750
- '&.mq-empty:after': {
751
- top: '-0.45em'
752
- }
753
- },
754
- '& .mq-overarrow.mq-arrow-right': {
755
- '&:before': {
756
- top: '-0.4em',
757
- right: '-1px'
758
- }
759
- },
760
- '& .mq-longdiv-inner': {
761
- borderTop: '1px solid !important',
762
- paddingTop: '1.5px !important'
763
- },
764
- '& .mq-parallelogram': {
765
- lineHeight: 0.85
766
- }
767
- },
768
- showCorrectness: {
769
- border: '2px solid'
770
- },
771
- correctAnswerShown: {
772
- padding: theme.spacing.unit,
773
- letterSpacing: '0.5px'
774
- },
775
- correct: {
776
- borderColor: `${color.correct()} !important`
777
- },
778
- incorrect: {
779
- borderColor: `${color.incorrect()} !important`
780
- },
781
- blockContainer: {
782
- margin: `${theme.spacing.unit}px !important`,
783
- display: 'inline-flex',
784
- border: '2px solid grey !important'
785
- },
786
- blockResponse: {
787
- flex: 2,
788
- color: 'grey',
789
- background: theme.palette.grey['A100'],
790
- fontSize: '0.8rem !important',
791
- padding: `${theme.spacing.unit / 2}px !important`,
792
- display: 'flex',
793
- alignItems: 'center',
794
- justifyContent: 'center',
795
- borderRight: `2px solid ${color.disabled()} !important`
796
- },
797
- toggle: {
798
- color: color.text(),
799
- marginBottom: theme.spacing.unit * 2
800
- },
801
- blockMath: {
802
- color: color.text(),
803
- backgroundColor: color.background(),
804
- padding: `${theme.spacing.unit / 2}px !important`,
805
- display: 'flex',
806
- alignItems: 'center',
807
- justifyContent: 'center',
808
- flex: 8,
809
- '& > .mq-math-mode': {
810
- '& > .mq-hasCursor': {
811
- '& > .mq-cursor': {
812
- display: 'none'
813
- }
814
- }
815
- }
816
- },
817
- printContainer: {
818
- marginBottom: theme.spacing.unit,
819
- pointerEvents: 'none'
820
- },
821
- srOnly: {
822
- position: 'absolute',
823
- left: '-10000px',
824
- top: 'auto',
825
- width: '1px',
826
- height: '1px',
827
- overflow: 'hidden'
828
- },
829
- note: {
830
- marginBottom: theme.spacing.unit * 2
831
- }
832
- });
833
-
834
- var Main$1 = withStyles(styles)(Main);
835
-
836
- class MathTemplated extends HTMLElement {
837
- constructor() {
838
- super();
839
- this.sessionChangedEventCaller = _.debounce(() => {
840
- this.dispatchEvent(new SessionChangedEvent(this.tagName.toLowerCase(), true));
841
- }, 1000);
842
- }
843
-
844
- set model(m) {
845
- this._model = m;
846
- this.render();
847
- this.dispatchEvent(new ModelSetEvent(this.tagName.toLowerCase(), this.isSessionComplete(), this._model !== undefined));
848
- }
849
-
850
- get model() {
851
- return this._model;
852
- }
853
-
854
- set session(s) {
855
- this._session = s;
856
- this.render();
857
- }
858
-
859
- get session() {
860
- return this._session;
861
- }
862
-
863
- isSessionComplete() {
864
- // a method to check if student answered the question
865
- return true;
866
- }
867
-
868
- onSessionChange(session) {
869
- // you can add an extra step here to validate session
870
- Object.keys(session).map(key => {
871
- this._session[key] = session[key];
872
- });
873
- this.sessionChangedEventCaller();
874
- this.render();
875
- }
876
-
877
- connectedCallback() {
878
- // TODO set accessibility labels
879
- this.render();
880
- }
881
-
882
- render() {
883
- if (!this._model || !this._session) {
884
- return;
885
- }
886
-
887
- if (this._model && this._session) {
888
- const el = /*#__PURE__*/React.createElement(Main$1, {
889
- model: this._model,
890
- session: this._session,
891
- onSessionChange: this.onSessionChange.bind(this)
892
- });
893
- ReactDOM.render(el, this);
894
- }
895
- }
896
-
897
- }
898
-
899
- export { MathTemplated as default };
900
- //# sourceMappingURL=element.js.map