Skip to content

Commit e9d5cb9

Browse files
committed
Subgenerators added for component, container, reducer, and action.
1 parent da82ae3 commit e9d5cb9

File tree

17 files changed

+409
-0
lines changed

17 files changed

+409
-0
lines changed

Diff for: generators/action/index.js

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
'use strict';
2+
var yeoman = require('yeoman-generator');
3+
4+
module.exports = yeoman.generators.Base.extend({
5+
initializing: function () {
6+
this.argument('name', {
7+
required: true,
8+
type: String,
9+
desc: 'The subgenerator name'
10+
});
11+
12+
this.log('You called the WebpackReduxReact subgenerator with the argument ' + this.name + '.');
13+
},
14+
15+
writing: function () {
16+
this.fs.copy(
17+
this.templatePath('somefile.js'),
18+
this.destinationPath('somefile.js')
19+
);
20+
}
21+
});

Diff for: generators/action/templates/somefile.js

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
// This is a file copied by your subgenerator

Diff for: generators/component/index.js

+39
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
'use strict';
2+
var yeoman = require('yeoman-generator');
3+
var _ = require('lodash');
4+
5+
module.exports = yeoman.generators.Base.extend({
6+
initializing: function () {
7+
this.argument('name', {
8+
required: true,
9+
type: String,
10+
desc: 'The subgenerator name'
11+
});
12+
13+
this.log('You called the Component subgenerator with the argument ' + this.name + '.');
14+
},
15+
prompting: function () {
16+
var done = this.async();
17+
18+
var prompts = [{
19+
type: 'confirm',
20+
name: 'addStyle',
21+
message: 'Do you want to include an SCSS file for styles?',
22+
default: true
23+
}];
24+
25+
this.prompt(prompts, function (props) {
26+
this.props = props;
27+
// To access props later use this.props.someOption;
28+
done();
29+
}.bind(this));
30+
},
31+
writing: function () {
32+
if(this.props.addStyle){
33+
this.template('_style.js', 'components/'+ this.name + '/' + this.name + '.js', this.templateContext);
34+
this.template('_main.scss', 'components/'+ this.name + '/' + this.name + '.scss', this.templateContext);
35+
} else {
36+
this.template('_noStyle.js', 'components/'+ this.name + '/' + this.name + '.js', this.templateContext);
37+
}
38+
}
39+
});

Diff for: generators/component/templates/_main.scss

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
.<%= name %> {
2+
3+
}

Diff for: generators/component/templates/_noStyle.js

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import React, {Component, PropTypes} from 'react';
2+
3+
class <%= name %> extends Component {
4+
constructor(props){
5+
super(props);
6+
}
7+
render(){
8+
return (
9+
<div>
10+
11+
</div>
12+
);
13+
}
14+
}
15+
16+
export default <%= name %>

Diff for: generators/component/templates/_style.js

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import React, {Component, PropTypes} from 'react';
2+
import './<%= name %>.scss';
3+
4+
class <%= name %> extends Component {
5+
constructor(props){
6+
super(props);
7+
}
8+
render(){
9+
return (
10+
<div className="<%= name %>">
11+
12+
</div>
13+
);
14+
}
15+
}
16+
17+
export default <%= name %>

Diff for: generators/container/index.js

+40
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
'use strict';
2+
var yeoman = require('yeoman-generator');
3+
var _ = require('lodash');
4+
var chalk = require('chalk');
5+
6+
module.exports = yeoman.generators.Base.extend({
7+
initializing: function () {
8+
this.argument('name', {
9+
required: true,
10+
type: String,
11+
desc: 'The subgenerator name'
12+
});
13+
this.capsName = _.capitalize(this.name);
14+
this.camelName = this.name.toLowerCase().charAt(0).toUpperCase().slice(1); //Capitalize first letter only
15+
// this.log('You called the Component subgenerator with the argument ' + this.name + '.');
16+
},
17+
prompting: function () {
18+
var done = this.async();
19+
20+
var prompts = [{
21+
type: 'confirm',
22+
name: 'addAction',
23+
message: 'Do you want to create an action file for this component?\n' + chalk.red('WARNING:This will overwrite an existing action file of the same name.') + '\n',
24+
default: false
25+
}];
26+
27+
this.prompt(prompts, function (props) {
28+
this.props = props;
29+
// To access props later use this.props.someOption;
30+
done();
31+
}.bind(this));
32+
},
33+
writing: function () {
34+
if(this.props.addAction){
35+
this.template('_action.js', 'actions/' + this.name.toLowerCase() + '.js', this.templateContext);
36+
}
37+
this.template('_main.js', 'containers/'+ this.name + '/' + this.name + '.js', this.templateContext);
38+
this.template('_main.scss', 'containers/'+ this.name + '/' + this.name + '.scss',this.templateContext);
39+
}
40+
});

