flysoft-react-ui 0.5.0 → 0.5.3

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 (206) hide show
  1. package/dist/App.d.ts.map +1 -1
  2. package/dist/App.js +19 -7
  3. package/dist/components/form-controls/AutocompleteInput.d.ts +11 -3
  4. package/dist/components/form-controls/AutocompleteInput.d.ts.map +1 -1
  5. package/dist/components/form-controls/AutocompleteInput.js +411 -31
  6. package/dist/components/form-controls/Button.d.ts +3 -0
  7. package/dist/components/form-controls/Button.d.ts.map +1 -1
  8. package/dist/components/form-controls/Button.js +160 -19
  9. package/dist/components/form-controls/Checkbox.d.ts +14 -0
  10. package/dist/components/form-controls/Checkbox.d.ts.map +1 -0
  11. package/dist/components/form-controls/Checkbox.js +79 -0
  12. package/dist/components/form-controls/DateInput.d.ts +24 -4
  13. package/dist/components/form-controls/DateInput.d.ts.map +1 -1
  14. package/dist/components/form-controls/DateInput.js +492 -70
  15. package/dist/components/form-controls/DatePicker.d.ts +4 -3
  16. package/dist/components/form-controls/DatePicker.d.ts.map +1 -1
  17. package/dist/components/form-controls/DatePicker.js +26 -30
  18. package/dist/components/form-controls/Input.d.ts +10 -1
  19. package/dist/components/form-controls/Input.d.ts.map +1 -1
  20. package/dist/components/form-controls/Input.js +17 -10
  21. package/dist/components/form-controls/LinkButton.d.ts +15 -0
  22. package/dist/components/form-controls/LinkButton.d.ts.map +1 -0
  23. package/dist/components/form-controls/LinkButton.js +248 -0
  24. package/dist/components/form-controls/Pagination.d.ts +1 -0
  25. package/dist/components/form-controls/Pagination.d.ts.map +1 -1
  26. package/dist/components/form-controls/Pagination.js +3 -40
  27. package/dist/components/form-controls/RadioButtonGroup.d.ts +62 -0
  28. package/dist/components/form-controls/RadioButtonGroup.d.ts.map +1 -0
  29. package/dist/components/form-controls/RadioButtonGroup.js +220 -0
  30. package/dist/components/form-controls/SearchSelectInput-OLD.d.ts +68 -0
  31. package/dist/components/form-controls/SearchSelectInput-OLD.d.ts.map +1 -0
  32. package/dist/components/form-controls/SearchSelectInput-OLD.js +963 -0
  33. package/dist/components/form-controls/SearchSelectInput.d.ts +70 -0
  34. package/dist/components/form-controls/SearchSelectInput.d.ts.map +1 -0
  35. package/dist/components/form-controls/SearchSelectInput.js +336 -0
  36. package/dist/components/form-controls/index.d.ts +9 -1
  37. package/dist/components/form-controls/index.d.ts.map +1 -1
  38. package/dist/components/form-controls/index.js +4 -0
  39. package/dist/components/layout/Accordion.d.ts +13 -0
  40. package/dist/components/layout/Accordion.d.ts.map +1 -0
  41. package/dist/components/layout/Accordion.js +67 -0
  42. package/dist/components/layout/AppLayout.d.ts +3 -2
  43. package/dist/components/layout/AppLayout.d.ts.map +1 -1
  44. package/dist/components/layout/AppLayout.js +104 -31
  45. package/dist/components/layout/Card.d.ts +8 -3
  46. package/dist/components/layout/Card.d.ts.map +1 -1
  47. package/dist/components/layout/Card.js +18 -19
  48. package/dist/components/layout/Collection.js +1 -1
  49. package/dist/components/layout/DataTable.d.ts +3 -1
  50. package/dist/components/layout/DataTable.d.ts.map +1 -1
  51. package/dist/components/layout/DataTable.js +34 -29
  52. package/dist/components/layout/index.d.ts +2 -0
  53. package/dist/components/layout/index.d.ts.map +1 -1
  54. package/dist/components/layout/index.js +1 -0
  55. package/dist/components/utils/Avatar.d.ts +49 -0
  56. package/dist/components/utils/Avatar.d.ts.map +1 -0
  57. package/dist/components/utils/Avatar.js +93 -0
  58. package/dist/components/utils/Badge.d.ts +3 -0
  59. package/dist/components/utils/Badge.d.ts.map +1 -1
  60. package/dist/components/utils/Badge.js +131 -26
  61. package/dist/components/utils/Dialog.d.ts.map +1 -1
  62. package/dist/components/utils/Dialog.js +6 -1
  63. package/dist/components/utils/Filter.d.ts +57 -0
  64. package/dist/components/utils/Filter.d.ts.map +1 -0
  65. package/dist/components/utils/Filter.js +581 -0
  66. package/dist/components/utils/FiltersDialog.d.ts +21 -0
  67. package/dist/components/utils/FiltersDialog.d.ts.map +1 -0
  68. package/dist/components/utils/FiltersDialog.js +104 -0
  69. package/dist/components/utils/Loader.js +2 -2
  70. package/dist/components/utils/RoadMap.d.ts +59 -0
  71. package/dist/components/utils/RoadMap.d.ts.map +1 -0
  72. package/dist/components/utils/RoadMap.js +139 -0
  73. package/dist/components/utils/Snackbar.d.ts +13 -0
  74. package/dist/components/utils/Snackbar.d.ts.map +1 -0
  75. package/dist/components/utils/Snackbar.js +122 -0
  76. package/dist/components/utils/SnackbarContainer.d.ts +7 -0
  77. package/dist/components/utils/SnackbarContainer.d.ts.map +1 -0
  78. package/dist/components/utils/SnackbarContainer.js +25 -0
  79. package/dist/components/utils/iconUtils.d.ts +16 -0
  80. package/dist/components/utils/iconUtils.d.ts.map +1 -0
  81. package/dist/components/utils/iconUtils.js +40 -0
  82. package/dist/components/utils/index.d.ts +12 -0
  83. package/dist/components/utils/index.d.ts.map +1 -1
  84. package/dist/components/utils/index.js +6 -0
  85. package/dist/contexts/AppLayoutContext.d.ts +40 -0
  86. package/dist/contexts/AppLayoutContext.d.ts.map +1 -0
  87. package/dist/contexts/AppLayoutContext.js +98 -0
  88. package/dist/contexts/ListCrudContext.d.ts +50 -0
  89. package/dist/contexts/ListCrudContext.d.ts.map +1 -0
  90. package/dist/contexts/ListCrudContext.js +253 -0
  91. package/dist/contexts/SnackbarContext.d.ts +26 -0
  92. package/dist/contexts/SnackbarContext.d.ts.map +1 -0
  93. package/dist/contexts/SnackbarContext.js +34 -0
  94. package/dist/contexts/index.d.ts +6 -0
  95. package/dist/contexts/index.d.ts.map +1 -1
  96. package/dist/contexts/index.js +6 -0
  97. package/dist/contexts/presets.js +6 -6
  98. package/dist/docs/AccordionDocs.d.ts +4 -0
  99. package/dist/docs/AccordionDocs.d.ts.map +1 -0
  100. package/dist/docs/AccordionDocs.js +21 -0
  101. package/dist/docs/AuthDocs.tsx/AuthDocsContent.js +3 -5
  102. package/dist/docs/AutocompleteInputDocs.js +1 -1
  103. package/dist/docs/AvatarDocs.d.ts +4 -0
  104. package/dist/docs/AvatarDocs.d.ts.map +1 -0
  105. package/dist/docs/AvatarDocs.js +7 -0
  106. package/dist/docs/BadgeDocs.d.ts.map +1 -1
  107. package/dist/docs/BadgeDocs.js +4 -2
  108. package/dist/docs/ButtonDocs.d.ts.map +1 -1
  109. package/dist/docs/ButtonDocs.js +1 -1
  110. package/dist/docs/CardDocs.d.ts.map +1 -1
  111. package/dist/docs/CardDocs.js +17 -8
  112. package/dist/docs/CheckboxDocs.d.ts +4 -0
  113. package/dist/docs/CheckboxDocs.d.ts.map +1 -0
  114. package/dist/docs/CheckboxDocs.js +7 -0
  115. package/dist/docs/DataTableDocs.d.ts.map +1 -1
  116. package/dist/docs/DataTableDocs.js +9 -5
  117. package/dist/docs/DateInputDocs.d.ts +1 -0
  118. package/dist/docs/DateInputDocs.d.ts.map +1 -1
  119. package/dist/docs/DateInputDocs.js +7 -9
  120. package/dist/docs/DatePickerDocs.d.ts +1 -0
  121. package/dist/docs/DatePickerDocs.d.ts.map +1 -1
  122. package/dist/docs/DatePickerDocs.js +6 -8
  123. package/dist/docs/DialogDocs.js +1 -1
  124. package/dist/docs/DocAdmin.d.ts +4 -0
  125. package/dist/docs/DocAdmin.d.ts.map +1 -0
  126. package/dist/docs/DocAdmin.js +68 -0
  127. package/dist/docs/DocsMenu.d.ts.map +1 -1
  128. package/dist/docs/DocsMenu.js +3 -3
  129. package/dist/docs/DocsRouter.d.ts.map +1 -1
  130. package/dist/docs/DocsRouter.js +13 -1
  131. package/dist/docs/DropdownMenuDocs.js +1 -1
  132. package/dist/docs/ExampleFormDocs.d.ts +4 -0
  133. package/dist/docs/ExampleFormDocs.d.ts.map +1 -0
  134. package/dist/docs/ExampleFormDocs.js +148 -0
  135. package/dist/docs/FilterDocs.d.ts +4 -0
  136. package/dist/docs/FilterDocs.d.ts.map +1 -0
  137. package/dist/docs/FilterDocs.js +112 -0
  138. package/dist/docs/InputDocs.d.ts.map +1 -1
  139. package/dist/docs/InputDocs.js +11 -1
  140. package/dist/docs/LinkButtonDocs.d.ts +4 -0
  141. package/dist/docs/LinkButtonDocs.d.ts.map +1 -0
  142. package/dist/docs/LinkButtonDocs.js +7 -0
  143. package/dist/docs/ListCrudDocs.tsx/ListCrudDocs.d.ts +2 -0
  144. package/dist/docs/ListCrudDocs.tsx/ListCrudDocs.d.ts.map +1 -0
  145. package/dist/docs/ListCrudDocs.tsx/ListCrudDocs.js +29 -0
  146. package/dist/docs/ListCrudDocs.tsx/ListCrudDocsContentEmpresas.d.ts +2 -0
  147. package/dist/docs/ListCrudDocs.tsx/ListCrudDocsContentEmpresas.d.ts.map +1 -0
  148. package/dist/docs/ListCrudDocs.tsx/ListCrudDocsContentEmpresas.js +7 -0
  149. package/dist/docs/ListCrudDocs.tsx/ListCrudDocsContentPersonas.d.ts +2 -0
  150. package/dist/docs/ListCrudDocs.tsx/ListCrudDocsContentPersonas.d.ts.map +1 -0
  151. package/dist/docs/ListCrudDocs.tsx/ListCrudDocsContentPersonas.js +57 -0
  152. package/dist/docs/ListCrudDocs.tsx/ListCrudDocsEditDialog.d.ts +9 -0
  153. package/dist/docs/ListCrudDocs.tsx/ListCrudDocsEditDialog.d.ts.map +1 -0
  154. package/dist/docs/ListCrudDocs.tsx/ListCrudDocsEditDialog.js +30 -0
  155. package/dist/docs/PaginationDocs.js +6 -6
  156. package/dist/docs/RadioButtonGroupDocs.d.ts +4 -0
  157. package/dist/docs/RadioButtonGroupDocs.d.ts.map +1 -0
  158. package/dist/docs/RadioButtonGroupDocs.js +46 -0
  159. package/dist/docs/RoadMapDocs.d.ts +4 -0
  160. package/dist/docs/RoadMapDocs.d.ts.map +1 -0
  161. package/dist/docs/RoadMapDocs.js +171 -0
  162. package/dist/docs/SearchSelectInputDocs.d.ts +4 -0
  163. package/dist/docs/SearchSelectInputDocs.d.ts.map +1 -0
  164. package/dist/docs/SearchSelectInputDocs.js +168 -0
  165. package/dist/docs/SnackbarDocs.d.ts +4 -0
  166. package/dist/docs/SnackbarDocs.d.ts.map +1 -0
  167. package/dist/docs/SnackbarDocs.js +50 -0
  168. package/dist/docs/TabsGroupDocs.d.ts.map +1 -1
  169. package/dist/docs/TabsGroupDocs.js +12 -1
  170. package/dist/docs/docMockServices/empresaService.d.ts +38 -0
  171. package/dist/docs/docMockServices/empresaService.d.ts.map +1 -0
  172. package/dist/docs/docMockServices/empresaService.js +117 -0
  173. package/dist/docs/docMockServices/index.d.ts +9 -0
  174. package/dist/docs/docMockServices/index.d.ts.map +1 -0
  175. package/dist/docs/docMockServices/index.js +8 -0
  176. package/dist/docs/docMockServices/initialData.d.ts +6 -0
  177. package/dist/docs/docMockServices/initialData.d.ts.map +1 -0
  178. package/dist/docs/docMockServices/initialData.js +132 -0
  179. package/dist/docs/docMockServices/interfaces.d.ts +26 -0
  180. package/dist/docs/docMockServices/interfaces.d.ts.map +1 -0
  181. package/dist/docs/docMockServices/interfaces.js +1 -0
  182. package/dist/docs/docMockServices/personaEmpresaService.d.ts +43 -0
  183. package/dist/docs/docMockServices/personaEmpresaService.d.ts.map +1 -0
  184. package/dist/docs/docMockServices/personaEmpresaService.js +113 -0
  185. package/dist/docs/docMockServices/personaService.d.ts +39 -0
  186. package/dist/docs/docMockServices/personaService.d.ts.map +1 -0
  187. package/dist/docs/docMockServices/personaService.js +181 -0
  188. package/dist/hooks/index.d.ts +2 -0
  189. package/dist/hooks/index.d.ts.map +1 -1
  190. package/dist/hooks/index.js +1 -0
  191. package/dist/hooks/useAsyncRequest.d.ts +17 -0
  192. package/dist/hooks/useAsyncRequest.d.ts.map +1 -0
  193. package/dist/hooks/useAsyncRequest.js +70 -0
  194. package/dist/index.css +1 -1
  195. package/dist/index.d.ts +23 -1
  196. package/dist/index.d.ts.map +1 -1
  197. package/dist/index.js +11 -0
  198. package/dist/index.js.map +1 -1
  199. package/dist/templates/forms/ContactForm.js +2 -2
  200. package/dist/templates/forms/LoginForm.js +1 -1
  201. package/dist/templates/forms/RegistrationForm.js +1 -1
  202. package/dist/templates/layouts/SidebarLayout.d.ts.map +1 -1
  203. package/dist/templates/layouts/SidebarLayout.js +3 -2
  204. package/dist/templates/patterns/FormPattern.d.ts.map +1 -1
  205. package/dist/templates/patterns/FormPattern.js +4 -3
  206. package/package.json +5 -2
