@pie-lib/config-ui 11.25.1-next.0 → 11.26.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/esm/index.js ADDED
@@ -0,0 +1,3191 @@
1
+ import * as React from 'react';
2
+ import React__default from 'react';
3
+ import PropTypes from 'prop-types';
4
+ import { Dialog, DialogTitle, DialogContent, DialogContentText, DialogActions, Button, withStyles as withStyles$1 } from '@material-ui/core';
5
+ import { withStyles } from '@material-ui/core/styles';
6
+ import EditableHTML from '@pie-lib/editable-html';
7
+ import { color, InputContainer, AppendCSSRules } from '@pie-lib/render-ui';
8
+ export { InputContainer } from '@pie-lib/render-ui';
9
+ import FormControlLabel from '@material-ui/core/FormControlLabel';
10
+ import Radio$1 from '@material-ui/core/Radio';
11
+ import classNames from 'classnames';
12
+ import ExpansionPanel from '@material-ui/core/ExpansionPanel';
13
+ import ExpansionPanelSummary from '@material-ui/core/ExpansionPanelSummary';
14
+ import ExpansionPanelDetails from '@material-ui/core/ExpansionPanelDetails';
15
+ import Typography from '@material-ui/core/Typography';
16
+ import ExpandMoreIcon from '@material-ui/icons/ExpandMore';
17
+ import merge from 'lodash/merge';
18
+ import Checkbox$2 from '@material-ui/core/Checkbox';
19
+ import Switch from '@material-ui/core/Switch';
20
+ import MaterialInput from '@material-ui/core/Input';
21
+ import InputLabel from '@material-ui/core/InputLabel';
22
+ import Select from '@material-ui/core/Select';
23
+ import MenuItem from '@material-ui/core/MenuItem';
24
+ import FormControl from '@material-ui/core/FormControl';
25
+ import debug from 'debug';
26
+ import MuiTabs from '@material-ui/core/Tabs';
27
+ import MuiTab from '@material-ui/core/Tab';
28
+ import grey from '@material-ui/core/colors/grey';
29
+ import Dialog$1 from '@material-ui/core/Dialog';
30
+ import DialogTitle$1 from '@material-ui/core/DialogTitle';
31
+ import DialogContentText$1 from '@material-ui/core/DialogContentText';
32
+ import DialogContent$1 from '@material-ui/core/DialogContent';
33
+ import DialogActions$1 from '@material-ui/core/DialogActions';
34
+ import Button$1 from '@material-ui/core/Button';
35
+ import HelpIcon from '@material-ui/icons/Help';
36
+ import IconButton from '@material-ui/core/IconButton';
37
+ import TextField$1 from '@material-ui/core/TextField';
38
+ import isFinite from 'lodash/isFinite';
39
+ import InputAdornment from '@material-ui/core/InputAdornment';
40
+ import Remove from '@material-ui/icons/Remove';
41
+ import Add from '@material-ui/icons/Add';
42
+ import * as math from 'mathjs';
43
+ import uniq from 'lodash/uniq';
44
+ import Chip from '@material-ui/core/Chip';
45
+ import ActionDelete from '@material-ui/icons/Delete';
46
+ import ArrowRight from '@material-ui/icons/SubdirectoryArrowRight';
47
+ import Menu from '@material-ui/core/Menu';
48
+ import ActionFeedback from '@material-ui/icons/Feedback';
49
+ import Measure, { withContentRect } from 'react-measure';
50
+ import includes from 'lodash/includes';
51
+ import get from 'lodash/get';
52
+ import set from 'lodash/set';
53
+
54
+ const AlertDialog = ({
55
+ text,
56
+ title,
57
+ onClose,
58
+ onConfirm,
59
+ open,
60
+ onCloseText,
61
+ onConfirmText,
62
+ classes
63
+ }) => /*#__PURE__*/React__default.createElement(Dialog, {
64
+ open: open,
65
+ onClose: onClose
66
+ }, title && /*#__PURE__*/React__default.createElement(DialogTitle, {
67
+ className: classes.heading
68
+ }, title), text && /*#__PURE__*/React__default.createElement(DialogContent, null, /*#__PURE__*/React__default.createElement(DialogContentText, {
69
+ className: classes.subheading
70
+ }, text)), /*#__PURE__*/React__default.createElement(DialogActions, null, onClose && /*#__PURE__*/React__default.createElement(Button, {
71
+ onClick: onClose,
72
+ color: "primary"
73
+ }, onCloseText), onConfirm && /*#__PURE__*/React__default.createElement(Button, {
74
+ autoFocus: true,
75
+ onClick: onConfirm,
76
+ color: "primary"
77
+ }, onConfirmText)));
78
+
79
+ AlertDialog.defaultProps = {
80
+ onCloseText: 'CANCEL',
81
+ onConfirmText: 'OK'
82
+ };
83
+ AlertDialog.propTypes = {
84
+ text: PropTypes.oneOfType([PropTypes.string, PropTypes.object]),
85
+ title: PropTypes.string,
86
+ onClose: PropTypes.func,
87
+ onConfirm: PropTypes.func,
88
+ open: PropTypes.bool,
89
+ onConfirmText: PropTypes.string,
90
+ onCloseText: PropTypes.string,
91
+ classes: PropTypes.object
92
+ };
93
+
94
+ const styles$b = () => ({
95
+ heading: {
96
+ '& h2': {
97
+ fontSize: 'max(1.25rem, 18px)'
98
+ }
99
+ },
100
+ subheading: {
101
+ fontSize: 'max(1rem, 14px)'
102
+ }
103
+ });
104
+
105
+ var alertDialog = withStyles(styles$b)(AlertDialog);
106
+
107
+ function _extends() {
108
+ _extends = Object.assign || function (target) {
109
+ for (var i = 1; i < arguments.length; i++) {
110
+ var source = arguments[i];
111
+
112
+ for (var key in source) {
113
+ if (Object.prototype.hasOwnProperty.call(source, key)) {
114
+ target[key] = source[key];
115
+ }
116
+ }
117
+ }
118
+
119
+ return target;
120
+ };
121
+
122
+ return _extends.apply(this, arguments);
123
+ }
124
+
125
+ function _objectWithoutPropertiesLoose(source, excluded) {
126
+ if (source == null) return {};
127
+ var target = {};
128
+ var sourceKeys = Object.keys(source);
129
+ var key, i;
130
+
131
+ for (i = 0; i < sourceKeys.length; i++) {
132
+ key = sourceKeys[i];
133
+ if (excluded.indexOf(key) >= 0) continue;
134
+ target[key] = source[key];
135
+ }
136
+
137
+ return target;
138
+ }
139
+
140
+ var RadioWithLabel = withStyles({
141
+ label: {
142
+ left: '-5px',
143
+ position: 'relative'
144
+ },
145
+ customColor: {
146
+ color: `${color.tertiary()} !important`
147
+ }
148
+ })(({
149
+ label,
150
+ value,
151
+ checked,
152
+ onChange,
153
+ classes
154
+ }) => /*#__PURE__*/React__default.createElement(FormControlLabel, {
155
+ value: value,
156
+ classes: {
157
+ label: classes.label
158
+ },
159
+ control: /*#__PURE__*/React__default.createElement(Radio$1, {
160
+ className: classes.customColor,
161
+ checked: checked,
162
+ onChange: onChange
163
+ }),
164
+ label: label
165
+ }));
166
+
167
+ const styles$a = theme => ({
168
+ radioLabel: {
169
+ fontSize: theme.typography.fontSize - 2
170
+ },
171
+ choice: {
172
+ display: 'flex',
173
+ alignItems: 'center'
174
+ },
175
+ choiceHolder: {
176
+ display: 'flex',
177
+ alignItems: 'center'
178
+ }
179
+ });
180
+
181
+ const Group$1 = props => {
182
+ const {
183
+ feedbackLabels,
184
+ value,
185
+ classes,
186
+ className,
187
+ onChange,
188
+ keys
189
+ } = props;
190
+ return /*#__PURE__*/React__default.createElement("div", {
191
+ className: classNames(classes.choiceHolder, className)
192
+ }, keys.map(key => {
193
+ return /*#__PURE__*/React__default.createElement("div", {
194
+ className: classes.choice,
195
+ key: key
196
+ }, /*#__PURE__*/React__default.createElement(RadioWithLabel, {
197
+ value: key,
198
+ checked: value === key,
199
+ classes: {
200
+ label: classes.radioLabel
201
+ },
202
+ onChange: e => onChange(e.currentTarget.value),
203
+ label: feedbackLabels[key]
204
+ }));
205
+ }));
206
+ };
207
+
208
+ Group$1.propTypes = {
209
+ className: PropTypes.string,
210
+ feedbackLabels: PropTypes.object.isRequired,
211
+ value: PropTypes.string.isRequired,
212
+ classes: PropTypes.object.isRequired,
213
+ keys: PropTypes.arrayOf(PropTypes.string),
214
+ onChange: PropTypes.func
215
+ };
216
+ var Group$2 = withStyles(styles$a)(Group$1);
217
+
218
+ const feedbackLabels = {
219
+ default: 'Simple Feedback',
220
+ none: 'No Feedback',
221
+ custom: 'Customized Feedback'
222
+ };
223
+
224
+ const holder = (theme, extras) => _extends({
225
+ marginTop: '0px',
226
+ background: theme.palette.grey[300],
227
+ padding: theme.spacing.unit,
228
+ marginBottom: theme.spacing.unit * 2,
229
+ borderRadius: '4px'
230
+ }, extras);
231
+
232
+ const style$1 = theme => ({
233
+ feedbackSelector: {
234
+ marginBottom: theme.spacing.unit
235
+ },
236
+ label: {
237
+ cursor: 'pointer'
238
+ },
239
+ inputContainerLabel: {
240
+ transform: 'translateY(-20%)'
241
+ },
242
+ feedbackInputContainer: {
243
+ paddingBottom: 0
244
+ },
245
+ customHolder: holder(theme, {
246
+ background: theme.palette.grey[300],
247
+ padding: 0
248
+ }),
249
+ defaultHolder: holder(theme, {
250
+ fontFamily: theme.typography.fontFamily,
251
+ padding: theme.spacing.unit * 2,
252
+ cursor: 'default'
253
+ }),
254
+ editor: {
255
+ fontFamily: theme.typography.fontFamily
256
+ },
257
+ group: {
258
+ paddingTop: theme.spacing.unit
259
+ }
260
+ });
261
+
262
+ const FeedbackType = {
263
+ type: PropTypes.oneOf(['default', 'custom', 'none']),
264
+ default: PropTypes.string,
265
+ custom: PropTypes.string
266
+ };
267
+ class FeedbackSelector extends React__default.Component {
268
+ constructor(...args) {
269
+ super(...args);
270
+
271
+ this.changeType = type => {
272
+ const {
273
+ onChange,
274
+ feedback
275
+ } = this.props;
276
+ onChange(_extends({}, feedback, {
277
+ type
278
+ }));
279
+ };
280
+
281
+ this.changeCustom = custom => {
282
+ const {
283
+ onChange,
284
+ feedback
285
+ } = this.props;
286
+ onChange(_extends({}, feedback, {
287
+ type: 'custom',
288
+ custom
289
+ }));
290
+ };
291
+ }
292
+
293
+ render() {
294
+ const {
295
+ keys,
296
+ classes,
297
+ label,
298
+ feedback,
299
+ toolbarOpts,
300
+ mathMlOptions = {}
301
+ } = this.props;
302
+ const feedbackKeys = keys || Object.keys(feedbackLabels);
303
+ return /*#__PURE__*/React__default.createElement("div", {
304
+ className: classes.feedbackSelector
305
+ }, /*#__PURE__*/React__default.createElement(InputContainer, {
306
+ label: label,
307
+ className: classes.feedbackInputContainer,
308
+ extraClasses: {
309
+ label: classes.inputContainerLabel
310
+ }
311
+ }, /*#__PURE__*/React__default.createElement(Group$2, {
312
+ className: classes.group,
313
+ keys: feedbackKeys,
314
+ label: label,
315
+ value: feedback.type,
316
+ onChange: this.changeType,
317
+ feedbackLabels: feedbackLabels
318
+ })), feedback.type === 'custom' && /*#__PURE__*/React__default.createElement("div", {
319
+ className: classes.customHolder
320
+ }, /*#__PURE__*/React__default.createElement(EditableHTML, {
321
+ className: classes.editor,
322
+ onChange: this.changeCustom,
323
+ markup: feedback.custom || '',
324
+ toolbarOpts: toolbarOpts,
325
+ languageCharactersProps: [{
326
+ language: 'spanish'
327
+ }, {
328
+ language: 'special'
329
+ }],
330
+ mathMlOptions: mathMlOptions
331
+ })), feedback.type === 'default' && /*#__PURE__*/React__default.createElement("div", {
332
+ className: classes.defaultHolder
333
+ }, " ", feedback.default));
334
+ }
335
+
336
+ }
337
+ FeedbackSelector.propTypes = {
338
+ keys: PropTypes.arrayOf(PropTypes.string),
339
+ classes: PropTypes.object.isRequired,
340
+ label: PropTypes.string.isRequired,
341
+ feedback: PropTypes.shape(FeedbackType).isRequired,
342
+ onChange: PropTypes.func.isRequired,
343
+ toolbarOpts: PropTypes.object
344
+ };
345
+ var FeedbackSelector$1 = withStyles(style$1)(FeedbackSelector);
346
+
347
+ const style = {
348
+ feedbackContainer: {
349
+ display: 'flex',
350
+ flex: 1,
351
+ flexDirection: 'column'
352
+ },
353
+ panelDetails: {
354
+ paddingTop: 0,
355
+ paddingBottom: 0
356
+ }
357
+ };
358
+ const buildDefaults = input => {
359
+ return merge({}, {
360
+ correct: {
361
+ type: 'default',
362
+ default: 'Correct'
363
+ },
364
+ incorrect: {
365
+ type: 'default',
366
+ default: 'Incorrect'
367
+ },
368
+ partial: {
369
+ type: 'default',
370
+ default: 'Nearly'
371
+ }
372
+ }, input);
373
+ };
374
+ class FeedbackConfig extends React__default.Component {
375
+ constructor(...args) {
376
+ super(...args);
377
+ this.onCorrectChange = this.onChange.bind(this, 'correct');
378
+ this.onIncorrectChange = this.onChange.bind(this, 'incorrect');
379
+ this.onPartialChange = this.onChange.bind(this, 'partial');
380
+ }
381
+
382
+ onChange(key, config) {
383
+ const {
384
+ feedback,
385
+ onChange
386
+ } = this.props;
387
+
388
+ const update = _extends({}, feedback, {
389
+ [key]: config
390
+ });
391
+
392
+ onChange(update);
393
+ }
394
+
395
+ render() {
396
+ const {
397
+ classes,
398
+ className,
399
+ allowPartial,
400
+ feedback,
401
+ toolbarOpts
402
+ } = this.props;
403
+ return /*#__PURE__*/React__default.createElement("div", {
404
+ className: className
405
+ }, /*#__PURE__*/React__default.createElement(ExpansionPanel, null, /*#__PURE__*/React__default.createElement(ExpansionPanelSummary, {
406
+ expandIcon: /*#__PURE__*/React__default.createElement(ExpandMoreIcon, null)
407
+ }, /*#__PURE__*/React__default.createElement(Typography, {
408
+ className: classes.heading
409
+ }, "Feedback")), /*#__PURE__*/React__default.createElement(ExpansionPanelDetails, {
410
+ className: classes.panelDetails
411
+ }, /*#__PURE__*/React__default.createElement("div", {
412
+ className: classes.feedbackContainer
413
+ }, /*#__PURE__*/React__default.createElement(FeedbackSelector$1, {
414
+ label: "If correct, show",
415
+ feedback: feedback.correct,
416
+ onChange: this.onCorrectChange,
417
+ toolbarOpts: toolbarOpts
418
+ }), allowPartial && /*#__PURE__*/React__default.createElement(FeedbackSelector$1, {
419
+ label: "If partially correct, show",
420
+ feedback: feedback.partial,
421
+ onChange: this.onPartialChange,
422
+ toolbarOpts: toolbarOpts
423
+ }), /*#__PURE__*/React__default.createElement(FeedbackSelector$1, {
424
+ label: "If incorrect, show",
425
+ feedback: feedback.incorrect,
426
+ onChange: this.onIncorrectChange,
427
+ toolbarOpts: toolbarOpts
428
+ })))));
429
+ }
430
+
431
+ }
432
+ FeedbackConfig.propTypes = {
433
+ allowPartial: PropTypes.bool,
434
+ className: PropTypes.string,
435
+ feedback: PropTypes.shape({
436
+ correct: PropTypes.shape(FeedbackType),
437
+ incorrect: PropTypes.shape(FeedbackType),
438
+ partial: PropTypes.shape(FeedbackType)
439
+ }),
440
+ onChange: PropTypes.func.isRequired,
441
+ classes: PropTypes.object.isRequired,
442
+ toolbarOpts: PropTypes.object
443
+ };
444
+ FeedbackConfig.defaultProps = {
445
+ allowPartial: true,
446
+ feedback: buildDefaults()
447
+ };
448
+ var index$4 = withStyles(style)(FeedbackConfig);
449
+
450
+ const InputTypes = {
451
+ classes: PropTypes.object.isRequired,
452
+ className: PropTypes.string,
453
+ label: PropTypes.string,
454
+ checked: PropTypes.bool,
455
+ onChange: PropTypes.func,
456
+ disabled: PropTypes.bool,
457
+ error: PropTypes.string
458
+ };
459
+
460
+ const RawInputSwitch = ({
461
+ classes,
462
+ className,
463
+ label,
464
+ checked,
465
+ onChange
466
+ }) => {
467
+ return /*#__PURE__*/React__default.createElement(InputContainer, {
468
+ className: className,
469
+ label: label
470
+ }, /*#__PURE__*/React__default.createElement(Switch, {
471
+ className: classes.switchRoot,
472
+ checked: checked,
473
+ onChange: onChange,
474
+ "aria-label": label
475
+ }));
476
+ };
477
+
478
+ RawInputSwitch.propTypes = _extends({}, InputTypes);
479
+ const InputSwitch = withStyles({
480
+ switchRoot: {
481
+ justifyContent: 'inherit',
482
+ transform: 'translate(-20%, 20%)'
483
+ }
484
+ })(RawInputSwitch);
485
+
486
+ const RawInputCheckbox = props => {
487
+ const {
488
+ classes,
489
+ className,
490
+ label,
491
+ checked,
492
+ onChange,
493
+ disabled,
494
+ error
495
+ } = props;
496
+ return /*#__PURE__*/React__default.createElement(InputContainer, {
497
+ className: className,
498
+ label: label
499
+ }, /*#__PURE__*/React__default.createElement(Checkbox$2, {
500
+ className: classNames(classes.checkboxRoot, classes.customColor, error && classes.error),
501
+ disabled: disabled,
502
+ checked: checked,
503
+ onChange: onChange,
504
+ "aria-label": label
505
+ }));
506
+ };
507
+
508
+ RawInputCheckbox.propTypes = _extends({}, InputTypes);
509
+
510
+ const RawInputRadio = props => {
511
+ const {
512
+ classes,
513
+ className,
514
+ label,
515
+ checked,
516
+ onChange,
517
+ disabled,
518
+ error
519
+ } = props;
520
+ return /*#__PURE__*/React__default.createElement(InputContainer, {
521
+ className: className,
522
+ label: label
523
+ }, /*#__PURE__*/React__default.createElement(Radio$1, {
524
+ className: classNames(classes.radioRoot, classes.customColor, error && classes.error),
525
+ disabled: disabled,
526
+ checked: checked,
527
+ onChange: onChange,
528
+ "aria-label": label
529
+ }));
530
+ };
531
+
532
+ RawInputRadio.propTypes = _extends({}, InputTypes);
533
+ const InputCheckbox = withStyles(theme => ({
534
+ checkboxRoot: {
535
+ transform: 'translate(-25%, 20%)'
536
+ },
537
+ error: {
538
+ color: theme.palette.error.main
539
+ },
540
+ customColor: {
541
+ color: `${color.tertiary()} !important`
542
+ }
543
+ }))(RawInputCheckbox);
544
+ const InputRadio = withStyles(theme => ({
545
+ radioRoot: {
546
+ transform: 'translate(-20%, 20%)'
547
+ },
548
+ error: {
549
+ color: theme.palette.error.main
550
+ },
551
+ customColor: {
552
+ color: `${color.tertiary()} !important`
553
+ }
554
+ }))(RawInputRadio);
555
+
556
+ const log$3 = debug('pie-elements:config-ui:langs');
557
+
558
+ const styles$9 = theme => ({
559
+ root: {
560
+ flexDirection: 'column',
561
+ alignItems: 'start',
562
+ display: 'flex',
563
+ position: 'relative',
564
+ paddingTop: '0px',
565
+ paddingRight: '0px'
566
+ },
567
+ formControl: {
568
+ position: 'initial'
569
+ },
570
+ inputLabel: {
571
+ paddingBottom: theme.spacing.unit
572
+ }
573
+ });
574
+
575
+ class RawLangs extends React__default.Component {
576
+ constructor(props) {
577
+ super(props);
578
+
579
+ this.choose = event => {
580
+ log$3('[choose] event: ', event);
581
+
582
+ if (this.props.onChange) {
583
+ this.props.onChange(event.target.value);
584
+ }
585
+ };
586
+
587
+ this.uid = props.uid || (Math.random() * 10000).toFixed();
588
+ }
589
+
590
+ render() {
591
+ let {
592
+ langs,
593
+ selected,
594
+ label,
595
+ classes
596
+ } = this.props;
597
+ log$3('[render] selected:', selected);
598
+ return /*#__PURE__*/React__default.createElement("div", {
599
+ className: classes.root
600
+ }, /*#__PURE__*/React__default.createElement(FormControl, {
601
+ className: classes.formControl
602
+ }, /*#__PURE__*/React__default.createElement(InputLabel, {
603
+ className: classes.inputLabel,
604
+ htmlFor: this.uid
605
+ }, label), /*#__PURE__*/React__default.createElement(Select, {
606
+ value: selected,
607
+ onChange: this.choose,
608
+ input: /*#__PURE__*/React__default.createElement(MaterialInput, {
609
+ id: this.uid
610
+ })
611
+ }, langs.map((l, index) => /*#__PURE__*/React__default.createElement(MenuItem, {
612
+ key: index,
613
+ value: l
614
+ }, l)))));
615
+ }
616
+
617
+ }
618
+ RawLangs.propTypes = {
619
+ onChange: PropTypes.func,
620
+ langs: PropTypes.array,
621
+ selected: PropTypes.string,
622
+ label: PropTypes.string,
623
+ classes: PropTypes.object.isRequired,
624
+ uid: PropTypes.string
625
+ };
626
+ const Langs = withStyles(styles$9, {
627
+ name: 'Langs'
628
+ })(RawLangs);
629
+ const LanguageControls = withStyles({
630
+ languageControls: {
631
+ display: 'grid',
632
+ gridAutoFlow: 'column',
633
+ gridAutoColumns: '1fr',
634
+ gridGap: '8px'
635
+ }
636
+ })(({
637
+ classes,
638
+ langs,
639
+ activeLang,
640
+ defaultLang,
641
+ onActiveLangChange,
642
+ onDefaultLangChange,
643
+ className
644
+ }) => {
645
+ const names = classNames(classes.languageControls, className);
646
+ return /*#__PURE__*/React__default.createElement("div", {
647
+ className: names
648
+ }, /*#__PURE__*/React__default.createElement(Langs, {
649
+ label: "Choose language to edit",
650
+ langs: langs,
651
+ selected: activeLang,
652
+ onChange: l => onActiveLangChange(l)
653
+ }), /*#__PURE__*/React__default.createElement(Langs, {
654
+ label: "Default language",
655
+ langs: langs,
656
+ selected: defaultLang,
657
+ onChange: l => onDefaultLangChange(l)
658
+ }));
659
+ });
660
+ LanguageControls.propTypes = {
661
+ langs: PropTypes.array,
662
+ activeLang: PropTypes.string.isRequired,
663
+ defaultLang: PropTypes.string.isRequired,
664
+ onActiveLangChange: PropTypes.func.isRequired,
665
+ onDefaultLangChange: PropTypes.func.isRequired
666
+ };
667
+
668
+ class Tabs extends React__default.Component {
669
+ constructor(props) {
670
+ super(props);
671
+
672
+ this.handleChange = (event, value) => {
673
+ this.setState({
674
+ value
675
+ });
676
+ };
677
+
678
+ this.state = {
679
+ value: 0
680
+ };
681
+ }
682
+
683
+ render() {
684
+ const {
685
+ value
686
+ } = this.state;
687
+ const {
688
+ children,
689
+ className,
690
+ contentClassName,
691
+ contentStyle = {},
692
+ classes
693
+ } = this.props;
694
+ const tabClasses = {
695
+ root: classes.tabRoot
696
+ };
697
+ return /*#__PURE__*/React__default.createElement("div", {
698
+ className: className
699
+ }, /*#__PURE__*/React__default.createElement(MuiTabs, {
700
+ indicatorColor: "primary",
701
+ value: value,
702
+ onChange: this.handleChange
703
+ }, React__default.Children.map(children, (c, index) => c && c.props.title ? /*#__PURE__*/React__default.createElement(MuiTab, {
704
+ classes: tabClasses,
705
+ key: index,
706
+ label: c.props.title
707
+ }) : null)), /*#__PURE__*/React__default.createElement("div", {
708
+ className: contentClassName,
709
+ style: contentStyle
710
+ }, children[value]));
711
+ }
712
+
713
+ }
714
+ Tabs.propTypes = {
715
+ classes: PropTypes.object,
716
+ className: PropTypes.string,
717
+ contentClassName: PropTypes.string,
718
+ contentStyle: PropTypes.object,
719
+ children: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.node), PropTypes.node]).isRequired
720
+ };
721
+ var Tabs$1 = withStyles$1(() => ({
722
+ tabRoot: {}
723
+ }))(Tabs);
724
+
725
+ const Checkbox = ({
726
+ mini,
727
+ checked,
728
+ onChange,
729
+ value,
730
+ label,
731
+ classes,
732
+ error
733
+ }) => /*#__PURE__*/React__default.createElement(FormControlLabel, {
734
+ className: classNames(classes.mini),
735
+ classes: {
736
+ label: classNames(classes.label, {
737
+ [classes.miniLabel]: mini
738
+ })
739
+ },
740
+ control: /*#__PURE__*/React__default.createElement(Checkbox$2, {
741
+ checked: checked,
742
+ onChange: onChange,
743
+ value: value,
744
+ className: classNames(classes.customColor, {
745
+ [classes.miniCheckbox]: mini,
746
+ [classes.error]: error
747
+ })
748
+ }),
749
+ label: label
750
+ });
751
+
752
+ Checkbox.propTypes = {
753
+ mini: PropTypes.bool,
754
+ classes: PropTypes.object.isRequired,
755
+ checked: PropTypes.bool.isRequired,
756
+ onChange: PropTypes.func.isRequired,
757
+ value: PropTypes.string,
758
+ label: PropTypes.string.isRequired
759
+ };
760
+ Checkbox.defaultProps = {
761
+ value: '',
762
+ mini: false
763
+ };
764
+ var Checkbox$1 = withStyles(theme => ({
765
+ label: {
766
+ fontSize: theme.typography.fontSize - 1,
767
+ transform: 'translate(-4%, 2%)',
768
+ color: 'rgba(0,0,0,1.0)'
769
+ },
770
+ miniCheckbox: {
771
+ margin: 0,
772
+ padding: 0,
773
+ width: theme.spacing.unit * 3,
774
+ height: theme.spacing.unit * 3
775
+ },
776
+ miniLabel: {
777
+ marginLeft: theme.spacing.unit,
778
+ color: grey[700],
779
+ fontSize: theme.typography.fontSize - 3
780
+ },
781
+ mini: {
782
+ margin: 0,
783
+ marginLeft: 0,
784
+ padding: 0
785
+ },
786
+ error: {
787
+ color: theme.palette.error.main
788
+ },
789
+ customColor: {
790
+ color: `${color.tertiary()} !important`
791
+ }
792
+ }))(Checkbox);
793
+
794
+ const styles$8 = theme => ({
795
+ formSection: {
796
+ marginTop: theme.spacing.unit * 2,
797
+ marginBottom: theme.spacing.unit * 2
798
+ },
799
+ label: {
800
+ marginBottom: theme.spacing.unit
801
+ }
802
+ });
803
+
804
+ var formSection = withStyles(styles$8)(({
805
+ className,
806
+ classes,
807
+ label,
808
+ children,
809
+ labelExtraStyle
810
+ }) => /*#__PURE__*/React__default.createElement("div", {
811
+ className: classNames(classes.formSection, className)
812
+ }, /*#__PURE__*/React__default.createElement(Typography, {
813
+ className: classes.label,
814
+ type: "subheading",
815
+ style: labelExtraStyle
816
+ }, label), children));
817
+
818
+ const RawHelpButton = ({
819
+ onClick,
820
+ classes
821
+ }) => /*#__PURE__*/React__default.createElement(IconButton, {
822
+ classes: {
823
+ label: classes.icon
824
+ },
825
+ onClick: onClick
826
+ }, /*#__PURE__*/React__default.createElement(HelpIcon, null));
827
+
828
+ RawHelpButton.propTypes = {
829
+ onClick: PropTypes.func,
830
+ classes: PropTypes.object.isRequired
831
+ };
832
+ const HelpButton = withStyles(theme => ({
833
+ icon: {
834
+ '&:hover': {
835
+ color: theme.palette.grey[300]
836
+ }
837
+ }
838
+ }))(RawHelpButton);
839
+ const HelpDialog = ({
840
+ open,
841
+ onClose,
842
+ children,
843
+ title
844
+ }) => /*#__PURE__*/React__default.createElement(Dialog$1, {
845
+ open: open,
846
+ onRequestClose: onClose
847
+ }, /*#__PURE__*/React__default.createElement(DialogTitle$1, null, title), /*#__PURE__*/React__default.createElement(DialogContent$1, null, /*#__PURE__*/React__default.createElement(DialogContentText$1, null, children)), /*#__PURE__*/React__default.createElement(DialogActions$1, null, /*#__PURE__*/React__default.createElement(Button$1, {
848
+ onClick: onClose,
849
+ color: "primary"
850
+ }, "OK")));
851
+ HelpDialog.propTypes = {
852
+ open: PropTypes.bool,
853
+ onClose: PropTypes.func,
854
+ children: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.node), PropTypes.node]).isRequired,
855
+ title: PropTypes.string.isRequired
856
+ };
857
+
858
+ class Help extends React__default.Component {
859
+ constructor(props) {
860
+ super(props);
861
+ this.state = {
862
+ open: false
863
+ };
864
+ }
865
+
866
+ render() {
867
+ const {
868
+ children,
869
+ title
870
+ } = this.props;
871
+ return /*#__PURE__*/React__default.createElement("div", null, /*#__PURE__*/React__default.createElement(HelpButton, {
872
+ color: "accent",
873
+ onClick: () => this.setState({
874
+ open: true
875
+ })
876
+ }), /*#__PURE__*/React__default.createElement(HelpDialog, {
877
+ open: this.state.open,
878
+ title: title,
879
+ onClose: () => this.setState({
880
+ open: false
881
+ })
882
+ }, children));
883
+ }
884
+
885
+ }
886
+
887
+ Help.propTypes = {
888
+ children: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.node), PropTypes.node]).isRequired,
889
+ title: PropTypes.string
890
+ };
891
+
892
+ const _excluded$1 = ["label", "type", "noModelUpdateOnError"];
893
+ class Input extends React.Component {
894
+ constructor(props) {
895
+ super(props);
896
+
897
+ this.onChange = event => {
898
+ const {
899
+ type,
900
+ onChange,
901
+ error
902
+ } = this.props;
903
+ const value = event.target.value;
904
+
905
+ if (error(value, type)) {
906
+ this.setState({
907
+ error: true,
908
+ value: event.target.value
909
+ });
910
+ } else {
911
+ this.setState({
912
+ error: false,
913
+ value: event.target.value
914
+ });
915
+ onChange(event);
916
+ }
917
+ };
918
+
919
+ this.state = {
920
+ value: props.value
921
+ };
922
+ }
923
+
924
+ UNSAFE_componentWillReceiveProps(newProps) {
925
+ this.setState({
926
+ value: newProps.value
927
+ });
928
+ }
929
+
930
+ render() {
931
+ const _this$props = this.props,
932
+ {
933
+ label,
934
+ type
935
+ } = _this$props,
936
+ rest = _objectWithoutPropertiesLoose(_this$props, _excluded$1);
937
+
938
+ const {
939
+ value,
940
+ error
941
+ } = this.state;
942
+ return label ? /*#__PURE__*/React.createElement(InputContainer, {
943
+ label: label
944
+ }, /*#__PURE__*/React.createElement(MaterialInput, _extends({
945
+ type: type
946
+ }, rest, {
947
+ value: value,
948
+ onChange: this.onChange,
949
+ error: error
950
+ }))) : /*#__PURE__*/React.createElement(MaterialInput, _extends({
951
+ type: type
952
+ }, rest, {
953
+ value: value,
954
+ onChange: this.onChange,
955
+ error: error
956
+ }));
957
+ }
958
+
959
+ }
960
+ Input.propTypes = {
961
+ value: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
962
+ onChange: PropTypes.func.isRequired,
963
+ label: PropTypes.string,
964
+ type: PropTypes.string.isRequired,
965
+ error: PropTypes.func,
966
+ noModelUpdateOnError: PropTypes.bool
967
+ };
968
+ Input.defaultProps = {
969
+ type: 'text',
970
+ error: (value, type) => type === 'number' ? !value || isNaN(value) : !value,
971
+ noModelUpdateOnError: false
972
+ };
973
+
974
+ const log$2 = debug('@pie-lib:config-ui:number-text-field');
975
+
976
+ const styles$7 = theme => ({
977
+ root: {
978
+ marginRight: theme.spacing.unit,
979
+ '& label': {
980
+ width: 'max-content'
981
+ }
982
+ }
983
+ });
984
+
985
+ const fallbackNumber$1 = (min, max) => {
986
+ if (!isFinite(min) && !isFinite(max)) {
987
+ return 0;
988
+ }
989
+
990
+ if (!isFinite(min) && isFinite(max)) {
991
+ return max;
992
+ }
993
+
994
+ if (isFinite(min)) {
995
+ return min;
996
+ }
997
+ };
998
+
999
+ class NumberTextField extends React__default.Component {
1000
+ constructor(props) {
1001
+ super(props);
1002
+
1003
+ this.onBlur = event => {
1004
+ const value = event.target.value;
1005
+ const rawNumber = parseFloat(value);
1006
+ log$2('rawNumber: ', rawNumber);
1007
+ const number = this.clamp(rawNumber);
1008
+ log$2('number: ', number);
1009
+
1010
+ if (number !== this.state.value) {
1011
+ log$2('trigger update...');
1012
+ this.setState({
1013
+ value: number.toString()
1014
+ }, () => {
1015
+ this.props.onChange(event, number);
1016
+ });
1017
+ }
1018
+ };
1019
+
1020
+ this.errorMessage = () => {
1021
+ const {
1022
+ min,
1023
+ max
1024
+ } = this.props;
1025
+
1026
+ if (min && max) {
1027
+ return `The value must be between ${min} and ${max}`;
1028
+ }
1029
+
1030
+ if (min) {
1031
+ return `The value must be greater than ${min}`;
1032
+ }
1033
+
1034
+ if (max) {
1035
+ return `The value must be less than ${max}`;
1036
+ }
1037
+ };
1038
+
1039
+ this.getError = () => {
1040
+ const {
1041
+ value
1042
+ } = this.state;
1043
+ const float = parseFloat(value);
1044
+ const clamped = this.clamp(float);
1045
+
1046
+ if (clamped !== float) {
1047
+ return this.errorMessage();
1048
+ }
1049
+ };
1050
+
1051
+ const _value = this.clamp(props.value);
1052
+
1053
+ this.state = {
1054
+ value: _value
1055
+ };
1056
+
1057
+ if (_value !== props.value) {
1058
+ this.props.onChange({}, _value);
1059
+ }
1060
+
1061
+ this.onChange = this.onChange.bind(this);
1062
+ }
1063
+
1064
+ UNSAFE_componentWillReceiveProps(props) {
1065
+ const value = this.clamp(props.value, props.min, props.max);
1066
+ this.setState({
1067
+ value
1068
+ });
1069
+ }
1070
+
1071
+ clamp(value, min = this.props.min, max = this.props.max) {
1072
+ if (!isFinite(value)) {
1073
+ return fallbackNumber$1(min, max);
1074
+ }
1075
+
1076
+ if (isFinite(max)) {
1077
+ value = Math.min(value, max);
1078
+ }
1079
+
1080
+ if (isFinite(min)) {
1081
+ value = Math.max(value, min);
1082
+ }
1083
+
1084
+ return value;
1085
+ }
1086
+ /**
1087
+ * on Blur (this can be triggered by pressing Enter, see below)
1088
+ * we check the entered value and reset it if needed
1089
+ */
1090
+
1091
+
1092
+ onChange(event) {
1093
+ const value = event.target.value;
1094
+ this.setState({
1095
+ value
1096
+ });
1097
+ }
1098
+
1099
+ render() {
1100
+ const {
1101
+ className,
1102
+ classes,
1103
+ label,
1104
+ disabled,
1105
+ suffix,
1106
+ min,
1107
+ max,
1108
+ inputClassName,
1109
+ disableUnderline,
1110
+ showErrorWhenOutsideRange,
1111
+ variant
1112
+ } = this.props;
1113
+ const names = classNames(classes.root, className);
1114
+ const error = showErrorWhenOutsideRange && this.getError();
1115
+ return /*#__PURE__*/React__default.createElement(TextField$1, {
1116
+ variant: variant || 'standard',
1117
+ inputRef: ref => {
1118
+ this.inputRef = ref;
1119
+ },
1120
+ disabled: disabled,
1121
+ label: label,
1122
+ value: this.state.value,
1123
+ error: !!error,
1124
+ helperText: error,
1125
+ onChange: this.onChange,
1126
+ onBlur: this.onBlur,
1127
+ onKeyPress: e => {
1128
+ // once the Enter key is pressed, we force input blur
1129
+ if (e.key === 'Enter' && this.inputRef) {
1130
+ this.inputRef.blur();
1131
+ }
1132
+ },
1133
+ type: "number",
1134
+ className: names,
1135
+ InputLabelProps: {
1136
+ shrink: true
1137
+ },
1138
+ InputProps: {
1139
+ endAdornment: suffix && /*#__PURE__*/React__default.createElement(InputAdornment, {
1140
+ position: "end"
1141
+ }, suffix),
1142
+ className: inputClassName,
1143
+ disableUnderline: disableUnderline
1144
+ },
1145
+ inputProps: {
1146
+ min,
1147
+ max
1148
+ },
1149
+ margin: "normal"
1150
+ });
1151
+ }
1152
+
1153
+ }
1154
+ NumberTextField.propTypes = {
1155
+ disabled: PropTypes.bool,
1156
+ classes: PropTypes.object.isRequired,
1157
+ className: PropTypes.string,
1158
+ inputClassName: PropTypes.string,
1159
+ onChange: PropTypes.func.isRequired,
1160
+ value: PropTypes.number,
1161
+ min: PropTypes.number,
1162
+ max: PropTypes.number,
1163
+ label: PropTypes.string,
1164
+ suffix: PropTypes.string,
1165
+ showErrorWhenOutsideRange: PropTypes.bool,
1166
+ disableUnderline: PropTypes.bool,
1167
+ variant: PropTypes.string
1168
+ };
1169
+ NumberTextField.defaultProps = {
1170
+ showErrorWhenOutsideRange: false
1171
+ };
1172
+ var NumberTextField$1 = withStyles(styles$7)(NumberTextField);
1173
+
1174
+ const styles$6 = () => ({
1175
+ input: {
1176
+ '& input[type=number]': {
1177
+ '-moz-appearance': 'textfield'
1178
+ },
1179
+ '& input[type=number]::-webkit-outer-spin-button': {
1180
+ '-webkit-appearance': 'none',
1181
+ margin: 0
1182
+ },
1183
+ '& input[type=number]::-webkit-inner-spin-button': {
1184
+ '-webkit-appearance': 'none',
1185
+ margin: 0
1186
+ }
1187
+ },
1188
+ iconButton: {
1189
+ padding: '2px'
1190
+ }
1191
+ });
1192
+
1193
+ const fallbackNumber = (min, max) => {
1194
+ if (!isFinite(min) && !isFinite(max)) {
1195
+ return 0;
1196
+ }
1197
+
1198
+ if (!isFinite(min) && isFinite(max)) {
1199
+ return max;
1200
+ }
1201
+
1202
+ if (isFinite(min)) {
1203
+ return min;
1204
+ }
1205
+ };
1206
+
1207
+ class NumberTextFieldCustom extends React__default.Component {
1208
+ constructor(props) {
1209
+ super(props);
1210
+
1211
+ this.normalizeValueAndIndex = (customValues, number, min, max) => {
1212
+ const {
1213
+ type
1214
+ } = this.props;
1215
+ const value = this.clamp(number, min, max);
1216
+ const currentIndex = (customValues || []).findIndex(val => val === value);
1217
+
1218
+ if ((customValues || []).length > 0 && currentIndex === -1) {
1219
+ const closestValue = type === 'text' ? this.getClosestFractionValue(customValues, value) : this.getClosestValue(customValues, value);
1220
+ return {
1221
+ value: closestValue.value,
1222
+ currentIndex: closestValue.index
1223
+ };
1224
+ }
1225
+
1226
+ return {
1227
+ value,
1228
+ currentIndex
1229
+ };
1230
+ };
1231
+
1232
+ this.getClosestValue = (customValues, number) => customValues.reduce((closest, value, index) => Math.abs(value - number) < Math.abs(closest.value - number) ? {
1233
+ value,
1234
+ index
1235
+ } : closest, {
1236
+ value: customValues[0],
1237
+ index: 0
1238
+ });
1239
+
1240
+ this.getClosestFractionValue = (customValues, number) => customValues.reduce((closest, value, index) => Math.abs(math.number(math.fraction(value)) - math.number(math.fraction(number))) < Math.abs(math.number(math.fraction(closest.value)) - math.number(math.fraction(number))) ? {
1241
+ value,
1242
+ index
1243
+ } : closest, {
1244
+ value: customValues[0],
1245
+ index: 0
1246
+ });
1247
+
1248
+ this.getValidFraction = value => {
1249
+ if (this.isPositiveInteger(value.trim())) {
1250
+ return value.trim();
1251
+ }
1252
+
1253
+ if (value.trim() === '' || value.trim().split('/').length !== 2) {
1254
+ return false;
1255
+ }
1256
+
1257
+ let [numerator, denominator] = value.trim().split('/');
1258
+
1259
+ if (isNaN(numerator) || isNaN(denominator)) {
1260
+ return false;
1261
+ }
1262
+
1263
+ numerator = parseFloat(numerator);
1264
+ denominator = parseFloat(denominator);
1265
+
1266
+ if (!Number.isInteger(numerator) || !Number.isInteger(denominator)) {
1267
+ return false;
1268
+ }
1269
+
1270
+ if (numerator < 0 || denominator < 1) {
1271
+ return false;
1272
+ }
1273
+
1274
+ return numerator + '/' + denominator;
1275
+ };
1276
+
1277
+ this.isPositiveInteger = n => {
1278
+ return n >>> 0 === parseFloat(n);
1279
+ };
1280
+
1281
+ this.onBlur = event => {
1282
+ const {
1283
+ customValues,
1284
+ onlyIntegersAllowed,
1285
+ type
1286
+ } = this.props;
1287
+ let {
1288
+ value
1289
+ } = event.target;
1290
+
1291
+ if (type === 'text') {
1292
+ let tempValue = this.getValidFraction(value);
1293
+
1294
+ if (tempValue) {
1295
+ value = tempValue;
1296
+ } else {
1297
+ value = this.props.value;
1298
+ }
1299
+ }
1300
+
1301
+ let rawNumber = onlyIntegersAllowed ? Math.round(parseFloat(value)) : parseFloat(value);
1302
+
1303
+ if (type === 'text') {
1304
+ rawNumber = value.trim();
1305
+ }
1306
+
1307
+ const {
1308
+ value: number,
1309
+ currentIndex
1310
+ } = this.normalizeValueAndIndex(customValues, rawNumber);
1311
+ this.setState({
1312
+ value: number.toString(),
1313
+ currentIndex
1314
+ }, () => this.props.onChange(event, number));
1315
+ };
1316
+
1317
+ const {
1318
+ value: _value,
1319
+ currentIndex: _currentIndex
1320
+ } = this.normalizeValueAndIndex(props.customValues, props.value);
1321
+ this.state = {
1322
+ value: _value,
1323
+ currentIndex: _currentIndex
1324
+ };
1325
+
1326
+ if (_value !== props.value) {
1327
+ this.props.onChange({}, _value);
1328
+ }
1329
+
1330
+ this.onChange = this.onChange.bind(this);
1331
+ }
1332
+
1333
+ UNSAFE_componentWillReceiveProps(props) {
1334
+ const {
1335
+ value,
1336
+ currentIndex
1337
+ } = this.normalizeValueAndIndex(props.customValues, props.value, props.min, props.max);
1338
+ this.setState({
1339
+ value,
1340
+ currentIndex
1341
+ });
1342
+ }
1343
+
1344
+ clamp(value, min = this.props.min, max = this.props.max) {
1345
+ const {
1346
+ customValues
1347
+ } = this.props;
1348
+
1349
+ if ((customValues || []).length > 0) {
1350
+ return value;
1351
+ }
1352
+
1353
+ if (!isFinite(value)) {
1354
+ return fallbackNumber(min, max);
1355
+ }
1356
+
1357
+ if (isFinite(max)) {
1358
+ value = Math.min(value, max);
1359
+ }
1360
+
1361
+ if (isFinite(min)) {
1362
+ value = Math.max(value, min);
1363
+ }
1364
+
1365
+ return value;
1366
+ }
1367
+
1368
+ onChange(event) {
1369
+ const {
1370
+ type
1371
+ } = this.props;
1372
+ const {
1373
+ value
1374
+ } = event.target;
1375
+
1376
+ if (type !== 'text' && typeof value === 'string' && value.trim() === '') {
1377
+ return;
1378
+ }
1379
+
1380
+ this.setState({
1381
+ value
1382
+ });
1383
+ }
1384
+
1385
+ changeValue(event, sign = 1, shouldUpdate = false) {
1386
+ event.preventDefault();
1387
+ const {
1388
+ customValues,
1389
+ step,
1390
+ onlyIntegersAllowed,
1391
+ onChange
1392
+ } = this.props;
1393
+ const {
1394
+ currentIndex,
1395
+ value
1396
+ } = this.state;
1397
+ const updatedIndex = currentIndex + sign * 1;
1398
+ let number;
1399
+
1400
+ if (customValues.length > 0) {
1401
+ if (updatedIndex < 0 || updatedIndex >= customValues.length) {
1402
+ return;
1403
+ }
1404
+
1405
+ number = customValues[updatedIndex];
1406
+ } else {
1407
+ const rawNumber = onlyIntegersAllowed ? parseInt(value) : parseFloat(value);
1408
+ const updatedValue = (rawNumber * 10000 + step * sign * 10000) / 10000;
1409
+ number = this.clamp(updatedValue);
1410
+ }
1411
+
1412
+ this.setState({
1413
+ value: number.toString(),
1414
+ currentIndex: updatedIndex
1415
+ }, () => {
1416
+ if (shouldUpdate) {
1417
+ onChange(event, number);
1418
+ }
1419
+ });
1420
+ }
1421
+
1422
+ render() {
1423
+ const {
1424
+ className,
1425
+ classes,
1426
+ label,
1427
+ disabled,
1428
+ error,
1429
+ min,
1430
+ max,
1431
+ customValues,
1432
+ inputClassName,
1433
+ disableUnderline,
1434
+ helperText,
1435
+ variant,
1436
+ textAlign,
1437
+ type = 'number'
1438
+ } = this.props;
1439
+ const {
1440
+ value
1441
+ } = this.state;
1442
+ const names = classNames(className, classes.input); //Logic to disable the increment and decrement buttons
1443
+
1444
+ let disabledStart = false;
1445
+ let disabledEnd = false;
1446
+
1447
+ if (customValues.length > 0) {
1448
+ disabledStart = value === customValues[0];
1449
+ disabledEnd = value === customValues[customValues.length - 1];
1450
+ } else if (isFinite(min) && isFinite(max)) {
1451
+ disabledStart = value === min;
1452
+ disabledEnd = value === max;
1453
+ }
1454
+
1455
+ return /*#__PURE__*/React__default.createElement(TextField$1, {
1456
+ variant: variant,
1457
+ inputRef: ref => this.inputRef = ref,
1458
+ disabled: disabled,
1459
+ label: label,
1460
+ value: value,
1461
+ error: error,
1462
+ helperText: helperText,
1463
+ onChange: this.onChange,
1464
+ onBlur: this.onBlur,
1465
+ onKeyPress: e => {
1466
+ // once the Enter key is pressed, we force input blur
1467
+ if (e.key === 'Enter' && this.inputRef) {
1468
+ this.inputRef.blur();
1469
+ }
1470
+ },
1471
+ onKeyDown: e => {
1472
+ if (e.key === 'ArrowUp') {
1473
+ this.changeValue(e);
1474
+ }
1475
+
1476
+ if (e.key === 'ArrowDown') {
1477
+ this.changeValue(e, -1);
1478
+ }
1479
+ },
1480
+ title: '',
1481
+ type: type,
1482
+ className: names,
1483
+ InputProps: {
1484
+ className: inputClassName,
1485
+ disableUnderline: disableUnderline,
1486
+ startAdornment: /*#__PURE__*/React__default.createElement(InputAdornment, {
1487
+ position: "start"
1488
+ }, /*#__PURE__*/React__default.createElement(IconButton, {
1489
+ className: classes.iconButton,
1490
+ disabled: disabled ? disabled : disabledStart,
1491
+ onClick: e => this.changeValue(e, -1, true)
1492
+ }, /*#__PURE__*/React__default.createElement(Remove, {
1493
+ fontSize: "small"
1494
+ }))),
1495
+ endAdornment: /*#__PURE__*/React__default.createElement(InputAdornment, {
1496
+ position: "end"
1497
+ }, /*#__PURE__*/React__default.createElement(IconButton, {
1498
+ className: classes.iconButton,
1499
+ disabled: disabled ? disabled : disabledEnd,
1500
+ onClick: e => this.changeValue(e, 1, true)
1501
+ }, /*#__PURE__*/React__default.createElement(Add, {
1502
+ fontSize: "small"
1503
+ })))
1504
+ },
1505
+ inputProps: {
1506
+ style: {
1507
+ textAlign
1508
+ },
1509
+ min,
1510
+ max
1511
+ }
1512
+ });
1513
+ }
1514
+
1515
+ }
1516
+ NumberTextFieldCustom.propTypes = {
1517
+ classes: PropTypes.object.isRequired,
1518
+ className: PropTypes.string,
1519
+ customValues: PropTypes.array,
1520
+ disabled: PropTypes.bool,
1521
+ error: PropTypes.bool,
1522
+ inputClassName: PropTypes.string,
1523
+ helperText: PropTypes.string,
1524
+ onChange: PropTypes.func.isRequired,
1525
+ onlyIntegersAllowed: PropTypes.bool,
1526
+ value: PropTypes.any,
1527
+ min: PropTypes.number,
1528
+ max: PropTypes.number,
1529
+ step: PropTypes.number,
1530
+ label: PropTypes.string,
1531
+ disableUnderline: PropTypes.bool,
1532
+ textAlign: PropTypes.string,
1533
+ variant: PropTypes.string,
1534
+ type: PropTypes.string
1535
+ };
1536
+ NumberTextFieldCustom.defaultProps = {
1537
+ step: 1,
1538
+ customValues: [],
1539
+ textAlign: 'center',
1540
+ variant: 'standard',
1541
+ onlyIntegersAllowed: false
1542
+ };
1543
+ var numberTextFieldCustom = withStyles(styles$6)(NumberTextFieldCustom);
1544
+
1545
+ const styles$5 = theme => ({
1546
+ group: {
1547
+ display: 'flex',
1548
+ flexWrap: 'wrap',
1549
+ paddingLeft: 0,
1550
+ marginTop: theme.spacing.unit
1551
+ },
1552
+ vertical: {
1553
+ flexDirection: 'column'
1554
+ }
1555
+ });
1556
+
1557
+ class RawNChoice extends React__default.Component {
1558
+ constructor(...args) {
1559
+ super(...args);
1560
+
1561
+ this.handleChange = event => {
1562
+ this.props.onChange(event.currentTarget.value);
1563
+ };
1564
+ }
1565
+
1566
+ render() {
1567
+ const {
1568
+ header,
1569
+ className,
1570
+ classes,
1571
+ customLabel,
1572
+ opts,
1573
+ value,
1574
+ direction
1575
+ } = this.props;
1576
+ const preppedOpts = opts.map(o => {
1577
+ return typeof o === 'string' ? {
1578
+ label: o,
1579
+ value: o
1580
+ } : o;
1581
+ });
1582
+ const LabelComponent = customLabel || RadioWithLabel;
1583
+ return /*#__PURE__*/React__default.createElement(InputContainer, {
1584
+ label: header,
1585
+ className: className
1586
+ }, /*#__PURE__*/React__default.createElement("div", {
1587
+ className: classNames(classes.group, classes[direction])
1588
+ }, preppedOpts.map((o, index) => /*#__PURE__*/React__default.createElement(LabelComponent, {
1589
+ value: o.value,
1590
+ key: index,
1591
+ checked: o.value === value,
1592
+ onChange: this.handleChange,
1593
+ label: o.label
1594
+ }))));
1595
+ }
1596
+
1597
+ }
1598
+
1599
+ RawNChoice.propTypes = {
1600
+ header: PropTypes.string.isRequired,
1601
+ className: PropTypes.string,
1602
+ customLabel: PropTypes.func,
1603
+ opts: PropTypes.array.isRequired,
1604
+ value: PropTypes.string,
1605
+ onChange: PropTypes.func.isRequired,
1606
+ direction: PropTypes.oneOf(['horizontal', 'vertical']),
1607
+ classes: PropTypes.object.isRequired
1608
+ };
1609
+ const NChoice = withStyles(styles$5)(RawNChoice);
1610
+ const labelValue$1 = PropTypes.shape({
1611
+ label: PropTypes.string,
1612
+ value: PropTypes.string
1613
+ });
1614
+
1615
+ class TwoChoice extends React__default.Component {
1616
+ render() {
1617
+ const {
1618
+ one,
1619
+ two,
1620
+ header,
1621
+ className,
1622
+ customLabel,
1623
+ value,
1624
+ onChange
1625
+ } = this.props;
1626
+ const opts = [one, two];
1627
+ return /*#__PURE__*/React__default.createElement(NChoice, {
1628
+ customLabel: customLabel,
1629
+ header: header,
1630
+ className: className,
1631
+ opts: opts,
1632
+ value: value,
1633
+ onChange: onChange
1634
+ });
1635
+ }
1636
+
1637
+ }
1638
+
1639
+ TwoChoice.propTypes = {
1640
+ header: PropTypes.string.isRequired,
1641
+ value: PropTypes.string.isRequired,
1642
+ onChange: PropTypes.func.isRequired,
1643
+ one: PropTypes.oneOfType([labelValue$1, PropTypes.string]),
1644
+ two: PropTypes.oneOfType([labelValue$1, PropTypes.string]),
1645
+ className: PropTypes.string,
1646
+ customLabel: PropTypes.func
1647
+ };
1648
+ var twoChoice = withStyles(styles$5)(TwoChoice);
1649
+
1650
+ const log$1 = debug('pie-elements:config-ui:mui-box');
1651
+ const MuiBox = withStyles(theme => {
1652
+ const light = theme.palette.type === 'light';
1653
+ const bottomLineColor = light ? 'rgba(0, 0, 0, 0.42)' : 'rgba(255, 255, 255, 0.7)';
1654
+ log$1(theme.palette.primary[theme.palette.type || 'light']);
1655
+ return {
1656
+ muiBox: {
1657
+ paddingTop: theme.spacing.unit,
1658
+ paddingBottom: theme.spacing.unit,
1659
+ position: 'relative',
1660
+ '&:before': {
1661
+ left: 0,
1662
+ right: 0,
1663
+ bottom: 0,
1664
+ height: '1px',
1665
+ content: '""',
1666
+ position: 'absolute',
1667
+ transition: 'background-color 200ms cubic-bezier(0.4, 0, 0.2, 1) 0ms',
1668
+ pointerEvents: 'none',
1669
+ backgroundColor: bottomLineColor
1670
+ },
1671
+ '&:hover:before': {
1672
+ height: '2px'
1673
+ },
1674
+ '&:after': {
1675
+ left: 0,
1676
+ right: 0,
1677
+ bottom: 0,
1678
+ height: '2px',
1679
+ content: '""',
1680
+ position: 'absolute',
1681
+ transform: 'scaleX(0)',
1682
+ transition: 'transform 200ms cubic-bezier(0.0, 0, 0.2, 1) 0ms',
1683
+ pointerEvents: 'none',
1684
+ backgroundColor: theme.palette.primary[theme.palette.type] //'#304ffe'
1685
+
1686
+ }
1687
+ },
1688
+ focused: {
1689
+ '&:after': {
1690
+ transform: 'scaleX(1)'
1691
+ }
1692
+ }
1693
+ };
1694
+ })(({
1695
+ children,
1696
+ classes,
1697
+ focused
1698
+ }) => {
1699
+ const names = classNames(classes.muiBox, focused && classes.focused);
1700
+ return /*#__PURE__*/React__default.createElement("div", {
1701
+ className: names
1702
+ }, children);
1703
+ });
1704
+ MuiBox.propTypes = {
1705
+ children: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.node), PropTypes.node]).isRequired,
1706
+ focused: PropTypes.bool.isRequired
1707
+ };
1708
+
1709
+ const ENTER = 13;
1710
+ const Tag = withStyles(() => ({
1711
+ tag: {
1712
+ padding: '0px',
1713
+ margin: '1px'
1714
+ }
1715
+ }))(({
1716
+ classes,
1717
+ label,
1718
+ onDelete
1719
+ }) => /*#__PURE__*/React__default.createElement(Chip, {
1720
+ className: classes.tag,
1721
+ label: label,
1722
+ onDelete: onDelete
1723
+ }));
1724
+ Tag.propTypes = {
1725
+ label: PropTypes.string.isRequired,
1726
+ onDelete: PropTypes.func.isRequired
1727
+ };
1728
+ class TagsInput extends React__default.Component {
1729
+ constructor(props) {
1730
+ super(props);
1731
+
1732
+ this.onFocus = () => {
1733
+ this.setState({
1734
+ focused: true
1735
+ });
1736
+ };
1737
+
1738
+ this.onBlur = () => {
1739
+ this.setState({
1740
+ focused: false
1741
+ });
1742
+ };
1743
+
1744
+ this.state = {
1745
+ value: '',
1746
+ focused: false
1747
+ };
1748
+
1749
+ this.onKeyDown = event => {
1750
+ if (event.keyCode === ENTER && this.state.value !== '') {
1751
+ const tag = this.state.value.trim();
1752
+ const newTags = uniq(this.props.tags.concat([tag]));
1753
+
1754
+ if (newTags.length !== this.props.tags.length) {
1755
+ this.props.onChange(newTags);
1756
+ this.setState({
1757
+ value: ''
1758
+ });
1759
+ }
1760
+ }
1761
+ };
1762
+
1763
+ this.onChange = event => {
1764
+ this.setState({
1765
+ value: event.target.value
1766
+ });
1767
+ };
1768
+
1769
+ this.deleteTag = tag => {
1770
+ const {
1771
+ tags
1772
+ } = this.props;
1773
+ const tagIndex = tags.indexOf(tag);
1774
+
1775
+ if (tagIndex !== -1) {
1776
+ tags.splice(tagIndex, 1);
1777
+ this.props.onChange(tags);
1778
+ this.input.focus();
1779
+ }
1780
+ };
1781
+ }
1782
+
1783
+ render() {
1784
+ const {
1785
+ classes,
1786
+ tags
1787
+ } = this.props;
1788
+ return /*#__PURE__*/React__default.createElement(MuiBox, {
1789
+ focused: this.state.focused
1790
+ }, /*#__PURE__*/React__default.createElement("div", {
1791
+ className: classes.tagsInput
1792
+ }, (tags || []).map((t, index) => /*#__PURE__*/React__default.createElement(Tag, {
1793
+ key: index,
1794
+ label: t,
1795
+ onDelete: () => this.deleteTag(t)
1796
+ })), /*#__PURE__*/React__default.createElement("input", {
1797
+ ref: r => this.input = r,
1798
+ onKeyDown: this.onKeyDown,
1799
+ onChange: this.onChange,
1800
+ className: classes.input,
1801
+ value: this.state.value,
1802
+ onFocus: this.onFocus,
1803
+ onBlur: this.onBlur,
1804
+ type: "text"
1805
+ })));
1806
+ }
1807
+
1808
+ }
1809
+ TagsInput.propTypes = {
1810
+ classes: PropTypes.object.isRequired,
1811
+ tags: PropTypes.arrayOf(PropTypes.string).isRequired,
1812
+ onChange: PropTypes.func.isRequired
1813
+ };
1814
+
1815
+ const styles$4 = theme => ({
1816
+ tagsInput: {
1817
+ border: `0px solid ${theme.palette.background.paper}`,
1818
+ display: 'flex',
1819
+ flexWrap: 'wrap'
1820
+ },
1821
+ input: {
1822
+ padding: '2px',
1823
+ margin: '1px',
1824
+ minWidth: '30px',
1825
+ width: '100%',
1826
+ flex: '1',
1827
+ border: `0px solid ${theme.palette.background.paper}`,
1828
+ height: '28px',
1829
+ fontSize: theme.typography.fontSize,
1830
+ fontFamily: theme.typography.fontFamily,
1831
+ outline: 'none',
1832
+ '&:focus': {
1833
+ outline: 'none'
1834
+ }
1835
+ }
1836
+ });
1837
+
1838
+ var index$3 = withStyles(styles$4)(TagsInput);
1839
+
1840
+ class IconMenu extends React__default.Component {
1841
+ constructor(props) {
1842
+ super(props);
1843
+
1844
+ this.handleClick = event => {
1845
+ this.setState({
1846
+ open: true,
1847
+ anchorEl: event.currentTarget
1848
+ });
1849
+ };
1850
+
1851
+ this.handleRequestClose = () => {
1852
+ this.setState({
1853
+ open: false
1854
+ });
1855
+ };
1856
+
1857
+ this.state = {
1858
+ anchorEl: undefined,
1859
+ open: false
1860
+ };
1861
+ }
1862
+
1863
+ render() {
1864
+ const {
1865
+ opts,
1866
+ onClick
1867
+ } = this.props;
1868
+ const keys = Object.keys(opts);
1869
+
1870
+ const handleMenuClick = key => () => {
1871
+ onClick(key);
1872
+ this.handleRequestClose();
1873
+ };
1874
+
1875
+ return /*#__PURE__*/React__default.createElement("div", null, /*#__PURE__*/React__default.createElement("div", {
1876
+ onClick: this.handleClick
1877
+ }, this.props.iconButtonElement), /*#__PURE__*/React__default.createElement(Menu, {
1878
+ id: "simple-menu",
1879
+ anchorEl: this.state.anchorEl,
1880
+ open: this.state.open,
1881
+ onClose: this.handleRequestClose
1882
+ }, keys.map((k, index) => /*#__PURE__*/React__default.createElement(MenuItem, {
1883
+ key: index,
1884
+ onClick: handleMenuClick(k)
1885
+ }, opts[k]))));
1886
+ }
1887
+
1888
+ }
1889
+ IconMenu.propTypes = {
1890
+ opts: PropTypes.object,
1891
+ onClick: PropTypes.func.isRequired,
1892
+ iconButtonElement: PropTypes.any
1893
+ };
1894
+ class FeedbackMenu extends React__default.Component {
1895
+ render() {
1896
+ const {
1897
+ value,
1898
+ onChange,
1899
+ classes
1900
+ } = this.props;
1901
+ const t = value && value.type;
1902
+ const iconColor = t === 'custom' || t === 'default' ? 'primary' : 'disabled';
1903
+ const tooltip = t === 'custom' ? 'Custom Feedback' : t === 'default' ? 'Default Feedback' : 'Feedback disabled';
1904
+ const icon = /*#__PURE__*/React__default.createElement(IconButton, {
1905
+ className: classes.icon,
1906
+ "aria-label": tooltip
1907
+ }, /*#__PURE__*/React__default.createElement(ActionFeedback, {
1908
+ color: iconColor
1909
+ }));
1910
+ return /*#__PURE__*/React__default.createElement(IconMenu, {
1911
+ iconButtonElement: icon,
1912
+ onClick: key => onChange(key),
1913
+ opts: {
1914
+ none: 'No Feedback',
1915
+ default: 'Default',
1916
+ custom: 'Custom'
1917
+ }
1918
+ });
1919
+ }
1920
+
1921
+ }
1922
+ FeedbackMenu.propTypes = {
1923
+ value: PropTypes.object,
1924
+ onChange: PropTypes.func.isRequired,
1925
+ classes: PropTypes.object.isRequired
1926
+ };
1927
+ FeedbackMenu.defaultProps = {
1928
+ classes: {}
1929
+ };
1930
+
1931
+ const EditableHtmlContainer = withStyles(theme => ({
1932
+ labelContainer: {},
1933
+ editorHolder: {
1934
+ marginTop: theme.spacing.unit * 2
1935
+ }
1936
+ }))(({
1937
+ label,
1938
+ classes,
1939
+ onChange,
1940
+ value,
1941
+ className,
1942
+ imageSupport,
1943
+ disableImageAlignmentButtons,
1944
+ disabled,
1945
+ spellCheck,
1946
+ nonEmpty,
1947
+ pluginOpts,
1948
+ toolbarOpts,
1949
+ error,
1950
+ maxImageWidth,
1951
+ maxImageHeight,
1952
+ uploadSoundSupport,
1953
+ mathMlOptions: _mathMlOptions = {}
1954
+ }) => {
1955
+ const names = classNames(classes.labelContainer, className);
1956
+ return /*#__PURE__*/React__default.createElement(InputContainer, {
1957
+ label: label,
1958
+ className: names
1959
+ }, /*#__PURE__*/React__default.createElement("div", {
1960
+ className: classes.editorHolder
1961
+ }, /*#__PURE__*/React__default.createElement(EditableHTML, {
1962
+ markup: value || '',
1963
+ disabled: disabled,
1964
+ spellCheck: spellCheck,
1965
+ nonEmpty: nonEmpty,
1966
+ onChange: onChange,
1967
+ imageSupport: imageSupport,
1968
+ disableImageAlignmentButtons: disableImageAlignmentButtons,
1969
+ className: classes.editor,
1970
+ pluginProps: pluginOpts || {},
1971
+ toolbarOpts: toolbarOpts,
1972
+ error: error,
1973
+ maxImageWidth: maxImageWidth,
1974
+ maxImageHeight: maxImageHeight,
1975
+ uploadSoundSupport: uploadSoundSupport,
1976
+ languageCharactersProps: [{
1977
+ language: 'spanish'
1978
+ }, {
1979
+ language: 'special'
1980
+ }],
1981
+ mathMlOptions: _mathMlOptions
1982
+ })));
1983
+ });
1984
+ const Feedback = withStyles(theme => ({
1985
+ text: {
1986
+ width: '100%'
1987
+ },
1988
+ feedbackContainer: {
1989
+ position: 'relative'
1990
+ },
1991
+ arrowIcon: {
1992
+ fill: theme.palette.grey[400],
1993
+ left: -56,
1994
+ position: 'absolute',
1995
+ top: 20
1996
+ }
1997
+ }))(({
1998
+ value,
1999
+ onChange,
2000
+ type,
2001
+ correct,
2002
+ classes,
2003
+ defaults,
2004
+ toolbarOpts,
2005
+ mathMlOptions: _mathMlOptions2 = {}
2006
+ }) => {
2007
+ if (!type || type === 'none') {
2008
+ return null;
2009
+ } else if (type === 'default') {
2010
+ return /*#__PURE__*/React__default.createElement("div", {
2011
+ className: classes.feedbackContainer
2012
+ }, /*#__PURE__*/React__default.createElement(ArrowRight, {
2013
+ className: classes.arrowIcon
2014
+ }), /*#__PURE__*/React__default.createElement(TextField$1, {
2015
+ className: classes.text,
2016
+ label: "Feedback Text",
2017
+ value: correct ? defaults.correct : defaults.incorrect
2018
+ }));
2019
+ } else {
2020
+ return /*#__PURE__*/React__default.createElement("div", {
2021
+ className: classes.feedbackContainer
2022
+ }, /*#__PURE__*/React__default.createElement(ArrowRight, {
2023
+ className: classes.arrowIcon
2024
+ }), /*#__PURE__*/React__default.createElement(EditableHtmlContainer, {
2025
+ className: classes.text,
2026
+ label: "Feedback Text",
2027
+ value: value,
2028
+ onChange: onChange,
2029
+ toolbarOpts: toolbarOpts,
2030
+ mathMlOptions: _mathMlOptions2
2031
+ }));
2032
+ }
2033
+ });
2034
+ class ChoiceConfiguration extends React__default.Component {
2035
+ constructor(...args) {
2036
+ super(...args);
2037
+
2038
+ this._changeFn = key => update => {
2039
+ const {
2040
+ data,
2041
+ onChange
2042
+ } = this.props;
2043
+
2044
+ if (onChange) {
2045
+ onChange(_extends({}, data, {
2046
+ [key]: update
2047
+ }));
2048
+ }
2049
+ };
2050
+
2051
+ this.onLabelChange = this._changeFn('label');
2052
+
2053
+ this.onCheckedChange = event => {
2054
+ const correct = event.target.checked;
2055
+ const {
2056
+ data,
2057
+ onChange
2058
+ } = this.props;
2059
+
2060
+ if (onChange) {
2061
+ onChange(_extends({}, data, {
2062
+ correct
2063
+ }));
2064
+ }
2065
+ };
2066
+
2067
+ this.onFeedbackValueChange = v => {
2068
+ const {
2069
+ data,
2070
+ onChange
2071
+ } = this.props;
2072
+
2073
+ if (data.feedback.type !== 'custom') {
2074
+ return;
2075
+ }
2076
+
2077
+ const fb = _extends({}, data.feedback, {
2078
+ value: v
2079
+ });
2080
+
2081
+ if (onChange) onChange(_extends({}, data, {
2082
+ feedback: fb
2083
+ }));
2084
+ };
2085
+
2086
+ this.onFeedbackTypeChange = t => {
2087
+ const {
2088
+ data,
2089
+ onChange
2090
+ } = this.props;
2091
+
2092
+ const fb = _extends({}, data.feedback, {
2093
+ type: t
2094
+ });
2095
+
2096
+ if (fb.type !== 'custom') {
2097
+ fb.value = undefined;
2098
+ }
2099
+
2100
+ if (onChange) onChange(_extends({}, data, {
2101
+ feedback: fb
2102
+ }));
2103
+ };
2104
+ }
2105
+
2106
+ render() {
2107
+ const {
2108
+ data,
2109
+ classes,
2110
+ mode,
2111
+ onDelete,
2112
+ defaultFeedback,
2113
+ index,
2114
+ className,
2115
+ noLabels,
2116
+ useLetterOrdering,
2117
+ imageSupport,
2118
+ disableImageAlignmentButtons,
2119
+ disabled,
2120
+ spellCheck,
2121
+ nonEmpty,
2122
+ allowFeedBack,
2123
+ allowDelete,
2124
+ pluginOpts,
2125
+ toolbarOpts,
2126
+ error,
2127
+ noCorrectAnswerError,
2128
+ uploadSoundSupport,
2129
+ maxImageWidth,
2130
+ maxImageHeight,
2131
+ mathMlOptions = {}
2132
+ } = this.props;
2133
+ const InputToggle = mode === 'checkbox' ? InputCheckbox : InputRadio;
2134
+ const names = classNames(classes.choiceConfiguration, className);
2135
+ return /*#__PURE__*/React__default.createElement("div", {
2136
+ className: names
2137
+ }, /*#__PURE__*/React__default.createElement("div", {
2138
+ className: classes.topRow
2139
+ }, index > 0 && /*#__PURE__*/React__default.createElement("span", {
2140
+ className: classes.index,
2141
+ type: "title"
2142
+ }, useLetterOrdering ? String.fromCharCode(96 + index).toUpperCase() : index), /*#__PURE__*/React__default.createElement(InputToggle, {
2143
+ className: classes.toggle,
2144
+ onChange: this.onCheckedChange,
2145
+ label: !noLabels ? 'Correct' : '',
2146
+ checked: !!data.correct,
2147
+ error: noCorrectAnswerError
2148
+ }), /*#__PURE__*/React__default.createElement("div", {
2149
+ className: classes.middleColumn
2150
+ }, /*#__PURE__*/React__default.createElement(EditableHtmlContainer, {
2151
+ className: classes.input,
2152
+ label: !noLabels ? 'Label' : '',
2153
+ value: data.label,
2154
+ onChange: this.onLabelChange,
2155
+ imageSupport: imageSupport,
2156
+ disableImageAlignmentButtons: disableImageAlignmentButtons,
2157
+ disabled: disabled,
2158
+ spellCheck: spellCheck,
2159
+ nonEmpty: nonEmpty,
2160
+ pluginOpts: pluginOpts,
2161
+ toolbarOpts: toolbarOpts,
2162
+ error: error,
2163
+ uploadSoundSupport: uploadSoundSupport,
2164
+ mathMlOptions: mathMlOptions,
2165
+ maxImageWidth: maxImageWidth,
2166
+ maxImageHeight: maxImageHeight
2167
+ }), error && /*#__PURE__*/React__default.createElement("div", {
2168
+ className: classes.errorText
2169
+ }, error), allowFeedBack && /*#__PURE__*/React__default.createElement(Feedback, _extends({}, data.feedback, {
2170
+ correct: data.correct,
2171
+ defaults: defaultFeedback,
2172
+ onChange: this.onFeedbackValueChange,
2173
+ toolbarOpts: toolbarOpts
2174
+ }))), allowFeedBack && /*#__PURE__*/React__default.createElement(InputContainer, {
2175
+ className: classes.feedback,
2176
+ label: !noLabels ? 'Feedback' : ''
2177
+ }, /*#__PURE__*/React__default.createElement(FeedbackMenu, {
2178
+ onChange: this.onFeedbackTypeChange,
2179
+ value: data.feedback,
2180
+ classes: {
2181
+ icon: classes.feedbackIcon
2182
+ }
2183
+ })), allowDelete && /*#__PURE__*/React__default.createElement(InputContainer, {
2184
+ className: classes.delete,
2185
+ label: !noLabels ? 'Delete' : ''
2186
+ }, /*#__PURE__*/React__default.createElement(IconButton, {
2187
+ "aria-label": "delete",
2188
+ className: classes.deleteIcon,
2189
+ onClick: onDelete
2190
+ }, /*#__PURE__*/React__default.createElement(ActionDelete, null)))));
2191
+ }
2192
+
2193
+ }
2194
+ ChoiceConfiguration.propTypes = {
2195
+ classes: PropTypes.object.isRequired,
2196
+ noLabels: PropTypes.bool,
2197
+ useLetterOrdering: PropTypes.bool,
2198
+ className: PropTypes.string,
2199
+ error: PropTypes.string,
2200
+ mode: PropTypes.oneOf(['checkbox', 'radio']),
2201
+ defaultFeedback: PropTypes.object.isRequired,
2202
+ disabled: PropTypes.bool,
2203
+ nonEmpty: PropTypes.bool,
2204
+ data: PropTypes.shape({
2205
+ label: PropTypes.string.isRequired,
2206
+ value: PropTypes.string.isRequired,
2207
+ correct: PropTypes.bool,
2208
+ feedback: PropTypes.shape({
2209
+ type: PropTypes.string,
2210
+ value: PropTypes.string
2211
+ })
2212
+ }),
2213
+ onDelete: PropTypes.func,
2214
+ onChange: PropTypes.func,
2215
+ index: PropTypes.number,
2216
+ imageSupport: PropTypes.shape({
2217
+ add: PropTypes.func.isRequired,
2218
+ delete: PropTypes.func.isRequired
2219
+ }),
2220
+ disableImageAlignmentButtons: PropTypes.bool,
2221
+ allowFeedBack: PropTypes.bool,
2222
+ allowDelete: PropTypes.bool,
2223
+ noCorrectAnswerError: PropTypes.string,
2224
+ spellCheck: PropTypes.bool,
2225
+ pluginOpts: PropTypes.object,
2226
+ toolbarOpts: PropTypes.object,
2227
+ uploadSoundSupport: PropTypes.object,
2228
+ maxImageWidth: PropTypes.number,
2229
+ maxImageHeight: PropTypes.number
2230
+ };
2231
+ ChoiceConfiguration.defaultProps = {
2232
+ index: -1,
2233
+ noLabels: false,
2234
+ useLetterOrdering: false,
2235
+ allowFeedBack: true,
2236
+ allowDelete: true
2237
+ };
2238
+
2239
+ const styles$3 = theme => ({
2240
+ index: {
2241
+ paddingRight: theme.spacing.unit,
2242
+ paddingTop: theme.spacing.unit * 3.5
2243
+ },
2244
+ choiceConfiguration: {},
2245
+ topRow: {
2246
+ display: 'flex'
2247
+ },
2248
+ value: {
2249
+ flex: '0.5',
2250
+ paddingRight: theme.spacing.unit
2251
+ },
2252
+ editorHolder: {
2253
+ marginTop: theme.spacing.unit * 2
2254
+ },
2255
+ toggle: {
2256
+ flex: '0 1 auto',
2257
+ paddingTop: theme.spacing.unit / 2,
2258
+ paddingBottom: 0,
2259
+ marginRight: 0,
2260
+ marginLeft: theme.spacing.unit
2261
+ },
2262
+ feedback: {
2263
+ flex: '0 1 auto',
2264
+ paddingTop: theme.spacing.unit * 2,
2265
+ paddingLeft: 0,
2266
+ marginLeft: 0,
2267
+ marginRight: theme.spacing.unit
2268
+ },
2269
+ feedbackIcon: {
2270
+ margin: 0,
2271
+ width: 'inherit'
2272
+ },
2273
+ deleteIcon: {
2274
+ margin: 0,
2275
+ width: 'inherit'
2276
+ },
2277
+ delete: {
2278
+ flex: '0 1 auto',
2279
+ paddingTop: theme.spacing.unit * 2,
2280
+ paddingLeft: 0,
2281
+ marginLeft: 0
2282
+ },
2283
+ middleColumn: {
2284
+ display: 'flex',
2285
+ flex: 1,
2286
+ flexDirection: 'column',
2287
+ marginRight: theme.spacing.unit
2288
+ },
2289
+ input: {
2290
+ marginRight: 0
2291
+ },
2292
+ errorText: {
2293
+ fontSize: theme.typography.fontSize - 2,
2294
+ color: theme.palette.error.main
2295
+ }
2296
+ });
2297
+
2298
+ var index$2 = withStyles(styles$3)(ChoiceConfiguration);
2299
+
2300
+ class RawLayoutContents extends React__default.Component {
2301
+ constructor(...args) {
2302
+ super(...args);
2303
+
2304
+ this.getConfiguration = () => {
2305
+ var _secondary$props, _secondary$props2, _secondary$props2$chi, _secondary$props2$chi2;
2306
+
2307
+ const {
2308
+ secondary
2309
+ } = this.props; // in config-layout, secondary can be: <SettingsBox>{settings}</SettingsBox>, settings, null
2310
+
2311
+ return (secondary == null ? void 0 : (_secondary$props = secondary.props) == null ? void 0 : _secondary$props.configuration) || (secondary == null ? void 0 : (_secondary$props2 = secondary.props) == null ? void 0 : (_secondary$props2$chi = _secondary$props2.children) == null ? void 0 : (_secondary$props2$chi2 = _secondary$props2$chi.props) == null ? void 0 : _secondary$props2$chi2.configuration) || undefined;
2312
+ };
2313
+ }
2314
+
2315
+ // // eslint-disable-next-line no-unused-vars
2316
+ // componentDidUpdate(prevProps, prevState, snapshot) {
2317
+ // const configuration = this.getConfiguration();
2318
+ // const { mode } = this.props;
2319
+ //
2320
+ // // promptHolder class is used to wrap up inputs:
2321
+ // // we don't want inputs to fill the entire scrollable container,
2322
+ // // but instead we want inputs to fit in the first view,
2323
+ // // so we calculate the maximum space inputs need
2324
+ // try {
2325
+ // if (
2326
+ // configuration?.maxWidth &&
2327
+ // getComputedStyle(document.documentElement).getPropertyValue('--pie-prompt-holder-max-width') !==
2328
+ // configuration?.maxWidth
2329
+ // ) {
2330
+ // document.documentElement.style.setProperty(
2331
+ // '--pie-prompt-holder-max-width',
2332
+ // mode === 'inline' ? `calc(${configuration.maxWidth} - 340px)` : configuration.maxWidth,
2333
+ // );
2334
+ // }
2335
+ // } catch (e) {
2336
+ // console.log(e.toString());
2337
+ // }
2338
+ // }
2339
+ render() {
2340
+ const {
2341
+ mode,
2342
+ secondary,
2343
+ children,
2344
+ classes,
2345
+ dimensions
2346
+ } = this.props;
2347
+ const {
2348
+ minHeight,
2349
+ minWidth,
2350
+ maxHeight,
2351
+ maxWidth
2352
+ } = dimensions || {};
2353
+ const configuration = this.getConfiguration();
2354
+ let hasSettingsPanel = Object.entries(configuration || {}).some(([, obj]) => !!(obj != null && obj.settings)); // ebsr has configuration.partA and configuration.partB
2355
+ // because we might have nested configuration for other item types as well, let's add this simple regex to check values for settings
2356
+
2357
+ if (!hasSettingsPanel) {
2358
+ try {
2359
+ var _JSON$stringify, _JSON$stringify$match;
2360
+
2361
+ hasSettingsPanel = (_JSON$stringify = JSON.stringify(configuration)) == null ? void 0 : (_JSON$stringify$match = _JSON$stringify.match(/settings":true/)) == null ? void 0 : _JSON$stringify$match.length;
2362
+ } catch (e) {
2363
+ // eslint-disable-next-line no-console
2364
+ console.log(e.toString());
2365
+ }
2366
+ }
2367
+
2368
+ return /*#__PURE__*/React__default.createElement("div", {
2369
+ className: classes.container,
2370
+ style: {
2371
+ minHeight,
2372
+ minWidth,
2373
+ maxHeight,
2374
+ maxWidth
2375
+ }
2376
+ }, mode === 'inline' && /*#__PURE__*/React__default.createElement("div", {
2377
+ className: classNames(classes.flow, classes.contentContainer)
2378
+ }, /*#__PURE__*/React__default.createElement("div", {
2379
+ className: classNames(classes.configContainer, 'design-container')
2380
+ }, children), hasSettingsPanel && /*#__PURE__*/React__default.createElement("div", {
2381
+ className: classNames(classes.settingsContainer, 'settings-container')
2382
+ }, secondary)), mode === 'tabbed' && hasSettingsPanel && /*#__PURE__*/React__default.createElement(Tabs$1, {
2383
+ onChange: this.onTabsChange,
2384
+ contentClassName: classes.contentContainer,
2385
+ indicatorColor: "primary"
2386
+ }, /*#__PURE__*/React__default.createElement("div", {
2387
+ title: "Design",
2388
+ className: "design-container"
2389
+ }, children), /*#__PURE__*/React__default.createElement("div", {
2390
+ title: "Settings",
2391
+ className: "settings-container"
2392
+ }, secondary)), mode === 'tabbed' && !hasSettingsPanel && /*#__PURE__*/React__default.createElement("div", {
2393
+ className: classNames(classes.contentContainer, 'design-container')
2394
+ }, children));
2395
+ }
2396
+
2397
+ }
2398
+
2399
+ RawLayoutContents.propTypes = {
2400
+ mode: PropTypes.oneOf(['tabbed', 'inline']),
2401
+ secondary: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.node), PropTypes.node]),
2402
+ children: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.node), PropTypes.node]),
2403
+ classes: PropTypes.object,
2404
+ dimensions: PropTypes.object
2405
+ };
2406
+
2407
+ const styles$2 = theme => ({
2408
+ flow: {
2409
+ display: 'flex',
2410
+ justifyContent: 'space-between'
2411
+ },
2412
+ container: {
2413
+ display: 'flex',
2414
+ flexDirection: 'column',
2415
+ position: 'relative'
2416
+ },
2417
+ contentContainer: {
2418
+ padding: `${theme.spacing.unit * 2}px 0`
2419
+ },
2420
+ configContainer: {
2421
+ flex: '1'
2422
+ },
2423
+ settingsContainer: {
2424
+ marginLeft: theme.spacing.unit * 2
2425
+ }
2426
+ });
2427
+
2428
+ var LayoutContents = withStyles$1(styles$2)(RawLayoutContents);
2429
+
2430
+ class SettingsBox extends React__default.Component {
2431
+ render() {
2432
+ const {
2433
+ classes,
2434
+ className,
2435
+ children
2436
+ } = this.props;
2437
+ return /*#__PURE__*/React__default.createElement("div", {
2438
+ className: classNames(classes.settingsBox, className)
2439
+ }, children);
2440
+ }
2441
+
2442
+ }
2443
+ SettingsBox.propTypes = {
2444
+ classes: PropTypes.object.isRequired,
2445
+ className: PropTypes.string,
2446
+ children: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.node), PropTypes.node]).isRequired
2447
+ };
2448
+ SettingsBox.defaultProps = {};
2449
+
2450
+ const styles$1 = theme => ({
2451
+ settingsBox: {
2452
+ backgroundColor: theme.palette.background.paper,
2453
+ border: `2px solid ${theme.palette.grey[200]}`,
2454
+ display: 'flex',
2455
+ flexDirection: 'column',
2456
+ justifyContent: 'flex-start',
2457
+ minWidth: '275px',
2458
+ maxWidth: '300px',
2459
+ padding: '20px 4px 4px 20px',
2460
+ zIndex: 99
2461
+ }
2462
+ });
2463
+
2464
+ var SettingsBox$1 = withStyles(styles$1)(SettingsBox);
2465
+
2466
+ const styles = {
2467
+ extraCSSRules: {}
2468
+ };
2469
+
2470
+ class MeasuredConfigLayout extends AppendCSSRules {
2471
+ constructor(...props) {
2472
+ super(...props);
2473
+
2474
+ this.onResize = contentRect => {
2475
+ const {
2476
+ bounds
2477
+ } = contentRect;
2478
+ const {
2479
+ sidePanelMinWidth,
2480
+ dimensions
2481
+ } = this.props;
2482
+ const {
2483
+ maxWidth
2484
+ } = dimensions || {};
2485
+ const layoutMode = bounds.width > sidePanelMinWidth && (maxWidth ? maxWidth > sidePanelMinWidth : true) ? 'inline' : 'tabbed';
2486
+ this.setState({
2487
+ layoutMode
2488
+ });
2489
+ };
2490
+
2491
+ this.state = {
2492
+ layoutMode: undefined
2493
+ };
2494
+ }
2495
+
2496
+ render() {
2497
+ return /*#__PURE__*/React__default.createElement(Measure, {
2498
+ bounds: true,
2499
+ onResize: this.onResize
2500
+ }, ({
2501
+ measureRef
2502
+ }) => {
2503
+ const {
2504
+ children,
2505
+ settings,
2506
+ hideSettings,
2507
+ dimensions,
2508
+ classes
2509
+ } = this.props;
2510
+ const {
2511
+ layoutMode
2512
+ } = this.state;
2513
+ const settingsPanel = layoutMode === 'inline' ? /*#__PURE__*/React__default.createElement(SettingsBox$1, {
2514
+ className: "settings-box"
2515
+ }, settings) : settings;
2516
+ const secondaryContent = hideSettings ? null : settingsPanel;
2517
+ const finalClass = classNames('main-container', classes.extraCSSRules);
2518
+ return /*#__PURE__*/React__default.createElement("div", {
2519
+ ref: measureRef,
2520
+ className: finalClass
2521
+ }, /*#__PURE__*/React__default.createElement(LayoutContents, {
2522
+ mode: layoutMode,
2523
+ secondary: secondaryContent,
2524
+ dimensions: dimensions
2525
+ }, children));
2526
+ });
2527
+ }
2528
+
2529
+ }
2530
+
2531
+ MeasuredConfigLayout.propTypes = {
2532
+ children: PropTypes.oneOfType([PropTypes.string, PropTypes.arrayOf(PropTypes.element), PropTypes.element]),
2533
+ className: PropTypes.string,
2534
+ classes: PropTypes.object,
2535
+ dimensions: PropTypes.object,
2536
+ settings: PropTypes.element,
2537
+ sidePanelMinWidth: PropTypes.number,
2538
+ hideSettings: PropTypes.bool
2539
+ };
2540
+ MeasuredConfigLayout.defaultProps = {
2541
+ sidePanelMinWidth: 1135,
2542
+ hideSettings: false,
2543
+ dimensions: {}
2544
+ };
2545
+ const ConfigLayout = withStyles(styles)(withContentRect('bounds')(MeasuredConfigLayout));
2546
+
2547
+ var index$1 = /*#__PURE__*/Object.freeze({
2548
+ __proto__: null,
2549
+ ConfigLayout: ConfigLayout,
2550
+ LayoutContents: LayoutContents
2551
+ });
2552
+
2553
+ /**
2554
+ * Add value to every model.choices.
2555
+ * @param {Object} model the model to normalize
2556
+ * @return {Object} the updated model
2557
+ */
2558
+
2559
+ const normalizeChoices = model => {
2560
+ const choices = model.choices.map((c, index) => {
2561
+ if (!c.value) {
2562
+ c.value = `${index}`;
2563
+ }
2564
+
2565
+ return c;
2566
+ });
2567
+ return _extends({}, model, {
2568
+ choices
2569
+ });
2570
+ };
2571
+ /**
2572
+ * Find the first available index.
2573
+ * @param {string[]} values
2574
+ * @param {number} index
2575
+ * @return {string}
2576
+ */
2577
+
2578
+ const firstAvailableIndex = (values, index) => {
2579
+ if (includes(values, `${index}`)) {
2580
+ return firstAvailableIndex(values, index + 1);
2581
+ } else {
2582
+ return `${index}`;
2583
+ }
2584
+ };
2585
+
2586
+ var choiceUtils = /*#__PURE__*/Object.freeze({
2587
+ __proto__: null,
2588
+ firstAvailableIndex: firstAvailableIndex,
2589
+ normalizeChoices: normalizeChoices
2590
+ });
2591
+
2592
+ const withStatefulModel = Component => {
2593
+ class Stateful extends React__default.Component {
2594
+ constructor(props) {
2595
+ super(props);
2596
+
2597
+ this.onChange = model => {
2598
+ this.setState({
2599
+ model
2600
+ }, () => {
2601
+ this.props.onChange(this.state.model);
2602
+ });
2603
+ };
2604
+
2605
+ this.state = {
2606
+ model: props.model
2607
+ };
2608
+ }
2609
+
2610
+ UNSAFE_componentWillReceiveProps(props) {
2611
+ this.setState({
2612
+ model: props.model
2613
+ });
2614
+ }
2615
+
2616
+ render() {
2617
+ return /*#__PURE__*/React__default.createElement(Component, {
2618
+ model: this.state.model,
2619
+ onChange: this.onChange
2620
+ });
2621
+ }
2622
+
2623
+ }
2624
+
2625
+ Stateful.propTypes = {
2626
+ model: PropTypes.object.isRequired,
2627
+ onChange: PropTypes.func.isRequired
2628
+ };
2629
+ return Stateful;
2630
+ };
2631
+
2632
+ const Toggle = withStyles(theme => ({
2633
+ toggle: {
2634
+ display: 'flex',
2635
+ width: '100%',
2636
+ justifyContent: 'space-between'
2637
+ },
2638
+ label: {
2639
+ color: 'rgba(0, 0, 0, 0.89)',
2640
+ fontSize: theme.typography.fontSize,
2641
+ paddingTop: theme.spacing.unit * 2
2642
+ },
2643
+ checkedThumb: {
2644
+ color: `${color.tertiary()} !important`
2645
+ },
2646
+ checkedBar: {
2647
+ backgroundColor: `${color.tertiaryLight()} !important`
2648
+ }
2649
+ }))(({
2650
+ checked,
2651
+ disabled,
2652
+ label,
2653
+ toggle,
2654
+ classes
2655
+ }) => /*#__PURE__*/React__default.createElement("div", {
2656
+ className: classes.toggle
2657
+ }, /*#__PURE__*/React__default.createElement(InputLabel, {
2658
+ className: classes.label
2659
+ }, label), /*#__PURE__*/React__default.createElement(Switch, {
2660
+ classes: {
2661
+ checked: classNames(classes.checkedThumb),
2662
+ bar: classNames({
2663
+ [classes.checkedBar]: checked
2664
+ })
2665
+ },
2666
+ checked: checked,
2667
+ disabled: disabled,
2668
+ onChange: e => toggle(e.target.checked)
2669
+ })));
2670
+ Toggle.propTypes = {
2671
+ checked: PropTypes.bool,
2672
+ label: PropTypes.string.isRequired,
2673
+ toggle: PropTypes.func.isRequired
2674
+ };
2675
+
2676
+ const DisplaySize = withStyles(theme => ({
2677
+ displaySize: {
2678
+ display: 'flex',
2679
+ paddingTop: theme.spacing.unit
2680
+ }
2681
+ }))(({
2682
+ size,
2683
+ label,
2684
+ classes,
2685
+ onChange
2686
+ }) => {
2687
+ const updateSize = (key, v) => {
2688
+ onChange(_extends({}, size, {
2689
+ [key]: v
2690
+ }));
2691
+ };
2692
+
2693
+ return /*#__PURE__*/React__default.createElement("div", null, /*#__PURE__*/React__default.createElement(Typography, null, label), /*#__PURE__*/React__default.createElement("div", {
2694
+ className: classes.displaySize
2695
+ }, /*#__PURE__*/React__default.createElement(NumberTextField$1, {
2696
+ label: "Width",
2697
+ type: "number",
2698
+ variant: "outlined",
2699
+ value: size.width,
2700
+ min: 150,
2701
+ max: 1000,
2702
+ onChange: (e, v) => updateSize('width', v)
2703
+ }), /*#__PURE__*/React__default.createElement(NumberTextField$1, {
2704
+ label: "Height",
2705
+ type: "number",
2706
+ variant: "outlined",
2707
+ min: 150,
2708
+ max: 1000,
2709
+ value: size.height,
2710
+ onChange: (e, v) => updateSize('height', v)
2711
+ })));
2712
+ });
2713
+ DisplaySize.propTypes = {
2714
+ size: PropTypes.shape({
2715
+ width: PropTypes.number.isRequired,
2716
+ height: PropTypes.number.isRequired
2717
+ }).isRequired,
2718
+ label: PropTypes.string.isRequired,
2719
+ onChange: PropTypes.func
2720
+ };
2721
+
2722
+ var SettingsRadioLabel = withStyles(theme => ({
2723
+ label: {
2724
+ color: 'rgba(0, 0, 0, 0.89)',
2725
+ fontSize: theme.typography.fontSize - 2,
2726
+ left: '-5px',
2727
+ position: 'relative'
2728
+ },
2729
+ customColor: {
2730
+ color: `${color.tertiary()} !important`
2731
+ }
2732
+ }))(({
2733
+ label,
2734
+ value,
2735
+ checked,
2736
+ onChange,
2737
+ classes
2738
+ }) => /*#__PURE__*/React__default.createElement(FormControlLabel, {
2739
+ value: value,
2740
+ classes: {
2741
+ label: classes.label
2742
+ },
2743
+ control: /*#__PURE__*/React__default.createElement(Radio$1, {
2744
+ className: classes.customColor,
2745
+ checked: checked,
2746
+ onChange: onChange
2747
+ }),
2748
+ label: label
2749
+ }));
2750
+
2751
+ const _excluded = ["isConfigProperty"];
2752
+ const log = debug('pie-lib:config-ui:settings:panel');
2753
+ const labelValue = {
2754
+ label: PropTypes.string,
2755
+ value: PropTypes.string
2756
+ };
2757
+ const baseTypes = {
2758
+ label: PropTypes.string,
2759
+ value: PropTypes.string,
2760
+ onChange: PropTypes.func
2761
+ };
2762
+
2763
+ const CheckboxChoice = ({
2764
+ label,
2765
+ value,
2766
+ onChange
2767
+ }) => {
2768
+ return /*#__PURE__*/React__default.createElement(Checkbox$1, {
2769
+ checked: value,
2770
+ label: label,
2771
+ onChange: event => {
2772
+ onChange(event.target.checked);
2773
+ }
2774
+ });
2775
+ };
2776
+
2777
+ CheckboxChoice.propTypes = {
2778
+ label: PropTypes.string,
2779
+ value: PropTypes.bool,
2780
+ onChange: PropTypes.func
2781
+ };
2782
+
2783
+ const Radio = ({
2784
+ classes,
2785
+ label,
2786
+ value,
2787
+ onChange,
2788
+ choices
2789
+ }) => {
2790
+ return /*#__PURE__*/React__default.createElement(NChoice, {
2791
+ className: classes.radioSettings,
2792
+ direction: "horizontal",
2793
+ customLabel: SettingsRadioLabel,
2794
+ value: value,
2795
+ header: label,
2796
+ opts: choices,
2797
+ onChange: onChange
2798
+ });
2799
+ };
2800
+
2801
+ Radio.propTypes = _extends({}, baseTypes, {
2802
+ choices: PropTypes.arrayOf(PropTypes.shape(labelValue))
2803
+ });
2804
+ const StyledRadio = withStyles(theme => ({
2805
+ radioSettings: {
2806
+ marginTop: theme.spacing.unit / 2,
2807
+ paddingBottom: theme.spacing.unit / 2,
2808
+ width: '100%',
2809
+ '& > label': {
2810
+ color: 'rgba(0, 0, 0, 0.89)',
2811
+ transform: 'translate(0, 10px) scale(1)',
2812
+ fontSize: '14px'
2813
+ },
2814
+ '& > div': {
2815
+ marginTop: theme.spacing.unit * 2.5
2816
+ }
2817
+ },
2818
+ label: {
2819
+ display: 'none'
2820
+ }
2821
+ }))(Radio);
2822
+ const Dropdown = withStyles(theme => ({
2823
+ label: {
2824
+ margin: 0,
2825
+ fontSize: theme.typography.fontSize
2826
+ },
2827
+ wrapper: {
2828
+ marginTop: theme.spacing.unit / 2,
2829
+ border: '2px solid lightgrey',
2830
+ borderRadius: '4px',
2831
+ padding: `0 ${theme.spacing.unit}px`
2832
+ }
2833
+ }))(({
2834
+ classes,
2835
+ label,
2836
+ value,
2837
+ onChange,
2838
+ choices: _choices = []
2839
+ }) => {
2840
+ const getItemLabel = l => typeof l === 'string' ? l : l.label;
2841
+
2842
+ const getItemValue = l => typeof l === 'string' ? l : l.value;
2843
+
2844
+ return /*#__PURE__*/React__default.createElement("div", null, label && /*#__PURE__*/React__default.createElement("p", {
2845
+ className: classes.label
2846
+ }, label), /*#__PURE__*/React__default.createElement(Select, {
2847
+ className: classes.wrapper,
2848
+ value: value || _choices && _choices[0],
2849
+ onChange: ({
2850
+ target
2851
+ }) => onChange(target.value),
2852
+ input: /*#__PURE__*/React__default.createElement(MaterialInput, {
2853
+ id: `dropdown-${label}`
2854
+ }),
2855
+ disableUnderline: true
2856
+ }, _choices.map((l, index) => /*#__PURE__*/React__default.createElement(MenuItem, {
2857
+ key: index,
2858
+ value: getItemValue(l)
2859
+ }, getItemLabel(l)))));
2860
+ });
2861
+ Dropdown.propTypes = _extends({}, baseTypes, {
2862
+ choices: PropTypes.arrayOf(PropTypes.string)
2863
+ });
2864
+ const TextField = withStyles(theme => ({
2865
+ field: {
2866
+ marginRight: theme.spacing.unit * 3,
2867
+ marginTop: theme.spacing.unit
2868
+ }
2869
+ }))(({
2870
+ classes,
2871
+ label
2872
+ }) => {
2873
+ return /*#__PURE__*/React__default.createElement(Typography, {
2874
+ className: classes.field
2875
+ }, label);
2876
+ });
2877
+ const NumberField = withStyles(theme => ({
2878
+ field: {
2879
+ width: '35%',
2880
+ marginRight: theme.spacing.unit * 3,
2881
+ marginTop: theme.spacing.unit
2882
+ },
2883
+ wrapper: {
2884
+ marginTop: theme.spacing.unit / 2,
2885
+ border: '2px solid lightgrey',
2886
+ borderRadius: '4px',
2887
+ padding: `0 ${theme.spacing.unit}px`
2888
+ }
2889
+ }))(({
2890
+ classes,
2891
+ label,
2892
+ value,
2893
+ onChange: _onChange = () => {},
2894
+ suffix,
2895
+ min,
2896
+ max
2897
+ }) => {
2898
+ return /*#__PURE__*/React__default.createElement(NumberTextField$1, {
2899
+ label: label || 'Label',
2900
+ value: value,
2901
+ max: max,
2902
+ min: min,
2903
+ onChange: (ev, value) => _onChange(value),
2904
+ suffix: suffix,
2905
+ className: classes.field,
2906
+ showErrorWhenOutsideRange: true,
2907
+ inputClassName: classes.wrapper,
2908
+ disableUnderline: true,
2909
+ classes: classes
2910
+ });
2911
+ });
2912
+ NumberField.propTypes = _extends({}, baseTypes, {
2913
+ classes: PropTypes.object,
2914
+ suffix: PropTypes.string,
2915
+ min: PropTypes.number,
2916
+ max: PropTypes.number,
2917
+ value: PropTypes.number
2918
+ });
2919
+ TextField.propTypes = _extends({}, baseTypes);
2920
+
2921
+ const ToggleWrapper = ({
2922
+ disabled,
2923
+ label,
2924
+ value,
2925
+ onChange
2926
+ }) => /*#__PURE__*/React__default.createElement(Toggle, {
2927
+ label: label,
2928
+ checked: !!value,
2929
+ disabled: !!disabled,
2930
+ toggle: onChange
2931
+ });
2932
+
2933
+ ToggleWrapper.propTypes = _extends({}, baseTypes, {
2934
+ value: PropTypes.bool
2935
+ });
2936
+ const tagMap = {
2937
+ toggle: ToggleWrapper,
2938
+ radio: StyledRadio,
2939
+ dropdown: Dropdown,
2940
+ numberField: NumberField,
2941
+ checkbox: CheckboxChoice,
2942
+ textField: TextField
2943
+ };
2944
+ const Group = withStyles(theme => ({
2945
+ group: {
2946
+ margin: `0 0 ${theme.spacing.unit * 2}px 0`
2947
+ },
2948
+ groupHeader: {
2949
+ color: '#495B8F',
2950
+ fontSize: theme.typography.fontSize + 2,
2951
+ fontWeight: 600,
2952
+ marginBottom: theme.spacing.unit
2953
+ },
2954
+ numberFields: {
2955
+ fontSize: theme.typography.fontSize,
2956
+ marginBottom: 0
2957
+ }
2958
+ }))(props => {
2959
+ const {
2960
+ classes,
2961
+ model,
2962
+ label,
2963
+ group,
2964
+ configuration,
2965
+ onChange
2966
+ } = props;
2967
+ /**
2968
+ * @param group - the group of settings
2969
+ * @param key - the key(or path) to be used to set or get from model or configuration
2970
+ * @param innerKey - the key(or path) to be used to get from the group (used only for numberField type)
2971
+ * @returns tag that corresponds to element type */
2972
+
2973
+ const getTag = (group, key, innerKey) => {
2974
+ const _get = get(group, innerKey || key),
2975
+ {
2976
+ isConfigProperty
2977
+ } = _get,
2978
+ properties = _objectWithoutPropertiesLoose(_get, _excluded);
2979
+
2980
+ const value = isConfigProperty ? get(configuration, key) : get(model, key);
2981
+
2982
+ const tagProps = _extends({}, properties, {
2983
+ key,
2984
+ value
2985
+ });
2986
+
2987
+ const Tag = tagMap[tagProps.type];
2988
+ return /*#__PURE__*/React__default.createElement(Tag, _extends({
2989
+ key: key
2990
+ }, tagProps, {
2991
+ onChange: v => onChange(key, v, isConfigProperty)
2992
+ }));
2993
+ };
2994
+
2995
+ const content = (group, key) => {
2996
+ const currentGroup = group[key];
2997
+
2998
+ if (!currentGroup) {
2999
+ return null;
3000
+ }
3001
+
3002
+ const {
3003
+ type,
3004
+ label,
3005
+ fields,
3006
+ choices
3007
+ } = currentGroup;
3008
+
3009
+ if (type === 'numberFields') {
3010
+ return /*#__PURE__*/React__default.createElement("div", {
3011
+ key: `numberField-${label}`
3012
+ }, /*#__PURE__*/React__default.createElement("p", {
3013
+ className: classes.numberFields
3014
+ }, label), Object.keys(fields).map(fieldKey => {
3015
+ return getTag(group, `${key}.${fieldKey}`, `${key}.fields.${fieldKey}`);
3016
+ }));
3017
+ }
3018
+
3019
+ if (type === 'checkboxes') {
3020
+ return /*#__PURE__*/React__default.createElement("div", {
3021
+ key: `checkbox-${label}`
3022
+ }, /*#__PURE__*/React__default.createElement("p", null, label), Object.keys(choices).map(choiceKey => {
3023
+ return getTag(group, `${key}.${choiceKey}`, `${key}.choices.${choiceKey}`);
3024
+ }));
3025
+ } // if type is toggle, radio, dropdown, numberField or numberText
3026
+
3027
+
3028
+ return getTag(group, key);
3029
+ };
3030
+
3031
+ return /*#__PURE__*/React__default.createElement("div", {
3032
+ className: classes.group
3033
+ }, /*#__PURE__*/React__default.createElement("div", {
3034
+ className: classes.groupHeader
3035
+ }, label), Object.keys(group).map(key => {
3036
+ return content(group, key);
3037
+ }));
3038
+ });
3039
+ class Panel extends React__default.Component {
3040
+ constructor(...args) {
3041
+ super(...args);
3042
+
3043
+ this.change = (key, value, isConfigProperty = false) => {
3044
+ log('[changeModel]', key, value);
3045
+ const {
3046
+ onChangeModel,
3047
+ onChangeConfiguration
3048
+ } = this.props;
3049
+
3050
+ const model = _extends({}, this.props.model);
3051
+
3052
+ const configuration = _extends({}, this.props.configuration);
3053
+
3054
+ if (isConfigProperty) {
3055
+ set(configuration, key, value);
3056
+ onChangeConfiguration(configuration, key);
3057
+ } else {
3058
+ set(model, key, value);
3059
+ onChangeModel(model, key);
3060
+ }
3061
+ };
3062
+ }
3063
+
3064
+ render() {
3065
+ const {
3066
+ groups,
3067
+ model,
3068
+ configuration,
3069
+ modal
3070
+ } = this.props;
3071
+ log('render:', model);
3072
+ const renderedGroups = Object.keys(groups || {}).map(group => {
3073
+ const showGroup = Object.entries(groups[group]).some(([, propVal]) => !!propVal);
3074
+
3075
+ if (showGroup) {
3076
+ return /*#__PURE__*/React__default.createElement(Group, {
3077
+ label: group,
3078
+ key: group,
3079
+ model: model,
3080
+ configuration: configuration,
3081
+ group: groups[group],
3082
+ onChange: this.change
3083
+ });
3084
+ }
3085
+
3086
+ return null;
3087
+ });
3088
+ return /*#__PURE__*/React__default.createElement("div", null, renderedGroups, modal);
3089
+ }
3090
+
3091
+ }
3092
+ Panel.propTypes = {
3093
+ model: PropTypes.object,
3094
+ configuration: PropTypes.object,
3095
+ groups: PropTypes.object,
3096
+ onChangeModel: PropTypes.func,
3097
+ onChangeConfiguration: PropTypes.func,
3098
+ modal: PropTypes.object
3099
+ };
3100
+ Panel.defaultProps = {
3101
+ onChangeModel: () => {},
3102
+ onChangeConfiguration: () => {}
3103
+ };
3104
+
3105
+ const textField = (label, isConfigProperty = true) => ({
3106
+ label,
3107
+ type: 'textField',
3108
+ isConfigProperty
3109
+ });
3110
+ const toggle = (label, isConfigProperty = false, disabled = false) => ({
3111
+ type: 'toggle',
3112
+ label,
3113
+ isConfigProperty,
3114
+ disabled
3115
+ });
3116
+
3117
+ const toChoice = opt => {
3118
+ if (typeof opt === 'string') {
3119
+ return {
3120
+ label: opt,
3121
+ value: opt
3122
+ };
3123
+ } else {
3124
+ return opt;
3125
+ }
3126
+ };
3127
+
3128
+ const radio = function radio() {
3129
+ const args = Array.prototype.slice.call(arguments);
3130
+ const [label, choices, isConfigProperty = false] = args;
3131
+ return {
3132
+ type: 'radio',
3133
+ label,
3134
+ choices: choices && choices.map(o => toChoice(o)),
3135
+ isConfigProperty
3136
+ };
3137
+ };
3138
+ const dropdown = (label, choices, isConfigProperty = false) => {
3139
+ return {
3140
+ type: 'dropdown',
3141
+ label,
3142
+ choices,
3143
+ isConfigProperty
3144
+ };
3145
+ };
3146
+ const numberField = (label, options, isConfigProperty = false) => _extends({}, options, {
3147
+ label,
3148
+ type: 'numberField',
3149
+ isConfigProperty
3150
+ });
3151
+ const numberFields = (label, fields, isConfigProperty = false) => {
3152
+ Object.keys(fields).map(key => {
3153
+ fields[key] = numberField(fields[key].label, fields[key], isConfigProperty);
3154
+ });
3155
+ return {
3156
+ type: 'numberFields',
3157
+ label,
3158
+ fields
3159
+ };
3160
+ };
3161
+ const checkbox = (label, settings, isConfigProperty = false) => _extends({}, settings, {
3162
+ label,
3163
+ type: 'checkbox',
3164
+ isConfigProperty
3165
+ });
3166
+ const checkboxes = (label, choices, isConfigProperty = false) => {
3167
+ Object.keys(choices).map(key => {
3168
+ choices[key] = checkbox(choices[key].label, choices[key], isConfigProperty);
3169
+ });
3170
+ return {
3171
+ type: 'checkboxes',
3172
+ label,
3173
+ choices
3174
+ };
3175
+ };
3176
+
3177
+ var index = /*#__PURE__*/Object.freeze({
3178
+ __proto__: null,
3179
+ Panel: Panel,
3180
+ checkbox: checkbox,
3181
+ checkboxes: checkboxes,
3182
+ dropdown: dropdown,
3183
+ numberField: numberField,
3184
+ numberFields: numberFields,
3185
+ radio: radio,
3186
+ textField: textField,
3187
+ toggle: toggle
3188
+ });
3189
+
3190
+ export { alertDialog as AlertDialog, Checkbox$1 as Checkbox, index$2 as ChoiceConfiguration, DisplaySize, index$4 as FeedbackConfig, FeedbackSelector$1 as FeedbackSelector, formSection as FormSection, Help, Input, InputCheckbox, InputRadio, InputSwitch, Langs, LanguageControls, MuiBox, NChoice, NumberTextField$1 as NumberTextField, numberTextFieldCustom as NumberTextFieldCustom, Tabs$1 as Tabs, index$3 as TagsInput, Toggle, twoChoice as TwoChoice, choiceUtils, buildDefaults as feedbackConfigDefaults, index$1 as layout, index as settings, withStatefulModel };
3191
+ //# sourceMappingURL=index.js.map