flysoft-react-ui 0.5.3 → 1.0.1
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.
- package/AI_CONTEXT.md +84 -0
- package/dist/components/form-controls/AutocompleteInput.d.ts.map +1 -1
- package/dist/components/form-controls/AutocompleteInput.js +175 -130
- package/dist/components/form-controls/SearchSelectInput-OLD.d.ts.map +1 -1
- package/dist/components/form-controls/SearchSelectInput-OLD.js +2 -2
- package/dist/components/form-controls/SearchSelectInput.d.ts.map +1 -1
- package/dist/components/form-controls/SearchSelectInput.js +1 -1
- package/dist/components/layout/AppLayout.d.ts.map +1 -1
- package/dist/components/layout/AppLayout.js +7 -7
- package/dist/components/layout/Card.d.ts.map +1 -1
- package/dist/components/layout/Card.js +4 -4
- package/dist/components/layout/DataTable.js +1 -1
- package/dist/components/layout/DropdownMenu.d.ts.map +1 -0
- package/dist/components/{utils → layout}/DropdownMenu.js +12 -6
- package/dist/components/layout/DropdownPanel.d.ts +7 -0
- package/dist/components/layout/DropdownPanel.d.ts.map +1 -0
- package/dist/components/layout/DropdownPanel.js +137 -0
- package/dist/components/{utils → layout}/Filter.d.ts +5 -0
- package/dist/components/layout/Filter.d.ts.map +1 -0
- package/dist/components/{utils → layout}/Filter.js +17 -9
- package/dist/components/layout/Menu.d.ts +31 -0
- package/dist/components/layout/Menu.d.ts.map +1 -0
- package/dist/components/layout/Menu.js +21 -0
- package/dist/components/layout/index.d.ts +8 -0
- package/dist/components/layout/index.d.ts.map +1 -1
- package/dist/components/layout/index.js +4 -0
- package/dist/components/utils/Dialog.d.ts +2 -2
- package/dist/components/utils/Dialog.d.ts.map +1 -1
- package/dist/components/utils/Dialog.js +2 -2
- package/dist/components/utils/FiltersDialog.d.ts +1 -1
- package/dist/components/utils/FiltersDialog.d.ts.map +1 -1
- package/dist/components/utils/FiltersDialog.js +2 -2
- package/dist/components/utils/index.d.ts +0 -2
- package/dist/components/utils/index.d.ts.map +1 -1
- package/dist/components/utils/index.js +0 -1
- package/dist/contexts/{ListCrudContext.d.ts → CrudContext.d.ts} +20 -8
- package/dist/contexts/CrudContext.d.ts.map +1 -0
- package/dist/contexts/{ListCrudContext.js → CrudContext.js} +102 -22
- package/dist/contexts/index.d.ts +2 -2
- package/dist/contexts/index.d.ts.map +1 -1
- package/dist/contexts/index.js +2 -2
- package/dist/docs/DialogDocs.d.ts.map +1 -1
- package/dist/docs/DialogDocs.js +1 -1
- package/dist/docs/DocsMenu.d.ts.map +1 -1
- package/dist/docs/DocsMenu.js +1 -1
- package/dist/docs/DocsRouter.d.ts.map +1 -1
- package/dist/docs/DocsRouter.js +3 -1
- package/dist/docs/DropdownPanelDocs.d.ts +4 -0
- package/dist/docs/DropdownPanelDocs.d.ts.map +1 -0
- package/dist/docs/DropdownPanelDocs.js +7 -0
- package/dist/docs/FilterDocs.d.ts.map +1 -1
- package/dist/docs/FilterDocs.js +19 -1
- package/dist/docs/ListCrudDocs.tsx/ListCrudDocs.d.ts.map +1 -1
- package/dist/docs/ListCrudDocs.tsx/ListCrudDocs.js +26 -14
- package/dist/docs/ListCrudDocs.tsx/ListCrudDocsContentEmpresaPersonas.d.ts +2 -0
- package/dist/docs/ListCrudDocs.tsx/ListCrudDocsContentEmpresaPersonas.d.ts.map +1 -0
- package/dist/docs/ListCrudDocs.tsx/ListCrudDocsContentEmpresaPersonas.js +34 -0
- package/dist/docs/ListCrudDocs.tsx/ListCrudDocsContentEmpresaSingle.d.ts +2 -0
- package/dist/docs/ListCrudDocs.tsx/ListCrudDocsContentEmpresaSingle.d.ts.map +1 -0
- package/dist/docs/ListCrudDocs.tsx/ListCrudDocsContentEmpresaSingle.js +66 -0
- package/dist/docs/ListCrudDocs.tsx/ListCrudDocsContentEmpresas.d.ts.map +1 -1
- package/dist/docs/ListCrudDocs.tsx/ListCrudDocsContentEmpresas.js +5 -5
- package/dist/docs/ListCrudDocs.tsx/ListCrudDocsContentEmpresasPersonasEditDialog.d.ts +10 -0
- package/dist/docs/ListCrudDocs.tsx/ListCrudDocsContentEmpresasPersonasEditDialog.d.ts.map +1 -0
- package/dist/docs/ListCrudDocs.tsx/ListCrudDocsContentEmpresasPersonasEditDialog.js +39 -0
- package/dist/docs/ListCrudDocs.tsx/ListCrudDocsContentPersonas.d.ts.map +1 -1
- package/dist/docs/ListCrudDocs.tsx/ListCrudDocsContentPersonas.js +3 -3
- package/dist/docs/ListCrudDocs.tsx/ListCrudDocsEditDialog.d.ts.map +1 -1
- package/dist/docs/ListCrudDocs.tsx/ListCrudDocsEditDialog.js +4 -4
- package/dist/docs/MenuDocs.d.ts +4 -0
- package/dist/docs/MenuDocs.d.ts.map +1 -0
- package/dist/docs/MenuDocs.js +26 -0
- package/dist/docs/docMockServices/empresaService.d.ts +5 -5
- package/dist/docs/docMockServices/empresaService.d.ts.map +1 -1
- package/dist/docs/docMockServices/empresaService.js +18 -10
- package/dist/docs/docMockServices/interfaces.d.ts +12 -0
- package/dist/docs/docMockServices/interfaces.d.ts.map +1 -1
- package/dist/docs/docMockServices/personaEmpresaService.d.ts +6 -6
- package/dist/docs/docMockServices/personaEmpresaService.d.ts.map +1 -1
- package/dist/docs/docMockServices/personaEmpresaService.js +52 -14
- package/dist/docs/docMockServices/personaService.d.ts +1 -1
- package/dist/docs/docMockServices/personaService.d.ts.map +1 -1
- package/dist/docs/docMockServices/personaService.js +14 -5
- package/dist/index.css +1 -1
- package/dist/index.d.ts +8 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -2
- package/dist/index.js.map +1 -1
- package/package.json +6 -4
- package/dist/components/utils/DropdownMenu.d.ts.map +0 -1
- package/dist/components/utils/Filter.d.ts.map +0 -1
- package/dist/contexts/ListCrudContext.d.ts.map +0 -1
- /package/dist/components/{utils → layout}/DropdownMenu.d.ts +0 -0
package/AI_CONTEXT.md
ADDED
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
# Flysoft React UI - AI Context & Documentation
|
|
2
|
+
|
|
3
|
+
This document serves as the source of truth for AI models (Gemini, Claude, GPT, etc.) when generating code that consumes the `flysoft-react-ui` library.
|
|
4
|
+
|
|
5
|
+
## Library Philosophy
|
|
6
|
+
`flysoft-react-ui` is a React component library built with TypeScript. It emphasizes a consistent look and feel, ease of use, and "premium" aesthetics out of the box.
|
|
7
|
+
|
|
8
|
+
## 🚨 Critical Rules for AI
|
|
9
|
+
1. **Top-Level Imports Only**: Always import components from the root package `flysoft-react-ui`.
|
|
10
|
+
- **CORRECT**: `import { Button, Card } from 'flysoft-react-ui';`
|
|
11
|
+
- **INCORRECT**: `import { Button } from 'flysoft-react-ui/components/Button';`
|
|
12
|
+
2. **TypeScript First**: Use the exported types (e.g., `ButtonProps`, `DataTableColumn`) to ensure type safety.
|
|
13
|
+
3. **No Direct Style Imports**: Do not import CSS files from the library (like `flysoft-react-ui/dist/index.css`) in components. This is handled at the app root.
|
|
14
|
+
|
|
15
|
+
## Component Categorization
|
|
16
|
+
|
|
17
|
+
### 1. Layouts (Priority for Page Structure)
|
|
18
|
+
- **AppLayout**: The main wrapper for applications.
|
|
19
|
+
- **Props**: `navbar` (NavbarInterface), `leftDrawer` (LeftDrawerInterface), `children`.
|
|
20
|
+
- **Usage**: Use this as the root component for your page routes.
|
|
21
|
+
- **DashboardLayout**: Specialized layout for dashboard views with statistics.
|
|
22
|
+
- **SidebarLayout**: Layout with a persistent sidebar.
|
|
23
|
+
|
|
24
|
+
### 2. Form Controls
|
|
25
|
+
- **Button / LinkButton**: Standard buttons. Supports `variant` ('primary' | 'secondary' | 'danger' | 'ghost') and `icon`.
|
|
26
|
+
- **Input**: Text inputs.
|
|
27
|
+
- **AutocompleteInput**: Searchable dropdown. Critical for foreign key selection.
|
|
28
|
+
- **DateInput / DatePicker**: Date handling.
|
|
29
|
+
- **Checkbox / RadioButtonGroup**: Boolean and option selection.
|
|
30
|
+
- **ThemeSwitcher**: Toggle between light/dark modes.
|
|
31
|
+
|
|
32
|
+
### 3. Data Display & Containers
|
|
33
|
+
- **DataTable<T>**: High-performance table.
|
|
34
|
+
- **Props**: `columns` (array of definitions), `rows` (data), `isLoading`.
|
|
35
|
+
- **Card**: Generic container with shadow and rounded corners.
|
|
36
|
+
- **DataField**: Displays a Label + Value pair, useful for detail views.
|
|
37
|
+
- **Accordion**: Collapsible content sections.
|
|
38
|
+
- **Collection**: Renders a list of items using a render prop or component.
|
|
39
|
+
- **TabsGroup / TabPanel**: Tabbed interfaces.
|
|
40
|
+
|
|
41
|
+
### 4. Utilities & Feedback
|
|
42
|
+
- **Dialog**: Modal windows for confirmation or complex forms.
|
|
43
|
+
- **Snackbar**: Toast notifications. Requires `SnackbarContainer` at the app root.
|
|
44
|
+
- **Loader**: Visual loading indicator.
|
|
45
|
+
- **Badge / Avatar**: status indicators and user images.
|
|
46
|
+
|
|
47
|
+
## Common Patterns
|
|
48
|
+
|
|
49
|
+
### Basic Page Structure
|
|
50
|
+
```tsx
|
|
51
|
+
import { AppLayout, Card, Button } from 'flysoft-react-ui';
|
|
52
|
+
|
|
53
|
+
export default function Page() {
|
|
54
|
+
return (
|
|
55
|
+
<AppLayout
|
|
56
|
+
navbar={{ title: "My Page" }}
|
|
57
|
+
>
|
|
58
|
+
<div className="p-4 space-y-4">
|
|
59
|
+
<Card>
|
|
60
|
+
<h2>Content</h2>
|
|
61
|
+
<Button variant="primary" onClick={() => {}}>Action</Button>
|
|
62
|
+
</Card>
|
|
63
|
+
</div>
|
|
64
|
+
</AppLayout>
|
|
65
|
+
);
|
|
66
|
+
}
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
### Data Table Usage
|
|
70
|
+
```tsx
|
|
71
|
+
import { DataTable, DataTableColumn } from 'flysoft-react-ui';
|
|
72
|
+
|
|
73
|
+
interface User { id: number; name: string; }
|
|
74
|
+
|
|
75
|
+
const columns: DataTableColumn<User>[] = [
|
|
76
|
+
{ header: 'ID', accessorKey: 'id' },
|
|
77
|
+
{ header: 'Name', accessorKey: 'name' },
|
|
78
|
+
];
|
|
79
|
+
|
|
80
|
+
<DataTable columns={columns} rows={users} />
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
## Icons
|
|
84
|
+
The library is agnostic but pairs well with `lucide-react`. Pass icons as ReactNodes to props like `icon`, `startIcon`, or `endIcon`.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AutocompleteInput.d.ts","sourceRoot":"","sources":["../../../src/components/form-controls/AutocompleteInput.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"AutocompleteInput.d.ts","sourceRoot":"","sources":["../../../src/components/form-controls/AutocompleteInput.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAI1B,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAI1C,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAC9B,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,sBAAsB,CAAC,CAAC,GAAG,kBAAkB,EAAE,CAAC,GAAG,MAAM,CACxE,SAAQ,IAAI,CAAC,UAAU,EAAE,UAAU,GAAG,OAAO,GAAG,KAAK,CAAC;IACtD,OAAO,EAAE,CAAC,EAAE,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;;OAGG;IACH,QAAQ,CAAC,EACL,KAAK,CAAC,kBAAkB,CAAC,gBAAgB,CAAC,GAC1C,CAAC,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC,CAAC;IAC9B;;OAEG;IACH,cAAc,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,KAAK,IAAI,CAAC;IAC/C,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;;OAEG;IACH,cAAc,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,MAAM,CAAC;IACrC;;OAEG;IACH,cAAc,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC;IAChC;;OAEG;IACH,oBAAoB,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC;IAChE;;OAEG;IACH,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,KAAK,CAAC,SAAS,CAAC;IAC5C;;;OAGG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAguBD,eAAO,MAAM,iBAAiB,EAA6B,CACzD,CAAC,GAAG,kBAAkB,EACtB,CAAC,GAAG,MAAM,EAEV,KAAK,EAAE,sBAAsB,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG;IACpC,GAAG,CAAC,EAAE,KAAK,CAAC,YAAY,CAAC,gBAAgB,CAAC,CAAC;CAC5C,KACE,KAAK,CAAC,YAAY,CAAC"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
2
|
import React from "react";
|
|
3
3
|
import { createPortal } from "react-dom";
|
|
4
|
+
import { useFormContext } from "react-hook-form";
|
|
4
5
|
import { Input } from "./Input";
|
|
5
6
|
import { normalizeIconClass } from "../utils/iconUtils";
|
|
6
7
|
const AutocompleteInputInner = React.forwardRef(({ options, value, onChange, onSelectOption, noResultsText = "Sin resultados", className = "", getOptionLabel, getOptionValue, getOptionDescription, renderOption, readOnly = false, ...inputProps }, ref) => {
|
|
@@ -12,6 +13,7 @@ const AutocompleteInputInner = React.forwardRef(({ options, value, onChange, onS
|
|
|
12
13
|
const containerRef = React.useRef(null);
|
|
13
14
|
const dropdownRef = React.useRef(null);
|
|
14
15
|
const inputRef = React.useRef(null);
|
|
16
|
+
const hiddenInputRef = React.useRef(null);
|
|
15
17
|
const justClearedRef = React.useRef(false);
|
|
16
18
|
// Detectar si estamos en modo register: si viene 'name' de register, estamos en modo register
|
|
17
19
|
// register siempre pasa 'name', 'onChange', 'onBlur', y 'ref'
|
|
@@ -19,6 +21,16 @@ const AutocompleteInputInner = React.forwardRef(({ options, value, onChange, onS
|
|
|
19
21
|
// Si viene 'name' en inputProps, es porque viene de register
|
|
20
22
|
return "name" in inputProps && inputProps.name !== undefined;
|
|
21
23
|
}, [inputProps]);
|
|
24
|
+
const fieldName = isRegisterMode && "name" in inputProps
|
|
25
|
+
? inputProps.name
|
|
26
|
+
: undefined;
|
|
27
|
+
// Obtener setValue del contexto del formulario
|
|
28
|
+
// Para usar con register, el formulario debe estar dentro de FormProvider
|
|
29
|
+
// useFormContext debe llamarse incondicionalmente (requisito de React Hooks)
|
|
30
|
+
// Si no hay FormProvider y se usa en modo register, useFormContext lanzará un error
|
|
31
|
+
// Para usar sin FormProvider, usar Controller en lugar de register
|
|
32
|
+
const formContext = useFormContext();
|
|
33
|
+
const setValue = formContext?.setValue;
|
|
22
34
|
const inputValue = isRegisterMode
|
|
23
35
|
? displayValue
|
|
24
36
|
: value !== undefined
|
|
@@ -54,23 +66,27 @@ const AutocompleteInputInner = React.forwardRef(({ options, value, onChange, onS
|
|
|
54
66
|
}, [inputValue, options, labelGetter, valueGetter]);
|
|
55
67
|
// Función helper para sincronizar displayValue con el valor del formulario
|
|
56
68
|
const syncDisplayValue = React.useCallback(() => {
|
|
57
|
-
if (isRegisterMode
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
69
|
+
if (isRegisterMode) {
|
|
70
|
+
// En modo register, usamos el hiddenInputRef si existe, sino el inputRef (legacy/fallback)
|
|
71
|
+
const targetInput = hiddenInputRef.current || inputRef.current;
|
|
72
|
+
if (targetInput) {
|
|
73
|
+
const formValue = targetInput.value;
|
|
74
|
+
// Si el valor del formulario coincide con algún getOptionValue, mostrar su label
|
|
75
|
+
const matchingOption = options.find((option) => String(valueGetter(option)) === String(formValue));
|
|
76
|
+
if (matchingOption) {
|
|
77
|
+
const label = labelGetter(matchingOption);
|
|
78
|
+
setDisplayValue(label);
|
|
79
|
+
return true; // Indica que se encontró y sincronizó un valor
|
|
80
|
+
}
|
|
81
|
+
else if (formValue) {
|
|
82
|
+
// Si hay un valor pero no coincide, mostrarlo tal cual (o buscar por label si fuera el caso)
|
|
83
|
+
setDisplayValue(formValue);
|
|
84
|
+
return true;
|
|
85
|
+
}
|
|
86
|
+
else {
|
|
87
|
+
setDisplayValue("");
|
|
88
|
+
return false; // No hay valor aún
|
|
89
|
+
}
|
|
74
90
|
}
|
|
75
91
|
}
|
|
76
92
|
return false;
|
|
@@ -83,8 +99,9 @@ const AutocompleteInputInner = React.forwardRef(({ options, value, onChange, onS
|
|
|
83
99
|
const maxAttempts = 50; // Intentar durante ~5 segundos (50 * 100ms)
|
|
84
100
|
// Función que intenta sincronizar y retorna true si encontró un valor
|
|
85
101
|
const trySync = () => {
|
|
86
|
-
|
|
87
|
-
|
|
102
|
+
const targetInput = hiddenInputRef.current || inputRef.current;
|
|
103
|
+
if (targetInput) {
|
|
104
|
+
const formValue = targetInput.value;
|
|
88
105
|
if (formValue) {
|
|
89
106
|
// Hay un valor, intentar sincronizar
|
|
90
107
|
const matchingOption = options.find((option) => String(valueGetter(option)) === String(formValue));
|
|
@@ -126,30 +143,36 @@ const AutocompleteInputInner = React.forwardRef(({ options, value, onChange, onS
|
|
|
126
143
|
};
|
|
127
144
|
}
|
|
128
145
|
}, [isRegisterMode, options, valueGetter, labelGetter]);
|
|
129
|
-
// También escuchar cambios en el input
|
|
146
|
+
// También escuchar cambios en el input (hidden o visible) para sincronizar cuando cambie
|
|
130
147
|
React.useEffect(() => {
|
|
131
|
-
if (isRegisterMode
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
148
|
+
if (isRegisterMode) {
|
|
149
|
+
// Observamos el hiddenInput si estamos en register mode y existe, o el input normal
|
|
150
|
+
const targetElement = hiddenInputRef.current || inputRef.current;
|
|
151
|
+
if (targetElement) {
|
|
152
|
+
// Función para sincronizar cuando el input cambia
|
|
153
|
+
const handleInputSync = () => {
|
|
154
|
+
// Solo sincronizar si es el hidden input o si no tenemos hidden input
|
|
155
|
+
if (targetElement === hiddenInputRef.current) {
|
|
156
|
+
syncDisplayValue();
|
|
157
|
+
}
|
|
158
|
+
};
|
|
159
|
+
// Escuchar eventos de input y change (aunque en hidden input no suelen dispararse eventos de usuario)
|
|
160
|
+
targetElement.addEventListener("input", handleInputSync);
|
|
161
|
+
targetElement.addEventListener("change", handleInputSync);
|
|
162
|
+
// También usar MutationObserver para detectar cambios en el atributo value (más fiable para hidden inputs cambiados por JS)
|
|
163
|
+
const observer = new MutationObserver(() => {
|
|
164
|
+
syncDisplayValue();
|
|
165
|
+
});
|
|
166
|
+
observer.observe(targetElement, {
|
|
167
|
+
attributes: true,
|
|
168
|
+
attributeFilter: ["value"],
|
|
169
|
+
});
|
|
170
|
+
return () => {
|
|
171
|
+
targetElement.removeEventListener("input", handleInputSync);
|
|
172
|
+
targetElement.removeEventListener("change", handleInputSync);
|
|
173
|
+
observer.disconnect();
|
|
174
|
+
};
|
|
175
|
+
}
|
|
153
176
|
}
|
|
154
177
|
}, [isRegisterMode, syncDisplayValue]);
|
|
155
178
|
const handleChange = (event) => {
|
|
@@ -179,53 +202,56 @@ const AutocompleteInputInner = React.forwardRef(({ options, value, onChange, onS
|
|
|
179
202
|
const selectedValue = valueGetter(option);
|
|
180
203
|
const valueString = String(selectedValue ?? "");
|
|
181
204
|
if (isRegisterMode) {
|
|
182
|
-
// En modo register
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
//
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
nativeInputValueSetter.call(nativeInput, valueString);
|
|
192
|
-
}
|
|
193
|
-
else {
|
|
194
|
-
// Fallback si el setter no está disponible
|
|
195
|
-
nativeInput.value = valueString;
|
|
205
|
+
// En modo register, setear el valor usando setValue o actualizando el input nativo (hidden)
|
|
206
|
+
if (setValue && fieldName) {
|
|
207
|
+
setValue(fieldName, selectedValue, {
|
|
208
|
+
shouldValidate: true,
|
|
209
|
+
shouldDirty: true,
|
|
210
|
+
});
|
|
211
|
+
// Actualizar el input hidden con el ID
|
|
212
|
+
if (hiddenInputRef.current) {
|
|
213
|
+
hiddenInputRef.current.value = valueString;
|
|
196
214
|
}
|
|
197
|
-
//
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
215
|
+
// Actualizar displayValue con el label para mostrarlo visualmente en el input visible
|
|
216
|
+
setDisplayValue(label);
|
|
217
|
+
}
|
|
218
|
+
else {
|
|
219
|
+
// Fallback si no hay setValue (raro en registerMode) o para inputs manuales
|
|
220
|
+
const targetInput = hiddenInputRef.current || inputRef.current;
|
|
221
|
+
if (targetInput) {
|
|
222
|
+
const nativeInput = targetInput;
|
|
223
|
+
const nativeInputValueSetter = Object.getOwnPropertyDescriptor(window.HTMLInputElement.prototype, "value")?.set;
|
|
224
|
+
if (nativeInputValueSetter) {
|
|
225
|
+
nativeInputValueSetter.call(nativeInput, valueString);
|
|
226
|
+
}
|
|
227
|
+
else {
|
|
228
|
+
nativeInput.value = valueString;
|
|
229
|
+
}
|
|
230
|
+
// Disparar eventos en el input que tiene el ref de register
|
|
231
|
+
if (onChange) {
|
|
232
|
+
const changeEvent = {
|
|
233
|
+
target: nativeInput,
|
|
234
|
+
currentTarget: nativeInput,
|
|
235
|
+
}; // Cast agresivo necesario
|
|
236
|
+
onChange(changeEvent);
|
|
237
|
+
}
|
|
238
|
+
const inputEvent = new Event("input", {
|
|
239
|
+
bubbles: true,
|
|
240
|
+
cancelable: true,
|
|
241
|
+
});
|
|
242
|
+
nativeInput.dispatchEvent(inputEvent);
|
|
243
|
+
const changeEventNative = new Event("change", {
|
|
244
|
+
bubbles: true,
|
|
245
|
+
cancelable: true,
|
|
246
|
+
});
|
|
247
|
+
nativeInput.dispatchEvent(changeEventNative);
|
|
207
248
|
}
|
|
208
|
-
//
|
|
209
|
-
|
|
210
|
-
const inputEvent = new Event("input", {
|
|
211
|
-
bubbles: true,
|
|
212
|
-
cancelable: true,
|
|
213
|
-
});
|
|
214
|
-
nativeInput.dispatchEvent(inputEvent);
|
|
215
|
-
const changeEventNative = new Event("change", {
|
|
216
|
-
bubbles: true,
|
|
217
|
-
cancelable: true,
|
|
218
|
-
});
|
|
219
|
-
nativeInput.dispatchEvent(changeEventNative);
|
|
249
|
+
// Y actualizamos visualmente
|
|
250
|
+
setDisplayValue(label);
|
|
220
251
|
}
|
|
221
|
-
// Actualizar el displayValue para mostrar el label
|
|
222
|
-
setDisplayValue(label);
|
|
223
252
|
}
|
|
224
253
|
else {
|
|
225
254
|
// Modo API personalizada - comportamiento original
|
|
226
|
-
if (value === undefined) {
|
|
227
|
-
setInternalValue(label);
|
|
228
|
-
}
|
|
229
255
|
// Pasar el valor devuelto por getOptionValue, no el label
|
|
230
256
|
if (onChange) {
|
|
231
257
|
onChange(valueString);
|
|
@@ -347,11 +373,15 @@ const AutocompleteInputInner = React.forwardRef(({ options, value, onChange, onS
|
|
|
347
373
|
// Detectar si hay un valor seleccionado
|
|
348
374
|
// Un valor está seleccionado si el value coincide con el getOptionValue de alguna opción
|
|
349
375
|
const hasSelectedValue = React.useMemo(() => {
|
|
350
|
-
if (isRegisterMode
|
|
351
|
-
const
|
|
352
|
-
if (
|
|
353
|
-
|
|
354
|
-
|
|
376
|
+
if (isRegisterMode) {
|
|
377
|
+
const targetInput = hiddenInputRef.current || inputRef.current;
|
|
378
|
+
if (targetInput) {
|
|
379
|
+
const formValue = targetInput.value;
|
|
380
|
+
if (!formValue)
|
|
381
|
+
return false;
|
|
382
|
+
return options.some((option) => String(valueGetter(option)) === String(formValue));
|
|
383
|
+
}
|
|
384
|
+
return false;
|
|
355
385
|
}
|
|
356
386
|
if (value === undefined || value === null || value === "")
|
|
357
387
|
return false;
|
|
@@ -367,9 +397,10 @@ const AutocompleteInputInner = React.forwardRef(({ options, value, onChange, onS
|
|
|
367
397
|
// Marcar que acabamos de limpiar para prevenir que onFocus abra el diálogo
|
|
368
398
|
justClearedRef.current = true;
|
|
369
399
|
if (isRegisterMode) {
|
|
370
|
-
// En modo register, limpiar el input nativo y disparar eventos
|
|
371
|
-
|
|
372
|
-
|
|
400
|
+
// En modo register, limpiar el input nativo (hidden) y disparar eventos
|
|
401
|
+
const targetInput = hiddenInputRef.current || inputRef.current;
|
|
402
|
+
if (targetInput) {
|
|
403
|
+
const nativeInput = targetInput;
|
|
373
404
|
const setter = Object.getOwnPropertyDescriptor(window.HTMLInputElement.prototype, "value")?.set;
|
|
374
405
|
setter?.call(nativeInput, "");
|
|
375
406
|
// Disparar eventos para que react-hook-form lo capture
|
|
@@ -377,17 +408,17 @@ const AutocompleteInputInner = React.forwardRef(({ options, value, onChange, onS
|
|
|
377
408
|
nativeInput.dispatchEvent(inputEvent);
|
|
378
409
|
const changeEvent = new Event("change", { bubbles: true });
|
|
379
410
|
nativeInput.dispatchEvent(changeEvent);
|
|
411
|
+
// Llamar al onChange de register
|
|
412
|
+
if (onChange) {
|
|
413
|
+
const changeEventReact = {
|
|
414
|
+
target: nativeInput,
|
|
415
|
+
currentTarget: nativeInput,
|
|
416
|
+
};
|
|
417
|
+
onChange(changeEventReact);
|
|
418
|
+
}
|
|
380
419
|
}
|
|
381
420
|
// Limpiar el displayValue
|
|
382
421
|
setDisplayValue("");
|
|
383
|
-
// Llamar al onChange de register
|
|
384
|
-
if (onChange && inputRef.current) {
|
|
385
|
-
const changeEvent = {
|
|
386
|
-
target: inputRef.current,
|
|
387
|
-
currentTarget: inputRef.current,
|
|
388
|
-
};
|
|
389
|
-
onChange(changeEvent);
|
|
390
|
-
}
|
|
391
422
|
}
|
|
392
423
|
else {
|
|
393
424
|
// Modo API personalizada
|
|
@@ -421,39 +452,53 @@ const AutocompleteInputInner = React.forwardRef(({ options, value, onChange, onS
|
|
|
421
452
|
: hasSelectedValue
|
|
422
453
|
? handleClear
|
|
423
454
|
: inputProps.onIconClick;
|
|
424
|
-
//
|
|
425
|
-
const
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
455
|
+
// Refs separados: uno para el visible y otro para el hidden (registrado)
|
|
456
|
+
const setHiddenRef = React.useCallback((node) => {
|
|
457
|
+
hiddenInputRef.current = node;
|
|
458
|
+
// Solo pasar el ref externo al hidden input en modo register
|
|
459
|
+
if (isRegisterMode) {
|
|
460
|
+
if (typeof ref === "function") {
|
|
461
|
+
ref(node);
|
|
462
|
+
}
|
|
463
|
+
else if (ref) {
|
|
464
|
+
ref.current = node;
|
|
465
|
+
}
|
|
466
|
+
// Sincronización inicial cuando el ref se monta
|
|
467
|
+
if (node) {
|
|
468
|
+
[0, 10, 50, 100, 200, 500].forEach((delay) => {
|
|
469
|
+
setTimeout(() => {
|
|
470
|
+
if (node && hiddenInputRef.current === node) {
|
|
471
|
+
const formValue = node.value;
|
|
472
|
+
if (formValue) {
|
|
473
|
+
const matchingOption = options.find((option) => String(valueGetter(option)) === String(formValue));
|
|
474
|
+
if (matchingOption) {
|
|
475
|
+
setDisplayValue(labelGetter(matchingOption));
|
|
476
|
+
}
|
|
477
|
+
else {
|
|
478
|
+
setDisplayValue(formValue);
|
|
479
|
+
}
|
|
449
480
|
}
|
|
450
481
|
}
|
|
451
|
-
}
|
|
452
|
-
}
|
|
453
|
-
}
|
|
482
|
+
}, delay);
|
|
483
|
+
});
|
|
484
|
+
}
|
|
454
485
|
}
|
|
455
486
|
}, [ref, isRegisterMode, options, valueGetter, labelGetter]);
|
|
456
|
-
|
|
487
|
+
const setVisibleRef = React.useCallback((node) => {
|
|
488
|
+
inputRef.current = node;
|
|
489
|
+
// En modo NO register, pasamos el ref al input visible
|
|
490
|
+
if (!isRegisterMode) {
|
|
491
|
+
if (typeof ref === "function") {
|
|
492
|
+
ref(node);
|
|
493
|
+
}
|
|
494
|
+
else if (ref) {
|
|
495
|
+
ref.current = node;
|
|
496
|
+
}
|
|
497
|
+
}
|
|
498
|
+
}, [ref, isRegisterMode]);
|
|
499
|
+
// Separar propiedades para input visible y hidden
|
|
500
|
+
const { name: nameProp, ...visibleInputProps } = inputProps;
|
|
501
|
+
return (_jsxs("div", { ref: containerRef, className: "relative w-full", children: [isRegisterMode && (_jsx("input", { type: "hidden", name: nameProp, ref: setHiddenRef, defaultValue: value })), _jsx(Input, { ...visibleInputProps, name: isRegisterMode ? undefined : nameProp, ref: setVisibleRef, value: inputValue, onChange: handleChange, onFocus: () => {
|
|
457
502
|
if (!readOnly && !justClearedRef.current) {
|
|
458
503
|
setIsOpen(true);
|
|
459
504
|
}
|
|
@@ -468,7 +513,7 @@ const AutocompleteInputInner = React.forwardRef(({ options, value, onChange, onS
|
|
|
468
513
|
dropdownPosition &&
|
|
469
514
|
isMounted &&
|
|
470
515
|
bodyElement &&
|
|
471
|
-
createPortal(_jsx("div", { ref: dropdownRef, className: "fixed z-[2001] min-w-full w-max rounded-md border border-[var(--color-border-default)] \
|
|
516
|
+
createPortal(_jsx("div", { ref: dropdownRef, className: "fixed z-[2001] min-w-full w-max rounded-md border border-[var(--color-border-default)] \n bg-[var(--color-bg-default)] shadow-[var(--shadow-lg)] max-h-60 overflow-auto", style: {
|
|
472
517
|
top: `${dropdownPosition.top}px`,
|
|
473
518
|
left: `${dropdownPosition.left}px`,
|
|
474
519
|
minWidth: `${dropdownPosition.width}px`,
|
|
@@ -476,7 +521,7 @@ const AutocompleteInputInner = React.forwardRef(({ options, value, onChange, onS
|
|
|
476
521
|
const label = labelGetter(option);
|
|
477
522
|
const description = descriptionGetter(option);
|
|
478
523
|
const anyOption = option;
|
|
479
|
-
return (_jsx("li", { className: `px-3 py-2 cursor-pointer flex items-start gap-2 text-sm
|
|
524
|
+
return (_jsx("li", { className: `px-3 py-2 cursor-pointer flex items-start gap-2 text-sm
|
|
480
525
|
${index === highlightedIndex
|
|
481
526
|
? "bg-[var(--color-primary-soft)] text-[var(--color-primary)]"
|
|
482
527
|
: "text-[var(--color-text-primary)] hover:bg-[var(--color-bg-secondary)]"}`, onMouseDown: (event) => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SearchSelectInput-OLD.d.ts","sourceRoot":"","sources":["../../../src/components/form-controls/SearchSelectInput-OLD.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAG1B,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAG1C,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;AAED,MAAM,WAAW,sBAAsB,CAAC,CAAC,GAAG,kBAAkB,EAAE,CAAC,GAAG,MAAM,CACxE,SAAQ,IAAI,CAAC,UAAU,EAAE,UAAU,GAAG,OAAO,GAAG,KAAK,CAAC;IACtD;;;OAGG;IACH,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC;IACvB;;;;OAIG;IACH,QAAQ,CAAC,
|
|
1
|
+
{"version":3,"file":"SearchSelectInput-OLD.d.ts","sourceRoot":"","sources":["../../../src/components/form-controls/SearchSelectInput-OLD.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAG1B,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAG1C,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;AAED,MAAM,WAAW,sBAAsB,CAAC,CAAC,GAAG,kBAAkB,EAAE,CAAC,GAAG,MAAM,CACxE,SAAQ,IAAI,CAAC,UAAU,EAAE,UAAU,GAAG,OAAO,GAAG,KAAK,CAAC;IACtD;;;OAGG;IACH,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC;IACvB;;;;OAIG;IACH,QAAQ,CAAC,EACP,CAAC,CAAC,KAAK,EAAE,CAAC,GAAG,CAAC,KAAK,IAAI,CAAC,GACxB,KAAK,CAAC,kBAAkB,CAAC,gBAAgB,CAAC,CAAC;IAC7C;;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,oBAAoB,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IACxC;;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;CAC7C;AA6sCD,eAAO,MAAM,iBAAiB,EAAiC,CAC7D,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"}
|
|
@@ -945,7 +945,7 @@ function SearchSelectInputInner({ value, onChange, onSearchPromiseFn, onSingleSe
|
|
|
945
945
|
restInputProps.onFocus(e);
|
|
946
946
|
}
|
|
947
947
|
handleInputFocus(e);
|
|
948
|
-
}, onBlur: registerOnBlur, onKeyDown: handleKeyDown, size: size, icon: displayIcon, iconPosition: displayIconPosition, onIconClick: displayOnIconClick, readOnly: true }) }), _jsx(Dialog, { isOpen: isDialogOpen, title: dialogTitle,
|
|
948
|
+
}, onBlur: registerOnBlur, onKeyDown: handleKeyDown, size: size, icon: displayIcon, iconPosition: displayIconPosition, onIconClick: displayOnIconClick, readOnly: true }) }), _jsx(Dialog, { isOpen: isDialogOpen, title: dialogTitle, children: _jsxs("div", { className: "space-y-2", children: [_jsx(Input, { value: dialogSearchText, onChange: (e) => setDialogSearchText(e.target.value), onKeyDown: (e) => {
|
|
949
949
|
if (e.key === "Enter") {
|
|
950
950
|
e.preventDefault();
|
|
951
951
|
handleDialogSearch();
|
|
@@ -956,7 +956,7 @@ function SearchSelectInputInner({ value, onChange, onSearchPromiseFn, onSingleSe
|
|
|
956
956
|
const anyOption = option;
|
|
957
957
|
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 &&
|
|
958
958
|
description !== null && (_jsx("span", { className: "text-xs text-[var(--color-text-secondary)]", children: description }))] })] })) }, String(valueGetter(option) ?? label ?? index)));
|
|
959
|
-
}) })) : hasSearched ? (_jsx("div", { className: "px-3 py-8 text-center text-sm text-[var(--color-text-secondary)]", children: noResultsText })) : null] }),
|
|
959
|
+
}) })) : hasSearched ? (_jsx("div", { className: "px-3 py-8 text-center text-sm text-[var(--color-text-secondary)]", children: noResultsText })) : null] }), footer: _jsx(Button, { variant: "outline", onClick: () => setIsDialogOpen(false), children: "Cerrar" }), onClose: () => setIsDialogOpen(false), closeOnOverlayClick: true })] }));
|
|
960
960
|
}
|
|
961
961
|
const SearchSelectInputForwarded = React.forwardRef(SearchSelectInputInner);
|
|
962
962
|
SearchSelectInputForwarded.displayName = "SearchSelectInput";
|
|
@@ -1 +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,
|
|
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,EACP,CAAC,CAAC,KAAK,EAAE,CAAC,GAAG,CAAC,KAAK,IAAI,CAAC,GACxB,KAAK,CAAC,kBAAkB,CAAC,gBAAgB,CAAC,CAAC;IAC7C;;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;AAyfD,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"}
|
|
@@ -329,7 +329,7 @@ const SearchSelectInputInner = React.forwardRef(function SearchSelectInput({ val
|
|
|
329
329
|
if (!readOnly && !justClearedRef.current) {
|
|
330
330
|
setIsDialogOpen(true);
|
|
331
331
|
}
|
|
332
|
-
}, icon: displayIcon, iconPosition: displayIconPosition, onIconClick: displayOnIconClick, readOnly: readOnly }), !readOnly && (_jsx(Dialog, { isOpen: isDialogOpen, title: dialogTitle,
|
|
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
333
|
});
|
|
334
334
|
SearchSelectInputInner.displayName = "SearchSelectInput";
|
|
335
335
|
// Exportar con el cast genérico para permitir uso como <SearchSelectInput<T, K>>
|
|
@@ -1 +1 @@
|
|
|
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,
|
|
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,CAgd9C,CAAC"}
|