Skip to content

feat(focus): focus keys, destination keys and exits - #128

Merged
RuudBurger merged 1 commit into
mainfrom
ruud/focus-regions
Oct 8, 2026
Merged

RuudBurger merged 1 commit into
mainfrom
ruud/focus-regions

Conversation

@RuudBurger

@RuudBurger RuudBurger commented Oct 5, 2026 •

Copy link
Copy Markdown
Member

Groundwork for running the native focus regions from the Plex app on Lightning (app side: https://github.com/plexinc/react-native-client/pull/6698). The engine had no way to name an element, so anything key based (destinations, exits, focusByKey) had to be worked around from outside.

What changed

  • focusKey on FocusGroup / useFocus registers an element under a string, FocusManager.focusByKey(key) focuses it (false if nothing is mounted under it)
  • destinationKeys: ordered keys that arriving focus is forwarded to, first mounted one wins. first and last-focused stand for the group's own first and remembered child
  • exits: a key per direction for when a move finds nothing inside the group (only used then, same as before for traps)
  • A focusable View, Pressable or FocusGroup in react-native-lightning registers its nativeID as its key
  • An empty redirect group that has destinations now counts as a navigation target, otherwise a thin redirect between two rows gets skipped
  • Entry modes (first, last-focused, spatial), rememberAs per value, scopes, nearest repick when the remembered node is gone, and enter/leave events
  • Initial focus claims: highest priority wins, batched in a microtask so no item takes focus first, and the default pick is held back while a claim waits for content
  • rememberAs swaps the whole remembered chain (a value that comes back returns to its item by focus key, so recycled list cells stay right), and refocusInitial holds the repick while its target is still mounting (at most 1 s)
  • useFocus registers once and updates with a single effect
  • An inactive element stays unfocusable after it is re-parented

Setters for the new options run before the node is in the tree (the parent registers a render later), so they also go through addElement options, same as destinations.

Tested with unit tests (FocusKeys.spec.ts, FocusRegions.spec.ts, 356 passing in the package) and against the 42 Plex focus cases in the Lightning storybook: all 42 pass.

@RuudBurger
RuudBurger marked this pull request as ready for review October 5, 2026 12:19
@RuudBurger
RuudBurger requested a review from DouweBos October 8, 2026 13:16
@RuudBurger
RuudBurger merged commit e307f24 into main Oct 8, 2026
1 check passed
@RuudBurger
RuudBurger deleted the ruud/focus-regions branch October 8, 2026 15:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants