view_component 3.23.2 → 4.0.0.alpha1

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.
Files changed (60) hide show
  1. checksums.yaml +4 -4
  2. data/app/controllers/concerns/view_component/preview_actions.rb +2 -9
  3. data/app/controllers/view_components_system_test_controller.rb +17 -20
  4. data/app/views/test_mailer/test_asset_email.html.erb +1 -0
  5. data/app/views/view_components/preview.html.erb +1 -9
  6. data/docs/CHANGELOG.md +93 -9
  7. data/lib/view_component/base.rb +43 -66
  8. data/lib/view_component/collection.rb +11 -17
  9. data/lib/view_component/compiler.rb +50 -74
  10. data/lib/view_component/config.rb +0 -21
  11. data/lib/view_component/deprecation.rb +1 -1
  12. data/lib/view_component/engine.rb +3 -82
  13. data/lib/view_component/errors.rb +16 -22
  14. data/lib/view_component/inline_template.rb +2 -3
  15. data/lib/view_component/instrumentation.rb +4 -10
  16. data/lib/view_component/preview.rb +3 -10
  17. data/lib/view_component/request_details.rb +30 -0
  18. data/lib/view_component/slot.rb +2 -5
  19. data/lib/view_component/slotable.rb +30 -37
  20. data/lib/view_component/system_test_helpers.rb +1 -2
  21. data/lib/view_component/template.rb +106 -83
  22. data/lib/view_component/test_helpers.rb +22 -42
  23. data/lib/view_component/translatable.rb +24 -23
  24. data/lib/view_component/use_helpers.rb +3 -4
  25. data/lib/view_component/version.rb +4 -4
  26. data/lib/view_component.rb +0 -1
  27. metadata +68 -211
  28. data/app/assets/vendor/prism.css +0 -4
  29. data/app/assets/vendor/prism.min.js +0 -12
  30. data/app/helpers/preview_helper.rb +0 -85
  31. data/app/views/view_components/_preview_source.html.erb +0 -17
  32. data/lib/rails/generators/abstract_generator.rb +0 -56
  33. data/lib/rails/generators/component/component_generator.rb +0 -67
  34. data/lib/rails/generators/component/templates/component.rb.tt +0 -16
  35. data/lib/rails/generators/erb/component_generator.rb +0 -33
  36. data/lib/rails/generators/erb/templates/component.html.erb.tt +0 -1
  37. data/lib/rails/generators/haml/component_generator.rb +0 -22
  38. data/lib/rails/generators/haml/templates/component.html.haml.tt +0 -1
  39. data/lib/rails/generators/locale/component_generator.rb +0 -46
  40. data/lib/rails/generators/preview/component_generator.rb +0 -39
  41. data/lib/rails/generators/preview/templates/component_preview.rb.tt +0 -9
  42. data/lib/rails/generators/rspec/component_generator.rb +0 -31
  43. data/lib/rails/generators/rspec/templates/component_spec.rb.tt +0 -15
  44. data/lib/rails/generators/slim/component_generator.rb +0 -22
  45. data/lib/rails/generators/slim/templates/component.html.slim.tt +0 -1
  46. data/lib/rails/generators/stimulus/component_generator.rb +0 -44
  47. data/lib/rails/generators/stimulus/templates/component_controller.js.tt +0 -7
  48. data/lib/rails/generators/stimulus/templates/component_controller.ts.tt +0 -9
  49. data/lib/rails/generators/tailwindcss/component_generator.rb +0 -11
  50. data/lib/rails/generators/tailwindcss/templates/component.html.erb.tt +0 -1
  51. data/lib/rails/generators/test_unit/component_generator.rb +0 -20
  52. data/lib/rails/generators/test_unit/templates/component_test.rb.tt +0 -12
  53. data/lib/view_component/component_error.rb +0 -6
  54. data/lib/view_component/rails/tasks/view_component.rake +0 -20
  55. data/lib/view_component/render_component_helper.rb +0 -10
  56. data/lib/view_component/render_component_to_string_helper.rb +0 -9
  57. data/lib/view_component/render_monkey_patch.rb +0 -13
  58. data/lib/view_component/render_to_string_monkey_patch.rb +0 -13
  59. data/lib/view_component/rendering_component_helper.rb +0 -9
  60. data/lib/view_component/rendering_monkey_patch.rb +0 -13
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 79672f93bd1c3bfa2dae00890f833c5dfb63dec49585dd79453f6592f9f47520
4
- data.tar.gz: e6fe55dfe963ce0e7f4d793c93b67aefa92c99ee834c17c35644a9ea8b746886
3
+ metadata.gz: e8c0d5be4a21f5c14ed5447caeaffb8d6e51397a1ec786f573bc58d9486fc747
4
+ data.tar.gz: 332de180e52e1b5eae806fb47e9d1dea4a32374cdf63a0642ca69d3661e4c802
5
5
  SHA512:
