@atlaskit/tooltip 20.11.0 → 20.12.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,20 @@
1
1
  # @atlaskit/tooltip
2
2
 
3
+ ## 20.12.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [`2e7328e8eff65`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/2e7328e8eff65) -
8
+ Adds `mouse-x` and `mouse-y` positions for tooltips behind the
9
+ `platform_dst_nav4_side_nav_resize_tooltip_feedback` gate. These positions only use the mouse
10
+ coordinates on one axis, but are otherwise relative to the target.
11
+
12
+ ## 20.11.1
13
+
14
+ ### Patch Changes
15
+
16
+ - Updated dependencies
17
+
3
18
  ## 20.11.0
4
19
 
5
20
  ### Minor Changes
@@ -4,6 +4,7 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.show = show;
7
+ var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
7
8
  var _sharedSchedule = require("./shared-schedule");
8
9
  // This file is a singleton for managing tooltips
9
10
 
@@ -137,7 +138,13 @@ function show(entry) {
137
138
  isActive: isActive,
138
139
  requestHide: requestHide,
139
140
  finishHideAnimation: finishHideAnimation,
140
- mousePosition: getInitialMouse()
141
+ // Removing old `mousePosition` behind gate because it stored a function.
142
+ // With the gate we just store the coords which are easier to work with.
143
+ mousePosition: (0, _platformFeatureFlags.fg)('platform_dst_nav4_side_nav_resize_tooltip_feedback') ? undefined : getInitialMouse(),
144
+ mousePos: entry.source.type === 'mouse' && (0, _platformFeatureFlags.fg)('platform_dst_nav4_side_nav_resize_tooltip_feedback') ? {
145
+ clientX: entry.source.clientX,
146
+ clientY: entry.source.clientY
147
+ } : null
141
148
  };
142
149
  return result;
143
150
  }
@@ -17,6 +17,7 @@ var _useCloseOnEscapePress = _interopRequireDefault(require("@atlaskit/ds-lib/us
17
17
  var _useStableRef = _interopRequireDefault(require("@atlaskit/ds-lib/use-stable-ref"));
18
18
  var _openLayerObserver = require("@atlaskit/layering/experimental/open-layer-observer");
19
19
  var _motion = require("@atlaskit/motion");
20
+ var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
20
21
  var _popper = require("@atlaskit/popper");
21
22
  var _portal = _interopRequireDefault(require("@atlaskit/portal"));
22
23
  var _constants = require("@atlaskit/theme/constants");
@@ -32,7 +33,7 @@ var tooltipZIndex = _constants.layers.tooltip();
32
33
  var analyticsAttributes = {
33
34
  componentName: 'tooltip',
34
35
  packageName: "@atlaskit/tooltip",
35
- packageVersion: "20.10.0"
36
+ packageVersion: "0.0.0-development"
36
37
  };
37
38
 
38
39
  // Inverts motion direction
@@ -90,7 +91,9 @@ function Tooltip(_ref) {
90
91
  _ref$isScreenReaderAn = _ref.isScreenReaderAnnouncementDisabled,
91
92
  isScreenReaderAnnouncementDisabled = _ref$isScreenReaderAn === void 0 ? false : _ref$isScreenReaderAn,
92
93
  shortcut = _ref.shortcut;
93
- var tooltipPosition = position === 'mouse' ? mousePosition : position;
94
+ // Not using a gate for this check. When the gate is disabled `mouse-y` and `mouse-x` are treated as `mouse`.
95
+ var isMousePosition = position === 'mouse' || position === 'mouse-y' || position === 'mouse-x';
96
+ var tooltipPosition = isMousePosition ? mousePosition : position;
94
97
  var onShowHandler = (0, _analyticsNext.usePlatformLeafSyntheticEventHandler)(_objectSpread({
95
98
  fn: onShow,
96
99
  action: 'displayed',
@@ -323,18 +326,22 @@ function Tooltip(_ref) {
323
326
  return;
324
327
  }
325
328
  event.preventDefault();
326
- var source = position === 'mouse' ? {
329
+ var source = isMousePosition ? {
327
330
  type: 'mouse',
328
331
  // TODO: ideally not recalculating this object each time
329
- mouse: (0, _utilities.getMousePosition)({
332
+ // Removing old `mouse` behind gate because it stored a function.
333
+ // With the gate we just store the coords which are easier to work with.
334
+ mouse: (0, _platformFeatureFlags.fg)('platform_dst_nav4_side_nav_resize_tooltip_feedback') ? undefined : (0, _utilities.getMousePosition)({
330
335
  left: event.clientX,
331
336
  top: event.clientY
332
- })
337
+ }),
338
+ clientX: event.clientX,
339
+ clientY: event.clientY
333
340
  } : {
334
341
  type: 'keyboard'
335
342
  };
336
343
  tryShowTooltip(source);
337
- }, [position, tryShowTooltip]);
344
+ }, [isMousePosition, tryShowTooltip]);
338
345
 
339
346
  // Ideally we would be using onMouseEnter here, but
340
347
  // because we are binding the event to the target parent
@@ -358,13 +365,19 @@ function Tooltip(_ref) {
358
365
  });
359
366
  }
360
367
  }, []);
