actionview-component 1.6.0 → 1.6.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e0d1497b59c35721a9d9c48906ca5b1a64eb30f72e9bfd17d0da2437820e7e87
4
- data.tar.gz: e703a27db8cac4a589f6d8f78e3ffc2bb7783af16d7c49c8986d06db7155bcd4
3
+ metadata.gz: 642717e715c2f33794d3647e8756af86226bf90a9ee40c28496109288fa63201
4
+ data.tar.gz: a2144dc99b735c2e0cd27b86e5f5b95f60031facc7b47af0e35f3ab0ff2562ba
5
5
  SHA512:
6
- metadata.gz: 481e35fdf095d48a1c3a33795d8e1d8b0be6a6b6944b149e5a6320add88f8748f4ea8e19282cd90bb62f9858291cd07084e9b1221051fcfb89f70b7dd6471281
7
- data.tar.gz: 45fd087cc394799a8f21044c58de91a3aeee93dc29c8fbd8ff8c4a1979977bb86bc47d38341f51a37bbe93038c81b77908ec8d634d4d41b064a11585a684ae44
6
+ metadata.gz: 34973a14a10b96e2905b2fadfa93828de4014c12f97239a367527aabea8218d13281cdc8dbad7808f9575afafb66172202612a65e51506db4f2e8be4a6055354
7
+ data.tar.gz: 893531f33aaf0982973df46acc708e42de316464a3860bda12a693e810283d12d7d5a3a5a743149fa406645ff7242f9ef04509f18a0c855379b867f6ef4f9117
@@ -1,3 +1,29 @@
1
+ # v1.6.1
2
+
3
+ * Allow Previews to have no layout.
4
+
5
+ *Jon Palmer*
6
+
7
+ * Bump rack from 2.0.7 to 2.0.8.
8
+
9
+ *Dependabot*
10
+
11
+ * Compile components on application boot when eager loading is enabled.
12
+
13
+ *Joel Hawksley*
14
+
15
+ * Previews support content blocks.
16
+
17
+ *Cesario Uy*
18
+
19
+ * Follow Rails conventions. (refactor)
20
+
21
+ *Rainer Borene*
22
+
23
+ * Fix edge case issue with extracting variants from less conventional source_locations.
24
+
25
+ *Ryan Workman*
26
+
1
27
  # v1.6.0
2
28
 
3
29
  * Avoid dropping elements in the render_inline test helper.
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- actionview-component (1.6.0)
4
+ actionview-component (1.6.1)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
@@ -101,7 +101,7 @@ GEM
101
101
  parallel (1.17.0)
102
102
  parser (2.6.3.0)
103
103
  ast (~> 2.4.0)
104
- rack (2.0.7)
104
+ rack (2.0.8)
105
105
  rack-test (1.1.0)
106
106
  rack (>= 1.0, < 3)
107
107
  rails (6.0.0)
data/README.md CHANGED
@@ -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
@@ -174,7 +174,7 @@ Example for a `Post` model:
174
174
  `render(@post)`
175
175
 
176
176
  ```ruby
177
- class PostComponent < ActionView::Component
177
+ class PostComponent < ActionView::Component::Base
178
178
  def initialize(post)
179
179
  @post = post
180
180
  end
@@ -204,12 +204,10 @@ An error will be raised:
204
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:
205
205
 
206
206
  ```ruby
207
- require "action_view/component/test_helpers"
208
-
209
- class MyComponentTest < Minitest::Test
210
- include ActionView::Component::TestHelpers
207
+ require "action_view/component/test_case"
211
208
 
