flysoft-react-ui 0.5.2 → 1.0.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 (152) hide show
  1. package/dist/App.d.ts.map +1 -1
  2. package/dist/App.js +5 -6
  3. package/dist/components/form-controls/AutocompleteInput.d.ts.map +1 -1
  4. package/dist/components/form-controls/AutocompleteInput.js +177 -131
  5. package/dist/components/form-controls/Button.d.ts +3 -0
  6. package/dist/components/form-controls/Button.d.ts.map +1 -1
  7. package/dist/components/form-controls/Button.js +160 -19
  8. package/dist/components/form-controls/Checkbox.d.ts.map +1 -1
  9. package/dist/components/form-controls/Checkbox.js +3 -1
  10. package/dist/components/form-controls/DateInput.d.ts +5 -1
  11. package/dist/components/form-controls/DateInput.d.ts.map +1 -1
  12. package/dist/components/form-controls/DateInput.js +94 -27
  13. package/dist/components/form-controls/Input.d.ts.map +1 -1
  14. package/dist/components/form-controls/Input.js +2 -1
  15. package/dist/components/form-controls/LinkButton.d.ts +15 -0
  16. package/dist/components/form-controls/LinkButton.d.ts.map +1 -0
  17. package/dist/components/form-controls/LinkButton.js +248 -0
  18. package/dist/components/form-controls/SearchSelectInput-OLD.d.ts.map +1 -1
  19. package/dist/components/form-controls/SearchSelectInput-OLD.js +5 -4
  20. package/dist/components/form-controls/SearchSelectInput.d.ts.map +1 -1
  21. package/dist/components/form-controls/SearchSelectInput.js +3 -2
  22. package/dist/components/form-controls/index.d.ts +2 -0
  23. package/dist/components/form-controls/index.d.ts.map +1 -1
  24. package/dist/components/form-controls/index.js +1 -0
  25. package/dist/components/layout/Accordion.d.ts +13 -0
  26. package/dist/components/layout/Accordion.d.ts.map +1 -0
  27. package/dist/components/layout/Accordion.js +67 -0
  28. package/dist/components/layout/AppLayout.d.ts.map +1 -1
  29. package/dist/components/layout/AppLayout.js +7 -7
  30. package/dist/components/layout/Card.d.ts +8 -3
  31. package/dist/components/layout/Card.d.ts.map +1 -1
  32. package/dist/components/layout/Card.js +21 -22
  33. package/dist/components/layout/DataTable.js +1 -1
  34. package/dist/components/layout/DropdownMenu.d.ts.map +1 -0
  35. package/dist/components/{utils → layout}/DropdownMenu.js +12 -6
  36. package/dist/components/layout/DropdownPanel.d.ts +7 -0
  37. package/dist/components/layout/DropdownPanel.d.ts.map +1 -0
  38. package/dist/components/layout/DropdownPanel.js +137 -0
  39. package/dist/components/{utils → layout}/Filter.d.ts +5 -0
  40. package/dist/components/layout/Filter.d.ts.map +1 -0
  41. package/dist/components/{utils → layout}/Filter.js +18 -9
  42. package/dist/components/layout/Menu.d.ts +31 -0
  43. package/dist/components/layout/Menu.d.ts.map +1 -0
  44. package/dist/components/layout/Menu.js +21 -0
  45. package/dist/components/layout/index.d.ts +10 -0
  46. package/dist/components/layout/index.d.ts.map +1 -1
  47. package/dist/components/layout/index.js +5 -0
  48. package/dist/components/utils/Badge.d.ts.map +1 -1
  49. package/dist/components/utils/Badge.js +3 -2
  50. package/dist/components/utils/Dialog.d.ts +2 -2
  51. package/dist/components/utils/Dialog.d.ts.map +1 -1
  52. package/dist/components/utils/Dialog.js +4 -3
  53. package/dist/components/utils/FiltersDialog.d.ts +1 -1
  54. package/dist/components/utils/FiltersDialog.d.ts.map +1 -1
  55. package/dist/components/utils/FiltersDialog.js +2 -2
  56. package/dist/components/utils/Loader.js +1 -1
  57. package/dist/components/utils/RoadMap.d.ts.map +1 -1
  58. package/dist/components/utils/RoadMap.js +2 -1
  59. package/dist/components/utils/Snackbar.d.ts.map +1 -1
  60. package/dist/components/utils/Snackbar.js +2 -1
  61. package/dist/components/utils/iconUtils.d.ts +16 -0
  62. package/dist/components/utils/iconUtils.d.ts.map +1 -0
  63. package/dist/components/utils/iconUtils.js +40 -0
  64. package/dist/components/utils/index.d.ts +0 -2
  65. package/dist/components/utils/index.d.ts.map +1 -1
  66. package/dist/components/utils/index.js +0 -1
  67. package/dist/contexts/CrudContext.d.ts +62 -0
  68. package/dist/contexts/CrudContext.d.ts.map +1 -0
  69. package/dist/contexts/CrudContext.js +333 -0
  70. package/dist/contexts/index.d.ts +2 -2
  71. package/dist/contexts/index.d.ts.map +1 -1
  72. package/dist/contexts/index.js +2 -2
  73. package/dist/docs/AccordionDocs.d.ts +4 -0
  74. package/dist/docs/AccordionDocs.d.ts.map +1 -0
  75. package/dist/docs/AccordionDocs.js +21 -0
  76. package/dist/docs/AuthDocs.tsx/AuthDocsContent.js +3 -5
  77. package/dist/docs/AutocompleteInputDocs.js +1 -1
  78. package/dist/docs/ButtonDocs.d.ts.map +1 -1
  79. package/dist/docs/ButtonDocs.js +1 -1
  80. package/dist/docs/CardDocs.d.ts.map +1 -1
  81. package/dist/docs/CardDocs.js +17 -8
  82. package/dist/docs/DataTableDocs.js +3 -3
  83. package/dist/docs/DialogDocs.d.ts.map +1 -1
  84. package/dist/docs/DialogDocs.js +1 -1
  85. package/dist/docs/DocAdmin.js +1 -1
  86. package/dist/docs/DocsMenu.d.ts.map +1 -1
  87. package/dist/docs/DocsMenu.js +3 -3
  88. package/dist/docs/DocsRouter.d.ts.map +1 -1
  89. package/dist/docs/DocsRouter.js +5 -1
  90. package/dist/docs/DropdownMenuDocs.js +1 -1
  91. package/dist/docs/DropdownPanelDocs.d.ts +4 -0
  92. package/dist/docs/DropdownPanelDocs.d.ts.map +1 -0
  93. package/dist/docs/DropdownPanelDocs.js +7 -0
  94. package/dist/docs/FilterDocs.d.ts.map +1 -1
  95. package/dist/docs/FilterDocs.js +19 -1
  96. package/dist/docs/LinkButtonDocs.d.ts +4 -0
  97. package/dist/docs/LinkButtonDocs.d.ts.map +1 -0
  98. package/dist/docs/LinkButtonDocs.js +7 -0
  99. package/dist/docs/ListCrudDocs.tsx/ListCrudDocs.d.ts +0 -9
  100. package/dist/docs/ListCrudDocs.tsx/ListCrudDocs.d.ts.map +1 -1
  101. package/dist/docs/ListCrudDocs.tsx/ListCrudDocs.js +32 -16
  102. package/dist/docs/ListCrudDocs.tsx/ListCrudDocsContentEmpresaPersonas.d.ts +2 -0
  103. package/dist/docs/ListCrudDocs.tsx/ListCrudDocsContentEmpresaPersonas.d.ts.map +1 -0
  104. package/dist/docs/ListCrudDocs.tsx/ListCrudDocsContentEmpresaPersonas.js +34 -0
  105. package/dist/docs/ListCrudDocs.tsx/ListCrudDocsContentEmpresaSingle.d.ts +2 -0
  106. package/dist/docs/ListCrudDocs.tsx/ListCrudDocsContentEmpresaSingle.d.ts.map +1 -0
  107. package/dist/docs/ListCrudDocs.tsx/ListCrudDocsContentEmpresaSingle.js +66 -0
  108. package/dist/docs/ListCrudDocs.tsx/ListCrudDocsContentEmpresas.d.ts +2 -0
  109. package/dist/docs/ListCrudDocs.tsx/ListCrudDocsContentEmpresas.d.ts.map +1 -0
  110. package/dist/docs/ListCrudDocs.tsx/ListCrudDocsContentEmpresas.js +7 -0
  111. package/dist/docs/ListCrudDocs.tsx/ListCrudDocsContentEmpresasPersonasEditDialog.d.ts +10 -0
  112. package/dist/docs/ListCrudDocs.tsx/ListCrudDocsContentEmpresasPersonasEditDialog.d.ts.map +1 -0
  113. package/dist/docs/ListCrudDocs.tsx/ListCrudDocsContentEmpresasPersonasEditDialog.js +39 -0
  114. package/dist/docs/ListCrudDocs.tsx/ListCrudDocsContentPersonas.d.ts.map +1 -1
  115. package/dist/docs/ListCrudDocs.tsx/ListCrudDocsContentPersonas.js +33 -27
  116. package/dist/docs/ListCrudDocs.tsx/ListCrudDocsEditDialog.d.ts +9 -0
  117. package/dist/docs/ListCrudDocs.tsx/ListCrudDocsEditDialog.d.ts.map +1 -0
  118. package/dist/docs/ListCrudDocs.tsx/ListCrudDocsEditDialog.js +30 -0
  119. package/dist/docs/MenuDocs.d.ts +4 -0
  120. package/dist/docs/MenuDocs.d.ts.map +1 -0
  121. package/dist/docs/MenuDocs.js +26 -0
  122. package/dist/docs/SearchSelectInputDocs.js +1 -1
  123. package/dist/docs/docMockServices/empresaService.d.ts +5 -5
  124. package/dist/docs/docMockServices/empresaService.d.ts.map +1 -1
  125. package/dist/docs/docMockServices/empresaService.js +20 -11
  126. package/dist/docs/docMockServices/interfaces.d.ts +12 -0
  127. package/dist/docs/docMockServices/interfaces.d.ts.map +1 -1
  128. package/dist/docs/docMockServices/personaEmpresaService.d.ts +6 -6
  129. package/dist/docs/docMockServices/personaEmpresaService.d.ts.map +1 -1
  130. package/dist/docs/docMockServices/personaEmpresaService.js +52 -14
  131. package/dist/docs/docMockServices/personaService.d.ts +2 -2
  132. package/dist/docs/docMockServices/personaService.d.ts.map +1 -1
  133. package/dist/docs/docMockServices/personaService.js +17 -7
  134. package/dist/index.css +1 -1
  135. package/dist/index.d.ts +12 -4
  136. package/dist/index.d.ts.map +1 -1
  137. package/dist/index.js +6 -2
  138. package/dist/index.js.map +1 -1
  139. package/dist/templates/forms/ContactForm.js +2 -2
  140. package/dist/templates/forms/LoginForm.js +1 -1
  141. package/dist/templates/forms/RegistrationForm.js +1 -1
  142. package/dist/templates/layouts/SidebarLayout.d.ts.map +1 -1
  143. package/dist/templates/layouts/SidebarLayout.js +3 -2
  144. package/dist/templates/patterns/FormPattern.d.ts.map +1 -1
  145. package/dist/templates/patterns/FormPattern.js +4 -3
  146. package/package.json +4 -3
  147. package/dist/components/utils/DropdownMenu.d.ts.map +0 -1
  148. package/dist/components/utils/Filter.d.ts.map +0 -1
  149. package/dist/contexts/ListCrudContext.d.ts +0 -29
  150. package/dist/contexts/ListCrudContext.d.ts.map +0 -1
  151. package/dist/contexts/ListCrudContext.js +0 -209
  152. /package/dist/components/{utils → layout}/DropdownMenu.d.ts +0 -0
