Skip to content

Add es6 option to generator #332

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 13 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,7 @@ end
### Component generator

`react-rails` ships with a Rails generator to help you get started with a simple component scaffold.
You can run it using `rails generate react:component ComponentName`.
You can run it using `rails generate react:component ComponentName (--es6)`.
The generator takes an optional list of arguments for default propTypes,
which follow the conventions set in the [Reusable Components](http://facebook.github.io/react/docs/reusable-components.html)
section of the React documentation.
Expand Down Expand Up @@ -239,6 +239,18 @@ var Post = React.createClass({
});
```

#### Options

**--es6** : Generate the same component but using cutting edge es6 class

For example:

```shell
rails generate react:component Label label:string --es6
```

#### Arguments

The generator can use the following arguments to create basic propTypes:

* any
Expand Down
7 changes: 6 additions & 1 deletion lib/generators/react/component_generator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,11 @@ class ComponentGenerator < ::Rails::Generators::NamedBase
:default => [],
:banner => "field[:type] field[:type] ..."

class_option :es6,
type: :boolean,
default: false,
desc: 'Output es6 class based component'

REACT_PROP_TYPES = {
"node" => 'React.PropTypes.node',
"bool" => 'React.PropTypes.bool',
Expand Down Expand Up @@ -80,7 +85,7 @@ class ComponentGenerator < ::Rails::Generators::NamedBase
}

def create_component_file
extension = "js.jsx"
extension = options[:es6] ? "es6.jsx" : "js.jsx"
file_path = File.join('app/assets/javascripts/components', "#{file_name}.#{extension}")
template("component.#{extension}", file_path)
end
Expand Down
23 changes: 23 additions & 0 deletions lib/generators/templates/component.es6.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
class <%= file_name.camelize %> extends React.Component {
render () {
<% if attributes.size > 0 -%>
return (
<div>
<% attributes.each do |attribute| -%>
<div><%= attribute[:name].titleize %>: {this.props.<%= attribute[:name].camelize(:lower) %>}</div>
<% end -%>
</div>
);
<% else -%>
return <div />;
<% end -%>
}
}

<% if attributes.size > 0 -%>
<%= file_name.camelize %>.propTypes = {
<% attributes.each_with_index do |attribute, idx| -%>
<%= attribute[:name].camelize(:lower) %>: <%= attribute[:type] %><% if (idx < attributes.length-1) %>,<% end %>
<% end -%>
};
<% end -%>
39 changes: 39 additions & 0 deletions test/generators/es6_component_generator_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
require 'test_helper'
require 'generators/react/component_generator'

class Es6ComponentGeneratorTest < Rails::Generators::TestCase
destination File.join(Rails.root, 'tmp', 'component_generator_test_output')
setup :prepare_destination
tests React::Generators::ComponentGenerator

def filename
'app/assets/javascripts/components/generated_component.es6.jsx'
end

def class_name
'GeneratedComponent'
end

test "uses es6 syntax" do
run_generator %w(GeneratedComponent name --es6)

assert_file filename, /^class\s#{class_name}\sextends\sReact\.Component/
end

test "assigns defaultProps after class definintion" do
run_generator %w(GeneratedComponent name --es6)

assert_file filename, /\s^#{class_name}\.propTypes/
end

test "generates working jsx" do
expected_name_div = /React\.createElement\(\s*"div",\s*null,\s*\"Name:\s*\",\s*this\.props\.name\s*\)/x
expected_shape_div = /React\.createElement\(\s*"div",\s*null,\s*\"Address:\s*\",\s*this\.props\.address\s*\)/x

run_generator %w(GeneratedComponent name:string address:shape --es6)
jsx = React::JSX.transform(File.read(File.join(destination_root, filename)))

assert_match(Regexp.new(expected_name_div), jsx)
assert_match(Regexp.new(expected_shape_div), jsx)
end
end