view_component 2.44.0 → 2.48.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of view_component might be problematic. Click here for more details.

checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2542c18f4fbd3071c18fb27d8edb563021ad201fa5cc4d0c02fb8190918b6920
4
- data.tar.gz: 7c7fb2ef2a79ed3816655cd8f27a52248fe0181957487a9b0297968914034c9f
3
+ metadata.gz: 3abce9e08dcb71614178ed68b9c8443211ff78790911057752d8fda6fbb194b7
4
+ data.tar.gz: 3ac0a8ff1d7cafd2eb12e04a24f1d8f3362675833e4fda780bc238b8fc5ed41f
5
5
  SHA512:
6
- metadata.gz: 4e43d3b7398bd838b25e87a566ce82229e82343f64a9f70230b90d4eb2b0afdc8e0ffda355acd032877d0751082e3e4342ecd53955011de89ea1ce341c6b7a80
7
- data.tar.gz: 3d90591c1d4d3cbff9d8e4c7dd1f94015ddce95e62f8284586dda63da99311609c3558fd353f0cf3c6b8c58f4c9a0b18f0fa91e60aa2275e57284cb2e10bff4a
6
+ metadata.gz: dba31d0d37e73b7a1e26863d167f5d1eaefb8c5f53d9f542e47667090802b5f53b5c6b9c4b0a9188bf76f42d375c5d7a2cd3024065620aa9ff40b15911706cb8
7
+ data.tar.gz: f329872b25f36fe8fa0d018c2a5847ed0b6e47b095d16a27e89d2b0c7180f938d09730d0868405483a8e7c4fe4075afed56927a018b7a273ac4c94950d174fac
data/README.md CHANGED
@@ -1,4 +1,5 @@
1
- <img src="/docs/logo/github-readme-logo.svg" alt="ViewComponent logo" width="400">
1
+ ![ViewComponent logo](/docs/logo/readme-light.svg#gh-light-mode-only)
2
+ ![ViewComponent logo](/docs/logo/readme-dark.svg#gh-dark-mode-only)
2
3
 
3
4
  A framework for building reusable, testable & encapsulated view components in Ruby on Rails.
4
5
 
@@ -29,12 +29,11 @@ class ViewComponentsController < Rails::ApplicationController # :nodoc:
29
29
  @example_name = File.basename(params[:path])
30
30
  @render_args = @preview.render_args(@example_name, params: params.permit!)
31
31
  layout = determine_layout(@render_args[:layout], prepend_views: false)[:layout]
32
- template = @render_args[:template]
33
32
  locals = @render_args[:locals]
34
33
  opts = {}
35
34
  opts[:layout] = layout if layout.present? || layout == false
36
35
  opts[:locals] = locals if locals.present?
37
- render template, opts # rubocop:disable GitHub/RailsControllerRenderLiteral
36
+ render "view_components/preview", opts # rubocop:disable GitHub/RailsControllerRenderLiteral
38
37
  end
39
38
  end
40
39
 
@@ -4,16 +4,64 @@ module PreviewHelper
4
4
  AVAILABLE_PRISM_LANGUAGES = ["ruby", "erb", "haml"]
5
5
  FALLBACK_LANGUAGE = "ruby"
6
6
 
7
- def prism_language_name(template:)
7
+ def preview_source
8
+ return if @render_args.nil?
9
+
10
+ render "preview_source" # rubocop:disable GitHub/RailsViewRenderPathsExist
11
+ end
12
+
13
+ def find_template_data(lookup_context:, template_identifier:)
14
+ template = lookup_context.find_template(template_identifier)
15
+
16
+ if Rails.version.to_f >= 6.1 || template.source.present?
17
+ return {
18
+ source: template.source,
19
+ prism_language_name: prism_language_name_by_template(template: template)
20
+ }
21
+ else
22
+ # Fetch template source via finding it through preview paths
23
+ # to accomodate source view when exclusively using templates
24
+ # for previews for Rails < 6.1.
25
+ all_template_paths = ViewComponent::Base.preview_paths.map do |preview_path|
26
+ Dir.glob("#{preview_path}/**/*")
27
+ end.flatten
28
+
29
+ # Search for templates the contain `html`.
30
+ matching_templates = all_template_paths.find_all do |template|
31
+ template =~ /#{template_identifier}*.(html)/
32
+ end
33
+
34
+ # In-case of a conflict due to multiple template files with
35
+ # the same name
36
+ raise "found 0 matches for templates for #{template_identifier}." if matching_templates.empty?
37
+ raise "found multiple templates for #{template_identifier}." if matching_templates.size > 1
38
+
39
+ template_file_path = matching_templates.first
40
+ template_source = File.read(template_file_path)
41
+ prism_language_name = prism_language_name_by_template_path(template_file_path: template_file_path)
42
+
43
+ return {
44
+ source: template_source,
45
+ prism_language_name: prism_language_name
46
+ }
47
+ end
48
+ end
49
+
50
+ private
51
+
52
+ def prism_language_name_by_template(template:)
8
53
  language = template.identifier.split(".").last
54
+
9
55
  return FALLBACK_LANGUAGE unless AVAILABLE_PRISM_LANGUAGES.include? language
10
56
 
11
57
  language
12
58
  end
13
59
 
14
- def preview_source
15
- return if @render_args.nil?
60
+ def prism_language_name_by_template_path(template_file_path:)
61
+ language = template_file_path.gsub(".html", "").split(".").last
16
62
 
17
- render "preview_source" # rubocop:disable GitHub/RailsViewRenderPathsExist
63
+ return FALLBACK_LANGUAGE unless AVAILABLE_PRISM_LANGUAGES.include? language
64
+
65
+ language
18
66
  end
19
67
  end
@@ -7,9 +7,9 @@
7
7
  <%= h @preview.preview_source(@example_name) %>
8
8
  </code>
9
9
  <% else %>
10
- <% template = @view_renderer.lookup_context.find_template(@render_args[:template]) %>
11
- <code class="language-<%= prism_language_name(template: template) %>">
12
- <%= h template.source %>
10
+ <% template_data = find_template_data(lookup_context: @view_renderer.lookup_context, template_identifier: @render_args[:template]) %>
11
+ <code class="language-<%= template_data[:prism_language_name] %>">
12
+ <%= h template_data[:source] %>
13
13
  </code>
14
14
  <% end %>
15
15
  </pre>
@@ -1,7 +1,11 @@
1
- <% if ViewComponent::Base.render_monkey_patch_enabled || Rails.version.to_f >= 6.1 %>
2
- <%= render(@render_args[:component], @render_args[:args], &@render_args[:block]) %>
1
+ <% if @render_args[:component] %>
2
+ <% if ViewComponent::Base.render_monkey_patch_enabled || Rails.version.to_f >= 6.1 %>
3
+ <%= render(@render_args[:component], @render_args[:args], &@render_args[:block]) %>
4
+ <% else %>
5
+ <%= render_component(@render_args[:component], &@render_args[:block]) %>
6
+ <% end %>
3
7
  <% else %>
4
- <%= render_component(@render_args[:component], &@render_args[:block]) %>
8
+ <%= render template: @render_args[:template], locals: @render_args[:locals] || {} %>
5
9
  <% end %>
6
10
 
7
11
  <% if ViewComponent::Base.show_previews_source %>
data/docs/CHANGELOG.md CHANGED
@@ -7,6 +7,203 @@ title: Changelog
7
7
 
8
8
  ## main
9
9
 
10
+ ## 2.48.0
11
+
12
+ * Correct path in example test command in Contributing docs.
13
+
14
+ *Mark Wilkinson*
15
+
16
+ * Update link to GOV.UK Components library in the resources list.
17
+
18
+ *Peter Yates*
19
+
20
+ * Add Lookbook to Resources docs page.
21
+
22
+ *Mark Perkins*
23
+
24
+ * Add blocking compiler mode for use in Rails development and testing modes, improving thread safety.
25
+
26
+ *Horia Radu*
27
+
28
+ * Add generators to support `tailwindcss-rails`.
29
+
30
+ *Dino Maric*, *Hans Lemuet*
31
+
32
+ * Add a namespaced component example to docs.
33
+
34
+ *Hans Lemuet*
35
+
36
+ * Setup `Appraisal` to add flexibility when testing ViewComponent against multiple Rails versions.
37
+
38
+ *Hans Lemuet*
39
+
40
+ * Return correct values for `request.path` and `request.query_string` methods when using the `with_request_url` test helper.
41
+
42
+ *Vasiliy Matyushin*
43
+
44
+ * Improve style in generators docs.
45
+
46
+ *Hans Lemuet*
47
+
48
+ * Correctly type Ruby version strings and update Rails versions used in CI configuration.
49
+
50
+ *Hans Lemuet*
51
+
52
+ * Make `ViewComponent::Collection` act like a collection of view components.
53
+
54
+ *Sammy Henningsson*
55
+
56
+ * Update `@param` of `#render_inline` to include `ViewComponent::Collection`.
57
+
58
+ *Yutaka Kamei*
59
+
60
+ * Add Wecasa to users list.
61
+
62
+ *Mohamed Ziata*
63
+
64
+ ## 2.47.0
65
+
66
+ * Display preview source on previews that exclusively use templates.
67
+
68
+ *Edwin Mak*
69
+
70
+ * Add a test to ensure trailing newlines are stripped when rendering with `#render_in`.
71
+
72
+ *Simon Fish*
73
+
74
+ * Add WEBrick as a depenency to the application.
75
+
76
+ *Connor McQuillan*
77
+
78
+ * Update Ruby version in `.tool-versions`.
79
+
80
+ *Connor McQuillan*
81
+
82
+ * Add a test to ensure blocks can be passed into lambda slots without the need for any other arguments.
83
+
84
+ *Simon Fish*
85
+
86
+ * Add linters for file consistency.
87
+
88
+ *Simon Fish*
89
+
90
+ * Add @boardfish to docs/index.md and sort contributors.
91
+
92
+ *Simon Fish*
93
+
94
+ * Set up Codespaces for bug replication.
95
+
96
+ *Simon Fish*
97
+
98
+ * Add instructions for replicating bugs and failures.
99
+
100
+ *Simon Fish*
101
+
102
+ * Make @boardfish a committer.
103
+
104
+ *Joel Hawksley*
105
+
106
+ * Validate collection parameter with Active Model attribute names.
107
+
108
+ *Simon Fish*
109
+
110
+ * Fix `helpers` not working with component slots when rendered more than 2 component levels deep.
111
+
112
+ *Blake Williams*
113
+
114
+ * Update ruby to the latest versions
115
+
116
+ *Pedro Paiva*
117
+
118
+ * Fix `vale` linter config options.
119
+
120
+ *Hans Lemuet*
121
+
122
+ * Improve Contributing docs to include how to run tests for a specific version on Rails.
123
+
124
+ *Hans Lemuet*
125
+
126
+ * Add failing test for default form builder and documentation around known issue.
127
+
128
+ *Simon Fish*
129
+
130
+ * Add `--locale` flag to the component generator. Generates as many locale files as defined in `I18n.available_locales`, alongside the component.
131
+ * Add config option `config.view_component.generate_locale` to enable project-wide locale generation.
132
+ * Add config option `config.view_component.generate_distinct_locale_files` to enable project-wide per-locale translations file generation.
133
+
134
+ *Bob Maerten*
135
+
136
+ * Add config option `config.view_component.generate_sidecar` to always generate in the sidecar directory.
137
+
138
+ *Gleydson Tavares*
139
+
140
+ ## 2.46.0
141
+
142
+ * Add thread safety to the compiler.
143
+
144
+ *Horia Radu*
145
+
146
+ * Add theme-specific logo images to readme.
147
+
148
+ *Dylan Smith*
149
+
150
+ * Add Orbit to users list.
151
+
152
+ *Nicolas Goutay*
153
+
154
+ * Increase clarity around purpose and use of slots.
155
+
156
+ *Simon Fish*
157
+
158
+ * Deprecate loading `view_component/engine` directly.
159
+
160
+ **Upgrade notice**: You should update your `Gemfile` like this:
161
+
162
+ ```diff
163
+ - gem "view_component", require: "view_component/engine"`
164
+ + gem "view_component"
165
+ ```
166
+
167
+ *Yoshiyuki Hirano*
168
+
169
+ ## 2.45.0
170
+
171
+ * Remove internal APIs from API documentation, fix link to license.
172
+
173
+ *Joel Hawksley*
174
+
175
+ * Add @yhirano55 to triage team.
176
+
177
+ *Joel Hawksley*
178
+
179
+ * Correct a typo in the sample slots code.
180
+
181
+ *Simon Fish*
182
+
183
+ * Add note about `allowed_queries`.
184
+
185
+ *Joel Hawksley*
186
+
187
+ * Add `vale` content linter.
188
+
189
+ *Joel Hawksley*
190
+
191
+ * Remove `require "rails/generators/test_case"` in generator tests.
192
+
193
+ *Yoshiyuki Hirano*
194
+
195
+ * Suppress zeitwerk warning about circular require.
196
+
197
+ *Yoshiyuki Hirano*
198
+
199
+ * Move `test_unit_generator_test.rb` from `test/view_component/` to `test/generators/`.
200
+
201
+ *Yoshiyuki Hirano*
202
+
203
+ * Unify test code of `TestUnitGeneratorTest` with the other generators tests.
204
+
205
+ *Yoshiyuki Hirano*
206
+
10
207
  ## 2.44.0
11
208
 
12
209
  * Rename internal accessor to use private naming.
@@ -142,7 +339,7 @@ title: Changelog
142
339
 
143
340
  *Matthew Rider*
144
341
 
145
- * Fix bug where `with_collection_parameter` did not inherit from parent component.
342
+ * Fix bug where `with_collection_parameter` didn't inherit from parent component.
146
343
 
147
344
  *Will Drexler*, *Christian Campoli*
148
345
 
@@ -346,7 +543,7 @@ title: Changelog
346
543
 
347
544
  *Hans Lemuet*
348
545
 
349
- * Fix bug where ViewComponents did not work in ActionMailers.
546
+ * Fix bug where ViewComponents didn't work in ActionMailers.
350
547
 
351
548
  *dark-panda*
352
549
 
@@ -394,7 +591,7 @@ title: Changelog
394
591
 
395
592
  ## 2.31.0
396
593
 
397
- _Note: This release includes an underlying change to Slots that may affect incorrect usage of the API, where Slots were set on a line prefixed by `<%=`. The result of setting a Slot should not be returned. (`<%`)_
594
+ _Note: This release includes an underlying change to Slots that may affect incorrect usage of the API, where Slots were set on a line prefixed by `<%=`. The result of setting a Slot shouldn't be returned. (`<%`)_
398
595
 
399
596
  * Add `#with_content` to allow setting content without a block.
400
597
 
@@ -405,7 +602,7 @@ _Note: This release includes an underlying change to Slots that may affect incor
405
602
  *Mario Schüttel*
406
603
 
407
604
  * Improve feature parity with Rails translations
408
- * Don't create a translation backend if the component has no translation file
605
+ * Don't create a translation back end if the component has no translation file
409
606
  * Mark translation keys ending with `html` as HTML-safe
410
607
  * Always convert keys to String
411
608
  * Support multiple keys
@@ -447,7 +644,7 @@ _Note: This release includes an underlying change to Slots that may affect incor
447
644
 
448
645
  *Alex Robbin, Blake Williams*
449
646
 
450
- * Experimental: call `._sidecar_files` to fetch the sidecar files for a given list of extensions, e.g. passing `["yml", "yaml"]`.
647
+ * Experimental: call `._sidecar_files` to fetch the sidecar files for a given list of extensions, for example passing `["yml", "yaml"]`.
451
648
 
452
649
  *Elia Schito*
453
650
 
@@ -487,11 +684,11 @@ _Note: This release includes an underlying change to Slots that may affect incor
487
684
 
488
685
  ## 2.26.0
489
686
 
490
- * Lazily evaluate component `content` in `render?`, preventing the `content` block from being evaluated when `render?` returns false.
687
+ * Delay evaluating component `content` in `render?`, preventing the `content` block from being evaluated when `render?` returns false.
491
688
 
492
689
  *Blake Williams*
493
690
 
494
- * Do not generate template when using `--inline` flag.
691
+ * Don't generate template when using `--inline` flag.
495
692
 
496
693
  *Hans Lemuet*
497
694
 
@@ -552,7 +749,7 @@ _Note: This release includes an underlying change to Slots that may affect incor
552
749
  * `with_slot collection: true` becomes `renders_many`.
553
750
  * Slot definitions now accept either a component class, component class name, or a lambda instead of a `class_name:` keyword argument.
554
751
  * Slots now support positional arguments.
555
- * Slots no longer use the `content` attribute to render content, instead relying on `to_s`. e.g. `<%= my_slot %>`.
752
+ * Slots no longer use the `content` attribute to render content, instead relying on `to_s`. for example `<%= my_slot %>`.
556
753
  * Slot values are no longer set via the `slot` method, and instead use the name of the slot.
557
754
 
558
755
  *Blake Williams*
@@ -615,7 +812,7 @@ _Note: This release includes an underlying change to Slots that may affect incor
615
812
 
616
813
  ## 2.18.2
617
814
 
618
- * Raise an error if controller or view context is accessed during initialize as they are only available in render.
815
+ * Raise an error if controller or view context is accessed during initialize as they're only available in render.
619
816
 
620
817
  *Julian Nadeau*
621
818
 
@@ -631,7 +828,7 @@ _Note: This release includes an underlying change to Slots that may affect incor
631
828
 
632
829
  ## 2.18.0
633
830
 
634
- * Fix auto-loading of previews (changes no longer require a server restart)
831
+ * Fix auto loading of previews (changes no longer require a server restart)
635
832
 
636
833
  *Matt Brictson*
637
834
 
@@ -724,7 +921,7 @@ _Note: This release includes an underlying change to Slots that may affect incor
724
921
 
725
922
  ## 2.10.0
726
923
 
727
- * Raise an `ArgumentError` with a helpful message when Ruby cannot parse a component class.
924
+ * Raise an `ArgumentError` with a helpful message when Ruby can't parse a component class.
728
925
 
729
926
  *Max Beizer*
730
927
 
@@ -816,7 +1013,7 @@ _Note: This release includes an underlying change to Slots that may affect incor
816
1013
 
817
1014
  ## v2.2.1
818
1015
 
819
- * Fix bug where template could not be found if `inherited` was redefined.
1016
+ * Fix bug where template couldn't be found if `inherited` was redefined.
820
1017
 
821
1018
  *Joel Hawksley*
822
1019
 
@@ -832,7 +1029,7 @@ _Note: This release includes an underlying change to Slots that may affect incor
832
1029
 
833
1030
  ## v2.1.0
834
1031
 
835
- * Support rendering collections (e.g., `render(MyComponent.with_collection(@items))`).
1032
+ * Support rendering collections (for example, `render(MyComponent.with_collection(@items))`).
836
1033
 
837
1034
  *Tim Clem*
838
1035
 
@@ -854,7 +1051,7 @@ _Note: This release includes an underlying change to Slots that may affect incor
854
1051
 
855
1052
  *Andrew Mason*
856
1053
 
857
- * ViewComponent generators do not not prompt for content requirement.
1054
+ * ViewComponent generators don't not prompt for content requirement.
858
1055
 
859
1056
  *Joel Hawksley*
860
1057
 
@@ -976,7 +1173,7 @@ _Note: This release includes an underlying change to Slots that may affect incor
976
1173
 
977
1174
  *Jon Palmer*
978
1175
 
979
- * Add `#render?` hook to easily allow components to be no-ops.
1176
+ * Add `#render?` hook to allow components to be no-ops.
980
1177
 
981
1178
  *Kyle Fox*
982
1179
 
@@ -1044,7 +1241,9 @@ _Note: This release includes an underlying change to Slots that may affect incor
1044
1241
 
1045
1242
  * Fix edge case issue with extracting variants from less conventional source_locations.
1046
1243
 
1244
+ <!-- vale proselint.GenderBias = NO -->
1047
1245
  *Ryan Workman*
1246
+ <!-- vale proselint.GenderBias = YES -->
1048
1247
 
1049
1248
  ## v1.6.0
1050
1249
 
@@ -1080,7 +1279,9 @@ _Note: This release includes an underlying change to Slots that may affect incor
1080
1279
 
1081
1280
  * Add support for RSpec to generators.
1082
1281
 
1282
+ <!-- vale proselint.GenderBias = NO -->
1083
1283
  *Dylan Clark, Ryan Workman*
1284
+ <!-- vale proselint.GenderBias = YES -->
1084
1285
 
1085
1286
  * Require controllers as part of setting autoload paths.
1086
1287
 
@@ -1104,7 +1305,9 @@ Note: `actionview-component` is now loaded by requiring `actionview/component`,
1104
1305
 
1105
1306
  * Fix issue with generating component method signatures.
1106
1307
 
1308
+ <!-- vale proselint.GenderBias = NO -->
1107
1309
  *Ryan Workman, Dylan Clark*
1310
+ <!-- vale proselint.GenderBias = YES -->
1108
1311
 
1109
1312
  * Create component generator.
1110
1313
 
@@ -1176,7 +1379,7 @@ Note: `actionview-component` is now loaded by requiring `actionview/component`,
1176
1379
 
1177
1380
  ## v1.3.3
1178
1381
 
1179
- * Do not raise error when sidecar files that are not templates exist.
1382
+ * Don't raise error when sidecar files that aren't templates exist.
1180
1383
 
1181
1384
  *Joel Hawksley*
1182
1385
 
@@ -15,7 +15,7 @@ module ViewComponent
15
15
  end
16
16
 
17
17
  def destination_directory
18
- if options["sidecar"]
18
+ if sidecar?
19
19
  File.join(component_path, class_path, destination_file_name)
20
20
  else
21
21
  File.join(component_path, class_path)
@@ -42,5 +42,9 @@ module ViewComponent
42
42
  gsub("/", "--")
43
43
  end
44
44
  end
45
+
46
+ def sidecar?
47
+ options["sidecar"] || ViewComponent::Base.generate_sidecar
48
+ end
45
49
  end
46
50
  end
@@ -15,6 +15,7 @@ module Rails
15
15
  class_option :parent, type: :string, desc: "The parent class for the generated component"
16
16
  class_option :stimulus, type: :boolean, default: ViewComponent::Base.generate_stimulus_controller
17
17
  class_option :sidecar, type: :boolean, default: false
18
+ class_option :locale, type: :boolean, default: ViewComponent::Base.generate_locale
18
19
 
19
20
  def create_component_file
20
21
  template "component.rb", File.join(component_path, class_path, "#{file_name}_component.rb")
@@ -26,6 +27,8 @@ module Rails
26
27
 
27
28
  hook_for :stimulus, type: :boolean
28
29
 
30
+ hook_for :locale, type: :boolean
31
+
29
32
  hook_for :template_engine do |instance, template_engine|
30
33
  instance.invoke template_engine, [instance.name]
31
34
  end
@@ -6,7 +6,7 @@ class <%= class_name %>Component < <%= parent_class %>
6
6
  <%= initialize_body %>
7
7
  end
8
8
  <%- end -%>
9
- <%- if initialize_call_method_for_inline? -%>
9
+ <%- if initialize_call_method_for_inline? -%>
10
10
  def call
11
11
  content_tag :h1, "Hello world!"<%= ", data: { controller: \"#{stimulus_controller}\" }" if options["stimulus"] %>
12
12
  end
@@ -0,0 +1,46 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "rails/generators/abstract_generator"
4
+
5
+ module Locale
6
+ module Generators
7
+ class ComponentGenerator < ::Rails::Generators::NamedBase
8
+ include ViewComponent::AbstractGenerator
9
+
10
+ source_root File.expand_path("templates", __dir__)
11
+ argument :attributes, type: :array, default: [], banner: "attribute"
12
+ class_option :sidecar, type: :boolean, default: false
13
+
14
+ def create_locale_file
15
+ if ViewComponent::Base.generate_distinct_locale_files
16
+ I18n.available_locales.each do |locale|
17
+ create_file destination(locale), translations_hash([locale]).to_yaml
18
+ end
19
+ else
20
+ create_file destination, translations_hash(I18n.available_locales).to_yaml
21
+ end
22
+ end
23
+
24
+ private
25
+
26
+ def translations_hash(locales = [:en])
27
+ locales.map { |locale| [locale.to_s, translation_keys] }.to_h
28
+ end
29
+
30
+ def translation_keys
31
+ keys = attributes.map(&:name)
32
+ keys = %w[hello] if keys.empty?
33
+ keys.map { |name| [name, name.capitalize] }.to_h
34
+ end
35
+
36
+ def destination(locale = nil)
37
+ extention = ".#{locale}" if locale
38
+ if sidecar?
39
+ File.join(component_path, class_path, "#{file_name}_component", "#{file_name}_component#{extention}.yml")
40
+ else
41
+ File.join(component_path, class_path, "#{file_name}_component#{extention}.yml")
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
@@ -23,7 +23,7 @@ module Stimulus
23
23
  private
24
24
 
25
25
  def destination
26
- if options["sidecar"]
26
+ if sidecar?
27
27
  File.join(component_path, class_path, "#{file_name}_component", "#{file_name}_component_controller.js")
28
28
  else
29
29
  File.join(component_path, class_path, "#{file_name}_component_controller.js")
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "rails/generators/erb/component_generator"
4
+
5
+ module Tailwindcss
6
+ module Generators
7
+ class ComponentGenerator < Erb::Generators::ComponentGenerator
8
+ source_root File.expand_path("templates", __dir__)
9
+ end
10
+ end
11
+ end
@@ -0,0 +1 @@
1
+ <div<%= data_attributes %>>Add <%= class_name %> template here</div>
@@ -152,7 +152,7 @@ module ViewComponent
152
152
  if view_context.nil?
153
153
  raise(
154
154
  ViewContextCalledBeforeRenderError,
155
- "`#controller` cannot be used during initialization, as it depends " \
155
+ "`#controller` can't be used during initialization, as it depends " \
156
156
  "on the view context that only exists once a ViewComponent is passed to " \
157
157
  "the Rails render pipeline.\n\n" \
158
158
  "It's sometimes possible to fix this issue by moving code dependent on " \
@@ -171,7 +171,7 @@ module ViewComponent
171
171
  if view_context.nil?
172
172
  raise(
173
173
  ViewContextCalledBeforeRenderError,
174
- "`#helpers` cannot be used during initialization, as it depends " \
174
+ "`#helpers` can't be used during initialization, as it depends " \
175
175
  "on the view context that only exists once a ViewComponent is passed to " \
176
176
  "the Rails render pipeline.\n\n" \
177
177
  "It's sometimes possible to fix this issue by moving code dependent on " \
@@ -206,7 +206,7 @@ module ViewComponent
206
206
  #
207
207
  # @private
208
208
  def format
209
- # Ruby 2.6 throws a warning without checking `defined?`, 2.7 does not
209
+ # Ruby 2.6 throws a warning without checking `defined?`, 2.7 doesn't
210
210
  if defined?(@__vc_variant)
211
211
  @__vc_variant
212
212
  end
@@ -279,11 +279,31 @@ module ViewComponent
279
279
  #
280
280
  mattr_accessor :generate_stimulus_controller, instance_writer: false, default: false
281
281
 
282
+ # Always generate translations file alongside the component:
283
+ #
284
+ # config.view_component.generate_locale = true
285
+ #
286
+ # Defaults to `false`.
287
+ #
288
+ mattr_accessor :generate_locale, instance_writer: false, default: false
289
+
290
+ # Always generate as many translations files as available locales:
291
+ #
292
+ # config.view_component.generate_distinct_locale_files = true
293
+ #
294
+ # Defaults to `false`.
295
+ #
296
+ # One file will be generated for each configured `I18n.available_locales`.
297
+ # Fallback on `[:en]` when no available_locales is defined.
298
+ #
299
+ mattr_accessor :generate_distinct_locale_files, instance_writer: false, default: false
300
+
282
301
  # Path for component files
283
302
  #
284
303
  # config.view_component.view_component_path = "app/my_components"
285
304
  #
286
- # Defaults to "app/components".
305
+ # Defaults to `app/components`.
306
+ #
287
307
  mattr_accessor :view_component_path, instance_writer: false, default: "app/components"
288
308
 
289
309
  # Parent class for generated components
@@ -291,8 +311,16 @@ module ViewComponent
291
311
  # config.view_component.component_parent_class = "MyBaseComponent"
292
312
  #
293
313
  # Defaults to "ApplicationComponent" if defined, "ViewComponent::Base" otherwise.
294
- mattr_accessor :component_parent_class,
295
- instance_writer: false
314
+ #
315
+ mattr_accessor :component_parent_class, instance_writer: false
316
+
317
+ # Always generate a component with a sidecar directory:
318
+ #
319
+ # config.view_component.generate_sidecar = true
320
+ #
321
+ # Defaults to `false`.
322
+ #
323
+ mattr_accessor :generate_sidecar, instance_writer: false, default: false
296
324
 
297
325
  class << self
298
326
  # @private
@@ -318,7 +346,7 @@ module ViewComponent
318
346
 
319
347
  # Add support for nested components defined in the same file.
320
348
  #
321
- # e.g.
349
+ # for example
322
350
  #
323
351
  # class MyComponent < ViewComponent::Base
324
352
  # class MyOtherComponent < ViewComponent::Base
@@ -431,7 +459,7 @@ module ViewComponent
431
459
  end
432
460
 
433
461
  # Ensure the component initializer accepts the
434
- # collection parameter. By default, we do not
462
+ # collection parameter. By default, we don't
435
463
  # validate that the default parameter name
436
464
  # is accepted, as support for collection
437
465
  # rendering is optional.
@@ -442,7 +470,7 @@ module ViewComponent
442
470
  return unless parameter
443
471
  return if initialize_parameter_names.include?(parameter)
444
472
 
445
- # If Ruby cannot parse the component class, then the initalize
473
+ # If Ruby can't parse the component class, then the initalize
446
474
  # parameters will be empty and ViewComponent will not be able to render
447
475
  # the component.
448
476
  if initialize_parameters.empty?
@@ -455,14 +483,14 @@ module ViewComponent
455
483
  end
456
484
 
457
485
  raise ArgumentError.new(
458
- "The initializer for #{self} does not accept the parameter `#{parameter}`, " \
486
+ "The initializer for #{self} doesn't accept the parameter `#{parameter}`, " \
459
487
  "which is required in order to render it as a collection.\n\n" \
460
488
  "To fix this issue, update the initializer to accept `#{parameter}`.\n\n" \
461
489
  "See https://viewcomponent.org/guide/collections.html for more information on rendering collections."
462
490
  )
463
491
  end
464
492
 
465
- # Ensure the component initializer does not define
493
+ # Ensure the component initializer doesn't define
466
494
  # invalid parameters that could override the framework's
467
495
  # methods.
468
496
  # @private TODO: add documentation
@@ -470,7 +498,7 @@ module ViewComponent
470
498
  return unless initialize_parameter_names.include?(RESERVED_PARAMETER)
471
499
 
472
500
  raise ViewComponent::ComponentError.new(
473
- "#{self} initializer cannot accept the parameter `#{RESERVED_PARAMETER}`, as it will override a " \
501
+ "#{self} initializer can't accept the parameter `#{RESERVED_PARAMETER}`, as it will override a " \
474
502
  "public ViewComponent method. To fix this issue, rename the parameter."
475
503
  )
476
504
  end
@@ -507,6 +535,10 @@ module ViewComponent
507
535
  private
508
536
 
509
537
  def initialize_parameter_names
538
+ return attribute_names.map(&:to_sym) if respond_to?(:attribute_names)
539
+
540
+ return attribute_types.keys.map(&:to_sym) if Rails::VERSION::MAJOR <= 5 && respond_to?(:attribute_types)
541
+
510
542
  initialize_parameters.map(&:last)
511
543
  end
512
544
 
@@ -4,20 +4,34 @@ require "action_view/renderer/collection_renderer" if Rails.version.to_f >= 6.1
4
4
 
5
5
  module ViewComponent
6
6
  class Collection
7
+ include Enumerable
7
8
  attr_reader :component
8
9
 
9
10
  delegate :format, to: :component
11
+ delegate :size, to: :@collection
10
12
 
11
13
  def render_in(view_context, &block)
14
+ components.map do |component|
15
+ component.render_in(view_context, &block)
16
+ end.join.html_safe # rubocop:disable Rails/OutputSafety
17
+ end
18
+
19
+ def components
20
+ return @components if defined? @components
21
+
12
22
  iterator = ActionView::PartialIteration.new(@collection.size)
13
23
 
14
24
  component.validate_collection_parameter!(validate_default: true)
15
25
 
16
- @collection.map do |item|
17
- content = component.new(**component_options(item, iterator)).render_in(view_context, &block)
18
- iterator.iterate!
19
- content
20
- end.join.html_safe # rubocop:disable Rails/OutputSafety
26
+ @components = @collection.map do |item|
27
+ component.new(**component_options(item, iterator)).tap do |component|
28
+ iterator.iterate!
29
+ end
30
+ end
31
+ end
32
+
33
+ def each(&block)
34
+ components.each(&block)
21
35
  end
22
36
 
23
37
  private
@@ -42,7 +56,7 @@ module ViewComponent
42
56
  def component_options(item, iterator)
43
57
  item_options = { component.collection_parameter => item }
44
58
  item_options[component.collection_counter_parameter] = iterator.index + 1 if component.counter_argument_present?
45
- item_options[component.collection_iteration_parameter] = iterator if component.iteration_argument_present?
59
+ item_options[component.collection_iteration_parameter] = iterator.dup if component.iteration_argument_present?
46
60
 
47
61
  @options.merge(item_options)
48
62
  end
@@ -2,7 +2,7 @@
2
2
 
3
3
  module ViewComponent
4
4
  # Keeps track of which templates have already been compiled
5
- # This is not part of the public API
5
+ # This isn't part of the public API
6
6
  module CompileCache
7
7
  mattr_accessor :cache, instance_reader: false, instance_accessor: false do
8
8
  Set.new
@@ -18,6 +18,10 @@ module ViewComponent
18
18
  cache.include? klass
19
19
  end
20
20
 
21
+ def invalidate_class!(klass)
22
+ cache.delete(klass)
23
+ end
24
+
21
25
  def invalidate!
22
26
  cache.clear
23
27
  end
@@ -2,66 +2,95 @@
2
2
 
3
3
  module ViewComponent
4
4
  class Compiler
5
+ # Lock required to be obtained before compiling the component
6
+ attr_reader :__vc_compiler_lock
7
+
8
+ # Compiler mode. Can be either:
9
+ # * development (a blocking mode which ensures thread safety when redefining the `call` method for components,
10
+ # default in Rails development and test mode)
11
+ # * production (a non-blocking mode, default in Rails production mode)
12
+ DEVELOPMENT_MODE = :development
13
+ PRODUCTION_MODE = :production
14
+
15
+ class_attribute :mode, default: PRODUCTION_MODE
16
+
5
17
  def initialize(component_class)
6
18
  @component_class = component_class
19
+ @__vc_compiler_lock = Monitor.new
7
20
  end
8
21
 
9
22
  def compiled?
10
23
  CompileCache.compiled?(component_class)
11
24
  end
12
25
 
26
+ def development?
27
+ self.class.mode == DEVELOPMENT_MODE
28
+ end
29
+
13
30
  def compile(raise_errors: false)
14
31
  return if compiled?
15
32
 
16
- subclass_instance_methods = component_class.instance_methods(false)
33
+ with_lock do
34
+ CompileCache.invalidate_class!(component_class)
17
35
 
18
- if subclass_instance_methods.include?(:with_content) && raise_errors
19
- raise ViewComponent::ComponentError.new(
20
- "#{component_class} implements a reserved method, `#with_content`.\n\n" \
21
- "To fix this issue, change the name of the method."
22
- )
23
- end
24
-
25
- if template_errors.present?
26
- raise ViewComponent::TemplateError.new(template_errors) if raise_errors
36
+ subclass_instance_methods = component_class.instance_methods(false)
27
37
 
28
- return false
29
- end
38
+ if subclass_instance_methods.include?(:with_content) && raise_errors
39
+ raise ViewComponent::ComponentError.new(
40
+ "#{component_class} implements a reserved method, `#with_content`.\n\n" \
41
+ "To fix this issue, change the name of the method."
42
+ )
43
+ end
30
44
 
31
- if subclass_instance_methods.include?(:before_render_check)
32
- ActiveSupport::Deprecation.warn(
33
- "`#before_render_check` will be removed in v3.0.0.\n\n" \
34
- "To fix this issue, use `#before_render` instead."
35
- )
36
- end
45
+ if template_errors.present?
46
+ raise ViewComponent::TemplateError.new(template_errors) if raise_errors
37
47
 
38
- if raise_errors
39
- component_class.validate_initialization_parameters!
40
- component_class.validate_collection_parameter!
41
- end
48
+ return false
49
+ end
42
50
 
43
- templates.each do |template|
44
- # Remove existing compiled template methods,
45
- # as Ruby warns when redefining a method.
46
- method_name = call_method_name(template[:variant])
51
+ if subclass_instance_methods.include?(:before_render_check)
52
+ ActiveSupport::Deprecation.warn(
53
+ "`#before_render_check` will be removed in v3.0.0.\n\n" \
54
+ "To fix this issue, use `#before_render` instead."
55
+ )
56
+ end
47
57
 
48
- if component_class.instance_methods.include?(method_name.to_sym)
49
- component_class.send(:undef_method, method_name.to_sym)
58
+ if raise_errors
59
+ component_class.validate_initialization_parameters!
60
+ component_class.validate_collection_parameter!
50
61
  end
51
62
 
52
- component_class.class_eval <<-RUBY, template[:path], -1
63
+ templates.each do |template|
64
+ # Remove existing compiled template methods,
65
+ # as Ruby warns when redefining a method.
66
+ method_name = call_method_name(template[:variant])
67
+
68
+ if component_class.instance_methods.include?(method_name.to_sym)
69
+ component_class.send(:undef_method, method_name.to_sym)
70
+ end
71
+
72
+ component_class.class_eval <<-RUBY, template[:path], -1
53
73
  def #{method_name}
54
74
  @output_buffer = ActionView::OutputBuffer.new
55
75
  #{compiled_template(template[:path])}
56
76
  end
57
- RUBY
58
- end
77
+ RUBY
78
+ end
79
+
80
+ define_render_template_for
59
81
 
60
- define_render_template_for
82
+ component_class._after_compile
61
83
 
62
- component_class._after_compile
84
+ CompileCache.register(component_class)
85
+ end
86
+ end
63
87
 
64
- CompileCache.register(component_class)
88
+ def with_lock(&block)
89
+ if development?
90
+ __vc_compiler_lock.synchronize(&block)
91
+ else
92
+ block.call
93
+ end
65
94
  end
66
95
 
67
96
  private
@@ -77,16 +106,30 @@ module ViewComponent
77
106
  "elsif variant.to_sym == :#{variant}\n #{call_method_name(variant)}"
78
107
  end.join("\n")
79
108
 
80
- component_class.class_eval <<-RUBY, __FILE__, __LINE__ + 1
109
+ body = <<-RUBY
110
+ if variant.nil?
111
+ call
112
+ #{variant_elsifs}
113
+ else
114
+ call
115
+ end
116
+ RUBY
117
+
118
+ if development?
119
+ component_class.class_eval <<-RUBY, __FILE__, __LINE__ + 1
81
120
  def render_template_for(variant = nil)
82
- if variant.nil?
83
- call
84
- #{variant_elsifs}
85
- else
86
- call
121
+ self.class.compiler.with_lock do
122
+ #{body}
87
123
  end
88
124
  end
89
- RUBY
125
+ RUBY
126
+ else
127
+ component_class.class_eval <<-RUBY, __FILE__, __LINE__ + 1
128
+ def render_template_for(variant = nil)
129
+ #{body}
130
+ end
131
+ RUBY
132
+ end
90
133
  end
91
134
 
92
135
  def template_errors
@@ -95,7 +138,7 @@ module ViewComponent
95
138
  errors = []
96
139
 
97
140
  if (templates + inline_calls).empty?
98
- errors << "Could not find a template file or inline render method for #{component_class}."
141
+ errors << "Couldn't find a template file or inline render method for #{component_class}."
99
142
  end
100
143
 
101
144
  if templates.count { |template| template[:variant].nil? } > 1
@@ -1,7 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "rails"
4
- require "view_component"
5
4
 
6
5
  module ViewComponent
7
6
  class Engine < Rails::Engine # :nodoc:
@@ -116,6 +115,14 @@ module ViewComponent
116
115
  end
117
116
  end
118
117
 
118
+ initializer "compiler mode" do |app|
119
+ ViewComponent::Compiler.mode = if Rails.env.development? || Rails.env.test?
120
+ ViewComponent::Compiler::DEVELOPMENT_MODE
121
+ else
122
+ ViewComponent::Compiler::PRODUCTION_MODE
123
+ end
124
+ end
125
+
119
126
  config.after_initialize do |app|
120
127
  options = app.config.view_component
121
128
 
@@ -145,3 +152,14 @@ module ViewComponent
145
152
  end
146
153
  end
147
154
  end
155
+
156
+ # :nocov:
157
+ unless defined?(ViewComponent::Base)
158
+ ActiveSupport::Deprecation.warn(
159
+ "This manually engine loading is deprecated and will be removed in v3.0.0. " \
160
+ "Remove `require \"view_component/engine\"`."
161
+ )
162
+
163
+ require "view_component"
164
+ end
165
+ # :nocov:
@@ -80,7 +80,7 @@ module ViewComponent # :nodoc:
80
80
  if preview_path.nil?
81
81
  raise(
82
82
  PreviewTemplateError,
83
- "A preview template for example #{example} does not exist.\n\n" \
83
+ "A preview template for example #{example} doesn't exist.\n\n" \
84
84
  "To fix this issue, create a template for the example."
85
85
  )
86
86
  end
@@ -20,7 +20,7 @@ module ViewComponent
20
20
  # component, or a function that returns a component, we render that
21
21
  # component instance, returning the string.
22
22
  #
23
- # If the slot renderable is a function and returns a string, it is
23
+ # If the slot renderable is a function and returns a string, it's
24
24
  # set as `@__vc_content` and is returned directly.
25
25
  #
26
26
  # If there is no slot renderable, we evaluate the block passed to
@@ -40,6 +40,8 @@ module ViewComponent
40
40
 
41
41
  @content =
42
42
  if defined?(@__vc_component_instance)
43
+ @__vc_component_instance.__vc_original_view_context = @parent.__vc_original_view_context
44
+
43
45
  if defined?(@__vc_content_set_by_with_content)
44
46
  @__vc_component_instance.with_content(@__vc_content_set_by_with_content)
45
47
 
@@ -69,7 +71,7 @@ module ViewComponent
69
71
 
70
72
  # Allow access to public component methods via the wrapper
71
73
  #
72
- # e.g.
74
+ # for example
73
75
  #
74
76
  # calling `header.name` (where `header` is a slot) will call `name`
75
77
  # on the `HeaderComponent` instance.
@@ -29,12 +29,12 @@ module ViewComponent
29
29
  )
30
30
 
31
31
  slot_names.each do |slot_name|
32
- # Ensure slot_name is not already declared
32
+ # Ensure slot_name isn't already declared
33
33
  if self.slots.key?(slot_name)
34
34
  raise ArgumentError.new("#{slot_name} slot declared multiple times")
35
35
  end
36
36
 
37
- # Ensure slot name is not :content
37
+ # Ensure slot name isn't :content
38
38
  if slot_name == :content
39
39
  raise ArgumentError.new ":content is a reserved slot name. Please use another name, such as ':body'"
40
40
  end
@@ -105,7 +105,7 @@ module ViewComponent
105
105
  # <% end %>
106
106
  #
107
107
  def slot(slot_name, **args, &block)
108
- # Raise ArgumentError if `slot` does not exist
108
+ # Raise ArgumentError if `slot` doesn't exist
109
109
  unless slots.keys.include?(slot_name)
110
110
  raise ArgumentError.new "Unknown slot '#{slot_name}' - expected one of '#{slots.keys}'"
111
111
  end
@@ -140,7 +140,7 @@ module ViewComponent
140
140
  instance_variable_set(slot[:instance_variable_name], slot_instance)
141
141
  end
142
142
 
143
- # Return nil, as this method should not output anything to the view itself.
143
+ # Return nil, as this method shouldn't output anything to the view itself.
144
144
  nil
145
145
  end
146
146
  end
@@ -121,7 +121,7 @@ module ViewComponent
121
121
  singular_name = ActiveSupport::Inflector.singularize(slot_name)
122
122
 
123
123
  # Define setter for singular names
124
- # e.g. `renders_many :items` allows fetching all tabs with
124
+ # for example `renders_many :items` allows fetching all tabs with
125
125
  # `component.tabs` and setting a tab with `component.tab`
126
126
  define_method singular_name do |*args, &block|
127
127
  set_slot(slot_name, nil, *args, &block)
@@ -181,7 +181,7 @@ module ViewComponent
181
181
  # If callable is a string, we assume it's referencing an internal class
182
182
  slot[:renderable_class_name] = callable
183
183
  elsif callable.respond_to?(:call)
184
- # If slot does not respond to `render_in`, we assume it's a proc,
184
+ # If slot doesn't respond to `render_in`, we assume it's a proc,
185
185
  # define a method, and save a reference to it to call when setting
186
186
  method_name = :"_call_#{slot_name}"
187
187
  define_method method_name, &callable
@@ -256,7 +256,7 @@ module ViewComponent
256
256
  # 1. If this is a `content_area` style sub-component, we will render the
257
257
  # block via the `slot`
258
258
  #
259
- # 2. Since we have to pass block content to components when calling
259
+ # 2. Since we've to pass block content to components when calling
260
260
  # `render`, evaluating the block here would require us to call
261
261
  # `view_context.capture` twice, which is slower
262
262
  slot.__vc_content_block = block if block_given?
@@ -38,7 +38,7 @@ module ViewComponent
38
38
  # assert_text("Hello, World!")
39
39
  # ```
40
40
  #
41
- # @param component [ViewComponent::Base] The instance of the component to be rendered.
41
+ # @param component [ViewComponent::Base, ViewComponent::Collection] The instance of the component to be rendered.
42
42
  # @return [Nokogiri::HTML]
43
43
  def render_inline(component, **args, &block)
44
44
  @rendered_component =
@@ -103,7 +103,7 @@ module ViewComponent
103
103
  @controller = old_controller
104
104
  end
105
105
 
106
- # Set the URL for the current request (such as when using request-dependent path helpers):
106
+ # Set the URL of the current request (such as when using request-dependent path helpers):
107
107
  #
108
108
  # ```ruby
109
109
  # with_request_url("/users/42") do
@@ -113,16 +113,22 @@ module ViewComponent
113
113
  #
114
114
  # @param path [String] The path to set for the current request.
115
115
  def with_request_url(path)
116
+ old_request_path_info = request.path_info
116
117
  old_request_path_parameters = request.path_parameters
117
118
  old_request_query_parameters = request.query_parameters
119
+ old_request_query_string = request.query_string
118
120
  old_controller = defined?(@controller) && @controller
119
121
 
122
+ request.path_info = path
120
123
  request.path_parameters = Rails.application.routes.recognize_path(path)
121
124
  request.set_header("action_dispatch.request.query_parameters", Rack::Utils.parse_query(path.split("?")[1]))
125
+ request.set_header(Rack::QUERY_STRING, path.split("?")[1])
122
126
  yield
123
127
  ensure
128
+ request.path_info = old_request_path_info
124
129
  request.path_parameters = old_request_path_parameters
125
130
  request.set_header("action_dispatch.request.query_parameters", old_request_query_parameters)
131
+ request.set_header(Rack::QUERY_STRING, old_request_query_string)
126
132
  @controller = old_controller
127
133
  end
128
134
 
@@ -3,7 +3,7 @@
3
3
  module ViewComponent
4
4
  module VERSION
5
5
  MAJOR = 2
6
- MINOR = 44
6
+ MINOR = 48
7
7
  PATCH = 0
8
8
 
9
9
  STRING = [MAJOR, MINOR, PATCH].join(".")
@@ -19,4 +19,13 @@ module ViewComponent
19
19
  autoload :Translatable
20
20
  end
21
21
 
22
- require "view_component/engine" if defined?(Rails::Engine)
22
+ # :nocov:
23
+ if defined?(ViewComponent::Engine)
24
+ ActiveSupport::Deprecation.warn(
25
+ "This manually engine loading is deprecated and will be removed in v3.0.0. " \
26
+ "Remove `require \"view_component/engine\"`."
27
+ )
28
+ elsif defined?(Rails::Engine)
29
+ require "view_component/engine"
30
+ end
31
+ # :nocov:
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.44.0
4
+ version: 2.48.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - GitHub Open Source
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-11-18 00:00:00.000000000 Z
11
+ date: 2022-01-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -44,6 +44,20 @@ dependencies:
44
44
  - - "~>"
45
45
  - !ruby/object:Gem::Version
46
46
  version: '1.0'
47
+ - !ruby/object:Gem::Dependency
48
+ name: appraisal
49
+ requirement: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - "~>"
52
+ - !ruby/object:Gem::Version
53
+ version: '2.4'
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - "~>"
59
+ - !ruby/object:Gem::Version
60
+ version: '2.4'
47
61
  - !ruby/object:Gem::Dependency
48
62
  name: benchmark-ips
49
63
  requirement: !ruby/object:Gem::Requirement
@@ -268,7 +282,7 @@ dependencies:
268
282
  - - ">="
269
283
  - !ruby/object:Gem::Version
270
284
  version: '0'
271
- description:
285
+ description:
272
286
  email:
273
287
  - opensource+view_component@github.com
274
288
  executables: []
@@ -295,6 +309,7 @@ files:
295
309
  - lib/rails/generators/erb/templates/component.html.erb.tt
296
310
  - lib/rails/generators/haml/component_generator.rb
297
311
  - lib/rails/generators/haml/templates/component.html.haml.tt
312
+ - lib/rails/generators/locale/component_generator.rb
298
313
  - lib/rails/generators/preview/component_generator.rb
299
314
  - lib/rails/generators/preview/templates/component_preview.rb.tt
300
315
  - lib/rails/generators/rspec/component_generator.rb
@@ -303,6 +318,8 @@ files:
303
318
  - lib/rails/generators/slim/templates/component.html.slim.tt
304
319
  - lib/rails/generators/stimulus/component_generator.rb
305
320
  - lib/rails/generators/stimulus/templates/component_controller.js.tt
321
+ - lib/rails/generators/tailwindcss/component_generator.rb
322
+ - lib/rails/generators/tailwindcss/templates/component.html.erb.tt
306
323
  - lib/rails/generators/test_unit/component_generator.rb
307
324
  - lib/rails/generators/test_unit/templates/component_test.rb.tt
308
325
  - lib/view_component.rb
@@ -341,7 +358,7 @@ licenses:
341
358
  - MIT
342
359
  metadata:
343
360
  allowed_push_host: https://rubygems.org
344
- post_install_message:
361
+ post_install_message:
345
362
  rdoc_options: []
346
363
  require_paths:
347
364
  - lib
@@ -356,8 +373,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
356
373
  - !ruby/object:Gem::Version
357
374
  version: '0'
358
375
  requirements: []
359
- rubygems_version: 3.1.2
360
- signing_key:
376
+ rubygems_version: 3.1.4
377
+ signing_key:
361
378
  specification_version: 4
362
379
  summary: View components for Rails
363
380
  test_files: []