@pie-element/image-cloze-association 4.3.3-next.8 → 4.3.3-next.90

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. package/configure/lib/defaults.js.map +1 -1
  2. package/configure/lib/index.js.map +1 -1
  3. package/configure/lib/root.js.map +1 -1
  4. package/configure/package.json +2 -2
  5. package/configure/src/__tests__/index.test.js +12 -15
  6. package/configure/src/defaults.js +8 -8
  7. package/configure/src/index.js +4 -4
  8. package/configure/src/root.jsx +7 -20
  9. package/controller/lib/index.js.map +1 -1
  10. package/controller/lib/utils.js.map +1 -1
  11. package/controller/src/__tests__/index.test.js +34 -67
  12. package/controller/src/index.js +38 -26
  13. package/controller/src/utils.js +10 -9
  14. package/docs/config-schema.json.md +1 -1
  15. package/docs/demo/config.js +2 -2
  16. package/docs/demo/generate.js +20 -17
  17. package/docs/demo/session.js +1 -1
  18. package/docs/pie-schema.json.md +1 -1
  19. package/lib/constants.js.map +1 -1
  20. package/lib/evaluation-icon.js.map +1 -1
  21. package/lib/image-container.js.map +1 -1
  22. package/lib/image-drop-target.js.map +1 -1
  23. package/lib/index.js.map +1 -1
  24. package/lib/interactive-section.js.map +1 -1
  25. package/lib/possible-response.js.map +1 -1
  26. package/lib/possible-responses.js.map +1 -1
  27. package/lib/root.js.map +1 -1
  28. package/lib/utils-correctness.js.map +1 -1
  29. package/package.json +3 -3
  30. package/src/__tests__/image-container.test.jsx +5 -5
  31. package/src/__tests__/possible-response.test.jsx +2 -2
  32. package/src/__tests__/root.test.jsx +3 -3
  33. package/src/__tests__/utils.test.js +144 -148
  34. package/src/constants.js +3 -3
  35. package/src/evaluation-icon.jsx +8 -17
  36. package/src/image-container.jsx +11 -19
  37. package/src/image-drop-target.jsx +40 -39
  38. package/src/index.js +5 -18
  39. package/src/interactive-section.jsx +15 -22
  40. package/src/possible-response.jsx +30 -23
  41. package/src/possible-responses.jsx +17 -25
  42. package/src/root.jsx +29 -69
  43. package/src/utils-correctness.js +31 -23
@@ -5,25 +5,25 @@ const trapeze = 'trapeze';
5
5
  const hexagon = 'hexagon';
6
6
 
7
7
  const answer1 = {
8
- containerIndex: 0,
9
- id: 1,
10
- value: rhomb
8
+ containerIndex: 0,
9
+ id: 1,
10
+ value: rhomb,
11
11
  };
12
12
  const answer2 = {
13
- containerIndex: 0,
14
- id: 2,
15
- value: rhomb
13
+ containerIndex: 0,
14
+ id: 2,
15
+ value: rhomb,
16
16
  };
17
17
  const answer3 = {
18
- containerIndex: 0,
19
- id: 3,
20
- value: trapeze
18
+ containerIndex: 0,
19
+ id: 3,
20
+ value: trapeze,
21
21
  };
22
22
 
23
23
  const answer4 = {
24
- containerIndex: 1,
25
- id: 4,
26
- value: hexagon,
24
+ containerIndex: 1,
25
+ id: 4,
26
+ value: hexagon,
27
27
  };
28
28
 
