mirror of
https://github.com/sissbruecker/linkding.git
synced 2026-02-27 22:43:15 +08:00
72 lines
1.7 KiB
JavaScript
72 lines
1.7 KiB
JavaScript
import {
|
|
arrow,
|
|
autoUpdate,
|
|
computePosition,
|
|
flip,
|
|
offset,
|
|
shift,
|
|
} from "@floating-ui/dom";
|
|
|
|
export class PositionController {
|
|
constructor(options) {
|
|
this.anchor = options.anchor;
|
|
this.overlay = options.overlay;
|
|
this.arrow = options.arrow;
|
|
this.placement = options.placement || "bottom";
|
|
this.offset = options.offset;
|
|
this.autoWidth = options.autoWidth || false;
|
|
this.autoUpdateCleanup = null;
|
|
}
|
|
|
|
enable() {
|
|
if (!this.autoUpdateCleanup) {
|
|
this.autoUpdateCleanup = autoUpdate(this.anchor, this.overlay, () =>
|
|
this.updatePosition(),
|
|
);
|
|
}
|
|
}
|
|
|
|
disable() {
|
|
if (this.autoUpdateCleanup) {
|
|
this.autoUpdateCleanup();
|
|
this.autoUpdateCleanup = null;
|
|
}
|
|
}
|
|
|
|
updatePosition() {
|
|
const middleware = [flip(), shift()];
|
|
if (this.arrow) {
|
|
middleware.push(arrow({ element: this.arrow }));
|
|
}
|
|
if (this.offset) {
|
|
middleware.push(offset(this.offset));
|
|
}
|
|
computePosition(this.anchor, this.overlay, {
|
|
placement: this.placement,
|
|
strategy: "fixed",
|
|
middleware,
|
|
}).then(({ x, y, placement, middlewareData }) => {
|
|
Object.assign(this.overlay.style, {
|
|
left: `${x}px`,
|
|
top: `${y}px`,
|
|
});
|
|
|
|
this.overlay.classList.remove("top-aligned", "bottom-aligned");
|
|
this.overlay.classList.add(`${placement}-aligned`);
|
|
|
|
if (this.arrow) {
|
|
const { x, y } = middlewareData.arrow;
|
|
Object.assign(this.arrow.style, {
|
|
left: x != null ? `${x}px` : "",
|
|
top: y != null ? `${y}px` : "",
|
|
});
|
|
}
|
|
});
|
|
|
|
if (this.autoWidth) {
|
|
const width = this.anchor.offsetWidth;
|
|
this.overlay.style.width = `${width}px`;
|
|
}
|
|
}
|
|
}
|