PrivatecontainerPrivatepanelPrivatescrimPrivatenavigatorPrivateonPrivate OptionalonPrivate OptionalcurrentPrivate ReadonlyoriginOrigin used for relative path resolution; captured at construction.
PrivatenavigationNavigation 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.
PrivatecurrentEntries for the current directory (unfiltered), cached so the search bar can re-filter without re-fetching.
PrivatecurrentDetection strategy label for the current directory, shown in the status bar.
PrivatefilterLive filter text from the search bar; matched case-insensitively against entry names.
PrivatecurrentPath of the current (last successfully rendered) directory — seeds the inline path editor.
PrivatelastPath of the most recent navigate() attempt — target for the error-state Retry button.
Private OptionaluntrapTeardown for the modal focus trap (Tab must not escape behind the scrim).
Private OptionaluntypeTeardown for the container-focus + type-to-filter forwarder.
PrivateinstallPark 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.
PrivateextractExtract base URL from a full URL.
PrivateextractExtract relative path from a full URL. Thin wrapper around the shared extractPath helper.
PrivatecreateCreate 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().
PrivatecreateCreate the browser panel UI.
PrivatenavigateNavigate 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.
PrivatenavigatePrivateupdateUpdate breadcrumb navigation. Rebuilds the crumb trail and the "enter path manually" toggle (which swaps the row for an inline editor).
PrivateparkKeep modal keyboard handling active after a focused child is replaced.
PrivateopenSwap 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.
PrivatecommitCommit 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.
PrivateresetClear the search bar and filter state (called on every navigation so a filter from the previous directory doesn't carry over).
PrivatesetShow 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.
PrivaterenderRender 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.
PrivateshowShow manual entry form for servers that don't support listing.
Show the browser panel.
Hide the browser panel.
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.
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
onDatasetSelectwith the full dataset URL when a.zarris 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
manualdetection strategy.Initial focus goes to the panel container rather than the search field, so the
Oshortcut still toggles the browser shut (a focused text field tripsInputHandler's typing guard — issue #1922); the first printable keystroke is forwarded into the search field so typing still filters immediately.