view_component 2.31.0 → 2.35.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/README.md +1 -1
- data/app/assets/vendor/prism.css +196 -0
- data/app/assets/vendor/prism.min.js +12 -0
- data/app/helpers/preview_helper.rb +19 -0
- data/app/views/test_mailer/test_email.html.erb +1 -0
- data/app/views/view_components/_preview_source.html.erb +17 -0
- data/app/views/view_components/preview.html.erb +6 -2
- data/{CHANGELOG.md → docs/CHANGELOG.md} +131 -1
- data/lib/rails/generators/abstract_generator.rb +29 -0
- data/lib/rails/generators/component/component_generator.rb +5 -5
- data/lib/rails/generators/erb/component_generator.rb +7 -16
- data/lib/rails/generators/haml/component_generator.rb +6 -16
- data/lib/rails/generators/slim/component_generator.rb +6 -16
- data/lib/view_component.rb +2 -0
- data/lib/view_component/base.rb +142 -74
- data/lib/view_component/collection.rb +3 -1
- data/lib/view_component/compile_cache.rb +1 -0
- data/lib/view_component/compiler.rb +58 -54
- data/lib/view_component/content_areas.rb +50 -0
- data/lib/view_component/engine.rb +19 -2
- data/lib/view_component/instrumentation.rb +17 -0
- data/lib/view_component/preview.rb +14 -7
- data/lib/view_component/previewable.rb +16 -18
- data/lib/view_component/slot_v2.rb +28 -27
- data/lib/view_component/slotable.rb +2 -1
- data/lib/view_component/slotable_v2.rb +23 -22
- data/lib/view_component/test_helpers.rb +6 -1
- data/lib/view_component/translatable.rb +6 -5
- data/lib/view_component/version.rb +1 -1
- data/lib/view_component/with_content_helper.rb +1 -1
- data/lib/yard/mattr_accessor_handler.rb +19 -0
- metadata +94 -43
@@ -1,8 +1,12 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require "rails/generators/abstract_generator"
|
4
|
+
|
3
5
|
module Rails
|
4
6
|
module Generators
|
5
7
|
class ComponentGenerator < Rails::Generators::NamedBase
|
8
|
+
include ViewComponent::AbstractGenerator
|
9
|
+
|
6
10
|
source_root File.expand_path("templates", __dir__)
|
7
11
|
|
8
12
|
argument :attributes, type: :array, default: [], banner: "attribute"
|
@@ -10,7 +14,7 @@ module Rails
|
|
10
14
|
class_option :inline, type: :boolean, default: false
|
11
15
|
|
12
16
|
def create_component_file
|
13
|
-
template "component.rb", File.join(
|
17
|
+
template "component.rb", File.join(component_path, class_path, "#{file_name}_component.rb")
|
14
18
|
end
|
15
19
|
|
16
20
|
hook_for :test_framework
|
@@ -23,10 +27,6 @@ module Rails
|
|
23
27
|
|
24
28
|
private
|
25
29
|
|
26
|
-
def file_name
|
27
|
-
@_file_name ||= super.sub(/_component\z/i, "")
|
28
|
-
end
|
29
|
-
|
30
30
|
def parent_class
|
31
31
|
defined?(ApplicationComponent) ? "ApplicationComponent" : "ViewComponent::Base"
|
32
32
|
end
|
@@ -1,32 +1,23 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require "rails/generators/erb"
|
4
|
+
require "rails/generators/abstract_generator"
|
4
5
|
|
5
6
|
module Erb
|
6
7
|
module Generators
|
7
8
|
class ComponentGenerator < Base
|
9
|
+
include ViewComponent::AbstractGenerator
|
10
|
+
|
8
11
|
source_root File.expand_path("templates", __dir__)
|
9
12
|
class_option :sidecar, type: :boolean, default: false
|
10
13
|
class_option :inline, type: :boolean, default: false
|
11
14
|
|
12
|
-
def
|
13
|
-
|
14
|
-
template "component.html.erb", destination
|
15
|
-
end
|
16
|
-
end
|
17
|
-
|
18
|
-
private
|
19
|
-
|
20
|
-
def destination
|
21
|
-
if options["sidecar"]
|
22
|
-
File.join("app/components", class_path, "#{file_name}_component", "#{file_name}_component.html.erb")
|
23
|
-
else
|
24
|
-
File.join("app/components", class_path, "#{file_name}_component.html.erb")
|
25
|
-
end
|
15
|
+
def engine_name
|
16
|
+
"erb"
|
26
17
|
end
|
27
18
|
|
28
|
-
def
|
29
|
-
|
19
|
+
def copy_view_file
|
20
|
+
super
|
30
21
|
end
|
31
22
|
end
|
32
23
|
end
|
@@ -5,27 +5,17 @@ require "rails/generators/erb/component_generator"
|
|
5
5
|
module Haml
|
6
6
|
module Generators
|
7
7
|
class ComponentGenerator < Erb::Generators::ComponentGenerator
|
8
|
+
include ViewComponent::AbstractGenerator
|
9
|
+
|
8
10
|
source_root File.expand_path("templates", __dir__)
|
9
11
|
class_option :sidecar, type: :boolean, default: false
|
10
12
|
|
11
|
-
def
|
12
|
-
|
13
|
-
template "component.html.haml", destination
|
14
|
-
end
|
15
|
-
end
|
16
|
-
|
17
|
-
private
|
18
|
-
|
19
|
-
def destination
|
20
|
-
if options["sidecar"]
|
21
|
-
File.join("app/components", class_path, "#{file_name}_component", "#{file_name}_component.html.haml")
|
22
|
-
else
|
23
|
-
File.join("app/components", class_path, "#{file_name}_component.html.haml")
|
24
|
-
end
|
13
|
+
def engine_name
|
14
|
+
"haml"
|
25
15
|
end
|
26
16
|
|
27
|
-
def
|
28
|
-
|
17
|
+
def copy_view_file
|
18
|
+
super
|
29
19
|
end
|
30
20
|
end
|
31
21
|
end
|
@@ -5,27 +5,17 @@ require "rails/generators/erb/component_generator"
|
|
5
5
|
module Slim
|
6
6
|
module Generators
|
7
7
|
class ComponentGenerator < Erb::Generators::ComponentGenerator
|
8
|
+
include ViewComponent::AbstractGenerator
|
9
|
+
|
8
10
|
source_root File.expand_path("templates", __dir__)
|
9
11
|
class_option :sidecar, type: :boolean, default: false
|
10
12
|
|
11
|
-
def
|
12
|
-
|
13
|
-
template "component.html.slim", destination
|
14
|
-
end
|
15
|
-
end
|
16
|
-
|
17
|
-
private
|
18
|
-
|
19
|
-
def destination
|
20
|
-
if options["sidecar"]
|
21
|
-
File.join("app/components", class_path, "#{file_name}_component", "#{file_name}_component.html.slim")
|
22
|
-
else
|
23
|
-
File.join("app/components", class_path, "#{file_name}_component.html.slim")
|
24
|
-
end
|
13
|
+
def engine_name
|
14
|
+
"slim"
|
25
15
|
end
|
26
16
|
|
27
|
-
def
|
28
|
-
|
17
|
+
def copy_view_file
|
18
|
+
super
|
29
19
|
end
|
30
20
|
end
|
31
21
|
end
|
data/lib/view_component.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
|
2
3
|
require "action_view"
|
3
4
|
require "active_support/dependencies/autoload"
|
4
5
|
|
@@ -8,6 +9,7 @@ module ViewComponent
|
|
8
9
|
autoload :Base
|
9
10
|
autoload :Compiler
|
10
11
|
autoload :ComponentError
|
12
|
+
autoload :Instrumentation
|
11
13
|
autoload :Preview
|
12
14
|
autoload :PreviewTemplateError
|
13
15
|
autoload :TestHelpers
|
data/lib/view_component/base.rb
CHANGED
@@ -4,6 +4,7 @@ require "action_view"
|
|
4
4
|
require "active_support/configurable"
|
5
5
|
require "view_component/collection"
|
6
6
|
require "view_component/compile_cache"
|
7
|
+
require "view_component/content_areas"
|
7
8
|
require "view_component/previewable"
|
8
9
|
require "view_component/slotable"
|
9
10
|
require "view_component/slotable_v2"
|
@@ -12,6 +13,7 @@ require "view_component/with_content_helper"
|
|
12
13
|
module ViewComponent
|
13
14
|
class Base < ActionView::Base
|
14
15
|
include ActiveSupport::Configurable
|
16
|
+
include ViewComponent::ContentAreas
|
15
17
|
include ViewComponent::Previewable
|
16
18
|
include ViewComponent::SlotableV2
|
17
19
|
include ViewComponent::WithContentHelper
|
@@ -30,6 +32,7 @@ module ViewComponent
|
|
30
32
|
# Hook for allowing components to do work as part of the compilation process.
|
31
33
|
#
|
32
34
|
# For example, one might compile component-specific assets at this point.
|
35
|
+
# @private TODO: add documentation
|
33
36
|
def self._after_compile
|
34
37
|
# noop
|
35
38
|
end
|
@@ -58,6 +61,7 @@ module ViewComponent
|
|
58
61
|
# returns:
|
59
62
|
# <span title="greeting">Hello, world!</span>
|
60
63
|
#
|
64
|
+
# @private
|
61
65
|
def render_in(view_context, &block)
|
62
66
|
self.class.compile(raise_errors: true)
|
63
67
|
|
@@ -74,22 +78,24 @@ module ViewComponent
|
|
74
78
|
@virtual_path ||= virtual_path
|
75
79
|
|
76
80
|
# For template variants (+phone, +desktop, etc.)
|
77
|
-
@
|
81
|
+
@__vc_variant ||= @lookup_context.variants.first
|
78
82
|
|
79
83
|
# For caching, such as #cache_if
|
80
84
|
@current_template = nil unless defined?(@current_template)
|
81
85
|
old_current_template = @current_template
|
82
86
|
@current_template = self
|
83
87
|
|
84
|
-
|
88
|
+
if block && defined?(@__vc_content_set_by_with_content)
|
89
|
+
raise ArgumentError.new("Block provided after calling `with_content`. Use one or the other.")
|
90
|
+
end
|
85
91
|
|
86
|
-
@
|
87
|
-
@
|
92
|
+
@__vc_content_evaluated = false
|
93
|
+
@__vc_render_in_block = block
|
88
94
|
|
89
95
|
before_render
|
90
96
|
|
91
97
|
if render?
|
92
|
-
render_template_for(@
|
98
|
+
render_template_for(@__vc_variant).to_s + _output_postamble
|
93
99
|
else
|
94
100
|
""
|
95
101
|
end
|
@@ -97,18 +103,36 @@ module ViewComponent
|
|
97
103
|
@current_template = old_current_template
|
98
104
|
end
|
99
105
|
|
106
|
+
# EXPERIMENTAL: Optional content to be returned after the rendered template.
|
107
|
+
#
|
108
|
+
# @return [String]
|
109
|
+
def _output_postamble
|
110
|
+
""
|
111
|
+
end
|
112
|
+
|
113
|
+
# Called before rendering the component. Override to perform operations that depend on having access to the view context, such as helpers.
|
114
|
+
#
|
115
|
+
# @return [void]
|
100
116
|
def before_render
|
101
117
|
before_render_check
|
102
118
|
end
|
103
119
|
|
120
|
+
# Called after rendering the component.
|
121
|
+
#
|
122
|
+
# @deprecated Use `#before_render` instead. Will be removed in v3.0.0.
|
123
|
+
# @return [void]
|
104
124
|
def before_render_check
|
105
125
|
# noop
|
106
126
|
end
|
107
127
|
|
128
|
+
# Override to determine whether the ViewComponent should render.
|
129
|
+
#
|
130
|
+
# @return [Boolean]
|
108
131
|
def render?
|
109
132
|
true
|
110
133
|
end
|
111
134
|
|
135
|
+
# @private
|
112
136
|
def initialize(*); end
|
113
137
|
|
114
138
|
# Re-use original view_context if we're not rendering a component.
|
@@ -116,6 +140,8 @@ module ViewComponent
|
|
116
140
|
# This prevents an exception when rendering a partial inside of a component that has also been rendered outside
|
117
141
|
# of the component. This is due to the partials compiled template method existing in the parent `view_context`,
|
118
142
|
# and not the component's `view_context`.
|
143
|
+
#
|
144
|
+
# @private
|
119
145
|
def render(options = {}, args = {}, &block)
|
120
146
|
if options.is_a? ViewComponent::Base
|
121
147
|
super
|
@@ -124,60 +150,62 @@ module ViewComponent
|
|
124
150
|
end
|
125
151
|
end
|
126
152
|
|
153
|
+
# The current controller. Use sparingly as doing so introduces coupling that inhibits encapsulation & reuse, often making testing difficult.
|
154
|
+
#
|
155
|
+
# @return [ActionController::Base]
|
127
156
|
def controller
|
128
157
|
raise ViewContextCalledBeforeRenderError, "`controller` can only be called at render time." if view_context.nil?
|
129
|
-
|
158
|
+
|
159
|
+
@__vc_controller ||= view_context.controller
|
130
160
|
end
|
131
161
|
|
132
|
-
#
|
162
|
+
# A proxy through which to access helpers. Use sparingly as doing so introduces coupling that inhibits encapsulation & reuse, often making testing difficult.
|
163
|
+
#
|
164
|
+
# @return [ActionView::Base]
|
133
165
|
def helpers
|
134
166
|
raise ViewContextCalledBeforeRenderError, "`helpers` can only be called at render time." if view_context.nil?
|
135
|
-
|
167
|
+
|
168
|
+
@__vc_helpers ||= controller.view_context
|
136
169
|
end
|
137
170
|
|
138
171
|
# Exposes .virtual_path as an instance method
|
172
|
+
#
|
173
|
+
# @private
|
139
174
|
def virtual_path
|
140
175
|
self.class.virtual_path
|
141
176
|
end
|
142
177
|
|
143
178
|
# For caching, such as #cache_if
|
179
|
+
# @private
|
144
180
|
def view_cache_dependencies
|
145
181
|
[]
|
146
182
|
end
|
147
183
|
|
148
184
|
# For caching, such as #cache_if
|
185
|
+
#
|
186
|
+
# @private
|
149
187
|
def format
|
150
188
|
# Ruby 2.6 throws a warning without checking `defined?`, 2.7 does not
|
151
|
-
if defined?(@
|
152
|
-
@
|
153
|
-
end
|
154
|
-
end
|
155
|
-
|
156
|
-
# Assign the provided content to the content area accessor
|
157
|
-
def with(area, content = nil, &block)
|
158
|
-
unless content_areas.include?(area)
|
159
|
-
raise ArgumentError.new "Unknown content_area '#{area}' - expected one of '#{content_areas}'"
|
160
|
-
end
|
161
|
-
|
162
|
-
if block_given?
|
163
|
-
content = view_context.capture(&block)
|
189
|
+
if defined?(@__vc_variant)
|
190
|
+
@__vc_variant
|
164
191
|
end
|
165
|
-
|
166
|
-
instance_variable_set("@#{area}".to_sym, content)
|
167
|
-
nil
|
168
192
|
end
|
169
193
|
|
194
|
+
# Use the provided variant instead of the one determined by the current request.
|
195
|
+
#
|
196
|
+
# @param variant [Symbol] The variant to be used by the component.
|
197
|
+
# @return [self]
|
170
198
|
def with_variant(variant)
|
171
|
-
@
|
199
|
+
@__vc_variant = variant
|
172
200
|
|
173
201
|
self
|
174
202
|
end
|
175
203
|
|
176
|
-
#
|
177
|
-
#
|
178
|
-
#
|
204
|
+
# The current request. Use sparingly as doing so introduces coupling that inhibits encapsulation & reuse, often making testing difficult.
|
205
|
+
#
|
206
|
+
# @return [ActionDispatch::Request]
|
179
207
|
def request
|
180
|
-
@request ||= controller.request
|
208
|
+
@request ||= controller.request if controller.respond_to?(:request)
|
181
209
|
end
|
182
210
|
|
183
211
|
private
|
@@ -185,31 +213,54 @@ module ViewComponent
|
|
185
213
|
attr_reader :view_context
|
186
214
|
|
187
215
|
def content
|
188
|
-
|
189
|
-
@
|
190
|
-
|
191
|
-
@
|
192
|
-
view_context
|
193
|
-
|
194
|
-
@
|
195
|
-
|
216
|
+
@__vc_content_evaluated = true
|
217
|
+
return @__vc_content if defined?(@__vc_content)
|
218
|
+
|
219
|
+
@__vc_content =
|
220
|
+
if @view_context && @__vc_render_in_block
|
221
|
+
view_context.capture(self, &@__vc_render_in_block)
|
222
|
+
elsif defined?(@__vc_content_set_by_with_content)
|
223
|
+
@__vc_content_set_by_with_content
|
224
|
+
end
|
196
225
|
end
|
197
226
|
|
198
227
|
def content_evaluated?
|
199
|
-
@
|
228
|
+
@__vc_content_evaluated
|
200
229
|
end
|
201
230
|
|
202
|
-
#
|
203
|
-
#
|
204
|
-
#
|
205
|
-
#
|
231
|
+
# Set the controller used for testing components:
|
232
|
+
#
|
233
|
+
# config.view_component.test_controller = "MyTestController"
|
234
|
+
#
|
235
|
+
# Defaults to ApplicationController. Can also be configured on a per-test
|
236
|
+
# basis using `with_controller_class`.
|
237
|
+
#
|
206
238
|
mattr_accessor :test_controller
|
207
239
|
@@test_controller = "ApplicationController"
|
208
240
|
|
209
|
-
#
|
241
|
+
# Set if render monkey patches should be included or not in Rails <6.1:
|
242
|
+
#
|
243
|
+
# config.view_component.render_monkey_patch_enabled = false
|
244
|
+
#
|
210
245
|
mattr_accessor :render_monkey_patch_enabled, instance_writer: false, default: true
|
211
246
|
|
247
|
+
# Enable or disable source code previews in component previews:
|
248
|
+
#
|
249
|
+
# config.view_component.show_previews_source = true
|
250
|
+
#
|
251
|
+
# Defaults to `false`.
|
252
|
+
#
|
253
|
+
mattr_accessor :show_previews_source, instance_writer: false, default: false
|
254
|
+
|
255
|
+
# Path for component files
|
256
|
+
#
|
257
|
+
# config.view_component.view_component_path = "app/my_components"
|
258
|
+
#
|
259
|
+
# Defaults to "app/components".
|
260
|
+
mattr_accessor :view_component_path, instance_writer: false, default: "app/components"
|
261
|
+
|
212
262
|
class << self
|
263
|
+
# @private
|
213
264
|
attr_accessor :source_location, :virtual_path
|
214
265
|
|
215
266
|
# EXPERIMENTAL: This API is experimental and may be removed at any time.
|
@@ -219,6 +270,7 @@ module ViewComponent
|
|
219
270
|
# strings starting without the "dot", example: `["erb", "haml"]`.
|
220
271
|
#
|
221
272
|
# For example, one might collect sidecar CSS files that need to be compiled.
|
273
|
+
# @private TODO: add documentation
|
222
274
|
def _sidecar_files(extensions)
|
223
275
|
return [] unless source_location
|
224
276
|
|
@@ -239,11 +291,12 @@ module ViewComponent
|
|
239
291
|
# end
|
240
292
|
#
|
241
293
|
# Without this, `MyOtherComponent` will not look for `my_component/my_other_component.html.erb`
|
242
|
-
nested_component_files =
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
294
|
+
nested_component_files =
|
295
|
+
if name.include?("::") && component_name != filename
|
296
|
+
Dir["#{directory}/#{filename}/#{component_name}.*{#{extensions}}"]
|
297
|
+
else
|
298
|
+
[]
|
299
|
+
end
|
247
300
|
|
248
301
|
# view files in the same directory as the component
|
249
302
|
sidecar_files = Dir["#{directory}/#{component_name}.*{#{extensions}}"]
|
@@ -253,16 +306,24 @@ module ViewComponent
|
|
253
306
|
(sidecar_files - [source_location] + sidecar_directory_files + nested_component_files).uniq
|
254
307
|
end
|
255
308
|
|
256
|
-
# Render a component collection
|
309
|
+
# Render a component for each element in a collection ([documentation](/guide/collections)):
|
310
|
+
#
|
311
|
+
# render(ProductsComponent.with_collection(@products, foo: :bar))
|
312
|
+
#
|
313
|
+
# @param collection [Enumerable] A list of items to pass the ViewComponent one at a time.
|
314
|
+
# @param args [Arguments] Arguments to pass to the ViewComponent every time.
|
257
315
|
def with_collection(collection, **args)
|
258
316
|
Collection.new(self, collection, **args)
|
259
317
|
end
|
260
318
|
|
261
319
|
# Provide identifier for ActionView template annotations
|
320
|
+
#
|
321
|
+
# @private
|
262
322
|
def short_identifier
|
263
323
|
@short_identifier ||= defined?(Rails.root) ? source_location.sub("#{Rails.root}/", "") : source_location
|
264
324
|
end
|
265
325
|
|
326
|
+
# @private
|
266
327
|
def inherited(child)
|
267
328
|
# Compile so child will inherit compiled `call_*` template methods that
|
268
329
|
# `compile` defines
|
@@ -280,11 +341,14 @@ module ViewComponent
|
|
280
341
|
child.source_location = caller_locations(1, 10).reject { |l| l.label == "inherited" }[0].absolute_path
|
281
342
|
|
282
343
|
# Removes the first part of the path and the extension.
|
283
|
-
child.virtual_path = child.source_location.gsub(
|
344
|
+
child.virtual_path = child.source_location.gsub(
|
345
|
+
%r{(.*#{Regexp.quote(ViewComponent::Base.view_component_path)})|(\.rb)}, ""
|
346
|
+
)
|
284
347
|
|
285
348
|
super
|
286
349
|
end
|
287
350
|
|
351
|
+
# @private
|
288
352
|
def compiled?
|
289
353
|
compiler.compiled?
|
290
354
|
end
|
@@ -293,50 +357,39 @@ module ViewComponent
|
|
293
357
|
#
|
294
358
|
# Do as much work as possible in this step, as doing so reduces the amount
|
295
359
|
# of work done each time a component is rendered.
|
360
|
+
# @private
|
296
361
|
def compile(raise_errors: false)
|
297
362
|
compiler.compile(raise_errors: raise_errors)
|
298
363
|
end
|
299
364
|
|
365
|
+
# @private
|
300
366
|
def compiler
|
301
|
-
@
|
367
|
+
@__vc_compiler ||= Compiler.new(self)
|
302
368
|
end
|
303
369
|
|
304
370
|
# we'll eventually want to update this to support other types
|
371
|
+
# @private
|
305
372
|
def type
|
306
373
|
"text/html"
|
307
374
|
end
|
308
375
|
|
376
|
+
# @private
|
309
377
|
def format
|
310
378
|
:html
|
311
379
|
end
|
312
380
|
|
381
|
+
# @private
|
313
382
|
def identifier
|
314
383
|
source_location
|
315
384
|
end
|
316
385
|
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
raise ArgumentError.new ":content is a reserved content area name. Please use another name, such as ':body'"
|
325
|
-
end
|
326
|
-
|
327
|
-
areas.each do |area|
|
328
|
-
define_method area.to_sym do
|
329
|
-
content unless content_evaluated? # ensure content is loaded so content_areas will be defined
|
330
|
-
instance_variable_get(:"@#{area}") if instance_variable_defined?(:"@#{area}")
|
331
|
-
end
|
332
|
-
end
|
333
|
-
|
334
|
-
self.content_areas = areas
|
335
|
-
end
|
336
|
-
|
337
|
-
# Support overriding collection parameter name
|
338
|
-
def with_collection_parameter(param)
|
339
|
-
@provided_collection_parameter = param
|
386
|
+
# Set the parameter name used when rendering elements of a collection ([documentation](/guide/collections)):
|
387
|
+
#
|
388
|
+
# with_collection_parameter :item
|
389
|
+
#
|
390
|
+
# @param parameter [Symbol] The parameter name used when rendering elements of a collection.
|
391
|
+
def with_collection_parameter(parameter)
|
392
|
+
@provided_collection_parameter = parameter
|
340
393
|
end
|
341
394
|
|
342
395
|
# Ensure the component initializer accepts the
|
@@ -344,6 +397,7 @@ module ViewComponent
|
|
344
397
|
# validate that the default parameter name
|
345
398
|
# is accepted, as support for collection
|
346
399
|
# rendering is optional.
|
400
|
+
# @private TODO: add documentation
|
347
401
|
def validate_collection_parameter!(validate_default: false)
|
348
402
|
parameter = validate_default ? collection_parameter : provided_collection_parameter
|
349
403
|
|
@@ -368,6 +422,7 @@ module ViewComponent
|
|
368
422
|
# Ensure the component initializer does not define
|
369
423
|
# invalid parameters that could override the framework's
|
370
424
|
# methods.
|
425
|
+
# @private TODO: add documentation
|
371
426
|
def validate_initialization_parameters!
|
372
427
|
return unless initialize_parameter_names.include?(RESERVED_PARAMETER)
|
373
428
|
|
@@ -378,6 +433,7 @@ module ViewComponent
|
|
378
433
|
)
|
379
434
|
end
|
380
435
|
|
436
|
+
# @private
|
381
437
|
def collection_parameter
|
382
438
|
if provided_collection_parameter
|
383
439
|
provided_collection_parameter
|
@@ -386,14 +442,26 @@ module ViewComponent
|
|
386
442
|
end
|
387
443
|
end
|
388
444
|
|
445
|
+
# @private
|
389
446
|
def collection_counter_parameter
|
390
447
|
"#{collection_parameter}_counter".to_sym
|
391
448
|
end
|
392
449
|
|
450
|
+
# @private
|
393
451
|
def counter_argument_present?
|
394
452
|
initialize_parameter_names.include?(collection_counter_parameter)
|
395
453
|
end
|
396
454
|
|
455
|
+
# @private
|
456
|
+
def collection_iteration_parameter
|
457
|
+
"#{collection_parameter}_iteration".to_sym
|
458
|
+
end
|
459
|
+
|
460
|
+
# @private
|
461
|
+
def iteration_argument_present?
|
462
|
+
initialize_parameter_names.include?(collection_iteration_parameter)
|
463
|
+
end
|
464
|
+
|
397
465
|
private
|
398
466
|
|
399
467
|
def initialize_parameter_names
|