diff --git a/src/components/grid_overlay/grid_overlay.ts b/src/components/grid_overlay/grid_overlay.ts index 5f2c02929d..99447d5990 100644 --- a/src/components/grid_overlay/grid_overlay.ts +++ b/src/components/grid_overlay/grid_overlay.ts @@ -9,6 +9,7 @@ import { SpreadsheetChildEnv, } from "../../types"; import { FiguresContainer } from "../figures/figure_container/figure_container"; +import { useRefListener } from "../helpers/listener_hook"; import { useInterval } from "../helpers/time_hooks"; function useCellHovered( @@ -59,21 +60,10 @@ function useCellHovered( } } - onMounted(() => { - const grid = gridRef.el!; - grid.addEventListener("mousemove", updateMousePosition); - grid.addEventListener("mouseleave", pause); - grid.addEventListener("mouseenter", resume); - grid.addEventListener("mousedown", recompute); - }); - - onWillUnmount(() => { - const grid = gridRef.el!; - grid.removeEventListener("mousemove", updateMousePosition); - grid.removeEventListener("mouseleave", pause); - grid.removeEventListener("mouseenter", resume); - grid.removeEventListener("mousedown", recompute); - }); + useRefListener(gridRef, "mousemove", updateMousePosition); + useRefListener(gridRef, "mouseleave", pause); + useRefListener(gridRef, "mouseenter", resume); + useRefListener(gridRef, "mousedown", recompute); function setPosition(col?: number, row?: number) { if (col !== hoveredPosition.col || row !== hoveredPosition.row) { @@ -120,17 +110,9 @@ function useTouchMove( y = currentY; } - onMounted(() => { - gridRef.el!.addEventListener("touchstart", onTouchStart); - gridRef.el!.addEventListener("touchend", onTouchEnd); - gridRef.el!.addEventListener("touchmove", onTouchMove); - }); - - onWillUnmount(() => { - gridRef.el!.removeEventListener("touchstart", onTouchStart); - gridRef.el!.removeEventListener("touchend", onTouchEnd); - gridRef.el!.removeEventListener("touchmove", onTouchMove); - }); + useRefListener(gridRef, "touchstart", onTouchStart); + useRefListener(gridRef, "touchend", onTouchEnd); + useRefListener(gridRef, "touchmove", onTouchMove); } interface Props { diff --git a/src/components/helpers/listener_hook.ts b/src/components/helpers/listener_hook.ts new file mode 100644 index 0000000000..6399fbc54e --- /dev/null +++ b/src/components/helpers/listener_hook.ts @@ -0,0 +1,23 @@ +import { useEffect } from "@odoo/owl"; +import { Ref } from "../../types"; + +/** + * Manages an event listener on a ref. Useful for hooks that want to manage + * event listeners, especially more than one. Prefer using t-on directly in + * components. If your hook only needs a single event listener, consider simply + * returning it from the hook and letting the user attach it with t-on. + * + * Adapted from Odoo Community - See https://github.com/odoo/odoo/blob/saas-16.2/addons/web/static/src/core/utils/hooks.js + */ +export function useRefListener( + ref: Ref, + ...listener: Parameters +) { + useEffect( + (el: HTMLElement | null) => { + el?.addEventListener(...listener); + return () => el?.removeEventListener(...listener); + }, + () => [ref.el] + ); +}