Fix incorrect tooltip position after window resize

This commit fixes an issue where the tooltip position becomes inaccurate
after resizing the window.

The solution uses `autoUpdate` functionality of `floating-ui` to update
the position automatically on resize events. This function depends on
browser APIs: `IntersectionObserver` and `ResizeObserver`. The official
documentation recommends polyfilling those to support old browsers.

Polyfilling `ResizeObserver` is already part of the codebase, used by
`SizeObserver.vue`. This commit refactors polyfill logic to be reusable
across different components, and reuses it on `TooltipWrapper.vue`.

Polyfilling `IntersectionObserver` is ignored due to this API being
older and more widely supported.
This commit is contained in:
undergroundwires
2023-10-27 20:58:07 +02:00
parent f4a74f058d
commit f8e5f1a5a2
3 changed files with 40 additions and 14 deletions

View File

@@ -8,6 +8,7 @@
import {
defineComponent, ref, onMounted, onBeforeUnmount,
} from 'vue';
import { useResizeObserverPolyfill } from '@/presentation/components/Shared/Hooks/UseResizeObserverPolyfill';
export default defineComponent({
emits: {
@@ -18,18 +19,22 @@ export default defineComponent({
/* eslint-enable @typescript-eslint/no-unused-vars */
},
setup(_, { emit }) {
const { resizeObserverReady } = useResizeObserverPolyfill();
const containerElement = ref<HTMLElement>();
let width = 0;
let height = 0;
let observer: ResizeObserver;
onMounted(async () => {
onMounted(() => {
width = containerElement.value.offsetWidth;
height = containerElement.value.offsetHeight;
observer = await initializeResizeObserver(updateSize);
observer.observe(containerElement.value);
resizeObserverReady.then(() => {
observer = new ResizeObserver(updateSize);
observer.observe(containerElement.value);
});
fireChangeEvents();
});
@@ -38,16 +43,6 @@ export default defineComponent({
observer?.disconnect();
});
async function initializeResizeObserver(
callback: ResizeObserverCallback,
): Promise<ResizeObserver> {
if ('ResizeObserver' in window) {
return new window.ResizeObserver(callback);
}
const module = await import('@juggle/resize-observer');
return new module.ResizeObserver(callback);
}
function updateSize() {
let sizeChanged = false;
if (isWidthChanged()) {