Flexible UI components

At carwow we have a styleguide. It’s a great way to keep a more consistent design and it also helps to improve designer and developer communication as it creates a common vocabulary for UI discussions.

That’s the place we keep shared components that act as building blocks which can be combined to create the things you see on our website. And in order to make it easier to “componentise” the design as much as we can, we’ve created the concept of UI components.

An UI component is simply a partial describing how certain design elements are rendered. It accepts a hash of custom properties and a block containing a Haml snippet that’s usually appended to the component but can be also used in a different location within the component.

If you need a tooltip, for example, we would use the following code:

The snippet above would be rendered as the following:

It works quite well but lacks flexibility. We can’t, for example, have properties that are composed by other components once we can only provide one block to it. Also, for the content, it’s not ideal to write HTML in the properties. Especially because everything else is written in HAML.

In my opinion, it would be great to have a way to describe a component using a simple DSL (like rails JBuilder, for example). Something like:

While you can still set the properties hash like the id and position, it would also allow us to describe properties as blocks. In this case, the content and placeholder blocks behave like component custom properties.

It would be awesome if we also could create composed components. A component the contains other components. Something like:

Where ui_icon behaves like an ui_component.

Cool! With this draft in mind I decided to give it a try and, to my surprise, it turned out to be a super easy change.

I created theComponentProperties class that can catch the properties described for the blocks with the help of the (in)famous method_missing. Basically:

The method_missing is the one to pay attention here. It catches the property name and the block that defines it and, using capture, sets the rendered view to the hash. To be able to do the that I’ve included the Haml helpers so I could get advantage of capture_haml that basically renders the haml code provided in the property block.

In the ui_component helper method we have the following:

If a block is given we initialise a component then yield it to the block to capture and store the custom properties.

The component partial (located in the /views/components folder) reads like so:

All properties set in the hash or through the blocks can be accessed from the properties hash assigned to the partial.

Here’s an example of the new way of setting the component properties:

That will generate the following html snippet:

Where the SVG content is the result of our ui_icon component.

So the ui_component now can handle blocks for all its properties. This allow us, for example, to create components that contain other components.

It’s a simple change but it brings a lot of power and flexibility to our ui components.

Especially now that we’re planning to play with Atomic Design it could be very handy.

Keep coding!

Interested in making an Impact? Join the carwow-team!
Feeling social? Connect with us on Twitter and LinkedIn :-)