anubis-ui 1.0.14 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +178 -65
- package/index.js +22 -10
- package/package.json +3 -2
- package/src/config/config.tool.ts +42 -38
- package/src/config/presets.config.json +47 -33
- package/src/config/qol.config.json +42 -0
- package/src/config/states.config.json +4 -0
- package/src/interfaces/config.interface.ts +16 -0
- package/src/interfaces/preset.interface.ts +18 -0
- package/src/manual/build.js +3 -0
- package/src/tools/{extract/classes/index.ts → extraction/extractClasses.ts} +15 -16
- package/src/tools/fileStuff/configFile.ts +26 -0
- package/src/tools/{cssFile.ts → fileStuff/cssFile.ts} +1 -3
- package/src/tools/{extract/extract.tools.ts → fileStuff/file.tools.ts} +0 -1
- package/src/tools/logger.ts +3 -1
- package/src/tools/mapping/mapClassIntoRule.ts +108 -84
- package/src/config/selectors.config.json +0 -13
- package/src/index.ts +0 -43
- package/src/interfaces/config.presets.interface.ts +0 -19
- package/src/manual/build.ts +0 -4
- package/src/tools/declaration/color.ts +0 -3
- package/template/colors.js +0 -5
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Improba
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -20,6 +20,7 @@ AnubisUI (Autonomous Nominative Utility Based Intuitive Styler) is a Vite plugin
|
|
|
20
20
|
5. [Prefix/Declaration relations](#prefixdeclaration-relations)
|
|
21
21
|
6. [Architecture](#architecture)
|
|
22
22
|
7. [Credits](#credits)
|
|
23
|
+
8. [Licence](#licence)
|
|
23
24
|
|
|
24
25
|
## Features
|
|
25
26
|
- 🎨 Dynamic CSS generation based on utility classes
|
|
@@ -128,7 +129,55 @@ $background-opacity: (
|
|
|
128
129
|
## Configuration
|
|
129
130
|
AnubisUI uses several configuration files located in the `src/config` directory:
|
|
130
131
|
<br />
|
|
131
|
-
|
|
132
|
+
To override default configuration, add a `anubis.config.json` in project root folder.
|
|
133
|
+
>Overriding completly replaces default configuration. You need to copy/paste it and add yours if you want to keep the default too.
|
|
134
|
+
<br />
|
|
135
|
+
|
|
136
|
+
For every config you want to change, add the corresponding section in your config file:
|
|
137
|
+
|
|
138
|
+
```js
|
|
139
|
+
{
|
|
140
|
+
// files.config.json
|
|
141
|
+
"files": {
|
|
142
|
+
"targets": ["/.vue"],
|
|
143
|
+
"ignore": []
|
|
144
|
+
},
|
|
145
|
+
|
|
146
|
+
// colors.config.json
|
|
147
|
+
"colors": ["primary", "secondary"],
|
|
148
|
+
|
|
149
|
+
// states.config.json
|
|
150
|
+
"states": ["hover"],
|
|
151
|
+
|
|
152
|
+
// qol.config.json
|
|
153
|
+
"qol": [
|
|
154
|
+
{
|
|
155
|
+
"prefix": "bg",
|
|
156
|
+
"declaration": "background: ${color}"
|
|
157
|
+
}
|
|
158
|
+
],
|
|
159
|
+
|
|
160
|
+
// presets.config.json
|
|
161
|
+
"presets": [
|
|
162
|
+
{
|
|
163
|
+
"prefix": "border",
|
|
164
|
+
"declaration": "border-width: ${value} !important; border-color: ${color} !important; border-style: solid;",
|
|
165
|
+
"variations": {
|
|
166
|
+
"default": "4px",
|
|
167
|
+
"thin": "2px"
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
]
|
|
171
|
+
}
|
|
172
|
+
```
|
|
173
|
+
<sup>anubis.config.json (example)</sup>
|
|
174
|
+
|
|
175
|
+
Only the sections you want to override need to be included - other sections will use default values. Not every
|
|
176
|
+
> Presets is still unstable, use at your own risks
|
|
177
|
+
<br />
|
|
178
|
+
You __MUST__ use the exact same [presets](#presets-presetsconfigjson) names syntax to keep it working, but variations key/values can change.
|
|
179
|
+
<br />
|
|
180
|
+
Copy-paste is recommanded
|
|
132
181
|
|
|
133
182
|
---
|
|
134
183
|
### Colors (`colors.config.json`)
|
|
@@ -146,7 +195,6 @@ Define your color palette
|
|
|
146
195
|
"warning",
|
|
147
196
|
"danger"
|
|
148
197
|
]
|
|
149
|
-
// no need to includes (lowest, lower, low, high, higher, highest) variants as long as the color name is present in the class
|
|
150
198
|
```
|
|
151
199
|
</details>
|
|
152
200
|
|
|
@@ -168,69 +216,131 @@ Specify which files to scan for classes
|
|
|
168
216
|
---
|
|
169
217
|
### Presets (`presets.config.json`)
|
|
170
218
|
Configure common style presets
|
|
219
|
+
> If overrided in config, default key/value are __REQUIRED__
|
|
220
|
+
|
|
171
221
|
<details>
|
|
172
222
|
<summary>Default config</summary>
|
|
173
223
|
|
|
174
224
|
```json
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
225
|
+
[
|
|
226
|
+
{
|
|
227
|
+
"prefix": "bg",
|
|
228
|
+
"declaration": "background: ${color}"
|
|
229
|
+
},
|
|
230
|
+
{
|
|
231
|
+
"prefix": "border",
|
|
232
|
+
"declaration": "border-width: ${value} !important; border-color: ${color} !important; border-style: solid;",
|
|
233
|
+
"variations": {
|
|
234
|
+
"default": "4px",
|
|
235
|
+
"thinest": "1px",
|
|
236
|
+
"thiner": "2px",
|
|
237
|
+
"thin": "3px",
|
|
238
|
+
"thick": "6px",
|
|
239
|
+
"thicker": "8px",
|
|
240
|
+
"thickest": "10px",
|
|
241
|
+
"node": "0.2rem"
|
|
242
|
+
}
|
|
243
|
+
},
|
|
244
|
+
{
|
|
245
|
+
"prefix": "inner-border",
|
|
246
|
+
"declaration": "box-shadow: inset 0px 0px 0px ${value} ${color}",
|
|
247
|
+
"variations": {
|
|
248
|
+
"default": "4px",
|
|
249
|
+
"thinest": "1px",
|
|
250
|
+
"thiner": "2px",
|
|
251
|
+
"thin": "3px",
|
|
252
|
+
"thick": "6px",
|
|
253
|
+
"thicker": "8px",
|
|
254
|
+
"thickest": "10px",
|
|
255
|
+
"node": "0.2rem"
|
|
256
|
+
}
|
|
257
|
+
},
|
|
258
|
+
{
|
|
259
|
+
"prefix": "shadow",
|
|
260
|
+
"declaration": "box-shadow: ${value} ${color}",
|
|
261
|
+
"variations": {
|
|
262
|
+
"default": "0px 0px 7px 1px",
|
|
263
|
+
"densest": "0px 0px 3px 1px",
|
|
264
|
+
"denser": "0px 0px 5px 1px",
|
|
265
|
+
"dense": "0px 0px 5px 1px",
|
|
266
|
+
"wide": "0px 0px 10px 1px",
|
|
267
|
+
"wider": "0px 0px 15px 1px",
|
|
268
|
+
"widest": "0px 0px 20px 1px"
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
]
|
|
206
272
|
```
|
|
207
273
|
</details>
|
|
208
274
|
|
|
209
|
-
|
|
210
275
|
---
|
|
211
|
-
###
|
|
212
|
-
Define
|
|
213
|
-
|
|
276
|
+
### Quality of Life (`qol.config.json`)
|
|
277
|
+
Define simple style rules that can have variations but don't require color values. These are CSS declarations that work independently.
|
|
214
278
|
<details>
|
|
215
279
|
<summary>Default config</summary>
|
|
216
280
|
|
|
217
281
|
```json
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
"
|
|
225
|
-
"
|
|
226
|
-
"
|
|
227
|
-
"
|
|
228
|
-
"
|
|
229
|
-
|
|
230
|
-
|
|
282
|
+
[
|
|
283
|
+
{
|
|
284
|
+
"prefix": "smooth",
|
|
285
|
+
"standalone": true,
|
|
286
|
+
"declaration": "transition-duration: ${value}",
|
|
287
|
+
"variations": {
|
|
288
|
+
"default": "0.1s",
|
|
289
|
+
"slowest": "0.5s",
|
|
290
|
+
"slower": "0.3s",
|
|
291
|
+
"slow": "0.2s",
|
|
292
|
+
"quick": "0.07s",
|
|
293
|
+
"quicker": "0.05s",
|
|
294
|
+
"quickest": "0.03s"
|
|
295
|
+
}
|
|
296
|
+
},
|
|
297
|
+
{
|
|
298
|
+
"prefix": "rounded",
|
|
299
|
+
"standalone": true,
|
|
300
|
+
"declaration": "border-radius: ${value}",
|
|
301
|
+
"variations": {
|
|
302
|
+
"default": "8px",
|
|
303
|
+
"square": "0px",
|
|
304
|
+
"xs": "2px",
|
|
305
|
+
"sm": "4px",
|
|
306
|
+
"md": "8px",
|
|
307
|
+
"lg": "12px",
|
|
308
|
+
"xl": "16px",
|
|
309
|
+
"very": "9999px",
|
|
310
|
+
"full": "50%",
|
|
311
|
+
"half": "100%"
|
|
312
|
+
}
|
|
313
|
+
},
|
|
314
|
+
{
|
|
315
|
+
"prefix": "border",
|
|
316
|
+
"declaration": "border-style: ${value}",
|
|
317
|
+
"variations": {
|
|
318
|
+
"solid": "solid",
|
|
319
|
+
"dashed": "dashed",
|
|
320
|
+
"dotted": "dotted"
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
]
|
|
231
324
|
```
|
|
232
325
|
</details>
|
|
233
326
|
|
|
327
|
+
QoL rules can have:
|
|
328
|
+
1. A prefix
|
|
329
|
+
2. A declaration that uses ${value} for variations
|
|
330
|
+
3. Optional variations with default values
|
|
331
|
+
4. Optional `standalone` flag to allow usage without variations
|
|
332
|
+
|
|
333
|
+
The `standalone` flag allows a QoL rule to be used without any variation. When set to `true`, the rule can be used:
|
|
334
|
+
- With a variation: `rounded-lg`, `smooth-slow`
|
|
335
|
+
- Without a variation: `rounded`, `smooth` (will use the default value)
|
|
336
|
+
|
|
337
|
+
When `standalone` is `false` or not specified, the rule must always include a variation (e.g., `border-dashed`).
|
|
338
|
+
|
|
339
|
+
Example usage:
|
|
340
|
+
```html
|
|
341
|
+
<div class="rounded-lg smooth-slow border-dashed" />
|
|
342
|
+
<div class="rounded smooth" /> <!-- Works because these are standalone -->
|
|
343
|
+
```
|
|
234
344
|
|
|
235
345
|
## Available Utility Classes
|
|
236
346
|
#### Colors
|
|
@@ -240,31 +350,31 @@ Define available states and style prefixes
|
|
|
240
350
|
- `inner-border-{color}` - Inner border color (inset box shadow, not compatible with `shadow-`)
|
|
241
351
|
- `shadow-{color}` - Box shadow color (not compatible with `inner-border-`)
|
|
242
352
|
|
|
353
|
+
#### Presets variations
|
|
354
|
+
- `bg-{color}-{(10-90)}` - Background opacity
|
|
355
|
+
- `border-{color}-{presetKey}` - Border width
|
|
356
|
+
- `shadow-{color}-{presetKey}` - Box shadow spread
|
|
357
|
+
- `inner-border-{color}-{presetKey}` - Box shadow inset width
|
|
358
|
+
|
|
243
359
|
#### States
|
|
244
360
|
- `hover:{utility}` - Apply style on hover
|
|
245
361
|
- `not-hover:{utility}` - Apply style when not hovering
|
|
246
362
|
|
|
247
|
-
#### Presets
|
|
248
|
-
- `bg-{color}-{(10-90)}` - Background opacity
|
|
249
|
-
- `border-{color}-{preset}` - Border width
|
|
250
|
-
- `shadow-{color}-{preset}` - Box shadow spread
|
|
251
|
-
- `inner-border-{color}-{preset}` - Box shadow inset width
|
|
252
|
-
|
|
253
363
|
## Prefix/Declaration relations
|
|
254
364
|
| prefix | declaration |
|
|
255
365
|
|--------------|-----------------------------------------------------------------------------|
|
|
256
366
|
| bg | `background: {color} important;` |
|
|
257
367
|
| text | `color: {color} important;` |
|
|
258
|
-
| border | `border-width: {
|
|
259
|
-
| inner-border | `box-shadow: inset {
|
|
260
|
-
| shadow | `box-shadow: {
|
|
368
|
+
| border | `border-width: {presetValue \|\| default} !important; border-color: {color} !important; border-style: solid;` |
|
|
369
|
+
| inner-border | `box-shadow: inset {presetValue \|\| default} {color} !important;` |
|
|
370
|
+
| shadow | `box-shadow: {presetValue \|\| default} {color} !important;` |
|
|
261
371
|
|
|
262
372
|
## Architecture
|
|
263
373
|
### Core Components
|
|
264
374
|
- **Vite Plugin**: Handles file watching and build process
|
|
265
375
|
- **Class Extractor**: Scans files for utility classes
|
|
266
376
|
- **Rule Generator**: Converts utility classes to CSS rules
|
|
267
|
-
- **Configuration System**:
|
|
377
|
+
- **Configuration System**: Manages user preferences and presets
|
|
268
378
|
|
|
269
379
|
### File Structure
|
|
270
380
|
```
|
|
@@ -272,11 +382,10 @@ Define available states and style prefixes
|
|
|
272
382
|
├── src/
|
|
273
383
|
│ ├── config/ # Configuration files
|
|
274
384
|
│ ├── interfaces/ # TypeScript interfaces
|
|
275
|
-
│ ├── manual/ # Manually trigger anubis actions
|
|
276
385
|
│ └── tools/
|
|
277
|
-
│
|
|
278
|
-
│
|
|
279
|
-
│
|
|
386
|
+
│ ├── extraction/ # Class extraction logic
|
|
387
|
+
│ ├── fileStuff/ # File handling utilities
|
|
388
|
+
│ └── mapping/ # Class to CSS rule mapping
|
|
280
389
|
└── index.js # Plugin entry point
|
|
281
390
|
```
|
|
282
391
|
|
|
@@ -285,4 +394,8 @@ Define available states and style prefixes
|
|
|
285
394
|
|
|
286
395
|
This project was made possible thanks to the support and resources provided by [__Improba__](https://improba.fr/).
|
|
287
396
|
<br />
|
|
288
|
-
Their trust and commitment played a key role in bringing this idea to life, and i'm grateful for their involvement in making it happen.
|
|
397
|
+
Their trust and commitment played a key role in bringing this idea to life, and i'm grateful for their involvement in making it happen.
|
|
398
|
+
|
|
399
|
+
## Licence
|
|
400
|
+
|
|
401
|
+
This project is licensed under the [MIT License](./LICENSE).
|
package/index.js
CHANGED
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
3
|
const { init: initConfig } = require('./dist/config/config.tool');
|
|
4
|
-
const { log, logPrefix } = require('./dist/tools/logger');
|
|
5
|
-
const { init: initClassExtraction } = require('./dist/tools/
|
|
4
|
+
const { log, logPrefix, logo } = require('./dist/tools/logger');
|
|
5
|
+
const { init: initClassExtraction } = require('./dist/tools/extraction/extractClasses');
|
|
6
6
|
|
|
7
7
|
/** List every imported colors across the projet */
|
|
8
8
|
const colors = [];
|
|
9
9
|
|
|
10
10
|
const init = async () => {
|
|
11
|
+
logo();
|
|
12
|
+
|
|
11
13
|
console.time(`${logPrefix} Config initialized in`);
|
|
12
14
|
initConfig();
|
|
13
15
|
console.timeEnd(`${logPrefix} Config initialized in`);
|
|
@@ -19,19 +21,29 @@ const init = async () => {
|
|
|
19
21
|
log('---');
|
|
20
22
|
};
|
|
21
23
|
|
|
24
|
+
const refresh = async (file) => {
|
|
25
|
+
// console.log({ file });
|
|
26
|
+
|
|
27
|
+
// _ Prevent self change loop
|
|
28
|
+
// todo - add targets / ignore detection
|
|
29
|
+
if (file.endsWith('_anubis.scss')) { return }
|
|
30
|
+
if (file.endsWith('anubis.config.json')) {
|
|
31
|
+
log('Config file changed, restarting...')
|
|
32
|
+
init();
|
|
33
|
+
return
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
console.time(`${logPrefix} Refreshed in`);
|
|
37
|
+
await initClassExtraction();
|
|
38
|
+
console.timeEnd(`${logPrefix} Refreshed in`);
|
|
39
|
+
}
|
|
40
|
+
|
|
22
41
|
function AnubisUI() {
|
|
23
42
|
return {
|
|
24
43
|
name: 'anubis-ui',
|
|
25
44
|
configureServer(server) {
|
|
26
45
|
server.watcher.on('change', async (file) => {
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
// _ Prevent self change loop
|
|
30
|
-
if (file.endsWith('_anubis.scss')) { return }
|
|
31
|
-
|
|
32
|
-
console.time(`${logPrefix} Refreshed in`);
|
|
33
|
-
await initClassExtraction();
|
|
34
|
-
console.timeEnd(`${logPrefix} Refreshed in`);
|
|
46
|
+
await refresh(file)
|
|
35
47
|
});
|
|
36
48
|
},
|
|
37
49
|
async buildStart() {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "anubis-ui",
|
|
3
|
-
"version": "1.0
|
|
3
|
+
"version": "1.2.0",
|
|
4
4
|
"description": "Class-based css generator",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"keywords": [
|
|
@@ -15,6 +15,7 @@
|
|
|
15
15
|
"vue"
|
|
16
16
|
],
|
|
17
17
|
"scripts": {
|
|
18
|
+
"dev": "npm run preinstall; node src/manual/build.js",
|
|
18
19
|
"build": "tsc",
|
|
19
20
|
"preinstall": "npm run build"
|
|
20
21
|
},
|
|
@@ -24,7 +25,7 @@
|
|
|
24
25
|
"url": "git+https://github.com/HugoLMTY/anubis-ui.git"
|
|
25
26
|
},
|
|
26
27
|
"author": "Improba",
|
|
27
|
-
"license": "
|
|
28
|
+
"license": "MIT",
|
|
28
29
|
"bugs": {
|
|
29
30
|
"url": "https://github.com/HugoLMTY/anubis-ui/issues"
|
|
30
31
|
},
|
|
@@ -1,62 +1,66 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
import { IEnvConfig } from "../interfaces/config.interface";
|
|
2
|
+
import { readUserConfigFile, userConfig } from "../tools/fileStuff/configFile"
|
|
3
|
+
import { log } from "../tools/logger"
|
|
4
|
+
|
|
3
5
|
const fs = require('fs')
|
|
4
6
|
const path = require('path')
|
|
5
7
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
[key: string]: string
|
|
10
|
-
}
|
|
11
|
-
interface IEnvConfig {
|
|
12
|
-
files: {
|
|
13
|
-
targets: string|string[],
|
|
14
|
-
ignore: string[]
|
|
15
|
-
},
|
|
16
|
-
colors: string[],
|
|
17
|
-
selectors: {
|
|
18
|
-
states: string[],
|
|
19
|
-
prefixes: string[]
|
|
20
|
-
},
|
|
21
|
-
presets: {
|
|
22
|
-
'border': IPreset[],
|
|
23
|
-
'inner-border': IPreset[],
|
|
24
|
-
'shadow': IPreset[],
|
|
25
|
-
},
|
|
26
|
-
[key: string]: any
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
const configFolder = path.join(__dirname, '..', '..', 'src', 'config');
|
|
30
|
-
const configFiles = [
|
|
8
|
+
const anubisConfigFolder = path.join(__dirname, '..', '..', 'src', 'config');
|
|
9
|
+
const anubisConfigFiles = [
|
|
10
|
+
'qol',
|
|
31
11
|
'files',
|
|
32
12
|
'colors',
|
|
13
|
+
'states',
|
|
33
14
|
'presets',
|
|
34
|
-
'selectors'
|
|
35
15
|
]
|
|
36
16
|
|
|
37
17
|
const config = {
|
|
18
|
+
qol: [],
|
|
19
|
+
presets: [],
|
|
20
|
+
|
|
38
21
|
files: { targets: [], ignore: [] },
|
|
39
22
|
colors: [],
|
|
40
|
-
|
|
41
|
-
presets: {
|
|
42
|
-
border: [],
|
|
43
|
-
"inner-border": [],
|
|
44
|
-
shadow: [],
|
|
45
|
-
},
|
|
23
|
+
states: [],
|
|
46
24
|
} as IEnvConfig
|
|
47
25
|
|
|
48
26
|
const init = () => {
|
|
49
|
-
|
|
50
|
-
|
|
27
|
+
readUserConfigFile()
|
|
28
|
+
|
|
29
|
+
checkUserConfig()
|
|
30
|
+
|
|
31
|
+
for (const file of anubisConfigFiles) {
|
|
32
|
+
let configToUse = null
|
|
51
33
|
|
|
52
|
-
|
|
34
|
+
if (userConfig && userConfig[file]) {
|
|
35
|
+
log(`${file} config found, overriding default.`)
|
|
36
|
+
configToUse = userConfig[file]
|
|
37
|
+
} else {
|
|
38
|
+
const filePath = path.join(anubisConfigFolder, `${file}.config.json`)
|
|
39
|
+
const configContent = fs.readFileSync(filePath, { encoding: 'utf-8' })
|
|
53
40
|
|
|
54
|
-
|
|
41
|
+
configToUse = JSON.parse(configContent)
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
config[file as keyof typeof config] = configToUse
|
|
55
45
|
}
|
|
56
46
|
|
|
57
47
|
return config
|
|
58
48
|
}
|
|
59
49
|
|
|
50
|
+
const checkUserConfig = () => {
|
|
51
|
+
|
|
52
|
+
// todo - also check values
|
|
53
|
+
const userConfigKeys = Object.keys(userConfig)
|
|
54
|
+
|
|
55
|
+
const unknownKeys = userConfigKeys?.filter(key => !anubisConfigFiles.includes(key))
|
|
56
|
+
if (!unknownKeys?.length) { return }
|
|
57
|
+
|
|
58
|
+
log(`${unknownKeys?.length} unknown config keys found in user config file`)
|
|
59
|
+
for (const key of unknownKeys) {
|
|
60
|
+
log(`- ${key}`)
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
60
64
|
export {
|
|
61
65
|
init,
|
|
62
66
|
config
|
|
@@ -1,33 +1,47 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
}
|
|
1
|
+
[
|
|
2
|
+
{
|
|
3
|
+
"prefix": "bg",
|
|
4
|
+
"declaration": "background: ${color}"
|
|
5
|
+
},
|
|
6
|
+
{
|
|
7
|
+
"prefix": "border",
|
|
8
|
+
"declaration": "border-width: ${value} !important; border-color: ${color} !important; border-style: solid;",
|
|
9
|
+
"variations": {
|
|
10
|
+
"default": "4px",
|
|
11
|
+
"thinest": "1px",
|
|
12
|
+
"thiner": "2px",
|
|
13
|
+
"thin": "3px",
|
|
14
|
+
"thick": "6px",
|
|
15
|
+
"thicker": "8px",
|
|
16
|
+
"thickest": "10px",
|
|
17
|
+
"node": "0.2rem"
|
|
18
|
+
}
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
"prefix": "inner-border",
|
|
22
|
+
"declaration": "box-shadow: inset 0px 0px 0px ${value} ${color}",
|
|
23
|
+
"variations": {
|
|
24
|
+
"default": "4px" ,
|
|
25
|
+
"thinest": "1px" ,
|
|
26
|
+
"thiner": "2px" ,
|
|
27
|
+
"thin": "3px" ,
|
|
28
|
+
"thick": "6px" ,
|
|
29
|
+
"thicker": "8px" ,
|
|
30
|
+
"thickest": "10px" ,
|
|
31
|
+
"node": "0.2rem"
|
|
32
|
+
}
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
"prefix": "shadow",
|
|
36
|
+
"declaration": "box-shadow: ${value} ${color}",
|
|
37
|
+
"variations": {
|
|
38
|
+
"default": "0px 0px 7px 1px" ,
|
|
39
|
+
"densest": "0px 0px 3px 1px" ,
|
|
40
|
+
"denser": "0px 0px 5px 1px" ,
|
|
41
|
+
"dense": "0px 0px 5px 1px" ,
|
|
42
|
+
"wide": "0px 0px 10px 1px" ,
|
|
43
|
+
"wider": "0px 0px 15px 1px" ,
|
|
44
|
+
"widest": "0px 0px 20px 1px"
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
]
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
[
|
|
2
|
+
{
|
|
3
|
+
"prefix": "smooth",
|
|
4
|
+
"standalone": true,
|
|
5
|
+
"declaration": "transition-duration: ${value}",
|
|
6
|
+
"variations": {
|
|
7
|
+
"default": "0.1s",
|
|
8
|
+
"slowest": "0.5s",
|
|
9
|
+
"slower": "0.3s",
|
|
10
|
+
"slow": "0.2s",
|
|
11
|
+
"quick": "0.07s",
|
|
12
|
+
"quicker": "0.05s",
|
|
13
|
+
"quickest": "0.03s"
|
|
14
|
+
}
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
"prefix": "rounded",
|
|
18
|
+
"standalone": true,
|
|
19
|
+
"declaration": "border-radius: ${value}",
|
|
20
|
+
"variations": {
|
|
21
|
+
"default": "8px",
|
|
22
|
+
"square": "0px",
|
|
23
|
+
"xs": "2px",
|
|
24
|
+
"sm": "4px",
|
|
25
|
+
"md": "8px",
|
|
26
|
+
"lg": "12px",
|
|
27
|
+
"xl": "16s",
|
|
28
|
+
"very": "9999px",
|
|
29
|
+
"full": "50%",
|
|
30
|
+
"half": "100%"
|
|
31
|
+
}
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
"prefix": "border",
|
|
35
|
+
"declaration": "border-style: ${value}",
|
|
36
|
+
"variations": {
|
|
37
|
+
"solid": "solid",
|
|
38
|
+
"dashed": "dashed",
|
|
39
|
+
"dotted": "dotted"
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
]
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { IPreset } from "./preset.interface"
|
|
2
|
+
|
|
3
|
+
export interface IFilePatterns {
|
|
4
|
+
targets: string|string[],
|
|
5
|
+
ignore: string[]
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export interface IEnvConfig {
|
|
9
|
+
qol: IPreset[]
|
|
10
|
+
presets: IPreset[],
|
|
11
|
+
files: IFilePatterns,
|
|
12
|
+
|
|
13
|
+
colors: string[],
|
|
14
|
+
states: string[],
|
|
15
|
+
[key: string]: any
|
|
16
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export interface IVariation {
|
|
2
|
+
[key: string]: string
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
export interface IPreset {
|
|
6
|
+
// [key: string]: string
|
|
7
|
+
prefix: string,
|
|
8
|
+
declaration: string,
|
|
9
|
+
|
|
10
|
+
/** When true, class can be called without variation, creating a rule with default variation */
|
|
11
|
+
standalone?: boolean,
|
|
12
|
+
|
|
13
|
+
/**In a quasar project (quasar.variabls.scss), will set as !default the precised key with the default variations */
|
|
14
|
+
globalVariableOverride?: string,
|
|
15
|
+
|
|
16
|
+
/** List of every possible variations */
|
|
17
|
+
variations: IVariation
|
|
18
|
+
}
|
|
@@ -1,22 +1,19 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
1
|
+
import { getFiles } from "../fileStuff/file.tools"
|
|
2
|
+
import { mapClassesIntoRules } from "../mapping/mapClassIntoRule"
|
|
3
|
+
import { buildCssRuleFile } from "../fileStuff/cssFile"
|
|
4
|
+
import { config } from "../../config/config.tool"
|
|
5
5
|
|
|
6
|
-
// import fs from 'fs'
|
|
7
6
|
const fs = require('fs')
|
|
8
7
|
|
|
9
8
|
/** Fetch vue file based on config target patterns */
|
|
10
9
|
const init = async () => {
|
|
11
10
|
const files = await getFiles(config.files)
|
|
12
|
-
// console.log({ files })
|
|
13
11
|
|
|
14
12
|
const uniqueClasses = await getUniqueClasses(files)
|
|
15
13
|
const mappedRules = mapClassesIntoRules(uniqueClasses)
|
|
16
|
-
// console.log({ uniqueClasses, mappedRules })
|
|
17
14
|
|
|
18
15
|
const file = buildCssRuleFile(mappedRules)
|
|
19
|
-
|
|
16
|
+
return file
|
|
20
17
|
}
|
|
21
18
|
|
|
22
19
|
/** Extract detected class and map into a flat set */
|
|
@@ -28,8 +25,6 @@ const getUniqueClasses = async (files: string[]): Promise<string[]> => {
|
|
|
28
25
|
?.sort()
|
|
29
26
|
|
|
30
27
|
const uniqueClasses = Array.from(new Set(extractedClasses))
|
|
31
|
-
// log(`${uniqueClasses?.length} classes found`)
|
|
32
|
-
|
|
33
28
|
return uniqueClasses
|
|
34
29
|
}
|
|
35
30
|
|
|
@@ -38,16 +33,20 @@ const extractClasses = async (filePath: string): Promise<string[]> => {
|
|
|
38
33
|
const file = await fs.promises.readFile(filePath, 'utf-8')
|
|
39
34
|
if (!file) { return [] }
|
|
40
35
|
|
|
41
|
-
const { states,
|
|
36
|
+
const { states, qol, presets } = config
|
|
42
37
|
|
|
43
|
-
const
|
|
44
|
-
const
|
|
38
|
+
const partialPrefixes = presets?.map(p => `${p.prefix}-`)
|
|
39
|
+
const partialQol = qol?.map(q => `${q.prefix}`)
|
|
45
40
|
|
|
46
|
-
const
|
|
41
|
+
const mappedPrefixes = [
|
|
42
|
+
...partialPrefixes,
|
|
43
|
+
...partialQol
|
|
44
|
+
]?.join('|')
|
|
45
|
+
const mappedStates = `(${states?.map(s => `${s}:`)?.join('|')})`
|
|
47
46
|
|
|
48
|
-
const
|
|
49
|
-
if (!matches?.length) { return [] }
|
|
47
|
+
const classDetectionRegex = new RegExp(`${mappedStates}?(${mappedPrefixes})(-?(\\w+(-+)?)+)?`, 'gi')
|
|
50
48
|
|
|
49
|
+
const matches = file.match(classDetectionRegex) || []
|
|
51
50
|
return matches
|
|
52
51
|
}
|
|
53
52
|
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
const fs = require('fs')
|
|
2
|
+
const path = require('path')
|
|
3
|
+
|
|
4
|
+
import { log } from '../logger'
|
|
5
|
+
|
|
6
|
+
const userConfigPath = path.join(process.cwd(), 'anubis.config.json')
|
|
7
|
+
let userConfig = null
|
|
8
|
+
|
|
9
|
+
const readUserConfigFile = () => {
|
|
10
|
+
const userConfigExists = fs.existsSync(userConfigPath)
|
|
11
|
+
|
|
12
|
+
if (!userConfigExists) {
|
|
13
|
+
log('No user config file found, using default configuration.')
|
|
14
|
+
return
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
const config = fs.readFileSync(userConfigPath, { encoding: 'utf-8'})
|
|
18
|
+
userConfig = JSON.parse(config)
|
|
19
|
+
|
|
20
|
+
return userConfig
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export {
|
|
24
|
+
userConfig,
|
|
25
|
+
readUserConfigFile
|
|
26
|
+
}
|
|
@@ -1,9 +1,7 @@
|
|
|
1
|
-
// import fs from 'fs'
|
|
2
|
-
// import path from 'path'
|
|
3
1
|
const fs = require('fs')
|
|
4
2
|
const path = require('path')
|
|
5
3
|
|
|
6
|
-
import { cssHeader, log } from '
|
|
4
|
+
import { cssHeader, log } from '../logger'
|
|
7
5
|
|
|
8
6
|
const srcDir = path.join(process.cwd(), 'src', 'css')
|
|
9
7
|
const outputPath = path.join(srcDir, '_anubis.scss')
|
package/src/tools/logger.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
const logPrefix = '☯︎ [ANUBIS]'
|
|
2
2
|
const log = (str: string) => console.log(`${logPrefix} ${str}`)
|
|
3
3
|
|
|
4
|
+
const { version } = require('./../../package.json')
|
|
5
|
+
|
|
4
6
|
const logo = () => {
|
|
5
7
|
log(' ___ _ ____ ______ _________')
|
|
6
8
|
log(' / | / | / / / / / __ )/ _/ ___/')
|
|
@@ -14,7 +16,7 @@ const logo = () => {
|
|
|
14
16
|
}
|
|
15
17
|
|
|
16
18
|
const cssHeader = `/*!
|
|
17
|
-
* * Anubis v
|
|
19
|
+
* * Anubis v.${version}
|
|
18
20
|
* * Improba
|
|
19
21
|
* * Released under the MIT License.
|
|
20
22
|
* */`
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { config } from "../../config/config.tool"
|
|
2
|
+
import { IPreset } from "../../interfaces/preset.interface"
|
|
2
3
|
import { log } from "../logger"
|
|
3
4
|
|
|
4
5
|
const mapClassesIntoRules = (classes: string[]) => {
|
|
@@ -13,31 +14,52 @@ const mapClassesIntoRules = (classes: string[]) => {
|
|
|
13
14
|
}
|
|
14
15
|
|
|
15
16
|
const mapClassIntoRule = (stringClass: string) => {
|
|
16
|
-
const colorExists = config.colors?.some(color => stringClass.includes(color))
|
|
17
|
-
if (!colorExists) { return }
|
|
18
|
-
|
|
19
17
|
const params = getClassInfos(stringClass)
|
|
20
|
-
// console.log({ params })
|
|
21
18
|
|
|
22
|
-
|
|
23
|
-
|
|
19
|
+
/**
|
|
20
|
+
* _ If no variations are found, maybe it's just a color like bg-primary
|
|
21
|
+
* _ So we need to check if the color exists to avoid useless computing
|
|
22
|
+
* */
|
|
23
|
+
if (!params.preset) {
|
|
24
|
+
const { colorExists } = checkOpacity(params.color)
|
|
25
|
+
|
|
26
|
+
if (!colorExists) {
|
|
27
|
+
return
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* _ If the current QoL isn't standalone (can be called without variation)
|
|
33
|
+
* _ no
|
|
34
|
+
*/
|
|
35
|
+
if (!params.color && !params.preset?.standalone) {
|
|
36
|
+
return
|
|
37
|
+
}
|
|
24
38
|
|
|
39
|
+
const rule = mapIntoRule(params)
|
|
25
40
|
return rule
|
|
26
41
|
}
|
|
27
42
|
|
|
28
|
-
const getClassInfos = (stringClass: string)
|
|
43
|
+
const getClassInfos = (stringClass: string) => {
|
|
29
44
|
const { cleanedClass, state } = getStateInfos(stringClass)
|
|
30
45
|
const { cleanedColor, prefix } = getPrefixInfos(cleanedClass)
|
|
31
|
-
const {
|
|
46
|
+
const { preset, variation } = getPresetInfos({ cleanedColor, prefix })
|
|
47
|
+
|
|
48
|
+
return {
|
|
49
|
+
state,
|
|
32
50
|
|
|
33
|
-
|
|
34
|
-
|
|
51
|
+
color: cleanedColor,
|
|
52
|
+
prefix,
|
|
53
|
+
|
|
54
|
+
preset,
|
|
55
|
+
variation
|
|
56
|
+
}
|
|
35
57
|
}
|
|
36
58
|
|
|
37
59
|
const getStateInfos = (stringClass: string) => {
|
|
38
60
|
let state = undefined
|
|
39
61
|
|
|
40
|
-
for (const configState of config.
|
|
62
|
+
for (const configState of config.states) {
|
|
41
63
|
if (!stringClass.startsWith(configState)) { continue }
|
|
42
64
|
|
|
43
65
|
state = configState
|
|
@@ -51,62 +73,67 @@ const getStateInfos = (stringClass: string) => {
|
|
|
51
73
|
}
|
|
52
74
|
|
|
53
75
|
const getPrefixInfos = (stringClass: string): { cleanedColor: string, prefix: string } => {
|
|
54
|
-
|
|
76
|
+
const prefixes = [
|
|
77
|
+
...config.presets?.map(q => q.prefix),
|
|
78
|
+
...config.qol?.map(q => q.prefix)
|
|
79
|
+
]
|
|
55
80
|
|
|
56
|
-
for (const
|
|
57
|
-
if (!stringClass.startsWith(
|
|
81
|
+
for (const prefix of prefixes) {
|
|
82
|
+
if (!stringClass.startsWith(prefix)) { continue }
|
|
58
83
|
|
|
59
|
-
|
|
84
|
+
return {
|
|
85
|
+
cleanedColor: stringClass?.slice(prefix.length + 1),
|
|
86
|
+
prefix
|
|
87
|
+
}
|
|
60
88
|
}
|
|
61
89
|
|
|
62
|
-
return
|
|
63
|
-
cleanedColor: stringClass?.slice(prefix.length + 1),
|
|
64
|
-
prefix,
|
|
65
|
-
}
|
|
90
|
+
return null
|
|
66
91
|
}
|
|
67
92
|
|
|
68
|
-
const
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
93
|
+
const getPresetInfos = ({ cleanedColor, prefix }: { cleanedColor: string, prefix?: string }) => {
|
|
94
|
+
/**
|
|
95
|
+
* _ Find preset variants matching the prefix from the config
|
|
96
|
+
* _ Since a prefix can be in multiple presets and qol, filter every matching prefixes then flatten everything
|
|
97
|
+
* TODO fix first default occurence getting picked when duplicate
|
|
98
|
+
* */
|
|
99
|
+
const possiblePresets = [...config.presets, ...config.qol]
|
|
100
|
+
?.filter(p => p.prefix === prefix)
|
|
101
|
+
?.flat()
|
|
102
|
+
if (!possiblePresets?.length) { return { matchingPreset: null, variation: null } }
|
|
103
|
+
|
|
104
|
+
const { colorExists } = checkOpacity(cleanedColor)
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Find the preset where the variations exists
|
|
108
|
+
* If the color exists, it is a preset, so use the preset
|
|
109
|
+
* */
|
|
110
|
+
const matchingPreset = colorExists || !cleanedColor
|
|
111
|
+
? possiblePresets[0]
|
|
112
|
+
: possiblePresets?.find(({ variations }) => !variations || Object.keys(variations)?.find(v => cleanedColor.endsWith(v)))
|
|
113
|
+
|
|
114
|
+
if (!matchingPreset) {
|
|
115
|
+
log(`No preset found for ${cleanedColor || prefix}`)
|
|
116
|
+
|
|
73
117
|
return {
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
// variation: {
|
|
77
|
-
// key: 'opacity',
|
|
78
|
-
// value: cleanedColor?.slice(-2),
|
|
79
|
-
// }
|
|
118
|
+
matchingPreset,
|
|
119
|
+
variation: null
|
|
80
120
|
}
|
|
81
121
|
}
|
|
82
122
|
|
|
83
|
-
|
|
84
|
-
const variants = config.presets[prefix as keyof typeof config.presets]
|
|
85
|
-
if (!variants) { return { color: cleanedColor } }
|
|
86
|
-
|
|
87
|
-
// _ Map found variants into a key/value object
|
|
88
|
-
const matchingVariants = variants
|
|
89
|
-
?.map(v => Object.entries(v))
|
|
90
|
-
?.flat()
|
|
91
|
-
?.map(([key, value]) => ({ key, value }))
|
|
92
|
-
// ?.filter(({ key }) => key !== 'default')
|
|
123
|
+
const possibleVariations = (matchingPreset.variations || { default: '' })
|
|
93
124
|
|
|
94
|
-
const
|
|
95
|
-
|
|
125
|
+
const matchingVariation = Object.keys(possibleVariations)
|
|
126
|
+
?.find(v => cleanedColor.endsWith(v)) || 'default'
|
|
96
127
|
|
|
97
|
-
const
|
|
98
|
-
? cleanedColor?.slice(0, variation.key.length + 1)
|
|
99
|
-
: cleanedColor
|
|
128
|
+
const variation = possibleVariations[matchingVariation]
|
|
100
129
|
|
|
101
130
|
return {
|
|
102
|
-
|
|
103
|
-
variation
|
|
131
|
+
preset: matchingPreset,
|
|
132
|
+
variation,
|
|
104
133
|
}
|
|
105
134
|
}
|
|
106
135
|
|
|
107
|
-
|
|
108
|
-
const colorVar = `var(--${color})`
|
|
109
|
-
|
|
136
|
+
const mapIntoRule = ({ state, prefix, color, preset, variation }) => {
|
|
110
137
|
// _ Set state selector
|
|
111
138
|
let stateSelector = ''
|
|
112
139
|
switch (state) {
|
|
@@ -119,50 +146,47 @@ function mapIntoRule({ state, prefix, color, variation }: { state?: string, pref
|
|
|
119
146
|
break
|
|
120
147
|
}
|
|
121
148
|
|
|
122
|
-
let
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
switch (prefix) {
|
|
127
|
-
case 'bg':
|
|
128
|
-
declaration = `background: ${colorVar} !important`
|
|
129
|
-
break
|
|
130
|
-
|
|
131
|
-
case 'text':
|
|
132
|
-
declaration = `color: ${colorVar} !important`
|
|
133
|
-
break
|
|
134
|
-
|
|
135
|
-
case 'border':
|
|
136
|
-
declaration = `border-width: ${variation?.value} !important; border-color: ${colorVar} !important; border-style: solid`
|
|
137
|
-
break
|
|
138
|
-
|
|
139
|
-
case 'inner-border':
|
|
140
|
-
declaration = `box-shadow: inset ${variation?.value} ${colorVar} !important`
|
|
141
|
-
break
|
|
142
|
-
|
|
143
|
-
case 'shadow':
|
|
144
|
-
declaration = `box-shadow: ${variation?.value} ${colorVar} !important`
|
|
145
|
-
break
|
|
149
|
+
let selector = `${prefix}${color ? `-${color}` : ''}`
|
|
150
|
+
if (state) {
|
|
151
|
+
selector = `${state}\\:${selector}${stateSelector}`
|
|
152
|
+
}
|
|
146
153
|
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
154
|
+
const colorVar = `var(--${color})`
|
|
155
|
+
let declaration = preset.declaration
|
|
156
|
+
?.replace('${value}', variation)
|
|
157
|
+
?.replace('${color}', colorVar)
|
|
151
158
|
|
|
152
|
-
|
|
153
|
-
|
|
159
|
+
if (!declaration.endsWith(';')) {
|
|
160
|
+
declaration += ';'
|
|
154
161
|
}
|
|
155
162
|
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
163
|
+
if (!declaration.includes('!important')) {
|
|
164
|
+
declaration = declaration
|
|
165
|
+
?.replace(';', ' !important;')
|
|
159
166
|
}
|
|
160
167
|
|
|
161
168
|
const rule = `.${selector} { ${declaration} }`
|
|
162
|
-
|
|
163
169
|
return rule
|
|
164
170
|
}
|
|
165
171
|
|
|
172
|
+
/**
|
|
173
|
+
* _ Check if a color includes opacity (ends with 2 digits)
|
|
174
|
+
* * Opacity is included in the color name during mixin declaration
|
|
175
|
+
* */
|
|
176
|
+
const checkOpacity = (color: string) => {
|
|
177
|
+
const opacityDetectionRegex = new RegExp(/(?:(\w-?)+)-\d{2}$/, 'gm') // Strings that end with two digits
|
|
178
|
+
const isOpacity = opacityDetectionRegex.test(color)
|
|
179
|
+
|
|
180
|
+
const baseColor = isOpacity ? color?.slice(0, -3) : color
|
|
181
|
+
const colorExists = config.colors?.some(configColor => configColor === baseColor)
|
|
182
|
+
|
|
183
|
+
return {
|
|
184
|
+
colorExists,
|
|
185
|
+
isOpacity,
|
|
186
|
+
baseColor
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
|
|
166
190
|
export {
|
|
167
191
|
mapClassesIntoRules,
|
|
168
192
|
mapClassIntoRule
|
package/src/index.ts
DELETED
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
import { Plugin } from 'vite'
|
|
2
|
-
|
|
3
|
-
import { init as initConfig } from './config/config.tool'
|
|
4
|
-
import { log, logo, logPrefix } from './tools/logger'
|
|
5
|
-
// import { init as initPresets } from './config/'
|
|
6
|
-
import { init as initClassExtraction } from './tools/extract/classes'
|
|
7
|
-
|
|
8
|
-
/** List every imported colors across the projet */
|
|
9
|
-
const colors: string[] = []
|
|
10
|
-
|
|
11
|
-
const init = async () => {
|
|
12
|
-
console.time(`${logPrefix} Config initialized in`)
|
|
13
|
-
initConfig()
|
|
14
|
-
console.timeEnd(`${logPrefix} Config initialized in`)
|
|
15
|
-
log('---')
|
|
16
|
-
|
|
17
|
-
console.time(`${logPrefix} Rules generated in`)
|
|
18
|
-
await initClassExtraction()
|
|
19
|
-
console.timeEnd(`${logPrefix} Rules generated in`)
|
|
20
|
-
log('---')
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
export default function AnubisUI (): Plugin {
|
|
24
|
-
return {
|
|
25
|
-
name: 'anubis-ui',
|
|
26
|
-
configureServer(server: any) {
|
|
27
|
-
server.watcher.on('change', (file: any) => {
|
|
28
|
-
console.log({ file })
|
|
29
|
-
})
|
|
30
|
-
},
|
|
31
|
-
async buildStart() {
|
|
32
|
-
logo()
|
|
33
|
-
|
|
34
|
-
console.time(`${logPrefix} Anubis initialized in`)
|
|
35
|
-
await init()
|
|
36
|
-
console.timeEnd(`${logPrefix} Anubis initialized in`)
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
export {
|
|
42
|
-
colors
|
|
43
|
-
}
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
interface IConfigDeclaration {
|
|
2
|
-
[key: string]: string,
|
|
3
|
-
}
|
|
4
|
-
|
|
5
|
-
export interface IConfigPresets {
|
|
6
|
-
defaultInnerBorderWidth?: string
|
|
7
|
-
innerBorderWidths?: IConfigDeclaration[]
|
|
8
|
-
|
|
9
|
-
defaultBorderWidth?: string
|
|
10
|
-
borderWidths?: IConfigDeclaration[]
|
|
11
|
-
|
|
12
|
-
defaultShadow?: string,
|
|
13
|
-
shadowWidths?: IConfigDeclaration[]
|
|
14
|
-
|
|
15
|
-
defaultBorderRadius?: string
|
|
16
|
-
borderRadiuses?: IConfigDeclaration[]
|
|
17
|
-
|
|
18
|
-
fontWeights?: IConfigDeclaration[]
|
|
19
|
-
}
|
package/src/manual/build.ts
DELETED