npm package: @locktech/atomic-mixins
Description: PostCSS mixins for Atomic UI components
Author: realStandal
Latest version: 0.4.5

# Atomic: PostCSS Mixins

[![GitHub release](https://img.shields.io/github/release/locktech/atomic-mixins?include_prereleases=&sort=semver&color=blue)](https://github.com/locktech/atomic-mixins/releases/)
[![Build and Publish](https://github.com/locktech/atomic-mixins/workflows/Build%20and%20Publish/badge.svg)](https://github.com/locktech/atomic-mixins/actions?query=workflow:"Build+and+Publish")
[![Build and Deploy Storybook](https://github.com/LockTech/atomic-mixins/workflows/Build%20and%20Deploy%20Storybook/badge.svg)](https://github.com/LockTech/atomic-mixins/actions?query=workflow:"Build+and+Deploy+Storybook")

`atomic-mixins` is a library providing [PostCSS mixins](https://github.com/postcss/postcss-mixins) to generate [Atomic's UI components](https://www.figma.com/file/tgF7iprIC1KwKUzTNIDXLC/Atomic)
using [TailwindCSS'](https://tailwindcss.com/) utility-classes.

On this page:

- [Storybook Documentation + Examples](https://locktech.github.io/atomic-mixins/)
- [Installation](#installation)
- [Usage](#usage)

## Installation

- [0) Setting up TailwindCSS and PostCSS](#0-setting-up-tailwindcss-and-postcss)
- [1) Downloading the library](#1-downloading-the-library)
- [2) Setting up PostCSS plugins](#2-setting-up-postcss-plugins)
- [3) Importing Atomic's mixins](#3-importing-atomics-mixins)
- [4) Use Atomic's TailwindCSS Preset (Optional)](#4-use-atomics-tailwindcss-preset-optional)

### 0) Setting up TailwindCSS and PostCSS

Installing [TailwindCSS](https://tailwindcss.com/docs/installation) and [PostCSS](https://github.com/postcss/postcss#usage) is well beyond this document.

How you do so will largely depend upon your environment, libraries, and/or framework of choice.

### 1) Downloading the library

Downloading the library will depend upon your environment of choice. I'll be using [Yarn](https://yarnpkg.com/) below:

```bash
yarn add --dev @locktech/atomic-mixins
```

### 2) Setting up PostCSS plugins

To make getting started easier, Atomic takes care of ensuring the required PostCSS plugins are available through a single plugin of its own.
These opinionations will be a down-stream benefit to your application: the plugins Atomic makes use of are fully available to you in your application's styling.

Plugins Atomic will provide you:

- [`postcss-import`](https://github.com/postcss/postcss-import)
- [`postcss-mixins`](https://github.com/postcss/postcss-mixins)
- [`postcss-simple-vars`](https://github.com/postcss/postcss-simple-vars)

In addition to Atomic's plugin, you'll also need to add the [`tailwindcss/nesting` plugin](https://tailwindcss.com/docs/using-with-preprocessors#nesting).
All said and done, your `postcss.config.js` file should resemble:

```js
// postcss.config.js
module.exports = {
  plugins: [
    // Notice how we've loaded them *before* Tailwind.
    require("@locktech/atomic-mixins/postcss"),
    require("tailwindcss/nesting"),
    require("tailwindcss"),
    require("autoprefixer"),
  ],
};
```

### 3) Importing Atomic's mixins

Finally, you'll need to `@import` Atomic's mixins into your application's CSS file - the same you've used to setup Tailwind.

> Below I'm using [Tailwind's `@import` syntax](https://tailwindcss.com/docs/using-with-preprocessors#build-time-imports).

```css
@import "tailwindcss/base";
@import "tailwindcss/components";
@import "tailwindcss/utilities";

@import "@locktech/atomic/mixins";

/* Your styling... */
```

### 4) Use Atomic's TailwindCSS Preset (Optional)

Provided is Atomic's TailwindCSS preset, you may choose to use this in your project's `tailwind.config.js` file or not - its up to you.

```js
module.exports = {
  presets: [require("@locktech/atomic-mixins/preset")],
  purge: [
    /* ... */
  ],
};
```

This preset will:

- Configure TailwindCSS in [JIT mode](https://tailwindcss.com/docs/just-in-time-mode).
- Enable [dark mode](https://tailwindcss.com/docs/dark-mode), using the `'media'` setting.
- Add a _spin_ animation
- Add Atomic's gray color pallete.

## Usage

- [Basic Use](#basic-use)
- [Nested Styling](#nested-styling)
- [Extending Mixins](#extending-mixins)

### Basic Use

Let's use the `btn` mixin as an example. It provides a call signature resembling:

```css
@mixin btn $color;
```

To make use of this mixin, your class would invoke it as such:

> Note: It is _highly_ recommended you organize your custom-classes using [Tailwind's `@layer` directive](https://tailwindcss.com/docs/functions-and-directives#layer),
> to ensure any styling you don't use is not included in your final CSS.

```css
.btn-red {
  @mixin btn red;
}
```

You are free to `@apply` any of Tailwind's classes to your own, customizing the mixin to your liking:

```css
.btn-red-ghost-lg {
  @mixin btn red;
  @apply px-3 py-2; /* Increase the apparent size of our button */
  @apply bg-transparent; /* Remove the mixin's "resting" background. */
  @apply border-transparent; /* Remove the mixin's "resting" border. */
  @apply text-gray-900 dark:text-gray-50; /* Ensure our button's text contrasts our app's background. */
}
```

### Nested Styling

Some components offer styling spread throughout many classes. These classes are often styled using Tailwind's [nesting wrapper](https://tailwindcss.com/docs/using-with-preprocessors#nesting).
Your customizations should, much like the classes themselves, be nested under the invocation of the mixin defining them.

Component's which provide this functionality will have a code-block in their documentation, highlighting how you may go about applying your customizations.
For the purpose of demonstration, let's look at how you might go about customizing the `'menu-items'` class - which is created when using the Menu mixin:

```css
.menu {
  @mixin menu;

  & > .menu-items {
    @apply bg-gray-300;
  }
}
```

### Extending Mixins

As the installation document would tell you, the plugins which power Atomic are available to you - this includes the mixin plugin.

Let's take advantage of it to extend one of Atomic's mixins to make our own, which we may reuse:

```css
@define-mixin btn-raised $color {
  @mixin btn $color;
  @apply shadow hover:shadow-md active:shadow-sm;
}

.btn-raised-green {
  @mixin btn-raised green;
}

.btn-raised-red {
  @mixin btn-raised red;
}
```