view_component 2.25.1 → 2.29.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c411f9f34b25054093f7abe23c5842c7523f083ecdb1ba586429545548eca423
4
- data.tar.gz: 744c27c0907544dfb93eb37ecf47c74dd7df86855c0e2b91f9619a77bd8eefc8
3
+ metadata.gz: f8c387807061db7889dbc2e49ccb75a15a2cacd416048a6681b046eb321fb27b
4
+ data.tar.gz: fbddc58ff50b3ddaf615f773a681a7a8b7bef3972581dad8b87bf8425efff275
5
5
  SHA512:
6
- metadata.gz: bee62ecbcfecbc53146b8a8e55207baf2d14769adda2bb2349494a82224acf12fa6584bfc32512e96474f28f011823f2c5712cbc021773d439c43fab8b090503
7
- data.tar.gz: 3f519b85b066d89fdf75afb17563cb868bb4fb673caa21326661f0738b9b4398af068421064ca6f77abf08b7b46bdc549c132252b111b8fb3009809d430b9682
6
+ metadata.gz: 63a070fc0a5001b888dbd57a2a9fb0660b351a05b522d9a832efdd2a60f981d218eda2f500a50d01ca6a8c5ada4cccb61f2837e7b956215e89528d9454d3fd39
7
+ data.tar.gz: 8176f0427272a8305a520eeaa72ae58be2d9df42282a981f376eb69ac0543017f98d737ecb09f6fa6fc8cacf85adbbf82fbefe337da22432448ab361f35ae447
data/CHANGELOG.md CHANGED
@@ -2,6 +2,75 @@
2
2
 
3
3
  ## main
4
4
 
5
+ ## 2.29.0
6
+
7
+ * Allow Slot lambdas to share data from the parent component and allow chaining on the returned component.
8
+
9
+ *Sjors Baltus, Blake Williams*
10
+
11
+ * Experimental: Add `ViewComponent::Translatable`
12
+ * `t` and `translate` now will look first into the sidecar YAML translations file.
13
+ * `helpers.t` and `I18n.t` still reference the global Rails translation files.
14
+ * `l` and `localize` will still reference the global Rails translation files.
15
+
16
+ *Elia Schito*
17
+
18
+ * Fix rendering output of pass through slots when using HAML.
19
+
20
+ *Alex Robbin, Blake Williams*
21
+
22
+ * Experimental: call `._sidecar_files` to fetch the sidecar files for a given list of extensions, e.g. passing `["yml", "yaml"]`.
23
+
24
+ *Elia Schito*
25
+
26
+ * Fix bug where a single `jbuilder` template matched multiple template handlers.
27
+
28
+ *Niels Slot*
29
+
30
+ ## 2.28.0
31
+
32
+ * Include SlotableV2 by default in Base. **Note:** It's no longer necessary to include `ViewComponent::SlotableV2` to use Slots.
33
+
34
+ *Joel Hawksley*
35
+
36
+ * Prepend Preview routes instead of appending, accounting for cases where host application has catchall route.
37
+
38
+ *Joel Hawksley*
39
+
40
+ * Fix bug where blocks passed to lambda slots will render incorrectly in certain situations.
41
+
42
+ *Blake Williams*
43
+
44
+ ## 2.27.0
45
+
46
+ * Allow customization of the controller used in component tests.
47
+
48
+ *Alex Robbin*
49
+
50
+ * Generate preview at overridden path if one exists when using `--preview` flag.
51
+
52
+ *Nishiki Liu*
53
+
54
+ ## 2.26.1
55
+
56
+ * Fix bug that raises when trying to use a collection before the component has been compiled.
57
+
58
+ *Blake Williams*
59
+
60
+ ## 2.26.0
61
+
62
+ * Lazily evaluate component `content` in `render?`, preventing the `content` block from being evaluated when `render?` returns false.
63
+
64
+ *Blake Williams*
65
+
66
+ * Do not generate template when using `--inline` flag.
67
+
68
+ *Hans Lemuet*
69
+
70
+ * Add `--inline` option to the Haml and Slim generators
71
+
72
+ *Hans Lemuet*
73
+
5
74
  ## 2.25.1
6
75
 
7
76
  * Experimental: call `._after_compile` class method after a component is compiled.
data/README.md CHANGED
@@ -6,14 +6,6 @@ A framework for building reusable, testable & encapsulated view components in Ru
6
6
 
