@beweco/aurora-ui 0.0.9 → 0.0.11

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 (96) hide show
  1. package/dist/assets/css/styles.css +1 -1
  2. package/dist/index.cjs.js +673 -14
  3. package/dist/index.esm.js +664 -17
  4. package/dist/types/components/autocomplete/AutoComplete.d.ts +13 -0
  5. package/dist/types/components/autocomplete/AutoComplete.d.ts.map +1 -0
  6. package/dist/types/components/autocomplete/AutoComplete.types.d.ts +8 -0
  7. package/dist/types/components/autocomplete/AutoComplete.types.d.ts.map +1 -0
  8. package/dist/types/components/autocomplete/index.d.ts +3 -0
  9. package/dist/types/components/autocomplete/index.d.ts.map +1 -0
  10. package/dist/types/components/button/Button.d.ts +12 -5
  11. package/dist/types/components/button/Button.d.ts.map +1 -1
  12. package/dist/types/components/button/Button.types.d.ts +10 -20
  13. package/dist/types/components/button/Button.types.d.ts.map +1 -1
  14. package/dist/types/components/button/index.d.ts +2 -2
  15. package/dist/types/components/button/index.d.ts.map +1 -1
  16. package/dist/types/components/card/Card.d.ts +13 -0
  17. package/dist/types/components/card/Card.d.ts.map +1 -0
  18. package/dist/types/components/card/Card.types.d.ts +15 -0
  19. package/dist/types/components/card/Card.types.d.ts.map +1 -0
  20. package/dist/types/components/card/index.d.ts +3 -0
  21. package/dist/types/components/card/index.d.ts.map +1 -0
  22. package/dist/types/components/header/Header.d.ts +5 -0
  23. package/dist/types/components/header/Header.d.ts.map +1 -0
  24. package/dist/types/components/header/Header.types.d.ts +27 -0
  25. package/dist/types/components/header/Header.types.d.ts.map +1 -0
  26. package/dist/types/components/header/_internal/config-menu/ConfigMenu.d.ts +4 -0
  27. package/dist/types/components/header/_internal/config-menu/ConfigMenu.d.ts.map +1 -0
  28. package/dist/types/components/header/_internal/config-menu/ConfigMenu.types.d.ts +9 -0
  29. package/dist/types/components/header/_internal/config-menu/ConfigMenu.types.d.ts.map +1 -0
  30. package/dist/types/components/header/_internal/notification-button/NotificationButton.d.ts +7 -0
  31. package/dist/types/components/header/_internal/notification-button/NotificationButton.d.ts.map +1 -0
  32. package/dist/types/components/header/index.d.ts +3 -0
  33. package/dist/types/components/header/index.d.ts.map +1 -0
  34. package/dist/types/components/input/Input.d.ts +14 -0
  35. package/dist/types/components/input/Input.d.ts.map +1 -0
  36. package/dist/types/components/input/Input.types.d.ts +8 -0
  37. package/dist/types/components/input/Input.types.d.ts.map +1 -0
  38. package/dist/types/components/input/index.d.ts +3 -0
  39. package/dist/types/components/input/index.d.ts.map +1 -0
  40. package/dist/types/components/{Menu → menu}/Menu.d.ts.map +1 -1
  41. package/dist/types/components/{Menu → menu}/Menu.types.d.ts +1 -1
  42. package/dist/types/components/{Menu → menu}/Menu.types.d.ts.map +1 -1
  43. package/dist/types/components/{menu-nav-list → menu/_internal/menu-nav-list}/MenuNavList.d.ts +1 -2
  44. package/dist/types/components/menu/_internal/menu-nav-list/MenuNavList.d.ts.map +1 -0
  45. package/dist/types/components/menu/_internal/menu-nav-list/MenuNavList.styles.d.ts.map +1 -0
  46. package/dist/types/components/menu/_internal/menu-nav-list/MenuNavList.types.d.ts.map +1 -0
  47. package/dist/types/components/{menu-nav-list → menu/_internal/menu-nav-list}/index.d.ts +1 -0
  48. package/dist/types/components/menu/_internal/menu-nav-list/index.d.ts.map +1 -0
  49. package/dist/types/components/menu/sidebar-items.d.ts +3 -0
  50. package/dist/types/components/{Menu → menu}/sidebar-items.d.ts.map +1 -1
  51. package/dist/types/components/phone/Phone.d.ts +1 -20
  52. package/dist/types/components/phone/Phone.d.ts.map +1 -1
  53. package/dist/types/components/phone/Phone.types.d.ts +21 -0
  54. package/dist/types/components/phone/Phone.types.d.ts.map +1 -0
  55. package/dist/types/components/phone/index.d.ts +1 -0
  56. package/dist/types/components/phone/index.d.ts.map +1 -1
  57. package/dist/types/components/select/Select.d.ts +14 -0
  58. package/dist/types/components/select/Select.d.ts.map +1 -0
  59. package/dist/types/components/select/Select.types.d.ts +8 -0
  60. package/dist/types/components/select/Select.types.d.ts.map +1 -0
  61. package/dist/types/components/select/index.d.ts +3 -0
  62. package/dist/types/components/select/index.d.ts.map +1 -0
  63. package/dist/types/components/theme-picker/ThemePicker.d.ts +14 -0
  64. package/dist/types/components/theme-picker/ThemePicker.d.ts.map +1 -0
  65. package/dist/types/components/theme-picker/ThemePicker.types.d.ts +21 -0
  66. package/dist/types/components/theme-picker/ThemePicker.types.d.ts.map +1 -0
  67. package/dist/types/components/theme-picker/index.d.ts +3 -0
  68. package/dist/types/components/theme-picker/index.d.ts.map +1 -0
  69. package/dist/types/components/upload-file/UploadFile.d.ts +20 -0
  70. package/dist/types/components/upload-file/UploadFile.d.ts.map +1 -0
  71. package/dist/types/components/upload-file/UploadFile.types.d.ts +104 -0
  72. package/dist/types/components/upload-file/UploadFile.types.d.ts.map +1 -0
  73. package/dist/types/components/upload-file/index.d.ts +3 -0
  74. package/dist/types/components/upload-file/index.d.ts.map +1 -0
  75. package/dist/types/index.d.ts +9 -1
  76. package/dist/types/index.d.ts.map +1 -1
  77. package/package.json +1 -1
  78. package/dist/assets/output-Ck0ffzyL.css +0 -73
  79. package/dist/types/components/Menu/sidebar-items.d.ts +0 -3
  80. package/dist/types/components/index.d.ts +0 -4
  81. package/dist/types/components/index.d.ts.map +0 -1
  82. package/dist/types/components/menu-nav-list/MenuNavList.d.ts.map +0 -1
  83. package/dist/types/components/menu-nav-list/MenuNavList.styles.d.ts.map +0 -1
  84. package/dist/types/components/menu-nav-list/MenuNavList.types.d.ts.map +0 -1
  85. package/dist/types/components/menu-nav-list/index.d.ts.map +0 -1
  86. package/dist/types/components/menuprueba/MenuPrueba.d.ts +0 -4
  87. package/dist/types/components/menuprueba/MenuPrueba.d.ts.map +0 -1
  88. package/dist/types/components/menuprueba/MenuPrueba.types.d.ts +0 -23
  89. package/dist/types/components/menuprueba/MenuPrueba.types.d.ts.map +0 -1
  90. package/dist/types/components/menuprueba/index.d.ts +0 -3
  91. package/dist/types/components/menuprueba/index.d.ts.map +0 -1
  92. /package/dist/types/components/{Menu → menu}/Menu.d.ts +0 -0
  93. /package/dist/types/components/{menu-nav-list → menu/_internal/menu-nav-list}/MenuNavList.styles.d.ts +0 -0
  94. /package/dist/types/components/{menu-nav-list → menu/_internal/menu-nav-list}/MenuNavList.types.d.ts +0 -0
  95. /package/dist/types/components/{Menu → menu}/index.d.ts +0 -0
  96. /package/dist/types/components/{Menu → menu}/index.d.ts.map +0 -0
package/dist/index.cjs.js CHANGED
@@ -1,7 +1,7 @@
1
1
  'use strict';
2
2
 
3
- var jsxRuntime = require('react/jsx-runtime');
4
3
  var react = require('@heroui/react');
4
+ var jsxRuntime = require('react/jsx-runtime');
5
5
  var React = require('react');
6
6
  var react$1 = require('@iconify/react');
7
7
  var useTheme = require('@heroui/use-theme');
@@ -52,15 +52,22 @@ typeof SuppressedError === "function" ? SuppressedError : function (error, suppr
52
52
  };
53
53
 
54
54
  /**
55
- * Button component with HeroUI styling
56
- * Provides a consistent interface for button interactions across the application
55
+ * AutoComplete genérico reutilizable basado en HeroUI siguiendo las reglas de diseño BeweOS.
56
+ *
57
+ * Reglas aplicadas:
58
+ * - Variant: Bordered (por defecto)
59
+ * - Radius: md (por defecto)
60
+ * - labelPlacement: Outside
61
+ * - Size: sm, md, lg (configurable)
57
62
  */
