Skip to content

Commit

Permalink
Merge pull request #228 from reaviz/floating-ui-virtual-el
Browse files Browse the repository at this point in the history
Add supporting virtual element via FloatingUI
  • Loading branch information
amcdnl authored Jun 12, 2024
2 parents a238507 + 6d5003e commit 6856672
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ export const ConnectedOverlayContent: FC<
const id = useId();
const [overlayIndex, setOverlayIndex] = useState<number | null>(null);
const { refs, floatingStyles, update } = usePosition({
reference: triggerRef.current,
reference: triggerRef.current ?? triggerRef,
followCursor,
modifiers,
placement
Expand Down
37 changes: 34 additions & 3 deletions src/utils/Position/usePosition.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
import { useLayoutEffect, RefObject, useCallback } from 'react';
import {
useLayoutEffect,
RefObject,
useCallback,
useEffect,
useMemo
} from 'react';
import {
useFloating,
Placement as FloatingUIPlacement,
Expand All @@ -24,7 +30,7 @@ export interface ReferenceObject {
}

export interface PositionOptions {
reference?: Element;
reference?: Element | ReferenceObject;
floating?: HTMLElement;
placement?: Placement;
modifiers?: Modifiers;
Expand All @@ -40,16 +46,41 @@ export const usePosition = ({
placement = 'top',
modifiers = [flip(), shift({ limiter: limitShift() })]
}: PositionOptions = {}) => {
const isVirtualElement = useMemo(
() => !(reference as Element)?.nodeType,
[reference]
);

const { refs, floatingStyles, update } = useFloating({
open: true,
placement,
middleware: modifiers,
elements: {
reference: reference,
reference: isVirtualElement ? null : (reference as Element),
floating: floating
}
});

useEffect(() => {
if (isVirtualElement) {
const refObject = reference as ReferenceObject;
refs.setPositionReference({
getBoundingClientRect() {
return {
width: refObject.width,
height: refObject.height,
x: refObject.left,
y: refObject.top,
left: refObject.left,
top: refObject.top,
right: refObject.left + refObject.width,
bottom: refObject.top + refObject.height
};
}
});
}
}, [reference, refs, isVirtualElement]);

const onMouseMove = useCallback(
({ pageX, pageY }: MouseEvent) => {
// Virtual reference object for cursor position.
Expand Down

0 comments on commit 6856672

Please sign in to comment.