UNPKG

@gravity-ui/graph

Version:

Modern graph editor component

65 lines (64 loc) 1.97 kB
import { useLayoutEffect, useMemo, useRef } from "react"; import { ESchedulerPriority } from "../../lib"; import { debounce } from "../../utils/utils/schedule"; import { GraphCallbacksMap } from "../events"; import { useFn } from "../utils/hooks/useFn"; export function useGraphEvent(graph, event, cb, debounceParams) { const lastEventRef = useRef(null); const fn = useMemo(() => { const invoke = () => { const lastEvent = lastEventRef.current; if (!lastEvent) { return; } cb(lastEvent.detail, lastEvent); }; if (!debounceParams) { return invoke; } return debounce(invoke, { priority: ESchedulerPriority.MEDIUM, frameInterval: 1, frameTimeout: 0, ...debounceParams, }); }, [cb, debounceParams]); const onEvent = useFn((e) => { lastEventRef.current = e; fn(); }); useLayoutEffect(() => { if (!graph) return undefined; return graph.on(event, onEvent); }, [graph, event, onEvent]); useLayoutEffect(() => { return () => { fn.cancel?.(); }; }, [fn]); } export function useGraphEvents(graph, events) { useLayoutEffect(() => { if (!graph) return undefined; const unsubscribe = []; const subscribe = (key, cb) => { const eventName = GraphCallbacksMap[key]; return graph.on(eventName, (event) => { cb(event.detail, event); }); }; const eventKeys = Object.keys(events); eventKeys.forEach((key) => { const cb = events[key]; if (!cb) { return; } unsubscribe.push(subscribe(key, cb)); }); return () => { unsubscribe.forEach((unsubscribe) => unsubscribe()); }; }, [graph, events]); }