chaincss 2.0.6 → 2.1.0
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/CHANGELOG.md +30 -0
- package/CODE_OF_CONDUCT.md +21 -0
- package/CONTRIBUTING.md +28 -0
- package/README.md +454 -231
- package/demo/demo/node_modules/caniuse-db/fulldata-json/data-2.0.json +1 -0
- package/demo/index.html +16 -0
- package/demo/package.json +20 -0
- package/demo/src/App.tsx +117 -0
- package/demo/src/chaincss-barrel.ts +9 -0
- package/demo/src/main.tsx +8 -0
- package/demo/src/styles.chain.ts +300 -0
- package/demo/vite.config.ts +46 -0
- package/dist/cli/commands/build.d.ts +0 -1
- package/dist/cli/commands/cache.d.ts +1 -0
- package/dist/cli/commands/init.d.ts +6 -3
- package/dist/cli/commands/timeline.d.ts +0 -1
- package/dist/cli/commands/watch.d.ts +0 -1
- package/dist/cli/index.d.ts +0 -1
- package/dist/cli/index.js +3213 -5296
- package/dist/cli/types.d.ts +51 -20
- package/dist/cli/utils/config-loader.d.ts +0 -1
- package/dist/cli/utils/file-utils.d.ts +27 -3
- package/dist/cli/utils/logger.d.ts +0 -1
- package/dist/compiler/Chain.d.ts +215 -0
- package/dist/compiler/animations.d.ts +76 -0
- package/dist/compiler/atomic-optimizer.d.ts +47 -12
- package/dist/compiler/breakpoints.d.ts +46 -0
- package/dist/compiler/btt.d.ts +36 -60
- package/dist/compiler/cache-manager.d.ts +58 -4
- package/dist/compiler/commonProps.d.ts +0 -1
- package/dist/compiler/content-addressable-cache.d.ts +78 -0
- package/dist/compiler/helpers.d.ts +54 -0
- package/dist/compiler/index.d.ts +16 -9
- package/dist/compiler/index.js +4450 -4316
- package/dist/compiler/prefixer.d.ts +17 -1
- package/dist/compiler/shorthands.d.ts +28 -0
- package/dist/compiler/suggestions.d.ts +43 -0
- package/dist/compiler/theme-contract.d.ts +16 -27
- package/dist/compiler/token-resolver.d.ts +69 -0
- package/dist/compiler/tokens.d.ts +33 -8
- package/dist/core/auto-detector.d.ts +34 -0
- package/dist/core/common-utils.d.ts +97 -0
- package/dist/core/compiler.d.ts +63 -23
- package/dist/core/constants.d.ts +137 -36
- package/dist/core/smart-chain.d.ts +3 -0
- package/dist/core/types.d.ts +122 -15
- package/dist/core/utils.d.ts +134 -17
- package/dist/index.d.ts +52 -8
- package/dist/index.js +7090 -5578
- package/dist/plugins/vite.d.ts +7 -5
- package/dist/plugins/vite.js +2964 -25641
- package/dist/plugins/webpack.d.ts +24 -1
- package/dist/plugins/webpack.js +209 -72
- package/dist/runtime/Chain.d.ts +32 -0
- package/dist/runtime/auto-hooks.d.ts +11 -0
- package/dist/runtime/hmr.d.ts +22 -2
- package/dist/runtime/index.d.ts +3 -2
- package/dist/runtime/index.js +3649 -301
- package/dist/runtime/injector.d.ts +39 -71
- package/dist/runtime/react.d.ts +17 -12
- package/dist/runtime/svelte.d.ts +15 -0
- package/dist/runtime/types.d.ts +126 -4
- package/dist/runtime/utils.d.ts +0 -1
- package/dist/runtime/vue.d.ts +34 -14
- package/package.json +59 -66
- package/src/cli/commands/build.ts +133 -0
- package/src/cli/commands/cache.ts +371 -0
- package/src/cli/commands/init.ts +230 -0
- package/src/cli/commands/timeline.ts +435 -0
- package/src/cli/commands/watch.ts +211 -0
- package/src/cli/index.ts +226 -0
- package/src/cli/types.ts +100 -0
- package/src/cli/utils/config-loader.ts +174 -0
- package/src/cli/utils/file-utils.ts +139 -0
- package/src/cli/utils/logger.ts +74 -0
- package/src/compiler/Chain.ts +831 -0
- package/src/compiler/animations.ts +517 -0
- package/src/compiler/atomic-optimizer.ts +786 -0
- package/src/compiler/breakpoints.ts +347 -0
- package/src/compiler/btt.ts +1147 -0
- package/src/compiler/cache-manager.ts +446 -0
- package/src/compiler/commonProps.ts +18 -0
- package/src/compiler/content-addressable-cache.ts +478 -0
- package/src/compiler/helpers.ts +407 -0
- package/src/compiler/index.ts +72 -0
- package/src/compiler/prefixer.ts +724 -0
- package/src/compiler/shorthands.ts +558 -0
- package/src/compiler/suggestions.ts +436 -0
- package/src/compiler/theme-contract.ts +197 -0
- package/src/compiler/token-resolver.ts +241 -0
- package/src/compiler/tokens.ts +612 -0
- package/src/core/auto-detector.ts +187 -0
- package/src/core/common-utils.ts +423 -0
- package/src/core/compiler.ts +835 -0
- package/src/core/constants.ts +424 -0
- package/src/core/index.ts +107 -0
- package/src/core/smart-chain.ts +163 -0
- package/src/core/types.ts +257 -0
- package/src/core/utils.ts +598 -0
- package/src/index.ts +208 -0
- package/src/plugins/vite.d.ts +316 -0
- package/src/plugins/vite.ts +424 -0
- package/src/plugins/webpack.d.ts +289 -0
- package/src/plugins/webpack.ts +416 -0
- package/src/runtime/Chain.ts +242 -0
- package/src/runtime/auto-hooks.tsx +127 -0
- package/src/runtime/auto-vue.ts +72 -0
- package/src/runtime/hmr.ts +212 -0
- package/src/runtime/index.ts +82 -0
- package/src/runtime/injector.ts +273 -0
- package/src/runtime/react.tsx +269 -0
- package/src/runtime/svelte.ts +15 -0
- package/src/runtime/types.ts +256 -0
- package/src/runtime/utils.ts +128 -0
- package/src/runtime/vite-env.d.ts +120 -0
- package/src/runtime/vue.ts +231 -0
- package/tsconfig.build.json +41 -0
- package/tsconfig.json +25 -0
- package/tsconfig.runtimes.json +18 -0
- package/dist/cli/cli.cjs +0 -7
- package/dist/cli/commands/build.d.ts.map +0 -1
- package/dist/cli/commands/compile.d.ts +0 -3
- package/dist/cli/commands/compile.d.ts.map +0 -1
- package/dist/cli/commands/init.d.ts.map +0 -1
- package/dist/cli/commands/timeline.d.ts.map +0 -1
- package/dist/cli/commands/watch.d.ts.map +0 -1
- package/dist/cli/index.d.ts.map +0 -1
- package/dist/cli/types.d.ts.map +0 -1
- package/dist/cli/utils/config-loader.d.ts.map +0 -1
- package/dist/cli/utils/file-utils.d.ts.map +0 -1
- package/dist/cli/utils/logger.d.ts.map +0 -1
- package/dist/compiler/atomic-optimizer.d.ts.map +0 -1
- package/dist/compiler/btt.d.ts.map +0 -1
- package/dist/compiler/cache-manager.d.ts.map +0 -1
- package/dist/compiler/commonProps.d.ts.map +0 -1
- package/dist/compiler/index.d.ts.map +0 -1
- package/dist/compiler/prefixer.d.ts.map +0 -1
- package/dist/compiler/theme-contract.d.ts.map +0 -1
- package/dist/compiler/tokens.d.ts.map +0 -1
- package/dist/compiler/types.d.ts +0 -57
- package/dist/compiler/types.d.ts.map +0 -1
- package/dist/core/compiler.d.ts.map +0 -1
- package/dist/core/constants.d.ts.map +0 -1
- package/dist/core/index.d.ts +0 -4
- package/dist/core/index.d.ts.map +0 -1
- package/dist/core/types.d.ts.map +0 -1
- package/dist/core/utils.d.ts.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/plugins/vite.d.ts.map +0 -1
- package/dist/plugins/webpack.d.ts.map +0 -1
- package/dist/runtime/hmr.d.ts.map +0 -1
- package/dist/runtime/index.d.ts.map +0 -1
- package/dist/runtime/injector.d.ts.map +0 -1
- package/dist/runtime/react.d.ts.map +0 -1
- package/dist/runtime/react.js +0 -270
- package/dist/runtime/types.d.ts.map +0 -1
- package/dist/runtime/utils.d.ts.map +0 -1
- package/dist/runtime/vue.d.ts.map +0 -1
- package/dist/runtime/vue.js +0 -232
package/README.md
CHANGED
|
@@ -1,274 +1,497 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
>
|
|
8
|
-
|
|
9
|
-
>
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
|
62
|
-
|
|
63
|
-
| **
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
```
|
|
70
|
-
src/
|
|
71
|
-
├── components/
|
|
72
|
-
│ └── Button/
|
|
73
|
-
│ ├── Button.tsx
|
|
74
|
-
│ └── styles/
|
|
75
|
-
│ ├── button.chain.js # Source styles
|
|
76
|
-
│ ├── button.class.js # Generated class names
|
|
77
|
-
│ └── button.css # Generated CSS
|
|
78
|
-
├── global-style/
|
|
79
|
-
│ ├── global.chain.js # Global styles
|
|
80
|
-
│ └── global.css # Combined CSS
|
|
81
|
-
└── chaincss.config.js # Configuration
|
|
82
|
-
```
|
|
83
|
-
|
|
84
|
-
## 📦 Installation
|
|
85
|
-
|
|
86
|
-
```bash
|
|
1
|
+
<p align="center">
|
|
2
|
+
<h1 align="center">ChainCSS</h1>
|
|
3
|
+
<p align="center">
|
|
4
|
+
<strong>The first CSS-in-JS library with true auto-detection mixed mode.</strong><br>
|
|
5
|
+
Zero runtime by default. Dynamic when you need it. No compromises.
|
|
6
|
+
</p>
|
|
7
|
+
</p>
|
|
8
|
+
|
|
9
|
+
<p align="center">
|
|
10
|
+
<a href="https://www.npmjs.com/package/chaincss"><img src="https://img.shields.io/npm/v/chaincss" alt="npm"></a>
|
|
11
|
+
<a href="https://github.com/melcanz08/chaincss/blob/main/LICENSE"><img src="https://img.shields.io/github/license/melcanz08/chaincss" alt="license"></a>
|
|
12
|
+
<a href="https://chaincss.dev"><img src="https://img.shields.io/badge/docs-chaincss.dev-blue" alt="docs"></a>
|
|
13
|
+
</p>
|
|
14
|
+
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
## What is ChainCSS?
|
|
18
|
+
|
|
19
|
+
ChainCSS lets you write styles as **native JavaScript method chains** instead of CSS strings or object literals. It auto-detects which parts of your styles are static (compile to zero-runtime CSS) and which are dynamic (stay in JS), then splits them automatically.
|
|
20
|
+
|
|
21
|
+
import { chain } from "chaincss";
|
|
22
|
+
|
|
23
|
+
const card = chain()
|
|
24
|
+
.display("flex")
|
|
25
|
+
.flexDirection("column")
|
|
26
|
+
.gap(16)
|
|
27
|
+
.padding(24)
|
|
28
|
+
.background("white")
|
|
29
|
+
.borderRadius(12)
|
|
30
|
+
.hover()
|
|
31
|
+
.boxShadow("0 4px 12px rgba(0,0,0,0.15)")
|
|
32
|
+
.transform("translateY(-2px)")
|
|
33
|
+
.end()
|
|
34
|
+
.$el("card");
|
|
35
|
+
text
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
**No CSS syntax. No template literals. No object literals. Just JavaScript.**
|
|
39
|
+
|
|
40
|
+
---
|
|
41
|
+
|
|
42
|
+
## The Killer Feature: Auto-Detection Mixed Mode
|
|
43
|
+
|
|
44
|
+
ChainCSS automatically detects which styles are static and which are dynamic.
|
|
45
|
+
|
|
46
|
+
import { smartChain } from "chaincss";
|
|
47
|
+
|
|
48
|
+
const styles = smartChain()
|
|
49
|
+
.display("flex") // static -> extracted to CSS file
|
|
50
|
+
.padding(20) // static -> extracted to CSS file
|
|
51
|
+
.color(props.textColor) // dynamic -> stays in JS
|
|
52
|
+
.fontSize(theme.sizes.lg) // dynamic -> stays in JS
|
|
53
|
+
.$el("dynamic-card");
|
|
54
|
+
text
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
| Library | Approach | Dynamic Support | Runtime Cost |
|
|
58
|
+
|---------|----------|----------------|-------------|
|
|
59
|
+
| Tailwind | Utility classes | No | Zero |
|
|
60
|
+
| Styled Components | Runtime CSS-in-JS | Yes | Full |
|
|
61
|
+
| Panda CSS | Build-time + recipes | Limited | Near-zero |
|
|
62
|
+
| Vanilla Extract | Build-time only | No | Zero |
|
|
63
|
+
| **ChainCSS** | **Auto-detection + split** | **Yes** | **Minimal** |
|
|
64
|
+
|
|
65
|
+
---
|
|
66
|
+
|
|
67
|
+
## Installation
|
|
68
|
+
|
|
87
69
|
npm install chaincss
|
|
88
|
-
|
|
70
|
+
text
|
|
89
71
|
|
|
90
|
-
## 🚀 Quick Start
|
|
91
72
|
|
|
92
|
-
###
|
|
73
|
+
### Quick Start with Vite
|
|
93
74
|
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
npx chaincss init --full
|
|
98
|
-
```
|
|
75
|
+
// vite.config.ts
|
|
76
|
+
import { defineConfig } from "vite";
|
|
77
|
+
import chaincss from "chaincss/plugin/vite";
|
|
99
78
|
|
|
100
|
-
|
|
79
|
+
export default defineConfig({
|
|
80
|
+
plugins: [chaincss()],
|
|
81
|
+
});
|
|
82
|
+
text
|
|
101
83
|
|
|
102
|
-
```javascript
|
|
103
|
-
// src/components/Button/styles/button.chain.js
|
|
104
|
-
import { $ } from 'chaincss';
|
|
105
84
|
|
|
106
|
-
|
|
107
|
-
.bg('#667eea')
|
|
108
|
-
.c('white')
|
|
109
|
-
.p('12px 24px')
|
|
110
|
-
.rounded('8px')
|
|
111
|
-
.cursor('pointer')
|
|
112
|
-
.hover()
|
|
113
|
-
.bg('#5a67d8')
|
|
114
|
-
.end()
|
|
115
|
-
.$el('.btn');
|
|
116
|
-
```
|
|
85
|
+
---
|
|
117
86
|
|
|
118
|
-
|
|
87
|
+
## Core API
|
|
119
88
|
|
|
120
|
-
|
|
121
|
-
npx chaincss build
|
|
122
|
-
```
|
|
89
|
+
### The Chain
|
|
123
90
|
|
|
124
|
-
|
|
91
|
+
import { chain } from "chaincss";
|
|
125
92
|
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
93
|
+
const styles = chain()
|
|
94
|
+
.display("flex")
|
|
95
|
+
.padding(20) // numbers auto-convert to px
|
|
96
|
+
.color("red")
|
|
97
|
+
.$el("my-component");
|
|
98
|
+
text
|
|
129
99
|
|
|
130
|
-
function Button() {
|
|
131
|
-
return <button className={button}>Click me</button>;
|
|
132
|
-
}
|
|
133
|
-
```
|
|
134
100
|
|
|
135
|
-
|
|
101
|
+
### Shorthands (80+)
|
|
102
|
+
|
|
103
|
+
chain()
|
|
104
|
+
.bg("#fff") // backgroundColor
|
|
105
|
+
.m(16) // margin
|
|
106
|
+
.p(20) // padding
|
|
107
|
+
.br(8) // borderRadius
|
|
108
|
+
.fs(16) // fontSize
|
|
109
|
+
.fw(700) // fontWeight
|
|
110
|
+
.c("#333") // color
|
|
111
|
+
.w(200) // width
|
|
112
|
+
.h(100) // height
|
|
113
|
+
.d("flex") // display
|
|
114
|
+
text
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
### Macros (57 built-in)
|
|
118
|
+
|
|
119
|
+
**Layout:**
|
|
120
|
+
|
|
121
|
+
chain().flex() // display: flex
|
|
122
|
+
chain().grid() // display: grid
|
|
123
|
+
chain().center() // flex + align-items + justify-content center
|
|
124
|
+
chain().flexCenter() // flex centering
|
|
125
|
+
chain().gridCenter() // grid centering
|
|
126
|
+
chain().stack(16) // flex column with gap
|
|
127
|
+
chain().cols(3) // grid-template-columns: repeat(3, 1fr)
|
|
128
|
+
chain().bento(4) // bento grid layout
|
|
129
|
+
text
|
|
130
|
+
|
|
131
|
+
|
|
132
|
+
**Spacing:**
|
|
133
|
+
|
|
134
|
+
chain().mx(10) // margin-left + margin-right
|
|
135
|
+
chain().my(20) // margin-top + margin-bottom
|
|
136
|
+
chain().px(16) // padding-left + padding-right
|
|
137
|
+
chain().py(24) // padding-top + padding-bottom
|
|
138
|
+
chain().size(50) // width + height
|
|
139
|
+
chain().gap(16) // gap
|
|
140
|
+
text
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
**Positioning:**
|
|
144
|
+
|
|
145
|
+
chain().absolute({ top: 0, left: 0 })
|
|
146
|
+
chain().fixed({ top: 0, right: 0 })
|
|
147
|
+
chain().sticky({ top: 0 })
|
|
148
|
+
chain().relative()
|
|
149
|
+
text
|
|
150
|
+
|
|
151
|
+
|
|
152
|
+
**Visibility:**
|
|
153
|
+
|
|
154
|
+
chain().hide() // visibility: hidden + opacity: 0
|
|
155
|
+
chain().show() // visibility: visible + opacity: 1
|
|
156
|
+
chain().unselectable() // user-select: none
|
|
157
|
+
chain().scrollable("y") // overflow-y: auto
|
|
158
|
+
text
|
|
159
|
+
|
|
160
|
+
|
|
161
|
+
**Shapes:**
|
|
162
|
+
|
|
163
|
+
chain().circle(50) // width + height + border-radius: 50%
|
|
164
|
+
chain().square(40) // width + height
|
|
165
|
+
chain().pill() // border-radius: 9999px
|
|
166
|
+
chain().truncate() // text-overflow: ellipsis
|
|
167
|
+
chain().aspect("16/9") // aspect-ratio
|
|
168
|
+
text
|
|
169
|
+
|
|
170
|
+
|
|
171
|
+
**Aesthetic Effects:**
|
|
172
|
+
|
|
173
|
+
chain().glass() // backdrop-filter blur + semi-transparent bg
|
|
174
|
+
chain().glow("#ff0000") // box-shadow glow
|
|
175
|
+
chain().textGradient(["#667eea", "#764ba2"]) // gradient text
|
|
176
|
+
chain().meshGradient(["#f0f", "#0ff", "#ff0", "#0f0"]) // mesh gradient
|
|
177
|
+
chain().noise(0.05) // noise texture overlay
|
|
178
|
+
chain().shimmer() // loading shimmer effect
|
|
179
|
+
text
|
|
180
|
+
|
|
181
|
+
|
|
182
|
+
**State & Interactions:**
|
|
183
|
+
|
|
184
|
+
chain()
|
|
185
|
+
.hover()
|
|
186
|
+
.background("#2563eb")
|
|
187
|
+
.transform("scale(1.05)")
|
|
188
|
+
.end()
|
|
189
|
+
|
|
190
|
+
chain().clickScale(0.95) // scale on click
|
|
191
|
+
chain().pressable() // cursor pointer + hover effects
|
|
192
|
+
chain().focusRing("#3b82f6") // focus-visible ring
|
|
193
|
+
chain().skeleton(true) // loading skeleton animation
|
|
194
|
+
chain().dark(c => c.bg("#1a202c").c("white")) // dark mode
|
|
195
|
+
chain().light(c => c.bg("white").c("#1a202c")) // light mode
|
|
196
|
+
chain().children(c => c.gap(8)) // direct children styles
|
|
197
|
+
text
|
|
198
|
+
|
|
199
|
+
|
|
200
|
+
**Utility:**
|
|
201
|
+
|
|
202
|
+
chain().fullScreen() // fixed fullscreen overlay
|
|
203
|
+
chain().containerMacro(1200) // centered container
|
|
204
|
+
chain().outlineDebug() // debug outlines
|
|
205
|
+
chain().parallax(2) // parallax scrolling
|
|
206
|
+
chain().lineClamp(3) // text line clamp
|
|
207
|
+
chain().frostedNav(15) // frosted glass navigation
|
|
208
|
+
text
|
|
209
|
+
|
|
210
|
+
|
|
211
|
+
### Conditional Styles
|
|
212
|
+
|
|
213
|
+
chain()
|
|
214
|
+
.padding(12)
|
|
215
|
+
.when(isActive, c => c
|
|
216
|
+
.background("#10b981")
|
|
217
|
+
.color("white")
|
|
218
|
+
)
|
|
219
|
+
.when(isDisabled, c => c
|
|
220
|
+
.opacity(0.5)
|
|
221
|
+
.cursor("not-allowed")
|
|
222
|
+
)
|
|
223
|
+
.$el("stateful-btn");
|
|
224
|
+
text
|
|
225
|
+
|
|
226
|
+
|
|
227
|
+
### Nested Selectors
|
|
228
|
+
|
|
229
|
+
chain()
|
|
230
|
+
.display("flex")
|
|
231
|
+
.nest("& > *", c => c.flex(1))
|
|
232
|
+
.nest("&:first-child", c => c.fontWeight(700))
|
|
233
|
+
.nest(".child", c => c.color("red"))
|
|
234
|
+
.$el("flex-container");
|
|
235
|
+
text
|
|
236
|
+
|
|
237
|
+
|
|
238
|
+
### Mixins with use()
|
|
239
|
+
|
|
240
|
+
const sharedStyles = { display: "flex", alignItems: "center", gap: 8 };
|
|
241
|
+
chain().use(sharedStyles).padding(20).$el("reused");
|
|
242
|
+
text
|
|
243
|
+
|
|
136
244
|
|
|
137
245
|
### Responsive Design
|
|
138
246
|
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
.rounded('12px')
|
|
156
|
-
.$el('.card');
|
|
157
|
-
```
|
|
247
|
+
chain()
|
|
248
|
+
.display("flex")
|
|
249
|
+
.flexDirection("column")
|
|
250
|
+
.responsive("md", c => c.flexDirection("row"))
|
|
251
|
+
.media("(min-width: 1024px)", c => c.maxWidth(1200))
|
|
252
|
+
.$el("responsive");
|
|
253
|
+
text
|
|
254
|
+
|
|
255
|
+
|
|
256
|
+
Built-in breakpoints: sm, md, lg, xl, 2xl, mobile, tablet, desktop, dark, light, reducedMotion, highContrast, print, hover, portrait, landscape.
|
|
257
|
+
|
|
258
|
+
### Transform Methods
|
|
259
|
+
|
|
260
|
+
chain().scale(1.1).rotate("45deg").x(10).y(20).$el("transformed");
|
|
261
|
+
text
|
|
262
|
+
|
|
158
263
|
|
|
159
264
|
### Math Helpers
|
|
160
265
|
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
266
|
+
chain()
|
|
267
|
+
.width(chain().calc("100% - 20px"))
|
|
268
|
+
.fontSize(chain().clamp(16, 4, 24))
|
|
269
|
+
.margin(chain().add(10, 20))
|
|
270
|
+
.$el("calculated");
|
|
271
|
+
text
|
|
272
|
+
|
|
273
|
+
|
|
274
|
+
---
|
|
275
|
+
|
|
276
|
+
## Recipe System (Variants)
|
|
277
|
+
|
|
278
|
+
import { recipe } from "chaincss";
|
|
279
|
+
|
|
280
|
+
const button = recipe({
|
|
281
|
+
base: {
|
|
282
|
+
selectors: ["btn"],
|
|
283
|
+
display: "inline-flex",
|
|
284
|
+
borderRadius: "8px",
|
|
285
|
+
fontWeight: 600,
|
|
286
|
+
},
|
|
287
|
+
variants: {
|
|
288
|
+
size: {
|
|
289
|
+
sm: { padding: "8px 16px", fontSize: "14px" },
|
|
290
|
+
md: { padding: "12px 24px", fontSize: "16px" },
|
|
291
|
+
lg: { padding: "16px 32px", fontSize: "18px" },
|
|
292
|
+
},
|
|
293
|
+
color: {
|
|
294
|
+
primary: { background: "#3b82f6", color: "white" },
|
|
295
|
+
danger: { background: "#ef4444", color: "white" },
|
|
296
|
+
},
|
|
297
|
+
},
|
|
298
|
+
defaultVariants: { size: "md", color: "primary" },
|
|
299
|
+
compoundVariants: [
|
|
300
|
+
{
|
|
301
|
+
variants: { size: "lg", color: "primary" },
|
|
302
|
+
style: { fontWeight: 800 },
|
|
303
|
+
},
|
|
304
|
+
],
|
|
305
|
+
});
|
|
168
306
|
|
|
169
|
-
|
|
307
|
+
const styles = button({ size: "lg", color: "danger" });
|
|
308
|
+
text
|
|
170
309
|
|
|
171
|
-
```javascript
|
|
172
|
-
export const card = $
|
|
173
|
-
.bg('white')
|
|
174
|
-
.c('gray-800')
|
|
175
|
-
.p('20px')
|
|
176
|
-
.m('10px')
|
|
177
|
-
.rounded('8px')
|
|
178
|
-
.shadow('lg')
|
|
179
|
-
.$el('.card');
|
|
180
|
-
```
|
|
181
310
|
|
|
182
|
-
|
|
311
|
+
---
|
|
183
312
|
|
|
184
|
-
|
|
313
|
+
## Animations (42 built-in presets)
|
|
185
314
|
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
tablet: '(min-width: 769px) and (max-width: 1024px)',
|
|
200
|
-
desktop: '(min-width: 1025px)'
|
|
201
|
-
},
|
|
202
|
-
debug: false,
|
|
203
|
-
verbose: false
|
|
204
|
-
};
|
|
205
|
-
```
|
|
315
|
+
chain()
|
|
316
|
+
.fadeIn()
|
|
317
|
+
.slideInUp()
|
|
318
|
+
.zoomIn()
|
|
319
|
+
.bounce()
|
|
320
|
+
.pulse()
|
|
321
|
+
.spin()
|
|
322
|
+
.shake()
|
|
323
|
+
.wiggle()
|
|
324
|
+
.float()
|
|
325
|
+
.flash()
|
|
326
|
+
.textReveal()
|
|
327
|
+
.$el("animated");
|
|
206
328
|
|
|
207
|
-
|
|
329
|
+
// Custom animation
|
|
330
|
+
chain()
|
|
331
|
+
.animate("myKeyframes", {
|
|
332
|
+
"0%": { opacity: 0, transform: "scale(0.5)" },
|
|
333
|
+
"100%": { opacity: 1, transform: "scale(1)" },
|
|
334
|
+
}, { duration: "0.5s", timing: "ease-out" })
|
|
335
|
+
.$el("custom-anim");
|
|
336
|
+
text
|
|
208
337
|
|
|
209
|
-
For dynamic styles without build step:
|
|
210
338
|
|
|
211
|
-
|
|
212
|
-
import { useChainStyles } from 'chaincss/runtime';
|
|
339
|
+
---
|
|
213
340
|
|
|
214
|
-
|
|
215
|
-
const styles = useChainStyles({
|
|
216
|
-
button: {
|
|
217
|
-
backgroundColor: '#667eea',
|
|
218
|
-
color: 'white',
|
|
219
|
-
padding: '12px 24px'
|
|
220
|
-
}
|
|
221
|
-
});
|
|
222
|
-
|
|
223
|
-
return <button className={styles.button}>Click me</button>;
|
|
224
|
-
}
|
|
225
|
-
```
|
|
341
|
+
## Design Tokens
|
|
226
342
|
|
|
227
|
-
|
|
343
|
+
import { createTokens } from "chaincss";
|
|
228
344
|
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
| `chaincss build` | Build all styles |
|
|
234
|
-
| `chaincss build --timeline` | Build with timeline tracking |
|
|
235
|
-
| `chaincss watch` | Watch for changes |
|
|
236
|
-
| `chaincss clean` | Remove generated files |
|
|
345
|
+
const tokens = createTokens({
|
|
346
|
+
colors: { primary: "#3b82f6", secondary: "#10b981", danger: "#ef4444" },
|
|
347
|
+
spacing: { sm: "8px", md: "16px", lg: "24px" },
|
|
348
|
+
});
|
|
237
349
|
|
|
238
|
-
|
|
350
|
+
chain(true)
|
|
351
|
+
.color("colors.primary").padding("colors.primary").padding("spacing.md")
|
|
352
|
+
.$el("themed");
|
|
353
|
+
text
|
|
239
354
|
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
355
|
+
|
|
356
|
+
---
|
|
357
|
+
|
|
358
|
+
## Theme Contract
|
|
359
|
+
|
|
360
|
+
import { createThemeContract, createTheme, validateTheme } from "chaincss";
|
|
361
|
+
|
|
362
|
+
const contract = createThemeContract({
|
|
363
|
+
colors: { primary: "", background: "", text: "" },
|
|
364
|
+
});
|
|
365
|
+
|
|
366
|
+
const lightTheme = createTheme(contract, {
|
|
367
|
+
colors: { primary: "#3b82f6", background: "#ffffff", text: "#1a202c" },
|
|
368
|
+
});
|
|
369
|
+
|
|
370
|
+
const darkTheme = createTheme(contract, {
|
|
371
|
+
colors: { primary: "#60a5fa", background: "#1a202c", text: "#f7fafc" },
|
|
372
|
+
});
|
|
373
|
+
text
|
|
374
|
+
|
|
375
|
+
|
|
376
|
+
---
|
|
377
|
+
|
|
378
|
+
## Framework Integration
|
|
379
|
+
|
|
380
|
+
### React
|
|
381
|
+
|
|
382
|
+
import { chain } from "chaincss";
|
|
383
|
+
|
|
384
|
+
function Card() {
|
|
385
|
+
const styles = chain().bg("white").p(24).rounded(12).$el("card");
|
|
386
|
+
return <div className={styles.selectors[0]}>Content</div>;
|
|
249
387
|
}
|
|
250
|
-
|
|
388
|
+
text
|
|
389
|
+
|
|
390
|
+
|
|
391
|
+
### Vue
|
|
392
|
+
|
|
393
|
+
import { chain } from "chaincss";
|
|
394
|
+
const styles = chain().display("grid").cols(3).gap(16).$el("vue-grid");
|
|
395
|
+
// <div :class="styles.selectors[0]">
|
|
396
|
+
text
|
|
397
|
+
|
|
398
|
+
|
|
399
|
+
### Svelte
|
|
400
|
+
|
|
401
|
+
import { chain } from "chaincss";
|
|
402
|
+
const styles = chain().flex().center().$el("centered");
|
|
403
|
+
// <div class={styles.selectors[0]}>Content</div>
|
|
404
|
+
text
|
|
405
|
+
|
|
406
|
+
|
|
407
|
+
---
|
|
408
|
+
|
|
409
|
+
## Smart Chain (Auto-Detection)
|
|
410
|
+
|
|
411
|
+
import { smartChain, buildChain, runtimeChain } from "chaincss";
|
|
412
|
+
|
|
413
|
+
// Auto-detect
|
|
414
|
+
const styles = smartChain()
|
|
415
|
+
.display("flex") // static -> build
|
|
416
|
+
.color(dynamicVariable) // dynamic -> runtime
|
|
417
|
+
.$el("hybrid");
|
|
418
|
+
|
|
419
|
+
// Force build-time only
|
|
420
|
+
const static = buildChain().display("flex").$el("static");
|
|
421
|
+
|
|
422
|
+
// Force runtime only
|
|
423
|
+
const dynamic = runtimeChain().color(props.color).$el("runtime");
|
|
424
|
+
text
|
|
425
|
+
|
|
426
|
+
|
|
427
|
+
---
|
|
428
|
+
|
|
429
|
+
## CLI
|
|
430
|
+
|
|
431
|
+
chaincss init # Create config file
|
|
432
|
+
chaincss build # Build all styles
|
|
433
|
+
chaincss watch # Watch for changes
|
|
434
|
+
chaincss cache clear # Clear cache
|
|
435
|
+
chaincss cache stats # Cache statistics
|
|
436
|
+
chaincss timeline list # Style history
|
|
437
|
+
text
|
|
438
|
+
|
|
439
|
+
|
|
440
|
+
---
|
|
441
|
+
|
|
442
|
+
## Configuration
|
|
443
|
+
|
|
444
|
+
// chaincss.config.js
|
|
445
|
+
export default {
|
|
446
|
+
inputs: ["src//*.chain.{js,ts}", "src//*.tsx"],
|
|
447
|
+
output: { cssFile: "global.css", minify: true },
|
|
448
|
+
atomic: { enabled: true, mode: "hybrid", threshold: 2, naming: "hash" },
|
|
449
|
+
breakpoints: { sm: "(min-width: 640px)", md: "(min-width: 768px)", lg: "(min-width: 1024px)" },
|
|
450
|
+
tokens: { enabled: true, prefix: "$" },
|
|
451
|
+
};
|
|
452
|
+
text
|
|
453
|
+
|
|
454
|
+
|
|
455
|
+
---
|
|
456
|
+
|
|
457
|
+
## Complete Feature List
|
|
251
458
|
|
|
252
|
-
|
|
459
|
+
| Category | Count |
|
|
460
|
+
|----------|-------|
|
|
461
|
+
| Macros | 57 |
|
|
462
|
+
| Shorthand Properties | 80 |
|
|
463
|
+
| Animation Presets | 42 |
|
|
464
|
+
| Breakpoints | 20 |
|
|
465
|
+
| Chain API Methods | 30+ |
|
|
466
|
+
| Math Helpers | 15 |
|
|
467
|
+
| CSS Properties | 300+ |
|
|
468
|
+
| CLI Commands | 5 |
|
|
469
|
+
| Framework Integrations | 4 (React, Vue, Svelte, Solid) |
|
|
470
|
+
| Plugins | 2 (Vite, Webpack) |
|
|
471
|
+
| React Hooks | 6 |
|
|
472
|
+
| Recipe System | Variants, defaultVariants, compoundVariants |
|
|
473
|
+
| Theme System | Theme, createThemeContract, validateTheme |
|
|
253
474
|
|
|
254
|
-
|
|
475
|
+
**Total: 550+ features | 210 tests | Zero-runtime by default**
|
|
255
476
|
|
|
256
|
-
|
|
477
|
+
---
|
|
257
478
|
|
|
258
|
-
|
|
259
|
-
- [Chainable API](https://chaincss.dev/docs/chainable-api)
|
|
260
|
-
- [Responsive Design](https://chaincss.dev/docs/responsive)
|
|
261
|
-
- [Animations](https://chaincss.dev/docs/animations)
|
|
262
|
-
- [Configuration](https://chaincss.dev/docs/configuration)
|
|
479
|
+
## Contributing
|
|
263
480
|
|
|
264
|
-
|
|
481
|
+
git clone https://github.com/melcanz08/chaincss.git
|
|
482
|
+
cd chaincss
|
|
483
|
+
npm install
|
|
484
|
+
npm test
|
|
485
|
+
text
|
|
265
486
|
|
|
266
|
-
Contributions are welcome! Please read our [Contributing Guide](CONTRIBUTING.md).
|
|
267
487
|
|
|
268
|
-
|
|
488
|
+
---
|
|
269
489
|
|
|
270
|
-
|
|
490
|
+
## License
|
|
271
491
|
|
|
272
|
-
|
|
492
|
+
MIT © Rommel Caneos
|
|
273
493
|
|
|
274
|
-
|
|
494
|
+
<p align="center">
|
|
495
|
+
<strong>ChainCSS</strong> — Write styles like JavaScript. Ship zero runtime.<br>
|
|
496
|
+
<a href="https://chaincss.dev">chaincss.dev</a>
|
|
497
|
+
</p>
|