actionview-component 1.5.2 → 1.7.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 +30 -0
- data/.github/PULL_REQUEST_TEMPLATE +19 -0
- data/.gitignore +1 -0
- data/CHANGELOG.md +90 -0
- data/Gemfile.lock +13 -2
- data/README.md +217 -9
- data/actionview-component.gemspec +1 -0
- data/lib/action_view/component.rb +20 -2
- data/lib/action_view/component/base.rb +82 -39
- data/lib/action_view/component/conversion.rb +11 -0
- data/lib/action_view/component/preview.rb +8 -27
- data/lib/action_view/component/previewable.rb +27 -0
- data/lib/action_view/component/railtie.rb +16 -13
- data/lib/action_view/component/render_monkey_patch.rb +29 -0
- data/lib/action_view/component/template_error.rb +11 -0
- data/lib/action_view/component/test_case.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/rspec/component_generator.rb +19 -0
- data/lib/rails/generators/rspec/templates/component_spec.rb.tt +13 -0
- data/lib/rails/generators/test_unit/templates/component_test.rb.tt +2 -4
- metadata +25 -3
- data/lib/action_view/component/monkey_patch.rb +0 -27
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: '085434585e1e3fa1493bbc7bd90439b1645015acd66a713a33545c0eb4677dc4'
|
|
4
|
+
data.tar.gz: 34ec8d8f390471689fbd1085c94885b74c4f9a1b0b7d9b78650dae506520dd13
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 89e3c7d8b6c1d67a29f2ad67a032e424c42f57dd719d5b8cbde01b167385d9d2aeb5feb8fd77fcd9284e0a33da828b935edeebbb758c7cd68951178eea2d3b14
|
|
7
|
+
data.tar.gz: bc76f28233c72f7d5ff3a818429e8c763649db3ec46e406b554070cd456b73ae923905ecb94d3b37949ca5c6b0960890594a341e72a9755343462cf4c5c24cff
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
<!-- **** Filing a Feature Request? Include these sections. **** -->
|
|
2
|
+
|
|
3
|
+
### Feature request
|
|
4
|
+
<!-- Provide a summary of the behavior. -->
|
|
5
|
+
|
|
6
|
+
### Motivation
|
|
7
|
+
|
|
8
|
+
<!-- What would you like to do with this feature? Can you provide
|
|
9
|
+
context or references to similar behavior in other libraries. -->
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
<!-- **** Filing a Bug Report? Include these sections. **** -->
|
|
16
|
+
|
|
17
|
+
### Steps to reproduce
|
|
18
|
+
<!-- Provide an series of steps or, better yet, a link to a repo to
|
|
19
|
+
demonstrate the bug you've identified. -->
|
|
20
|
+
|
|
21
|
+
### Expected behavior
|
|
22
|
+
<!-- Tell us what should happen -->
|
|
23
|
+
|
|
24
|
+
### Actual behavior
|
|
25
|
+
<!-- Tell us what happens instead -->
|
|
26
|
+
|
|
27
|
+
### System configuration
|
|
28
|
+
**Rails version**:
|
|
29
|
+
|
|
30
|
+
**Ruby version**:
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
<!-- https://github.com/github/actionview-component/blob/master/CONTRIBUTING.md#submitting-a-pull-request -->
|
|
2
|
+
|
|
3
|
+
### Summary
|
|
4
|
+
|
|
5
|
+
<!-- Provide a general description of the code changes in your pull
|
|
6
|
+
request... were there any bugs you had fixed? If so, mention them. If
|
|
7
|
+
these bugs have open GitHub issues, be sure to tag them here as well,
|
|
8
|
+
to keep the conversation linked together. -->
|
|
9
|
+
|
|
10
|
+
### Other Information
|
|
11
|
+
|
|
12
|
+
<!-- If there's anything else that's important and relevant to your pull
|
|
13
|
+
request, mention that information here. This could include
|
|
14
|
+
benchmarks, or other information.
|
|
15
|
+
|
|
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! -->
|
data/.gitignore
CHANGED
data/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,93 @@
|
|
|
1
|
+
# v1.7.0
|
|
2
|
+
|
|
3
|
+
* Simplify validation of templates and compilation.
|
|
4
|
+
|
|
5
|
+
*Jon Palmer*
|
|
6
|
+
|
|
7
|
+
* Add support for multiple content areas.
|
|
8
|
+
|
|
9
|
+
*Jon Palmer*
|
|
10
|
+
|
|
11
|
+
# v1.6.2
|
|
12
|
+
|
|
13
|
+
* Fix Uninitialized Constant error.
|
|
14
|
+
|
|
15
|
+
*Jon Palmer*
|
|
16
|
+
|
|
17
|
+
* Add basic github issue and PR templates.
|
|
18
|
+
|
|
19
|
+
*Dylan Clark*
|
|
20
|
+
|
|
21
|
+
* Update readme phrasing around previews.
|
|
22
|
+
|
|
23
|
+
*Justin Coyne*
|
|
24
|
+
|
|
25
|
+
# v1.6.1
|
|
26
|
+
|
|
27
|
+
* Allow Previews to have no layout.
|
|
28
|
+
|
|
29
|
+
*Jon Palmer*
|
|
30
|
+
|
|
31
|
+
* Bump rack from 2.0.7 to 2.0.8.
|
|
32
|
+
|
|
33
|
+
*Dependabot*
|
|
34
|
+
|
|
35
|
+
* Compile components on application boot when eager loading is enabled.
|
|
36
|
+
|
|
37
|
+
*Joel Hawksley*
|
|
38
|
+
|
|
39
|
+
* Previews support content blocks.
|
|
40
|
+
|
|
41
|
+
*Cesario Uy*
|
|
42
|
+
|
|
43
|
+
* Follow Rails conventions. (refactor)
|
|
44
|
+
|
|
45
|
+
*Rainer Borene*
|
|
46
|
+
|
|
47
|
+
* Fix edge case issue with extracting variants from less conventional source_locations.
|
|
48
|
+
|
|
49
|
+
*Ryan Workman*
|
|
50
|
+
|
|
51
|
+
# v1.6.0
|
|
52
|
+
|
|
53
|
+
* Avoid dropping elements in the render_inline test helper.
|
|
54
|
+
|
|
55
|
+
*@dark-panda*
|
|
56
|
+
|
|
57
|
+
* Add test for helpers.asset_url.
|
|
58
|
+
|
|
59
|
+
*Christopher Coleman*
|
|
60
|
+
|
|
61
|
+
* Add rudimentary compatibility with better_html.
|
|
62
|
+
|
|
63
|
+
*Joel Hawksley*
|
|
64
|
+
|
|
65
|
+
* Template-less variants fall back to default template.
|
|
66
|
+
|
|
67
|
+
*Asger Behncke Jacobsen*, *Cesario Uy*
|
|
68
|
+
|
|
69
|
+
* Generated tests use new naming convention.
|
|
70
|
+
|
|
71
|
+
*Simon Træls Ravn*
|
|
72
|
+
|
|
73
|
+
* Eliminate sqlite dependency.
|
|
74
|
+
|
|
75
|
+
*Simon Dawson*
|
|
76
|
+
|
|
77
|
+
* Add support for rendering components via #to_component_class
|
|
78
|
+
|
|
79
|
+
*Vinicius Stock*
|
|
80
|
+
|
|
81
|
+
# v1.5.3
|
|
82
|
+
|
|
83
|
+
* Add support for RSpec to generators.
|
|
84
|
+
|
|
85
|
+
*Dylan Clark, Ryan Workman*
|
|
86
|
+
|
|
87
|
+
* Require controllers as part of setting autoload paths.
|
|
88
|
+
|
|
89
|
+
*Joel Hawksley*
|
|
90
|
+
|
|
1
91
|
# v1.5.2
|
|
2
92
|
|
|
3
93
|
* Disable eager loading initializer.
|
data/Gemfile.lock
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
PATH
|
|
2
2
|
remote: .
|
|
3
3
|
specs:
|
|
4
|
-
actionview-component (1.
|
|
4
|
+
actionview-component (1.7.0)
|
|
5
5
|
|
|
6
6
|
GEM
|
|
7
7
|
remote: https://rubygems.org/
|
|
@@ -62,6 +62,14 @@ GEM
|
|
|
62
62
|
tzinfo (~> 1.1)
|
|
63
63
|
zeitwerk (~> 2.1, >= 2.1.8)
|
|
64
64
|
ast (2.4.0)
|
|
65
|
+
better_html (1.0.14)
|
|
66
|
+
actionview (>= 4.0)
|
|
67
|
+
activesupport (>= 4.0)
|
|
68
|
+
ast (~> 2.0)
|
|
69
|
+
erubi (~> 1.4)
|
|
70
|
+
html_tokenizer (~> 0.0.6)
|
|
71
|
+
parser (>= 2.4)
|
|
72
|
+
smart_properties
|
|
65
73
|
builder (3.2.3)
|
|
66
74
|
concurrent-ruby (1.1.5)
|
|
67
75
|
crass (1.0.5)
|
|
@@ -71,6 +79,7 @@ GEM
|
|
|
71
79
|
haml (5.1.2)
|
|
72
80
|
temple (>= 0.8.0)
|
|
73
81
|
tilt
|
|
82
|
+
html_tokenizer (0.0.7)
|
|
74
83
|
i18n (1.6.0)
|
|
75
84
|
concurrent-ruby (~> 1.0)
|
|
76
85
|
jaro_winkler (1.5.3)
|
|
@@ -92,7 +101,7 @@ GEM
|
|
|
92
101
|
parallel (1.17.0)
|
|
93
102
|
parser (2.6.3.0)
|
|
94
103
|
ast (~> 2.4.0)
|
|
95
|
-
rack (2.0.
|
|
104
|
+
rack (2.0.8)
|
|
96
105
|
rack-test (1.1.0)
|
|
97
106
|
rack (>= 1.0, < 3)
|
|
98
107
|
rails (6.0.0)
|
|
@@ -139,6 +148,7 @@ GEM
|
|
|
139
148
|
slim (4.0.1)
|
|
140
149
|
temple (>= 0.7.6, < 0.9)
|
|
141
150
|
tilt (>= 2.0.6, < 2.1)
|
|
151
|
+
smart_properties (1.15.0)
|
|
142
152
|
sprockets (3.7.2)
|
|
143
153
|
concurrent-ruby (~> 1.0)
|
|
144
154
|
rack (> 1, < 3)
|
|
@@ -163,6 +173,7 @@ PLATFORMS
|
|
|
163
173
|
|
|
164
174
|
DEPENDENCIES
|
|
165
175
|
actionview-component!
|
|
176
|
+
better_html (~> 1)
|
|
166
177
|
bundler (>= 1.14)
|
|
167
178
|
haml (~> 5)
|
|
168
179
|
minitest (= 5.1.0)
|
data/README.md
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
|
|
8
8
|
This gem is meant to serve as a precursor to upstreaming the `ActionView::Component` class into Rails. It also serves to enable the usage of `ActionView::Component` in older versions of Rails.
|
|
9
9
|
|
|
10
|
-
Preliminary support for rendering components was merged into Rails `6.1.0.alpha` in https://github.com/rails/rails/pull/36388. Assuming `ActionView::Component` makes it into Rails
|
|
10
|
+
Preliminary support for rendering components was merged into Rails `6.1.0.alpha` in https://github.com/rails/rails/pull/36388. Assuming `ActionView::Component` makes it into Rails, this gem will then exist to serve as a backport.
|
|
11
11
|
|
|
12
12
|
## Design philosophy
|
|
13
13
|
|
|
@@ -32,7 +32,7 @@ $ bundle
|
|
|
32
32
|
In `config/application.rb`, add:
|
|
33
33
|
|
|
34
34
|
```bash
|
|
35
|
-
require "action_view/component"
|
|
35
|
+
require "action_view/component/railtie"
|
|
36
36
|
```
|
|
37
37
|
|
|
38
38
|
## Guide
|
|
@@ -163,6 +163,24 @@ Components can be rendered via:
|
|
|
163
163
|
|
|
164
164
|
`render(component: TestComponent, locals: { foo: :bar })`
|
|
165
165
|
|
|
166
|
+
**Rendering components through models**
|
|
167
|
+
|
|
168
|
+
Passing model instances will cause `render` to look for its respective component class.
|
|
169
|
+
|
|
170
|
+
The component is instantiated with the rendered model instance.
|
|
171
|
+
|
|
172
|
+
Example for a `Post` model:
|
|
173
|
+
|
|
174
|
+
`render(@post)`
|
|
175
|
+
|
|
176
|
+
```ruby
|
|
177
|
+
class PostComponent < ActionView::Component::Base
|
|
178
|
+
def initialize(post)
|
|
179
|
+
@post = post
|
|
180
|
+
end
|
|
181
|
+
end
|
|
182
|
+
```
|
|
183
|
+
|
|
166
184
|
The following syntax has been deprecated and will be removed in v2.0.0:
|
|
167
185
|
|
|
168
186
|
`render(TestComponent.new(foo: :bar))`
|
|
@@ -181,17 +199,183 @@ An error will be raised:
|
|
|
181
199
|
|
|
182
200
|
`ActiveModel::ValidationError: Validation failed: Title can't be blank`
|
|
183
201
|
|
|
202
|
+
#### Content Areas
|
|
203
|
+
|
|
204
|
+
|
|
205
|
+
A component can declare additional content areas to be rendered in the component. For example:
|
|
206
|
+
|
|
207
|
+
`app/components/modal_component.rb`:
|
|
208
|
+
```ruby
|
|
209
|
+
class ModalComponent < ActionView::Component::Base
|
|
210
|
+
validates :user, :header, :body, presence: true
|
|
211
|
+
|
|
212
|
+
with_content_areas :header, :body
|
|
213
|
+
|
|
214
|
+
def initialize(user:)
|
|
215
|
+
@user = user
|
|
216
|
+
end
|
|
217
|
+
end
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
`app/components/modal_component.html.erb`:
|
|
221
|
+
```erb
|
|
222
|
+
<div class="modal">
|
|
223
|
+
<div class="header"><%= header %></div>
|
|
224
|
+
<div class="body"><%= body %>"></div>
|
|
225
|
+
</div>
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
We can render it in a view as:
|
|
229
|
+
|
|
230
|
+
```erb
|
|
231
|
+
<%= render(ModalComponent, user: {name: 'Jane'}) do |component| %>
|
|
232
|
+
<% component.with(:header) do %>
|
|
233
|
+
Hello <%= user[:name] %>
|
|
234
|
+
<% end %>
|
|
235
|
+
<% component.with(:body) do %>
|
|
236
|
+
<p>Have a great day.</p>
|
|
237
|
+
<% end %>
|
|
238
|
+
<% end %>
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
Which returns:
|
|
242
|
+
|
|
243
|
+
```html
|
|
244
|
+
<div class="modal">
|
|
245
|
+
<div class="header">Hello Jane</div>
|
|
246
|
+
<div class="body"><p>Have a great day.</p></div>
|
|
247
|
+
</div>
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
Content for content areas can be passed as arguments to the render method or as named blocks passed to the `with` method.
|
|
251
|
+
This allows a few different combinations of ways to render the component:
|
|
252
|
+
|
|
253
|
+
##### Required render argument optionally overridden or wrapped by a named block
|
|
254
|
+
|
|
255
|
+
`app/components/modal_component.rb`:
|
|
256
|
+
```ruby
|
|
257
|
+
class ModalComponent < ActionView::Component::Base
|
|
258
|
+
validates :header, :body, presence: true
|
|
259
|
+
|
|
260
|
+
with_content_areas :header, :body
|
|
261
|
+
|
|
262
|
+
def initialize(header:)
|
|
263
|
+
@header = header
|
|
264
|
+
end
|
|
265
|
+
end
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
```erb
|
|
269
|
+
<%= render(ModalComponent, header: "Hi!") do |component| %>
|
|
270
|
+
<% help_enabled? && component.with(:header) do %>
|
|
271
|
+
<span class="help_icon"><%= component.header %></span>
|
|
272
|
+
<% end %>
|
|
273
|
+
<% component.with(:body) do %>
|
|
274
|
+
<p>Have a great day.</p>
|
|
275
|
+
<% end %>
|
|
276
|
+
<% end %>
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
##### Required argument passed by render argument or by named block
|
|
280
|
+
|
|
281
|
+
`app/components/modal_component.rb`:
|
|
282
|
+
```ruby
|
|
283
|
+
class ModalComponent < ActionView::Component::Base
|
|
284
|
+
validates :header, :body, presence: true
|
|
285
|
+
|
|
286
|
+
with_content_areas :header, :body
|
|
287
|
+
|
|
288
|
+
def initialize(header: nil)
|
|
289
|
+
@header = header
|
|
290
|
+
end
|
|
291
|
+
end
|
|
292
|
+
```
|
|
293
|
+
|
|
294
|
+
`app/views/render_arg.html.erb`:
|
|
295
|
+
```erb
|
|
296
|
+
<%= render(ModalComponent, header: "Hi!") do |component| %>
|
|
297
|
+
<% component.with(:body) do %>
|
|
298
|
+
<p>Have a great day.</p>
|
|
299
|
+
<% end %>
|
|
300
|
+
<% end %>
|
|
301
|
+
```
|
|
302
|
+
|
|
303
|
+
`app/views/with_block.html.erb`:
|
|
304
|
+
```erb
|
|
305
|
+
<%= render(ModalComponent) do |component| %>
|
|
306
|
+
<% component.with(:header) do %>
|
|
307
|
+
<span class="help_icon">Hello</span>
|
|
308
|
+
<% end %>
|
|
309
|
+
<% component.with(:body) do %>
|
|
310
|
+
<p>Have a great day.</p>
|
|
311
|
+
<% end %>
|
|
312
|
+
<% end %>
|
|
313
|
+
```
|
|
314
|
+
|
|
315
|
+
##### Optional argument passed by render argument, by named block, or neither
|
|
316
|
+
|
|
317
|
+
`app/components/modal_component.rb`:
|
|
318
|
+
```ruby
|
|
319
|
+
class ModalComponent < ActionView::Component::Base
|
|
320
|
+
validates :body, presence: true
|
|
321
|
+
|
|
322
|
+
with_content_areas :header, :body
|
|
323
|
+
|
|
324
|
+
def initialize(header: nil)
|
|
325
|
+
@header = header
|
|
326
|
+
end
|
|
327
|
+
end
|
|
328
|
+
```
|
|
329
|
+
|
|
330
|
+
`app/components/modal_component.html.erb`:
|
|
331
|
+
```erb
|
|
332
|
+
<div class="modal">
|
|
333
|
+
<% if header %>
|
|
334
|
+
<div class="header"><%= header %></div>
|
|
335
|
+
<% end %>
|
|
336
|
+
<div class="body"><%= body %>"></div>
|
|
337
|
+
</div>
|
|
338
|
+
```
|
|
339
|
+
|
|
340
|
+
`app/views/render_arg.html.erb`:
|
|
341
|
+
```erb
|
|
342
|
+
<%= render(ModalComponent, header: "Hi!") do |component| %>
|
|
343
|
+
<% component.with(:body) do %>
|
|
344
|
+
<p>Have a great day.</p>
|
|
345
|
+
<% end %>
|
|
346
|
+
<% end %>
|
|
347
|
+
```
|
|
348
|
+
|
|
349
|
+
`app/views/with_block.html.erb`:
|
|
350
|
+
```erb
|
|
351
|
+
<%= render(ModalComponent) do |component| %>
|
|
352
|
+
<% component.with(:header) do %>
|
|
353
|
+
<span class="help_icon">Hello</span>
|
|
354
|
+
<% end %>
|
|
355
|
+
<% component.with(:body) do %>
|
|
356
|
+
<p>Have a great day.</p>
|
|
357
|
+
<% end %>
|
|
358
|
+
<% end %>
|
|
359
|
+
```
|
|
360
|
+
|
|
361
|
+
`app/views/no_header.html.erb`:
|
|
362
|
+
```erb
|
|
363
|
+
<%= render(ModalComponent) do |component| %>
|
|
364
|
+
<% component.with(:body) do %>
|
|
365
|
+
<p>Have a great day.</p>
|
|
366
|
+
<% end %>
|
|
367
|
+
<% end %>
|
|
368
|
+
```
|
|
369
|
+
|
|
184
370
|
### Testing
|
|
185
371
|
|
|
186
372
|
Components are unit tested directly. The `render_inline` test helper wraps the result in `Nokogiri.HTML`, allowing us to test the component above as:
|
|
187
373
|
|
|
188
374
|
```ruby
|
|
189
|
-
require "action_view/component/
|
|
375
|
+
require "action_view/component/test_case"
|
|
190
376
|
|
|
191
|
-
class MyComponentTest <
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
def test_render_component
|
|
377
|
+
class MyComponentTest < ActionView::Component::TestCase
|
|
378
|
+
test "render component" do
|
|
195
379
|
assert_equal(
|
|
196
380
|
%(<span title="my title">Hello, World!</span>),
|
|
197
381
|
render_inline(TestComponent, title: "my title") { "Hello, World!" }.to_html
|
|
@@ -207,7 +391,7 @@ In general, we’ve found it makes the most sense to test components based on th
|
|
|
207
391
|
To test a specific variant you can wrap your test with the `with_variant` helper method as:
|
|
208
392
|
|
|
209
393
|
```ruby
|
|
210
|
-
|
|
394
|
+
test "render component for tablet" do
|
|
211
395
|
with_variant :tablet do
|
|
212
396
|
assert_equal(
|
|
213
397
|
%(<span title="my title">Hello, tablets!</span>),
|
|
@@ -218,7 +402,7 @@ end
|
|
|
218
402
|
```
|
|
219
403
|
|
|
220
404
|
### Previewing Components
|
|
221
|
-
`ActionView::Component::Preview`
|
|
405
|
+
`ActionView::Component::Preview` provides a way to see how components look by visiting a special URL that renders them.
|
|
222
406
|
In the previous example, the preview class for `TestComponent` would be called `TestComponentPreview` and located in `test/components/previews/test_component_preview.rb`.
|
|
223
407
|
To see the preview of the component with a given title, implement a method that renders the component.
|
|
224
408
|
You can define as many examples as you want:
|
|
@@ -260,6 +444,30 @@ For example, if you want to use `lib/component_previews`, set the following in `
|
|
|
260
444
|
config.action_view_component.preview_path = "#{Rails.root}/lib/component_previews"
|
|
261
445
|
```
|
|
262
446
|
|
|
447
|
+
### Setting up RSpec
|
|
448
|
+
|
|
449
|
+
If you're using RSpec, you can configure component specs to have access to test helpers. Add the following to
|
|
450
|
+
`spec/rails_helper.rb`:
|
|
451
|
+
|
|
452
|
+
```ruby
|
|
453
|
+
require "action_view/component/test_helpers"
|
|
454
|
+
|
|
455
|
+
RSpec.configure do |config|
|
|
456
|
+
# ...
|
|
457
|
+
|
|
458
|
+
# Ensure that the test helpers are available in component specs
|
|
459
|
+
config.include ActionView::Component::TestHelpers, type: :component
|
|
460
|
+
end
|
|
461
|
+
```
|
|
462
|
+
|
|
463
|
+
Specs created by the generator should now have access to test helpers like `render_inline`.
|
|
464
|
+
|
|
465
|
+
To use component previews, set the following in `config/application.rb`:
|
|
466
|
+
|
|
467
|
+
```ruby
|
|
468
|
+
config.action_view_component.preview_path = "#{Rails.root}/spec/components/previews"
|
|
469
|
+
```
|
|
470
|
+
|
|
263
471
|
## Frequently Asked Questions
|
|
264
472
|
|
|
265
473
|
### Can I use other templating languages besides ERB?
|
|
@@ -39,6 +39,7 @@ Gem::Specification.new do |spec|
|
|
|
39
39
|
spec.add_development_dependency "minitest", "= 5.1.0"
|
|
40
40
|
spec.add_development_dependency "haml", "~> 5"
|
|
41
41
|
spec.add_development_dependency "slim", "~> 4.0"
|
|
42
|
+
spec.add_development_dependency "better_html", "~> 1"
|
|
42
43
|
spec.add_development_dependency "rubocop", "= 0.74"
|
|
43
44
|
spec.add_development_dependency "rubocop-github", "~> 0.13.0"
|
|
44
45
|
end
|
|
@@ -1,5 +1,23 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require "
|
|
4
|
-
require "action_view
|
|
3
|
+
require "active_model"
|
|
4
|
+
require "action_view"
|
|
5
|
+
require "active_support/dependencies/autoload"
|
|
5
6
|
require "action_view/component/railtie"
|
|
7
|
+
|
|
8
|
+
module ActionView
|
|
9
|
+
module Component
|
|
10
|
+
extend ActiveSupport::Autoload
|
|
11
|
+
|
|
12
|
+
autoload :Base
|
|
13
|
+
autoload :Conversion
|
|
14
|
+
autoload :Preview
|
|
15
|
+
autoload :Previewable
|
|
16
|
+
autoload :TestHelpers
|
|
17
|
+
autoload :TestCase
|
|
18
|
+
autoload :RenderMonkeyPatch
|
|
19
|
+
autoload :TemplateError
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
ActiveModel::Conversion.include ActionView::Component::Conversion
|
|
@@ -1,20 +1,18 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require "active_model"
|
|
4
|
-
require "action_view"
|
|
5
3
|
require "active_support/configurable"
|
|
6
|
-
require_relative "preview"
|
|
7
4
|
|
|
8
5
|
module ActionView
|
|
9
6
|
module Component
|
|
10
7
|
class Base < ActionView::Base
|
|
11
8
|
include ActiveModel::Validations
|
|
12
9
|
include ActiveSupport::Configurable
|
|
13
|
-
include ActionView::Component::
|
|
10
|
+
include ActionView::Component::Previewable
|
|
14
11
|
|
|
15
12
|
delegate :form_authenticity_token, :protect_against_forgery?, to: :helpers
|
|
16
13
|
|
|
17
|
-
|
|
14
|
+
class_attribute :content_areas, default: []
|
|
15
|
+
self.content_areas = [] # default doesn't work until Rails 5.2
|
|
18
16
|
|
|
19
17
|
# Entrypoint for rendering components. Called by ActionView::Base#render.
|
|
20
18
|
#
|
|
@@ -42,7 +40,7 @@ module ActionView
|
|
|
42
40
|
# <span title="greeting">Hello, world!</span>
|
|
43
41
|
#
|
|
44
42
|
def render_in(view_context, *args, &block)
|
|
45
|
-
self.class.compile
|
|
43
|
+
self.class.compile!
|
|
46
44
|
@view_context = view_context
|
|
47
45
|
@view_renderer ||= view_context.view_renderer
|
|
48
46
|
@lookup_context ||= view_context.lookup_context
|
|
@@ -52,7 +50,8 @@ module ActionView
|
|
|
52
50
|
old_current_template = @current_template
|
|
53
51
|
@current_template = self
|
|
54
52
|
|
|
55
|
-
@content = view_context.capture(&block) if block_given?
|
|
53
|
+
@content = view_context.capture(self, &block) if block_given?
|
|
54
|
+
|
|
56
55
|
validate!
|
|
57
56
|
|
|
58
57
|
send(self.class.call_method_name(@variant))
|
|
@@ -92,14 +91,21 @@ module ActionView
|
|
|
92
91
|
@variant
|
|
93
92
|
end
|
|
94
93
|
|
|
95
|
-
|
|
94
|
+
def with(area, content = nil, &block)
|
|
95
|
+
unless content_areas.include?(area)
|
|
96
|
+
raise ArgumentError.new "Unknown content_area '#{area}' - expected one of '#{content_areas}'"
|
|
97
|
+
end
|
|
96
98
|
|
|
97
|
-
|
|
98
|
-
|
|
99
|
+
if block_given?
|
|
100
|
+
content = view_context.capture(&block)
|
|
101
|
+
end
|
|
99
102
|
|
|
100
|
-
|
|
103
|
+
instance_variable_set("@#{area}".to_sym, content)
|
|
104
|
+
nil
|
|
101
105
|
end
|
|
102
106
|
|
|
107
|
+
private
|
|
108
|
+
|
|
103
109
|
def request
|
|
104
110
|
@request ||= controller.request
|
|
105
111
|
end
|
|
@@ -114,7 +120,7 @@ module ActionView
|
|
|
114
120
|
end
|
|
115
121
|
|
|
116
122
|
def call_method_name(variant)
|
|
117
|
-
if variant.present?
|
|
123
|
+
if variant.present? && variants.include?(variant)
|
|
118
124
|
"call_#{variant}"
|
|
119
125
|
else
|
|
120
126
|
"call"
|
|
@@ -122,25 +128,39 @@ module ActionView
|
|
|
122
128
|
end
|
|
123
129
|
|
|
124
130
|
def source_location
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
131
|
+
@source_location ||=
|
|
132
|
+
begin
|
|
133
|
+
# Require #initialize to be defined so that we can use
|
|
134
|
+
# method#source_location to look up the file name
|
|
135
|
+
# of the component.
|
|
136
|
+
#
|
|
137
|
+
# If we were able to only support Ruby 2.7+,
|
|
138
|
+
# We could just use Module#const_source_location,
|
|
139
|
+
# rendering this unnecessary.
|
|
140
|
+
#
|
|
141
|
+
initialize_method = instance_method(:initialize)
|
|
142
|
+
initialize_method.source_location[0] if initialize_method.owner == self
|
|
143
|
+
end
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
def compiled?
|
|
147
|
+
@compiled && ActionView::Base.cache_template_loading
|
|
148
|
+
end
|
|
133
149
|
|
|
134
|
-
|
|
150
|
+
def compile!
|
|
151
|
+
compile(validate: true)
|
|
135
152
|
end
|
|
136
153
|
|
|
137
154
|
# Compile templates to instance methods, assuming they haven't been compiled already.
|
|
138
155
|
# We could in theory do this on app boot, at least in production environments.
|
|
139
156
|
# Right now this just compiles the first time the component is rendered.
|
|
140
|
-
def compile
|
|
141
|
-
return if
|
|
157
|
+
def compile(validate: false)
|
|
158
|
+
return if compiled?
|
|
142
159
|
|
|
143
|
-
|
|
160
|
+
if template_errors.present?
|
|
161
|
+
raise ActionView::Component::TemplateError.new(template_errors) if validate
|
|
162
|
+
return false
|
|
163
|
+
end
|
|
144
164
|
|
|
145
165
|
templates.each do |template|
|
|
146
166
|
class_eval <<-RUBY, __FILE__, __LINE__ + 1
|
|
@@ -164,36 +184,59 @@ module ActionView
|
|
|
164
184
|
end
|
|
165
185
|
|
|
166
186
|
def identifier
|
|
167
|
-
|
|
187
|
+
source_location
|
|
188
|
+
end
|
|
189
|
+
|
|
190
|
+
def with_content_areas(*areas)
|
|
191
|
+
if areas.include?(:content)
|
|
192
|
+
raise ArgumentError.new ":content is a reserved content area name. Please use another name, such as ':body'"
|
|
193
|
+
end
|
|
194
|
+
attr_reader *areas
|
|
195
|
+
self.content_areas = areas
|
|
168
196
|
end
|
|
169
197
|
|
|
170
198
|
private
|
|
171
199
|
|
|
200
|
+
def matching_views_in_source_location
|
|
201
|
+
return [] unless source_location
|
|
202
|
+
(Dir["#{source_location.sub(/#{File.extname(source_location)}$/, '')}.*{#{ActionView::Template.template_handler_extensions.join(',')}}"] - [source_location])
|
|
203
|
+
end
|
|
204
|
+
|
|
172
205
|
def templates
|
|
173
206
|
@templates ||=
|
|
174
|
-
|
|
207
|
+
matching_views_in_source_location.each_with_object([]) do |path, memo|
|
|
208
|
+
pieces = File.basename(path).split(".")
|
|
209
|
+
|
|
175
210
|
memo << {
|
|
176
211
|
path: path,
|
|
177
|
-
variant:
|
|
178
|
-
handler:
|
|
212
|
+
variant: pieces.second.split("+").second&.to_sym,
|
|
213
|
+
handler: pieces.last
|
|
179
214
|
}
|
|
180
215
|
end
|
|
181
216
|
end
|
|
182
217
|
|
|
183
|
-
def
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
218
|
+
def template_errors
|
|
219
|
+
@template_errors ||=
|
|
220
|
+
begin
|
|
221
|
+
errors = []
|
|
222
|
+
errors << "#{self} must implement #initialize." if source_location.nil?
|
|
223
|
+
errors << "Could not find a template file for #{self}." if templates.empty?
|
|
187
224
|
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
225
|
+
if templates.count { |template| template[:variant].nil? } > 1
|
|
226
|
+
errors << "More than one template found for #{self}. There can only be one default template file per component."
|
|
227
|
+
end
|
|
191
228
|
|
|
192
|
-
|
|
193
|
-
|
|
229
|
+
invalid_variants = templates
|
|
230
|
+
.group_by { |template| template[:variant] }
|
|
231
|
+
.map { |variant, grouped| variant if grouped.length > 1 }
|
|
232
|
+
.compact
|
|
233
|
+
.sort
|
|
194
234
|
|
|
195
|
-
|
|
196
|
-
|
|
235
|
+
unless invalid_variants.empty?
|
|
236
|
+
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."
|
|
237
|
+
end
|
|
238
|
+
errors
|
|
239
|
+
end
|
|
197
240
|
end
|
|
198
241
|
|
|
199
242
|
def compiled_template(file_path)
|
|
@@ -1,37 +1,15 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require "active_support/concern"
|
|
4
3
|
require "active_support/descendants_tracker"
|
|
5
|
-
require_relative "test_helpers"
|
|
6
4
|
|
|
7
5
|
module ActionView
|
|
8
|
-
module Component
|
|
9
|
-
module Previews
|
|
10
|
-
extend ActiveSupport::Concern
|
|
11
|
-
|
|
12
|
-
included do
|
|
13
|
-
# Set the location of component previews through app configuration:
|
|
14
|
-
#
|
|
15
|
-
# config.action_view_component.preview_path = "#{Rails.root}/lib/component_previews"
|
|
16
|
-
#
|
|
17
|
-
mattr_accessor :preview_path, instance_writer: false
|
|
18
|
-
|
|
19
|
-
# Enable or disable component previews through app configuration:
|
|
20
|
-
#
|
|
21
|
-
# config.action_view_component.show_previews = true
|
|
22
|
-
#
|
|
23
|
-
# Defaults to +true+ for development environment
|
|
24
|
-
#
|
|
25
|
-
mattr_accessor :show_previews, instance_writer: false
|
|
26
|
-
end
|
|
27
|
-
end
|
|
28
|
-
|
|
6
|
+
module Component # :nodoc:
|
|
29
7
|
class Preview
|
|
30
8
|
extend ActiveSupport::DescendantsTracker
|
|
31
9
|
include ActionView::Component::TestHelpers
|
|
32
10
|
|
|
33
|
-
def render(component, *locals)
|
|
34
|
-
render_inline(component, *locals)
|
|
11
|
+
def render(component, *locals, &block)
|
|
12
|
+
render_inline(component, *locals, &block)
|
|
35
13
|
end
|
|
36
14
|
|
|
37
15
|
class << self
|
|
@@ -42,11 +20,14 @@ module ActionView
|
|
|
42
20
|
end
|
|
43
21
|
|
|
44
22
|
# Returns the html of the component in its layout
|
|
45
|
-
def call(example)
|
|
23
|
+
def call(example, layout: nil)
|
|
46
24
|
example_html = new.public_send(example)
|
|
25
|
+
if layout.nil?
|
|
26
|
+
layout = @layout.nil? ? "layouts/application" : @layout
|
|
27
|
+
end
|
|
47
28
|
|
|
48
29
|
Rails::ComponentExamplesController.render(template: "examples/show",
|
|
49
|
-
layout:
|
|
30
|
+
layout: layout,
|
|
50
31
|
assigns: { example: example_html })
|
|
51
32
|
end
|
|
52
33
|
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "active_support/concern"
|
|
4
|
+
|
|
5
|
+
module ActionView
|
|
6
|
+
module Component # :nodoc:
|
|
7
|
+
module Previewable
|
|
8
|
+
extend ActiveSupport::Concern
|
|
9
|
+
|
|
10
|
+
included do
|
|
11
|
+
# Set the location of component previews through app configuration:
|
|
12
|
+
#
|
|
13
|
+
# config.action_view_component.preview_path = "#{Rails.root}/lib/component_previews"
|
|
14
|
+
#
|
|
15
|
+
mattr_accessor :preview_path, instance_writer: false
|
|
16
|
+
|
|
17
|
+
# Enable or disable component previews through app configuration:
|
|
18
|
+
#
|
|
19
|
+
# config.action_view_component.show_previews = true
|
|
20
|
+
#
|
|
21
|
+
# Defaults to +true+ for development environment
|
|
22
|
+
#
|
|
23
|
+
mattr_accessor :show_previews, instance_writer: false
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
@@ -1,18 +1,13 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require "
|
|
4
|
-
require "
|
|
3
|
+
require "rails"
|
|
4
|
+
require "action_view/component"
|
|
5
5
|
|
|
6
6
|
module ActionView
|
|
7
7
|
module Component
|
|
8
8
|
class Railtie < Rails::Railtie # :nodoc:
|
|
9
9
|
config.action_view_component = ActiveSupport::OrderedOptions.new
|
|
10
10
|
|
|
11
|
-
# Disabled due to issues with ActionView::Component::Base not defining .logger
|
|
12
|
-
# initializer "action_view_component.logger" do
|
|
13
|
-
# ActiveSupport.on_load(:action_view_component) { self.logger ||= Rails.logger }
|
|
14
|
-
# end
|
|
15
|
-
|
|
16
11
|
initializer "action_view_component.set_configs" do |app|
|
|
17
12
|
options = app.config.action_view_component
|
|
18
13
|
|
|
@@ -28,6 +23,9 @@ module ActionView
|
|
|
28
23
|
end
|
|
29
24
|
|
|
30
25
|
initializer "action_view_component.set_autoload_paths" do |app|
|
|
26
|
+
require "railties/lib/rails/components_controller"
|
|
27
|
+
require "railties/lib/rails/component_examples_controller"
|
|
28
|
+
|
|
31
29
|
options = app.config.action_view_component
|
|
32
30
|
|
|
33
31
|
if options.show_previews && options.preview_path
|
|
@@ -35,18 +33,23 @@ module ActionView
|
|
|
35
33
|
end
|
|
36
34
|
end
|
|
37
35
|
|
|
36
|
+
initializer "action_view_component.eager_load_actions" do
|
|
37
|
+
ActiveSupport.on_load(:after_initialize) do
|
|
38
|
+
ActionView::Component::Base.descendants.each(&:compile)
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
38
42
|
initializer "action_view_component.compile_config_methods" do
|
|
39
43
|
ActiveSupport.on_load(:action_view_component) do
|
|
40
44
|
config.compile_methods! if config.respond_to?(:compile_methods!)
|
|
41
45
|
end
|
|
42
46
|
end
|
|
43
47
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
# end
|
|
48
|
+
initializer "action_view_component.monkey_patch_render" do
|
|
49
|
+
ActiveSupport.on_load(:action_view) do
|
|
50
|
+
ActionView::Base.prepend ActionView::Component::RenderMonkeyPatch
|
|
51
|
+
end
|
|
52
|
+
end
|
|
50
53
|
|
|
51
54
|
config.after_initialize do |app|
|
|
52
55
|
options = app.config.action_view_component
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
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
|
+
module ActionView
|
|
8
|
+
module Component
|
|
9
|
+
module RenderMonkeyPatch # :nodoc:
|
|
10
|
+
def render(options = {}, args = {}, &block)
|
|
11
|
+
if options.respond_to?(:render_in)
|
|
12
|
+
ActiveSupport::Deprecation.warn(
|
|
13
|
+
"passing component instances (`render MyComponent.new(foo: :bar)`) has been deprecated and will be removed in v2.0.0. Use `render MyComponent, foo: :bar` instead."
|
|
14
|
+
)
|
|
15
|
+
|
|
16
|
+
options.render_in(self, &block)
|
|
17
|
+
elsif options.is_a?(Class) && options < ActionView::Component::Base
|
|
18
|
+
options.new(args).render_in(self, &block)
|
|
19
|
+
elsif options.is_a?(Hash) && options.has_key?(:component)
|
|
20
|
+
options[:component].new(options[:locals]).render_in(self, &block)
|
|
21
|
+
elsif options.respond_to?(:to_component_class) && !options.to_component_class.nil?
|
|
22
|
+
options.to_component_class.new(options).render_in(self, &block)
|
|
23
|
+
else
|
|
24
|
+
super
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
@@ -4,7 +4,7 @@ module ActionView
|
|
|
4
4
|
module Component
|
|
5
5
|
module TestHelpers
|
|
6
6
|
def render_inline(component, **args, &block)
|
|
7
|
-
Nokogiri::HTML(controller.view_context.render(component, args, &block))
|
|
7
|
+
Nokogiri::HTML.fragment(controller.view_context.render(component, args, &block))
|
|
8
8
|
end
|
|
9
9
|
|
|
10
10
|
def controller
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Rspec
|
|
4
|
+
module Generators
|
|
5
|
+
class ComponentGenerator < ::Rails::Generators::NamedBase
|
|
6
|
+
source_root File.expand_path("templates", __dir__)
|
|
7
|
+
|
|
8
|
+
def create_test_file
|
|
9
|
+
template "component_spec.rb", File.join("spec/components", "#{file_name}_component_spec.rb")
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
private
|
|
13
|
+
|
|
14
|
+
def file_name
|
|
15
|
+
@_file_name ||= super.sub(/_component\z/i, "")
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
require "rails_helper"
|
|
2
|
+
|
|
3
|
+
RSpec.describe <%= class_name %>Component, type: :component do
|
|
4
|
+
pending "add some examples to (or delete) #{__FILE__}"
|
|
5
|
+
|
|
6
|
+
# it "renders something useful" do
|
|
7
|
+
# expect(
|
|
8
|
+
# render_inline(described_class, attr: "value") { "Hello, components!" }.css("p").to_html
|
|
9
|
+
# ).to include(
|
|
10
|
+
# "Hello, components!"
|
|
11
|
+
# )
|
|
12
|
+
# end
|
|
13
|
+
end
|
|
@@ -1,12 +1,10 @@
|
|
|
1
1
|
require "test_helper"
|
|
2
2
|
|
|
3
|
-
class <%= class_name %>ComponentTest <
|
|
4
|
-
include ActionView::Component::TestHelpers
|
|
5
|
-
|
|
3
|
+
class <%= class_name %>ComponentTest < ActionView::Component::TestCase
|
|
6
4
|
test "component renders something useful" do
|
|
7
5
|
# assert_equal(
|
|
8
6
|
# %(<span title="my title">Hello, components!</span>),
|
|
9
|
-
# render_inline(<%= class_name
|
|
7
|
+
# render_inline(<%= class_name %>Component, attr: "value") { "Hello, components!" }.css("span").to_html
|
|
10
8
|
# )
|
|
11
9
|
end
|
|
12
10
|
end
|
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.7.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:
|
|
11
|
+
date: 2020-01-09 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: bundler
|
|
@@ -80,6 +80,20 @@ dependencies:
|
|
|
80
80
|
- - "~>"
|
|
81
81
|
- !ruby/object:Gem::Version
|
|
82
82
|
version: '4.0'
|
|
83
|
+
- !ruby/object:Gem::Dependency
|
|
84
|
+
name: better_html
|
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
|
86
|
+
requirements:
|
|
87
|
+
- - "~>"
|
|
88
|
+
- !ruby/object:Gem::Version
|
|
89
|
+
version: '1'
|
|
90
|
+
type: :development
|
|
91
|
+
prerelease: false
|
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
93
|
+
requirements:
|
|
94
|
+
- - "~>"
|
|
95
|
+
- !ruby/object:Gem::Version
|
|
96
|
+
version: '1'
|
|
83
97
|
- !ruby/object:Gem::Dependency
|
|
84
98
|
name: rubocop
|
|
85
99
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -115,6 +129,8 @@ executables: []
|
|
|
115
129
|
extensions: []
|
|
116
130
|
extra_rdoc_files: []
|
|
117
131
|
files:
|
|
132
|
+
- ".github/ISSUE_TEMPLATE"
|
|
133
|
+
- ".github/PULL_REQUEST_TEMPLATE"
|
|
118
134
|
- ".github/workflows/ruby_on_rails.yml"
|
|
119
135
|
- ".gitignore"
|
|
120
136
|
- ".rubocop.yml"
|
|
@@ -129,15 +145,21 @@ files:
|
|
|
129
145
|
- actionview-component.gemspec
|
|
130
146
|
- lib/action_view/component.rb
|
|
131
147
|
- lib/action_view/component/base.rb
|
|
132
|
-
- lib/action_view/component/
|
|
148
|
+
- lib/action_view/component/conversion.rb
|
|
133
149
|
- lib/action_view/component/preview.rb
|
|
150
|
+
- lib/action_view/component/previewable.rb
|
|
134
151
|
- lib/action_view/component/railtie.rb
|
|
152
|
+
- lib/action_view/component/render_monkey_patch.rb
|
|
153
|
+
- lib/action_view/component/template_error.rb
|
|
154
|
+
- lib/action_view/component/test_case.rb
|
|
135
155
|
- lib/action_view/component/test_helpers.rb
|
|
136
156
|
- lib/action_view/component/version.rb
|
|
137
157
|
- lib/rails/generators/component/USAGE
|
|
138
158
|
- lib/rails/generators/component/component_generator.rb
|
|
139
159
|
- lib/rails/generators/component/templates/component.html.erb.tt
|
|
140
160
|
- lib/rails/generators/component/templates/component.rb.tt
|
|
161
|
+
- lib/rails/generators/rspec/component_generator.rb
|
|
162
|
+
- lib/rails/generators/rspec/templates/component_spec.rb.tt
|
|
141
163
|
- lib/rails/generators/test_unit/component_generator.rb
|
|
142
164
|
- lib/rails/generators/test_unit/templates/component_test.rb.tt
|
|
143
165
|
- lib/railties/lib/rails.rb
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
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
|
-
class ActionView::Base
|
|
8
|
-
module RenderMonkeyPatch
|
|
9
|
-
def render(options = {}, args = {}, &block)
|
|
10
|
-
if options.respond_to?(:render_in)
|
|
11
|
-
ActiveSupport::Deprecation.warn(
|
|
12
|
-
"passing component instances (`render MyComponent.new(foo: :bar)`) has been deprecated and will be removed in v2.0.0. Use `render MyComponent, foo: :bar` instead."
|
|
13
|
-
)
|
|
14
|
-
|
|
15
|
-
options.render_in(self, &block)
|
|
16
|
-
elsif options.is_a?(Class) && options < ActionView::Component::Base
|
|
17
|
-
options.new(args).render_in(self, &block)
|
|
18
|
-
elsif options.is_a?(Hash) && options.has_key?(:component)
|
|
19
|
-
options[:component].new(options[:locals]).render_in(self, &block)
|
|
20
|
-
else
|
|
21
|
-
super
|
|
22
|
-
end
|
|
23
|
-
end
|
|
24
|
-
end
|
|
25
|
-
|
|
26
|
-
prepend RenderMonkeyPatch
|
|
27
|
-
end
|