view_component 2.47.0 → 2.48.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.
Potentially problematic release.
This version of view_component might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/docs/CHANGELOG.md +59 -1
- data/lib/rails/generators/abstract_generator.rb +5 -1
- data/lib/rails/generators/locale/component_generator.rb +1 -1
- data/lib/rails/generators/stimulus/component_generator.rb +1 -1
- data/lib/rails/generators/tailwindcss/component_generator.rb +11 -0
- data/lib/rails/generators/tailwindcss/templates/component.html.erb.tt +1 -0
- data/lib/view_component/base.rb +11 -2
- data/lib/view_component/collection.rb +20 -6
- data/lib/view_component/compiler.rb +47 -12
- data/lib/view_component/engine.rb +8 -0
- data/lib/view_component/test_helpers.rb +7 -1
- data/lib/view_component/version.rb +1 -1
- metadata +23 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3abce9e08dcb71614178ed68b9c8443211ff78790911057752d8fda6fbb194b7
|
4
|
+
data.tar.gz: 3ac0a8ff1d7cafd2eb12e04a24f1d8f3362675833e4fda780bc238b8fc5ed41f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: dba31d0d37e73b7a1e26863d167f5d1eaefb8c5f53d9f542e47667090802b5f53b5c6b9c4b0a9188bf76f42d375c5d7a2cd3024065620aa9ff40b15911706cb8
|
7
|
+
data.tar.gz: f329872b25f36fe8fa0d018c2a5847ed0b6e47b095d16a27e89d2b0c7180f938d09730d0868405483a8e7c4fe4075afed56927a018b7a273ac4c94950d174fac
|
data/docs/CHANGELOG.md
CHANGED
@@ -7,6 +7,60 @@ title: Changelog
|
|
7
7
|
|
8
8
|
## main
|
9
9
|
|
10
|
+
## 2.48.0
|
11
|
+
|
12
|
+
* Correct path in example test command in Contributing docs.
|
13
|
+
|
14
|
+
*Mark Wilkinson*
|
15
|
+
|
16
|
+
* Update link to GOV.UK Components library in the resources list.
|
17
|
+
|
18
|
+
*Peter Yates*
|
19
|
+
|
20
|
+
* Add Lookbook to Resources docs page.
|
21
|
+
|
22
|
+
*Mark Perkins*
|
23
|
+
|
24
|
+
* Add blocking compiler mode for use in Rails development and testing modes, improving thread safety.
|
25
|
+
|
26
|
+
*Horia Radu*
|
27
|
+
|
28
|
+
* Add generators to support `tailwindcss-rails`.
|
29
|
+
|
30
|
+
*Dino Maric*, *Hans Lemuet*
|
31
|
+
|
32
|
+
* Add a namespaced component example to docs.
|
33
|
+
|
34
|
+
*Hans Lemuet*
|
35
|
+
|
36
|
+
* Setup `Appraisal` to add flexibility when testing ViewComponent against multiple Rails versions.
|
37
|
+
|
38
|
+
*Hans Lemuet*
|
39
|
+
|
40
|
+
* Return correct values for `request.path` and `request.query_string` methods when using the `with_request_url` test helper.
|
41
|
+
|
42
|
+
*Vasiliy Matyushin*
|
43
|
+
|
44
|
+
* Improve style in generators docs.
|
45
|
+
|
46
|
+
*Hans Lemuet*
|
47
|
+
|
48
|
+
* Correctly type Ruby version strings and update Rails versions used in CI configuration.
|
49
|
+
|
50
|
+
*Hans Lemuet*
|
51
|
+
|
52
|
+
* Make `ViewComponent::Collection` act like a collection of view components.
|
53
|
+
|
54
|
+
*Sammy Henningsson*
|
55
|
+
|
56
|
+
* Update `@param` of `#render_inline` to include `ViewComponent::Collection`.
|
57
|
+
|
58
|
+
*Yutaka Kamei*
|
59
|
+
|
60
|
+
* Add Wecasa to users list.
|
61
|
+
|
62
|
+
*Mohamed Ziata*
|
63
|
+
|
10
64
|
## 2.47.0
|
11
65
|
|
12
66
|
* Display preview source on previews that exclusively use templates.
|
@@ -17,7 +71,7 @@ title: Changelog
|
|
17
71
|
|
18
72
|
*Simon Fish*
|
19
73
|
|
20
|
-
* Add WEBrick as a depenency to the
|
74
|
+
* Add WEBrick as a depenency to the application.
|
21
75
|
|
22
76
|
*Connor McQuillan*
|
23
77
|
|
@@ -79,6 +133,10 @@ title: Changelog
|
|
79
133
|
|
80
134
|
*Bob Maerten*
|
81
135
|
|
136
|
+
* Add config option `config.view_component.generate_sidecar` to always generate in the sidecar directory.
|
137
|
+
|
138
|
+
*Gleydson Tavares*
|
139
|
+
|
82
140
|
## 2.46.0
|
83
141
|
|
84
142
|
* Add thread safety to the compiler.
|
@@ -15,7 +15,7 @@ module ViewComponent
|
|
15
15
|
end
|
16
16
|
|
17
17
|
def destination_directory
|
18
|
-
if
|
18
|
+
if sidecar?
|
19
19
|
File.join(component_path, class_path, destination_file_name)
|
20
20
|
else
|
21
21
|
File.join(component_path, class_path)
|
@@ -42,5 +42,9 @@ module ViewComponent
|
|
42
42
|
gsub("/", "--")
|
43
43
|
end
|
44
44
|
end
|
45
|
+
|
46
|
+
def sidecar?
|
47
|
+
options["sidecar"] || ViewComponent::Base.generate_sidecar
|
48
|
+
end
|
45
49
|
end
|
46
50
|
end
|
@@ -35,7 +35,7 @@ module Locale
|
|
35
35
|
|
36
36
|
def destination(locale = nil)
|
37
37
|
extention = ".#{locale}" if locale
|
38
|
-
if
|
38
|
+
if sidecar?
|
39
39
|
File.join(component_path, class_path, "#{file_name}_component", "#{file_name}_component#{extention}.yml")
|
40
40
|
else
|
41
41
|
File.join(component_path, class_path, "#{file_name}_component#{extention}.yml")
|
@@ -23,7 +23,7 @@ module Stimulus
|
|
23
23
|
private
|
24
24
|
|
25
25
|
def destination
|
26
|
-
if
|
26
|
+
if sidecar?
|
27
27
|
File.join(component_path, class_path, "#{file_name}_component", "#{file_name}_component_controller.js")
|
28
28
|
else
|
29
29
|
File.join(component_path, class_path, "#{file_name}_component_controller.js")
|
@@ -0,0 +1,11 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "rails/generators/erb/component_generator"
|
4
|
+
|
5
|
+
module Tailwindcss
|
6
|
+
module Generators
|
7
|
+
class ComponentGenerator < Erb::Generators::ComponentGenerator
|
8
|
+
source_root File.expand_path("templates", __dir__)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
<div<%= data_attributes %>>Add <%= class_name %> template here</div>
|
data/lib/view_component/base.rb
CHANGED
@@ -303,6 +303,7 @@ module ViewComponent
|
|
303
303
|
# config.view_component.view_component_path = "app/my_components"
|
304
304
|
#
|
305
305
|
# Defaults to `app/components`.
|
306
|
+
#
|
306
307
|
mattr_accessor :view_component_path, instance_writer: false, default: "app/components"
|
307
308
|
|
308
309
|
# Parent class for generated components
|
@@ -310,8 +311,16 @@ module ViewComponent
|
|
310
311
|
# config.view_component.component_parent_class = "MyBaseComponent"
|
311
312
|
#
|
312
313
|
# Defaults to "ApplicationComponent" if defined, "ViewComponent::Base" otherwise.
|
313
|
-
|
314
|
-
|
314
|
+
#
|
315
|
+
mattr_accessor :component_parent_class, instance_writer: false
|
316
|
+
|
317
|
+
# Always generate a component with a sidecar directory:
|
318
|
+
#
|
319
|
+
# config.view_component.generate_sidecar = true
|
320
|
+
#
|
321
|
+
# Defaults to `false`.
|
322
|
+
#
|
323
|
+
mattr_accessor :generate_sidecar, instance_writer: false, default: false
|
315
324
|
|
316
325
|
class << self
|
317
326
|
# @private
|
@@ -4,20 +4,34 @@ require "action_view/renderer/collection_renderer" if Rails.version.to_f >= 6.1
|
|
4
4
|
|
5
5
|
module ViewComponent
|
6
6
|
class Collection
|
7
|
+
include Enumerable
|
7
8
|
attr_reader :component
|
8
9
|
|
9
10
|
delegate :format, to: :component
|
11
|
+
delegate :size, to: :@collection
|
10
12
|
|
11
13
|
def render_in(view_context, &block)
|
14
|
+
components.map do |component|
|
15
|
+
component.render_in(view_context, &block)
|
16
|
+
end.join.html_safe # rubocop:disable Rails/OutputSafety
|
17
|
+
end
|
18
|
+
|
19
|
+
def components
|
20
|
+
return @components if defined? @components
|
21
|
+
|
12
22
|
iterator = ActionView::PartialIteration.new(@collection.size)
|
13
23
|
|
14
24
|
component.validate_collection_parameter!(validate_default: true)
|
15
25
|
|
16
|
-
@collection.map do |item|
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
end
|
26
|
+
@components = @collection.map do |item|
|
27
|
+
component.new(**component_options(item, iterator)).tap do |component|
|
28
|
+
iterator.iterate!
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def each(&block)
|
34
|
+
components.each(&block)
|
21
35
|
end
|
22
36
|
|
23
37
|
private
|
@@ -42,7 +56,7 @@ module ViewComponent
|
|
42
56
|
def component_options(item, iterator)
|
43
57
|
item_options = { component.collection_parameter => item }
|
44
58
|
item_options[component.collection_counter_parameter] = iterator.index + 1 if component.counter_argument_present?
|
45
|
-
item_options[component.collection_iteration_parameter] = iterator if component.iteration_argument_present?
|
59
|
+
item_options[component.collection_iteration_parameter] = iterator.dup if component.iteration_argument_present?
|
46
60
|
|
47
61
|
@options.merge(item_options)
|
48
62
|
end
|
@@ -5,6 +5,15 @@ module ViewComponent
|
|
5
5
|
# Lock required to be obtained before compiling the component
|
6
6
|
attr_reader :__vc_compiler_lock
|
7
7
|
|
8
|
+
# Compiler mode. Can be either:
|
9
|
+
# * development (a blocking mode which ensures thread safety when redefining the `call` method for components,
|
10
|
+
# default in Rails development and test mode)
|
11
|
+
# * production (a non-blocking mode, default in Rails production mode)
|
12
|
+
DEVELOPMENT_MODE = :development
|
13
|
+
PRODUCTION_MODE = :production
|
14
|
+
|
15
|
+
class_attribute :mode, default: PRODUCTION_MODE
|
16
|
+
|
8
17
|
def initialize(component_class)
|
9
18
|
@component_class = component_class
|
10
19
|
@__vc_compiler_lock = Monitor.new
|
@@ -14,10 +23,14 @@ module ViewComponent
|
|
14
23
|
CompileCache.compiled?(component_class)
|
15
24
|
end
|
16
25
|
|
26
|
+
def development?
|
27
|
+
self.class.mode == DEVELOPMENT_MODE
|
28
|
+
end
|
29
|
+
|
17
30
|
def compile(raise_errors: false)
|
18
31
|
return if compiled?
|
19
32
|
|
20
|
-
|
33
|
+
with_lock do
|
21
34
|
CompileCache.invalidate_class!(component_class)
|
22
35
|
|
23
36
|
subclass_instance_methods = component_class.instance_methods(false)
|
@@ -57,10 +70,10 @@ module ViewComponent
|
|
57
70
|
end
|
58
71
|
|
59
72
|
component_class.class_eval <<-RUBY, template[:path], -1
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
73
|
+
def #{method_name}
|
74
|
+
@output_buffer = ActionView::OutputBuffer.new
|
75
|
+
#{compiled_template(template[:path])}
|
76
|
+
end
|
64
77
|
RUBY
|
65
78
|
end
|
66
79
|
|
@@ -72,6 +85,14 @@ module ViewComponent
|
|
72
85
|
end
|
73
86
|
end
|
74
87
|
|
88
|
+
def with_lock(&block)
|
89
|
+
if development?
|
90
|
+
__vc_compiler_lock.synchronize(&block)
|
91
|
+
else
|
92
|
+
block.call
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
75
96
|
private
|
76
97
|
|
77
98
|
attr_reader :component_class
|
@@ -85,16 +106,30 @@ module ViewComponent
|
|
85
106
|
"elsif variant.to_sym == :#{variant}\n #{call_method_name(variant)}"
|
86
107
|
end.join("\n")
|
87
108
|
|
88
|
-
|
109
|
+
body = <<-RUBY
|
110
|
+
if variant.nil?
|
111
|
+
call
|
112
|
+
#{variant_elsifs}
|
113
|
+
else
|
114
|
+
call
|
115
|
+
end
|
116
|
+
RUBY
|
117
|
+
|
118
|
+
if development?
|
119
|
+
component_class.class_eval <<-RUBY, __FILE__, __LINE__ + 1
|
89
120
|
def render_template_for(variant = nil)
|
90
|
-
|
91
|
-
|
92
|
-
#{variant_elsifs}
|
93
|
-
else
|
94
|
-
call
|
121
|
+
self.class.compiler.with_lock do
|
122
|
+
#{body}
|
95
123
|
end
|
96
124
|
end
|
97
|
-
|
125
|
+
RUBY
|
126
|
+
else
|
127
|
+
component_class.class_eval <<-RUBY, __FILE__, __LINE__ + 1
|
128
|
+
def render_template_for(variant = nil)
|
129
|
+
#{body}
|
130
|
+
end
|
131
|
+
RUBY
|
132
|
+
end
|
98
133
|
end
|
99
134
|
|
100
135
|
def template_errors
|
@@ -115,6 +115,14 @@ module ViewComponent
|
|
115
115
|
end
|
116
116
|
end
|
117
117
|
|
118
|
+
initializer "compiler mode" do |app|
|
119
|
+
ViewComponent::Compiler.mode = if Rails.env.development? || Rails.env.test?
|
120
|
+
ViewComponent::Compiler::DEVELOPMENT_MODE
|
121
|
+
else
|
122
|
+
ViewComponent::Compiler::PRODUCTION_MODE
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
118
126
|
config.after_initialize do |app|
|
119
127
|
options = app.config.view_component
|
120
128
|
|
@@ -38,7 +38,7 @@ module ViewComponent
|
|
38
38
|
# assert_text("Hello, World!")
|
39
39
|
# ```
|
40
40
|
#
|
41
|
-
# @param component [ViewComponent::Base] The instance of the component to be rendered.
|
41
|
+
# @param component [ViewComponent::Base, ViewComponent::Collection] The instance of the component to be rendered.
|
42
42
|
# @return [Nokogiri::HTML]
|
43
43
|
def render_inline(component, **args, &block)
|
44
44
|
@rendered_component =
|
@@ -113,16 +113,22 @@ module ViewComponent
|
|
113
113
|
#
|
114
114
|
# @param path [String] The path to set for the current request.
|
115
115
|
def with_request_url(path)
|
116
|
+
old_request_path_info = request.path_info
|
116
117
|
old_request_path_parameters = request.path_parameters
|
117
118
|
old_request_query_parameters = request.query_parameters
|
119
|
+
old_request_query_string = request.query_string
|
118
120
|
old_controller = defined?(@controller) && @controller
|
119
121
|
|
122
|
+
request.path_info = path
|
120
123
|
request.path_parameters = Rails.application.routes.recognize_path(path)
|
121
124
|
request.set_header("action_dispatch.request.query_parameters", Rack::Utils.parse_query(path.split("?")[1]))
|
125
|
+
request.set_header(Rack::QUERY_STRING, path.split("?")[1])
|
122
126
|
yield
|
123
127
|
ensure
|
128
|
+
request.path_info = old_request_path_info
|
124
129
|
request.path_parameters = old_request_path_parameters
|
125
130
|
request.set_header("action_dispatch.request.query_parameters", old_request_query_parameters)
|
131
|
+
request.set_header(Rack::QUERY_STRING, old_request_query_string)
|
126
132
|
@controller = old_controller
|
127
133
|
end
|
128
134
|
|
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.48.0
|
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:
|
11
|
+
date: 2022-01-14 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -44,6 +44,20 @@ dependencies:
|
|
44
44
|
- - "~>"
|
45
45
|
- !ruby/object:Gem::Version
|
46
46
|
version: '1.0'
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: appraisal
|
49
|
+
requirement: !ruby/object:Gem::Requirement
|
50
|
+
requirements:
|
51
|
+
- - "~>"
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '2.4'
|
54
|
+
type: :development
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
requirements:
|
58
|
+
- - "~>"
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
version: '2.4'
|
47
61
|
- !ruby/object:Gem::Dependency
|
48
62
|
name: benchmark-ips
|
49
63
|
requirement: !ruby/object:Gem::Requirement
|
@@ -268,7 +282,7 @@ dependencies:
|
|
268
282
|
- - ">="
|
269
283
|
- !ruby/object:Gem::Version
|
270
284
|
version: '0'
|
271
|
-
description:
|
285
|
+
description:
|
272
286
|
email:
|
273
287
|
- opensource+view_component@github.com
|
274
288
|
executables: []
|
@@ -304,6 +318,8 @@ files:
|
|
304
318
|
- lib/rails/generators/slim/templates/component.html.slim.tt
|
305
319
|
- lib/rails/generators/stimulus/component_generator.rb
|
306
320
|
- lib/rails/generators/stimulus/templates/component_controller.js.tt
|
321
|
+
- lib/rails/generators/tailwindcss/component_generator.rb
|
322
|
+
- lib/rails/generators/tailwindcss/templates/component.html.erb.tt
|
307
323
|
- lib/rails/generators/test_unit/component_generator.rb
|
308
324
|
- lib/rails/generators/test_unit/templates/component_test.rb.tt
|
309
325
|
- lib/view_component.rb
|
@@ -342,7 +358,7 @@ licenses:
|
|
342
358
|
- MIT
|
343
359
|
metadata:
|
344
360
|
allowed_push_host: https://rubygems.org
|
345
|
-
post_install_message:
|
361
|
+
post_install_message:
|
346
362
|
rdoc_options: []
|
347
363
|
require_paths:
|
348
364
|
- lib
|
@@ -357,8 +373,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
357
373
|
- !ruby/object:Gem::Version
|
358
374
|
version: '0'
|
359
375
|
requirements: []
|
360
|
-
rubygems_version: 3.1.
|
361
|
-
signing_key:
|
376
|
+
rubygems_version: 3.1.4
|
377
|
+
signing_key:
|
362
378
|
specification_version: 4
|
363
379
|
summary: View components for Rails
|
364
380
|
test_files: []
|