From f5318d7971020326c674b75450d228dc1e11e748 Mon Sep 17 00:00:00 2001
From: DonovanYe <72693206+Donovan-Ye@users.noreply.github.com>
Date: Fri, 12 Jul 2024 13:57:41 +0800
Subject: [PATCH] feat(plugins): icons enhanced feature can be used for layout
menu (#12515)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
* feat(max/layout): 支持菜单图标使用图标集或者本地图标
* refactor(max/layout): 根据icons功能是否开启动态插入菜单项使用icons功能的代码
* refactor(layout/max): 使用api.isPluginEnable判断是否开启了icons功能
* docs(layout-menu): 更新layout中菜单icon相关的文档
* docs(layout-menu): 修改菜单icon说明中的绝对路径为相对路径
---
docs/docs/docs/max/layout-menu.md | 2 ++
examples/max/.umirc.ts | 5 +++--
examples/max/package.json | 2 ++
examples/max/pages/index.tsx | 7 ++++++-
packages/plugins/src/layout.ts | 17 +++++++++++++++++
.../preset-umi/src/features/icons/icons.ts | 8 ++++++--
pnpm-lock.yaml | 18 ++++++++++++++++++
7 files changed, 54 insertions(+), 5 deletions(-)
diff --git a/docs/docs/docs/max/layout-menu.md b/docs/docs/docs/max/layout-menu.md
index 4eeb39e25f97..fdcd1f0d2f25 100644
--- a/docs/docs/docs/max/layout-menu.md
+++ b/docs/docs/docs/max/layout-menu.md
@@ -191,6 +191,8 @@ icon: 'HomeFilled';
icon: 'HomeTwoTone';
```
+兼容[icons](../../docs/api/config#icons)功能,打开icons功能后,可以使用图标集或者本地的图标。具体请参考icons功能的相关配置和使用方法。
+
#### access
- Type: `string`
diff --git a/examples/max/.umirc.ts b/examples/max/.umirc.ts
index 3dbb892f951d..3ff7983d7f4c 100644
--- a/examples/max/.umirc.ts
+++ b/examples/max/.umirc.ts
@@ -5,13 +5,13 @@ export default defineConfig({
{
title: 'site.title',
path: '/',
- icon: 'PlaySquareFilled',
+ icon: 'ic:baseline-14mp',
component: 'index',
name: 'index',
},
{
path: '/users',
- icon: 'SmileFilled',
+ icon: 'local:rice',
component: 'users',
name: 'users',
wrappers: ['@/wrappers/foo', '@/wrappers/bar'],
@@ -105,6 +105,7 @@ export default defineConfig({
jsStrategy: 'granularChunks',
},
icons: {
+ autoInstall: {},
include: ['local:rice', 'local:logo/umi', 'ant-design:fire-twotone'],
},
});
diff --git a/examples/max/package.json b/examples/max/package.json
index 653719fb1333..3f03f810cb20 100644
--- a/examples/max/package.json
+++ b/examples/max/package.json
@@ -23,6 +23,8 @@
"react-dom": "18.3.1"
},
"devDependencies": {
+ "@iconify-json/ic": "1.1.17",
+ "@iconify-json/solar": "1.1.9",
"cross-env": "^7.0.3",
"cypress": "^12.0.0",
"start-server-and-test": "^1.15.2",
diff --git a/examples/max/pages/index.tsx b/examples/max/pages/index.tsx
index 5ba558d16b57..92f0e51c91c0 100644
--- a/examples/max/pages/index.tsx
+++ b/examples/max/pages/index.tsx
@@ -54,7 +54,12 @@ export default function HomePage() {
tailwindcss
-
Icons
+ Icon library icons
+
+
+
+
+ Local Icons
{includedIcons.map((i) => {
return ;
diff --git a/packages/plugins/src/layout.ts b/packages/plugins/src/layout.ts
index 0a711ac4fdfa..b9498500d245 100644
--- a/packages/plugins/src/layout.ts
+++ b/packages/plugins/src/layout.ts
@@ -423,12 +423,19 @@ export default { ${icons.join(', ')} };
`,
});
+ // 是否启用了 icons 功能
+ const isIconsFeatureEnable = api.isPluginEnable('icons');
// runtime.tsx
api.writeTmpFile({
path: 'runtime.tsx',
content: `
import React from 'react';
import icons from './icons';
+${
+ isIconsFeatureEnable
+ ? `import { Icon, getIconComponent } from '@umijs/max';`
+ : ''
+}
function formatIcon(name: string) {
return name
@@ -442,6 +449,16 @@ export function patchRoutes({ routes }) {
Object.keys(routes).forEach(key => {
const { icon } = routes[key];
if (icon && typeof icon === 'string') {
+ ${
+ isIconsFeatureEnable
+ ? `const Component = getIconComponent(icon)
+ if (Component) {
+ routes[key].icon = ;
+ return;
+ }`
+ : ''
+ }
+
const upperIcon = formatIcon(icon);
if (icons[upperIcon] || icons[upperIcon + 'Outlined']) {
routes[key].icon = React.createElement(icons[upperIcon] || icons[upperIcon + 'Outlined']);
diff --git a/packages/preset-umi/src/features/icons/icons.ts b/packages/preset-umi/src/features/icons/icons.ts
index fc4e87668a96..531c98df15d5 100644
--- a/packages/preset-umi/src/features/icons/icons.ts
+++ b/packages/preset-umi/src/features/icons/icons.ts
@@ -322,10 +322,14 @@ interface IUmiIconProps extends React.SVGAttributes {
flip?: 'vertical' | 'horizontal' | 'horizontal,vertical' | 'vertical,horizontal';
}
+export const getIconComponent = (icon: Pick) => {
+ const iconName = normalizeIconName(alias[icon] || icon);
+ return iconsMap[iconName];
+}
+
export const Icon = React.forwardRef((props, ref) => {
const { icon, hover, style, className = '' , rotate, spin, flip, ...extraProps } = props;
- const iconName = normalizeIconName(alias[icon] || icon);
- const Component = iconsMap[iconName];
+ const Component = getIconComponent(icon);
if (!Component) {
// TODO: give a error icon when dev, to help developer find the error
return null;
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 7c10a3ef449f..28f2a28013cf 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -737,6 +737,12 @@ importers:
specifier: 18.3.1
version: 18.3.1(react@18.3.1)
devDependencies:
+ '@iconify-json/ic':
+ specifier: 1.1.17
+ version: 1.1.17
+ '@iconify-json/solar':
+ specifier: 1.1.9
+ version: 1.1.9
cross-env:
specifier: ^7.0.3
version: 7.0.3
@@ -13799,6 +13805,18 @@ packages:
'@iconify/types': 2.0.0
dev: true
+ /@iconify-json/ic@1.1.17:
+ resolution: {integrity: sha512-EvAjZzVESmN36zlyefylePUNaU2BQ3eRKVZ6KQSQ2bG01ppoZaiFZRri74VTyvp5Mlv2yn68ux1fgCoT+etGmA==}
+ dependencies:
+ '@iconify/types': 2.0.0
+ dev: true
+
+ /@iconify-json/solar@1.1.9:
+ resolution: {integrity: sha512-BcWzZqA02BiQduYizqU/J4v4RNs0MkjZUGpMbejpozH8YQSt3+S/LfV6zfVRonx/2DhXTVSqiLa1abDRAZtojQ==}
+ dependencies:
+ '@iconify/types': 2.0.0
+ dev: true
+
/@iconify/types@1.1.0:
resolution: {integrity: sha512-Jh0llaK2LRXQoYsorIH8maClebsnzTcve+7U3rQUSnC11X4jtPnFuyatqFLvMxZ8MLG8dB4zfHsbPfuvxluONw==}
dev: false