luna-components-library 1.1.34 → 1.1.37

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.
@@ -1,7 +1,1077 @@
1
- import { useEffect, useRef, useState } from "react";
1
+ import React, { useCallback, useEffect, useMemo, useRef, useState } from "react";
2
2
  //#region \0rolldown/runtime.js
3
3
  var __commonJSMin = (cb, mod) => () => (mod || (cb((mod = { exports: {} }).exports, mod), cb = null), mod.exports);
4
4
  //#endregion
5
+ //#region src/styles.ts
6
+ var colors = {
7
+ white: "#ffffff",
8
+ border: "#e5e7eb",
9
+ borderInput: "#d1d5db",
10
+ borderLight: "#f3f4f6",
11
+ text: "#374151",
12
+ textSecondary: "#4b5563",
13
+ textMuted: "#6b7280",
14
+ textDisabled: "#9ca3af",
15
+ bgHeader: "#f9fafb",
16
+ bgHover: "#f3f4f6",
17
+ bgSelected: "#eff6ff",
18
+ bgSkeleton: "#f3f4f6",
19
+ primary: "#2563eb",
20
+ dark: "#111827"
21
+ };
22
+ var radii = {
23
+ sm: "0.375rem",
24
+ md: "0.5rem",
25
+ lg: "0.75rem",
26
+ full: "50%",
27
+ pill: "9999px"
28
+ };
29
+ var fontSizes = {
30
+ xs: "0.75rem",
31
+ sm: "0.875rem",
32
+ base: "1rem",
33
+ lg: "1.125rem",
34
+ xl: "1.25rem"
35
+ };
36
+ var fontWeights = {
37
+ medium: 500,
38
+ semibold: 600,
39
+ bold: 700
40
+ };
41
+ var transitions = {
42
+ fast: "all 150ms ease-in-out",
43
+ bg: "background-color 150ms",
44
+ bgSlow: "background-color 200ms",
45
+ transform: "transform 200ms",
46
+ normal: "all 300ms ease-in-out"
47
+ };
48
+ var shadows = {
49
+ panel: "0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05)",
50
+ menu: "0 4px 6px -1px rgba(0, 0, 0, 0.1)"
51
+ };
52
+ var zIndices = {
53
+ panel: 1e3,
54
+ menu: 100
55
+ };
56
+ var sizeStyles = {
57
+ sm: {
58
+ padding: "0.375rem 0.75rem",
59
+ fontSize: "0.875rem"
60
+ },
61
+ md: {
62
+ padding: "0.5rem 1rem",
63
+ fontSize: "1rem"
64
+ },
65
+ lg: {
66
+ padding: "0.75rem 1.5rem",
67
+ fontSize: "1.125rem"
68
+ }
69
+ };
70
+ var sizeClasses = {
71
+ sm: "px-3 py-1.5 text-sm",
72
+ md: "px-4 py-2 text-base",
73
+ lg: "px-6 py-3 text-lg"
74
+ };
75
+ var commonStyles = {
76
+ container: {
77
+ backgroundColor: colors.white,
78
+ border: `1px solid ${colors.border}`,
79
+ borderRadius: radii.lg
80
+ },
81
+ panel: {
82
+ position: "absolute",
83
+ top: "100%",
84
+ left: 0,
85
+ width: "100%",
86
+ marginTop: "0.5rem",
87
+ backgroundColor: colors.white,
88
+ border: `1px solid ${colors.border}`,
89
+ borderRadius: radii.lg,
90
+ boxShadow: shadows.panel,
91
+ zIndex: zIndices.panel,
92
+ overflow: "hidden"
93
+ },
94
+ trigger: {
95
+ width: "100%",
96
+ padding: "0.5rem 0.75rem",
97
+ backgroundColor: colors.white,
98
+ border: `1px solid ${colors.borderInput}`,
99
+ borderRadius: radii.lg,
100
+ display: "flex",
101
+ alignItems: "center",
102
+ justifyContent: "space-between",
103
+ fontSize: fontSizes.sm,
104
+ color: colors.text,
105
+ cursor: "pointer",
106
+ outline: "none",
107
+ transition: transitions.fast
108
+ },
109
+ header: {
110
+ width: "100%",
111
+ padding: "1rem",
112
+ display: "flex",
113
+ alignItems: "center",
114
+ justifyContent: "space-between",
115
+ backgroundColor: colors.bgHeader,
116
+ border: "none",
117
+ cursor: "pointer",
118
+ textAlign: "left",
119
+ fontSize: fontSizes.sm,
120
+ fontWeight: fontWeights.semibold,
121
+ color: colors.text,
122
+ outline: "none"
123
+ },
124
+ chevron: {
125
+ fontSize: fontSizes.xs,
126
+ transition: transitions.transform,
127
+ color: colors.textDisabled
128
+ },
129
+ list: {
130
+ maxHeight: "200px",
131
+ overflowY: "auto",
132
+ padding: "0.25rem 0"
133
+ },
134
+ item: (isSelected, isDisabled) => ({
135
+ padding: "0.5rem 0.75rem",
136
+ display: "flex",
137
+ alignItems: "center",
138
+ gap: "0.75rem",
139
+ cursor: isDisabled ? "not-allowed" : "pointer",
140
+ backgroundColor: isSelected ? colors.bgSelected : "transparent",
141
+ color: isDisabled ? colors.textDisabled : colors.text,
142
+ fontSize: fontSizes.sm,
143
+ transition: transitions.bg
144
+ }),
145
+ chip: {
146
+ display: "inline-flex",
147
+ alignItems: "center",
148
+ gap: "0.25rem",
149
+ backgroundColor: colors.bgHover,
150
+ border: `1px solid ${colors.border}`,
151
+ borderRadius: radii.sm,
152
+ padding: "0.125rem 0.375rem",
153
+ fontSize: fontSizes.xs,
154
+ color: colors.textSecondary
155
+ },
156
+ icon: {
157
+ marginLeft: "0.5rem",
158
+ fontSize: fontSizes.xs,
159
+ color: colors.textDisabled,
160
+ cursor: "pointer",
161
+ display: "inline-flex",
162
+ alignItems: "center"
163
+ },
164
+ checkbox: {
165
+ width: "1rem",
166
+ height: "1rem",
167
+ cursor: "inherit"
168
+ },
169
+ filterMenu: {
170
+ position: "absolute",
171
+ top: "100%",
172
+ left: "1rem",
173
+ backgroundColor: colors.white,
174
+ border: `1px solid ${colors.border}`,
175
+ borderRadius: radii.md,
176
+ boxShadow: shadows.menu,
177
+ zIndex: zIndices.menu,
178
+ padding: "0.5rem",
179
+ minWidth: "150px"
180
+ },
181
+ filterOption: (active) => ({
182
+ width: "100%",
183
+ padding: "0.375rem 0.75rem",
184
+ textAlign: "left",
185
+ fontSize: fontSizes.xs,
186
+ border: "none",
187
+ backgroundColor: active ? colors.bgSelected : "transparent",
188
+ color: active ? colors.primary : colors.text,
189
+ borderRadius: radii.sm,
190
+ cursor: "pointer",
191
+ display: "block"
192
+ }),
193
+ pagination: {
194
+ padding: "1rem",
195
+ display: "flex",
196
+ alignItems: "center",
197
+ justifyContent: "space-between",
198
+ borderTop: `1px solid ${colors.border}`,
199
+ backgroundColor: colors.bgHeader
200
+ },
201
+ buttonBase: {
202
+ display: "inline-flex",
203
+ alignItems: "center",
204
+ justifyContent: "center",
205
+ fontWeight: fontWeights.medium,
206
+ borderRadius: radii.md,
207
+ transition: transitions.fast,
208
+ cursor: "pointer",
209
+ outline: "none",
210
+ border: "1px solid transparent"
211
+ },
212
+ inputWrapper: {
213
+ position: "relative",
214
+ display: "inline-block",
215
+ width: "100%"
216
+ },
217
+ inputLabel: {
218
+ marginBottom: "0.25rem",
219
+ display: "block",
220
+ fontSize: fontSizes.sm,
221
+ fontWeight: fontWeights.medium,
222
+ color: colors.text
223
+ },
224
+ inputField: {
225
+ width: "100%",
226
+ borderRadius: radii.md,
227
+ border: `1px solid ${colors.borderInput}`,
228
+ transition: transitions.fast,
229
+ outline: "none"
230
+ },
231
+ popover: {
232
+ position: "absolute",
233
+ width: "220px",
234
+ backgroundColor: colors.white,
235
+ border: `1px solid ${colors.border}`,
236
+ borderRadius: radii.lg,
237
+ boxShadow: shadows.panel,
238
+ zIndex: zIndices.panel,
239
+ padding: "1rem"
240
+ },
241
+ floatingButton: {
242
+ cursor: "pointer",
243
+ border: "none",
244
+ outline: "none",
245
+ display: "flex",
246
+ alignItems: "center",
247
+ justifyContent: "center",
248
+ borderRadius: radii.full,
249
+ boxShadow: shadows.panel
250
+ },
251
+ card: {
252
+ backgroundColor: colors.white,
253
+ border: `1px solid ${colors.border}`,
254
+ borderRadius: radii.md
255
+ }
256
+ };
257
+ var cardPaddingValues = {
258
+ none: "0",
259
+ sm: "0.75rem",
260
+ md: "1rem",
261
+ lg: "1.5rem"
262
+ };
263
+ var cardShadowValues = {
264
+ none: "none",
265
+ sm: "0 1px 2px 0 rgba(0, 0, 0, 0.05)",
266
+ md: "0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06)",
267
+ lg: "0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05)"
268
+ };
269
+ var cardStyles = (padding, shadow, styles) => ({
270
+ container: {
271
+ ...commonStyles.card,
272
+ padding: cardPaddingValues[padding],
273
+ boxShadow: cardShadowValues[shadow],
274
+ width: "100%",
275
+ ...styles?.container
276
+ },
277
+ titleContainer: {
278
+ marginBottom: "1rem",
279
+ ...styles?.titleContainer
280
+ },
281
+ title: {
282
+ fontSize: fontSizes.lg,
283
+ fontWeight: fontWeights.semibold,
284
+ color: colors.dark,
285
+ margin: 0,
286
+ ...styles?.title
287
+ },
288
+ content: { ...styles?.content }
289
+ });
290
+ var dataTableStyles = (styles) => ({
291
+ container: {
292
+ ...commonStyles.container,
293
+ width: "100%",
294
+ overflowX: "auto",
295
+ ...styles?.container
296
+ },
297
+ searchContainer: {
298
+ padding: "1rem",
299
+ borderBottom: `1px solid ${colors.border}`
300
+ },
301
+ table: {
302
+ width: "100%",
303
+ borderCollapse: "collapse",
304
+ textAlign: "left",
305
+ fontSize: fontSizes.sm,
306
+ ...styles?.table
307
+ },
308
+ thead: { ...styles?.thead },
309
+ th: {
310
+ padding: "0.75rem 1rem",
311
+ backgroundColor: colors.bgHeader,
312
+ borderBottom: `1px solid ${colors.border}`,
313
+ fontWeight: fontWeights.semibold,
314
+ color: colors.text,
315
+ fontSize: fontSizes.sm,
316
+ position: "relative",
317
+ ...styles?.th
318
+ },
319
+ td: {
320
+ padding: "0.75rem 1rem",
321
+ borderBottom: `1px solid ${colors.border}`,
322
+ color: colors.textSecondary,
323
+ ...styles?.td
324
+ },
325
+ tr: (clickable) => ({
326
+ transition: transitions.bg,
327
+ cursor: clickable ? "pointer" : "default"
328
+ }),
329
+ pagination: { ...commonStyles.pagination },
330
+ icon: { ...commonStyles.icon },
331
+ filterMenu: { ...commonStyles.filterMenu },
332
+ filterOption: (active) => ({ ...commonStyles.filterOption(active) })
333
+ });
334
+ var dropDownStyles = (styles, disabled, isOpen, hoverIndex, value) => ({
335
+ container: {
336
+ position: "relative",
337
+ display: "inline-flex",
338
+ width: "100%",
339
+ fontSize: fontSizes.sm,
340
+ color: colors.text,
341
+ ...styles?.container
342
+ },
343
+ trigger: {
344
+ ...commonStyles.trigger,
345
+ padding: "0.625rem 1rem",
346
+ borderRadius: radii.md,
347
+ color: value ? colors.dark : colors.textDisabled,
348
+ cursor: disabled ? "not-allowed" : "pointer",
349
+ transition: "border-color 200ms, box-shadow 200ms",
350
+ boxShadow: isOpen ? "0 0 0 3px rgba(37, 99, 235, 0.1)" : "none",
351
+ borderColor: isOpen ? colors.primary : colors.borderInput,
352
+ ...styles?.trigger
353
+ },
354
+ panel: {
355
+ ...commonStyles.panel,
356
+ marginTop: "0.25rem",
357
+ borderRadius: radii.md,
358
+ maxHeight: "200px",
359
+ overflow: "auto",
360
+ display: isOpen ? "block" : "none",
361
+ ...styles?.panel
362
+ },
363
+ option: (index) => ({
364
+ ...commonStyles.item(false, false),
365
+ display: "block",
366
+ textAlign: "left",
367
+ width: "100%",
368
+ border: "none",
369
+ gap: 0,
370
+ padding: "0.5rem 1rem",
371
+ backgroundColor: hoverIndex === index ? colors.bgHover : "transparent",
372
+ ...styles?.option
373
+ }),
374
+ arrow: {
375
+ ...commonStyles.chevron,
376
+ marginLeft: "0.5rem",
377
+ transform: isOpen ? "rotate(180deg)" : "rotate(0deg)"
378
+ }
379
+ });
380
+ var variantStyles = {
381
+ primary: {
382
+ backgroundColor: "#2563eb",
383
+ color: "#ffffff"
384
+ },
385
+ secondary: {
386
+ backgroundColor: "#4b5563",
387
+ color: "#ffffff"
388
+ },
389
+ outline: {
390
+ backgroundColor: "transparent",
391
+ color: "#374151",
392
+ borderColor: "#d1d5db"
393
+ },
394
+ success: {
395
+ backgroundColor: "#16a34a",
396
+ color: "#ffffff"
397
+ },
398
+ danger: {
399
+ backgroundColor: "#dc2626",
400
+ color: "#ffffff"
401
+ },
402
+ warning: {
403
+ backgroundColor: "#eab308",
404
+ color: "#ffffff"
405
+ },
406
+ info: {
407
+ backgroundColor: "#0891b2",
408
+ color: "#ffffff"
409
+ },
410
+ dark: {
411
+ backgroundColor: "#111827",
412
+ color: "#ffffff"
413
+ },
414
+ light: {
415
+ backgroundColor: "#f3f4f6",
416
+ color: "#111827"
417
+ },
418
+ link: {
419
+ backgroundColor: "transparent",
420
+ color: "#2563eb",
421
+ border: "none",
422
+ padding: 0,
423
+ textDecoration: "underline"
424
+ }
425
+ };
426
+ var variantClasses = {
427
+ primary: "bg-blue-600 text-white hover:bg-blue-700",
428
+ secondary: "bg-gray-600 text-white hover:bg-gray-700",
429
+ outline: "border border-gray-300 text-gray-700 hover:bg-gray-50",
430
+ success: "bg-green-600 text-white hover:bg-green-700",
431
+ danger: "bg-red-600 text-white hover:bg-red-700",
432
+ warning: "bg-yellow-500 text-white hover:bg-yellow-600",
433
+ info: "bg-cyan-600 text-white hover:bg-cyan-700",
434
+ dark: "bg-gray-900 text-white hover:bg-gray-800",
435
+ light: "bg-gray-100 text-gray-900 hover:bg-gray-200",
436
+ link: "text-blue-600 hover:text-blue-800 hover:underline"
437
+ };
438
+ var inputStyles = (styles, extraStyle, inputSize, readOnly, disabled) => ({
439
+ container: {
440
+ ...commonStyles.inputWrapper,
441
+ ...styles?.container,
442
+ ...extraStyle
443
+ },
444
+ label: {
445
+ ...commonStyles.inputLabel,
446
+ ...styles?.label
447
+ },
448
+ input: {
449
+ ...commonStyles.inputField,
450
+ padding: inputSize === "sm" ? "0.25rem 0.5rem" : inputSize === "lg" ? "0.75rem 1rem" : inputSize === "xl" ? "1rem 1.5rem" : "0.5rem 0.75rem",
451
+ fontSize: inputSize === "sm" ? fontSizes.sm : inputSize === "lg" ? fontSizes.lg : inputSize === "xl" ? fontSizes.xl : fontSizes.base,
452
+ backgroundColor: readOnly ? colors.borderLight : colors.white,
453
+ cursor: disabled ? "not-allowed" : readOnly ? "default" : "text",
454
+ opacity: disabled ? .5 : 1,
455
+ ...styles?.input
456
+ },
457
+ variants: {
458
+ none: {},
459
+ primary: {
460
+ ...variantStyles.primary,
461
+ borderColor: "#2563eb"
462
+ },
463
+ secondary: {
464
+ ...variantStyles.secondary,
465
+ borderColor: "#4b5563"
466
+ },
467
+ outline: {
468
+ ...variantStyles.outline,
469
+ backgroundColor: "#ffffff",
470
+ borderColor: "#d1d5db"
471
+ },
472
+ danger: {
473
+ ...variantStyles.danger,
474
+ borderColor: "#dc2626"
475
+ },
476
+ success: {
477
+ ...variantStyles.success,
478
+ borderColor: "#16a34a"
479
+ }
480
+ }
481
+ });
482
+ var multiSelectStyles = (styles, disabled, isOpen) => ({
483
+ container: {
484
+ position: "relative",
485
+ width: "100%",
486
+ ...styles?.container
487
+ },
488
+ trigger: {
489
+ ...commonStyles.trigger,
490
+ minHeight: "2.5rem",
491
+ cursor: disabled ? "not-allowed" : "pointer",
492
+ opacity: disabled ? .6 : 1,
493
+ ...styles?.trigger
494
+ },
495
+ chevron: {
496
+ ...commonStyles.chevron,
497
+ transform: isOpen ? "rotate(180deg)" : "rotate(0)"
498
+ },
499
+ panel: {
500
+ ...commonStyles.panel,
501
+ display: isOpen ? "block" : "none",
502
+ ...styles?.panel
503
+ },
504
+ header: {
505
+ ...commonStyles.header,
506
+ padding: "0.75rem",
507
+ borderBottom: `1px solid ${colors.borderLight}`,
508
+ flexDirection: "column",
509
+ gap: "0.5rem",
510
+ ...styles?.header
511
+ },
512
+ selectAllWrapper: {
513
+ display: "flex",
514
+ alignItems: "center",
515
+ gap: "0.5rem",
516
+ fontSize: fontSizes.sm,
517
+ color: colors.text,
518
+ cursor: "pointer"
519
+ },
520
+ list: { ...commonStyles.list },
521
+ item: (isSelected, isDisabled) => ({
522
+ ...commonStyles.item(isSelected, isDisabled),
523
+ ...styles?.item
524
+ }),
525
+ checkbox: { ...commonStyles.checkbox },
526
+ chip: {
527
+ ...commonStyles.chip,
528
+ ...styles?.chip
529
+ },
530
+ chipIcon: {
531
+ cursor: "pointer",
532
+ fontSize: fontSizes.base,
533
+ lineHeight: 1,
534
+ color: colors.textDisabled
535
+ }
536
+ });
537
+ var popconfirmPositionStyles = (pos) => {
538
+ const distance = "10px";
539
+ switch (pos) {
540
+ case "top": return {
541
+ bottom: "100%",
542
+ left: "50%",
543
+ transform: "translateX(-50%)",
544
+ marginBottom: distance
545
+ };
546
+ case "bottom": return {
547
+ top: "100%",
548
+ left: "50%",
549
+ transform: "translateX(-50%)",
550
+ marginTop: distance
551
+ };
552
+ case "left": return {
553
+ right: "100%",
554
+ top: "50%",
555
+ transform: "translateY(-50%)",
556
+ marginRight: distance
557
+ };
558
+ case "right": return {
559
+ left: "100%",
560
+ top: "50%",
561
+ transform: "translateY(-50%)",
562
+ marginLeft: distance
563
+ };
564
+ default: return {};
565
+ }
566
+ };
567
+ var popconfirmStyles = (styles, show, position) => ({
568
+ container: {
569
+ position: "relative",
570
+ display: "inline-block",
571
+ ...styles?.container
572
+ },
573
+ popover: {
574
+ ...commonStyles.popover,
575
+ display: show ? "block" : "none",
576
+ ...popconfirmPositionStyles(position || "top"),
577
+ ...styles?.popover
578
+ },
579
+ titleWrapper: {
580
+ display: "flex",
581
+ alignItems: "flex-start",
582
+ gap: "0.5rem",
583
+ marginBottom: "0.5rem"
584
+ },
585
+ icon: {
586
+ color: "#eab308",
587
+ fontSize: "1rem",
588
+ fontWeight: "bold",
589
+ marginTop: "1px"
590
+ },
591
+ title: {
592
+ fontSize: fontSizes.sm,
593
+ fontWeight: fontWeights.semibold,
594
+ color: colors.dark,
595
+ ...styles?.title
596
+ },
597
+ description: {
598
+ fontSize: fontSizes.xs,
599
+ color: colors.textMuted,
600
+ marginBottom: "0.75rem",
601
+ marginLeft: "1.5rem",
602
+ ...styles?.description
603
+ },
604
+ actions: {
605
+ display: "flex",
606
+ justifyContent: "flex-end",
607
+ gap: "0.5rem"
608
+ }
609
+ });
610
+ var preloaderStyles = (zIndex, backgroundColor, size, borderWidth, styles) => ({
611
+ overlay: {
612
+ position: "fixed",
613
+ top: 0,
614
+ left: 0,
615
+ right: 0,
616
+ bottom: 0,
617
+ zIndex,
618
+ backgroundColor,
619
+ display: "flex",
620
+ alignItems: "center",
621
+ justifyContent: "center",
622
+ transition: "opacity 300ms ease-in-out",
623
+ ...styles?.overlay
624
+ },
625
+ spinner: {
626
+ width: `${size}px`,
627
+ height: `${size}px`,
628
+ borderWidth: `${borderWidth}px`,
629
+ ...styles?.spinner
630
+ }
631
+ });
632
+ var progressBarVariantColors = {
633
+ primary: {
634
+ bg: "#2563eb",
635
+ text: "#ffffff",
636
+ track: "#e5e7eb"
637
+ },
638
+ success: {
639
+ bg: "#16a34a",
640
+ text: "#ffffff",
641
+ track: "#e5e7eb"
642
+ },
643
+ warning: {
644
+ bg: "#eab308",
645
+ text: "#111827",
646
+ track: "#e5e7eb"
647
+ },
648
+ danger: {
649
+ bg: "#dc2626",
650
+ text: "#ffffff",
651
+ track: "#e5e7eb"
652
+ },
653
+ dark: {
654
+ bg: "#1f2937",
655
+ text: "#ffffff",
656
+ track: "#d1d5db"
657
+ },
658
+ light: {
659
+ bg: "#f3f4f6",
660
+ text: "#111827",
661
+ track: "#d1d5db"
662
+ }
663
+ };
664
+ var progressBarStyles = (styles, percentage, variant) => {
665
+ const currentVariant = progressBarVariantColors[variant || "primary"] || progressBarVariantColors.primary;
666
+ return {
667
+ container: {
668
+ width: "100%",
669
+ backgroundColor: colors.bgHover,
670
+ borderRadius: radii.pill,
671
+ height: "1rem",
672
+ overflow: "hidden",
673
+ ...styles?.container
674
+ },
675
+ bar: {
676
+ height: "100%",
677
+ backgroundColor: currentVariant.bg,
678
+ width: `${percentage || 0}%`,
679
+ transition: transitions.normal,
680
+ display: "flex",
681
+ alignItems: "center",
682
+ justifyContent: "center",
683
+ borderRadius: radii.pill,
684
+ ...styles?.bar
685
+ },
686
+ text: {
687
+ color: currentVariant.text,
688
+ fontSize: fontSizes.xs,
689
+ fontWeight: fontWeights.medium,
690
+ whiteSpace: "nowrap",
691
+ padding: "0 0.5rem",
692
+ ...styles?.text
693
+ }
694
+ };
695
+ };
696
+ var qrCodeStyles = (styles, bordered, cleanBgColor, size, isLoading) => ({
697
+ container: {
698
+ display: "inline-flex",
699
+ alignItems: "center",
700
+ justifyContent: "center",
701
+ padding: bordered ? "0.75rem" : "0",
702
+ backgroundColor: `#${cleanBgColor || "ffffff"}`,
703
+ border: bordered ? `1px solid ${colors.border}` : "none",
704
+ borderRadius: radii.lg,
705
+ width: "fit-content",
706
+ position: "relative",
707
+ overflow: "hidden",
708
+ ...styles?.container
709
+ },
710
+ image: {
711
+ display: "block",
712
+ width: `${size || 160}px`,
713
+ height: `${size || 160}px`,
714
+ opacity: isLoading ? 0 : 1,
715
+ transition: "opacity 300ms ease-in-out",
716
+ ...styles?.image
717
+ },
718
+ skeleton: {
719
+ position: "absolute",
720
+ width: `${size || 160}px`,
721
+ height: `${size || 160}px`,
722
+ backgroundColor: colors.bgSkeleton,
723
+ borderRadius: radii.sm,
724
+ display: isLoading ? "block" : "none",
725
+ animation: "pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite"
726
+ }
727
+ });
728
+ var spinnerAnimationStyles = `
729
+ @keyframes luna-spin { to { transform: rotate(360deg); } }
730
+ @keyframes luna-bounce { 0%, 100% { transform: translateY(-25%); animation-timing-function: cubic-bezier(0.8,0,1,1); } 50% { transform: translateY(0); animation-timing-function: cubic-bezier(0,0,0.2,1); } }
731
+ @keyframes luna-pulse { 50% { opacity: .5; } }
732
+ `;
733
+ var spinnerSizeValues = {
734
+ sm: "1rem",
735
+ md: "1.5rem",
736
+ lg: "2rem"
737
+ };
738
+ var spinnerDotSizeValues = {
739
+ sm: "0.25rem",
740
+ md: "0.5rem",
741
+ lg: "0.75rem"
742
+ };
743
+ var spinnerBarSizeValues = {
744
+ sm: {
745
+ w: "0.25rem",
746
+ h: "1rem"
747
+ },
748
+ md: {
749
+ w: "0.25rem",
750
+ h: "1.5rem"
751
+ },
752
+ lg: {
753
+ w: "0.25rem",
754
+ h: "2rem"
755
+ }
756
+ };
757
+ var toastSeverityConfig = {
758
+ success: {
759
+ bg: "#f0fdf4",
760
+ border: "#bcf0da",
761
+ text: "#166534",
762
+ secondaryText: "#15803d",
763
+ icon: "✓"
764
+ },
765
+ info: {
766
+ bg: "#eff6ff",
767
+ border: "#bfdbfe",
768
+ text: "#1e40af",
769
+ secondaryText: "#1d4ed8",
770
+ icon: "ℹ"
771
+ },
772
+ warn: {
773
+ bg: "#fffbeb",
774
+ border: "#fef3c7",
775
+ text: "#92400e",
776
+ secondaryText: "#b45309",
777
+ icon: "⚠"
778
+ },
779
+ error: {
780
+ bg: "#fef2f2",
781
+ border: "#fecaca",
782
+ text: "#991b1b",
783
+ secondaryText: "#b91c1c",
784
+ icon: "✖"
785
+ }
786
+ };
787
+ var toastPositionStyles = (pos) => {
788
+ const base = {
789
+ position: "fixed",
790
+ zIndex: zIndices.panel,
791
+ margin: "1rem"
792
+ };
793
+ switch (pos) {
794
+ case "top-right": return {
795
+ ...base,
796
+ top: 0,
797
+ right: 0
798
+ };
799
+ case "top-left": return {
800
+ ...base,
801
+ top: 0,
802
+ left: 0
803
+ };
804
+ case "bottom-right": return {
805
+ ...base,
806
+ bottom: 0,
807
+ right: 0
808
+ };
809
+ case "bottom-left": return {
810
+ ...base,
811
+ bottom: 0,
812
+ left: 0
813
+ };
814
+ case "top-center": return {
815
+ ...base,
816
+ top: 0,
817
+ left: "50%",
818
+ transform: "translateX(-50%)"
819
+ };
820
+ case "bottom-center": return {
821
+ ...base,
822
+ bottom: 0,
823
+ left: "50%",
824
+ transform: "translateX(-50%)"
825
+ };
826
+ default: return {
827
+ ...base,
828
+ top: 0,
829
+ right: 0
830
+ };
831
+ }
832
+ };
833
+ var toastStyles = (styles, severity, position, isExiting, visible) => {
834
+ const config = toastSeverityConfig[severity || "info"];
835
+ return {
836
+ container: {
837
+ ...toastPositionStyles(position || "top-right"),
838
+ ...commonStyles.container,
839
+ minWidth: "300px",
840
+ maxWidth: "450px",
841
+ backgroundColor: config.bg,
842
+ border: `1px solid ${config.border}`,
843
+ padding: "1rem",
844
+ boxShadow: shadows.panel,
845
+ display: "flex",
846
+ alignItems: "flex-start",
847
+ gap: "0.75rem",
848
+ transition: transitions.normal,
849
+ opacity: isExiting || !visible ? 0 : 1,
850
+ transform: isExiting || !visible ? (position || "top-right").includes("top") ? "translateY(-20px)" : "translateY(20px)" : (position || "top-right").includes("center") ? "translateX(-50%)" : "none",
851
+ ...styles?.container
852
+ },
853
+ iconWrapper: {
854
+ display: "flex",
855
+ alignItems: "center",
856
+ justifyContent: "center",
857
+ width: "1.5rem",
858
+ height: "1.5rem",
859
+ borderRadius: radii.full,
860
+ backgroundColor: config.border,
861
+ color: config.text,
862
+ fontSize: fontSizes.sm,
863
+ fontWeight: fontWeights.bold,
864
+ flexShrink: 0
865
+ },
866
+ content: {
867
+ flex: 1,
868
+ display: "flex",
869
+ flexDirection: "column",
870
+ gap: "0.25rem",
871
+ ...styles?.content
872
+ },
873
+ summary: {
874
+ fontWeight: fontWeights.bold,
875
+ fontSize: fontSizes.sm,
876
+ color: config.text,
877
+ ...styles?.summary
878
+ },
879
+ detail: {
880
+ fontSize: fontSizes.sm,
881
+ color: config.secondaryText,
882
+ lineHeight: "1.25rem",
883
+ ...styles?.detail
884
+ },
885
+ closeButton: {
886
+ background: "none",
887
+ border: "none",
888
+ color: config.text,
889
+ cursor: "pointer",
890
+ fontSize: fontSizes.xl,
891
+ lineHeight: 1,
892
+ padding: "0.25rem",
893
+ opacity: .6,
894
+ transition: transitions.fast,
895
+ display: "flex",
896
+ alignItems: "center",
897
+ justifyContent: "center",
898
+ flexShrink: 0
899
+ }
900
+ };
901
+ };
902
+ var typedStyles = (style, cursorStyle, cursorOpacity) => ({
903
+ container: {
904
+ display: "inline-flex",
905
+ alignItems: "center",
906
+ gap: "0.25rem",
907
+ ...style
908
+ },
909
+ cursor: {
910
+ display: "inline-block",
911
+ marginLeft: "0.25rem",
912
+ width: "0.125rem",
913
+ height: "1.2em",
914
+ backgroundColor: "currentColor",
915
+ opacity: cursorOpacity ?? 1,
916
+ transition: transitions.fast,
917
+ ...cursorStyle
918
+ }
919
+ });
920
+ var whatsAppSizes = {
921
+ sm: {
922
+ button: 40,
923
+ icon: 20
924
+ },
925
+ md: {
926
+ button: 56,
927
+ icon: 28
928
+ },
929
+ lg: {
930
+ button: 64,
931
+ icon: 32
932
+ }
933
+ };
934
+ var cornerPositionStyles = (position) => {
935
+ switch (position) {
936
+ case "bottom-left": return {
937
+ bottom: "2rem",
938
+ left: "2rem"
939
+ };
940
+ case "top-right": return {
941
+ top: "2rem",
942
+ right: "2rem"
943
+ };
944
+ case "top-left": return {
945
+ top: "2rem",
946
+ left: "2rem"
947
+ };
948
+ default: return {
949
+ bottom: "2rem",
950
+ right: "2rem"
951
+ };
952
+ }
953
+ };
954
+ var whatsAppStyles = (styles, position, size, isHovered, zIndex) => {
955
+ const currentSize = whatsAppSizes[size || "md"];
956
+ const pos = position || "bottom-right";
957
+ return {
958
+ button: {
959
+ ...commonStyles.floatingButton,
960
+ position: "fixed",
961
+ ...cornerPositionStyles(pos),
962
+ width: `${currentSize.button}px`,
963
+ height: `${currentSize.button}px`,
964
+ backgroundColor: isHovered ? "#128C7E" : "#25D366",
965
+ color: colors.white,
966
+ zIndex: zIndex ?? 1e3,
967
+ transition: transitions.normal,
968
+ transform: isHovered ? "scale(1.1)" : "scale(1)",
969
+ ...styles?.button
970
+ },
971
+ tooltip: {
972
+ position: "fixed",
973
+ ...cornerPositionStyles(pos),
974
+ [pos.includes("bottom") ? "bottom" : "top"]: "5.5rem",
975
+ backgroundColor: colors.white,
976
+ color: colors.text,
977
+ padding: "0.5rem 1rem",
978
+ borderRadius: radii.md,
979
+ fontSize: fontSizes.sm,
980
+ fontWeight: fontWeights.semibold,
981
+ boxShadow: shadows.menu,
982
+ whiteSpace: "nowrap",
983
+ opacity: isHovered ? 1 : 0,
984
+ transform: isHovered ? "translateY(0)" : "translateY(10px)",
985
+ transition: transitions.fast,
986
+ pointerEvents: "none",
987
+ zIndex: (zIndex ?? 1e3) + 1,
988
+ ...styles?.tooltip
989
+ }
990
+ };
991
+ };
992
+ var scrollTopStyles = (styles, position, size, isVisible) => ({
993
+ ...commonStyles.floatingButton,
994
+ position: "fixed",
995
+ ...cornerPositionStyles(position || "bottom-right"),
996
+ width: `${size || 48}px`,
997
+ height: `${size || 48}px`,
998
+ backgroundColor: colors.primary,
999
+ color: colors.white,
1000
+ zIndex: 1e3,
1001
+ opacity: isVisible ? 1 : 0,
1002
+ transform: isVisible ? "translateY(0)" : "translateY(20px)",
1003
+ transition: transitions.normal,
1004
+ pointerEvents: isVisible ? "auto" : "none",
1005
+ ...styles
1006
+ });
1007
+ var modalSizeClasses = {
1008
+ sm: "max-w-sm",
1009
+ md: "max-w-md",
1010
+ lg: "max-w-lg",
1011
+ xl: "max-w-xl"
1012
+ };
1013
+ var modalOverlayClasses = (show, animation, className) => `fixed inset-0 z-60 flex items-center justify-center ${show ? "opacity-100 pointer-events-auto" : "opacity-0 pointer-events-none"} ${animation ? "transition-opacity duration-300" : ""} ${className}`.trim();
1014
+ var modalDialogClasses = (size, centered, dialogClassName) => `relative w-full ${modalSizeClasses[size]} mx-auto ${centered ? "flex items-center justify-center min-h-screen" : "mt-8"} ${dialogClassName}`.trim();
1015
+ var anchorBaseStyles = (variant, isHovered, size) => ({
1016
+ ...commonStyles.buttonBase,
1017
+ gap: "0",
1018
+ cursor: "pointer",
1019
+ textDecoration: variant === "none" ? isHovered ? "underline" : "none" : "none",
1020
+ border: variant === "none" ? "none" : "1px solid transparent",
1021
+ ...variant !== "none" ? sizeStyles[size] : {},
1022
+ display: variant === "none" ? "inline" : "inline-flex",
1023
+ borderRadius: variant === "none" ? "0" : radii.md
1024
+ });
1025
+ var accordionStyles = (isActive, styles) => ({
1026
+ container: {
1027
+ ...commonStyles.container,
1028
+ overflow: "hidden",
1029
+ marginBottom: "0.5rem",
1030
+ ...styles?.container
1031
+ },
1032
+ header: {
1033
+ ...commonStyles.header,
1034
+ transition: transitions.bgSlow,
1035
+ ...styles?.header
1036
+ },
1037
+ content: {
1038
+ maxHeight: isActive ? "1000px" : "0",
1039
+ opacity: isActive ? 1 : 0,
1040
+ overflow: "hidden",
1041
+ transition: transitions.normal,
1042
+ borderTop: isActive ? `1px solid ${colors.border}` : "none",
1043
+ ...styles?.content
1044
+ },
1045
+ innerContent: {
1046
+ padding: "1rem",
1047
+ fontSize: fontSizes.sm,
1048
+ color: colors.textSecondary
1049
+ },
1050
+ arrow: {
1051
+ ...commonStyles.chevron,
1052
+ transform: isActive ? "rotate(180deg)" : "rotate(0deg)",
1053
+ ...styles?.arrow
1054
+ }
1055
+ });
1056
+ var anchorVariantStyles = (isHovered) => ({
1057
+ none: { color: colors.primary },
1058
+ primary: {
1059
+ backgroundColor: isHovered ? "#1d4ed8" : "#2563eb",
1060
+ color: "#ffffff",
1061
+ border: "1px solid transparent"
1062
+ },
1063
+ secondary: {
1064
+ backgroundColor: isHovered ? "#374151" : "#4b5563",
1065
+ color: "#ffffff",
1066
+ border: "1px solid transparent"
1067
+ },
1068
+ outline: {
1069
+ backgroundColor: isHovered ? "#f9fafb" : "transparent",
1070
+ color: "#374151",
1071
+ border: `1px solid ${colors.borderInput}`
1072
+ }
1073
+ });
1074
+ //#endregion
5
1075
  //#region node_modules/react/cjs/react-jsx-runtime.production.js
