@atlaskit/top-layer 4.4.5 → 5.0.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.
Files changed (130) hide show
  1. package/CHANGELOG.md +41 -0
  2. package/README.md +13 -4
  3. package/dist/cjs/dialog/dialog-content.js +2 -0
  4. package/dist/cjs/entry-points/use-popover-id.js +5 -10
  5. package/dist/cjs/internal/anchor-positioning/apply-anchor-positioning.js +86 -0
  6. package/dist/cjs/internal/anchor-positioning/cross-axis-shift-margins.js +34 -0
  7. package/dist/cjs/internal/anchor-positioning/edge-margin.js +21 -0
  8. package/dist/cjs/internal/anchor-positioning/fit-margins.js +77 -0
  9. package/dist/cjs/internal/anchor-positioning/get-existing-anchor-name.js +18 -0
  10. package/dist/cjs/internal/{placement-to-position-area.js → anchor-positioning/placement-to-position-area.js} +11 -11
  11. package/dist/cjs/internal/anchor-positioning/placement-to-try-fallbacks.js +95 -0
  12. package/dist/cjs/internal/anchored-popover-size.js +345 -0
  13. package/dist/cjs/internal/get-aria-for-trigger.js +7 -13
  14. package/dist/cjs/internal/{anchor-positioning-fallback.js → javascript-fallback/anchor-positioning-fallback.js} +12 -33
  15. package/dist/cjs/internal/javascript-fallback/apply-javascript-fallback-positioning.js +297 -0
  16. package/dist/cjs/internal/javascript-fallback/resolve-css-length-to-pixels.js +90 -0
  17. package/dist/cjs/internal/javascript-fallback/warn-fallback-failure.js +19 -0
  18. package/dist/cjs/internal/resolve-placement.js +14 -6
  19. package/dist/cjs/internal/supports-anchor-positioning.js +17 -0
  20. package/dist/cjs/internal/supports-anchor-size.js +17 -0
  21. package/dist/cjs/internal/supports-css-declaration.js +25 -0
  22. package/dist/cjs/internal/surface-reset.js +5 -0
  23. package/dist/cjs/internal/use-anchored-popover-at-point.js +124 -0
  24. package/dist/cjs/internal/use-anchored-popover.js +277 -0
  25. package/dist/cjs/popover/popover.compiled.css +4 -0
  26. package/dist/cjs/popover/popover.js +11 -4
  27. package/dist/cjs/testing/polyfill.js +6 -7
  28. package/dist/es2019/dialog/dialog-content.js +2 -0
  29. package/dist/es2019/entry-points/use-popover-id.js +6 -10
  30. package/dist/es2019/internal/anchor-positioning/apply-anchor-positioning.js +83 -0
  31. package/dist/es2019/internal/anchor-positioning/cross-axis-shift-margins.js +29 -0
  32. package/dist/es2019/internal/anchor-positioning/edge-margin.js +18 -0
  33. package/dist/es2019/internal/anchor-positioning/fit-margins.js +69 -0
  34. package/dist/es2019/internal/anchor-positioning/get-existing-anchor-name.js +12 -0
  35. package/dist/es2019/internal/{placement-to-position-area.js → anchor-positioning/placement-to-position-area.js} +9 -9
  36. package/dist/es2019/internal/anchor-positioning/placement-to-try-fallbacks.js +94 -0
  37. package/dist/es2019/internal/anchored-popover-size.js +343 -0
  38. package/dist/es2019/internal/get-aria-for-trigger.js +7 -13
  39. package/dist/es2019/internal/{anchor-positioning-fallback.js → javascript-fallback/anchor-positioning-fallback.js} +12 -33
  40. package/dist/es2019/internal/javascript-fallback/apply-javascript-fallback-positioning.js +291 -0
  41. package/dist/es2019/internal/javascript-fallback/resolve-css-length-to-pixels.js +87 -0
  42. package/dist/es2019/internal/javascript-fallback/warn-fallback-failure.js +14 -0
  43. package/dist/es2019/internal/resolve-placement.js +14 -6
  44. package/dist/es2019/internal/supports-anchor-positioning.js +12 -0
  45. package/dist/es2019/internal/supports-anchor-size.js +12 -0
  46. package/dist/es2019/internal/supports-css-declaration.js +20 -0
  47. package/dist/es2019/internal/surface-reset.js +1 -0
  48. package/dist/es2019/internal/use-anchored-popover-at-point.js +116 -0
  49. package/dist/es2019/internal/use-anchored-popover.js +265 -0
  50. package/dist/es2019/popover/popover.compiled.css +4 -0
  51. package/dist/es2019/popover/popover.js +11 -4
  52. package/dist/es2019/testing/polyfill.js +6 -7
  53. package/dist/esm/dialog/dialog-content.js +2 -0
  54. package/dist/esm/entry-points/use-popover-id.js +6 -10
  55. package/dist/esm/internal/anchor-positioning/apply-anchor-positioning.js +80 -0
  56. package/dist/esm/internal/anchor-positioning/cross-axis-shift-margins.js +28 -0
  57. package/dist/esm/internal/anchor-positioning/edge-margin.js +15 -0
  58. package/dist/esm/internal/anchor-positioning/fit-margins.js +71 -0
  59. package/dist/esm/internal/anchor-positioning/get-existing-anchor-name.js +12 -0
  60. package/dist/esm/internal/{placement-to-position-area.js → anchor-positioning/placement-to-position-area.js} +11 -12
  61. package/dist/esm/internal/anchor-positioning/placement-to-try-fallbacks.js +89 -0
  62. package/dist/esm/internal/anchored-popover-size.js +338 -0
  63. package/dist/esm/internal/get-aria-for-trigger.js +7 -13
  64. package/dist/esm/internal/{anchor-positioning-fallback.js → javascript-fallback/anchor-positioning-fallback.js} +12 -33
  65. package/dist/esm/internal/javascript-fallback/apply-javascript-fallback-positioning.js +290 -0
  66. package/dist/esm/internal/javascript-fallback/resolve-css-length-to-pixels.js +85 -0
  67. package/dist/esm/internal/javascript-fallback/warn-fallback-failure.js +13 -0
  68. package/dist/esm/internal/resolve-placement.js +14 -6
  69. package/dist/esm/internal/supports-anchor-positioning.js +12 -0
  70. package/dist/esm/internal/supports-anchor-size.js +12 -0
  71. package/dist/esm/internal/supports-css-declaration.js +19 -0
  72. package/dist/esm/internal/surface-reset.js +1 -0
  73. package/dist/esm/internal/use-anchored-popover-at-point.js +118 -0
  74. package/dist/esm/internal/use-anchored-popover.js +271 -0
  75. package/dist/esm/popover/popover.compiled.css +4 -0
  76. package/dist/esm/popover/popover.js +11 -4
  77. package/dist/esm/testing/polyfill.js +6 -7
  78. package/dist/types/entry-points/placement-map.d.ts +2 -2
  79. package/dist/types/entry-points/use-popover-id.d.ts +3 -7
  80. package/dist/types/internal/anchor-positioning/apply-anchor-positioning.d.ts +26 -0
  81. package/dist/types/internal/anchor-positioning/cross-axis-shift-margins.d.ts +19 -0
  82. package/dist/types/internal/anchor-positioning/edge-margin.d.ts +10 -0
  83. package/dist/types/internal/anchor-positioning/fit-margins.d.ts +30 -0
  84. package/dist/types/internal/anchor-positioning/get-existing-anchor-name.d.ts +8 -0
  85. package/dist/types/internal/{placement-to-position-area.d.ts → anchor-positioning/placement-to-position-area.d.ts} +10 -6
  86. package/dist/types/internal/anchor-positioning/placement-to-try-fallbacks.d.ts +30 -0
  87. package/dist/types/internal/anchored-popover-size.d.ts +126 -0
  88. package/dist/types/internal/get-aria-for-trigger.d.ts +13 -25
  89. package/dist/types/internal/javascript-fallback/anchor-positioning-fallback.d.ts +36 -0
  90. package/dist/types/internal/javascript-fallback/apply-javascript-fallback-positioning.d.ts +15 -0
  91. package/dist/types/internal/javascript-fallback/resolve-css-length-to-pixels.d.ts +20 -0
  92. package/dist/types/internal/javascript-fallback/warn-fallback-failure.d.ts +7 -0
  93. package/dist/types/internal/resolve-placement.d.ts +18 -2
  94. package/dist/types/internal/supports-anchor-positioning.d.ts +5 -0
  95. package/dist/types/internal/supports-anchor-size.d.ts +5 -0
  96. package/dist/types/internal/supports-css-declaration.d.ts +11 -0
  97. package/dist/types/internal/surface-reset.d.ts +25 -0
  98. package/dist/types/internal/use-anchored-popover-at-point.d.ts +48 -0
  99. package/dist/types/internal/use-anchored-popover.d.ts +143 -0
  100. package/dist/types/popover/index.d.ts +2 -1
  101. package/dist/types/popover/popover.d.ts +1 -1
  102. package/dist/types/popover/types.d.ts +15 -17
  103. package/dist/types/testing/polyfill.d.ts +3 -3
  104. package/package.json +2 -2
  105. package/use-anchored-popover/package.json +10 -0
  106. package/use-anchored-popover-at-point/package.json +10 -0
  107. package/dist/cjs/internal/placement-to-try-fallbacks.js +0 -108
  108. package/dist/cjs/internal/resolve-css-length-to-pixels.js +0 -104
  109. package/dist/cjs/internal/use-anchor-position-at-point.js +0 -129
  110. package/dist/cjs/internal/use-anchor-position.js +0 -501
  111. package/dist/cjs/internal/use-width-from-anchor.js +0 -124
  112. package/dist/es2019/internal/placement-to-try-fallbacks.js +0 -108
  113. package/dist/es2019/internal/resolve-css-length-to-pixels.js +0 -101
  114. package/dist/es2019/internal/use-anchor-position-at-point.js +0 -124
  115. package/dist/es2019/internal/use-anchor-position.js +0 -480
  116. package/dist/es2019/internal/use-width-from-anchor.js +0 -120
  117. package/dist/esm/internal/placement-to-try-fallbacks.js +0 -103
  118. package/dist/esm/internal/resolve-css-length-to-pixels.js +0 -98
  119. package/dist/esm/internal/use-anchor-position-at-point.js +0 -124
  120. package/dist/esm/internal/use-anchor-position.js +0 -494
  121. package/dist/esm/internal/use-width-from-anchor.js +0 -118
  122. package/dist/types/internal/anchor-positioning-fallback.d.ts +0 -51
  123. package/dist/types/internal/placement-to-try-fallbacks.d.ts +0 -13
  124. package/dist/types/internal/resolve-css-length-to-pixels.d.ts +0 -20
  125. package/dist/types/internal/use-anchor-position-at-point.d.ts +0 -67
  126. package/dist/types/internal/use-anchor-position.d.ts +0 -87
  127. package/dist/types/internal/use-width-from-anchor.d.ts +0 -19
  128. package/use-anchor-position/package.json +0 -10
  129. package/use-anchor-position-at-point/package.json +0 -10
  130. package/use-width-from-anchor/package.json +0 -10
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlaskit/top-layer",
3
- "version": "4.4.5",
3
+ "version": "5.0.0",
4
4
  "description": "Low-level layering primitives based on popover and dialog",
