view_component 3.22.0 → 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 (64) 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 +127 -1
  7. data/lib/view_component/base.rb +41 -61
  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 +31 -39
  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 +3 -3
  26. data/lib/view_component.rb +0 -1
  27. metadata +73 -220
  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/USAGE +0 -13
  34. data/lib/rails/generators/component/component_generator.rb +0 -67
  35. data/lib/rails/generators/component/templates/component.rb.tt +0 -16
  36. data/lib/rails/generators/erb/component_generator.rb +0 -33
  37. data/lib/rails/generators/erb/templates/component.html.erb.tt +0 -1
  38. data/lib/rails/generators/haml/component_generator.rb +0 -22
  39. data/lib/rails/generators/haml/templates/component.html.haml.tt +0 -1
  40. data/lib/rails/generators/locale/component_generator.rb +0 -46
  41. data/lib/rails/generators/preview/component_generator.rb +0 -39
  42. data/lib/rails/generators/preview/templates/component_preview.rb.tt +0 -9
  43. data/lib/rails/generators/rspec/component_generator.rb +0 -31
  44. data/lib/rails/generators/rspec/templates/component_spec.rb.tt +0 -15
  45. data/lib/rails/generators/slim/component_generator.rb +0 -22
  46. data/lib/rails/generators/slim/templates/component.html.slim.tt +0 -1
  47. data/lib/rails/generators/stimulus/component_generator.rb +0 -44
  48. data/lib/rails/generators/stimulus/templates/component_controller.js.tt +0 -7
  49. data/lib/rails/generators/stimulus/templates/component_controller.ts.tt +0 -9
  50. data/lib/rails/generators/tailwindcss/component_generator.rb +0 -11
  51. data/lib/rails/generators/tailwindcss/templates/component.html.erb.tt +0 -1
  52. data/lib/rails/generators/test_unit/component_generator.rb +0 -20
  53. data/lib/rails/generators/test_unit/templates/component_test.rb.tt +0 -12
  54. data/lib/view_component/component_error.rb +0 -6
  55. data/lib/view_component/docs_builder_component.html.erb +0 -22
  56. data/lib/view_component/docs_builder_component.rb +0 -96
  57. data/lib/view_component/rails/tasks/view_component.rake +0 -20
  58. data/lib/view_component/render_component_helper.rb +0 -10
  59. data/lib/view_component/render_component_to_string_helper.rb +0 -9
  60. data/lib/view_component/render_monkey_patch.rb +0 -13
  61. data/lib/view_component/render_to_string_monkey_patch.rb +0 -13
  62. data/lib/view_component/rendering_component_helper.rb +0 -9
  63. data/lib/view_component/rendering_monkey_patch.rb +0 -13
  64. data/lib/yard/mattr_accessor_handler.rb +0 -19
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b6afc3fe994c0954654d58d797e36d274013494e6caec61ef1b5535a4a5a4267
4
- data.tar.gz: ae921110a568f5e212b0c2d60cf31bf4ac7628b961a65cde871577f13fddee60
3
+ metadata.gz: e8c0d5be4a21f5c14ed5447caeaffb8d6e51397a1ec786f573bc58d9486fc747
4
+ data.tar.gz: 332de180e52e1b5eae806fb47e9d1dea4a32374cdf63a0642ca69d3661e4c802
5
5
  SHA512:
6
- metadata.gz: 240679c690a13c69669173be5c076271e1a2f0f02dfabfc2bdbfa49c0b03cbd7456e88204c84be3e7b85c703c606270b3c794f47f845d3062c6a9f620fda9da2
7
- data.tar.gz: da6b4298a67311608e1641c5ace24e321e6270fb67921f2bb6f70cce9dedb7f53b2ea8006acb193775ce4d4f6a963338f310d754bc95aac6c793a9b52abddf62
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
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  layout: default
3
3
  title: Changelog
4
- nav_order: 5
4
+ nav_order: 6
5
5
  ---
6
6
 
7
7
  <!-- Add unreleased changes under the "main" heading. -->
