0
# Utility Functions
1
2
WindiCSS provides a comprehensive set of utility functions for common operations including type checking, string manipulation, color processing, and object operations. These utilities are essential for plugin development and advanced WindiCSS usage.
3
4
## Capabilities
5
6
### Array and Type Utilities
7
8
General utilities for working with arrays, types, and basic operations.
9
10
```typescript { .api }
11
/**
12
* Converts value to array
13
* @param v - Value to convert (can be single value or array)
14
* @returns Array containing the value(s)
15
*/
16
function toArray<T>(v: T | T[]): T[];
17
18
/**
19
* Gets the type of a value as string
20
* @param val - Value to check
21
* @returns Type name as string
22
*/
23
function type(val: unknown): string;
24
25
/**
26
* Type guard for string values
27
* @param value - Value to check
28
* @returns True if value is string
29
*/
30
function isString(value: unknown): value is string;
31
32
/**
33
* Deep copies an object or value
34
* @param source - Source object to copy
35
* @returns Deep copied object
36
*/
37
function deepCopy<T>(source: T): T;
38
39
/**
40
* Converts value to specific type
41
* @param value - Value to convert
42
* @param type - Target type name
43
* @returns Converted value
44
*/
45
function toType(value: unknown, type: string): any;
46
```
47
48
**Usage Examples:**
49
50
```typescript
51
import { toArray, type, isString, deepCopy, toType } from "windicss/utils";
52
53
// Convert to array
54
const singleValue = toArray("hello"); // ["hello"]
55
const multiValue = toArray(["a", "b", "c"]); // ["a", "b", "c"]
56
57
// Type checking
58
console.log(type(123)); // "number"
59
console.log(type([])); // "array"
60
console.log(isString("hello")); // true
61
console.log(isString(123)); // false
62
63
// Deep copy objects
64
const original = { a: { b: { c: 1 } } };
65
const copied = deepCopy(original);
66
copied.a.b.c = 2; // original is unchanged
67
68
// Type conversion
69
const numberString = toType("123", "number"); // 123
70
const booleanString = toType("true", "boolean"); // true
71
```
72
73
### String Manipulation
74
75
Utilities for string processing, case conversion, and text manipulation.
76
77
```typescript { .api }
78
/**
79
* Converts camelCase to dash-case
80
* @param str - camelCase string
81
* @returns dash-case string
82
*/
83
function camelToDash(str: string): string;
84
85
/**
86
* Converts dash-case to camelCase
87
* @param str - dash-case string
88
* @returns camelCase string
89
*/
90
function dashToCamel(str: string): string;
91
92
/**
93
* Creates hash from string
94
* @param str - String to hash
95
* @returns Hash string
96
*/
97
function hash(str: string): string;
98
99
/**
100
* Indents code with specified number of tabs
101
* @param code - Code to indent
102
* @param tab - Number of tabs (default: 1)
103
* @returns Indented code
104
*/
105
function indent(code: string, tab?: number): string;
106
107
/**
108
* Wraps code with start and end strings
109
* @param code - Code to wrap
110
* @param start - Start wrapper
111
* @param end - End wrapper
112
* @param tab - Indentation level
113
* @param minify - Whether to minify
114
* @returns Wrapped code
115
*/
116
function wrapit(
117
code: string,
118
start?: string,
119
end?: string,
120
tab?: number,
121
minify?: boolean
122
): string;
123
124
/**
125
* Tests if string is whitespace
126
* @param str - String to test
127
* @returns True if string is whitespace
128
*/
129
function isSpace(str: string): boolean;
130
131
/**
132
* Searches text from specific index
133
* @param text - Text to search
134
* @param regex - Regular expression
135
* @param startIndex - Starting index
136
* @returns Match index or -1
137
*/
138
function searchFrom(text: string, regex: RegExp, startIndex?: number): number;
139
140
/**
141
* Searches for non-escaped characters
142
* @param text - Text to search
143
* @param chars - Characters to find
144
* @returns Index of first non-escaped match
145
*/
146
function searchNotEscape(text: string, chars?: string | string[]): number;
147
148
/**
149
* Finds end of CSS property in text
150
* @param text - CSS text
151
* @param startIndex - Starting index
152
* @returns End index of property
153
*/
154
function searchPropEnd(text: string, startIndex?: number): number;
155
```
156
157
**Usage Examples:**
158
159
```typescript
160
import {
161
camelToDash,
162
dashToCamel,
163
hash,
164
indent,
165
wrapit,
166
isSpace,
167
searchFrom
168
} from "windicss/utils";
169
170
// Case conversion
171
console.log(camelToDash("backgroundColor")); // "background-color"
172
console.log(dashToCamel("background-color")); // "backgroundColor"
173
174
// Hashing
175
const hashValue = hash("bg-blue-500"); // "a1b2c3d4"
176
177
// Code formatting
178
const css = ".btn { color: red; }";
179
const indented = indent(css, 2); // " .btn { color: red; }"
180
const wrapped = wrapit(css, "/* Start */\n", "\n/* End */");
181
182
// String testing
183
console.log(isSpace(" ")); // true
184
console.log(isSpace("text")); // false
185
186
// Pattern searching
187
const cssText = ".class { color: red; background: blue; }";
188
const colorIndex = searchFrom(cssText, /color/, 0); // finds "color" position
189
```
190
191
### Number and Size Validation
192
193
Utilities for validating and processing numeric values, sizes, and measurements.
194
195
```typescript { .api }
196
/**
197
* Tests if string represents a number
198
* @param amount - String to test
199
* @param start - Start range for validation
200
* @param end - End range for validation
201
* @param type - Number type ('int' or 'float')
202
* @returns True if string is valid number
203
*/
204
function isNumber(
205
amount: string,
206
start?: number,
207
end?: number,
208
type?: "int" | "float"
209
): boolean;
210
211
/**
212
* Tests if string is fraction format
213
* @param amount - String to test
214
* @returns True if string is fraction (e.g., "1/2")
215
*/
216
function isFraction(amount: string): boolean;
217
218
/**
219
* Tests if string is valid CSS size value
220
* @param amount - String to test
221
* @returns True if string has valid size format
222
*/
223
function isSize(amount: string): boolean;
224
225
/**
226
* Rounds number up to specified precision
227
* @param num - Number to round
228
* @param precision - Decimal precision
229
* @returns Rounded number
230
*/
231
function roundUp(num: number, precision?: number): number;
232
233
/**
234
* Converts fraction string to percentage
235
* @param amount - Fraction string (e.g., "1/2")
236
* @returns Percentage string or undefined
237
*/
238
function fracToPercent(amount: string): string | undefined;
239
240
/**
241
* Negates a numeric value string
242
* @param value - Value to negate
243
* @returns Negated value string
244
*/
245
function negateValue(value: string): string;
246
247
/**
248
* Increases value preserving units
249
* @param target - Target value (number or string with units)
250
* @param delta - Amount to increase
251
* @returns Increased value with preserved units
252
*/
253
function increaseWithUnit(target: string | number, delta: number): string | number;
254
```
255
256
**Usage Examples:**
257
258
```typescript
259
import {
260
isNumber,
261
isFraction,
262
isSize,
263
roundUp,
264
fracToPercent,
265
negateValue,
266
increaseWithUnit
267
} from "windicss/utils";
268
269
// Number validation
270
console.log(isNumber("123")); // true
271
console.log(isNumber("12.5")); // true
272
console.log(isNumber("abc")); // false
273
console.log(isNumber("10", 1, 100, "int")); // true (10 is between 1-100 and integer)
274
275
// Fraction validation
276
console.log(isFraction("1/2")); // true
277
console.log(isFraction("3/4")); // true
278
console.log(isFraction("1.5")); // false
279
280
// Size validation
281
console.log(isSize("10px")); // true
282
console.log(isSize("1.5rem")); // true
283
console.log(isSize("100%")); // true
284
console.log(isSize("invalid")); // false
285
286
// Number operations
287
console.log(roundUp(1.234, 2)); // 1.24
288
console.log(fracToPercent("1/2")); // "50%"
289
console.log(negateValue("10px")); // "-10px"
290
console.log(increaseWithUnit("10px", 5)); // "15px"
291
console.log(increaseWithUnit(10, 5)); // 15
292
```
293
294
### Color Utilities
295
296
Comprehensive color manipulation and conversion utilities.
297
298
```typescript { .api }
299
/**
300
* Converts hex color to RGB array
301
* @param hex - Hex color string (with or without #)
302
* @returns RGB array [r, g, b] or undefined if invalid
303
*/
304
function hex2RGB(hex: string): number[] | undefined;
305
306
/**
307
* Converts HSL to RGB
308
* @param h - Hue (0-360)
309
* @param s - Saturation (0-100)
310
* @param l - Lightness (0-100)
311
* @returns RGB array [r, g, b]
312
*/
313
function hsl2rgb(h: number, s: number, l: number): [number, number, number];
314
315
/**
316
* Converts HWB to RGB
317
* @param h - Hue (0-360)
318
* @param w - Whiteness (0-100)
319
* @param b - Blackness (0-100)
320
* @returns RGB array [r, g, b]
321
*/
322
function hwb2rgb(h: number, w: number, b: number): [number, number, number];
323
324
/**
325
* Converts color string to RGBA object
326
* @param color - Color string (hex, rgb, hsl, etc.)
327
* @returns Color object or undefined if invalid
328
*/
329
function toRGBA(color: string): Color | undefined;
330
331
/**
332
* Converts color string to RGB array
333
* @param color - Color string
334
* @returns RGB array or undefined if invalid
335
*/
336
function toRGB(color: string): number[] | undefined;
337
338
/**
339
* Parses color string with opacity
340
* @param color_string - Color string potentially with opacity
341
* @returns Object with color and opacity strings
342
*/
343
function toColor(color_string: string): { color: string; opacity: string };
344
345
/**
346
* Splits color group into parts
347
* @param color - Color string with potential opacity
348
* @returns Tuple with color and opacity parts
349
*/
350
function splitColorGroup(color: string): [string, string | undefined];
351
352
/**
353
* Flattens nested color object
354
* @param colors - Nested color object
355
* @param head - Prefix for flattened keys
356
* @returns Flattened color object
357
*/
358
function flatColors(
359
colors: Record<string, any>,
360
head?: string
361
): Record<string, string>;
362
363
interface Color {
364
r: number;
365
g: number;
366
b: number;
367
a?: number;
368
}
369
```
370
371
**Usage Examples:**
372
373
```typescript
374
import {
375
hex2RGB,
376
hsl2rgb,
377
toRGBA,
378
toRGB,
379
toColor,
380
splitColorGroup,
381
flatColors
382
} from "windicss/utils";
383
384
// Color conversions
385
console.log(hex2RGB("#3b82f6")); // [59, 130, 246]
386
console.log(hex2RGB("3b82f6")); // [59, 130, 246] (works without #)
387
console.log(hsl2rgb(220, 92, 50)); // [10, 132, 245]
388
389
// Color parsing
390
const rgba = toRGBA("rgba(59, 130, 246, 0.5)");
391
console.log(rgba); // { r: 59, g: 130, b: 246, a: 0.5 }
392
393
const rgb = toRGB("rgb(59, 130, 246)");
394
console.log(rgb); // [59, 130, 246]
395
396
// Color with opacity
397
const parsed = toColor("blue-500/50");
398
console.log(parsed); // { color: "blue-500", opacity: "50" }
399
400
const [color, opacity] = splitColorGroup("red-500/25");
401
console.log(color); // "red-500"
402
console.log(opacity); // "25"
403
404
// Flatten color object
405
const colors = {
406
blue: {
407
500: "#3b82f6",
408
600: "#2563eb"
409
},
410
red: {
411
500: "#ef4444"
412
}
413
};
414
const flattened = flatColors(colors);
415
console.log(flattened); // { "blue-500": "#3b82f6", "blue-600": "#2563eb", "red-500": "#ef4444" }
416
```
417
418
### Object and Data Utilities
419
420
Utilities for working with objects, nested data, and data manipulation.
421
422
```typescript { .api }
423
/**
424
* Gets nested value from object by path
425
* @param obj - Source object
426
* @param key - Dot-separated path to value
427
* @returns Value at path or undefined
428
*/
429
function getNestedValue(obj: Record<string, any>, key: string): any;
430
431
/**
432
* Connects two arrays with options
433
* @param a - First array
434
* @param b - Second array
435
* @param append - Whether to append or prepend
436
* @returns Connected array
437
*/
438
function connectList<T>(a?: T[], b?: T[], append?: boolean): T[];
439
440
/**
441
* Tests if string is HTML tag name
442
* @param name - String to test
443
* @returns True if string is valid HTML tag
444
*/
445
function isTagName(name: string): boolean;
446
447
/**
448
* Tests text against array of regex patterns
449
* @param text - Text to test
450
* @param expressions - Array of regular expressions
451
* @returns True if any regex matches
452
*/
453
function testRegexr(text: string, expressions: RegExp[]): boolean;
454
455
/**
456
* Splits CSS selector string into individual selectors
457
* @param selectors - Selector string
458
* @returns Array of individual selectors
459
*/
460
function splitSelectors(selectors: string): string[];
461
462
/**
463
* Extracts class information from CSS selector
464
* @param selector - CSS selector
465
* @returns Class information object or array
466
*/
467
function guessClassName(selector: string): any;
468
```
469
470
**Usage Examples:**
471
472
```typescript
473
import {
474
getNestedValue,
475
connectList,
476
isTagName,
477
testRegexr,
478
splitSelectors,
479
guessClassName
480
} from "windicss/utils";
481
482
// Nested object access
483
const config = {
484
theme: {
485
colors: {
486
blue: {
487
500: "#3b82f6"
488
}
489
}
490
}
491
};
492
const blueColor = getNestedValue(config, "theme.colors.blue.500");
493
console.log(blueColor); // "#3b82f6"
494
495
// Array operations
496
const combined = connectList(["a", "b"], ["c", "d"], true);
497
console.log(combined); // ["a", "b", "c", "d"]
498
499
// Validation
500
console.log(isTagName("div")); // true
501
console.log(isTagName("custom-element")); // false
502
503
// Pattern testing
504
const patterns = [/^bg-/, /^text-/, /^p-/];
505
console.log(testRegexr("bg-blue-500", patterns)); // true
506
console.log(testRegexr("invalid-class", patterns)); // false
507
508
// CSS processing
509
const multiSelector = ".btn, .button, input[type='button']";
510
const selectors = splitSelectors(multiSelector);
511
console.log(selectors); // [".btn", ".button", "input[type='button']"]
512
513
const classInfo = guessClassName(".hover\\:bg-blue-500");
514
console.log(classInfo); // Information about the class structure
515
```
516
517
### Helper Scale Functions
518
519
Utilities for generating scales and helper objects for theming.
520
521
```typescript { .api }
522
/**
523
* Creates negative scale from positive scale
524
* @param scale - Object with positive values
525
* @returns Object with negative values added
526
*/
527
function negative(scale: Record<string, string>): Record<string, string>;
528
529
/**
530
* Creates breakpoint utilities from screen configuration
531
* @param screens - Screen breakpoint configuration
532
* @returns Breakpoint utilities object
533
*/
534
function breakpoints(screens: Record<string, string>): Record<string, string>;
535
536
/**
537
* Generates CSS properties for font size configuration
538
* @param font - Font size configuration
539
* @returns Array of CSS properties
540
*/
541
function generateFontSize(font: FontSize): Property[];
542
543
/**
544
* Expands directional mapping to all directions
545
* @param mapping - Base mapping object
546
* @param directions - Array of direction suffixes
547
* @param prefix - Optional prefix for keys
548
* @returns Expanded mapping with all directions
549
*/
550
function expandDirection(
551
mapping: Record<string, string>,
552
directions: string[],
553
prefix?: string
554
): Record<string, string>;
555
556
type FontSize =
557
| string
558
| [fontSize: string, letterSpacing?: string]
559
| [fontSize?: string, options?: { letterSpacing?: string; lineHeight?: string }];
560
```
561
562
**Usage Examples:**
563
564
```typescript
565
import {
566
negative,
567
breakpoints,
568
generateFontSize,
569
expandDirection
570
} from "windicss/utils";
571
572
// Generate negative scale
573
const spacing = { "1": "0.25rem", "2": "0.5rem", "4": "1rem" };
574
const withNegative = negative(spacing);
575
console.log(withNegative);
576
// { "1": "0.25rem", "2": "0.5rem", "4": "1rem", "-1": "-0.25rem", "-2": "-0.5rem", "-4": "-1rem" }
577
578
// Generate breakpoint utilities
579
const screens = { sm: "640px", md: "768px", lg: "1024px" };
580
const breakpointUtils = breakpoints(screens);
581
console.log(breakpointUtils);
582
// Utilities for responsive design
583
584
// Generate font size properties
585
const fontSize = generateFontSize("1.5rem");
586
console.log(fontSize); // Array of Property objects for font-size
587
588
const fontSizeWithOptions = generateFontSize([
589
"1.5rem",
590
{ lineHeight: "2rem", letterSpacing: "0.05em" }
591
]);
592
593
// Expand directional utilities
594
const borderMapping = { "": "1px" };
595
const directions = ["t", "r", "b", "l", "x", "y"];
596
const expanded = expandDirection(borderMapping, directions, "border");
597
console.log(expanded);
598
// { "border": "1px", "border-t": "1px", "border-r": "1px", ... }
599
```
600
601
### Advanced Utilities
602
603
Additional utility functions for complex operations and development support.
604
605
```typescript { .api }
606
/**
607
* Console class with enhanced logging capabilities
608
*/
609
class Console {
610
log(...args: any[]): void;
611
warn(...args: any[]): void;
612
error(...args: any[]): void;
613
info(...args: any[]): void;
614
debug(...args: any[]): void;
615
}
616
617
/**
618
* Indents code string with specified tab size
619
* @param code - Code string to indent
620
* @param tab - Number of spaces for indentation (default: 2)
621
* @returns Indented code string
622
*/
623
function indent(code: string, tab?: number): string;
624
625
/**
626
* Wraps code with start/end markers with proper formatting
627
* @param code - Code to wrap
628
* @param start - Start wrapper
629
* @param end - End wrapper
630
* @param tab - Indentation level
631
* @param minify - Whether to minify output
632
* @returns Wrapped code string
633
*/
634
function wrapit(
635
code: string,
636
start?: string,
637
end?: string,
638
tab?: number,
639
minify?: boolean
640
): string;
641
642
/**
643
* Rounds number up to specified precision
644
* @param num - Number to round
645
* @param precision - Decimal precision (default: 2)
646
* @returns Rounded number
647
*/
648
function roundUp(num: number, precision?: number): number;
649
650
/**
651
* Tests if string contains only whitespace
652
* @param str - String to test
653
* @returns True if string is only whitespace
654
*/
655
function isSpace(str: string): boolean;
656
657
/**
658
* Tests string against regex or array of regexes
659
* @param str - String to test
660
* @param regex - Regular expression(s) to test against
661
* @returns True if string matches any regex
662
*/
663
function testRegexr(str: string, regex: RegExp | RegExp[]): boolean;
664
665
/**
666
* Infers class name from CSS selector string
667
* @param str - CSS selector string
668
* @returns Inferred class name information
669
*/
670
function guessClassName(str: string): ClassNameGuess | ClassNameGuess[];
671
672
interface ClassNameGuess {
673
selector: string;
674
isClass: boolean;
675
pseudo?: string;
676
}
677
```
678
679
### Color Conversion Utilities
680
681
Advanced color space conversion functions.
682
683
```typescript { .api }
684
/**
685
* Converts HSL values to RGB
686
* @param h - Hue (0-360)
687
* @param s - Saturation (0-100)
688
* @param l - Lightness (0-100)
689
* @returns RGB values as [r, g, b] tuple
690
*/
691
function hsl2rgb(h: number, s: number, l: number): [number, number, number];
692
693
/**
694
* Converts HWB values to RGB
695
* @param h - Hue (0-360)
696
* @param w - Whiteness (0-100)
697
* @param b - Blackness (0-100)
698
* @returns RGB values as [r, g, b] tuple
699
*/
700
function hwb2rgb(h: number, w: number, b: number): [number, number, number];
701
```
702
703
**Usage Examples:**
704
705
```typescript
706
import {
707
Console,
708
indent,
709
wrapit,
710
roundUp,
711
isSpace,
712
testRegexr,
713
guessClassName,
714
hsl2rgb,
715
hwb2rgb
716
} from "windicss/utils";
717
718
// Enhanced console
719
const console = new Console();
720
console.log("Enhanced logging");
721
console.warn("Warning message");
722
723
// Code formatting
724
const code = "const x = 1;\nconst y = 2;";
725
const indented = indent(code, 4);
726
console.log(indented);
727
// " const x = 1;\n const y = 2;"
728
729
const wrapped = wrapit(code, "function() {", "}", 2);
730
console.log(wrapped);
731
// "function() {\n const x = 1;\n const y = 2;\n}"
732
733
// Number operations
734
const rounded = roundUp(3.14159, 2);
735
console.log(rounded); // 3.14
736
737
// String testing
738
console.log(isSpace(" \n\t ")); // true
739
console.log(isSpace("hello")); // false
740
741
// Regex testing
742
const isValid = testRegexr("bg-blue-500", [/^bg-/, /^text-/]);
743
console.log(isValid); // true
744
745
// Class name inference
746
const classInfo = guessClassName(".hover\\:bg-blue-500\\:focus");
747
console.log(classInfo);
748
// { selector: "hover:bg-blue-500:focus", isClass: true, pseudo: ":focus" }
749
750
// Color conversions
751
const rgb1 = hsl2rgb(220, 92, 50);
752
console.log(rgb1); // [10, 132, 245]
753
754
const rgb2 = hwb2rgb(220, 10, 5);
755
console.log(rgb2); // [25, 132, 242]
756
```