7
7
  See [viewcomponent.org](https://viewcomponent.org/) for documentation.
8
8
 
9
- ## Installation
10
-
11
- In `Gemfile`, add:
12
-
13
- ```ruby
14
- gem "view_component", require: "view_component/engine"
15
- ```
16
-
17
9
  ## Contributing
18
10
 
19
11
  This project is intended to be a safe, welcoming space for collaboration. Contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct. We recommend reading the [contributing guide](./CONTRIBUTING.md) as well.
@@ -10,18 +10,18 @@ module Erb
10
10
  class_option :inline, type: :boolean, default: false
11
11
 
12
12
  def copy_view_file
13
- template "component.html.erb", destination
13
+ unless options["inline"]
14
+ template "component.html.erb", destination
15
+ end
14
16
  end
15
17
 
16
18
  private
17
19
 
18
20
  def destination
19
- if !options["inline"]
20
- if options["sidecar"]
21
- File.join("app/components", class_path, "#{file_name}_component", "#{file_name}_component.html.erb")
22
- else
23
- File.join("app/components", class_path, "#{file_name}_component.html.erb")
24
- end
21
+ if options["sidecar"]
22
+ File.join("app/components", class_path, "#{file_name}_component", "#{file_name}_component.html.erb")
23
+ else
24
+ File.join("app/components", class_path, "#{file_name}_component.html.erb")
25
25
  end
26
26
  end
27
27
 
@@ -9,7 +9,9 @@ module Haml
9
9
  class_option :sidecar, type: :boolean, default: false
10
10
 
11
11
  def copy_view_file
12
- template "component.html.haml", destination
12
+ if !options["inline"]
13
+ template "component.html.haml", destination
14
+ end
13
15
  end
14
16
 
15
17
  private
@@ -8,7 +8,11 @@ module Preview
8
8
  check_class_collision suffix: "ComponentPreview"
9
9
 
10
10
  def create_preview_file
11
- template "component_preview.rb", File.join("test/components/previews", class_path, "#{file_name}_component_preview.rb")
11
+ preview_paths = Rails.application.config.view_component.preview_paths
12
+ return if preview_paths.count > 1
13
+
14
+ path_prefix = preview_paths.one? ? preview_paths.first : "test/components/previews"
15
+ template "component_preview.rb", File.join(path_prefix, class_path, "#{file_name}_component_preview.rb")
12
16
  end
13
17
 
14
18
  private
@@ -9,7 +9,9 @@ module Slim
9
9
  class_option :sidecar, type: :boolean, default: false
10
10
 
11
11
  def copy_view_file
12
- template "component.html.slim", destination
12
+ if !options["inline"]
13
+ template "component.html.slim", destination
14
+ end
13
15
  end
14
16
 
15
17
  private
@@ -12,4 +12,5 @@ module ViewComponent
12
12
  autoload :TestHelpers
13
13
  autoload :TestCase
14
14
  autoload :TemplateError
15
+ autoload :Translatable
15
16
  end
@@ -12,6 +12,7 @@ module ViewComponent
12
12
  class Base < ActionView::Base
13
13
  include ActiveSupport::Configurable
14
14
  include ViewComponent::Previewable
15
+ include ViewComponent::SlotableV2
15
16
 
16
17
  ViewContextCalledBeforeRenderError = Class.new(StandardError)
17
18
 
@@ -78,8 +79,8 @@ module ViewComponent
78
79
  old_current_template = @current_template
79
80
  @current_template = self
80
81
 
81
- # Assign captured content passed to component as a block to @content
82
- @content = view_context.capture(self, &block) if block_given?
82
+ @_content_evaluated = false
83
+ @_render_in_block = block
83
84
 
84
85
  before_render
85
86
 
@@ -130,7 +131,7 @@ module ViewComponent
130
131
  @helpers ||= controller.view_context
131
132
  end
132
133
 
133
- # Exposes .virutal_path as an instance method
134
+ # Exposes .virtual_path as an instance method
134
135
  def virtual_path
135
136
  self.class.virtual_path
136
137
  end
@@ -177,11 +178,25 @@ module ViewComponent
177
178
  @request ||= controller.request
178
179
  end
179
180
 
180
- attr_reader :content, :view_context
181
+ attr_reader :view_context
182
+
183
+ def content
184
+ return @_content if defined?(@_content)
185
+ @_content_evaluated = true
186
+
187
+ @_content = if @view_context && @_render_in_block
188
+ view_context.capture(self, &@_render_in_block)
189
+ end
190
+ end
191
+
192
+ def content_evaluated?
193
+ @_content_evaluated
194
+ end
181
195
 
182
196
  # The controller used for testing components.
183
- # Defaults to ApplicationController. This should be set early
184
- # in the initialization process and should be set to a string.
197
+ # Defaults to ApplicationController, but can be configured
198
+ # on a per-test basis using `with_controller_class`.
199
+ # This should be set early in the initialization process and should be a string.
185
200
  mattr_accessor :test_controller
186
201
  @@test_controller = "ApplicationController"
187
202
 
@@ -191,6 +206,47 @@ module ViewComponent
191
206
  class << self
192
207
  attr_accessor :source_location, :virtual_path
193
208
 
209
+ # EXPERIMENTAL: This API is experimental and may be removed at any time.
210
+ # Find sidecar files for the given extensions.
211
+ #
212
+ # The provided array of extensions is expected to contain
213
+ # strings starting without the "dot", example: `["erb", "haml"]`.
214
+ #
215
+ # For example, one might collect sidecar CSS files that need to be compiled.
216
+ def _sidecar_files(extensions)
217
+ return [] unless source_location
218
+
219
+ extensions = extensions.join(",")
220
+
221
+ # view files in a directory named like the component
222
+ directory = File.dirname(source_location)
223
+ filename = File.basename(source_location, ".rb")
224
+ component_name = name.demodulize.underscore
225
+
226
+ # Add support for nested components defined in the same file.
227
+ #
228
+ # e.g.
229
+ #
230
+ # class MyComponent < ViewComponent::Base
231
+ # class MyOtherComponent < ViewComponent::Base
232
+ # end
233
+ # end
234
+ #
235
+ # Without this, `MyOtherComponent` will not look for `my_component/my_other_component.html.erb`
236
+ nested_component_files = if name.include?("::") && component_name != filename
237
+ Dir["#{directory}/#{filename}/#{component_name}.*{#{extensions}}"]
238
+ else
239
+ []
240
+ end
241
+
242
+ # view files in the same directory as the component
243
+ sidecar_files = Dir["#{directory}/#{component_name}.*{#{extensions}}"]
244
+
245
+ sidecar_directory_files = Dir["#{directory}/#{component_name}/#{filename}.*{#{extensions}}"]
246
+
247
+ (sidecar_files - [source_location] + sidecar_directory_files + nested_component_files).uniq
248
+ end
249
+
194
250
  # Render a component collection.
195
251
  def with_collection(collection, **args)
196
252
  Collection.new(self, collection, **args)
@@ -256,7 +312,14 @@ module ViewComponent
256
312
  if areas.include?(:content)
257
313
  raise ArgumentError.new ":content is a reserved content area name. Please use another name, such as ':body'"
258
314
  end
259
- attr_reader(*areas)
315
+
316
+ areas.each do |area|
317
+ define_method area.to_sym do
318
+ content unless content_evaluated? # ensure content is loaded so content_areas will be defined
319
+ instance_variable_get(:"@#{area}") if instance_variable_defined?(:"@#{area}")
320
+ end
321
+ end
322
+
260
323
  self.content_areas = areas
261
324
  end
262
325
 
@@ -304,6 +367,22 @@ module ViewComponent
304
367
  )