@@ -0,0 +1,70 @@
1
+ import React from "react";
2
+ import { type InputProps } from "./Input";
3
+ import type { PaginationInterface } from "./Pagination";
4
+ export interface SearchSelectOption {
5
+ label: string;
6
+ value?: string;
7
+ description?: string | number;
8
+ icon?: string;
9
+ }
10
+ export interface SearchSelectInputProps<T = SearchSelectOption, K = string> extends Omit<InputProps, "onChange" | "value" | "ref"> {
11
+ value?: T | K | string;
12
+ /**
13
+ * Callback cuando cambia el valor del input.
14
+ * Recibe la opción completa (T) si no hay getOptionValue, o el valor extraído (K) si hay getOptionValue.
15
+ * También es compatible con react-hook-form: acepta el onChange estándar de HTML.
16
+ */
17
+ onChange?: ((value: T | K) => void) | React.ChangeEventHandler<HTMLInputElement>;
18
+ /**
19
+ * Función que realiza la búsqueda y devuelve un Promise con los resultados
20
+ */
21
+ onSearchPromiseFn: (text: string) => Promise<Array<T> | PaginationInterface<T>>;
22
+ /**
23
+ * Función que busca un elemento individual usando su valor (K).
24
+ * Se usa cuando hay un valor por defecto que no está presente en las opciones cargadas.
25
+ * Recibe el valor (K) y devuelve una Promise con el objeto completo (T) o undefined si no se encuentra.
26
+ */
27
+ onSingleSearchPromiseFn: (value: K) => Promise<T | undefined>;
28
+ /**
29
+ * Callback al seleccionar una opción. Devuelve el item completo (T) y el valor mapeado (K)
30
+ */
31
+ onSelectOption?: (option: T, value: K) => void;
32
+ /**
33
+ * Título del dialog de selección. Por defecto "Seleccione una opción"
34
+ */
35
+ dialogTitle?: string;
36
+ /**
37
+ * Posición del botón de búsqueda. Por defecto "right"
38
+ */
39
+ icon?: string;
40
+ iconPosition?: "left" | "right";
41
+ /**
42
+ * Texto a mostrar cuando no hay resultados
43
+ */
44
+ noResultsText?: string;
45
+ /**
46
+ * Obtiene el label que se muestra para cada opción. Por defecto usa la propiedad "label".
47
+ */
48
+ getOptionLabel?: (item: T) => string;
49
+ /**
50
+ * Obtiene el valor que se devuelve al seleccionar una opción. Por defecto usa la propiedad "value".
51
+ */
52
+ getOptionValue?: (item: T) => K;
53
+ /**
54
+ * Obtiene la descripción opcional para cada opción. Por defecto usa la propiedad "description".
55
+ */
56
+ getOptionDescription?: (item: T) => string | number | undefined;
57
+ /**
58
+ * Renderizado personalizado de cada opción. Si se define, se ignora el render por defecto.
59
+ */
60
+ renderOption?: (item: T) => React.ReactNode;
61
+ /**
62
+ * Si es true, el input será de solo lectura. No se podrá modificar ni abrir el diálogo de selección.
63
+ * Por defecto es false.
64
+ */
65
+ readOnly?: boolean;
66
+ }
67
+ export declare const SearchSelectInput: <T = SearchSelectOption, K = string>(props: SearchSelectInputProps<T, K> & {
68
+ ref?: React.ForwardedRef<HTMLInputElement>;
69
+ }) => React.ReactElement;
70
+ //# sourceMappingURL=SearchSelectInput.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SearchSelectInput.d.ts","sourceRoot":"","sources":["../../../src/components/form-controls/SearchSelectInput.tsx"],"names":[],"mappings":"AAAA,OAAO,KAMN,MAAM,OAAO,CAAC;AAEf,OAAO,EAAS,KAAK,UAAU,EAAE,MAAM,SAAS,CAAC;AACjD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AAKxD,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAC9B,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AACD,MAAM,WAAW,sBAAsB,CAAC,CAAC,GAAG,kBAAkB,EAAE,CAAC,GAAG,MAAM,CACxE,SAAQ,IAAI,CAAC,UAAU,EAAE,UAAU,GAAG,OAAO,GAAG,KAAK,CAAC;IACtD,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC;IACvB;;;;OAIG;IACH,QAAQ,CAAC,EACL,CAAC,CAAC,KAAK,EAAE,CAAC,GAAG,CAAC,KAAK,IAAI,CAAC,GACxB,KAAK,CAAC,kBAAkB,CAAC,gBAAgB,CAAC,CAAC;IAC/C;;OAEG;IACH,iBAAiB,EAAE,CACjB,IAAI,EAAE,MAAM,KACT,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,mBAAmB,CAAC,CAAC,CAAC,CAAC,CAAC;IAChD;;;;OAIG;IACH,uBAAuB,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,OAAO,CAAC,CAAC,GAAG,SAAS,CAAC,CAAC;IAC9D;;OAEG;IACH,cAAc,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,KAAK,IAAI,CAAC;IAC/C;;OAEG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;OAEG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,YAAY,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IAChC;;OAEG;IACH,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;AAwfD,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"}
@@ -0,0 +1,336 @@
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", children: _jsx("ul", { className: "space-y-1 max-h-96 overflow-y-auto", 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, dialogBody: getDialogBody(), dialogActions: _jsx(Button, { variant: "outline", onClick: () => setIsDialogOpen(false), children: "Cerrar" }), onClose: () => setIsDialogOpen(false) }))] }));
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,13 +1,21 @@
1
1
  export { Button } from "./Button";
