view_component 3.20.0 → 3.21.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 84bc019145d592e5a7f4dbb439cc960497ac347e12c2a6f73d7544a777365522
4
- data.tar.gz: 2832c147430779d124335b8e82c915115b5b6840ab02365df551f5313621e85c
3
+ metadata.gz: 24be9824d2f5208831e8de57930415019c781a1245224659efb9258372dcafbc
4
+ data.tar.gz: 33182c814b14959c85370e274619a3da70ea19906dd40c8d0be0cd12c9f16a2b
5
5
  SHA512:
6
- metadata.gz: ccbe1677fec16d8de063aafe220ada3ee0647d9963d91f269ef3081b9b2edffc4bf2f535c2097a730d72e80521a9367e97353927997f353f3ec59923e2611deb
7
- data.tar.gz: d52f357464701228bc686f4ea367974a287ce4fcd895845814f9a175635750664b705411c096f3f01c0bad0914a1db95573f50d12ff1b0e7d9029a55adf492b8
6
+ metadata.gz: 0d856adb4c86acc808277c7fcc17291b41328b932b53991db003dccab6e23f2a02177e200065e78d3004f8233df98b0926202138b8b536f67c8f848f876231e2
7
+ data.tar.gz: a7c6b583fd6eaf4bdb20cdc9d7ca86ed0a5e818e90d1099c5fd799d2127122c058d5d58285251ea0713aeb73d719cabad8ab971e994e0f658767235089953dfd
data/docs/CHANGELOG.md CHANGED
@@ -10,6 +10,36 @@ nav_order: 5
10
10
 
11
11
  ## main
12
12
 
13
+ ## 3.21.0
14
+
15
+ * Updates testing docs to include an example of how to use with RSpec.
16
+
17
+ *Rylan Bowers*
18
+
19
+ * Add `--skip-suffix` option to component generator.
20
+
21
+ *KAWAKAMI Moeki*
22
+
23
+ * Add FreeATS to list of companies using ViewComponent.
24
+
25
+ *Ilia Liamshin*
26
+
27
+ * Ensure HTML output safety wrapper is used for all inline templates.
28
+
29
+ *Joel Hawksley*
30
+
31
+ * Expose `.identifier` method as part of public API.
32
+
33
+ *Joel Hawksley*
34
+
35
+ * Add rails 8 support to CI.
36
+
37
+ *Reegan Viljoen*
38
+
39
+ * Updates ActionText compatibility documentation to reference `rich_textarea_tag` for Rails 8.0 support.
40
+
41
+ *Alvin Crespo*
42
+
13
43
  ## 3.20.0
14
44
 
15
45
  * Allow rendering `with_collection` to accept an optional `spacer_component` to be rendered between each item.
@@ -19,9 +19,10 @@ module Rails
19
19
  class_option :sidecar, type: :boolean, default: false
20
20
  class_option :stimulus, type: :boolean,
21
21
  default: ViewComponent::Base.config.generate.stimulus_controller
22
+ class_option :skip_suffix, type: :boolean, default: false
22
23
 
23
24
  def create_component_file
24
- template "component.rb", File.join(component_path, class_path, "#{file_name}_component.rb")
25
+ template "component.rb", File.join(component_path, class_path, "#{file_name}#{options[:skip_suffix] ? "" : "_component"}.rb")
25
26
  end
26
27
 
27
28
  hook_for :test_framework
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  <% module_namespacing do -%>
4
- class <%= class_name %>Component < <%= parent_class %>
4
+ class <%= class_name %><%= options[:skip_suffix] ? "" : "Component" %> < <%= parent_class %>
5
5
  <%- if initialize_signature -%>
6
6
  def initialize(<%= initialize_signature %>)
7
7
  <%= initialize_body %>
@@ -108,14 +108,7 @@ module ViewComponent
108
108
  before_render
109
109
 
110
110
  if render?
111
- rendered_template =
112
- if compiler.renders_template_for?(@__vc_variant, __vc_request&.format&.to_sym)
113
- render_template_for(@__vc_variant, __vc_request&.format&.to_sym)
114
- else
115
- maybe_escape_html(render_template_for(@__vc_variant, __vc_request&.format&.to_sym)) do
116
- Kernel.warn("WARNING: The #{self.class} component rendered HTML-unsafe output. The output will be automatically escaped, but you may want to investigate.")
117
- end
118
- end.to_s
111
+ rendered_template = render_template_for(@__vc_variant, __vc_request&.format&.to_sym).to_s
119
112
 
120
113
  # Avoid allocating new string when output_preamble and output_postamble are blank
121
114
  if output_preamble.blank? && output_postamble.blank?
@@ -358,10 +351,6 @@ module ViewComponent
358
351
  end
359
352
  end
360
353
 
