teawind-engine 1.0.0 → 1.0.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 CHANGED
@@ -2,28 +2,53 @@
2
2
 
3
3
  A lightweight utility-first CSS engine. Build UIs using `chai-*` classes without writing CSS!
4
4
 
5
- ## Installation
5
+ ## ✨ Features
6
+
7
+ * 🚀 **Zero Configuration** - Just add classes and they work
8
+
9
+ * 📦 **Lightweight** - No CSS files to manage, pure JavaScript
10
+
11
+ * 🎨 **Utility-First** - Build complex UIs with simple classes
12
+
13
+ * 🔄 **Dynamic** - Works with dynamically added elements
14
+
15
+ * 🎯 **No Dependencies** - Pure vanilla JavaScript
16
+
17
+
18
+ ## 📦 Installation
19
+
20
+ ### NPM
6
21
 
7
22
  ```bash
8
- npm install teawind
23
+ npm install teawind-engine
24
+ ```
9
25
 
10
- Or via CDN:
26
+ ### **CDN**
11
27
 
28
+ ```plaintext
12
29
  <script type="module">
13
- import { initTeawind } from 'https://cdn.jsdelivr.net/npm/teawind@1.0.0/src/index.js';
30
+ import { initTeawind } from 'https://cdn.jsdelivr.net/npm/teawind-engine@1.0.0/src/index.js';
14
31
  initTeawind();
15
32
  </script>
33
+ ```
34
+
35
+ ### **GitHub**
16
36
 
17
- Usage
37
+ ```plaintext
38
+ git clone https://github.com/ravi8555/teawind-engine.git
39
+ ```
18
40
 
19
- Basic Setup
41
+ ### **🚀 Usage**
20
42
 
43
+ **Basic Setup**
44
+
45
+ ```plaintext
21
46
  <!DOCTYPE html>
22
47
  <html>
23
48
  <head>
24
49
  <title>Teawind Demo</title>
25
50
  <script type="module">
26
- import { initTeawind } from 'teawind';
51
+ import { initTeawind } from 'teawind-engine';
27
52
 
28
53
  // Initialize the engine
29
54
  initTeawind();
@@ -35,83 +60,202 @@ Basic Setup
35
60
  </div>
36
61
  </body>
37
62
  </html>
63
+ ```
64
+
65
+ ### **🎨 Available Classes**
66
+
67
+ **Colors**
68
+
69
+ | **Class** | **Effect** |
70
+ | --- | --- |
71
+ | `chai-bg-red` | Background: red |
72
+ | `chai-bg-blue` | Background: blue |
73
+ | `chai-bg-green` | Background: green |
74
+ | `chai-bg-yellow` | Background: yellow |
75
+ | `chai-bg-gray` | Background: gray |
76
+ | `chai-bg-black` | Background: black |
77
+ | `chai-bg-white` | Background: white |
78
+ | `chai-text-red` | Text: red |
79
+ | `chai-text-blue` | Text: blue |
80
+ | `chai-text-green` | Text: green |
81
+ | `chai-text-yellow` | Text: yellow |
82
+ | `chai-text-gray` | Text: gray |
83
+ | `chai-text-black` | Text: black |
84
+ | `chai-text-white` | Text: white |
85
+
86
+ ### **Spacing (1 unit = 4px)**
87
+
88
+ | **Class** | **CSS Output** |
89
+ | --- | --- |
90
+ | `chai-p-10` | `padding: 40px` |
91
+ | `chai-p-20` | `padding: 80px` |
92
+ | `chai-p-50` | `padding: 200px` |
93
+ | `chai-m-10` | `margin: 40px` |
94
+ | `chai-m-20` | `margin: 80px` |
95
+ | `chai-px-30` | `padding-left/right: 120px` |
96
+ | `chai-py-15` | `padding-top/bottom: 60px` |
97
+ | `chai-mt-10` | `margin-top: 40px` |
98
+ | `chai-mb-20` | `margin-bottom: 80px` |
99
+ | `chai-ml-10` | `margin-left: 40px` |
100
+ | `chai-mr-20` | `margin-right: 80px` |
101
+
102
+ ### **Typography**
103
+
104
+ | **Class** | **Effect** |
105
+ | --- | --- |
106
+ | `chai-text-16` | `font-size: 16px` |
107
+ | `chai-text-24` | `font-size: 24px` |
108
+ | `chai-font-bold` | `font-weight: bold` |
109
+ | `chai-text-center` | `text-align: center` |
110
+ | `chai-text-left` | `text-align: left` |
111
+ | `chai-text-right` | `text-align: right` |
112
+
113
+ ### **Layout & Flexbox**
114
+
115
+ | **Class** | **Effect** |
116
+ | --- | --- |
117
+ | `chai-flex` | `display: flex` |
118
+ | `chai-flex-col` | `flex-direction: column` |
119
+ | `chai-flex-center` | Centered flex items |
120
+ | `chai-justify-between` | `justify-content: space-between` |
121
+ | `chai-gap-10` | `gap: 10px` |
122
+
123
+ ### **Borders & Radius**
124
+
125
+ | **Class** | **Effect** |
126
+ | --- | --- |
127
+ | `chai-border-2` | `border-width: 2px` |
128
+ | `chai-border-4` | `border-width: 4px` |
129
+ | `chai-rounded-10` | `border-radius: 10px` |
130
+ | `chai-rounded-20` | `border-radius: 20px` |
131
+ | `chai-border-red` | `border-color: red` |
132
+
133
+ ### **Transforms**
134
+
135
+ | **Class** | **Effect** |
136
+ | --- | --- |
137
+ | `chai-scale-2` | `transform: scale(2)` |
138
+ | `chai-scale-3` | `transform: scale(3)` |
139
+ | `chai-scale-1` | `transform: scale(1)` |
140
+ | `chai-rotate-45` | `transform: rotate(45deg)` |
141
+ | `chai-rotate-90` | `transform: rotate(90deg)` |
142
+
143
+ ### **Hover Effects**
144
+
145
+ | **Class** | **Effect on Hover** |
146
+ | --- | --- |
147
+ | `chai-hover-scale` | Zoom effect (scale 1.05) |
148
+ | `chai-hover-bg-red` | Background changes to red |
149
+ | `chai-hover-text-white` | Text color changes to white |
150
+ | `chai-hover-shadow` | Box shadow appears |
151
+ | `chai-hover-border` | Border becomes red |
152
+
153
+ ## **📖 API**
154
+
155
+ ### `initTeawind(container)`
38
156
 
