@chakrabortyrajarshi2005/chai-tailwind-css 1.0.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/README.md ADDED
@@ -0,0 +1,485 @@
1
+ # ☕ chai-css
2
+
3
+ > A lightweight, zero-dependency, custom Tailwind-like CSS engine you build yourself.
4
+ > Write `chai-` classes in your HTML — get real CSS applied at runtime.
5
+
6
+ ```html
7
+ <div class="chai-bg-slate-950 chai-px-24 chai-py-16 chai-rounded-12 chai-text-indigo-400">
8
+ Hello from chai ☕
9
+ </div>
10
+ ```
11
+
12
+ ---
13
+
14
+ ## What is chai-css?
15
+
16
+ chai-css is a **DIY utility-class CSS engine** inspired by Tailwind CSS. Instead of a build step or a CDN stylesheet, chai works by:
17
+
18
+ 1. **Scanning** the DOM for any element with a `chai-` class
19
+ 2. **Parsing** the class name into a `{ property, value }` pair
20
+ 3. **Applying** the CSS directly to the element as an inline style
21
+
22
+ No compiler. No config file. No stylesheet to ship. Just your JavaScript engine + your HTML.
23
+
24
+ ---
25
+
26
+ ## Project Structure
27
+
28
+ ```
29
+ your-project/
30
+ ├── index.html
31
+ ├── src/
32
+ │ └── main.js ← entry point (run chai here)
33
+ └── config/
34
+ └── propertyMap.js ← all shorthand keys + color palette
35
+ ```
36
+
37
+ The engine itself lives in four files:
38
+
39
+ ```
40
+ src/
41
+ ├── main.js ← entry point: connects everything
42
+ ├── scanner.js ← finds all chai- elements in the DOM
43
+ ├── parser.js ← breaks "chai-bg-red-500" into { property, value }
44
+ └── apply.js ← sets the actual CSS on the element
45
+ ```
46
+
47
+ ---
48
+
49
+ ## How It Works
50
+
51
+ ### 1. `scanner.js` — Find
52
+
53
+ Walks every element in the DOM and collects any class starting with `chai-`.
54
+
55
+ ```js
56
+ // Returns: [{ element: <div>, className: "chai-bg-red-500" }, ...]
57
+ scan()
58
+ ```
59
+
60
+ ### 2. `parser.js` — Parse
61
+
62
+ Splits the class name into a property key and a value.
63
+
64
+ ```
65
+ "chai-bg-red-500" → { property: "bg", value: "red-500" }
66
+ "chai-px-16" → { property: "px", value: "16" }
67
+ "chai-rounded-8" → { property: "rounded", value: "8" }
68
+ "chai-gridCols-3" → { property: "gridCols", value: "3" }
69
+ ```
70
+
71
+ The parser tries each possible split point left-to-right and picks the first one where the property key exists in `propertyMap`. This correctly handles color names like `red-500` that contain a dash.
72
+
73
+ ### 3. `apply.js` — Apply
74
+
75
+ Looks up the CSS property in `propertyMap`, resolves the value, and sets it.
76
+
77
+ ```
78
+ "bg" → "backgroundColor" → element.style.backgroundColor = "#ef4444"
79
+ "px" → ["paddingLeft","paddingRight"] → sets both at once
80
+ "text" → "color" → element.style.color = "#3b82f6"
81
+ ```
82
+
83
+ **Value resolution order:**
84
+ 1. Color name? (`red-500`) → look up hex in `categoryGroups.colors`
85
+ 2. Already has a unit? (`2rem`, `50%`) → use as-is
86
+ 3. Keyword? (`auto`, `flex`, `none`) → use as-is
87
+ 4. Plain number? (`16`, `8`) → append `px` automatically
88
+ 5. Anything else → use as-is (hex codes, CSS vars, etc.)
89
+
90
+ ### 4. `main.js` — Run
91
+
92
+ ```js
93
+ import { scan } from "./scanner.js";
94
+ import { parse } from "./parser.js";
95
+ import { applyStyle } from "./apply.js";
96
+
97
+ function run() {
98
+ scan().forEach(item => applyStyle(item.element, parse(item.className)));
99
+ }
100
+
101
+ document.readyState === "loading"
102
+ ? document.addEventListener("DOMContentLoaded", run)
103
+ : run();
104
+ ```
105
+
106
+ ---
107
+
108
+ ## Class Syntax
109
+
110
+ ```
111
+ chai-{property}-{value}
112
+ ```
113
+
114
+ | Part | Example | What it is |
115
+ |---|---|---|
116
+ | `chai-` | always | required prefix |
117
+ | `{property}` | `bg`, `px`, `rounded` | key from `propertyMap` |
118
+ | `{value}` | `red-500`, `16`, `auto` | color name, number, or keyword |
119
+
120
+ ---
121
+
122
+ ## Property Reference
123
+
124
+ ### Spacing
125
+
126
+ | Class | CSS Property |
127
+ |---|---|
128
+ | `chai-p-{n}` | `padding` |
129
+ | `chai-px-{n}` | `paddingLeft` + `paddingRight` |
130
+ | `chai-py-{n}` | `paddingTop` + `paddingBottom` |
131
+ | `chai-pt-{n}` | `paddingTop` |
132
+ | `chai-pb-{n}` | `paddingBottom` |
133
+ | `chai-pl-{n}` | `paddingLeft` |
134
+ | `chai-pr-{n}` | `paddingRight` |
135
+ | `chai-m-{n}` | `margin` |
136
+ | `chai-mx-{n}` | `marginLeft` + `marginRight` |
137
+ | `chai-my-{n}` | `marginTop` + `marginBottom` |
138
+ | `chai-mt-{n}` | `marginTop` |
139
+ | `chai-mb-{n}` | `marginBottom` |
140
+ | `chai-ml-{n}` | `marginLeft` |
141
+ | `chai-mr-{n}` | `marginRight` |
142
+ | `chai-gap-{n}` | `gap` |
143
+ | `chai-gapX-{n}` | `columnGap` |
144
+ | `chai-gapY-{n}` | `rowGap` |
145
+
146
+ ### Sizing
147
+
148
+ | Class | CSS Property |
149
+ |---|---|
150
+ | `chai-w-{n}` | `width` |
151
+ | `chai-h-{n}` | `height` |
152
+ | `chai-size-{n}` | `width` + `height` |
153
+ | `chai-minW-{n}` | `minWidth` |
154
+ | `chai-maxW-{n}` | `maxWidth` |
155
+ | `chai-minH-{n}` | `minHeight` |
156
+ | `chai-maxH-{n}` | `maxHeight` |
157
+
158
+ ### Colors
159
+
160
+ | Class | CSS Property |
161
+ |---|---|
162
+ | `chai-bg-{color}` | `backgroundColor` |
163
+ | `chai-text-{color}` | `color` |
164
+ | `chai-fill-{color}` | `fill` |
165
+ | `chai-stroke-{color}` | `stroke` |
166
+ | `chai-borderColor-{color}` | `borderColor` |
167
+ | `chai-outlineColor-{color}` | `outlineColor` |
168
+ | `chai-accentColor-{color}` | `accentColor` |
169
+ | `chai-caretColor-{color}` | `caretColor` |
170
+
171
+ ### Typography
172
+
173
+ | Class | CSS Property |
174
+ |---|---|
175
+ | `chai-fontSize-{n}` | `fontSize` |
176
+ | `chai-fontWeight-{n}` | `fontWeight` |
177
+ | `chai-fontStyle-{v}` | `fontStyle` |
178
+ | `chai-lineHeight-{n}` | `lineHeight` |
179
+ | `chai-letterSpacing-{n}` | `letterSpacing` |
180
+ | `chai-textAlign-{v}` | `textAlign` |
181
+ | `chai-textTransform-{v}` | `textTransform` |
182
+ | `chai-textDecor-{v}` | `textDecoration` |
183
+ | `chai-textOverflow-{v}` | `textOverflow` |
184
+ | `chai-whiteSpace-{v}` | `whiteSpace` |
185
+ | `chai-lineClamp-{n}` | `-webkit-line-clamp` |
186
+ | `chai-wordBreak-{v}` | `wordBreak` |
187
+
188
+ ### Borders & Radius
189
+
190
+ | Class | CSS Property |
191
+ |---|---|
192
+ | `chai-border-{v}` | `border` |
193
+ | `chai-borderW-{n}` | `borderWidth` |
194
+ | `chai-borderStyle-{v}` | `borderStyle` |
195
+ | `chai-borderColor-{color}` | `borderColor` |
196
+ | `chai-rounded-{n}` | `borderRadius` |
197
+ | `chai-roundedT-{n}` | top-left + top-right radius |
198
+ | `chai-roundedB-{n}` | bottom-left + bottom-right radius |
199
+ | `chai-roundedTL-{n}` | `borderTopLeftRadius` |
200
+ | `chai-roundedTR-{n}` | `borderTopRightRadius` |
201
+ | `chai-roundedBL-{n}` | `borderBottomLeftRadius` |
202
+ | `chai-roundedBR-{n}` | `borderBottomRightRadius` |
203
+
204
+ ### Layout & Display
205
+
206
+ | Class | CSS Property |
207
+ |---|---|
208
+ | `chai-d-{v}` | `display` |
209
+ | `chai-pos-{v}` | `position` |
210
+ | `chai-overflow-{v}` | `overflow` |
211
+ | `chai-overflowX-{v}` | `overflowX` |
212
+ | `chai-overflowY-{v}` | `overflowY` |
213
+ | `chai-z-{n}` | `zIndex` |
214
+ | `chai-opacity-{n}` | `opacity` |
215
+ | `chai-visibility-{v}` | `visibility` |
216
+ | `chai-cursor-{v}` | `cursor` |
217
+ | `chai-objectFit-{v}` | `objectFit` |
218
+
219
+ ### Flexbox
220
+
221
+ | Class | CSS Property |
222
+ |---|---|
223
+ | `chai-flex-{v}` | `flex` |
224
+ | `chai-flexDir-{v}` | `flexDirection` |
225
+ | `chai-flexWrap-{v}` | `flexWrap` |
226
+ | `chai-flexGrow-{n}` | `flexGrow` |
227
+ | `chai-flexShrink-{n}` | `flexShrink` |
228
+ | `chai-flexBasis-{n}` | `flexBasis` |
229
+ | `chai-alignItems-{v}` | `alignItems` |
230
+ | `chai-alignSelf-{v}` | `alignSelf` |
231
+ | `chai-alignContent-{v}` | `alignContent` |
232
+ | `chai-justifyContent-{v}` | `justifyContent` |
233
+ | `chai-justifyItems-{v}` | `justifyItems` |
234
+ | `chai-justifySelf-{v}` | `justifySelf` |
235
+ | `chai-placeItems-{v}` | `placeItems` |
236
+ | `chai-order-{n}` | `order` |
237
+
238
+ ### Grid
239
+
240
+ | Class | CSS Property |
241
+ |---|---|
242
+ | `chai-gridCols-{v}` | `gridTemplateColumns` |
243
+ | `chai-gridRows-{v}` | `gridTemplateRows` |
244
+ | `chai-gridArea-{v}` | `gridArea` |
245
+ | `chai-gridAutoFlow-{v}` | `gridAutoFlow` |
246
+ | `chai-colStart-{n}` | `gridColumnStart` |
247
+ | `chai-colEnd-{n}` | `gridColumnEnd` |
248
+ | `chai-rowStart-{n}` | `gridRowStart` |
249
+ | `chai-rowEnd-{n}` | `gridRowEnd` |
250
+
251
+ ### Position
252
+
253
+ | Class | CSS Property |
254
+ |---|---|
255
+ | `chai-top-{n}` | `top` |
256
+ | `chai-bottom-{n}` | `bottom` |
257
+ | `chai-left-{n}` | `left` |
258
+ | `chai-right-{n}` | `right` |
259
+ | `chai-inset-{n}` | `inset` |
260
+ | `chai-insetX-{n}` | `left` + `right` |
261
+ | `chai-insetY-{n}` | `top` + `bottom` |
262
+ | `chai-z-{n}` | `zIndex` |
263
+
264
+ ### Transforms & Transitions
265
+
266
+ | Class | CSS Property |
267
+ |---|---|
268
+ | `chai-transform-{v}` | `transform` |
269
+ | `chai-rotate-{v}` | `rotate` |
270
+ | `chai-scale-{v}` | `scale` |
271
+ | `chai-translate-{v}` | `translate` |
272
+ | `chai-transition-{v}` | `transition` |
273
+ | `chai-duration-{n}` | `transitionDuration` |
274
+ | `chai-delay-{n}` | `transitionDelay` |
275
+ | `chai-ease-{v}` | `transitionTimingFunction` |
276
+
277
+ ### Shadow & Filter
278
+
279
+ | Class | CSS Property |
280
+ |---|---|
281
+ | `chai-shadow-{v}` | `boxShadow` |
282
+ | `chai-filter-{v}` | `filter` |
283
+ | `chai-backdropFilter-{v}` | `backdropFilter` |
284
+ | `chai-blur-{v}` | `filter` |
285
+ | `chai-opacity-{n}` | `opacity` |
286
+
287
+ ---
288
+
289
+ ## Color Palette
290
+
291
+ chai includes the full Tailwind color palette with shades from `50` to `950`.
292
+
293
+ **Available color families:**
294
+ `slate` · `gray` · `zinc` · `neutral` · `stone` · `red` · `orange` · `amber` · `yellow` · `lime` · `green` · `emerald` · `teal` · `cyan` · `sky` · `blue` · `indigo` · `violet` · `purple` · `fuchsia` · `pink` · `rose`
295
+
296
+ **Usage:**
297
+ ```html
298
+ chai-bg-{color}-{shade}
299
+ chai-text-{color}-{shade}
300
+ chai-borderColor-{color}-{shade}
301
+ ```
302
+
303
+ **Examples:**
304
+ ```html
305
+ <div class="chai-bg-blue-500"> <!-- backgroundColor: #3b82f6 -->
306
+ <p class="chai-text-rose-400"> <!-- color: #fb7185 -->
307
+ <hr class="chai-bg-slate-200"> <!-- backgroundColor: #e2e8f0 -->
308
+ ```
309
+
310
+ **Special values:** `black`, `white`, `transparent`, `current`
311
+
312
+ ---
313
+
314
+ ## Value Rules
315
+
316
+ | Value type | Example | What chai does |
317
+ |---|---|---|
318
+ | Plain number | `16`, `8`, `24` | Appends `px` → `16px` |
319
+ | Number with unit | `1.5rem`, `50%`, `100vh` | Used as-is |
320
+ | Color name | `red-500`, `indigo-400` | Resolved to hex → `#ef4444` |
321
+ | Keyword | `auto`, `flex`, `none`, `center` | Used as-is |
322
+ | Raw hex | `#ff0000` | Used as-is |
323
+
324
+ ---
325
+
326
+ ## Examples
327
+
328
+ ### Card component
329
+ ```html
330
+ <div class="
331
+ chai-bg-slate-800
332
+ chai-px-24 chai-py-20
333
+ chai-rounded-16
334
+ chai-shadow-lg
335
+ ">
336
+ <h2 class="chai-text-white chai-fontSize-20 chai-fontWeight-700 chai-mb-8">
337
+ Title
338
+ </h2>
339
+ <p class="chai-text-slate-400 chai-fontSize-14 chai-lineHeight-1.6">
340
+ Some description text here.
341
+ </p>
342
+ </div>
343
+ ```
344
+
345
+ ### Flex row
346
+ ```html
347
+ <div class="chai-d-flex chai-alignItems-center chai-justifyContent-between chai-gap-16">
348
+ <span class="chai-text-slate-300 chai-fontSize-14">Label</span>
349
+ <button class="chai-bg-indigo-600 chai-text-white chai-px-16 chai-py-8 chai-rounded-8">
350
+ Action
351
+ </button>
352
+ </div>
353
+ ```
354
+
355
+ ### Responsive-ish sizing
356
+ ```html
357
+ <img
358
+ class="chai-w-100 chai-h-200 chai-objectFit-cover chai-rounded-12"
359
+ src="photo.jpg"
360
+ alt="Photo"
361
+ />
362
+ ```
363
+
364
+ ### Dark badge
365
+ ```html
366
+ <span class="
367
+ chai-bg-indigo-950
368
+ chai-text-indigo-300
369
+ chai-fontSize-11
370
+ chai-px-10 chai-py-4
371
+ chai-rounded-100
372
+ chai-letterSpacing-0.08em
373
+ chai-textTransform-uppercase
374
+ ">
375
+ New
376
+ </span>
377
+ ```
378
+
379
+ ---
380
+
381
+ ## Setup with Vite
382
+
383
+ ```html
384
+ <!-- index.html -->
385
+ <body>
386
+ <div class="chai-bg-slate-950 chai-px-32 chai-py-24">
387
+ <h1 class="chai-text-white chai-fontSize-32 chai-fontWeight-800">
388
+ Hello chai ☕
389
+ </h1>
390
+ </div>
391
+ <script type="module" src="./src/main.js"></script>
392
+ </body>
393
+ ```
394
+
395
+ ```js
396
+ // src/main.js
397
+ import { scan } from "./scanner.js";
398
+ import { parse } from "./parser.js";
399
+ import { applyStyle } from "./apply.js";
400
+
401
+ function run() {
402
+ scan().forEach(item => applyStyle(item.element, parse(item.className)));
403
+ }
404
+
405
+ document.readyState === "loading"
406
+ ? document.addEventListener("DOMContentLoaded", run)
407
+ : run();
408
+ ```
409
+
410
+ Then run:
411
+ ```bash
412
+ npm create vite@latest my-app -- --template vanilla
413
+ cd my-app
414
+ npm install
415
+ npm run dev
416
+ ```
417
+
418
+ ---
419
+
420
+ ## Extending chai
421
+
422
+ ### Add a new property shorthand
423
+
424
+ Open `config/propertyMap.js` and add your key:
425
+
426
+ ```js
427
+ export const propertyMap = {
428
+ // ...existing properties...
429
+
430
+ // your new ones:
431
+ trackColor: "scrollbarColor",
432
+ txtSize: "fontSize",
433
+ bd: ["borderLeft", "borderRight", "borderTop", "borderBottom"],
434
+ };
435
+ ```
436
+
437
+ Now `chai-trackColor-slate-500` and `chai-txtSize-18` work immediately.
438
+
439
+ ### Add a custom color
440
+
441
+ Open `config/propertyMap.js` and add to `categoryGroups.colors`:
442
+
443
+ ```js
444
+ export const categoryGroups = {
445
+ // ...
446
+ colors: {
447
+ // ...existing colors...
448
+ "brand": "#your-hex",
449
+ "brand-light":"#your-light-hex",
450
+ "brand-dark": "#your-dark-hex",
451
+ }
452
+ };
453
+ ```
454
+
455
+ Now `chai-bg-brand` and `chai-text-brand-light` work.
456
+
457
+ ---
458
+
459
+ ## Limitations
460
+
461
+ Since chai applies **inline styles**, it cannot handle:
462
+
463
+ - **Pseudo-classes** like `:hover`, `:focus`, `:nth-child` — use a `<style>` block for these
464
+ - **Media queries** — add responsive logic manually in JS if needed
465
+ - **CSS variables** — you can pass them as values (`chai-color-var(--my-color)`) but they must already be defined
466
+ - **Complex values with spaces** — e.g. `chai-shadow-0 2px 8px black` won't parse — define these in a `<style>` block
467
+
468
+ ---
469
+
470
+ ## File Overview
471
+
472
+ | File | Purpose |
473
+ |---|---|
474
+ | `config/propertyMap.js` | All shorthand keys → CSS properties + color palette |
475
+ | `src/scanner.js` | Finds all `chai-` elements in the DOM |
476
+ | `src/parser.js` | Parses `"chai-bg-red-500"` into `{ property, value }` |
477
+ | `src/apply.js` | Resolves values and sets `element.style` |
478
+ | `src/main.js` | Runs the engine on page load |
479
+ | `index.html` | Your HTML — use `chai-` classes here |
480
+
481
+ ---
482
+
483
+ ## License
484
+
485
+ MIT — build whatever you want with it. ☕
package/package.json ADDED
@@ -0,0 +1,33 @@
1
+ {
2
+ "name": "@chakrabortyrajarshi2005/chai-tailwind-css",
3
+ "version": "1.0.0",
4
+ "description": "A lightweight utility-class CSS engine. Write chai- classes, get real CSS.",
5
+ "type": "module",
6
+ "files": [
7
+ "src/",
8
+ "config/",
9
+ "README.md"
10
+ ],
11
+ "keywords": [
12
+ "css",
13
+ "utility",
14
+ "tailwind",
15
+ "classnames",
16
+ "styling"
17
+ ],
18
+ "author": "Rajarshi Chakraborty",
19
+ "scripts": {
20
+ "dev": "vite",
21
+ "preview": "vite preview",
22
+ "build": "rollup -c"
23
+ },
24
+ "devDependencies": {
25
+ "rollup": "^4.60.0",
26
+ "vite": "^8.0.1"
27
+ },
28
+ "license": "MIT",
29
+ "repository": {
30
+ "type": "git",
31
+ "url": "https://github.com/chakrabortyrajarshi2005/Mini-TailwindCSS"
32
+ }
33
+ }
package/src/apply.js ADDED
@@ -0,0 +1,80 @@
1
+ import { propertyMap, categoryGroups } from "./config/propertyMap.js";
2
+
3
+ const colors = categoryGroups.colors;
4
+
5
+ const keywords = [
6
+ "auto",
7
+ "none",
8
+ "inherit",
9
+ "initial",
10
+ "unset",
11
+ "normal",
12
+ "bold",
13
+ "italic",
14
+ "hidden",
15
+ "visible",
16
+ "flex",
17
+ "grid",
18
+ "block",
19
+ "inline",
20
+ "absolute",
21
+ "relative",
22
+ "fixed",
23
+ "sticky",
24
+ "static",
25
+ "top",
26
+ "bottom",
27
+ "left",
28
+ "right",
29
+ "center",
30
+ "wrap",
31
+ "nowrap",
32
+ "pointer",
33
+ "default",
34
+ "row",
35
+ "column",
36
+ "row-reverse",
37
+ "column-reverse",
38
+ "transparent",
39
+ "currentColor",
40
+ "full",
41
+ "fit",
42
+ "min",
43
+ "max",
44
+ "underline",
45
+ "start",
46
+ "end",
47
+ "stretch",
48
+ "baseline",
49
+ "scroll",
50
+ ];
51
+
52
+ function alreadyHasUnit(value) {
53
+ return /(%|px|em|rem|vh|vw|vmin|vmax|ch|fr|deg|ms|s)$/.test(value);
54
+ }
55
+
56
+ function getFinalValue(value) {
57
+ if (colors[value] !== undefined) return colors[value];
58
+ if (alreadyHasUnit(value)) return value;
59
+ if (keywords.includes(value)) return value;
60
+ if (/^\d+(\.\d+)?$/.test(value)) return value + "px";
61
+ return value;
62
+ }
63
+
64
+ export function applyStyle(element, parsed) {
65
+ if (!parsed) return;
66
+
67
+ const cssProperty = propertyMap[parsed.property];
68
+ if (!cssProperty) return;
69
+
70
+ const finalValue = getFinalValue(parsed.value);
71
+
72
+ if (Array.isArray(cssProperty)) {
73
+ cssProperty.forEach((prop) => {
74
+ element.style[prop] = finalValue;
75
+ });
76
+ } else {
77
+ element.style[cssProperty] = finalValue;
78
+ }
79
+ }
80
+