I was recently tasked with building a user-card
component for the bit.cloud platform. I was also tasked with building the
employee-card component along with it.
Before we begin, let's see how easy it is to extend the
user-card component by plugging in independent
components. Go ahead and drag teambit.people/ui/u[email protected] and
teambit.people/ui/[email protected] into teambit.people/[email protected] component. Watch out
for my head! (notice what happens to its name once you drag them all):
In this post, we will learn how to construct composable UIs.
A beginning of a card story ❤
As you have already seen in the intro, the employee card consumes the user card and extends its
abilities. We have the employee info on the right and the social links at the bottom of the card.
How would you compose them together?
If you are used to working with monoliths, your first thought might have been to
create all of these components (user card, employee card, social links) in the src folder, and then
compose them together.
That is doable but not scalable. If we couple these components together, our ability to create new compositions in the future will be limited.
What happens if you want to add memory to your computer? You plug out the old memory card and
plug in a better one with a larger memory capacity. At Bit, we believe software
components should behave the same. Let's see how we solve this task using independent components
created with Bit.
We have decided that we want to be able to extend our card from the bottom and the right side of it.
CSS-wise, it will be easy to achieve. We will define our card container as a flexbox. The first
default div that will enter this container will be our user card. Every div that will enter
after it will be on its right as this is the default behavior of CSS flexbox.
We figured out how to extend it from the right, but what about the bottom? By defining the user-card
div as a flexbox with a flex-direction of a column, we will get precisely the behavior we want.
Every div we insert inside the user card div will take its position right below the existing
One last CSS tip. We will give our user-card a width of 50% so that when we inject the plugin on the
right, they both take an equal amount of space. But we will also add the pseudo-class :only-child
to give it 100% width when we don't render any plugins.
Please make sure that the Bit binary is installed on your machine:
npx @teambit/bvm install
Go ahead and fork the user-card component to your local
Workspace. It will be easier to follow the code
bit fork teambit.people/user-card
Planning the extendable card API
Let's plan the user card API.
Here is the API for the user-card:
* The username to fetch the user profile from the cloud API.
* */ username:string;/**
* Plugins to be injected to the bottom and right side of the card.
* */ plugins?: UserCardPlugin<unknown,unknown>;}& React.HTMLAttributes<HTMLDivElement>;
The plugins array will contain objects that store a component either on the right or the bottom key.
Let's say that later on, another task was open: create a developer card. The developer card structure is similar to the employee card, but instead of employee info, it has developer
information on the right and 'frameworks/programming languages' at the bottom.
So how would we compose the developer card?
We could create a plugin for the developers' information and the frameworks/programming languages.
We would then inject them into the plugins array, and there you go - a developer card!
The place where this really shines is when it comes to collaboration. You can have a team of
developers working on plugins, and you can share them throughout your projects. This is true
autonomy. Each plugin is independently versioned and has its own release pipeline. If a new version
of a plugin is released, each team using it can decide whether they want to update the plugins'
version or not.
P.S. If you were wondering, I don't live in San Francisco.