@digdir/designsystemet-react 0.58.0 → 0.59.1-alpha.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 (107) hide show
  1. package/dist/cjs/components/Alert/Alert.js +2 -2
  2. package/dist/cjs/components/Button/Button.js +1 -2
  3. package/dist/cjs/components/DropdownMenu/DropdownMenuContent.js +4 -4
  4. package/dist/cjs/components/DropdownMenu/DropdownMenuTrigger.js +1 -1
  5. package/dist/cjs/components/Modal/ModalDialog.js +1 -1
  6. package/dist/cjs/components/Popover/PopoverContent.js +6 -6
  7. package/dist/cjs/components/Popover/PopoverTrigger.js +1 -1
  8. package/dist/cjs/components/SkipLink/SkipLink.js +1 -2
  9. package/dist/cjs/components/Tooltip/Tooltip.js +6 -6
  10. package/dist/cjs/components/form/Checkbox/Checkbox.js +1 -1
  11. package/dist/cjs/components/form/Combobox/Combobox.js +60 -177
  12. package/dist/cjs/components/form/Combobox/ComboboxContext.js +8 -0
  13. package/dist/cjs/components/form/Combobox/ComboboxIdContext.js +42 -0
  14. package/dist/cjs/components/form/Combobox/Custom/Custom.js +14 -9
  15. package/dist/cjs/components/form/Combobox/Empty/Empty.js +4 -4
  16. package/dist/cjs/components/form/Combobox/Option/Option.js +15 -33
  17. package/dist/cjs/components/form/Combobox/Option/useComboboxOption.js +47 -0
  18. package/dist/cjs/components/form/Combobox/internal/ComboboxChips.js +14 -6
  19. package/dist/cjs/components/form/Combobox/internal/ComboboxClearButton.js +4 -4
  20. package/dist/cjs/components/form/Combobox/internal/ComboboxInput.js +40 -35
  21. package/dist/cjs/components/form/Combobox/internal/ComboboxNative.js +2 -2
  22. package/dist/cjs/components/form/Combobox/useCombobox.js +46 -32
  23. package/dist/cjs/components/form/Combobox/useComboboxKeyboard.js +79 -0
  24. package/dist/cjs/components/form/Combobox/useFloatingCombobox.js +78 -0
  25. package/dist/cjs/components/form/Search/Search.js +1 -1
  26. package/dist/cjs/node_modules/@floating-ui/utils/{dom/dist → dist}/floating-ui.utils.dom.js +7 -4
  27. package/dist/cjs/node_modules/@floating-ui/utils/dist/floating-ui.utils.js +5 -0
  28. package/dist/cjs/{node_modules → packages/react/node_modules}/@floating-ui/core/dist/floating-ui.core.js +40 -16
  29. package/dist/cjs/{node_modules → packages/react/node_modules}/@floating-ui/dom/dist/floating-ui.dom.js +83 -31
  30. package/dist/cjs/{node_modules → packages/react/node_modules}/@floating-ui/react/dist/floating-ui.react.js +307 -157
  31. package/dist/cjs/{node_modules/@floating-ui/react/utils → packages/react/node_modules/@floating-ui/react}/dist/floating-ui.react.utils.js +9 -4
  32. package/dist/cjs/{node_modules → packages/react/node_modules}/@floating-ui/react-dom/dist/floating-ui.react-dom.js +22 -18
  33. package/dist/{esm → cjs/packages/react}/node_modules/tabbable/dist/index.esm.js +59 -13
  34. package/dist/cjs/react-css-modules.css +0 -315
  35. package/dist/cjs/utilities/RovingTabIndex/RovingTabindexItem.js +1 -1
  36. package/dist/cjs/utilities/RovingTabIndex/RovingTabindexRoot.js +1 -1
  37. package/dist/esm/components/Alert/Alert.js +2 -2
  38. package/dist/esm/components/Button/Button.js +1 -2
  39. package/dist/esm/components/DropdownMenu/DropdownMenuContent.js +3 -3
  40. package/dist/esm/components/DropdownMenu/DropdownMenuTrigger.js +1 -1
  41. package/dist/esm/components/Modal/ModalDialog.js +1 -1
  42. package/dist/esm/components/Popover/PopoverContent.js +4 -4
  43. package/dist/esm/components/Popover/PopoverTrigger.js +1 -1
  44. package/dist/esm/components/SkipLink/SkipLink.js +1 -2
  45. package/dist/esm/components/Tooltip/Tooltip.js +4 -4
  46. package/dist/esm/components/form/Checkbox/Checkbox.js +1 -1
  47. package/dist/esm/components/form/Combobox/Combobox.js +65 -182
  48. package/dist/esm/components/form/Combobox/ComboboxContext.js +6 -0
  49. package/dist/esm/components/form/Combobox/ComboboxIdContext.js +35 -0
  50. package/dist/esm/components/form/Combobox/Custom/Custom.js +13 -8
  51. package/dist/esm/components/form/Combobox/Empty/Empty.js +3 -3
  52. package/dist/esm/components/form/Combobox/Option/Option.js +15 -33
  53. package/dist/esm/components/form/Combobox/Option/useComboboxOption.js +45 -0
  54. package/dist/esm/components/form/Combobox/internal/ComboboxChips.js +13 -5
  55. package/dist/esm/components/form/Combobox/internal/ComboboxClearButton.js +3 -3
  56. package/dist/esm/components/form/Combobox/internal/ComboboxInput.js +39 -34
  57. package/dist/esm/components/form/Combobox/internal/ComboboxNative.js +2 -2
  58. package/dist/esm/components/form/Combobox/useCombobox.js +46 -32
  59. package/dist/esm/components/form/Combobox/useComboboxKeyboard.js +77 -0
  60. package/dist/esm/components/form/Combobox/useFloatingCombobox.js +76 -0
  61. package/dist/esm/components/form/Search/Search.js +1 -1
  62. package/dist/esm/node_modules/@floating-ui/utils/{dom/dist → dist}/floating-ui.utils.dom.js +7 -4
  63. package/dist/esm/node_modules/@floating-ui/utils/dist/floating-ui.utils.js +5 -0
  64. package/dist/esm/{node_modules → packages/react/node_modules}/@floating-ui/core/dist/floating-ui.core.js +40 -16
  65. package/dist/esm/{node_modules → packages/react/node_modules}/@floating-ui/dom/dist/floating-ui.dom.js +82 -30
  66. package/dist/esm/{node_modules → packages/react/node_modules}/@floating-ui/react/dist/floating-ui.react.js +282 -135
  67. package/dist/esm/{node_modules/@floating-ui/react/utils → packages/react/node_modules/@floating-ui/react}/dist/floating-ui.react.utils.js +9 -5
  68. package/dist/esm/{node_modules → packages/react/node_modules}/@floating-ui/react-dom/dist/floating-ui.react-dom.js +19 -14
  69. package/dist/{cjs → esm/packages/react}/node_modules/tabbable/dist/index.esm.js +55 -15
  70. package/dist/esm/react-css-modules.css +0 -315
  71. package/dist/esm/utilities/RovingTabIndex/RovingTabindexItem.js +1 -1
  72. package/dist/esm/utilities/RovingTabIndex/RovingTabindexRoot.js +1 -1
  73. package/dist/types/components/Alert/Alert.d.ts +12 -0
  74. package/dist/types/components/Alert/Alert.d.ts.map +1 -1
  75. package/dist/types/components/Button/Button.d.ts.map +1 -1
  76. package/dist/types/components/SkipLink/SkipLink.d.ts.map +1 -1
  77. package/dist/types/components/form/Combobox/Combobox.d.ts +104 -39
  78. package/dist/types/components/form/Combobox/Combobox.d.ts.map +1 -1
  79. package/dist/types/components/form/Combobox/ComboboxContext.d.ts +48 -0
  80. package/dist/types/components/form/Combobox/ComboboxContext.d.ts.map +1 -0
  81. package/dist/types/components/form/Combobox/ComboboxIdContext.d.ts +19 -0
  82. package/dist/types/components/form/Combobox/ComboboxIdContext.d.ts.map +1 -0
  83. package/dist/types/components/form/Combobox/Custom/Custom.d.ts.map +1 -1
  84. package/dist/types/components/form/Combobox/Option/Option.d.ts +2 -2
  85. package/dist/types/components/form/Combobox/Option/Option.d.ts.map +1 -1
  86. package/dist/types/components/form/Combobox/Option/useComboboxOption.d.ts +14 -0
  87. package/dist/types/components/form/Combobox/Option/useComboboxOption.d.ts.map +1 -0
  88. package/dist/types/components/form/Combobox/internal/ComboboxChips.d.ts.map +1 -1
  89. package/dist/types/components/form/Combobox/internal/ComboboxInput.d.ts +0 -1
  90. package/dist/types/components/form/Combobox/internal/ComboboxInput.d.ts.map +1 -1
  91. package/dist/types/components/form/Combobox/internal/ComboboxNative.d.ts +3 -1
  92. package/dist/types/components/form/Combobox/internal/ComboboxNative.d.ts.map +1 -1
  93. package/dist/types/components/form/Combobox/useCombobox.d.ts +13 -5
  94. package/dist/types/components/form/Combobox/useCombobox.d.ts.map +1 -1
  95. package/dist/types/components/form/Combobox/useComboboxKeyboard.d.ts +20 -0
  96. package/dist/types/components/form/Combobox/useComboboxKeyboard.d.ts.map +1 -0
  97. package/dist/types/components/form/Combobox/useFloatingCombobox.d.ts +41 -0
  98. package/dist/types/components/form/Combobox/useFloatingCombobox.d.ts.map +1 -0
  99. package/package.json +3 -3
  100. package/dist/cjs/components/Button/Button.module.css.js +0 -6
  101. package/dist/cjs/components/SkipLink/SkipLink.module.css.js +0 -6
  102. package/dist/cjs/node_modules/@floating-ui/react/node_modules/@floating-ui/utils/dist/floating-ui.utils.js +0 -6
  103. package/dist/cjs/node_modules/@floating-ui/react/node_modules/@floating-ui/utils/dom/dist/floating-ui.utils.dom.js +0 -68
  104. package/dist/esm/components/Button/Button.module.css.js +0 -4
  105. package/dist/esm/components/SkipLink/SkipLink.module.css.js +0 -4
  106. package/dist/esm/node_modules/@floating-ui/react/node_modules/@floating-ui/utils/dist/floating-ui.utils.js +0 -4
  107. package/dist/esm/node_modules/@floating-ui/react/node_modules/@floating-ui/utils/dom/dist/floating-ui.utils.dom.js +0 -57