361
- var onMouseMove = position === 'mouse' ? function (event) {
368
+ var onMouseMove = isMousePosition ? function (event) {
362
369
  var _apiRef$current3;
363
370
  if ((_apiRef$current3 = apiRef.current) !== null && _apiRef$current3 !== void 0 && _apiRef$current3.isActive()) {
364
- apiRef.current.mousePosition = (0, _utilities.getMousePosition)({
365
- left: event.clientX,
366
- top: event.clientY
367
- });
371
+ if (!(0, _platformFeatureFlags.fg)('platform_dst_nav4_side_nav_resize_tooltip_feedback')) {
372
+ apiRef.current.mousePosition = (0, _utilities.getMousePosition)({
373
+ left: event.clientX,
374
+ top: event.clientY
375
+ });
376
+ }
377
+ apiRef.current.mousePos = {
378
+ clientX: event.clientX,
379
+ clientY: event.clientY
380
+ };
368
381
  }
369
382
  } : undefined;
370
383
  var onMouseOverTooltip = (0, _react.useCallback)(function () {
@@ -381,7 +394,7 @@ function Tooltip(_ref) {
381
394
  if (!e.target.matches(':focus-visible')) {
382
395
  return;
383
396
  }
384
- } catch (_) {
397
+ } catch (_unused) {
385
398
  // Ignore errors from environments that don't support :focus-visible
386
399
  }
387
400
 
@@ -431,10 +444,16 @@ function Tooltip(_ref) {
431
444
  onClose: handleOpenLayerObserverCloseSignal
432
445
  });
433
446
  var getReferenceElement = function getReferenceElement() {
434
- var _apiRef$current5;
435
- if (position === 'mouse' && (_apiRef$current5 = apiRef.current) !== null && _apiRef$current5 !== void 0 && _apiRef$current5.mousePosition) {
436
- var _apiRef$current6;
437
- return (_apiRef$current6 = apiRef.current) === null || _apiRef$current6 === void 0 ? void 0 : _apiRef$current6.mousePosition;
447
+ var _apiRef$current5, _apiRef$current6;
448
+ if (isMousePosition && (_apiRef$current5 = apiRef.current) !== null && _apiRef$current5 !== void 0 && _apiRef$current5.mousePos && targetRef.current && (0, _platformFeatureFlags.fg)('platform_dst_nav4_side_nav_resize_tooltip_feedback')) {
449
+ return (0, _utilities.getVirtualElementFromMousePos)(apiRef.current.mousePos, {
450
+ targetElement: targetRef.current,
451
+ tooltipPosition: position
452
+ });
453
+ }
454
+ if (isMousePosition && (_apiRef$current6 = apiRef.current) !== null && _apiRef$current6 !== void 0 && _apiRef$current6.mousePosition && !(0, _platformFeatureFlags.fg)('platform_dst_nav4_side_nav_resize_tooltip_feedback')) {
455
+ var _apiRef$current7;
456
+ return (_apiRef$current7 = apiRef.current) === null || _apiRef$current7 === void 0 ? void 0 : _apiRef$current7.mousePosition;
438
457
  }
439
458
  return targetRef.current || undefined;
440
459
  };
@@ -514,7 +533,7 @@ function Tooltip(_ref) {
514
533
  // Invert the entrance and exit directions.
515
534
  // E.g. a tooltip's position is on the 'right', it should enter from and exit to the 'left'
516
535
  // This gives the effect the tooltip is appearing from the target
517
- var direction = position === 'mouse' ? undefined : invertedDirection[getDirectionFromPlacement(placement)];
536
+ var direction = isMousePosition ? undefined : invertedDirection[getDirectionFromPlacement(placement)];
518
537
  return /*#__PURE__*/_react.default.createElement(_motion.ExitingPersistence, {
519
538
  appear: true
520
539
  }, shouldRenderTooltipChildren && /*#__PURE__*/_react.default.createElement(_motion.FadeIn, {
@@ -4,6 +4,7 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.getMousePosition = getMousePosition;
7
+ exports.getVirtualElementFromMousePos = getVirtualElementFromMousePos;
7
8
  function getMousePosition(mouseCoordinates) {
8
9
  var safeMouse = mouseCoordinates || {
9
10
  top: 0,
@@ -24,4 +25,46 @@ function getMousePosition(mouseCoordinates) {
24
25
  clientWidth: 0,
25
26
  clientHeight: 0
26
27
  };
28
+ }
29
+ function getVirtualElementFromMousePos(mousePos, _ref) {
30
+ var targetElement = _ref.targetElement,
31
+ tooltipPosition = _ref.tooltipPosition;
32
+ if (tooltipPosition === 'mouse') {
33
+ return {
34
+ getBoundingClientRect: function getBoundingClientRect() {
35
+ return DOMRect.fromRect({
36
+ x: mousePos.clientX,
37
+ y: mousePos.clientY,
38
+ width: 0,
39
+ height: 0
40
+ });
41
+ }
42
+ };
43
+ }
44
+ var targetRect = targetElement.getBoundingClientRect();
45
+ if (tooltipPosition === 'mouse-x') {
46
+ return {
47
+ getBoundingClientRect: function getBoundingClientRect() {
48
+ return DOMRect.fromRect({
49
+ x: mousePos.clientX,
50
+ y: targetRect.top,
51
+ width: 0,
52
+ height: targetRect.height
53
+ });
54
+ }
55
+ };
56
+ }
57
+ if (tooltipPosition === 'mouse-y') {
58
+ return {
59
+ getBoundingClientRect: function getBoundingClientRect() {
60
+ return DOMRect.fromRect({
61
+ x: targetRect.left,
62
+ y: mousePos.clientY,
63
+ width: targetRect.width,
64
+ height: 0
65
+ });
66
+ }
67
+ };
68
+ }
69
+ throw new Error("Invalid tooltip position for virtual element: ".concat(tooltipPosition));
27
70
  }
@@ -1,3 +1,4 @@
1
+ import { fg } from '@atlaskit/platform-feature-flags';
1
2
  import { clearScheduled, scheduleTimeout } from './shared-schedule';
2
3
 
3
4
  // This file is a singleton for managing tooltips
@@ -133,7 +134,13 @@ export function show(entry) {
133
134
  isActive,
134
135
  requestHide,
135
136
  finishHideAnimation,
136
- mousePosition: getInitialMouse()
137
+ // Removing old `mousePosition` behind gate because it stored a function.
138
+ // With the gate we just store the coords which are easier to work with.
139
+ mousePosition: fg('platform_dst_nav4_side_nav_resize_tooltip_feedback') ? undefined : getInitialMouse(),
140
+ mousePos: entry.source.type === 'mouse' && fg('platform_dst_nav4_side_nav_resize_tooltip_feedback') ? {
141
+ clientX: entry.source.clientX,
142
+ clientY: entry.source.clientY
143
+ } : null
137
144
  };
138
145
  return result;
139
146
  }
@@ -7,6 +7,7 @@ import useCloseOnEscapePress from '@atlaskit/ds-lib/use-close-on-escape-press';
7
7
  import useStableRef from '@atlaskit/ds-lib/use-stable-ref';
8
8
  import { useNotifyOpenLayerObserver } from '@atlaskit/layering/experimental/open-layer-observer';
9
9
  import { ExitingPersistence, FadeIn } from '@atlaskit/motion';
10
+ import { fg } from '@atlaskit/platform-feature-flags';
10
11
  import { Popper } from '@atlaskit/popper';
11
12
  import Portal from '@atlaskit/portal';
12
13
  import { layers } from '@atlaskit/theme/constants';
@@ -14,12 +15,12 @@ import { register } from './internal/drag-manager';
14
15
  import { show } from './internal/tooltip-manager';
15
16
  import useUniqueId from './internal/use-unique-id';
16
17
  import TooltipContainer from './tooltip-container';
17
- import { getMousePosition } from './utilities';
18
+ import { getMousePosition, getVirtualElementFromMousePos } from './utilities';
18
19
  const tooltipZIndex = layers.tooltip();
19
20
  const analyticsAttributes = {
20
21
  componentName: 'tooltip',
21
22
  packageName: "@atlaskit/tooltip",
22
- packageVersion: "20.10.0"
23
+ packageVersion: "0.0.0-development"
23
24
  };
24
25
 
25
26
  // Inverts motion direction
@@ -64,7 +65,9 @@ function Tooltip({
64
65
  isScreenReaderAnnouncementDisabled = false,
65
66
  shortcut
66
67
  }) {
67
- const tooltipPosition = position === 'mouse' ? mousePosition : position;
68
+ // Not using a gate for this check. When the gate is disabled `mouse-y` and `mouse-x` are treated as `mouse`.
69
+ const isMousePosition = position === 'mouse' || position === 'mouse-y' || position === 'mouse-x';
70
+ const tooltipPosition = isMousePosition ? mousePosition : position;
68
71
  const onShowHandler = usePlatformLeafSyntheticEventHandler({
69
72
  fn: onShow,
70
73
  action: 'displayed',
@@ -299,18 +302,22 @@ function Tooltip({
299
302
  return;
300
303
  }
301
304
  event.preventDefault();
302
- const source = position === 'mouse' ? {
305
+ const source = isMousePosition ? {
303
306
  type: 'mouse',
304
307
  // TODO: ideally not recalculating this object each time
305
- mouse: getMousePosition({
308
+ // Removing old `mouse` behind gate because it stored a function.
309
+ // With the gate we just store the coords which are easier to work with.
310
+ mouse: fg('platform_dst_nav4_side_nav_resize_tooltip_feedback') ? undefined : getMousePosition({
306
311
  left: event.clientX,
307
312
  top: event.clientY
308
- })
313
+ }),
314
+ clientX: event.clientX,
315
+ clientY: event.clientY
309
316
  } : {
310
317
  type: 'keyboard'
311
318
  };
312
319
  tryShowTooltip(source);
313
- }, [position, tryShowTooltip]);
320
+ }, [isMousePosition, tryShowTooltip]);
314
321
 
315
322
  // Ideally we would be using onMouseEnter here, but
316
323
  // because we are binding the event to the target parent
@@ -334,13 +341,19 @@ function Tooltip({
334
341
  });
335
342
  }
336
343
  }, []);
337
- const onMouseMove = position === 'mouse' ? event => {
344
+ const onMouseMove = isMousePosition ? event => {
338
345
  var _apiRef$current3;
339
346
  if ((_apiRef$current3 = apiRef.current) !== null && _apiRef$current3 !== void 0 && _apiRef$current3.isActive()) {
340
- apiRef.current.mousePosition = getMousePosition({
341
- left: event.clientX,
342
- top: event.clientY
343
- });
347
+ if (!fg('platform_dst_nav4_side_nav_resize_tooltip_feedback')) {
348
+ apiRef.current.mousePosition = getMousePosition({
349
+ left: event.clientX,
350
+ top: event.clientY
351
+ });
352
+ }
353
+ apiRef.current.mousePos = {
354
+ clientX: event.clientX,
355
+ clientY: event.clientY
356
+ };
344
357
  }
345
358
  } : undefined;
346
359
  const onMouseOverTooltip = useCallback(() => {
@@ -357,7 +370,7 @@ function Tooltip({
357
370
  if (!e.target.matches(':focus-visible')) {
358
371
  return;
359
372
  }
360
- } catch (_) {
373
+ } catch {
361
374
  // Ignore errors from environments that don't support :focus-visible
362
375
  }
363
376
 
@@ -407,10 +420,16 @@ function Tooltip({
407
420
  onClose: handleOpenLayerObserverCloseSignal
408
421
  });
409
422
  const getReferenceElement = () => {
410
- var _apiRef$current5;
411
- if (position === 'mouse' && (_apiRef$current5 = apiRef.current) !== null && _apiRef$current5 !== void 0 && _apiRef$current5.mousePosition) {
412
- var _apiRef$current6;
413
- return (_apiRef$current6 = apiRef.current) === null || _apiRef$current6 === void 0 ? void 0 : _apiRef$current6.mousePosition;
423
+ var _apiRef$current5, _apiRef$current6;
424
+ if (isMousePosition && (_apiRef$current5 = apiRef.current) !== null && _apiRef$current5 !== void 0 && _apiRef$current5.mousePos && targetRef.current && fg('platform_dst_nav4_side_nav_resize_tooltip_feedback')) {
425
+ return getVirtualElementFromMousePos(apiRef.current.mousePos, {
426
+ targetElement: targetRef.current,
427
+ tooltipPosition: position
428
+ });
429
+ }
430
+ if (isMousePosition && (_apiRef$current6 = apiRef.current) !== null && _apiRef$current6 !== void 0 && _apiRef$current6.mousePosition && !fg('platform_dst_nav4_side_nav_resize_tooltip_feedback')) {
431
+ var _apiRef$current7;
432
+ return (_apiRef$current7 = apiRef.current) === null || _apiRef$current7 === void 0 ? void 0 : _apiRef$current7.mousePosition;
414
433
  }
415
434
  return targetRef.current || undefined;
416
435
  };
@@ -490,7 +509,7 @@ function Tooltip({
490
509
  // Invert the entrance and exit directions.
491
510
  // E.g. a tooltip's position is on the 'right', it should enter from and exit to the 'left'
492
511
  // This gives the effect the tooltip is appearing from the target
493
- const direction = position === 'mouse' ? undefined : invertedDirection[getDirectionFromPlacement(placement)];
512
+ const direction = isMousePosition ? undefined : invertedDirection[getDirectionFromPlacement(placement)];
494
513
  return /*#__PURE__*/React.createElement(ExitingPersistence, {
495
514
  appear: true
496
515
  }, shouldRenderTooltipChildren && /*#__PURE__*/React.createElement(FadeIn, {
@@ -16,4 +16,41 @@ export function getMousePosition(mouseCoordinates) {
16
16
  clientWidth: 0,
17
17
  clientHeight: 0
18
18
  };
19
+ }
20
+ export function getVirtualElementFromMousePos(mousePos, {
21
+ targetElement,
22
+ tooltipPosition
23
+ }) {
24
+ if (tooltipPosition === 'mouse') {
25
+ return {
26
+ getBoundingClientRect: () => DOMRect.fromRect({
27
+ x: mousePos.clientX,
28
+ y: mousePos.clientY,
29
+ width: 0,
30
+ height: 0
31
+ })
32
+ };
33
+ }
34
+ const targetRect = targetElement.getBoundingClientRect();
35
+ if (tooltipPosition === 'mouse-x') {
36
+ return {
37
+ getBoundingClientRect: () => DOMRect.fromRect({
38
+ x: mousePos.clientX,
39
+ y: targetRect.top,
40
+ width: 0,
41
+ height: targetRect.height
42
+ })
43
+ };
44
+ }
45
+ if (tooltipPosition === 'mouse-y') {
46
+ return {
47
+ getBoundingClientRect: () => DOMRect.fromRect({
48
+ x: targetRect.left,
49
+ y: mousePos.clientY,
50
+ width: targetRect.width,
51
+ height: 0
52
+ })
53
+ };
54
+ }
55
+ throw new Error(`Invalid tooltip position for virtual element: ${tooltipPosition}`);
19
56
  }
@@ -1,3 +1,4 @@
1
+ import { fg } from '@atlaskit/platform-feature-flags';
1
2
  import { clearScheduled, scheduleTimeout } from './shared-schedule';
2
3
 
3
4
  // This file is a singleton for managing tooltips
@@ -132,7 +133,13 @@ export function show(entry) {
132
133
  isActive: isActive,
133
134
  requestHide: requestHide,
134
135
  finishHideAnimation: finishHideAnimation,
135
- mousePosition: getInitialMouse()
136
+ // Removing old `mousePosition` behind gate because it stored a function.
137
+ // With the gate we just store the coords which are easier to work with.
138
+ mousePosition: fg('platform_dst_nav4_side_nav_resize_tooltip_feedback') ? undefined : getInitialMouse(),
139
+ mousePos: entry.source.type === 'mouse' && fg('platform_dst_nav4_side_nav_resize_tooltip_feedback') ? {
140
+ clientX: entry.source.clientX,
141
+ clientY: entry.source.clientY
142
+ } : null
136
143
  };
137
144
  return result;
138
145
  }
@@ -11,6 +11,7 @@ import useCloseOnEscapePress from '@atlaskit/ds-lib/use-close-on-escape-press';
11
11
  import useStableRef from '@atlaskit/ds-lib/use-stable-ref';
12
12
  import { useNotifyOpenLayerObserver } from '@atlaskit/layering/experimental/open-layer-observer';
13
13
  import { ExitingPersistence, FadeIn } from '@atlaskit/motion';
14
+ import { fg } from '@atlaskit/platform-feature-flags';
14
15
  import { Popper } from '@atlaskit/popper';
15
16
  import Portal from '@atlaskit/portal';
16
17
  import { layers } from '@atlaskit/theme/constants';
@@ -18,12 +19,12 @@ import { register } from './internal/drag-manager';
18
19
  import { show } from './internal/tooltip-manager';
19
20
  import useUniqueId from './internal/use-unique-id';
20
21
  import TooltipContainer from './tooltip-container';
21
- import { getMousePosition } from './utilities';
22
+ import { getMousePosition, getVirtualElementFromMousePos } from './utilities';
22
23
  var tooltipZIndex = layers.tooltip();
23
24
  var analyticsAttributes = {
24
25
  componentName: 'tooltip',
25
26
  packageName: "@atlaskit/tooltip",
26
- packageVersion: "20.10.0"
27
+ packageVersion: "0.0.0-development"
27
28
  };
28
29
 
29
30
  // Inverts motion direction
@@ -81,7 +82,9 @@ function Tooltip(_ref) {
81
82
  _ref$isScreenReaderAn = _ref.isScreenReaderAnnouncementDisabled,
82
83
  isScreenReaderAnnouncementDisabled = _ref$isScreenReaderAn === void 0 ? false : _ref$isScreenReaderAn,
83
84
  shortcut = _ref.shortcut;
84
- var tooltipPosition = position === 'mouse' ? mousePosition : position;
85
+ // Not using a gate for this check. When the gate is disabled `mouse-y` and `mouse-x` are treated as `mouse`.
86
+ var isMousePosition = position === 'mouse' || position === 'mouse-y' || position === 'mouse-x';
87
+ var tooltipPosition = isMousePosition ? mousePosition : position;
85
88
  var onShowHandler = usePlatformLeafSyntheticEventHandler(_objectSpread({
86
89
  fn: onShow,
87
90
  action: 'displayed',
@@ -314,18 +317,22 @@ function Tooltip(_ref) {
314
317
  return;
315
318
  }
316
319
  event.preventDefault();
317
- var source = position === 'mouse' ? {
320
+ var source = isMousePosition ? {
318
321
  type: 'mouse',
319
322
  // TODO: ideally not recalculating this object each time
320
- mouse: getMousePosition({
323
+ // Removing old `mouse` behind gate because it stored a function.
324
+ // With the gate we just store the coords which are easier to work with.
325
+ mouse: fg('platform_dst_nav4_side_nav_resize_tooltip_feedback') ? undefined : getMousePosition({
321
326
  left: event.clientX,
322
327
  top: event.clientY
323
- })
328
+ }),
329
+ clientX: event.clientX,
330
+ clientY: event.clientY
324
331
  } : {
325
332
  type: 'keyboard'
326
333
  };
327
334
  tryShowTooltip(source);
328
- }, [position, tryShowTooltip]);
335
+ }, [isMousePosition, tryShowTooltip]);
329
336
 
330
337
  // Ideally we would be using onMouseEnter here, but
331
338
  // because we are binding the event to the target parent
@@ -349,13 +356,19 @@ function Tooltip(_ref) {
349
356
  });
350
357
  }
351
358
  }, []);
352
- var onMouseMove = position === 'mouse' ? function (event) {
359
+ var onMouseMove = isMousePosition ? function (event) {
353
360
  var _apiRef$current3;
354
361
  if ((_apiRef$current3 = apiRef.current) !== null && _apiRef$current3 !== void 0 && _apiRef$current3.isActive()) {
355
- apiRef.current.mousePosition = getMousePosition({
356
- left: event.clientX,
357
- top: event.clientY
358
- });
362
+ if (!fg('platform_dst_nav4_side_nav_resize_tooltip_feedback')) {
363
+ apiRef.current.mousePosition = getMousePosition({
364
+ left: event.clientX,
365
+ top: event.clientY
366
+ });
367
+ }
368
+ apiRef.current.mousePos = {
369
+ clientX: event.clientX,
370
+ clientY: event.clientY
371
+ };
359
372
  }
360
373
  } : undefined;
361
374
  var onMouseOverTooltip = useCallback(function () {
@@ -372,7 +385,7 @@ function Tooltip(_ref) {
372
385
  if (!e.target.matches(':focus-visible')) {
373
386
  return;
374
387
  }
375
- } catch (_) {
388
+ } catch (_unused) {
376
389
  // Ignore errors from environments that don't support :focus-visible
377
390
  }
378
391
 
@@ -422,10 +435,16 @@ function Tooltip(_ref) {
422
435
  onClose: handleOpenLayerObserverCloseSignal
423
436
  });
424
437
  var getReferenceElement = function getReferenceElement() {
425
- var _apiRef$current5;
426
- if (position === 'mouse' && (_apiRef$current5 = apiRef.current) !== null && _apiRef$current5 !== void 0 && _apiRef$current5.mousePosition) {
427
- var _apiRef$current6;
428
- return (_apiRef$current6 = apiRef.current) === null || _apiRef$current6 === void 0 ? void 0 : _apiRef$current6.mousePosition;
438
+ var _apiRef$current5, _apiRef$current6;
439
+ if (isMousePosition && (_apiRef$current5 = apiRef.current) !== null && _apiRef$current5 !== void 0 && _apiRef$current5.mousePos && targetRef.current && fg('platform_dst_nav4_side_nav_resize_tooltip_feedback')) {
440
+ return getVirtualElementFromMousePos(apiRef.current.mousePos, {
441
+ targetElement: targetRef.current,
442
+ tooltipPosition: position
443
+ });
444
+ }
445
+ if (isMousePosition && (_apiRef$current6 = apiRef.current) !== null && _apiRef$current6 !== void 0 && _apiRef$current6.mousePosition && !fg('platform_dst_nav4_side_nav_resize_tooltip_feedback')) {
446
+ var _apiRef$current7;
447
+ return (_apiRef$current7 = apiRef.current) === null || _apiRef$current7 === void 0 ? void 0 : _apiRef$current7.mousePosition;
429
448
  }
430
449
  return targetRef.current || undefined;
431
450
  };
@@ -505,7 +524,7 @@ function Tooltip(_ref) {
505
524
  // Invert the entrance and exit directions.
506
525
  // E.g. a tooltip's position is on the 'right', it should enter from and exit to the 'left'
507
526
  // This gives the effect the tooltip is appearing from the target
508
- var direction = position === 'mouse' ? undefined : invertedDirection[getDirectionFromPlacement(placement)];
527
+ var direction = isMousePosition ? undefined : invertedDirection[getDirectionFromPlacement(placement)];
509
528
  return /*#__PURE__*/React.createElement(ExitingPersistence, {
510
529
  appear: true
511
530
  }, shouldRenderTooltipChildren && /*#__PURE__*/React.createElement(FadeIn, {
@@ -18,4 +18,46 @@ export function getMousePosition(mouseCoordinates) {
18
18
  clientWidth: 0,
19
19
  clientHeight: 0
20
20
  };
21
+ }
22
+ export function getVirtualElementFromMousePos(mousePos, _ref) {
23
+ var targetElement = _ref.targetElement,
24
+ tooltipPosition = _ref.tooltipPosition;
25
+ if (tooltipPosition === 'mouse') {
26
+ return {
27
+ getBoundingClientRect: function getBoundingClientRect() {
28
+ return DOMRect.fromRect({
29
+ x: mousePos.clientX,
30
+ y: mousePos.clientY,
31
+ width: 0,
32
+ height: 0
33
+ });
34
+ }
35
+ };
36
+ }
37
+ var targetRect = targetElement.getBoundingClientRect();
38
+ if (tooltipPosition === 'mouse-x') {
39
+ return {
40
+ getBoundingClientRect: function getBoundingClientRect() {
41
+ return DOMRect.fromRect({
42
+ x: mousePos.clientX,
43
+ y: targetRect.top,
44
+ width: 0,
45
+ height: targetRect.height
46
+ });
47
+ }
48
+ };
49
+ }
50
+ if (tooltipPosition === 'mouse-y') {
51
+ return {
52
+ getBoundingClientRect: function getBoundingClientRect() {
53
+ return DOMRect.fromRect({
54
+ x: targetRect.left,
55
+ y: mousePos.clientY,
56
+ width: targetRect.width,
57
+ height: 0
58
+ });
59
+ }
60
+ };
61
+ }
62
+ throw new Error("Invalid tooltip position for virtual element: ".concat(tooltipPosition));
21
63
  }
@@ -1,7 +1,10 @@
1
- import { type FakeMouseElement } from '../utilities';
1
+ import type { VirtualElement } from '@popperjs/core';
2
+ import type { FakeMouseElement } from '../utilities';
2
3
  export type Source = {
3
4
  type: 'mouse';
4
- mouse: FakeMouseElement;
5
+ mouse?: VirtualElement | FakeMouseElement;
6
+ clientX: number;
7
+ clientY: number;
5
8
  } | {
6
9
  type: 'keyboard';
7
10
  };
@@ -18,7 +21,8 @@ export type Entry = {
18
21
  };
19
22
  export type API = {
20
23
  isActive: () => boolean;
21
- mousePosition: FakeMouseElement | null;
24
+ mousePosition: VirtualElement | FakeMouseElement | null | undefined;
25
+ mousePos: Pick<React.MouseEvent<HTMLElement>, 'clientX' | 'clientY'> | null;
22
26
  requestHide: (value: {
23
27
  isImmediate: boolean;
24
28
  }) => void;
@@ -3,7 +3,7 @@ import { type UIAnalyticsEvent } from '@atlaskit/analytics-next';
3
3
  import { type Placement } from '@atlaskit/popper';
4
4
  import { type TooltipPrimitiveProps } from './tooltip-primitive';
5
5
  export type PositionTypeBase = Placement;
6
- export type PositionType = PositionTypeBase | 'mouse';
6
+ export type PositionType = PositionTypeBase | 'mouse' | 'mouse-y' | 'mouse-x';
7
7
  export interface TriggerProps {
8
8
  onMouseOver: (event: React.MouseEvent<HTMLElement>) => void;
9
9
  onMouseOut: (event: React.MouseEvent<HTMLElement>) => void;
@@ -56,7 +56,7 @@ export interface TooltipProps {
56
56
  hideTooltipOnMouseDown?: boolean;
57
57
  /**
58
58
  * Where the tooltip should appear relative to the mouse pointer.
59
- * Only use this when the `position` prop is set to `"mouse"`.
59
+ * Only use this when the `position` prop is set to `"mouse"`, `"mouse-y"`, or `"mouse-x"`.
60
60
  * When interacting with the target element using a keyboard, it will use this position against the target element instead.
61
61
  */
62
62
  mousePosition?: PositionTypeBase;
@@ -92,6 +92,8 @@ export interface TooltipProps {
92
92
  /**
93
93
  * Where the tooltip should appear relative to its target.
94
94
  * If set to `"mouse"`, the tooltip will display next to the mouse pointer instead.
95
+ * If set to `"mouse-y"`, the tooltip will use the mouse Y coordinate but the target X coordinate.
96
+ * If set to `"mouse-x"`, the tooltip will use the mouse X coordinate but the target Y coordinate.
95
97
  * Make sure to utilize the `mousePosition` if you want to customize where the tooltip will show in relation to the mouse.
96
98
  */
97
99
  position?: PositionType;
@@ -1,3 +1,4 @@
1
+ import type { VirtualElement } from '@popperjs/core';
1
2
  export interface FakeMouseElement {
2
3
  getBoundingClientRect: () => {
3
4
  top: number;
@@ -14,3 +15,10 @@ export declare function getMousePosition(mouseCoordinates: {
14
15
  top: number;
15
16
  left: number;
16
17
  }): FakeMouseElement;
18
+ export declare function getVirtualElementFromMousePos(mousePos: {
19
+ clientX: number;
20
+ clientY: number;
21
+ }, { targetElement, tooltipPosition, }: {
22
+ targetElement: HTMLElement;
23
+ tooltipPosition: 'mouse' | 'mouse-x' | 'mouse-y';
24
+ }): VirtualElement;
@@ -1,7 +1,10 @@
1
- import { type FakeMouseElement } from '../utilities';
1
+ import type { VirtualElement } from '@popperjs/core';
2
+ import type { FakeMouseElement } from '../utilities';
2
3
  export type Source = {
3
4
  type: 'mouse';
4
- mouse: FakeMouseElement;
5
+ mouse?: VirtualElement | FakeMouseElement;
6
+ clientX: number;
7
+ clientY: number;
5
8
  } | {
6
9
  type: 'keyboard';
7
10
  };
@@ -18,7 +21,8 @@ export type Entry = {
18
21
  };
19
22
  export type API = {
20
23
  isActive: () => boolean;
21
- mousePosition: FakeMouseElement | null;
24
+ mousePosition: VirtualElement | FakeMouseElement | null | undefined;
25
+ mousePos: Pick<React.MouseEvent<HTMLElement>, 'clientX' | 'clientY'> | null;
22
26
  requestHide: (value: {
23
27
  isImmediate: boolean;
24
28
  }) => void;
@@ -3,7 +3,7 @@ import { type UIAnalyticsEvent } from '@atlaskit/analytics-next';
3
3
  import { type Placement } from '@atlaskit/popper';
4
4
  import { type TooltipPrimitiveProps } from './tooltip-primitive';
5
5
  export type PositionTypeBase = Placement;
6
- export type PositionType = PositionTypeBase | 'mouse';
6
+ export type PositionType = PositionTypeBase | 'mouse' | 'mouse-y' | 'mouse-x';
7
7
  export interface TriggerProps {
8
8
  onMouseOver: (event: React.MouseEvent<HTMLElement>) => void;
9
9
  onMouseOut: (event: React.MouseEvent<HTMLElement>) => void;
@@ -56,7 +56,7 @@ export interface TooltipProps {
56
56
  hideTooltipOnMouseDown?: boolean;
57
57
  /**
58
58
  * Where the tooltip should appear relative to the mouse pointer.
59
- * Only use this when the `position` prop is set to `"mouse"`.
59
+ * Only use this when the `position` prop is set to `"mouse"`, `"mouse-y"`, or `"mouse-x"`.
60
60
  * When interacting with the target element using a keyboard, it will use this position against the target element instead.
61
61
  */
62
62
  mousePosition?: PositionTypeBase;
@@ -92,6 +92,8 @@ export interface TooltipProps {
92
92
  /**
93
93
  * Where the tooltip should appear relative to its target.
94
94
  * If set to `"mouse"`, the tooltip will display next to the mouse pointer instead.
95
+ * If set to `"mouse-y"`, the tooltip will use the mouse Y coordinate but the target X coordinate.
96
+ * If set to `"mouse-x"`, the tooltip will use the mouse X coordinate but the target Y coordinate.
95
97
  * Make sure to utilize the `mousePosition` if you want to customize where the tooltip will show in relation to the mouse.
96
98
  */
97
99
  position?: PositionType;
@@ -1,3 +1,4 @@
1
+ import type { VirtualElement } from '@popperjs/core';
1
2
  export interface FakeMouseElement {
2
3
  getBoundingClientRect: () => {
3
4
  top: number;
@@ -14,3 +15,10 @@ export declare function getMousePosition(mouseCoordinates: {
14
15
  top: number;
15
16
  left: number;
16
17
  }): FakeMouseElement;
18
+ export declare function getVirtualElementFromMousePos(mousePos: {
19
+ clientX: number;
20
+ clientY: number;
21
+ }, { targetElement, tooltipPosition, }: {
22
+ targetElement: HTMLElement;
23
+ tooltipPosition: 'mouse' | 'mouse-x' | 'mouse-y';
24
+ }): VirtualElement;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlaskit/tooltip",
3
- "version": "20.11.0",
3
+ "version": "20.12.0",
4
4
  "description": "A tooltip describes an interactive element on mouse hover or keyboard focus.",
5
5
  "publishConfig": {
6
6
  "registry": "https://registry.npmjs.org/"
@@ -34,13 +34,13 @@
34
34
  "dependencies": {
35
35
  "@atlaskit/analytics-next": "^11.1.0",
36
36
  "@atlaskit/ds-lib": "^5.3.0",
37
- "@atlaskit/layering": "^3.4.0",
37
+ "@atlaskit/layering": "^3.6.0",
38
38
  "@atlaskit/motion": "^5.3.0",
39
39
  "@atlaskit/platform-feature-flags": "^1.1.0",
40
40
  "@atlaskit/popper": "^7.1.0",
41
41
  "@atlaskit/portal": "^5.1.0",
42
42
  "@atlaskit/theme": "^21.0.0",
43
- "@atlaskit/tokens": "^8.4.0",
43
+ "@atlaskit/tokens": "^9.1.0",
44
44
  "@babel/runtime": "^7.0.0",
45
45
  "@compiled/react": "^0.18.6",
46
46
  "bind-event-listener": "^3.0.0"
@@ -52,14 +52,15 @@
52
52
  "devDependencies": {
53
53
  "@af/accessibility-testing": "workspace:^",
54
54
  "@af/integration-testing": "workspace:^",
55
+ "@af/suppress-react-warnings": "workspace:^",
55
56
  "@af/visual-regression": "workspace:^",
56
- "@atlaskit/button": "^23.6.0",
57
- "@atlaskit/css": "^0.17.0",
57
+ "@atlaskit/button": "^23.9.0",
58
+ "@atlaskit/css": "^0.19.0",
58
59
  "@atlaskit/docs": "^11.2.0",
59
- "@atlaskit/icon": "^29.0.0",
60
- "@atlaskit/link": "^3.2.0",
61
- "@atlaskit/primitives": "^16.4.0",
62
- "@atlaskit/section-message": "^8.9.0",
60
+ "@atlaskit/icon": "^29.3.0",
61
+ "@atlaskit/link": "^3.3.0",
62
+ "@atlaskit/primitives": "^17.0.0",
63
+ "@atlaskit/section-message": "^8.11.0",
63
64
  "@atlassian/ssr-tests": "workspace:^",
64
65
  "@atlassian/testing-library": "^0.4.0",
65
66
  "@testing-library/react": "^13.4.0",
@@ -92,6 +93,9 @@
92
93
  },
93
94
  "homepage": "https://atlassian.design/components/tooltip/",
94
95
  "platform-feature-flags": {
96
+ "platform_dst_nav4_side_nav_resize_tooltip_feedback": {
97
+ "type": "boolean"
98
+ },
95
99
  "platform-component-visual-refresh": {
96
100
  "type": "boolean",
97
101
  "referenceOnly": true