chaincss 2.1.30 → 2.1.32

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
@@ -1,4 +1,4 @@
1
- # ChainCSS
1
+ <h1 align="center">ChainCSS</h1>
2
2
 
3
3
  <p align="center">
4
4
  <strong>The first CSS-in-JS library with true auto-detection mixed mode.</strong><br>
@@ -6,18 +6,26 @@
6
6
  </p>
7
7
 
8
8
  <p align="center">
9
- <a href="https://www.npmjs.com/package/chaincss"><img src="https://img.shields.io/npm/v/chaincss" alt="npm"></a>
10
- <a href="https://github.com/melcanz08/chaincss/blob/main/LICENSE"><img src="https://img.shields.io/github/license/melcanz08/chaincss" alt="license"></a>
11
- <a href="https://chaincss.dev"><img src="https://img.shields.io/badge/docs-chaincss.dev-blue" alt="docs"></a>
9
+ <a href="https://www.npmjs.com/package/chaincss">
10
+ <img src="https://img.shields.io/npm/v/chaincss" alt="npm">
11
+ </a>
12
+ <a href="https://github.com/melcanz08/chaincss/blob/main/LICENSE">
13
+ <img src="https://img.shields.io/github/license/melcanz08/chaincss" alt="license">
14
+ </a>
15
+ <a href="https://chaincss.dev">
16
+ <img src="https://img.shields.io/badge/docs-chaincss.dev-blue" alt="docs">
17
+ </a>
18
+ <a href="https://github.com/melcanz08/chaincss/actions">
19
+ <img src="https://img.shields.io/badge/tests-258%20passed-brightgreen" alt="tests">
20
+ </a>
12
21
  </p>
13
22
 
14
- ---
15
23
 
16
- ## What is ChainCSS?
24
+ # What is ChainCSS?
17
25
 
18
- ChainCSS lets you write styles as **native JavaScript method chains** instead of CSS strings or object literals.
26
+ ChainCSS lets you write styles as **native JavaScript method chains** no CSS syntax, no template literals, no object literals.
19
27
 
20
- It automatically detects which styles are static (compiled to CSS) and which are dynamic (kept in JS), then splits them for optimal performance.
28
+ It automatically detects which styles are static (compiled to zero-runtime CSS) and which are dynamic (stay in JS), then splits them automatically.
21
29
 
22
30
  ```ts
23
31
  import { chain } from "chaincss";
@@ -38,53 +46,41 @@ const card = chain()
38
46
 
39
47
  **No CSS syntax. No template literals. No object literals. Just JavaScript.**
40
48
 
41
- ---
42
49
 
43
- ## Auto-Detection Mixed Mode
50
+ # Installation
44
51
 
45
- ```ts
46
- import { smartChain } from "chaincss";
47
-
48
- const styles = smartChain()
49
- .display("flex")
50
- .padding(20)
51
- .color(props.textColor)
52
- .fontSize(theme.sizes.lg)
53
- .$el("dynamic-card");
52
+ ```bash
53
+ npm install chaincss
54
54
  ```
55
55
 
56
- | Library | Approach | Dynamic Support | Runtime Cost |
57
- |--------|---------|----------------|-------------|
58
- | Tailwind | Utility classes | No | Zero |
59
- | Styled Components | Runtime CSS-in-JS | Yes | High |
60
- | Panda CSS | Build-time + recipes | Limited | Near-zero |
61
- | Vanilla Extract | Build-time only | No | Zero |
62
- | **ChainCSS** | **Auto-detection + split** | **Yes** | **Minimal** |
63
-
64
- ---
56
+ ## Quick Start
65
57
 
66
- ## Installation
58
+ | Environment | Setup |
59
+ |---|---|
60
+ | **Vite** | Add `chaincss()` plugin to `vite.config.ts` |
61
+ | **Node.js** | `import { chain } from "chaincss"` |
62
+ | **Browser CDN** | `import { chain } from "https://cdn.jsdelivr.net/npm/chaincss/dist/browser.js"` |
63
+ | **Browser + import map** | Map `"chaincss"` to `./node_modules/chaincss/dist/browser.js` |
67
64
 
68
- ```bash
69
- npm install chaincss
70
- ```
71
65
 
72
- ### Vite Setup
66
+ ## Vite Configuration
73
67
 
