@xyflow/react 12.0.0-next.5 → 12.0.0-next.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/esm/additional-components/Controls/Controls.d.ts +1 -1
- package/dist/esm/additional-components/Controls/Controls.d.ts.map +1 -1
- package/dist/esm/additional-components/Controls/types.d.ts +5 -2
- package/dist/esm/additional-components/Controls/types.d.ts.map +1 -1
- package/dist/esm/hooks/useReactFlow.d.ts.map +1 -1
- package/dist/esm/index.js +149 -107
- package/dist/esm/index.mjs +149 -107
- package/dist/esm/types/changes.d.ts +8 -6
- package/dist/esm/types/changes.d.ts.map +1 -1
- package/dist/esm/types/instance.d.ts +1 -2
- package/dist/esm/types/instance.d.ts.map +1 -1
- package/dist/esm/utils/changes.d.ts +18 -0
- package/dist/esm/utils/changes.d.ts.map +1 -1
- package/dist/umd/additional-components/Controls/Controls.d.ts +1 -1
- package/dist/umd/additional-components/Controls/Controls.d.ts.map +1 -1
- package/dist/umd/additional-components/Controls/types.d.ts +5 -2
- package/dist/umd/additional-components/Controls/types.d.ts.map +1 -1
- package/dist/umd/hooks/useReactFlow.d.ts.map +1 -1
- package/dist/umd/index.js +2 -2
- package/dist/umd/types/changes.d.ts +8 -6
- package/dist/umd/types/changes.d.ts.map +1 -1
- package/dist/umd/types/instance.d.ts +1 -2
- package/dist/umd/types/instance.d.ts.map +1 -1
- package/dist/umd/utils/changes.d.ts +18 -0
- package/dist/umd/utils/changes.d.ts.map +1 -1
- package/package.json +3 -3
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/// <reference types="react" />
|
|
2
2
|
import type { ControlProps } from './types';
|
|
3
|
-
declare function ControlsComponent({ style, showZoom, showFitView, showInteractive, fitViewOptions, onZoomIn, onZoomOut, onFitView, onInteractiveChange, className, children, position, }: ControlProps): import("react/jsx-runtime").JSX.Element;
|
|
3
|
+
declare function ControlsComponent({ style, showZoom, showFitView, showInteractive, fitViewOptions, onZoomIn, onZoomOut, onFitView, onInteractiveChange, className, children, position, 'aria-label': ariaLabel, }: ControlProps): import("react/jsx-runtime").JSX.Element;
|
|
4
4
|
declare namespace ControlsComponent {
|
|
5
5
|
var displayName: string;
|
|
6
6
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Controls.d.ts","sourceRoot":"","sources":["../../../../../packages/react/src/additional-components/Controls/Controls.tsx"],"names":[],"mappings":";AAeA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAQ5C,iBAAS,iBAAiB,CAAC,EACzB,KAAK,EACL,QAAe,EACf,WAAkB,EAClB,eAAsB,EACtB,cAAc,EACd,QAAQ,EACR,SAAS,EACT,SAAS,EACT,mBAAmB,EACnB,SAAS,EACT,QAAQ,EACR,QAAwB,
|
|
1
|
+
{"version":3,"file":"Controls.d.ts","sourceRoot":"","sources":["../../../../../packages/react/src/additional-components/Controls/Controls.tsx"],"names":[],"mappings":";AAeA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAQ5C,iBAAS,iBAAiB,CAAC,EACzB,KAAK,EACL,QAAe,EACf,WAAkB,EAClB,eAAsB,EACtB,cAAc,EACd,QAAQ,EACR,SAAS,EACT,SAAS,EACT,mBAAmB,EACnB,SAAS,EACT,QAAQ,EACR,QAAwB,EACxB,YAAY,EAAE,SAAiC,GAChD,EAAE,YAAY,2CAmFd;kBAjGQ,iBAAiB;;;AAqG1B,eAAO,MAAM,QAAQ,+DAA0B,CAAC"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import type { ButtonHTMLAttributes,
|
|
1
|
+
import type { ButtonHTMLAttributes, ReactNode } from 'react';
|
|
2
2
|
import type { PanelPosition } from '@xyflow/system';
|
|
3
3
|
import type { FitViewOptions } from '../../types';
|
|
4
|
-
export type ControlProps =
|
|
4
|
+
export type ControlProps = {
|
|
5
5
|
showZoom?: boolean;
|
|
6
6
|
showFitView?: boolean;
|
|
7
7
|
showInteractive?: boolean;
|
|
@@ -12,6 +12,9 @@ export type ControlProps = HTMLAttributes<HTMLDivElement> & {
|
|
|
12
12
|
onInteractiveChange?: (interactiveStatus: boolean) => void;
|
|
13
13
|
position?: PanelPosition;
|
|
14
14
|
children?: ReactNode;
|
|
15
|
+
style?: React.CSSProperties;
|
|
16
|
+
className?: string;
|
|
17
|
+
'aria-label'?: string;
|
|
15
18
|
};
|
|
16
19
|
export type ControlButtonProps = ButtonHTMLAttributes<HTMLButtonElement>;
|
|
17
20
|
//# sourceMappingURL=types.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../../packages/react/src/additional-components/Controls/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../../packages/react/src/additional-components/Controls/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAC7D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAEpD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAElD,MAAM,MAAM,YAAY,GAAG;IACzB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,cAAc,CAAC,EAAE,cAAc,CAAC;IAChC,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,IAAI,CAAC;IACvB,SAAS,CAAC,EAAE,MAAM,IAAI,CAAC;IACvB,mBAAmB,CAAC,EAAE,CAAC,iBAAiB,EAAE,OAAO,KAAK,IAAI,CAAC;IAC3D,QAAQ,CAAC,EAAE,aAAa,CAAC;IACzB,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,KAAK,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC;IAC5B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG,oBAAoB,CAAC,iBAAiB,CAAC,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useReactFlow.d.ts","sourceRoot":"","sources":["../../../../packages/react/src/hooks/useReactFlow.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EACV,iBAAiB,
|
|
1
|
+
{"version":3,"file":"useReactFlow.d.ts","sourceRoot":"","sources":["../../../../packages/react/src/hooks/useReactFlow.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EACV,iBAAiB,EAIjB,IAAI,EACJ,IAAI,EAGL,MAAM,UAAU,CAAC;AAGlB;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,QAAQ,SAAS,IAAI,GAAG,IAAI,EAAE,QAAQ,SAAS,IAAI,GAAG,IAAI,KAAK,iBAAiB,CAC3G,QAAQ,EACR,QAAQ,CACT,CAqSA"}
|
package/dist/esm/index.js
CHANGED
|
@@ -496,97 +496,102 @@ function handleParentExpand(updatedElements, updateItem) {
|
|
|
496
496
|
// When you drag a node for example, React Flow will send a position change update.
|
|
497
497
|
// This function then applies the changes and returns the updated elements.
|
|
498
498
|
function applyChanges(changes, elements) {
|
|
499
|
-
// we need this hack to handle the setNodes and setEdges function of the useReactFlow hook for controlled flows
|
|
500
|
-
if (changes.some((c) => c.type === 'reset')) {
|
|
501
|
-
return changes.filter((c) => c.type === 'reset').map((c) => c.item);
|
|
502
|
-
}
|
|
503
|
-
let remainingChanges = [];
|
|
504
499
|
const updatedElements = [];
|
|
500
|
+
// By storing a map of changes for each element, we can a quick lookup as we
|
|
501
|
+
// iterate over the elements array!
|
|
502
|
+
const changesMap = new Map();
|
|
505
503
|
for (const change of changes) {
|
|
506
504
|
if (change.type === 'add') {
|
|
507
505
|
updatedElements.push(change.item);
|
|
506
|
+
continue;
|
|
508
507
|
}
|
|
509
|
-
else {
|
|
510
|
-
|
|
508
|
+
else if (change.type === 'remove' || change.type === 'replace') {
|
|
509
|
+
// For a 'remove' change we can safely ignore any other changes queued for
|
|
510
|
+
// the same element, it's going to be removed anyway!
|
|
511
|
+
changesMap.set(change.id, [change]);
|
|
511
512
|
}
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
nextChanges.push(change);
|
|
513
|
+
else {
|
|
514
|
+
const elementChanges = changesMap.get(change.id);
|
|
515
|
+
if (elementChanges) {
|
|
516
|
+
// If we have some changes queued already, we can do a mutable update of
|
|
517
|
+
// that array and save ourselves some copying.
|
|
518
|
+
elementChanges.push(change);
|
|
519
519
|
}
|
|
520
520
|
else {
|
|
521
|
-
|
|
521
|
+
changesMap.set(change.id, [change]);
|
|
522
522
|
}
|
|
523
523
|
}
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
524
|
+
}
|
|
525
|
+
for (const element of elements) {
|
|
526
|
+
const changes = changesMap.get(element.id);
|
|
527
|
+
// When there are no changes for an element we can just push it unmodified,
|
|
528
|
+
// no need to copy it.
|
|
529
|
+
if (!changes) {
|
|
530
|
+
updatedElements.push(element);
|
|
527
531
|
continue;
|
|
528
532
|
}
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
break;
|
|
537
|
-
}
|
|
538
|
-
case 'position': {
|
|
539
|
-
if (typeof currentChange.position !== 'undefined') {
|
|
540
|
-
updateItem.position = currentChange.position;
|
|
541
|
-
}
|
|
542
|
-
if (typeof currentChange.positionAbsolute !== 'undefined') {
|
|
543
|
-
if (!updateItem.computed) {
|
|
544
|
-
updateItem.computed = {};
|
|
545
|
-
}
|
|
546
|
-
updateItem.computed.positionAbsolute = currentChange.positionAbsolute;
|
|
547
|
-
}
|
|
548
|
-
if (typeof currentChange.dragging !== 'undefined') {
|
|
549
|
-
updateItem.dragging = currentChange.dragging;
|
|
550
|
-
}
|
|
551
|
-
if (updateItem.expandParent) {
|
|
552
|
-
handleParentExpand(updatedElements, updateItem);
|
|
553
|
-
}
|
|
554
|
-
break;
|
|
555
|
-
}
|
|
556
|
-
case 'dimensions': {
|
|
557
|
-
if (typeof currentChange.dimensions !== 'undefined') {
|
|
558
|
-
if (!updateItem.computed) {
|
|
559
|
-
updateItem.computed = {};
|
|
560
|
-
}
|
|
561
|
-
updateItem.computed.width = currentChange.dimensions.width;
|
|
562
|
-
updateItem.computed.height = currentChange.dimensions.height;
|
|
563
|
-
// this is needed for the node resizer to work
|
|
564
|
-
if (currentChange.resizing) {
|
|
565
|
-
updateItem.width = currentChange.dimensions.width;
|
|
566
|
-
updateItem.height = currentChange.dimensions.height;
|
|
567
|
-
}
|
|
568
|
-
}
|
|
569
|
-
if (typeof currentChange.resizing === 'boolean') {
|
|
570
|
-
updateItem.resizing = currentChange.resizing;
|
|
571
|
-
}
|
|
572
|
-
if (updateItem.expandParent) {
|
|
573
|
-
handleParentExpand(updatedElements, updateItem);
|
|
574
|
-
}
|
|
575
|
-
break;
|
|
576
|
-
}
|
|
577
|
-
case 'remove': {
|
|
578
|
-
isDeletion = true;
|
|
579
|
-
continue;
|
|
580
|
-
}
|
|
581
|
-
}
|
|
582
|
-
}
|
|
533
|
+
// If we have a 'remove' change queued, it'll be the only change in the array
|
|
534
|
+
if (changes[0].type === 'remove') {
|
|
535
|
+
continue;
|
|
536
|
+
}
|
|
537
|
+
if (changes[0].type === 'replace') {
|
|
538
|
+
updatedElements.push({ ...changes[0].item });
|
|
539
|
+
continue;
|
|
583
540
|
}
|
|
584
|
-
|
|
585
|
-
|
|
541
|
+
// For other types of changes, we want to start with a shallow copy of the
|
|
542
|
+
// object so React knows this element has changed. Sequential changes will
|
|
543
|
+
/// each _mutate_ this object, so there's only ever one copy.
|
|
544
|
+
const updatedElement = { ...element };
|
|
545
|
+
for (const change of changes) {
|
|
546
|
+
applyChange(change, updatedElement, elements);
|
|
586
547
|
}
|
|
548
|
+
updatedElements.push(updatedElement);
|
|
587
549
|
}
|
|
588
550
|
return updatedElements;
|
|
589
551
|
}
|
|
552
|
+
// Applies a single change to an element. This is a *mutable* update.
|
|
553
|
+
function applyChange(change, element, elements = []) {
|
|
554
|
+
switch (change.type) {
|
|
555
|
+
case 'select': {
|
|
556
|
+
element.selected = change.selected;
|
|
557
|
+
break;
|
|
558
|
+
}
|
|
559
|
+
case 'position': {
|
|
560
|
+
if (typeof change.position !== 'undefined') {
|
|
561
|
+
element.position = change.position;
|
|
562
|
+
}
|
|
563
|
+
if (typeof change.positionAbsolute !== 'undefined') {
|
|
564
|
+
element.computed ??= {};
|
|
565
|
+
element.computed.positionAbsolute = change.positionAbsolute;
|
|
566
|
+
}
|
|
567
|
+
if (typeof change.dragging !== 'undefined') {
|
|
568
|
+
element.dragging = change.dragging;
|
|
569
|
+
}
|
|
570
|
+
if (element.expandParent) {
|
|
571
|
+
handleParentExpand(elements, element);
|
|
572
|
+
}
|
|
573
|
+
break;
|
|
574
|
+
}
|
|
575
|
+
case 'dimensions': {
|
|
576
|
+
if (typeof change.dimensions !== 'undefined') {
|
|
577
|
+
element.computed ??= {};
|
|
578
|
+
element.computed.width = change.dimensions.width;
|
|
579
|
+
element.computed.height = change.dimensions.height;
|
|
580
|
+
if (change.resizing) {
|
|
581
|
+
element.width = change.dimensions.width;
|
|
582
|
+
element.height = change.dimensions.height;
|
|
583
|
+
}
|
|
584
|
+
}
|
|
585
|
+
if (typeof change.resizing === 'boolean') {
|
|
586
|
+
element.resizing = change.resizing;
|
|
587
|
+
}
|
|
588
|
+
if (element.expandParent) {
|
|
589
|
+
handleParentExpand(elements, element);
|
|
590
|
+
}
|
|
591
|
+
break;
|
|
592
|
+
}
|
|
593
|
+
}
|
|
594
|
+
}
|
|
590
595
|
/**
|
|
591
596
|
* Drop in function that applies node changes to an array of nodes.
|
|
592
597
|
* @public
|
|
@@ -655,6 +660,26 @@ function getSelectionChanges(items, selectedIds = new Set(), mutateItem = false)
|
|
|
655
660
|
}
|
|
656
661
|
return changes;
|
|
657
662
|
}
|
|
663
|
+
function getElementsDiffChanges({ items = [], lookup, }) {
|
|
664
|
+
const changes = [];
|
|
665
|
+
const itemsLookup = new Map(items.map((item) => [item.id, item]));
|
|
666
|
+
for (const item of items) {
|
|
667
|
+
const storeItem = lookup.get(item.id);
|
|
668
|
+
if (storeItem !== undefined && storeItem !== item) {
|
|
669
|
+
changes.push({ id: item.id, item: item, type: 'replace' });
|
|
670
|
+
}
|
|
671
|
+
if (storeItem === undefined) {
|
|
672
|
+
changes.push({ item: item, type: 'add' });
|
|
673
|
+
}
|
|
674
|
+
}
|
|
675
|
+
for (const [id] of lookup) {
|
|
676
|
+
const nextNode = itemsLookup.get(id);
|
|
677
|
+
if (nextNode === undefined) {
|
|
678
|
+
changes.push({ id, type: 'remove' });
|
|
679
|
+
}
|
|
680
|
+
}
|
|
681
|
+
return changes;
|
|
682
|
+
}
|
|
658
683
|
|
|
659
684
|
/**
|
|
660
685
|
* Test whether an object is useable as a Node
|
|
@@ -739,31 +764,50 @@ function useReactFlow() {
|
|
|
739
764
|
const { edges = [] } = store.getState();
|
|
740
765
|
return edges.find((e) => e.id === id);
|
|
741
766
|
}, []);
|
|
767
|
+
// this is used to handle multiple syncronous setNodes calls
|
|
768
|
+
const setNodesData = useRef();
|
|
769
|
+
const setNodesTimeout = useRef();
|
|
742
770
|
const setNodes = useCallback((payload) => {
|
|
743
|
-
const { nodes, setNodes, hasDefaultNodes, onNodesChange } = store.getState();
|
|
744
|
-
const nextNodes = typeof payload === 'function' ? payload(nodes) : payload;
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
771
|
+
const { nodes = [], setNodes, hasDefaultNodes, onNodesChange, nodeLookup } = store.getState();
|
|
772
|
+
const nextNodes = typeof payload === 'function' ? payload(setNodesData.current || nodes) : payload;
|
|
773
|
+
setNodesData.current = nextNodes;
|
|
774
|
+
if (setNodesTimeout.current) {
|
|
775
|
+
clearTimeout(setNodesTimeout.current);
|
|
776
|
+
}
|
|
777
|
+
// if there are multiple synchronous setNodes calls, we only want to call onNodesChange once
|
|
778
|
+
// for this, we use a timeout to wait for the last call and store updated nodes in setNodesData
|
|
779
|
+
// this is not perfect, but should work in most cases
|
|
780
|
+
setNodesTimeout.current = setTimeout(() => {
|
|
781
|
+
if (hasDefaultNodes) {
|
|
782
|
+
setNodes(nextNodes);
|
|
783
|
+
}
|
|
784
|
+
else if (onNodesChange) {
|
|
785
|
+
const changes = getElementsDiffChanges({ items: setNodesData.current, lookup: nodeLookup });
|
|
786
|
+
onNodesChange(changes);
|
|
787
|
+
}
|
|
788
|
+
setNodesData.current = undefined;
|
|
789
|
+
}, 0);
|
|
754
790
|
}, []);
|
|
791
|
+
// this is used to handle multiple syncronous setEdges calls
|
|
792
|
+
const setEdgesData = useRef();
|
|
793
|
+
const setEdgesTimeout = useRef();
|
|
755
794
|
const setEdges = useCallback((payload) => {
|
|
756
|
-
const { edges = [], setEdges, hasDefaultEdges, onEdgesChange } = store.getState();
|
|
757
|
-
const nextEdges = typeof payload === 'function' ? payload(edges) : payload;
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
else if (onEdgesChange) {
|
|
762
|
-
const changes = nextEdges.length === 0
|
|
763
|
-
? edges.map((edge) => ({ type: 'remove', id: edge.id }))
|
|
764
|
-
: nextEdges.map((edge) => ({ item: edge, type: 'reset' }));
|
|
765
|
-
onEdgesChange(changes);
|
|
795
|
+
const { edges = [], setEdges, hasDefaultEdges, onEdgesChange, edgeLookup } = store.getState();
|
|
796
|
+
const nextEdges = typeof payload === 'function' ? payload(setEdgesData.current || edges) : payload;
|
|
797
|
+
setEdgesData.current = nextEdges;
|
|
798
|
+
if (setEdgesTimeout.current) {
|
|
799
|
+
clearTimeout(setEdgesTimeout.current);
|
|
766
800
|
}
|
|
801
|
+
setEdgesTimeout.current = setTimeout(() => {
|
|
802
|
+
if (hasDefaultEdges) {
|
|
803
|
+
setEdges(nextEdges);
|
|
804
|
+
}
|
|
805
|
+
else if (onEdgesChange) {
|
|
806
|
+
const changes = getElementsDiffChanges({ items: nextEdges, lookup: edgeLookup });
|
|
807
|
+
onEdgesChange(changes);
|
|
808
|
+
}
|
|
809
|
+
setEdgesData.current = undefined;
|
|
810
|
+
}, 0);
|
|
767
811
|
}, []);
|
|
768
812
|
const addNodes = useCallback((payload) => {
|
|
769
813
|
const nodes = Array.isArray(payload) ? payload : [payload];
|
|
@@ -801,8 +845,8 @@ function useReactFlow() {
|
|
|
801
845
|
},
|
|
802
846
|
};
|
|
803
847
|
}, []);
|
|
804
|
-
const deleteElements = useCallback(async ({ nodes: nodesToRemove = [], edges: edgesToRemove = []
|
|
805
|
-
const { nodes, edges, hasDefaultNodes, hasDefaultEdges, onNodesDelete, onEdgesDelete, onNodesChange, onEdgesChange, onDelete, } = store.getState();
|
|
848
|
+
const deleteElements = useCallback(async ({ nodes: nodesToRemove = [], edges: edgesToRemove = [] }) => {
|
|
849
|
+
const { nodes, edges, hasDefaultNodes, hasDefaultEdges, onNodesDelete, onEdgesDelete, onNodesChange, onEdgesChange, onDelete, onBeforeDelete, } = store.getState();
|
|
806
850
|
const { nodes: matchingNodes, edges: matchingEdges } = await getElementsToRemove({
|
|
807
851
|
nodesToRemove,
|
|
808
852
|
edgesToRemove,
|
|
@@ -814,9 +858,8 @@ function useReactFlow() {
|
|
|
814
858
|
const hasMatchingNodes = matchingNodes.length > 0;
|
|
815
859
|
if (hasMatchingEdges) {
|
|
816
860
|
if (hasDefaultEdges) {
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
});
|
|
861
|
+
const nextEdges = edges.filter((e) => !matchingEdges.some((mE) => mE.id === e.id));
|
|
862
|
+
store.getState().setEdges(nextEdges);
|
|
820
863
|
}
|
|
821
864
|
onEdgesDelete?.(matchingEdges);
|
|
822
865
|
onEdgesChange?.(matchingEdges.map((edge) => ({
|
|
@@ -826,9 +869,8 @@ function useReactFlow() {
|
|
|
826
869
|
}
|
|
827
870
|
if (hasMatchingNodes) {
|
|
828
871
|
if (hasDefaultNodes) {
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
});
|
|
872
|
+
const nextNodes = nodes.filter((n) => !matchingNodes.some((mN) => mN.id === n.id));
|
|
873
|
+
store.getState().setNodes(nextNodes);
|
|
832
874
|
}
|
|
833
875
|
onNodesDelete?.(matchingNodes);
|
|
834
876
|
onNodesChange?.(matchingNodes.map((node) => ({ id: node.id, type: 'remove' })));
|
|
@@ -934,8 +976,8 @@ function useGlobalKeyHandler({ deleteKeyCode, multiSelectionKeyCode, }) {
|
|
|
934
976
|
const multiSelectionKeyPressed = useKeyPress(multiSelectionKeyCode);
|
|
935
977
|
useEffect(() => {
|
|
936
978
|
if (deleteKeyPressed) {
|
|
937
|
-
const { edges, nodes
|
|
938
|
-
deleteElements({ nodes: nodes.filter(selected), edges: edges.filter(selected)
|
|
979
|
+
const { edges, nodes } = store.getState();
|
|
980
|
+
deleteElements({ nodes: nodes.filter(selected), edges: edges.filter(selected) });
|
|
939
981
|
store.setState({ nodesSelectionActive: false });
|
|
940
982
|
}
|
|
941
983
|
}, [deleteKeyPressed]);
|
|
@@ -3120,7 +3162,7 @@ const selector$3 = (s) => ({
|
|
|
3120
3162
|
minZoomReached: s.transform[2] <= s.minZoom,
|
|
3121
3163
|
maxZoomReached: s.transform[2] >= s.maxZoom,
|
|
3122
3164
|
});
|
|
3123
|
-
function ControlsComponent({ style, showZoom = true, showFitView = true, showInteractive = true, fitViewOptions, onZoomIn, onZoomOut, onFitView, onInteractiveChange, className, children, position = 'bottom-left', }) {
|
|
3165
|
+
function ControlsComponent({ style, showZoom = true, showFitView = true, showInteractive = true, fitViewOptions, onZoomIn, onZoomOut, onFitView, onInteractiveChange, className, children, position = 'bottom-left', 'aria-label': ariaLabel = 'React Flow controls', }) {
|
|
3124
3166
|
const store = useStoreApi();
|
|
3125
3167
|
const { isInteractive, minZoomReached, maxZoomReached } = useStore(selector$3, shallow);
|
|
3126
3168
|
const { zoomIn, zoomOut, fitView } = useReactFlow();
|
|
@@ -3144,7 +3186,7 @@ function ControlsComponent({ style, showZoom = true, showFitView = true, showInt
|
|
|
3144
3186
|
});
|
|
3145
3187
|
onInteractiveChange?.(!isInteractive);
|
|
3146
3188
|
};
|
|
3147
|
-
return (jsxs(Panel, { className: cc(['react-flow__controls', className]), position: position, style: style, "data-testid": "rf__controls", children: [showZoom && (jsxs(Fragment, { children: [jsx(ControlButton, { onClick: onZoomInHandler, className: "react-flow__controls-zoomin", title: "zoom in", "aria-label": "zoom in", disabled: maxZoomReached, children: jsx(PlusIcon, {}) }), jsx(ControlButton, { onClick: onZoomOutHandler, className: "react-flow__controls-zoomout", title: "zoom out", "aria-label": "zoom out", disabled: minZoomReached, children: jsx(MinusIcon, {}) })] })), showFitView && (jsx(ControlButton, { className: "react-flow__controls-fitview", onClick: onFitViewHandler, title: "fit view", "aria-label": "fit view", children: jsx(FitViewIcon, {}) })), showInteractive && (jsx(ControlButton, { className: "react-flow__controls-interactive", onClick: onToggleInteractivity, title: "toggle interactivity", "aria-label": "toggle interactivity", children: isInteractive ? jsx(UnlockIcon, {}) : jsx(LockIcon, {}) })), children] }));
|
|
3189
|
+
return (jsxs(Panel, { className: cc(['react-flow__controls', className]), position: position, style: style, "data-testid": "rf__controls", "aria-label": ariaLabel, children: [showZoom && (jsxs(Fragment, { children: [jsx(ControlButton, { onClick: onZoomInHandler, className: "react-flow__controls-zoomin", title: "zoom in", "aria-label": "zoom in", disabled: maxZoomReached, children: jsx(PlusIcon, {}) }), jsx(ControlButton, { onClick: onZoomOutHandler, className: "react-flow__controls-zoomout", title: "zoom out", "aria-label": "zoom out", disabled: minZoomReached, children: jsx(MinusIcon, {}) })] })), showFitView && (jsx(ControlButton, { className: "react-flow__controls-fitview", onClick: onFitViewHandler, title: "fit view", "aria-label": "fit view", children: jsx(FitViewIcon, {}) })), showInteractive && (jsx(ControlButton, { className: "react-flow__controls-interactive", onClick: onToggleInteractivity, title: "toggle interactivity", "aria-label": "toggle interactivity", children: isInteractive ? jsx(UnlockIcon, {}) : jsx(LockIcon, {}) })), children] }));
|
|
3148
3190
|
}
|
|
3149
3191
|
ControlsComponent.displayName = 'Controls';
|
|
3150
3192
|
const Controls = memo(ControlsComponent);
|