import React, { memo, useCallback, HTMLAttributes, FC, useEffect, useState } from 'react'; import cc from 'classcat'; import { useStore } from '../../store'; import PlusIcon from '../../../assets/icons/plus.svg'; import MinusIcon from '../../../assets/icons/minus.svg'; import FitviewIcon from '../../../assets/icons/fitview.svg'; import LockIcon from '../../../assets/icons/lock.svg'; import UnlockIcon from '../../../assets/icons/unlock.svg'; import useZoomPanHelper from '../../hooks/useZoomPanHelper'; import { FitViewParams, ReactFlowState } from '../../types'; export interface ControlProps extends HTMLAttributes { showZoom?: boolean; showFitView?: boolean; showInteractive?: boolean; fitViewParams?: FitViewParams; onZoomIn?: () => void; onZoomOut?: () => void; onFitView?: () => void; onInteractiveChange?: (interactiveStatus: boolean) => void; } export interface ControlButtonProps extends HTMLAttributes {} export const ControlButton: FC = ({ children, className, ...rest }) => ( ); const setInteractiveSelector = (s: ReactFlowState) => s.setInteractive; const isInteractiveSelector = (s: ReactFlowState) => s.nodesDraggable && s.nodesConnectable && s.elementsSelectable; const Controls: FC = ({ style, showZoom = true, showFitView = true, showInteractive = true, fitViewParams, onZoomIn, onZoomOut, onFitView, onInteractiveChange, className, children, }) => { const [isVisible, setIsVisible] = useState(false); const setInteractive = useStore(setInteractiveSelector); const isInteractive = useStore(isInteractiveSelector); const { zoomIn, zoomOut, fitView } = useZoomPanHelper(); const mapClasses = cc(['react-flow__controls', className]); const onZoomInHandler = useCallback(() => { zoomIn?.(); onZoomIn?.(); }, [zoomIn, onZoomIn]); const onZoomOutHandler = useCallback(() => { zoomOut?.(); onZoomOut?.(); }, [zoomOut, onZoomOut]); const onFitViewHandler = useCallback(() => { fitView?.(fitViewParams); onFitView?.(); }, [fitView, fitViewParams, onFitView]); const onInteractiveChangeHandler = useCallback(() => { setInteractive?.(!isInteractive); onInteractiveChange?.(!isInteractive); }, [isInteractive, setInteractive, onInteractiveChange]); useEffect(() => { setIsVisible(true); }, []); if (!isVisible) { return null; } return (
{showZoom && ( <> )} {showFitView && ( )} {showInteractive && ( {isInteractive ? : } )} {children}
); }; Controls.displayName = 'Controls'; export default memo(Controls);