29
29
  describe('utils', () => {
@@ -32,178 +32,174 @@ describe('utils', () => {
32
32
  beforeEach(() => {
33
33
  validResponses = {
34
34
  validResponse: {
35
- value: [
36
- { images: [rhomb] },
37
- { images: [rhomb, trapeze] }
38
- ]
39
- }
35
+ value: [{ images: [rhomb] }, { images: [rhomb, trapeze] }],
36
+ },
40
37
  };
41
38
  });
42
39
 
43
40
  describe('correctness', () => {
44
41
  it('marks correct answers as correct', () => {
45
42
  const result = getAnswersCorrectness(
46
- [answer1, {
47
- ...answer3,
48
- containerIndex: 1
49
- }],
50
- validResponses
43
+ [
44
+ answer1,
45
+ {
46
+ ...answer3,
47
+ containerIndex: 1,
48
+ },
49
+ ],
50
+ validResponses,
51
51
  );
52
- expect(result).toEqual([{
53
- ...answer1,
54
- isCorrect: true
55
- },{
56
- ...answer3,
57
- isCorrect: true,
58
- containerIndex: 1
59
- }]);
52
+ expect(result).toEqual([
53
+ {
54
+ ...answer1,
55
+ isCorrect: true,
56
+ },
57
+ {
58
+ ...answer3,
59
+ isCorrect: true,
60
+ containerIndex: 1,
61
+ },
62
+ ]);
60
63
  });
61
64
 
62
65
  it('marks incorrect answers as incorrect', () => {
63
- const result = getAnswersCorrectness(
64
- [answer1, answer3],
65
- validResponses
66
- );
67
- expect(result).toEqual([{
68
- ...answer1,
69
- isCorrect: true
70
- },{
71
- ...answer3,
72
- isCorrect: false
73
- }]);
66
+ const result = getAnswersCorrectness([answer1, answer3], validResponses);
67
+ expect(result).toEqual([
68
+ {
69
+ ...answer1,
70
+ isCorrect: true,
71
+ },
72
+ {
73
+ ...answer3,
74
+ isCorrect: false,
75
+ },
76
+ ]);
74
77
  });
75
78
 
76
79
  it('marks duplicates as incorrect', () => {
77
- const result = getAnswersCorrectness(
78
- [answer1, answer2],
79
- validResponses
80
- );
81
- expect(result).toEqual([{
82
- ...answer1,
83
- isCorrect: true
84
- },{
85
- ...answer2,
86
- isCorrect: false
87
- }]);
80
+ const result = getAnswersCorrectness([answer1, answer2], validResponses);
81
+ expect(result).toEqual([
82
+ {
83
+ ...answer1,
84
+ isCorrect: true,
85
+ },
86
+ {
87
+ ...answer2,
88
+ isCorrect: false,
89
+ },
90
+ ]);
88
91
  });
89
92
 
90
93
  it('marks duplicates and incorrect as incorrect', () => {
91
- const result = getAnswersCorrectness(
92
- [answer1, answer2, answer3],
93
- validResponses
94
- );
95
- expect(result).toEqual([{
96
- ...answer1,
97
- isCorrect: true
98
- },{
99
- ...answer2,
100
- isCorrect: false
101
- },{
102
- ...answer3,
103
- isCorrect: false
104
- }]);
94
+ const result = getAnswersCorrectness([answer1, answer2, answer3], validResponses);
95
+ expect(result).toEqual([
96
+ {
97
+ ...answer1,
98
+ isCorrect: true,
99
+ },
100
+ {
101
+ ...answer2,
102
+ isCorrect: false,
103
+ },
104
+ {
105
+ ...answer3,
106
+ isCorrect: false,
107
+ },
108
+ ]);
105
109
  });
106
110
 
107
111
  describe('alternate correct answers', () => {
108
112
  describe('handles one option', () => {
109
113
  it('marks correct answers as correct', () => {
110
- const result = getAnswersCorrectness(
111
- [answer1, answer4],
114
+ const result = getAnswersCorrectness([answer1, answer4], {
115
+ ...validResponses,
116
+ altResponses: [
117
+ {
118
+ value: [{ images: [rhomb] }, { images: [hexagon] }],
119
+ },
120
+ ],
121
+ });
122
+ expect(result).toEqual([
123
+ {
124
+ ...answer1,
125
+ isCorrect: true,
126
+ },
112
127
  {
113
- ...validResponses,
114
- altResponses: [{
115
- value: [
116
- { images: [rhomb] },
117
- { images: [hexagon] }
118
- ]
119
- }]
120
- }
121
- );
122
- expect(result).toEqual([{
123
- ...answer1,
124
- isCorrect: true
125
- },{
126
- ...answer4,
127
- isCorrect: true
128
- }]);
128
+ ...answer4,
129
+ isCorrect: true,
130
+ },
131
+ ]);
129
132
  });
130
133
 
131
134
  it('marks incorrect answers as incorrect', () => {
132
- const result = getAnswersCorrectness(
133
- [answer1, answer4],
135
+ const result = getAnswersCorrectness([answer1, answer4], {
136
+ ...validResponses,
137
+ altResponses: [
138
+ {
139
+ value: [{ images: [hexagon] }, { images: [rhomb] }],
140
+ },
141
+ ],
142
+ });
143
+ expect(result).toEqual([
134
144
  {
135
- ...validResponses,
136
- altResponses: [{
137
- value: [
138
- { images: [hexagon] },
139
- { images: [rhomb] },
140
- ]
141
- }]
142
- }
143
- );
144
- expect(result).toEqual([{
145
- ...answer1,
146
- isCorrect: false
147
- },{
148
- ...answer4,
149
- isCorrect: false
150
- }]);
145
+ ...answer1,
146
+ isCorrect: false,
147
+ },
148
+ {
149
+ ...answer4,
150
+ isCorrect: false,
151
+ },
152
+ ]);
151
153
  });
152
154
  });
153
155
 
154
156
  describe('handles multiple options', () => {
155
157
  it('marks correct answers as correct', () => {
156
- const result = getAnswersCorrectness(
157
- [answer1, answer4],
158
+ const result = getAnswersCorrectness([answer1, answer4], {
159
+ ...validResponses,
160
+ altResponses: [
161
+ {
162
+ value: [{ images: [hexagon] }, { images: [rhomb] }],
163
+ },
164
+ {
165
+ value: [{ images: [rhomb] }, { images: [hexagon] }],
166
+ },
167
+ ],
168
+ });
169
+ expect(result).toEqual([
170
+ {
171
+ ...answer1,
172
+ isCorrect: true,
173
+ },
158
174
  {
159
- ...validResponses,
160
- altResponses: [{
161
- value: [
162
- { images: [hexagon] },
163
- { images: [rhomb] },
164
- ]
165
- }, {
166
- value: [
167
- { images: [rhomb] },
168
- { images: [hexagon] },
169
- ]
170
- }]
171
- }
172
- );
173
- expect(result).toEqual([{
174
- ...answer1,
175
- isCorrect: true
176
- },{
177
- ...answer4,
178
- isCorrect: true
179
- }]);
175
+ ...answer4,
176
+ isCorrect: true,
177
+ },
178
+ ]);
180
179
  });
181
180
 
182
181
  it('marks incorrect answers as incorrect', () => {
183
- const result = getAnswersCorrectness(
184
- [answer1, answer4],
182
+ const result = getAnswersCorrectness([answer1, answer4], {
183
+ ...validResponses,
184
+ altResponses: [
185
+ {
186
+ value: [{ images: [hexagon] }, { images: [rhomb] }],
187
+ },
188
+ {
189
+ value: [{ images: [hexagon] }, { images: [hexagon] }],
190
+ },
191
+ ],
192
+ });
193
+ expect(result).toEqual([
194
+ {
195
+ ...answer1,
196
+ isCorrect: false,
197
+ },
185
198
  {
186
- ...validResponses,
187
- altResponses: [{
188
- value: [
189
- { images: [hexagon] },
190
- { images: [rhomb] },
191
- ]
192
- }, {
193
- value: [
194
- { images: [hexagon] },
195
- { images: [hexagon] },
196
- ]
197
- }]
198
- }
199
- );
200
- expect(result).toEqual([{
201
- ...answer1,
202
- isCorrect: false
203
- },{
204
- ...answer4,
205
- isCorrect: true
206
- }]);
199
+ ...answer4,
200
+ isCorrect: true,
201
+ },
202
+ ]);
207
203
  });
208
204
  });
209
205
  });
package/src/constants.js CHANGED
@@ -1,5 +1,5 @@
1
1
  export default {
2
2
  types: {
3
- response: 'react-dnd-response'
4
- }
5
- }
3
+ response: 'react-dnd-response',
4
+ },
5
+ };
@@ -17,47 +17,38 @@ const EvaluationIcon = ({ classes, containerStyle, isCorrect, filled }) => {
17
17
  const showCorrectness = isCorrect !== undefined;
18
18
  const correctness = showCorrectness ? getCorrectnessClass(isCorrect, filled) : '';
19
19
 
20
- return showCorrectness
21
- ? (
22
- <Icon
23
- className={`${classes.icon} ${classes[correctness]}`}
24
- style={containerStyle}
25
- />
26
- ) : null
20
+ return showCorrectness ? <Icon className={`${classes.icon} ${classes[correctness]}`} style={containerStyle} /> : null;
27
21
  };
