Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import { forwardRef } from "react"
- function combine(...classNames: string[]) {
- return classNames.filter((className) => !!className).join(" ")
- }
- type TagName = keyof JSX.IntrinsicElements
- type NormalFn<T extends TagName> = (...classNames: string[]) => GetTheirRefType<T>
- type TemplateFn<T extends TagName> = (
- strings: TemplateStringsArray,
- ...values: string[]
- ) => GetTheirRefType<T>
- type GetTheirRefType<T extends TagName> = JSX.IntrinsicElements[T] extends React.DetailedHTMLProps<infer X, infer Y> ? Y : never
- type TailwindFn = {
- [tagName in TagName]: NormalFn<tagName>
- }
- type TailwindTemplate = {
- [tagName in TagName]: TemplateFn<tagName>
- }
- export const tailwind_fn = new Proxy(
- {},
- {
- get<T extends TagName>(target: any, tagName: T) {
- const Element = tagName as any // FIXME: will have a type error if it's not any (probably an edge case with a specific tag name)
- return (...classNames: string[]) =>
- forwardRef<GetTheirRefType<T>, JSX.IntrinsicElements[T]>(
- ({ className = "", ...props }, ref) => (
- <Element className={combine(className, ...classNames)} {...props} ref={ref} />
- )
- )
- },
- }
- ) as TailwindFn
- export const tailwind = new Proxy(
- {},
- {
- get<T extends TagName>(target: any, tagName: T) {
- return (literals: TemplateStringsArray, ...placeholders: string[]) =>
- tailwind_fn[tagName](...literals, ...placeholders)
- },
- }
- ) as TailwindTemplate
- /* How to use:
- * const Button = tailwind.button`px-2 py-1 m-5 bg-green-500 rounded-md`
- * const Button2 = tailwind_fn.button("px-2 py-1 m-5", "bg-green-500", "rounded-md") // <- insert variables with class names
- */
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement