Skip to content

Commit 444208e

Browse files
authored
Allow customisation of the tag used to render the component. (#31)
Fixes #30
1 parent 2b53302 commit 444208e

File tree

12 files changed

+75
-17
lines changed

12 files changed

+75
-17
lines changed

CHANGELOG.md

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,17 +5,26 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/)
55
and this project adheres to [Semantic Versioning](http://semver.org/).
66

77
## [Unreleased]
8+
9+
### Added
10+
- Added a `tag` option to change the tag used to render the component (default is `div`)
11+
812
## 0.2.0 - 2017-03-20
13+
914
### Added
1015
- support for Turbolinks 5, Turbolinks 2.4 and PJAX. Components will be mounted and unmounted when Turbolinks-specific events occur. Also, the integration works with Turbolinks 5 cache.
1116
- New `WebpackerReact.setup({Component1, Component2, ...})` initialization API. The old API couldn't properly detect the components' names, thus user is required to provide the names in the configuration object's keys.
17+
1218
### Removed
1319
- `WebpackerReact.register(Component)` has been dropped in favor of `WebpackerReact.setup({Component})`
20+
21+
1422
## 0.1.0 - 2017-02-23
23+
1524
### Added
1625
- First released version
1726
- render React components from views using the `react_component` helper
1827
- render React components from controllers using `render react_component: 'name'` (#1 by @daninfpj)
1928
- basic Hot Module Remplacement (#7 by @mfazekas)
2029

21-
[Unreleased]: https://github.com/renchap/webpacker-react/compare/v0.1.0...HEAD
30+
[Unreleased]: https://github.com/renchap/webpacker-react/compare/v0.2.0...HEAD

README.md

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,12 +70,19 @@ Now you can render React components from your views or your controllers.
7070

7171
### Rendering from a view
7272

73-
Use the `react_component` helper:
73+
Use the `react_component` helper. The first argument is your component's name, the second one is the `props`:
7474

7575
```erb
7676
<%= react_component('Hello', name: 'React') %>
7777
```
7878

79+
You can pass a `tag` argument to render the React component in another tag than the default `div`. All other arguments will be passed to `content_tag`:
80+
81+
```erb
82+
<%= react_component('Hello', { name: 'React' }, tag: :span, class: 'my-custom-component') %>
83+
# This will render <span class="my-custom-component" data-react-class="Hello" data-react-props="..."></div>
84+
```
85+
7986
### Rendering from a controller
8087

8188
```rb
@@ -86,7 +93,13 @@ class PageController < ApplicationController
8693
end
8794
```
8895

89-
You can pass any of the usual arguments to render in this call: `layout`, `status`, `content_type`, etc.
96+
You can use the `tag_options` argument to change the generated HTML, similar to the `react_component` method above:
97+
98+
```rb
99+
render react_component: 'Hello', props: { name: 'React' }, tag_options: { tag: :span, class: 'my-custom-component' }
100+
```
101+
102+
You can also pass any of the usual arguments to `render` in this call: `layout`, `status`, `content_type`, etc.
90103

91104
*Note: you need to have [Webpack process your code](https://github.com/rails/webpacker#binstubs) before it is available to the browser, either by manually running `./bin/webpack` or having the `./bin/webpack-watcher` process running.*
92105

lib/webpacker/react/component.rb

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,10 @@ def initialize(name)
1111
end
1212

1313
def render(props = {}, options = {})
14+
tag = options.delete(:tag) || :div
1415
data = { data: { "react-class" => @name, "react-props" => props.to_json } }
15-
content_tag(:div, nil, options.deep_merge(data))
16+
17+
content_tag(tag, nil, options.deep_merge(data))
1618
end
1719
end
1820
end

lib/webpacker/react/railtie.rb

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@ class Engine < ::Rails::Engine
1212
initializer :webpacker_react_renderer, group: :all do |_app|
1313
ActionController::Renderers.add :react_component do |component_name, options|
1414
props = options.fetch(:props, {})
15-
html = Webpacker::React::Component.new(component_name).render(props)
15+
tag_options = options.fetch(:tag_options, {})
16+
html = Webpacker::React::Component.new(component_name).render(props, tag_options)
1617
render_options = options.merge(inline: html)
1718
render(render_options)
1819
end
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
class CustomTagController < ApplicationController
2+
def view_component
3+
end
4+
5+
def controller_component
6+
render react_component: "HelloReact", props: { name: "a component rendered from a controller in a span" }, tag_options: { tag: :span }
7+
end
8+
end
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
<%= react_component('HelloReact', { name: 'a component rendered from a view in a span' }, tag: :span) %>

test/example_app/config/routes.rb

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,5 +9,8 @@
99

1010
get "/two_packs/view_all", to: "two_packs#view_all"
1111

12+
get "/custom_tag_view", to: "custom_tag#view_component"
13+
get "/custom_tag_controller", to: "custom_tag#controller_component"
14+
1215
root to: "pages#view_component"
1316
end
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
require "test_helper"
2+
3+
class CustomTagTest < ActionDispatch::IntegrationTest
4+
test "renders from a view with a custom tag" do
5+
require_js
6+
7+
visit "/custom_tag_view"
8+
assert_selector "span[data-react-class]", text: "Hello, I am a component rendered from a view in a span!"
9+
end
10+
11+
test "renders from a controller with a custom tag" do
12+
require_js
13+
14+
visit "/custom_tag_controller"
15+
assert_selector "span[data-react-class]", text: "Hello, I am a component rendered from a controller in a span!"
16+
end
17+
end

test/integration/renderer_test.rb

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,4 @@ def url_prefix
3030
assert page.has_content? "component 1"
3131
assert page.has_content? "component 2"
3232
end
33-
34-
private
35-
36-
def require_js
37-
Capybara.current_driver = Capybara.javascript_driver
38-
end
3933
end

test/integration/renderer_with_two_packs_test.rb

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,4 @@ class RendererWithTwoPacksTest < ActionDispatch::IntegrationTest
1515
assert page.has_content? "Component A"
1616
assert page.has_content? "Component B"
1717
end
18-
19-
private
20-
21-
def require_js
22-
Capybara.current_driver = Capybara.javascript_driver
23-
end
2418
end

0 commit comments

Comments
 (0)