@pie-element/hotspot 4.10.10 → 4.10.11-beta.1445

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 (91) hide show
  1. package/CHANGELOG.md +349 -0
  2. package/configure/CHANGELOG.md +311 -0
  3. package/configure/lib/button.js.map +1 -1
  4. package/configure/lib/defaults.js +23 -2
  5. package/configure/lib/defaults.js.map +1 -1
  6. package/configure/lib/hotspot-container.js +28 -19
  7. package/configure/lib/hotspot-container.js.map +1 -1
  8. package/configure/lib/hotspot-drawable.js +3 -3
  9. package/configure/lib/hotspot-drawable.js.map +1 -1
  10. package/configure/lib/hotspot-palette.js.map +1 -1
  11. package/configure/lib/hotspot-polygon.js.map +1 -1
  12. package/configure/lib/hotspot-rectangle.js.map +1 -1
  13. package/configure/lib/index.js +16 -2
  14. package/configure/lib/index.js.map +1 -1
  15. package/configure/lib/root.js +129 -38
  16. package/configure/lib/root.js.map +1 -1
  17. package/configure/lib/upload-control.js.map +1 -1
  18. package/configure/lib/utils.js +15 -3
  19. package/configure/lib/utils.js.map +1 -1
  20. package/configure/package.json +4 -4
  21. package/configure/src/__tests__/__snapshots__/hotspot-container.test.js.snap +1 -1
  22. package/configure/src/__tests__/__snapshots__/root.test.js.snap +56 -4
  23. package/configure/src/__tests__/hotspot-container.test.js +98 -71
  24. package/configure/src/__tests__/hotspot-drawable.test.js +48 -49
  25. package/configure/src/__tests__/index.test.js +28 -51
  26. package/configure/src/__tests__/root.test.js +162 -82
  27. package/configure/src/__tests__/utils.test.js +112 -98
  28. package/configure/src/button.jsx +4 -4
  29. package/configure/src/defaults.js +35 -18
  30. package/configure/src/hotspot-container.jsx +99 -98
  31. package/configure/src/hotspot-drawable.jsx +56 -56
  32. package/configure/src/hotspot-palette.jsx +12 -25
  33. package/configure/src/hotspot-polygon.jsx +20 -22
  34. package/configure/src/hotspot-rectangle.jsx +5 -15
  35. package/configure/src/index.js +32 -18
  36. package/configure/src/root.jsx +116 -60
  37. package/configure/src/upload-control.jsx +9 -20
  38. package/configure/src/utils.js +51 -22
  39. package/controller/CHANGELOG.md +23 -0
  40. package/controller/lib/defaults.js +2 -2
  41. package/controller/lib/defaults.js.map +1 -1
  42. package/controller/lib/index.js +39 -3
  43. package/controller/lib/index.js.map +1 -1
  44. package/controller/lib/utils.js.map +1 -1
  45. package/controller/package.json +2 -2
  46. package/controller/src/__tests__/index.test.js +29 -50
  47. package/controller/src/defaults.js +5 -9
  48. package/controller/src/index.js +47 -33
  49. package/controller/src/utils.js +9 -6
  50. package/docs/config-schema.json +217 -0
  51. package/docs/config-schema.json.md +169 -0
  52. package/docs/demo/config.js +2 -2
  53. package/docs/demo/generate.js +53 -35
  54. package/docs/demo/session.js +2 -2
  55. package/docs/pie-schema.json +49 -0
  56. package/docs/pie-schema.json.md +36 -0
  57. package/lib/hotspot/container.js +24 -6
  58. package/lib/hotspot/container.js.map +1 -1
  59. package/lib/hotspot/icons.js.map +1 -1
  60. package/lib/hotspot/image.js.map +1 -1
  61. package/lib/hotspot/index.js +65 -5
  62. package/lib/hotspot/index.js.map +1 -1
  63. package/lib/hotspot/polygon.js +45 -19
  64. package/lib/hotspot/polygon.js.map +1 -1
  65. package/lib/hotspot/rectangle.js +45 -19
  66. package/lib/hotspot/rectangle.js.map +1 -1
  67. package/lib/index.js +3 -0
  68. package/lib/index.js.map +1 -1
  69. package/lib/session-updater.js.map +1 -1
  70. package/package.json +7 -4
  71. package/src/__tests__/__snapshots__/{container-test.jsx.snap → container.test.jsx.snap} +8 -0
  72. package/src/__tests__/__snapshots__/image.test.jsx.snap +43 -0
  73. package/src/__tests__/__snapshots__/{polygon-test.jsx.snap → polygon.test.jsx.snap} +11 -0
  74. package/src/__tests__/__snapshots__/{rectangle-test.jsx.snap → rectangle.test.jsx.snap} +11 -0
  75. package/src/__tests__/container.test.jsx +214 -0
  76. package/src/__tests__/{image-test.jsx → image.test.jsx} +2 -2
  77. package/src/__tests__/polygon.test.jsx +235 -0
  78. package/src/__tests__/rectangle.test.jsx +237 -0
  79. package/src/__tests__/{session-updater-test.jsx → session-updater.test.jsx} +22 -31
  80. package/src/hotspot/container.jsx +40 -23
  81. package/src/hotspot/icons.js +4 -2
  82. package/src/hotspot/image.jsx +4 -8
  83. package/src/hotspot/index.jsx +73 -33
  84. package/src/hotspot/polygon.jsx +48 -30
  85. package/src/hotspot/rectangle.jsx +48 -30
  86. package/src/index.js +10 -18
  87. package/src/session-updater.js +1 -1
  88. package/src/__tests__/__snapshots__/image-test.jsx.snap +0 -21
  89. package/src/__tests__/container-test.jsx +0 -143
  90. package/src/__tests__/polygon-test.jsx +0 -77
  91. package/src/__tests__/rectangle-test.jsx +0 -78
