Closed bloudermilk closed 1 year ago
I'm working around this for now by concatenating the children explicitly:
def call
form_for object, url: url do |form|
content + Form::ButtonBarComponent.new(self).render_in(self)
end
end
It works but syntactically seems a bit strange? Other than some kind of magic DSL the only (arguably) better syntax might be to return an Array like so:
def call
form_for object, url: url do |form|
[
content,
Form::ButtonBarComponent.new(self).render_in(self),
]
end
end
Technically #call
can return any string and that'll be inserted into the rendered HTML output, so e.g. you could do something like:
def call
form_for object, url: url do |form|
[
content,
Form::ButtonBarComponent.new(self).render_in(self)
].join
end
end
I'd recommend making the form_for
itself a component though, and using context to pass the form builder down to child components like <Form.TextField />
etc
class FormComponent
def call
form_for object, url: url do |form|
create_context(:form, form)
content
end
end
end
And then you can use it like so:
<Form object={...} url={...}>
# whatever you had as children to your example component
<Form.ButtonBar />
</Form>
Haha jinx on that workaround!
If you wanted all forms to have that bar, you could just wrap that example template above in another component like <FormWithButtons />
haha nice timing
I like the composition-based approach you proposed. I'll probably go that route for now, thanks!
Having everything as a component makes things smoother, rather than switching between components and Rails block-based HTML builders (those are yucky when you have to concat them like above). So I'll just wrap those Rails helpers in call-components when I do need them.
In JSX / React you can use Fragment components to encapsulate multiple child components without rendering any wrapping DOM elements.
Examples from React docs:
I'm wishing I had this right now in a #call method with multiple children where I don't want to render another parent element.
Any way to accomplish this in rbexy today? If not, would it be a welcome contribution?