@vueland/utils-jit 0.2.0 → 0.2.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 +32 -1069
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -4,1105 +4,68 @@
|
|
|
4
4
|
|
|
5
5
|
# @vueland/utils-jit
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
Vite JIT utility engine for the Vueland platform.
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
@vueland/utils-jit generates CSS utilities on demand from arbitrary utility classes used in your source files. It is designed for Vue/Vite projects that need a lightweight utility layer without shipping a large predefined CSS bundle.
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
## Documentation
|
|
12
12
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
-
|
|
16
|
-
- Incremental updates during development
|
|
17
|
-
- File reference counting to remove unused generated rules
|
|
18
|
-
- Built-in utilities for sizing, spacing, radius, position, z-index, opacity and colors
|
|
19
|
-
- Built-in pseudo variants such as `hover:`, `focus:` and `active:`
|
|
20
|
-
- Responsive variants through configurable breakpoints
|
|
21
|
-
- Custom selector, attribute and media variants
|
|
22
|
-
- Custom rules through `defineRule`
|
|
23
|
-
- Safe value validation before CSS generation
|
|
24
|
-
- Configurable include / exclude patterns
|
|
25
|
-
- Configurable output file
|
|
13
|
+
Full documentation and examples are available here:
|
|
14
|
+
|
|
15
|
+
https://vueland.github.io/vueland/en/plugins/utils-jit/getting-started
|
|
26
16
|
|
|
27
17
|
## Installation
|
|
28
18
|
|
|
29
|
-
|
|
30
|
-
pnpm add -D @vueland/utils-jit
|
|
31
|
-
```
|
|
19
|
+
bash pnpm add -D @vueland/utils-jit
|
|
32
20
|
|
|
33
|
-
|
|
34
|
-
npm install -D @vueland/utils-jit
|
|
35
|
-
```
|
|
21
|
+
You also need Vite installed in your project:
|
|
36
22
|
|
|
37
|
-
|
|
38
|
-
yarn add -D @vueland/utils-jit
|
|
39
|
-
```
|
|
23
|
+
bash pnpm add -D vite
|
|
40
24
|
|
|
41
25
|
## Usage
|
|
42
26
|
|
|
43
|
-
Add
|
|
44
|
-
|
|
45
|
-
```ts
|
|
46
|
-
import { defineConfig } from 'vite'
|
|
47
|
-
import vue from '@vitejs/plugins-vue'
|
|
48
|
-
import { utilsJIT } from '@vueland/utils-jit'
|
|
49
|
-
|
|
50
|
-
export default defineConfig({
|
|
51
|
-
plugins: [
|
|
52
|
-
vue(),
|
|
53
|
-
utilsJIT(),
|
|
54
|
-
],
|
|
55
|
-
})
|
|
56
|
-
```
|
|
57
|
-
|
|
58
|
-
By default, the plugin generates this file:
|
|
59
|
-
|
|
60
|
-
```txt
|
|
61
|
-
src/.generated/utils-jit.css
|
|
62
|
-
```
|
|
63
|
-
|
|
64
|
-
Import it in your application entry file:
|
|
65
|
-
|
|
66
|
-
```ts
|
|
67
|
-
import './.generated/utils-jit.css'
|
|
68
|
-
```
|
|
69
|
-
|
|
70
|
-
Now you can use arbitrary utility classes in your components:
|
|
71
|
-
|
|
72
|
-
```vue
|
|
73
|
-
<template>
|
|
74
|
-
<div class="w-[320px] px-[16px] radius-[12px] hover:w-[360px] md:px-[24px]">
|
|
75
|
-
Card content
|
|
76
|
-
</div>
|
|
77
|
-
</template>
|
|
78
|
-
```
|
|
79
|
-
|
|
80
|
-
The generated CSS will contain only the rules used in your source files.
|
|
81
|
-
|
|
82
|
-
## Quick example
|
|
83
|
-
|
|
84
|
-
```vue
|
|
85
|
-
<template>
|
|
86
|
-
<div class="w-[300px] h-[200px] px-[16px] radius-[12px] z-[10]">
|
|
87
|
-
Hello Vueland
|
|
88
|
-
</div>
|
|
89
|
-
</template>
|
|
90
|
-
```
|
|
91
|
-
|
|
92
|
-
Generated CSS example:
|
|
93
|
-
|
|
94
|
-
```css
|
|
95
|
-
/* @vueland/utils-jit: generated utilities */
|
|
96
|
-
.h-\[200px\]{height: 200px !important;}
|
|
97
|
-
.px-\[16px\]{padding-left: 16px !important;padding-right: 16px !important;}
|
|
98
|
-
.radius-\[12px\]{border-radius: 12px !important;}
|
|
99
|
-
.w-\[300px\]{width: 300px !important;}
|
|
100
|
-
.z-\[10\]{z-index: 10 !important;}
|
|
101
|
-
```
|
|
102
|
-
|
|
103
|
-
Generated rules are sorted by utility token for stable output.
|
|
104
|
-
|
|
105
|
-
## Built-in utilities
|
|
106
|
-
|
|
107
|
-
| Utility | CSS property | Example |
|
|
108
|
-
| --- | --- | --- |
|
|
109
|
-
| `w-[value]` | `width` | `w-[320px]` |
|
|
110
|
-
| `h-[value]` | `height` | `h-[200px]` |
|
|
111
|
-
| `min-w-[value]` | `min-width` | `min-w-[240px]` |
|
|
112
|
-
| `max-w-[value]` | `max-width` | `max-w-[1200px]` |
|
|
113
|
-
| `min-h-[value]` | `min-height` | `min-h-[100vh]` |
|
|
114
|
-
| `max-h-[value]` | `max-height` | `max-h-[600px]` |
|
|
115
|
-
| `ma-[value]` | `margin` | `ma-[16px]` |
|
|
116
|
-
| `mx-[value]` | `margin-left`, `margin-right` | `mx-[auto]` |
|
|
117
|
-
| `my-[value]` | `margin-top`, `margin-bottom` | `my-[24px]` |
|
|
118
|
-
| `mt-[value]` | `margin-top` | `mt-[16px]` |
|
|
119
|
-
| `mr-[value]` | `margin-right` | `mr-[12px]` |
|
|
120
|
-
| `mb-[value]` | `margin-bottom` | `mb-[24px]` |
|
|
121
|
-
| `ml-[value]` | `margin-left` | `ml-[12px]` |
|
|
122
|
-
| `pa-[value]` | `padding` | `pa-[20px]` |
|
|
123
|
-
| `px-[value]` | `padding-left`, `padding-right` | `px-[16px]` |
|
|
124
|
-
| `py-[value]` | `padding-top`, `padding-bottom` | `py-[12px]` |
|
|
125
|
-
| `pt-[value]` | `padding-top` | `pt-[10px]` |
|
|
126
|
-
| `pr-[value]` | `padding-right` | `pr-[8px]` |
|
|
127
|
-
| `pb-[value]` | `padding-bottom` | `pb-[20px]` |
|
|
128
|
-
| `pl-[value]` | `padding-left` | `pl-[16px]` |
|
|
129
|
-
| `left-[value]` | `left` | `left-[12px]` |
|
|
130
|
-
| `right-[value]` | `right` | `right-[12px]` |
|
|
131
|
-
| `top-[value]` | `top` | `top-[12px]` |
|
|
132
|
-
| `bottom-[value]` | `bottom` | `bottom-[12px]` |
|
|
133
|
-
| `inset-[value]` | `inset` | `inset-[0px]` |
|
|
134
|
-
| `radius-[value]` | `border-radius` | `radius-[12px]` |
|
|
135
|
-
| `radius-tl-[value]` | `border-top-left-radius` | `radius-tl-[8px]` |
|
|
136
|
-
| `radius-tr-[value]` | `border-top-right-radius` | `radius-tr-[8px]` |
|
|
137
|
-
| `radius-bl-[value]` | `border-bottom-left-radius` | `radius-bl-[8px]` |
|
|
138
|
-
| `radius-br-[value]` | `border-bottom-right-radius` | `radius-br-[8px]` |
|
|
139
|
-
| `z-[value]` | `z-index` | `z-[100]` |
|
|
140
|
-
| `opacity-[value]` | `opacity` | `opacity-[0.64]` |
|
|
141
|
-
| `color-[value]` | `color` | `color-[#111]` |
|
|
142
|
-
| `bg-[value]` | `background-color` | `bg-[#fff]` |
|
|
143
|
-
|
|
144
|
-
Built-in rules generate declarations with `!important`.
|
|
145
|
-
|
|
146
|
-
## Supported values
|
|
147
|
-
|
|
148
|
-
Values are validated before CSS is generated. Invalid or unsafe values are ignored.
|
|
149
|
-
|
|
150
|
-
### Size, padding, radius and position
|
|
151
|
-
|
|
152
|
-
The following utilities support length-like values:
|
|
153
|
-
|
|
154
|
-
- `w`
|
|
155
|
-
- `h`
|
|
156
|
-
- `min-w`
|
|
157
|
-
- `max-w`
|
|
158
|
-
- `min-h`
|
|
159
|
-
- `max-h`
|
|
160
|
-
- `pa`
|
|
161
|
-
- `px`
|
|
162
|
-
- `py`
|
|
163
|
-
- `pt`
|
|
164
|
-
- `pr`
|
|
165
|
-
- `pb`
|
|
166
|
-
- `pl`
|
|
167
|
-
- `radius`
|
|
168
|
-
- `left`
|
|
169
|
-
- `right`
|
|
170
|
-
- `top`
|
|
171
|
-
- `bottom`
|
|
172
|
-
- `inset`
|
|
173
|
-
|
|
174
|
-
Examples:
|
|
175
|
-
|
|
176
|
-
```html
|
|
177
|
-
<div class="w-[320px]"></div>
|
|
178
|
-
<div class="h-[50%]"></div>
|
|
179
|
-
<div class="px-[1rem]"></div>
|
|
180
|
-
<div class="radius-[12px]"></div>
|
|
181
|
-
<div class="left-[10vw]"></div>
|
|
182
|
-
<div class="w-[calc(100%-32px)]"></div>
|
|
183
|
-
<div class="max-w-[clamp(320px,50vw,960px)]"></div>
|
|
184
|
-
<div class="h-[var(--panel-height)]"></div>
|
|
185
|
-
```
|
|
186
|
-
|
|
187
|
-
Supported units:
|
|
27
|
+
Add the plugin to your Vite config:
|
|
188
28
|
|
|
189
|
-
|
|
190
|
-
px, em, rem, %, vw, vh, svw, svh, lvw, lvh, dvw, dvh, vmin, vmax, ch, ex, cm, mm, in, pt, pc
|
|
191
|
-
```
|
|
29
|
+
ts import { defineConfig } from 'vite' import { utilsJit } from '@vueland/utils-jit' export default defineConfig({ plugins: [ utilsJit(), ], })
|
|
192
30
|
|
|
193
|
-
|
|
31
|
+
Then use arbitrary utility classes in your templates:
|
|
194
32
|
|
|
195
|
-
|
|
196
|
-
calc(), min(), max(), clamp(), var()
|
|
197
|
-
```
|
|
33
|
+
vue <template> <button class="w-[160px] px-[20px] py-[12px] radius-[8px] bg-[#42b883] color-[#fff]"> Button </button> </template>
|
|
198
34
|
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
Margin utilities support length-like values and `auto`.
|
|
202
|
-
|
|
203
|
-
```html
|
|
204
|
-
<div class="ma-[16px]"></div>
|
|
205
|
-
<div class="mx-[auto]"></div>
|
|
206
|
-
<div class="mt-[2rem]"></div>
|
|
207
|
-
<div class="mb-[calc(100%-20px)]"></div>
|
|
208
|
-
<div class="ma-[10px 20px]"></div>
|
|
209
|
-
```
|
|
210
|
-
|
|
211
|
-
### Padding
|
|
212
|
-
|
|
213
|
-
Padding utilities support length-like values.
|
|
214
|
-
|
|
215
|
-
```html
|
|
216
|
-
<div class="pa-[16px]"></div>
|
|
217
|
-
<div class="px-[12px]"></div>
|
|
218
|
-
<div class="py-[8px 12px]"></div>
|
|
219
|
-
```
|
|
220
|
-
|
|
221
|
-
`auto` is not valid for padding and will be ignored.
|
|
222
|
-
|
|
223
|
-
### Radius
|
|
224
|
-
|
|
225
|
-
Radius utilities support length-like values.
|
|
226
|
-
|
|
227
|
-
```html
|
|
228
|
-
<div class="radius-[8px]"></div>
|
|
229
|
-
<div class="radius-[8px 12px]"></div>
|
|
230
|
-
<div class="radius-tl-[16px]"></div>
|
|
231
|
-
```
|
|
232
|
-
|
|
233
|
-
### Z-index
|
|
234
|
-
|
|
235
|
-
`z-[value]` supports numbers, `auto` and CSS variables.
|
|
236
|
-
|
|
237
|
-
```html
|
|
238
|
-
<div class="z-[1]"></div>
|
|
239
|
-
<div class="z-[999]"></div>
|
|
240
|
-
<div class="z-[auto]"></div>
|
|
241
|
-
<div class="z-[var(--z-modal)]"></div>
|
|
242
|
-
```
|
|
243
|
-
|
|
244
|
-
### Opacity
|
|
245
|
-
|
|
246
|
-
`opacity-[value]` supports values from `0` to `1`, CSS variables and global CSS values.
|
|
247
|
-
|
|
248
|
-
```html
|
|
249
|
-
<div class="opacity-[0]"></div>
|
|
250
|
-
<div class="opacity-[0.64]"></div>
|
|
251
|
-
<div class="opacity-[1]"></div>
|
|
252
|
-
<div class="opacity-[var(--opacity)]"></div>
|
|
253
|
-
```
|
|
254
|
-
|
|
255
|
-
### Color and background-color
|
|
256
|
-
|
|
257
|
-
`color-[value]` and `bg-[value]` support hex colors, CSS color functions, CSS variables and selected keyword values.
|
|
258
|
-
|
|
259
|
-
```html
|
|
260
|
-
<div class="color-[#111]"></div>
|
|
261
|
-
<div class="bg-[#fff]"></div>
|
|
262
|
-
<div class="bg-[rgb(255,255,255)]"></div>
|
|
263
|
-
<div class="color-[oklch(60% 0.2 20)]"></div>
|
|
264
|
-
<div class="bg-[var(--vl-surface)]"></div>
|
|
265
|
-
<div class="color-[currentColor]"></div>
|
|
266
|
-
```
|
|
267
|
-
|
|
268
|
-
Invalid values are ignored:
|
|
269
|
-
|
|
270
|
-
```html
|
|
271
|
-
<div class="w-[;]"></div>
|
|
272
|
-
<div class="radius-[.]"></div>
|
|
273
|
-
<div class="px-[auto]"></div>
|
|
274
|
-
<div class="z-[10px]"></div>
|
|
275
|
-
<div class="opacity-[2]"></div>
|
|
276
|
-
```
|
|
35
|
+
The plugin scans your project files and generates only the CSS utilities that are actually used.
|
|
277
36
|
|
|
278
37
|
## Variants
|
|
279
38
|
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
```html
|
|
283
|
-
<div class="hover:w-[320px] md:px-[24px]"></div>
|
|
284
|
-
```
|
|
285
|
-
|
|
286
|
-
### Built-in pseudo variants
|
|
287
|
-
|
|
288
|
-
The following pseudo variants are available by default:
|
|
289
|
-
|
|
290
|
-
```txt
|
|
291
|
-
hover
|
|
292
|
-
focus
|
|
293
|
-
focus-visible
|
|
294
|
-
focus-within
|
|
295
|
-
active
|
|
296
|
-
disabled
|
|
297
|
-
checked
|
|
298
|
-
visited
|
|
299
|
-
first
|
|
300
|
-
last
|
|
301
|
-
odd
|
|
302
|
-
even
|
|
303
|
-
```
|
|
304
|
-
|
|
305
|
-
Example:
|
|
306
|
-
|
|
307
|
-
```vue
|
|
308
|
-
<template>
|
|
309
|
-
<button class="w-[160px] hover:w-[180px] focus:px-[20px] active:radius-[10px]">
|
|
310
|
-
Button
|
|
311
|
-
</button>
|
|
312
|
-
</template>
|
|
313
|
-
```
|
|
314
|
-
|
|
315
|
-
Generated CSS:
|
|
316
|
-
|
|
317
|
-
```css
|
|
318
|
-
.hover\:w-\[180px\]:hover{width: 180px !important;}
|
|
319
|
-
.focus\:px-\[20px\]:focus{padding-left: 20px !important;padding-right: 20px !important;}
|
|
320
|
-
.active\:radius-\[10px\]:active{border-radius: 10px !important;}
|
|
321
|
-
```
|
|
322
|
-
|
|
323
|
-
## Responsive variants
|
|
324
|
-
|
|
325
|
-
The default breakpoints are:
|
|
326
|
-
|
|
327
|
-
```ts
|
|
328
|
-
{
|
|
329
|
-
sm: 640,
|
|
330
|
-
md: 768,
|
|
331
|
-
lg: 1024,
|
|
332
|
-
xl: 1280,
|
|
333
|
-
'2xl': 1536,
|
|
334
|
-
}
|
|
335
|
-
```
|
|
336
|
-
|
|
337
|
-
Example:
|
|
338
|
-
|
|
339
|
-
```vue
|
|
340
|
-
<template>
|
|
341
|
-
<div class="w-[100%] md:w-[720px] lg:w-[960px] xl:w-[1200px] 2xl:w-[1440px]">
|
|
342
|
-
Container
|
|
343
|
-
</div>
|
|
344
|
-
</template>
|
|
345
|
-
```
|
|
346
|
-
|
|
347
|
-
Generated CSS:
|
|
348
|
-
|
|
349
|
-
```css
|
|
350
|
-
@media (min-width: 768px) { .md\:w-\[720px\]{width: 720px !important;} }
|
|
351
|
-
@media (min-width: 1024px) { .lg\:w-\[960px\]{width: 960px !important;} }
|
|
352
|
-
@media (min-width: 1280px) { .xl\:w-\[1200px\]{width: 1200px !important;} }
|
|
353
|
-
@media (min-width: 1536px) { .2xl\:w-\[1440px\]{width: 1440px !important;} }
|
|
354
|
-
```
|
|
355
|
-
|
|
356
|
-
## Custom variants
|
|
357
|
-
|
|
358
|
-
You can add custom selector, attribute and media variants.
|
|
359
|
-
|
|
360
|
-
```ts
|
|
361
|
-
utilsJIT({
|
|
362
|
-
variants: {
|
|
363
|
-
hocus: {
|
|
364
|
-
kind: 'selector',
|
|
365
|
-
value: '&:hover,&:focus',
|
|
366
|
-
},
|
|
367
|
-
selected: {
|
|
368
|
-
kind: 'attribute',
|
|
369
|
-
value: '[aria-selected="true"]',
|
|
370
|
-
},
|
|
371
|
-
tablet: {
|
|
372
|
-
kind: 'media',
|
|
373
|
-
value: 900,
|
|
374
|
-
},
|
|
375
|
-
},
|
|
376
|
-
})
|
|
377
|
-
```
|
|
378
|
-
|
|
379
|
-
Usage:
|
|
380
|
-
|
|
381
|
-
```html
|
|
382
|
-
<div class="hocus:w-[320px] selected:bg-[#eee] tablet:px-[24px]"></div>
|
|
383
|
-
```
|
|
384
|
-
|
|
385
|
-
Generated CSS:
|
|
386
|
-
|
|
387
|
-
```css
|
|
388
|
-
.hocus\:w-\[320px\]:hover,.hocus\:w-\[320px\]:focus{width: 320px !important;}
|
|
389
|
-
.selected\:bg-\[\#eee\][aria-selected="true"]{background-color: #eee !important;}
|
|
390
|
-
@media (min-width: 900px) { .tablet\:px-\[24px\]{padding-left: 24px !important;padding-right: 24px !important;} }
|
|
391
|
-
```
|
|
392
|
-
|
|
393
|
-
### Theme variants
|
|
394
|
-
Dark mode is part of the application theme strategy. Different projects may implement it through `.dark`, `data-theme`, CSS variables, a provider, or a custom theme layer. The plugin does not enforce one specific approach.
|
|
395
|
-
|
|
396
|
-
If you need `dark:`, add it explicitly.
|
|
397
|
-
|
|
398
|
-
Using `data-theme`:
|
|
399
|
-
|
|
400
|
-
```ts
|
|
401
|
-
utilsJIT({
|
|
402
|
-
variants: {
|
|
403
|
-
dark: {
|
|
404
|
-
kind: 'selector',
|
|
405
|
-
value: '[data-theme="dark"] &',
|
|
406
|
-
},
|
|
407
|
-
},
|
|
408
|
-
})
|
|
409
|
-
```
|
|
410
|
-
|
|
411
|
-
Usage:
|
|
412
|
-
|
|
413
|
-
```html
|
|
414
|
-
<div class="bg-[#fff] dark:bg-[#111] color-[#111] dark:color-[#fff]"></div>
|
|
415
|
-
```
|
|
416
|
-
|
|
417
|
-
Generated CSS:
|
|
418
|
-
|
|
419
|
-
```css
|
|
420
|
-
[data-theme="dark"] .dark\:bg-\[\#111\]{background-color: #111 !important;}
|
|
421
|
-
[data-theme="dark"] .dark\:color-\[\#fff\]{color: #fff !important;}
|
|
422
|
-
```
|
|
423
|
-
|
|
424
|
-
Using `.dark`:
|
|
425
|
-
|
|
426
|
-
```ts
|
|
427
|
-
utilsJIT({
|
|
428
|
-
variants: {
|
|
429
|
-
dark: {
|
|
430
|
-
kind: 'selector',
|
|
431
|
-
value: '.dark &',
|
|
432
|
-
},
|
|
433
|
-
},
|
|
434
|
-
})
|
|
435
|
-
```
|
|
436
|
-
|
|
437
|
-
Usage:
|
|
438
|
-
|
|
439
|
-
```html
|
|
440
|
-
<div class="dark:bg-[#111]"></div>
|
|
441
|
-
```
|
|
442
|
-
|
|
443
|
-
Generated CSS:
|
|
444
|
-
|
|
445
|
-
```css
|
|
446
|
-
.dark .dark\:bg-\[\#111\]{background-color: #111 !important;}
|
|
447
|
-
```
|
|
448
|
-
|
|
449
|
-
## Combining variants
|
|
450
|
-
|
|
451
|
-
Pseudo variants, custom selector variants and responsive variants can be combined.
|
|
452
|
-
|
|
453
|
-
`hocus:` is not built in. Add it first:
|
|
454
|
-
|
|
455
|
-
```ts
|
|
456
|
-
utilsJIT({
|
|
457
|
-
variants: {
|
|
458
|
-
hocus: {
|
|
459
|
-
kind: 'selector',
|
|
460
|
-
value: '&:hover,&:focus',
|
|
461
|
-
},
|
|
462
|
-
},
|
|
463
|
-
})
|
|
464
|
-
```
|
|
465
|
-
|
|
466
|
-
Then it can be combined with responsive variants:
|
|
467
|
-
|
|
468
|
-
```vue
|
|
469
|
-
<template>
|
|
470
|
-
<button class="hover:md:w-[240px] focus:lg:px-[32px] hocus:xl:bg-[#eee]">
|
|
471
|
-
Responsive button
|
|
472
|
-
</button>
|
|
473
|
-
</template>
|
|
474
|
-
```
|
|
475
|
-
|
|
476
|
-
Generated CSS:
|
|
477
|
-
|
|
478
|
-
```css
|
|
479
|
-
@media (min-width: 768px) { .hover\:md\:w-\[240px\]:hover{width: 240px !important;} }
|
|
480
|
-
@media (min-width: 1024px) { .focus\:lg\:px-\[32px\]:focus{padding-left: 32px !important;padding-right: 32px !important;} }
|
|
481
|
-
@media (min-width: 1280px) { .hocus\:xl\:bg-\[\#eee\]:hover,.hocus\:xl\:bg-\[\#eee\]:focus{background-color: #eee !important;} }
|
|
482
|
-
```
|
|
483
|
-
|
|
484
|
-
## Configuration
|
|
485
|
-
|
|
486
|
-
`utilsJIT` accepts an options object.
|
|
487
|
-
|
|
488
|
-
```ts
|
|
489
|
-
import { defineConfig } from 'vite'
|
|
490
|
-
import vue from '@vitejs/plugins-vue'
|
|
491
|
-
import { utilsJIT } from '@vueland/utils-jit'
|
|
492
|
-
|
|
493
|
-
export default defineConfig({
|
|
494
|
-
plugins: [
|
|
495
|
-
vue(),
|
|
496
|
-
utilsJIT({
|
|
497
|
-
outFile: 'src/.generated/utils-jit.css',
|
|
498
|
-
include: [/\.(vue|js|ts|jsx|tsx|html)$/],
|
|
499
|
-
exclude: [/src\/fixtures/],
|
|
500
|
-
breakpoints: {
|
|
501
|
-
xs: 480,
|
|
502
|
-
sm: 640,
|
|
503
|
-
md: 768,
|
|
504
|
-
lg: 1024,
|
|
505
|
-
xl: 1280,
|
|
506
|
-
'2xl': 1536,
|
|
507
|
-
},
|
|
508
|
-
debug: false,
|
|
509
|
-
}),
|
|
510
|
-
],
|
|
511
|
-
})
|
|
512
|
-
```
|
|
513
|
-
|
|
514
|
-
## Options
|
|
515
|
-
|
|
516
|
-
| Option | Type | Default | Description |
|
|
517
|
-
| --- | --- | --- | --- |
|
|
518
|
-
| `include` | `Array<string \| RegExp>` | `[/\.(vue\|js\|ts\|jsx\|tsx\|html)$/]` | Files to scan. |
|
|
519
|
-
| `exclude` | `Array<string \| RegExp>` | Internal service directories | Files and directories to ignore. |
|
|
520
|
-
| `outFile` | `string` | `src/.generated/utils-jit.css` | Generated CSS path relative to the Vite root. |
|
|
521
|
-
| `breakpoints` | `Record<string, number>` | `sm`, `md`, `lg`, `xl`, `2xl` | Responsive variants. |
|
|
522
|
-
| `rules` | `UtilityRule[]` | `[]` | Custom utility rules. |
|
|
523
|
-
| `variants` | `VariantMap` | Built-in variants | Custom variants. |
|
|
524
|
-
| `banner` | `string` | `/* @vueland/utils-jit: generated utilities */` | Banner at the top of the generated CSS file. |
|
|
525
|
-
| `emitEmptyFile` | `boolean` | `true` | Create a file with a comment when no utilities are found. |
|
|
526
|
-
| `debug` | `boolean` | `false` | Print diagnostic messages. |
|
|
527
|
-
|
|
528
|
-
### outFile
|
|
529
|
-
|
|
530
|
-
Path to the generated CSS file relative to the Vite project root.
|
|
531
|
-
|
|
532
|
-
```ts
|
|
533
|
-
utilsJIT({
|
|
534
|
-
outFile: 'src/styles/generated/utils.css',
|
|
535
|
-
})
|
|
536
|
-
```
|
|
537
|
-
|
|
538
|
-
Then update your import accordingly:
|
|
539
|
-
|
|
540
|
-
```ts
|
|
541
|
-
import './styles/generated/utils.css'
|
|
542
|
-
```
|
|
543
|
-
|
|
544
|
-
### include
|
|
545
|
-
|
|
546
|
-
Patterns for files that should be scanned.
|
|
547
|
-
|
|
548
|
-
Default:
|
|
549
|
-
|
|
550
|
-
```ts
|
|
551
|
-
[/\.(vue|js|ts|jsx|tsx|html)$/]
|
|
552
|
-
```
|
|
553
|
-
|
|
554
|
-
Example:
|
|
555
|
-
|
|
556
|
-
```ts
|
|
557
|
-
utilsJIT({
|
|
558
|
-
include: [/\.(vue|ts)$/],
|
|
559
|
-
})
|
|
560
|
-
```
|
|
561
|
-
|
|
562
|
-
### exclude
|
|
563
|
-
|
|
564
|
-
Patterns for files and directories that should be excluded from the initial scan, transform and HMR.
|
|
565
|
-
|
|
566
|
-
The following directories are excluded by default:
|
|
567
|
-
|
|
568
|
-
```txt
|
|
569
|
-
node_modules
|
|
570
|
-
.git
|
|
571
|
-
dist
|
|
572
|
-
build
|
|
573
|
-
coverage
|
|
574
|
-
.output
|
|
575
|
-
.nuxt
|
|
576
|
-
.turbo
|
|
577
|
-
.generated
|
|
578
|
-
storybook-static
|
|
579
|
-
playwright-report
|
|
580
|
-
```
|
|
581
|
-
|
|
582
|
-
Example:
|
|
583
|
-
|
|
584
|
-
```ts
|
|
585
|
-
utilsJIT({
|
|
586
|
-
exclude: [
|
|
587
|
-
/src\/fixtures/,
|
|
588
|
-
/src\/legacy/,
|
|
589
|
-
'storybook-static',
|
|
590
|
-
],
|
|
591
|
-
})
|
|
592
|
-
```
|
|
593
|
-
|
|
594
|
-
### breakpoints
|
|
595
|
-
|
|
596
|
-
Responsive variants. The key is used as the class prefix, and the value is used as `min-width` in pixels.
|
|
597
|
-
|
|
598
|
-
```ts
|
|
599
|
-
utilsJIT({
|
|
600
|
-
breakpoints: {
|
|
601
|
-
xs: 480,
|
|
602
|
-
sm: 640,
|
|
603
|
-
md: 768,
|
|
604
|
-
lg: 1024,
|
|
605
|
-
xl: 1280,
|
|
606
|
-
'2xl': 1536,
|
|
607
|
-
'3xl': 1920,
|
|
608
|
-
},
|
|
609
|
-
})
|
|
610
|
-
```
|
|
611
|
-
|
|
612
|
-
Usage:
|
|
613
|
-
|
|
614
|
-
```html
|
|
615
|
-
<div class="xs:w-[320px] 3xl:w-[1600px]"></div>
|
|
616
|
-
```
|
|
617
|
-
|
|
618
|
-
### variants
|
|
619
|
-
|
|
620
|
-
Custom variants extend the state and selector syntax.
|
|
621
|
-
|
|
622
|
-
```ts
|
|
623
|
-
utilsJIT({
|
|
624
|
-
variants: {
|
|
625
|
-
hocus: {
|
|
626
|
-
kind: 'selector',
|
|
627
|
-
value: '&:hover,&:focus',
|
|
628
|
-
},
|
|
629
|
-
selected: {
|
|
630
|
-
kind: 'attribute',
|
|
631
|
-
value: '[aria-selected="true"]',
|
|
632
|
-
},
|
|
633
|
-
tablet: {
|
|
634
|
-
kind: 'media',
|
|
635
|
-
value: 900,
|
|
636
|
-
},
|
|
637
|
-
},
|
|
638
|
-
})
|
|
639
|
-
```
|
|
640
|
-
|
|
641
|
-
### emitEmptyFile
|
|
642
|
-
|
|
643
|
-
When `emitEmptyFile` is `true`, the plugin creates a file with this content if no utilities are found:
|
|
644
|
-
|
|
645
|
-
```css
|
|
646
|
-
/* @vueland/utils-jit: no utilities found */
|
|
647
|
-
```
|
|
648
|
-
|
|
649
|
-
When `emitEmptyFile` is `false`, the file is not created until at least one utility class is found.
|
|
650
|
-
|
|
651
|
-
```ts
|
|
652
|
-
utilsJIT({
|
|
653
|
-
emitEmptyFile: false,
|
|
654
|
-
})
|
|
655
|
-
```
|
|
656
|
-
|
|
657
|
-
## Custom utility rules
|
|
658
|
-
|
|
659
|
-
The plugin can be extended with custom rules through `rules` and `defineRule`.
|
|
660
|
-
|
|
661
|
-
```ts
|
|
662
|
-
import { defineConfig } from 'vite'
|
|
663
|
-
import vue from '@vitejs/plugins-vue'
|
|
664
|
-
import {
|
|
665
|
-
defineRule,
|
|
666
|
-
isColorValue,
|
|
667
|
-
isSizeValue,
|
|
668
|
-
utilsJIT,
|
|
669
|
-
} from '@vueland/utils-jit'
|
|
670
|
-
|
|
671
|
-
export default defineConfig({
|
|
672
|
-
plugins: [
|
|
673
|
-
vue(),
|
|
674
|
-
utilsJIT({
|
|
675
|
-
rules: [
|
|
676
|
-
defineRule({
|
|
677
|
-
name: 'surface',
|
|
678
|
-
matcher: /^surface-\[(.+)\]$/,
|
|
679
|
-
validate: isColorValue,
|
|
680
|
-
declaration: (value) => ({
|
|
681
|
-
backgroundColor: value,
|
|
682
|
-
}),
|
|
683
|
-
important: false,
|
|
684
|
-
}),
|
|
685
|
-
|
|
686
|
-
defineRule({
|
|
687
|
-
name: 'size',
|
|
688
|
-
matcher: /^size-\[(.+)\]$/,
|
|
689
|
-
validate: isSizeValue,
|
|
690
|
-
declaration: (value) => ({
|
|
691
|
-
width: value,
|
|
692
|
-
height: value,
|
|
693
|
-
}),
|
|
694
|
-
}),
|
|
695
|
-
],
|
|
696
|
-
}),
|
|
697
|
-
],
|
|
698
|
-
})
|
|
699
|
-
```
|
|
700
|
-
|
|
701
|
-
Usage:
|
|
702
|
-
|
|
703
|
-
```vue
|
|
704
|
-
<template>
|
|
705
|
-
<div class="surface-[#fff] size-[40px] hover:size-[48px]">
|
|
706
|
-
Custom utilities
|
|
707
|
-
</div>
|
|
708
|
-
</template>
|
|
709
|
-
```
|
|
710
|
-
|
|
711
|
-
Generated CSS:
|
|
712
|
-
|
|
713
|
-
```css
|
|
714
|
-
.surface-\[\#fff\]{background-color: #fff;}
|
|
715
|
-
.size-\[40px\]{width: 40px !important;height: 40px !important;}
|
|
716
|
-
.hover\:size-\[48px\]:hover{width: 48px !important;height: 48px !important;}
|
|
717
|
-
```
|
|
718
|
-
|
|
719
|
-
## defineRule API
|
|
720
|
-
|
|
721
|
-
```ts
|
|
722
|
-
defineRule({
|
|
723
|
-
name: 'rule-name',
|
|
724
|
-
matcher: /^rule-name-\[(.+)\]$/,
|
|
725
|
-
validate: (value) => true,
|
|
726
|
-
declaration: (value) => ({
|
|
727
|
-
cssProperty: value,
|
|
728
|
-
}),
|
|
729
|
-
important: true,
|
|
730
|
-
})
|
|
731
|
-
```
|
|
732
|
-
|
|
733
|
-
| Field | Type | Description |
|
|
734
|
-
| --- | --- | --- |
|
|
735
|
-
| `name` | `string` | Rule name for readability and debugging. |
|
|
736
|
-
| `matcher` | `RegExp` | Matcher for the utility part without variants. |
|
|
737
|
-
| `validate` | `(value: string) => boolean` | Validates the value inside `[]`. |
|
|
738
|
-
| `declaration` | `(value: string) => Record<string, string \| number> \| string[]` | Generates CSS declarations. |
|
|
739
|
-
| `important` | `boolean` | Adds `!important` to object-based declarations. Defaults to `true`. |
|
|
740
|
-
|
|
741
|
-
`declaration` usually returns a JS-style object:
|
|
742
|
-
|
|
743
|
-
```ts
|
|
744
|
-
defineRule({
|
|
745
|
-
name: 'bg',
|
|
746
|
-
matcher: /^bg-\[(.+)\]$/,
|
|
747
|
-
validate: isColorValue,
|
|
748
|
-
declaration: (value) => ({
|
|
749
|
-
backgroundColor: value,
|
|
750
|
-
}),
|
|
751
|
-
})
|
|
752
|
-
```
|
|
753
|
-
|
|
754
|
-
CamelCase CSS properties are converted to kebab-case:
|
|
755
|
-
|
|
756
|
-
```ts
|
|
757
|
-
{
|
|
758
|
-
backgroundColor: '#fff',
|
|
759
|
-
borderTopLeftRadius: '8px',
|
|
760
|
-
}
|
|
761
|
-
```
|
|
762
|
-
|
|
763
|
-
Result:
|
|
764
|
-
|
|
765
|
-
```css
|
|
766
|
-
background-color: #fff !important;
|
|
767
|
-
border-top-left-radius: 8px !important;
|
|
768
|
-
```
|
|
769
|
-
|
|
770
|
-
CSS variables are preserved:
|
|
771
|
-
|
|
772
|
-
```ts
|
|
773
|
-
defineRule({
|
|
774
|
-
name: 'token',
|
|
775
|
-
matcher: /^token-\[(.+)\]$/,
|
|
776
|
-
declaration: (value) => ({
|
|
777
|
-
'--vl-token': value,
|
|
778
|
-
}),
|
|
779
|
-
important: false,
|
|
780
|
-
})
|
|
781
|
-
```
|
|
782
|
-
|
|
783
|
-
Result:
|
|
784
|
-
|
|
785
|
-
```css
|
|
786
|
-
--vl-token: #fff;
|
|
787
|
-
```
|
|
788
|
-
|
|
789
|
-
If `declaration` returns `string[]`, the strings are treated as final CSS declarations. In this case, `!important` is not added automatically.
|
|
790
|
-
|
|
791
|
-
```ts
|
|
792
|
-
defineRule({
|
|
793
|
-
name: 'raw',
|
|
794
|
-
matcher: /^raw-\[(.+)\]$/,
|
|
795
|
-
declaration: (value) => [
|
|
796
|
-
`--raw-value: ${value};`,
|
|
797
|
-
],
|
|
798
|
-
})
|
|
799
|
-
```
|
|
800
|
-
|
|
801
|
-
## Validators
|
|
802
|
-
|
|
803
|
-
The package exports validators that can be reused in custom rules.
|
|
804
|
-
|
|
805
|
-
```ts
|
|
806
|
-
import {
|
|
807
|
-
isColorValue,
|
|
808
|
-
isMarginValue,
|
|
809
|
-
isOpacityValue,
|
|
810
|
-
isPaddingValue,
|
|
811
|
-
isPositionValue,
|
|
812
|
-
isRadiusValue,
|
|
813
|
-
isSizeValue,
|
|
814
|
-
isZIndexValue,
|
|
815
|
-
} from '@vueland/utils-jit'
|
|
816
|
-
```
|
|
817
|
-
|
|
818
|
-
Example:
|
|
819
|
-
|
|
820
|
-
```ts
|
|
821
|
-
defineRule({
|
|
822
|
-
name: 'text',
|
|
823
|
-
matcher: /^text-\[(.+)\]$/,
|
|
824
|
-
validate: isColorValue,
|
|
825
|
-
declaration: (value) => ({
|
|
826
|
-
color: value,
|
|
827
|
-
}),
|
|
828
|
-
})
|
|
829
|
-
```
|
|
830
|
-
|
|
831
|
-
For production rules, prefer strict validation.
|
|
832
|
-
|
|
833
|
-
```ts
|
|
834
|
-
import { defineRule } from '@vueland/utils-jit'
|
|
835
|
-
|
|
836
|
-
const gridColsRule = defineRule({
|
|
837
|
-
name: 'grid-cols',
|
|
838
|
-
matcher: /^grid-cols-\[(.+)\]$/,
|
|
839
|
-
validate: (value) => /^\d+$/.test(value),
|
|
840
|
-
declaration: (value) => ({
|
|
841
|
-
gridTemplateColumns: `repeat(${value}, minmax(0, 1fr))`,
|
|
842
|
-
}),
|
|
843
|
-
})
|
|
844
|
-
```
|
|
845
|
-
|
|
846
|
-
Usage:
|
|
847
|
-
|
|
848
|
-
```html
|
|
849
|
-
<div class="grid-cols-[3]"></div>
|
|
850
|
-
```
|
|
851
|
-
|
|
852
|
-
Generated CSS:
|
|
853
|
-
|
|
854
|
-
```css
|
|
855
|
-
.grid-cols-\[3\]{grid-template-columns: repeat(3, minmax(0, 1fr)) !important;}
|
|
856
|
-
```
|
|
857
|
-
|
|
858
|
-
## Vue class scanning
|
|
859
|
-
|
|
860
|
-
The plugin first tries to extract content from `class="..."` and `:class="..."`, then tokenizes the found chunks.
|
|
861
|
-
|
|
862
|
-
Static strings inside `:class` are supported:
|
|
863
|
-
|
|
864
|
-
```vue
|
|
865
|
-
<template>
|
|
866
|
-
<div :class="['w-[200px]', active && 'px-[16px]']"></div>
|
|
867
|
-
<div :class="{ 'radius-[12px]': rounded }"></div>
|
|
868
|
-
</template>
|
|
869
|
-
```
|
|
870
|
-
|
|
871
|
-
Runtime-generated class names are not evaluated. The class must exist as a static token in the source code.
|
|
872
|
-
|
|
873
|
-
This will not work:
|
|
874
|
-
|
|
875
|
-
```vue
|
|
876
|
-
<script setup lang="ts">
|
|
877
|
-
const width = 320
|
|
878
|
-
</script>
|
|
879
|
-
|
|
880
|
-
<template>
|
|
881
|
-
<div :class="`w-[${width}px]`"></div>
|
|
882
|
-
</template>
|
|
883
|
-
```
|
|
884
|
-
|
|
885
|
-
This will work:
|
|
886
|
-
|
|
887
|
-
```vue
|
|
888
|
-
<template>
|
|
889
|
-
<div :class="isWide ? 'w-[320px]' : 'w-[240px]'"></div>
|
|
890
|
-
</template>
|
|
891
|
-
```
|
|
892
|
-
|
|
893
|
-
## How generation works
|
|
894
|
-
|
|
895
|
-
During startup, the plugin:
|
|
896
|
-
|
|
897
|
-
1. Walks through project files.
|
|
898
|
-
2. Skips service directories like `node_modules`, `.git`, `dist`, `build` and `.generated`.
|
|
899
|
-
3. Scans only files that match `include`.
|
|
900
|
-
4. Extracts utility tokens.
|
|
901
|
-
5. Validates values.
|
|
902
|
-
6. Generates the final CSS file.
|
|
903
|
-
|
|
904
|
-
During development, the plugin updates CSS incrementally:
|
|
905
|
-
|
|
906
|
-
- adds rules for new tokens;
|
|
907
|
-
- removes rules when a token is no longer used anywhere;
|
|
908
|
-
- keeps a rule when the same token is still used in another file;
|
|
909
|
-
- reuses token parsing and CSS rule caches;
|
|
910
|
-
- notifies the Vite watcher when the generated CSS changes.
|
|
911
|
-
|
|
912
|
-
## Safety limits
|
|
913
|
-
|
|
914
|
-
To avoid unsafe or invalid CSS, the plugin limits arbitrary values:
|
|
915
|
-
|
|
916
|
-
- minimum token length: `5`;
|
|
917
|
-
- maximum token length: `180`;
|
|
918
|
-
- maximum value length: `160`;
|
|
919
|
-
- forbidden characters: `;`, `{`, `}`, `<`, `>`;
|
|
920
|
-
- CSS comments inside values are forbidden;
|
|
921
|
-
- the value must contain at least one letter or digit;
|
|
922
|
-
- only a safe subset of CSS value characters is allowed.
|
|
923
|
-
|
|
924
|
-
The following classes are ignored:
|
|
925
|
-
|
|
926
|
-
```html
|
|
927
|
-
<div class="w-[;]"></div>
|
|
928
|
-
<div class="w-[{}]"></div>
|
|
929
|
-
<div class="w-[<script>]"></div>
|
|
930
|
-
<div class="w-[...........................................]"></div>
|
|
931
|
-
```
|
|
932
|
-
|
|
933
|
-
## Recommendations
|
|
934
|
-
|
|
935
|
-
Use Utils JIT for precise one-off arbitrary values, not as a replacement for a design system.
|
|
936
|
-
|
|
937
|
-
Good:
|
|
938
|
-
|
|
939
|
-
```vue
|
|
940
|
-
<template>
|
|
941
|
-
<c-card class="max-w-[720px] px-[24px] radius-[16px]">
|
|
942
|
-
Content
|
|
943
|
-
</c-card>
|
|
944
|
-
</template>
|
|
945
|
-
```
|
|
946
|
-
|
|
947
|
-
If a value is repeated across the project, prefer moving it into a theme, preset, token or component variant.
|
|
948
|
-
|
|
949
|
-
## Troubleshooting
|
|
950
|
-
|
|
951
|
-
### The CSS file was not created
|
|
952
|
-
|
|
953
|
-
Check that:
|
|
954
|
-
|
|
955
|
-
- `utilsJIT()` is added to `vite.config.ts`;
|
|
956
|
-
- there is at least one supported utility class in the project;
|
|
957
|
-
- `outFile` is correct;
|
|
958
|
-
- the generated CSS file is imported by the application;
|
|
959
|
-
- the file matches `include`;
|
|
960
|
-
- the file is not ignored by `exclude`.
|
|
961
|
-
|
|
962
|
-
If no utilities are found and `emitEmptyFile` is `true`, the file is created with this content:
|
|
963
|
-
|
|
964
|
-
```css
|
|
965
|
-
/* @vueland/utils-jit: no utilities found */
|
|
966
|
-
```
|
|
967
|
-
|
|
968
|
-
If `emitEmptyFile` is `false`, the file appears only after at least one utility class is found.
|
|
969
|
-
|
|
970
|
-
### A class exists, but CSS is not generated
|
|
971
|
-
|
|
972
|
-
Check that:
|
|
973
|
-
|
|
974
|
-
- the file matches `include`;
|
|
975
|
-
- the file is not ignored by `exclude`;
|
|
976
|
-
- the class is written statically and is not generated at runtime;
|
|
977
|
-
- the value passes validation;
|
|
978
|
-
- the utility is supported by built-in rules or added through `rules`;
|
|
979
|
-
- the variant exists in `breakpoints` or `variants`.
|
|
980
|
-
|
|
981
|
-
### `xs:` or `3xl:` does not work
|
|
982
|
-
|
|
983
|
-
Add the breakpoint manually:
|
|
984
|
-
|
|
985
|
-
```ts
|
|
986
|
-
utilsJIT({
|
|
987
|
-
breakpoints: {
|
|
988
|
-
xs: 480,
|
|
989
|
-
sm: 640,
|
|
990
|
-
md: 768,
|
|
991
|
-
lg: 1024,
|
|
992
|
-
xl: 1280,
|
|
993
|
-
'2xl': 1536,
|
|
994
|
-
'3xl': 1920,
|
|
995
|
-
},
|
|
996
|
-
})
|
|
997
|
-
```
|
|
998
|
-
|
|
999
|
-
### A custom rule does not work
|
|
1000
|
-
|
|
1001
|
-
Make sure `matcher` matches only the utility part without variants.
|
|
1002
|
-
|
|
1003
|
-
For this class:
|
|
1004
|
-
|
|
1005
|
-
```html
|
|
1006
|
-
<div class="hover:surface-[#fff]"></div>
|
|
1007
|
-
```
|
|
1008
|
-
|
|
1009
|
-
The matcher receives:
|
|
1010
|
-
|
|
1011
|
-
```txt
|
|
1012
|
-
surface-[#fff]
|
|
1013
|
-
```
|
|
1014
|
-
|
|
1015
|
-
Correct rule:
|
|
1016
|
-
|
|
1017
|
-
```ts
|
|
1018
|
-
defineRule({
|
|
1019
|
-
name: 'surface',
|
|
1020
|
-
matcher: /^surface-\[(.+)\]$/,
|
|
1021
|
-
validate: isColorValue,
|
|
1022
|
-
declaration: (value) => ({
|
|
1023
|
-
backgroundColor: value,
|
|
1024
|
-
}),
|
|
1025
|
-
})
|
|
1026
|
-
```
|
|
39
|
+
Utility classes can be combined with variants:
|
|
1027
40
|
|
|
1028
|
-
|
|
41
|
+
vue <template> <button class="w-[160px] hover:w-[180px] focus:px-[24px]"> Button </button> </template>
|
|
1029
42
|
|
|
1030
|
-
|
|
1031
|
-
import { defineConfig } from 'vite'
|
|
1032
|
-
import vue from '@vitejs/plugins-vue'
|
|
1033
|
-
import {
|
|
1034
|
-
defineRule,
|
|
1035
|
-
isColorValue,
|
|
1036
|
-
isSizeValue,
|
|
1037
|
-
utilsJIT,
|
|
1038
|
-
} from '@vueland/utils-jit'
|
|
43
|
+
Example output:
|
|
1039
44
|
|
|
1040
|
-
|
|
1041
|
-
plugins: [
|
|
1042
|
-
vue(),
|
|
45
|
+
css .hover\:w-\[180px\]:hover { width: 180px !important; } .focus\:px-\[24px\]:focus { padding-left: 24px !important; padding-right: 24px !important; }
|
|
1043
46
|
|
|
1044
|
-
|
|
1045
|
-
outFile: 'src/.generated/utils-jit.css',
|
|
47
|
+
## Responsive utilities
|
|
1046
48
|
|
|
1047
|
-
|
|
1048
|
-
/\.(vue|js|ts|jsx|tsx|html)$/,
|
|
1049
|
-
],
|
|
49
|
+
Responsive variants are also supported:
|
|
1050
50
|
|
|
1051
|
-
|
|
1052
|
-
/src\/fixtures/,
|
|
1053
|
-
],
|
|
51
|
+
vue <template> <div class="w-[100%] md:w-[720px] lg:w-[960px]"></div> </template>
|
|
1054
52
|
|
|
1055
|
-
|
|
1056
|
-
xs: 480,
|
|
1057
|
-
sm: 640,
|
|
1058
|
-
md: 768,
|
|
1059
|
-
lg: 1024,
|
|
1060
|
-
xl: 1280,
|
|
1061
|
-
'2xl': 1536,
|
|
1062
|
-
},
|
|
53
|
+
## Why @vueland/utils-jit?
|
|
1063
54
|
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
55
|
+
- Generates utilities on demand
|
|
56
|
+
- Works with Vite
|
|
57
|
+
- Supports arbitrary values
|
|
58
|
+
- Supports pseudo-class and responsive variants
|
|
59
|
+
- Keeps generated CSS close to actual project usage
|
|
60
|
+
- Designed to be used as part of the Vueland ecosystem
|
|
1069
61
|
|
|
1070
|
-
|
|
1071
|
-
kind: 'attribute',
|
|
1072
|
-
value: '[aria-selected="true"]',
|
|
1073
|
-
},
|
|
62
|
+
## Package
|
|
1074
63
|
|
|
1075
|
-
|
|
1076
|
-
kind: 'selector',
|
|
1077
|
-
value: '[data-theme="dark"] &',
|
|
1078
|
-
},
|
|
1079
|
-
},
|
|
64
|
+
bash pnpm add -D @vueland/utils-jit
|
|
1080
65
|
|
|
1081
|
-
|
|
1082
|
-
defineRule({
|
|
1083
|
-
name: 'surface',
|
|
1084
|
-
matcher: /^surface-\[(.+)\]$/,
|
|
1085
|
-
validate: isColorValue,
|
|
1086
|
-
declaration: (value) => ({
|
|
1087
|
-
backgroundColor: value,
|
|
1088
|
-
}),
|
|
1089
|
-
important: false,
|
|
1090
|
-
}),
|
|
66
|
+
npm:
|
|
1091
67
|
|
|
1092
|
-
|
|
1093
|
-
name: 'size',
|
|
1094
|
-
matcher: /^size-\[(.+)\]$/,
|
|
1095
|
-
validate: isSizeValue,
|
|
1096
|
-
declaration: (value) => ({
|
|
1097
|
-
width: value,
|
|
1098
|
-
height: value,
|
|
1099
|
-
}),
|
|
1100
|
-
}),
|
|
1101
|
-
],
|
|
1102
|
-
}),
|
|
1103
|
-
],
|
|
1104
|
-
})
|
|
1105
|
-
```
|
|
68
|
+
https://www.npmjs.com/package/@vueland/utils-jit
|
|
1106
69
|
|
|
1107
70
|
## License
|
|
1108
71
|
|