actionview-component 1.3.4 → 1.5.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.
- checksums.yaml +4 -4
- data/.github/workflows/ruby_on_rails.yml +2 -6
- data/CHANGELOG.md +72 -0
- data/CONTRIBUTING.md +2 -1
- data/Gemfile.lock +5 -5
- data/README.md +78 -4
- data/actionview-component.gemspec +3 -2
- data/lib/action_view/component.rb +5 -0
- data/lib/action_view/component/base.rb +124 -80
- data/lib/action_view/component/monkey_patch.rb +27 -0
- data/lib/action_view/component/preview.rb +106 -0
- data/lib/action_view/component/railtie.rb +62 -0
- data/lib/action_view/component/test_helpers.rb +9 -1
- data/lib/action_view/component/version.rb +13 -0
- data/lib/rails/generators/component/USAGE +13 -0
- data/lib/rails/generators/component/component_generator.rb +50 -0
- data/lib/rails/generators/component/templates/component.html.erb.tt +5 -0
- data/lib/rails/generators/component/templates/component.rb.tt +9 -0
- data/lib/rails/generators/test_unit/component_generator.rb +20 -0
- data/lib/rails/generators/test_unit/templates/component_test.rb.tt +12 -0
- data/lib/railties/lib/rails.rb +6 -0
- data/lib/railties/lib/rails/component_examples_controller.rb +9 -0
- data/lib/railties/lib/rails/components_controller.rb +55 -0
- data/lib/railties/lib/rails/templates/rails/components/index.html.erb +8 -0
- data/lib/railties/lib/rails/templates/rails/components/preview.html.erb +1 -0
- data/lib/railties/lib/rails/templates/rails/components/previews.html.erb +6 -0
- data/lib/railties/lib/rails/templates/rails/examples/show.html.erb +1 -0
- metadata +24 -6
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 84c85d88f1ceefc7d3a0c97affcaa2465120a4513f0f445863a068715cb55f88
|
|
4
|
+
data.tar.gz: ad3ae8d04886ee3c22f79b73998e6d3d0156f9ef8e84cd64468139a6bd9b282a
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: fd41865d44d1b450f9772ff3da1dac80b5873c809bb4cc598c93be37e15c074fb5fdbf5186350af13a8da65d7c8502dcccfd069e7e71ef86e4b87b19891f4bcd
|
|
7
|
+
data.tar.gz: c44f9d1129c3597553abf20510ec50a9f490b707bc121fd0bee8f7046ae257a6cf0a6517e91bdfa14391e1028b88565f14eda017224c79577700741ef85560c1
|
|
@@ -8,22 +8,18 @@ jobs:
|
|
|
8
8
|
strategy:
|
|
9
9
|
matrix:
|
|
10
10
|
rails_version: [5.0.0, 5.2.3, 6.0.0, master]
|
|
11
|
-
ruby_version: [2.
|
|
11
|
+
ruby_version: [2.4.x, 2.5.x, 2.6.x]
|
|
12
12
|
exclude:
|
|
13
13
|
- rails_version: master
|
|
14
14
|
ruby_version: 2.4.x
|
|
15
|
-
- rails_version: master
|
|
16
|
-
ruby_version: 2.3.x
|
|
17
15
|
- rails_version: 6.0.0
|
|
18
16
|
ruby_version: 2.4.x
|
|
19
|
-
- rails_version: 6.0.0
|
|
20
|
-
ruby_version: 2.3.x
|
|
21
17
|
steps:
|
|
22
18
|
- uses: actions/checkout@master
|
|
23
19
|
- name: Setup Ruby
|
|
24
20
|
uses: actions/setup-ruby@v1
|
|
25
21
|
with:
|
|
26
|
-
version: ${{ matrix.ruby_version }}
|
|
22
|
+
ruby-version: ${{ matrix.ruby_version }}
|
|
27
23
|
- name: Build and test with Rake
|
|
28
24
|
run: |
|
|
29
25
|
gem install bundler:1.14.0
|
data/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,75 @@
|
|
|
1
|
+
# v1.5.1
|
|
2
|
+
|
|
3
|
+
* Update railties class to work with Rails 6.
|
|
4
|
+
|
|
5
|
+
*Juan Manuel Ramallo*
|
|
6
|
+
|
|
7
|
+
# v1.5.0
|
|
8
|
+
|
|
9
|
+
Note: `actionview-component` is now loaded by requiring `actionview/component`, not `actionview/component/base`.
|
|
10
|
+
|
|
11
|
+
* Fix issue with generating component method signatures.
|
|
12
|
+
|
|
13
|
+
*Ryan Workman, Dylan Clark*
|
|
14
|
+
|
|
15
|
+
* Create component generator.
|
|
16
|
+
|
|
17
|
+
*Vinicius Stock*
|
|
18
|
+
|
|
19
|
+
* Add helpers proxy.
|
|
20
|
+
|
|
21
|
+
*Kasper Meyer*
|
|
22
|
+
|
|
23
|
+
* Introduce ActionView::Component::Previews.
|
|
24
|
+
|
|
25
|
+
*Juan Manuel Ramallo*
|
|
26
|
+
|
|
27
|
+
# v1.4.0
|
|
28
|
+
|
|
29
|
+
* Fix bug where components broke in application paths with periods.
|
|
30
|
+
|
|
31
|
+
*Anton, Joel Hawksley*
|
|
32
|
+
|
|
33
|
+
* Add support for `cache_if` in component templates.
|
|
34
|
+
|
|
35
|
+
*Aaron Patterson, Joel Hawksley*
|
|
36
|
+
|
|
37
|
+
* Add support for variants.
|
|
38
|
+
|
|
39
|
+
*Juan Manuel Ramallo*
|
|
40
|
+
|
|
41
|
+
* Fix bug in virtual path lookup.
|
|
42
|
+
|
|
43
|
+
*Juan Manuel Ramallo*
|
|
44
|
+
|
|
45
|
+
* Preselect the rendered component in render_inline.
|
|
46
|
+
|
|
47
|
+
*Elia Schito*
|
|
48
|
+
|
|
49
|
+
# v1.3.6
|
|
50
|
+
|
|
51
|
+
* Allow template file names without format.
|
|
52
|
+
|
|
53
|
+
*Joel Hawksley*
|
|
54
|
+
|
|
55
|
+
* Add support for translations.
|
|
56
|
+
|
|
57
|
+
*Juan Manuel Ramallo*
|
|
58
|
+
|
|
59
|
+
# v1.3.5
|
|
60
|
+
|
|
61
|
+
* Re-expose `controller` method.
|
|
62
|
+
|
|
63
|
+
*Michael Emhofer, Joel Hawksley*
|
|
64
|
+
|
|
65
|
+
* Gem version numbers are now accessible through `ActionView::Component::VERSION`
|
|
66
|
+
|
|
67
|
+
*Richard Macklin*
|
|
68
|
+
|
|
69
|
+
* Fix typo in README
|
|
70
|
+
|
|
71
|
+
*ars moriendi*
|
|
72
|
+
|
|
1
73
|
# v1.3.4
|
|
2
74
|
|
|
3
75
|
* Template errors surface correct file and line number.
|
data/CONTRIBUTING.md
CHANGED
|
@@ -32,7 +32,8 @@ Here are a few things you can do that will increase the likelihood of your pull
|
|
|
32
32
|
If you are the current maintainer of this gem:
|
|
33
33
|
|
|
34
34
|
1. Create a branch for the release: `git checkout -b release-vxx.xx.xx`
|
|
35
|
-
1. Bump gem version in `
|
|
35
|
+
1. Bump gem version in `lib/action_view/component/version.rb`.
|
|
36
|
+
1. Add version heading/entries to `CHANGELOG.md`.
|
|
36
37
|
1. Make sure your local dependencies are up to date: `bundle`
|
|
37
38
|
1. Ensure that tests are green: `bundle exec rake`
|
|
38
39
|
1. Build a test gem `GEM_VERSION=$(git describe --tags 2>/dev/null | sed 's/-/./g' | sed 's/v//') gem build actionview-component.gemspec`
|
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.5.1)
|
|
5
5
|
|
|
6
6
|
GEM
|
|
7
7
|
remote: https://rubygems.org/
|
|
@@ -64,7 +64,7 @@ GEM
|
|
|
64
64
|
ast (2.4.0)
|
|
65
65
|
builder (3.2.3)
|
|
66
66
|
concurrent-ruby (1.1.5)
|
|
67
|
-
crass (1.0.
|
|
67
|
+
crass (1.0.5)
|
|
68
68
|
erubi (1.8.0)
|
|
69
69
|
globalid (0.4.2)
|
|
70
70
|
activesupport (>= 4.2.0)
|
|
@@ -74,7 +74,7 @@ GEM
|
|
|
74
74
|
i18n (1.6.0)
|
|
75
75
|
concurrent-ruby (~> 1.0)
|
|
76
76
|
jaro_winkler (1.5.3)
|
|
77
|
-
loofah (2.
|
|
77
|
+
loofah (2.3.1)
|
|
78
78
|
crass (~> 1.0.2)
|
|
79
79
|
nokogiri (>= 1.5.9)
|
|
80
80
|
mail (2.7.1)
|
|
@@ -87,7 +87,7 @@ GEM
|
|
|
87
87
|
mini_portile2 (2.4.0)
|
|
88
88
|
minitest (5.1.0)
|
|
89
89
|
nio4r (2.5.2)
|
|
90
|
-
nokogiri (1.10.
|
|
90
|
+
nokogiri (1.10.5)
|
|
91
91
|
mini_portile2 (~> 2.4.0)
|
|
92
92
|
parallel (1.17.0)
|
|
93
93
|
parser (2.6.3.0)
|
|
@@ -168,7 +168,7 @@ DEPENDENCIES
|
|
|
168
168
|
minitest (= 5.1.0)
|
|
169
169
|
rails (= 6.0.0)
|
|
170
170
|
rake (~> 10.0)
|
|
171
|
-
rubocop (
|
|
171
|
+
rubocop (= 0.74)
|
|
172
172
|
rubocop-github (~> 0.13.0)
|
|
173
173
|
slim (~> 4.0)
|
|
174
174
|
|
data/README.md
CHANGED
|
@@ -15,7 +15,7 @@ As the goal of this gem is to be upstreamed into Rails, it is designed to integr
|
|
|
15
15
|
|
|
16
16
|
## Compatibility
|
|
17
17
|
|
|
18
|
-
`actionview-component` is tested for compatibility with combinations of Ruby `2.
|
|
18
|
+
`actionview-component` is tested for compatibility with combinations of Ruby `2.4`/`2.5`/`2.6` and Rails `5.0.0`/`5.2.3`/`6.0.0`/`6.1.0.alpha`.
|
|
19
19
|
|
|
20
20
|
## Installation
|
|
21
21
|
Add this line to your application's Gemfile:
|
|
@@ -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"
|
|
36
36
|
```
|
|
37
37
|
|
|
38
38
|
## Guide
|
|
@@ -97,10 +97,26 @@ Components are subclasses of `ActionView::Component::Base` and live in `app/comp
|
|
|
97
97
|
|
|
98
98
|
Component class names end in -`Component`.
|
|
99
99
|
|
|
100
|
+
Component module names are plural, as they are for controllers. (`Users::AvatarComponent`)
|
|
101
|
+
|
|
100
102
|
Components support ActiveModel validations. Components are validated after initialization, but before rendering.
|
|
101
103
|
|
|
102
104
|
Content passed to an `ActionView::Component` as a block is captured and assigned to the `content` accessor.
|
|
103
105
|
|
|
106
|
+
#### Quick start
|
|
107
|
+
|
|
108
|
+
Use the component generator to create a new `ActionView::Component`.
|
|
109
|
+
|
|
110
|
+
The generator accepts the component name and the list of accepted properties as arguments:
|
|
111
|
+
|
|
112
|
+
```bash
|
|
113
|
+
bin/rails generate component Example title content
|
|
114
|
+
invoke test_unit
|
|
115
|
+
create test/components/example_component_test.rb
|
|
116
|
+
create app/components/example_component.rb
|
|
117
|
+
create app/components/example_component.html.erb
|
|
118
|
+
```
|
|
119
|
+
|
|
104
120
|
#### Implementation
|
|
105
121
|
|
|
106
122
|
An `ActionView::Component` is a Ruby file and corresponding template file (in any format supported by Rails) with the same base name:
|
|
@@ -149,7 +165,7 @@ Components can be rendered via:
|
|
|
149
165
|
|
|
150
166
|
The following syntax has been deprecated and will be removed in v2.0.0:
|
|
151
167
|
|
|
152
|
-
`render(TestComponent.new(foo: :bar)`
|
|
168
|
+
`render(TestComponent.new(foo: :bar))`
|
|
153
169
|
|
|
154
170
|
#### Error case
|
|
155
171
|
|
|
@@ -178,7 +194,7 @@ class MyComponentTest < Minitest::Test
|
|
|
178
194
|
def test_render_component
|
|
179
195
|
assert_equal(
|
|
180
196
|
%(<span title="my title">Hello, World!</span>),
|
|
181
|
-
render_inline(TestComponent, title: "my title") { "Hello, World!" }.
|
|
197
|
+
render_inline(TestComponent, title: "my title") { "Hello, World!" }.to_html
|
|
182
198
|
)
|
|
183
199
|
end
|
|
184
200
|
end
|
|
@@ -186,6 +202,64 @@ end
|
|
|
186
202
|
|
|
187
203
|
In general, we’ve found it makes the most sense to test components based on their rendered HTML.
|
|
188
204
|
|
|
205
|
+
#### Action Pack Variants
|
|
206
|
+
|
|
207
|
+
To test a specific variant you can wrap your test with the `with_variant` helper method as:
|
|
208
|
+
|
|
209
|
+
```ruby
|
|
210
|
+
def test_render_component_for_tablet
|
|
211
|
+
with_variant :tablet do
|
|
212
|
+
assert_equal(
|
|
213
|
+
%(<span title="my title">Hello, tablets!</span>),
|
|
214
|
+
render_inline(TestComponent, title: "my title") { "Hello, tablets!" }.css("span").to_html
|
|
215
|
+
)
|
|
216
|
+
end
|
|
217
|
+
end
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
### Previewing Components
|
|
221
|
+
`ActionView::Component::Preview`s provide a way to see how components look by visiting a special URL that renders them.
|
|
222
|
+
In the previous example, the preview class for `TestComponent` would be called `TestComponentPreview` and located in `test/components/previews/test_component_preview.rb`.
|
|
223
|
+
To see the preview of the component with a given title, implement a method that renders the component.
|
|
224
|
+
You can define as many examples as you want:
|
|
225
|
+
|
|
226
|
+
```ruby
|
|
227
|
+
# test/components/previews/test_component_preview.rb
|
|
228
|
+
|
|
229
|
+
class TestComponentPreview < ActionView::Component::Preview
|
|
230
|
+
def with_default_title
|
|
231
|
+
render(TestComponent, title: "Test component default")
|
|
232
|
+
end
|
|
233
|
+
|
|
234
|
+
def with_long_title
|
|
235
|
+
render(TestComponent, title: "This is a really long title to see how the component renders this")
|
|
236
|
+
end
|
|
237
|
+
end
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
The previews will be available in <http://localhost:3000/rails/components/test_component/with_default_title>
|
|
241
|
+
and <http://localhost:3000/rails/components/test_component/with_long_title>.
|
|
242
|
+
|
|
243
|
+
Previews use the application layout by default, but you can also use other layouts from your app:
|
|
244
|
+
|
|
245
|
+
```ruby
|
|
246
|
+
# test/components/previews/test_component_preview.rb
|
|
247
|
+
|
|
248
|
+
class TestComponentPreview < ActionView::Component::Preview
|
|
249
|
+
layout "admin"
|
|
250
|
+
|
|
251
|
+
...
|
|
252
|
+
end
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
By default, the preview classes live in `test/components/previews`.
|
|
256
|
+
This can be configured using the `preview_path` option.
|
|
257
|
+
For example, if you want to use `lib/component_previews`, set the following in `config/application.rb`:
|
|
258
|
+
|
|
259
|
+
```ruby
|
|
260
|
+
config.action_view_component.preview_path = "#{Rails.root}/lib/component_previews"
|
|
261
|
+
```
|
|
262
|
+
|
|
189
263
|
## Frequently Asked Questions
|
|
190
264
|
|
|
191
265
|
### Can I use other templating languages besides ERB?
|
|
@@ -3,10 +3,11 @@
|
|
|
3
3
|
|
|
4
4
|
lib = File.expand_path("../lib", __FILE__)
|
|
5
5
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
6
|
+
require "action_view/component/version"
|
|
6
7
|
|
|
7
8
|
Gem::Specification.new do |spec|
|
|
8
9
|
spec.name = "actionview-component"
|
|
9
|
-
spec.version =
|
|
10
|
+
spec.version = ActionView::Component::VERSION::STRING
|
|
10
11
|
spec.authors = ["GitHub Open Source"]
|
|
11
12
|
spec.email = ["opensource+actionview-component@github.com"]
|
|
12
13
|
|
|
@@ -38,6 +39,6 @@ Gem::Specification.new do |spec|
|
|
|
38
39
|
spec.add_development_dependency "minitest", "= 5.1.0"
|
|
39
40
|
spec.add_development_dependency "haml", "~> 5"
|
|
40
41
|
spec.add_development_dependency "slim", "~> 4.0"
|
|
41
|
-
spec.add_development_dependency "rubocop", "
|
|
42
|
+
spec.add_development_dependency "rubocop", "= 0.74"
|
|
42
43
|
spec.add_development_dependency "rubocop-github", "~> 0.13.0"
|
|
43
44
|
end
|
|
@@ -1,37 +1,20 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
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 to `render` 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
|
|
3
|
+
require "active_model"
|
|
4
|
+
require "action_view"
|
|
5
|
+
require "active_support/configurable"
|
|
6
|
+
require_relative "preview"
|
|
28
7
|
|
|
29
8
|
module ActionView
|
|
30
9
|
module Component
|
|
31
10
|
class Base < ActionView::Base
|
|
32
11
|
include ActiveModel::Validations
|
|
33
12
|
include ActiveSupport::Configurable
|
|
34
|
-
include
|
|
13
|
+
include ActionView::Component::Previews
|
|
14
|
+
|
|
15
|
+
delegate :form_authenticity_token, :protect_against_forgery?, to: :helpers
|
|
16
|
+
|
|
17
|
+
validate :variant_exists
|
|
35
18
|
|
|
36
19
|
# Entrypoint for rendering components. Called by ActionView::Base#render.
|
|
37
20
|
#
|
|
@@ -64,10 +47,17 @@ module ActionView
|
|
|
64
47
|
@view_renderer ||= view_context.view_renderer
|
|
65
48
|
@lookup_context ||= view_context.lookup_context
|
|
66
49
|
@view_flow ||= view_context.view_flow
|
|
50
|
+
@virtual_path ||= virtual_path
|
|
51
|
+
@variant = @lookup_context.variants.first
|
|
52
|
+
old_current_template = @current_template
|
|
53
|
+
@current_template = self
|
|
67
54
|
|
|
68
55
|
@content = view_context.capture(&block) if block_given?
|
|
69
56
|
validate!
|
|
70
|
-
|
|
57
|
+
|
|
58
|
+
send(self.class.call_method_name(@variant))
|
|
59
|
+
ensure
|
|
60
|
+
@current_template = old_current_template
|
|
71
61
|
end
|
|
72
62
|
|
|
73
63
|
def initialize(*); end
|
|
@@ -80,91 +70,145 @@ module ActionView
|
|
|
80
70
|
end
|
|
81
71
|
end
|
|
82
72
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
73
|
+
def controller
|
|
74
|
+
@controller ||= view_context.controller
|
|
75
|
+
end
|
|
86
76
|
|
|
87
|
-
|
|
88
|
-
|
|
77
|
+
# Provides a proxy to access helper methods through
|
|
78
|
+
def helpers
|
|
79
|
+
@helpers ||= view_context
|
|
80
|
+
end
|
|
89
81
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
return if @compiled && ActionView::Base.cache_template_loading
|
|
82
|
+
# Removes the first part of the path and the extension.
|
|
83
|
+
def virtual_path
|
|
84
|
+
self.class.source_location.gsub(%r{(.*app/components)|(\.rb)}, "")
|
|
85
|
+
end
|
|
95
86
|
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
#{compiled_template}
|
|
100
|
-
end
|
|
101
|
-
RUBY
|
|
87
|
+
def view_cache_dependencies
|
|
88
|
+
[]
|
|
89
|
+
end
|
|
102
90
|
|
|
103
|
-
|
|
104
|
-
|
|
91
|
+
def format # :nodoc:
|
|
92
|
+
@variant
|
|
93
|
+
end
|
|
105
94
|
|
|
106
|
-
|
|
95
|
+
private
|
|
107
96
|
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
template = File.read(template_file_path)
|
|
97
|
+
def variant_exists
|
|
98
|
+
return if self.class.variants.include?(@variant) || @variant.nil?
|
|
111
99
|
|
|
112
|
-
|
|
113
|
-
|
|
100
|
+
errors.add(:variant, "'#{@variant}' has no template defined")
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
def request
|
|
104
|
+
@request ||= controller.request
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
attr_reader :content, :view_context
|
|
108
|
+
|
|
109
|
+
class << self
|
|
110
|
+
def inherited(child)
|
|
111
|
+
child.include Rails.application.routes.url_helpers unless child < Rails.application.routes.url_helpers
|
|
112
|
+
|
|
113
|
+
super
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
def call_method_name(variant)
|
|
117
|
+
if variant.present?
|
|
118
|
+
"call_#{variant}"
|
|
114
119
|
else
|
|
115
|
-
|
|
120
|
+
"call"
|
|
116
121
|
end
|
|
117
122
|
end
|
|
118
123
|
|
|
119
|
-
def
|
|
124
|
+
def source_location
|
|
125
|
+
# Require #initialize to be defined so that we can use
|
|
126
|
+
# method#source_location to look up the file name
|
|
127
|
+
# of the component.
|
|
128
|
+
#
|
|
129
|
+
# If we were able to only support Ruby 2.7+,
|
|
130
|
+
# We could just use Module#const_source_location,
|
|
131
|
+
# rendering this unnecessary.
|
|
120
132
|
raise NotImplementedError.new("#{self} must implement #initialize.") unless self.instance_method(:initialize).owner == self
|
|
121
133
|
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
134
|
+
instance_method(:initialize).source_location[0]
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
# Compile templates to instance methods, assuming they haven't been compiled already.
|
|
138
|
+
# We could in theory do this on app boot, at least in production environments.
|
|
139
|
+
# Right now this just compiles the first time the component is rendered.
|
|
140
|
+
def compile
|
|
141
|
+
return if @compiled && ActionView::Base.cache_template_loading
|
|
125
142
|
|
|
126
|
-
|
|
127
|
-
raise StandardError.new("More than one template found for #{self}. There can only be one sidecar template file per component.")
|
|
128
|
-
end
|
|
143
|
+
validate_templates
|
|
129
144
|
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
145
|
+
templates.each do |template|
|
|
146
|
+
class_eval <<-RUBY, __FILE__, __LINE__ + 1
|
|
147
|
+
def #{call_method_name(template[:variant])}
|
|
148
|
+
@output_buffer = ActionView::OutputBuffer.new
|
|
149
|
+
#{compiled_template(template[:path])}
|
|
150
|
+
end
|
|
151
|
+
RUBY
|
|
134
152
|
end
|
|
135
153
|
|
|
136
|
-
|
|
154
|
+
@compiled = true
|
|
137
155
|
end
|
|
138
|
-
end
|
|
139
156
|
|
|
140
|
-
|
|
141
|
-
|
|
157
|
+
def variants
|
|
158
|
+
templates.map { |template| template[:variant] }
|
|
159
|
+
end
|
|
142
160
|
|
|
143
|
-
|
|
144
|
-
|
|
161
|
+
# we'll eventually want to update this to support other types
|
|
162
|
+
def type
|
|
163
|
+
"text/html"
|
|
145
164
|
end
|
|
146
165
|
|
|
147
166
|
def identifier
|
|
148
167
|
""
|
|
149
168
|
end
|
|
150
169
|
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
170
|
+
private
|
|
171
|
+
|
|
172
|
+
def templates
|
|
173
|
+
@templates ||=
|
|
174
|
+
(Dir["#{source_location.sub(/#{File.extname(source_location)}$/, '')}.*{#{ActionView::Template.template_handler_extensions.join(',')}}"] - [source_location]).each_with_object([]) do |path, memo|
|
|
175
|
+
memo << {
|
|
176
|
+
path: path,
|
|
177
|
+
variant: path.split(".").second.split("+")[1]&.to_sym,
|
|
178
|
+
handler: path.split(".").last
|
|
179
|
+
}
|
|
180
|
+
end
|
|
154
181
|
end
|
|
155
|
-
end
|
|
156
182
|
|
|
157
|
-
|
|
183
|
+
def validate_templates
|
|
184
|
+
if templates.empty?
|
|
185
|
+
raise NotImplementedError.new("Could not find a template file for #{self}.")
|
|
186
|
+
end
|
|
158
187
|
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
188
|
+
if templates.select { |template| template[:variant].nil? }.length > 1
|
|
189
|
+
raise StandardError.new("More than one template found for #{self}. There can only be one default template file per component.")
|
|
190
|
+
end
|
|
162
191
|
|
|
163
|
-
|
|
164
|
-
|
|
192
|
+
variants.each_with_object(Hash.new(0)) { |variant, counts| counts[variant] += 1 }.each do |variant, count|
|
|
193
|
+
next unless count > 1
|
|
194
|
+
|
|
195
|
+
raise StandardError.new("More than one template found for variant '#{variant}' in #{self}. There can only be one template file per variant.")
|
|
196
|
+
end
|
|
197
|
+
end
|
|
198
|
+
|
|
199
|
+
def compiled_template(file_path)
|
|
200
|
+
handler = ActionView::Template.handler_for_extension(File.extname(file_path).gsub(".", ""))
|
|
201
|
+
template = File.read(file_path)
|
|
202
|
+
|
|
203
|
+
if handler.method(:call).parameters.length > 1
|
|
204
|
+
handler.call(self, template)
|
|
205
|
+
else # remove before upstreaming into Rails
|
|
206
|
+
handler.call(OpenStruct.new(source: template, identifier: identifier, type: type))
|
|
207
|
+
end
|
|
208
|
+
end
|
|
165
209
|
end
|
|
166
210
|
|
|
167
|
-
|
|
211
|
+
ActiveSupport.run_load_hooks(:action_view_component, self)
|
|
168
212
|
end
|
|
169
213
|
end
|
|
170
214
|
end
|
|
@@ -0,0 +1,27 @@
|
|
|
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
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "active_support/concern"
|
|
4
|
+
require "active_support/descendants_tracker"
|
|
5
|
+
require_relative "test_helpers"
|
|
6
|
+
|
|
7
|
+
module ActionView
|
|
8
|
+
module Component #:nodoc:
|
|
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
|
+
|
|
29
|
+
class Preview
|
|
30
|
+
extend ActiveSupport::DescendantsTracker
|
|
31
|
+
include ActionView::Component::TestHelpers
|
|
32
|
+
|
|
33
|
+
def render(component, *locals)
|
|
34
|
+
render_inline(component, *locals)
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
class << self
|
|
38
|
+
# Returns all component preview classes.
|
|
39
|
+
def all
|
|
40
|
+
load_previews if descendants.empty?
|
|
41
|
+
descendants
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
# Returns the html of the component in its layout
|
|
45
|
+
def call(example)
|
|
46
|
+
example_html = new.public_send(example)
|
|
47
|
+
|
|
48
|
+
Rails::ComponentExamplesController.render(template: "examples/show",
|
|
49
|
+
layout: @layout || "layouts/application",
|
|
50
|
+
assigns: { example: example_html })
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
# Returns the component object class associated to the preview.
|
|
54
|
+
def component
|
|
55
|
+
self.name.sub(%r{Preview$}, "").constantize
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
# Returns all of the available examples for the component preview.
|
|
59
|
+
def examples
|
|
60
|
+
public_instance_methods(false).map(&:to_s).sort
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
# Returns +true+ if the example of the component preview exists.
|
|
64
|
+
def example_exists?(example)
|
|
65
|
+
examples.include?(example)
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
# Returns +true+ if the preview exists.
|
|
69
|
+
def exists?(preview)
|
|
70
|
+
all.any? { |p| p.preview_name == preview }
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
# Find a component preview by its underscored class name.
|
|
74
|
+
def find(preview)
|
|
75
|
+
all.find { |p| p.preview_name == preview }
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
# Returns the underscored name of the component preview without the suffix.
|
|
79
|
+
def preview_name
|
|
80
|
+
name.sub(/Preview$/, "").underscore
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
# Setter for layout name.
|
|
84
|
+
def layout(layout_name)
|
|
85
|
+
@layout = layout_name
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
private
|
|
89
|
+
|
|
90
|
+
def load_previews
|
|
91
|
+
if preview_path
|
|
92
|
+
Dir["#{preview_path}/**/*_preview.rb"].sort.each { |file| require_dependency file }
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
def preview_path
|
|
97
|
+
Base.preview_path
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
def show_previews
|
|
101
|
+
Base.show_previews
|
|
102
|
+
end
|
|
103
|
+
end
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
end
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "railties/lib/rails/components_controller"
|
|
4
|
+
require "railties/lib/rails/component_examples_controller"
|
|
5
|
+
|
|
6
|
+
module ActionView
|
|
7
|
+
module Component
|
|
8
|
+
class Railtie < Rails::Railtie # :nodoc:
|
|
9
|
+
config.action_view_component = ActiveSupport::OrderedOptions.new
|
|
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
|
+
initializer "action_view_component.set_configs" do |app|
|
|
17
|
+
options = app.config.action_view_component
|
|
18
|
+
|
|
19
|
+
options.show_previews = Rails.env.development? if options.show_previews.nil?
|
|
20
|
+
|
|
21
|
+
if options.show_previews
|
|
22
|
+
options.preview_path ||= defined?(Rails.root) ? "#{Rails.root}/test/components/previews" : nil
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
ActiveSupport.on_load(:action_view_component) do
|
|
26
|
+
options.each { |k, v| send("#{k}=", v) }
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
initializer "action_view_component.set_autoload_paths" do |app|
|
|
31
|
+
options = app.config.action_view_component
|
|
32
|
+
|
|
33
|
+
if options.show_previews && options.preview_path
|
|
34
|
+
ActiveSupport::Dependencies.autoload_paths << options.preview_path
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
initializer "action_view_component.compile_config_methods" do
|
|
39
|
+
ActiveSupport.on_load(:action_view_component) do
|
|
40
|
+
config.compile_methods! if config.respond_to?(:compile_methods!)
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
initializer "action_view_component.eager_load_actions" do
|
|
45
|
+
ActiveSupport.on_load(:after_initialize) do
|
|
46
|
+
ActionView::Component::Base.descendants.each(&:action_methods) if config.eager_load
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
config.after_initialize do |app|
|
|
51
|
+
options = app.config.action_view_component
|
|
52
|
+
|
|
53
|
+
if options.show_previews
|
|
54
|
+
app.routes.prepend do
|
|
55
|
+
get "/rails/components" => "rails/components#index", :internal => true
|
|
56
|
+
get "/rails/components/*path" => "rails/components#previews", :internal => true
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
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(controller.view_context.render(component, args, &block)).css("body > *")
|
|
8
8
|
end
|
|
9
9
|
|
|
10
10
|
def controller
|
|
@@ -22,6 +22,14 @@ module ActionView
|
|
|
22
22
|
|
|
23
23
|
render_inline(component, args, &block)
|
|
24
24
|
end
|
|
25
|
+
|
|
26
|
+
def with_variant(variant)
|
|
27
|
+
old_variants = controller.view_context.lookup_context.variants
|
|
28
|
+
|
|
29
|
+
controller.view_context.lookup_context.variants = variant
|
|
30
|
+
yield
|
|
31
|
+
controller.view_context.lookup_context.variants = old_variants
|
|
32
|
+
end
|
|
25
33
|
end
|
|
26
34
|
end
|
|
27
35
|
end
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
Description:
|
|
2
|
+
============
|
|
3
|
+
Creates a new component and test.
|
|
4
|
+
Pass the component name, either CamelCased or under_scored, and an optional list of attributes as arguments.
|
|
5
|
+
|
|
6
|
+
Example:
|
|
7
|
+
========
|
|
8
|
+
bin/rails generate component Profile name age
|
|
9
|
+
|
|
10
|
+
creates a Profile component and test:
|
|
11
|
+
Component: app/components/profile_component.rb
|
|
12
|
+
Template: app/components/profile_component.html.erb
|
|
13
|
+
Test: test/components/profile_component_test.rb
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Rails
|
|
4
|
+
module Generators
|
|
5
|
+
class ComponentGenerator < Rails::Generators::NamedBase
|
|
6
|
+
source_root File.expand_path("templates", __dir__)
|
|
7
|
+
|
|
8
|
+
argument :attributes, type: :array, default: [], banner: "attribute"
|
|
9
|
+
hook_for :test_framework
|
|
10
|
+
check_class_collision suffix: "Component"
|
|
11
|
+
|
|
12
|
+
def create_component_file
|
|
13
|
+
template "component.rb", File.join("app/components", "#{file_name}_component.rb")
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def create_template_file
|
|
17
|
+
template "component.html.erb", File.join("app/components", "#{file_name}_component.html.erb")
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
private
|
|
21
|
+
|
|
22
|
+
def file_name
|
|
23
|
+
@_file_name ||= super.sub(/_component\z/i, "")
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def requires_content?
|
|
27
|
+
return @requires_content if @asked
|
|
28
|
+
|
|
29
|
+
@asked = true
|
|
30
|
+
@requires_content = ask("Would you like #{class_name} to require content? (Y/n)").downcase == "y"
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def parent_class
|
|
34
|
+
defined?(ApplicationComponent) ? "ApplicationComponent" : "ActionView::Component::Base"
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def initialize_signature
|
|
38
|
+
if attributes.present?
|
|
39
|
+
attributes.map { |attr| "#{attr.name}:" }.join(", ")
|
|
40
|
+
else
|
|
41
|
+
"*"
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def initialize_body
|
|
46
|
+
attributes.map { |attr| "@#{attr.name} = #{attr.name}" }.join("\n ")
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module TestUnit
|
|
4
|
+
module Generators
|
|
5
|
+
class ComponentGenerator < ::Rails::Generators::NamedBase
|
|
6
|
+
source_root File.expand_path("templates", __dir__)
|
|
7
|
+
check_class_collision suffix: "ComponentTest"
|
|
8
|
+
|
|
9
|
+
def create_test_file
|
|
10
|
+
template "component_test.rb", File.join("test/components", "#{file_name}_component_test.rb")
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
private
|
|
14
|
+
|
|
15
|
+
def file_name
|
|
16
|
+
@_file_name ||= super.sub(/_component\z/i, "")
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
require "test_helper"
|
|
2
|
+
|
|
3
|
+
class <%= class_name %>ComponentTest < ActiveSupport::TestCase
|
|
4
|
+
include ActionView::Component::TestHelpers
|
|
5
|
+
|
|
6
|
+
test "component renders something useful" do
|
|
7
|
+
# assert_equal(
|
|
8
|
+
# %(<span title="my title">Hello, components!</span>),
|
|
9
|
+
# render_inline(<%= class_name %>, attr: "value") { "Hello, components!" }.css("span").to_html
|
|
10
|
+
# )
|
|
11
|
+
end
|
|
12
|
+
end
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "rails/application_controller"
|
|
4
|
+
load "config/application.rb" unless Rails.root
|
|
5
|
+
|
|
6
|
+
class Rails::ComponentExamplesController < ActionController::Base # :nodoc:
|
|
7
|
+
prepend_view_path File.expand_path("templates/rails", __dir__)
|
|
8
|
+
append_view_path Rails.root.join("app/views")
|
|
9
|
+
end
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "rails/application_controller"
|
|
4
|
+
|
|
5
|
+
class Rails::ComponentsController < Rails::ApplicationController # :nodoc:
|
|
6
|
+
prepend_view_path File.expand_path("templates/rails", __dir__)
|
|
7
|
+
|
|
8
|
+
around_action :set_locale, only: :previews
|
|
9
|
+
before_action :find_preview, only: :previews
|
|
10
|
+
before_action :require_local!, unless: :show_previews?
|
|
11
|
+
|
|
12
|
+
if respond_to?(:content_security_policy)
|
|
13
|
+
content_security_policy(false)
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def index
|
|
17
|
+
@previews = ActionView::Component::Preview.all
|
|
18
|
+
@page_title = "Component Previews"
|
|
19
|
+
render template: "components/index"
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def previews
|
|
23
|
+
if params[:path] == @preview.preview_name
|
|
24
|
+
@page_title = "Component Previews for #{@preview.preview_name}"
|
|
25
|
+
render template: "components/previews"
|
|
26
|
+
else
|
|
27
|
+
@example_name = File.basename(params[:path])
|
|
28
|
+
render template: "components/preview", layout: false
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
private
|
|
33
|
+
|
|
34
|
+
def show_previews? # :doc:
|
|
35
|
+
ActionView::Component::Base.show_previews
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def find_preview # :doc:
|
|
39
|
+
candidates = []
|
|
40
|
+
params[:path].to_s.scan(%r{/|$}) { candidates << $` }
|
|
41
|
+
preview = candidates.detect { |candidate| ActionView::Component::Preview.exists?(candidate) }
|
|
42
|
+
|
|
43
|
+
if preview
|
|
44
|
+
@preview = ActionView::Component::Preview.find(preview)
|
|
45
|
+
else
|
|
46
|
+
raise AbstractController::ActionNotFound, "Component preview '#{params[:path]}' not found"
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def set_locale
|
|
51
|
+
I18n.with_locale(params[:locale] || I18n.default_locale) do
|
|
52
|
+
yield
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
<% @previews.each do |preview| %>
|
|
2
|
+
<h3><%= link_to preview.preview_name.titleize, "/rails/components/#{preview.preview_name}" %></h3>
|
|
3
|
+
<ul>
|
|
4
|
+
<% preview.examples.each do |preview_example| %>
|
|
5
|
+
<li><%= link_to preview_example, "/rails/components/#{preview.preview_name}/#{preview_example}" %></li>
|
|
6
|
+
<% end %>
|
|
7
|
+
</ul>
|
|
8
|
+
<% end %>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<%= raw @preview.call(@example_name) %>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<%= raw @example %>
|
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.5.1
|
|
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: 2019-
|
|
11
|
+
date: 2019-11-21 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: bundler
|
|
@@ -84,16 +84,16 @@ dependencies:
|
|
|
84
84
|
name: rubocop
|
|
85
85
|
requirement: !ruby/object:Gem::Requirement
|
|
86
86
|
requirements:
|
|
87
|
-
- -
|
|
87
|
+
- - '='
|
|
88
88
|
- !ruby/object:Gem::Version
|
|
89
|
-
version: '0.
|
|
89
|
+
version: '0.74'
|
|
90
90
|
type: :development
|
|
91
91
|
prerelease: false
|
|
92
92
|
version_requirements: !ruby/object:Gem::Requirement
|
|
93
93
|
requirements:
|
|
94
|
-
- -
|
|
94
|
+
- - '='
|
|
95
95
|
- !ruby/object:Gem::Version
|
|
96
|
-
version: '0.
|
|
96
|
+
version: '0.74'
|
|
97
97
|
- !ruby/object:Gem::Dependency
|
|
98
98
|
name: rubocop-github
|
|
99
99
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -127,8 +127,26 @@ files:
|
|
|
127
127
|
- README.md
|
|
128
128
|
- Rakefile
|
|
129
129
|
- actionview-component.gemspec
|
|
130
|
+
- lib/action_view/component.rb
|
|
130
131
|
- lib/action_view/component/base.rb
|
|
132
|
+
- lib/action_view/component/monkey_patch.rb
|
|
133
|
+
- lib/action_view/component/preview.rb
|
|
134
|
+
- lib/action_view/component/railtie.rb
|
|
131
135
|
- lib/action_view/component/test_helpers.rb
|
|
136
|
+
- lib/action_view/component/version.rb
|
|
137
|
+
- lib/rails/generators/component/USAGE
|
|
138
|
+
- lib/rails/generators/component/component_generator.rb
|
|
139
|
+
- lib/rails/generators/component/templates/component.html.erb.tt
|
|
140
|
+
- lib/rails/generators/component/templates/component.rb.tt
|
|
141
|
+
- lib/rails/generators/test_unit/component_generator.rb
|
|
142
|
+
- lib/rails/generators/test_unit/templates/component_test.rb.tt
|
|
143
|
+
- lib/railties/lib/rails.rb
|
|
144
|
+
- lib/railties/lib/rails/component_examples_controller.rb
|
|
145
|
+
- lib/railties/lib/rails/components_controller.rb
|
|
146
|
+
- lib/railties/lib/rails/templates/rails/components/index.html.erb
|
|
147
|
+
- lib/railties/lib/rails/templates/rails/components/preview.html.erb
|
|
148
|
+
- lib/railties/lib/rails/templates/rails/components/previews.html.erb
|
|
149
|
+
- lib/railties/lib/rails/templates/rails/examples/show.html.erb
|
|
132
150
|
- script/bootstrap
|
|
133
151
|
- script/console
|
|
134
152
|
- script/install
|