305
368
  end
306
369
 
370
+ def collection_parameter
371
+ if provided_collection_parameter
372
+ provided_collection_parameter
373
+ else
374
+ name && name.demodulize.underscore.chomp("_component").to_sym
375
+ end
376
+ end
377
+
378
+ def collection_counter_parameter
379
+ "#{collection_parameter}_counter".to_sym
380
+ end
381
+
382
+ def counter_argument_present?
383
+ instance_method(:initialize).parameters.map(&:second).include?(collection_counter_parameter)
384
+ end
385
+
307
386
  private
308
387
 
309
388
  def initialize_parameter_names
@@ -10,7 +10,6 @@ module ViewComponent
10
10
  def render_in(view_context, &block)
11
11
  iterator = ActionView::PartialIteration.new(@collection.size)
12
12
 
13
- component.compile(raise_errors: true)
14
13
  component.validate_collection_parameter!(validate_default: true)
15
14
 
16
15
  @collection.map do |item|
@@ -24,28 +24,6 @@ module ViewComponent
24
24
  )
25
25
  end
26
26
 
27
- # Remove any existing singleton methods,
28
- # as Ruby warns when redefining a method.
29
- component_class.remove_possible_singleton_method(:collection_parameter)
30
- component_class.remove_possible_singleton_method(:collection_counter_parameter)
31
- component_class.remove_possible_singleton_method(:counter_argument_present?)
32
-
33
- component_class.define_singleton_method(:collection_parameter) do
34
- if provided_collection_parameter
35
- provided_collection_parameter
36
- else
37
- name.demodulize.underscore.chomp("_component").to_sym
38
- end
39
- end
40
-
41
- component_class.define_singleton_method(:collection_counter_parameter) do
42
- "#{collection_parameter}_counter".to_sym
43
- end
44
-
45
- component_class.define_singleton_method(:counter_argument_present?) do
46
- instance_method(:initialize).parameters.map(&:second).include?(collection_counter_parameter)
47
- end
48
-
49
27
  if raise_errors
