Drawflow icon indicating copy to clipboard operation
Drawflow copied to clipboard

Can drawflow use svelte components?

Open Crystal701 opened this issue 2 years ago • 1 comments

Hi. Is there anyway to use svelte component as the node itself?

Crystal701 avatar Sep 13 '22 03:09 Crystal701

Hi @Crystal701

Default no.

But I've been experimenting a bit with svelte's REPL. It must be said that I have not touched svelte.

But I managed to load a svelte node by overriding the "addNode" function.

REPL-URL: https://svelte.dev/repl/hello-world?version=3.50.1

Name file: "App.svelte" Code:

<script>
  import { onMount } from 'svelte';
	import Drawflow from 'drawflow'
	import MyElement from './Component2.svelte';
	//import styleDrawflow from 'drawflow/dist/drawflow.min.css'

	onMount(() => {
		
		var id = document.getElementById("drawflow");
		const editor = new Drawflow(id);
		
		editor.addNode = function(name, num_in, num_out, ele_pos_x, ele_pos_y, classoverride, data, html, typenode = false) {
						if (this.useuuid) {
							var newNodeId = this.getUuid();
						} else {
							var newNodeId = this.nodeId;
						}
						const parent = document.createElement('div');
						parent.classList.add("parent-node");

						const node = document.createElement('div');
						node.innerHTML = "";
						node.setAttribute("id", "node-"+newNodeId);
						node.classList.add("drawflow-node");
						if(classoverride != '') {
							node.classList.add(...classoverride.split(' '));
						}

						const inputs = document.createElement('div');
						inputs.classList.add("inputs");

						const outputs = document.createElement('div');
						outputs.classList.add("outputs");

						const json_inputs = {}
						for(var x = 0; x < num_in; x++) {
							const input = document.createElement('div');
							input.classList.add("input");
							input.classList.add("input_"+(x+1));
							json_inputs["input_"+(x+1)] = { "connections": []};
							inputs.appendChild(input);
						}

						const json_outputs = {}
						for(var x = 0; x < num_out; x++) {
							const output = document.createElement('div');
							output.classList.add("output");
							output.classList.add("output_"+(x+1));
							json_outputs["output_"+(x+1)] = { "connections": []};
							outputs.appendChild(output);
						}

						const content = document.createElement('div');
						content.classList.add("drawflow_content_node");
						if(typenode === false) {
							content.innerHTML = html;
						} else if (typenode === true) {
							content.appendChild(this.noderegister[html].html.cloneNode(true));

						} else {
							// SVELTE CODE
							const wrapper = new this.noderegister[html].html({
								target: content,
							});
							// SVELTE CODE
						}

						Object.entries(data).forEach(function (key, value) {
							if(typeof key[1] === "object") {
								insertObjectkeys(null, key[0], key[0]);
							} else {
								var elems = content.querySelectorAll('[df-'+key[0]+']');
									for(var i = 0; i < elems.length; i++) {
										elems[i].value = key[1];
										if(elems[i].isContentEditable) {
											elems[i].innerText = key[1];
										}
									}
							}
						})

						function insertObjectkeys(object, name, completname) {
							if(object === null) {
								var object = data[name];
							} else {
								var object = object[name]
							}
							if(object !== null) {
								Object.entries(object).forEach(function (key, value) {
									if(typeof key[1] === "object") {
										insertObjectkeys(object, key[0], completname+'-'+key[0]);
									} else {
										var elems = content.querySelectorAll('[df-'+completname+'-'+key[0]+']');
											for(var i = 0; i < elems.length; i++) {
												elems[i].value = key[1];
												if(elems[i].isContentEditable) {
													elems[i].innerText = key[1];
												}
											}
									}
								});
							}
						}
						node.appendChild(inputs);
						node.appendChild(content);
						node.appendChild(outputs);
						node.style.top = ele_pos_y + "px";
						node.style.left = ele_pos_x + "px";
						parent.appendChild(node);
						this.precanvas.appendChild(parent);
						var json = {
							id: newNodeId,
							name: name,
							data: data,
							class: classoverride,
							html: html,
							typenode: typenode,
							inputs: json_inputs,
							outputs: json_outputs,
							pos_x: ele_pos_x,
							pos_y: ele_pos_y,
						}
						this.drawflow.drawflow[this.module].data[newNodeId] = json;
						this.dispatch('nodeCreated', newNodeId);
						if (!this.useuuid) {
							this.nodeId++;
						}
						return newNodeId;
					}
	
		editor.start();
		
		// Normal HTML Node
		editor.addNode('test', 0, 1, 150, 300, 'test', {}, 'test');
		
		// Register Node
		editor.registerNode('testComponent', MyElement);
		// Use
		editor.addNode('github', 0, 1, 150, 300, 'github', {}, 'testComponent', 'svelte');

	})
</script>

<div id="drawflow" class="parent-drawflow"></div>

<style>
	#drawflow {
		position:relative;
		width: 600px;
		height: 400px;
		border: 1px solid red;
	}
</style>

Name file: "Component2.svelte" Code component:

<script>
	export let name = 'world';
</script>

<h1>Hello {name}!</h1>

And load component correctly without style.

image

I think it's the right way to load a component, it's out of the documentation: https://svelte.dev/docs#run-time-client-side-component-api-creating-a-component

The only thing I haven't been able to load is the drawflow style 'styleDrawflow', surely the REPL has limitations.

The code that has been overwritten would also have to be overwritten by the addNodeImport function. It is currently documented with // SVELTE CODE

Having never worked with svelte I don't know if it's the right way. I think so.

Here is someone who has already imported svelte, although I don't know if the components.

  • https://github.com/jerosoler/Drawflow/issues/440

jerosoler avatar Sep 13 '22 07:09 jerosoler