@dnb/eufemia 9.32.0 → 9.32.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (86) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/cjs/components/slider/SliderThumb.js +17 -4
  3. package/cjs/components/slider/SliderTrack.js +3 -6
  4. package/cjs/components/slider/hooks/useSliderEvents.d.ts +2 -2
  5. package/cjs/components/slider/hooks/useSliderEvents.js +3 -2
  6. package/cjs/components/tooltip/Tooltip.js +21 -18
  7. package/cjs/components/tooltip/TooltipContainer.js +42 -17
  8. package/cjs/components/tooltip/TooltipHelpers.d.ts +1 -1
  9. package/cjs/components/tooltip/TooltipHelpers.js +5 -9
  10. package/cjs/components/tooltip/TooltipPortal.d.ts +1 -1
  11. package/cjs/components/tooltip/TooltipPortal.js +47 -30
  12. package/cjs/components/tooltip/TooltipWithEvents.d.ts +1 -1
  13. package/cjs/components/tooltip/TooltipWithEvents.js +69 -41
  14. package/cjs/components/tooltip/types.d.ts +1 -0
  15. package/cjs/shared/Eufemia.js +1 -1
  16. package/cjs/shared/component-helper.js +1 -1
  17. package/cjs/style/dnb-ui-elements.css +31 -16
  18. package/cjs/style/dnb-ui-elements.min.css +1 -1
  19. package/cjs/style/dnb-ui-tags.css +60 -31
  20. package/cjs/style/dnb-ui-tags.min.css +1 -1
  21. package/cjs/style/elements/ui-spacing.scss +3 -1
  22. package/cjs/style/themes/theme-eiendom/dnb-theme-eiendom.css +31 -16
  23. package/cjs/style/themes/theme-eiendom/dnb-theme-eiendom.min.css +1 -1
  24. package/cjs/style/themes/theme-ui/dnb-theme-ui.css +31 -16
  25. package/cjs/style/themes/theme-ui/dnb-theme-ui.min.css +1 -1
  26. package/components/slider/SliderThumb.js +18 -5
  27. package/components/slider/SliderTrack.js +3 -6
  28. package/components/slider/hooks/useSliderEvents.d.ts +2 -2
  29. package/components/slider/hooks/useSliderEvents.js +3 -2
  30. package/components/tooltip/Tooltip.js +21 -18
  31. package/components/tooltip/TooltipContainer.js +41 -18
  32. package/components/tooltip/TooltipHelpers.d.ts +1 -1
  33. package/components/tooltip/TooltipHelpers.js +5 -9
  34. package/components/tooltip/TooltipPortal.d.ts +1 -1
  35. package/components/tooltip/TooltipPortal.js +46 -29
  36. package/components/tooltip/TooltipWithEvents.d.ts +1 -1
  37. package/components/tooltip/TooltipWithEvents.js +67 -42
  38. package/components/tooltip/types.d.ts +1 -0
  39. package/es/components/slider/SliderThumb.js +18 -5
  40. package/es/components/slider/SliderTrack.js +3 -6
  41. package/es/components/slider/hooks/useSliderEvents.d.ts +2 -2
  42. package/es/components/slider/hooks/useSliderEvents.js +3 -2
  43. package/es/components/tooltip/Tooltip.js +13 -15
  44. package/es/components/tooltip/TooltipContainer.js +37 -20
  45. package/es/components/tooltip/TooltipHelpers.d.ts +1 -1
  46. package/es/components/tooltip/TooltipHelpers.js +5 -9
  47. package/es/components/tooltip/TooltipPortal.d.ts +1 -1
  48. package/es/components/tooltip/TooltipPortal.js +44 -29
  49. package/es/components/tooltip/TooltipWithEvents.d.ts +1 -1
  50. package/es/components/tooltip/TooltipWithEvents.js +69 -43
  51. package/es/components/tooltip/types.d.ts +1 -0
  52. package/es/shared/Eufemia.js +1 -1
  53. package/es/shared/component-helper.js +1 -1
  54. package/es/style/dnb-ui-elements.css +31 -16
  55. package/es/style/dnb-ui-elements.min.css +1 -1
  56. package/es/style/dnb-ui-tags.css +60 -31
  57. package/es/style/dnb-ui-tags.min.css +1 -1
  58. package/es/style/elements/ui-spacing.scss +3 -1
  59. package/es/style/themes/theme-eiendom/dnb-theme-eiendom.css +31 -16
  60. package/es/style/themes/theme-eiendom/dnb-theme-eiendom.min.css +1 -1
  61. package/es/style/themes/theme-ui/dnb-theme-ui.css +31 -16
  62. package/es/style/themes/theme-ui/dnb-theme-ui.min.css +1 -1
  63. package/esm/dnb-ui-basis.min.mjs +1 -1
  64. package/esm/dnb-ui-components.min.mjs +1 -1
  65. package/esm/dnb-ui-elements.min.mjs +3 -3
  66. package/esm/dnb-ui-extensions.min.mjs +1 -1
  67. package/esm/dnb-ui-lib.min.mjs +2 -2
  68. package/esm/dnb-ui-web-components.min.mjs +2 -2
  69. package/package.json +1 -1
  70. package/shared/Eufemia.js +1 -1
  71. package/shared/component-helper.js +1 -1
  72. package/style/dnb-ui-elements.css +31 -16
  73. package/style/dnb-ui-elements.min.css +1 -1
  74. package/style/dnb-ui-tags.css +60 -31
  75. package/style/dnb-ui-tags.min.css +1 -1
  76. package/style/elements/ui-spacing.scss +3 -1
  77. package/style/themes/theme-eiendom/dnb-theme-eiendom.css +31 -16
  78. package/style/themes/theme-eiendom/dnb-theme-eiendom.min.css +1 -1
  79. package/style/themes/theme-ui/dnb-theme-ui.css +31 -16
  80. package/style/themes/theme-ui/dnb-theme-ui.min.css +1 -1
  81. package/umd/dnb-ui-basis.min.js +1 -1
  82. package/umd/dnb-ui-components.min.js +1 -1
  83. package/umd/dnb-ui-elements.min.js +2 -2
  84. package/umd/dnb-ui-extensions.min.js +1 -1
  85. package/umd/dnb-ui-lib.min.js +2 -2
  86. package/umd/dnb-ui-web-components.min.js +2 -2