6
- metadata.gz: 311478a282f72c7b703594ec119dfc2686ec8cd3c6d6e97ff9fab9a32638e09eacefdc82a3808c581e48ab2af4cbfb26f66c7064cb614367cb4916fdf3b7df76
7
- data.tar.gz: 3c059cb40bfa81c45a60bc9d107be8402923f92f0a8e1b50c6cdfcad88a4da6407244f1e5220d58f59a938c3d77e748ec22f360b8cf49041279616138ac4397d
6
+ metadata.gz: e298e8e18d147034b30fb60f32a7bbf5d5f42d1235d5947cfeba4e3e1b8ad65a57379f3a3fb361ba7ffdec727687689ceb98b4b893e038a16ea5496663d4423a
7
+ data.tar.gz: f6e8f8956abde8eac1e4825c09a2554dde1dd80efac74ba541210e2fe663e23399ddc01289ca44dee21e6c3551b32117b88444d9795fbb450b02639ebc9fadbf
@@ -10,18 +10,11 @@ module ViewComponent
10
10
  around_action :set_locale, only: :previews
11
11
  before_action :require_local!, unless: :show_previews?
12
12
 
13
- content_security_policy(false) if respond_to?(:content_security_policy)
13
+ content_security_policy(false)
14
14
 
15
15
  # Including helpers here ensures that we're loading the
16
16
  # latest version of helpers if code-reloading is enabled
17
- if include_all_helpers
18
- helper :all
19
- else
20
- # :nocov:
21
- # Always provide the #view_source helper
22
- helper PreviewHelper
23
- # :nocov:
24
- end
17
+ helper :all if include_all_helpers
25
18
  end
26
19
 
27
20
  def index
@@ -1,30 +1,27 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class ViewComponentsSystemTestController < ActionController::Base # :nodoc:
4
- before_action :validate_test_env
5
- before_action :validate_file_path
4
+ if Rails.env.test?
5
+ before_action :validate_file_path
6
6
 
7
- def self.temp_dir
8
- @_tmpdir ||= FileUtils.mkdir_p("./tmp/view_components/").first
9
- end
10
-
11
- def system_test_entrypoint
12
- render file: @path
13
- end
7
+ def self.temp_dir
8
+ @_tmpdir ||= FileUtils.mkdir_p("./tmp/view_components/").first
9
+ end
14
10
 
15
- private
11
+ def system_test_entrypoint
12
+ render file: @path
13
+ end
16
14
 
17
- def validate_test_env
18
- raise ViewComponent::SystemTestControllerOnlyAllowedInTestError unless Rails.env.test?
19
- end
15
+ private
20
16
 
21
- # Ensure that the file path is valid and doesn't target files outside
22
- # the expected directory (e.g. via a path traversal or symlink attack)
23
- def validate_file_path
24
- base_path = ::File.realpath(self.class.temp_dir)
25
- @path = ::File.realpath(params.permit(:file)[:file], base_path)
26
- unless @path.start_with?(base_path)
27
- raise ViewComponent::SystemTestControllerNefariousPathError
17
+ # Ensure that the file path is valid and doesn't target files outside
18
+ # the expected directory (e.g. via a path traversal or symlink attack)
19
+ def validate_file_path
20
+ base_path = ::File.realpath(self.class.temp_dir)
21
+ @path = ::File.realpath(params.permit(:file)[:file], base_path)
22
+ unless @path.start_with?(base_path)
23
+ raise ViewComponent::SystemTestControllerNefariousPathError
24
+ end
28
25
  end