@@ -10,6 +10,132 @@ nav_order: 5
10
10
 
11
11
  ## main
12
12
 
13
+ ## 4.0.0
14
+
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
+
17
+ This release makes the following breaking changes:
18
+
19
+ * BREAKING: `--inline` generator option now generates inline template. Use `--call` to generate `#call` method.
20
+
21
+ *Joel Hawksley*
22
+
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*
70
+
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*
110
+
111
+ * Remove unnecessary `respond_to` checks.
112
+
113
+ *Tiago Menegaz*, *Joel Hawksley*
114
+
115
+ * Do not include internal `DocsBuilderComponent` or `YARD::MattrAccessorHandler` in published gem.
116
+
117
+ *Joel Hawksley*
118
+
119
+ * Only lock to `concurrent-ruby` `1.3.4` for Rails 6.1.
120
+
121
+ *Joel Hawksley*
122
+
123
+ * Fix generation of ViewComponent documentation that was broken due to HTML safety issues.
124
+
125
+ *Simon Fish*
126
+
127
+ * Add documentation on how ViewComponent works.
128
+
129
+ *Joel Hawksley*
130
+
131
+ * Clarify that `config.use_deprecated_instrumentation_name` will be removed in v4.
132
+
133
+ *Joel Hawksley*
134
+
135
+ * Run RSpec tests in CI.
136
+
137
+ *Joel Hawksley*
138
+
13
139
  ## 3.22.0
14
140
 
15
141
  * Rewrite `ViewComponents at GitHub` documentation as more general `Best practices`.
@@ -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"
@@ -39,9 +40,6 @@ module ViewComponent
39
40
  include ViewComponent::Translatable
40
41
  include ViewComponent::WithContentHelper
41
42
 
42
- RESERVED_PARAMETER = :content
43
- VC_INTERNAL_DEFAULT_FORMAT = :html
44
-
45
43
  # For CSRF authenticity tokens in forms
46
44
  delegate :form_authenticity_token, :protect_against_forgery?, :config, to: :helpers
47
45
 
@@ -49,8 +47,7 @@ module ViewComponent
49
47
  delegate :content_security_policy_nonce, to: :helpers
50
48
 
51
49
  # Config option that strips trailing whitespace in templates before compiling them.
52
- class_attribute :__vc_strip_trailing_whitespace, instance_accessor: false, instance_predicate: false
53
- 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
54
51
 
55
52
  attr_accessor :__vc_original_view_context
56
53
 
@@ -67,6 +64,8 @@ module ViewComponent
67
64
  self.__vc_original_view_context = view_context
68
65
  end
69
66
 
67
+ using RequestDetails
68
+
70
69
  # Entrypoint for rendering components.
71
70
  #
72
71
  # - `view_context`: ActionView context from calling view
@@ -76,7 +75,7 @@ module ViewComponent
76
75
  #
77
76
  # @return [String]
78
77
  def render_in(view_context, &block)
79
- self.class.compile(raise_errors: true)
78
+ self.class.__vc_compile(raise_errors: true)
80
79
 
81
80
  @view_context = view_context
82
81
  self.__vc_original_view_context ||= view_context
@@ -85,22 +84,18 @@ module ViewComponent
85
84
 
86
85
  @lookup_context ||= view_context.lookup_context
87
86
 
88
- # required for path helpers in older Rails versions
89
- @view_renderer ||= view_context.view_renderer
90
-
91
87
  # For content_for
92
88
  @view_flow ||= view_context.view_flow
93
89
 
94
90
  # For i18n
95
91
  @virtual_path ||= virtual_path
96
92
 
97
- # For template variants (+phone, +desktop, etc.)
98
- @__vc_variant ||= @lookup_context.variants.first
93
+ # Describes the inferred request constraints (locales, formats, variants)
94
+ @__vc_requested_details ||= @lookup_context.vc_requested_details
99
95
 
100
96
  # For caching, such as #cache_if
101
97
  @current_template = nil unless defined?(@current_template)
102
98
  old_current_template = @current_template
