@shalomormsby/ui 0.0.5

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/dist/utils.js ADDED
@@ -0,0 +1,873 @@
1
+ "use client";
2
+ "use strict";
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
7
+ var __export = (target, all) => {
8
+ for (var name in all)
9
+ __defProp(target, name, { get: all[name], enumerable: true });
10
+ };
11
+ var __copyProps = (to, from, except, desc) => {
12
+ if (from && typeof from === "object" || typeof from === "function") {
13
+ for (let key of __getOwnPropNames(from))
14
+ if (!__hasOwnProp.call(to, key) && key !== except)
15
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
16
+ }
17
+ return to;
18
+ };
19
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
20
+
21
+ // src/utils.ts
22
+ var utils_exports = {};
23
+ __export(utils_exports, {
24
+ adjustLightness: () => adjustLightness,
25
+ adjustOpacity: () => adjustOpacity,
26
+ adjustSaturation: () => adjustSaturation,
27
+ cn: () => cn,
28
+ collapseVariants: () => collapseVariants,
29
+ colorTokens: () => colorTokens,
30
+ colorUtils: () => colorUtils,
31
+ createAnimation: () => createAnimation,
32
+ detectLanguage: () => detectLanguage,
33
+ drawerVariants: () => drawerVariants,
34
+ durations: () => durations,
35
+ easings: () => easings,
36
+ fadeVariants: () => fadeVariants,
37
+ generateBreadcrumbs: () => generateBreadcrumbs,
38
+ generateColorScale: () => generateColorScale,
39
+ getCSSVariable: () => getCSSVariable,
40
+ getContrastRatio: () => getContrastRatio,
41
+ getForegroundColor: () => getForegroundColor,
42
+ getLuminance: () => getLuminance,
43
+ getOptimalForeground: () => getOptimalForeground,
44
+ getSemanticColorPair: () => getSemanticColorPair,
45
+ hasErrors: () => hasErrors,
46
+ hexToHSL: () => hexToHSL,
47
+ hexToRgb: () => hexToRgb,
48
+ hslToHex: () => hslToHex,
49
+ listVariants: () => listVariants,
50
+ meetsContrastRequirements: () => meetsContrastRequirements,
51
+ modalVariants: () => modalVariants,
52
+ parseCode: () => parseCode,
53
+ patterns: () => patterns,
54
+ presets: () => presets,
55
+ rotateHue: () => rotateHue,
56
+ rotateVariants: () => rotateVariants,
57
+ rules: () => rules,
58
+ scaleDuration: () => scaleDuration,
59
+ scaleVariants: () => scaleVariants,
60
+ semanticColors: () => semanticColors,
61
+ setCSSVariable: () => setCSSVariable,
62
+ slideVariants: () => slideVariants,
63
+ tokenize: () => tokenize,
64
+ transitions: () => transitions,
65
+ validateField: () => validateField,
66
+ validateForm: () => validateForm
67
+ });
68
+ module.exports = __toCommonJS(utils_exports);
69
+
70
+ // src/lib/animations.ts
71
+ var durations = {
72
+ instant: 0,
73
+ fast: 0.15,
74
+ normal: 0.3,
75
+ slow: 0.5,
76
+ slower: 0.7
77
+ };
78
+ var easings = {
79
+ // Standard easing - default for most transitions
80
+ standard: [0.4, 0, 0.2, 1],
81
+ // Deceleration - use when objects enter screen
82
+ decelerate: [0, 0, 0.2, 1],
83
+ // Acceleration - use when objects exit screen
84
+ accelerate: [0.4, 0, 1, 1],
85
+ // Sharp - use for very quick transitions
86
+ sharp: [0.4, 0, 0.6, 1],
87
+ // Bounce - playful animation
88
+ bounce: [0.68, -0.55, 0.265, 1.55]
89
+ };
90
+ var transitions = {
91
+ default: {
92
+ duration: durations.normal,
93
+ ease: easings.standard
94
+ },
95
+ fast: {
96
+ duration: durations.fast,
97
+ ease: easings.standard
98
+ },
99
+ slow: {
100
+ duration: durations.slow,
101
+ ease: easings.standard
102
+ },
103
+ bounce: {
104
+ duration: durations.normal,
105
+ ease: easings.bounce
106
+ },
107
+ spring: {
108
+ type: "spring",
109
+ damping: 20,
110
+ stiffness: 300
111
+ },
112
+ springBouncy: {
113
+ type: "spring",
114
+ damping: 10,
115
+ stiffness: 100
116
+ }
117
+ };
118
+ var fadeVariants = {
119
+ hidden: { opacity: 0 },
120
+ visible: { opacity: 1 },
121
+ exit: { opacity: 0 }
122
+ };
123
+ var slideVariants = {
124
+ fromLeft: {
125
+ hidden: { x: -20, opacity: 0 },
126
+ visible: { x: 0, opacity: 1 },
127
+ exit: { x: -20, opacity: 0 }
128
+ },
129
+ fromRight: {
130
+ hidden: { x: 20, opacity: 0 },
131
+ visible: { x: 0, opacity: 1 },
132
+ exit: { x: 20, opacity: 0 }
133
+ },
134
+ fromTop: {
135
+ hidden: { y: -20, opacity: 0 },
136
+ visible: { y: 0, opacity: 1 },
137
+ exit: { y: -20, opacity: 0 }
138
+ },
139
+ fromBottom: {
140
+ hidden: { y: 20, opacity: 0 },
141
+ visible: { y: 0, opacity: 1 },
142
+ exit: { y: 20, opacity: 0 }
143
+ }
144
+ };
145
+ var scaleVariants = {
146
+ default: {
147
+ hidden: { scale: 0.95, opacity: 0 },
148
+ visible: { scale: 1, opacity: 1 },
149
+ exit: { scale: 0.95, opacity: 0 }
150
+ },
151
+ grow: {
152
+ hidden: { scale: 0.8, opacity: 0 },
153
+ visible: { scale: 1, opacity: 1 },
154
+ exit: { scale: 0.8, opacity: 0 }
155
+ },
156
+ pop: {
157
+ hidden: { scale: 0 },
158
+ visible: { scale: 1 },
159
+ exit: { scale: 0 }
160
+ }
161
+ };
162
+ var rotateVariants = {
163
+ default: {
164
+ hidden: { rotate: -10, opacity: 0 },
165
+ visible: { rotate: 0, opacity: 1 },
166
+ exit: { rotate: 10, opacity: 0 }
167
+ },
168
+ flip: {
169
+ hidden: { rotateX: 90, opacity: 0 },
170
+ visible: { rotateX: 0, opacity: 1 },
171
+ exit: { rotateX: -90, opacity: 0 }
172
+ }
173
+ };
174
+ var listVariants = {
175
+ container: {
176
+ hidden: { opacity: 0 },
177
+ visible: {
178
+ opacity: 1,
179
+ transition: {
180
+ staggerChildren: 0.1
181
+ }
182
+ }
183
+ },
184
+ item: {
185
+ hidden: { y: 20, opacity: 0 },
186
+ visible: {
187
+ y: 0,
188
+ opacity: 1
189
+ }
190
+ }
191
+ };
192
+ var modalVariants = {
193
+ overlay: {
194
+ hidden: { opacity: 0 },
195
+ visible: { opacity: 1 },
196
+ exit: { opacity: 0 }
197
+ },
198
+ content: {
199
+ hidden: { scale: 0.95, opacity: 0, y: 20 },
200
+ visible: { scale: 1, opacity: 1, y: 0 },
201
+ exit: { scale: 0.95, opacity: 0, y: 20 }
202
+ }
203
+ };
204
+ var drawerVariants = {
205
+ fromLeft: {
206
+ hidden: { x: "-100%" },
207
+ visible: { x: 0 },
208
+ exit: { x: "-100%" }
209
+ },
210
+ fromRight: {
211
+ hidden: { x: "100%" },
212
+ visible: { x: 0 },
213
+ exit: { x: "100%" }
214
+ },
215
+ fromTop: {
216
+ hidden: { y: "-100%" },
217
+ visible: { y: 0 },
218
+ exit: { y: "-100%" }
219
+ },
220
+ fromBottom: {
221
+ hidden: { y: "100%" },
222
+ visible: { y: 0 },
223
+ exit: { y: "100%" }
224
+ }
225
+ };
226
+ var collapseVariants = {
227
+ collapsed: {
228
+ height: 0,
229
+ opacity: 0,
230
+ transition: { duration: durations.fast }
231
+ },
232
+ expanded: {
233
+ height: "auto",
234
+ opacity: 1,
235
+ transition: { duration: durations.normal }
236
+ }
237
+ };
238
+ var presets = {
239
+ /**
240
+ * Fade in/out animation
241
+ */
242
+ fade: {
243
+ initial: "hidden",
244
+ animate: "visible",
245
+ exit: "exit",
246
+ variants: fadeVariants,
247
+ transition: transitions.default
248
+ },
249
+ /**
250
+ * Slide from bottom animation
251
+ */
252
+ slideUp: {
253
+ initial: "hidden",
254
+ animate: "visible",
255
+ exit: "exit",
256
+ variants: slideVariants.fromBottom,
257
+ transition: transitions.default
258
+ },
259
+ /**
260
+ * Scale animation
261
+ */
262
+ scale: {
263
+ initial: "hidden",
264
+ animate: "visible",
265
+ exit: "exit",
266
+ variants: scaleVariants.default,
267
+ transition: transitions.default
268
+ },
269
+ /**
270
+ * Modal animation (overlay + content)
271
+ */
272
+ modal: {
273
+ overlay: {
274
+ initial: "hidden",
275
+ animate: "visible",
276
+ exit: "exit",
277
+ variants: modalVariants.overlay,
278
+ transition: transitions.fast
279
+ },
280
+ content: {
281
+ initial: "hidden",
282
+ animate: "visible",
283
+ exit: "exit",
284
+ variants: modalVariants.content,
285
+ transition: transitions.default
286
+ }
287
+ },
288
+ /**
289
+ * List stagger animation
290
+ */
291
+ list: {
292
+ container: {
293
+ initial: "hidden",
294
+ animate: "visible",
295
+ variants: listVariants.container
296
+ },
297
+ item: {
298
+ variants: listVariants.item
299
+ }
300
+ }
301
+ };
302
+ function createAnimation(variants, transition = transitions.default) {
303
+ return {
304
+ initial: "hidden",
305
+ animate: "visible",
306
+ exit: "exit",
307
+ variants,
308
+ transition
309
+ };
310
+ }
311
+ function scaleDuration(duration, scale) {
312
+ return duration * (scale / 10);
313
+ }
314
+
315
+ // src/lib/breadcrumbs.ts
316
+ function generateBreadcrumbs(hash, routeConfig, baseUrl = "#") {
317
+ const cleanHash = hash.replace(/^#/, "").trim();
318
+ if (!cleanHash) {
319
+ return [{ label: "Home", href: baseUrl }];
320
+ }
321
+ const segments = cleanHash.split("/").filter(Boolean);
322
+ const breadcrumbs = [{ label: "Home", href: baseUrl }];
323
+ let currentPath = "";
324
+ let currentConfig = routeConfig;
325
+ for (let i = 0; i < segments.length; i++) {
326
+ const segment = segments[i];
327
+ const isLast = i === segments.length - 1;
328
+ currentPath += (currentPath ? "/" : "") + segment;
329
+ const config = currentConfig[segment];
330
+ if (!config) {
331
+ const label = segment.split("-").map((word) => word.charAt(0).toUpperCase() + word.slice(1)).join(" ");
332
+ breadcrumbs.push({
333
+ label,
334
+ // No href for the last item (current page)
335
+ href: isLast ? void 0 : `${baseUrl}${currentPath}`
336
+ });
337
+ } else {
338
+ breadcrumbs.push({
339
+ label: config.label,
340
+ // No href for the last item (current page)
341
+ href: isLast ? void 0 : `${baseUrl}${currentPath}`
342
+ });
343
+ if (config.children) {
344
+ currentConfig = config.children;
345
+ }
346
+ }
347
+ }
348
+ return breadcrumbs;
349
+ }
350
+
351
+ // src/lib/colors.ts
352
+ var colorTokens = {
353
+ // Background colors
354
+ background: "var(--color-background)",
355
+ backgroundSecondary: "var(--color-background-secondary)",
356
+ backgroundTertiary: "var(--color-background-tertiary)",
357
+ surface: "var(--color-surface)",
358
+ // Foreground/Text colors
359
+ foreground: "var(--color-foreground)",
360
+ foregroundSecondary: "var(--color-foreground-secondary)",
361
+ foregroundTertiary: "var(--color-foreground-tertiary)",
362
+ textPrimary: "var(--color-text-primary)",
363
+ textSecondary: "var(--color-text-secondary)",
364
+ textMuted: "var(--color-text-muted)",
365
+ // Brand colors
366
+ primary: "var(--color-primary)",
367
+ primaryForeground: "var(--color-primary-foreground)",
368
+ secondary: "var(--color-secondary)",
369
+ secondaryForeground: "var(--color-secondary-foreground)",
370
+ accent: "var(--color-accent)",
371
+ accentForeground: "var(--color-accent-foreground)",
372
+ // Semantic colors
373
+ success: "var(--color-success)",
374
+ successForeground: "var(--color-success-foreground)",
375
+ warning: "var(--color-warning)",
376
+ warningForeground: "var(--color-warning-foreground)",
377
+ error: "var(--color-error)",
378
+ errorForeground: "var(--color-error-foreground)",
379
+ info: "var(--color-info)",
380
+ infoForeground: "var(--color-info-foreground)",
381
+ // Borders
382
+ border: "var(--color-border)",
383
+ borderSubtle: "var(--color-border-subtle)",
384
+ // Interactive states
385
+ hover: "var(--color-hover)",
386
+ active: "var(--color-active)",
387
+ focus: "var(--color-focus)",
388
+ // Links
389
+ link: "var(--color-link)",
390
+ linkHover: "var(--color-link-hover)",
391
+ linkHoverForeground: "var(--color-link-hover-foreground)"
392
+ };
393
+ function getCSSVariable(variableName, element = document.documentElement) {
394
+ const name = variableName.startsWith("--") ? variableName : `--${variableName}`;
395
+ return getComputedStyle(element).getPropertyValue(name).trim();
396
+ }
397
+ function setCSSVariable(variableName, value, element = document.documentElement) {
398
+ const name = variableName.startsWith("--") ? variableName : `--${variableName}`;
399
+ element.style.setProperty(name, value);
400
+ }
401
+ function getForegroundColor(backgroundToken) {
402
+ const token = backgroundToken.replace(/var\(|\)/g, "");
403
+ const foregroundMap = {
404
+ "--color-primary": "var(--color-primary-foreground)",
405
+ "--color-secondary": "var(--color-secondary-foreground)",
406
+ "--color-accent": "var(--color-accent-foreground)",
407
+ "--color-success": "var(--color-success-foreground)",
408
+ "--color-warning": "var(--color-warning-foreground)",
409
+ "--color-error": "var(--color-error-foreground)",
410
+ "--color-info": "var(--color-info-foreground)",
411
+ "--color-background": "var(--color-foreground)",
412
+ "--color-surface": "var(--color-text-primary)"
413
+ };
414
+ return foregroundMap[token] || "var(--color-text-primary)";
415
+ }
416
+ var semanticColors = {
417
+ /**
418
+ * Status colors for indicating states
419
+ */
420
+ status: {
421
+ success: {
422
+ bg: colorTokens.success,
423
+ fg: colorTokens.successForeground
424
+ },
425
+ warning: {
426
+ bg: colorTokens.warning,
427
+ fg: colorTokens.warningForeground
428
+ },
429
+ error: {
430
+ bg: colorTokens.error,
431
+ fg: colorTokens.errorForeground
432
+ },
433
+ info: {
434
+ bg: colorTokens.info,
435
+ fg: colorTokens.infoForeground
436
+ }
437
+ },
438
+ /**
439
+ * Brand colors for primary UI elements
440
+ */
441
+ brand: {
442
+ primary: {
443
+ bg: colorTokens.primary,
444
+ fg: colorTokens.primaryForeground
445
+ },
446
+ secondary: {
447
+ bg: colorTokens.secondary,
448
+ fg: colorTokens.secondaryForeground
449
+ },
450
+ accent: {
451
+ bg: colorTokens.accent,
452
+ fg: colorTokens.accentForeground
453
+ }
454
+ },
455
+ /**
456
+ * Interactive state colors
457
+ */
458
+ interactive: {
459
+ default: {
460
+ bg: colorTokens.background,
461
+ fg: colorTokens.foreground
462
+ },
463
+ hover: {
464
+ bg: colorTokens.hover,
465
+ fg: colorTokens.foreground
466
+ },
467
+ active: {
468
+ bg: colorTokens.active,
469
+ fg: colorTokens.foreground
470
+ },
471
+ focus: {
472
+ border: colorTokens.focus
473
+ }
474
+ }
475
+ };
476
+ function getSemanticColorPair(type) {
477
+ if (type === "primary" || type === "secondary" || type === "accent") {
478
+ return semanticColors.brand[type];
479
+ }
480
+ return semanticColors.status[type];
481
+ }
482
+ function hexToRgb(hex) {
483
+ const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
484
+ return result ? {
485
+ r: parseInt(result[1], 16),
486
+ g: parseInt(result[2], 16),
487
+ b: parseInt(result[3], 16)
488
+ } : null;
489
+ }
490
+ function getLuminance(r, g, b) {
491
+ const [rs, gs, bs] = [r, g, b].map((c) => {
492
+ const srgb = c / 255;
493
+ return srgb <= 0.03928 ? srgb / 12.92 : Math.pow((srgb + 0.055) / 1.055, 2.4);
494
+ });
495
+ return 0.2126 * rs + 0.7152 * gs + 0.0722 * bs;
496
+ }
497
+ function getContrastRatio(hex1, hex2) {
498
+ const rgb1 = hexToRgb(hex1);
499
+ const rgb2 = hexToRgb(hex2);
500
+ if (!rgb1 || !rgb2) return 0;
501
+ const lum1 = getLuminance(rgb1.r, rgb1.g, rgb1.b);
502
+ const lum2 = getLuminance(rgb2.r, rgb2.g, rgb2.b);
503
+ const lighter = Math.max(lum1, lum2);
504
+ const darker = Math.min(lum1, lum2);
505
+ return (lighter + 0.05) / (darker + 0.05);
506
+ }
507
+ function meetsContrastRequirements(foreground, background, level = "AA", size = "normal") {
508
+ const ratio = getContrastRatio(foreground, background);
509
+ const requirements = {
510
+ AA: { normal: 4.5, large: 3 },
511
+ AAA: { normal: 7, large: 4.5 }
512
+ };
513
+ return ratio >= requirements[level][size];
514
+ }
515
+ function hexToHSL(hex) {
516
+ const rgb = hexToRgb(hex);
517
+ if (!rgb) return { h: 0, s: 0, l: 0 };
518
+ const r = rgb.r / 255;
519
+ const g = rgb.g / 255;
520
+ const b = rgb.b / 255;
521
+ const max = Math.max(r, g, b);
522
+ const min = Math.min(r, g, b);
523
+ let h = 0, s = 0, l = (max + min) / 2;
524
+ if (max !== min) {
525
+ const d = max - min;
526
+ s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
527
+ switch (max) {
528
+ case r:
529
+ h = ((g - b) / d + (g < b ? 6 : 0)) / 6;
530
+ break;
531
+ case g:
532
+ h = ((b - r) / d + 2) / 6;
533
+ break;
534
+ case b:
535
+ h = ((r - g) / d + 4) / 6;
536
+ break;
537
+ }
538
+ }
539
+ return {
540
+ h: Math.round(h * 360),
541
+ s: Math.round(s * 100),
542
+ l: Math.round(l * 100)
543
+ };
544
+ }
545
+ function hslToHex(h, s, l) {
546
+ h = h / 360;
547
+ s = s / 100;
548
+ l = l / 100;
549
+ let r, g, b;
550
+ if (s === 0) {
551
+ r = g = b = l;
552
+ } else {
553
+ const hue2rgb = (p2, q2, t) => {
554
+ if (t < 0) t += 1;
555
+ if (t > 1) t -= 1;
556
+ if (t < 1 / 6) return p2 + (q2 - p2) * 6 * t;
557
+ if (t < 1 / 2) return q2;
558
+ if (t < 2 / 3) return p2 + (q2 - p2) * (2 / 3 - t) * 6;
559
+ return p2;
560
+ };
561
+ const q = l < 0.5 ? l * (1 + s) : l + s - l * s;
562
+ const p = 2 * l - q;
563
+ r = hue2rgb(p, q, h + 1 / 3);
564
+ g = hue2rgb(p, q, h);
565
+ b = hue2rgb(p, q, h - 1 / 3);
566
+ }
567
+ const toHex = (x) => {
568
+ const hex = Math.round(x * 255).toString(16);
569
+ return hex.length === 1 ? "0" + hex : hex;
570
+ };
571
+ return `#${toHex(r)}${toHex(g)}${toHex(b)}`;
572
+ }
573
+ function adjustLightness(hex, percent) {
574
+ const hsl = hexToHSL(hex);
575
+ const newL = Math.max(0, Math.min(100, hsl.l + percent));
576
+ return hslToHex(hsl.h, hsl.s, newL);
577
+ }
578
+ function adjustSaturation(hex, percent) {
579
+ const hsl = hexToHSL(hex);
580
+ const newS = Math.max(0, Math.min(100, hsl.s + percent));
581
+ return hslToHex(hsl.h, newS, hsl.l);
582
+ }
583
+ function rotateHue(hex, degrees) {
584
+ const hsl = hexToHSL(hex);
585
+ const newH = (hsl.h + degrees) % 360;
586
+ return hslToHex(newH, hsl.s, hsl.l);
587
+ }
588
+ function adjustOpacity(hex, opacity) {
589
+ const rgb = hexToRgb(hex);
590
+ if (!rgb) return hex;
591
+ return `rgba(${rgb.r}, ${rgb.g}, ${rgb.b}, ${opacity})`;
592
+ }
593
+ function getOptimalForeground(bgHex, whiteHex = "#ffffff", blackHex = "#000000") {
594
+ const whiteRatio = getContrastRatio(bgHex, whiteHex);
595
+ const blackRatio = getContrastRatio(bgHex, blackHex);
596
+ return whiteRatio > blackRatio ? whiteHex : blackHex;
597
+ }
598
+ function generateColorScale(baseHex) {
599
+ const hsl = hexToHSL(baseHex);
600
+ return {
601
+ 50: hslToHex(hsl.h, Math.max(hsl.s - 10, 20), 95),
602
+ 100: hslToHex(hsl.h, Math.max(hsl.s - 5, 30), 90),
603
+ 200: hslToHex(hsl.h, hsl.s, 80),
604
+ 300: hslToHex(hsl.h, hsl.s, 70),
605
+ 400: hslToHex(hsl.h, hsl.s, 60),
606
+ 500: baseHex,
607
+ // Base color
608
+ 600: hslToHex(hsl.h, Math.min(hsl.s + 5, 100), 45),
609
+ 700: hslToHex(hsl.h, Math.min(hsl.s + 10, 100), 35),
610
+ 800: hslToHex(hsl.h, Math.min(hsl.s + 15, 100), 25),
611
+ 900: hslToHex(hsl.h, Math.min(hsl.s + 20, 100), 15)
612
+ };
613
+ }
614
+ var colorUtils = {
615
+ getCSSVariable,
616
+ setCSSVariable,
617
+ getForegroundColor,
618
+ getSemanticColorPair,
619
+ hexToRgb,
620
+ hexToHSL,
621
+ hslToHex,
622
+ adjustLightness,
623
+ adjustSaturation,
624
+ rotateHue,
625
+ adjustOpacity,
626
+ getOptimalForeground,
627
+ generateColorScale,
628
+ getContrastRatio,
629
+ meetsContrastRequirements
630
+ };
631
+
632
+ // src/lib/utils.ts
633
+ var import_clsx = require("clsx");
634
+ var import_tailwind_merge = require("tailwind-merge");
635
+ function cn(...inputs) {
636
+ return (0, import_tailwind_merge.twMerge)((0, import_clsx.clsx)(inputs));
637
+ }
638
+
639
+ // src/lib/validation.ts
640
+ var patterns = {
641
+ email: {
642
+ value: /^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}$/i,
643
+ message: "Invalid email address"
644
+ },
645
+ url: {
646
+ value: /^https?:\/\/.+\..+/,
647
+ message: "Invalid URL"
648
+ },
649
+ phone: {
650
+ value: /^[\d\s\-\+\(\)]+$/,
651
+ message: "Invalid phone number"
652
+ },
653
+ alphanumeric: {
654
+ value: /^[a-zA-Z0-9]+$/,
655
+ message: "Only letters and numbers allowed"
656
+ },
657
+ noSpaces: {
658
+ value: /^\S+$/,
659
+ message: "Spaces are not allowed"
660
+ }
661
+ };
662
+ function validateField(value, rules2) {
663
+ if (rules2.required) {
664
+ const isEmpty = value === void 0 || value === null || value === "" || Array.isArray(value) && value.length === 0;
665
+ if (isEmpty) {
666
+ return typeof rules2.required === "string" ? rules2.required : "This field is required";
667
+ }
668
+ }
669
+ if (!value && !rules2.required) {
670
+ return void 0;
671
+ }
672
+ if (rules2.minLength && value.length < rules2.minLength.value) {
673
+ return rules2.minLength.message;
674
+ }
675
+ if (rules2.maxLength && value.length > rules2.maxLength.value) {
676
+ return rules2.maxLength.message;
677
+ }
678
+ if (rules2.pattern && !rules2.pattern.value.test(value)) {
679
+ return rules2.pattern.message;
680
+ }
681
+ if (rules2.custom) {
682
+ for (const rule of rules2.custom) {
683
+ if (!rule.validate(value)) {
684
+ return rule.message;
685
+ }
686
+ }
687
+ }
688
+ return void 0;
689
+ }
690
+ function validateForm(values, validations) {
691
+ const errors = {};
692
+ for (const [field, rules2] of Object.entries(validations)) {
693
+ const error = validateField(values[field], rules2);
694
+ if (error) {
695
+ errors[field] = error;
696
+ }
697
+ }
698
+ return errors;
699
+ }
700
+ function hasErrors(errors) {
701
+ return Object.values(errors).some((error) => error !== void 0);
702
+ }
703
+ var rules = {
704
+ required: (message = "This field is required") => ({
705
+ required: message
706
+ }),
707
+ email: (message = "Invalid email address") => ({
708
+ pattern: { value: patterns.email.value, message }
709
+ }),
710
+ minLength: (length, message) => ({
711
+ minLength: {
712
+ value: length,
713
+ message: message || `Minimum ${length} characters required`
714
+ }
715
+ }),
716
+ maxLength: (length, message) => ({
717
+ maxLength: {
718
+ value: length,
719
+ message: message || `Maximum ${length} characters allowed`
720
+ }
721
+ }),
722
+ match: (otherValue, message = "Values do not match") => ({
723
+ custom: [
724
+ {
725
+ validate: (value) => value === otherValue,
726
+ message
727
+ }
728
+ ]
729
+ })
730
+ };
731
+
732
+ // src/lib/syntax-parser/patterns.ts
733
+ var TOKEN_PATTERNS = [
734
+ // Single-line comments
735
+ { type: "comment", pattern: /\/\/.*$/gm },
736
+ // Multi-line comments
737
+ { type: "comment", pattern: /\/\*[\s\S]*?\*\//g },
738
+ // Template literals and strings
739
+ { type: "string", pattern: /`(?:\\.|[^`\\])*`/g },
740
+ { type: "string", pattern: /"(?:\\.|[^"\\])*"/g },
741
+ { type: "string", pattern: /'(?:\\.|[^'\\])*'/g },
742
+ // JSX/TSX tags
743
+ { type: "tag", pattern: /<\/?[A-Z][a-zA-Z0-9]*(?=[\s>])/g },
744
+ { type: "tag", pattern: /<\/?[a-z][a-zA-Z0-9-]*(?=[\s>])/g },
745
+ // Keywords
746
+ {
747
+ type: "keyword",
748
+ pattern: /\b(const|let|var|function|return|if|else|for|while|do|switch|case|break|continue|throw|try|catch|finally|new|typeof|instanceof|void|delete|async|await|yield|export|import|from|default|class|extends|implements|interface|type|enum|namespace|declare|public|private|protected|static|readonly|abstract|as|is|in|of|null|undefined)\b/g
749
+ },
750
+ // Booleans
751
+ { type: "boolean", pattern: /\b(true|false)\b/g },
752
+ // Numbers
753
+ { type: "number", pattern: /\b\d+\.?\d*(?:e[+-]?\d+)?(?:n)?\b/gi },
754
+ { type: "number", pattern: /\b0x[0-9a-f]+\b/gi },
755
+ // Function calls
756
+ { type: "function", pattern: /\b[a-zA-Z_$][a-zA-Z0-9_$]*(?=\s*\()/g },
757
+ // Class names (PascalCase identifiers)
758
+ { type: "className", pattern: /\b[A-Z][a-zA-Z0-9]*\b/g },
759
+ // JSX attributes
760
+ { type: "attribute", pattern: /\b[a-z][a-zA-Z0-9]*(?=\s*=)/g },
761
+ // Object properties (after dot)
762
+ { type: "property", pattern: /(?<=\.)[a-zA-Z_$][a-zA-Z0-9_$]*/g },
763
+ // Operators
764
+ {
765
+ type: "operator",
766
+ pattern: /[+\-*/%=!<>&|^~?:]+|&&|\|\||\.\.\.|\?\?|===|!==|==|!=|<=|>=|<<|>>|>>>/g
767
+ },
768
+ // Punctuation
769
+ { type: "punctuation", pattern: /[{}[\](),.;]/g }
770
+ ];
771
+
772
+ // src/lib/syntax-parser/tokenizer.ts
773
+ function tokenize(code, language = "typescript") {
774
+ if (!code || code.trim() === "") {
775
+ return [{ text: code, type: "plain" }];
776
+ }
777
+ const matches = [];
778
+ for (const { type, pattern } of TOKEN_PATTERNS) {
779
+ pattern.lastIndex = 0;
780
+ let match;
781
+ while ((match = pattern.exec(code)) !== null) {
782
+ matches.push({
783
+ text: match[0],
784
+ type,
785
+ index: match.index
786
+ });
787
+ }
788
+ }
789
+ matches.sort((a, b) => a.index - b.index);
790
+ const nonOverlapping = [];
791
+ let lastEnd = 0;
792
+ for (const match of matches) {
793
+ if (match.index >= lastEnd) {
794
+ nonOverlapping.push(match);
795
+ lastEnd = match.index + match.text.length;
796
+ }
797
+ }
798
+ const tokens = [];
799
+ let position = 0;
800
+ for (const match of nonOverlapping) {
801
+ if (match.index > position) {
802
+ const plainText = code.slice(position, match.index);
803
+ tokens.push({ text: plainText, type: "plain" });
804
+ }
805
+ tokens.push({ text: match.text, type: match.type });
806
+ position = match.index + match.text.length;
807
+ }
808
+ if (position < code.length) {
809
+ tokens.push({ text: code.slice(position), type: "plain" });
810
+ }
811
+ return tokens;
812
+ }
813
+ function detectLanguage(code, filename) {
814
+ if (filename) {
815
+ if (filename.endsWith(".tsx")) return "tsx";
816
+ if (filename.endsWith(".jsx")) return "jsx";
817
+ if (filename.endsWith(".js")) return "javascript";
818
+ }
819
+ return "typescript";
820
+ }
821
+
822
+ // src/lib/syntax-parser/index.ts
823
+ function parseCode(code, language) {
824
+ const lang = language || detectLanguage(code);
825
+ return tokenize(code, lang);
826
+ }
827
+ // Annotate the CommonJS export names for ESM import in node:
828
+ 0 && (module.exports = {
829
+ adjustLightness,
830
+ adjustOpacity,
831
+ adjustSaturation,
832
+ cn,
833
+ collapseVariants,
834
+ colorTokens,
835
+ colorUtils,
836
+ createAnimation,
837
+ detectLanguage,
838
+ drawerVariants,
839
+ durations,
840
+ easings,
841
+ fadeVariants,
842
+ generateBreadcrumbs,
843
+ generateColorScale,
844
+ getCSSVariable,
845
+ getContrastRatio,
846
+ getForegroundColor,
847
+ getLuminance,
848
+ getOptimalForeground,
849
+ getSemanticColorPair,
850
+ hasErrors,
851
+ hexToHSL,
852
+ hexToRgb,
853
+ hslToHex,
854
+ listVariants,
855
+ meetsContrastRequirements,
856
+ modalVariants,
857
+ parseCode,
858
+ patterns,
859
+ presets,
860
+ rotateHue,
861
+ rotateVariants,
862
+ rules,
863
+ scaleDuration,
864
+ scaleVariants,
865
+ semanticColors,
866
+ setCSSVariable,
867
+ slideVariants,
868
+ tokenize,
869
+ transitions,
870
+ validateField,
871
+ validateForm
872
+ });
873
+ //# sourceMappingURL=utils.js.map