Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/guilhermerodz/atomic-variants

Tiny utility for handling atomic CSS
https://github.com/guilhermerodz/atomic-variants

atomic classname classnames css react variants

Last synced: 3 months ago
JSON representation

Tiny utility for handling atomic CSS

Awesome Lists containing this project

README

        

# Atomic Variants

## ๐Ÿš€ Get Started

```sh
npm i @rodz/atomic-variants
```

### ๐Ÿง  Tailwind Intellisense for VSCode

If you're using the ["Tailwind CSS IntelliSense" Visual Studio Code extension](https://marketplace.visualstudio.com/items?itemName=bradlc.vscode-tailwindcss), you can enable autocompletion for `atomic-variants` by adding the following to your [`settings.json`](https://code.visualstudio.com/docs/getstarted/settings):

```json
{
"tailwindCSS.experimental.classRegex": [
["(?:styled|c[xsb])\\(([^)]*)\\)", "[\"'`]([^\"'`]*).*?[\"'`]"]
]
}
```

๐Ÿ‘ VSCode Pro Tips

### Improve Regex performance

If you adopt the `cz` alias instead of `styled` and you are using the Tailwind extension, know you can improve your Regex performance:

```diff
// .vscode/settings.json
{
"tailwindCSS.experimental.classRegex": [
- ["(?:styled|c[xsb])\\(([^)]*)\\)", "[\"'`]([^\"'`]*).*?[\"'`]"]
+ ["c[zxsb]\\(([^)]*)\\)", "[\"'`]([^\"'`]*).*?[\"'`]"]
]
}

// src/components/Button.tsx
- import { styled } from '@rodz/atomic-variants'
+ import { cz } from '@rodz/atomic-variants'

- export const Button = styled('button', {...})
+ export const Button = cz('button', {...})
```

### Project-specific configuration

You peers can share the same setup if they have installed the Tailwind extension.
Commit to your `git` repo instead of your personal `User` settings:

```
โœ… Prefer Workspace Settings
my-git-repo-directory/
โ””โ”€โ”€ .vscode/
โ””โ”€โ”€ settings.json ๐Ÿ‘

โŒ Not Personal Settings
Users/
โ””โ”€โ”€ username/
โ””โ”€โ”€ Library/
โ””โ”€โ”€ Application Support/
โ””โ”€โ”€ Code/
โ””โ”€โ”€ User/
โ””โ”€โ”€ settings.json ๐Ÿ‘Ž
```

## ๐Ÿฅณ Quick Start

### styled (Composable Components)

It's a wrapper around [`cb`](#cb-class-builder), built for React JSX composition.

```tsx
import { styled } from '@rodz/atomic-variants'

const Button = styled('button', {
base: ['font-semibold', 'border', 'rounded'],
variants: {
intent: {
primary: [
'bg-black',
'text-white',
],
// **or**
// primary: "bg-black text-white",
secondary: [
'bg-white',
'text-black',
],
},
size: {
small: ['text-sm', 'py-1', 'px-2'],
medium: ['text-base', 'py-2', 'px-4'],
},
},
compoundVariants: [{ intent: 'secondary', size: 'small', className: 'uppercase' }],
defaultVariants: {
intent: 'primary',
size: 'medium',
},
})

// It's ready to use. Includes a `variants` prop.
Click me
// => className: "font-semibold border rounded bg-white text-black text-base py-2 px-4"
```

## ๐Ÿ““ Features

### cz

Alias for `styled`. See [VSCode Pro Tips](#regex-performance) to understand why.

### cx (Class Concat & Flatten)

A tiny utility for concatenating & flattening & cleaning class names.
Supports arrays of strings in infinite depths. Supports undefined in first depth.

```ts
import { cx } from '@rodz/atomic-variants'

cx('a', 'b', 'c')
// => "a b c"

cx('a', ['b', ['c', 'd'], 'e'], ['f'])
// => "a b c d e f"

cx('a', undefined, ['b', ['c', 'd']], ['e', ['f', 'g'], 'h'])
// => "a b c d e f g h"
```

### cb (Class Builder)

It's similar to [`styled`](#styled-composable-components), but it returns a normal function instead of of returning a React component.

The returned function will assign `{ ...props, className }` to a final class name (string).

In the following example, [`cb`](#cb-class-builder) has been called and returned `button`, which is a function.
`button` can now be called to reduce its props into a final className.

```ts
import { cb } from '@rodz/atomic-variants'

const button = cb({
base: ['font-semibold', 'border', 'rounded'],
variants: {
intent: {
primary: ['bg-black', 'text-white'],
// **or**
// primary: "bg-black text-white",
secondary: ['bg-white', 'text-black'],
},
size: {
small: ['text-sm', 'py-1', 'px-2'],
medium: ['text-base', 'py-2', 'px-4'],
},
},
compoundVariants: [
{ intent: 'secondary', size: 'small', className: 'uppercase' },
],
defaultVariants: {
intent: 'primary',
size: 'medium',
},
})

button()
// => "font-semibold border rounded bg-black text-white text-base py-2 px-4"

button({ intent: 'secondary', size: 'small' })
// => "font-semibold border rounded bg-white text-black text-sm py-1 px-2 uppercase"
```

### cs (Config Shared)

Useful for sharing similar variants between components.
Expects the same parameters as [`cb`](#cb-class-builder).

```tsx
import { cs } from '@rodz/atomic-variants'

const sharedTableCell = cs({
base: [
'first:pl-6 last:pr-6',
'group-[]/table-condensed:first:pl-4 group-[]/table-condensed:first:pr-4',
'group-[]/table-condensed:py-2',
],
variants: {
align: {
start: ['text-start'],
center: ['text-center'],
end: ['text-end'],
},
},
defaultVariants: { align: 'start' },
})

export const Th = styled('th', {
...sharedTableCell,
base: [sharedTableCell.base, 'py-3'],
})

export const Td = styled('td', {
...sharedTableCell,
base: [sharedTableCell.base, 'py-4'],
})
```

---

## Acknowledgements:

- [joe-bell/cva](https://github.com/joe-bell/cva) ๐Ÿงฌ for type-safe atomic class names
- [stitchesjs/stitches](https://github.com/stitchesjs/stitches) ๐Ÿงต for React composability