description: "Sidebar shell plugin for the dsh web client: brand row, New Session action, collapse control, scroll-aware region seat, and bottom-pinned Settings seat."
English | 中文
The dsh web client sidebar lets users recognize the active build, start a new session, collapse navigation to a 56px rail, browse Workspaces and Sessions, and open Settings. It preserves a bottom-pinned Settings entry and hides idle scrollbars without moving browser rows. New Session uses an explicitly selected Workspace, then the current Session's Workspace, then the most recently active Workspace; if none exists, it opens a blank New Session page. Deployments can replace the brand mark or name while retaining the navigation controls and rail geometry.
The sidebar is the navigation shell: users see the brand, start new sessions, collapse the rail, and reach Settings. Feature plugins fill its seats — ui-workspace fills sidebar.workspaces, ui-settings registers the trigger row and settings panel at sidebar.settings.
The expanded brand row renders sidebar.brand.mark and sidebar.brand.name as independent single slots; the collapsed rail renders the same mark slot. Without occupants, the shell uses the fish mark and a localized local-build label. A complete build stacks a code badge below the label as version[-commit][-dirty], using DSH_CLIENT_VERSION, the optional 7-character DSH_CLIENT_COMMIT_HASH, and DSH_CLIENT_GIT_DIRTY=true; missing version metadata omits the badge. New Session targets the explicit Workspace used by a scoped action, otherwise the current Session's Workspace, otherwise the most recently active Workspace; when none exists it clears into the blank New Session page.
Plugins add an icon component to the root-scoped sidebar.panellist list with an id, optional order, and a string or locale-aware label. The same id addresses the component registered in the layout's root-scoped main keyed slot; selecting a missing main entry throws without changing the current selection. The label supplies plain visible text, the accessible name, and the collapsed tooltip. Each row reads its own selected state through usePanelInfo; moving DOM focus to search or a directory picker does not change the displayed panel or its selected row. With no registrations, neither the list nor spacing for it is rendered. The shipped composition registers no example panel.
During a live collapse, the expanded content fades out at its current width, the upper controls share one fade and leftward translation into the 56px rail, and the layout's column slide ends the motion. A page that starts collapsed renders the rail statically, and reduced-motion mode disables both transitions. The bottom-pinned sidebar.settings control shares the fade timing but has no horizontal translation.
Scrollbars in the column are a pointer affordance: the shell rebinds the scrollbar indirection to transparent whenever the pointer is outside the column and keeps the thumb drawn for 2s after the pointer leaves, so a list nobody is pointing at carries no bar. The reservation that keeps rows from moving belongs to the scrolling region (ui-workspace), so revealing a thumb never reflows.
These pages cover the surfaces that fill the shell's seats and the composition model.
sidebar.workspaces.sidebar.settings.None, as the package is a browser-side UI plugin layer that registers nothing model-facing.
None; this package neither assembles nor sends a provider request.
These limits define what the shell owns versus what its occupants own; they are current package constraints.
Runtime invariant: No companion is published. Panel metadata is a read-only presentation projection of the Slot registry and locale, with no independent write API. The registry owns entry identity and disposal; this package's assembly tests assert the projection after registration and locale notifications settle. The shell owns no separate navigation state to reconcile with those sources.