361
- def compiler
362
- @compiler ||= self.class.compiler
363
- end
364
-
365
354
  # Set the controller used for testing components:
366
355
  #
367
356
  # ```ruby
@@ -457,8 +446,16 @@ module ViewComponent
457
446
  # Defaults to `false`.
458
447
 
459
448
  class << self
449
+ # The file path of the component Ruby file.
450
+ #
451
+ # @return [String]
452
+ attr_reader :identifier
453
+
454
+ # @private
455
+ attr_writer :identifier
456
+
460
457
  # @private
461
- attr_accessor :source_location, :virtual_path
458
+ attr_accessor :virtual_path
462
459
 
463
460
  # Find sidecar files for the given extensions.
464
461
  #
@@ -468,13 +465,13 @@ module ViewComponent
468
465
  # For example, one might collect sidecar CSS files that need to be compiled.
469
466
  # @param extensions [Array<String>] Extensions of which to return matching sidecar files.
470
467
  def sidecar_files(extensions)
471
- return [] unless source_location
468
+ return [] unless identifier
472
469
 
473
470
  extensions = extensions.join(",")
474
471
 
475
472
  # view files in a directory named like the component
476
- directory = File.dirname(source_location)
477
- filename = File.basename(source_location, ".rb")
473
+ directory = File.dirname(identifier)
474
+ filename = File.basename(identifier, ".rb")
478
475
  component_name = name.demodulize.underscore
479
476
 
480
477
  # Add support for nested components defined in the same file.
@@ -499,7 +496,7 @@ module ViewComponent
499
496
 
500
497
  sidecar_directory_files = Dir["#{directory}/#{component_name}/#{filename}.*{#{extensions}}"]
501
498
 
502
- (sidecar_files - [source_location] + sidecar_directory_files + nested_component_files).uniq
499
+ (sidecar_files - [identifier] + sidecar_directory_files + nested_component_files).uniq
503
500
  end
504
501
 
505
502
  # Render a component for each element in a collection ([documentation](/guide/collections)):
@@ -548,11 +545,11 @@ module ViewComponent
548
545
  # has been re-defined by the consuming application, likely in ApplicationComponent.
549
546
  # We use `base_label` method here instead of `label` to avoid cases where the method
550
547
  # owner is included in a prefix like `ApplicationComponent.inherited`.
551
- child.source_location = caller_locations(1, 10).reject { |l| l.base_label == "inherited" }[0].path
548
+ child.identifier = caller_locations(1, 10).reject { |l| l.base_label == "inherited" }[0].path
552
549
 
553
550
  # If Rails application is loaded, removes the first part of the path and the extension.
554
551
  if defined?(Rails) && Rails.application
555
- child.virtual_path = child.source_location.gsub(
552
+ child.virtual_path = child.identifier.gsub(
556
553
  /(.*#{Regexp.quote(ViewComponent::Base.config.view_component_path)})|(\.rb)/, ""
557
554
  )
558
555
  end
@@ -590,15 +587,6 @@ module ViewComponent
590
587
  @__vc_compiler ||= Compiler.new(self)
591
588
  end
592
589
 
593
- # @private
594
- def identifier
595
- # :nocov:
596
- Kernel.warn("WARNING: The #{self.class}.identifier is undocumented and was meant for internal framework usage only. As it is no longer used by the framework it will be removed in a coming non-breaking ViewComponent release.")
597
-
598
- source_location
599
- # :nocov:
600
- end
601
-
602
590
  # Set the parameter name used when rendering elements of a collection ([documentation](/guide/collections)):
603
591
  #
604
592
  # ```ruby
@@ -636,7 +624,7 @@ module ViewComponent
636
624
  # validate that the default parameter name
637
625
  # is accepted, as support for collection
638
626
  # rendering is optional.
639
- # @private TODO: add documentation
627
+ # @private
640
628
  def validate_collection_parameter!(validate_default: false)
641
629
  parameter = validate_default ? collection_parameter : provided_collection_parameter
642
630
 
@@ -656,7 +644,7 @@ module ViewComponent
656
644
  # Ensure the component initializer doesn't define
657
645
  # invalid parameters that could override the framework's
658
646
  # methods.
659
- # @private TODO: add documentation
647
+ # @private
660
648
  def validate_initialization_parameters!
661
649
  return unless initialize_parameter_names.include?(RESERVED_PARAMETER)
662
650
 
@@ -13,7 +13,6 @@ module ViewComponent
13
13
  def initialize(component)
14
14
  @component = component
15
15
  @lock = Mutex.new
16
- @rendered_templates = Set.new
17
16
  end
18
17
 
19
18
  def compiled?
@@ -56,10 +55,6 @@ module ViewComponent
56
55
  end
57
56
  end
58
57
 
59
- def renders_template_for?(variant, format)
60
- @rendered_templates.include?([variant, format])
61
- end
62
-
63
58
  private
64
59
 
65
60
  attr_reader :templates
@@ -71,9 +66,9 @@ module ViewComponent
71
66
 
72
67
  method_body =
73
68
  if @templates.one?
74
- @templates.first.safe_method_name
69
+ @templates.first.safe_method_name_call
75
70
  elsif (template = @templates.find(&:inline?))
76
- template.safe_method_name
71
+ template.safe_method_name_call
77
72
  else
78
73
  branches = []
79
74
 
@@ -88,13 +83,13 @@ module ViewComponent
88
83
  ].join(" && ")
89
84
  end
90
85
 
91
- branches << [conditional, template.safe_method_name]
86
+ branches << [conditional, template.safe_method_name_call]
92
87
  end
93
88
 
94
89
  out = branches.each_with_object(+"") do |(conditional, branch_body), memo|
95
90
  memo << "#{(!memo.present?) ? "if" : "elsif"} #{conditional}\n #{branch_body}\n"
96
91
  end
97
- out << "else\n #{templates.find { _1.variant.nil? && _1.default_format? }.safe_method_name}\nend"
92
+ out << "else\n #{templates.find { _1.variant.nil? && _1.default_format? }.safe_method_name_call}\nend"
98
93
  end
99
94
 
100
95
  @component.silence_redefinition_of_method(:render_template_for)
@@ -196,10 +191,6 @@ module ViewComponent
196
191
  variant: variant
197
192
  )
