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

Local-scoped components #110

Open
guisehn opened this issue Apr 17, 2024 · 1 comment
Open

Local-scoped components #110

guisehn opened this issue Apr 17, 2024 · 1 comment

Comments

@guisehn
Copy link

guisehn commented Apr 17, 2024

Hello! First of all, thanks so much for building this project. I've always wanted to have this kind of template in Ruby/Rails, and it's amazing to see this library implementing it.

I'm currently evaluating using it in a personal project, but one feature that I couldn't find in Rbexy and that I think is very interesting is the ability to define local-scoped components, just like React allows you to define multiple function components in a file, and like Phoenix LiveView also allows doing with functional components.

Sometimes, a component, or a view, is made of smaller subcomponents that are not supposed to be global throughout the application. Global components promote reusability, but lots of times a component is not meant to be reusable. The issues I think we have with everything being global by default are:

  • We need to be more careful to avoid name clashes, and sometimes create very specific namespaces

  • Too many files for defining a component, and lots of indirection and jumping around

  • Global components promote reusability and sometimes making something reusable/abstracted too soon results in a complex component that addresses too many use cases (by receiving different options). Early abstractions are often bad.

Allowing multiple components to be defined in a single file and making them locally scoped would help address those points. I think this would require allowing the template to be defined inside the ruby file itself, which also has some challenges around code highlighting.

What do you think of the idea? Is this something that was already considered in the development of Rbexy?

@patbenatar
Copy link
Owner

@guisehn Hey! This is a great idea. I think this is more-or-less already doable in a couple of different ways, but perhaps could have some syntactic sugar added to make it a little nicer to do so:

Option 1: namespaced component classes

class RootComponent < Rbexy::Component
  class SubComponent < Rbexy::Component
  end
end

Templates would be root_component.rbx and root_component/sub_component.rbx

Technically SubComponent is still globally available as <RootComponent.Sub /> but I think the naming being within the RootComponent namespace makes the intention clear.

Option 2: manually render sub-templates

class RootComponent < Rbexy::Component
  def sub
    Rbexy.evaluate("<div>Some sub-template here</div>", self)
  end
end

And in root_component.rbx template:

<div>
  <h1>Root component</h1>
  {sub}
</div>

You could use a heredoc for longer templates:

class RootComponent < Rbexy::Component
  def sub
    Rbexy.evaluate(<<-RBX, self)
      <div>
        <p>Some more complicated template here</p>
      </div>
    RBX
  end
end

I haven't tested any of this but I think it's all possible. Curious to hear your thoughts.

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

No branches or pull requests

2 participants