@@ -1,5 +1,6 @@
1
1
  import React, { Component } from 'react';
2
2
  import PropTypes from 'prop-types';
3
+ import classNames from 'classnames';
3
4
  import { withStyles } from '@material-ui/core/styles/index';
4
5
  import Help from '@material-ui/icons/Help';
5
6
 
@@ -10,6 +11,7 @@ import { getAllShapes, groupShapes } from './utils';
10
11
 
11
12
  const isImage = (file) => {
12
13
  const imageType = /image.*/;
14
+
13
15
  return file.type.match(imageType);
14
16
  };
15
17
 
@@ -19,7 +21,7 @@ export class Container extends Component {
19
21
  return {
20
22
  ...prevState,
21
23
  shapes: getAllShapes(nextProps.shapes),
22
- }
24
+ };
23
25
  }
24
26
 
25
27
  constructor(props) {
@@ -28,16 +30,18 @@ export class Container extends Component {
28
30
  this.state = {
29
31
  dragEnabled: true,
30
32
  // always transform shapes map into shapes array at this level
31
- shapes: getAllShapes(props.shapes)
32
- }
33
+ shapes: getAllShapes(props.shapes),
34
+ };
33
35
  }
34
36
 
35
37
  handleFileRead = (file) => {
36
- const { onImageUpload } = this.props;
37
- const reader = new FileReader();
38
+ if (file instanceof Blob) {
39
+ const { onImageUpload } = this.props;
40
+ const reader = new FileReader();
38
41
 
39
- reader.onloadend = () => onImageUpload(reader.result);
40
- reader.readAsDataURL(file)
42
+ reader.onloadend = () => onImageUpload(reader.result);
43
+ reader.readAsDataURL(file);
44
+ }
41
45
  };
42
46
 
