view_component 2.47.0 → 2.48.0
Sign up to get free protection for your applications and to get access to all the features.
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: []
|