28
22
 
29
23
  EvaluationIcon.propTypes = {
30
24
  classes: PropTypes.object,
31
25
  containerStyle: PropTypes.object,
32
26
  filled: PropTypes.bool,
33
- isCorrect: PropTypes.oneOfType([
34
- PropTypes.bool,
35
- PropTypes.number
36
- ])
27
+ isCorrect: PropTypes.oneOfType([PropTypes.bool, PropTypes.number]),
37
28
  };
38
29
 
39
30
  EvaluationIcon.defaultProps = {
40
31
  classes: {},
41
32
  containerStyle: {},
42
33
  filled: false,
43
- isCorrect: undefined
34
+ isCorrect: undefined,
44
35
  };
45
36
 
46
37
  const styles = () => ({
47
38
  correctEmpty: {
48
- color: color.correct()
39
+ color: color.correct(),
49
40
  },
50
41
  correctFilled: {
51
42
  color: color.background(),
52
- backgroundColor: color.correct()
43
+ backgroundColor: color.correct(),
53
44
  },
54
45
  incorrectEmpty: {
55
- color: color.incorrect()
46
+ color: color.incorrect(),
56
47
  },
57
48
  incorrectFilled: {
58
49
  color: color.background(),
59
- backgroundColor: color.incorrect()
60
- }
50
+ backgroundColor: color.incorrect(),
51
+ },
61
52
  });