29
26
  end
30
27
  end
@@ -0,0 +1 @@
1
+ <%= render AssetComponent.new %>
@@ -1,13 +1,5 @@
1
1
  <% if @render_args[:component] %>
2
- <% if ViewComponent::Base.config.render_monkey_patch_enabled || Rails.version.to_f >= 6.1 %>
3
- <%= render(@render_args[:component], @render_args[:args], &@render_args[:block]) %>
4
- <% else %>
5
- <%= render_component(@render_args[:component], &@render_args[:block]) %>
6
- <% end %>
2
+ <%= render(@render_args[:component], @render_args[:args], &@render_args[:block]) %>
7
3
  <% else %>
8
4
  <%= render template: @render_args[:template], locals: @render_args[:locals] || {} %>
9
5
  <% end %>
10
-
11
- <% if ViewComponent::Base.config.show_previews_source %>
12
- <%= preview_source %>
13
- <% end %>
data/docs/CHANGELOG.md CHANGED
@@ -10,23 +10,107 @@ nav_order: 6
10
10
 
11
11
  ## main
12
12
 
13
- ## 3.23.2
13
+ ## 4.0.0
14
14
 
15
- * Include .tt files in published gem. Fixes templates not being available when using generators.
15
+ Almost six years after releasing [v1.0.0](https://github.com/ViewComponent/view_component/releases/tag/v1.0.0), we're proud to ship ViewComponent 4. This release marks a shift towards a Long Term Support model for the project, having reached significant feature maturity. While contributions are always welcome, we're unlikely to accept further breaking changes or major feature additions.
16
16
 
17
- *Florian Aßmann*
17
+ This release makes the following breaking changes:
18
18
 
19
- ## 3.23.1
19
+ * BREAKING: `--inline` generator option now generates inline template. Use `--call` to generate `#call` method.
20
20
 
21
- * Restore Rake tasks in published gem.
21
+ *Joel Hawksley*
22
22
 
23
- *Franz Liedke*
23
+ * BREAKING: Remove `use_deprecated_instrumentation_name` configuration option. Events will always use `render.view_component` name.
24
+
25
+ *Joel Hawksley*
26
+
27
+ * BREAKING: Remove `preview_source` functionality. Consider using [Lookbook](https://lookbook.build/) instead.
28
+
29
+ *Joel Hawksley*
30
+
31
+ * BREAKING: Use `Nokogiri::HTML5` instead of `Nokogiri::HTML4` for test helpers.
32
+
33
+ *Noah Silvera*, *Joel Hawksley*
34
+
35
+ * BREAKING: Move generators to a ViewComponent namespace.
36
+
37
+ Before, ViewComponent generators pollute the generator namespace with a bunch of top level items, and claim the generic "component" name.
38
+
39
+ Now, generators live in a "view_component" module/namespace, so what was before `rails g
40
+ component` is now `rails g view_component:component`.
41
+
42
+ *Paul Sadauskas*
43
+
44
+ * BREAKING: Require [non-EOL](https://endoflife.date/rails) Rails (`>= 7.1.0`).
45
+
46
+ *Joel Hawksley*
47
+
48
+ * BREAKING: Require [non-EOL](https://www.ruby-lang.org/en/downloads/branches/) Ruby (`>= 3.2.0`).
49
+
50
+ *Joel Hawksley*
51
+
52
+ * BREAKING: Remove `render_component` and `render` monkey patch configured with `render_monkey_patch_enabled`.
53
+
54
+ *Joel Hawksley*
55
+
56
+ * BREAKING: Remove support for variant names containing `.` to be consistent with Rails.
57
+
58
+ *Stephen Nelson*
59
+
60
+ * BREAKING: Use ActionView's `lookup_context` for picking templates instead of the request format.
61
+
62
+ 3.15 added support for using templates that match the request format, i.e. if `/resource.csv` is requested then
63
+ ViewComponents would pick `_component.csv.erb` over `_component.html.erb`.
64
+
65
+ With this release, the request format is no longer considered and instead ViewComponent will use the Rails logic
66
+ for picking the most appropriate template type, i.e. the csv template will be used if it matches the `Accept` header
67
+ or because the controller uses a `respond_to` block to pick the response format.
68
+
69
+ *Stephen Nelson*
24
70
 
25
- ## 3.23.0
71
+ * BREAKING: Rename internal methods to have `__vc_` prefix if they shouldn't be used by consumers. Make internal constants private. Make `Collection#components`, `Slotable#register_polymorphic_slot` private. Remove unused `ComponentError` class.
72
+
73
+ *Joel Hawksley*
74
+
75
+ * Fix bug where request-aware helpers did not work outside of the request context.
76
+
77
+ *Joel Hawksley*, *Stephen Nelson*
78
+
79
+ * `ViewComponentsSystemTestController` should not be useable outside of test environment
80
+
81
+ *Joel Hawksley*, *Stephen Nelson*
82
+
83
+ * Remove unnecessary ENABLE_RELOADING test suite flag.
84
+
85
+ *Joel Hawksley*
86
+
87
+ * Add test coverage for uncovered code.
88
+
89
+ *Joel Hawksley*
90
+
91
+ * Remove unnecessary `#format` methods that returned `nil`.
92
+
93
+ *Joel Hawksley*
94
+
95
+ * Clean up project dependencies, relaxing versions of development gems.
96
+
97
+ *Joel Hawksley*
98
+
99
+ * Test against `turbo-rails` `v2`.
100
+
101
+ *Joel Hawksley*
102
+
103
+ * Test against `rspec-rails` `v7`.
104
+
105
+ *Joel Hawksley*
106
+
107
+ * Remove unnecessary usage of `ruby2_keywords`.
108
+
109
+ *Joel Hawksley*
26
110
 
27
- * Add docs about Slack channel in Ruby Central workspace. (Join us! #oss-view-component). Email joelhawksley@github.com for an invite.
111
+ * Remove unnecessary `respond_to` checks.
28
112
 
29
- *Joel Hawksley
113
+ *Tiago Menegaz*, *Joel Hawksley*
30
114
 
31
115
  * Do not include internal `DocsBuilderComponent` or `YARD::MattrAccessorHandler` in published gem.
32
116
 
@@ -9,6 +9,7 @@ require "view_component/config"
9
9
  require "view_component/errors"
10
10
  require "view_component/inline_template"
11
11
  require "view_component/preview"
12
+ require "view_component/request_details"
12
13
  require "view_component/slotable"
13
14
  require "view_component/slotable_default"
14
15
  require "view_component/template"
@@ -25,10 +26,9 @@ module ViewComponent
25
26
  #
26
27
  # @return [ActiveSupport::OrderedOptions]
27
28
  def config
28
- module_parents.each do |module_parent|
29
- next unless module_parent.respond_to?(:config)
30
- module_parent_config = module_parent.config.try(:view_component)
31
- return module_parent_config if module_parent_config
29
+ module_parents.each do |m|
30
+ config = m.try(:config).try(:view_component)
31
+ return config if config
32
32
  end
33
33
  ViewComponent::Config.current
34
34
  end
@@ -40,9 +40,6 @@ module ViewComponent
40
40
  include ViewComponent::Translatable
41
41
  include ViewComponent::WithContentHelper
42
42
 
43
- RESERVED_PARAMETER = :content
44
- VC_INTERNAL_DEFAULT_FORMAT = :html
45
-
46
43
  # For CSRF authenticity tokens in forms
47
44
  delegate :form_authenticity_token, :protect_against_forgery?, :config, to: :helpers
48
45
 
@@ -50,8 +47,7 @@ module ViewComponent
50
47
  delegate :content_security_policy_nonce, to: :helpers
51
48
 
52
49
  # Config option that strips trailing whitespace in templates before compiling them.
53
- class_attribute :__vc_strip_trailing_whitespace, instance_accessor: false, instance_predicate: false
54
- self.__vc_strip_trailing_whitespace = false # class_attribute:default doesn't work until Rails 5.2
50
+ class_attribute :__vc_strip_trailing_whitespace, instance_accessor: false, instance_predicate: false, default: false
55
51
 
56
52
  attr_accessor :__vc_original_view_context
57
53
 
@@ -68,6 +64,8 @@ module ViewComponent
68
64
  self.__vc_original_view_context = view_context
69
65
  end
70
66
 
67
+ using RequestDetails
68
+
71
69
  # Entrypoint for rendering components.
72
70
  #
73
71
  # - `view_context`: ActionView context from calling view
@@ -77,7 +75,7 @@ module ViewComponent
77
75
  #
78
76
  # @return [String]
79
77
  def render_in(view_context, &block)
80
- self.class.compile(raise_errors: true)
78
+ self.class.__vc_compile(raise_errors: true)
81
79
 
82
80
  @view_context = view_context
83
81
  self.__vc_original_view_context ||= view_context
@@ -86,22 +84,18 @@ module ViewComponent
86
84
 
87
85
  @lookup_context ||= view_context.lookup_context
88
86
 
89
- # required for path helpers in older Rails versions
90
- @view_renderer ||= view_context.view_renderer
91
-
92
87
  # For content_for
93
88
  @view_flow ||= view_context.view_flow
94
89
 
95
90
  # For i18n
96
91
  @virtual_path ||= virtual_path
97
92
 
98
- # For template variants (+phone, +desktop, etc.)
99
- @__vc_variant ||= @lookup_context.variants.first
93
+ # Describes the inferred request constraints (locales, formats, variants)
94
+ @__vc_requested_details ||= @lookup_context.vc_requested_details
100
95
 
101
96
  # For caching, such as #cache_if
102
97
  @current_template = nil unless defined?(@current_template)
103
98
  old_current_template = @current_template
104
- @current_template = self
105
99
 
106
100
  if block && defined?(@__vc_content_set_by_with_content)
107
101
  raise DuplicateContentError.new(self.class.name)
@@ -113,7 +107,7 @@ module ViewComponent
113
107
  before_render
114
108
 
115
109
  if render?
116
- rendered_template = render_template_for(@__vc_variant, __vc_request&.format&.to_sym).to_s
110
+ rendered_template = render_template_for(@__vc_requested_details).to_s
117
111
 
118
112
  # Avoid allocating new string when output_preamble and output_postamble are blank
119
113
  if output_preamble.blank? && output_postamble.blank?
@@ -161,7 +155,7 @@ module ViewComponent
161
155
  target_render = self.class.instance_variable_get(:@__vc_ancestor_calls)[@__vc_parent_render_level]
162
156
  @__vc_parent_render_level += 1
163
157
 
164
- target_render.bind_call(self, @__vc_variant)
158
+ target_render.bind_call(self, @__vc_requested_details)
165
159
  ensure
166
160
  @__vc_parent_render_level -= 1
167
161
  end
@@ -206,7 +200,7 @@ module ViewComponent
206
200
  #
207
201
  # This prevents an exception when rendering a partial inside of a component that has also been rendered outside
208
202
  # of the component. This is due to the partials compiled template method existing in the parent `view_context`,
209
- # and not the component's `view_context`.
203
+ # and not the component's `view_context`.
210
204
  #
211
205
  # @private
212
206
  def render(options = {}, args = {}, &block)
@@ -254,7 +248,7 @@ module ViewComponent
254
248
  raise e, <<~MESSAGE.chomp if view_context && e.is_a?(NameError) && helpers.respond_to?(method_name)
255
249
  #{e.message}
256
250
 
257
- You may be trying to call a method provided as a view helper. Did you mean `helpers.#{method_name}`?
251
+ You may be trying to call a method provided as a view helper. Did you mean `helpers.#{method_name}'?
258
252
  MESSAGE
259
253
 
260
254
  raise
@@ -274,13 +268,6 @@ module ViewComponent
274
268
  []
275
269
  end
276
270
 
277
- # For caching, such as #cache_if
278
- #
279
- # @private
280
- def format
281
- @__vc_variant if defined?(@__vc_variant)
282
- end
283
-
284
271
  # The current request. Use sparingly as doing so introduces coupling that
285
272
  # inhibits encapsulation & reuse, often making testing difficult.
286
273
  #
@@ -289,10 +276,9 @@ module ViewComponent
289
276
  __vc_request
290
277
  end
291
278
 
292
- # Enables consumers to override request/@request
293
- #
294
279
  # @private
295
280
  def __vc_request
281
+ # The current request (if present, as mailers/jobs/etc do not have a request)
296
282
  @__vc_request ||= controller.request if controller.respond_to?(:request)
297
283
  end
298
284
 
@@ -335,7 +321,7 @@ module ViewComponent
335
321
  end
336
322
 
337
323
  def maybe_escape_html(text)
338
- return text if __vc_request && !__vc_request.format.html?
324
+ return text if @current_template && !@current_template.html?
339
325
  return text if text.blank?
340
326
 
341
327
  if text.html_safe?
@@ -368,13 +354,6 @@ module ViewComponent
368
354
  # configured on a per-test basis using `with_controller_class`.
369
355
  #
370
356
 
371
- # Set if render monkey patches should be included or not in Rails <6.1:
372
- #
373
- # ```ruby
374
- # config.view_component.render_monkey_patch_enabled = false
375
- # ```
376
- #
377
-
378
357
  # Path for component files
379
358
  #
380
359
  # ```ruby
@@ -523,20 +502,20 @@ module ViewComponent
523
502
  def inherited(child)
524
503
  # Compile so child will inherit compiled `call_*` template methods that
525
504
  # `compile` defines
526
- compile
505
+ __vc_compile
527
506
 
528
507
  # Give the child its own personal #render_template_for to protect against the case when
529
508
  # eager loading is disabled and the parent component is rendered before the child. In
530
509
  # such a scenario, the parent will override ViewComponent::Base#render_template_for,
531
510
  # meaning it will not be called for any children and thus not compile their templates.
532
- if !child.instance_methods(false).include?(:render_template_for) && !child.compiled?
511
+ if !child.instance_methods(false).include?(:render_template_for) && !child.__vc_compiled?
533
512
  child.class_eval <<~RUBY, __FILE__, __LINE__ + 1
534
- def render_template_for(variant = nil, format = nil)
513
+ def render_template_for(requested_details)
535
514
  # Force compilation here so the compiler always redefines render_template_for.
536
515
  # This is mostly a safeguard to prevent infinite recursion.
537
- self.class.compile(raise_errors: true, force: true)
538
- # .compile replaces this method; call the new one
539
- render_template_for(variant, format)
516
+ self.class.__vc_compile(raise_errors: true, force: true)
517
+ # .__vc_compile replaces this method; call the new one
518
+ render_template_for(requested_details)
540
519
  end
541
520
  RUBY
542
521
  end
@@ -575,22 +554,22 @@ module ViewComponent
575
554
  end
576
555
 
577
556
  # @private
578
- def compiled?
579
- compiler.compiled?
557
+ def __vc_compiled?
558
+ __vc_compiler.compiled?
580
559
  end
581
560
 
582
561
  # @private
583
- def ensure_compiled
584
- compile unless compiled?
562
+ def __vc_ensure_compiled
563
+ __vc_compile unless __vc_compiled?
585
564
  end
586
565
 
587
566
  # @private
588
- def compile(raise_errors: false, force: false)
589
- compiler.compile(raise_errors: raise_errors, force: force)
567
+ def __vc_compile(raise_errors: false, force: false)
568
+ __vc_compiler.compile(raise_errors: raise_errors, force: force)
590
569
  end
591
570
 
592
571
  # @private
593
- def compiler
572
+ def __vc_compiler
594
573
  @__vc_compiler ||= Compiler.new(self)
595
574
  end
596
575
 
@@ -632,8 +611,8 @@ module ViewComponent
632
611
  # is accepted, as support for collection
633
612
  # rendering is optional.
634
613
  # @private
635
- def validate_collection_parameter!(validate_default: false)
636
- parameter = validate_default ? collection_parameter : provided_collection_parameter
614
+ def __vc_validate_collection_parameter!(validate_default: false)
615
+ parameter = validate_default ? __vc_collection_parameter : provided_collection_parameter
637
616
 
638
617
  return unless parameter
639
618
  return if initialize_parameter_names.include?(parameter) || splatted_keyword_argument_present?
@@ -652,35 +631,35 @@ module ViewComponent
652
631
  # invalid parameters that could override the framework's
653
632
  # methods.
654
633
  # @private
655
- def validate_initialization_parameters!
656
- return unless initialize_parameter_names.include?(RESERVED_PARAMETER)
634
+ def __vc_validate_initialization_parameters!
635
+ return unless initialize_parameter_names.include?(:content)
657
636
 
658
- raise ReservedParameterError.new(name, RESERVED_PARAMETER)
637
+ raise ReservedParameterError.new(name, :content)
659
638
  end
660
639
 
661
640
  # @private
662
- def collection_parameter
641
+ def __vc_collection_parameter
663
642
  provided_collection_parameter || name && name.demodulize.underscore.chomp("_component").to_sym
664
643
  end
665
644
 
666
645
  # @private
667
- def collection_counter_parameter
668
- :"#{collection_parameter}_counter"
646
+ def __vc_collection_counter_parameter
647
+ :"#{__vc_collection_parameter}_counter"
669
648
  end
670
649
 
671
650
  # @private
672
- def counter_argument_present?
673
- initialize_parameter_names.include?(collection_counter_parameter)
651
+ def __vc_counter_argument_present?
652
+ initialize_parameter_names.include?(__vc_collection_counter_parameter)
674
653
  end
675
654
 
676
655
  # @private
677
- def collection_iteration_parameter
678
- :"#{collection_parameter}_iteration"
656
+ def __vc_collection_iteration_parameter
657
+ :"#{__vc_collection_parameter}_iteration"
679
658
  end
680
659
 
681
660
  # @private
682
- def iteration_argument_present?
683
- initialize_parameter_names.include?(collection_iteration_parameter)
661
+ def __vc_iteration_argument_present?
662
+ initialize_parameter_names.include?(__vc_collection_iteration_parameter)
684
663
  end
685
664
 
686
665
  private
@@ -693,8 +672,6 @@ module ViewComponent
693
672
  def initialize_parameter_names
694
673
  return attribute_names.map(&:to_sym) if respond_to?(:attribute_names)
695
674
 
696
- return attribute_types.keys.map(&:to_sym) if Rails::VERSION::MAJOR <= 5 && respond_to?(:attribute_types)
697
-
698
675
  initialize_parameters.map(&:last)
699
676
  end
700
677
 
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "action_view/renderer/collection_renderer" if Rails.version.to_f >= 6.1
3
+ require "action_view/renderer/collection_renderer"
4
4
 
5
5
  module ViewComponent
6
6
  class Collection
@@ -22,12 +22,18 @@ module ViewComponent
22
22
  end.join(rendered_spacer(view_context)).html_safe
23
23
  end
24
24
 
25
+ def each(&block)
26
+ components.each(&block)
27
+ end
28
+
29
+ private
30
+
25
31
  def components
26
32
  return @components if defined? @components
27
33
 
28
34
  iterator = ActionView::PartialIteration.new(@collection.size)
29
35
 
30
- component.validate_collection_parameter!(validate_default: true)
36
+ component.__vc_validate_collection_parameter!(validate_default: true)
31
37
 
32
38
  @components = @collection.map do |item|
33
39
  component.new(**component_options(item, iterator)).tap do |component|
@@ -36,18 +42,6 @@ module ViewComponent
36
42
  end
37
43
  end
38
44
 
39
- def each(&block)
40
- components.each(&block)
41
- end
42
-
43
- # Rails expects us to define `format` on all renderables,
44
- # but we do not know the `format` of a ViewComponent until runtime.
45
- def format
46
- nil
47
- end
48
-
49
- private
50
-
51
45
  def initialize(component, object, spacer_component, **options)
52
46
  @component = component
53
47
  @collection = collection_variable(object || [])
@@ -64,9 +58,9 @@ module ViewComponent
64
58
  end
65
59
 
66
60
  def component_options(item, iterator)
67
- item_options = {component.collection_parameter => item}
68
- item_options[component.collection_counter_parameter] = iterator.index if component.counter_argument_present?
69
- item_options[component.collection_iteration_parameter] = iterator.dup if component.iteration_argument_present?
61
+ item_options = {component.__vc_collection_parameter => item}
62
+ item_options[component.__vc_collection_counter_parameter] = iterator.index if component.__vc_counter_argument_present?
63
+ item_options[component.__vc_collection_iteration_parameter] = iterator.dup if component.__vc_iteration_argument_present?
70
64
 
71
65
  @options.merge(item_options)
72
66
  end