2
+ export { LinkButton } from "./LinkButton";
2
3
  export { Input } from "./Input";
3
4
  export { AutocompleteInput } from "./AutocompleteInput";
5
+ export { SearchSelectInput } from "./SearchSelectInput-OLD";
4
6
  export { DatePicker } from "./DatePicker";
5
7
  export { DateInput } from "./DateInput";
6
8
  export { Pagination } from "./Pagination";
9
+ export { Checkbox } from "./Checkbox";
10
+ export { RadioButtonGroup } from "./RadioButtonGroup";
7
11
  export type { ButtonProps } from "./Button";
12
+ export type { LinkButtonProps } from "./LinkButton";
8
13
  export type { InputProps } from "./Input";
9
14
  export type { AutocompleteInputProps, AutocompleteOption, } from "./AutocompleteInput";
15
+ export type { SearchSelectInputProps, SearchSelectOption, } from "./SearchSelectInput-OLD";
10
16
  export type { DatePickerProps } from "./DatePicker";
11
17
  export type { DateInputProps, DateInputFormat } from "./DateInput";
12
- export type { PaginationProps, PaginationInterface, } from "./Pagination";
18
+ export type { PaginationProps, PaginationInterface } from "./Pagination";
19
+ export type { CheckboxProps } from "./Checkbox";
20
+ export type { RadioButtonGroupProps, RadioOption } from "./RadioButtonGroup";
13
21
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/form-controls/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAClC,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAChC,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,YAAY,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAC5C,YAAY,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAC1C,YAAY,EACV,sBAAsB,EACtB,kBAAkB,GACnB,MAAM,qBAAqB,CAAC;AAC7B,YAAY,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AACpD,YAAY,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AACnE,YAAY,EACV,eAAe,EACf,mBAAmB,GACpB,MAAM,cAAc,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/form-controls/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAClC,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAChC,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,YAAY,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAC5C,YAAY,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AACpD,YAAY,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAC1C,YAAY,EACV,sBAAsB,EACtB,kBAAkB,GACnB,MAAM,qBAAqB,CAAC;AAC7B,YAAY,EACV,sBAAsB,EACtB,kBAAkB,GACnB,MAAM,yBAAyB,CAAC;AACjC,YAAY,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AACpD,YAAY,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AACnE,YAAY,EAAE,eAAe,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AACzE,YAAY,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAChD,YAAY,EAAE,qBAAqB,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC"}
@@ -1,6 +1,10 @@
1
1
  export { Button } from "./Button";
