neogestify-ui-components 2.2.2 → 2.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +803 -349
  3. package/dist/components/ElementLibraryBuilder/index.js +299 -120
  4. package/dist/components/ElementLibraryBuilder/index.js.map +1 -1
  5. package/dist/components/ElementLibraryBuilder/index.mjs +300 -121
  6. package/dist/components/ElementLibraryBuilder/index.mjs.map +1 -1
  7. package/dist/components/VenueMapEditor/index.js.map +1 -1
  8. package/dist/components/VenueMapEditor/index.mjs.map +1 -1
  9. package/dist/components/alerts/index.js +108 -51
  10. package/dist/components/alerts/index.js.map +1 -1
  11. package/dist/components/alerts/index.mjs +109 -52
  12. package/dist/components/alerts/index.mjs.map +1 -1
  13. package/dist/components/html/index.d.mts +101 -22
  14. package/dist/components/html/index.d.ts +101 -22
  15. package/dist/components/html/index.js +506 -166
  16. package/dist/components/html/index.js.map +1 -1
  17. package/dist/components/html/index.mjs +507 -167
  18. package/dist/components/html/index.mjs.map +1 -1
  19. package/dist/components/icons/index.d.mts +5 -1
  20. package/dist/components/icons/index.d.ts +5 -1
  21. package/dist/components/icons/index.js +16 -0
  22. package/dist/components/icons/index.js.map +1 -1
  23. package/dist/components/icons/index.mjs +13 -1
  24. package/dist/components/icons/index.mjs.map +1 -1
  25. package/dist/context/theme/index.js +59 -37
  26. package/dist/context/theme/index.js.map +1 -1
  27. package/dist/context/theme/index.mjs +59 -37
  28. package/dist/context/theme/index.mjs.map +1 -1
  29. package/dist/index.d.mts +1 -1
  30. package/dist/index.d.ts +1 -1
  31. package/dist/index.js +510 -166
  32. package/dist/index.js.map +1 -1
  33. package/dist/index.mjs +508 -168
  34. package/dist/index.mjs.map +1 -1
  35. package/package.json +1 -1
  36. package/src/components/html/Button.tsx +84 -38
  37. package/src/components/html/Form.tsx +33 -13
  38. package/src/components/html/Input.tsx +110 -31
  39. package/src/components/html/Loading.tsx +58 -33
  40. package/src/components/html/Modal.tsx +67 -20
  41. package/src/components/html/Select.tsx +92 -39
  42. package/src/components/html/Table.tsx +274 -50
  43. package/src/components/html/TextArea.tsx +81 -31
  44. package/src/components/icons/icons.tsx +32 -0
