Quantcast
Channel: Active questions tagged svelte - Stack Overflow
Viewing all articles
Browse latest Browse all 1541

Svelte 5: Passing state and derived values from children to parent (runes mode without stores)

$
0
0

I have a parent component with multiple draggable Item-components which will be created dynamically in the final app. Inside each Item I calculate the current position as well as a derived offset value. Each time, any Item is dragged I want its position/offset to be shared reactively with the parent component.

In Svelte 4 with stores this was fairly easy. However, I struggle implementing this in Svelte 5 with runes. Context-API somehow isn't an option, since I'd like to define pos/offset inside the Item-component where they belong... shouldn't I?

Here is my current code: REPL

The current code has two issues:

  • (1) While sending the position (state) to the parent via bound props, this does not work for the offset (derived). Why?
  • (2) As soon as the second item-component is mounted, the connection between the first item and the parent is lost. Why?
Update

Reduced code (without timers): REPL

App.svelte

<svelte:options runes="{true}" /><script>    import Item from './Item.svelte';    let CURRENT = $state({pos: {x:99, y:99}, offset: 99});</script><h1>Last dragged item: ({CURRENT.pos.x} / {CURRENT.pos.y}) Offset: {CURRENT.offset}</h1><Item bind:CURRENT={CURRENT} itemName='ONE' /><Item bind:CURRENT={CURRENT} itemName='TWO' />

Item.svelte

<svelte:options runes="{true}" /><script>    import interact from 'interactjs';    let { CURRENT = $bindable(), itemName } = $props();    let item;    let pos = $state({x:0, y:0});    let offset = $derived(Math.floor(Math.sqrt( Math.pow(pos.x,2) + Math.pow(pos.y,2) )));    CURRENT.pos = pos;    CURRENT.offset = offset;    const handleDraggable = (node) => {        interact(node).draggable({                          onmove: (ev) => {                let el = ev.target;                let x = (parseFloat(el.getAttribute('data-x')) || 0) + ev.dx;                let y = (parseFloat(el.getAttribute('data-y')) || 0) + ev.dy;                el.style.webkitTransform =  el.style.transform = `translate(${x}px,${y}px)`;                el.setAttribute('data-x', x);                el.setAttribute('data-y', y);                pos.x = x;                pos.y = y;            },        });    }</script><div id="draggable" bind:this={item} use:handleDraggable> <p>{itemName} ({pos.x} / {pos.y}) Offset: {offset}</p></div>

Viewing all articles
Browse latest Browse all 1541

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>