2
+ export { LinkButton } from "./LinkButton";
2
3
  export { Input } from "./Input";
3
4
  export { AutocompleteInput } from "./AutocompleteInput";
5
+ export { SearchSelectInput } from "./SearchSelectInput-OLD";
4
6
  export { DatePicker } from "./DatePicker";
5
7
  export { DateInput } from "./DateInput";
6
8
  export { Pagination } from "./Pagination";
9
+ export { Checkbox } from "./Checkbox";
10
+ export { RadioButtonGroup } from "./RadioButtonGroup";
@@ -0,0 +1,13 @@
1
+ import React from "react";
2
+ export interface AccordionProps {
3
+ title: string | React.ReactNode;
4
+ children: React.ReactNode;
5
+ icon?: string;
6
+ rightNode?: React.ReactNode;
7
+ defaultOpen?: boolean;
8
+ className?: string;
9
+ variant?: "default" | "elevated" | "outlined";
10
+ onToggle?: (isOpen: boolean) => void;
11
+ }
12
+ export declare const Accordion: React.FC<AccordionProps>;
13
+ //# sourceMappingURL=Accordion.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Accordion.d.ts","sourceRoot":"","sources":["../../../src/components/layout/Accordion.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAsC,MAAM,OAAO,CAAC;AAG3D,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,MAAM,GAAG,KAAK,CAAC,SAAS,CAAC;IAChC,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC5B,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,SAAS,GAAG,UAAU,GAAG,UAAU,CAAC;IAC9C,QAAQ,CAAC,EAAE,CAAC,MAAM,EAAE,OAAO,KAAK,IAAI,CAAC;CACtC;AAED,eAAO,MAAM,SAAS,EAAE,KAAK,CAAC,EAAE,CAAC,cAAc,CAgI9C,CAAC"}
@@ -0,0 +1,67 @@
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 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,7 +1,8 @@
1
1
  import React from "react";
