chaiwind 1.0.0 → 2.1.1
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 +189 -24
- package/chaiwind.js +326 -76
- package/demo/demo.html +104 -0
- package/package.json +18 -4
package/README.md
CHANGED
|
@@ -1,46 +1,211 @@
|
|
|
1
|
-
#
|
|
1
|
+
# chaiwind
|
|
2
2
|
|
|
3
|
-
A
|
|
3
|
+
A lightweight utility-first CSS engine for the ChaiCode family.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
Write `chai-*` class names on your HTML elements. chaiwind scans the DOM,
|
|
6
|
+
parses those class names, and applies inline styles directly — no build step,
|
|
7
|
+
no config, no stylesheet required.
|
|
6
8
|
|
|
7
|
-
|
|
8
|
-
- Tailwind CSS styling
|
|
9
|
-
- Chai testing framework
|
|
10
|
-
- Clean project structure
|
|
9
|
+
---
|
|
11
10
|
|
|
12
|
-
##
|
|
11
|
+
## Install
|
|
13
12
|
|
|
14
13
|
```bash
|
|
15
|
-
npm install
|
|
14
|
+
npm install chaiwind
|
|
16
15
|
```
|
|
17
16
|
|
|
18
|
-
|
|
17
|
+
After installation, import `chaiwind.css` to enable autocomplete in your IDE (see Setup below).
|
|
19
18
|
|
|
20
|
-
|
|
21
|
-
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
## Quick Demo
|
|
22
|
+
|
|
23
|
+
Open `node_modules/chaiwind/demo/demo.html` in your browser to see chaiwind in action!
|
|
24
|
+
|
|
25
|
+
---
|
|
26
|
+
|
|
27
|
+
## Setup
|
|
28
|
+
|
|
29
|
+
### 1. Import CSS (for autocomplete)
|
|
30
|
+
|
|
31
|
+
Add this to your main CSS/HTML file to enable IDE autocomplete:
|
|
32
|
+
|
|
33
|
+
```html
|
|
34
|
+
<link rel="stylesheet" href="node_modules/chaiwind/chaiwind.css" />
|
|
22
35
|
```
|
|
23
36
|
|
|
24
|
-
|
|
37
|
+
Or in CSS/SCSS:
|
|
25
38
|
|
|
26
|
-
```
|
|
27
|
-
|
|
39
|
+
```css
|
|
40
|
+
@import "chaiwind/chaiwind.css";
|
|
28
41
|
```
|
|
29
42
|
|
|
30
|
-
|
|
43
|
+
**Note:** This CSS file is only for autocomplete suggestions in your editor. The actual styling is done by the JavaScript at runtime.
|
|
31
44
|
|
|
32
|
-
|
|
33
|
-
- **Chai** - BDD assertion library
|
|
34
|
-
- **Node.js** - JavaScript runtime
|
|
45
|
+
### 2. Add the JavaScript
|
|
35
46
|
|
|
36
|
-
|
|
47
|
+
Add the script tag at the **bottom of your body** tag:
|
|
37
48
|
|
|
38
|
-
|
|
49
|
+
```html
|
|
50
|
+
<body>
|
|
51
|
+
<!-- your HTML here -->
|
|
52
|
+
|
|
53
|
+
<script src="node_modules/chaiwind/chaiwind.js"></script>
|
|
54
|
+
</body>
|
|
55
|
+
```
|
|
39
56
|
|
|
40
|
-
|
|
57
|
+
Then use `chai-*` classes on any element:
|
|
41
58
|
|
|
42
|
-
|
|
59
|
+
```html
|
|
60
|
+
<div class="chai-bg-chai chai-p-4 chai-rounded-md chai-text-white">Haanji!</div>
|
|
61
|
+
|
|
62
|
+
<div class="chai-flex chai-items-center chai-justify-between chai-gap-4">
|
|
63
|
+
<p class="chai-fs-lg chai-font-bold chai-text-masala">Hitesh sir</p>
|
|
64
|
+
<p class="chai-fs-sm chai-text-gray">ChaiCode</p>
|
|
65
|
+
</div>
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
chaiwind converts each `chai-*` class into an inline style and removes the
|
|
69
|
+
class from the element. A `data-chaiwind` attribute is added so you can still
|
|
70
|
+
see what was applied by inspecting the element.
|
|
43
71
|
|
|
44
72
|
---
|
|
45
73
|
|
|
46
|
-
|
|
74
|
+
## How it works
|
|
75
|
+
|
|
76
|
+
1. Script runs after the DOM is ready
|
|
77
|
+
2. `querySelectorAll('[class]')` finds every element with a class
|
|
78
|
+
3. For each class starting with `chai-` — parses the suffix into a CSS property and value
|
|
79
|
+
4. Applies styles via `Object.assign(el.style, styles)`
|
|
80
|
+
5. Removes the `chai-*` class, stores applied names in `data-chaiwind`
|
|
81
|
+
6. `MutationObserver` watches for elements added after load and applies the same logic
|
|
82
|
+
|
|
83
|
+
---
|
|
84
|
+
|
|
85
|
+
## Color tokens
|
|
86
|
+
|
|
87
|
+
### ChaiCode brand
|
|
88
|
+
|
|
89
|
+
| Class | Value |
|
|
90
|
+
| ----------------------- | --------- |
|
|
91
|
+
| `chai-bg-chaicode` | `#f97316` |
|
|
92
|
+
| `chai-bg-chaicode-dark` | `#1a1a2e` |
|
|
93
|
+
|
|
94
|
+
### Hitesh sir
|
|
95
|
+
|
|
96
|
+
| Class | Value |
|
|
97
|
+
| ---------------- | --------- |
|
|
98
|
+
| `chai-bg-chai` | `#c8843a` |
|
|
99
|
+
| `chai-bg-adrak` | `#d4a056` |
|
|
100
|
+
| `chai-bg-masala` | `#8b4513` |
|
|
101
|
+
| `chai-bg-kulhad` | `#b5651d` |
|
|
102
|
+
|
|
103
|
+
### Piyush sir
|
|
104
|
+
|
|
105
|
+
| Class | Value |
|
|
106
|
+
| --------------------- | --------- |
|
|
107
|
+
| `chai-bg-piyush` | `#ec4899` |
|
|
108
|
+
| `chai-bg-piyush-dark` | `#be185d` |
|
|
109
|
+
|
|
110
|
+
### Akash sir
|
|
111
|
+
|
|
112
|
+
| Class | Value |
|
|
113
|
+
| ------------------ | --------- |
|
|
114
|
+
| `chai-bg-midnight` | `#1d1d1f` |
|
|
115
|
+
| `chai-bg-silver` | `#e8e8ed` |
|
|
116
|
+
|
|
117
|
+
Each color token generates three classes: `chai-bg-*`, `chai-text-*`, `chai-border-*`
|
|
118
|
+
|
|
119
|
+
---
|
|
120
|
+
|
|
121
|
+
## Spacing
|
|
122
|
+
|
|
123
|
+
`chai-p-{0|1|2|3|4|6|8|10|12}` — padding
|
|
124
|
+
`chai-px-` `chai-py-` `chai-pt-` `chai-pb-` `chai-pl-` `chai-pr-`
|
|
125
|
+
`chai-m-{0|1|2|3|4|6|8|10|12}` — margin
|
|
126
|
+
`chai-mx-` `chai-my-` `chai-mt-` `chai-mb-` `chai-ml-` `chai-mr-`
|
|
127
|
+
`chai-gap-{n}` `chai-w-{n}` `chai-h-{n}`
|
|
128
|
+
|
|
129
|
+
Scale: 0=0px 1=4px 2=8px 3=12px 4=16px 6=24px 8=32px 10=40px 12=48px
|
|
130
|
+
|
|
131
|
+
---
|
|
132
|
+
|
|
133
|
+
## Typography
|
|
134
|
+
|
|
135
|
+
`chai-fs-{xs|sm|base|lg|xl|2xl}` — font size
|
|
136
|
+
`chai-font-{normal|medium|semibold|bold}` — font weight
|
|
137
|
+
`chai-text-{left|center|right}` — alignment
|
|
138
|
+
`chai-uppercase` `chai-lowercase` `chai-capitalize`
|
|
139
|
+
`chai-italic` `chai-underline` `chai-no-underline` `chai-truncate`
|
|
140
|
+
|
|
141
|
+
---
|
|
142
|
+
|
|
143
|
+
## Layout
|
|
144
|
+
|
|
145
|
+
`chai-flex` `chai-flex-col` `chai-flex-row` `chai-flex-wrap` `chai-flex-1`
|
|
146
|
+
`chai-items-{start|center|end}`
|
|
147
|
+
`chai-justify-{start|center|end|between}`
|
|
148
|
+
`chai-grid` `chai-block` `chai-inline-block` `chai-hidden`
|
|
149
|
+
|
|
150
|
+
---
|
|
151
|
+
|
|
152
|
+
## Sizing
|
|
153
|
+
|
|
154
|
+
`chai-w-full` `chai-w-screen` `chai-w-auto`
|
|
155
|
+
`chai-h-full` `chai-h-screen` `chai-h-auto`
|
|
156
|
+
|
|
157
|
+
---
|
|
158
|
+
|
|
159
|
+
## Position
|
|
160
|
+
|
|
161
|
+
`chai-relative` `chai-absolute` `chai-fixed` `chai-sticky`
|
|
162
|
+
|
|
163
|
+
---
|
|
164
|
+
|
|
165
|
+
## Border & Radius
|
|
166
|
+
|
|
167
|
+
`chai-border` `chai-border-2` `chai-border-none` `chai-border-dashed`
|
|
168
|
+
`chai-rounded-{none|sm|md|lg|full}`
|
|
169
|
+
|
|
170
|
+
---
|
|
171
|
+
|
|
172
|
+
## Misc
|
|
173
|
+
|
|
174
|
+
`chai-overflow-{hidden|auto}`
|
|
175
|
+
`chai-cursor-pointer` `chai-cursor-not-allowed`
|
|
176
|
+
`chai-opacity-{0|50|100}`
|
|
177
|
+
`chai-select-none` `chai-box-border`
|
|
178
|
+
|
|
179
|
+
---
|
|
180
|
+
|
|
181
|
+
## Autocomplete setup
|
|
182
|
+
|
|
183
|
+
### Option 1: Import CSS (recommended)
|
|
184
|
+
|
|
185
|
+
Import `chaiwind.css` in your project (see Setup above). Most modern IDEs will automatically provide autocomplete.
|
|
186
|
+
|
|
187
|
+
### Option 2: VS Code custom data
|
|
188
|
+
|
|
189
|
+
Add this to `.vscode/settings.json`:
|
|
190
|
+
|
|
191
|
+
```json
|
|
192
|
+
{
|
|
193
|
+
"css.customData": ["./node_modules/chaiwind/chaiwind.css-data.json"]
|
|
194
|
+
}
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
Restart VS Code after adding.
|
|
198
|
+
|
|
199
|
+
---
|
|
200
|
+
|
|
201
|
+
## Known limitations
|
|
202
|
+
|
|
203
|
+
- Inline styles override all external CSS — this is a tradeoff of the inline approach
|
|
204
|
+
- Hover and focus states (`chai-hover-*`) are not supported — inline styles cannot express pseudo-classes
|
|
205
|
+
- Responsive breakpoints (`sm:chai-p-4`) are not supported — media queries require a stylesheet
|
|
206
|
+
|
|
207
|
+
---
|
|
208
|
+
|
|
209
|
+
## License
|
|
210
|
+
|
|
211
|
+
MIT
|
package/chaiwind.js
CHANGED
|
@@ -1,29 +1,37 @@
|
|
|
1
1
|
(function () {
|
|
2
|
+
// ─── TOKENS ───────────────────────────────────────────────────────────────
|
|
3
|
+
// same tokens as before — just used for lookup, not for building CSS strings
|
|
4
|
+
|
|
2
5
|
const colors = {
|
|
3
6
|
// chaicode brand
|
|
4
7
|
chaicode: "#f97316",
|
|
5
8
|
"chaicode-dark": "#1a1a2e",
|
|
6
9
|
|
|
7
|
-
//
|
|
10
|
+
// hitesh sir
|
|
8
11
|
chai: "#c8843a",
|
|
9
12
|
adrak: "#d4a056",
|
|
10
13
|
masala: "#8b4513",
|
|
11
14
|
kulhad: "#b5651d",
|
|
15
|
+
tapri: "#6b3a2a",
|
|
16
|
+
dudh: "#f5f0e8",
|
|
12
17
|
|
|
13
|
-
//
|
|
18
|
+
// piyush sir
|
|
14
19
|
piyush: "#ec4899",
|
|
15
20
|
"piyush-light": "#f9a8d4",
|
|
16
21
|
"piyush-dark": "#be185d",
|
|
22
|
+
rose: "#fb7185",
|
|
23
|
+
blush: "#fce7f3",
|
|
24
|
+
fuschia: "#d946ef",
|
|
17
25
|
|
|
18
|
-
//
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
"
|
|
24
|
-
"
|
|
25
|
-
"
|
|
26
|
-
|
|
26
|
+
// akash sir
|
|
27
|
+
midnight: "#1d1d1f",
|
|
28
|
+
spacegray: "#86868b",
|
|
29
|
+
silver: "#e8e8ed",
|
|
30
|
+
starlight: "#f5f1eb",
|
|
31
|
+
"macos-blue": "#0071e3",
|
|
32
|
+
"macos-green": "#34c759",
|
|
33
|
+
"macos-red": "#ff3b30",
|
|
34
|
+
aluminum: "#d1d1d6",
|
|
27
35
|
|
|
28
36
|
// basics
|
|
29
37
|
white: "#ffffff",
|
|
@@ -32,6 +40,12 @@
|
|
|
32
40
|
red: "#ef4444",
|
|
33
41
|
green: "#22c55e",
|
|
34
42
|
blue: "#3b82f6",
|
|
43
|
+
yellow: "#eab308",
|
|
44
|
+
purple: "#a855f7",
|
|
45
|
+
orange: "#f97316",
|
|
46
|
+
pink: "#ec4899",
|
|
47
|
+
teal: "#14b8a6",
|
|
48
|
+
indigo: "#6366f1",
|
|
35
49
|
};
|
|
36
50
|
|
|
37
51
|
const spacing = {
|
|
@@ -40,94 +54,330 @@
|
|
|
40
54
|
2: "8px",
|
|
41
55
|
3: "12px",
|
|
42
56
|
4: "16px",
|
|
57
|
+
5: "20px",
|
|
43
58
|
6: "24px",
|
|
59
|
+
7: "28px",
|
|
44
60
|
8: "32px",
|
|
61
|
+
9: "36px",
|
|
45
62
|
10: "40px",
|
|
46
63
|
12: "48px",
|
|
64
|
+
16: "64px",
|
|
65
|
+
20: "80px",
|
|
66
|
+
24: "96px",
|
|
47
67
|
};
|
|
48
68
|
|
|
49
69
|
const fontSizes = {
|
|
50
|
-
|
|
70
|
+
xs: "11px",
|
|
71
|
+
sm: "13px",
|
|
51
72
|
base: "16px",
|
|
52
|
-
lg: "
|
|
53
|
-
xl: "
|
|
54
|
-
"2xl": "
|
|
73
|
+
lg: "18px",
|
|
74
|
+
xl: "20px",
|
|
75
|
+
"2xl": "24px",
|
|
76
|
+
"3xl": "30px",
|
|
77
|
+
"4xl": "36px",
|
|
78
|
+
"5xl": "48px",
|
|
55
79
|
};
|
|
56
80
|
|
|
57
81
|
const radii = {
|
|
82
|
+
none: "0px",
|
|
58
83
|
sm: "4px",
|
|
59
84
|
md: "8px",
|
|
60
85
|
lg: "12px",
|
|
86
|
+
xl: "16px",
|
|
87
|
+
"2xl": "24px",
|
|
61
88
|
full: "9999px",
|
|
62
89
|
};
|
|
63
90
|
|
|
64
|
-
|
|
91
|
+
const shadows = {
|
|
92
|
+
sm: "0 1px 3px rgba(0,0,0,0.10)",
|
|
93
|
+
md: "0 4px 12px rgba(0,0,0,0.12)",
|
|
94
|
+
lg: "0 8px 24px rgba(0,0,0,0.15)",
|
|
95
|
+
xl: "0 16px 48px rgba(0,0,0,0.20)",
|
|
96
|
+
chai: "0 4px 20px rgba(200,132,58,0.35)",
|
|
97
|
+
piyush: "0 4px 20px rgba(236,72,153,0.30)",
|
|
98
|
+
mac: "0 8px 32px rgba(29,29,31,0.25)",
|
|
99
|
+
none: "none",
|
|
100
|
+
};
|
|
65
101
|
|
|
66
|
-
|
|
102
|
+
// ─── PARSER ─────────────────────────────────
|
|
103
|
+
// takes one element + one class name
|
|
104
|
+
// parses the class → applies inline style → removes class
|
|
67
105
|
|
|
68
|
-
function
|
|
69
|
-
|
|
70
|
-
|
|
106
|
+
function applyClass(el, cls) {
|
|
107
|
+
// strip 'chai-' prefix → 'p-4' or 'bg-chai' or 'text-center' etc
|
|
108
|
+
const raw = cls.slice(5); // removes 'chai-'
|
|
109
|
+
const dashIndex = raw.indexOf("-"); // find first dash
|
|
71
110
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
add(`.bg-${name}`, `background-color: ${value};`);
|
|
76
|
-
add(`.border-${name}`, `border-color: ${value};`);
|
|
77
|
-
}
|
|
111
|
+
// if no dash → single word utility like 'chai-flex', 'chai-block'
|
|
112
|
+
const utility = dashIndex === -1 ? raw : raw.slice(0, dashIndex);
|
|
113
|
+
const value = dashIndex === -1 ? "" : raw.slice(dashIndex + 1);
|
|
78
114
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
115
|
+
// resolve color token or fall back to raw value (e.g. 'red', '#fff')
|
|
116
|
+
const color = colors[value] || value;
|
|
117
|
+
const space = spacing[value] || value;
|
|
118
|
+
const size = fontSizes[value];
|
|
119
|
+
const radius = radii[value] || value;
|
|
120
|
+
const shadow = shadows[value] || value;
|
|
121
|
+
|
|
122
|
+
switch (utility) {
|
|
123
|
+
// ── spacing ───────────────────────────────────────────────────────────
|
|
124
|
+
case "p":
|
|
125
|
+
el.style.padding = space;
|
|
126
|
+
break;
|
|
127
|
+
case "px":
|
|
128
|
+
el.style.paddingLeft = space;
|
|
129
|
+
el.style.paddingRight = space;
|
|
130
|
+
break;
|
|
131
|
+
case "py":
|
|
132
|
+
el.style.paddingTop = space;
|
|
133
|
+
el.style.paddingBottom = space;
|
|
134
|
+
break;
|
|
135
|
+
case "pt":
|
|
136
|
+
el.style.paddingTop = space;
|
|
137
|
+
break;
|
|
138
|
+
case "pb":
|
|
139
|
+
el.style.paddingBottom = space;
|
|
140
|
+
break;
|
|
141
|
+
case "pl":
|
|
142
|
+
el.style.paddingLeft = space;
|
|
143
|
+
break;
|
|
144
|
+
case "pr":
|
|
145
|
+
el.style.paddingRight = space;
|
|
146
|
+
break;
|
|
147
|
+
case "m":
|
|
148
|
+
el.style.margin = space;
|
|
149
|
+
break;
|
|
150
|
+
case "mx":
|
|
151
|
+
el.style.marginLeft = space;
|
|
152
|
+
el.style.marginRight = space;
|
|
153
|
+
break;
|
|
154
|
+
case "my":
|
|
155
|
+
el.style.marginTop = space;
|
|
156
|
+
el.style.marginBottom = space;
|
|
157
|
+
break;
|
|
158
|
+
case "mt":
|
|
159
|
+
el.style.marginTop = space;
|
|
160
|
+
break;
|
|
161
|
+
case "mb":
|
|
162
|
+
el.style.marginBottom = space;
|
|
163
|
+
break;
|
|
164
|
+
case "ml":
|
|
165
|
+
el.style.marginLeft = space;
|
|
166
|
+
break;
|
|
167
|
+
case "mr":
|
|
168
|
+
el.style.marginRight = space;
|
|
169
|
+
break;
|
|
170
|
+
case "gap":
|
|
171
|
+
el.style.gap = space;
|
|
172
|
+
break;
|
|
173
|
+
|
|
174
|
+
// ── colors ────────────────────────────────────────────────────────────
|
|
175
|
+
case "bg":
|
|
176
|
+
el.style.backgroundColor = color;
|
|
177
|
+
break;
|
|
178
|
+
case "border":
|
|
179
|
+
el.style.border = "1px solid " + color;
|
|
180
|
+
break;
|
|
181
|
+
case "outline":
|
|
182
|
+
el.style.outline = "2px solid " + color;
|
|
183
|
+
break;
|
|
184
|
+
|
|
185
|
+
// ── text ──────────────────────────────────────────────────────────────
|
|
186
|
+
// chai-text-red → color
|
|
187
|
+
// chai-text-sm → font size
|
|
188
|
+
// chai-text-center / left / right / justify → alignment
|
|
189
|
+
case "text":
|
|
190
|
+
if (colors[value]) el.style.color = color;
|
|
191
|
+
else if (fontSizes[value]) el.style.fontSize = size;
|
|
192
|
+
else el.style.textAlign = value;
|
|
193
|
+
break;
|
|
194
|
+
|
|
195
|
+
// ── font ──────────────────────────────────────────────────────────────
|
|
196
|
+
case "font":
|
|
197
|
+
if (value === "bold") el.style.fontWeight = "700";
|
|
198
|
+
else if (value === "semibold") el.style.fontWeight = "600";
|
|
199
|
+
else if (value === "medium") el.style.fontWeight = "500";
|
|
200
|
+
else if (value === "normal") el.style.fontWeight = "400";
|
|
201
|
+
else if (value === "light") el.style.fontWeight = "300";
|
|
202
|
+
else if (value === "italic") el.style.fontStyle = "italic";
|
|
203
|
+
break;
|
|
204
|
+
|
|
205
|
+
// ── sizing ────────────────────────────────────────────────────────────
|
|
206
|
+
case "w":
|
|
207
|
+
if (value === "full") el.style.width = "100%";
|
|
208
|
+
else if (value === "screen") el.style.width = "100vw";
|
|
209
|
+
else if (value === "auto") el.style.width = "auto";
|
|
210
|
+
else el.style.width = spacing[value] || value;
|
|
211
|
+
break;
|
|
212
|
+
case "h":
|
|
213
|
+
if (value === "full") el.style.height = "100%";
|
|
214
|
+
else if (value === "screen") el.style.height = "100vh";
|
|
215
|
+
else if (value === "auto") el.style.height = "auto";
|
|
216
|
+
else el.style.height = spacing[value] || value;
|
|
217
|
+
break;
|
|
218
|
+
case "min":
|
|
219
|
+
// chai-min-h-screen etc — value = 'h-screen'
|
|
220
|
+
if (value === "h-screen") el.style.minHeight = "100vh";
|
|
221
|
+
if (value === "w-full") el.style.minWidth = "100%";
|
|
222
|
+
break;
|
|
223
|
+
case "max":
|
|
224
|
+
if (value === "w-full") el.style.maxWidth = "100%";
|
|
225
|
+
break;
|
|
226
|
+
|
|
227
|
+
// ── border radius ─────────────────────────────────────────────────────
|
|
228
|
+
case "rounded":
|
|
229
|
+
el.style.borderRadius = radius;
|
|
230
|
+
break;
|
|
231
|
+
|
|
232
|
+
// ── shadow ────────────────────────────────────────────────────────────
|
|
233
|
+
case "shadow":
|
|
234
|
+
el.style.boxShadow = shadow;
|
|
235
|
+
break;
|
|
236
|
+
|
|
237
|
+
// ── opacity ───────────────────────────────────────────────────────────
|
|
238
|
+
case "opacity":
|
|
239
|
+
el.style.opacity = String(Number(value) / 100);
|
|
240
|
+
break;
|
|
89
241
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
242
|
+
// ── display ───────────────────────────────────────────────────────────
|
|
243
|
+
case "flex":
|
|
244
|
+
el.style.display = "flex";
|
|
245
|
+
break;
|
|
246
|
+
case "grid":
|
|
247
|
+
el.style.display = "grid";
|
|
248
|
+
break;
|
|
249
|
+
case "block":
|
|
250
|
+
el.style.display = "block";
|
|
251
|
+
break;
|
|
252
|
+
case "hidden":
|
|
253
|
+
el.style.display = "none";
|
|
254
|
+
break;
|
|
255
|
+
case "inline":
|
|
256
|
+
el.style.display = "inline";
|
|
257
|
+
break;
|
|
258
|
+
|
|
259
|
+
// ── flex helpers ──────────────────────────────────────────────────────
|
|
260
|
+
case "items":
|
|
261
|
+
if (value === "center") el.style.alignItems = "center";
|
|
262
|
+
if (value === "start") el.style.alignItems = "flex-start";
|
|
263
|
+
if (value === "end") el.style.alignItems = "flex-end";
|
|
264
|
+
break;
|
|
265
|
+
case "justify":
|
|
266
|
+
if (value === "center") el.style.justifyContent = "center";
|
|
267
|
+
if (value === "start") el.style.justifyContent = "flex-start";
|
|
268
|
+
if (value === "end") el.style.justifyContent = "flex-end";
|
|
269
|
+
if (value === "between") el.style.justifyContent = "space-between";
|
|
270
|
+
if (value === "around") el.style.justifyContent = "space-around";
|
|
271
|
+
break;
|
|
272
|
+
case "flex-col":
|
|
273
|
+
el.style.flexDirection = "column";
|
|
274
|
+
break;
|
|
275
|
+
case "flex-row":
|
|
276
|
+
el.style.flexDirection = "row";
|
|
277
|
+
break;
|
|
278
|
+
case "flex-wrap":
|
|
279
|
+
el.style.flexWrap = "wrap";
|
|
280
|
+
break;
|
|
281
|
+
|
|
282
|
+
// ── position ──────────────────────────────────────────────────────────
|
|
283
|
+
case "relative":
|
|
284
|
+
el.style.position = "relative";
|
|
285
|
+
break;
|
|
286
|
+
case "absolute":
|
|
287
|
+
el.style.position = "absolute";
|
|
288
|
+
break;
|
|
289
|
+
case "fixed":
|
|
290
|
+
el.style.position = "fixed";
|
|
291
|
+
break;
|
|
292
|
+
case "sticky":
|
|
293
|
+
el.style.position = "sticky";
|
|
294
|
+
break;
|
|
295
|
+
|
|
296
|
+
// ── overflow ──────────────────────────────────────────────────────────
|
|
297
|
+
case "overflow":
|
|
298
|
+
el.style.overflow = value;
|
|
299
|
+
break;
|
|
300
|
+
|
|
301
|
+
// ── cursor ────────────────────────────────────────────────────────────
|
|
302
|
+
case "cursor":
|
|
303
|
+
el.style.cursor = value;
|
|
304
|
+
break;
|
|
305
|
+
|
|
306
|
+
// ── misc ──────────────────────────────────────────────────────────────
|
|
307
|
+
case "uppercase":
|
|
308
|
+
el.style.textTransform = "uppercase";
|
|
309
|
+
break;
|
|
310
|
+
case "lowercase":
|
|
311
|
+
el.style.textTransform = "lowercase";
|
|
312
|
+
break;
|
|
313
|
+
case "capitalize":
|
|
314
|
+
el.style.textTransform = "capitalize";
|
|
315
|
+
break;
|
|
316
|
+
case "underline":
|
|
317
|
+
el.style.textDecoration = "underline";
|
|
318
|
+
break;
|
|
319
|
+
case "line-through":
|
|
320
|
+
el.style.textDecoration = "line-through";
|
|
321
|
+
break;
|
|
322
|
+
case "italic":
|
|
323
|
+
el.style.fontStyle = "italic";
|
|
324
|
+
break;
|
|
325
|
+
case "truncate":
|
|
326
|
+
el.style.overflow = "hidden";
|
|
327
|
+
el.style.textOverflow = "ellipsis";
|
|
328
|
+
el.style.whiteSpace = "nowrap";
|
|
329
|
+
break;
|
|
330
|
+
case "transition":
|
|
331
|
+
el.style.transition = "all 150ms ease";
|
|
332
|
+
break;
|
|
333
|
+
case "select-none":
|
|
334
|
+
el.style.userSelect = "none";
|
|
335
|
+
break;
|
|
336
|
+
|
|
337
|
+
default:
|
|
338
|
+
// unknown class — silently skip
|
|
339
|
+
break;
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
// requirement: remove the chai- class after applying
|
|
343
|
+
el.classList.remove(cls);
|
|
93
344
|
}
|
|
94
345
|
|
|
95
|
-
//
|
|
96
|
-
|
|
97
|
-
|
|
346
|
+
// ─── SCANNER ──────────────────────────────────────────────────────────────
|
|
347
|
+
// traverses the full DOM once
|
|
348
|
+
// finds every element that has at least one chai- class
|
|
349
|
+
// applies all chai- classes on that element
|
|
350
|
+
|
|
351
|
+
function scan() {
|
|
352
|
+
const elements = document.querySelectorAll("[class]");
|
|
353
|
+
|
|
354
|
+
elements.forEach(function (el) {
|
|
355
|
+
// snapshot classList into array first
|
|
356
|
+
// because we're removing classes mid-loop
|
|
357
|
+
const classes = Array.from(el.classList);
|
|
358
|
+
|
|
359
|
+
classes.forEach(function (cls) {
|
|
360
|
+
if (cls.startsWith("chai-")) {
|
|
361
|
+
applyClass(el, cls);
|
|
362
|
+
}
|
|
363
|
+
});
|
|
364
|
+
});
|
|
365
|
+
|
|
366
|
+
console.log(
|
|
367
|
+
"%c☕ chaiwind done — DOM scanned",
|
|
368
|
+
"color: #c8843a; font-weight: bold; font-size: 13px;",
|
|
369
|
+
);
|
|
98
370
|
}
|
|
99
371
|
|
|
100
|
-
//
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
add(".text-center", "text-align: center;");
|
|
113
|
-
add(".font-bold", "font-weight: 700;");
|
|
114
|
-
add(".font-normal", "font-weight: 400;");
|
|
115
|
-
add(".border", "border-width: 1px; border-style: solid;");
|
|
116
|
-
add(".cursor-pointer", "cursor: pointer;");
|
|
117
|
-
add(".transition", "transition: all 150ms ease;");
|
|
118
|
-
add(".overflow-hidden", "overflow: hidden;");
|
|
119
|
-
add(".relative", "position: relative;");
|
|
120
|
-
add(".absolute", "position: absolute;");
|
|
121
|
-
|
|
122
|
-
// ─── inject -----
|
|
123
|
-
|
|
124
|
-
const style = document.createElement("style");
|
|
125
|
-
style.setAttribute("id", "chaiwind");
|
|
126
|
-
style.textContent = rules.join("\n");
|
|
127
|
-
document.head.appendChild(style);
|
|
128
|
-
|
|
129
|
-
console.log(
|
|
130
|
-
`%c☕ chaiwind ready — ${rules.length} classes`,
|
|
131
|
-
"color: #c8843a; font-weight: bold;",
|
|
132
|
-
);
|
|
133
|
-
})();
|
|
372
|
+
// ─── INIT ─────────────────────────────────────────────────────────────────
|
|
373
|
+
// run scan() only after HTML is fully parsed
|
|
374
|
+
// handles both cases: script in head vs script at end of body
|
|
375
|
+
|
|
376
|
+
if (document.readyState === "loading") {
|
|
377
|
+
// HTML not done parsing yet — wait for it
|
|
378
|
+
document.addEventListener("DOMContentLoaded", scan);
|
|
379
|
+
} else {
|
|
380
|
+
// HTML already parsed (script is at bottom of body)
|
|
381
|
+
scan();
|
|
382
|
+
}
|
|
383
|
+
})();
|
package/demo/demo.html
ADDED
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8">
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
6
|
+
<title>chaiwind demo</title>
|
|
7
|
+
<!-- load chaiwind in head — DOMContentLoaded handles timing -->
|
|
8
|
+
<script src="chaiwind.js"></script>
|
|
9
|
+
<style>
|
|
10
|
+
* { box-sizing: border-box; margin: 0; padding: 0; }
|
|
11
|
+
body { font-family: -apple-system, BlinkMacSystemFont, sans-serif; }
|
|
12
|
+
</style>
|
|
13
|
+
</head>
|
|
14
|
+
<body>
|
|
15
|
+
|
|
16
|
+
<!-- hero -->
|
|
17
|
+
<div class="chai-bg-chaicode-dark chai-p-12 chai-text-center">
|
|
18
|
+
<h1 class="chai-text-white chai-text-4xl chai-font-bold chai-mb-4">
|
|
19
|
+
chaiwind.js
|
|
20
|
+
</h1>
|
|
21
|
+
<p class="chai-text-gray chai-text-lg chai-mb-8">
|
|
22
|
+
utility-first CSS engine — chai-* classes, inline styles
|
|
23
|
+
</p>
|
|
24
|
+
<div class="chai-flex chai-justify-center chai-gap-4">
|
|
25
|
+
<button class="chai-bg-chai chai-text-white chai-p-3 chai-rounded-md chai-cursor-pointer chai-font-bold">
|
|
26
|
+
☕ Hitesh sir
|
|
27
|
+
</button>
|
|
28
|
+
<button class="chai-bg-piyush chai-text-white chai-p-3 chai-rounded-md chai-cursor-pointer chai-font-bold">
|
|
29
|
+
🩷 Piyush sir
|
|
30
|
+
</button>
|
|
31
|
+
<button class="chai-bg-macos-blue chai-text-white chai-p-3 chai-rounded-md chai-cursor-pointer chai-font-bold">
|
|
32
|
+
🍎 Akash sir
|
|
33
|
+
</button>
|
|
34
|
+
</div>
|
|
35
|
+
</div>
|
|
36
|
+
|
|
37
|
+
<!-- cards -->
|
|
38
|
+
<div class="chai-bg-white chai-p-10">
|
|
39
|
+
<div class="chai-flex chai-gap-6 chai-justify-center">
|
|
40
|
+
|
|
41
|
+
<!-- hitesh card -->
|
|
42
|
+
<div class="chai-bg-dudh chai-p-6 chai-rounded-lg chai-shadow-chai chai-w-full">
|
|
43
|
+
<p class="chai-text-masala chai-font-bold chai-text-xl chai-mb-3">
|
|
44
|
+
☕ Chai palette
|
|
45
|
+
</p>
|
|
46
|
+
<p class="chai-text-gray chai-text-sm chai-mb-4">
|
|
47
|
+
Warm, earthy, tapri-coded
|
|
48
|
+
</p>
|
|
49
|
+
<div class="chai-flex chai-gap-2">
|
|
50
|
+
<span class="chai-bg-chai chai-text-white chai-p-2 chai-rounded-full chai-text-xs chai-font-bold">chai</span>
|
|
51
|
+
<span class="chai-bg-adrak chai-text-white chai-p-2 chai-rounded-full chai-text-xs chai-font-bold">adrak</span>
|
|
52
|
+
<span class="chai-bg-masala chai-text-white chai-p-2 chai-rounded-full chai-text-xs chai-font-bold">masala</span>
|
|
53
|
+
<span class="chai-bg-kulhad chai-text-white chai-p-2 chai-rounded-full chai-text-xs chai-font-bold">kulhad</span>
|
|
54
|
+
</div>
|
|
55
|
+
</div>
|
|
56
|
+
|
|
57
|
+
<!-- piyush card -->
|
|
58
|
+
<div class="chai-bg-blush chai-p-6 chai-rounded-lg chai-shadow-piyush chai-w-full">
|
|
59
|
+
<p class="chai-text-piyush-dark chai-font-bold chai-text-xl chai-mb-3">
|
|
60
|
+
🩷 Pink palette
|
|
61
|
+
</p>
|
|
62
|
+
<p class="chai-text-gray chai-text-sm chai-mb-4">
|
|
63
|
+
Hot pink to soft blush
|
|
64
|
+
</p>
|
|
65
|
+
<div class="chai-flex chai-gap-2">
|
|
66
|
+
<span class="chai-bg-piyush chai-text-white chai-p-2 chai-rounded-full chai-text-xs chai-font-bold">piyush</span>
|
|
67
|
+
<span class="chai-bg-rose chai-text-white chai-p-2 chai-rounded-full chai-text-xs chai-font-bold">rose</span>
|
|
68
|
+
<span class="chai-bg-fuschia chai-text-white chai-p-2 chai-rounded-full chai-text-xs chai-font-bold">fuschia</span>
|
|
69
|
+
</div>
|
|
70
|
+
</div>
|
|
71
|
+
|
|
72
|
+
<!-- akash card -->
|
|
73
|
+
<div class="chai-bg-silver chai-p-6 chai-rounded-lg chai-shadow-mac chai-w-full">
|
|
74
|
+
<p class="chai-text-midnight chai-font-bold chai-text-xl chai-mb-3">
|
|
75
|
+
🍎 Mac palette
|
|
76
|
+
</p>
|
|
77
|
+
<p class="chai-text-gray chai-text-sm chai-mb-4">
|
|
78
|
+
Clean, minimal, premium
|
|
79
|
+
</p>
|
|
80
|
+
<div class="chai-flex chai-gap-2">
|
|
81
|
+
<span class="chai-bg-midnight chai-text-white chai-p-2 chai-rounded-full chai-text-xs chai-font-bold">midnight</span>
|
|
82
|
+
<span class="chai-bg-spacegray chai-text-white chai-p-2 chai-rounded-full chai-text-xs chai-font-bold">spacegray</span>
|
|
83
|
+
<span class="chai-bg-macos-blue chai-text-white chai-p-2 chai-rounded-full chai-text-xs chai-font-bold">macos-blue</span>
|
|
84
|
+
</div>
|
|
85
|
+
</div>
|
|
86
|
+
|
|
87
|
+
</div>
|
|
88
|
+
</div>
|
|
89
|
+
|
|
90
|
+
<!-- usage example -->
|
|
91
|
+
<div class="chai-bg-midnight chai-p-10 chai-text-center">
|
|
92
|
+
<p class="chai-text-white chai-text-2xl chai-font-bold chai-mb-2">
|
|
93
|
+
Zero config. Just add classes.
|
|
94
|
+
</p>
|
|
95
|
+
<p class="chai-text-gray chai-mb-6">
|
|
96
|
+
chai-* prefix → parsed → inline style applied → class removed
|
|
97
|
+
</p>
|
|
98
|
+
<div class="chai-bg-chaicode chai-text-white chai-p-4 chai-rounded-lg chai-text-lg chai-font-bold chai-shadow-chai">
|
|
99
|
+
chai-bg-chaicode + chai-p-4 + chai-rounded-lg
|
|
100
|
+
</div>
|
|
101
|
+
</div>
|
|
102
|
+
|
|
103
|
+
</body>
|
|
104
|
+
</html>
|
package/package.json
CHANGED
|
@@ -1,13 +1,27 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "chaiwind",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "2.1.1",
|
|
4
4
|
"description": "Bounty Jitenge hum Hehe",
|
|
5
5
|
"main": "chaiwind.js",
|
|
6
6
|
"scripts": {
|
|
7
|
-
"
|
|
7
|
+
"postinstall": "node scripts/postinstall.js"
|
|
8
8
|
},
|
|
9
|
-
"
|
|
9
|
+
"files": [
|
|
10
|
+
"chaiwind.js",
|
|
11
|
+
"chaiwind.css",
|
|
12
|
+
"chaiwind.css-data.json",
|
|
13
|
+
"scripts/postinstall.js",
|
|
14
|
+
"demo/",
|
|
15
|
+
"README.md"
|
|
16
|
+
],
|
|
17
|
+
"keywords": [
|
|
18
|
+
"css",
|
|
19
|
+
"utility",
|
|
20
|
+
"framework",
|
|
21
|
+
"chaicode",
|
|
22
|
+
"inline-style"
|
|
23
|
+
],
|
|
10
24
|
"author": "anand",
|
|
11
25
|
"license": "MIT",
|
|
12
26
|
"type": "commonjs"
|
|
13
|
-
}
|
|
27
|
+
}
|