@pie-lib/rubric 0.26.0 → 0.28.0-mui-update.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/src/authoring.jsx CHANGED
@@ -1,27 +1,26 @@
1
1
  import React from 'react';
2
2
  import PropTypes from 'prop-types';
3
- import { withStyles } from '@material-ui/core/styles';
4
- import classNames from 'classnames';
5
- import OutlinedInput from '@material-ui/core/OutlinedInput';
6
- import InputLabel from '@material-ui/core/InputLabel';
7
- import Select from '@material-ui/core/Select';
8
- import FormControl from '@material-ui/core/FormControl';
9
- import MenuItem from '@material-ui/core/MenuItem';
3
+ import { styled } from '@mui/material/styles';
4
+
5
+ import InputLabel from '@mui/material/InputLabel';
6
+ import OutlinedInput from '@mui/material/OutlinedInput';
7
+ import Select from '@mui/material/Select';
8
+ import FormControl from '@mui/material/FormControl';
9
+ import MenuItem from '@mui/material/MenuItem';
10
10
  import times from 'lodash/times';
11
- import Checkbox from '@material-ui/core/Checkbox';
12
- import FormGroup from '@material-ui/core/FormGroup';
13
- import FormControlLabel from '@material-ui/core/FormControlLabel';
14
- import grey from '@material-ui/core/colors/grey';
15
- import Typography from '@material-ui/core/Typography';
16
- import DragIndicator from '@material-ui/icons/DragIndicator';
17
- import EditableHtml from '@pie-lib/editable-html';
18
- import { DragDropContext, Droppable, Draggable } from 'react-beautiful-dnd';
11
+ import Checkbox from '@mui/material/Checkbox';
12
+ import FormGroup from '@mui/material/FormGroup';
13
+ import FormControlLabel from '@mui/material/FormControlLabel';
14
+ import Typography from '@mui/material/Typography';
15
+ import DragIndicator from '@mui/icons-material/DragIndicator';
16
+ import { DragDropContext, Droppable, Draggable } from '@hello-pangea/dnd';
19
17
  import debug from 'debug';
20
18
  import takeRight from 'lodash/takeRight';
21
19
  import PointMenu from './point-menu';
22
-
23
20
  import range from 'lodash/range';
21
+ import EditableHtml from '@pie-lib/editable-html';
24
22
  import { InputContainer } from '@pie-lib/config-ui';
23
+ import { grey } from '@mui/material/colors';
25
24
 
26
25
  const log = debug('pie-lib:rubric:authoring');
27
26
 
@@ -42,20 +41,20 @@ export const RubricType = PropTypes.shape({
42
41
  rubriclessInstruction: PropTypes.string,
43
42
  });
44
43
 
