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