actionview-component 1.5.1 → 1.6.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/ISSUE_TEMPLATE +30 -0
- data/.github/PULL_REQUEST_TEMPLATE +19 -0
- data/.gitignore +1 -0
- data/CHANGELOG.md +86 -0
- data/Gemfile.lock +13 -2
- data/README.md +49 -9
- data/actionview-component.gemspec +1 -0
- data/lib/action_view/component.rb +19 -2
- data/lib/action_view/component/base.rb +22 -19
- data/lib/action_view/component/conversion.rb +11 -0
- data/lib/action_view/component/preview.rb +8 -27
- data/lib/action_view/component/previewable.rb +27 -0
- data/lib/action_view/component/railtie.rb +16 -10
- data/lib/action_view/component/render_monkey_patch.rb +29 -0
- data/lib/action_view/component/test_case.rb +11 -0
- data/lib/action_view/component/test_helpers.rb +1 -1
- data/lib/action_view/component/version.rb +2 -2
- data/lib/rails/generators/rspec/component_generator.rb +19 -0
- data/lib/rails/generators/rspec/templates/component_spec.rb.tt +13 -0
- data/lib/rails/generators/test_unit/templates/component_test.rb.tt +2 -4
- metadata +24 -3
- data/lib/action_view/component/monkey_patch.rb +0 -27
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 57dd1d0375f05f3a5849670716be000a0c8074f4ae63b1d422278006b07e5b32
|
4
|
+
data.tar.gz: 42309cc4774f3405e338cd48a84bc6ee6619ffa3306d98ab8432e8a196d6cb5f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: fdaad351b7db8bb6aab8e94294c221c50993cdd851fac8d43f64c3628627b5652be8fd3bb93f450467f74401433d4d3fffea560ca9ddc8c78fe645fbe0596056
|
7
|
+
data.tar.gz: f75561cba609fd4eecf3ac958a0cf9ef9ee9300772c3016749cf3ab5bea5e5ac5f4c2005f47623587e5a80fb9c9d71a18aeaad33fc9d89ba8c1123191dc0345b
|
@@ -0,0 +1,30 @@
|
|
1
|
+
<!-- **** Filing a Feature Request? Include these sections. **** -->
|
2
|
+
|
3
|
+
### Feature request
|
4
|
+
<!-- Provide a summary of the behavior. -->
|
5
|
+
|
6
|
+
### Motivation
|
7
|
+
|
8
|
+
<!-- What would you like to do with this feature? Can you provide
|
9
|
+
context or references to similar behavior in other libraries. -->
|
10
|
+
|
11
|
+
|
12
|
+
|
13
|
+
|
14
|
+
|
15
|
+
<!-- **** Filing a Bug Report? Include these sections. **** -->
|
16
|
+
|
17
|
+
### Steps to reproduce
|
18
|
+
<!-- Provide an series of steps or, better yet, a link to a repo to
|
19
|
+
demonstrate the bug you've identified. -->
|
20
|
+
|
21
|
+
### Expected behavior
|
22
|
+
<!-- Tell us what should happen -->
|
23
|
+
|
24
|
+
### Actual behavior
|
25
|
+
<!-- Tell us what happens instead -->
|
26
|
+
|
27
|
+
### System configuration
|
28
|
+
**Rails version**:
|
29
|
+
|
30
|
+
**Ruby version**:
|
@@ -0,0 +1,19 @@
|
|
1
|
+
<!-- https://github.com/github/actionview-component/blob/master/CONTRIBUTING.md#submitting-a-pull-request -->
|
2
|
+
|
3
|
+
### Summary
|
4
|
+
|
5
|
+
<!-- Provide a general description of the code changes in your pull
|
6
|
+
request... were there any bugs you had fixed? If so, mention them. If
|
7
|
+
these bugs have open GitHub issues, be sure to tag them here as well,
|
8
|
+
to keep the conversation linked together. -->
|
9
|
+
|
10
|
+
### Other Information
|
11
|
+
|
12
|
+
<!-- If there's anything else that's important and relevant to your pull
|
13
|
+
request, mention that information here. This could include
|
14
|
+
benchmarks, or other information.
|
15
|
+
|
16
|
+
If you are updating any of the CHANGELOG files or are asked to update the
|
17
|
+
CHANGELOG files by reviewers, please add the CHANGELOG entry at the top of the file.
|
18
|
+
|
19
|
+
Thanks for contributing to actionview-component! -->
|
data/.gitignore
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,89 @@
|
|
1
|
+
# v1.6.2
|
2
|
+
|
3
|
+
* Fix Uninitialized Constant error.
|
4
|
+
|
5
|
+
*Jon Palmer*
|
6
|
+
|
7
|
+
* Add basic github issue and PR templates.
|
8
|
+
|
9
|
+
*Dylan Clark*
|
10
|
+
|
11
|
+
* Update readme phrasing around previews.
|
12
|
+
|
13
|
+
*Justin Coyne*
|
14
|
+
|
15
|
+
# v1.6.1
|
16
|
+
|
17
|
+
* Allow Previews to have no layout.
|
18
|
+
|
19
|
+
*Jon Palmer*
|
20
|
+
|
21
|
+
* Bump rack from 2.0.7 to 2.0.8.
|
22
|
+
|
23
|
+
*Dependabot*
|
24
|
+
|
25
|
+
* Compile components on application boot when eager loading is enabled.
|
26
|
+
|
27
|
+
*Joel Hawksley*
|
28
|
+
|
29
|
+
* Previews support content blocks.
|
30
|
+
|
31
|
+
*Cesario Uy*
|
32
|
+
|
33
|
+
* Follow Rails conventions. (refactor)
|
34
|
+
|
35
|
+
*Rainer Borene*
|
36
|
+
|
37
|
+
* Fix edge case issue with extracting variants from less conventional source_locations.
|
38
|
+
|
39
|
+
*Ryan Workman*
|
40
|
+
|
41
|
+
# v1.6.0
|
42
|
+
|
43
|
+
* Avoid dropping elements in the render_inline test helper.
|
44
|
+
|
45
|
+
*@dark-panda*
|
46
|
+
|
47
|
+
* Add test for helpers.asset_url.
|
48
|
+
|
49
|
+
*Christopher Coleman*
|
50
|
+
|
51
|
+
* Add rudimentary compatibility with better_html.
|
52
|
+
|
53
|
+
*Joel Hawksley*
|
54
|
+
|
55
|
+
* Template-less variants fall back to default template.
|
56
|
+
|
57
|
+
*Asger Behncke Jacobsen*, *Cesario Uy*
|
58
|
+
|
59
|
+
* Generated tests use new naming convention.
|
60
|
+
|
61
|
+
*Simon Træls Ravn*
|
62
|
+
|
63
|
+
* Eliminate sqlite dependency.
|
64
|
+
|
65
|
+
*Simon Dawson*
|
66
|
+
|
67
|
+
* Add support for rendering components via #to_component_class
|
68
|
+
|
69
|
+
*Vinicius Stock*
|
70
|
+
|
71
|
+
# v1.5.3
|
72
|
+
|
73
|
+
* Add support for RSpec to generators.
|
74
|
+
|
75
|
+
*Dylan Clark, Ryan Workman*
|
76
|
+
|
77
|
+
* Require controllers as part of setting autoload paths.
|
78
|
+
|
79
|
+
*Joel Hawksley*
|
80
|
+
|
81
|
+
# v1.5.2
|
82
|
+
|
83
|
+
* Disable eager loading initializer.
|
84
|
+
|
85
|
+
*Kasper Meyer*
|
86
|
+
|
1
87
|
# v1.5.1
|
2
88
|
|
3
89
|
* Update railties class to work with Rails 6.
|
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
actionview-component (1.
|
4
|
+
actionview-component (1.6.2)
|
5
5
|
|
6
6
|
GEM
|
7
7
|
remote: https://rubygems.org/
|
@@ -62,6 +62,14 @@ GEM
|
|
62
62
|
tzinfo (~> 1.1)
|
63
63
|
zeitwerk (~> 2.1, >= 2.1.8)
|
64
64
|
ast (2.4.0)
|
65
|
+
better_html (1.0.14)
|
66
|
+
actionview (>= 4.0)
|
67
|
+
activesupport (>= 4.0)
|
68
|
+
ast (~> 2.0)
|
69
|
+
erubi (~> 1.4)
|
70
|
+
html_tokenizer (~> 0.0.6)
|
71
|
+
parser (>= 2.4)
|
72
|
+
smart_properties
|
65
73
|
builder (3.2.3)
|
66
74
|
concurrent-ruby (1.1.5)
|
67
75
|
crass (1.0.5)
|
@@ -71,6 +79,7 @@ GEM
|
|
71
79
|
haml (5.1.2)
|
72
80
|
temple (>= 0.8.0)
|
73
81
|
tilt
|
82
|
+
html_tokenizer (0.0.7)
|
74
83
|
i18n (1.6.0)
|
75
84
|
concurrent-ruby (~> 1.0)
|
76
85
|
jaro_winkler (1.5.3)
|
@@ -92,7 +101,7 @@ GEM
|
|
92
101
|
parallel (1.17.0)
|
93
102
|
parser (2.6.3.0)
|
94
103
|
ast (~> 2.4.0)
|
95
|
-
rack (2.0.
|
104
|
+
rack (2.0.8)
|
96
105
|
rack-test (1.1.0)
|
97
106
|
rack (>= 1.0, < 3)
|
98
107
|
rails (6.0.0)
|
@@ -139,6 +148,7 @@ GEM
|
|
139
148
|
slim (4.0.1)
|
140
149
|
temple (>= 0.7.6, < 0.9)
|
141
150
|
tilt (>= 2.0.6, < 2.1)
|
151
|
+
smart_properties (1.15.0)
|
142
152
|
sprockets (3.7.2)
|
143
153
|
concurrent-ruby (~> 1.0)
|
144
154
|
rack (> 1, < 3)
|
@@ -163,6 +173,7 @@ PLATFORMS
|
|
163
173
|
|
164
174
|
DEPENDENCIES
|
165
175
|
actionview-component!
|
176
|
+
better_html (~> 1)
|
166
177
|
bundler (>= 1.14)
|
167
178
|
haml (~> 5)
|
168
179
|
minitest (= 5.1.0)
|
data/README.md
CHANGED
@@ -7,7 +7,7 @@
|
|
7
7
|
|
8
8
|
This gem is meant to serve as a precursor to upstreaming the `ActionView::Component` class into Rails. It also serves to enable the usage of `ActionView::Component` in older versions of Rails.
|
9
9
|
|
10
|
-
Preliminary support for rendering components was merged into Rails `6.1.0.alpha` in https://github.com/rails/rails/pull/36388. Assuming `ActionView::Component` makes it into Rails
|
10
|
+
Preliminary support for rendering components was merged into Rails `6.1.0.alpha` in https://github.com/rails/rails/pull/36388. Assuming `ActionView::Component` makes it into Rails, this gem will then exist to serve as a backport.
|
11
11
|
|
12
12
|
## Design philosophy
|
13
13
|
|
@@ -32,7 +32,7 @@ $ bundle
|
|
32
32
|
In `config/application.rb`, add:
|
33
33
|
|
34
34
|
```bash
|
35
|
-
require "action_view/component"
|
35
|
+
require "action_view/component/railtie"
|
36
36
|
```
|
37
37
|
|
38
38
|
## Guide
|
@@ -163,6 +163,24 @@ Components can be rendered via:
|
|
163
163
|
|
164
164
|
`render(component: TestComponent, locals: { foo: :bar })`
|
165
165
|
|
166
|
+
**Rendering components through models**
|
167
|
+
|
168
|
+
Passing model instances will cause `render` to look for its respective component class.
|
169
|
+
|
170
|
+
The component is instantiated with the rendered model instance.
|
171
|
+
|
172
|
+
Example for a `Post` model:
|
173
|
+
|
174
|
+
`render(@post)`
|
175
|
+
|
176
|
+
```ruby
|
177
|
+
class PostComponent < ActionView::Component::Base
|
178
|
+
def initialize(post)
|
179
|
+
@post = post
|
180
|
+
end
|
181
|
+
end
|
182
|
+
```
|
183
|
+
|
166
184
|
The following syntax has been deprecated and will be removed in v2.0.0:
|
167
185
|
|
168
186
|
`render(TestComponent.new(foo: :bar))`
|
@@ -186,12 +204,10 @@ An error will be raised:
|
|
186
204
|
Components are unit tested directly. The `render_inline` test helper wraps the result in `Nokogiri.HTML`, allowing us to test the component above as:
|
187
205
|
|
188
206
|
```ruby
|
189
|
-
require "action_view/component/
|
190
|
-
|
191
|
-
class MyComponentTest < Minitest::Test
|
192
|
-
include ActionView::Component::TestHelpers
|
207
|
+
require "action_view/component/test_case"
|
193
208
|
|
194
|
-
|
209
|
+
class MyComponentTest < ActionView::Component::TestCase
|
210
|
+
test "render component" do
|
195
211
|
assert_equal(
|
196
212
|
%(<span title="my title">Hello, World!</span>),
|
197
213
|
render_inline(TestComponent, title: "my title") { "Hello, World!" }.to_html
|
@@ -207,7 +223,7 @@ In general, we’ve found it makes the most sense to test components based on th
|
|
207
223
|
To test a specific variant you can wrap your test with the `with_variant` helper method as:
|
208
224
|
|
209
225
|
```ruby
|
210
|
-
|
226
|
+
test "render component for tablet" do
|
211
227
|
with_variant :tablet do
|
212
228
|
assert_equal(
|
213
229
|
%(<span title="my title">Hello, tablets!</span>),
|
@@ -218,7 +234,7 @@ end
|
|
218
234
|
```
|
219
235
|
|
220
236
|
### Previewing Components
|
221
|
-
`ActionView::Component::Preview`
|
237
|
+
`ActionView::Component::Preview` provides a way to see how components look by visiting a special URL that renders them.
|
222
238
|
In the previous example, the preview class for `TestComponent` would be called `TestComponentPreview` and located in `test/components/previews/test_component_preview.rb`.
|
223
239
|
To see the preview of the component with a given title, implement a method that renders the component.
|
224
240
|
You can define as many examples as you want:
|
@@ -260,6 +276,30 @@ For example, if you want to use `lib/component_previews`, set the following in `
|
|
260
276
|
config.action_view_component.preview_path = "#{Rails.root}/lib/component_previews"
|
261
277
|
```
|
262
278
|
|
279
|
+
### Setting up RSpec
|
280
|
+
|
281
|
+
If you're using RSpec, you can configure component specs to have access to test helpers. Add the following to
|
282
|
+
`spec/rails_helper.rb`:
|
283
|
+
|
284
|
+
```ruby
|
285
|
+
require "action_view/component/test_helpers"
|
286
|
+
|
287
|
+
RSpec.configure do |config|
|
288
|
+
# ...
|
289
|
+
|
290
|
+
# Ensure that the test helpers are available in component specs
|
291
|
+
config.include ActionView::Component::TestHelpers, type: :component
|
292
|
+
end
|
293
|
+
```
|
294
|
+
|
295
|
+
Specs created by the generator should now have access to test helpers like `render_inline`.
|
296
|
+
|
297
|
+
To use component previews, set the following in `config/application.rb`:
|
298
|
+
|
299
|
+
```ruby
|
300
|
+
config.action_view_component.preview_path = "#{Rails.root}/spec/components/previews"
|
301
|
+
```
|
302
|
+
|
263
303
|
## Frequently Asked Questions
|
264
304
|
|
265
305
|
### Can I use other templating languages besides ERB?
|
@@ -39,6 +39,7 @@ Gem::Specification.new do |spec|
|
|
39
39
|
spec.add_development_dependency "minitest", "= 5.1.0"
|
40
40
|
spec.add_development_dependency "haml", "~> 5"
|
41
41
|
spec.add_development_dependency "slim", "~> 4.0"
|
42
|
+
spec.add_development_dependency "better_html", "~> 1"
|
42
43
|
spec.add_development_dependency "rubocop", "= 0.74"
|
43
44
|
spec.add_development_dependency "rubocop-github", "~> 0.13.0"
|
44
45
|
end
|
@@ -1,5 +1,22 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require "
|
4
|
-
require "action_view
|
3
|
+
require "active_model"
|
4
|
+
require "action_view"
|
5
|
+
require "active_support/dependencies/autoload"
|
5
6
|
require "action_view/component/railtie"
|
7
|
+
|
8
|
+
module ActionView
|
9
|
+
module Component
|
10
|
+
extend ActiveSupport::Autoload
|
11
|
+
|
12
|
+
autoload :Base
|
13
|
+
autoload :Conversion
|
14
|
+
autoload :Preview
|
15
|
+
autoload :Previewable
|
16
|
+
autoload :TestHelpers
|
17
|
+
autoload :TestCase
|
18
|
+
autoload :RenderMonkeyPatch
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
ActiveModel::Conversion.include ActionView::Component::Conversion
|
@@ -1,21 +1,16 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require "active_model"
|
4
|
-
require "action_view"
|
5
3
|
require "active_support/configurable"
|
6
|
-
require_relative "preview"
|
7
4
|
|
8
5
|
module ActionView
|
9
6
|
module Component
|
10
7
|
class Base < ActionView::Base
|
11
8
|
include ActiveModel::Validations
|
12
9
|
include ActiveSupport::Configurable
|
13
|
-
include ActionView::Component::
|
10
|
+
include ActionView::Component::Previewable
|
14
11
|
|
15
12
|
delegate :form_authenticity_token, :protect_against_forgery?, to: :helpers
|
16
13
|
|
17
|
-
validate :variant_exists
|
18
|
-
|
19
14
|
# Entrypoint for rendering components. Called by ActionView::Base#render.
|
20
15
|
#
|
21
16
|
# view_context: ActionView context from calling view
|
@@ -94,12 +89,6 @@ module ActionView
|
|
94
89
|
|
95
90
|
private
|
96
91
|
|
97
|
-
def variant_exists
|
98
|
-
return if self.class.variants.include?(@variant) || @variant.nil?
|
99
|
-
|
100
|
-
errors.add(:variant, "'#{@variant}' has no template defined")
|
101
|
-
end
|
102
|
-
|
103
92
|
def request
|
104
93
|
@request ||= controller.request
|
105
94
|
end
|
@@ -114,13 +103,17 @@ module ActionView
|
|
114
103
|
end
|
115
104
|
|
116
105
|
def call_method_name(variant)
|
117
|
-
if variant.present?
|
106
|
+
if variant.present? && variants.include?(variant)
|
118
107
|
"call_#{variant}"
|
119
108
|
else
|
120
109
|
"call"
|
121
110
|
end
|
122
111
|
end
|
123
112
|
|
113
|
+
def has_initializer?
|
114
|
+
self.instance_method(:initialize).owner == self
|
115
|
+
end
|
116
|
+
|
124
117
|
def source_location
|
125
118
|
# Require #initialize to be defined so that we can use
|
126
119
|
# method#source_location to look up the file name
|
@@ -129,16 +122,20 @@ module ActionView
|
|
129
122
|
# If we were able to only support Ruby 2.7+,
|
130
123
|
# We could just use Module#const_source_location,
|
131
124
|
# rendering this unnecessary.
|
132
|
-
raise NotImplementedError.new("#{self} must implement #initialize.") unless
|
125
|
+
raise NotImplementedError.new("#{self} must implement #initialize.") unless has_initializer?
|
133
126
|
|
134
127
|
instance_method(:initialize).source_location[0]
|
135
128
|
end
|
136
129
|
|
130
|
+
def compiled?
|
131
|
+
@compiled && ActionView::Base.cache_template_loading
|
132
|
+
end
|
133
|
+
|
137
134
|
# Compile templates to instance methods, assuming they haven't been compiled already.
|
138
135
|
# We could in theory do this on app boot, at least in production environments.
|
139
136
|
# Right now this just compiles the first time the component is rendered.
|
140
137
|
def compile
|
141
|
-
return if
|
138
|
+
return if compiled?
|
142
139
|
|
143
140
|
validate_templates
|
144
141
|
|
@@ -164,18 +161,24 @@ module ActionView
|
|
164
161
|
end
|
165
162
|
|
166
163
|
def identifier
|
167
|
-
|
164
|
+
source_location
|
168
165
|
end
|
169
166
|
|
170
167
|
private
|
171
168
|
|
169
|
+
def matching_views_in_source_location
|
170
|
+
(Dir["#{source_location.sub(/#{File.extname(source_location)}$/, '')}.*{#{ActionView::Template.template_handler_extensions.join(',')}}"] - [source_location])
|
171
|
+
end
|
172
|
+
|
172
173
|
def templates
|
173
174
|
@templates ||=
|
174
|
-
|
175
|
+
matching_views_in_source_location.each_with_object([]) do |path, memo|
|
176
|
+
pieces = File.basename(path).split(".")
|
177
|
+
|
175
178
|
memo << {
|
176
179
|
path: path,
|
177
|
-
variant:
|
178
|
-
handler:
|
180
|
+
variant: pieces.second.split("+")[1]&.to_sym,
|
181
|
+
handler: pieces.last
|
179
182
|
}
|
180
183
|
end
|
181
184
|
end
|
@@ -1,37 +1,15 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require "active_support/concern"
|
4
3
|
require "active_support/descendants_tracker"
|
5
|
-
require_relative "test_helpers"
|
6
4
|
|
7
5
|
module ActionView
|
8
|
-
module Component
|
9
|
-
module Previews
|
10
|
-
extend ActiveSupport::Concern
|
11
|
-
|
12
|
-
included do
|
13
|
-
# Set the location of component previews through app configuration:
|
14
|
-
#
|
15
|
-
# config.action_view_component.preview_path = "#{Rails.root}/lib/component_previews"
|
16
|
-
#
|
17
|
-
mattr_accessor :preview_path, instance_writer: false
|
18
|
-
|
19
|
-
# Enable or disable component previews through app configuration:
|
20
|
-
#
|
21
|
-
# config.action_view_component.show_previews = true
|
22
|
-
#
|
23
|
-
# Defaults to +true+ for development environment
|
24
|
-
#
|
25
|
-
mattr_accessor :show_previews, instance_writer: false
|
26
|
-
end
|
27
|
-
end
|
28
|
-
|
6
|
+
module Component # :nodoc:
|
29
7
|
class Preview
|
30
8
|
extend ActiveSupport::DescendantsTracker
|
31
9
|
include ActionView::Component::TestHelpers
|
32
10
|
|
33
|
-
def render(component, *locals)
|
34
|
-
render_inline(component, *locals)
|
11
|
+
def render(component, *locals, &block)
|
12
|
+
render_inline(component, *locals, &block)
|
35
13
|
end
|
36
14
|
|
37
15
|
class << self
|
@@ -42,11 +20,14 @@ module ActionView
|
|
42
20
|
end
|
43
21
|
|
44
22
|
# Returns the html of the component in its layout
|
45
|
-
def call(example)
|
23
|
+
def call(example, layout: nil)
|
46
24
|
example_html = new.public_send(example)
|
25
|
+
if layout.nil?
|
26
|
+
layout = @layout.nil? ? "layouts/application" : @layout
|
27
|
+
end
|
47
28
|
|
48
29
|
Rails::ComponentExamplesController.render(template: "examples/show",
|
49
|
-
layout:
|
30
|
+
layout: layout,
|
50
31
|
assigns: { example: example_html })
|
51
32
|
end
|
52
33
|
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "active_support/concern"
|
4
|
+
|
5
|
+
module ActionView
|
6
|
+
module Component # :nodoc:
|
7
|
+
module Previewable
|
8
|
+
extend ActiveSupport::Concern
|
9
|
+
|
10
|
+
included do
|
11
|
+
# Set the location of component previews through app configuration:
|
12
|
+
#
|
13
|
+
# config.action_view_component.preview_path = "#{Rails.root}/lib/component_previews"
|
14
|
+
#
|
15
|
+
mattr_accessor :preview_path, instance_writer: false
|
16
|
+
|
17
|
+
# Enable or disable component previews through app configuration:
|
18
|
+
#
|
19
|
+
# config.action_view_component.show_previews = true
|
20
|
+
#
|
21
|
+
# Defaults to +true+ for development environment
|
22
|
+
#
|
23
|
+
mattr_accessor :show_previews, instance_writer: false
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -1,18 +1,13 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require "
|
4
|
-
require "
|
3
|
+
require "rails"
|
4
|
+
require "action_view/component"
|
5
5
|
|
6
6
|
module ActionView
|
7
7
|
module Component
|
8
8
|
class Railtie < Rails::Railtie # :nodoc:
|
9
9
|
config.action_view_component = ActiveSupport::OrderedOptions.new
|
10
10
|
|
11
|
-
# Disabled due to issues with ActionView::Component::Base not defining .logger
|
12
|
-
# initializer "action_view_component.logger" do
|
13
|
-
# ActiveSupport.on_load(:action_view_component) { self.logger ||= Rails.logger }
|
14
|
-
# end
|
15
|
-
|
16
11
|
initializer "action_view_component.set_configs" do |app|
|
17
12
|
options = app.config.action_view_component
|
18
13
|
|
@@ -28,6 +23,9 @@ module ActionView
|
|
28
23
|
end
|
29
24
|
|
30
25
|
initializer "action_view_component.set_autoload_paths" do |app|
|
26
|
+
require "railties/lib/rails/components_controller"
|
27
|
+
require "railties/lib/rails/component_examples_controller"
|
28
|
+
|
31
29
|
options = app.config.action_view_component
|
32
30
|
|
33
31
|
if options.show_previews && options.preview_path
|
@@ -35,15 +33,23 @@ module ActionView
|
|
35
33
|
end
|
36
34
|
end
|
37
35
|
|
36
|
+
initializer "action_view_component.eager_load_actions" do
|
37
|
+
ActiveSupport.on_load(:after_initialize) do
|
38
|
+
ActionView::Component::Base.descendants.each do |descendant|
|
39
|
+
descendant.compile if descendant.has_initializer? && config.eager_load
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
38
44
|
initializer "action_view_component.compile_config_methods" do
|
39
45
|
ActiveSupport.on_load(:action_view_component) do
|
40
46
|
config.compile_methods! if config.respond_to?(:compile_methods!)
|
41
47
|
end
|
42
48
|
end
|
43
49
|
|
44
|
-
initializer "action_view_component.
|
45
|
-
ActiveSupport.on_load(:
|
46
|
-
ActionView::
|
50
|
+
initializer "action_view_component.monkey_patch_render" do
|
51
|
+
ActiveSupport.on_load(:action_view) do
|
52
|
+
ActionView::Base.prepend ActionView::Component::RenderMonkeyPatch
|
47
53
|
end
|
48
54
|
end
|
49
55
|
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Monkey patch ActionView::Base#render to support ActionView::Component
|
4
|
+
#
|
5
|
+
# A version of this monkey patch was upstreamed in https://github.com/rails/rails/pull/36388
|
6
|
+
# We'll need to upstream an updated version of this eventually.
|
7
|
+
module ActionView
|
8
|
+
module Component
|
9
|
+
module RenderMonkeyPatch # :nodoc:
|
10
|
+
def render(options = {}, args = {}, &block)
|
11
|
+
if options.respond_to?(:render_in)
|
12
|
+
ActiveSupport::Deprecation.warn(
|
13
|
+
"passing component instances (`render MyComponent.new(foo: :bar)`) has been deprecated and will be removed in v2.0.0. Use `render MyComponent, foo: :bar` instead."
|
14
|
+
)
|
15
|
+
|
16
|
+
options.render_in(self, &block)
|
17
|
+
elsif options.is_a?(Class) && options < ActionView::Component::Base
|
18
|
+
options.new(args).render_in(self, &block)
|
19
|
+
elsif options.is_a?(Hash) && options.has_key?(:component)
|
20
|
+
options[:component].new(options[:locals]).render_in(self, &block)
|
21
|
+
elsif options.respond_to?(:to_component_class) && !options.to_component_class.nil?
|
22
|
+
options.to_component_class.new(options).render_in(self, &block)
|
23
|
+
else
|
24
|
+
super
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -4,7 +4,7 @@ module ActionView
|
|
4
4
|
module Component
|
5
5
|
module TestHelpers
|
6
6
|
def render_inline(component, **args, &block)
|
7
|
-
Nokogiri::HTML(controller.view_context.render(component, args, &block))
|
7
|
+
Nokogiri::HTML.fragment(controller.view_context.render(component, args, &block))
|
8
8
|
end
|
9
9
|
|
10
10
|
def controller
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Rspec
|
4
|
+
module Generators
|
5
|
+
class ComponentGenerator < ::Rails::Generators::NamedBase
|
6
|
+
source_root File.expand_path("templates", __dir__)
|
7
|
+
|
8
|
+
def create_test_file
|
9
|
+
template "component_spec.rb", File.join("spec/components", "#{file_name}_component_spec.rb")
|
10
|
+
end
|
11
|
+
|
12
|
+
private
|
13
|
+
|
14
|
+
def file_name
|
15
|
+
@_file_name ||= super.sub(/_component\z/i, "")
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
require "rails_helper"
|
2
|
+
|
3
|
+
RSpec.describe <%= class_name %>Component, type: :component do
|
4
|
+
pending "add some examples to (or delete) #{__FILE__}"
|
5
|
+
|
6
|
+
# it "renders something useful" do
|
7
|
+
# expect(
|
8
|
+
# render_inline(described_class, attr: "value") { "Hello, components!" }.css("p").to_html
|
9
|
+
# ).to include(
|
10
|
+
# "Hello, components!"
|
11
|
+
# )
|
12
|
+
# end
|
13
|
+
end
|
@@ -1,12 +1,10 @@
|
|
1
1
|
require "test_helper"
|
2
2
|
|
3
|
-
class <%= class_name %>ComponentTest <
|
4
|
-
include ActionView::Component::TestHelpers
|
5
|
-
|
3
|
+
class <%= class_name %>ComponentTest < ActionView::Component::TestCase
|
6
4
|
test "component renders something useful" do
|
7
5
|
# assert_equal(
|
8
6
|
# %(<span title="my title">Hello, components!</span>),
|
9
|
-
# render_inline(<%= class_name
|
7
|
+
# render_inline(<%= class_name %>Component, attr: "value") { "Hello, components!" }.css("span").to_html
|
10
8
|
# )
|
11
9
|
end
|
12
10
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: actionview-component
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.6.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- GitHub Open Source
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2020-01-06 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -80,6 +80,20 @@ dependencies:
|
|
80
80
|
- - "~>"
|
81
81
|
- !ruby/object:Gem::Version
|
82
82
|
version: '4.0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: better_html
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - "~>"
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '1'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - "~>"
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '1'
|
83
97
|
- !ruby/object:Gem::Dependency
|
84
98
|
name: rubocop
|
85
99
|
requirement: !ruby/object:Gem::Requirement
|
@@ -115,6 +129,8 @@ executables: []
|
|
115
129
|
extensions: []
|
116
130
|
extra_rdoc_files: []
|
117
131
|
files:
|
132
|
+
- ".github/ISSUE_TEMPLATE"
|
133
|
+
- ".github/PULL_REQUEST_TEMPLATE"
|
118
134
|
- ".github/workflows/ruby_on_rails.yml"
|
119
135
|
- ".gitignore"
|
120
136
|
- ".rubocop.yml"
|
@@ -129,15 +145,20 @@ files:
|
|
129
145
|
- actionview-component.gemspec
|
130
146
|
- lib/action_view/component.rb
|
131
147
|
- lib/action_view/component/base.rb
|
132
|
-
- lib/action_view/component/
|
148
|
+
- lib/action_view/component/conversion.rb
|
133
149
|
- lib/action_view/component/preview.rb
|
150
|
+
- lib/action_view/component/previewable.rb
|
134
151
|
- lib/action_view/component/railtie.rb
|
152
|
+
- lib/action_view/component/render_monkey_patch.rb
|
153
|
+
- lib/action_view/component/test_case.rb
|
135
154
|
- lib/action_view/component/test_helpers.rb
|
136
155
|
- lib/action_view/component/version.rb
|
137
156
|
- lib/rails/generators/component/USAGE
|
138
157
|
- lib/rails/generators/component/component_generator.rb
|
139
158
|
- lib/rails/generators/component/templates/component.html.erb.tt
|
140
159
|
- lib/rails/generators/component/templates/component.rb.tt
|
160
|
+
- lib/rails/generators/rspec/component_generator.rb
|
161
|
+
- lib/rails/generators/rspec/templates/component_spec.rb.tt
|
141
162
|
- lib/rails/generators/test_unit/component_generator.rb
|
142
163
|
- lib/rails/generators/test_unit/templates/component_test.rb.tt
|
143
164
|
- lib/railties/lib/rails.rb
|
@@ -1,27 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
# Monkey patch ActionView::Base#render to support ActionView::Component
|
4
|
-
#
|
5
|
-
# A version of this monkey patch was upstreamed in https://github.com/rails/rails/pull/36388
|
6
|
-
# We'll need to upstream an updated version of this eventually.
|
7
|
-
class ActionView::Base
|
8
|
-
module RenderMonkeyPatch
|
9
|
-
def render(options = {}, args = {}, &block)
|
10
|
-
if options.respond_to?(:render_in)
|
11
|
-
ActiveSupport::Deprecation.warn(
|
12
|
-
"passing component instances (`render MyComponent.new(foo: :bar)`) has been deprecated and will be removed in v2.0.0. Use `render MyComponent, foo: :bar` instead."
|
13
|
-
)
|
14
|
-
|
15
|
-
options.render_in(self, &block)
|
16
|
-
elsif options.is_a?(Class) && options < ActionView::Component::Base
|
17
|
-
options.new(args).render_in(self, &block)
|
18
|
-
elsif options.is_a?(Hash) && options.has_key?(:component)
|
19
|
-
options[:component].new(options[:locals]).render_in(self, &block)
|
20
|
-
else
|
21
|
-
super
|
22
|
-
end
|
23
|
-
end
|
24
|
-
end
|
25
|
-
|
26
|
-
prepend RenderMonkeyPatch
|
27
|
-
end
|