carbon-addons-iot-react 5.8.0 → 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/css/carbon-addons-iot-react.css +1 -1
- package/css/carbon-addons-iot-react.css.map +1 -1
- 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/lib/css/carbon-addons-iot-react.css +1 -1
- package/lib/css/carbon-addons-iot-react.css.map +1 -1
- package/lib/scss/components/ValueCard/_attribute.scss +1 -1
- package/package.json +1 -1
- package/scss/components/ValueCard/_attribute.scss +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
|
}));
|