fix(svelte): repair selection, add multi selection closes #3557

This commit is contained in:
moklick
2023-10-31 18:31:24 +01:00
parent ce1680ba71
commit d2b140ce5e
12 changed files with 204 additions and 117 deletions
+77 -33
View File
@@ -15,7 +15,8 @@ import {
type CoordinateExtent,
type UpdateConnection,
type NodeBase,
type NodeDragItem
type NodeDragItem,
errorMessages
} from '@xyflow/system';
import { addEdge as addEdgeUtil } from '$lib/utils';
@@ -173,25 +174,29 @@ export function createStore({
}
}
function resetSelectedItem<T extends Node | Edge>(item: T) {
if (item.selected) {
return {
...item,
selected: false
};
}
function resetSelectedItem<T extends Node | Edge>(ids: string[]) {
return (item: T) => {
if (item.selected && ids.includes(item.id)) {
return {
...item,
selected: false
};
}
return item;
return item;
};
}
function unselectNodesAndEdges() {
if (get(store.nodes).some((node) => node.selected)) {
store.nodes.update((ns) => ns.map(resetSelectedItem));
}
function unselectNodesAndEdges(params?: { nodes?: Node[]; edges?: Edge[] }) {
const nodeIdsToUnselect = (params?.nodes ? params.nodes : get(store.nodes)).map(
(item) => item.id
);
const edgeIdsToUnselect = (params?.edges ? params.edges : get(store.edges)).map(
(item) => item.id
);
if (get(store.edges).some((edge) => edge.selected)) {
store.edges.update((es) => es.map(resetSelectedItem));
}
store.nodes.update((ns) => ns.map(resetSelectedItem(nodeIdsToUnselect)));
store.edges.update((es) => es.map(resetSelectedItem(edgeIdsToUnselect)));
}
store.deleteKeyPressed.subscribe((deleteKeyPressed) => {
@@ -220,36 +225,74 @@ export function createStore({
});
function addSelectedNodes(ids: string[]) {
store.selectionRect.set(null);
store.selectionRectMode.set(null);
if (get(store.multiselectionKeyPressed)) {
// @todo handle multiselection key
}
const isMultiSelection = get(store.multiselectionKeyPressed);
store.nodes.update((ns) =>
ns.map((node) => {
return {
...node,
selected: ids.includes(node.id)
};
const nodeWillBeSelected = ids.includes(node.id);
const selected = isMultiSelection
? node.selected || nodeWillBeSelected
: nodeWillBeSelected;
// we need to mutate the node here in order to have the correct selected state in the drag handler
node.selected = selected;
return node;
})
);
if (!isMultiSelection) {
store.edges.update((es) =>
es.map((edge) => {
edge.selected = false;
return edge;
})
);
}
}
function addSelectedEdges(ids: string[]) {
if (get(store.multiselectionKeyPressed)) {
// @todo handle multiselection key
}
const isMultiSelection = get(store.multiselectionKeyPressed);
store.edges.update((edges) =>
edges.map((edge) => {
return {
...edge,
selected: ids.includes(edge.id)
};
const edgeWillBeSelected = ids.includes(edge.id);
const selected = isMultiSelection
? edge.selected || edgeWillBeSelected
: edgeWillBeSelected;
edge.selected = selected;
return edge;
})
);
if (!isMultiSelection) {
store.nodes.update((ns) =>
ns.map((node) => {
node.selected = false;
return node;
})
);
}
}
function handleNodeSelection(id: string) {
const node = get(store.nodes)?.find((n) => n.id === id);
if (!node) {
console.warn('012', errorMessages['error012'](id));
return;
}
store.selectionRect.set(null);
store.selectionRectMode.set(null);
if (!node.selected) {
addSelectedNodes([id]);
} else if (node.selected && get(store.multiselectionKeyPressed)) {
unselectNodesAndEdges({ nodes: [node], edges: [] });
}
}
function panBy(delta: XYPosition) {
@@ -326,6 +369,7 @@ export function createStore({
unselectNodesAndEdges,
addSelectedNodes,
addSelectedEdges,
handleNodeSelection,
panBy,
updateConnection,
cancelConnection,
+2 -1
View File
@@ -28,9 +28,10 @@ export type SvelteFlowStoreActions = {
fitView: (options?: FitViewOptions) => boolean;
updateNodePositions: UpdateNodePositions;
updateNodeDimensions: (updates: NodeDimensionUpdate[]) => void;
unselectNodesAndEdges: () => void;
unselectNodesAndEdges: (params?: { nodes?: Node[]; edges?: Edge[] }) => void;
addSelectedNodes: (ids: string[]) => void;
addSelectedEdges: (ids: string[]) => void;
handleNodeSelection: (id: string) => void;
panBy: (delta: XYPosition) => boolean;
updateConnection: UpdateConnection;
cancelConnection: () => void;