view_component-contrib 0.1.3 → 0.1.5
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +37 -0
- data/README.md +25 -0
- data/app/views/view_component_contrib/preview.html.erb +5 -1
- data/lib/view_component_contrib/preview/base.rb +8 -2
- data/lib/view_component_contrib/preview/default_template.rb +13 -1
- data/lib/view_component_contrib/version.rb +1 -1
- metadata +6 -17
- data/app/templates/install/application_view_component.rb +0 -2
- data/app/templates/install/application_view_component_preview.rb +0 -3
- data/app/templates/install/builder.rb +0 -24
- data/app/templates/install/class_for.rb +0 -3
- data/app/templates/install/generator.rb +0 -275
- data/app/templates/install/identifier.rb +0 -7
- data/app/templates/install/index.js +0 -2
- data/app/templates/install/index.stimulus.js +0 -20
- data/app/templates/install/initializer.rb +0 -16
- data/app/templates/install/postcss-modules.js +0 -13
- data/app/templates/install/template.rb +0 -137
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3dfe8a56d9d79e6fbb11442811f68a9cdc7980c4dcbe00fdeba825a11d5124c7
|
4
|
+
data.tar.gz: 4ec650eab3f6c6b11ba79f598ecb79f34a3f900b44e1b6e53b55d08a9501f7aa
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
-
|
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(
|
64
|
-
|
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
|
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
|
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.
|
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-
|
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.
|
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,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,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,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!"
|