@@ -19,7 +19,8 @@ export function useSliderEvents() {
19
19
  onDragStart = allProps.onDragStart,
20
20
  onDragEnd = allProps.onDragEnd;
21
21
 
22
- var onTrackMouseUpHandler = function onTrackMouseUpHandler(event) {
22
+ var onTrackMouseDownHandler = function onTrackMouseDownHandler(event) {
23
+ onThumbMouseDownHandler(event);
23
24
  var percent = calculatePercent(trackRef.current, event, isVertical);
24
25
  emitChange(event, percentToValue(percent, min, max, isReverse));
25
26
  setShouldAnimate(true);
@@ -107,7 +108,7 @@ export function useSliderEvents() {
107
108
  return {
108
109
  onThumbMouseDownHandler: onThumbMouseDownHandler,
109
110
  onThumbMouseUpHandler: onThumbMouseUpHandler,
110
- onTrackMouseUpHandler: onTrackMouseUpHandler,
111
+ onTrackMouseDownHandler: onTrackMouseDownHandler,
111
112
  onHelperChangeHandler: onHelperChangeHandler,
112
113
  onHelperFocusHandler: onHelperFocusHandler,
113
114
  removeEvents: removeEvents
@@ -18,12 +18,10 @@ function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { va
18
18
  import React from 'react';
19
19
  import classnames from 'classnames';
20
20
  import Context from '../../shared/Context';
21
- import { makeUniqueId, validateDOMAttributes, isTrue } from '../../shared/component-helper';
21
+ import { makeUniqueId, validateDOMAttributes } from '../../shared/component-helper';
22
22
  import { createSpacingClasses } from '../space/SpacingHelper';
23
- import TooltipContainer from './TooltipContainer';
24
23
  import TooltipWithEvents from './TooltipWithEvents';
25
- import TooltipPortal from './TooltipPortal';
26
- import { defaultProps, getPropsFromTooltipProp, injectTooltipSemantic } from './TooltipHelpers';
24
+ import { defaultProps, getPropsFromTooltipProp, getRefElement, getTargetElement, injectTooltipSemantic } from './TooltipHelpers';
27
25
  import { convertSnakeCaseProps } from '../../shared/helpers/withSnakeCaseProps';
28
26
 
29
27
  function Tooltip(localProps) {
@@ -50,13 +48,24 @@ function Tooltip(localProps) {
50
48
  align = props.align,
51
49
  params = _objectWithoutProperties(props, _excluded);
52
50
 
53
- var _React$useState = React.useState(function () {
51
+ var target = targetElement || targetSelector;
52
+
53
+ var _React$useState = React.useState(),
54
+ _React$useState2 = _slicedToArray(_React$useState, 2),
55
+ element = _React$useState2[0],
56
+ setElement = _React$useState2[1];
57
+
58
+ var _React$useState3 = React.useState(function () {
54
59
  return props.id || makeUniqueId();
55
60
  }),
56
- _React$useState2 = _slicedToArray(_React$useState, 1),
57
- internalId = _React$useState2[0];
61
+ _React$useState4 = _slicedToArray(_React$useState3, 1),
62
+ internalId = _React$useState4[0];
58
63
 
59
64
  props.internalId = internalId;
65
+ React.useEffect(function () {
66
+ var element = getTargetElement(getRefElement(target));
67
+ setElement(element);
68
+ }, [target]);
60
69
  var classes = classnames('dnb-tooltip', createSpacingClasses(props), className, size === 'large' && 'dnb-tooltip--large');
61
70
 
62
71
  var attributes = _objectSpread({
@@ -65,20 +74,14 @@ function Tooltip(localProps) {
65
74
 
66
75
  validateDOMAttributes(localProps, attributes);
67
76
 
68
- if (!isTrue(props.active)) {
69
- delete props.active;
77
+ if (target && !element) {
78
+ return null;
70
79
  }
71
80
 
72
- return React.createElement(React.Fragment, null, skipPortal ? React.createElement(TooltipContainer, _extends({
73
- target: targetElement,
74
- attributes: attributes
75
- }, props), props.children) : targetElement ? React.createElement(TooltipWithEvents, _extends({
76
- target: targetElement,
77
- attributes: attributes
78
- }, props), props.children) : targetSelector && React.createElement(TooltipPortal, _extends({
79
- target: targetSelector,
81
+ return React.createElement(TooltipWithEvents, _extends({
82
+ target: element,
80
83
  attributes: attributes
81
- }, props), props.children));
84
+ }, props), props.children);
82
85
  }
83
86
 
84
87
  export { injectTooltipSemantic };
@@ -17,7 +17,7 @@ function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { va
17
17
 
18
18
  import React from 'react';
19
19
  import { isTrue } from '../../shared/component-helper';
20
- import { getOffsetLeft } from '../../shared/helpers';
20
+ import { getOffsetLeft, getOffsetTop } from '../../shared/helpers';
21
21
  import classnames from 'classnames';
22
22
  export default function TooltipContainer(props) {
23
23
  var internalId = props.internalId,
@@ -25,11 +25,16 @@ export default function TooltipContainer(props) {
25
25
  attributes = props.attributes,
26
26
  arrow = props.arrow,
27
27
  position = props.position,
28
+ align = props.align,
29
+ group = props.group,
30
+ hideDelay = props.hideDelay,
28
31
  animatePosition = props.animatePosition,
29
32
  fixedPosition = props.fixedPosition,
30
33
  noAnimation = props.noAnimation,
34
+ skipPortal = props.skipPortal,
31
35
  useHover = props.useHover,
32
- children = props.children;
36
+ children = props.children,
37
+ target = props.targetElement;
33
38
 
34
39
  var _React$useState = React.useState(null),
35
40
  _React$useState2 = _slicedToArray(_React$useState, 2),
@@ -77,7 +82,7 @@ export default function TooltipContainer(props) {
77
82
  }
78
83
 
79
84
  try {
80
- resizeObserver.current = new ResizeObserver(function (entries) {
85
+ resizeObserver.current = new ResizeObserver(function () {
81
86
  clearTimeout(debounceTimeout.current);
82
87
  debounceTimeout.current = setTimeout(function () {
83
88
  return forceRerender(getBodySize());
@@ -103,19 +108,29 @@ export default function TooltipContainer(props) {
103
108
 
104
109
  return removePositionObserver;
105
110
  }, [isActive]);
111
+ var offsetLeft = React.useRef(0);
112
+ var offsetTop = React.useRef(0);
106
113
  React.useLayoutEffect(function () {
114
+ if (!isActive) {
115
+ if (group && wasActive) {
116
+ clearTimeout(debounceTimeout.current);
117
+ debounceTimeout.current = setTimeout(function () {
118
+ return setStyle(null);
119
+ }, hideDelay);
120
+ }
121
+
122
+ return;
123
+ }
124
+
107
125
  var element = elementRef === null || elementRef === void 0 ? void 0 : elementRef.current;
108
- var target = props.targetElement,
109
- align = props.align,
110
- fixedPosition = props.fixedPosition;
111
126
 
112
127
  if (typeof window === 'undefined' || !element || !(target !== null && target !== void 0 && target.getBoundingClientRect)) {
113
128
  return;
114
129
  }
115
130
 
131
+ var alignOffset = 0;
116
132
  var elementWidth = element.offsetWidth;
117
133
  var elementHeight = element.offsetHeight;
118
- var alignOffset = 0;
119
134
  var rect = target.getBoundingClientRect();
120
135
  var targetBodySize = {
121
136
  width: target.offsetWidth,
@@ -127,16 +142,21 @@ export default function TooltipContainer(props) {
127
142
  targetBodySize.height = rect.height;
128
143
  }
129
144
 
145
+ if (skipPortal && (!offsetLeft.current || !offsetTop.current)) {
146
+ offsetLeft.current = getOffsetLeft(element) - offset.current;
147
+ offsetTop.current = getOffsetTop(element) - offset.current;
148
+ }
149
+
130
150
  var scrollY = window.scrollY !== undefined ? window.scrollY : window.pageYOffset;
131
151
  var scrollX = window.scrollX !== undefined ? window.scrollX : window.pageXOffset;
132
152
 
133
- var _top = (isTrue(fixedPosition) ? 0 : scrollY) + rect.top;
153
+ var _top = (isTrue(fixedPosition) ? 0 : scrollY) + rect.top - offsetTop.current;
134
154
 
135
155
  var useMouseWhen = targetBodySize.width > 400;
136
156
  var mousePos = getOffsetLeft(target) + rect.left / 2 + (element ? element.offsetWidth : 0);
137
157
  var widthBased = scrollX + rect.left;
138
158
 
139
- var _left = useMouseWhen && mousePos < targetBodySize.width ? mousePos : widthBased;
159
+ var _left = (useMouseWhen && mousePos < targetBodySize.width ? mousePos : widthBased) - offsetLeft.current;
140
160
 
141
161
  var style = _objectSpread({}, props.style);
142
162
 
@@ -183,9 +203,7 @@ export default function TooltipContainer(props) {
183
203
 
184
204
  if (stylesFromPosition[position]) {
185
205
  stylesFromPosition[position]();
186
- }
187
-
188
- if (stylesFromArrow[arrow]) {
206
+ } else if (stylesFromArrow[arrow]) {
189
207
  stylesFromArrow[arrow]();
190
208
  }
191
209
 
@@ -203,10 +221,8 @@ export default function TooltipContainer(props) {
203
221
  style.top = 0;
204
222
  }
205
223
 
206
- if (isActive) {
207
- setStyle(style);
208
- }
209
- }, [isActive, arrow, position, children, renewStyles]);
224
+ setStyle(style);
225
+ }, [active, arrow, position, children, renewStyles]);
210
226
 
211
227
  var handleMouseEnter = function handleMouseEnter() {
212
228
  if (isTrue(active) && useHover !== false) {
@@ -220,12 +236,19 @@ export default function TooltipContainer(props) {
220
236
  }
221
237
  };
222
238
 
239
+ var handlePropagation = function handlePropagation(e) {
240
+ return e.stopPropagation();
241
+ };
242
+
223
243
  return React.createElement("span", _extends({
224
244
  role: "tooltip",
225
- "aria-hidden": true,
245
+ "aria-hidden": target ? true : undefined,
226
246
  ref: elementRef,
227
247
  onMouseEnter: handleMouseEnter,
228
- onMouseLeave: handleMouseLeave
248
+ onMouseLeave: handleMouseLeave,
249
+ onMouseMove: handlePropagation,
250
+ onMouseDown: handlePropagation,
251
+ onTouchStart: handlePropagation
229
252
  }, attributes, {
230
253
  className: classnames(attributes === null || attributes === void 0 ? void 0 : attributes.className, isActive ? 'dnb-tooltip--active' : wasActive && 'dnb-tooltip--hide', isTrue(animatePosition) && 'dnb-tooltip--animate_position', isTrue(noAnimation) && 'dnb-tooltip--no-animation', isTrue(fixedPosition) && 'dnb-tooltip--fixed'),
231
254
  style: _objectSpread(_objectSpread({}, style), attributes.style)
@@ -25,7 +25,7 @@ export declare const defaultProps: {
25
25
  tooltip: any;
26
26
  };
27
27
  export declare function getTargetElement(target: HTMLElement): HTMLElement;
28
- export declare function useHandleAria(targetElement: React.RefObject<HTMLElement>, internalId: string): void;
28
+ export declare function useHandleAria(targetElement: HTMLElement, internalId: string): void;
29
29
  export declare function getPropsFromTooltipProp(localProps: any): any;
30
30
  export declare function getRefElement(target: React.RefObject<HTMLElement>): any;
31
31
  export declare const isTouch: (type: string) => boolean;
@@ -35,14 +35,10 @@ export function getTargetElement(target) {
35
35
  export function useHandleAria(targetElement, internalId) {
36
36
  React.useEffect(function () {
37
37
  try {
38
- var elem = getTargetElement(getRefElement(targetElement));
39
-
40
- if (!(elem !== null && elem !== void 0 && elem.classList.contains('dnb-tooltip__wrapper'))) {
41
- var existing = {
42
- 'aria-describedby': elem.getAttribute('aria-describedby')
43
- };
44
- elem.setAttribute('aria-describedby', combineDescribedBy(existing, internalId));
45
- }
38
+ var existing = {
39
+ 'aria-describedby': targetElement.getAttribute('aria-describedby')
40
+ };
41
+ targetElement.setAttribute('aria-describedby', combineDescribedBy(existing, internalId));
46
42
  } catch (e) {}
47
43
  }, [targetElement, internalId]);
48
44
  }
@@ -61,7 +57,7 @@ export function getRefElement(target) {
61
57
  element = getRefElement(unknownTarget.current._ref);
62
58
  }
63
59
 
64
- if (Object.prototype.hasOwnProperty.call(element, 'current')) {
60
+ if (element && Object.prototype.hasOwnProperty.call(element, 'current')) {
65
61
  element = element.current;
66
62
  }
67
63
 
@@ -5,7 +5,7 @@
5
5
  import React from 'react';
6
6
  import { TooltipProps } from './types';
7
7
  declare type TooltipPortalProps = {
8
- target: HTMLElement;
8
+ targetElement: HTMLElement;
9
9
  active: boolean;
10
10
  keepInDOM?: boolean;
11
11
  group?: string;
@@ -6,7 +6,6 @@ import React from 'react';
6
6
  import ReactDOM from 'react-dom';
7
7
  import { makeUniqueId, warn } from '../../shared/component-helper';
8
8
  import TooltipContainer from './TooltipContainer';
9
- import { getTargetElement } from './TooltipHelpers';
10
9
  var tooltipPortal;
11
10
 
12
11
  if (typeof globalThis !== 'undefined') {
@@ -18,7 +17,7 @@ if (typeof globalThis !== 'undefined') {
18
17
 
19
18
  function TooltipPortal(props) {
20
19
  var active = props.active,
21
- target = props.target,
20
+ targetElement = props.targetElement,
22
21
  hideDelay = props.hideDelay,
23
22
  keepInDOM = props.keepInDOM,
24
23
  noAnimation = props.noAnimation,
@@ -38,41 +37,57 @@ function TooltipPortal(props) {
38
37
  return props.group || makeUniqueId();
39
38
  }),
40
39
  _React$useState6 = _slicedToArray(_React$useState5, 1),
41
- group = _React$useState6[0];
40
+ id = _React$useState6[0];
42
41
 
43
42
  var isInDOM = React.useRef(false);
44
43
  var hasGroup = props.group;
45
44
 
46
- if (tooltipPortal[group]) {
47
- tooltipPortal[group].inDOM = isInDOM.current;
48
- }
49
-
50
45
  var makePortal = function makePortal() {
51
- if (!tooltipPortal[group]) {
52
- tooltipPortal[group] = {
53
- node: hasGroup ? createGroupElement(group) : createRootElement('dnb-tooltip__portal')
46
+ if (!tooltipPortal[id]) {
47
+ tooltipPortal[id] = {
48
+ count: 0,
49
+ node: hasGroup ? createGroupElement(id) : createRootElement()
54
50
  };
55
51
  }
56
52
  };
57
53
 
58
- var removeFromDOM = function removeFromDOM() {
59
- if (!keepInDOM && hasGroup && tooltipPortal[group] && !tooltipPortal[group].inDOM) {
60
- ReactDOM.unmountComponentAtNode(tooltipPortal[group].node);
54
+ var removeFromDOM = function removeFromDOM(hide) {
55
+ if (isActive && hide) {
56
+ return;
57
+ }
58
+
59
+ var ref = tooltipPortal[id];
60
+
61
+ if (ref !== null && ref !== void 0 && ref.node) {
62
+ ref.count--;
63
+
64
+ if (ref.count <= 0) {
65
+ if (hasGroup) {
66
+ ReactDOM.unmountComponentAtNode(ref.node);
67
+ createRootElement().removeChild(ref.node);
68
+ }
69
+
70
+ delete tooltipPortal[id];
71
+ }
61
72
  }
62
73
  };
63
74
 
64
75
  React.useEffect(function () {
65
- var _tooltipPortal$group, _tooltipPortal$group2;
76
+ var _tooltipPortal$id, _tooltipPortal$id2;
66
77
 
67
78
  setIsMounted(true);
68
- clearTimeout((_tooltipPortal$group = tooltipPortal[group]) === null || _tooltipPortal$group === void 0 ? void 0 : _tooltipPortal$group.delayTimeout);
69
- clearTimeout((_tooltipPortal$group2 = tooltipPortal[group]) === null || _tooltipPortal$group2 === void 0 ? void 0 : _tooltipPortal$group2.hiddenTimeout);
79
+ clearTimeout((_tooltipPortal$id = tooltipPortal[id]) === null || _tooltipPortal$id === void 0 ? void 0 : _tooltipPortal$id.delayTimeout);
80
+ clearTimeout((_tooltipPortal$id2 = tooltipPortal[id]) === null || _tooltipPortal$id2 === void 0 ? void 0 : _tooltipPortal$id2.hiddenTimeout);
70
81
 
71
82
  if (active) {
72
83
  makePortal();
73
84
  setIsActive(true);
74
85
  isInDOM.current = true;
75
86
 
87
+ if (!isMounted) {
88
+ tooltipPortal[id].count++;
89
+ }
90
+
76
91
  if (hasGroup) {
77
92
  renderPortal(true);
78
93
  }
@@ -87,19 +102,19 @@ function TooltipPortal(props) {
87
102
 
88
103
  var delayHidden = function delayHidden() {
89
104
  isInDOM.current = false;
90
- removeFromDOM();
105
+ removeFromDOM(true);
91
106
  };
92
107
 
93
108
  if (noAnimation || globalThis.IS_TEST) {
94
109
  delayRender();
95
110
  delayHidden();
96
- } else if (tooltipPortal[group]) {
111
+ } else if (tooltipPortal[id]) {
97
112
  var delay = parseFloat(String(hideDelay));
98
- tooltipPortal[group].delayTimeout = setTimeout(delayRender, delay);
99
- tooltipPortal[group].hiddenTimeout = setTimeout(delayHidden, delay + 300);
113
+ tooltipPortal[id].delayTimeout = setTimeout(delayRender, delay);
114
+ tooltipPortal[id].hiddenTimeout = setTimeout(delayHidden, delay + 300);
100
115
  }
101
116
  }
102
- }, [children, active, group, hideDelay, noAnimation]);
117
+ }, [children, active, id, hideDelay, noAnimation]);
103
118
  React.useEffect(function () {
104
119
  if (keepInDOM) {
105
120
  makePortal();
@@ -109,13 +124,13 @@ function TooltipPortal(props) {
109
124
  }, []);
110
125
 
111
126
  var renderPortal = function renderPortal(isActive) {
112
- var _tooltipPortal$group3;
127
+ var _tooltipPortal$id3;
113
128
 
114
- var root = (_tooltipPortal$group3 = tooltipPortal[group]) === null || _tooltipPortal$group3 === void 0 ? void 0 : _tooltipPortal$group3.node;
129
+ var root = (_tooltipPortal$id3 = tooltipPortal[id]) === null || _tooltipPortal$id3 === void 0 ? void 0 : _tooltipPortal$id3.node;
115
130
 
116
131
  if (root && hasGroup && isInDOM.current) {
117
132
  ReactDOM.render(React.createElement(TooltipContainer, _extends({}, props, {
118
- targetElement: getTargetElement(target),
133
+ targetElement: targetElement,
119
134
  active: isActive
120
135
  })), root);
121
136
  }
@@ -124,13 +139,13 @@ function TooltipPortal(props) {
124
139
  };
125
140
 
126
141
  if (!hasGroup) {
127
- var _tooltipPortal$group4;
142
+ var _tooltipPortal$id4;
128
143
 
129
- var root = (_tooltipPortal$group4 = tooltipPortal[group]) === null || _tooltipPortal$group4 === void 0 ? void 0 : _tooltipPortal$group4.node;
144
+ var root = (_tooltipPortal$id4 = tooltipPortal[id]) === null || _tooltipPortal$id4 === void 0 ? void 0 : _tooltipPortal$id4.node;
130
145
 
131
146
  if (root) {
132
147
  return ReactDOM.createPortal(isInDOM.current || keepInDOM ? React.createElement(TooltipContainer, _extends({}, props, {
133
- targetElement: getTargetElement(target),
148
+ targetElement: targetElement,
134
149
  active: isActive
135
150
  }), children) : null, root);
136
151
  }
@@ -146,14 +161,16 @@ var createGroupElement = function createGroupElement(id) {
146
161
  var elem = document.createElement('div');
147
162
  elem.classList.add('dnb-tooltip__group');
148
163
  elem.setAttribute('id', id);
149
- createRootElement('dnb-tooltip__portal').appendChild(elem);
164
+ createRootElement().appendChild(elem);
150
165
  return elem;
151
166
  } catch (e) {
152
167
  warn(e);
153
168
  }
154
169
  };
155
170
 
156
- var createRootElement = function createRootElement(className) {
171
+ var createRootElement = function createRootElement() {
172
+ var className = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'dnb-tooltip__portal';
173
+
157
174
  try {
158
175
  var element = document.querySelector(".".concat(className));
159
176
 
@@ -5,7 +5,7 @@
5
5
  import React from 'react';
6
6
  import { TooltipProps } from './types';
7
7
  declare type TooltipWithEventsProps = {
8
- target: React.ReactElement & React.RefObject<HTMLElement>;
8
+ target: HTMLElement | React.ReactElement;
9
9
  active: boolean;
10
10
  internalId: string;
11
11
  };
@@ -2,7 +2,7 @@ import _extends from "@babel/runtime/helpers/esm/extends";
2
2
  import _defineProperty from "@babel/runtime/helpers/esm/defineProperty";
3
3
  import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
4
4
  import _objectWithoutProperties from "@babel/runtime/helpers/esm/objectWithoutProperties";
5
- var _excluded = ["children", "target"];
5
+ var _excluded = ["children"];
6
6
 
7
7
  function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) { symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); } keys.push.apply(keys, symbols); } return keys; }
8
8
 
@@ -20,15 +20,23 @@ import "core-js/modules/web.dom-collections.for-each.js";
20
20
  import "core-js/modules/es.object.get-own-property-descriptors.js";
21
21
  import React from 'react';
22
22
  import { combineDescribedBy, warn } from '../../shared/component-helper';
23
+ import TooltipContainer from './TooltipContainer';
23
24
  import { getRefElement, injectTooltipSemantic, isTouch, useHandleAria } from './TooltipHelpers';
24
25
  import TooltipPortal from './TooltipPortal';
25
26
 
26
27
  function TooltipWithEvents(props) {
27
28
  var children = props.children,
28
- target = props.target,
29
29
  restProps = _objectWithoutProperties(props, _excluded);
30
30
 
31
- var _React$useState = React.useState(false),
31
+ var active = restProps.active,
32
+ target = restProps.target,
33
+ skipPortal = restProps.skipPortal,
34
+ noAnimation = restProps.noAnimation,
35
+ showDelay = restProps.showDelay,
36
+ hideDelay = restProps.hideDelay,
37
+ internalId = restProps.internalId;
38
+
39
+ var _React$useState = React.useState(active),
32
40
  _React$useState2 = _slicedToArray(_React$useState, 2),
33
41
  isActive = _React$useState2[0],
34
42
  setIsActive = _React$useState2[1];
@@ -38,21 +46,19 @@ function TooltipWithEvents(props) {
38
46
  isNotSemanticElement = _React$useState4[0],
39
47
  setIsNotSemanticElement = _React$useState4[1];
40
48
 
41
- var _React$useState5 = React.useState(false),
49
+ var _React$useState5 = React.useState(!target),
42
50
  _React$useState6 = _slicedToArray(_React$useState5, 2),
43
51
  isMounted = _React$useState6[0],
44
52
  setIsMounted = _React$useState6[1];
45
53
 
46
54
  var onEnterTimeout = React.useRef();
47
- var targetRef = React.useRef();
55
+ var onLeaveTimeout = React.useRef();
48
56
  var cloneRef = React.useRef();
49
- React.useEffect(function () {
57
+ var targetRef = React.useRef();
58
+ React.useLayoutEffect(function () {
50
59
  targetRef.current = getRefElement(cloneRef);
51
-
52
- if (!targetRef.current) {
53
- targetRef.current = target.current;
54
- }
55
-
60
+ }, [target]);
61
+ React.useLayoutEffect(function () {
56
62
  if (targetRef.current) {
57
63
  setIsMounted(true);
58
64
  addEvents(targetRef.current);
@@ -60,28 +66,17 @@ function TooltipWithEvents(props) {
60
66
  }
61
67
 
62
68
  return function () {
63
- clearTimeout(onEnterTimeout.current);
64
- var element = targetRef.current;
65
-
66
- if (element) {
67
- try {
68
- element.removeEventListener('click', onMouseLeave);
69
- element.removeEventListener('focus', onFocus);
70
- element.removeEventListener('blur', onMouseLeave);
71
- element.removeEventListener('mouseenter', onMouseEnter);
72
- element.removeEventListener('mouseleave', onMouseLeave);
73
- element.removeEventListener('touchstart', onMouseEnter);
74
- element.removeEventListener('touchend', onMouseLeave);
75
- } catch (e) {
76
- warn(e);
77
- }
69
+ clearTimers();
70
+
71
+ if (targetRef.current) {
72
+ removeEvents(targetRef.current);
78
73
  }
79
74
  };
80
75
  }, []);
81
76
 
82
77
  var handleSemanticElement = function handleSemanticElement() {
83
78
  try {
84
- var targetElement = document.querySelector("*[aria-describedby*=\"".concat(props.internalId, "\"]"));
79
+ var targetElement = document.querySelector("*[aria-describedby*=\"".concat(internalId, "\"]"));
85
80
 
86
81
  if (targetElement) {
87
82
  var role = targetElement.getAttribute('role');
@@ -110,16 +105,29 @@ function TooltipWithEvents(props) {
110
105
  }
111
106
  };
112
107
 
113
- var onFocus = function onFocus(e) {
108
+ var removeEvents = function removeEvents(element) {
114
109
  try {
115
- if (document.documentElement.getAttribute('data-whatintent') === 'keyboard') {
116
- return onMouseEnter(e);
117
- }
110
+ element.removeEventListener('click', onMouseLeave);
111
+ element.removeEventListener('focus', onFocus);
112
+ element.removeEventListener('blur', onMouseLeave);
113
+ element.removeEventListener('mouseenter', onMouseEnter);
114
+ element.removeEventListener('mouseleave', onMouseLeave);
115
+ element.removeEventListener('touchstart', onMouseEnter);
116
+ element.removeEventListener('touchend', onMouseLeave);
118
117
  } catch (e) {
119
118
  warn(e);
120
119
  }
121
120
  };
122
121
 
122
+ var clearTimers = function clearTimers() {
123
+ clearTimeout(onEnterTimeout.current);
124
+ clearTimeout(onLeaveTimeout.current);
125
+ };
126
+
127
+ var onFocus = function onFocus(e) {
128
+ return onMouseEnter(e);
129
+ };
130
+
123
131
  var onMouseEnter = function onMouseEnter(e) {
124
132
  try {
125
133
  if (isTouch(e.type)) {
@@ -134,15 +142,19 @@ function TooltipWithEvents(props) {
134
142
  setIsActive(true);
135
143
  };
136
144
 
137
- if (props.noAnimation || globalThis.IS_TEST) {
145
+ if (noAnimation || globalThis.IS_TEST) {
138
146
  run();
139
147
  } else {
140
- clearTimeout(onEnterTimeout.current);
141
- onEnterTimeout.current = setTimeout(run, parseFloat(String(props.showDelay)) || 1);
148
+ clearTimers();
149
+ onEnterTimeout.current = setTimeout(run, parseFloat(String(showDelay)) || 1);
142
150
  }
143
151
  };
144
152
 
145
153
  var onMouseLeave = function onMouseLeave(e) {
154
+ if (active) {
155
+ return;
156
+ }
157
+
146
158
  try {
147
159
  if (isTouch(e.type)) {
148
160
  var elem = e.currentTarget;
@@ -152,8 +164,17 @@ function TooltipWithEvents(props) {
152
164
  warn(e);
153
165
  }
154
166
 
155
- clearTimeout(onEnterTimeout.current);
156
- setIsActive(false);
167
+ clearTimers();
168
+
169
+ var run = function run() {
170
+ setIsActive(false);
171
+ };
172
+
173
+ if (skipPortal) {
174
+ onLeaveTimeout.current = setTimeout(run, parseFloat(String(hideDelay)));
175
+ } else {
176
+ run();
177
+ }
157
178
  };
158
179
 
159
180
  var componentWrapper = React.useMemo(function () {
@@ -164,19 +185,23 @@ function TooltipWithEvents(props) {
164
185
  return React.cloneElement(target, _objectSpread(_objectSpread({
165
186
  ref: cloneRef
166
187
  }, params), {}, {
167
- 'aria-describedby': combineDescribedBy(target.props, props.internalId)
188
+ 'aria-describedby': combineDescribedBy(target.props, internalId)
168
189
  }));
190
+ } else {
191
+ cloneRef.current = target;
169
192
  }
170
193
 
171
194
  return null;
172
195
  }, [target]);
173
- useHandleAria(target, props.internalId);
174
- return React.createElement(React.Fragment, null, componentWrapper, isMounted && React.createElement(TooltipPortal, _extends({
175
- key: "tooltip",
196
+ useHandleAria(targetRef.current, internalId);
197
+ return React.createElement(React.Fragment, null, isMounted && (skipPortal ? React.createElement(TooltipContainer, _extends({}, restProps, {
198
+ active: isActive,
199
+ targetElement: targetRef.current
200
+ }), children) : React.createElement(TooltipPortal, _extends({}, restProps, {
176
201
  active: isActive,
177
- target: targetRef.current,
202
+ targetElement: targetRef.current,
178
203
  keepInDOM: true
179
- }, restProps), children));
204
+ }), children)), componentWrapper);
180
205
  }
181
206
 
182
207
  export default TooltipWithEvents;
@@ -24,5 +24,6 @@ export declare type TooltipProps = IncludeSnakeCase<{
24
24
  tooltip?: React.ReactNode;
25
25
  className?: string;
26
26
  children?: React.ReactNode;
27
+ style?: React.CSSProperties;
27
28
  }>;
28
29
  export declare type TooltipAllProps = TooltipProps & SpacingProps & Omit<React.HTMLProps<HTMLElement>, keyof TooltipProps>;