React
Configuring classed

Configuring classed

Classed can be configured using the createClassed method.

The createClassed method takes a single argument, which is an object with the following properties:

interface ClassedConfig {
  merger: (...classes: string[]) => string;
}

The merger property is a function that takes a variable number of strings and returns a single string. This function is used to merge the class names together.

Using a custom merger

Removing duplicates is not default behaviour. To enable it, you can pass a custom merger to the createClassed method.

// classed.config.ts
import { createClassed } from "@tw-classed/react";
 
// custom merger that removes duplicates using Set
const customMerger = (...classes: string[]) =>
  Array.from(new Set(classes)).join(" ");
 
export const { classed } = createClassed({ merger: customMerger });

Using Tailwind merge

Tailwind merge is a 3rd party merger that removes duplicates and intelligently merges Tailwind classes by order of importance. This is especially useful when using the Variants API to override classes.

// classed.config.ts
import { twMerge } from "tailwind-merge";
 
import { createClassed } from "@tw-classed/react";
 
export const { classed } = createClassed({ merger: twMerge });

In your components

// Button.tsx
import { classed } from "classed.config";
 
const Button = classed.button({
  base: "py-2 px-4 rounded-md",
  variants: {
    color: {
      primary: "bg-blue-500 text-white",
      secondary: "bg-gray-500 text-white",
    },
 
    // If applied will override the base class, but may or may not be applied depending on the order of the classes that tailwind generates
    size: {
      small: "text-sm py-1 px-2",
      large: "text-lg py-3 px-5",
    },
  },
 
  defaultVariants: {
    color: "primary",
  },
});
 
() => <Button color="secondary" size="large" />;

What happens here?

The Button component will be rendered with the following classes:

<button class="bg-blue-500 text-white text-lg py-3 px-5 rounded-md"></button>

This happens because of tailwind-merge, which intelligently merges the classes by order of importance. In this case, the size variant is applied after the base classes, so the size variant will override the py-2 px-4 base classes.

Without the tailwind-merge merger, the Button component would be rendered with the following classes:

<button
  class="bg-blue-500 text-white py-2 px-4 text-lg py-3 px-5 rounded-md"
></button>

We dont know which classes will be applied first, so we can't be sure that the size variant will override the base classes.