diff --git a/examples/react/src/examples/Stress/index.tsx b/examples/react/src/examples/Stress/index.tsx index 14b56b09..9020ddd6 100644 --- a/examples/react/src/examples/Stress/index.tsx +++ b/examples/react/src/examples/Stress/index.tsx @@ -11,7 +11,6 @@ import { EdgeChange, Controls, Background, - MiniMap, Panel, } from '@xyflow/react'; diff --git a/packages/react/src/additional-components/Background/Background.tsx b/packages/react/src/additional-components/Background/Background.tsx index 3e71d723..738ed699 100644 --- a/packages/react/src/additional-components/Background/Background.tsx +++ b/packages/react/src/additional-components/Background/Background.tsx @@ -3,10 +3,10 @@ import cc from 'classcat'; import { shallow } from 'zustand/shallow'; import { useStore } from '../../hooks/useStore'; -import { type ReactFlowState } from '../../types'; -import { BackgroundProps, BackgroundVariant } from './types'; import { DotPattern, LinePattern } from './Patterns'; import { containerStyle } from '../../styles/utils'; +import { type BackgroundProps, BackgroundVariant } from './types'; +import { type ReactFlowState } from '../../types'; const defaultSize = { [BackgroundVariant.Dots]: 1, @@ -16,7 +16,7 @@ const defaultSize = { const selector = (s: ReactFlowState) => ({ transform: s.transform, patternId: `pattern-${s.rfId}` }); -function Background({ +function BackgroundComponent({ id, variant = BackgroundVariant.Dots, // only used for dots and cross @@ -87,6 +87,6 @@ function Background({ ); } -Background.displayName = 'Background'; +BackgroundComponent.displayName = 'Background'; -export default memo(Background); +export const Background = memo(BackgroundComponent); diff --git a/packages/react/src/additional-components/Background/index.tsx b/packages/react/src/additional-components/Background/index.tsx index c0996179..ad5e1dea 100644 --- a/packages/react/src/additional-components/Background/index.tsx +++ b/packages/react/src/additional-components/Background/index.tsx @@ -1,2 +1,2 @@ -export { default as Background } from './Background'; -export * from './types'; +export { Background } from './Background'; +export { BackgroundVariant, type BackgroundProps } from './types'; diff --git a/packages/react/src/additional-components/Controls/ControlButton.tsx b/packages/react/src/additional-components/Controls/ControlButton.tsx index 9952fde0..744f46d4 100644 --- a/packages/react/src/additional-components/Controls/ControlButton.tsx +++ b/packages/react/src/additional-components/Controls/ControlButton.tsx @@ -1,14 +1,11 @@ -import type { FC, PropsWithChildren } from 'react'; import cc from 'classcat'; import type { ControlButtonProps } from './types'; -const ControlButton: FC> = ({ children, className, ...rest }) => ( - -); - -ControlButton.displayName = 'ControlButton'; - -export default ControlButton; +export function ControlButton({ children, className, ...rest }: ControlButtonProps) { + return ( + + ); +} diff --git a/packages/react/src/additional-components/Controls/Controls.tsx b/packages/react/src/additional-components/Controls/Controls.tsx index 0604186b..3a38790d 100644 --- a/packages/react/src/additional-components/Controls/Controls.tsx +++ b/packages/react/src/additional-components/Controls/Controls.tsx @@ -1,19 +1,18 @@ -import { memo, type FC, type PropsWithChildren } from 'react'; +import { memo } from 'react'; import cc from 'classcat'; import { shallow } from 'zustand/shallow'; import { useStore, useStoreApi } from '../../hooks/useStore'; import { useReactFlow } from '../../hooks/useReactFlow'; -import Panel from '../../components/Panel'; +import { Panel } from '../../components/Panel'; import { type ReactFlowState } from '../../types'; -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 ControlButton from './ControlButton'; - +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 { ControlButton } from './ControlButton'; import type { ControlProps } from './types'; const selector = (s: ReactFlowState) => ({ @@ -22,7 +21,7 @@ const selector = (s: ReactFlowState) => ({ maxZoomReached: s.transform[2] >= s.maxZoom, }); -const Controls: FC> = ({ +function ControlsComponent({ style, showZoom = true, showFitView = true, @@ -35,7 +34,7 @@ const Controls: FC> = ({ className, children, position = 'bottom-left', -}) => { +}: ControlProps) { const store = useStoreApi(); const { isInteractive, minZoomReached, maxZoomReached } = useStore(selector, shallow); const { zoomIn, zoomOut, fitView } = useReactFlow(); @@ -101,7 +100,7 @@ const Controls: FC> = ({ title="fit view" aria-label="fit view" > - + )} {showInteractive && ( @@ -117,8 +116,8 @@ const Controls: FC> = ({ {children} ); -}; +} -Controls.displayName = 'Controls'; +ControlsComponent.displayName = 'Controls'; -export default memo(Controls); +export const Controls = memo(ControlsComponent); diff --git a/packages/react/src/additional-components/Controls/Icons/FitView.tsx b/packages/react/src/additional-components/Controls/Icons/FitView.tsx index a5926730..cf67758e 100644 --- a/packages/react/src/additional-components/Controls/Icons/FitView.tsx +++ b/packages/react/src/additional-components/Controls/Icons/FitView.tsx @@ -1,9 +1,7 @@ -function FitViewIcon() { +export function FitViewIcon() { return ( ); } - -export default FitViewIcon; diff --git a/packages/react/src/additional-components/Controls/Icons/Lock.tsx b/packages/react/src/additional-components/Controls/Icons/Lock.tsx index 7f62ff65..f0c4b51c 100644 --- a/packages/react/src/additional-components/Controls/Icons/Lock.tsx +++ b/packages/react/src/additional-components/Controls/Icons/Lock.tsx @@ -1,9 +1,7 @@ -function LockIcon() { +export function LockIcon() { return ( ); } - -export default LockIcon; diff --git a/packages/react/src/additional-components/Controls/Icons/Minus.tsx b/packages/react/src/additional-components/Controls/Icons/Minus.tsx index 89a8b354..befbc12c 100644 --- a/packages/react/src/additional-components/Controls/Icons/Minus.tsx +++ b/packages/react/src/additional-components/Controls/Icons/Minus.tsx @@ -1,9 +1,7 @@ -function MinusIcon() { +export function MinusIcon() { return ( ); } - -export default MinusIcon; diff --git a/packages/react/src/additional-components/Controls/Icons/Plus.tsx b/packages/react/src/additional-components/Controls/Icons/Plus.tsx index eaa5efb8..b4ff4137 100644 --- a/packages/react/src/additional-components/Controls/Icons/Plus.tsx +++ b/packages/react/src/additional-components/Controls/Icons/Plus.tsx @@ -1,9 +1,7 @@ -function PlusIcon() { +export function PlusIcon() { return ( ); } - -export default PlusIcon; diff --git a/packages/react/src/additional-components/Controls/Icons/Unlock.tsx b/packages/react/src/additional-components/Controls/Icons/Unlock.tsx index ce113166..f68ae0b9 100644 --- a/packages/react/src/additional-components/Controls/Icons/Unlock.tsx +++ b/packages/react/src/additional-components/Controls/Icons/Unlock.tsx @@ -1,9 +1,7 @@ -function UnlockIcon() { +export function UnlockIcon() { return ( ); } - -export default UnlockIcon; diff --git a/packages/react/src/additional-components/Controls/index.tsx b/packages/react/src/additional-components/Controls/index.tsx index ac6f816c..7a5ce679 100644 --- a/packages/react/src/additional-components/Controls/index.tsx +++ b/packages/react/src/additional-components/Controls/index.tsx @@ -1,3 +1,3 @@ -export { default as Controls } from './Controls'; -export { default as ControlButton } from './ControlButton'; -export * from './types'; +export { Controls } from './Controls'; +export { ControlButton } from './ControlButton'; +export type { ControlProps, ControlButtonProps } from './types'; diff --git a/packages/react/src/additional-components/Controls/types.ts b/packages/react/src/additional-components/Controls/types.ts index 2d93540c..3833c50f 100644 --- a/packages/react/src/additional-components/Controls/types.ts +++ b/packages/react/src/additional-components/Controls/types.ts @@ -1,4 +1,4 @@ -import type { ButtonHTMLAttributes, HTMLAttributes } from 'react'; +import type { ButtonHTMLAttributes, HTMLAttributes, ReactNode } from 'react'; import type { PanelPosition } from '@xyflow/system'; import type { FitViewOptions } from '../../types'; @@ -13,6 +13,7 @@ export type ControlProps = HTMLAttributes & { onFitView?: () => void; onInteractiveChange?: (interactiveStatus: boolean) => void; position?: PanelPosition; + children?: ReactNode; }; export type ControlButtonProps = ButtonHTMLAttributes; diff --git a/packages/react/src/additional-components/MiniMap/MiniMap.tsx b/packages/react/src/additional-components/MiniMap/MiniMap.tsx index 8d1f0538..34a66fa1 100644 --- a/packages/react/src/additional-components/MiniMap/MiniMap.tsx +++ b/packages/react/src/additional-components/MiniMap/MiniMap.tsx @@ -6,11 +6,11 @@ import { shallow } from 'zustand/shallow'; import { getNodesBounds, getBoundsOfRects, XYMinimap, type Rect, type XYMinimapInstance } from '@xyflow/system'; import { useStore, useStoreApi } from '../../hooks/useStore'; -import Panel from '../../components/Panel'; +import { Panel } from '../../components/Panel'; import type { ReactFlowState } from '../../types'; -import type { MiniMapProps } from './types'; import MiniMapNodes from './MiniMapNodes'; +import type { MiniMapProps } from './types'; const defaultWidth = 200; const defaultHeight = 150; @@ -37,7 +37,7 @@ const selector = (s: ReactFlowState) => { const ARIA_LABEL_KEY = 'react-flow__minimap-desc'; -function MiniMap({ +function MiniMapComponent({ style, className, nodeStrokeColor, @@ -171,6 +171,6 @@ function MiniMap({ ); } -MiniMap.displayName = 'MiniMap'; +MiniMapComponent.displayName = 'MiniMap'; -export default memo(MiniMap); +export const MiniMap = memo(MiniMapComponent); diff --git a/packages/react/src/additional-components/MiniMap/MiniMapNode.tsx b/packages/react/src/additional-components/MiniMap/MiniMapNode.tsx index 76edf5e6..ec9fd725 100644 --- a/packages/react/src/additional-components/MiniMap/MiniMapNode.tsx +++ b/packages/react/src/additional-components/MiniMap/MiniMapNode.tsx @@ -3,7 +3,7 @@ import cc from 'classcat'; import type { MiniMapNodeProps } from './types'; -function MiniMapNode({ +function MiniMapNodeComponent({ id, x, y, @@ -42,4 +42,4 @@ function MiniMapNode({ ); } -export default memo(MiniMapNode); +export const MiniMapNode = memo(MiniMapNodeComponent); diff --git a/packages/react/src/additional-components/MiniMap/MiniMapNodes.tsx b/packages/react/src/additional-components/MiniMap/MiniMapNodes.tsx index 71cce50b..63851aad 100644 --- a/packages/react/src/additional-components/MiniMap/MiniMapNodes.tsx +++ b/packages/react/src/additional-components/MiniMap/MiniMapNodes.tsx @@ -5,8 +5,8 @@ import { NodeOrigin, getNodePositionWithOrigin } from '@xyflow/system'; import { shallow } from 'zustand/shallow'; import { useStore } from '../../hooks/useStore'; +import { MiniMapNode } from './MiniMapNode'; import type { ReactFlowState } from '../../types'; -import MiniMapNode from './MiniMapNode'; import type { MiniMapNodes as MiniMapNodesProps, GetMiniMapNodeAttribute, MiniMapNodeProps } from './types'; declare const window: any; diff --git a/packages/react/src/additional-components/MiniMap/index.tsx b/packages/react/src/additional-components/MiniMap/index.tsx index 7b91e95d..f08cb9de 100644 --- a/packages/react/src/additional-components/MiniMap/index.tsx +++ b/packages/react/src/additional-components/MiniMap/index.tsx @@ -1,2 +1,2 @@ -export { default as MiniMap } from './MiniMap'; +export { MiniMap } from './MiniMap'; export * from './types'; diff --git a/packages/react/src/additional-components/NodeToolbar/NodeToolbar.tsx b/packages/react/src/additional-components/NodeToolbar/NodeToolbar.tsx index 6f4ad13c..a681d6f3 100644 --- a/packages/react/src/additional-components/NodeToolbar/NodeToolbar.tsx +++ b/packages/react/src/additional-components/NodeToolbar/NodeToolbar.tsx @@ -6,8 +6,8 @@ import { getNodesBounds, Rect, Position, internalsSymbol, getNodeToolbarTransfor import { Node, ReactFlowState } from '../../types'; import { useStore } from '../../hooks/useStore'; import { useNodeId } from '../../contexts/NodeIdContext'; -import NodeToolbarPortal from './NodeToolbarPortal'; -import { NodeToolbarProps } from './types'; +import { NodeToolbarPortal } from './NodeToolbarPortal'; +import type { NodeToolbarProps } from './types'; const nodeEqualityFn = (a?: Node, b?: Node) => a?.computed?.positionAbsolute?.x !== b?.computed?.positionAbsolute?.x || @@ -35,7 +35,7 @@ const storeSelector = (state: ReactFlowState) => ({ selectedNodesCount: state.nodes.filter((node) => node.selected).length, }); -function NodeToolbar({ +export function NodeToolbar({ nodeId, children, className, @@ -96,5 +96,3 @@ function NodeToolbar({ ); } - -export default NodeToolbar; diff --git a/packages/react/src/additional-components/NodeToolbar/NodeToolbarPortal.tsx b/packages/react/src/additional-components/NodeToolbar/NodeToolbarPortal.tsx index 4b8d8d02..c7301c77 100644 --- a/packages/react/src/additional-components/NodeToolbar/NodeToolbarPortal.tsx +++ b/packages/react/src/additional-components/NodeToolbar/NodeToolbarPortal.tsx @@ -6,7 +6,7 @@ import { useStore } from '../../hooks/useStore'; const selector = (state: ReactFlowState) => state.domNode?.querySelector('.react-flow__renderer'); -function NodeToolbarPortal({ children }: { children: ReactNode }) { +export function NodeToolbarPortal({ children }: { children: ReactNode }) { const wrapperRef = useStore(selector); if (!wrapperRef) { @@ -15,5 +15,3 @@ function NodeToolbarPortal({ children }: { children: ReactNode }) { return createPortal(children, wrapperRef); } - -export default NodeToolbarPortal; diff --git a/packages/react/src/additional-components/NodeToolbar/index.tsx b/packages/react/src/additional-components/NodeToolbar/index.tsx index 3cded08b..d42a83c5 100644 --- a/packages/react/src/additional-components/NodeToolbar/index.tsx +++ b/packages/react/src/additional-components/NodeToolbar/index.tsx @@ -1,2 +1,2 @@ -export { default as NodeToolbar } from './NodeToolbar'; -export * from './types'; +export { NodeToolbar } from './NodeToolbar'; +export type { NodeToolbarProps } from './types'; diff --git a/packages/react/src/components/A11yDescriptions/index.tsx b/packages/react/src/components/A11yDescriptions/index.tsx index a92f27ac..51b4a939 100644 --- a/packages/react/src/components/A11yDescriptions/index.tsx +++ b/packages/react/src/components/A11yDescriptions/index.tsx @@ -32,7 +32,7 @@ function AriaLiveMessage({ rfId }: { rfId: string }) { ); } -function A11yDescriptions({ rfId, disableKeyboardA11y }: { rfId: string; disableKeyboardA11y: boolean }) { +export function A11yDescriptions({ rfId, disableKeyboardA11y }: { rfId: string; disableKeyboardA11y: boolean }) { return ( <>
@@ -47,5 +47,3 @@ function A11yDescriptions({ rfId, disableKeyboardA11y }: { rfId: string; disable ); } - -export default A11yDescriptions; diff --git a/packages/react/src/components/Attribution/index.tsx b/packages/react/src/components/Attribution/index.tsx index 8c2aa484..eb69bd13 100644 --- a/packages/react/src/components/Attribution/index.tsx +++ b/packages/react/src/components/Attribution/index.tsx @@ -1,13 +1,13 @@ import type { PanelPosition, ProOptions } from '@xyflow/system'; -import Panel from '../Panel'; +import { Panel } from '../Panel'; type AttributionProps = { proOptions?: ProOptions; position?: PanelPosition; }; -function Attribution({ proOptions, position = 'bottom-right' }: AttributionProps) { +export function Attribution({ proOptions, position = 'bottom-right' }: AttributionProps) { if (proOptions?.hideAttribution) { return null; } @@ -24,5 +24,3 @@ function Attribution({ proOptions, position = 'bottom-right' }: AttributionProps ); } - -export default Attribution; diff --git a/packages/react/src/components/ConnectionLine/index.tsx b/packages/react/src/components/ConnectionLine/index.tsx index 143ec6ef..4fe2ca76 100644 --- a/packages/react/src/components/ConnectionLine/index.tsx +++ b/packages/react/src/components/ConnectionLine/index.tsx @@ -142,7 +142,7 @@ const selector = (s: ReactFlowState) => ({ height: s.height, }); -function ConnectionLineWrapper({ containerStyle, style, type, component }: ConnectionLineWrapperProps) { +export function ConnectionLineWrapper({ containerStyle, style, type, component }: ConnectionLineWrapperProps) { const { nodeId, handleType, nodesConnectable, width, height, connectionStatus } = useStore(selector, shallow); const isValid = !!(nodeId && handleType && width && nodesConnectable); @@ -170,5 +170,3 @@ function ConnectionLineWrapper({ containerStyle, style, type, component }: Conne ); } - -export default ConnectionLineWrapper; diff --git a/packages/react/src/components/EdgeLabelRenderer/index.tsx b/packages/react/src/components/EdgeLabelRenderer/index.tsx index 85c94291..c66b70ae 100644 --- a/packages/react/src/components/EdgeLabelRenderer/index.tsx +++ b/packages/react/src/components/EdgeLabelRenderer/index.tsx @@ -6,7 +6,7 @@ import type { ReactFlowState } from '../../types'; const selector = (s: ReactFlowState) => s.domNode?.querySelector('.react-flow__edgelabel-renderer'); -function EdgeLabelRenderer({ children }: { children: ReactNode }) { +export function EdgeLabelRenderer({ children }: { children: ReactNode }) { const edgeLabelRenderer = useStore(selector); if (!edgeLabelRenderer) { @@ -15,5 +15,3 @@ function EdgeLabelRenderer({ children }: { children: ReactNode }) { return createPortal(children, edgeLabelRenderer); } - -export default EdgeLabelRenderer; diff --git a/packages/react/src/components/EdgeWrapper/EdgeUpdateAnchors.tsx b/packages/react/src/components/EdgeWrapper/EdgeUpdateAnchors.tsx index 57c81724..3e3f3bf7 100644 --- a/packages/react/src/components/EdgeWrapper/EdgeUpdateAnchors.tsx +++ b/packages/react/src/components/EdgeWrapper/EdgeUpdateAnchors.tsx @@ -18,7 +18,7 @@ type EdgeUpdateAnchorsProps = { setUpdating: (updating: boolean) => void; } & EdgePosition; -function EdgeUpdateAnchors({ +export function EdgeUpdateAnchors({ isUpdatable, edgeUpdaterRadius, edge, @@ -133,5 +133,3 @@ function EdgeUpdateAnchors({ ); } - -export default EdgeUpdateAnchors; diff --git a/packages/react/src/components/EdgeWrapper/index.tsx b/packages/react/src/components/EdgeWrapper/index.tsx index 9d96948c..cb9b9c8b 100644 --- a/packages/react/src/components/EdgeWrapper/index.tsx +++ b/packages/react/src/components/EdgeWrapper/index.tsx @@ -1,4 +1,4 @@ -import { memo, useState, useMemo, useRef, type KeyboardEvent, useCallback } from 'react'; +import { useState, useMemo, useRef, type KeyboardEvent, useCallback } from 'react'; import cc from 'classcat'; import { shallow } from 'zustand/shallow'; import { @@ -11,11 +11,11 @@ import { import { useStoreApi, useStore } from '../../hooks/useStore'; import { ARIA_EDGE_DESC_KEY } from '../A11yDescriptions'; -import type { EdgeWrapperProps } from '../../types'; import { builtinEdgeTypes, nullPosition } from './utils'; -import EdgeUpdateAnchors from './EdgeUpdateAnchors'; +import { EdgeUpdateAnchors } from './EdgeUpdateAnchors'; +import type { EdgeWrapperProps } from '../../types'; -function EdgeWrapper({ +export function EdgeWrapper({ id, edgesFocusable, edgesUpdatable, @@ -258,7 +258,3 @@ function EdgeWrapper({ ); } - -EdgeWrapper.displayName = 'EdgeWrapper'; - -export default memo(EdgeWrapper); diff --git a/packages/react/src/components/Edges/BaseEdge.tsx b/packages/react/src/components/Edges/BaseEdge.tsx index ae14b472..fab06220 100644 --- a/packages/react/src/components/Edges/BaseEdge.tsx +++ b/packages/react/src/components/Edges/BaseEdge.tsx @@ -1,10 +1,10 @@ import { isNumeric } from '@xyflow/system'; +import cc from 'classcat'; +import { EdgeText } from './EdgeText'; import type { BaseEdgeProps } from '../../types'; -import EdgeText from './EdgeText'; -import classcat from 'classcat'; -const BaseEdge = ({ +export function BaseEdge({ id, path, labelX, @@ -20,7 +20,7 @@ const BaseEdge = ({ markerStart, className, interactionWidth = 20, -}: BaseEdgeProps) => { +}: BaseEdgeProps) { return ( <> @@ -55,8 +55,4 @@ const BaseEdge = ({ ) : null} ); -}; - -BaseEdge.displayName = 'BaseEdge'; - -export default BaseEdge; +} diff --git a/packages/react/src/components/Edges/BezierEdge.tsx b/packages/react/src/components/Edges/BezierEdge.tsx index 2a0b54a2..482f1fd8 100644 --- a/packages/react/src/components/Edges/BezierEdge.tsx +++ b/packages/react/src/components/Edges/BezierEdge.tsx @@ -1,7 +1,7 @@ import { memo } from 'react'; import { Position, getBezierPath } from '@xyflow/system'; -import BaseEdge from './BaseEdge'; +import { BaseEdge } from './BaseEdge'; import type { BezierEdgeProps } from '../../types'; function createBezierEdge(params: { isInternal: boolean }) { diff --git a/packages/react/src/components/Edges/EdgeAnchor.tsx b/packages/react/src/components/Edges/EdgeAnchor.tsx index 575023b3..a975eaf5 100644 --- a/packages/react/src/components/Edges/EdgeAnchor.tsx +++ b/packages/react/src/components/Edges/EdgeAnchor.tsx @@ -1,4 +1,4 @@ -import type { FC, MouseEvent as ReactMouseEvent, SVGAttributes } from 'react'; +import type { MouseEvent as ReactMouseEvent, SVGAttributes } from 'react'; import cc from 'classcat'; import { Position } from '@xyflow/system'; @@ -27,7 +27,7 @@ export interface EdgeAnchorProps extends SVGAttributes { const EdgeUpdaterClassName = 'react-flow__edgeupdater'; -export const EdgeAnchor: FC = ({ +export function EdgeAnchor({ position, centerX, centerY, @@ -36,16 +36,18 @@ export const EdgeAnchor: FC = ({ onMouseEnter, onMouseOut, type, -}: EdgeAnchorProps) => ( - -); +}: EdgeAnchorProps) { + return ( + + ); +} diff --git a/packages/react/src/components/Edges/EdgeText.tsx b/packages/react/src/components/Edges/EdgeText.tsx index 8cc5c388..2e671895 100644 --- a/packages/react/src/components/Edges/EdgeText.tsx +++ b/packages/react/src/components/Edges/EdgeText.tsx @@ -1,10 +1,10 @@ -import { memo, useState, type FC, type PropsWithChildren, useCallback } from 'react'; +import { memo, useState, useCallback } from 'react'; import cc from 'classcat'; import type { Rect } from '@xyflow/system'; import type { EdgeTextProps } from '../../types'; -const EdgeText: FC> = ({ +function EdgeTextComponent({ x, y, label, @@ -16,7 +16,7 @@ const EdgeText: FC> = ({ children, className, ...rest -}) => { +}: EdgeTextProps) { const [edgeTextBbox, setEdgeTextBbox] = useState({ x: 1, y: 0, width: 0, height: 0 }); const edgeTextClasses = cc(['react-flow__edge-textwrapper', className]); @@ -68,5 +68,6 @@ const EdgeText: FC> = ({ {children} ); -}; -export default memo(EdgeText); +} + +export const EdgeText = memo(EdgeTextComponent); diff --git a/packages/react/src/components/Edges/SimpleBezierEdge.tsx b/packages/react/src/components/Edges/SimpleBezierEdge.tsx index 09c7a752..b3378c48 100644 --- a/packages/react/src/components/Edges/SimpleBezierEdge.tsx +++ b/packages/react/src/components/Edges/SimpleBezierEdge.tsx @@ -1,7 +1,7 @@ import { memo } from 'react'; import { Position, getBezierEdgeCenter } from '@xyflow/system'; -import BaseEdge from './BaseEdge'; +import { BaseEdge } from './BaseEdge'; import type { SimpleBezierEdgeProps } from '../../types'; export interface GetSimpleBezierPathParams { diff --git a/packages/react/src/components/Edges/SmoothStepEdge.tsx b/packages/react/src/components/Edges/SmoothStepEdge.tsx index 8eb10d89..1f6bcfd1 100644 --- a/packages/react/src/components/Edges/SmoothStepEdge.tsx +++ b/packages/react/src/components/Edges/SmoothStepEdge.tsx @@ -1,7 +1,7 @@ import { memo } from 'react'; import { Position, getSmoothStepPath } from '@xyflow/system'; -import BaseEdge from './BaseEdge'; +import { BaseEdge } from './BaseEdge'; import type { SmoothStepEdgeProps } from '../../types'; function createSmoothStepEdge(params: { isInternal: boolean }) { diff --git a/packages/react/src/components/Edges/StraightEdge.tsx b/packages/react/src/components/Edges/StraightEdge.tsx index 5a3c824d..53d1ac29 100644 --- a/packages/react/src/components/Edges/StraightEdge.tsx +++ b/packages/react/src/components/Edges/StraightEdge.tsx @@ -1,7 +1,7 @@ import { memo } from 'react'; import { getStraightPath } from '@xyflow/system'; -import BaseEdge from './BaseEdge'; +import { BaseEdge } from './BaseEdge'; import type { StraightEdgeProps } from '../../types'; function createStraightEdge(params: { isInternal: boolean }) { diff --git a/packages/react/src/components/Handle/index.tsx b/packages/react/src/components/Handle/index.tsx index a2c0101f..41bf492c 100644 --- a/packages/react/src/components/Handle/index.tsx +++ b/packages/react/src/components/Handle/index.tsx @@ -47,7 +47,7 @@ const connectingSelector = }; }; -const Handle = forwardRef( +const HandleComponent = forwardRef( ( { type = 'source', @@ -216,6 +216,6 @@ const Handle = forwardRef( } ); -Handle.displayName = 'Handle'; +HandleComponent.displayName = 'Handle'; -export default memo(Handle); +export const Handle = memo(HandleComponent); diff --git a/packages/react/src/components/NodeWrapper/index.tsx b/packages/react/src/components/NodeWrapper/index.tsx index 461abf5a..64b5ac66 100644 --- a/packages/react/src/components/NodeWrapper/index.tsx +++ b/packages/react/src/components/NodeWrapper/index.tsx @@ -1,4 +1,4 @@ -import { useEffect, useRef, memo, type MouseEvent, type KeyboardEvent } from 'react'; +import { useEffect, useRef, type MouseEvent, type KeyboardEvent } from 'react'; import cc from 'classcat'; import { shallow } from 'zustand/shallow'; import { @@ -19,7 +19,7 @@ import { handleNodeClick } from '../Nodes/utils'; import { arrowKeyDiffs, builtinNodeTypes } from './utils'; import type { NodeWrapperProps } from '../../types'; -const NodeWrapper = ({ +export function NodeWrapper({ id, onClick, onMouseEnter, @@ -40,7 +40,7 @@ const NodeWrapper = ({ nodeExtent, nodeOrigin, onError, -}: NodeWrapperProps) => { +}: NodeWrapperProps) { const { node, positionAbsoluteX, positionAbsoluteY, zIndex, isParent } = useStore((s) => { const node = s.nodeLookup.get(id)!; @@ -257,8 +257,4 @@ const NodeWrapper = ({
); -}; - -NodeWrapper.displayName = 'NodeWrapper'; - -export default memo(NodeWrapper); +} diff --git a/packages/react/src/components/NodeWrapper/utils.tsx b/packages/react/src/components/NodeWrapper/utils.tsx index 6ae5f994..5dd73964 100644 --- a/packages/react/src/components/NodeWrapper/utils.tsx +++ b/packages/react/src/components/NodeWrapper/utils.tsx @@ -1,10 +1,10 @@ import type { ComponentType } from 'react'; import type { NodeProps, XYPosition } from '@xyflow/system'; -import InputNode from '../Nodes/InputNode'; -import DefaultNode from '../Nodes/DefaultNode'; -import GroupNode from '../Nodes/GroupNode'; -import OutputNode from '../Nodes/OutputNode'; +import { InputNode } from '../Nodes/InputNode'; +import { DefaultNode } from '../Nodes/DefaultNode'; +import { GroupNode } from '../Nodes/GroupNode'; +import { OutputNode } from '../Nodes/OutputNode'; import type { NodeTypes } from '../../types'; export const arrowKeyDiffs: Record = { diff --git a/packages/react/src/components/Nodes/DefaultNode.tsx b/packages/react/src/components/Nodes/DefaultNode.tsx index 611e6165..132044c5 100644 --- a/packages/react/src/components/Nodes/DefaultNode.tsx +++ b/packages/react/src/components/Nodes/DefaultNode.tsx @@ -1,14 +1,13 @@ -import { memo } from 'react'; import { Position, type NodeProps } from '@xyflow/system'; -import Handle from '../../components/Handle'; +import { Handle } from '../../components/Handle'; -const DefaultNode = ({ +export function DefaultNode({ data, isConnectable, targetPosition = Position.Top, sourcePosition = Position.Bottom, -}: NodeProps) => { +}: NodeProps) { return ( <> @@ -16,8 +15,4 @@ const DefaultNode = ({ ); -}; - -DefaultNode.displayName = 'DefaultNode'; - -export default memo(DefaultNode); +} diff --git a/packages/react/src/components/Nodes/GroupNode.tsx b/packages/react/src/components/Nodes/GroupNode.tsx index cea42e43..a8a1ad14 100644 --- a/packages/react/src/components/Nodes/GroupNode.tsx +++ b/packages/react/src/components/Nodes/GroupNode.tsx @@ -1,5 +1,3 @@ -const GroupNode = () => null; - -GroupNode.displayName = 'GroupNode'; - -export default GroupNode; +export function GroupNode() { + return null; +} diff --git a/packages/react/src/components/Nodes/InputNode.tsx b/packages/react/src/components/Nodes/InputNode.tsx index 354da2ce..e4b9da9b 100644 --- a/packages/react/src/components/Nodes/InputNode.tsx +++ b/packages/react/src/components/Nodes/InputNode.tsx @@ -1,15 +1,12 @@ -import { memo } from 'react'; import { Position, type NodeProps } from '@xyflow/system'; -import Handle from '../../components/Handle'; +import { Handle } from '../../components/Handle'; -const InputNode = ({ data, isConnectable, sourcePosition = Position.Bottom }: NodeProps) => ( - <> - {data?.label} - - -); - -InputNode.displayName = 'InputNode'; - -export default memo(InputNode); +export function InputNode({ data, isConnectable, sourcePosition = Position.Bottom }: NodeProps) { + return ( + <> + {data?.label} + + + ); +} diff --git a/packages/react/src/components/Nodes/OutputNode.tsx b/packages/react/src/components/Nodes/OutputNode.tsx index 8d52ba1e..64af091c 100644 --- a/packages/react/src/components/Nodes/OutputNode.tsx +++ b/packages/react/src/components/Nodes/OutputNode.tsx @@ -1,15 +1,12 @@ -import { memo } from 'react'; import { Position, type NodeProps } from '@xyflow/system'; -import Handle from '../../components/Handle'; +import { Handle } from '../../components/Handle'; -const OutputNode = ({ data, isConnectable, targetPosition = Position.Top }: NodeProps) => ( - <> - - {data?.label} - -); - -OutputNode.displayName = 'OutputNode'; - -export default memo(OutputNode); +export function OutputNode({ data, isConnectable, targetPosition = Position.Top }: NodeProps) { + return ( + <> + + {data?.label} + + ); +} diff --git a/packages/react/src/components/Nodes/utils.ts b/packages/react/src/components/Nodes/utils.ts index 26b1f246..81939bbc 100644 --- a/packages/react/src/components/Nodes/utils.ts +++ b/packages/react/src/components/Nodes/utils.ts @@ -1,8 +1,8 @@ import type { RefObject } from 'react'; import type { StoreApi } from 'zustand'; +import { errorMessages } from '@xyflow/system'; import type { ReactFlowState } from '../../types'; -import { errorMessages } from '@xyflow/system'; // this handler is called by // 1. the click handler when node is not draggable or selectNodesOnDrag = false diff --git a/packages/react/src/components/NodesSelection/index.tsx b/packages/react/src/components/NodesSelection/index.tsx index c485d65c..f8aeb77c 100644 --- a/packages/react/src/components/NodesSelection/index.tsx +++ b/packages/react/src/components/NodesSelection/index.tsx @@ -3,7 +3,7 @@ * made a selection with on or several nodes */ -import { memo, useRef, useEffect, type MouseEvent, type KeyboardEvent } from 'react'; +import { useRef, useEffect, type MouseEvent, type KeyboardEvent } from 'react'; import cc from 'classcat'; import { shallow } from 'zustand/shallow'; import { getNodesBounds } from '@xyflow/system'; @@ -32,7 +32,7 @@ const selector = (s: ReactFlowState) => { }; }; -function NodesSelection({ onSelectionContextMenu, noPanClassName, disableKeyboardA11y }: NodesSelectionProps) { +export function NodesSelection({ onSelectionContextMenu, noPanClassName, disableKeyboardA11y }: NodesSelectionProps) { const store = useStoreApi(); const { width, height, transformString, userSelectionActive } = useStore(selector, shallow); const updatePositions = useUpdateNodePositions(); @@ -93,5 +93,3 @@ function NodesSelection({ onSelectionContextMenu, noPanClassName, disableKeyboar ); } - -export default memo(NodesSelection); diff --git a/packages/react/src/components/Panel/index.tsx b/packages/react/src/components/Panel/index.tsx index 7bcf6f97..cde20716 100644 --- a/packages/react/src/components/Panel/index.tsx +++ b/packages/react/src/components/Panel/index.tsx @@ -6,13 +6,13 @@ import { useStore } from '../../hooks/useStore'; import type { ReactFlowState } from '../../types'; export type PanelProps = HTMLAttributes & { - position: PanelPosition; + position?: PanelPosition; children: ReactNode; }; const selector = (s: ReactFlowState) => (s.userSelectionActive ? 'none' : 'all'); -function Panel({ position, children, className, style, ...rest }: PanelProps) { +export function Panel({ position = 'top-left', children, className, style, ...rest }: PanelProps) { const pointerEvents = useStore(selector); const positionClasses = `${position}`.split('-'); @@ -26,5 +26,3 @@ function Panel({ position, children, className, style, ...rest }: PanelProps) { ); } - -export default Panel; diff --git a/packages/react/src/components/ReactFlowProvider/index.tsx b/packages/react/src/components/ReactFlowProvider/index.tsx index 07f011ca..34999c6f 100644 --- a/packages/react/src/components/ReactFlowProvider/index.tsx +++ b/packages/react/src/components/ReactFlowProvider/index.tsx @@ -6,7 +6,7 @@ import { Provider } from '../../contexts/RFStoreContext'; import { createRFStore } from '../../store'; import type { ReactFlowState, Node, Edge } from '../../types'; -function ReactFlowProvider({ +export function ReactFlowProvider({ children, initialNodes, initialEdges, @@ -35,7 +35,3 @@ function ReactFlowProvider({ return {children}; } - -ReactFlowProvider.displayName = 'ReactFlowProvider'; - -export default ReactFlowProvider; diff --git a/packages/react/src/components/SelectionListener/index.tsx b/packages/react/src/components/SelectionListener/index.tsx index 4ef1e130..0a3fa5a9 100644 --- a/packages/react/src/components/SelectionListener/index.tsx +++ b/packages/react/src/components/SelectionListener/index.tsx @@ -4,7 +4,7 @@ * or is using the useOnSelectionChange hook. * @TODO: Now that we have the onNodesChange and on EdgesChange listeners, do we still need this component? */ -import { memo, useEffect } from 'react'; +import { useEffect } from 'react'; import { shallow } from 'zustand/shallow'; import { useStore, useStoreApi } from '../../hooks/useStore'; @@ -30,7 +30,7 @@ function areEqual(a: SelectorSlice, b: SelectorSlice) { ); } -const SelectionListener = memo(({ onSelectionChange }: SelectionListenerProps) => { +function SelectionListenerInner({ onSelectionChange }: SelectionListenerProps) { const store = useStoreApi(); const { selectedNodes, selectedEdges } = useStore(selector, areEqual); @@ -42,20 +42,16 @@ const SelectionListener = memo(({ onSelectionChange }: SelectionListenerProps) = }, [selectedNodes, selectedEdges, onSelectionChange]); return null; -}); - -SelectionListener.displayName = 'SelectionListener'; +} const changeSelector = (s: ReactFlowState) => !!s.onSelectionChangeHandlers; -function Wrapper({ onSelectionChange }: SelectionListenerProps) { +export function SelectionListener({ onSelectionChange }: SelectionListenerProps) { const storeHasSelectionChangeHandlers = useStore(changeSelector); if (onSelectionChange || storeHasSelectionChangeHandlers) { - return ; + return ; } return null; } - -export default Wrapper; diff --git a/packages/react/src/components/StoreUpdater/index.tsx b/packages/react/src/components/StoreUpdater/index.tsx index 344c718f..3a12594c 100644 --- a/packages/react/src/components/StoreUpdater/index.tsx +++ b/packages/react/src/components/StoreUpdater/index.tsx @@ -84,7 +84,7 @@ const selector = (s: ReactFlowState) => ({ reset: s.reset, }); -const StoreUpdater = (props: StoreUpdaterProps) => { +export function StoreUpdater(props: StoreUpdaterProps) { const { setNodes, setEdges, @@ -149,6 +149,4 @@ const StoreUpdater = (props: StoreUpdaterProps) => { ); return null; -}; - -export default StoreUpdater; +} diff --git a/packages/react/src/components/UserSelection/index.tsx b/packages/react/src/components/UserSelection/index.tsx index 00bbcd63..45a4e228 100644 --- a/packages/react/src/components/UserSelection/index.tsx +++ b/packages/react/src/components/UserSelection/index.tsx @@ -8,7 +8,7 @@ const selector = (s: ReactFlowState) => ({ userSelectionRect: s.userSelectionRect, }); -function UserSelection() { +export function UserSelection() { const { userSelectionActive, userSelectionRect } = useStore(selector, shallow); const isActive = userSelectionActive && userSelectionRect; @@ -27,5 +27,3 @@ function UserSelection() { /> ); } - -export default UserSelection; diff --git a/packages/react/src/components/ViewportPortal/index.tsx b/packages/react/src/components/ViewportPortal/index.tsx index 4195a608..c1b9b406 100644 --- a/packages/react/src/components/ViewportPortal/index.tsx +++ b/packages/react/src/components/ViewportPortal/index.tsx @@ -6,7 +6,7 @@ import type { ReactFlowState } from '../../types'; const selector = (s: ReactFlowState) => s.domNode?.querySelector('.react-flow__viewport-portal'); -function ViewportPortal({ children }: { children: ReactNode }) { +export function ViewportPortal({ children }: { children: ReactNode }) { const viewPortalDiv = useStore(selector); if (!viewPortalDiv) { @@ -15,5 +15,3 @@ function ViewportPortal({ children }: { children: ReactNode }) { return createPortal(children, viewPortalDiv); } - -export default ViewportPortal; diff --git a/packages/react/src/container/EdgeRenderer/MarkerSymbols.tsx b/packages/react/src/container/EdgeRenderer/MarkerSymbols.tsx index 13ebfd92..6b59d04e 100644 --- a/packages/react/src/container/EdgeRenderer/MarkerSymbols.tsx +++ b/packages/react/src/container/EdgeRenderer/MarkerSymbols.tsx @@ -57,5 +57,3 @@ export function useMarkerSymbol(type: MarkerType) { return symbol; } - -export default MarkerSymbols; diff --git a/packages/react/src/container/EdgeRenderer/index.tsx b/packages/react/src/container/EdgeRenderer/index.tsx index ef78ed80..5fdaa1af 100644 --- a/packages/react/src/container/EdgeRenderer/index.tsx +++ b/packages/react/src/container/EdgeRenderer/index.tsx @@ -2,10 +2,10 @@ import { memo, ReactNode } from 'react'; import { shallow } from 'zustand/shallow'; import { useStore } from '../../hooks/useStore'; -import useVisibleEdgeIds from '../../hooks/useVisibleEdgeIds'; +import { useVisibleEdgeIds } from '../../hooks/useVisibleEdgeIds'; import MarkerDefinitions from './MarkerDefinitions'; import { GraphViewProps } from '../GraphView'; -import EdgeWrapper from '../../components/EdgeWrapper'; +import { EdgeWrapper } from '../../components/EdgeWrapper'; import type { ReactFlowState } from '../../types'; type EdgeRendererProps = Pick< @@ -40,7 +40,7 @@ const selector = (s: ReactFlowState) => ({ onError: s.onError, }); -const EdgeRenderer = ({ +function EdgeRendererComponent({ defaultMarkerColor, onlyRenderVisibleElements, rfId, @@ -56,8 +56,7 @@ const EdgeRenderer = ({ onEdgeDoubleClick, onEdgeUpdateStart, onEdgeUpdateEnd, - children, -}: EdgeRendererProps) => { +}: EdgeRendererProps) { const { edgesFocusable, edgesUpdatable, elementsSelectable, onError } = useStore(selector, shallow); const edgeIds = useVisibleEdgeIds(onlyRenderVisibleElements); @@ -90,11 +89,10 @@ const EdgeRenderer = ({ /> ); })} - {children} ); -}; +} -EdgeRenderer.displayName = 'EdgeRenderer'; +EdgeRendererComponent.displayName = 'EdgeRenderer'; -export default memo(EdgeRenderer); +export const EdgeRenderer = memo(EdgeRendererComponent); diff --git a/packages/react/src/container/FlowRenderer/index.tsx b/packages/react/src/container/FlowRenderer/index.tsx index 04604ec9..06d6fab6 100644 --- a/packages/react/src/container/FlowRenderer/index.tsx +++ b/packages/react/src/container/FlowRenderer/index.tsx @@ -4,9 +4,9 @@ import { useStore } from '../../hooks/useStore'; import { useGlobalKeyHandler } from '../../hooks/useGlobalKeyHandler'; import { useKeyPress } from '../../hooks/useKeyPress'; import { GraphViewProps } from '../GraphView'; -import ZoomPane from '../ZoomPane'; -import Pane from '../Pane'; -import NodesSelection from '../../components/NodesSelection'; +import { ZoomPane } from '../ZoomPane'; +import { Pane } from '../Pane'; +import { NodesSelection } from '../../components/NodesSelection'; import type { ReactFlowState } from '../../types'; export type FlowRendererProps = Omit< @@ -30,7 +30,7 @@ export type FlowRendererProps = Omit< const selector = (s: ReactFlowState) => s.nodesSelectionActive; -const FlowRenderer = ({ +const FlowRendererComponent = ({ children, onPaneClick, onPaneMouseEnter, @@ -125,6 +125,6 @@ const FlowRenderer = ({ ); }; -FlowRenderer.displayName = 'FlowRenderer'; +FlowRendererComponent.displayName = 'FlowRenderer'; -export default memo(FlowRenderer); +export const FlowRenderer = memo(FlowRendererComponent); diff --git a/packages/react/src/container/GraphView/index.tsx b/packages/react/src/container/GraphView/index.tsx index ae67d6b4..fd7ac277 100644 --- a/packages/react/src/container/GraphView/index.tsx +++ b/packages/react/src/container/GraphView/index.tsx @@ -1,14 +1,14 @@ import { memo } from 'react'; -import FlowRenderer from '../FlowRenderer'; -import NodeRenderer from '../NodeRenderer'; -import EdgeRenderer from '../EdgeRenderer'; -import ViewportWrapper from '../Viewport'; +import { FlowRenderer } from '../FlowRenderer'; +import { NodeRenderer } from '../NodeRenderer'; +import { EdgeRenderer } from '../EdgeRenderer'; +import { Viewport } from '../Viewport'; import { useOnInitHandler } from '../../hooks/useOnInitHandler'; import { useViewportSync } from '../../hooks/useViewportSync'; -import ConnectionLine from '../../components/ConnectionLine'; -import type { ReactFlowProps } from '../../types'; +import { ConnectionLineWrapper } from '../../components/ConnectionLine'; import { useNodeOrEdgeTypesWarning } from './useNodeOrEdgeTypesWarning'; +import type { ReactFlowProps } from '../../types'; export type GraphViewProps = Omit< ReactFlowProps, @@ -38,7 +38,7 @@ export type GraphViewProps = Omit< rfId: string; }; -const GraphView = ({ +function GraphViewComponent({ nodeTypes, edgeTypes, onInit, @@ -102,7 +102,7 @@ const GraphView = ({ rfId, viewport, onViewportChange, -}: GraphViewProps) => { +}: GraphViewProps) { useNodeOrEdgeTypesWarning(nodeTypes); useNodeOrEdgeTypesWarning(edgeTypes); @@ -147,7 +147,7 @@ const GraphView = ({ onViewportChange={onViewportChange} isControlledViewport={!!viewport} > - + - - + ); -}; +} -GraphView.displayName = 'GraphView'; +GraphViewComponent.displayName = 'GraphView'; -export default memo(GraphView); +export const GraphView = memo(GraphViewComponent); diff --git a/packages/react/src/container/NodeRenderer/index.tsx b/packages/react/src/container/NodeRenderer/index.tsx index e61b8bc5..11cab66f 100644 --- a/packages/react/src/container/NodeRenderer/index.tsx +++ b/packages/react/src/container/NodeRenderer/index.tsx @@ -1,13 +1,13 @@ import { memo } from 'react'; import { shallow } from 'zustand/shallow'; -import useVisibleNodesIds from '../../hooks/useVisibleNodeIds'; +import { useVisibleNodeIds } from '../../hooks/useVisibleNodeIds'; import { useStore } from '../../hooks/useStore'; import { containerStyle } from '../../styles/utils'; import { GraphViewProps } from '../GraphView'; +import { useResizeObserver } from './useResizeObserver'; +import { NodeWrapper } from '../../components/NodeWrapper'; import type { ReactFlowState } from '../../types'; -import useResizeObserver from './useResizeObserver'; -import NodeWrapper from '../../components/NodeWrapper'; export type NodeRendererProps = Pick< GraphViewProps, @@ -35,9 +35,9 @@ const selector = (s: ReactFlowState) => ({ onError: s.onError, }); -const NodeRenderer = (props: NodeRendererProps) => { +const NodeRendererComponent = (props: NodeRendererProps) => { const { nodesDraggable, nodesConnectable, nodesFocusable, elementsSelectable, onError } = useStore(selector, shallow); - const nodeIds = useVisibleNodesIds(props.onlyRenderVisibleElements); + const nodeIds = useVisibleNodeIds(props.onlyRenderVisibleElements); const resizeObserver = useResizeObserver(); return ( @@ -96,6 +96,6 @@ const NodeRenderer = (props: NodeRendererProps) => { ); }; -NodeRenderer.displayName = 'NodeRenderer'; +NodeRendererComponent.displayName = 'NodeRenderer'; -export default memo(NodeRenderer); +export const NodeRenderer = memo(NodeRendererComponent); diff --git a/packages/react/src/container/NodeRenderer/useResizeObserver.ts b/packages/react/src/container/NodeRenderer/useResizeObserver.ts index d109d798..f0d0a22e 100644 --- a/packages/react/src/container/NodeRenderer/useResizeObserver.ts +++ b/packages/react/src/container/NodeRenderer/useResizeObserver.ts @@ -5,7 +5,7 @@ import { useStore } from '../../hooks/useStore'; const selector = (s: ReactFlowState) => s.updateNodeDimensions; -export default function useResizeObserver() { +export function useResizeObserver() { const updateNodeDimensions = useStore(selector); const resizeObserverRef = useRef(); diff --git a/packages/react/src/container/Pane/index.tsx b/packages/react/src/container/Pane/index.tsx index 6acd7770..af1ca28e 100644 --- a/packages/react/src/container/Pane/index.tsx +++ b/packages/react/src/container/Pane/index.tsx @@ -2,12 +2,12 @@ * The user selection rectangle gets displayed when a user drags the mouse while pressing shift */ -import { memo, useRef, type MouseEvent as ReactMouseEvent, type ReactNode } from 'react'; +import { useRef, type MouseEvent as ReactMouseEvent, type ReactNode } from 'react'; import { shallow } from 'zustand/shallow'; import cc from 'classcat'; import { getNodesInside, getEventPosition, SelectionMode } from '@xyflow/system'; -import UserSelection from '../../components/UserSelection'; +import { UserSelection } from '../../components/UserSelection'; import { containerStyle } from '../../styles/utils'; import { useStore, useStoreApi } from '../../hooks/useStore'; import { getSelectionChanges } from '../../utils'; @@ -50,196 +50,190 @@ const selector = (s: ReactFlowState) => ({ dragging: s.paneDragging, }); -const Pane = memo( - ({ - isSelecting, - selectionMode = SelectionMode.Full, - panOnDrag, - onSelectionStart, - onSelectionEnd, - onPaneClick, - onPaneContextMenu, - onPaneScroll, - onPaneMouseEnter, - onPaneMouseMove, - onPaneMouseLeave, - children, - }: PaneProps) => { - const container = useRef(null); - const store = useStoreApi(); - const prevSelectedNodesCount = useRef(0); - const prevSelectedEdgesCount = useRef(0); - const containerBounds = useRef(); - const { userSelectionActive, elementsSelectable, dragging } = useStore(selector, shallow); +export function Pane({ + isSelecting, + selectionMode = SelectionMode.Full, + panOnDrag, + onSelectionStart, + onSelectionEnd, + onPaneClick, + onPaneContextMenu, + onPaneScroll, + onPaneMouseEnter, + onPaneMouseMove, + onPaneMouseLeave, + children, +}: PaneProps) { + const container = useRef(null); + const store = useStoreApi(); + const prevSelectedNodesCount = useRef(0); + const prevSelectedEdgesCount = useRef(0); + const containerBounds = useRef(); + const { userSelectionActive, elementsSelectable, dragging } = useStore(selector, shallow); - const resetUserSelection = () => { - store.setState({ userSelectionActive: false, userSelectionRect: null }); + const resetUserSelection = () => { + store.setState({ userSelectionActive: false, userSelectionRect: null }); - prevSelectedNodesCount.current = 0; - prevSelectedEdgesCount.current = 0; + prevSelectedNodesCount.current = 0; + prevSelectedEdgesCount.current = 0; + }; + + const onClick = (event: ReactMouseEvent) => { + onPaneClick?.(event); + store.getState().resetSelectedElements(); + store.setState({ nodesSelectionActive: false }); + }; + + const onContextMenu = (event: ReactMouseEvent) => { + if (Array.isArray(panOnDrag) && panOnDrag?.includes(2)) { + event.preventDefault(); + return; + } + + onPaneContextMenu?.(event); + }; + + const onWheel = onPaneScroll ? (event: React.WheelEvent) => onPaneScroll(event) : undefined; + + const onMouseDown = (event: ReactMouseEvent): void => { + const { resetSelectedElements, domNode } = store.getState(); + containerBounds.current = domNode?.getBoundingClientRect(); + + if ( + !elementsSelectable || + !isSelecting || + event.button !== 0 || + event.target !== container.current || + !containerBounds.current + ) { + return; + } + + const { x, y } = getEventPosition(event.nativeEvent, containerBounds.current); + + resetSelectedElements(); + + store.setState({ + userSelectionRect: { + width: 0, + height: 0, + startX: x, + startY: y, + x, + y, + }, + }); + + onSelectionStart?.(event); + }; + + const onMouseMove = (event: ReactMouseEvent): void => { + const { userSelectionRect, edges, transform, nodeOrigin, nodes, onNodesChange, onEdgesChange } = store.getState(); + if (!isSelecting || !containerBounds.current || !userSelectionRect) { + return; + } + + store.setState({ userSelectionActive: true, nodesSelectionActive: false }); + + const mousePos = getEventPosition(event.nativeEvent, containerBounds.current); + const startX = userSelectionRect.startX ?? 0; + const startY = userSelectionRect.startY ?? 0; + + const nextUserSelectRect = { + ...userSelectionRect, + x: mousePos.x < startX ? mousePos.x : startX, + y: mousePos.y < startY ? mousePos.y : startY, + width: Math.abs(mousePos.x - startX), + height: Math.abs(mousePos.y - startY), }; - const onClick = (event: ReactMouseEvent) => { - onPaneClick?.(event); - store.getState().resetSelectedElements(); - store.setState({ nodesSelectionActive: false }); - }; - - const onContextMenu = (event: ReactMouseEvent) => { - if (Array.isArray(panOnDrag) && panOnDrag?.includes(2)) { - event.preventDefault(); - return; - } - - onPaneContextMenu?.(event); - }; - - const onWheel = onPaneScroll ? (event: React.WheelEvent) => onPaneScroll(event) : undefined; - - const onMouseDown = (event: ReactMouseEvent): void => { - const { resetSelectedElements, domNode } = store.getState(); - containerBounds.current = domNode?.getBoundingClientRect(); - - if ( - !elementsSelectable || - !isSelecting || - event.button !== 0 || - event.target !== container.current || - !containerBounds.current - ) { - return; - } - - const { x, y } = getEventPosition(event.nativeEvent, containerBounds.current); - - resetSelectedElements(); - - store.setState({ - userSelectionRect: { - width: 0, - height: 0, - startX: x, - startY: y, - x, - y, - }, - }); - - onSelectionStart?.(event); - }; - - const onMouseMove = (event: ReactMouseEvent): void => { - const { userSelectionRect, edges, transform, nodeOrigin, nodes, onNodesChange, onEdgesChange } = store.getState(); - if (!isSelecting || !containerBounds.current || !userSelectionRect) { - return; - } - - store.setState({ userSelectionActive: true, nodesSelectionActive: false }); - - const mousePos = getEventPosition(event.nativeEvent, containerBounds.current); - const startX = userSelectionRect.startX ?? 0; - const startY = userSelectionRect.startY ?? 0; - - const nextUserSelectRect = { - ...userSelectionRect, - x: mousePos.x < startX ? mousePos.x : startX, - y: mousePos.y < startY ? mousePos.y : startY, - width: Math.abs(mousePos.x - startX), - height: Math.abs(mousePos.y - startY), - }; - - const selectedNodes = getNodesInside( - nodes, - nextUserSelectRect, - transform, - selectionMode === SelectionMode.Partial, - true, - nodeOrigin - ); - - const selectedEdgeIds = new Set(); - const selectedNodeIds = new Set(); - - for (const selectedNode of selectedNodes) { - selectedNodeIds.add(selectedNode.id); - - for (const edge of edges) { - if (edge.source === selectedNode.id || edge.target === selectedNode.id) { - selectedEdgeIds.add(edge.id); - } - } - } - - if (prevSelectedNodesCount.current !== selectedNodeIds.size) { - prevSelectedNodesCount.current = selectedNodeIds.size; - const changes = getSelectionChanges(nodes, selectedNodeIds, true) as NodeChange[]; - if (changes.length) { - onNodesChange?.(changes); - } - } - - if (prevSelectedEdgesCount.current !== selectedEdgeIds.size) { - prevSelectedEdgesCount.current = selectedEdgeIds.size; - const changes = getSelectionChanges(edges, selectedEdgeIds) as EdgeChange[]; - if (changes.length) { - onEdgesChange?.(changes); - } - } - - store.setState({ - userSelectionRect: nextUserSelectRect, - }); - }; - - const onMouseUp = (event: ReactMouseEvent) => { - if (event.button !== 0) { - return; - } - const { userSelectionRect } = store.getState(); - // We only want to trigger click functions when in selection mode if - // the user did not move the mouse. - if (!userSelectionActive && userSelectionRect && event.target === container.current) { - onClick?.(event); - } - - store.setState({ nodesSelectionActive: prevSelectedNodesCount.current > 0 }); - - resetUserSelection(); - onSelectionEnd?.(event); - }; - - const onMouseLeave = (event: ReactMouseEvent) => { - if (userSelectionActive) { - store.setState({ nodesSelectionActive: prevSelectedNodesCount.current > 0 }); - onSelectionEnd?.(event); - } - - resetUserSelection(); - }; - - const hasActiveSelection = elementsSelectable && (isSelecting || userSelectionActive); - - return ( -
- {children} - -
+ const selectedNodes = getNodesInside( + nodes, + nextUserSelectRect, + transform, + selectionMode === SelectionMode.Partial, + true, + nodeOrigin ); - } -); -Pane.displayName = 'Pane'; + const selectedEdgeIds = new Set(); + const selectedNodeIds = new Set(); -export default Pane; + for (const selectedNode of selectedNodes) { + selectedNodeIds.add(selectedNode.id); + + for (const edge of edges) { + if (edge.source === selectedNode.id || edge.target === selectedNode.id) { + selectedEdgeIds.add(edge.id); + } + } + } + + if (prevSelectedNodesCount.current !== selectedNodeIds.size) { + prevSelectedNodesCount.current = selectedNodeIds.size; + const changes = getSelectionChanges(nodes, selectedNodeIds, true) as NodeChange[]; + if (changes.length) { + onNodesChange?.(changes); + } + } + + if (prevSelectedEdgesCount.current !== selectedEdgeIds.size) { + prevSelectedEdgesCount.current = selectedEdgeIds.size; + const changes = getSelectionChanges(edges, selectedEdgeIds) as EdgeChange[]; + if (changes.length) { + onEdgesChange?.(changes); + } + } + + store.setState({ + userSelectionRect: nextUserSelectRect, + }); + }; + + const onMouseUp = (event: ReactMouseEvent) => { + if (event.button !== 0) { + return; + } + const { userSelectionRect } = store.getState(); + // We only want to trigger click functions when in selection mode if + // the user did not move the mouse. + if (!userSelectionActive && userSelectionRect && event.target === container.current) { + onClick?.(event); + } + + store.setState({ nodesSelectionActive: prevSelectedNodesCount.current > 0 }); + + resetUserSelection(); + onSelectionEnd?.(event); + }; + + const onMouseLeave = (event: ReactMouseEvent) => { + if (userSelectionActive) { + store.setState({ nodesSelectionActive: prevSelectedNodesCount.current > 0 }); + onSelectionEnd?.(event); + } + + resetUserSelection(); + }; + + const hasActiveSelection = elementsSelectable && (isSelecting || userSelectionActive); + + return ( +
+ {children} + +
+ ); +} diff --git a/packages/react/src/container/ReactFlow/Wrapper.tsx b/packages/react/src/container/ReactFlow/Wrapper.tsx index d658c5a3..4d3cb7b7 100644 --- a/packages/react/src/container/ReactFlow/Wrapper.tsx +++ b/packages/react/src/container/ReactFlow/Wrapper.tsx @@ -1,10 +1,10 @@ import { useContext, type ReactNode } from 'react'; import StoreContext from '../../contexts/RFStoreContext'; -import ReactFlowProvider from '../../components/ReactFlowProvider'; +import { ReactFlowProvider } from '../../components/ReactFlowProvider'; import type { Node, Edge } from '../../types'; -function Wrapper({ +export function Wrapper({ children, nodes, edges, @@ -39,7 +39,3 @@ function Wrapper({ ); } - -Wrapper.displayName = 'ReactFlowWrapper'; - -export default Wrapper; diff --git a/packages/react/src/container/ReactFlow/index.tsx b/packages/react/src/container/ReactFlow/index.tsx index 5f1f2628..d64af5ec 100644 --- a/packages/react/src/container/ReactFlow/index.tsx +++ b/packages/react/src/container/ReactFlow/index.tsx @@ -5,19 +5,18 @@ import { PanOnScrollMode, SelectionMode, infiniteExtent, + isMacOs, type NodeOrigin, type Viewport, - isMacOs, } from '@xyflow/system'; -import Attribution from '../../components/Attribution'; - -import SelectionListener from '../../components/SelectionListener'; -import StoreUpdater from '../../components/StoreUpdater'; -import A11yDescriptions from '../../components/A11yDescriptions'; +import { A11yDescriptions } from '../../components/A11yDescriptions'; +import { Attribution } from '../../components/Attribution'; +import { SelectionListener } from '../../components/SelectionListener'; +import { StoreUpdater } from '../../components/StoreUpdater'; import { useColorModeClass } from '../../hooks/useColorModeClass'; -import GraphView from '../GraphView'; -import Wrapper from './Wrapper'; +import { GraphView } from '../GraphView'; +import { Wrapper } from './Wrapper'; import type { ReactFlowProps, ReactFlowRefType } from '../../types'; export const initNodeOrigin: NodeOrigin = [0, 0]; diff --git a/packages/react/src/container/Viewport/index.tsx b/packages/react/src/container/Viewport/index.tsx index b0de6954..bf12b907 100644 --- a/packages/react/src/container/Viewport/index.tsx +++ b/packages/react/src/container/Viewport/index.tsx @@ -9,7 +9,7 @@ type ViewportProps = { children: ReactNode; }; -export default function Viewport({ children }: ViewportProps) { +export function Viewport({ children }: ViewportProps) { const transform = useStore(selector); return ( diff --git a/packages/react/src/container/ZoomPane/index.tsx b/packages/react/src/container/ZoomPane/index.tsx index f79e5c29..f6e7a79c 100644 --- a/packages/react/src/container/ZoomPane/index.tsx +++ b/packages/react/src/container/ZoomPane/index.tsx @@ -27,7 +27,7 @@ const selector = (s: ReactFlowState) => ({ lib: s.lib, }); -const ZoomPane = ({ +export function ZoomPane({ onPaneContextMenu, zoomOnScroll = true, zoomOnPinch = true, @@ -47,7 +47,7 @@ const ZoomPane = ({ noPanClassName, onViewportChange, isControlledViewport, -}: ZoomPaneProps) => { +}: ZoomPaneProps) { const store = useStoreApi(); const zoomPane = useRef(null); const { userSelectionActive, lib } = useStore(selector, shallow); @@ -142,6 +142,4 @@ const ZoomPane = ({ {children} ); -}; - -export default ZoomPane; +} diff --git a/packages/react/src/hooks/useVisibleEdgeIds.ts b/packages/react/src/hooks/useVisibleEdgeIds.ts index ceb40f31..4505de9c 100644 --- a/packages/react/src/hooks/useVisibleEdgeIds.ts +++ b/packages/react/src/hooks/useVisibleEdgeIds.ts @@ -12,7 +12,7 @@ import { type ReactFlowState } from '../types'; * @param onlyRenderVisible * @returns array with visible edge ids */ -function useVisibleEdgeIds(onlyRenderVisible: boolean): string[] { +export function useVisibleEdgeIds(onlyRenderVisible: boolean): string[] { const edgeIds = useStore( useCallback( (s: ReactFlowState) => { @@ -52,5 +52,3 @@ function useVisibleEdgeIds(onlyRenderVisible: boolean): string[] { return edgeIds; } - -export default useVisibleEdgeIds; diff --git a/packages/react/src/hooks/useVisibleNodeIds.ts b/packages/react/src/hooks/useVisibleNodeIds.ts index 803fde6d..309391dc 100644 --- a/packages/react/src/hooks/useVisibleNodeIds.ts +++ b/packages/react/src/hooks/useVisibleNodeIds.ts @@ -20,10 +20,8 @@ const selector = (onlyRenderVisible: boolean) => (s: ReactFlowState) => { * @param onlyRenderVisible * @returns array with visible node ids */ -function useVisibleNodeIds(onlyRenderVisible: boolean) { +export function useVisibleNodeIds(onlyRenderVisible: boolean) { const nodeIds = useStore(useCallback(selector(onlyRenderVisible), [onlyRenderVisible]), shallow); return nodeIds; } - -export default useVisibleNodeIds; diff --git a/packages/react/src/index.ts b/packages/react/src/index.ts index 3d419470..c0f28fa9 100644 --- a/packages/react/src/index.ts +++ b/packages/react/src/index.ts @@ -1,16 +1,16 @@ export { default as ReactFlow } from './container/ReactFlow'; -export { default as Handle, type HandleComponentProps } from './components/Handle'; -export { default as EdgeText } from './components/Edges/EdgeText'; +export { Handle, type HandleComponentProps } from './components/Handle'; +export { EdgeText } from './components/Edges/EdgeText'; export { StraightEdge } from './components/Edges/StraightEdge'; export { StepEdge } from './components/Edges/StepEdge'; export { BezierEdge } from './components/Edges/BezierEdge'; export { SimpleBezierEdge, getSimpleBezierPath } from './components/Edges/SimpleBezierEdge'; export { SmoothStepEdge } from './components/Edges/SmoothStepEdge'; -export { default as BaseEdge } from './components/Edges/BaseEdge'; -export { default as ReactFlowProvider } from './components/ReactFlowProvider'; -export { default as Panel, type PanelProps } from './components/Panel'; -export { default as EdgeLabelRenderer } from './components/EdgeLabelRenderer'; -export { default as ViewportPortal } from './components/ViewportPortal'; +export { BaseEdge } from './components/Edges/BaseEdge'; +export { ReactFlowProvider } from './components/ReactFlowProvider'; +export { Panel, type PanelProps } from './components/Panel'; +export { EdgeLabelRenderer } from './components/EdgeLabelRenderer'; +export { ViewportPortal } from './components/ViewportPortal'; export { useReactFlow } from './hooks/useReactFlow'; export { useUpdateNodeInternals } from './hooks/useUpdateNodeInternals';