chaincss 2.3.1 → 2.3.2
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 +236 -0
- package/chaincssTutorial.md +1168 -0
- package/dist/browser.js +94 -1
- package/dist/compiler/index.js +93 -0
- package/dist/compiler/intent-engine.d.ts +5 -0
- package/dist/compiler/suggestions.d.ts +2 -0
- package/dist/core/types.d.ts +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +121 -1
- package/dist/runtime/index.js +94 -1
- package/package.json +1 -1
- package/src/compiler/intent-engine.ts +28 -0
- package/src/compiler/suggestions.ts +32 -0
- package/src/core/types.ts +1 -0
- package/src/index.ts +1 -0
package/README.md
CHANGED
|
@@ -62,6 +62,242 @@ const hero = chain()
|
|
|
62
62
|
**No CSS syntax. No template literals. Compiler-enforced quality.**
|
|
63
63
|
|
|
64
64
|
|
|
65
|
+
# Constraint-Based Styling
|
|
66
|
+
|
|
67
|
+
Declare relationships, not values. The constraint solver compiles them to native CSS at build time.
|
|
68
|
+
|
|
69
|
+
**No runtime JS. No manual `calc()`. The compiler picks the best CSS feature.**
|
|
70
|
+
|
|
71
|
+
---
|
|
72
|
+
|
|
73
|
+
## 1. Aspect Ratios from Math
|
|
74
|
+
|
|
75
|
+
Describe the relationship between width and height:
|
|
76
|
+
|
|
77
|
+
```ts
|
|
78
|
+
chain()
|
|
79
|
+
.constrain("height", "= width * 0.5") // 2:1 ratio
|
|
80
|
+
.constrain("width", "< parent") // Don't overflow container
|
|
81
|
+
.$el("video");
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
### Compiles to
|
|
85
|
+
|
|
86
|
+
```css
|
|
87
|
+
.video {
|
|
88
|
+
aspect-ratio: 1 / 2;
|
|
89
|
+
max-width: 100%;
|
|
90
|
+
}
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
The solver detects `width * 0.5` and emits `aspect-ratio` instead of:
|
|
94
|
+
|
|
95
|
+
```css
|
|
96
|
+
height: calc(width * 0.5);
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
`aspect-ratio` has better performance and avoids layout shifts.
|
|
100
|
+
|
|
101
|
+
### Tailwind Equivalent
|
|
102
|
+
|
|
103
|
+
```txt
|
|
104
|
+
aspect-[2/1] max-w-full
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
### ChainCSS Difference
|
|
108
|
+
|
|
109
|
+
You write the math. The compiler writes the CSS.
|
|
110
|
+
|
|
111
|
+
---
|
|
112
|
+
|
|
113
|
+
## 2. Container-Aware Responsive Layouts
|
|
114
|
+
|
|
115
|
+
Use conditional constraints to generate `@container` queries automatically.
|
|
116
|
+
|
|
117
|
+
```ts
|
|
118
|
+
chain()
|
|
119
|
+
.constrain("columns", ">= 3 when > 768px")
|
|
120
|
+
.constrain("gap", "= 24px")
|
|
121
|
+
.$el("grid");
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
### Compiles to
|
|
125
|
+
|
|
126
|
+
```css
|
|
127
|
+
.grid {
|
|
128
|
+
gap: 24px;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
@container (min-width: 768px) {
|
|
132
|
+
.grid {
|
|
133
|
+
columns: 3;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
> Requires `container-type: inline-size` on the parent.
|
|
139
|
+
> ChainCSS adds it automatically when container constraints are detected.
|
|
140
|
+
|
|
141
|
+
---
|
|
142
|
+
|
|
143
|
+
## 3. Fluid Values with `clamp()`
|
|
144
|
+
|
|
145
|
+
Stop calculating `clamp()` manually.
|
|
146
|
+
|
|
147
|
+
```ts
|
|
148
|
+
chain()
|
|
149
|
+
.constrain("fontSize", "= clamp(14px, 5vw, 24px)")
|
|
150
|
+
.constrain("padding", "= clamp(16px, 4vw, 32px)")
|
|
151
|
+
.$el("hero");
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
### Compiles to
|
|
155
|
+
|
|
156
|
+
```css
|
|
157
|
+
.hero {
|
|
158
|
+
font-size: clamp(14px, 5vw, 24px);
|
|
159
|
+
padding: clamp(16px, 4vw, 32px);
|
|
160
|
+
}
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
Works with:
|
|
164
|
+
|
|
165
|
+
- `clamp()`
|
|
166
|
+
- `min()`
|
|
167
|
+
- `max()`
|
|
168
|
+
- `calc()`
|
|
169
|
+
|
|
170
|
+
---
|
|
171
|
+
|
|
172
|
+
## 4. Scroll-Driven Sticky Positioning
|
|
173
|
+
|
|
174
|
+
"Stick this element until another element reaches the viewport."
|
|
175
|
+
|
|
176
|
+
```ts
|
|
177
|
+
chain()
|
|
178
|
+
.constrain("sidebar", "sticky until footer")
|
|
179
|
+
.$el("sidebar");
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
### Compiles to
|
|
183
|
+
|
|
184
|
+
```css
|
|
185
|
+
.sidebar {
|
|
186
|
+
position: sticky;
|
|
187
|
+
top: 0;
|
|
188
|
+
|
|
189
|
+
animation: sticky-sidebar 1s linear both;
|
|
190
|
+
animation-timeline: scroll();
|
|
191
|
+
animation-range: contain 0% contain 100%;
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
@keyframes sticky-sidebar {
|
|
195
|
+
to {
|
|
196
|
+
position: relative;
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
Zero JavaScript. Uses native `animation-timeline: scroll()` available in modern Chromium browsers.
|
|
202
|
+
|
|
203
|
+
---
|
|
204
|
+
|
|
205
|
+
## 5. Parent-Relative Constraints
|
|
206
|
+
|
|
207
|
+
Keep elements inside their parents without writing media queries.
|
|
208
|
+
|
|
209
|
+
```ts
|
|
210
|
+
chain()
|
|
211
|
+
.constrain("width", "< parent")
|
|
212
|
+
.constrain("width", "> 320px")
|
|
213
|
+
.$el("modal");
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
### Compiles to
|
|
217
|
+
|
|
218
|
+
```css
|
|
219
|
+
.modal {
|
|
220
|
+
max-width: 100%;
|
|
221
|
+
min-width: 320px;
|
|
222
|
+
}
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
---
|
|
226
|
+
|
|
227
|
+
# How It Works
|
|
228
|
+
|
|
229
|
+
The compiler parses constraint expressions and resolves them into the most optimal native CSS feature.
|
|
230
|
+
|
|
231
|
+
| You Write | Compiler Resolves To | Strategy |
|
|
232
|
+
|---|---|---|
|
|
233
|
+
| `width < parent` | `max-width: 100%` | Direct mapping |
|
|
234
|
+
| `height = width * 0.5` | `aspect-ratio: 1 / 2` | Aspect-ratio optimization |
|
|
235
|
+
| `fontSize = clamp(14, 5vw, 24)` | `font-size: clamp(...)` | Native clamp |
|
|
236
|
+
| `columns >= 3 when > 768px` | `@container (min-width: 768px)` | Container query |
|
|
237
|
+
| `sidebar sticky until footer` | `animation-timeline: scroll()` | Scroll timeline |
|
|
238
|
+
|
|
239
|
+
---
|
|
240
|
+
|
|
241
|
+
## Supported Operators
|
|
242
|
+
|
|
243
|
+
```txt
|
|
244
|
+
< > <= >= = !=
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
## Supported References
|
|
248
|
+
|
|
249
|
+
```txt
|
|
250
|
+
parent
|
|
251
|
+
viewport
|
|
252
|
+
self
|
|
253
|
+
sibling.width
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
## Supported Functions
|
|
257
|
+
|
|
258
|
+
```txt
|
|
259
|
+
clamp()
|
|
260
|
+
min()
|
|
261
|
+
max()
|
|
262
|
+
calc()
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
---
|
|
266
|
+
|
|
267
|
+
# Debugging Constraints
|
|
268
|
+
|
|
269
|
+
See how constraints were resolved during compilation.
|
|
270
|
+
|
|
271
|
+
## CLI
|
|
272
|
+
|
|
273
|
+
```bash
|
|
274
|
+
chaincss build --explain
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
### Output
|
|
278
|
+
|
|
279
|
+
```txt
|
|
280
|
+
card: height = width * 0.5 → aspect-ratio: 1/2
|
|
281
|
+
card: width < parent → max-width: 100%
|
|
282
|
+
```
|
|
283
|
+
|
|
284
|
+
---
|
|
285
|
+
|
|
286
|
+
## Programmatic Debugging
|
|
287
|
+
|
|
288
|
+
```ts
|
|
289
|
+
import { resolveConstraint } from "chaincss/compiler";
|
|
290
|
+
|
|
291
|
+
const result = resolveConstraint({
|
|
292
|
+
property: "height",
|
|
293
|
+
operator: "=",
|
|
294
|
+
expression: "width * 0.5",
|
|
295
|
+
});
|
|
296
|
+
|
|
297
|
+
console.log(result.explanation);
|
|
298
|
+
// "height = width * 0.5 → aspect-ratio: 1/2"
|
|
299
|
+
```
|
|
300
|
+
|
|
65
301
|
|
|
66
302
|
# What Makes ChainCSS Different
|
|
67
303
|
|