view_component 3.12.1 → 3.14.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: 875f47469a83b3b70de2e4271cc4af72542d88c6e12c373c8f6912d3c8c6d13e
4
- data.tar.gz: 161671b627c087f227706c10e6ca7f900dcdd3d2ea49232024543bf78a3be14b
3
+ metadata.gz: 7ef8c603bedd61511ed3eb2da02cd7aaccc5b890ad20badac0cfc9a3e7d4af1e
4
+ data.tar.gz: f756c5bd11f44e7e8984d6cb6b29ec409dc082d83864ee4bd82c50adc784310c
5
5
  SHA512:
6
- metadata.gz: aaa215e2aba616eca2ea0e1bd1e4ab76df2f6f4f34d1f3f225a5802a943b8e6c8e920b3821fda06353e52979345a8d941c2d3d2eaa24b71a6928502846224acc
7
- data.tar.gz: f7da13dfa835866ac685d567f41549857ca40682e6f2beee269bf07b4b9bfaf942af62d03dbcc019cb72ef349ed8c601be24c1598efd0cb38e26397decb4e09a
6
+ metadata.gz: 8815314944335c3b69196bf5ba8779e10ec78a3146e8cc51d4d278d5e444035c8bc50858315c45e5556337e925ab94f4afee6b3283839079db6892292bec3581
7
+ data.tar.gz: 42c9159369779c50a9904525239d5bf3daa62ed5373104cb11f80251b9481a8225290421d0d9a5663e9f7c7e0bd4d73c63a53bc44845dc4b5bc23a0419869301
data/docs/CHANGELOG.md CHANGED
@@ -10,6 +10,62 @@ nav_order: 5
10
10
 
11
11
  ## main
12
12
 
13
+ ## 3.14.0
14
+
15
+ * Defer to built-in caching for language environment setup, rather than manually using `actions/cache` in CI.
16
+
17
+ *Simon Fish*
18
+
19
+ * Add test coverage for use of `turbo_stream` helpers in components when `capture_compatibility_patch_enabled` is `true`.
20
+
21
+ *Simon Fish*
22
+
23
+ * Add experimental `SlotableDefault` module, allowing components to define a `default_SLOTNAME` method to provide a default value for slots.
24
+
25
+ *Joel Hawksley*
26
+
27
+ * Add documentation on rendering ViewComponents outside of the view context.
28
+
29
+ *Joel Hawksley*
30
+
31
+ * Look for preview files that end in `preview.rb` rather than `_preview.rb` to allow previews to exist in sidecar directory with test files.
32
+
33
+ *Seth Herr*
34
+
35
+ * Add `assert_component_rendered` test helper.
36
+
37
+ *Reegan Viljoen*
38
+
39
+ * Add `prefix:` option to `use_helpers`.
40
+
41
+ *Reegan Viljoen*
42
+
43
+ * Add support for Rails 7.2.
44
+
45
+ *Reegan Viljoen*
46
+
47
+ ## 3.13.0
48
+
49
+ * Add ruby head and YJIT to CI.
50
+
51
+ *Reegan Viljoen*
52
+
53
+ * Fixed a bug where inline templates where unable to remove trailing whitespace without throwing an error.
54
+
55
+ *Reegan Viljoen*
56
+
57
+ * Fixed CI for Rails main.
58
+
59
+ *Reegan Viljoen*
60
+
61
+ * Add `from:` option to `use_helpers` to allow for more flexible helper inclusion from modules.
62
+
63
+ *Reegan Viljoen*
64
+
65
+ * Fixed ruby head matcher issue.
66
+
67
+ *Reegan Viljoen*
68
+
13
69
  ## 3.12.1
14
70
 
15
71
  * Ensure content is rendered correctly for forwarded slots.
@@ -24,15 +80,15 @@ nav_order: 5
24
80
 
25
81
  * Fix templates not being correctly populated when caller location label has a prefix.
26
82
 
27
- On the upstream version of Ruby, method owners are now included in backtraces as prefixes. This caused the call stack filtering to not work as intended and thus `source_location` to be incorrect for child ViewComponents, consequently not populating templates correctly.
83
+ On the upstream version of Ruby, method owners are now included in backtraces as prefixes. This caused the call stack filtering to not work as intended and thus `source_location` to be incorrect for child ViewComponents, consequently not populating templates correctly.
28
84
 
29
85
  *Allan Pires, Jason Kim*
30
86
 
31
87
  * Use component path for generating RSpec files.
32
88
 