Diff for: generators/container/templates/_action.js

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
export const ADD_<%= capsName %> = 'ADD_<%= capsName %>';
2+
export const REMOVE_<%= capsName %> = 'REMOVE_<%= capsName %>';
3+
export const UPDATE_<%= capsName %> = 'UPDATE_<%= capsName %>';
4+
5+
export function add<%= camelName %>(<%= name.toLowerCase() %>) {
6+
return {
7+
type: 'ADD_<%= capsName %>',
8+
payload: '<%= name.toLowerCase() %>'
9+
};
10+
}
11+
export function remove<%= camelName %>(<%= name.toLowerCase() %>) {
12+
return {
13+
type: 'REMOVE_<%= capsName %>',
14+
payload: '<%= name.toLowerCase() %>'
15+
};
16+
}
17+
export function update<%= camelName %>(<%= name.toLowerCase() %>) {
18+
return {
19+
type: 'UPDATE_<%= capsName %>',
20+
payload: '<%= name.toLowerCase() %>'
21+
};
22+
}

Diff for: generators/container/templates/_main.js

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import React, {Component, PropTypes} from 'react';
2+
import {bindActionCreators} from 'redux';
3+
import {connect} from 'react-redux';
4+
5+
import * as Actions from '../../actions/<%= name %>';
6+
import './<%= name %>.scss';
7+
8+
class <%= name %> extends Component {
9+
constructor(props){
10+
super(props);
11+
}
12+
render(){
13+
return (
14+
<div className="<%= name %>">
15+
16+
</div>
17+
);
18+
}
19+
}
20+
21+
export default <%= name %>

Diff for: generators/container/templates/_main.scss

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
.<%= name %> {
2+
3+
}

Diff for: generators/reducer/index.js

+52
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
'use strict';
2+
var yeoman = require('yeoman-generator');
3+
var _ = require('lodash');
4+
var chalk = require('chalk');
5+
module.exports = yeoman.generators.Base.extend({
6+
initializing: function () {
7+
this.argument('name', {
8+
required: true,
9+
type: String,
10+
desc: 'The reducers name'
11+
});
12+
this.capsName = this.name.toUpperCase();
13+
this.singularName = this.name.toLowerCase().charAt(this.name.length - 1) == 's' ? this.name.substring(0, this.name.length - 1): this.name;
14+
this.camelName = _.capitalize(this.name); //Capitalize first letter only
15+
// this.log('You called the WebpackReduxReact subgenerator with the argument ' + this.name + '.');
16+
},
17+
prompting: function () {
18+
var done = this.async();
19+
20+
var prompts = [{
21+
type: 'list',
22+
name: 'stateType',
23+
message: 'What type of state is this reducer reducing to?',
24+
choices: [
25+
{name: 'Array', value: 'array'},
26+
{name: 'Object', value: 'object'},
27+
{name: 'No Clue', value: 'array'},
28+
]
29+
}];
30+
31+
this.prompt(prompts, function (props) {
32+
this.props = props;
33+
// To access props later use this.props.someOption;
34+
done();
35+
}.bind(this));
36+
},
37+
writing: function () {
38+
this.log('state type: ', this.props.stateType);
39+
this.log('props: ', this.props);
40+
41+
switch(this.props.stateType){
42+
case 'array':
43+
this.template('_array.js', 'reducers/' + this.name.toLowerCase() + '.js', this.templateContext);
44+
break;
45+
case 'object':
46+
this.template('_object.js', 'reducers/' + this.name.toLowerCase() + '.js', this.templateContext);
47+
break;
48+
default :
49+
this.template('_array.js', 'reducers/' + this.name.toLowerCase() + '.js', this.templateContext);
50+
}
51+
}
52+
});

Diff for: generators/reducer/templates/_array.js

