8000 feat(arco): add iconPrefix option for arco resolver (#516) · reslear/unplugin-vue-components@6b25075 · GitHub
[go: up one dir, main page]

Skip to content

Commit 6b25075

Browse files
authored
feat(arco): add iconPrefix option for arco resolver (unplugin#516)
1 parent 5aafb35 commit 6b25075

File tree

2 files changed

+82
-6
lines changed

2 files changed

+82
-6
lines changed

src/core/resolvers/arco.ts

Lines changed: 41 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
1+
import Debug from 'debug'
12
import type { ComponentInfo, ComponentResolver } from '../../types'
2-
import { kebabCase } from '../utils'
3+
import { kebabCase, pascalCase } from '../utils'
4+
const debug = Debug('unplugin-vue-components:resolvers:arco')
35

46
const matchComponents = [
57
{
@@ -139,6 +141,31 @@ function getComponentStyleDir(importName: string, importStyle: boolean | 'css' |
139141
return `@arco-design/web-vue/es/${componentDir}/style/css.js`
140142
}
141143

144+
function canResolveIcons(options?: ResolveIconsOption): options is AllowResolveIconOption {
145+
if (options === undefined)
146+
return false
147+
if (typeof options === 'boolean')
148+
return options
149+
else
150+
return options.enable
151+
}
152+
153+
function getResolveIconPrefix(options?: ResolveIconsOption) {
154+
if (canResolveIcons(options)) {
155+
if (typeof options === 'boolean' && options)
156+
return ''
157+
else if (options.enable)
158+
return options.iconPrefix ?? ''
159+
else
160+
return ''
161+
}
162+
return ''
163+
}
164+
165+
export type DisallowResolveIconOption = undefined | false | { enable: false }
166+
export type AllowResolveIconOption = true | { enable: true; iconPrefix?: string }
167+
export type ResolveIconsOption = DisallowResolveIconOption | AllowResolveIconOption
168+
142169
export interface ArcoResolverOptions {
143170
/**
144171
* import style css or less with components
@@ -151,7 +178,7 @@ export interface ArcoResolverOptions {
151178
*
152179
* @default false
153180
*/
154-
resolveIcons?: boolean
181+
resolveIcons?: ResolveIconsOption
155182
/**
156183
* Control style automatic import
157184
*
@@ -175,10 +202,18 @@ export function ArcoResolver(
175202
return {
176203
type: 'component',
177204
resolve: (name: string) => {
178-
if (options.resolveIcons && name.match(/^Icon/)) {
179-
return {
180-
name,
181-
from: '@arco-design/web-vue/es/icon',
205+
if (canResolveIcons(options.resolveIcons)) {
206+
const iconPrefix = pascalCase(getResolveIconPrefix(options.resolveIcons))
207+
const newNameRegexp = new RegExp(`^${iconPrefix}Icon`)
208+
if (newNameRegexp.test(name)) {
209+
debug('found icon component name %s', name)
210+
const rawComponentName = name.slice(iconPrefix.length)
211+
debug('found icon component raw name %s', rawComponentName)
212+
return {
213+
name: rawComponentName,
214+
as: name,
215+
from: '@arco-design/web-vue/es/icon',
216+
}
182217
}
183218
}
184219
if (name.match(/^A[A-Z]/)) {

test/resolvers/arco.test.ts

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import { describe, expect, test } from 'vitest'
2+
import { ArcoResolver } from '../../src/resolvers'
3+
4+
import type { ComponentResolveResult, ComponentResolverObject } from '../../src'
5+
6+
function testNoIconComponentResolve(resolver: ComponentResolverObject) {
7+
expect(resolver.resolve('AButton')).toEqual<ComponentResolveResult>({
8+
name: 'Button',
9+
from: '@arco-design/web-vue',
10+
sideEffects: '@arco-design/web-vue/es/button/style/css.js',
11+
})
12+
}
13+
14+
describe('ArcoResolver', () => {
15+
test('Resolve component except icon', async () => {
16+
const resolver = ArcoResolver() as ComponentResolverObject
17+
expect(typeof resolver).toEqual('object')
18+
testNoIconComponentResolve(resolver)
19+
expect(resolver.resolve('IconStar')).toBeFalsy()
20+
})
21+
22+
test('Can resolve icon component', () => {
23+
const resolver = ArcoResolver({ resolveIcons: true }) as ComponentResolverObject
24+
testNoIconComponentResolve(resolver)
25+
expect(resolver.resolve('IconStar')).toEqual<ComponentResolveResult>({
26+
name: 'IconStar',
27+
from: '@arco-design/web-vue/es/icon',
28+
as: 'IconStar',
29+
})
30+
})
31+
32+
test('Can resolve icon component with custom icon prefix', () => {
33+
const resolver = ArcoResolver({ resolveIcons: { enable: true, iconPrefix: 'arco' } }) as ComponentResolverObject
34+
testNoIconComponentResolve(resolver)
35+
expect(resolver.resolve('ArcoIconStar')).toEqual<ComponentResolveResult>({
36+
name: 'IconStar',
37+
from: '@arco-design/web-vue/es/icon',
38+
as: 'ArcoIconStar',
39+
})
40+
})
41+
})

0 commit comments

Comments
 (0)
0