@teamturing/react-kit 2.45.4 → 2.46.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.
@@ -0,0 +1,233 @@
1
+ import { isShadowRoot, isHTMLElement } from '../../utils/dist/floating-ui.utils.dom.js';
2
+ import * as React from 'react';
3
+ import { useLayoutEffect } from 'react';
4
+ import { tabbable } from '../../../tabbable/dist/index.esm.js';
5
+
6
+ // Avoid Chrome DevTools blue warning.
7
+ function getPlatform() {
8
+ const uaData = navigator.userAgentData;
9
+ if (uaData != null && uaData.platform) {
10
+ return uaData.platform;
11
+ }
12
+ return navigator.platform;
13
+ }
14
+ function getUserAgent() {
15
+ const uaData = navigator.userAgentData;
16
+ if (uaData && Array.isArray(uaData.brands)) {
17
+ return uaData.brands.map(_ref => {
18
+ let {
19
+ brand,
20
+ version
21
+ } = _ref;
22
+ return brand + "/" + version;
23
+ }).join(' ');
24
+ }
25
+ return navigator.userAgent;
26
+ }
27
+ function isSafari() {
28
+ // Chrome DevTools does not complain about navigator.vendor
29
+ return /apple/i.test(navigator.vendor);
30
+ }
31
+ function isMac() {
32
+ return getPlatform().toLowerCase().startsWith('mac') && !navigator.maxTouchPoints;
33
+ }
34
+ function isJSDOM() {
35
+ return getUserAgent().includes('jsdom/');
36
+ }
37
+
38
+ const FOCUSABLE_ATTRIBUTE = 'data-floating-ui-focusable';
39
+ const TYPEABLE_SELECTOR = "input:not([type='hidden']):not([disabled])," + "[contenteditable]:not([contenteditable='false']),textarea:not([disabled])";
40
+
41
+ function activeElement(doc) {
42
+ let activeElement = doc.activeElement;
43
+ while (((_activeElement = activeElement) == null || (_activeElement = _activeElement.shadowRoot) == null ? void 0 : _activeElement.activeElement) != null) {
44
+ var _activeElement;
45
+ activeElement = activeElement.shadowRoot.activeElement;
46
+ }
47
+ return activeElement;
48
+ }
49
+ function contains(parent, child) {
50
+ if (!parent || !child) {
51
+ return false;
52
+ }
53
+ const rootNode = child.getRootNode == null ? void 0 : child.getRootNode();
54
+
55
+ // First, attempt with faster native method
56
+ if (parent.contains(child)) {
57
+ return true;
58
+ }
59
+
60
+ // then fallback to custom implementation with Shadow DOM support
61
+ if (rootNode && isShadowRoot(rootNode)) {
62
+ let next = child;
63
+ while (next) {
64
+ if (parent === next) {
65
+ return true;
66
+ }
67
+ // @ts-ignore
68
+ next = next.parentNode || next.host;
69
+ }
70
+ }
71
+
72
+ // Give up, the result is false
73
+ return false;
74
+ }
75
+ function getTarget(event) {
76
+ if ('composedPath' in event) {
77
+ return event.composedPath()[0];
78
+ }
79
+
80
+ // TS thinks `event` is of type never as it assumes all browsers support
81
+ // `composedPath()`, but browsers without shadow DOM don't.
82
+ return event.target;
83
+ }
84
+ function isEventTargetWithin(event, node) {
85
+ if (node == null) {
86
+ return false;
87
+ }
88
+ if ('composedPath' in event) {
89
+ return event.composedPath().includes(node);
90
+ }
91
+
92
+ // TS thinks `event` is of type never as it assumes all browsers support composedPath, but browsers without shadow dom don't
93
+ const e = event;
94
+ return e.target != null && node.contains(e.target);
95
+ }
96
+ function isRootElement(element) {
97
+ return element.matches('html,body');
98
+ }
99
+ function getDocument(node) {
100
+ return (node == null ? void 0 : node.ownerDocument) || document;
101
+ }
102
+ function isTypeableElement(element) {
103
+ return isHTMLElement(element) && element.matches(TYPEABLE_SELECTOR);
104
+ }
105
+ function matchesFocusVisible(element) {
106
+ // We don't want to block focus from working with `visibleOnly`
107
+ // (JSDOM doesn't match `:focus-visible` when the element has `:focus`)
108
+ if (!element || isJSDOM()) return true;
109
+ try {
110
+ return element.matches(':focus-visible');
111
+ } catch (_e) {
112
+ return true;
113
+ }
114
+ }
115
+ function getFloatingFocusElement(floatingElement) {
116
+ if (!floatingElement) {
117
+ return null;
118
+ }
119
+ // Try to find the element that has `{...getFloatingProps()}` spread on it.
120
+ // This indicates the floating element is acting as a positioning wrapper, and
121
+ // so focus should be managed on the child element with the event handlers and
122
+ // aria props.
123
+ return floatingElement.hasAttribute(FOCUSABLE_ATTRIBUTE) ? floatingElement : floatingElement.querySelector("[" + FOCUSABLE_ATTRIBUTE + "]") || floatingElement;
124
+ }
125
+
126
+ function getNodeChildren(nodes, id, onlyOpenChildren) {
127
+ if (onlyOpenChildren === void 0) {
128
+ onlyOpenChildren = true;
129
+ }
130
+ const directChildren = nodes.filter(node => {
131
+ var _node$context;
132
+ return node.parentId === id && (!onlyOpenChildren || ((_node$context = node.context) == null ? void 0 : _node$context.open));
133
+ });
134
+ return directChildren.flatMap(child => [child, ...getNodeChildren(nodes, child.id, onlyOpenChildren)]);
135
+ }
136
+ function isReactEvent(event) {
137
+ return 'nativeEvent' in event;
138
+ }
139
+ function isMouseLikePointerType(pointerType, strict) {
140
+ // On some Linux machines with Chromium, mouse inputs return a `pointerType`
141
+ // of "pen": https://github.com/floating-ui/floating-ui/issues/2015
142
+ const values = ['mouse', 'pen'];
143
+ if (!strict) {
144
+ values.push('', undefined);
145
+ }
146
+ return values.includes(pointerType);
147
+ }
148
+
149
+ var isClient = typeof document !== 'undefined';
150
+
151
+ var noop = function noop() {};
152
+ var index = isClient ? useLayoutEffect : noop;
153
+
154
+ // https://github.com/mui/material-ui/issues/41190#issuecomment-2040873379
155
+ const SafeReact = {
156
+ ...React
157
+ };
158
+
159
+ function useLatestRef(value) {
160
+ const ref = React.useRef(value);
161
+ index(() => {
162
+ ref.current = value;
163
+ });
164
+ return ref;
165
+ }
166
+ const useInsertionEffect = SafeReact.useInsertionEffect;
167
+ const useSafeInsertionEffect = useInsertionEffect || (fn => fn());
168
+ function useEffectEvent(callback) {
169
+ const ref = React.useRef(() => {
170
+ if (process.env.NODE_ENV !== "production") {
171
+ throw new Error('Cannot call an event handler while rendering.');
172
+ }
173
+ });
174
+ useSafeInsertionEffect(() => {
175
+ ref.current = callback;
176
+ });
177
+ return React.useCallback(function () {
178
+ for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
179
+ args[_key] = arguments[_key];
180
+ }
181
+ return ref.current == null ? void 0 : ref.current(...args);
182
+ }, []);
183
+ }
184
+
185
+ const getTabbableOptions = () => ({
186
+ getShadowRoot: true,
187
+ displayCheck:
188
+ // JSDOM does not support the `tabbable` library. To solve this we can
189
+ // check if `ResizeObserver` is a real function (not polyfilled), which
190
+ // determines if the current environment is JSDOM-like.
191
+ typeof ResizeObserver === 'function' && ResizeObserver.toString().includes('[native code]') ? 'full' : 'none'
192
+ });
193
+ function getTabbableIn(container, dir) {
194
+ const list = tabbable(container, getTabbableOptions());
195
+ const len = list.length;
196
+ if (len === 0) return;
197
+ const active = activeElement(getDocument(container));
198
+ const index = list.indexOf(active);
199
+ const nextIndex = index === -1 ? dir === 1 ? 0 : len - 1 : index + dir;
200
+ return list[nextIndex];
201
+ }
202
+ function getNextTabbable(referenceElement) {
203
+ return getTabbableIn(getDocument(referenceElement).body, 1) || referenceElement;
204
+ }
205
+ function getPreviousTabbable(referenceElement) {
206
+ return getTabbableIn(getDocument(referenceElement).body, -1) || referenceElement;
207
+ }
208
+ function isOutsideEvent(event, container) {
209
+ const containerElement = container || event.currentTarget;
210
+ const relatedTarget = event.relatedTarget;
211
+ return !relatedTarget || !contains(containerElement, relatedTarget);
212
+ }
213
+ function disableFocusInside(container) {
214
+ const tabbableElements = tabbable(container, getTabbableOptions());
215
+ tabbableElements.forEach(element => {
216
+ element.dataset.tabindex = element.getAttribute('tabindex') || '';
217
+ element.setAttribute('tabindex', '-1');
218
+ });
219
+ }
220
+ function enableFocusInside(container) {
221
+ const elements = container.querySelectorAll('[data-tabindex]');
222
+ elements.forEach(element => {
223
+ const tabindex = element.dataset.tabindex;
224
+ delete element.dataset.tabindex;
225
+ if (tabindex) {
226
+ element.setAttribute('tabindex', tabindex);
227
+ } else {
228
+ element.removeAttribute('tabindex');
229
+ }
230
+ });
231
+ }
232
+
233
+ export { activeElement, contains, disableFocusInside, enableFocusInside, getDocument, getFloatingFocusElement, getNextTabbable, getNodeChildren, getPlatform, getPreviousTabbable, getTabbableOptions, getTarget, getUserAgent, isEventTargetWithin, isJSDOM, isMac, isMouseLikePointerType, isOutsideEvent, isReactEvent, isRootElement, isSafari, isTypeableElement, matchesFocusVisible, useEffectEvent, useLatestRef, index as useModernLayoutEffect };
@@ -1,10 +1,13 @@
1
- import { computePosition } from '../../dom/dist/floating-ui.dom.js';
1
+ import { offset as offset$1, shift as shift$1, flip as flip$1, computePosition, arrow as arrow$2 } from '../../dom/dist/floating-ui.dom.js';
2
2
  export { autoUpdate, platform } from '../../dom/dist/floating-ui.dom.js';
