@fluentui/react-positioning 9.3.9 → 9.3.11

Sign up to get free protection for your applications and to get access to all the features.
package/CHANGELOG.json CHANGED
@@ -2,7 +2,37 @@
2
2
  "name": "@fluentui/react-positioning",
3
3
  "entries": [
4
4
  {
5
- "date": "Thu, 26 Jan 2023 13:27:53 GMT",
5
+ "date": "Tue, 07 Feb 2023 14:10:44 GMT",
6
+ "tag": "@fluentui/react-positioning_v9.3.11",
7
+ "version": "9.3.11",
8
+ "comments": {
9
+ "patch": [
10
+ {
11
+ "author": "lingfangao@hotmail.com",
12
+ "package": "@fluentui/react-positioning",
13
+ "commit": "db4be59f6c1677bd9182205dabfcb3e2bb47837f",
14
+ "comment": "fix(createPositionManager): computePosition should not apply styles after destruction"
15
+ }
16
+ ]
17
+ }
18
+ },
19
+ {
20
+ "date": "Tue, 31 Jan 2023 19:53:58 GMT",
21
+ "tag": "@fluentui/react-positioning_v9.3.10",
22
+ "version": "9.3.10",
23
+ "comments": {
24
+ "patch": [
25
+ {
26
+ "author": "beachball",
27
+ "package": "@fluentui/react-positioning",
28
+ "comment": "Bump @fluentui/react-utilities to v9.5.1",
29
+ "commit": "794d9e845cb952f597ba786e70cd8d248be62746"
30
+ }
31
+ ]
32
+ }
33
+ },
34
+ {
35
+ "date": "Thu, 26 Jan 2023 13:31:03 GMT",
6
36
  "tag": "@fluentui/react-positioning_v9.3.9",
7
37
  "version": "9.3.9",
8
38
  "comments": {
package/CHANGELOG.md CHANGED
@@ -1,12 +1,30 @@
1
1
  # Change Log - @fluentui/react-positioning
2
2
 
3
- This log was last generated on Thu, 26 Jan 2023 13:27:53 GMT and should not be manually modified.
3
+ This log was last generated on Tue, 07 Feb 2023 14:10:44 GMT and should not be manually modified.
4
4
 
5
5
  <!-- Start content -->
6
6
 
7
+ ## [9.3.11](https://github.com/microsoft/fluentui/tree/@fluentui/react-positioning_v9.3.11)
8
+
9
+ Tue, 07 Feb 2023 14:10:44 GMT
10
+ [Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-positioning_v9.3.10..@fluentui/react-positioning_v9.3.11)
11
+
12
+ ### Patches
13
+
14
+ - fix(createPositionManager): computePosition should not apply styles after destruction ([PR #26593](https://github.com/microsoft/fluentui/pull/26593) by lingfangao@hotmail.com)
15
+
16
+ ## [9.3.10](https://github.com/microsoft/fluentui/tree/@fluentui/react-positioning_v9.3.10)
17
+
18
+ Tue, 31 Jan 2023 19:53:58 GMT
19
+ [Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-positioning_v9.3.9..@fluentui/react-positioning_v9.3.10)
20
+
21
+ ### Patches
22
+
23
+ - Bump @fluentui/react-utilities to v9.5.1 ([PR #26557](https://github.com/microsoft/fluentui/pull/26557) by beachball)
24
+
7
25
  ## [9.3.9](https://github.com/microsoft/fluentui/tree/@fluentui/react-positioning_v9.3.9)
8
26
 
9
- Thu, 26 Jan 2023 13:27:53 GMT
27
+ Thu, 26 Jan 2023 13:31:03 GMT
10
28
  [Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-positioning_v9.3.8..@fluentui/react-positioning_v9.3.9)
11
29
 
12
30
  ### Patches
@@ -13,6 +13,7 @@ export function createPositionManager(options) {
13
13
  middleware,
14
14
  placement
15
15
  } = options;
16
+ let isDestroyed = false;
16
17
  if (!target || !container) {
17
18
  return {
18
19
  updatePosition: () => undefined,
@@ -30,7 +31,12 @@ export function createPositionManager(options) {
30
31
  top: 0,
31
32
  margin: 0
32
33
  });
33
- let forceUpdate = () => {
34
+ const forceUpdate = () => {
35
+ // debounced update can still occur afterwards
36
+ // early return to avoid memory leaks
37
+ if (isDestroyed) {
38
+ return;
39
+ }
34
40
  if (isFirstUpdate) {
35
41
  scrollParents.add(getScrollParent(container));
36
42
  if (target instanceof HTMLElement) {
@@ -54,6 +60,11 @@ export function createPositionManager(options) {
54
60
  middlewareData,
55
61
  placement: computedPlacement
56
62
  }) => {
63
+ // Promise can still resolve after destruction
64
+ // early return to avoid applying outdated position
65
+ if (isDestroyed) {
66
+ return;
67
+ }
57
68
  writeArrowUpdates({
58
69
  arrow,
59
70
  middlewareData
@@ -85,9 +96,7 @@ export function createPositionManager(options) {
85
96
  };
86
97
  const updatePosition = debounce(() => forceUpdate());
87
98
  const dispose = () => {
88
- // debounced update can still occur afterwards
89
- // so destroy the reference to forceUpdate
90
- forceUpdate = () => null;
99
+ isDestroyed = true;
91
100
  if (targetWindow) {
92
101
  targetWindow.removeEventListener('scroll', updatePosition);
93
102
  targetWindow.removeEventListener('resize', updatePosition);
@@ -1 +1 @@
1
- {"version":3,"mappings":"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","names":["computePosition","debounce","writeArrowUpdates","writeContainerUpdates","getScrollParent","createPositionManager","options","container","target","arrow","strategy","middleware","placement","updatePosition","undefined","dispose","isFirstUpdate","scrollParents","Set","targetWindow","ownerDocument","defaultView","Object","assign","style","position","left","top","margin","forceUpdate","add","HTMLElement","forEach","scrollParent","addEventListener","then","x","y","middlewareData","computedPlacement","coordinates","lowPPI","devicePixelRatio","catch","err","process","env","NODE_ENV","console","error","removeEventListener"],"sourceRoot":"../src/","sources":["packages/react-components/react-positioning/src/createPositionManager.ts"],"sourcesContent":["import { computePosition } from '@floating-ui/dom';\nimport type { Middleware, Placement, Strategy } from '@floating-ui/dom';\nimport type { PositionManager, TargetElement } from './types';\nimport { debounce, writeArrowUpdates, writeContainerUpdates, getScrollParent } from './utils';\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\n/**\n * @internal\n * @returns manager that handles positioning out of the react lifecycle\n */\nexport function createPositionManager(options: PositionManagerOptions): PositionManager {\n const { container, target, arrow, strategy, middleware, placement } = options;\n if (!target || !container) {\n return {\n updatePosition: () => undefined,\n dispose: () => undefined,\n };\n }\n\n let isFirstUpdate = true;\n const scrollParents: Set<HTMLElement> = new Set<HTMLElement>();\n const targetWindow = container.ownerDocument.defaultView;\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 let forceUpdate = () => {\n if (isFirstUpdate) {\n scrollParents.add(getScrollParent(container));\n if (target instanceof HTMLElement) {\n scrollParents.add(getScrollParent(target));\n }\n\n scrollParents.forEach(scrollParent => {\n scrollParent.addEventListener('scroll', updatePosition);\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 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 });\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 // debounced update can still occur afterwards\n // so destroy the reference to forceUpdate\n forceUpdate = () => null;\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 };\n\n if (targetWindow) {\n targetWindow.addEventListener('scroll', updatePosition);\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"]}
1
+ {"version":3,"mappings":"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","names":["computePosition","debounce","writeArrowUpdates","writeContainerUpdates","getScrollParent","createPositionManager","options","container","target","arrow","strategy","middleware","placement","isDestroyed","updatePosition","undefined","dispose","isFirstUpdate","scrollParents","Set","targetWindow","ownerDocument","defaultView","Object","assign","style","position","left","top","margin","forceUpdate","add","HTMLElement","forEach","scrollParent","addEventListener","then","x","y","middlewareData","computedPlacement","coordinates","lowPPI","devicePixelRatio","catch","err","process","env","NODE_ENV","console","error","removeEventListener"],"sourceRoot":"../src/","sources":["packages/react-components/react-positioning/src/createPositionManager.ts"],"sourcesContent":["import { computePosition } from '@floating-ui/dom';\nimport type { Middleware, Placement, Strategy } from '@floating-ui/dom';\nimport type { PositionManager, TargetElement } from './types';\nimport { debounce, writeArrowUpdates, writeContainerUpdates, getScrollParent } from './utils';\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\n/**\n * @internal\n * @returns manager that handles positioning out of the react lifecycle\n */\nexport function createPositionManager(options: PositionManagerOptions): PositionManager {\n const { container, target, arrow, strategy, middleware, placement } = options;\n let isDestroyed = false;\n if (!target || !container) {\n return {\n updatePosition: () => undefined,\n dispose: () => undefined,\n };\n }\n\n let isFirstUpdate = true;\n const scrollParents: Set<HTMLElement> = new Set<HTMLElement>();\n const targetWindow = container.ownerDocument.defaultView;\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 scrollParents.add(getScrollParent(container));\n if (target instanceof HTMLElement) {\n scrollParents.add(getScrollParent(target));\n }\n\n scrollParents.forEach(scrollParent => {\n scrollParent.addEventListener('scroll', updatePosition);\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 });\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 };\n\n if (targetWindow) {\n targetWindow.addEventListener('scroll', updatePosition);\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"]}
@@ -8,6 +8,7 @@ define(["require", "exports", "@floating-ui/dom", "./utils"], function (require,
8
8
  */
9
9
  function createPositionManager(options) {
10
10
  var container = options.container, target = options.target, arrow = options.arrow, strategy = options.strategy, middleware = options.middleware, placement = options.placement;
11
+ var isDestroyed = false;
11
12
  if (!target || !container) {
12
13
  return {
13
14
  updatePosition: function () { return undefined; },
@@ -21,6 +22,11 @@ define(["require", "exports", "@floating-ui/dom", "./utils"], function (require,
21
22
  // Without this scroll jumps can occur when the element is rendered initially and receives focus
22
23
  Object.assign(container.style, { position: 'fixed', left: 0, top: 0, margin: 0 });
23
24
  var forceUpdate = function () {
25
+ // debounced update can still occur afterwards
26
+ // early return to avoid memory leaks
27
+ if (isDestroyed) {
28
+ return;
29
+ }
24
30
  if (isFirstUpdate) {
25
31
  scrollParents.add(utils_1.getScrollParent(container));
26
32
  if (target instanceof HTMLElement) {
@@ -35,6 +41,11 @@ define(["require", "exports", "@floating-ui/dom", "./utils"], function (require,
35
41
  dom_1.computePosition(target, container, { placement: placement, middleware: middleware, strategy: strategy })
36
42
  .then(function (_a) {
37
43
  var x = _a.x, y = _a.y, middlewareData = _a.middlewareData, computedPlacement = _a.placement;
44
+ // Promise can still resolve after destruction
45
+ // early return to avoid applying outdated position
46
+ if (isDestroyed) {
47
+ return;
48
+ }
38
49
  utils_1.writeArrowUpdates({ arrow: arrow, middlewareData: middlewareData });
39
50
  utils_1.writeContainerUpdates({
40
51
  container: container,
@@ -61,9 +72,7 @@ define(["require", "exports", "@floating-ui/dom", "./utils"], function (require,
61
72
  };
62
73
  var updatePosition = utils_1.debounce(function () { return forceUpdate(); });
63
74
  var dispose = function () {
64
- // debounced update can still occur afterwards
65
- // so destroy the reference to forceUpdate
66
- forceUpdate = function () { return null; };
75
+ isDestroyed = true;
67
76
  if (targetWindow) {
68
77
  targetWindow.removeEventListener('scroll', updatePosition);
69
78
  targetWindow.removeEventListener('resize', updatePosition);
@@ -1 +1 @@
1
- {"version":3,"file":"createPositionManager.js","sourceRoot":"","sources":["../../../../../../../packages/react-components/react-positioning/src/createPositionManager.ts"],"names":[],"mappings":";;;;IAiCA;;;OAGG;IACH,SAAgB,qBAAqB,CAAC,OAA+B;QAC3D,IAAA,SAAS,GAAqD,OAAO,UAA5D,EAAE,MAAM,GAA6C,OAAO,OAApD,EAAE,KAAK,GAAsC,OAAO,MAA7C,EAAE,QAAQ,GAA4B,OAAO,SAAnC,EAAE,UAAU,GAAgB,OAAO,WAAvB,EAAE,SAAS,GAAK,OAAO,UAAZ,CAAa;QAC9E,IAAI,CAAC,MAAM,IAAI,CAAC,SAAS,EAAE;YACzB,OAAO;gBACL,cAAc,EAAE,cAAM,OAAA,SAAS,EAAT,CAAS;gBAC/B,OAAO,EAAE,cAAM,OAAA,SAAS,EAAT,CAAS;aACzB,CAAC;SACH;QAED,IAAI,aAAa,GAAG,IAAI,CAAC;QACzB,IAAM,aAAa,GAAqB,IAAI,GAAG,EAAe,CAAC;QAC/D,IAAM,YAAY,GAAG,SAAS,CAAC,aAAa,CAAC,WAAW,CAAC;QAEzD,oFAAoF;QACpF,gGAAgG;QAChG,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC,CAAC;QAElF,IAAI,WAAW,GAAG;YAChB,IAAI,aAAa,EAAE;gBACjB,aAAa,CAAC,GAAG,CAAC,uBAAe,CAAC,SAAS,CAAC,CAAC,CAAC;gBAC9C,IAAI,MAAM,YAAY,WAAW,EAAE;oBACjC,aAAa,CAAC,GAAG,CAAC,uBAAe,CAAC,MAAM,CAAC,CAAC,CAAC;iBAC5C;gBAED,aAAa,CAAC,OAAO,CAAC,UAAA,YAAY;oBAChC,YAAY,CAAC,gBAAgB,CAAC,QAAQ,EAAE,cAAc,CAAC,CAAC;gBAC1D,CAAC,CAAC,CAAC;gBAEH,aAAa,GAAG,KAAK,CAAC;aACvB;YAED,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,EAAE,EAAE,QAAQ,EAAE,QAAQ,EAAE,CAAC,CAAC;YACvD,qBAAe,CAAC,MAAM,EAAE,SAAS,EAAE,EAAE,SAAS,WAAA,EAAE,UAAU,YAAA,EAAE,QAAQ,UAAA,EAAE,CAAC;iBACpE,IAAI,CAAC,UAAC,EAAsD;oBAApD,CAAC,OAAA,EAAE,CAAC,OAAA,EAAE,cAAc,oBAAA,EAAa,iBAAiB,eAAA;gBACzD,yBAAiB,CAAC,EAAE,KAAK,OAAA,EAAE,cAAc,gBAAA,EAAE,CAAC,CAAC;gBAC7C,6BAAqB,CAAC;oBACpB,SAAS,WAAA;oBACT,cAAc,gBAAA;oBACd,SAAS,EAAE,iBAAiB;oBAC5B,WAAW,EAAE,EAAE,CAAC,GAAA,EAAE,CAAC,GAAA,EAAE;oBACrB,MAAM,EAAE,CAAC,CAAA,YAAY,aAAZ,YAAY,uBAAZ,YAAY,CAAE,gBAAgB,KAAI,CAAC,CAAC,IAAI,CAAC;oBAClD,QAAQ,UAAA;iBACT,CAAC,CAAC;YACL,CAAC,CAAC;iBACD,KAAK,CAAC,UAAA,GAAG;gBACR,yDAAyD;gBACzD,sBAAsB;gBACtB,uEAAuE;gBACvE,wFAAwF;gBACxF,4GAA4G;gBAC5G,0GAA0G;gBAC1G,sCAAsC;gBACtC,IAAI,OAAO,CAAC,GAAG,CAAC,QAAQ,KAAK,aAAa,EAAE;oBAC1C,sCAAsC;oBACtC,OAAO,CAAC,KAAK,CAAC,gDAAgD,EAAE,GAAG,CAAC,CAAC;iBACtE;YACH,CAAC,CAAC,CAAC;QACP,CAAC,CAAC;QAEF,IAAM,cAAc,GAAG,gBAAQ,CAAC,cAAM,OAAA,WAAW,EAAE,EAAb,CAAa,CAAC,CAAC;QAErD,IAAM,OAAO,GAAG;YACd,8CAA8C;YAC9C,0CAA0C;YAC1C,WAAW,GAAG,cAAM,OAAA,IAAI,EAAJ,CAAI,CAAC;YAEzB,IAAI,YAAY,EAAE;gBAChB,YAAY,CAAC,mBAAmB,CAAC,QAAQ,EAAE,cAAc,CAAC,CAAC;gBAC3D,YAAY,CAAC,mBAAmB,CAAC,QAAQ,EAAE,cAAc,CAAC,CAAC;aAC5D;YAED,aAAa,CAAC,OAAO,CAAC,UAAA,YAAY;gBAChC,YAAY,CAAC,mBAAmB,CAAC,QAAQ,EAAE,cAAc,CAAC,CAAC;YAC7D,CAAC,CAAC,CAAC;QACL,CAAC,CAAC;QAEF,IAAI,YAAY,EAAE;YAChB,YAAY,CAAC,gBAAgB,CAAC,QAAQ,EAAE,cAAc,CAAC,CAAC;YACxD,YAAY,CAAC,gBAAgB,CAAC,QAAQ,EAAE,cAAc,CAAC,CAAC;SACzD;QAED,wCAAwC;QACxC,cAAc,EAAE,CAAC;QAEjB,OAAO;YACL,cAAc,gBAAA;YACd,OAAO,SAAA;SACR,CAAC;IACJ,CAAC;IAxFD,sDAwFC","sourcesContent":["import { computePosition } from '@floating-ui/dom';\nimport type { Middleware, Placement, Strategy } from '@floating-ui/dom';\nimport type { PositionManager, TargetElement } from './types';\nimport { debounce, writeArrowUpdates, writeContainerUpdates, getScrollParent } from './utils';\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\n/**\n * @internal\n * @returns manager that handles positioning out of the react lifecycle\n */\nexport function createPositionManager(options: PositionManagerOptions): PositionManager {\n const { container, target, arrow, strategy, middleware, placement } = options;\n if (!target || !container) {\n return {\n updatePosition: () => undefined,\n dispose: () => undefined,\n };\n }\n\n let isFirstUpdate = true;\n const scrollParents: Set<HTMLElement> = new Set<HTMLElement>();\n const targetWindow = container.ownerDocument.defaultView;\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 let forceUpdate = () => {\n if (isFirstUpdate) {\n scrollParents.add(getScrollParent(container));\n if (target instanceof HTMLElement) {\n scrollParents.add(getScrollParent(target));\n }\n\n scrollParents.forEach(scrollParent => {\n scrollParent.addEventListener('scroll', updatePosition);\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 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 });\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 // debounced update can still occur afterwards\n // so destroy the reference to forceUpdate\n forceUpdate = () => null;\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 };\n\n if (targetWindow) {\n targetWindow.addEventListener('scroll', updatePosition);\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"]}
1
+ {"version":3,"file":"createPositionManager.js","sourceRoot":"","sources":["../../../../../../../packages/react-components/react-positioning/src/createPositionManager.ts"],"names":[],"mappings":";;;;IAiCA;;;OAGG;IACH,SAAgB,qBAAqB,CAAC,OAA+B;QAC3D,IAAA,SAAS,GAAqD,OAAO,UAA5D,EAAE,MAAM,GAA6C,OAAO,OAApD,EAAE,KAAK,GAAsC,OAAO,MAA7C,EAAE,QAAQ,GAA4B,OAAO,SAAnC,EAAE,UAAU,GAAgB,OAAO,WAAvB,EAAE,SAAS,GAAK,OAAO,UAAZ,CAAa;QAC9E,IAAI,WAAW,GAAG,KAAK,CAAC;QACxB,IAAI,CAAC,MAAM,IAAI,CAAC,SAAS,EAAE;YACzB,OAAO;gBACL,cAAc,EAAE,cAAM,OAAA,SAAS,EAAT,CAAS;gBAC/B,OAAO,EAAE,cAAM,OAAA,SAAS,EAAT,CAAS;aACzB,CAAC;SACH;QAED,IAAI,aAAa,GAAG,IAAI,CAAC;QACzB,IAAM,aAAa,GAAqB,IAAI,GAAG,EAAe,CAAC;QAC/D,IAAM,YAAY,GAAG,SAAS,CAAC,aAAa,CAAC,WAAW,CAAC;QAEzD,oFAAoF;QACpF,gGAAgG;QAChG,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC,CAAC;QAElF,IAAM,WAAW,GAAG;YAClB,8CAA8C;YAC9C,qCAAqC;YACrC,IAAI,WAAW,EAAE;gBACf,OAAO;aACR;YAED,IAAI,aAAa,EAAE;gBACjB,aAAa,CAAC,GAAG,CAAC,uBAAe,CAAC,SAAS,CAAC,CAAC,CAAC;gBAC9C,IAAI,MAAM,YAAY,WAAW,EAAE;oBACjC,aAAa,CAAC,GAAG,CAAC,uBAAe,CAAC,MAAM,CAAC,CAAC,CAAC;iBAC5C;gBAED,aAAa,CAAC,OAAO,CAAC,UAAA,YAAY;oBAChC,YAAY,CAAC,gBAAgB,CAAC,QAAQ,EAAE,cAAc,CAAC,CAAC;gBAC1D,CAAC,CAAC,CAAC;gBAEH,aAAa,GAAG,KAAK,CAAC;aACvB;YAED,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,EAAE,EAAE,QAAQ,EAAE,QAAQ,EAAE,CAAC,CAAC;YACvD,qBAAe,CAAC,MAAM,EAAE,SAAS,EAAE,EAAE,SAAS,WAAA,EAAE,UAAU,YAAA,EAAE,QAAQ,UAAA,EAAE,CAAC;iBACpE,IAAI,CAAC,UAAC,EAAsD;oBAApD,CAAC,OAAA,EAAE,CAAC,OAAA,EAAE,cAAc,oBAAA,EAAa,iBAAiB,eAAA;gBACzD,8CAA8C;gBAC9C,mDAAmD;gBACnD,IAAI,WAAW,EAAE;oBACf,OAAO;iBACR;gBAED,yBAAiB,CAAC,EAAE,KAAK,OAAA,EAAE,cAAc,gBAAA,EAAE,CAAC,CAAC;gBAC7C,6BAAqB,CAAC;oBACpB,SAAS,WAAA;oBACT,cAAc,gBAAA;oBACd,SAAS,EAAE,iBAAiB;oBAC5B,WAAW,EAAE,EAAE,CAAC,GAAA,EAAE,CAAC,GAAA,EAAE;oBACrB,MAAM,EAAE,CAAC,CAAA,YAAY,aAAZ,YAAY,uBAAZ,YAAY,CAAE,gBAAgB,KAAI,CAAC,CAAC,IAAI,CAAC;oBAClD,QAAQ,UAAA;iBACT,CAAC,CAAC;YACL,CAAC,CAAC;iBACD,KAAK,CAAC,UAAA,GAAG;gBACR,yDAAyD;gBACzD,sBAAsB;gBACtB,uEAAuE;gBACvE,wFAAwF;gBACxF,4GAA4G;gBAC5G,0GAA0G;gBAC1G,sCAAsC;gBACtC,IAAI,OAAO,CAAC,GAAG,CAAC,QAAQ,KAAK,aAAa,EAAE;oBAC1C,sCAAsC;oBACtC,OAAO,CAAC,KAAK,CAAC,gDAAgD,EAAE,GAAG,CAAC,CAAC;iBACtE;YACH,CAAC,CAAC,CAAC;QACP,CAAC,CAAC;QAEF,IAAM,cAAc,GAAG,gBAAQ,CAAC,cAAM,OAAA,WAAW,EAAE,EAAb,CAAa,CAAC,CAAC;QAErD,IAAM,OAAO,GAAG;YACd,WAAW,GAAG,IAAI,CAAC;YAEnB,IAAI,YAAY,EAAE;gBAChB,YAAY,CAAC,mBAAmB,CAAC,QAAQ,EAAE,cAAc,CAAC,CAAC;gBAC3D,YAAY,CAAC,mBAAmB,CAAC,QAAQ,EAAE,cAAc,CAAC,CAAC;aAC5D;YAED,aAAa,CAAC,OAAO,CAAC,UAAA,YAAY;gBAChC,YAAY,CAAC,mBAAmB,CAAC,QAAQ,EAAE,cAAc,CAAC,CAAC;YAC7D,CAAC,CAAC,CAAC;QACL,CAAC,CAAC;QAEF,IAAI,YAAY,EAAE;YAChB,YAAY,CAAC,gBAAgB,CAAC,QAAQ,EAAE,cAAc,CAAC,CAAC;YACxD,YAAY,CAAC,gBAAgB,CAAC,QAAQ,EAAE,cAAc,CAAC,CAAC;SACzD;QAED,wCAAwC;QACxC,cAAc,EAAE,CAAC;QAEjB,OAAO;YACL,cAAc,gBAAA;YACd,OAAO,SAAA;SACR,CAAC;IACJ,CAAC;IAnGD,sDAmGC","sourcesContent":["import { computePosition } from '@floating-ui/dom';\nimport type { Middleware, Placement, Strategy } from '@floating-ui/dom';\nimport type { PositionManager, TargetElement } from './types';\nimport { debounce, writeArrowUpdates, writeContainerUpdates, getScrollParent } from './utils';\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\n/**\n * @internal\n * @returns manager that handles positioning out of the react lifecycle\n */\nexport function createPositionManager(options: PositionManagerOptions): PositionManager {\n const { container, target, arrow, strategy, middleware, placement } = options;\n let isDestroyed = false;\n if (!target || !container) {\n return {\n updatePosition: () => undefined,\n dispose: () => undefined,\n };\n }\n\n let isFirstUpdate = true;\n const scrollParents: Set<HTMLElement> = new Set<HTMLElement>();\n const targetWindow = container.ownerDocument.defaultView;\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 scrollParents.add(getScrollParent(container));\n if (target instanceof HTMLElement) {\n scrollParents.add(getScrollParent(target));\n }\n\n scrollParents.forEach(scrollParent => {\n scrollParent.addEventListener('scroll', updatePosition);\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 });\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 };\n\n if (targetWindow) {\n targetWindow.addEventListener('scroll', updatePosition);\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"]}
@@ -19,6 +19,7 @@ function createPositionManager(options) {
19
19
  middleware,
20
20
  placement
21
21
  } = options;
22
+ let isDestroyed = false;
22
23
  if (!target || !container) {
23
24
  return {
24
25
  updatePosition: () => undefined,
@@ -36,7 +37,12 @@ function createPositionManager(options) {
36
37
  top: 0,
37
38
  margin: 0
38
39
  });
39
- let forceUpdate = () => {
40
+ const forceUpdate = () => {
41
+ // debounced update can still occur afterwards
42
+ // early return to avoid memory leaks
43
+ if (isDestroyed) {
44
+ return;
45
+ }
40
46
  if (isFirstUpdate) {
41
47
  scrollParents.add(utils_1.getScrollParent(container));
42
48
  if (target instanceof HTMLElement) {
@@ -60,6 +66,11 @@ function createPositionManager(options) {
60
66
  middlewareData,
61
67
  placement: computedPlacement
62
68
  }) => {
69
+ // Promise can still resolve after destruction
70
+ // early return to avoid applying outdated position
71
+ if (isDestroyed) {
72
+ return;
73
+ }
63
74
  utils_1.writeArrowUpdates({
64
75
  arrow,
65
76
  middlewareData
@@ -91,9 +102,7 @@ function createPositionManager(options) {
91
102
  };
92
103
  const updatePosition = utils_1.debounce(() => forceUpdate());
93
104
  const dispose = () => {
94
- // debounced update can still occur afterwards
95
- // so destroy the reference to forceUpdate
96
- forceUpdate = () => null;
105
+ isDestroyed = true;
97
106
  if (targetWindow) {
98
107
  targetWindow.removeEventListener('scroll', updatePosition);
99
108
  targetWindow.removeEventListener('resize', updatePosition);
@@ -1 +1 @@
1
- {"version":3,"mappings":"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","names":["createPositionManager","options","container","target","arrow","strategy","middleware","placement","updatePosition","undefined","dispose","isFirstUpdate","scrollParents","Set","targetWindow","ownerDocument","defaultView","Object","assign","style","position","left","top","margin","forceUpdate","add","utils_1","HTMLElement","forEach","scrollParent","addEventListener","dom_1","then","x","y","middlewareData","computedPlacement","coordinates","lowPPI","devicePixelRatio","catch","err","process","env","NODE_ENV","console","error","removeEventListener","exports"],"sourceRoot":"../src/","sources":["packages/react-components/react-positioning/src/createPositionManager.ts"],"sourcesContent":["import { computePosition } from '@floating-ui/dom';\nimport type { Middleware, Placement, Strategy } from '@floating-ui/dom';\nimport type { PositionManager, TargetElement } from './types';\nimport { debounce, writeArrowUpdates, writeContainerUpdates, getScrollParent } from './utils';\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\n/**\n * @internal\n * @returns manager that handles positioning out of the react lifecycle\n */\nexport function createPositionManager(options: PositionManagerOptions): PositionManager {\n const { container, target, arrow, strategy, middleware, placement } = options;\n if (!target || !container) {\n return {\n updatePosition: () => undefined,\n dispose: () => undefined,\n };\n }\n\n let isFirstUpdate = true;\n const scrollParents: Set<HTMLElement> = new Set<HTMLElement>();\n const targetWindow = container.ownerDocument.defaultView;\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 let forceUpdate = () => {\n if (isFirstUpdate) {\n scrollParents.add(getScrollParent(container));\n if (target instanceof HTMLElement) {\n scrollParents.add(getScrollParent(target));\n }\n\n scrollParents.forEach(scrollParent => {\n scrollParent.addEventListener('scroll', updatePosition);\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 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 });\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 // debounced update can still occur afterwards\n // so destroy the reference to forceUpdate\n forceUpdate = () => null;\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 };\n\n if (targetWindow) {\n targetWindow.addEventListener('scroll', updatePosition);\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"]}
1
+ {"version":3,"mappings":"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","names":["createPositionManager","options","container","target","arrow","strategy","middleware","placement","isDestroyed","updatePosition","undefined","dispose","isFirstUpdate","scrollParents","Set","targetWindow","ownerDocument","defaultView","Object","assign","style","position","left","top","margin","forceUpdate","add","utils_1","HTMLElement","forEach","scrollParent","addEventListener","dom_1","then","x","y","middlewareData","computedPlacement","coordinates","lowPPI","devicePixelRatio","catch","err","process","env","NODE_ENV","console","error","removeEventListener","exports"],"sourceRoot":"../src/","sources":["packages/react-components/react-positioning/src/createPositionManager.ts"],"sourcesContent":["import { computePosition } from '@floating-ui/dom';\nimport type { Middleware, Placement, Strategy } from '@floating-ui/dom';\nimport type { PositionManager, TargetElement } from './types';\nimport { debounce, writeArrowUpdates, writeContainerUpdates, getScrollParent } from './utils';\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\n/**\n * @internal\n * @returns manager that handles positioning out of the react lifecycle\n */\nexport function createPositionManager(options: PositionManagerOptions): PositionManager {\n const { container, target, arrow, strategy, middleware, placement } = options;\n let isDestroyed = false;\n if (!target || !container) {\n return {\n updatePosition: () => undefined,\n dispose: () => undefined,\n };\n }\n\n let isFirstUpdate = true;\n const scrollParents: Set<HTMLElement> = new Set<HTMLElement>();\n const targetWindow = container.ownerDocument.defaultView;\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 scrollParents.add(getScrollParent(container));\n if (target instanceof HTMLElement) {\n scrollParents.add(getScrollParent(target));\n }\n\n scrollParents.forEach(scrollParent => {\n scrollParent.addEventListener('scroll', updatePosition);\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 });\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 };\n\n if (targetWindow) {\n targetWindow.addEventListener('scroll', updatePosition);\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"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fluentui/react-positioning",
3
- "version": "9.3.9",
3
+ "version": "9.3.11",
4
4
  "description": "A react wrapper around Popper.js for Fluent UI",
5
5
  "main": "lib-commonjs/index.js",
6
6
  "module": "lib/index.js",
@@ -31,7 +31,7 @@
31
31
  "@floating-ui/dom": "^1.0.0",
32
32
  "@fluentui/react-shared-contexts": "^9.2.0",
33
33
  "@fluentui/react-theme": "^9.1.5",
34
- "@fluentui/react-utilities": "^9.5.0",
34
+ "@fluentui/react-utilities": "^9.5.1",
35
35
  "@griffel/react": "^1.5.2",
36
36
  "tslib": "^2.1.0"
37
37
  },