6
1076
  /**
7
1077
  * @license React
@@ -40,301 +1110,328 @@ var require_react_jsx_runtime_production = /* @__PURE__ */ __commonJSMin(((expor
40
1110
  var import_jsx_runtime = (/* @__PURE__ */ __commonJSMin(((exports, module) => {
41
1111
  module.exports = require_react_jsx_runtime_production();
42
1112
  })))();
43
- var Button = ({ children, variant = "primary", size = "sm", onClick = () => void 0, disabled = false, className = "", containerClassName = "font-medium rounded-lg transition-colors focus:outline-none focus:ring-2", variantClassName = "bg-blue-600 text-white hover:bg-blue-700 focus:ring-blue-500", sizeClassName = "px-3 py-1.5 text-sm", style, ...props }) => {
1113
+ var Button = ({ children, variant = "primary", size = "sm", onClick, disabled = false, classNames = {}, styles = {}, className = "", style: extraStyle = {}, ...props }) => {
1114
+ const finalButtonStyle = {
1115
+ ...commonStyles.buttonBase,
1116
+ cursor: disabled ? "not-allowed" : "pointer",
1117
+ opacity: disabled ? .5 : 1,
1118
+ ...sizeStyles[size],
1119
+ ...styles.button,
1120
+ ...variantStyles[variant],
1121
+ ...extraStyle
1122
+ };
44
1123
  return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", {
45
- className: `
46
- ${containerClassName}
47
- ${{
48
- primary: "bg-blue-600 text-white hover:bg-blue-700 focus:ring-blue-500",
49
- secondary: "bg-gray-600 text-white hover:bg-gray-700 focus:ring-gray-500",
50
- outline: "border border-gray-300 text-gray-700 hover:bg-gray-50 focus:ring-gray-500",
51
- success: "bg-green-600 text-white hover:bg-green-700 focus:ring-green-500",
52
- danger: "bg-red-600 text-white hover:bg-red-700 focus:ring-red-500",
53
- warning: "bg-yellow-500 text-white hover:bg-yellow-600 focus:ring-yellow-500",
54
- info: "bg-cyan-600 text-white hover:bg-cyan-700 focus:ring-cyan-500",
55
- dark: "bg-gray-900 text-white hover:bg-gray-800 focus:ring-gray-900",
56
- light: "bg-gray-100 text-gray-900 hover:bg-gray-200 focus:ring-gray-300",
57
- link: "text-blue-600 hover:text-blue-800 hover:underline focus:outline-none focus:ring-2 focus:ring-blue-500"
58
- }[variant]}
59
- ${{
60
- sm: "px-3 py-1.5 text-sm",
61
- md: "px-4 py-2 text-base",
62
- lg: "px-6 py-3 text-lg"
63
- }[size]}
64
- ${disabled ? "opacity-50 cursor-not-allowed" : ""}
65
- ${className}
66
- `.trim(),
1124
+ className: [
1125
+ classNames.container || "",
1126
+ variantClasses[variant],
1127
+ sizeClasses[size],
1128
+ classNames.button || "",
1129
+ "luna-button",
1130
+ className
1131
+ ].filter(Boolean).join(" ").trim(),
67
1132
  onClick,
68
1133
  disabled,
69
- style,
1134
+ style: finalButtonStyle,
70
1135
  ...props,
71
1136
  children
72
1137
  });
73
1138
  };
74
1139
  //#endregion
75
1140
  //#region src/components/Card.tsx
76
- var Card = ({ children, title, className = "", containerClassName = "bg-white rounded-lg border border-gray-200", titleClassName = "text-lg font-semibold text-gray-900", padding = "md", shadow = "md", style }) => {
1141
+ var Card = ({ children, title, className = "", padding = "md", shadow = "md", styles = {} }) => {
1142
+ const uiStyles = cardStyles(padding, shadow, styles);
77
1143
  return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
78
- className: `
79
- ${containerClassName}
80
- ${{
81
- none: "",
82
- sm: "p-3",
83
- md: "p-4",
84
- lg: "p-6"
85
- }[padding]}
86
- ${{
87
- none: "",
88
- sm: "shadow-sm",
89
- md: "shadow-md",
90
- lg: "shadow-lg"
91
- }[shadow]}
92
- ${className}
93
- `.trim(),
94
- style,
1144
+ style: uiStyles.container,
1145
+ className: `luna-card ${className}`.trim(),
95
1146
  children: [title && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
96
- className: "mb-4",
1147
+ style: uiStyles.titleContainer,
97
1148
  children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("h3", {
98
- className: titleClassName,
1149
+ style: uiStyles.title,
99
1150
  children: title
100
1151
  })
101
- }), children]
1152
+ }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
1153
+ style: uiStyles.content,
1154
+ children
1155
+ })]
102
1156
  });