33
- When generating new RSpec files for components, the generator will use the `view_component_path` value in the config to decide where to put the new spec file. For instance, if the `view_component_path` option has been changed to `app/views/components`, the generator will put the spec file in `spec/views/components`. **If the `view_component_path` doesn't start with `app/`, then the generator will fall back to `spec/components/`.**
89
+ When generating new RSpec files for components, the generator will use the `view_component_path` value in the config to decide where to put the new spec file. For instance, if the `view_component_path` option has been changed to `app/views/components`, the generator will put the spec file in `spec/views/components`. **If the `view_component_path` doesn't start with `app/`, then the generator will fall back to `spec/components/`.**
34
90
 
35
- This feature is enabled via the `config.view_component.generate.use_component_path_for_rspec_tests` option, defaulting to `false`. The default will change to `true` in ViewComponent v4.
91
+ This feature is enabled via the `config.view_component.generate.use_component_path_for_rspec_tests` option, defaulting to `false`. The default will change to `true` in ViewComponent v4.
36
92
 
37
93
  *William Mathewson*
38
94
 
@@ -56,7 +112,7 @@ This feature is enabled via the `config.view_component.generate.use_component_pa
56
112
 
57
113
  * Include ViewComponent::UseHelpers by default.
58
114
 
59
- *Reegan Viljoen*
115
+ *Reegan Viljoen*
60
116
 
61
117
  * Bump `puma` in Gemfile.lock.
62
118
 
@@ -10,6 +10,7 @@ require "view_component/errors"
10
10
  require "view_component/inline_template"
11
11
  require "view_component/preview"
12
12
  require "view_component/slotable"
13
+ require "view_component/slotable_default"
13
14
  require "view_component/translatable"
14
15
  require "view_component/with_content_helper"
15
16
  require "view_component/use_helpers"
@@ -86,6 +86,12 @@ module ViewComponent
86
86
  define_render_template_for
87
87
  end
88
88
 
89
+ component_class.registered_slots.each do |slot_name, config|
90
+ config[:default_method] = component_class.instance_methods.find { |method_name| method_name == :"default_#{slot_name}" }
91
+
92
+ component_class.registered_slots[slot_name] = config
93
+ end
94
+
89
95
  component_class.build_i18n_backend
90
96
 
91
97
  CompileCache.register(component_class)
@@ -247,9 +253,9 @@ module ViewComponent
247
253
 
248
254
  def compiled_inline_template(template)
249
255
  handler = ActionView::Template.handler_for_extension(template.language)
250
- template.rstrip! if component_class.strip_trailing_whitespace?
256
+ template = template.source.dup
251
257
 
252
- compile_template(template.source, handler)
258
+ compile_template(template, handler)
253
259
  end
254
260
 
255
261
  def compiled_template(file_path)
@@ -16,7 +16,7 @@ module ViewComponent # :nodoc:
16
16
  identifier: self.class.identifier
17
17
  }
18
18
  ) do
19
- super(view_context, &block)
19
+ super
20
20
  end
21
21
  end
22
22
 
@@ -102,7 +102,7 @@ module ViewComponent # :nodoc:
102
102
 
103
103
  def load_previews
104
104
  Array(preview_paths).each do |preview_path|
105
- Dir["#{preview_path}/**/*_preview.rb"].sort.each { |file| require_dependency file }
105
+ Dir["#{preview_path}/**/*preview.rb"].sort.each { |file| require_dependency file }
106
106
  end
107
107
  end
108
108
 
@@ -266,10 +266,7 @@ module ViewComponent
266
266
  end
267
267
 
268
268
  def define_slot(slot_name, collection:, callable:)
269
- # Setup basic slot data
270
- slot = {
271
- collection: collection
272
- }
269
+ slot = {collection: collection}
273
270
  return slot unless callable
274
271
 
275
272
  # If callable responds to `render_in`, we set it on the slot as a renderable
@@ -0,0 +1,20 @@
1
+ module ViewComponent
2
+ module SlotableDefault
3
+ def get_slot(slot_name)
4
+ @__vc_set_slots ||= {}
5
+
6
+ return super unless !@__vc_set_slots[slot_name] && (default_method = registered_slots[slot_name][:default_method])
7
+
8
+ renderable_value = send(default_method)
9
+ slot = Slot.new(self)
10
+
11
+ if renderable_value.respond_to?(:render_in)
12
+ slot.__vc_component_instance = renderable_value
13
+ else
14
+ slot.__vc_content = renderable_value
15
+ end
16
+
17
+ slot
18
+ end
19
+ end
20
+ end
@@ -14,6 +14,10 @@ module ViewComponent
14
14
  def refute_component_rendered
15
15
  assert_no_selector("body")
16
16
  end
17
+
18
+ def assert_component_rendered
19
+ assert_selector("body")
20
+ end
17
21
  rescue LoadError
18
22
  # We don't have a test case for running an application without capybara installed.
19
23
  # It's probably fine to leave this without coverage.
@@ -4,17 +4,39 @@ module ViewComponent::UseHelpers
4
4
  extend ActiveSupport::Concern
5
5
 
6
6
  class_methods do
7
- def use_helpers(*args)
8
- args.each do |helper_method|
9
- class_eval(<<-RUBY, __FILE__, __LINE__ + 1)
10
- def #{helper_method}(*args, &block)
11
- raise HelpersCalledBeforeRenderError if view_context.nil?
12
- __vc_original_view_context.#{helper_method}(*args, &block)
13
- end
14
- RUBY
15
-
16
- ruby2_keywords(helper_method) if respond_to?(:ruby2_keywords, true)
7
+ def use_helpers(*args, from: nil, prefix: false)
8
+ args.each { |helper_method| use_helper(helper_method, from: from, prefix: prefix) }
9
+ end
10
+
11
+ def use_helper(helper_method, from: nil, prefix: false)
12
+ helper_method_name = full_helper_method_name(helper_method, prefix: prefix, source: from)
13
+
14
+ class_eval(<<-RUBY, __FILE__, __LINE__ + 1)
15
+ def #{helper_method_name}(*args, &block)
16
+ raise HelpersCalledBeforeRenderError if view_context.nil?
17
+
18
+ #{define_helper(helper_method: helper_method, source: from)}
19
+ end
20
+ RUBY
21
+ ruby2_keywords(helper_method_name) if respond_to?(:ruby2_keywords, true)
22
+ end
23
+
24
+ private
25
+
26
+ def full_helper_method_name(helper_method, prefix: false, source: nil)
27
+ return helper_method unless prefix.present?
28
+
29
+ if !!prefix == prefix
30
+ "#{source.to_s.underscore}_#{helper_method}"
31
+ else
32
+ "#{prefix}_#{helper_method}"
17
33
  end
18
34
  end
35
+
36
+ def define_helper(helper_method:, source:)
37
+ return "__vc_original_view_context.#{helper_method}(*args, &block)" unless source.present?
38
+
39
+ "#{source}.instance_method(:#{helper_method}).bind(self).call(*args, &block)"
40
+ end
19
41
  end
20
42
  end
@@ -3,8 +3,8 @@
3
3
  module ViewComponent
4
4
  module VERSION
5
5
  MAJOR = 3
6
- MINOR = 12
7
- PATCH = 1
6
+ MINOR = 14
7
+ PATCH = 0
8
8
  PRE = nil
9
9
 
10
10
  STRING = [MAJOR, MINOR, PATCH, PRE].compact.join(".")
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.12.1
4
+ version: 3.14.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-04-17 00:00:00.000000000 Z
11
+ date: 2024-08-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -380,6 +380,20 @@ dependencies:
380
380
  - - "~>"
381
381
  - !ruby/object:Gem::Version
382
382
  version: 3.4.2
383
+ - !ruby/object:Gem::Dependency
384
+ name: turbo-rails
385
+ requirement: !ruby/object:Gem::Requirement
386
+ requirements:
387
+ - - "~>"
388
+ - !ruby/object:Gem::Version
389
+ version: '1'
390
+ type: :development
391
+ prerelease: false
392
+ version_requirements: !ruby/object:Gem::Requirement
393
+ requirements:
394
+ - - "~>"
395
+ - !ruby/object:Gem::Version
396
+ version: '1'
383
397
  - !ruby/object:Gem::Dependency
384
398
  name: warning
385
399
  requirement: !ruby/object:Gem::Requirement
@@ -530,6 +544,7 @@ files:
530
544
  - lib/view_component/rendering_monkey_patch.rb
531
545
  - lib/view_component/slot.rb
532
546
  - lib/view_component/slotable.rb
547
+ - lib/view_component/slotable_default.rb
533
548
  - lib/view_component/system_test_case.rb
534
549
  - lib/view_component/system_test_helpers.rb
535
550
  - lib/view_component/test_case.rb
@@ -561,7 +576,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
561
576
  - !ruby/object:Gem::Version
562
577
  version: '0'
563
578
  requirements: []
564
- rubygems_version: 3.5.4
579
+ rubygems_version: 3.5.3
565
580
  signing_key:
566
581
  specification_version: 4
567
582
  summary: A framework for building reusable, testable & encapsulated view components