103
- @current_template = self
104
99
 
105
100
  if block && defined?(@__vc_content_set_by_with_content)
106
101
  raise DuplicateContentError.new(self.class.name)
@@ -112,7 +107,7 @@ module ViewComponent
112
107
  before_render
113
108
 
114
109
  if render?
115
- 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
116
111
 
117
112
  # Avoid allocating new string when output_preamble and output_postamble are blank
118
113
  if output_preamble.blank? && output_postamble.blank?
@@ -160,7 +155,7 @@ module ViewComponent
160
155
  target_render = self.class.instance_variable_get(:@__vc_ancestor_calls)[@__vc_parent_render_level]
161
156
  @__vc_parent_render_level += 1
162
157
 
163
- target_render.bind_call(self, @__vc_variant)
158
+ target_render.bind_call(self, @__vc_requested_details)
164
159
  ensure
165
160
  @__vc_parent_render_level -= 1
166
161
  end
@@ -195,6 +190,8 @@ module ViewComponent
195
190
  true
196
191
  end
197
192
 
193
+ # Override the ActionView::Base initializer so that components
194
+ # do not need to define their own initializers.
198
195
  # @private
199
196
  def initialize(*)
200
197
  end
@@ -203,7 +200,7 @@ module ViewComponent
203
200
  #
204
201
  # This prevents an exception when rendering a partial inside of a component that has also been rendered outside
205
202
  # of the component. This is due to the partials compiled template method existing in the parent `view_context`,
206
- # and not the component's `view_context`.
203
+ # and not the component's `view_context`.
207
204
  #
208
205
  # @private
209
206
  def render(options = {}, args = {}, &block)
@@ -271,13 +268,6 @@ module ViewComponent
271
268
  []
272
269
  end
273
270
 
274
- # For caching, such as #cache_if
275
- #
276
- # @private
277
- def format
278
- @__vc_variant if defined?(@__vc_variant)
279
- end
280
-
281
271
  # The current request. Use sparingly as doing so introduces coupling that
282
272
  # inhibits encapsulation & reuse, often making testing difficult.
283
273
  #
@@ -286,10 +276,9 @@ module ViewComponent
286
276
  __vc_request
287
277
  end
288
278
 
289
- # Enables consumers to override request/@request
290
- #
291
279
  # @private
292
280
  def __vc_request
281
+ # The current request (if present, as mailers/jobs/etc do not have a request)
293
282
  @__vc_request ||= controller.request if controller.respond_to?(:request)
294
283
  end
295
284
 
@@ -332,7 +321,7 @@ module ViewComponent
332
321
  end
333
322
 
334
323
  def maybe_escape_html(text)
335
- return text if __vc_request && !__vc_request.format.html?
324
+ return text if @current_template && !@current_template.html?
336
325
  return text if text.blank?
337
326
 
338
327
  if text.html_safe?
@@ -365,13 +354,6 @@ module ViewComponent
365
354
  # configured on a per-test basis using `with_controller_class`.
366
355
  #
367
356
 
368
- # Set if render monkey patches should be included or not in Rails <6.1:
369
- #
370
- # ```ruby
371
- # config.view_component.render_monkey_patch_enabled = false
372
- # ```
373
- #
374
-
375
357
  # Path for component files
376
358
  #
377
359
  # ```ruby
@@ -520,20 +502,20 @@ module ViewComponent
520
502
  def inherited(child)
521
503
  # Compile so child will inherit compiled `call_*` template methods that
522
504
  # `compile` defines
523
- compile
505
+ __vc_compile
524
506
 
525
507
  # Give the child its own personal #render_template_for to protect against the case when
526
508
  # eager loading is disabled and the parent component is rendered before the child. In
527
509
  # such a scenario, the parent will override ViewComponent::Base#render_template_for,
528
510
  # meaning it will not be called for any children and thus not compile their templates.
529
- if !child.instance_methods(false).include?(:render_template_for) && !child.compiled?
511
+ if !child.instance_methods(false).include?(:render_template_for) && !child.__vc_compiled?
530
512
  child.class_eval <<~RUBY, __FILE__, __LINE__ + 1
