import { Block, Source, Step, Table, Target } from 'models' import { createContext, Dispatch, MutableRefObject, ReactNode, SetStateAction, useContext, useState, } from 'react' export const stubLength = 20 export const blockWidth = 300 export const blockAnchorsOffset = { left: { x: 0, y: 20, }, top: { x: blockWidth / 2, y: 0, }, right: { x: blockWidth, y: 20, }, } export type Coordinates = { x: number; y: number } type Position = Coordinates & { scale: number } export type Anchor = { coordinates: Coordinates } export type Node = Omit & { steps: (Step & { sourceAnchorsPosition: { left: Coordinates; right: Coordinates } })[] } const graphPositionDefaultValue = { x: 400, y: 100, scale: 1 } export type ConnectingIds = { source: Source target?: Target } type StepId = string type NodeId = string export type Endpoint = { id: StepId | NodeId ref: MutableRefObject } const graphContext = createContext<{ graphPosition: Position setGraphPosition: Dispatch> connectingIds: ConnectingIds | null setConnectingIds: Dispatch> previewingEdgeId?: string setPreviewingEdgeId: Dispatch> sourceEndpoints: Table addSourceEndpoint: (endpoint: Endpoint) => void targetEndpoints: Table addTargetEndpoint: (endpoint: Endpoint) => void // eslint-disable-next-line @typescript-eslint/ban-ts-comment //@ts-ignore }>({ graphPosition: graphPositionDefaultValue, connectingIds: null, }) export const GraphProvider = ({ children }: { children: ReactNode }) => { const [graphPosition, setGraphPosition] = useState(graphPositionDefaultValue) const [connectingIds, setConnectingIds] = useState(null) const [previewingEdgeId, setPreviewingEdgeId] = useState() const [sourceEndpoints, setSourceEndpoints] = useState>({ byId: {}, allIds: [], }) const [targetEndpoints, setTargetEndpoints] = useState>({ byId: {}, allIds: [], }) const addSourceEndpoint = (endpoint: Endpoint) => { setSourceEndpoints((endpoints) => ({ byId: { ...endpoints.byId, [endpoint.id]: endpoint }, allIds: [...endpoints.allIds, endpoint.id], })) } const addTargetEndpoint = (endpoint: Endpoint) => { setTargetEndpoints((endpoints) => ({ byId: { ...endpoints.byId, [endpoint.id]: endpoint }, allIds: [...endpoints.allIds, endpoint.id], })) } return ( {children} ) } export const useGraph = () => useContext(graphContext)