103
1157
  };
104
1158
  //#endregion
105
1159
  //#region src/components/Anchor.tsx
106
- var Anchor = ({ children = "Pablo Andrey Chacon Luna", variant = "none", size = "sm", href = "https://andreychaconresumereact.netlify.app/", className, containerClassName = variant === "none" ? "font-medium transition-colors focus:outline-none" : "font-medium rounded-lg transition-colors focus:outline-none focus:ring-2", variantClassName = "bg-blue-600 text-white hover:bg-blue-700", sizeClassName = "px-3 py-1.5 text-sm", target = "_blank", rel = "noopener noreferrer", style, ...props }) => {
1160
+ var Anchor = ({ children, variant = "none", size = "md", href, className = "", target, rel, style = {}, ...props }) => {
1161
+ const [isHovered, setIsHovered] = useState(false);
1162
+ const combinedClassName = `luna-anchor ${className}`.trim();
1163
+ const uiStyles = {
1164
+ base: anchorBaseStyles(variant, isHovered, size),
1165
+ variants: anchorVariantStyles(isHovered)
1166
+ };
107
1167
  return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("a", {
108
1168
  href,
109
1169
  target,
110
1170
  rel,
111
- className: `
112
- ${containerClassName}
113
- ${{
114
- none: "",
115
- primary: "bg-blue-600 text-white hover:bg-blue-700",
116
- secondary: "bg-gray-600 text-white hover:bg-gray-700",
117
- outline: "border border-gray-300 text-gray-700 hover:bg-gray-50"
118
- }[variant]}
119
- ${{
120
- sm: "px-3 py-1.5 text-sm",
121
- md: "px-4 py-2 text-base",
122
- lg: "px-6 py-3 text-lg"
123
- }[size]}
124
- ${variantClassName}
125
- ${sizeClassName}
126
- ${className}
127
- `.trim(),
128
- style,
1171
+ className: combinedClassName,
1172
+ style: {
1173
+ ...uiStyles.base,
1174
+ ...uiStyles.variants[variant],
1175
+ ...style
1176
+ },
1177
+ onMouseEnter: () => setIsHovered(true),
1178
+ onMouseLeave: () => setIsHovered(false),
129
1179
  ...props,
130
1180
  children
131
1181
  });
132
1182
  };
133
1183
  //#endregion
134
1184
  //#region src/components/Accordion.tsx
135
- var Accordion = ({ active, onClick, header, content, className = "", containerClassName = "border border-gray-200 rounded-lg overflow-hidden", headerClassName = "w-full px-4 py-3 text-left bg-gray-50 hover:bg-gray-100 focus:bg-gray-100 focus:outline-none transition-colors duration-200 flex justify-between items-center", contentClassName = "transition-all duration-300 ease-in-out", style }) => {
1185
+ var Accordion = ({ title, children, defaultActive = false, active: externalActive, onClick, className, styles = {} }) => {
1186
+ const combinedClassName = `luna-accordion ${className || ""}`.trim();
1187
+ const [internalActive, setInternalActive] = useState(defaultActive);
1188
+ const isActive = externalActive !== void 0 ? externalActive : internalActive;
1189
+ const handleToggle = () => {
1190
+ if (onClick) onClick();
1191
+ else setInternalActive(!internalActive);
1192
+ };
1193
+ const uiStyles = accordionStyles(isActive, styles);
136
1194
  return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
137
- className: `${containerClassName} ${className}`,
138
- style,
1195
+ style: uiStyles.container,
1196
+ className: combinedClassName,
139
1197
  children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("button", {
140
- onClick,
141
- className: headerClassName,
142
- "aria-expanded": active,
143
- children: [header, /* @__PURE__ */ (0, import_jsx_runtime.jsx)("svg", {
144
- className: `w-5 h-5 text-gray-500 transition-transform duration-200 ${active ? "transform rotate-180" : ""}`,
145
- fill: "none",
146
- stroke: "currentColor",
147
- viewBox: "0 0 24 24",
148
- children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", {
149
- strokeLinecap: "round",
150
- strokeLinejoin: "round",
151
- strokeWidth: 2,
152
- d: "M19 9l-7 7-7-7"
153
- })
1198
+ type: "button",
1199
+ style: uiStyles.header,
1200
+ onClick: handleToggle,
1201
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { children: title }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
1202
+ style: uiStyles.arrow,
1203
+ children: ""
154
1204
  })]
155
1205
  }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
156
- className: `${contentClassName} ${active ? "max-h-96 opacity-100" : "max-h-0 opacity-0"} overflow-hidden`,
1206
+ style: uiStyles.content,
157
1207
  children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
158
- className: `p-4 bg-white border-t border-gray-200 ${contentClassName}`,
159
- children: content
1208
+ style: uiStyles.innerContent,
1209
+ children
160
1210
  })