212
- def test_render_component
209
+ class MyComponentTest < ActionView::Component::TestCase
210
+ test "render component" do
213
211
  assert_equal(
214
212
  %(<span title="my title">Hello, World!</span>),
215
213
  render_inline(TestComponent, title: "my title") { "Hello, World!" }.to_html
@@ -225,7 +223,7 @@ In general, we’ve found it makes the most sense to test components based on th
225
223
  To test a specific variant you can wrap your test with the `with_variant` helper method as:
226
224
 
227
225
  ```ruby
228
- def test_render_component_for_tablet
226
+ test "render component for tablet" do
229
227
  with_variant :tablet do
230
228
  assert_equal(
231
229
  %(<span title="my title">Hello, tablets!</span>),
@@ -1,6 +1,22 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "action_view/component/monkey_patch"
4
- require "action_view/component/active_model_conversion_monkey_patch"
5
- require "action_view/component/base"
3
+ require "active_model"
4
+ require "action_view"
5
+ require "active_support/dependencies/autoload"
6
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,16 +1,13 @@
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::Previews
10
+ include ActionView::Component::Previewable
14
11
 
15
12
  delegate :form_authenticity_token, :protect_against_forgery?, to: :helpers
16
13
 
@@ -113,6 +110,10 @@ module ActionView
113
110
  end
114
111
  end
115
112
 
113
+ def has_initializer?
114
+ self.instance_method(:initialize).owner == self
115
+ end
116
+
116
117
  def source_location
117
118
  # Require #initialize to be defined so that we can use
118
119
  # method#source_location to look up the file name
@@ -121,16 +122,26 @@ module ActionView
121
122
  # If we were able to only support Ruby 2.7+,
122
123
  # We could just use Module#const_source_location,
123
124
  # rendering this unnecessary.
124
- raise NotImplementedError.new("#{self} must implement #initialize.") unless self.instance_method(:initialize).owner == self
125
+ raise NotImplementedError.new("#{self} must implement #initialize.") unless has_initializer?
125
126
 
126
127
  instance_method(:initialize).source_location[0]
127
128
  end
128
129
 
130
+ def eager_load!
131
+ self.descendants.each do |descendant|
132
+ descendant.compile if descendant.has_initializer?
133
+ end
134
+ end
135
+
136
+ def compiled?
137
+ @compiled && ActionView::Base.cache_template_loading
138
+ end
139
+
129
140
  # Compile templates to instance methods, assuming they haven't been compiled already.
130
141
  # We could in theory do this on app boot, at least in production environments.
131
142
  # Right now this just compiles the first time the component is rendered.
132
143
  def compile
133
- return if @compiled && ActionView::Base.cache_template_loading
144
+ return if compiled?
134
145
 
135
146
  validate_templates
136
147
 
@@ -161,13 +172,19 @@ module ActionView
161
172
 
162
173
  private
163
174
 
175
+ def matching_views_in_source_location
176
+ (Dir["#{source_location.sub(/#{File.extname(source_location)}$/, '')}.*{#{ActionView::Template.template_handler_extensions.join(',')}}"] - [source_location])
177
+ end
178
+
164
179
  def templates
165
180
  @templates ||=
166
- (Dir["#{source_location.sub(/#{File.extname(source_location)}$/, '')}.*{#{ActionView::Template.template_handler_extensions.join(',')}}"] - [source_location]).each_with_object([]) do |path, memo|
181
+ matching_views_in_source_location.each_with_object([]) do |path, memo|
182
+ pieces = File.basename(path).split(".")
183
+
167
184
  memo << {
168
185
  path: path,
169
- variant: path.split(".").second.split("+")[1]&.to_sym,
170
- handler: path.split(".").last
186
+ variant: pieces.second.split("+")[1]&.to_sym,
187
+ handler: pieces.last
171
188
  }
172
189
  end
173
190
  end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActionView
4
+ module Component # :nodoc:
5
+ module Conversion
6
+ def to_component_class
7
+ "#{self.class.name}Component".safe_constantize
8
+ end
9
+ end
10
+ end
11
+ 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 #: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
-
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: @layout || "layouts/application",
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,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "rails"
4
+
3
5
  module ActionView
4
6
  module Component
5
7
  class Railtie < Rails::Railtie # :nodoc:
@@ -23,6 +25,7 @@ module ActionView
23
25
  require "railties/lib/rails/components_controller"
24
26
  require "railties/lib/rails/component_examples_controller"
25
27
 
28
+ app.config.eager_load_namespaces << ActionView::Component::Base
26
29
  options = app.config.action_view_component
27
30
 
28
31
  if options.show_previews && options.preview_path
@@ -36,6 +39,12 @@ module ActionView
36
39
  end
37
40
  end
38
41
 
42
+ initializer "action_view_component.monkey_patch_render" do
43
+ ActiveSupport.on_load(:action_view) do
44
+ ActionView::Base.prepend ActionView::Component::RenderMonkeyPatch
45
+ end
46
+ end
47
+
39
48
  config.after_initialize do |app|
40
49
  options = app.config.action_view_component
41
50
 
@@ -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
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/test_case"
4
+
5
+ module ActionView
6
+ module Component
7
+ class TestCase < ActiveSupport::TestCase
8
+ include ActionView::Component::TestHelpers
9
+ end
10
+ end
11
+ end
@@ -5,7 +5,7 @@ module ActionView
5
5
  module VERSION
6
6
  MAJOR = 1
7
7
  MINOR = 6
8
- PATCH = 0
8
+ PATCH = 1
9
9
 
10
10
  STRING = [MAJOR, MINOR, PATCH].join(".")
11
11
  end
@@ -1,8 +1,6 @@
1
1
  require "test_helper"
2
2
 
3
- class <%= class_name %>ComponentTest < ActiveSupport::TestCase
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>),
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.6.0
4
+ version: 1.6.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-12-11 00:00:00.000000000 Z
11
+ date: 2019-12-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -142,11 +142,13 @@ files:
142
142
  - Rakefile
143
143
  - actionview-component.gemspec
144
144
  - lib/action_view/component.rb
145
- - lib/action_view/component/active_model_conversion_monkey_patch.rb
146
145
  - lib/action_view/component/base.rb
147
- - lib/action_view/component/monkey_patch.rb
146
+ - lib/action_view/component/conversion.rb
148
147
  - lib/action_view/component/preview.rb
148
+ - lib/action_view/component/previewable.rb
149
149
  - lib/action_view/component/railtie.rb
150
+ - lib/action_view/component/render_monkey_patch.rb
151
+ - lib/action_view/component/test_case.rb
150
152
  - lib/action_view/component/test_helpers.rb
151
153
  - lib/action_view/component/version.rb
152
154
  - lib/rails/generators/component/USAGE
@@ -1,9 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module ActiveModel
4
- module Conversion
5
- def to_component_class
6
- "#{self.class.name}Component".safe_constantize
7
- end
8
- end
9
- end
@@ -1,29 +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
- elsif options.respond_to?(:to_component_class) && !options.to_component_class.nil?
21
- options.to_component_class.new(options).render_in(self, &block)
22
- else
23
- super
24
- end
25
- end
26
- end
27
-
28
- prepend RenderMonkeyPatch
29
- end