flysoft-react-ui 1.2.3 → 1.2.5

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 (270) hide show
  1. package/AI_CONTEXT.md +1400 -217
  2. package/AI_INTEGRATION_GUIDE.md +343 -0
  3. package/INTEGRATION_GUIDE.md +60 -0
  4. package/README.md +5 -3
  5. package/dist/components/form-controls/Input.d.ts.map +1 -1
  6. package/dist/components/form-controls/index.d.ts +2 -2
  7. package/dist/components/form-controls/index.d.ts.map +1 -1
  8. package/dist/components/layout/Accordion.d.ts +1 -0
  9. package/dist/components/layout/Accordion.d.ts.map +1 -1
  10. package/dist/components/layout/DataTable.d.ts.map +1 -1
  11. package/dist/components/layout/DropdownMenu.d.ts +2 -1
  12. package/dist/components/layout/DropdownMenu.d.ts.map +1 -1
  13. package/dist/components/layout/DropdownPanel.d.ts +2 -1
  14. package/dist/components/layout/DropdownPanel.d.ts.map +1 -1
  15. package/dist/components/layout/Filter.d.ts +1 -0
  16. package/dist/components/layout/Filter.d.ts.map +1 -1
  17. package/dist/components/layout/Menu.d.ts +2 -1
  18. package/dist/components/layout/Menu.d.ts.map +1 -1
  19. package/dist/components/layout/TabsGroup.d.ts +1 -0
  20. package/dist/components/layout/TabsGroup.d.ts.map +1 -1
  21. package/dist/index.css +1 -1
  22. package/dist/index.d.ts +2 -0
  23. package/dist/index.d.ts.map +1 -1
  24. package/dist/index.js +11889 -24
  25. package/dist/index.js.map +1 -1
  26. package/dist/templates/forms/ContactForm.d.ts +1 -0
  27. package/dist/templates/forms/ContactForm.d.ts.map +1 -1
  28. package/dist/templates/forms/LoginForm.d.ts +1 -0
  29. package/dist/templates/forms/LoginForm.d.ts.map +1 -1
  30. package/dist/templates/forms/RegistrationForm.d.ts +1 -0
  31. package/dist/templates/forms/RegistrationForm.d.ts.map +1 -1
  32. package/dist/templates/layouts/DashboardLayout.d.ts +1 -0
  33. package/dist/templates/layouts/DashboardLayout.d.ts.map +1 -1
  34. package/dist/templates/layouts/SidebarLayout.d.ts +1 -0
  35. package/dist/templates/layouts/SidebarLayout.d.ts.map +1 -1
  36. package/dist/templates/patterns/FormPattern.d.ts +1 -0
  37. package/dist/templates/patterns/FormPattern.d.ts.map +1 -1
  38. package/dist/templates/patterns/ListPattern.d.ts +77 -0
  39. package/dist/templates/patterns/ListPattern.d.ts.map +1 -0
  40. package/package.json +6 -3
  41. package/dist/App.d.ts +0 -4
  42. package/dist/App.d.ts.map +0 -1
  43. package/dist/App.js +0 -30
  44. package/dist/components/ThemeSwitcher.js +0 -12
  45. package/dist/components/form-controls/AutocompleteInput.js +0 -680
  46. package/dist/components/form-controls/Button.js +0 -211
  47. package/dist/components/form-controls/Checkbox.js +0 -79
  48. package/dist/components/form-controls/CurrencyInput.js +0 -106
  49. package/dist/components/form-controls/DateInput.js +0 -578
  50. package/dist/components/form-controls/DatePicker.js +0 -144
  51. package/dist/components/form-controls/Input.js +0 -35
  52. package/dist/components/form-controls/LinkButton.js +0 -248
  53. package/dist/components/form-controls/Pagination.js +0 -23
  54. package/dist/components/form-controls/RadioButtonGroup.js +0 -220
  55. package/dist/components/form-controls/SearchSelectInput-OLD.d.ts +0 -68
  56. package/dist/components/form-controls/SearchSelectInput-OLD.d.ts.map +0 -1
  57. package/dist/components/form-controls/SearchSelectInput-OLD.js +0 -962
  58. package/dist/components/form-controls/SearchSelectInput.js +0 -336
  59. package/dist/components/form-controls/index.js +0 -11
  60. package/dist/components/index.js +0 -7
  61. package/dist/components/layout/Accordion.js +0 -67
  62. package/dist/components/layout/AppLayout.js +0 -230
  63. package/dist/components/layout/Card.js +0 -54
  64. package/dist/components/layout/Collection.js +0 -18
  65. package/dist/components/layout/DataField.js +0 -38
  66. package/dist/components/layout/DataTable.js +0 -164
  67. package/dist/components/layout/DropdownMenu.js +0 -176
  68. package/dist/components/layout/DropdownPanel.js +0 -162
  69. package/dist/components/layout/Filter.js +0 -629
  70. package/dist/components/layout/Menu.js +0 -21
  71. package/dist/components/layout/TabPanel.js +0 -11
  72. package/dist/components/layout/TabsGroup.js +0 -52
  73. package/dist/components/layout/index.js +0 -12
  74. package/dist/components/utils/Avatar.js +0 -77
  75. package/dist/components/utils/Badge.js +0 -151
  76. package/dist/components/utils/Dialog.js +0 -44
  77. package/dist/components/utils/FiltersDialog.js +0 -104
  78. package/dist/components/utils/Loader.js +0 -44
  79. package/dist/components/utils/RoadMap.js +0 -139
  80. package/dist/components/utils/Skeleton.js +0 -10
  81. package/dist/components/utils/Snackbar.js +0 -136
  82. package/dist/components/utils/SnackbarContainer.js +0 -26
  83. package/dist/components/utils/iconUtils.js +0 -40
  84. package/dist/components/utils/index.js +0 -9
  85. package/dist/contexts/AppLayoutContext.js +0 -104
  86. package/dist/contexts/AuthContext.js +0 -224
  87. package/dist/contexts/CrudContext.js +0 -333
  88. package/dist/contexts/SnackbarContext.js +0 -41
  89. package/dist/contexts/ThemeContext.js +0 -197
  90. package/dist/contexts/index.js +0 -13
  91. package/dist/contexts/presets.js +0 -311
  92. package/dist/contexts/types.js +0 -1
  93. package/dist/docs/AccordionDocs.d.ts +0 -4
  94. package/dist/docs/AccordionDocs.d.ts.map +0 -1
  95. package/dist/docs/AccordionDocs.js +0 -21
  96. package/dist/docs/AuthDocs.tsx/AuthDocs.d.ts +0 -13
  97. package/dist/docs/AuthDocs.tsx/AuthDocs.d.ts.map +0 -1
  98. package/dist/docs/AuthDocs.tsx/AuthDocs.js +0 -18
  99. package/dist/docs/AuthDocs.tsx/AuthDocsContent.d.ts +0 -2
  100. package/dist/docs/AuthDocs.tsx/AuthDocsContent.d.ts.map +0 -1
  101. package/dist/docs/AuthDocs.tsx/AuthDocsContent.js +0 -22
  102. package/dist/docs/AuthDocs.tsx/mockAuthService.d.ts +0 -24
  103. package/dist/docs/AuthDocs.tsx/mockAuthService.d.ts.map +0 -1
  104. package/dist/docs/AuthDocs.tsx/mockAuthService.js +0 -78
  105. package/dist/docs/AutocompleteInputDocs.d.ts +0 -4
  106. package/dist/docs/AutocompleteInputDocs.d.ts.map +0 -1
  107. package/dist/docs/AutocompleteInputDocs.js +0 -84
  108. package/dist/docs/AvatarDocs.d.ts +0 -4
  109. package/dist/docs/AvatarDocs.d.ts.map +0 -1
  110. package/dist/docs/AvatarDocs.js +0 -7
  111. package/dist/docs/BadgeDocs.d.ts +0 -4
  112. package/dist/docs/BadgeDocs.d.ts.map +0 -1
  113. package/dist/docs/BadgeDocs.js +0 -9
  114. package/dist/docs/ButtonDocs.d.ts +0 -4
  115. package/dist/docs/ButtonDocs.d.ts.map +0 -1
  116. package/dist/docs/ButtonDocs.js +0 -7
  117. package/dist/docs/CardDocs.d.ts +0 -4
  118. package/dist/docs/CardDocs.d.ts.map +0 -1
  119. package/dist/docs/CardDocs.js +0 -22
  120. package/dist/docs/CheckboxDocs.d.ts +0 -4
  121. package/dist/docs/CheckboxDocs.d.ts.map +0 -1
  122. package/dist/docs/CheckboxDocs.js +0 -7
  123. package/dist/docs/CurrencyInputDocs.d.ts +0 -4
  124. package/dist/docs/CurrencyInputDocs.d.ts.map +0 -1
  125. package/dist/docs/CurrencyInputDocs.js +0 -22
  126. package/dist/docs/DataFieldDocs.d.ts +0 -4
  127. package/dist/docs/DataFieldDocs.d.ts.map +0 -1
  128. package/dist/docs/DataFieldDocs.js +0 -7
  129. package/dist/docs/DataTableDocs.d.ts +0 -4
  130. package/dist/docs/DataTableDocs.d.ts.map +0 -1
  131. package/dist/docs/DataTableDocs.js +0 -244
  132. package/dist/docs/DateInputDocs.d.ts +0 -5
  133. package/dist/docs/DateInputDocs.d.ts.map +0 -1
  134. package/dist/docs/DateInputDocs.js +0 -19
  135. package/dist/docs/DatePickerDocs.d.ts +0 -5
  136. package/dist/docs/DatePickerDocs.d.ts.map +0 -1
  137. package/dist/docs/DatePickerDocs.js +0 -16
  138. package/dist/docs/DialogDocs.d.ts +0 -4
  139. package/dist/docs/DialogDocs.d.ts.map +0 -1
  140. package/dist/docs/DialogDocs.js +0 -13
  141. package/dist/docs/DocAdmin.d.ts +0 -4
  142. package/dist/docs/DocAdmin.d.ts.map +0 -1
  143. package/dist/docs/DocAdmin.js +0 -68
  144. package/dist/docs/DocsMenu.d.ts +0 -2
  145. package/dist/docs/DocsMenu.d.ts.map +0 -1
  146. package/dist/docs/DocsMenu.js +0 -5
  147. package/dist/docs/DocsRouter.d.ts +0 -4
  148. package/dist/docs/DocsRouter.d.ts.map +0 -1
  149. package/dist/docs/DocsRouter.js +0 -39
  150. package/dist/docs/DropdownMenuDocs.d.ts +0 -4
  151. package/dist/docs/DropdownMenuDocs.d.ts.map +0 -1
  152. package/dist/docs/DropdownMenuDocs.js +0 -66
  153. package/dist/docs/DropdownPanelDocs.d.ts +0 -4
  154. package/dist/docs/DropdownPanelDocs.d.ts.map +0 -1
  155. package/dist/docs/DropdownPanelDocs.js +0 -7
  156. package/dist/docs/ExampleFormDocs.d.ts +0 -4
  157. package/dist/docs/ExampleFormDocs.d.ts.map +0 -1
  158. package/dist/docs/ExampleFormDocs.js +0 -153
  159. package/dist/docs/FilterDocs.d.ts +0 -4
  160. package/dist/docs/FilterDocs.d.ts.map +0 -1
  161. package/dist/docs/FilterDocs.js +0 -130
  162. package/dist/docs/InputDocs.d.ts +0 -4
  163. package/dist/docs/InputDocs.d.ts.map +0 -1
  164. package/dist/docs/InputDocs.js +0 -17
  165. package/dist/docs/LinkButtonDocs.d.ts +0 -4
  166. package/dist/docs/LinkButtonDocs.d.ts.map +0 -1
  167. package/dist/docs/LinkButtonDocs.js +0 -7
  168. package/dist/docs/ListCrudDocs.tsx/ListCrudDocs.d.ts +0 -2
  169. package/dist/docs/ListCrudDocs.tsx/ListCrudDocs.d.ts.map +0 -1
  170. package/dist/docs/ListCrudDocs.tsx/ListCrudDocs.js +0 -47
  171. package/dist/docs/ListCrudDocs.tsx/ListCrudDocsContentEmpresaPersonas.d.ts +0 -2
  172. package/dist/docs/ListCrudDocs.tsx/ListCrudDocsContentEmpresaPersonas.d.ts.map +0 -1
  173. package/dist/docs/ListCrudDocs.tsx/ListCrudDocsContentEmpresaPersonas.js +0 -34
  174. package/dist/docs/ListCrudDocs.tsx/ListCrudDocsContentEmpresaSingle.d.ts +0 -2
  175. package/dist/docs/ListCrudDocs.tsx/ListCrudDocsContentEmpresaSingle.d.ts.map +0 -1
  176. package/dist/docs/ListCrudDocs.tsx/ListCrudDocsContentEmpresaSingle.js +0 -66
  177. package/dist/docs/ListCrudDocs.tsx/ListCrudDocsContentEmpresas.d.ts +0 -2
  178. package/dist/docs/ListCrudDocs.tsx/ListCrudDocsContentEmpresas.d.ts.map +0 -1
  179. package/dist/docs/ListCrudDocs.tsx/ListCrudDocsContentEmpresas.js +0 -7
  180. package/dist/docs/ListCrudDocs.tsx/ListCrudDocsContentEmpresasPersonasEditDialog.d.ts +0 -10
  181. package/dist/docs/ListCrudDocs.tsx/ListCrudDocsContentEmpresasPersonasEditDialog.d.ts.map +0 -1
  182. package/dist/docs/ListCrudDocs.tsx/ListCrudDocsContentEmpresasPersonasEditDialog.js +0 -39
  183. package/dist/docs/ListCrudDocs.tsx/ListCrudDocsContentPersonas.d.ts +0 -2
  184. package/dist/docs/ListCrudDocs.tsx/ListCrudDocsContentPersonas.d.ts.map +0 -1
  185. package/dist/docs/ListCrudDocs.tsx/ListCrudDocsContentPersonas.js +0 -57
  186. package/dist/docs/ListCrudDocs.tsx/ListCrudDocsEditDialog.d.ts +0 -9
  187. package/dist/docs/ListCrudDocs.tsx/ListCrudDocsEditDialog.d.ts.map +0 -1
  188. package/dist/docs/ListCrudDocs.tsx/ListCrudDocsEditDialog.js +0 -30
  189. package/dist/docs/LoaderDocs.d.ts +0 -4
  190. package/dist/docs/LoaderDocs.d.ts.map +0 -1
  191. package/dist/docs/LoaderDocs.js +0 -33
  192. package/dist/docs/MenuDocs.d.ts +0 -4
  193. package/dist/docs/MenuDocs.d.ts.map +0 -1
  194. package/dist/docs/MenuDocs.js +0 -26
  195. package/dist/docs/PaginationDocs.d.ts +0 -4
  196. package/dist/docs/PaginationDocs.d.ts.map +0 -1
  197. package/dist/docs/PaginationDocs.js +0 -38
  198. package/dist/docs/RadioButtonGroupDocs.d.ts +0 -4
  199. package/dist/docs/RadioButtonGroupDocs.d.ts.map +0 -1
  200. package/dist/docs/RadioButtonGroupDocs.js +0 -46
  201. package/dist/docs/RoadMapDocs.d.ts +0 -4
  202. package/dist/docs/RoadMapDocs.d.ts.map +0 -1
  203. package/dist/docs/RoadMapDocs.js +0 -171
  204. package/dist/docs/SearchSelectInputDocs.d.ts +0 -4
  205. package/dist/docs/SearchSelectInputDocs.d.ts.map +0 -1
  206. package/dist/docs/SearchSelectInputDocs.js +0 -168
  207. package/dist/docs/SkeletonDocs.d.ts +0 -4
  208. package/dist/docs/SkeletonDocs.d.ts.map +0 -1
  209. package/dist/docs/SkeletonDocs.js +0 -7
  210. package/dist/docs/SnackbarDocs.d.ts +0 -4
  211. package/dist/docs/SnackbarDocs.d.ts.map +0 -1
  212. package/dist/docs/SnackbarDocs.js +0 -69
  213. package/dist/docs/TabsGroupDocs.d.ts +0 -4
  214. package/dist/docs/TabsGroupDocs.d.ts.map +0 -1
  215. package/dist/docs/TabsGroupDocs.js +0 -38
  216. package/dist/docs/ThemeSwitcherDocs.d.ts +0 -4
  217. package/dist/docs/ThemeSwitcherDocs.d.ts.map +0 -1
  218. package/dist/docs/ThemeSwitcherDocs.js +0 -11
  219. package/dist/docs/docMockServices/empresaService.d.ts +0 -38
  220. package/dist/docs/docMockServices/empresaService.d.ts.map +0 -1
  221. package/dist/docs/docMockServices/empresaService.js +0 -125
  222. package/dist/docs/docMockServices/index.d.ts +0 -9
  223. package/dist/docs/docMockServices/index.d.ts.map +0 -1
  224. package/dist/docs/docMockServices/index.js +0 -8
  225. package/dist/docs/docMockServices/initialData.d.ts +0 -6
  226. package/dist/docs/docMockServices/initialData.d.ts.map +0 -1
  227. package/dist/docs/docMockServices/initialData.js +0 -132
  228. package/dist/docs/docMockServices/interfaces.d.ts +0 -38
  229. package/dist/docs/docMockServices/interfaces.d.ts.map +0 -1
  230. package/dist/docs/docMockServices/interfaces.js +0 -1
  231. package/dist/docs/docMockServices/personaEmpresaService.d.ts +0 -43
  232. package/dist/docs/docMockServices/personaEmpresaService.d.ts.map +0 -1
  233. package/dist/docs/docMockServices/personaEmpresaService.js +0 -151
  234. package/dist/docs/docMockServices/personaService.d.ts +0 -39
  235. package/dist/docs/docMockServices/personaService.d.ts.map +0 -1
  236. package/dist/docs/docMockServices/personaService.js +0 -190
  237. package/dist/helpers/currencyFormat.js +0 -3
  238. package/dist/helpers/getErrorMessage.js +0 -13
  239. package/dist/helpers/getInitialLetters.js +0 -5
  240. package/dist/helpers/getQueryString.js +0 -13
  241. package/dist/helpers/index.js +0 -9
  242. package/dist/helpers/mappers.js +0 -27
  243. package/dist/helpers/nameValueArrayToObject.js +0 -3
  244. package/dist/helpers/objectToQueryString.js +0 -3
  245. package/dist/helpers/queryStringToObject.js +0 -13
  246. package/dist/helpers/regularExpressions.js +0 -5
  247. package/dist/hooks/index.js +0 -6
  248. package/dist/hooks/useAsyncRequest.js +0 -53
  249. package/dist/hooks/useBreakpoint.js +0 -59
  250. package/dist/hooks/useElementScroll.js +0 -58
  251. package/dist/hooks/useEnum.js +0 -21
  252. package/dist/hooks/useGlobalThemeStyles.js +0 -40
  253. package/dist/hooks/useThemeOverride.js +0 -99
  254. package/dist/interfaces/index.js +0 -1
  255. package/dist/interfaces/name-value.interface.js +0 -1
  256. package/dist/interfaces/pagination.interface.js +0 -1
  257. package/dist/main.d.ts +0 -2
  258. package/dist/main.d.ts.map +0 -1
  259. package/dist/main.js +0 -6
  260. package/dist/services/apiClient.js +0 -216
  261. package/dist/services/index.js +0 -1
  262. package/dist/styles.d.ts +0 -2
  263. package/dist/styles.d.ts.map +0 -1
  264. package/dist/styles.js +0 -3
  265. package/dist/templates/forms/ContactForm.js +0 -58
  266. package/dist/templates/forms/LoginForm.js +0 -36
  267. package/dist/templates/forms/RegistrationForm.js +0 -54
  268. package/dist/templates/layouts/DashboardLayout.js +0 -26
  269. package/dist/templates/layouts/SidebarLayout.js +0 -28
  270. package/dist/templates/patterns/FormPattern.js +0 -68
