view_component 3.12.1 → 3.23.2

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.
Files changed (35) hide show
  1. checksums.yaml +4 -4
  2. data/app/controllers/concerns/view_component/preview_actions.rb +8 -1
  3. data/app/helpers/preview_helper.rb +1 -1
  4. data/app/views/view_components/_preview_source.html.erb +1 -1
  5. data/docs/CHANGELOG.md +299 -5
  6. data/lib/rails/generators/abstract_generator.rb +9 -1
  7. data/lib/rails/generators/component/component_generator.rb +2 -1
  8. data/lib/rails/generators/component/templates/component.rb.tt +3 -2
  9. data/lib/rails/generators/erb/component_generator.rb +1 -1
  10. data/lib/rails/generators/preview/templates/component_preview.rb.tt +2 -0
  11. data/lib/rails/generators/rspec/templates/component_spec.rb.tt +1 -1
  12. data/lib/rails/generators/stimulus/component_generator.rb +8 -3
  13. data/lib/rails/generators/stimulus/templates/component_controller.ts.tt +9 -0
  14. data/lib/rails/generators/test_unit/templates/component_test.rb.tt +1 -1
  15. data/lib/view_component/base.rb +52 -59
  16. data/lib/view_component/collection.rb +18 -3
  17. data/lib/view_component/compiler.rb +164 -240
  18. data/lib/view_component/config.rb +26 -2
  19. data/lib/view_component/configurable.rb +17 -0
  20. data/lib/view_component/engine.rb +21 -11
  21. data/lib/view_component/errors.rb +7 -5
  22. data/lib/view_component/instrumentation.rb +1 -1
  23. data/lib/view_component/preview.rb +1 -1
  24. data/lib/view_component/rails/tasks/view_component.rake +8 -2
  25. data/lib/view_component/slotable.rb +28 -14
  26. data/lib/view_component/slotable_default.rb +20 -0
  27. data/lib/view_component/template.rb +134 -0
  28. data/lib/view_component/test_helpers.rb +29 -2
  29. data/lib/view_component/use_helpers.rb +32 -10
  30. data/lib/view_component/version.rb +2 -2
  31. metadata +112 -19
  32. data/lib/rails/generators/component/USAGE +0 -13
  33. data/lib/view_component/docs_builder_component.html.erb +0 -22
  34. data/lib/view_component/docs_builder_component.rb +0 -96
  35. data/lib/yard/mattr_accessor_handler.rb +0 -19
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 875f47469a83b3b70de2e4271cc4af72542d88c6e12c373c8f6912d3c8c6d13e
4
- data.tar.gz: 161671b627c087f227706c10e6ca7f900dcdd3d2ea49232024543bf78a3be14b
3
+ metadata.gz: 79672f93bd1c3bfa2dae00890f833c5dfb63dec49585dd79453f6592f9f47520
4
+ data.tar.gz: e6fe55dfe963ce0e7f4d793c93b67aefa92c99ee834c17c35644a9ea8b746886
5
5
  SHA512:
6
- metadata.gz: aaa215e2aba616eca2ea0e1bd1e4ab76df2f6f4f34d1f3f225a5802a943b8e6c8e920b3821fda06353e52979345a8d941c2d3d2eaa24b71a6928502846224acc
7
- data.tar.gz: f7da13dfa835866ac685d567f41549857ca40682e6f2beee269bf07b4b9bfaf942af62d03dbcc019cb72ef349ed8c601be24c1598efd0cb38e26397decb4e09a
6
+ metadata.gz: 311478a282f72c7b703594ec119dfc2686ec8cd3c6d6e97ff9fab9a32638e09eacefdc82a3808c581e48ab2af4cbfb26f66c7064cb614367cb4916fdf3b7df76
7
+ data.tar.gz: 3c059cb40bfa81c45a60bc9d107be8402923f92f0a8e1b50c6cdfcad88a4da6407244f1e5220d58f59a938c3d77e748ec22f360b8cf49041279616138ac4397d
@@ -14,7 +14,14 @@ module ViewComponent
14
14
 
