refactor(ui): extract shared icons into icons.tsx

The ten most-duplicated inline SVGs (Check, Close, ChevronDown/Right,
Plus, Photo, Folder, Warning, Star, Play) become shared components --
34+ copies across 15 files replaced. Stroke icons take a per-site
strokeWidth since weights legitimately differ by context; icons that
appear once or use variant path data stay inline.
This commit is contained in:
2026-07-04 12:29:14 +01:00
parent 4d41f3744f
commit fbf8a7878c
16 changed files with 122 additions and 170 deletions
+7 -21
View File
@@ -7,6 +7,7 @@ import { InlineConfirm } from "./InlineConfirm";
import { InlineRename } from "./InlineRename";
import { mediaSrc } from "../lib/mediaSrc";
import { Tooltip } from "./Tooltip";
import { CheckIcon, CloseIcon, FolderIcon, PhotoIcon, PlusIcon } from "./icons";
type LibrarySort = "az" | "za" | "custom";
const LIBRARY_SORT_KEY = "phokus-library-sort";
@@ -146,10 +147,7 @@ function FolderItem({
</svg>
</span>
) : (
<svg className="w-3.5 h-3.5 shrink-0" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={1.5}
d="M3 7a2 2 0 012-2h3.586a1 1 0 01.707.293l1.414 1.414A1 1 0 0011.414 7H19a2 2 0 012 2v9a2 2 0 01-2 2H5a2 2 0 01-2-2V7z" />
</svg>
<FolderIcon className="w-3.5 h-3.5 shrink-0" />
)}
<div className="flex-1 min-w-0">
@@ -204,10 +202,7 @@ function FolderItem({
className="p-1 rounded text-gray-600 hover:text-red-400 hover:bg-red-500/10 transition-colors"
onClick={(e) => { e.stopPropagation(); setConfirmingRemoval(true); }}
>
<svg className="w-3 h-3" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={1.75}
d="M6 18L18 6M6 6l12 12" />
</svg>
<CloseIcon className="w-3 h-3" strokeWidth={1.75} />
</button>
</Tooltip>
</div>
@@ -334,9 +329,7 @@ function AlbumItem({
selectedForManage ? "border-blue-400 bg-blue-500 text-white" : "border-white/30 text-transparent"
}`}
>
<svg className="h-2.5 w-2.5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={3} d="M5 13l4 4L19 7" />
</svg>
<CheckIcon className="h-2.5 w-2.5" strokeWidth={3} />
</div>
) : null}
@@ -369,10 +362,7 @@ function AlbumItem({
<img src={cover} alt="" className="h-full w-full object-cover" />
) : (
<div className="flex h-full w-full items-center justify-center text-white/20">
<svg className="h-3.5 w-3.5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={1.5}
d="M4 16l4.586-4.586a2 2 0 012.828 0L16 16m-2-2l1.586-1.586a2 2 0 012.828 0L20 14m-6-6h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z" />
</svg>
<PhotoIcon className="h-3.5 w-3.5" />
</div>
)}
</div>
@@ -663,9 +653,7 @@ export function Sidebar() {
onClick={handleAddFolder}
className="p-1.5 rounded-lg text-gray-500 hover:text-gray-200 hover:bg-white/8 transition-colors"
>
<svg className="w-4 h-4" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={1.75} d="M12 4v16m8-8H4" />
</svg>
<PlusIcon className="w-4 h-4" />
</button>
</Tooltip>
</div>
@@ -786,9 +774,7 @@ export function Sidebar() {
onClick={startCreatingAlbum}
className="rounded p-0.5 text-gray-600 transition-colors hover:bg-white/8 hover:text-gray-200"
>
<svg className="h-3.5 w-3.5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={1.75} d="M12 4v16m8-8H4" />
</svg>
<PlusIcon className="h-3.5 w-3.5" />
</button>
</Tooltip>
</div>