view_component 2.35.0 → 2.36.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of view_component might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/app/controllers/view_components_controller.rb +1 -1
- data/docs/CHANGELOG.md +30 -0
- data/lib/view_component/base.rb +43 -13
- data/lib/view_component/collection.rb +4 -1
- data/lib/view_component/compiler.rb +40 -10
- data/lib/view_component/content_areas.rb +10 -3
- data/lib/view_component/engine.rb +13 -2
- data/lib/view_component/instrumentation.rb +5 -1
- data/lib/view_component/preview.rb +5 -1
- data/lib/view_component/slot_v2.rb +7 -1
- data/lib/view_component/slotable_v2.rb +40 -7
- data/lib/view_component/test_helpers.rb +7 -1
- data/lib/view_component/version.rb +1 -1
- data/lib/view_component/with_content_helper.rb +4 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 74a9bb65a4c364b86c92249805629eb7dc5d7dad010e6743a461cd668d6897f3
|
4
|
+
data.tar.gz: ab5bf1fa266b729faebf8bed8b8884300a8fca4462d4ab8a0c6a0dce32153a26
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: eae497c864c6005b6ec9cea9073d2659b5378e0f0ebde82397a7e8a09e834525293f6b1a25a615198a28ae9ccfc077505c0bdb35def7cbea69aeaa3472dba7a3
|
7
|
+
data.tar.gz: b11a86583fb7886828690d0d9d57ec9db3bf0f99b40f5cc0de5bb8fb6ca54ffd8e6fb65e150cdd2865c8cd71d46e13e9d7adbd3bd846d5ba5996a0a3c4ebf7d0
|
@@ -56,7 +56,7 @@ class ViewComponentsController < Rails::ApplicationController # :nodoc:
|
|
56
56
|
if preview
|
57
57
|
@preview = ViewComponent::Preview.find(preview)
|
58
58
|
else
|
59
|
-
raise AbstractController::ActionNotFound, "Component preview '#{params[:path]}' not found"
|
59
|
+
raise AbstractController::ActionNotFound, "Component preview '#{params[:path]}' not found."
|
60
60
|
end
|
61
61
|
end
|
62
62
|
|
data/docs/CHANGELOG.md
CHANGED
@@ -7,6 +7,36 @@ title: Changelog
|
|
7
7
|
|
8
8
|
## main
|
9
9
|
|
10
|
+
## 2.36.0
|
11
|
+
|
12
|
+
* Add `slot_type` helper method.
|
13
|
+
|
14
|
+
*Jon Palmer*
|
15
|
+
|
16
|
+
* Add test case for rendering a ViewComponent with slots in a controller.
|
17
|
+
|
18
|
+
*Simon Fish*
|
19
|
+
|
20
|
+
* Add example ViewComponent to documentation landing page.
|
21
|
+
|
22
|
+
*Joel Hawksley*
|
23
|
+
|
24
|
+
* Set maximum line length to 120.
|
25
|
+
|
26
|
+
*Joel Hawksley*
|
27
|
+
|
28
|
+
* Setting a collection slot with the plural setter (`component.items(array)` for `renders_many :items`) returns the array of slots.
|
29
|
+
|
30
|
+
*Jon Palmer*
|
31
|
+
|
32
|
+
* Update error messages to be more descriptive and helpful.
|
33
|
+
|
34
|
+
*Joel Hawksley*
|
35
|
+
|
36
|
+
* Raise an error if the slot name for renders_many is :contents
|
37
|
+
|
38
|
+
*Simon Fish*
|
39
|
+
|
10
40
|
## 2.35.0
|
11
41
|
|
12
42
|
* Only load assets for Preview source highlighting if previews are enabled.
|
data/lib/view_component/base.rb
CHANGED
@@ -86,7 +86,11 @@ module ViewComponent
|
|
86
86
|
@current_template = self
|
87
87
|
|
88
88
|
if block && defined?(@__vc_content_set_by_with_content)
|
89
|
-
raise ArgumentError.new(
|
89
|
+
raise ArgumentError.new(
|
90
|
+
"It looks like a block was provided after calling `with_content` on #{self.class.name}, " \
|
91
|
+
"which means that ViewComponent doesn't know which content to use.\n\n" \
|
92
|
+
"To fix this issue, use either `with_content` or a block."
|
93
|
+
)
|
90
94
|
end
|
91
95
|
|
92
96
|
@__vc_content_evaluated = false
|
@@ -110,7 +114,8 @@ module ViewComponent
|
|
110
114
|
""
|
111
115
|
end
|
112
116
|
|
113
|
-
# Called before rendering the component. Override to perform operations that
|
117
|
+
# Called before rendering the component. Override to perform operations that
|
118
|
+
# depend on having access to the view context, such as helpers.
|
114
119
|
#
|
115
120
|
# @return [void]
|
116
121
|
def before_render
|
@@ -150,20 +155,40 @@ module ViewComponent
|
|
150
155
|
end
|
151
156
|
end
|
152
157
|
|
153
|
-
# The current controller. Use sparingly as doing so introduces coupling
|
158
|
+
# The current controller. Use sparingly as doing so introduces coupling
|
159
|
+
# that inhibits encapsulation & reuse, often making testing difficult.
|
154
160
|
#
|
155
161
|
# @return [ActionController::Base]
|
156
162
|
def controller
|
157
|
-
|
163
|
+
if view_context.nil?
|
164
|
+
raise(
|
165
|
+
ViewContextCalledBeforeRenderError,
|
166
|
+
"`#controller` cannot be used during initialization, as it depends " \
|
167
|
+
"on the view context that only exists once a ViewComponent is passed to " \
|
168
|
+
"the Rails render pipeline.\n\n" \
|
169
|
+
"It's sometimes possible to fix this issue by moving code dependent on " \
|
170
|
+
"`#controller` to a `#before_render` method: https://viewcomponent.org/api.html#before_render--void."
|
171
|
+
)
|
172
|
+
end
|
158
173
|
|
159
174
|
@__vc_controller ||= view_context.controller
|
160
175
|
end
|
161
176
|
|
162
|
-
# A proxy through which to access helpers. Use sparingly as doing so introduces
|
177
|
+
# A proxy through which to access helpers. Use sparingly as doing so introduces
|
178
|
+
# coupling that inhibits encapsulation & reuse, often making testing difficult.
|
163
179
|
#
|
164
180
|
# @return [ActionView::Base]
|
165
181
|
def helpers
|
166
|
-
|
182
|
+
if view_context.nil?
|
183
|
+
raise(
|
184
|
+
ViewContextCalledBeforeRenderError,
|
185
|
+
"`#helpers` cannot be used during initialization, as it depends " \
|
186
|
+
"on the view context that only exists once a ViewComponent is passed to " \
|
187
|
+
"the Rails render pipeline.\n\n" \
|
188
|
+
"It's sometimes possible to fix this issue by moving code dependent on " \
|
189
|
+
"`#helpers` to a `#before_render` method: https://viewcomponent.org/api.html#before_render--void."
|
190
|
+
)
|
191
|
+
end
|
167
192
|
|
168
193
|
@__vc_helpers ||= controller.view_context
|
169
194
|
end
|
@@ -201,7 +226,8 @@ module ViewComponent
|
|
201
226
|
self
|
202
227
|
end
|
203
228
|
|
204
|
-
# The current request. Use sparingly as doing so introduces coupling that
|
229
|
+
# The current request. Use sparingly as doing so introduces coupling that
|
230
|
+
# inhibits encapsulation & reuse, often making testing difficult.
|
205
231
|
#
|
206
232
|
# @return [ActionDispatch::Request]
|
207
233
|
def request
|
@@ -409,13 +435,18 @@ module ViewComponent
|
|
409
435
|
# the component.
|
410
436
|
if initialize_parameters.empty?
|
411
437
|
raise ArgumentError.new(
|
412
|
-
"#{self} initializer is empty or invalid."
|
438
|
+
"The #{self} initializer is empty or invalid." \
|
439
|
+
"It must accept the parameter `#{parameter}` to render it as a collection.\n\n" \
|
440
|
+
"To fix this issue, update the initializer to accept `#{parameter}`.\n\n" \
|
441
|
+
"See https://viewcomponent.org/guide/collections.html for more information on rendering collections."
|
413
442
|
)
|
414
443
|
end
|
415
444
|
|
416
445
|
raise ArgumentError.new(
|
417
|
-
"#{self}
|
418
|
-
"
|
446
|
+
"The initializer for #{self} does not accept the parameter `#{parameter}`, " \
|
447
|
+
"which is required in order to render it as a collection.\n\n" \
|
448
|
+
"To fix this issue, update the initializer to accept `#{parameter}`.\n\n" \
|
449
|
+
"See https://viewcomponent.org/guide/collections.html for more information on rendering collections."
|
419
450
|
)
|
420
451
|
end
|
421
452
|
|
@@ -427,9 +458,8 @@ module ViewComponent
|
|
427
458
|
return unless initialize_parameter_names.include?(RESERVED_PARAMETER)
|
428
459
|
|
429
460
|
raise ViewComponent::ComponentError.new(
|
430
|
-
"#{self} initializer cannot
|
431
|
-
"
|
432
|
-
"public ViewComponent method."
|
461
|
+
"#{self} initializer cannot accept the parameter `#{RESERVED_PARAMETER}`, as it will override a " \
|
462
|
+
"public ViewComponent method. To fix this issue, rename the parameter."
|
433
463
|
)
|
434
464
|
end
|
435
465
|
|
@@ -32,7 +32,10 @@ module ViewComponent
|
|
32
32
|
if object.respond_to?(:to_ary)
|
33
33
|
object.to_ary
|
34
34
|
else
|
35
|
-
raise ArgumentError.new(
|
35
|
+
raise ArgumentError.new(
|
36
|
+
"The value of the first argument passed to `with_collection` isn't a valid collection. " \
|
37
|
+
"Make sure it responds to `to_ary`."
|
38
|
+
)
|
36
39
|
end
|
37
40
|
end
|
38
41
|
|
@@ -16,7 +16,10 @@ module ViewComponent
|
|
16
16
|
subclass_instance_methods = component_class.instance_methods(false)
|
17
17
|
|
18
18
|
if subclass_instance_methods.include?(:with_content) && raise_errors
|
19
|
-
raise ViewComponent::ComponentError.new(
|
19
|
+
raise ViewComponent::ComponentError.new(
|
20
|
+
"#{component_class} implements a reserved method, `#with_content`.\n\n" \
|
21
|
+
"To fix this issue, change the name of the method."
|
22
|
+
)
|
20
23
|
end
|
21
24
|
|
22
25
|
if template_errors.present?
|
@@ -27,7 +30,8 @@ module ViewComponent
|
|
27
30
|
|
28
31
|
if subclass_instance_methods.include?(:before_render_check)
|
29
32
|
ActiveSupport::Deprecation.warn(
|
30
|
-
"
|
33
|
+
"`#before_render_check` will be removed in v3.0.0.\n\n" \
|
34
|
+
"To fix this issue, use `#before_render` instead."
|
31
35
|
)
|
32
36
|
end
|
33
37
|
|
@@ -40,7 +44,10 @@ module ViewComponent
|
|
40
44
|
# Remove existing compiled template methods,
|
41
45
|
# as Ruby warns when redefining a method.
|
42
46
|
method_name = call_method_name(template[:variant])
|
43
|
-
|
47
|
+
|
48
|
+
if component_class.instance_methods.include?(method_name.to_sym)
|
49
|
+
component_class.send(:undef_method, method_name.to_sym)
|
50
|
+
end
|
44
51
|
|
45
52
|
component_class.class_eval <<-RUBY, template[:path], -1
|
46
53
|
def #{method_name}
|
@@ -62,7 +69,9 @@ module ViewComponent
|
|
62
69
|
attr_reader :component_class
|
63
70
|
|
64
71
|
def define_render_template_for
|
65
|
-
|
72
|
+
if component_class.instance_methods.include?(:render_template_for)
|
73
|
+
component_class.send(:undef_method, :render_template_for)
|
74
|
+
end
|
66
75
|
|
67
76
|
variant_elsifs = variants.compact.uniq.map do |variant|
|
68
77
|
"elsif variant.to_sym == :#{variant}\n #{call_method_name(variant)}"
|
@@ -90,7 +99,9 @@ module ViewComponent
|
|
90
99
|
end
|
91
100
|
|
92
101
|
if templates.count { |template| template[:variant].nil? } > 1
|
93
|
-
errors <<
|
102
|
+
errors <<
|
103
|
+
"More than one template found for #{component_class}. " \
|
104
|
+
"There can only be one default template file per component."
|
94
105
|
end
|
95
106
|
|
96
107
|
invalid_variants =
|
@@ -101,11 +112,16 @@ module ViewComponent
|
|
101
112
|
sort
|
102
113
|
|
103
114
|
unless invalid_variants.empty?
|
104
|
-
errors <<
|
115
|
+
errors <<
|
116
|
+
"More than one template found for #{'variant'.pluralize(invalid_variants.count)} " \
|
117
|
+
"#{invalid_variants.map { |v| "'#{v}'" }.to_sentence} in #{component_class}. " \
|
118
|
+
"There can only be one template file per variant."
|
105
119
|
end
|
106
120
|
|
107
121
|
if templates.find { |template| template[:variant].nil? } && inline_calls_defined_on_self.include?(:call)
|
108
|
-
errors <<
|
122
|
+
errors <<
|
123
|
+
"Template file and inline render method found for #{component_class}. " \
|
124
|
+
"There can only be a template file or inline render method per component."
|
109
125
|
end
|
110
126
|
|
111
127
|
duplicate_template_file_and_inline_variant_calls =
|
@@ -114,7 +130,12 @@ module ViewComponent
|
|
114
130
|
unless duplicate_template_file_and_inline_variant_calls.empty?
|
115
131
|
count = duplicate_template_file_and_inline_variant_calls.count
|
116
132
|
|
117
|
-
errors <<
|
133
|
+
errors <<
|
134
|
+
"Template #{'file'.pluralize(count)} and inline render #{'method'.pluralize(count)} " \
|
135
|
+
"found for #{'variant'.pluralize(count)} " \
|
136
|
+
"#{duplicate_template_file_and_inline_variant_calls.map { |v| "'#{v}'" }.to_sentence} " \
|
137
|
+
"in #{component_class}. " \
|
138
|
+
"There can only be a template file or inline render method per variant."
|
118
139
|
end
|
119
140
|
|
120
141
|
errors
|
@@ -143,7 +164,10 @@ module ViewComponent
|
|
143
164
|
# Fetch only ViewComponent ancestor classes to limit the scope of
|
144
165
|
# finding inline calls
|
145
166
|
view_component_ancestors =
|
146
|
-
|
167
|
+
(
|
168
|
+
component_class.ancestors.take_while { |ancestor| ancestor != ViewComponent::Base } -
|
169
|
+
component_class.included_modules
|
170
|
+
)
|
147
171
|
|
148
172
|
view_component_ancestors.flat_map { |ancestor| ancestor.instance_methods(false).grep(/^call/) }.uniq
|
149
173
|
end
|
@@ -172,7 +196,13 @@ module ViewComponent
|
|
172
196
|
if handler.method(:call).parameters.length > 1
|
173
197
|
handler.call(component_class, template)
|
174
198
|
else
|
175
|
-
handler.call(
|
199
|
+
handler.call(
|
200
|
+
OpenStruct.new(
|
201
|
+
source: template,
|
202
|
+
identifier: component_class.identifier,
|
203
|
+
type: component_class.type
|
204
|
+
)
|
205
|
+
)
|
176
206
|
end
|
177
207
|
end
|
178
208
|
|
@@ -14,7 +14,11 @@ module ViewComponent
|
|
14
14
|
# @private
|
15
15
|
def with(area, content = nil, &block)
|
16
16
|
unless content_areas.include?(area)
|
17
|
-
raise ArgumentError.new
|
17
|
+
raise ArgumentError.new(
|
18
|
+
"Unknown content_area '#{area}' for #{self} - expected one of '#{content_areas}'.\n\n" \
|
19
|
+
"To fix this issue, add `with_content_area :#{area}` to #{self} or reference " \
|
20
|
+
"a valid content area."
|
21
|
+
)
|
18
22
|
end
|
19
23
|
|
20
24
|
if block_given?
|
@@ -28,12 +32,15 @@ module ViewComponent
|
|
28
32
|
class_methods do
|
29
33
|
def with_content_areas(*areas)
|
30
34
|
ActiveSupport::Deprecation.warn(
|
31
|
-
"`with_content_areas` is deprecated and will be removed in ViewComponent v3.0.0.\n" \
|
35
|
+
"`with_content_areas` is deprecated and will be removed in ViewComponent v3.0.0.\n\n" \
|
32
36
|
"Use slots (https://viewcomponent.org/guide/slots.html) instead."
|
33
37
|
)
|
34
38
|
|
35
39
|
if areas.include?(:content)
|
36
|
-
raise ArgumentError.new
|
40
|
+
raise ArgumentError.new(
|
41
|
+
"#{self} defines a content area called :content, which is a reserved name. \n\n" \
|
42
|
+
"To fix this issue, use another name, such as `:body`."
|
43
|
+
)
|
37
44
|
end
|
38
45
|
|
39
46
|
areas.each do |area|
|
@@ -110,8 +110,19 @@ module ViewComponent
|
|
110
110
|
app.routes.prepend do
|
111
111
|
preview_controller = options.preview_controller.sub(/Controller$/, "").underscore
|
112
112
|
|
113
|
-
get
|
114
|
-
|
113
|
+
get(
|
114
|
+
options.preview_route,
|
115
|
+
to: "#{preview_controller}#index",
|
116
|
+
as: :preview_view_components,
|
117
|
+
internal: true
|
118
|
+
)
|
119
|
+
|
120
|
+
get(
|
121
|
+
"#{options.preview_route}/*path",
|
122
|
+
to: "#{preview_controller}#previews",
|
123
|
+
as: :preview_view_component,
|
124
|
+
internal: true
|
125
|
+
)
|
115
126
|
end
|
116
127
|
end
|
117
128
|
|
@@ -9,7 +9,11 @@ module ViewComponent # :nodoc:
|
|
9
9
|
end
|
10
10
|
|
11
11
|
def render_in(view_context, &block)
|
12
|
-
ActiveSupport::Notifications.instrument(
|
12
|
+
ActiveSupport::Notifications.instrument(
|
13
|
+
"!render.view_component",
|
14
|
+
name: self.class.name,
|
15
|
+
identifier: self.class.identifier
|
16
|
+
) do
|
13
17
|
super(view_context, &block)
|
14
18
|
end
|
15
19
|
end
|
@@ -77,7 +77,11 @@ module ViewComponent # :nodoc:
|
|
77
77
|
end
|
78
78
|
|
79
79
|
if preview_path.nil?
|
80
|
-
raise
|
80
|
+
raise(
|
81
|
+
PreviewTemplateError,
|
82
|
+
"A preview template for example #{example} does not exist.\n\n" \
|
83
|
+
"To fix this issue, create a template for the example."
|
84
|
+
)
|
81
85
|
end
|
82
86
|
|
83
87
|
path = Dir["#{preview_path}/#{preview_name}_preview/#{example}.html.*"].first
|
@@ -30,7 +30,13 @@ module ViewComponent
|
|
30
30
|
|
31
31
|
view_context = @parent.send(:view_context)
|
32
32
|
|
33
|
-
|
33
|
+
if defined?(@__vc_content_block) && defined?(@__vc_content_set_by_with_content)
|
34
|
+
raise ArgumentError.new(
|
35
|
+
"It looks like a block was provided after calling `with_content` on #{self.class.name}, " \
|
36
|
+
"which means that ViewComponent doesn't know which content to use.\n\n" \
|
37
|
+
"To fix this issue, use either `with_content` or a block."
|
38
|
+
)
|
39
|
+
end
|
34
40
|
|
35
41
|
@content =
|
36
42
|
if defined?(@__vc_component_instance)
|
@@ -65,7 +65,7 @@ module ViewComponent
|
|
65
65
|
# <% end %>
|
66
66
|
# <% end %>
|
67
67
|
def renders_one(slot_name, callable = nil)
|
68
|
-
|
68
|
+
validate_singular_slot_name(slot_name)
|
69
69
|
|
70
70
|
define_method slot_name do |*args, **kwargs, &block|
|
71
71
|
if args.empty? && kwargs.empty? && block.nil?
|
@@ -116,7 +116,7 @@ module ViewComponent
|
|
116
116
|
# <% end %>
|
117
117
|
# <% end %>
|
118
118
|
def renders_many(slot_name, callable = nil)
|
119
|
-
|
119
|
+
validate_plural_slot_name(slot_name)
|
120
120
|
|
121
121
|
singular_name = ActiveSupport::Inflector.singularize(slot_name)
|
122
122
|
|
@@ -133,7 +133,7 @@ module ViewComponent
|
|
133
133
|
if collection_args.nil? && block.nil?
|
134
134
|
get_slot(slot_name)
|
135
135
|
else
|
136
|
-
collection_args.
|
136
|
+
collection_args.map do |args|
|
137
137
|
set_slot(slot_name, **args, &block)
|
138
138
|
end
|
139
139
|
end
|
@@ -142,6 +142,17 @@ module ViewComponent
|
|
142
142
|
register_slot(slot_name, collection: true, callable: callable)
|
143
143
|
end
|
144
144
|
|
145
|
+
def slot_type(slot_name)
|
146
|
+
registered_slot = registered_slots[slot_name]
|
147
|
+
if registered_slot
|
148
|
+
registered_slot[:collection] ? :collection : :single
|
149
|
+
else
|
150
|
+
plural_slot_name = ActiveSupport::Inflector.pluralize(slot_name).to_sym
|
151
|
+
plural_registered_slot = registered_slots[plural_slot_name]
|
152
|
+
plural_registered_slot&.fetch(:collection) ? :collection_item : nil
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
145
156
|
# Clone slot configuration into child class
|
146
157
|
# see #test_slots_pollution
|
147
158
|
def inherited(child)
|
@@ -174,14 +185,35 @@ module ViewComponent
|
|
174
185
|
self.registered_slots[slot_name] = slot
|
175
186
|
end
|
176
187
|
|
177
|
-
def
|
188
|
+
def validate_plural_slot_name(slot_name)
|
189
|
+
if slot_name.to_sym == :contents
|
190
|
+
raise ArgumentError.new(
|
191
|
+
"#{self} declares a slot named #{slot_name}, which is a reserved word in the ViewComponent framework.\n\n" \
|
192
|
+
"To fix this issue, choose a different name."
|
193
|
+
)
|
194
|
+
end
|
195
|
+
|
196
|
+
raise_if_slot_registered(slot_name)
|
197
|
+
end
|
198
|
+
|
199
|
+
def validate_singular_slot_name(slot_name)
|
178
200
|
if slot_name.to_sym == :content
|
179
|
-
raise ArgumentError.new(
|
201
|
+
raise ArgumentError.new(
|
202
|
+
"#{self} declares a slot named #{slot_name}, which is a reserved word in the ViewComponent framework.\n\n" \
|
203
|
+
"To fix this issue, choose a different name."
|
204
|
+
)
|
180
205
|
end
|
181
206
|
|
207
|
+
raise_if_slot_registered(slot_name)
|
208
|
+
end
|
209
|
+
|
210
|
+
def raise_if_slot_registered(slot_name)
|
182
211
|
if self.registered_slots.key?(slot_name)
|
183
212
|
# TODO remove? This breaks overriding slots when slots are inherited
|
184
|
-
raise ArgumentError.new(
|
213
|
+
raise ArgumentError.new(
|
214
|
+
"#{self} declares the #{slot_name} slot multiple times.\n\n" \
|
215
|
+
"To fix this issue, choose a different slot name."
|
216
|
+
)
|
185
217
|
end
|
186
218
|
end
|
187
219
|
end
|
@@ -224,7 +256,8 @@ module ViewComponent
|
|
224
256
|
slot.__vc_component_instance = slot_definition[:renderable].new(*args, **kwargs)
|
225
257
|
# If class name as a string
|
226
258
|
elsif slot_definition[:renderable_class_name]
|
227
|
-
slot.__vc_component_instance =
|
259
|
+
slot.__vc_component_instance =
|
260
|
+
self.class.const_get(slot_definition[:renderable_class_name]).new(*args, **kwargs)
|
228
261
|
# If passed a lambda
|
229
262
|
elsif slot_definition[:renderable_function]
|
230
263
|
# Use `bind(self)` to ensure lambda is executed in the context of the
|
@@ -17,7 +17,13 @@ module ViewComponent
|
|
17
17
|
# We don't have a test case for running an application without capybara installed.
|
18
18
|
# It's probably fine to leave this without coverage.
|
19
19
|
# :nocov:
|
20
|
-
|
20
|
+
if ENV["DEBUG"]
|
21
|
+
warn(
|
22
|
+
"WARNING in `ViewComponent::TestHelpers`: You must add `capybara` " \
|
23
|
+
"to your Gemfile to use Capybara assertions."
|
24
|
+
)
|
25
|
+
end
|
26
|
+
|
21
27
|
# :nocov:
|
22
28
|
end
|
23
29
|
|
@@ -4,7 +4,10 @@ module ViewComponent
|
|
4
4
|
module WithContentHelper
|
5
5
|
def with_content(value)
|
6
6
|
if value.nil?
|
7
|
-
raise ArgumentError.new(
|
7
|
+
raise ArgumentError.new(
|
8
|
+
"No content provided to `#with_content` for #{self}.\n\n" \
|
9
|
+
"To fix this issue, pass a value."
|
10
|
+
)
|
8
11
|
else
|
9
12
|
@__vc_content_set_by_with_content = value
|
10
13
|
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.36.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: 2021-07-
|
11
|
+
date: 2021-07-28 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|