50
28
  component_class.validate_initialization_parameters!
51
29
  component_class.validate_collection_parameter!
@@ -83,7 +61,7 @@ module ViewComponent
83
61
  "elsif variant.to_sym == :#{variant}\n #{call_method_name(variant)}"
84
62
  end.join("\n")
85
63
 
86
- component_class.class_eval <<-RUBY
64
+ component_class.class_eval <<-RUBY, __FILE__, __LINE__ + 1
87
65
  def render_template_for(variant = nil)
88
66
  if variant.nil?
89
67
  call
@@ -136,50 +114,18 @@ module ViewComponent
136
114
  end
137
115
 
138
116
  def templates
139
- @templates ||= matching_views_in_source_location.each_with_object([]) do |path, memo|
140
- pieces = File.basename(path).split(".")
141
-
142
- memo << {
143
- path: path,
144
- variant: pieces.second.split("+").second&.to_sym,
145
- handler: pieces.last
146
- }
147
- end
148
- end
149
-
150
- def matching_views_in_source_location
151
- source_location = component_class.source_location
152
- return [] unless source_location
153
-
154
- extensions = ActionView::Template.template_handler_extensions.join(",")
155
-
156
- # view files in a directory named like the component
157
- directory = File.dirname(source_location)
158
- filename = File.basename(source_location, ".rb")
159
- component_name = component_class.name.demodulize.underscore
160
-
161
- # Add support for nested components defined in the same file.
162
- #
163
- # e.g.
164
- #
165
- # class MyComponent < ViewComponent::Base
166
- # class MyOtherComponent < ViewComponent::Base
167
- # end
168
- # end
169
- #
170
- # Without this, `MyOtherComponent` will not look for `my_component/my_other_component.html.erb`
171
- nested_component_files = if component_class.name.include?("::") && component_name != filename
172
- Dir["#{directory}/#{filename}/#{component_name}.*{#{extensions}}"]
173
- else
174
- []
117
+ @templates ||= begin
118
+ extensions = ActionView::Template.template_handler_extensions
119
+
120
+ component_class._sidecar_files(extensions).each_with_object([]) do |path, memo|
121
+ pieces = File.basename(path).split(".")
122
+ memo << {
123
+ path: path,
124
+ variant: pieces.second.split("+").second&.to_sym,
125
+ handler: pieces.last
126
+ }
127
+ end
175
128
  end
176
-
177
- # view files in the same directory as the component
178
- sidecar_files = Dir["#{directory}/#{component_name}.*{#{extensions}}"]
179
-
180
- sidecar_directory_files = Dir["#{directory}/#{component_name}/#{filename}.*{#{extensions}}"]
181
-
182
- (sidecar_files - [source_location] + sidecar_directory_files + nested_component_files)
183
129
  end
184
130
 
185
131
  def inline_calls
@@ -90,7 +90,7 @@ module ViewComponent
90
90
  options = app.config.view_component
91
91
 
92
92
  if options.show_previews
93
- app.routes.append do
93
+ app.routes.prepend do
94
94
  preview_controller = options.preview_controller.sub(/Controller$/, "").underscore
95
95
 
96
96
  get options.preview_route, to: "#{preview_controller}#index", as: :preview_view_components, internal: true
@@ -25,15 +25,22 @@ module ViewComponent
25
25
  return @content if defined?(@content)
26
26
 
27
27
  view_context = @parent.send(:view_context)