43
47
  handleUploadImage = (e) => {
@@ -47,6 +51,7 @@ export class Container extends Component {
47
51
  };
48
52
 
49
53
  enableDropzone = () => this.setState({ dropzoneActive: true });
54
+
50
55
  disableDropzone = () => this.setState({ dropzoneActive: false });
51
56
 
52
57
  handleOnPaste = (e) => {
@@ -71,6 +76,7 @@ export class Container extends Component {
71
76
  } else if (isImage(files[0])) {
72
77
  this.handleFileRead(files[0]);
73
78
  }
79
+
74
80
  this.disableDropzone();
75
81
  };
76
82
 
@@ -90,13 +96,13 @@ export class Container extends Component {
90
96
  this.disableDropzone();
91
97
  };
92
98
 
93
- onUpdateShapes = newShapes => {
99
+ onUpdateShapes = (newShapes) => {
94
100
  const { onUpdateShapes } = this.props;
95
101
 
96
102
  this.setState(
97
103
  { shapes: newShapes },
98
104
  // always transform shapes array back into shapes map when saving changes
99
- () => onUpdateShapes(groupShapes(newShapes))
105
+ () => onUpdateShapes(groupShapes(newShapes)),
100
106
  );
101
107
  };
102
108
 
@@ -105,7 +111,7 @@ export class Container extends Component {
105
111
 
106
112
  if (shapes && shapes.length) {
107
113
  // sort by index value
108
- let newShapes = shapes.sort((a, b) => (parseInt(a.index) - parseInt(b.index)));
114
+ let newShapes = shapes.sort((a, b) => parseInt(a.index) - parseInt(b.index));
109
115
 
110
116
  newShapes = newShapes ? newShapes.slice(0, newShapes.length - 1) : [];
111
117
 
@@ -116,7 +122,9 @@ export class Container extends Component {
116
122
  handleClearAll = () => this.onUpdateShapes([]);
117
123
 
118
124
  handleEnableDrag = () => this.setState({ dragEnabled: true });
125
+
119
126
  handleDisableDrag = () => this.setState({ dragEnabled: false });
127
+
120
128
  handleInputClick = () => this.input.click();
121
129
 
122
130
  toggleTooltip = () => this.setState({ showTooltip: !this.state.showTooltip });
@@ -125,31 +133,34 @@ export class Container extends Component {
125
133
  const {
126
134
  classes,
127
135
  dimensions,
136
+ hasErrors,
128
137
  hotspotColor,
129
138
  imageUrl,
130
139
  multipleCorrect,
131
140
  onUpdateImageDimension,
132
141
  outlineColor,
133
142
  strokeWidth,
134
- preserveAspectRatioEnabled
143
+ preserveAspectRatioEnabled,
135
144
  } = this.props;
136
- const {
137
- dropzoneActive,
138
- dragEnabled,
139
- showTooltip
140
- } = this.state;
145
+ const { dropzoneActive, dragEnabled, showTooltip } = this.state;
141
146
  const { shapes } = this.state;
142
147
 
143
148
  return (
144
149
  <div className={classes.base}>
145
- <div className={`${classes.box} ${dropzoneActive ? classes.boxActive : ''}`}
146
- {...dragEnabled ? {
147
- onDragExit: this.handleOnDragExit,
148
- onDragLeave: this.handleOnDragExit,
149
- onDragOver: this.handleOnDragOver,
150
- onDrop: this.handleOnDrop,
151
- onPaste: this.handleOnPaste
152
- } : {}}
150
+ <div
151
+ className={classNames(classes.box, {
152
+ [classes.boxError]: hasErrors && !dropzoneActive,
153
+ [classes.boxActive]: dropzoneActive,
154
+ })}
155
+ {...(dragEnabled
156
+ ? {
157
+ onDragExit: this.handleOnDragExit,
158
+ onDragLeave: this.handleOnDragExit,
159
+ onDragOver: this.handleOnDragOver,
160
+ onDrop: this.handleOnDrop,
161
+ onPaste: this.handleOnPaste,
162
+ }
163
+ : {})}
153
164
  >
154
165
  <div className={classes.toolbar}>
155
166
  {imageUrl && (
@@ -164,54 +175,46 @@ export class Container extends Component {
164
175
  }}
165
176
  />
166
177
  )}
167
- <Button
168
- disabled={!(shapes && shapes.length)}
169
- onClick={this.handleUndo}
170
- label="Undo"
171
- />
172
- <Button
173
- disabled={!(shapes && shapes.length)}
174
- onClick={this.handleClearAll}
175
- label="Clear all"
176
- />
178
+
179
+ <Button disabled={!(shapes && shapes.length)} onClick={this.handleUndo} label="Undo" />
180
+ <Button disabled={!(shapes && shapes.length)} onClick={this.handleClearAll} label="Clear all" />
177
181
  </div>
178
182
 
179
183
  <div
180
- ref={ref => {
184
+ ref={(ref) => {
181
185
  this.imageSection = ref;
182
186
  }}
183
- className={classes.drawableHeight}>
184
- {imageUrl
185
- ? (
186
- <Drawable
187
- dimensions={dimensions}
188
- disableDrag={this.handleDisableDrag}
189
- enableDrag={this.handleEnableDrag}
190
- imageUrl={imageUrl}
191
- hotspotColor={hotspotColor}
192
- multipleCorrect={multipleCorrect}
193
- onUpdateImageDimension={onUpdateImageDimension}
194
- onUpdateShapes={this.onUpdateShapes}
195
- outlineColor={outlineColor}
196
- shapes={shapes}
197
- strokeWidth={strokeWidth}
198
- preserveAspectRatioEnabled={preserveAspectRatioEnabled}
187
+ className={classes.drawableHeight}
188
+ >
189
+ {imageUrl ? (
190
+ <Drawable
191
+ dimensions={dimensions}
192
+ disableDrag={this.handleDisableDrag}
193
+ enableDrag={this.handleEnableDrag}
194
+ imageUrl={imageUrl}
195
+ hotspotColor={hotspotColor}
196
+ multipleCorrect={multipleCorrect}
197
+ onUpdateImageDimension={onUpdateImageDimension}
198
+ onUpdateShapes={this.onUpdateShapes}
199
+ outlineColor={outlineColor}
200
+ shapes={shapes}
201
+ strokeWidth={strokeWidth}
202
+ preserveAspectRatioEnabled={preserveAspectRatioEnabled}
203
+ />
204
+ ) : (
205
+ <div className={classNames(classes.drawableHeight, classes.centered)}>
206
+ <label>Drag and drop or upload image from computer</label>
207
+ <br />
208
+ <UploadControl
209
+ label="Upload Image"
210
+ onInputClick={this.handleInputClick}
211
+ onUploadImage={this.handleUploadImage}
212
+ setRef={(ref) => {
213
+ this.input = ref;
214
+ }}
199
215
  />
200
- )
201
- : (
202
- <div className={`${classes.drawableHeight} ${classes.centered}`}>
203
- <label>Drag and drop or upload image from computer</label>
204
- <br/>
205
- <UploadControl
206
- label="Upload Image"
207
- onInputClick={this.handleInputClick}
208
- onUploadImage={this.handleUploadImage}
209
- setRef={(ref) => {
210
- this.input = ref;
211
- }}
212
- />
213
- </div>
214
- )}
216
+ </div>
217
+ )}
215
218
  </div>
216
219
 
217
220
  {imageUrl && (
@@ -219,60 +222,58 @@ export class Container extends Component {
219
222
  {showTooltip && (
220
223
  <div className={classes.tooltipContent}>
221
224
  <label>
222
- Click and drag to create a hotspot. Click the hotspot to mark correct. Click
223
- again to unmark.
225
+ Click and drag to create a hotspot. Click the hotspot to mark correct. Click again to unmark.
224
226
  </label>
225
- <div className={classes.tooltipArrow}/>
227
+ <div className={classes.tooltipArrow} />
226
228
  </div>
227
229
  )}
228
- <Help
229
- className={classes.icon}
230
- onMouseOut={this.toggleTooltip}
231
- onMouseOver={this.toggleTooltip}
232
- />
230
+
231
+ <Help className={classes.icon} onMouseOut={this.toggleTooltip} onMouseOver={this.toggleTooltip} />
233
232
  </div>
234
233
  )}
235
234
  </div>
236
235
  </div>
237
-
238
236
  );
239
237
  }
240
238
  }
241
239
 
242
- const styles = theme => ({
240
+ const styles = (theme) => ({
243
241
  base: {
244
- marginTop: theme.spacing.unit * 2
242
+ marginTop: theme.spacing.unit * 2,
245
243
  },
246
244
  box: {
247
245
  border: '1px solid #E0E1E6',
248
- borderRadius: '5px'
246
+ borderRadius: '5px',
249
247
  },
250
248
  boxActive: {
251
- border: '1px solid #0032C2'
249
+ border: '1px solid #0032C2',
250
+ },
251
+ boxError: {
252
+ border: '1px solid red',
252
253
  },
253
254
  centered: {
254
255
  alignItems: 'center',
255
256
  display: 'flex',
256
257
  flexDirection: 'column',
257
- justifyContent: 'center'
258
+ justifyContent: 'center',
258
259
  },
259
260
  drawableHeight: {
260
261
  minHeight: 350,
261
- paddingBottom: '40px',
262
- paddingRight: '40px',
262
+ paddingBottom: theme.spacing.unit * 5,
263
+ paddingRight: theme.spacing.unit * 5,
263
264
  },
264
265
  icon: {
265
266
  '&:hover': {
266
267
  color: '#333131',
267
- cursor: 'help'
268
+ cursor: 'help',
268
269
  },
269
- color: '#C1C1C1'
270
+ color: '#C1C1C1',
270
271
  },
271
272
  replaceButton: {
272
273
  marginLeft: 0,
273
274
  },
274
275
  replaceSection: {
275
- marginRight: 'auto'
276
+ marginRight: 'auto',
276
277
  },
277
278
  toolbar: {
278
279
  backgroundColor: '#ECEDF1',
@@ -281,25 +282,25 @@ const styles = theme => ({
281
282
  borderTopRightRadius: '5px',
282
283
  display: 'flex',
283
284
  justifyContent: 'flex-end',
284
- padding: '12px 8px'
285
+ padding: theme.spacing.unit,
285
286
  },
286
287
  tooltip: {
287
288
  position: 'relative',
288
289
  textAlign: 'right',
289
- padding: '5px 9px'
290
+ padding: theme.spacing.unit,
290
291
  },
291
292
  tooltipContent: {
292
293
  background: '#333131',
293
294
  borderRadius: '4px',
294
295
  color: '#FFFFFF',
295
- fontSize: '14px',
296
+ fontSize: theme.typography.fontSize,
296
297
  lineHeight: '18px',
297
- marginTop: '-70px',
298
- padding: '7px 16px',
298
+ marginTop: '-60px',
299
+ padding: theme.spacing.unit,
299
300
  position: 'absolute',
300
301
  right: '5px',
301
302
  textAlign: 'left',
302
- width: '300px'
303
+ width: '300px',
303
304
  },
304
305
  tooltipArrow: {
305
306
  width: 0,
@@ -308,10 +309,10 @@ const styles = theme => ({
308
309
  borderRight: '10px solid transparent',
309
310
  borderTop: '10px solid #333131',
310
311
  marginBottom: -10,
311
- marginTop: '2px',
312
+ marginTop: '4px',
312
313
  position: 'absolute',
313
- right: '5px'
314
- }
314
+ right: '5px',
315
+ },
315
316
  });
316
317
 
317
318
  Container.propTypes = {
@@ -326,14 +327,14 @@ Container.propTypes = {
326
327
  outlineColor: PropTypes.string.isRequired,
327
328
  shapes: PropTypes.shape({
328
329
  rectangles: PropTypes.array,
329
- polygons: PropTypes.array
330
+ polygons: PropTypes.array,
330
331
  }).isRequired,
331
332
  strokeWidth: PropTypes.number,
332
- preserveAspectRatioEnabled: PropTypes.bool
333
+ preserveAspectRatioEnabled: PropTypes.bool,
333
334
  };
335
+
334
336
  Container.defaultProps = {
335
- strokeWidth: 5
337
+ strokeWidth: 5,
336
338
  };
337
339
 
338
-
339
340
  export default withStyles(styles)(Container);
@@ -22,7 +22,7 @@ export class Drawable extends React.Component {
22
22
  return {
23
23
  ...prevState,
24
24
  dimensions: dimensions,
25
- }
25
+ };
26
26
  }
27
27
 
28
28
  constructor(props) {
@@ -36,7 +36,7 @@ export class Drawable extends React.Component {
36
36
  height: 0,
37
37
  width: 0,
38
38
  },
39
- }
39
+ };
40
40
  }
41
41
 
42
42
  /// start of handling HotSpots section
@@ -45,7 +45,7 @@ export class Drawable extends React.Component {
45
45
  const { onUpdateShapes, shapes } = this.props;
46
46
  // Add a new rectangle at the mouse position with 0 width and height
47
47
  const newShapes = shapes.slice();
48
- const value = max(newShapes.map(c => parseInt(c.id)).filter(id => !isNaN(id))) || 0;
48
+ const value = max(newShapes.map((c) => parseInt(c.id)).filter((id) => !isNaN(id))) || 0;
49
49
 
50
50
  newShapes.push({
51
51
  id: `${value + 1}`,
@@ -54,7 +54,7 @@ export class Drawable extends React.Component {
54
54
  x: e.evt.layerX,
55
55
  y: e.evt.layerY,
56
56
  group: 'rectangles',
57
- index: shapes.length
57
+ index: shapes.length,
58
58
  });
59
59
 
60
60
  this.setState({ isDrawing: true, isDrawingShapeId: `${value + 1}` });
@@ -86,7 +86,7 @@ export class Drawable extends React.Component {
86
86
  const mouseX = e.evt.layerX;
87
87
  const mouseY = e.evt.layerY;
88
88
 
89
- const currShapeIndex = shapes.findIndex(shape => shape.id === isDrawingShapeId);
89
+ const currShapeIndex = shapes.findIndex((shape) => shape.id === isDrawingShapeId);
90
90
  const currShape = shapes[currShapeIndex];
91
91
 
92
92
  if (currShape) {
@@ -100,7 +100,7 @@ export class Drawable extends React.Component {
100
100
  height: newHeight,
101
101
  width: newWidth,
102
102
  x: currShape.x,
103
- y: currShape.y
103
+ y: currShape.y,
104
104
  };
105
105
 
106
106
  // On mouse move don't trigger any event. Put the shapes on this state instead.
@@ -111,12 +111,12 @@ export class Drawable extends React.Component {
111
111
 
112
112
  handleOnDragEnd = (id, updatedProps) => {
113
113
  const { shapes, onUpdateShapes } = this.props;
114
- const newShapes = shapes.map(shape => {
114
+ const newShapes = shapes.map((shape) => {
115
115
  if (shape.id === id) {
116
116
  return {
117
117
  ...shape,
118
- ...updatedProps
119
- }
118
+ ...updatedProps,
119
+ };
120
120
  }
121
121
  return shape;
122
122
  });
@@ -131,17 +131,17 @@ export class Drawable extends React.Component {
131
131
  let newShapes = [];
132
132
 
133
133
  if (multipleCorrect) {
134
- newShapes = shapes.map(shape => {
134
+ newShapes = shapes.map((shape) => {
135
135
  if (shape.id === id) {
136
136
  shape.correct = !shape.correct;
137
137
  }
138
138
  return shape;
139
- })
139
+ });
140
140
  } else {
141
- newShapes = shapes.map(shape => {
141
+ newShapes = shapes.map((shape) => {
142
142
  shape.correct = shape.id === id;
143
143
  return shape;
144
- })
144
+ });
145
145
  }
146
146
 
147
147
  onUpdateShapes(cloneDeep(newShapes));
@@ -157,17 +157,18 @@ export class Drawable extends React.Component {
157
157
  const newWidth = parseFloat(elementStyle.width);
158
158
  const aspectWidth = newWidth / IMAGE_MAX_WIDTH;
159
159
 
160
- const dimensions = newWidth > IMAGE_MAX_WIDTH ? {
161
- height: newHeight / aspectWidth,
162
- width: IMAGE_MAX_WIDTH
163
- } : {
164
- height: newHeight,
165
- width: newWidth
166
- };
160
+ const dimensions =
161
+ newWidth > IMAGE_MAX_WIDTH
162
+ ? {
163
+ height: newHeight / aspectWidth,
164
+ width: IMAGE_MAX_WIDTH,
165
+ }
166
+ : {
167
+ height: newHeight,
168
+ width: newWidth,
169
+ };
167
170
 
168
- this.setState(
169
- { dimensions },
170
- () => onUpdateImageDimension(dimensions));
171
+ this.setState({ dimensions }, () => onUpdateImageDimension(dimensions));
171
172
 
172
173
  resizeHandle.addEventListener('mousedown', this.initialiseResize, false);
173
174
  };
@@ -182,47 +183,43 @@ export class Drawable extends React.Component {
182
183
  let drawable = true;
183
184
 
184
185
  // Do not allow resizing over the hotspots
185
- shapes && shapes.forEach(shape => {
186
- const right = shape.x + shape.width + 5;
187
- const bottom = shape.y + shape.height + 5;
188
- if (x <= right || y <= bottom) {
189
- drawable = false
190
- }
191
- });
186
+ shapes &&
187
+ shapes.forEach((shape) => {
188
+ const right = shape.x + shape.width + 5;
189
+ const bottom = shape.y + shape.height + 5;
190
+ if (x <= right || y <= bottom) {
191
+ drawable = false;
192
+ }
193
+ });
192
194
  return drawable;
193
195
  }
194
196
 
195
197
  startResizing = (e) => {
196
198
  const bounds = e.target.getBoundingClientRect();
197
199
  const box = this.image;
198
- const {
199
- disableDrag,
200
- preserveAspectRatioEnabled,
201
- dimensions,
202
- shapes
203
- } = this.props;
200
+ const { disableDrag, preserveAspectRatioEnabled, dimensions, shapes } = this.props;
204
201
 
205
202
  // todo previously we had state.dimensions, is it needed?
206
203
  const { width, height } = updateImageDimensions(
207
204
  dimensions,
208
205
  {
209
206
  width: e.clientX - bounds.left,
210
- height: e.clientY - bounds.top
207
+ height: e.clientY - bounds.top,
211
208
  },
212
- preserveAspectRatioEnabled
209
+ preserveAspectRatioEnabled,
213
210
  );
214
211
 
215
212
  const resizeValid = this.checkIfResizeValid(width, height);
216
213
  const hasMinimumWidth = width > 150 && height > 150;
217
214
 
218
- if (resizeValid && hasMinimumWidth) {
215
+ if (resizeValid && hasMinimumWidth && box) {
219
216
  box.style.width = `${width}px`;
220
217
  box.style.height = `${height}px`;
221
218
 
222
219
  this.setState({
223
220
  resizing: true,
224
221
  dimensions: { height: height, width: width },
225
- stateShapes: getUpdatedShapes(dimensions, { width, height }, shapes)
222
+ stateShapes: getUpdatedShapes(dimensions, { width, height }, shapes),
226
223
  });
227
224
  }
228
225
 
@@ -256,12 +253,12 @@ export class Drawable extends React.Component {
256
253
  hotspotColor,
257
254
  outlineColor,
258
255
  shapes,
259
- strokeWidth
256
+ strokeWidth,
260
257
  } = this.props;
261
258
  const {
262
259
  stateShapes,
263
260
  isDrawing,
264
- dimensions: { height: heightFromState, width: widthFromState }
261
+ dimensions: { height: heightFromState, width: widthFromState },
265
262
  } = this.state;
266
263
  const shapesToUse = stateShapes || shapes;
267
264
 
@@ -272,15 +269,18 @@ export class Drawable extends React.Component {
272
269
  <img
273
270
  className={classes.image}
274
271
  onLoad={this.handleOnImageLoad}
275
- ref={ref => {
272
+ ref={(ref) => {
276
273
  this.image = ref;
277
274
  }}
278
275
  src={imageUrl}
279
- {...height && width ? { style: { height, width } } : {}}
276
+ {...(height && width ? { style: { height, width } } : {})}
277
+ />
278
+ <div
279
+ ref={(ref) => {
280
+ this.resize = ref;
281
+ }}
282
+ className={classes.resize}
280
283
  />
281
- <div ref={ref => {
282
- this.resize = ref;
283
- }} className={classes.resize}/>
284
284
  </div>
285
285
  )}
286
286
 
@@ -288,9 +288,9 @@ export class Drawable extends React.Component {
288
288
  className={classes.stage}
289
289
  height={heightFromState || height}
290
290
  width={widthFromState || width}
291
- onMouseDown={this.handleOnMouseDown }
292
- onMouseUp={this.handleOnMouseUp }
293
- onMouseMove={this.handleMouseMove }
291
+ onMouseDown={this.handleOnMouseDown}
292
+ onMouseUp={this.handleOnMouseUp}
293
+ onMouseMove={this.handleMouseMove}
294
294
  >
295
295
  <Layer>
296
296
  {shapesToUse.map((shape, index) => {
@@ -324,7 +324,7 @@ export class Drawable extends React.Component {
324
324
 
325
325
  const styles = () => ({
326
326
  base: {
327
- position: 'relative'
327
+ position: 'relative',
328
328
  },
329
329
  image: {
330
330
  alignItems: 'center',
@@ -333,7 +333,7 @@ const styles = () => ({
333
333
  },
334
334
  imageContainer: {
335
335
  position: 'relative',
336
- width: 'fit-content'
336
+ width: 'fit-content',
337
337
  },
338
338
  resize: {
339
339
  borderBottom: '1px solid #727272',
@@ -343,13 +343,13 @@ const styles = () => ({
343
343
  height: '10px',
344
344
  position: 'absolute',
345
345
  right: '-10px',
346
- width: '10px'
346
+ width: '10px',
347
347
  },
348
348
  stage: {
349
349
  left: 0,
350
350
  top: 0,
351
- position: 'absolute'
352
- }
351
+ position: 'absolute',
352
+ },
353
353
  });
354
354
 
355
355
  Drawable.propTypes = {
@@ -365,7 +365,7 @@ Drawable.propTypes = {
365
365
  outlineColor: PropTypes.string.isRequired,
366
366
  shapes: PropTypes.array.isRequired,
367
367
  strokeWidth: PropTypes.number,
368
- preserveAspectRatioEnabled: PropTypes.bool
368
+ preserveAspectRatioEnabled: PropTypes.bool,
369
369
  };
370
370
 
371
371
  export default withStyles(styles)(Drawable);