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