58
- var ButtonPrueba = function (_a) {
59
- var children = _a.children, startIcon = _a.startIcon, endIcon = _a.endIcon, _b = _a.loading, loading = _b === void 0 ? false : _b, disabled = _a.disabled, _c = _a.variant, variant = _c === void 0 ? "solid" : _c, _d = _a.color, color = _d === void 0 ? "primary" : _d, _e = _a.size, size = _e === void 0 ? "md" : _e, radius = _a.radius, _f = _a.fullWidth, fullWidth = _f === void 0 ? false : _f, _g = _a.className, className = _g === void 0 ? "" : _g, props = __rest(_a, ["children", "startIcon", "endIcon", "loading", "disabled", "variant", "color", "size", "radius", "fullWidth", "className"]);
60
- React.useEffect(function () {
61
- // console.log("estamos dentro del botnon");
62
- }, []);
63
- return (jsxRuntime.jsx(react.Button, __assign({ variant: variant, color: color, size: size, radius: radius, fullWidth: fullWidth, isLoading: loading, isDisabled: disabled, startContent: startIcon, endContent: endIcon, className: className }, props, { children: children })));
63
+ var AutoComplete = function (_a) {
64
+ var label = _a.label, id = _a.id, _b = _a.size, size = _b === void 0 ? "md" : _b, _c = _a.variant, variant = _c === void 0 ? "bordered" : _c, _d = _a.radius, radius = _d === void 0 ? "md" : _d, props = __rest(_a, ["label", "id", "size", "variant", "radius"]);
65
+ var generatedId = React.useId();
66
+ var autoId = id || generatedId;
67
+ return (jsxRuntime.jsxs("div", { children: [label && (jsxRuntime.jsx("label", { htmlFor: autoId, className: "block mb-2 text-tiny text-default-600", children: label })), jsxRuntime.jsx(react.Autocomplete, __assign({}, props, { id: autoId, label: undefined, labelPlacement: "outside", variant: variant, size: size, radius: radius, classNames: {
68
+ base: "[&_[data-slot=input-wrapper][data-focus=true]]:!border-primary-500",
69
+ popoverContent: "[&_li[data-hover=true]]:!bg-primary-50 [&_li[data-hover=true]]:!text-default-600 [&_li]:!text-default-500",
70
+ } }))] }));
64
71
  };
65
72
 
66
73
  var sizeMap = {
@@ -248,9 +255,9 @@ var MenuComponent = React.memo(function Menu(_a) {
248
255
  }
249
256
  return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("button", { type: "button", "aria-label": "Close sidebar", className: "fixed inset-0 bg-black bg-opacity-40 z-40 xs:block sm:hidden", onClick: handleSidebarClose, style: { border: "none", padding: 0, margin: 0 } }), jsxRuntime.jsx("div", { className: "container__menu ".concat(isCollapsed
250
257
  ? "container__menu--collapsed"
251
- : "container__menu--expanded"), children: jsxRuntime.jsxs("div", { className: "content__menu", children: [jsxRuntime.jsxs("div", { className: "content__menu--header", style: { flexDirection: isCollapsed ? "column-reverse" : "row" }, children: [jsxRuntime.jsxs("div", { className: "flex flex-row items-center justify-center ".concat(isCollapsed ? "gap-0" : "gap-2"), children: [jsxRuntime.jsx("div", { className: "flex h-8 w-8 items-center justify-center rounded-full bg-foreground", children: jsxRuntime.jsx("img", { src: commerceInfo.logo, alt: "Logo of ".concat(commerceInfo.name) }) }), jsxRuntime.jsx("span", { className: "collapsible-item text-small font-bold uppercase", children: commerceInfo.name })] }), jsxRuntime.jsxs("div", { className: "flex items-center", children: [jsxRuntime.jsx(IconComponent, { icon: "material-symbols-light:close", size: "lg", className: "cursor-pointer block sm:hidden", onClick: handleSidebarClose }), jsxRuntime.jsx(IconComponent, { icon: isCollapsed
258
+ : "container__menu--expanded"), children: jsxRuntime.jsxs("div", { className: "content__menu", children: [jsxRuntime.jsxs("div", { className: "content__menu--header", style: { flexDirection: isCollapsed ? "column-reverse" : "row" }, children: [jsxRuntime.jsxs("div", { className: "flex flex-row items-center justify-center ".concat(isCollapsed ? "gap-0" : "gap-2"), children: [jsxRuntime.jsx("div", { className: "flex h-8 w-8 items-center justify-center rounded-full bg-foreground", children: jsxRuntime.jsx("img", { src: commerceInfo.logo, alt: "Logo of ".concat(commerceInfo.name) }) }), jsxRuntime.jsx("span", { className: "collapsible-item text-small font-bold ", children: commerceInfo.name })] }), jsxRuntime.jsxs("div", { className: "flex items-center", children: [jsxRuntime.jsx(IconComponent, { icon: "material-symbols-light:close", size: "lg", className: "cursor-pointer block sm:hidden", onClick: handleSidebarClose }), jsxRuntime.jsx(IconComponent, { icon: isCollapsed
252
259
  ? "solar:alt-arrow-right-outline"
253
- : "solar:alt-arrow-left-outline", size: "lg", className: "hidden sm:block cursor-pointer", onClick: handleCollapseToggle })] })] }), jsxRuntime.jsx(react.Spacer, { y: 6 }), jsxRuntime.jsxs("div", { className: "content__menu--user ".concat(isCollapsed ? "gap-0" : "gap-3"), children: [jsxRuntime.jsx(react.Avatar, { size: "md", src: userInfo.avatar, color: userInfo.avatar === "" ? "warning" : "default", name: userInfo.name }), jsxRuntime.jsxs("div", { className: "collapsible-item flex flex-col", children: [jsxRuntime.jsx("p", { className: "text-small font-medium text-default-900", children: userInfo.name }), jsxRuntime.jsx("p", { className: "text-tiny text-default-400", children: userInfo.role })] })] }), jsxRuntime.jsx("div", { className: "".concat(!isCollapsed ? "flex-1" : "h-full", " min-h-0 py-6"), children: jsxRuntime.jsx("div", { className: "h-full overflow-y-auto pr-6 -mr-6 [&::-webkit-scrollbar]:hidden [-ms-overflow-style:none] [scrollbar-width:none]", children: jsxRuntime.jsx(MenuNavList, { defaultSelectedKey: menuItems.selectedKey, items: menuItems.items, isCollapsed: isCollapsed }) }) }), upgradeCard && (jsxRuntime.jsxs("div", { className: "collapsible-item relative", children: [jsxRuntime.jsxs(react.Card, { className: "border-none overflow-visible shadow-none", shadow: "sm", children: [jsxRuntime.jsxs(react.CardBody, { className: "items-center py-5 text-center gap-1", children: [jsxRuntime.jsx("h3", { className: "text-medium font-medium text-default-900", children: upgradeCard.title }), jsxRuntime.jsx("p", { className: "text-small text-default-500 pb-3 whitespace-normal", children: upgradeCard.description })] }), jsxRuntime.jsx(react.CardFooter, { className: "absolute justify-center", style: { bottom: "-30px" }, children: jsxRuntime.jsx(react.Button, { className: "px-10 shadow-md", color: "primary", radius: "full", variant: "shadow", onPress: handleUpgradeClick, children: upgradeCard.buttonText }) })] }), jsxRuntime.jsx(react.Spacer, { y: 9 })] })), jsxRuntime.jsx("div", { className: "mt-auto flex flex-col justify-center items-center", children: jsxRuntime.jsx(react.Button, { fullWidth: true, className: " text-default-600 data-[hover=true]:text-foreground", startContent: jsxRuntime.jsx(IconComponent, { className: "text-default-500", icon: "solar:info-circle-line-duotone", size: "md" }), variant: "light", onPress: handleHelpClick, isIconOnly: isCollapsed, children: !isCollapsed && (jsxRuntime.jsx("span", { className: "collapsible-item", children: helpButton.title })) }) })] }) })] }));
260
+ : "solar:alt-arrow-left-outline", size: "lg", className: "hidden sm:block cursor-pointer", onClick: handleCollapseToggle })] })] }), jsxRuntime.jsx(react.Spacer, { y: 6 }), jsxRuntime.jsxs("div", { className: "content__menu--user ".concat(isCollapsed ? "gap-0" : "gap-3"), children: [jsxRuntime.jsx(react.Avatar, { size: "md", src: userInfo.avatar, color: userInfo.avatar === "" ? "warning" : "default", name: userInfo.name }), jsxRuntime.jsxs("div", { className: "collapsible-item flex flex-col", children: [jsxRuntime.jsx("p", { className: "text-small font-medium text-default-900", children: userInfo.name }), jsxRuntime.jsx("p", { className: "text-tiny text-default-400", children: userInfo.role })] })] }), jsxRuntime.jsx("div", { className: "".concat(!isCollapsed ? "flex-1" : "h-full", " min-h-0 py-6"), children: jsxRuntime.jsx("div", { className: "h-full overflow-y-auto pr-6 -mr-6 [&::-webkit-scrollbar]:hidden [-ms-overflow-style:none] [scrollbar-width:none]", children: jsxRuntime.jsx(MenuNavList, { defaultSelectedKey: menuItems.selectedKey, items: menuItems.items, isCollapsed: isCollapsed }) }) }), upgradeCard && (jsxRuntime.jsxs("div", { className: "collapsible-item relative", children: [jsxRuntime.jsxs(react.Card, { className: "border-none overflow-visible shadow-none", shadow: "sm", children: [jsxRuntime.jsxs(react.CardBody, { className: "items-center py-5 text-center gap-1", children: [jsxRuntime.jsx("h3", { className: "text-medium font-medium text-default-900", children: upgradeCard.title }), jsxRuntime.jsx("p", { className: "text-small text-default-500 pb-3 whitespace-normal", children: upgradeCard.description })] }), jsxRuntime.jsx(react.CardFooter, { className: "absolute justify-center", style: { bottom: "-30px" }, children: jsxRuntime.jsx(react.Button, { className: "px-10 shadow-md", color: "primary", radius: "full", variant: "shadow", onPress: handleUpgradeClick, children: upgradeCard.buttonText }) })] }), jsxRuntime.jsx(react.Spacer, { y: 9 })] })), jsxRuntime.jsx("div", { className: "mt-auto flex flex-col justify-center items-center", children: jsxRuntime.jsx(react.Button, { fullWidth: true, className: " text-default-500 data-[hover=true]:text-default-600", startContent: jsxRuntime.jsx(IconComponent, { className: "text-default-500", icon: "solar:info-circle-line-duotone", size: "md" }), variant: "light", onPress: handleHelpClick, isIconOnly: isCollapsed, children: !isCollapsed && (jsxRuntime.jsx("span", { className: "collapsible-item", children: helpButton.title })) }) })] }) })] }));
254
261
  });
