// Copyright: Ankitects Pty Ltd and contributors
// License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
import type { FloatingElement, ReferenceElement } from "@floating-ui/dom";
import { autoUpdate as floatingUiAutoUpdate } from "@floating-ui/dom";
import type { ActionReturn } from "svelte/action";
import type { Callback } from "../../lib/typing";
/**
* The interface of `autoUpdate` of floating-ui.
* This means PositioningCallback can be used with that, but also invoked as it is.
*
* @example ```
* // Invoke the positioning algorithm handily
* position(myReference, (_, _, callback) => {
* callback();
* })`
*/
export type PositioningCallback = (
reference: ReferenceElement,
floating: FloatingElement,
position: Callback,
) => Callback;
* The interface of a function that calls `computePosition` of floating-ui.
export type PositionFunc = (
callback: PositioningCallback,
function autoUpdate(
* The method to position the floating element.
position: PositionFunc,
): ActionReturn<PositionFunc> {
let cleanup: Callback;
function destroy() {
cleanup?.();
}
function update(position: PositionFunc): void {
destroy();
cleanup = position(reference, floatingUiAutoUpdate);
update(position);
return { destroy, update };
export default autoUpdate;