3
3
  import * as React from 'react';
4
- import { useLayoutEffect, useEffect } from 'react';
4
+ import { useLayoutEffect } from 'react';
5
5
  import { r as reactDomExports } from '../../../react-dom/index.js';
6
6
 
7
- var index = typeof document !== 'undefined' ? useLayoutEffect : useEffect;
7
+ var isClient = typeof document !== 'undefined';
8
+
9
+ var noop = function noop() {};
10
+ var index = isClient ? useLayoutEffect : noop;
8
11
 
9
12
  // Fork of `fast-deep-equal` that only does the comparisons we need and compares
10
13
  // functions
@@ -18,11 +21,13 @@ function deepEqual(a, b) {
18
21
  if (typeof a === 'function' && a.toString() === b.toString()) {
19
22
  return true;
20
23
  }
21
- let length, i, keys;
22
- if (a && b && typeof a == 'object') {
24
+ let length;
25
+ let i;
26
+ let keys;
27
+ if (a && b && typeof a === 'object') {
23
28
  if (Array.isArray(a)) {
24
29
  length = a.length;
25
- if (length != b.length) return false;
30
+ if (length !== b.length) return false;
26
31
  for (i = length; i-- !== 0;) {
27
32
  if (!deepEqual(a[i], b[i])) {
28
33
  return false;
@@ -77,7 +82,7 @@ function useLatestRef(value) {
77
82
 
78
83
  /**
79
84
  * Provides data to position a floating element.
80
- * @see https://floating-ui.com/docs/react
85
+ * @see https://floating-ui.com/docs/useFloating
81
86
  */
82
87
  function useFloating(options) {
83
88
  if (options === void 0) {
@@ -111,24 +116,26 @@ function useFloating(options) {
111
116
  const [_reference, _setReference] = React.useState(null);
112
117
  const [_floating, _setFloating] = React.useState(null);
113
118
  const setReference = React.useCallback(node => {
114
- if (node != referenceRef.current) {
119
+ if (node !== referenceRef.current) {
115
120
  referenceRef.current = node;
116
121
  _setReference(node);
117
122
  }
118
- }, [_setReference]);
123
+ }, []);
119
124
  const setFloating = React.useCallback(node => {
120
125
  if (node !== floatingRef.current) {
121
126
  floatingRef.current = node;
122
127
  _setFloating(node);
123
128
  }
124
- }, [_setFloating]);
129
+ }, []);
125
130
  const referenceEl = externalReference || _reference;
126
131
  const floatingEl = externalFloating || _floating;
127
132
  const referenceRef = React.useRef(null);
128
133
  const floatingRef = React.useRef(null);
129
134
  const dataRef = React.useRef(data);
135
+ const hasWhileElementsMounted = whileElementsMounted != null;
130
136
  const whileElementsMountedRef = useLatestRef(whileElementsMounted);
131
137
  const platformRef = useLatestRef(platform);
138
+ const openRef = useLatestRef(open);
132
139
  const update = React.useCallback(() => {
133
140
  if (!referenceRef.current || !floatingRef.current) {
134
141
  return;
@@ -144,7 +151,11 @@ function useFloating(options) {
144
151
  computePosition(referenceRef.current, floatingRef.current, config).then(data => {
145
152
  const fullData = {
146
153
  ...data,
147
- isPositioned: true
154
+ // The floating element's position may be recomputed while it's closed
155
+ // but still mounted (such as when transitioning out). To ensure
156
+ // `isPositioned` will be `false` initially on the next open, avoid
157
+ // setting it to `true` when `open === false` (must be specified).
158
+ isPositioned: openRef.current !== false
148
159
  };
149
160
  if (isMountedRef.current && !deepEqual(dataRef.current, fullData)) {
150
161
  dataRef.current = fullData;
@@ -153,7 +164,7 @@ function useFloating(options) {
153
164
  });
154
165
  }
155
166
  });
156
- }, [latestMiddleware, placement, strategy, platformRef]);
167
+ }, [latestMiddleware, placement, strategy, platformRef, openRef]);
157
168
  index(() => {
158
169
  if (open === false && dataRef.current.isPositioned) {
159
170
  dataRef.current.isPositioned = false;
@@ -176,11 +187,10 @@ function useFloating(options) {
176
187
  if (referenceEl && floatingEl) {
177
188
  if (whileElementsMountedRef.current) {
178
189
  return whileElementsMountedRef.current(referenceEl, floatingEl, update);
179
- } else {
180
- update();
181
190
  }
191
+ update();
182
192
  }
183
- }, [referenceEl, floatingEl, update, whileElementsMountedRef]);
193
+ }, [referenceEl, floatingEl, update, whileElementsMountedRef, hasWhileElementsMounted]);
184
194
  const refs = React.useMemo(() => ({
185
195
  reference: referenceRef,
186
196
  floating: floatingRef,
@@ -226,4 +236,86 @@ function useFloating(options) {
226
236
  }), [data, update, refs, elements, floatingStyles]);
227
237
  }
228
238
 
229
- export { computePosition, useFloating };
239
+ /**
240
+ * Provides data to position an inner element of the floating element so that it
241
+ * appears centered to the reference element.
242
+ * This wraps the core `arrow` middleware to allow React refs as the element.
243
+ * @see https://floating-ui.com/docs/arrow
244
+ */
245
+ const arrow$1 = options => {
246
+ function isRef(value) {
247
+ return {}.hasOwnProperty.call(value, 'current');
248
+ }
249
+ return {
250
+ name: 'arrow',
251
+ options,
252
+ fn(state) {
253
+ const {
254
+ element,
255
+ padding
256
+ } = typeof options === 'function' ? options(state) : options;
257
+ if (element && isRef(element)) {
258
+ if (element.current != null) {
259
+ return arrow$2({
260
+ element: element.current,
261
+ padding
262
+ }).fn(state);
263
+ }
264
+ return {};
265
+ }
266
+ if (element) {
267
+ return arrow$2({
268
+ element,
269
+ padding
270
+ }).fn(state);
271
+ }
272
+ return {};
273
+ }
274
+ };
275
+ };
276
+
277
+ /**
278
+ * Modifies the placement by translating the floating element along the
279
+ * specified axes.
280
+ * A number (shorthand for `mainAxis` or distance), or an axes configuration
281
+ * object may be passed.
282
+ * @see https://floating-ui.com/docs/offset
283
+ */
284
+ const offset = (options, deps) => ({
285
+ ...offset$1(options),
286
+ options: [options, deps]
287
+ });
288
+
289
+ /**
290
+ * Optimizes the visibility of the floating element by shifting it in order to
291
+ * keep it in view when it will overflow the clipping boundary.
292
+ * @see https://floating-ui.com/docs/shift
293
+ */
294
+ const shift = (options, deps) => ({
295
+ ...shift$1(options),
296
+ options: [options, deps]
297
+ });
298
+
299
+ /**
300
+ * Optimizes the visibility of the floating element by flipping the `placement`
301
+ * in order to keep it in view when the preferred placement(s) will overflow the
302
+ * clipping boundary. Alternative to `autoPlacement`.
303
+ * @see https://floating-ui.com/docs/flip
304
+ */
305
+ const flip = (options, deps) => ({
306
+ ...flip$1(options),
307
+ options: [options, deps]
308
+ });
309
+
310
+ /**
311
+ * Provides data to position an inner element of the floating element so that it
312
+ * appears centered to the reference element.
313
+ * This wraps the core `arrow` middleware to allow React refs as the element.
314
+ * @see https://floating-ui.com/docs/arrow
315
+ */
316
+ const arrow = (options, deps) => ({
317
+ ...arrow$1(options),
318
+ options: [options, deps]
319
+ });
320
+
321
+ export { arrow, computePosition, flip, offset, shift, useFloating };
@@ -1,3 +1,6 @@
1
+ function hasWindow() {
2
+ return typeof window !== 'undefined';
3
+ }
1
4
  function getNodeName(node) {
2
5
  if (isNode(node)) {
3
6
  return (node.nodeName || '').toLowerCase();
@@ -9,28 +12,37 @@ function getNodeName(node) {
9
12
  }
10
13
  function getWindow(node) {
11
14
  var _node$ownerDocument;
12
- return (node == null ? void 0 : (_node$ownerDocument = node.ownerDocument) == null ? void 0 : _node$ownerDocument.defaultView) || window;
15
+ return (node == null || (_node$ownerDocument = node.ownerDocument) == null ? void 0 : _node$ownerDocument.defaultView) || window;
13
16
  }
14
17
  function getDocumentElement(node) {
15
18
  var _ref;
16
19
  return (_ref = (isNode(node) ? node.ownerDocument : node.document) || window.document) == null ? void 0 : _ref.documentElement;
17
20
  }
18
21
  function isNode(value) {
22
+ if (!hasWindow()) {
23
+ return false;
24
+ }
19
25
  return value instanceof Node || value instanceof getWindow(value).Node;
20
26
  }
21
27
  function isElement(value) {
28
+ if (!hasWindow()) {
29
+ return false;
30
+ }
22
31
  return value instanceof Element || value instanceof getWindow(value).Element;
23
32
  }
24
33
  function isHTMLElement(value) {
34
+ if (!hasWindow()) {
35
+ return false;
36
+ }
25
37
  return value instanceof HTMLElement || value instanceof getWindow(value).HTMLElement;
26
38
  }
27
39
  function isShadowRoot(value) {
28
- // Browsers without `ShadowRoot` support.
29
- if (typeof ShadowRoot === 'undefined') {
40
+ if (!hasWindow() || typeof ShadowRoot === 'undefined') {
30
41
  return false;
31
42
  }
32
43
  return value instanceof ShadowRoot || value instanceof getWindow(value).ShadowRoot;
33
44
  }
45
+ const invalidOverflowDisplayValues = /*#__PURE__*/new Set(['inline', 'contents']);
34
46
  function isOverflowElement(element) {
35
47
  const {
36
48
  overflow,
@@ -38,26 +50,42 @@ function isOverflowElement(element) {
38
50
  overflowY,
39
51
  display
40
52
  } = getComputedStyle(element);
41
- return /auto|scroll|overlay|hidden|clip/.test(overflow + overflowY + overflowX) && !['inline', 'contents'].includes(display);
53
+ return /auto|scroll|overlay|hidden|clip/.test(overflow + overflowY + overflowX) && !invalidOverflowDisplayValues.has(display);
42
54
  }
55
+ const tableElements = /*#__PURE__*/new Set(['table', 'td', 'th']);
43
56
  function isTableElement(element) {
44
- return ['table', 'td', 'th'].includes(getNodeName(element));
57
+ return tableElements.has(getNodeName(element));
58
+ }
59
+ const topLayerSelectors = [':popover-open', ':modal'];
60
+ function isTopLayer(element) {
61
+ return topLayerSelectors.some(selector => {
62
+ try {
63
+ return element.matches(selector);
64
+ } catch (_e) {
65
+ return false;
66
+ }
67
+ });
45
68
  }
46
- function isContainingBlock(element) {
69
+ const transformProperties = ['transform', 'translate', 'scale', 'rotate', 'perspective'];
70
+ const willChangeValues = ['transform', 'translate', 'scale', 'rotate', 'perspective', 'filter'];
71
+ const containValues = ['paint', 'layout', 'strict', 'content'];
72
+ function isContainingBlock(elementOrCss) {
47
73
  const webkit = isWebKit();
48
- const css = getComputedStyle(element);
74
+ const css = isElement(elementOrCss) ? getComputedStyle(elementOrCss) : elementOrCss;
49
75
 
50
76
  // https://developer.mozilla.org/en-US/docs/Web/CSS/Containing_block#identifying_the_containing_block
51
- return css.transform !== 'none' || css.perspective !== 'none' || (css.containerType ? css.containerType !== 'normal' : false) || !webkit && (css.backdropFilter ? css.backdropFilter !== 'none' : false) || !webkit && (css.filter ? css.filter !== 'none' : false) || ['transform', 'perspective', 'filter'].some(value => (css.willChange || '').includes(value)) || ['paint', 'layout', 'strict', 'content'].some(value => (css.contain || '').includes(value));
77
+ // https://drafts.csswg.org/css-transforms-2/#individual-transforms
78
+ return transformProperties.some(value => css[value] ? css[value] !== 'none' : false) || (css.containerType ? css.containerType !== 'normal' : false) || !webkit && (css.backdropFilter ? css.backdropFilter !== 'none' : false) || !webkit && (css.filter ? css.filter !== 'none' : false) || willChangeValues.some(value => (css.willChange || '').includes(value)) || containValues.some(value => (css.contain || '').includes(value));
52
79
  }
53
80
  function getContainingBlock(element) {
54
81
  let currentNode = getParentNode(element);
55
82
  while (isHTMLElement(currentNode) && !isLastTraversableNode(currentNode)) {
56
83
  if (isContainingBlock(currentNode)) {
57
84
  return currentNode;
58
- } else {
59
- currentNode = getParentNode(currentNode);
85
+ } else if (isTopLayer(currentNode)) {
86
+ return null;
60
87
  }
88
+ currentNode = getParentNode(currentNode);
61
89
  }
62
90
  return null;
63
91
  }
@@ -65,8 +93,9 @@ function isWebKit() {
65
93
  if (typeof CSS === 'undefined' || !CSS.supports) return false;
66
94
  return CSS.supports('-webkit-backdrop-filter', 'none');
67
95
  }
96
+ const lastTraversableNodeNames = /*#__PURE__*/new Set(['html', 'body', '#document']);
68
97
  function isLastTraversableNode(node) {
69
- return ['html', 'body', '#document'].includes(getNodeName(node));
98
+ return lastTraversableNodeNames.has(getNodeName(node));
70
99
  }
71
100
  function getComputedStyle(element) {
72
101
  return getWindow(element).getComputedStyle(element);
@@ -79,8 +108,8 @@ function getNodeScroll(element) {
79
108
  };
80
109
  }
81
110
  return {
82
- scrollLeft: element.pageXOffset,
83
- scrollTop: element.pageYOffset
111
+ scrollLeft: element.scrollX,
112
+ scrollTop: element.scrollY
84
113
  };
85
114
  }
86
115
  function getParentNode(node) {
@@ -120,9 +149,13 @@ function getOverflowAncestors(node, list, traverseIframes) {
120
149
  const isBody = scrollableAncestor === ((_node$ownerDocument2 = node.ownerDocument) == null ? void 0 : _node$ownerDocument2.body);
121
150
  const win = getWindow(scrollableAncestor);
122
151
  if (isBody) {
123
- return list.concat(win, win.visualViewport || [], isOverflowElement(scrollableAncestor) ? scrollableAncestor : [], win.frameElement && traverseIframes ? getOverflowAncestors(win.frameElement) : []);
152
+ const frameElement = getFrameElement(win);
153
+ return list.concat(win, win.visualViewport || [], isOverflowElement(scrollableAncestor) ? scrollableAncestor : [], frameElement && traverseIframes ? getOverflowAncestors(frameElement) : []);
124
154
  }
125
155
  return list.concat(scrollableAncestor, getOverflowAncestors(scrollableAncestor, [], traverseIframes));
126
156
  }
157
+ function getFrameElement(win) {
158
+ return win.parent && Object.getPrototypeOf(win.parent) ? win.frameElement : null;
159
+ }
127
160
 
128
- export { getComputedStyle, getContainingBlock, getDocumentElement, getNearestOverflowAncestor, getNodeName, getNodeScroll, getOverflowAncestors, getParentNode, getWindow, isContainingBlock, isElement, isHTMLElement, isLastTraversableNode, isNode, isOverflowElement, isShadowRoot, isTableElement, isWebKit };
161
+ export { getComputedStyle, getContainingBlock, getDocumentElement, getFrameElement, getNearestOverflowAncestor, getNodeName, getNodeScroll, getOverflowAncestors, getParentNode, getWindow, isContainingBlock, isElement, isHTMLElement, isLastTraversableNode, isNode, isOverflowElement, isShadowRoot, isTableElement, isTopLayer, isWebKit };
@@ -1,3 +1,8 @@
1
+ /**
2
+ * Custom positioning reference element.
3
+ * @see https://floating-ui.com/docs/virtual-elements
4
+ */
5
+
1
6
  const min = Math.min;
2
7
  const max = Math.max;
3
8
  const round = Math.round;
@@ -34,8 +39,9 @@ function getOppositeAxis(axis) {
34
39
  function getAxisLength(axis) {
35
40
  return axis === 'y' ? 'height' : 'width';
36
41
  }
42
+ const yAxisSides = /*#__PURE__*/new Set(['top', 'bottom']);
37
43
  function getSideAxis(placement) {
38
- return ['top', 'bottom'].includes(getSide(placement)) ? 'y' : 'x';
44
+ return yAxisSides.has(getSide(placement)) ? 'y' : 'x';
39
45
  }
40
46
  function getAlignmentAxis(placement) {
41
47
  return getOppositeAxis(getSideAxis(placement));
@@ -60,19 +66,19 @@ function getExpandedPlacements(placement) {
60
66
  function getOppositeAlignmentPlacement(placement) {
61
67
  return placement.replace(/start|end/g, alignment => oppositeAlignmentMap[alignment]);
62
68
  }
69
+ const lrPlacement = ['left', 'right'];
70
+ const rlPlacement = ['right', 'left'];
71
+ const tbPlacement = ['top', 'bottom'];
72
+ const btPlacement = ['bottom', 'top'];
63
73
  function getSideList(side, isStart, rtl) {
64
- const lr = ['left', 'right'];
65
- const rl = ['right', 'left'];
66
- const tb = ['top', 'bottom'];
67
- const bt = ['bottom', 'top'];
68
74
  switch (side) {
69
75
  case 'top':
70
76
  case 'bottom':
71
- if (rtl) return isStart ? rl : lr;
72
- return isStart ? lr : rl;
77
+ if (rtl) return isStart ? rlPlacement : lrPlacement;
78
+ return isStart ? lrPlacement : rlPlacement;
73
79
  case 'left':
74
80
  case 'right':
75
- return isStart ? tb : bt;
81
+ return isStart ? tbPlacement : btPlacement;
76
82
  default:
77
83
  return [];
78
84
  }
@@ -109,12 +115,21 @@ function getPaddingObject(padding) {
109
115
  };
110
116
  }
111
117
  function rectToClientRect(rect) {
118
+ const {
119
+ x,
120
+ y,
121
+ width,
122
+ height
123
+ } = rect;
112
124
  return {
113
- ...rect,
114
- top: rect.y,
115
- left: rect.x,
116
- right: rect.x + rect.width,
117
- bottom: rect.y + rect.height
125
+ width,
126
+ height,
127
+ top: y,
128
+ left: x,
129
+ right: x + width,
130
+ bottom: y + height,
131
+ x,
132
+ y
118
133
  };
119
134
  }
120
135