@gravity-ui/graph
Version:
Modern graph editor component
65 lines (64 loc) • 1.97 kB
JavaScript
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]);
}