161
1211
  })]
162
1212
  });
163
1213
  };
164
1214
  //#endregion
165
1215
  //#region src/components/Spinner.tsx
166
- var Spinner = ({ className, containerClassName = "flex gap-1", dotClassName = "bg-blue-600 rounded-full animate-bounce", barClassName = "bg-blue-600 animate-pulse", size = "md", type = "circle", style }) => {
167
- const sizeClasses = {
168
- sm: "w-4 h-4",
169
- md: "w-6 h-6",
170
- lg: "w-8 h-8"
171
- };
172
- const dotSizeClasses = {
173
- sm: "w-1 h-1",
174
- md: "w-2 h-2",
175
- lg: "w-3 h-3"
176
- };
177
- const barSizeClasses = {
178
- sm: "w-1 h-4",
179
- md: "w-1 h-6",
180
- lg: "w-1 h-8"
181
- };
182
- if (type === "dots") return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
183
- role: "status",
184
- className: `${containerClassName} ${className || ""}`,
185
- children: [
186
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
187
- className: "sr-only",
188
- children: "Loading..."
189
- }),
190
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
191
- className: `${dotSizeClasses[size]} ${dotClassName}`,
192
- style: { animationDelay: "0ms" }
193
- }),
194
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
195
- className: `${dotSizeClasses[size]} ${dotClassName}`,
196
- style: { animationDelay: "150ms" }
197
- }),
198
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
199
- className: `${dotSizeClasses[size]} ${dotClassName}`,
200
- style: { animationDelay: "300ms" }
201
- })
202
- ]
203
- });
1216
+ var Spinner = ({ className = "", size = "md", type = "circle", color = "#2563eb", style = {} }) => {
1217
+ const combinedClassName = `luna-spinner ${className}`.trim();
1218
+ const currentSize = spinnerSizeValues[size];
1219
+ const currentDotSize = spinnerDotSizeValues[size];
1220
+ const currentBarSize = spinnerBarSizeValues[size];
1221
+ if (type === "dots") {
1222
+ const dotStyle = {
1223
+ width: currentDotSize,
1224
+ height: currentDotSize,
1225
+ backgroundColor: color,
1226
+ borderRadius: "9999px",
1227
+ animation: "luna-bounce 1s infinite"
1228
+ };
1229
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
1230
+ role: "status",
1231
+ style: {
1232
+ display: "flex",
1233
+ gap: "0.25rem",
1234
+ ...style
1235
+ },
1236
+ className: combinedClassName,
1237
+ children: [
1238
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("style", { children: spinnerAnimationStyles }),
1239
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: {
1240
+ ...dotStyle,
1241
+ animationDelay: "0ms"
1242
+ } }),
1243
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: {
1244
+ ...dotStyle,
1245
+ animationDelay: "150ms"
1246
+ } }),
1247
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: {
1248
+ ...dotStyle,
1249
+ animationDelay: "300ms"
1250
+ } })
1251
+ ]
1252
+ });
1253
+ }
204
1254
  if (type === "pulse") return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
205
1255
  role: "status",
206
- className: `${sizeClasses[size]} ${className || ""}`,
207
- children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
208
- className: "sr-only",
209
- children: "Loading..."
210
- }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: `${sizeClasses[size]} ${dotClassName}` })]
1256
+ style: { ...style },
1257
+ className: combinedClassName,
1258
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("style", { children: spinnerAnimationStyles }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: {
1259
+ width: currentSize,
1260
+ height: currentSize,
1261
+ backgroundColor: color,
1262
+ borderRadius: "9999px",
1263
+ animation: "luna-pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite"
1264
+ } })]
211
1265
  });
212
- if (type === "bars") return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
213
- role: "status",
214
- className: `flex gap-1 items-center ${containerClassName} ${className || ""}`,
215
- children: [
216
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
217
- className: "sr-only",
218
- children: "Loading..."
219
- }),
220
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
221
- className: `${barSizeClasses[size]} ${barClassName}`,
222
- style: { animationDelay: "0ms" }
223
- }),
224
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
225
- className: `${barSizeClasses[size]} ${barClassName}`,
226
- style: { animationDelay: "200ms" }
227
- }),
228
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
229
- className: `${barSizeClasses[size]} ${barClassName}`,
230
- style: { animationDelay: "400ms" }
231
- }),
232
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
233
- className: `${barSizeClasses[size]} ${barClassName}`,
234
- style: { animationDelay: "600ms" }
235
- })
236
- ]
237
- });
238
- return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
1266
+ if (type === "bars") {
1267
+ const barStyle = {
1268
+ width: currentBarSize.w,
1269
+ height: currentBarSize.h,
1270
+ backgroundColor: color,
1271
+ animation: "luna-pulse 1.2s cubic-bezier(0.4, 0, 0.6, 1) infinite"
1272
+ };
1273
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
1274
+ role: "status",
1275
+ style: {
1276
+ display: "flex",
1277
+ gap: "0.25rem",
1278
+ alignItems: "center",
1279
+ ...style
1280
+ },
1281
+ className: combinedClassName,
1282
+ children: [
1283
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("style", { children: spinnerAnimationStyles }),
1284
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: {
1285
+ ...barStyle,
1286
+ animationDelay: "0ms"
1287
+ } }),
1288
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: {
1289
+ ...barStyle,
1290
+ animationDelay: "200ms"
1291
+ } }),
1292
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: {
1293
+ ...barStyle,
1294
+ animationDelay: "400ms"
1295
+ } }),
1296
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: {
1297
+ ...barStyle,
1298
+ animationDelay: "600ms"
1299
+ } })
1300
+ ]
1301
+ });
1302
+ }
1303
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
239
1304
  role: "status",
240
- className: `inline-block animate-spin rounded-full border-2 border-gray-300 border-t-blue-600 ${sizeClasses[size]} ${className || ""}`,
241
- style,
242
- children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
243
- className: "sr-only",
1305
+ className: combinedClassName,
1306
+ style: {
1307
+ display: "inline-block",
1308
+ width: currentSize,
1309
+ height: currentSize,
1310
+ borderRadius: "9999px",
1311
+ border: "2px solid #e5e7eb",
1312
+ borderTopColor: color,
1313
+ animation: "luna-spin 1s linear infinite",
1314
+ ...style
1315
+ },
1316
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("style", { children: spinnerAnimationStyles }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
1317
+ style: {
1318
+ position: "absolute",
1319
+ width: "1px",
1320
+ height: "1px",
1321
+ padding: 0,
1322
+ margin: "-1px",
1323
+ overflow: "hidden",
1324
+ clip: "rect(0, 0, 0, 0)",
1325
+ whiteSpace: "nowrap",
1326
+ borderWidth: 0
1327
+ },
244
1328
  children: "Loading..."
245
- })
1329
+ })]
246
1330
  });
247
1331
  };
248
1332
  //#endregion
249
1333
  //#region src/components/DropDown.tsx
250
- var DropDown = ({ toggle, options, selected, onChange, className = "", containerClassName = "relative inline-block text-left", dropdownClassName = "absolute z-50 mt-2 w-48 rounded-md bg-white shadow-lg ring-1 ring-black ring-opacity-5 focus:outline-none", optionsContainerClassName = "py-1 flex flex-col", optionClassName = "block w-full px-4 py-2 text-left text-sm text-gray-700 hover:bg-gray-100 hover:text-gray-900 focus:bg-gray-100 focus:text-gray-900", style }) => {
1334
+ var DropDown = ({ options, value, onChange, placeholder = "Select an option", toggle, classNames = {}, styles = {}, disabled = false, className }) => {
1335
+ const finalClassNames = {
1336
+ container: "luna-dropdown",
1337
+ trigger: "luna-dropdown-trigger",
1338
+ panel: "luna-dropdown-panel",
1339
+ option: "luna-dropdown-option",
1340
+ ...classNames
1341
+ };
251
1342
  const [isOpen, setIsOpen] = useState(false);
1343
+ const [hoverIndex, setHoverIndex] = useState(null);
1344
+ const containerRef = useRef(null);
1345
+ useEffect(() => {
1346
+ const handleClickOutside = (event) => {
1347
+ if (containerRef.current && !containerRef.current.contains(event.target)) setIsOpen(false);
1348
+ };
1349
+ document.addEventListener("mousedown", handleClickOutside);
1350
+ return () => document.removeEventListener("mousedown", handleClickOutside);
1351
+ }, []);
252
1352
  const handleToggle = () => {
1353
+ if (disabled) return;
253
1354
  setIsOpen(!isOpen);
254
1355
  };
255
- const handleOptionClick = (option) => {
256
- onChange(option);
1356
+ const handleOptionClick = (optionValue) => {
1357
+ onChange(optionValue);
257
1358
  setIsOpen(false);
258
1359
  };
1360
+ const getDisplayLabel = () => {
1361
+ if (value === void 0 || value === null || value === "") return placeholder;
1362
+ const found = options.find((opt) => {
1363
+ if (typeof opt === "object") return opt.value === value;
1364
+ return opt === value;
1365
+ });
1366
+ if (found && typeof found === "object") return found.label;
1367
+ return found || value;
1368
+ };
1369
+ const uiStyles = dropDownStyles(styles, disabled, isOpen, hoverIndex, value);
259
1370
  return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
260
- className: `${containerClassName} ${className}`,
261
- style,
262
- children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
1371
+ ref: containerRef,
1372
+ style: uiStyles.container,
1373
+ className: `${finalClassNames.container} ${className || ""}`.trim(),
1374
+ children: [toggle ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
263
1375
  onClick: handleToggle,
264
- className: "cursor-pointer",
1376
+ style: { display: "inline-block" },
265
1377
  children: toggle
266
- }), isOpen && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
267
- className: dropdownClassName,
268
- children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
269
- className: optionsContainerClassName,
270
- children: options.map((option, index) => {
271
- const isOptionObject = typeof option === "object" && option !== null && "value" in option;
272
- const optionValue = isOptionObject ? option.value : option;
273
- return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", {
274
- onClick: () => handleOptionClick(optionValue),
275
- className: optionClassName,
276
- children: isOptionObject ? option.label : option
277
- }, index);
278
- })
1378
+ }) : /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("button", {
1379
+ type: "button",
1380
+ style: uiStyles.trigger,
1381
+ className: finalClassNames.trigger,
1382
+ onClick: handleToggle,
1383
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { children: getDisplayLabel() }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
1384
+ style: uiStyles.arrow,
1385
+ children: ""
1386
+ })]
1387
+ }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
1388
+ style: uiStyles.panel,
1389
+ className: finalClassNames.panel,
1390
+ children: options.map((option, index) => {
1391
+ const isObj = typeof option === "object" && option !== null && "value" in option;
1392
+ const optValue = isObj ? option.value : option;
1393
+ const optLabel = isObj ? option.label : option;
1394
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", {
1395
+ type: "button",
1396
+ style: uiStyles.option(index),
1397
+ className: finalClassNames.option,
1398
+ onMouseEnter: () => setHoverIndex(index),
1399
+ onMouseLeave: () => setHoverIndex(null),
1400
+ onClick: () => handleOptionClick(optValue),
1401
+ children: optLabel
1402
+ }, index);
279
1403
  })
