Skip to content

Commit d398fbf

Browse files
authored
feat(resolver): add resolver for layui-vue (#366)
* feat(resolver): add resolver for layui-vue * fix: fix lint
1 parent a1d2694 commit d398fbf

File tree

2 files changed

+172
-0
lines changed

2 files changed

+172
-0
lines changed

src/core/resolvers/index.ts

+1
Original file line numberDiff line numberDiff line change
@@ -16,3 +16,4 @@ export * from './quasar'
1616
export * from './devui'
1717
export * from './arco'
1818
export * from './tdesign'
19+
export * from './layui-vue'

src/core/resolvers/layui-vue.ts

+171
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,171 @@
1+
import type { ComponentInfo, ComponentResolver, SideEffectsInfo } from '../../types'
2+
import { camelCase } from '../utils'
3+
4+
const matchComponents = [
5+
{
6+
pattern: /^LayAvatarList$/,
7+
styleDir: 'avatar',
8+
},
9+
{
10+
pattern: /^LayBreadcrumbItem$/,
11+
styleDir: 'breadcrumb',
12+
},
13+
{
14+
pattern: /^(LayCarouselItem)$/,
15+
styleDir: 'carousel',
16+
},
17+
{
18+
pattern: /^(LayCheckboxGroup)$/,
19+
styleDir: 'checkbox',
20+
},
21+
{
22+
pattern: /^LayCol$/,
23+
styleDir: 'row',
24+
},
25+
{
26+
pattern: /^(LayCollapseItem)$/,
27+
styleDir: 'collapse',
28+
},
29+
{
30+
pattern: /^LayConfigProvider$/,
31+
styleDir: undefined,
32+
},
33+
{
34+
pattern: /^LayCountUp$/,
35+
styleDir: undefined,
36+
},
37+
{
38+
pattern: /^(LayDropdownMenu|LayDropdownMenuItem)$/,
39+
styleDir: 'dropdown',
40+
},
41+
{
42+
pattern: /^(LayFormItem)$/,
43+
styleDir: 'form',
44+
},
45+
{
46+
pattern: /^(LayMenuItem|LaySubMenu)$/,
47+
styleDir: 'menu',
48+
},
49+
{
50+
pattern: /^LaySelectOption$/,
51+
styleDir: 'select',
52+
},
53+
{
54+
pattern: /^LaySkeletonItem$/,
55+
styleDir: 'skeleton',
56+
},
57+
{
58+
pattern: /^LaySplitPanelItem$/,
59+
styleDir: 'splitPanel',
60+
},
61+
{
62+
pattern: /^LayStepItem$/,
63+
styleDir: 'step',
64+
},
65+
{
66+
pattern: /^(LayTabItem)$/,
67+
styleDir: 'tab',
68+
},
69+
{
70+
pattern: /^LayTimelineItem$/,
71+
styleDir: 'timeline',
72+
},
73+
]
74+
75+
export interface LayuiVueResolverOptions {
76+
/**
77+
* import style along with components
78+
*
79+
* @default 'css'
80+
*/
81+
importStyle?: boolean | 'css'
82+
83+
/**
84+
* resolve '@layui/layui-vue' icons
85+
* requires package `@layui/icons-vue`
86+
*
87+
* @default false
88+
*/
89+
resolveIcons?: boolean
90+
91+
/**
92+
* exclude components that do not require automatic import
93+
*
94+
*/
95+
exclude?: Array<string | RegExp>
96+
}
97+
98+
const layuiRE = /^Lay[A-Z]/
99+
const layerRE = /^(layer|LayLayer)$/
100+
const iconsRE = /^([A-Z][\w]+Icon|LayIcon)$/
101+
let libName = '@layui/layui-vue'
102+
103+
function getSideEffects(importName: string, options: LayuiVueResolverOptions): SideEffectsInfo | undefined {
104+
const { importStyle = 'css' } = options
105+
if (!importStyle)
106+
return undefined
107+
108+
if (libName !== '@layui/layui-vue')
109+
return `${libName}/lib/index.css`
110+
111+
let styleDir: string | undefined = camelCase(importName.slice(3)) // LayBackTop -> backTop
112+
for (const item of matchComponents) {
113+
if (item.pattern.test(importName)) {
114+
styleDir = item.styleDir
115+
break
116+
}
117+
}
118+
if (importStyle === 'css' || importStyle) {
119+
return styleDir
120+
? [`@layui/layui-vue/es/${styleDir}/index.css`, '@layui/layui-vue/es/index/index.css']
121+
: undefined
122+
}
123+
}
124+
125+
function resolveComponent(importName: string, options: LayuiVueResolverOptions): ComponentInfo | undefined {
126+
let name: string | undefined
127+
128+
if (options.exclude && isExclude(importName, options.exclude))
129+
return undefined
130+
131+
if (options.resolveIcons && importName.match(iconsRE)) {
132+
name = importName
133+
libName = '@layui/icons-vue'
134+
}
135+
else if (importName.match(layerRE)) {
136+
name = importName
137+
libName = '@layui/layer-vue'
138+
}
139+
else if (importName.match(layuiRE)) {
140+
name = importName
141+
libName = '@layui/layui-vue'
142+
}
143+
return name
144+
? { name, from: libName, sideEffects: getSideEffects(name, options) }
145+
: undefined
146+
}
147+
148+
function isExclude(name: string, exclude: Array<string | RegExp>): boolean {
149+
for (const item of exclude) {
150+
if (name === item || name.match(item))
151+
return true
152+
}
153+
return false
154+
}
155+
156+
/**
157+
* Resolver for layui-vue
158+
*
159+
* @link http://www.layui-vue.com/ for layui-vue
160+
*
161+
*/
162+
export function LayuiVueResolver(
163+
options: LayuiVueResolverOptions = {},
164+
): ComponentResolver {
165+
return {
166+
type: 'component',
167+
resolve: (name: string) => {
168+
return resolveComponent(name, options)
169+
},
170+
}
171+
}

0 commit comments

Comments
 (0)