import React, { memo, FC, useEffect, useState, useRef } from 'react'; import cc from 'classcat'; import { useStore } from '../../store'; import { createGridLinesPath, createGridDotsPath } from './utils'; import { BackgroundVariant, ReactFlowState, BackgroundProps } from '../../types'; const defaultColors = { [BackgroundVariant.Dots]: '#81818a', [BackgroundVariant.Lines]: '#eee', }; const transformSelector = (s: ReactFlowState) => s.transform; const Background: FC = ({ variant = BackgroundVariant.Dots, gap = 15, size = 0.4, color, style, className, }) => { const ref = useRef(null); const [patternId, setPatternId] = useState(null); const [x, y, scale] = useStore(transformSelector); useEffect(() => { // when there are multiple flows on a page we need to make sure that every background gets its own pattern. const bgs = document.querySelectorAll('.react-flow__background'); const index = Array.from(bgs).findIndex((bg) => bg === ref.current); setPatternId(`pattern-${index}`); }, []); const bgClasses = cc(['react-flow__background', 'react-flow__container', className]); const scaledGap = gap * scale; const xOffset = x % scaledGap; const yOffset = y % scaledGap; const isLines = variant === BackgroundVariant.Lines; const bgColor = color ? color : defaultColors[variant]; const path = isLines ? createGridLinesPath(scaledGap, size, bgColor) : createGridDotsPath(size * scale, bgColor); return ( {patternId && ( <> {path} )} ); }; Background.displayName = 'Background'; export default memo(Background);