actionview-component 1.6.2 → 1.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.github/ISSUE_TEMPLATE +3 -8
- data/.github/PULL_REQUEST_TEMPLATE +2 -4
- data/.github/workflows/ruby_on_rails.yml +2 -2
- data/.gitignore +1 -0
- data/.rubocop.yml +4 -0
- data/CHANGELOG.md +52 -0
- data/CONTRIBUTING.md +5 -14
- data/Gemfile.lock +1 -1
- data/README.md +258 -26
- data/lib/action_view/component.rb +1 -0
- data/lib/action_view/component/base.rb +89 -31
- data/lib/action_view/component/preview.rb +7 -15
- data/lib/action_view/component/railtie.rb +1 -4
- data/lib/action_view/component/render_monkey_patch.rb +11 -6
- data/lib/action_view/component/template_error.rb +11 -0
- data/lib/action_view/component/test_helpers.rb +1 -1
- data/lib/action_view/component/version.rb +2 -2
- data/lib/rails/generators/component/component_generator.rb +2 -2
- data/lib/rails/generators/rspec/component_generator.rb +1 -1
- data/lib/rails/generators/test_unit/component_generator.rb +1 -1
- data/lib/railties/lib/rails.rb +0 -1
- data/lib/railties/lib/rails/components_controller.rb +5 -1
- data/lib/railties/lib/rails/templates/rails/components/preview.html.erb +1 -1
- metadata +3 -4
- data/lib/railties/lib/rails/component_examples_controller.rb +0 -9
- data/lib/railties/lib/rails/templates/rails/examples/show.html.erb +0 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: c20b9ae371123eb58c62aa3c093baafdf7d5745bf8311ff2fb975c70282e6dfd
|
|
4
|
+
data.tar.gz: caaad9f6e645602efe2faea055ff08dd1f548efe08b503a3048d83eebc824997
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 52aec02cba11b482df4c4e4f160ad7602dadca664eb75a4fad579fb5802c9f4efb6a7e07f1082ab634e99c9ed8efad82861daf1fdc9c5108cdf63e3f2b0f80d1
|
|
7
|
+
data.tar.gz: 4d5fb555f12740dfa62a64b4c9b095879e4ea182a3930f9a725482525c6d5bbeae08d9914dff847e8521a7107f31b13b919f5b9d5cc69d83cbaf53c08422503c
|
data/.github/ISSUE_TEMPLATE
CHANGED
|
@@ -6,17 +6,12 @@
|
|
|
6
6
|
### Motivation
|
|
7
7
|
|
|
8
8
|
<!-- What would you like to do with this feature? Can you provide
|
|
9
|
-
context or references to similar behavior in other libraries
|
|
9
|
+
context or references to similar behavior in other libraries? -->
|
|
10
10
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
<!-- **** Filing a Bug Report? Include these sections. **** -->
|
|
11
|
+
<!-- **** Filing a Bug Report? Include these sections: **** -->
|
|
16
12
|
|
|
17
13
|
### Steps to reproduce
|
|
18
|
-
<!-- Provide
|
|
19
|
-
demonstrate the bug you've identified. -->
|
|
14
|
+
<!-- Provide a series of steps or, better yet, a link to a repo to demonstrate the bug you've identified. -->
|
|
20
15
|
|
|
21
16
|
### Expected behavior
|
|
22
17
|
<!-- Tell us what should happen -->
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
<!-- https://github.com/github/actionview-component/blob/master/CONTRIBUTING.md#submitting-a-pull-request -->
|
|
1
|
+
<!-- See https://github.com/github/actionview-component/blob/master/CONTRIBUTING.md#submitting-a-pull-request -->
|
|
2
2
|
|
|
3
3
|
### Summary
|
|
4
4
|
|
|
@@ -14,6 +14,4 @@ request, mention that information here. This could include
|
|
|
14
14
|
benchmarks, or other information.
|
|
15
15
|
|
|
16
16
|
If you are updating any of the CHANGELOG files or are asked to update the
|
|
17
|
-
CHANGELOG files by reviewers, please add the CHANGELOG entry at the top of the file.
|
|
18
|
-
|
|
19
|
-
Thanks for contributing to actionview-component! -->
|
|
17
|
+
CHANGELOG files by reviewers, please add the CHANGELOG entry at the top of the file. -->
|
|
@@ -8,7 +8,7 @@ jobs:
|
|
|
8
8
|
strategy:
|
|
9
9
|
matrix:
|
|
10
10
|
rails_version: [5.0.0, 5.2.3, 6.0.0, master]
|
|
11
|
-
ruby_version: [2.
|
|
11
|
+
ruby_version: [2.5.x, 2.6.x, 2.7.x]
|
|
12
12
|
exclude:
|
|
13
13
|
- rails_version: master
|
|
14
14
|
ruby_version: 2.4.x
|
|
@@ -22,7 +22,7 @@ jobs:
|
|
|
22
22
|
ruby-version: ${{ matrix.ruby_version }}
|
|
23
23
|
- name: Build and test with Rake
|
|
24
24
|
run: |
|
|
25
|
-
gem install bundler:1.
|
|
25
|
+
gem install bundler:1.17.3
|
|
26
26
|
bundle update
|
|
27
27
|
bundle install --jobs 4 --retry 3
|
|
28
28
|
bundle exec rake
|
data/.gitignore
CHANGED
data/.rubocop.yml
CHANGED
data/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,55 @@
|
|
|
1
|
+
# v1.10.0
|
|
2
|
+
|
|
3
|
+
* Deprecate all `render` syntaxes except for `render(MyComponent.new(foo: :bar))`
|
|
4
|
+
|
|
5
|
+
# v1.9.0
|
|
6
|
+
|
|
7
|
+
* Remove initializer requirement for Ruby 2.7+
|
|
8
|
+
|
|
9
|
+
*Dylan Clark*
|
|
10
|
+
|
|
11
|
+
# v1.8.1
|
|
12
|
+
|
|
13
|
+
* Run validation checks before calling `#render?`.
|
|
14
|
+
|
|
15
|
+
*Ash Wilson*
|
|
16
|
+
|
|
17
|
+
# v1.8.0
|
|
18
|
+
|
|
19
|
+
* Remove the unneeded ComponentExamplesController and simplify preview rendering.
|
|
20
|
+
|
|
21
|
+
*Jon Palmer*
|
|
22
|
+
|
|
23
|
+
* Add `#render?` hook to easily allow components to be no-ops.
|
|
24
|
+
|
|
25
|
+
*Kyle Fox*
|
|
26
|
+
|
|
27
|
+
* Don't assume ApplicationController exists.
|
|
28
|
+
|
|
29
|
+
*Jon Palmer*
|
|
30
|
+
|
|
31
|
+
* Allow some additional checks to overrided render?
|
|
32
|
+
|
|
33
|
+
*Sergey Malykh*
|
|
34
|
+
|
|
35
|
+
* Fix generator placing namespaced components in the root directory.
|
|
36
|
+
|
|
37
|
+
*Asger Behncke Jacobsen*
|
|
38
|
+
|
|
39
|
+
* Fix cache test.
|
|
40
|
+
|
|
41
|
+
*Sergey Malykh*
|
|
42
|
+
|
|
43
|
+
# v1.7.0
|
|
44
|
+
|
|
45
|
+
* Simplify validation of templates and compilation.
|
|
46
|
+
|
|
47
|
+
*Jon Palmer*
|
|
48
|
+
|
|
49
|
+
* Add support for multiple content areas.
|
|
50
|
+
|
|
51
|
+
*Jon Palmer*
|
|
52
|
+
|
|
1
53
|
# v1.6.2
|
|
2
54
|
|
|
3
55
|
* Fix Uninitialized Constant error.
|
data/CONTRIBUTING.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
# Contributing
|
|
2
2
|
|
|
3
3
|
[fork]: https://github.com/github/actionview-component/fork
|
|
4
4
|
[pr]: https://github.com/github/actionview-component/compare
|
|
@@ -15,9 +15,11 @@ Please note that this project is released with a [Contributor Code of Conduct][c
|
|
|
15
15
|
|
|
16
16
|
0. [Fork][fork] and clone the repository
|
|
17
17
|
0. Configure and install the dependencies: `bundle`
|
|
18
|
-
0. Make sure the tests pass on your machine: `rake`
|
|
18
|
+
0. Make sure the tests pass on your machine: `bundle exec rake`
|
|
19
19
|
0. Create a new branch: `git checkout -b my-branch-name`
|
|
20
20
|
0. Make your change, add tests, and make sure the tests still pass
|
|
21
|
+
0. Add an entry to the top of `CHANGELOG.md` for your changes
|
|
22
|
+
0. If it's your first time contributing, add yourself to the contributors at the bottom of `README.md`
|
|
21
23
|
0. Push to your fork and [submit a pull request][pr]
|
|
22
24
|
0. Pat your self on the back and wait for your pull request to be reviewed and merged.
|
|
23
25
|
|
|
@@ -32,24 +34,13 @@ Here are a few things you can do that will increase the likelihood of your pull
|
|
|
32
34
|
If you are the current maintainer of this gem:
|
|
33
35
|
|
|
34
36
|
1. Create a branch for the release: `git checkout -b release-vxx.xx.xx`
|
|
35
|
-
1. Bump gem version in `lib/action_view/component/version.rb`.
|
|
37
|
+
1. Bump gem version in `lib/action_view/component/version.rb`. Try to adhere to SemVer.
|
|
36
38
|
1. Add version heading/entries to `CHANGELOG.md`.
|
|
37
39
|
1. Make sure your local dependencies are up to date: `bundle`
|
|
38
40
|
1. Ensure that tests are green: `bundle exec rake`
|
|
39
|
-
1. Build a test gem `GEM_VERSION=$(git describe --tags 2>/dev/null | sed 's/-/./g' | sed 's/v//') gem build actionview-component.gemspec`
|
|
40
|
-
1. Test the test gem:
|
|
41
|
-
1. Bump the Gemfile and Gemfile.lock versions for an app which relies on this gem
|
|
42
|
-
1. Install the new gem locally
|
|
43
|
-
1. Test behavior locally, branch deploy, whatever needs to happen
|
|
44
41
|
1. Make a PR to github/actionview-component.
|
|
45
42
|
1. Build a local gem: `gem build actionview-component.gemspec`
|
|
46
43
|
1. Merge github/actionview-component PR
|
|
47
44
|
1. Tag and push: `git tag vx.xx.xx; git push --tags`
|
|
48
45
|
1. Create a GitHub release with the pushed tag (https://github.com/github/actionview-component/releases/new) and populate it with a list of the commits from `git log --pretty=format:"- %s" --reverse refs/tags/[OLD TAG]...refs/tags/[NEW TAG]`
|
|
49
46
|
1. Push to rubygems.org -- `gem push actionview-component-VERSION.gem`
|
|
50
|
-
|
|
51
|
-
## Resources
|
|
52
|
-
|
|
53
|
-
- [How to Contribute to Open Source](https://opensource.guide/how-to-contribute/)
|
|
54
|
-
- [Using Pull Requests](https://help.github.com/articles/about-pull-requests/)
|
|
55
|
-
- [GitHub Help](https://help.github.com)
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
|
@@ -15,7 +15,7 @@ As the goal of this gem is to be upstreamed into Rails, it is designed to integr
|
|
|
15
15
|
|
|
16
16
|
## Compatibility
|
|
17
17
|
|
|
18
|
-
`actionview-component` is tested for compatibility with combinations of Ruby `2.
|
|
18
|
+
`actionview-component` is tested for compatibility with combinations of Ruby `2.5`/`2.6` and Rails `5.0.0`/`5.2.3`/`6.0.0`/`6.1.0.alpha`.
|
|
19
19
|
|
|
20
20
|
## Installation
|
|
21
21
|
Add this line to your application's Gemfile:
|
|
@@ -144,7 +144,7 @@ end
|
|
|
144
144
|
We can render it in a view as:
|
|
145
145
|
|
|
146
146
|
```erb
|
|
147
|
-
<%= render(TestComponent
|
|
147
|
+
<%= render(TestComponent.new(title: "my title")) do %>
|
|
148
148
|
Hello, World!
|
|
149
149
|
<% end %>
|
|
150
150
|
```
|
|
@@ -155,49 +155,237 @@ Which returns:
|
|
|
155
155
|
<span title="my title">Hello, World!</span>
|
|
156
156
|
```
|
|
157
157
|
|
|
158
|
-
|
|
158
|
+
#### Error case
|
|
159
|
+
|
|
160
|
+
If the component is rendered with a blank title:
|
|
161
|
+
|
|
162
|
+
```erb
|
|
163
|
+
<%= render(TestComponent.new(title: "")) do %>
|
|
164
|
+
Hello, World!
|
|
165
|
+
<% end %>
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
An error will be raised:
|
|
169
|
+
|
|
170
|
+
`ActiveModel::ValidationError: Validation failed: Title can't be blank`
|
|
171
|
+
|
|
172
|
+
#### Content Areas
|
|
173
|
+
|
|
174
|
+
A component can declare additional content areas to be rendered in the component. For example:
|
|
159
175
|
|
|
160
|
-
|
|
176
|
+
`app/components/modal_component.rb`:
|
|
177
|
+
```ruby
|
|
178
|
+
class ModalComponent < ActionView::Component::Base
|
|
179
|
+
validates :user, :header, :body, presence: true
|
|
161
180
|
|
|
162
|
-
|
|
181
|
+
with_content_areas :header, :body
|
|
163
182
|
|
|
164
|
-
|
|
183
|
+
def initialize(user:)
|
|
184
|
+
@user = user
|
|
185
|
+
end
|
|
186
|
+
end
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
`app/components/modal_component.html.erb`:
|
|
190
|
+
```erb
|
|
191
|
+
<div class="modal">
|
|
192
|
+
<div class="header"><%= header %></div>
|
|
193
|
+
<div class="body"><%= body %>"></div>
|
|
194
|
+
</div>
|
|
195
|
+
```
|
|
165
196
|
|
|
166
|
-
|
|
197
|
+
We can render it in a view as:
|
|
167
198
|
|
|
168
|
-
|
|
199
|
+
```erb
|
|
200
|
+
<%= render(ModalComponent.new(user: {name: 'Jane'})) do |component| %>
|
|
201
|
+
<% component.with(:header) do %>
|
|
202
|
+
Hello <%= user[:name] %>
|
|
203
|
+
<% end %>
|
|
204
|
+
<% component.with(:body) do %>
|
|
205
|
+
<p>Have a great day.</p>
|
|
206
|
+
<% end %>
|
|
207
|
+
<% end %>
|
|
208
|
+
```
|
|
169
209
|
|
|
170
|
-
|
|
210
|
+
Which returns:
|
|
171
211
|
|
|
172
|
-
|
|
212
|
+
```html
|
|
213
|
+
<div class="modal">
|
|
214
|
+
<div class="header">Hello Jane</div>
|
|
215
|
+
<div class="body"><p>Have a great day.</p></div>
|
|
216
|
+
</div>
|
|
217
|
+
```
|
|
173
218
|
|
|
174
|
-
|
|
219
|
+
Content for content areas can be passed as arguments to the render method or as named blocks passed to the `with` method.
|
|
220
|
+
This allows a few different combinations of ways to render the component:
|
|
175
221
|
|
|
222
|
+
##### Required render argument optionally overridden or wrapped by a named block
|
|
223
|
+
|
|
224
|
+
`app/components/modal_component.rb`:
|
|
176
225
|
```ruby
|
|
177
|
-
class
|
|
178
|
-
|
|
179
|
-
|
|
226
|
+
class ModalComponent < ActionView::Component::Base
|
|
227
|
+
validates :header, :body, presence: true
|
|
228
|
+
|
|
229
|
+
with_content_areas :header, :body
|
|
230
|
+
|
|
231
|
+
def initialize(header:)
|
|
232
|
+
@header = header
|
|
180
233
|
end
|
|
181
234
|
end
|
|
182
235
|
```
|
|
183
236
|
|
|
184
|
-
|
|
237
|
+
```erb
|
|
238
|
+
<%= render(ModalComponent.new(header: "Hi!")) do |component| %>
|
|
239
|
+
<% help_enabled? && component.with(:header) do %>
|
|
240
|
+
<span class="help_icon"><%= component.header %></span>
|
|
241
|
+
<% end %>
|
|
242
|
+
<% component.with(:body) do %>
|
|
243
|
+
<p>Have a great day.</p>
|
|
244
|
+
<% end %>
|
|
245
|
+
<% end %>
|
|
246
|
+
```
|
|
185
247
|
|
|
186
|
-
|
|
248
|
+
##### Required argument passed by render argument or by named block
|
|
187
249
|
|
|
188
|
-
|
|
250
|
+
`app/components/modal_component.rb`:
|
|
251
|
+
```ruby
|
|
252
|
+
class ModalComponent < ActionView::Component::Base
|
|
253
|
+
validates :header, :body, presence: true
|
|
189
254
|
|
|
190
|
-
|
|
255
|
+
with_content_areas :header, :body
|
|
191
256
|
|
|
257
|
+
def initialize(header: nil)
|
|
258
|
+
@header = header
|
|
259
|
+
end
|
|
260
|
+
end
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
`app/views/render_arg.html.erb`:
|
|
192
264
|
```erb
|
|
193
|
-
<%= render(
|
|
194
|
-
|
|
265
|
+
<%= render(ModalComponent.new(header: "Hi!")) do |component| %>
|
|
266
|
+
<% component.with(:body) do %>
|
|
267
|
+
<p>Have a great day.</p>
|
|
268
|
+
<% end %>
|
|
195
269
|
<% end %>
|
|
196
270
|
```
|
|
197
271
|
|
|
198
|
-
|
|
272
|
+
`app/views/with_block.html.erb`:
|
|
273
|
+
```erb
|
|
274
|
+
<%= render(ModalComponent) do |component| %>
|
|
275
|
+
<% component.with(:header) do %>
|
|
276
|
+
<span class="help_icon">Hello</span>
|
|
277
|
+
<% end %>
|
|
278
|
+
<% component.with(:body) do %>
|
|
279
|
+
<p>Have a great day.</p>
|
|
280
|
+
<% end %>
|
|
281
|
+
<% end %>
|
|
282
|
+
```
|
|
199
283
|
|
|
200
|
-
|
|
284
|
+
##### Optional argument passed by render argument, by named block, or neither
|
|
285
|
+
|
|
286
|
+
`app/components/modal_component.rb`:
|
|
287
|
+
```ruby
|
|
288
|
+
class ModalComponent < ActionView::Component::Base
|
|
289
|
+
validates :body, presence: true
|
|
290
|
+
|
|
291
|
+
with_content_areas :header, :body
|
|
292
|
+
|
|
293
|
+
def initialize(header: nil)
|
|
294
|
+
@header = header
|
|
295
|
+
end
|
|
296
|
+
end
|
|
297
|
+
```
|
|
298
|
+
|
|
299
|
+
`app/components/modal_component.html.erb`:
|
|
300
|
+
```erb
|
|
301
|
+
<div class="modal">
|
|
302
|
+
<% if header %>
|
|
303
|
+
<div class="header"><%= header %></div>
|
|
304
|
+
<% end %>
|
|
305
|
+
<div class="body"><%= body %>"></div>
|
|
306
|
+
</div>
|
|
307
|
+
```
|
|
308
|
+
|
|
309
|
+
`app/views/render_arg.html.erb`:
|
|
310
|
+
```erb
|
|
311
|
+
<%= render(ModalComponent.new(header: "Hi!")) do |component| %>
|
|
312
|
+
<% component.with(:body) do %>
|
|
313
|
+
<p>Have a great day.</p>
|
|
314
|
+
<% end %>
|
|
315
|
+
<% end %>
|
|
316
|
+
```
|
|
317
|
+
|
|
318
|
+
`app/views/with_block.html.erb`:
|
|
319
|
+
```erb
|
|
320
|
+
<%= render(ModalComponent.new) do |component| %>
|
|
321
|
+
<% component.with(:header) do %>
|
|
322
|
+
<span class="help_icon">Hello</span>
|
|
323
|
+
<% end %>
|
|
324
|
+
<% component.with(:body) do %>
|
|
325
|
+
<p>Have a great day.</p>
|
|
326
|
+
<% end %>
|
|
327
|
+
<% end %>
|
|
328
|
+
```
|
|
329
|
+
|
|
330
|
+
`app/views/no_header.html.erb`:
|
|
331
|
+
```erb
|
|
332
|
+
<%= render(ModalComponent.new) do |component| %>
|
|
333
|
+
<% component.with(:body) do %>
|
|
334
|
+
<p>Have a great day.</p>
|
|
335
|
+
<% end %>
|
|
336
|
+
<% end %>
|
|
337
|
+
```
|
|
338
|
+
|
|
339
|
+
### Conditional Rendering
|
|
340
|
+
|
|
341
|
+
Components can implement a `#render?` method which indicates if they should be rendered, or not at all.
|
|
342
|
+
|
|
343
|
+
For example, you might have a component that displays a "Please confirm your email address" banner to users who haven't confirmed their email address. The logic for rendering the banner would need to go in either the component template:
|
|
344
|
+
|
|
345
|
+
```
|
|
346
|
+
<!-- app/components/confirm_email_component.html.erb -->
|
|
347
|
+
<% if user.requires_confirmation? %>
|
|
348
|
+
<div class="alert">
|
|
349
|
+
Please confirm your email address.
|
|
350
|
+
</div>
|
|
351
|
+
<% end %>
|
|
352
|
+
```
|
|
353
|
+
|
|
354
|
+
or the view that renders the component:
|
|
355
|
+
|
|
356
|
+
```erb
|
|
357
|
+
<!-- app/views/_banners.html.erb -->
|
|
358
|
+
<% if current_user.requires_confirmation? %>
|
|
359
|
+
<%= render(ConfirmEmailComponent.new(user: current_user)) %>
|
|
360
|
+
<% end %>
|
|
361
|
+
```
|
|
362
|
+
|
|
363
|
+
The `#render?` hook allows you to move this logic into the Ruby class, leaving your views more readable and declarative in style:
|
|
364
|
+
|
|
365
|
+
```ruby
|
|
366
|
+
# app/components/confirm_email_component.rb
|
|
367
|
+
class ConfirmEmailComponent < ApplicationComponent
|
|
368
|
+
def initialize(user:)
|
|
369
|
+
@user = user
|
|
370
|
+
end
|
|
371
|
+
|
|
372
|
+
def render?
|
|
373
|
+
@user.requires_confirmation?
|
|
374
|
+
end
|
|
375
|
+
end
|
|
376
|
+
```
|
|
377
|
+
|
|
378
|
+
```
|
|
379
|
+
<!-- app/components/confirm_email_component.html.erb -->
|
|
380
|
+
<div class="banner">
|
|
381
|
+
Please confirm your email address.
|
|
382
|
+
</div>
|
|
383
|
+
```
|
|
384
|
+
|
|
385
|
+
```erb
|
|
386
|
+
<!-- app/views/_banners.html.erb -->
|
|
387
|
+
<%= render(ConfirmEmailComponent.new(user: current_user)) %>
|
|
388
|
+
```
|
|
201
389
|
|
|
202
390
|
### Testing
|
|
203
391
|
|
|
@@ -210,7 +398,7 @@ class MyComponentTest < ActionView::Component::TestCase
|
|
|
210
398
|
test "render component" do
|
|
211
399
|
assert_equal(
|
|
212
400
|
%(<span title="my title">Hello, World!</span>),
|
|
213
|
-
render_inline(TestComponent
|
|
401
|
+
render_inline(TestComponent.new(title: "my title")) { "Hello, World!" }.to_html
|
|
214
402
|
)
|
|
215
403
|
end
|
|
216
404
|
end
|
|
@@ -227,7 +415,7 @@ test "render component for tablet" do
|
|
|
227
415
|
with_variant :tablet do
|
|
228
416
|
assert_equal(
|
|
229
417
|
%(<span title="my title">Hello, tablets!</span>),
|
|
230
|
-
render_inline(TestComponent
|
|
418
|
+
render_inline(TestComponent.new(title: "my title")) { "Hello, tablets!" }.css("span").to_html
|
|
231
419
|
)
|
|
232
420
|
end
|
|
233
421
|
end
|
|
@@ -244,11 +432,11 @@ You can define as many examples as you want:
|
|
|
244
432
|
|
|
245
433
|
class TestComponentPreview < ActionView::Component::Preview
|
|
246
434
|
def with_default_title
|
|
247
|
-
render(TestComponent
|
|
435
|
+
render(TestComponent.new(title: "Test component default"))
|
|
248
436
|
end
|
|
249
437
|
|
|
250
438
|
def with_long_title
|
|
251
|
-
render(TestComponent
|
|
439
|
+
render(TestComponent.new(title: "This is a really long title to see how the component renders this"))
|
|
252
440
|
end
|
|
253
441
|
end
|
|
254
442
|
```
|
|
@@ -276,6 +464,16 @@ For example, if you want to use `lib/component_previews`, set the following in `
|
|
|
276
464
|
config.action_view_component.preview_path = "#{Rails.root}/lib/component_previews"
|
|
277
465
|
```
|
|
278
466
|
|
|
467
|
+
#### Configuring TestController
|
|
468
|
+
|
|
469
|
+
By default components tests and previews expect your Rails project to contain an `ApplicationController` class from which Controller classes inherit.
|
|
470
|
+
This can be configured using the `test_controller` option.
|
|
471
|
+
For example, if your controllers inherit from `BaseController`, set the following in `config/application.rb`:
|
|
472
|
+
|
|
473
|
+
```ruby
|
|
474
|
+
config.action_view_component.test_controller = "BaseController"
|
|
475
|
+
```
|
|
476
|
+
|
|
279
477
|
### Setting up RSpec
|
|
280
478
|
|
|
281
479
|
If you're using RSpec, you can configure component specs to have access to test helpers. Add the following to
|
|
@@ -300,6 +498,11 @@ To use component previews, set the following in `config/application.rb`:
|
|
|
300
498
|
config.action_view_component.preview_path = "#{Rails.root}/spec/components/previews"
|
|
301
499
|
```
|
|
302
500
|
|
|
501
|
+
### Initializer requirement
|
|
502
|
+
|
|
503
|
+
In Ruby 2.6.x and below, ActionView::Component requires the presence of an `initialize` method in each component.
|
|
504
|
+
However, `initialize` is no longer required for projects using 2.7.x and above.
|
|
505
|
+
|
|
303
506
|
## Frequently Asked Questions
|
|
304
507
|
|
|
305
508
|
### Can I use other templating languages besides ERB?
|
|
@@ -331,6 +534,35 @@ Inline templates have been removed (for now) due to concerns raised by [@soutaro
|
|
|
331
534
|
|
|
332
535
|
Bug reports and pull requests are welcome on GitHub at https://github.com/github/actionview-component. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct. We recommend reading the [contributing guide](./CONTRIBUTING.md) as well.
|
|
333
536
|
|
|
537
|
+
## Contributors
|
|
538
|
+
|
|
539
|
+
`actionview-component` is built by:
|
|
540
|
+
|
|
541
|
+
|<img src="https://avatars.githubusercontent.com/joelhawksley?s=256" alt="joelhawksley" width="128" />|<img src="https://avatars.githubusercontent.com/tenderlove?s=256" alt="tenderlove" width="128" />|<img src="https://avatars.githubusercontent.com/jonspalmer?s=256" alt="jonspalmer" width="128" />|<img src="https://avatars.githubusercontent.com/juanmanuelramallo?s=256" alt="juanmanuelramallo" width="128" />|<img src="https://avatars.githubusercontent.com/vinistock?s=256" alt="vinistock" width="128" />|
|
|
542
|
+
|:---:|:---:|:---:|:---:|:---:|
|
|
543
|
+
|@joelhawksley|@tenderlove|@jonspalmer|@juanmanuelramallo|@vinistock|
|
|
544
|
+
|Denver|Seattle|Boston||Toronto|
|
|
545
|
+
|
|
546
|
+
|<img src="https://avatars.githubusercontent.com/metade?s=256" alt="metade" width="128" />|<img src="https://avatars.githubusercontent.com/asgerb?s=256" alt="asgerb" width="128" />|<img src="https://avatars.githubusercontent.com/xronos-i-am?s=256" alt="xronos-i-am" width="128" />|<img src="https://avatars.githubusercontent.com/dylnclrk?s=256" alt="dylnclrk" width="128" />|<img src="https://avatars.githubusercontent.com/kaspermeyer?s=256" alt="kaspermeyer" width="128" />|
|
|
547
|
+
|:---:|:---:|:---:|:---:|:---:|
|
|
548
|
+
|@metade|@asgerb|@xronos-i-am|@dylnclrk|@kaspermeyer|
|
|
549
|
+
|London|Copenhagen|Russia, Kirov|Berkeley, CA|Denmark|
|
|
550
|
+
|
|
551
|
+
|<img src="https://avatars.githubusercontent.com/rdavid1099?s=256" alt="rdavid1099" width="128" />|<img src="https://avatars.githubusercontent.com/kylefox?s=256" alt="kylefox" width="128" />|<img src="https://avatars.githubusercontent.com/traels?s=256" alt="traels" width="128" />|<img src="https://avatars.githubusercontent.com/rainerborene?s=256" alt="rainerborene" width="128" />|<img src="https://avatars.githubusercontent.com/jcoyne?s=256" alt="jcoyne" width="128" />|
|
|
552
|
+
|:---:|:---:|:---:|:---:|:---:|
|
|
553
|
+
|@rdavid1099|@kylefox|@traels|@rainerborene|@jcoyne|
|
|
554
|
+
|Los Angeles|Edmonton|Odense, Denmark|Brazil|Minneapolis|
|
|
555
|
+
|
|
556
|
+
|<img src="https://avatars.githubusercontent.com/elia?s=256" alt="elia" width="128" />|<img src="https://avatars.githubusercontent.com/cesariouy?s=256" alt="cesariouy" width="128" />|<img src="https://avatars.githubusercontent.com/spdawson?s=256" alt="spdawson" width="128" />|<img src="https://avatars.githubusercontent.com/rmacklin?s=256" alt="rmacklin" width="128" />|<img src="https://avatars.githubusercontent.com/michaelem?s=256" alt="michaelem" width="128" />|
|
|
557
|
+
|:---:|:---:|:---:|:---:|:---:|
|
|
558
|
+
|@elia|@cesariouy|@spdawson|@rmacklin|@michaelem|
|
|
559
|
+
|Milan||United Kingdom||Berlin|
|
|
560
|
+
|
|
561
|
+
|<img src="https://avatars.githubusercontent.com/mellowfish?s=256" alt="mellowfish" width="128" />|<img src="https://avatars.githubusercontent.com/horacio?s=256" alt="horacio" width="128" />|<img src="https://avatars.githubusercontent.com/dukex?s=256" alt="dukex" width="128" />|<img src="https://avatars.githubusercontent.com/dark-panda?s=256" alt="dark-panda" width="128" />|<img src="https://avatars.githubusercontent.com/smashwilson?s=256" alt="smashwilson" width="128" />|
|
|
562
|
+
|:---:|:---:|:---:|:---:|:---:|
|
|
563
|
+
|@mellowfish|@horacio|@dukex|@dark-panda|@smashwilson|
|
|
564
|
+
|Spring Hill, TN|Buenos Aires|São Paulo||Gambrills, MD|
|
|
565
|
+
|
|
334
566
|
## License
|
|
335
567
|
|
|
336
568
|
The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
|
|
@@ -11,6 +11,9 @@ module ActionView
|
|
|
11
11
|
|
|
12
12
|
delegate :form_authenticity_token, :protect_against_forgery?, to: :helpers
|
|
13
13
|
|
|
14
|
+
class_attribute :content_areas, default: []
|
|
15
|
+
self.content_areas = [] # default doesn't work until Rails 5.2
|
|
16
|
+
|
|
14
17
|
# Entrypoint for rendering components. Called by ActionView::Base#render.
|
|
15
18
|
#
|
|
16
19
|
# view_context: ActionView context from calling view
|
|
@@ -37,24 +40,32 @@ module ActionView
|
|
|
37
40
|
# <span title="greeting">Hello, world!</span>
|
|
38
41
|
#
|
|
39
42
|
def render_in(view_context, *args, &block)
|
|
40
|
-
self.class.compile
|
|
43
|
+
self.class.compile!
|
|
41
44
|
@view_context = view_context
|
|
42
45
|
@view_renderer ||= view_context.view_renderer
|
|
43
46
|
@lookup_context ||= view_context.lookup_context
|
|
44
47
|
@view_flow ||= view_context.view_flow
|
|
45
48
|
@virtual_path ||= virtual_path
|
|
46
49
|
@variant = @lookup_context.variants.first
|
|
50
|
+
|
|
47
51
|
old_current_template = @current_template
|
|
48
52
|
@current_template = self
|
|
49
53
|
|
|
50
|
-
@content = view_context.capture(&block) if block_given?
|
|
54
|
+
@content = view_context.capture(self, &block) if block_given?
|
|
55
|
+
|
|
51
56
|
validate!
|
|
52
57
|
|
|
58
|
+
return "" unless render?
|
|
59
|
+
|
|
53
60
|
send(self.class.call_method_name(@variant))
|
|
54
61
|
ensure
|
|
55
62
|
@current_template = old_current_template
|
|
56
63
|
end
|
|
57
64
|
|
|
65
|
+
def render?
|
|
66
|
+
true
|
|
67
|
+
end
|
|
68
|
+
|
|
58
69
|
def initialize(*); end
|
|
59
70
|
|
|
60
71
|
def render(options = {}, args = {}, &block)
|
|
@@ -87,6 +98,19 @@ module ActionView
|
|
|
87
98
|
@variant
|
|
88
99
|
end
|
|
89
100
|
|
|
101
|
+
def with(area, content = nil, &block)
|
|
102
|
+
unless content_areas.include?(area)
|
|
103
|
+
raise ArgumentError.new "Unknown content_area '#{area}' - expected one of '#{content_areas}'"
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
if block_given?
|
|
107
|
+
content = view_context.capture(&block)
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
instance_variable_set("@#{area}".to_sym, content)
|
|
111
|
+
nil
|
|
112
|
+
end
|
|
113
|
+
|
|
90
114
|
private
|
|
91
115
|
|
|
92
116
|
def request
|
|
@@ -95,6 +119,12 @@ module ActionView
|
|
|
95
119
|
|
|
96
120
|
attr_reader :content, :view_context
|
|
97
121
|
|
|
122
|
+
# The controller used for testing components.
|
|
123
|
+
# Defaults to ApplicationController. This should be set early
|
|
124
|
+
# in the initialization process and should be set to a string.
|
|
125
|
+
mattr_accessor :test_controller
|
|
126
|
+
@@test_controller = "ApplicationController"
|
|
127
|
+
|
|
98
128
|
class << self
|
|
99
129
|
def inherited(child)
|
|
100
130
|
child.include Rails.application.routes.url_helpers unless child < Rails.application.routes.url_helpers
|
|
@@ -110,34 +140,36 @@ module ActionView
|
|
|
110
140
|
end
|
|
111
141
|
end
|
|
112
142
|
|
|
113
|
-
def has_initializer?
|
|
114
|
-
self.instance_method(:initialize).owner == self
|
|
115
|
-
end
|
|
116
|
-
|
|
117
143
|
def source_location
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
instance_method(:initialize).source_location[0]
|
|
144
|
+
@source_location ||=
|
|
145
|
+
if const_source_location_supported?
|
|
146
|
+
const_source_location(self.name)[0]
|
|
147
|
+
else
|
|
148
|
+
# Require `#initialize` to be defined so that we can use `method#source_location`
|
|
149
|
+
# to look up the filename of the component.
|
|
150
|
+
initialize_method = instance_method(:initialize)
|
|
151
|
+
initialize_method.source_location[0] if initialize_method.owner == self
|
|
152
|
+
end
|
|
128
153
|
end
|
|
129
154
|
|
|
130
155
|
def compiled?
|
|
131
156
|
@compiled && ActionView::Base.cache_template_loading
|
|
132
157
|
end
|
|
133
158
|
|
|
159
|
+
def compile!
|
|
160
|
+
compile(validate: true)
|
|
161
|
+
end
|
|
162
|
+
|
|
134
163
|
# Compile templates to instance methods, assuming they haven't been compiled already.
|
|
135
164
|
# We could in theory do this on app boot, at least in production environments.
|
|
136
165
|
# Right now this just compiles the first time the component is rendered.
|
|
137
|
-
def compile
|
|
166
|
+
def compile(validate: false)
|
|
138
167
|
return if compiled?
|
|
139
168
|
|
|
140
|
-
|
|
169
|
+
if template_errors.present?
|
|
170
|
+
raise ActionView::Component::TemplateError.new(template_errors) if validate
|
|
171
|
+
return false
|
|
172
|
+
end
|
|
141
173
|
|
|
142
174
|
templates.each do |template|
|
|
143
175
|
class_eval <<-RUBY, __FILE__, __LINE__ + 1
|
|
@@ -164,10 +196,23 @@ module ActionView
|
|
|
164
196
|
source_location
|
|
165
197
|
end
|
|
166
198
|
|
|
199
|
+
def with_content_areas(*areas)
|
|
200
|
+
if areas.include?(:content)
|
|
201
|
+
raise ArgumentError.new ":content is a reserved content area name. Please use another name, such as ':body'"
|
|
202
|
+
end
|
|
203
|
+
attr_reader *areas
|
|
204
|
+
self.content_areas = areas
|
|
205
|
+
end
|
|
206
|
+
|
|
167
207
|
private
|
|
168
208
|
|
|
209
|
+
def const_source_location_supported?
|
|
210
|
+
respond_to? :const_source_location # introduced in Ruby 2.7
|
|
211
|
+
end
|
|
212
|
+
|
|
169
213
|
def matching_views_in_source_location
|
|
170
|
-
|
|
214
|
+
return [] unless source_location
|
|
215
|
+
(Dir["#{source_location.chomp(File.extname(source_location))}.*{#{ActionView::Template.template_handler_extensions.join(',')}}"] - [source_location])
|
|
171
216
|
end
|
|
172
217
|
|
|
173
218
|
def templates
|
|
@@ -177,26 +222,39 @@ module ActionView
|
|
|
177
222
|
|
|
178
223
|
memo << {
|
|
179
224
|
path: path,
|
|
180
|
-
variant: pieces.second.split("+")
|
|
225
|
+
variant: pieces.second.split("+").second&.to_sym,
|
|
181
226
|
handler: pieces.last
|
|
182
227
|
}
|
|
183
228
|
end
|
|
184
229
|
end
|
|
185
230
|
|
|
186
|
-
def
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
231
|
+
def template_errors
|
|
232
|
+
@template_errors ||=
|
|
233
|
+
begin
|
|
234
|
+
errors = []
|
|
235
|
+
if source_location.nil? && !const_source_location_supported?
|
|
236
|
+
# Require `#initialize` to be defined so that we can use `method#source_location`
|
|
237
|
+
# to look up the filename of the component.
|
|
238
|
+
errors << "#{self} must implement #initialize."
|
|
239
|
+
end
|
|
190
240
|
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
241
|
+
errors << "Could not find a template file for #{self}." if templates.empty?
|
|
242
|
+
|
|
243
|
+
if templates.count { |template| template[:variant].nil? } > 1
|
|
244
|
+
errors << "More than one template found for #{self}. There can only be one default template file per component."
|
|
245
|
+
end
|
|
194
246
|
|
|
195
|
-
|
|
196
|
-
|
|
247
|
+
invalid_variants = templates
|
|
248
|
+
.group_by { |template| template[:variant] }
|
|
249
|
+
.map { |variant, grouped| variant if grouped.length > 1 }
|
|
250
|
+
.compact
|
|
251
|
+
.sort
|
|
197
252
|
|
|
198
|
-
|
|
199
|
-
|
|
253
|
+
unless invalid_variants.empty?
|
|
254
|
+
errors << "More than one template found for #{'variant'.pluralize(invalid_variants.count)} #{invalid_variants.map { |v| "'#{v}'" }.to_sentence} in #{self}. There can only be one template file per variant."
|
|
255
|
+
end
|
|
256
|
+
errors
|
|
257
|
+
end
|
|
200
258
|
end
|
|
201
259
|
|
|
202
260
|
def compiled_template(file_path)
|
|
@@ -6,10 +6,9 @@ module ActionView
|
|
|
6
6
|
module Component # :nodoc:
|
|
7
7
|
class Preview
|
|
8
8
|
extend ActiveSupport::DescendantsTracker
|
|
9
|
-
include ActionView::Component::TestHelpers
|
|
10
9
|
|
|
11
|
-
def render(component,
|
|
12
|
-
|
|
10
|
+
def render(component, **args, &block)
|
|
11
|
+
{ component: component, args: args, block: block }
|
|
13
12
|
end
|
|
14
13
|
|
|
15
14
|
class << self
|
|
@@ -19,21 +18,14 @@ module ActionView
|
|
|
19
18
|
descendants
|
|
20
19
|
end
|
|
21
20
|
|
|
22
|
-
# Returns the
|
|
23
|
-
def
|
|
24
|
-
|
|
25
|
-
if layout.nil?
|
|
26
|
-
layout = @layout.nil? ? "layouts/application" : @layout
|
|
27
|
-
end
|
|
28
|
-
|
|
29
|
-
Rails::ComponentExamplesController.render(template: "examples/show",
|
|
30
|
-
layout: layout,
|
|
31
|
-
assigns: { example: example_html })
|
|
21
|
+
# Returns the arguments for rendering of the component in its layout
|
|
22
|
+
def render_args(example)
|
|
23
|
+
new.public_send(example).merge(layout: @layout)
|
|
32
24
|
end
|
|
33
25
|
|
|
34
26
|
# Returns the component object class associated to the preview.
|
|
35
27
|
def component
|
|
36
|
-
|
|
28
|
+
name.chomp("Preview").constantize
|
|
37
29
|
end
|
|
38
30
|
|
|
39
31
|
# Returns all of the available examples for the component preview.
|
|
@@ -58,7 +50,7 @@ module ActionView
|
|
|
58
50
|
|
|
59
51
|
# Returns the underscored name of the component preview without the suffix.
|
|
60
52
|
def preview_name
|
|
61
|
-
name.
|
|
53
|
+
name.chomp("Preview").underscore
|
|
62
54
|
end
|
|
63
55
|
|
|
64
56
|
# Setter for layout name.
|
|
@@ -24,7 +24,6 @@ module ActionView
|
|
|
24
24
|
|
|
25
25
|
initializer "action_view_component.set_autoload_paths" do |app|
|
|
26
26
|
require "railties/lib/rails/components_controller"
|
|
27
|
-
require "railties/lib/rails/component_examples_controller"
|
|
28
27
|
|
|
29
28
|
options = app.config.action_view_component
|
|
30
29
|
|
|
@@ -35,9 +34,7 @@ module ActionView
|
|
|
35
34
|
|
|
36
35
|
initializer "action_view_component.eager_load_actions" do
|
|
37
36
|
ActiveSupport.on_load(:after_initialize) do
|
|
38
|
-
ActionView::Component::Base.descendants.each
|
|
39
|
-
descendant.compile if descendant.has_initializer? && config.eager_load
|
|
40
|
-
end
|
|
37
|
+
ActionView::Component::Base.descendants.each(&:compile)
|
|
41
38
|
end
|
|
42
39
|
end
|
|
43
40
|
|
|
@@ -1,24 +1,29 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
# Monkey patch ActionView::Base#render to support ActionView::Component
|
|
4
|
-
#
|
|
5
|
-
# A version of this monkey patch was upstreamed in https://github.com/rails/rails/pull/36388
|
|
6
|
-
# We'll need to upstream an updated version of this eventually.
|
|
7
4
|
module ActionView
|
|
8
5
|
module Component
|
|
9
6
|
module RenderMonkeyPatch # :nodoc:
|
|
10
7
|
def render(options = {}, args = {}, &block)
|
|
11
8
|
if options.respond_to?(:render_in)
|
|
9
|
+
options.render_in(self, &block)
|
|
10
|
+
elsif options.is_a?(Class) && options < ActionView::Component::Base
|
|
12
11
|
ActiveSupport::Deprecation.warn(
|
|
13
|
-
"
|
|
12
|
+
"`render MyComponent, foo: :bar` has been deprecated and will be removed in v2.0.0. Use `render MyComponent.new(foo: :bar)` instead."
|
|
14
13
|
)
|
|
15
14
|
|
|
16
|
-
options.render_in(self, &block)
|
|
17
|
-
elsif options.is_a?(Class) && options < ActionView::Component::Base
|
|
18
15
|
options.new(args).render_in(self, &block)
|
|
19
16
|
elsif options.is_a?(Hash) && options.has_key?(:component)
|
|
17
|
+
ActiveSupport::Deprecation.warn(
|
|
18
|
+
"`render component: MyComponent, locals: { foo: :bar }` has been deprecated and will be removed in v2.0.0. Use `render MyComponent.new(foo: :bar)` instead."
|
|
19
|
+
)
|
|
20
|
+
|
|
20
21
|
options[:component].new(options[:locals]).render_in(self, &block)
|
|
21
22
|
elsif options.respond_to?(:to_component_class) && !options.to_component_class.nil?
|
|
23
|
+
ActiveSupport::Deprecation.warn(
|
|
24
|
+
"rendering objects that respond_to `to_component_class` has been deprecated and will be removed in v2.0.0. Use `render MyComponent.new(foo: :bar)` instead."
|
|
25
|
+
)
|
|
26
|
+
|
|
22
27
|
options.to_component_class.new(options).render_in(self, &block)
|
|
23
28
|
else
|
|
24
29
|
super
|
|
@@ -8,7 +8,7 @@ module ActionView
|
|
|
8
8
|
end
|
|
9
9
|
|
|
10
10
|
def controller
|
|
11
|
-
@controller ||=
|
|
11
|
+
@controller ||= Base.test_controller.constantize.new.tap { |c| c.request = request }.extend(Rails.application.routes.url_helpers)
|
|
12
12
|
end
|
|
13
13
|
|
|
14
14
|
def request
|
|
@@ -10,11 +10,11 @@ module Rails
|
|
|
10
10
|
check_class_collision suffix: "Component"
|
|
11
11
|
|
|
12
12
|
def create_component_file
|
|
13
|
-
template "component.rb", File.join("app/components",
|
|
13
|
+
template "component.rb", File.join("app/components", class_path, "#{file_name}_component.rb")
|
|
14
14
|
end
|
|
15
15
|
|
|
16
16
|
def create_template_file
|
|
17
|
-
template "component.html.erb", File.join("app/components",
|
|
17
|
+
template "component.html.erb", File.join("app/components", class_path, "#{file_name}_component.html.erb")
|
|
18
18
|
end
|
|
19
19
|
|
|
20
20
|
private
|
|
@@ -6,7 +6,7 @@ module Rspec
|
|
|
6
6
|
source_root File.expand_path("templates", __dir__)
|
|
7
7
|
|
|
8
8
|
def create_test_file
|
|
9
|
-
template "component_spec.rb", File.join("spec/components", "#{file_name}_component_spec.rb")
|
|
9
|
+
template "component_spec.rb", File.join("spec/components", class_path, "#{file_name}_component_spec.rb")
|
|
10
10
|
end
|
|
11
11
|
|
|
12
12
|
private
|
|
@@ -7,7 +7,7 @@ module TestUnit
|
|
|
7
7
|
check_class_collision suffix: "ComponentTest"
|
|
8
8
|
|
|
9
9
|
def create_test_file
|
|
10
|
-
template "component_test.rb", File.join("test/components", "#{file_name}_component_test.rb")
|
|
10
|
+
template "component_test.rb", File.join("test/components", class_path, "#{file_name}_component_test.rb")
|
|
11
11
|
end
|
|
12
12
|
|
|
13
13
|
private
|
data/lib/railties/lib/rails.rb
CHANGED
|
@@ -4,6 +4,7 @@ require "rails/application_controller"
|
|
|
4
4
|
|
|
5
5
|
class Rails::ComponentsController < Rails::ApplicationController # :nodoc:
|
|
6
6
|
prepend_view_path File.expand_path("templates/rails", __dir__)
|
|
7
|
+
prepend_view_path "#{Rails.root}/app/views/" if defined?(Rails.root)
|
|
7
8
|
|
|
8
9
|
around_action :set_locale, only: :previews
|
|
9
10
|
before_action :find_preview, only: :previews
|
|
@@ -25,7 +26,10 @@ class Rails::ComponentsController < Rails::ApplicationController # :nodoc:
|
|
|
25
26
|
render template: "components/previews"
|
|
26
27
|
else
|
|
27
28
|
@example_name = File.basename(params[:path])
|
|
28
|
-
|
|
29
|
+
@render_args = @preview.render_args(@example_name)
|
|
30
|
+
layout = @render_args[:layout]
|
|
31
|
+
opts = layout.nil? ? {} : { layout: layout }
|
|
32
|
+
render template: "components/preview", **opts
|
|
29
33
|
end
|
|
30
34
|
end
|
|
31
35
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
<%=
|
|
1
|
+
<%= render(@render_args[:component], **@render_args[:args], &@render_args[:block])%>
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: actionview-component
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.
|
|
4
|
+
version: 1.10.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- GitHub Open Source
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2020-
|
|
11
|
+
date: 2020-02-14 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: bundler
|
|
@@ -150,6 +150,7 @@ files:
|
|
|
150
150
|
- lib/action_view/component/previewable.rb
|
|
151
151
|
- lib/action_view/component/railtie.rb
|
|
152
152
|
- lib/action_view/component/render_monkey_patch.rb
|
|
153
|
+
- lib/action_view/component/template_error.rb
|
|
153
154
|
- lib/action_view/component/test_case.rb
|
|
154
155
|
- lib/action_view/component/test_helpers.rb
|
|
155
156
|
- lib/action_view/component/version.rb
|
|
@@ -162,12 +163,10 @@ files:
|
|
|
162
163
|
- lib/rails/generators/test_unit/component_generator.rb
|
|
163
164
|
- lib/rails/generators/test_unit/templates/component_test.rb.tt
|
|
164
165
|
- lib/railties/lib/rails.rb
|
|
165
|
-
- lib/railties/lib/rails/component_examples_controller.rb
|
|
166
166
|
- lib/railties/lib/rails/components_controller.rb
|
|
167
167
|
- lib/railties/lib/rails/templates/rails/components/index.html.erb
|
|
168
168
|
- lib/railties/lib/rails/templates/rails/components/preview.html.erb
|
|
169
169
|
- lib/railties/lib/rails/templates/rails/components/previews.html.erb
|
|
170
|
-
- lib/railties/lib/rails/templates/rails/examples/show.html.erb
|
|
171
170
|
- script/bootstrap
|
|
172
171
|
- script/console
|
|
173
172
|
- script/install
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require "rails/application_controller"
|
|
4
|
-
load "config/application.rb" unless Rails.root
|
|
5
|
-
|
|
6
|
-
class Rails::ComponentExamplesController < ActionController::Base # :nodoc:
|
|
7
|
-
prepend_view_path File.expand_path("templates/rails", __dir__)
|
|
8
|
-
append_view_path Rails.root.join("app/views")
|
|
9
|
-
end
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
<%= raw @example %>
|