@fluentui/react-positioning 9.23.1 → 9.23.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,12 +1,24 @@
1
1
  # Change Log - @fluentui/react-positioning
2
2
 
3
- <!-- This log was last generated on Tue, 11 Aug 2026 17:16:02 GMT and should not be manually modified. -->
3
+ <!-- This log was last generated on Mon, 21 Sep 2026 16:12:52 GMT and should not be manually modified. -->
4
4
 
5
5
  <!-- Start content -->
6
6
 
7
+ ## [9.23.2](https://github.com/microsoft/fluentui/tree/@fluentui/react-positioning_v9.23.2)
8
+
9
+ Mon, 21 Sep 2026 16:12:52 GMT
10
+ [Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-positioning_v9.23.1..@fluentui/react-positioning_v9.23.2)
11
+
12
+ ### Patches
13
+
14
+ - fix: remove unused react-dom and @types/react-dom peer dependencies, mark @types/react as optional, require use-sync-external-store ^1.4.0 for react 19 support ([PR #36559](https://github.com/microsoft/fluentui/pull/36559) by martinhochel@microsoft.com)
15
+ - Treat unavailable positioning geometry as indeterminate when reporting visibility flags. ([PR #36758](https://github.com/microsoft/fluentui/pull/36758) by bernardo.sunderhus@gmail.com)
16
+ - Bump @fluentui/react-shared-contexts to v9.26.4 ([commit](https://github.com/microsoft/fluentui/commit/undefined) by beachball)
17
+ - Bump @fluentui/react-utilities to v9.26.7 ([commit](https://github.com/microsoft/fluentui/commit/undefined) by beachball)
18
+
7
19
  ## [9.23.1](https://github.com/microsoft/fluentui/tree/@fluentui/react-positioning_v9.23.1)
8
20
 
9
- Tue, 11 Aug 2026 17:16:02 GMT
21
+ Tue, 11 Aug 2026 17:20:14 GMT
10
22
  [Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-positioning_v9.23.0..@fluentui/react-positioning_v9.23.1)
11
23
 
12
24
  ### Patches
@@ -4,6 +4,10 @@ import { debounce, writeArrowUpdates, writeContainerUpdates } from "./utils/inde
4
4
  import { listScrollParents } from "./utils/listScrollParents.js";
5
5
  import { POSITIONING_END_EVENT } from "./constants.js";
6
6
  import { createResizeObserver } from "./utils/createResizeObserver.js";
7
+ function isLayoutViewportUnavailable(container) {
8
+ const { clientWidth, clientHeight } = container.ownerDocument.documentElement;
9
+ return clientWidth === 0 && clientHeight === 0;
10
+ }
7
11
  /**
8
12
  * @internal
9
13
  * @returns manager that handles positioning out of the react lifecycle
@@ -68,19 +72,27 @@ import { createResizeObserver } from "./utils/createResizeObserver.js";
68
72
  middleware,
69
73
  strategy
70
74
  }).then(({ x, y, middlewareData, placement: computedPlacement })=>{
71
- var _middlewareData_hide, _middlewareData_hide1;
75
+ var _positioningMiddlewareData_hide, _positioningMiddlewareData_hide1;
72
76
  // Promise can still resolve after destruction
73
77
  // early return to avoid applying outdated position
74
78
  if (isDestroyed) {
75
79
  return;
76
80
  }
81
+ const positioningMiddlewareData = isLayoutViewportUnavailable(container) ? {
82
+ ...middlewareData,
83
+ hide: {
84
+ ...middlewareData.hide,
85
+ escaped: false,
86
+ referenceHidden: false
87
+ }
88
+ } : middlewareData;
77
89
  writeArrowUpdates({
78
90
  arrow,
79
- middlewareData
91
+ middlewareData: positioningMiddlewareData
80
92
  });
81
93
  writeContainerUpdates({
82
94
  container,
83
- middlewareData,
95
+ middlewareData: positioningMiddlewareData,
84
96
  placement: computedPlacement,
85
97
  coordinates: {
86
98
  x,
@@ -90,15 +102,15 @@ import { createResizeObserver } from "./utils/createResizeObserver.js";
90
102
  strategy,
91
103
  useTransform
92
104
  });
93
- var _middlewareData_hide_escaped, _middlewareData_hide_referenceHidden;
105
+ var _positioningMiddlewareData_hide_escaped, _positioningMiddlewareData_hide_referenceHidden;
94
106
  container.dispatchEvent(new CustomEvent(POSITIONING_END_EVENT, {
95
107
  detail: {
96
108
  // Cast from Floating UI's Placement to the Fluent-owned PositioningPlacement.
97
109
  // These are equivalent string unions; the cast avoids leaking @floating-ui/dom
98
110
  // types into the public API surface.
99
111
  placement: computedPlacement,
100
- escaped: (_middlewareData_hide_escaped = (_middlewareData_hide = middlewareData.hide) === null || _middlewareData_hide === void 0 ? void 0 : _middlewareData_hide.escaped) !== null && _middlewareData_hide_escaped !== void 0 ? _middlewareData_hide_escaped : false,
101
- referenceHidden: (_middlewareData_hide_referenceHidden = (_middlewareData_hide1 = middlewareData.hide) === null || _middlewareData_hide1 === void 0 ? void 0 : _middlewareData_hide1.referenceHidden) !== null && _middlewareData_hide_referenceHidden !== void 0 ? _middlewareData_hide_referenceHidden : false
112
+ escaped: (_positioningMiddlewareData_hide_escaped = (_positioningMiddlewareData_hide = positioningMiddlewareData.hide) === null || _positioningMiddlewareData_hide === void 0 ? void 0 : _positioningMiddlewareData_hide.escaped) !== null && _positioningMiddlewareData_hide_escaped !== void 0 ? _positioningMiddlewareData_hide_escaped : false,
113
+ referenceHidden: (_positioningMiddlewareData_hide_referenceHidden = (_positioningMiddlewareData_hide1 = positioningMiddlewareData.hide) === null || _positioningMiddlewareData_hide1 === void 0 ? void 0 : _positioningMiddlewareData_hide1.referenceHidden) !== null && _positioningMiddlewareData_hide_referenceHidden !== void 0 ? _positioningMiddlewareData_hide_referenceHidden : false
102
114
  }
103
115
  }));
104
116
  }).catch((err)=>{
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/createPositionManager.ts"],"sourcesContent":["import { computePosition } from '@floating-ui/dom';\nimport type { Middleware, Placement, Strategy } from '@floating-ui/dom';\nimport { isHTMLElement } from '@fluentui/react-utilities';\nimport type { OnPositioningEndEventDetail, PositionManager, PositioningPlacement, TargetElement } from './types';\nimport { debounce, writeArrowUpdates, writeContainerUpdates } from './utils';\nimport { listScrollParents } from './utils/listScrollParents';\nimport { POSITIONING_END_EVENT } from './constants';\nimport { createResizeObserver } from './utils/createResizeObserver';\n\ninterface PositionManagerOptions {\n /**\n * The positioned element\n */\n container: HTMLElement;\n /**\n * Element that the container will be anchored to\n */\n target: TargetElement;\n /**\n * Arrow that points from the container to the target\n */\n arrow: HTMLElement | null;\n /**\n * The value of the css `position` property\n * @default absolute\n */\n strategy: Strategy;\n /**\n * [Floating UI middleware](https://floating-ui.com/docs/middleware)\n */\n middleware: Middleware[];\n /**\n * [Floating UI placement](https://floating-ui.com/docs/computePosition#placement)\n */\n placement?: Placement;\n /**\n * Modifies whether popover is positioned using transform.\n * @default true\n */\n useTransform?: boolean;\n /**\n * Disables the resize observer that updates position on target or dimension change\n */\n disableUpdateOnResize?: boolean;\n}\n\n/**\n * @internal\n * @returns manager that handles positioning out of the react lifecycle\n */\nexport function createPositionManager(options: PositionManagerOptions): PositionManager {\n let isDestroyed = false;\n const {\n container,\n target,\n arrow,\n strategy,\n middleware,\n placement,\n useTransform = true,\n disableUpdateOnResize = false,\n } = options;\n const targetWindow = container.ownerDocument.defaultView;\n if (!target || !container || !targetWindow) {\n return {\n updatePosition: () => undefined,\n dispose: () => undefined,\n };\n }\n\n // When the dimensions of the target or the container change - trigger a position update\n const resizeObserver = disableUpdateOnResize\n ? null\n : createResizeObserver(targetWindow, entries => {\n // If content rect dimensions to go 0 -> very likely that `display: none` is being used to hide the element\n // In this case don't update and let users update imperatively\n const shouldUpdateOnResize = entries.every(entry => {\n return entry.contentRect.width > 0 && entry.contentRect.height > 0;\n });\n\n if (shouldUpdateOnResize) {\n updatePosition();\n }\n });\n\n let isFirstUpdate = true;\n const scrollParents: Set<HTMLElement> = new Set<HTMLElement>();\n\n // When the container is first resolved, set position `fixed` to avoid scroll jumps.\n // Without this scroll jumps can occur when the element is rendered initially and receives focus\n Object.assign(container.style, { position: 'fixed', left: 0, top: 0, margin: 0 });\n\n const forceUpdate = () => {\n // debounced update can still occur afterwards\n // early return to avoid memory leaks\n if (isDestroyed) {\n return;\n }\n\n if (isFirstUpdate) {\n listScrollParents(container).forEach(scrollParent => scrollParents.add(scrollParent));\n if (isHTMLElement(target)) {\n listScrollParents(target).forEach(scrollParent => scrollParents.add(scrollParent));\n }\n\n scrollParents.forEach(scrollParent => {\n scrollParent.addEventListener('scroll', updatePosition, { passive: true });\n });\n\n resizeObserver?.observe(container);\n if (isHTMLElement(target)) {\n resizeObserver?.observe(target);\n }\n\n isFirstUpdate = false;\n }\n\n Object.assign(container.style, { position: strategy });\n computePosition(target, container, { placement, middleware, strategy })\n .then(({ x, y, middlewareData, placement: computedPlacement }) => {\n // Promise can still resolve after destruction\n // early return to avoid applying outdated position\n if (isDestroyed) {\n return;\n }\n\n writeArrowUpdates({ arrow, middlewareData });\n writeContainerUpdates({\n container,\n middlewareData,\n placement: computedPlacement,\n coordinates: { x, y },\n lowPPI: (targetWindow?.devicePixelRatio || 1) <= 1,\n strategy,\n useTransform,\n });\n\n container.dispatchEvent(\n new CustomEvent<OnPositioningEndEventDetail>(POSITIONING_END_EVENT, {\n detail: {\n // Cast from Floating UI's Placement to the Fluent-owned PositioningPlacement.\n // These are equivalent string unions; the cast avoids leaking @floating-ui/dom\n // types into the public API surface.\n placement: computedPlacement satisfies PositioningPlacement,\n escaped: middlewareData.hide?.escaped ?? false,\n referenceHidden: middlewareData.hide?.referenceHidden ?? false,\n },\n }),\n );\n })\n .catch(err => {\n // https://github.com/floating-ui/floating-ui/issues/1845\n // FIXME for node > 14\n // node 15 introduces promise rejection which means that any components\n // tests need to be `it('', async () => {})` otherwise there can be race conditions with\n // JSDOM being torn down before this promise is resolved so globals like `window` and `document` don't exist\n // Unless all tests that ever use `usePositioning` are turned into async tests, any logging during testing\n // will actually be counter productive\n if (process.env.NODE_ENV === 'development') {\n // eslint-disable-next-line no-console\n console.error('[usePositioning]: Failed to calculate position', err);\n }\n });\n };\n\n const updatePosition = debounce(() => forceUpdate());\n\n const dispose = () => {\n isDestroyed = true;\n\n if (targetWindow) {\n targetWindow.removeEventListener('scroll', updatePosition);\n targetWindow.removeEventListener('resize', updatePosition);\n }\n\n scrollParents.forEach(scrollParent => {\n scrollParent.removeEventListener('scroll', updatePosition);\n });\n scrollParents.clear();\n\n resizeObserver?.disconnect();\n };\n\n if (targetWindow) {\n targetWindow.addEventListener('scroll', updatePosition, { passive: true });\n targetWindow.addEventListener('resize', updatePosition);\n }\n\n // Update the position on initialization\n updatePosition();\n\n return {\n updatePosition,\n dispose,\n };\n}\n"],"names":["computePosition","isHTMLElement","debounce","writeArrowUpdates","writeContainerUpdates","listScrollParents","POSITIONING_END_EVENT","createResizeObserver","createPositionManager","options","isDestroyed","container","target","arrow","strategy","middleware","placement","useTransform","disableUpdateOnResize","targetWindow","ownerDocument","defaultView","updatePosition","undefined","dispose","resizeObserver","entries","shouldUpdateOnResize","every","entry","contentRect","width","height","isFirstUpdate","scrollParents","Set","Object","assign","style","position","left","top","margin","forceUpdate","forEach","scrollParent","add","addEventListener","passive","observe","then","x","y","middlewareData","computedPlacement","coordinates","lowPPI","devicePixelRatio","dispatchEvent","CustomEvent","detail","escaped","hide","referenceHidden","catch","err","process","env","NODE_ENV","console","error","removeEventListener","clear","disconnect"],"mappings":"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"}
1
+ {"version":3,"sources":["../src/createPositionManager.ts"],"sourcesContent":["import { computePosition } from '@floating-ui/dom';\nimport type { Middleware, Placement, Strategy } from '@floating-ui/dom';\nimport { isHTMLElement } from '@fluentui/react-utilities';\nimport type { OnPositioningEndEventDetail, PositionManager, PositioningPlacement, TargetElement } from './types';\nimport { debounce, writeArrowUpdates, writeContainerUpdates } from './utils';\nimport { listScrollParents } from './utils/listScrollParents';\nimport { POSITIONING_END_EVENT } from './constants';\nimport { createResizeObserver } from './utils/createResizeObserver';\n\ninterface PositionManagerOptions {\n /**\n * The positioned element\n */\n container: HTMLElement;\n /**\n * Element that the container will be anchored to\n */\n target: TargetElement;\n /**\n * Arrow that points from the container to the target\n */\n arrow: HTMLElement | null;\n /**\n * The value of the css `position` property\n * @default absolute\n */\n strategy: Strategy;\n /**\n * [Floating UI middleware](https://floating-ui.com/docs/middleware)\n */\n middleware: Middleware[];\n /**\n * [Floating UI placement](https://floating-ui.com/docs/computePosition#placement)\n */\n placement?: Placement;\n /**\n * Modifies whether popover is positioned using transform.\n * @default true\n */\n useTransform?: boolean;\n /**\n * Disables the resize observer that updates position on target or dimension change\n */\n disableUpdateOnResize?: boolean;\n}\n\nfunction isLayoutViewportUnavailable(container: HTMLElement): boolean {\n const { clientWidth, clientHeight } = container.ownerDocument.documentElement;\n\n return clientWidth === 0 && clientHeight === 0;\n}\n\n/**\n * @internal\n * @returns manager that handles positioning out of the react lifecycle\n */\nexport function createPositionManager(options: PositionManagerOptions): PositionManager {\n let isDestroyed = false;\n const {\n container,\n target,\n arrow,\n strategy,\n middleware,\n placement,\n useTransform = true,\n disableUpdateOnResize = false,\n } = options;\n const targetWindow = container.ownerDocument.defaultView;\n if (!target || !container || !targetWindow) {\n return {\n updatePosition: () => undefined,\n dispose: () => undefined,\n };\n }\n\n // When the dimensions of the target or the container change - trigger a position update\n const resizeObserver = disableUpdateOnResize\n ? null\n : createResizeObserver(targetWindow, entries => {\n // If content rect dimensions to go 0 -> very likely that `display: none` is being used to hide the element\n // In this case don't update and let users update imperatively\n const shouldUpdateOnResize = entries.every(entry => {\n return entry.contentRect.width > 0 && entry.contentRect.height > 0;\n });\n\n if (shouldUpdateOnResize) {\n updatePosition();\n }\n });\n\n let isFirstUpdate = true;\n const scrollParents: Set<HTMLElement> = new Set<HTMLElement>();\n\n // When the container is first resolved, set position `fixed` to avoid scroll jumps.\n // Without this scroll jumps can occur when the element is rendered initially and receives focus\n Object.assign(container.style, { position: 'fixed', left: 0, top: 0, margin: 0 });\n\n const forceUpdate = () => {\n // debounced update can still occur afterwards\n // early return to avoid memory leaks\n if (isDestroyed) {\n return;\n }\n\n if (isFirstUpdate) {\n listScrollParents(container).forEach(scrollParent => scrollParents.add(scrollParent));\n if (isHTMLElement(target)) {\n listScrollParents(target).forEach(scrollParent => scrollParents.add(scrollParent));\n }\n\n scrollParents.forEach(scrollParent => {\n scrollParent.addEventListener('scroll', updatePosition, { passive: true });\n });\n\n resizeObserver?.observe(container);\n if (isHTMLElement(target)) {\n resizeObserver?.observe(target);\n }\n\n isFirstUpdate = false;\n }\n\n Object.assign(container.style, { position: strategy });\n computePosition(target, container, { placement, middleware, strategy })\n .then(({ x, y, middlewareData, placement: computedPlacement }) => {\n // Promise can still resolve after destruction\n // early return to avoid applying outdated position\n if (isDestroyed) {\n return;\n }\n\n const positioningMiddlewareData = isLayoutViewportUnavailable(container)\n ? {\n ...middlewareData,\n hide: { ...middlewareData.hide, escaped: false, referenceHidden: false },\n }\n : middlewareData;\n\n writeArrowUpdates({ arrow, middlewareData: positioningMiddlewareData });\n writeContainerUpdates({\n container,\n middlewareData: positioningMiddlewareData,\n placement: computedPlacement,\n coordinates: { x, y },\n lowPPI: (targetWindow?.devicePixelRatio || 1) <= 1,\n strategy,\n useTransform,\n });\n\n container.dispatchEvent(\n new CustomEvent<OnPositioningEndEventDetail>(POSITIONING_END_EVENT, {\n detail: {\n // Cast from Floating UI's Placement to the Fluent-owned PositioningPlacement.\n // These are equivalent string unions; the cast avoids leaking @floating-ui/dom\n // types into the public API surface.\n placement: computedPlacement satisfies PositioningPlacement,\n escaped: positioningMiddlewareData.hide?.escaped ?? false,\n referenceHidden: positioningMiddlewareData.hide?.referenceHidden ?? false,\n },\n }),\n );\n })\n .catch(err => {\n // https://github.com/floating-ui/floating-ui/issues/1845\n // FIXME for node > 14\n // node 15 introduces promise rejection which means that any components\n // tests need to be `it('', async () => {})` otherwise there can be race conditions with\n // JSDOM being torn down before this promise is resolved so globals like `window` and `document` don't exist\n // Unless all tests that ever use `usePositioning` are turned into async tests, any logging during testing\n // will actually be counter productive\n if (process.env.NODE_ENV === 'development') {\n // eslint-disable-next-line no-console\n console.error('[usePositioning]: Failed to calculate position', err);\n }\n });\n };\n\n const updatePosition = debounce(() => forceUpdate());\n\n const dispose = () => {\n isDestroyed = true;\n\n if (targetWindow) {\n targetWindow.removeEventListener('scroll', updatePosition);\n targetWindow.removeEventListener('resize', updatePosition);\n }\n\n scrollParents.forEach(scrollParent => {\n scrollParent.removeEventListener('scroll', updatePosition);\n });\n scrollParents.clear();\n\n resizeObserver?.disconnect();\n };\n\n if (targetWindow) {\n targetWindow.addEventListener('scroll', updatePosition, { passive: true });\n targetWindow.addEventListener('resize', updatePosition);\n }\n\n // Update the position on initialization\n updatePosition();\n\n return {\n updatePosition,\n dispose,\n };\n}\n"],"names":["computePosition","isHTMLElement","debounce","writeArrowUpdates","writeContainerUpdates","listScrollParents","POSITIONING_END_EVENT","createResizeObserver","isLayoutViewportUnavailable","container","clientWidth","clientHeight","ownerDocument","documentElement","createPositionManager","options","isDestroyed","target","arrow","strategy","middleware","placement","useTransform","disableUpdateOnResize","targetWindow","defaultView","updatePosition","undefined","dispose","resizeObserver","entries","shouldUpdateOnResize","every","entry","contentRect","width","height","isFirstUpdate","scrollParents","Set","Object","assign","style","position","left","top","margin","forceUpdate","forEach","scrollParent","add","addEventListener","passive","observe","then","x","y","middlewareData","computedPlacement","positioningMiddlewareData","hide","escaped","referenceHidden","coordinates","lowPPI","devicePixelRatio","dispatchEvent","CustomEvent","detail","catch","err","process","env","NODE_ENV","console","error","removeEventListener","clear","disconnect"],"mappings":"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"}
@@ -14,6 +14,10 @@ const _index = require("./utils/index.cjs");
14
14
  const _listScrollParents = require("./utils/listScrollParents.cjs");
15
15
  const _constants = require("./constants.cjs");
16
16
  const _createResizeObserver = require("./utils/createResizeObserver.cjs");
17
+ function isLayoutViewportUnavailable(container) {
18
+ const { clientWidth, clientHeight } = container.ownerDocument.documentElement;
19
+ return clientWidth === 0 && clientHeight === 0;
20
+ }
17
21
  function createPositionManager(options) {
18
22
  let isDestroyed = false;
19
23
  const { container, target, arrow, strategy, middleware, placement, useTransform = true, disableUpdateOnResize = false } = options;
@@ -75,19 +79,27 @@ function createPositionManager(options) {
75
79
  middleware,
76
80
  strategy
77
81
  }).then(({ x, y, middlewareData, placement: computedPlacement })=>{
78
- var _middlewareData_hide, _middlewareData_hide1;
82
+ var _positioningMiddlewareData_hide, _positioningMiddlewareData_hide1;
79
83
  // Promise can still resolve after destruction
80
84
  // early return to avoid applying outdated position
81
85
  if (isDestroyed) {
82
86
  return;
83
87
  }
88
+ const positioningMiddlewareData = isLayoutViewportUnavailable(container) ? {
89
+ ...middlewareData,
90
+ hide: {
91
+ ...middlewareData.hide,
92
+ escaped: false,
93
+ referenceHidden: false
94
+ }
95
+ } : middlewareData;
84
96
  (0, _index.writeArrowUpdates)({
85
97
  arrow,
86
- middlewareData
98
+ middlewareData: positioningMiddlewareData
87
99
  });
88
100
  (0, _index.writeContainerUpdates)({
89
101
  container,
90
- middlewareData,
102
+ middlewareData: positioningMiddlewareData,
91
103
  placement: computedPlacement,
92
104
  coordinates: {
93
105
  x,
@@ -97,15 +109,15 @@ function createPositionManager(options) {
97
109
  strategy,
98
110
  useTransform
99
111
  });
100
- var _middlewareData_hide_escaped, _middlewareData_hide_referenceHidden;
112
+ var _positioningMiddlewareData_hide_escaped, _positioningMiddlewareData_hide_referenceHidden;
101
113
  container.dispatchEvent(new CustomEvent(_constants.POSITIONING_END_EVENT, {
102
114
  detail: {
103
115
  // Cast from Floating UI's Placement to the Fluent-owned PositioningPlacement.
104
116
  // These are equivalent string unions; the cast avoids leaking @floating-ui/dom
105
117
  // types into the public API surface.
106
118
  placement: computedPlacement,
107
- escaped: (_middlewareData_hide_escaped = (_middlewareData_hide = middlewareData.hide) === null || _middlewareData_hide === void 0 ? void 0 : _middlewareData_hide.escaped) !== null && _middlewareData_hide_escaped !== void 0 ? _middlewareData_hide_escaped : false,
108
- referenceHidden: (_middlewareData_hide_referenceHidden = (_middlewareData_hide1 = middlewareData.hide) === null || _middlewareData_hide1 === void 0 ? void 0 : _middlewareData_hide1.referenceHidden) !== null && _middlewareData_hide_referenceHidden !== void 0 ? _middlewareData_hide_referenceHidden : false
119
+ escaped: (_positioningMiddlewareData_hide_escaped = (_positioningMiddlewareData_hide = positioningMiddlewareData.hide) === null || _positioningMiddlewareData_hide === void 0 ? void 0 : _positioningMiddlewareData_hide.escaped) !== null && _positioningMiddlewareData_hide_escaped !== void 0 ? _positioningMiddlewareData_hide_escaped : false,
120
+ referenceHidden: (_positioningMiddlewareData_hide_referenceHidden = (_positioningMiddlewareData_hide1 = positioningMiddlewareData.hide) === null || _positioningMiddlewareData_hide1 === void 0 ? void 0 : _positioningMiddlewareData_hide1.referenceHidden) !== null && _positioningMiddlewareData_hide_referenceHidden !== void 0 ? _positioningMiddlewareData_hide_referenceHidden : false
109
121
  }
110
122
  }));
111
123
  }).catch((err)=>{
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/createPositionManager.ts"],"sourcesContent":["import { computePosition } from '@floating-ui/dom';\nimport type { Middleware, Placement, Strategy } from '@floating-ui/dom';\nimport { isHTMLElement } from '@fluentui/react-utilities';\nimport type { OnPositioningEndEventDetail, PositionManager, PositioningPlacement, TargetElement } from './types';\nimport { debounce, writeArrowUpdates, writeContainerUpdates } from './utils';\nimport { listScrollParents } from './utils/listScrollParents';\nimport { POSITIONING_END_EVENT } from './constants';\nimport { createResizeObserver } from './utils/createResizeObserver';\n\ninterface PositionManagerOptions {\n /**\n * The positioned element\n */\n container: HTMLElement;\n /**\n * Element that the container will be anchored to\n */\n target: TargetElement;\n /**\n * Arrow that points from the container to the target\n */\n arrow: HTMLElement | null;\n /**\n * The value of the css `position` property\n * @default absolute\n */\n strategy: Strategy;\n /**\n * [Floating UI middleware](https://floating-ui.com/docs/middleware)\n */\n middleware: Middleware[];\n /**\n * [Floating UI placement](https://floating-ui.com/docs/computePosition#placement)\n */\n placement?: Placement;\n /**\n * Modifies whether popover is positioned using transform.\n * @default true\n */\n useTransform?: boolean;\n /**\n * Disables the resize observer that updates position on target or dimension change\n */\n disableUpdateOnResize?: boolean;\n}\n\n/**\n * @internal\n * @returns manager that handles positioning out of the react lifecycle\n */\nexport function createPositionManager(options: PositionManagerOptions): PositionManager {\n let isDestroyed = false;\n const {\n container,\n target,\n arrow,\n strategy,\n middleware,\n placement,\n useTransform = true,\n disableUpdateOnResize = false,\n } = options;\n const targetWindow = container.ownerDocument.defaultView;\n if (!target || !container || !targetWindow) {\n return {\n updatePosition: () => undefined,\n dispose: () => undefined,\n };\n }\n\n // When the dimensions of the target or the container change - trigger a position update\n const resizeObserver = disableUpdateOnResize\n ? null\n : createResizeObserver(targetWindow, entries => {\n // If content rect dimensions to go 0 -> very likely that `display: none` is being used to hide the element\n // In this case don't update and let users update imperatively\n const shouldUpdateOnResize = entries.every(entry => {\n return entry.contentRect.width > 0 && entry.contentRect.height > 0;\n });\n\n if (shouldUpdateOnResize) {\n updatePosition();\n }\n });\n\n let isFirstUpdate = true;\n const scrollParents: Set<HTMLElement> = new Set<HTMLElement>();\n\n // When the container is first resolved, set position `fixed` to avoid scroll jumps.\n // Without this scroll jumps can occur when the element is rendered initially and receives focus\n Object.assign(container.style, { position: 'fixed', left: 0, top: 0, margin: 0 });\n\n const forceUpdate = () => {\n // debounced update can still occur afterwards\n // early return to avoid memory leaks\n if (isDestroyed) {\n return;\n }\n\n if (isFirstUpdate) {\n listScrollParents(container).forEach(scrollParent => scrollParents.add(scrollParent));\n if (isHTMLElement(target)) {\n listScrollParents(target).forEach(scrollParent => scrollParents.add(scrollParent));\n }\n\n scrollParents.forEach(scrollParent => {\n scrollParent.addEventListener('scroll', updatePosition, { passive: true });\n });\n\n resizeObserver?.observe(container);\n if (isHTMLElement(target)) {\n resizeObserver?.observe(target);\n }\n\n isFirstUpdate = false;\n }\n\n Object.assign(container.style, { position: strategy });\n computePosition(target, container, { placement, middleware, strategy })\n .then(({ x, y, middlewareData, placement: computedPlacement }) => {\n // Promise can still resolve after destruction\n // early return to avoid applying outdated position\n if (isDestroyed) {\n return;\n }\n\n writeArrowUpdates({ arrow, middlewareData });\n writeContainerUpdates({\n container,\n middlewareData,\n placement: computedPlacement,\n coordinates: { x, y },\n lowPPI: (targetWindow?.devicePixelRatio || 1) <= 1,\n strategy,\n useTransform,\n });\n\n container.dispatchEvent(\n new CustomEvent<OnPositioningEndEventDetail>(POSITIONING_END_EVENT, {\n detail: {\n // Cast from Floating UI's Placement to the Fluent-owned PositioningPlacement.\n // These are equivalent string unions; the cast avoids leaking @floating-ui/dom\n // types into the public API surface.\n placement: computedPlacement satisfies PositioningPlacement,\n escaped: middlewareData.hide?.escaped ?? false,\n referenceHidden: middlewareData.hide?.referenceHidden ?? false,\n },\n }),\n );\n })\n .catch(err => {\n // https://github.com/floating-ui/floating-ui/issues/1845\n // FIXME for node > 14\n // node 15 introduces promise rejection which means that any components\n // tests need to be `it('', async () => {})` otherwise there can be race conditions with\n // JSDOM being torn down before this promise is resolved so globals like `window` and `document` don't exist\n // Unless all tests that ever use `usePositioning` are turned into async tests, any logging during testing\n // will actually be counter productive\n if (process.env.NODE_ENV === 'development') {\n // eslint-disable-next-line no-console\n console.error('[usePositioning]: Failed to calculate position', err);\n }\n });\n };\n\n const updatePosition = debounce(() => forceUpdate());\n\n const dispose = () => {\n isDestroyed = true;\n\n if (targetWindow) {\n targetWindow.removeEventListener('scroll', updatePosition);\n targetWindow.removeEventListener('resize', updatePosition);\n }\n\n scrollParents.forEach(scrollParent => {\n scrollParent.removeEventListener('scroll', updatePosition);\n });\n scrollParents.clear();\n\n resizeObserver?.disconnect();\n };\n\n if (targetWindow) {\n targetWindow.addEventListener('scroll', updatePosition, { passive: true });\n targetWindow.addEventListener('resize', updatePosition);\n }\n\n // Update the position on initialization\n updatePosition();\n\n return {\n updatePosition,\n dispose,\n };\n}\n"],"names":["computePosition","isHTMLElement","debounce","writeArrowUpdates","writeContainerUpdates","listScrollParents","POSITIONING_END_EVENT","createResizeObserver","createPositionManager","options","isDestroyed","container","target","arrow","strategy","middleware","placement","useTransform","disableUpdateOnResize","targetWindow","ownerDocument","defaultView","updatePosition","undefined","dispose","resizeObserver","entries","shouldUpdateOnResize","every","entry","contentRect","width","height","isFirstUpdate","scrollParents","Set","Object","assign","style","position","left","top","margin","forceUpdate","forEach","scrollParent","add","addEventListener","passive","observe","then","x","y","middlewareData","computedPlacement","coordinates","lowPPI","devicePixelRatio","dispatchEvent","CustomEvent","detail","escaped","hide","referenceHidden","catch","err","process","env","NODE_ENV","console","error","removeEventListener","clear","disconnect"],"mappings":"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"}
1
+ {"version":3,"sources":["../src/createPositionManager.ts"],"sourcesContent":["import { computePosition } from '@floating-ui/dom';\nimport type { Middleware, Placement, Strategy } from '@floating-ui/dom';\nimport { isHTMLElement } from '@fluentui/react-utilities';\nimport type { OnPositioningEndEventDetail, PositionManager, PositioningPlacement, TargetElement } from './types';\nimport { debounce, writeArrowUpdates, writeContainerUpdates } from './utils';\nimport { listScrollParents } from './utils/listScrollParents';\nimport { POSITIONING_END_EVENT } from './constants';\nimport { createResizeObserver } from './utils/createResizeObserver';\n\ninterface PositionManagerOptions {\n /**\n * The positioned element\n */\n container: HTMLElement;\n /**\n * Element that the container will be anchored to\n */\n target: TargetElement;\n /**\n * Arrow that points from the container to the target\n */\n arrow: HTMLElement | null;\n /**\n * The value of the css `position` property\n * @default absolute\n */\n strategy: Strategy;\n /**\n * [Floating UI middleware](https://floating-ui.com/docs/middleware)\n */\n middleware: Middleware[];\n /**\n * [Floating UI placement](https://floating-ui.com/docs/computePosition#placement)\n */\n placement?: Placement;\n /**\n * Modifies whether popover is positioned using transform.\n * @default true\n */\n useTransform?: boolean;\n /**\n * Disables the resize observer that updates position on target or dimension change\n */\n disableUpdateOnResize?: boolean;\n}\n\nfunction isLayoutViewportUnavailable(container: HTMLElement): boolean {\n const { clientWidth, clientHeight } = container.ownerDocument.documentElement;\n\n return clientWidth === 0 && clientHeight === 0;\n}\n\n/**\n * @internal\n * @returns manager that handles positioning out of the react lifecycle\n */\nexport function createPositionManager(options: PositionManagerOptions): PositionManager {\n let isDestroyed = false;\n const {\n container,\n target,\n arrow,\n strategy,\n middleware,\n placement,\n useTransform = true,\n disableUpdateOnResize = false,\n } = options;\n const targetWindow = container.ownerDocument.defaultView;\n if (!target || !container || !targetWindow) {\n return {\n updatePosition: () => undefined,\n dispose: () => undefined,\n };\n }\n\n // When the dimensions of the target or the container change - trigger a position update\n const resizeObserver = disableUpdateOnResize\n ? null\n : createResizeObserver(targetWindow, entries => {\n // If content rect dimensions to go 0 -> very likely that `display: none` is being used to hide the element\n // In this case don't update and let users update imperatively\n const shouldUpdateOnResize = entries.every(entry => {\n return entry.contentRect.width > 0 && entry.contentRect.height > 0;\n });\n\n if (shouldUpdateOnResize) {\n updatePosition();\n }\n });\n\n let isFirstUpdate = true;\n const scrollParents: Set<HTMLElement> = new Set<HTMLElement>();\n\n // When the container is first resolved, set position `fixed` to avoid scroll jumps.\n // Without this scroll jumps can occur when the element is rendered initially and receives focus\n Object.assign(container.style, { position: 'fixed', left: 0, top: 0, margin: 0 });\n\n const forceUpdate = () => {\n // debounced update can still occur afterwards\n // early return to avoid memory leaks\n if (isDestroyed) {\n return;\n }\n\n if (isFirstUpdate) {\n listScrollParents(container).forEach(scrollParent => scrollParents.add(scrollParent));\n if (isHTMLElement(target)) {\n listScrollParents(target).forEach(scrollParent => scrollParents.add(scrollParent));\n }\n\n scrollParents.forEach(scrollParent => {\n scrollParent.addEventListener('scroll', updatePosition, { passive: true });\n });\n\n resizeObserver?.observe(container);\n if (isHTMLElement(target)) {\n resizeObserver?.observe(target);\n }\n\n isFirstUpdate = false;\n }\n\n Object.assign(container.style, { position: strategy });\n computePosition(target, container, { placement, middleware, strategy })\n .then(({ x, y, middlewareData, placement: computedPlacement }) => {\n // Promise can still resolve after destruction\n // early return to avoid applying outdated position\n if (isDestroyed) {\n return;\n }\n\n const positioningMiddlewareData = isLayoutViewportUnavailable(container)\n ? {\n ...middlewareData,\n hide: { ...middlewareData.hide, escaped: false, referenceHidden: false },\n }\n : middlewareData;\n\n writeArrowUpdates({ arrow, middlewareData: positioningMiddlewareData });\n writeContainerUpdates({\n container,\n middlewareData: positioningMiddlewareData,\n placement: computedPlacement,\n coordinates: { x, y },\n lowPPI: (targetWindow?.devicePixelRatio || 1) <= 1,\n strategy,\n useTransform,\n });\n\n container.dispatchEvent(\n new CustomEvent<OnPositioningEndEventDetail>(POSITIONING_END_EVENT, {\n detail: {\n // Cast from Floating UI's Placement to the Fluent-owned PositioningPlacement.\n // These are equivalent string unions; the cast avoids leaking @floating-ui/dom\n // types into the public API surface.\n placement: computedPlacement satisfies PositioningPlacement,\n escaped: positioningMiddlewareData.hide?.escaped ?? false,\n referenceHidden: positioningMiddlewareData.hide?.referenceHidden ?? false,\n },\n }),\n );\n })\n .catch(err => {\n // https://github.com/floating-ui/floating-ui/issues/1845\n // FIXME for node > 14\n // node 15 introduces promise rejection which means that any components\n // tests need to be `it('', async () => {})` otherwise there can be race conditions with\n // JSDOM being torn down before this promise is resolved so globals like `window` and `document` don't exist\n // Unless all tests that ever use `usePositioning` are turned into async tests, any logging during testing\n // will actually be counter productive\n if (process.env.NODE_ENV === 'development') {\n // eslint-disable-next-line no-console\n console.error('[usePositioning]: Failed to calculate position', err);\n }\n });\n };\n\n const updatePosition = debounce(() => forceUpdate());\n\n const dispose = () => {\n isDestroyed = true;\n\n if (targetWindow) {\n targetWindow.removeEventListener('scroll', updatePosition);\n targetWindow.removeEventListener('resize', updatePosition);\n }\n\n scrollParents.forEach(scrollParent => {\n scrollParent.removeEventListener('scroll', updatePosition);\n });\n scrollParents.clear();\n\n resizeObserver?.disconnect();\n };\n\n if (targetWindow) {\n targetWindow.addEventListener('scroll', updatePosition, { passive: true });\n targetWindow.addEventListener('resize', updatePosition);\n }\n\n // Update the position on initialization\n updatePosition();\n\n return {\n updatePosition,\n dispose,\n };\n}\n"],"names":["computePosition","isHTMLElement","debounce","writeArrowUpdates","writeContainerUpdates","listScrollParents","POSITIONING_END_EVENT","createResizeObserver","isLayoutViewportUnavailable","container","clientWidth","clientHeight","ownerDocument","documentElement","createPositionManager","options","isDestroyed","target","arrow","strategy","middleware","placement","useTransform","disableUpdateOnResize","targetWindow","defaultView","updatePosition","undefined","dispose","resizeObserver","entries","shouldUpdateOnResize","every","entry","contentRect","width","height","isFirstUpdate","scrollParents","Set","Object","assign","style","position","left","top","margin","forceUpdate","forEach","scrollParent","add","addEventListener","passive","observe","then","x","y","middlewareData","computedPlacement","positioningMiddlewareData","hide","escaped","referenceHidden","coordinates","lowPPI","devicePixelRatio","dispatchEvent","CustomEvent","detail","catch","err","process","env","NODE_ENV","console","error","removeEventListener","clear","disconnect"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fluentui/react-positioning",
3
- "version": "9.23.1",
3
+ "version": "9.23.2",
4
4
  "description": "A react wrapper around Popper.js for Fluent UI",
5
5
  "main": "lib-commonjs/index.cjs",
6
6
  "module": "lib/index.js",
@@ -14,18 +14,21 @@
14
14
  "dependencies": {
15
15
  "@floating-ui/devtools": "^0.2.3",
16
16
  "@floating-ui/dom": "^1.6.12",
17
- "@fluentui/react-shared-contexts": "^9.26.3",
17
+ "@fluentui/react-shared-contexts": "^9.26.4",
18
18
  "@fluentui/react-theme": "^9.2.2",
19
- "@fluentui/react-utilities": "^9.26.6",
19
+ "@fluentui/react-utilities": "^9.26.7",
20
20
  "@griffel/react": "^1.5.32",
21
21
  "@swc/helpers": "^0.5.1",
22
- "use-sync-external-store": "^1.2.0"
22
+ "use-sync-external-store": "^1.4.0"
23
23
  },
24
24
  "peerDependencies": {
25
25
  "@types/react": ">=16.14.0 <20.0.0",
26
- "@types/react-dom": ">=16.9.0 <20.0.0",
27
- "react": ">=16.14.0 <20.0.0",
28
- "react-dom": ">=16.14.0 <20.0.0"
26
+ "react": ">=16.14.0 <20.0.0"
27
+ },
28
+ "peerDependenciesMeta": {
29
+ "@types/react": {
30
+ "optional": true
31
+ }
29
32
  },
30
33
  "beachball": {
31
34
  "disallowedChangeTypes": [