npm package: @socialcare/generator-component
Description: A yeoman generator that scaffold standalone social care react components and JS packages.
Author: Jonathan King
Latest version: 1.0.0

# @socialcare/generator-component
> A generator that scaffolds out code for a standalone react component(s). Includes helpful generators for
setting up sub-components. 

## Installation

First, install [Yeoman](http://yeoman.io) using [npm](https://www.npmjs.com/) (we assume you
have pre-installed [node.js](https://nodejs.org/) version >=8.3 <9.0).

```bash
npm install -g yo
npm install -g @socialcare/generator-component
```

## Generating a standalone component
This will scaffold out a component with all the files needed to get up and running.

1. ` cd ` into your components directory.
2. Run the yeoman SocialCare component generator and follow the onscreen prompts.
  ```bash
  $ yo @socialcare/component
  ```  
  
### Prompts
When running the component generator you'll be asked a series of questions that will determine the final code generated.

#### `What type of component will this be?`
This option will determine the file structure for the created component as well as the questions you'll be asked.

##### Option: `Javascript Module`
A javascript module will only include babel to transpile es6 -> es5 as the build step. This is best for creating logic
functions that are framework agnostic.  

##### Option: `Single React Component`
This will create a package that is designed to contain 1 primary react components. It will also set up
Storybook as a way to dev, demo, and document how to interact with the react components.

##### Option: `Collection of Components`
A react component will create a package that is designed to contain multiple react components. It will initially create
no components. To add components run the component sub generator `yo @socialcare/component:component` It will also set
up Storybook as a way to dev, demo, and document how to interact with the react components.

##### Option: `React HOC`
This will create a react Higher Order Component package. Read more on what those are 
[here](https://reactjs.org/docs/higher-order-components.html). It does not include storybook as the results of a HOC
should be an invisible wrapper around other UI components. 

---
#### `What would you like to call this component?`
*Default: (current directory name)*  
The name you enter here will be prepended with `@socialcare/` for the package name and the directory will be prepended
with either `sc-pkg-`, `sc-component-`, or `sc-hoc-` depending on the answer to the previous question.

---
#### `What is this component going to do / why does it exist?`
*Default: (blank)*  
This is the description that will be used in the package.json file and storybook if this is a react component. 

---
#### `Will this component manage state?`
*Default: (No)*  
- If **No** this will create a stateless functional react component.
- If **Yes** this will create a react component class that extends React.Component. 

---
#### `Initial component props (',' or ' ' separated)`
*Default: (none)*  
This should be a single string that lists all props for this component. The props can be either space or comma separated,
each prop will be converted to camelCase regardless of how it's entered.  

Best practice is to enter as many props as you expect this component to have when done. The generator will ask 2-3
follow up questions for each prop entered. Then create a component with the correct props, a test that expects the
props with their correct types and a will create a storybook story with a code example pre-defined with prop definitions. 

---
#### Prop Question `What is the propType of {propName}?`
*Default: string*  
Select the appropriate react propType for this prop. When selecting array or object it's expected that the developer will
change them manually to `arrayOf(x)` and `shape(x)` during development. *note* the linter will complain during
installation about these until they are changed.   

##### Options: `string`, `number`, `bool`, `func`, `symbol`, `array`, `object`, `node`, `element`

---
#### Prop Question `Is the prop {propName} required?`
*Default: Yes*  
- If **No** you will be asked to enter a default value
- If **Yes** the propType will be marked `.isRequired`

---
#### Prop Question `Default value for {propName}?`
*Default: (this changes per prop type)*  
Based on the propType some validation is performed when possible to make sure the default entered is of the correct type.  

**NOTE:** Type validation is not possible for the propTypes of `symbol`, `node`, `element`. For these types any value is
accepted so only use these if you know what you're doing. 
 
### Next Steps
The generator will copy all the files needed for a new SocialCare component and will also run `npm
install`, `yarn test`, `yarn fix`, and `yarn build`. When the instillation is complete you're ready to run the component. 

*Note if any test fail during instillation it's usually do to the component not having any engineering TLC.   
```bash
$ yarn start
```  

## Generating a sub component
This will scaffold out a component within a parent component or module. It will create component files, add a story entry
in the `.storybook/config.js` file, add an export for in the `src/components/index.js` file, and add an import in the
`src/styles.css` file.

1. ` cd ` into your components directory.
2. Run the yeoman SocialCare component sub-component generator and follow the onscreen prompts.
  ```bash
  $ yo @socialcare/component:component
  ```  
  
### Prompts

When running the component generator you'll be asked a series of questions that will determine the final code generated.
#### `Component name?`
*Default: (current directory name)*  
The name you enter here will be prepended with `@socialcare/` for the package name and the directory will be prepended
with either `sc-pkg-`, `sc-component-`, or `sc-hoc-` depending on the answer to the previous question.

---
#### `What is this component going to do / why does it exist?`
*Default: (blank)*  
This is the description that will be used in the package.json file and storybook if this is a react component. 

---
#### `Will this component manage state?`
*Default: (No)*  
- If **No** this will create a stateless functional react component.
- If **Yes** this will create a react component class that extends React.Component. 

---
#### `Initial component props (',' or ' ' separated)`
*Default: (none)*  
This should be a single string that lists all props for this component. The props can be either space or comma separated,
each prop will be converted to camelCase regardless of how it's entered.  

Best practice is to enter as many props as you expect this component to have when done. The generator will ask 2-3
follow up questions for each prop entered. Then create a component with the correct props, a test that expects the
props with their correct types and a will create a storybook story with a code example pre-defined with prop definitions. 

---
#### Prop Question `What is the propType of {propName}?`
*Default: string*  
Select the appropriate react propType for this prop. When selecting array or object it's expected that the developer will
change them manually to `arrayOf(x)` and `shape(x)` during development. *note* the linter will complain during
installation about these until they are changed.   

##### Options: `string`, `number`, `bool`, `func`, `symbol`, `array`, `object`, `node`, `element`

---
#### Prop Question `Is the prop {propName} required?`
*Default: Yes*  
- If **No** you will be asked to enter a default value
- If **Yes** the propType will be marked `.isRequired`

---
#### Prop Question `Default value for {propName}?`
*Default: (this changes per prop type)*  
Based on the propType some validation is performed when possible to make sure the default entered is of the correct type.  

**NOTE:** Type validation is not possible for the propTypes of `symbol`, `node`, `element`. For these types any value is
accepted so only use these if you know what you're doing. 
 

### Development Notes
1. When developing it's helpful to run `npm link` to link the local component into your global NPM directory. This will
allow you to make changes and run the generator normally and have it use the updated code.
2. When any edits are made they need be on a branch of master with a PR to master
3. Once the changes are merged into master you'll need to publish to other can use it.
    - Tag the updated version. This package uses [simver read more here](http://simver.org/)  
    ` $ npm version {patch|minor|major} `
    - Publish the updated version to npm  
    ` $ npm publish `    
    - Push the tagged commit up to the repo  
    `$ git push origin/master --tags`

## License

 © [Social Care](https://www.socialcare.com)