open-source-labs / Svelvet

🎛 A Svelte library for building dynamic, infinitely customizable node-based user interfaces and flowcharts
https://svelvet.io
2.59k stars 166 forks source link

Feature request: Something similar to `isValidConnection` in reactflow #453

Open MrMugame opened 1 year ago

MrMugame commented 1 year ago

So I would like to only be able to connected anchors of the same "kind" with each other. This could either be achieved through a making something like an anchor "kind" you could optionally specify and checking it when connecting the edge or having something like isValidConnection, which gets called before connecting the edge and has to return true of false. Maybe this is already a feature, which Im missing but I couldn't find anything.

I was able to make a workaround by subscribing to the input store in a custom anchor and checking if the newly added store is of the correct type (by having every output store, output an object with a type parameter) and disconnecting the edge if necessary. But this is more than a hack in my opinion.

andreapiso commented 1 year ago

+1 for the feature! I need to have some "type" criteria to determine whether an edge is valid or not. @MrMugame would you be able to share with the community the snippet for your "hack"? If the functionality is not supported, this might be the best solution yet.

MrMugame commented 1 year ago

Sure, but I really don't know if Id recommend using it, because this is a really quick and dirty hack

A wrapper component for the anchor:

<script>
    import { Anchor } from "svelvet";
    import { get } from "svelte/store"
    // Import some kind of uuid function

    export let inputsStore;
    export let disconnect;
    export let nodeID;

    // Using somekind of uuid here, because I don't know if there is a way to extract the ID from an Anchor
    let id = uuid();

    inputsStore.subscribe((event) => {
        if (get(event.one)?.type !== "foo") {
            delete event.one;
            disconnect([nodeID, id]);
        }
    });
</script>

<Anchor {id} key="one" {inputsStore} input direction="west"/>

Using the anchor comoponent:

<script>
    import { Node, generateInput } from 'svelvet';
    // Import the above component
    // Again some uuid function

    let id = uuid();

    const input = generateInput();
</script>

<Node {id} useDefaults let:disconnect>
    <CustomAnchor nodeID={id} {disconnect} inputsStore={input} />
</Node>

And this is what every output store would have to look like to be able to connect with the anchor:

const output = writable({ type: "foo", data: null });