A lighter version of twin.macro that allows you to create tailwind react components like styled-components

Tw-Tailwind

A lighter version of twin.macro that allows you to create tailwind react components like styled-components

Install

Using npm

npm i tw-tailwind

Using yarn

yarn add tw-tailwind

Usage

Import

import tw from 'tw-tailwind'

Features

const sharedClasses = tw`border-red-500`

const Component = tw.div`flex items-center justify-center`

const Component = tw(Button)`flex items-center justify-center`

const Component = tw.div<{ $hasBorder: boolean }>`
  bg-red-500 
  ${({ $hasBorder }) => $hasBorder && 'border-2 border-blue-500'}`

const Component = tw(Button)<{ $hasBorder: boolean }>`
  bg-red-500 
  ${({ $hasBorder }) => $hasBorder && 'border-2 border-blue-500'}`

const Component = tw.div(() => ['bg-red-500'])

const Component = tw(Button)(() => ['bg-red-500'])

const Component = tw.div<{ $hasBorder: boolean }>(({ $hasBorder }) => [
  'bg-red-500',
  $hasBorder && 'border-2 border-blue-500',
])

const Component = tw(Button)<{ $hasBorder: boolean }>`
  bg-red-500 
  ${({ $hasBorder }) => $hasBorder && 'border-2 border-blue-500'}`

Example

Button

import tw from 'tw-tailwind'

const colors = {
  white: tw`bg-white hover:bg-gray-100 text-black`,
  gray: tw`bg-gray-100 hover:bg-gray-200 text-black`,
  emerald: tw`bg-emerald-600 hover:bg-emerald-700 text-white`,
}
const loadingColors: typeof colors = {
  white: tw`text-white`,
  gray: tw`text-gray-100`,
  emerald: tw`text-emerald-600`,
}

type ButtonProps = Omit<JSX.IntrinsicElements['button'], 'ref'> & {
  color?: keyof typeof colors
  isLoading?: boolean
}

export const Button = ({ children, className, type = 'button', color = 'emerald', isLoading, ...props }: ButtonProps) => (
  <ButtonStyled type={type} {...props} $color={color} $isLoading={isLoading} className={className}>
    {children}
  </ButtonStyled>
)

const ButtonStyled = tw.button<{ $color: keyof typeof colors; $isLoading?: boolean }>(({ $isLoading, $color }) => [
  `disabled:opacity-30 disabled:pointer-events-none text-white font-medium rounded-md px-4 h-10 flex items-center relative select-none`,
  colors[$color],
  $isLoading && ['pointer-events-none', loadingColors[$color]],
])

Input

import { forwardRef, ReactNode } from 'react'
import tw from 'tw-tailwind'
import { Label } from './label'
import clsx from 'clsx'

const colors = { white: tw`bg-white `, gray: tw`bg-gray-200` }

type InputProps = Omit<JSX.IntrinsicElements['input'], 'ref'> & {
  label?: string
  icon?: ReactNode
  className?: string
  color?: keyof typeof colors
}
export const Input = forwardRef<HTMLInputElement, InputProps>(
  ({ label, className, icon, color = 'white', ...props }, ref) => (
    <Container className={className}>
      {label && <Label>{label}</Label>}
      <Wrapper>
        <InputStyled className={clsx([colors[color], !!icon && `pl-10 `])} {...props} ref={ref} />
        <IconWrapper>{icon}</IconWrapper>
      </Wrapper>
    </Container>
  ),
)

Input.displayName = 'Input'

const InputStyled = tw.input`bg-white rounded-md px-3 shadow-sm h-10 flex border border-gray-300 items-center w-full pb-px`
const Container = tw.div`text-sm w-full`
const Wrapper = tw.div`relative`
const IconWrapper = tw.div`absolute text-xl h-10 px-3 flex justify-center items-center top-0 left-0`

VS Code setup – extension

Install Tailwind CSS IntelliSense VSCode extension

https://marketplace.visualstudio.com/items?itemName=bradlc.vscode-tailwindcss

  "scss.validate": false,
  "editor.quickSuggestions": {
    "strings": true
  },
  "editor.autoClosingQuotes": "always",
  "tailwindCSS.experimental.classRegex": [
    "tw`([^`]*)", // tw`...`
    "tw\\.[^`]+`([^`]*)", // tw.xxx`...`
    "tw\\(.*?\\).*?`([^`]*)", // tw(Component)`...`
    ["tw\\.[^\\)]+\\(.*=>([^)]*)\\)", "(?:'|\"|`)([^']*)(?:'|\"|`)"], // tw.xxx(()=> ['...'])
    ["tw\\(.*?\\)\\(.*=>([^)]*)\\)", "(?:'|\"|`)([^']*)(?:'|\"|`)"], // tw(Component)(()=> ['...'])
    ["tw\\(.*?\\).*?\\(.*=>([^)]*)\\)", "(?:'|\"|`)([^']*)(?:'|\"|`)"], // tw(Component)<...>(()=> ['...'])
    ["clsx\\(([^)]*)\\)", "(?:'|\"|`)([^']*)(?:'|\"|`)"] // clsx( ['...'])
  ],

  "tailwindCSS.includeLanguages": {
    "typescript": "javascript",
    "typescriptreact": "javascript"
  },

GitHub

View Github