@@ -2,14 +2,13 @@
2
2
  'use strict';
3
3
 
4
4
  var React = require('react');
5
- var floatingUi_react_utils = require('../utils/dist/floating-ui.react.utils.js');
6
- var floatingUi_utils = require('../node_modules/@floating-ui/utils/dist/floating-ui.utils.js');
5
+ var floatingUi_react_utils = require('./floating-ui.react.utils.js');
6
+ var floatingUi_utils = require('../../../../../../node_modules/@floating-ui/utils/dist/floating-ui.utils.js');
7
7
  var floatingUi_reactDom = require('../../react-dom/dist/floating-ui.react-dom.js');
8
- var floatingUi_utils_dom$1 = require('../node_modules/@floating-ui/utils/dom/dist/floating-ui.utils.dom.js');
8
+ var floatingUi_utils_dom = require('../../../../../../node_modules/@floating-ui/utils/dist/floating-ui.utils.dom.js');
9
9
  var index_esm = require('../../../tabbable/dist/index.esm.js');
10
10
  var ReactDOM = require('react-dom');
11
11
  var floatingUi_dom = require('../../dom/dist/floating-ui.dom.js');
12
- var floatingUi_utils_dom = require('../../utils/dom/dist/floating-ui.utils.dom.js');
13
12
 
