Svelte - Rete.js

Svelte

This guide is an extension of the Basic guide and provides instructions for using the rete-svelte-plugin instead of rete-react-plugin

BasicCustomizationControlsPluginSvelteContext menuMinimapReroute

This plugin offers a classic preset that comes with visual components for nodes, connections, sockets, and input controls.

Supports both versions of Svelte: 3 and 4

Install dependencies

bash
npm i rete-svelte-plugin rete-render-utils sass

Plugin connection

ts
import { AreaPlugin } from "rete-area-plugin";
import { SveltePlugin, Presets, SvelteArea2D } from "rete-svelte-plugin";

type AreaExtra = SvelteArea2D<Schemes>;

// ....

const render = new SveltePlugin<Schemes, AreaExtra>();

render.addPreset(Presets.classic.setup());

area.use(render);

Please note that this plugin is intended for client-side use only. Therefore, modules that use it within your *.svelte modules need to be dynamically imported.

ts
onMount(async () => {
  const { createEditor } = await import("./editor");
})

Check out the Svelte page for an example usage of this render plugin.

Controls

This plugin provides built-in controls that are displayed based on the following objects:

  • ClassicPreset.InputControl as <input type="number" /> or <input type="text" />

Simply add the control to the node

ts
node.addControl('my-control', new ClassicPreset.InputControl("number", {
  initial: 0,
  readonly: false,
  change(value) { }
}))

If you want to add different types of controls, you can return the necessary component in the control handler of customize property.

tsx
import MyButton from './MyButton.svelte'

render.addPreset(Presets.classic.setup({
  customize: {
    control(context) {
      if (context.payload.isButton) {
        return MyButton
      }
      if (context.payload instanceof ClassicPreset.InputControl) { // don't forget to explicitly specify the built-in Presets.classic.Control
        return Presets.classic.Control;
      }
    }
  }
}));

node.addControl('my-button', { isButton: true, label: 'Click', onClick() {} })

MyButton.svelte

svelte
<button
  on:pointerdown|stopPropagation={() => null}
  on:click="data.onClick"
>
  {data.label}
</button>

This is a simplified version suitable for introductory purposes. For projects, it is recommended to follow the approach demonstrated in the example

Make sure to specify on:pointerdown|stopPropagation to prevent the area from intercepting events such as click.

Customization

In a similar manner to the approach outlined above, you can replace node, connection, or socket components.

Customization of all nodes

If you want to completely change the node structure, you can implement your own component similar to Node.svelte from the classic preset

ts
import CustomNode from './CustomNode.svelte'

render.addPreset(Presets.classic.setup({
  customize: {
    node() {
      return CustomNode
    }
  }
}))

The implementation of CustomNode is available in the CustomNode.svelte file of the Customization for Svelte example.

Specific nodes

You can add an extra condition to apply this component only to specific nodes.

ts
render.addPreset(Presets.classic.setup({
  customize: {
    node(context) {
      if (context.payload.label === "Custom") {
        return CustomNode;
      }
      return Presets.classic.Node;
    }
  }
}))

await editor.addNode(new ClassicPreset.Node('White'))

Connection customization

Use Connection.svelte as a starting point from the presets/classic/components directory of the plugin's source code.

ts
import CustomConnection from './CustomConnection.svelte'

render.addPreset(Presets.classic.setup({
  customize: {
    connection() {
      return CustomConnection
    }
  }
}))

Socket customization

Use Socket.svelte as a starting point from the presets/classic/components directory of the plugin's source code.

ts
import CustomSocket from './CustomSocket.svelte'

render.addPreset(Presets.classic.setup({
  customize: {
    socket() {
      return CustomSocket
    }
  }
}))

Customize context menu

In order to customize the context menu for this rendering plugin, one can override styles using selectors (and it's important to consider the specificity of selectors in CSS)

scss
.rete-context-menu {
  width: 320px !important;
  .block:first-child input {
    background: grey;
  }
  .block.item {
    background: grey;
  }
}

Other presets

Check out the complete result on the Customization for Svelte example page.