Building a UI-Kit for React Projects

June 20, 2018 0 Comments

Building a UI-Kit for React Projects

 

 

I am Lead Frontend Developer at Homelike, a PropTech Start-Up from Cologne, Germany. I specialise in ReactJS and its ecosystem, as well as the Apollo Client for our GraphQL queries.

Most of my experience is self-taught over multiple years and several projects, including a year of struggling with Angular 4/5. That also taught me a lot more about building a more complete application architecture and unit-testing.

The problem we wanted to solve

With a strong focus on minimalism and clean design, I try to prevent duplicate code as much as possible, especially across projects in the same company with the same design. Sharing components across multiple components, by copying them. This would be a huge pain to maintain in the long run.

So what was our solution?

The Homelike UI-Kit is a highly customisable UI Library, that adds presentational components with certain interactions, like onClicks and onChanges. These are defined by our design team, because they are already thinking in the same concepts as us in the dev team.

A big project that led to creating our UI-Kit was the rethinking of the Booking Flow on Homelike. We had also in mind that all components built there should be available in other micro-services and parts of our application, like the Dashboard and the Search page.

So the decision was made by me and our Lead Engineer to built a UI-Kit which houses all our main UI-Components and that is scalable in the future. We wanted to have a UI-Kit that enhances our development experience, by adding re-usability of the most common UI Elements and the interactivity with them.

The core of our UI-Kit is React with styled-components. We chose styled-components, because it is one of the major CSS-in-JS libraries in the React ecosystem. As we only wanted to build Presentational Components, this came in very handy as our components just consisted of CSS, that reacts to certain props.

Here is an example of the Card, CardBody and CardFooter component, with which we can style our Card-Layout in the Dashboard on a mobile screen.

Card.js

import styled from 'styled-components'; import Panel from '../Panel';
import * as variables from '../../styles/variables'; const Card = styled(Panel)` padding: 0; display: flex; flex-direction: column; margin-bottom: ${variables.spacing * 1.5}px;
`; export default Card;

CardBody.js

import styled from 'styled-components'; import * as variables from '../../styles/variables'; const CardBody = styled.div` display: flex; flex-wrap: wrap; width: 100%; margin-bottom: ${variables.spacing * 1.5}px;
`; export default CardBody;

CardFooter.js

import styled from 'styled-components';
import PropTypes from 'prop-types'; import * as colors from '../../styles/colors';
import { spacing } from '../../styles/variables'; const CardFooter = styled.div` display: flex; width: 100%; padding: ${spacing * 0.5}px 0; background-color: ${({ bgColor }) => colors[bgColor || 'white']};
`; CardFooter.defaultProps = { bgColor: 'white'
}; CardFooter.propTypes = { bgColor: PropTypes.string
}; export default CardFooter;

With that we can now use them like this and create our UI without repeating CSS and different style states etc.:

import React from 'react';
import { Card, CardBody, CardFooter } from 'my-ui-kit'; const ExampleCard = ({ name, description, image, action }) => { return ( <Card> <CardBody> <img src={image} className="image" /> <span>{name}</span> <span>{description}</span> </CardBody> <CardFooter bgColor="green"> <button onClick={action}>More Details</button> </CardFooter> </Card> );
}; export default ExampleCard;

Key learnings

It was definitely a big thought process for me. I always had to keep in mind, that these are universal solutions, not just for one single part of the application, so any change will affect the other parts of the application. It kept the code clean on one hand, but on the other it made us and the design team think more about uniformity and sometimes sacrifice form over function.

I also would definitely say, that this was an amazing experience as it helps you stay on focus with all changes you make. Any new project will add complexity, but the benefits came apparent later. In the next project we started our development time was blazing fast. We managed to implement the Dashboard with these components in less then 3 weeks and only one developer, thanks to the already existing components.

A challenge we faced was deciding on where we want to house this library. Because we were not working in a mono-repo yet, we decided to go with a npm package, that we install through git as this takes away the complexity of setting up a private npm org and adding all team members. Another challenge was unit-testing as we did not implement that right away, because of time constraints in the project plan.

Tips and advice

These are some tips I can give you:

  1. Any ReactJS codebase should implement a UI-Library as soon as possible, even if it increases the development time in the beginning, it will be a huge win in the long run.

  2. Pick a CSS-in-JS library you are comfortable with and that lets you customise as much as possible.

  3. Reduce the time between updating packages in projects with using npm link ../path/to/package in the development process.

  4. Stay in contact with the design team through this process and keep them up to date, so they can adapt their designs to your code, as well as the other way around.

  5. Implement Unit-Testing and Snapshot testing as soon as possible, to prevent the UI from breaking.

  6. If you don't want to open source it and keep it private, maybe think about implementing your own company npm registry, to house the packages there.

Final thoughts and next steps

As the library will never be 100% done, we have lots of things in the pipeline:

  • We will be implementing Snapshot Tests during the next project, to add another safety layer to the code.

  • We will add a library like storybooks to our UI-library to have a visual documentation.

  • We will grant of design team access to the repository, so they can fine-tune the components.

  • We will probably open-source it at one point.

If you have any more questions hit me up on Twitter. I would be happy to chat about anything React and JavaScript related.


Tag cloud