Skip to content

Commit 4d5cf3e

Browse files
Merge pull request #410 from open-source-labs/dev
feat: position prop features two way data binding
2 parents d5b4425 + 6b2c8b7 commit 4d5cf3e

File tree

3 files changed

+63
-7
lines changed

3 files changed

+63
-7
lines changed

docs/components/node.mdx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,8 @@ detail.node.set.bgColor('red');
5656
## Props
5757

5858
<ResponseField name="position" type="{x: number, y: number}" default="{x: 0, y: 0}">
59-
Initial position of the node. Coordinate is relative to the top/left point of the canvas.
59+
The position of the Node. These correspond to pixel values at the default graph scale. This prop
60+
newly features two way data binding. Please report any issues on GitHub.
6061
</ResponseField>
6162
<ResponseField
6263
name="dimensions"

src/lib/components/Node/Node.svelte

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,9 @@
1717
//const storedNode = JSON.parse(localStorage.getItem('state'))?.nodes?[id]
1818
/**
1919
* @default { x: 0, y: 0 }
20-
* @description The initial position of the Node. These correspond to pixel values
21-
* at default graph scale. This value does not currently feature two way binding
20+
* @description The position of the Node. These correspond to pixel values
21+
* at default graph scale. This prop newly features two way data binding. Please report any issues
22+
* on GitHub.
2223
*/
2324
export let position = { x: 0, y: 0 };
2425
export let drop: 'cursor' | 'center' | false = false;
@@ -227,12 +228,28 @@
227228
node.zIndex.set(zIndex);
228229
}
229230
230-
// This is a bit of a hack to get around the fact that the position prop is not two way bindable
231-
// Future versions will have an implementation
232-
// That uses component instance binding to achieve the same result
233231
$: nodePosition = node && node?.position;
232+
233+
let priorPosition = position;
234+
234235
$: if (node) {
235-
position = $nodePosition;
236+
const { x: priorX, y: priorY } = priorPosition;
237+
const { x: nodeX, y: nodeY } = $nodePosition;
238+
const { x: propX, y: propY } = position;
239+
240+
const areDifferent = propX !== nodeX || propY !== nodeY;
241+
242+
const propChanged = propX !== priorX || propY !== priorY;
243+
244+
if (areDifferent) {
245+
if (propChanged) {
246+
priorPosition = position;
247+
node.position.set(position);
248+
} else {
249+
priorPosition = $nodePosition;
250+
position = $nodePosition;
251+
}
252+
}
236253
}
237254
$: if (node) {
238255
node.inputs.set(inputs);

src/routes/movement/+page.svelte

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
<script lang="ts">
2+
import { Svelvet, Node, Anchor } from '$lib';
3+
4+
let position = { x: 300, y: 300 };
5+
$: console.log(position);
6+
</script>
7+
8+
<body>
9+
<Svelvet minimap title="test">
10+
<Node bgColor="red" inputs={4} bind:position>
11+
<div class="node-body">
12+
<p>{JSON.stringify(position)}</p>
13+
<button
14+
on:click={() => {
15+
position = { x: 100, y: 100 };
16+
}}>Move</button
17+
>
18+
</div>
19+
</Node>
20+
</Svelvet>
21+
</body>
22+
23+
<style>
24+
.node-body {
25+
width: 200px;
26+
height: 300px;
27+
display: flex;
28+
flex-direction: column;
29+
justify-content: center;
30+
align-items: center;
31+
}
32+
body {
33+
width: 100vw;
34+
height: 100vh;
35+
margin: 0;
36+
padding: 0;
37+
}
38+
</style>

0 commit comments

Comments
 (0)