@cuipengyu5/build-plugin-lowcode 0.0.1 → 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +47 -0
- package/package.json +2 -2
- package/src/compile/babel.js +198 -0
- package/src/compile/meta.js +87 -0
- package/src/config/user-config.js +71 -0
- package/src/constants.js +135 -0
- package/src/public/designer.html +302 -0
- package/src/public/index.html +308 -0
- package/src/public/preview.html +38 -0
- package/src/templates/assets.json +31 -0
- package/src/templates/component-meta.js +11 -0
- package/src/templates/index.jsx +273 -0
- package/src/templates/meta.js +168 -0
- package/src/templates/preview.jsx +93 -0
- package/src/templates/view.js +24 -0
- package/src/utils/getDemoDir.js +16 -0
- package/src/utils/index.js +252 -0
- package/src/utils/npm.js +41 -0
- package/src/utils/parse-props.js +261 -0
- package/demo/antd-setter-map/src/index.tsx +0 -5
- package/demo/component/src/index.tsx +0 -6
|
@@ -0,0 +1,252 @@
|
|
|
1
|
+
const _ = require('lodash');
|
|
2
|
+
const path = require('path');
|
|
3
|
+
const fse = require('fs-extra');
|
|
4
|
+
const hbs = require('handlebars');
|
|
5
|
+
const glob = require('glob');
|
|
6
|
+
const parseProps = require('./parse-props');
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* @description generate js file as webpack entry
|
|
10
|
+
* @param {String} template template path
|
|
11
|
+
* @param {String} filename
|
|
12
|
+
* @param {String} rootDir
|
|
13
|
+
* @param {Object} params params for compile template content
|
|
14
|
+
* @returns {String} path of entry file
|
|
15
|
+
*/
|
|
16
|
+
function generateEntry({ template, filename = 'index.js', rootDir = process.cwd(), params, tmpDirName = '.tmp' }) {
|
|
17
|
+
const hbsTemplatePath = path.join(__dirname, `../templates/${template}`);
|
|
18
|
+
const hbsTemplateContent = fse.readFileSync(hbsTemplatePath, 'utf-8');
|
|
19
|
+
const compileTemplateContent = hbs.compile(hbsTemplateContent);
|
|
20
|
+
|
|
21
|
+
const tempDir = path.join(rootDir, tmpDirName);
|
|
22
|
+
const jsPath = path.join(tempDir, filename);
|
|
23
|
+
|
|
24
|
+
const jsTemplateContent = compileTemplateContent(params);
|
|
25
|
+
fse.outputFileSync(jsPath, jsTemplateContent);
|
|
26
|
+
|
|
27
|
+
return jsPath;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function parseNpmName(npmName) {
|
|
31
|
+
if (typeof npmName !== 'string') {
|
|
32
|
+
throw new TypeError('Expected a string');
|
|
33
|
+
}
|
|
34
|
+
const matched =
|
|
35
|
+
npmName.charAt(0) === '@' ? /(@[^\/]+)\/(.+)/g.exec(npmName) : [npmName, '', npmName];
|
|
36
|
+
if (!matched) {
|
|
37
|
+
throw new Error(`[parse-package-name] "${npmName}" is not a valid string`);
|
|
38
|
+
}
|
|
39
|
+
const scope = matched[1];
|
|
40
|
+
const name = (matched[2] || '').replace(/\s+/g, '').replace(/[\-_]+([^\-_])/g, ($0, $1) => {
|
|
41
|
+
return $1.toUpperCase();
|
|
42
|
+
});
|
|
43
|
+
const uniqueName =
|
|
44
|
+
(matched[1]
|
|
45
|
+
? matched[1].charAt(1).toUpperCase() +
|
|
46
|
+
matched[1].slice(2).replace(/[\-_]+([^\-_])/g, ($0, $1) => {
|
|
47
|
+
return $1.toUpperCase();
|
|
48
|
+
})
|
|
49
|
+
: '') +
|
|
50
|
+
name.charAt(0).toUpperCase() +
|
|
51
|
+
name.slice(1);
|
|
52
|
+
return {
|
|
53
|
+
scope,
|
|
54
|
+
name,
|
|
55
|
+
uniqueName,
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
function camel2KebabComponentName(camel) {
|
|
60
|
+
return camel
|
|
61
|
+
.replace(/[A-Z]/g, (item) => {
|
|
62
|
+
return `-${item.toLowerCase()}`;
|
|
63
|
+
})
|
|
64
|
+
.replace(/^\-/, '');
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
function kebab2CamelComponentName(kebab) {
|
|
68
|
+
const camel = kebab.charAt(0).toUpperCase() + kebab.substr(1);
|
|
69
|
+
return camel.replace(/-([a-z])/g, (keb, item) => {
|
|
70
|
+
return item.toUpperCase();
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
function generateComponentList(components) {
|
|
75
|
+
const componentList = [
|
|
76
|
+
{
|
|
77
|
+
title: '常用',
|
|
78
|
+
icon: '',
|
|
79
|
+
children: [],
|
|
80
|
+
},
|
|
81
|
+
{
|
|
82
|
+
title: '容器',
|
|
83
|
+
icon: '',
|
|
84
|
+
children: [],
|
|
85
|
+
},
|
|
86
|
+
{
|
|
87
|
+
title: '导航',
|
|
88
|
+
icon: '',
|
|
89
|
+
children: [],
|
|
90
|
+
},
|
|
91
|
+
{
|
|
92
|
+
title: '内容',
|
|
93
|
+
icon: '',
|
|
94
|
+
children: [],
|
|
95
|
+
},
|
|
96
|
+
{
|
|
97
|
+
title: 'Feedback 反馈',
|
|
98
|
+
icon: '',
|
|
99
|
+
children: [],
|
|
100
|
+
},
|
|
101
|
+
];
|
|
102
|
+
|
|
103
|
+
components.forEach((comp) => {
|
|
104
|
+
const category = comp.category || '其他';
|
|
105
|
+
let target = componentList.find((item) => item.title === category);
|
|
106
|
+
if (!target) {
|
|
107
|
+
target = {
|
|
108
|
+
title: category,
|
|
109
|
+
icon: '',
|
|
110
|
+
children: [],
|
|
111
|
+
};
|
|
112
|
+
|
|
113
|
+
componentList.push(target);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
if (comp.snippets) {
|
|
117
|
+
target.children.push({
|
|
118
|
+
componentName: comp.componentName,
|
|
119
|
+
title: comp.title || comp.componentName,
|
|
120
|
+
icon: '',
|
|
121
|
+
package: comp.npm.pkg,
|
|
122
|
+
snippets: comp.snippets || [],
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
});
|
|
126
|
+
return componentList;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
function replacer(key, value) {
|
|
130
|
+
if (typeof value === 'function') {
|
|
131
|
+
return {
|
|
132
|
+
type: 'JSFunction',
|
|
133
|
+
value: String(value),
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
return value;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
function isAsyncFunction(fn) {
|
|
140
|
+
return fn[Symbol.toStringTag] === 'AsyncFunction';
|
|
141
|
+
}
|
|
142
|
+
function reviewer(key, value) {
|
|
143
|
+
if (!value) {
|
|
144
|
+
return value;
|
|
145
|
+
}
|
|
146
|
+
if (key === 'icon') {
|
|
147
|
+
if (typeof value === 'object') {
|
|
148
|
+
return {
|
|
149
|
+
type: 'smile',
|
|
150
|
+
size: 'small',
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
if (typeof value === 'object') {
|
|
155
|
+
if (value.type === 'JSFunction') {
|
|
156
|
+
let _value = value.value && value.value.trim();
|
|
157
|
+
let template = `
|
|
158
|
+
return function lowcode() {
|
|
159
|
+
const self = this;
|
|
160
|
+
try {
|
|
161
|
+
return (${_value}).apply(self, arguments);
|
|
162
|
+
} catch(e) {
|
|
163
|
+
console.log('call function which parsed by lowcode for key ${key} failed: ', e);
|
|
164
|
+
return e.message;
|
|
165
|
+
}
|
|
166
|
+
};`;
|
|
167
|
+
try {
|
|
168
|
+
return Function(template)();
|
|
169
|
+
} catch (e) {
|
|
170
|
+
if (e && e.message.includes("Unexpected token '{'")) {
|
|
171
|
+
console.log('method need add funtion prefix');
|
|
172
|
+
_value = `function ${_value}`;
|
|
173
|
+
template = `
|
|
174
|
+
return function lowcode() {
|
|
175
|
+
const self = this;
|
|
176
|
+
try {
|
|
177
|
+
return (${_value}).apply(self, arguments);
|
|
178
|
+
} catch(e) {
|
|
179
|
+
console.log('call function which parsed by lowcode for key ${key} failed: ', e);
|
|
180
|
+
return e.message;
|
|
181
|
+
}
|
|
182
|
+
};`;
|
|
183
|
+
return Function(template)();
|
|
184
|
+
}
|
|
185
|
+
console.error('parse lowcode function error: ', e);
|
|
186
|
+
console.error(value);
|
|
187
|
+
return value;
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
return value;
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
function toJson(object, replacer) {
|
|
195
|
+
return JSON.stringify(object, replacer || this.replacer, 2);
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
function parseJson(json) {
|
|
199
|
+
const input = typeof json === 'string' ? json : JSON.stringify(json);
|
|
200
|
+
return JSON.parse(input, this.reviewer);
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
function asyncDebounce(func, wait) {
|
|
204
|
+
const debounced = _.debounce(async (resolve, reject, bindSelf, args) => {
|
|
205
|
+
try {
|
|
206
|
+
const result = await func.bind(bindSelf)(...args);
|
|
207
|
+
resolve(result);
|
|
208
|
+
} catch (error) {
|
|
209
|
+
reject(error);
|
|
210
|
+
}
|
|
211
|
+
}, wait);
|
|
212
|
+
|
|
213
|
+
// This is the function that will be bound by the caller, so it must contain the `function` keyword.
|
|
214
|
+
function returnFunc(...args) {
|
|
215
|
+
return new Promise((resolve, reject) => {
|
|
216
|
+
debounced(resolve, reject, this, args);
|
|
217
|
+
});
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
return returnFunc;
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
function getUsedComponentMetas(rootDir, lowcodeDir = 'lowcode', metaFilename, components) {
|
|
224
|
+
let metaPaths = glob.sync(
|
|
225
|
+
path.resolve(rootDir, `${lowcodeDir}/**/${metaFilename}.@(js|ts|jsx|tsx)`),
|
|
226
|
+
);
|
|
227
|
+
if (metaPaths && metaPaths.length) {
|
|
228
|
+
metaPaths = metaPaths.map((item) => {
|
|
229
|
+
return item.slice(
|
|
230
|
+
path.resolve(rootDir, lowcodeDir).length + 1,
|
|
231
|
+
item.lastIndexOf(metaFilename) - 1,
|
|
232
|
+
);
|
|
233
|
+
});
|
|
234
|
+
}
|
|
235
|
+
return components
|
|
236
|
+
? components.filter((component) => {
|
|
237
|
+
return metaPaths.includes(camel2KebabComponentName(component));
|
|
238
|
+
})
|
|
239
|
+
: metaPaths.map((dir) => kebab2CamelComponentName(dir));
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
module.exports = {
|
|
243
|
+
toJson,
|
|
244
|
+
parseProps,
|
|
245
|
+
parseNpmName,
|
|
246
|
+
generateEntry,
|
|
247
|
+
asyncDebounce,
|
|
248
|
+
generateComponentList,
|
|
249
|
+
camel2KebabComponentName,
|
|
250
|
+
kebab2CamelComponentName,
|
|
251
|
+
getUsedComponentMetas,
|
|
252
|
+
};
|
package/src/utils/npm.js
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
const path = require('path');
|
|
2
|
+
const { pathExists } = require('fs-extra');
|
|
3
|
+
const spawn = require('cross-spawn-promise');
|
|
4
|
+
|
|
5
|
+
async function isNPMInstalled(args) {
|
|
6
|
+
return pathExists(path.join(args.workDir, 'node_modules'));
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
async function install(args) {
|
|
10
|
+
if (await isNPMInstalled(args)) return;
|
|
11
|
+
const { workDir, npmClient = 'tnpm' } = args;
|
|
12
|
+
try {
|
|
13
|
+
await spawn(npmClient, ['i'], { stdio: 'inherit', cwd: workDir });
|
|
14
|
+
} catch (e) {
|
|
15
|
+
// TODO
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
async function isNPMModuleInstalled(args, name) {
|
|
20
|
+
const modulePkgJsonPath = path.resolve(args.workDir || '', 'node_modules', name, 'package.json');
|
|
21
|
+
return pathExists(modulePkgJsonPath);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
async function installModule(args, name) {
|
|
25
|
+
if (await isNPMModuleInstalled(args, name)) return;
|
|
26
|
+
const { workDir, npmClient = 'tnpm' } = args;
|
|
27
|
+
try {
|
|
28
|
+
await spawn(npmClient, [
|
|
29
|
+
'i',
|
|
30
|
+
name,
|
|
31
|
+
npmClient === 'npm' ? '--registry=https://registry.npmmirror.com' : ''
|
|
32
|
+
], { stdio: 'inherit', cwd: workDir });
|
|
33
|
+
} catch (e) {
|
|
34
|
+
// TODO
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
module.exports = {
|
|
39
|
+
installModule,
|
|
40
|
+
install,
|
|
41
|
+
};
|
|
@@ -0,0 +1,261 @@
|
|
|
1
|
+
function propConfigToFieldConfig(propConfig) {
|
|
2
|
+
const { name, description } = propConfig;
|
|
3
|
+
const title = {
|
|
4
|
+
label: {
|
|
5
|
+
type: 'i18n',
|
|
6
|
+
'en-US': name,
|
|
7
|
+
'zh-CN': (description && description.slice(0, 10)) || name,
|
|
8
|
+
},
|
|
9
|
+
tip: description ? `${name} | ${description}` : undefined,
|
|
10
|
+
};
|
|
11
|
+
const setter = propConfig.setter ? propConfig.setter : propTypeToSetter(propConfig.propType);
|
|
12
|
+
delete propConfig.propType;
|
|
13
|
+
return {
|
|
14
|
+
title,
|
|
15
|
+
...propConfig,
|
|
16
|
+
// TODO 这边直接用propConfig,将setter丢在propconfig里,需要确认是否在PropConfig扩展还是换实现
|
|
17
|
+
setter,
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
function propTypeToSetter(propType) {
|
|
22
|
+
let typeName;
|
|
23
|
+
let isRequired = false;
|
|
24
|
+
if (typeof propType === 'string') {
|
|
25
|
+
typeName = propType;
|
|
26
|
+
} else if (typeof propType === 'object') {
|
|
27
|
+
typeName = propType.type;
|
|
28
|
+
isRequired = propType.isRequired;
|
|
29
|
+
} else {
|
|
30
|
+
typeName = 'string';
|
|
31
|
+
}
|
|
32
|
+
// TODO: use mixinSetter wrapper
|
|
33
|
+
switch (typeName) {
|
|
34
|
+
case 'string':
|
|
35
|
+
return {
|
|
36
|
+
componentName: 'StringSetter',
|
|
37
|
+
isRequired,
|
|
38
|
+
initialValue: '',
|
|
39
|
+
};
|
|
40
|
+
case 'number':
|
|
41
|
+
return {
|
|
42
|
+
componentName: 'NumberSetter',
|
|
43
|
+
isRequired,
|
|
44
|
+
initialValue: 0,
|
|
45
|
+
};
|
|
46
|
+
case 'bool':
|
|
47
|
+
return {
|
|
48
|
+
componentName: 'BoolSetter',
|
|
49
|
+
isRequired,
|
|
50
|
+
initialValue: false,
|
|
51
|
+
};
|
|
52
|
+
case 'oneOf':
|
|
53
|
+
const dataSource = (propType.value || []).map((value, index) => {
|
|
54
|
+
const t = typeof value;
|
|
55
|
+
return {
|
|
56
|
+
label:
|
|
57
|
+
t === 'string' || t === 'number' || t === 'boolean' ? String(value) : `value ${index}`,
|
|
58
|
+
value,
|
|
59
|
+
};
|
|
60
|
+
});
|
|
61
|
+
const componentName = dataSource.length >= 4 ? 'SelectSetter' : 'RadioGroupSetter';
|
|
62
|
+
return {
|
|
63
|
+
componentName,
|
|
64
|
+
props: { dataSource, options: dataSource },
|
|
65
|
+
isRequired,
|
|
66
|
+
initialValue: dataSource[0] ? dataSource[0].value : null,
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
case 'element':
|
|
70
|
+
case 'node': // TODO: use Mixin
|
|
71
|
+
return {
|
|
72
|
+
// slotSetter
|
|
73
|
+
componentName: 'SlotSetter',
|
|
74
|
+
props: {
|
|
75
|
+
mode: typeName,
|
|
76
|
+
},
|
|
77
|
+
isRequired,
|
|
78
|
+
initialValue: {
|
|
79
|
+
type: 'JSSlot',
|
|
80
|
+
value: [],
|
|
81
|
+
},
|
|
82
|
+
};
|
|
83
|
+
case 'shape':
|
|
84
|
+
case 'exact':
|
|
85
|
+
const items = (propType.value || []).map((item) => propConfigToFieldConfig(item));
|
|
86
|
+
return {
|
|
87
|
+
componentName: 'ObjectSetter',
|
|
88
|
+
props: {
|
|
89
|
+
config: {
|
|
90
|
+
items,
|
|
91
|
+
extraSetter: typeName === 'shape' ? propTypeToSetter('any') : null,
|
|
92
|
+
},
|
|
93
|
+
},
|
|
94
|
+
isRequired,
|
|
95
|
+
initialValue: (field) => {
|
|
96
|
+
const data = {};
|
|
97
|
+
items.forEach((item) => {
|
|
98
|
+
let initial = item.defaultValue;
|
|
99
|
+
if (initial == null && item.setter && typeof item.setter === 'object') {
|
|
100
|
+
initial = item.setter.initialValue;
|
|
101
|
+
}
|
|
102
|
+
data[item.name] = initial
|
|
103
|
+
? typeof initial === 'function'
|
|
104
|
+
? initial(field)
|
|
105
|
+
: initial
|
|
106
|
+
: null;
|
|
107
|
+
});
|
|
108
|
+
return data;
|
|
109
|
+
},
|
|
110
|
+
};
|
|
111
|
+
case 'object':
|
|
112
|
+
case 'objectOf':
|
|
113
|
+
return {
|
|
114
|
+
componentName: 'ObjectSetter',
|
|
115
|
+
props: {
|
|
116
|
+
config: {
|
|
117
|
+
extraSetter: propTypeToSetter(typeName === 'objectOf' ? propType.value : 'any'),
|
|
118
|
+
},
|
|
119
|
+
},
|
|
120
|
+
isRequired,
|
|
121
|
+
initialValue: {},
|
|
122
|
+
};
|
|
123
|
+
case 'array':
|
|
124
|
+
case 'arrayOf':
|
|
125
|
+
return {
|
|
126
|
+
componentName: 'ArraySetter',
|
|
127
|
+
props: {
|
|
128
|
+
itemSetter: propTypeToSetter(typeName === 'arrayOf' ? propType.value : 'any'),
|
|
129
|
+
},
|
|
130
|
+
isRequired,
|
|
131
|
+
initialValue: [],
|
|
132
|
+
};
|
|
133
|
+
case 'func':
|
|
134
|
+
return {
|
|
135
|
+
componentName: 'FunctionSetter',
|
|
136
|
+
isRequired,
|
|
137
|
+
};
|
|
138
|
+
case 'color':
|
|
139
|
+
return {
|
|
140
|
+
componentName: 'ColorSetter',
|
|
141
|
+
isRequired,
|
|
142
|
+
};
|
|
143
|
+
case 'oneOfType':
|
|
144
|
+
return {
|
|
145
|
+
componentName: 'MixedSetter',
|
|
146
|
+
props: {
|
|
147
|
+
// TODO:
|
|
148
|
+
setters: (propType.value || []).map((item) => propTypeToSetter(item)),
|
|
149
|
+
},
|
|
150
|
+
isRequired,
|
|
151
|
+
};
|
|
152
|
+
default:
|
|
153
|
+
// do nothing
|
|
154
|
+
}
|
|
155
|
+
return {
|
|
156
|
+
componentName: 'MixedSetter',
|
|
157
|
+
isRequired,
|
|
158
|
+
props: {},
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
const EVENT_RE = /^on|after|before[A-Z][\w]*$/;
|
|
163
|
+
|
|
164
|
+
module.exports = function (metadata) {
|
|
165
|
+
const { configure = {} } = metadata;
|
|
166
|
+
// TODO types后续补充
|
|
167
|
+
let extendsProps = null;
|
|
168
|
+
if (configure.props) {
|
|
169
|
+
if (Array.isArray(configure.props)) {
|
|
170
|
+
return metadata;
|
|
171
|
+
}
|
|
172
|
+
const { isExtends, override = [] } = configure.props;
|
|
173
|
+
// 不开启继承时,直接返回configure配置
|
|
174
|
+
if (!isExtends) {
|
|
175
|
+
return {
|
|
176
|
+
...metadata,
|
|
177
|
+
configure: {
|
|
178
|
+
...configure,
|
|
179
|
+
props: [...override],
|
|
180
|
+
},
|
|
181
|
+
};
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
extendsProps = {};
|
|
185
|
+
// 开启继承后,缓存重写内容的配置
|
|
186
|
+
override.forEach((prop) => {
|
|
187
|
+
extendsProps[prop.name] = prop;
|
|
188
|
+
});
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
if (!metadata.props) {
|
|
192
|
+
return {
|
|
193
|
+
...metadata,
|
|
194
|
+
configure: {
|
|
195
|
+
...configure,
|
|
196
|
+
props: [],
|
|
197
|
+
},
|
|
198
|
+
};
|
|
199
|
+
}
|
|
200
|
+
const { component = {}, supports = {} } = configure;
|
|
201
|
+
const supportedEvents = supports.events ? null : [];
|
|
202
|
+
const props = [];
|
|
203
|
+
|
|
204
|
+
metadata.props.forEach((prop) => {
|
|
205
|
+
const { name, propType, description } = prop;
|
|
206
|
+
if (
|
|
207
|
+
name === 'children' &&
|
|
208
|
+
(component.isContainer || propType === 'node' || propType === 'element' || propType === 'any')
|
|
209
|
+
) {
|
|
210
|
+
if (component.isContainer !== false) {
|
|
211
|
+
component.isContainer = true;
|
|
212
|
+
props.push(propConfigToFieldConfig(prop));
|
|
213
|
+
return;
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
if (EVENT_RE.test(name) && (propType === 'func' || propType === 'any')) {
|
|
218
|
+
if (supportedEvents) {
|
|
219
|
+
supportedEvents.push({
|
|
220
|
+
name,
|
|
221
|
+
description,
|
|
222
|
+
});
|
|
223
|
+
supports.events = supportedEvents;
|
|
224
|
+
}
|
|
225
|
+
return;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
if (name === 'className' && (propType === 'string' || propType === 'any')) {
|
|
229
|
+
if (supports.className == null) {
|
|
230
|
+
supports.className = true;
|
|
231
|
+
}
|
|
232
|
+
return;
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
if (name === 'style' && (propType === 'object' || propType === 'any')) {
|
|
236
|
+
if (supports.style == null) {
|
|
237
|
+
supports.style = true;
|
|
238
|
+
}
|
|
239
|
+
return;
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
// 存在覆盖配置时
|
|
243
|
+
if (extendsProps) {
|
|
244
|
+
if (name in extendsProps) {
|
|
245
|
+
prop = extendsProps[name];
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
props.push(propConfigToFieldConfig(prop));
|
|
250
|
+
});
|
|
251
|
+
|
|
252
|
+
return {
|
|
253
|
+
...metadata,
|
|
254
|
+
configure: {
|
|
255
|
+
...configure,
|
|
256
|
+
props,
|
|
257
|
+
supports,
|
|
258
|
+
component,
|
|
259
|
+
},
|
|
260
|
+
};
|
|
261
|
+
};
|