Skip to content

Commit e17a979

Browse files
authored
Merge pull request #98 from TyIsI/TemplatedDirectoryNames
feat: templated customDirectory name override
2 parents 04cfc2c + 164c29b commit e17a979

File tree

3 files changed

+200
-30
lines changed

3 files changed

+200
-30
lines changed

readme.md

Lines changed: 111 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
[![License](https://img.shields.io/npm/l/express.svg)](https://github.com/arminbro/generate-react-cli/blob/master/LICENSE)
44

5-
<p align="center">
5+
<p align="center">
66
<img src="https://raw.githubusercontent.com/arminbro/generate-react-cli/master/docs/assets/generate-react-cli.svg?raw=true"/>
77
</p>
88

@@ -20,6 +20,7 @@ You can also watch an excellent [video](https://www.youtube.com/watch?v=NEvnt3MW
2020
- [Generate components](#generate-components)
2121
- [Custom component types](#custom-component-types)
2222
- [Custom component templates](#custom-component-templates)
23+
- [Custom component directory](#custom-component-directory)
2324
- [Custom component files](#custom-component-files)
2425
- [OpenAi integration (Alpha release)](#openai-integration-alpha-release)
2526

@@ -97,10 +98,11 @@ Otherwise, if you don't pass any options, it will just use the default values th
9798
<th>Value Type</th>
9899
<th>Default Value</th>
99100
</tr>
101+
100102
<tr>
101103
<td width="20%"><b>--path</b></td>
102104
<td width="60%">
103-
Value of the path where you want the component to be generated in (e.g. <b>src/components</b>).
105+
Value of the path where you want the component to be generated in (e.g. <b>src/components</b>).
104106
</td>
105107
<td width="20%">String</td>
106108
<td width="20%"><code>component.default.path<code></td>
@@ -118,7 +120,7 @@ Otherwise, if you don't pass any options, it will just use the default values th
118120
<tr>
119121
<td width="20%"><b>--withLazy</b></td>
120122
<td width="60%">
121-
Creates a corresponding lazy file (a file that lazy-loads your component out of the box and enables <a href="https://reactjs.org/docs/code-splitting.html#code-splitting">code splitting</a>) with this component.
123+
Creates a corresponding lazy file (a file that lazy-loads your component out of the box and enables <a href="https://reactjs.org/docs/code-splitting.html#code-splitting">code splitting</a>) with this component.
122124
</td>
123125
<td width="20%">Boolean</td>
124126
<td width="20%"><code>component.default.withLazy<code></td>
@@ -127,7 +129,7 @@ Otherwise, if you don't pass any options, it will just use the default values th
127129
<tr>
128130
<td width="20%"><b>--withStory</b></td>
129131
<td width="60%">
130-
Creates a corresponding (<a href="https://storybook.js.org">storybook</a>) story file with this component.
132+
Creates a corresponding (<a href="https://storybook.js.org">storybook</a>) story file with this component.
131133
</td>
132134
<td width="20%">Boolean</td>
133135
<td width="20%"><code>component.default.withStory<code></td>
@@ -136,7 +138,7 @@ Otherwise, if you don't pass any options, it will just use the default values th
136138
<tr>
137139
<td width="20%"><b>--withStyle</b></td>
138140
<td width="60%">
139-
Creates a corresponding stylesheet file with this component.
141+
Creates a corresponding stylesheet file with this component.
140142
</td>
141143
<td width="20%">Boolean</td>
142144
<td width="20%"><code>component.default.withStyle<code></td>
@@ -145,11 +147,12 @@ Otherwise, if you don't pass any options, it will just use the default values th
145147
<tr>
146148
<td width="20%"><b>--withTest</b></td>
147149
<td width="60%">
148-
Creates a corresponding test file with this component.
150+
Creates a corresponding test file with this component.
149151
</td>
150152
<td width="20%">Boolean</td>
151153
<td width="20%"><code>component.default.withTest<code></td>
152154
</tr>
155+
153156
<tr>
154157
<td width="20%"><b>--dry-run</b></td>
155158
<td width="60%">
@@ -158,15 +161,27 @@ Otherwise, if you don't pass any options, it will just use the default values th
158161
<td width="20%">Boolean</td>
159162
<td width="20%"><code>false<code></td>
160163
</tr>
164+
161165
<tr>
162166
<td width="20%"><b>--flat</b></td>
163167
<td width="60%">
164-
Generate the files in the mentioned path insted of creating new folder for it
168+
Generate the files in the mentioned path instead of creating new folder for it
165169
</td>
166170
<td width="20%">Boolean</td>
167171
<td width="20%"><code>false<code></td>
168172
</tr>
169-
<tr>
173+
174+
<tr>
175+
<td width="20%"><b>--customDirectory</b></td>
176+
<td width="60%">
177+
Template value that overrides the name of the directory of the component to be generated in.<br />
178+
See more under <a href="#custom-component-directory">custom component directory</a>.
179+
</td>
180+
<td width="20%">String</td>
181+
<td width="20%"><code>null</code></td>
182+
</tr>
183+
184+
<tr>
170185
<td width="20%"><b>--describe</b></td>
171186
<td width="60%">
172187
Describe the component you're trying to generate, and OpenAI will do its best to render it following your instructions.
@@ -176,7 +191,7 @@ Otherwise, if you don't pass any options, it will just use the default values th
176191
</tr>
177192
</table>
178193

179-
### Custom component types:
194+
### Custom component types
180195

181196
By default, GRC will use the `component.default` configuration rules when running the component command out of the box.
182197

@@ -329,6 +344,93 @@ it('It should mount', () => {
329344
});
330345
```
331346

347+
### Custom component directory
348+
349+
Using the `customDirectory` you can easily override the directory name for the component generated. For instance, if prefixes are required for particular components or if template names will be mixed, the `customDirectory` option will allow you to override the way that GRC generates the name of the directory where the component files will live.
350+
351+
The `customDirectory` directive allows all supported casings (see previous section) and can be overridden at the following levels in ascending specific of priority:
352+
353+
- top
354+
- component.default
355+
- component._type_
356+
- CLI
357+
358+
#### Example:
359+
360+
For React Context Providers in a project, the decision has been made to separate Context generation from the visual components.
361+
362+
In a typical configuration the configuration would look as following:
363+
364+
```json
365+
{
366+
"provider": {
367+
"path": "src/components/providers",
368+
"withLazy": false,
369+
"withStory": true,
370+
"withStyle": false,
371+
"withTest": true,
372+
"withTypes": true,
373+
"withContext": true,
374+
"customTemplates": {
375+
"component": "src/components/templates/provider/TemplateName.tsx",
376+
"context": "src/components/templates/provider/TemplateName.context.ts",
377+
"story": "src/components/templates/provider/TemplateName.stories.tsx",
378+
"test": "src/components/templates/provider/TemplateName.test.tsx",
379+
"types": "src/components/templates/provider/TemplateName.types.ts"
380+
}
381+
}
382+
}
383+
```
384+
385+
With the configuration above, the component would be required to either follow a full or a minimalistic naming convention.
386+
I.e. the component would either need to be generated as `ThemeProvider` and consequently the context name would be generated as `ThemeProviderContext`, or by renaming the files and templates as `TemplateNameProvider` but with the downside of the component path being generated as `src/components/providers/Theme`. This creates inconsistent naming in the directory containg the component files.
387+
388+
To work around this, the `customDirectory` option can be used to enforce a particular style.
389+
390+
```json
391+
{
392+
...
393+
"provider": {
394+
"path": "src/components/providers",
395+
"withLazy": false,
396+
"withStory": true,
397+
"withStyle": false,
398+
"withTest": true,
399+
"withTypes": true,
400+
"withContext": true,
401+
"customDirectory": "TemplateNameProvider",
402+
"customTemplates": {
403+
"component": "src/components/templates/provider/TemplateNameProvider.tsx",
404+
"context": "src/components/templates/provider/TemplateName.context.ts",
405+
"story": "src/components/templates/provider/TemplateNameProvider.stories.tsx",
406+
"test": "src/components/templates/provider/TemplateNameProvider.test.tsx",
407+
"types": "src/components/templates/provider/TemplateNameProvider.types.ts"
408+
}
409+
}
410+
...
411+
}
412+
```
413+
414+
The above configuration would allow you to mix and match different template names and keep naming consistent.
415+
416+
If we executed GRC with the above configuration (`npx generate-react-cli component Theme --type=provider`), the result would look like this:
417+
418+
```fs
419+
src/components/providers/ThemeProvider/Theme.context.ts
420+
src/components/providers/ThemeProvider/ThemeProvider.tsx
421+
src/components/providers/ThemeProvider/ThemeProvider.stories.tsx
422+
src/components/providers/ThemeProvider/ThemeProvider.test.tsx
423+
src/components/providers/ThemeProvider/ThemeProvider.types.ts
424+
```
425+
426+
Similarly, this construct could be used as a shortcut for generating other named components, like the `BoxLayout` example above, depending on that could be shortened to:
427+
428+
```sh
429+
npx generate-react-cli component Box --type=layout --customDir=TemplateNameLayout
430+
```
431+
432+
Or it could be used to generate files with a naming convention with `Test`, `Lazy`, `Context`, `Theme`, or `Provider` suffixes. Or even combined with skeleton CSS
433+
332434
### Custom component files
333435

334436
GRC comes with corresponding built-in files for a given component if you need them (i.e., `withStyle`, `withTest`, `withStory`, and `withLazy`).

src/commands/generateComponent.js

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,17 @@ export default function initGenerateComponentCommand(args, cliConfigFile, progra
2929
'Generate the files in the mentioned path instead of creating new folder for it',
3030
selectedComponentType.flat || false
3131
)
32-
.option('-dr, --dry-run', 'Show what will be generated without writing to disk');
32+
.option('-dr, --dry-run', 'Show what will be generated without writing to disk')
33+
.option(
34+
'--customDirectory <customDirectory>',
35+
'You can pass a cased path template that will be used as the component path for the component being generated.\n' +
36+
'E.g. this allows you to add a prefix or suffix to the component path, ' +
37+
'or change the case of the name of the directory holding the components to kebab-case.\n' +
38+
'Examples:\n' +
39+
'- TemplateName\n' +
40+
'- template-name\n' +
41+
'- TemplateNameSuffix'
42+
);
3343

3444
// Dynamic component command option defaults.
3545

0 commit comments

Comments
 (0)