28
- @content = view_context.capture do
29
- if defined?(@_component_instance)
30
- # render_in is faster than `parent.render`
31
- @_component_instance.render_in(view_context, &@_content_block)
32
- elsif defined?(@_content)
33
- @_content
34
- elsif defined?(@_content_block)
35
- @_content_block.call
28
+
29
+ @content = if defined?(@_component_instance)
30
+ # render_in is faster than `parent.render`
31
+ if defined?(@_content_block)
32
+ view_context.capture do
33
+ @_component_instance.render_in(view_context, &@_content_block)
34
+ end
35
+ else
36
+ view_context.capture do
37
+ @_component_instance.render_in(view_context)
38
+ end
36
39
  end
40
+ elsif defined?(@_content)
41
+ @_content
42
+ elsif defined?(@_content_block)
43
+ view_context.capture(&@_content_block)
37
44
  end
38
45
 
39
46
  @content
@@ -49,13 +49,19 @@ module ViewComponent
49
49
 
50
50
  # If the slot is a collection, define an accesor that defaults to an empty array
51
51
  if collection
52
- class_eval <<-RUBY
52
+ class_eval <<-RUBY, __FILE__, __LINE__ + 1
53
53
  def #{accessor_name}
54
+ content unless content_evaluated? # ensure content is loaded so slots will be defined
54
55
  #{instance_variable_name} ||= []
55
56
  end
56
57
  RUBY
57
58
  else
58
- attr_reader accessor_name
59
+ class_eval <<-RUBY, __FILE__, __LINE__ + 1
60
+ def #{accessor_name}
61
+ content unless content_evaluated? # ensure content is loaded so slots will be defined
62
+ #{instance_variable_name} if defined?(#{instance_variable_name})
63
+ end
64
+ RUBY
59
65
  end
60
66
 
61
67
  # Default class_name to ViewComponent::Slot
@@ -183,6 +183,8 @@ module ViewComponent
183
183
  end
184
184
 
185
185
  def get_slot(slot_name)
186
+ content unless content_evaluated? # ensure content is loaded so slots will be defined
187
+
186
188
  slot = self.class.registered_slots[slot_name]
187
189
  @_set_slots ||= {}
188
190
 
@@ -224,7 +226,13 @@ module ViewComponent
224
226
  # Use `bind(self)` to ensure lambda is executed in the context of the
225
227
  # current component. This is necessary to allow the lambda to access helper
226
228
  # methods like `content_tag` as well as parent component state.
227
- renderable_value = slot_definition[:renderable_function].bind(self).call(*args, **kwargs, &block)
229
+ renderable_value = if block_given?
230
+ slot_definition[:renderable_function].bind(self).call(*args, **kwargs) do |*args, **kwargs|
231
+ view_context.capture(*args, **kwargs, &block)
232
+ end
233
+ else
234
+ slot_definition[:renderable_function].bind(self).call(*args, **kwargs)
235
+ end
228
236
 
229
237
  # Function calls can return components, so if it's a component handle it specially
230
238
  if renderable_value.respond_to?(:render_in)
@@ -35,7 +35,7 @@ module ViewComponent
35
35
  end
36
36
 
37
37
  def controller
38
- @controller ||= Base.test_controller.constantize.new.tap { |c| c.request = request }.extend(Rails.application.routes.url_helpers)
38
+ @controller ||= build_controller(Base.test_controller.constantize)
39
39
  end
40
40
 
41
41
  def request
@@ -47,7 +47,21 @@ module ViewComponent
47
47
 
48
48
  controller.view_context.lookup_context.variants = variant
49
49
  yield
50
+ ensure
50
51
  controller.view_context.lookup_context.variants = old_variants
51
52
  end
53
+
54
+ def with_controller_class(klass)
55
+ old_controller = defined?(@controller) && @controller
56
+
57
+ @controller = build_controller(klass)
58
+ yield
59
+ ensure
60
+ @controller = old_controller
61
+ end
62
+
63
+ def build_controller(klass)
64
+ klass.new.tap { |c| c.request = request }.extend(Rails.application.routes.url_helpers)
65
+ end
52
66
  end
53
67
  end