package/dist/index.js CHANGED
@@ -430,56 +430,101 @@ function IconPolygon({ className }) {
430
430
  function IconLayers({ className }) {
431
431
  return /* @__PURE__ */ jsxRuntime.jsx("svg", { viewBox: "0 0 16 16", className, fill: "currentColor", children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M8.235 1.559a.5.5 0 0 0-.47 0l-7.5 4a.5.5 0 0 0 0 .882L3.188 8 .265 9.559a.5.5 0 0 0 0 .882l7.5 4a.5.5 0 0 0 .47 0l7.5-4a.5.5 0 0 0 0-.882L12.813 8l2.922-1.559a.5.5 0 0 0 0-.882l-7.5-4zm3.515 7.008L14.438 10 8 13.433 1.562 10 4.25 8.567l3.515 1.874a.5.5 0 0 0 .47 0l3.515-1.874zM8 9.433 1.562 6 8 2.567 14.438 6 8 9.433z" }) });
432
432
  }
433
+ function ChevronDownIcon({ className }) {
434
+ return /* @__PURE__ */ jsxRuntime.jsx("svg", { viewBox: "0 0 16 16", className, fill: "currentColor", "aria-hidden": true, children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M4.516 7.548c.436-.446 1.043-.481 1.576 0L8 9.747l1.908-2.199c.533-.481 1.14-.446 1.576 0 .436.445.408 1.197 0 1.615-.408.418-2.695 2.977-2.695 2.977-.27.282-.64.423-1.01.423s-.74-.14-1.01-.423c0 0-2.287-2.559-2.695-2.977-.408-.418-.436-1.17 0-1.615z" }) });
435
+ }
436
+ function SortAscIcon({ className }) {
437
+ return /* @__PURE__ */ jsxRuntime.jsx("svg", { viewBox: "0 0 12 12", className, fill: "currentColor", "aria-hidden": true, children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M6 2.5l4 5H2l4-5z" }) });
438
+ }
439
+ function SortDescIcon({ className }) {
440
+ return /* @__PURE__ */ jsxRuntime.jsx("svg", { viewBox: "0 0 12 12", className, fill: "currentColor", "aria-hidden": true, children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M6 9.5L2 4.5h8L6 9.5z" }) });
441
+ }
442
+ function SortBothIcon({ className }) {
443
+ return /* @__PURE__ */ jsxRuntime.jsx("svg", { viewBox: "0 0 12 12", className, fill: "currentColor", "aria-hidden": true, children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M6 1.5l3 3.5H3L6 1.5zm0 9l-3-3.5h6L6 10.5z" }) });
444
+ }
445
+ var BASE = "transition-all duration-200 disabled:opacity-50 disabled:cursor-not-allowed cursor-pointer inline-flex items-center gap-2";
446
+ var SIZE_PAD = {
447
+ sm: "px-2.5 py-1.5 text-xs",
448
+ md: "px-3 py-2 text-sm",
449
+ lg: "px-4 py-2.5 text-base"
450
+ };
451
+ var SIZE_ICON_PAD = {
452
+ sm: "p-1.5",
453
+ md: "p-2",
454
+ lg: "p-2.5"
455
+ };
456
+ var SHAPE_CLASS = {
457
+ rounded: "rounded-md",
458
+ pill: "rounded-full",
459
+ square: "rounded-none"
460
+ };
461
+ var VARIANT_STYLE = {
462
+ primary: "border border-indigo-600/20 dark:border-indigo-500/20 font-medium text-white bg-indigo-600 hover:bg-indigo-700 dark:bg-indigo-500 dark:hover:bg-indigo-600 focus:outline-none focus:ring-2 focus:ring-indigo-500 dark:focus:ring-indigo-400 focus:ring-offset-2 focus:ring-offset-gray-50 dark:focus:ring-offset-gray-900",
463
+ secondary: "font-medium text-gray-600 dark:text-gray-400 hover:text-gray-900 dark:hover:text-white hover:bg-gray-200 dark:hover:bg-gray-800 border border-gray-300 dark:border-gray-600 shadow-sm hover:shadow-md focus:outline-none focus:ring-2 focus:ring-indigo-500 dark:focus:ring-indigo-400 focus:ring-offset-2 focus:ring-offset-gray-50 dark:focus:ring-offset-gray-900",
464
+ icon: "text-gray-600 dark:text-gray-400 hover:text-gray-900 dark:hover:text-white hover:bg-gray-200 dark:hover:bg-gray-800 focus:outline-none focus:ring-2 focus:ring-indigo-500 dark:focus:ring-indigo-400 focus:ring-offset-2 focus:ring-offset-gray-50 dark:focus:ring-offset-gray-900",
465
+ danger: "border border-red-600/20 dark:border-red-500/20 font-medium text-white bg-red-600 hover:bg-red-700 dark:bg-red-500 dark:hover:bg-red-600 focus:outline-none focus:ring-2 focus:ring-red-500 dark:focus:ring-red-400 focus:ring-offset-2 focus:ring-offset-gray-50 dark:focus:ring-offset-gray-900",
466
+ success: "border border-green-600/20 dark:border-green-500/20 font-medium text-white bg-green-600 hover:bg-green-700 dark:bg-green-500 dark:hover:bg-green-600 focus:outline-none focus:ring-2 focus:ring-green-500 dark:focus:ring-green-400 focus:ring-offset-2 focus:ring-offset-gray-50 dark:focus:ring-offset-gray-900",
467
+ outline: "border border-gray-300 dark:border-gray-600 font-medium text-gray-700 dark:text-gray-300 bg-transparent hover:bg-gray-100 dark:hover:bg-gray-700 focus:outline-none focus:ring-2 focus:ring-indigo-500 dark:focus:ring-indigo-400 focus:ring-offset-2 focus:ring-offset-gray-50 dark:focus:ring-offset-gray-900",
468
+ nav: "w-full px-4 py-2 text-sm font-medium hover:scale-105 text-gray-700 dark:text-gray-300 dark:hover:text-white hover:shadow-lg focus:outline-none focus:ring-2 focus:ring-indigo-500 dark:focus:ring-indigo-400 focus:ring-offset-2 focus:ring-offset-gray-50 dark:focus:ring-offset-gray-900",
469
+ custom: "",
470
+ link: "text-sm text-indigo-600 dark:text-indigo-400 hover:text-indigo-700 dark:hover:text-indigo-300 focus:outline-none focus:ring-2 focus:ring-indigo-500 dark:focus:ring-indigo-400 focus:ring-offset-2 focus:ring-offset-gray-50 dark:focus:ring-offset-gray-900 rounded-lg px-2",
471
+ warning: "border border-yellow-600/20 dark:border-yellow-500/20 font-medium text-white bg-yellow-600 hover:bg-yellow-700 dark:bg-yellow-500 dark:hover:bg-yellow-600 focus:outline-none focus:ring-2 focus:ring-yellow-500 dark:focus:ring-yellow-400 focus:ring-offset-2 focus:ring-offset-gray-50 dark:focus:ring-offset-gray-900",
472
+ toggle: "font-medium border-2 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2 focus:ring-offset-gray-50 dark:focus:ring-offset-gray-900",
473
+ ghost: "font-medium text-indigo-600 dark:text-indigo-400 bg-transparent border border-indigo-200 dark:border-indigo-800 hover:bg-indigo-50 dark:hover:bg-indigo-900/30 focus:outline-none focus:ring-2 focus:ring-indigo-500 dark:focus:ring-indigo-400 focus:ring-offset-2 focus:ring-offset-gray-50 dark:focus:ring-offset-gray-900"
474
+ };
433
475
  var Button = ({
434
476
  variant = "primary",
435
477
  children,
436
478
  isLoading = false,
437
479
  loadingText,
438
480
  isActive = false,
481
+ size = "md",
482
+ leftIcon,
483
+ rightIcon,
484
+ fullWidth = false,
485
+ shape,
439
486
  className = "",
440
487
  disabled,
441
488
  ...props
442
489
  }) => {
443
- const baseClasses = "transition-all duration-200 disabled:opacity-50 disabled:cursor-not-allowed cursor-pointer";
444
- const variantClasses = {
445
- primary: "py-2 px-2 border border-indigo-600/20 dark:border-indigo-500/20 text-sm font-medium rounded-md text-white bg-indigo-600 hover:bg-indigo-700 dark:bg-indigo-500 dark:hover:bg-indigo-600 focus:outline-none focus:ring-2 focus:ring-indigo-500 dark:focus:ring-indigo-400 focus:ring-offset-2 focus:ring-offset-gray-50 dark:focus:ring-offset-gray-900",
446
- secondary: "p-2 text-gray-600 dark:text-gray-400 hover:text-gray-900 dark:hover:text-white hover:bg-gray-200 dark:hover:bg-gray-800 rounded-md border border-gray-300 dark:border-gray-600 shadow-sm hover:shadow-md focus:outline-none focus:ring-2 focus:ring-indigo-500 dark:focus:ring-indigo-400 focus:ring-offset-2 focus:ring-offset-gray-50 dark:focus:ring-offset-gray-900",
447
- icon: "p-2 text-gray-600 dark:text-gray-400 hover:text-gray-900 dark:hover:text-white hover:bg-gray-200 dark:hover:bg-gray-800 rounded-full focus:outline-none focus:ring-2 focus:ring-indigo-500 dark:focus:ring-indigo-400 focus:ring-offset-2 focus:ring-offset-gray-50 dark:focus:ring-offset-gray-900",
448
- danger: "py-2 px-2 border border-red-600/20 dark:border-red-500/20 text-sm font-medium rounded-md text-white bg-red-600 hover:bg-red-700 dark:bg-red-500 dark:hover:bg-red-600 focus:outline-none focus:ring-2 focus:ring-red-500 dark:focus:ring-red-400 focus:ring-offset-2 focus:ring-offset-gray-50 dark:focus:ring-offset-gray-900",
449
- success: "py-2 px-2 border border-green-600/20 dark:border-green-500/20 text-sm font-medium rounded-md text-white bg-green-600 hover:bg-green-700 dark:bg-green-500 dark:hover:bg-green-600 focus:outline-none focus:ring-2 focus:ring-green-500 dark:focus:ring-green-400 focus:ring-offset-2 focus:ring-offset-gray-50 dark:focus:ring-offset-gray-900",
450
- outline: "py-2 px-2 border border-gray-300 dark:border-gray-600 text-sm font-medium rounded-md text-gray-700 dark:text-gray-300 bg-transparent hover:bg-gray-100 dark:hover:bg-gray-700 focus:outline-none focus:ring-2 focus:ring-indigo-500 dark:focus:ring-indigo-400 focus:ring-offset-2 focus:ring-offset-gray-50 dark:focus:ring-offset-gray-900",
451
- nav: "w-full flex items-center px-4 py-2 text-sm font-medium rounded-md transition-all duration-200 hover:scale-105 text-gray-700 dark:text-gray-300 dark:hover:text-white hover:shadow-lg focus:outline-none focus:ring-2 focus:ring-indigo-500 dark:focus:ring-indigo-400 focus:ring-offset-2 focus:ring-offset-gray-50 dark:focus:ring-offset-gray-900",
452
- custom: "",
453
- link: "text-sm text-indigo-600 dark:text-indigo-400 hover:text-indigo-700 dark:hover:text-indigo-300 transition-colors duration-200 focus:outline-none focus:ring-2 focus:ring-indigo-500 dark:focus:ring-indigo-400 focus:ring-offset-2 focus:ring-offset-gray-50 dark:focus:ring-offset-gray-900 rounded-lg px-2",
454
- warning: "py-2 px-2 border border-yellow-600/20 dark:border-yellow-500/20 text-sm font-medium rounded-md text-white bg-yellow-600 hover:bg-yellow-700 dark:bg-yellow-500 dark:hover:bg-yellow-600 focus:outline-none focus:ring-2 focus:ring-yellow-500 dark:focus:ring-yellow-400 focus:ring-offset-2 focus:ring-offset-gray-50 dark:focus:ring-offset-gray-900",
455
- toggle: "px-2 py-2 rounded-lg font-medium transition-all duration-200 disabled:cursor-not-allowed border-2 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2 focus:ring-offset-gray-50 dark:focus:ring-offset-gray-900"
456
- };
457
- let classes = `${baseClasses} ${variantClasses[variant]} ${className}`;
458
- if (variant === "nav" && isActive) {
459
- classes += " bg-indigo-600 dark:bg-indigo-500 hover:bg-indigo-700 dark:hover:bg-indigo-600 text-white shadow-lg scale-105";
460
- }
461
- if (variant === "nav" && !isActive) {
462
- classes += " hover:bg-white dark:hover:bg-gray-700 hover:shadow-lg";
490
+ const sizeCls = variant === "icon" ? SIZE_ICON_PAD[size] : variant === "nav" || variant === "link" || variant === "custom" ? "" : SIZE_PAD[size];
491
+ const defaultShape = variant === "icon" ? "pill" : "rounded";
492
+ const shapeCls = variant === "link" || variant === "custom" ? "" : SHAPE_CLASS[shape ?? defaultShape];
493
+ let stateCls = "";
494
+ if (variant === "nav") {
495
+ stateCls = isActive ? "bg-indigo-600 dark:bg-indigo-500 hover:bg-indigo-700 dark:hover:bg-indigo-600 text-white shadow-lg scale-105" : "hover:bg-white dark:hover:bg-gray-700";
463
496
  }
464
497
  if (variant === "toggle") {
465
- if (isActive) {
466
- classes += " bg-indigo-600 text-white border-indigo-600/30 dark:border-indigo-500/30 hover:bg-indigo-700";
467
- } else {
468
- classes += " bg-gray-200 dark:bg-gray-700 text-gray-700 dark:text-gray-300 border-gray-300 dark:border-gray-600 hover:bg-gray-300 dark:hover:bg-gray-600 hover:border-gray-400 dark:hover:border-gray-500";
469
- }
498
+ stateCls = isActive ? "bg-indigo-600 text-white border-indigo-600/30 dark:border-indigo-500/30 hover:bg-indigo-700" : "bg-gray-200 dark:bg-gray-700 text-gray-700 dark:text-gray-300 border-gray-300 dark:border-gray-600 hover:bg-gray-300 dark:hover:bg-gray-600";
470
499
  }
471
- return /* @__PURE__ */ jsxRuntime.jsx(
472
- "button",
473
- {
474
- className: classes,
475
- disabled: disabled || isLoading,
476
- ...props,
477
- children: isLoading ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
478
- /* @__PURE__ */ jsxRuntime.jsx(AnimateSpin, { className: "h-5 w-5 mr-2 inline-block text-current" }),
479
- loadingText || "Cargando..."
480
- ] }) : children
481
- }
482
- );
500
+ const classes = [
501
+ BASE,
502
+ VARIANT_STYLE[variant],
503
+ sizeCls,
504
+ shapeCls,
505
+ stateCls,
506
+ fullWidth ? "w-full justify-center" : "",
507
+ className
508
+ ].filter(Boolean).join(" ");
509
+ return /* @__PURE__ */ jsxRuntime.jsx("button", { className: classes, disabled: disabled || isLoading, ...props, children: isLoading ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
510
+ /* @__PURE__ */ jsxRuntime.jsx(AnimateSpin, { className: "h-4 w-4 shrink-0 text-current" }),
511
+ loadingText ?? "Cargando..."
512
+ ] }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
513
+ leftIcon && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "shrink-0", children: leftIcon }),
514
+ children,
515
+ rightIcon && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "shrink-0", children: rightIcon })
516
+ ] }) });
517
+ };
518
+ var SIZE_CLASSES = {
519
+ sm: "px-2.5 py-1.5 text-xs",
520
+ md: "px-3 py-2 text-sm",
521
+ lg: "px-4 py-2.5 text-base"
522
+ };
523
+ var VARIANT_CLASSES = {
524
+ default: "border border-gray-300 dark:border-gray-600 bg-white dark:bg-gray-800",
525
+ outline: "border-2 border-indigo-300 dark:border-indigo-600 bg-transparent",
526
+ filled: "border border-gray-300 dark:border-gray-600 bg-gray-100 dark:bg-gray-700",
527
+ minimal: "border-0 border-b border-gray-300 dark:border-gray-600 bg-transparent rounded-none focus:ring-0"
483
528
  };
