Add navigationStrategy to override default behavior#231
Conversation
…NavigationService for custom navigation handling
🦋 Changeset detectedLatest commit: e17ccdb The changes in this PR will be included in the next version bump. Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
| siblings.map((sibling) => sibling.focusKey).join(', '), | ||
| siblings.map((sibling) => sibling.node), | ||
| siblings.map((sibling) => sibling) | ||
| nextComponent = navigationStrategy( |
There was a problem hiding this comment.
Since this is external function, we should add some warnings if the returned nextComponent is invalid/missing/not in focusable components list, so people see that their navigationStrategy is not working as intended.
| focusBoundaryDirections?: Direction[]; | ||
| autoRestoreFocus: boolean; | ||
| forceFocus: boolean; | ||
| navigationStrategy?: NavigationStrategy; |
There was a problem hiding this comment.
navigationStrategy name is misleading, this is a function, while the name suggests it's an object
There was a problem hiding this comment.
yeah I know, I wanted to avoid navigationStrategyFn or similar. Not sure if onNavigate is a good one either
There was a problem hiding this comment.
getNextNavigationTarget, onNavigateToCustom, onIncerceptNavigation
Summary
Adds an optional
navigationStrategyhook so a parent focus scope can override default spatial navigation when moving between siblings. When set on the parent focusable, arrow navigation among its children uses your function instead of cutoff coordinates and priority sorting.Motivation
Default spatial navigation is geometry-based (cutoff coordinates, RTL/LTR,
sortSiblingsByPriority). Some UIs need deterministic or domain-specific ordering (e.g. custom grids, masked lists, non-rect layouts, overlapped elements...). This change lets callers supply the next focus target explicitly while keeping the existing algorithm as the default when no strategy is provided.API
NavigationStrategy:FocusableComponent.navigationStrategy(optional) — stored and updated with addFocusable / updateFocusable.useFocusable({ navigationStrategy })— passes the strategy through registration and dependency updates.Behavior
During smartNavigate, the service reads navigationStrategy from the parent (focusableComponents[parentFocusKey]).
If present: collects siblings with the same parentFocusKey that are focusable, calls navigationStrategy(direction, focusKey, siblings), and uses its return value as the next component (skips default sibling filtering by layout cutoff, visual-debug sibling drawing for that path, and sortSiblingsByPriority).