package/dist/App.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"App.d.ts","sourceRoot":"","sources":["../src/App.tsx"],"names":[],"mappings":"AAGA,OAAO,aAAa,CAAC;AA2DrB,iBAAS,GAAG,4CAoBX;AAED,eAAe,GAAG,CAAC"}
1
+ {"version":3,"file":"App.d.ts","sourceRoot":"","sources":["../src/App.tsx"],"names":[],"mappings":"AAGA,OAAO,aAAa,CAAC;AAuDrB,iBAAS,GAAG,4CAsBX;AAED,eAAe,GAAG,CAAC"}
package/dist/App.js CHANGED
@@ -8,20 +8,19 @@ import DocsRouter from "./docs/DocsRouter";
8
8
  import { AuthDocs } from "./docs/AuthDocs.tsx/AuthDocs";
9
9
  import packageJson from "../package.json";
10
10
  function HomeContent() {
11
- return (_jsxs(_Fragment, { children: [_jsx(Card, { title: "Empleados", className: "bg-gray-50", children: _jsx(Card, { className: "w-1/2", title: "FALCONE WALTER ALDO", subtitle: "3558-03 - Titular", footer: _jsx(Button, { children: "Ver" }), headerActions: () => [
12
- _jsx(Badge, { variant: "secondary", children: "OSOCNA" }),
13
- _jsx(Badge, { variant: "secondary", children: "B\u00C1SICO" }),
14
- ], children: _jsxs(Collection, { direction: "row", gap: "1rem", wrap: true, children: [_jsx(DataField, { label: "Cuil", value: "20179902711" }), _jsx(DataField, { label: "Doc", value: "17990271" }), _jsx(DataField, { label: "F Nac", value: "23/06/1966" }), _jsx(DataField, { label: "F Alta", value: "01/03/2012" })] }) }) }), _jsx("div", { children: _jsx(AuthDocs, {}) })] }));
11
+ return (_jsxs(_Fragment, { children: [_jsx(Card, { title: "Empleados", className: "bg-gray-50", children: _jsx(Card, { className: "w-1/2", title: "FALCONE WALTER ALDO", subtitle: "3558-03 - Titular", footer: _jsx(Button, { children: "Ver" }), headerActions: _jsxs(_Fragment, { children: [_jsx(Badge, { variant: "secondary", children: "OSOCNA" }), _jsx(Badge, { variant: "secondary", children: "B\u00C1SICO" })] }), children: _jsxs(Collection, { direction: "row", gap: "1rem", wrap: true, children: [_jsx(DataField, { label: "Cuil", value: "20179902711" }), _jsx(DataField, { label: "Doc", value: "17990271" }), _jsx(DataField, { label: "F Nac", value: "23/06/1966" }), _jsx(DataField, { label: "F Alta", value: "01/03/2012" })] }) }) }), _jsx("div", { children: _jsx(AuthDocs, {}) })] }));
15
12
  }