62
53
 
63
54
  export default withStyles(styles)(EvaluationIcon);
@@ -12,31 +12,23 @@ class ImageContainer extends Component {
12
12
  classes,
13
13
  draggingElement,
14
14
  duplicateResponses,
15
- image: {
16
- height,
17
- src,
18
- width
19
- },
15
+ image: { height, src, width },
20
16
  onAnswerSelect,
21
17
  onDragAnswerBegin,
22
18
  onDragAnswerEnd,
23
19
  responseContainers,
24
- showDashedBorder
20
+ showDashedBorder,
25
21
  } = this.props;
26
22
 
27
23
  return (
28
24
  <div className={classes.base}>
29
- <img
30
- src={src}
31
- height={height}
32
- width={width}
33
- />
25
+ <img src={src} height={height} width={width} />
34
26
  {responseContainers.map((r, i) => {
35
27
  const rHeight = (r.height.replace('%', '') / 100) * height;
36
28
  const rWidth = (r.width.replace('%', '') / 100) * width;
37
29
  const rLeft = (r.x / 100) * width;
38
30
  const rTop = (r.y / 100) * height;
39
- const answersParsed = answers.filter(a => a.containerIndex === r.index);
31
+ const answersParsed = answers.filter((a) => a.containerIndex === r.index);
40
32
 
41
33
  return (
42
34
  <ImageDropTarget
@@ -46,7 +38,7 @@ class ImageContainer extends Component {
46
38
  height: rHeight,
47
39
  width: rWidth,
48
40
  left: rLeft,
49
- top: rTop
41
+ top: rTop,
50
42
  }}
51
43
  duplicateResponses={duplicateResponses}
52
44
  key={r.id + i}
@@ -59,7 +51,7 @@ class ImageContainer extends Component {
59
51
  );
60
52
  })}
61
53
  </div>
62
- )
54
+ );
63
55
  }
64
56
  }
65
57
 
