LearnNewsExamplesServices
Frontmatter
id9179
titleDevIndex: Introduce StateProvider for animateVisuals
stateClosed
labels
bugairefactoring
assignees[]
createdAtFeb 16, 2026, 2:07 AM
updatedAtFeb 16, 2026, 3:14 AM
githubUrlhttps://github.com/neomjs/neo/issues/9179
authortobiu
commentsCount1
parentIssuenull
subIssues[]
subIssuesCompleted0
subIssuesTotal0
blockedBy[]
blocking[]
closedAtFeb 16, 2026, 3:14 AM

DevIndex: Introduce StateProvider for animateVisuals

Closed v12.0.0 bugairefactoring
tobiu
tobiu commented on Feb 16, 2026, 2:07 AM

To fix a regression where animateVisuals state is lost or listeners are not attached due to lazy loading of the Grid, we will introduce a Neo.state.Provider.

  1. Create apps/devindex/view/ViewportStateProvider.mjs with animateVisuals: true.
  2. Add the provider to DevIndex.view.Viewport.
  3. Bind GridContainer's animateVisuals config to the state provider: bind: {animateVisuals: data => data.animateVisuals}.
  4. Update MainContainerController (checkbox) to write to the state provider instead of the grid directly.
  5. Update ViewportController to listen to the state provider changes to update the HeaderCanvas pulse effect, removing the direct dependency on the Grid component.
tobiu added the bug label on Feb 16, 2026, 2:07 AM
tobiu added the ai label on Feb 16, 2026, 2:07 AM
tobiu added the refactoring label on Feb 16, 2026, 2:07 AM
tobiu referenced in commit 5c201c1 - "refactor(devindex): Implement StateProvider for Viewport state management (#9179)" on Feb 16, 2026, 3:13 AM
tobiu
tobiu Feb 16, 2026, 3:13 AM

Input from Gemini 3 Pro:

✦ Refactoring complete.

Summary of Changes:

  1. State Provider: Introduced DevIndex.view.ViewportStateProvider to manage animateVisuals and isScrolling state globally for the Viewport.
  2. Decoupling: Removed imperative event listeners from ViewportController, solving the regression where lazy-loaded components (Grid) were missed during initialization.
  3. Bridge Pattern: DevIndex.view.HeaderToolbar now acts as a bridge, binding to the State Provider and declaratively updating the HeaderCanvas renderer via afterSet hooks.
  4. Grid Integration: GridContainer now binds to animateVisuals and pushes isScrolling state to the provider, ensuring the header animation reacts to grid interactions regardless of component lifecycle.
  5. State Logic: State mutations (onShowAnimationsChange and onGridIsScrollingChange) are centralized in MainContainerController.

The architecture is now more robust, leveraging Neo.mjs State Providers for clean, persistent state management across lazy-loaded views.

tobiu closed this issue on Feb 16, 2026, 3:14 AM