Skip to content

Commit 507aa53

Browse files
committed
ui: 公開サイト・管理画面の全体最適化
主な改善: - a11y: focus-visible リング統一、aria-invalid/aria-describedby/role=dialog、alt 補強 - ホバー一貫性: 検索/フッター/ナビに hover:bg-primary/5 系を統一 - レスポンシブ: 記事ヘッダーのモバイル縦並び、画像高さ抑制、グリッド調整 - ポリッシュ: 空状態カード化、prose 色明示、ページネーション/カード ring 強化 - フォーム: スラッグラベル可視化、保存成功表示の延長、エラー aria 紐付け - 画像: ImageSection に loading=lazy/decoding=async、カテゴリバッジに dark base bun tidy / build ともクリーン通過。
1 parent de7a253 commit 507aa53

28 files changed

Lines changed: 124 additions & 92 deletions

src/lib/components/ImageSection.svelte

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,13 @@
2020
? 'lg:rounded-r-2xl'
2121
: 'lg:ml-auto lg:rounded-l-2xl'}"
2222
>
23-
<img src={image} alt={imageAlt} class="h-full w-full object-cover" />
23+
<img
24+
src={image}
25+
alt={imageAlt}
26+
loading="lazy"
27+
decoding="async"
28+
class="h-full w-full object-cover"
29+
/>
2430
</div>
2531
</div>
2632
<div style:grid-area="1 / 1" class="container mx-auto lg:max-w-screen-lg">

src/lib/components/Markdown.svelte

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
});
1515
</script>
1616

17-
<div class="prose max-w-none prose-zinc">
17+
<div class="prose max-w-none prose-zinc prose-headings:text-zinc-900 prose-p:text-zinc-700 prose-a:text-primary hover:prose-a:underline">
1818
<!-- eslint-disable-next-line svelte/no-at-html-tags -->
1919
{@html html}
2020
</div>