14
13
  function _interopNamespaceDefault(e) {
15
14
  var n = Object.create(null);
@@ -32,7 +31,7 @@ var React__namespace = /*#__PURE__*/_interopNamespaceDefault(React);
32
31
 
33
32
  /**
34
33
  * Merges an array of refs into a single memoized callback ref or `null`.
35
- * @see https://floating-ui.com/docs/useMergeRefs
34
+ * @see https://floating-ui.com/docs/react-utils#usemergerefs
36
35
  */
37
36
  function useMergeRefs(refs) {
38
37
  return React__namespace.useMemo(() => {
@@ -52,8 +51,12 @@ function useMergeRefs(refs) {
52
51
  }, refs);
53
52
  }
54
53
 
55
- // `toString()` prevents bundlers from trying to `import { useInsertionEffect } from 'react'`
56
- const useInsertionEffect = React__namespace[/*#__PURE__*/'useInsertionEffect'.toString()];
54
+ // https://github.com/mui/material-ui/issues/41190#issuecomment-2040873379
55
+ const SafeReact = {
56
+ ...React__namespace
57
+ };
58
+
59
+ const useInsertionEffect = SafeReact.useInsertionEffect;
57
60
  const useSafeInsertionEffect = useInsertionEffect || (fn => fn());
58
61
  function useEffectEvent(callback) {
59
62
  const ref = React__namespace.useRef(() => {
@@ -241,6 +244,67 @@ function getGridNavigatedIndex(elementsRef, _ref) {
241
244
  return nextIndex;
242
245
  }
243
246
 
247
+ /** For each cell index, gets the item index that occupies that cell */
248
+ function buildCellMap(sizes, cols, dense) {
249
+ const cellMap = [];
250
+ let startIndex = 0;
251
+ sizes.forEach((_ref2, index) => {
252
+ let {
253
+ width,
254
+ height
255
+ } = _ref2;
256
+ if (width > cols) {
257
+ if (process.env.NODE_ENV !== "production") {
258
+ throw new Error("[Floating UI]: Invalid grid - item width at index " + index + " is greater than grid columns");
259
+ }
260
+ }
261
+ let itemPlaced = false;
262
+ if (dense) {
263
+ startIndex = 0;
264
+ }
265
+ while (!itemPlaced) {
266
+ const targetCells = [];
267
+ for (let i = 0; i < width; i++) {
268
+ for (let j = 0; j < height; j++) {
269
+ targetCells.push(startIndex + i + j * cols);
270
+ }
271
+ }
272
+ if (startIndex % cols + width <= cols && targetCells.every(cell => cellMap[cell] == null)) {
273
+ targetCells.forEach(cell => {
274
+ cellMap[cell] = index;
275
+ });
276
+ itemPlaced = true;
277
+ } else {
278
+ startIndex++;
279
+ }
280
+ }
281
+ });
282
+
283
+ // convert into a non-sparse array
284
+ return [...cellMap];
285
+ }
286
+
287
+ /** Gets cell index of an item's corner or -1 when index is -1. */
288
+ function getCellIndexOfCorner(index, sizes, cellMap, cols, corner) {
289
+ if (index === -1) return -1;
290
+ const firstCellIndex = cellMap.indexOf(index);
291
+ switch (corner) {
292
+ case 'tl':
293
+ return firstCellIndex;
294
+ case 'tr':
295
+ return firstCellIndex + sizes[index].width - 1;
296
+ case 'bl':
297
+ return firstCellIndex + (sizes[index].height - 1) * cols;
298
+ case 'br':
299
+ return cellMap.lastIndexOf(index);
300
+ }
301
+ }
302
+
303
+ /** Gets all cell indices that correspond to the specified indices */
304
+ function getCellIndices(indices, cellMap) {
305
+ return cellMap.flatMap((index, cellIndex) => indices.includes(index) ? [cellIndex] : []);
306
+ }
307
+
244
308
  let rafId = 0;
245
309
  function enqueueFocus(el, options) {
246
310
  if (options === void 0) {
@@ -281,7 +345,9 @@ function _extends() {
281
345
 
282
346
  let serverHandoffComplete = false;
283
347
  let count = 0;
284
- const genId = () => "floating-ui-" + count++;
348
+ const genId = () => // Ensure the id is unique with multiple independent versions of Floating UI
349
+ // on <React 18
350
+ "floating-ui-" + Math.random().toString(36).slice(2, 6) + count++;
285
351
  function useFloatingId() {
286
352
  const [id, setId] = React__namespace.useState(() => serverHandoffComplete ? genId() : undefined);
287
353
  index(() => {
@@ -291,30 +357,55 @@ function useFloatingId() {
291
357
  // eslint-disable-next-line react-hooks/exhaustive-deps
292
358
  }, []);
293
359
  React__namespace.useEffect(() => {
294
- if (!serverHandoffComplete) {
295
- serverHandoffComplete = true;
296
- }
360
+ serverHandoffComplete = true;
297
361
  }, []);
298
362
  return id;
299
363
  }
300
-
301
- // `toString()` prevents bundlers from trying to `import { useId } from 'react'`
302
- const useReactId = React__namespace[/*#__PURE__*/'useId'.toString()];
364
+ const useReactId = SafeReact.useId;
303
365
 
304
366
  /**
305
367
  * Uses React 18's built-in `useId()` when available, or falls back to a
306
368
  * slightly less performant (requiring a double render) implementation for
307
369
  * earlier React versions.
308
- * @see https://floating-ui.com/docs/useId
370
+ * @see https://floating-ui.com/docs/react-utils#useid
309
371
  */
310
372
  const useId = useReactId || useFloatingId;
311
373
 
374
+ let devMessageSet;
375
+ if (process.env.NODE_ENV !== "production") {
376
+ devMessageSet = /*#__PURE__*/new Set();
377
+ }
378
+ function warn() {
379
+ var _devMessageSet;
380
+ for (var _len = arguments.length, messages = new Array(_len), _key = 0; _key < _len; _key++) {
381
+ messages[_key] = arguments[_key];
382
+ }
383
+ const message = "Floating UI: " + messages.join(' ');
384
+ if (!((_devMessageSet = devMessageSet) != null && _devMessageSet.has(message))) {
385
+ var _devMessageSet2;
386
+ (_devMessageSet2 = devMessageSet) == null || _devMessageSet2.add(message);
387
+ console.warn(message);
388
+ }
389
+ }
390
+ function error() {
391
+ var _devMessageSet3;
392
+ for (var _len2 = arguments.length, messages = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
393
+ messages[_key2] = arguments[_key2];
394
+ }
395
+ const message = "Floating UI: " + messages.join(' ');
396
+ if (!((_devMessageSet3 = devMessageSet) != null && _devMessageSet3.has(message))) {
397
+ var _devMessageSet4;
398
+ (_devMessageSet4 = devMessageSet) == null || _devMessageSet4.add(message);
399
+ console.error(message);
400
+ }
401
+ }
402
+
312
403
  /**
313
404
  * Renders a pointing arrow triangle.
314
405
  * @see https://floating-ui.com/docs/FloatingArrow
315
406
  */
316
- const FloatingArrow = /*#__PURE__*/React__namespace.forwardRef(function FloatingArrow(_ref, ref) {
317
- let {
407
+ const FloatingArrow = /*#__PURE__*/React__namespace.forwardRef(function FloatingArrow(props, ref) {
408
+ const {
318
409
  context: {
319
410
  placement,
320
411
  elements: {
@@ -336,10 +427,10 @@ const FloatingArrow = /*#__PURE__*/React__namespace.forwardRef(function Floating
336
427
  ...restStyle
337
428
  } = {},
338
429
  ...rest
339
- } = _ref;
430
+ } = props;
340
431
  if (process.env.NODE_ENV !== "production") {
341
432
  if (!ref) {
342
- console.warn('Floating UI: The `ref` prop is required for the `FloatingArrow`', 'component.');
433
+ warn('The `ref` prop is required for `FloatingArrow`.');
343
434
  }
344
435
  }
345
436
  const clipPathId = useId();
@@ -349,8 +440,8 @@ const FloatingArrow = /*#__PURE__*/React__namespace.forwardRef(function Floating
349
440
 
350
441
  // Strokes must be double the border width, this ensures the stroke's width
351
442
  // works as you'd expect.
352
- strokeWidth *= 2;
353
- const halfStrokeWidth = strokeWidth / 2;
443
+ const computedStrokeWidth = strokeWidth * 2;
444
+ const halfStrokeWidth = computedStrokeWidth / 2;
354
445
  const svgX = width / 2 * (tipRadius / -8 + 1);
355
446
  const svgY = height / 2 * tipRadius / 4;
356
447
  const [side, alignment] = placement.split('-');
@@ -374,7 +465,7 @@ const FloatingArrow = /*#__PURE__*/React__namespace.forwardRef(function Floating
374
465
  return /*#__PURE__*/React__namespace.createElement("svg", _extends({}, rest, {
375
466
  "aria-hidden": true,
376
467
  ref: ref,
377
- width: isCustomShape ? width : width + strokeWidth,
468
+ width: isCustomShape ? width : width + computedStrokeWidth,
378
469
  height: width,
379
470
  viewBox: "0 0 " + width + " " + (height > width ? height : width),
380
471
  style: {
@@ -382,27 +473,27 @@ const FloatingArrow = /*#__PURE__*/React__namespace.forwardRef(function Floating
382
473
  pointerEvents: 'none',
383
474
  [xOffsetProp]: arrowX,
384
475
  [yOffsetProp]: arrowY,
385
- [side]: isVerticalSide || isCustomShape ? '100%' : "calc(100% - " + strokeWidth / 2 + "px)",
476
+ [side]: isVerticalSide || isCustomShape ? '100%' : "calc(100% - " + computedStrokeWidth / 2 + "px)",
386
477
  transform: "" + rotation + (transform != null ? transform : ''),
387
478
  ...restStyle
388
479
  }
389
- }), strokeWidth > 0 && /*#__PURE__*/React__namespace.createElement("path", {
480
+ }), computedStrokeWidth > 0 && /*#__PURE__*/React__namespace.createElement("path", {
390
481
  clipPath: "url(#" + clipPathId + ")",
391
482
  fill: "none",
392
483
  stroke: stroke
393
484
  // Account for the stroke on the fill path rendered below.
394
485
  ,
395
- strokeWidth: strokeWidth + (d ? 0 : 1),
486
+ strokeWidth: computedStrokeWidth + (d ? 0 : 1),
396
487
  d: dValue
397
488
  }), /*#__PURE__*/React__namespace.createElement("path", {
398
- stroke: strokeWidth && !d ? rest.fill : 'none',
489
+ stroke: computedStrokeWidth && !d ? rest.fill : 'none',
399
490
  d: dValue
400
491
  }), /*#__PURE__*/React__namespace.createElement("clipPath", {
401
492
  id: clipPathId
402
493
  }, /*#__PURE__*/React__namespace.createElement("rect", {
403
494
  x: -halfStrokeWidth,
404
495
  y: halfStrokeWidth * (isCustomShape ? -1 : 1),
405
- width: width + strokeWidth,
496
+ width: width + computedStrokeWidth,
406
497
  height: width
407
498
  })));
408
499
  });
@@ -426,10 +517,19 @@ function createPubSub() {
426
517
 
427
518
  const FloatingNodeContext = /*#__PURE__*/React__namespace.createContext(null);
428
519
  const FloatingTreeContext = /*#__PURE__*/React__namespace.createContext(null);
520
+
521
+ /**
522
+ * Returns the parent node id for nested floating elements, if available.
523
+ * Returns `null` for top-level floating elements.
524
+ */
429
525
  const useFloatingParentNodeId = () => {
430
526
  var _React$useContext;
431
527
  return ((_React$useContext = React__namespace.useContext(FloatingNodeContext)) == null ? void 0 : _React$useContext.id) || null;
432
528
  };
529
+
530
+ /**
531
+ * Returns the nearest floating tree context, if available.
532
+ */
433
533
  const useFloatingTree = () => React__namespace.useContext(FloatingTreeContext);
434
534
 
435
535
  function createAttribute(name) {
@@ -534,7 +634,7 @@ function useHover(context, props) {
534
634
  return () => {
535
635
  html.removeEventListener('mouseleave', onLeave);
536
636
  };
537
- }, [floating, open, onOpenChange, enabled, handleCloseRef, dataRef, isHoverOpen]);
637
+ }, [floating, open, onOpenChange, enabled, handleCloseRef, isHoverOpen]);
538
638
  const closeWithDelay = React__namespace.useCallback(function (event, runElseBranch, reason) {
539
639
  if (runElseBranch === void 0) {
540
640
  runElseBranch = true;
@@ -648,7 +748,7 @@ function useHover(context, props) {
648
748
  }
649
749
  })(event);
650
750
  }
651
- if (floatingUi_utils_dom$1.isElement(domReference)) {
751
+ if (floatingUi_utils_dom.isElement(domReference)) {
652
752
  const ref = domReference;
653
753
  open && ref.addEventListener('mouseleave', onScrollMouseLeave);
654
754
  floating == null || floating.addEventListener('mouseleave', onScrollMouseLeave);
@@ -681,7 +781,7 @@ function useHover(context, props) {
681
781
  body.setAttribute(safePolygonIdentifier, '');
682
782
  body.style.pointerEvents = 'none';
683
783
  performedPointerEventsMutationRef.current = true;
684
- if (floatingUi_utils_dom$1.isElement(domReference) && floating) {
784
+ if (floatingUi_utils_dom.isElement(domReference) && floating) {
685
785
  var _tree$nodesRef$curren;
686
786
  const ref = domReference;
687
787
  const parentFloating = tree == null || (_tree$nodesRef$curren = tree.nodesRef.current.find(node => node.id === parentId)) == null || (_tree$nodesRef$curren = _tree$nodesRef$curren.context) == null ? void 0 : _tree$nodesRef$curren.elements.floating;
@@ -696,7 +796,7 @@ function useHover(context, props) {
696
796
  };
697
797
  }
698
798
  }
699
- }, [enabled, open, parentId, floating, domReference, tree, handleCloseRef, dataRef, isHoverOpen]);
799
+ }, [enabled, open, parentId, floating, domReference, tree, handleCloseRef, isHoverOpen]);
700
800
  index(() => {
701
801
  if (!open) {
702
802
  pointerTypeRef.current = undefined;
@@ -724,15 +824,23 @@ function useHover(context, props) {
724
824
  onPointerDown: setPointerRef,
725
825
  onPointerEnter: setPointerRef,
726
826
  onMouseMove(event) {
827
+ function handleMouseMove() {
828
+ if (!blockMouseMoveRef.current) {
829
+ onOpenChange(true, event.nativeEvent, 'hover');
830
+ }
831
+ }
832
+ if (mouseOnly && !floatingUi_react_utils.isMouseLikePointerType(pointerTypeRef.current)) {
833
+ return;
834
+ }
727
835
  if (open || restMs === 0) {
728
836
  return;
729
837
  }
730
838
  clearTimeout(restTimeoutRef.current);
731
- restTimeoutRef.current = setTimeout(() => {
732
- if (!blockMouseMoveRef.current) {
733
- onOpenChange(true, event.nativeEvent, 'hover');
734
- }
735
- }, restMs);
839
+ if (pointerTypeRef.current === 'touch') {
840
+ handleMouseMove();
841
+ } else {
842
+ restTimeoutRef.current = setTimeout(handleMouseMove, restMs);
843
+ }
736
844
  }
737
845
  },
738
846
  floating: {
@@ -744,7 +852,7 @@ function useHover(context, props) {
744
852
  }
745
853
  }
746
854
  };
747
- }, [enabled, restMs, open, onOpenChange, closeWithDelay]);
855
+ }, [enabled, mouseOnly, open, restMs, onOpenChange, closeWithDelay]);
748
856
  }
749
857
 
750
858
  function getAncestors(nodes, id) {
@@ -999,75 +1107,81 @@ const FocusGuard = /*#__PURE__*/React__namespace.forwardRef(function FocusGuard(
999
1107
  });
1000
1108
 
1001
1109
  const PortalContext = /*#__PURE__*/React__namespace.createContext(null);
1002
- function useFloatingPortalNode(_temp) {
1003
- let {
1110
+ const attr = /*#__PURE__*/createAttribute('portal');
1111
+
1112
+ /**
1113
+ * @see https://floating-ui.com/docs/FloatingPortal#usefloatingportalnode
1114
+ */
1115
+ function useFloatingPortalNode(props) {
1116
+ if (props === void 0) {
1117
+ props = {};
1118
+ }
1119
+ const {
1004
1120
  id,
1005
1121
  root
1006
- } = _temp === void 0 ? {} : _temp;
1007
- const [portalNode, setPortalNode] = React__namespace.useState(null);
1122
+ } = props;
1008
1123
  const uniqueId = useId();
1009
1124
  const portalContext = usePortalContext();
1010
- const data = React__namespace.useMemo(() => ({
1011
- id,
1012
- root,
1013
- portalContext,
1014
- uniqueId
1015
- }), [id, root, portalContext, uniqueId]);
1016
- const dataRef = React__namespace.useRef();
1125
+ const [portalNode, setPortalNode] = React__namespace.useState(null);
1126
+ const portalNodeRef = React__namespace.useRef(null);
1017
1127
  index(() => {
1018
1128
  return () => {
1019
1129
  portalNode == null || portalNode.remove();
1130
+ // Allow the subsequent layout effects to create a new node on updates.
1131
+ // The portal node will still be cleaned up on unmount.
1132
+ // https://github.com/floating-ui/floating-ui/issues/2454
1133
+ queueMicrotask(() => {
1134
+ portalNodeRef.current = null;
1135
+ });
1020
1136
  };
1021
- }, [portalNode, data]);
1137
+ }, [portalNode]);
1022
1138
  index(() => {
1023
- if (dataRef.current === data) return;
1024
- dataRef.current = data;
1025
- const {
1026
- id,
1027
- root,
1028
- portalContext,
1029
- uniqueId
1030
- } = data;
1139
+ if (portalNodeRef.current) return;
1031
1140
  const existingIdRoot = id ? document.getElementById(id) : null;
1032
- const attr = createAttribute('portal');
1033
- if (existingIdRoot) {
1034
- const subRoot = document.createElement('div');
1035
- subRoot.id = uniqueId;
1036
- subRoot.setAttribute(attr, '');
1037
- existingIdRoot.appendChild(subRoot);
1038
- setPortalNode(subRoot);
1039
- } else {
1040
- let container = root || (portalContext == null ? void 0 : portalContext.portalNode);
1041
- if (container && !floatingUi_utils_dom$1.isElement(container)) container = container.current;
1042
- container = container || document.body;
1043
- let idWrapper = null;
1044
- if (id) {
1045
- idWrapper = document.createElement('div');
1046
- idWrapper.id = id;
1047
- container.appendChild(idWrapper);
1048
- }
1049
- const subRoot = document.createElement('div');
1050
- subRoot.id = uniqueId;
1051
- subRoot.setAttribute(attr, '');
1052
- container = idWrapper || container;
1053
- container.appendChild(subRoot);
1054
- setPortalNode(subRoot);
1055
- }
1056
- }, [data]);
1141
+ if (!existingIdRoot) return;
1142
+ const subRoot = document.createElement('div');
1143
+ subRoot.id = uniqueId;
1144
+ subRoot.setAttribute(attr, '');
1145
+ existingIdRoot.appendChild(subRoot);
1146
+ portalNodeRef.current = subRoot;
1147
+ setPortalNode(subRoot);
1148
+ }, [id, uniqueId]);
1149
+ index(() => {
1150
+ if (portalNodeRef.current) return;
1151
+ let container = root || (portalContext == null ? void 0 : portalContext.portalNode);
1152
+ if (container && !floatingUi_utils_dom.isElement(container)) container = container.current;
1153
+ container = container || document.body;
1154
+ let idWrapper = null;
1155
+ if (id) {
1156
+ idWrapper = document.createElement('div');
1157
+ idWrapper.id = id;
1158
+ container.appendChild(idWrapper);
1159
+ }
1160
+ const subRoot = document.createElement('div');
1161
+ subRoot.id = uniqueId;
1162
+ subRoot.setAttribute(attr, '');
1163
+ container = idWrapper || container;
1164
+ container.appendChild(subRoot);
1165
+ portalNodeRef.current = subRoot;
1166
+ setPortalNode(subRoot);
1167
+ }, [id, root, uniqueId, portalContext]);
1057
1168
  return portalNode;
1058
1169
  }
1059
1170
  /**
1060
1171
  * Portals the floating element into a given container element — by default,
1061
1172
  * outside of the app root and into the body.
1173
+ * This is necessary to ensure the floating element can appear outside any
1174
+ * potential parent containers that cause clipping (such as `overflow: hidden`),
1175
+ * while retaining its location in the React tree.
1062
1176
  * @see https://floating-ui.com/docs/FloatingPortal
1063
1177
  */
1064
- function FloatingPortal(_ref) {
1065
- let {
1178
+ function FloatingPortal(props) {
1179
+ const {
1066
1180
  children,
1067
1181
  id,
1068
1182
  root = null,
1069
1183
  preserveTabOrder = true
1070
- } = _ref;
1184
+ } = props;
1071
1185
  const portalNode = useFloatingPortalNode({
1072
1186
  id,
1073
1187
  root
@@ -1157,11 +1271,16 @@ const LIST_LIMIT = 20;
1157
1271
  let previouslyFocusedElements = [];
1158
1272
  function addPreviouslyFocusedElement(element) {
1159
1273
  previouslyFocusedElements = previouslyFocusedElements.filter(el => el.isConnected);
1160
- if (element && floatingUi_utils_dom$1.getNodeName(element) !== 'body') {
1161
- previouslyFocusedElements.push(element);
1162
- if (previouslyFocusedElements.length > LIST_LIMIT) {
1163
- previouslyFocusedElements = previouslyFocusedElements.slice(-LIST_LIMIT);
1164
- }
1274
+ let tabbableEl = element;
1275
+ if (!tabbableEl || floatingUi_utils_dom.getNodeName(tabbableEl) === 'body') return;
1276
+ if (!index_esm.isTabbable(tabbableEl, getTabbableOptions())) {
1277
+ const tabbableChild = index_esm.tabbable(tabbableEl, getTabbableOptions())[0];
1278
+ if (!tabbableChild) return;
1279
+ tabbableEl = tabbableChild;
1280
+ }
1281
+ previouslyFocusedElements.push(tabbableEl);
1282
+ if (previouslyFocusedElements.length > LIST_LIMIT) {
1283
+ previouslyFocusedElements = previouslyFocusedElements.slice(-LIST_LIMIT);
1165
1284
  }
1166
1285
  }
1167
1286
  function getPreviouslyFocusedElement() {
@@ -1271,7 +1390,7 @@ function FloatingFocusManager(props) {
1271
1390
  return () => {
1272
1391
  doc.removeEventListener('keydown', onKeyDown);
1273
1392
  };
1274
- }, [disabled, domReference, floating, modal, orderRef, refs, isUntrappedTypeableCombobox, getTabbableContent, getTabbableElements]);
1393
+ }, [disabled, domReference, floating, modal, orderRef, isUntrappedTypeableCombobox, getTabbableContent, getTabbableElements]);
1275
1394
  React__namespace.useEffect(() => {
1276
1395
  if (disabled || !closeOnFocusOut) return;
1277
1396
 
@@ -1303,7 +1422,7 @@ function FloatingFocusManager(props) {
1303
1422
  }
1304
1423
  });
1305
1424
  }
1306
- if (floating && floatingUi_utils_dom$1.isHTMLElement(domReference)) {
1425
+ if (floating && floatingUi_utils_dom.isHTMLElement(domReference)) {
1307
1426
  domReference.addEventListener('focusout', handleFocusOutside);
1308
1427
  domReference.addEventListener('pointerdown', handlePointerDown);
1309
1428
  !modal && floating.addEventListener('focusout', handleFocusOutside);
@@ -1391,7 +1510,7 @@ function FloatingFocusManager(props) {
1391
1510
  const returnElement = getPreviouslyFocusedElement();
1392
1511
  if (
1393
1512
  // eslint-disable-next-line react-hooks/exhaustive-deps
1394
- returnFocusRef.current && !preventReturnFocusRef.current && floatingUi_utils_dom$1.isHTMLElement(returnElement) && (
1513
+ returnFocusRef.current && !preventReturnFocusRef.current && floatingUi_utils_dom.isHTMLElement(returnElement) && (
1395
1514
  // If the focus moved somewhere else after mount, avoid returning focus
1396
1515
  // since it likely entered a different element which should be
1397
1516
  // respected: https://github.com/floating-ui/floating-ui/issues/2607
@@ -1499,7 +1618,7 @@ function FloatingFocusManager(props) {
1499
1618
  }
1500
1619
 
1501
1620
  function isButtonTarget(event) {
1502
- return floatingUi_utils_dom$1.isHTMLElement(event.target) && event.target.tagName === 'BUTTON';
1621
+ return floatingUi_utils_dom.isHTMLElement(event.target) && event.target.tagName === 'BUTTON';
1503
1622
  }
1504
1623
  function isSpaceIgnored(element) {
1505
1624
  return floatingUi_react_utils.isTypeableElement(element);
@@ -1723,19 +1842,18 @@ function useDismiss(context, props) {
1723
1842
  const target = floatingUi_react_utils.getTarget(event);
1724
1843
  const inertSelector = "[" + createAttribute('inert') + "]";
1725
1844
  const markers = floatingUi_react_utils.getDocument(floating).querySelectorAll(inertSelector);
1726
- let targetRootAncestor = floatingUi_utils_dom$1.isElement(target) ? target : null;
1727
- while (targetRootAncestor && !floatingUi_utils_dom$1.isLastTraversableNode(targetRootAncestor)) {
1728
- const nextParent = floatingUi_utils_dom$1.getParentNode(targetRootAncestor);
1729
- if (floatingUi_utils_dom$1.isLastTraversableNode(nextParent) || !floatingUi_utils_dom$1.isElement(nextParent)) {
1845
+ let targetRootAncestor = floatingUi_utils_dom.isElement(target) ? target : null;
1846
+ while (targetRootAncestor && !floatingUi_utils_dom.isLastTraversableNode(targetRootAncestor)) {
1847
+ const nextParent = floatingUi_utils_dom.getParentNode(targetRootAncestor);
1848
+ if (floatingUi_utils_dom.isLastTraversableNode(nextParent) || !floatingUi_utils_dom.isElement(nextParent)) {
1730
1849
  break;
1731
- } else {
1732
- targetRootAncestor = nextParent;
1733
1850
  }
1851
+ targetRootAncestor = nextParent;
1734
1852
  }
1735
1853
 
1736
1854
  // Check if the click occurred on a third-party element injected after the
1737
1855
  // floating element rendered.
1738
- if (markers.length && floatingUi_utils_dom$1.isElement(target) && !floatingUi_react_utils.isRootElement(target) &&
1856
+ if (markers.length && floatingUi_utils_dom.isElement(target) && !floatingUi_react_utils.isRootElement(target) &&
1739
1857
  // Clicked on a direct ancestor (e.g. FloatingOverlay).
1740
1858
  !floatingUi_react_utils.contains(target, floating) &&
1741
1859
  // If the target root element contains none of the markers, then the
@@ -1745,7 +1863,7 @@ function useDismiss(context, props) {
1745
1863
  }
1746
1864
 
1747
1865
  // Check if the click occurred on the scrollbar
1748
- if (floatingUi_utils_dom$1.isHTMLElement(target) && floating) {
1866
+ if (floatingUi_utils_dom.isHTMLElement(target) && floating) {
1749
1867
  // In Firefox, `target.scrollWidth > target.clientWidth` for inline
1750
1868
  // elements.
1751
1869
  const canScrollX = target.clientWidth > 0 && target.scrollWidth > target.clientWidth;
@@ -1757,7 +1875,7 @@ function useDismiss(context, props) {
1757
1875
  // check for. Plus, for modal dialogs with backdrops, it is more
1758
1876
  // important that the backdrop is checked but not so much the window.
1759
1877
  if (canScrollY) {
1760
- const isRTL = floatingUi_utils_dom$1.getComputedStyle(target).direction === 'rtl';
1878
+ const isRTL = floatingUi_utils_dom.getComputedStyle(target).direction === 'rtl';
1761
1879
  if (isRTL) {
1762
1880
  xCond = event.offsetX <= target.offsetWidth - target.clientWidth;
1763
1881
  }
@@ -1812,13 +1930,13 @@ function useDismiss(context, props) {
1812
1930
  outsidePress && doc.addEventListener(outsidePressEvent, outsidePressCapture ? closeOnPressOutsideCapture : closeOnPressOutside, outsidePressCapture);
1813
1931
  let ancestors = [];
1814
1932
  if (ancestorScroll) {
1815
- if (floatingUi_utils_dom$1.isElement(domReference)) {
1933
+ if (floatingUi_utils_dom.isElement(domReference)) {
1816
1934
  ancestors = floatingUi_utils_dom.getOverflowAncestors(domReference);
1817
1935
  }
1818
- if (floatingUi_utils_dom$1.isElement(floating)) {
1936
+ if (floatingUi_utils_dom.isElement(floating)) {
1819
1937
  ancestors = ancestors.concat(floatingUi_utils_dom.getOverflowAncestors(floating));
1820
1938
  }
1821
- if (!floatingUi_utils_dom$1.isElement(reference) && reference && reference.contextElement) {
1939
+ if (!floatingUi_utils_dom.isElement(reference) && reference && reference.contextElement) {
1822
1940
  ancestors = ancestors.concat(floatingUi_utils_dom.getOverflowAncestors(reference.contextElement));
1823
1941
  }
1824
1942
  }
@@ -1873,17 +1991,12 @@ function useDismiss(context, props) {
1873
1991
  }, [enabled, referencePress, outsidePressEvent, referencePressEvent, onOpenChange, closeOnEscapeKeyDown]);
1874
1992
  }
1875
1993
 
1876
- let devMessageSet;
1877
- if (process.env.NODE_ENV !== "production") {
1878
- devMessageSet = /*#__PURE__*/new Set();
1879
- }
1880
-
1881
1994
  /**
1882
1995
  * Provides data to position a floating element and context to add interactions.
1883
1996
  * @see https://floating-ui.com/docs/useFloating
1884
1997
  */
1885
1998
  function useFloating(options) {
1886
- var _options$elements2;
1999
+ var _options$elements;
1887
2000
  if (options === void 0) {
1888
2001
  options = {};
1889
2002
  }
@@ -1892,27 +2005,33 @@ function useFloating(options) {
1892
2005
  onOpenChange: unstable_onOpenChange,
1893
2006
  nodeId
1894
2007
  } = options;
2008
+ const [_domReference, setDomReference] = React__namespace.useState(null);
2009
+ const [positionReference, _setPositionReference] = React__namespace.useState(null);
2010
+ const optionDomReference = (_options$elements = options.elements) == null ? void 0 : _options$elements.reference;
2011
+ const domReference = optionDomReference || _domReference;
1895
2012
  if (process.env.NODE_ENV !== "production") {
1896
- var _options$elements;
1897
- const err = 'Floating UI: Cannot pass a virtual element to the ' + '`elements.reference` option, as it must be a real DOM element. ' + 'Use `refs.setPositionReference` instead.';
1898
- if ((_options$elements = options.elements) != null && _options$elements.reference && !floatingUi_utils_dom$1.isElement(options.elements.reference)) {
1899
- var _devMessageSet;
1900
- if (!((_devMessageSet = devMessageSet) != null && _devMessageSet.has(err))) {
1901
- var _devMessageSet2;
1902
- (_devMessageSet2 = devMessageSet) == null || _devMessageSet2.add(err);
1903
- console.error(err);
1904
- }
2013
+ if (optionDomReference && !floatingUi_utils_dom.isElement(optionDomReference)) {
2014
+ error('Cannot pass a virtual element to the `elements.reference` option,', 'as it must be a real DOM element. Use `refs.setPositionReference()`', 'instead.');
1905
2015
  }
1906
2016
  }
1907
- const [_domReference, setDomReference] = React__namespace.useState(null);
1908
- const domReference = ((_options$elements2 = options.elements) == null ? void 0 : _options$elements2.reference) || _domReference;
1909
- const position = floatingUi_reactDom.useFloating(options);
2017
+ index(() => {
2018
+ if (domReference) {
2019
+ domReferenceRef.current = domReference;
2020
+ }
2021
+ }, [domReference]);
2022
+ const position = floatingUi_reactDom.useFloating({
2023
+ ...options,
2024
+ elements: {
2025
+ ...options.elements,
2026
+ ...(positionReference && {
2027
+ reference: positionReference
2028
+ })
2029
+ }
2030
+ });
1910
2031
  const tree = useFloatingTree();
1911
2032
  const nested = useFloatingParentNodeId() != null;
1912
2033
  const onOpenChange = useEffectEvent((open, event, reason) => {
1913
- if (open) {
1914
- dataRef.current.openEvent = event;
1915
- }
2034
+ dataRef.current.openEvent = open ? event : undefined;
1916
2035
  events.emit('openchange', {
1917
2036
  open,
1918
2037
  event,
@@ -1926,25 +2045,28 @@ function useFloating(options) {
1926
2045
  const events = React__namespace.useState(() => createPubSub())[0];
1927
2046
  const floatingId = useId();
1928
2047
  const setPositionReference = React__namespace.useCallback(node => {
1929
- const positionReference = floatingUi_utils_dom$1.isElement(node) ? {
2048
+ const computedPositionReference = floatingUi_utils_dom.isElement(node) ? {
1930
2049
  getBoundingClientRect: () => node.getBoundingClientRect(),
1931
2050
  contextElement: node
1932
2051
  } : node;
1933
- position.refs.setReference(positionReference);
2052
+ // Store the positionReference in state if the DOM reference is specified externally via the
2053
+ // `elements.reference` option. This ensures that it won't be overridden on future renders.
2054
+ _setPositionReference(computedPositionReference);
2055
+ position.refs.setReference(computedPositionReference);
1934
2056
  }, [position.refs]);
1935
2057
  const setReference = React__namespace.useCallback(node => {
1936
- if (floatingUi_utils_dom$1.isElement(node) || node === null) {
2058
+ if (floatingUi_utils_dom.isElement(node) || node === null) {
1937
2059
  domReferenceRef.current = node;
1938
2060
  setDomReference(node);
1939
2061
  }
1940
2062
 
1941
2063
  // Backwards-compatibility for passing a virtual element to `reference`
1942
2064
  // after it has set the DOM reference.
1943
- if (floatingUi_utils_dom$1.isElement(position.refs.reference.current) || position.refs.reference.current === null ||
2065
+ if (floatingUi_utils_dom.isElement(position.refs.reference.current) || position.refs.reference.current === null ||
1944
2066
  // Don't allow setting virtual elements using the old technique back to
1945
2067
  // `null` to support `positionReference` + an unstable `reference`
1946
2068
  // callback ref.
1947
- node !== null && !floatingUi_utils_dom$1.isElement(node)) {
2069
+ node !== null && !floatingUi_utils_dom.isElement(node)) {
1948
2070
  position.refs.setReference(node);
1949
2071
  }
1950
2072
  }, [position.refs]);
@@ -1998,7 +2120,6 @@ function useFocus(context, props) {
1998
2120
  events,
1999
2121
  refs,
2000
2122
  elements: {
2001
- floating,
2002
2123
  domReference
2003
2124
  }
2004
2125
  } = context;
@@ -2013,13 +2134,13 @@ function useFocus(context, props) {
2013
2134
  if (!enabled) {
2014
2135
  return;
2015
2136
  }
2016
- const win = floatingUi_utils_dom$1.getWindow(domReference);
2137
+ const win = floatingUi_utils_dom.getWindow(domReference);
2017
2138
 
2018
2139
  // If the reference was focused and the user left the tab/window, and the
2019
2140
  // floating element was not open, the focus should be blocked when they
2020
2141
  // return to the tab/window.
2021
2142
  function onBlur() {
2022
- if (!open && floatingUi_utils_dom$1.isHTMLElement(domReference) && domReference === floatingUi_react_utils.activeElement(floatingUi_react_utils.getDocument(domReference))) {
2143
+ if (!open && floatingUi_utils_dom.isHTMLElement(domReference) && domReference === floatingUi_react_utils.activeElement(floatingUi_react_utils.getDocument(domReference))) {
2023
2144
  blockFocusRef.current = true;
2024
2145
  }
2025
2146
  }
@@ -2032,7 +2153,7 @@ function useFocus(context, props) {
2032
2153
  win.removeEventListener('blur', onBlur);
2033
2154
  win.removeEventListener('keydown', onKeyDown, true);
2034
2155
  };
2035
- }, [floating, domReference, open, enabled]);
2156
+ }, [domReference, open, enabled]);
2036
2157
  React__namespace.useEffect(() => {
2037
2158
  if (!enabled) {
2038
2159
  return;
@@ -2071,7 +2192,7 @@ function useFocus(context, props) {
2071
2192
  onFocus(event) {
2072
2193
  if (blockFocusRef.current) return;
2073
2194
  const target = floatingUi_react_utils.getTarget(event.nativeEvent);
2074
- if (visibleOnly && floatingUi_utils_dom$1.isElement(target)) {
2195
+ if (visibleOnly && floatingUi_utils_dom.isElement(target)) {
2075
2196
  try {
2076
2197
  // Mac Safari unreliably matches `:focus-visible` on the reference
2077
2198
  // if focus was outside the page initially - use the fallback
@@ -2093,7 +2214,7 @@ function useFocus(context, props) {
2093
2214
 
2094
2215
  // Hit the non-modal focus management portal guard. Focus will be
2095
2216
  // moved into the floating element immediately after.
2096
- const movedToFocusGuard = floatingUi_utils_dom$1.isElement(relatedTarget) && relatedTarget.hasAttribute(createAttribute('focus-guard')) && relatedTarget.getAttribute('data-type') === 'outside';
2217
+ const movedToFocusGuard = floatingUi_utils_dom.isElement(relatedTarget) && relatedTarget.hasAttribute(createAttribute('focus-guard')) && relatedTarget.getAttribute('data-type') === 'outside';
2097
2218
 
2098
2219
  // Wait for the window blur listener to fire.
2099
2220
  timeoutRef.current = window.setTimeout(() => {
@@ -2105,7 +2226,11 @@ function useFocus(context, props) {
2105
2226
  // When focusing the reference element (e.g. regular click), then
2106
2227
  // clicking into the floating element, prevent it from hiding.
2107
2228
  // Note: it must be focusable, e.g. `tabindex="-1"`.
2108
- if (floatingUi_react_utils.contains(refs.floating.current, relatedTarget) || floatingUi_react_utils.contains(domReference, relatedTarget) || movedToFocusGuard) {
2229
+ // We can not rely on relatedTarget to point to the correct element
2230
+ // as it will only point to the shadow host of the newly focused element
2231
+ // and not the element that actually has received focus if it is located
2232
+ // inside a shadow root.
2233
+ if (floatingUi_react_utils.contains(refs.floating.current, activeEl) || floatingUi_react_utils.contains(domReference, activeEl) || movedToFocusGuard) {
2109
2234
  return;
2110
2235
  }
2111
2236
  onOpenChange(false, event.nativeEvent, 'focus');
@@ -2123,7 +2248,6 @@ function mergeProps(userProps, propsList, elementKey) {
2123
2248
  const isItem = elementKey === 'item';
2124
2249
  let domUserProps = userProps;
2125
2250
  if (isItem && userProps) {
2126
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
2127
2251
  const {
2128
2252
  [ACTIVE_KEY]: _,
2129
2253
  [SELECTED_KEY]: __,
@@ -2227,7 +2351,7 @@ function isMainOrientationKey(key, orientation) {
2227
2351
  function isMainOrientationToEndKey(key, orientation, rtl) {
2228
2352
  const vertical = key === ARROW_DOWN;
2229
2353
  const horizontal = rtl ? key === ARROW_LEFT : key === ARROW_RIGHT;
2230
- return doSwitch(orientation, vertical, horizontal) || key === 'Enter' || key == ' ' || key === '';
2354
+ return doSwitch(orientation, vertical, horizontal) || key === 'Enter' || key === ' ' || key === '';
2231
2355
  }
2232
2356
  function isCrossOrientationOpenKey(key, orientation, rtl) {
2233
2357
  const vertical = rtl ? key === ARROW_LEFT : key === ARROW_RIGHT;
@@ -2272,19 +2396,21 @@ function useListNavigation(context, props) {
2272
2396
  orientation = 'vertical',
2273
2397
  cols = 1,
2274
2398
  scrollItemIntoView = true,
2275
- virtualItemRef
2399
+ virtualItemRef,
2400
+ itemSizes,
2401
+ dense = false
2276
2402
  } = props;
2277
2403
  if (process.env.NODE_ENV !== "production") {
2278
2404
  if (allowEscape) {
2279
2405
  if (!loop) {
2280
- console.warn(['Floating UI: `useListNavigation` looping must be enabled to allow', 'escaping.'].join(' '));
2406
+ warn('`useListNavigation` looping must be enabled to allow escaping.');
2281
2407
  }
2282
2408
  if (!virtual) {
2283
- console.warn(['Floating UI: `useListNavigation` must be virtual to allow', 'escaping.'].join(' '));
2409
+ warn('`useListNavigation` must be virtual to allow escaping.');
2284
2410
  }
2285
2411
  }
2286
2412
  if (orientation === 'vertical' && cols > 1) {
2287
- console.warn(['Floating UI: In grid list navigation mode (`cols` > 1), the', '`orientation` should be either "horizontal" or "both".'].join(' '));
2413
+ warn('In grid list navigation mode (`cols` > 1), the `orientation` should', 'be either "horizontal" or "both".');
2288
2414
  }
2289
2415
  }
2290
2416
  const parentId = useFloatingParentNodeId();
@@ -2362,6 +2488,7 @@ function useListNavigation(context, props) {
2362
2488
  // Regardless of the pointer modality, we want to ensure the selected
2363
2489
  // item comes into view when the floating element is opened.
2364
2490
  forceScrollIntoViewRef.current = true;
2491
+ indexRef.current = selectedIndex;
2365
2492
  onNavigate(selectedIndex);
2366
2493
  }
2367
2494
  } else if (previousMountedRef.current) {
@@ -2530,7 +2657,7 @@ function useListNavigation(context, props) {
2530
2657
  if (nested && isCrossOrientationCloseKey(event.key, orientation, rtl)) {
2531
2658
  floatingUi_react_utils.stopEvent(event);
2532
2659
  onOpenChange(false, event.nativeEvent, 'list-navigation');
2533
- if (floatingUi_utils_dom$1.isHTMLElement(domReference) && !virtual) {
2660
+ if (floatingUi_utils_dom.isHTMLElement(domReference) && !virtual) {
2534
2661
  domReference.focus();
2535
2662
  }
2536
2663
  return;
@@ -2551,17 +2678,38 @@ function useListNavigation(context, props) {
2551
2678
 
2552
2679
  // Grid navigation.
2553
2680
  if (cols > 1) {
2554
- indexRef.current = getGridNavigatedIndex(listRef, {
2681
+ const sizes = itemSizes || Array.from({
2682
+ length: listRef.current.length
2683
+ }, () => ({
2684
+ width: 1,
2685
+ height: 1
2686
+ }));
2687
+ // To calculate movements on the grid, we use hypothetical cell indices
2688
+ // as if every item was 1x1, then convert back to real indices.
2689
+ const cellMap = buildCellMap(sizes, cols, dense);
2690
+ const minGridIndex = cellMap.findIndex(index => index != null && !(disabledIndices != null && disabledIndices.includes(index)));
2691
+ // last enabled index
2692
+ const maxGridIndex = cellMap.reduce((foundIndex, index, cellIndex) => index != null && !(disabledIndices != null && disabledIndices.includes(index)) ? cellIndex : foundIndex, -1);
2693
+ indexRef.current = cellMap[getGridNavigatedIndex({
2694
+ current: cellMap.map(itemIndex => itemIndex != null ? listRef.current[itemIndex] : null)
2695
+ }, {
2555
2696
  event,
2556
2697
  orientation,
2557
2698
  loop,
2558
2699
  cols,
2559
- disabledIndices,
2560
- minIndex,
2561
- maxIndex,
2562
- prevIndex: indexRef.current,
2700
+ // treat undefined (empty grid spaces) as disabled indices so we
2701
+ // don't end up in them
2702
+ disabledIndices: getCellIndices([...(disabledIndices || []), undefined], cellMap),
2703
+ minIndex: minGridIndex,
2704
+ maxIndex: maxGridIndex,
2705
+ prevIndex: getCellIndexOfCorner(indexRef.current, sizes, cellMap, cols,
2706
+ // use a corner matching the edge closest to the direction
2707
+ // we're moving in so we don't end up in the same item. Prefer
2708
+ // top/left over bottom/right.
2709
+ event.key === ARROW_DOWN ? 'bl' : event.key === ARROW_RIGHT ? 'tr' : 'tl'),
2563
2710
  stopEvent: true
2564
- });
2711
+ })]; // navigated cell will never be nullish
2712
+
2565
2713
  onNavigate(indexRef.current);
2566
2714
  if (orientation === 'both') {
2567
2715
  return;
@@ -2720,7 +2868,7 @@ function useListNavigation(context, props) {
2720
2868
  },
2721
2869
  item
2722
2870
  };
2723
- }, [domReference, refs, activeId, virtualId, disabledIndicesRef, latestOpenRef, listRef, enabled, orientation, rtl, virtual, open, hasActiveIndex, nested, selectedIndex, openOnArrowKeyDown, allowEscape, cols, loop, focusItemOnOpen, onNavigate, onOpenChange, item, tree, virtualItemRef]);
2871
+ }, [domReference, refs, activeId, virtualId, disabledIndicesRef, latestOpenRef, listRef, enabled, orientation, rtl, virtual, open, hasActiveIndex, nested, selectedIndex, openOnArrowKeyDown, allowEscape, cols, loop, focusItemOnOpen, onNavigate, onOpenChange, item, tree, virtualItemRef, itemSizes, dense]);
2724
2872
  }
2725
2873
 
2726
2874
  const componentRoleToAriaRoleMap = /*#__PURE__*/new Map([['select', 'listbox'], ['combobox', 'listbox'], ['label', false]]);
@@ -2889,10 +3037,9 @@ function useTransitionStatus(context, props) {
2889
3037
  return () => {
2890
3038
  cancelAnimationFrame(frame);
2891
3039
  };
2892
- } else {
2893
- setInitiated(true);
2894
- setStatus('close');
2895
3040
  }
3041
+ setInitiated(true);
3042
+ setStatus('close');
2896
3043
  }, [open, floating]);
2897
3044
  return {
2898
3045
  isMounted,
@@ -2980,10 +3127,13 @@ function useTransitionStyles(context, props) {
2980
3127
  }
2981
3128
 
2982
3129
  exports.arrow = floatingUi_reactDom.arrow;
3130
+ exports.getOverflowAncestors = floatingUi_utils_dom.getOverflowAncestors;
2983
3131
  exports.autoUpdate = floatingUi_dom.autoUpdate;
2984
3132
  exports.computePosition = floatingUi_dom.computePosition;
3133
+ exports.flip = floatingUi_dom.flip;
2985
3134
  exports.platform = floatingUi_dom.platform;
2986
- exports.getOverflowAncestors = floatingUi_utils_dom.getOverflowAncestors;
3135
+ exports.shift = floatingUi_dom.shift;
3136
+ exports.size = floatingUi_dom.size;
2987
3137
  exports.FloatingArrow = FloatingArrow;
2988
3138
  exports.FloatingFocusManager = FloatingFocusManager;
2989
3139
  exports.FloatingPortal = FloatingPortal;