view_component-contrib 0.1.3 → 0.1.5

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b7cf65bd25a29819f2a1337d7590e6c2274a9e0d0642b52a34606bde33140a76
4
- data.tar.gz: 54131be9ed2d51cd9dc688a7ca6010219f7b9b98c937ca84ef84c68890abfd52
3
+ metadata.gz: 3dfe8a56d9d79e6fbb11442811f68a9cdc7980c4dcbe00fdeba825a11d5124c7
4
+ data.tar.gz: 4ec650eab3f6c6b11ba79f598ecb79f34a3f900b44e1b6e53b55d08a9501f7aa
5
5
  SHA512:
6
- metadata.gz: ed6a4aed6af147f1e768ddfbffbda467c31ff54395e4dfdebb26fc12ab214c6a9740e4c3b7aec5dac7a5dcb5c2b0e637298e32f6803fa5f07045a73e6d781f73
7
- data.tar.gz: 25d7f12795c9e871439f7aa8f5990b97891de16b08c7ff2a7c571e5cc7bd03481ed943492c37be65252bcb264e6c20e8c245e141ddc0be71d388967db51a0f35
6
+ metadata.gz: 6a3f375f7e61f7b29ff6379caf4dec9d89a98226ca6c0c2bf55349e1ee3e28a6b6076840fe29a937b1700bc65546c6d946b575cc5337208a7ae49e555a75f3dc
7
+ data.tar.gz: e129b0af8c6f11b979bd202e9761f2acb5dc267e895ad010043eac3a028f9a5312a3c552bfc49cac4fa173abf48b07578fc017ea126162ee017739b8de1a3207
data/CHANGELOG.md CHANGED
@@ -2,6 +2,43 @@
2
2
 
3
3
  ## master
4
4
 
