xwind
TypeScript icon, indicating that this package has built-in type declarations

0.8.0 • Public • Published

xwind

NPM version License Babel Macro

xwind uses a babel plugin that transforms Tailwind classes into CSS object styles or a classes string. The CSS object styles output can be used with your favorite CSS-in-JS library like emotion, styled-components ... The classes string output can be used with the xwind cli to generate a minimal css file of the used Tailwind classes.

Table of Contents

Basic examples

Output mode "objectstyles" example

import xw from "xwind";
//OR
import xw from "xwind/macro";

const styles = xw`text-red-100 hover:text-green-100 hover:bg-blue-200`;
// OR (with custom array syntax)
const styles = xw`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 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));
  }
`;

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

Output mode "classes" example

import xw from "xwind";
//OR
import xw from "xwind/macro";

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

Transforms into a classes string:

const styles = "text-red-100 hover:text-green-100 hover:bg-blue-200";

Generate the css output with with the xwind cli:

npx run xwind

Output file "/src/styles/xwind.css":

/*! Generated with xwind | https://github.com/arthie/xwind */
.hover\:bg-blue-200:hover {
  --tw-bg-opacity: 1;
  background-color: rgba(191, 219, 254, var(--tw-bg-opacity));
}
.text-red-100 {
  --tw-text-opacity: 1;
  color: rgba(254, 226, 226, var(--tw-text-opacity));
}
.hover\:text-green-100:hover {
  --tw-text-opacity: 1;
  color: rgba(220, 252, 231, var(--tw-text-opacity));
}

Import the output file "/src/styles/xwind.css" into your project:

//Javascript:
import "/src/styles/xwind.css";
//OR
//HTML:
<link rel="stylesheet" href="/src/styles/xwind.css" />;

objectstyles mode

In objectstyles mode xwind will transform Tailwind classes into CSS object styles. The CSS object styles output can be used with your favorite CSS-in-JS library like emotion, styled-components. Objectstyles plugins make it possible to support any CSS-in-JS library syntax.

note: objectstyles mode is recommended if you are using a CSS-in-JS library.

classes mode

In classes mode xwind will transforms Tailwind classes into classes string. The classes string output can be used with the xwind cli to generate a minimal css file of the used Tailwind classes. This allows xwind to be used without a CSS-in-JS library.

note: classes mode is recommended if you're already using tailwindcss and want the benefits of xwind.

API

//these import will be removed by the babel plugin in build
import xw from "xwind";
//also available as macro variant
import xw from "xwind/macro";

import xw, { cx } from "xwind"; //or "xwind/macro"

//cx is used to compose different classes
//cx uses the clsx library from lukreed: https://github.com/lukeed/clsx#readme
cx(xw`text-green-200`, true && xw`bg-red-500`);

//tagged template syntax
xw`bg-red-100 bg-blue-400`;

//call expression syntax
xw("bg-red-100 bg-blue-400");
xw("bg-red-100", "bg-blue-400", [["text-sm"], "font-sans"]);

//xwind can evaluate static expressions
xw`bg-red-100 ${"bg-red-100"}`;

const bg = "bg-red-100";

xw`bg-red-100 ${bg}`;

xw("bg-red-100", bg);

Install

0. Prerequisites:

1. Install packages

# with npm
npm install -D xwind tailwindcss postcss autoprefixer

# with Yarn
yarn add -D xwind tailwindcss postcss autoprefixer

note autoprefixer is optional tailwindcss has it as peerdependency but it's not needed for xwind.

2. Add xwind babel plugin to babel config

This step is optional if you plan on using the "xwind/macro" instead.

// .babelrc
{
  "presets": [
    //... presets
  ],
  "plugins": [
    //add this:
    "xwind/babel"
  ]
}

3. Create Tailwind config file

The tailwind.config.js file is required to configure xwind config options.

npx tailwindcss init

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

4. Choose your preferred xwind mode:

4.A "objectstyles" mode install instructions

4.1 Add xwind config mode option to tailwind.config.js

// tailwind.config.js
module.exports = {
  theme: {},
  plugins: [],
  // ... tailwind config options

  //Add this:
  xwind: {
    mode: "objectstyles",
  },
};

4.2 Add Tailwind base css

4.2.A Using "XWIND_BASE XWIND_GLOBAL" classes

You can add the Tailwind base styling and classes global styling with the special xwind classes:

  • XWIND_BASE adds Tailwind base styling
  • XWIND_GLOBAL adds global classes styling e.g. keyframes and ring / shadow css variables

