From c93f2aa12cd0790dbf0985609b0a12db4663d5a7 Mon Sep 17 00:00:00 2001 From: xarmian Date: Wed, 17 Jun 2026 21:56:25 -0400 Subject: [PATCH] feat(web): unified mobile top bar with always-on workspace switcher (IDEA-1835) (#737) Promote MobileContextBar from a detail-only back+title bar to the persistent mobile top bar shown on every screen inside a workspace. The collection/item name now reads the same everywhere and the workspace switcher (moved out of the bottom-nav sheet) is always visible for at-a-glance context and quick switching. - MobileContextBar: show on all workspace screens (was depth >= 2); gate the back affordance to non-root screens; embed WorkspaceSwitcher on the right, restyled onto --bg-tertiary and sized to fill the 44px bar. - WorkspaceSheet: drop the switcher card + inline list (now in the top bar); the "Workspace" bottom-nav slot keeps its label/avatar and Navigate + Collections. - Collection list: hide the now-duplicate in-page collection-name heading on mobile; the name lives in the bar. --- .../components/layout/MobileContextBar.svelte | 94 ++++++--- .../components/layout/WorkspaceSheet.svelte | 194 +----------------- .../[workspace]/[collection]/+page.svelte | 7 + 3 files changed, 78 insertions(+), 217 deletions(-) diff --git a/web/src/lib/components/layout/MobileContextBar.svelte b/web/src/lib/components/layout/MobileContextBar.svelte index 4f171159..f4a57114 100644 --- a/web/src/lib/components/layout/MobileContextBar.svelte +++ b/web/src/lib/components/layout/MobileContextBar.svelte @@ -1,13 +1,18 @@
- - - - {#if switching} -
- {#each workspaceStore.workspaces as ws (ws.slug)} - - {/each} - -
- {/if} -
Navigate
@@ -171,125 +110,6 @@ padding: 0 var(--space-4); } - /* Workspace switcher card */ - .ws-card { - display: flex; - align-items: center; - gap: var(--space-3); - width: 100%; - padding: var(--space-3); - background: var(--bg-primary); - border: 1px solid var(--border); - border-radius: var(--radius-lg); - cursor: pointer; - text-align: left; - } - .ws-avatar { - flex-shrink: 0; - width: 40px; - height: 40px; - border-radius: var(--radius-md, 6px); - display: flex; - align-items: center; - justify-content: center; - color: #fff; - font-weight: 700; - font-size: 1.1em; - } - .ws-meta { - display: flex; - flex-direction: column; - gap: 1px; - min-width: 0; - flex: 1; - } - .ws-name { - font-weight: 600; - color: var(--text-primary); - font-size: 1em; - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; - } - .ws-role { - font-size: 0.75em; - color: var(--text-muted); - text-transform: capitalize; - } - .ws-switch { - flex-shrink: 0; - display: flex; - align-items: center; - gap: 2px; - font-size: 0.8em; - color: var(--text-secondary); - } - .ws-chev { - display: inline-block; - transition: transform 0.15s ease; - } - .ws-chev.up { - transform: rotate(180deg); - } - - .ws-list { - display: flex; - flex-direction: column; - margin-top: var(--space-2); - border: 1px solid var(--border); - border-radius: var(--radius-md, 6px); - overflow: hidden; - } - .ws-row { - display: flex; - align-items: center; - gap: var(--space-3); - padding: var(--space-2) var(--space-3); - background: none; - border: none; - cursor: pointer; - text-align: left; - color: var(--text-secondary); - } - .ws-row:hover { - background: var(--bg-hover); - } - .ws-row.active { - color: var(--text-primary); - } - .ws-row-avatar { - flex-shrink: 0; - width: 26px; - height: 26px; - border-radius: var(--radius-sm); - display: flex; - align-items: center; - justify-content: center; - color: #fff; - font-weight: 700; - font-size: 0.8em; - } - .ws-row-avatar.plus { - background: transparent; - border: 1px dashed var(--border); - color: var(--text-muted); - } - .ws-row-name { - flex: 1; - min-width: 0; - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; - font-size: 0.95em; - } - .ws-row-check { - color: var(--accent-blue); - font-size: 0.9em; - } - .ws-new .ws-row-name { - color: var(--text-muted); - } - .ws-label { padding: var(--space-4) var(--space-1) var(--space-2); font-size: 0.7em; diff --git a/web/src/routes/[username]/[workspace]/[collection]/+page.svelte b/web/src/routes/[username]/[workspace]/[collection]/+page.svelte index 5e4a64f8..8a873f66 100644 --- a/web/src/routes/[username]/[workspace]/[collection]/+page.svelte +++ b/web/src/routes/[username]/[workspace]/[collection]/+page.svelte @@ -2768,6 +2768,13 @@ } @media (max-width: 768px) { + /* The collection name now lives in the persistent top bar + (MobileContextBar, IDEA-1835) — drop the duplicate in-page heading + but keep the view controls in the row. */ + .title-row h1 { + display: none; + } + .title-row { flex-direction: column; align-items: flex-start;