@@ -1,336 +0,0 @@
1
- import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
- import React, { useState, useMemo, useRef, useCallback, useEffect, } from "react";
3
- import { useFormContext } from "react-hook-form";
4
- import { Input } from "./Input";
5
- import { Button } from "./Button";
6
- import { Dialog, Loader } from "../utils";
7
- import { normalizeIconClass } from "../utils/iconUtils";
8
- const SearchSelectInputInner = React.forwardRef(function SearchSelectInput({ value, onChange, onSearchPromiseFn, onSingleSearchPromiseFn, onSelectOption, dialogTitle = "Seleccione una opción", icon = "fa-search", iconPosition = "right", noResultsText = "Sin resultados", getOptionLabel, getOptionValue, getOptionDescription, renderOption, label, readOnly = false, ...inputProps }, ref) {
9
- const [inputText, setInputText] = useState("");
10
- const [dialogInputText, setDialogInputText] = useState("");
11
- const [isDialogOpen, setIsDialogOpen] = useState(false);
12
- const [options, setOptions] = useState([]);
13
- const [isLoading, setIsLoading] = useState(false);
14
- const [hasSearched, setHasSearched] = useState(false);
15
- const inputRef = useRef(null);
16
- const dialogInputRef = useRef(null);
17
- const justClearedRef = useRef(false);
18
- // Detectar modo register
19
- const isRegisterMode = useMemo(() => {
20
- return "name" in inputProps && inputProps.name !== undefined;
21
- }, [inputProps]);
22
- const fieldName = isRegisterMode && "name" in inputProps
23
- ? inputProps.name
24
- : undefined;
25
- // Obtener setValue del contexto del formulario
26
- // Para usar con register, el formulario debe estar dentro de FormProvider
27
- // useFormContext debe llamarse incondicionalmente (requisito de React Hooks)
28
- // Si no hay FormProvider y se usa en modo register, useFormContext lanzará un error
29
- // Para usar sin FormProvider, usar Controller en lugar de register
30
- const formContext = useFormContext();
31
- const setValue = formContext?.setValue;
32
- // Combinar refs
33
- const combinedRef = useCallback((node) => {
34
- inputRef.current = node;
35
- if (typeof ref === "function") {
36
- ref(node);
37
- }
38
- else if (ref) {
39
- ref.current = node;
40
- }
41
- }, [ref]);
42
- const valueGetter = useCallback((item) => {
43
- if (getOptionValue)
44
- return getOptionValue(item);
45
- return item["value"];
46
- }, [getOptionValue]);
47
- const labelGetter = useCallback((item) => {
48
- if (getOptionLabel)
49
- return getOptionLabel(item);
50
- return item["label"];
51
- }, [getOptionLabel]);
52
- const descriptionGetter = useCallback((item) => {
53
- if (getOptionDescription)
54
- return getOptionDescription(item);
55
- return item["description"];
56
- }, [getOptionDescription]);
57
- const handleSearch = async (text) => {
58
- setIsLoading(true);
59
- setHasSearched(true);
60
- const options = await onSearchPromiseFn(text);
61
- if (options instanceof Array) {
62
- setOptions(options);
63
- }
64
- else {
65
- setOptions(options.list);
66
- }
67
- setIsLoading(false);
68
- };
69
- const handleSelect = (option) => {
70
- const selectedValue = valueGetter(option);
71
- setIsDialogOpen(false);
72
- // En modo register, setear el valor usando setValue o actualizando el input nativo
73
- if (isRegisterMode) {
74
- if (setValue && fieldName) {
75
- setValue(fieldName, selectedValue, {
76
- shouldValidate: true,
77
- shouldDirty: true,
78
- });
79
- }
80
- else if (inputRef.current) {
81
- const nativeInput = inputRef.current;
82
- const nativeInputValueSetter = Object.getOwnPropertyDescriptor(window.HTMLInputElement.prototype, "value")?.set;
83
- if (nativeInputValueSetter) {
84
- nativeInputValueSetter.call(nativeInput, String(selectedValue ?? ""));
85
- }
86
- else {
87
- nativeInput.value = String(selectedValue ?? "");
88
- }
89
- if (onChange) {
90
- const changeEvent = {
91
- target: nativeInput,
92
- currentTarget: nativeInput,
93
- };
94
- onChange(changeEvent);
95
- }
96
- const inputEvent = new Event("input", {
97
- bubbles: true,
98
- cancelable: true,
99
- });
100
- nativeInput.dispatchEvent(inputEvent);
101
- const changeEventNative = new Event("change", {
102
- bubbles: true,
103
- cancelable: true,
104
- });
105
- nativeInput.dispatchEvent(changeEventNative);
106
- }
107
- }
108
- else {
109
- onChange?.(selectedValue);
110
- }
111
- onSelectOption?.(option, selectedValue);
112
- setInputText(labelGetter(option));
113
- setDialogInputText("");
114
- setOptions([]);
115
- setHasSearched(false);
116
- };
117
- // Función para sincronizar inputText con un valor
118
- const syncInputText = useCallback((currentValue) => {
119
- if (currentValue === undefined ||
120
- currentValue === null ||
121
- currentValue === "") {
122
- setInputText("");
123
- return;
124
- }
125
- // Si currentValue es un objeto (T) y tenemos getOptionLabel, usar directamente
126
- if (typeof currentValue === "object" &&
127
- getOptionLabel &&
128
- !getOptionValue) {
129
- try {
130
- const label = getOptionLabel(currentValue);
131
- setInputText(label);
132
- return;
133
- }
134
- catch {
135
- // Si falla, continuar con la búsqueda normal
136
- }
137
- }
138
- // Normalizar el value: si es un objeto (T), extraer el valor usando valueGetter
139
- let valueToSearch = currentValue;
140
- if (typeof currentValue === "object" && getOptionValue) {
141
- // Si currentValue es un objeto y tenemos getOptionValue, extraer el valor
142
- try {
143
- valueToSearch = getOptionValue(currentValue);
144
- }
145
- catch {
146
- // Si falla, no podemos usar onSingleSearchPromiseFn con un objeto
147
- // Intentar mostrar el label directamente si está disponible
148
- if (getOptionLabel) {
149
- try {
150
- setInputText(getOptionLabel(currentValue));
151
- return;
152
- }
153
- catch {
154
- setInputText(String(currentValue));
155
- return;
156
- }
157
- }
158
- setInputText(String(currentValue));
159
- return;
160
- }
161
- }
162
- // Buscar en las opciones actuales
163
- const matchingOption = options.find((opt) => valueGetter(opt) === valueToSearch ||
164
- valueGetter(opt) === currentValue);
165
- if (matchingOption) {
166
- setInputText(labelGetter(matchingOption));
167
- return;
168
- }
169
- // Si no se encuentra en las opciones actuales, usar onSingleSearchPromiseFn
170
- if (onSingleSearchPromiseFn &&
171
- valueToSearch !== undefined &&
172
- valueToSearch !== null) {
173
- onSingleSearchPromiseFn(valueToSearch)
174
- .then((foundOption) => {
175
- if (foundOption) {
176
- setInputText(labelGetter(foundOption));
177
- // Agregar la opción a las opciones disponibles si no está ya
178
- setOptions((prev) => {
179
- if (!prev.find((opt) => valueGetter(opt) === valueGetter(foundOption))) {
180
- return [...prev, foundOption];
181
- }
182
- return prev;
183
- });
184
- }
185
- else {
186
- // Si no se encuentra, mostrar el valor como string
187
- setInputText(String(valueToSearch));
188
- }
189
- })
190
- .catch((error) => {
191
- console.error("Error al buscar opción individual:", error);
192
- setInputText(String(valueToSearch));
193
- });
194
- }
195
- else {
196
- // Si no hay onSingleSearchPromiseFn, mostrar el valor como string
197
- setInputText(String(valueToSearch));
198
- }
199
- }, [
200
- options,
201
- getOptionValue,
202
- getOptionLabel,
203
- onSingleSearchPromiseFn,
204
- valueGetter,
205
- labelGetter,
206
- ]);
207
- // Sincronizar inputText cuando cambia el value (modo controlado)
208
- useEffect(() => {
209
- if (!isRegisterMode) {
210
- syncInputText(value);
211
- }
212
- }, [value, isRegisterMode, syncInputText]);
213
- // Sincronizar inputText cuando cambia el valor del formulario (modo register)
214
- useEffect(() => {
215
- if (isRegisterMode && formContext && fieldName) {
216
- // Sincronizar inicialmente
217
- const formValue = formContext.watch(fieldName);
218
- syncInputText(formValue);
219
- // Suscribirse a cambios del formulario
220
- const subscription = formContext.watch((_data, { name }) => {
221
- // Solo sincronizar cuando cambia el campo específico
222
- if (name === fieldName) {
223
- const currentFormValue = formContext.watch(fieldName);
224
- syncInputText(currentFormValue);
225
- }
226
- });
227
- return () => subscription.unsubscribe();
228
- }
229
- }, [isRegisterMode, formContext, fieldName, syncInputText]);
230
- // Hacer blur en el input del dialog cuando se abre
231
- useEffect(() => {
232
- if (isDialogOpen) {
233
- // El Dialog renderiza condicionalmente, así que necesitamos esperar a que el input esté montado
234
- // Usar requestAnimationFrame doble para asegurar que el DOM esté completamente renderizado
235
- const timeoutId = setTimeout(() => {
236
- requestAnimationFrame(() => {
237
- dialogInputRef.current?.focus();
238
- });
239
- }, 50);
240
- return () => clearTimeout(timeoutId);
241
- }
242
- }, [isDialogOpen]);
243
- const getDialogBody = () => {
244
- return (_jsxs("div", { children: [_jsx("div", { className: "mb-2", children: _jsx(Input, { ref: dialogInputRef, value: dialogInputText, onChange: (e) => setDialogInputText(e.target.value), icon: icon, iconPosition: iconPosition, onIconClick: () => handleSearch(dialogInputText), onKeyDown: (e) => {
245
- if (e.key === "Enter") {
246
- e.preventDefault();
247
- handleSearch(dialogInputText);
248
- }
249
- } }) }), _jsx("div", { children: _jsx(Loader, { isLoading: isLoading, children: !hasSearched || options.length > 0 ? (_jsx("ul", { className: "space-y-1 max-h-96 overflow-y-auto list-none pl-0 m-0", children: options.map((option, index) => {
250
- const label = labelGetter(option);
251
- const description = descriptionGetter(option);
252
- const anyOption = option;
253
- return (_jsx("li", { className: "px-3 py-2 cursor-pointer rounded-md flex items-start gap-2 text-sm\r\n text-[var(--color-text-primary)] hover:bg-[var(--color-bg-secondary)] transition-colors", onClick: () => handleSelect(option), children: renderOption ? (renderOption(option)) : (_jsxs(_Fragment, { children: [anyOption.icon && (_jsx("i", { className: `${normalizeIconClass(anyOption.icon)} mt-0.5 text-[var(--color-text-muted)]` })), _jsxs("div", { className: "flex flex-col flex-1", children: [_jsx("span", { className: "font-[var(--font-default)]", children: label }), description !== undefined &&
254
- description !== null && (_jsx("span", { className: "text-xs text-[var(--color-text-secondary)]", children: description }))] })] })) }, String(valueGetter(option) ?? label ?? index)));
255
- }) })) : (_jsx("div", { className: "px-3 py-8 text-center text-sm text-[var(--color-text-secondary)]", children: noResultsText })) }) })] }));
256
- };
257
- // Detectar si hay un valor seleccionado
258
- const hasValue = inputText !== "" && inputText !== undefined && inputText !== null;
259
- // Función para limpiar el valor y abrir el dialog
260
- const handleIconClick = useCallback((event) => {
261
- if (readOnly)
262
- return;
263
- event.preventDefault();
264
- event.stopPropagation();
265
- if (hasValue) {
266
- // Si hay valor, limpiarlo
267
- // Marcar que acabamos de limpiar para prevenir que onFocus abra el diálogo
268
- justClearedRef.current = true;
269
- if (isRegisterMode) {
270
- if (setValue && fieldName) {
271
- setValue(fieldName, undefined, {
272
- shouldValidate: true,
273
- shouldDirty: true,
274
- });
275
- }
276
- else if (inputRef.current) {
277
- const nativeInput = inputRef.current;
278
- const nativeInputValueSetter = Object.getOwnPropertyDescriptor(window.HTMLInputElement.prototype, "value")?.set;
279
- if (nativeInputValueSetter) {
280
- nativeInputValueSetter.call(nativeInput, "");
281
- }
282
- else {
283
- nativeInput.value = "";
284
- }
285
- if (onChange) {
286
- const changeEvent = {
287
- target: nativeInput,
288
- currentTarget: nativeInput,
289
- };
290
- onChange(changeEvent);
291
- }
292
- const inputEvent = new Event("input", {
293
- bubbles: true,
294
- cancelable: true,
295
- });
296
- nativeInput.dispatchEvent(inputEvent);
297
- const changeEventNative = new Event("change", {
298
- bubbles: true,
299
- cancelable: true,
300
- });
301
- nativeInput.dispatchEvent(changeEventNative);
302
- }
303
- }
304
- else {
305
- onChange?.(undefined);
306
- }
307
- setInputText("");
308
- setIsDialogOpen(false);
309
- // Resetear el flag después de un pequeño delay para permitir que otros eventos se procesen
310
- setTimeout(() => {
311
- justClearedRef.current = false;
312
- }, 100);
313
- }
314
- else {
315
- // Si no hay valor, abrir el dialog
316
- setIsDialogOpen(true);
317
- }
318
- }, [hasValue, isRegisterMode, setValue, fieldName, onChange, readOnly]);
319
- // Determinar qué ícono mostrar: si hay valor, mostrar "fa-times", sino el ícono original
320
- // Si está en readOnly, no mostrar ningún ícono
321
- const displayIcon = readOnly ? undefined : hasValue ? "fa-times" : icon;
322
- const displayIconPosition = readOnly ? undefined : iconPosition;
323
- const displayOnIconClick = readOnly ? undefined : handleIconClick;
324
- return (_jsxs(_Fragment, { children: [_jsx(Input, { ...inputProps, ref: combinedRef, label: label, value: inputText, onChange: (e) => {
325
- if (readOnly)
326
- return;
327
- setInputText(e.target.value);
328
- }, onFocus: () => {
329
- if (!readOnly && !justClearedRef.current) {
330
- setIsDialogOpen(true);
331
- }
332
- }, icon: displayIcon, iconPosition: displayIconPosition, onIconClick: displayOnIconClick, readOnly: readOnly }), !readOnly && (_jsx(Dialog, { isOpen: isDialogOpen, title: dialogTitle, footer: _jsx(Button, { variant: "outline", onClick: () => setIsDialogOpen(false), children: "Cerrar" }), onClose: () => setIsDialogOpen(false), children: getDialogBody() }))] }));
333
- });
334
- SearchSelectInputInner.displayName = "SearchSelectInput";
335
- // Exportar con el cast genérico para permitir uso como <SearchSelectInput<T, K>>
336
- export const SearchSelectInput = SearchSelectInputInner;
@@ -1,11 +0,0 @@
1
- export { Button } from "./Button";
2
- export { LinkButton } from "./LinkButton";
3
- export { Input } from "./Input";
4
- export { AutocompleteInput } from "./AutocompleteInput";
5
- export { SearchSelectInput } from "./SearchSelectInput-OLD";
6
- export { DatePicker } from "./DatePicker";
7
- export { DateInput } from "./DateInput";
8
- export { Pagination } from "./Pagination";
9
- export { Checkbox } from "./Checkbox";
10
- export { RadioButtonGroup } from "./RadioButtonGroup";
11
- export { CurrencyInput } from "./CurrencyInput";
@@ -1,7 +0,0 @@
1
- // Form Controls
2
- export * from "./form-controls";
3
- // Layout Components
4
- export * from "./layout";
5
- // Utility Components
6
- export * from "./utils";
7
- export { ThemeSwitcher } from "./ThemeSwitcher";
@@ -1,67 +0,0 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import React, { useState, useRef, useEffect } from "react";
3
- import { normalizeIconClass } from "../utils/iconUtils";
4
- export const Accordion = ({ title, children, icon, rightNode, defaultOpen = false, className = "", variant = "default", onToggle, }) => {
5
- const [isOpen, setIsOpen] = useState(defaultOpen);
6
- const [contentHeight, setContentHeight] = useState(0);
7
- const contentRef = useRef(null);
8
- // Separar clases de background del className
9
- const classArray = className.trim().split(/\s+/).filter(Boolean);
10
- const bgClasses = [];
11
- const otherClasses = [];
12
- classArray.forEach((cls) => {
13
- // Detectar clases de background (bg-*, bg-gradient-*, bg-[...])
14
- if (cls.startsWith("bg-") || cls.startsWith("bg-gradient-")) {
15
- bgClasses.push(cls);
16
- }
17
- else {
18
- otherClasses.push(cls);
19
- }
20
- });
21
- const backgroundClass = bgClasses.length > 0 ? bgClasses.join(" ") : "bg-[var(--color-bg-default)]";
22
- const baseClasses = `
23
- ${backgroundClass} rounded-lg border
24
- font-[var(--font-default)]
25
- `;
26
- const variantClasses = {
27
- default: `border-[var(--color-border-default)]`,
28
- elevated: `border-[var(--color-border-default)] shadow-[var(--shadow-lg)]`,
29
- outlined: `border-[var(--color-gray-300)]`,
30
- };
31
- const classes = `${baseClasses} ${variantClasses[variant]} ${otherClasses.join(" ")}`;
32
- useEffect(() => {
33
- if (contentRef.current) {
34
- if (isOpen) {
35
- // Usar requestAnimationFrame para asegurar que el DOM esté actualizado
36
- requestAnimationFrame(() => {
37
- if (contentRef.current) {
38
- setContentHeight(contentRef.current.scrollHeight);
39
- }
40
- });
41
- }
42
- else {
43
- setContentHeight(0);
44
- }
45
- }
46
- }, [isOpen, children]);
47
- // Inicializar altura si está abierto por defecto
48
- useEffect(() => {
49
- if (defaultOpen && contentRef.current) {
50
- requestAnimationFrame(() => {
51
- if (contentRef.current) {
52
- setContentHeight(contentRef.current.scrollHeight);
53
- }
54
- });
55
- }
56
- }, [defaultOpen]);
57
- const handleToggle = () => {
58
- const newIsOpen = !isOpen;
59
- setIsOpen(newIsOpen);
60
- if (onToggle) {
61
- onToggle(newIsOpen);
62
- }
63
- };
64
- return (_jsxs("div", { className: `${classes} overflow-hidden`, children: [_jsxs("button", { onClick: handleToggle, className: "w-full flex items-center justify-between px-4 py-3 flysoft-button-reset bg-transparent border-none hover:bg-black/5 dark:hover:bg-white/5 transition-colors cursor-pointer", "aria-expanded": isOpen, children: [_jsxs("div", { className: "flex items-center gap-3 flex-1 min-w-0", children: [icon && (_jsx("i", { className: `${normalizeIconClass(icon)} text-[var(--color-text-secondary)] flex-shrink-0` })), _jsx("span", { className: "text-left font-medium text-[var(--color-text-primary)] truncate", children: title })] }), _jsxs("div", { className: "flex items-center gap-2 flex-shrink-0", children: [rightNode && (_jsx("div", { className: "flex items-center", onClick: (e) => e.stopPropagation(), children: rightNode })), _jsx("i", { className: `${normalizeIconClass(`fa-chevron-${isOpen ? "up" : "down"}`)} text-[var(--color-text-secondary)] transition-all duration-200 flex-shrink-0` })] })] }), _jsx("div", { ref: contentRef, className: "overflow-hidden transition-all duration-300 ease-in-out", style: {
65
- maxHeight: `${contentHeight}px`,
66
- }, children: _jsx("div", { className: "px-4 py-3 text-[var(--color-text-primary)]", children: children }) })] }));
67
- };
@@ -1,230 +0,0 @@
1
- import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
- import React, { useState, useRef } from "react";
3
- import { useBreakpoint } from "../../hooks";
4
- import { useElementScroll } from "../../hooks/useElementScroll";
5
- import { Button } from "../form-controls";
6
- export const AppLayout = ({ navbar, leftDrawer, contentFooter, children, className = "", }) => {
7
- // Extract values from interfaces
8
- const navBarLeftNode = navbar?.navBarLeftNode;
9
- const navBarRightNode = navbar?.navBarRightNode;
10
- const fullWidthNavbar = navbar?.fullWidthNavbar ?? true;
11
- const navbarHeight = navbar?.height ?? "64px";
12
- const navbarClassName = navbar?.className || "";
13
- const leftDrawerHeader = leftDrawer?.headerNode;
14
- const leftDrawerContent = leftDrawer?.contentNode;
15
- const leftDrawerFooter = leftDrawer?.footerNode;
16
- const leftDrawerClassName = leftDrawer?.className || "";
17
- const leftDrawerWidth = leftDrawer?.width;
18
- const { isMobile, isTablet } = useBreakpoint();
19
- const contentRef = useRef(null);
20
- const { scrollY, scrollDirection } = useElementScroll(contentRef);
21
- const [isMobileDrawerOpen, setIsMobileDrawerOpen] = useState(false);
22
- const [isNavbarVisible, setIsNavbarVisible] = useState(true);
23
- const isNavbarVisibleRef = useRef(isNavbarVisible);
24
- const isTransitioningRef = useRef(false);
25
- const lastScrollYRef = useRef(0);
26
- // Determinar si hay algún contenido en el drawer izquierdo
27
- const hasLeftDrawerContent = leftDrawerHeader || leftDrawerContent || leftDrawerFooter;
28
- const shouldShowMobileDrawer = isMobile || isTablet;
29
- const shouldShowDesktopDrawer = !shouldShowMobileDrawer && hasLeftDrawerContent;
30
- // Determinar si debemos mostrar el navbar
31
- // Se muestra si hay navBarLeftNode o navBarRightNode o si estamos en móvil/tablet con contenido en el drawer
32
- const shouldShowNavbar = navBarLeftNode ||
33
- navBarRightNode ||
34
- (shouldShowMobileDrawer && hasLeftDrawerContent);
35
- // Mantener el ref sincronizado con el estado
36
- React.useEffect(() => {
37
- isNavbarVisibleRef.current = isNavbarVisible;
38
- // Marcar que estamos en transición por 350ms (duración de la transición + margen)
39
- isTransitioningRef.current = true;
40
- const timer = setTimeout(() => {
41
- isTransitioningRef.current = false;
42
- }, 350);
43
- return () => clearTimeout(timer);
44
- }, [isNavbarVisible]);
45
- // Controlar visibilidad del navbar basado en scroll con histeresis mejorada
46
- React.useEffect(() => {
47
- // Ignorar cambios durante transiciones o cambios muy pequeños de scroll
48
- if (isTransitioningRef.current) {
49
- return;
50
- }
51
- const SCROLL_DELTA_THRESHOLD = 5; // Mínimo cambio de scroll para considerar
52
- const scrollDelta = Math.abs(scrollY - lastScrollYRef.current);
53
- // Ignorar cambios muy pequeños que pueden ser causados por el cambio de padding
54
- if (scrollDelta < SCROLL_DELTA_THRESHOLD && lastScrollYRef.current > 0) {
55
- return;
56
- }
57
- const SHOW_THRESHOLD = 80;
58
- const HIDE_THRESHOLD = 120;
59
- // Verificar si estamos cerca del final del scroll (margen de error de 10px)
60
- const element = contentRef.current;
61
- const isNearBottom = element
62
- ? Math.abs(element.scrollHeight - element.clientHeight - element.scrollTop) < 10
63
- : false;
64
- let shouldBeVisible;
65
- if (scrollY < SHOW_THRESHOLD) {
66
- // Siempre mostrar navbar cerca del top
67
- shouldBeVisible = true;
68
- }
69
- else if (scrollDirection === "down" &&
70
- scrollY > HIDE_THRESHOLD &&
71
- !isNearBottom) {
72
- // Ocultar navbar al hacer scroll hacia abajo, excepto si estamos cerca del final
73
- shouldBeVisible = false;
74
- }
75
- else if (scrollDirection === "up" && scrollY > SHOW_THRESHOLD) {
76
- // Mostrar navbar al hacer scroll hacia arriba
77
- shouldBeVisible = true;
78
- }
79
- else if (isNearBottom && scrollDirection === "down") {
80
- // Si estamos en el final y scrolleamos hacia abajo, mantener el estado actual
81
- return;
82
- }
83
- else {
84
- // No cambiar el estado si scrollDirection es null o no se cumple ninguna condición
85
- return;
86
- }
87
- // Solo actualizar el estado si hay un cambio real
88
- if (shouldBeVisible !== isNavbarVisibleRef.current) {
89
- lastScrollYRef.current = scrollY;
90
- setIsNavbarVisible(shouldBeVisible);
91
- }
92
- else {
93
- // Actualizar la referencia del scroll incluso si no cambiamos la visibilidad
94
- lastScrollYRef.current = scrollY;
95
- }
96
- }, [scrollDirection, scrollY]);
97
- const handleMobileDrawerToggle = () => {
98
- setIsMobileDrawerOpen(!isMobileDrawerOpen);
99
- };
100
- const handleOverlayClick = () => {
101
- setIsMobileDrawerOpen(false);
102
- };
103
- // Clases base del layout
104
- const layoutClasses = `
105
- flex flex-col w-full ${navbar?.navBarLeftNode || navbar?.navBarRightNode || leftDrawer?.contentNode || leftDrawer?.headerNode || leftDrawer?.footerNode ? "h-screen overflow-hidden" : "h-auto"}
106
- font-[var(--font-default)]
107
- ${className}
108
- `;
109
- // Clases del navbar
110
- const navbarClasses = `${fullWidthNavbar
111
- ? `z-[1000] fixed top-0 left-0 right-0 overflow-hidden`
112
- : `relative z-[1000] overflow-hidden`} ${navbarClassName}`.trim();
113
- // Estilos inline para la transformación
114
- // Cuando fullWidthNavbar es false, solo usamos height para ocultar (sin transform)
115
- // Cuando fullWidthNavbar es true, usamos transform para ocultar (manteniendo height)
116
- const navbarStyle = fullWidthNavbar
117
- ? {
118
- transform: isNavbarVisible ? "translateY(0)" : "translateY(-100%)",
119
- transition: "transform 100ms ease-in",
120
- willChange: "transform",
121
- height: navbarHeight, // Override any height classes in className
122
- }
123
- : {
124
- height: isNavbarVisible ? navbarHeight : "0",
125
- minHeight: isNavbarVisible ? navbarHeight : "0",
126
- maxHeight: isNavbarVisible ? navbarHeight : "0",
127
- transition: "height 100ms ease-in, min-height 100ms ease-in, max-height 100ms ease-in",
128
- overflow: "hidden",
129
- };
130
- const navbarContentClasses = `flex items-center justify-between gap-2`;
131
- // Style for navbar content with dynamic height
132
- // When fullWidthNavbar is false and hidden, set height to 0 to not occupy space
133
- // When fullWidthNavbar is true, always maintain height to prevent layout shifts
134
- const navbarContentStyle = {
135
- height: fullWidthNavbar || isNavbarVisible ? navbarHeight : "0",
136
- maxHeight: fullWidthNavbar || isNavbarVisible ? navbarHeight : "0",
137
- overflow: "hidden",
138
- transition: "height 100ms ease-in, max-height 100ms ease-in",
139
- opacity: isNavbarVisible || fullWidthNavbar ? 1 : 0,
140
- };
141
- const navbarLeftClasses = `flex items-center gap-2`;
142
- const navbarRightClasses = `flex items-center gap-2`;
143
- // Clases del contenido principal
144
- const mainClasses = `flex flex-1 overflow-hidden transition-all duration-100 ease-in`;
145
- // Style for main content with dynamic navbar height padding
146
- // No padding here anymore, it's handled by individual elements
147
- const mainStyle = {};
148
- // Style for the main content area (actual scrollable area)
149
- // When fullWidthNavbar is true, we need top padding to avoid being covered by fixed navbar
150
- const contentStyle = fullWidthNavbar && shouldShowNavbar && isNavbarVisible
151
- ? { paddingTop: navbarHeight }
152
- : {};
153
- // Clases del drawer izquierdo (contenedor principal)
154
- // width se aplica como estilo inline para tener prioridad sobre className
155
- const leftDrawerClasses = `
156
- ${leftDrawerWidth ? "" : "w-64"} bg-[var(--color-bg-default)]
157
- flex-shrink-0 flex flex-col
158
- transition-all duration-100 ease-in
159
- ${leftDrawerClassName}
160
- `
161
- .trim()
162
- .replace(/\s+/g, " ");
163
- // Style for left drawer with dynamic height and positioning
164
- const leftDrawerStyle = {
165
- ...(leftDrawerWidth ? { width: leftDrawerWidth } : {}),
166
- height: "100%", // Siempre 100% para evitar huecos en la parte superior
167
- };
168
- if (fullWidthNavbar) {
169
- // Si el navbar es fullwidth, el drawer mide 100% y usamos padding para que el contenido
170
- // no quede debajo del navbar fixed.
171
- leftDrawerStyle.paddingTop =
172
- shouldShowNavbar && isNavbarVisible ? navbarHeight : "0px";
173
- leftDrawerStyle.transition = "padding-top 100ms ease-in";
174
- }
175
- else {
176
- // Si no es fullwidth, el drawer está al lado del navbar.
177
- // No necesitamos marginTop ni height dinámico porque ya está en un flex-row
178
- // y queremos que ocupe siempre todo el alto desde el borde superior.
179
- leftDrawerStyle.marginTop = "0px";
180
- leftDrawerStyle.transition = "padding-top 100ms ease-in";
181
- }
182
- // Clases del contenedor que incluye drawer y contenido (cuando fullWidthNavbar es false)
183
- const contentWrapperClasses = fullWidthNavbar
184
- ? ""
185
- : `flex flex-row flex-1 overflow-hidden`;
186
- // Clases del contenedor que incluye navbar y main (cuando fullWidthNavbar es false)
187
- const drawerAndContentClasses = fullWidthNavbar
188
- ? ""
189
- : `flex flex-col flex-1 overflow-hidden`;
190
- // Style for drawer and content wrapper with dynamic navbar height padding
191
- const drawerAndContentStyle = !fullWidthNavbar && shouldShowNavbar && isNavbarVisible
192
- ? { paddingTop: 0 }
193
- : {};
194
- // Clases del header del drawer (fijo arriba)
195
- const leftDrawerHeaderClasses = `
196
- flex-shrink-0
197
- `;
198
- // Clases del contenido del drawer (scrolleable sin scrollbar visible)
199
- const leftDrawerContentClasses = `
200
- flex-1 overflow-y-auto scrollbar-hide
201
- `;
202
- // Clases del footer del drawer (fijo abajo)
203
- const leftDrawerFooterClasses = `
204
- flex-shrink-0
205
- `;
206
- const contentClasses = `
207
- flex-1 overflow-y-auto flex flex-col
208
- `;
209
- // Clases del overlay móvil
210
- const overlayClasses = `
211
- fixed inset-0 bg-black/50 backdrop-blur-sm z-[1998]
212
- `;
213
- // Clases del drawer móvil
214
- const mobileDrawerBaseClasses = `
215
- fixed top-0 left-0 h-screen w-64 max-w-[80vw]
216
- bg-[var(--color-bg-default)] shadow-[var(--shadow-xl)]
217
- transform -translate-x-full transition-transform duration-100 ease-in
218
- z-[1999] flex flex-col
219
- ${leftDrawerClassName}
220
- `
221
- .trim()
222
- .replace(/\s+/g, " ");
223
- // Style for mobile drawer with dynamic width
224
- const mobileDrawerStyle = leftDrawerWidth ? { width: leftDrawerWidth } : {};
225
- const mobileDrawerOpenClasses = `translate-x-0`;
226
- const mobileDrawerContentClasses = `
227
- flex-1 overflow-y-auto scrollbar-hide
228
- `;
229
- return (_jsxs("div", { className: layoutClasses, children: [fullWidthNavbar ? (_jsxs(_Fragment, { children: [shouldShowNavbar && (_jsx("nav", { className: navbarClasses, style: navbarStyle, children: _jsxs("div", { className: navbarContentClasses, style: navbarContentStyle, children: [_jsxs("div", { className: navbarLeftClasses, children: [shouldShowMobileDrawer && hasLeftDrawerContent && (_jsx("div", { className: "pr-4 lg:px-4 md:px-3", children: _jsx(Button, { variant: "ghost", icon: "fa-bars", onClick: handleMobileDrawerToggle, "aria-label": "Abrir men\u00FA" }) })), navBarLeftNode && (_jsx("div", { children: typeof navBarLeftNode === "string" ? (_jsx("span", { children: navBarLeftNode })) : (navBarLeftNode) }))] }), navBarRightNode && (_jsx("div", { className: navbarRightClasses, children: typeof navBarRightNode === "string" ? (_jsx("span", { children: navBarRightNode })) : (navBarRightNode) }))] }) })), _jsxs("div", { className: mainClasses, style: mainStyle, children: [shouldShowDesktopDrawer && (_jsxs("aside", { className: leftDrawerClasses, style: leftDrawerStyle, children: [leftDrawerHeader && (_jsx("div", { className: leftDrawerHeaderClasses, children: leftDrawerHeader })), leftDrawerContent && (_jsx("div", { className: leftDrawerContentClasses, children: leftDrawerContent })), leftDrawerFooter && (_jsx("div", { className: leftDrawerFooterClasses, children: leftDrawerFooter }))] })), _jsxs("main", { ref: contentRef, className: contentClasses, style: contentStyle, children: [_jsx("div", { className: "flex-1", children: children }), contentFooter && _jsx("div", { role: "contentinfo", children: contentFooter })] })] })] })) : (_jsx(_Fragment, { children: _jsxs("div", { className: contentWrapperClasses, children: [shouldShowDesktopDrawer && (_jsxs("aside", { className: leftDrawerClasses, style: leftDrawerStyle, children: [leftDrawerHeader && (_jsx("div", { className: leftDrawerHeaderClasses, children: leftDrawerHeader })), leftDrawerContent && (_jsx("div", { className: leftDrawerContentClasses, children: leftDrawerContent })), leftDrawerFooter && (_jsx("div", { className: leftDrawerFooterClasses, children: leftDrawerFooter }))] })), _jsxs("div", { className: drawerAndContentClasses, style: drawerAndContentStyle, children: [shouldShowNavbar && (_jsx("nav", { className: navbarClasses, style: navbarStyle, children: _jsxs("div", { className: navbarContentClasses, style: navbarContentStyle, children: [_jsxs("div", { className: navbarLeftClasses, children: [shouldShowMobileDrawer && hasLeftDrawerContent && (_jsx("div", { className: "pr-4 px-2", children: _jsx(Button, { variant: "ghost", icon: "fa-bars", onClick: handleMobileDrawerToggle, "aria-label": "Abrir men\u00FA" }) })), navBarLeftNode && (_jsx("div", { children: typeof navBarLeftNode === "string" ? (_jsx("span", { children: navBarLeftNode })) : (navBarLeftNode) }))] }), navBarRightNode && (_jsx("div", { className: navbarRightClasses, children: typeof navBarRightNode === "string" ? (_jsx("span", { children: navBarRightNode })) : (navBarRightNode) }))] }) })), _jsxs("main", { ref: contentRef, className: contentClasses, style: contentStyle, children: [_jsx("div", { className: "flex-1", children: children }), contentFooter && _jsx("div", { role: "contentinfo", children: contentFooter })] })] })] }) })), shouldShowMobileDrawer && hasLeftDrawerContent && isMobileDrawerOpen && (_jsx("div", { className: overlayClasses, onClick: handleOverlayClick })), shouldShowMobileDrawer && hasLeftDrawerContent && (_jsxs("aside", { className: `${mobileDrawerBaseClasses} ${isMobileDrawerOpen ? mobileDrawerOpenClasses : ""}`, style: mobileDrawerStyle, children: [_jsxs("div", { className: "flex-shrink-0 flex items-center justify-between", children: [leftDrawerHeader ? (_jsx("div", { className: "flex-1", children: leftDrawerHeader })) : (_jsx("div", { className: "flex-1" })), _jsx("div", { className: "absolute top-3 right-2", children: _jsx(Button, { variant: "ghost", icon: "fa-times", onClick: handleMobileDrawerToggle, "aria-label": "Cerrar men\u00FA" }) })] }), leftDrawerContent && (_jsx("div", { className: mobileDrawerContentClasses, children: leftDrawerContent })), leftDrawerFooter && (_jsx("div", { className: "flex-shrink-0", children: leftDrawerFooter }))] }))] }));
230
- };