Browser

Main file browser component with virtualized collection rendering.

Main Browser Component

The primary public API for rendering the file browser.


render_file_browser


def render_file_browser(
    items:list, # Current filtered/sorted FileInfo list
    config:FileBrowserConfig, # Browser configuration
    state:BrowserState, # Browser state (path, selection)
    listing:DirectoryListing, # Raw directory listing (for path bar)
    vc_config:VirtualCollectionConfig, # Virtual collection config
    vc_state:VirtualCollectionState, # Virtual collection state
    vc_ids:VirtualCollectionHtmlIds, # Virtual collection HTML IDs
    vc_btn_ids:VirtualCollectionButtonIds, # Virtual collection button IDs
    urls:VirtualCollectionUrls, # Virtual collection URL bundle
    render_cell:Callable, # Cell render callback
    navigate_url:str, # URL for directory navigation
    refresh_url:str, # URL for refresh
    path_input_url:str='', # URL for path input (optional)
    home_path:str='', # Home directory path
    hx_target:Optional=None, # Override HTMX target (default: container_id)
    keyboard_system:Optional=None, # Pre-built keyboard system (when None, builds internally via build_file_browser_keyboard_system)
    manager_label:Optional=None, # Label for the internally-built ZoneManager (ignored when keyboard_system is provided)
)->Any: # Complete file browser component

Render the complete file browser with virtualized collection.

When keyboard_system is provided, the caller has built the system upstream (typically init_router) and owns the underlying ZoneManager. When None, builds the system internally via build_file_browser_keyboard_system using manager_label. The internally-built path preserves pre-L7 behavior for direct render_file_browser callers that don’t need the manager handoff.


build_file_browser_keyboard_system


def build_file_browser_keyboard_system(
    vc_ids:VirtualCollectionHtmlIds, # Virtual collection HTML IDs
    vc_btn_ids:VirtualCollectionButtonIds, # Virtual collection button IDs
    urls:VirtualCollectionUrls, # Virtual collection URL bundle
    manager_label:Optional=None, # Human-readable label for the ZoneManager (used as the modal section header when rendered as a child)
)->KeyboardSystem: # Complete rendered KeyboardSystem (carries .manager for hierarchical hints handoff)

Build the file browser’s KeyboardSystem standalone.

Lifts the manager construction out of render_file_browser so the underlying ZoneManager is accessible via KeyboardSystem.manager — consumers wiring this system as a child in a hierarchy pass that manager to render_keyboard_hints_modal(..., child_managers=[...]) so the modal’s section header reads as manager_label instead of the technical system_id.

The composition (VC nav actions + Backspace→parent-dir extra action + apply_nav_sync on the action buttons) matches what render_file_browser used to build internally pre-L7. Callers who want the default behavior don’t need to call this directly — render_file_browser builds the system internally when its keyboard_system parameter is None.

from fasthtml.common import to_xml, Span
from cjm_file_discovery.core.models import FileInfo
from cjm_fasthtml_virtual_collection.core.models import ColumnDef

# Set up test data
config = FileBrowserConfig()
state = BrowserState(current_path="/home/user")
listing = DirectoryListing(
    path="/home/user",
    items=[
        FileInfo(name="Documents", path="/home/user/Documents", is_directory=True),
        FileInfo(name="file.txt", path="/home/user/file.txt", is_directory=False, size=1024),
    ],
    parent_path="/home"
)

columns = (
    ColumnDef(key="name", header="Name", sortable=True),
    ColumnDef(key="size", header="Size", sortable=True),
)
vc_config = VirtualCollectionConfig(prefix="fb", columns=columns)
vc_state = VirtualCollectionState(total_items=2, visible_rows=1, cursor_index=0)
vc_ids = VirtualCollectionHtmlIds(prefix="fb")
vc_btn_ids = VirtualCollectionButtonIds(prefix="fb")
urls = VirtualCollectionUrls()

def test_render_cell(item, ctx):
    return Span(item.name)

browser = render_file_browser(
    items=listing.items, config=config, state=state, listing=listing,
    vc_config=vc_config, vc_state=vc_state, vc_ids=vc_ids, vc_btn_ids=vc_btn_ids,
    urls=urls, render_cell=test_render_cell,
    navigate_url="/nav", refresh_url="/ref",
)
html = to_xml(browser)

# Container
assert 'id="file-browser"' in html
# Path bar
assert "path-bar" in html
# Virtual collection elements
assert 'id="fb-collection"' in html
assert 'id="fb-wrapper"' in html
assert 'id="fb-table"' in html
# Keyboard system
assert "keyboard" in html.lower() or "hidden" in html.lower()
# Viewport fit JS
assert "ViewportFit" in html or "viewport" in html.lower()

print("Browser integration tests passed!")
Browser integration tests passed!