Spatial Navigation
A JavaScript-based implementation for Spatial Navigation with gamepad support
Basic implementation
Section titled “Basic implementation”spatialNavigation.init(['.square']);Click on an element and move the focus with your keyboard arrow keys:
If you add a disabled property to a navigable element it will skip it when moving the focus
init(navigableElements, overlap)
Section titled “init(navigableElements, overlap)”Initializes the spatial navigation.
type NavigableArea = { area: string, elements: (string | HTMLElement)[]};
type NavigationInput = (string | HTMLElement)[] | NavigableArea[];
spatialNavigation.init(navigableElements: NavigationInput = [], overlap?: number);navigableElement
Section titled “navigableElement”The navigableElement can be:
1. A string selector:
Section titled “1. A string selector:”spatialNavigation.init(['.square']);2. An HTMLElement reference: 2.4.4
Section titled “2. An HTMLElement reference: ”2.4.4const element = document.getElementById('myElement');spatialNavigation.init([element]);3. A navigableArea object:
Section titled “3. A navigableArea object:”spatialNavigation.init([ { area: 'square-1', elements: ['.square1'] }, { area: 'square-2', elements: ['.square2'] },]);This will create different areas to separate the navigation. If you pass only selectors or HTMLElements directly, they will be saved to the default area.
Overlap (optional)
Section titled “Overlap (optional)”The init method takes an optional second argument, overlap, which accepts a value between 0.01 and 1. The default value is 0.5 (50%). It specifies the percentage of acceptable overlap between the current element and the next potential element for navigation.
If you want the elements to overlap perfectly (without any offset) in order to navigate between them, set the overlap value to 1 (100%).
spatialNavigation.init(['.square'], 1);If you set a value less than 0 or greater than 1, the default value (0.5) will be used

In the following example, when navigating to the right, square 3 will be skipped because it has a Y-offset of 51%, and the overlap parameter was not specified when calling the init method (defaulting to 0.5, or 50%). By specifying an overlap value of 0.55, square 3 will be considered a valid target, and moving right will focus on square 3.
spatialNavigation.init(['.square'], 0.55);Type:
type area = stringThe name of the area you want to be navigable
elements
Section titled “elements”Type:
type elements = (string | HTMLElement)[]An array of element selectors (strings) or HTMLElement references that will be navigable in this area. You can mix both types in the same array.
deinit()
Section titled “deinit()”Removes the spatial navigation, listeners and actions.
spatialNavigation.deinit();add(navigableElements)
Section titled “add(navigableElements)”The same as .init() but only adds elements to areas and new areas. Use it after initialization.
Supports the same formats as init(): selector strings, HTMLElement references, or navigableArea objects with mixed types.
// Add selectors to default areaspatialNavigation.add(['.new-element']);
// Add HTMLElement references to default areaconst newEl = document.getElementById('newItem');spatialNavigation.add([newEl]);
// Add to named area with mixed typesconst element = document.getElementById('sidebar-item');spatialNavigation.add([ { area: 'area-1', elements: ['.element', element] }]);remove(area)
Section titled “remove(area)”default='default'
Remove all of the elements from an area. It uses the area name as an argument, if you don’t pass any arguments it will remove the elements from the default area.
spatialNavigation.remove(area: string = 'default');spatialNavigation.remove('area-1');focusFirst(area)
Section titled “focusFirst(area)”default='default'
Focuses on the first element of an area.
spatialNavigation.focusFirst(area: string = 'default');focusLast(area)
Section titled “focusLast(area)”default='default'
Focuses on the last element of an area.
spatialNavigation.focusLast(area: string = 'default');switchArea(area)
Section titled “switchArea(area)”Switches to another area and focuses on the first element.
spatialNavigation.switchArea(area: string);clearFocus()
Section titled “clearFocus()”Unfocuses the currently focused element in a navigable area.
spatialNavigation.clearFocus();changeKeys(customDirections, options)
Section titled “changeKeys(customDirections, options)”type Direction = 'down' | 'up' | 'left' | 'right';type CustomKeysInput = Partial<Record<Direction, KeyName | KeyName[]>>;
spatialNavigation.changeKeys(customDirections: CustomKeysInput, options = { clearCurrentActiveKeys: false });spatialNavigation.changeKeys({ up: 'W', down: 's', left: 'a', right: 'd' }, { clearCurrentActiveKeys: true });The method accepts an optional options object as a last argument. The available options are:
clearCurrentActiveKeys- Boolean. Defaults tofalse. Iftrue, it clears all other keys except the provided ones. Iffalseоr not specified the provided keys will just be added to the registered keys collection.
resetKeys()
Section titled “resetKeys()”Resets the navigation keys to their default settings, restoring the key bindings to the standard navigation keys (arrow_up, arrow_down, arrow_left, arrow_right).
spatialNavigation.resetKeys();pause() 2.5.5
Section titled “pause() ”2.5.5Pauses the spatial navigation functionality. When paused, navigation keys will not move focus between elements. This is useful when you need to temporarily disable navigation, such as during modal dialogs or text input.
spatialNavigation.pause();resume() 2.5.5
Section titled “resume() ”2.5.5Resumes the spatial navigation functionality after it has been paused. Navigation keys will work normally again.
spatialNavigation.resume();Example usage:
// Pause navigation when opening a modalopenModal();spatialNavigation.pause();
// Resume navigation when closing the modalcloseModal();spatialNavigation.resume();Properties
Section titled “Properties”enabled
Section titled “enabled”Type: boolean
Returns true if the spatial navigation is enabled, otherwise false.
lastFocusedElement
Section titled “lastFocusedElement”Type: HTMLElement | null | undefined
Returns the last focused element.
paused
Section titled “paused”Type: boolean
Returns true if the spatial navigation is paused, otherwise false.
Type: Record<string, { elements: HTMLElement[], distance: number, overflow: { x: number, y: number } }>
Returns an object with all the registered areas.
Actions
Section titled “Actions”The spatial-navigation registers actions that move the focus. You can use these from your code directly with
action.execute('move-focus-down'); // moves the focus downaction.execute('move-focus-up'); // moves the focus upaction.execute('move-focus-left'); // moves the focus leftaction.execute('move-focus-right'); // moves the focus right