15
15
  # Including helpers here ensures that we're loading the
16
16
  # latest version of helpers if code-reloading is enabled
17
- helper :all if include_all_helpers
17
+ if include_all_helpers
18
+ helper :all
19
+ else
20
+ # :nocov:
21
+ # Always provide the #view_source helper
22
+ helper PreviewHelper
23
+ # :nocov:
24
+ end
18
25
  end
19
26
 
20
27
  def index
@@ -22,7 +22,7 @@ module PreviewHelper
22
22
  serve_static_preview_assets? ? asset_path("prism.min.js", skip_pipeline: true) : "https://cdn.jsdelivr.net/npm/prismjs@1.28.0/prism.min.js"
23
23
  end
24
24
 
25
- def find_template_data(lookup_context:, template_identifier:)
25
+ def find_template_data_for_preview_source(lookup_context:, template_identifier:)
26
26
  template = lookup_context.find_template(template_identifier)
27
27
 
28
28
  if Rails.version.to_f >= 6.1 || template.source.present?
@@ -7,7 +7,7 @@
7
7
  <%= h @preview.preview_source(@example_name) %>
8
8
  </code>
9
9
  <% else %>
10
- <% template_data = find_template_data(lookup_context: @view_renderer.lookup_context, template_identifier: @render_args[:template]) %>
10
+ <% template_data = find_template_data_for_preview_source(lookup_context: @view_renderer.lookup_context, template_identifier: @render_args[:template]) %>
11
11
  <code class="language-<%= template_data[:prism_language_name] %>">
12
12
  <%= h template_data[:source] %>
13
13
  </code>
data/docs/CHANGELOG.md CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  layout: default
3
3
  title: Changelog
4
- nav_order: 5
4
+ nav_order: 6
5
5
  ---
6
6
 
7
7
  <!-- Add unreleased changes under the "main" heading. -->
@@ -10,6 +10,300 @@ nav_order: 5
10
10
 
11
11
  ## main
12
12
 