484
529
  var Input = ({
485
530
  label,
@@ -487,34 +532,63 @@ var Input = ({
487
532
  helperText,
488
533
  icon,
489
534
  iconSide = "left",
535
+ variant = "default",
536
+ size = "md",
537
+ prefix,
538
+ suffix,
539
+ clearable = false,
540
+ onClear,
490
541
  className = "",
491
542
  id,
492
543
  type,
493
544
  ...props
494
545
  }) => {
495
546
  const inputId = id || `input-${Math.random().toString(36).substring(2, 9)}`;
496
- const baseClasses = "appearance-none relative block w-full px-3 py-2 border placeholder-gray-500 dark:placeholder-gray-400 text-gray-900 dark:text-white bg-white dark:bg-gray-800 rounded-md focus:outline-none focus:ring-2 focus:ring-indigo-500 dark:focus:ring-indigo-400 focus:border-indigo-500 focus:z-10 sm:text-sm disabled:opacity-50 disabled:cursor-not-allowed transition-colors duration-200";
497
- const errorClasses = error ? "border-red-300 dark:border-red-600 focus:ring-red-500 dark:focus:ring-red-400 focus:border-red-500" : "border-gray-300 dark:border-gray-600";
498
- const iconPaddingLeft = icon && iconSide === "left" ? "pl-9" : "";
499
- const iconPaddingRight = icon && iconSide === "right" ? "pr-9" : "";
500
- const classes = `${baseClasses} ${errorClasses} ${iconPaddingLeft} ${iconPaddingRight} ${className}`.trim();
501
- const toggleShape = type === "radio" ? "rounded-full" : "rounded";
502
- const toggleBaseClasses = `h-4 w-4 ${toggleShape} border border-gray-300 dark:border-gray-600 bg-white dark:bg-gray-800 text-indigo-600 dark:text-indigo-400 focus:outline-none focus:ring-2 focus:ring-indigo-500 dark:focus:ring-indigo-400 focus:ring-offset-2 focus:ring-offset-white dark:focus:ring-offset-gray-900 disabled:opacity-50 disabled:cursor-not-allowed transition-colors duration-200 cursor-pointer`;
503
- const toggleErrorClasses = error ? "border-red-300 dark:border-red-600 focus:ring-red-500 dark:focus:ring-red-400" : "";
504
- const toggleClasses = `${toggleBaseClasses} ${toggleErrorClasses}`.trim();
505
- const fileBaseClasses = "block w-full sm:text-sm text-gray-500 dark:text-gray-400 bg-white dark:bg-gray-800 border rounded-md focus:outline-none focus:ring-2 focus:ring-indigo-500 dark:focus:ring-indigo-400 focus:border-indigo-500 disabled:opacity-50 disabled:cursor-not-allowed transition-colors duration-200 file:mr-4 file:py-2 file:px-4 file:rounded-l-md file:border-0 file:text-sm file:font-medium file:bg-indigo-50 file:text-indigo-700 dark:file:bg-indigo-900/50 dark:file:text-indigo-300 hover:file:bg-indigo-100 dark:hover:file:bg-indigo-800/50 file:transition-colors file:duration-200 file:cursor-pointer";
506
- const fileErrorClasses = error ? "border-red-300 dark:border-red-600 focus:ring-red-500 dark:focus:ring-red-400" : "border-gray-300 dark:border-gray-600";
507
- const fileClasses = `${fileBaseClasses} ${fileErrorClasses} ${className}`.trim();
547
+ const errorCls = error ? "border-red-300 dark:border-red-600 focus:ring-red-500 dark:focus:ring-red-400 focus:border-red-500" : "";
548
+ const showClear = clearable && !props.disabled && props.value !== void 0 && props.value !== "";
549
+ const hasRightSlot = icon && iconSide === "right" || showClear;
550
+ const baseCls = "appearance-none relative block w-full placeholder-gray-500 dark:placeholder-gray-400 text-gray-900 dark:text-white rounded-md focus:outline-none focus:ring-2 focus:ring-indigo-500 dark:focus:ring-indigo-400 focus:border-indigo-500 focus:z-10 disabled:opacity-50 disabled:cursor-not-allowed transition-colors duration-200";
551
+ const inputCls = [
552
+ baseCls,
553
+ SIZE_CLASSES[size],
554
+ VARIANT_CLASSES[variant],
555
+ errorCls,
556
+ icon && iconSide === "left" ? "pl-9" : "",
557
+ hasRightSlot ? "pr-9" : "",
558
+ prefix ? "rounded-l-none" : "",
559
+ suffix ? "rounded-r-none" : "",
560
+ className
561
+ ].filter(Boolean).join(" ");
562
+ const toggleCls = [
563
+ `h-4 w-4 ${type === "radio" ? "rounded-full" : "rounded"} border border-gray-300 dark:border-gray-600 bg-white dark:bg-gray-800`,
564
+ "text-indigo-600 dark:text-indigo-400 focus:outline-none focus:ring-2 focus:ring-indigo-500 dark:focus:ring-indigo-400",
565
+ "focus:ring-offset-2 focus:ring-offset-white dark:focus:ring-offset-gray-900",
566
+ "disabled:opacity-50 disabled:cursor-not-allowed transition-colors duration-200 cursor-pointer",
567
+ error ? "border-red-300 dark:border-red-600 focus:ring-red-500 dark:focus:ring-red-400" : ""
568
+ ].filter(Boolean).join(" ");
569
+ const fileCls = [
570
+ "block w-full text-gray-500 dark:text-gray-400 bg-white dark:bg-gray-800 border rounded-md",
571
+ "focus:outline-none focus:ring-2 focus:ring-indigo-500 dark:focus:ring-indigo-400 focus:border-indigo-500",
572
+ "disabled:opacity-50 disabled:cursor-not-allowed transition-colors duration-200",
573
+ "file:mr-4 file:py-2 file:px-4 file:rounded-l-md file:border-0 file:text-sm file:font-medium",
574
+ "file:bg-indigo-50 file:text-indigo-700 dark:file:bg-indigo-900/50 dark:file:text-indigo-300",
575
+ "hover:file:bg-indigo-100 dark:hover:file:bg-indigo-800/50 file:transition-colors file:duration-200 file:cursor-pointer",
576
+ SIZE_CLASSES[size],
577
+ error ? "border-red-300 dark:border-red-600 focus:ring-red-500 dark:focus:ring-red-400" : "border-gray-300 dark:border-gray-600",
578
+ className
579
+ ].filter(Boolean).join(" ");
508
580
  const hasHidden = Boolean(className && /\bhidden\b/.test(className));
509
- const wrapperBase = "space-y-1 w-full";
510
- const wrapperClasses = hasHidden ? `${wrapperBase} hidden` : wrapperBase;
511
- const labelNode = label && (typeof label === "string" ? /* @__PURE__ */ jsxRuntime.jsx("label", { htmlFor: inputId, className: "block text-sm font-medium text-gray-700 dark:text-gray-300", children: label }) : label);
581
+ const wrapperCls = `space-y-1 w-full${hasHidden ? " hidden" : ""}`;
582
+ const labelNode = label && (typeof label === "string" ? /* @__PURE__ */ jsxRuntime.jsxs("label", { htmlFor: inputId, className: "block text-sm font-medium text-gray-700 dark:text-gray-300", children: [
583
+ label,
584
+ props.required && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "ml-1 text-red-500", "aria-hidden": "true", children: "*" })
585
+ ] }) : label);
512
586
  const errorNode = error && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-red-600 dark:text-red-400", role: "alert", children: error });
513
587
  const helperNode = helperText && !error && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-gray-500 dark:text-gray-400", children: helperText });
514
588
  if (type === "checkbox" || type === "radio") {
515
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: wrapperClasses, children: [
589
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: wrapperCls, children: [
516
590
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center space-x-2", children: [
517
- /* @__PURE__ */ jsxRuntime.jsx("input", { id: inputId, type, className: toggleClasses, ...props }),
591
+ /* @__PURE__ */ jsxRuntime.jsx("input", { id: inputId, type, className: toggleCls, ...props }),
518
592
  labelNode
519
593
  ] }),
520
594
  errorNode,
@@ -522,63 +596,108 @@ var Input = ({
522
596
  ] });
