anubis-ui 1.2.15 → 1.2.16

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
@@ -1,14 +1,14 @@
1
1
  # AnubisUI
2
2
  > powered by [__Improba__](https://improba.fr/)
3
3
 
4
- AnubisUI (Autonomous Nominative Utility Based Intuitive Styler) is a Vite plugin that provides dynamic CSS class generation based on configuration files. It automatically generates CSS rules by scanning your Vue files and mapping utility classes to their corresponding styles.
4
+ AnubisUI (Autonomous Nominative Utility Based Intuitive Styler) is a Vite plugin that provides dynamic CSS class generation based on configuration files. It automatically generates CSS rules by scanning your source files and mapping utility classes to their corresponding styles.
5
+
6
+ > __⚠️ IMPORTANT__ - Dynamic classes like `` `bg-primary-${props.bg}` `` **will NOT work**
7
+ >
8
+ > Classes must be **EXPLICITLY written** in the code to allow the extraction to work correctly. The plugin uses regex pattern matching on your source files.
9
+ >
10
+ > Use the `force` configuration to generate specific classes even if they're not present in the code.
5
11
 
6
- > __THIS DOESN'T WORK__ ```<div :class="`bg-primary-${props.bg || 'low'}\`" />```
7
- > <br />
8
- > Classes must be EXPLICITY written in the code to allow the extraction to work correctly, dynamic classes will not work
9
- > <br />
10
- > You can use the `force` configuration to generate specific classes even if they're not present in the code
11
- > <br />
12
12
 
13
13
  ## Table of Contents
14
14
  1. [Features](#features)
@@ -17,20 +17,27 @@ AnubisUI (Autonomous Nominative Utility Based Intuitive Styler) is a Vite plugin
17
17
  4. [Available Utility Classes](#available-utility-classes)
18
18
  5. [Prefix/Declaration relations](#prefixdeclaration-relations)
19
19
  6. [Architecture](#architecture)
20
- 7. [Credits](#credits)
21
- 8. [Licence](#licence)
20
+ 7. [Development](#development)
21
+ 8. [Credits](#credits)
22
+ 9. [Licence](#licence)
22
23
 
23
24
  ## Features
24
25
  - 🎨 Dynamic CSS generation based on utility classes
25
26
  - 🔄 Hot-reloading support through Vite plugin
26
- - 📦 Configurable color system
27
+ - 🌓 Built-in light/dark theme color system
27
28
  - 🛠️ Customizable presets for:
28
- - Background opacities
29
- - Border widths
30
- - Inner borders
31
- - Shadows
29
+ - Background & text colors
30
+ - Border widths and styles
31
+ - Inner borders (inset shadows)
32
+ - Box shadows
33
+ - Border radius
34
+ - Transitions
35
+ - Typography (size, weight)
36
+ - Positioning & blur effects
32
37
  - 🎯 State modifiers (hover, not-hover)
33
38
  - 🔍 Smart class detection and parsing
39
+ - 📦 CSS variable generation for reusable values
40
+ - ⚙️ Export variations as CSS variables for custom styling
34
41
 
35
42
  # Installation
36
43
 
@@ -58,72 +65,30 @@ css: [
58
65
  ```
59
66
  <sup>quasar.config.js</sup>
60
67
 
61
- 4. Declare your project colors in the DOM ::root in anyway you want
62
- <br />
63
- Personnaly, i use the following method based on a mixin declaration
64
-
65
- ```scss
66
- $background-opacity: (
67
- 10: 0.1,
68
- 20: 0.2,
69
- 30: 0.3,
70
- 40: 0.4,
71
- 50: 0.5,
72
- 60: 0.6,
73
- 70: 0.7,
74
- 80: 0.8,
75
- 90: 0.9
76
- );
77
-
78
- @mixin setGlobalColors($name, $light, $dark) {
79
- @include setRootColors($name, $light, 'body--light');
80
- @include setRootColors($name, $dark, 'body--dark');
81
- }
82
-
83
- @mixin setRootColors ($name, $color, $theme) {
84
- :root {
85
- body.#{$theme} {
86
- #{"--"+$name}: $color;
87
-
88
- @if $color != transparent {
89
- @each $opacity, $multiplier in $background-opacity {
90
- #{"--"+$name+"-"+$opacity}: #{rgba(red($color), green($color), blue($color), $multiplier)};
91
- }
92
- }
93
- }
94
- }
95
- }
96
- ```
97
- <sup>src/css/_mixins.scss</sup>
98
-
99
- ```scss
100
- @import './mixins';
101
-
102
- /**...highest... */
103
- /**...higher... */
104
- /**...high... */
105
- @include setGlobalColors('primary', $blue-500, $blue-400);
106
- /**...low... */
107
- /**...lower... */
108
- /**...lowest... */
109
-
110
- @include setGlobalColors('secondary', $blue-grey-500, $blue-grey-400);
111
- @include setGlobalColors('accent', $blue-500, $blue-400);
112
- @include setGlobalColors('neutral', $slate-500, $slate-500);
113
- @include setGlobalColors('success', $green-500, $green-400);
114
- @include setGlobalColors('danger', $red-500, $red-400);
115
- ```
116
- <sup>src/css/_colors_.scss</sup>
117
-
68
+ 4. Colors are automatically defined from the configuration
69
+ - AnubisUI generates CSS variables for all colors defined in `colors.config.json`
70
+ - Colors support light/dark themes automatically
71
+ - Each color is exposed as a CSS variable: `--primary`, `--secondary`, etc.
72
+ - Pre-defined color levels: `lowest`, `lower`, `low`, `medium`, `high`, `higher`, `highest`
118
73
 
119
- 5. Start adding classes however you want to (in *.vue files)
74
+ 5. Start adding classes to your HTML files
120
75
  ```html
121
- <div class="bg-primary border-neutral-low hover:shadow-low" />
76
+ <div class="bg-primary-low border-neutral-medium hover:shadow-wide rounded-lg" />
77
+ <button class="bg-accent text-text-invert size-lg weight-bold smooth">Click me</button>
122
78
  ```
123
- <sup>any .vue file</sup>
79
+ <sup>any .html file</sup>
124
80
 
125
81
  6. Enjoy
126
82
 
83
+ > **Note**: Generated CSS variables (from colors and export-variations) are available for custom styling:
84
+ > ```css
85
+ > .custom-class {
86
+ > background: var(--primary-low);
87
+ > font-size: var(--size-xl);
88
+ > font-weight: var(--weight-bold);
89
+ > }
90
+ > ```
91
+
127
92
  ## Configuration
128
93
  AnubisUI uses several configuration files located in the `src/config` directory:
129
94
  <br />
@@ -186,237 +151,338 @@ Copy-paste is recommanded
186
151
 
187
152
  ---
188
153
  ### Colors (`colors.config.json`)
189
- Define your color palette
190
- <details>
191
- <summary>Default config</summary>
192
-
193
- ```json
194
- [
195
- "primary",
196
- "secondary",
197
- "accent",
198
- "neutral",
199
- "success",
200
- "warning",
201
- "danger"
202
- ]
203
- ```
204
- </details>
154
+ Define your color palette with light/dark theme support. Colors can be defined in three different ways:
155
+
156
+ **[View default colors config →](./src/config/colors.config.json)**
157
+
158
+ **Color generation modes**:
159
+ 1. **Both themes** - Define both `light` and `dark` values:
160
+ ```json
161
+ "primary": {
162
+ "light": "#0f84cb",
163
+ "dark": "#1a94db"
164
+ }
165
+ ```
166
+ Generates color variables for both light and dark themes with opacity variations.
167
+
168
+ 2. **Light theme only** - Define only `light` value:
169
+ ```json
170
+ "custom-light": {
171
+ "light": "#ff00ff"
172
+ }
173
+ ```
174
+ Generates color variables only for light theme. Dark theme will not have this color defined.
175
+
176
+ 3. **Dark theme only** - Define only `dark` value:
177
+ ```json
178
+ "custom-dark": {
179
+ "dark": "#00ffff"
180
+ }
181
+ ```
182
+ Generates color variables only for dark theme. Light theme will not have this color defined.
183
+
184
+ Full palette includes: `primary`, `secondary`, `accent`, `neutral`, `success`, `warning`, `danger` with levels: `lowest`, `lower`, `low`, `medium`, `high`, `higher`, `highest`.
185
+
186
+ **Color naming convention**: Colors are automatically converted to CSS variables as `--{color-name}`. Use semantic color levels to ensure proper theme adaptation.
187
+
188
+ **Opacity variations**: For non-transparent colors, AnubisUI automatically generates opacity variants (10 to 90) accessible via `--{color-name}-{opacity}` (e.g., `--primary-50` for 50% opacity).
189
+
190
+ **Color validation**: AnubisUI automatically validates your color configuration on build:
191
+ - Each color must have at least one theme defined (`light` or `dark`)
192
+ - Color values must be valid hex format (`#RRGGBB` or `#RGB`) or `transparent`
193
+ - Invalid configurations will throw an error with detailed messages
205
194
 
206
195
  ---
207
196
  ### Files (`files.config.json`)
208
- Specify which files to scan for classes
209
- <details>
210
- <summary>Default config</summary>
197
+ Specify which files to scan for classes using glob patterns.
198
+
199
+ **[View default files config →](./src/config/files.config.json)**
211
200
 
201
+ You can add multiple glob patterns to scan different file types:
212
202
  ```json
213
203
  {
214
204
  "targets": [
215
- "/.vue"
205
+ "**/*.html",
206
+ "**/*.vue",
207
+ "**/*.jsx"
216
208
  ]
217
209
  }
218
210
  ```
219
- </details>
220
211
 
221
212
  ---
222
213
  ### Presets (`presets.config.json`)
223
- Configure common style presets
224
- > If overrided in config, default key/value are __REQUIRED__
214
+ Configure common style presets that require both color and variation values.
225
215
 
226
- <details>
227
- <summary>Default config</summary>
216
+ **[View default presets config →](./src/config/presets.config.json)**
228
217
 
229
- ```json
230
- [
231
- {
232
- "prefix": "bg",
233
- "declaration": "background: ${color}"
234
- },
235
- {
236
- "prefix": "border",
237
- "declaration": "border-width: ${value} !important; border-color: ${color} !important; border-style: solid;",
238
- "variations": {
239
- "default": "4px",
240
- "thinest": "1px",
241
- "thiner": "2px",
242
- "thin": "3px",
243
- "thick": "6px",
244
- "thicker": "8px",
245
- "thickest": "10px",
246
- "node": "0.2rem"
247
- }
248
- },
249
- {
250
- "prefix": "inner-border",
251
- "declaration": "box-shadow: inset 0px 0px 0px ${value} ${color}",
252
- "variations": {
253
- "default": "4px",
254
- "thinest": "1px",
255
- "thiner": "2px",
256
- "thin": "3px",
257
- "thick": "6px",
258
- "thicker": "8px",
259
- "thickest": "10px",
260
- "node": "0.2rem"
261
- }
262
- },
263
- {
264
- "prefix": "shadow",
265
- "declaration": "box-shadow: ${value} ${color}",
266
- "variations": {
267
- "default": "0px 0px 7px 1px",
268
- "densest": "0px 0px 3px 1px",
269
- "denser": "0px 0px 5px 1px",
270
- "dense": "0px 0px 5px 1px",
271
- "wide": "0px 0px 10px 1px",
272
- "wider": "0px 0px 15px 1px",
273
- "widest": "0px 0px 20px 1px"
274
- }
275
- }
276
- ]
277
- ```
278
- </details>
218
+ > **Note**: If overriding in your config, the default key/value are __REQUIRED__
219
+
220
+ Presets include:
221
+ - `bg` - Background colors (no variations)
222
+ - `text` - Text colors (no variations)
223
+ - `border` - Border with width variations
224
+ - `inner-border` - Inset box shadow with width variations
225
+ - `shadow` - Box shadow with spread variations
279
226
 
280
227
  ---
281
228
  ### Quality of Life (`qol.config.json`)
282
229
  Define simple style rules that can have variations but don't require color values. These are CSS declarations that work independently.
283
- <details>
284
- <summary>Default config</summary>
285
230
 
286
- ```json
287
- [
288
- {
289
- "prefix": "smooth",
290
- "standalone": true,
291
- "declaration": "transition-duration: ${value}",
292
- "variations": {
293
- "default": "0.1s",
294
- "slowest": "0.5s",
295
- "slower": "0.3s",
296
- "slow": "0.2s",
297
- "quick": "0.07s",
298
- "quicker": "0.05s",
299
- "quickest": "0.03s"
300
- }
301
- },
302
- {
303
- "prefix": "rounded",
304
- "standalone": true,
305
- "declaration": "border-radius: ${value}",
306
- "variations": {
307
- "default": "8px",
308
- "square": "0px",
309
- "xs": "2px",
310
- "sm": "4px",
311
- "md": "8px",
312
- "lg": "12px",
313
- "xl": "16px",
314
- "very": "9999px",
315
- "full": "50%",
316
- "half": "100%"
317
- }
318
- },
319
- {
320
- "prefix": "border",
321
- "declaration": "border-style: ${value}",
322
- "variations": {
323
- "solid": "solid",
324
- "dashed": "dashed",
325
- "dotted": "dotted"
326
- }
327
- }
328
- ]
329
- ```
330
- </details>
231
+ **[View default QoL config →](./src/config/qol.config.json)**
232
+
233
+ QoL utilities include:
234
+ - `blur` - Backdrop filter blur effect
235
+ - `smooth` - Transition duration
236
+ - `rounded` - Border radius
237
+ - `border` - Border style (solid, dashed, dotted)
238
+ - `position` - CSS positioning (relative, absolute)
239
+ - `size` - Font sizes (2xs to 9xl) with CSS variable export
240
+ - `weight` - Font weights (thin to black) with CSS variable export
331
241
 
332
- QoL rules can have:
333
- 1. A prefix
334
- 2. A declaration that uses ${value} for variations
335
- 3. Optional variations with default values
336
- 4. Optional `standalone` flag to allow usage without variations
242
+ **Configuration options**:
243
+ 1. `prefix` - The class name prefix
244
+ 2. `declaration` - CSS rule using `${value}` placeholder for variations
245
+ 3. `variations` - Key-value pairs of variation names and their CSS values
246
+ 4. `standalone` (optional) - Allows usage without variation (uses `default` value)
247
+ 5. `export-variations` (optional) - Generates CSS variables for all variations
337
248
 
338
- The `standalone` flag allows a QoL rule to be used without any variation. When set to `true`, the rule can be used:
339
- - With a variation: `rounded-lg`, `smooth-slow`
340
- - Without a variation: `rounded`, `smooth` (will use the default value)
249
+ **The `standalone` flag**:
250
+ - `standalone: true` Can use `rounded` or `rounded-lg` (both valid)
251
+ - `standalone: false` or omitted → Must use `border-solid` (requires variation)
341
252
 
342
- When `standalone` is `false` or not specified, the rule must always include a variation (e.g., `border-dashed`).
253
+ **The `export-variations` flag**:
254
+ - `export-variations: true` → Generates `--size-xs`, `--size-md`, etc. as CSS variables
255
+ - These can be used in custom CSS: `font-size: var(--size-xl)`
343
256
 
344
257
  Example usage:
345
258
  ```html
346
259
  <div class="rounded-lg smooth-slow border-dashed" />
347
- <div class="rounded smooth" /> <!-- Works because these are standalone -->
260
+ <div class="rounded smooth blur" /> <!-- Standalone rules with default values -->
261
+ <p class="size-2xl weight-bold">Typography utilities</p>
348
262
  ```
349
263
 
350
- ### Force (`force.config.json`)
351
- Force the generation of specific CSS classes even if they're not found in your code. This is particularly useful for dynamic classes that can't be detected during the extraction process.
264
+ ### States (`states.config.json`)
265
+ Define state modifiers that can be applied to any utility class.
352
266
 
353
- <details>
354
- <summary>Default config</summary>
267
+ **[View default states config →](./src/config/states.config.json)**
355
268
 
356
- ```json
357
- []
358
- ```
359
- </details>
269
+ Default states: `hover`, `not-hover`
360
270
 
361
- Example usage:
271
+ ### Force
272
+ Force the generation of specific CSS classes even if they're not found in your code. This is particularly useful for dynamic classes that can't be detected during the extraction process.
273
+
274
+ Add a `force` array to your `anubis.config.json`:
362
275
  ```json
363
276
  {
364
277
  "force": [
365
- "bg-primary-10",
366
- "bg-primary-20",
367
- "bg-primary-30",
368
- "hover:bg-secondary-50"
278
+ "bg-primary-lowest",
279
+ "bg-primary-low",
280
+ "bg-primary-medium",
281
+ "hover:bg-secondary-high"
369
282
  ]
370
283
  }
371
284
  ```
372
285
 
373
286
  ## Available Utility Classes
374
- #### Colors
287
+
288
+ ### Color-Based Classes
289
+ These utilities require a color from your config:
290
+
375
291
  - `bg-{color}` - Background color
376
292
  - `text-{color}` - Text color
377
- - `border-{color}` - Border color
378
- - `inner-border-{color}` - Inner border color (inset box shadow, not compatible with `shadow-`)
379
- - `shadow-{color}` - Box shadow color (not compatible with `inner-border-`)
293
+ - `border-{color}` - Border with color (also requires variation for width)
294
+ - `inner-border-{color}` - Inset box shadow (not compatible with `shadow-`)
295
+ - `shadow-{color}` - Box shadow (not compatible with `inner-border-`)
296
+
297
+ **Available colors**: `none`, `text`, `text-invert`, `text-link`, `primary`, `secondary`, `accent`, `neutral`, `success`, `warning`, `danger`
298
+
299
+ **Color levels**: Most colors have variants - `lowest`, `lower`, `low`, `medium`, `high`, `higher`, `highest`
300
+
301
+ Examples:
302
+ ```html
303
+ <div class="bg-primary-low text-text-invert">Blue background with inverted text</div>
304
+ <div class="bg-success-lowest text-success-highest">Success themed element</div>
305
+ ```
306
+
307
+ ### Preset Variations (Color + Size)
308
+ Presets combine colors with size variations:
309
+
310
+ - `border-{color}-{variation}` - Border with color and width
311
+ - Variations: `thinest`, `thiner`, `thin`, `default`, `thick`, `thicker`, `thickest`, `node`
312
+ - `inner-border-{color}-{variation}` - Inset shadow with color and width
313
+ - Variations: `thinest`, `thiner`, `thin2`, `default`, `thick`, `thicker`, `thickest`, `node`
314
+ - `shadow-{color}-{variation}` - Box shadow with color and spread
315
+ - Variations: `densest`, `lower`, `dense`, `default`, `wide`, `wider`, `widest`
316
+
317
+ Examples:
318
+ ```html
319
+ <div class="border-neutral-thin">Thin neutral border</div>
320
+ <div class="inner-border-accent-thick">Thick accent inset border</div>
321
+ <div class="shadow-primary-wide hover:shadow-primary-widest">Shadow on hover</div>
322
+ ```
323
+
324
+ ### Quality of Life Classes (No Color Required)
325
+ Standalone utilities that work independently:
326
+
327
+ - `blur` / `blur-{default}` - Backdrop filter blur (default: 3px)
328
+ - `smooth` / `smooth-{variation}` - Transition duration
329
+ - Variations: `quickest`, `quicker`, `quick`, `default`, `slow`, `slower`, `slowest`
330
+ - `rounded` / `rounded-{variation}` - Border radius
331
+ - Variations: `square`, `xs`, `sm`, `md`, `lg`, `xl`, `very`, `full`, `half`
332
+ - `border-{style}` - Border style
333
+ - Variations: `solid`, `dashed`, `dotted`
334
+ - `position-{type}` - CSS positioning
335
+ - Variations: `relative`, `absolute`
336
+ - `size-{size}` - Font size (generates CSS variables)
337
+ - Variations: `2xs`, `xs`, `sm`, `md`, `lg`, `xl`, `2xl`, `3xl`, `4xl`, `5xl`, `6xl`, `7xl`, `8xl`, `9xl`
338
+ - `weight-{weight}` - Font weight (generates CSS variables)
339
+ - Variations: `thin`, `extra-light`, `light`, `normal`, `medium`, `semi-bold`, `bold`, `extra-bold`, `black`
340
+
341
+ Examples:
342
+ ```html
343
+ <div class="rounded-lg smooth">Rounded with smooth transition</div>
344
+ <p class="size-xl weight-bold">Large bold text</p>
345
+ <div class="blur position-absolute">Blurred absolute positioned element</div>
346
+ ```
380
347
 
381
- #### Presets variations
382
- - `bg-{color}-{(10-90)}` - Background opacity
383
- - `border-{color}-{presetKey}` - Border width
384
- - `shadow-{color}-{presetKey}` - Box shadow spread
385
- - `inner-border-{color}-{presetKey}` - Box shadow inset width
348
+ ### State Modifiers
349
+ Apply styles conditionally based on element state:
386
350
 
387
- #### States
388
351
  - `hover:{utility}` - Apply style on hover
389
352
  - `not-hover:{utility}` - Apply style when not hovering
390
353
 
391
- ## Prefix/Declaration relations
392
- | prefix | declaration |
393
- |--------------|-----------------------------------------------------------------------------|
394
- | bg | `background: {color} important;` |
395
- | text | `color: {color} important;` |
396
- | border | `border-width: {presetValue \|\| default} !important; border-color: {color} !important; border-style: solid;` |
397
- | inner-border | `box-shadow: inset {presetValue \|\| default} {color} !important;` |
398
- | shadow | `box-shadow: {presetValue \|\| default} {color} !important;` |
354
+ Examples:
355
+ ```html
356
+ <button class="bg-primary hover:bg-primary-high">Darkens on hover</button>
357
+ <div class="shadow-none hover:shadow-accent-wide">Shadow appears on hover</div>
358
+ <span class="size-md hover:size-lg">Text grows on hover</span>
359
+ ```
360
+
361
+ ## Prefix/Declaration Relations
362
+
363
+ ### Color Presets
364
+ | Prefix | CSS Declaration |
365
+ |--------------|---------------------------------------------------------------------------------|
366
+ | bg | `background: var(--{color}) !important;` |
367
+ | text | `color: var(--{color}) !important;` |
368
+ | border | `border-width: {value} !important; border-color: var(--{color}) !important; border-style: solid;` |
369
+ | inner-border | `box-shadow: inset 0px 0px 0px {value} var(--{color}) !important;` |
370
+ | shadow | `box-shadow: {value} var(--{color}) !important;` |
371
+
372
+ ### Quality of Life Utilities
373
+ | Prefix | CSS Declaration |
374
+ |----------|-----------------------------------------------|
375
+ | blur | `backdrop-filter: blur({value}) !important;` |
376
+ | smooth | `transition-duration: {value} !important;` |
377
+ | rounded | `border-radius: {value} !important;` |
378
+ | border | `border-style: {value} !important;` |
379
+ | position | `position: {value} !important;` |
380
+ | size | `font-size: {value} !important;` |
381
+ | weight | `font-weight: {value} !important;` |
382
+
383
+ **Note**: When `export-variations: true` is set, `{value}` becomes `var(--{prefix}-{variation})` instead of the direct value.
399
384
 
400
385
  ## Architecture
386
+
387
+ ### Build Process Flow
388
+
389
+ 1. **Configuration Initialization** (`src/tools/config.tool.ts`)
390
+ - Loads default configs from `src/config/*.config.json`
391
+ - Merges with user's `anubis.config.json` if present
392
+ - User config completely replaces default sections (no deep merge)
393
+
394
+ 2. **File Scanning** (`src/tools/fileStuff/file.tools.ts`)
395
+ - Scans files matching glob patterns from `files.config.json`
396
+ - Concurrent file reading with configurable limit (default: 10 files)
397
+
398
+ 3. **Class Extraction** (`src/tools/extraction/extractClasses.ts`)
399
+ - Builds dynamic regex from config (states, presets, qol prefixes)
400
+ - Extracts classes matching pattern: `(state:)?(prefix-)(-?(color|variation))?`
401
+ - Merges with forced classes from config
402
+ - Deduplicates and returns unique classes
403
+
404
+ 4. **Rule Generation** (`src/tools/mapping/mapClassIntoRule.ts`)
405
+ - Parses each class to identify state, prefix, color, and variation
406
+ - Validates color existence in config
407
+ - Handles preset variations (direct values or CSS variables)
408
+ - Generates CSS rules with proper selectors and declarations
409
+ - Collects variants for CSS variable export
410
+
411
+ 5. **CSS Output** (`src/tools/fileStuff/css.file.ts`)
412
+ - Generates color CSS variables with light/dark theme support
413
+ - Generates variation CSS variables (from `export-variations: true`)
414
+ - Writes final CSS rules
415
+ - Outputs to `src/css/_anubis.scss`
416
+
417
+ ### Vite Plugin Integration
418
+
419
+ The plugin (`index.js`) provides:
420
+ - **`buildStart()` hook** - Runs full CSS generation on build
421
+ - **`configureServer()` hook** - Watches file changes and regenerates CSS
422
+ - **Hot reload** - Automatically reloads on `anubis.config.json` changes
423
+
401
424
  ### Core Components
402
- - **Vite Plugin**: Handles file watching and build process
403
- - **Class Extractor**: Scans files for utility classes
404
- - **Rule Generator**: Converts utility classes to CSS rules
405
- - **Configuration System**: Manages user preferences and presets
425
+
426
+ - **Config System**: Manages configuration loading and merging
427
+ - **Class Extractor**: Regex-based pattern matching for class detection
428
+ - **Rule Mapper**: Complex parsing logic for class-to-CSS conversion
429
+ - **CSS Generator**: Generates variables and rules with proper formatting
406
430
 
407
431
  ### File Structure
408
432
  ```
409
- ├── dist/ # Compiled and generated output
433
+ ├── dist/ # Compiled output
410
434
  ├── src/
411
- ├── config/ # Configuration files
412
- ├── interfaces/ # TypeScript interfaces
413
- └── tools/
414
- │ ├── extraction/ # Class extraction logic
415
- │ ├── fileStuff/ # File handling utilities
416
- │ └── mapping/ # Class to CSS rule mapping
417
- └── index.js # Plugin entry point
435
+ ├── config/ # Default configuration files
436
+ ├── colors.config.json # Color palette (light/dark themes)
437
+ │ ├── presets.config.json # Color-based utilities
438
+ ├── qol.config.json # Standalone utilities
439
+ ├── states.config.json # State modifiers
440
+ └── files.config.json # File scan patterns
441
+ │ ├── interfaces/ # TypeScript type definitions
442
+ │ └── tools/
443
+ │ ├── extraction/ # Class extraction logic
444
+ │ ├── fileStuff/ # File I/O operations
445
+ │ ├── mapping/ # Class-to-CSS mapping
446
+ │ ├── config.tool.ts # Configuration loader
447
+ │ └── logger.ts # Logging utilities
448
+ └── index.js # Vite plugin entry point
418
449
  ```
419
450
 
451
+ ### Key Design Decisions
452
+
453
+ **Regex-Based Extraction**: Classes must be literal strings in source code for detection to work. Dynamic string interpolation is not supported.
454
+
455
+ **CSS Variables**: Colors and exported variations use CSS variables (`var(--name)`) for better reusability and theme support.
456
+
457
+ **Configuration Override**: User configs completely replace default sections to avoid merge complexity and unexpected behavior.
458
+
459
+ **Concurrency Control**: File reading uses a concurrency limit to prevent system overload on large codebases.
460
+
461
+ **Caching**: Regex patterns are cached based on config hash to avoid recompilation on every file scan.
462
+
463
+ ## Development
464
+
465
+ ### Running Tests
466
+
467
+ AnubisUI uses [Vitest](https://vitest.dev/) for testing:
468
+
469
+ ```bash
470
+ # Run tests in watch mode (recommended for development)
471
+ npm test
472
+
473
+ # Run tests once (CI/production)
474
+ npm run test:run
475
+
476
+ # Run tests with UI
477
+ npm run test:ui
478
+ ```
479
+
480
+ ### Test Coverage
481
+
482
+ - **Color Validation** - Tests for configuration validation logic
483
+ - Located in `tests/validation/`
484
+
485
+ See [tests/README.md](./tests/README.md) for more information.
420
486
 
421
487
  ## Credits
422
488