@fluentui/react-positioning 9.23.3 → 9.23.4

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,22 @@
1
1
  # Change Log - @fluentui/react-positioning
2
2
 
3
- <!-- This log was last generated on Wed, 23 Sep 2026 09:03:15 GMT and should not be manually modified. -->
3
+ <!-- This log was last generated on Mon, 19 Oct 2026 14:49:10 GMT and should not be manually modified. -->
4
4
 
5
5
  <!-- Start content -->
6
6
 
7
+ ## [9.23.4](https://github.com/microsoft/fluentui/tree/@fluentui/react-positioning_v9.23.4)
8
+
9
+ Mon, 19 Oct 2026 14:49:10 GMT
10
+ [Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-positioning_v9.23.3..@fluentui/react-positioning_v9.23.4)
11
+
12
+ ### Patches
13
+
14
+ - fix: register positioning slide-direction CSS properties once per document ([PR #36833](https://github.com/microsoft/fluentui/pull/36833) by bernardo.sunderhus@gmail.com)
15
+ - Bump @fluentui/react-utilities to v9.27.0 ([commit](https://github.com/microsoft/fluentui/commit/undefined) by beachball)
16
+
7
17
  ## [9.23.3](https://github.com/microsoft/fluentui/tree/@fluentui/react-positioning_v9.23.3)
8
18
 
9
- Wed, 23 Sep 2026 09:03:15 GMT
19
+ Wed, 23 Sep 2026 09:04:33 GMT
10
20
  [Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-positioning_v9.23.2..@fluentui/react-positioning_v9.23.3)
11
21
 
12
22
  ### Patches
@@ -2,6 +2,11 @@
2
2
  import * as React from "react";
3
3
  import { useEventCallback, isHTMLElement } from "@fluentui/react-utilities";
4
4
  import { POSITIONING_SLIDE_DIRECTION_VAR_X, POSITIONING_SLIDE_DIRECTION_VAR_Y } from "./constants.js";
5
+ const registeredProperties = new WeakMap();
6
+ const slideDirectionProperties = [
7
+ POSITIONING_SLIDE_DIRECTION_VAR_X,
8
+ POSITIONING_SLIDE_DIRECTION_VAR_Y
9
+ ];
5
10
  /**
6
11
  * Returns the slide direction unit vectors for a given Floating UI placement.
7
12
  * Values are -1, 0, or 1, representing the direction the element slides in from.
@@ -46,30 +51,34 @@ import { POSITIONING_SLIDE_DIRECTION_VAR_X, POSITIONING_SLIDE_DIRECTION_VAR_Y }
46
51
  element.style.setProperty(POSITIONING_SLIDE_DIRECTION_VAR_X, `${x}px`);
47
52
  element.style.setProperty(POSITIONING_SLIDE_DIRECTION_VAR_Y, `${y}px`);
48
53
  });
49
- // Register the CSS custom properties so they can be interpolated during animations.
50
- // CSS.registerProperty is idempotent — the try/catch handles the case where
51
- // properties are already registered.
52
54
  React.useEffect(()=>{
53
- var _targetDocument_defaultView_CSS, _targetDocument_defaultView;
54
- var _targetDocument_defaultView_CSS_registerProperty;
55
- const registerProperty = (_targetDocument_defaultView_CSS_registerProperty = targetDocument === null || targetDocument === void 0 ? void 0 : (_targetDocument_defaultView = targetDocument.defaultView) === null || _targetDocument_defaultView === void 0 ? void 0 : (_targetDocument_defaultView_CSS = _targetDocument_defaultView.CSS) === null || _targetDocument_defaultView_CSS === void 0 ? void 0 : _targetDocument_defaultView_CSS.registerProperty) !== null && _targetDocument_defaultView_CSS_registerProperty !== void 0 ? _targetDocument_defaultView_CSS_registerProperty : ()=>{
56
- // No-op if registerProperty is not supported
57
- };
58
- try {
59
- registerProperty({
60
- name: POSITIONING_SLIDE_DIRECTION_VAR_X,
61
- syntax: '<length>',
62
- inherits: false,
63
- initialValue: '0px'
64
- });
65
- registerProperty({
66
- name: POSITIONING_SLIDE_DIRECTION_VAR_Y,
67
- syntax: '<length>',
68
- inherits: false,
69
- initialValue: '0px'
70
- });
71
- } catch (e) {
72
- // Ignore errors from registerProperty, which can occur if the properties are already registered
55
+ var _targetDocument_defaultView;
56
+ const css = targetDocument === null || targetDocument === void 0 ? void 0 : (_targetDocument_defaultView = targetDocument.defaultView) === null || _targetDocument_defaultView === void 0 ? void 0 : _targetDocument_defaultView.CSS;
57
+ if (!targetDocument || !(css === null || css === void 0 ? void 0 : css.registerProperty)) {
58
+ return;
59
+ }
60
+ let properties = registeredProperties.get(targetDocument);
61
+ if (!properties) {
62
+ properties = new Set();
63
+ registeredProperties.set(targetDocument, properties);
64
+ }
65
+ for (const name of slideDirectionProperties){
66
+ if (properties.has(name)) {
67
+ continue;
68
+ }
69
+ try {
70
+ css.registerProperty({
71
+ name,
72
+ syntax: '<length>',
73
+ inherits: false,
74
+ initialValue: '0px'
75
+ });
76
+ properties.add(name);
77
+ } catch (error) {
78
+ if (error && typeof error === 'object' && 'name' in error && error.name === 'InvalidModificationError') {
79
+ properties.add(name);
80
+ }
81
+ }
73
82
  }
74
83
  }, [
75
84
  targetDocument
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/usePositioningSlideDirection.ts"],"sourcesContent":["'use client';\n\nimport * as React from 'react';\nimport { useEventCallback, isHTMLElement } from '@fluentui/react-utilities';\nimport type { PositioningProps } from './types';\nimport { POSITIONING_SLIDE_DIRECTION_VAR_X, POSITIONING_SLIDE_DIRECTION_VAR_Y } from './constants';\n\n/**\n * Returns the slide direction unit vectors for a given Floating UI placement.\n * Values are -1, 0, or 1, representing the direction the element slides in from.\n */\nexport function getPlacementSlideDirections(placement: string): { x: number; y: number } {\n const side = placement.split('-')[0];\n // Default to sliding down from the top side\n let x = 0;\n let y = 1;\n\n if (side === 'right') {\n x = -1;\n y = 0;\n } else if (side === 'bottom') {\n x = 0;\n y = -1;\n } else if (side === 'left') {\n x = 1;\n y = 0;\n }\n\n return { x, y };\n}\n\ntype UsePositioningSlideDirectionOptions = {\n /** The target document for CSS.registerProperty. */\n targetDocument: Document | undefined;\n /** The user's original onPositioningEnd callback, if any. */\n onPositioningEnd?: PositioningProps['onPositioningEnd'];\n};\n\n/**\n * A hook that manages CSS custom properties for slide direction based on positioning placement.\n *\n * It wraps the `onPositioningEnd` callback to set `--fui-positioning-slide-direction-x` and\n * `--fui-positioning-slide-direction-y` CSS custom properties on the positioned element,\n * and registers them via `CSS.registerProperty` to avoid properties propagation down to a DOM tree.\n *\n * @returns The wrapped `onPositioningEnd` handler to pass to the positioning config.\n */\nexport function usePositioningSlideDirection(\n options: UsePositioningSlideDirectionOptions,\n): NonNullable<PositioningProps['onPositioningEnd']> {\n const { targetDocument, onPositioningEnd } = options;\n\n const handlePositionEnd: NonNullable<PositioningProps['onPositioningEnd']> = useEventCallback(e => {\n onPositioningEnd?.(e);\n\n const element = e.target;\n const placement = e.detail.placement;\n\n if (!isHTMLElement(element)) {\n return;\n }\n\n const { x, y } = getPlacementSlideDirections(placement);\n\n element.style.setProperty(POSITIONING_SLIDE_DIRECTION_VAR_X, `${x}px`);\n element.style.setProperty(POSITIONING_SLIDE_DIRECTION_VAR_Y, `${y}px`);\n });\n\n // Register the CSS custom properties so they can be interpolated during animations.\n // CSS.registerProperty is idempotent — the try/catch handles the case where\n // properties are already registered.\n React.useEffect(() => {\n const registerProperty =\n targetDocument?.defaultView?.CSS?.registerProperty ??\n (() => {\n // No-op if registerProperty is not supported\n });\n\n try {\n registerProperty({\n name: POSITIONING_SLIDE_DIRECTION_VAR_X,\n syntax: '<length>',\n inherits: false,\n initialValue: '0px',\n });\n registerProperty({\n name: POSITIONING_SLIDE_DIRECTION_VAR_Y,\n syntax: '<length>',\n inherits: false,\n initialValue: '0px',\n });\n } catch (e) {\n // Ignore errors from registerProperty, which can occur if the properties are already registered\n }\n }, [targetDocument]);\n\n return handlePositionEnd;\n}\n"],"names":["React","useEventCallback","isHTMLElement","POSITIONING_SLIDE_DIRECTION_VAR_X","POSITIONING_SLIDE_DIRECTION_VAR_Y","getPlacementSlideDirections","placement","side","split","x","y","usePositioningSlideDirection","options","targetDocument","onPositioningEnd","handlePositionEnd","e","element","target","detail","style","setProperty","useEffect","registerProperty","defaultView","CSS","name","syntax","inherits","initialValue"],"mappings":"AAAA;AAEA,YAAYA,WAAW,QAAQ;AAC/B,SAASC,gBAAgB,EAAEC,aAAa,QAAQ,4BAA4B;AAE5E,SAASC,iCAAiC,EAAEC,iCAAiC,QAAQ,iBAAc;AAEnG;;;CAGC,GACD,OAAO,SAASC,4BAA4BC,SAAiB;IAC3D,MAAMC,OAAOD,UAAUE,KAAK,CAAC,IAAI,CAAC,EAAE;IACpC,4CAA4C;IAC5C,IAAIC,IAAI;IACR,IAAIC,IAAI;IAER,IAAIH,SAAS,SAAS;QACpBE,IAAI,CAAC;QACLC,IAAI;IACN,OAAO,IAAIH,SAAS,UAAU;QAC5BE,IAAI;QACJC,IAAI,CAAC;IACP,OAAO,IAAIH,SAAS,QAAQ;QAC1BE,IAAI;QACJC,IAAI;IACN;IAEA,OAAO;QAAED;QAAGC;IAAE;AAChB;AASA;;;;;;;;CAQC,GACD,OAAO,SAASC,6BACdC,OAA4C;IAE5C,MAAM,EAAEC,cAAc,EAAEC,gBAAgB,EAAE,GAAGF;IAE7C,MAAMG,oBAAuEd,iBAAiBe,CAAAA;QAC5FF,6BAAAA,uCAAAA,iBAAmBE;QAEnB,MAAMC,UAAUD,EAAEE,MAAM;QACxB,MAAMZ,YAAYU,EAAEG,MAAM,CAACb,SAAS;QAEpC,IAAI,CAACJ,cAAce,UAAU;YAC3B;QACF;QAEA,MAAM,EAAER,CAAC,EAAEC,CAAC,EAAE,GAAGL,4BAA4BC;QAE7CW,QAAQG,KAAK,CAACC,WAAW,CAAClB,mCAAmC,GAAGM,EAAE,EAAE,CAAC;QACrEQ,QAAQG,KAAK,CAACC,WAAW,CAACjB,mCAAmC,GAAGM,EAAE,EAAE,CAAC;IACvE;IAEA,oFAAoF;IACpF,4EAA4E;IAC5E,qCAAqC;IACrCV,MAAMsB,SAAS,CAAC;YAEZT,iCAAAA;YAAAA;QADF,MAAMU,mBACJV,CAAAA,mDAAAA,2BAAAA,sCAAAA,8BAAAA,eAAgBW,WAAW,cAA3BX,mDAAAA,kCAAAA,4BAA6BY,GAAG,cAAhCZ,sDAAAA,gCAAkCU,gBAAgB,cAAlDV,8DAAAA,mDACC;QACC,6CAA6C;QAC/C;QAEF,IAAI;YACFU,iBAAiB;gBACfG,MAAMvB;gBACNwB,QAAQ;gBACRC,UAAU;gBACVC,cAAc;YAChB;YACAN,iBAAiB;gBACfG,MAAMtB;gBACNuB,QAAQ;gBACRC,UAAU;gBACVC,cAAc;YAChB;QACF,EAAE,OAAOb,GAAG;QACV,gGAAgG;QAClG;IACF,GAAG;QAACH;KAAe;IAEnB,OAAOE;AACT"}
1
+ {"version":3,"sources":["../src/usePositioningSlideDirection.ts"],"sourcesContent":["'use client';\n\nimport * as React from 'react';\nimport { useEventCallback, isHTMLElement } from '@fluentui/react-utilities';\nimport type { PositioningProps } from './types';\nimport { POSITIONING_SLIDE_DIRECTION_VAR_X, POSITIONING_SLIDE_DIRECTION_VAR_Y } from './constants';\n\nconst registeredProperties = new WeakMap<Document, Set<string>>();\nconst slideDirectionProperties = [POSITIONING_SLIDE_DIRECTION_VAR_X, POSITIONING_SLIDE_DIRECTION_VAR_Y];\n\n/**\n * Returns the slide direction unit vectors for a given Floating UI placement.\n * Values are -1, 0, or 1, representing the direction the element slides in from.\n */\nexport function getPlacementSlideDirections(placement: string): { x: number; y: number } {\n const side = placement.split('-')[0];\n // Default to sliding down from the top side\n let x = 0;\n let y = 1;\n\n if (side === 'right') {\n x = -1;\n y = 0;\n } else if (side === 'bottom') {\n x = 0;\n y = -1;\n } else if (side === 'left') {\n x = 1;\n y = 0;\n }\n\n return { x, y };\n}\n\ntype UsePositioningSlideDirectionOptions = {\n /** The target document for CSS.registerProperty. */\n targetDocument: Document | undefined;\n /** The user's original onPositioningEnd callback, if any. */\n onPositioningEnd?: PositioningProps['onPositioningEnd'];\n};\n\n/**\n * A hook that manages CSS custom properties for slide direction based on positioning placement.\n *\n * It wraps the `onPositioningEnd` callback to set `--fui-positioning-slide-direction-x` and\n * `--fui-positioning-slide-direction-y` CSS custom properties on the positioned element,\n * and registers them via `CSS.registerProperty` to avoid properties propagation down to a DOM tree.\n *\n * @returns The wrapped `onPositioningEnd` handler to pass to the positioning config.\n */\nexport function usePositioningSlideDirection(\n options: UsePositioningSlideDirectionOptions,\n): NonNullable<PositioningProps['onPositioningEnd']> {\n const { targetDocument, onPositioningEnd } = options;\n\n const handlePositionEnd: NonNullable<PositioningProps['onPositioningEnd']> = useEventCallback(e => {\n onPositioningEnd?.(e);\n\n const element = e.target;\n const placement = e.detail.placement;\n\n if (!isHTMLElement(element)) {\n return;\n }\n\n const { x, y } = getPlacementSlideDirections(placement);\n\n element.style.setProperty(POSITIONING_SLIDE_DIRECTION_VAR_X, `${x}px`);\n element.style.setProperty(POSITIONING_SLIDE_DIRECTION_VAR_Y, `${y}px`);\n });\n\n React.useEffect(() => {\n const css = targetDocument?.defaultView?.CSS;\n if (!targetDocument || !css?.registerProperty) {\n return;\n }\n let properties = registeredProperties.get(targetDocument);\n if (!properties) {\n properties = new Set<string>();\n registeredProperties.set(targetDocument, properties);\n }\n for (const name of slideDirectionProperties) {\n if (properties.has(name)) {\n continue;\n }\n try {\n css.registerProperty({ name, syntax: '<length>', inherits: false, initialValue: '0px' });\n properties.add(name);\n } catch (error) {\n if (error && typeof error === 'object' && 'name' in error && error.name === 'InvalidModificationError') {\n properties.add(name);\n }\n }\n }\n }, [targetDocument]);\n\n return handlePositionEnd;\n}\n"],"names":["React","useEventCallback","isHTMLElement","POSITIONING_SLIDE_DIRECTION_VAR_X","POSITIONING_SLIDE_DIRECTION_VAR_Y","registeredProperties","WeakMap","slideDirectionProperties","getPlacementSlideDirections","placement","side","split","x","y","usePositioningSlideDirection","options","targetDocument","onPositioningEnd","handlePositionEnd","e","element","target","detail","style","setProperty","useEffect","css","defaultView","CSS","registerProperty","properties","get","Set","set","name","has","syntax","inherits","initialValue","add","error"],"mappings":"AAAA;AAEA,YAAYA,WAAW,QAAQ;AAC/B,SAASC,gBAAgB,EAAEC,aAAa,QAAQ,4BAA4B;AAE5E,SAASC,iCAAiC,EAAEC,iCAAiC,QAAQ,iBAAc;AAEnG,MAAMC,uBAAuB,IAAIC;AACjC,MAAMC,2BAA2B;IAACJ;IAAmCC;CAAkC;AAEvG;;;CAGC,GACD,OAAO,SAASI,4BAA4BC,SAAiB;IAC3D,MAAMC,OAAOD,UAAUE,KAAK,CAAC,IAAI,CAAC,EAAE;IACpC,4CAA4C;IAC5C,IAAIC,IAAI;IACR,IAAIC,IAAI;IAER,IAAIH,SAAS,SAAS;QACpBE,IAAI,CAAC;QACLC,IAAI;IACN,OAAO,IAAIH,SAAS,UAAU;QAC5BE,IAAI;QACJC,IAAI,CAAC;IACP,OAAO,IAAIH,SAAS,QAAQ;QAC1BE,IAAI;QACJC,IAAI;IACN;IAEA,OAAO;QAAED;QAAGC;IAAE;AAChB;AASA;;;;;;;;CAQC,GACD,OAAO,SAASC,6BACdC,OAA4C;IAE5C,MAAM,EAAEC,cAAc,EAAEC,gBAAgB,EAAE,GAAGF;IAE7C,MAAMG,oBAAuEjB,iBAAiBkB,CAAAA;QAC5FF,6BAAAA,uCAAAA,iBAAmBE;QAEnB,MAAMC,UAAUD,EAAEE,MAAM;QACxB,MAAMZ,YAAYU,EAAEG,MAAM,CAACb,SAAS;QAEpC,IAAI,CAACP,cAAckB,UAAU;YAC3B;QACF;QAEA,MAAM,EAAER,CAAC,EAAEC,CAAC,EAAE,GAAGL,4BAA4BC;QAE7CW,QAAQG,KAAK,CAACC,WAAW,CAACrB,mCAAmC,GAAGS,EAAE,EAAE,CAAC;QACrEQ,QAAQG,KAAK,CAACC,WAAW,CAACpB,mCAAmC,GAAGS,EAAE,EAAE,CAAC;IACvE;IAEAb,MAAMyB,SAAS,CAAC;YACFT;QAAZ,MAAMU,MAAMV,2BAAAA,sCAAAA,8BAAAA,eAAgBW,WAAW,cAA3BX,kDAAAA,4BAA6BY,GAAG;QAC5C,IAAI,CAACZ,kBAAkB,EAACU,gBAAAA,0BAAAA,IAAKG,gBAAgB,GAAE;YAC7C;QACF;QACA,IAAIC,aAAazB,qBAAqB0B,GAAG,CAACf;QAC1C,IAAI,CAACc,YAAY;YACfA,aAAa,IAAIE;YACjB3B,qBAAqB4B,GAAG,CAACjB,gBAAgBc;QAC3C;QACA,KAAK,MAAMI,QAAQ3B,yBAA0B;YAC3C,IAAIuB,WAAWK,GAAG,CAACD,OAAO;gBACxB;YACF;YACA,IAAI;gBACFR,IAAIG,gBAAgB,CAAC;oBAAEK;oBAAME,QAAQ;oBAAYC,UAAU;oBAAOC,cAAc;gBAAM;gBACtFR,WAAWS,GAAG,CAACL;YACjB,EAAE,OAAOM,OAAO;gBACd,IAAIA,SAAS,OAAOA,UAAU,YAAY,UAAUA,SAASA,MAAMN,IAAI,KAAK,4BAA4B;oBACtGJ,WAAWS,GAAG,CAACL;gBACjB;YACF;QACF;IACF,GAAG;QAAClB;KAAe;IAEnB,OAAOE;AACT"}
@@ -21,6 +21,11 @@ const _interop_require_wildcard = require("@swc/helpers/_/_interop_require_wildc
21
21
  const _react = /*#__PURE__*/ _interop_require_wildcard._(require("react"));
22
22
  const _reactutilities = require("@fluentui/react-utilities");
23
23
  const _constants = require("./constants.cjs");
24
+ const registeredProperties = new WeakMap();
25
+ const slideDirectionProperties = [
26
+ _constants.POSITIONING_SLIDE_DIRECTION_VAR_X,
27
+ _constants.POSITIONING_SLIDE_DIRECTION_VAR_Y
28
+ ];
24
29
  function getPlacementSlideDirections(placement) {
25
30
  const side = placement.split('-')[0];
26
31
  // Default to sliding down from the top side
@@ -54,30 +59,34 @@ function usePositioningSlideDirection(options) {
54
59
  element.style.setProperty(_constants.POSITIONING_SLIDE_DIRECTION_VAR_X, `${x}px`);
55
60
  element.style.setProperty(_constants.POSITIONING_SLIDE_DIRECTION_VAR_Y, `${y}px`);
56
61
  });
57
- // Register the CSS custom properties so they can be interpolated during animations.
58
- // CSS.registerProperty is idempotent — the try/catch handles the case where
59
- // properties are already registered.
60
62
  _react.useEffect(()=>{
61
- var _targetDocument_defaultView_CSS, _targetDocument_defaultView;
62
- var _targetDocument_defaultView_CSS_registerProperty;
63
- const registerProperty = (_targetDocument_defaultView_CSS_registerProperty = targetDocument === null || targetDocument === void 0 ? void 0 : (_targetDocument_defaultView = targetDocument.defaultView) === null || _targetDocument_defaultView === void 0 ? void 0 : (_targetDocument_defaultView_CSS = _targetDocument_defaultView.CSS) === null || _targetDocument_defaultView_CSS === void 0 ? void 0 : _targetDocument_defaultView_CSS.registerProperty) !== null && _targetDocument_defaultView_CSS_registerProperty !== void 0 ? _targetDocument_defaultView_CSS_registerProperty : ()=>{
64
- // No-op if registerProperty is not supported
65
- };
66
- try {
67
- registerProperty({
68
- name: _constants.POSITIONING_SLIDE_DIRECTION_VAR_X,
69
- syntax: '<length>',
70
- inherits: false,
71
- initialValue: '0px'
72
- });
73
- registerProperty({
74
- name: _constants.POSITIONING_SLIDE_DIRECTION_VAR_Y,
75
- syntax: '<length>',
76
- inherits: false,
77
- initialValue: '0px'
78
- });
79
- } catch (e) {
80
- // Ignore errors from registerProperty, which can occur if the properties are already registered
63
+ var _targetDocument_defaultView;
64
+ const css = targetDocument === null || targetDocument === void 0 ? void 0 : (_targetDocument_defaultView = targetDocument.defaultView) === null || _targetDocument_defaultView === void 0 ? void 0 : _targetDocument_defaultView.CSS;
65
+ if (!targetDocument || !(css === null || css === void 0 ? void 0 : css.registerProperty)) {
66
+ return;
67
+ }
68
+ let properties = registeredProperties.get(targetDocument);
69
+ if (!properties) {
70
+ properties = new Set();
71
+ registeredProperties.set(targetDocument, properties);
72
+ }
73
+ for (const name of slideDirectionProperties){
74
+ if (properties.has(name)) {
75
+ continue;
76
+ }
77
+ try {
78
+ css.registerProperty({
79
+ name,
80
+ syntax: '<length>',
81
+ inherits: false,
82
+ initialValue: '0px'
83
+ });
84
+ properties.add(name);
85
+ } catch (error) {
86
+ if (error && typeof error === 'object' && 'name' in error && error.name === 'InvalidModificationError') {
87
+ properties.add(name);
88
+ }
89
+ }
81
90
  }
82
91
  }, [
83
92
  targetDocument
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/usePositioningSlideDirection.ts"],"sourcesContent":["'use client';\n\nimport * as React from 'react';\nimport { useEventCallback, isHTMLElement } from '@fluentui/react-utilities';\nimport type { PositioningProps } from './types';\nimport { POSITIONING_SLIDE_DIRECTION_VAR_X, POSITIONING_SLIDE_DIRECTION_VAR_Y } from './constants';\n\n/**\n * Returns the slide direction unit vectors for a given Floating UI placement.\n * Values are -1, 0, or 1, representing the direction the element slides in from.\n */\nexport function getPlacementSlideDirections(placement: string): { x: number; y: number } {\n const side = placement.split('-')[0];\n // Default to sliding down from the top side\n let x = 0;\n let y = 1;\n\n if (side === 'right') {\n x = -1;\n y = 0;\n } else if (side === 'bottom') {\n x = 0;\n y = -1;\n } else if (side === 'left') {\n x = 1;\n y = 0;\n }\n\n return { x, y };\n}\n\ntype UsePositioningSlideDirectionOptions = {\n /** The target document for CSS.registerProperty. */\n targetDocument: Document | undefined;\n /** The user's original onPositioningEnd callback, if any. */\n onPositioningEnd?: PositioningProps['onPositioningEnd'];\n};\n\n/**\n * A hook that manages CSS custom properties for slide direction based on positioning placement.\n *\n * It wraps the `onPositioningEnd` callback to set `--fui-positioning-slide-direction-x` and\n * `--fui-positioning-slide-direction-y` CSS custom properties on the positioned element,\n * and registers them via `CSS.registerProperty` to avoid properties propagation down to a DOM tree.\n *\n * @returns The wrapped `onPositioningEnd` handler to pass to the positioning config.\n */\nexport function usePositioningSlideDirection(\n options: UsePositioningSlideDirectionOptions,\n): NonNullable<PositioningProps['onPositioningEnd']> {\n const { targetDocument, onPositioningEnd } = options;\n\n const handlePositionEnd: NonNullable<PositioningProps['onPositioningEnd']> = useEventCallback(e => {\n onPositioningEnd?.(e);\n\n const element = e.target;\n const placement = e.detail.placement;\n\n if (!isHTMLElement(element)) {\n return;\n }\n\n const { x, y } = getPlacementSlideDirections(placement);\n\n element.style.setProperty(POSITIONING_SLIDE_DIRECTION_VAR_X, `${x}px`);\n element.style.setProperty(POSITIONING_SLIDE_DIRECTION_VAR_Y, `${y}px`);\n });\n\n // Register the CSS custom properties so they can be interpolated during animations.\n // CSS.registerProperty is idempotent — the try/catch handles the case where\n // properties are already registered.\n React.useEffect(() => {\n const registerProperty =\n targetDocument?.defaultView?.CSS?.registerProperty ??\n (() => {\n // No-op if registerProperty is not supported\n });\n\n try {\n registerProperty({\n name: POSITIONING_SLIDE_DIRECTION_VAR_X,\n syntax: '<length>',\n inherits: false,\n initialValue: '0px',\n });\n registerProperty({\n name: POSITIONING_SLIDE_DIRECTION_VAR_Y,\n syntax: '<length>',\n inherits: false,\n initialValue: '0px',\n });\n } catch (e) {\n // Ignore errors from registerProperty, which can occur if the properties are already registered\n }\n }, [targetDocument]);\n\n return handlePositionEnd;\n}\n"],"names":["React","useEventCallback","isHTMLElement","POSITIONING_SLIDE_DIRECTION_VAR_X","POSITIONING_SLIDE_DIRECTION_VAR_Y","getPlacementSlideDirections","placement","side","split","x","y","usePositioningSlideDirection","options","targetDocument","onPositioningEnd","handlePositionEnd","e","element","target","detail","style","setProperty","useEffect","registerProperty","defaultView","CSS","name","syntax","inherits","initialValue"],"mappings":"AAAA;;;;;;;;;;;;IAWgBK,2BAAAA;;;IAoCAM,4BAAAA;;;;;iEA7CO,QAAQ;gCACiB,4BAA4B;2BAES,iBAAc;AAM5F,qCAAqCL,SAAiB;IAC3D,MAAMC,OAAOD,UAAUE,KAAK,CAAC,IAAI,CAAC,EAAE;IACpC,4CAA4C;IAC5C,IAAIC,IAAI;IACR,IAAIC,IAAI;IAER,IAAIH,SAAS,SAAS;QACpBE,IAAI,CAAC;QACLC,IAAI;IACN,OAAO,IAAIH,SAAS,UAAU;QAC5BE,IAAI;QACJC,IAAI,CAAC;IACP,OAAO,IAAIH,SAAS,QAAQ;QAC1BE,IAAI;QACJC,IAAI;IACN;IAEA,OAAO;QAAED;QAAGC;IAAE;AAChB;AAkBO,sCACLE,OAA4C;IAE5C,MAAM,EAAEC,cAAc,EAAEC,gBAAgB,EAAE,GAAGF;IAE7C,MAAMG,wBAAuEd,gCAAAA,EAAiBe,CAAAA;QAC5FF,qBAAAA,QAAAA,qBAAAA,KAAAA,IAAAA,KAAAA,IAAAA,iBAAmBE;QAEnB,MAAMC,UAAUD,EAAEE,MAAM;QACxB,MAAMZ,YAAYU,EAAEG,MAAM,CAACb,SAAS;QAEpC,IAAI,CAACJ,iCAAAA,EAAce,UAAU;YAC3B;QACF;QAEA,MAAM,EAAER,CAAC,EAAEC,CAAC,EAAE,GAAGL,4BAA4BC;QAE7CW,QAAQG,KAAK,CAACC,WAAW,CAAClB,4CAAAA,EAAmC,GAAGM,EAAE,EAAE,CAAC;QACrEQ,QAAQG,KAAK,CAACC,WAAW,CAACjB,4CAAAA,EAAmC,GAAGM,EAAE,EAAE,CAAC;IACvE;IAEA,oFAAoF;IACpF,4EAA4E;IAC5E,qCAAqC;IACrCV,OAAMsB,SAAS,CAAC;YAEZT,iCAAAA;YAAAA;QADF,MAAMU,mBACJV,oDAAAA,mBAAAA,QAAAA,mBAAAA,KAAAA,IAAAA,KAAAA,IAAAA,CAAAA,8BAAAA,eAAgBW,WAAAA,AAAW,MAAA,QAA3BX,gCAAAA,KAAAA,IAAAA,KAAAA,IAAAA,CAAAA,kCAAAA,4BAA6BY,GAAAA,AAAG,MAAA,QAAhCZ,oCAAAA,KAAAA,IAAAA,KAAAA,IAAAA,gCAAkCU,gBAAAA,AAAgB,MAAA,QAAlDV,qDAAAA,KAAAA,IAAAA,mDACC;QACC,6CAA6C;QAC/C;QAEF,IAAI;YACFU,iBAAiB;gBACfG,MAAMvB,4CAAAA;gBACNwB,QAAQ;gBACRC,UAAU;gBACVC,cAAc;YAChB;YACAN,iBAAiB;gBACfG,MAAMtB,4CAAAA;gBACNuB,QAAQ;gBACRC,UAAU;gBACVC,cAAc;YAChB;QACF,EAAE,OAAOb,GAAG;QACV,gGAAgG;QAClG;IACF,GAAG;QAACH;KAAe;IAEnB,OAAOE;AACT"}
1
+ {"version":3,"sources":["../src/usePositioningSlideDirection.ts"],"sourcesContent":["'use client';\n\nimport * as React from 'react';\nimport { useEventCallback, isHTMLElement } from '@fluentui/react-utilities';\nimport type { PositioningProps } from './types';\nimport { POSITIONING_SLIDE_DIRECTION_VAR_X, POSITIONING_SLIDE_DIRECTION_VAR_Y } from './constants';\n\nconst registeredProperties = new WeakMap<Document, Set<string>>();\nconst slideDirectionProperties = [POSITIONING_SLIDE_DIRECTION_VAR_X, POSITIONING_SLIDE_DIRECTION_VAR_Y];\n\n/**\n * Returns the slide direction unit vectors for a given Floating UI placement.\n * Values are -1, 0, or 1, representing the direction the element slides in from.\n */\nexport function getPlacementSlideDirections(placement: string): { x: number; y: number } {\n const side = placement.split('-')[0];\n // Default to sliding down from the top side\n let x = 0;\n let y = 1;\n\n if (side === 'right') {\n x = -1;\n y = 0;\n } else if (side === 'bottom') {\n x = 0;\n y = -1;\n } else if (side === 'left') {\n x = 1;\n y = 0;\n }\n\n return { x, y };\n}\n\ntype UsePositioningSlideDirectionOptions = {\n /** The target document for CSS.registerProperty. */\n targetDocument: Document | undefined;\n /** The user's original onPositioningEnd callback, if any. */\n onPositioningEnd?: PositioningProps['onPositioningEnd'];\n};\n\n/**\n * A hook that manages CSS custom properties for slide direction based on positioning placement.\n *\n * It wraps the `onPositioningEnd` callback to set `--fui-positioning-slide-direction-x` and\n * `--fui-positioning-slide-direction-y` CSS custom properties on the positioned element,\n * and registers them via `CSS.registerProperty` to avoid properties propagation down to a DOM tree.\n *\n * @returns The wrapped `onPositioningEnd` handler to pass to the positioning config.\n */\nexport function usePositioningSlideDirection(\n options: UsePositioningSlideDirectionOptions,\n): NonNullable<PositioningProps['onPositioningEnd']> {\n const { targetDocument, onPositioningEnd } = options;\n\n const handlePositionEnd: NonNullable<PositioningProps['onPositioningEnd']> = useEventCallback(e => {\n onPositioningEnd?.(e);\n\n const element = e.target;\n const placement = e.detail.placement;\n\n if (!isHTMLElement(element)) {\n return;\n }\n\n const { x, y } = getPlacementSlideDirections(placement);\n\n element.style.setProperty(POSITIONING_SLIDE_DIRECTION_VAR_X, `${x}px`);\n element.style.setProperty(POSITIONING_SLIDE_DIRECTION_VAR_Y, `${y}px`);\n });\n\n React.useEffect(() => {\n const css = targetDocument?.defaultView?.CSS;\n if (!targetDocument || !css?.registerProperty) {\n return;\n }\n let properties = registeredProperties.get(targetDocument);\n if (!properties) {\n properties = new Set<string>();\n registeredProperties.set(targetDocument, properties);\n }\n for (const name of slideDirectionProperties) {\n if (properties.has(name)) {\n continue;\n }\n try {\n css.registerProperty({ name, syntax: '<length>', inherits: false, initialValue: '0px' });\n properties.add(name);\n } catch (error) {\n if (error && typeof error === 'object' && 'name' in error && error.name === 'InvalidModificationError') {\n properties.add(name);\n }\n }\n }\n }, [targetDocument]);\n\n return handlePositionEnd;\n}\n"],"names":["React","useEventCallback","isHTMLElement","POSITIONING_SLIDE_DIRECTION_VAR_X","POSITIONING_SLIDE_DIRECTION_VAR_Y","registeredProperties","WeakMap","slideDirectionProperties","getPlacementSlideDirections","placement","side","split","x","y","usePositioningSlideDirection","options","targetDocument","onPositioningEnd","handlePositionEnd","e","element","target","detail","style","setProperty","useEffect","css","defaultView","CSS","registerProperty","properties","get","Set","set","name","has","syntax","inherits","initialValue","add","error"],"mappings":"AAAA;;;;;;;;;;;;IAcgBQ,2BAAAA;;;IAoCAM,4BAAAA;;;;;iEAhDO,QAAQ;gCACiB,4BAA4B;2BAES,iBAAc;AAEnG,MAAMT,uBAAuB,IAAIC;AACjC,MAAMC,2BAA2B;IAACJ,4CAAAA;IAAmCC,4CAAAA;CAAkC;AAMhG,qCAAqCK,SAAiB;IAC3D,MAAMC,OAAOD,UAAUE,KAAK,CAAC,IAAI,CAAC,EAAE;IACpC,4CAA4C;IAC5C,IAAIC,IAAI;IACR,IAAIC,IAAI;IAER,IAAIH,SAAS,SAAS;QACpBE,IAAI,CAAC;QACLC,IAAI;IACN,OAAO,IAAIH,SAAS,UAAU;QAC5BE,IAAI;QACJC,IAAI,CAAC;IACP,OAAO,IAAIH,SAAS,QAAQ;QAC1BE,IAAI;QACJC,IAAI;IACN;IAEA,OAAO;QAAED;QAAGC;IAAE;AAChB;AAkBO,sCACLE,OAA4C;IAE5C,MAAM,EAAEC,cAAc,EAAEC,gBAAgB,EAAE,GAAGF;IAE7C,MAAMG,oBAAuEjB,oCAAAA,EAAiBkB,CAAAA;QAC5FF,qBAAAA,QAAAA,qBAAAA,KAAAA,IAAAA,KAAAA,IAAAA,iBAAmBE;QAEnB,MAAMC,UAAUD,EAAEE,MAAM;QACxB,MAAMZ,YAAYU,EAAEG,MAAM,CAACb,SAAS;QAEpC,IAAI,KAACP,6BAAAA,EAAckB,UAAU;YAC3B;QACF;QAEA,MAAM,EAAER,CAAC,EAAEC,CAAC,EAAE,GAAGL,4BAA4BC;QAE7CW,QAAQG,KAAK,CAACC,WAAW,CAACrB,4CAAAA,EAAmC,GAAGS,EAAE,EAAE,CAAC;QACrEQ,QAAQG,KAAK,CAACC,WAAW,CAACpB,4CAAAA,EAAmC,GAAGS,EAAE,EAAE,CAAC;IACvE;IAEAb,OAAMyB,SAAS,CAAC;YACFT;QAAZ,MAAMU,MAAMV,mBAAAA,QAAAA,mBAAAA,KAAAA,IAAAA,KAAAA,IAAAA,CAAAA,8BAAAA,eAAgBW,WAAAA,AAAW,MAAA,QAA3BX,gCAAAA,KAAAA,IAAAA,KAAAA,IAAAA,4BAA6BY,GAAG;QAC5C,IAAI,CAACZ,kBAAkB,EAACU,QAAAA,QAAAA,QAAAA,KAAAA,IAAAA,KAAAA,IAAAA,IAAKG,gBAAAA,AAAgB,GAAE;YAC7C;QACF;QACA,IAAIC,aAAazB,qBAAqB0B,GAAG,CAACf;QAC1C,IAAI,CAACc,YAAY;YACfA,aAAa,IAAIE;YACjB3B,qBAAqB4B,GAAG,CAACjB,gBAAgBc;QAC3C;QACA,KAAK,MAAMI,QAAQ3B,yBAA0B;YAC3C,IAAIuB,WAAWK,GAAG,CAACD,OAAO;gBACxB;YACF;YACA,IAAI;gBACFR,IAAIG,gBAAgB,CAAC;oBAAEK;oBAAME,QAAQ;oBAAYC,UAAU;oBAAOC,cAAc;gBAAM;gBACtFR,WAAWS,GAAG,CAACL;YACjB,EAAE,OAAOM,OAAO;gBACd,IAAIA,SAAS,OAAOA,UAAU,YAAY,UAAUA,SAASA,MAAMN,IAAI,KAAK,4BAA4B;oBACtGJ,WAAWS,GAAG,CAACL;gBACjB;YACF;QACF;IACF,GAAG;QAAClB;KAAe;IAEnB,OAAOE;AACT"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fluentui/react-positioning",
3
- "version": "9.23.3",
3
+ "version": "9.23.4",
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",
@@ -16,7 +16,7 @@
16
16
  "@floating-ui/dom": "^1.6.12",
17
17
  "@fluentui/react-shared-contexts": "^9.26.4",
18
18
  "@fluentui/react-theme": "^9.2.2",
19
- "@fluentui/react-utilities": "^9.26.7",
19
+ "@fluentui/react-utilities": "^9.27.0",
20
20
  "@griffel/react": "^1.5.32",
21
21
  "@swc/helpers": "^0.5.1",
22
22
  "use-sync-external-store": "^1.4.0"