Floating layers
Every popup, menu, tooltip and dialog of the library is portaled out to <body>. Its DOM is elsewhere, but its React events still bubble through the tree it was declared in. A canvas that treats a pointer event as its own needs to tell the two apart.
tsx
import { cameThroughPortal, isInFloatingLayer } from '@basmilius/react-ui';tsx
import { useState, type PointerEvent } from 'react';
import { Button, Menu, isInFloatingLayer } from '@basmilius/react-ui';
export default function FloatingLayersDemo() {
const [clicks, setClicks] = useState(0);
const onPointerDown = (event: PointerEvent<HTMLDivElement>): void => {
// A popup is portaled out of this box, yet its events still bubble here through React.
if (isInFloatingLayer(event.target)) {
return;
}
setClicks((count) => count + 1);
};
return (
<div onPointerDown={onPointerDown} className="grid h-44 w-full max-w-md place-items-center rounded-lg border border-dashed border-border-strong">
<div className="flex flex-col items-center gap-2 text-xs text-text-muted">
The canvas took {clicks} clicks.
<Menu.Root>
<Menu.Trigger render={<Button variant="secondary" size="sm" />}>Open a menu</Menu.Trigger>
<Menu.Popup>
<Menu.Item>A click in here is not the canvas's</Menu.Item>
</Menu.Popup>
</Menu.Root>
</div>
</div>
);
}isInFloatingLayer(target) says whether an event's target lies in a popup, a tooltip or a dialog of the library, rather than on the surface under it. Clicking the menu row above does not count as a click on the canvas.
cameThroughPortal(event) says whether an event reached currentTarget through a portal, with its target inside the element in React's tree but not in the DOM. Use it for a handler that should only hear events from its own DOM.