Merge branch 'refactor/icon-button-outliers' into chore/reconcile-ui-review

# Conflicts:
#	frontend/src/routes/collections/[id]/+page.svelte
This commit is contained in:
MechaCat02
2026-06-25 21:13:06 +02:00
8 changed files with 208 additions and 198 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"
@@ -923,26 +931,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);
}

View File

@@ -12,6 +12,7 @@
import type { Manga } from '$lib/api/client';
import { fileUrl } from '$lib/api/client';
import MangaCard from '$lib/components/MangaCard.svelte';
import IconButton from '$lib/components/IconButton.svelte';
import ArrowLeft from '@lucide/svelte/icons/arrow-left';
import Pencil from '@lucide/svelte/icons/pencil';
import Check from '@lucide/svelte/icons/check';
@@ -148,26 +149,23 @@
{:else}
<div class="title-row">
<h1 data-testid="collection-name">{collection.name}</h1>
<button
type="button"
class="icon-btn"
<IconButton
onclick={startEdit}
aria-label="Edit collection"
title="Edit"
data-testid="collection-edit-open"
>
<Pencil size={16} aria-hidden="true" />
</button>
<button
type="button"
class="icon-btn danger"
</IconButton>
<IconButton
variant="danger"
onclick={onDeleteCollection}
aria-label="Delete collection"
title="Delete"
data-testid="collection-delete"
>
<Trash2 size={16} aria-hidden="true" />
</button>
</IconButton>
</div>
{#if collection.description}
<p class="description" data-testid="collection-description">
@@ -418,26 +416,4 @@
height: 32px;
}
}
.icon-btn {
display: inline-flex;
align-items: center;
justify-content: center;
width: 32px;
height: 32px;
padding: 0;
background: transparent;
color: var(--text-muted);
border: 1px solid transparent;
border-radius: var(--radius-sm);
}
.icon-btn:hover {
background: var(--surface-elevated);
color: var(--text);
}
.icon-btn.danger:hover {
color: var(--danger);
}
</style>

View File

@@ -10,6 +10,7 @@
import { session } from '$lib/session.svelte';
import { formatBytes, validateImageFile } from '$lib/upload-validation';
import Chip from '$lib/components/Chip.svelte';
import IconButton from '$lib/components/IconButton.svelte';
import Plus from '@lucide/svelte/icons/plus';
import Trash2 from '@lucide/svelte/icons/trash-2';
@@ -190,16 +191,15 @@
maxlength="200"
data-testid="manga-author-input"
/>
<button
type="button"
class="icon-btn primary"
<IconButton
variant="primary"
onclick={addAuthor}
disabled={!authorDraft.trim()}
aria-label="Add author"
title="Add author"
>
<Plus size={16} aria-hidden="true" />
</button>
</IconButton>
</div>
</div>
@@ -240,16 +240,15 @@
maxlength="200"
data-testid="manga-alt-input"
/>
<button
type="button"
class="icon-btn primary"
<IconButton
variant="primary"
onclick={addAltTitle}
disabled={!altTitleDraft.trim()}
aria-label="Add alternative title"
title="Add alternative title"
>
<Plus size={16} aria-hidden="true" />
</button>
</IconButton>
</div>
</div>
@@ -270,16 +269,15 @@
src={fileUrl(currentCoverPath)}
alt="Current cover"
/>
<button
type="button"
class="icon-btn danger"
<IconButton
variant="danger"
onclick={markCoverForRemoval}
aria-label="Remove cover"
title="Remove cover"
data-testid="cover-remove"
>
<Trash2 size={16} aria-hidden="true" />
</button>
</IconButton>
</div>
{:else if pendingCoverRemoval}
<p class="hint" data-testid="cover-pending-removal">
@@ -419,39 +417,6 @@
cursor: pointer;
}
.icon-btn {
display: inline-flex;
align-items: center;
justify-content: center;
width: 32px;
height: 32px;
padding: 0;
background: transparent;
color: var(--text-muted);
border: 1px solid transparent;
border-radius: var(--radius-sm);
}
.icon-btn:hover:not(:disabled) {
background: var(--surface-elevated);
color: var(--text);
}
.icon-btn.primary {
background: var(--primary);
color: var(--primary-contrast);
border-color: var(--primary);
}
.icon-btn.primary:hover:not(:disabled) {
background: var(--primary-hover);
border-color: var(--primary-hover);
}
.icon-btn.danger:hover:not(:disabled) {
color: var(--danger);
}
.cover-preview {
display: flex;
align-items: flex-start;

View File

@@ -9,6 +9,7 @@
import ChapterPagesEditor, {
type PendingPage
} from '$lib/components/ChapterPagesEditor.svelte';
import IconButton from '$lib/components/IconButton.svelte';
import Plus from '@lucide/svelte/icons/plus';
import Trash2 from '@lucide/svelte/icons/trash-2';
@@ -236,16 +237,15 @@
maxlength="200"
data-testid="manga-author-input"
/>
<button
type="button"
class="icon-btn primary"
<IconButton
variant="primary"
onclick={addAuthor}
disabled={!authorDraft.trim()}
aria-label="Add author"
title="Add author"
>
<Plus size={16} aria-hidden="true" />
</button>
</IconButton>
</div>
</div>
@@ -286,16 +286,15 @@
maxlength="200"
data-testid="manga-alt-input"
/>
<button
type="button"
class="icon-btn primary"
<IconButton
variant="primary"
onclick={addAltTitle}
disabled={!altTitleDraft.trim()}
aria-label="Add alternative title"
title="Add alternative title"
>
<Plus size={16} aria-hidden="true" />
</button>
</IconButton>
</div>
</div>
@@ -378,16 +377,15 @@
Failed
{/if}
</span>
<button
type="button"
class="icon-btn danger"
<IconButton
variant="danger"
onclick={() => removeChapter(c.id)}
aria-label="Remove chapter"
title="Remove chapter"
data-testid="staged-chapter-remove"
>
<Trash2 size={16} aria-hidden="true" />
</button>
</IconButton>
</div>
{#if c.error}
<p class="field-error" role="alert">{c.error}</p>
@@ -513,39 +511,6 @@
cursor: pointer;
}
.icon-btn {
display: inline-flex;
align-items: center;
justify-content: center;
width: 32px;
height: 32px;
padding: 0;
background: transparent;
color: var(--text-muted);
border: 1px solid transparent;
border-radius: var(--radius-sm);
}
.icon-btn:hover:not(:disabled) {
background: var(--surface-elevated);
color: var(--text);
}
.icon-btn.primary {
background: var(--primary);
color: var(--primary-contrast);
border-color: var(--primary);
}
.icon-btn.primary:hover:not(:disabled) {
background: var(--primary-hover);
border-color: var(--primary-hover);
}
.icon-btn.danger:hover:not(:disabled) {
color: var(--danger);
}
.chapters-header {
display: flex;
align-items: center;