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 activetoggle = render_view_toggle(ViewMode.GRID, "/toggle-view", "#gallery")html = to_xml(toggle)assert"join"in htmlassert"btn-primary"in html # Active buttonassert"btn-ghost"in html # Inactive buttonassert"hx-post"in html # HTMX on inactive# Test view toggle - list mode activetoggle = render_view_toggle(ViewMode.LIST, "/toggle-view", "#gallery")html = to_xml(toggle)# Both buttons should be presentassert"Grid view"in html or"grid_view"in html.lower() or"<svg"in htmlprint("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 buttonbtn_elem = render_type_filter_button( FileType.AUDIO, True, "/filter", "#gallery")html = to_xml(btn_elem)assert"<button"in htmlassert"btn-primary"in html # Activeassert"Audio"in htmlassert"hx-post"in html# Test inactive buttonbtn_elem = render_type_filter_button( FileType.VIDEO, False, "/filter", "#gallery")html = to_xml(btn_elem)assert"btn-ghost"in html # Inactiveassert"Video"in html# Test with countbtn_elem = render_type_filter_button( FileType.IMAGE, True, "/filter", "#gallery", count=42)html = to_xml(btn_elem)assert"42"in htmlassert"badge"in htmlprint("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 filtersfilters = 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 htmlassert"Video"in htmlassert"Images"in html# Should have 2 active and 1 inactiveassert html.count("btn-primary") ==2assert html.count("btn-ghost") ==1# Test with countsfilters = 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 htmlassert"5"in htmlprint("render_type_filters tests passed!")
render_type_filters tests passed!
Gallery Controls Bar
Combined controls bar with view toggle and type filters.
render_gallery_controls
def render_gallery_controls( config:GalleryConfig, # Gallery configuration current_view:ViewMode, # Current view mode active_types:List, # Currently active type filters toggle_view_url:str, # URL for view toggle filter_url:str, # URL for type filter hx_target:Optional=None, # HTMX target type_counts:Optional=None, # File counts per type controls_id:Optional=None, # HTML ID for controls container)->Any: # Controls bar component
Render the gallery controls bar.
# Test gallery controlsconfig = GalleryConfig()controls = render_gallery_controls( config=config, current_view=ViewMode.GRID, active_types=[FileType.AUDIO, FileType.VIDEO, FileType.IMAGE, FileType.DOCUMENT], toggle_view_url="/toggle-view", filter_url="/filter", hx_target="#gallery", controls_id="gallery-controls")html = to_xml(controls)assert'id="gallery-controls"'in htmlassert'class="join"'in html # View toggle button groupassert"Audio"in html # Type filtersassert"Video"in html# Test with view toggle disabledconfig_no_toggle = GalleryConfig(allow_view_toggle=False)controls = render_gallery_controls( config=config_no_toggle, current_view=ViewMode.GRID, active_types=[FileType.AUDIO], toggle_view_url="/toggle-view", filter_url="/filter")html = to_xml(controls)assert'class="join"'notin html # No view toggle button groupassert"Audio"in html # Type filters still presentprint("render_gallery_controls tests passed!")