523
597
  }
524
598
  if (type === "file") {
525
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: wrapperClasses, children: [
599
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: wrapperCls, children: [
526
600
  labelNode,
527
- /* @__PURE__ */ jsxRuntime.jsx("input", { id: inputId, type: "file", className: fileClasses, ...props }),
601
+ /* @__PURE__ */ jsxRuntime.jsx("input", { id: inputId, type: "file", className: fileCls, ...props }),
528
602
  errorNode,
529
603
  helperNode
530
604
  ] });
531
605
  }
532
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: wrapperClasses, children: [
606
+ const prefixBorderCls = error ? "border-red-300 dark:border-red-600" : "border-gray-300 dark:border-gray-600";
607
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: wrapperCls, children: [
533
608
  labelNode,
534
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative", children: [
535
- icon && iconSide === "left" && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pointer-events-none absolute inset-y-0 left-0 z-10 flex items-center pl-3 text-gray-400 dark:text-gray-500", children: icon }),
536
- /* @__PURE__ */ jsxRuntime.jsx("input", { id: inputId, className: classes, type, ...props }),
537
- icon && iconSide === "right" && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pointer-events-none absolute inset-y-0 right-0 z-10 flex items-center pr-3 text-gray-400 dark:text-gray-500", children: icon })
609
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex", children: [
610
+ prefix && /* @__PURE__ */ jsxRuntime.jsx("span", { className: `inline-flex shrink-0 items-center px-3 border border-r-0 ${prefixBorderCls} bg-gray-50 dark:bg-gray-700 text-gray-500 dark:text-gray-400 rounded-l-md text-sm`, children: prefix }),
611
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative flex-1", children: [
612
+ icon && iconSide === "left" && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pointer-events-none absolute inset-y-0 left-0 z-10 flex items-center pl-3 text-gray-400 dark:text-gray-500", children: icon }),
613
+ /* @__PURE__ */ jsxRuntime.jsx("input", { id: inputId, className: inputCls, type, ...props }),
614
+ icon && iconSide === "right" && !showClear && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pointer-events-none absolute inset-y-0 right-0 z-10 flex items-center pr-3 text-gray-400 dark:text-gray-500", children: icon }),
615
+ showClear && /* @__PURE__ */ jsxRuntime.jsx(
616
+ "button",
617
+ {
618
+ type: "button",
619
+ onClick: onClear,
620
+ tabIndex: -1,
621
+ "aria-label": "Limpiar",
622
+ className: "absolute inset-y-0 right-0 z-10 flex items-center pr-3 text-gray-400 dark:text-gray-500 hover:text-gray-600 dark:hover:text-gray-300",
623
+ children: /* @__PURE__ */ jsxRuntime.jsx(CloseIcon, { className: "w-4 h-4" })
624
+ }
625
+ )
626
+ ] }),
627
+ suffix && /* @__PURE__ */ jsxRuntime.jsx("span", { className: `inline-flex shrink-0 items-center px-3 border border-l-0 ${prefixBorderCls} bg-gray-50 dark:bg-gray-700 text-gray-500 dark:text-gray-400 rounded-r-md text-sm`, children: suffix })
538
628
  ] }),
539
629
  errorNode,
540
630
  helperNode
541
631
  ] });
542
632
  };
633
+ var SIZE_CLASSES2 = {
634
+ small: "px-2 py-1 text-xs",
635
+ medium: "px-3 py-2 text-sm",
636
+ large: "px-4 py-3 text-base"
637
+ };
638
+ var VARIANT_CLASSES2 = {
639
+ default: "border border-gray-300 dark:border-gray-600 bg-white dark:bg-gray-800",
640
+ outline: "border-2 border-indigo-300 dark:border-indigo-600 bg-transparent",
641
+ filled: "border border-gray-300 dark:border-gray-600 bg-gray-100 dark:bg-gray-700",
642
+ minimal: "border-0 border-b border-gray-300 dark:border-gray-600 bg-transparent rounded-none focus:ring-0"
643
+ };
644
+ var RESIZE_CLASSES = {
645
+ vertical: "resize-y",
646
+ horizontal: "resize-x",
647
+ both: "resize",
648
+ none: "resize-none"
649
+ };
543
650
  var TextArea = ({
544
651
  label,
545
652
  error,
546
653
  helperText,
547
654
  variant = "default",
548
655
  size = "medium",
656
+ autoResize = false,
657
+ showCount = false,
658
+ resize = "vertical",
549
659
  className = "",
550
660
  id,
661
+ onInput: propsOnInput,
551
662
  ...props
552
663
  }) => {
553
664
  const textAreaId = id || `textarea-${Math.random().toString(36).substring(2, 9)}`;
554
- const sizeClasses = {
555
- small: "px-2 py-1 text-xs",
556
- medium: "px-3 py-2 text-sm",
557
- large: "px-4 py-3 text-base"
665
+ const textareaRef = react.useRef(null);
666
+ const adjustHeight = () => {
667
+ const el = textareaRef.current;
668
+ if (!el) return;
669
+ el.style.height = "auto";
670
+ el.style.height = `${el.scrollHeight}px`;
558
671
  };
559
- const variantClasses = {
560
- default: "border-gray-300 dark:border-gray-600 bg-white dark:bg-gray-800",
561
- outline: "border-2 border-indigo-300 dark:border-indigo-600 bg-transparent",
562
- filled: "border-gray-300 dark:border-gray-600 bg-gray-100 dark:bg-gray-700",
563
- minimal: "border-0 bg-transparent focus:ring-0 focus:border-0"
672
+ react.useEffect(() => {
673
+ if (autoResize) adjustHeight();
674
+ }, [autoResize, props.value]);
675
+ const handleInput = (e) => {
676
+ if (autoResize) adjustHeight();
677
+ propsOnInput?.(e);
564
678
  };
565
- const baseClasses = "appearance-none relative block w-full placeholder-gray-500 dark:placeholder-gray-400 text-gray-900 dark:text-white rounded-md border focus:outline-none focus:ring-2 focus:ring-indigo-500 dark:focus:ring-indigo-400 focus:border-indigo-500 focus:z-10 disabled:opacity-50 disabled:cursor-not-allowed transition-colors duration-200 resize-y";
566
- const errorClasses = error ? "border-red-300 dark:border-red-600 focus:ring-red-500 dark:focus:ring-red-400 focus:border-red-500" : "";
567
- const classes = `${baseClasses} ${sizeClasses[size]} ${variantClasses[variant]} ${errorClasses} ${className}`;
679
+ const baseCls = "appearance-none relative block w-full placeholder-gray-500 dark:placeholder-gray-400 text-gray-900 dark:text-white rounded-md border focus:outline-none focus:ring-2 focus:ring-indigo-500 dark:focus:ring-indigo-400 focus:border-indigo-500 focus:z-10 disabled:opacity-50 disabled:cursor-not-allowed transition-colors duration-200";
680
+ const errorCls = error ? "border-red-300 dark:border-red-600 focus:ring-red-500 dark:focus:ring-red-400 focus:border-red-500" : "";
681
+ const resizeCls = autoResize ? "resize-none overflow-hidden" : RESIZE_CLASSES[resize];
682
+ const classes = [baseCls, SIZE_CLASSES2[size], VARIANT_CLASSES2[variant], errorCls, resizeCls, className].filter(Boolean).join(" ");
683
+ const maxLength = typeof props.maxLength === "number" ? props.maxLength : void 0;
684
+ const currentLength = typeof props.value === "string" ? props.value.length : typeof props.value === "number" ? String(props.value).length : 0;
685
+ const overLimit = maxLength !== void 0 && currentLength > maxLength;
568
686
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-1 w-full", children: [
569
- label && typeof label === "string" ? /* @__PURE__ */ jsxRuntime.jsx(
570
- "label",
571
- {
572
- htmlFor: textAreaId,
573
- className: "block text-sm font-medium text-gray-700 dark:text-gray-300",
574
- children: label
575
- }
576
- ) : label,
687
+ (label || showCount) && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-baseline gap-2", children: [
688
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1", children: label && (typeof label === "string" ? /* @__PURE__ */ jsxRuntime.jsxs("label", { htmlFor: textAreaId, className: "block text-sm font-medium text-gray-700 dark:text-gray-300", children: [
689
+ label,
690
+ props.required && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "ml-1 text-red-500", "aria-hidden": "true", children: "*" })
691
+ ] }) : label) }),
692
+ showCount && /* @__PURE__ */ jsxRuntime.jsx("span", { className: `text-xs shrink-0 tabular-nums ${overLimit ? "text-red-500" : "text-gray-400 dark:text-gray-500"}`, children: maxLength ? `${currentLength} / ${maxLength}` : currentLength })
693
+ ] }),
577
694
  /* @__PURE__ */ jsxRuntime.jsx(
578
695
  "textarea",
579
696
  {
697
+ ref: textareaRef,
580
698
  id: textAreaId,
581
699
  className: classes,
700
+ onInput: handleInput,
582
701
  ...props
583
702
  }
584
703
  ),
