<p>Twin blends the magic of Tailwind with the flexibility of css-in-js </p> <p> Demo twin on CodeSandbox → </p> <p>Use Twin’s tw prop to add Tailwind classes onto jsx elements:<br /> import &#8220;twin.macro&#8221;; </p> <p>const Input = () = > ;<br /> Nest Twin’s tw import within a css prop to add conditional styles:<br /> import tw from &#8220;twin.macro&#8221;; </p> <p>const Input = ({ hasHover }) = > ( </p> <p>);<br /> Or mix sass styles with the css import:<br /> import tw, { css } from &#8220;twin.macro&#8221;; </p> <p>const hoverStyles = css`<br /> &#038;:hover {<br /> border-color: black;<br /> ${tw`text-black`}<br /> }<br /> `;<br /> const Input = ({ hasHover }) = > ( </p> <p>);<br /> Styled Components<br /> You can also use the tw import to create and style new components:<br /> import tw from &#8220;twin.macro&#8221;; </p> <p>const Input = tw.input`border hover:border-black`;<br /> And clone and style existing components:<br /> const PurpleInput = tw(Input)`border-purple-500`;<br /> Switch to the styled import to add conditional styling:<br /> import tw, { styled } from &#8220;twin.macro&#8221;; </p> <p>const Input = styled.input(({ hasHover }) = > [<br /> `color: purple;`,<br /> tw`border rounded`,<br /> hasHover &#038;&#038; tw`hover:border-black`,<br /> ]);<br /> const Component = () = > ;<br /> Or use backticks to mix with sass styles:<br /> import tw, { styled } from &#8220;twin.macro&#8221;; </p> <p>const Input = styled.input`<br /> color: purple;<br /> ${tw`border rounded`}<br /> ${({ hasHover }) = > hasHover &#038;&#038; tw`hover:border-black`}<br /> `;<br /> const Component = () = > ;<br /> How it works<br /> When babel runs over your code, Twin’s css and styled imports get swapped with the real imports from libraries like 💅 styled‑components and 👩‍🎤 emotion.<br /> Twin offers import presets for both libraries or you can fully customise the imports.<br /> When you use tw, Twin converts your classes into css objects, ready for passing to your chosen css-in-js library:<br /> import tw from &#8216;twin.macro&#8217; </p> <p>tw`text-sm md:text-lg` </p> <p>// ↓ ↓ ↓ ↓ ↓ ↓ </p> <p>{<br /> fontSize: &#8216;0.875rem&#8217;,<br /> &#8216;@media (min-width: 768px)&#8217;: {<br /> fontSize: &#8216;1.125rem&#8217;,<br /> },<br /> }<br /> Features<br /> 🎨 Style with all classes and variants available in Tailwind v2<br /> 🐹 Adds no size to your build &#8211; Twin converts classes you’ve used into css objects using Babel and then compiles away, leaving no runtime code<br /> 🛎 Helpful suggestions for mistypings &#8211; Twin chimes in with class and variant values from your Tailwind config:<br /> ✕ ml-7 was not found </p> <p>Try one of these classes:<br /> 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]<br /> ml-8 [2rem] / ml-10 [2.5rem] / ml-12 [3rem] / ml-16 [4rem] / ml-20 [5rem] / ml-24 [6rem] / ml-32 [8rem]<br /> ml-40 [10rem] / ml-48 [12rem] / ml-56 [14rem] / ml-64 [16rem] / ml-auto [auto] / ml-px [1px]<br /> 🖌️ Use the theme import to add values from your tailwind config<br /> import { theme, css } from &#8220;twin.macro&#8221;; </p> <p>const Input = () = > ;<br /> See more examples using the theme import →<br /> 💥 Add important to any class with a trailing bang!<br /> tw`hidden!`<br /> // ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓<br /> { &#8220;display&#8221;: &#8220;none !important&#8221; }<br /> 🚥 Over 40 variants to prefix on your classes &#8211; Unlike Tailwind, the prefixes are always available to add to your classes </p> <p>Prefix with before: and after: to style pseudo-elements<br /> Prefix with hocus: to style hover + focus at the same time<br /> Style with extra group states like group-hocus: and group-active:<br /> Style form field states with checked:, invalid: and required:<br /> Stack up variants whenever you need them sm:hover:first:bg-black </p> <p>Check out the full list of variants →<br /> 🍱 Apply variants to multiple classes at once with variant groups<br /> import &#8216;twin.macro&#8217; </p> <p>const interactionStyles = () = > ( </p> <p>) </p> <p>const mediaStyles = () = > </p> <p>const pseudoElementStyles = () = > ( </p> <p>) </p> <p>const stackedVariants = () = > </p> <p>const variantsInGroups = () = ><br /> Get started<br /> Take a look at these examples to get started:<br /> React<br /> 💅 styled-components   👩‍🎤 emotion<br /> Preact<br /> 💅 styled-components   🥜 goober<br /> Create React App<br /> 💅 styled-components   👩‍🎤 emotion<br /> Gatsby<br /> 💅 styled-components   👩‍🎤 emotion<br /> Next.js<br /> 💅 styled-components   👩‍🎤 emotion<br /> Snowpack<br /> 💅 styled-components   💅 styled-components (TypeScript)   👩‍🎤 emotion<br /> Storybook<br /> 👩‍🎤 emotion<br /> Monorepo component library<br /> 💅 styled-components (TypeScript)<br /> Laravel<br /> 💅 styled-components (TypeScript)<br /> Vue<br /> 👩‍🎤 emotion (Experimental)<br /> Plugins<br /> 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 &#8211; those features are coming soon.<br /> See list of supported plugins →<br /> TypeScript<br /> Twin fully supports TypeScript projects and includes types for every import except the css and styled imports.<br /> How to add the missing css and styled types →<br /> Community<br /> Drop into our Discord server for announcements, help and styling chat. </p> <p>Resources </p> <p>Special thanks<br /> 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.<br /> Let&#8217;s block ads! (Why?)</p>

Breakdown

Twin blends the magic of Tailwind with the flexibility of css-in-js

Read full post on github.com