Skip to content

Commit 648252d

Browse files
authored
Merge pull request #9 from ovh/feat/component-generator
chore: create component generator
2 parents 56207e5 + 10ecbe0 commit 648252d

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

67 files changed

+4309
-22
lines changed

package.json

+3-4
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,8 @@
2020
"packages/stencil/components/!(loader|custom-elements|custom-elements-bundle)*/vue",
2121
"packages/stencil",
2222
"packages/starters/*",
23-
"packages/tools/*"
23+
"packages/tools/*",
24+
"packages/tools/generator/component"
2425
],
2526
"scripts": {
2627
"build": "lerna run build",
@@ -35,10 +36,8 @@
3536
"doc": "lerna run doc",
3637
"doc:api": "lerna run doc:api",
3738
"doc:api:slow": "lerna run --concurrency 1 doc:api",
39+
"generate:component": "yarn workspace @ovhcloud/ods-component-generator run generate",
3840
"generate:licence": "npx generate-license-file --input package.json --output THIRD-PARTY-LICENCES --overwrite && lerna run generate:licence",
39-
"generate:stencil:component": "yarn workspace @ovhcloud/ods-stencil-component-generator run generate",
40-
"generate:stencil:library": "yarn workspace @ovhcloud/ods-stencil-library-generator run generate",
41-
"generate:story": "yarn workspace @ovhcloud/ods-story-generator run generate",
4241
"generate:theme": "lerna run generate:theme",
4342
"ignore:rm": "lerna run ignore:rm",
4443
"lerna:ls:pl": "lerna ls -pl",

packages/contributing/howto/contributing-create-component.mdx

+5
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,11 @@ packages.
3535
> Be sure to document interfaces, classes, functions, constants etc. with TSdoc and Typedoc syntax so that the automatic
3636
> technical specifications can be generated.
3737
38+
## [NEW] Component generator
39+
40+
In order to simplify the following creation, we set up a command that creates all initiated files explained below.
41+
Please use ```yarn generate:component``` at root folder.
42+
3843
### @ovhcloud/ods-core
3944

4045
This library contains all the code base of `ODS` with all the code that
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
# Change Log
2+
3+
All notable changes to this project will be documented in this file.
4+
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
{
2+
"outDir": "../../../..",
3+
"odsCorePath": "libraries/core/src/components",
4+
"odsTestingPath": "libraries/testing/src/components",
5+
"odsThemingPath": "libraries/theming/size",
6+
"odsStencilPath": "stencil/components",
7+
"odsStorybookPath": "tools/storybook/stories/components",
8+
"odsSpecificationsPath": "specifications/components",
9+
"packagePrefix": "@ovhcloud/ods-",
10+
"corePrefix": "ods",
11+
"stencilPrefix": "osds",
12+
"npmClient": "yarn"
13+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
{
2+
"name": "@ovhcloud/ods-component-generator",
3+
"version": "0.0.0",
4+
"private": true,
5+
"description": "OVHcloud Design System UI Component generator",
6+
"author": "OVH SAS",
7+
"license": "Apache-2.0",
8+
"scripts": {
9+
"generate": "sao . _tmp && rm -rf _tmp"
10+
},
11+
"devDependencies": {
12+
"lodash.kebabcase": "^4.1.1",
13+
"lodash.startcase": "^4.4.0",
14+
"sao": "^1.7.1"
15+
}
16+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,183 @@
1+
const kebabCase = require('lodash.kebabcase');
2+
const startCase = require('lodash.startcase');
3+
const config = require('./config.json');
4+
const packageJson = require('./package.json');
5+
6+
module.exports = {
7+
description: 'Scaffolding out a new ods component.',
8+
templateDir: 'template',
9+
transformerOptions: {
10+
context: {
11+
kebabCase,
12+
startCase,
13+
},
14+
},
15+
prompts() {
16+
return [
17+
{
18+
name: 'name',
19+
message: 'Component name ?',
20+
default: 'My Awesome Component',
21+
},
22+
{
23+
name: 'packageDescription',
24+
message: 'Component description ?',
25+
default: 'Component to do awesome things',
26+
}
27+
];
28+
},
29+
actions() {
30+
const templateData = {
31+
name: kebabCase(this.answers.name),
32+
packageVersion: packageJson.version,
33+
componentName: startCase(this.answers.name).replace(/\s/gmi, ''),
34+
componentFolderName: `${kebabCase(this.answers.name)}`,
35+
componentFileNamePrefix: `${config.corePrefix}-${kebabCase(this.answers.name)}`,
36+
stencilPrefix: config.stencilPrefix
37+
};
38+
return [
39+
// Add all template files
40+
{
41+
type: 'add',
42+
files: '**',
43+
templateData
44+
},
45+
46+
// Move Core files
47+
{
48+
type: 'move',
49+
patterns: {
50+
'core/component.ts': `${config.outDir}/${config.odsCorePath}/${templateData.componentFolderName}/${templateData.componentFileNamePrefix}.ts`,
51+
'core/component-attributes.ts': `${config.outDir}/${config.odsCorePath}/${templateData.componentFolderName}/${templateData.componentFileNamePrefix}-attributes.ts`,
52+
'core/component-controller.ts': `${config.outDir}/${config.odsCorePath}/${templateData.componentFolderName}/${templateData.componentFileNamePrefix}-controller.ts`,
53+
'core/component-default-attributes.ts': `${config.outDir}/${config.odsCorePath}/${templateData.componentFolderName}/${templateData.componentFileNamePrefix}-default-attributes.ts`,
54+
'core/component-events.ts': `${config.outDir}/${config.odsCorePath}/${templateData.componentFolderName}/${templateData.componentFileNamePrefix}-events.ts`,
55+
'core/component-methods.ts': `${config.outDir}/${config.odsCorePath}/${templateData.componentFolderName}/${templateData.componentFileNamePrefix}-methods.ts`,
56+
'core/public-api.ts': `${config.outDir}/${config.odsCorePath}/${templateData.componentFolderName}/public-api.ts`,
57+
}
58+
},
59+
{
60+
type: 'modify',
61+
files: `${config.outDir}/${config.odsCorePath}/public-api.ts`,
62+
handler(data) {
63+
return data + `export * from './${templateData.componentFolderName}/public-api';`
64+
}
65+
},
66+
67+
// Move Specifications files
68+
{
69+
type: 'move',
70+
patterns: {
71+
'specifications/specifications-component.mdx': `${config.outDir}/${config.odsSpecificationsPath}/${templateData.name}/specifications-${templateData.name}.mdx`,
72+
'specifications/specifications-component-contents.mdx': `${config.outDir}/${config.odsSpecificationsPath}/${templateData.name}/specifications-${templateData.name}-contents.mdx`,
73+
'specifications/specifications-component-events.mdx': `${config.outDir}/${config.odsSpecificationsPath}/${templateData.name}/specifications-${templateData.name}-events.mdx`,
74+
'specifications/specifications-component-methods.mdx': `${config.outDir}/${config.odsSpecificationsPath}/${templateData.name}/specifications-${templateData.name}-methods.mdx`,
75+
'specifications/specifications-component-properties.mdx': `${config.outDir}/${config.odsSpecificationsPath}/${templateData.name}/specifications-${templateData.name}-properties.mdx`,
76+
'specifications/specifications-component-tests.mdx': `${config.outDir}/${config.odsSpecificationsPath}/${templateData.name}/specifications-${templateData.name}-tests.mdx`,
77+
}
78+
},
79+
80+
// Move Storybook files
81+
{
82+
type: 'move',
83+
patterns: {
84+
'storybook/component.design.stories.mdx': `${config.outDir}/${config.odsStorybookPath}/${templateData.name}/${templateData.name}.design.stories.mdx`,
85+
'storybook/component.specifications.stories.mdx': `${config.outDir}/${config.odsStorybookPath}/${templateData.name}/${templateData.name}.specifications.stories.mdx`,
86+
'storybook/component.web-component.stories.page.mdx': `${config.outDir}/${config.odsStorybookPath}/${templateData.name}/${templateData.name}.web-component.stories.page.mdx`,
87+
'storybook/component.web-components.stories.ts': `${config.outDir}/${config.odsStorybookPath}/${templateData.name}/${templateData.name}.web-components.stories.ts`,
88+
}
89+
},
90+
91+
// Move Stencil files
92+
{
93+
type: 'move',
94+
patterns: {
95+
// Root
96+
'stencil/.gitignore': `${config.outDir}/${config.odsStencilPath}/${templateData.name}/.gitignore`,
97+
'stencil/.npmignore': `${config.outDir}/${config.odsStencilPath}/${templateData.name}/.npmignore`,
98+
'stencil/CHANGELOG.md': `${config.outDir}/${config.odsStencilPath}/${templateData.name}/CHANGELOG.md`,
99+
'stencil/jest.config.ts': `${config.outDir}/${config.odsStencilPath}/${templateData.name}/jest.config.ts`,
100+
'stencil/package.json': `${config.outDir}/${config.odsStencilPath}/${templateData.name}/package.json`,
101+
'stencil/stencil.config.ts': `${config.outDir}/${config.odsStencilPath}/${templateData.name}/stencil.config.ts`,
102+
'stencil/THIRD-PARTY-LICENCES': `${config.outDir}/${config.odsStencilPath}/${templateData.name}/THIRD-PARTY-LICENCES`,
103+
'stencil/tsconfig.dev.json': `${config.outDir}/${config.odsStencilPath}/${templateData.name}/tsconfig.dev.json`,
104+
'stencil/tsconfig.json': `${config.outDir}/${config.odsStencilPath}/${templateData.name}/tsconfig.json`,
105+
'stencil/tsconfig.prod.json': `${config.outDir}/${config.odsStencilPath}/${templateData.name}/tsconfig.prod.json`,
106+
'stencil/typedoc.json': `${config.outDir}/${config.odsStencilPath}/${templateData.name}/typedoc.json`,
107+
// Sources
108+
'stencil/src/global.dev.ts': `${config.outDir}/${config.odsStencilPath}/${templateData.name}/src/global.dev.ts`,
109+
'stencil/src/global.prod.ts': `${config.outDir}/${config.odsStencilPath}/${templateData.name}/src/global.prod.ts`,
110+
'stencil/src/global.ts': `${config.outDir}/${config.odsStencilPath}/${templateData.name}/src/global.ts`,
111+
'stencil/src/index.html': `${config.outDir}/${config.odsStencilPath}/${templateData.name}/src/index.html`,
112+
'stencil/src/index.ts': `${config.outDir}/${config.odsStencilPath}/${templateData.name}/src/index.ts`,
113+
'stencil/src/components/osds-component/osds-component.e2e.screenshot.ts': `${config.outDir}/${config.odsStencilPath}/${templateData.name}/src/components/${config.stencilPrefix}-${templateData.name}/${config.stencilPrefix}-${templateData.name}.e2e.screenshot.ts`,
114+
'stencil/src/components/osds-component/osds-component.e2e.ts': `${config.outDir}/${config.odsStencilPath}/${templateData.name}/src/components/${config.stencilPrefix}-${templateData.name}/${config.stencilPrefix}-${templateData.name}.e2e.ts`,
115+
'stencil/src/components/osds-component/osds-component.scss': `${config.outDir}/${config.odsStencilPath}/${templateData.name}/src/components/${config.stencilPrefix}-${templateData.name}/${config.stencilPrefix}-${templateData.name}.scss`,
116+
'stencil/src/components/osds-component/osds-component.spec.ts': `${config.outDir}/${config.odsStencilPath}/${templateData.name}/src/components/${config.stencilPrefix}-${templateData.name}/${config.stencilPrefix}-${templateData.name}.spec.ts`,
117+
'stencil/src/components/osds-component/osds-component.tsx': `${config.outDir}/${config.odsStencilPath}/${templateData.name}/src/components/${config.stencilPrefix}-${templateData.name}/${config.stencilPrefix}-${templateData.name}.tsx`,
118+
'stencil/src/components/osds-component/public-api.ts': `${config.outDir}/${config.odsStencilPath}/${templateData.name}/src/components/${config.stencilPrefix}-${templateData.name}/public-api.ts`,
119+
'stencil/src/components/osds-component/styles/osds-component.color.scss': `${config.outDir}/${config.odsStencilPath}/${templateData.name}/src/components/${config.stencilPrefix}-${templateData.name}/styles/${config.stencilPrefix}-${templateData.name}.color.scss`,
120+
'stencil/src/components/osds-component/styles/osds-component.mixins.scss': `${config.outDir}/${config.odsStencilPath}/${templateData.name}/src/components/${config.stencilPrefix}-${templateData.name}/styles/${config.stencilPrefix}-${templateData.name}.mixins.scss`,
121+
'stencil/src/components/osds-component/styles/osds-component.size.scss': `${config.outDir}/${config.odsStencilPath}/${templateData.name}/src/components/${config.stencilPrefix}-${templateData.name}/styles/${config.stencilPrefix}-${templateData.name}.size.scss`,
122+
'stencil/src/components/osds-component/styles/osds-component.typography.scss': `${config.outDir}/${config.odsStencilPath}/${templateData.name}/src/components/${config.stencilPrefix}-${templateData.name}/styles/${config.stencilPrefix}-${templateData.name}.typography.scss`,
123+
'stencil/src/docs/osds-component/usage.mdx': `${config.outDir}/${config.odsStencilPath}/${templateData.name}/src/docs/${config.stencilPrefix}-${templateData.name}/usage.mdx`,
124+
// React adapter
125+
'stencil/react/.gitignore': `${config.outDir}/${config.odsStencilPath}/${templateData.name}/react/.gitignore`,
126+
'stencil/react/.npmignore': `${config.outDir}/${config.odsStencilPath}/${templateData.name}/react/.npmignore`,
127+
'stencil/react/CHANGELOG.md': `${config.outDir}/${config.odsStencilPath}/${templateData.name}/react/CHANGELOG.md`,
128+
'stencil/react/package.json': `${config.outDir}/${config.odsStencilPath}/${templateData.name}/react/package.json`,
129+
'stencil/react/tsconfig.cjs.json': `${config.outDir}/${config.odsStencilPath}/${templateData.name}/react/tsconfig.cjs.json`,
130+
'stencil/react/tsconfig.json': `${config.outDir}/${config.odsStencilPath}/${templateData.name}/react/tsconfig.json`,
131+
// Vue adapter
132+
'stencil/vue/.gitignore': `${config.outDir}/${config.odsStencilPath}/${templateData.name}/vue/.gitignore`,
133+
'stencil/vue/.npmignore': `${config.outDir}/${config.odsStencilPath}/${templateData.name}/vue/.npmignore`,
134+
'stencil/vue/CHANGELOG.md': `${config.outDir}/${config.odsStencilPath}/${templateData.name}/vue/CHANGELOG.md`,
135+
'stencil/vue/package.json': `${config.outDir}/${config.odsStencilPath}/${templateData.name}/vue/package.json`,
136+
'stencil/vue/tsconfig.cjs.json': `${config.outDir}/${config.odsStencilPath}/${templateData.name}/vue/tsconfig.cjs.json`,
137+
'stencil/vue/tsconfig.json': `${config.outDir}/${config.odsStencilPath}/${templateData.name}/vue/tsconfig.json`,
138+
}
139+
},
140+
{
141+
type: 'modify',
142+
files: `${config.outDir}/${config.odsThemingPath}/ods-size-definitions.scss`,
143+
handler(data) {
144+
return data + `@import './${config.corePrefix}-theming-size.${templateData.name}.scss';`
145+
}
146+
},
147+
148+
// Move Testing files
149+
{
150+
type: 'move',
151+
patterns: {
152+
'testing/component-base-attributes.ts': `${config.outDir}/${config.odsTestingPath}/${templateData.componentFolderName}/${templateData.componentFileNamePrefix}-base-attributes.ts`,
153+
'testing/public-api.ts': `${config.outDir}/${config.odsTestingPath}/${templateData.componentFolderName}/public-api.ts`,
154+
}
155+
},
156+
{
157+
type: 'modify',
158+
files: `${config.outDir}/${config.odsTestingPath}/public-api.ts`,
159+
handler(data) {
160+
return data + `export * from './${templateData.componentFolderName}/public-api';`
161+
}
162+
},
163+
164+
// Move Theming files
165+
{
166+
type: 'move',
167+
patterns: {
168+
'theming/component-theming-size.scss': `${config.outDir}/${config.odsThemingPath}/${config.corePrefix}-theming-size.${templateData.name}.scss`,
169+
}
170+
},
171+
{
172+
type: 'modify',
173+
files: `${config.outDir}/${config.odsThemingPath}/ods-size-definitions.scss`,
174+
handler(data) {
175+
return data + `@import './${config.corePrefix}-theming-size.${templateData.name}.scss';`
176+
}
177+
}
178+
];
179+
},
180+
async completed() {
181+
this.showProjectTips();
182+
},
183+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import { OdsComponentAttributes } from '../ods-component-attributes';
2+
3+
export interface Ods<%= componentName %>Attributes extends OdsComponentAttributes {
4+
/**
5+
* <%= componentName %> attribute description
6+
*/
7+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import { Ods<%= componentName %> } from './<%= componentFileNamePrefix %>';
2+
import { OdsComponentController } from '../ods-component-controller';
3+
4+
/**
5+
* common controller logic for cmpnt component used by the different implementations.
6+
* it contains all the glue between framework implementation and the third party service.
7+
*/
8+
export class Ods<%= componentName %>Controller extends OdsComponentController<Ods<%= componentName %>> {
9+
// private readonly logger = new OdsLogger('Ods<%= componentName %>Controller');
10+
11+
constructor(component: Ods<%= componentName %>) {
12+
super(component);
13+
}
14+
15+
/**
16+
* Attributes validation documentation
17+
*/
18+
validateAttributes(): void {
19+
return;
20+
}
21+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import { Ods<%= componentName %>Attributes } from './<%= componentFileNamePrefix %>-attributes';
2+
3+
export const ods<%= componentName %>DefaultAttributesDoc = {
4+
// default attributes
5+
} as const;
6+
7+
export const ods<%= componentName %>DefaultAttributes = ods<%= componentName %>DefaultAttributesDoc as Ods<%= componentName %>Attributes;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import { OdsComponentEvents } from '../ods-component-events';
2+
3+
export interface Ods<%= componentName %>Events extends OdsComponentEvents {
4+
// Events
5+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import { OdsComponentMethods } from '../ods-component-methods';
2+
3+
export interface Ods<%= componentName %>Methods extends OdsComponentMethods {
4+
// Methods
5+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import { Ods<%= componentName %>Attributes } from './<%= componentFileNamePrefix %>-attributes';
2+
import { Ods<%= componentName %>Controller } from './<%= componentFileNamePrefix %>-controller';
3+
import { Ods<%= componentName %>Events } from './<%= componentFileNamePrefix %>-events';
4+
import { Ods<%= componentName %>Methods } from './<%= componentFileNamePrefix %>-methods';
5+
import { OdsComponent } from '../ods-component';
6+
import { OdsComponentGenericEvents } from '../ods-component-generic-events';
7+
import { OdsComponentGenericMethods } from '../ods-component-generic-methods';
8+
9+
/**
10+
* interface description of all implementation of `<%= componentFileNamePrefix %>`.
11+
* each implementation must have defined events, methods, attributes
12+
* and one controller for the common behavior logic
13+
*/
14+
export type Ods<%= componentName %><ComponentMethods extends OdsComponentGenericMethods<Ods<%= componentName %>Methods> = OdsComponentGenericMethods<Ods<%= componentName %>Methods>,
15+
ComponentEvents extends OdsComponentGenericEvents<Ods<%= componentName %>Events> = OdsComponentGenericEvents<Ods<%= componentName %>Events>> =
16+
OdsComponent<ComponentMethods, ComponentEvents, Ods<%= componentName %>Attributes, Ods<%= componentName %>Controller>;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
export * from './<%= componentFileNamePrefix %>';
2+
export * from './<%= componentFileNamePrefix %>-attributes';
3+
export * from './<%= componentFileNamePrefix %>-controller';
4+
export * from './<%= componentFileNamePrefix %>-default-attributes';
5+
export * from './<%= componentFileNamePrefix %>-events';
6+
export * from './<%= componentFileNamePrefix %>-methods';
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
| Name | default | Description |
2+
|---------|---------|-------------|
3+
| - | '' | |
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
_none_
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
_none_
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
| Name | Type | default | Description |
2+
|------|------|---------|-------------|
3+
| | | | |
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
_none_
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import {Description} from '@storybook/addon-docs';
2+
3+
[//]: # (import Specs from '@ovhcloud/ods-core/src/components/<%= name %>/docs/spec.md';)
4+
import Specs<%= componentName %>Contents from './specifications-<%= name %>-contents.mdx';
5+
import Specs<%= componentName %>Tests from './specifications-<%= name %>-tests.mdx';
6+
7+
[//]: # (<Description>{Specs}</Description>)
8+
9+
## Contents
10+
<Specs<%= componentName %>Contents />
11+
12+
## Tests
13+
<Specs<%= componentName %>Tests />
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
dist/
2+
custom-elements/
3+
custom-elements-bundle/
4+
www/
5+
loader/
6+
docs-api
7+
src/components.d.ts
8+
9+
*~
10+
*.sw[mnpcod]
11+
*.log
12+
*.lock
13+
*.tmp
14+
*.tmp.*
15+
log.txt
16+
*.sublime-project
17+
*.sublime-workspace
18+
19+
.stencil/
20+
screenshot/
21+
.idea/
22+
.vscode/
23+
.sass-cache/
24+
.versions/
25+
node_modules/
26+
$RECYCLE.BIN/
27+
28+
.DS_Store
29+
Thumbs.db
30+
UserInterfaceState.xcuserstate
31+
.env
32+
33+
src/**/readme.md
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
!dist/
2+
!loader/
3+
!docs-api/
4+
src/
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
# Change Log
2+
3+
All notable changes to this project will be documented in this file.
4+
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.

0 commit comments

Comments
 (0)