255
262
 
256
263
  // Lista simple de países con bandera emoji y código
@@ -294,7 +301,8 @@ var countries = [
294
301
  { code: "+971", name: "UAE", flag: "🇦🇪" },
295
302
  ];
296
303
  var uniqueCountries = Array.from(new Map(countries.map(function (item) { return [item.code + item.name, item]; })).values());
297
- var defaultTranslations = {
304
+ // Traducciones por defecto
305
+ var defaultTranslations$2 = {
298
306
  label: "Teléfono",
299
307
  placeholder: "Número de teléfono",
300
308
  searchPlaceholder: "Buscar país...",
@@ -310,7 +318,7 @@ var Phone = function (_a) {
310
318
  var dropdownRef = React.useRef(null);
311
319
  var _m = React.useState(uniqueCountries), filteredCountries = _m[0], setFilteredCountries = _m[1];
312
320
  // Combinar traducciones por defecto con las proporcionadas
313
- var t = __assign(__assign({}, defaultTranslations), translations);
321
+ var t = __assign(__assign({}, defaultTranslations$2), translations);
314
322
  // Usar la etiqueta de las traducciones si no se proporciona label explícitamente
315
323
  var finalLabel = label || t.label;
316
324
  // Sincroniza valor externo
@@ -379,6 +387,644 @@ var Phone = function (_a) {
379
387
  : ""), onClick: function () { return handleCountrySelect(country); }, children: [jsxRuntime.jsx("span", { className: "mr-3 text-lg", children: country.flag }), jsxRuntime.jsx("span", { className: "flex-1 text-left dark:text-gray-100", children: country.name }), jsxRuntime.jsx("span", { className: "text-xs text-gray-500 dark:text-gray-400", children: country.code })] }, country.code)); })) : (jsxRuntime.jsx("div", { className: "px-4 py-2 text-sm text-gray-500 dark:text-gray-400", children: t.noCountriesFound })) })] }))] }), jsxRuntime.jsx(react.Input, { type: "tel", className: "flex-1 border-none bg-transparent text-gray-900 dark:text-gray-100 placeholder-gray-400 dark:placeholder-gray-500 h-10 px-2", placeholder: t.placeholder, value: inputValue, onChange: handleInputChange, onBlur: onBlur, disabled: disabled, name: name, autoComplete: "tel", id: "phone-input-".concat(name) })] }), error && errorText && (jsxRuntime.jsx("span", { className: "text-xs text-pink-600 dark:text-pink-400 mt-1", children: errorText }))] }));
380
388
  };
381
389
 
