-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathplopfile.js
More file actions
121 lines (109 loc) · 3.4 KB
/
plopfile.js
File metadata and controls
121 lines (109 loc) · 3.4 KB
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
121
/**
* Plop Component Generator Configuration
* Generates React components with the 5-file pattern (including accessibility tests)
*/
module.exports = function (plop) {
// Component generator
plop.setGenerator('component', {
description: 'Create a new component with 5-file structure',
prompts: [
{
type: 'input',
name: 'name',
message: 'Component name (PascalCase):',
validate: (value) => {
// Validate PascalCase
if (!/^[A-Z][a-zA-Z0-9]*$/.test(value)) {
return 'Component name must be in PascalCase (e.g., ButtonComponent)';
}
return true;
},
},
{
type: 'list',
name: 'category',
message: 'Component category:',
choices: [
{ name: 'Subatomic (smallest building blocks)', value: 'subatomic' },
{ name: 'Atomic (basic UI elements)', value: 'atomic' },
{ name: 'Molecular (compound components)', value: 'molecular' },
{ name: 'Organisms (complex sections)', value: 'organisms' },
{ name: 'Templates (page layouts)', value: 'templates' },
],
default: 'atomic',
},
{
type: 'confirm',
name: 'hasProps',
message: 'Will this component have props?',
default: true,
},
{
type: 'confirm',
name: 'withHooks',
message: 'Include custom hooks?',
default: false,
},
],
actions: (data) => {
const actions = [];
const componentPath = 'src/components/{{category}}/{{pascalCase name}}';
// Add index.tsx
actions.push({
type: 'add',
path: `${componentPath}/index.tsx`,
templateFile: 'tools/templates/component/index.tsx.hbs',
});
// Add Component.tsx
actions.push({
type: 'add',
path: `${componentPath}/{{pascalCase name}}.tsx`,
templateFile: 'tools/templates/component/Component.tsx.hbs',
});
// Add Component.test.tsx
actions.push({
type: 'add',
path: `${componentPath}/{{pascalCase name}}.test.tsx`,
templateFile: 'tools/templates/component/Component.test.tsx.hbs',
});
// Add Component.stories.tsx
actions.push({
type: 'add',
path: `${componentPath}/{{pascalCase name}}.stories.tsx`,
templateFile: 'tools/templates/component/Component.stories.tsx.hbs',
});
// Add Component.accessibility.test.tsx
actions.push({
type: 'add',
path: `${componentPath}/{{pascalCase name}}.accessibility.test.tsx`,
templateFile:
'tools/templates/component/Component.accessibility.test.tsx.hbs',
});
// Add custom hook if requested
if (data.withHooks) {
actions.push({
type: 'add',
path: `${componentPath}/use{{pascalCase name}}.ts`,
template: `import { useState, useEffect } from 'react';
/**
* Custom hook for {{pascalCase name}} component
*/
export function use{{pascalCase name}}() {
const [state, setState] = useState(null);
useEffect(() => {
// Hook logic here
}, []);
return { state };
}
`,
});
}
return actions;
},
});
// Helper to add custom Handlebars helpers
plop.setHelper('upperCase', (text) => text.toUpperCase());
plop.setHelper('properCase', (text) => {
return text.charAt(0).toUpperCase() + text.slice(1).toLowerCase();
});
};