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:
@@ -6,14 +6,14 @@ import {
|
||||
DropdownMenuItem,
|
||||
DropdownMenuTrigger,
|
||||
} from '@/components/ui/dropdown-menu';
|
||||
import { RiMore2Line } from '@remixicon/react';
|
||||
import { Icon } from "@/components/icon/Icon";
|
||||
import { cn } from '@/lib/utils';
|
||||
|
||||
export interface SettingsSidebarItemAction {
|
||||
/** Label shown in dropdown menu */
|
||||
label: string;
|
||||
/** Icon component to show before label */
|
||||
icon?: React.ComponentType<{ className?: string }>;
|
||||
icon?: string;
|
||||
/** Callback when action is clicked */
|
||||
onClick: () => void;
|
||||
/** If true, uses destructive styling (red text) */
|
||||
@@ -47,10 +47,10 @@ interface SettingsSidebarItemProps {
|
||||
* metadata={agent.description}
|
||||
* selected={selectedId === agent.id}
|
||||
* onSelect={() => setSelectedId(agent.id)}
|
||||
* icon={<RiRobotLine className="h-4 w-4" />}
|
||||
* icon={<'robot' className="h-4 w-4" />}
|
||||
* actions={[
|
||||
* { label: 'Duplicate', icon: RiFileCopyLine, onClick: handleDuplicate },
|
||||
* { label: 'Delete', icon: RiDeleteBinLine, onClick: handleDelete, destructive: true },
|
||||
* { label: 'Duplicate', icon: 'file-copy', onClick: handleDuplicate },
|
||||
* { label: 'Delete', icon: 'delete-bin', onClick: handleDelete, destructive: true },
|
||||
* ]}
|
||||
* />
|
||||
*/
|
||||
@@ -103,12 +103,12 @@ export const SettingsSidebarItem: React.FC<SettingsSidebarItemProps> = ({
|
||||
variant="ghost"
|
||||
className="h-6 w-6 flex-shrink-0 -mr-1 opacity-100 transition-opacity md:opacity-0 md:group-hover:opacity-100"
|
||||
>
|
||||
<RiMore2Line className="h-3.5 w-3.5" />
|
||||
<Icon name="more-2" className="h-3.5 w-3.5" />
|
||||
</Button>
|
||||
</DropdownMenuTrigger>
|
||||
<DropdownMenuContent align="end" className="w-fit min-w-20">
|
||||
{actions.map((action) => {
|
||||
const Icon = action.icon;
|
||||
const iconName = action.icon;
|
||||
return (
|
||||
<DropdownMenuItem
|
||||
key={action.label}
|
||||
@@ -120,7 +120,7 @@ export const SettingsSidebarItem: React.FC<SettingsSidebarItemProps> = ({
|
||||
action.destructive && 'text-destructive focus:text-destructive'
|
||||
)}
|
||||
>
|
||||
{Icon && <Icon className="h-4 w-4 mr-px" />}
|
||||
{iconName && <Icon name={iconName} className="h-4 w-4 mr-px" />}
|
||||
{action.label}
|
||||
</DropdownMenuItem>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user