@@ -74,18 +66,18 @@ ImageContainer.propTypes = {
74
66
  onDragAnswerBegin: PropTypes.func.isRequired,
75
67
  onDragAnswerEnd: PropTypes.func.isRequired,
76
68
  responseContainers: PropTypes.array.isRequired,
77
- showDashedBorder: PropTypes.bool
69
+ showDashedBorder: PropTypes.bool,
78
70
  };
79
71
 
80
72
  ImageContainer.defaultProps = {
81
73
  classes: {},
82
- duplicateResponses: false
74
+ duplicateResponses: false,
83
75
  };
84
76
 
85
- const styles = theme => ({
77
+ const styles = (theme) => ({
86
78
  base: {
87
79
  margin: theme.spacing.unit * 2,
88
- position: 'relative'
89
- }
80
+ position: 'relative',
81
+ },
90
82
  });
91
83
  export default withStyles(styles)(ImageContainer);
@@ -19,40 +19,41 @@ const ImageDropTarget = ({
19
19
  showDashedBorder,
20
20
  // dnd-related props
21
21
  connectDropTarget,
22
- isOverCurrent
23
- }) => connectDropTarget(
24
- <div
25
- className={`
22
+ isOverCurrent,
23
+ }) =>
24
+ connectDropTarget(
25
+ <div
26
+ className={`
26
27
  ${classes.responseContainer}
27
28
  ${showDashedBorder && !draggingElement.id ? classes.responseContainerDashed : ''}
28
29
  ${draggingElement.id ? classes.responseContainerActive : ''}
29
30
  `}
30
- style={containerStyle}
31
- >
32
- {/* HOVER */}
33
- {isOverCurrent && !duplicateResponses ? (
34
- <div className={classes.dragOverContainer}>
35
- <span dangerouslySetInnerHTML={{ __html: draggingElement.value }} />
36
- </div>
37
- ) : null}
31
+ style={containerStyle}
32
+ >
33
+ {/* HOVER */}
34
+ {isOverCurrent && !duplicateResponses ? (
35
+ <div className={classes.dragOverContainer}>
36
+ <span dangerouslySetInnerHTML={{ __html: draggingElement.value }} />
37
+ </div>
38
+ ) : null}
38
39
 
39
- {/* EXISTING ANSWERS */}
40
- {(!isOverCurrent && answers.length) || (duplicateResponses && answers.length) ? (
41
- <div className={classes.answers}>
42
- {answers.map(answer => (
43
- <PossibleResponse
44
- canDrag={canDrag}
45
- containerStyle={answer.isCorrect === undefined ? { borderWidth: 0 } : {}}
46
- key={answer.id}
47
- data={answer}
48
- onDragBegin={() => onDragAnswerBegin(answer)}
49
- onDragEnd={onDragAnswerEnd}
50
- />
51
- ))}
52
- </div>
53
- ) : null}
54
- </div>
55
- );
40
+ {/* EXISTING ANSWERS */}
41
+ {(!isOverCurrent && answers.length) || (duplicateResponses && answers.length) ? (
42
+ <div className={classes.answers}>
43
+ {answers.map((answer) => (
44
+ <PossibleResponse
45
+ canDrag={canDrag}
46
+ containerStyle={answer.isCorrect === undefined ? { borderWidth: 0 } : {}}
47
+ key={answer.id}
48
+ data={answer}
49
+ onDragBegin={() => onDragAnswerBegin(answer)}
50
+ onDragEnd={onDragAnswerEnd}
51
+ />
52
+ ))}
53
+ </div>
54
+ ) : null}
55
+ </div>,
56
+ );
56
57
 
57
58
  ImageDropTarget.propTypes = {
58
59
  answer: PropTypes.object,
@@ -63,34 +64,34 @@ ImageDropTarget.propTypes = {
63
64
  onDragAnswerBegin: PropTypes.func.isRequired,
64
65
  onDragAnswerEnd: PropTypes.func.isRequired,
65
66
  onDrop: PropTypes.func.isRequired,
66
- showDashedBorder: PropTypes.bool
67
+ showDashedBorder: PropTypes.bool,
67
68
  };
68
69
 
69
70
  ImageDropTarget.defaultProps = {
70
71
  answer: {},
71
- classes: {}
72
+ classes: {},
72
73
  };
73
74
 
74
75
  const styles = () => ({
75
76
  answers: {
76
77
  display: 'flex',
77
- flexWrap: 'wrap'
78
+ flexWrap: 'wrap',
78
79
  },
79
80
  dragOverContainer: {
80
81
  backgroundColor: color.background(),
81
82
  pointerEvents: 'none',
82
- width: 'fit-content'
83
+ width: 'fit-content',
83
84
  },
84
85
  responseContainer: {
85
- position: 'absolute'
86
+ position: 'absolute',
86
87
  },
87
88
  responseContainerActive: {
88
89
  border: `2px solid ${color.text()}`,
89
- backgroundColor: 'rgba(230, 242, 252, .8)'
90
+ backgroundColor: 'rgba(230, 242, 252, .8)',
90
91
  },
91
92
  responseContainerDashed: {
92
- border: `2px dashed ${color.text()}`
93
- }
93
+ border: `2px dashed ${color.text()}`,
94
+ },
94
95
  });
95
96
 
96
97
  const Styled = withStyles(styles)(ImageDropTarget);
@@ -102,10 +103,10 @@ const tileSource = {
102
103
  drop(props, monitor) {
103
104
  const item = monitor.getItem();
104
105
  props.onDrop(item);
105
- }
106
+ },
106
107
  };
107
108
 
108
109
  export default DropTarget(c.types.response, tileSource, (connect, monitor) => ({
109
110
  connectDropTarget: connect.dropTarget(),
110
- isOverCurrent: monitor.isOver({ shallow: true })
111
+ isOverCurrent: monitor.isOver({ shallow: true }),
111
112
  }))(Styled);
package/src/index.js CHANGED
@@ -1,10 +1,7 @@
1
1
  import React from 'react';
2
2
  import ReactDOM from 'react-dom';
3
3
  import { renderMath } from '@pie-lib/math-rendering';
4
- import {
5
- ModelSetEvent,
6
- SessionChangedEvent
7
- } from '@pie-framework/pie-player-events';
4
+ import { ModelSetEvent, SessionChangedEvent } from '@pie-framework/pie-player-events';
8
5
 
9
6
  import ImageClozeAssociationComponent from './root';
10
7
 
@@ -12,13 +9,7 @@ export default class ImageClozeAssociation extends HTMLElement {
12
9
  set model(m) {
13
10
  this._model = m;
14
11
 
15
- this.dispatchEvent(
16
- new ModelSetEvent(
17
- this.tagName.toLowerCase(),
18
- this.isComplete(),
19
- !!this._model
20
- )
21
- );
12
+ this.dispatchEvent(new ModelSetEvent(this.tagName.toLowerCase(), this.isComplete(), !!this._model));
22
13
  this._render();
23
14
  }
24
15
 
@@ -27,9 +18,7 @@ export default class ImageClozeAssociation extends HTMLElement {
27
18
  return false;
28
19
  }
29
20
 
30
- return (
31
- Array.isArray(this._session.answers) && this._session.answers.length > 0
32
- );
21
+ return Array.isArray(this._session.answers) && this._session.answers.length > 0;
33
22
  }
34
23
 
35
24
  set session(s) {
@@ -48,9 +37,7 @@ export default class ImageClozeAssociation extends HTMLElement {
48
37
  updateAnswer(data) {
49
38
  this._session.answers = data;
50
39
 
51
- this.dispatchEvent(
52
- new SessionChangedEvent(this.tagName.toLowerCase(), this.isComplete())
53
- );
40
+ this.dispatchEvent(new SessionChangedEvent(this.tagName.toLowerCase(), this.isComplete()));
54
41
 
55
42
  this._render();
56
43
  }
@@ -64,7 +51,7 @@ export default class ImageClozeAssociation extends HTMLElement {
64
51
  const el = React.createElement(ImageClozeAssociationComponent, {
65
52
  model: this._model,
66
53
  session: this._session,
67
- updateAnswer: this.updateAnswer.bind(this)
54
+ updateAnswer: this.updateAnswer.bind(this),
68
55
  });
69
56
 
70
57
  ReactDOM.render(el, this, () => {