@@ -189,16 +189,38 @@ class DesignMainDomainComponent extends UiComponent2<DesignMainDomainProps> with
189189
190190 // needed for capturing right-click events with React:
191191 // https://medium.com/@ericclemmons/react-event-preventdefault-78c28c950e46
192+ //
193+ // React may replace the underlying DOM element on re-render (e.g., after moving a strand),
194+ // so we track the element we attached to and re-attach in componentDidUpdate if it changed.
195+ Element ? _attachedElement;
196+
197+ void _attachContextMenuListener () {
198+ var element = querySelector ('#${props .domain .id }' );
199+ if (element != null && ! identical (element, _attachedElement)) {
200+ _detachContextMenuListener ();
201+ element.addEventListener (constants.context_menu_event_name, on_context_menu);
202+ _attachedElement = element;
203+ }
204+ }
205+
206+ void _detachContextMenuListener () {
207+ _attachedElement? .removeEventListener (constants.context_menu_event_name, on_context_menu);
208+ _attachedElement = null ;
209+ }
210+
192211 @override
193212 componentDidMount () {
194- var element = querySelector ('#${props .domain .id }' )! ;
195- element.addEventListener ('contextmenu' , on_context_menu);
213+ _attachContextMenuListener ();
214+ }
215+
216+ @override
217+ componentDidUpdate (Map prevProps, Map prevState, [dynamic snapshot]) {
218+ _attachContextMenuListener ();
196219 }
197220
198221 @override
199222 componentWillUnmount () {
200- var element = querySelector ('#${props .domain .id }' )! ;
201- element.removeEventListener ('contextmenu' , on_context_menu);
223+ _detachContextMenuListener ();
202224 super .componentWillUnmount ();
203225 }
204226
0 commit comments