I'm trying to build a DND survey editor using SVELTE. I use svelte-dnd-action. It should be possible to add new categories and questions to a 'root' DNDZone via copy and drag from a bar with the options "New Category" or "New Question". Categories should be nested within each other and questions should be able to be added to them.
Basically it should look like this example. Only 'nodes' and 'items' should be able to be created.
App.svelte:
<script> import Content from './Content.svelte' let nodes = { node1:{name:'node 1', items:[ {id: 'node2'}, {id: 'node3'}, {id: 'node4'} ], id:'node1' }, node2:{name:'node 2', items:[ {id: 'node5'}, {id: 'node6'}, {id: 'node7'}, {id: 'node8'} ], id:'node2' }, node3:{name:'node 3', items:[ {id: 'node9'}, {id: 'node10'}, {id: 'node11'}, {id: 'node12'} ], id:'node3' }, node4:{name:'node 4', items:[ {id: 'node13'}, {id: 'node14'}, {id: 'node15'}, {id: 'node16'} ], id:'node4', color: 'salmon' }, }for (let i = 5; i < 17; i++) { nodes[`node${i}`]={id:`node${i}`, name:`item ${i}`}}nodes['node10'].color='steelblue' nodes['node11'].color='steelblue' nodes['node14'].color='orange' nodes['node15'].color='orange' nodes['node6'].color='forestgreen'</script><h3> Try dragging node2 into node3 and then node4 into node2 </h3><Content node={nodes.node1} bind:nodes={nodes} />
Content.svelte:
<script> import { flip } from 'svelte/animate'; import { dndzone } from 'svelte-dnd-action'; export let nodes export let node const flipDurationMs = 300; function handleDndConsider(e) { node.items = e.detail.items; } function handleDndFinalize(e) { node.items = e.detail.items; nodes = {...nodes}; }</script><b style="color:{node?.color}">{node?.name}</b> {#if node?.hasOwnProperty("items")}<section use:dndzone={{items:node.items, flipDurationMs, centreDraggedOnCursor: true}} on:consider={handleDndConsider} on:finalize={handleDndFinalize}> {#each node.items as item(item.id)}<div animate:flip="{{duration: flipDurationMs}}" class="item"><svelte:self bind:nodes={nodes} node={nodes[item.id]} /></div> {/each}</section>{/if}<style> section { width: auto; max-width: 400px; border: 0px solid black; padding: 0.4em; /* this will allow the dragged element to scroll the list */ overflow-y: auto ; height: auto; background-color: rgba(100, 100, 100, 0.1); } div { width: 90%; padding: 0.3em; border: 0px solid blue; margin: 0.15em 0; } .item{ background-color: rgba(00, 100, 100, 0.1); }</style>