74
68
  ```ts
69
+ // vite.config.ts
75
70
  import { defineConfig } from "vite";
76
71
  import chaincss from "chaincss/plugin/vite";
77
72
 
78
73
  export default defineConfig({
79
- plugins: [chaincss()],
74
+ plugins: [chaincss({ atomic: true })],
80
75
  });
81
76
  ```
82
77
 
83
- ---
84
78
 
85
- ## Core API
79
+ # Core API
80
+
81
+ ## The Chain
86
82
 
87
- ### Basic Chain
83
+ Every style starts with `chain()` and ends with `$el()`.
88
84
 
89
85
  ```ts
90
86
  import { chain } from "chaincss";
@@ -96,9 +92,37 @@ const styles = chain()
96
92
  .$el("my-component");
97
93
  ```
98
94
 
99
- ---
95
+ ## Smart Chain (Auto-Detection)
96
+
97
+ ```ts
98
+ import { smartChain } from "chaincss";
99
+
100
+ const styles = smartChain()
101
+ .display("flex")
102
+ .padding(20)
103
+ .color(props.textColor)
104
+ .fontSize(theme.sizes.lg)
105
+ .$el("hybrid-card");
106
+ ```
107
+
108
+ ## Runtime Injection
100
109
 
101
- ## Shorthands
110
+ ```ts
111
+ import { chain, injectChainStyles } from "chaincss";
112
+
113
+ const heading = chain()
114
+ .fs(48)
115
+ .fw(800)
116
+ .textGradient(["#6366f1", "#06b6d4"])
117
+ .$el("h1");
118
+
119
+ injectChainStyles({ heading });
120
+ ```
121
+
122
+
123
+ # Feature Reference
124
+
125
+ ## Shorthands (80+)
102
126
 
103
127
  ```ts
104
128
  chain()
@@ -111,14 +135,17 @@ chain()
111
135
  .c("#333")
112
136
  .w(200)
113
137
  .h(100)
114
- .d("flex");
138
+ .d("flex")
139
+ .z(10)
140
+ .op(0.5)
141
+ .ov("hidden")
142
+ .pos("relative");
115
143
  ```
116
144
 
117
- ---
118
145
 
119
- ## Macros
146
+ ## Macros (57)
120
147
 
121
- ### Layout
148
+ ### Layout & Display
122
149
 
123
150
  ```ts
124
151
  chain().flex();
@@ -128,6 +155,9 @@ chain().flexCenter();
128
155
  chain().gridCenter();
129
156
  chain().stack(16);
130
157
  chain().cols(3);
158
+ chain().rows(2);
159
+ chain().bento(4);
160
+ chain().gridTable("200px");
131
161
  ```
132
162
 
133
163
  ### Spacing
@@ -139,21 +169,87 @@ chain().px(16);
139
169
  chain().py(24);
140
170
  chain().size(50);
141
171
  chain().gap(16);
172
+ chain().gapX(8);
173
+ chain().gapY(12);
174
+ chain().inset(0);
175
+ chain().insetX(16);
176
+ chain().insetY(8);
177
+ ```
178
+
179
+ ### Borders
180
+
181
+ ```ts
182
+ chain().borderX("1px solid red");
183
+ chain().borderY("1px solid blue");
142
184
  ```
143
185
 
144
- ---
186
+ ### Positioning
187
+
188
+ ```ts
189
+ chain().absolute({ top: 0, left: 0 });
190
+ chain().fixed({ top: 0, right: 0 });
191
+ chain().sticky({ top: 0 });
192
+ chain().relative();
193
+ ```
194
+
195
+ ### Visibility & Behavior
196
+
197
+ ```ts
198
+ chain().hide();
199
+ chain().show();
200
+ chain().unselectable();
201
+ chain().scrollable("y");
202
+ chain().safeArea("top");
203
+ ```
204
+
205
+ ### Shapes & Typography
206
+
207
+ ```ts
208
+ chain().circle(50);
209
+ chain().square(40);
210
+ chain().pill();
211
+ chain().truncate();
212
+ chain().aspect("16/9");
213
+ chain().aspect("square");
214
+ chain().fluidText({ min: 16, max: 24 });
215
+ chain().lineClamp(3);
216
+ ```
217
+
218
+ ### Aesthetic Effects
219
+
220
+ ```ts
221
+ chain().glass();
222
+ chain().glass(5);
223
+ chain().glow("#ff0000");
224
+ chain().glow({ color: "#6366f1", size: 20 });
225
+ chain().textGradient(["#667eea", "#764ba2"]);
226
+ chain().meshGradient(["#f0f", "#0ff", "#ff0", "#0f0"]);
227
+ chain().noise(0.05);
228
+ chain().shimmer();
229
+ ```
145
230
 
146
- ## States & Interactions
231
+ ### State & Interactions
147
232
 
148
233
  ```ts
