feat: implement universal icon system with Phosphor Icons

- Install @phosphor-icons/react package
- Create centralized Icon component with size/weight/color variants
- Create icon registry with 34 icons across 5 categories
- Replace all raw Unicode symbols with proper icon components
- Add icons to navigation, buttons, status indicators, git operations
- Add icon CSS with consistent sizing and spacing
- Fix type definitions for Phosphor icon compatibility

Quality gates: typecheck ✓, lint ✓, build ✓ (375KB bundle)
This commit is contained in:
Fusion
2026-05-19 19:33:06 +02:00
parent cccc4a9d5a
commit 6f41fa7cbe
37 changed files with 1037 additions and 41 deletions
+10 -3
View File
@@ -10,6 +10,7 @@ import {
type URLParseResult,
} from "../api/git_repositories";
import type { GitRepository } from "../api/git_repositories";
import { Icon } from "../components/icon";
type RepoStatus = "loading" | "ready" | "error";
type UrlValidationStatus = "idle" | "validating" | "valid" | "needs-parsing" | "invalid";
@@ -160,6 +161,7 @@ export const GitRepositoriesPage = () => {
<div className="page-header">
<h1>Repositories</h1>
<button className="primary-button" onClick={() => setShowCreate(true)} type="button">
<Icon name="add" size="sm" />
New Repository
</button>
</div>
@@ -170,6 +172,7 @@ export const GitRepositoriesPage = () => {
<div className="card stack">
<p>Failed to load repositories</p>
<button className="secondary-button" onClick={() => void loadRepositories()} type="button">
<Icon name="refresh" size="sm" />
Retry
</button>
</div>
@@ -256,12 +259,14 @@ export const GitRepositoriesPage = () => {
<span className="validation-status validating">Validating...</span>
)}
{urlValidation.status === "valid" && (
<span className="validation-status valid"> Valid git URL</span>
<span className="validation-status valid">
<Icon name="success" size="sm" /> Valid git URL
</span>
)}
{urlValidation.status === "needs-parsing" && urlValidation.result && (
<div className="url-suggestion">
<span className="validation-status warning">
This looks like a browser URL
<Icon name="warning" size="sm" /> This looks like a browser URL
</span>
<div className="suggestion-actions">
<span className="suggested-url">
@@ -279,7 +284,7 @@ export const GitRepositoriesPage = () => {
)}
{urlValidation.status === "invalid" && (
<span className="validation-status invalid">
Invalid URL
<Icon name="error" size="sm" /> Invalid URL
</span>
)}
</label>
@@ -292,9 +297,11 @@ export const GitRepositoriesPage = () => {
)}
<div className="dialog-actions">
<button className="secondary-button" onClick={() => setShowCreate(false)} type="button">
<Icon name="cancel" size="sm" />
Cancel
</button>
<button className="primary-button" type="submit">
<Icon name="add" size="sm" />
Create
</button>
</div>