ben-rogerson / twin.macro
- понедельник, 30 ноября 2020 г. в 00:24:23
JavaScript
🦹♂️ Twin blends the magic of Tailwind with the flexibility of css-in-js (emotion, styled-components and goober) at build time.
Twin blends the magic of Tailwind with the flexibility of css-in-js
Use Twin’s tw
prop to add Tailwind classes onto jsx elements:
import 'twin.macro'
const Input = () => <input tw="border hover:border-black" />
Nest Twin’s tw
import within a css prop to add conditional styles:
import tw from 'twin.macro'
const Input = ({ hasHover }) => (
<input css={[tw`border`, hasHover && tw`hover:border-black`]} />
)
Or mix sass styles with the css import:
import tw, { css } from 'twin.macro'
const hoverStyles = css`
&:hover {
border-color: black;
${tw`text-black`}
}
`
const Input = ({ hasHover }) => (
<input css={[tw`border`, hasHover && hoverStyles]} />
)
You can also use the tw import to create and style new components:
import tw from 'twin.macro'
const Input = tw.input`border hover:border-black`
And clone and style existing components:
const PurpleInput = tw(Input)`border-purple-500`
Switch to the styled import to add conditional styling:
import tw, { styled } from 'twin.macro'
const Input = styled.input(({ hasHover }) => [
`color: purple;`,
tw`border rounded`,
hasHover && tw`hover:border-black`,
])
const Component = () => <Input hasHover />
Or use backticks to mix with sass styles:
import tw, { styled } from 'twin.macro'
const Input = styled.input`
color: purple;
${tw`border rounded`}
${({ hasHover }) => hasHover && tw`hover:border-black`}
`
const Component = () => <Input hasHover />
When babel runs over your code, Twin’s css
and styled
imports get swapped with the real imports from libraries like
Twin offers import presets for both libraries or you can fully customise the imports.
When you use tw
, Twin converts your classes into css objects, ready for passing to your chosen css-in-js library:
import tw from 'twin.macro'
tw`text-sm md:text-lg`
// ↓ ↓ ↓ ↓ ↓ ↓
{
fontSize: '0.875rem',
'@media (min-width: 768px)': {
fontSize: '1.125rem',
},
}
✕ ml-7 was not found
Try one of these classes:
ml-0 [0] / ml-1 [0.25rem] / ml-2 [0.5rem] / ml-3 [0.75rem] / ml-4 [1rem] / ml-5 [1.25rem] / ml-6 [1.5rem]
ml-8 [2rem] / ml-10 [2.5rem] / ml-12 [3rem] / ml-16 [4rem] / ml-20 [5rem] / ml-24 [6rem] / ml-32 [8rem]
ml-40 [10rem] / ml-48 [12rem] / ml-56 [14rem] / ml-64 [16rem] / ml-auto [auto] / ml-px [1px]
import { theme, css } from 'twin.macro'
const Input = () => <input css={css({ color: theme`colors.purple.500` })} />
See more examples using the theme import →
tw`hidden!`
// ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓
{ "display": "none !important" }
before:
and after:
to style pseudo-elementshocus:
to style hover + focus at the same timegroup-hocus:
and group-active:
checked:
, invalid:
and required:
sm:hover:first:bg-black
Check out the full list of variants →
import 'twin.macro'
const interactionStyles = () => (
<div tw="hover:(text-black underline) focus:(text-blue-500 underline)" />
)
const mediaStyles = () => <div tw="sm:(w-4 mt-3) lg:(w-8 mt-6)" />
const pseudoElementStyles = () => (
<div tw="before:(content block w-10 h-10 bg-black)" />
)
const stackedVariants = () => <div tw="sm:hover:(bg-black text-white)" />
const variantsInGroups = () => <div tw="sm:(bg-black hover:bg-white)">
Take a look at these examples to get started:
You can use many Tailwind plugins with twin, like Tailwind UI and Custom forms but there’s no compatibility with other plugins that use the addVariant
or addBase
functions - those features are coming soon.
See list of supported plugins →
Twin fully supports TypeScript projects and includes types for every import except the css
and styled
imports.
How to add the missing css
and styled
types →
Drop into our Discord server for announcements, help and styling chat.
This project stemmed from babel-plugin-tailwind-components so a big shout out goes to Brad Cornes for the amazing work he produced. Styling with tailwind.macro has been such a pleasure.