Merge branch 'main' into feat/packages
This commit is contained in:
@@ -1,5 +1,22 @@
|
||||
# @reactflow/background
|
||||
|
||||
## 11.2.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- [#2941](https://github.com/wbkd/react-flow/pull/2941) Thanks [@Elringus](https://github.com/Elringus)! - add `id` and `offset` props
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`098eee3d`](https://github.com/wbkd/react-flow/commit/098eee3d41dabc870777b081796401ff13b5a776), [`fe8cac0a`](https://github.com/wbkd/react-flow/commit/fe8cac0adb359109e0e9eafe8b9261ba354076bb), [`4a4ca171`](https://github.com/wbkd/react-flow/commit/4a4ca171955f5c8d58b23e3ad48406f1a21dc402), [`923a54c4`](https://github.com/wbkd/react-flow/commit/923a54c481b90954806202817ba844cfa7203a38), [`4d97a0ed`](https://github.com/wbkd/react-flow/commit/4d97a0ed168ce643fc0c99fa6b47cf1296d66065), [`c22e1c28`](https://github.com/wbkd/react-flow/commit/c22e1c28c5555a638c2a8e82c3bfc986b3965d36)]:
|
||||
- @reactflow/core@11.7.0
|
||||
|
||||
## 11.1.10
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies
|
||||
|
||||
## 11.1.9
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@reactflow/background",
|
||||
"version": "11.1.9",
|
||||
"version": "11.2.0",
|
||||
"description": "Background component with different variants for React Flow",
|
||||
"keywords": [
|
||||
"react",
|
||||
|
||||
@@ -21,12 +21,14 @@ const defaultSize = {
|
||||
const selector = (s: ReactFlowState) => ({ transform: s.transform, patternId: `pattern-${s.rfId}` });
|
||||
|
||||
function Background({
|
||||
id,
|
||||
variant = BackgroundVariant.Dots,
|
||||
gap = 20,
|
||||
// only used for dots and cross
|
||||
size,
|
||||
gap = 20,
|
||||
// only used for lines and cross
|
||||
size,
|
||||
lineWidth = 1,
|
||||
offset = 2,
|
||||
color,
|
||||
style,
|
||||
className,
|
||||
@@ -44,8 +46,8 @@ function Background({
|
||||
const patternDimensions: [number, number] = isCross ? [scaledSize, scaledSize] : scaledGap;
|
||||
|
||||
const patternOffset = isDots
|
||||
? [scaledSize / 2, scaledSize / 2]
|
||||
: [patternDimensions[0] / 2, patternDimensions[1] / 2];
|
||||
? [scaledSize / offset, scaledSize / offset]
|
||||
: [patternDimensions[0] / offset, patternDimensions[1] / offset];
|
||||
|
||||
return (
|
||||
<svg
|
||||
@@ -62,7 +64,7 @@ function Background({
|
||||
data-testid="rf__background"
|
||||
>
|
||||
<pattern
|
||||
id={patternId}
|
||||
id={patternId+id}
|
||||
x={transform[0] % scaledGap[0]}
|
||||
y={transform[1] % scaledGap[1]}
|
||||
width={scaledGap[0]}
|
||||
@@ -71,12 +73,12 @@ function Background({
|
||||
patternTransform={`translate(-${patternOffset[0]},-${patternOffset[1]})`}
|
||||
>
|
||||
{isDots ? (
|
||||
<DotPattern color={patternColor} radius={scaledSize / 2} />
|
||||
<DotPattern color={patternColor} radius={scaledSize / offset} />
|
||||
) : (
|
||||
<LinePattern dimensions={patternDimensions} color={patternColor} lineWidth={lineWidth} />
|
||||
)}
|
||||
</pattern>
|
||||
<rect x="0" y="0" width="100%" height="100%" fill={`url(#${patternId})`} />
|
||||
<rect x="0" y="0" width="100%" height="100%" fill={`url(#${patternId+id})`} />
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -7,10 +7,12 @@ export enum BackgroundVariant {
|
||||
}
|
||||
|
||||
export type BackgroundProps = {
|
||||
id?: string
|
||||
color?: string;
|
||||
className?: string;
|
||||
gap?: number | [number, number];
|
||||
size?: number;
|
||||
offset?: number;
|
||||
lineWidth?: number;
|
||||
variant?: BackgroundVariant;
|
||||
style?: CSSProperties;
|
||||
|
||||
@@ -1,5 +1,18 @@
|
||||
# @reactflow/controls
|
||||
|
||||
## 11.1.11
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`098eee3d`](https://github.com/wbkd/react-flow/commit/098eee3d41dabc870777b081796401ff13b5a776), [`fe8cac0a`](https://github.com/wbkd/react-flow/commit/fe8cac0adb359109e0e9eafe8b9261ba354076bb), [`4a4ca171`](https://github.com/wbkd/react-flow/commit/4a4ca171955f5c8d58b23e3ad48406f1a21dc402), [`923a54c4`](https://github.com/wbkd/react-flow/commit/923a54c481b90954806202817ba844cfa7203a38), [`4d97a0ed`](https://github.com/wbkd/react-flow/commit/4d97a0ed168ce643fc0c99fa6b47cf1296d66065), [`c22e1c28`](https://github.com/wbkd/react-flow/commit/c22e1c28c5555a638c2a8e82c3bfc986b3965d36)]:
|
||||
- @reactflow/core@11.7.0
|
||||
|
||||
## 11.1.10
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies
|
||||
|
||||
## 11.1.9
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@reactflow/controls",
|
||||
"version": "11.1.9",
|
||||
"version": "11.1.11",
|
||||
"description": "Component to control the viewport of a React Flow instance",
|
||||
"keywords": [
|
||||
"react",
|
||||
|
||||
@@ -1,5 +1,32 @@
|
||||
# @reactflow/core
|
||||
|
||||
## 11.7.0
|
||||
|
||||
Most notable updates:
|
||||
|
||||
- Handles: `isConnectableStart` and `isConnectableEnd` props to configure if you can start or end a connection at a certain handle
|
||||
- Edges: `updatable` option to enable updates for specific edges
|
||||
- useNodesInitialized: options to configure if hidden nodes should be included (false by default)
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- [#2960](https://github.com/wbkd/react-flow/pull/2960) Thanks [@bcakmakoglu](https://github.com/bcakmakoglu)! - edges: add `updatable` option
|
||||
- [#2958](https://github.com/wbkd/react-flow/pull/2958) [`4d97a0ed`](https://github.com/wbkd/react-flow/commit/4d97a0ed168ce643fc0c99fa6b47cf1296d66065) - handles: add `isConnectableStart` and `isConnectableEnd` props
|
||||
- [#2956](https://github.com/wbkd/react-flow/pull/2956) [`923a54c4`](https://github.com/wbkd/react-flow/commit/923a54c481b90954806202817ba844cfa7203a38) - add options for `useNodesInitialized`, ignore hidden nodes by default
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#2926](https://github.com/wbkd/react-flow/pull/2926) Thanks [@Elringus](https://github.com/Elringus)! - fix non-passive wheel event listener violation
|
||||
- [#2933](https://github.com/wbkd/react-flow/pull/2933) [`fe8cac0a`](https://github.com/wbkd/react-flow/commit/fe8cac0adb359109e0e9eafe8b9261ba354076bb) - prefix error keys with "error"
|
||||
- [#2939](https://github.com/wbkd/react-flow/pull/2939) [`4a4ca171`](https://github.com/wbkd/react-flow/commit/4a4ca171955f5c8d58b23e3ad48406f1a21dc402) - add connection result to store
|
||||
|
||||
|
||||
## 11.6.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Always create new edge object (fixes an issue with Redux toolkit and other immutable helper libs)
|
||||
|
||||
## 11.6.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@reactflow/core",
|
||||
"version": "11.6.0",
|
||||
"version": "11.7.0",
|
||||
"description": "Core components and util functions of React Flow.",
|
||||
"keywords": [
|
||||
"react",
|
||||
|
||||
@@ -54,6 +54,7 @@ export default (EdgeComponent: ComponentType<EdgeProps>) => {
|
||||
rfId,
|
||||
ariaLabel,
|
||||
isFocusable,
|
||||
isUpdatable,
|
||||
pathOptions,
|
||||
interactionWidth,
|
||||
}: WrapEdgeProps): JSX.Element | null => {
|
||||
@@ -137,7 +138,6 @@ export default (EdgeComponent: ComponentType<EdgeProps>) => {
|
||||
const onEdgeUpdaterMouseOut = () => setUpdateHover(false);
|
||||
|
||||
const inactive = !elementsSelectable && !onClick;
|
||||
const handleEdgeUpdate = typeof onEdgeUpdate !== 'undefined';
|
||||
|
||||
const onKeyDown = (event: KeyboardEvent) => {
|
||||
if (elementSelectionKeys.includes(event.key) && elementsSelectable) {
|
||||
@@ -204,28 +204,32 @@ export default (EdgeComponent: ComponentType<EdgeProps>) => {
|
||||
interactionWidth={interactionWidth}
|
||||
/>
|
||||
)}
|
||||
{handleEdgeUpdate && (
|
||||
{isUpdatable && (
|
||||
<>
|
||||
<EdgeAnchor
|
||||
position={sourcePosition}
|
||||
centerX={sourceX}
|
||||
centerY={sourceY}
|
||||
radius={edgeUpdaterRadius}
|
||||
onMouseDown={onEdgeUpdaterSourceMouseDown}
|
||||
onMouseEnter={onEdgeUpdaterMouseEnter}
|
||||
onMouseOut={onEdgeUpdaterMouseOut}
|
||||
type="source"
|
||||
/>
|
||||
<EdgeAnchor
|
||||
position={targetPosition}
|
||||
centerX={targetX}
|
||||
centerY={targetY}
|
||||
radius={edgeUpdaterRadius}
|
||||
onMouseDown={onEdgeUpdaterTargetMouseDown}
|
||||
onMouseEnter={onEdgeUpdaterMouseEnter}
|
||||
onMouseOut={onEdgeUpdaterMouseOut}
|
||||
type="target"
|
||||
/>
|
||||
{(isUpdatable === 'source' || isUpdatable === true) && (
|
||||
<EdgeAnchor
|
||||
position={sourcePosition}
|
||||
centerX={sourceX}
|
||||
centerY={sourceY}
|
||||
radius={edgeUpdaterRadius}
|
||||
onMouseDown={onEdgeUpdaterSourceMouseDown}
|
||||
onMouseEnter={onEdgeUpdaterMouseEnter}
|
||||
onMouseOut={onEdgeUpdaterMouseOut}
|
||||
type="source"
|
||||
/>
|
||||
)}
|
||||
{(isUpdatable === 'target' || isUpdatable === true) && (
|
||||
<EdgeAnchor
|
||||
position={targetPosition}
|
||||
centerX={targetX}
|
||||
centerY={targetY}
|
||||
radius={edgeUpdaterRadius}
|
||||
onMouseDown={onEdgeUpdaterTargetMouseDown}
|
||||
onMouseEnter={onEdgeUpdaterMouseEnter}
|
||||
onMouseOut={onEdgeUpdaterMouseOut}
|
||||
type="target"
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
</g>
|
||||
|
||||
@@ -95,10 +95,17 @@ export function handlePointerDown({
|
||||
|
||||
setState({
|
||||
connectionPosition,
|
||||
connectionStatus: null,
|
||||
// connectionNodeId etc will be removed in the next major in favor of connectionStartHandle
|
||||
connectionNodeId: nodeId,
|
||||
connectionHandleId: handleId,
|
||||
connectionHandleType: handleType,
|
||||
connectionStatus: null,
|
||||
connectionStartHandle: {
|
||||
nodeId,
|
||||
handleId,
|
||||
type: handleType,
|
||||
},
|
||||
connectionEndHandle: null,
|
||||
});
|
||||
|
||||
onConnectStart?.(event, { nodeId, handleId, handleType });
|
||||
@@ -145,6 +152,7 @@ export function handlePointerDown({
|
||||
)
|
||||
: connectionPosition,
|
||||
connectionStatus: getConnectionStatus(!!prevClosestHandle, isValid),
|
||||
connectionEndHandle: result.endHandle,
|
||||
});
|
||||
|
||||
if (!prevClosestHandle && !isValid && !handleDomNode) {
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
import { memo, HTMLAttributes, forwardRef, MouseEvent as ReactMouseEvent, TouchEvent as ReactTouchEvent } from 'react';
|
||||
import cc from 'classcat';
|
||||
import { shallow } from 'zustand/shallow';
|
||||
import { errorMessages, Position, type HandleProps, type Connection } from '@reactflow/system';
|
||||
import { errorMessages, Position, type HandleProps, type Connection, type HandleType } from '@reactflow/system';
|
||||
import { getHostForElement, isMouseEvent } from '@reactflow/utils';
|
||||
|
||||
import { useStore, useStoreApi } from '../../hooks/useStore';
|
||||
import { useNodeId } from '../../contexts/NodeIdContext';
|
||||
import { handlePointerDown } from './handler';
|
||||
import { addEdge } from '../../utils/';
|
||||
import { type ReactFlowState } from '../../types';
|
||||
import { isValidHandle } from './utils';
|
||||
import { addEdge } from '../../utils';
|
||||
import type { ReactFlowState } from '../../types';
|
||||
|
||||
const alwaysValid = () => true;
|
||||
|
||||
@@ -21,6 +21,23 @@ const selector = (s: ReactFlowState) => ({
|
||||
noPanClassName: s.noPanClassName,
|
||||
});
|
||||
|
||||
const connectingSelector =
|
||||
(nodeId: string | null, handleId: string | null, type: HandleType) => (state: ReactFlowState) => {
|
||||
const {
|
||||
connectionStartHandle: startHandle,
|
||||
connectionEndHandle: endHandle,
|
||||
connectionClickStartHandle: clickHandle,
|
||||
} = state;
|
||||
|
||||
return {
|
||||
connecting:
|
||||
(startHandle?.nodeId === nodeId && startHandle?.handleId === handleId && startHandle?.type === type) ||
|
||||
(endHandle?.nodeId === nodeId && endHandle?.handleId === handleId && endHandle?.type === type),
|
||||
clickConnecting:
|
||||
clickHandle?.nodeId === nodeId && clickHandle?.handleId === handleId && clickHandle?.type === type,
|
||||
};
|
||||
};
|
||||
|
||||
const Handle = forwardRef<HTMLDivElement, HandleComponentProps>(
|
||||
(
|
||||
{
|
||||
@@ -28,6 +45,8 @@ const Handle = forwardRef<HTMLDivElement, HandleComponentProps>(
|
||||
position = Position.Top,
|
||||
isValidConnection,
|
||||
isConnectable = true,
|
||||
isConnectableStart = true,
|
||||
isConnectableEnd = true,
|
||||
id,
|
||||
onConnect,
|
||||
children,
|
||||
@@ -38,19 +57,16 @@ const Handle = forwardRef<HTMLDivElement, HandleComponentProps>(
|
||||
},
|
||||
ref
|
||||
) => {
|
||||
const store = useStoreApi();
|
||||
const nodeId = useNodeId();
|
||||
|
||||
if (!nodeId) {
|
||||
store.getState().onError?.('010', errorMessages['010']());
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
const { connectionStartHandle, connectOnClick, noPanClassName } = useStore(selector, shallow);
|
||||
|
||||
const handleId = id || null;
|
||||
const isTarget = type === 'target';
|
||||
const store = useStoreApi();
|
||||
const nodeId = useNodeId();
|
||||
const { connectOnClick, noPanClassName } = useStore(selector, shallow);
|
||||
const { connecting, clickConnecting } = useStore(connectingSelector(nodeId, handleId, type));
|
||||
|
||||
if (!nodeId) {
|
||||
store.getState().onError?.('010', errorMessages['error010']());
|
||||
}
|
||||
|
||||
const onConnectExtended = (params: Connection) => {
|
||||
const { defaultEdgeOptions, onConnect: onConnectAction, hasDefaultEdges } = store.getState();
|
||||
@@ -69,9 +85,16 @@ const Handle = forwardRef<HTMLDivElement, HandleComponentProps>(
|
||||
};
|
||||
|
||||
const onPointerDown = (event: ReactMouseEvent<HTMLDivElement> | ReactTouchEvent<HTMLDivElement>) => {
|
||||
if (!nodeId) {
|
||||
return;
|
||||
}
|
||||
|
||||
const isMouseTriggered = isMouseEvent(event.nativeEvent);
|
||||
|
||||
if ((isMouseTriggered && (event as ReactMouseEvent<HTMLDivElement>).button === 0) || !isMouseTriggered) {
|
||||
if (
|
||||
isConnectableStart &&
|
||||
((isMouseTriggered && (event as ReactMouseEvent<HTMLDivElement>).button === 0) || !isMouseTriggered)
|
||||
) {
|
||||
handlePointerDown({
|
||||
event,
|
||||
handleId,
|
||||
@@ -95,12 +118,18 @@ const Handle = forwardRef<HTMLDivElement, HandleComponentProps>(
|
||||
const {
|
||||
onClickConnectStart,
|
||||
onClickConnectEnd,
|
||||
connectionClickStartHandle,
|
||||
connectionMode,
|
||||
isValidConnection: isValidConnectionStore,
|
||||
} = store.getState();
|
||||
if (!connectionStartHandle) {
|
||||
|
||||
if (!nodeId || (!connectionClickStartHandle && !isConnectableStart)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!connectionClickStartHandle) {
|
||||
onClickConnectStart?.(event, { nodeId, handleId, handleType: type });
|
||||
store.setState({ connectionStartHandle: { nodeId, type, handleId } });
|
||||
store.setState({ connectionClickStartHandle: { nodeId, type, handleId } });
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -114,9 +143,9 @@ const Handle = forwardRef<HTMLDivElement, HandleComponentProps>(
|
||||
type,
|
||||
},
|
||||
connectionMode,
|
||||
connectionStartHandle.nodeId,
|
||||
connectionStartHandle.handleId || null,
|
||||
connectionStartHandle.type,
|
||||
connectionClickStartHandle.nodeId,
|
||||
connectionClickStartHandle.handleId || null,
|
||||
connectionClickStartHandle.type,
|
||||
isValidConnectionHandler,
|
||||
doc
|
||||
);
|
||||
@@ -127,7 +156,7 @@ const Handle = forwardRef<HTMLDivElement, HandleComponentProps>(
|
||||
|
||||
onClickConnectEnd?.(event as unknown as MouseEvent);
|
||||
|
||||
store.setState({ connectionStartHandle: null });
|
||||
store.setState({ connectionClickStartHandle: null });
|
||||
};
|
||||
|
||||
return (
|
||||
@@ -146,10 +175,12 @@ const Handle = forwardRef<HTMLDivElement, HandleComponentProps>(
|
||||
source: !isTarget,
|
||||
target: isTarget,
|
||||
connectable: isConnectable,
|
||||
connecting:
|
||||
connectionStartHandle?.nodeId === nodeId &&
|
||||
connectionStartHandle?.handleId === handleId &&
|
||||
connectionStartHandle?.type === type,
|
||||
connectablestart: isConnectableStart,
|
||||
connectableend: isConnectableEnd,
|
||||
connecting: clickConnecting,
|
||||
// this class is used to style the handle when the user is connecting
|
||||
connectionindicator:
|
||||
isConnectable && ((isConnectableStart && !connecting) || (isConnectableEnd && connecting)),
|
||||
},
|
||||
])}
|
||||
onMouseDown={onPointerDown}
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
import { MouseEvent as ReactMouseEvent, TouchEvent as ReactTouchEvent } from 'react';
|
||||
import {
|
||||
internalsSymbol,
|
||||
ConnectionMode,
|
||||
ConnectionStatus,
|
||||
type ConnectingHandle,
|
||||
type Connection,
|
||||
type HandleType,
|
||||
type XYPosition,
|
||||
type NodeHandleBounds,
|
||||
type XYPosition,
|
||||
} from '@reactflow/system';
|
||||
import { getEventPosition } from '@reactflow/utils';
|
||||
|
||||
@@ -67,6 +67,7 @@ type Result = {
|
||||
handleDomNode: Element | null;
|
||||
isValid: boolean;
|
||||
connection: Connection;
|
||||
endHandle: ConnectingHandle | null;
|
||||
};
|
||||
|
||||
const nullConnection: Connection = { source: null, target: null, sourceHandle: null, targetHandle: null };
|
||||
@@ -78,7 +79,7 @@ export function isValidHandle(
|
||||
connectionMode: ConnectionMode,
|
||||
fromNodeId: string,
|
||||
fromHandleId: string | null,
|
||||
fromType: string,
|
||||
fromType: HandleType,
|
||||
isValidConnection: ValidConnectionFunc,
|
||||
doc: Document | ShadowRoot
|
||||
) {
|
||||
@@ -94,12 +95,15 @@ export function isValidHandle(
|
||||
handleDomNode: handleToCheck,
|
||||
isValid: false,
|
||||
connection: nullConnection,
|
||||
endHandle: null,
|
||||
};
|
||||
|
||||
if (handleToCheck) {
|
||||
const handleType = getHandleType(undefined, handleToCheck);
|
||||
const handleNodeId = handleToCheck.getAttribute('data-nodeid');
|
||||
const handleId = handleToCheck.getAttribute('data-handleid');
|
||||
const connectable = handleToCheck.classList.contains('connectable');
|
||||
const connectableEnd = handleToCheck.classList.contains('connectableend');
|
||||
|
||||
const connection: Connection = {
|
||||
source: isTarget ? handleNodeId : fromNodeId,
|
||||
@@ -110,14 +114,21 @@ export function isValidHandle(
|
||||
|
||||
result.connection = connection;
|
||||
|
||||
const isConnectable = connectable && connectableEnd;
|
||||
// in strict mode we don't allow target to target or source to source connections
|
||||
const isValid =
|
||||
handleToCheck.classList.contains('connectable') &&
|
||||
isConnectable &&
|
||||
(connectionMode === ConnectionMode.Strict
|
||||
? (isTarget && handleType === 'source') || (!isTarget && handleType === 'target')
|
||||
: handleNodeId !== fromNodeId || handleId !== fromHandleId);
|
||||
|
||||
if (isValid) {
|
||||
result.endHandle = {
|
||||
nodeId: handleNodeId as string,
|
||||
handleId,
|
||||
type: handleType as HandleType,
|
||||
};
|
||||
|
||||
result.isValid = isValidConnection(connection);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,6 +21,7 @@ type StoreUpdaterProps = Pick<
|
||||
| 'nodesConnectable'
|
||||
| 'nodesFocusable'
|
||||
| 'edgesFocusable'
|
||||
| 'edgesUpdatable'
|
||||
| 'minZoom'
|
||||
| 'maxZoom'
|
||||
| 'nodeExtent'
|
||||
@@ -99,6 +100,7 @@ const StoreUpdater = ({
|
||||
nodesConnectable,
|
||||
nodesFocusable,
|
||||
edgesFocusable,
|
||||
edgesUpdatable,
|
||||
elevateNodesOnSelect,
|
||||
minZoom,
|
||||
maxZoom,
|
||||
@@ -163,6 +165,7 @@ const StoreUpdater = ({
|
||||
useDirectStoreUpdater('nodesConnectable', nodesConnectable, store.setState);
|
||||
useDirectStoreUpdater('nodesFocusable', nodesFocusable, store.setState);
|
||||
useDirectStoreUpdater('edgesFocusable', edgesFocusable, store.setState);
|
||||
useDirectStoreUpdater('edgesUpdatable', edgesUpdatable, store.setState);
|
||||
useDirectStoreUpdater('elementsSelectable', elementsSelectable, store.setState);
|
||||
useDirectStoreUpdater('elevateNodesOnSelect', elevateNodesOnSelect, store.setState);
|
||||
useDirectStoreUpdater('snapToGrid', snapToGrid, store.setState);
|
||||
|
||||
@@ -43,7 +43,7 @@ export function useMarkerSymbol(type: MarkerType) {
|
||||
const symbolExists = Object.prototype.hasOwnProperty.call(MarkerSymbols, type);
|
||||
|
||||
if (!symbolExists) {
|
||||
store.getState().onError?.('009', errorMessages['009'](type));
|
||||
store.getState().onError?.('009', errorMessages['error009'](type));
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -38,6 +38,7 @@ type EdgeRendererProps = Pick<
|
||||
const selector = (s: ReactFlowState) => ({
|
||||
nodesConnectable: s.nodesConnectable,
|
||||
edgesFocusable: s.edgesFocusable,
|
||||
edgesUpdatable: s.edgesUpdatable,
|
||||
elementsSelectable: s.elementsSelectable,
|
||||
width: s.width,
|
||||
height: s.height,
|
||||
@@ -65,10 +66,8 @@ const EdgeRenderer = ({
|
||||
onEdgeUpdateEnd,
|
||||
children,
|
||||
}: EdgeRendererProps) => {
|
||||
const { edgesFocusable, elementsSelectable, width, height, connectionMode, nodeInternals, onError } = useStore(
|
||||
selector,
|
||||
shallow
|
||||
);
|
||||
const { edgesFocusable, edgesUpdatable, elementsSelectable, width, height, connectionMode, nodeInternals, onError } =
|
||||
useStore(selector, shallow);
|
||||
const edgeTree = useVisibleEdges(onlyRenderVisibleElements, nodeInternals, elevateEdgesOnSelect);
|
||||
|
||||
if (!width) {
|
||||
@@ -98,7 +97,7 @@ const EdgeRenderer = ({
|
||||
let edgeType = edge.type || 'default';
|
||||
|
||||
if (!edgeTypes[edgeType]) {
|
||||
onError?.('011', errorMessages['011'](edgeType));
|
||||
onError?.('011', errorMessages['error011'](edgeType));
|
||||
edgeType = 'default';
|
||||
}
|
||||
|
||||
@@ -113,9 +112,12 @@ const EdgeRenderer = ({
|
||||
const sourcePosition = sourceHandle?.position || Position.Bottom;
|
||||
const targetPosition = targetHandle?.position || Position.Top;
|
||||
const isFocusable = !!(edge.focusable || (edgesFocusable && typeof edge.focusable === 'undefined'));
|
||||
const isUpdatable =
|
||||
typeof onEdgeUpdate !== 'undefined' &&
|
||||
(edge.updatable || (edgesUpdatable && typeof edge.updatable === 'undefined'));
|
||||
|
||||
if (!sourceHandle || !targetHandle) {
|
||||
onError?.('008', errorMessages['008'](sourceHandle, edge));
|
||||
onError?.('008', errorMessages['error008'](sourceHandle, edge));
|
||||
|
||||
return null;
|
||||
}
|
||||
@@ -172,6 +174,7 @@ const EdgeRenderer = ({
|
||||
rfId={rfId}
|
||||
ariaLabel={edge.ariaLabel}
|
||||
isFocusable={isFocusable}
|
||||
isUpdatable={isUpdatable}
|
||||
pathOptions={'pathOptions' in edge ? edge.pathOptions : undefined}
|
||||
interactionWidth={edge.interactionWidth}
|
||||
/>
|
||||
|
||||
@@ -75,7 +75,7 @@ const NodeRenderer = (props: NodeRendererProps) => {
|
||||
let nodeType = node.type || 'default';
|
||||
|
||||
if (!props.nodeTypes[nodeType]) {
|
||||
onError?.('003', errorMessages['003'](nodeType));
|
||||
onError?.('003', errorMessages['error003'](nodeType));
|
||||
|
||||
nodeType = 'default';
|
||||
}
|
||||
|
||||
@@ -119,6 +119,7 @@ const ReactFlow = forwardRef<ReactFlowRefType, ReactFlowProps>(
|
||||
nodesFocusable,
|
||||
nodeOrigin = initNodeOrigin,
|
||||
edgesFocusable,
|
||||
edgesUpdatable,
|
||||
elementsSelectable,
|
||||
defaultViewport = initDefaultViewport,
|
||||
minZoom = 0.5,
|
||||
@@ -270,6 +271,7 @@ const ReactFlow = forwardRef<ReactFlowRefType, ReactFlowProps>(
|
||||
nodesConnectable={nodesConnectable}
|
||||
nodesFocusable={nodesFocusable}
|
||||
edgesFocusable={edgesFocusable}
|
||||
edgesUpdatable={edgesUpdatable}
|
||||
elementsSelectable={elementsSelectable}
|
||||
elevateNodesOnSelect={elevateNodesOnSelect}
|
||||
minZoom={minZoom}
|
||||
|
||||
@@ -17,7 +17,7 @@ export function useNodeOrEdgeTypes(nodeOrEdgeTypes: any, createTypes: any): any
|
||||
if (process.env.NODE_ENV === 'development') {
|
||||
const typeKeys = Object.keys(nodeOrEdgeTypes);
|
||||
if (shallow(typesKeysRef.current, typeKeys)) {
|
||||
devWarn('002', errorMessages['002']());
|
||||
devWarn('002', errorMessages['error002']());
|
||||
}
|
||||
|
||||
typesKeysRef.current = typeKeys;
|
||||
|
||||
@@ -139,7 +139,7 @@ const ZoomPane = ({
|
||||
-(deltaX / currentZoom) * panOnScrollSpeed,
|
||||
-(deltaY / currentZoom) * panOnScrollSpeed
|
||||
);
|
||||
});
|
||||
}, { passive: false });
|
||||
} else if (typeof d3ZoomHandler !== 'undefined') {
|
||||
d3Selection.on('wheel.zoom', function (event: any, d: any) {
|
||||
if (!preventScrolling || isWrappedWithClass(event, noWheelClassName)) {
|
||||
@@ -148,7 +148,7 @@ const ZoomPane = ({
|
||||
|
||||
event.preventDefault();
|
||||
d3ZoomHandler.call(this, event, d);
|
||||
});
|
||||
}, { passive: false });
|
||||
}
|
||||
}
|
||||
}, [
|
||||
|
||||
@@ -103,7 +103,7 @@ export function calcNextPosition(
|
||||
]
|
||||
: currentExtent;
|
||||
} else {
|
||||
onError?.('005', errorMessages['005']());
|
||||
onError?.('005', errorMessages['error005']());
|
||||
|
||||
currentExtent = nodeExtent;
|
||||
}
|
||||
|
||||
@@ -3,16 +3,27 @@ import { internalsSymbol } from '@reactflow/system';
|
||||
import { useStore } from './useStore';
|
||||
import type { ReactFlowState } from '../types';
|
||||
|
||||
const selector = (s: ReactFlowState) => {
|
||||
export type UseNodesInitializedOptions = {
|
||||
includeHiddenNodes?: boolean;
|
||||
};
|
||||
|
||||
const selector = (options: UseNodesInitializedOptions) => (s: ReactFlowState) => {
|
||||
if (s.nodeInternals.size === 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return s.getNodes().every((n) => n[internalsSymbol]?.handleBounds !== undefined);
|
||||
return s
|
||||
.getNodes()
|
||||
.filter((n) => (options.includeHiddenNodes ? true : !n.hidden))
|
||||
.every((n) => n[internalsSymbol]?.handleBounds !== undefined);
|
||||
};
|
||||
|
||||
function useNodesInitialized(): boolean {
|
||||
const initialized = useStore(selector);
|
||||
const defaultOptions = {
|
||||
includeHiddenNodes: false,
|
||||
};
|
||||
|
||||
function useNodesInitialized(options: UseNodesInitializedOptions = defaultOptions): boolean {
|
||||
const initialized = useStore(selector(options));
|
||||
|
||||
return initialized;
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ function useResizeHandler(rendererNode: MutableRefObject<HTMLDivElement | null>)
|
||||
const size = getDimensions(rendererNode.current);
|
||||
|
||||
if (size.height === 0 || size.width === 0) {
|
||||
store.getState().onError?.('004', errorMessages['004']());
|
||||
store.getState().onError?.('004', errorMessages['error004']());
|
||||
}
|
||||
|
||||
store.setState({ width: size.width || 500, height: size.height || 500 });
|
||||
|
||||
@@ -5,7 +5,7 @@ import { errorMessages } from '@reactflow/system';
|
||||
import StoreContext from '../contexts/RFStoreContext';
|
||||
import type { ReactFlowState } from '../types';
|
||||
|
||||
const zustandErrorMessage = errorMessages['001']();
|
||||
const zustandErrorMessage = errorMessages['error001']();
|
||||
|
||||
type ExtractState = StoreApi<ReactFlowState> extends { getState: () => infer T } ? T : never;
|
||||
|
||||
|
||||
@@ -19,9 +19,9 @@ export { default as useViewport } from './hooks/useViewport';
|
||||
export { default as useKeyPress } from './hooks/useKeyPress';
|
||||
export * from './hooks/useNodesEdgesState';
|
||||
export { useStore, useStoreApi } from './hooks/useStore';
|
||||
export { default as useOnViewportChange } from './hooks/useOnViewportChange';
|
||||
export { default as useOnSelectionChange } from './hooks/useOnSelectionChange';
|
||||
export { default as useNodesInitialized } from './hooks/useNodesInitialized';
|
||||
export { default as useOnViewportChange, type UseOnViewportChangeOptions } from './hooks/useOnViewportChange';
|
||||
export { default as useOnSelectionChange, type UseOnSelectionChangeOptions } from './hooks/useOnSelectionChange';
|
||||
export { default as useNodesInitialized, type UseNodesInitializedOptions } from './hooks/useNodesInitialized';
|
||||
export { default as useGetPointerPosition } from './hooks/useGetPointerPosition';
|
||||
export { useNodeId } from './contexts/NodeIdContext';
|
||||
export * from '@reactflow/edge-utils';
|
||||
|
||||
@@ -35,8 +35,8 @@ const createRFStore = () =>
|
||||
return Array.from(get().nodeInternals.values());
|
||||
},
|
||||
setEdges: (edges: Edge[]) => {
|
||||
const { defaultEdgeOptions = null } = get();
|
||||
set({ edges: defaultEdgeOptions ? edges.map((e) => ({ ...defaultEdgeOptions, ...e })) : edges });
|
||||
const { defaultEdgeOptions = {} } = get();
|
||||
set({ edges: edges.map((e) => ({ ...defaultEdgeOptions, ...e })) });
|
||||
},
|
||||
setDefaultNodesAndEdges: (nodes?: Node[], edges?: Edge[]) => {
|
||||
const hasDefaultNodes = typeof nodes !== 'undefined';
|
||||
@@ -299,6 +299,8 @@ const createRFStore = () =>
|
||||
connectionHandleId: initialState.connectionHandleId,
|
||||
connectionHandleType: initialState.connectionHandleType,
|
||||
connectionStatus: initialState.connectionStatus,
|
||||
connectionStartHandle: initialState.connectionStartHandle,
|
||||
connectionEndHandle: initialState.connectionEndHandle,
|
||||
}),
|
||||
reset: () => set({ ...initialState }),
|
||||
}));
|
||||
|
||||
@@ -42,6 +42,7 @@ const initialState: ReactFlowStore = {
|
||||
nodesConnectable: true,
|
||||
nodesFocusable: true,
|
||||
edgesFocusable: true,
|
||||
edgesUpdatable: true,
|
||||
elementsSelectable: true,
|
||||
elevateNodesOnSelect: true,
|
||||
fitViewOnInit: false,
|
||||
@@ -51,6 +52,8 @@ const initialState: ReactFlowStore = {
|
||||
multiSelectionActive: false,
|
||||
|
||||
connectionStartHandle: null,
|
||||
connectionEndHandle: null,
|
||||
connectionClickStartHandle: null,
|
||||
connectOnClick: true,
|
||||
|
||||
ariaLiveMessage: '',
|
||||
|
||||
@@ -144,7 +144,7 @@
|
||||
min-width: 5px;
|
||||
min-height: 5px;
|
||||
|
||||
&.connectable {
|
||||
&.connectionindicator {
|
||||
pointer-events: all;
|
||||
cursor: crosshair;
|
||||
}
|
||||
|
||||
@@ -114,6 +114,7 @@ export type ReactFlowProps = HTMLAttributes<HTMLDivElement> & {
|
||||
nodesFocusable?: boolean;
|
||||
nodeOrigin?: NodeOrigin;
|
||||
edgesFocusable?: boolean;
|
||||
edgesUpdatable?: boolean;
|
||||
initNodeOrigin?: NodeOrigin;
|
||||
elementsSelectable?: boolean;
|
||||
selectNodesOnDrag?: boolean;
|
||||
|
||||
@@ -25,11 +25,14 @@ export type EdgeLabelOptions = {
|
||||
labelBgBorderRadius?: number;
|
||||
};
|
||||
|
||||
export type EdgeUpdatable = boolean | HandleType;
|
||||
|
||||
export type DefaultEdge<EdgeData = any> = BaseEdge<EdgeData> & {
|
||||
style?: CSSProperties;
|
||||
className?: string;
|
||||
sourceNode?: Node;
|
||||
targetNode?: Node;
|
||||
updatable?: EdgeUpdatable;
|
||||
} & EdgeLabelOptions;
|
||||
|
||||
type SmoothStepEdgeType<T> = DefaultEdge<T> & {
|
||||
@@ -68,6 +71,7 @@ export type WrapEdgeProps<T = any> = Omit<Edge<T>, 'sourceHandle' | 'targetHandl
|
||||
onEdgeUpdateEnd?: (event: MouseEvent | TouchEvent, edge: Edge, handleType: HandleType) => void;
|
||||
rfId?: string;
|
||||
isFocusable: boolean;
|
||||
isUpdatable: EdgeUpdatable;
|
||||
pathOptions?: BezierPathOptions | SmoothStepPathOptions;
|
||||
};
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@ import {
|
||||
OnViewportChange,
|
||||
SelectionRect,
|
||||
SnapGrid,
|
||||
StartHandle,
|
||||
ConnectingHandle,
|
||||
Transform,
|
||||
XYPosition,
|
||||
} from '@reactflow/system';
|
||||
@@ -80,12 +80,15 @@ export type ReactFlowStore = {
|
||||
nodesConnectable: boolean;
|
||||
nodesFocusable: boolean;
|
||||
edgesFocusable: boolean;
|
||||
edgesUpdatable: boolean;
|
||||
elementsSelectable: boolean;
|
||||
elevateNodesOnSelect: boolean;
|
||||
|
||||
multiSelectionActive: boolean;
|
||||
|
||||
connectionStartHandle: StartHandle | null;
|
||||
connectionStartHandle: ConnectingHandle | null;
|
||||
connectionEndHandle: ConnectingHandle | null;
|
||||
connectionClickStartHandle: ConnectingHandle | null;
|
||||
|
||||
onNodeDragStart?: NodeDragHandler;
|
||||
onNodeDrag?: NodeDragHandler;
|
||||
|
||||
@@ -1,5 +1,22 @@
|
||||
# @reactflow/minimap
|
||||
|
||||
## 11.5.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- [#2944](https://github.com/wbkd/react-flow/pull/2944) Thanks [@Elringus](https://github.com/Elringus)! - add `inversePan` and `zoomStep` props
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`098eee3d`](https://github.com/wbkd/react-flow/commit/098eee3d41dabc870777b081796401ff13b5a776), [`fe8cac0a`](https://github.com/wbkd/react-flow/commit/fe8cac0adb359109e0e9eafe8b9261ba354076bb), [`4a4ca171`](https://github.com/wbkd/react-flow/commit/4a4ca171955f5c8d58b23e3ad48406f1a21dc402), [`923a54c4`](https://github.com/wbkd/react-flow/commit/923a54c481b90954806202817ba844cfa7203a38), [`4d97a0ed`](https://github.com/wbkd/react-flow/commit/4d97a0ed168ce643fc0c99fa6b47cf1296d66065), [`c22e1c28`](https://github.com/wbkd/react-flow/commit/c22e1c28c5555a638c2a8e82c3bfc986b3965d36)]:
|
||||
- @reactflow/core@11.7.0
|
||||
|
||||
## 11.4.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies
|
||||
|
||||
## 11.4.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@reactflow/minimap",
|
||||
"version": "11.4.0",
|
||||
"version": "11.5.0",
|
||||
"description": "Minimap component for React Flow.",
|
||||
"keywords": [
|
||||
"react",
|
||||
|
||||
@@ -67,6 +67,8 @@ function MiniMap({
|
||||
pannable = false,
|
||||
zoomable = false,
|
||||
ariaLabel = 'React Flow mini map',
|
||||
inversePan = false,
|
||||
zoomStep = 10
|
||||
}: MiniMapProps) {
|
||||
const store = useStoreApi();
|
||||
const svg = useRef<SVGSVGElement>(null);
|
||||
@@ -106,7 +108,7 @@ function MiniMap({
|
||||
const pinchDelta =
|
||||
-event.sourceEvent.deltaY *
|
||||
(event.sourceEvent.deltaMode === 1 ? 0.05 : event.sourceEvent.deltaMode ? 1 : 0.002) *
|
||||
10;
|
||||
zoomStep;
|
||||
const zoom = transform[2] * Math.pow(2, pinchDelta);
|
||||
|
||||
d3Zoom.scaleTo(d3Selection, zoom);
|
||||
@@ -120,9 +122,10 @@ function MiniMap({
|
||||
}
|
||||
|
||||
// @TODO: how to calculate the correct next position? Math.max(1, transform[2]) is a workaround.
|
||||
const moveScale = viewScaleRef.current * Math.max(1, transform[2]) * (inversePan ? -1 : 1);
|
||||
const position = {
|
||||
x: transform[0] - event.sourceEvent.movementX * viewScaleRef.current * Math.max(1, transform[2]),
|
||||
y: transform[1] - event.sourceEvent.movementY * viewScaleRef.current * Math.max(1, transform[2]),
|
||||
x: transform[0] - event.sourceEvent.movementX * moveScale,
|
||||
y: transform[1] - event.sourceEvent.movementY * moveScale,
|
||||
};
|
||||
const extent: CoordinateExtent = [
|
||||
[0, 0],
|
||||
@@ -147,7 +150,7 @@ function MiniMap({
|
||||
selection.on('zoom', null);
|
||||
};
|
||||
}
|
||||
}, [pannable, zoomable]);
|
||||
}, [pannable, zoomable, inversePan, zoomStep]);
|
||||
|
||||
const onSvgClick = onClick
|
||||
? (event: MouseEvent) => {
|
||||
|
||||
@@ -20,6 +20,8 @@ export type MiniMapProps<NodeData = any> = Omit<HTMLAttributes<SVGSVGElement>, '
|
||||
pannable?: boolean;
|
||||
zoomable?: boolean;
|
||||
ariaLabel?: string | null;
|
||||
inversePan?: boolean;
|
||||
zoomStep?: number;
|
||||
};
|
||||
|
||||
export interface MiniMapNodeProps {
|
||||
|
||||
@@ -1,5 +1,18 @@
|
||||
# @reactflow/node-toolbar
|
||||
|
||||
## 1.1.11
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`098eee3d`](https://github.com/wbkd/react-flow/commit/098eee3d41dabc870777b081796401ff13b5a776), [`fe8cac0a`](https://github.com/wbkd/react-flow/commit/fe8cac0adb359109e0e9eafe8b9261ba354076bb), [`4a4ca171`](https://github.com/wbkd/react-flow/commit/4a4ca171955f5c8d58b23e3ad48406f1a21dc402), [`923a54c4`](https://github.com/wbkd/react-flow/commit/923a54c481b90954806202817ba844cfa7203a38), [`4d97a0ed`](https://github.com/wbkd/react-flow/commit/4d97a0ed168ce643fc0c99fa6b47cf1296d66065), [`c22e1c28`](https://github.com/wbkd/react-flow/commit/c22e1c28c5555a638c2a8e82c3bfc986b3965d36)]:
|
||||
- @reactflow/core@11.7.0
|
||||
|
||||
## 1.1.10
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies
|
||||
|
||||
## 1.1.9
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@reactflow/node-toolbar",
|
||||
"version": "1.1.9",
|
||||
"version": "1.1.11",
|
||||
"description": "A toolbar component for React Flow that can be attached to a node.",
|
||||
"keywords": [
|
||||
"react",
|
||||
|
||||
@@ -1,5 +1,50 @@
|
||||
# reactflow
|
||||
|
||||
## 11.7.0
|
||||
|
||||
Most notable updates:
|
||||
|
||||
- `@reactflow/node-resizer` is now part of this package. No need to install it separately anymore.
|
||||
- Handles: `isConnectableStart` and `isConnectableEnd` props to configure if you can start or end a connection at a certain handle
|
||||
- Edges: `updatable` option to enable updates for specific edges
|
||||
- MiniMap: `inversePan` and `zoomStep` props
|
||||
- Background: `id` and `offset` props - this enables you to combine different patterns (useful if you want a graph paper like background for example)
|
||||
- useNodesInitialized: options to configure if hidden nodes should be included (false by default)
|
||||
|
||||
Big thanks to [@Elringus](https://github.com/Elringus) and [@bcakmakoglu](https://github.com/bcakmakoglu)!
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- [#2964](https://github.com/wbkd/react-flow/pull/2964) [`2fb4c2c8`](https://github.com/wbkd/react-flow/commit/2fb4c2c82343751ff536da262de74bd9080321b4) - add @reactflow/node-resizer package
|
||||
- [#2960](https://github.com/wbkd/react-flow/pull/2960) Thanks [@bcakmakoglu](https://github.com/bcakmakoglu)! - edges: add `updatable` option
|
||||
- [#2958](https://github.com/wbkd/react-flow/pull/2958) [`4d97a0ed`](https://github.com/wbkd/react-flow/commit/4d97a0ed168ce643fc0c99fa6b47cf1296d66065) - handles: add `isConnectableStart` and `isConnectableEnd` props
|
||||
- [#2956](https://github.com/wbkd/react-flow/pull/2956) [`923a54c4`](https://github.com/wbkd/react-flow/commit/923a54c481b90954806202817ba844cfa7203a38) - add options for `useNodesInitialized`, ignore hidden nodes by default
|
||||
- [#2944](https://github.com/wbkd/react-flow/pull/2944) Thanks [@Elringus](https://github.com/Elringus)! - add `inversePan` and `zoomStep` props
|
||||
- [#2941](https://github.com/wbkd/react-flow/pull/2941) Thanks [@Elringus](https://github.com/Elringus)! - background: add `id` and `offset` props
|
||||
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#2926](https://github.com/wbkd/react-flow/pull/2926) Thanks [@Elringus](https://github.com/Elringus)! - fix non-passive wheel event listener violation
|
||||
- [#2933](https://github.com/wbkd/react-flow/pull/2933) [`fe8cac0a`](https://github.com/wbkd/react-flow/commit/fe8cac0adb359109e0e9eafe8b9261ba354076bb) - prefix error keys with "error"
|
||||
- [#2939](https://github.com/wbkd/react-flow/pull/2939) [`4a4ca171`](https://github.com/wbkd/react-flow/commit/4a4ca171955f5c8d58b23e3ad48406f1a21dc402) - add connection result to store
|
||||
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`098eee3d`](https://github.com/wbkd/react-flow/commit/098eee3d41dabc870777b081796401ff13b5a776), [`fe8cac0a`](https://github.com/wbkd/react-flow/commit/fe8cac0adb359109e0e9eafe8b9261ba354076bb), [`4a4ca171`](https://github.com/wbkd/react-flow/commit/4a4ca171955f5c8d58b23e3ad48406f1a21dc402), [`c1448c2f`](https://github.com/wbkd/react-flow/commit/c1448c2f7415dd3b4b2c54e05404c5ab24e8978d), [`923a54c4`](https://github.com/wbkd/react-flow/commit/923a54c481b90954806202817ba844cfa7203a38), [`4d97a0ed`](https://github.com/wbkd/react-flow/commit/4d97a0ed168ce643fc0c99fa6b47cf1296d66065), [`771c7a5d`](https://github.com/wbkd/react-flow/commit/771c7a5d133ce96e9f7471394c15189e0657ce01), [`c22e1c28`](https://github.com/wbkd/react-flow/commit/c22e1c28c5555a638c2a8e82c3bfc986b3965d36)]:
|
||||
- @reactflow/core@11.7.0
|
||||
- @reactflow/minimap@11.5.0
|
||||
- @reactflow/background@11.2.0
|
||||
- @reactflow/controls@11.1.11
|
||||
- @reactflow/node-toolbar@1.1.11
|
||||
|
||||
## 11.6.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Always create new edge object (fixes an issue with Redux toolkit and other immutable helper libs)
|
||||
|
||||
## 11.6.0
|
||||
|
||||
This release introduces a new `isValidConnection` prop for the ReactFlow component. You no longer need to pass it to all your Handle components but can pass it once. We also added a new option for the `updateEdge` function that allows you to specify if you want to replace an id when updating it. More over the `MiniMap` got a new `nodeComponent` prop to pass a custom component for the mini map nodes.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "reactflow",
|
||||
"version": "11.6.0",
|
||||
"version": "11.7.0",
|
||||
"description": "A highly customizable React library for building node-based editors and interactive flow charts",
|
||||
"keywords": [
|
||||
"react",
|
||||
@@ -39,6 +39,7 @@
|
||||
"@reactflow/controls": "workspace:*",
|
||||
"@reactflow/core": "workspace:*",
|
||||
"@reactflow/minimap": "workspace:*",
|
||||
"@reactflow/node-resizer": "workspace:*",
|
||||
"@reactflow/node-toolbar": "workspace:*"
|
||||
},
|
||||
"peerDependencies": {
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
@import '@reactflow/core/dist/base.css';
|
||||
@import '@reactflow/controls/dist/style.css';
|
||||
@import '@reactflow/minimap/dist/style.css';
|
||||
@import '@reactflow/node-resizer/dist/style.css';
|
||||
|
||||
@@ -3,5 +3,6 @@ export * from '@reactflow/minimap';
|
||||
export * from '@reactflow/controls';
|
||||
export * from '@reactflow/background';
|
||||
export * from '@reactflow/node-toolbar';
|
||||
export * from '@reactflow/node-resizer';
|
||||
|
||||
export { ReactFlow as default } from '@reactflow/core';
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
@import '@reactflow/core/dist/style.css';
|
||||
@import '@reactflow/controls/dist/style.css';
|
||||
@import '@reactflow/minimap/dist/style.css';
|
||||
@import '@reactflow/node-resizer/dist/style.css';
|
||||
|
||||
@@ -1,20 +1,20 @@
|
||||
import { BaseEdge, HandleElement } from './types';
|
||||
|
||||
export const errorMessages = {
|
||||
'001': () =>
|
||||
error001: () =>
|
||||
'[React Flow]: Seems like you have not used zustand provider as an ancestor. Help: https://reactflow.dev/error#001',
|
||||
'002': () =>
|
||||
error002: () =>
|
||||
"It looks like you've created a new nodeTypes or edgeTypes object. If this wasn't on purpose please define the nodeTypes/edgeTypes outside of the component or memoize them.",
|
||||
'003': (nodeType: string) => `Node type "${nodeType}" not found. Using fallback type "default".`,
|
||||
'004': () => 'The React Flow parent container needs a width and a height to render the graph.',
|
||||
'005': () => 'Only child nodes can use a parent extent.',
|
||||
'006': () => "Can't create edge. An edge needs a source and a target.",
|
||||
'007': (id: string) => `The old edge with id=${id} does not exist.`,
|
||||
'009': (type: string) => `Marker type "${type}" doesn't exist.`,
|
||||
'008': (sourceHandle: HandleElement | null, edge: BaseEdge) =>
|
||||
error003: (nodeType: string) => `Node type "${nodeType}" not found. Using fallback type "default".`,
|
||||
error004: () => 'The React Flow parent container needs a width and a height to render the graph.',
|
||||
error005: () => 'Only child nodes can use a parent extent.',
|
||||
error006: () => "Can't create edge. An edge needs a source and a target.",
|
||||
error007: (id: string) => `The old edge with id=${id} does not exist.`,
|
||||
error009: (type: string) => `Marker type "${type}" doesn't exist.`,
|
||||
error008: (sourceHandle: HandleElement | null, edge: BaseEdge) =>
|
||||
`Couldn't create edge for ${!sourceHandle ? 'source' : 'target'} handle id: "${
|
||||
!sourceHandle ? edge.sourceHandle : edge.targetHandle
|
||||
}", edge id: ${edge.id}.`,
|
||||
'010': () => 'Handle: No node id found. Make sure to only use a Handle inside a custom Node.',
|
||||
'011': (edgeType: string) => `Edge type "${edgeType}" not found. Using fallback type "default".`,
|
||||
error010: () => 'Handle: No node id found. Make sure to only use a Handle inside a custom Node.',
|
||||
error011: (edgeType: string) => `Edge type "${edgeType}" not found. Using fallback type "default".`,
|
||||
};
|
||||
|
||||
@@ -8,7 +8,7 @@ export type HandleElement = XYPosition &
|
||||
position: Position;
|
||||
};
|
||||
|
||||
export type StartHandle = {
|
||||
export type ConnectingHandle = {
|
||||
nodeId: string;
|
||||
type: HandleType;
|
||||
handleId?: string | null;
|
||||
@@ -18,6 +18,8 @@ export type HandleProps = {
|
||||
type: HandleType;
|
||||
position: Position;
|
||||
isConnectable?: boolean;
|
||||
isConnectableStart?: boolean;
|
||||
isConnectableEnd?: boolean;
|
||||
onConnect?: OnConnect;
|
||||
isValidConnection?: (connection: Connection) => boolean;
|
||||
id?: string;
|
||||
|
||||
@@ -86,7 +86,7 @@ export const addEdgeBase = <EdgeType extends BaseEdge>(
|
||||
edges: EdgeType[]
|
||||
): EdgeType[] => {
|
||||
if (!edgeParams.source || !edgeParams.target) {
|
||||
devWarn('006', errorMessages['006']());
|
||||
devWarn('006', errorMessages['error006']());
|
||||
|
||||
return edges;
|
||||
}
|
||||
@@ -121,7 +121,7 @@ export const updateEdgeBase = <EdgeType extends BaseEdge>(
|
||||
const { id: oldEdgeId, ...rest } = oldEdge;
|
||||
|
||||
if (!newConnection.source || !newConnection.target) {
|
||||
devWarn('006', errorMessages['006']());
|
||||
devWarn('006', errorMessages['error006']());
|
||||
|
||||
return edges;
|
||||
}
|
||||
@@ -129,7 +129,7 @@ export const updateEdgeBase = <EdgeType extends BaseEdge>(
|
||||
const foundEdge = edges.find((e) => e.id === oldEdge.id) as EdgeType;
|
||||
|
||||
if (!foundEdge) {
|
||||
devWarn('007', errorMessages['007'](oldEdgeId));
|
||||
devWarn('007', errorMessages['error007'](oldEdgeId));
|
||||
|
||||
return edges;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user