13
+ ## 3.23.2
14
+
15
+ * Include .tt files in published gem. Fixes templates not being available when using generators.
16
+
17
+ *Florian Aßmann*
18
+
19
+ ## 3.23.1
20
+
21
+ * Restore Rake tasks in published gem.
22
+
23
+ *Franz Liedke*
24
+
25
+ ## 3.23.0
26
+
27
+ * Add docs about Slack channel in Ruby Central workspace. (Join us! #oss-view-component). Email joelhawksley@github.com for an invite.
28
+
29
+ *Joel Hawksley
30
+
31
+ * Do not include internal `DocsBuilderComponent` or `YARD::MattrAccessorHandler` in published gem.
32
+
33
+ *Joel Hawksley*
34
+
35
+ * Only lock to `concurrent-ruby` `1.3.4` for Rails 6.1.
36
+
37
+ *Joel Hawksley*
38
+
39
+ * Fix generation of ViewComponent documentation that was broken due to HTML safety issues.
40
+
41
+ *Simon Fish*
42
+
43
+ * Add documentation on how ViewComponent works.
44
+
45
+ *Joel Hawksley*
46
+
47
+ * Clarify that `config.use_deprecated_instrumentation_name` will be removed in v4.
48
+
49
+ *Joel Hawksley*
50
+
51
+ * Run RSpec tests in CI.
52
+
53
+ *Joel Hawksley*
54
+
55
+ ## 3.22.0
56
+
57
+ * Rewrite `ViewComponents at GitHub` documentation as more general `Best practices`.
58
+
59
+ *Phil Schalm*, *Joel Hawksley*
60
+
61
+ * Add unused mechanism for inheriting config from parent modules to enable future engine-local configuration.
62
+
63
+ *Simon Fish*
64
+
65
+ * Improve handling of malformed component edge case when mocking components in tests.
66
+
67
+ *Martin Meyerhoff*, *Joel Hawksley*
68
+
69
+ * Add Content Harmony & Learn To Be to list of companies using ViewComponent.
70
+
71
+ *Kane Jamison*
72
+
73
+ * Clarify error message about render-dependent logic.
74
+
75
+ Error messages about render-dependent logic were sometimes inaccurate, saying `during initialization` despite also being raised after a component had been initialized but before it was rendered.
76
+
77
+ *Joel Hawksley*
78
+
79
+ * Remove JS and CSS docs as they proved difficult to maintain and lacked consensus.
80
+
81
+ *Joel Hawksley*
82
+
83
+ * Do not prefix release tags with `v`, per recommendation from @bkuhlmann.
84
+
85
+ *Joel Hawksley*
86
+
87
+ * Add ruby 3.4 support to CI.
88
+
89
+ *Reegan Viljoen*
90
+
91
+ * Add HomeStyler AI to list of companies using ViewComponent.
92
+
93
+ *JP Balarini*
94
+
95
+ ## 3.21.0
96
+
97
+ * Updates testing docs to include an example of how to use with RSpec.
98
+
99
+ *Rylan Bowers*
100
+
101
+ * Add `--skip-suffix` option to component generator.
102
+
103
+ *KAWAKAMI Moeki*
104
+
105
+ * Add FreeATS to list of companies using ViewComponent.
106
+
107
+ *Ilia Liamshin*
108
+
109
+ * Ensure HTML output safety wrapper is used for all inline templates.
110
+
111
+ *Joel Hawksley*
112
+
113
+ * Expose `.identifier` method as part of public API.
114
+
115
+ *Joel Hawksley*
116
+
117
+ * Add rails 8 support to CI.
118
+
119
+ *Reegan Viljoen*
120
+
121
+ * Updates ActionText compatibility documentation to reference `rich_textarea_tag` for Rails 8.0 support.
122
+
123
+ *Alvin Crespo*
124
+
125
+ ## 3.20.0
126
+
127
+ * Allow rendering `with_collection` to accept an optional `spacer_component` to be rendered between each item.
128
+
129
+ *Nick Coyne*
130
+
131
+ * Remove OpenStruct from codebase.
132
+
133
+ *Oleksii Vasyliev*
134
+
135
+ ## 3.19.0
136
+
137
+ * Relax Active Support version constraint in gemspec.
138
+
139
+ *Simon Fish*
140
+
141
+ ## 3.18.0
142
+
143
+ * Enable components to use `@request` and `request` methods/ivars.
144
+
145
+ *Blake Williams*
146
+
147
+ * Fix bug where implicit locales in component filenames threw a `NameError`.
148
+
149
+ *Chloe Fons*
150
+
151
+ * Register ViewComponent tests directory for `rails stats`.
152
+
153
+ *Javier Aranda*
154
+
155
+ * Wrap entire compile step in a mutex to make it more resilient to race conditions.
156
+
157
+ *Blake Williams*
158
+
159
+ * Add [Niva]([niva.co](https://www.niva.co/)) to companies who use `ViewComponent`.
160
+
161
+ *Daniel Vu Dao*
162
+
163
+ * Fix `preview_paths` in docs.
164
+
165
+ *Javier Aranda*
166
+
167
+ ## 3.17.0
168
+
169
+ * Use struct instead openstruct in lib code.
170
+
171
+ *Oleksii Vasyliev*
172
+
173
+ * Fix bug where stimulus controller was not added to ERB when stimulus was activated by default.
174
+
175
+ *Denis Pasin*
176
+
177
+ * Add typescript support to stimulus generator.
178
+
179
+ *Denis Pasin*
180
+
181
+ * Fix the example of #vc_test_request in the API reference to use the correct method name.
182
+
183
+ *Alberto Rocha*
184
+
185
+ * Fix development mode race condition that caused an invalid duplicate template error.
186
+
187
+ *Blake Williams*
188
+
189
+ ## 3.16.0
190
+
191
+ * Add template information to multiple template error messages.
192
+
193
+ *Joel Hawksley*
194
+
195
+ * Add `ostruct` to gemspec file to suppress stdlib removal warning.
196
+
197
+ *Jonathan Underwood*
198
+
199
+ ## 3.15.1
200
+
201
+ * Re-add `@private`, undocumented `.identifier` method that was only meant for internal framework use but was used by some downstream consumers. This method will be removed in a coming minor release.
202
+
203
+ *Joel Hawksley*
204
+
205
+ ## 3.15.0
206
+
207
+ * Add basic internal testing for memory allocations.
208
+
209
+ *Joel Hawksley*
210
+
211
+ * Add support for request formats.
212
+
213
+ *Joel Hawksley*
214
+
215
+ * Add `rendered_json` test helper.
216
+
217
+ *Joel Hawksley*
218
+
219
+ * Add `with_format` test helper.
220
+
221
+ *Joel Hawksley*
222
+
223
+ * Warn if using Ruby < 3.2 or Rails < 7.1, which won't be supported by ViewComponent v4, to be released no earlier than April 1, 2025.
224
+
225
+ *Joel Hawksley*
226
+
227
+ * Add Kicksite to list of companies using ViewComponent.
228
+
229
+ *Adil Lari*
230
+
231
+ * Allow overridden slot methods to use `super`.
232
+
233
+ *Andrew Schwartz*
234
+
235
+ * Add Rails engine support to generators.
236
+
237
+ *Tomasz Kowalewski*
238
+
239
+ * Register stats directories with `Rails::CodeStatistics.register_directory` to support `rails stats` in Rails 8.
240
+
241
+ *Petrik de Heus*
242
+
243
+ * Fixed type declaration for `ViewComponent::TestHelpers.with_controller_class` parameter.
244
+
245
+ *Graham Rogers*
246
+
247
+ ## 3.14.0
248
+
249
+ * Defer to built-in caching for language environment setup, rather than manually using `actions/cache` in CI.
250
+
251
+ *Simon Fish*
252
+
253
+ * Add test coverage for use of `turbo_stream` helpers in components when `capture_compatibility_patch_enabled` is `true`.
254
+
255
+ *Simon Fish*
256
+
257
+ * Add experimental `SlotableDefault` module, allowing components to define a `default_SLOTNAME` method to provide a default value for slots.
258
+
259
+ *Joel Hawksley*
260
+
261
+ * Add documentation on rendering ViewComponents outside of the view context.
262
+
263
+ *Joel Hawksley*
264
+
265
+ * Look for preview files that end in `preview.rb` rather than `_preview.rb` to allow previews to exist in sidecar directory with test files.
266
+
267
+ *Seth Herr*
268
+
269
+ * Add `assert_component_rendered` test helper.
270
+
271
+ *Reegan Viljoen*
272
+
273
+ * Add `prefix:` option to `use_helpers`.
274
+
275
+ *Reegan Viljoen*
276
+
277
+ * Add support for Rails 7.2.
278
+
279
+ *Reegan Viljoen*
280
+
281
+ ## 3.13.0
282
+
283
+ * Add ruby head and YJIT to CI.
284
+
285
+ *Reegan Viljoen*
286
+
287
+ * Fixed a bug where inline templates where unable to remove trailing whitespace without throwing an error.
288
+
289
+ *Reegan Viljoen*
290
+
291
+ * Fixed CI for Rails main.
292
+
293
+ *Reegan Viljoen*
294
+
295
+ * Add `from:` option to `use_helpers` to allow for more flexible helper inclusion from modules.
296
+
297
+ *Reegan Viljoen*
298
+
299
+ * Fixed ruby head matcher issue.
300
+
301
+ *Reegan Viljoen*
302
+
303
+ * Fix a bug where component previews would crash with "undefined local variable or method `preview_source`."
304
+
305
+ *Henning Koch*
306
+
13
307
  ## 3.12.1
14
308
 
15
309
  * Ensure content is rendered correctly for forwarded slots.
@@ -24,15 +318,15 @@ nav_order: 5
24
318
 
25
319
  * Fix templates not being correctly populated when caller location label has a prefix.
26
320
 
27
- On the upstream version of Ruby, method owners are now included in backtraces as prefixes. This caused the call stack filtering to not work as intended and thus `source_location` to be incorrect for child ViewComponents, consequently not populating templates correctly.
321
+ On the upstream version of Ruby, method owners are now included in backtraces as prefixes. This caused the call stack filtering to not work as intended and thus `source_location` to be incorrect for child ViewComponents, consequently not populating templates correctly.
28
322
 
29
323
  *Allan Pires, Jason Kim*
30
324
 
31
325
  * Use component path for generating RSpec files.
32
326
 
33
- When generating new RSpec files for components, the generator will use the `view_component_path` value in the config to decide where to put the new spec file. For instance, if the `view_component_path` option has been changed to `app/views/components`, the generator will put the spec file in `spec/views/components`. **If the `view_component_path` doesn't start with `app/`, then the generator will fall back to `spec/components/`.**
327
+ When generating new RSpec files for components, the generator will use the `view_component_path` value in the config to decide where to put the new spec file. For instance, if the `view_component_path` option has been changed to `app/views/components`, the generator will put the spec file in `spec/views/components`. **If the `view_component_path` doesn't start with `app/`, then the generator will fall back to `spec/components/`.**
34
328
 
35
- This feature is enabled via the `config.view_component.generate.use_component_path_for_rspec_tests` option, defaulting to `false`. The default will change to `true` in ViewComponent v4.
329
+ This feature is enabled via the `config.view_component.generate.use_component_path_for_rspec_tests` option, defaulting to `false`. The default will change to `true` in ViewComponent v4.
36
330
 
37
331
  *William Mathewson*
38
332
 
@@ -56,7 +350,7 @@ This feature is enabled via the `config.view_component.generate.use_component_pa
56
350
 
57
351
  * Include ViewComponent::UseHelpers by default.
58
352
 
59
- *Reegan Viljoen*
353
+ *Reegan Viljoen*
60
354
 
61
355
  * Bump `puma` in Gemfile.lock.
62
356
 
@@ -33,7 +33,7 @@ module ViewComponent
33
33
  end
34
34
 
35
35
  def stimulus_controller
36
- if options["stimulus"]
36
+ if stimulus?
37
37
  File.join(destination_directory, destination_file_name)
38
38
  .sub("#{component_path}/", "")
39
39
  .tr("_", "-")
@@ -44,5 +44,13 @@ module ViewComponent
44
44
  def sidecar?
45
45
  options["sidecar"] || ViewComponent::Base.config.generate.sidecar
46
46
  end
47
+
48
+ def stimulus?
49
+ options["stimulus"] || ViewComponent::Base.config.generate.stimulus_controller
50
+ end
51
+
52
+ def typescript?
53
+ options["typescript"] || ViewComponent::Base.config.generate.typescript
54
+ end
47
55
  end
48
56
  end
@@ -19,9 +19,10 @@ module Rails
19
19
  class_option :sidecar, type: :boolean, default: false
20
20
  class_option :stimulus, type: :boolean,
21
21
  default: ViewComponent::Base.config.generate.stimulus_controller
22
+ class_option :skip_suffix, type: :boolean, default: false
22
23
 
23
24
  def create_component_file
24
- template "component.rb", File.join(component_path, class_path, "#{file_name}_component.rb")
25
+ template "component.rb", File.join(component_path, class_path, "#{file_name}#{options[:skip_suffix] ? "" : "_component"}.rb")
25
26
  end
26
27
 
27
28
  hook_for :test_framework
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- class <%= class_name %>Component < <%= parent_class %>
3
+ <% module_namespacing do -%>
4
+ class <%= class_name %><%= options[:skip_suffix] ? "" : "Component" %> < <%= parent_class %>
4
5
  <%- if initialize_signature -%>
5
6
  def initialize(<%= initialize_signature %>)
6
7
  <%= initialize_body %>
@@ -11,5 +12,5 @@ class <%= class_name %>Component < <%= parent_class %>
11
12
  content_tag :h1, "Hello world!"<%= ", data: { controller: \"#{stimulus_controller}\" }" if options["stimulus"] %>
12
13
  end
13
14
  <%- end -%>
14
-
15
15
  end
16
+ <% end -%>
@@ -24,7 +24,7 @@ module Erb
24
24
  private
25
25
 
26
26
  def data_attributes
27
- if options["stimulus"]
27
+ if stimulus?
28
28
  " data-controller=\"#{stimulus_controller}\""
29
29
  end
30
30
  end
@@ -1,7 +1,9 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ <% module_namespacing do -%>
3
4
  class <%= class_name %>ComponentPreview < ViewComponent::Preview
4
5
  def default
5
6
  render(<%= class_name %>Component.new<%= "(#{render_signature})" if render_signature %>)
6
7
  end
7
8
  end
9
+ <% end -%>
@@ -2,7 +2,7 @@
2
2
 
3
3
  require "rails_helper"
4
4
 
5
- RSpec.describe <%= class_name %>Component, type: :component do
5
+ RSpec.describe <%= namespaced? ? "#{namespace.name}::" : '' %><%= class_name %>Component, type: :component do
6
6
  pending "add some examples to (or delete) #{__FILE__}"
7
7
 
8
8
  # it "renders something useful" do
@@ -9,9 +9,10 @@ module Stimulus
9
9
 
10
10
  source_root File.expand_path("templates", __dir__)
11
11
  class_option :sidecar, type: :boolean, default: false
12
+ class_option :typescript, type: :boolean, default: false
12
13
 
13
14
  def create_stimulus_controller
14
- template "component_controller.js", destination
15
+ template "component_controller.#{filetype}", destination
15
16
  end
16
17
 
17
18
  def stimulus_module
@@ -22,11 +23,15 @@ module Stimulus
22
23
 
23
24
  private
24
25
 
26
+ def filetype
27
+ typescript? ? "ts" : "js"
28
+ end
29
+
25
30
  def destination
26
31
  if sidecar?
27
- File.join(component_path, class_path, "#{file_name}_component", "#{file_name}_component_controller.js")
32
+ File.join(component_path, class_path, "#{file_name}_component", "#{file_name}_component_controller.#{filetype}")
28
33
  else
29
- File.join(component_path, class_path, "#{file_name}_component_controller.js")
34
+ File.join(component_path, class_path, "#{file_name}_component_controller.#{filetype}")
30
35
  end
31
36
  end
32
37
 
@@ -0,0 +1,9 @@
1
+ import { Controller } from "<%= stimulus_module %>";
2
+
3
+ export default class extends Controller {
4
+ declare element: HTMLElement;
5
+
6
+ connect() {
7
+ console.log("Hello, Stimulus!", this.element);
8
+ }
9
+ }
@@ -2,7 +2,7 @@
2
2
 
3
3
  require "test_helper"
4
4
 
5
- class <%= class_name %>ComponentTest < ViewComponent::TestCase
5
+ class <%= namespaced? ? "#{namespace.name}::" : '' %><%= class_name %>ComponentTest < ViewComponent::TestCase
6
6
  def test_component_renders_something_useful
7
7
  # assert_equal(
8
8
  # %(<span>Hello, components!</span>),