Composing complex components

Code generation with Figmagic 4 will only take you so far. For our most important and complicated components, we will need to do some manual work, composing small bits into more advanced ones. Let's compose one from what we've made so far!

We've made quite some headway this far. By now, it's fairly easy to start seeing how we can make something bigger and more involved from smaller parts. In the nomenclature of "atomic design," what we have made so far corresponds to:

  • The "atoms," being the design tokens, and I'd argue, any styles in Figma; though Brad Frost, the creator of atomic design, would say this related to foundational HTML tags et al

  • The "molecules" that combine several atoms into a cohesive entity like an input element with a label

  • The "organisms" that collect several molecules into complex entities, of which there typically are quite few

From the general outlines of the UX sketch to the high fidelity prototype, we can now see that our Product Card is using elements that we can deconstruct and make universal and then reassemble to form the Product Card. I'm seeing that we have:

  • A Card (the background or layout itself)

  • A Heading

  • A Description

  • An Image

First, we need to wrap up work on them so that they are correctly generated into code. After that, we can proceed to use them in a new component that we need to set up in Storybook and React (manually).

Verify config#

For the following part, because we are starting to populate our component library, make sure you have your component library codebase open in your editor.

Verify that your configuration can generate elements. Your figmagic.json should look like the below:

The most important thing we do here is configure Figmagic not to automatically ("force") update all files when we get new data, so it does not overwrite changes we do to the React, Storybook, or Styled Components files.

Separate compound components from simple (generated) elements

To improve our application architecture and improve discoverability, we'll separate elements that Figmagic generates for us from the bigger "compound" components that stitch them together. Those compound components require more manual work, and as we've said previously, relate more closely to Brad Frost's atomic design convention of "molecules," while the elements can be called our "atoms."

As a consequence, src/components is the manual bigger ones, and src/elements will be mostly automated ones.

Having done that, run npx figmagic to pull new data with Figmagic and see what happens in Storybook!

Update elements#

Making sure our elements are output as the intended tags#

Start Figma and go to the Elements page.

First things first. We want to make sure all of the Product Card elements are output as the intended tags. Click the Image component. On the right side, you should see a Documentation box. Enter element=img.

Take a moment to add element=h2 to the Heading and element=p to the documentation while you are at it. Else, they will become div elements, and we don't want that. That, however, is just fine for the Card, so leave that one alone for now.

Adjusting element tag generation

Next, we are going to do some coding for our basic elements now, starting with the Image.

Update the Image code#

Open up src/elements/Image/ImageStyled.js.

If we'd look at Storybook now, we would see that our Image, unfortunately, retains the sharp edges and nullifies the corner radius of the outer Card element. Therefore, we need to add those manually to the top corners of the image.

For later, we'll also be adding the possibility to set a fixed height and to force hard corners.

And replace the function in Image/Image.js so its props can take an image:

Here we are also passing in the height and hardCorners props, which we need later.

We should add those to our Storybook file (src/elements/Image/Image.stories.mdx) as well, replacing the Canvas block:

Now we're talking!

Updating the Card code#

Let's restrict the card from being too wide. Update and add the following to elements/Card/CardStyled.js:

Start a new discussion. All notification go to the author.