flysoft-react-ui 0.4.0 → 0.5.2

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 (178) hide show
  1. package/dist/App.d.ts.map +1 -1
  2. package/dist/App.js +20 -4
  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 +410 -31
  6. package/dist/components/form-controls/Button.js +1 -1
  7. package/dist/components/form-controls/Checkbox.d.ts +14 -0
  8. package/dist/components/form-controls/Checkbox.d.ts.map +1 -0
  9. package/dist/components/form-controls/Checkbox.js +77 -0
  10. package/dist/components/form-controls/DateInput.d.ts +20 -4
  11. package/dist/components/form-controls/DateInput.d.ts.map +1 -1
  12. package/dist/components/form-controls/DateInput.js +425 -70
  13. package/dist/components/form-controls/DatePicker.d.ts +4 -3
  14. package/dist/components/form-controls/DatePicker.d.ts.map +1 -1
  15. package/dist/components/form-controls/DatePicker.js +26 -30
  16. package/dist/components/form-controls/Input.d.ts +10 -1
  17. package/dist/components/form-controls/Input.d.ts.map +1 -1
  18. package/dist/components/form-controls/Input.js +16 -10
  19. package/dist/components/form-controls/Pagination.d.ts +1 -0
  20. package/dist/components/form-controls/Pagination.d.ts.map +1 -1
  21. package/dist/components/form-controls/Pagination.js +3 -40
  22. package/dist/components/form-controls/RadioButtonGroup.d.ts +62 -0
  23. package/dist/components/form-controls/RadioButtonGroup.d.ts.map +1 -0
  24. package/dist/components/form-controls/RadioButtonGroup.js +220 -0
  25. package/dist/components/form-controls/SearchSelectInput-OLD.d.ts +68 -0
  26. package/dist/components/form-controls/SearchSelectInput-OLD.d.ts.map +1 -0
  27. package/dist/components/form-controls/SearchSelectInput-OLD.js +962 -0
  28. package/dist/components/form-controls/SearchSelectInput.d.ts +70 -0
  29. package/dist/components/form-controls/SearchSelectInput.d.ts.map +1 -0
  30. package/dist/components/form-controls/SearchSelectInput.js +335 -0
  31. package/dist/components/form-controls/index.d.ts +7 -1
  32. package/dist/components/form-controls/index.d.ts.map +1 -1
  33. package/dist/components/form-controls/index.js +3 -0
  34. package/dist/components/layout/AppLayout.d.ts +3 -2
  35. package/dist/components/layout/AppLayout.d.ts.map +1 -1
  36. package/dist/components/layout/AppLayout.js +104 -31
  37. package/dist/components/layout/Card.d.ts +4 -1
  38. package/dist/components/layout/Card.d.ts.map +1 -1
  39. package/dist/components/layout/Card.js +30 -1
  40. package/dist/components/layout/Collection.js +1 -1
  41. package/dist/components/layout/DataTable.d.ts +29 -0
  42. package/dist/components/layout/DataTable.d.ts.map +1 -0
  43. package/dist/components/layout/DataTable.js +165 -0
  44. package/dist/components/layout/index.d.ts +2 -0
  45. package/dist/components/layout/index.d.ts.map +1 -1
  46. package/dist/components/layout/index.js +1 -0
  47. package/dist/components/utils/Avatar.d.ts +49 -0
  48. package/dist/components/utils/Avatar.d.ts.map +1 -0
  49. package/dist/components/utils/Avatar.js +93 -0
  50. package/dist/components/utils/Badge.d.ts +3 -0
  51. package/dist/components/utils/Badge.d.ts.map +1 -1
  52. package/dist/components/utils/Badge.js +130 -26
  53. package/dist/components/utils/Dialog.d.ts.map +1 -1
  54. package/dist/components/utils/Dialog.js +5 -1
  55. package/dist/components/utils/DropdownMenu.d.ts +25 -0
  56. package/dist/components/utils/DropdownMenu.d.ts.map +1 -0
  57. package/dist/components/utils/DropdownMenu.js +145 -0
  58. package/dist/components/utils/Filter.d.ts +57 -0
  59. package/dist/components/utils/Filter.d.ts.map +1 -0
  60. package/dist/components/utils/Filter.js +580 -0
  61. package/dist/components/utils/FiltersDialog.d.ts +21 -0
  62. package/dist/components/utils/FiltersDialog.d.ts.map +1 -0
  63. package/dist/components/utils/FiltersDialog.js +104 -0
  64. package/dist/components/utils/Loader.js +1 -1
  65. package/dist/components/utils/RoadMap.d.ts +59 -0
  66. package/dist/components/utils/RoadMap.d.ts.map +1 -0
  67. package/dist/components/utils/RoadMap.js +138 -0
  68. package/dist/components/utils/Snackbar.d.ts +13 -0
  69. package/dist/components/utils/Snackbar.d.ts.map +1 -0
  70. package/dist/components/utils/Snackbar.js +121 -0
  71. package/dist/components/utils/SnackbarContainer.d.ts +7 -0
  72. package/dist/components/utils/SnackbarContainer.d.ts.map +1 -0
  73. package/dist/components/utils/SnackbarContainer.js +25 -0
  74. package/dist/components/utils/index.d.ts +12 -0
  75. package/dist/components/utils/index.d.ts.map +1 -1
  76. package/dist/components/utils/index.js +6 -0
  77. package/dist/contexts/AppLayoutContext.d.ts +40 -0
  78. package/dist/contexts/AppLayoutContext.d.ts.map +1 -0
  79. package/dist/contexts/AppLayoutContext.js +98 -0
  80. package/dist/contexts/ListCrudContext.d.ts +29 -0
  81. package/dist/contexts/ListCrudContext.d.ts.map +1 -0
  82. package/dist/contexts/ListCrudContext.js +209 -0
  83. package/dist/contexts/SnackbarContext.d.ts +26 -0
  84. package/dist/contexts/SnackbarContext.d.ts.map +1 -0
  85. package/dist/contexts/SnackbarContext.js +34 -0
  86. package/dist/contexts/index.d.ts +6 -0
  87. package/dist/contexts/index.d.ts.map +1 -1
  88. package/dist/contexts/index.js +6 -0
  89. package/dist/contexts/presets.js +6 -6
  90. package/dist/docs/AuthDocs.tsx/AuthDocsContent.js +3 -1
  91. package/dist/docs/AvatarDocs.d.ts +4 -0
  92. package/dist/docs/AvatarDocs.d.ts.map +1 -0
  93. package/dist/docs/AvatarDocs.js +7 -0
  94. package/dist/docs/BadgeDocs.d.ts.map +1 -1
  95. package/dist/docs/BadgeDocs.js +4 -2
  96. package/dist/docs/CardDocs.d.ts.map +1 -1
  97. package/dist/docs/CardDocs.js +7 -1
  98. package/dist/docs/CheckboxDocs.d.ts +4 -0
  99. package/dist/docs/CheckboxDocs.d.ts.map +1 -0
  100. package/dist/docs/CheckboxDocs.js +7 -0
  101. package/dist/docs/DataTableDocs.d.ts +4 -0
  102. package/dist/docs/DataTableDocs.d.ts.map +1 -0
  103. package/dist/docs/DataTableDocs.js +244 -0
  104. package/dist/docs/DateInputDocs.d.ts +1 -0
  105. package/dist/docs/DateInputDocs.d.ts.map +1 -1
  106. package/dist/docs/DateInputDocs.js +7 -9
  107. package/dist/docs/DatePickerDocs.d.ts +1 -0
  108. package/dist/docs/DatePickerDocs.d.ts.map +1 -1
  109. package/dist/docs/DatePickerDocs.js +6 -8
  110. package/dist/docs/DocAdmin.d.ts +4 -0
  111. package/dist/docs/DocAdmin.d.ts.map +1 -0
  112. package/dist/docs/DocAdmin.js +68 -0
  113. package/dist/docs/DocsMenu.d.ts.map +1 -1
  114. package/dist/docs/DocsMenu.js +1 -1
  115. package/dist/docs/DocsRouter.d.ts.map +1 -1
  116. package/dist/docs/DocsRouter.js +13 -1
  117. package/dist/docs/DropdownMenuDocs.d.ts +4 -0
  118. package/dist/docs/DropdownMenuDocs.d.ts.map +1 -0
  119. package/dist/docs/DropdownMenuDocs.js +66 -0
  120. package/dist/docs/ExampleFormDocs.d.ts +4 -0
  121. package/dist/docs/ExampleFormDocs.d.ts.map +1 -0
  122. package/dist/docs/ExampleFormDocs.js +148 -0
  123. package/dist/docs/FilterDocs.d.ts +4 -0
  124. package/dist/docs/FilterDocs.d.ts.map +1 -0
  125. package/dist/docs/FilterDocs.js +112 -0
  126. package/dist/docs/InputDocs.d.ts.map +1 -1
  127. package/dist/docs/InputDocs.js +11 -1
  128. package/dist/docs/ListCrudDocs.tsx/ListCrudDocs.d.ts +11 -0
  129. package/dist/docs/ListCrudDocs.tsx/ListCrudDocs.d.ts.map +1 -0
  130. package/dist/docs/ListCrudDocs.tsx/ListCrudDocs.js +25 -0
  131. package/dist/docs/ListCrudDocs.tsx/ListCrudDocsContentPersonas.d.ts +2 -0
  132. package/dist/docs/ListCrudDocs.tsx/ListCrudDocsContentPersonas.d.ts.map +1 -0
  133. package/dist/docs/ListCrudDocs.tsx/ListCrudDocsContentPersonas.js +51 -0
  134. package/dist/docs/PaginationDocs.js +6 -6
  135. package/dist/docs/RadioButtonGroupDocs.d.ts +4 -0
  136. package/dist/docs/RadioButtonGroupDocs.d.ts.map +1 -0
  137. package/dist/docs/RadioButtonGroupDocs.js +46 -0
  138. package/dist/docs/RoadMapDocs.d.ts +4 -0
  139. package/dist/docs/RoadMapDocs.d.ts.map +1 -0
  140. package/dist/docs/RoadMapDocs.js +171 -0
  141. package/dist/docs/SearchSelectInputDocs.d.ts +4 -0
  142. package/dist/docs/SearchSelectInputDocs.d.ts.map +1 -0
  143. package/dist/docs/SearchSelectInputDocs.js +168 -0
  144. package/dist/docs/SnackbarDocs.d.ts +4 -0
  145. package/dist/docs/SnackbarDocs.d.ts.map +1 -0
  146. package/dist/docs/SnackbarDocs.js +50 -0
  147. package/dist/docs/TabsGroupDocs.d.ts.map +1 -1
  148. package/dist/docs/TabsGroupDocs.js +12 -1
  149. package/dist/docs/docMockServices/empresaService.d.ts +38 -0
  150. package/dist/docs/docMockServices/empresaService.d.ts.map +1 -0
  151. package/dist/docs/docMockServices/empresaService.js +116 -0
  152. package/dist/docs/docMockServices/index.d.ts +9 -0
  153. package/dist/docs/docMockServices/index.d.ts.map +1 -0
  154. package/dist/docs/docMockServices/index.js +8 -0
  155. package/dist/docs/docMockServices/initialData.d.ts +6 -0
  156. package/dist/docs/docMockServices/initialData.d.ts.map +1 -0
  157. package/dist/docs/docMockServices/initialData.js +132 -0
  158. package/dist/docs/docMockServices/interfaces.d.ts +26 -0
  159. package/dist/docs/docMockServices/interfaces.d.ts.map +1 -0
  160. package/dist/docs/docMockServices/interfaces.js +1 -0
  161. package/dist/docs/docMockServices/personaEmpresaService.d.ts +43 -0
  162. package/dist/docs/docMockServices/personaEmpresaService.d.ts.map +1 -0
  163. package/dist/docs/docMockServices/personaEmpresaService.js +113 -0
  164. package/dist/docs/docMockServices/personaService.d.ts +39 -0
  165. package/dist/docs/docMockServices/personaService.d.ts.map +1 -0
  166. package/dist/docs/docMockServices/personaService.js +180 -0
  167. package/dist/hooks/index.d.ts +2 -0
  168. package/dist/hooks/index.d.ts.map +1 -1
  169. package/dist/hooks/index.js +1 -0
  170. package/dist/hooks/useAsyncRequest.d.ts +17 -0
  171. package/dist/hooks/useAsyncRequest.d.ts.map +1 -0
  172. package/dist/hooks/useAsyncRequest.js +70 -0
  173. package/dist/index.css +1 -1
  174. package/dist/index.d.ts +22 -0
  175. package/dist/index.d.ts.map +1 -1
  176. package/dist/index.js +11 -0
  177. package/dist/index.js.map +1 -1
  178. 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;AAIxD,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;AAsfD,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,335 @@
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
+ 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) {
8
+ const [inputText, setInputText] = useState("");
9
+ const [dialogInputText, setDialogInputText] = useState("");
10
+ const [isDialogOpen, setIsDialogOpen] = useState(false);
11
+ const [options, setOptions] = useState([]);
12
+ const [isLoading, setIsLoading] = useState(false);
13
+ const [hasSearched, setHasSearched] = useState(false);
14
+ const inputRef = useRef(null);
15
+ const dialogInputRef = useRef(null);
16
+ const justClearedRef = useRef(false);
17
+ // Detectar modo register
18
+ const isRegisterMode = useMemo(() => {
19
+ return "name" in inputProps && inputProps.name !== undefined;
20
+ }, [inputProps]);
21
+ const fieldName = isRegisterMode && "name" in inputProps
22
+ ? inputProps.name
23
+ : undefined;
24
+ // Obtener setValue del contexto del formulario
25
+ // Para usar con register, el formulario debe estar dentro de FormProvider
26
+ // useFormContext debe llamarse incondicionalmente (requisito de React Hooks)
27
+ // Si no hay FormProvider y se usa en modo register, useFormContext lanzará un error
28
+ // Para usar sin FormProvider, usar Controller en lugar de register
29
+ const formContext = useFormContext();
30
+ const setValue = formContext?.setValue;
31
+ // Combinar refs
32
+ const combinedRef = useCallback((node) => {
33
+ inputRef.current = node;
34
+ if (typeof ref === "function") {
35
+ ref(node);
36
+ }
37
+ else if (ref) {
38
+ ref.current = node;
39
+ }
40
+ }, [ref]);
41
+ const valueGetter = useCallback((item) => {
42
+ if (getOptionValue)
43
+ return getOptionValue(item);
44
+ return item["value"];
45
+ }, [getOptionValue]);
46
+ const labelGetter = useCallback((item) => {
47
+ if (getOptionLabel)
48
+ return getOptionLabel(item);
49
+ return item["label"];
50
+ }, [getOptionLabel]);
51
+ const descriptionGetter = useCallback((item) => {
52
+ if (getOptionDescription)
53
+ return getOptionDescription(item);
54
+ return item["description"];
55
+ }, [getOptionDescription]);
56
+ const handleSearch = async (text) => {
57
+ setIsLoading(true);
58
+ setHasSearched(true);
59
+ const options = await onSearchPromiseFn(text);
60
+ if (options instanceof Array) {
61
+ setOptions(options);
62
+ }
63
+ else {
64
+ setOptions(options.list);
65
+ }
66
+ setIsLoading(false);
67
+ };
68
+ const handleSelect = (option) => {
69
+ const selectedValue = valueGetter(option);
70
+ setIsDialogOpen(false);
71
+ // En modo register, setear el valor usando setValue o actualizando el input nativo
72
+ if (isRegisterMode) {
73
+ if (setValue && fieldName) {
74
+ setValue(fieldName, selectedValue, {
75
+ shouldValidate: true,
76
+ shouldDirty: true,
77
+ });
78
+ }
79
+ else if (inputRef.current) {
80
+ const nativeInput = inputRef.current;
81
+ const nativeInputValueSetter = Object.getOwnPropertyDescriptor(window.HTMLInputElement.prototype, "value")?.set;
82
+ if (nativeInputValueSetter) {
83
+ nativeInputValueSetter.call(nativeInput, String(selectedValue ?? ""));
84
+ }
85
+ else {
86
+ nativeInput.value = String(selectedValue ?? "");
87
+ }
88
+ if (onChange) {
89
+ const changeEvent = {
90
+ target: nativeInput,
91
+ currentTarget: nativeInput,
92
+ };
93
+ onChange(changeEvent);
94
+ }
95
+ const inputEvent = new Event("input", {
96
+ bubbles: true,
97
+ cancelable: true,
98
+ });
99
+ nativeInput.dispatchEvent(inputEvent);
100
+ const changeEventNative = new Event("change", {
101
+ bubbles: true,
102
+ cancelable: true,
103
+ });
104
+ nativeInput.dispatchEvent(changeEventNative);
105
+ }
106
+ }
107
+ else {
108
+ onChange?.(selectedValue);
109
+ }
110
+ onSelectOption?.(option, selectedValue);
111
+ setInputText(labelGetter(option));
112
+ setDialogInputText("");
113
+ setOptions([]);
114
+ setHasSearched(false);
115
+ };
116
+ // Función para sincronizar inputText con un valor
117
+ const syncInputText = useCallback((currentValue) => {
118
+ if (currentValue === undefined ||
119
+ currentValue === null ||
120
+ currentValue === "") {
121
+ setInputText("");
122
+ return;
123
+ }
124
+ // Si currentValue es un objeto (T) y tenemos getOptionLabel, usar directamente
125
+ if (typeof currentValue === "object" &&
126
+ getOptionLabel &&
127
+ !getOptionValue) {
128
+ try {
129
+ const label = getOptionLabel(currentValue);
130
+ setInputText(label);
131
+ return;
132
+ }
133
+ catch {
134
+ // Si falla, continuar con la búsqueda normal
135
+ }
136
+ }
137
+ // Normalizar el value: si es un objeto (T), extraer el valor usando valueGetter
138
+ let valueToSearch = currentValue;
139
+ if (typeof currentValue === "object" && getOptionValue) {
140
+ // Si currentValue es un objeto y tenemos getOptionValue, extraer el valor
141
+ try {
142
+ valueToSearch = getOptionValue(currentValue);
143
+ }
144
+ catch {
145
+ // Si falla, no podemos usar onSingleSearchPromiseFn con un objeto
146
+ // Intentar mostrar el label directamente si está disponible
147
+ if (getOptionLabel) {
148
+ try {
149
+ setInputText(getOptionLabel(currentValue));
150
+ return;
151
+ }
152
+ catch {
153
+ setInputText(String(currentValue));
154
+ return;
155
+ }
156
+ }
157
+ setInputText(String(currentValue));
158
+ return;
159
+ }
160
+ }
161
+ // Buscar en las opciones actuales
162
+ const matchingOption = options.find((opt) => valueGetter(opt) === valueToSearch ||
163
+ valueGetter(opt) === currentValue);
164
+ if (matchingOption) {
165
+ setInputText(labelGetter(matchingOption));
166
+ return;
167
+ }
168
+ // Si no se encuentra en las opciones actuales, usar onSingleSearchPromiseFn
169
+ if (onSingleSearchPromiseFn &&
170
+ valueToSearch !== undefined &&
171
+ valueToSearch !== null) {
172
+ onSingleSearchPromiseFn(valueToSearch)
173
+ .then((foundOption) => {
174
+ if (foundOption) {
175
+ setInputText(labelGetter(foundOption));
176
+ // Agregar la opción a las opciones disponibles si no está ya
177
+ setOptions((prev) => {
178
+ if (!prev.find((opt) => valueGetter(opt) === valueGetter(foundOption))) {
179
+ return [...prev, foundOption];
180
+ }
181
+ return prev;
182
+ });
183
+ }
184
+ else {
185
+ // Si no se encuentra, mostrar el valor como string
186
+ setInputText(String(valueToSearch));
187
+ }
188
+ })
189
+ .catch((error) => {
190
+ console.error("Error al buscar opción individual:", error);
191
+ setInputText(String(valueToSearch));
192
+ });
193
+ }
194
+ else {
195
+ // Si no hay onSingleSearchPromiseFn, mostrar el valor como string
196
+ setInputText(String(valueToSearch));
197
+ }
198
+ }, [
199
+ options,
200
+ getOptionValue,
201
+ getOptionLabel,
202
+ onSingleSearchPromiseFn,
203
+ valueGetter,
204
+ labelGetter,
205
+ ]);
206
+ // Sincronizar inputText cuando cambia el value (modo controlado)
207
+ useEffect(() => {
208
+ if (!isRegisterMode) {
209
+ syncInputText(value);
210
+ }
211
+ }, [value, isRegisterMode, syncInputText]);
212
+ // Sincronizar inputText cuando cambia el valor del formulario (modo register)
213
+ useEffect(() => {
214
+ if (isRegisterMode && formContext && fieldName) {
215
+ // Sincronizar inicialmente
216
+ const formValue = formContext.watch(fieldName);
217
+ syncInputText(formValue);
218
+ // Suscribirse a cambios del formulario
219
+ const subscription = formContext.watch((_data, { name }) => {
220
+ // Solo sincronizar cuando cambia el campo específico
221
+ if (name === fieldName) {
222
+ const currentFormValue = formContext.watch(fieldName);
223
+ syncInputText(currentFormValue);
224
+ }
225
+ });
226
+ return () => subscription.unsubscribe();
227
+ }
228
+ }, [isRegisterMode, formContext, fieldName, syncInputText]);
229
+ // Hacer blur en el input del dialog cuando se abre
230
+ useEffect(() => {
231
+ if (isDialogOpen) {
232
+ // El Dialog renderiza condicionalmente, así que necesitamos esperar a que el input esté montado
233
+ // Usar requestAnimationFrame doble para asegurar que el DOM esté completamente renderizado
234
+ const timeoutId = setTimeout(() => {
235
+ requestAnimationFrame(() => {
236
+ dialogInputRef.current?.focus();
237
+ });
238
+ }, 50);
239
+ return () => clearTimeout(timeoutId);
240
+ }
241
+ }, [isDialogOpen]);
242
+ const getDialogBody = () => {
243
+ 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) => {
244
+ if (e.key === "Enter") {
245
+ e.preventDefault();
246
+ handleSearch(dialogInputText);
247
+ }
248
+ } }) }), _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) => {
249
+ const label = labelGetter(option);
250
+ const description = descriptionGetter(option);
251
+ const anyOption = option;
252
+ 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: `fa ${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 &&
253
+ description !== null && (_jsx("span", { className: "text-xs text-[var(--color-text-secondary)]", children: description }))] })] })) }, String(valueGetter(option) ?? label ?? index)));
254
+ }) }) })) : (_jsx("div", { className: "px-3 py-8 text-center text-sm text-[var(--color-text-secondary)]", children: noResultsText })) }) })] }));
255
+ };
256
+ // Detectar si hay un valor seleccionado
257
+ const hasValue = inputText !== "" && inputText !== undefined && inputText !== null;
258
+ // Función para limpiar el valor y abrir el dialog
259
+ const handleIconClick = useCallback((event) => {
260
+ if (readOnly)
261
+ return;
262
+ event.preventDefault();
263
+ event.stopPropagation();
264
+ if (hasValue) {
265
+ // Si hay valor, limpiarlo
266
+ // Marcar que acabamos de limpiar para prevenir que onFocus abra el diálogo
267
+ justClearedRef.current = true;
268
+ if (isRegisterMode) {
269
+ if (setValue && fieldName) {
270
+ setValue(fieldName, undefined, {
271
+ shouldValidate: true,
272
+ shouldDirty: true,
273
+ });
274
+ }
275
+ else if (inputRef.current) {
276
+ const nativeInput = inputRef.current;
277
+ const nativeInputValueSetter = Object.getOwnPropertyDescriptor(window.HTMLInputElement.prototype, "value")?.set;
278
+ if (nativeInputValueSetter) {
279
+ nativeInputValueSetter.call(nativeInput, "");
280
+ }
281
+ else {
282
+ nativeInput.value = "";
283
+ }
284
+ if (onChange) {
285
+ const changeEvent = {
286
+ target: nativeInput,
287
+ currentTarget: nativeInput,
288
+ };
289
+ onChange(changeEvent);
290
+ }
291
+ const inputEvent = new Event("input", {
292
+ bubbles: true,
293
+ cancelable: true,
294
+ });
295
+ nativeInput.dispatchEvent(inputEvent);
296
+ const changeEventNative = new Event("change", {
297
+ bubbles: true,
298
+ cancelable: true,
299
+ });
300
+ nativeInput.dispatchEvent(changeEventNative);
301
+ }
302
+ }
303
+ else {
304
+ onChange?.(undefined);
305
+ }
306
+ setInputText("");
307
+ setIsDialogOpen(false);
308
+ // Resetear el flag después de un pequeño delay para permitir que otros eventos se procesen
309
+ setTimeout(() => {
310
+ justClearedRef.current = false;
311
+ }, 100);
312
+ }
313
+ else {
314
+ // Si no hay valor, abrir el dialog
315
+ setIsDialogOpen(true);
316
+ }
317
+ }, [hasValue, isRegisterMode, setValue, fieldName, onChange, readOnly]);
318
+ // Determinar qué ícono mostrar: si hay valor, mostrar "fa-times", sino el ícono original
319
+ // Si está en readOnly, no mostrar ningún ícono
320
+ const displayIcon = readOnly ? undefined : hasValue ? "fa-times" : icon;
321
+ const displayIconPosition = readOnly ? undefined : iconPosition;
322
+ const displayOnIconClick = readOnly ? undefined : handleIconClick;
323
+ return (_jsxs(_Fragment, { children: [_jsx(Input, { ...inputProps, ref: combinedRef, label: label, value: inputText, onChange: (e) => {
324
+ if (readOnly)
325
+ return;
326
+ setInputText(e.target.value);
327
+ }, onFocus: () => {
328
+ if (!readOnly && !justClearedRef.current) {
329
+ setIsDialogOpen(true);
330
+ }
331
+ }, 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) }))] }));
332
+ });
333
+ SearchSelectInputInner.displayName = "SearchSelectInput";
334
+ // Exportar con el cast genérico para permitir uso como <SearchSelectInput<T, K>>
335
+ export const SearchSelectInput = SearchSelectInputInner;
@@ -1,13 +1,19 @@
1
1
  export { Button } from "./Button";
2
2
  export { Input } from "./Input";
3
3
  export { AutocompleteInput } from "./AutocompleteInput";
4
+ export { SearchSelectInput } from "./SearchSelectInput-OLD";
4
5
  export { DatePicker } from "./DatePicker";
5
6
  export { DateInput } from "./DateInput";
6
7
  export { Pagination } from "./Pagination";
8
+ export { Checkbox } from "./Checkbox";
9
+ export { RadioButtonGroup } from "./RadioButtonGroup";
7
10
  export type { ButtonProps } from "./Button";
8
11
  export type { InputProps } from "./Input";
9
12
  export type { AutocompleteInputProps, AutocompleteOption, } from "./AutocompleteInput";
13
+ export type { SearchSelectInputProps, SearchSelectOption, } from "./SearchSelectInput-OLD";
10
14
  export type { DatePickerProps } from "./DatePicker";
11
15
  export type { DateInputProps, DateInputFormat } from "./DateInput";
12
- export type { PaginationProps, PaginationInterface, } from "./Pagination";
16
+ export type { PaginationProps, PaginationInterface } from "./Pagination";
17
+ export type { CheckboxProps } from "./Checkbox";
18
+ export type { RadioButtonGroupProps, RadioOption } from "./RadioButtonGroup";
13
19
  //# 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,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,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,9 @@
1
1
  export { Button } from "./Button";
2
2
  export { Input } from "./Input";
3
3
  export { AutocompleteInput } from "./AutocompleteInput";
4
+ export { SearchSelectInput } from "./SearchSelectInput-OLD";
4
5
  export { DatePicker } from "./DatePicker";
5
6
  export { DateInput } from "./DateInput";
6
7
  export { Pagination } from "./Pagination";
8
+ export { Checkbox } from "./Checkbox";
9
+ export { RadioButtonGroup } from "./RadioButtonGroup";
@@ -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"}