carbon-addons-iot-react 5.8.1 → 5.8.2
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/es/components/HotspotEditorModal/HotspotEditorModal.js +4 -0
- package/es/components/HotspotEditorModal/hooks/hotspotStateHook.js +33 -3
- package/es/components/ImageCard/HotspotContent.js +1 -1
- package/es/components/ImageCard/ImageHotspots.js +187 -9
- package/lib/components/HotspotEditorModal/HotspotEditorModal.js +4 -0
- package/lib/components/HotspotEditorModal/hooks/hotspotStateHook.js +33 -3
- package/lib/components/ImageCard/HotspotContent.js +1 -1
- package/lib/components/ImageCard/ImageHotspots.js +186 -8
- package/package.json +1 -1
- package/umd/carbon-addons-iot-react.js +224 -12
|
@@ -315,6 +315,7 @@ var HotspotEditorModal = function HotspotEditorModal(_ref) {
|
|
|
315
315
|
switchCurrentType = _useHotspotEditorStat.switchCurrentType,
|
|
316
316
|
updateHotspotDataSource = _useHotspotEditorStat.updateHotspotDataSource,
|
|
317
317
|
updateHotspotTooltip = _useHotspotEditorStat.updateHotspotTooltip,
|
|
318
|
+
updateHotspotPosition = _useHotspotEditorStat.updateHotspotPosition,
|
|
318
319
|
updateTextHotspotStyle = _useHotspotEditorStat.updateTextHotspotStyle,
|
|
319
320
|
updateTextHotspotContent = _useHotspotEditorStat.updateTextHotspotContent,
|
|
320
321
|
updateDynamicHotspotSourceX = _useHotspotEditorStat.updateDynamicHotspotSourceX,
|
|
@@ -380,6 +381,8 @@ var HotspotEditorModal = function HotspotEditorModal(_ref) {
|
|
|
380
381
|
}
|
|
381
382
|
var hotspotsWithoutExampleValues = filteredHotspots.map(function (hotspot) {
|
|
382
383
|
return update(hotspot, {
|
|
384
|
+
$unset: ['id'],
|
|
385
|
+
// Remove the internal id added for drag tracking
|
|
383
386
|
content: {
|
|
384
387
|
$unset: ['values']
|
|
385
388
|
}
|
|
@@ -629,6 +632,7 @@ var HotspotEditorModal = function HotspotEditorModal(_ref) {
|
|
|
629
632
|
hotspotDefaults: hotspotDefaults
|
|
630
633
|
});
|
|
631
634
|
},
|
|
635
|
+
onUpdateHotspotPosition: updateHotspotPosition,
|
|
632
636
|
onSelectHotspot: setSelectedHotspot,
|
|
633
637
|
selectedHotspots: getSelectedHotspotsList(selectedHotspot, hotspots),
|
|
634
638
|
src: cardConfig.content.src,
|
|
@@ -49,6 +49,7 @@ var hotspotActionTypes = {
|
|
|
49
49
|
hotspotDataSourceChange: 'HOTSPOT_DATA_SOURCE_CHANGE',
|
|
50
50
|
hotspotDataSourceSettingsChange: 'HOTSPOT_DATA_SOURCE_SETTINGS_CHANGE',
|
|
51
51
|
hotspotTooltipChange: 'HOTSPOT_TOOLTIP_CHANGE',
|
|
52
|
+
hotspotPositionChange: 'HOTSPOT_POSITION_CHANGE',
|
|
52
53
|
hotspotSelect: 'HOTSPOT_SELECT',
|
|
53
54
|
hotspotsAdd: 'HOTSPOTS_ADD',
|
|
54
55
|
textHotspotStyleChange: 'TEXT_HOTSPOT_STYLE_CHANGE',
|
|
@@ -151,10 +152,32 @@ function hotspotEditorReducer(state, _ref2) {
|
|
|
151
152
|
};
|
|
152
153
|
return getHotspotUpdate(state, _mergeSpec);
|
|
153
154
|
}
|
|
155
|
+
// HOTSPOT POSITION CHANGE
|
|
156
|
+
case hotspotActionTypes.hotspotPositionChange:
|
|
157
|
+
{
|
|
158
|
+
var isPositionAvailable = !state.hotspots.find(function (hotspot) {
|
|
159
|
+
return isHotspotMatch(hotspot, payload.position);
|
|
160
|
+
});
|
|
161
|
+
if (isPositionAvailable) {
|
|
162
|
+
// Find the updated hotspot in the new hotspots array to maintain selection
|
|
163
|
+
var updatedSelectedHotspot = payload.newHotspots.find(function (hotspot) {
|
|
164
|
+
return isHotspotMatch(hotspot, payload.position);
|
|
165
|
+
});
|
|
166
|
+
return update(state, {
|
|
167
|
+
hotspots: {
|
|
168
|
+
$set: payload.newHotspots
|
|
169
|
+
},
|
|
170
|
+
selectedHotspot: {
|
|
171
|
+
$set: updatedSelectedHotspot
|
|
172
|
+
}
|
|
173
|
+
});
|
|
174
|
+
}
|
|
175
|
+
return state;
|
|
176
|
+
}
|
|
154
177
|
// HOTSPOTS ADD
|
|
155
178
|
case hotspotActionTypes.hotspotsAdd:
|
|
156
179
|
{
|
|
157
|
-
var
|
|
180
|
+
var _isPositionAvailable = !state.hotspots.find(function (hotspot) {
|
|
158
181
|
return isHotspotMatch(hotspot, payload.position);
|
|
159
182
|
});
|
|
160
183
|
var defaultContent = state.currentType === hotspotTypes.TEXT ? {
|
|
@@ -165,7 +188,7 @@ function hotspotEditorReducer(state, _ref2) {
|
|
|
165
188
|
content: defaultContent,
|
|
166
189
|
type: createableType
|
|
167
190
|
});
|
|
168
|
-
return
|
|
191
|
+
return _isPositionAvailable ? update(state, {
|
|
169
192
|
selectedHotspot: {
|
|
170
193
|
$set: newHotspot
|
|
171
194
|
},
|
|
@@ -193,7 +216,7 @@ function hotspotEditorReducer(state, _ref2) {
|
|
|
193
216
|
$set: hotspot
|
|
194
217
|
},
|
|
195
218
|
currentType: {
|
|
196
|
-
$set: (_hotspot$type = hotspot.type) !== null && _hotspot$type !== void 0 ? _hotspot$type : defaultTypeWhenMissing
|
|
219
|
+
$set: (_hotspot$type = hotspot === null || hotspot === void 0 ? void 0 : hotspot.type) !== null && _hotspot$type !== void 0 ? _hotspot$type : defaultTypeWhenMissing
|
|
197
220
|
}
|
|
198
221
|
});
|
|
199
222
|
}
|
|
@@ -392,6 +415,12 @@ function useHotspotEditorState() {
|
|
|
392
415
|
payload: hotspotContent
|
|
393
416
|
});
|
|
394
417
|
};
|
|
418
|
+
var updateHotspotPosition = function updateHotspotPosition(hotspotPosition) {
|
|
419
|
+
return dispatch({
|
|
420
|
+
type: hotspotActionTypes.hotspotPositionChange,
|
|
421
|
+
payload: hotspotPosition
|
|
422
|
+
});
|
|
423
|
+
};
|
|
395
424
|
|
|
396
425
|
/** Updates the properties of the text hotspot, passes a payload like {color: 'blue'} */
|
|
397
426
|
var updateTextHotspotStyle = function updateTextHotspotStyle(textHotspotStyle) {
|
|
@@ -479,6 +508,7 @@ function useHotspotEditorState() {
|
|
|
479
508
|
switchCurrentType: switchCurrentType,
|
|
480
509
|
updateHotspotDataSource: updateHotspotDataSource,
|
|
481
510
|
updateHotspotTooltip: updateHotspotTooltip,
|
|
511
|
+
updateHotspotPosition: updateHotspotPosition,
|
|
482
512
|
updateTextHotspotStyle: updateTextHotspotStyle,
|
|
483
513
|
updateTextHotspotContent: updateTextHotspotContent,
|
|
484
514
|
updateDynamicHotspotSourceX: updateDynamicHotspotSourceX,
|
|
@@ -174,7 +174,7 @@ var HotspotContent = function HotspotContent(_ref) {
|
|
|
174
174
|
}, typeof value === 'number' ? formatNumberWithPrecision(value, !isNil(precision) ? precision : Math.abs(value) < 1 ? value === 0 ? 0 : 3 // for small decimals give 3 spots
|
|
175
175
|
: 1,
|
|
176
176
|
// otherwise 1 spot if precision isn't set
|
|
177
|
-
locale) : value, unit && value !== '--' && /*#__PURE__*/React__default.createElement("span", {
|
|
177
|
+
locale) : typeof value === 'boolean' ? String(value) : value, unit && value !== '--' && /*#__PURE__*/React__default.createElement("span", {
|
|
178
178
|
className: "".concat(iotPrefix, "--hotspot-content-unit")
|
|
179
179
|
}, unit))));
|
|
180
180
|
}));
|
|
@@ -16,7 +16,7 @@ import 'core-js/modules/es.object.keys.js';
|
|
|
16
16
|
import 'core-js/modules/es.object.to-string.js';
|
|
17
17
|
import 'core-js/modules/web.dom-collections.for-each.js';
|
|
18
18
|
import 'core-js/modules/web.dom-collections.iterator.js';
|
|
19
|
-
import React__default, { useState,
|
|
19
|
+
import React__default, { useState, useRef, useMemo, useEffect, useCallback } from 'react';
|
|
20
20
|
import PropTypes from 'prop-types';
|
|
21
21
|
import { InlineLoading } from '@carbon/react';
|
|
22
22
|
import warning from 'warning';
|
|
@@ -75,6 +75,10 @@ var propTypes = {
|
|
|
75
75
|
* Emits position obj {x, y} of hotspot to be added.
|
|
76
76
|
*/
|
|
77
77
|
onAddHotspotPosition: PropTypes.func,
|
|
78
|
+
/** Callback when a hotspot is dragged to new position in isEditable mode
|
|
79
|
+
* Emits new hotspots and updated position obj {x, y} of hotspot.
|
|
80
|
+
*/
|
|
81
|
+
onUpdateHotspotPosition: PropTypes.func,
|
|
78
82
|
/** Callback when a hotspot is clicked in isEditable mode, emits position obj {x, y} */
|
|
79
83
|
onSelectHotspot: PropTypes.func,
|
|
80
84
|
/**
|
|
@@ -115,6 +119,7 @@ var defaultProps = {
|
|
|
115
119
|
isHotspotDataLoading: false,
|
|
116
120
|
isEditable: false,
|
|
117
121
|
onAddHotspotPosition: function onAddHotspotPosition() {},
|
|
122
|
+
onUpdateHotspotPosition: function onUpdateHotspotPosition() {},
|
|
118
123
|
onSelectHotspot: function onSelectHotspot() {},
|
|
119
124
|
onHotspotContentChanged: function onHotspotContentChanged() {},
|
|
120
125
|
background: '#eee',
|
|
@@ -233,6 +238,7 @@ var calculateHotspotContainerLayout = function calculateHotspotContainerLayout(_
|
|
|
233
238
|
var width;
|
|
234
239
|
var height;
|
|
235
240
|
var top;
|
|
241
|
+
var left;
|
|
236
242
|
|
|
237
243
|
// CONTAIN
|
|
238
244
|
if (objectFit === 'contain') {
|
|
@@ -240,32 +246,38 @@ var calculateHotspotContainerLayout = function calculateHotspotContainerLayout(_
|
|
|
240
246
|
width = imageWidth;
|
|
241
247
|
height = imageWidth / imageRatio;
|
|
242
248
|
top = imageScale > 1 ? imageOffsetY : imageObjectFitOffsetY;
|
|
249
|
+
left = imageScale > 1 ? 0 : (containerWidth - imageWidth) / 2;
|
|
243
250
|
} else if (imageOrientation === 'portrait') {
|
|
244
251
|
width = imageHeight / imageRatio;
|
|
245
252
|
height = imageHeight;
|
|
246
253
|
top = imageOffsetY;
|
|
254
|
+
left = (containerWidth - width) / 2;
|
|
247
255
|
}
|
|
248
256
|
// FILL
|
|
249
257
|
} else if (objectFit === 'fill') {
|
|
250
258
|
width = imageScale > 1 ? imageWidth : containerWidth;
|
|
251
259
|
height = imageScale > 1 ? imageHeight : containerHeight;
|
|
252
260
|
top = imageOffsetY;
|
|
261
|
+
left = 0;
|
|
253
262
|
// NO OBJECT FIT
|
|
254
263
|
} else if (!objectFit) {
|
|
255
264
|
if (imageOrientation === 'landscape') {
|
|
256
265
|
width = imageWidth;
|
|
257
266
|
height = imageWidth / imageRatio;
|
|
258
267
|
top = imageOffsetY;
|
|
268
|
+
left = 0;
|
|
259
269
|
} else if (imageOrientation === 'portrait') {
|
|
260
270
|
width = imageHeight / imageRatio;
|
|
261
271
|
height = imageHeight;
|
|
262
272
|
top = imageOffsetY;
|
|
273
|
+
left = (containerWidth - width) / 2;
|
|
263
274
|
}
|
|
264
275
|
}
|
|
265
276
|
return {
|
|
266
277
|
width: width,
|
|
267
278
|
height: height,
|
|
268
|
-
top: top
|
|
279
|
+
top: top,
|
|
280
|
+
left: left
|
|
269
281
|
};
|
|
270
282
|
};
|
|
271
283
|
var calculateObjectFitOffset = function calculateObjectFitOffset(_ref5) {
|
|
@@ -510,6 +522,7 @@ var ImageHotspots = function ImageHotspots(_ref9) {
|
|
|
510
522
|
isEditable = _ref9.isEditable,
|
|
511
523
|
isHotspotDataLoading = _ref9.isHotspotDataLoading,
|
|
512
524
|
onAddHotspotPosition = _ref9.onAddHotspotPosition,
|
|
525
|
+
onUpdateHotspotPosition = _ref9.onUpdateHotspotPosition,
|
|
513
526
|
onSelectHotspot = _ref9.onSelectHotspot,
|
|
514
527
|
onHotspotContentChanged = _ref9.onHotspotContentChanged,
|
|
515
528
|
zoomMax = _ref9.zoomMax,
|
|
@@ -554,9 +567,52 @@ var ImageHotspots = function ImageHotspots(_ref9) {
|
|
|
554
567
|
_useState12 = _slicedToArray(_useState11, 2),
|
|
555
568
|
options = _useState12[0],
|
|
556
569
|
setOptions = _useState12[1];
|
|
570
|
+
// Tracks if a hotspot is being dragged and which one.
|
|
571
|
+
var _useState13 = useState(null),
|
|
572
|
+
_useState14 = _slicedToArray(_useState13, 2),
|
|
573
|
+
draggingHotspotId = _useState14[0],
|
|
574
|
+
setDraggingHotspotId = _useState14[1];
|
|
575
|
+
|
|
576
|
+
// Ref for outer container
|
|
577
|
+
var containerRef = useRef(null);
|
|
578
|
+
var dragStateRef = useRef({
|
|
579
|
+
// Flag to indicate if a drag is active
|
|
580
|
+
isDragging: false,
|
|
581
|
+
// Stores the starting mouse position of a drag
|
|
582
|
+
dragStartPosition: {
|
|
583
|
+
x: 0,
|
|
584
|
+
y: 0
|
|
585
|
+
},
|
|
586
|
+
// Tracks the current position during a drag
|
|
587
|
+
currentDargPosition: null,
|
|
588
|
+
// Stores layout of image and container
|
|
589
|
+
layout: {
|
|
590
|
+
rect: null,
|
|
591
|
+
hotspotLayout: null
|
|
592
|
+
},
|
|
593
|
+
// Tracks Scheduled Animation Frames
|
|
594
|
+
frame: null
|
|
595
|
+
});
|
|
596
|
+
|
|
597
|
+
// Minimum pixel movement before a drag is initiated
|
|
598
|
+
var DRAG_THRESHOLD = 5;
|
|
557
599
|
var mergedI18n = useMemo(function () {
|
|
558
600
|
return _objectSpread(_objectSpread({}, defaultProps.i18n), i18n);
|
|
559
601
|
}, [i18n]);
|
|
602
|
+
var hotspotsWithId = useMemo(function () {
|
|
603
|
+
return hotspots.map(function (hotspot, index) {
|
|
604
|
+
return _objectSpread(_objectSpread({}, hotspot), {}, {
|
|
605
|
+
id: "".concat(hotspot.x, "-").concat(hotspot.y, "-").concat(index)
|
|
606
|
+
});
|
|
607
|
+
});
|
|
608
|
+
}, [hotspots]);
|
|
609
|
+
var _useState15 = useState(hotspotsWithId),
|
|
610
|
+
_useState16 = _slicedToArray(_useState15, 2),
|
|
611
|
+
editableHotspots = _useState16[0],
|
|
612
|
+
setEditableHotspots = _useState16[1];
|
|
613
|
+
useEffect(function () {
|
|
614
|
+
setEditableHotspots(hotspotsWithId);
|
|
615
|
+
}, [hotspotsWithId]);
|
|
560
616
|
var handleCtrlKeyUp = useCallback(function (event) {
|
|
561
617
|
// Was the control key unpressed
|
|
562
618
|
if (event.key === keyboardKeys.CONTROL) {
|
|
@@ -628,6 +684,11 @@ var ImageHotspots = function ImageHotspots(_ref9) {
|
|
|
628
684
|
objectFit: displayOption
|
|
629
685
|
};
|
|
630
686
|
var onHotspotClicked = useCallback(function (evt, position) {
|
|
687
|
+
// prevent click behavior after drag
|
|
688
|
+
if (dragStateRef.current.isDragging) {
|
|
689
|
+
return;
|
|
690
|
+
}
|
|
691
|
+
|
|
631
692
|
// It is possible to receive two events here, one Mouse event and one Pointer event.
|
|
632
693
|
// When used in the ImageHotspots component the Pointer event can somehow be from a
|
|
633
694
|
// previously clicked hotspot. See https://github.com/carbon-design-system/carbon-addons-iot-react/issues/1803
|
|
@@ -636,6 +697,108 @@ var ImageHotspots = function ImageHotspots(_ref9) {
|
|
|
636
697
|
onSelectHotspot(position);
|
|
637
698
|
}
|
|
638
699
|
}, [onSelectHotspot, isEditable]);
|
|
700
|
+
var handleMouseDownHotspot = useCallback(function (e, id1) {
|
|
701
|
+
var hotspot = editableHotspots.find(function (h) {
|
|
702
|
+
return h.id === id1;
|
|
703
|
+
});
|
|
704
|
+
if (!isEditable || (hotspot === null || hotspot === void 0 ? void 0 : hotspot.type) === 'dynamic') {
|
|
705
|
+
return;
|
|
706
|
+
}
|
|
707
|
+
e.stopPropagation();
|
|
708
|
+
setDraggingHotspotId(id1);
|
|
709
|
+
dragStateRef.current.isDragging = true;
|
|
710
|
+
dragStateRef.current.dragStartPosition = {
|
|
711
|
+
x: e.clientX,
|
|
712
|
+
y: e.clientY
|
|
713
|
+
};
|
|
714
|
+
|
|
715
|
+
// Calculate layout once at drag start
|
|
716
|
+
if (containerRef.current) {
|
|
717
|
+
var rect = containerRef.current.getBoundingClientRect();
|
|
718
|
+
var hotspotLayout = calculateHotspotContainerLayout(image, container, displayOption);
|
|
719
|
+
dragStateRef.current.layout = {
|
|
720
|
+
rect: rect,
|
|
721
|
+
hotspotLayout: hotspotLayout
|
|
722
|
+
};
|
|
723
|
+
}
|
|
724
|
+
}, [container, displayOption, image, isEditable, editableHotspots]);
|
|
725
|
+
var handleMouseMoveHotspot = useCallback(function (e) {
|
|
726
|
+
if (draggingHotspotId !== null && containerRef.current) {
|
|
727
|
+
var _dragStateRef$current = dragStateRef.current,
|
|
728
|
+
isDragging = _dragStateRef$current.isDragging,
|
|
729
|
+
dragStartPosition = _dragStateRef$current.dragStartPosition,
|
|
730
|
+
layout = _dragStateRef$current.layout;
|
|
731
|
+
var dx = e.clientX - dragStartPosition.x;
|
|
732
|
+
var dy = e.clientY - dragStartPosition.y;
|
|
733
|
+
var distance = Math.sqrt(dx * dx + dy * dy);
|
|
734
|
+
if (distance > DRAG_THRESHOLD && isDragging) {
|
|
735
|
+
var rect = layout.rect,
|
|
736
|
+
hotspotLayout = layout.hotspotLayout;
|
|
737
|
+
var x = (e.clientX - rect.left - hotspotLayout.left) / hotspotLayout.width * 100;
|
|
738
|
+
var y = (e.clientY - rect.top - hotspotLayout.top) / hotspotLayout.height * 100;
|
|
739
|
+
// Clamp within image boundaries
|
|
740
|
+
x = Math.max(0, Math.min(100, x));
|
|
741
|
+
y = Math.max(0, Math.min(100, y));
|
|
742
|
+
dragStateRef.current.currentDargPosition = {
|
|
743
|
+
x: x,
|
|
744
|
+
y: y
|
|
745
|
+
};
|
|
746
|
+
|
|
747
|
+
// throttle with requestAnimationFrame
|
|
748
|
+
if (dragStateRef.current.frame === null) {
|
|
749
|
+
dragStateRef.current.frame = requestAnimationFrame(function () {
|
|
750
|
+
setEditableHotspots(function (prev) {
|
|
751
|
+
return prev.map(function (item) {
|
|
752
|
+
return item.id === draggingHotspotId ? _objectSpread(_objectSpread({}, item), {}, {
|
|
753
|
+
x: dragStateRef.current.currentDargPosition.x,
|
|
754
|
+
y: dragStateRef.current.currentDargPosition.y
|
|
755
|
+
}) : item;
|
|
756
|
+
});
|
|
757
|
+
});
|
|
758
|
+
dragStateRef.current.frame = null;
|
|
759
|
+
});
|
|
760
|
+
}
|
|
761
|
+
}
|
|
762
|
+
}
|
|
763
|
+
}, [draggingHotspotId]);
|
|
764
|
+
var handleMouseUpHotspot = useCallback(function (e) {
|
|
765
|
+
if (draggingHotspotId !== null && dragStateRef.current.isDragging) {
|
|
766
|
+
e.stopPropagation();
|
|
767
|
+
var _ref10 = dragStateRef.current.currentDargPosition || {},
|
|
768
|
+
x = _ref10.x,
|
|
769
|
+
y = _ref10.y;
|
|
770
|
+
onUpdateHotspotPosition({
|
|
771
|
+
newHotspots: editableHotspots,
|
|
772
|
+
position: {
|
|
773
|
+
x: x,
|
|
774
|
+
y: y
|
|
775
|
+
}
|
|
776
|
+
});
|
|
777
|
+
setDraggingHotspotId(null);
|
|
778
|
+
dragStateRef.current.currentDargPosition = null;
|
|
779
|
+
dragStateRef.current.isDragging = false;
|
|
780
|
+
}
|
|
781
|
+
}, [editableHotspots, draggingHotspotId, onUpdateHotspotPosition]);
|
|
782
|
+
useEffect(function () {
|
|
783
|
+
var dragState = dragStateRef.current;
|
|
784
|
+
return function () {
|
|
785
|
+
if (dragState.frame !== null) {
|
|
786
|
+
cancelAnimationFrame(dragState.frame);
|
|
787
|
+
}
|
|
788
|
+
};
|
|
789
|
+
}, []);
|
|
790
|
+
|
|
791
|
+
// Listens to mouse movement for dragging hotspot
|
|
792
|
+
useEffect(function () {
|
|
793
|
+
if (!isEditable) return undefined;
|
|
794
|
+
var containerElement = containerRef.current;
|
|
795
|
+
containerElement.addEventListener('mousemove', handleMouseMoveHotspot);
|
|
796
|
+
containerElement.addEventListener('mouseup', handleMouseUpHotspot);
|
|
797
|
+
return function () {
|
|
798
|
+
containerElement.removeEventListener('mousemove', handleMouseMoveHotspot);
|
|
799
|
+
containerElement.removeEventListener('mouseup', handleMouseUpHotspot);
|
|
800
|
+
};
|
|
801
|
+
}, [draggingHotspotId, handleMouseMoveHotspot, handleMouseUpHotspot, isEditable]);
|
|
639
802
|
var getIconRenderFunction = useCallback(function () {
|
|
640
803
|
return renderIconByName || (Array.isArray(icons) ? function (name, props) {
|
|
641
804
|
var _icons$find;
|
|
@@ -654,7 +817,7 @@ var ImageHotspots = function ImageHotspots(_ref9) {
|
|
|
654
817
|
|
|
655
818
|
// Performance improvement
|
|
656
819
|
var cachedHotspots = useMemo(function () {
|
|
657
|
-
return
|
|
820
|
+
return editableHotspots.map(function (hotspot, index) {
|
|
658
821
|
var _hotspot$content;
|
|
659
822
|
var x = hotspot.x,
|
|
660
823
|
y = hotspot.y;
|
|
@@ -664,10 +827,10 @@ var ImageHotspots = function ImageHotspots(_ref9) {
|
|
|
664
827
|
// Determine whether the icon needs to be dynamically overridden by a threshold
|
|
665
828
|
var matchingAttributeThresholds = [];
|
|
666
829
|
if ((_hotspot$content = hotspot.content) !== null && _hotspot$content !== void 0 && _hotspot$content.attributes) {
|
|
667
|
-
hotspot.content.attributes.forEach(function (
|
|
830
|
+
hotspot.content.attributes.forEach(function (_ref11) {
|
|
668
831
|
var _hotspot$content2;
|
|
669
|
-
var thresholds =
|
|
670
|
-
dataSourceId =
|
|
832
|
+
var thresholds = _ref11.thresholds,
|
|
833
|
+
dataSourceId = _ref11.dataSourceId;
|
|
671
834
|
if (!isEmpty(thresholds) && !isEmpty((_hotspot$content2 = hotspot.content) === null || _hotspot$content2 === void 0 ? void 0 : _hotspot$content2.values)) {
|
|
672
835
|
var _hotspot$content3;
|
|
673
836
|
var attributeThresholds = findMatchingThresholds(thresholds.map(function (threshold) {
|
|
@@ -693,10 +856,13 @@ var ImageHotspots = function ImageHotspots(_ref9) {
|
|
|
693
856
|
key: "".concat(x, "-").concat(y, "-").concat(index),
|
|
694
857
|
renderIconByName: getIconRenderFunction(),
|
|
695
858
|
isSelected: hotspotIsSelected,
|
|
696
|
-
onClick: onHotspotClicked
|
|
859
|
+
onClick: onHotspotClicked,
|
|
860
|
+
onMouseDown: function onMouseDown(e) {
|
|
861
|
+
return handleMouseDownHotspot(e, hotspot.id);
|
|
862
|
+
}
|
|
697
863
|
}));
|
|
698
864
|
});
|
|
699
|
-
}, [
|
|
865
|
+
}, [editableHotspots, selectedHotspots, locale, getIconRenderFunction, isEditable, onHotspotContentChanged, mergedI18n, onHotspotClicked, handleMouseDownHotspot]);
|
|
700
866
|
var hotspotsStyle = {
|
|
701
867
|
position: 'absolute',
|
|
702
868
|
left: image.offsetX,
|
|
@@ -739,7 +905,8 @@ var ImageHotspots = function ImageHotspots(_ref9) {
|
|
|
739
905
|
// If we leave the container, stop detecting the drag
|
|
740
906
|
stopDrag(cursor, setCursor);
|
|
741
907
|
}
|
|
742
|
-
}
|
|
908
|
+
},
|
|
909
|
+
ref: containerRef
|
|
743
910
|
}, src ? /*#__PURE__*/React__default.createElement("img", {
|
|
744
911
|
id: id,
|
|
745
912
|
className: "".concat(iotPrefix, "--image-card-img"),
|
|
@@ -966,6 +1133,17 @@ ImageHotspots.__docgenInfo = {
|
|
|
966
1133
|
},
|
|
967
1134
|
"required": false
|
|
968
1135
|
},
|
|
1136
|
+
"onUpdateHotspotPosition": {
|
|
1137
|
+
"defaultValue": {
|
|
1138
|
+
"value": "() => {}",
|
|
1139
|
+
"computed": false
|
|
1140
|
+
},
|
|
1141
|
+
"description": "Callback when a hotspot is dragged to new position in isEditable mode\nEmits new hotspots and updated position obj {x, y} of hotspot.",
|
|
1142
|
+
"type": {
|
|
1143
|
+
"name": "func"
|
|
1144
|
+
},
|
|
1145
|
+
"required": false
|
|
1146
|
+
},
|
|
969
1147
|
"onSelectHotspot": {
|
|
970
1148
|
"defaultValue": {
|
|
971
1149
|
"value": "() => {}",
|
|
@@ -332,6 +332,7 @@ var HotspotEditorModal = function HotspotEditorModal(_ref) {
|
|
|
332
332
|
switchCurrentType = _useHotspotEditorStat.switchCurrentType,
|
|
333
333
|
updateHotspotDataSource = _useHotspotEditorStat.updateHotspotDataSource,
|
|
334
334
|
updateHotspotTooltip = _useHotspotEditorStat.updateHotspotTooltip,
|
|
335
|
+
updateHotspotPosition = _useHotspotEditorStat.updateHotspotPosition,
|
|
335
336
|
updateTextHotspotStyle = _useHotspotEditorStat.updateTextHotspotStyle,
|
|
336
337
|
updateTextHotspotContent = _useHotspotEditorStat.updateTextHotspotContent,
|
|
337
338
|
updateDynamicHotspotSourceX = _useHotspotEditorStat.updateDynamicHotspotSourceX,
|
|
@@ -397,6 +398,8 @@ var HotspotEditorModal = function HotspotEditorModal(_ref) {
|
|
|
397
398
|
}
|
|
398
399
|
var hotspotsWithoutExampleValues = filteredHotspots.map(function (hotspot) {
|
|
399
400
|
return update__default.default(hotspot, {
|
|
401
|
+
$unset: ['id'],
|
|
402
|
+
// Remove the internal id added for drag tracking
|
|
400
403
|
content: {
|
|
401
404
|
$unset: ['values']
|
|
402
405
|
}
|
|
@@ -646,6 +649,7 @@ var HotspotEditorModal = function HotspotEditorModal(_ref) {
|
|
|
646
649
|
hotspotDefaults: hotspotDefaults
|
|
647
650
|
});
|
|
648
651
|
},
|
|
652
|
+
onUpdateHotspotPosition: updateHotspotPosition,
|
|
649
653
|
onSelectHotspot: setSelectedHotspot,
|
|
650
654
|
selectedHotspots: getSelectedHotspotsList(selectedHotspot, hotspots),
|
|
651
655
|
src: cardConfig.content.src,
|
|
@@ -77,6 +77,7 @@ var hotspotActionTypes = {
|
|
|
77
77
|
hotspotDataSourceChange: 'HOTSPOT_DATA_SOURCE_CHANGE',
|
|
78
78
|
hotspotDataSourceSettingsChange: 'HOTSPOT_DATA_SOURCE_SETTINGS_CHANGE',
|
|
79
79
|
hotspotTooltipChange: 'HOTSPOT_TOOLTIP_CHANGE',
|
|
80
|
+
hotspotPositionChange: 'HOTSPOT_POSITION_CHANGE',
|
|
80
81
|
hotspotSelect: 'HOTSPOT_SELECT',
|
|
81
82
|
hotspotsAdd: 'HOTSPOTS_ADD',
|
|
82
83
|
textHotspotStyleChange: 'TEXT_HOTSPOT_STYLE_CHANGE',
|
|
@@ -179,10 +180,32 @@ function hotspotEditorReducer(state, _ref2) {
|
|
|
179
180
|
};
|
|
180
181
|
return getHotspotUpdate(state, _mergeSpec);
|
|
181
182
|
}
|
|
183
|
+
// HOTSPOT POSITION CHANGE
|
|
184
|
+
case hotspotActionTypes.hotspotPositionChange:
|
|
185
|
+
{
|
|
186
|
+
var isPositionAvailable = !state.hotspots.find(function (hotspot) {
|
|
187
|
+
return isHotspotMatch(hotspot, payload.position);
|
|
188
|
+
});
|
|
189
|
+
if (isPositionAvailable) {
|
|
190
|
+
// Find the updated hotspot in the new hotspots array to maintain selection
|
|
191
|
+
var updatedSelectedHotspot = payload.newHotspots.find(function (hotspot) {
|
|
192
|
+
return isHotspotMatch(hotspot, payload.position);
|
|
193
|
+
});
|
|
194
|
+
return update__default.default(state, {
|
|
195
|
+
hotspots: {
|
|
196
|
+
$set: payload.newHotspots
|
|
197
|
+
},
|
|
198
|
+
selectedHotspot: {
|
|
199
|
+
$set: updatedSelectedHotspot
|
|
200
|
+
}
|
|
201
|
+
});
|
|
202
|
+
}
|
|
203
|
+
return state;
|
|
204
|
+
}
|
|
182
205
|
// HOTSPOTS ADD
|
|
183
206
|
case hotspotActionTypes.hotspotsAdd:
|
|
184
207
|
{
|
|
185
|
-
var
|
|
208
|
+
var _isPositionAvailable = !state.hotspots.find(function (hotspot) {
|
|
186
209
|
return isHotspotMatch(hotspot, payload.position);
|
|
187
210
|
});
|
|
188
211
|
var defaultContent = state.currentType === hotspotTypes.TEXT ? {
|
|
@@ -193,7 +216,7 @@ function hotspotEditorReducer(state, _ref2) {
|
|
|
193
216
|
content: defaultContent,
|
|
194
217
|
type: createableType
|
|
195
218
|
});
|
|
196
|
-
return
|
|
219
|
+
return _isPositionAvailable ? update__default.default(state, {
|
|
197
220
|
selectedHotspot: {
|
|
198
221
|
$set: newHotspot
|
|
199
222
|
},
|
|
@@ -221,7 +244,7 @@ function hotspotEditorReducer(state, _ref2) {
|
|
|
221
244
|
$set: hotspot
|
|
222
245
|
},
|
|
223
246
|
currentType: {
|
|
224
|
-
$set: (_hotspot$type = hotspot.type) !== null && _hotspot$type !== void 0 ? _hotspot$type : defaultTypeWhenMissing
|
|
247
|
+
$set: (_hotspot$type = hotspot === null || hotspot === void 0 ? void 0 : hotspot.type) !== null && _hotspot$type !== void 0 ? _hotspot$type : defaultTypeWhenMissing
|
|
225
248
|
}
|
|
226
249
|
});
|
|
227
250
|
}
|
|
@@ -420,6 +443,12 @@ function useHotspotEditorState() {
|
|
|
420
443
|
payload: hotspotContent
|
|
421
444
|
});
|
|
422
445
|
};
|
|
446
|
+
var updateHotspotPosition = function updateHotspotPosition(hotspotPosition) {
|
|
447
|
+
return dispatch({
|
|
448
|
+
type: hotspotActionTypes.hotspotPositionChange,
|
|
449
|
+
payload: hotspotPosition
|
|
450
|
+
});
|
|
451
|
+
};
|
|
423
452
|
|
|
424
453
|
/** Updates the properties of the text hotspot, passes a payload like {color: 'blue'} */
|
|
425
454
|
var updateTextHotspotStyle = function updateTextHotspotStyle(textHotspotStyle) {
|
|
@@ -507,6 +536,7 @@ function useHotspotEditorState() {
|
|
|
507
536
|
switchCurrentType: switchCurrentType,
|
|
508
537
|
updateHotspotDataSource: updateHotspotDataSource,
|
|
509
538
|
updateHotspotTooltip: updateHotspotTooltip,
|
|
539
|
+
updateHotspotPosition: updateHotspotPosition,
|
|
510
540
|
updateTextHotspotStyle: updateTextHotspotStyle,
|
|
511
541
|
updateTextHotspotContent: updateTextHotspotContent,
|
|
512
542
|
updateDynamicHotspotSourceX: updateDynamicHotspotSourceX,
|
|
@@ -182,7 +182,7 @@ var HotspotContent = function HotspotContent(_ref) {
|
|
|
182
182
|
}, typeof value === 'number' ? cardUtilityFunctions.formatNumberWithPrecision(value, !isNil(precision) ? precision : Math.abs(value) < 1 ? value === 0 ? 0 : 3 // for small decimals give 3 spots
|
|
183
183
|
: 1,
|
|
184
184
|
// otherwise 1 spot if precision isn't set
|
|
185
|
-
locale) : value, unit && value !== '--' && /*#__PURE__*/React__default.default.createElement("span", {
|
|
185
|
+
locale) : typeof value === 'boolean' ? String(value) : value, unit && value !== '--' && /*#__PURE__*/React__default.default.createElement("span", {
|
|
186
186
|
className: "".concat(iotPrefix, "--hotspot-content-unit")
|
|
187
187
|
}, unit))));
|
|
188
188
|
}));
|
|
@@ -89,6 +89,10 @@ var propTypes = {
|
|
|
89
89
|
* Emits position obj {x, y} of hotspot to be added.
|
|
90
90
|
*/
|
|
91
91
|
onAddHotspotPosition: PropTypes__default.default.func,
|
|
92
|
+
/** Callback when a hotspot is dragged to new position in isEditable mode
|
|
93
|
+
* Emits new hotspots and updated position obj {x, y} of hotspot.
|
|
94
|
+
*/
|
|
95
|
+
onUpdateHotspotPosition: PropTypes__default.default.func,
|
|
92
96
|
/** Callback when a hotspot is clicked in isEditable mode, emits position obj {x, y} */
|
|
93
97
|
onSelectHotspot: PropTypes__default.default.func,
|
|
94
98
|
/**
|
|
@@ -129,6 +133,7 @@ var defaultProps = {
|
|
|
129
133
|
isHotspotDataLoading: false,
|
|
130
134
|
isEditable: false,
|
|
131
135
|
onAddHotspotPosition: function onAddHotspotPosition() {},
|
|
136
|
+
onUpdateHotspotPosition: function onUpdateHotspotPosition() {},
|
|
132
137
|
onSelectHotspot: function onSelectHotspot() {},
|
|
133
138
|
onHotspotContentChanged: function onHotspotContentChanged() {},
|
|
134
139
|
background: '#eee',
|
|
@@ -247,6 +252,7 @@ var calculateHotspotContainerLayout = function calculateHotspotContainerLayout(_
|
|
|
247
252
|
var width;
|
|
248
253
|
var height;
|
|
249
254
|
var top;
|
|
255
|
+
var left;
|
|
250
256
|
|
|
251
257
|
// CONTAIN
|
|
252
258
|
if (objectFit === 'contain') {
|
|
@@ -254,32 +260,38 @@ var calculateHotspotContainerLayout = function calculateHotspotContainerLayout(_
|
|
|
254
260
|
width = imageWidth;
|
|
255
261
|
height = imageWidth / imageRatio;
|
|
256
262
|
top = imageScale > 1 ? imageOffsetY : imageObjectFitOffsetY;
|
|
263
|
+
left = imageScale > 1 ? 0 : (containerWidth - imageWidth) / 2;
|
|
257
264
|
} else if (imageOrientation === 'portrait') {
|
|
258
265
|
width = imageHeight / imageRatio;
|
|
259
266
|
height = imageHeight;
|
|
260
267
|
top = imageOffsetY;
|
|
268
|
+
left = (containerWidth - width) / 2;
|
|
261
269
|
}
|
|
262
270
|
// FILL
|
|
263
271
|
} else if (objectFit === 'fill') {
|
|
264
272
|
width = imageScale > 1 ? imageWidth : containerWidth;
|
|
265
273
|
height = imageScale > 1 ? imageHeight : containerHeight;
|
|
266
274
|
top = imageOffsetY;
|
|
275
|
+
left = 0;
|
|
267
276
|
// NO OBJECT FIT
|
|
268
277
|
} else if (!objectFit) {
|
|
269
278
|
if (imageOrientation === 'landscape') {
|
|
270
279
|
width = imageWidth;
|
|
271
280
|
height = imageWidth / imageRatio;
|
|
272
281
|
top = imageOffsetY;
|
|
282
|
+
left = 0;
|
|
273
283
|
} else if (imageOrientation === 'portrait') {
|
|
274
284
|
width = imageHeight / imageRatio;
|
|
275
285
|
height = imageHeight;
|
|
276
286
|
top = imageOffsetY;
|
|
287
|
+
left = (containerWidth - width) / 2;
|
|
277
288
|
}
|
|
278
289
|
}
|
|
279
290
|
return {
|
|
280
291
|
width: width,
|
|
281
292
|
height: height,
|
|
282
|
-
top: top
|
|
293
|
+
top: top,
|
|
294
|
+
left: left
|
|
283
295
|
};
|
|
284
296
|
};
|
|
285
297
|
var calculateObjectFitOffset = function calculateObjectFitOffset(_ref5) {
|
|
@@ -524,6 +536,7 @@ var ImageHotspots = function ImageHotspots(_ref9) {
|
|
|
524
536
|
isEditable = _ref9.isEditable,
|
|
525
537
|
isHotspotDataLoading = _ref9.isHotspotDataLoading,
|
|
526
538
|
onAddHotspotPosition = _ref9.onAddHotspotPosition,
|
|
539
|
+
onUpdateHotspotPosition = _ref9.onUpdateHotspotPosition,
|
|
527
540
|
onSelectHotspot = _ref9.onSelectHotspot,
|
|
528
541
|
onHotspotContentChanged = _ref9.onHotspotContentChanged,
|
|
529
542
|
zoomMax = _ref9.zoomMax,
|
|
@@ -568,9 +581,52 @@ var ImageHotspots = function ImageHotspots(_ref9) {
|
|
|
568
581
|
_useState12 = _slicedToArray__default.default(_useState11, 2),
|
|
569
582
|
options = _useState12[0],
|
|
570
583
|
setOptions = _useState12[1];
|
|
584
|
+
// Tracks if a hotspot is being dragged and which one.
|
|
585
|
+
var _useState13 = React.useState(null),
|
|
586
|
+
_useState14 = _slicedToArray__default.default(_useState13, 2),
|
|
587
|
+
draggingHotspotId = _useState14[0],
|
|
588
|
+
setDraggingHotspotId = _useState14[1];
|
|
589
|
+
|
|
590
|
+
// Ref for outer container
|
|
591
|
+
var containerRef = React.useRef(null);
|
|
592
|
+
var dragStateRef = React.useRef({
|
|
593
|
+
// Flag to indicate if a drag is active
|
|
594
|
+
isDragging: false,
|
|
595
|
+
// Stores the starting mouse position of a drag
|
|
596
|
+
dragStartPosition: {
|
|
597
|
+
x: 0,
|
|
598
|
+
y: 0
|
|
599
|
+
},
|
|
600
|
+
// Tracks the current position during a drag
|
|
601
|
+
currentDargPosition: null,
|
|
602
|
+
// Stores layout of image and container
|
|
603
|
+
layout: {
|
|
604
|
+
rect: null,
|
|
605
|
+
hotspotLayout: null
|
|
606
|
+
},
|
|
607
|
+
// Tracks Scheduled Animation Frames
|
|
608
|
+
frame: null
|
|
609
|
+
});
|
|
610
|
+
|
|
611
|
+
// Minimum pixel movement before a drag is initiated
|
|
612
|
+
var DRAG_THRESHOLD = 5;
|
|
571
613
|
var mergedI18n = React.useMemo(function () {
|
|
572
614
|
return _objectSpread(_objectSpread({}, defaultProps.i18n), i18n);
|
|
573
615
|
}, [i18n]);
|
|
616
|
+
var hotspotsWithId = React.useMemo(function () {
|
|
617
|
+
return hotspots.map(function (hotspot, index) {
|
|
618
|
+
return _objectSpread(_objectSpread({}, hotspot), {}, {
|
|
619
|
+
id: "".concat(hotspot.x, "-").concat(hotspot.y, "-").concat(index)
|
|
620
|
+
});
|
|
621
|
+
});
|
|
622
|
+
}, [hotspots]);
|
|
623
|
+
var _useState15 = React.useState(hotspotsWithId),
|
|
624
|
+
_useState16 = _slicedToArray__default.default(_useState15, 2),
|
|
625
|
+
editableHotspots = _useState16[0],
|
|
626
|
+
setEditableHotspots = _useState16[1];
|
|
627
|
+
React.useEffect(function () {
|
|
628
|
+
setEditableHotspots(hotspotsWithId);
|
|
629
|
+
}, [hotspotsWithId]);
|
|
574
630
|
var handleCtrlKeyUp = React.useCallback(function (event) {
|
|
575
631
|
// Was the control key unpressed
|
|
576
632
|
if (event.key === KeyCodeConstants.keyboardKeys.CONTROL) {
|
|
@@ -642,6 +698,11 @@ var ImageHotspots = function ImageHotspots(_ref9) {
|
|
|
642
698
|
objectFit: displayOption
|
|
643
699
|
};
|
|
644
700
|
var onHotspotClicked = React.useCallback(function (evt, position) {
|
|
701
|
+
// prevent click behavior after drag
|
|
702
|
+
if (dragStateRef.current.isDragging) {
|
|
703
|
+
return;
|
|
704
|
+
}
|
|
705
|
+
|
|
645
706
|
// It is possible to receive two events here, one Mouse event and one Pointer event.
|
|
646
707
|
// When used in the ImageHotspots component the Pointer event can somehow be from a
|
|
647
708
|
// previously clicked hotspot. See https://github.com/carbon-design-system/carbon-addons-iot-react/issues/1803
|
|
@@ -650,6 +711,108 @@ var ImageHotspots = function ImageHotspots(_ref9) {
|
|
|
650
711
|
onSelectHotspot(position);
|
|
651
712
|
}
|
|
652
713
|
}, [onSelectHotspot, isEditable]);
|
|
714
|
+
var handleMouseDownHotspot = React.useCallback(function (e, id1) {
|
|
715
|
+
var hotspot = editableHotspots.find(function (h) {
|
|
716
|
+
return h.id === id1;
|
|
717
|
+
});
|
|
718
|
+
if (!isEditable || (hotspot === null || hotspot === void 0 ? void 0 : hotspot.type) === 'dynamic') {
|
|
719
|
+
return;
|
|
720
|
+
}
|
|
721
|
+
e.stopPropagation();
|
|
722
|
+
setDraggingHotspotId(id1);
|
|
723
|
+
dragStateRef.current.isDragging = true;
|
|
724
|
+
dragStateRef.current.dragStartPosition = {
|
|
725
|
+
x: e.clientX,
|
|
726
|
+
y: e.clientY
|
|
727
|
+
};
|
|
728
|
+
|
|
729
|
+
// Calculate layout once at drag start
|
|
730
|
+
if (containerRef.current) {
|
|
731
|
+
var rect = containerRef.current.getBoundingClientRect();
|
|
732
|
+
var hotspotLayout = calculateHotspotContainerLayout(image, container, displayOption);
|
|
733
|
+
dragStateRef.current.layout = {
|
|
734
|
+
rect: rect,
|
|
735
|
+
hotspotLayout: hotspotLayout
|
|
736
|
+
};
|
|
737
|
+
}
|
|
738
|
+
}, [container, displayOption, image, isEditable, editableHotspots]);
|
|
739
|
+
var handleMouseMoveHotspot = React.useCallback(function (e) {
|
|
740
|
+
if (draggingHotspotId !== null && containerRef.current) {
|
|
741
|
+
var _dragStateRef$current = dragStateRef.current,
|
|
742
|
+
isDragging = _dragStateRef$current.isDragging,
|
|
743
|
+
dragStartPosition = _dragStateRef$current.dragStartPosition,
|
|
744
|
+
layout = _dragStateRef$current.layout;
|
|
745
|
+
var dx = e.clientX - dragStartPosition.x;
|
|
746
|
+
var dy = e.clientY - dragStartPosition.y;
|
|
747
|
+
var distance = Math.sqrt(dx * dx + dy * dy);
|
|
748
|
+
if (distance > DRAG_THRESHOLD && isDragging) {
|
|
749
|
+
var rect = layout.rect,
|
|
750
|
+
hotspotLayout = layout.hotspotLayout;
|
|
751
|
+
var x = (e.clientX - rect.left - hotspotLayout.left) / hotspotLayout.width * 100;
|
|
752
|
+
var y = (e.clientY - rect.top - hotspotLayout.top) / hotspotLayout.height * 100;
|
|
753
|
+
// Clamp within image boundaries
|
|
754
|
+
x = Math.max(0, Math.min(100, x));
|
|
755
|
+
y = Math.max(0, Math.min(100, y));
|
|
756
|
+
dragStateRef.current.currentDargPosition = {
|
|
757
|
+
x: x,
|
|
758
|
+
y: y
|
|
759
|
+
};
|
|
760
|
+
|
|
761
|
+
// throttle with requestAnimationFrame
|
|
762
|
+
if (dragStateRef.current.frame === null) {
|
|
763
|
+
dragStateRef.current.frame = requestAnimationFrame(function () {
|
|
764
|
+
setEditableHotspots(function (prev) {
|
|
765
|
+
return prev.map(function (item) {
|
|
766
|
+
return item.id === draggingHotspotId ? _objectSpread(_objectSpread({}, item), {}, {
|
|
767
|
+
x: dragStateRef.current.currentDargPosition.x,
|
|
768
|
+
y: dragStateRef.current.currentDargPosition.y
|
|
769
|
+
}) : item;
|
|
770
|
+
});
|
|
771
|
+
});
|
|
772
|
+
dragStateRef.current.frame = null;
|
|
773
|
+
});
|
|
774
|
+
}
|
|
775
|
+
}
|
|
776
|
+
}
|
|
777
|
+
}, [draggingHotspotId]);
|
|
778
|
+
var handleMouseUpHotspot = React.useCallback(function (e) {
|
|
779
|
+
if (draggingHotspotId !== null && dragStateRef.current.isDragging) {
|
|
780
|
+
e.stopPropagation();
|
|
781
|
+
var _ref10 = dragStateRef.current.currentDargPosition || {},
|
|
782
|
+
x = _ref10.x,
|
|
783
|
+
y = _ref10.y;
|
|
784
|
+
onUpdateHotspotPosition({
|
|
785
|
+
newHotspots: editableHotspots,
|
|
786
|
+
position: {
|
|
787
|
+
x: x,
|
|
788
|
+
y: y
|
|
789
|
+
}
|
|
790
|
+
});
|
|
791
|
+
setDraggingHotspotId(null);
|
|
792
|
+
dragStateRef.current.currentDargPosition = null;
|
|
793
|
+
dragStateRef.current.isDragging = false;
|
|
794
|
+
}
|
|
795
|
+
}, [editableHotspots, draggingHotspotId, onUpdateHotspotPosition]);
|
|
796
|
+
React.useEffect(function () {
|
|
797
|
+
var dragState = dragStateRef.current;
|
|
798
|
+
return function () {
|
|
799
|
+
if (dragState.frame !== null) {
|
|
800
|
+
cancelAnimationFrame(dragState.frame);
|
|
801
|
+
}
|
|
802
|
+
};
|
|
803
|
+
}, []);
|
|
804
|
+
|
|
805
|
+
// Listens to mouse movement for dragging hotspot
|
|
806
|
+
React.useEffect(function () {
|
|
807
|
+
if (!isEditable) return undefined;
|
|
808
|
+
var containerElement = containerRef.current;
|
|
809
|
+
containerElement.addEventListener('mousemove', handleMouseMoveHotspot);
|
|
810
|
+
containerElement.addEventListener('mouseup', handleMouseUpHotspot);
|
|
811
|
+
return function () {
|
|
812
|
+
containerElement.removeEventListener('mousemove', handleMouseMoveHotspot);
|
|
813
|
+
containerElement.removeEventListener('mouseup', handleMouseUpHotspot);
|
|
814
|
+
};
|
|
815
|
+
}, [draggingHotspotId, handleMouseMoveHotspot, handleMouseUpHotspot, isEditable]);
|
|
653
816
|
var getIconRenderFunction = React.useCallback(function () {
|
|
654
817
|
return renderIconByName || (Array.isArray(icons) ? function (name, props) {
|
|
655
818
|
var _icons$find;
|
|
@@ -668,7 +831,7 @@ var ImageHotspots = function ImageHotspots(_ref9) {
|
|
|
668
831
|
|
|
669
832
|
// Performance improvement
|
|
670
833
|
var cachedHotspots = React.useMemo(function () {
|
|
671
|
-
return
|
|
834
|
+
return editableHotspots.map(function (hotspot, index) {
|
|
672
835
|
var _hotspot$content;
|
|
673
836
|
var x = hotspot.x,
|
|
674
837
|
y = hotspot.y;
|
|
@@ -678,10 +841,10 @@ var ImageHotspots = function ImageHotspots(_ref9) {
|
|
|
678
841
|
// Determine whether the icon needs to be dynamically overridden by a threshold
|
|
679
842
|
var matchingAttributeThresholds = [];
|
|
680
843
|
if ((_hotspot$content = hotspot.content) !== null && _hotspot$content !== void 0 && _hotspot$content.attributes) {
|
|
681
|
-
hotspot.content.attributes.forEach(function (
|
|
844
|
+
hotspot.content.attributes.forEach(function (_ref11) {
|
|
682
845
|
var _hotspot$content2;
|
|
683
|
-
var thresholds =
|
|
684
|
-
dataSourceId =
|
|
846
|
+
var thresholds = _ref11.thresholds,
|
|
847
|
+
dataSourceId = _ref11.dataSourceId;
|
|
685
848
|
if (!isEmpty(thresholds) && !isEmpty((_hotspot$content2 = hotspot.content) === null || _hotspot$content2 === void 0 ? void 0 : _hotspot$content2.values)) {
|
|
686
849
|
var _hotspot$content3;
|
|
687
850
|
var attributeThresholds = cardUtilityFunctions.findMatchingThresholds(thresholds.map(function (threshold) {
|
|
@@ -707,10 +870,13 @@ var ImageHotspots = function ImageHotspots(_ref9) {
|
|
|
707
870
|
key: "".concat(x, "-").concat(y, "-").concat(index),
|
|
708
871
|
renderIconByName: getIconRenderFunction(),
|
|
709
872
|
isSelected: hotspotIsSelected,
|
|
710
|
-
onClick: onHotspotClicked
|
|
873
|
+
onClick: onHotspotClicked,
|
|
874
|
+
onMouseDown: function onMouseDown(e) {
|
|
875
|
+
return handleMouseDownHotspot(e, hotspot.id);
|
|
876
|
+
}
|
|
711
877
|
}));
|
|
712
878
|
});
|
|
713
|
-
}, [
|
|
879
|
+
}, [editableHotspots, selectedHotspots, locale, getIconRenderFunction, isEditable, onHotspotContentChanged, mergedI18n, onHotspotClicked, handleMouseDownHotspot]);
|
|
714
880
|
var hotspotsStyle = {
|
|
715
881
|
position: 'absolute',
|
|
716
882
|
left: image.offsetX,
|
|
@@ -753,7 +919,8 @@ var ImageHotspots = function ImageHotspots(_ref9) {
|
|
|
753
919
|
// If we leave the container, stop detecting the drag
|
|
754
920
|
stopDrag(cursor, setCursor);
|
|
755
921
|
}
|
|
756
|
-
}
|
|
922
|
+
},
|
|
923
|
+
ref: containerRef
|
|
757
924
|
}, src ? /*#__PURE__*/React__default.default.createElement("img", {
|
|
758
925
|
id: id,
|
|
759
926
|
className: "".concat(iotPrefix, "--image-card-img"),
|
|
@@ -980,6 +1147,17 @@ ImageHotspots.__docgenInfo = {
|
|
|
980
1147
|
},
|
|
981
1148
|
"required": false
|
|
982
1149
|
},
|
|
1150
|
+
"onUpdateHotspotPosition": {
|
|
1151
|
+
"defaultValue": {
|
|
1152
|
+
"value": "() => {}",
|
|
1153
|
+
"computed": false
|
|
1154
|
+
},
|
|
1155
|
+
"description": "Callback when a hotspot is dragged to new position in isEditable mode\nEmits new hotspots and updated position obj {x, y} of hotspot.",
|
|
1156
|
+
"type": {
|
|
1157
|
+
"name": "func"
|
|
1158
|
+
},
|
|
1159
|
+
"required": false
|
|
1160
|
+
},
|
|
983
1161
|
"onSelectHotspot": {
|
|
984
1162
|
"defaultValue": {
|
|
985
1163
|
"value": "() => {}",
|
package/package.json
CHANGED
|
@@ -302625,7 +302625,7 @@ ${formatRule(Codicon.menuSubmenu)}
|
|
|
302625
302625
|
}, typeof value === 'number' ? formatNumberWithPrecision(value, !isNil(precision) ? precision : Math.abs(value) < 1 ? value === 0 ? 0 : 3 // for small decimals give 3 spots
|
|
302626
302626
|
: 1,
|
|
302627
302627
|
// otherwise 1 spot if precision isn't set
|
|
302628
|
-
locale) : value, unit && value !== '--' && /*#__PURE__*/React$1.createElement("span", {
|
|
302628
|
+
locale) : typeof value === 'boolean' ? String(value) : value, unit && value !== '--' && /*#__PURE__*/React$1.createElement("span", {
|
|
302629
302629
|
className: "".concat(iotPrefix$Z, "--hotspot-content-unit")
|
|
302630
302630
|
}, unit))));
|
|
302631
302631
|
}));
|
|
@@ -302766,6 +302766,10 @@ ${formatRule(Codicon.menuSubmenu)}
|
|
|
302766
302766
|
* Emits position obj {x, y} of hotspot to be added.
|
|
302767
302767
|
*/
|
|
302768
302768
|
onAddHotspotPosition: PropTypes.func,
|
|
302769
|
+
/** Callback when a hotspot is dragged to new position in isEditable mode
|
|
302770
|
+
* Emits new hotspots and updated position obj {x, y} of hotspot.
|
|
302771
|
+
*/
|
|
302772
|
+
onUpdateHotspotPosition: PropTypes.func,
|
|
302769
302773
|
/** Callback when a hotspot is clicked in isEditable mode, emits position obj {x, y} */
|
|
302770
302774
|
onSelectHotspot: PropTypes.func,
|
|
302771
302775
|
/**
|
|
@@ -302806,6 +302810,7 @@ ${formatRule(Codicon.menuSubmenu)}
|
|
|
302806
302810
|
isHotspotDataLoading: false,
|
|
302807
302811
|
isEditable: false,
|
|
302808
302812
|
onAddHotspotPosition: function onAddHotspotPosition() {},
|
|
302813
|
+
onUpdateHotspotPosition: function onUpdateHotspotPosition() {},
|
|
302809
302814
|
onSelectHotspot: function onSelectHotspot() {},
|
|
302810
302815
|
onHotspotContentChanged: function onHotspotContentChanged() {},
|
|
302811
302816
|
background: '#eee',
|
|
@@ -302924,6 +302929,7 @@ ${formatRule(Codicon.menuSubmenu)}
|
|
|
302924
302929
|
var width;
|
|
302925
302930
|
var height;
|
|
302926
302931
|
var top;
|
|
302932
|
+
var left;
|
|
302927
302933
|
|
|
302928
302934
|
// CONTAIN
|
|
302929
302935
|
if (objectFit === 'contain') {
|
|
@@ -302931,32 +302937,38 @@ ${formatRule(Codicon.menuSubmenu)}
|
|
|
302931
302937
|
width = imageWidth;
|
|
302932
302938
|
height = imageWidth / imageRatio;
|
|
302933
302939
|
top = imageScale > 1 ? imageOffsetY : imageObjectFitOffsetY;
|
|
302940
|
+
left = imageScale > 1 ? 0 : (containerWidth - imageWidth) / 2;
|
|
302934
302941
|
} else if (imageOrientation === 'portrait') {
|
|
302935
302942
|
width = imageHeight / imageRatio;
|
|
302936
302943
|
height = imageHeight;
|
|
302937
302944
|
top = imageOffsetY;
|
|
302945
|
+
left = (containerWidth - width) / 2;
|
|
302938
302946
|
}
|
|
302939
302947
|
// FILL
|
|
302940
302948
|
} else if (objectFit === 'fill') {
|
|
302941
302949
|
width = imageScale > 1 ? imageWidth : containerWidth;
|
|
302942
302950
|
height = imageScale > 1 ? imageHeight : containerHeight;
|
|
302943
302951
|
top = imageOffsetY;
|
|
302952
|
+
left = 0;
|
|
302944
302953
|
// NO OBJECT FIT
|
|
302945
302954
|
} else if (!objectFit) {
|
|
302946
302955
|
if (imageOrientation === 'landscape') {
|
|
302947
302956
|
width = imageWidth;
|
|
302948
302957
|
height = imageWidth / imageRatio;
|
|
302949
302958
|
top = imageOffsetY;
|
|
302959
|
+
left = 0;
|
|
302950
302960
|
} else if (imageOrientation === 'portrait') {
|
|
302951
302961
|
width = imageHeight / imageRatio;
|
|
302952
302962
|
height = imageHeight;
|
|
302953
302963
|
top = imageOffsetY;
|
|
302964
|
+
left = (containerWidth - width) / 2;
|
|
302954
302965
|
}
|
|
302955
302966
|
}
|
|
302956
302967
|
return {
|
|
302957
302968
|
width: width,
|
|
302958
302969
|
height: height,
|
|
302959
|
-
top: top
|
|
302970
|
+
top: top,
|
|
302971
|
+
left: left
|
|
302960
302972
|
};
|
|
302961
302973
|
};
|
|
302962
302974
|
var calculateObjectFitOffset = function calculateObjectFitOffset(_ref5) {
|
|
@@ -303201,6 +303213,7 @@ ${formatRule(Codicon.menuSubmenu)}
|
|
|
303201
303213
|
isEditable = _ref9.isEditable,
|
|
303202
303214
|
isHotspotDataLoading = _ref9.isHotspotDataLoading,
|
|
303203
303215
|
onAddHotspotPosition = _ref9.onAddHotspotPosition,
|
|
303216
|
+
onUpdateHotspotPosition = _ref9.onUpdateHotspotPosition,
|
|
303204
303217
|
onSelectHotspot = _ref9.onSelectHotspot,
|
|
303205
303218
|
onHotspotContentChanged = _ref9.onHotspotContentChanged,
|
|
303206
303219
|
zoomMax = _ref9.zoomMax,
|
|
@@ -303245,9 +303258,52 @@ ${formatRule(Codicon.menuSubmenu)}
|
|
|
303245
303258
|
_useState12 = _slicedToArray$9(_useState11, 2),
|
|
303246
303259
|
options = _useState12[0],
|
|
303247
303260
|
setOptions = _useState12[1];
|
|
303261
|
+
// Tracks if a hotspot is being dragged and which one.
|
|
303262
|
+
var _useState13 = React$1.useState(null),
|
|
303263
|
+
_useState14 = _slicedToArray$9(_useState13, 2),
|
|
303264
|
+
draggingHotspotId = _useState14[0],
|
|
303265
|
+
setDraggingHotspotId = _useState14[1];
|
|
303266
|
+
|
|
303267
|
+
// Ref for outer container
|
|
303268
|
+
var containerRef = React$1.useRef(null);
|
|
303269
|
+
var dragStateRef = React$1.useRef({
|
|
303270
|
+
// Flag to indicate if a drag is active
|
|
303271
|
+
isDragging: false,
|
|
303272
|
+
// Stores the starting mouse position of a drag
|
|
303273
|
+
dragStartPosition: {
|
|
303274
|
+
x: 0,
|
|
303275
|
+
y: 0
|
|
303276
|
+
},
|
|
303277
|
+
// Tracks the current position during a drag
|
|
303278
|
+
currentDargPosition: null,
|
|
303279
|
+
// Stores layout of image and container
|
|
303280
|
+
layout: {
|
|
303281
|
+
rect: null,
|
|
303282
|
+
hotspotLayout: null
|
|
303283
|
+
},
|
|
303284
|
+
// Tracks Scheduled Animation Frames
|
|
303285
|
+
frame: null
|
|
303286
|
+
});
|
|
303287
|
+
|
|
303288
|
+
// Minimum pixel movement before a drag is initiated
|
|
303289
|
+
var DRAG_THRESHOLD = 5;
|
|
303248
303290
|
var mergedI18n = React$1.useMemo(function () {
|
|
303249
303291
|
return _objectSpread$T(_objectSpread$T({}, defaultProps$13.i18n), i18n);
|
|
303250
303292
|
}, [i18n]);
|
|
303293
|
+
var hotspotsWithId = React$1.useMemo(function () {
|
|
303294
|
+
return hotspots.map(function (hotspot, index) {
|
|
303295
|
+
return _objectSpread$T(_objectSpread$T({}, hotspot), {}, {
|
|
303296
|
+
id: "".concat(hotspot.x, "-").concat(hotspot.y, "-").concat(index)
|
|
303297
|
+
});
|
|
303298
|
+
});
|
|
303299
|
+
}, [hotspots]);
|
|
303300
|
+
var _useState15 = React$1.useState(hotspotsWithId),
|
|
303301
|
+
_useState16 = _slicedToArray$9(_useState15, 2),
|
|
303302
|
+
editableHotspots = _useState16[0],
|
|
303303
|
+
setEditableHotspots = _useState16[1];
|
|
303304
|
+
React$1.useEffect(function () {
|
|
303305
|
+
setEditableHotspots(hotspotsWithId);
|
|
303306
|
+
}, [hotspotsWithId]);
|
|
303251
303307
|
var handleCtrlKeyUp = React$1.useCallback(function (event) {
|
|
303252
303308
|
// Was the control key unpressed
|
|
303253
303309
|
if (event.key === keyboardKeys.CONTROL) {
|
|
@@ -303319,6 +303375,11 @@ ${formatRule(Codicon.menuSubmenu)}
|
|
|
303319
303375
|
objectFit: displayOption
|
|
303320
303376
|
};
|
|
303321
303377
|
var onHotspotClicked = React$1.useCallback(function (evt, position) {
|
|
303378
|
+
// prevent click behavior after drag
|
|
303379
|
+
if (dragStateRef.current.isDragging) {
|
|
303380
|
+
return;
|
|
303381
|
+
}
|
|
303382
|
+
|
|
303322
303383
|
// It is possible to receive two events here, one Mouse event and one Pointer event.
|
|
303323
303384
|
// When used in the ImageHotspots component the Pointer event can somehow be from a
|
|
303324
303385
|
// previously clicked hotspot. See https://github.com/carbon-design-system/carbon-addons-iot-react/issues/1803
|
|
@@ -303327,6 +303388,108 @@ ${formatRule(Codicon.menuSubmenu)}
|
|
|
303327
303388
|
onSelectHotspot(position);
|
|
303328
303389
|
}
|
|
303329
303390
|
}, [onSelectHotspot, isEditable]);
|
|
303391
|
+
var handleMouseDownHotspot = React$1.useCallback(function (e, id1) {
|
|
303392
|
+
var hotspot = editableHotspots.find(function (h) {
|
|
303393
|
+
return h.id === id1;
|
|
303394
|
+
});
|
|
303395
|
+
if (!isEditable || (hotspot === null || hotspot === void 0 ? void 0 : hotspot.type) === 'dynamic') {
|
|
303396
|
+
return;
|
|
303397
|
+
}
|
|
303398
|
+
e.stopPropagation();
|
|
303399
|
+
setDraggingHotspotId(id1);
|
|
303400
|
+
dragStateRef.current.isDragging = true;
|
|
303401
|
+
dragStateRef.current.dragStartPosition = {
|
|
303402
|
+
x: e.clientX,
|
|
303403
|
+
y: e.clientY
|
|
303404
|
+
};
|
|
303405
|
+
|
|
303406
|
+
// Calculate layout once at drag start
|
|
303407
|
+
if (containerRef.current) {
|
|
303408
|
+
var rect = containerRef.current.getBoundingClientRect();
|
|
303409
|
+
var hotspotLayout = calculateHotspotContainerLayout(image, container, displayOption);
|
|
303410
|
+
dragStateRef.current.layout = {
|
|
303411
|
+
rect: rect,
|
|
303412
|
+
hotspotLayout: hotspotLayout
|
|
303413
|
+
};
|
|
303414
|
+
}
|
|
303415
|
+
}, [container, displayOption, image, isEditable, editableHotspots]);
|
|
303416
|
+
var handleMouseMoveHotspot = React$1.useCallback(function (e) {
|
|
303417
|
+
if (draggingHotspotId !== null && containerRef.current) {
|
|
303418
|
+
var _dragStateRef$current = dragStateRef.current,
|
|
303419
|
+
isDragging = _dragStateRef$current.isDragging,
|
|
303420
|
+
dragStartPosition = _dragStateRef$current.dragStartPosition,
|
|
303421
|
+
layout = _dragStateRef$current.layout;
|
|
303422
|
+
var dx = e.clientX - dragStartPosition.x;
|
|
303423
|
+
var dy = e.clientY - dragStartPosition.y;
|
|
303424
|
+
var distance = Math.sqrt(dx * dx + dy * dy);
|
|
303425
|
+
if (distance > DRAG_THRESHOLD && isDragging) {
|
|
303426
|
+
var rect = layout.rect,
|
|
303427
|
+
hotspotLayout = layout.hotspotLayout;
|
|
303428
|
+
var x = (e.clientX - rect.left - hotspotLayout.left) / hotspotLayout.width * 100;
|
|
303429
|
+
var y = (e.clientY - rect.top - hotspotLayout.top) / hotspotLayout.height * 100;
|
|
303430
|
+
// Clamp within image boundaries
|
|
303431
|
+
x = Math.max(0, Math.min(100, x));
|
|
303432
|
+
y = Math.max(0, Math.min(100, y));
|
|
303433
|
+
dragStateRef.current.currentDargPosition = {
|
|
303434
|
+
x: x,
|
|
303435
|
+
y: y
|
|
303436
|
+
};
|
|
303437
|
+
|
|
303438
|
+
// throttle with requestAnimationFrame
|
|
303439
|
+
if (dragStateRef.current.frame === null) {
|
|
303440
|
+
dragStateRef.current.frame = requestAnimationFrame(function () {
|
|
303441
|
+
setEditableHotspots(function (prev) {
|
|
303442
|
+
return prev.map(function (item) {
|
|
303443
|
+
return item.id === draggingHotspotId ? _objectSpread$T(_objectSpread$T({}, item), {}, {
|
|
303444
|
+
x: dragStateRef.current.currentDargPosition.x,
|
|
303445
|
+
y: dragStateRef.current.currentDargPosition.y
|
|
303446
|
+
}) : item;
|
|
303447
|
+
});
|
|
303448
|
+
});
|
|
303449
|
+
dragStateRef.current.frame = null;
|
|
303450
|
+
});
|
|
303451
|
+
}
|
|
303452
|
+
}
|
|
303453
|
+
}
|
|
303454
|
+
}, [draggingHotspotId]);
|
|
303455
|
+
var handleMouseUpHotspot = React$1.useCallback(function (e) {
|
|
303456
|
+
if (draggingHotspotId !== null && dragStateRef.current.isDragging) {
|
|
303457
|
+
e.stopPropagation();
|
|
303458
|
+
var _ref10 = dragStateRef.current.currentDargPosition || {},
|
|
303459
|
+
x = _ref10.x,
|
|
303460
|
+
y = _ref10.y;
|
|
303461
|
+
onUpdateHotspotPosition({
|
|
303462
|
+
newHotspots: editableHotspots,
|
|
303463
|
+
position: {
|
|
303464
|
+
x: x,
|
|
303465
|
+
y: y
|
|
303466
|
+
}
|
|
303467
|
+
});
|
|
303468
|
+
setDraggingHotspotId(null);
|
|
303469
|
+
dragStateRef.current.currentDargPosition = null;
|
|
303470
|
+
dragStateRef.current.isDragging = false;
|
|
303471
|
+
}
|
|
303472
|
+
}, [editableHotspots, draggingHotspotId, onUpdateHotspotPosition]);
|
|
303473
|
+
React$1.useEffect(function () {
|
|
303474
|
+
var dragState = dragStateRef.current;
|
|
303475
|
+
return function () {
|
|
303476
|
+
if (dragState.frame !== null) {
|
|
303477
|
+
cancelAnimationFrame(dragState.frame);
|
|
303478
|
+
}
|
|
303479
|
+
};
|
|
303480
|
+
}, []);
|
|
303481
|
+
|
|
303482
|
+
// Listens to mouse movement for dragging hotspot
|
|
303483
|
+
React$1.useEffect(function () {
|
|
303484
|
+
if (!isEditable) return undefined;
|
|
303485
|
+
var containerElement = containerRef.current;
|
|
303486
|
+
containerElement.addEventListener('mousemove', handleMouseMoveHotspot);
|
|
303487
|
+
containerElement.addEventListener('mouseup', handleMouseUpHotspot);
|
|
303488
|
+
return function () {
|
|
303489
|
+
containerElement.removeEventListener('mousemove', handleMouseMoveHotspot);
|
|
303490
|
+
containerElement.removeEventListener('mouseup', handleMouseUpHotspot);
|
|
303491
|
+
};
|
|
303492
|
+
}, [draggingHotspotId, handleMouseMoveHotspot, handleMouseUpHotspot, isEditable]);
|
|
303330
303493
|
var getIconRenderFunction = React$1.useCallback(function () {
|
|
303331
303494
|
return renderIconByName || (Array.isArray(icons) ? function (name, props) {
|
|
303332
303495
|
var _icons$find;
|
|
@@ -303345,7 +303508,7 @@ ${formatRule(Codicon.menuSubmenu)}
|
|
|
303345
303508
|
|
|
303346
303509
|
// Performance improvement
|
|
303347
303510
|
var cachedHotspots = React$1.useMemo(function () {
|
|
303348
|
-
return
|
|
303511
|
+
return editableHotspots.map(function (hotspot, index) {
|
|
303349
303512
|
var _hotspot$content;
|
|
303350
303513
|
var x = hotspot.x,
|
|
303351
303514
|
y = hotspot.y;
|
|
@@ -303355,10 +303518,10 @@ ${formatRule(Codicon.menuSubmenu)}
|
|
|
303355
303518
|
// Determine whether the icon needs to be dynamically overridden by a threshold
|
|
303356
303519
|
var matchingAttributeThresholds = [];
|
|
303357
303520
|
if ((_hotspot$content = hotspot.content) !== null && _hotspot$content !== void 0 && _hotspot$content.attributes) {
|
|
303358
|
-
hotspot.content.attributes.forEach(function (
|
|
303521
|
+
hotspot.content.attributes.forEach(function (_ref11) {
|
|
303359
303522
|
var _hotspot$content2;
|
|
303360
|
-
var thresholds =
|
|
303361
|
-
dataSourceId =
|
|
303523
|
+
var thresholds = _ref11.thresholds,
|
|
303524
|
+
dataSourceId = _ref11.dataSourceId;
|
|
303362
303525
|
if (!isEmpty(thresholds) && !isEmpty((_hotspot$content2 = hotspot.content) === null || _hotspot$content2 === void 0 ? void 0 : _hotspot$content2.values)) {
|
|
303363
303526
|
var _hotspot$content3;
|
|
303364
303527
|
var attributeThresholds = findMatchingThresholds(thresholds.map(function (threshold) {
|
|
@@ -303384,10 +303547,13 @@ ${formatRule(Codicon.menuSubmenu)}
|
|
|
303384
303547
|
key: "".concat(x, "-").concat(y, "-").concat(index),
|
|
303385
303548
|
renderIconByName: getIconRenderFunction(),
|
|
303386
303549
|
isSelected: hotspotIsSelected,
|
|
303387
|
-
onClick: onHotspotClicked
|
|
303550
|
+
onClick: onHotspotClicked,
|
|
303551
|
+
onMouseDown: function onMouseDown(e) {
|
|
303552
|
+
return handleMouseDownHotspot(e, hotspot.id);
|
|
303553
|
+
}
|
|
303388
303554
|
}));
|
|
303389
303555
|
});
|
|
303390
|
-
}, [
|
|
303556
|
+
}, [editableHotspots, selectedHotspots, locale, getIconRenderFunction, isEditable, onHotspotContentChanged, mergedI18n, onHotspotClicked, handleMouseDownHotspot]);
|
|
303391
303557
|
var hotspotsStyle = {
|
|
303392
303558
|
position: 'absolute',
|
|
303393
303559
|
left: image.offsetX,
|
|
@@ -303430,7 +303596,8 @@ ${formatRule(Codicon.menuSubmenu)}
|
|
|
303430
303596
|
// If we leave the container, stop detecting the drag
|
|
303431
303597
|
stopDrag(cursor, setCursor);
|
|
303432
303598
|
}
|
|
303433
|
-
}
|
|
303599
|
+
},
|
|
303600
|
+
ref: containerRef
|
|
303434
303601
|
}, src ? /*#__PURE__*/React$1.createElement("img", {
|
|
303435
303602
|
id: id,
|
|
303436
303603
|
className: "".concat(iotPrefix$Y, "--image-card-img"),
|
|
@@ -303657,6 +303824,17 @@ ${formatRule(Codicon.menuSubmenu)}
|
|
|
303657
303824
|
},
|
|
303658
303825
|
"required": false
|
|
303659
303826
|
},
|
|
303827
|
+
"onUpdateHotspotPosition": {
|
|
303828
|
+
"defaultValue": {
|
|
303829
|
+
"value": "() => {}",
|
|
303830
|
+
"computed": false
|
|
303831
|
+
},
|
|
303832
|
+
"description": "Callback when a hotspot is dragged to new position in isEditable mode\nEmits new hotspots and updated position obj {x, y} of hotspot.",
|
|
303833
|
+
"type": {
|
|
303834
|
+
"name": "func"
|
|
303835
|
+
},
|
|
303836
|
+
"required": false
|
|
303837
|
+
},
|
|
303660
303838
|
"onSelectHotspot": {
|
|
303661
303839
|
"defaultValue": {
|
|
303662
303840
|
"value": "() => {}",
|
|
@@ -316150,6 +316328,7 @@ ${formatRule(Codicon.menuSubmenu)}
|
|
|
316150
316328
|
hotspotDataSourceChange: 'HOTSPOT_DATA_SOURCE_CHANGE',
|
|
316151
316329
|
hotspotDataSourceSettingsChange: 'HOTSPOT_DATA_SOURCE_SETTINGS_CHANGE',
|
|
316152
316330
|
hotspotTooltipChange: 'HOTSPOT_TOOLTIP_CHANGE',
|
|
316331
|
+
hotspotPositionChange: 'HOTSPOT_POSITION_CHANGE',
|
|
316153
316332
|
hotspotSelect: 'HOTSPOT_SELECT',
|
|
316154
316333
|
hotspotsAdd: 'HOTSPOTS_ADD',
|
|
316155
316334
|
textHotspotStyleChange: 'TEXT_HOTSPOT_STYLE_CHANGE',
|
|
@@ -316252,10 +316431,32 @@ ${formatRule(Codicon.menuSubmenu)}
|
|
|
316252
316431
|
};
|
|
316253
316432
|
return getHotspotUpdate(state, _mergeSpec);
|
|
316254
316433
|
}
|
|
316434
|
+
// HOTSPOT POSITION CHANGE
|
|
316435
|
+
case hotspotActionTypes.hotspotPositionChange:
|
|
316436
|
+
{
|
|
316437
|
+
var isPositionAvailable = !state.hotspots.find(function (hotspot) {
|
|
316438
|
+
return isHotspotMatch(hotspot, payload.position);
|
|
316439
|
+
});
|
|
316440
|
+
if (isPositionAvailable) {
|
|
316441
|
+
// Find the updated hotspot in the new hotspots array to maintain selection
|
|
316442
|
+
var updatedSelectedHotspot = payload.newHotspots.find(function (hotspot) {
|
|
316443
|
+
return isHotspotMatch(hotspot, payload.position);
|
|
316444
|
+
});
|
|
316445
|
+
return update(state, {
|
|
316446
|
+
hotspots: {
|
|
316447
|
+
$set: payload.newHotspots
|
|
316448
|
+
},
|
|
316449
|
+
selectedHotspot: {
|
|
316450
|
+
$set: updatedSelectedHotspot
|
|
316451
|
+
}
|
|
316452
|
+
});
|
|
316453
|
+
}
|
|
316454
|
+
return state;
|
|
316455
|
+
}
|
|
316255
316456
|
// HOTSPOTS ADD
|
|
316256
316457
|
case hotspotActionTypes.hotspotsAdd:
|
|
316257
316458
|
{
|
|
316258
|
-
var
|
|
316459
|
+
var _isPositionAvailable = !state.hotspots.find(function (hotspot) {
|
|
316259
316460
|
return isHotspotMatch(hotspot, payload.position);
|
|
316260
316461
|
});
|
|
316261
316462
|
var defaultContent = state.currentType === hotspotTypes.TEXT ? {
|
|
@@ -316266,7 +316467,7 @@ ${formatRule(Codicon.menuSubmenu)}
|
|
|
316266
316467
|
content: defaultContent,
|
|
316267
316468
|
type: createableType
|
|
316268
316469
|
});
|
|
316269
|
-
return
|
|
316470
|
+
return _isPositionAvailable ? update(state, {
|
|
316270
316471
|
selectedHotspot: {
|
|
316271
316472
|
$set: newHotspot
|
|
316272
316473
|
},
|
|
@@ -316294,7 +316495,7 @@ ${formatRule(Codicon.menuSubmenu)}
|
|
|
316294
316495
|
$set: hotspot
|
|
316295
316496
|
},
|
|
316296
316497
|
currentType: {
|
|
316297
|
-
$set: (_hotspot$type = hotspot.type) !== null && _hotspot$type !== void 0 ? _hotspot$type : defaultTypeWhenMissing
|
|
316498
|
+
$set: (_hotspot$type = hotspot === null || hotspot === void 0 ? void 0 : hotspot.type) !== null && _hotspot$type !== void 0 ? _hotspot$type : defaultTypeWhenMissing
|
|
316298
316499
|
}
|
|
316299
316500
|
});
|
|
316300
316501
|
}
|
|
@@ -316493,6 +316694,12 @@ ${formatRule(Codicon.menuSubmenu)}
|
|
|
316493
316694
|
payload: hotspotContent
|
|
316494
316695
|
});
|
|
316495
316696
|
};
|
|
316697
|
+
var updateHotspotPosition = function updateHotspotPosition(hotspotPosition) {
|
|
316698
|
+
return dispatch({
|
|
316699
|
+
type: hotspotActionTypes.hotspotPositionChange,
|
|
316700
|
+
payload: hotspotPosition
|
|
316701
|
+
});
|
|
316702
|
+
};
|
|
316496
316703
|
|
|
316497
316704
|
/** Updates the properties of the text hotspot, passes a payload like {color: 'blue'} */
|
|
316498
316705
|
var updateTextHotspotStyle = function updateTextHotspotStyle(textHotspotStyle) {
|
|
@@ -316580,6 +316787,7 @@ ${formatRule(Codicon.menuSubmenu)}
|
|
|
316580
316787
|
switchCurrentType: switchCurrentType,
|
|
316581
316788
|
updateHotspotDataSource: updateHotspotDataSource,
|
|
316582
316789
|
updateHotspotTooltip: updateHotspotTooltip,
|
|
316790
|
+
updateHotspotPosition: updateHotspotPosition,
|
|
316583
316791
|
updateTextHotspotStyle: updateTextHotspotStyle,
|
|
316584
316792
|
updateTextHotspotContent: updateTextHotspotContent,
|
|
316585
316793
|
updateDynamicHotspotSourceX: updateDynamicHotspotSourceX,
|
|
@@ -317119,6 +317327,7 @@ ${formatRule(Codicon.menuSubmenu)}
|
|
|
317119
317327
|
switchCurrentType = _useHotspotEditorStat.switchCurrentType,
|
|
317120
317328
|
updateHotspotDataSource = _useHotspotEditorStat.updateHotspotDataSource,
|
|
317121
317329
|
updateHotspotTooltip = _useHotspotEditorStat.updateHotspotTooltip,
|
|
317330
|
+
updateHotspotPosition = _useHotspotEditorStat.updateHotspotPosition,
|
|
317122
317331
|
updateTextHotspotStyle = _useHotspotEditorStat.updateTextHotspotStyle,
|
|
317123
317332
|
updateTextHotspotContent = _useHotspotEditorStat.updateTextHotspotContent,
|
|
317124
317333
|
updateDynamicHotspotSourceX = _useHotspotEditorStat.updateDynamicHotspotSourceX,
|
|
@@ -317184,6 +317393,8 @@ ${formatRule(Codicon.menuSubmenu)}
|
|
|
317184
317393
|
}
|
|
317185
317394
|
var hotspotsWithoutExampleValues = filteredHotspots.map(function (hotspot) {
|
|
317186
317395
|
return update(hotspot, {
|
|
317396
|
+
$unset: ['id'],
|
|
317397
|
+
// Remove the internal id added for drag tracking
|
|
317187
317398
|
content: {
|
|
317188
317399
|
$unset: ['values']
|
|
317189
317400
|
}
|
|
@@ -317433,6 +317644,7 @@ ${formatRule(Codicon.menuSubmenu)}
|
|
|
317433
317644
|
hotspotDefaults: hotspotDefaults
|
|
317434
317645
|
});
|
|
317435
317646
|
},
|
|
317647
|
+
onUpdateHotspotPosition: updateHotspotPosition,
|
|
317436
317648
|
onSelectHotspot: setSelectedHotspot,
|
|
317437
317649
|
selectedHotspots: getSelectedHotspotsList(selectedHotspot, hotspots),
|
|
317438
317650
|
src: cardConfig.content.src,
|