From 8e2b30d112006d1509b3552fd2568a5990f45eaa Mon Sep 17 00:00:00 2001 From: Antamansid Date: Fri, 13 Feb 2026 13:24:24 +0300 Subject: [PATCH 1/2] fix: resolve race condition in anchor positioning for newly created anchors --- src/react-components/hooks/useBlockAnchorState.ts | 15 ++++++++++++++- src/store/anchor/Anchor.ts | 3 +++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/src/react-components/hooks/useBlockAnchorState.ts b/src/react-components/hooks/useBlockAnchorState.ts index e8646121..0fa135fa 100644 --- a/src/react-components/hooks/useBlockAnchorState.ts +++ b/src/react-components/hooks/useBlockAnchorState.ts @@ -24,7 +24,20 @@ export function useBlockAnchorPosition( return; } - const position = state.getViewComponent()?.getPosition(); + if (!state.$viewComponentReady.value) { + return; + } + + const viewComponent = state.getViewComponent(); + if (!viewComponent) { + return; + } + + const position = viewComponent.getPosition(); + if (!position) { + return; + } + const blockGeometry = state.block.$geometry.value; anchorContainerRef.current.style.setProperty("--graph-block-anchor-x", `${position.x - blockGeometry.x}px`); anchorContainerRef.current.style.setProperty("--graph-block-anchor-y", `${position.y - blockGeometry.y}px`); diff --git a/src/store/anchor/Anchor.ts b/src/store/anchor/Anchor.ts index 3f0d8640..7853fb3a 100644 --- a/src/store/anchor/Anchor.ts +++ b/src/store/anchor/Anchor.ts @@ -13,6 +13,8 @@ export class AnchorState { public $selected = computed(() => this.block.store.anchorSelectionBucket.isSelected(this.id)); + public $viewComponentReady = signal(false); + private anchorView: Anchor; public get id() { @@ -43,6 +45,7 @@ export class AnchorState { public setViewComponent(anchorComponent: Anchor) { this.anchorView = anchorComponent; + this.$viewComponentReady.value = true; } public getViewComponent() { From f7c464ff9d1a7eabaf68d02645c8d044dad5f302 Mon Sep 17 00:00:00 2001 From: Antamansid Date: Tue, 17 Feb 2026 18:04:50 +0300 Subject: [PATCH 2/2] fix(anchor): reset viewComponentReady state on unmount --- src/components/canvas/anchors/index.ts | 1 + src/store/anchor/Anchor.ts | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/src/components/canvas/anchors/index.ts b/src/components/canvas/anchors/index.ts index ee7100dd..d7b1bb27 100644 --- a/src/components/canvas/anchors/index.ts +++ b/src/components/canvas/anchors/index.ts @@ -171,6 +171,7 @@ export class Anchor extends GraphComponen protected unmount() { this.props.port.removeOwner(); + this.connectedState.unsetViewComponent(); super.unmount(); } diff --git a/src/store/anchor/Anchor.ts b/src/store/anchor/Anchor.ts index 7853fb3a..c41e87b6 100644 --- a/src/store/anchor/Anchor.ts +++ b/src/store/anchor/Anchor.ts @@ -48,6 +48,11 @@ export class AnchorState { this.$viewComponentReady.value = true; } + public unsetViewComponent() { + this.anchorView = undefined; + this.$viewComponentReady.value = false; + } + public getViewComponent() { return this.anchorView; }