perf(ui): migrate icons to SVG sprite system
Replace @remixicon/react with a shared Icon component that renders via <use href> references to a single hidden SVG sprite. This reduces DOM node count by replacing inline SVGs with lightweight references. - Create Icon component with sprite injection (packages/ui/src/components/icon/) - Migrate all 164 files from @remixicon/react to Icon component - Auto-generate sprite data from remixicon bundle (scripts/generate-icon-sprite.mjs) - Add bun run icons:generate to package.json - Move @remixicon/react to devDependencies - Add icon usage instructions to theme-system skill
This commit is contained in:
@@ -23,6 +23,7 @@ import { useI18n } from '@/lib/i18n';
|
||||
import { ProviderLogo } from '@/components/ui/ProviderLogo';
|
||||
import { UsageProgressBar } from '@/components/sections/usage/UsageProgressBar';
|
||||
import { PaceIndicator } from '@/components/sections/usage/PaceIndicator';
|
||||
import { Icon } from "@/components/icon/Icon";
|
||||
import { formatQuotaValueLabel, formatWindowLabel, QUOTA_PROVIDERS, calculatePace, calculateExpectedUsagePercent } from '@/lib/quota';
|
||||
import { useQuotaAutoRefresh, useQuotaStore } from '@/stores/useQuotaStore';
|
||||
import { useUpdateStore } from '@/stores/useUpdateStore';
|
||||
@@ -30,7 +31,6 @@ import { updateDesktopSettings } from '@/lib/persistence';
|
||||
import { lazyWithChunkRecovery } from '@/lib/chunkLoadRecovery';
|
||||
import type { UsageWindow } from '@/types';
|
||||
import type { SessionContextUsage } from '@/stores/types/sessionTypes';
|
||||
import { RiAddLine, RiArrowLeftLine, RiRefreshLine, RiRobot2Line, RiSettings3Line, RiTimerLine } from '@remixicon/react';
|
||||
|
||||
const SettingsView = lazyWithChunkRecovery(() => import('@/components/views/SettingsView').then(m => ({ default: m.SettingsView })));
|
||||
|
||||
@@ -220,7 +220,6 @@ export const VSCodeLayout: React.FC = () => {
|
||||
setCurrentView('sessions');
|
||||
}, []);
|
||||
|
||||
|
||||
// Listen for connection status changes
|
||||
React.useEffect(() => {
|
||||
// Catch up with the latest status even if the extension posted the connection message
|
||||
@@ -695,7 +694,7 @@ const VSCodeHeader: React.FC<VSCodeHeaderProps> = ({ title, showBack, onBack, on
|
||||
className="inline-flex h-7 w-7 items-center justify-center text-muted-foreground hover:text-foreground transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary"
|
||||
aria-label={t('vscodeLayout.actions.backToSessionsAria')}
|
||||
>
|
||||
<RiArrowLeftLine className="h-5 w-5" />
|
||||
<Icon name="arrow-left" className="h-5 w-5" />
|
||||
</button>
|
||||
)}
|
||||
<h1 className="text-sm font-medium truncate flex-1" title={title}>{title}</h1>
|
||||
@@ -705,7 +704,7 @@ const VSCodeHeader: React.FC<VSCodeHeaderProps> = ({ title, showBack, onBack, on
|
||||
className="inline-flex h-9 w-9 items-center justify-center p-2 text-muted-foreground hover:text-foreground transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary"
|
||||
aria-label={t('vscodeLayout.actions.newSessionAria')}
|
||||
>
|
||||
<RiAddLine className="h-5 w-5" />
|
||||
<Icon name="add" className="h-5 w-5" />
|
||||
</button>
|
||||
)}
|
||||
{onAgentManager && (
|
||||
@@ -714,7 +713,7 @@ const VSCodeHeader: React.FC<VSCodeHeaderProps> = ({ title, showBack, onBack, on
|
||||
className="inline-flex h-9 w-9 items-center justify-center p-2 text-muted-foreground hover:text-foreground transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary"
|
||||
aria-label={t('vscodeLayout.actions.openAgentManagerAria')}
|
||||
>
|
||||
<RiRobot2Line className="h-5 w-5" />
|
||||
<Icon name="robot-2" className="h-5 w-5" />
|
||||
</button>
|
||||
)}
|
||||
{showMcp && (
|
||||
@@ -737,7 +736,7 @@ const VSCodeHeader: React.FC<VSCodeHeaderProps> = ({ title, showBack, onBack, on
|
||||
className="inline-flex h-9 w-9 items-center justify-center p-2 text-muted-foreground hover:text-foreground transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary"
|
||||
disabled={isQuotaLoading}
|
||||
>
|
||||
<RiTimerLine className="h-5 w-5" />
|
||||
<Icon name="timer" className="h-5 w-5" />
|
||||
</button>
|
||||
</DropdownMenuTrigger>
|
||||
<DropdownMenuContent
|
||||
@@ -785,7 +784,7 @@ const VSCodeHeader: React.FC<VSCodeHeaderProps> = ({ title, showBack, onBack, on
|
||||
disabled={isQuotaLoading}
|
||||
aria-label={t('vscodeLayout.quota.actions.refreshAria')}
|
||||
>
|
||||
<RiRefreshLine className="h-4 w-4" />
|
||||
<Icon name="refresh" className="h-4 w-4" />
|
||||
</button>
|
||||
</div>
|
||||
</DropdownMenuLabel>
|
||||
@@ -870,7 +869,7 @@ const VSCodeHeader: React.FC<VSCodeHeaderProps> = ({ title, showBack, onBack, on
|
||||
className="inline-flex h-9 w-9 items-center justify-center p-2 text-muted-foreground hover:text-foreground transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary"
|
||||
aria-label={t('vscodeLayout.actions.settingsAria')}
|
||||
>
|
||||
<RiSettings3Line className="h-5 w-5" />
|
||||
<Icon name="settings-3" className="h-5 w-5" />
|
||||
</button>
|
||||
)}
|
||||
{showContextUsage && stableContextUsage && stableContextUsage.totalTokens > 0 && (
|
||||
|
||||
Reference in New Issue
Block a user