fix(react): apply defaultEdgeOptions marker closes #3826
This commit is contained in:
@@ -175,6 +175,15 @@ const edgeTypes: EdgeTypes = {
|
|||||||
custom2: CustomEdge2,
|
custom2: CustomEdge2,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const defaultEdgeOptions = {
|
||||||
|
markerEnd: {
|
||||||
|
type: MarkerType.ArrowClosed,
|
||||||
|
color: 'red',
|
||||||
|
width: 20,
|
||||||
|
height: 20,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
const EdgesFlow = () => {
|
const EdgesFlow = () => {
|
||||||
const [nodes, , onNodesChange] = useNodesState(initialNodes);
|
const [nodes, , onNodesChange] = useNodesState(initialNodes);
|
||||||
const [edges, setEdges, onEdgesChange] = useEdgesState(initialEdges);
|
const [edges, setEdges, onEdgesChange] = useEdgesState(initialEdges);
|
||||||
@@ -197,6 +206,7 @@ const EdgesFlow = () => {
|
|||||||
onEdgeMouseMove={onEdgeMouseMove}
|
onEdgeMouseMove={onEdgeMouseMove}
|
||||||
onEdgeMouseLeave={onEdgeMouseLeave}
|
onEdgeMouseLeave={onEdgeMouseLeave}
|
||||||
onDelete={console.log}
|
onDelete={console.log}
|
||||||
|
defaultEdgeOptions={defaultEdgeOptions}
|
||||||
>
|
>
|
||||||
<MiniMap />
|
<MiniMap />
|
||||||
<Controls />
|
<Controls />
|
||||||
|
|||||||
@@ -6,7 +6,8 @@
|
|||||||
|
|
||||||
- selection box is not interrupted by selectionKey being let go
|
- selection box is not interrupted by selectionKey being let go
|
||||||
- fix `OnNodeDrag` type
|
- fix `OnNodeDrag` type
|
||||||
- refactor(handles): do not use fallback handle if an id is being used #3409
|
- do not use fallback handle if a specific id is being used
|
||||||
|
- fix `defaultEdgeOptions` markers not being applied
|
||||||
|
|
||||||
## 12.0.0-next.7
|
## 12.0.0-next.7
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,8 @@
|
|||||||
import { memo, useCallback } from 'react';
|
import { memo, useMemo } from 'react';
|
||||||
import { type MarkerProps, createMarkerIds } from '@xyflow/system';
|
import { type MarkerProps, createMarkerIds } from '@xyflow/system';
|
||||||
|
|
||||||
import { useStore } from '../../hooks/useStore';
|
import { useStore } from '../../hooks/useStore';
|
||||||
import { useMarkerSymbol } from './MarkerSymbols';
|
import { useMarkerSymbol } from './MarkerSymbols';
|
||||||
import type { ReactFlowState } from '../../types';
|
|
||||||
|
|
||||||
type MarkerDefinitionsProps = {
|
type MarkerDefinitionsProps = {
|
||||||
defaultColor: string;
|
defaultColor: string;
|
||||||
@@ -43,23 +42,23 @@ const Marker = ({
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const markerSelector =
|
|
||||||
({ defaultColor, rfId }: { defaultColor: string; rfId?: string }) =>
|
|
||||||
(s: ReactFlowState) => {
|
|
||||||
const markers = createMarkerIds(s.edges, { id: rfId, defaultColor });
|
|
||||||
|
|
||||||
return markers;
|
|
||||||
};
|
|
||||||
|
|
||||||
const markersEqual = (a: MarkerProps[], b: MarkerProps[]) =>
|
|
||||||
// the id includes all marker options, so we just need to look at that part of the marker
|
|
||||||
!(a.length !== b.length || a.some((m, i) => m.id !== b[i].id));
|
|
||||||
|
|
||||||
// when you have multiple flows on a page and you hide the first one, the other ones have no markers anymore
|
// when you have multiple flows on a page and you hide the first one, the other ones have no markers anymore
|
||||||
// when they do have markers with the same ids. To prevent this the user can pass a unique id to the react flow wrapper
|
// when they do have markers with the same ids. To prevent this the user can pass a unique id to the react flow wrapper
|
||||||
// that we can then use for creating our unique marker ids
|
// that we can then use for creating our unique marker ids
|
||||||
const MarkerDefinitions = ({ defaultColor, rfId }: MarkerDefinitionsProps) => {
|
const MarkerDefinitions = ({ defaultColor, rfId }: MarkerDefinitionsProps) => {
|
||||||
const markers = useStore(useCallback(markerSelector({ defaultColor, rfId }), [defaultColor, rfId]), markersEqual);
|
const edges = useStore((s) => s.edges);
|
||||||
|
const defaultEdgeOptions = useStore((s) => s.defaultEdgeOptions);
|
||||||
|
|
||||||
|
const markers = useMemo(() => {
|
||||||
|
const markers = createMarkerIds(edges, {
|
||||||
|
id: rfId,
|
||||||
|
defaultColor,
|
||||||
|
defaultMarkerStart: defaultEdgeOptions?.markerStart,
|
||||||
|
defaultMarkerEnd: defaultEdgeOptions?.markerEnd,
|
||||||
|
});
|
||||||
|
|
||||||
|
return markers;
|
||||||
|
}, [edges, defaultEdgeOptions, rfId, defaultColor]);
|
||||||
|
|
||||||
if (!markers.length) {
|
if (!markers.length) {
|
||||||
return null;
|
return null;
|
||||||
|
|||||||
@@ -11,7 +11,8 @@
|
|||||||
|
|
||||||
- selection box is not interrupted by selectionKey being let go
|
- selection box is not interrupted by selectionKey being let go
|
||||||
- Edge label has a default background and is clickable
|
- Edge label has a default background and is clickable
|
||||||
- refactor(handles): do not use fallback handle if an id is being used #3409
|
- do not use fallback handle if a specific id is being used
|
||||||
|
- use correct id for `<Handle />` data-id attribute
|
||||||
|
|
||||||
## 0.0.34
|
## 0.0.34
|
||||||
|
|
||||||
|
|||||||
@@ -19,21 +19,32 @@ export function getMarkerId(marker: EdgeMarkerType | undefined, id?: string | nu
|
|||||||
|
|
||||||
export function createMarkerIds(
|
export function createMarkerIds(
|
||||||
edges: EdgeBase[],
|
edges: EdgeBase[],
|
||||||
{ id, defaultColor }: { id?: string | null; defaultColor?: string }
|
{
|
||||||
|
id,
|
||||||
|
defaultColor,
|
||||||
|
defaultMarkerStart,
|
||||||
|
defaultMarkerEnd,
|
||||||
|
}: {
|
||||||
|
id?: string | null;
|
||||||
|
defaultColor?: string;
|
||||||
|
defaultMarkerStart?: EdgeMarkerType;
|
||||||
|
defaultMarkerEnd?: EdgeMarkerType;
|
||||||
|
}
|
||||||
) {
|
) {
|
||||||
const ids: string[] = [];
|
const ids = new Set<string>();
|
||||||
|
|
||||||
return edges
|
return edges
|
||||||
.reduce<MarkerProps[]>((markers, edge) => {
|
.reduce<MarkerProps[]>((markers, edge) => {
|
||||||
[edge.markerStart, edge.markerEnd].forEach((marker) => {
|
[edge.markerStart || defaultMarkerStart, edge.markerEnd || defaultMarkerEnd].forEach((marker) => {
|
||||||
if (marker && typeof marker === 'object') {
|
if (marker && typeof marker === 'object') {
|
||||||
const markerId = getMarkerId(marker, id);
|
const markerId = getMarkerId(marker, id);
|
||||||
if (!ids.includes(markerId)) {
|
if (!ids.has(markerId)) {
|
||||||
markers.push({ id: markerId, color: marker.color || defaultColor, ...marker });
|
markers.push({ id: markerId, color: marker.color || defaultColor, ...marker });
|
||||||
ids.push(markerId);
|
ids.add(markerId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
return markers;
|
return markers;
|
||||||
}, [])
|
}, [])
|
||||||
.sort((a, b) => a.id.localeCompare(b.id));
|
.sort((a, b) => a.id.localeCompare(b.id));
|
||||||
|
|||||||
Reference in New Issue
Block a user