css-variants 2.1.0 โ†’ 2.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -3,24 +3,38 @@
3
3
  [![npm](https://img.shields.io/npm/dm/css-variants)](https://npmjs.com/package/css-variants)
4
4
  ![npm](https://img.shields.io/npm/v/css-variants)
5
5
 
6
- # css-variants
6
+ # css-variants โ€” Compose class names & styles with variants
7
7
 
8
- A lightweight, flexible API for managing CSS class variants and inline styles in JavaScript and TypeScript projects.
8
+ Lightweight helpers to compose class names and inline styles using "variants". Zero runtime deps, small bundle, and first-class TypeScript support.
9
+
10
+ <p align="center">
11
+ <img src="/.github/assets/logo.png" alt="css-variants" />
12
+ </p>
9
13
 
10
14
  ## Features
11
15
 
12
- - ๐ŸŽจ Dynamic class name generation with variant support
13
- - ๐Ÿ’… First-class inline styles support alongside class names
14
- - ๐Ÿงฉ Powerful slot-based variant system for complex components
15
- - ๐Ÿ“ฆ Zero dependencies
16
- - ๐Ÿ”’ Fully type-safe with TypeScript
17
- - ๐Ÿš€ Framework-agnostic
18
- - ๐Ÿชถ Lightweight (~2KB gzipped)
19
- - ๐Ÿ”ฅ Strong tree-shaking support
20
- - โšก๏ธ Optimal runtime performance
16
+ ๐ŸŒฑ **Zero deps** โ€” No runtime dependencies; tiny bundle and minimal maintenance.
17
+
18
+ ๐Ÿช **Tailwind-friendly** โ€” First-class compatibility with Tailwind via `tw-merge` (see "Tailwind Integration (tw-merge)"), so conflicting utilities are resolved predictably.
19
+
20
+ ๐Ÿ”’ **TypeScript-safe** โ€” Strong inference and mapped-type helpers keep variant props typed correctly.
21
+
22
+ ๐Ÿงฉ **Variants & compound rules** โ€” Simple `variants` maps plus `compoundVariants` for combination rules (e.g., size + color).
23
+
24
+ ๐Ÿงญ **Slot support** โ€” `scv` / `ssv` manage multiple named slots with per-slot `base`, `variants`, and overrides.
25
+
26
+ โš™๏ธ **Flexible resolver** โ€” Default `cx`, with an option to pass a custom `classNameResolver` (recommended: `twMerge(cx(...))`).
27
+
28
+ โšก **Performance & tree-shaking** โ€” Minimal runtime and tree-shakeable code paths for small bundles.
29
+
30
+ ๐Ÿงช **Developer ergonomics** โ€” Colocated `*.test.ts` (Vitest), clear build scripts (`yarn build`) and linting (`yarn lint`).
31
+
32
+ Use cases: design-system components, Tailwind + component libraries, SSR-friendly UI primitives.
21
33
 
22
34
  ## Installation
23
35
 
36
+ Install with your preferred package manager:
37
+
24
38
  ```bash
25
39
  # npm
26
40
  npm install css-variants
@@ -28,22 +42,46 @@ npm install css-variants
28
42
  # yarn
29
43
  yarn add css-variants
30
44
 
31
- # pnpm
45
+ # pnpm
32
46
  pnpm add css-variants
33
47
  ```
34
48
 
49
+ TypeScript types are included. Import the package in ESM or CJS projects:
50
+
51
+ ```ts
52
+ // ESM
53
+ import { cv, scv, cx } from 'css-variants'
54
+
55
+ // CJS
56
+ const { cv, scv, cx } = require('css-variants')
57
+ ```
58
+
35
59
  ## Core Utilities
36
60
 
37
- css-variants provides four main utilities:
61
+ Quick reference for the main exports. Each utility has full examples below.
38
62
 
39
- - [cv](#class-variants-cv) - Class Variants for managing single component class names
40
- - [sv](#style-variants-sv) - Style Variants for managing single component inline styles
41
- - [scv](#slot-class-variants-scv) - Slot Class Variants for managing multiple slot class names
42
- - [ssv](#slot-style-variants-ssv) - Slot Style Variants for managing multiple slot inline styles
43
- - [cx](#class-merger-cx) - Utility for composing class names conditionally.
63
+ - ๐Ÿงฉ [`cv`](#cv---class-variants) โ€” Class Variants (single element)
64
+ - Use to compose class names for one element. Supports `base`, `variants`, `compoundVariants`, and `defaultVariants`.
65
+ - Quick: `const btn = cv({ base: 'btn', variants: { size: { sm: 'p-2', lg: 'p-4' } } })`
44
66
 
45
- ### Class Variants ([cv](./src/cv.ts))
46
- For managing class names for a single component:
67
+ - ๐ŸŽจ [`sv`](#sv---style-variants) โ€” Style Variants (single element)
68
+ - Compose inline style objects similarly to `cv` but returning CSS props.
69
+ - Quick: `const s = sv({ base: { display: 'flex' }, variants: { size: { sm: { gap: '4px' } } } })`
70
+
71
+ - ๐Ÿงฐ [`scv`](#scv-slot-class-variants) โ€” Slot Class Variants (multi-slot)
72
+ - Manage class names across named slots (`slots: ['root','title']`) with per-slot `base`, `variants`, and `classNames` overrides.
73
+ - Quick: `const card = scv({ slots: ['root','title'], base: { root: 'card' } })`
74
+
75
+ - ๐Ÿงพ [`ssv`](#ssv---slot-style-variants) โ€” Slot Style Variants (multi-slot styles)
76
+ - Same as `scv` but composes inline style objects per slot.
77
+
78
+ - โš™๏ธ [`cx`](#cx---class-merger) โ€” Class merger
79
+ - Small, typed `clsx`-like utility used as the default `classNameResolver`.
80
+ - Quick: `cx('a', { b: true }, ['c']) // => 'a b c'`
81
+
82
+ ### [cv](./src/cv.ts) - Class Variants
83
+ Compose class names for a single element. Config keys: `base`, `variants`, `defaultVariants`, `compoundVariants`, and optional `classNameResolver` (defaults to `cx`).
84
+ `cv` returns a typed function you call with variant props (and optional `className`) to get the final class string.
47
85
 
48
86
  ```ts
49
87
  import { cv } from 'css-variants'
@@ -81,9 +119,10 @@ button({ size: 'lg' }) // => 'font-bold rounded-lg bg-blue-500 text-white text-l
81
119
  button({ size: 'lg', className: 'custom' }) // => 'font-bold rounded-lg bg-blue-500 text-white text-lg px-4 py-2 uppercase custom'
82
120
  ```
83
121
 
84
- ### Style Variants ([sv](./src/sv.ts))
122
+ ### [sv](./src/sv.ts) - Style Variants
85
123
 
86
- For managing inline styles:
124
+ Compose inline style objects for a single element. Config keys: `base`, `variants`, `defaultVariants`, and `compoundVariants`.
125
+ `sv` returns a typed function that accepts variant props and an optional `style` object which is shallow-merged into the result.
87
126
 
88
127
  ```ts
89
128
  import { sv } from 'css-variants'
@@ -118,9 +157,13 @@ button({
118
157
  // => { fontWeight: 'bold', borderRadius: '8px', backgroundColor: 'gray', color: 'white', padding: '4px' }
119
158
  ```
120
159
 
121
- ### Slot Class Variants ([scv](./src/scv.ts))
160
+ ### [scv](./src/scv.ts) - Slot Class Variants
122
161
 
123
- For managing class names across multiple slots/elements:
162
+ Compose and merge class names across named slots.
163
+ `scv` accepts `slots` plus per-slot `base`, `variants`, `compoundVariants`,
164
+ and runtime `classNames` overrides, and returns an object mapping each slot to
165
+ its final merged class string. Ideal for components with multiple sub-elements
166
+ (for example: `root`, `title`, `content`).
124
167
 
125
168
  ```ts
126
169
  import { scv } from 'css-variants'
@@ -167,9 +210,13 @@ card({
167
210
  // }
168
211
  ```
169
212
 
170
- ### Slot Style Variants ([ssv](./src/ssv.ts))
213
+ ### [ssv](./src/ssv.ts) - Slot Style Variants
171
214
 
172
- For managing inline styles across multiple slots:
215
+ Compose and merge inline style objects across named slots.
216
+ `ssv` accepts `slots` plus per-slot `base`, `variants`, `compoundVariants`,
217
+ and runtime `styles` overrides, and returns an object mapping each slot to
218
+ its final merged style. Useful for components with multiple styled
219
+ sub-elements (for example: `root`, `title`, `content`).
173
220
 
174
221
  ```ts
175
222
  import { ssv } from 'css-variants'
@@ -215,7 +262,7 @@ card({
215
262
  // }
216
263
  ```
217
264
 
218
- ### Class Merger ([cx](./src/cx.ts))
265
+ ### [cx](./src/cx.ts) - Class Merger
219
266
 
220
267
  Similar to `clsx/classnames` but with better TypeScript support.
221
268
 
@@ -247,95 +294,30 @@ cx('foo', {
247
294
  cx('foo', null, undefined, false, 0, '') // => 'foo'
248
295
  ```
249
296
 
250
- ## Advanced Features
251
-
252
- ### Boolean Variants
253
-
254
- Support for boolean variants to toggle styles conditionally:
255
-
256
- ```ts
257
- import { cv } from 'css-variants'
258
-
259
- const button = cv({
260
- variants: {
261
- disabled: {
262
- true: 'opacity-50 cursor-not-allowed'
263
- }
264
- }
265
- })
266
-
267
- button({ disabled: true }) // => 'opacity-50 cursor-not-allowed'
268
- ```
269
-
270
- ### Compound Variants
297
+ ## Tailwind Integration (tw-merge)
271
298
 
272
- Apply styles based on combinations of variants:
299
+ Use a resolver that combines `cx` with `tw-merge` to properly merge Tailwind classes
300
+ and let `tw-merge` remove conflicting utility classes (recommended for Tailwind users).
273
301
 
274
302
  ```ts
275
- import { cv } from 'css-variants'
303
+ import { cv, cx } from 'css-variants'
304
+ import { twMerge } from 'tailwind-merge'
276
305
 
277
306
  const button = cv({
307
+ base: 'btn',
278
308
  variants: {
279
309
  color: {
280
310
  primary: 'bg-blue-500',
281
- danger: 'bg-red-500'
282
- },
283
- size: {
284
- sm: 'text-sm',
285
- lg: 'text-lg'
311
+ danger: 'bg-red-500'
286
312
  }
287
313
  },
288
- compoundVariants: [
289
- {
290
- color: 'danger',
291
- size: 'lg',
292
- className: 'animate-pulse'
293
- }
294
- ]
314
+ // recommended resolver: compose `cx` then `twMerge`
315
+ classNameResolver: (...args) => twMerge(cx(...args))
295
316
  })
296
317
 
297
- button({ color: 'danger', size: 'lg' }) // => 'bg-red-500 text-lg animate-pulse'
298
- ```
299
-
300
- ### Default Variants
301
-
302
- Specify default variant values:
303
-
304
- ```ts
305
- import { cv } from 'css-variants'
306
-
307
- const button = cv({
308
- variants: {
309
- size: {
310
- sm: 'text-sm',
311
- lg: 'text-lg'
312
- }
313
- },
314
- defaultVariants: {
315
- size: 'sm'
316
- }
317
- })
318
-
319
- button() // => 'text-sm'
320
- ```
321
-
322
- ### Custom Class Name Resolver
323
-
324
- Use your preferred class name utility:
325
-
326
- ```ts
327
- import { cv } from 'css-variants'
328
- import { clsx } from 'clsx'
329
-
330
- const button = cv({
331
- base: 'btn',
332
- variants: {
333
- color: {
334
- primary: 'btn-primary'
335
- }
336
- },
337
- classNameResolver: clsx
338
- })
318
+ // Later classes and conflicting utilities are resolved by `tw-merge`:
319
+ button({ color: 'primary', className: 'bg-red-600' })
320
+ // => 'btn bg-red-600' (tw-merge will prefer the later `bg-red-600` value)
339
321
  ```
340
322
 
341
323
  ## TypeScript Support
@@ -365,9 +347,17 @@ This library is inspired by several excellent projects:
365
347
  - [CVA (Class Variance Authority)](https://github.com/joe-bell/cva)
366
348
  - [Panda CSS](https://github.com/chakra-ui/panda)
367
349
 
350
+ ## Developer commands
351
+
352
+ ```bash
353
+ yarn test # run vitest tests
354
+ yarn build # build CJS + ESM artifacts into dist/
355
+ yarn lint # eslint + prettier
356
+ ```
357
+
368
358
  ## Contribute
369
359
 
370
- If you would like to contribute to the project, please read how to contribute here [CONTRIBUTING.md](./CONTRIBUTING.md).
360
+ Please open PRs with focused changes and unit tests under `src/*.test.ts`. Keep runtime footprint minimal and preserve the exported API (`cv`, `sv`, `scv`, `ssv`, `cx`). See [CONTRIBUTING.md](./CONTRIBUTING.md) for process details.
371
361
 
372
362
  ## License
373
363
 
package/dist/cjs/scv.js CHANGED
@@ -63,15 +63,15 @@ const scv = (config) => {
63
63
  }
64
64
  }
65
65
  for (const key in mergedProps) {
66
- const slotClassValue = variants[key]?.[mergedProps[key]];
67
- if (slotClassValue) {
68
- for (const slot in slotClassValue) {
69
- slotClassValues[slot].push(slotClassValue[slot]);
66
+ const cls = variants[key]?.[mergedProps[key]];
67
+ if (cls) {
68
+ for (const slot in cls) {
69
+ slotClassValues[slot]?.push(cls[slot]);
70
70
  }
71
71
  }
72
72
  }
73
73
  if (compoundVariants) {
74
- for (const { classNames: slotClassValue, ...compoundVariant } of compoundVariants) {
74
+ for (const { classNames: cls, ...compoundVariant } of compoundVariants) {
75
75
  let matches = true;
76
76
  for (const key in compoundVariant) {
77
77
  const value = compoundVariant[key];
@@ -82,15 +82,15 @@ const scv = (config) => {
82
82
  }
83
83
  }
84
84
  if (matches) {
85
- for (const slot in slotClassValue) {
86
- slotClassValues[slot].push(slotClassValue[slot]);
85
+ for (const slot in cls) {
86
+ slotClassValues[slot]?.push(cls[slot]);
87
87
  }
88
88
  }
89
89
  }
90
90
  }
91
91
  if (classNames) {
92
92
  for (const slot in classNames) {
93
- slotClassValues[slot].push(classNames[slot]);
93
+ slotClassValues[slot]?.push(classNames[slot]);
94
94
  }
95
95
  }
96
96
  const result = {};
@@ -1 +1 @@
1
- {"version":3,"file":"scv.js","sourceRoot":"","sources":["../../src/scv.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"scv.js","sourceRoot":"","sources":["../../src/scv.ts"],"names":[],"mappings":"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"}
@@ -5,10 +5,10 @@ export type RequireAtLeastOne<T> = {
5
5
  [K in keyof T]-?: Required<Pick<T, K>> & Partial<Pick<T, Exclude<keyof T, K>>>;
6
6
  }[keyof T];
7
7
  export type StringToBoolean<T> = T extends 'true' | 'false' ? boolean : T;
8
- export type ObjectKeyPicker<T> = keyof never extends keyof T ? Record<string, unknown> : {
8
+ export type ObjectKeyPicker<T> = [keyof T] extends [never] ? Record<string, unknown> : {
9
9
  [K in keyof T]?: StringToBoolean<keyof T[K]> | undefined;
10
10
  };
11
- export type ObjectKeyArrayPicker<T> = keyof never extends keyof T ? Record<string, unknown> : {
11
+ export type ObjectKeyArrayPicker<T> = [keyof T] extends [never] ? Record<string, unknown> : {
12
12
  [K in keyof T]?: OneOrMore<StringToBoolean<keyof T[K]>> | undefined;
13
13
  };
14
14
  export type CssProperties = Properties<string | number>;
package/dist/esm/scv.js CHANGED
@@ -60,15 +60,15 @@ export const scv = (config) => {
60
60
  }
61
61
  }
62
62
  for (const key in mergedProps) {
63
- const slotClassValue = variants[key]?.[mergedProps[key]];
64
- if (slotClassValue) {
65
- for (const slot in slotClassValue) {
66
- slotClassValues[slot].push(slotClassValue[slot]);
63
+ const cls = variants[key]?.[mergedProps[key]];
64
+ if (cls) {
65
+ for (const slot in cls) {
66
+ slotClassValues[slot]?.push(cls[slot]);
67
67
  }
68
68
  }
69
69
  }
70
70
  if (compoundVariants) {
71
- for (const { classNames: slotClassValue, ...compoundVariant } of compoundVariants) {
71
+ for (const { classNames: cls, ...compoundVariant } of compoundVariants) {
72
72
  let matches = true;
73
73
  for (const key in compoundVariant) {
74
74
  const value = compoundVariant[key];
@@ -79,15 +79,15 @@ export const scv = (config) => {
79
79
  }
80
80
  }
81
81
  if (matches) {
82
- for (const slot in slotClassValue) {
83
- slotClassValues[slot].push(slotClassValue[slot]);
82
+ for (const slot in cls) {
83
+ slotClassValues[slot]?.push(cls[slot]);
84
84
  }
85
85
  }
86
86
  }
87
87
  }
88
88
  if (classNames) {
89
89
  for (const slot in classNames) {
90
- slotClassValues[slot].push(classNames[slot]);
90
+ slotClassValues[slot]?.push(classNames[slot]);
91
91
  }
92
92
  }
93
93
  const result = {};
@@ -1 +1 @@
1
- {"version":3,"file":"scv.js","sourceRoot":"","sources":["../../src/scv.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"scv.js","sourceRoot":"","sources":["../../src/scv.ts"],"names":[],"mappings":"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"}
@@ -5,10 +5,10 @@ export type RequireAtLeastOne<T> = {
5
5
  [K in keyof T]-?: Required<Pick<T, K>> & Partial<Pick<T, Exclude<keyof T, K>>>;
6
6
  }[keyof T];
7
7
  export type StringToBoolean<T> = T extends 'true' | 'false' ? boolean : T;
8
- export type ObjectKeyPicker<T> = keyof never extends keyof T ? Record<string, unknown> : {
8
+ export type ObjectKeyPicker<T> = [keyof T] extends [never] ? Record<string, unknown> : {
9
9
  [K in keyof T]?: StringToBoolean<keyof T[K]> | undefined;
10
10
  };
11
- export type ObjectKeyArrayPicker<T> = keyof never extends keyof T ? Record<string, unknown> : {
11
+ export type ObjectKeyArrayPicker<T> = [keyof T] extends [never] ? Record<string, unknown> : {
12
12
  [K in keyof T]?: OneOrMore<StringToBoolean<keyof T[K]>> | undefined;
13
13
  };
14
14
  export type CssProperties = Properties<string | number>;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "css-variants",
3
- "version": "2.1.0",
4
- "description": "A lightweight, flexible API for managing CSS class variants.",
3
+ "version": "2.1.1",
4
+ "description": "Lightweight helpers to compose class names and inline styles using variants. Zero runtime deps, small bundle, and first-class TypeScript support.",
5
5
  "main": "dist/cjs/index.js",
6
6
  "module": "dist/esm/index.js",
7
7
  "types": "dist/esm/index.d.ts",