// 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 = ( reference: ReferenceElement, callback: PositioningCallback, ) => Callback; function autoUpdate( reference: ReferenceElement, /** * The method to position the floating element. */ position: PositionFunc, ): ActionReturn { let cleanup: Callback; function destroy() { cleanup?.(); } function update(position: PositionFunc): void { destroy(); cleanup = position(reference, floatingUiAutoUpdate); } update(position); return { destroy, update }; } export default autoUpdate;