@pie-element/hotspot 9.3.4-next.0 → 10.0.0-beta.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.
Files changed (103) hide show
  1. package/configure/lib/DeleteWidget.js +30 -43
  2. package/configure/lib/DeleteWidget.js.map +1 -1
  3. package/configure/lib/button.js +26 -45
  4. package/configure/lib/button.js.map +1 -1
  5. package/configure/lib/buttons/circle.js +20 -27
  6. package/configure/lib/buttons/circle.js.map +1 -1
  7. package/configure/lib/buttons/polygon.js +26 -33
  8. package/configure/lib/buttons/polygon.js.map +1 -1
  9. package/configure/lib/buttons/rectangle.js +26 -33
  10. package/configure/lib/buttons/rectangle.js.map +1 -1
  11. package/configure/lib/defaults.js +2 -3
  12. package/configure/lib/defaults.js.map +1 -1
  13. package/configure/lib/hotspot-circle.js +132 -198
  14. package/configure/lib/hotspot-circle.js.map +1 -1
  15. package/configure/lib/hotspot-container.js +250 -355
  16. package/configure/lib/hotspot-container.js.map +1 -1
  17. package/configure/lib/hotspot-drawable.js +360 -472
  18. package/configure/lib/hotspot-drawable.js.map +1 -1
  19. package/configure/lib/hotspot-palette.js +92 -139
  20. package/configure/lib/hotspot-palette.js.map +1 -1
  21. package/configure/lib/hotspot-polygon.js +212 -317
  22. package/configure/lib/hotspot-polygon.js.map +1 -1
  23. package/configure/lib/hotspot-rectangle.js +128 -192
  24. package/configure/lib/hotspot-rectangle.js.map +1 -1
  25. package/configure/lib/icons.js.map +1 -1
  26. package/configure/lib/image-konva.js +46 -86
  27. package/configure/lib/image-konva.js.map +1 -1
  28. package/configure/lib/index.js +162 -222
  29. package/configure/lib/index.js.map +1 -1
  30. package/configure/lib/root.js +301 -393
  31. package/configure/lib/root.js.map +1 -1
  32. package/configure/lib/shapes/circle.js +69 -101
  33. package/configure/lib/shapes/circle.js.map +1 -1
  34. package/configure/lib/shapes/index.js +4 -12
  35. package/configure/lib/shapes/index.js.map +1 -1
  36. package/configure/lib/shapes/polygon.js +64 -96
  37. package/configure/lib/shapes/polygon.js.map +1 -1
  38. package/configure/lib/shapes/rectagle.js +69 -101
  39. package/configure/lib/shapes/rectagle.js.map +1 -1
  40. package/configure/lib/shapes/utils.js +2 -8
  41. package/configure/lib/shapes/utils.js.map +1 -1
  42. package/configure/lib/upload-control.js +25 -52
  43. package/configure/lib/upload-control.js.map +1 -1
  44. package/configure/lib/utils.js +84 -137
  45. package/configure/lib/utils.js.map +1 -1
  46. package/configure/package.json +11 -10
  47. package/configure/src/__tests__/hotspot-container.test.js +50 -19
  48. package/configure/src/__tests__/hotspot-drawable.test.js +55 -34
  49. package/configure/src/__tests__/index.test.js +167 -5
  50. package/configure/src/__tests__/root.test.js +89 -63
  51. package/configure/src/button.jsx +12 -20
  52. package/configure/src/hotspot-circle.jsx +5 -18
  53. package/configure/src/hotspot-container.jsx +82 -98
  54. package/configure/src/hotspot-drawable.jsx +43 -45
  55. package/configure/src/hotspot-palette.jsx +45 -37
  56. package/configure/src/hotspot-polygon.jsx +4 -20
  57. package/configure/src/hotspot-rectangle.jsx +4 -17
  58. package/configure/src/index.js +12 -2
  59. package/configure/src/root.jsx +85 -79
  60. package/configure/src/upload-control.jsx +6 -16
  61. package/controller/lib/defaults.js +2 -3
  62. package/controller/lib/defaults.js.map +1 -1
  63. package/controller/lib/index.js +151 -205
  64. package/controller/lib/index.js.map +1 -1
  65. package/controller/lib/utils.js +14 -34
  66. package/controller/lib/utils.js.map +1 -1
  67. package/controller/package.json +2 -2
  68. package/lib/hotspot/circle.js +110 -169
  69. package/lib/hotspot/circle.js.map +1 -1
  70. package/lib/hotspot/container.js +174 -260
  71. package/lib/hotspot/container.js.map +1 -1
  72. package/lib/hotspot/icons.js.map +1 -1
  73. package/lib/hotspot/image-konva-tooltip.js +65 -112
  74. package/lib/hotspot/image-konva-tooltip.js.map +1 -1
  75. package/lib/hotspot/index.js +135 -198
  76. package/lib/hotspot/index.js.map +1 -1
  77. package/lib/hotspot/polygon.js +150 -214
  78. package/lib/hotspot/polygon.js.map +1 -1
  79. package/lib/hotspot/rectangle.js +128 -185
  80. package/lib/hotspot/rectangle.js.map +1 -1
  81. package/lib/index.js +187 -256
  82. package/lib/index.js.map +1 -1
  83. package/lib/session-updater.js +12 -18
  84. package/lib/session-updater.js.map +1 -1
  85. package/package.json +14 -11
  86. package/src/__tests__/container.test.jsx +27 -175
  87. package/src/__tests__/index.test.js +70 -30
  88. package/src/hotspot/circle.jsx +2 -13
  89. package/src/hotspot/container.jsx +35 -50
  90. package/src/hotspot/index.jsx +16 -28
  91. package/src/hotspot/polygon.jsx +4 -13
  92. package/src/hotspot/rectangle.jsx +5 -15
  93. package/src/index.js +21 -12
  94. package/configure/src/__tests__/DeleteWidget.test.js +0 -64
  95. package/configure/src/__tests__/__snapshots__/hotspot-container.test.js.snap +0 -192
  96. package/configure/src/__tests__/__snapshots__/hotspot-drawable.test.js.snap +0 -562
  97. package/configure/src/__tests__/__snapshots__/root.test.js.snap +0 -469
  98. package/src/__tests__/__snapshots__/container.test.jsx.snap +0 -264
  99. package/src/__tests__/__snapshots__/index.test.js.snap +0 -81
  100. package/src/__tests__/__snapshots__/polygon.test.jsx.snap +0 -192
  101. package/src/__tests__/__snapshots__/rectangle.test.jsx.snap +0 -127
  102. package/src/__tests__/polygon.test.jsx +0 -230
  103. package/src/__tests__/rectangle.test.jsx +0 -232