234
+ chain().clickScale(0.95);
235
+ chain().pressable();
236
+ chain().focusRing("#3b82f6");
237
+ chain().skeleton(true);
238
+
149
239
  chain()
150
- .hover()
151
- .background("#2563eb")
152
- .transform("scale(1.05)")
153
- .end();
240
+ .dark(c => c.bg("#1a202c").c("white"))
241
+ .light(c => c.bg("white").c("#1a202c"));
154
242
  ```
155
243
 
156
- ---
244
+ ### Utility
245
+
246
+ ```ts
247
+ chain().fullScreen();
248
+ chain().containerMacro(1200);
249
+ chain().outlineDebug();
250
+ chain().parallax(2);
251
+ chain().frostedNav(15);
252
+ ```
157
253
 
158
254
  ## Conditional Styles
159
255
 
@@ -165,45 +261,165 @@ chain()
165
261
  .$el("stateful-btn");
166
262
  ```
167
263
 
168
- ---
169
-
170
264
  ## Nested Selectors
171
265
 
172
266
  ```ts
173
267
  chain()
174
268
  .display("flex")
175
269
  .nest("& > *", c => c.flex(1))
270
+ .nest("&:first-child", c => c.fontWeight(700))
176
271
  .nest(".child", c => c.color("red"))
177
272
  .$el("flex-container");
178
273
  ```
179
274
 
180
- ---
275
+ ### Mixins with use()
181
276
 
182
- ## Responsive
277
+ ```ts
278
+ const shared = { display: "flex", alignItems: "center", gap: 8 };
279
+ chain().use(shared).padding(20).$el("reused");
280
+ ```
281
+
282
+ ## Responsive Design
183
283
 
184
284
  ```ts
185
285
  chain()
186
286
  .display("flex")
187
287
  .flexDirection("column")
188
288
  .responsive("md", c => c.flexDirection("row"))
289
+ .media("(min-width: 1024px)", c => c.maxWidth(1200))
189
290
  .$el("responsive");
190
291
  ```
191
292
 
192
- ---
293
+ **Built-in breakpoints (20):** `sm`, `md`, `lg`, `xl`, `2xl`, `mobile`, `tablet`, `desktop`, `portrait`, `landscape`, `dark`, `light`, `reducedMotion`, `highContrast`, `print`, `hover`, `no-hover`, `fine`, `coarse`
193
294
 
194
- ## Animations
295
+ ## Transform Methods
195
296
 
196
297
  ```ts
197
298
  chain()
198
- .fadeIn()
199
- .slideInUp()
200
- .zoomIn()
201
- .$el("animated");
299
+ .scale(1.1)
300
+ .rotate("45deg")
301
+ .x(10)
302
+ .y(20)
303
+ .skew("5deg")
304
+ .$el("transformed");
202
305
  ```
203
306
 
204
- ---
307
+ ### Math Helpers (15)
308
+
309
+ ```ts
310
+ chain()
311
+ .width(helpers.calc("100% - 20px"))
312
+ .fontSize(helpers.clamp(16, 4, 24))
313
+ .margin(helpers.add(10, 20))
314
+ .$el("calculated");
315
+
316
+ // helpers.add(), .sub(), .mul(), .div(), .sum(), .difference()
317
+ // helpers.mpx(), .rem(), .em(), .percent(), .vw(), .vh()
318
+ // helpers.min(), .max(), .clamp(), .round(), .rgba(), .hsla()
319
+ // helpers.fluidType(min, max, minWidth, maxWidth)
320
+ ```
205
321
 
