diff --git a/examples/max/.umirc.ts b/examples/max/.umirc.ts
index c5b82677e2f9..3dbb892f951d 100644
--- a/examples/max/.umirc.ts
+++ b/examples/max/.umirc.ts
@@ -105,6 +105,6 @@ export default defineConfig({
jsStrategy: 'granularChunks',
},
icons: {
- include: ['local:rice', 'ant-design:fire-twotone'],
+ include: ['local:rice', 'local:logo/umi', 'ant-design:fire-twotone'],
},
});
diff --git a/examples/max/cypress/e2e/smoke.cy.ts b/examples/max/cypress/e2e/smoke.cy.ts
index 3a58770f247e..9f5d7e0622eb 100644
--- a/examples/max/cypress/e2e/smoke.cy.ts
+++ b/examples/max/cypress/e2e/smoke.cy.ts
@@ -65,5 +65,6 @@ describe('Basic Test', () => {
it('display included Icon components', () => {
cy.get('span.local\\:rice');
cy.get('span.ant-design\\:fire-twotone');
+ cy.get('span.local\\:logo\\/umi');
});
});
diff --git a/examples/max/icons/logo/foo/smile.svg b/examples/max/icons/logo/foo/smile.svg
new file mode 100644
index 000000000000..f054c7c034ab
--- /dev/null
+++ b/examples/max/icons/logo/foo/smile.svg
@@ -0,0 +1,10 @@
+
+
\ No newline at end of file
diff --git a/examples/max/icons/logo/umi.svg b/examples/max/icons/logo/umi.svg
new file mode 100644
index 000000000000..1aed42f96a40
--- /dev/null
+++ b/examples/max/icons/logo/umi.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/examples/max/pages/index.tsx b/examples/max/pages/index.tsx
index 8a358988c850..b87298709814 100644
--- a/examples/max/pages/index.tsx
+++ b/examples/max/pages/index.tsx
@@ -13,7 +13,11 @@ import { Button, DatePicker, Input } from 'antd';
import styles from './index.less';
console.log(TestDecorator);
-const icons = ['local:rice', 'ant-design:fire-twotone'];
+const includedIcons = [
+ 'local:rice',
+ 'local:logo/umi',
+ 'ant-design:fire-twotone',
+];
export default function HomePage() {
const { initialState } = useModel('@@initialState');
@@ -45,9 +49,10 @@ export default function HomePage() {
Icons
- {icons.map((i) => (
-
- ))}
+ {includedIcons.map((i) => {
+ return ;
+ })}
+
);
diff --git a/packages/preset-umi/src/features/icons/icons.ts b/packages/preset-umi/src/features/icons/icons.ts
index ab5e2c9d840d..452d43e3b77e 100644
--- a/packages/preset-umi/src/features/icons/icons.ts
+++ b/packages/preset-umi/src/features/icons/icons.ts
@@ -3,6 +3,7 @@ import {
importLazy,
installWithNpmClient,
logger,
+ winPath,
} from '@umijs/utils';
import fs from 'fs';
import path from 'path';
@@ -135,10 +136,10 @@ export default (api: IApi) => {
}
const localIconDir = getLocalIconDir();
const localIcons: string[] = [];
+
if (fs.existsSync(localIconDir)) {
localIcons.push(
- ...fs
- .readdirSync(localIconDir)
+ ...readIconsFromDir(localIconDir)
.filter((file) => file.endsWith('.svg'))
.map((file) => file.replace(/\.svg$/, '')),
);
@@ -380,7 +381,7 @@ function normalizeRotate(rotate: number | string) {
}
function camelCase(str: string) {
- return str.replace(/-([a-z]|[1-9])/g, (g) => g[1].toUpperCase());
+ return str.replace(/\\//g, '-').replace(/-([a-z]|[1-9])/g, (g) => g[1].toUpperCase());
}
function normalizeIconName(name: string) {
@@ -430,3 +431,23 @@ function normalizeIconName(name: string) {
return path.join(api.paths.absSrcPath, 'icons');
}
};
+
+function readIconsFromDir(dir: string) {
+ const icons: string[] = [];
+ const prefix = winPath(path.join(dir, './'));
+
+ const collect = (p: string) => {
+ if (fs.statSync(p).isDirectory()) {
+ const files = fs.readdirSync(p);
+ files.forEach((name) => {
+ collect(path.join(p, name));
+ });
+ } else {
+ const prunePath = winPath(p).replace(prefix, '');
+ icons.push(prunePath);
+ }
+ };
+ collect(dir);
+
+ return icons;
+}
diff --git a/packages/preset-umi/src/features/icons/svgr.ts b/packages/preset-umi/src/features/icons/svgr.ts
index 9455507de70e..7c01e13e2abe 100644
--- a/packages/preset-umi/src/features/icons/svgr.ts
+++ b/packages/preset-umi/src/features/icons/svgr.ts
@@ -5,7 +5,9 @@ import type { IApi } from '../../types';
import { loadIcon } from './loadIcon';
function camelCase(str: string) {
- return str.replace(/-([a-z]|[0-9])/g, (g) => g[1].toUpperCase());
+ return str
+ .replace(/\//g, '-')
+ .replace(/-([a-z]|[0-9])/g, (g) => g[1].toUpperCase());
}
export function generateIconName(opts: { collect: string; icon: string }) {