45
- const MaxPoints = withStyles((theme) => ({
46
- formControl: {
47
- minWidth: '120px',
48
- margin: theme.spacing.unit,
49
- },
50
- }))((props) => {
51
- const { value, onChange, max, classes } = props;
44
+ const MaxPoints = (props) => {
45
+ const { value, onChange, max } = props;
46
+ const labelId = 'max-points-label';
52
47
 
53
48
  return (
54
- <FormControl className={classes.formControl} variant="outlined">
55
- <InputLabel width={100} htmlFor="...">
56
- Max Points
57
- </InputLabel>
58
- <Select value={value} onChange={(e) => onChange(e.target.value)} input={<OutlinedInput labelWidth={80} />}>
49
+ <FormControl sx={{ minWidth: 120, m: 1 }} variant="outlined">
50
+ <InputLabel id={labelId}>Max Points</InputLabel>
51
+ <Select
52
+ labelId={labelId}
53
+ label="Max Points"
54
+ value={value}
55
+ onChange={(e) => onChange(e.target.value)}
56
+ input={<OutlinedInput label="Max Points" />}
57
+ >
59
58
  {range(1, max + 1).map((v) => (
60
59
  <MenuItem key={`${v}`} value={v}>
61
60
  {v}
@@ -64,96 +63,79 @@ const MaxPoints = withStyles((theme) => ({
64
63
  </Select>
65
64
  </FormControl>
66
65
  );
67
- });
66
+ };
68
67
 
69
68
  // if the value is null or 'null', the Sample Answer input field for that point will not be dispalyed
70
69
  // if the value is '', the Sample Answer input field will be empty
71
70
  const checkSampleAnswer = (sampleAnswer) => sampleAnswer === null || sampleAnswer === 'null';
72
71
 
73
- export const PointConfig = withStyles((theme) => ({
74
- pointConfig: {},
75
- row: {
76
- display: 'flex',
77
- width: '100%',
78
- position: 'relative',
79
- },
80
- editor: {
81
- width: '100%',
82
- backgroundColor: `${theme.palette.common.white} !important`,
83
- },
84
- dragIndicator: {
85
- paddingTop: theme.spacing.unit,
86
- color: grey[500],
87
- },
88
- pointsLabel: {
89
- color: grey[500],
90
- paddingBottom: theme.spacing.unit,
91
- textTransform: 'uppercase',
92
- },
93
- sampleAnswersEditor: {
94
- paddingLeft: theme.spacing.unit * 3,
95
- },
96
- pointMenu: {
97
- position: 'absolute',
98
- right: 0,
99
- },
100
- errorText: {
101
- fontSize: theme.typography.fontSize - 2,
102
- color: theme.palette.error.main,
103
- paddingLeft: theme.spacing.unit * 3,
104
- paddingTop: theme.spacing.unit,
105
- },
106
- }))((props) => {
107
- const { points, content, classes, sampleAnswer, mathMlOptions = {}, error, pluginOpts = {} } = props;
72
+ const PCContainer = styled('div')(() => ({}));
73
+ const Row = styled('div')(() => ({ display: 'flex', width: '100%', position: 'relative' }));
74
+ const EditorDiv = styled('div')(({ theme }) => ({ width: '100%', backgroundColor: `${theme.palette.common.white}` }));
75
+ const DragIndicatorStyled = styled(DragIndicator)(({ theme }) => ({ paddingTop: theme.spacing(1), color: grey[500] }));
76
+ const PointsLabel = styled(Typography)(({ theme }) => ({ color: grey[500], paddingBottom: theme.spacing(1), textTransform: 'uppercase' }));
77
+ const SampleAnswersEditor = styled('div')(({ theme }) => ({ paddingLeft: theme.spacing(3) }));
78
+ const ErrorText = styled('div')(({ theme }) => ({ fontSize: theme.typography.fontSize - 2, color: theme.palette.error.main, paddingLeft: theme.spacing(3), paddingTop: theme.spacing(1) }));
79
+ const PointMenuWrapper = styled('div')(() => ({ position: 'absolute', right: 0 }));
80
+
81
+ export const PointConfig = (props) => {
82
+ const { points, content, sampleAnswer, mathMlOptions = {}, error, pluginOpts = {} } = props;
108
83
  const pointsLabel = `${points} ${points <= 1 ? 'pt' : 'pts'}`;
109
84
  const showSampleAnswer = checkSampleAnswer(sampleAnswer);
110
85
 
111
86
  return (
112
- <div className={classes.pointConfig}>
113
- <Typography variant="overline" className={classes.pointsLabel}>
114
- {pointsLabel}
115
- </Typography>
116
-
117
- <div className={classes.row}>
118
- <DragIndicator className={classes.dragIndicator} />
119
- <EditableHtml
120
- className={classes.editor}
121
- error={error}
122
- pluginProps={pluginOpts}
123
- markup={content}
124
- onChange={props.onChange}
125
- mathMlOptions={mathMlOptions}
126
- />
127
- <PointMenu
128
- classes={{
129
- icon: classes.pointMenu,
130
- }}
131
- showSampleAnswer={showSampleAnswer}
132
- onChange={props.onMenuChange}
133
- />
134
- </div>
135
- {error && <div className={classes.errorText}>{error}</div>}
136
- {!showSampleAnswer && (
137
- <div className={classes.sampleAnswersEditor}>
138
- <Typography variant="overline" className={classes.dragIndicator}>
139
- Sample Response
140
- </Typography>
87
+ <PCContainer>
88
+ <PointsLabel variant="overline">{pointsLabel}</PointsLabel>
89
+ <Row>
90
+ <DragIndicatorStyled />
91
+ <EditorDiv>
141
92
  <EditableHtml
142
- className={classes.editor}
143
- markup={sampleAnswer}
93
+ error={error}
144
94
  pluginProps={pluginOpts}
145
- onChange={props.onSampleChange}
95
+ markup={content}
96
+ onChange={props.onChange}
146
97
  mathMlOptions={mathMlOptions}
147
98
  />
148
- </div>
99
+ </EditorDiv>
100
+ <PointMenuWrapper>
101
+ <PointMenu showSampleAnswer={showSampleAnswer} onChange={props.onMenuChange} />
102
+ </PointMenuWrapper>
103
+ </Row>
104
+ {error && <ErrorText>{error}</ErrorText>}
105
+ {!showSampleAnswer && (
106
+ <SampleAnswersEditor>
107
+ <DragIndicatorStyled as={Typography} variant="overline">
108
+ Sample Response
109
+ </DragIndicatorStyled>
110
+ <EditorDiv>
111
+ <EditableHtml
112
+ markup={sampleAnswer}
113
+ pluginProps={pluginOpts}
114
+ onChange={props.onSampleChange}
115
+ mathMlOptions={mathMlOptions}
116
+ />
117
+ </EditorDiv>
118
+ </SampleAnswersEditor>
149
119
  )}
150
- </div>
120
+ </PCContainer>
151
121
  );
152
- });
122
+ };
123
+
124
+ const Container = styled('div')(({ theme }) => ({
125
+ backgroundColor: grey[200],
126
+ borderWidth: 1,
127
+ borderStyle: 'solid',
128
+ borderColor: grey[300],
129
+ padding: theme.spacing(2),
130
+ margin: theme.spacing(1),
131
+ }));
132
+ const InputContainerWrapper = styled('div')(({ theme }) => ({ width: '100%', paddingTop: theme.spacing(2), marginBottom: theme.spacing(2) }));
133
+ const Rubricless = styled('div')(() => ({ display: 'none' }));
134
+ const ConfigHolder = styled('div')(({ theme }) => ({ paddingTop: theme.spacing(1), paddingBottom: theme.spacing(1) }));
135
+ const RubricTitle = styled(Typography)(({ theme }) => ({ paddingLeft: theme.spacing(1), margin: theme.spacing(1) }));
153
136
 
154
137
  export class RawAuthoring extends React.Component {
155
138
  static propTypes = {
156
- classes: PropTypes.object.isRequired,
157
139
  className: PropTypes.string,
158
140
  value: RubricType,
159
141
  config: PropTypes.object,
@@ -265,7 +247,6 @@ export class RawAuthoring extends React.Component {
265
247
 
266
248
  render() {
267
249
  const {
268
- classes,
269
250
  className,
270
251
  value,
271
252
  mathMlOptions = {},
@@ -292,10 +273,10 @@ export class RawAuthoring extends React.Component {
292
273
  const maxPointsValue = !rubricless ? value.points.length - 1 : maxPoints;
293
274
 
294
275
  return (
295
- <div className={classNames(classes.class, className)}>
296
- <Typography variant="h5" className={classes.rubricTitle}>
276
+ <div className={className}>
277
+ <RubricTitle variant="h5">
297
278
  Rubric
298
- </Typography>
279
+ </RubricTitle>
299
280
  <FormGroup row>
300
281
  {maxPointsEnabled && (
301
282
  <MaxPoints
@@ -314,93 +295,72 @@ export class RawAuthoring extends React.Component {
314
295
  </FormGroup>
315
296
 
316
297
  {rubriclessInstructionEnabled && rubricless && (
317
- <InputContainer label={rubriclessInstruction.label} className={classes.inputContainer}>
318
- <EditableHtml
319
- className={classes.input}
320
- markup={value.rubriclessInstruction || ''}
321
- onChange={this.changeRubriclessInstruction}
322
- pluginProps={pluginOpts}
323
- nonEmpty={false}
324
- disableUnderline
325
- languageCharactersProps={[{ language: 'spanish' }, { language: 'special' }]}
326
- mathMlOptions={mathMlOptions}
327
- />
328
- </InputContainer>
298
+ <InputContainerWrapper>
299
+ <InputContainer label={rubriclessInstruction.label}>
300
+ <EditableHtml
301
+ markup={value.rubriclessInstruction || ''}
302
+ onChange={this.changeRubriclessInstruction}
303
+ pluginProps={pluginOpts}
304
+ nonEmpty={false}
305
+ disableUnderline
306
+ languageCharactersProps={[{ language: 'spanish' }, { language: 'special' }]}
307
+ mathMlOptions={mathMlOptions}
308
+ />
309
+ </InputContainer>
310
+ </InputContainerWrapper>
329
311
  )}
330
312
 
331
- <div className={rubricless ? classes.rubricless : classes.container}>
332
- <DragDropContext onDragEnd={this.dragEnd}>
333
- <Droppable droppableId="droppable">
334
- {(provided) => (
335
- <div {...provided.droppableProps} ref={provided.innerRef}>
336
- {value.points.map(
337
- (p, index) =>
338
- this.shouldRenderPoint(index, value) && (
339
- <Draggable key={`${p.points}-${index}`} index={index} draggableId={index.toString()}>
340
- {(provided) => (
341
- <div
342
- className={classes.configHolder}
343
- ref={provided.innerRef}
344
- {...provided.draggableProps}
345
- {...provided.dragHandleProps}
346
- >
347
- <PointConfig
348
- points={value.points.length - 1 - index}
349
- content={p}
350
- error={
351
- pointsDescriptorsErrors && pointsDescriptorsErrors[value.points.length - 1 - index]
352
- }
353
- sampleAnswer={value.sampleAnswers && value.sampleAnswers[index]}
354
- onChange={(content) => this.changeContent(index, content, 'points')}
355
- onSampleChange={(content) => this.changeContent(index, content, 'sampleAnswers')}
356
- onMenuChange={(clickedItem) => this.onPointMenuChange(index, clickedItem)}
357
- mathMlOptions={mathMlOptions}
358
- pluginOpts={pluginOpts}
359
- />
360
- </div>
361
- )}
362
- </Draggable>
363
- ),
313
+ <div className={rubricless ? undefined : undefined}>
314
+ {rubricless ? (
315
+ <Rubricless />
316
+ ) : (
317
+ <Container>
318
+ <DragDropContext onDragEnd={this.dragEnd}>
319
+ <Droppable droppableId="droppable">
320
+ {(provided) => (
321
+ <div {...provided.droppableProps} ref={provided.innerRef}>
322
+ {value.points.map(
323
+ (p, index) =>
324
+ this.shouldRenderPoint(index, value) && (
325
+ <Draggable key={`${p.points}-${index}`} index={index} draggableId={index.toString()}>
326
+ {(provided) => (
327
+ <ConfigHolder
328
+ ref={provided.innerRef}
329
+ {...provided.draggableProps}
330
+ {...provided.dragHandleProps}
331
+ >
332
+ <PointConfig
333
+ points={value.points.length - 1 - index}
334
+ content={p}
335
+ error={
336
+ pointsDescriptorsErrors && pointsDescriptorsErrors[value.points.length - 1 - index]
337
+ }
338
+ sampleAnswer={value.sampleAnswers && value.sampleAnswers[index]}
339
+ onChange={(content) => this.changeContent(index, content, 'points')}
340
+ onSampleChange={(content) => this.changeContent(index, content, 'sampleAnswers')}
341
+ onMenuChange={(clickedItem) => this.onPointMenuChange(index, clickedItem)}
342
+ mathMlOptions={mathMlOptions}
343
+ pluginOpts={pluginOpts}
344
+ />
345
+ </ConfigHolder>
346
+ )}
347
+ </Draggable>
348
+ ),
349
+ )}
350
+ {provided.placeholder}
351
+ </div>
364
352
  )}
365
- {provided.placeholder}
366
- </div>
367
- )}
368
- </Droppable>
369
- </DragDropContext>
353
+ </Droppable>
354
+ </DragDropContext>
355
+ </Container>
356
+ )}
370
357
  </div>
371
358
  </div>
372
359
  );
373
360
  }
374
361
  }
375
362
 
376
- const styles = (theme) => ({
377
- container: {
378
- backgroundColor: grey[200],
379
- borderWidth: 1,
380
- borderStyle: 'solid',
381
- borderColor: grey[300],
382
- padding: theme.spacing.unit * 2,
383
- margin: theme.spacing.unit,
384
- },
385
- inputContainer: {
386
- width: '100%',
387
- paddingTop: theme.spacing.unit * 2,
388
- marginBottom: theme.spacing.unit * 2,
389
- },
390
- rubricless: {
391
- display: 'none',
392
- },
393
- configHolder: {
394
- paddingTop: theme.spacing.unit,
395
- paddingBottom: theme.spacing.unit,
396
- },
397
- rubricTitle: {
398
- paddingLeft: theme.spacing.unit,
399
- margin: theme.spacing.unit,
400
- },
401
- });
402
-
403
- const StyledRawAuthoring = withStyles(styles)(RawAuthoring);
363
+ // styles migrated to styled-components above
404
364
 
405
365
  const Reverse = (props) => {
406
366
  const { rubricless = false, config = {}, pluginOpts = {} } = props || {};
@@ -424,7 +384,7 @@ const Reverse = (props) => {
424
384
  };
425
385
 
426
386
  return (
427
- <StyledRawAuthoring
387
+ <RawAuthoring
428
388
  value={value}
429
389
  config={config}
430
390
  onChange={onChange}
@@ -1,8 +1,8 @@
1
- import Menu from '@material-ui/core/Menu';
2
- import MenuItem from '@material-ui/core/MenuItem';
3
- import MoreVertIcon from '@material-ui/icons/MoreVert';
4
- import MoreHorizIcon from '@material-ui/icons/MoreHoriz';
5
- import IconButton from '@material-ui/core/IconButton';
1
+ import Menu from '@mui/material/Menu';
2
+ import MenuItem from '@mui/material/MenuItem';
3
+ import MoreVertIcon from '@mui/icons-material/MoreVert';
4
+ import MoreHorizIcon from '@mui/icons-material/MoreHoriz';
5
+ import IconButton from '@mui/material/IconButton';
6
6
  import PropTypes from 'prop-types';
7
7
  import React from 'react';
8
8
 
@@ -10,7 +10,7 @@ export class IconMenu extends React.Component {
10
10
  static propTypes = {
11
11
  opts: PropTypes.object,
12
12
  onClick: PropTypes.func.isRequired,
13
- classes: PropTypes.object.isRequired,
13
+ classes: PropTypes.object,
14
14
  };
15
15
 
16
16
  constructor(props) {
@@ -26,7 +26,7 @@ export class IconMenu extends React.Component {
26
26
  handleRequestClose = () => this.setState({ open: false });
27
27
 
28
28
  render() {
29
- const { opts, onClick, classes } = this.props;
29
+ const { opts, onClick, classes = {} } = this.props;
30
30
  const { open, anchorEl } = this.state;
31
31
  const keys = Object.keys(opts) || [];
32
32
 
@@ -40,7 +40,7 @@ export class IconMenu extends React.Component {
40
40
  return (
41
41
  <div>
42
42
  <div onClick={this.handleClick}>
43
- <IconButton className={classes.icon}>
43
+ <IconButton className={classes.icon} size="large">
44
44
  {open ? <MoreVertIcon color={iconColor} /> : <MoreHorizIcon color={iconColor} />}
45
45
  </IconButton>
46
46
  </div>
@@ -69,7 +69,7 @@ export class IconMenu extends React.Component {
69
69
  export default class PointMenu extends React.Component {
70
70
  static propTypes = {
71
71
  onChange: PropTypes.func.isRequired,
72
- classes: PropTypes.object.isRequired,
72
+ classes: PropTypes.object,
73
73
  showSampleAnswer: PropTypes.bool.isRequired,
74
74
  };
75
75