typesafe, reusable tailwind
``bash`
npx create-tailwind-type -A # disable arbitrary values
`bash`
npm i tailwindest@latest
`ts
import {
createTools,
type CreateTailwindest,
type CreateTailwindLiteral,
} from "tailwindest"
import type { Tailwind, TailwindNestGroups } from "./tailwind"
import { twMerge } from "tailwind-merge"
export type Tailwindest = CreateTailwindest<{
tailwind: Tailwind
tailwindNestGroups: TailwindNestGroups
groupPrefix: "$" // prefix for nest groups, [optional]
useArbitrary: true // enable arbitrary values, [optional]
}>
export type TailwindLiteral = CreateTailwindLiteral
export const tw = createTools<{
tailwindest: Tailwindest
tailwindLiteral: TailwindLiteral
useArbitrary: true // enable arbitrary values, [optional]
}>({
merger: twMerge, // set tailwind-merge as merger, [optional]
})
`
#### Def - tw.def(classList, ...styleList)
`tsx
const condition: boolean = true
const container = tw.def(
// 🚀 Powered by clsx
[
// ✅ Statically typed literals
"flex",
"size-fit",
"flex-col",
"items-center",
"justify-center",
"gap-y-12",
// ✅ Arbitrary strings
"md:flex-row md:gap-x-7",
"lg:gap-x-24",
// ✅ Conditional styling
condition ? "p-3" : "p-1",
// ✅ Array-based styling
["dark:text-white", "text-black"],
],
// 🚀 Default merging behavior
{
// ✅ Record-based styling
backgroundColor: "bg-white",
dark: {
backgroundColor: "dark:bg-black",
},
},
{
// ✅ Support for infinite record styling
// Additional styles here...
}
)
const Box = ({ children }) =>
#### Style -
tw.style(stylesheet)`tsx
const box = tw.style({
display: "flex",
alignItems: "items-center",
justifyContent: "justify-center",
padding: ["px-[2.25px]", "py-1"],
$hover: {
opacity: "hover:opacity-90",
},
$sm: {
padding: ["sm:px-[4.5px]", "sm:py-2"],
},
})const Box = ({ children }) => {
return
{children}
}const Box2 = ({ children }) => {
// pass arbitrary classnames
return
{children}
}
`#### Toggle -
tw.toggle({ truthy, falsy, base })If you want to change the style based on a single
boolean condition, use toggle.`tsx
const themeBtn = tw.toggle({
truthy: {}, // › light mode
falsy: {}, // › dark mode
base: {}, // [optional] base style
})const ThemeBtn = ({ children }) => {
const [isLight, setIsLight] = useState(false)
return
}
`#### Rotary -
tw.rotary({ variants, base })If you need to change styles based on three or more conditions within a single category, use
rotary.`tsx
import { type GetVariants } from "tailwindest"const btn = tw.rotary({
variants: {
success: {}, // › success
warning: {}, // › warning
error: {}, // › error
},
base: {}, // [optional] base style
})
interface BtnProps {
onClick: () => void
children: ReactNode
type?: GetVariants
}
const Btn = ({ onClick, children, type = "default" }: BtnProps) => (
)
`#### Variants -
tw.variants({ variants, base })`tsx
const btn = tw.variants({
variants: {
type: {
default: {}, // › type.default
success: {}, // › type.success
warning: {}, // › type.warning
},
size: {
sm: {}, // › size.sm
md: {}, // › size.md
lg: {}, // › size.lg
},
border: {
sm: {}, // › border.sm
md: {}, // › border.md
lg: {}, // › border.lg
},
},
base: {}, // [optional] base style
})interface BtnProps extends GetVariants {
onClick: () => void
children: ReactNode
}
const Btn = ({
children,
size = "md",
border = "md",
type = "default",
onClick,
}: BtnProps) => (
)
``