@@ -586,80 +705,125 @@ var TextArea = ({
586
705
  helperText && !error && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-gray-500 dark:text-gray-400", children: helperText })
587
706
  ] });
588
707
  };
589
- var Form = ({ onSubmit, children, variant = "default", className = "", ...props }) => {
708
+ var Form = ({
709
+ onSubmit,
710
+ children,
711
+ variant = "default",
712
+ columns,
713
+ className = "",
714
+ style,
715
+ ...props
716
+ }) => {
590
717
  const handleSubmit = (e) => {
591
718
  e.preventDefault();
592
- if (onSubmit) {
593
- onSubmit(e);
594
- }
719
+ onSubmit?.(e);
595
720
  };
721
+ const hasGrid = columns !== void 0 && columns > 1;
596
722
  const getVariantClasses = () => {
597
723
  switch (variant) {
598
724
  case "modal":
599
725
  return "flex-1 px-6 py-4 overflow-y-auto";
600
726
  case "card":
601
- return "p-6 space-y-6";
727
+ return `bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-700 rounded-xl shadow-sm p-6${hasGrid ? "" : " space-y-6"}`;
602
728
  case "inline":
603
- return "flex flex-wrap gap-4 items-end";
729
+ return hasGrid ? "" : "flex flex-wrap gap-4 items-end";
604
730
  case "compact":
605
- return "space-y-3";
731
+ return hasGrid ? "" : "space-y-3";
606
732
  case "default":
607
733
  default:
608
- return "space-y-4";
734
+ return hasGrid ? "" : "space-y-4";
609
735
  }
610
736
  };
611
- const combinedClassName = `${getVariantClasses()} ${className}`.trim();
612
- return /* @__PURE__ */ jsxRuntime.jsx("form", { onSubmit: handleSubmit, className: combinedClassName, ...props, children });
737
+ const gridStyle = hasGrid ? { display: "grid", gridTemplateColumns: `repeat(${columns}, minmax(0, 1fr))`, gap: "1rem" } : {};
738
+ const combinedClassName = [getVariantClasses(), className].filter(Boolean).join(" ");
739
+ const combinedStyle = { ...gridStyle, ...style };
740
+ return /* @__PURE__ */ jsxRuntime.jsx(
741
+ "form",
742
+ {
743
+ onSubmit: handleSubmit,
744
+ className: combinedClassName,
745
+ style: Object.keys(combinedStyle).length > 0 ? combinedStyle : void 0,
746
+ ...props,
747
+ children
748
+ }
749
+ );
750
+ };
751
+ var SIZE_CLASSES3 = {
752
+ sm: "py-1.5 text-xs",
753
+ md: "py-2 text-sm",
754
+ lg: "py-2.5 text-base"
755
+ };
756
+ var VARIANT_CLASSES3 = {
757
+ default: "border border-gray-300 dark:border-gray-600 bg-white dark:bg-gray-800",
758
+ outline: "border-2 border-indigo-300 dark:border-indigo-600 bg-transparent",
759
+ filled: "border border-gray-300 dark:border-gray-600 bg-gray-100 dark:bg-gray-700",
760
+ minimal: "border-0 border-b border-gray-300 dark:border-gray-600 bg-transparent rounded-none focus:ring-0",
761
+ custom: ""
613
762
  };
614
763
  var Select = ({
615
764
  options,
616
765
  placeholder,
617
766
  variant = "default",
767
+ size = "md",
618
768
  error = false,
619
769
  helperText,
620
770
  label,
771
+ icon,
621
772
  className = "",
622
773
  id,
623
774
  ...props
624
775
  }) => {
625
776
  const selectId = id || `select-${Math.random().toString(36).substring(2, 9)}`;
626
- const getVariantClasses = () => {
627
- const baseClasses = "appearance-none relative block w-full px-3 py-2 border placeholder-gray-500 dark:placeholder-gray-400 text-gray-900 dark:text-white bg-white dark:bg-gray-800 rounded-md focus:outline-none focus:ring-2 focus:ring-indigo-500 dark:focus:ring-indigo-400 focus:border-indigo-500 focus:z-10 sm:text-sm disabled:opacity-50 disabled:cursor-not-allowed transition-colors duration-200";
628
- if (variant === "small") {
629
- return `${baseClasses.replace("px-3 py-2", "px-2.5 py-1.5 text-sm")} border-gray-300 dark:border-gray-600`;
630
- }
631
- return `${baseClasses} border-gray-300 dark:border-gray-600 ${error ? "border-red-300 dark:border-red-600 focus:ring-red-500 dark:focus:ring-red-400 focus:border-red-500" : ""}`;
632
- };
633
- const getOptionClasses = (option) => {
634
- return `bg-white dark:bg-gray-800 text-gray-900 dark:text-white py-2 ${option.disabled ? "opacity-50 cursor-not-allowed" : ""}`;
635
- };
636
- const combinedClassName = `${getVariantClasses()} ${className}`.trim();
777
+ const effectiveSize = variant === "small" ? "sm" : size;
778
+ const effectiveVariant = variant === "small" ? "default" : variant;
779
+ const hasError = Boolean(error);
780
+ const errorMsg = typeof error === "string" ? error : "";
781
+ const computedDefaultValue = props.value === void 0 && props.defaultValue === void 0 ? options.find((o) => o.selected)?.value?.toString() : void 0;
782
+ const baseCls = "appearance-none relative block w-full pl-3 pr-9 placeholder-gray-500 dark:placeholder-gray-400 text-gray-900 dark:text-white rounded-md focus:outline-none focus:ring-2 focus:ring-indigo-500 dark:focus:ring-indigo-400 focus:border-indigo-500 focus:z-10 disabled:opacity-50 disabled:cursor-not-allowed transition-colors duration-200";
783
+ const errorCls = hasError ? "border-red-300 dark:border-red-600 focus:ring-red-500 dark:focus:ring-red-400 focus:border-red-500" : "";
784
+ const selectCls = [
785
+ baseCls,
786
+ SIZE_CLASSES3[effectiveSize],
787
+ VARIANT_CLASSES3[effectiveVariant],
788
+ errorCls,
789
+ icon ? "pl-9" : "",
790
+ className
791
+ ].filter(Boolean).join(" ");
637
792
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-1 w-full", children: [
638
- label && typeof label === "string" ? /* @__PURE__ */ jsxRuntime.jsx("label", { htmlFor: selectId, className: "block text-sm font-medium text-gray-700 dark:text-gray-300", children: label }) : label,
639
- /* @__PURE__ */ jsxRuntime.jsxs("select", { id: selectId, className: combinedClassName, ...props, children: [
640
- placeholder && placeholder.trim() && /* @__PURE__ */ jsxRuntime.jsx("option", { value: "", disabled: true, selected: true, className: "bg-white dark:bg-gray-800 text-gray-500 dark:text-gray-400 py-2", children: placeholder }),
641
- options.map((option) => /* @__PURE__ */ jsxRuntime.jsx(
642
- "option",
793
+ label && (typeof label === "string" ? /* @__PURE__ */ jsxRuntime.jsxs("label", { htmlFor: selectId, className: "block text-sm font-medium text-gray-700 dark:text-gray-300", children: [
794
+ label,
795
+ props.required && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "ml-1 text-red-500", "aria-hidden": "true", children: "*" })
796
+ ] }) : label),
797
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative", children: [
798
+ icon && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pointer-events-none absolute inset-y-0 left-0 z-10 flex items-center pl-3 text-gray-400 dark:text-gray-500", children: icon }),
799
+ /* @__PURE__ */ jsxRuntime.jsxs(
800
+ "select",
643
801
  {
644
- value: option.value,
645
- disabled: option.disabled,
646
- selected: option.selected,
647
- className: getOptionClasses(option),
648
- children: option.label
649
- },
650
- option.value
651
- ))
802
+ id: selectId,
803
+ className: selectCls,
804
+ defaultValue: computedDefaultValue,
805
+ ...props,
806
+ children: [
807
+ placeholder && /* @__PURE__ */ jsxRuntime.jsx("option", { value: "", disabled: true, className: "bg-white dark:bg-gray-800 text-gray-500 dark:text-gray-400", children: placeholder }),
808
+ options.map((option) => /* @__PURE__ */ jsxRuntime.jsx(
809
+ "option",
810
+ {
811
+ value: option.value,
812
+ disabled: option.disabled,
813
+ className: `bg-white dark:bg-gray-800 text-gray-900 dark:text-white${option.disabled ? " opacity-50" : ""}`,
814
+ children: option.label
815
+ },
816
+ option.value
817
+ ))
818
+ ]
819
+ }
820
+ ),
821
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pointer-events-none absolute inset-y-0 right-0 flex items-center pr-2.5 text-gray-400 dark:text-gray-500", children: /* @__PURE__ */ jsxRuntime.jsx(ChevronDownIcon, { className: "w-4 h-4" }) })
652
822
  ] }),