+45
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
import {
2+
ADD_<%= singularName.toUpperCase() %>,
3+
UPDATE_<%= singularName.toUpperCase() %>,
4+
REMOVE_<%= singularName.toUpperCase() %>,
5+
} from '../actions/<%= name.toLowerCase() %>';
6+
import {union, clone} from 'lodash';
7+
export default function <%= name.toLowerCase() %>(state = [], action) {
8+
switch (action.type) {
9+
case ADD_<%= singularName.toUpperCase() %>:
10+
if(!action.payload){
11+
console.error('Payload required to add a <%= name %>');
12+
return state;
13+
}
14+
return [...state, action.payload];
15+
break;
16+
case UPDATE_<%= singularName.toUpperCase() %>:
17+
if(!action.index && action.payload){
18+
console.error('Index and payload required to update a <%= name %>');
19+
return state;
20+
}
21+
if(!state[action.name]){
22+
console.error('<%= name %> with that name already exists');
23+
return state;
24+
}
25+
let newState = clone(state);
26+
newState[action.index] = action.payload;
27+
return newState;
28+
break;
29+
case REMOVE_<%= singularName.toUpperCase() %>:
30+
if(!action.index){
31+
console.error('Index required to delete a <%= name %>');
32+
return state;
33+
}
34+
if(!state[action.index]){
35+
console.error('<%= name %> at that index does not exist');
36+
return state;
37+
}
38+
let newState = clone(state);
39+
delete newState[action.index];
40+
return newState;
41+
break;
42+
default:
43+
return state;
44+
}
45+
}

Diff for: generators/reducer/templates/_object.js

+49
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
import {
2+
ADD_<%= singularName.toUpperCase() %>,
3+
UPDATE_<%= singularName.toUpperCase() %>,
4+
REMOVE_<%= singularName.toUpperCase() %>,
5+
} from '../actions/<%= name.toLowerCase() %>';
6+
import {merge, clone} from 'lodash';
7+
8+
export default function <%= name.toLowerCase() %>(state = {}, action) {
9+
switch (action.type) {
10+
case ADD_<%= singularName.toUpperCase() %>:
11+
if(!action.name){
12+
console.error('Name is required to add a <%= camelName %>');
13+
return state;
14+
}
15+
if(!state[action.name]){
16+
console.error('<%= camelName %> with that name already exists');
17+
return state;
18+
}
19+
let newState = {};
20+
newState[action.name] = action.payload;
21+
return merge({}, state, newState);
22+
case UPDATE_<%= singularName.toUpperCase() %>:
23+
if(!action.name){
24+
console.error('Name is required to update a <%= camelName %>');
25+
return state;
26+
}
27+
if(!state[action.name]){
28+
console.error('<%= camelName %> with that name not found');
29+
return state;
30+
}
31+
let newState = clone(state);
32+
newState[action.name] = action.payload;
33+
return merge({}, state, newState);
34+
case REMOVE_<%= singularName.toUpperCase() %>:
35+
if(!action.name){
36+
console.error('Name is required to remove a <%= camelName %>');
37+
return state;
38+
}
39+
if(!state[action.name]){
40+
console.error('<%= camelName %> with that name not found');
41+
return state;
42+
}
43+
let newState = clone(state);
44+
newState[action.name] = action.payload;
45+
return merge({}, state, newState);
46+
default:
47+
return state;
48+
}
49+
}

Diff for: test/action.js

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
'use strict';
2+
3+
var path = require('path');
4+
var assert = require('yeoman-generator').assert;
5+
var helpers = require('yeoman-generator').test;
6+
7+
describe('WebpackReduxReact:generators/action', function () {
8+
before(function (done) {
9+
helpers.run(path.join(__dirname, '../generators/action'))
10+
.withArguments('name')
11+
.withOptions({ skipInstall: true, force: true })
12+
.on('end', done);
13+
});
14+
15+
it('creates files', function () {
16+
assert.file([
17+
'somefile.js'
18+
]);
19+
});
20+
});

Diff for: test/component.js

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
'use strict';
2+
3+
var path = require('path');
4+
var assert = require('yeoman-generator').assert;
5+
var helpers = require('yeoman-generator').test;
6+
7+
describe('WebpackReduxReact:generators/component', function () {
8+
before(function (done) {
9+
helpers.run(path.join(__dirname, '../generators/component'))
10+
.withArguments('name')
11+
.withOptions({ skipInstall: true, force: true })
12+
.on('end', done);
13+
});
14+
15+
it('creates files', function () {
16+
assert.file([
17+
'somefile.js'
18+
]);
19+
});
20+
});

0 commit comments

Comments
 (0)