2
+ import type { NavbarInterface, LeftDrawerInterface } from "../../contexts/AppLayoutContext";
2
3
  export interface AppLayoutProps {
3
- navBarDrawer?: React.ReactNode;
4
- leftDrawer?: React.ReactNode;
4
+ navbar?: NavbarInterface;
5
+ leftDrawer?: LeftDrawerInterface;
5
6
  children: React.ReactNode;
6
7
  className?: string;
7
8
  }
@@ -1 +1 @@
1
- {"version":3,"file":"AppLayout.d.ts","sourceRoot":"","sources":["../../../src/components/layout/AppLayout.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA2B,MAAM,OAAO,CAAC;AAKhD,MAAM,WAAW,cAAc;IAC7B,YAAY,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC/B,UAAU,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC7B,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,eAAO,MAAM,SAAS,EAAE,KAAK,CAAC,EAAE,CAAC,cAAc,CAyN9C,CAAC"}
1
+ {"version":3,"file":"AppLayout.d.ts","sourceRoot":"","sources":["../../../src/components/layout/AppLayout.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA2B,MAAM,OAAO,CAAC;AAIhD,OAAO,KAAK,EACV,eAAe,EACf,mBAAmB,EACpB,MAAM,iCAAiC,CAAC;AAEzC,MAAM,WAAW,cAAc;IAC7B,MAAM,CAAC,EAAE,eAAe,CAAC;IACzB,UAAU,CAAC,EAAE,mBAAmB,CAAC;IACjC,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,eAAO,MAAM,SAAS,EAAE,KAAK,CAAC,EAAE,CAAC,cAAc,CAmd9C,CAAC"}