0.1.0 • Published 4 years ago

@xwind/macro v0.1.0

Weekly downloads
-
License
MIT
Repository
-
Last release
4 years ago

@xwind/macro

NPM version License Babel Macro

@xwind/macro is a babel macro that transforms Tailwind classes into CSS object styles. These CSS object styles can be used with your favorite CSS-in-JS library like emotion, styled-components ...

Basic example

import tw from "@xwind/macro";

const styles = tw`text-red-100 hover:text-green-100 hover:bg-blue-200`;
// OR (with custom array syntax)
const styles = tw`text-red-100 hover[text-green-100 bg-blue-200]`;

Transforms by default into Postcss-js / JSS compatible syntax:

const styles = {
  "--text-opacity": "1",
  color: ["#fde8e8", "rgba(253, 232, 232, var(--text-opacity))"],
  "&:hover": {
    "--text-opacity": "1",
    "--bg-opacity": "1",
    color: ["#def7ec", "rgba(222, 247, 236, var(--text-opacity))"],
    backgroundColor: ["#c3ddfd", "rgba(195, 221, 253, var(--bg-opacity))"],
  },
};

Transform to CSS string syntax with the CSS string plugin:

const styles = `
  --text-opacity: 1;
  color: #fde8e8;
  color: rgba(253, 232, 232, var(--text-opacity));
  &:hover {
    --text-opacity: 1;
    --bg-opacity: 1;
    color: #def7ec;
    color: rgba(222, 247, 236, var(--text-opacity));
    background-color: #c3ddfd;
    background-color: rgba(195, 221, 253, var(--bg-opacity));
  }
`;

Plugins make it possible to support any CSS-in-JS library syntax.

Install

0. Prerequisites:

1. Install packages

# with npm
npm install --save-dev @xwind/macro tailwindcss

# with Yarn
yarn add -D @xwind/macro tailwindcss

2. Add Tailwind base css

import "tailwindcss/dist/base.min.css";

If you use Tailwind plugins that register new base styles you will need to generate a customized base CSS file.

2.1 Create a tailwind.base.css file

/* tailwind.base.css */
@tailwind base;

2.2 Using Tailwind CLI

# Use the `npx tailwindcss help build` command to learn more about the various CLI options.
npx tailwindcss build tailwind.base.css -o base.css

Tip: add this command to your package.json scripts section

2.3 Import base.css

import "base.css";

3. Create a Tailwind config file (optional)

npx tailwindcss init

Check out the Tailwind documentation for customizing the Tailwind config file.

3.1 Add Tailwind plugins to support all Tailwind features (keyframes, darkmode)

//tailwind.config.js
module.exports = {
  // ... config options
  plugins: [
    //Add @keyframes to the base/preflight css file
    plugin(function ({ addBase, addUtilities, e, theme, variants }) {
      const keyframesConfig = theme('keyframes')
      const keyframesStyles = Object.fromEntries(
        Object.entries(keyframesConfig).map(([name, keyframes]) => {
          return [`@keyframes ${name}`, keyframes]
        })
      )
      addBase(keyframesStyles)
    }),
    //Add !important to css rule with variant: important:bg-red-400
    plugin(function ({ addVariant, addUtilities, addComponents, e, prefix, config }) {
      addVariant("important", ({ container }) => {
        container.walkRules((rule) => {
          rule.selector = `.important\\${config("separator")}${rule.selector.slice(1)}`
          rule.walkDecls((decl) => {
            decl.important = true;
          });
        });
      });
    }),
    //Adds tailwindcss official dark mode plugin for tailwind versions 1.X
    require("tailwindcss/lib/flagged/darkModeVariantPlugin").default
  ]

Customization

Babel macro configuration

// package.json
"babelMacros": {
    "xwind": {
      "config": "./tailwind.config.js",  //Path to 'tailwind.config.js'
      "developmentMode": true //Enable reacting to tailwind.config.js changes
    }
},
// babel-plugin-macros.config.js
module.exports = {
  xwind: {
    config: "./tailwind.config.js", //Path to 'tailwind.config.js'
    developmentMode: true, //Enable reacting to tailwind.config.js changes
  },
};

xwind plugins (experimental)

To support the different CSS-in-JS syntaxes we need a way to change the macro's default output this can be done with xwind plugins.

note: this is still experimental breaking changes are possible

xwind plugins are added in the tailwind.config.js file

// tailwind.config.js

module.exports = {
  theme: {},
  variants: {},
  plugins: [],

  //this is added
  xwind: {
    plugins: [
      /* your plugins */
    ],
  },
};

xwind plugin list

CSS string

// tailwind.config.js
module.exports = {
  xwind: {
    plugins: [require("@xwind/macro/lib/plugins/cssString").default];
  }
};

Default

const styles = {
  "--text-opacity": "1",
  color: ["#fde8e8", "rgba(253, 232, 232, var(--text-opacity))"],
  "&:hover": {
    "--text-opacity": "1",
    "--bg-opacity": "1",
    color: ["#def7ec", "rgba(222, 247, 236, var(--text-opacity))"],
    backgroundColor: ["#c3ddfd", "rgba(195, 221, 253, var(--bg-opacity))"],
  },
};

With CSS string plugin

const styles = `
  --text-opacity: 1;
  color: #fde8e8;
  color: rgba(253, 232, 232, var(--text-opacity));
  &:hover {
    --text-opacity: 1;
    --bg-opacity: 1;
    color: #def7ec;
    color: rgba(222, 247, 236, var(--text-opacity));
    background-color: #c3ddfd;
    background-color: rgba(195, 221, 253, var(--bg-opacity));
  }
`;

Remove fallbacks

// tailwind.config.js
module.exports = {
  xwind: {
    plugins: [require("@xwind/macro/lib/plugins/removeFallbacks").default];
  }
};
const styles = {
  "--text-opacity": "1",
  color: ["#fde8e8", "rgba(253, 232, 232, var(--text-opacity))"],
  "&:hover": {
    "--text-opacity": "1",
    "--bg-opacity": "1",
    color: ["#def7ec", "rgba(222, 247, 236, var(--text-opacity))"],
    backgroundColor: ["#c3ddfd", "rgba(195, 221, 253, var(--bg-opacity))"],
  },
};

With remove fallbacks plugin

const styles = {
  "--text-opacity": "1",
  color: "rgba(253, 232, 232, var(--text-opacity))",
  "&:hover": {
    "--text-opacity": "1",
    "--bg-opacity": "1",
    color: "rgba(222, 247, 236, var(--text-opacity))",
    backgroundColor: "rgba(195, 221, 253, var(--bg-opacity))",
  },
};

Advanced Examples

Codesandbox with Typescript, Nextjs and Emotion

Official Next.js example - Tailwind CSS with Emotion.js

License

MIT. Copyright (c) 2020 Arthur Petrie.