view_component 2.44.0 → 2.48.0

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.

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: []