Luxar Viewer API Documentation - v2026.9.22
    Preparing search index...

    Class DatasetBrowser

    Interactive panel for browsing a server's directory tree and selecting a Zarr dataset to load. Wraps a DirectoryNavigator for the async listing, renders directory entries, and fires onDatasetSelect with the full dataset URL when a .zarr is chosen. Navigation uses a generation token so stale async responses from abandoned directories are discarded rather than rendered.

    A dimming scrim is mounted behind the panel (click-to-close), the listing is arrow-key navigable, and the breadcrumb row hosts an inline "enter path manually" editor so a path/URL can always be typed — not only when the server falls back to the manual detection strategy.

    Initial focus goes to the panel container rather than the search field, so the O shortcut still toggles the browser shut (a focused text field trips InputHandler's typing guard — issue #1922); the first printable keystroke is forwarded into the search field so typing still filters immediately.

    Index
    container: HTMLElement
    panel: HTMLElement
    scrim: HTMLElement
    onDatasetSelect: (fullUrl: string) => false | void | Promise<void>
    onClose?: () => void
    currentDataset?: string
    origin: string

    Origin used for relative path resolution; captured at construction.

    navigationGeneration: number = 0

    Navigation generation token. Incremented on every navigate() call; the navigation discards its result if the generation has moved by the time the async navigator fetch resolves. Without this, fast user picks (or simply a slow first response while the user clicks something else) could let the stale result render entries — or worse, fire onDatasetSelect for a directory the user already left when the stale response arrives at a .zarr path.

    currentEntries: DirectoryEntry[] = []

    Entries for the current directory (unfiltered), cached so the search bar can re-filter without re-fetching.

    currentStrategy: string = ''

    Detection strategy label for the current directory, shown in the status bar.

    filterText: string = ''

    Live filter text from the search bar; matched case-insensitively against entry names.

    currentPath: string = ''

    Path of the current (last successfully rendered) directory — seeds the inline path editor.

    lastAttemptedPath: string = ''

    Path of the most recent navigate() attempt — target for the error-state Retry button.

    untrapFocus?: () => void

    Teardown for the modal focus trap (Tab must not escape behind the scrim).

    untypeToFilter?: () => void

    Teardown for the container-focus + type-to-filter forwarder.

    • Park focus on the panel container and forward the first printable keystroke into the search field.

      The browser used to autofocus the search field on the first successful listing, which trips InputHandler's typing guard and made O one-way — it opened the browser but the second O was swallowed as typing (issue #1922). Focus now stays on the (non-typing) panel container, so O toggles, while typing still filters from the very first key. O itself is passed through to the global binding, so it cannot be the FIRST character of a filter query (it types normally once the field has focus).

      The resolver only ever names the SEARCH field, and only while the search bar is actually shown: it returns null while that bar is hidden (loading, error, empty directory, manual-entry fallback), and the keystroke is then contained by the modal. The manual-entry #luxar-dataset-browser-manual-path field is deliberately NOT a resolver target — it is a URL entry field, not a filter, so stray keystrokes should not be routed into it. The user clicks or Tabs into that field, which is a deliberate act, and from there the ordinary typing guard applies exactly as it does for every other text field in the app.

      passthroughKeys lists every shortcut this panel advertises while it is open: O (its own toggle) and H (the H Help chip in the welcome banner). Containment would otherwise make that chip a lie.

      resolveFirstItem restores the "ArrowDown enters the listing" affordance the search field's own handler provides: with focus parked on the container, that handler never sees the key.

      Returns () => void

    • Extract base URL from a full URL.

      Parameters

      • url: string

      Returns string

    • Extract relative path from a full URL. Thin wrapper around the shared extractPath helper.

      Parameters

      • url: string

      Returns string

    • Create the dimming scrim mounted behind the panel. Clicking it closes the browser (standard modal affordance); it fades in with the panel and is removed together with it in close().

      Returns HTMLElement

    • Navigate to a path and update the UI.

      Cancellable: each call bumps navigationGeneration. If the user kicks off a newer navigate while an older one's navigator.navigate() is still in flight, the older call discards its result on resume instead of overwriting the UI or (worst case) firing onDatasetSelect for a path the user already left.

      Parameters

      • path: string

      Returns Promise<void>

    • Update breadcrumb navigation. Rebuilds the crumb trail and the "enter path manually" toggle (which swaps the row for an inline editor).

      Parameters

      • currentPath: string

      Returns void

    • Keep modal keyboard handling active after a focused child is replaced.

      Returns void

    • Swap the breadcrumb row for an inline path editor (mono input seeded with the current path). Enter commits — a value containing .zarr (or a full URL) is selected as a dataset, anything else is navigated to; Escape or blur restores the crumb trail.

      Returns void

    • Commit the inline path editor's value (see openPathEditor).

      Full URLs are selected as-is (parity with the manual-entry form). A relative path is selected only when it deliberately names a .zarr directory — i.e. its last path segment ends with .zarr (trailing slashes ignored), OR deliberately names a zipped store (foo.zarr.zip, read in place over range requests). A mere .zarr SUBSTRING (archives.zarr-backup) is not a dataset; those navigate instead, and navigate() still auto-selects if the server reports a real zarr.

      Parameters

      • raw: string

      Returns void

    • Clear the search bar and filter state (called on every navigation so a filter from the previous directory doesn't carry over).

      Returns void

    • Show or hide the search/filter bar. Hidden in states where filtering is meaningless (loading, error, empty directory, manual-entry fallback) so it only appears when there's an actual listing to narrow.

      Parameters

      • visible: boolean

      Returns void

    • Render the current directory's entries, applying the live search filter, and refresh the status bar (visible / total counts + detection strategy). Re-run on navigation and on every keystroke in the search bar.

      Returns void

    • Close and dispose the browser. Idempotent: a second call is a no-op, so app teardown can call close() defensively without checking whether the user already dismissed the browser.

      Returns void