feat(components): Support passing shadow root as document

This commit is contained in:
Przemysław Żydek
2021-03-22 11:34:47 +01:00
parent e3cdecbafe
commit 96290483b1
9 changed files with 36 additions and 9 deletions
+12 -8
View File
@@ -31,7 +31,8 @@ function checkElementBelowIsValid(
isTarget: boolean, isTarget: boolean,
nodeId: ElementId, nodeId: ElementId,
handleId: ElementId | null, handleId: ElementId | null,
isValidConnection: ValidConnectionFunc isValidConnection: ValidConnectionFunc,
document: Document | ShadowRoot
) { ) {
const elementBelow = document.elementFromPoint(event.clientX, event.clientY); const elementBelow = document.elementFromPoint(event.clientX, event.clientY);
const elementBelowIsTarget = elementBelow?.classList.contains('target') || false; const elementBelowIsTarget = elementBelow?.classList.contains('target') || false;
@@ -95,7 +96,8 @@ export function onMouseDown(
connectionMode: ConnectionMode, connectionMode: ConnectionMode,
onConnectStart?: OnConnectStartFunc, onConnectStart?: OnConnectStartFunc,
onConnectStop?: OnConnectStopFunc, onConnectStop?: OnConnectStopFunc,
onConnectEnd?: OnConnectEndFunc onConnectEnd?: OnConnectEndFunc,
document: Document | ShadowRoot = window.document
): void { ): void {
const reactFlowNode = (event.target as Element).closest('.react-flow'); const reactFlowNode = (event.target as Element).closest('.react-flow');
const elementBelow = document.elementFromPoint(event.clientX, event.clientY); const elementBelow = document.elementFromPoint(event.clientX, event.clientY);
@@ -131,7 +133,8 @@ export function onMouseDown(
isTarget, isTarget,
nodeId, nodeId,
handleId, handleId,
isValidConnection isValidConnection,
document
); );
if (!isHoveringHandle) { if (!isHoveringHandle) {
@@ -154,7 +157,8 @@ export function onMouseDown(
isTarget, isTarget,
nodeId, nodeId,
handleId, handleId,
isValidConnection isValidConnection,
document
); );
onConnectStop?.(event); onConnectStop?.(event);
@@ -168,10 +172,10 @@ export function onMouseDown(
resetRecentHandle(recentHoveredHandle); resetRecentHandle(recentHoveredHandle);
setConnectionNodeId({ connectionNodeId: null, connectionHandleId: null, connectionHandleType: null }); setConnectionNodeId({ connectionNodeId: null, connectionHandleId: null, connectionHandleType: null });
document.removeEventListener('mousemove', onMouseMove); document.removeEventListener('mousemove', onMouseMove as EventListenerOrEventListenerObject);
document.removeEventListener('mouseup', onMouseUp); document.removeEventListener('mouseup', onMouseUp as EventListenerOrEventListenerObject);
} }
document.addEventListener('mousemove', onMouseMove); document.addEventListener('mousemove', onMouseMove as EventListenerOrEventListenerObject);
document.addEventListener('mouseup', onMouseUp); document.addEventListener('mouseup', onMouseUp as EventListenerOrEventListenerObject);
} }
+4 -1
View File
@@ -28,6 +28,7 @@ const Handle: FC<HandleProps & Omit<HTMLAttributes<HTMLDivElement>, 'id'>> = ({
const onConnectStop = useStoreState((state) => state.onConnectStop); const onConnectStop = useStoreState((state) => state.onConnectStop);
const onConnectEnd = useStoreState((state) => state.onConnectEnd); const onConnectEnd = useStoreState((state) => state.onConnectEnd);
const connectionMode = useStoreState((state) => state.connectionMode); const connectionMode = useStoreState((state) => state.connectionMode);
const document = useStoreState(state => state.document);
const handleId = id || null; const handleId = id || null;
const isTarget = type === 'target'; const isTarget = type === 'target';
@@ -53,7 +54,8 @@ const Handle: FC<HandleProps & Omit<HTMLAttributes<HTMLDivElement>, 'id'>> = ({
connectionMode, connectionMode,
onConnectStart, onConnectStart,
onConnectStop, onConnectStop,
onConnectEnd onConnectEnd,
document
); );
}, },
[ [
@@ -68,6 +70,7 @@ const Handle: FC<HandleProps & Omit<HTMLAttributes<HTMLDivElement>, 'id'>> = ({
onConnectStart, onConnectStart,
onConnectStop, onConnectStop,
onConnectEnd, onConnectEnd,
document
] ]
); );
+6
View File
@@ -91,6 +91,7 @@ const GraphView = ({
onEdgeMouseMove, onEdgeMouseMove,
onEdgeMouseLeave, onEdgeMouseLeave,
edgeUpdaterRadius, edgeUpdaterRadius,
document,
}: GraphViewProps) => { }: GraphViewProps) => {
const isInitialized = useRef<boolean>(false); const isInitialized = useRef<boolean>(false);
const setOnConnect = useStoreActions((actions) => actions.setOnConnect); const setOnConnect = useStoreActions((actions) => actions.setOnConnect);
@@ -107,6 +108,7 @@ const GraphView = ({
const setTranslateExtent = useStoreActions((actions) => actions.setTranslateExtent); const setTranslateExtent = useStoreActions((actions) => actions.setTranslateExtent);
const setNodeExtent = useStoreActions((actions) => actions.setNodeExtent); const setNodeExtent = useStoreActions((actions) => actions.setNodeExtent);
const setConnectionMode = useStoreActions((actions) => actions.setConnectionMode); const setConnectionMode = useStoreActions((actions) => actions.setConnectionMode);
const setDocument = useStoreActions(actions => actions.setDocument);
const currentStore = useStore(); const currentStore = useStore();
const { zoomIn, zoomOut, zoomTo, transform, fitView, initialized } = useZoomPanHelper(); const { zoomIn, zoomOut, zoomTo, transform, fitView, initialized } = useZoomPanHelper();
@@ -129,6 +131,10 @@ const GraphView = ({
} }
}, [onLoad, zoomIn, zoomOut, zoomTo, transform, fitView, initialized]); }, [onLoad, zoomIn, zoomOut, zoomTo, transform, fitView, initialized]);
useEffect(() => {
setDocument(document);
}, [document])
useEffect(() => { useEffect(() => {
if (onConnect) { if (onConnect) {
setOnConnect(onConnect); setOnConnect(onConnect);
+3
View File
@@ -115,6 +115,7 @@ export interface ReactFlowProps extends Omit<HTMLAttributes<HTMLDivElement>, 'on
onEdgeMouseMove?: (event: MouseEvent, edge: Edge) => void; onEdgeMouseMove?: (event: MouseEvent, edge: Edge) => void;
onEdgeMouseLeave?: (event: MouseEvent, edge: Edge) => void; onEdgeMouseLeave?: (event: MouseEvent, edge: Edge) => void;
edgeUpdaterRadius?: number; edgeUpdaterRadius?: number;
document?: Document | ShadowRoot;
nodeTypesId?: string; nodeTypesId?: string;
edgeTypesId?: string; edgeTypesId?: string;
} }
@@ -189,6 +190,7 @@ const ReactFlow = ({
edgeUpdaterRadius = 10, edgeUpdaterRadius = 10,
nodeTypesId = '1', nodeTypesId = '1',
edgeTypesId = '1', edgeTypesId = '1',
document = window.document,
...rest ...rest
}: ReactFlowProps) => { }: ReactFlowProps) => {
const nodeTypesParsed = useMemo(() => createNodeTypes(nodeTypes), [nodeTypesId]); const nodeTypesParsed = useMemo(() => createNodeTypes(nodeTypes), [nodeTypesId]);
@@ -262,6 +264,7 @@ const ReactFlow = ({
onEdgeMouseMove={onEdgeMouseMove} onEdgeMouseMove={onEdgeMouseMove}
onEdgeMouseLeave={onEdgeMouseLeave} onEdgeMouseLeave={onEdgeMouseLeave}
edgeUpdaterRadius={edgeUpdaterRadius} edgeUpdaterRadius={edgeUpdaterRadius}
document={document}
/> />
<ElementUpdater elements={elements} /> <ElementUpdater elements={elements} />
{onSelectionChange && <SelectionListener onSelectionChange={onSelectionChange} />} {onSelectionChange && <SelectionListener onSelectionChange={onSelectionChange} />}
+6
View File
@@ -42,6 +42,11 @@ export const setOnConnectEnd = (onConnectEnd: OnConnectEndFunc) =>
onConnectEnd, onConnectEnd,
}); });
export const setDocument = (document: Document | ShadowRoot) =>
createAction(constants.SET_DOCUMENT, {
document
})
export const setElements = (elements: Elements) => createAction(constants.SET_ELEMENTS, elements); export const setElements = (elements: Elements) => createAction(constants.SET_ELEMENTS, elements);
export const updateNodeDimensions = (updates: NodeDimensionUpdate[]) => export const updateNodeDimensions = (updates: NodeDimensionUpdate[]) =>
@@ -160,4 +165,5 @@ export type ReactFlowAction = ReturnType<
| typeof setMultiSelectionActive | typeof setMultiSelectionActive
| typeof setConnectionMode | typeof setConnectionMode
| typeof setNodeExtent | typeof setNodeExtent
| typeof setDocument
>; >;
+1
View File
@@ -31,3 +31,4 @@ export const SET_ELEMENTS_SELECTABLE = 'SET_ELEMENTS_SELECTABLE';
export const SET_MULTI_SELECTION_ACTIVE = 'SET_MULTI_SELECTION_ACTIVE'; export const SET_MULTI_SELECTION_ACTIVE = 'SET_MULTI_SELECTION_ACTIVE';
export const SET_CONNECTION_MODE = 'SET_CONNECTION_MODE'; export const SET_CONNECTION_MODE = 'SET_CONNECTION_MODE';
export const SET_NODE_EXTENT = 'SET_NODE_EXTENT'; export const SET_NODE_EXTENT = 'SET_NODE_EXTENT';
export const SET_DOCUMENT = 'SET_DOCUMENT';
+1
View File
@@ -3,6 +3,7 @@ import configureStore from './configure-store';
import { ReactFlowState, ConnectionMode } from '../types'; import { ReactFlowState, ConnectionMode } from '../types';
export const initialState: ReactFlowState = { export const initialState: ReactFlowState = {
document: window.document,
width: 0, width: 0,
height: 0, height: 0,
transform: [0, 0, 1], transform: [0, 0, 1],
+1
View File
@@ -334,6 +334,7 @@ export default function reactFlowReducer(state = initialState, action: ReactFlow
case constants.SET_ELEMENTS_SELECTABLE: case constants.SET_ELEMENTS_SELECTABLE:
case constants.SET_MULTI_SELECTION_ACTIVE: case constants.SET_MULTI_SELECTION_ACTIVE:
case constants.SET_CONNECTION_MODE: case constants.SET_CONNECTION_MODE:
case constants.SET_DOCUMENT:
return { ...state, ...action.payload }; return { ...state, ...action.payload };
default: default:
return state; return state;
+2
View File
@@ -430,6 +430,8 @@ export interface ReactFlowState {
onConnectStart?: OnConnectStartFunc; onConnectStart?: OnConnectStartFunc;
onConnectStop?: OnConnectStopFunc; onConnectStop?: OnConnectStopFunc;
onConnectEnd?: OnConnectEndFunc; onConnectEnd?: OnConnectEndFunc;
document: Document | ShadowRoot;
} }
export type UpdateNodeInternals = (nodeId: ElementId) => void; export type UpdateNodeInternals = (nodeId: ElementId) => void;