280
1404
  })]
281
1405
  });
282
1406
  };
283
1407
  //#endregion
284
1408
  //#region src/components/ProgressBar.tsx
285
- var ProgressBar = ({ progress, max, min, "aria-label": ariaLabel, className, style, containerClassName = "w-full bg-gray-200 rounded-full h-4 overflow-hidden", barClassName = "h-full rounded-full transition-all duration-300 flex items-center justify-center text-xs font-medium", variant = "primary" }) => {
286
- const currentVariant = {
287
- primary: {
288
- bg: "bg-blue-600",
289
- text: "text-white",
290
- containerBg: "bg-gray-200"
291
- },
292
- success: {
293
- bg: "bg-green-600",
294
- text: "text-white",
295
- containerBg: "bg-gray-200"
296
- },
297
- warning: {
298
- bg: "bg-yellow-500",
299
- text: "text-gray-900",
300
- containerBg: "bg-gray-200"
301
- },
302
- danger: {
303
- bg: "bg-red-600",
304
- text: "text-white",
305
- containerBg: "bg-gray-200"
306
- },
307
- dark: {
308
- bg: "bg-gray-800",
309
- text: "text-white",
310
- containerBg: "bg-gray-300"
311
- },
312
- light: {
313
- bg: "bg-gray-100",
314
- text: "text-gray-900",
315
- containerBg: "bg-gray-300"
316
- }
317
- }[variant];
1409
+ var ProgressBar = ({ progress, max = 100, min = 0, "aria-label": ariaLabel = "Progress", variant = "primary", showPercentage = true, className = "", styles = {} }) => {
1410
+ const combinedClassName = `luna-progress ${className}`.trim();
1411
+ const clampedProgress = Math.max(min, Math.min(max, progress));
1412
+ const percentage = (clampedProgress - min) / (max - min) * 100;
1413
+ const uiStyles = progressBarStyles(styles, percentage, variant);
318
1414
  return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
319
- className: containerClassName,
320
- style,
1415
+ style: uiStyles.container,
1416
+ className: combinedClassName,
321
1417
  children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
322
1418
  role: "progressbar",
323
- className: `${currentVariant.bg} ${barClassName} ${currentVariant.text}`,
324
- "aria-valuenow": progress,
1419
+ style: uiStyles.bar,
1420
+ "aria-valuenow": clampedProgress,
325
1421
  "aria-valuemin": min,
326
1422
  "aria-valuemax": max,
327
- style: {
328
- width: `${progress}%`,
329
- ...className
330
- },
331
- children: progress > 10 && `${progress}%`
1423
+ "aria-label": ariaLabel,
1424
+ children: showPercentage && percentage >= 10 && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", {
1425
+ style: uiStyles.text,
1426
+ children: [Math.round(percentage), "%"]
1427
+ })
332
1428
  })
333
1429
  });
334
1430
  };
335
1431
  //#endregion
336
1432
  //#region src/components/Typed.tsx
337
- var Typed = ({ strings, typeSpeed = 50, backSpeed = 30, backDelay = 500, startDelay = 0, loop = true, showCursor = true, className = "", containerClassName = "inline-block", typedClassName = "typed", cursorClassName = "typed-cursor ml-1 inline-block w-0.5 h-5 bg-current", style = {} }) => {
1433
+ var Typed = ({ strings, typeSpeed = 50, backSpeed = 30, backDelay = 500, startDelay = 0, loop = true, showCursor = true, className = "", style = {}, cursorStyle = {} }) => {
1434
+ const combinedClassName = `luna-typed ${className}`.trim();
338
1435
  const [currentStringIndex, setCurrentStringIndex] = useState(0);
339
1436
  const [currentText, setCurrentText] = useState("");
340
1437
  const [isDeleting, setIsDeleting] = useState(false);
@@ -378,30 +1475,26 @@ var Typed = ({ strings, typeSpeed = 50, backSpeed = 30, backDelay = 500, startDe
378
1475
  isPaused
379
1476
  ]);
380
1477
  useEffect(() => {
1478
+ if (!showCursor) return;
381
1479
  const fadeTimer = setInterval(() => {
382
- setCursorOpacity((prev) => {
383
- if (prev === 1) return 0;
384
- return 1;
385
- });
386
- }, 750);
1480
+ setCursorOpacity((prev) => prev === 1 ? 0 : 1);
1481
+ }, 500);
387
1482
  return () => clearInterval(fadeTimer);
388
- }, []);
1483
+ }, [showCursor]);
1484
+ const uiStyles = typedStyles(style, cursorStyle, cursorOpacity);
389
1485
  return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", {
390
- className: `${containerClassName} ${className}`,
391
- style,
392
- children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
393
- className: typedClassName,
394
- children: currentText
395
- }), showCursor && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
396
- className: cursorClassName,
1486
+ className: combinedClassName,
1487
+ style: uiStyles.container,
1488
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { children: currentText }), showCursor && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
397
1489
  "aria-hidden": "true",
398
- style: { opacity: cursorOpacity }
1490
+ style: uiStyles.cursor
399
1491
  })]
400
1492
  });
401
1493
  };
402
1494
  //#endregion
403
1495
  //#region src/components/Preloader.tsx
404
- var Preloader = ({ isLoading: externalLoading, duration = 1e3, backgroundColor, accentColor, size = 90, borderWidth = 6, className = "", spinnerClassName = "", zIndex = 999999, onComplete, style }) => {
1496
+ var Preloader = ({ isLoading: externalLoading, duration = 2e3, backgroundColor = "rgba(255, 255, 255, 0.9)", accentColor = "#2563eb", size = 60, borderWidth = 4, className = "", spinnerClassName = "", zIndex = 99999, onComplete, styles = {} }) => {
1497
+ const combinedClassName = `luna-preloader ${className}`.trim();
405
1498
  const [internalLoading, setInternalLoading] = useState(true);
406
1499
  const isLoading = externalLoading !== void 0 ? externalLoading : internalLoading;
407
1500
  useEffect(() => {
@@ -417,225 +1510,97 @@ var Preloader = ({ isLoading: externalLoading, duration = 1e3, backgroundColor,
417
1510
  externalLoading,
418
1511
  onComplete
419
1512
  ]);
420
- useEffect(() => {
421
- if (externalLoading === true) {
422
- const timer = setTimeout(() => {
423
- onComplete?.();
424
- }, duration);
425
- return () => clearTimeout(timer);
426
- }
427
- }, [
428
- externalLoading,
429
- duration,
430
- onComplete
431
- ]);
432
- const preloaderStyle = {
433
- position: "fixed",
434
- inset: 0,
435
- zIndex,
436
- overflow: "hidden",
437
- background: backgroundColor || "var(--background-color, #00000018)",
438
- transition: "all 0.6s ease-out",
439
- display: isLoading ? "block" : "none"
440
- };
441
- const spinnerStyle = {
442
- position: "fixed",
443
- top: "50%",
444
- left: "50%",
445
- transform: "translate(-50%, -50%)",
446
- border: `${borderWidth}px solid #ffffff`,
447
- borderColor: `${accentColor || "var(--accent-color, #007bff)"} transparent transparent transparent`,
448
- borderRadius: "50%",
449
- width: `${size}px`,
450
- height: `${size}px`,
451
- animation: "animate-preloader 1.5s linear infinite"
452
- };
453
- return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
454
- className: `preloader-overlay ${className}`,
455
- style: {
456
- ...preloaderStyle,
457
- ...style
458
- },
459
- children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
460
- className: `preloader-spinner ${spinnerClassName}`,
461
- style: spinnerStyle
1513
+ if (!isLoading) return null;
1514
+ const uiStyles = preloaderStyles(zIndex, backgroundColor, size, borderWidth, styles);
1515
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
1516
+ style: uiStyles.overlay,
1517
+ className: combinedClassName,
1518
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Spinner, {
1519
+ className: spinnerClassName,
1520
+ color: accentColor,
1521
+ style: uiStyles.spinner
462
1522
  })
463
- }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("style", { children: `
464
- @keyframes animate-preloader {
465
- 0% {
466
- transform: translate(-50%, -50%) rotate(0deg);
467
- }
468
- 100% {
469
- transform: translate(-50%, -50%) rotate(360deg);
470
- }
471
- }
472
- ` })] });
1523
+ });
473
1524
  };
474
1525
  //#endregion
475
1526
  //#region src/components/ScrollTop.tsx
476
- var ScrollTop = ({ threshold = 100, className = "", children, position = "bottom-right", size = "md", shape = "circle", showInitially = false, scrollBehavior = "smooth", style, onClick, onVisibilityChange, targetElement, scrollPercentage }) => {
477
- const [isVisible, setIsVisible] = useState(showInitially);
1527
+ var ScrollTop = ({ threshold = 100, className = "", children, position = "bottom-right", size = 48, scrollBehavior = "smooth", styles = {} }) => {
1528
+ const combinedClassName = `luna-scrolltop ${className}`.trim();
1529
+ const [isVisible, setIsVisible] = useState(false);
478
1530
  useEffect(() => {
479
1531
  const toggleVisibility = () => {
480
- let shouldBeVisible = false;
481
- if (scrollPercentage !== void 0) {
482
- const maxScroll = document.documentElement.scrollHeight - window.innerHeight;
483
- shouldBeVisible = window.scrollY / maxScroll * 100 >= scrollPercentage;
484
- } else if (targetElement) {
485
- const element = document.querySelector(targetElement);
486
- if (element) {
487
- const rect = element.getBoundingClientRect();
488
- shouldBeVisible = rect.top < window.innerHeight && rect.bottom > 0;
489
- } else shouldBeVisible = window.scrollY > threshold;
490
- } else shouldBeVisible = window.scrollY > threshold;
491
- setIsVisible(shouldBeVisible);
492
- onVisibilityChange?.(shouldBeVisible);
1532
+ if (window.scrollY > threshold) setIsVisible(true);
1533
+ else setIsVisible(false);
493
1534
  };
494
1535
  window.addEventListener("scroll", toggleVisibility, { passive: true });
495
- toggleVisibility();
496
- return () => {
497
- window.removeEventListener("scroll", toggleVisibility);
498
- };
499
- }, [
500
- threshold,
501
- onVisibilityChange,
502
- targetElement,
503
- scrollPercentage
504
- ]);
505
- const scrollToTop = () => {
1536
+ return () => window.removeEventListener("scroll", toggleVisibility);
1537
+ }, [threshold]);
1538
+ const handleScrollToTop = () => {
506
1539
  window.scrollTo({
507
1540
  top: 0,
508
1541
  behavior: scrollBehavior
509
1542
  });
510
- onClick?.();
511
- };
512
- const handleClick = (e) => {
513
- e.preventDefault();
514
- scrollToTop();
515
1543
  };
516
1544
  return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", {
517
- className: `
518
- ${{
519
- "bottom-right": "fixed bottom-8 right-8",
520
- "bottom-left": "fixed bottom-8 left-8",
521
- "bottom-center": "fixed bottom-8 left-1/2 transform -translate-x-1/2",
522
- "top-right": "fixed top-8 right-8",
523
- "top-left": "fixed top-8 left-8",
524
- "top-center": "fixed top-8 left-1/2 transform -translate-x-1/2"
525
- }[position]}
526
- ${{
527
- sm: "w-8 h-8 text-sm",
528
- md: "w-12 h-12 text-base",
529
- lg: "w-16 h-16 text-lg"
530
- }[size]}
531
- ${{
532
- circle: "rounded-full",
533
- square: "rounded-none",
534
- rounded: "rounded-lg"
535
- }[shape]}
536
- ${className}
537
- flex items-center justify-center
538
- bg-blue-600 hover:bg-blue-700
539
- text-white
540
- shadow-lg hover:shadow-xl
541
- transition-all duration-300 ease-in-out
542
- cursor-pointer
543
- z-50
544
- ${isVisible ? "opacity-100 translate-y-0" : "opacity-0 translate-y-4 pointer-events-none"}
545
- `,
546
- onClick: handleClick,
547
- style,
1545
+ type: "button",
1546
+ style: scrollTopStyles(styles, position, size, isVisible),
1547
+ className: combinedClassName,
1548
+ onClick: handleScrollToTop,
548
1549
  "aria-label": "Scroll to top",
549
- title: "Scroll to top",
550
1550
  children: children || /* @__PURE__ */ (0, import_jsx_runtime.jsx)("svg", {
551
- className: "w-4 h-4",
1551
+ width: "20",
1552
+ height: "20",
1553
+ viewBox: "0 0 24 24",
552
1554
  fill: "none",
553
1555
  stroke: "currentColor",
554
- viewBox: "0 0 24 24",
555
- children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", {
556
- strokeLinecap: "round",
557
- strokeLinejoin: "round",
558
- strokeWidth: 2,
559
- d: "M5 10l7-7m0 0l7 7m-7-7v18"
560
- })
1556
+ strokeWidth: "2.5",
1557
+ strokeLinecap: "round",
1558
+ strokeLinejoin: "round",
1559
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M18 15l-6-6-6 6" })
561
1560
  })
