view_component 2.17.1 → 2.19.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/CHANGELOG.md +132 -76
- data/README.md +153 -28
- data/app/controllers/view_components_controller.rb +26 -3
- data/app/views/view_components/preview.html.erb +5 -1
- data/lib/view_component/base.rb +21 -9
- data/lib/view_component/collection.rb +2 -0
- data/lib/view_component/engine.rb +2 -2
- data/lib/view_component/preview.rb +2 -14
- data/lib/view_component/previewable.rb +8 -0
- data/lib/view_component/test_helpers.rb +4 -0
- data/lib/view_component/version.rb +1 -1
- metadata +23 -9
@@ -16,22 +16,23 @@ class ViewComponentsController < Rails::ApplicationController # :nodoc:
|
|
16
16
|
def index
|
17
17
|
@previews = ViewComponent::Preview.all
|
18
18
|
@page_title = "Component Previews"
|
19
|
+
render "view_components/index", **determine_layout
|
19
20
|
end
|
20
21
|
|
21
22
|
def previews
|
22
23
|
if params[:path] == @preview.preview_name
|
23
24
|
@page_title = "Component Previews for #{@preview.preview_name}"
|
24
|
-
render "view_components/previews"
|
25
|
+
render "view_components/previews", **determine_layout
|
25
26
|
else
|
26
27
|
prepend_application_view_paths
|
27
28
|
prepend_preview_examples_view_path
|
28
29
|
@example_name = File.basename(params[:path])
|
29
30
|
@render_args = @preview.render_args(@example_name, params: params.permit!)
|
30
|
-
layout = @render_args[:layout]
|
31
|
+
layout = determine_layout(@render_args[:layout], prepend_views: false)[:layout]
|
31
32
|
template = @render_args[:template]
|
32
33
|
locals = @render_args[:locals]
|
33
34
|
opts = {}
|
34
|
-
opts[:layout] = layout if layout.present?
|
35
|
+
opts[:layout] = layout if layout.present? || layout == false
|
35
36
|
opts[:locals] = locals if locals.present?
|
36
37
|
render template, opts # rubocop:disable GitHub/RailsControllerRenderLiteral
|
37
38
|
end
|
@@ -39,6 +40,10 @@ class ViewComponentsController < Rails::ApplicationController # :nodoc:
|
|
39
40
|
|
40
41
|
private
|
41
42
|
|
43
|
+
def default_preview_layout # :doc:
|
44
|
+
ViewComponent::Base.default_preview_layout
|
45
|
+
end
|
46
|
+
|
42
47
|
def show_previews? # :doc:
|
43
48
|
ViewComponent::Base.show_previews
|
44
49
|
end
|
@@ -61,6 +66,24 @@ class ViewComponentsController < Rails::ApplicationController # :nodoc:
|
|
61
66
|
end
|
62
67
|
end
|
63
68
|
|
69
|
+
# Returns either {} or {layout: value} depending on configuration
|
70
|
+
def determine_layout(layout_override = nil, prepend_views: true)
|
71
|
+
return {} unless defined?(Rails.root)
|
72
|
+
|
73
|
+
layout_declaration = {}
|
74
|
+
|
75
|
+
if !layout_override.nil?
|
76
|
+
# Allow component-level override, even if false (thus no layout rendered)
|
77
|
+
layout_declaration[:layout] = layout_override
|
78
|
+
elsif default_preview_layout.present?
|
79
|
+
layout_declaration[:layout] = default_preview_layout
|
80
|
+
end
|
81
|
+
|
82
|
+
prepend_application_view_paths if layout_declaration[:layout].present? && prepend_views
|
83
|
+
|
84
|
+
layout_declaration
|
85
|
+
end
|
86
|
+
|
64
87
|
def prepend_application_view_paths
|
65
88
|
prepend_view_path Rails.root.join("app/views") if defined?(Rails.root)
|
66
89
|
end
|
@@ -1 +1,5 @@
|
|
1
|
-
|
1
|
+
<% if ViewComponent::Base.render_monkey_patch_enabled || Rails.version.to_f >= 6.1 %>
|
2
|
+
<%= render(@render_args[:component], @render_args[:args], &@render_args[:block])%>
|
3
|
+
<% else %>
|
4
|
+
<%= render_component(@render_args[:component], &@render_args[:block])%>
|
5
|
+
<% end %>
|
data/lib/view_component/base.rb
CHANGED
@@ -12,6 +12,8 @@ module ViewComponent
|
|
12
12
|
include ActiveSupport::Configurable
|
13
13
|
include ViewComponent::Previewable
|
14
14
|
|
15
|
+
ViewContextCalledBeforeRenderError = Class.new(StandardError)
|
16
|
+
|
15
17
|
# For CSRF authenticity tokens in forms
|
16
18
|
delegate :form_authenticity_token, :protect_against_forgery?, :config, to: :helpers
|
17
19
|
|
@@ -108,17 +110,19 @@ module ViewComponent
|
|
108
110
|
end
|
109
111
|
|
110
112
|
def controller
|
113
|
+
raise ViewContextCalledBeforeRenderError, "`controller` can only be called at render time." if view_context.nil?
|
111
114
|
@controller ||= view_context.controller
|
112
115
|
end
|
113
116
|
|
114
117
|
# Provides a proxy to access helper methods from the context of the current controller
|
115
118
|
def helpers
|
119
|
+
raise ViewContextCalledBeforeRenderError, "`helpers` can only be called at render time." if view_context.nil?
|
116
120
|
@helpers ||= controller.view_context
|
117
121
|
end
|
118
122
|
|
119
|
-
#
|
123
|
+
# Exposes .virutal_path as an instance method
|
120
124
|
def virtual_path
|
121
|
-
self.class.
|
125
|
+
self.class.virtual_path
|
122
126
|
end
|
123
127
|
|
124
128
|
# For caching, such as #cache_if
|
@@ -166,7 +170,7 @@ module ViewComponent
|
|
166
170
|
mattr_accessor :render_monkey_patch_enabled, instance_writer: false, default: true
|
167
171
|
|
168
172
|
class << self
|
169
|
-
attr_accessor :source_location
|
173
|
+
attr_accessor :source_location, :virtual_path
|
170
174
|
|
171
175
|
# Render a component collection.
|
172
176
|
def with_collection(collection, **args)
|
@@ -179,8 +183,13 @@ module ViewComponent
|
|
179
183
|
end
|
180
184
|
|
181
185
|
def inherited(child)
|
182
|
-
#
|
183
|
-
|
186
|
+
# Compile so child will inherit compiled `call_*` template methods that
|
187
|
+
# `compile` defines
|
188
|
+
compile
|
189
|
+
|
190
|
+
# If Rails application is loaded, add application url_helpers to the component context
|
191
|
+
# we need to check this to use this gem as a dependency
|
192
|
+
if defined?(Rails) && Rails.application
|
184
193
|
child.include Rails.application.routes.url_helpers unless child < Rails.application.routes.url_helpers
|
185
194
|
end
|
186
195
|
|
@@ -189,6 +198,9 @@ module ViewComponent
|
|
189
198
|
# has been re-defined by the consuming application, likely in ApplicationComponent.
|
190
199
|
child.source_location = caller_locations(1, 10).reject { |l| l.label == "inherited" }[0].absolute_path
|
191
200
|
|
201
|
+
# Removes the first part of the path and the extension.
|
202
|
+
child.virtual_path = child.source_location.gsub(%r{(.*app/components)|(\.rb)}, "")
|
203
|
+
|
192
204
|
# Clone slot configuration into child class
|
193
205
|
# see #test_slots_pollution
|
194
206
|
child.slots = self.slots.clone
|
@@ -378,17 +390,17 @@ module ViewComponent
|
|
378
390
|
|
379
391
|
location_without_extension = source_location.chomp(File.extname(source_location))
|
380
392
|
|
381
|
-
|
393
|
+
extensions = ActionView::Template.template_handler_extensions.join(",")
|
382
394
|
|
383
|
-
# view files in the same directory as
|
384
|
-
sidecar_files = Dir["#{location_without_extension}.*{#{
|
395
|
+
# view files in the same directory as the component
|
396
|
+
sidecar_files = Dir["#{location_without_extension}.*{#{extensions}}"]
|
385
397
|
|
386
398
|
# view files in a directory named like the component
|
387
399
|
directory = File.dirname(source_location)
|
388
400
|
filename = File.basename(source_location, ".rb")
|
389
401
|
component_name = name.demodulize.underscore
|
390
402
|
|
391
|
-
sidecar_directory_files = Dir["#{directory}/#{component_name}/#{filename}.*{#{
|
403
|
+
sidecar_directory_files = Dir["#{directory}/#{component_name}/#{filename}.*{#{extensions}}"]
|
392
404
|
|
393
405
|
(sidecar_files - [source_location] + sidecar_directory_files)
|
394
406
|
end
|
@@ -34,8 +34,8 @@ module ViewComponent
|
|
34
34
|
initializer "view_component.set_autoload_paths" do |app|
|
35
35
|
options = app.config.view_component
|
36
36
|
|
37
|
-
if options.show_previews && options.
|
38
|
-
ActiveSupport::Dependencies.autoload_paths
|
37
|
+
if options.show_previews && !options.preview_paths.empty?
|
38
|
+
ActiveSupport::Dependencies.autoload_paths.concat(options.preview_paths)
|
39
39
|
end
|
40
40
|
end
|
41
41
|
|
@@ -24,6 +24,8 @@ module ViewComponent # :nodoc:
|
|
24
24
|
}
|
25
25
|
end
|
26
26
|
|
27
|
+
alias_method :render_component, :render
|
28
|
+
|
27
29
|
class << self
|
28
30
|
# Returns all component preview classes.
|
29
31
|
def all
|
@@ -42,21 +44,11 @@ module ViewComponent # :nodoc:
|
|
42
44
|
result.merge(layout: @layout)
|
43
45
|
end
|
44
46
|
|
45
|
-
# Returns the component object class associated to the preview.
|
46
|
-
def component
|
47
|
-
name.chomp("Preview").constantize
|
48
|
-
end
|
49
|
-
|
50
47
|
# Returns all of the available examples for the component preview.
|
51
48
|
def examples
|
52
49
|
public_instance_methods(false).map(&:to_s).sort
|
53
50
|
end
|
54
51
|
|
55
|
-
# Returns +true+ if the example of the component preview exists.
|
56
|
-
def example_exists?(example)
|
57
|
-
examples.include?(example)
|
58
|
-
end
|
59
|
-
|
60
52
|
# Returns +true+ if the preview exists.
|
61
53
|
def exists?(preview)
|
62
54
|
all.any? { |p| p.preview_name == preview }
|
@@ -102,10 +94,6 @@ module ViewComponent # :nodoc:
|
|
102
94
|
def preview_paths
|
103
95
|
Base.preview_paths
|
104
96
|
end
|
105
|
-
|
106
|
-
def show_previews
|
107
|
-
Base.show_previews
|
108
|
-
end
|
109
97
|
end
|
110
98
|
end
|
111
99
|
end
|
@@ -7,6 +7,14 @@ module ViewComponent # :nodoc:
|
|
7
7
|
extend ActiveSupport::Concern
|
8
8
|
|
9
9
|
included do
|
10
|
+
# Set a custom default preview layout through app configuration:
|
11
|
+
#
|
12
|
+
# config.view_component.default_preview_layout = "component_preview"
|
13
|
+
#
|
14
|
+
# This affects preview index pages as well as individual component previews
|
15
|
+
#
|
16
|
+
mattr_accessor :default_preview_layout, instance_writer: false
|
17
|
+
|
10
18
|
# Set the location of component previews through app configuration:
|
11
19
|
#
|
12
20
|
# config.view_component.preview_paths << "#{Rails.root}/lib/component_previews"
|
@@ -14,7 +14,11 @@ module ViewComponent
|
|
14
14
|
assert_no_selector("body")
|
15
15
|
end
|
16
16
|
rescue LoadError
|
17
|
+
# We don't have a test case for running an application without capybara installed.
|
18
|
+
# It's probably fine to leave this without coverage.
|
19
|
+
# :nocov:
|
17
20
|
warn "WARNING in `ViewComponent::TestHelpers`: You must add `capybara` to your Gemfile to use Capybara assertions." if ENV["DEBUG"]
|
21
|
+
# :nocov:
|
18
22
|
end
|
19
23
|
|
20
24
|
attr_reader :rendered_component
|
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.19.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- GitHub Open Source
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-
|
11
|
+
date: 2020-09-21 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -30,6 +30,20 @@ dependencies:
|
|
30
30
|
- - "<"
|
31
31
|
- !ruby/object:Gem::Version
|
32
32
|
version: '7.0'
|
33
|
+
- !ruby/object:Gem::Dependency
|
34
|
+
name: benchmark-ips
|
35
|
+
requirement: !ruby/object:Gem::Requirement
|
36
|
+
requirements:
|
37
|
+
- - "~>"
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
version: 2.8.2
|
40
|
+
type: :development
|
41
|
+
prerelease: false
|
42
|
+
version_requirements: !ruby/object:Gem::Requirement
|
43
|
+
requirements:
|
44
|
+
- - "~>"
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: 2.8.2
|
33
47
|
- !ruby/object:Gem::Dependency
|
34
48
|
name: bundler
|
35
49
|
requirement: !ruby/object:Gem::Requirement
|
@@ -157,20 +171,20 @@ dependencies:
|
|
157
171
|
- !ruby/object:Gem::Version
|
158
172
|
version: 0.18.0
|
159
173
|
- !ruby/object:Gem::Dependency
|
160
|
-
name: simplecov-
|
174
|
+
name: simplecov-console
|
161
175
|
requirement: !ruby/object:Gem::Requirement
|
162
176
|
requirements:
|
163
177
|
- - "~>"
|
164
178
|
- !ruby/object:Gem::Version
|
165
|
-
version:
|
179
|
+
version: 0.7.2
|
166
180
|
type: :development
|
167
181
|
prerelease: false
|
168
182
|
version_requirements: !ruby/object:Gem::Requirement
|
169
183
|
requirements:
|
170
184
|
- - "~>"
|
171
185
|
- !ruby/object:Gem::Version
|
172
|
-
version:
|
173
|
-
description:
|
186
|
+
version: 0.7.2
|
187
|
+
description:
|
174
188
|
email:
|
175
189
|
- opensource+view_component@github.com
|
176
190
|
executables: []
|
@@ -222,7 +236,7 @@ licenses:
|
|
222
236
|
- MIT
|
223
237
|
metadata:
|
224
238
|
allowed_push_host: https://rubygems.org
|
225
|
-
post_install_message:
|
239
|
+
post_install_message:
|
226
240
|
rdoc_options: []
|
227
241
|
require_paths:
|
228
242
|
- lib
|
@@ -238,7 +252,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
238
252
|
version: '0'
|
239
253
|
requirements: []
|
240
254
|
rubygems_version: 3.1.2
|
241
|
-
signing_key:
|
255
|
+
signing_key:
|
242
256
|
specification_version: 4
|
243
257
|
summary: View components for Rails
|
244
258
|
test_files: []
|