Skip to content
GitHub

Benefits

Bringing a type system to Tailwind was the overarching goal of this project. Let’s take a look at how you can benefit from type stability with tailwindest.

type TailwindClass = Tailwindest[keyof Tailwindest]

typescript’s recursive type computation allows you to write infinite Nested Break conditions.

const autocompleted = tw.style({
    after: {
        before: {
            file: {
                "first-letter": {
                    "first-line": {
                        marker: {
                            placeholder: {
                                selection: {
                                    active: {
                                        autofill: {
                                            backgroundColor:
                                                "after:before:file:first-letter:first-line:marker:placeholder:selection:active:autofill:bg-red-500", // <-- We can strictly type this value
                                        },
                                    },
                                },
                            },
                        },
                    },
                },
            },
        },
    },
})

Design an intuitive, primitive, familiar API is essential process. Final conclusion is going back to the most primitive form, as if we were writing down pure CSS. And this led to the conclusion that the CSS in JS form is the best fit.

const box = tw.style({
    display: "flex",
    flexDirection: "flex-row",
    alignItems: "items-center",
    justifyContent: "justify-center",
    gap: "gap-2",

    margin: "mx-2",
})

In pure tailwind, you should write nest conditions like this.

const smConditions =
    "sm:flex sm:items-center sm:justify-center sm:p-2 sm:m-2 sm:border sm:rounded-sm"

As you can see, the sm: expression is repeated. But in tailwindest, you can colocate nest conditions in one object.

const easyToRead = tw.style({
    sm: {
        display: "sm:flex",
        alignItems: "sm:items-center",
        justifyContent: "sm:justify-center",

        padding: "sm:p-2",
        margin: "sm:m-2",

        borderWidth: "sm:border",
        borderRadius: "sm:rounded-sm",
    },
})

tailwindest handles string. That means, we can reuse all the elements of function.

const box = tw.style({
    display: "flex",
    flexDirection: "flex-row",
    alignItems: "items-center",
    justifyContent: "justify-center",
    gap: "gap-2",
})
  1. classname: string

    get classname

    const boxClass = box.class()
    // flex flex-row items-center justify-center gap-2
  2. styleSheet: object

    extract styleSheet

    const boxStyle = box.style()
    /**
    {
        display: "flex",
        flexDirection: "flex-row",
        alignItems: "items-center",
        justifyContent: "justify-center",
        gap: "gap-2",
    }
    **/

classname and styleSheet are just string and object. So you can modifying it whatever you want.

Now, you are ready to dive in. Let’s get into it!