DEV Community

Krzysztof Żuraw
Krzysztof Żuraw

Posted on • Originally published at krzysztofzuraw.com on

Polymorphic react component with vanilla-extract

I started using vanilla-extract library as foundation to design system at work. All is going well, but I have one problem - I couldn't find a good way to create polymorphic React components. I tried with React TypeScript Cheatsheet, but it didn't work for me. I was looking for a solution for a while and I was recommended (thanks Jonatan) to check out this handy little library called dessert-box. What this library is doing? It uses a concept of vanilla-extract sprinkles and connect them together with polymorphic Box component.

Let's say you have this sprinkles defined:

import { createSprinkles, defineProperties } from "@vanilla-extract/sprinkles";

const colorProperties = defineProperties({
  conditions: {
    lightMode: {},
    darkMode: { "@media": "(prefers-color-scheme: dark)" },
  },
  defaultCondition: "lightMode",
  properties: {
    color: [{ brand: "#00a98f" }],
  },
});

export const sprinkles = createSprinkles(colorProperties);
Enter fullscreen mode Exit fullscreen mode

Now you want to pass those as atoms to your Box component. You can do it like this:

import { createBox } from "@dessert-box/react";

import { sprinkles } from "./sprinkles.css";

export const Box = createBox({ atoms: sprinkles });
Enter fullscreen mode Exit fullscreen mode

Now you can use it like this:

<Box as="button" color="brand">
  Submit
</Box>
Enter fullscreen mode Exit fullscreen mode

And it is all type-safe. You can't pass different color than brand to the Box. Now you can build your own components on top of it and combine them into more complex molecules. It really helps to write as little custom CSS as possible and instead use typed props to style your components.

Top comments (0)