Andrea Barghigiani


870 Experience
8 Lessons Completed
0 Questions Solved


Posted in Dropzone with Shrine

Tim did you had any luck with this? I am in your same situation and the only resource I found it's an old article on Medium

Well after a first look at the Primer BaseComponent I should start create some helper methods to handle this situation.

I am still new with the OOP paradigm and Rails in general. Even if this could be a great opportunity to learn it I am starting to think that probably will be better for me if I stick with the focus of the project to get experienced with Rails while following closely the evolution in the ViewComponent repo.

I know you don't know my experience but I'll asking anyway: do you think will be a better use of my time? 😊

Hi all,
this is my first post and I am working with Ruby and Ruby on Rails for about a month. I have years of experience as a web developer but my focus was more on the Frontend part, if you don't count the WordPress experience.
I am trying to build some side projects to get me comfortable with Ruby and I am trying to use the ViewComponent and TailwindCSS just for practice.

As commonly happen I got confused setting up my project.

The scope of the app I am building is not important for now because I got stuck at creating a sort of design system that uses Tailwind CSS classes under the hood. Right now my focus is to create a sort of general ViewComponent that will let me define those classes passing attributes. Basically, I am creating a general BaseComponent that is supposed to handle all the class setting stuff:

<%= render
  bgc: "blue-300",
  color: "gray-100",
  m: 3
) %>

This is how I think to invoke the BaseComponent and the idea behind this is that all my components should inherit this class to compose the classes in an easier way, but before to give you an example here's the class:

class BaseComponent < ViewComponent::Base
  def initialize(styles)
    @styles = styles
    @c = []

  def classes
    # Calling internal methods before return

  def colors
    @c << "bg-#{@styles[:bgc]}" if @styles[:bgc]
    @c << "text-#{@styles[:color]}" if @styles[:color]

  def margins
    # Global
    @c << "m-#{@styles[:m]}" if @styles[:m]
    # Positive
    @c << "my-#{@styles[:my]}" if @styles[:my]
    @c << "mt-#{@styles[:mt]}" if @styles[:mt]
    @c << "mb-#{@styles[:mb]}" if @styles[:mb]
    @c << "mx-#{@styles[:mx]}" if @styles[:mx]
    @c << "mr-#{@styles[:mr]}" if @styles[:mr]
    @c << "ml-#{@styles[:ml]}" if @styles[:ml]
    # Negative 
    @c << "-m-#{@styles[:n_m]}" if @styles[:n_m]
    @c << "-my-#{@styles[:n_my]}" if @styles[:n_my]
    @c << "-mt-#{@styles[:n_mt]}" if @styles[:n_mt]
    @c << "-mb-#{@styles[:n_mb]}" if @styles[:n_mb]
    @c << "-mx-#{@styles[:n_mx]}" if @styles[:n_mx]
    @c << "-mr-#{@styles[:n_mr]}" if @styles[:n_mr]
    @c << "-ml-#{@styles[:n_ml]}" if @styles[:n_ml]

From my point of view, this is already getting too complex and this is the reason I am writing to you, I just handled a bunch of color and margins and the code seems just too much from what I saw from the Rails codebase I working on and on many tutorials. Also Rubocop tells me that the margin method is already too complex since it has too many lines of code 😊

The idea behind this "mess" is for example that in a ButtonComponent I could setup it like the following:

<%= render
  style: "rounded",
  variant: "primary"
) %>

And within the class that defines it check the values of the attributes and build the class from the dedicated parent methods.

I would like to confront with you because all the tutorials that I saw that mixes ViewComponents and TailwindCSS the classes is embedded in the ERB template and from my point of view this is a good use for that single button, but it will not help me if I need to give more flexibility to my components.

So here's my question: what do you think of this approach? Shall I just forget about the BaseComponent and build the TailwindCSS classes right inside the single component? Something like:

class ButtonComponent < ViewComponent::Base
    def initialize(
        style: "square",
        variant: nil
        @style = style
        @variant = variant

    def classes
        c = ["standard-tailwind-classes"]
        c << "rounded-full" if @style == "pil"
        c << "rounded-md" if @style == "rounded"
        c << "bg-green-600 text-gray-100" if @variant == "primary"
        c << "bg-red-700 text-gray-100" if @variant == "danger"
        c.join(' ')

Or shall I just keep trying to get the flexibility that TailwindCSS offers passing attributes to my ViewComponents?

As you can see I am a bit confused 😂