Review-specific keyboard building blocks for assembly into a KeyboardManager
Keyboard Parts Builder
Returns (zone, actions, modes) tuple for assembly into a KeyboardManager. Review uses simple navigation only (no sub-modes like segmentation’s split mode).
Creates a complete ZoneManager for the review step (single-zone, no zone switching).
create_review_keyboard_manager
def create_review_keyboard_manager( ids:CardStackHtmlIds, # Card stack HTML IDs button_ids:CardStackButtonIds, # Card stack button IDs for navigation config:CardStackConfig, # Card stack configuration)->ZoneManager: # Configured keyboard zone manager
Create the keyboard zone manager for the review step.
# Speed cycle KeyActions wire correctly into the review zonefrom cjm_fasthtml_card_stack.core.html_ids import CardStackHtmlIds as _IDsfrom cjm_fasthtml_card_stack.core.button_ids import CardStackButtonIds as _BtnIdsfrom cjm_fasthtml_card_stack.core.config import CardStackConfig as _Cfg_zone, _actions, _modes = create_review_kb_parts( ids=_IDs(prefix="review-cs"), button_ids=_BtnIds(prefix="review-cs"), config=_Cfg(),)_by_key = {(a.key, frozenset(a.modifiers)): a for a in _actions}_up = _by_key.get(("ArrowUp", frozenset({"shift"})))_dn = _by_key.get(("ArrowDown", frozenset({"shift"})))assert _up isnotNone, "Shift+ArrowUp binding missing"assert _dn isnotNone, "Shift+ArrowDown binding missing"# Scoped to the review card-stack zone, wired to web-audio's cycle helpers,# grouped with the other audio bindings in the hint panelassert _up.js_callback =="cycleReviewSpeedUp"assert _dn.js_callback =="cycleReviewSpeedDown"assert _up.zone_ids == (_zone.id,)assert _dn.zone_ids == (_zone.id,)assert _up.hint_group =="Audio"assert _dn.hint_group =="Audio"# Plain ArrowUp/ArrowDown (card-stack nav) must NOT collide — distinct modifiers frozenset_nav_up = _by_key.get(("ArrowUp", frozenset()))_nav_dn = _by_key.get(("ArrowDown", frozenset()))assert _nav_up isnotNoneand _nav_up.htmx_trigger, "Plain ArrowUp should still be the card-stack nav binding"assert _nav_dn isnotNoneand _nav_dn.htmx_trigger, "Plain ArrowDown should still be the card-stack nav binding"print("Shift+Arrow speed cycle bindings test passed")