Controls

Gallery control components for view toggle and type filtering.

View Mode Toggle

Buttons to switch between grid and list view.


render_view_toggle


def render_view_toggle(
    current_mode:ViewMode, # Current view mode
    toggle_url:str, # URL for toggle handler
    hx_target:Optional=None, # HTMX target for swap
)->Any: # View toggle button group

Render view mode toggle buttons.

from fasthtml.common import to_xml

# Test view toggle - grid mode active
toggle = render_view_toggle(ViewMode.GRID, "/toggle-view", "#gallery")
html = to_xml(toggle)
assert "join" in html
assert "btn-primary" in html  # Active button
assert "btn-ghost" in html    # Inactive button
assert "hx-post" in html      # HTMX on inactive

# Test view toggle - list mode active
toggle = render_view_toggle(ViewMode.LIST, "/toggle-view", "#gallery")
html = to_xml(toggle)
# Both buttons should be present
assert "Grid view" in html or "grid_view" in html.lower() or "<svg" in html

print("render_view_toggle tests passed!")
render_view_toggle tests passed!

Type Filter Buttons

Filter buttons to show/hide specific file types.


render_type_filter_button


def render_type_filter_button(
    file_type:FileType, # File type for this button
    is_active:bool, # Whether this type is currently shown
    filter_url:str, # URL for filter handler
    hx_target:Optional=None, # HTMX target for swap
    count:Optional=None, # Number of files of this type
)->functools.partial(<function ft_hx at 0x7f5282f831a0>, 'button'): # Filter button

Render a single type filter button.

# Test type filter button
btn_elem = render_type_filter_button(
    FileType.AUDIO, True, "/filter", "#gallery"
)
html = to_xml(btn_elem)
assert "<button" in html
assert "btn-primary" in html  # Active
assert "Audio" in html
assert "hx-post" in html

# Test inactive button
btn_elem = render_type_filter_button(
    FileType.VIDEO, False, "/filter", "#gallery"
)
html = to_xml(btn_elem)
assert "btn-ghost" in html  # Inactive
assert "Video" in html

# Test with count
btn_elem = render_type_filter_button(
    FileType.IMAGE, True, "/filter", "#gallery", count=42
)
html = to_xml(btn_elem)
assert "42" in html
assert "badge" in html

print("render_type_filter_button tests passed!")
render_type_filter_button tests passed!

render_type_filters


def render_type_filters(
    available_types:List, # File types to show buttons for
    active_types:List, # Currently active (shown) types
    filter_url:str, # URL for filter handler
    hx_target:Optional=None, # HTMX target for swap
    type_counts:Optional=None, # File counts per type
)->Any: # Type filter button group

Render type filter buttons.

# Test type filters
filters = render_type_filters(
    available_types=[FileType.AUDIO, FileType.VIDEO, FileType.IMAGE],
    active_types=[FileType.AUDIO, FileType.IMAGE],
    filter_url="/filter",
    hx_target="#gallery"
)
html = to_xml(filters)
assert "Audio" in html
assert "Video" in html
assert "Images" in html
# Should have 2 active and 1 inactive
assert html.count("btn-primary") == 2
assert html.count("btn-ghost") == 1

# Test with counts
filters = render_type_filters(
    available_types=[FileType.AUDIO, FileType.VIDEO],
    active_types=[FileType.AUDIO],
    filter_url="/filter",
    type_counts={FileType.AUDIO: 10, FileType.VIDEO: 5}
)
html = to_xml(filters)
assert "10" in html
assert "5" in html

print("render_type_filters tests passed!")
render_type_filters tests passed!