# Test CardStackState defaults
state = CardStackState()
assert state.focused_index == 0
assert state.visible_count == 1
assert state.card_width == 80
assert state.card_scale == 100
assert state.active_mode is None
assert state.focus_position is None
assert state.is_auto_mode is True
print("CardStackState default tests passed!")Models
Core dataclasses for card stack state, render context, and URL routing.
CardStackState
Runtime-changeable state that the consumer persists. All fields use simple types for trivial JSON/SQLite serialization.
CardStackState
def CardStackState(
focused_index:int=0, visible_count:int=1, card_width:int=80, card_scale:int=100, active_mode:Optional=None,
focus_position:Optional=None, is_auto_mode:bool=True
)->None:
Viewport state for a card stack instance.
# Test CardStackState with custom values
state = CardStackState(
focused_index=5,
visible_count=7,
card_width=60,
card_scale=150,
active_mode="split",
focus_position=-1,
)
assert state.focused_index == 5
assert state.visible_count == 7
assert state.card_width == 60
assert state.card_scale == 150
assert state.active_mode == "split"
assert state.focus_position == -1
print("CardStackState custom value tests passed!")CardStackState custom value tests passed!
# Test CardStackState mutability (in-place mutation pattern)
state = CardStackState()
state.focused_index = 10
state.active_mode = "edit"
assert state.focused_index == 10
assert state.active_mode == "edit"
print("CardStackState mutation tests passed!")CardStackState mutation tests passed!
CardRenderContext
Passed to the consumer’s render_card(item, context) callback. Provides all positional and state information the consumer needs to render a card.
CardRenderContext
def CardRenderContext(
card_role:str, index:int, total_items:int, is_first:bool, is_last:bool, active_mode:Optional, card_scale:int,
distance_from_focus:int
)->None:
Context passed to the consumer’s render_card callback.
# Test CardRenderContext for focused card
ctx = CardRenderContext(
card_role="focused",
index=5,
total_items=20,
is_first=False,
is_last=False,
active_mode=None,
card_scale=100,
distance_from_focus=0,
)
assert ctx.card_role == "focused"
assert ctx.distance_from_focus == 0
assert not ctx.is_first
assert not ctx.is_last
print("CardRenderContext focused card tests passed!")CardRenderContext focused card tests passed!
# Test CardRenderContext for context cards at various distances
ctx_before = CardRenderContext(
card_role="context",
index=3,
total_items=20,
is_first=False,
is_last=False,
active_mode="split",
card_scale=75,
distance_from_focus=-2,
)
assert ctx_before.card_role == "context"
assert ctx_before.distance_from_focus == -2
assert ctx_before.active_mode == "split"
assert ctx_before.card_scale == 75
ctx_after = CardRenderContext(
card_role="context",
index=7,
total_items=20,
is_first=False,
is_last=False,
active_mode=None,
card_scale=100,
distance_from_focus=2,
)
assert ctx_after.distance_from_focus == 2
print("CardRenderContext distance tests passed!")CardRenderContext distance tests passed!
# Test CardRenderContext edge items
ctx_first = CardRenderContext(
card_role="focused",
index=0,
total_items=10,
is_first=True,
is_last=False,
active_mode=None,
card_scale=100,
distance_from_focus=0,
)
assert ctx_first.is_first
assert not ctx_first.is_last
assert ctx_first.index == 0
ctx_last = CardRenderContext(
card_role="focused",
index=9,
total_items=10,
is_first=False,
is_last=True,
active_mode=None,
card_scale=100,
distance_from_focus=0,
)
assert not ctx_last.is_first
assert ctx_last.is_last
assert ctx_last.index == 9
print("CardRenderContext edge item tests passed!")CardRenderContext edge item tests passed!
CardStackUrls
URL bundle for routing. Built from route .to() calls inside the convenience router, or constructed manually by the consumer.
CardStackUrls
def CardStackUrls(
nav_up:str='', nav_down:str='', nav_first:str='', nav_last:str='', nav_page_up:str='', nav_page_down:str='',
nav_to_index:str='', update_viewport:str='', save_width:str='', save_scale:str=''
)->None:
URL bundle for card stack navigation and viewport operations.
# Test CardStackUrls defaults
urls = CardStackUrls()
assert urls.nav_up == ""
assert urls.save_scale == ""
# Test with actual URL values
urls = CardStackUrls(
nav_up="/card-stack/nav_up",
nav_down="/card-stack/nav_down",
nav_first="/card-stack/nav_first",
nav_last="/card-stack/nav_last",
nav_page_up="/card-stack/nav_page_up",
nav_page_down="/card-stack/nav_page_down",
nav_to_index="/card-stack/nav_to_index",
update_viewport="/card-stack/update_viewport",
save_width="/card-stack/save_width",
save_scale="/card-stack/save_scale",
)
assert urls.nav_up == "/card-stack/nav_up"
assert urls.nav_to_index == "/card-stack/nav_to_index"
assert urls.save_scale == "/card-stack/save_scale"
print("CardStackUrls tests passed!")CardStackUrls tests passed!