390
+ // Traducciones por defecto en español según las reglas de diseño
391
+ var defaultTranslations$1 = {
392
+ lightTheme: "Claro",
393
+ darkTheme: "Oscuro",
394
+ };
395
+ /**
396
+ * Selector de tema visual con preview interactivo siguiendo las reglas de diseño BeweOS.
397
+ *
398
+ * Reglas aplicadas:
399
+ * - Soporte completo de traducciones mediante props
400
+ * - Sin dependencias de sistemas i18n específicos
401
+ * - Dark mode compatible
402
+ * - Uso exclusivo de Tailwind CSS
403
+ */
404
+ var ThemePicker = function (_a) {
405
+ var value = _a.value, onChange = _a.onChange, className = _a.className, _b = _a.translations, translations = _b === void 0 ? {} : _b;
406
+ // Combinar traducciones por defecto con las proporcionadas
407
+ var t = __assign(__assign({}, defaultTranslations$1), translations);
408
+ var themes = [
409
+ {
410
+ key: "light",
411
+ label: t.lightTheme,
412
+ cardClass: "bg-white border border-[#E4E4E7] text-zinc-900",
413
+ previewClass: "bg-[#F4F4F5] border border-[#E4E4E7]",
414
+ labelClass: "font-medium text-[14px] leading-[20px] text-zinc-900",
415
+ radioColor: "primary",
416
+ previewContent: (jsxRuntime.jsxs("div", { className: "rounded-lg border border-[#E4E4E7] p-3 mt-4 flex flex-col gap-2", children: [jsxRuntime.jsx("div", { className: "h-3 w-1/2 bg-[#E4E4E7] rounded mb-2" }), jsxRuntime.jsxs("div", { className: "flex flex-col gap-1", children: [jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [jsxRuntime.jsx("div", { className: "h-3 w-3 rounded-full bg-[#E4E4E7]" }), jsxRuntime.jsx("div", { className: "h-3 w-1/3 rounded bg-[#E4E4E7]" })] }), jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [jsxRuntime.jsx("div", { className: "h-3 w-3 rounded-full bg-[#E4E4E7]" }), jsxRuntime.jsx("div", { className: "h-3 w-1/4 rounded bg-[#E4E4E7]" })] })] }), jsxRuntime.jsx("div", { className: "h-8 w-2/3 bg-[#F4F4F5] rounded-lg mt-2" })] })),
417
+ },
418
+ {
419
+ key: "dark",
420
+ label: t.darkTheme,
421
+ cardClass: "bg-black border border-[#3F3F46] text-white",
422
+ previewClass: "bg-[#27272A] border border-[#3F3F46]",
423
+ labelClass: "font-medium text-[14px] leading-[20px] text-white",
424
+ radioColor: "primary",
425
+ previewContent: (jsxRuntime.jsxs("div", { className: "rounded-lg border border-[#3F3F46] p-3 mt-4 flex flex-col gap-2", children: [jsxRuntime.jsx("div", { className: "h-3 w-1/2 bg-[#3F3F46] rounded mb-2" }), jsxRuntime.jsxs("div", { className: "flex flex-col gap-1", children: [jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [jsxRuntime.jsx("div", { className: "h-3 w-3 rounded-full bg-[#3F3F46]" }), jsxRuntime.jsx("div", { className: "h-3 w-1/3 rounded bg-[#3F3F46]" })] }), jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [jsxRuntime.jsx("div", { className: "h-3 w-3 rounded-full bg-[#3F3F46]" }), jsxRuntime.jsx("div", { className: "h-3 w-1/4 rounded bg-[#3F3F46]" })] })] }), jsxRuntime.jsx("div", { className: "h-8 w-2/3 bg-[#27272A] rounded-lg mt-2" })] })),
426
+ },
427
+ ];
428
+ return (jsxRuntime.jsx(react.RadioGroup, { value: value, onChange: function (e) { return onChange(e.target.value); }, className: "flex gap-6 w-full ".concat(className || ""), style: { gap: 16 }, children: themes.map(function (theme) { return (jsxRuntime.jsxs("div", { className: "relative rounded-[14px] ".concat(theme.cardClass, " p-6 w-1/2 min-h-[180px] transition-all duration-200 flex flex-col justify-start"), children: [jsxRuntime.jsx("div", { className: "absolute top-6 right-6", children: jsxRuntime.jsx(react.Radio, { "aria-label": theme.label, color: theme.radioColor, size: "sm", value: theme.key }) }), jsxRuntime.jsx("span", { className: theme.labelClass, children: theme.label }), theme.previewContent] }, theme.key)); }) }));
429
+ };
430
+
431
+ // Traducciones por defecto en español
432
+ var defaultTranslations = {
433
+ uploadText: "Da clic y selecciona tus archivos",
434
+ subText: "",
435
+ dragText: "Suelta el archivo aquí",
436
+ multipleFilesError: "Solo puedes subir un archivo",
437
+ maxFilesError: "Puedes subir máximo {maxFiles} archivos",
438
+ invalidFileTypeError: "Solo se aceptan archivos de tipo: {acceptedTypes}",
439
+ maxFileSizeError: "El archivo excede el tamaño máximo permitido de {maxSize}",
440
+ removeFileAriaLabel: "Remover archivo",
441
+ uploadAreaAriaLabel: "Área de carga de archivos",
442
+ cropModalTitle: "Recortar imagen",
443
+ cropSaveButton: "Guardar",
444
+ cropCancelButton: "Cancelar",
445
+ cropZoomLabel: "Zoom",
446
+ cropInstructions: "Arrastra para mover la imagen y usa el zoom para ajustar el tamaño",
447
+ cropBackgroundLabel: "Color de fondo",
448
+ cropBackgroundWhite: "Blanco",
449
+ cropBackgroundBlack: "Negro",
450
+ cropBackgroundTransparent: "Transparente",
451
+ };
452
+ /**
453
+ * Formatea el tipo de archivo para mostrar
454
+ */
455
+ var formatFileType = function (type) {
456
+ var _a;
457
+ if (type.startsWith(".")) {
458
+ return type.toUpperCase();
459
+ }
460
+ if (type.includes("/")) {
461
+ var parts = type.split("/");
462
+ return ((_a = parts[1]) === null || _a === void 0 ? void 0 : _a.toUpperCase()) || type;
463
+ }
464
+ return type.toUpperCase();
465
+ };
466
+ /**
467
+ * Formatea el tamaño del archivo de forma legible
468
+ */
469
+ var formatFileSize = function (bytes) {
470
+ if (bytes === 0) {
471
+ return "0 Bytes";
472
+ }
473
+ var k = 1024;
474
+ var sizes = ["Bytes", "KB", "MB", "GB"];
475
+ var i = Math.floor(Math.log(bytes) / Math.log(k));
476
+ return "".concat(Math.round(bytes / Math.pow(k, i)), " ").concat(sizes[i]);
477
+ };
478
+ /**
479
+ * Componente de recorte de imagen usando Canvas API
480
+ */
481
+ var ImageCropModal = function (_a) {
482
+ var isOpen = _a.isOpen, imageUrl = _a.imageUrl, targetWidth = _a.targetWidth, targetHeight = _a.targetHeight, onSave = _a.onSave, onCancel = _a.onCancel, translations = _a.translations;
483
+ var canvasRef = React.useRef(null);
484
+ var _b = React.useState(null), imageElement = _b[0], setImageElement = _b[1];
485
+ var _c = React.useState(0), zoomValue = _c[0], setZoomValue = _c[1]; // Valor del slider de -1 a 1
486
+ var _d = React.useState({ x: 0, y: 0 }), position = _d[0], setPosition = _d[1];
487
+ var _e = React.useState(false), isDragging = _e[0], setIsDragging = _e[1];
488
+ var _f = React.useState({ x: 0, y: 0 }), dragStart = _f[0], setDragStart = _f[1];
489
+ var _g = React.useState(1), baseScale = _g[0], setBaseScale = _g[1]; // Escala base inicial
490
+ var _h = React.useState({ width: 400, height: 300 }), canvasSize = _h[0], setCanvasSize = _h[1];
491
+ var _j = React.useState("white"), backgroundColor = _j[0], setBackgroundColor = _j[1];
492
+ // Función para convertir el valor del zoom slider a escala real
493
+ var getScaleFromZoom = function (zoomValue) {
494
+ if (zoomValue === 0) {
495
+ return baseScale;
496
+ }
497
+ if (zoomValue > 0) {
498
+ // Zoom in: de baseScale a baseScale * 3
499
+ return baseScale + baseScale * 2 * zoomValue;
500
+ }
501
+ // Zoom out: de baseScale * 0.3 a baseScale
502
+ return baseScale + baseScale * 0.7 * zoomValue;
503
+ };
504
+ var currentScale = getScaleFromZoom(zoomValue);
505
+ // Cargar imagen cuando se abre el modal
506
+ React.useEffect(function () {
507
+ if (isOpen && imageUrl) {
508
+ var img_1 = new Image();
509
+ img_1.onload = function () {
510
+ setImageElement(img_1);
511
+ // Calcular escala inicial para que la imagen quepa en el área de crop
512
+ var scaleX = targetWidth / img_1.width;
513
+ var scaleY = targetHeight / img_1.height;
514
+ var initialScale = Math.max(scaleX, scaleY);
515
+ setBaseScale(initialScale);
516
+ setZoomValue(0); // Empezar en el centro
517
+ setPosition({ x: 0, y: 0 });
518
+ setBackgroundColor("white"); // Reset color de fondo
519
+ };
520
+ img_1.src = imageUrl;
521
+ }
522
+ }, [isOpen, imageUrl, targetWidth, targetHeight]);
523
+ // Dibujar en el canvas
524
+ React.useEffect(function () {
525
+ if (!(imageElement && canvasRef.current)) {
526
+ return;
527
+ }
528
+ var canvas = canvasRef.current;
529
+ var ctx = canvas.getContext("2d");
530
+ if (!ctx) {
531
+ return;
532
+ }
533
+ // Limpiar canvas
534
+ ctx.clearRect(0, 0, canvas.width, canvas.height);
535
+ // Dibujar fondo gris del canvas
536
+ ctx.fillStyle = "#f3f4f6";
537
+ ctx.fillRect(0, 0, canvas.width, canvas.height);
538
+ // Calcular posición y tamaño de la imagen
539
+ var imgWidth = imageElement.width * currentScale;
540
+ var imgHeight = imageElement.height * currentScale;
541
+ var imgX = (canvas.width - imgWidth) / 2 + position.x;
542
+ var imgY = (canvas.height - imgHeight) / 2 + position.y;
543
+ // Dibujar imagen
544
+ ctx.drawImage(imageElement, imgX, imgY, imgWidth, imgHeight);
545
+ // Dibujar overlay para mostrar área de recorte
546
+ ctx.fillStyle = "rgba(0, 0, 0, 0.5)";
547
+ ctx.fillRect(0, 0, canvas.width, canvas.height);
548
+ // Limpiar área de recorte (centro)
549
+ var cropX = (canvas.width - targetWidth) / 2;
550
+ var cropY = (canvas.height - targetHeight) / 2;
551
+ ctx.clearRect(cropX, cropY, targetWidth, targetHeight);
552
+ // Dibujar color de fondo del área de recorte
553
+ if (backgroundColor !== "transparent") {
554
+ ctx.fillStyle = backgroundColor === "white" ? "#ffffff" : "#000000";
555
+ ctx.fillRect(cropX, cropY, targetWidth, targetHeight);
556
+ }
557
+ // Redibujar imagen solo en el área de recorte
558
+ ctx.save();
559
+ ctx.beginPath();
560
+ ctx.rect(cropX, cropY, targetWidth, targetHeight);
561
+ ctx.clip();
562
+ ctx.drawImage(imageElement, imgX, imgY, imgWidth, imgHeight);
563
+ ctx.restore();
564
+ // Dibujar borde del área de recorte
565
+ ctx.strokeStyle = "#3b82f6";
566
+ ctx.lineWidth = 2;
567
+ ctx.strokeRect(cropX, cropY, targetWidth, targetHeight);
568
+ }, [
569
+ imageElement,
570
+ currentScale,
571
+ position,
572
+ targetWidth,
573
+ targetHeight,
574
+ backgroundColor,
575
+ ]);
576
+ var handleMouseDown = function (e) {
577
+ var _a;
578
+ e.preventDefault();
579
+ setIsDragging(true);
580
+ var rect = (_a = canvasRef.current) === null || _a === void 0 ? void 0 : _a.getBoundingClientRect();
581
+ if (rect) {
582
+ setDragStart({
583
+ x: e.clientX - rect.left - position.x,
584
+ y: e.clientY - rect.top - position.y,
585
+ });
586
+ }
587
+ };
588
+ var handleMouseMove = function (e) {
589
+ var _a;
590
+ if (!isDragging) {
591
+ return;
592
+ }
593
+ e.preventDefault();
594
+ var rect = (_a = canvasRef.current) === null || _a === void 0 ? void 0 : _a.getBoundingClientRect();
595
+ if (rect) {
596
+ setPosition({
597
+ x: e.clientX - rect.left - dragStart.x,
598
+ y: e.clientY - rect.top - dragStart.y,
599
+ });
600
+ }
601
+ };
602
+ var handleMouseUp = function () {
603
+ setIsDragging(false);
604
+ };
605
+ // Eventos táctiles para dispositivos móviles
606
+ var handleTouchStart = function (e) {
607
+ var _a;
608
+ e.preventDefault();
609
+ if (e.touches.length === 1) {
610
+ setIsDragging(true);
611
+ var rect = (_a = canvasRef.current) === null || _a === void 0 ? void 0 : _a.getBoundingClientRect();
612
+ if (rect) {
613
+ var touch = e.touches[0];
614
+ setDragStart({
615
+ x: touch.clientX - rect.left - position.x,
616
+ y: touch.clientY - rect.top - position.y,
617
+ });
618
+ }
619
+ }
620
+ };
621
+ var handleTouchMove = function (e) {
622
+ var _a;
623
+ if (!isDragging || e.touches.length !== 1) {
624
+ return;
625
+ }
626
+ e.preventDefault();
627
+ var rect = (_a = canvasRef.current) === null || _a === void 0 ? void 0 : _a.getBoundingClientRect();
628
+ if (rect) {
629
+ var touch = e.touches[0];
630
+ setPosition({
631
+ x: touch.clientX - rect.left - dragStart.x,
632
+ y: touch.clientY - rect.top - dragStart.y,
633
+ });
634
+ }
635
+ };
636
+ var handleTouchEnd = function () {
637
+ setIsDragging(false);
638
+ };
639
+ var handleSave = function () {
640
+ if (!(imageElement && canvasRef.current)) {
641
+ return;
642
+ }
643
+ // Crear canvas temporal para el recorte
644
+ var tempCanvas = document.createElement("canvas");
645
+ tempCanvas.width = targetWidth;
646
+ tempCanvas.height = targetHeight;
647
+ var tempCtx = tempCanvas.getContext("2d");
648
+ if (!tempCtx) {
649
+ return;
650
+ }
651
+ // Dibujar color de fondo si no es transparente
652
+ if (backgroundColor !== "transparent") {
653
+ tempCtx.fillStyle = backgroundColor === "white" ? "#ffffff" : "#000000";
654
+ tempCtx.fillRect(0, 0, targetWidth, targetHeight);
655
+ }
656
+ // Calcular parámetros de recorte
657
+ var canvas = canvasRef.current;
658
+ var imgWidth = imageElement.width * currentScale;
659
+ var imgHeight = imageElement.height * currentScale;
660
+ var imgX = (canvas.width - imgWidth) / 2 + position.x;
661
+ var imgY = (canvas.height - imgHeight) / 2 + position.y;
662
+ var cropX = (canvas.width - targetWidth) / 2;
663
+ var cropY = (canvas.height - targetHeight) / 2;
664
+ // Calcular área fuente en la imagen original
665
+ var sourceX = (cropX - imgX) / currentScale;
666
+ var sourceY = (cropY - imgY) / currentScale;
667
+ var sourceWidth = targetWidth / currentScale;
668
+ var sourceHeight = targetHeight / currentScale;
669
+ // Dibujar recorte sobre el fondo
670
+ tempCtx.drawImage(imageElement, sourceX, sourceY, sourceWidth, sourceHeight, 0, 0, targetWidth, targetHeight);
671
+ // Convertir a blob y crear archivo
672
+ var fileType = backgroundColor === "transparent" ? "image/png" : "image/png";
673
+ tempCanvas.toBlob(function (blob) {
674
+ if (blob) {
675
+ var timestamp = new Date().getTime();
676
+ var file = new File([blob], "cropped-image-".concat(timestamp, ".png"), {
677
+ type: fileType,
678
+ });
679
+ onSave(file, imageElement.src);
680
+ }
681
+ }, fileType);
682
+ };
683
+ // Calcular dimensiones responsive del canvas
684
+ var updateCanvasSize = React.useCallback(function () {
685
+ var minCanvasWidth = Math.min(350, window.innerWidth - 40);
686
+ var minCanvasHeight = Math.min(250, window.innerHeight - 300);
687
+ var newCanvasWidth = Math.max(minCanvasWidth, targetWidth + 60);
688
+ var newCanvasHeight = Math.max(minCanvasHeight, targetHeight + 60);
689
+ setCanvasSize({ width: newCanvasWidth, height: newCanvasHeight });
690
+ }, [targetWidth, targetHeight]);
691
+ // Actualizar tamaño del canvas al cambiar el tamaño de la ventana
692
+ React.useEffect(function () {
693
+ if (!isOpen) {
694
+ return;
695
+ }
696
+ updateCanvasSize();
697
+ var handleResize = function () {
698
+ updateCanvasSize();
699
+ };
700
+ window.addEventListener("resize", handleResize);
701
+ return function () {
702
+ window.removeEventListener("resize", handleResize);
703
+ };
704
+ }, [isOpen, updateCanvasSize]);
705
+ return (jsxRuntime.jsx(react.Modal, { isOpen: isOpen, onClose: onCancel, size: "5xl", className: "sm:max-w-4xl", scrollBehavior: "inside", backdrop: "blur", classNames: {
706
+ backdrop: "bg-black/80",
707
+ wrapper: "p-0 sm:p-4",
708
+ base: "m-0 sm:m-4 max-h-screen sm:max-h-[90vh] w-full sm:w-auto",
709
+ }, children: jsxRuntime.jsxs(react.ModalContent, { className: "m-0 sm:m-0 h-screen sm:h-auto sm:max-h-[90vh] sm:rounded-lg", children: [jsxRuntime.jsxs(react.ModalHeader, { className: "flex flex-col gap-1 px-4 sm:px-6", children: [translations.cropModalTitle, jsxRuntime.jsx("p", { className: "text-xs sm:text-sm text-gray-500 font-normal", children: translations.cropInstructions })] }), jsxRuntime.jsx(react.ModalBody, { className: "px-4 sm:px-6 py-4", children: jsxRuntime.jsxs("div", { className: "flex flex-col gap-4", children: [jsxRuntime.jsx("div", { className: "flex justify-center overflow-hidden", children: jsxRuntime.jsx("canvas", { ref: canvasRef, width: canvasSize.width, height: canvasSize.height, className: "border border-gray-300 cursor-move select-none max-w-full max-h-[50vh] sm:max-h-[60vh]", onMouseDown: handleMouseDown, onMouseMove: handleMouseMove, onMouseUp: handleMouseUp, onMouseLeave: handleMouseUp, onTouchStart: handleTouchStart, onTouchMove: handleTouchMove, onTouchEnd: handleTouchEnd, style: { touchAction: "none" } }) }), jsxRuntime.jsxs("div", { className: "flex flex-col gap-2", children: [jsxRuntime.jsx("label", { htmlFor: "zoom-slider", className: "text-sm font-medium", children: translations.cropZoomLabel }), jsxRuntime.jsxs("div", { className: "flex items-center gap-2 sm:gap-3 w-full", children: [jsxRuntime.jsx("span", { className: "text-xs text-gray-500 min-w-[15px] sm:min-w-[20px]", children: "-" }), jsxRuntime.jsx(react.Slider, { id: "zoom-slider", size: "sm", step: 0.1, minValue: -1, maxValue: 1, value: zoomValue, onChange: function (value) { return setZoomValue(value); }, className: "flex-1", marks: [
710
+ { value: -1, label: "Out" },
711
+ { value: 0, label: "0" },
712
+ { value: 1, label: "In" },
713
+ ] }), jsxRuntime.jsx("span", { className: "text-xs text-gray-500 min-w-[15px] sm:min-w-[20px]", children: "+" })] })] }), jsxRuntime.jsxs("div", { className: "flex flex-col gap-2", children: [jsxRuntime.jsx("div", { className: "text-sm font-medium", children: translations.cropBackgroundLabel }), jsxRuntime.jsxs("div", { className: "flex flex-wrap gap-3 sm:gap-4", children: [jsxRuntime.jsxs("label", { className: "flex items-center gap-2 cursor-pointer", children: [jsxRuntime.jsx("input", { type: "radio", name: "background-color", value: "white", checked: backgroundColor === "white", onChange: function (e) {
714
+ return setBackgroundColor(e.target.value);
715
+ }, className: "text-blue-600 focus:ring-blue-500" }), jsxRuntime.jsx("div", { className: "w-4 h-4 bg-white border border-gray-300 rounded" }), jsxRuntime.jsx("span", { className: "text-sm", children: translations.cropBackgroundWhite })] }), jsxRuntime.jsxs("label", { className: "flex items-center gap-2 cursor-pointer", children: [jsxRuntime.jsx("input", { type: "radio", name: "background-color", value: "black", checked: backgroundColor === "black", onChange: function (e) {
716
+ return setBackgroundColor(e.target.value);
717
+ }, className: "text-blue-600 focus:ring-blue-500" }), jsxRuntime.jsx("div", { className: "w-4 h-4 bg-black border border-gray-300 rounded" }), jsxRuntime.jsx("span", { className: "text-sm", children: translations.cropBackgroundBlack })] }), jsxRuntime.jsxs("label", { className: "flex items-center gap-2 cursor-pointer", children: [jsxRuntime.jsx("input", { type: "radio", name: "background-color", value: "transparent", checked: backgroundColor === "transparent", onChange: function (e) {
718
+ return setBackgroundColor(e.target.value);
719
+ }, className: "text-blue-600 focus:ring-blue-500" }), jsxRuntime.jsx("div", { className: "w-4 h-4 bg-gray-200 border border-gray-300 rounded", style: {
720
+ backgroundImage: "linear-gradient(45deg, #ccc 25%, transparent 25%), linear-gradient(-45deg, #ccc 25%, transparent 25%), linear-gradient(45deg, transparent 75%, #ccc 75%), linear-gradient(-45deg, transparent 75%, #ccc 75%)",
721
+ backgroundSize: "8px 8px",
722
+ backgroundPosition: "0 0, 0 4px, 4px -4px, -4px 0px",
723
+ } }), jsxRuntime.jsx("span", { className: "text-sm", children: translations.cropBackgroundTransparent })] })] })] })] }) }), jsxRuntime.jsxs(react.ModalFooter, { className: "flex flex-col-reverse sm:flex-row gap-2 px-4 sm:px-6", children: [jsxRuntime.jsx(react.Button, { color: "danger", variant: "light", onPress: onCancel, className: "w-full sm:w-auto", children: translations.cropCancelButton }), jsxRuntime.jsx(react.Button, { color: "primary", onPress: handleSave, className: "w-full sm:w-auto", children: translations.cropSaveButton })] })] }) }));
724
+ };
725
+ /**
726
+ * Componente de previsualización de archivo
727
+ */
728
+ var FilePreview = function (_a) {
729
+ var file = _a.file, onRemove = _a.onRemove, removeAriaLabel = _a.removeAriaLabel;
730
+ var _b = React.useState(""), previewUrl = _b[0], setPreviewUrl = _b[1];
731
+ React.useEffect(function () {
732
+ if (file === null || file === void 0 ? void 0 : file.type.startsWith("image/")) {
733
+ var url_1 = URL.createObjectURL(file);
734
+ setPreviewUrl(url_1);
735
+ return function () { return URL.revokeObjectURL(url_1); };
736
+ }
737
+ }, [file]);
738
+ if (!(file === null || file === void 0 ? void 0 : file.type.startsWith("image/"))) {
739
+ return null;
740
+ }
741
+ return (jsxRuntime.jsxs("div", { className: "absolute inset-0 overflow-hidden z-10", children: [jsxRuntime.jsx("img", { src: previewUrl, alt: file.name, className: "w-full h-full object-cover" }), jsxRuntime.jsx(react.Button, { isIconOnly: true, size: "sm", color: "danger", variant: "solid", className: "absolute top-2 right-2 sm:top-3 sm:right-3 z-20 bg-red-100 hover:bg-red-200 text-red-600 min-w-8 h-8 sm:min-w-10 sm:h-10", onPress: onRemove, "aria-label": removeAriaLabel, children: jsxRuntime.jsx(IconComponent, { icon: "heroicons:trash", size: "sm" }) })] }));
742
+ };
743
+ /**
744
+ * Componente UploadDocument basado en Hero UI con funcionalidad mejorada
745
+ *
746
+ * @example
747
+ * ```tsx
748
+ * <UploadDocument
749
+ * onUpload={(files) => console.log(files)}
750
+ * acceptedFiles="image/*,.pdf"
751
+ * multiple={false}
752
+ * translations={{
753
+ * uploadText: "Upload your files",
754
+ * dragText: "Drop files here"
755
+ * }}
756
+ * />
757
+ * ```
758
+ */
759
+ var UploadFile = function (_a) {
760
+ var text = _a.text, textColor = _a.textColor, subText = _a.subText,
761
+ // borderColor, // TODO: Implementar colores personalizados
762
+ iconColor = _a.iconColor,
763
+ // backgroundColor, // TODO: Implementar colores personalizados
764
+ _b = _a.width,
765
+ // backgroundColor, // TODO: Implementar colores personalizados
766
+ width = _b === void 0 ? "100%" : _b, _c = _a.height, height = _c === void 0 ? "auto" : _c, _d = _a.multiple, multiple = _d === void 0 ? false : _d, _e = _a.maxFiles, maxFiles = _e === void 0 ? 1 : _e, maxFileSize = _a.maxFileSize, _f = _a.acceptedFiles, acceptedFiles = _f === void 0 ? ".pdf" : _f, _g = _a.icon, icon = _g === void 0 ? "heroicons:arrow-up-on-square" : _g, onUpload = _a.onUpload, onError = _a.onError, _h = _a.error, error = _h === void 0 ? false : _h, _j = _a.success, success = _j === void 0 ? false : _j, _k = _a.disabled, disabled = _k === void 0 ? false : _k, errorText = _a.errorText, cropConfig = _a.cropConfig, image = _a.image, _l = _a.className, className = _l === void 0 ? "" : _l, _m = _a.translations, translations = _m === void 0 ? {} : _m;
767
+ var inputRef = React.useRef(null);
768
+ var uploadImageRef = React.useRef(image || null);
769
+ var _o = React.useState(false), isDragging = _o[0], setIsDragging = _o[1];
770
+ // Estados para el modal de crop
771
+ var _p = React.useState(false), showCropModal = _p[0], setShowCropModal = _p[1];
772
+ var _q = React.useState(""), selectedImageUrl = _q[0], setSelectedImageUrl = _q[1];
773
+ var _r = React.useState(null); _r[0]; var setOriginalFile = _r[1];
774
+ // Combinar traducciones por defecto con las proporcionadas
775
+ var t = React.useMemo(function () { return (__assign(__assign({}, defaultTranslations), translations)); }, [translations]);
776
+ // Actualizar texto si se pasa como prop (retrocompatibilidad)
777
+ var finalText = text || t.uploadText;
778
+ var finalSubText = subText || t.subText;
779
+ var handleClick = function () {
780
+ var _a;
781
+ if (!(disabled || uploadImageRef.current)) {
782
+ (_a = inputRef.current) === null || _a === void 0 ? void 0 : _a.click();
783
+ }
784
+ };
785
+ var validateFiles = React.useCallback(function (files) {
786
+ var filesArray = Array.from(files);
787
+ if (!multiple && filesArray.length > 1) {
788
+ onError === null || onError === void 0 ? void 0 : onError(t.multipleFilesError);
789
+ return [];
790
+ }
791
+ if (filesArray.length > maxFiles) {
792
+ onError === null || onError === void 0 ? void 0 : onError(t.maxFilesError.replace("{maxFiles}", maxFiles.toString()));
793
+ return [];
794
+ }
795
+ // Validar tamaño de archivo
796
+ if (maxFileSize) {
797
+ var oversizedFiles = filesArray.filter(function (file) { return file.size > maxFileSize; });
798
+ if (oversizedFiles.length > 0) {
799
+ var maxSizeFormatted = formatFileSize(maxFileSize);
800
+ onError === null || onError === void 0 ? void 0 : onError(t.maxFileSizeError.replace("{maxSize}", maxSizeFormatted));
801
+ return [];
802
+ }
803
+ }
804
+ // Validar tipos de archivo
805
+ var acceptedExtensions = Array.isArray(acceptedFiles)
806
+ ? acceptedFiles.map(function (ext) { return ext.trim().toLowerCase(); })
807
+ : acceptedFiles.split(",").map(function (ext) { return ext.trim().toLowerCase(); });
808
+ var validFiles = filesArray.filter(function (file) {
809
+ var _a;
810
+ if (acceptedFiles.includes("image/*") &&
811
+ file.type.startsWith("image/")) {
812
+ return true;
813
+ }
814
+ if (acceptedExtensions.some(function (ext) { return ext.includes("/"); })) {
815
+ return acceptedExtensions.some(function (type) { return file.type === type; });
816
+ }
817
+ var fileExtension = ".".concat((_a = file.name.split(".").pop()) === null || _a === void 0 ? void 0 : _a.toLowerCase());
818
+ return acceptedExtensions.some(function (ext) { return ext === fileExtension || ext === "*"; });
819
+ });
820
+ if (validFiles.length === 0) {
821
+ var formattedTypes = acceptedExtensions
822
+ .map(formatFileType)
823
+ .join(", ");
824
+ onError === null || onError === void 0 ? void 0 : onError(t.invalidFileTypeError.replace("{acceptedTypes}", formattedTypes));
825
+ return [];
826
+ }
827
+ return validFiles;
828
+ }, [multiple, maxFiles, maxFileSize, acceptedFiles, t, onError]);
829
+ var handleFileUpload = React.useCallback(function (files) {
830
+ var validFiles = validateFiles(files);
831
+ if (validFiles.length > 0) {
832
+ var file_1 = validFiles[0];
833
+ // Si es imagen y hay configuración de crop, abrir modal
834
+ if (file_1.type.startsWith("image/") && cropConfig) {
835
+ var reader_1 = new FileReader();
836
+ reader_1.onload = function () {
837
+ setSelectedImageUrl(reader_1.result);
838
+ setOriginalFile(file_1);
839
+ setShowCropModal(true);
840
+ };
841
+ reader_1.readAsDataURL(file_1);
842
+ }
843
+ else {
844
+ // Procesar directamente si no necesita crop
845
+ uploadImageRef.current = file_1;
846
+ onUpload(validFiles);
847
+ }
848
+ }
849
+ }, [onUpload, validateFiles, cropConfig]);
850
+ // Manejar guardado de imagen recortada
851
+ var handleCropSave = React.useCallback(function (croppedFile) {
852
+ uploadImageRef.current = croppedFile;
853
+ setShowCropModal(false);
854
+ setSelectedImageUrl("");
855
+ setOriginalFile(null);
856
+ onUpload([croppedFile]);
857
+ }, [onUpload]);
858
+ // Manejar cancelación de crop
859
+ var handleCropCancel = React.useCallback(function () {
860
+ setShowCropModal(false);
861
+ setSelectedImageUrl("");
862
+ setOriginalFile(null);
863
+ }, []);
864
+ var handleChange = function (event) {
865
+ var files = event.target.files;
866
+ if (files && files.length > 0) {
867
+ handleFileUpload(files);
868
+ }
869
+ // Limpiar el input
870
+ if (inputRef.current) {
871
+ inputRef.current.value = "";
872
+ }
873
+ };
874
+ var handleDragEnter = React.useCallback(function (e) {
875
+ e.preventDefault();
876
+ e.stopPropagation();
877
+ if (!disabled) {
878
+ setIsDragging(true);
879
+ }
880
+ }, [disabled]);
881
+ var handleDragLeave = React.useCallback(function (e) {
882
+ e.preventDefault();
883
+ e.stopPropagation();
884
+ setIsDragging(false);
885
+ }, []);
886
+ var handleDragOver = React.useCallback(function (e) {
887
+ e.preventDefault();
888
+ e.stopPropagation();
889
+ }, []);
890
+ var handleDrop = React.useCallback(function (e) {
891
+ e.preventDefault();
892
+ e.stopPropagation();
893
+ setIsDragging(false);
894
+ if (disabled) {
895
+ return;
896
+ }
897
+ var droppedFiles = e.dataTransfer.files;
898
+ if (droppedFiles.length > 0) {
899
+ handleFileUpload(droppedFiles);
900
+ }
901
+ }, [disabled, handleFileUpload]);
902
+ var handleRemoveImage = function () {
903
+ uploadImageRef.current = null;
904
+ onUpload([]);
905
+ };
906
+ // Clases CSS dinámicas usando Tailwind
907
+ var containerClasses = "\n\t\trelative w-full border-2 border-dashed rounded-2xl p-2 sm:p-4 lg:p-4 transition-all duration-300\n\t\t".concat(width !== "100%" ? "w-[".concat(width, "]") : "w-full", "\n\t\t").concat(height !== "auto" ? "h-[".concat(height, "]") : "min-h-[150px] sm:min-h-[180px] lg:min-h-[200px]", "\n\t\t").concat(isDragging
908
+ ? "border-blue-500 bg-blue-50 dark:bg-blue-950"
909
+ : error
910
+ ? "border-red-500 bg-red-50 dark:bg-red-950"
911
+ : success
912
+ ? "border-green-500 bg-green-50 dark:bg-green-950"
913
+ : disabled
914
+ ? "border-gray-300 bg-gray-100 dark:bg-gray-800"
915
+ : "border-gray-300 hover:border-gray-400 bg-gray-50 dark:bg-gray-900", "\n\t\t").concat(!(disabled || uploadImageRef.current) ? "cursor-pointer" : "cursor-default", "\n\t\t").concat(className, "\n\t")
916
+ .trim()
917
+ .replace(/\s+/g, " ");
918
+ var textClasses = "\n\t\ttext-center mb-1 sm:mb-2 text-sm sm:text-base lg:text-lg font-medium\n\t\t".concat(disabled ? "text-gray-400" : textColor || "text-gray-700 dark:text-gray-200", "\n\t");
919
+ var subTextClasses = "\n\t\ttext-xs sm:text-sm text-center\n\t\t".concat(disabled ? "text-gray-400" : "text-gray-500 dark:text-gray-400", "\n\t");
920
+ return (jsxRuntime.jsxs("div", { className: "relative", children: [jsxRuntime.jsx(react.Card, { className: containerClasses, isPressable: !(disabled || uploadImageRef.current), onPress: handleClick, children: jsxRuntime.jsxs(react.CardBody, { className: "flex flex-col items-center justify-center gap-3 sm:gap-4 relative", onDragEnter: handleDragEnter, onDragOver: handleDragOver, onDragLeave: handleDragLeave, onDrop: handleDrop, children: [uploadImageRef.current && (jsxRuntime.jsx(FilePreview, { file: uploadImageRef.current, onRemove: handleRemoveImage, removeAriaLabel: t.removeFileAriaLabel })), jsxRuntime.jsx("div", { className: uploadImageRef.current
921
+ ? "opacity-0"
922
+ : "opacity-100 transition-opacity", children: jsxRuntime.jsxs("div", { className: "flex flex-col items-center gap-3 sm:gap-4", children: [jsxRuntime.jsx(IconComponent, { icon: icon, size: "xl", className: "sm:text-4xl lg:text-5xl ".concat(disabled ? "text-gray-400" : iconColor || "text-primary") }), jsxRuntime.jsxs("div", { className: "space-y-1 sm:space-y-2 text-center px-2", children: [jsxRuntime.jsx("p", { className: textClasses, children: isDragging ? t.dragText : finalText }), finalSubText && !isDragging && (jsxRuntime.jsx("p", { className: subTextClasses, children: finalSubText }))] })] }) }), jsxRuntime.jsx("input", { ref: inputRef, type: "file", className: "hidden", multiple: multiple, accept: Array.isArray(acceptedFiles)
923
+ ? acceptedFiles.join(",")
924
+ : acceptedFiles, onChange: handleChange, disabled: disabled, "aria-label": t.uploadAreaAriaLabel })] }) }), error && errorText && (jsxRuntime.jsx("p", { className: "text-red-500 text-sm mt-2", role: "alert", children: errorText })), showCropModal && selectedImageUrl && cropConfig && (jsxRuntime.jsx(ImageCropModal, { isOpen: showCropModal, imageUrl: selectedImageUrl, targetWidth: cropConfig.targetWidth, targetHeight: cropConfig.targetHeight, onSave: handleCropSave, onCancel: handleCropCancel, translations: t }))] }));
925
+ };
926
+ UploadFile.displayName = "UploadFile";
927
+
928
+ var ConfigMenu = function (_a) {
929
+ var _b;
930
+ var options = _a.options, onLogout = _a.onLogout, translations = _a.translations;
931
+ return (jsxRuntime.jsxs(react.Dropdown, { className: "min-w-40", children: [jsxRuntime.jsx(react.DropdownTrigger, { children: jsxRuntime.jsx(react.Button, { isIconOnly: true, color: "default", startContent: jsxRuntime.jsx(IconComponent, { icon: "solar:settings-linear" }) }) }), jsxRuntime.jsxs(react.DropdownMenu, { "aria-label": "Configuration", children: [jsxRuntime.jsx(react.DropdownSection, { showDivider: true, className: "mb-0", children: options.map(function (item) { return (jsxRuntime.jsx(react.DropdownItem, { href: item.href, className: "data-[hover=true]:bg-primary-50 data-[hover=true]:text-default-700", classNames: {
932
+ base: "text-default-500",
933
+ }, startContent: item.icon ? jsxRuntime.jsx(IconComponent, { icon: item.icon }) : undefined, children: item.label }, item.label)); }) }), jsxRuntime.jsx(react.DropdownSection, { children: jsxRuntime.jsx(react.DropdownItem, { onPress: onLogout, className: "data-[hover=true]:bg-primary-50 data-[hover=true]:text-default-700", classNames: {
934
+ base: "text-default-500",
935
+ }, startContent: jsxRuntime.jsx(IconComponent, { icon: "solar:logout-2-linear" }), children: (_b = translations === null || translations === void 0 ? void 0 : translations.logout) !== null && _b !== void 0 ? _b : "Logout" }, "logout") })] })] }));
936
+ };
937
+ ConfigMenu.displayName = "ConfigMenu";
938
+
939
+ var NotificationButton = function (_a) {
940
+ var _b = _a.notificationCount, notificationCount = _b === void 0 ? 0 : _b;
941
+ return (jsxRuntime.jsx(react.Button, { isIconOnly: true, color: "secondary", variant: "flat", startContent: jsxRuntime.jsx(IconComponent, { icon: "solar:bell-bing-linear" }), children: notificationCount > 0 && (jsxRuntime.jsx("span", { className: "notification__alert", children: notificationCount })) }));
942
+ };
943
+ NotificationButton.displayName = "NotificationButton";
944
+
945
+ var HeaderComponent = function (_a) {
946
+ var notificationCount = _a.notificationCount, options = _a.options, onMenuClick = _a.onMenuClick, onLogout = _a.onLogout, translations = _a.translations;
947
+ return (jsxRuntime.jsxs("header", { className: "header__container", children: [jsxRuntime.jsx(react.Button, { className: "sm:hidden", isIconOnly: true, variant: "light", startContent: jsxRuntime.jsx(IconComponent, { icon: "solar:hamburger-menu-linear" }), onPress: onMenuClick }), jsxRuntime.jsxs("div", { className: "flex items-center gap-4", children: [jsxRuntime.jsx(NotificationButton, { notificationCount: notificationCount }), jsxRuntime.jsx(ConfigMenu, { options: options, onLogout: onLogout, translations: translations })] })] }));
948
+ };
949
+ HeaderComponent.displayName = "Header";
950
+
951
+ /**
952
+ * Botón genérico basado en HeroUI siguiendo las reglas de diseño BeweOS.
953
+ *
954
+ * Reglas aplicadas:
955
+ * - Variant: Solid, Bordered, Light, Flat, Faded
956
+ * - Size: sm, md, lg
957
+ * - StartContent: On, Off
958
+ * - isLoading: On, Off
959
+ * - Radius: md (por defecto)
960
+ * - isIconOnly: True, False
961
+ */
962
+ var Button = function (_a) {
963
+ var _b = _a.color, color = _b === void 0 ? "primary" : _b, _c = _a.size, size = _c === void 0 ? "md" : _c, _d = _a.variant, variant = _d === void 0 ? "solid" : _d, _e = _a.radius, radius = _e === void 0 ? "sm" : _e, startContent = _a.startContent, endContent = _a.endContent, _f = _a.isLoading, isLoading = _f === void 0 ? false : _f, _g = _a.isIconOnly, isIconOnly = _g === void 0 ? false : _g, props = __rest(_a, ["color", "size", "variant", "radius", "startContent", "endContent", "isLoading", "isIconOnly"]);
964
+ return (jsxRuntime.jsx(react.Button, __assign({}, props, { color: color, size: size, variant: variant, radius: radius, startContent: startContent, endContent: endContent, isLoading: isLoading, isIconOnly: isIconOnly })));
965
+ };
966
+
967
+ var paddingClasses = {
968
+ sm: "p-4",
969
+ md: "p-6",
970
+ lg: "p-8",
971
+ };
972
+
973
+ /**
974
+ * Card genérica siguiendo las reglas de diseño BeweOS basada en HeroUI.
975
+ *
976
+ * Reglas aplicadas:
977
+ * - Shadow: none, sm, md, lg (configurable)
978
+ * - Radius: sm (por defecto, configurable)
979
+ * - Padding configurable (sm, md, lg)
980
+ * - Hereda de HeroUI Card con personalización BeweOS
981
+ */
982
+ var Card = function (_a) {
983
+ var children = _a.children, _b = _a.className, className = _b === void 0 ? "" : _b, _c = _a.shadow, shadow = _c === void 0 ? "sm" : _c, _d = _a.radius, radius = _d === void 0 ? "sm" : _d, _e = _a.padding, padding = _e === void 0 ? "md" : _e, props = __rest(_a, ["children", "className", "shadow", "radius", "padding"]);
984
+ var paddingClass = paddingClasses[padding];
985
+ var combinedClassName = [paddingClass, className].filter(Boolean).join(" ");
986
+ return (jsxRuntime.jsx(react.Card, __assign({ shadow: shadow, radius: radius, className: combinedClassName }, props, { children: children })));
987
+ };
988
+
989
+ /**
990
+ * Input genérico reutilizable basado en HeroUI siguiendo las reglas de diseño BeweOS.
991
+ *
992
+ * Reglas aplicadas:
993
+ * - Variant: Bordered (por defecto)
994
+ * - labelPlacement: Outside
995
+ * - Size: sm, md, lg (configurable)
996
+ * - Radius configurable
997
+ */
998
+ var Input = function (_a) {
999
+ var label = _a.label, id = _a.id, _b = _a.size, size = _b === void 0 ? "md" : _b, _c = _a.variant, variant = _c === void 0 ? "bordered" : _c, _d = _a.radius, radius = _d === void 0 ? "md" : _d, placeholder = _a.placeholder, props = __rest(_a, ["label", "id", "size", "variant", "radius", "placeholder"]);
1000
+ var generatedId = React.useId();
1001
+ var inputId = id || generatedId;
1002
+ return (jsxRuntime.jsx(react.Input, __assign({}, props, { id: inputId, label: label, labelPlacement: "outside", placeholder: placeholder, variant: variant, size: size, radius: radius, classNames: {
1003
+ label: "text-default-600 text-tiny",
1004
+ inputWrapper: "focus-within:!border-primary-500",
1005
+ } })));
1006
+ };
1007
+
1008
+ /**
1009
+ * Select genérico reutilizable basado en HeroUI siguiendo las reglas de diseño BeweOS.
1010
+ *
1011
+ * Reglas aplicadas:
1012
+ * - Variant: Bordered (por defecto)
1013
+ * - Radius: md (por defecto)
1014
+ * - labelPlacement: Outside
1015
+ * - Size: sm, md, lg (configurable)
1016
+ */
1017
+ var Select = function (_a) {
1018
+ var label = _a.label, id = _a.id, _b = _a.size, size = _b === void 0 ? "md" : _b, _c = _a.variant, variant = _c === void 0 ? "bordered" : _c, _d = _a.radius, radius = _d === void 0 ? "md" : _d, placeholder = _a.placeholder, props = __rest(_a, ["label", "id", "size", "variant", "radius", "placeholder"]);
1019
+ var generatedId = React.useId();
1020
+ var selectId = id || generatedId;
1021
+ return (jsxRuntime.jsx("div", { className: "group", children: jsxRuntime.jsx(react.Select, __assign({}, props, { id: selectId, label: label, labelPlacement: "outside", placeholder: placeholder, variant: variant, size: size, radius: radius, classNames: {
1022
+ label: "text-default-600 text-tiny group-data-[filled=true]:text-default-600",
1023
+ trigger: "data-[open=true]:!border-primary-500 data-[focus=true]:!border-primary-500",
1024
+ popoverContent: "[&_[data-focus-visible=true]]:!outline-none [&_[data-selectable=true]:focus]:!bg-primary-50 [&_li]:!text-default-500 [&_li[data-hover=true]]:!text-default-600",
1025
+ } })) }));
1026
+ };
1027
+
382
1028
  var themeColors = {
383
1029
  "purple-light": {
384
1030
  extend: "light",
@@ -577,12 +1223,25 @@ var ThemeProvider = function (_a) {
577
1223
  return (jsxRuntime.jsx(ThemeContext.Provider, { value: { theme: theme, setTheme: setTheme }, children: jsxRuntime.jsx("main", { className: "".concat(theme, " bg-background text-foreground "), children: children }) }));
578
1224
  };
579
1225
 
580
- exports.ButtonPrueba = ButtonPrueba;
1226
+ exports.AutoComplete = AutoComplete;
1227
+ exports.Button = Button;
1228
+ exports.Card = Card;
1229
+ exports.HeaderComponent = HeaderComponent;
581
1230
  exports.IconComponent = IconComponent;
1231
+ exports.Input = Input;
582
1232
  exports.MenuComponent = MenuComponent;
583
1233
  exports.Phone = Phone;
1234
+ exports.Select = Select;
584
1235
  exports.ThemeContext = ThemeContext;
1236
+ exports.ThemePicker = ThemePicker;
585
1237
  exports.ThemeProvider = ThemeProvider;
1238
+ exports.UploadFile = UploadFile;
586
1239
  exports.sizeMap = sizeMap;
587
1240
  exports.themeColors = themeColors;
588
1241
  exports.useThemeContext = useThemeContext;
1242
+ Object.keys(react).forEach(function (k) {
1243
+ if (k !== 'default' && !Object.prototype.hasOwnProperty.call(exports, k)) Object.defineProperty(exports, k, {
1244
+ enumerable: true,
1245
+ get: function () { return react[k]; }
1246
+ });
1247
+ });