view_component 3.25.0 → 4.0.0.alpha1
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/app/controllers/concerns/view_component/preview_actions.rb +2 -9
- data/app/controllers/view_components_system_test_controller.rb +17 -29
- data/app/views/test_mailer/test_asset_email.html.erb +1 -0
- data/app/views/view_components/preview.html.erb +1 -9
- data/docs/CHANGELOG.md +77 -17
- data/lib/view_component/base.rb +49 -100
- data/lib/view_component/collection.rb +12 -19
- data/lib/view_component/compiler.rb +50 -74
- data/lib/view_component/config.rb +0 -21
- data/lib/view_component/deprecation.rb +1 -1
- data/lib/view_component/engine.rb +3 -82
- data/lib/view_component/errors.rb +16 -22
- data/lib/view_component/inline_template.rb +2 -4
- data/lib/view_component/instrumentation.rb +5 -11
- data/lib/view_component/preview.rb +3 -12
- data/lib/view_component/request_details.rb +30 -0
- data/lib/view_component/slot.rb +3 -6
- data/lib/view_component/slotable.rb +30 -37
- data/lib/view_component/system_test_helpers.rb +1 -2
- data/lib/view_component/template.rb +106 -83
- data/lib/view_component/test_helpers.rb +22 -42
- data/lib/view_component/translatable.rb +24 -23
- data/lib/view_component/use_helpers.rb +3 -4
- data/lib/view_component/version.rb +3 -3
- data/lib/view_component.rb +0 -1
- metadata +88 -124
- data/app/assets/vendor/prism.css +0 -4
- data/app/assets/vendor/prism.min.js +0 -12
- data/app/helpers/preview_helper.rb +0 -85
- data/app/views/view_components/_preview_source.html.erb +0 -17
- data/lib/rails/generators/abstract_generator.rb +0 -56
- data/lib/rails/generators/component/component_generator.rb +0 -67
- data/lib/rails/generators/component/templates/component.rb.tt +0 -16
- data/lib/rails/generators/erb/component_generator.rb +0 -33
- data/lib/rails/generators/erb/templates/component.html.erb.tt +0 -1
- data/lib/rails/generators/haml/component_generator.rb +0 -22
- data/lib/rails/generators/haml/templates/component.html.haml.tt +0 -1
- data/lib/rails/generators/locale/component_generator.rb +0 -46
- data/lib/rails/generators/preview/component_generator.rb +0 -39
- data/lib/rails/generators/preview/templates/component_preview.rb.tt +0 -9
- data/lib/rails/generators/rspec/component_generator.rb +0 -31
- data/lib/rails/generators/rspec/templates/component_spec.rb.tt +0 -15
- data/lib/rails/generators/slim/component_generator.rb +0 -22
- data/lib/rails/generators/slim/templates/component.html.slim.tt +0 -1
- data/lib/rails/generators/stimulus/component_generator.rb +0 -44
- data/lib/rails/generators/stimulus/templates/component_controller.js.tt +0 -7
- data/lib/rails/generators/stimulus/templates/component_controller.ts.tt +0 -9
- data/lib/rails/generators/tailwindcss/component_generator.rb +0 -11
- data/lib/rails/generators/tailwindcss/templates/component.html.erb.tt +0 -1
- data/lib/rails/generators/test_unit/component_generator.rb +0 -20
- data/lib/rails/generators/test_unit/templates/component_test.rb.tt +0 -12
- data/lib/view_component/component_error.rb +0 -6
- data/lib/view_component/rails/tasks/view_component.rake +0 -20
- data/lib/view_component/render_component_helper.rb +0 -10
- data/lib/view_component/render_component_to_string_helper.rb +0 -9
- data/lib/view_component/render_monkey_patch.rb +0 -13
- data/lib/view_component/render_to_string_monkey_patch.rb +0 -13
- data/lib/view_component/rendering_component_helper.rb +0 -9
- data/lib/view_component/rendering_monkey_patch.rb +0 -13
|
@@ -1,85 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module PreviewHelper
|
|
4
|
-
# :nocov:
|
|
5
|
-
include ActionView::Helpers::AssetUrlHelper if Rails.version.to_f < 6.1
|
|
6
|
-
# :nocov:
|
|
7
|
-
|
|
8
|
-
AVAILABLE_PRISM_LANGUAGES = %w[ruby erb haml]
|
|
9
|
-
FALLBACK_LANGUAGE = "ruby"
|
|
10
|
-
|
|
11
|
-
def preview_source
|
|
12
|
-
return if @render_args.nil?
|
|
13
|
-
|
|
14
|
-
render "preview_source"
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
def prism_css_source_url
|
|
18
|
-
serve_static_preview_assets? ? asset_path("prism.css", skip_pipeline: true) : "https://cdn.jsdelivr.net/npm/prismjs@1.28.0/themes/prism.min.css"
|
|
19
|
-
end
|
|
20
|
-
|
|
21
|
-
def prism_js_source_url
|
|
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
|
-
end
|
|
24
|
-
|
|
25
|
-
def find_template_data_for_preview_source(lookup_context:, template_identifier:)
|
|
26
|
-
template = lookup_context.find_template(template_identifier)
|
|
27
|
-
|
|
28
|
-
if Rails.version.to_f >= 6.1 || template.source.present?
|
|
29
|
-
{
|
|
30
|
-
source: template.source,
|
|
31
|
-
prism_language_name: prism_language_name_by_template(template: template)
|
|
32
|
-
}
|
|
33
|
-
# :nocov:
|
|
34
|
-
else
|
|
35
|
-
# Fetch template source via finding it through preview paths
|
|
36
|
-
# to accomodate source view when exclusively using templates
|
|
37
|
-
# for previews for Rails < 6.1.
|
|
38
|
-
all_template_paths = ViewComponent::Base.config.preview_paths.map do |preview_path|
|
|
39
|
-
Dir.glob("#{preview_path}/**/*")
|
|
40
|
-
end.flatten
|
|
41
|
-
|
|
42
|
-
# Search for templates the contain `html`.
|
|
43
|
-
matching_templates = all_template_paths.find_all do |path|
|
|
44
|
-
path =~ /#{template_identifier}*.(html)/
|
|
45
|
-
end
|
|
46
|
-
|
|
47
|
-
raise ViewComponent::NoMatchingTemplatesForPreviewError.new(template_identifier) if matching_templates.empty?
|
|
48
|
-
raise ViewComponent::MultipleMatchingTemplatesForPreviewError.new(template_identifier) if matching_templates.size > 1
|
|
49
|
-
|
|
50
|
-
template_file_path = matching_templates.first
|
|
51
|
-
template_source = File.read(template_file_path)
|
|
52
|
-
prism_language_name = prism_language_name_by_template_path(template_file_path: template_file_path)
|
|
53
|
-
|
|
54
|
-
{
|
|
55
|
-
source: template_source,
|
|
56
|
-
prism_language_name: prism_language_name
|
|
57
|
-
}
|
|
58
|
-
end
|
|
59
|
-
# :nocov:
|
|
60
|
-
end
|
|
61
|
-
|
|
62
|
-
private
|
|
63
|
-
|
|
64
|
-
def prism_language_name_by_template(template:)
|
|
65
|
-
language = template.identifier.split(".").last
|
|
66
|
-
|
|
67
|
-
return FALLBACK_LANGUAGE unless AVAILABLE_PRISM_LANGUAGES.include? language
|
|
68
|
-
|
|
69
|
-
language
|
|
70
|
-
end
|
|
71
|
-
|
|
72
|
-
# :nocov:
|
|
73
|
-
def prism_language_name_by_template_path(template_file_path:)
|
|
74
|
-
language = template_file_path.gsub(".html", "").split(".").last
|
|
75
|
-
|
|
76
|
-
return FALLBACK_LANGUAGE unless AVAILABLE_PRISM_LANGUAGES.include? language
|
|
77
|
-
|
|
78
|
-
language
|
|
79
|
-
end
|
|
80
|
-
# :nocov:
|
|
81
|
-
|
|
82
|
-
def serve_static_preview_assets?
|
|
83
|
-
ViewComponent::Base.config.show_previews && Rails.application.config.public_file_server.enabled
|
|
84
|
-
end
|
|
85
|
-
end
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
<link href="<%= prism_css_source_url %>" media="screen" rel="stylesheet" type="text/css">
|
|
2
|
-
<div class="view-component-source-example">
|
|
3
|
-
<h2>Source:</h2>
|
|
4
|
-
<pre class="source">
|
|
5
|
-
<% if @render_args[:component] %>
|
|
6
|
-
<code class="language-ruby">
|
|
7
|
-
<%= h @preview.preview_source(@example_name) %>
|
|
8
|
-
</code>
|
|
9
|
-
<% else %>
|
|
10
|
-
<% template_data = find_template_data_for_preview_source(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
|
-
</code>
|
|
14
|
-
<% end %>
|
|
15
|
-
</pre>
|
|
16
|
-
</div>
|
|
17
|
-
<script type="text/javascript" src="<%= prism_js_source_url %>"></script>
|
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module ViewComponent
|
|
4
|
-
module AbstractGenerator
|
|
5
|
-
def copy_view_file
|
|
6
|
-
template "component.html.#{engine_name}", destination unless options["inline"]
|
|
7
|
-
end
|
|
8
|
-
|
|
9
|
-
private
|
|
10
|
-
|
|
11
|
-
def destination
|
|
12
|
-
File.join(destination_directory, "#{destination_file_name}.html.#{engine_name}")
|
|
13
|
-
end
|
|
14
|
-
|
|
15
|
-
def destination_directory
|
|
16
|
-
if sidecar?
|
|
17
|
-
File.join(component_path, class_path, destination_file_name)
|
|
18
|
-
else
|
|
19
|
-
File.join(component_path, class_path)
|
|
20
|
-
end
|
|
21
|
-
end
|
|
22
|
-
|
|
23
|
-
def destination_file_name
|
|
24
|
-
"#{file_name}_component"
|
|
25
|
-
end
|
|
26
|
-
|
|
27
|
-
def file_name
|
|
28
|
-
@_file_name ||= super.sub(/_component\z/i, "")
|
|
29
|
-
end
|
|
30
|
-
|
|
31
|
-
def component_path
|
|
32
|
-
ViewComponent::Base.config.view_component_path
|
|
33
|
-
end
|
|
34
|
-
|
|
35
|
-
def stimulus_controller
|
|
36
|
-
if stimulus?
|
|
37
|
-
File.join(destination_directory, destination_file_name)
|
|
38
|
-
.sub("#{component_path}/", "")
|
|
39
|
-
.tr("_", "-")
|
|
40
|
-
.gsub("/", "--")
|
|
41
|
-
end
|
|
42
|
-
end
|
|
43
|
-
|
|
44
|
-
def sidecar?
|
|
45
|
-
options["sidecar"] || ViewComponent::Base.config.generate.sidecar
|
|
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
|
|
55
|
-
end
|
|
56
|
-
end
|
|
@@ -1,67 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require "rails/generators/abstract_generator"
|
|
4
|
-
|
|
5
|
-
module Rails
|
|
6
|
-
module Generators
|
|
7
|
-
class ComponentGenerator < Rails::Generators::NamedBase
|
|
8
|
-
include ViewComponent::AbstractGenerator
|
|
9
|
-
|
|
10
|
-
source_root File.expand_path("templates", __dir__)
|
|
11
|
-
|
|
12
|
-
argument :attributes, type: :array, default: [], banner: "attribute"
|
|
13
|
-
check_class_collision suffix: "Component"
|
|
14
|
-
|
|
15
|
-
class_option :inline, type: :boolean, default: false
|
|
16
|
-
class_option :locale, type: :boolean, default: ViewComponent::Base.config.generate.locale
|
|
17
|
-
class_option :parent, type: :string, desc: "The parent class for the generated component"
|
|
18
|
-
class_option :preview, type: :boolean, default: ViewComponent::Base.config.generate.preview
|
|
19
|
-
class_option :sidecar, type: :boolean, default: false
|
|
20
|
-
class_option :stimulus, type: :boolean,
|
|
21
|
-
default: ViewComponent::Base.config.generate.stimulus_controller
|
|
22
|
-
class_option :skip_suffix, type: :boolean, default: false
|
|
23
|
-
|
|
24
|
-
def create_component_file
|
|
25
|
-
template "component.rb", File.join(component_path, class_path, "#{file_name}#{"_component" unless options[:skip_suffix]}.rb")
|
|
26
|
-
end
|
|
27
|
-
|
|
28
|
-
hook_for :test_framework
|
|
29
|
-
|
|
30
|
-
hook_for :preview, type: :boolean
|
|
31
|
-
|
|
32
|
-
hook_for :stimulus, type: :boolean
|
|
33
|
-
|
|
34
|
-
hook_for :locale, type: :boolean
|
|
35
|
-
|
|
36
|
-
hook_for :template_engine do |instance, template_engine|
|
|
37
|
-
instance.invoke template_engine, [instance.name]
|
|
38
|
-
end
|
|
39
|
-
|
|
40
|
-
private
|
|
41
|
-
|
|
42
|
-
def parent_class
|
|
43
|
-
return options[:parent] if options[:parent]
|
|
44
|
-
|
|
45
|
-
ViewComponent::Base.config.component_parent_class || default_parent_class
|
|
46
|
-
end
|
|
47
|
-
|
|
48
|
-
def initialize_signature
|
|
49
|
-
return if attributes.blank?
|
|
50
|
-
|
|
51
|
-
attributes.map { |attr| "#{attr.name}:" }.join(", ")
|
|
52
|
-
end
|
|
53
|
-
|
|
54
|
-
def initialize_body
|
|
55
|
-
attributes.map { |attr| "@#{attr.name} = #{attr.name}" }.join("\n ")
|
|
56
|
-
end
|
|
57
|
-
|
|
58
|
-
def initialize_call_method_for_inline?
|
|
59
|
-
options["inline"]
|
|
60
|
-
end
|
|
61
|
-
|
|
62
|
-
def default_parent_class
|
|
63
|
-
defined?(ApplicationComponent) ? ApplicationComponent : ViewComponent::Base
|
|
64
|
-
end
|
|
65
|
-
end
|
|
66
|
-
end
|
|
67
|
-
end
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
<% module_namespacing do -%>
|
|
4
|
-
class <%= class_name %><%= options[:skip_suffix] ? "" : "Component" %> < <%= parent_class %>
|
|
5
|
-
<%- if initialize_signature -%>
|
|
6
|
-
def initialize(<%= initialize_signature %>)
|
|
7
|
-
<%= initialize_body %>
|
|
8
|
-
end
|
|
9
|
-
<%- end -%>
|
|
10
|
-
<%- if initialize_call_method_for_inline? -%>
|
|
11
|
-
def call
|
|
12
|
-
content_tag :h1, "Hello world!"<%= ", data: { controller: \"#{stimulus_controller}\" }" if options["stimulus"] %>
|
|
13
|
-
end
|
|
14
|
-
<%- end -%>
|
|
15
|
-
end
|
|
16
|
-
<% end -%>
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require "rails/generators/erb"
|
|
4
|
-
require "rails/generators/abstract_generator"
|
|
5
|
-
|
|
6
|
-
module Erb
|
|
7
|
-
module Generators
|
|
8
|
-
class ComponentGenerator < Base
|
|
9
|
-
include ViewComponent::AbstractGenerator
|
|
10
|
-
|
|
11
|
-
source_root File.expand_path("templates", __dir__)
|
|
12
|
-
class_option :sidecar, type: :boolean, default: false
|
|
13
|
-
class_option :inline, type: :boolean, default: false
|
|
14
|
-
class_option :stimulus, type: :boolean, default: false
|
|
15
|
-
|
|
16
|
-
def engine_name
|
|
17
|
-
"erb"
|
|
18
|
-
end
|
|
19
|
-
|
|
20
|
-
def copy_view_file
|
|
21
|
-
super
|
|
22
|
-
end
|
|
23
|
-
|
|
24
|
-
private
|
|
25
|
-
|
|
26
|
-
def data_attributes
|
|
27
|
-
if stimulus?
|
|
28
|
-
" data-controller=\"#{stimulus_controller}\""
|
|
29
|
-
end
|
|
30
|
-
end
|
|
31
|
-
end
|
|
32
|
-
end
|
|
33
|
-
end
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
<div<%= data_attributes %>>Add <%= class_name %> template here</div>
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require "rails/generators/erb/component_generator"
|
|
4
|
-
|
|
5
|
-
module Haml
|
|
6
|
-
module Generators
|
|
7
|
-
class ComponentGenerator < Erb::Generators::ComponentGenerator
|
|
8
|
-
include ViewComponent::AbstractGenerator
|
|
9
|
-
|
|
10
|
-
source_root File.expand_path("templates", __dir__)
|
|
11
|
-
class_option :sidecar, type: :boolean, default: false
|
|
12
|
-
|
|
13
|
-
def engine_name
|
|
14
|
-
"haml"
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
def copy_view_file
|
|
18
|
-
super
|
|
19
|
-
end
|
|
20
|
-
end
|
|
21
|
-
end
|
|
22
|
-
end
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
%div Add <%= class_name %> template here
|
|
@@ -1,46 +0,0 @@
|
|
|
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.config.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
|
-
extension = ".#{locale}" if locale
|
|
38
|
-
if sidecar?
|
|
39
|
-
File.join(component_path, class_path, "#{file_name}_component", "#{file_name}_component#{extension}.yml")
|
|
40
|
-
else
|
|
41
|
-
File.join(component_path, class_path, "#{file_name}_component#{extension}.yml")
|
|
42
|
-
end
|
|
43
|
-
end
|
|
44
|
-
end
|
|
45
|
-
end
|
|
46
|
-
end
|
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Preview
|
|
4
|
-
module Generators
|
|
5
|
-
class ComponentGenerator < ::Rails::Generators::NamedBase
|
|
6
|
-
source_root File.expand_path("templates", __dir__)
|
|
7
|
-
class_option :preview_path, type: :string, desc: "Path for previews, required when multiple preview paths are configured", default: ViewComponent::Base.config.generate.preview_path
|
|
8
|
-
|
|
9
|
-
argument :attributes, type: :array, default: [], banner: "attribute"
|
|
10
|
-
check_class_collision suffix: "ComponentPreview"
|
|
11
|
-
|
|
12
|
-
def create_preview_file
|
|
13
|
-
preview_paths = ViewComponent::Base.config.preview_paths
|
|
14
|
-
optional_path = options[:preview_path]
|
|
15
|
-
return if preview_paths.count > 1 && optional_path.blank?
|
|
16
|
-
|
|
17
|
-
path_prefix = if optional_path.present?
|
|
18
|
-
optional_path
|
|
19
|
-
else
|
|
20
|
-
preview_paths.one? ? preview_paths.first : "test/components/previews"
|
|
21
|
-
end
|
|
22
|
-
|
|
23
|
-
template "component_preview.rb", File.join(path_prefix, class_path, "#{file_name}_component_preview.rb")
|
|
24
|
-
end
|
|
25
|
-
|
|
26
|
-
private
|
|
27
|
-
|
|
28
|
-
def file_name
|
|
29
|
-
@_file_name ||= super.sub(/_component\z/i, "")
|
|
30
|
-
end
|
|
31
|
-
|
|
32
|
-
def render_signature
|
|
33
|
-
return if attributes.blank?
|
|
34
|
-
|
|
35
|
-
attributes.map { |attr| %(#{attr.name}: "#{attr.name}") }.join(", ")
|
|
36
|
-
end
|
|
37
|
-
end
|
|
38
|
-
end
|
|
39
|
-
end
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require "rails/generators/abstract_generator"
|
|
4
|
-
|
|
5
|
-
module Rspec
|
|
6
|
-
module Generators
|
|
7
|
-
class ComponentGenerator < ::Rails::Generators::NamedBase
|
|
8
|
-
include ViewComponent::AbstractGenerator
|
|
9
|
-
|
|
10
|
-
source_root File.expand_path("templates", __dir__)
|
|
11
|
-
|
|
12
|
-
def create_test_file
|
|
13
|
-
template "component_spec.rb", File.join(spec_component_path, class_path, "#{file_name}_component_spec.rb")
|
|
14
|
-
end
|
|
15
|
-
|
|
16
|
-
private
|
|
17
|
-
|
|
18
|
-
def spec_component_path
|
|
19
|
-
return "spec/components" unless ViewComponent::Base.config.generate.use_component_path_for_rspec_tests
|
|
20
|
-
|
|
21
|
-
configured_component_path = component_path
|
|
22
|
-
if configured_component_path.start_with?("app#{File::SEPARATOR}")
|
|
23
|
-
_app, *rest_of_path = Pathname.new(configured_component_path).each_filename.to_a
|
|
24
|
-
File.join("spec", *rest_of_path)
|
|
25
|
-
else
|
|
26
|
-
"spec/components"
|
|
27
|
-
end
|
|
28
|
-
end
|
|
29
|
-
end
|
|
30
|
-
end
|
|
31
|
-
end
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require "rails_helper"
|
|
4
|
-
|
|
5
|
-
RSpec.describe <%= namespaced? ? "#{namespace.name}::" : '' %><%= class_name %>Component, type: :component do
|
|
6
|
-
pending "add some examples to (or delete) #{__FILE__}"
|
|
7
|
-
|
|
8
|
-
# it "renders something useful" do
|
|
9
|
-
# expect(
|
|
10
|
-
# render_inline(described_class.new(attr: "value")) { "Hello, components!" }.css("p").to_html
|
|
11
|
-
# ).to include(
|
|
12
|
-
# "Hello, components!"
|
|
13
|
-
# )
|
|
14
|
-
# end
|
|
15
|
-
end
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require "rails/generators/erb/component_generator"
|
|
4
|
-
|
|
5
|
-
module Slim
|
|
6
|
-
module Generators
|
|
7
|
-
class ComponentGenerator < Erb::Generators::ComponentGenerator
|
|
8
|
-
include ViewComponent::AbstractGenerator
|
|
9
|
-
|
|
10
|
-
source_root File.expand_path("templates", __dir__)
|
|
11
|
-
class_option :sidecar, type: :boolean, default: false
|
|
12
|
-
|
|
13
|
-
def engine_name
|
|
14
|
-
"slim"
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
def copy_view_file
|
|
18
|
-
super
|
|
19
|
-
end
|
|
20
|
-
end
|
|
21
|
-
end
|
|
22
|
-
end
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
div Add <%= class_name %> template here
|
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require "rails/generators/abstract_generator"
|
|
4
|
-
|
|
5
|
-
module Stimulus
|
|
6
|
-
module Generators
|
|
7
|
-
class ComponentGenerator < ::Rails::Generators::NamedBase
|
|
8
|
-
include ViewComponent::AbstractGenerator
|
|
9
|
-
|
|
10
|
-
source_root File.expand_path("templates", __dir__)
|
|
11
|
-
class_option :sidecar, type: :boolean, default: false
|
|
12
|
-
class_option :typescript, type: :boolean, default: false
|
|
13
|
-
|
|
14
|
-
def create_stimulus_controller
|
|
15
|
-
template "component_controller.#{filetype}", destination
|
|
16
|
-
end
|
|
17
|
-
|
|
18
|
-
def stimulus_module
|
|
19
|
-
return "stimulus" if legacy_stimulus?
|
|
20
|
-
|
|
21
|
-
"@hotwired/stimulus"
|
|
22
|
-
end
|
|
23
|
-
|
|
24
|
-
private
|
|
25
|
-
|
|
26
|
-
def filetype
|
|
27
|
-
typescript? ? "ts" : "js"
|
|
28
|
-
end
|
|
29
|
-
|
|
30
|
-
def destination
|
|
31
|
-
if sidecar?
|
|
32
|
-
File.join(component_path, class_path, "#{file_name}_component", "#{file_name}_component_controller.#{filetype}")
|
|
33
|
-
else
|
|
34
|
-
File.join(component_path, class_path, "#{file_name}_component_controller.#{filetype}")
|
|
35
|
-
end
|
|
36
|
-
end
|
|
37
|
-
|
|
38
|
-
def legacy_stimulus?
|
|
39
|
-
package_json_pathname = Rails.root.join("package.json")
|
|
40
|
-
package_json_pathname.exist? && JSON.parse(package_json_pathname.read).dig("dependencies", "stimulus").present?
|
|
41
|
-
end
|
|
42
|
-
end
|
|
43
|
-
end
|
|
44
|
-
end
|
|
@@ -1,11 +0,0 @@
|
|
|
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
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
<div<%= data_attributes %>>Add <%= class_name %> template here</div>
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module TestUnit
|
|
4
|
-
module Generators
|
|
5
|
-
class ComponentGenerator < ::Rails::Generators::NamedBase
|
|
6
|
-
source_root File.expand_path("templates", __dir__)
|
|
7
|
-
check_class_collision suffix: "ComponentTest"
|
|
8
|
-
|
|
9
|
-
def create_test_file
|
|
10
|
-
template "component_test.rb", File.join("test/components", class_path, "#{file_name}_component_test.rb")
|
|
11
|
-
end
|
|
12
|
-
|
|
13
|
-
private
|
|
14
|
-
|
|
15
|
-
def file_name
|
|
16
|
-
@_file_name ||= super.sub(/_component\z/i, "")
|
|
17
|
-
end
|
|
18
|
-
end
|
|
19
|
-
end
|
|
20
|
-
end
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require "test_helper"
|
|
4
|
-
|
|
5
|
-
class <%= namespaced? ? "#{namespace.name}::" : '' %><%= class_name %>ComponentTest < ViewComponent::TestCase
|
|
6
|
-
def test_component_renders_something_useful
|
|
7
|
-
# assert_equal(
|
|
8
|
-
# %(<span>Hello, components!</span>),
|
|
9
|
-
# render_inline(<%= class_name %>Component.new(message: "Hello, components!")).css("span").to_html
|
|
10
|
-
# )
|
|
11
|
-
end
|
|
12
|
-
end
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
task stats: "view_component:statsetup"
|
|
4
|
-
|
|
5
|
-
namespace :view_component do
|
|
6
|
-
task :statsetup do
|
|
7
|
-
# :nocov:
|
|
8
|
-
require "rails/code_statistics"
|
|
9
|
-
|
|
10
|
-
if Rails.root.join(ViewComponent::Base.view_component_path).directory?
|
|
11
|
-
::STATS_DIRECTORIES << ["ViewComponents", ViewComponent::Base.view_component_path]
|
|
12
|
-
end
|
|
13
|
-
|
|
14
|
-
if Rails.root.join("test/components").directory?
|
|
15
|
-
::STATS_DIRECTORIES << ["ViewComponent tests", "test/components"]
|
|
16
|
-
CodeStatistics::TEST_TYPES << "ViewComponent tests"
|
|
17
|
-
end
|
|
18
|
-
# :nocov:
|
|
19
|
-
end
|
|
20
|
-
end
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module ViewComponent
|
|
4
|
-
module RenderComponentHelper # :nodoc:
|
|
5
|
-
def render_component(component, &block)
|
|
6
|
-
component.set_original_view_context(__vc_original_view_context) if is_a?(ViewComponent::Base)
|
|
7
|
-
component.render_in(self, &block)
|
|
8
|
-
end
|
|
9
|
-
end
|
|
10
|
-
end
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module ViewComponent
|
|
4
|
-
module RenderToStringMonkeyPatch # :nodoc:
|
|
5
|
-
def render_to_string(options = {}, args = {})
|
|
6
|
-
if options.respond_to?(:render_in)
|
|
7
|
-
options.render_in(view_context)
|
|
8
|
-
else
|
|
9
|
-
super
|
|
10
|
-
end
|
|
11
|
-
end
|
|
12
|
-
end
|
|
13
|
-
end
|