16
13
  function LeftDrawerHeader() {
17
- return (_jsx("div", { className: "h-[64px] flex flex-col justify-center px-4", children: _jsx("h2", { children: _jsx(Link, { to: "/", children: "Flysoft React UI" }) }) }));
14
+ return (_jsx("div", { className: "h-[64px] flex flex-col justify-center px-4 bg-gray-300", children: _jsx("h2", { children: _jsx(Link, { to: "/", children: "Flysoft React UI" }) }) }));
18
15
  }
19
16
  function LeftDrawerFooter() {
20
- return (_jsx("div", { className: "px-4", children: _jsxs("span", { children: ["v ", packageJson.version] }) }));
17
+ return (_jsx("div", { className: "px-4 bg-gray-300", children: _jsxs("span", { children: ["v ", packageJson.version] }) }));
21
18
  }
22
19
  function App() {
23
20
  return (_jsx(AppLayoutProvider, { initialTheme: "light", forceInitialTheme: false, initialNavbar: {
21
+ navBarLeftNode: _jsx(_Fragment, {}),
24
22
  fullWidthNavbar: false,
23
+ className: "bg-gray-300 pl-0 lg:pl-8",
25
24
  }, initialLeftDrawer: {
26
25
  headerNode: _jsx(LeftDrawerHeader, {}),
27
26
  contentNode: _jsx(DocsMenu, {}),
@@ -1 +1 @@
1
- {"version":3,"file":"AutocompleteInput.d.ts","sourceRoot":"","sources":["../../../src/components/form-controls/AutocompleteInput.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAG1B,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAG1C,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAC9B,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,sBAAsB,CAAC,CAAC,GAAG,kBAAkB,EAAE,CAAC,GAAG,MAAM,CACxE,SAAQ,IAAI,CAAC,UAAU,EAAE,UAAU,GAAG,OAAO,GAAG,KAAK,CAAC;IACtD,OAAO,EAAE,CAAC,EAAE,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;;OAGG;IACH,QAAQ,CAAC,EACL,KAAK,CAAC,kBAAkB,CAAC,gBAAgB,CAAC,GAC1C,CAAC,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC,CAAC;IAC9B;;OAEG;IACH,cAAc,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,KAAK,IAAI,CAAC;IAC/C,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;;OAEG;IACH,cAAc,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,MAAM,CAAC;IACrC;;OAEG;IACH,cAAc,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC;IAChC;;OAEG;IACH,oBAAoB,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC;IAChE;;OAEG;IACH,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,KAAK,CAAC,SAAS,CAAC;IAC5C;;;OAGG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAkqBD,eAAO,MAAM,iBAAiB,EAA6B,CACzD,CAAC,GAAG,kBAAkB,EACtB,CAAC,GAAG,MAAM,EAEV,KAAK,EAAE,sBAAsB,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG;IACpC,GAAG,CAAC,EAAE,KAAK,CAAC,YAAY,CAAC,gBAAgB,CAAC,CAAC;CAC5C,KACE,KAAK,CAAC,YAAY,CAAC"}
1
+ {"version":3,"file":"AutocompleteInput.d.ts","sourceRoot":"","sources":["../../../src/components/form-controls/AutocompleteInput.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAI1B,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAI1C,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAC9B,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,sBAAsB,CAAC,CAAC,GAAG,kBAAkB,EAAE,CAAC,GAAG,MAAM,CACxE,SAAQ,IAAI,CAAC,UAAU,EAAE,UAAU,GAAG,OAAO,GAAG,KAAK,CAAC;IACtD,OAAO,EAAE,CAAC,EAAE,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;;OAGG;IACH,QAAQ,CAAC,EACL,KAAK,CAAC,kBAAkB,CAAC,gBAAgB,CAAC,GAC1C,CAAC,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC,CAAC;IAC9B;;OAEG;IACH,cAAc,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,KAAK,IAAI,CAAC;IAC/C,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;;OAEG;IACH,cAAc,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,MAAM,CAAC;IACrC;;OAEG;IACH,cAAc,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC;IAChC;;OAEG;IACH,oBAAoB,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC;IAChE;;OAEG;IACH,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,KAAK,CAAC,SAAS,CAAC;IAC5C;;;OAGG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAguBD,eAAO,MAAM,iBAAiB,EAA6B,CACzD,CAAC,GAAG,kBAAkB,EACtB,CAAC,GAAG,MAAM,EAEV,KAAK,EAAE,sBAAsB,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG;IACpC,GAAG,CAAC,EAAE,KAAK,CAAC,YAAY,CAAC,gBAAgB,CAAC,CAAC;CAC5C,KACE,KAAK,CAAC,YAAY,CAAC"}
@@ -1,7 +1,9 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
2
  import React from "react";
3
3
  import { createPortal } from "react-dom";
4
+ import { useFormContext } from "react-hook-form";
4
5
  import { Input } from "./Input";
6
+ import { normalizeIconClass } from "../utils/iconUtils";
5
7
  const AutocompleteInputInner = React.forwardRef(({ options, value, onChange, onSelectOption, noResultsText = "Sin resultados", className = "", getOptionLabel, getOptionValue, getOptionDescription, renderOption, readOnly = false, ...inputProps }, ref) => {
6
8
  const [internalValue, setInternalValue] = React.useState(value || "");
7
9
  const [displayValue, setDisplayValue] = React.useState("");
@@ -11,6 +13,7 @@ const AutocompleteInputInner = React.forwardRef(({ options, value, onChange, onS
11
13
  const containerRef = React.useRef(null);
12
14
  const dropdownRef = React.useRef(null);
13
15
  const inputRef = React.useRef(null);
16
+ const hiddenInputRef = React.useRef(null);
14
17
  const justClearedRef = React.useRef(false);
15
18
  // Detectar si estamos en modo register: si viene 'name' de register, estamos en modo register
16
19
  // register siempre pasa 'name', 'onChange', 'onBlur', y 'ref'
@@ -18,6 +21,16 @@ const AutocompleteInputInner = React.forwardRef(({ options, value, onChange, onS
18
21
  // Si viene 'name' en inputProps, es porque viene de register
19
22
  return "name" in inputProps && inputProps.name !== undefined;
20
23
  }, [inputProps]);
24
+ const fieldName = isRegisterMode && "name" in inputProps
25
+ ? inputProps.name
26
+ : undefined;
27
+ // Obtener setValue del contexto del formulario
28
+ // Para usar con register, el formulario debe estar dentro de FormProvider
29
+ // useFormContext debe llamarse incondicionalmente (requisito de React Hooks)
30
+ // Si no hay FormProvider y se usa en modo register, useFormContext lanzará un error
31
+ // Para usar sin FormProvider, usar Controller en lugar de register
32
+ const formContext = useFormContext();
33
+ const setValue = formContext?.setValue;
21
34
  const inputValue = isRegisterMode
22
35
  ? displayValue
23
36
  : value !== undefined
@@ -53,23 +66,27 @@ const AutocompleteInputInner = React.forwardRef(({ options, value, onChange, onS
53
66
  }, [inputValue, options, labelGetter, valueGetter]);
54
67
  // Función helper para sincronizar displayValue con el valor del formulario
55
68
  const syncDisplayValue = React.useCallback(() => {
56
- if (isRegisterMode && inputRef.current) {
57
- const formValue = inputRef.current.value;
58
- // Si el valor del formulario coincide con algún getOptionValue, mostrar su label
59
- const matchingOption = options.find((option) => String(valueGetter(option)) === String(formValue));
60
- if (matchingOption) {
61
- const label = labelGetter(matchingOption);
62
- setDisplayValue(label);
63
- return true; // Indica que se encontró y sincronizó un valor
64
- }
65
- else if (formValue) {
66
- // Si hay un valor pero no coincide, mostrarlo tal cual
67
- setDisplayValue(formValue);
68
- return true;
69
- }
70
- else {
71
- setDisplayValue("");
72
- return false; // No hay valor aún
69
+ if (isRegisterMode) {
70
+ // En modo register, usamos el hiddenInputRef si existe, sino el inputRef (legacy/fallback)
71
+ const targetInput = hiddenInputRef.current || inputRef.current;
72
+ if (targetInput) {
73
+ const formValue = targetInput.value;
74
+ // Si el valor del formulario coincide con algún getOptionValue, mostrar su label
75
+ const matchingOption = options.find((option) => String(valueGetter(option)) === String(formValue));
76
+ if (matchingOption) {
77
+ const label = labelGetter(matchingOption);
78
+ setDisplayValue(label);
79
+ return true; // Indica que se encontró y sincronizó un valor
80
+ }
81
+ else if (formValue) {
82
+ // Si hay un valor pero no coincide, mostrarlo tal cual (o buscar por label si fuera el caso)
83
+ setDisplayValue(formValue);
84
+ return true;
85
+ }
86
+ else {
87
+ setDisplayValue("");
88
+ return false; // No hay valor aún
89
+ }
73
90
  }
74
91
  }
75
92
  return false;
@@ -82,8 +99,9 @@ const AutocompleteInputInner = React.forwardRef(({ options, value, onChange, onS
82
99
  const maxAttempts = 50; // Intentar durante ~5 segundos (50 * 100ms)
83
100
  // Función que intenta sincronizar y retorna true si encontró un valor
84
101
  const trySync = () => {
85
- if (inputRef.current) {
86
- const formValue = inputRef.current.value;
102
+ const targetInput = hiddenInputRef.current || inputRef.current;
103
+ if (targetInput) {
104
+ const formValue = targetInput.value;
87
105
  if (formValue) {
88
106
  // Hay un valor, intentar sincronizar
89
107
  const matchingOption = options.find((option) => String(valueGetter(option)) === String(formValue));
@@ -125,30 +143,36 @@ const AutocompleteInputInner = React.forwardRef(({ options, value, onChange, onS
125
143
  };
126
144
  }
127
145
  }, [isRegisterMode, options, valueGetter, labelGetter]);
128
- // También escuchar cambios en el input nativo para sincronizar cuando cambie
146
+ // También escuchar cambios en el input (hidden o visible) para sincronizar cuando cambie
129
147
  React.useEffect(() => {
130
- if (isRegisterMode && inputRef.current) {
131
- const input = inputRef.current;
132
- // Función para sincronizar cuando el input cambia
133
- const handleInputSync = () => {
134
- syncDisplayValue();
135
- };
136
- // Escuchar eventos de input y change
137
- input.addEventListener("input", handleInputSync);
138
- input.addEventListener("change", handleInputSync);
139
- // También usar MutationObserver para detectar cambios en el atributo value
140
- const observer = new MutationObserver(() => {
141
- syncDisplayValue();
142
- });
143
- observer.observe(input, {
144
- attributes: true,
145
- attributeFilter: ["value"],
146
- });
147
- return () => {
148
- input.removeEventListener("input", handleInputSync);
149
- input.removeEventListener("change", handleInputSync);
150
- observer.disconnect();
151
- };
148
+ if (isRegisterMode) {
149
+ // Observamos el hiddenInput si estamos en register mode y existe, o el input normal
150
+ const targetElement = hiddenInputRef.current || inputRef.current;
151
+ if (targetElement) {
152
+ // Función para sincronizar cuando el input cambia
153
+ const handleInputSync = () => {
154
+ // Solo sincronizar si es el hidden input o si no tenemos hidden input
155
+ if (targetElement === hiddenInputRef.current) {
156
+ syncDisplayValue();
157
+ }
158
+ };
159
+ // Escuchar eventos de input y change (aunque en hidden input no suelen dispararse eventos de usuario)
160
+ targetElement.addEventListener("input", handleInputSync);
161
+ targetElement.addEventListener("change", handleInputSync);
162
+ // También usar MutationObserver para detectar cambios en el atributo value (más fiable para hidden inputs cambiados por JS)
163
+ const observer = new MutationObserver(() => {
164
+ syncDisplayValue();
165
+ });
166
+ observer.observe(targetElement, {
167
+ attributes: true,
168
+ attributeFilter: ["value"],
169
+ });
170
+ return () => {
171
+ targetElement.removeEventListener("input", handleInputSync);
172
+ targetElement.removeEventListener("change", handleInputSync);
173
+ observer.disconnect();
174
+ };
175
+ }
152
176
  }
153
177
  }, [isRegisterMode, syncDisplayValue]);
154
178
  const handleChange = (event) => {
@@ -178,53 +202,56 @@ const AutocompleteInputInner = React.forwardRef(({ options, value, onChange, onS
178
202
  const selectedValue = valueGetter(option);
179
203
  const valueString = String(selectedValue ?? "");
180
204
  if (isRegisterMode) {
181
- // En modo register:
182
- // 1. Actualizar el input nativo con el valor (para que react-hook-form lo capture)
183
- // 2. Actualizar displayValue con el label (para mostrarlo visualmente)
184
- if (inputRef.current) {
185
- const nativeInput = inputRef.current;
186
- // Actualizar el valor del input directamente usando el setter nativo
187
- // Esto evita que React sobrescriba el valor inmediatamente
188
- const nativeInputValueSetter = Object.getOwnPropertyDescriptor(window.HTMLInputElement.prototype, "value")?.set;
189
- if (nativeInputValueSetter) {
190
- nativeInputValueSetter.call(nativeInput, valueString);
191
- }
192
- else {
193
- // Fallback si el setter no está disponible
194
- nativeInput.value = valueString;
205
+ // En modo register, setear el valor usando setValue o actualizando el input nativo (hidden)
206
+ if (setValue && fieldName) {
207
+ setValue(fieldName, selectedValue, {
208
+ shouldValidate: true,
209
+ shouldDirty: true,
210
+ });
211
+ // Actualizar el input hidden con el ID
212
+ if (hiddenInputRef.current) {
213
+ hiddenInputRef.current.value = valueString;
195
214
  }
196
- // IMPORTANTE: Llamar al onChange de register DESPUÉS de actualizar el input
197
- // El evento debe tener el input nativo como target con el valor ya actualizado
198
- if (onChange) {
199
- // Crear un evento que tenga el input nativo como target
200
- // react-hook-form leerá el valor desde event.target.value
201
- const changeEvent = {
202
- target: nativeInput,
203
- currentTarget: nativeInput,
204
- };
205
- onChange(changeEvent);
215
+ // Actualizar displayValue con el label para mostrarlo visualmente en el input visible
216
+ setDisplayValue(label);
217
+ }
218
+ else {
219
+ // Fallback si no hay setValue (raro en registerMode) o para inputs manuales
220
+ const targetInput = hiddenInputRef.current || inputRef.current;
221
+ if (targetInput) {
222
+ const nativeInput = targetInput;
223
+ const nativeInputValueSetter = Object.getOwnPropertyDescriptor(window.HTMLInputElement.prototype, "value")?.set;
224
+ if (nativeInputValueSetter) {
225
+ nativeInputValueSetter.call(nativeInput, valueString);
226
+ }
227
+ else {
228
+ nativeInput.value = valueString;
229
+ }
230
+ // Disparar eventos en el input que tiene el ref de register
231
+ if (onChange) {
232
+ const changeEvent = {
233
+ target: nativeInput,
234
+ currentTarget: nativeInput,
235
+ }; // Cast agresivo necesario
236
+ onChange(changeEvent);
237
+ }
238
+ const inputEvent = new Event("input", {
239
+ bubbles: true,
240
+ cancelable: true,
241
+ });
242
+ nativeInput.dispatchEvent(inputEvent);
243
+ const changeEventNative = new Event("change", {
244
+ bubbles: true,
245
+ cancelable: true,
246
+ });
247
+ nativeInput.dispatchEvent(changeEventNative);
206
248
  }
207
- // También disparar eventos nativos para asegurar que todo esté sincronizado
208
- // Estos eventos son importantes para la validación y el estado del formulario
209
- const inputEvent = new Event("input", {
210
- bubbles: true,
211
- cancelable: true,
212
- });
213
- nativeInput.dispatchEvent(inputEvent);
214
- const changeEventNative = new Event("change", {
215
- bubbles: true,
216
- cancelable: true,
217
- });
218
- nativeInput.dispatchEvent(changeEventNative);
249
+ // Y actualizamos visualmente
250
+ setDisplayValue(label);
219
251
  }
220
- // Actualizar el displayValue para mostrar el label
221
- setDisplayValue(label);
222
252
  }
223
253
  else {
224
254
  // Modo API personalizada - comportamiento original
225
- if (value === undefined) {
226
- setInternalValue(label);
227
- }
228
255
  // Pasar el valor devuelto por getOptionValue, no el label
229
256
  if (onChange) {
230
257
  onChange(valueString);
@@ -346,11 +373,15 @@ const AutocompleteInputInner = React.forwardRef(({ options, value, onChange, onS
346
373
  // Detectar si hay un valor seleccionado
347
374
  // Un valor está seleccionado si el value coincide con el getOptionValue de alguna opción
348
375
  const hasSelectedValue = React.useMemo(() => {
349
- if (isRegisterMode && inputRef.current) {
350
- const formValue = inputRef.current.value;
351
- if (!formValue)
352
- return false;
353
- return options.some((option) => String(valueGetter(option)) === String(formValue));
376
+ if (isRegisterMode) {
377
+ const targetInput = hiddenInputRef.current || inputRef.current;
378
+ if (targetInput) {
379
+ const formValue = targetInput.value;
380
+ if (!formValue)
381
+ return false;
382
+ return options.some((option) => String(valueGetter(option)) === String(formValue));
383
+ }
384
+ return false;
354
385
  }
355
386
  if (value === undefined || value === null || value === "")
356
387
  return false;
@@ -366,9 +397,10 @@ const AutocompleteInputInner = React.forwardRef(({ options, value, onChange, onS
366
397
  // Marcar que acabamos de limpiar para prevenir que onFocus abra el diálogo
367
398
  justClearedRef.current = true;
368
399
  if (isRegisterMode) {
369
- // En modo register, limpiar el input nativo y disparar eventos
370
- if (inputRef.current) {
371
- const nativeInput = inputRef.current;
400
+ // En modo register, limpiar el input nativo (hidden) y disparar eventos
401
+ const targetInput = hiddenInputRef.current || inputRef.current;
402
+ if (targetInput) {
403
+ const nativeInput = targetInput;
372
404
  const setter = Object.getOwnPropertyDescriptor(window.HTMLInputElement.prototype, "value")?.set;
373
405
  setter?.call(nativeInput, "");
374
406
  // Disparar eventos para que react-hook-form lo capture
@@ -376,17 +408,17 @@ const AutocompleteInputInner = React.forwardRef(({ options, value, onChange, onS
376
408
  nativeInput.dispatchEvent(inputEvent);
377
409
  const changeEvent = new Event("change", { bubbles: true });
378
410
  nativeInput.dispatchEvent(changeEvent);
411
+ // Llamar al onChange de register
412
+ if (onChange) {
413
+ const changeEventReact = {
414
+ target: nativeInput,
415
+ currentTarget: nativeInput,
416
+ };
417
+ onChange(changeEventReact);
418
+ }
379
419
  }
380
420
  // Limpiar el displayValue
381
421
  setDisplayValue("");
382
- // Llamar al onChange de register
383
- if (onChange && inputRef.current) {
384
- const changeEvent = {
385
- target: inputRef.current,
386
- currentTarget: inputRef.current,
387
- };
388
- onChange(changeEvent);
389
- }
390
422
  }
391
423
  else {
392
424
  // Modo API personalizada
@@ -420,39 +452,53 @@ const AutocompleteInputInner = React.forwardRef(({ options, value, onChange, onS
420
452
  : hasSelectedValue
421
453
  ? handleClear
422
454
  : inputProps.onIconClick;
423
- // Combinar refs: el ref del componente y el ref interno
424
- const combinedRef = React.useCallback((node) => {
425
- inputRef.current = node;
426
- if (typeof ref === "function") {
427
- ref(node);
428
- }
429
- else if (ref) {
430
- ref.current = node;
431
- }
432
- // Cuando el ref se establece en modo register, sincronizar el displayValue
433
- // Esto es importante para valores por defecto que vienen del formulario
434
- if (isRegisterMode && node) {
435
- // Intentar múltiples veces con diferentes delays
436
- // react-hook-form puede establecer el valor en diferentes momentos
437
- [0, 10, 50, 100, 200, 500].forEach((delay) => {
438
- setTimeout(() => {
439
- if (node && inputRef.current === node) {
440
- const formValue = node.value;
441
- if (formValue) {
442
- const matchingOption = options.find((option) => String(valueGetter(option)) === String(formValue));
443
- if (matchingOption) {
444
- setDisplayValue(labelGetter(matchingOption));
445
- }
446
- else {
447
- setDisplayValue(formValue);
455
+ // Refs separados: uno para el visible y otro para el hidden (registrado)
456
+ const setHiddenRef = React.useCallback((node) => {
457
+ hiddenInputRef.current = node;
458
+ // Solo pasar el ref externo al hidden input en modo register
459
+ if (isRegisterMode) {
460
+ if (typeof ref === "function") {
461
+ ref(node);
462
+ }
463
+ else if (ref) {
464
+ ref.current = node;
465
+ }
466
+ // Sincronización inicial cuando el ref se monta
467
+ if (node) {
468
+ [0, 10, 50, 100, 200, 500].forEach((delay) => {
469
+ setTimeout(() => {
470
+ if (node && hiddenInputRef.current === node) {
471
+ const formValue = node.value;
472
+ if (formValue) {
473
+ const matchingOption = options.find((option) => String(valueGetter(option)) === String(formValue));
474
+ if (matchingOption) {
475
+ setDisplayValue(labelGetter(matchingOption));
476
+ }
477
+ else {
478
+ setDisplayValue(formValue);
479
+ }
448
480
  }
449
481
  }
450
- }
451
- }, delay);
452
- });
482
+ }, delay);
483
+ });
484
+ }
453
485
  }
454
486
  }, [ref, isRegisterMode, options, valueGetter, labelGetter]);
455
- return (_jsxs("div", { ref: containerRef, className: "relative w-full", children: [_jsx(Input, { ...inputProps, ref: combinedRef, value: inputValue, onChange: handleChange, onFocus: () => {
487
+ const setVisibleRef = React.useCallback((node) => {
488
+ inputRef.current = node;
489
+ // En modo NO register, pasamos el ref al input visible
490
+ if (!isRegisterMode) {
491
+ if (typeof ref === "function") {
492
+ ref(node);
493
+ }
494
+ else if (ref) {
495
+ ref.current = node;
496
+ }
497
+ }
498
+ }, [ref, isRegisterMode]);
499
+ // Separar propiedades para input visible y hidden
500
+ const { name: nameProp, ...visibleInputProps } = inputProps;
501
+ return (_jsxs("div", { ref: containerRef, className: "relative w-full", children: [isRegisterMode && (_jsx("input", { type: "hidden", name: nameProp, ref: setHiddenRef, defaultValue: value })), _jsx(Input, { ...visibleInputProps, name: isRegisterMode ? undefined : nameProp, ref: setVisibleRef, value: inputValue, onChange: handleChange, onFocus: () => {
456
502
  if (!readOnly && !justClearedRef.current) {
457
503
  setIsOpen(true);
458
504
  }
@@ -467,7 +513,7 @@ const AutocompleteInputInner = React.forwardRef(({ options, value, onChange, onS
467
513
  dropdownPosition &&
468
514
  isMounted &&
469
515
  bodyElement &&
470
- createPortal(_jsx("div", { ref: dropdownRef, className: "fixed z-[2001] min-w-full w-max rounded-md border border-[var(--color-border-default)] \r\n bg-[var(--color-bg-default)] shadow-[var(--shadow-lg)] max-h-60 overflow-auto", style: {
516
+ createPortal(_jsx("div", { ref: dropdownRef, className: "fixed z-[2001] min-w-full w-max rounded-md border border-[var(--color-border-default)] \n bg-[var(--color-bg-default)] shadow-[var(--shadow-lg)] max-h-60 overflow-auto", style: {
471
517
  top: `${dropdownPosition.top}px`,
472
518
  left: `${dropdownPosition.left}px`,
473
519
  minWidth: `${dropdownPosition.width}px`,
@@ -475,13 +521,13 @@ const AutocompleteInputInner = React.forwardRef(({ options, value, onChange, onS
475
521
  const label = labelGetter(option);
476
522
  const description = descriptionGetter(option);
477
523
  const anyOption = option;
478
- return (_jsx("li", { className: `px-3 py-2 cursor-pointer flex items-start gap-2 text-sm
524
+ return (_jsx("li", { className: `px-3 py-2 cursor-pointer flex items-start gap-2 text-sm
479
525
  ${index === highlightedIndex
480
526
  ? "bg-[var(--color-primary-soft)] text-[var(--color-primary)]"
481
527
  : "text-[var(--color-text-primary)] hover:bg-[var(--color-bg-secondary)]"}`, onMouseDown: (event) => {
482
528
  event.preventDefault();
483
529
  handleSelect(option);
484
- }, onMouseEnter: () => setHighlightedIndex(index), children: renderOption ? (renderOption(option)) : (_jsxs(_Fragment, { children: [anyOption.icon && (_jsx("i", { className: `fa ${anyOption.icon} mt-0.5 text-[var(--color-text-muted)] flex-shrink-0` })), _jsxs("div", { className: "flex flex-col min-w-0", children: [_jsx("span", { className: "font-[var(--font-default)] whitespace-nowrap", children: label }), description !== undefined &&
530
+ }, onMouseEnter: () => setHighlightedIndex(index), children: renderOption ? (renderOption(option)) : (_jsxs(_Fragment, { children: [anyOption.icon && (_jsx("i", { className: `${normalizeIconClass(anyOption.icon)} mt-0.5 text-[var(--color-text-muted)] flex-shrink-0` })), _jsxs("div", { className: "flex flex-col min-w-0", children: [_jsx("span", { className: "font-[var(--font-default)] whitespace-nowrap", children: label }), description !== undefined &&
485
531
  description !== null && (_jsx("span", { className: "text-xs text-[var(--color-text-secondary)] break-words", children: description }))] })] })) }, String(valueGetter(option) ?? label ?? index)));
486
532
  }) })) : (_jsx("div", { className: "px-3 py-2 text-sm text-[var(--color-text-secondary)]", children: noResultsText })) }), bodyElement));
487
533
  })()] }));
@@ -2,6 +2,9 @@ import React from "react";
2
2
  export interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
3
3
  variant?: "primary" | "outline" | "ghost";
4
4
  size?: "sm" | "md" | "lg";
5
+ color?: "primary" | "secondary" | "success" | "warning" | "danger" | "info";
6
+ bg?: string;
7
+ textColor?: string;
5
8
  icon?: string;
6
9
  iconPosition?: "left" | "right";
7
10
  loading?: boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"Button.d.ts","sourceRoot":"","sources":["../../../src/components/form-controls/Button.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,MAAM,WAAW,WACf,SAAQ,KAAK,CAAC,oBAAoB,CAAC,iBAAiB,CAAC;IACrD,OAAO,CAAC,EAAE,SAAS,GAAG,SAAS,GAAG,OAAO,CAAC;IAC1C,IAAI,CAAC,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;IAC1B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,YAAY,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IAChC,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CAC5B;AASD,eAAO,MAAM,MAAM,EAAE,KAAK,CAAC,EAAE,CAAC,WAAW,CAiHxC,CAAC"}
1
+ {"version":3,"file":"Button.d.ts","sourceRoot":"","sources":["../../../src/components/form-controls/Button.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAkC1B,MAAM,WAAW,WACf,SAAQ,KAAK,CAAC,oBAAoB,CAAC,iBAAiB,CAAC;IACrD,OAAO,CAAC,EAAE,SAAS,GAAG,SAAS,GAAG,OAAO,CAAC;IAC1C,IAAI,CAAC,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;IAC1B,KAAK,CAAC,EAAE,SAAS,GAAG,WAAW,GAAG,SAAS,GAAG,SAAS,GAAG,QAAQ,GAAG,MAAM,CAAC;IAC5E,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,YAAY,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IAChC,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CAC5B;AASD,eAAO,MAAM,MAAM,EAAE,KAAK,CAAC,EAAE,CAAC,WAAW,CAwPxC,CAAC"}