refactor(controls): move controls into own package and replace in examples
This commit is contained in:
@@ -1,11 +0,0 @@
|
||||
import React from 'react';
|
||||
|
||||
function FitViewIcon() {
|
||||
return (
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 30">
|
||||
<path d="M3.692 4.63c0-.53.4-.938.939-.938h5.215V0H4.708C2.13 0 0 2.054 0 4.63v5.216h3.692V4.631zM27.354 0h-5.2v3.692h5.17c.53 0 .984.4.984.939v5.215H32V4.631A4.624 4.624 0 0027.354 0zm.954 24.83c0 .532-.4.94-.939.94h-5.215v3.768h5.215c2.577 0 4.631-2.13 4.631-4.707v-5.139h-3.692v5.139zm-23.677.94c-.531 0-.939-.4-.939-.94v-5.138H0v5.139c0 2.577 2.13 4.707 4.708 4.707h5.138V25.77H4.631z" />
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
|
||||
export default FitViewIcon;
|
||||
@@ -1,11 +0,0 @@
|
||||
import React from 'react';
|
||||
|
||||
function LockIcon() {
|
||||
return (
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 25 32">
|
||||
<path d="M21.333 10.667H19.81V7.619C19.81 3.429 16.38 0 12.19 0 8 0 4.571 3.429 4.571 7.619v3.048H3.048A3.056 3.056 0 000 13.714v15.238A3.056 3.056 0 003.048 32h18.285a3.056 3.056 0 003.048-3.048V13.714a3.056 3.056 0 00-3.048-3.047zM12.19 24.533a3.056 3.056 0 01-3.047-3.047 3.056 3.056 0 013.047-3.048 3.056 3.056 0 013.048 3.048 3.056 3.056 0 01-3.048 3.047zm4.724-13.866H7.467V7.619c0-2.59 2.133-4.724 4.723-4.724 2.591 0 4.724 2.133 4.724 4.724v3.048z" />
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
|
||||
export default LockIcon;
|
||||
@@ -1,11 +0,0 @@
|
||||
import React from 'react';
|
||||
|
||||
function MinusIcon() {
|
||||
return (
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 5">
|
||||
<path d="M0 0h32v4.2H0z" />
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
|
||||
export default MinusIcon;
|
||||
@@ -1,11 +0,0 @@
|
||||
import React from 'react';
|
||||
|
||||
function PlusIcon() {
|
||||
return (
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
|
||||
<path d="M32 18.133H18.133V32h-4.266V18.133H0v-4.266h13.867V0h4.266v13.867H32z" />
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
|
||||
export default PlusIcon;
|
||||
@@ -1,11 +0,0 @@
|
||||
import React from 'react';
|
||||
|
||||
function UnlockIcon() {
|
||||
return (
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 25 32">
|
||||
<path d="M21.333 10.667H19.81V7.619C19.81 3.429 16.38 0 12.19 0c-4.114 1.828-1.37 2.133.305 2.438 1.676.305 4.42 2.59 4.42 5.181v3.048H3.047A3.056 3.056 0 000 13.714v15.238A3.056 3.056 0 003.048 32h18.285a3.056 3.056 0 003.048-3.048V13.714a3.056 3.056 0 00-3.048-3.047zM12.19 24.533a3.056 3.056 0 01-3.047-3.047 3.056 3.056 0 013.047-3.048 3.056 3.056 0 013.048 3.048 3.056 3.056 0 01-3.048 3.047z" />
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
|
||||
export default UnlockIcon;
|
||||
@@ -1,123 +0,0 @@
|
||||
import React, { memo, FC, useEffect, useState, PropsWithChildren } from 'react';
|
||||
import cc from 'classcat';
|
||||
|
||||
import { useStore, useStoreApi } from '../../store';
|
||||
import useReactFlow from '../../hooks/useReactFlow';
|
||||
|
||||
import PlusIcon from './Icons/Plus';
|
||||
import MinusIcon from './Icons/Minus';
|
||||
import FitviewIcon from './Icons/FitView';
|
||||
import LockIcon from './Icons/Lock';
|
||||
import UnlockIcon from './Icons/Unlock';
|
||||
|
||||
import { ControlProps, ControlButtonProps, ReactFlowState } from '../../types';
|
||||
|
||||
export const ControlButton: FC<PropsWithChildren<ControlButtonProps>> = ({ children, className, ...rest }) => (
|
||||
<button type="button" className={cc(['react-flow__controls-button', className])} {...rest}>
|
||||
{children}
|
||||
</button>
|
||||
);
|
||||
|
||||
const isInteractiveSelector = (s: ReactFlowState) => s.nodesDraggable && s.nodesConnectable && s.elementsSelectable;
|
||||
|
||||
const Controls: FC<PropsWithChildren<ControlProps>> = ({
|
||||
style,
|
||||
showZoom = true,
|
||||
showFitView = true,
|
||||
showInteractive = true,
|
||||
fitViewOptions,
|
||||
onZoomIn,
|
||||
onZoomOut,
|
||||
onFitView,
|
||||
onInteractiveChange,
|
||||
className,
|
||||
children,
|
||||
}) => {
|
||||
const store = useStoreApi();
|
||||
const [isVisible, setIsVisible] = useState<boolean>(false);
|
||||
const isInteractive = useStore(isInteractiveSelector);
|
||||
const { zoomIn, zoomOut, fitView } = useReactFlow();
|
||||
|
||||
useEffect(() => {
|
||||
setIsVisible(true);
|
||||
}, []);
|
||||
|
||||
if (!isVisible) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const onZoomInHandler = () => {
|
||||
zoomIn?.();
|
||||
onZoomIn?.();
|
||||
};
|
||||
|
||||
const onZoomOutHandler = () => {
|
||||
zoomOut?.();
|
||||
onZoomOut?.();
|
||||
};
|
||||
|
||||
const onFitViewHandler = () => {
|
||||
fitView?.(fitViewOptions);
|
||||
onFitView?.();
|
||||
};
|
||||
|
||||
const onToggleInteractivity = () => {
|
||||
store.setState({
|
||||
nodesDraggable: !isInteractive,
|
||||
nodesConnectable: !isInteractive,
|
||||
elementsSelectable: !isInteractive,
|
||||
});
|
||||
|
||||
onInteractiveChange?.(!isInteractive);
|
||||
};
|
||||
|
||||
return (
|
||||
<div className={cc(['react-flow__controls', className])} style={style}>
|
||||
{showZoom && (
|
||||
<>
|
||||
<ControlButton
|
||||
onClick={onZoomInHandler}
|
||||
className="react-flow__controls-zoomin"
|
||||
title="zoom in"
|
||||
aria-label="zoom in"
|
||||
>
|
||||
<PlusIcon />
|
||||
</ControlButton>
|
||||
<ControlButton
|
||||
onClick={onZoomOutHandler}
|
||||
className="react-flow__controls-zoomout"
|
||||
title="zoom out"
|
||||
aria-label="zoom out"
|
||||
>
|
||||
<MinusIcon />
|
||||
</ControlButton>
|
||||
</>
|
||||
)}
|
||||
{showFitView && (
|
||||
<ControlButton
|
||||
className="react-flow__controls-fitview"
|
||||
onClick={onFitViewHandler}
|
||||
title="fit view"
|
||||
aria-label="fit view"
|
||||
>
|
||||
<FitviewIcon />
|
||||
</ControlButton>
|
||||
)}
|
||||
{showInteractive && (
|
||||
<ControlButton
|
||||
className="react-flow__controls-interactive"
|
||||
onClick={onToggleInteractivity}
|
||||
title="toggle interactivity"
|
||||
aria-label="toggle interactivity"
|
||||
>
|
||||
{isInteractive ? <UnlockIcon /> : <LockIcon />}
|
||||
</ControlButton>
|
||||
)}
|
||||
{children}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
Controls.displayName = 'Controls';
|
||||
|
||||
export default memo(Controls);
|
||||
@@ -1,5 +0,0 @@
|
||||
// These components are not used by React Flow directly
|
||||
// They can be added as children of a React Flow component
|
||||
|
||||
export { default as Controls, ControlButton } from './Controls';
|
||||
export { default as ReactFlowProvider } from './ReactFlowProvider';
|
||||
@@ -17,7 +17,6 @@ export {
|
||||
getSimpleBezierCenter as getSimpleBezierEdgeCenter,
|
||||
} from './components/Edges/SimpleBezierEdge';
|
||||
export { default as SmoothStepEdge, getSmoothStepPath } from './components/Edges/SmoothStepEdge';
|
||||
export * from './additional-components';
|
||||
|
||||
export { internalsSymbol } from './utils';
|
||||
export {
|
||||
@@ -33,6 +32,7 @@ export {
|
||||
} from './utils/graph';
|
||||
export { applyNodeChanges, applyEdgeChanges } from './utils/changes';
|
||||
export { getMarkerEnd, getCenter as getEdgeCenter } from './components/Edges/utils';
|
||||
export { default as ReactFlowProvider } from './components/ReactFlowProvider';
|
||||
|
||||
export { default as useReactFlow } from './hooks/useReactFlow';
|
||||
export { default as useUpdateNodeInternals } from './hooks/useUpdateNodeInternals';
|
||||
|
||||
@@ -134,16 +134,3 @@ export interface ReactFlowProps extends HTMLAttributes<HTMLDivElement> {
|
||||
}
|
||||
|
||||
export type ReactFlowRefType = HTMLDivElement;
|
||||
|
||||
export interface ControlProps extends HTMLAttributes<HTMLDivElement> {
|
||||
showZoom?: boolean;
|
||||
showFitView?: boolean;
|
||||
showInteractive?: boolean;
|
||||
fitViewOptions?: FitViewOptions;
|
||||
onZoomIn?: () => void;
|
||||
onZoomOut?: () => void;
|
||||
onFitView?: () => void;
|
||||
onInteractiveChange?: (interactiveStatus: boolean) => void;
|
||||
}
|
||||
|
||||
export interface ControlButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {}
|
||||
|
||||
Reference in New Issue
Block a user