39
- Available Classes
40
- Colors
41
- chai-bg-red, chai-bg-blue, chai-bg-green, chai-bg-yellow, chai-bg-gray, chai-bg-black, chai-bg-white
157
+ Initializes Teawind on the specified container (defaults to document.body).
42
158
 
43
- chai-text-red, chai-text-blue, chai-text-green, chai-text-yellow, chai-text-gray, chai-text-black, chai-text-white
159
+ ```plaintext
160
+ import { initTeawind } from 'teawind-engine';
44
161
 
45
- Spacing (1 unit = 4px)
46
- chai-p-10 → padding: 40px
162
+ // Initialize on entire document
163
+ initTeawind();
47
164
 
48
- chai-m-20 margin: 80px
165
+ // Initialize on specific container only
166
+ initTeawind(document.querySelector('#app'));
167
+ ```
49
168
 
50
- chai-px-30 → padding-left/right: 120px
169
+ ### `applyStyles(element)`
51
170
 
52
- chai-py-15 padding-top/bottom: 60px
171
+ Manually apply Teawind styles to an element.
53
172
 
54
- Typography
55
- chai-text-16, chai-text-24 font size
173
+ ```plaintext
174
+ import { applyStyles } from 'teawind-engine';
56
175
 
57
- chai-font-bold bold text
176
+ const element = document.querySelector('.my-element');
177
+ applyStyles(element);
178
+ ```
58
179
 
59
- chai-text-center, chai-text-left, chai-text-right → text alignment
180
+ ## **💡 Examples**
60
181
 
61
- Layout
62
- chai-flex, chai-flex-col, chai-flex-center
182
+ ### **Interactive Card**
63
183
 
64
- chai-justify-between
184
+ ```plaintext
185
+ <div class="chai-bg-white chai-rounded-20 chai-p-20 chai-hover-shadow">
186
+ <h2 class="chai-text-24 chai-font-bold">Interactive Card</h2>
187
+ <p class="chai-text-16 chai-mt-10">Hover me for shadow effect!</p>
188
+ <button class="chai-bg-blue chai-text-white chai-rounded-10 chai-p-10 chai-mt-10 chai-hover-scale">
189
+ Click Me
190
+ </button>
191
+ </div>
192
+ ```
65
193
 
66
- chai-gap-10
194
+ ### **Flex Layout**
67
195
 
68
- Borders
69
- chai-border-2, chai-border-4
196
+ ```plaintext
197
+ <div class="chai-flex chai-justify-between chai-gap-10">
198
+ <div class="chai-bg-red chai-text-white chai-p-20">Item 1</div>
199
+ <div class="chai-bg-green chai-text-white chai-p-20">Item 2</div>
200
+ <div class="chai-bg-blue chai-text-white chai-p-20">Item 3</div>
201
+ </div>
202
+ ```
70
203
 
71
- chai-rounded-10, chai-rounded-20
204
+ ## **🔧 Development**
72
205
 
73
- chai-border-red
206
+ ### **Clone the repository**
74
207
 
75
- Transforms
76
- chai-scale-2, chai-scale-3, chai-scale-1
208
+ git clone https://github.com/ravi8555/teawind-engine.git
77
209
 
78
- chai-rotate-45, chai-rotate-90
210
+ ### **Navigate to project**
79
211
 
80
- Hover Effects
81
- chai-hover-scale → zoom effect
212
+ cd teawind-engine
82
213
 
83
- chai-hover-bg-red background change
214
+ ### **Install dependencies**
84
215
 
85
- chai-hover-text-white → text color change
216
+ npm install
86
217
 
87
- chai-hover-shadow shadow effect
218
+ ### **Run tests**
88
219
 
89
- chai-hover-border → border effect
220
+ npm test
90
221
 
91
- API
92
- initTeawind(container)
93
- Initializes Teawind on the specified container (defaults to document.body).
222
+ ### **Run visual demo**
94
223
 
95
- javascript
96
- import { initTeawind } from 'teawind';
97
- initTeawind();
98
- applyStyles(element)
99
- Manually apply Teawind styles to an element.
224
+ npx http-server -o demo.html
100
225
 
