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.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
2
- import { forwardRef, useState, useEffect, useImperativeHandle, createContext, useContext, useCallback, useRef, useMemo } from 'react';
2
+ import { forwardRef, useState, useRef, useEffect, useImperativeHandle, createContext, useContext, useCallback, useMemo } from 'react';
3
3
  import Swal from 'sweetalert2';
4
4
 
5
5
  // src/components/icons/icons.tsx
@@ -424,56 +424,101 @@ function IconPolygon({ className }) {
424
424
  function IconLayers({ className }) {
425
425
  return /* @__PURE__ */ jsx("svg", { viewBox: "0 0 16 16", className, fill: "currentColor", children: /* @__PURE__ */ 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" }) });
426
426
  }
427
+ function ChevronDownIcon({ className }) {
428
+ return /* @__PURE__ */ jsx("svg", { viewBox: "0 0 16 16", className, fill: "currentColor", "aria-hidden": true, children: /* @__PURE__ */ 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" }) });
429
+ }
430
+ function SortAscIcon({ className }) {
431
+ return /* @__PURE__ */ jsx("svg", { viewBox: "0 0 12 12", className, fill: "currentColor", "aria-hidden": true, children: /* @__PURE__ */ jsx("path", { d: "M6 2.5l4 5H2l4-5z" }) });
432
+ }
433
+ function SortDescIcon({ className }) {
434
+ return /* @__PURE__ */ jsx("svg", { viewBox: "0 0 12 12", className, fill: "currentColor", "aria-hidden": true, children: /* @__PURE__ */ jsx("path", { d: "M6 9.5L2 4.5h8L6 9.5z" }) });
435
+ }
436
+ function SortBothIcon({ className }) {
437
+ return /* @__PURE__ */ jsx("svg", { viewBox: "0 0 12 12", className, fill: "currentColor", "aria-hidden": true, children: /* @__PURE__ */ jsx("path", { d: "M6 1.5l3 3.5H3L6 1.5zm0 9l-3-3.5h6L6 10.5z" }) });
438
+ }
439
+ var BASE = "transition-all duration-200 disabled:opacity-50 disabled:cursor-not-allowed cursor-pointer inline-flex items-center gap-2";
440
+ var SIZE_PAD = {
441
+ sm: "px-2.5 py-1.5 text-xs",
442
+ md: "px-3 py-2 text-sm",
443
+ lg: "px-4 py-2.5 text-base"
444
+ };
445
+ var SIZE_ICON_PAD = {
446
+ sm: "p-1.5",
447
+ md: "p-2",
448
+ lg: "p-2.5"
449
+ };
450
+ var SHAPE_CLASS = {
451
+ rounded: "rounded-md",
452
+ pill: "rounded-full",
453
+ square: "rounded-none"
454
+ };
455
+ var VARIANT_STYLE = {
456
+ 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",
457
+ 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",
458
+ 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",
459
+ 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",
460
+ 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",
461
+ 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",
462
+ 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",
463
+ custom: "",
464
+ 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",
465
+ 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",
466
+ 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",
467
+ 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"
468
+ };
427
469
  var Button = ({
428
470
  variant = "primary",
429
471
  children,
430
472
  isLoading = false,
431
473
  loadingText,
432
474
  isActive = false,
475
+ size = "md",
476
+ leftIcon,
477
+ rightIcon,
478
+ fullWidth = false,
479
+ shape,
433
480
  className = "",
434
481
  disabled,
435
482
  ...props
436
483
  }) => {
437
- const baseClasses = "transition-all duration-200 disabled:opacity-50 disabled:cursor-not-allowed cursor-pointer";
438
- const variantClasses = {
439
- 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",
440
- 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",
441
- 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",
442
- 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",
443
- 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",
444
- 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",
445
- 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",
446
- custom: "",
447
- 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",
448
- 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",
449
- 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"
450
- };
451
- let classes = `${baseClasses} ${variantClasses[variant]} ${className}`;
452
- if (variant === "nav" && isActive) {
453
- classes += " bg-indigo-600 dark:bg-indigo-500 hover:bg-indigo-700 dark:hover:bg-indigo-600 text-white shadow-lg scale-105";
454
- }
455
- if (variant === "nav" && !isActive) {
456
- classes += " hover:bg-white dark:hover:bg-gray-700 hover:shadow-lg";
484
+ const sizeCls = variant === "icon" ? SIZE_ICON_PAD[size] : variant === "nav" || variant === "link" || variant === "custom" ? "" : SIZE_PAD[size];
485
+ const defaultShape = variant === "icon" ? "pill" : "rounded";
486
+ const shapeCls = variant === "link" || variant === "custom" ? "" : SHAPE_CLASS[shape ?? defaultShape];
487
+ let stateCls = "";
488
+ if (variant === "nav") {
489
+ 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";
457
490
  }
458
491
  if (variant === "toggle") {
459
- if (isActive) {
460
- classes += " bg-indigo-600 text-white border-indigo-600/30 dark:border-indigo-500/30 hover:bg-indigo-700";
461
- } else {
462
- 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";
463
- }
492
+ 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";
464
493
  }
465
- return /* @__PURE__ */ jsx(
466
- "button",
467
- {
468
- className: classes,
469
- disabled: disabled || isLoading,
470
- ...props,
471
- children: isLoading ? /* @__PURE__ */ jsxs(Fragment, { children: [
472
- /* @__PURE__ */ jsx(AnimateSpin, { className: "h-5 w-5 mr-2 inline-block text-current" }),
473
- loadingText || "Cargando..."
474
- ] }) : children
475
- }
476
- );
494
+ const classes = [
495
+ BASE,
496
+ VARIANT_STYLE[variant],
497
+ sizeCls,
498
+ shapeCls,
499
+ stateCls,
500
+ fullWidth ? "w-full justify-center" : "",
501
+ className
502
+ ].filter(Boolean).join(" ");
503
+ return /* @__PURE__ */ jsx("button", { className: classes, disabled: disabled || isLoading, ...props, children: isLoading ? /* @__PURE__ */ jsxs(Fragment, { children: [
504
+ /* @__PURE__ */ jsx(AnimateSpin, { className: "h-4 w-4 shrink-0 text-current" }),
505
+ loadingText ?? "Cargando..."
506
+ ] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
507
+ leftIcon && /* @__PURE__ */ jsx("span", { className: "shrink-0", children: leftIcon }),
508
+ children,
509
+ rightIcon && /* @__PURE__ */ jsx("span", { className: "shrink-0", children: rightIcon })
510
+ ] }) });
511
+ };
512
+ var SIZE_CLASSES = {
513
+ sm: "px-2.5 py-1.5 text-xs",
514
+ md: "px-3 py-2 text-sm",
515
+ lg: "px-4 py-2.5 text-base"
516
+ };
517
+ var VARIANT_CLASSES = {
518
+ default: "border border-gray-300 dark:border-gray-600 bg-white dark:bg-gray-800",
519
+ outline: "border-2 border-indigo-300 dark:border-indigo-600 bg-transparent",
520
+ filled: "border border-gray-300 dark:border-gray-600 bg-gray-100 dark:bg-gray-700",
521
+ minimal: "border-0 border-b border-gray-300 dark:border-gray-600 bg-transparent rounded-none focus:ring-0"
477
522
  };
478
523
  var Input = ({
479
524
  label,
@@ -481,34 +526,63 @@ var Input = ({
481
526
  helperText,
482
527
  icon,
483
528
  iconSide = "left",
529
+ variant = "default",
530
+ size = "md",
531
+ prefix,
532
+ suffix,
533
+ clearable = false,
534
+ onClear,
484
535
  className = "",
485
536
  id,
486
537
  type,
487
538
  ...props
488
539
  }) => {
489
540
  const inputId = id || `input-${Math.random().toString(36).substring(2, 9)}`;
490
- 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";
491
- 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";
492
- const iconPaddingLeft = icon && iconSide === "left" ? "pl-9" : "";
493
- const iconPaddingRight = icon && iconSide === "right" ? "pr-9" : "";
494
- const classes = `${baseClasses} ${errorClasses} ${iconPaddingLeft} ${iconPaddingRight} ${className}`.trim();
495
- const toggleShape = type === "radio" ? "rounded-full" : "rounded";
496
- 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`;
497
- const toggleErrorClasses = error ? "border-red-300 dark:border-red-600 focus:ring-red-500 dark:focus:ring-red-400" : "";
498
- const toggleClasses = `${toggleBaseClasses} ${toggleErrorClasses}`.trim();
499
- 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";
500
- 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";
501
- const fileClasses = `${fileBaseClasses} ${fileErrorClasses} ${className}`.trim();
541
+ const errorCls = error ? "border-red-300 dark:border-red-600 focus:ring-red-500 dark:focus:ring-red-400 focus:border-red-500" : "";
542
+ const showClear = clearable && !props.disabled && props.value !== void 0 && props.value !== "";
543
+ const hasRightSlot = icon && iconSide === "right" || showClear;
544
+ 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";
545
+ const inputCls = [
546
+ baseCls,
547
+ SIZE_CLASSES[size],
548
+ VARIANT_CLASSES[variant],
549
+ errorCls,
550
+ icon && iconSide === "left" ? "pl-9" : "",
551
+ hasRightSlot ? "pr-9" : "",
552
+ prefix ? "rounded-l-none" : "",
553
+ suffix ? "rounded-r-none" : "",
554
+ className
555
+ ].filter(Boolean).join(" ");
556
+ const toggleCls = [
557
+ `h-4 w-4 ${type === "radio" ? "rounded-full" : "rounded"} border border-gray-300 dark:border-gray-600 bg-white dark:bg-gray-800`,
558
+ "text-indigo-600 dark:text-indigo-400 focus:outline-none focus:ring-2 focus:ring-indigo-500 dark:focus:ring-indigo-400",
559
+ "focus:ring-offset-2 focus:ring-offset-white dark:focus:ring-offset-gray-900",
560
+ "disabled:opacity-50 disabled:cursor-not-allowed transition-colors duration-200 cursor-pointer",
561
+ error ? "border-red-300 dark:border-red-600 focus:ring-red-500 dark:focus:ring-red-400" : ""
562
+ ].filter(Boolean).join(" ");
563
+ const fileCls = [
564
+ "block w-full text-gray-500 dark:text-gray-400 bg-white dark:bg-gray-800 border rounded-md",
565
+ "focus:outline-none focus:ring-2 focus:ring-indigo-500 dark:focus:ring-indigo-400 focus:border-indigo-500",
566
+ "disabled:opacity-50 disabled:cursor-not-allowed transition-colors duration-200",
567
+ "file:mr-4 file:py-2 file:px-4 file:rounded-l-md file:border-0 file:text-sm file:font-medium",
568
+ "file:bg-indigo-50 file:text-indigo-700 dark:file:bg-indigo-900/50 dark:file:text-indigo-300",
569
+ "hover:file:bg-indigo-100 dark:hover:file:bg-indigo-800/50 file:transition-colors file:duration-200 file:cursor-pointer",
570
+ SIZE_CLASSES[size],
571
+ error ? "border-red-300 dark:border-red-600 focus:ring-red-500 dark:focus:ring-red-400" : "border-gray-300 dark:border-gray-600",
572
+ className
573
+ ].filter(Boolean).join(" ");
502
574
  const hasHidden = Boolean(className && /\bhidden\b/.test(className));
503
- const wrapperBase = "space-y-1 w-full";
504
- const wrapperClasses = hasHidden ? `${wrapperBase} hidden` : wrapperBase;
505
- const labelNode = label && (typeof label === "string" ? /* @__PURE__ */ jsx("label", { htmlFor: inputId, className: "block text-sm font-medium text-gray-700 dark:text-gray-300", children: label }) : label);
575
+ const wrapperCls = `space-y-1 w-full${hasHidden ? " hidden" : ""}`;
576
+ const labelNode = label && (typeof label === "string" ? /* @__PURE__ */ jsxs("label", { htmlFor: inputId, className: "block text-sm font-medium text-gray-700 dark:text-gray-300", children: [
577
+ label,
578
+ props.required && /* @__PURE__ */ jsx("span", { className: "ml-1 text-red-500", "aria-hidden": "true", children: "*" })
579
+ ] }) : label);
506
580
  const errorNode = error && /* @__PURE__ */ jsx("p", { className: "text-sm text-red-600 dark:text-red-400", role: "alert", children: error });
507
581
  const helperNode = helperText && !error && /* @__PURE__ */ jsx("p", { className: "text-sm text-gray-500 dark:text-gray-400", children: helperText });
508
582
  if (type === "checkbox" || type === "radio") {
509
- return /* @__PURE__ */ jsxs("div", { className: wrapperClasses, children: [
583
+ return /* @__PURE__ */ jsxs("div", { className: wrapperCls, children: [
510
584
  /* @__PURE__ */ jsxs("div", { className: "flex items-center space-x-2", children: [
511
- /* @__PURE__ */ jsx("input", { id: inputId, type, className: toggleClasses, ...props }),
585
+ /* @__PURE__ */ jsx("input", { id: inputId, type, className: toggleCls, ...props }),
512
586
  labelNode
513
587
  ] }),
514
588
  errorNode,
@@ -516,63 +590,108 @@ var Input = ({
516
590
  ] });
517
591
  }
518
592
  if (type === "file") {
519
- return /* @__PURE__ */ jsxs("div", { className: wrapperClasses, children: [
593
+ return /* @__PURE__ */ jsxs("div", { className: wrapperCls, children: [
520
594
  labelNode,
521
- /* @__PURE__ */ jsx("input", { id: inputId, type: "file", className: fileClasses, ...props }),
595
+ /* @__PURE__ */ jsx("input", { id: inputId, type: "file", className: fileCls, ...props }),
522
596
  errorNode,
523
597
  helperNode
524
598
  ] });
525
599
  }
526
- return /* @__PURE__ */ jsxs("div", { className: wrapperClasses, children: [
600
+ const prefixBorderCls = error ? "border-red-300 dark:border-red-600" : "border-gray-300 dark:border-gray-600";
601
+ return /* @__PURE__ */ jsxs("div", { className: wrapperCls, children: [
527
602
  labelNode,
528
- /* @__PURE__ */ jsxs("div", { className: "relative", children: [
529
- icon && iconSide === "left" && /* @__PURE__ */ 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 }),
530
- /* @__PURE__ */ jsx("input", { id: inputId, className: classes, type, ...props }),
531
- icon && iconSide === "right" && /* @__PURE__ */ 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 })
603
+ /* @__PURE__ */ jsxs("div", { className: "flex", children: [
604
+ prefix && /* @__PURE__ */ 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 }),
605
+ /* @__PURE__ */ jsxs("div", { className: "relative flex-1", children: [
606
+ icon && iconSide === "left" && /* @__PURE__ */ 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 }),
607
+ /* @__PURE__ */ jsx("input", { id: inputId, className: inputCls, type, ...props }),
608
+ icon && iconSide === "right" && !showClear && /* @__PURE__ */ 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
+ showClear && /* @__PURE__ */ jsx(
610
+ "button",
611
+ {
612
+ type: "button",
613
+ onClick: onClear,
614
+ tabIndex: -1,
615
+ "aria-label": "Limpiar",
616
+ 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",
617
+ children: /* @__PURE__ */ jsx(CloseIcon, { className: "w-4 h-4" })
618
+ }
619
+ )
620
+ ] }),
621
+ suffix && /* @__PURE__ */ 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 })
532
622
  ] }),
533
623
  errorNode,
534
624
  helperNode
535
625
  ] });
536
626
  };
627
+ var SIZE_CLASSES2 = {
628
+ small: "px-2 py-1 text-xs",
629
+ medium: "px-3 py-2 text-sm",
630
+ large: "px-4 py-3 text-base"
631
+ };
632
+ var VARIANT_CLASSES2 = {
633
+ default: "border border-gray-300 dark:border-gray-600 bg-white dark:bg-gray-800",
634
+ outline: "border-2 border-indigo-300 dark:border-indigo-600 bg-transparent",
635
+ filled: "border border-gray-300 dark:border-gray-600 bg-gray-100 dark:bg-gray-700",
636
+ minimal: "border-0 border-b border-gray-300 dark:border-gray-600 bg-transparent rounded-none focus:ring-0"
637
+ };
638
+ var RESIZE_CLASSES = {
639
+ vertical: "resize-y",
640
+ horizontal: "resize-x",
641
+ both: "resize",
642
+ none: "resize-none"
643
+ };
537
644
  var TextArea = ({
538
645
  label,
539
646
  error,
540
647
  helperText,
541
648
  variant = "default",
542
649
  size = "medium",
650
+ autoResize = false,
651
+ showCount = false,
652
+ resize = "vertical",
543
653
  className = "",
544
654
  id,
655
+ onInput: propsOnInput,
545
656
  ...props
546
657
  }) => {
547
658
  const textAreaId = id || `textarea-${Math.random().toString(36).substring(2, 9)}`;
548
- const sizeClasses = {
549
- small: "px-2 py-1 text-xs",
550
- medium: "px-3 py-2 text-sm",
551
- large: "px-4 py-3 text-base"
659
+ const textareaRef = useRef(null);
660
+ const adjustHeight = () => {
661
+ const el = textareaRef.current;
662
+ if (!el) return;
663
+ el.style.height = "auto";
664
+ el.style.height = `${el.scrollHeight}px`;
552
665
  };
553
- const variantClasses = {
554
- default: "border-gray-300 dark:border-gray-600 bg-white dark:bg-gray-800",
555
- outline: "border-2 border-indigo-300 dark:border-indigo-600 bg-transparent",
556
- filled: "border-gray-300 dark:border-gray-600 bg-gray-100 dark:bg-gray-700",
557
- minimal: "border-0 bg-transparent focus:ring-0 focus:border-0"
666
+ useEffect(() => {
667
+ if (autoResize) adjustHeight();
668
+ }, [autoResize, props.value]);
669
+ const handleInput = (e) => {
670
+ if (autoResize) adjustHeight();
671
+ propsOnInput?.(e);
558
672
  };
559
- 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";
560
- const errorClasses = error ? "border-red-300 dark:border-red-600 focus:ring-red-500 dark:focus:ring-red-400 focus:border-red-500" : "";
561
- const classes = `${baseClasses} ${sizeClasses[size]} ${variantClasses[variant]} ${errorClasses} ${className}`;
673
+ 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";
674
+ const errorCls = error ? "border-red-300 dark:border-red-600 focus:ring-red-500 dark:focus:ring-red-400 focus:border-red-500" : "";
675
+ const resizeCls = autoResize ? "resize-none overflow-hidden" : RESIZE_CLASSES[resize];
676
+ const classes = [baseCls, SIZE_CLASSES2[size], VARIANT_CLASSES2[variant], errorCls, resizeCls, className].filter(Boolean).join(" ");
677
+ const maxLength = typeof props.maxLength === "number" ? props.maxLength : void 0;
678
+ const currentLength = typeof props.value === "string" ? props.value.length : typeof props.value === "number" ? String(props.value).length : 0;
679
+ const overLimit = maxLength !== void 0 && currentLength > maxLength;
562
680
  return /* @__PURE__ */ jsxs("div", { className: "space-y-1 w-full", children: [
563
- label && typeof label === "string" ? /* @__PURE__ */ jsx(
564
- "label",
565
- {
566
- htmlFor: textAreaId,
567
- className: "block text-sm font-medium text-gray-700 dark:text-gray-300",
568
- children: label
569
- }
570
- ) : label,
681
+ (label || showCount) && /* @__PURE__ */ jsxs("div", { className: "flex items-baseline gap-2", children: [
682
+ /* @__PURE__ */ jsx("div", { className: "flex-1", children: label && (typeof label === "string" ? /* @__PURE__ */ jsxs("label", { htmlFor: textAreaId, className: "block text-sm font-medium text-gray-700 dark:text-gray-300", children: [
683
+ label,
684
+ props.required && /* @__PURE__ */ jsx("span", { className: "ml-1 text-red-500", "aria-hidden": "true", children: "*" })
685
+ ] }) : label) }),
686
+ showCount && /* @__PURE__ */ 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 })
687
+ ] }),
571
688
  /* @__PURE__ */ jsx(
572
689
  "textarea",
573
690
  {
691
+ ref: textareaRef,
574
692
  id: textAreaId,
575
693
  className: classes,
694
+ onInput: handleInput,
576
695
  ...props
577
696
  }
578
697
  ),
@@ -580,80 +699,125 @@ var TextArea = ({
580
699
  helperText && !error && /* @__PURE__ */ jsx("p", { className: "text-sm text-gray-500 dark:text-gray-400", children: helperText })
581
700
  ] });
582
701
  };
583
- var Form = ({ onSubmit, children, variant = "default", className = "", ...props }) => {
702
+ var Form = ({
703
+ onSubmit,
704
+ children,
705
+ variant = "default",
706
+ columns,
707
+ className = "",
708
+ style,
709
+ ...props
710
+ }) => {
584
711
  const handleSubmit = (e) => {
585
712
  e.preventDefault();
586
- if (onSubmit) {
587
- onSubmit(e);
588
- }
713
+ onSubmit?.(e);
589
714
  };
715
+ const hasGrid = columns !== void 0 && columns > 1;
590
716
  const getVariantClasses = () => {
591
717
  switch (variant) {
592
718
  case "modal":
593
719
  return "flex-1 px-6 py-4 overflow-y-auto";
594
720
  case "card":
595
- return "p-6 space-y-6";
721
+ 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"}`;
596
722
  case "inline":
597
- return "flex flex-wrap gap-4 items-end";
723
+ return hasGrid ? "" : "flex flex-wrap gap-4 items-end";
598
724
  case "compact":
599
- return "space-y-3";
725
+ return hasGrid ? "" : "space-y-3";
600
726
  case "default":
601
727
  default:
602
- return "space-y-4";
728
+ return hasGrid ? "" : "space-y-4";
603
729
  }
604
730
  };
605
- const combinedClassName = `${getVariantClasses()} ${className}`.trim();
606
- return /* @__PURE__ */ jsx("form", { onSubmit: handleSubmit, className: combinedClassName, ...props, children });
731
+ const gridStyle = hasGrid ? { display: "grid", gridTemplateColumns: `repeat(${columns}, minmax(0, 1fr))`, gap: "1rem" } : {};
732
+ const combinedClassName = [getVariantClasses(), className].filter(Boolean).join(" ");
733
+ const combinedStyle = { ...gridStyle, ...style };
734
+ return /* @__PURE__ */ jsx(
735
+ "form",
736
+ {
737
+ onSubmit: handleSubmit,
738
+ className: combinedClassName,
739
+ style: Object.keys(combinedStyle).length > 0 ? combinedStyle : void 0,
740
+ ...props,
741
+ children
742
+ }
743
+ );
744
+ };
745
+ var SIZE_CLASSES3 = {
746
+ sm: "py-1.5 text-xs",
747
+ md: "py-2 text-sm",
748
+ lg: "py-2.5 text-base"
749
+ };
750
+ var VARIANT_CLASSES3 = {
751
+ default: "border border-gray-300 dark:border-gray-600 bg-white dark:bg-gray-800",
752
+ outline: "border-2 border-indigo-300 dark:border-indigo-600 bg-transparent",
753
+ filled: "border border-gray-300 dark:border-gray-600 bg-gray-100 dark:bg-gray-700",
754
+ minimal: "border-0 border-b border-gray-300 dark:border-gray-600 bg-transparent rounded-none focus:ring-0",
755
+ custom: ""
607
756
  };
608
757
  var Select = ({
609
758
  options,
610
759
  placeholder,
611
760
  variant = "default",
761
+ size = "md",
612
762
  error = false,
613
763
  helperText,
614
764
  label,
765
+ icon,
615
766
  className = "",
616
767
  id,
617
768
  ...props
618
769
  }) => {
619
770
  const selectId = id || `select-${Math.random().toString(36).substring(2, 9)}`;
620
- const getVariantClasses = () => {
621
- 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";
622
- if (variant === "small") {
623
- return `${baseClasses.replace("px-3 py-2", "px-2.5 py-1.5 text-sm")} border-gray-300 dark:border-gray-600`;
624
- }
625
- 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" : ""}`;
626
- };
627
- const getOptionClasses = (option) => {
628
- return `bg-white dark:bg-gray-800 text-gray-900 dark:text-white py-2 ${option.disabled ? "opacity-50 cursor-not-allowed" : ""}`;
629
- };
630
- const combinedClassName = `${getVariantClasses()} ${className}`.trim();
771
+ const effectiveSize = variant === "small" ? "sm" : size;
772
+ const effectiveVariant = variant === "small" ? "default" : variant;
773
+ const hasError = Boolean(error);
774
+ const errorMsg = typeof error === "string" ? error : "";
775
+ const computedDefaultValue = props.value === void 0 && props.defaultValue === void 0 ? options.find((o) => o.selected)?.value?.toString() : void 0;
776
+ 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";
777
+ const errorCls = hasError ? "border-red-300 dark:border-red-600 focus:ring-red-500 dark:focus:ring-red-400 focus:border-red-500" : "";
778
+ const selectCls = [
779
+ baseCls,
780
+ SIZE_CLASSES3[effectiveSize],
781
+ VARIANT_CLASSES3[effectiveVariant],
782
+ errorCls,
783
+ icon ? "pl-9" : "",
784
+ className
785
+ ].filter(Boolean).join(" ");
631
786
  return /* @__PURE__ */ jsxs("div", { className: "space-y-1 w-full", children: [
632
- label && typeof label === "string" ? /* @__PURE__ */ jsx("label", { htmlFor: selectId, className: "block text-sm font-medium text-gray-700 dark:text-gray-300", children: label }) : label,
633
- /* @__PURE__ */ jsxs("select", { id: selectId, className: combinedClassName, ...props, children: [
634
- placeholder && placeholder.trim() && /* @__PURE__ */ 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 }),
635
- options.map((option) => /* @__PURE__ */ jsx(
636
- "option",
787
+ label && (typeof label === "string" ? /* @__PURE__ */ jsxs("label", { htmlFor: selectId, className: "block text-sm font-medium text-gray-700 dark:text-gray-300", children: [
788
+ label,
789
+ props.required && /* @__PURE__ */ jsx("span", { className: "ml-1 text-red-500", "aria-hidden": "true", children: "*" })
790
+ ] }) : label),
791
+ /* @__PURE__ */ jsxs("div", { className: "relative", children: [
792
+ icon && /* @__PURE__ */ 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 }),
793
+ /* @__PURE__ */ jsxs(
794
+ "select",
637
795
  {
638
- value: option.value,
639
- disabled: option.disabled,
640
- selected: option.selected,
641
- className: getOptionClasses(option),
642
- children: option.label
643
- },
644
- option.value
645
- ))
796
+ id: selectId,
797
+ className: selectCls,
798
+ defaultValue: computedDefaultValue,
799
+ ...props,
800
+ children: [
801
+ placeholder && /* @__PURE__ */ jsx("option", { value: "", disabled: true, className: "bg-white dark:bg-gray-800 text-gray-500 dark:text-gray-400", children: placeholder }),
802
+ options.map((option) => /* @__PURE__ */ jsx(
803
+ "option",
804
+ {
805
+ value: option.value,
806
+ disabled: option.disabled,
807
+ className: `bg-white dark:bg-gray-800 text-gray-900 dark:text-white${option.disabled ? " opacity-50" : ""}`,
808
+ children: option.label
809
+ },
810
+ option.value
811
+ ))
812
+ ]
813
+ }
814
+ ),
815
+ /* @__PURE__ */ 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__ */ jsx(ChevronDownIcon, { className: "w-4 h-4" }) })
646
816
  ] }),
647
- helperText && /* @__PURE__ */ jsx("p", { className: `text-sm ${error ? "text-red-600 dark:text-red-400" : "text-gray-500 dark:text-gray-400"}`, children: helperText })
817
+ errorMsg && /* @__PURE__ */ jsx("p", { className: "text-sm text-red-600 dark:text-red-400", role: "alert", children: errorMsg }),
818
+ helperText && !errorMsg && /* @__PURE__ */ jsx("p", { className: `text-sm ${hasError ? "text-red-600 dark:text-red-400" : "text-gray-500 dark:text-gray-400"}`, children: helperText })
648
819
  ] });
649
820
  };
650
- function isColumnDef(col) {
651
- return typeof col === "object" && col !== null && "header" in col;
652
- }
653
- function resolveColumn(col) {
654
- if (isColumnDef(col)) return col;
655
- return { header: col };
656
- }
657
821
  var ALIGN_CLASS = {
658
822
  left: "text-left",
659
823
  center: "text-center",
@@ -674,6 +838,10 @@ var VARIANT_TABLE = {
674
838
  striped: "w-full min-w-full table-auto",
675
839
  bordered: "w-full min-w-full table-auto border border-gray-300 dark:border-gray-600",
676
840
  minimal: "w-full min-w-full table-auto",
841
+ ghost: "w-full min-w-full table-auto",
842
+ card: "w-full min-w-full table-auto",
843
+ accent: "w-full min-w-full table-auto",
844
+ dark: "w-full min-w-full table-auto",
677
845
  custom: "w-full min-w-full table-auto"
678
846
  };
679
847
  var VARIANT_THEAD = {
@@ -681,6 +849,10 @@ var VARIANT_THEAD = {
681
849
  striped: "bg-gray-100 dark:bg-gray-700",
682
850
  bordered: "bg-gray-100 dark:bg-gray-700",
683
851
  minimal: "",
852
+ ghost: "",
853
+ card: "bg-gray-50 dark:bg-gray-800/80",
854
+ accent: "bg-blue-600 dark:bg-blue-700",
855
+ dark: "bg-gray-800 dark:bg-gray-900",
684
856
  custom: ""
685
857
  };
686
858
  var VARIANT_TH = {
@@ -688,13 +860,43 @@ var VARIANT_TH = {
688
860
  striped: "font-semibold uppercase tracking-wider text-gray-600 dark:text-gray-300",
689
861
  bordered: "font-semibold uppercase tracking-wider text-gray-600 dark:text-gray-300 border border-gray-300 dark:border-gray-600",
690
862
  minimal: "font-semibold text-gray-500 dark:text-gray-400 border-b border-gray-200 dark:border-gray-700",
863
+ ghost: "font-semibold text-gray-600 dark:text-gray-400 border-b-2 border-gray-300 dark:border-gray-600",
864
+ card: "font-semibold text-gray-600 dark:text-gray-300 border-b border-gray-200 dark:border-gray-700",
865
+ accent: "font-semibold uppercase tracking-wider text-white",
866
+ dark: "font-semibold uppercase tracking-wider text-gray-100",
691
867
  custom: ""
692
868
  };
693
- var VARIANT_TR = {
694
- default: () => "bg-white dark:bg-gray-800 hover:bg-gray-50 dark:hover:bg-gray-700/60 transition-colors",
695
- 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`,
696
- bordered: () => "bg-white dark:bg-gray-800 hover:bg-gray-50 dark:hover:bg-gray-700/60 transition-colors",
697
- minimal: () => "hover:bg-gray-50 dark:hover:bg-gray-800/60 transition-colors",
869
+ var VARIANT_TR_BASE = {
870
+ default: "bg-white dark:bg-gray-800",
871
+ striped: "",
872
+ bordered: "bg-white dark:bg-gray-800",
873
+ minimal: "",
874
+ ghost: "",
875
+ card: "bg-white dark:bg-gray-900",
876
+ accent: "bg-white dark:bg-gray-800",
877
+ dark: "bg-white dark:bg-gray-800",
878
+ custom: ""
879
+ };
880
+ var VARIANT_TR_HOVER = {
881
+ default: "hover:bg-gray-50 dark:hover:bg-gray-700/60",
882
+ striped: "hover:bg-blue-50 dark:hover:bg-blue-900/20",
883
+ bordered: "hover:bg-gray-50 dark:hover:bg-gray-700/60",
884
+ minimal: "hover:bg-gray-50 dark:hover:bg-gray-800/60",
885
+ ghost: "hover:bg-gray-50/70 dark:hover:bg-white/5",
886
+ card: "hover:bg-gray-50 dark:hover:bg-gray-800/50",
887
+ accent: "hover:bg-blue-50 dark:hover:bg-blue-900/20",
888
+ dark: "hover:bg-gray-50 dark:hover:bg-gray-700/60",
889
+ custom: ""
890
+ };
891
+ var VARIANT_TR_STRIPE = {
892
+ default: () => "",
893
+ striped: (i) => i % 2 === 0 ? "bg-white dark:bg-gray-800" : "bg-gray-50 dark:bg-gray-700/40",
894
+ bordered: () => "",
895
+ minimal: () => "",
896
+ ghost: () => "",
897
+ card: () => "",
898
+ accent: () => "",
899
+ dark: () => "",
698
900
  custom: () => ""
699
901
  };
700
902
  var VARIANT_TD = {
@@ -702,6 +904,10 @@ var VARIANT_TD = {
702
904
  striped: "text-gray-700 dark:text-gray-300",
703
905
  bordered: "text-gray-700 dark:text-gray-300 border border-gray-200 dark:border-gray-700",
704
906
  minimal: "text-gray-700 dark:text-gray-300 border-b border-gray-100 dark:border-gray-800",
907
+ ghost: "text-gray-700 dark:text-gray-300",
908
+ card: "text-gray-700 dark:text-gray-300",
909
+ accent: "text-gray-700 dark:text-gray-300",
910
+ dark: "text-gray-700 dark:text-gray-300",
705
911
  custom: ""
706
912
  };
707
913
  var VARIANT_TBODY_DIVIDER = {
@@ -709,8 +915,33 @@ var VARIANT_TBODY_DIVIDER = {
709
915
  striped: "",
710
916
  bordered: "",
711
917
  minimal: "",
918
+ ghost: "divide-y divide-gray-200 dark:divide-gray-700",
919
+ card: "divide-y divide-gray-100 dark:divide-gray-800",
920
+ accent: "divide-y divide-gray-200 dark:divide-gray-700",
921
+ dark: "divide-y divide-gray-200 dark:divide-gray-700",
712
922
  custom: ""
713
923
  };
924
+ function SortIcon({ direction }) {
925
+ if (direction === "asc") return /* @__PURE__ */ jsx(SortAscIcon, { className: "inline-block ml-1 w-3 h-3 shrink-0" });
926
+ if (direction === "desc") return /* @__PURE__ */ jsx(SortDescIcon, { className: "inline-block ml-1 w-3 h-3 shrink-0" });
927
+ return /* @__PURE__ */ jsx(SortBothIcon, { className: "inline-block ml-1 w-3 h-3 shrink-0 opacity-40" });
928
+ }
929
+ function SkeletonRow({ colCount, size }) {
930
+ return /* @__PURE__ */ jsx("tr", { children: Array.from({ length: colCount }).map((_, i) => /* @__PURE__ */ jsx("td", { className: SIZE_TD[size], children: /* @__PURE__ */ jsx("div", { className: "h-4 rounded bg-gray-200 dark:bg-gray-700 animate-pulse" }) }, i)) });
931
+ }
932
+ function isColumnDef(col) {
933
+ return typeof col === "object" && col !== null && "header" in col;
934
+ }
935
+ function resolveColumn(col) {
936
+ if (isColumnDef(col)) return col;
937
+ return { header: col };
938
+ }
939
+ function colSizeStyle(col) {
940
+ const s = {};
941
+ if (col.width !== void 0) s.width = col.width;
942
+ if (col.minWidth !== void 0) s.minWidth = col.minWidth;
943
+ return s;
944
+ }
714
945
  function Table({
715
946
  columns,
716
947
  rows,
@@ -724,46 +955,84 @@ function Table({
724
955
  emptyState,
725
956
  onRowClick,
726
957
  hideHeader = false,
727
- style
958
+ style,
959
+ stickyHeader = false,
960
+ caption,
961
+ footerRows,
962
+ loading = false,
963
+ loadingRows = 4,
964
+ getRowStyle,
965
+ rounded = false,
966
+ shadow = false,
967
+ hoverable = true,
968
+ sortState,
969
+ onSort
728
970
  }) {
729
971
  const cols = columns.map(resolveColumn);
730
972
  const resolvedTrClass = (i) => {
731
- const variantCls = VARIANT_TR[variant](i);
973
+ const stripeCls = VARIANT_TR_STRIPE[variant](i);
974
+ const baseCls = stripeCls || VARIANT_TR_BASE[variant];
975
+ const hoverCls = hoverable ? `${VARIANT_TR_HOVER[variant]} transition-colors` : "";
732
976
  const clickCls = onRowClick ? "cursor-pointer" : "";
733
977
  const customCls = typeof trClassName === "function" ? trClassName(i) : trClassName ?? "";
734
- return `${variantCls} ${clickCls} ${customCls}`.trim();
978
+ return [baseCls, hoverCls, clickCls, customCls].filter(Boolean).join(" ");
735
979
  };
736
- return /* @__PURE__ */ jsx("div", { className: `overflow-x-auto w-full ${className}`.trim(), children: /* @__PURE__ */ jsxs(
980
+ const wrapperCls = [
981
+ "overflow-x-auto w-full",
982
+ rounded ? "rounded-lg overflow-hidden" : "",
983
+ shadow ? "shadow-md" : "",
984
+ className
985
+ ].filter(Boolean).join(" ");
986
+ const theadCls = [
987
+ VARIANT_THEAD[variant],
988
+ stickyHeader ? "sticky top-0 z-20" : ""
989
+ ].filter(Boolean).join(" ");
990
+ const stickyColCls = "sticky left-0 z-10 bg-inherit";
991
+ return /* @__PURE__ */ jsx("div", { className: wrapperCls, children: /* @__PURE__ */ jsxs(
737
992
  "table",
738
993
  {
739
994
  className: `${VARIANT_TABLE[variant]} ${tableClassName}`.trim(),
740
995
  style,
741
996
  children: [
742
- !hideHeader && /* @__PURE__ */ jsx("thead", { className: VARIANT_THEAD[variant], children: /* @__PURE__ */ jsx("tr", { children: cols.map((col, i) => /* @__PURE__ */ jsx(
743
- "th",
744
- {
745
- className: [
746
- SIZE_TH[size],
747
- VARIANT_TH[variant],
748
- ALIGN_CLASS[col.align ?? "left"],
749
- col.className ?? "",
750
- thClassName
751
- ].filter(Boolean).join(" "),
752
- children: col.header
753
- },
754
- i
755
- )) }) }),
756
- /* @__PURE__ */ jsx("tbody", { className: VARIANT_TBODY_DIVIDER[variant], children: rows.length === 0 ? /* @__PURE__ */ jsx("tr", { children: /* @__PURE__ */ jsx(
997
+ caption && /* @__PURE__ */ jsx("caption", { className: "mb-2 text-left text-sm text-gray-500 dark:text-gray-400", children: caption }),
998
+ !hideHeader && /* @__PURE__ */ jsx("thead", { className: theadCls, children: /* @__PURE__ */ jsx("tr", { children: cols.map((col, i) => {
999
+ const isSortable = col.sortable && col.key;
1000
+ const activeSort = sortState?.key === col.key ? sortState.direction : null;
1001
+ return /* @__PURE__ */ jsxs(
1002
+ "th",
1003
+ {
1004
+ scope: "col",
1005
+ className: [
1006
+ SIZE_TH[size],
1007
+ VARIANT_TH[variant],
1008
+ ALIGN_CLASS[col.align ?? "left"],
1009
+ col.className ?? "",
1010
+ thClassName,
1011
+ col.sticky ? stickyColCls : "",
1012
+ isSortable ? "cursor-pointer select-none" : ""
1013
+ ].filter(Boolean).join(" "),
1014
+ style: { ...colSizeStyle(col), ...col.thStyle ?? {} },
1015
+ onClick: isSortable ? () => onSort?.(col.key) : void 0,
1016
+ children: [
1017
+ col.header,
1018
+ isSortable && /* @__PURE__ */ jsx(SortIcon, { direction: activeSort })
1019
+ ]
1020
+ },
1021
+ i
1022
+ );
1023
+ }) }) }),
1024
+ /* @__PURE__ */ jsx("tbody", { className: VARIANT_TBODY_DIVIDER[variant], children: loading ? Array.from({ length: loadingRows }).map((_, i) => /* @__PURE__ */ jsx(SkeletonRow, { colCount: cols.length, size }, i)) : rows.length === 0 ? /* @__PURE__ */ jsx("tr", { children: /* @__PURE__ */ jsx(
757
1025
  "td",
758
1026
  {
759
1027
  colSpan: cols.length,
760
- className: `${SIZE_TD[size]} text-center text-gray-400 dark:text-gray-500 py-8`,
1028
+ className: `${SIZE_TD[size]} py-8 text-center text-gray-400 dark:text-gray-500`,
761
1029
  children: emptyState ?? "Sin datos"
762
1030
  }
763
1031
  ) }) : rows.map((row, rowIndex) => /* @__PURE__ */ jsx(
764
1032
  "tr",
765
1033
  {
766
1034
  className: resolvedTrClass(rowIndex),
1035
+ style: getRowStyle?.(rowIndex),
767
1036
  onClick: onRowClick ? () => onRowClick(rowIndex) : void 0,
768
1037
  children: row.map((cell, cellIndex) => {
769
1038
  const col = cols[cellIndex];
@@ -775,8 +1044,13 @@ function Table({
775
1044
  VARIANT_TD[variant],
776
1045
  ALIGN_CLASS[col?.align ?? "left"],
777
1046
  col?.className ?? "",
778
- tdClassName
1047
+ tdClassName,
1048
+ col?.sticky ? stickyColCls : ""
779
1049
  ].filter(Boolean).join(" "),
1050
+ style: {
1051
+ ...col ? colSizeStyle(col) : {},
1052
+ ...col?.tdStyle ?? {}
1053
+ },
780
1054
  children: cell
781
1055
  },
782
1056
  cellIndex
@@ -784,47 +1058,100 @@ function Table({
784
1058
  })
785
1059
  },
786
1060
  rowIndex
787
- )) })
1061
+ )) }),
1062
+ footerRows && footerRows.length > 0 && /* @__PURE__ */ 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__ */ jsx("tr", { children: row.map((cell, cellIndex) => {
1063
+ const col = cols[cellIndex];
1064
+ return /* @__PURE__ */ jsx(
1065
+ "td",
1066
+ {
1067
+ className: [
1068
+ SIZE_TD[size],
1069
+ "font-medium text-gray-700 dark:text-gray-300",
1070
+ ALIGN_CLASS[col?.align ?? "left"],
1071
+ col?.className ?? "",
1072
+ tdClassName
1073
+ ].filter(Boolean).join(" "),
1074
+ style: col?.tdStyle,
1075
+ children: cell
1076
+ },
1077
+ cellIndex
1078
+ );
1079
+ }) }, rowIndex)) })
788
1080
  ]
789
1081
  }
790
1082
  ) });
791
1083
  }
1084
+ var SIZE_CLASS = {
1085
+ sm: "max-w-sm",
1086
+ md: "max-w-md",
1087
+ lg: "max-w-2xl",
1088
+ xl: "max-w-4xl",
1089
+ full: "max-w-[95vw] w-[95vw]"
1090
+ };
1091
+ var VARIANT_HEADER = {
1092
+ default: "bg-gray-50 dark:bg-gray-800 border-b border-gray-200 dark:border-gray-700",
1093
+ danger: "bg-red-50 dark:bg-red-900/30 border-b border-red-200 dark:border-red-800",
1094
+ success: "bg-green-50 dark:bg-green-900/30 border-b border-green-200 dark:border-green-800",
1095
+ warning: "bg-yellow-50 dark:bg-yellow-900/30 border-b border-yellow-200 dark:border-yellow-800"
1096
+ };
1097
+ var VARIANT_TITLE = {
1098
+ default: "text-gray-900 dark:text-white",
1099
+ danger: "text-red-700 dark:text-red-300",
1100
+ success: "text-green-700 dark:text-green-300",
1101
+ warning: "text-yellow-700 dark:text-yellow-300"
1102
+ };
792
1103
  var Modal = forwardRef(({
793
1104
  onClose,
794
1105
  title,
795
1106
  children,
796
1107
  footer,
797
- maxWidth = "max-w-2xl",
1108
+ maxWidth,
1109
+ size,
798
1110
  showCloseButton = true,
799
- zIndex = 50
1111
+ zIndex = 50,
1112
+ closeOnBackdrop = false,
1113
+ closeOnEsc = false,
1114
+ variant = "default"
800
1115
  }, ref) => {
801
1116
  const [show, setShow] = useState(false);
1117
+ const handleCloseRef = useRef(() => {
1118
+ });
1119
+ const handleClose = () => {
1120
+ setShow(false);
1121
+ setTimeout(() => onClose(), 300);
1122
+ };
1123
+ handleCloseRef.current = handleClose;
802
1124
  useEffect(() => {
803
1125
  setShow(true);
804
1126
  }, []);
805
- const handleClose = () => {
806
- setShow(false);
807
- setTimeout(() => {
808
- onClose();
809
- }, 300);
1127
+ useEffect(() => {
1128
+ if (!closeOnEsc) return;
1129
+ const handler = (e) => {
1130
+ if (e.key === "Escape") handleCloseRef.current();
1131
+ };
1132
+ document.addEventListener("keydown", handler);
1133
+ return () => document.removeEventListener("keydown", handler);
1134
+ }, [closeOnEsc]);
1135
+ useImperativeHandle(ref, () => ({ handleClose }));
1136
+ const widthCls = size ? SIZE_CLASS[size] : maxWidth ?? "max-w-2xl";
1137
+ const handleBackdropClick = (e) => {
1138
+ if (closeOnBackdrop && e.target === e.currentTarget) handleClose();
810
1139
  };
811
- useImperativeHandle(ref, () => ({
812
- handleClose
813
- }));
814
1140
  return /* @__PURE__ */ jsx(
815
1141
  "dialog",
816
1142
  {
817
1143
  open: show,
818
- 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`,
1144
+ 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"}`,
819
1145
  style: { zIndex: zIndex - 10 },
1146
+ onClick: handleBackdropClick,
820
1147
  children: /* @__PURE__ */ jsxs(
821
1148
  "article",
822
1149
  {
823
- 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`,
1150
+ 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`,
824
1151
  style: { zIndex },
825
1152
  children: [
826
- /* @__PURE__ */ 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: [
827
- /* @__PURE__ */ jsx("h2", { className: "text-2xl font-bold text-gray-900 dark:text-white", children: title }),
1153
+ /* @__PURE__ */ jsxs("header", { className: `shrink-0 px-6 py-4 flex items-center justify-between ${VARIANT_HEADER[variant]}`, children: [
1154
+ /* @__PURE__ */ jsx("h2", { className: `text-2xl font-bold ${VARIANT_TITLE[variant]}`, children: title }),
828
1155
  showCloseButton && /* @__PURE__ */ jsx(
829
1156
  Button,
830
1157
  {
@@ -849,7 +1176,9 @@ var Loading = ({
849
1176
  size = "medium",
850
1177
  color = "primary",
851
1178
  label,
852
- className = ""
1179
+ className = "",
1180
+ overlay = false,
1181
+ fullPage = false
853
1182
  }) => {
854
1183
  const sizeClasses = {
855
1184
  small: "h-4 w-4",
@@ -868,13 +1197,14 @@ var Loading = ({
868
1197
  const renderIcon = () => {
869
1198
  const commonClass = `${sizeClasses[size]} ${colorClasses[color]}`;
870
1199
  switch (variant) {
871
- case "dots":
1200
+ case "dots": {
872
1201
  const dotSize = size === "small" ? "h-1 w-1" : size === "medium" ? "h-2 w-2" : size === "large" ? "h-3 w-3" : "h-4 w-4";
873
1202
  return /* @__PURE__ */ jsxs("div", { className: `flex space-x-1 ${colorClasses[color]}`, children: [
874
1203
  /* @__PURE__ */ jsx("div", { className: `rounded-full bg-current animate-bounce ${dotSize}`, style: { animationDelay: "0s" } }),
875
1204
  /* @__PURE__ */ jsx("div", { className: `rounded-full bg-current animate-bounce ${dotSize}`, style: { animationDelay: "0.15s" } }),
876
1205
  /* @__PURE__ */ jsx("div", { className: `rounded-full bg-current animate-bounce ${dotSize}`, style: { animationDelay: "0.3s" } })
877
1206
  ] });
1207
+ }
878
1208
  case "bars":
879
1209
  return /* @__PURE__ */ jsxs("div", { className: `flex items-end space-x-1 ${sizeClasses[size]} ${colorClasses[color]}`, children: [
880
1210
  /* @__PURE__ */ jsx("div", { className: "w-1/4 bg-current animate-[pulse_1s_ease-in-out_infinite]", style: { height: "60%", animationDelay: "0s" } }),
@@ -906,6 +1236,16 @@ var Loading = ({
906
1236
  ] });
907
1237
  }
908
1238
  };
1239
+ const inner = /* @__PURE__ */ jsxs("div", { className: `flex flex-col items-center justify-center ${className}`, role: "status", children: [
1240
+ renderIcon(),
1241
+ label && /* @__PURE__ */ jsx("span", { className: `mt-3 text-sm font-medium ${colorClasses[color]}`, children: label })
1242
+ ] });
1243
+ if (fullPage) {
1244
+ return /* @__PURE__ */ jsx("div", { className: "fixed inset-0 z-50 flex items-center justify-center bg-gray-900/50 backdrop-blur-sm", children: inner });
1245
+ }
1246
+ if (overlay) {
1247
+ return /* @__PURE__ */ jsx("div", { className: "absolute inset-0 z-10 flex items-center justify-center bg-gray-900/40 backdrop-blur-sm rounded-[inherit]", children: inner });
1248
+ }
909
1249
  return /* @__PURE__ */ jsxs("div", { className: `flex flex-col items-center justify-center w-full h-full min-h-[inherit] ${className}`, role: "status", children: [
910
1250
  renderIcon(),
911
1251
  label && /* @__PURE__ */ jsx("span", { className: `mt-3 text-sm font-medium ${colorClasses[color]}`, children: label })
@@ -4187,6 +4527,6 @@ var ElementLibraryBuilder = () => {
4187
4527
  ] });
4188
4528
  };
4189
4529
 
4190
- export { AddIcon, Alerta, AlertaAdvertencia, AlertaConfirmacion, AlertaError, AlertaExito, AlertaInfo, AlertaToast, AnimateSpin, ArchiveIcon, ArrowIcon, ArrowLeftIcon, ArrowRightIcon, BackIcon, BarsChartsIcon, BoxIcon, BuildingIcon, Button, CajasIcon, CalendarIcon, CamaraIcon, CancelIcon, CashIcon, CategorieIcon, ChartIcon, CheckCircleIcon, CheckIcon, ClockIcon, CloseIcon, CloudIcon, CopyIcon, DeleteIcon, DocumentIcon, EditIcon, ElementLibraryBuilder, FacturacionIcon, FilterIcon, FolderIcon, Form, GearIcon, HomeIcon, IconCursor, IconDownload, IconDuplicate, IconErase, IconGrid, IconHand, IconLayers, IconPlace, IconPolygon, IconRedo, IconReset, IconUndo, IconUpload, IconWall, IconZoomIn, IconZoomOut, InfoAlert, InfoIcon, Input, LifeGuardIcon, LightingIcon, Loading, LocationIcon, LogoutIcon, MenuIcon, MinusIcon, Modal, MoneyIcon, MonitorIcon, MoonIcon, NetworkIcon, NotFoundIcon, PasteIcon, PercentIcon, PrinterIcon, QuestionIcon, RestaurantMenuIcon, SaveIcon, SearchIcon, Select, ShieldIcon, SpinnerIcon, StackIcon, SunIcon, Table, TestIcon, TextArea, ThemeContext, ThemeProvider, ThemeToggle, TrashIcon, TruckIcon, UsersIcon, VenueMapEditor, VenueMapViewer, WhatsAppIcon, findNearestNode, genId, parseSvgMarkup, snapPoint, snapToGrid, useLibraryStorage, usePanZoom, useTheme };
4530
+ export { AddIcon, Alerta, AlertaAdvertencia, AlertaConfirmacion, AlertaError, AlertaExito, AlertaInfo, AlertaToast, AnimateSpin, ArchiveIcon, ArrowIcon, ArrowLeftIcon, ArrowRightIcon, BackIcon, BarsChartsIcon, BoxIcon, BuildingIcon, Button, CajasIcon, CalendarIcon, CamaraIcon, CancelIcon, CashIcon, CategorieIcon, ChartIcon, CheckCircleIcon, CheckIcon, ChevronDownIcon, ClockIcon, CloseIcon, CloudIcon, CopyIcon, DeleteIcon, DocumentIcon, EditIcon, ElementLibraryBuilder, FacturacionIcon, FilterIcon, FolderIcon, Form, GearIcon, HomeIcon, IconCursor, IconDownload, IconDuplicate, IconErase, IconGrid, IconHand, IconLayers, IconPlace, IconPolygon, IconRedo, IconReset, IconUndo, IconUpload, IconWall, IconZoomIn, IconZoomOut, InfoAlert, InfoIcon, Input, LifeGuardIcon, LightingIcon, Loading, LocationIcon, LogoutIcon, MenuIcon, MinusIcon, Modal, MoneyIcon, MonitorIcon, MoonIcon, NetworkIcon, NotFoundIcon, PasteIcon, PercentIcon, PrinterIcon, QuestionIcon, RestaurantMenuIcon, SaveIcon, SearchIcon, Select, ShieldIcon, SortAscIcon, SortBothIcon, SortDescIcon, SpinnerIcon, StackIcon, SunIcon, Table, TestIcon, TextArea, ThemeContext, ThemeProvider, ThemeToggle, TrashIcon, TruckIcon, UsersIcon, VenueMapEditor, VenueMapViewer, WhatsAppIcon, findNearestNode, genId, parseSvgMarkup, snapPoint, snapToGrid, useLibraryStorage, usePanZoom, useTheme };
4191
4531
  //# sourceMappingURL=index.mjs.map
4192
4532
  //# sourceMappingURL=index.mjs.map