/
component-generator.js
120 lines (112 loc) · 3.25 KB
/
component-generator.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
const {unflatten} = require('flat');
const {pascalCase, sentenceCase} = require('change-case');
const {inputRequired, addWithCustomData} = require('./utils');
const MAX_PROPS = 10;
const propsPrompts = [];
[...new Array(MAX_PROPS)].forEach((v, i) => {
propsPrompts.push(
{
type: 'confirm',
name: '_props',
message: () => (i === 0 ? 'Do you have props?' : 'Other props?'),
when: data => i === 0 || data._props
},
{
type: 'input',
name: `props.${i}.name`,
message: 'Props name?',
validate: inputRequired('props name'),
when: data => data._props
},
{
type: 'input',
name: `props.${i}.type`,
message: 'Props type?',
validate: inputRequired('props type'),
when: data => data._props
},
{
type: 'confirm',
name: `props.${i}.required`,
message: 'Props is required?',
when: data => data._props
}
);
});
module.exports = plop => {
plop.addHelper('propsHelper', text => `{${text}}`);
plop.setGenerator('component', {
prompts: [
{
type: 'input',
name: 'name',
message: 'Component name?',
validate: inputRequired('name')
},
{
type: 'input',
name: 'description',
message: 'Component description?',
default: data => `${sentenceCase(data.name)} component.`
},
...propsPrompts,
{
type: 'checkbox',
name: 'files',
message: 'Wish files do you generate?',
choices: data => [
{
name: `${pascalCase(data.name)}.tsx`,
value: 'component',
checked: true
},
{
name: `${pascalCase(data.name)}.test.tsx`,
value: 'test',
checked: true
},
{
name: `${pascalCase(data.name)}.stories.tsx`,
value: 'stories',
checked: true
}
]
}
],
actions: data => {
// Parse data for easy templating
data = unflatten(data);
data.props = data.props || [];
data.haveRequiredProps = data.props.reduce(
(mem, prop) => mem || prop.required,
false
);
data.props = data.props.map(prop =>
Object.assign({}, prop, {optional: !prop.required})
);
const basePath = data.files.length > 0 ?
'../src/components/{{pascalCase name}}/' :
'../src/components/';
const actions = [];
[
{condition: 'component', actions: [
{path: `${basePath}{{pascalCase name}}.tsx`, templateFile: 'templates/component-tsx.template'}
]},
{condition: 'test', actions: [
{path: `${basePath}{{pascalCase name}}.test.tsx`, templateFile: 'templates/component-test-tsx.template'}
]},
{condition: 'stories', actions: [
{path: `${basePath}{{pascalCase name}}.stories.tsx`, templateFile: 'templates/component-stories-tsx.template'},
{path: `${basePath}README.md`, templateFile: 'templates/component-readme-md.template'}
]}
].forEach(a => {
if (data.files.includes(a.condition)) {
a.actions.forEach(i => {
actions.push(addWithCustomData(plop, i, data));
});
}
});
return actions;
}
});
};