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
+20 -13
View File
@@ -9,6 +9,7 @@ import {
pushRepository,
type GitStatus,
} from "../api/git_repositories";
import { Icon } from "./icon";
import { MergeDialog } from "./merge-dialog";
interface GitToolbarProps {
@@ -140,7 +141,13 @@ export const GitToolbar = ({
>
{branches.map((b) => (
<option key={b} value={b}>
{b === currentBranch ? `${b}` : b}
{b === currentBranch ? (
<>
<Icon name="branch" size="sm" /> {b}
</>
) : (
b
)}
</option>
))}
</select>
@@ -150,18 +157,18 @@ export const GitToolbar = ({
disabled={loading}
type="button"
>
+ New
<Icon name="add" size="sm" /> New
</button>
</div>
<div className="toolbar-group">
<button
<button
className="toolbar-button"
onClick={handleFetch}
disabled={loading}
type="button"
>
Fetch
<Icon name="fetch" size="sm" /> Fetch
</button>
<button
className="toolbar-button"
@@ -169,7 +176,7 @@ export const GitToolbar = ({
disabled={loading}
type="button"
>
Pull
<Icon name="pull" size="sm" /> Pull
{status?.behind ? <span className="badge">{status.behind}</span> : null}
</button>
<button
@@ -178,7 +185,7 @@ export const GitToolbar = ({
disabled={loading || !status?.ahead}
type="button"
>
Push
<Icon name="push" size="sm" /> Push
{status?.ahead ? <span className="badge">{status.ahead}</span> : null}
</button>
<button
@@ -187,7 +194,7 @@ export const GitToolbar = ({
disabled={loading}
type="button"
>
🔀 Merge
<Icon name="merge" size="sm" /> Merge
</button>
</div>
</div>
@@ -217,24 +224,24 @@ export const GitToolbar = ({
disabled={loading || !newBranchName.trim()}
type="button"
>
Create
<Icon name="add" size="sm" /> Create
</button>
<button
className="toolbar-button"
onClick={() => setShowNewBranch(false)}
type="button"
>
Cancel
<Icon name="cancel" size="sm" /> Cancel
</button>
</div>
)}
{hasChanges && status && (
<div className="toolbar-row status-summary">
{status.modified.length > 0 && <span className="status-badge modified"> {status.modified.length} modified</span>}
{status.added.length > 0 && <span className="status-badge added"> {status.added.length} added</span>}
{status.deleted.length > 0 && <span className="status-badge deleted">🗑 {status.deleted.length} deleted</span>}
{status.untracked.length > 0 && <span className="status-badge untracked"> {status.untracked.length} untracked</span>}
{status.modified.length > 0 && <span className="status-badge modified"><Icon name="edit" size="sm" /> {status.modified.length} modified</span>}
{status.added.length > 0 && <span className="status-badge added"><Icon name="add" size="sm" /> {status.added.length} added</span>}
{status.deleted.length > 0 && <span className="status-badge deleted"><Icon name="delete" size="sm" /> {status.deleted.length} deleted</span>}
{status.untracked.length > 0 && <span className="status-badge untracked"><Icon name="warning" size="sm" /> {status.untracked.length} untracked</span>}
</div>
)}