Merge branch 'next' into refactor/tsdoc

This commit is contained in:
moklick
2023-12-19 11:59:44 +01:00
117 changed files with 3388 additions and 2000 deletions
@@ -1,21 +1,18 @@
/* eslint-disable @typescript-eslint/ban-ts-comment */
/* eslint-disable @typescript-eslint/no-explicit-any */
import { memo } from 'react';
import { ComponentType, memo } from 'react';
import { NodeOrigin, getNodePositionWithOrigin } from '@xyflow/system';
import { shallow } from 'zustand/shallow';
import { getNodePositionWithOrigin } from '@xyflow/system';
import { useStore } from '../../hooks/useStore';
import type { ReactFlowState } from '../../types';
import MiniMapNode from './MiniMapNode';
import type { MiniMapNodes, GetMiniMapNodeAttribute } from './types';
import type { MiniMapNodes as MiniMapNodesProps, GetMiniMapNodeAttribute, MiniMapNodeProps } from './types';
declare const window: any;
const selector = (s: ReactFlowState) => s.nodeOrigin;
const selectorNodes = (s: ReactFlowState) =>
s.nodes.filter(
(node) => !node.hidden && (node.computed?.width || node.width) && (node.computed?.height || node.height)
);
const selectorNodeIds = (s: ReactFlowState) => s.nodes.map((node) => node.id);
const getAttrFunction = (func: any): GetMiniMapNodeAttribute => (func instanceof Function ? func : () => func);
function MiniMapNodes({
@@ -28,8 +25,8 @@ function MiniMapNodes({
// a component properly.
nodeComponent: NodeComponent = MiniMapNode,
onClick,
}: MiniMapNodes) {
const nodes = useStore(selectorNodes, shallow);
}: MiniMapNodesProps) {
const nodeIds = useStore(selectorNodeIds, shallow);
const nodeOrigin = useStore(selector);
const nodeColorFunc = getAttrFunction(nodeColor);
const nodeStrokeColorFunc = getAttrFunction(nodeStrokeColor);
@@ -39,33 +36,78 @@ function MiniMapNodes({
return (
<>
{nodes.map((node) => {
const { x, y } = getNodePositionWithOrigin(node, node.origin || nodeOrigin).positionAbsolute;
const color = nodeColor === undefined ? undefined : nodeColorFunc(node);
const strokeColor = nodeStrokeColor === undefined ? undefined : nodeStrokeColorFunc(node);
return (
<NodeComponent
key={node.id}
x={x}
y={y}
width={node.computed?.width ?? node.width ?? 0}
height={node.computed?.height ?? node.height ?? 0}
style={node.style}
selected={!!node.selected}
className={nodeClassNameFunc(node)}
color={color}
borderRadius={nodeBorderRadius}
strokeColor={strokeColor}
strokeWidth={nodeStrokeWidth}
shapeRendering={shapeRendering}
onClick={onClick}
id={node.id}
/>
);
})}
{nodeIds.map((nodeId) => (
// The split of responsibilities between MiniMapNodes and
// NodeComponentWrapper may appear weird. However, its designed to
// minimize the cost of updates when individual nodes change.
//
// For more details, see a similar commit in `NodeRenderer/index.tsx`.
<NodeComponentWrapper
key={nodeId}
id={nodeId}
nodeOrigin={nodeOrigin}
nodeColorFunc={nodeColorFunc}
nodeStrokeColorFunc={nodeStrokeColorFunc}
nodeClassNameFunc={nodeClassNameFunc}
nodeBorderRadius={nodeBorderRadius}
nodeStrokeWidth={nodeStrokeWidth}
NodeComponent={NodeComponent}
onClick={onClick}
shapeRendering={shapeRendering}
/>
))}
</>
);
}
const NodeComponentWrapper = memo(function NodeComponentWrapper({
id,
nodeOrigin,
nodeColorFunc,
nodeStrokeColorFunc,
nodeClassNameFunc,
nodeBorderRadius,
nodeStrokeWidth,
shapeRendering,
NodeComponent,
onClick,
}: {
id: string;
nodeOrigin: NodeOrigin;
nodeColorFunc: GetMiniMapNodeAttribute;
nodeStrokeColorFunc: GetMiniMapNodeAttribute;
nodeClassNameFunc: GetMiniMapNodeAttribute;
nodeBorderRadius: number;
nodeStrokeWidth?: number;
NodeComponent: ComponentType<MiniMapNodeProps>;
onClick: MiniMapNodesProps['onClick'];
shapeRendering: string;
}) {
const node = useStore((s) => s.nodeLookup.get(id));
if (!node || node.hidden || !(node.computed?.width || node.width) || !(node.computed?.height || node.height)) {
return null;
}
const positionOrigin = getNodePositionWithOrigin(node, node.origin || nodeOrigin).positionAbsolute;
return (
<NodeComponent
x={positionOrigin.x}
y={positionOrigin.y}
width={node.computed?.width ?? node.width ?? 0}
height={node.computed?.height ?? node.height ?? 0}
style={node.style}
selected={!!node.selected}
className={nodeClassNameFunc(node)}
color={nodeColorFunc(node)}
borderRadius={nodeBorderRadius}
strokeColor={nodeStrokeColorFunc(node)}
strokeWidth={nodeStrokeWidth}
shapeRendering={shapeRendering}
onClick={onClick}
id={node.id}
/>
);
});
export default memo(MiniMapNodes);
@@ -9,16 +9,20 @@ import { useNodeId } from '../../contexts/NodeIdContext';
import NodeToolbarPortal from './NodeToolbarPortal';
import { NodeToolbarProps } from './types';
const nodeEqualityFn = (a: Node | undefined, b: Node | undefined) =>
a?.computed?.positionAbsolute?.x === b?.computed?.positionAbsolute?.x &&
a?.computed?.positionAbsolute?.y === b?.computed?.positionAbsolute?.y &&
a?.width === b?.width &&
a?.height === b?.height &&
a?.selected === b?.selected &&
a?.[internalsSymbol]?.z === b?.[internalsSymbol]?.z;
const nodeEqualityFn = (a?: Node, b?: Node) =>
a?.computed?.positionAbsolute?.x !== b?.computed?.positionAbsolute?.x ||
a?.computed?.positionAbsolute?.y !== b?.computed?.positionAbsolute?.y ||
a?.computed?.width !== b?.computed?.width ||
a?.computed?.height !== b?.computed?.height ||
a?.selected !== b?.selected ||
a?.[internalsSymbol]?.z !== b?.[internalsSymbol]?.z;
const nodesEqualityFn = (a: Node[], b: Node[]) => {
return a.length === b.length && a.every((node, i) => nodeEqualityFn(node, b[i]));
if (a.length !== b.length) {
return false;
}
return !a.some((node, i) => nodeEqualityFn(node, b[i]));
};
const storeSelector = (state: ReactFlowState) => ({