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 @@ + + + smile + + + + + + + \ 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 }) {