Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"type": "minor",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would say that it's a patch, as we didn't bring anything new

"comment": "feat: Upgrade to Floating UI v1",
"packageName": "@fluentui/react-positioning",
"email": "[email protected]",
"dependentChangeType": "patch"
}
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@ describe('Menu', () => {

beforeEach(() => {
resetIdsForTests();
jest.useRealTimers();
});

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -111,8 +111,8 @@ export function resolvePositioningShorthand(shorthand: PositioningShorthand | un

// Warning: (ae-internal-missing-underscore) The name "usePositioning" should be prefixed with an underscore because the declaration is marked as @internal
//
// @internal
export function usePositioning(options?: UsePopperOptions): {
// @internal (undocumented)
export function usePositioning(options: UsePositioningOptions): {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It was not public before, are we making it public?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good catch 👍

targetRef: React_2.MutableRefObject<any>;
containerRef: React_2.MutableRefObject<any>;
arrowRef: React_2.MutableRefObject<any>;
Expand Down
4 changes: 2 additions & 2 deletions packages/react-components/react-positioning/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,11 @@
"@fluentui/scripts": "^1.0.0"
},
"dependencies": {
"@griffel/react": "^1.3.0",
"@floating-ui/dom": "^1.0.0",
"@fluentui/react-shared-contexts": "^9.0.0",
"@fluentui/react-theme": "^9.0.0",
"@fluentui/react-utilities": "^9.0.2",
"@popperjs/core": "~2.4.3",
"@griffel/react": "^1.3.0",
"tslib": "^2.1.0"
},
"peerDependencies": {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export const DATA_POSITIONING_INTERSECTING = 'data-popper-is-intersecting';
export const DATA_POSITIONING_ESCAPED = 'data-popper-escaped';
export const DATA_POSITIONING_HIDDEN = 'data-popper-reference-hidden';
export const DATA_POSITIONING_PLACEMENT = 'data-popper-placement';

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import type { Middleware } from '@floating-ui/dom';
import { parseFloatingUIPlacement } from '../utils/index';

export function coverTarget(): Middleware {
return {
name: 'coverTarget',
fn: middlewareArguments => {
const { placement, rects, x, y } = middlewareArguments;
const basePlacement = parseFloatingUIPlacement(placement).side;
const newCoords = { x, y };

switch (basePlacement) {
case 'bottom':
newCoords.y -= rects.reference.height;
break;
case 'top':
newCoords.y += rects.reference.height;
break;
case 'left':
newCoords.x += rects.reference.width;
break;
case 'right':
newCoords.x -= rects.reference.width;
break;
}

return newCoords;
},
};
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { flip as baseFlip } from '@floating-ui/dom';
import type { PositioningOptions } from '../types';
import { getBoundary } from '../utils/index';

export interface FlipMiddlewareOptions extends Pick<PositioningOptions, 'flipBoundary'> {
hasScrollableElement?: boolean;
container: HTMLElement | null;
}

export function flip(options: FlipMiddlewareOptions) {
const { hasScrollableElement, flipBoundary, container } = options;

return baseFlip({
...(hasScrollableElement && { boundary: 'clippingAncestors' }),
...(flipBoundary && { altBoundary: true, boundary: getBoundary(container, flipBoundary) }),
fallbackStrategy: 'bestFit',
});
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
export * from './coverTarget';
export * from './flip';
export * from './intersecting';
export * from './maxSize';
export * from './offset';
export * from './shift';
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import type { Middleware } from '@floating-ui/dom';
import { detectOverflow } from '@floating-ui/dom';

export function intersecting(): Middleware {
return {
name: 'intersectionObserver',
fn: async middlewareArguments => {
const floatingRect = middlewareArguments.rects.floating;
const altOverflow = await detectOverflow(middlewareArguments, { altBoundary: true });

const isIntersectingTop = altOverflow.top < floatingRect.height && altOverflow.top > 0;
const isIntersectingBottom = altOverflow.bottom < floatingRect.height && altOverflow.bottom > 0;

const isIntersecting = isIntersectingTop || isIntersectingBottom;

return {
data: {
intersecting: isIntersecting,
},
};
},
};
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import { detectOverflow } from '@floating-ui/dom';
import type { Middleware, Side } from '@floating-ui/dom';
import type { PositioningOptions } from '../types';
import { parseFloatingUIPlacement } from '../utils/index';

export function maxSize(autoSize: PositioningOptions['autoSize']): Middleware {
return {
name: 'maxSize',
fn: async middlewareArguments => {
const { placement, rects, elements, middlewareData } = middlewareArguments;
const basePlacement = parseFloatingUIPlacement(placement).side;

const overflow = await detectOverflow(middlewareArguments);
const { x, y } = middlewareData.shift || { x: 0, y: 0 };
const { width, height } = rects.floating;

const widthProp: Side = basePlacement === 'left' ? 'left' : 'right';
const heightProp: Side = basePlacement === 'top' ? 'top' : 'bottom';

const applyMaxWidth =
autoSize === 'always' ||
autoSize === 'width-always' ||
(overflow[widthProp] > 0 && (autoSize === true || autoSize === 'width'));
const applyMaxHeight =
autoSize === 'always' ||
autoSize === 'height-always' ||
(overflow[heightProp] > 0 && (autoSize === true || autoSize === 'height'));

if (applyMaxWidth) {
elements.floating.style.maxWidth = `${width - overflow[widthProp] - x}px`;
}
if (applyMaxHeight) {
elements.floating.style.maxHeight = `${height - overflow[heightProp] - y}px`;
}

return {};
},
};
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { offset as baseOffset } from '@floating-ui/dom';
import type { PositioningOptions } from '../types';
import { getFloatingUIOffset } from '../utils/getFloatingUIOffset';

/**
* Wraps floating UI offset middleware to to transform offset value
*/
export function offset(offsetValue: PositioningOptions['offset']) {
const floatingUIOffset = getFloatingUIOffset(offsetValue);
return baseOffset(floatingUIOffset);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { shift as baseShift, limitShift } from '@floating-ui/dom';
import type { PositioningOptions } from '../types';
import { getBoundary } from '../utils/index';

export interface ShiftMiddlewareOptions extends Pick<PositioningOptions, 'overflowBoundary'> {
hasScrollableElement?: boolean;
disableTether?: PositioningOptions['unstable_disableTether'];
container: HTMLElement | null;
}

/**
* Wraps the floating UI shift middleware for easier usage of our options
*/
export function shift(options: ShiftMiddlewareOptions) {
const { hasScrollableElement, disableTether, overflowBoundary, container } = options;

return baseShift({
...(hasScrollableElement && { boundary: 'clippingAncestors' }),
...(disableTether && {
crossAxis: disableTether === 'all',
limiter: limitShift({ crossAxis: disableTether !== 'all', mainAxis: false }),
}),
...(overflowBoundary && { altBoundary: true, boundary: getBoundary(container, overflowBoundary) }),
});
}
Loading