5
5
  "homepage": "https://atlassian.design/components/top-layer",
6
6
  "repository": "https://bitbucket.org/atlassian/atlassian-frontend-mirror",
@@ -40,7 +40,7 @@
40
40
  "@atlaskit/ds-lib": "^8.0.0",
41
41
  "@atlaskit/layering": "^5.2.0",
42
42
  "@atlaskit/react-compiler-gating": "^0.2.0",
43
- "@atlaskit/tokens": "^16.11.0",
43
+ "@atlaskit/tokens": "^16.12.0",
44
44
  "@babel/runtime": "^7.0.0",
45
45
  "@compiled/react": "^1.0.2",
46
46
  "bind-event-listener": "^3.0.0",
@@ -0,0 +1,10 @@
1
+ {
2
+ "name": "@atlaskit/top-layer/use-anchored-popover",
3
+ "main": "../dist/cjs/internal/use-anchored-popover.js",
4
+ "module": "../dist/esm/internal/use-anchored-popover.js",
5
+ "module:es2019": "../dist/es2019/internal/use-anchored-popover.js",
6
+ "sideEffects": [
7
+ "*.compiled.css"
8
+ ],
9
+ "types": "../dist/types/internal/use-anchored-popover.d.ts"
10
+ }
@@ -0,0 +1,10 @@
1
+ {
2
+ "name": "@atlaskit/top-layer/use-anchored-popover-at-point",
3
+ "main": "../dist/cjs/internal/use-anchored-popover-at-point.js",
4
+ "module": "../dist/esm/internal/use-anchored-popover-at-point.js",
5
+ "module:es2019": "../dist/es2019/internal/use-anchored-popover-at-point.js",
6
+ "sideEffects": [
7
+ "*.compiled.css"
8
+ ],
9
+ "types": "../dist/types/internal/use-anchored-popover-at-point.d.ts"
10
+ }
@@ -1,108 +0,0 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.placementToTryFallbacks = placementToTryFallbacks;
7
- var _resolvePlacement = require("./resolve-placement");
8
- /**
9
- * A `position-area` primary edge — the placement axis joined to its edge, e.g.
10
- * `block-end` or `inline-start`. These are the four edges a popover can sit on.
11
- */
12
-
13
- function slideOnEdge(_ref) {
14
- var align = _ref.align,
15
- edgeKey = _ref.edgeKey,
16
- crossAxis = _ref.crossAxis;
17
- if (align === 'center') {
18
- return ["".concat(edgeKey, " span-").concat(crossAxis, "-end"), "".concat(edgeKey, " span-").concat(crossAxis, "-start")];
19
- }
20
- // For `align: 'start'` the popover expands toward `end`, so the "near"
21
- // span is `end` and the "far" span is `start`; `align: 'end'` mirrors
22
- // this. The bare `edgeKey` (re-centered) sits between them.
23
- var near = align === 'start' ? 'end' : 'start';
24
- var far = align === 'start' ? 'start' : 'end';
25
- return ["".concat(edgeKey, " span-").concat(crossAxis, "-").concat(near), edgeKey, "".concat(edgeKey, " span-").concat(crossAxis, "-").concat(far)];
26
- }
27
- function flipDiagonally(_ref2) {
28
- var axis = _ref2.axis;
29
- var flipOnMainAxis = axis === 'block' ? 'flip-block' : 'flip-inline';
30
- var flipToCrossAxis = axis === 'block' ? 'flip-inline' : 'flip-block';
31
- return "".concat(flipOnMainAxis, " ").concat(flipToCrossAxis);
32
- }
33
-
34
- /**
35
- * Returns the `position-try-fallbacks` value for a placement.
36
- *
37
- * @example
38
- * // Centered on the block-end edge (the default placement):
39
- * placementToTryFallbacks({ placement: { axis: 'block', edge: 'end', align: 'center' } });
40
- * // => 'block-end span-inline-end, block-end span-inline-start, flip-block,
41
- * // block-start span-inline-end, block-start span-inline-start'
42
- */
43
- function placementToTryFallbacks(_ref3) {
44
- var placement = _ref3.placement;
45
- /**
46
- * **Build the fallback list**
47
- *
48
- * Each entry is a complete alternative position.
49
- * The browser tries them _in order_ and uses the _first_ one that fits.
50
- */
51
-
52
- var resolved = (0, _resolvePlacement.resolvePlacement)({
53
- placement: placement
54
- });
55
- var axis = resolved.axis,
56
- edge = resolved.edge,
57
- align = resolved.align;
58
- var crossAxis = axis === 'block' ? 'inline' : 'block';
59
- var flippedEdge = edge === 'start' ? 'end' : 'start';
60
- var sameEdgeArea = "".concat(axis, "-").concat(edge);
61
- var oppositeEdgeArea = "".concat(axis, "-").concat(flippedEdge);
62
- var flipOnMainAxis = axis === 'block' ? 'flip-block' : 'flip-inline';
63
-
64
- /**
65
- * **Fallback algorithm**
66
- *
67
- * We have two things we can do to keep something visible:
68
- *
69
- * 1. _Slide_ along edges
70
- * 2. _Flip_ to another edge
71
- *
72
- * _Centered popover_
73
- *
74
- * Desired: Sits in middle of main edge
75
- *
76
- * Fallbacks:
77
- * 1: _Slide_ along main edge on the cross axis
78
- * 2: _Flip_ on main axis to opposite edge (centered)
79
- * 3: _Slide_ along opposite edge on the cross axis
80
- *
81
- * _Start or end aligned popover_
82
- *
83
- * Desired: Sits at start / end of main edge
84
- *
85
- * Fallbacks:
86
- * 1: _Slide_ along main edge on the cross axis
87
- * 2: _Flip_ on main axis to opposite edge
88
- * 3: _Flip_ on the diagonal (flip main axis + flip cross axis) into the
89
- * opposite corner. For start / end alignment, this is the clean escape
90
- * when the popover would otherwise land offscreen on both axes (ie in a
91
- * corner). Rule 4 gets the job done, but a slide drops the gap
92
- * as named position-area values don't carry margins).
93
- * The diagonal flip keeps the gap and the alignment.
94
- * 4: _Slide_ along opposite edge on the cross axis
95
- */
96
-
97
- return [slideOnEdge({
98
- align: align,
99
- edgeKey: sameEdgeArea,
100
- crossAxis: crossAxis
101
- }), flipOnMainAxis, align !== 'center' ? flipDiagonally({
102
- axis: axis
103
- }) : null, slideOnEdge({
104
- align: align,
105
- edgeKey: oppositeEdgeArea,
106
- crossAxis: crossAxis
107
- })].filter(Boolean).flat().join(', ');
108
- }
@@ -1,104 +0,0 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.resolveCssLengthToPixels = resolveCssLengthToPixels;
7
- var elementCaches = new WeakMap();
8
- function canCacheResolvedLength(value) {
9
- // Custom-property values can be retargeted by inline overrides on the
10
- // consumer's wrapper, so we cannot prove a cached pixel value is still valid.
11
- return !value.includes('var(');
12
- }
13
- function getCachedResolvedLength(_ref) {
14
- var _cacheForElement$get;
15
- var element = _ref.element,
16
- value = _ref.value;
17
- if (!canCacheResolvedLength(value)) {
18
- return null;
19
- }
20
- var cacheForElement = elementCaches.get(element);
21
- return (_cacheForElement$get = cacheForElement === null || cacheForElement === void 0 ? void 0 : cacheForElement.get(value)) !== null && _cacheForElement$get !== void 0 ? _cacheForElement$get : null;
22
- }
23
- function cacheResolvedLength(_ref2) {
24
- var _elementCaches$get;
25
- var element = _ref2.element,
26
- value = _ref2.value,
27
- result = _ref2.result;
28
- if (!canCacheResolvedLength(value)) {
29
- return;
30
- }
31
- var cacheForElement = (_elementCaches$get = elementCaches.get(element)) !== null && _elementCaches$get !== void 0 ? _elementCaches$get : new Map();
32
- cacheForElement.set(value, result);
33
- elementCaches.set(element, cacheForElement);
34
- }
35
-
36
- /**
37
- * Resolves a CSS length value to a pixel number using a hidden DOM probe.
38
- *
39
- * Used by the JS positioning fallback: consumer offsets can be numbers,
40
- * `${n}px` strings, tokenised `var(--ds-space-100, 8px)` strings, `calc()`
41
- * expressions, viewport units, etc. Parsing arbitrary CSS in JS is fragile
42
- * (and impossible for `calc(var(...))` without a layout context), so we let
43
- * the browser do the math.
44
- *
45
- * The probe is appended to `container` so it inherits the same containing
46
- * block, font size, and custom-property scope as the popover.
47
- *
48
- * Cost: one synchronous reflow on first cacheable resolution per
49
- * (container, value) pair, then a `WeakMap` lookup. Resolutions involving
50
- * `var(` are intentionally not cached.
51
- */
52
- function resolveCssLengthToPixels(_ref3) {
53
- var value = _ref3.value,
54
- container = _ref3.container;
55
- if (typeof value === 'number') {
56
- return value;
57
- }
58
-
59
- // Fast path: unitless zero is universally zero pixels - accept `'0'` and
60
- // `'-0'` without a probe. (Consumers occasionally pass `'0'` instead of
61
- // the number `0`.)
62
- if (value === '0' || value === '-0') {
63
- return 0;
64
- }
65
-
66
- // Fast path: bare `${n}px` strings come from the consumer normalisation
67
- // in `resolvePlacement`. Avoid a reflow when we can.
68
- var pxMatch = value.match(/^(-?\d+(?:\.\d+)?)px$/);
69
- if (pxMatch) {
70
- return Number(pxMatch[1]);
71
- }
72
- var cached = getCachedResolvedLength({
73
- element: container,
74
- value: value
75
- });
76
- if (cached !== null) {
77
- return cached;
78
- }
79
- var probe = container.ownerDocument.createElement('div');
80
- probe.style.position = 'absolute';
81
- probe.style.visibility = 'hidden';
82
- probe.style.pointerEvents = 'none';
83
- probe.style.height = '0';
84
- probe.style.padding = '0';
85
- probe.style.border = '0';
86
- // `width` clamps negatives to 0; use `margin-left` instead so signs are
87
- // preserved. `getComputedStyle` returns the resolved pixel value for
88
- // margin-* properties even when the source was a token / calc / var.
89
- probe.style.marginLeft = value;
90
- // Hide the probe from assistive tech and event targeting; defensive
91
- // against `getElementsByTagName('div')` walks in consumer code.
92
- probe.setAttribute('aria-hidden', 'true');
93
- probe.setAttribute('inert', '');
94
- container.appendChild(probe);
95
- var resolved = parseFloat(getComputedStyle(probe).marginLeft);
96
- container.removeChild(probe);
97
- var result = Number.isFinite(resolved) ? resolved : 0;
98
- cacheResolvedLength({
99
- element: container,
100
- value: value,
101
- result: result
102
- });
103
- return result;
104
- }
@@ -1,129 +0,0 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.useAnchorPositionAtPoint = useAnchorPositionAtPoint;
7
- var _react = require("react");
8
- var _useAnchorPosition = require("./use-anchor-position");
9
- /**
10
- * A point in viewport coordinates (CSS pixels) at which the synthetic
11
- * anchor should be placed.
12
- *
13
- * Axis-named (`x`/`y`) rather than edge-named (`left`/`top`) so the
14
- * shape is unambiguous in RTL writing modes - there is no ambiguity
15
- * about whether a coordinate is logical (`inline-start`/`block-start`)
16
- * or physical (`left`/`top`). Viewport coordinates are always
17
- * physical, so we name them with the physical axis labels.
18
- */
19
-
20
- /**
21
- * Styles the synthetic anchor as an invisible, zero-size point.
22
- * Dynamic `inset-*` overrides are written by the positioning effect.
23
- *
24
- * Uses `Object.assign` rather than Compiled CSS (element is outside the React tree)
25
- * or the internal `setStyle` helper (we own this element entirely - it is created
26
- * and removed by this hook - so the snapshot/restore semantics `setStyle`
27
- * provides for caller-owned elements would be dead work here).
28
- */
29
- function applyStaticAnchorStyles(element) {
30
- Object.assign(element.style, {
31
- position: 'fixed',
32
- // `top`/`left` rather than `inset-block-start`/`inset-inline-start`
33
- // for consistency with the dynamic positioning effect below, which
34
- // uses physical properties (see comment there for the rationale).
35
- top: '0',
36
- left: '0',
37
- // Zero size - placement decides which side the popover sits on.
38
- width: '0',
39
- height: '0',
40
- // Prevent the overlay from intercepting pointer events.
41
- pointerEvents: 'none'
42
- });
43
- }
44
-
45
- // `useAnchorPosition` requires a real DOM element. When the caller only
46
- // has a viewport coordinate (e.g. cursor at hover time), this hook
47
- // manages a hidden `<div>` at that point and delegates the rest.
48
- //
49
- // The `<div>` is appended directly to `document.body` to escape any
50
- // transformed ancestor, which would otherwise break `position: fixed`
51
- // viewport-relative resolution.
52
-
53
- /**
54
- * Positions a popover at a consumer-supplied viewport coordinate using a
55
- * hidden synthetic anchor.
56
- *
57
- * @example
58
- * ```tsx
59
- * function PointPositionedPopover({ popoverRef, placement, mousePos }) {
60
- * useAnchorPositionAtPoint({
61
- * popoverRef,
62
- * placement,
63
- * isEnabled: Boolean(mousePos),
64
- * getPoint: () => {
65
- * if (!mousePos) return null;
66
- * return { x: mousePos.clientX, y: mousePos.clientY };
67
- * },
68
- * });
69
- * return <Popover ref={popoverRef}>...</Popover>;
70
- * }
71
- * ```
72
- */
73
- function useAnchorPositionAtPoint(_ref) {
74
- var popoverRef = _ref.popoverRef,
75
- placement = _ref.placement,
76
- getPoint = _ref.getPoint,
77
- _ref$isEnabled = _ref.isEnabled,
78
- isEnabled = _ref$isEnabled === void 0 ? true : _ref$isEnabled,
79
- isOpen = _ref.isOpen;
80
- var syntheticAnchorRef = (0, _react.useRef)(null);
81
-
82
- // `getPoint` is kept in a ref so the layout effect can call the
83
- // latest version without listing it as a dep - that would re-fire
84
- // on every render and re-latch the point.
85
- var getPointRef = (0, _react.useRef)(getPoint);
86
- getPointRef.current = getPoint;
87
-
88
- // Lazy element creation: the `<div>` is only created when both
89
- // `isEnabled` is true AND `getPoint()` returns a non-null point.
90
- // `useLayoutEffect` ensures the element exists before the inner
91
- // `useAnchorPosition` (also a layout effect) reads the ref.
92
- (0, _react.useLayoutEffect)(function () {
93
- if (!isEnabled) {
94
- return;
95
- }
96
- var point = getPointRef.current();
97
- if (!point) {
98
- return;
99
- }
100
- var anchor = document.createElement('div');
101
- anchor.setAttribute('aria-hidden', 'true');
102
- applyStaticAnchorStyles(anchor);
103
- // `point.x`/`y` are physical viewport coordinates (from
104
- // `MouseEvent.clientX/Y`), so map directly onto physical
105
- // `left`/`top`. This is RTL-safe: `position: fixed` + physical
106
- // insets is direction-independent. Using logical
107
- // `inset-inline-start` would need `viewportWidth - point.x` in
108
- // RTL to land at the same physical pixel.
109
- anchor.style.top = "".concat(point.y, "px");
110
- anchor.style.left = "".concat(point.x, "px");
111
- document.body.appendChild(anchor);
112
- syntheticAnchorRef.current = anchor;
113
- return function cleanup() {
114
- anchor.remove();
115
- syntheticAnchorRef.current = null;
116
- };
117
- }, [isEnabled]);
118
-
119
- // Mirror `isEnabled` so both hooks stay in sync - when disabled,
120
- // neither this hook nor the inner one touches the popover, leaving
121
- // any other positioning the consumer has set up free to take effect.
122
- (0, _useAnchorPosition.useAnchorPosition)({
123
- anchorRef: syntheticAnchorRef,
124
- popoverRef: popoverRef,
125
- placement: placement,
126
- isEnabled: isEnabled,
127
- isOpen: isOpen
128
- });
129
- }