Skip to content
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 required: true for renders_one slots #1861

Open
wants to merge 2 commits into
base: main
Choose a base branch
from

Conversation

jalyna
Copy link

@jalyna jalyna commented Sep 25, 2023

Hi everyone, first of all thanks for the amazing work! I really love working with view_component!

I'm very new to the project and hope I can contribute to this project. Looking forward to any feedback.

What are you trying to accomplish?

Trying to solve the issue described in #614

What approach did you choose and why?

Add required option to renders_one to indicate that there is a default slot to be rendered, which automatically applies lambda options. This only works with lambda or Component slots (and not for passthrough slots). It can be used with polymorphic slots but exactly one specific option can be required, otherwise an error is shown.

This is just my first attempt and probably a lot of fine tuning is needed as this project is used by many people.

Anything you want to highlight for special attention from reviewers?

I added a new method __vc_before_render to the Base class in order to register a method called from the Slotable module. This way I was able to add defaults to the slots before before_render is called. I'm not sure if this is the best approach yet, but I'm happy to get any feedback.

Fixes ViewComponent#614

Add `required` option to `renders_one` to indicate that there is a default slot to be rendered, which automatically applies lambda options. This only works with lambda or Component slots (and not for passthrough slots). It can be used with polymorphic slots but exactly one specific option can be required, otherwise an error is shown.
@jalyna jalyna marked this pull request as ready for review September 25, 2023 20:45
@BlakeWilliams
Copy link
Contributor

BlakeWilliams commented Oct 30, 2023

@jalyna Sorry for the delay here, and thanks for the PR!

I like the direction this is going, but I think there's a few tweaks we want to make before moving forward here. I think we should omit required as a keyword since that and providing a default value have different meanings. required should mean that a consumer has to provide the slot value.

Instead, I'd propose that we have a conventional/automagical field like default_line_item_icon that when present, is called and used as the slots default value if the consumer didn't provide one.

e.g.

class MyComponent
  renders_one :header

  # If a `with_header` is not called, this method will be called and the result will be used as the slots value
  def default_header
    MyHeaderComponent.new(title: "Hello world")
  end
end

This has a few advantages:

  • The existing public slot API stays the same with no changes
  • It doesn't require components to implement default arguments
  • The method allows you to pass your own arguments to the default slot and can use component local state to make decisions on what those arguments should be.
  • We can avoid having to add the internal __vc_before_render hook, and instead hook directly into the accessors generated by the slotable module.

Having default slot values is something we've wanted to implement for a while, so thanks for pushing this forward!

@joelhawksley
Copy link
Member

@jalyna what do you think of @BlakeWilliams's suggestion?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants