Private
Public Access
1
0

feat: Fluent UI Outlook Lite + connections mockup

This commit is contained in:
2026-04-14 18:52:25 +00:00
parent 1199eff6c3
commit dfa4010406
34820 changed files with 1003813 additions and 205 deletions

View File

@@ -0,0 +1,18 @@
export function createResizeObserver(targetWindow, callback) {
// https://github.com/jsdom/jsdom/issues/3368
// Add the polyfill here so it is not needed for all unit tests that leverage positioning
if (process.env.NODE_ENV === 'test') {
targetWindow.ResizeObserver = class ResizeObserver {
observe() {
// do nothing
}
unobserve() {
// do nothing
}
disconnect() {
// do nothing
}
};
}
return new targetWindow.ResizeObserver(callback);
}

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../src/utils/createResizeObserver.ts"],"sourcesContent":["export function createResizeObserver(\n targetWindow: Window & typeof globalThis,\n callback: ResizeObserverCallback,\n): ResizeObserver {\n // https://github.com/jsdom/jsdom/issues/3368\n // Add the polyfill here so it is not needed for all unit tests that leverage positioning\n if (process.env.NODE_ENV === 'test') {\n targetWindow.ResizeObserver = class ResizeObserver {\n public observe() {\n // do nothing\n }\n public unobserve() {\n // do nothing\n }\n public disconnect() {\n // do nothing\n }\n };\n }\n\n return new targetWindow.ResizeObserver(callback);\n}\n"],"names":["createResizeObserver","targetWindow","callback","process","env","NODE_ENV","ResizeObserver","observe","unobserve","disconnect"],"mappings":"AAAA,OAAO,SAASA,qBACdC,YAAwC,EACxCC,QAAgC;IAEhC,6CAA6C;IAC7C,yFAAyF;IACzF,IAAIC,QAAQC,GAAG,CAACC,QAAQ,KAAK,QAAQ;QACnCJ,aAAaK,cAAc,GAAG,MAAMA;YAC3BC,UAAU;YACf,aAAa;YACf;YACOC,YAAY;YACjB,aAAa;YACf;YACOC,aAAa;YAClB,aAAa;YACf;QACF;IACF;IAEA,OAAO,IAAIR,aAAaK,cAAc,CAACJ;AACzC"}

View File

@@ -0,0 +1,19 @@
/**
* Promise microtask debouncer used by Popper.js v2
* This is no longer exported in Floating UI (Popper.js v3)
* https://github.com/floating-ui/floating-ui/blob/v2.x/src/utils/debounce.js
* @param fn function that will be debounced
*/ export function debounce(fn) {
let pending;
return ()=>{
if (!pending) {
pending = new Promise((resolve)=>{
Promise.resolve().then(()=>{
pending = undefined;
resolve(fn());
});
});
}
return pending;
};
}

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../src/utils/debounce.ts"],"sourcesContent":["/**\n * Promise microtask debouncer used by Popper.js v2\n * This is no longer exported in Floating UI (Popper.js v3)\n * https://github.com/floating-ui/floating-ui/blob/v2.x/src/utils/debounce.js\n * @param fn function that will be debounced\n */\nexport function debounce<T>(fn: Function): () => Promise<T> {\n let pending: Promise<T> | undefined;\n return () => {\n if (!pending) {\n pending = new Promise<T>(resolve => {\n Promise.resolve().then(() => {\n pending = undefined;\n resolve(fn());\n });\n });\n }\n\n return pending;\n };\n}\n"],"names":["debounce","fn","pending","Promise","resolve","then","undefined"],"mappings":"AAAA;;;;;CAKC,GACD,OAAO,SAASA,SAAYC,EAAY;IACtC,IAAIC;IACJ,OAAO;QACL,IAAI,CAACA,SAAS;YACZA,UAAU,IAAIC,QAAWC,CAAAA;gBACvBD,QAAQC,OAAO,GAAGC,IAAI,CAAC;oBACrBH,UAAUI;oBACVF,QAAQH;gBACV;YACF;QACF;QAEA,OAAOC;IACT;AACF"}

View File

@@ -0,0 +1,27 @@
import { isHTMLElement } from '@fluentui/react-utilities';
import { listScrollParents } from './listScrollParents';
import { fromFloatingUIPlacement } from './fromFloatingUIPlacement';
export const devtoolsCallback = (options)=>(middlewareState)=>{
const { elements: { floating, reference } } = middlewareState;
const scrollParentsSet = new Set();
if (isHTMLElement(reference)) {
listScrollParents(reference).forEach((scrollParent)=>scrollParentsSet.add(scrollParent));
}
listScrollParents(floating).forEach((scrollParent)=>scrollParentsSet.add(scrollParent));
const flipBoundaries = Array.isArray(options.flipBoundary) ? options.flipBoundary : isHTMLElement(options.flipBoundary) ? [
options.flipBoundary
] : [];
const overflowBoundaries = Array.isArray(options.overflowBoundary) ? options.overflowBoundary : isHTMLElement(options.overflowBoundary) ? [
options.overflowBoundary
] : [];
return {
type: 'FluentUIMiddleware',
middlewareState,
options,
initialPlacement: fromFloatingUIPlacement(middlewareState.initialPlacement),
placement: fromFloatingUIPlacement(middlewareState.placement),
flipBoundaries,
overflowBoundaries,
scrollParents: Array.from(scrollParentsSet)
};
};

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../src/utils/devtools.ts"],"sourcesContent":["import type { MiddlewareState } from '@floating-ui/dom';\nimport type { PositioningOptions, Position, Alignment } from '../types';\nimport { isHTMLElement } from '@fluentui/react-utilities';\nimport { listScrollParents } from './listScrollParents';\nimport { fromFloatingUIPlacement } from './fromFloatingUIPlacement';\n\nexport const devtoolsCallback =\n (options: Pick<PositioningOptions, 'flipBoundary' | 'overflowBoundary'>) =>\n (\n middlewareState: MiddlewareState,\n ): {\n type: 'FluentUIMiddleware';\n middlewareState: MiddlewareState;\n options: Pick<PositioningOptions, 'flipBoundary' | 'overflowBoundary'>;\n initialPlacement: { position: Position; alignment?: Alignment };\n placement: { position: Position; alignment?: Alignment };\n flipBoundaries: HTMLElement[];\n overflowBoundaries: HTMLElement[];\n scrollParents: HTMLElement[];\n } => {\n const {\n elements: { floating, reference },\n } = middlewareState;\n const scrollParentsSet = new Set<HTMLElement>();\n if (isHTMLElement(reference)) {\n listScrollParents(reference).forEach(scrollParent => scrollParentsSet.add(scrollParent));\n }\n listScrollParents(floating).forEach(scrollParent => scrollParentsSet.add(scrollParent));\n const flipBoundaries: HTMLElement[] = Array.isArray(options.flipBoundary)\n ? options.flipBoundary\n : isHTMLElement(options.flipBoundary)\n ? [options.flipBoundary]\n : [];\n const overflowBoundaries: HTMLElement[] = Array.isArray(options.overflowBoundary)\n ? options.overflowBoundary\n : isHTMLElement(options.overflowBoundary)\n ? [options.overflowBoundary]\n : [];\n return {\n type: 'FluentUIMiddleware',\n middlewareState,\n options,\n initialPlacement: fromFloatingUIPlacement(middlewareState.initialPlacement),\n placement: fromFloatingUIPlacement(middlewareState.placement),\n flipBoundaries,\n overflowBoundaries,\n scrollParents: Array.from(scrollParentsSet),\n } as const;\n };\n"],"names":["isHTMLElement","listScrollParents","fromFloatingUIPlacement","devtoolsCallback","options","middlewareState","elements","floating","reference","scrollParentsSet","Set","forEach","scrollParent","add","flipBoundaries","Array","isArray","flipBoundary","overflowBoundaries","overflowBoundary","type","initialPlacement","placement","scrollParents","from"],"mappings":"AAEA,SAASA,aAAa,QAAQ,4BAA4B;AAC1D,SAASC,iBAAiB,QAAQ,sBAAsB;AACxD,SAASC,uBAAuB,QAAQ,4BAA4B;AAEpE,OAAO,MAAMC,mBACX,CAACC,UACD,CACEC;QAWA,MAAM,EACJC,UAAU,EAAEC,QAAQ,EAAEC,SAAS,EAAE,EAClC,GAAGH;QACJ,MAAMI,mBAAmB,IAAIC;QAC7B,IAAIV,cAAcQ,YAAY;YAC5BP,kBAAkBO,WAAWG,OAAO,CAACC,CAAAA,eAAgBH,iBAAiBI,GAAG,CAACD;QAC5E;QACAX,kBAAkBM,UAAUI,OAAO,CAACC,CAAAA,eAAgBH,iBAAiBI,GAAG,CAACD;QACzE,MAAME,iBAAgCC,MAAMC,OAAO,CAACZ,QAAQa,YAAY,IACpEb,QAAQa,YAAY,GACpBjB,cAAcI,QAAQa,YAAY,IAClC;YAACb,QAAQa,YAAY;SAAC,GACtB,EAAE;QACN,MAAMC,qBAAoCH,MAAMC,OAAO,CAACZ,QAAQe,gBAAgB,IAC5Ef,QAAQe,gBAAgB,GACxBnB,cAAcI,QAAQe,gBAAgB,IACtC;YAACf,QAAQe,gBAAgB;SAAC,GAC1B,EAAE;QACN,OAAO;YACLC,MAAM;YACNf;YACAD;YACAiB,kBAAkBnB,wBAAwBG,gBAAgBgB,gBAAgB;YAC1EC,WAAWpB,wBAAwBG,gBAAgBiB,SAAS;YAC5DR;YACAI;YACAK,eAAeR,MAAMS,IAAI,CAACf;QAC5B;IACF,EAAE"}

View File

@@ -0,0 +1,33 @@
import { parseFloatingUIPlacement } from './parseFloatingUIPlacement';
const getPositionMap = ()=>({
top: 'above',
bottom: 'below',
right: 'after',
left: 'before'
});
// Floating UI automatically flips alignment
// https://github.com/floating-ui/floating-ui/issues/1563
const getAlignmentMap = (position)=>{
if (position === 'above' || position === 'below') {
return {
start: 'start',
end: 'end'
};
}
return {
start: 'top',
end: 'bottom'
};
};
/**
* Maps Floating UI placement to positioning values
* @see positioningHelper.test.ts for expected placement values
*/ export const fromFloatingUIPlacement = (placement)=>{
const { side, alignment: floatingUIAlignment } = parseFloatingUIPlacement(placement);
const position = getPositionMap()[side];
const alignment = floatingUIAlignment && getAlignmentMap(position)[floatingUIAlignment];
return {
position,
alignment
};
};

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../src/utils/fromFloatingUIPlacement.ts"],"sourcesContent":["import type { Side, Alignment as FloatingUIAlignment, Placement } from '@floating-ui/dom';\nimport type { Alignment, Position } from '../types';\nimport { parseFloatingUIPlacement } from './parseFloatingUIPlacement';\n\nconst getPositionMap = (): Record<Side, Position> => ({\n top: 'above',\n bottom: 'below',\n right: 'after',\n left: 'before',\n});\n\n// Floating UI automatically flips alignment\n// https://github.com/floating-ui/floating-ui/issues/1563\nconst getAlignmentMap = (position: Position): Record<FloatingUIAlignment, Alignment> => {\n if (position === 'above' || position === 'below') {\n return {\n start: 'start',\n end: 'end',\n };\n }\n\n return {\n start: 'top',\n end: 'bottom',\n };\n};\n\n/**\n * Maps Floating UI placement to positioning values\n * @see positioningHelper.test.ts for expected placement values\n */\nexport const fromFloatingUIPlacement = (placement: Placement): { position: Position; alignment?: Alignment } => {\n const { side, alignment: floatingUIAlignment } = parseFloatingUIPlacement(placement);\n const position = getPositionMap()[side];\n const alignment = floatingUIAlignment && getAlignmentMap(position)[floatingUIAlignment];\n\n return { position, alignment };\n};\n"],"names":["parseFloatingUIPlacement","getPositionMap","top","bottom","right","left","getAlignmentMap","position","start","end","fromFloatingUIPlacement","placement","side","alignment","floatingUIAlignment"],"mappings":"AAEA,SAASA,wBAAwB,QAAQ,6BAA6B;AAEtE,MAAMC,iBAAiB,IAA+B,CAAA;QACpDC,KAAK;QACLC,QAAQ;QACRC,OAAO;QACPC,MAAM;IACR,CAAA;AAEA,4CAA4C;AAC5C,yDAAyD;AACzD,MAAMC,kBAAkB,CAACC;IACvB,IAAIA,aAAa,WAAWA,aAAa,SAAS;QAChD,OAAO;YACLC,OAAO;YACPC,KAAK;QACP;IACF;IAEA,OAAO;QACLD,OAAO;QACPC,KAAK;IACP;AACF;AAEA;;;CAGC,GACD,OAAO,MAAMC,0BAA0B,CAACC;IACtC,MAAM,EAAEC,IAAI,EAAEC,WAAWC,mBAAmB,EAAE,GAAGd,yBAAyBW;IAC1E,MAAMJ,WAAWN,gBAAgB,CAACW,KAAK;IACvC,MAAMC,YAAYC,uBAAuBR,gBAAgBC,SAAS,CAACO,oBAAoB;IAEvF,OAAO;QAAEP;QAAUM;IAAU;AAC/B,EAAE"}

View File

@@ -0,0 +1,19 @@
import { getScrollParent } from './getScrollParent';
/**
* Allows to mimic a behavior from V1 of Popper and accept `window` and `scrollParent` as strings.
*/ export function getBoundary(element, boundary) {
if (boundary === 'window') {
return element === null || element === void 0 ? void 0 : element.ownerDocument.documentElement;
}
if (boundary === 'clippingParents') {
return 'clippingAncestors';
}
if (boundary === 'scrollParent') {
let boundariesNode = getScrollParent(element);
if (boundariesNode.nodeName === 'BODY') {
boundariesNode = element === null || element === void 0 ? void 0 : element.ownerDocument.documentElement;
}
return boundariesNode;
}
return boundary;
}

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../src/utils/getBoundary.ts"],"sourcesContent":["import type { Boundary as FloatingUIBoundary } from '@floating-ui/dom';\n\nimport { getScrollParent } from './getScrollParent';\nimport type { PositioningBoundary } from '../types';\n\n/**\n * Allows to mimic a behavior from V1 of Popper and accept `window` and `scrollParent` as strings.\n */\nexport function getBoundary(\n element: HTMLElement | null,\n boundary?: PositioningBoundary,\n): FloatingUIBoundary | undefined {\n if (boundary === 'window') {\n return element?.ownerDocument!.documentElement;\n }\n\n if (boundary === 'clippingParents') {\n return 'clippingAncestors';\n }\n\n if (boundary === 'scrollParent') {\n let boundariesNode: HTMLElement | undefined = getScrollParent(element);\n\n if (boundariesNode.nodeName === 'BODY') {\n boundariesNode = element?.ownerDocument!.documentElement;\n }\n\n return boundariesNode;\n }\n\n return boundary;\n}\n"],"names":["getScrollParent","getBoundary","element","boundary","ownerDocument","documentElement","boundariesNode","nodeName"],"mappings":"AAEA,SAASA,eAAe,QAAQ,oBAAoB;AAGpD;;CAEC,GACD,OAAO,SAASC,YACdC,OAA2B,EAC3BC,QAA8B;IAE9B,IAAIA,aAAa,UAAU;QACzB,OAAOD,oBAAAA,8BAAAA,QAASE,aAAa,CAAEC,eAAe;IAChD;IAEA,IAAIF,aAAa,mBAAmB;QAClC,OAAO;IACT;IAEA,IAAIA,aAAa,gBAAgB;QAC/B,IAAIG,iBAA0CN,gBAAgBE;QAE9D,IAAII,eAAeC,QAAQ,KAAK,QAAQ;YACtCD,iBAAiBJ,oBAAAA,8BAAAA,QAASE,aAAa,CAAEC,eAAe;QAC1D;QAEA,OAAOC;IACT;IAEA,OAAOH;AACT"}

View File

@@ -0,0 +1,22 @@
import { fromFloatingUIPlacement } from './fromFloatingUIPlacement';
/**
* Shim to transform offset values from this library to Floating UI
* @param rawOffset Offset from this library
* @returns An offset value compatible with Floating UI
*/ export function getFloatingUIOffset(rawOffset) {
if (!rawOffset) {
return rawOffset;
}
if (typeof rawOffset === 'number' || typeof rawOffset === 'object') {
return rawOffset;
}
return ({ rects: { floating, reference }, placement })=>{
const { position, alignment } = fromFloatingUIPlacement(placement);
return rawOffset({
positionedRect: floating,
targetRect: reference,
position,
alignment
});
};
}

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../src/utils/getFloatingUIOffset.ts"],"sourcesContent":["import type { Offset } from '../types';\nimport type { MiddlewareState } from '@floating-ui/dom';\nimport { fromFloatingUIPlacement } from './fromFloatingUIPlacement';\n/**\n * Type taken from Floating UI since they are not exported\n */\nexport type FloatingUIOffsetValue =\n | number\n | {\n /**\n * The axis that runs along the side of the floating element.\n * @default 0\n */\n mainAxis?: number;\n /**\n * The axis that runs along the alignment of the floating element.\n * @default 0\n */\n crossAxis?: number;\n /**\n * When set to a number, overrides the `crossAxis` value for aligned\n * (non-centered/base) placements and works logically. A positive number\n * will move the floating element in the direction of the opposite edge\n * to the one that is aligned, while a negative number the reverse.\n * @default null\n */\n alignmentAxis?: number | null;\n };\n\n/**\n * Type taken from Floating UI since they are not exported\n */\nexport type FloatingUIOffsetFunction = (args: MiddlewareState) => FloatingUIOffsetValue;\n\n/**\n * Shim to transform offset values from this library to Floating UI\n * @param rawOffset Offset from this library\n * @returns An offset value compatible with Floating UI\n */\nexport function getFloatingUIOffset(\n rawOffset: Offset | undefined,\n): FloatingUIOffsetValue | FloatingUIOffsetFunction | undefined {\n if (!rawOffset) {\n return rawOffset;\n }\n\n if (typeof rawOffset === 'number' || typeof rawOffset === 'object') {\n return rawOffset;\n }\n\n return ({ rects: { floating, reference }, placement }) => {\n const { position, alignment } = fromFloatingUIPlacement(placement);\n return rawOffset({ positionedRect: floating, targetRect: reference, position, alignment });\n };\n}\n"],"names":["fromFloatingUIPlacement","getFloatingUIOffset","rawOffset","rects","floating","reference","placement","position","alignment","positionedRect","targetRect"],"mappings":"AAEA,SAASA,uBAAuB,QAAQ,4BAA4B;AAgCpE;;;;CAIC,GACD,OAAO,SAASC,oBACdC,SAA6B;IAE7B,IAAI,CAACA,WAAW;QACd,OAAOA;IACT;IAEA,IAAI,OAAOA,cAAc,YAAY,OAAOA,cAAc,UAAU;QAClE,OAAOA;IACT;IAEA,OAAO,CAAC,EAAEC,OAAO,EAAEC,QAAQ,EAAEC,SAAS,EAAE,EAAEC,SAAS,EAAE;QACnD,MAAM,EAAEC,QAAQ,EAAEC,SAAS,EAAE,GAAGR,wBAAwBM;QACxD,OAAOJ,UAAU;YAAEO,gBAAgBL;YAAUM,YAAYL;YAAWE;YAAUC;QAAU;IAC1F;AACF"}

View File

@@ -0,0 +1,42 @@
import * as React from 'react';
var WorkTag = /*#__PURE__*/ function(WorkTag) {
WorkTag[WorkTag["FunctionComponent"] = 0] = "FunctionComponent";
WorkTag[WorkTag["ClassComponent"] = 1] = "ClassComponent";
WorkTag[WorkTag["IndeterminateComponent"] = 2] = "IndeterminateComponent";
WorkTag[WorkTag["HostRoot"] = 3] = "HostRoot";
WorkTag[WorkTag["HostPortal"] = 4] = "HostPortal";
WorkTag[WorkTag["HostComponent"] = 5] = "HostComponent";
WorkTag[WorkTag["HostText"] = 6] = "HostText";
WorkTag[WorkTag["Fragment"] = 7] = "Fragment";
WorkTag[WorkTag["Mode"] = 8] = "Mode";
WorkTag[WorkTag["ContextConsumer"] = 9] = "ContextConsumer";
WorkTag[WorkTag["ContextProvider"] = 10] = "ContextProvider";
WorkTag[WorkTag["ForwardRef"] = 11] = "ForwardRef";
WorkTag[WorkTag["Profiler"] = 12] = "Profiler";
WorkTag[WorkTag["SuspenseComponent"] = 13] = "SuspenseComponent";
WorkTag[WorkTag["MemoComponent"] = 14] = "MemoComponent";
WorkTag[WorkTag["SimpleMemoComponent"] = 15] = "SimpleMemoComponent";
WorkTag[WorkTag["LazyComponent"] = 16] = "LazyComponent";
WorkTag[WorkTag["IncompleteClassComponent"] = 17] = "IncompleteClassComponent";
WorkTag[WorkTag["DehydratedFragment"] = 18] = "DehydratedFragment";
WorkTag[WorkTag["SuspenseListComponent"] = 19] = "SuspenseListComponent";
WorkTag[WorkTag["FundamentalComponent"] = 20] = "FundamentalComponent";
WorkTag[WorkTag["ScopeComponent"] = 21] = "ScopeComponent";
return WorkTag;
}(WorkTag || {});
export function getReactFiberFromNode(elm) {
if (!elm) {
return null;
}
for(const k in elm){
// React 16 uses "__reactInternalInstance$" prefix
// React 17 uses "__reactFiber$" prefix
// https://github.com/facebook/react/pull/18377
if (k.indexOf('__reactInternalInstance$') === 0 || k.indexOf('__reactFiber$') === 0) {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
return elm[k];
}
}
throw new Error('getReactFiber(): Failed to find a React Fiber on a node');
}

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,55 @@
/**
* Returns the parent node or the host of the node argument.
* @param node - DOM node.
* @returns - parent DOM node.
*/ 'use client';
export const getParentNode = (node)=>{
if (node.nodeName === 'HTML') {
return node;
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
return node.parentNode || node.host;
};
/**
* Returns CSS styles of the given node.
* @param node - DOM node.
* @returns - CSS styles.
*/ export const getStyleComputedProperty = (node)=>{
var _node_ownerDocument;
if (node.nodeType !== 1) {
return {};
}
const targetWindow = (_node_ownerDocument = node.ownerDocument) === null || _node_ownerDocument === void 0 ? void 0 : _node_ownerDocument.defaultView;
if (targetWindow) {
return targetWindow.getComputedStyle(node, null);
}
return {};
};
/**
* Returns the first scrollable parent of the given element.
* @param node - DOM node.
* @returns - the first scrollable parent.
*/ export const getScrollParent = (node)=>{
// Return body, `getScroll` will take care to get the correct `scrollTop` from it
const parentNode = node && getParentNode(node);
// eslint-disable-next-line
if (!parentNode) return document.body;
switch(parentNode.nodeName){
case 'HTML':
case 'BODY':
return parentNode.ownerDocument.body;
case '#document':
return parentNode.body;
}
// If any of the overflow props is defined for the node then we return it as the parent
const { overflow, overflowX, overflowY } = getStyleComputedProperty(parentNode);
if (/(auto|scroll|overlay)/.test(overflow + overflowY + overflowX)) {
return parentNode;
}
return getScrollParent(parentNode);
};
export const hasScrollParent = (node)=>{
var _scrollParentElement_ownerDocument;
const scrollParentElement = getScrollParent(node);
return scrollParentElement ? scrollParentElement !== ((_scrollParentElement_ownerDocument = scrollParentElement.ownerDocument) === null || _scrollParentElement_ownerDocument === void 0 ? void 0 : _scrollParentElement_ownerDocument.body) : false;
};

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../src/utils/getScrollParent.ts"],"sourcesContent":["/**\n * Returns the parent node or the host of the node argument.\n * @param node - DOM node.\n * @returns - parent DOM node.\n */\n\n'use client';\n\nexport const getParentNode = (node: HTMLElement): HTMLElement => {\n if (node.nodeName === 'HTML') {\n return node;\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return node.parentNode || (node as any).host;\n};\n\n/**\n * Returns CSS styles of the given node.\n * @param node - DOM node.\n * @returns - CSS styles.\n */\nexport const getStyleComputedProperty = (node: HTMLElement): Partial<CSSStyleDeclaration> => {\n if (node.nodeType !== 1) {\n return {};\n }\n\n const targetWindow = node.ownerDocument?.defaultView;\n\n if (targetWindow) {\n return targetWindow.getComputedStyle(node, null);\n }\n\n return {};\n};\n\n/**\n * Returns the first scrollable parent of the given element.\n * @param node - DOM node.\n * @returns - the first scrollable parent.\n */\nexport const getScrollParent = (node: Document | HTMLElement | null): HTMLElement => {\n // Return body, `getScroll` will take care to get the correct `scrollTop` from it\n const parentNode = node && getParentNode(node as HTMLElement);\n // eslint-disable-next-line\n if (!parentNode) return document.body;\n\n switch (parentNode.nodeName) {\n case 'HTML':\n case 'BODY':\n return parentNode.ownerDocument!.body;\n case '#document':\n return (parentNode as unknown as Document).body;\n }\n\n // If any of the overflow props is defined for the node then we return it as the parent\n const { overflow, overflowX, overflowY } = getStyleComputedProperty(parentNode);\n if (/(auto|scroll|overlay)/.test(overflow! + overflowY! + overflowX)) {\n return parentNode;\n }\n\n return getScrollParent(parentNode);\n};\n\nexport const hasScrollParent = (node: Document | HTMLElement | null): boolean => {\n const scrollParentElement: HTMLElement = getScrollParent(node);\n\n return scrollParentElement ? scrollParentElement !== scrollParentElement.ownerDocument?.body : false;\n};\n"],"names":["getParentNode","node","nodeName","parentNode","host","getStyleComputedProperty","nodeType","targetWindow","ownerDocument","defaultView","getComputedStyle","getScrollParent","document","body","overflow","overflowX","overflowY","test","hasScrollParent","scrollParentElement"],"mappings":"AAAA;;;;CAIC,GAED;AAEA,OAAO,MAAMA,gBAAgB,CAACC;IAC5B,IAAIA,KAAKC,QAAQ,KAAK,QAAQ;QAC5B,OAAOD;IACT;IAEA,8DAA8D;IAC9D,OAAOA,KAAKE,UAAU,IAAI,AAACF,KAAaG,IAAI;AAC9C,EAAE;AAEF;;;;CAIC,GACD,OAAO,MAAMC,2BAA2B,CAACJ;QAKlBA;IAJrB,IAAIA,KAAKK,QAAQ,KAAK,GAAG;QACvB,OAAO,CAAC;IACV;IAEA,MAAMC,gBAAeN,sBAAAA,KAAKO,aAAa,cAAlBP,0CAAAA,oBAAoBQ,WAAW;IAEpD,IAAIF,cAAc;QAChB,OAAOA,aAAaG,gBAAgB,CAACT,MAAM;IAC7C;IAEA,OAAO,CAAC;AACV,EAAE;AAEF;;;;CAIC,GACD,OAAO,MAAMU,kBAAkB,CAACV;IAC9B,iFAAiF;IACjF,MAAME,aAAaF,QAAQD,cAAcC;IACzC,2BAA2B;IAC3B,IAAI,CAACE,YAAY,OAAOS,SAASC,IAAI;IAErC,OAAQV,WAAWD,QAAQ;QACzB,KAAK;QACL,KAAK;YACH,OAAOC,WAAWK,aAAa,CAAEK,IAAI;QACvC,KAAK;YACH,OAAO,AAACV,WAAmCU,IAAI;IACnD;IAEA,uFAAuF;IACvF,MAAM,EAAEC,QAAQ,EAAEC,SAAS,EAAEC,SAAS,EAAE,GAAGX,yBAAyBF;IACpE,IAAI,wBAAwBc,IAAI,CAACH,WAAYE,YAAaD,YAAY;QACpE,OAAOZ;IACT;IAEA,OAAOQ,gBAAgBR;AACzB,EAAE;AAEF,OAAO,MAAMe,kBAAkB,CAACjB;QAGuBkB;IAFrD,MAAMA,sBAAmCR,gBAAgBV;IAEzD,OAAOkB,sBAAsBA,0BAAwBA,qCAAAA,oBAAoBX,aAAa,cAAjCW,yDAAAA,mCAAmCN,IAAI,IAAG;AACjG,EAAE"}

View File

@@ -0,0 +1,21 @@
//
// Dev utils to detect if nodes have "autoFocus" props.
//
import { getReactFiberFromNode } from './getReactFiberFromNode';
/**
* Detects if a passed HTML node has "autoFocus" prop on a React's fiber. Is needed as React handles autofocus behavior
* in React DOM and will not pass "autoFocus" to an actual HTML.
*
* @param node
*/ function hasAutofocusProp(node) {
// https://github.com/facebook/react/blob/848bb2426e44606e0a55dfe44c7b3ece33772485/packages/react-dom/src/client/ReactDOMHostConfig.js#L157-L166
const isAutoFocusableElement = node.nodeName === 'BUTTON' || node.nodeName === 'INPUT' || node.nodeName === 'SELECT' || node.nodeName === 'TEXTAREA';
if (isAutoFocusableElement) {
var _getReactFiberFromNode;
return !!((_getReactFiberFromNode = getReactFiberFromNode(node)) === null || _getReactFiberFromNode === void 0 ? void 0 : _getReactFiberFromNode.pendingProps.autoFocus);
}
return false;
}
export function hasAutofocusFilter(node) {
return hasAutofocusProp(node) ? NodeFilter.FILTER_ACCEPT : NodeFilter.FILTER_SKIP;
}

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../src/utils/hasAutoFocusFilter.ts"],"sourcesContent":["//\n// Dev utils to detect if nodes have \"autoFocus\" props.\n//\n\nimport { getReactFiberFromNode } from './getReactFiberFromNode';\n\n/**\n * Detects if a passed HTML node has \"autoFocus\" prop on a React's fiber. Is needed as React handles autofocus behavior\n * in React DOM and will not pass \"autoFocus\" to an actual HTML.\n *\n * @param node\n */\nfunction hasAutofocusProp(node: Node): boolean {\n // https://github.com/facebook/react/blob/848bb2426e44606e0a55dfe44c7b3ece33772485/packages/react-dom/src/client/ReactDOMHostConfig.js#L157-L166\n const isAutoFocusableElement =\n node.nodeName === 'BUTTON' ||\n node.nodeName === 'INPUT' ||\n node.nodeName === 'SELECT' ||\n node.nodeName === 'TEXTAREA';\n\n if (isAutoFocusableElement) {\n return !!getReactFiberFromNode(node)?.pendingProps.autoFocus;\n }\n\n return false;\n}\n\nexport function hasAutofocusFilter(node: Node): number {\n return hasAutofocusProp(node) ? NodeFilter.FILTER_ACCEPT : NodeFilter.FILTER_SKIP;\n}\n"],"names":["getReactFiberFromNode","hasAutofocusProp","node","isAutoFocusableElement","nodeName","pendingProps","autoFocus","hasAutofocusFilter","NodeFilter","FILTER_ACCEPT","FILTER_SKIP"],"mappings":"AAAA,EAAE;AACF,uDAAuD;AACvD,EAAE;AAEF,SAASA,qBAAqB,QAAQ,0BAA0B;AAEhE;;;;;CAKC,GACD,SAASC,iBAAiBC,IAAU;IAClC,gJAAgJ;IAChJ,MAAMC,yBACJD,KAAKE,QAAQ,KAAK,YAClBF,KAAKE,QAAQ,KAAK,WAClBF,KAAKE,QAAQ,KAAK,YAClBF,KAAKE,QAAQ,KAAK;IAEpB,IAAID,wBAAwB;YACjBH;QAAT,OAAO,CAAC,GAACA,yBAAAA,sBAAsBE,mBAAtBF,6CAAAA,uBAA6BK,YAAY,CAACC,SAAS;IAC9D;IAEA,OAAO;AACT;AAEA,OAAO,SAASC,mBAAmBL,IAAU;IAC3C,OAAOD,iBAAiBC,QAAQM,WAAWC,aAAa,GAAGD,WAAWE,WAAW;AACnF"}

View File

@@ -0,0 +1,16 @@
export { parseFloatingUIPlacement } from './parseFloatingUIPlacement';
export { getBoundary } from './getBoundary';
export { getReactFiberFromNode } from './getReactFiberFromNode';
export { getParentNode, getScrollParent, hasScrollParent } from './getScrollParent';
export { mergeArrowOffset } from './mergeArrowOffset';
export { toFloatingUIPadding } from './toFloatingUIPadding';
export { toFloatingUIPlacement } from './toFloatingUIPlacement';
export { fromFloatingUIPlacement } from './fromFloatingUIPlacement';
export { resolvePositioningShorthand } from './resolvePositioningShorthand';
export { useCallbackRef } from './useCallbackRef';
export { debounce } from './debounce';
export { toggleScrollListener } from './toggleScrollListener';
export { hasAutofocusFilter } from './hasAutoFocusFilter';
export { writeArrowUpdates } from './writeArrowUpdates';
export { writeContainerUpdates } from './writeContainerupdates';
export { normalizeAutoSize } from './normalizeAutoSize';

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../src/utils/index.ts"],"sourcesContent":["export { parseFloatingUIPlacement } from './parseFloatingUIPlacement';\nexport { getBoundary } from './getBoundary';\nexport type { Fiber, HookType } from './getReactFiberFromNode';\nexport { getReactFiberFromNode } from './getReactFiberFromNode';\nexport { getParentNode, getScrollParent, hasScrollParent } from './getScrollParent';\nexport { mergeArrowOffset } from './mergeArrowOffset';\nexport { toFloatingUIPadding } from './toFloatingUIPadding';\nexport { toFloatingUIPlacement } from './toFloatingUIPlacement';\nexport { fromFloatingUIPlacement } from './fromFloatingUIPlacement';\nexport { resolvePositioningShorthand } from './resolvePositioningShorthand';\nexport { useCallbackRef } from './useCallbackRef';\nexport { debounce } from './debounce';\nexport { toggleScrollListener } from './toggleScrollListener';\nexport { hasAutofocusFilter } from './hasAutoFocusFilter';\nexport { writeArrowUpdates } from './writeArrowUpdates';\nexport { writeContainerUpdates } from './writeContainerupdates';\nexport { normalizeAutoSize } from './normalizeAutoSize';\n"],"names":["parseFloatingUIPlacement","getBoundary","getReactFiberFromNode","getParentNode","getScrollParent","hasScrollParent","mergeArrowOffset","toFloatingUIPadding","toFloatingUIPlacement","fromFloatingUIPlacement","resolvePositioningShorthand","useCallbackRef","debounce","toggleScrollListener","hasAutofocusFilter","writeArrowUpdates","writeContainerUpdates","normalizeAutoSize"],"mappings":"AAAA,SAASA,wBAAwB,QAAQ,6BAA6B;AACtE,SAASC,WAAW,QAAQ,gBAAgB;AAE5C,SAASC,qBAAqB,QAAQ,0BAA0B;AAChE,SAASC,aAAa,EAAEC,eAAe,EAAEC,eAAe,QAAQ,oBAAoB;AACpF,SAASC,gBAAgB,QAAQ,qBAAqB;AACtD,SAASC,mBAAmB,QAAQ,wBAAwB;AAC5D,SAASC,qBAAqB,QAAQ,0BAA0B;AAChE,SAASC,uBAAuB,QAAQ,4BAA4B;AACpE,SAASC,2BAA2B,QAAQ,gCAAgC;AAC5E,SAASC,cAAc,QAAQ,mBAAmB;AAClD,SAASC,QAAQ,QAAQ,aAAa;AACtC,SAASC,oBAAoB,QAAQ,yBAAyB;AAC9D,SAASC,kBAAkB,QAAQ,uBAAuB;AAC1D,SAASC,iBAAiB,QAAQ,sBAAsB;AACxD,SAASC,qBAAqB,QAAQ,0BAA0B;AAChE,SAASC,iBAAiB,QAAQ,sBAAsB"}

View File

@@ -0,0 +1,22 @@
import { getScrollParent } from './getScrollParent';
export function listScrollParents(node) {
const scrollParents = [];
let cur = node;
while(cur){
const scrollParent = getScrollParent(cur);
if (node.ownerDocument.body === scrollParent) {
scrollParents.push(scrollParent);
break;
}
if (scrollParent.nodeName === 'BODY' && scrollParent !== node.ownerDocument.body) {
if (process.env.NODE_ENV !== 'production') {
// eslint-disable-next-line no-console
console.error('@fluentui/react-positioning: You are comparing two different documents! This is an unexpected error, please report this as a bug to the Fluent UI team ');
}
break;
}
scrollParents.push(scrollParent);
cur = scrollParent;
}
return scrollParents;
}

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../src/utils/listScrollParents.ts"],"sourcesContent":["import { getScrollParent } from './getScrollParent';\n\nexport function listScrollParents(node: HTMLElement): HTMLElement[] {\n const scrollParents: HTMLElement[] = [];\n\n let cur: HTMLElement | null = node;\n while (cur) {\n const scrollParent = getScrollParent(cur);\n\n if (node.ownerDocument.body === scrollParent) {\n scrollParents.push(scrollParent);\n break;\n }\n\n if (scrollParent.nodeName === 'BODY' && scrollParent !== node.ownerDocument.body) {\n if (process.env.NODE_ENV !== 'production') {\n // eslint-disable-next-line no-console\n console.error(\n '@fluentui/react-positioning: You are comparing two different documents! This is an unexpected error, please report this as a bug to the Fluent UI team ',\n );\n }\n break;\n }\n\n scrollParents.push(scrollParent);\n cur = scrollParent;\n }\n\n return scrollParents;\n}\n"],"names":["getScrollParent","listScrollParents","node","scrollParents","cur","scrollParent","ownerDocument","body","push","nodeName","process","env","NODE_ENV","console","error"],"mappings":"AAAA,SAASA,eAAe,QAAQ,oBAAoB;AAEpD,OAAO,SAASC,kBAAkBC,IAAiB;IACjD,MAAMC,gBAA+B,EAAE;IAEvC,IAAIC,MAA0BF;IAC9B,MAAOE,IAAK;QACV,MAAMC,eAAeL,gBAAgBI;QAErC,IAAIF,KAAKI,aAAa,CAACC,IAAI,KAAKF,cAAc;YAC5CF,cAAcK,IAAI,CAACH;YACnB;QACF;QAEA,IAAIA,aAAaI,QAAQ,KAAK,UAAUJ,iBAAiBH,KAAKI,aAAa,CAACC,IAAI,EAAE;YAChF,IAAIG,QAAQC,GAAG,CAACC,QAAQ,KAAK,cAAc;gBACzC,sCAAsC;gBACtCC,QAAQC,KAAK,CACX;YAEJ;YACA;QACF;QAEAX,cAAcK,IAAI,CAACH;QACnBD,MAAMC;IACR;IAEA,OAAOF;AACT"}

View File

@@ -0,0 +1,38 @@
'use client';
/**
* Generally when adding an arrow to popper, it's necessary to offset the position of the popper by the
* height of the arrow. A simple utility to merge a provided offset with an arrow height to return the final offset
*
* @internal
* @param userOffset - The offset provided by the user
* @param arrowHeight - The height of the arrow in px
* @returns User offset augmented with arrow height
*/ export function mergeArrowOffset(userOffset, arrowHeight) {
if (typeof userOffset === 'number') {
return addArrowOffset(userOffset, arrowHeight);
}
if (typeof userOffset === 'object' && userOffset !== null) {
return addArrowOffset(userOffset, arrowHeight);
}
if (typeof userOffset === 'function') {
return (offsetParams)=>{
const offset = userOffset(offsetParams);
return addArrowOffset(offset, arrowHeight);
};
}
return {
mainAxis: arrowHeight
};
}
const addArrowOffset = (offset, arrowHeight)=>{
if (typeof offset === 'number') {
return {
mainAxis: offset + arrowHeight
};
}
var _offset_mainAxis;
return {
...offset,
mainAxis: ((_offset_mainAxis = offset.mainAxis) !== null && _offset_mainAxis !== void 0 ? _offset_mainAxis : 0) + arrowHeight
};
};

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../src/utils/mergeArrowOffset.ts"],"sourcesContent":["'use client';\n\nimport type { Offset, OffsetObject } from '../types';\n\n/**\n * Generally when adding an arrow to popper, it's necessary to offset the position of the popper by the\n * height of the arrow. A simple utility to merge a provided offset with an arrow height to return the final offset\n *\n * @internal\n * @param userOffset - The offset provided by the user\n * @param arrowHeight - The height of the arrow in px\n * @returns User offset augmented with arrow height\n */\nexport function mergeArrowOffset(userOffset: Offset | undefined | null, arrowHeight: number): Offset {\n if (typeof userOffset === 'number') {\n return addArrowOffset(userOffset, arrowHeight);\n }\n\n if (typeof userOffset === 'object' && userOffset !== null) {\n return addArrowOffset(userOffset, arrowHeight);\n }\n\n if (typeof userOffset === 'function') {\n return offsetParams => {\n const offset = userOffset(offsetParams);\n return addArrowOffset(offset, arrowHeight);\n };\n }\n\n return { mainAxis: arrowHeight };\n}\n\nconst addArrowOffset = (offset: OffsetObject | number, arrowHeight: number): OffsetObject => {\n if (typeof offset === 'number') {\n return { mainAxis: offset + arrowHeight };\n }\n\n return { ...offset, mainAxis: (offset.mainAxis ?? 0) + arrowHeight };\n};\n"],"names":["mergeArrowOffset","userOffset","arrowHeight","addArrowOffset","offsetParams","offset","mainAxis"],"mappings":"AAAA;AAIA;;;;;;;;CAQC,GACD,OAAO,SAASA,iBAAiBC,UAAqC,EAAEC,WAAmB;IACzF,IAAI,OAAOD,eAAe,UAAU;QAClC,OAAOE,eAAeF,YAAYC;IACpC;IAEA,IAAI,OAAOD,eAAe,YAAYA,eAAe,MAAM;QACzD,OAAOE,eAAeF,YAAYC;IACpC;IAEA,IAAI,OAAOD,eAAe,YAAY;QACpC,OAAOG,CAAAA;YACL,MAAMC,SAASJ,WAAWG;YAC1B,OAAOD,eAAeE,QAAQH;QAChC;IACF;IAEA,OAAO;QAAEI,UAAUJ;IAAY;AACjC;AAEA,MAAMC,iBAAiB,CAACE,QAA+BH;IACrD,IAAI,OAAOG,WAAW,UAAU;QAC9B,OAAO;YAAEC,UAAUD,SAASH;QAAY;IAC1C;QAE+BG;IAA/B,OAAO;QAAE,GAAGA,MAAM;QAAEC,UAAU,AAACD,CAAAA,CAAAA,mBAAAA,OAAOC,QAAQ,cAAfD,8BAAAA,mBAAmB,CAAA,IAAKH;IAAY;AACrE"}

View File

@@ -0,0 +1,28 @@
/**
* AutoSizes contains many options from historic implementation.
* Now options 'always'/'height-always'/'width-always' are obsolete.
* This function maps them to true/'height'/'width'
*/ export const normalizeAutoSize = (autoSize)=>{
switch(autoSize){
case 'always':
case true:
return {
applyMaxWidth: true,
applyMaxHeight: true
};
case 'width-always':
case 'width':
return {
applyMaxWidth: true,
applyMaxHeight: false
};
case 'height-always':
case 'height':
return {
applyMaxWidth: false,
applyMaxHeight: true
};
default:
return false;
}
};

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../src/utils/normalizeAutoSize.ts"],"sourcesContent":["import type { NormalizedAutoSize, PositioningOptions } from '../types';\n\n/**\n * AutoSizes contains many options from historic implementation.\n * Now options 'always'/'height-always'/'width-always' are obsolete.\n * This function maps them to true/'height'/'width'\n */\nexport const normalizeAutoSize = (autoSize?: PositioningOptions['autoSize']): NormalizedAutoSize | false => {\n switch (autoSize) {\n case 'always':\n case true:\n return {\n applyMaxWidth: true,\n applyMaxHeight: true,\n };\n\n case 'width-always':\n case 'width':\n return {\n applyMaxWidth: true,\n applyMaxHeight: false,\n };\n\n case 'height-always':\n case 'height':\n return {\n applyMaxWidth: false,\n applyMaxHeight: true,\n };\n\n default:\n return false;\n }\n};\n"],"names":["normalizeAutoSize","autoSize","applyMaxWidth","applyMaxHeight"],"mappings":"AAEA;;;;CAIC,GACD,OAAO,MAAMA,oBAAoB,CAACC;IAChC,OAAQA;QACN,KAAK;QACL,KAAK;YACH,OAAO;gBACLC,eAAe;gBACfC,gBAAgB;YAClB;QAEF,KAAK;QACL,KAAK;YACH,OAAO;gBACLD,eAAe;gBACfC,gBAAgB;YAClB;QAEF,KAAK;QACL,KAAK;YACH,OAAO;gBACLD,eAAe;gBACfC,gBAAgB;YAClB;QAEF;YACE,OAAO;IACX;AACF,EAAE"}

View File

@@ -0,0 +1,12 @@
/**
* Parses Floating UI placement and returns the different components
* @param placement - the floating ui placement (i.e. bottom-start)
*
* @returns side and alignment components of the placement
*/ export function parseFloatingUIPlacement(placement) {
const tokens = placement.split('-');
return {
side: tokens[0],
alignment: tokens[1]
};
}

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../src/utils/parseFloatingUIPlacement.ts"],"sourcesContent":["import type { Side, Placement, Alignment } from '@floating-ui/dom';\n\n/**\n * Parses Floating UI placement and returns the different components\n * @param placement - the floating ui placement (i.e. bottom-start)\n *\n * @returns side and alignment components of the placement\n */\nexport function parseFloatingUIPlacement(placement: Placement): { side: Side; alignment: Alignment } {\n const tokens = placement.split('-');\n return {\n side: tokens[0] as Side,\n alignment: tokens[1] as Alignment,\n };\n}\n"],"names":["parseFloatingUIPlacement","placement","tokens","split","side","alignment"],"mappings":"AAEA;;;;;CAKC,GACD,OAAO,SAASA,yBAAyBC,SAAoB;IAC3D,MAAMC,SAASD,UAAUE,KAAK,CAAC;IAC/B,OAAO;QACLC,MAAMF,MAAM,CAAC,EAAE;QACfG,WAAWH,MAAM,CAAC,EAAE;IACtB;AACF"}

View File

@@ -0,0 +1,60 @@
// Look up table for shorthand to avoid parsing strings
const shorthandLookup = {
above: {
position: 'above',
align: 'center'
},
'above-start': {
position: 'above',
align: 'start'
},
'above-end': {
position: 'above',
align: 'end'
},
below: {
position: 'below',
align: 'center'
},
'below-start': {
position: 'below',
align: 'start'
},
'below-end': {
position: 'below',
align: 'end'
},
before: {
position: 'before',
align: 'center'
},
'before-top': {
position: 'before',
align: 'top'
},
'before-bottom': {
position: 'before',
align: 'bottom'
},
after: {
position: 'after',
align: 'center'
},
'after-top': {
position: 'after',
align: 'top'
},
'after-bottom': {
position: 'after',
align: 'bottom'
}
};
export function resolvePositioningShorthand(shorthand) {
if (shorthand === undefined || shorthand === null) {
return {};
}
if (typeof shorthand === 'string') {
return shorthandLookup[shorthand];
}
return shorthand;
}

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../src/utils/resolvePositioningShorthand.ts"],"sourcesContent":["import type { PositioningShorthand, PositioningShorthandValue, PositioningProps } from '../types';\n\n// Look up table for shorthand to avoid parsing strings\nconst shorthandLookup: Record<PositioningShorthandValue, Pick<PositioningProps, 'position' | 'align'>> = {\n above: { position: 'above', align: 'center' },\n 'above-start': { position: 'above', align: 'start' },\n 'above-end': { position: 'above', align: 'end' },\n below: { position: 'below', align: 'center' },\n 'below-start': { position: 'below', align: 'start' },\n 'below-end': { position: 'below', align: 'end' },\n before: { position: 'before', align: 'center' },\n 'before-top': { position: 'before', align: 'top' },\n 'before-bottom': { position: 'before', align: 'bottom' },\n after: { position: 'after', align: 'center' },\n 'after-top': { position: 'after', align: 'top' },\n 'after-bottom': { position: 'after', align: 'bottom' },\n};\n\nexport function resolvePositioningShorthand(\n shorthand: PositioningShorthand | undefined | null,\n): Readonly<PositioningProps> {\n if (shorthand === undefined || shorthand === null) {\n return {};\n }\n\n if (typeof shorthand === 'string') {\n return shorthandLookup[shorthand];\n }\n\n return shorthand as Readonly<PositioningProps>;\n}\n"],"names":["shorthandLookup","above","position","align","below","before","after","resolvePositioningShorthand","shorthand","undefined"],"mappings":"AAEA,uDAAuD;AACvD,MAAMA,kBAAmG;IACvGC,OAAO;QAAEC,UAAU;QAASC,OAAO;IAAS;IAC5C,eAAe;QAAED,UAAU;QAASC,OAAO;IAAQ;IACnD,aAAa;QAAED,UAAU;QAASC,OAAO;IAAM;IAC/CC,OAAO;QAAEF,UAAU;QAASC,OAAO;IAAS;IAC5C,eAAe;QAAED,UAAU;QAASC,OAAO;IAAQ;IACnD,aAAa;QAAED,UAAU;QAASC,OAAO;IAAM;IAC/CE,QAAQ;QAAEH,UAAU;QAAUC,OAAO;IAAS;IAC9C,cAAc;QAAED,UAAU;QAAUC,OAAO;IAAM;IACjD,iBAAiB;QAAED,UAAU;QAAUC,OAAO;IAAS;IACvDG,OAAO;QAAEJ,UAAU;QAASC,OAAO;IAAS;IAC5C,aAAa;QAAED,UAAU;QAASC,OAAO;IAAM;IAC/C,gBAAgB;QAAED,UAAU;QAASC,OAAO;IAAS;AACvD;AAEA,OAAO,SAASI,4BACdC,SAAkD;IAElD,IAAIA,cAAcC,aAAaD,cAAc,MAAM;QACjD,OAAO,CAAC;IACV;IAEA,IAAI,OAAOA,cAAc,UAAU;QACjC,OAAOR,eAAe,CAACQ,UAAU;IACnC;IAEA,OAAOA;AACT"}

View File

@@ -0,0 +1,18 @@
export function toFloatingUIPadding(padding, isRtl) {
if (typeof padding === 'number') {
return padding;
}
const { start, end, ...verticalPadding } = padding;
const paddingObject = verticalPadding;
const left = isRtl ? 'end' : 'start';
const right = isRtl ? 'start' : 'end';
// assign properties explicitly since undefined values are actually handled by floating UI
// TODO create floating UI issue
if (padding[left]) {
paddingObject.left = padding[left];
}
if (padding[right]) {
paddingObject.right = padding[right];
}
return paddingObject;
}

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../src/utils/toFloatingUIPadding.ts"],"sourcesContent":["import type { SideObject } from '@floating-ui/dom';\nimport { PositioningOptions } from '../types';\n\nexport function toFloatingUIPadding(\n padding: NonNullable<PositioningOptions['overflowBoundaryPadding']>,\n isRtl: boolean,\n): number | Partial<SideObject> {\n if (typeof padding === 'number') {\n return padding;\n }\n\n const { start, end, ...verticalPadding } = padding;\n\n const paddingObject: Partial<SideObject> = verticalPadding;\n\n const left = isRtl ? 'end' : 'start';\n const right = isRtl ? 'start' : 'end';\n\n // assign properties explicitly since undefined values are actually handled by floating UI\n // TODO create floating UI issue\n if (padding[left]) {\n paddingObject.left = padding[left];\n }\n\n if (padding[right]) {\n paddingObject.right = padding[right];\n }\n\n return paddingObject;\n}\n"],"names":["toFloatingUIPadding","padding","isRtl","start","end","verticalPadding","paddingObject","left","right"],"mappings":"AAGA,OAAO,SAASA,oBACdC,OAAmE,EACnEC,KAAc;IAEd,IAAI,OAAOD,YAAY,UAAU;QAC/B,OAAOA;IACT;IAEA,MAAM,EAAEE,KAAK,EAAEC,GAAG,EAAE,GAAGC,iBAAiB,GAAGJ;IAE3C,MAAMK,gBAAqCD;IAE3C,MAAME,OAAOL,QAAQ,QAAQ;IAC7B,MAAMM,QAAQN,QAAQ,UAAU;IAEhC,0FAA0F;IAC1F,gCAAgC;IAChC,IAAID,OAAO,CAACM,KAAK,EAAE;QACjBD,cAAcC,IAAI,GAAGN,OAAO,CAACM,KAAK;IACpC;IAEA,IAAIN,OAAO,CAACO,MAAM,EAAE;QAClBF,cAAcE,KAAK,GAAGP,OAAO,CAACO,MAAM;IACtC;IAEA,OAAOF;AACT"}

View File

@@ -0,0 +1,32 @@
const getPositionMap = (rtl)=>({
above: 'top',
below: 'bottom',
before: rtl ? 'right' : 'left',
after: rtl ? 'left' : 'right'
});
// Floating UI automatically flips alignment
// https://github.com/floating-ui/floating-ui/issues/1563
const getAlignmentMap = ()=>({
start: 'start',
end: 'end',
top: 'start',
bottom: 'end',
center: undefined
});
const shouldAlignToCenter = (p, a)=>{
const positionedVertically = p === 'above' || p === 'below';
const alignedVertically = a === 'top' || a === 'bottom';
return positionedVertically && alignedVertically || !positionedVertically && !alignedVertically;
};
/**
* Maps internal positioning values to Floating UI placement
* @see positioningHelper.test.ts for expected placement values
*/ export const toFloatingUIPlacement = (align, position, rtl)=>{
const alignment = shouldAlignToCenter(position, align) ? 'center' : align;
const computedPosition = position && getPositionMap(rtl)[position];
const computedAlignment = alignment && getAlignmentMap()[alignment];
if (computedPosition && computedAlignment) {
return `${computedPosition}-${computedAlignment}`;
}
return computedPosition;
};

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../src/utils/toFloatingUIPlacement.ts"],"sourcesContent":["import type { Placement, Side, Alignment as FloatingUIAlignment } from '@floating-ui/dom';\nimport type { Alignment, Position } from '../types';\n\ntype PlacementPosition = Side;\ntype PlacementAlign = FloatingUIAlignment;\n\nconst getPositionMap = (rtl?: boolean): Record<Position, PlacementPosition> => ({\n above: 'top',\n below: 'bottom',\n before: rtl ? 'right' : 'left',\n after: rtl ? 'left' : 'right',\n});\n\n// Floating UI automatically flips alignment\n// https://github.com/floating-ui/floating-ui/issues/1563\nconst getAlignmentMap = (): Record<Alignment, PlacementAlign | undefined> => ({\n start: 'start',\n end: 'end',\n top: 'start',\n bottom: 'end',\n center: undefined,\n});\n\nconst shouldAlignToCenter = (p?: Position, a?: Alignment): boolean => {\n const positionedVertically = p === 'above' || p === 'below';\n const alignedVertically = a === 'top' || a === 'bottom';\n\n return (positionedVertically && alignedVertically) || (!positionedVertically && !alignedVertically);\n};\n\n/**\n * Maps internal positioning values to Floating UI placement\n * @see positioningHelper.test.ts for expected placement values\n */\nexport const toFloatingUIPlacement = (align?: Alignment, position?: Position, rtl?: boolean): Placement | undefined => {\n const alignment = shouldAlignToCenter(position, align) ? 'center' : align;\n\n const computedPosition = position && getPositionMap(rtl)[position];\n const computedAlignment = alignment && getAlignmentMap()[alignment];\n\n if (computedPosition && computedAlignment) {\n return `${computedPosition}-${computedAlignment}` as Placement;\n }\n\n return computedPosition;\n};\n"],"names":["getPositionMap","rtl","above","below","before","after","getAlignmentMap","start","end","top","bottom","center","undefined","shouldAlignToCenter","p","a","positionedVertically","alignedVertically","toFloatingUIPlacement","align","position","alignment","computedPosition","computedAlignment"],"mappings":"AAMA,MAAMA,iBAAiB,CAACC,MAAwD,CAAA;QAC9EC,OAAO;QACPC,OAAO;QACPC,QAAQH,MAAM,UAAU;QACxBI,OAAOJ,MAAM,SAAS;IACxB,CAAA;AAEA,4CAA4C;AAC5C,yDAAyD;AACzD,MAAMK,kBAAkB,IAAsD,CAAA;QAC5EC,OAAO;QACPC,KAAK;QACLC,KAAK;QACLC,QAAQ;QACRC,QAAQC;IACV,CAAA;AAEA,MAAMC,sBAAsB,CAACC,GAAcC;IACzC,MAAMC,uBAAuBF,MAAM,WAAWA,MAAM;IACpD,MAAMG,oBAAoBF,MAAM,SAASA,MAAM;IAE/C,OAAO,AAACC,wBAAwBC,qBAAuB,CAACD,wBAAwB,CAACC;AACnF;AAEA;;;CAGC,GACD,OAAO,MAAMC,wBAAwB,CAACC,OAAmBC,UAAqBnB;IAC5E,MAAMoB,YAAYR,oBAAoBO,UAAUD,SAAS,WAAWA;IAEpE,MAAMG,mBAAmBF,YAAYpB,eAAeC,IAAI,CAACmB,SAAS;IAClE,MAAMG,oBAAoBF,aAAaf,iBAAiB,CAACe,UAAU;IAEnE,IAAIC,oBAAoBC,mBAAmB;QACzC,OAAO,GAAGD,iBAAiB,CAAC,EAAEC,mBAAmB;IACnD;IAEA,OAAOD;AACT,EAAE"}

View File

@@ -0,0 +1,20 @@
import { isHTMLElement } from '@fluentui/react-utilities';
import { getScrollParent } from './getScrollParent';
/**
* Toggles event listeners for scroll parent.
* Cleans up the event listeners for the previous element and adds them for the new scroll parent.
* @param next Next element
* @param prev Previous element
*/ export function toggleScrollListener(next, prev, handler) {
if (next === prev) {
return;
}
if (isHTMLElement(prev)) {
const prevScrollParent = getScrollParent(prev);
prevScrollParent.removeEventListener('scroll', handler);
}
if (isHTMLElement(next)) {
const scrollParent = getScrollParent(next);
scrollParent.addEventListener('scroll', handler);
}
}

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../src/utils/toggleScrollListener.ts"],"sourcesContent":["import { isHTMLElement } from '@fluentui/react-utilities';\nimport type { PositioningVirtualElement } from '../types';\nimport { getScrollParent } from './getScrollParent';\n\n/**\n * Toggles event listeners for scroll parent.\n * Cleans up the event listeners for the previous element and adds them for the new scroll parent.\n * @param next Next element\n * @param prev Previous element\n */\nexport function toggleScrollListener(\n next: HTMLElement | PositioningVirtualElement | null,\n prev: HTMLElement | PositioningVirtualElement | null,\n handler: EventListener,\n): void {\n if (next === prev) {\n return;\n }\n\n if (isHTMLElement(prev)) {\n const prevScrollParent = getScrollParent(prev);\n prevScrollParent.removeEventListener('scroll', handler);\n }\n if (isHTMLElement(next)) {\n const scrollParent = getScrollParent(next);\n scrollParent.addEventListener('scroll', handler);\n }\n}\n"],"names":["isHTMLElement","getScrollParent","toggleScrollListener","next","prev","handler","prevScrollParent","removeEventListener","scrollParent","addEventListener"],"mappings":"AAAA,SAASA,aAAa,QAAQ,4BAA4B;AAE1D,SAASC,eAAe,QAAQ,oBAAoB;AAEpD;;;;;CAKC,GACD,OAAO,SAASC,qBACdC,IAAoD,EACpDC,IAAoD,EACpDC,OAAsB;IAEtB,IAAIF,SAASC,MAAM;QACjB;IACF;IAEA,IAAIJ,cAAcI,OAAO;QACvB,MAAME,mBAAmBL,gBAAgBG;QACzCE,iBAAiBC,mBAAmB,CAAC,UAAUF;IACjD;IACA,IAAIL,cAAcG,OAAO;QACvB,MAAMK,eAAeP,gBAAgBE;QACrCK,aAAaC,gBAAgB,CAAC,UAAUJ;IAC1C;AACF"}

View File

@@ -0,0 +1,50 @@
'use client';
import * as React from 'react';
import { useIsomorphicLayoutEffect } from '@fluentui/react-utilities';
/**
* Creates a MutableRef with ref change callback. Is useful as React.useRef() doesn't notify you when its content
* changes and mutating the .current property doesn't cause a re-render. An opt-out will be use a callback ref via
* React.useState(), but it will cause re-renders always.
*
* https://reactjs.org/docs/hooks-reference.html#useref
* https://github.com/theKashey/use-callback-ref#usecallbackref---to-replace-reactuseref
*
* @param initialValue - initial ref value
* @param callback - a callback to run when value changes
* @param skipInitialResolve - a flag to skip an initial ref report
*
* @example
* const ref = useCallbackRef(0, (newValue, oldValue) => console.log(oldValue, '->', newValue);
* ref.current = 1;
* // prints 0 -> 1
*/ export function useCallbackRef(initialValue, callback, skipInitialResolve) {
const isFirst = React.useRef(true);
const [ref] = React.useState(()=>({
// value
value: initialValue,
// last callback
callback,
// "memoized" public interface
facade: {
get current () {
return ref.value;
},
set current (value){
const last = ref.value;
if (last !== value) {
ref.value = value;
if (skipInitialResolve && isFirst.current) {
return;
}
ref.callback(value, last);
}
}
}
}));
useIsomorphicLayoutEffect(()=>{
isFirst.current = false;
}, []);
// update callback
ref.callback = callback;
return ref.facade;
}

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../src/utils/useCallbackRef.ts"],"sourcesContent":["'use client';\n\nimport * as React from 'react';\nimport { useIsomorphicLayoutEffect } from '@fluentui/react-utilities';\n\n/**\n * Creates a MutableRef with ref change callback. Is useful as React.useRef() doesn't notify you when its content\n * changes and mutating the .current property doesn't cause a re-render. An opt-out will be use a callback ref via\n * React.useState(), but it will cause re-renders always.\n *\n * https://reactjs.org/docs/hooks-reference.html#useref\n * https://github.com/theKashey/use-callback-ref#usecallbackref---to-replace-reactuseref\n *\n * @param initialValue - initial ref value\n * @param callback - a callback to run when value changes\n * @param skipInitialResolve - a flag to skip an initial ref report\n *\n * @example\n * const ref = useCallbackRef(0, (newValue, oldValue) => console.log(oldValue, '->', newValue);\n * ref.current = 1;\n * // prints 0 -> 1\n */\nexport function useCallbackRef<T>(\n initialValue: T | null,\n callback: (newValue: T | null, lastValue: T | null) => void,\n skipInitialResolve?: boolean,\n // eslint-disable-next-line @typescript-eslint/no-deprecated\n): React.MutableRefObject<T | null> {\n const isFirst = React.useRef(true);\n const [ref] = React.useState(() => ({\n // value\n value: initialValue,\n // last callback\n callback,\n // \"memoized\" public interface\n facade: {\n get current() {\n return ref.value;\n },\n set current(value) {\n const last = ref.value;\n\n if (last !== value) {\n ref.value = value;\n\n if (skipInitialResolve && isFirst.current) {\n return;\n }\n\n ref.callback(value, last);\n }\n },\n },\n }));\n\n useIsomorphicLayoutEffect(() => {\n isFirst.current = false;\n }, []);\n\n // update callback\n ref.callback = callback;\n\n return ref.facade;\n}\n"],"names":["React","useIsomorphicLayoutEffect","useCallbackRef","initialValue","callback","skipInitialResolve","isFirst","useRef","ref","useState","value","facade","current","last"],"mappings":"AAAA;AAEA,YAAYA,WAAW,QAAQ;AAC/B,SAASC,yBAAyB,QAAQ,4BAA4B;AAEtE;;;;;;;;;;;;;;;;CAgBC,GACD,OAAO,SAASC,eACdC,YAAsB,EACtBC,QAA2D,EAC3DC,kBAA4B;IAG5B,MAAMC,UAAUN,MAAMO,MAAM,CAAC;IAC7B,MAAM,CAACC,IAAI,GAAGR,MAAMS,QAAQ,CAAC,IAAO,CAAA;YAClC,QAAQ;YACRC,OAAOP;YACP,gBAAgB;YAChBC;YACA,8BAA8B;YAC9BO,QAAQ;gBACN,IAAIC,WAAU;oBACZ,OAAOJ,IAAIE,KAAK;gBAClB;gBACA,IAAIE,SAAQF,MAAO;oBACjB,MAAMG,OAAOL,IAAIE,KAAK;oBAEtB,IAAIG,SAASH,OAAO;wBAClBF,IAAIE,KAAK,GAAGA;wBAEZ,IAAIL,sBAAsBC,QAAQM,OAAO,EAAE;4BACzC;wBACF;wBAEAJ,IAAIJ,QAAQ,CAACM,OAAOG;oBACtB;gBACF;YACF;QACF,CAAA;IAEAZ,0BAA0B;QACxBK,QAAQM,OAAO,GAAG;IACpB,GAAG,EAAE;IAEL,kBAAkB;IAClBJ,IAAIJ,QAAQ,GAAGA;IAEf,OAAOI,IAAIG,MAAM;AACnB"}

View File

@@ -0,0 +1,13 @@
/**
* Writes all DOM element updates after position is computed
*/ export function writeArrowUpdates(options) {
const { arrow, middlewareData } = options;
if (!middlewareData.arrow || !arrow) {
return;
}
const { x: arrowX, y: arrowY } = middlewareData.arrow;
Object.assign(arrow.style, {
left: arrowX !== null && arrowX !== undefined ? `${arrowX}px` : '',
top: arrowY !== null && arrowY !== undefined ? `${arrowY}px` : ''
});
}

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../src/utils/writeArrowUpdates.ts"],"sourcesContent":["import { MiddlewareData } from '@floating-ui/dom';\n\n/**\n * Writes all DOM element updates after position is computed\n */\nexport function writeArrowUpdates(options: { arrow: HTMLElement | null; middlewareData: MiddlewareData }): void {\n const { arrow, middlewareData } = options;\n if (!middlewareData.arrow || !arrow) {\n return;\n }\n\n const { x: arrowX, y: arrowY } = middlewareData.arrow;\n\n Object.assign(arrow.style, {\n left: arrowX !== null && arrowX !== undefined ? `${arrowX}px` : '',\n top: arrowY !== null && arrowY !== undefined ? `${arrowY}px` : '',\n });\n}\n"],"names":["writeArrowUpdates","options","arrow","middlewareData","x","arrowX","y","arrowY","Object","assign","style","left","undefined","top"],"mappings":"AAEA;;CAEC,GACD,OAAO,SAASA,kBAAkBC,OAAsE;IACtG,MAAM,EAAEC,KAAK,EAAEC,cAAc,EAAE,GAAGF;IAClC,IAAI,CAACE,eAAeD,KAAK,IAAI,CAACA,OAAO;QACnC;IACF;IAEA,MAAM,EAAEE,GAAGC,MAAM,EAAEC,GAAGC,MAAM,EAAE,GAAGJ,eAAeD,KAAK;IAErDM,OAAOC,MAAM,CAACP,MAAMQ,KAAK,EAAE;QACzBC,MAAMN,WAAW,QAAQA,WAAWO,YAAY,GAAGP,OAAO,EAAE,CAAC,GAAG;QAChEQ,KAAKN,WAAW,QAAQA,WAAWK,YAAY,GAAGL,OAAO,EAAE,CAAC,GAAG;IACjE;AACF"}

View File

@@ -0,0 +1,43 @@
import { DATA_POSITIONING_ESCAPED, DATA_POSITIONING_HIDDEN, DATA_POSITIONING_INTERSECTING, DATA_POSITIONING_PLACEMENT } from '../constants';
/**
* Writes all container element position updates after the position is computed
*/ export function writeContainerUpdates(options) {
var _middlewareData_hide, _middlewareData_hide1, _container_ownerDocument_defaultView;
const { container, placement, middlewareData, strategy, lowPPI, coordinates, useTransform = true } = options;
if (!container) {
return;
}
container.setAttribute(DATA_POSITIONING_PLACEMENT, placement);
container.removeAttribute(DATA_POSITIONING_INTERSECTING);
if (middlewareData.intersectionObserver.intersecting) {
container.setAttribute(DATA_POSITIONING_INTERSECTING, '');
}
container.removeAttribute(DATA_POSITIONING_ESCAPED);
if ((_middlewareData_hide = middlewareData.hide) === null || _middlewareData_hide === void 0 ? void 0 : _middlewareData_hide.escaped) {
container.setAttribute(DATA_POSITIONING_ESCAPED, '');
}
container.removeAttribute(DATA_POSITIONING_HIDDEN);
if ((_middlewareData_hide1 = middlewareData.hide) === null || _middlewareData_hide1 === void 0 ? void 0 : _middlewareData_hide1.referenceHidden) {
container.setAttribute(DATA_POSITIONING_HIDDEN, '');
}
// Round so that the coordinates land on device pixels.
// This prevents blurriness in cases where the browser doesn't apply pixel snapping, such as when other effects like
// `backdrop-filter: blur()` are applied to the container, and the browser is zoomed in.
// See https://github.com/microsoft/fluentui/issues/26764 for more info.
const devicePixelRatio = ((_container_ownerDocument_defaultView = container.ownerDocument.defaultView) === null || _container_ownerDocument_defaultView === void 0 ? void 0 : _container_ownerDocument_defaultView.devicePixelRatio) || 1;
const x = Math.round(coordinates.x * devicePixelRatio) / devicePixelRatio;
const y = Math.round(coordinates.y * devicePixelRatio) / devicePixelRatio;
Object.assign(container.style, {
position: strategy
});
if (useTransform) {
Object.assign(container.style, {
transform: lowPPI ? `translate(${x}px, ${y}px)` : `translate3d(${x}px, ${y}px, 0)`
});
return;
}
Object.assign(container.style, {
left: `${x}px`,
top: `${y}px`
});
}

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../src/utils/writeContainerupdates.ts"],"sourcesContent":["import type { Placement, MiddlewareData, Strategy, Coords } from '@floating-ui/dom';\nimport {\n DATA_POSITIONING_ESCAPED,\n DATA_POSITIONING_HIDDEN,\n DATA_POSITIONING_INTERSECTING,\n DATA_POSITIONING_PLACEMENT,\n} from '../constants';\n\n/**\n * Writes all container element position updates after the position is computed\n */\nexport function writeContainerUpdates(options: {\n container: HTMLElement | null;\n placement: Placement;\n middlewareData: MiddlewareData;\n /**\n * Layer acceleration can disable subpixel rendering which causes slightly\n * blurry text on low PPI displays, so we want to use 2D transforms\n * instead\n */\n lowPPI: boolean;\n strategy: Strategy;\n coordinates: Coords;\n useTransform?: boolean;\n}): void {\n const { container, placement, middlewareData, strategy, lowPPI, coordinates, useTransform = true } = options;\n if (!container) {\n return;\n }\n container.setAttribute(DATA_POSITIONING_PLACEMENT, placement);\n container.removeAttribute(DATA_POSITIONING_INTERSECTING);\n if (middlewareData.intersectionObserver.intersecting) {\n container.setAttribute(DATA_POSITIONING_INTERSECTING, '');\n }\n\n container.removeAttribute(DATA_POSITIONING_ESCAPED);\n if (middlewareData.hide?.escaped) {\n container.setAttribute(DATA_POSITIONING_ESCAPED, '');\n }\n\n container.removeAttribute(DATA_POSITIONING_HIDDEN);\n if (middlewareData.hide?.referenceHidden) {\n container.setAttribute(DATA_POSITIONING_HIDDEN, '');\n }\n\n // Round so that the coordinates land on device pixels.\n // This prevents blurriness in cases where the browser doesn't apply pixel snapping, such as when other effects like\n // `backdrop-filter: blur()` are applied to the container, and the browser is zoomed in.\n // See https://github.com/microsoft/fluentui/issues/26764 for more info.\n const devicePixelRatio = container.ownerDocument.defaultView?.devicePixelRatio || 1;\n const x = Math.round(coordinates.x * devicePixelRatio) / devicePixelRatio;\n const y = Math.round(coordinates.y * devicePixelRatio) / devicePixelRatio;\n\n Object.assign(container.style, {\n position: strategy,\n });\n\n if (useTransform) {\n Object.assign(container.style, {\n transform: lowPPI ? `translate(${x}px, ${y}px)` : `translate3d(${x}px, ${y}px, 0)`,\n });\n return;\n }\n\n Object.assign(container.style, {\n left: `${x}px`,\n top: `${y}px`,\n });\n}\n"],"names":["DATA_POSITIONING_ESCAPED","DATA_POSITIONING_HIDDEN","DATA_POSITIONING_INTERSECTING","DATA_POSITIONING_PLACEMENT","writeContainerUpdates","options","middlewareData","container","placement","strategy","lowPPI","coordinates","useTransform","setAttribute","removeAttribute","intersectionObserver","intersecting","hide","escaped","referenceHidden","devicePixelRatio","ownerDocument","defaultView","x","Math","round","y","Object","assign","style","position","transform","left","top"],"mappings":"AACA,SACEA,wBAAwB,EACxBC,uBAAuB,EACvBC,6BAA6B,EAC7BC,0BAA0B,QACrB,eAAe;AAEtB;;CAEC,GACD,OAAO,SAASC,sBAAsBC,OAarC;QAYKC,sBAKAA,uBAQqBC;IAxBzB,MAAM,EAAEA,SAAS,EAAEC,SAAS,EAAEF,cAAc,EAAEG,QAAQ,EAAEC,MAAM,EAAEC,WAAW,EAAEC,eAAe,IAAI,EAAE,GAAGP;IACrG,IAAI,CAACE,WAAW;QACd;IACF;IACAA,UAAUM,YAAY,CAACV,4BAA4BK;IACnDD,UAAUO,eAAe,CAACZ;IAC1B,IAAII,eAAeS,oBAAoB,CAACC,YAAY,EAAE;QACpDT,UAAUM,YAAY,CAACX,+BAA+B;IACxD;IAEAK,UAAUO,eAAe,CAACd;IAC1B,KAAIM,uBAAAA,eAAeW,IAAI,cAAnBX,2CAAAA,qBAAqBY,OAAO,EAAE;QAChCX,UAAUM,YAAY,CAACb,0BAA0B;IACnD;IAEAO,UAAUO,eAAe,CAACb;IAC1B,KAAIK,wBAAAA,eAAeW,IAAI,cAAnBX,4CAAAA,sBAAqBa,eAAe,EAAE;QACxCZ,UAAUM,YAAY,CAACZ,yBAAyB;IAClD;IAEA,uDAAuD;IACvD,oHAAoH;IACpH,wFAAwF;IACxF,wEAAwE;IACxE,MAAMmB,mBAAmBb,EAAAA,uCAAAA,UAAUc,aAAa,CAACC,WAAW,cAAnCf,2DAAAA,qCAAqCa,gBAAgB,KAAI;IAClF,MAAMG,IAAIC,KAAKC,KAAK,CAACd,YAAYY,CAAC,GAAGH,oBAAoBA;IACzD,MAAMM,IAAIF,KAAKC,KAAK,CAACd,YAAYe,CAAC,GAAGN,oBAAoBA;IAEzDO,OAAOC,MAAM,CAACrB,UAAUsB,KAAK,EAAE;QAC7BC,UAAUrB;IACZ;IAEA,IAAIG,cAAc;QAChBe,OAAOC,MAAM,CAACrB,UAAUsB,KAAK,EAAE;YAC7BE,WAAWrB,SAAS,CAAC,UAAU,EAAEa,EAAE,IAAI,EAAEG,EAAE,GAAG,CAAC,GAAG,CAAC,YAAY,EAAEH,EAAE,IAAI,EAAEG,EAAE,MAAM,CAAC;QACpF;QACA;IACF;IAEAC,OAAOC,MAAM,CAACrB,UAAUsB,KAAK,EAAE;QAC7BG,MAAM,GAAGT,EAAE,EAAE,CAAC;QACdU,KAAK,GAAGP,EAAE,EAAE,CAAC;IACf;AACF"}