-
Notifications
You must be signed in to change notification settings - Fork 94
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support Phlex DSL on scenarios #585
base: main
Are you sure you want to change the base?
Conversation
✅ Deploy Preview for lookbook-docs canceled.
|
This does make sense if you're using Lookbook to document Phlex components that you intend to render inside other Phlex components, however, that's not the behaviour you would get from rendering a Phlex component in another context such as an ActionView view. Perhaps it should be a configuration option for this reason. 🤔 |
Yeah, I guess I can create another preview class, eg.: # lib/lookbook/phlex_preview.rb
module Lookbook
class PhlexPreview < Preview
def render(component, &block)
super do
component.instance_exec component, &block
end
end
end
end <!-- app/views/lookbook/previews/preview.html.erb -->
<% if defined?(Phlex::SGML) && @render_args[:component].is_a?(Phlex::SGML) %>
<%= render @render_args[:component], &@render_args[:block] %>
... User side: class MyComponentPreview < Lookbook::PhlexPreview # instead of Lookbook::Preview
def default
render MyComponent.new do |c|
c.title { "Hello" }
h2 { "World" }
render MyOtherComponent.new
end
end
end |
46330f0
to
cf7ec1a
Compare
<% else %> | ||
<%= render(@render_args[:component], @render_args[:args], &@render_args[:block]) %> | ||
<% end %> | ||
<%= render(@render_args[:component], @render_args[:args], &@render_args[:block]) %> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure why this was raw + call
, but changing to render component, args, block
worked on specs and on my project.
Using render
Rails calls component.render_in(self, &block)
. Ref: https://github.com/rails/rails/blob/main/actionview/lib/action_view/helpers/rendering_helper.rb#L42
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@stephannv the discussion in #400 should help explain the rationale for this, ugly as it is!
Having a different preview class for Phlex-context-previews feels better to me, but rather than instance-exec’ing the the block against the component being rendered, it would be better to have the preview itself be a It’s possible for components to override HTML elements. class A < Phlex::HTML
def template
h1 { "Hello" }
yield
end
def h1 = super(class: "from_a")
end
class B < Phlex::HTML
def template
render A.new do
h1 { "World!" }
end
end
end Rendering <h1 class="from_a">Hello</h1><h1>World!</h1> But if <h1 class="from_a">Hello</h1><h1 class="from_a">World!</h1> We can’t make |
cf7ec1a
to
da802d9
Compare
@stephannv thanks for taking the time to put this together. And @joeldrapper thanks for jumping in on the discussion with your expertise on this, much appreciated. I'm sadly not using Phlex on a day-today basis at the moment so forgive me if i'm a bit out of my depth with the details of what is being discussed here. I'm certainly not opposed to having a Phlex-specific preview class to inherit from (or a module that can be included in preview classes for Phlex components) if that means previews can be written in a way that feels more natural for Phlex users. FWIW, the sub-component render issue is actually also present for ViewComponent previews - to render a sub-component within a parent's component's block context you need to use the parent component's render method. You have to do something like: def example_preview
render ExampleComponent.new do |parent|
parent.render ChildComponent.new
end
end This is how it works in ViewComponent's own preview system which Lookbook previews are based on (and aim to be 100% compatible with). It's definitely not ideal for all the reasons you mention in #584 but will likely have to stay like that (for VC component previews, anyway). So is the general feeling here that it's worth waiting until |
I think that's our best option. It shouldn't be too long now. |
@stephannv helped me out, and I was able to make it work by using an initializer:
module Lookbook::PreviewOverrides
# see https://github.com/ViewComponent/lookbook/issues/584
def render(component = nil, **args, &block)
if block
super { component.instance_exec component, &block }
else
super
end
end
end
Rails.application.configure { Lookbook::Preview.prepend Lookbook::PreviewOverrides } But I would love to see better Phlex support! |
Fixes: #584
I'm not sure if this is the best solution but it's working 😅
Instead evaluating the block on Lookbook::Preview context, it is evaluating on component context, so it can render other components and use Phlex DSL.