5
+ ## 0.1.5 (2023-11-02)
6
+
7
+ - Support content blocks in `#render_component` and `#render_with`. ([@palkan][])
8
+
9
+ ```ruby
10
+ class MyComponent::Preview
11
+ def default
12
+ # Now you can pass a block to render_component to render it inside the component:
13
+ render_component(kind: "info") do
14
+ "Welcome!"
15
+ end
16
+ end
17
+ end
18
+ ```
19
+
20
+ - Support implicit components in `#render_component` helper. ([@palkan][])
21
+
22
+ ```ruby
23
+ class MyComponent::Preview
24
+ def default
25
+ # Before
26
+ render_component(MyComponent::Component.new(foo: "bar"))
27
+ end
28
+
29
+ # After
30
+ def default
31
+ render_component(foo: "bar")
32
+ end
33
+ end
34
+ ```
35
+
36
+ ## 0.1.4 (2023-04-30)
37
+
38
+ - Fix compatibility with new errors classes in view_component.
39
+
40
+ See [view_component#1701](https://github.com/ViewComponent/view_component/pull/1701).
41
+
5
42
  ## 0.1.3 (2023-02-02)
6
43
 
7
44
  - Fix release dependencies ([@palkan][])
data/README.md CHANGED
@@ -47,6 +47,9 @@ bundle exec rails g view_component -h
47
47
  **Why adding a custom generator to the project instead of bundling it into the gem?** The generator could only be useful if it fits
48
48
  your project needs. The more control you have over the generator the better. Thus, the best way is to make the generator a part of a project.
49
49
 
50
+ > [!IMPORTANT]
51
+ > If your application has the `lib/` folder in the autoload paths, make sure you ignored the generated `lib/generators` folder. In Rails 7.1+, you can do this via adding `generators` the `config.autoload_lib` call's `ignore` option. Before, you can use `Rails.autoloaders.main.ignore(...)`.
52
+
50
53
  ## Organizing components, or sidecar pattern extended
51
54
 
52
55
  ViewComponent provides different ways to organize your components: putting everyhing (Ruby files, templates, etc.) into `app/components` folder or using a _sidecar_ directory for everything but the `.rb` file itself. The first approach could easily result in a directory bloat; the second is better though there is a room for improvement: we can move `.rb` files into sidecar folders as well. Then, we can get rid of the _noisy_ `_component` suffixes. Finally, we can also put previews there (since storing them within the test folder is a little bit confusing):
@@ -156,6 +159,14 @@ class Banner::Preview < ApplicationViewComponentPreview
156
159
  def default
157
160
  # This will use `absolute w-full` for the container class
158
161
  render_component Banner::Component.new(text: "Welcome!")
162
+
163
+ # or even shorter
164
+ render_component(text: "Welcome!")
165
+
166
+ # you can also pass a content block
167
+ render_component(kind: :notice) do
168
+ "Some content"
169
+ end
159
170
  end
160
171
 
161
172
  def mobile
@@ -434,6 +445,20 @@ class FlashAlert::Component < ApplicationViewComponent
434
445
  end
435
446
  ```
436
447
 
448
+ ## Supporting `.with_collection`
449
+
450
+ The `.with_collection` method from ViewComponent expects a component class to have the "Component" suffix to correctly infer the parameter name. Since we're using a different naming convention, we need to specify the collection parameter name explicitly. For example:
451
+
452
+ ```ruby
453
+ class PostCard::Component < ApplicationViewComponent
454
+ with_collection_parameter :post
455
+
456
+ option :post
457
+ end
458
+ ```
459
+
460
+ You can add this to following line to your component generator (unless it's already added): `with_collection_parameter :<%= singular_name %>` to always explicitly provide the collection parameter name.
461
+
437
462
  ## Wrapped components
438
463
 
439
464
  Sometimes we need to wrap a component into a custom HTML container (for positioning or whatever). By default, such wrapping doesn't play well with the `#render?` method because if we don't need a component, we don't need a wrapper.
@@ -1,6 +1,10 @@
1
1
  <div class="<%= container_class %>">
2
2
  <%- if component -%>
3
- <%= render component %>
3
+ <%- if local_assigns[:content_block] -%>
4
+ <%= render component, &content_block %>
5
+ <% else %>
6
+ <%= render component %>
7
+ <% end %>
4
8
  <%- else -%>
5
9
  Failed to infer a component from the preview: <%= error %>
6
10
  <%- end -%>
@@ -60,8 +60,14 @@ module ViewComponentContrib
60
60
  end
61
61
 
62
62
  # Shortcut for render_with_template(locals: {component: ...})
63
- def render_component(component)
64
- render_with(component: component)
63
+ def render_component(component_or_props = nil, &block)
64
+ component = if component_or_props.is_a?(::ViewComponent::Base)
65
+ component_or_props
66
+ else
67
+ self.class.name.sub(/Preview$/, "Component").constantize.new(**(component_or_props || {}))
68
+ end
69
+
70
+ render_with(component: component, content_block: block)
65
71
  end
66
72
  end
67
73
  end
@@ -5,6 +5,18 @@ module ViewComponentContrib
5
5
  module DefaultTemplate
6
6
  DEFAULT_TEMPLATE = "view_component_contrib/preview"
7
7
 
8
+ # Make sure view components errors are loaded
9
+ begin
10
+ require "view_component/errors"
11
+ rescue LoadError
12
+ end
13
+
14
+ MISSING_TEMPLATE_ERROR = if ViewComponent.const_defined?(:MissingPreviewTemplateError)
15
+ ViewComponent::MissingPreviewTemplateError
16
+ else
17
+ ViewComponent::PreviewTemplateError
18
+ end
19
+
8
20
  def self.included(base)
9
21
  base.singleton_class.prepend(ClassMethods)
10
22
  end
@@ -25,7 +37,7 @@ module ViewComponentContrib
25
37
 
26
38
  def preview_example_template_path(example)
27
39
  super
28
- rescue ViewComponent::PreviewTemplateError
40
+ rescue MISSING_TEMPLATE_ERROR
29
41
  has_example_preview = preview_paths.find do |path|
30
42
  Dir.glob(File.join(path, preview_name, "previews", "#{example}.html.*")).any?
31
43
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ViewComponentContrib # :nodoc:all
4
- VERSION = "0.1.3"
4
+ VERSION = "0.1.5"
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: view_component-contrib
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.3
4
+ version: 0.1.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Vladimir Dementyev
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-02-02 00:00:00.000000000 Z
11
+ date: 2023-11-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: view_component
@@ -146,17 +146,6 @@ files:
146
146
  - CHANGELOG.md
147
147
  - LICENSE.txt
148
148
  - README.md
149
- - app/templates/install/application_view_component.rb
150
- - app/templates/install/application_view_component_preview.rb
151
- - app/templates/install/builder.rb
152
- - app/templates/install/class_for.rb
153
- - app/templates/install/generator.rb
154
- - app/templates/install/identifier.rb
155
- - app/templates/install/index.js
156
- - app/templates/install/index.stimulus.js
157
- - app/templates/install/initializer.rb
158
- - app/templates/install/postcss-modules.js
159
- - app/templates/install/template.rb
160
149
  - app/views/view_component_contrib/preview.html.erb
161
150
  - lib/view_component-contrib.rb
162
151
  - lib/view_component_contrib.rb
@@ -180,7 +169,7 @@ metadata:
180
169
  documentation_uri: http://github.com/palkan/view_component-contrib
181
170
  homepage_uri: http://github.com/palkan/view_component-contrib
182
171
  source_code_uri: http://github.com/palkan/view_component-contrib
183
- post_install_message:
172
+ post_install_message:
184
173
  rdoc_options: []
185
174
  require_paths:
186
175
  - lib
@@ -195,8 +184,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
195
184
  - !ruby/object:Gem::Version
196
185
  version: '0'
197
186
  requirements: []
198
- rubygems_version: 3.3.26
199
- signing_key:
187
+ rubygems_version: 3.4.20
188
+ signing_key:
200
189
  specification_version: 4
201
190
  summary: A collection of extensions and developer tools for ViewComponent
202
191
  test_files: []
@@ -1,2 +0,0 @@
1
- class ApplicationViewComponent < ViewComponentContrib::Base
2
- end
@@ -1,3 +0,0 @@
1
- class ApplicationViewComponentPreview < ViewComponentContrib::Preview::Base
2
- self.abstract_class = true
3
- end
@@ -1,24 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- class TemplateBuilder
4
- attr_reader :root
5
-
6
- def initialize(root)
7
- @root = root
8
- end
9
-
10
- def get_binding
11
- binding
12
- end
13
-
14
- def embed_code(path)
15
- contents = File.read(File.join(root, path))
16
- %Q(<<-CODE
17
- #{contents}
18
- CODE)
19
- end
20
-
21
- def embed(path)
22
- File.read(File.join(root, path))
23
- end
24
- end
@@ -1,3 +0,0 @@
1
- def class_for(name, from: identifier)
2
- "c-\#{from}-\#{name}"
3
- end
@@ -1,275 +0,0 @@
1
- if yes?("Would you like to create a custom generator for your setup? (Recommended)")
2
- template_choice_to_ext = {"1" => ".erb", "2" => ".haml", "3" => ".slim"}
3
-
4
- template = ask "Which template processor do you use? (1) ERB, (2) Haml, (3) Slim, (0) Other"
5
-
6
- TEMPLATE_EXT = template_choice_to_ext.fetch(template, "")
7
- TEST_SUFFIX = USE_RSPEC ? 'spec' : 'test'
8
-
9
- file "lib/generators/view_component/view_component_generator.rb", <<~CODE
10
- # frozen_string_literal: true
11
-
12
- # Based on https://github.com/github/view_component/blob/master/lib/rails/generators/component/component_generator.rb
13
- class ViewComponentGenerator < Rails::Generators::NamedBase
14
- source_root File.expand_path("templates", __dir__)
15
-
16
- class_option :skip_test, type: :boolean, default: false
17
- class_option :skip_preview, type: :boolean, default: false
18
-
19
- argument :attributes, type: :array, default: [], banner: "attribute"
20
-
21
- def create_component_file
22
- template "component.rb", File.join("#{ROOT_PATH}", class_path, file_name, "component.rb")
23
- end
24
-
25
- def create_template_file
26
- template "component.html#{TEMPLATE_EXT}", File.join("#{ROOT_PATH}", class_path, file_name, "component.html#{TEMPLATE_EXT}")
27
- end
28
-
29
- def create_test_file
30
- return if options[:skip_test]
31
-
32
- template "component_#{TEST_SUFFIX}.rb", File.join("#{TEST_ROOT_PATH}", class_path, "\#{file_name}_#{TEST_SUFFIX}.rb")
33
- end
34
-
35
- def create_preview_file
36
- return if options[:skip_preview]
37
-
38
- template "preview.rb", File.join("#{ROOT_PATH}", class_path, file_name, "preview.rb")
39
- end
40
-
41
- private
42
-
43
- def parent_class
44
- "ApplicationViewComponent"
45
- end
46
-
47
- def preview_parent_class
48
- "ApplicationViewComponentPreview"
49
- end
50
- end
51
- CODE
52
-
53
- if USE_WEBPACK
54
- inject_into_file "lib/generators/view_component/view_component_generator.rb", after: "class_option :skip_preview, type: :boolean, default: false\n" do
55
- <<-CODE
56
- class_option :skip_js, type: :boolean, default: false
57
- class_option :skip_css, type: :boolean, default: false
58
- CODE
59
- end
60
-
61
- inject_into_file "lib/generators/view_component/view_component_generator.rb", before: "\n private" do
62
- <<-CODE
63
- def create_css_file
64
- return if options[:skip_css] || options[:skip_js]
65
-
66
- template "index.css", File.join("#{ROOT_PATH}", class_path, file_name, "index.css")
67
- end
68
-
69
- def create_js_file
70
- return if options[:skip_js]
71
-
72
- template "index.js", File.join("#{ROOT_PATH}", class_path, file_name, "index.js")
73
- end
74
- CODE
75
- end
76
- end
77
-
78
- if USE_DRY
79
- inject_into_file "lib/generators/view_component/view_component_generator.rb", before: "\nend" do
80
- <<-CODE
81
-
82
-
83
- def initialize_signature
84
- return if attributes.blank?
85
-
86
- attributes.map { |attr| "option :\#{attr.name}" }.join("\\n ")
87
- end
88
- CODE
89
- end
90
-
91
- file "lib/generators/view_component/templates/component.rb.tt",
92
- <<~CODE
93
- # frozen_string_literal: true
94
-
95
- class <%= class_name %>::Component < <%= parent_class %>
96
- <%- if initialize_signature -%>
97
- <%= initialize_signature %>
98
- <%- end -%>
99
- end
100
- CODE
101
- else
102
- inject_into_file "lib/generators/view_component/view_component_generator.rb", before: "\nend" do
103
- <<-CODE
104
-
105
-
106
- def initialize_signature
107
- return if attributes.blank?
108
-
109
- attributes.map { |attr| "\#{attr.name}:" }.join(", ")
110
- end
111
-
112
- def initialize_body
113
- attributes.map { |attr| "@\#{attr.name} = \#{attr.name}" }.join("\\n ")
114
- end
115
- CODE
116
- end
117
-
118
- file "lib/generators/view_component/templates/component.rb.tt",
119
- <<~CODE
120
- # frozen_string_literal: true
121
-
122
- class <%= class_name %>::Component < <%= parent_class %>
123
- <%- if initialize_signature -%>
124
- def initialize(<%= initialize_signature %>)
125
- <%= initialize_body %>
126
- end
127
- <%- end -%>
128
- end
129
- CODE
130
- end
131
-
132
- if TEMPLATE_EXT == ".slim"
133
- file "lib/generators/view_component/templates/component.html.slim.tt", <<~CODE
134
- div Add <%= class_name %> template here
135
- CODE
136
- end
137
-
138
- if TEMPLATE_EXT == ".erb"
139
- file "lib/generators/view_component/templates/component.html.erb.tt", <<~CODE
140
- <div>Add <%= class_name %> template here</div>
141
- CODE
142
- end
143
-
144
- if TEMPLATE_EXT == ".haml"
145
- file "lib/generators/view_component/templates/component.html.tt", <<~CODE
146
- %div Add <%= class_name %> template here
147
- CODE
148
- end
149
-
150
- if TEMPLATE_EXT == ""
151
- file "lib/generators/view_component/templates/component.html.tt", <<~CODE
152
- <div>Add <%= class_name %> template here</div>
153
- CODE
154
- end
155
-
156
- file "lib/generators/view_component/templates/preview.rb.tt", <<~CODE
157
- # frozen_string_literal: true
158
-
159
- class <%= class_name %>::Preview < <%= preview_parent_class %>
160
- # You can specify the container class for the default template
161
- # self.container_class = "w-1/2 border border-gray-300"
162
-
163
- def default
164
- end
165
- end
166
- CODE
167
-
168
- if USE_WEBPACK
169
- if USE_STIMULUS
170
- file "lib/generators/view_component/templates/index.js.tt",
171
- <<-CODE
172
- import "./index.css"
173
-
174
- // Add a Stimulus controller for this component.
175
- // It will automatically registered and its name will be available
176
- // via #component_name in the component class.
177
- //
178
- // import { Controller as BaseController } from "stimulus";
179
- //
180
- // export class Controller extends BaseController {
181
- // connect() {
182
- // }
183
- //
184
- // disconnect() {
185
- // }
186
- // }
187
- CODE
188
- else
189
- file "lib/generators/view_component/templates/index.js.tt", <<~CODE
190
- import "./index.css"
191
-
192
- CODE
193
- end
194
-
195
- if USE_POSTCSS_MODULES
196
- file "lib/generators/view_component/templates/index.css.tt", <<~CODE
197
- /* Use component-local class names and add them to HTML via #class_for(name) helper */
198
-
199
- CODE
200
- else
201
- file "lib/generators/view_component/templates/index.css.tt", ""
202
- end
203
- end
204
-
205
- if USE_RSPEC
206
- file "lib/generators/view_component/templates/component_spec.rb.tt", <<~CODE
207
- # frozen_string_literal: true
208
-
209
- require "rails_helper"
210
-
211
- describe <%= class_name %>::Component do
212
- let(:options) { {} }
213
- let(:component) { <%= class_name %>::Component.new(**options) }
214
-
215
- subject { rendered_component }
216
-
217
- it "renders" do
218
- render_inline(component)
219
-
220
- is_expected.to have_css "div"
221
- end
222
- end
223
- CODE
224
- else
225
- file "lib/generators/view_component/templates/component_test.rb.tt", <<~CODE
226
- # frozen_string_literal: true
227
-
228
- require "test_helper"
229
-
230
- class <%= class_name %>::ComponentTest < ActiveSupport::TestCase
231
- include ViewComponent::TestHelpers
232
-
233
- def test_renders
234
- component = build_component
235
-
236
- render_inline(component)
237
-
238
- assert_selector "div"
239
- end
240
-
241
- private
242
-
243
- def build_component(**options)
244
- <%= class_name %>::Component.new(**options)
245
- end
246
- end
247
- CODE
248
- end
249
-
250
- file "lib/generators/view_component/USAGE", <<~CODE
251
- Description:
252
- ============
253
- Creates a new view component, test and preview files.
254
- Pass the component name, either CamelCased or under_scored, and an optional list of attributes as arguments.
255
-
256
- Example:
257
- ========
258
- bin/rails generate view_component Profile name age
259
-
260
- creates a Profile component and test:
261
- Component: #{ROOT_PATH}/profile/component.rb
262
- Template: #{ROOT_PATH}/profile/component.html#{TEMPLATE_EXT}
263
- Test: #{TEST_ROOT_PATH}/profile_component_#{TEST_SUFFIX}.rb
264
- Preview: #{ROOT_PATH}/profile/component_preview.rb
265
- CODE
266
-
267
- if USE_WEBPACK
268
- inject_into_file "lib/generators/view_component/USAGE" do
269
- <<-CODE
270
- JS: #{ROOT_PATH}/profile/component.js
271
- CSS: #{ROOT_PATH}/profile/component.css
272
- CODE
273
- end
274
- end
275
- end
@@ -1,7 +0,0 @@
1
-
2
-
3
- private
4
-
5
- def identifier
6
- @identifier ||= self.class.name.sub("::Component", "").underscore.split("/").join("--")
7
- end
@@ -1,2 +0,0 @@
1
- const context = require.context(".", true, /index.js$/)
2
- context.keys().forEach(context);
@@ -1,20 +0,0 @@
1
- // IMPORTANT: Update this import to reflect the location of your Stimulus application
2
- // See https://github.com/palkan/view_component-contrib#using-with-stimulusjs
3
- import { application } from "../init/stimulus";
4
-
5
- const context = require.context(".", true, /index.js$/)
6
- context.keys().forEach((path) => {
7
- const mod = context(path);
8
-
9
- // Check whether a module has the Controller export defined
10
- if (!mod.Controller) return;
11
-
12
- // Convert path into a controller identifier:
13
- // example/index.js -> example
14
- // nav/user_info/index.js -> nav--user-info
15
- const identifier = path.replace(/^\\.\\//, '')
16
- .replace(/\\/index\\.js$/, '')
17
- .replace(/\\//g, '--');
18
-
19
- application.register(identifier, mod.Controller);
20
- });
@@ -1,16 +0,0 @@
1
- ActiveSupport.on_load(:view_component) do
2
- # Extend your preview controller to support authentication and other
3
- # application-specific stuff
4
- #
5
- # Rails.application.config.to_prepare do
6
- # ViewComponentsController.class_eval do
7
- # include Authenticated
8
- # end
9
- # end
10
- #
11
- # Make it possible to store previews in sidecar folders
12
- # See https://github.com/palkan/view_component-contrib#organizing-components-or-sidecar-pattern-extended
13
- ViewComponent::Preview.extend ViewComponentContrib::Preview::Sidecarable
14
- # Enable `self.abstract_class = true` to exclude previews from the list
15
- ViewComponent::Preview.extend ViewComponentContrib::Preview::Abstract
16
- end
@@ -1,13 +0,0 @@
1
- generateScopedName: (name, filename, _css) => {
2
- const matches = filename.match(/#{ROOT_PATH.gsub('/', '\/')}\\/?(.*)\\/index.css$/);
3
- // Do not transform CSS files from outside of the components folder
4
- if (!matches) return name;
5
-
6
- // identifier here is the same identifier we used for Stimulus controller (see above)
7
- const identifier = matches[1].replace(/\\//g, "--");
8
-
9
- // We also add the `c-` prefix to all components classes
10
- return `c-${identifier}-${name}`;
11
- },
12
- // Do not generate *.css.json files (we don't use them)
13
- getJSON: () => {}
@@ -1,137 +0,0 @@
1
- say "👋 Welcome to interactive ViewComponent installer and configurator. " \
2
- "Make sure you've read the view_component-contrib guide: https://github.com/palkan/view_component-contrib"
3
-
4
- run "bundle add view_component view_component-contrib --skip-install"
5
-
6
- inject_into_file "config/application.rb", "\nrequire \"view_component/engine\"\n", before: "\nBundler.require(*Rails.groups)"
7
-
8
- say_status :info, "✅ ViewComponent gems added"
9
-
10
- DEFAULT_ROOT = "app/frontend/components"
11
-
12
- root = ask("Where do you want to store your view components? (default: #{DEFAULT_ROOT})")
13
- ROOT_PATH = root.present? && root.downcase != "n" ? root : DEFAULT_ROOT
14
-
15
- root_paths = ROOT_PATH.split("/").map { |path| "\"#{path}\"" }.join(", ")
16
-
17
- application "config.view_component.preview_paths << Rails.root.join(#{root_paths})"
18
- application "config.autoload_paths << Rails.root.join(#{root_paths})"
19
-
20
- say_status :info, "✅ ViewComponent paths configured"
21
-
22
- file "#{ROOT_PATH}/application_view_component.rb",
23
- <%= embed_code("./application_view_component.rb") %>
24
-
25
- file "#{ROOT_PATH}/application_view_component_preview.rb",
26
- <%= embed_code("./application_view_component_preview.rb") %>
27
-
28
- say_status :info, "✅ ApplicationViewComponent and ApplicationViewComponentPreview classes added"
29
-
30
- USE_RSPEC = File.directory?("spec")
31
- TEST_ROOT_PATH = USE_RSPEC ? File.join("spec", ROOT_PATH.sub("app/", "")) : File.join("test", ROOT_PATH.sub("app/", ""))
32
-
33
- USE_DRY = yes? "Would you like to use dry-initializer in your component classes?"
34
-
35
- if USE_DRY
36
- run "bundle add dry-initializer --skip-install"
37
-
38
- inject_into_file "#{ROOT_PATH}/application_view_component.rb", "\n extend Dry::Initializer", after: "class ApplicationViewComponent < ViewComponentContrib::Base"
39
-
40
- say_status :info, "✅ Extended ApplicationViewComponent with Dry::Initializer"
41
- end
42
-
43
- initializer "view_component.rb",
44
- <%= embed_code("./initializer.rb") %>
45
-
46
- say_status :info, "✅ Added ViewComponent initializer with required patches"
47
-
48
- if USE_RSPEC
49
- inject_into_file "spec/rails_helper.rb", after: "require \"rspec/rails\"\n" do
50
- "require \"capybara/rspec\"\nrequire \"view_component/test_helpers\"\n"
51
- end
52
-
53
- inject_into_file "spec/rails_helper.rb", after: "RSpec.configure do |config|\n" do
54
- <<-CODE
55
- config.include ViewComponent::TestHelpers, type: :view_component
56
- config.include Capybara::RSpecMatchers, type: :view_component
57
-
58
- config.define_derived_metadata(file_path: %r{/#{TEST_ROOT_PATH}}) do |metadata|
59
- metadata[:type] = :view_component
60
- end
61
-
62
- CODE
63
- end
64
- end
65
-
66
- say_status :info, "✅ RSpec configured"
67
-
68
- USE_WEBPACK = File.directory?("config/webpack") || File.file?("webpack.config.js")
69
-
70
- if USE_WEBPACK
71
- USE_STIMULUS = yes? "Do you use StimulusJS?"
72
-
73
- if USE_STIMULUS
74
- file "#{ROOT_PATH}/index.js",
75
- <%= embed_code("./index.stimulus.js") %>
76
-
77
- inject_into_file "#{ROOT_PATH}/application_view_component.rb", before: "\nend" do
78
- <%= embed_code("./identifier.rb") %>
79
- end
80
- else
81
- file "#{ROOT_PATH}/index.js",
82
- <%= embed_code("./index.js") %>
83
- end
84
-
85
- say_status :info, "✅ Added index.js to load components JS/CSS"
86
- say "⚠️ Don't forget to import component JS/CSS (#{ROOT_PATH}/index.js) from your application.js entrypoint"
87
-
88
- say "⚠️ Don't forget to add #{ROOT_PATH} to `additional_paths` in your `webpacker.yml` (unless your `source_path` already includes it)"
89
-
90
- USE_POSTCSS_MODULES = yes? "Would you like to use postcss-modules to isolate component styles?"
91
-
92
- if USE_POSTCSS_MODULES
93
- run "yarn add postcss-modules"
94
-
95
- if File.read("postcss.config.js").match(/plugins:\s*\[/)
96
- inject_into_file "postcss.config.js", after: "plugins: [" do
97
- <<-CODE
98
-
99
- require('postcss-modules')({
100
- <%= embed("./postcss-modules.js") %>
101
- }),
102
- CODE
103
- end
104
- else
105
- inject_into_file "postcss.config.js", after: "plugins: {" do
106
- <<-CODE
107
-
108
- 'postcss-modules': {
109
- <%= embed("./postcss-modules.js") %>
110
- },
111
- CODE
112
- end
113
- end
114
-
115
- if !USE_STIMULUS
116
- inject_into_file "#{ROOT_PATH}/application_view_component.rb", before: "\nend" do
117
- <%= embed_code("./identifier.rb") %>
118
- end
119
- end
120
-
121
- inject_into_file "#{ROOT_PATH}/application_view_component.rb", before: "\nend" do
122
- <%= embed_code("./class_for.rb") %>
123
- end
124
-
125
- say_status :info, "✅ postcss-modules configured"
126
- end
127
- else
128
- say "⚠️ See the discussion on how to configure non-Wepback JS/CSS installations: https://github.com/palkan/view_component-contrib/discussions/14"
129
- end
130
-
131
- <%= embed("./generator.rb") %>
132
-
133
- say "Installing gems..."
134
-
135
- Bundler.with_unbundled_env { run "bundle install" }
136
-
137
- say_status :info, "✅ You're ready to rock!"