refactor(ui): fold the 36px header/search buttons into IconButton

Completes the IconButton extraction by adding `size` and `radius` props and
converting the two remaining outliers that were left out of the first pass:
the desktop header logout button (+layout) and the home search submit button
(+page), both 36px with the medium radius.

IconButton now drives every icon button in the app (except profile/history's,
which the shared-HistoryList change removes separately). Defaults stay 32px /
small radius, so the four already-converted sites are untouched. Rendered
size, radius, and variant match the old markup — no behaviour change, no
version bump.

This also sets up applying the --tap-min touch floor in one place once the
touch-target change lands.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
MechaCat02
2026-06-25 19:46:54 +02:00
parent 129cb0241d
commit 79a1432db8
4 changed files with 62 additions and 54 deletions

View File

@@ -9,6 +9,7 @@
import { theme } from '$lib/theme.svelte';
import AppBar from '$lib/components/AppBar.svelte';
import BottomNav, { type BottomNavTab } from '$lib/components/BottomNav.svelte';
import IconButton from '$lib/components/IconButton.svelte';
import Upload from '@lucide/svelte/icons/upload';
import UserCircle from '@lucide/svelte/icons/user-circle';
import Bookmark from '@lucide/svelte/icons/bookmark';
@@ -232,9 +233,9 @@
<span data-testid="session-loading" aria-busy="true"></span>
{:else if session.user}
<span class="username" data-testid="session-user">{session.user.username}</span>
<button
class="icon-btn"
type="button"
<IconButton
size={36}
radius="md"
onclick={handleLogout}
disabled={loggingOut}
aria-label="Logout"
@@ -245,7 +246,7 @@
{:else}
<LogOut size={18} aria-hidden="true" />
{/if}
</button>
</IconButton>
{:else}
<a class="text-link" href="/login" data-testid="nav-login">Login</a>
{#if authConfig.self_register_enabled}
@@ -348,24 +349,6 @@
padding: 0 var(--space-2);
}
.icon-btn {
display: inline-flex;
align-items: center;
justify-content: center;
width: 36px;
height: 36px;
padding: 0;
background: transparent;
color: var(--text-muted);
border: 1px solid transparent;
border-radius: var(--radius-md);
}
.icon-btn:hover:not(:disabled) {
background: var(--surface-elevated);
color: var(--text);
}
.logging-out {
font-size: var(--font-base);
line-height: 1;

View File

@@ -27,6 +27,7 @@
import Pager from '$lib/components/Pager.svelte';
import SegmentedControl from '$lib/components/SegmentedControl.svelte';
import Sheet from '$lib/components/Sheet.svelte';
import IconButton from '$lib/components/IconButton.svelte';
import Search from '@lucide/svelte/icons/search';
import SlidersHorizontal from '@lucide/svelte/icons/sliders-horizontal';
import ArrowUpDown from '@lucide/svelte/icons/arrow-up-down';
@@ -467,9 +468,16 @@
placeholder="Search by title or author"
data-testid="search-input"
/>
<button class="icon-btn primary" type="submit" aria-label="Search" title="Search">
<IconButton
variant="primary"
size={36}
radius="md"
type="submit"
aria-label="Search"
title="Search"
>
<Search size={18} aria-hidden="true" />
</button>
</IconButton>
<button
type="button"
class="filters-toggle"
@@ -922,26 +930,6 @@
border-color: var(--primary-hover);
}
.icon-btn {
display: inline-flex;
align-items: center;
justify-content: center;
width: 36px;
height: 36px;
padding: 0;
}
.icon-btn.primary {
background: var(--primary);
color: var(--primary-contrast);
border: 1px solid var(--primary);
}
.icon-btn.primary:hover:not(:disabled) {
background: var(--primary-hover);
border-color: var(--primary-hover);
}
.status {
color: var(--text-muted);
}