Navigation Patterns

Protocols and implementations for keyboard navigation within focus zones.

Direction Type

Navigation directions supported by the framework.

LinearVertical

Up/Down navigation through a vertical list of items. This is the most common pattern.


source

LinearVertical


def LinearVertical(
    wrap:bool=False
)->None:

Up/Down navigation through a vertical list.

# Test LinearVertical
nav = LinearVertical()
assert nav.name == "linear_vertical"
assert nav.get_supported_directions() == ("up", "down")
assert nav.get_next_index(0, "down", 5) == 1
assert nav.get_next_index(4, "down", 5) == 4  # no wrap
assert nav.get_next_index(0, "up", 5) == 0    # no wrap

# Test with wrap
nav_wrap = LinearVertical(wrap=True)
assert nav_wrap.get_next_index(4, "down", 5) == 0  # wraps to start
assert nav_wrap.get_next_index(0, "up", 5) == 4    # wraps to end

LinearHorizontal

Left/Right navigation through a horizontal list. Useful for word tokens in split mode, tabs, etc.


source

LinearHorizontal


def LinearHorizontal(
    wrap:bool=False
)->None:

Left/Right navigation through a horizontal list.

# Test LinearHorizontal
nav = LinearHorizontal()
assert nav.name == "linear_horizontal"
assert nav.get_supported_directions() == ("left", "right")
assert nav.get_next_index(0, "right", 5) == 1
assert nav.get_next_index(4, "right", 5) == 4  # no wrap
assert nav.get_next_index(0, "left", 5) == 0   # no wrap

# Test with wrap
nav_wrap = LinearHorizontal(wrap=True)
assert nav_wrap.get_next_index(4, "right", 5) == 0  # wraps
assert nav_wrap.get_next_index(0, "left", 5) == 4   # wraps

ScrollOnly

A navigation pattern for zones that are scrollable but don’t have selectable items (e.g., a preview panel).


source

ScrollOnly


def ScrollOnly(
    
)->None:

No item navigation, zone is scrollable content only.

# Test ScrollOnly
nav = ScrollOnly()
assert nav.name == "scroll_only"
assert nav.get_supported_directions() == ()
assert nav.get_next_index(2, "down", 5) == 2  # unchanged

Grid (Placeholder)

2D grid navigation for use in media galleries and similar UIs. Marked as placeholder for future implementation.


source

Grid


def Grid(
    columns:int=4, wrap_horizontal:bool=True, wrap_vertical:bool=False
)->None:

2D grid navigation (placeholder for future implementation).

# Test Grid navigation
# Grid with 4 columns, 10 items:
# [0, 1, 2, 3]
# [4, 5, 6, 7]
# [8, 9]
grid = Grid(columns=4)
assert grid.name == "grid"
assert grid.get_supported_directions() == ("up", "down", "left", "right")

# Horizontal navigation
assert grid.get_next_index(0, "right", 10) == 1
assert grid.get_next_index(3, "right", 10) == 0  # wraps
assert grid.get_next_index(0, "left", 10) == 3   # wraps

# Vertical navigation
assert grid.get_next_index(1, "down", 10) == 5
assert grid.get_next_index(5, "up", 10) == 1
assert grid.get_next_index(9, "down", 10) == 9   # no vertical wrap by default

Protocol Verification

# Verify all implementations satisfy the protocol
assert isinstance(LinearVertical(), NavigationPattern)
assert isinstance(LinearHorizontal(), NavigationPattern)
assert isinstance(ScrollOnly(), NavigationPattern)
assert isinstance(Grid(), NavigationPattern)