Building Scalable Client-side Components

Matheus Azzi
The Miners
Published in
4 min readNov 29, 2016

Writing components is a good way to structure our client-side apps. However we should be careful when writing and using them.

In my recent projects I always kept a Styleguide. All components built by me and the team I work with live there as a components catalog. That’s great, because it provides us an isolated component development.

There we create components in a generic way, outside from its real scenario. We can ensure that it’s built to be reusable and not tailor made for a specific feature.

An example of that kind of tool is React Storybook. Although, you can do it in your own way, anything that fits your stack, but please, maintain a Styleguide, it will help everyone.

Reusability and Independence

Components should be reusable, but they should be independent too. Every behavior must be driven by the component API, it shouldn’t be manipulated by outside.

Lets take a button component as an example. It may have lots of variations, it can be a small button, an iconed button, a disabled button, etc… To achieve this we need classes like:

.btn {}, .btn-primary {}, .btn-small {}, .btn-loading {}, ... 

Those classes must be managed by a small component API. The developer who will use this component mustn’t touch those classes, the developer must only tell the component which variation is wanted.

Developer doesn’t need to style anything in the component, just pass options to generate the wanted variation.

What do you do when you need a new variation of a component? I’ve been seeing developers creating variations like:

The "btn-circle" class is added outside component’s definition.

As you can see, a new variation isn’t created. That circular button is styled and managed outside component’s API. That isn’t healthy for the app, because in future another developer may need to reuse that, what this developer will do is to copy & paste it in another place.

Doing things this way will certainly lead us to have variations of components not specified in our Styleguide.

Remember, that’s a single small example, imagine it happening with Modals, Cards and Tables with different variations through the app. It’ll be a Component-Frankenstein.

I think the correct way is to tell the button’s component API what I want. In that case I created a shape optional property:

With "shape" option the developer doesn’t need to know which classes are needed to generate a circular <ui-button>.

I advocate to that because in my opinion every behavior and style must be defined inside the component. CSS classes shouldn’t be exposed. Whatever methodology you’re using, CSS is about composition. I may use 3 different classes to supply a variation and I don’t want those classes being copied and pasted all over the app.

When everything is inside the component I can refactor CSS classes without changing component’s API or touching places that are using it.

For using a good component, you’ll need to just drop it and pass its options. Only with all styles being internal we can ensure that the Styleguide is being properly maintained.

Here is an example of how I’d build this <ui-button>. If you’re not familiar with, I’m using Vue.js to write the component below:

Here is the usage case (all values are optional):

Example of using <ui-button></ui-button>

The logic behind it applies to any kind of component library or web-components, you can choose your favorite one since you’ve a way to validate and set default properties for them.

Composability

Components must be composable. If you think it isn’t valid to add a shape property in the API of your <ui-button> component. Or if it isn’t only about styling but the circular button will have different behavior and responsibilities. One of the options is to create a circular button component (<circular-button>).

That component can composes <ui-button> and adds its own variations. For example, a floating property that will make the button be a floating fixed button in the right-bottom corner of screen.

More options could be added, as a floating-direction, and others, but I think you got it.

CSS Composability

Sometimes it may not make sense to create a component for something. I’m talking about a scenario where we’ve defined classes to style typography. Imagine we’ve reusable classes that style titles in our app like:

.title {}, .title-1 {}, .title-2 {}, ...

If doesn’t make sense to create a title component, whether because we want it to be free to set any typography style to any text element, such as h1, h2, span, p, li, for example, or any other reason. (I know that we can create a component with a dynamic tag, but that isnt the point here).

We want it to be a reusable style in our app. That seems to be a good case for CSS Modules. We can solve it composing the .title, .title-1 classes inside another component.

Creates a Modal component, where the .modal-title class composes .title and .title-1 styles.

The .modal-title will composes those typography styles we want and we are free to use any HTML tag together with the modal-title class. When using the Modal component, the generated HTML will use all three classes:

<strong class="modal-title title title-1">Hello World!</strong>

Composing classes will make our template code cleaner, but we must only do it when isn’t better to compose a component.

Those are my thoughts when writing components, I hope it helps someone.

Please share it if you liked. Or leave a comment :)

--

--