feat(ui): replace @ant-design/icons with Lucide
- Add frontend/src/icons.tsx adapter (Ant *Outlined names → lucide-react) - Rewrite all page/component imports - Drop @ant-design/icons; add lucide-react - CSS keyframes for optional spin prop feat(ui): replace @ant-design/icons with Lucide - Add frontend/src/icons.tsx adapter (Ant *Outlined names → lucide-react) - Rewrite all page/component imports - Drop @ant-design/icons; add lucide-react - CSS keyframes for optional spin prop feat(ui): replace @ant-design/icons with Lucide - Add frontend/src/icons.tsx adapter (Ant *Outlined names → lucide-react) - Rewrite all page/component imports - Drop @ant-design/icons; add lucide-react - CSS keyframes for optional spin prop feat(ui): replace @ant-design/icons with Lucide - Add frontend/src/icons.tsx adapter (Ant *Outlined names → lucide-react) - Rewrite all page/component imports - Drop @ant-design/icons; add lucide-react - CSS keyframes for optional spin prop feat(ui): replace @ant-design/icons with Lucide - Add frontend/src/icons.tsx adapter (Ant *Outlined names → lucide-react) - Rewrite all page/component imports - Drop @ant-design/icons; add lucide-react - CSS keyframes for optional spin prop feat(ui): replace @ant-design/icons with Lucide - Add frontend/src/icons.tsx adapter (Ant *Outlined names → lucide-react) - Rewrite all page/component imports - Drop @ant-design/icons; add lucide-react - CSS keyframes for optional spin prop feat(ui): replace @ant-design/icons with Lucide - Add frontend/src/icons.tsx adapter (Ant *Outlined names → lucide-react) - Rewrite all page/component imports - Drop @ant-design/icons; add lucide-react - CSS keyframes for optional spin prop feat(ui): replace @ant-design/icons with Lucide - Add frontend/src/icons.tsx adapter (Ant *Outlined names → lucide-react) - Rewrite all page/component imports - Drop @ant-design/icons; add lucide-react - CSS keyframes for optional spin prop feat(ui): replace @ant-design/icons with Lucide - Add frontend/src/icons.tsx adapter (Ant *Outlined names → lucide-react) - Rewrite all page/component imports - Drop @ant-design/icons; add lucide-react - CSS keyframes for optional spin prop feat(ui): replace @ant-design/icons with Lucide - Add frontend/src/icons.tsx adapter (Ant *Outlined names → lucide-react) - Rewrite all page/component imports - Drop @ant-design/icons; add lucide-react - CSS keyframes for optional spin prop feat(ui): replace @ant-design/icons with Lucide - Add frontend/src/icons.tsx adapter (Ant *Outlined names → lucide-react) - Rewrite all page/component imports - Drop @ant-design/icons; add lucide-react - CSS keyframes for optional spin prop feat(ui): replace @ant-design/icons with Lucide - Add frontend/src/icons.tsx adapter (Ant *Outlined names → lucide-react) - Rewrite all page/component imports - Drop @ant-design/icons; add lucide-react - CSS keyframes for optional spin prop
This commit is contained in:
1 parent
99e240d6bd
commit
4dfbdca143
20 files changed
+191
-19
No files matched your search
@@ -11,15 +11,15 @@
|
||||
"test:unit": "node --experimental-strip-types --test src/utils/*.test.mjs"
|
||||
},
|
||||
"dependencies": {
|
||||
"@ant-design/icons": "^6.3.2",
|
||||
"@monaco-editor/react": "^4.7.0",
|
||||
"antd": "^6.5.4",
|
||||
"axios": "^1.8.4",
|
||||
"dayjs": "^1.11.19",
|
||||
"lucide-react": "^0.544.0",
|
||||
"qrcode": "^1.5.4",
|
||||
"react": "^19.2.8",
|
||||
"react-dom": "^19.2.8",
|
||||
"react-router-dom": "^7.18.2",
|
||||
"dayjs": "^1.11.19",
|
||||
"zustand": "^5.0.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
||||
@@ -6,7 +6,7 @@ import {
|
||||
UserOutlined,
|
||||
GlobalOutlined,
|
||||
BgColorsOutlined,
|
||||
} from '@ant-design/icons';
|
||||
} from '../icons';
|
||||
import { useAuthStore } from '../stores/authStore';
|
||||
import { useThemeStore, ThemeMode } from '../stores/themeStore';
|
||||
import { useI18n, LOCALE_OPTIONS, type Locale } from '../i18n';
|
||||
|
||||
@@ -3,7 +3,7 @@ import { message,
|
||||
Form, Input, InputNumber, Select, Switch, Divider, Alert, Space, Typography, Button, Card, Radio,
|
||||
} from 'antd';
|
||||
import { generateMaterial } from '../api/listeners';
|
||||
import { MinusCircleOutlined, PlusOutlined } from '@ant-design/icons';
|
||||
import { MinusCircleOutlined, PlusOutlined } from '../icons';
|
||||
import { useI18n } from '../i18n';
|
||||
import RealityTargetFields from './RealityTargetFields';
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Alert, Button, Descriptions, Drawer, Space, Table, Tag, Typography } from 'antd';
|
||||
import { ReloadOutlined } from '@ant-design/icons';
|
||||
import { ReloadOutlined } from '../icons';
|
||||
import type { ListenerRuntime } from '../api/listenerRuntime';
|
||||
import type { Listener } from '../api/nodes';
|
||||
import { listenerAvailability, listenerDiagnosticReason } from '../utils/listenerAvailability';
|
||||
|
||||
@@ -14,7 +14,7 @@ import {
|
||||
ProfileOutlined,
|
||||
ControlOutlined,
|
||||
LogoutOutlined,
|
||||
} from '@ant-design/icons';
|
||||
} from '../icons';
|
||||
import { useLocation, useNavigate } from 'react-router-dom';
|
||||
import { useI18n } from '../i18n';
|
||||
import { useAuthStore } from '../stores/authStore';
|
||||
|
||||
@@ -13,7 +13,7 @@ import {
|
||||
ControlOutlined,
|
||||
ToolOutlined,
|
||||
LogoutOutlined,
|
||||
} from '@ant-design/icons';
|
||||
} from '../icons';
|
||||
import { useNavigate, useLocation } from 'react-router-dom';
|
||||
import { useAuthStore } from '../stores/authStore';
|
||||
import { useI18n } from '../i18n';
|
||||
|
||||
@@ -0,0 +1,166 @@
|
||||
/**
|
||||
* Panel icons — Lucide under the hood, Ant Design–style *Outlined names for drop-in replacement.
|
||||
* Import from `../icons` or `../../icons` instead of `@ant-design/icons`.
|
||||
*/
|
||||
import React from 'react';
|
||||
import type { LucideProps } from 'lucide-react';
|
||||
import {
|
||||
Plus,
|
||||
RefreshCw,
|
||||
Trash2,
|
||||
Pencil,
|
||||
Globe,
|
||||
Palette,
|
||||
Users,
|
||||
Link2,
|
||||
Share2,
|
||||
Copy,
|
||||
LayoutDashboard,
|
||||
FileText,
|
||||
Server,
|
||||
User,
|
||||
Lock,
|
||||
Shield,
|
||||
PlayCircle,
|
||||
Square,
|
||||
RotateCcw,
|
||||
Download,
|
||||
Send,
|
||||
Eraser,
|
||||
MoreHorizontal,
|
||||
QrCode,
|
||||
Save,
|
||||
BadgeCheck,
|
||||
LayoutGrid,
|
||||
Boxes,
|
||||
MonitorPlay,
|
||||
GitFork,
|
||||
Rocket,
|
||||
SlidersHorizontal,
|
||||
Wrench,
|
||||
LogOut,
|
||||
ArrowLeft,
|
||||
Undo2,
|
||||
HeartPulse,
|
||||
RefreshCcw,
|
||||
Monitor,
|
||||
HardDrive,
|
||||
LogIn,
|
||||
LineChart,
|
||||
Check,
|
||||
GitBranch,
|
||||
History,
|
||||
Power,
|
||||
FileDiff,
|
||||
Info,
|
||||
CloudDownload,
|
||||
CloudUpload,
|
||||
Cable,
|
||||
Settings,
|
||||
Bell,
|
||||
Network,
|
||||
Timer,
|
||||
PanelLeftClose,
|
||||
PanelLeftOpen,
|
||||
MinusCircle,
|
||||
} from 'lucide-react';
|
||||
|
||||
type IconProps = LucideProps & {
|
||||
/** Ant Design icons often pass style.fontSize — map to Lucide `size`. */
|
||||
style?: React.CSSProperties & { fontSize?: number | string };
|
||||
className?: string;
|
||||
twoToneColor?: string;
|
||||
spin?: boolean;
|
||||
rotate?: number;
|
||||
};
|
||||
|
||||
function wrap(Icon: React.ComponentType<LucideProps>, displayName: string) {
|
||||
const Comp = React.forwardRef<SVGSVGElement, IconProps>(function LucideAntIcon(
|
||||
{ style, className, spin, rotate, size, ...rest },
|
||||
ref,
|
||||
) {
|
||||
const fontSize = style?.fontSize;
|
||||
const resolvedSize =
|
||||
size ??
|
||||
(typeof fontSize === 'number' ? fontSize : typeof fontSize === 'string' && fontSize.endsWith('px') ? parseFloat(fontSize) : 16);
|
||||
const mergedStyle: React.CSSProperties = {
|
||||
...style,
|
||||
...(spin ? { animation: 'spin 1s linear infinite' } : null),
|
||||
...(rotate != null ? { transform: `rotate(${rotate}deg)` } : null),
|
||||
verticalAlign: style?.verticalAlign ?? 'middle',
|
||||
};
|
||||
return (
|
||||
<Icon
|
||||
ref={ref}
|
||||
size={resolvedSize}
|
||||
strokeWidth={1.75}
|
||||
className={className}
|
||||
style={mergedStyle}
|
||||
aria-hidden
|
||||
{...rest}
|
||||
/>
|
||||
);
|
||||
});
|
||||
Comp.displayName = displayName;
|
||||
return Comp;
|
||||
}
|
||||
|
||||
export const PlusOutlined = wrap(Plus, 'PlusOutlined');
|
||||
export const ReloadOutlined = wrap(RefreshCw, 'ReloadOutlined');
|
||||
export const DeleteOutlined = wrap(Trash2, 'DeleteOutlined');
|
||||
export const EditOutlined = wrap(Pencil, 'EditOutlined');
|
||||
export const GlobalOutlined = wrap(Globe, 'GlobalOutlined');
|
||||
export const BgColorsOutlined = wrap(Palette, 'BgColorsOutlined');
|
||||
export const TeamOutlined = wrap(Users, 'TeamOutlined');
|
||||
export const LinkOutlined = wrap(Link2, 'LinkOutlined');
|
||||
export const ShareAltOutlined = wrap(Share2, 'ShareAltOutlined');
|
||||
export const CopyOutlined = wrap(Copy, 'CopyOutlined');
|
||||
export const DashboardOutlined = wrap(LayoutDashboard, 'DashboardOutlined');
|
||||
export const ProfileOutlined = wrap(FileText, 'ProfileOutlined');
|
||||
export const CloudServerOutlined = wrap(Server, 'CloudServerOutlined');
|
||||
export const UserOutlined = wrap(User, 'UserOutlined');
|
||||
export const LockOutlined = wrap(Lock, 'LockOutlined');
|
||||
export const SafetyOutlined = wrap(Shield, 'SafetyOutlined');
|
||||
export const PlayCircleOutlined = wrap(PlayCircle, 'PlayCircleOutlined');
|
||||
export const StopOutlined = wrap(Square, 'StopOutlined');
|
||||
export const RedoOutlined = wrap(RotateCcw, 'RedoOutlined');
|
||||
export const DownloadOutlined = wrap(Download, 'DownloadOutlined');
|
||||
export const SendOutlined = wrap(Send, 'SendOutlined');
|
||||
export const ClearOutlined = wrap(Eraser, 'ClearOutlined');
|
||||
export const MoreOutlined = wrap(MoreHorizontal, 'MoreOutlined');
|
||||
export const QrcodeOutlined = wrap(QrCode, 'QrcodeOutlined');
|
||||
export const FileTextOutlined = wrap(FileText, 'FileTextOutlined');
|
||||
export const SaveOutlined = wrap(Save, 'SaveOutlined');
|
||||
export const SafetyCertificateOutlined = wrap(BadgeCheck, 'SafetyCertificateOutlined');
|
||||
export const AppstoreOutlined = wrap(LayoutGrid, 'AppstoreOutlined');
|
||||
export const DeploymentUnitOutlined = wrap(Boxes, 'DeploymentUnitOutlined');
|
||||
export const FundProjectionScreenOutlined = wrap(MonitorPlay, 'FundProjectionScreenOutlined');
|
||||
export const ForkOutlined = wrap(GitFork, 'ForkOutlined');
|
||||
export const RocketOutlined = wrap(Rocket, 'RocketOutlined');
|
||||
export const ControlOutlined = wrap(SlidersHorizontal, 'ControlOutlined');
|
||||
export const ToolOutlined = wrap(Wrench, 'ToolOutlined');
|
||||
export const LogoutOutlined = wrap(LogOut, 'LogoutOutlined');
|
||||
export const ArrowLeftOutlined = wrap(ArrowLeft, 'ArrowLeftOutlined');
|
||||
export const RollbackOutlined = wrap(Undo2, 'RollbackOutlined');
|
||||
export const MedicineBoxOutlined = wrap(HeartPulse, 'MedicineBoxOutlined');
|
||||
export const CloudSyncOutlined = wrap(RefreshCcw, 'CloudSyncOutlined');
|
||||
export const DesktopOutlined = wrap(Monitor, 'DesktopOutlined');
|
||||
export const HddOutlined = wrap(HardDrive, 'HddOutlined');
|
||||
export const LoginOutlined = wrap(LogIn, 'LoginOutlined');
|
||||
export const FundOutlined = wrap(LineChart, 'FundOutlined');
|
||||
export const CheckOutlined = wrap(Check, 'CheckOutlined');
|
||||
export const BranchesOutlined = wrap(GitBranch, 'BranchesOutlined');
|
||||
export const HistoryOutlined = wrap(History, 'HistoryOutlined');
|
||||
export const PoweroffOutlined = wrap(Power, 'PoweroffOutlined');
|
||||
export const DiffOutlined = wrap(FileDiff, 'DiffOutlined');
|
||||
export const InfoCircleOutlined = wrap(Info, 'InfoCircleOutlined');
|
||||
export const CloudDownloadOutlined = wrap(CloudDownload, 'CloudDownloadOutlined');
|
||||
export const CloudUploadOutlined = wrap(CloudUpload, 'CloudUploadOutlined');
|
||||
export const ApiOutlined = wrap(Cable, 'ApiOutlined');
|
||||
export const SettingOutlined = wrap(Settings, 'SettingOutlined');
|
||||
export const BellOutlined = wrap(Bell, 'BellOutlined');
|
||||
export const ClusterOutlined = wrap(Network, 'ClusterOutlined');
|
||||
export const FieldTimeOutlined = wrap(Timer, 'FieldTimeOutlined');
|
||||
export const MenuFoldOutlined = wrap(PanelLeftClose, 'MenuFoldOutlined');
|
||||
export const MenuUnfoldOutlined = wrap(PanelLeftOpen, 'MenuUnfoldOutlined');
|
||||
export const MinusCircleOutlined = wrap(MinusCircle, 'MinusCircleOutlined');
|
||||
@@ -14,7 +14,7 @@ import {
|
||||
HddOutlined,
|
||||
LoginOutlined,
|
||||
ReloadOutlined,
|
||||
} from '@ant-design/icons';
|
||||
} from '../icons';
|
||||
import {
|
||||
fetchCluster,
|
||||
createClusterNode,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { Card, Table, Button, Space, Modal, Form, Input, Select, message, Popconfirm, Tabs } from 'antd';
|
||||
import { PlusOutlined, DeleteOutlined, EditOutlined, DownloadOutlined, CheckOutlined, FileTextOutlined } from '@ant-design/icons';
|
||||
import { PlusOutlined, DeleteOutlined, EditOutlined, DownloadOutlined, CheckOutlined, FileTextOutlined } from '../icons';
|
||||
import {
|
||||
fetchProxies, createProxy, updateProxy, deleteProxy,
|
||||
fetchConfigYAML, generateConfig, validateConfigYAML, applyConfigYAML, rollbackConfig,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { useState, useEffect, useRef } from 'react';
|
||||
import { Alert, Button, Card, Descriptions, Modal, Select, Space, Spin, Steps, Typography, message } from 'antd';
|
||||
import { PlayCircleOutlined, StopOutlined, RedoOutlined, DownloadOutlined, RollbackOutlined } from '@ant-design/icons';
|
||||
import { PlayCircleOutlined, StopOutlined, RedoOutlined, DownloadOutlined, RollbackOutlined } from '../icons';
|
||||
import { coreAPI, type CoreStatus, type CoreRelease, type CoreUpdateStatus } from '../api/core';
|
||||
import { isCanceledError } from '../api/client';
|
||||
import { useI18n } from '../i18n';
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { Card, Row, Col, Statistic, Button, Space, Tag, Progress, Typography, message, theme } from 'antd';
|
||||
import { PlayCircleOutlined, StopOutlined, RedoOutlined } from '@ant-design/icons';
|
||||
import { PlayCircleOutlined, StopOutlined, RedoOutlined } from '../icons';
|
||||
import { fetchDashboard, startMihomo, stopMihomo, restartMihomo } from '../api/system';
|
||||
import { isCanceledError } from '../api/client';
|
||||
import { useI18n } from '../i18n';
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import React, { useEffect, useMemo, useRef, useState } from 'react';
|
||||
import { Table, Button, Space, Tag, Modal, Form, Input,
|
||||
InputNumber, Select, Switch, message, Popconfirm, Tooltip, Card, Tabs, Descriptions, Divider, Dropdown, Checkbox, Spin, Alert } from 'antd';
|
||||
import { PlusOutlined, ReloadOutlined, QrcodeOutlined, DeleteOutlined, EditOutlined, CopyOutlined, BranchesOutlined, HistoryOutlined, SaveOutlined, PoweroffOutlined, DiffOutlined, MoreOutlined, SafetyCertificateOutlined } from '@ant-design/icons';
|
||||
import { PlusOutlined, ReloadOutlined, QrcodeOutlined, DeleteOutlined, EditOutlined, CopyOutlined, BranchesOutlined, HistoryOutlined, SaveOutlined, PoweroffOutlined, DiffOutlined, MoreOutlined, SafetyCertificateOutlined } from '../icons';
|
||||
import {
|
||||
fetchListeners, createListener, quickCreateListener, updateListener, deleteListener, reloadListener, exportNodeURI, normalizeId, Listener,
|
||||
} from '../api/nodes';
|
||||
|
||||
@@ -7,7 +7,7 @@ import {
|
||||
BgColorsOutlined,
|
||||
SafetyOutlined,
|
||||
ArrowLeftOutlined,
|
||||
} from '@ant-design/icons';
|
||||
} from '../icons';
|
||||
import { useNavigate, useLocation } from 'react-router-dom';
|
||||
import { login } from '../api/auth';
|
||||
import { useAuthStore } from '../stores/authStore';
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { Card, List, Tag, Button, Space, Empty, Spin, message, theme } from 'antd';
|
||||
import { ReloadOutlined, ClearOutlined } from '@ant-design/icons';
|
||||
import { ReloadOutlined, ClearOutlined } from '../icons';
|
||||
import dayjs from 'dayjs';
|
||||
import client from '../api/client';
|
||||
import { useI18n } from '../i18n';
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { Card, Table, Button, Space, Modal, Form, Input, InputNumber, Select, message, Popconfirm } from 'antd';
|
||||
import { PlusOutlined, DeleteOutlined, SaveOutlined } from '@ant-design/icons';
|
||||
import { PlusOutlined, DeleteOutlined, SaveOutlined } from '../icons';
|
||||
import { fetchGroups, saveGroups, fetchRules, saveRules, GroupEntry } from '../api/routing';
|
||||
import { useI18n } from '../i18n';
|
||||
import useIsMobile from '../hooks/useIsMobile';
|
||||
|
||||
@@ -48,7 +48,7 @@ import {
|
||||
ProfileOutlined,
|
||||
CloudServerOutlined,
|
||||
FieldTimeOutlined,
|
||||
} from '@ant-design/icons';
|
||||
} from '../icons';
|
||||
import {
|
||||
downloadBackup,
|
||||
restoreDatabase,
|
||||
|
||||
@@ -2,7 +2,7 @@ import React, { useCallback, useEffect, useMemo, useState } from 'react';
|
||||
import {
|
||||
Alert, Button, Card, Collapse, Empty, Input, Select, Space, Spin, Tabs, Tag, Typography, message,
|
||||
} from 'antd';
|
||||
import { CopyOutlined, QrcodeOutlined, ReloadOutlined, LinkOutlined } from '@ant-design/icons';
|
||||
import { CopyOutlined, QrcodeOutlined, ReloadOutlined, LinkOutlined } from '../icons';
|
||||
import { useSearchParams } from 'react-router-dom';
|
||||
import { useI18n } from '../i18n';
|
||||
import useIsMobile from '../hooks/useIsMobile';
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { Card, Table, Tag, Space, Statistic, Row, Col, message, Button } from 'antd';
|
||||
import { ReloadOutlined } from '@ant-design/icons';
|
||||
import { ReloadOutlined } from '../icons';
|
||||
import { fetchTrafficStatus, fetchTrafficUsers, fetchConnections, UserTraffic, ConnectionView, TrafficStatus } from '../api/traffic';
|
||||
import { useI18n } from '../i18n';
|
||||
import PageHeader from '../components/PageHeader';
|
||||
|
||||
@@ -3,7 +3,7 @@ import {
|
||||
Card, Table, Button, Space, Modal, Form, Input, Switch, message, Popconfirm, Select, Tag,
|
||||
InputNumber, DatePicker, Progress, Tooltip, Dropdown, Checkbox, Spin,
|
||||
} from 'antd';
|
||||
import { PlusOutlined, DeleteOutlined, EditOutlined, LinkOutlined, ClearOutlined, ShareAltOutlined, CopyOutlined, MoreOutlined, FundOutlined } from '@ant-design/icons';
|
||||
import { PlusOutlined, DeleteOutlined, EditOutlined, LinkOutlined, ClearOutlined, ShareAltOutlined, CopyOutlined, MoreOutlined, FundOutlined } from '../icons';
|
||||
import dayjs from 'dayjs';
|
||||
import {
|
||||
fetchUsers, createUser, updateUser, deleteUser, resetUserTraffic, deleteDepletedUsers, batchUsers,
|
||||
|
||||
@@ -1189,3 +1189,9 @@ html.dark .app-header-bar,
|
||||
padding-bottom: calc(12px + env(safe-area-inset-bottom, 0px)) !important;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes spin {
|
||||
from { transform: rotate(0deg); }
|
||||
to { transform: rotate(360deg); }
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user