@@ -2,10 +2,20 @@ import React from 'react';
2
2
  import PropTypes from 'prop-types';
3
3
  import CorrectAnswerToggle from '@pie-lib/correct-answer-toggle';
4
4
  import { color, Collapsible, hasText, PreviewPrompt, UiLayout, hasMedia } from '@pie-lib/render-ui';
5
- import { withStyles } from '@material-ui/core/styles';
5
+ import { styled } from '@mui/material/styles';
6
6
 
7
7
  import Container from './container';
8
8
 
9
+ const StyledUiLayout = styled(UiLayout)({
10
+ color: color.text(),
11
+ backgroundColor: color.background(),
12
+ position: 'relative',
13
+ });
14
+
15
+ const StyledCollapsible = styled(Collapsible)(({ theme }) => ({
16
+ marginBottom: theme.spacing(2),
17
+ }));
18
+
9
19
  class HotspotComponent extends React.Component {
10
20
  constructor(props) {
11
21
  super(props);
@@ -81,7 +91,6 @@ class HotspotComponent extends React.Component {
81
91
  customAudioButton,
82
92
  },
83
93
  onSelectChoice,
84
- classes,
85
94
  } = this.props;
86
95
  const { showCorrect } = this.state;
87
96
  const isEvaluateMode = mode === 'evaluate';
@@ -91,19 +100,17 @@ class HotspotComponent extends React.Component {
91
100
  teacherInstructions && (hasText(teacherInstructions) || hasMedia(teacherInstructions));
92
101
 
93
102
  return (
94
- <UiLayout
103
+ <StyledUiLayout
95
104
  extraCSSRules={extraCSSRules}
96
105
  id={'main-container'}
97
- className={classes.main}
98
106
  fontSizeFactor={fontSizeFactor}
99
107
  >
100
108
  {showTeacherInstructions && (
101
- <Collapsible
109
+ <StyledCollapsible
102
110
  labels={{ hidden: 'Show Teacher Instructions', visible: 'Hide Teacher Instructions' }}
103
- className={classes.collapsible}
104
111
  >
105
112
  <PreviewPrompt className="prompt" prompt={teacherInstructions} />
106
- </Collapsible>
113
+ </StyledCollapsible>
107
114
  )}
108
115
 
109
116
  {prompt && (
@@ -149,34 +156,15 @@ class HotspotComponent extends React.Component {
149
156
  <PreviewPrompt className="prompt" prompt={rationale} />
150
157
  </Collapsible>
151
158
  )}
152
- </UiLayout>
159
+ </StyledUiLayout>
153
160
  );
154
161
  }
155
162
  }
156
163
 
157
164
  HotspotComponent.propTypes = {
158
- classes: PropTypes.object,
159
165
  model: PropTypes.object.isRequired,
160
166
  onSelectChoice: PropTypes.func.isRequired,
161
167
  session: PropTypes.object.isRequired,
162
168
  };
163
169
 
164
- HotspotComponent.defaultProps = {
165
- classes: {},
166
- };
167
-
168
- const styles = (theme) => ({
169
- main: {
170
- color: color.text(),
171
- backgroundColor: color.background(),
172
- position: 'relative',
173
- },
174
- collapsible: {
175
- marginBottom: theme.spacing.unit * 2,
176
- },
177
- prompt: {
178
- fontSize: 'inherit',
179
- },
180
- });
181
-
182
- export default withStyles(styles)(HotspotComponent);
170
+ export default HotspotComponent;
@@ -1,7 +1,6 @@
1
1
  import React from 'react';
2
2
  import PropTypes from 'prop-types';
3
3
  import { Line, Group, Rect } from 'react-konva';
4
- import { withStyles } from '@material-ui/core/styles';
5
4
  import ImageComponent from './image-konva-tooltip';
6
5
  import { faCorrect, faWrong } from './icons';
7
6
 
@@ -63,7 +62,6 @@ class PolygonComponent extends React.Component {
63
62
 
64
63
  render() {
65
64
  const {
66
- classes,
67
65
  hotspotColor,
68
66
  isCorrect,
69
67
  isEvaluateMode,
@@ -152,7 +150,6 @@ class PolygonComponent extends React.Component {
152
150
  <Line
153
151
  points={pointsParsed}
154
152
  closed={true}
155
- classes={classes.base}
156
153
  fill={selected && selectedHotspotColor? selectedHotspotColor : hotspotColor}
157
154
  onClick={this.handleClick}
158
155
  onTap={this.handleClick}
@@ -161,6 +158,9 @@ class PolygonComponent extends React.Component {
161
158
  strokeWidth={useHoveredStyle && !selected ? 0 : outlineWidth}
162
159
  onMouseLeave={this.handleMouseLeave}
163
160
  onMouseEnter={this.handleMouseEnter}
161
+ opacity={0.5}
162
+ cursor='pointer'
163
+ position='relative'
164
164
  />
165
165
  {isEvaluateMode && iconSrc ? <ImageComponent src={iconSrc} x={iconX} y={iconY} tooltip={evaluateText} /> : null}
166
166
  </Group>
@@ -168,16 +168,7 @@ class PolygonComponent extends React.Component {
168
168
  }
169
169
  }
170
170
 
171
- const styles = () => ({
172
- base: {
173
- cursor: 'pointer',
174
- opacity: 0.5,
175
- position: 'relative',
176
- },
177
- });
178
-
179
171
  PolygonComponent.propTypes = {
180
- classes: PropTypes.object.isRequired,
181
172
  hotspotColor: PropTypes.string.isRequired,
182
173
  id: PropTypes.string.isRequired,
183
174
  isCorrect: PropTypes.bool.isRequired,
@@ -202,4 +193,4 @@ PolygonComponent.defaultProps = {
202
193
  scale: 1,
203
194
  };
204
195
 
205
- export default withStyles(styles)(PolygonComponent);
196
+ export default PolygonComponent;
@@ -1,7 +1,6 @@
1
1
  import React from 'react';
2
2
  import PropTypes from 'prop-types';
3
3
  import { Rect, Group } from 'react-konva';
4
- import { withStyles } from '@material-ui/core/styles';
5
4
  import ImageComponent from './image-konva-tooltip';
6
5
  import { faCorrect, faWrong } from './icons';
7
6
 
@@ -44,7 +43,6 @@ class RectComponent extends React.Component {
44
43
 
45
44
  render() {
46
45
  const {
47
- classes,
48
46
  height,
49
47
  hotspotColor,
50
48
  hoverOutlineColor,
@@ -121,7 +119,8 @@ class RectComponent extends React.Component {
121
119
  />
122
120
  )}
123
121
  <Rect
124
- classes={classes.base}
122
+ x={x}
123
+ y={y}
125
124
  width={width}
126
125
  height={height}
127
126
  fill={selected && selectedHotspotColor ? selectedHotspotColor : hotspotColor}
@@ -132,8 +131,8 @@ class RectComponent extends React.Component {
132
131
  strokeWidth={useHoveredStyle && !selected ? 0 : outlineWidth}
133
132
  onMouseLeave={this.handleMouseLeave}
134
133
  onMouseEnter={this.handleMouseEnter}
135
- x={x}
136
- y={y}
134
+ opacity={0.5}
135
+ cursor="pointer"
137
136
  />
138
137
  {isEvaluateMode && iconSrc ? <ImageComponent src={iconSrc} x={iconX} y={iconY} tooltip={evaluateText} /> : null}
139
138
  </Group>
@@ -141,16 +140,7 @@ class RectComponent extends React.Component {
141
140
  }
142
141
  }
143
142
 
144
- const styles = () => ({
145
- base: {
146
- cursor: 'pointer',
147
- opacity: 0.5,
148
- position: 'relative',
149
- },
150
- });
151
-
152
143
  RectComponent.propTypes = {
153
- classes: PropTypes.object.isRequired,
154
144
  height: PropTypes.number.isRequired,
155
145
  hotspotColor: PropTypes.string.isRequired,
156
146
  id: PropTypes.string.isRequired,
@@ -179,4 +169,4 @@ RectComponent.defaultProps = {
179
169
  scale: 1,
180
170
  };
181
171
 
182
- export default withStyles(styles)(RectComponent);
172
+ export default RectComponent;
package/src/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import React from 'react';
2
- import ReactDOM from 'react-dom';
2
+ import { createRoot } from 'react-dom/client';
3
3
  import { renderMath } from '@pie-lib/math-rendering';
4
4
  import { EnableAudioAutoplayImage } from '@pie-lib/render-ui';
5
5
  import { SessionChangedEvent, ModelSetEvent } from '@pie-framework/pie-player-events';
@@ -14,6 +14,7 @@ export default class Hotspot extends HTMLElement {
14
14
  this._session = null;
15
15
  this._audioInitialized = false;
16
16
  this.audioComplete = false;
17
+ this._root = null;
17
18
  }
18
19
 
19
20
  set model(m) {
@@ -191,16 +192,6 @@ export default class Hotspot extends HTMLElement {
191
192
  observer.observe(this, { childList: true, subtree: true });
192
193
  }
193
194
 
194
- disconnectedCallback() {
195
- document.removeEventListener('click', this._enableAudio);
196
-
197
- if (this._audio) {
198
- this._audio.removeEventListener('playing', this._handlePlaying);
199
- this._audio.removeEventListener('ended', this._handleEnded);
200
- this._audio = null;
201
- }
202
- }
203
-
204
195
  _render() {
205
196
  if (this._model && this._session) {
206
197
  const el = React.createElement(HotspotComponent, {
@@ -209,9 +200,27 @@ export default class Hotspot extends HTMLElement {
209
200
  onSelectChoice: this.onSelectChoice.bind(this),
210
201
  });
211
202
 
212
- ReactDOM.render(el, this, () => {
203
+ if (!this._root) {
204
+ this._root = createRoot(this);
205
+ }
206
+ this._root.render(el);
207
+ queueMicrotask(() => {
213
208
  renderMath(this);
214
209
  });
215
210
  }
216
211
  }
212
+
213
+ disconnectedCallback() {
214
+ document.removeEventListener('click', this._enableAudio);
215
+
216
+ if (this._audio) {
217
+ this._audio.removeEventListener('playing', this._handlePlaying);
218
+ this._audio.removeEventListener('ended', this._handleEnded);
219
+ this._audio = null;
220
+ }
221
+
222
+ if (this._root) {
223
+ this._root.unmount();
224
+ }
225
+ }
217
226
  }
@@ -1,64 +0,0 @@
1
- import React from 'react';
2
- import { shallow } from 'enzyme';
3
- import DeleteWidget from '../DeleteWidget'; // Adjust the import path as needed
4
- import ImageComponent from '../image-konva';
5
-
6
- describe('DeleteWidget', () => {
7
- it('computes positionX and positionY correctly without points', () => {
8
- const mockHandleWidgetClick = jest.fn();
9
-
10
- const props = {
11
- id: 'someId',
12
- x: 5,
13
- y: 10,
14
- width: 30,
15
- height: 40,
16
- outlineColor: 'blue',
17
- handleWidgetClick: mockHandleWidgetClick,
18
- };
19
-
20
- const wrapper = shallow(<DeleteWidget {...props} />);
21
-
22
- // Assert that the computed positionX and positionY match the expected values
23
- expect(wrapper.find(ImageComponent).prop('x')).toEqual(15);
24
- expect(wrapper.find(ImageComponent).prop('y')).toEqual(30);
25
-
26
- // Simulate a click event on the Group element
27
- wrapper.find('Group').simulate('click');
28
-
29
- // Assert that the handleWidgetClick function is called with the correct arguments
30
- expect(mockHandleWidgetClick).toHaveBeenCalledWith('someId');
31
- });
32
-
33
- it('computes positionX and positionY correctly with points', () => {
34
- const props = {
35
- id: 'someId',
36
- x: 5,
37
- y: 10,
38
- points: [
39
- {
40
- "y": 151,
41
- "x": 141
42
- },
43
- {
44
- "y": 289,
45
- "x": 205
46
- },
47
- {
48
- "x": 269,
49
- "y": 151
50
- }
51
- ],
52
- width: 30,
53
- height: 40,
54
- outlineColor: 'blue',
55
- };
56
-
57
- const wrapper = shallow(<DeleteWidget {...props} />);
58
-
59
- // Assert that the computed positionX and positionY match the expected values
60
- expect(wrapper.find(ImageComponent).prop('x')).toEqual(239);
61
- expect(wrapper.find(ImageComponent).prop('y')).toEqual(194);
62
-
63
- });
64
- });
@@ -1,192 +0,0 @@
1
- // Jest Snapshot v1, https://goo.gl/fbAQLP
2
-
3
- exports[`HotspotContainer render renders 1`] = `
4
- <div>
5
- <div
6
- className=""
7
- onDragExit={[Function]}
8
- onDragLeave={[Function]}
9
- onDragOver={[Function]}
10
- onDrop={[Function]}
11
- onPaste={[Function]}
12
- >
13
- <div>
14
- <div
15
- onClick={[Function]}
16
- >
17
- <RectangleButton
18
- isActive={false}
19
- />
20
- </div>
21
- <div
22
- onClick={[Function]}
23
- >
24
- <PolygonButton
25
- isActive={false}
26
- />
27
- </div>
28
- <div
29
- onClick={[Function]}
30
- >
31
- <CircleButton
32
- isActive={false}
33
- />
34
- </div>
35
- <WithStyles(UploadControl)
36
- label="Replace Image"
37
- onInputClick={[Function]}
38
- setRef={[Function]}
39
- />
40
- <WithStyles(RawButton)
41
- disabled={false}
42
- label="Clear all"
43
- onClick={[Function]}
44
- />
45
- </div>
46
- <div>
47
- <WithStyles(Drawable)
48
- dimensions={
49
- Object {
50
- "height": 291,
51
- "width": 410,
52
- }
53
- }
54
- disableDrag={[Function]}
55
- enableDrag={[Function]}
56
- handleFinishDrawing={[Function]}
57
- hotspotColor="rgba(137, 183, 244, 0.65)"
58
- imageUrl="https://cdn.fluence.net/image/0240eb1455ce4c4bb6180232347b6aef_W"
59
- multipleCorrect={true}
60
- onDeleteShape={[Function]}
61
- onUpdateImageDimension={[MockFunction]}
62
- onUpdateShapes={[Function]}
63
- outlineColor="blue"
64
- shapeType="none"
65
- shapes={
66
- Array [
67
- Object {
68
- "correct": true,
69
- "group": "rectangles",
70
- "height": 140,
71
- "id": "0",
72
- "index": 0,
73
- "width": 130,
74
- "x": 1,
75
- "y": 1,
76
- },
77
- Object {
78
- "group": "rectangles",
79
- "height": 140,
80
- "id": "1",
81
- "index": 1,
82
- "width": 130,
83
- "x": 140,
84
- "y": 1,
85
- },
86
- Object {
87
- "group": "rectangles",
88
- "height": 140,
89
- "id": "2",
90
- "index": 2,
91
- "width": 130,
92
- "x": 280,
93
- "y": 1,
94
- },
95
- Object {
96
- "correct": true,
97
- "group": "polygons",
98
- "id": "3",
99
- "index": 3,
100
- "points": Array [
101
- Object {
102
- "x": 1,
103
- "y": 148,
104
- },
105
- Object {
106
- "x": 1,
107
- "y": 288,
108
- },
109
- Object {
110
- "x": 129,
111
- "y": 288,
112
- },
113
- Object {
114
- "x": 129,
115
- "y": 148,
116
- },
117
- ],
118
- },
119
- Object {
120
- "correct": false,
121
- "group": "polygons",
122
- "id": "4",
123
- "index": 4,
124
- "points": Array [
125
- Object {
126
- "x": 141,
127
- "y": 151,
128
- },
129
- Object {
130
- "x": 141,
131
- "y": 289,
132
- },
133
- Object {
134
- "x": 269,
135
- "y": 289,
136
- },
137
- Object {
138
- "x": 269,
139
- "y": 151,
140
- },
141
- ],
142
- },
143
- Object {
144
- "correct": false,
145
- "group": "polygons",
146
- "id": "5",
147
- "index": 5,
148
- "points": Array [
149
- Object {
150
- "x": 279,
151
- "y": 150,
152
- },
153
- Object {
154
- "x": 279,
155
- "y": 289,
156
- },
157
- Object {
158
- "x": 407,
159
- "y": 289,
160
- },
161
- Object {
162
- "x": 407,
163
- "y": 150,
164
- },
165
- ],
166
- },
167
- Object {
168
- "correct": false,
169
- "group": "circles",
170
- "id": "6",
171
- "index": 6,
172
- "radius": 70,
173
- "x": 100,
174
- "y": 100,
175
- },
176
- Object {
177
- "correct": true,
178
- "group": "circles",
179
- "id": "7",
180
- "index": 7,
181
- "radius": 30,
182
- "x": 200,
183
- "y": 150,
184
- },
185
- ]
186
- }
187
- strokeWidth={5}
188
- />
189
- </div>
190
- </div>
191
- </div>
192
- `;