@@ -0,0 +1,81 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "set"
4
+ require "i18n"
5
+ require "action_view/helpers/translation_helper"
6
+ require "active_support/concern"
7
+
8
+ module ViewComponent
9
+ module Translatable
10
+ extend ActiveSupport::Concern
11
+
12
+ included do
13
+ class_attribute :i18n_backend, instance_writer: false, instance_predicate: false
14
+ end
15
+
16
+ class_methods do
17
+ def i18n_scope
18
+ @i18n_scope ||= virtual_path.sub(%r{^/}, "").gsub(%r{/_?}, ".")
19
+ end
20
+
21
+ def _after_compile
22
+ super
23
+
24
+ unless CompileCache.compiled? self
25
+ self.i18n_backend = I18nBackend.new(
26
+ i18n_scope: i18n_scope,
27
+ load_paths: _sidecar_files(%w[yml yaml]),
28
+ )
29
+ end
30
+ end
31
+ end
32
+
33
+ class I18nBackend < ::I18n::Backend::Simple
34
+ EMPTY_HASH = {}.freeze
35
+
36
+ def initialize(i18n_scope:, load_paths:)
37
+ @i18n_scope = i18n_scope.split(".")
38
+ @load_paths = load_paths
39
+ end
40
+
41
+ # Ensure the Simple backend won't load paths from ::I18n.load_path
42
+ def load_translations
43
+ super(@load_paths)
44
+ end
45
+
46
+ def scope_data(data)
47
+ @i18n_scope.reverse_each do |part|
48
+ data = { part => data}
49
+ end
50
+ data
51
+ end
52
+
53
+ def store_translations(locale, data, options = EMPTY_HASH)
54
+ super(locale, scope_data(data), options)
55
+ end
56
+ end
57
+
58
+ def translate(key = nil, locale: nil, **options)
59
+ locale ||= ::I18n.locale
60
+
61
+ key = "#{i18n_scope}#{key}" if key.start_with?(".")
62
+
63
+ result = catch(:exception) do
64
+ i18n_backend.translate(locale, key, options)
65
+ end
66
+
67
+ # Fallback to the global translations
68
+ if result.is_a? ::I18n::MissingTranslation
69
+ result = helpers.t(key, locale: locale, **options)
70
+ end
71
+
72
+ result
73
+ end
74
+ alias :t :translate
75
+
76
+ # Exposes .i18n_scope as an instance method
77
+ def i18n_scope
78
+ self.class.i18n_scope
79
+ end
80
+ end
81
+ end
@@ -3,9 +3,11 @@
3
3
  module ViewComponent
4
4
  module VERSION
5
5
  MAJOR = 2
6
- MINOR = 25
7
- PATCH = 1
6
+ MINOR = 29
7
+ PATCH = 0
8
8
 
9
9
  STRING = [MAJOR, MINOR, PATCH].join(".")
10
10
  end
11
11
  end
12
+
13
+ puts ViewComponent::VERSION::STRING if __FILE__ == $PROGRAM_NAME
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.25.1
4
+ version: 2.29.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - GitHub Open Source
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-02-01 00:00:00.000000000 Z
11
+ date: 2021-04-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -128,6 +128,20 @@ dependencies:
128
128
  - - "~>"
129
129
  - !ruby/object:Gem::Version
130
130
  version: '1'
131
+ - !ruby/object:Gem::Dependency
132
+ name: jbuilder
133
+ requirement: !ruby/object:Gem::Requirement
134
+ requirements:
135
+ - - "~>"
136
+ - !ruby/object:Gem::Version
137
+ version: '2'
138
+ type: :development
139
+ prerelease: false
140
+ version_requirements: !ruby/object:Gem::Requirement
141
+ requirements:
142
+ - - "~>"
143
+ - !ruby/object:Gem::Version
144
+ version: '2'
131
145
  - !ruby/object:Gem::Dependency
132
146
  name: rubocop
133
147
  requirement: !ruby/object:Gem::Requirement
@@ -249,6 +263,7 @@ files:
249
263
  - lib/view_component/template_error.rb
250
264
  - lib/view_component/test_case.rb
251
265
  - lib/view_component/test_helpers.rb
266
+ - lib/view_component/translatable.rb
252
267
  - lib/view_component/version.rb
253
268
  homepage: https://github.com/github/view_component
254
269
  licenses:
@@ -270,7 +285,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
270
285
  - !ruby/object:Gem::Version
271
286
  version: '0'
272
287
  requirements: []
273
- rubygems_version: 3.0.3
288
+ rubygems_version: 3.1.2
274
289
  signing_key:
275
290
  specification_version: 4
276
291
  summary: View components for Rails