-
Notifications
You must be signed in to change notification settings - Fork 1.8k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(cli): add component command (#7384)
* feat(cli): add component command * chore(react): remove test files * chore(cli): fix eslint violations Co-authored-by: DAK <[email protected]> Co-authored-by: TJ Egan <[email protected]> Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
- Loading branch information
1 parent
e11fdf2
commit 74b0850
Showing
15 changed files
with
353 additions
and
10 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -51,3 +51,6 @@ packages/components/docs/js | |
|
||
# Generated files | ||
**/generated/** | ||
|
||
# Templates | ||
**/*.template.* |
Binary file not shown.
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,130 @@ | ||
/** | ||
* Copyright IBM Corp. 2019, 2019 | ||
* | ||
* This source code is licensed under the Apache-2.0 license found in the | ||
* LICENSE file in the root directory of this source tree. | ||
*/ | ||
|
||
'use strict'; | ||
|
||
const { paramCase } = require('change-case'); | ||
const fs = require('fs-extra'); | ||
const { prompt } = require('enquirer'); | ||
const path = require('path'); | ||
const { loadTemplates } = require('../component'); | ||
const { createLogger } = require('../logger'); | ||
|
||
const logger = createLogger('component'); | ||
|
||
function clearConsole() { | ||
process.stdout.write( | ||
process.platform === 'win32' ? '\x1B[2J\x1B[0f' : '\x1B[2J\x1B[3J\x1B[H' | ||
); | ||
} | ||
|
||
async function component() { | ||
const templates = await loadTemplates(); | ||
const questions = [ | ||
{ | ||
type: 'input', | ||
name: 'name', | ||
message: 'What is the name of this component?', | ||
validate(value) { | ||
if (value === '') { | ||
return 'A name is required for the component'; | ||
} | ||
return true; | ||
}, | ||
}, | ||
{ | ||
type: 'input', | ||
name: 'directory', | ||
message: 'Specify the path for this component', | ||
initial: '.', | ||
}, | ||
{ | ||
type: 'multiselect', | ||
name: 'options', | ||
message: 'What else should we scaffold out for you?', | ||
initial: ['tests', 'stories'], | ||
choices: [ | ||
{ | ||
name: 'tests', | ||
value: true, | ||
}, | ||
{ | ||
name: 'stories', | ||
value: true, | ||
}, | ||
], | ||
result(names) { | ||
return this.map(names); | ||
}, | ||
}, | ||
]; | ||
|
||
clearConsole(); | ||
const answers = await prompt(questions); | ||
|
||
logger.start('Generating component...'); | ||
|
||
const directory = path.resolve( | ||
process.cwd(), | ||
answers.directory, | ||
answers.name | ||
); | ||
|
||
logger.info(`Writing component directory to ${directory}`); | ||
|
||
if (await fs.exists(directory)) { | ||
throw new Error(`A directory already exists at ${directory}`); | ||
} | ||
|
||
logger.info('Scaffolding out default files...'); | ||
|
||
await fs.ensureDir(directory); | ||
await fs.writeFile( | ||
path.join(directory, 'index.js'), | ||
templates.index.compile({ name: answers.name }) | ||
); | ||
await fs.writeFile( | ||
path.join(directory, `${answers.name}.js`), | ||
templates.component.compile({ name: answers.name }) | ||
); | ||
|
||
if (answers.options.tests) { | ||
logger.start('Scaffolding out test files...'); | ||
await fs.ensureDir(path.join(directory, '__tests__')); | ||
await fs.writeFile( | ||
path.join(directory, '__tests__', `${answers.name}-test.js`), | ||
templates.test.compile({ name: answers.name }) | ||
); | ||
logger.stop(); | ||
} | ||
|
||
if (answers.options.stories) { | ||
logger.start('Scaffolding out story files...'); | ||
await fs.writeFile( | ||
path.join(directory, `${answers.name}-story.js`), | ||
templates.story.compile({ | ||
name: answers.name, | ||
}) | ||
); | ||
await fs.writeFile( | ||
path.join(directory, `${answers.name}.mdx`), | ||
templates.mdx.compile({ | ||
name: answers.name, | ||
url: paramCase(answers.name), | ||
}) | ||
); | ||
logger.stop(); | ||
} | ||
|
||
logger.stop(); | ||
} | ||
|
||
module.exports = { | ||
command: 'component', | ||
desc: '[EXPERIMENTAL] Scaffold a component in React', | ||
handler: component, | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
/** | ||
* Copyright IBM Corp. 2019, 2019 | ||
* | ||
* This source code is licensed under the Apache-2.0 license found in the | ||
* LICENSE file in the root directory of this source tree. | ||
*/ | ||
|
||
'use strict'; | ||
|
||
const fs = require('fs-extra'); | ||
const path = require('path'); | ||
const template = require('lodash.template'); | ||
|
||
const TEMPLATES_DIR = path.join(__dirname, 'templates'); | ||
const blocklist = new Set(['.DS_Store']); | ||
|
||
async function loadTemplates() { | ||
const files = await fs.readdir(TEMPLATES_DIR).then((names) => { | ||
return names | ||
.filter((name) => { | ||
return !blocklist.has(name); | ||
}) | ||
.map((name) => { | ||
const extension = path.extname(name); | ||
return { | ||
name: path.basename(name, `.template${extension}`), | ||
filepath: path.join(TEMPLATES_DIR, name), | ||
}; | ||
}); | ||
}); | ||
|
||
const templates = {}; | ||
|
||
for (const { name, filepath } of files) { | ||
const contents = await fs.readFile(filepath, 'utf8'); | ||
const compile = template(contents); | ||
templates[name] = { | ||
compile, | ||
}; | ||
} | ||
|
||
return templates; | ||
} | ||
|
||
module.exports = { | ||
loadTemplates, | ||
}; |
19 changes: 19 additions & 0 deletions
19
packages/cli/src/component/templates/component.template.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
/** | ||
* Copyright IBM Corp. 2016, 2020 | ||
* | ||
* This source code is licensed under the Apache-2.0 license found in the | ||
* LICENSE file in the root directory of this source tree. | ||
*/ | ||
|
||
import PropTypes from 'prop-types'; | ||
import React from 'react'; | ||
|
||
function <%= name %>({ children, ...rest }) { | ||
return <div {...rest}>{children}</div>; | ||
} | ||
|
||
<%= name %>.propTypes = { | ||
children: PropTypes.node, | ||
}; | ||
|
||
export default <%= name %>; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
/** | ||
* Copyright IBM Corp. 2016, 2020 | ||
* | ||
* This source code is licensed under the Apache-2.0 license found in the | ||
* LICENSE file in the root directory of this source tree. | ||
*/ | ||
|
||
import <%= name %> from './<%= name %>'; | ||
export { <%= name %> }; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
import { Props } from '@storybook/addon-docs/blocks'; | ||
import { <%= name %> } from './'; | ||
|
||
# <%= name %> | ||
|
||
[Source | ||
code](https://github.com/carbon-design-system/carbon/tree/master/packages/react/src/components/<%= | ||
name %>) | [Usage | ||
guidelines](https://www.carbondesignsystem.com/components/<%= name %>/usage) | ||
| [Accessibility](https://www.carbondesignsystem.com/components/<%= | ||
url %>/accessibility) | ||
|
||
<!-- START doctoc generated TOC please keep comment here to allow auto update --> | ||
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE --> | ||
|
||
## Table of Contents | ||
|
||
- [Overview](#overview) | ||
- [Component API](#component-api) | ||
- [Feedback](#feedback) | ||
|
||
<!-- END doctoc generated TOC please keep comment here to allow auto update --> | ||
|
||
## Overview | ||
|
||
TODO | ||
|
||
## Component API | ||
|
||
<Props /> | ||
|
||
## Feedback | ||
|
||
Help us improve this component by providing feedback, asking questions on Slack, | ||
or updating this file on | ||
[GitHub](https://github.com/carbon-design-system/carbon/edit/master/packages/react/src/components/<%= | ||
name %>/<%= name %>.mdx). |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
/** | ||
* Copyright IBM Corp. 2016, 2018 | ||
* | ||
* This source code is licensed under the Apache-2.0 license found in the | ||
* LICENSE file in the root directory of this source tree. | ||
*/ | ||
|
||
import React from 'react'; | ||
import { <%= name %> } from './'; | ||
import mdx from './<%= name %>.mdx'; | ||
|
||
export default { | ||
title: '<%= name %>', | ||
component: <%= name %>, | ||
parameters: { | ||
docs: { | ||
page: mdx, | ||
}, | ||
}, | ||
}; | ||
|
||
export const example = () => <<%= name %>>Story Example</<%= name %>>; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
/** | ||
* Copyright IBM Corp. 2016, 2020 | ||
* | ||
* This source code is licensed under the Apache-2.0 license found in the | ||
* LICENSE file in the root directory of this source tree. | ||
*/ | ||
|
||
import { cleanup, render, screen } from '@testing-library/react'; | ||
import React from 'react'; | ||
import { <%= name %> } from '../'; | ||
|
||
describe('<%= name %>', () => { | ||
afterEach(cleanup); | ||
|
||
it('should work', () => { | ||
render(<<%= name %>>test</<%= name %>>); | ||
// TODO | ||
}); | ||
|
||
describe('automated accessibility testing', () => { | ||
it('should have no axe violations', async () => { | ||
render(<<%= name %>>test</<%= name %>>); | ||
await expect(screen.getByText('test')).toHaveNoAxeViolations(); | ||
}); | ||
|
||
it('should have no accessibility checker violations', async () => { | ||
render(<<%= name %>>test</<%= name %>>); | ||
await expect(screen.getByText('test')).toHaveNoACViolations('<%= name %>'); | ||
}); | ||
}); | ||
|
||
describe('Component API', () => { | ||
// TODO | ||
}); | ||
}); |
Oops, something went wrong.