feat(svelte): make edges selectable
This commit is contained in:
@@ -108,7 +108,7 @@ export function calcNextPosition(
|
||||
]
|
||||
: currentExtent;
|
||||
} else {
|
||||
devWarn('005', errorMessages['005']());
|
||||
devWarn('005', errorMessages['error005']());
|
||||
currentExtent = nodeExtent;
|
||||
}
|
||||
} else if (node.extent && node.parentNode) {
|
||||
|
||||
@@ -14,7 +14,6 @@
|
||||
export let markerEnd: $$Props['markerEnd'] = undefined;
|
||||
export let style: $$Props['style'] = undefined;
|
||||
export let interactionWidth: $$Props['interactionWidth'] = 20;
|
||||
|
||||
</script>
|
||||
|
||||
<path
|
||||
|
||||
@@ -23,16 +23,17 @@
|
||||
export let targetPosition: $$Props['targetPosition'] = Position.Top;
|
||||
export let animated: $$Props['animated'] = false;
|
||||
export let selected: $$Props['selected'] = false;
|
||||
export let selectable: $$Props['selectable'] = true;
|
||||
export let label: $$Props['label'] = undefined;
|
||||
export let labelStyle: $$Props['labelStyle'] = undefined;
|
||||
export let markerStart: $$Props['markerStart'] = undefined;
|
||||
export let markerEnd: $$Props['markerEnd'] = undefined;
|
||||
export let sourceHandleId: $$Props['sourceHandleId'] = undefined;
|
||||
export let targetHandleId: $$Props['targetHandleId'] = undefined;
|
||||
|
||||
|
||||
// @ todo: support edge updates
|
||||
|
||||
const { edges, edgeTypes, flowId } = useStore();
|
||||
const { edges, edgeTypes, flowId, addSelectedEdges } = useStore();
|
||||
const dispatch = createEventDispatcher();
|
||||
|
||||
const edgeComponent: typeof SvelteComponentTyped<EdgeProps> = $edgeTypes[type!] || BezierEdge;
|
||||
@@ -41,6 +42,10 @@
|
||||
$: markerEndUrl = markerEnd ? `url(#${getMarkerId(markerEnd, $flowId)})` : undefined;
|
||||
|
||||
function onClick() {
|
||||
if (selectable) {
|
||||
addSelectedEdges([id]);
|
||||
}
|
||||
|
||||
const edge = $edges.find(e => e.id === id);
|
||||
dispatch('edge:click', edge);
|
||||
}
|
||||
@@ -50,6 +55,7 @@
|
||||
<g
|
||||
class="svelte-flow__edge"
|
||||
class:animated
|
||||
class:selected
|
||||
data-id={id}
|
||||
on:click={onClick}
|
||||
>
|
||||
@@ -83,13 +89,17 @@
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.svelte-flow__edge :global(path) {
|
||||
.svelte-flow__edge :global(.svelte-flow__edge-path) {
|
||||
stroke: #ccc;
|
||||
stroke-width: 1;
|
||||
fill: none;
|
||||
}
|
||||
|
||||
.animated :global(path) {
|
||||
.selected :global(.svelte-flow__edge-path) {
|
||||
stroke: #555;
|
||||
}
|
||||
|
||||
.animated :global(.svelte-flow__edge-path) {
|
||||
stroke-dasharray: 5;
|
||||
animation: dashdraw 0.5s linear infinite;
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
export let data: NodeWrapperProps['data'] = {};
|
||||
export let selected: NodeWrapperProps['selected'] = false;
|
||||
export let draggable: NodeWrapperProps['draggable'] = undefined;
|
||||
export let selectable: NodeWrapperProps['selectable'] = undefined;
|
||||
export let connectable: NodeWrapperProps['connectable'] = true;
|
||||
export let dragging: boolean = false;
|
||||
export let resizeObserver: NodeWrapperProps['resizeObserver'] = null;
|
||||
@@ -36,13 +37,12 @@
|
||||
const nodeTypeValid = !!$nodeTypes[type!];
|
||||
|
||||
if (!nodeTypeValid) {
|
||||
console.warn('003', errorMessages['003'](type!));
|
||||
console.warn('003', errorMessages['error003'](type!));
|
||||
type = 'default';
|
||||
}
|
||||
|
||||
const nodeComponent: typeof SvelteComponentTyped<Partial<NodeProps>> =
|
||||
$nodeTypes[type!] || DefaultNode;
|
||||
const isSelectable = true;
|
||||
const selectNodesOnDrag = false;
|
||||
const dispatch = createEventDispatcher();
|
||||
|
||||
@@ -63,7 +63,7 @@
|
||||
}
|
||||
|
||||
function onSelectNodeHandler(event: MouseEvent) {
|
||||
if (isSelectable && (!selectNodesOnDrag || !draggable)) {
|
||||
if (selectable && (!selectNodesOnDrag || !draggable)) {
|
||||
// this handler gets called within the drag start event when selectNodesOnDrag=true
|
||||
addSelectedNodes([id]);
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ export type NodeWrapperProps = Pick<
|
||||
| 'dragging'
|
||||
| 'positionAbsolute'
|
||||
| 'selected'
|
||||
| 'selectable'
|
||||
| 'style'
|
||||
| 'type'
|
||||
| 'width'
|
||||
|
||||
@@ -39,6 +39,7 @@
|
||||
data={node.data}
|
||||
selected={node.selected}
|
||||
draggable={node.draggable || node.draggable === undefined}
|
||||
selectable={node.selectable || node.selectable === undefined}
|
||||
connectable={node.connectable || node.connectable === undefined}
|
||||
positionAbsolute={node.positionAbsolute}
|
||||
positionOrigin={posOrigin}
|
||||
|
||||
@@ -45,6 +45,7 @@ export function getEdgesLayouted(store: SvelteFlowStoreState) {
|
||||
|
||||
res.push({
|
||||
...edge,
|
||||
selectable: edge.selectable || typeof edge.selectable === 'undefined',
|
||||
type: edgeType,
|
||||
sourceX,
|
||||
sourceY,
|
||||
|
||||
@@ -251,6 +251,21 @@ export function createStore(params: CreateStoreParams): SvelteFlowStore {
|
||||
);
|
||||
}
|
||||
|
||||
function addSelectedEdges(ids: string[]) {
|
||||
if (get(store.multiselectionKeyPressed)) {
|
||||
// @todo handle multiselection key
|
||||
}
|
||||
|
||||
store.edges.update((edges) =>
|
||||
edges.map((edge) => {
|
||||
return {
|
||||
...edge,
|
||||
selected: ids.includes(edge.id)
|
||||
};
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
function panBy(delta: XYPosition) {
|
||||
const { zoom: d3Zoom, selection: d3Selection } = get(store.d3);
|
||||
const transform = get(store.transform);
|
||||
@@ -335,6 +350,7 @@ export function createStore(params: CreateStoreParams): SvelteFlowStore {
|
||||
setMaxZoom,
|
||||
resetSelectedElements,
|
||||
addSelectedNodes,
|
||||
addSelectedEdges,
|
||||
panBy,
|
||||
updateConnection,
|
||||
cancelConnection,
|
||||
|
||||
@@ -27,6 +27,7 @@ export type SvelteFlowStoreActions = {
|
||||
updateNodeDimensions: (updates: NodeDimensionUpdate[]) => void;
|
||||
resetSelectedElements: () => void;
|
||||
addSelectedNodes: (ids: string[]) => void;
|
||||
addSelectedEdges: (ids: string[]) => void;
|
||||
panBy: (delta: XYPosition) => void;
|
||||
updateConnection: (connection: Partial<ConnectionData>) => void;
|
||||
cancelConnection: () => void;
|
||||
|
||||
@@ -34,7 +34,8 @@
|
||||
id: '2',
|
||||
type: 'default',
|
||||
data: { label: 'Node' },
|
||||
position: { x: 0, y: 150 }
|
||||
position: { x: 0, y: 150 },
|
||||
selectable: false,
|
||||
},
|
||||
{
|
||||
id: 'A',
|
||||
@@ -83,7 +84,8 @@
|
||||
id: '1-3',
|
||||
type: 'smoothstep',
|
||||
source: '1',
|
||||
target: '3'
|
||||
target: '3',
|
||||
selectable: false
|
||||
},
|
||||
{
|
||||
id: '2-4',
|
||||
|
||||
Reference in New Issue
Block a user