Skip to content
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
8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,14 @@ For example:
rails generate react:component Label label:string --es6
```

**--coffee** : Generate the component using CoffeeScript syntax

For example:

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

#### Arguments

The generator can use the following arguments to create basic propTypes:
Expand Down
21 changes: 17 additions & 4 deletions lib/generators/react/component_generator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,14 @@ class ComponentGenerator < ::Rails::Generators::NamedBase
:banner => "field[:type] field[:type] ..."

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

class_option :coffee,
type: :boolean,
default: false,
desc: 'Output coffeescript based component'

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

def create_component_file
extension = options[:es6] ? "es6.jsx" : "js.jsx"
extension = case
when options[:es6]
'es6.jsx'
when options[:coffee]
'js.jsx.coffee'
else
'js.jsx'
end

file_path = File.join('app/assets/javascripts/components', "#{file_name}.#{extension}")
template("component.#{extension}", file_path)
end
Expand Down
18 changes: 18 additions & 0 deletions lib/generators/templates/component.js.jsx.coffee
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
class @<%= file_name.camelize %> extends React.Component
<% if attributes.size > 0 -%>
@propTypes =
<% attributes.each do |attribute| -%>
<%= attribute[:name].camelize(:lower) %>: <%= attribute[:type] %>
<% end -%>

<% end -%>
render: ->
<% if attributes.size > 0 -%>
`<div>
<% attributes.each do |attribute| -%>
<div><%= attribute[:name].titleize %>: {this.props.<%= attribute[:name].camelize(:lower) %>}</div>
<% end -%>
</div>`
<% else -%>
`<div />`
<% end -%>
40 changes: 40 additions & 0 deletions test/generators/coffee_component_generator_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
require 'test_helper'
require 'generators/react/component_generator'

class CoffeeComponentGeneratorTest < 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.js.jsx.coffee'
end

def class_name
'GeneratedComponent'
end

test 'that it the uses CoffeeScript syntax' do
run_generator %w(GeneratedComponent name --coffee)

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

test 'that propTypes get assigned' do
run_generator %w(GeneratedComponent name --coffee)

assert_file filename, /@propTypes\s=/
assert_file filename, /React.PropTypes/
end

test 'that it 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 --coffee)
jsx = React::JSX.transform(CoffeeScript.compile(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