562
1561
  });
563
1562
  };
564
1563
  //#endregion
565
1564
  //#region src/components/WhatsApp.tsx
566
- var WhatsApp = ({ phone = "", message = "¡Hola! Me gustaría obtener más información.", position = "bottom-right", size = "md", showTooltip = true, tooltipText = "¿En qué podemos ayudarte?", className = "", tooltipClassName = "", style, onClick, zIndex = 50, openInNewTab = true }) => {
1565
+ var WhatsApp = ({ phone = "", message = "Hi!", position = "bottom-right", size = "md", showTooltip = true, tooltipText = "Need help?", className = "", styles = {}, onClick, zIndex = 1e3 }) => {
1566
+ const combinedClassName = `luna-whatsapp ${className}`.trim();
567
1567
  const [isHovered, setIsHovered] = useState(false);
568
1568
  if (!phone) return null;
569
1569
  const handleWhatsAppClick = () => {
570
1570
  const whatsappUrl = `https://wa.me/${phone.replace(/[^\d]/g, "")}?text=${encodeURIComponent(message)}`;
571
- if (openInNewTab) window.open(whatsappUrl, "_blank");
572
- else window.location.href = whatsappUrl;
1571
+ window.open(whatsappUrl, "_blank");
573
1572
  onClick?.();
574
1573
  };
575
- const positionClasses = {
576
- "bottom-right": "bottom-6 right-6",
577
- "bottom-left": "bottom-6 left-6",
578
- "bottom-center": "bottom-6 left-1/2 transform -translate-x-1/2",
579
- "top-right": "top-6 right-6",
580
- "top-left": "top-6 left-6",
581
- "top-center": "top-6 left-1/2 transform -translate-x-1/2"
582
- };
583
- const sizeClasses = {
584
- sm: "w-10 h-10",
585
- md: "w-14 h-14",
586
- lg: "w-16 h-16"
587
- };
588
- const iconSizes = {
589
- sm: 20,
590
- md: 32,
591
- lg: 40
592
- };
1574
+ const uiStyles = whatsAppStyles(styles, position, size, isHovered, zIndex);
1575
+ const currentSize = whatsAppSizes[size];
593
1576
  return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", {
594
- className: `
595
- fixed ${positionClasses[position]}
596
- ${sizeClasses[size]}
597
- bg-[#25D366] hover:bg-[#128C7E]
598
- text-white rounded-full shadow-2xl
599
- flex items-center justify-center
600
- transition-all duration-300 hover:scale-110
601
- z-${zIndex}
602
- group
603
- ${className}
604
- `,
1577
+ type: "button",
1578
+ style: uiStyles.button,
1579
+ className: combinedClassName,
605
1580
  onClick: handleWhatsAppClick,
606
1581
  onMouseEnter: () => setIsHovered(true),
607
1582
  onMouseLeave: () => setIsHovered(false),
608
- style,
609
- "aria-label": "Chatear por WhatsApp",
610
- title: "Chatear por WhatsApp",
1583
+ "aria-label": "WhatsApp",
611
1584
  children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("svg", {
612
- width: iconSizes[size],
613
- height: iconSizes[size],
1585
+ width: currentSize.icon,
1586
+ height: currentSize.icon,
614
1587
  viewBox: "0 0 24 24",
615
1588
  fill: "none",
616
1589
  stroke: "currentColor",
617
- strokeWidth: 2,
1590
+ strokeWidth: "2.5",
618
1591
  strokeLinecap: "round",
619
1592
  strokeLinejoin: "round",
620
1593
  children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M21 11.5a8.38 8.38 0 0 1-.9 3.8 8.5 8.5 0 0 1-7.6 4.7 8.38 8.38 0 0 1-3.8-.9L3 21l1.9-5.7a8.38 8.38 0 0 1-.9-3.8 8.5 8.5 0 0 1 4.7-7.6 8.38 8.38 0 0 1 3.8-.9h.5a8.48 8.48 0 0 1 8 8v.5z" })
621
1594
  })
622
1595
  }), showTooltip && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
623
- className: `
624
- fixed ${positionClasses[position].replace("6", "20").replace("bottom-6", "bottom-20").replace("top-6", "top-20")}
625
- bg-white text-gray-800 px-3 py-1 rounded-md text-sm font-semibold
626
- shadow-md whitespace-nowrap pointer-events-none
627
- transition-opacity duration-300
628
- ${isHovered ? "opacity-100" : "opacity-0"}
629
- ${position.includes("right") ? "right-20" : position.includes("left") ? "left-20" : "left-1/2 transform -translate-x-1/2"}
630
- ${tooltipClassName}
631
- `,
632
- style: { [position.includes("bottom") ? "bottom" : "top"]: position.includes("bottom") ? "5.5rem" : "5.5rem" },
1596
+ style: uiStyles.tooltip,
633
1597
  children: tooltipText
634
1598
  })] });
635
1599
  };
636
1600
  //#endregion
637
1601
  //#region src/components/Modal.tsx