101
- javascript
102
- import { applyStyles } from 'teawind';
103
- const element = document.querySelector('.my-element');
104
- applyStyles(element);
105
- License
106
- MIT
107
-
108
- text
109
-
110
- ### 3. **Create `.npmignore`**
111
- node_modules/
112
- test/
113
- *.log
114
- .DS_Store
115
- .git/
116
- .github/
117
- .vscode/
226
+ ## 🤝 Contributing\*\*
227
+
228
+ Contributions are welcome! Please feel free to submit a Pull Request.
229
+
230
+ 1. Fork the repository
231
+
232
+ 2. Create your feature branch (`git checkout -b feature/amazing-feature`)
233
+
234
+ 3. Commit your changes (`git commit -m 'Add some amazing feature'`)
235
+
236
+ 4. Push to the branch (`git push origin feature/amazing-feature`)
237
+
238
+ 5. Open a Pull Request
239
+
240
+
241
+ ## **📄 License**
242
+
243
+ MIT © [Ravindra Dhadave](https://github.com/ravi8555)
244
+
245
+ * * *
246
+
247
+ Made with ❤️ by [Ravindra Dhadave](https://github.com/ravi8555)
248
+
249
+ ## Key Updates in This README
250
+
251
+ | Item | Correct Value |
252
+ | --- | --- |
253
+ | **npm package** | `teawind-engine` |
254
+ | **Install command** | `npm install teawind-engine` |
255
+ | **Import statement** | `import { initTeawind } from 'teawind-engine'` |
256
+ | **CDN URL** | `https://cdn.jsdelivr.net/npm/teawind-engine@1.0.0/src/index.js` |
257
+ | **GitHub repo** | `https://github.com/ravi8555/teawind-engine.git` |
258
+ | **Stars badge** | Points to your GitHub repo |
259
+ | **Clone command** | Uses your GitHub URL |
260
+
261
+ Save this as `README.md` in your project root. It's now consistent with both your npm package and GitHub repository! 🚀
package/demo.html ADDED
@@ -0,0 +1,395 @@
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>Teawind CSS - Visual Demo</title>
7
+ <style>
8
+ * {
9
+ margin: 0;
10
+ padding: 0;
11
+ box-sizing: border-box;
12
+ }
13
+
14
+ body {
15
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', sans-serif;
16
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
17
+ padding: 40px 20px;
18
+ }
19
+
20
+ .container {
21
+ max-width: 1400px;
22
+ margin: 0 auto;
23
+ }
24
+
25
+ /* Header */
26
+ .header {
27
+ background: white;
28
+ border-radius: 24px;
29
+ padding: 40px;
30
+ margin-bottom: 40px;
31
+ text-align: center;
32
+ box-shadow: 0 20px 40px rgba(0,0,0,0.1);
33
+ }
34
+
35
+ .header h1 {
36
+ font-size: 3rem;
37
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
38
+ -webkit-background-clip: text;
39
+ -webkit-text-fill-color: transparent;
40
+ margin-bottom: 10px;
41
+ }
42
+
43
+ .header p {
44
+ color: #666;
45
+ font-size: 1.2rem;
46
+ }
47
+
48
+ .badge {
49
+ display: inline-block;
50
+ background: #10b981;
51
+ color: white;
52
+ padding: 5px 15px;
53
+ border-radius: 20px;
54
+ font-size: 0.9rem;
55
+ margin-top: 15px;
56
+ }
57
+
58
+ /* Grid Layout */
59
+ .grid {
60
+ display: grid;
61
+ grid-template-columns: repeat(auto-fit, minmax(380px, 1fr));
62
+ gap: 25px;
63
+ margin-bottom: 40px;
64
+ }
65
+
66
+ /* Cards */
67
+ .card {
68
+ background: white;
69
+ border-radius: 20px;
70
+ padding: 25px;
71
+ box-shadow: 0 10px 30px rgba(0,0,0,0.1);
72
+ transition: transform 0.3s, box-shadow 0.3s;
73
+ }
74
+
75
+ .card:hover {
76
+ transform: translateY(-5px);
77
+ box-shadow: 0 20px 40px rgba(0,0,0,0.15);
78
+ }
79
+
80
+ .card h2 {
81
+ font-size: 1.5rem;
82
+ margin-bottom: 20px;
83
+ color: #333;
84
+ border-left: 4px solid #667eea;
85
+ padding-left: 15px;
86
+ }
87
+
88
+ .demo-section {
89
+ margin: 15px 0;
90
+ }
91
+
92
+ .demo-box {
93
+ background: #f8f9fa;
94
+ border-radius: 12px;
95
+ padding: 15px;
96
+ margin: 10px 0;
97
+ text-align: center;
98
+ }
99
+
100
+ code {
101
+ background: #f0f0f0;
102
+ padding: 4px 8px;
103
+ border-radius: 6px;
104
+ font-family: 'Courier New', monospace;
105
+ font-size: 0.85rem;
106
+ color: #d63384;
107
+ display: inline-block;
108
+ margin: 5px;
109
+ }
110
+
111
+ .flex-demo {
112
+ display: flex;
113
+ gap: 10px;
114
+ margin: 10px 0;
115
+ }
116
+
117
+ .color-swatch {
118
+ width: 80px;
119
+ height: 80px;
120
+ border-radius: 12px;
121
+ display: inline-flex;
122
+ align-items: center;
123
+ justify-content: center;
124
+ margin: 5px;
125
+ font-size: 12px;
126
+ font-weight: bold;
127
+ }
128
+
129
+ button {
130
+ background: #667eea;
131
+ color: white;
132
+ border: none;
133
+ padding: 10px 20px;
134
+ border-radius: 8px;
135
+ cursor: pointer;
136
+ font-size: 14px;
137
+ transition: all 0.3s;
138
+ }
139
+
140
+ button:hover {
141
+ background: #764ba2;
142
+ }
143
+
144
+ .live-tester {
145
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
146
+ border-radius: 24px;
147
+ padding: 30px;
148
+ margin-top: 40px;
149
+ }
150
+
151
+ .live-tester-inner {
152
+ background: white;
153
+ border-radius: 20px;
154
+ padding: 30px;
155
+ }
156
+
157
+ .live-tester input {
158
+ width: 100%;
159
+ padding: 12px 16px;
160
+ border: 2px solid #e0e0e0;
161
+ border-radius: 10px;
162
+ font-family: 'Courier New', monospace;
163
+ font-size: 14px;
164
+ margin-bottom: 20px;
165
+ }
166
+
167
+ .preview-area {
168
+ background: #f8f9fa;
169
+ border-radius: 12px;
170
+ padding: 40px;
171
+ text-align: center;
172
+ min-height: 150px;
173
+ transition: all 0.3s;
174
+ }
175
+
176
+ .example-buttons {
177
+ display: flex;
178
+ flex-wrap: wrap;
179
+ gap: 10px;
180
+ margin-top: 20px;
181
+ }
182
+
183
+ .example-btn {
184
+ background: #e9ecef;
185
+ color: #495057;
186
+ padding: 8px 12px;
187
+ font-size: 12px;
188
+ }
189
+
190
+ .example-btn:hover {
191
+ background: #667eea;
192
+ color: white;
193
+ }
194
+
195
+ footer {
196
+ text-align: center;
197
+ color: white;
198
+ margin-top: 40px;
199
+ padding: 20px;
200
+ }
201
+
202
+ footer a {
203
+ color: white;
204
+ text-decoration: none;
205
+ }
206
+ </style>
207
+ </head>
208
+ <body>
209
+ <div class="container">
210
+ <!-- Header -->
211
+ <div class="header">
212
+ <h1>🍵 Teawind CSS</h1>
213
+ <p>Lightweight utility-first CSS engine - Visual Demo</p>
214
+ <div class="badge">✨ All chai-* classes in action</div>
215
+ </div>
216
+
217
+ <div class="grid">
218
+ <!-- Colors Card -->
219
+ <div class="card">
220
+ <h2>🎨 Colors</h2>
221
+ <div class="demo-section">
222
+ <div class="chai-bg-red color-swatch">Red</div>
223
+ <div class="chai-bg-blue color-swatch">Blue</div>
224
+ <div class="chai-bg-green color-swatch">Green</div>
225
+ <div class="chai-bg-yellow color-swatch" style="color:black;">Yellow</div>
226
+ <div class="chai-bg-gray color-swatch">Gray</div>
227
+ <div class="chai-bg-black color-swatch">Black</div>
228
+ </div>
229
+ <div class="demo-section">
230
+ <p class="chai-text-red">chai-text-red - Red text</p>
231
+ <p class="chai-text-blue">chai-text-blue - Blue text</p>
232
+ <p class="chai-text-green">chai-text-green - Green text</p>
233
+ </div>
234
+ <code>chai-bg-red</code>
235
+ <code>chai-text-white</code>
236
+ <code>chai-text-blue</code>
237
+ </div>
238
+
239
+ <!-- Spacing Card -->
240
+ <div class="card">
241
+ <h2>📏 Spacing (1 unit = 4px)</h2>
242
+ <div class="demo-box chai-bg-red chai-text-white chai-p-10">chai-p-10 (40px padding)</div>
243
+ <div class="demo-box chai-bg-blue chai-text-white chai-p-20">chai-p-20 (80px padding)</div>
244
+ <div class="demo-box chai-bg-green chai-text-white chai-m-10">chai-m-10 (40px margin)</div>
245
+ <div class="demo-box chai-bg-gray chai-text-white chai-px-20 chai-py-10">chai-px-20 chai-py-10</div>
246
+ <code>chai-p-10</code>
247
+ <code>chai-m-20</code>
248
+ <code>chai-px-30</code>
249
+ </div>
250
+
251
+ <!-- Typography Card -->
252
+ <div class="card">
253
+ <h2>✍️ Typography</h2>
254
+ <div class="demo-box chai-text-16">chai-text-16 (16px font)</div>
255
+ <div class="demo-box chai-text-24 chai-font-bold">chai-text-24 + bold</div>
256
+ <div class="demo-box chai-text-center">chai-text-center alignment</div>
257
+ <div class="demo-box chai-text-left">chai-text-left</div>
258
+ <div class="demo-box chai-text-right">chai-text-right</div>
259
+ <code>chai-text-16</code>
260
+ <code>chai-text-24</code>
261
+ <code>chai-font-bold</code>
262
+ </div>
263
+
264
+ <!-- Layout & Flex Card -->
265
+ <div class="card">
266
+ <h2>🔲 Layout & Flex</h2>
267
+ <div class="chai-flex chai-gap-10">
268
+ <div class="chai-bg-red chai-text-white chai-p-10 chai-rounded-5">Flex 1</div>
269
+ <div class="chai-bg-blue chai-text-white chai-p-10 chai-rounded-5">Flex 2</div>
270
+ <div class="chai-bg-green chai-text-white chai-p-10 chai-rounded-5">Flex 3</div>
271
+ </div>
272
+ <div class="chai-flex chai-justify-between chai-mt-10 chai-mb-10">
273
+ <span>← Left</span>
274
+ <span>Center</span>
275
+ <span>Right →</span>
276
+ </div>
277
+ <div class="chai-flex chai-flex-col chai-gap-5">
278
+ <div class="chai-bg-gray chai-text-white chai-p-5 chai-rounded-5">Column 1</div>
279
+ <div class="chai-bg-gray chai-text-white chai-p-5 chai-rounded-5">Column 2</div>
280
+ </div>
281
+ <code>chai-flex</code>
282
+ <code>chai-justify-between</code>
283
+ <code>chai-flex-col</code>
284
+ </div>
285
+
286
+ <!-- Borders Card -->
287
+ <div class="card">
288
+ <h2>🖌️ Borders & Radius</h2>
289
+ <div class="demo-box chai-border-2 chai-rounded-10">border-2 + rounded-10</div>
290
+ <div class="demo-box chai-border-4 chai-rounded-20 chai-mt-10">border-4 + rounded-20</div>
291
+ <div class="demo-box chai-border-red chai-border-2 chai-mt-10">border-red + border-2</div>
292
+ <code>chai-border-2</code>
293
+ <code>chai-rounded-20</code>
294
+ <code>chai-border-red</code>
295
+ </div>
296
+
297
+ <!-- Transforms Card -->
298
+ <div class="card">
299
+ <h2>🌀 Transforms</h2>
300
+ <div class="flex-demo">
301
+ <div class="chai-scale-2 chai-bg-red chai-text-white chai-p-10 chai-rounded-5">scale-2</div>
302
+ <div class="chai-scale-3 chai-bg-blue chai-text-white chai-p-10 chai-rounded-5">scale-3</div>
303
+ </div>
304
+ <div class="flex-demo">
305
+ <div class="chai-rotate-45 chai-bg-green chai-text-white chai-p-10 chai-rounded-5">rotate-45°</div>
306
+ <div class="chai-rotate-90 chai-bg-yellow chai-p-10 chai-rounded-5">rotate-90°</div>
307
+ </div>
308
+ <code>chai-scale-2</code>
309
+ <code>chai-rotate-45</code>
310
+ <code>chai-scale-1</code>
311
+ </div>
312
+
313
+ <!-- Hover Effects Card -->
314
+ <div class="card">
315
+ <h2>✨ Hover Effects</h2>
316
+ <div class="flex-demo">
317
+ <button class="chai-hover-scale">Hover Scale ↑</button>
318
+ <button class="chai-hover-bg-red">Hover Red BG</button>
319
+ </div>
320
+ <div class="flex-demo">
321
+ <button class="chai-hover-text-white chai-bg-black">Hover White Text</button>
322
+ <div class="chai-hover-shadow chai-bg-gray chai-p-10 chai-rounded-5">Hover Shadow</div>
323
+ </div>
324
+ <div class="chai-hover-border chai-border-2 chai-p-10 chai-text-center chai-rounded-5">Hover Border</div>
325
+ <code>chai-hover-scale</code>
326
+ <code>chai-hover-shadow</code>
327
+ <code>chai-hover-border</code>
328
+ </div>
329
+
330
+ <!-- Width & Height Card -->
331
+ <div class="card">
332
+ <h2>📐 Width & Height</h2>
333
+ <div class="chai-w-full chai-bg-blue chai-text-white chai-p-10 chai-text-center chai-rounded-5">w-full (100%)</div>
334
+ <div class="chai-w-50 chai-bg-green chai-text-white chai-p-10 chai-text-center chai-rounded-5 chai-mt-5">w-50 (200px)</div>
335
+ <div class="chai-h-20 chai-bg-red chai-text-white chai-p-10 chai-text-center chai-rounded-5 chai-mt-5">h-20 (80px)</div>
336
+ <code>chai-w-full</code>
337
+ <code>chai-w-50</code>
338
+ <code>chai-h-20</code>
339
+ </div>
340
+ </div>
341
+
342
+ <!-- Live Tester -->
343
+ <div class="live-tester">
344
+ <div class="live-tester-inner">
345
+ <h2 style="margin-bottom: 20px;">🎯 Live Class Tester</h2>
346
+ <input type="text" id="classInput" placeholder="Enter chai-* classes (e.g., chai-bg-red chai-text-white chai-p-20 chai-rounded-10)">
347
+ <div id="preview" class="preview-area">
348
+ <strong>✨ Preview Element</strong><br>
349
+ Try different classes above!
350
+ </div>
351
+ <div class="example-buttons">
352
+ <button class="example-btn" onclick="setClass('chai-bg-red chai-text-white chai-p-20 chai-rounded-10')">Red Card</button>
353
+ <button class="example-btn" onclick="setClass('chai-bg-blue chai-text-white chai-p-20 chai-rounded-20')">Blue Card</button>
354
+ <button class="example-btn" onclick="setClass('chai-bg-green chai-text-white chai-p-30 chai-rounded-10 chai-scale-2')">Green Scale</button>
355
+ <button class="example-btn" onclick="setClass('chai-border-4 chai-border-red chai-rounded-20 chai-p-20')">Border Demo</button>
356
+ <button class="example-btn" onclick="setClass('chai-text-24 chai-font-bold chai-text-center chai-bg-yellow chai-p-20')">Typography</button>
357
+ </div>
358
+ </div>
359
+ </div>
360
+
361
+ <footer>
362
+ <p>🍵 Teawind CSS Engine | All <code style="color:white; background:rgba(255,255,255,0.2);">chai-*</code> classes are processed dynamically</p>
363
+ <p style="margin-top: 10px;">
364
+ <a href="https://www.npmjs.com/package/teawind-engine" target="_blank">📦 npm</a> |
365
+ <a href="https://github.com/ravi8555/teawind-engine" target="_blank">🐙 GitHub</a>
366
+ </p>
367
+ </footer>
368
+ </div>
369
+
370
+ <script type="module">
371
+ import { initTeawind, applyStyles } from './src/index.js';
372
+ console.log("initTeawind");
373
+
374
+ // Initialize Teawind
375
+ initTeawind();
376
+
377
+ // Live tester
378
+ const classInput = document.getElementById('classInput');
379
+ const preview = document.getElementById('preview');
380
+
381
+ window.setClass = (classes) => {
382
+ classInput.value = classes;
383
+ preview.className = classes;
384
+ applyStyles(preview);
385
+ };
386
+
387
+ classInput.addEventListener('input', () => {
388
+ preview.className = classInput.value;
389
+ applyStyles(preview);
390
+ });
391
+
392
+ console.log('🍵 Teawind Visual Demo Loaded!');
393
+ </script>
394
+ </body>
395
+ </html>
package/package.json CHANGED
@@ -1,37 +1,32 @@
1
- {
2
- "name": "teawind-engine",
3
- "version": "1.0.0",
4
- "description": "Lightweight utility-first CSS engine - build UIs with chai-* classes without writing CSS",
5
- "main": "src/index.js",
6
- "module": "src/index.js",
7
- "type": "module",
8
- "exports": {
9
- ".": {
10
- "import": "./src/index.js",
11
- "require": "./src/index.js",
12
- "default": "./src/index.js"
13
- }
14
- },
15
- "files": [
16
- "src",
17
- "README.md",
18
- "LICENSE"
19
- ],
20
- "keywords": [
21
- "css",
22
- "tailwind",
23
- "utility",
24
- "lightweight",
25
- "css-framework",
26
- "teawind",
27
- "chai-classes"
28
- ],
29
- "author": {
30
- "name": "Your Name",
31
- "email": "your.email@example.com"
32
- },
33
- "license": "MIT",
34
- "scripts": {
35
- "test": "echo \"Error: no test specified\" && exit 0"
36
- }
37
- }
1
+ {
2
+ "name": "teawind-engine",
3
+ "version": "1.0.1",
4
+ "description": "Lightweight utility-first CSS engine",
5
+ "main": "src/index.js",
6
+ "type": "module",
7
+ "scripts": {
8
+ "test": "vitest",
9
+ "test:run": "vitest run",
10
+ "test:ui": "vitest --ui"
11
+ },
12
+ "vitest": {
13
+ "environment": "jsdom",
14
+ "globals": true,
15
+ "include": [
16
+ "test/**/*.test.js"
17
+ ]
18
+ },
19
+ "devDependencies": {
20
+ "vitest": "^1.6.0",
21
+ "jsdom": "^23.0.0",
22
+ "@vitest/ui": "^1.6.0"
23
+ },
24
+ "keywords": [
25
+ "css",
26
+ "utility",
27
+ "teawind",
28
+ "tailwind"
29
+ ],
30
+ "author": "Ravindra Dhadave",
31
+ "license": "MIT"
32
+ }
@@ -1,3 +1,173 @@
1
+ // /**
2
+ // * Teawind Observer Module
3
+ // * Handles DOM mutation observation and style application
4
+ // */
5
+
6
+ // import { applyStyles } from '../index.js';
7
+
8
+ // /**
9
+ // * Applies Teawind styles to all elements with class attributes
10
+ // * @param {HTMLElement} container - The container element to scan (default: document.body)
11
+ // */
12
+ // export function applyToExistingElements(container = document.body) {
13
+ // const elements = container.querySelectorAll('[class]');
14
+ // elements.forEach(element => {
15
+ // applyStyles(element);
16
+ // });
17
+ // return elements.length;
18
+ // }
19
+
20
+ // /**
21
+ // * Creates and configures a MutationObserver to watch for new elements
22
+ // * @param {HTMLElement} container - The container to observe
23
+ // * @param {Object} options - Observer options
24
+ // * @returns {MutationObserver} The configured observer instance
25
+ // */
26
+ // export function createObserver(container = document.body, options = {}) {
27
+ // const defaultOptions = {
28
+ // childList: true,
29
+ // subtree: true,
30
+ // attributes: false,
31
+ // characterData: false
32
+ // };
33
+
34
+ // const observerOptions = { ...defaultOptions, ...options };
35
+
36
+ // const observer = new MutationObserver((mutations) => {
37
+ // mutations.forEach((mutation) => {
38
+ // // Handle added nodes
39
+ // if (mutation.addedNodes && mutation.addedNodes.length > 0) {
40
+ // mutation.addedNodes.forEach((node) => {
41
+ // // Check if it's an element node
42
+ // if (node.nodeType === Node.ELEMENT_NODE) {
43
+ // // Apply styles to the new element itself
44
+ // if (node.hasAttribute && node.hasAttribute('class')) {
45
+ // applyStyles(node);
46
+ // }
47
+
48
+ // // Also apply styles to any child elements with classes
49
+ // const childElements = node.querySelectorAll('[class]');
50
+ // childElements.forEach(child => {
51
+ // applyStyles(child);
52
+ // });
53
+ // }
54
+ // });
55
+ // }
56
+
57
+ // // Handle attribute changes (optional)
58
+ // if (observerOptions.attributes && mutation.type === 'attributes') {
59
+ // if (mutation.attributeName === 'class') {
60
+ // applyStyles(mutation.target);
61
+ // }
62
+ // }
63
+ // });
64
+ // });
65
+
66
+ // observer.observe(container, observerOptions);
67
+ // return observer;
68
+ // }
69
+
70
+ // /**
71
+ // * Initializes the observer and applies styles to existing elements
72
+ // * @param {HTMLElement} container - Container to observe
73
+ // * @param {Object} options - Observer options
74
+ // * @returns {Object} Observer instance and cleanup function
75
+ // */
76
+ // export function initObserver(container = document.body, options = {}) {
77
+ // // Apply to existing elements
78
+ // const elementCount = applyToExistingElements(container);
79
+ // console.log(`🍵 Teawind: Applied styles to ${elementCount} existing elements`);
80
+
81
+ // // Create observer for new elements
82
+ // const observer = createObserver(container, options);
83
+
84
+ // // Return cleanup function
85
+ // return {
86
+ // observer,
87
+ // disconnect: () => {
88
+ // observer.disconnect();
89
+ // console.log('🍵 Teawind: Observer disconnected');
90
+ // }
91
+ // };
92
+ // }
93
+
94
+ // /**
95
+ // * Watches for class changes on specific elements
96
+ // * @param {HTMLElement} element - Element to watch
97
+ // * @returns {MutationObserver} Observer for class changes
98
+ // */
99
+ // export function watchClassChanges(element) {
100
+ // if (!element) return null;
101
+
102
+ // const observer = new MutationObserver((mutations) => {
103
+ // mutations.forEach((mutation) => {
104
+ // if (mutation.attributeName === 'class') {
105
+ // applyStyles(element);
106
+ // }
107
+ // });
108
+ // });
109
+
110
+ // observer.observe(element, { attributes: true, attributeFilter: ['class'] });
111
+ // return observer;
112
+ // }
113
+
114
+ // /**
115
+ // * Debounced observer for performance optimization
116
+ // * @param {HTMLElement} container - Container to observe
117
+ // * @param {number} delay - Debounce delay in ms
118
+ // * @returns {Object} Observer with debounced updates
119
+ // */
120
+ // export function createDebouncedObserver(container = document.body, delay = 100) {
121
+ // let timeoutId = null;
122
+ // let pendingElements = new Set();
123
+
124
+ // const processElements = () => {
125
+ // pendingElements.forEach(element => {
126
+ // applyStyles(element);
127
+ // });
128
+ // pendingElements.clear();
129
+ // };
130
+
131
+ // const observer = new MutationObserver((mutations) => {
132
+ // mutations.forEach((mutation) => {
133
+ // mutation.addedNodes.forEach((node) => {
134
+ // if (node.nodeType === Node.ELEMENT_NODE) {
135
+ // pendingElements.add(node);
136
+
137
+ // // Add child elements
138
+ // node.querySelectorAll('[class]').forEach(child => {
139
+ // pendingElements.add(child);
140
+ // });
141
+ // }
142
+ // });
143
+ // });
144
+
145
+ // // Clear previous timeout and set new one
146
+ // if (timeoutId) clearTimeout(timeoutId);
147
+ // timeoutId = setTimeout(processElements, delay);
148
+ // });
149
+
150
+ // observer.observe(container, { childList: true, subtree: true });
151
+
152
+ // return {
153
+ // observer,
154
+ // disconnect: () => {
155
+ // if (timeoutId) clearTimeout(timeoutId);
156
+ // observer.disconnect();
157
+ // }
158
+ // };
159
+ // }
160
+
161
+ // // Export default object with all methods
162
+ // export default {
163
+ // init: initObserver,
164
+ // createObserver,
165
+ // applyToExistingElements,
166
+ // watchClassChanges,
167
+ // createDebouncedObserver
168
+ // };
169
+
170
+
1
171
  /**
2
172
  * Teawind Observer Module
3
173
  * Handles DOM mutation observation and style application
package/src/index.js CHANGED
@@ -127,28 +127,162 @@
127
127
  * Teawind CSS Engine - Main Entry Point
128
128
  */
129
129
 
130
+ // import { styleMap, parseDynamicClass } from './core/parser.js';
131
+ // import { injectStyles, keyframes } from './core/styles.js';
132
+ // import { initObserver } from './core/observer.js';
133
+
134
+ // // Inject base styles when the engine loads
135
+ // if (typeof document !== 'undefined') {
136
+ // injectStyles();
137
+ // }
138
+
139
+ // // Export everything
140
+ // export { styleMap, parseDynamicClass };
141
+ // export { initObserver };
142
+ // export { injectStyles, keyframes };
143
+
144
+ // // Main initialization function
145
+ // export function initTeawind(container = document.body, options = {}) {
146
+ // return initObserver(container, options);
147
+ // }
148
+
149
+ // // Default export
150
+ // export default {
151
+ // init: initTeawind,
152
+ // injectStyles,
153
+ // keyframes,
154
+ // version: '1.0.0'
155
+ // };
156
+
157
+
158
+
159
+
160
+
161
+
162
+ // src/index.js
130
163
  import { styleMap, parseDynamicClass } from './core/parser.js';
131
164
  import { injectStyles, keyframes } from './core/styles.js';
132
165
  import { initObserver } from './core/observer.js';
133
166
 
167
+ // =========================
168
+ // APPLY STYLES FUNCTION
169
+ // =========================
170
+ export function applyStyles(element) {
171
+ if (!element || !element.className) return;
172
+
173
+ const classNames = element.className.split(/\s+/);
174
+ const styleToApply = {};
175
+ const remainingClasses = [];
176
+
177
+ classNames.forEach((className) => {
178
+ if (className.startsWith("chai-")) {
179
+ const cleanClass = className.replace("chai-", "");
180
+ const style = styleMap[cleanClass];
181
+
182
+ if (style) {
183
+ Object.assign(styleToApply, style);
184
+ }
185
+
186
+ parseDynamicClass(cleanClass, styleToApply);
187
+ } else {
188
+ remainingClasses.push(className);
189
+ }
190
+ });
191
+
192
+ Object.assign(element.style, styleToApply);
193
+ element.className = remainingClasses.join(" ");
194
+
195
+ // Apply hover effects
196
+ applyHoverEffects(element);
197
+ }
198
+
199
+ // =========================
200
+ // HOVER EFFECTS
201
+ // =========================
202
+ function applyHoverEffects(element) {
203
+ const classNames = element.className.split(/\s+/);
204
+
205
+ classNames.forEach(className => {
206
+ if (className === "chai-hover-scale") {
207
+ element.addEventListener("mouseenter", () => {
208
+ element.style.transform = "scale(1.05)";
209
+ element.style.transition = "transform 0.2s";
210
+ });
211
+ element.addEventListener("mouseleave", () => {
212
+ element.style.transform = "scale(1)";
213
+ });
214
+ }
215
+
216
+ if (className === "chai-hover-bg-red") {
217
+ const originalBg = element.style.backgroundColor;
218
+ element.addEventListener("mouseenter", () => {
219
+ element.style.backgroundColor = "#ef4444";
220
+ });
221
+ element.addEventListener("mouseleave", () => {
222
+ element.style.backgroundColor = originalBg || "";
223
+ });
224
+ }
225
+
226
+ if (className === "chai-hover-text-white") {
227
+ const originalColor = element.style.color;
228
+ element.addEventListener("mouseenter", () => {
229
+ element.style.color = "#ffffff";
230
+ });
231
+ element.addEventListener("mouseleave", () => {
232
+ element.style.color = originalColor || "";
233
+ });
234
+ }
235
+
236
+ if (className === "chai-hover-shadow") {
237
+ element.addEventListener("mouseenter", () => {
238
+ element.style.boxShadow = "0 10px 25px rgba(0,0,0,0.15)";
239
+ });
240
+ element.addEventListener("mouseleave", () => {
241
+ element.style.boxShadow = "";
242
+ });
243
+ }
244
+
245
+ if (className === "chai-hover-border") {
246
+ element.addEventListener("mouseenter", () => {
247
+ element.style.borderColor = "#ef4444";
248
+ element.style.borderWidth = "2px";
249
+ });
250
+ element.addEventListener("mouseleave", () => {
251
+ element.style.borderColor = "";
252
+ element.style.borderWidth = "";
253
+ });
254
+ }
255
+ });
256
+ }
257
+
258
+ // =========================
259
+ // INITIALIZATION
260
+ // =========================
134
261
  // Inject base styles when the engine loads
135
262
  if (typeof document !== 'undefined') {
136
263
  injectStyles();
137
264
  }
138
265
 
139
- // Export everything
140
- export { styleMap, parseDynamicClass };
141
- export { initObserver };
142
- export { injectStyles, keyframes };
143
-
144
266
  // Main initialization function
145
267
  export function initTeawind(container = document.body, options = {}) {
268
+ // First apply styles to all existing elements
269
+ document.querySelectorAll('[class]').forEach(ele => {
270
+ applyStyles(ele);
271
+ });
272
+
273
+ // Then initialize observer for dynamic elements
146
274
  return initObserver(container, options);
147
275
  }
148
276
 
277
+ // Export everything
278
+ export { styleMap, parseDynamicClass };
279
+ export { initObserver };
280
+ export { injectStyles, keyframes };
281
+
149
282
  // Default export
150
283
  export default {
151
284
  init: initTeawind,
285
+ applyStyles,
152
286
  injectStyles,
153
287
  keyframes,
154
288
  version: '1.0.0'
@@ -0,0 +1,10 @@
1
+ import { defineConfig } from 'vitest/config'
2
+
3
+ export default defineConfig({
4
+ test: {
5
+ environment: 'jsdom',
6
+ globals: true,
7
+ include: ['test/**/*.test.js'],
8
+ testTimeout: 10000,
9
+ },
10
+ })
File without changes