206
- ## CLI
322
+ ## Design Tokens
323
+
324
+ ```ts
325
+ import { createTokens } from "chaincss";
326
+
327
+ const tokens = createTokens({
328
+ colors: {
329
+ primary: "#6366f1",
330
+ secondary: "#10b981",
331
+ },
332
+ spacing: {
333
+ sm: "8px",
334
+ md: "16px",
335
+ lg: "24px",
336
+ },
337
+ });
338
+ ```
339
+
340
+ ### Theme Contracts
341
+
342
+ ```ts
343
+ import { createThemeContract, createTheme, validateTheme } from "chaincss";
344
+
345
+ const contract = createThemeContract({
346
+ colors: { primary: "", background: "" },
347
+ spacing: { sm: "", md: "" },
348
+ });
349
+
350
+ const light = createTheme(contract, {
351
+ colors: { primary: "#3b82f6", background: "#fff" },
352
+ spacing: { sm: "8px", md: "16px" },
353
+ });
354
+
355
+ const theme = new Theme(light);
356
+ theme.toCSSVariables("my-theme"); // -> :root { --my-theme-colors-primary: #3b82f6; ... }
357
+ ```
358
+
359
+ ## Recipe System (Variants)
360
+
361
+ ```ts
362
+ import { recipe } from "chaincss";
363
+
364
+ const button = recipe({
365
+ base: { selectors: ["btn"], display: "inline-flex", borderRadius: "8px", fontWeight: 600 },
366
+ variants: {
367
+ size: {
368
+ sm: { padding: "8px 16px", fontSize: "14px" },
369
+ lg: { padding: "16px 32px", fontSize: "18px" },
370
+ },
371
+ color: {
372
+ primary: { background: "#3b82f6", color: "white" },
373
+ danger: { background: "#ef4444", color: "white" },
374
+ },
375
+ },
376
+ defaultVariants: { size: "md", color: "primary" },
377
+ compoundVariants: [
378
+ { variants: { size: "lg", color: "primary" }, style: { fontWeight: 800 } },
379
+ ],
380
+ });
381
+
382
+ const styles = button({ size: "lg", color: "danger" });
383
+ ```
384
+
385
+ ### Animations (42 presets)
386
+
387
+ ```ts
388
+ chain().fadeIn().$el("el"); chain().slideInUp().$el("el"); chain().slideInUp().$el("el");
389
+ chain().zoomIn().$el("el"); chain().bounce().$el("el"); chain().bounce().$el("el");
390
+ chain().pulse().$el("el"); chain().spin().$el("el"); chain().spin().$el("el");
391
+ chain().shake().$el("el"); chain().wiggle().$el("el"); chain().wiggle().$el("el");
392
+ chain().float().$el("el"); chain().flash().$el("el"); chain().flash().$el("el");
393
+ chain().textReveal().$el("el");
394
+
395
+ // Custom animation
396
+ chain().animate("myName", { "0%": { opacity: 0 }, "100%": { opacity: 1 } }, { duration: "0.5s" }).$el("el");
397
+ ```
398
+
399
+ ### Suggestions Engine
400
+
401
+ ```ts
402
+ import { getSuggestion, getSuggestions } from "chaincss";
403
+
404
+ getSuggestion("bakcground"); // -> "background"
405
+ getSuggestion("felx"); // -> "flex"
406
+ getSuggestions("bordr"); // -> ["border", "borderW", "borderC"]
407
+ ```
408
+
409
+ ### Style Timeline
410
+
411
+ ```ts
412
+ import { enableTimeline, getStyleHistory, getStyleDiff } from "chaincss";
413
+
414
+ enableTimeline(true);
415
+ // ... compile styles ...
416
+ const history = getStyleHistory();
417
+ const diff = getStyleDiff(snapshotId1, snapshotId2);
418
+ // -> { added: {...}, removed: {...}, modified: {...} }
419
+ ```
420
+
421
+
422
+ # CLI
207
423
 
208
424
  ```bash
209
425
  chaincss init
@@ -211,37 +427,148 @@ chaincss build
211
427
  chaincss watch
212
428
  chaincss cache clear
213
429
  chaincss cache stats
430
+ chaincss timeline list
214
431
  ```
215
432
 
216
- ---
217
433
 
218
- ## Configuration
434
+ # Configuration
219
435
 
220
436
  ```ts
437
+ // chaincss.config.js
221
438
  export default {
222
439
  inputs: ["src/**/*.chain.{js,ts}", "src/**/*.tsx"],
223
- output: { cssFile: "global.css", minify: true },
440
+
441
+ output: {
442
+ cssFile: "global.css",
443
+ minify: true,
444
+ },
445
+
446
+ atomic: {
447
+ enabled: true,
448
+ mode: "hybrid",
449
+ threshold: 2,
450
+ naming: "hash",
451
+ },
452
+
453
+ breakpoints: {
454
+ sm: "(min-width: 640px)",
455
+ md: "(min-width: 768px)",
456
+ },
457
+
458
+ tokens: {
459
+ enabled: true,
460
+ prefix: "$",
461
+ },
224
462
  };
225
463
  ```
