diff --git a/CHANGELOG.md b/CHANGELOG.md
index 0763ae1..67dee12 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,6 +2,35 @@
## master
+- Support content blocks in `#render_component` and `#render_with`. ([@palkan][])
+
+```ruby
+class MyComponent::Preview
+ def default
+ # Now you can pass a block to render_component to render it inside the component:
+ render_component(kind: "info") do
+ "Welcome!"
+ end
+ end
+end
+```
+
+- Support implicit components in `#render_component` helper. ([@palkan][])
+
+```ruby
+class MyComponent::Preview
+ def default
+ # Before
+ render_component(MyComponent::Component.new(foo: "bar"))
+ end
+
+ # After
+ def default
+ render_component(foo: "bar")
+ end
+end
+```
+
## 0.1.4 (2023-04-30)
- Fix compatibility with new errors classes in view_component.
diff --git a/README.md b/README.md
index c277e6f..854009c 100644
--- a/README.md
+++ b/README.md
@@ -159,6 +159,14 @@ class Banner::Preview < ApplicationViewComponentPreview
def default
# This will use `absolute w-full` for the container class
render_component Banner::Component.new(text: "Welcome!")
+
+ # or even shorter
+ render_component(text: "Welcome!")
+
+ # you can also pass a content block
+ render_component(kind: :notice) do
+ "Some content"
+ end
end
def mobile
diff --git a/app/views/view_component_contrib/preview.html.erb b/app/views/view_component_contrib/preview.html.erb
index 493184f..9202111 100644
--- a/app/views/view_component_contrib/preview.html.erb
+++ b/app/views/view_component_contrib/preview.html.erb
@@ -1,6 +1,10 @@
<%- if component -%>
- <%= render component %>
+ <%- if local_assigns[:content_block] -%>
+ <%= render component, &content_block %>
+ <% else %>
+ <%= render component %>
+ <% end %>
<%- else -%>
Failed to infer a component from the preview: <%= error %>
<%- end -%>
diff --git a/lib/view_component_contrib/preview/base.rb b/lib/view_component_contrib/preview/base.rb
index 7ad2e35..7c95c98 100644
--- a/lib/view_component_contrib/preview/base.rb
+++ b/lib/view_component_contrib/preview/base.rb
@@ -60,8 +60,14 @@ def render_with(**locals)
end
# Shortcut for render_with_template(locals: {component: ...})
- def render_component(component)
- render_with(component: component)
+ def render_component(component_or_props = nil, &block)
+ component = if component_or_props.is_a?(::ViewComponent::Base)
+ component_or_props
+ else
+ self.class.name.sub(/Preview$/, "Component").constantize.new(**(component_or_props || {}))
+ end
+
+ render_with(component: component, content_block: block)
end
end
end
diff --git a/test/cases/previews_test.rb b/test/cases/previews_test.rb
index 87a4d7c..f315f54 100644
--- a/test/cases/previews_test.rb
+++ b/test/cases/previews_test.rb
@@ -42,6 +42,12 @@ def test_preview_with_explicit_component_and_container_class
assert_select "div.w-full", text: "Wide"
end
+ def test_preview_with_implicit_component_and_content_block
+ get "/rails/view_components/button/danger"
+
+ assert_select "button.btn-danger", text: "Danger"
+ end
+
def test_preview_with_explicit_root_template
get "/rails/view_components/custom_banner/default"
diff --git a/test/internal/app/frontend/components/banner/preview.rb b/test/internal/app/frontend/components/banner/preview.rb
index 0c635bb..0905269 100644
--- a/test/internal/app/frontend/components/banner/preview.rb
+++ b/test/internal/app/frontend/components/banner/preview.rb
@@ -14,4 +14,10 @@ def wide
container_class: "w-full"
)
end
+
+ def with_custom_text
+ render_component do
+ "Custom text"
+ end
+ end
end
diff --git a/test/internal/app/frontend/components/button/component.html.erb b/test/internal/app/frontend/components/button/component.html.erb
new file mode 100644
index 0000000..5a1094b
--- /dev/null
+++ b/test/internal/app/frontend/components/button/component.html.erb
@@ -0,0 +1 @@
+
diff --git a/test/internal/app/frontend/components/button/component.rb b/test/internal/app/frontend/components/button/component.rb
new file mode 100644
index 0000000..4dc507d
--- /dev/null
+++ b/test/internal/app/frontend/components/button/component.rb
@@ -0,0 +1,10 @@
+# frozen_string_literal: true
+
+class Button::Component < ViewComponentContrib::Base
+ attr_reader :type, :kind
+
+ def initialize(type: "button", kind: "primary")
+ @type = type
+ @kind = kind
+ end
+end
diff --git a/test/internal/app/frontend/components/button/preview.rb b/test/internal/app/frontend/components/button/preview.rb
new file mode 100644
index 0000000..557f07d
--- /dev/null
+++ b/test/internal/app/frontend/components/button/preview.rb
@@ -0,0 +1,11 @@
+# frozen_string_literal: true
+
+class Button::Preview < ApplicationViewComponentPreview
+ def info
+ render_component(kind: :info) { "Info" }
+ end
+
+ def danger
+ render_component(kind: :danger) { "Danger" }
+ end
+end