198
193
 
199
- # TODO: We should consider inlining the HTML output safety logic into the compiled render_template_for
200
- # instead of this indirect approach
201
- @rendered_templates << [out.variant, out.this_format]
202
-
203
194
  out
204
195
  end
205
196
 
@@ -13,7 +13,7 @@ module ViewComponent # :nodoc:
13
13
  notification_name,
14
14
  {
15
15
  name: self.class.name,
16
- identifier: self.class.source_location
16
+ identifier: self.class.identifier
17
17
  }
18
18
  ) do
19
19
  super
@@ -59,6 +59,14 @@ module ViewComponent
59
59
  @component.define_method(safe_method_name, @component.instance_method(@call_method_name))
60
60
  end
61
61
 
62
+ def safe_method_name_call
63
+ return safe_method_name unless inline_call?
64
+
65
+ "maybe_escape_html(#{safe_method_name}) " \
66
+ "{ Kernel.warn('WARNING: The #{@component} component rendered HTML-unsafe output. " \
67
+ "The output will be automatically escaped, but you may want to investigate.') } "
68
+ end
69
+
62
70
  def requires_compiled_superclass?
63
71
  inline_call? && !defined_on_self?
64
72
  end
@@ -3,7 +3,7 @@
3
3
  module ViewComponent
4
4
  module VERSION
5
5
  MAJOR = 3
6
- MINOR = 20
6
+ MINOR = 21
7
7
  PATCH = 0
8
8
  PRE = nil
9
9
 
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: 3.20.0
4
+ version: 3.21.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - ViewComponent Team
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-10-31 00:00:00.000000000 Z
11
+ date: 2024-12-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -324,6 +324,20 @@ dependencies:
324
324
  - - '='
325
325
  - !ruby/object:Gem::Version
326
326
  version: 4.9.0
327
+ - !ruby/object:Gem::Dependency
328
+ name: sprockets-rails
329
+ requirement: !ruby/object:Gem::Requirement
330
+ requirements:
331
+ - - "~>"
332
+ - !ruby/object:Gem::Version
333
+ version: 3.4.2
334
+ type: :development
335
+ prerelease: false
336
+ version_requirements: !ruby/object:Gem::Requirement
337
+ requirements:
338
+ - - "~>"
339
+ - !ruby/object:Gem::Version
340
+ version: 3.4.2
327
341
  - !ruby/object:Gem::Dependency
328
342
  name: standard
329
343
  requirement: !ruby/object:Gem::Requirement
@@ -380,20 +394,6 @@ dependencies:
380
394
  - - "~>"
381
395
  - !ruby/object:Gem::Version
382
396
  version: '5.1'
383
- - !ruby/object:Gem::Dependency
384
- name: sprockets-rails
385
- requirement: !ruby/object:Gem::Requirement
386
- requirements:
387
- - - "~>"
388
- - !ruby/object:Gem::Version
389
- version: 3.4.2
390
- type: :development
391
- prerelease: false
392
- version_requirements: !ruby/object:Gem::Requirement
393
- requirements:
394
- - - "~>"
395
- - !ruby/object:Gem::Version
396
- version: 3.4.2
397
397
  - !ruby/object:Gem::Dependency
398
398
  name: turbo-rails
399
399
  requirement: !ruby/object:Gem::Requirement