view_component 2.40.0 → 2.43.1
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/docs/CHANGELOG.md +111 -2
- data/lib/rails/generators/component/component_generator.rb +8 -1
- data/lib/rails/generators/stimulus/component_generator.rb +13 -0
- data/lib/rails/generators/stimulus/templates/component_controller.js.tt +1 -1
- data/lib/view_component/base.rb +30 -23
- data/lib/view_component/engine.rb +1 -1
- data/lib/view_component/polymorphic_slots.rb +73 -0
- data/lib/view_component/preview.rb +1 -0
- data/lib/view_component/slot_v2.rb +2 -1
- data/lib/view_component/slotable_v2.rb +32 -20
- data/lib/view_component/test_helpers.rb +3 -0
- data/lib/view_component/version.rb +2 -2
- data/lib/view_component.rb +2 -0
- metadata +18 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 68e0fc06b5f3e59c4baf241bef8827bb6d917823ee7d79052ff7e2e9406363da
|
4
|
+
data.tar.gz: a21f0dabe952531d817fdd6b3859089e4a21bd3f7474bdaee6c6b5953a653593
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7c8068857218b70cba3d99fe04df088ab2bb0da3f03f9277352b7a96dcebaff10fcf0d1b3657004ca5d6552c2033173a599fd64ce81b1e5635db224d48617d51
|
7
|
+
data.tar.gz: e7808192370b1c9f3eb4af84def46ebbfc4828b23f4c75be2f4753b18463f733beff77fff65ba3ccaa690efb6365fa5dcab574b962f905deb1cfbd4475dc3f20
|
data/README.md
CHANGED
data/docs/CHANGELOG.md
CHANGED
@@ -7,6 +7,115 @@ title: Changelog
|
|
7
7
|
|
8
8
|
## main
|
9
9
|
|
10
|
+
## 2.43.1
|
11
|
+
|
12
|
+
* Remove unnecessary call to `ruby2_keywords` for polymorphic slot getters.
|
13
|
+
|
14
|
+
*Cameron Dutro*
|
15
|
+
|
16
|
+
## 2.43.0
|
17
|
+
|
18
|
+
* Add note about tests and instance methods.
|
19
|
+
|
20
|
+
*Joel Hawksley*
|
21
|
+
|
22
|
+
* Flesh out `ViewComponents in practice`.
|
23
|
+
|
24
|
+
*Joel Hawksley*
|
25
|
+
|
26
|
+
* Add CODEOWNERS entries for feature areas owned by community committers.
|
27
|
+
|
28
|
+
*Joel Hawksley*
|
29
|
+
|
30
|
+
* Separate lint and CI workflows.
|
31
|
+
|
32
|
+
*Blake Williams*
|
33
|
+
|
34
|
+
* Add support for `image_path` helper in previews.
|
35
|
+
|
36
|
+
*Tobias Ahlin*, *Joel Hawksley*
|
37
|
+
|
38
|
+
* Add section to docs listing users of ViewComponent. Please submit a PR to add your team to the list!
|
39
|
+
|
40
|
+
*Joel Hawksley*
|
41
|
+
|
42
|
+
* Fix loading issue with Stimulus generator and add specs for Stimulus generator.
|
43
|
+
|
44
|
+
*Peter Sumskas*
|
45
|
+
|
46
|
+
* Remove dependency on `ActionDispatch::Static` in Rails middleware stack when enabling statics assets for source code preview.
|
47
|
+
|
48
|
+
*Gregory Igelmund*
|
49
|
+
|
50
|
+
* Require `view_component/engine` automatically.
|
51
|
+
|
52
|
+
*Cameron Dutro*
|
53
|
+
|
54
|
+
## 2.42.0
|
55
|
+
|
56
|
+
* Add logo files and page to docs.
|
57
|
+
|
58
|
+
*Dylan Smith*
|
59
|
+
|
60
|
+
* Add `ViewComponents in practice` documentation.
|
61
|
+
|
62
|
+
*Joel Hawksley*
|
63
|
+
|
64
|
+
* Fix bug where calling lambda slots without arguments would break in Ruby < 2.7.
|
65
|
+
|
66
|
+
*Manuel Puyol*
|
67
|
+
|
68
|
+
* Improve Stimulus controller template to import from `stimulus` or `@hotwired/stimulus`.
|
69
|
+
|
70
|
+
*Mario Schüttel*
|
71
|
+
|
72
|
+
* Fix bug where `helpers` would instantiate and use a new `view_context` in each component.
|
73
|
+
|
74
|
+
*Blake Williams*, *Ian C. Anderson*
|
75
|
+
|
76
|
+
* Implement polymorphic slots as experimental feature. See the Slots documentation to learn more.
|
77
|
+
|
78
|
+
*Cameron Dutro*
|
79
|
+
|
80
|
+
## 2.41.0
|
81
|
+
|
82
|
+
* Add `sprockets-rails` development dependency to fix test suite failures when using rails@main.
|
83
|
+
|
84
|
+
*Blake Williams*
|
85
|
+
|
86
|
+
* Fix Ruby indentation warning.
|
87
|
+
|
88
|
+
*Blake Williams*
|
89
|
+
|
90
|
+
* Add `--parent` generator option to specify the parent class.
|
91
|
+
* Add config option `config.view_component.component_parent_class` to change it project-wide.
|
92
|
+
|
93
|
+
*Hans Lemuet*
|
94
|
+
|
95
|
+
* Update docs to add example for using Devise helpers in tests.
|
96
|
+
|
97
|
+
*Matthew Rider*
|
98
|
+
|
99
|
+
* Fix bug where `with_collection_parameter` did not inherit from parent component.
|
100
|
+
|
101
|
+
*Will Drexler*, *Christian Campoli*
|
102
|
+
|
103
|
+
* Allow query parameters in `with_request_url` test helper.
|
104
|
+
|
105
|
+
*Javi Martín*
|
106
|
+
|
107
|
+
* Add "how to render a component to a string" to FAQ.
|
108
|
+
|
109
|
+
*Hans Lemuet*
|
110
|
+
|
111
|
+
* Add `#render_in` to API docs.
|
112
|
+
|
113
|
+
*Hans Lemuet*
|
114
|
+
|
115
|
+
* Forward keyword arguments from slot wrapper to component instance using ruby2_keywords.
|
116
|
+
|
117
|
+
*Cameron Dutro*
|
118
|
+
|
10
119
|
## 2.40.0
|
11
120
|
|
12
121
|
* Replace antipatterns section in the documentation with best practices.
|
@@ -62,7 +171,7 @@ title: Changelog
|
|
62
171
|
|
63
172
|
* Add test case for conflict with internal `@variant` variable.
|
64
173
|
|
65
|
-
|
174
|
+
*David Backeus*
|
66
175
|
|
67
176
|
* Document decision to not change naming convention recommendation to remove `-Component` suffix.
|
68
177
|
|
@@ -126,7 +235,7 @@ title: Changelog
|
|
126
235
|
|
127
236
|
* Ensure consistent indentation with Rubocop.
|
128
237
|
|
129
|
-
*Joel Hawksley
|
238
|
+
*Joel Hawksley*
|
130
239
|
|
131
240
|
* Bump `activesupport` upper bound from `< 7.0` to `< 8.0`.
|
132
241
|
|
@@ -12,6 +12,7 @@ module Rails
|
|
12
12
|
argument :attributes, type: :array, default: [], banner: "attribute"
|
13
13
|
check_class_collision suffix: "Component"
|
14
14
|
class_option :inline, type: :boolean, default: false
|
15
|
+
class_option :parent, type: :string, desc: "The parent class for the generated component"
|
15
16
|
class_option :stimulus, type: :boolean, default: ViewComponent::Base.generate_stimulus_controller
|
16
17
|
class_option :sidecar, type: :boolean, default: false
|
17
18
|
|
@@ -32,7 +33,9 @@ module Rails
|
|
32
33
|
private
|
33
34
|
|
34
35
|
def parent_class
|
35
|
-
|
36
|
+
return options[:parent] if options[:parent]
|
37
|
+
|
38
|
+
ViewComponent::Base.component_parent_class || default_parent_class
|
36
39
|
end
|
37
40
|
|
38
41
|
def initialize_signature
|
@@ -48,6 +51,10 @@ module Rails
|
|
48
51
|
def initialize_call_method_for_inline?
|
49
52
|
options["inline"]
|
50
53
|
end
|
54
|
+
|
55
|
+
def default_parent_class
|
56
|
+
defined?(ApplicationComponent) ? ApplicationComponent : ViewComponent::Base
|
57
|
+
end
|
51
58
|
end
|
52
59
|
end
|
53
60
|
end
|
@@ -1,5 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require "rails/generators/abstract_generator"
|
4
|
+
|
3
5
|
module Stimulus
|
4
6
|
module Generators
|
5
7
|
class ComponentGenerator < ::Rails::Generators::NamedBase
|
@@ -12,6 +14,12 @@ module Stimulus
|
|
12
14
|
template "component_controller.js", destination
|
13
15
|
end
|
14
16
|
|
17
|
+
def stimulus_module
|
18
|
+
return "stimulus" if legacy_stimulus?
|
19
|
+
|
20
|
+
"@hotwired/stimulus"
|
21
|
+
end
|
22
|
+
|
15
23
|
private
|
16
24
|
|
17
25
|
def destination
|
@@ -21,6 +29,11 @@ module Stimulus
|
|
21
29
|
File.join(component_path, class_path, "#{file_name}_component_controller.js")
|
22
30
|
end
|
23
31
|
end
|
32
|
+
|
33
|
+
def legacy_stimulus?
|
34
|
+
package_json_pathname = Rails.root.join("package.json")
|
35
|
+
package_json_pathname.exist? && JSON.parse(package_json_pathname.read).dig("dependencies", "stimulus").present?
|
36
|
+
end
|
24
37
|
end
|
25
38
|
end
|
26
39
|
end
|
data/lib/view_component/base.rb
CHANGED
@@ -5,6 +5,7 @@ require "active_support/configurable"
|
|
5
5
|
require "view_component/collection"
|
6
6
|
require "view_component/compile_cache"
|
7
7
|
require "view_component/content_areas"
|
8
|
+
require "view_component/polymorphic_slots"
|
8
9
|
require "view_component/previewable"
|
9
10
|
require "view_component/slotable"
|
10
11
|
require "view_component/slotable_v2"
|
@@ -28,6 +29,8 @@ module ViewComponent
|
|
28
29
|
class_attribute :content_areas
|
29
30
|
self.content_areas = [] # class_attribute:default doesn't work until Rails 5.2
|
30
31
|
|
32
|
+
attr_accessor :original_view_context
|
33
|
+
|
31
34
|
# EXPERIMENTAL: This API is experimental and may be removed at any time.
|
32
35
|
# Hook for allowing components to do work as part of the compilation process.
|
33
36
|
#
|
@@ -39,33 +42,18 @@ module ViewComponent
|
|
39
42
|
|
40
43
|
# Entrypoint for rendering components.
|
41
44
|
#
|
42
|
-
# view_context
|
43
|
-
# block
|
44
|
-
#
|
45
|
-
# returns HTML that has been escaped by the respective template handler
|
46
|
-
#
|
47
|
-
# Example subclass:
|
48
|
-
#
|
49
|
-
# app/components/my_component.rb:
|
50
|
-
# class MyComponent < ViewComponent::Base
|
51
|
-
# def initialize(title:)
|
52
|
-
# @title = title
|
53
|
-
# end
|
54
|
-
# end
|
45
|
+
# - `view_context`: ActionView context from calling view
|
46
|
+
# - `block`: optional block to be captured within the view context
|
55
47
|
#
|
56
|
-
#
|
57
|
-
# <span title="<%= @title %>">Hello, <%= content %>!</span>
|
48
|
+
# Returns HTML that has been escaped by the respective template handler.
|
58
49
|
#
|
59
|
-
#
|
60
|
-
# <%= render MyComponent.new(title: "greeting") do %>world<% end %>
|
61
|
-
# returns:
|
62
|
-
# <span title="greeting">Hello, world!</span>
|
63
|
-
#
|
64
|
-
# @private
|
50
|
+
# @return [String]
|
65
51
|
def render_in(view_context, &block)
|
66
52
|
self.class.compile(raise_errors: true)
|
67
53
|
|
68
54
|
@view_context = view_context
|
55
|
+
self.original_view_context ||= view_context
|
56
|
+
|
69
57
|
@lookup_context ||= view_context.lookup_context
|
70
58
|
|
71
59
|
# required for path helpers in older Rails versions
|
@@ -149,9 +137,10 @@ module ViewComponent
|
|
149
137
|
# @private
|
150
138
|
def render(options = {}, args = {}, &block)
|
151
139
|
if options.is_a? ViewComponent::Base
|
140
|
+
options.original_view_context = original_view_context
|
152
141
|
super
|
153
142
|
else
|
154
|
-
|
143
|
+
original_view_context.render(options, args, &block)
|
155
144
|
end
|
156
145
|
end
|
157
146
|
|
@@ -190,7 +179,14 @@ module ViewComponent
|
|
190
179
|
)
|
191
180
|
end
|
192
181
|
|
193
|
-
|
182
|
+
# Attempt to re-use the original view_context passed to the first
|
183
|
+
# component rendered in the rendering pipeline. This prevents the
|
184
|
+
# instantiation of a new view_context via `controller.view_context` which
|
185
|
+
# always returns a new instance of the view context class.
|
186
|
+
#
|
187
|
+
# This allows ivars to remain persisted when using the same helper via
|
188
|
+
# `helpers` across multiple components and partials.
|
189
|
+
@__vc_helpers ||= original_view_context || controller.view_context
|
194
190
|
end
|
195
191
|
|
196
192
|
# Exposes .virtual_path as an instance method
|
@@ -298,6 +294,14 @@ module ViewComponent
|
|
298
294
|
# Defaults to "app/components".
|
299
295
|
mattr_accessor :view_component_path, instance_writer: false, default: "app/components"
|
300
296
|
|
297
|
+
# Parent class for generated components
|
298
|
+
#
|
299
|
+
# config.view_component.component_parent_class = "MyBaseComponent"
|
300
|
+
#
|
301
|
+
# Defaults to "ApplicationComponent" if defined, "ViewComponent::Base" otherwise.
|
302
|
+
mattr_accessor :component_parent_class,
|
303
|
+
instance_writer: false
|
304
|
+
|
301
305
|
class << self
|
302
306
|
# @private
|
303
307
|
attr_accessor :source_location, :virtual_path
|
@@ -384,6 +388,9 @@ module ViewComponent
|
|
384
388
|
%r{(.*#{Regexp.quote(ViewComponent::Base.view_component_path)})|(\.rb)}, ""
|
385
389
|
)
|
386
390
|
|
391
|
+
# Set collection parameter to the extended component
|
392
|
+
child.with_collection_parameter provided_collection_parameter
|
393
|
+
|
387
394
|
super
|
388
395
|
end
|
389
396
|
|
@@ -103,7 +103,7 @@ module ViewComponent
|
|
103
103
|
|
104
104
|
initializer "static assets" do |app|
|
105
105
|
if app.config.view_component.show_previews
|
106
|
-
app.middleware.
|
106
|
+
app.middleware.use(::ActionDispatch::Static, "#{root}/app/assets/vendor")
|
107
107
|
end
|
108
108
|
end
|
109
109
|
|
@@ -0,0 +1,73 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ViewComponent
|
4
|
+
module PolymorphicSlots
|
5
|
+
# In older rails versions, using a concern isn't a good idea here because they appear to not work with
|
6
|
+
# Module#prepend and class methods.
|
7
|
+
def self.included(base)
|
8
|
+
base.singleton_class.prepend(ClassMethods)
|
9
|
+
base.include(InstanceMethods)
|
10
|
+
end
|
11
|
+
|
12
|
+
module ClassMethods
|
13
|
+
def renders_one(slot_name, callable = nil)
|
14
|
+
return super unless callable.is_a?(Hash) && callable.key?(:types)
|
15
|
+
|
16
|
+
validate_singular_slot_name(slot_name)
|
17
|
+
register_polymorphic_slot(slot_name, callable[:types], collection: false)
|
18
|
+
end
|
19
|
+
|
20
|
+
def renders_many(slot_name, callable = nil)
|
21
|
+
return super unless callable.is_a?(Hash) && callable.key?(:types)
|
22
|
+
|
23
|
+
validate_plural_slot_name(slot_name)
|
24
|
+
register_polymorphic_slot(slot_name, callable[:types], collection: true)
|
25
|
+
end
|
26
|
+
|
27
|
+
def register_polymorphic_slot(slot_name, types, collection:)
|
28
|
+
renderable_hash = types.each_with_object({}) do |(poly_type, poly_callable), memo|
|
29
|
+
memo[poly_type] = define_slot(
|
30
|
+
"#{slot_name}_#{poly_type}", collection: collection, callable: poly_callable
|
31
|
+
)
|
32
|
+
|
33
|
+
getter_name = slot_name
|
34
|
+
setter_name =
|
35
|
+
if collection
|
36
|
+
"#{ActiveSupport::Inflector.singularize(slot_name)}_#{poly_type}"
|
37
|
+
else
|
38
|
+
"#{slot_name}_#{poly_type}"
|
39
|
+
end
|
40
|
+
|
41
|
+
define_method(getter_name) do
|
42
|
+
get_slot(slot_name)
|
43
|
+
end
|
44
|
+
|
45
|
+
define_method(setter_name) do |*args, &block|
|
46
|
+
set_polymorphic_slot(slot_name, poly_type, *args, &block)
|
47
|
+
end
|
48
|
+
ruby2_keywords(setter_name.to_sym) if respond_to?(:ruby2_keywords, true)
|
49
|
+
end
|
50
|
+
|
51
|
+
self.registered_slots[slot_name] = {
|
52
|
+
collection: collection,
|
53
|
+
renderable_hash: renderable_hash
|
54
|
+
}
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
module InstanceMethods
|
59
|
+
def set_polymorphic_slot(slot_name, poly_type = nil, *args, &block)
|
60
|
+
slot_definition = self.class.registered_slots[slot_name]
|
61
|
+
|
62
|
+
if !slot_definition[:collection] && get_slot(slot_name)
|
63
|
+
raise ArgumentError, "content for slot '#{slot_name}' has already been provided"
|
64
|
+
end
|
65
|
+
|
66
|
+
poly_def = slot_definition[:renderable_hash][poly_type]
|
67
|
+
|
68
|
+
set_slot(slot_name, poly_def, *args, &block)
|
69
|
+
end
|
70
|
+
ruby2_keywords(:set_polymorphic_slot) if respond_to?(:ruby2_keywords, true)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
@@ -62,7 +62,7 @@ module ViewComponent
|
|
62
62
|
view_context.capture(&@__vc_content_block)
|
63
63
|
elsif defined?(@__vc_content_set_by_with_content)
|
64
64
|
@__vc_content_set_by_with_content
|
65
|
-
|
65
|
+
end
|
66
66
|
|
67
67
|
@content = @content.to_s
|
68
68
|
end
|
@@ -89,6 +89,7 @@ module ViewComponent
|
|
89
89
|
def method_missing(symbol, *args, &block)
|
90
90
|
@__vc_component_instance.public_send(symbol, *args, &block)
|
91
91
|
end
|
92
|
+
ruby2_keywords(:method_missing) if respond_to?(:ruby2_keywords, true)
|
92
93
|
|
93
94
|
def html_safe?
|
94
95
|
to_s.html_safe?
|
@@ -1,7 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require "active_support/concern"
|
4
|
-
|
5
4
|
require "view_component/slot_v2"
|
6
5
|
|
7
6
|
module ViewComponent
|
@@ -67,13 +66,14 @@ module ViewComponent
|
|
67
66
|
def renders_one(slot_name, callable = nil)
|
68
67
|
validate_singular_slot_name(slot_name)
|
69
68
|
|
70
|
-
define_method slot_name do |*args,
|
71
|
-
if args.empty? &&
|
69
|
+
define_method slot_name do |*args, &block|
|
70
|
+
if args.empty? && block.nil?
|
72
71
|
get_slot(slot_name)
|
73
72
|
else
|
74
|
-
set_slot(slot_name, *args,
|
73
|
+
set_slot(slot_name, nil, *args, &block)
|
75
74
|
end
|
76
75
|
end
|
76
|
+
ruby2_keywords(slot_name.to_sym) if respond_to?(:ruby2_keywords, true)
|
77
77
|
|
78
78
|
register_slot(slot_name, collection: false, callable: callable)
|
79
79
|
end
|
@@ -123,9 +123,10 @@ module ViewComponent
|
|
123
123
|
# Define setter for singular names
|
124
124
|
# e.g. `renders_many :items` allows fetching all tabs with
|
125
125
|
# `component.tabs` and setting a tab with `component.tab`
|
126
|
-
define_method singular_name do |*args,
|
127
|
-
set_slot(slot_name, *args,
|
126
|
+
define_method singular_name do |*args, &block|
|
127
|
+
set_slot(slot_name, nil, *args, &block)
|
128
128
|
end
|
129
|
+
ruby2_keywords(singular_name.to_sym) if respond_to?(:ruby2_keywords, true)
|
129
130
|
|
130
131
|
# Instantiates and and adds multiple slots forwarding the first
|
131
132
|
# argument to each slot constructor
|
@@ -134,7 +135,7 @@ module ViewComponent
|
|
134
135
|
get_slot(slot_name)
|
135
136
|
else
|
136
137
|
collection_args.map do |args|
|
137
|
-
set_slot(slot_name, **args, &block)
|
138
|
+
set_slot(slot_name, nil, **args, &block)
|
138
139
|
end
|
139
140
|
end
|
140
141
|
end
|
@@ -162,27 +163,37 @@ module ViewComponent
|
|
162
163
|
|
163
164
|
private
|
164
165
|
|
165
|
-
def register_slot(slot_name,
|
166
|
+
def register_slot(slot_name, **kwargs)
|
167
|
+
self.registered_slots[slot_name] = define_slot(slot_name, **kwargs)
|
168
|
+
end
|
169
|
+
|
170
|
+
def define_slot(slot_name, collection:, callable:)
|
166
171
|
# Setup basic slot data
|
167
172
|
slot = {
|
168
173
|
collection: collection,
|
169
174
|
}
|
175
|
+
return slot unless callable
|
176
|
+
|
170
177
|
# If callable responds to `render_in`, we set it on the slot as a renderable
|
171
|
-
if callable
|
178
|
+
if callable.respond_to?(:method_defined?) && callable.method_defined?(:render_in)
|
172
179
|
slot[:renderable] = callable
|
173
180
|
elsif callable.is_a?(String)
|
174
181
|
# If callable is a string, we assume it's referencing an internal class
|
175
182
|
slot[:renderable_class_name] = callable
|
176
|
-
elsif callable
|
183
|
+
elsif callable.respond_to?(:call)
|
177
184
|
# If slot does not respond to `render_in`, we assume it's a proc,
|
178
185
|
# define a method, and save a reference to it to call when setting
|
179
186
|
method_name = :"_call_#{slot_name}"
|
180
187
|
define_method method_name, &callable
|
181
188
|
slot[:renderable_function] = instance_method(method_name)
|
189
|
+
else
|
190
|
+
raise(
|
191
|
+
ArgumentError,
|
192
|
+
"invalid slot definition. Please pass a class, string, or callable (i.e. proc, lambda, etc)"
|
193
|
+
)
|
182
194
|
end
|
183
195
|
|
184
|
-
|
185
|
-
self.registered_slots[slot_name] = slot
|
196
|
+
slot
|
186
197
|
end
|
187
198
|
|
188
199
|
def validate_plural_slot_name(slot_name)
|
@@ -235,9 +246,8 @@ module ViewComponent
|
|
235
246
|
end
|
236
247
|
end
|
237
248
|
|
238
|
-
def set_slot(slot_name, *args,
|
239
|
-
slot_definition
|
240
|
-
|
249
|
+
def set_slot(slot_name, slot_definition = nil, *args, &block)
|
250
|
+
slot_definition ||= self.class.registered_slots[slot_name]
|
241
251
|
slot = SlotV2.new(self)
|
242
252
|
|
243
253
|
# Passing the block to the sub-component wrapper like this has two
|
@@ -253,23 +263,24 @@ module ViewComponent
|
|
253
263
|
|
254
264
|
# If class
|
255
265
|
if slot_definition[:renderable]
|
256
|
-
slot.__vc_component_instance = slot_definition[:renderable].new(*args
|
266
|
+
slot.__vc_component_instance = slot_definition[:renderable].new(*args)
|
257
267
|
# If class name as a string
|
258
268
|
elsif slot_definition[:renderable_class_name]
|
259
269
|
slot.__vc_component_instance =
|
260
|
-
self.class.const_get(slot_definition[:renderable_class_name]).new(*args
|
270
|
+
self.class.const_get(slot_definition[:renderable_class_name]).new(*args)
|
261
271
|
# If passed a lambda
|
262
272
|
elsif slot_definition[:renderable_function]
|
263
273
|
# Use `bind(self)` to ensure lambda is executed in the context of the
|
264
274
|
# current component. This is necessary to allow the lambda to access helper
|
265
275
|
# methods like `content_tag` as well as parent component state.
|
276
|
+
renderable_function = slot_definition[:renderable_function].bind(self)
|
266
277
|
renderable_value =
|
267
278
|
if block_given?
|
268
|
-
|
269
|
-
view_context.capture(*args,
|
279
|
+
renderable_function.call(*args) do |*args|
|
280
|
+
view_context.capture(*args, &block)
|
270
281
|
end
|
271
282
|
else
|
272
|
-
|
283
|
+
renderable_function.call(*args)
|
273
284
|
end
|
274
285
|
|
275
286
|
# Function calls can return components, so if it's a component handle it specially
|
@@ -291,5 +302,6 @@ module ViewComponent
|
|
291
302
|
|
292
303
|
slot
|
293
304
|
end
|
305
|
+
ruby2_keywords(:set_slot) if respond_to?(:ruby2_keywords, true)
|
294
306
|
end
|
295
307
|
end
|
@@ -114,12 +114,15 @@ module ViewComponent
|
|
114
114
|
# @param path [String] The path to set for the current request.
|
115
115
|
def with_request_url(path)
|
116
116
|
old_request_path_parameters = request.path_parameters
|
117
|
+
old_request_query_parameters = request.query_parameters
|
117
118
|
old_controller = defined?(@controller) && @controller
|
118
119
|
|
119
120
|
request.path_parameters = Rails.application.routes.recognize_path(path)
|
121
|
+
request.set_header("action_dispatch.request.query_parameters", Rack::Utils.parse_query(path.split("?")[1]))
|
120
122
|
yield
|
121
123
|
ensure
|
122
124
|
request.path_parameters = old_request_path_parameters
|
125
|
+
request.set_header("action_dispatch.request.query_parameters", old_request_query_parameters)
|
123
126
|
@controller = old_controller
|
124
127
|
end
|
125
128
|
|
data/lib/view_component.rb
CHANGED
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: 2.
|
4
|
+
version: 2.43.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- GitHub Open Source
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-
|
11
|
+
date: 2021-11-09 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -226,6 +226,20 @@ dependencies:
|
|
226
226
|
- - "~>"
|
227
227
|
- !ruby/object:Gem::Version
|
228
228
|
version: '4.0'
|
229
|
+
- !ruby/object:Gem::Dependency
|
230
|
+
name: sprockets-rails
|
231
|
+
requirement: !ruby/object:Gem::Requirement
|
232
|
+
requirements:
|
233
|
+
- - "~>"
|
234
|
+
- !ruby/object:Gem::Version
|
235
|
+
version: 3.2.2
|
236
|
+
type: :development
|
237
|
+
prerelease: false
|
238
|
+
version_requirements: !ruby/object:Gem::Requirement
|
239
|
+
requirements:
|
240
|
+
- - "~>"
|
241
|
+
- !ruby/object:Gem::Version
|
242
|
+
version: 3.2.2
|
229
243
|
- !ruby/object:Gem::Dependency
|
230
244
|
name: yard
|
231
245
|
requirement: !ruby/object:Gem::Requirement
|
@@ -300,6 +314,7 @@ files:
|
|
300
314
|
- lib/view_component/content_areas.rb
|
301
315
|
- lib/view_component/engine.rb
|
302
316
|
- lib/view_component/instrumentation.rb
|
317
|
+
- lib/view_component/polymorphic_slots.rb
|
303
318
|
- lib/view_component/preview.rb
|
304
319
|
- lib/view_component/preview_template_error.rb
|
305
320
|
- lib/view_component/previewable.rb
|
@@ -341,7 +356,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
341
356
|
- !ruby/object:Gem::Version
|
342
357
|
version: '0'
|
343
358
|
requirements: []
|
344
|
-
rubygems_version: 3.
|
359
|
+
rubygems_version: 3.2.22
|
345
360
|
signing_key:
|
346
361
|
specification_version: 4
|
347
362
|
summary: View components for Rails
|