UNPKG

@gravity-ui/graph

Version:

Modern graph editor component

41 lines (40 loc) 1.9 kB
import React, { useEffect, useMemo } from "react"; import { useSignal } from "./hooks"; import { useBlockAnchorPosition, useBlockAnchorState } from "./hooks/useBlockAnchorState"; import { cn } from "./utils/cn"; import "./Anchor.css"; export function GraphBlockAnchor({ graph, anchor, position = "fixed", children, className, }) { const anchorContainerRef = React.useRef(null); const anchorState = useBlockAnchorState(graph, anchor); const selected = useSignal(anchorState?.$selected); const [raised, setRaised] = React.useState(false); useBlockAnchorPosition(anchorState, anchorContainerRef); const classNames = useMemo(() => { return cn("graph-block-anchor", `graph-block-anchor-${anchor.type.toLocaleLowerCase()}`, `graph-block-position-${position}`, { "graph-block-anchor-raised": raised, "graph-block-anchor-selected": selected, }, className); }, [anchor?.type, position, className, selected, raised]); useEffect(() => { const component = anchorState?.getViewComponent(); if (!component) { return () => { }; } return component.onChange(() => { setRaised(component.state.raised); }); }, [anchorState]); useEffect(() => { if (anchorContainerRef.current) { const viewComponent = anchorState?.getViewComponent(); const hoverScale = viewComponent?.getHoverFactor(); if (hoverScale !== undefined) { anchorContainerRef.current.style.setProperty("--graph-block-anchor-hover-scale", hoverScale.toString()); } } }, [anchorState?.$selected.value]); if (!anchorState) return null; const layout = typeof children === "function" ? children(anchorState) : children; return (React.createElement("div", { ref: anchorContainerRef, className: classNames }, layout)); }