226
464
 
227
- ---
228
465
 
229
- ## Contributing
466
+ # Framework Integration
467
+
468
+ ## React
469
+
470
+ ```tsx
471
+ import { chain } from "chaincss";
472
+
473
+ function Card() {
474
+ const styles = chain()
475
+ .bg("white")
476
+ .p(24)
477
+ .rounded(12)
478
+ .$el("card");
479
+
480
+ return (
481
+ <div className={styles.selectors[0]}>
482
+ Content
483
+ </div>
484
+ );
485
+ }
486
+ ```
487
+
488
+ ## Vue
489
+
490
+ ```ts
491
+ import { chain } from "chaincss";
492
+
493
+ const styles = chain().display("grid").cols(3).gap(16).$el("grid");
494
+ // <div :class="styles.selectors[0]">
495
+ ```
496
+
497
+ ## Svelte
498
+
499
+ ```ts
500
+ import { chain } from "chaincss";
501
+
502
+ const styles = chain().flex().center().$el("centered");
503
+ // <div class={styles.selectors[0]}>
504
+ ```
505
+
506
+ ### Vanilla JS
507
+
508
+ ```html
509
+ <script type="module">
510
+ import { chain, injectChainStyles } from "https://cdn.jsdelivr.net/npm/chaincss/dist/browser.js";
511
+ const h1 = chain()
512
+ .fs(48)
513
+ .fw(800)
514
+ .textGradient(["#6366f1","#06b6d4"])
515
+ .$el("h1");
516
+
517
+ injectChainStyles({ h1 });
518
+
519
+ document.body.innerHTML = '<h1 class="' + h1.selectors[0] + '">Hello!</h1>';
520
+ </script>
521
+ ```
522
+
523
+
524
+ ## Complete Feature List
525
+
526
+ | Category | Count | Details |
527
+ |----------|-------|---------|
528
+ | Macros | 57 | Layout, spacing, borders, positioning, visibility, shapes, effects, state, utility |
529
+ | Shorthand Properties | 80 | 1-to-1 CSS property mappings |
530
+ | Animation Presets | 42 | Fades, slides, zooms, bounces, shakes, spins, flips, special effects |
531
+ | Breakpoints | 20 | Mobile-first, desktop-first, device-specific, feature queries |
532
+ | Chain API Methods | 30+ | hover, nest, when, use, responsive, media, supports, containerQuery, layer |
533
+ | Math Helpers | 15 | calc, add, sub, mul, div, clamp, min, max, unit conversions, fluidType |
534
+ | CSS Properties | 300+ | Every standard CSS property via type definitions |
535
+ | CLI Commands | 5 | init, build, watch, cache, timeline |
536
+ | Framework Integrations | 4 | React, Vue, Svelte, Solid |
537
+ | Plugins | 2 | Vite, Webpack |
538
+ | Bundles | 5 | Main, Runtime, Browser, Compiler, CLI |
539
+ | React Hooks | 6 | useSmartStyles, createSmartComponent, useChainStyles, useDynamicChainStyles, useThemeChainStyles, withSmartStyles |
540
+ | Design Systems | 3 | Tokens, Theme Contracts, Recipes |
541
+ | Dev Tools | 3 | Suggestions Engine, Timeline, Component Generator |
542
+ | Tests | 258 | 18 test files, 0 failures |
543
+
544
+
545
+ # Performance
546
+
547
+ - Zero runtime for static styles
548
+ - Atomic CSS extraction
549
+ - Smart static/dynamic splitting
550
+ - LRU persistent caching
551
+ - Shared property deduplication
552
+
553
+
554
+ # Contributing
230
555
 
231
556
  ```bash
232
557
  git clone https://github.com/melcanz08/chaincss.git
558
+
233
559
  cd chaincss
560
+
234
561
  npm install
562
+
235
563
  npm test
236
564
  ```
237
565
 
238
- ---
239
566
 
240
- ## License
567
+ # License
241
568
 
242
569
  MIT © Rommel Caneos
243
570
 
244
571
  <p align="center">
245
- <strong>ChainCSS</strong> — Write styles like JavaScript. Ship zero runtime.
572
+ <strong>ChainCSS</strong> — Write styles like JavaScript. Ship zero runtime.<br>
573
+ <a href="https://chaincss.dev">chaincss.dev</a>
246
574
  </p>
247
-