anki/ts/sveltelib/position/position-overlay.ts
Matthias Metelka a48c96559d
Fix glitchy animation of floating elements (#2224)
* Set max-height of 400px to scrollable Popover

* Pass computed placement to user components

to set different animation directions when the placement changes.

* Move elevation effect from WithFloating/WithOverlay to Popover

* Apply same changes as in WithFloating to WithOverlay

* Adjust FloatingArrow CSS to Popover

* Run eslint and formatter
2022-12-01 15:45:52 +10:00

66 lines
1.7 KiB
TypeScript

// Copyright: Ankitects Pty Ltd and contributors
// License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
import type { ComputePositionConfig, FloatingElement, Middleware, Placement, ReferenceElement } from "@floating-ui/dom";
import { computePosition, inline, offset } from "@floating-ui/dom";
import type { PositionAlgorithm } from "./position-algorithm";
export interface PositionOverlayArgs {
padding: number;
inline: boolean;
hideCallback: (reason: string) => void;
}
function positionOverlay({
padding,
inline: inlineArg,
hideCallback,
}: PositionOverlayArgs): PositionAlgorithm {
return async function(
reference: ReferenceElement,
floating: FloatingElement,
): Promise<Placement> {
const middleware: Middleware[] = inlineArg ? [inline()] : [];
const { width, height } = reference.getBoundingClientRect();
middleware.push(
offset({
mainAxis: -(height + padding),
}),
);
const computeArgs: Partial<ComputePositionConfig> = {
middleware,
};
const { x, y, middlewareData, placement } = await computePosition(
reference,
floating,
computeArgs,
);
// console.log(x, y)
if (middlewareData.hide?.escaped) {
hideCallback("escaped");
}
if (middlewareData.hide?.referenceHidden) {
hideCallback("referenceHidden");
}
Object.assign(floating.style, {
left: `${x}px`,
top: `${y}px`,
width: `${width + 2 * padding}px`,
height: `${height + 2 * padding}px`,
});
return placement;
};
}
export default positionOverlay;