example with emotion

import { Global } from "@emotion/react";
import xw from "xwind";

<Global
  //add tailwind base + keyframes ... to global styles
  styles={xw`XWIND_BASE XWIND_GLOBAL`}
/>;
Generate base CSS with Tailwind cli

4.2.B Create a tailwind.base.css file

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

4.2.1 Add the xwind base tailwind plugin to add support for keyframe, ring and shadow classes.

// tailwind.config.js
module.exports = {
  theme: {},
  // ... tailwind config options

  //Add this:
  plugins: [require("xwind/plugins/base")],

  xwind: {
    mode: "objectstyles",
  },
};

4.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

4.2.3 Import base.css

import "base.css";

4.B "classes" mode install instructions

4.1 Add xwind config mode option to tailwind.config.js

// tailwind.config.js
module.exports = {
  theme: {},
  plugins: [],
  // ... tailwind config options

  //Add this:
  xwind: {
    mode: "classes",
    classes: {
      //entry files location all files containing xwind imports
      entry: "./src", // string | string[] / required
      //output css file location
      output: "./styles/xwind.css", //string / required
    },
  },
};

4.2 Create the output css file

Create a new css file at the location specified in the xwind config output option.

4.3 Generate the tailwind classes

Run the xwind cli to generate a minimal css file of the used Tailwind classes.

# Use the `npx xwind --help` command to learn more about the various CLI options.
npx xwind

# Run the xwind cli in watch mode, file changes will trigger rebuilds.
npx xwind -w

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

Examples

objectstyles mode

Codesandbox with Typescript, Nextjs and Emotion

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

classes mode (WIP)

coming soon!

Customization

Babel plugin config options

// .babelrc
{
  "presets": [
    /* ...presets */
  ],
  "plugins": [
    [
      "xwind/babel",
      {
        "config": "./tailwind.config.js" //Path to tailwind config default: 'tailwind.config.js'
      }
    ]
    /* ...other plugins */
  ]
}
Babel macro plugin configuration
// .babelrc
{
  "presets": [
    /* ...presets */
  ],
  "plugins": [
    [
      "macros",
      {
        "xwind": {
          "config": "./tailwind.config.js" //Path to 'tailwind.config.js'
        }
      }
    ]
    /* ...other plugins */
  ]
}
// package.json
"babelMacros": {
    "xwind": {
      "config": "./tailwind.config.js",  //Path to 'tailwind.config.js'
    }
},
// babel-plugin-macros.config.js
module.exports = {
  xwind: {
    config: "./tailwind.config.js", //Path to 'tailwind.config.js'
  },
};

xwind config

The xwind config options are set in the tailwind.config.js file

classes mode

// tailwind.config.js
module.exports = {
  theme: {},
  plugins: [],
  // ... tailwind config options

  xwind: {
    //select xwind output mode
    mode: "classes", // "classes" / required
    classes: {
      //include tailwindcss base styles
      includeBase: true, // boolean / optional / default: true
      //entry files location all files containing xwind imports
      entry: "./src", // string | string[] / required
      //output css file location
      output: "./styles/xwind.css", //string / required
    },
  },
};

objectstyles mode

// tailwind.config.js
module.exports = {
  theme: {},
  plugins: [],
  // ... tailwind config options

  xwind: {
    //select xwind output mode
    mode: "objectstyles", // "objectstyles" / required
    objectstyles: {
      //enable babel cache warning
      warningCache: true, // boolean / optional / default: true,
      plugins: [
        /* objectstyles plugins / optional */
      ],
    },
  },
};

objectstyles plugins

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

CSS string

// tailwind.config.js
module.exports = {
  //... tailwind config options
  xwind: {
    mode: "objectstyles",
    objectstyles: {
      plugins: [require("xwind/plugins/objectstyles/css")],
    },
  },
};
CSS string plugin output example

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 = {
  //... tailwind config options
  xwind: {
    mode: "objectstyles",
    objectstyles: {
      plugins: [require("xwind/plugins/objectstyles/removeFallbacks")],
    },
  },
};
Remove fallbacks plugin output example 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))",
  },
};

License

MIT. Copyright (c) 2020 Arthur Petrie.

Package Sidebar

Install

npm i xwind

Weekly Downloads

59

Version

0.8.0

License

MIT

Unpacked Size

225 kB

Total Files

67

Last publish

Collaborators

  • arthie