view_component 2.9.0 → 2.13.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.
Potentially problematic release.
This version of view_component might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CHANGELOG.md +35 -1
- data/README.md +151 -0
- data/lib/view_component/base.rb +31 -6
- data/lib/view_component/collection.rb +1 -1
- data/lib/view_component/engine.rb +26 -11
- data/lib/view_component/render_component_helper.rb +9 -0
- data/lib/view_component/render_component_to_string_helper.rb +9 -0
- data/lib/view_component/rendering_component_helper.rb +9 -0
- data/lib/view_component/slot.rb +7 -0
- data/lib/view_component/slotable.rb +121 -0
- data/lib/view_component/version.rb +1 -1
- metadata +7 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3950532a26d2d6d1ddcf412383bfd9cde269c1f69c3d6f7f03dd4e51e7d638e2
|
4
|
+
data.tar.gz: ee2524ef62b335376287f30709e62f2d39a71e43c0f5ec9853db8142b6c8fb3c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c4cc6925445d3486e4c9a6ef915254cf3f28d973ad6a2876fca4fe3435b19ac273f18e89432622eaa38c8bba22ab9e9cafa07e417299dab8537848742175d1c8
|
7
|
+
data.tar.gz: 66d2a44a74a07e78f694adc4790218ee7a9d729e8cd8bb9546d154669a79d5abaa20e7d0bffa0801dfc276ef539b93d5a13dd2b4d3d3093cd8d806972d2dac81
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,39 @@
|
|
1
1
|
# master
|
2
2
|
|
3
|
+
# 2.13.0
|
4
|
+
|
5
|
+
* Add the ability to disable the render monkey patch with `config.view_component.render_monkey_patch_enabled`. In versions of Rails < 6.1, add `render_component` and `render_component_to_string` methods which can be used for rendering components instead of `render`.
|
6
|
+
|
7
|
+
*Johannes Engl*
|
8
|
+
|
9
|
+
# 2.12.0
|
10
|
+
|
11
|
+
* Implement Slots as potential successor to Content Areas.
|
12
|
+
|
13
|
+
*Jens Ljungblad, Brian Bugh, Jon Palmer, Joel Hawksley*
|
14
|
+
|
15
|
+
# 2.11.1
|
16
|
+
|
17
|
+
* Fix kwarg warnings in Ruby 2.7.
|
18
|
+
|
19
|
+
*Joel Hawksley*
|
20
|
+
|
21
|
+
# 2.11.0
|
22
|
+
|
23
|
+
* Ensure Rails configuration is available within components.
|
24
|
+
|
25
|
+
*Trevor Broaddus*
|
26
|
+
|
27
|
+
* Fix bug where global Rails helpers are inaccessible from nested components. Before, `helpers` was pointing to parent component.
|
28
|
+
|
29
|
+
*Franco Sebregondi*
|
30
|
+
|
31
|
+
# 2.10.0
|
32
|
+
|
33
|
+
* Raise an `ArgumentError` with a helpful message when Ruby cannot parse a component class.
|
34
|
+
|
35
|
+
*Max Beizer*
|
36
|
+
|
3
37
|
# 2.9.0
|
4
38
|
|
5
39
|
* Cache components per-request in development, preventing unnecessary recompilation during a single request.
|
@@ -16,7 +50,7 @@
|
|
16
50
|
|
17
51
|
* Add `rendered_component` method to `ViewComponent::TestHelpers` which exposes the raw output of the rendered component.
|
18
52
|
|
19
|
-
|
53
|
+
*Richard Macklin*
|
20
54
|
|
21
55
|
* Support sidecar directories for views and other assets.
|
22
56
|
|
data/README.md
CHANGED
@@ -160,6 +160,133 @@ Returning:
|
|
160
160
|
</div>
|
161
161
|
```
|
162
162
|
|
163
|
+
#### Slots (experimental)
|
164
|
+
|
165
|
+
_Slots are currently under development as a successor to Content Areas. The Slot APIs should be considered unfinished and subject to breaking changes in non-major releases of ViewComponent._
|
166
|
+
|
167
|
+
Slots enable multiple blocks of content to be passed to a single ViewComponent.
|
168
|
+
|
169
|
+
Slots exist in two forms: normal slots and collection slots.
|
170
|
+
|
171
|
+
Normal slots can be rendered once per component. They expose an accessor with the name of the slot that returns an instance of `ViewComponent::Slot`, etc.
|
172
|
+
|
173
|
+
Collection slots can be rendered multiple times. They expose an accessor with the pluralized name of the slot (`#rows`), which is an Array of `ViewComponent::Slot` instances.
|
174
|
+
|
175
|
+
To learn more about the design of the Slots API, see https://github.com/github/view_component/pull/348.
|
176
|
+
|
177
|
+
##### Defining Slots
|
178
|
+
|
179
|
+
Slots are defined by the `with_slot` macro:
|
180
|
+
|
181
|
+
`with_slot :header`
|
182
|
+
|
183
|
+
To define a collection slot, add `collection: true`:
|
184
|
+
|
185
|
+
`with_slot :row, collection: true`
|
186
|
+
|
187
|
+
To define a slot with a custom class, pass `class_name`:
|
188
|
+
|
189
|
+
`with_slot :body, class_name: 'BodySlot`
|
190
|
+
|
191
|
+
Slot classes should be subclasses of `ViewComponent::Slot`.
|
192
|
+
|
193
|
+
##### Example ViewComponent with Slots
|
194
|
+
|
195
|
+
`# box_component.rb`
|
196
|
+
```ruby
|
197
|
+
class BoxComponent < ViewComponent::Base
|
198
|
+
include ViewComponent::Slotable
|
199
|
+
|
200
|
+
with_slot :body, :footer
|
201
|
+
with_slot :header, class_name: "Header"
|
202
|
+
with_slot :row, collection: true, class_name: "Row"
|
203
|
+
|
204
|
+
class Header < ViewComponent::Slot
|
205
|
+
def initialize(class_names: "")
|
206
|
+
@class_names = class_names
|
207
|
+
end
|
208
|
+
|
209
|
+
def class_names
|
210
|
+
"Box-header #{@class_names}"
|
211
|
+
end
|
212
|
+
end
|
213
|
+
|
214
|
+
class Row < ViewComponent::Slot
|
215
|
+
def initialize(theme: :gray)
|
216
|
+
@theme = theme
|
217
|
+
end
|
218
|
+
|
219
|
+
def theme_class_name
|
220
|
+
case @theme
|
221
|
+
when :gray
|
222
|
+
"Box-row--gray"
|
223
|
+
when :hover_gray
|
224
|
+
"Box-row--hover-gray"
|
225
|
+
when :yellow
|
226
|
+
"Box-row--yellow"
|
227
|
+
when :blue
|
228
|
+
"Box-row--blue"
|
229
|
+
when :hover_blue
|
230
|
+
"Box-row--hover-blue"
|
231
|
+
else
|
232
|
+
"Box-row--gray"
|
233
|
+
end
|
234
|
+
end
|
235
|
+
end
|
236
|
+
end
|
237
|
+
```
|
238
|
+
|
239
|
+
`# box_component.html.erb`
|
240
|
+
```erb
|
241
|
+
<div class="Box">
|
242
|
+
<% if header %>
|
243
|
+
<div class="<%= header.class_names %>">
|
244
|
+
<%= header.content %>
|
245
|
+
</div>
|
246
|
+
<% end %>
|
247
|
+
<% if body %>
|
248
|
+
<div class="Box-body">
|
249
|
+
<%= body.content %>
|
250
|
+
</div>
|
251
|
+
<% end %>
|
252
|
+
<% if rows.any? %>
|
253
|
+
<ul>
|
254
|
+
<% rows.each do |row| %>
|
255
|
+
<li class="Box-row <%= row.theme_class_name %>">
|
256
|
+
<%= row.content %>
|
257
|
+
</li>
|
258
|
+
<% end %>
|
259
|
+
</ul>
|
260
|
+
<% end %>
|
261
|
+
<% if footer %>
|
262
|
+
<div class="Box-footer">
|
263
|
+
<%= footer %>
|
264
|
+
</div>
|
265
|
+
<% end %>
|
266
|
+
</div>
|
267
|
+
```
|
268
|
+
|
269
|
+
`# index.html.erb`
|
270
|
+
```erb
|
271
|
+
<%= render(BoxComponent.new) do |component| %>
|
272
|
+
<% component.slot(:header, class_names: "my-class-name") do %>
|
273
|
+
This is my header!
|
274
|
+
<% end %>
|
275
|
+
<% component.slot(:body) do %>
|
276
|
+
This is the body.
|
277
|
+
<% end %>
|
278
|
+
<% component.slot(:row) do %>
|
279
|
+
Row one
|
280
|
+
<% end %>
|
281
|
+
<% component.slot(:row, theme: :yellow) do %>
|
282
|
+
Yellow row
|
283
|
+
<% end %>
|
284
|
+
<% component.slot(:footer) do %>
|
285
|
+
This is the footer.
|
286
|
+
<% end %>
|
287
|
+
<% end %>
|
288
|
+
```
|
289
|
+
|
163
290
|
### Inline Component
|
164
291
|
|
165
292
|
ViewComponents can render without a template file, by defining a `call` method:
|
@@ -584,6 +711,18 @@ To use component previews:
|
|
584
711
|
config.view_component.preview_path = "#{Rails.root}/spec/components/previews"
|
585
712
|
```
|
586
713
|
|
714
|
+
### Disabling the render monkey patch (Rails < 6.1)
|
715
|
+
|
716
|
+
In order to [avoid conflicts](https://github.com/github/view_component/issues/288) between ViewComponent and other gems that also monkey patch the `render` method, it is possible to configure ViewComponent to not include the render monkey patch:
|
717
|
+
|
718
|
+
`config.view_component.render_monkey_patch_enabled = false # defaults to true`
|
719
|
+
|
720
|
+
With the monkey patch disabled, use `render_component` (or `render_component_to_string`) instead:
|
721
|
+
|
722
|
+
```
|
723
|
+
<%= render_component Component.new(message: "bar") %>
|
724
|
+
```
|
725
|
+
|
587
726
|
### Sidecar assets (experimental)
|
588
727
|
|
589
728
|
It’s possible to include Javascript and CSS alongside components, sometimes called "sidecar" assets or files.
|
@@ -731,6 +870,8 @@ ViewComponent is far from a novel idea! Popular implementations of view componen
|
|
731
870
|
## Resources
|
732
871
|
|
733
872
|
- [Encapsulating Views, RailsConf 2020](https://youtu.be/YVYRus_2KZM)
|
873
|
+
- [Rethinking the View Layer with Components, Ruby Rogues Podcast](https://devchat.tv/ruby-rogues/rr-461-rethinking-the-view-layer-with-components-with-joel-hawksley/)
|
874
|
+
- [ViewComponents in Action with Andrew Mason, Ruby on Rails Podcast](https://5by5.tv/rubyonrails/320)
|
734
875
|
- [ViewComponent at GitHub with Joel Hawksley](https://the-ruby-blend.fireside.fm/9)
|
735
876
|
- [Components, HAML vs ERB, and Design Systems](https://the-ruby-blend.fireside.fm/4)
|
736
877
|
- [Choosing the Right Tech Stack with Dave Paola](https://5by5.tv/rubyonrails/307)
|
@@ -783,6 +924,16 @@ ViewComponent is built by:
|
|
783
924
|
|@simonrand|@fugufish|@cover|@franks921|@fsateler|
|
784
925
|
|Dublin, Ireland|Salt Lake City, Utah|Barcelona|South Africa|Chile|
|
785
926
|
|
927
|
+
|<img src="https://avatars.githubusercontent.com/maxbeizer?s=256" alt="maxbeizer" width="128" />|<img src="https://avatars.githubusercontent.com/franco?s=256" alt="franco" width="128" />|<img src="https://avatars.githubusercontent.com/tbroad-ramsey?s=256" alt="tbroad-ramsey" width="128" />|<img src="https://avatars.githubusercontent.com/jensljungblad?s=256" alt="jensljungblad" width="128" />|<img src="https://avatars.githubusercontent.com/bbugh?s=256" alt="bbugh" width="128" />|
|
928
|
+
|:---:|:---:|:---:|:---:|:---:|
|
929
|
+
|@maxbeizer|@franco|@tbroad-ramsey|@jensljungblad|@bbugh|
|
930
|
+
|Nashville, TN|Switzerland|Spring Hill, TN|New York, NY|Austin, TX|
|
931
|
+
|
932
|
+
|<img src="https://avatars.githubusercontent.com/johannesengl?s=256" alt="johannesengl" width="128" />|
|
933
|
+
|:---:|
|
934
|
+
|@johannesengl|
|
935
|
+
|Berlin, Germany|
|
936
|
+
|
786
937
|
## License
|
787
938
|
|
788
939
|
ViewComponent is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
|
data/lib/view_component/base.rb
CHANGED
@@ -5,6 +5,7 @@ require "active_support/configurable"
|
|
5
5
|
require "view_component/collection"
|
6
6
|
require "view_component/compile_cache"
|
7
7
|
require "view_component/previewable"
|
8
|
+
require "view_component/slotable"
|
8
9
|
|
9
10
|
module ViewComponent
|
10
11
|
class Base < ActionView::Base
|
@@ -12,11 +13,15 @@ module ViewComponent
|
|
12
13
|
include ViewComponent::Previewable
|
13
14
|
|
14
15
|
# For CSRF authenticity tokens in forms
|
15
|
-
delegate :form_authenticity_token, :protect_against_forgery?, to: :helpers
|
16
|
+
delegate :form_authenticity_token, :protect_against_forgery?, :config, to: :helpers
|
16
17
|
|
17
18
|
class_attribute :content_areas
|
18
19
|
self.content_areas = [] # class_attribute:default doesn't work until Rails 5.2
|
19
20
|
|
21
|
+
# Hash of registered Slots
|
22
|
+
class_attribute :slots
|
23
|
+
self.slots = {}
|
24
|
+
|
20
25
|
# Entrypoint for rendering components.
|
21
26
|
#
|
22
27
|
# view_context: ActionView context from calling view
|
@@ -106,9 +111,9 @@ module ViewComponent
|
|
106
111
|
@controller ||= view_context.controller
|
107
112
|
end
|
108
113
|
|
109
|
-
# Provides a proxy to access helper methods
|
114
|
+
# Provides a proxy to access helper methods from the context of the current controller
|
110
115
|
def helpers
|
111
|
-
@helpers ||= view_context
|
116
|
+
@helpers ||= controller.view_context
|
112
117
|
end
|
113
118
|
|
114
119
|
# Removes the first part of the path and the extension.
|
@@ -157,12 +162,15 @@ module ViewComponent
|
|
157
162
|
mattr_accessor :test_controller
|
158
163
|
@@test_controller = "ApplicationController"
|
159
164
|
|
165
|
+
# Configure if render monkey patches should be included or not in Rails <6.1.
|
166
|
+
mattr_accessor :render_monkey_patch_enabled, instance_writer: false, default: true
|
167
|
+
|
160
168
|
class << self
|
161
169
|
attr_accessor :source_location
|
162
170
|
|
163
171
|
# Render a component collection.
|
164
|
-
def with_collection(
|
165
|
-
Collection.new(self,
|
172
|
+
def with_collection(collection, **args)
|
173
|
+
Collection.new(self, collection, **args)
|
166
174
|
end
|
167
175
|
|
168
176
|
# Provide identifier for ActionView template annotations
|
@@ -181,6 +189,10 @@ module ViewComponent
|
|
181
189
|
# has been re-defined by the consuming application, likely in ApplicationComponent.
|
182
190
|
child.source_location = caller_locations(1, 10).reject { |l| l.label == "inherited" }[0].absolute_path
|
183
191
|
|
192
|
+
# Clone slot configuration into child class
|
193
|
+
# see #test_slots_pollution
|
194
|
+
child.slots = self.slots.clone
|
195
|
+
|
184
196
|
super
|
185
197
|
end
|
186
198
|
|
@@ -307,7 +319,16 @@ module ViewComponent
|
|
307
319
|
parameter = validate_default ? collection_parameter : provided_collection_parameter
|
308
320
|
|
309
321
|
return unless parameter
|
310
|
-
return if
|
322
|
+
return if initialize_parameters.map(&:last).include?(parameter)
|
323
|
+
|
324
|
+
# If Ruby cannot parse the component class, then the initalize
|
325
|
+
# parameters will be empty and ViewComponent will not be able to render
|
326
|
+
# the component.
|
327
|
+
if initialize_parameters.empty?
|
328
|
+
raise ArgumentError.new(
|
329
|
+
"#{self} initializer is empty or invalid."
|
330
|
+
)
|
331
|
+
end
|
311
332
|
|
312
333
|
raise ArgumentError.new(
|
313
334
|
"#{self} initializer must accept " \
|
@@ -317,6 +338,10 @@ module ViewComponent
|
|
317
338
|
|
318
339
|
private
|
319
340
|
|
341
|
+
def initialize_parameters
|
342
|
+
instance_method(:initialize).parameters
|
343
|
+
end
|
344
|
+
|
320
345
|
def provided_collection_parameter
|
321
346
|
@provided_collection_parameter ||= nil
|
322
347
|
end
|
@@ -9,7 +9,7 @@ module ViewComponent
|
|
9
9
|
@component.validate_collection_parameter!(validate_default: true)
|
10
10
|
|
11
11
|
@collection.map do |item|
|
12
|
-
content = @component.new(component_options(item, iterator)).render_in(view_context, &block)
|
12
|
+
content = @component.new(**component_options(item, iterator)).render_in(view_context, &block)
|
13
13
|
iterator.iterate!
|
14
14
|
content
|
15
15
|
end.join.html_safe
|
@@ -10,6 +10,7 @@ module ViewComponent
|
|
10
10
|
initializer "view_component.set_configs" do |app|
|
11
11
|
options = app.config.view_component
|
12
12
|
|
13
|
+
options.render_monkey_patch_enabled = true if options.render_monkey_patch_enabled.nil?
|
13
14
|
options.show_previews = Rails.env.development? if options.show_previews.nil?
|
14
15
|
options.preview_route ||= ViewComponent::Base.preview_route
|
15
16
|
|
@@ -42,21 +43,35 @@ module ViewComponent
|
|
42
43
|
end
|
43
44
|
end
|
44
45
|
|
45
|
-
initializer "view_component.monkey_patch_render" do
|
46
|
+
initializer "view_component.monkey_patch_render" do |app|
|
47
|
+
next if Rails.version.to_f >= 6.1 || !app.config.view_component.render_monkey_patch_enabled
|
48
|
+
|
46
49
|
ActiveSupport.on_load(:action_view) do
|
47
|
-
|
48
|
-
|
49
|
-
ActionView::Base.prepend ViewComponent::RenderMonkeyPatch
|
50
|
-
end
|
50
|
+
require "view_component/render_monkey_patch"
|
51
|
+
ActionView::Base.prepend ViewComponent::RenderMonkeyPatch
|
51
52
|
end
|
52
53
|
|
53
54
|
ActiveSupport.on_load(:action_controller) do
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
55
|
+
require "view_component/rendering_monkey_patch"
|
56
|
+
require "view_component/render_to_string_monkey_patch"
|
57
|
+
ActionController::Base.prepend ViewComponent::RenderingMonkeyPatch
|
58
|
+
ActionController::Base.prepend ViewComponent::RenderToStringMonkeyPatch
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
initializer "view_component.include_render_component" do |app|
|
63
|
+
next if Rails.version.to_f >= 6.1
|
64
|
+
|
65
|
+
ActiveSupport.on_load(:action_view) do
|
66
|
+
require "view_component/render_component_helper"
|
67
|
+
ActionView::Base.include ViewComponent::RenderComponentHelper
|
68
|
+
end
|
69
|
+
|
70
|
+
ActiveSupport.on_load(:action_controller) do
|
71
|
+
require "view_component/rendering_component_helper"
|
72
|
+
require "view_component/render_component_to_string_helper"
|
73
|
+
ActionController::Base.include ViewComponent::RenderingComponentHelper
|
74
|
+
ActionController::Base.include ViewComponent::RenderComponentToStringHelper
|
60
75
|
end
|
61
76
|
end
|
62
77
|
|
@@ -0,0 +1,121 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "active_support/concern"
|
4
|
+
|
5
|
+
require "view_component/slot"
|
6
|
+
|
7
|
+
module ViewComponent
|
8
|
+
module Slotable
|
9
|
+
extend ActiveSupport::Concern
|
10
|
+
|
11
|
+
class_methods do
|
12
|
+
# support initializing slots as:
|
13
|
+
#
|
14
|
+
# with_slot(
|
15
|
+
# :header,
|
16
|
+
# collection: true|false,
|
17
|
+
# class_name: "Header" # class name string, used to instantiate Slot
|
18
|
+
# )
|
19
|
+
def with_slot(*slot_names, collection: false, class_name: nil)
|
20
|
+
slot_names.each do |slot_name|
|
21
|
+
# Ensure slot_name is not already declared
|
22
|
+
if self.slots.key?(slot_name)
|
23
|
+
raise ArgumentError.new("#{slot_name} slot declared multiple times")
|
24
|
+
end
|
25
|
+
|
26
|
+
# Ensure slot name is not :content
|
27
|
+
if slot_name == :content
|
28
|
+
raise ArgumentError.new ":content is a reserved slot name. Please use another name, such as ':body'"
|
29
|
+
end
|
30
|
+
|
31
|
+
# Set the name of the method used to access the Slot(s)
|
32
|
+
accessor_name =
|
33
|
+
if collection
|
34
|
+
# If Slot is a collection, set the accessor
|
35
|
+
# name to the pluralized form of the slot name
|
36
|
+
# For example: :tab => :tabs
|
37
|
+
ActiveSupport::Inflector.pluralize(slot_name)
|
38
|
+
else
|
39
|
+
slot_name
|
40
|
+
end
|
41
|
+
|
42
|
+
instance_variable_name = "@#{accessor_name}"
|
43
|
+
|
44
|
+
# If the slot is a collection, define an accesor that defaults to an empty array
|
45
|
+
if collection
|
46
|
+
class_eval <<-RUBY
|
47
|
+
def #{accessor_name}
|
48
|
+
#{instance_variable_name} ||= []
|
49
|
+
end
|
50
|
+
RUBY
|
51
|
+
else
|
52
|
+
attr_reader accessor_name
|
53
|
+
end
|
54
|
+
|
55
|
+
# Default class_name to ViewComponent::Slot
|
56
|
+
class_name = "ViewComponent::Slot" unless class_name.present?
|
57
|
+
|
58
|
+
# Register the slot on the component
|
59
|
+
self.slots[slot_name] = {
|
60
|
+
class_name: class_name,
|
61
|
+
instance_variable_name: instance_variable_name,
|
62
|
+
collection: collection
|
63
|
+
}
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
# Build a Slot instance on a component,
|
69
|
+
# exposing it for use inside the
|
70
|
+
# component template.
|
71
|
+
#
|
72
|
+
# slot: Name of Slot, in symbol form
|
73
|
+
# **args: Arguments to be passed to Slot initializer
|
74
|
+
#
|
75
|
+
# For example:
|
76
|
+
# <%= render(SlotsComponent.new) do |component| %>
|
77
|
+
# <% component.slot(:footer, class_names: "footer-class") do %>
|
78
|
+
# <p>This is my footer!</p>
|
79
|
+
# <% end %>
|
80
|
+
# <% end %>
|
81
|
+
#
|
82
|
+
def slot(slot_name, **args, &block)
|
83
|
+
# Raise ArgumentError if `slot` does not exist
|
84
|
+
unless slots.keys.include?(slot_name)
|
85
|
+
raise ArgumentError.new "Unknown slot '#{slot_name}' - expected one of '#{slots.keys}'"
|
86
|
+
end
|
87
|
+
|
88
|
+
slot = slots[slot_name]
|
89
|
+
|
90
|
+
# The class name of the Slot, such as Header
|
91
|
+
slot_class = self.class.const_get(slot[:class_name])
|
92
|
+
|
93
|
+
unless slot_class <= ViewComponent::Slot
|
94
|
+
raise ArgumentError.new "#{slot[:class_name]} must inherit from ViewComponent::Slot"
|
95
|
+
end
|
96
|
+
|
97
|
+
# Instantiate Slot class, accommodating Slots that don't accept arguments
|
98
|
+
slot_instance = args.present? ? slot_class.new(args) : slot_class.new
|
99
|
+
|
100
|
+
# Capture block and assign to slot_instance#content
|
101
|
+
slot_instance.content = view_context.capture(&block) if block_given?
|
102
|
+
|
103
|
+
if slot[:collection]
|
104
|
+
# Initialize instance variable as an empty array
|
105
|
+
# if slot is a collection and has yet to be initialized
|
106
|
+
unless instance_variable_defined?(slot[:instance_variable_name])
|
107
|
+
instance_variable_set(slot[:instance_variable_name], [])
|
108
|
+
end
|
109
|
+
|
110
|
+
# Append Slot instance to collection accessor Array
|
111
|
+
instance_variable_get(slot[:instance_variable_name]) << slot_instance
|
112
|
+
else
|
113
|
+
# Assign the Slot instance to the slot accessor
|
114
|
+
instance_variable_set(slot[:instance_variable_name], slot_instance)
|
115
|
+
end
|
116
|
+
|
117
|
+
# Return nil, as this method should not output anything to the view itself.
|
118
|
+
nil
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: view_component
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.13.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- GitHub Open Source
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-
|
11
|
+
date: 2020-07-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -204,9 +204,14 @@ files:
|
|
204
204
|
- lib/view_component/engine.rb
|
205
205
|
- lib/view_component/preview.rb
|
206
206
|
- lib/view_component/previewable.rb
|
207
|
+
- lib/view_component/render_component_helper.rb
|
208
|
+
- lib/view_component/render_component_to_string_helper.rb
|
207
209
|
- lib/view_component/render_monkey_patch.rb
|
208
210
|
- lib/view_component/render_to_string_monkey_patch.rb
|
211
|
+
- lib/view_component/rendering_component_helper.rb
|
209
212
|
- lib/view_component/rendering_monkey_patch.rb
|
213
|
+
- lib/view_component/slot.rb
|
214
|
+
- lib/view_component/slotable.rb
|
210
215
|
- lib/view_component/template_error.rb
|
211
216
|
- lib/view_component/test_case.rb
|
212
217
|
- lib/view_component/test_helpers.rb
|