src/lib/components/Pagination.svelte

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
{#if currentPage > 1}
1414
<a
1515
href={pageUrl(currentPage - 1)}
16-
class="w-full rounded-lg border border-zinc-200 bg-white px-4 py-2 text-center text-sm font-medium transition-colors hover:bg-primary/5 hover:border-primary/30 hover:text-primary focus:ring-2 focus:ring-primary/50 focus:ring-offset-2 sm:w-auto"
16+
class="w-full rounded-lg border border-zinc-200 bg-white px-4 py-2 text-center text-sm font-medium transition-colors hover:bg-primary/5 hover:border-primary/30 hover:text-primary focus:outline-none focus:ring-2 focus:ring-primary focus:ring-offset-2 sm:w-auto"
1717
>
1818
前へ
1919
</a>
@@ -30,7 +30,7 @@
3030
{#if totalPages <= 7 || pageNum === 1 || pageNum === totalPages || Math.abs(pageNum - currentPage) <= 1}
3131
<a
3232
href={pageUrl(pageNum)}
33-
class="min-w-[2.5rem] rounded-lg border px-3 py-2 text-center text-sm font-medium transition-colors focus:ring-2 focus:ring-primary/50 focus:ring-offset-2 {currentPage ===
33+
class="min-w-[2.5rem] rounded-lg border px-3 py-2 text-center text-sm font-medium transition-colors focus:outline-none focus:ring-2 focus:ring-primary focus:ring-offset-2 {currentPage ===
3434
pageNum
3535
? 'border-primary bg-primary text-white'
3636
: 'border-zinc-200 bg-white hover:bg-primary/5 hover:border-primary/30 hover:text-primary'}"
@@ -46,7 +46,7 @@
4646
{#if currentPage < totalPages}
4747
<a
4848
href={pageUrl(currentPage + 1)}
49-
class="w-full rounded-lg border border-zinc-200 bg-white px-4 py-2 text-center text-sm font-medium transition-colors hover:bg-primary/5 hover:border-primary/30 hover:text-primary focus:ring-2 focus:ring-primary/50 focus:ring-offset-2 sm:w-auto"
49+
class="w-full rounded-lg border border-zinc-200 bg-white px-4 py-2 text-center text-sm font-medium transition-colors hover:bg-primary/5 hover:border-primary/30 hover:text-primary focus:outline-none focus:ring-2 focus:ring-primary focus:ring-offset-2 sm:w-auto"
5050
>
5151
次へ
5252
</a>

src/lib/components/admin-dashboard/NeedsAttention.svelte

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@
3737
{#each draftArticles as draft (draft.id)}
3838
<a
3939
href="/admin/articles/edit/{draft.id}"
40-
class="group flex items-center gap-3 rounded-xl border border-base-300/50 bg-base-200/50 p-3 transition-all hover:bg-primary/5 hover:border-primary/30"
40+
class="group flex items-center gap-3 rounded-xl border border-base-300/50 bg-base-200/50 p-3 transition-all hover:bg-primary/5 hover:border-primary/30 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary focus-visible:ring-offset-2"
4141
>
4242
<div class="flex h-9 w-9 items-center justify-center rounded-lg bg-warning/10">
4343
<SquarePen class="h-4 w-4 text-warning" />

src/lib/components/admin-dashboard/QuickActions.svelte

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,21 +12,21 @@
1212
<div class="grid grid-cols-1 gap-3 sm:grid-cols-3">
1313
<a
1414
href="/admin/members/new"
15-
class="btn btn-sm gap-2 border-base-300 bg-base-100 font-medium transition-all hover:border-primary/30 hover:bg-primary/5 hover:text-primary sm:btn-md"
15+
class="btn btn-sm gap-2 border-base-300 bg-base-100 font-medium transition-all hover:border-primary/30 hover:bg-primary/5 hover:text-primary focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary focus-visible:ring-offset-2 sm:btn-md"
1616
>
1717
<UserPlus class="h-4 w-4" />
1818
Add Member
1919
</a>
2020
<a
2121
href="/admin/articles/new"
22-
class="btn btn-sm gap-2 border-base-300 bg-base-100 font-medium transition-all hover:border-primary/30 hover:bg-primary/5 hover:text-primary sm:btn-md"
22+
class="btn btn-sm gap-2 border-base-300 bg-base-100 font-medium transition-all hover:border-primary/30 hover:bg-primary/5 hover:text-primary focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary focus-visible:ring-offset-2 sm:btn-md"
2323
>
2424
<Pencil class="h-4 w-4" />
2525
New Article
2626
</a>
2727
<a
2828
href="/admin/projects/new"
29-
class="btn btn-sm gap-2 border-base-300 bg-base-100 font-medium transition-all hover:border-primary/30 hover:bg-primary/5 hover:text-primary sm:btn-md"
29+
class="btn btn-sm gap-2 border-base-300 bg-base-100 font-medium transition-all hover:border-primary/30 hover:bg-primary/5 hover:text-primary focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary focus-visible:ring-offset-2 sm:btn-md"
3030
>
3131
<Folder class="h-4 w-4" />
3232
New Project

src/lib/components/admin-dashboard/RecentActivity.svelte

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@
3232
{#each recentArticles as article (article.id)}
3333
<a
3434
href="/admin/articles/edit/{article.id}"
35-
class="group flex items-center gap-3 rounded-xl border border-base-300/50 bg-base-200/50 p-3 transition-all hover:bg-primary/5 hover:border-primary/30"
35+
class="group flex items-center gap-3 rounded-xl border border-base-300/50 bg-base-200/50 p-3 transition-all hover:bg-primary/5 hover:border-primary/30 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary focus-visible:ring-offset-2"
3636
>
3737
<div
3838
class="flex h-9 w-9 items-center justify-center rounded-lg {article.published

src/lib/components/article-form/ArticleEditor.svelte

Lines changed: 32 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -196,30 +196,40 @@
196196
</p>
197197

198198
<div class="flex gap-2">
199-
<input
200-
type="date"
201-
value={formatDateForSlug(slugDate)}
202-
oninput={handleDateChange}
203-
class="w-32 shrink-0 rounded-lg border bg-white px-2 py-1.5 font-mono text-sm text-zinc-900 focus:ring-0 focus:outline-none"
204-
class:border-zinc-200={!displayError && !isSlugValid}
205-
class:border-emerald-500={isSlugValid && slug.length > 0}
206-
class:border-red-300={displayError}
207-
/>
208-
<input
209-
type="text"
210-
value={slugTitle}
211-
oninput={handleSlugTitleChange}
212-
class="min-w-0 flex-1 rounded-lg border bg-white px-2 py-1.5 font-mono text-sm text-zinc-900 focus:ring-0 focus:outline-none"
213-
class:border-zinc-200={!displayError && !isSlugValid}
214-
class:border-emerald-500={isSlugValid && slug.length > 0}
215-
class:border-red-300={displayError}
216-
placeholder="title-slug"
217-
/>
199+
<div class="flex w-32 shrink-0 flex-col gap-1">
200+
<label for="slug-date" class="text-xs font-medium text-zinc-500">公開日</label>
201+
<input
202+
type="date"
203+
id="slug-date"
204+
value={formatDateForSlug(slugDate)}
205+
oninput={handleDateChange}
206+
class="w-full rounded-lg border bg-white px-2 py-1.5 font-mono text-sm text-zinc-900 focus:ring-0 focus:outline-none"
207+
class:border-zinc-200={!displayError && !isSlugValid}
208+
class:border-emerald-500={isSlugValid && slug.length > 0}
209+
class:border-red-300={displayError}
210+
/>
211+
</div>
212+
<div class="flex min-w-0 flex-1 flex-col gap-1">
213+
<label for="slug-title" class="text-xs font-medium text-zinc-500">スラッグタイトル</label>
214+
<input
215+
type="text"
216+
id="slug-title"
217+
value={slugTitle}
218+
oninput={handleSlugTitleChange}
219+
class="w-full rounded-lg border bg-white px-2 py-1.5 font-mono text-sm text-zinc-900 focus:ring-0 focus:outline-none"
220+
class:border-zinc-200={!displayError && !isSlugValid}
221+
class:border-emerald-500={isSlugValid && slug.length > 0}
222+
class:border-red-300={displayError}
223+
placeholder="title-slug"
224+
/>
225+
</div>
218226
</div>
219227

220-
{#if displayError}
221-
<p class="text-xs text-red-500">{displayError}</p>
222-
{/if}
228+
<div aria-live="polite">
229+
{#if displayError}
230+
<p class="text-xs text-red-500">{displayError}</p>
231+
{/if}
232+
</div>
223233

224234
<!-- Redirect checkbox (only show when editing and slug has changed) -->
225235
{#if initialSlug && slug !== initialSlug}

src/lib/components/article-form/ArticleFormHeader.svelte

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@
5858
successTimeout = setTimeout(() => {
5959
saveSuccess = false;
6060
successTimeout = null;
61-
}, 2000);
61+
}, 3500);
6262
}
6363
6464
return () => {
@@ -93,9 +93,9 @@
9393
</script>
9494

9595
<header
96-
class="sticky top-0 z-20 flex flex-wrap items-center justify-between gap-2 border-b border-zinc-200 bg-white px-3 py-2 sm:px-4 sm:py-3"
96+
class="sticky top-0 z-20 flex flex-col gap-3 border-b border-zinc-200 bg-white px-3 py-2 sm:flex-row sm:flex-wrap sm:items-center sm:justify-between sm:gap-4 sm:px-4 sm:py-3"
9797
>
98-
<div class="flex items-center gap-2 sm:gap-4">
98+
<div class="flex flex-wrap items-center gap-2 sm:gap-4">
9999
<button
100100
type="button"
101101
onclick={() => goto("/admin/articles")}
@@ -142,7 +142,7 @@
142142
>
143143
<UserCircle2 class="h-3.5 w-3.5 text-zinc-400" />
144144
{#if selectedAuthor}
145-
<span class="max-w-24 truncate sm:max-w-32">{selectedAuthor.name}</span>
145+
<span class="max-w-24 truncate sm:max-w-32" title={selectedAuthor.name}>{selectedAuthor.name}</span>
146146
{:else}
147147
<span class="text-zinc-400">No author</span>
148148
{/if}
@@ -198,7 +198,7 @@
198198
</Combobox.Root>
199199
</div>
200200

201-
<div class="flex items-center gap-1 sm:gap-2">
201+
<div class="flex w-full items-center gap-1 sm:w-auto sm:gap-2">
202202
<!-- Preview Button -->
203203
{#if articleId}
204204
<button
@@ -241,7 +241,7 @@
241241
<button
242242
type="submit"
243243
disabled={isSubmitting || saveSuccess}
244-
class="inline-flex items-center gap-1.5 rounded-lg px-3 py-1.5 text-sm font-semibold text-white transition-all active:scale-[0.98] disabled:cursor-not-allowed disabled:opacity-50 sm:gap-2 sm:px-4 sm:py-2 {published
244+
class="inline-flex w-full items-center justify-center gap-1.5 rounded-lg px-3 py-1.5 text-sm font-semibold text-white transition-all active:scale-[0.98] disabled:cursor-not-allowed disabled:opacity-50 sm:w-auto sm:gap-2 sm:px-4 sm:py-2 {published
245245
? 'bg-emerald-600 hover:bg-emerald-700'
246246
: 'bg-zinc-900 hover:bg-zinc-800'}"
247247
>

src/lib/components/confirm-modal.svelte

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@
115115
onkeydown={handleModalKeydown}
116116
role="dialog"
117117
aria-modal="true"
118-
aria-labelledby="modal-title"
118+
aria-labelledby="confirm-modal-title"
119119
tabindex="-1"
120120
>
121121
<!-- Icon -->
@@ -130,7 +130,7 @@
130130
</div>
131131

132132
<!-- Title -->
133-
<h3 id="modal-title" class="mt-4 text-center text-base font-semibold text-zinc-900">
133+
<h3 id="confirm-modal-title" class="mt-4 text-center text-base font-semibold text-zinc-900">
134134
{opts.title}
135135
</h3>
136136

src/lib/components/home/HeroSection.svelte

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
<img
88
src="/images/headers/hero.jpg"
99
alt=""
10+
role="presentation"
1011
class="absolute inset-0 h-full w-full object-cover"
1112
/>
1213
<!-- Gradient overlay for text readability -->

0 commit comments

Comments
 (0)