653
- helperText && /* @__PURE__ */ jsxRuntime.jsx("p", { className: `text-sm ${error ? "text-red-600 dark:text-red-400" : "text-gray-500 dark:text-gray-400"}`, children: helperText })
823
+ errorMsg && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-red-600 dark:text-red-400", role: "alert", children: errorMsg }),
824
+ helperText && !errorMsg && /* @__PURE__ */ jsxRuntime.jsx("p", { className: `text-sm ${hasError ? "text-red-600 dark:text-red-400" : "text-gray-500 dark:text-gray-400"}`, children: helperText })
654
825
  ] });
655
826
  };
656
- function isColumnDef(col) {
657
- return typeof col === "object" && col !== null && "header" in col;
658
- }
659
- function resolveColumn(col) {
660
- if (isColumnDef(col)) return col;
661
- return { header: col };
662
- }
663
827
  var ALIGN_CLASS = {
664
828
  left: "text-left",
665
829
  center: "text-center",
@@ -680,6 +844,10 @@ var VARIANT_TABLE = {
680
844
  striped: "w-full min-w-full table-auto",
681
845
  bordered: "w-full min-w-full table-auto border border-gray-300 dark:border-gray-600",
682
846
  minimal: "w-full min-w-full table-auto",
847
+ ghost: "w-full min-w-full table-auto",
848
+ card: "w-full min-w-full table-auto",
849
+ accent: "w-full min-w-full table-auto",
850
+ dark: "w-full min-w-full table-auto",
683
851
  custom: "w-full min-w-full table-auto"
684
852
  };
685
853
  var VARIANT_THEAD = {
@@ -687,6 +855,10 @@ var VARIANT_THEAD = {
687
855
  striped: "bg-gray-100 dark:bg-gray-700",
688
856
  bordered: "bg-gray-100 dark:bg-gray-700",
689
857
  minimal: "",
858
+ ghost: "",
859
+ card: "bg-gray-50 dark:bg-gray-800/80",
860
+ accent: "bg-blue-600 dark:bg-blue-700",
861
+ dark: "bg-gray-800 dark:bg-gray-900",
690
862
  custom: ""
691
863
  };
692
864
  var VARIANT_TH = {
@@ -694,13 +866,43 @@ var VARIANT_TH = {
694
866
  striped: "font-semibold uppercase tracking-wider text-gray-600 dark:text-gray-300",
695
867
  bordered: "font-semibold uppercase tracking-wider text-gray-600 dark:text-gray-300 border border-gray-300 dark:border-gray-600",
696
868
  minimal: "font-semibold text-gray-500 dark:text-gray-400 border-b border-gray-200 dark:border-gray-700",
869
+ ghost: "font-semibold text-gray-600 dark:text-gray-400 border-b-2 border-gray-300 dark:border-gray-600",
870
+ card: "font-semibold text-gray-600 dark:text-gray-300 border-b border-gray-200 dark:border-gray-700",
871
+ accent: "font-semibold uppercase tracking-wider text-white",
872
+ dark: "font-semibold uppercase tracking-wider text-gray-100",
697
873
  custom: ""
698
874
  };
699
- var VARIANT_TR = {
700
- default: () => "bg-white dark:bg-gray-800 hover:bg-gray-50 dark:hover:bg-gray-700/60 transition-colors",
701
- striped: (i) => `${i % 2 === 0 ? "bg-white dark:bg-gray-800" : "bg-gray-50 dark:bg-gray-700/40"} hover:bg-blue-50 dark:hover:bg-blue-900/20 transition-colors`,
702
- bordered: () => "bg-white dark:bg-gray-800 hover:bg-gray-50 dark:hover:bg-gray-700/60 transition-colors",
703
- minimal: () => "hover:bg-gray-50 dark:hover:bg-gray-800/60 transition-colors",
875
+ var VARIANT_TR_BASE = {
876
+ default: "bg-white dark:bg-gray-800",
877
+ striped: "",
878
+ bordered: "bg-white dark:bg-gray-800",
879
+ minimal: "",
880
+ ghost: "",
881
+ card: "bg-white dark:bg-gray-900",
882
+ accent: "bg-white dark:bg-gray-800",
883
+ dark: "bg-white dark:bg-gray-800",
884
+ custom: ""
885
+ };
886
+ var VARIANT_TR_HOVER = {
887
+ default: "hover:bg-gray-50 dark:hover:bg-gray-700/60",
888
+ striped: "hover:bg-blue-50 dark:hover:bg-blue-900/20",
889
+ bordered: "hover:bg-gray-50 dark:hover:bg-gray-700/60",
890
+ minimal: "hover:bg-gray-50 dark:hover:bg-gray-800/60",
891
+ ghost: "hover:bg-gray-50/70 dark:hover:bg-white/5",
892
+ card: "hover:bg-gray-50 dark:hover:bg-gray-800/50",
893
+ accent: "hover:bg-blue-50 dark:hover:bg-blue-900/20",
894
+ dark: "hover:bg-gray-50 dark:hover:bg-gray-700/60",
895
+ custom: ""
896
+ };
897
+ var VARIANT_TR_STRIPE = {
898
+ default: () => "",
899
+ striped: (i) => i % 2 === 0 ? "bg-white dark:bg-gray-800" : "bg-gray-50 dark:bg-gray-700/40",
900
+ bordered: () => "",
901
+ minimal: () => "",
902
+ ghost: () => "",
903
+ card: () => "",
904
+ accent: () => "",
905
+ dark: () => "",
704
906
  custom: () => ""
705
907
  };
706
908
  var VARIANT_TD = {
@@ -708,6 +910,10 @@ var VARIANT_TD = {
708
910
  striped: "text-gray-700 dark:text-gray-300",
709
911
  bordered: "text-gray-700 dark:text-gray-300 border border-gray-200 dark:border-gray-700",
710
912
  minimal: "text-gray-700 dark:text-gray-300 border-b border-gray-100 dark:border-gray-800",
913
+ ghost: "text-gray-700 dark:text-gray-300",
914
+ card: "text-gray-700 dark:text-gray-300",
915
+ accent: "text-gray-700 dark:text-gray-300",
916
+ dark: "text-gray-700 dark:text-gray-300",
711
917
  custom: ""
712
918
  };
713
919
  var VARIANT_TBODY_DIVIDER = {
@@ -715,8 +921,33 @@ var VARIANT_TBODY_DIVIDER = {
715
921
  striped: "",
716
922
  bordered: "",
717
923
  minimal: "",
924
+ ghost: "divide-y divide-gray-200 dark:divide-gray-700",
925
+ card: "divide-y divide-gray-100 dark:divide-gray-800",
926
+ accent: "divide-y divide-gray-200 dark:divide-gray-700",
927
+ dark: "divide-y divide-gray-200 dark:divide-gray-700",
718
928
  custom: ""
719
929
  };
930
+ function SortIcon({ direction }) {
931
+ if (direction === "asc") return /* @__PURE__ */ jsxRuntime.jsx(SortAscIcon, { className: "inline-block ml-1 w-3 h-3 shrink-0" });
932
+ if (direction === "desc") return /* @__PURE__ */ jsxRuntime.jsx(SortDescIcon, { className: "inline-block ml-1 w-3 h-3 shrink-0" });
933
+ return /* @__PURE__ */ jsxRuntime.jsx(SortBothIcon, { className: "inline-block ml-1 w-3 h-3 shrink-0 opacity-40" });
934
+ }
935
+ function SkeletonRow({ colCount, size }) {
936
+ return /* @__PURE__ */ jsxRuntime.jsx("tr", { children: Array.from({ length: colCount }).map((_, i) => /* @__PURE__ */ jsxRuntime.jsx("td", { className: SIZE_TD[size], children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-4 rounded bg-gray-200 dark:bg-gray-700 animate-pulse" }) }, i)) });
937
+ }
938
+ function isColumnDef(col) {
939
+ return typeof col === "object" && col !== null && "header" in col;
940
+ }
941
+ function resolveColumn(col) {
942
+ if (isColumnDef(col)) return col;
943
+ return { header: col };
944
+ }
945
+ function colSizeStyle(col) {
946
+ const s = {};
947
+ if (col.width !== void 0) s.width = col.width;
948
+ if (col.minWidth !== void 0) s.minWidth = col.minWidth;
949
+ return s;
950
+ }
720
951
  function Table({
721
952
  columns,
722
953
  rows,
@@ -730,46 +961,84 @@ function Table({
730
961
  emptyState,
731
962
  onRowClick,
732
963
  hideHeader = false,
733
- style
964
+ style,
965
+ stickyHeader = false,
966
+ caption,
967
+ footerRows,
968
+ loading = false,
969
+ loadingRows = 4,
970
+ getRowStyle,
971
+ rounded = false,
972
+ shadow = false,
973
+ hoverable = true,
974
+ sortState,
975
+ onSort
734
976
  }) {
735
977
  const cols = columns.map(resolveColumn);
736
978
  const resolvedTrClass = (i) => {
737
- const variantCls = VARIANT_TR[variant](i);
979
+ const stripeCls = VARIANT_TR_STRIPE[variant](i);
980
+ const baseCls = stripeCls || VARIANT_TR_BASE[variant];
981
+ const hoverCls = hoverable ? `${VARIANT_TR_HOVER[variant]} transition-colors` : "";
738
982
  const clickCls = onRowClick ? "cursor-pointer" : "";
739
983
  const customCls = typeof trClassName === "function" ? trClassName(i) : trClassName ?? "";
740
- return `${variantCls} ${clickCls} ${customCls}`.trim();
984
+ return [baseCls, hoverCls, clickCls, customCls].filter(Boolean).join(" ");
741
985
  };
742
- return /* @__PURE__ */ jsxRuntime.jsx("div", { className: `overflow-x-auto w-full ${className}`.trim(), children: /* @__PURE__ */ jsxRuntime.jsxs(
986
+ const wrapperCls = [
987
+ "overflow-x-auto w-full",
988
+ rounded ? "rounded-lg overflow-hidden" : "",
989
+ shadow ? "shadow-md" : "",
990
+ className
991
+ ].filter(Boolean).join(" ");
992
+ const theadCls = [
993
+ VARIANT_THEAD[variant],
994
+ stickyHeader ? "sticky top-0 z-20" : ""
995
+ ].filter(Boolean).join(" ");
996
+ const stickyColCls = "sticky left-0 z-10 bg-inherit";
997
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: wrapperCls, children: /* @__PURE__ */ jsxRuntime.jsxs(
743
998
  "table",
744
999
  {
745
1000
  className: `${VARIANT_TABLE[variant]} ${tableClassName}`.trim(),
746
1001
  style,
747
1002
  children: [
748
- !hideHeader && /* @__PURE__ */ jsxRuntime.jsx("thead", { className: VARIANT_THEAD[variant], children: /* @__PURE__ */ jsxRuntime.jsx("tr", { children: cols.map((col, i) => /* @__PURE__ */ jsxRuntime.jsx(
749
- "th",
750
- {
751
- className: [
752
- SIZE_TH[size],
753
- VARIANT_TH[variant],
754
- ALIGN_CLASS[col.align ?? "left"],
755
- col.className ?? "",
756
- thClassName
757
- ].filter(Boolean).join(" "),
758
- children: col.header
759
- },
760
- i
761
- )) }) }),
762
- /* @__PURE__ */ jsxRuntime.jsx("tbody", { className: VARIANT_TBODY_DIVIDER[variant], children: rows.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx("tr", { children: /* @__PURE__ */ jsxRuntime.jsx(
1003
+ caption && /* @__PURE__ */ jsxRuntime.jsx("caption", { className: "mb-2 text-left text-sm text-gray-500 dark:text-gray-400", children: caption }),
1004
+ !hideHeader && /* @__PURE__ */ jsxRuntime.jsx("thead", { className: theadCls, children: /* @__PURE__ */ jsxRuntime.jsx("tr", { children: cols.map((col, i) => {
1005
+ const isSortable = col.sortable && col.key;
1006
+ const activeSort = sortState?.key === col.key ? sortState.direction : null;
1007
+ return /* @__PURE__ */ jsxRuntime.jsxs(
1008
+ "th",
1009
+ {
1010
+ scope: "col",
1011
+ className: [
1012
+ SIZE_TH[size],
1013
+ VARIANT_TH[variant],
1014
+ ALIGN_CLASS[col.align ?? "left"],
1015
+ col.className ?? "",
1016
+ thClassName,
1017
+ col.sticky ? stickyColCls : "",
1018
+ isSortable ? "cursor-pointer select-none" : ""
1019
+ ].filter(Boolean).join(" "),
1020
+ style: { ...colSizeStyle(col), ...col.thStyle ?? {} },
1021
+ onClick: isSortable ? () => onSort?.(col.key) : void 0,
1022
+ children: [
1023
+ col.header,
1024
+ isSortable && /* @__PURE__ */ jsxRuntime.jsx(SortIcon, { direction: activeSort })
1025
+ ]
1026
+ },
1027
+ i
1028
+ );
1029
+ }) }) }),
1030
+ /* @__PURE__ */ jsxRuntime.jsx("tbody", { className: VARIANT_TBODY_DIVIDER[variant], children: loading ? Array.from({ length: loadingRows }).map((_, i) => /* @__PURE__ */ jsxRuntime.jsx(SkeletonRow, { colCount: cols.length, size }, i)) : rows.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx("tr", { children: /* @__PURE__ */ jsxRuntime.jsx(
763
1031
  "td",
764
1032
  {
765
1033
  colSpan: cols.length,
766
- className: `${SIZE_TD[size]} text-center text-gray-400 dark:text-gray-500 py-8`,
1034
+ className: `${SIZE_TD[size]} py-8 text-center text-gray-400 dark:text-gray-500`,
767
1035
  children: emptyState ?? "Sin datos"
768
1036
  }
769
1037
  ) }) : rows.map((row, rowIndex) => /* @__PURE__ */ jsxRuntime.jsx(
770
1038
  "tr",
771
1039
  {
772
1040
  className: resolvedTrClass(rowIndex),
1041
+ style: getRowStyle?.(rowIndex),
773
1042
  onClick: onRowClick ? () => onRowClick(rowIndex) : void 0,
774
1043
  children: row.map((cell, cellIndex) => {
775
1044
  const col = cols[cellIndex];
@@ -781,8 +1050,13 @@ function Table({
781
1050
  VARIANT_TD[variant],
782
1051
  ALIGN_CLASS[col?.align ?? "left"],
783
1052
  col?.className ?? "",
784
- tdClassName
1053
+ tdClassName,
1054
+ col?.sticky ? stickyColCls : ""
785
1055
  ].filter(Boolean).join(" "),
1056
+ style: {
1057
+ ...col ? colSizeStyle(col) : {},
1058
+ ...col?.tdStyle ?? {}
1059
+ },
786
1060
  children: cell
787
1061
  },
788
1062
  cellIndex
@@ -790,47 +1064,100 @@ function Table({
790
1064
  })
791
1065
  },
792
1066
  rowIndex
793
- )) })
1067
+ )) }),
1068
+ footerRows && footerRows.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("tfoot", { className: "border-t border-gray-200 bg-gray-50 dark:border-gray-700 dark:bg-gray-800/50", children: footerRows.map((row, rowIndex) => /* @__PURE__ */ jsxRuntime.jsx("tr", { children: row.map((cell, cellIndex) => {
1069
+ const col = cols[cellIndex];
1070
+ return /* @__PURE__ */ jsxRuntime.jsx(
1071
+ "td",
1072
+ {
1073
+ className: [
1074
+ SIZE_TD[size],
1075
+ "font-medium text-gray-700 dark:text-gray-300",
1076
+ ALIGN_CLASS[col?.align ?? "left"],
1077
+ col?.className ?? "",
1078
+ tdClassName
1079
+ ].filter(Boolean).join(" "),
1080
+ style: col?.tdStyle,
1081
+ children: cell
1082
+ },
1083
+ cellIndex
1084
+ );
1085
+ }) }, rowIndex)) })
794
1086
  ]
795
1087
  }
796
1088
  ) });
797
1089
  }
1090
+ var SIZE_CLASS = {
1091
+ sm: "max-w-sm",
1092
+ md: "max-w-md",
1093
+ lg: "max-w-2xl",
1094
+ xl: "max-w-4xl",
1095
+ full: "max-w-[95vw] w-[95vw]"
1096
+ };
1097
+ var VARIANT_HEADER = {
1098
+ default: "bg-gray-50 dark:bg-gray-800 border-b border-gray-200 dark:border-gray-700",
1099
+ danger: "bg-red-50 dark:bg-red-900/30 border-b border-red-200 dark:border-red-800",
1100
+ success: "bg-green-50 dark:bg-green-900/30 border-b border-green-200 dark:border-green-800",
1101
+ warning: "bg-yellow-50 dark:bg-yellow-900/30 border-b border-yellow-200 dark:border-yellow-800"
1102
+ };
1103
+ var VARIANT_TITLE = {
1104
+ default: "text-gray-900 dark:text-white",
1105
+ danger: "text-red-700 dark:text-red-300",
1106
+ success: "text-green-700 dark:text-green-300",
1107
+ warning: "text-yellow-700 dark:text-yellow-300"
1108
+ };
798
1109
  var Modal = react.forwardRef(({
799
1110
  onClose,
800
1111
  title,
801
1112
  children,
802
1113
  footer,
803
- maxWidth = "max-w-2xl",
1114
+ maxWidth,
1115
+ size,
804
1116
  showCloseButton = true,
805
- zIndex = 50
1117
+ zIndex = 50,
1118
+ closeOnBackdrop = false,
1119
+ closeOnEsc = false,
1120
+ variant = "default"
806
1121
  }, ref) => {
807
1122
  const [show, setShow] = react.useState(false);
1123
+ const handleCloseRef = react.useRef(() => {
1124
+ });
1125
+ const handleClose = () => {
1126
+ setShow(false);
1127
+ setTimeout(() => onClose(), 300);
1128
+ };
1129
+ handleCloseRef.current = handleClose;
808
1130
  react.useEffect(() => {
809
1131
  setShow(true);
810
1132
  }, []);
811
- const handleClose = () => {
812
- setShow(false);
813
- setTimeout(() => {
814
- onClose();
815
- }, 300);
1133
+ react.useEffect(() => {
1134
+ if (!closeOnEsc) return;
1135
+ const handler = (e) => {
1136
+ if (e.key === "Escape") handleCloseRef.current();
1137
+ };
1138
+ document.addEventListener("keydown", handler);
1139
+ return () => document.removeEventListener("keydown", handler);
1140
+ }, [closeOnEsc]);
1141
+ react.useImperativeHandle(ref, () => ({ handleClose }));
1142
+ const widthCls = size ? SIZE_CLASS[size] : maxWidth ?? "max-w-2xl";
1143
+ const handleBackdropClick = (e) => {
1144
+ if (closeOnBackdrop && e.target === e.currentTarget) handleClose();
816
1145
  };
817
- react.useImperativeHandle(ref, () => ({
818
- handleClose
819
- }));
820
1146
  return /* @__PURE__ */ jsxRuntime.jsx(
821
1147
  "dialog",
822
1148
  {
823
1149
  open: show,
824
- className: `fixed inset-0 w-full h-full flex items-center justify-center p-4 ${show && "opacity-100"} transition-opacity opacity-0 duration-300 bg-gray-900/60 backdrop-blur-sm`,
1150
+ className: `fixed inset-0 w-full h-full flex items-center justify-center p-4 transition-opacity duration-300 bg-gray-900/60 backdrop-blur-sm ${show ? "opacity-100" : "opacity-0"}`,
825
1151
  style: { zIndex: zIndex - 10 },
1152
+ onClick: handleBackdropClick,
826
1153
  children: /* @__PURE__ */ jsxRuntime.jsxs(
827
1154
  "article",
828
1155
  {
829
- className: `relative bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-700 rounded-lg shadow-2xl w-full ${maxWidth} max-h-[90vh] flex flex-col overflow-hidden`,
1156
+ className: `relative bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-700 rounded-lg shadow-2xl w-full ${widthCls} max-h-[90vh] flex flex-col overflow-hidden`,
830
1157
  style: { zIndex },
831
1158
  children: [
832
- /* @__PURE__ */ jsxRuntime.jsxs("header", { className: "shrink-0 bg-gray-50 dark:bg-gray-800 border-b border-gray-200 dark:border-gray-700 px-6 py-4 flex items-center justify-between", children: [
833
- /* @__PURE__ */ jsxRuntime.jsx("h2", { className: "text-2xl font-bold text-gray-900 dark:text-white", children: title }),
1159
+ /* @__PURE__ */ jsxRuntime.jsxs("header", { className: `shrink-0 px-6 py-4 flex items-center justify-between ${VARIANT_HEADER[variant]}`, children: [
1160
+ /* @__PURE__ */ jsxRuntime.jsx("h2", { className: `text-2xl font-bold ${VARIANT_TITLE[variant]}`, children: title }),
834
1161
  showCloseButton && /* @__PURE__ */ jsxRuntime.jsx(
835
1162
  Button,
836
1163
  {
@@ -855,7 +1182,9 @@ var Loading = ({
855
1182
  size = "medium",
856
1183
  color = "primary",
857
1184
  label,
858
- className = ""
1185
+ className = "",
1186
+ overlay = false,
1187
+ fullPage = false
859
1188
  }) => {
860
1189
  const sizeClasses = {
861
1190
  small: "h-4 w-4",
@@ -874,13 +1203,14 @@ var Loading = ({
874
1203
  const renderIcon = () => {
875
1204
  const commonClass = `${sizeClasses[size]} ${colorClasses[color]}`;
876
1205
  switch (variant) {
877
- case "dots":
1206
+ case "dots": {
878
1207
  const dotSize = size === "small" ? "h-1 w-1" : size === "medium" ? "h-2 w-2" : size === "large" ? "h-3 w-3" : "h-4 w-4";
879
1208
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `flex space-x-1 ${colorClasses[color]}`, children: [
880
1209
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: `rounded-full bg-current animate-bounce ${dotSize}`, style: { animationDelay: "0s" } }),
881
1210
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: `rounded-full bg-current animate-bounce ${dotSize}`, style: { animationDelay: "0.15s" } }),
882
1211
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: `rounded-full bg-current animate-bounce ${dotSize}`, style: { animationDelay: "0.3s" } })
883
1212
  ] });
1213
+ }
884
1214
  case "bars":
885
1215
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `flex items-end space-x-1 ${sizeClasses[size]} ${colorClasses[color]}`, children: [
886
1216
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-1/4 bg-current animate-[pulse_1s_ease-in-out_infinite]", style: { height: "60%", animationDelay: "0s" } }),
@@ -912,6 +1242,16 @@ var Loading = ({
912
1242
  ] });
913
1243
  }
914
1244
  };
1245
+ const inner = /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `flex flex-col items-center justify-center ${className}`, role: "status", children: [
1246
+ renderIcon(),
1247
+ label && /* @__PURE__ */ jsxRuntime.jsx("span", { className: `mt-3 text-sm font-medium ${colorClasses[color]}`, children: label })
1248
+ ] });
1249
+ if (fullPage) {
1250
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "fixed inset-0 z-50 flex items-center justify-center bg-gray-900/50 backdrop-blur-sm", children: inner });
1251
+ }
1252
+ if (overlay) {
1253
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute inset-0 z-10 flex items-center justify-center bg-gray-900/40 backdrop-blur-sm rounded-[inherit]", children: inner });
1254
+ }
915
1255
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `flex flex-col items-center justify-center w-full h-full min-h-[inherit] ${className}`, role: "status", children: [
916
1256
  renderIcon(),
917
1257
  label && /* @__PURE__ */ jsxRuntime.jsx("span", { className: `mt-3 text-sm font-medium ${colorClasses[color]}`, children: label })
@@ -4220,6 +4560,7 @@ exports.CategorieIcon = CategorieIcon;
4220
4560
  exports.ChartIcon = ChartIcon;
4221
4561
  exports.CheckCircleIcon = CheckCircleIcon;
4222
4562
  exports.CheckIcon = CheckIcon;
4563
+ exports.ChevronDownIcon = ChevronDownIcon;
4223
4564
  exports.ClockIcon = ClockIcon;
4224
4565
  exports.CloseIcon = CloseIcon;
4225
4566
  exports.CloudIcon = CloudIcon;
@@ -4275,6 +4616,9 @@ exports.SaveIcon = SaveIcon;
4275
4616
  exports.SearchIcon = SearchIcon;
4276
4617
  exports.Select = Select;
4277
4618
  exports.ShieldIcon = ShieldIcon;
4619
+ exports.SortAscIcon = SortAscIcon;
4620
+ exports.SortBothIcon = SortBothIcon;
4621
+ exports.SortDescIcon = SortDescIcon;
4278
4622
  exports.SpinnerIcon = SpinnerIcon;
4279
4623
  exports.StackIcon = StackIcon;
4280
4624
  exports.SunIcon = SunIcon;