From 642d1215f59239a848dfe886722847a31897b3b6 Mon Sep 17 00:00:00 2001 From: Joel Drapper Date: Sun, 12 May 2024 18:46:31 +0100 Subject: [PATCH 1/2] WIP --- lib/phlex/rails/buffered.rb | 2 +- lib/phlex/rails/sgml.rb | 27 +++++++++++++++++-- .../app/views/rendering/vc_component.html.erb | 2 ++ .../dummy/app/views/rendering/vc_component.rb | 6 ----- .../rendering/view_component_from_phlex.rb | 8 ++++-- test/phlex/render_test.rb | 1 + 6 files changed, 35 insertions(+), 11 deletions(-) create mode 100644 test/dummy/app/views/rendering/vc_component.html.erb diff --git a/lib/phlex/rails/buffered.rb b/lib/phlex/rails/buffered.rb index de1f475f..ef1f7c71 100644 --- a/lib/phlex/rails/buffered.rb +++ b/lib/phlex/rails/buffered.rb @@ -50,7 +50,7 @@ def respond_to_missing?(...) def method_missing(*args, **kwargs, &block) output = if block - @object.public_send(*args, **kwargs) { @view.capture(&block) } + @object.public_send(*args, **kwargs) { |*a| @view.capture(*a, &block) } else @object.public_send(*args, **kwargs) end diff --git a/lib/phlex/rails/sgml.rb b/lib/phlex/rails/sgml.rb index 4930ea54..98fe4c27 100644 --- a/lib/phlex/rails/sgml.rb +++ b/lib/phlex/rails/sgml.rb @@ -2,6 +2,23 @@ module Phlex module Rails + class ViewComponentDecorator + def initialize(view_component, context:) + @view_component = view_component + @context = context + end + + def method_missing(*args, **kwargs, &block) + if block + @view_component.public_send(*args, **kwargs) do |*a| + @context.capture(*a, &block) + end + else + @view_component.public_send(*args, **kwargs) + end + end + end + module SGML module ClassMethods def render_in(...) @@ -30,7 +47,13 @@ def render(*args, **kwargs, &block) return super unless renderable.is_a?(ActiveRecord::Relation) else if block - @_context.target << @_view_context.render(*args, **kwargs) { capture(&block) } + @_context.target << @_view_context.render(*args, **kwargs) do |*yielded_args| + if yielded_args.length == 1 && defined?(ViewComponent::Base) && ViewComponent::Base === yielded_args[0] + capture(Phlex::Rails::ViewComponentDecorator.new(yielded_args[0], context: self), &block) + else + capture(*yielded_args, &block) + end + end else @_context.target << @_view_context.render(*args, **kwargs) end @@ -70,7 +93,7 @@ def render_in(view_context, &block) end end - def capture + def capture(...) super&.html_safe end diff --git a/test/dummy/app/views/rendering/vc_component.html.erb b/test/dummy/app/views/rendering/vc_component.html.erb new file mode 100644 index 00000000..23a8e615 --- /dev/null +++ b/test/dummy/app/views/rendering/vc_component.html.erb @@ -0,0 +1,2 @@ + +<%= slot %> diff --git a/test/dummy/app/views/rendering/vc_component.rb b/test/dummy/app/views/rendering/vc_component.rb index 1376a576..d6ef3994 100644 --- a/test/dummy/app/views/rendering/vc_component.rb +++ b/test/dummy/app/views/rendering/vc_component.rb @@ -3,11 +3,5 @@ module Rendering class VcComponent < ViewComponent::Base renders_one :slot - - def call - if slot? - slot - end - end end end diff --git a/test/dummy/app/views/rendering/view_component_from_phlex.rb b/test/dummy/app/views/rendering/view_component_from_phlex.rb index 80b8a070..e17ea76c 100644 --- a/test/dummy/app/views/rendering/view_component_from_phlex.rb +++ b/test/dummy/app/views/rendering/view_component_from_phlex.rb @@ -3,11 +3,15 @@ module Rendering class ViewComponentFromPhlex < ApplicationView def view_template + h1 { "Before" } + render VcComponent.new do |component| - component.slot do - h1 { "Rendered from Phlex" } + component.with_slot do + h1(id: "phlex") { "Rendered from Phlex" } end end + + h1 { "After" } end end end diff --git a/test/phlex/render_test.rb b/test/phlex/render_test.rb index 17f0edb5..fdc30e9a 100644 --- a/test/phlex/render_test.rb +++ b/test/phlex/render_test.rb @@ -12,5 +12,6 @@ class RenderTest < ActionDispatch::IntegrationTest test "rendering view_component component from Phlex view" do get "/rendering/view_component_from_phlex" assert_response :success + assert_select "#phlex", "Rendered from Phlex" end end From db0fd203d91af4897cd1bed2723c63da85ab56dd Mon Sep 17 00:00:00 2001 From: Joel Drapper Date: Wed, 15 May 2024 13:30:41 +0100 Subject: [PATCH 2/2] Use the existing `Buffered` object for view component --- lib/phlex/rails/sgml.rb | 19 +------------------ 1 file changed, 1 insertion(+), 18 deletions(-) diff --git a/lib/phlex/rails/sgml.rb b/lib/phlex/rails/sgml.rb index 98fe4c27..90be5385 100644 --- a/lib/phlex/rails/sgml.rb +++ b/lib/phlex/rails/sgml.rb @@ -2,23 +2,6 @@ module Phlex module Rails - class ViewComponentDecorator - def initialize(view_component, context:) - @view_component = view_component - @context = context - end - - def method_missing(*args, **kwargs, &block) - if block - @view_component.public_send(*args, **kwargs) do |*a| - @context.capture(*a, &block) - end - else - @view_component.public_send(*args, **kwargs) - end - end - end - module SGML module ClassMethods def render_in(...) @@ -49,7 +32,7 @@ def render(*args, **kwargs, &block) if block @_context.target << @_view_context.render(*args, **kwargs) do |*yielded_args| if yielded_args.length == 1 && defined?(ViewComponent::Base) && ViewComponent::Base === yielded_args[0] - capture(Phlex::Rails::ViewComponentDecorator.new(yielded_args[0], context: self), &block) + capture(Phlex::Rails::Buffered.new(yielded_args[0], view: self), &block) else capture(*yielded_args, &block) end