638
- var Modal = ({ show, onHide, size = "md", centered = false, backdrop = true, backdropClose = true, keyboard = true, animation = true, className = "", dialogClassName = "", contentClassName = "", headerClassName = "", bodyClassName = "", footerClassName = "", title, header, children, footer, closeButton = true, style }) => {
1602
+ var Modal = ({ show, onHide, size = "md", centered = false, backdrop = true, backdropClose = true, keyboard = true, animation = true, className = "", dialogClassName = "luna-modal-dialog", contentClassName = "luna-modal-content", headerClassName = "luna-modal-header", bodyClassName = "luna-modal-body", footerClassName = "luna-modal-footer", title, header, children, footer, closeButton = true, style }) => {
1603
+ const combinedClassName = `luna-modal ${className}`.trim();
639
1604
  const modalRef = useRef(null);
640
1605
  const previousActiveElement = useRef(null);
641
1606
  useEffect(() => {
@@ -669,23 +1634,8 @@ var Modal = ({ show, onHide, size = "md", centered = false, backdrop = true, bac
669
1634
  document.body.style.overflow = "";
670
1635
  };
671
1636
  }, [show]);
672
- const sizeClasses = {
673
- sm: "max-w-sm",
674
- md: "max-w-md",
675
- lg: "max-w-lg",
676
- xl: "max-w-xl"
677
- };
678
- const modalClasses = `
679
- fixed inset-0 z-60 flex items-center justify-center
680
- ${show ? "opacity-100 pointer-events-auto" : "opacity-0 pointer-events-none"}
681
- ${animation ? "transition-opacity duration-300" : ""}
682
- ${className}
683
- `.trim();
684
- const dialogClasses = `
685
- relative w-full ${sizeClasses[size]} mx-auto
686
- ${centered ? "flex items-center justify-center min-h-screen" : "mt-8"}
687
- ${dialogClassName}
688
- `.trim();
1637
+ const modalClasses = modalOverlayClasses(show, animation, combinedClassName);
1638
+ const dialogClasses = modalDialogClasses(size, centered, dialogClassName);
689
1639
  if (!show) return null;
690
1640
  return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
691
1641
  ref: modalRef,
@@ -744,63 +1694,703 @@ var Modal = ({ show, onHide, size = "md", centered = false, backdrop = true, bac
744
1694
  };
745
1695
  //#endregion
746
1696
  //#region src/components/Input.tsx
747
- var Input = ({ children, variant = "none", type = "text", inputSize = "md", placeholder, value, onChange, onFocus, onBlur, disabled = false, required = false, readOnly = false, className = "", containerClassName = "relative inline-block", inputClassName = "border border-gray-300 rounded-md shadow-sm focus:ring-blue-500 focus:border-blue-500", variantClassName = "", sizeClassName = "", style, id, "aria-label": ariaLabel, "aria-labelledby": ariaLabelledby, ...props }) => {
748
- const baseClasses = containerClassName;
749
- const variantClasses = {
750
- none: "",
751
- primary: "bg-blue-600 text-white border-blue-600 focus:ring-blue-500 focus:border-blue-500",
752
- secondary: "bg-gray-600 text-white border-gray-600 focus:ring-gray-500 focus:border-gray-500",
753
- outline: "border-gray-300 text-gray-700 bg-white focus:ring-blue-500 focus:border-blue-500",
754
- danger: "bg-red-600 text-white border-red-600 focus:ring-red-500 focus:border-red-500",
755
- success: "bg-green-600 text-white border-green-600 focus:ring-green-500 focus:border-green-500"
1697
+ var Input = ({ children, variant = "none", type = "text", inputSize = "md", placeholder, value: controlledValue, onChange, onFocus, onBlur, disabled = false, required = false, readOnly = false, id, name, mask, maskChar = "_", useCurrency = false, currency = "USD", locale = "en-US", minFractionDigits = 0, maxFractionDigits = 2, "aria-label": ariaLabel, "aria-labelledby": ariaLabelledby, classNames = {}, styles = {}, className: extraClassName = "", style: extraStyle = {}, ...props }) => {
1698
+ const inputId = id || name;
1699
+ const finalClassNames = {
1700
+ container: "luna-input",
1701
+ input: "luna-input-field",
1702
+ label: "luna-input-label",
1703
+ ...classNames
1704
+ };
1705
+ const [internalValue, setInternalValue] = useState(controlledValue || "");
1706
+ useEffect(() => {
1707
+ if (controlledValue !== void 0) setInternalValue(controlledValue);
1708
+ }, [controlledValue]);
1709
+ const formatCurrency = useCallback((val) => {
1710
+ const cleanVal = val.replace(/[^0-9.]/g, "");
1711
+ if (!cleanVal) return "";
1712
+ const numericVal = parseFloat(cleanVal);
1713
+ if (isNaN(numericVal)) return "";
1714
+ return new Intl.NumberFormat(locale, {
1715
+ style: useCurrency ? "currency" : "decimal",
1716
+ currency: useCurrency ? currency : void 0,
1717
+ minimumFractionDigits: minFractionDigits,
1718
+ maximumFractionDigits: maxFractionDigits
1719
+ }).format(numericVal);
1720
+ }, [
1721
+ locale,
1722
+ useCurrency,
1723
+ currency,
1724
+ minFractionDigits,
1725
+ maxFractionDigits
1726
+ ]);
1727
+ const formatWithMask = useCallback((val, maskStr) => {
1728
+ if (!maskStr) return val;
1729
+ let formatted = "";
1730
+ let rawIdx = 0;
1731
+ const rawVal = val.replace(/[^a-zA-Z0-9]/g, "");
1732
+ for (let i = 0; i < maskStr.length; i++) {
1733
+ const m = maskStr[i];
1734
+ if (rawIdx >= rawVal.length) break;
1735
+ if (m === "9") if (/\d/.test(rawVal[rawIdx])) {
1736
+ formatted += rawVal[rawIdx];
1737
+ rawIdx++;
1738
+ } else {
1739
+ rawIdx++;
1740
+ i--;
1741
+ }
1742
+ else if (m === "a") if (/[a-zA-Z]/.test(rawVal[rawIdx])) {
1743
+ formatted += rawVal[rawIdx];
1744
+ rawIdx++;
1745
+ } else {
1746
+ rawIdx++;
1747
+ i--;
1748
+ }
1749
+ else if (m === "*") {
1750
+ formatted += rawVal[rawIdx];
1751
+ rawIdx++;
1752
+ } else {
1753
+ formatted += m;
1754
+ if (rawVal[rawIdx] === m) rawIdx++;
1755
+ }
1756
+ }
1757
+ return formatted;
1758
+ }, []);
1759
+ const handleChange = (e) => {
1760
+ let newVal = e.target.value;
1761
+ if (mask) newVal = formatWithMask(newVal, mask);
1762
+ else if (useCurrency || type === "number" && locale) newVal = newVal.replace(/[^0-9.]/g, "");
1763
+ if (controlledValue === void 0) setInternalValue(newVal);
1764
+ onChange?.(newVal);
1765
+ };
1766
+ const handleBlur = () => {
1767
+ if (useCurrency && internalValue) {
1768
+ const formatted = formatCurrency(internalValue);
1769
+ if (controlledValue === void 0) setInternalValue(formatted);
1770
+ onChange?.(formatted);
1771
+ }
1772
+ onBlur?.();
756
1773
  };
757
- const sizeClasses = {
758
- sm: "px-2 py-1 text-sm",
759
- md: "px-3 py-2 text-base",
760
- lg: "px-4 py-3 text-lg",
761
- xl: "px-6 py-4 text-xl"
1774
+ const uiStyles = inputStyles(styles, extraStyle, inputSize, readOnly, disabled);
1775
+ const finalInputStyle = {
1776
+ ...uiStyles.input,
1777
+ ...uiStyles.variants[variant]
762
1778
  };
763
1779
  return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
764
- className: `
765
- ${baseClasses}
766
- ${variantClasses[variant]}
767
- ${sizeClasses[inputSize]}
768
- ${variantClassName}
769
- ${sizeClassName}
770
- ${className}
771
- ${disabled ? "opacity-50 cursor-not-allowed" : ""}
772
- ${readOnly ? "bg-gray-100 cursor-not-allowed" : ""}
773
- `.trim(),
774
- style,
1780
+ className: `${finalClassNames.container || ""} ${extraClassName}`.trim(),
1781
+ style: uiStyles.container,
775
1782
  children: [children && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("label", {
776
- htmlFor: id,
777
- className: "block text-sm font-medium text-gray-700 mb-1",
1783
+ htmlFor: inputId,
1784
+ className: finalClassNames.label,
1785
+ style: uiStyles.label,
778
1786
  children
779
1787
  }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("input", {
780
- id,
781
- type,
782
- placeholder,
783
- value,
784
- onChange: (e) => onChange?.(e.target.value),
1788
+ id: inputId,
1789
+ name,
1790
+ type: useCurrency ? "text" : type,
1791
+ placeholder: placeholder || (mask ? mask.replace(/[9a*]/g, maskChar) : ""),
1792
+ value: internalValue,
1793
+ onChange: handleChange,
785
1794
  onFocus,
786
- onBlur,
1795
+ onBlur: handleBlur,
787
1796
  disabled,
788
1797
  required,
789
1798
  readOnly,
790
1799
  "aria-label": ariaLabel,
791
1800
  "aria-labelledby": ariaLabelledby,
792
- className: `
793
- ${inputClassName}
794
- ${variantClasses[variant]}
795
- ${sizeClasses[inputSize]}
796
- ${variantClassName}
797
- ${sizeClassName}
798
- `.trim(),
1801
+ style: finalInputStyle,
1802
+ className: `${finalClassNames.input || ""} rounded-xl`.trim(),
799
1803
  ...props
800
1804
  })]
801
1805
  });
802
1806
  };
803
1807
  //#endregion
1808
+ //#region src/components/DataTable.tsx
1809
+ var DataTable = ({ columns, data, pagination = false, pageSize = 10, selectable = false, onSelectionChange, onRowClick, onRowDoubleClick, searchable = false, texts = {}, classNames = {}, styles = {}, className }) => {
1810
+ const finalClassNames = {
1811
+ container: "luna-datatable",
1812
+ table: "luna-datatable-table",
1813
+ thead: "luna-datatable-thead",
1814
+ tbody: "luna-datatable-tbody",
1815
+ tr: "luna-datatable-tr",
1816
+ th: "luna-datatable-th",
1817
+ td: "luna-datatable-td",
1818
+ pagination: "luna-datatable-pagination",
1819
+ searchContainer: "luna-datatable-search",
1820
+ ...classNames
1821
+ };
1822
+ const [currentPage, setCurrentPage] = useState(1);
1823
+ const [sortConfig, setSortConfig] = useState(null);
1824
+ const [selectedIds, setSelectedIds] = useState(/* @__PURE__ */ new Set());
1825
+ const [searchTerm, setSearchTerm] = useState("");
1826
+ const [columnFilters, setColumnFilters] = useState({});
1827
+ const [activeFilterMenu, setActiveFilterMenu] = useState(null);
1828
+ const filterMenuRef = useRef(null);
1829
+ const t = {
1830
+ showing: "",
1831
+ results: "",
1832
+ prev: "←",
1833
+ next: "→",
1834
+ noData: "No results found",
1835
+ filterPlaceholder: "Filter...",
1836
+ ...texts
1837
+ };
1838
+ useEffect(() => {
1839
+ const handleClickOutside = (event) => {
1840
+ if (filterMenuRef.current && !filterMenuRef.current.contains(event.target)) setActiveFilterMenu(null);
1841
+ };
1842
+ document.addEventListener("mousedown", handleClickOutside);
1843
+ return () => document.removeEventListener("mousedown", handleClickOutside);
1844
+ }, []);
1845
+ const filteredData = useMemo(() => {
1846
+ let result = [...data];
1847
+ if (searchTerm) result = result.filter((row) => Object.values(row).some((val) => String(val).toLowerCase().includes(searchTerm.toLowerCase())));
1848
+ Object.keys(columnFilters).forEach((key) => {
1849
+ const filterValue = columnFilters[key];
1850
+ if (filterValue !== void 0 && filterValue !== "") result = result.filter((row) => String(row[key]) === String(filterValue));
1851
+ });
1852
+ return result;
1853
+ }, [
1854
+ data,
1855
+ searchTerm,
1856
+ columnFilters
1857
+ ]);
1858
+ const sortedData = useMemo(() => {
1859
+ const sortableItems = [...filteredData];
1860
+ if (sortConfig !== null) sortableItems.sort((a, b) => {
1861
+ const aValue = a[sortConfig.key];
1862
+ const bValue = b[sortConfig.key];
1863
+ if (aValue < bValue) return sortConfig.direction === "asc" ? -1 : 1;
1864
+ if (aValue > bValue) return sortConfig.direction === "asc" ? 1 : -1;
1865
+ return 0;
1866
+ });
1867
+ return sortableItems;
1868
+ }, [filteredData, sortConfig]);
1869
+ const totalPages = Math.ceil(sortedData.length / pageSize);
1870
+ const paginatedData = pagination ? sortedData.slice((currentPage - 1) * pageSize, currentPage * pageSize) : sortedData;
1871
+ const handleSort = (key) => {
1872
+ let direction = "asc";
1873
+ if (sortConfig && sortConfig.key === key && sortConfig.direction === "asc") direction = "desc";
1874
+ setSortConfig({
1875
+ key,
1876
+ direction
1877
+ });
1878
+ };
1879
+ const handleSelectAll = (e) => {
1880
+ const newSelected = /* @__PURE__ */ new Set();
1881
+ if (e.target.checked) paginatedData.forEach((row) => newSelected.add(row.id || row._id || JSON.stringify(row)));
1882
+ setSelectedIds(newSelected);
1883
+ notifySelectionChange(newSelected);
1884
+ };
1885
+ const handleSelectRow = (id, e) => {
1886
+ if (e) e.stopPropagation();
1887
+ const newSelected = new Set(selectedIds);
1888
+ if (newSelected.has(id)) newSelected.delete(id);
1889
+ else newSelected.add(id);
1890
+ setSelectedIds(newSelected);
1891
+ notifySelectionChange(newSelected);
1892
+ };
1893
+ const notifySelectionChange = (newIds) => {
1894
+ const selectedRows = Array.from(newIds).map((id) => data.find((r) => (r.id || r._id || JSON.stringify(r)) === id));
1895
+ onSelectionChange?.(selectedRows);
1896
+ };
1897
+ const handleFilterChange = (key, value) => {
1898
+ setColumnFilters((prev) => ({
1899
+ ...prev,
1900
+ [key]: value
1901
+ }));
1902
+ setCurrentPage(1);
1903
+ setActiveFilterMenu(null);
1904
+ };
1905
+ const uiStyles = dataTableStyles(styles);
1906
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
1907
+ style: uiStyles.container,
1908
+ className: `${finalClassNames.container} ${className || ""}`.trim(),
1909
+ children: [
1910
+ searchable && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
1911
+ style: uiStyles.searchContainer,
1912
+ className: finalClassNames.searchContainer,
1913
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Input, {
1914
+ id: "datatable-search",
1915
+ placeholder: "Search...",
1916
+ value: searchTerm,
1917
+ onChange: setSearchTerm,
1918
+ inputSize: "sm"
1919
+ })
1920
+ }),
1921
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("table", {
1922
+ style: uiStyles.table,
1923
+ className: finalClassNames.table,
1924
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("thead", {
1925
+ style: uiStyles.thead,
1926
+ className: finalClassNames.thead,
1927
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("tr", { children: [selectable && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("th", {
1928
+ style: uiStyles.th,
1929
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("input", {
1930
+ type: "checkbox",
1931
+ onChange: handleSelectAll,
1932
+ checked: paginatedData.length > 0 && selectedIds.size === paginatedData.length
1933
+ })
1934
+ }), columns.map((col) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("th", {
1935
+ style: uiStyles.th,
1936
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
1937
+ style: {
1938
+ display: "flex",
1939
+ alignItems: "center",
1940
+ justifyContent: "space-between"
1941
+ },
1942
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
1943
+ style: {
1944
+ cursor: col.sortable ? "pointer" : "default",
1945
+ display: "flex",
1946
+ alignItems: "center"
1947
+ },
1948
+ onClick: () => col.sortable && handleSort(col.key),
1949
+ children: [col.label, col.sortable && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
1950
+ style: uiStyles.icon,
1951
+ children: sortConfig?.key === col.key ? sortConfig.direction === "asc" ? "▲" : "▼" : "↕"
1952
+ })]
1953
+ }), col.filterable && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
1954
+ style: { position: "relative" },
1955
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
1956
+ style: {
1957
+ ...uiStyles.icon,
1958
+ color: columnFilters[col.key] ? "#2563eb" : "#9ca3af"
1959
+ },
1960
+ onClick: (e) => {
1961
+ e.stopPropagation();
1962
+ setActiveFilterMenu(activeFilterMenu === col.key ? null : col.key);
1963
+ },
1964
+ children: "🔍"
1965
+ }), activeFilterMenu === col.key && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
1966
+ ref: filterMenuRef,
1967
+ style: uiStyles.filterMenu,
1968
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", {
1969
+ style: uiStyles.filterOption(!columnFilters[col.key]),
1970
+ onClick: () => handleFilterChange(col.key, ""),
1971
+ children: "All"
1972
+ }), col.filterOptions?.map((opt) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", {
1973
+ style: uiStyles.filterOption(columnFilters[col.key] === opt.value),
1974
+ onClick: () => handleFilterChange(col.key, opt.value),
1975
+ children: opt.label
1976
+ }, opt.value))]
1977
+ })]
1978
+ })]
1979
+ })
1980
+ }, col.key))] })
1981
+ }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("tbody", {
1982
+ style: styles.tbody,
1983
+ className: finalClassNames.tbody,
1984
+ children: paginatedData.length > 0 ? paginatedData.map((row, idx) => {
1985
+ const rowId = row.id || row._id || JSON.stringify(row);
1986
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("tr", {
1987
+ style: uiStyles.tr(!!onRowClick || !!onRowDoubleClick || selectable),
1988
+ className: finalClassNames.tr,
1989
+ onClick: () => {
1990
+ if (onRowClick) onRowClick(row);
1991
+ if (selectable) handleSelectRow(rowId);
1992
+ },
1993
+ onDoubleClick: () => onRowDoubleClick && onRowDoubleClick(row),
1994
+ children: [selectable && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("td", {
1995
+ style: uiStyles.td,
1996
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("input", {
1997
+ type: "checkbox",
1998
+ checked: selectedIds.has(rowId),
1999
+ onChange: (e) => handleSelectRow(rowId, e)
2000
+ })
2001
+ }), columns.map((col) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("td", {
2002
+ style: uiStyles.td,
2003
+ className: finalClassNames.td,
2004
+ children: col.render ? col.render(row[col.key], row) : row[col.key]
2005
+ }, col.key))]
2006
+ }, idx);
2007
+ }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)("tr", { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("td", {
2008
+ colSpan: columns.length + (selectable ? 1 : 0),
2009
+ style: {
2010
+ ...uiStyles.td,
2011
+ textAlign: "center",
2012
+ padding: "2rem"
2013
+ },
2014
+ children: t.noData
2015
+ }) })
2016
+ })]
2017
+ }),
2018
+ pagination && totalPages > 1 && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
2019
+ style: uiStyles.pagination,
2020
+ className: finalClassNames.pagination,
2021
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
2022
+ style: {
2023
+ fontSize: "0.875rem",
2024
+ color: "#6b7280"
2025
+ },
2026
+ children: [
2027
+ Math.min((currentPage - 1) * pageSize + 1, sortedData.length),
2028
+ " - ",
2029
+ Math.min(currentPage * pageSize, sortedData.length),
2030
+ " of ",
2031
+ sortedData.length
2032
+ ]
2033
+ }), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
2034
+ style: {
2035
+ display: "flex",
2036
+ gap: "0.5rem"
2037
+ },
2038
+ children: [
2039
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Button, {
2040
+ variant: "outline",
2041
+ size: "sm",
2042
+ disabled: currentPage === 1,
2043
+ onClick: () => setCurrentPage((prev) => Math.max(prev - 1, 1)),
2044
+ children: t.prev
2045
+ }),
2046
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
2047
+ style: {
2048
+ display: "flex",
2049
+ alignItems: "center",
2050
+ gap: "0.25rem",
2051
+ padding: "0 0.5rem",
2052
+ fontSize: "0.875rem",
2053
+ fontWeight: 500
2054
+ },
2055
+ children: [
2056
+ currentPage,
2057
+ " / ",
2058
+ totalPages
2059
+ ]
2060
+ }),
2061
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Button, {
2062
+ variant: "outline",
2063
+ size: "sm",
2064
+ disabled: currentPage === totalPages,
2065
+ onClick: () => setCurrentPage((prev) => Math.min(prev + 1, totalPages)),
2066
+ children: t.next
2067
+ })
2068
+ ]
2069
+ })]
2070
+ })
2071
+ ]
2072
+ });
2073
+ };
2074
+ //#endregion
2075
+ //#region src/components/Toast.tsx
2076
+ var Toast = ({ visible, severity = "info", summary, detail, life, onClose, position = "top-right", classNames = {}, styles = {}, className }) => {
2077
+ const finalClassNames = {
2078
+ container: "luna-toast",
2079
+ content: "luna-toast-content",
2080
+ icon: "luna-toast-icon",
2081
+ summary: "luna-toast-summary",
2082
+ detail: "luna-toast-detail",
2083
+ closeButton: "luna-toast-close",
2084
+ ...classNames
2085
+ };
2086
+ const [isExiting, setIsExiting] = useState(false);
2087
+ useEffect(() => {
2088
+ let timer;
2089
+ if (visible && life && life > 0) timer = setTimeout(() => {
2090
+ handleClose();
2091
+ }, life);
2092
+ return () => {
2093
+ if (timer) clearTimeout(timer);
2094
+ };
2095
+ }, [visible, life]);
2096
+ const handleClose = () => {
2097
+ setIsExiting(true);
2098
+ setTimeout(() => {
2099
+ setIsExiting(false);
2100
+ onClose();
2101
+ }, 300);
2102
+ };
2103
+ if (!visible && !isExiting) return null;
2104
+ const uiStyles = toastStyles(styles, severity, position, isExiting, visible);
2105
+ const config = toastSeverityConfig[severity || "info"];
2106
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
2107
+ className: `${finalClassNames.container} ${className || ""}`.trim(),
2108
+ style: uiStyles.container,
2109
+ children: [
2110
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
2111
+ className: finalClassNames.icon,
2112
+ style: uiStyles.iconWrapper,
2113
+ children: config.icon
2114
+ }),
2115
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
2116
+ className: finalClassNames.content,
2117
+ style: uiStyles.content,
2118
+ children: [summary && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
2119
+ className: finalClassNames.summary,
2120
+ style: uiStyles.summary,
2121
+ children: summary
2122
+ }), detail && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
2123
+ className: finalClassNames.detail,
2124
+ style: uiStyles.detail,
2125
+ children: detail
2126
+ })]
2127
+ }),
2128
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", {
2129
+ className: finalClassNames.closeButton,
2130
+ style: uiStyles.closeButton,
2131
+ onClick: handleClose,
2132
+ onMouseOver: (e) => e.currentTarget.style.opacity = "1",
2133
+ onMouseOut: (e) => e.currentTarget.style.opacity = "0.6",
2134
+ children: "×"
2135
+ })
2136
+ ]
2137
+ });
2138
+ };
2139
+ //#endregion
2140
+ //#region src/components/MultiSelect.tsx
2141
+ var MultiSelect = ({ options, value = [], onChange, id, placeholder = "Select Items", display = "comma", filter = true, filterPlaceholder = "Search...", selectAll = true, maxSelectedLabels = 3, classNames = {}, styles = {}, disabled = false, className }) => {
2142
+ const finalClassNames = {
2143
+ container: "luna-multiselect",
2144
+ trigger: "luna-multiselect-trigger",
2145
+ panel: "luna-multiselect-panel",
2146
+ header: "luna-multiselect-header",
2147
+ item: "luna-multiselect-item",
2148
+ chip: "luna-multiselect-chip",
2149
+ ...classNames
2150
+ };
2151
+ const [isOpen, setIsOpen] = useState(false);
2152
+ const [filterText, setFilterText] = useState("");
2153
+ const containerRef = useRef(null);
2154
+ useEffect(() => {
2155
+ const handleClickOutside = (event) => {
2156
+ if (containerRef.current && !containerRef.current.contains(event.target)) setIsOpen(false);
2157
+ };
2158
+ document.addEventListener("mousedown", handleClickOutside);
2159
+ return () => document.removeEventListener("mousedown", handleClickOutside);
2160
+ }, []);
2161
+ const filteredOptions = useMemo(() => {
2162
+ return options.filter((opt) => opt.label.toLowerCase().includes(filterText.toLowerCase()));
2163
+ }, [options, filterText]);
2164
+ const handleToggleOption = (optionValue) => {
2165
+ onChange(value.includes(optionValue) ? value.filter((v) => v !== optionValue) : [...value, optionValue]);
2166
+ };
2167
+ const handleSelectAll = (e) => {
2168
+ if (e.target.checked) onChange(options.filter((opt) => !opt.disabled).map((opt) => opt.value));
2169
+ else onChange([]);
2170
+ };
2171
+ const isAllSelected = options.length > 0 && options.every((opt) => value.includes(opt.value));
2172
+ const renderLabel = () => {
2173
+ if (value.length === 0) return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
2174
+ style: { color: "#9ca3af" },
2175
+ children: placeholder
2176
+ });
2177
+ if (display === "chip") return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
2178
+ style: {
2179
+ display: "flex",
2180
+ flexWrap: "wrap",
2181
+ gap: "0.25rem"
2182
+ },
2183
+ children: value.map((val) => {
2184
+ const opt = options.find((o) => o.value === val);
2185
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
2186
+ style: uiStyles.chip,
2187
+ className: finalClassNames.chip,
2188
+ children: [opt?.label, /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
2189
+ style: uiStyles.chipIcon,
2190
+ onClick: (e) => {
2191
+ e.stopPropagation();
2192
+ handleToggleOption(val);
2193
+ },
2194
+ children: "×"
2195
+ })]
2196
+ }, val);
2197
+ })
2198
+ });
2199
+ if (value.length > maxSelectedLabels) return `${value.length} items selected`;
2200
+ return value.map((val) => options.find((o) => o.value === val)?.label).join(", ");
2201
+ };
2202
+ const uiStyles = multiSelectStyles(styles, disabled, isOpen);
2203
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
2204
+ ref: containerRef,
2205
+ className: `${finalClassNames.container} ${className || ""}`.trim(),
2206
+ style: uiStyles.container,
2207
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
2208
+ className: finalClassNames.trigger,
2209
+ style: uiStyles.trigger,
2210
+ onClick: () => !disabled && setIsOpen(!isOpen),
2211
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
2212
+ style: {
2213
+ flex: 1,
2214
+ overflow: "hidden",
2215
+ textOverflow: "ellipsis",
2216
+ whiteSpace: "nowrap"
2217
+ },
2218
+ children: renderLabel()
2219
+ }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
2220
+ style: uiStyles.chevron,
2221
+ children: "▼"
2222
+ })]
2223
+ }), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
2224
+ className: finalClassNames.panel,
2225
+ style: uiStyles.panel,
2226
+ children: [(filter || selectAll) && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
2227
+ style: uiStyles.header,
2228
+ className: finalClassNames.header,
2229
+ children: [selectAll && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", {
2230
+ style: uiStyles.selectAllWrapper,
2231
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("input", {
2232
+ type: "checkbox",
2233
+ style: uiStyles.checkbox,
2234
+ checked: isAllSelected,
2235
+ onChange: handleSelectAll
2236
+ }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { children: "Select All" })]
2237
+ }), filter && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Input, {
2238
+ inputSize: "sm",
2239
+ id: id ? `${id}-filter` : void 0,
2240
+ placeholder: filterPlaceholder,
2241
+ value: filterText,
2242
+ onChange: setFilterText,
2243
+ classNames: { container: "w-full" }
2244
+ })]
2245
+ }), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
2246
+ style: uiStyles.list,
2247
+ children: [filteredOptions.map((opt) => {
2248
+ const isSelected = value.includes(opt.value);
2249
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
2250
+ style: uiStyles.item(isSelected, !!opt.disabled),
2251
+ className: finalClassNames.item,
2252
+ onClick: () => !opt.disabled && handleToggleOption(opt.value),
2253
+ onMouseOver: (e) => !opt.disabled && !isSelected && (e.currentTarget.style.backgroundColor = "#f9fafb"),
2254
+ onMouseOut: (e) => !opt.disabled && !isSelected && (e.currentTarget.style.backgroundColor = "transparent"),
2255
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("input", {
2256
+ type: "checkbox",
2257
+ readOnly: true,
2258
+ checked: isSelected,
2259
+ style: uiStyles.checkbox,
2260
+ disabled: opt.disabled
2261
+ }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { children: opt.label })]
2262
+ }, opt.value);
2263
+ }), filteredOptions.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
2264
+ style: {
2265
+ padding: "1rem",
2266
+ textAlign: "center",
2267
+ fontSize: "0.875rem",
2268
+ color: "#6b7280"
2269
+ },
2270
+ children: "No results found"
2271
+ })]
2272
+ })]
2273
+ })]
2274
+ });
2275
+ };
2276
+ //#endregion
2277
+ //#region src/components/Popconfirm.tsx
2278
+ var Popconfirm = ({ title, description, onConfirm, onCancel, okText = "Yes", cancelText = "No", position = "top", children, classNames = {}, styles = {}, disabled = false, className = "" }) => {
2279
+ const finalClassNames = {
2280
+ container: "luna-popconfirm",
2281
+ popover: "luna-popconfirm-popover",
2282
+ title: "luna-popconfirm-title",
2283
+ description: "luna-popconfirm-description",
2284
+ actions: "luna-popconfirm-actions",
2285
+ okButton: "luna-popconfirm-ok",
2286
+ cancelButton: "luna-popconfirm-cancel",
2287
+ ...classNames
2288
+ };
2289
+ const [show, setShow] = useState(false);
2290
+ const containerRef = useRef(null);
2291
+ useEffect(() => {
2292
+ const handleClickOutside = (event) => {
2293
+ if (containerRef.current && !containerRef.current.contains(event.target)) setShow(false);
2294
+ };
2295
+ if (show) document.addEventListener("mousedown", handleClickOutside);
2296
+ return () => document.removeEventListener("mousedown", handleClickOutside);
2297
+ }, [show]);
2298
+ const handleConfirm = () => {
2299
+ onConfirm();
2300
+ setShow(false);
2301
+ };
2302
+ const handleCancel = () => {
2303
+ onCancel?.();
2304
+ setShow(false);
2305
+ };
2306
+ const triggerElement = React.cloneElement(children, { onClick: (e) => {
2307
+ if (disabled) return;
2308
+ e.stopPropagation();
2309
+ setShow(!show);
2310
+ const childProps = children.props;
2311
+ if (childProps?.onClick) childProps.onClick(e);
2312
+ } });
2313
+ const uiStyles = popconfirmStyles(styles, show, position);
2314
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
2315
+ ref: containerRef,
2316
+ style: uiStyles.container,
2317
+ className: `${finalClassNames.container} ${className}`.trim(),
2318
+ children: [triggerElement, /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
2319
+ style: uiStyles.popover,
2320
+ className: finalClassNames.popover,
2321
+ children: [
2322
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
2323
+ style: uiStyles.titleWrapper,
2324
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
2325
+ style: uiStyles.icon,
2326
+ children: "⚠"
2327
+ }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
2328
+ style: uiStyles.title,
2329
+ className: finalClassNames.title,
2330
+ children: title
2331
+ })]
2332
+ }),
2333
+ description && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
2334
+ style: uiStyles.description,
2335
+ className: finalClassNames.description,
2336
+ children: description
2337
+ }),
2338
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
2339
+ style: uiStyles.actions,
2340
+ className: finalClassNames.actions,
2341
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Button, {
2342
+ size: "sm",
2343
+ variant: "outline",
2344
+ onClick: handleCancel,
2345
+ className: finalClassNames.cancelButton,
2346
+ children: cancelText
2347
+ }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Button, {
2348
+ size: "sm",
2349
+ variant: "primary",
2350
+ onClick: handleConfirm,
2351
+ className: finalClassNames.okButton,
2352
+ children: okText
2353
+ })]
2354
+ })
2355
+ ]
2356
+ })]
2357
+ });
2358
+ };
2359
+ //#endregion
2360
+ //#region src/components/QRCode.tsx
2361
+ var QRCode = ({ value, size = 160, color = "000000", bgColor = "ffffff", bordered = true, classNames = {}, styles = {}, errorCorrectionLevel = "M", className }) => {
2362
+ const finalClassNames = {
2363
+ container: "luna-qrcode",
2364
+ image: "luna-qrcode-image",
2365
+ ...classNames
2366
+ };
2367
+ const [isLoading, setIsLoading] = useState(true);
2368
+ const cleanColor = color.startsWith("#") ? color.slice(1) : color;
2369
+ const cleanBgColor = bgColor.startsWith("#") ? bgColor.slice(1) : bgColor;
2370
+ const qrUrl = `https://api.qrserver.com/v1/create-qr-code/?size=${size}x${size}&data=${encodeURIComponent(value)}&color=${cleanColor}&bgcolor=${cleanBgColor}&ecc=${errorCorrectionLevel}`;
2371
+ const uiStyles = qrCodeStyles(styles, bordered, cleanBgColor, size, isLoading);
2372
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
2373
+ className: `${finalClassNames.container} ${className || ""}`.trim(),
2374
+ style: uiStyles.container,
2375
+ children: [
2376
+ isLoading && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: uiStyles.skeleton }),
2377
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("img", {
2378
+ src: qrUrl,
2379
+ alt: `QR Code for ${value}`,
2380
+ style: uiStyles.image,
2381
+ className: finalClassNames.image,
2382
+ onLoad: () => setIsLoading(false)
2383
+ }),
2384
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("style", { children: `
2385
+ @keyframes pulse {
2386
+ 0%, 100% { opacity: 1; }
2387
+ 50% { opacity: .5; }
2388
+ }
2389
+ ` })
2390
+ ]
2391
+ });
2392
+ };
2393
+ //#endregion
804
2394
  //#region src/utilities/apiFetch.util.ts