531
- def render_template_for(variant = nil, format = nil)
513
+ def render_template_for(requested_details)
532
514
  # Force compilation here so the compiler always redefines render_template_for.
533
515
  # This is mostly a safeguard to prevent infinite recursion.
534
- self.class.compile(raise_errors: true, force: true)
535
- # .compile replaces this method; call the new one
536
- 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)
537
519
  end
538
520
  RUBY
539
521
  end
@@ -572,22 +554,22 @@ module ViewComponent
572
554
  end
573
555
 
574
556
  # @private
575
- def compiled?
576
- compiler.compiled?
557
+ def __vc_compiled?
558
+ __vc_compiler.compiled?
577
559
  end
578
560
 
579
561
  # @private
580
- def ensure_compiled
581
- compile unless compiled?
562
+ def __vc_ensure_compiled
563
+ __vc_compile unless __vc_compiled?
582
564
  end
583
565
 
584
566
  # @private
585
- def compile(raise_errors: false, force: false)
586
- 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)
587
569
  end
588
570
 
589
571
  # @private
590
- def compiler
572
+ def __vc_compiler
591
573
  @__vc_compiler ||= Compiler.new(self)
592
574
  end
593
575
 
@@ -629,8 +611,8 @@ module ViewComponent
629
611
  # is accepted, as support for collection
630
612
  # rendering is optional.
631
613
  # @private
632
- def validate_collection_parameter!(validate_default: false)
633
- 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
634
616
 
635
617
  return unless parameter
636
618
  return if initialize_parameter_names.include?(parameter) || splatted_keyword_argument_present?
@@ -649,35 +631,35 @@ module ViewComponent
649
631
  # invalid parameters that could override the framework's
650
632
  # methods.
651
633
  # @private
652
- def validate_initialization_parameters!
653
- return unless initialize_parameter_names.include?(RESERVED_PARAMETER)
634
+ def __vc_validate_initialization_parameters!
635
+ return unless initialize_parameter_names.include?(:content)
654
636
 
655
- raise ReservedParameterError.new(name, RESERVED_PARAMETER)
637
+ raise ReservedParameterError.new(name, :content)
656
638
  end
657
639
 
658
640
  # @private
659
- def collection_parameter
641
+ def __vc_collection_parameter
660
642
  provided_collection_parameter || name && name.demodulize.underscore.chomp("_component").to_sym
661
643
  end
662
644
 
663
645
  # @private
664
- def collection_counter_parameter
665
- :"#{collection_parameter}_counter"
646
+ def __vc_collection_counter_parameter
647
+ :"#{__vc_collection_parameter}_counter"
666
648
  end
667
649
 
668
650
  # @private
669
- def counter_argument_present?
670
- initialize_parameter_names.include?(collection_counter_parameter)
651
+ def __vc_counter_argument_present?
652
+ initialize_parameter_names.include?(__vc_collection_counter_parameter)
671
653
  end
672
654
 
673
655
  # @private
674
- def collection_iteration_parameter
675
- :"#{collection_parameter}_iteration"
656
+ def __vc_collection_iteration_parameter
657
+ :"#{__vc_collection_parameter}_iteration"
676
658
  end
677
659
 
678
660
  # @private
679
- def iteration_argument_present?
680
- initialize_parameter_names.include?(collection_iteration_parameter)
661
+ def __vc_iteration_argument_present?
662
+ initialize_parameter_names.include?(__vc_collection_iteration_parameter)
681
663
  end
682
664
 
683
665
  private
@@ -690,8 +672,6 @@ module ViewComponent
690
672
  def initialize_parameter_names
691
673
  return attribute_names.map(&:to_sym) if respond_to?(:attribute_names)
692
674
 
693
- return attribute_types.keys.map(&:to_sym) if Rails::VERSION::MAJOR <= 5 && respond_to?(:attribute_types)
694
-
695
675
  initialize_parameters.map(&:last)
696
676
  end
697
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