feat(web): topbar cleanup — centered 2x search, icon-only Share, History/Download into the ⋯ menu

- search control sits centered in the topbar at ~2x width, kbd right-aligned
  (static again on mobile)
- Share is icon-only
- History button shows only on the project home: gone from dashboard/history
  (and other view routes) and whenever a file/folder is selected — the ⋯
  menu and sidebar carry it
- Download is ⋯-menu-only; a hidden anchor keeps the browser download flow
46/46 e2e.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VbiaaVM2ACxeRi8ySG9ybc
This commit is contained in:
Snow Lee
2026-07-19 11:16:50 -07:00
co-authored by Claude Fable 5
parent 317045cecb
commit 75f2b0bfe9
7 changed files with 26 additions and 16 deletions
+3 -1
View File
@@ -19,7 +19,9 @@ test("markdown file: rendered content, crumb, meta, download + share buttons", a
await expect(page.locator("#content h1")).toHaveText("Wiki");
await expect(page.locator("#crumb")).toContainText("index.md");
await expect(page.locator("#meta")).toContainText("alice@x.io");
await expect(page.locator("#download")).toBeVisible();
// Download lives in the ⋯ menu now; the hidden anchor powers it.
await expect(page.locator("#download")).toHaveCount(1);
await expect(page.locator("#more-btn")).toBeVisible();
await expect(page.locator("#share-btn")).toBeVisible();
});
@@ -352,18 +352,18 @@ export default function Browser(props: {
<Icon name="search" /> <span className="lbl">Search</span> <kbd>K</kbd>
</button>
{canShare && (
<button id="share-btn" className="btn" onClick={shareNow}>
<Icon name="share" /> <span className="lbl">Share</span>
<button id="share-btn" className="btn icon-only" title="Share" aria-label="Share" onClick={shareNow}>
<Icon name="share" />
</button>
)}
{canHistory && (
{canHistory && !path && !route.view && (
<button id="history-btn" className="btn" onClick={historyNow}>
<Icon name="hist" /> <span className="lbl">History</span>
</button>
)}
{canDownload && (
<a id="download" className="btn" download href={downloadURL} ref={downloadRef}>
<Icon name="download" /> <span className="lbl">Download</span>
<a id="download" hidden download href={downloadURL} ref={downloadRef}>
Download
</a>
)}
{canMore && (
+8
View File
@@ -217,6 +217,13 @@ button, input, a.btn { font-family: inherit; }
.btn:hover { background: var(--hover); color: var(--text); border-color: var(--border-2); }
.btn .ico { width: 15px; height: 15px; }
.btn.ghost { color: var(--text-dim); }
/* The search control sits dead-center in the topbar, twice its natural
width, reading as an input field. */
#search-btn {
position: absolute; left: 50%; transform: translateX(-50%);
width: 260px; justify-content: flex-start;
}
#search-btn kbd { margin-left: auto; }
#search-btn kbd {
font: 11px var(--ui); color: var(--text-faint);
background: var(--hover); border: 1px solid var(--border-2); border-radius: 5px;
@@ -456,6 +463,7 @@ button, input, a.btn { font-family: inherit; }
.icon-btn { display: inline-flex; width: 44px; height: 44px; }
#content { padding: 24px 18px 70px; }
#topbar { padding: 0 8px; gap: 4px; }
#search-btn { position: static; transform: none; width: auto; justify-content: center; }
#search-btn kbd, .btn .lbl { display: none; }
#topbar .btn { min-width: 44px; min-height: 44px; padding: 0; justify-content: center; gap: 0; }
#topbar .btn .ico { width: 18px; height: 18px; }
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+2 -2
View File
@@ -5,8 +5,8 @@
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>BearDrive</title>
<link rel="icon" href="data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'><text y='.9em' font-size='90'>&#128059;</text></svg>">
<script type="module" crossorigin src="/assets/index-T_RFOOBs.js"></script>
<link rel="stylesheet" crossorigin href="/assets/index-C5jjBsTc.css">
<script type="module" crossorigin src="/assets/index-XRsupwXA.js"></script>
<link rel="stylesheet" crossorigin href="/assets/index-CCQsgUR1.css">
</head>
<body>
<div id="root"></div>