805
2395
  /**
806
2396
  * A generic wrapper for the fetch API with error handling and response parsing.
@@ -1012,6 +2602,9 @@ var validators = {
1012
2602
  };
1013
2603
  //#endregion
1014
2604
  //#region src/utilities/logger.util.ts
2605
+ /**
2606
+ * Utility for logging messages with different levels.
2607
+ */
1015
2608
  var logStyles = {
1016
2609
  info: "color: #3b82f6; font-weight: bold;",
1017
2610
  warn: "color: #f59e0b; font-weight: bold;",
@@ -1019,12 +2612,18 @@ var logStyles = {
1019
2612
  success: "color: #10b981; font-weight: bold;"
1020
2613
  };
1021
2614
  var logger = {
1022
- info: (message, ...data) => {},
1023
- warn: (message, ...data) => {},
2615
+ info: (message, ...data) => {
2616
+ console.log(`%c[INFO] ${message}`, logStyles.info, ...data);
2617
+ },
2618
+ warn: (message, ...data) => {
2619
+ console.warn(`%c[WARN] ${message}`, logStyles.warn, ...data);
2620
+ },
1024
2621
  error: (message, ...data) => {
1025
2622
  console.error(`%c[ERROR] ${message}`, logStyles.error, ...data);
1026
2623
  },
1027
- success: (message, ...data) => {}
2624
+ success: (message, ...data) => {
2625
+ console.log(`%c[SUCCESS] ${message}`, logStyles.success, ...data);
2626
+ }
1028
2627
  };
1029
2628
  //#endregion
1030
2629
  //#region src/hooks/useFetch.hook.ts
@@ -1117,6 +2716,6 @@ function useDebounce(value, delay = 500) {
1117
2716
  return debouncedValue;
1118
2717
  }
1119
2718
  //#endregion
1120
- export { Accordion, Anchor, Button, Card, DropDown, Input, Modal, Preloader, ProgressBar, ScrollTop, Spinner, Typed, WhatsApp, apiFetch, del, formatters, get, httpClient, logger, post, put, storage, useDebounce, useFetch, useLocalStorage, validators };
2719
+ export { Accordion, Anchor, Button, Card, DataTable, DropDown, Input, Modal, MultiSelect, Popconfirm, Preloader, ProgressBar, QRCode, ScrollTop, Spinner, Toast, Typed, WhatsApp, apiFetch, del, formatters, get, httpClient, logger, post, put, storage, useDebounce, useFetch, useLocalStorage, validators };
1121
2720
 
1122
2721
  //# sourceMappingURL=luna-components-library.js.map