JS: Scroll Navigation

JavaScript generator for scroll-to-nav conversion.

generate_scroll_nav_js

Converts mouse wheel events on the card stack container into navigation button clicks. Uses delta accumulation with a cooldown to handle both trackpads and scroll wheels naturally. Supports mode-based disabling.


source

generate_scroll_nav_js


def generate_scroll_nav_js(
    ids:CardStackHtmlIds, # HTML IDs for this card stack instance
    button_ids:CardStackButtonIds, # Button IDs for navigation triggers
    disable_in_modes:Tuple=(), # Mode names where scroll nav is suppressed
    zone_id:str='', # Keyboard zone ID to activate on scroll interaction
)->str: # JavaScript code fragment for scroll navigation

Generate JS for scroll wheel to navigation conversion.

# Test scroll nav JS generation
ids = CardStackHtmlIds(prefix="cs0")
btn = CardStackButtonIds(prefix="cs0")
js = generate_scroll_nav_js(ids, btn)
assert ids.card_stack in js
assert btn.nav_up in js
assert btn.nav_down in js
assert "isScrollDisabled" not in js  # No mode check when no modes
assert "ns._setupScrollNav" in js

# Uses event timeStamp for cooldown, not Date.now()
assert "evt.timeStamp" in js
# assert "Date.now()" not in js

# deltaMode normalization
assert "deltaMode" in js
assert "DOM_DELTA_LINE" in js
assert "DOM_DELTA_PAGE" in js

# Trackpad vs mouse wheel detection with separate cooldowns
assert "_TRACKPAD_COOLDOWN" in js
assert "_TRACKPAD_DETECT" in js
assert "_NAV_COOLDOWN" in js

# Discards same-batch events, keeps trackpad events during cooldown
assert "Same-batch" in js

# Uses AbortController for clean listener teardown/re-setup
assert "AbortController" in js
assert "_scrollNavAbort" in js
assert "signal" in js

# No zone activation when zone_id not provided
assert "setActiveZone" not in js

# Zone activation when zone_id provided
js_zone = generate_scroll_nav_js(ids, btn, zone_id="my-card-stack")
assert "setActiveZone('my-card-stack')" in js_zone

print("Scroll nav JS basic tests passed!")
# Test with disabled modes
js_modes = generate_scroll_nav_js(ids, btn, disable_in_modes=("split", "edit"))
assert "isScrollDisabled" in js_modes
assert "'split'" in js_modes
assert "'edit'" in js_modes
print("Scroll nav JS mode disabling tests passed!")
Scroll nav JS mode disabling tests passed!