LearnNewsExamplesServices
Frontmatter
id8615
titleRefactor Container to support atomic component moves
stateClosed
labels
airefactoringcore
assigneestobiu
createdAtJan 13, 2026, 8:49 PM
updatedAtJan 13, 2026, 11:01 PM
githubUrlhttps://github.com/neomjs/neo/issues/8615
authortobiu
commentsCount2
parentIssue8601
subIssues[]
subIssuesCompleted0
subIssuesTotal0
blockedBy[]
blocking[]
closedAtJan 13, 2026, 11:01 PM

Refactor Container to support atomic component moves

Closed v11.21.0 airefactoringcore
tobiu
tobiu commented on Jan 13, 2026, 8:49 PM

Currently, Neo.worker.App.moveComponent implements custom logic to perform a "silent remove" from the old parent before inserting into the new parent. This is necessary to ensure DeltaUpdates receives a moveNode delta instead of removeNode + insertNode (which destroys DOM state like focus/iframes).

This logic should be moved into Neo.container.Base (or a Manager) to allow any component move operation (not just via moveComponent) to be atomic and state-preserving.

Goals:

  • Enhance Neo.container.Base to support moving items from another container.
  • Implement moveTo(newParent, index) or enhance add/insert to detect existing parent and handle transition.
  • Ensure VDOM updates generate moveNode delta where possible.
tobiu added the ai label on Jan 13, 2026, 8:49 PM
tobiu added the refactoring label on Jan 13, 2026, 8:49 PM
tobiu added the core label on Jan 13, 2026, 8:49 PM
tobiu added parent issue #8601 on Jan 13, 2026, 8:49 PM
tobiu assigned to @tobiu on Jan 13, 2026, 8:59 PM
tobiu referenced in commit b47b9d5 - "refactor: Container supports atomic component moves, preserving state & focus (#8615)" on Jan 13, 2026, 10:53 PM
tobiu
tobiu Jan 13, 2026, 10:53 PM

Input from Gemini 3 Pro:

✦ I have successfully refactored Neo.container.Base to support atomic component moves, preserving DOM state like input values and focus.

Key Changes:

  1. Container.Base.insert:

    • Refactored to handle moving existing NeoInstance items.
    • Implemented "Silent Remove + Update New Parent" strategy.
    • Calls oldParent.remove(item, false, true, true) (destroy=false, silent=true, keepMounted=true) to detach the item from the old parent's state without triggering a DOM update (which would send a removeNode delta).
    • Then, it updates the new parent (me). The VDOM diff generates an insertNode delta. DeltaUpdates uses insertBefore / appendChild which effectively moves the existing DOM node instead of destroying and recreating it.
  2. Container.Base.remove / removeAt:

    • Added keepMounted argument to prevent item.mounted = false during the silent move process. This is critical to keep the component's lifecycle active.
  3. Neo.worker.App.moveComponent:

    • Simplified to delegate the atomic move logic entirely to parent.insert (or parent.add).
    • Restored guardrails for component, parent existence, and parent.isContainer.
  4. Neo.main.DeltaUpdates.moveNode:

    • Addressed a critical browser behavior (Chromium/WebKit) where reparenting a focused element causes it to lose focus (blur event).
    • Implemented logic to capture document.activeElement before the move.
    • If the active element is within the moving node, focus() is called on it immediately after the move operation (insertBefore or replaceWith).
    • This ensures the user experience is seamless, even though it may trigger a rapid blur -> focus event sequence.

Verification:

  • Created a new Playwright test suite test/playwright/component/container/AtomicMoves.spec.mjs.
  • Baseline Test: Confirmed that native DOM appendChild loses focus in the test environment (Chromium), validating the need for manual restoration. Also confirmed moveBefore (if available) would preserve it.
  • Input State: Confirmed input values are preserved during a move between sibling containers.
  • Focus State: Confirmed focus is preserved during a move between sibling containers.
  • DOM State: Confirmed custom DOM properties are preserved.

The feature is implemented and robustly tested.

tobiu referenced in commit d2689b4 - "docs: Enhance JSDoc for atomic moves and focus preservation (#8615)" on Jan 13, 2026, 11:01 PM
tobiu
tobiu Jan 13, 2026, 11:01 PM

Input from Gemini 3 Pro:

✦ I have updated the JSDoc for Neo.container.Base, Neo.worker.App, and Neo.main.DeltaUpdates to explicitly document the new atomic move capabilities and focus preservation logic. This ensures that the knowledge about these significant architectural improvements is preserved in the codebase.

tobiu closed this issue on Jan 13, 2026, 11:01 PM