Skip to content
GitHub

Utility

mergeProps can be used when you want to apply a specific tailwind property to a style.

api reference, mergeProps

api reference, compose

import { tw } from "@/tw"
import type { Tailwindest } from "@/tw"

const box = tw.style({
    // ... Box styles
})

interface BoxProps {
    children: React.ReactNode
    borderColor?: Tailwindest["borderColor"] // Customizable borderColor
}
export const Box = ({ children, borderColor }: BoxProps) => {
    return (
        <div
            className={tw.mergeProps(box.style(), {
                borderColor,
            })}
        >
            {children}
        </div>
    )
}
interface UniversalTextProps {
    children: React.ReactNode
    tw?: Tailwindest
}
const UniversalText = ({ children, tw: twStyle }: UniversalTextProps) => (
    <p
        className={tw.mergeProps(
            text.style(),
            twStyle //   override new styleSheet
        )}
    >
        {children}
    </p>
)

Now UniversalText is fully customizable via tw props.

const Some = (
    <UniversalText
        tw={{
            fontFamily: "font-mono",
            // other styles...
        }}
    >
        It is UniversalText
    </UniversalText>
)

In this way, you don’t have to install classname merging packages like tailwind-merge.


For example, let’s say you’ve created a common container component called Box. What you want to do is dynamically change only the borderColor property of the box, while maintaining the unique style you’ve defined for the Box. So you create a borderColor props for Box component and add the desired color, and it’s applied.

import { tw } from "~/tw"
import type { Tailwindest } from "~/tw"

const box = tw.style({
    display: "flex",
    alignItems: "items-center",
    borderWidth: "border",
    borderColor: "border-blue-300",
    // more box styles here...
})

interface BoxProps {
    children: React.ReactNode
    borderColor?: Tailwindest["borderColor"]
}
export const Box = ({ children, borderColor }: BoxProps) => {
    // ass borderColor as props
    return <div className={`${box.class()} ${borderColor}`}>{children}</div>
}

Now you’re thinking, “I can perfectly apply any borderColor with types.”. In most cases, you’ll see that it works perfectly, but in some cases, it doesn’t.

// border color is red-300
const Works = () => <Box borderColor="border-red-300">love</Box>

// border color is not gray-100
const NotWorks = () => <Box borderColor="border-gray-100">love</Box>

This happens because the order of border-color property in the css file generated by tailwind doesn’t work as you wrote it down: in the className of the Box, borderColor is obviously last, but in the generated css, it’s not last. The order of the css is generated in the order predefined by the tailwind framework, so it doesn’t work as expected.

/* ... */

.border-gray-100 {
    border-color: "~100";
}

/* ... */

.border-blue-300 {
    border-color: "~300";
}

/* ... */

.border-red-300 {
    border-color: "~300";
}

/* ... */