Slots V2 #454
-
The road to Slots V2We've been using slots internally for a while now and we really like the concept. It's time to start thinking about how it should look like for ViewComponent 3.0 and beyond. Our feelings so farGood:
Bad:
Things we want to change
We'd love to hear from you!Are you using slots? We'd love to hear your thoughts/experiences using slots. We want to know what you like, what could be improved, and what you'd like to see in the future. cc @bbugh @jensljungblad @jonspalmer @thomasbrus since y'all had some really great thoughts and input on v1. |
Beta Was this translation helpful? Give feedback.
Replies: 9 comments 17 replies
-
I'm a big fan of the I like the simplicity of the collection API too. I remember there being reasons why we needed the explicit API but I no longer have the details paged into my brain. If we can make it work simply I'm a fan. |
Beta Was this translation helpful? Give feedback.
-
Hi! I was directed here from #451 . So, the question would be, if slots can be made to also solve #387. Slots, as currently documented, and with the modifications presented here, appear to be a way for the component user to inject content into the component. Slots do not have their own template, and are exposed to the end user. OTOH, what I actually need is only a way to be able to extract methods from the main method, for internal code organization purposes. For #387 to be solved, slots would need to (be able to):
I specifically don't want a hypothetical TableComponent user to know (or care) that there is a slot that renders the row. All the user should do is |
Beta Was this translation helpful? Give feedback.
-
Another thing that has come up for us internally is the desire to be able to pass content to slots via an argument vs. a block. For example, we have a component that has a |
Beta Was this translation helpful? Give feedback.
-
That's the API I chose for https://github.com/jensljungblad/elemental_components as well. There's an example here: https://github.com/jensljungblad/elemental_components#elements.
I too remember it was brought up somewhere, but I can't seem to find it! |
Beta Was this translation helpful? Give feedback.
-
I'm a huge fan of this.
The API for collections of slots has been bothering me. In some cases it acts like an array; in other cases it doesn't. I propose that the API goes all-in on acting like an array. Consider this code: = render BadgeComponent.new do |c|
= c.slot(:detail) do
Name: Brad Gessler
= c.slot(:detail) do
Height: Tall I assume I'm appending an array of slots? Could it look and feel more like I'm manipulating an array of slots? = render BadgeComponent.new do |c|
= c.details.append do
Name: Brad Gessler
= c.details.append do
Height: Tall The view code for the component is already using an Array-ish API: .badge-component
- if details.empty?
Nothing to see here
- else
- details.each do |d|
= d.content Inside of that component, I might want to also be able to look at that collection of detail slots and possibly manipulate it from within the Ruby code: class BadgeComponent < ViewComponent::Base
include ViewComponent::Slotable
with_slot :title
with_slot :detail, collection: true
def initialize(title, example_details: 0)
@title = title
example_details.times do |n|
details.append "Detail #{n}"
end
end
end Treating collection slots as an array would make some composition/inheritance problems a little easier to implement. |
Beta Was this translation helpful? Give feedback.
-
Seems like some good changes.
We had discussed this and I spent some time prototyping it this, but IIRC the reason it didn't work at the time is that the method has to perform two different incompatible functions. For example, these two <%= render SomeComponent.new do |c| %>
<%# c is the instance of SomeComponent %>
<% c.header ... %>
<% end %> # some_component.html.erb
<%# self is the same instance of SomeComponent %>
<%= header %> |
Beta Was this translation helpful? Give feedback.
-
@bbugh you're correct to identify the conflict between the two incompatible functions. It's likely that we'll need to change the API for accessing slot content. |
Beta Was this translation helpful? Give feedback.
-
Heya! I was directed from here. I'm gonna copy and paste some of what I wrote over there, but I think it'd be great if slots allowed non-keyword argument parameters! Feature Request Motivation class ButtonComponent < ApplicationComponent
def initialize(*traits, **html_attributes) class DropdownMenuComponent < ApplicationComponent
include ViewComponent::Slotable
...
class BaseToggle < ViewComponent::Slot
...
end
class ButtonToggle < BaseToggle
# It would be nice if I can match this with the button component and use *traits
def initialize(traits: [], **html_attributes)
...
end
end Definitely not a make it or break it, but I think the flexibility would be nice! |
Beta Was this translation helpful? Give feedback.
-
👋 Hey y'all! Thanks a ton for all the feedback, it's been super helpful 🙏 We've been hard at work on slots v2 and have a draft PR up here: #503 We'd love to get your feedback on the current state of slots v2 and how compatible these changes are with how you currently write, and want to write slots. There's also another proposal that we'd love feedback that has a larger impact on how slots would be written here: https://github.com/github/view_component/pull/503/files#r506001533 Feel free to comment with thoughts and ideas in the pull request itself. |
Beta Was this translation helpful? Give feedback.
👋 Hey y'all! Thanks a ton for all the feedback, it's been super helpful 🙏
We've been hard at work on slots v2 and have a draft PR up here: #503
We'd love to get your feedback on the current state of slots v2 and how compatible these changes are with how you currently write, and want to write slots. There's also another proposal that we'd love feedback that has a larger impact on how slots would be written here: https://github.com/github/view_component/pull/503/files#r506001533
Feel free to comment with thoughts and ideas in the pull request itself.