flysoft-react-ui 0.5.2 → 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.
- package/dist/App.d.ts.map +1 -1
- package/dist/App.js +5 -6
- package/dist/components/form-controls/AutocompleteInput.d.ts.map +1 -1
- package/dist/components/form-controls/AutocompleteInput.js +2 -1
- package/dist/components/form-controls/Button.d.ts +3 -0
- package/dist/components/form-controls/Button.d.ts.map +1 -1
- package/dist/components/form-controls/Button.js +160 -19
- package/dist/components/form-controls/Checkbox.d.ts.map +1 -1
- package/dist/components/form-controls/Checkbox.js +3 -1
- package/dist/components/form-controls/DateInput.d.ts +5 -1
- package/dist/components/form-controls/DateInput.d.ts.map +1 -1
- package/dist/components/form-controls/DateInput.js +94 -27
- package/dist/components/form-controls/Input.d.ts.map +1 -1
- package/dist/components/form-controls/Input.js +2 -1
- package/dist/components/form-controls/LinkButton.d.ts +15 -0
- package/dist/components/form-controls/LinkButton.d.ts.map +1 -0
- package/dist/components/form-controls/LinkButton.js +248 -0
- package/dist/components/form-controls/SearchSelectInput-OLD.d.ts.map +1 -1
- package/dist/components/form-controls/SearchSelectInput-OLD.js +3 -2
- package/dist/components/form-controls/SearchSelectInput.d.ts.map +1 -1
- package/dist/components/form-controls/SearchSelectInput.js +2 -1
- package/dist/components/form-controls/index.d.ts +2 -0
- package/dist/components/form-controls/index.d.ts.map +1 -1
- package/dist/components/form-controls/index.js +1 -0
- package/dist/components/layout/Accordion.d.ts +13 -0
- package/dist/components/layout/Accordion.d.ts.map +1 -0
- package/dist/components/layout/Accordion.js +67 -0
- package/dist/components/layout/AppLayout.js +1 -1
- package/dist/components/layout/Card.d.ts +8 -3
- package/dist/components/layout/Card.d.ts.map +1 -1
- package/dist/components/layout/Card.js +18 -19
- package/dist/components/layout/index.d.ts +2 -0
- package/dist/components/layout/index.d.ts.map +1 -1
- package/dist/components/layout/index.js +1 -0
- package/dist/components/utils/Badge.d.ts.map +1 -1
- package/dist/components/utils/Badge.js +3 -2
- package/dist/components/utils/Dialog.d.ts.map +1 -1
- package/dist/components/utils/Dialog.js +2 -1
- package/dist/components/utils/Filter.d.ts.map +1 -1
- package/dist/components/utils/Filter.js +2 -1
- package/dist/components/utils/Loader.js +1 -1
- package/dist/components/utils/RoadMap.d.ts.map +1 -1
- package/dist/components/utils/RoadMap.js +2 -1
- package/dist/components/utils/Snackbar.d.ts.map +1 -1
- package/dist/components/utils/Snackbar.js +2 -1
- package/dist/components/utils/iconUtils.d.ts +16 -0
- package/dist/components/utils/iconUtils.d.ts.map +1 -0
- package/dist/components/utils/iconUtils.js +40 -0
- package/dist/contexts/ListCrudContext.d.ts +28 -7
- package/dist/contexts/ListCrudContext.d.ts.map +1 -1
- package/dist/contexts/ListCrudContext.js +100 -56
- package/dist/docs/AccordionDocs.d.ts +4 -0
- package/dist/docs/AccordionDocs.d.ts.map +1 -0
- package/dist/docs/AccordionDocs.js +21 -0
- package/dist/docs/AuthDocs.tsx/AuthDocsContent.js +3 -5
- package/dist/docs/AutocompleteInputDocs.js +1 -1
- package/dist/docs/ButtonDocs.d.ts.map +1 -1
- package/dist/docs/ButtonDocs.js +1 -1
- package/dist/docs/CardDocs.d.ts.map +1 -1
- package/dist/docs/CardDocs.js +17 -8
- package/dist/docs/DataTableDocs.js +3 -3
- package/dist/docs/DialogDocs.js +1 -1
- package/dist/docs/DocAdmin.js +1 -1
- package/dist/docs/DocsMenu.d.ts.map +1 -1
- package/dist/docs/DocsMenu.js +3 -3
- package/dist/docs/DocsRouter.d.ts.map +1 -1
- package/dist/docs/DocsRouter.js +3 -1
- package/dist/docs/DropdownMenuDocs.js +1 -1
- package/dist/docs/LinkButtonDocs.d.ts +4 -0
- package/dist/docs/LinkButtonDocs.d.ts.map +1 -0
- package/dist/docs/LinkButtonDocs.js +7 -0
- package/dist/docs/ListCrudDocs.tsx/ListCrudDocs.d.ts +0 -9
- package/dist/docs/ListCrudDocs.tsx/ListCrudDocs.d.ts.map +1 -1
- package/dist/docs/ListCrudDocs.tsx/ListCrudDocs.js +16 -12
- package/dist/docs/ListCrudDocs.tsx/ListCrudDocsContentEmpresas.d.ts +2 -0
- package/dist/docs/ListCrudDocs.tsx/ListCrudDocsContentEmpresas.d.ts.map +1 -0
- package/dist/docs/ListCrudDocs.tsx/ListCrudDocsContentEmpresas.js +7 -0
- package/dist/docs/ListCrudDocs.tsx/ListCrudDocsContentPersonas.d.ts.map +1 -1
- package/dist/docs/ListCrudDocs.tsx/ListCrudDocsContentPersonas.js +32 -26
- package/dist/docs/ListCrudDocs.tsx/ListCrudDocsEditDialog.d.ts +9 -0
- package/dist/docs/ListCrudDocs.tsx/ListCrudDocsEditDialog.d.ts.map +1 -0
- package/dist/docs/ListCrudDocs.tsx/ListCrudDocsEditDialog.js +30 -0
- package/dist/docs/SearchSelectInputDocs.js +1 -1
- package/dist/docs/docMockServices/empresaService.d.ts.map +1 -1
- package/dist/docs/docMockServices/empresaService.js +2 -1
- 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 +3 -2
- package/dist/index.css +1 -1
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/templates/forms/ContactForm.js +2 -2
- package/dist/templates/forms/LoginForm.js +1 -1
- package/dist/templates/forms/RegistrationForm.js +1 -1
- package/dist/templates/layouts/SidebarLayout.d.ts.map +1 -1
- package/dist/templates/layouts/SidebarLayout.js +3 -2
- package/dist/templates/patterns/FormPattern.d.ts.map +1 -1
- package/dist/templates/patterns/FormPattern.js +4 -3
- package/package.json +1 -1
|
@@ -0,0 +1,248 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import React from "react";
|
|
3
|
+
import { Link } from "react-router-dom";
|
|
4
|
+
import { normalizeIconClass } from "../utils/iconUtils";
|
|
5
|
+
// Función helper para convertir nombres de colores comunes a valores CSS válidos
|
|
6
|
+
const getColorValue = (color) => {
|
|
7
|
+
if (!color)
|
|
8
|
+
return undefined;
|
|
9
|
+
// Si ya es un valor CSS válido (hex, rgb, rgba, hsl, etc.), retornarlo
|
|
10
|
+
if (color.startsWith("#") ||
|
|
11
|
+
color.startsWith("rgb") ||
|
|
12
|
+
color.startsWith("hsl")) {
|
|
13
|
+
return color;
|
|
14
|
+
}
|
|
15
|
+
// Mapeo de nombres de colores comunes
|
|
16
|
+
const colorMap = {
|
|
17
|
+
white: "#ffffff",
|
|
18
|
+
black: "#000000",
|
|
19
|
+
"gray-800": "#1f2937",
|
|
20
|
+
"gray-700": "#374151",
|
|
21
|
+
"gray-600": "#4b5563",
|
|
22
|
+
"gray-500": "#6b7280",
|
|
23
|
+
"gray-400": "#9ca3af",
|
|
24
|
+
"gray-300": "#d1d5db",
|
|
25
|
+
"gray-200": "#e5e7eb",
|
|
26
|
+
"gray-100": "#f3f4f6",
|
|
27
|
+
"gray-50": "#f9fafb",
|
|
28
|
+
};
|
|
29
|
+
return colorMap[color.toLowerCase()] || color;
|
|
30
|
+
};
|
|
31
|
+
export const LinkButton = ({ to, target, variant = "primary", size = "md", color = "primary", bg, textColor, icon, iconPosition = "left", children, className = "", onClick, ...props }) => {
|
|
32
|
+
const [ripples, setRipples] = React.useState([]);
|
|
33
|
+
const baseClasses = `
|
|
34
|
+
inline-flex items-center justify-center font-medium rounded-sm transition-colors
|
|
35
|
+
cursor-pointer relative overflow-hidden no-underline outline-none focus:outline-none
|
|
36
|
+
focus-visible:outline-none active:outline-none focus:ring-0 focus:ring-offset-0
|
|
37
|
+
font-[var(--font-default)]
|
|
38
|
+
`;
|
|
39
|
+
// Mapeo de clases para variant primary con color primary (usa Tailwind)
|
|
40
|
+
const getVariantClasses = (variantType, colorType) => {
|
|
41
|
+
// Solo usar clases Tailwind para primary con color primary
|
|
42
|
+
if (colorType === "primary") {
|
|
43
|
+
if (variantType === "primary") {
|
|
44
|
+
return `
|
|
45
|
+
bg-[var(--color-primary)] text-[var(--color-primary-contrast)]
|
|
46
|
+
hover:bg-[var(--color-primary-dark)]
|
|
47
|
+
`;
|
|
48
|
+
}
|
|
49
|
+
else if (variantType === "outline") {
|
|
50
|
+
return `
|
|
51
|
+
border border-[var(--color-primary)] text-[var(--color-primary)]
|
|
52
|
+
hover:bg-[var(--color-bg-secondary)]
|
|
53
|
+
`;
|
|
54
|
+
}
|
|
55
|
+
else {
|
|
56
|
+
return `
|
|
57
|
+
text-[var(--color-primary)] hover:bg-[var(--color-bg-secondary)]
|
|
58
|
+
`;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
// Para otros colores, retornar clases base sin color (se aplicarán con estilos inline)
|
|
62
|
+
if (variantType === "primary") {
|
|
63
|
+
return ``;
|
|
64
|
+
}
|
|
65
|
+
else if (variantType === "outline") {
|
|
66
|
+
return `border hover:bg-[var(--color-bg-secondary)]`;
|
|
67
|
+
}
|
|
68
|
+
else {
|
|
69
|
+
return `hover:bg-[var(--color-bg-secondary)]`;
|
|
70
|
+
}
|
|
71
|
+
};
|
|
72
|
+
// Si se proporciona bg personalizado, no usar las clases de variante
|
|
73
|
+
const variantClasses = bg ? "" : getVariantClasses(variant, color);
|
|
74
|
+
// Determinar si necesitamos usar estilos inline para colores del sistema
|
|
75
|
+
const needsInlineStyles = !bg && color !== "primary";
|
|
76
|
+
const sizeClasses = {
|
|
77
|
+
sm: `${children ? "px-3 py-1.5" : "p-1.5"} text-sm`,
|
|
78
|
+
md: `${children ? "px-4 py-2" : "p-2"} text-base`,
|
|
79
|
+
lg: `${children ? "px-6 py-3" : "p-3"} text-lg`,
|
|
80
|
+
};
|
|
81
|
+
// Clases adicionales para variant outline cuando hay bg personalizado
|
|
82
|
+
const outlineClasses = bg && variant === "outline" ? "border" : "";
|
|
83
|
+
const classes = `${baseClasses} ${variantClasses} ${sizeClasses[size]} ${outlineClasses} ${className}`;
|
|
84
|
+
// Función para obtener el valor de una variable CSS
|
|
85
|
+
const getCSSVariable = (varName) => {
|
|
86
|
+
if (typeof window !== "undefined") {
|
|
87
|
+
const value = getComputedStyle(document.documentElement)
|
|
88
|
+
.getPropertyValue(varName)
|
|
89
|
+
.trim();
|
|
90
|
+
// Si no se encuentra la variable, intentar con el prefijo flysoft
|
|
91
|
+
if (!value && varName.startsWith("--color-")) {
|
|
92
|
+
const flysoftVarName = varName.replace("--color-", "--flysoft-");
|
|
93
|
+
return (getComputedStyle(document.documentElement)
|
|
94
|
+
.getPropertyValue(flysoftVarName)
|
|
95
|
+
.trim() || value);
|
|
96
|
+
}
|
|
97
|
+
return value;
|
|
98
|
+
}
|
|
99
|
+
return "";
|
|
100
|
+
};
|
|
101
|
+
// Estilos inline para colores personalizados o colores del sistema (no primary)
|
|
102
|
+
const inlineStyles = bg
|
|
103
|
+
? {
|
|
104
|
+
backgroundColor: variant === "primary" ? getColorValue(bg) || bg : undefined,
|
|
105
|
+
color: getColorValue(textColor) ||
|
|
106
|
+
textColor ||
|
|
107
|
+
(variant === "primary" ? "#ffffff" : getColorValue(bg) || bg),
|
|
108
|
+
borderColor: variant === "outline" ? getColorValue(bg) || bg : undefined,
|
|
109
|
+
...(variant === "ghost" && {
|
|
110
|
+
color: getColorValue(textColor) || textColor || getColorValue(bg) || bg,
|
|
111
|
+
}),
|
|
112
|
+
}
|
|
113
|
+
: needsInlineStyles
|
|
114
|
+
? {
|
|
115
|
+
...(variant === "primary" && {
|
|
116
|
+
backgroundColor: getCSSVariable(`--color-${color}`),
|
|
117
|
+
color: getCSSVariable(`--color-${color}-contrast`) || "#ffffff",
|
|
118
|
+
}),
|
|
119
|
+
...(variant === "outline" && {
|
|
120
|
+
borderColor: getCSSVariable(`--color-${color}`),
|
|
121
|
+
color: getCSSVariable(`--color-${color}`),
|
|
122
|
+
}),
|
|
123
|
+
...(variant === "ghost" && {
|
|
124
|
+
color: getCSSVariable(`--color-${color}`),
|
|
125
|
+
}),
|
|
126
|
+
}
|
|
127
|
+
: {};
|
|
128
|
+
// Función para oscurecer un color (para hover en variant primary con bg personalizado)
|
|
129
|
+
const darkenColor = (color, percent) => {
|
|
130
|
+
const hex = color.replace("#", "");
|
|
131
|
+
const num = parseInt(hex, 16);
|
|
132
|
+
const r = Math.max(0, Math.floor((num >> 16) * (1 - percent / 100)));
|
|
133
|
+
const g = Math.max(0, Math.floor(((num >> 8) & 0x00ff) * (1 - percent / 100)));
|
|
134
|
+
const b = Math.max(0, Math.floor((num & 0x0000ff) * (1 - percent / 100)));
|
|
135
|
+
return `#${((r << 16) | (g << 8) | b).toString(16).padStart(6, "0")}`;
|
|
136
|
+
};
|
|
137
|
+
const renderIcon = () => {
|
|
138
|
+
if (!icon)
|
|
139
|
+
return null;
|
|
140
|
+
const iconClasses = size === "sm" ? "w-4 h-4" : size === "md" ? "w-5 h-5" : "w-6 h-6";
|
|
141
|
+
return (_jsx("i", { className: `${normalizeIconClass(icon)} ${iconClasses} ${children ? (iconPosition === "right" ? "ml-2" : "mr-2") : ""} mt-0.5` }));
|
|
142
|
+
};
|
|
143
|
+
// Determinar el color del ripple basado en el variant y si hay bg personalizado
|
|
144
|
+
const rippleColor = bg
|
|
145
|
+
? variant === "primary"
|
|
146
|
+
? "rgba(255, 255, 255, 0.45)"
|
|
147
|
+
: "rgba(0, 0, 0, 0.15)"
|
|
148
|
+
: variant === "primary"
|
|
149
|
+
? "rgba(255, 255, 255, 0.45)"
|
|
150
|
+
: "rgba(0, 0, 0, 0.15)";
|
|
151
|
+
const handleClick = (event) => {
|
|
152
|
+
const targetElement = event.currentTarget;
|
|
153
|
+
if (targetElement) {
|
|
154
|
+
const rect = targetElement.getBoundingClientRect();
|
|
155
|
+
const size = Math.max(rect.width, rect.height) * 1.2;
|
|
156
|
+
const x = event.clientX - rect.left;
|
|
157
|
+
const y = event.clientY - rect.top;
|
|
158
|
+
const id = window.performance.now();
|
|
159
|
+
const newRipple = { id, x, y, size };
|
|
160
|
+
setRipples((prev) => [...prev, newRipple]);
|
|
161
|
+
window.setTimeout(() => {
|
|
162
|
+
setRipples((prev) => prev.filter((ripple) => ripple.id !== id));
|
|
163
|
+
}, 600);
|
|
164
|
+
}
|
|
165
|
+
onClick?.(event);
|
|
166
|
+
};
|
|
167
|
+
// Determinar si es una ruta externa (http/https) o interna
|
|
168
|
+
const isExternal = to.startsWith("http://") || to.startsWith("https://") || to.startsWith("mailto:") || to.startsWith("tel:");
|
|
169
|
+
// Combinar estilos inline - agregar outline: none para asegurar que no aparezca
|
|
170
|
+
const combinedStyles = {
|
|
171
|
+
...inlineStyles,
|
|
172
|
+
outline: "none",
|
|
173
|
+
outlineWidth: "0",
|
|
174
|
+
outlineStyle: "none",
|
|
175
|
+
outlineOffset: "0",
|
|
176
|
+
WebkitTapHighlightColor: "transparent",
|
|
177
|
+
boxShadow: "none",
|
|
178
|
+
};
|
|
179
|
+
const linkProps = {
|
|
180
|
+
className: classes,
|
|
181
|
+
style: combinedStyles,
|
|
182
|
+
onClick: handleClick,
|
|
183
|
+
onFocus: (e) => {
|
|
184
|
+
e.currentTarget.style.outline = "none";
|
|
185
|
+
e.currentTarget.style.outlineWidth = "0";
|
|
186
|
+
e.currentTarget.style.outlineStyle = "none";
|
|
187
|
+
e.currentTarget.style.outlineOffset = "0";
|
|
188
|
+
e.currentTarget.style.boxShadow = "none";
|
|
189
|
+
},
|
|
190
|
+
onBlur: (e) => {
|
|
191
|
+
e.currentTarget.style.outline = "none";
|
|
192
|
+
e.currentTarget.style.outlineWidth = "0";
|
|
193
|
+
e.currentTarget.style.outlineStyle = "none";
|
|
194
|
+
e.currentTarget.style.outlineOffset = "0";
|
|
195
|
+
e.currentTarget.style.boxShadow = "none";
|
|
196
|
+
},
|
|
197
|
+
onKeyDown: (e) => {
|
|
198
|
+
// Eliminar outline cuando se presiona cualquier tecla
|
|
199
|
+
if (e.key === "Tab" || e.key === "Enter" || e.key === " ") {
|
|
200
|
+
e.currentTarget.style.outline = "none";
|
|
201
|
+
e.currentTarget.style.outlineWidth = "0";
|
|
202
|
+
e.currentTarget.style.outlineStyle = "none";
|
|
203
|
+
e.currentTarget.style.outlineOffset = "0";
|
|
204
|
+
e.currentTarget.style.boxShadow = "none";
|
|
205
|
+
}
|
|
206
|
+
},
|
|
207
|
+
onMouseEnter: (e) => {
|
|
208
|
+
if (variant === "primary") {
|
|
209
|
+
if (bg) {
|
|
210
|
+
const hoverBg = darkenColor(getColorValue(bg) || bg, 15);
|
|
211
|
+
e.currentTarget.style.backgroundColor = hoverBg;
|
|
212
|
+
}
|
|
213
|
+
else if (needsInlineStyles) {
|
|
214
|
+
const hoverBg = getCSSVariable(`--color-${color}-dark`);
|
|
215
|
+
e.currentTarget.style.backgroundColor = hoverBg;
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
},
|
|
219
|
+
onMouseLeave: (e) => {
|
|
220
|
+
if (variant === "primary") {
|
|
221
|
+
if (bg) {
|
|
222
|
+
e.currentTarget.style.backgroundColor = getColorValue(bg) || bg;
|
|
223
|
+
}
|
|
224
|
+
else if (needsInlineStyles) {
|
|
225
|
+
e.currentTarget.style.backgroundColor = getCSSVariable(`--color-${color}`);
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
},
|
|
229
|
+
...props,
|
|
230
|
+
};
|
|
231
|
+
if (isExternal) {
|
|
232
|
+
const externalTarget = target || "_blank";
|
|
233
|
+
return (_jsxs("a", { href: to, target: externalTarget, rel: externalTarget === "_blank" ? "noopener noreferrer" : undefined, ...linkProps, children: [_jsx("span", { className: "absolute inset-0 pointer-events-none", children: ripples.map((ripple) => (_jsx("span", { className: "absolute rounded-full opacity-40 flysoft-button-ripple", style: {
|
|
234
|
+
top: ripple.y,
|
|
235
|
+
left: ripple.x,
|
|
236
|
+
width: ripple.size,
|
|
237
|
+
height: ripple.size,
|
|
238
|
+
backgroundColor: rippleColor,
|
|
239
|
+
} }, ripple.id))) }), _jsxs("span", { className: "relative inline-flex items-center justify-center", children: [icon && iconPosition === "left" && renderIcon(), children, icon && iconPosition === "right" && renderIcon()] })] }));
|
|
240
|
+
}
|
|
241
|
+
return (_jsxs(Link, { to: to, ...linkProps, children: [_jsx("span", { className: "absolute inset-0 pointer-events-none", children: ripples.map((ripple) => (_jsx("span", { className: "absolute rounded-full opacity-40 flysoft-button-ripple", style: {
|
|
242
|
+
top: ripple.y,
|
|
243
|
+
left: ripple.x,
|
|
244
|
+
width: ripple.size,
|
|
245
|
+
height: ripple.size,
|
|
246
|
+
backgroundColor: rippleColor,
|
|
247
|
+
} }, ripple.id))) }), _jsxs("span", { className: "relative inline-flex items-center justify-center", children: [icon && iconPosition === "left" && renderIcon(), children, icon && iconPosition === "right" && renderIcon()] })] }));
|
|
248
|
+
};
|
|
@@ -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;
|
|
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,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,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"}
|
|
@@ -4,6 +4,7 @@ import { useFormContext } from "react-hook-form";
|
|
|
4
4
|
import { Input } from "./Input";
|
|
5
5
|
import { Button } from "./Button";
|
|
6
6
|
import { Dialog } from "../utils/Dialog";
|
|
7
|
+
import { normalizeIconClass } from "../utils/iconUtils";
|
|
7
8
|
function SearchSelectInputInner({ value, onChange, onSearchPromiseFn, onSingleSearchPromiseFn, onSelectOption, dialogTitle = "Seleccione una opción", searchButtonPosition = "right", noResultsText = "Sin resultados", getOptionLabel, getOptionValue, getOptionDescription, renderOption, className = "", size = "md", ...inputProps }, ref) {
|
|
8
9
|
// Extraer onBlur de inputProps para manejarlo por separado
|
|
9
10
|
const { onBlur: registerOnBlur, ...restInputProps } = inputProps;
|
|
@@ -949,11 +950,11 @@ function SearchSelectInputInner({ value, onChange, onSearchPromiseFn, onSingleSe
|
|
|
949
950
|
e.preventDefault();
|
|
950
951
|
handleDialogSearch();
|
|
951
952
|
}
|
|
952
|
-
}, icon: "fa-search", iconPosition: "right", onIconClick: dialogSearchText.trim() ? handleDialogSearch : undefined, size: size, placeholder: "Buscar...", autoFocus: true }), isLoading ? (_jsx("div", { className: "flex items-center justify-center py-8", children: _jsx("i", { className: "
|
|
953
|
+
}, icon: "fa-search", iconPosition: "right", onIconClick: dialogSearchText.trim() ? handleDialogSearch : undefined, size: size, placeholder: "Buscar...", autoFocus: true }), isLoading ? (_jsx("div", { className: "flex items-center justify-center py-8", children: _jsx("i", { className: "fal fa-spinner fa-spin text-2xl text-[var(--color-primary)]" }) })) : options.length > 0 ? (_jsx("ul", { className: "space-y-1 max-h-96 overflow-y-auto", children: options.map((option, index) => {
|
|
953
954
|
const label = labelGetter(option);
|
|
954
955
|
const description = descriptionGetter(option);
|
|
955
956
|
const anyOption = option;
|
|
956
|
-
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:
|
|
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 &&
|
|
957
958
|
description !== null && (_jsx("span", { className: "text-xs text-[var(--color-text-secondary)]", children: description }))] })] })) }, String(valueGetter(option) ?? label ?? index)));
|
|
958
959
|
}) })) : hasSearched ? (_jsx("div", { className: "px-3 py-8 text-center text-sm text-[var(--color-text-secondary)]", children: noResultsText })) : null] }), dialogActions: _jsx(Button, { variant: "outline", onClick: () => setIsDialogOpen(false), children: "Cerrar" }), onClose: () => setIsDialogOpen(false), closeOnOverlayClick: true })] }));
|
|
959
960
|
}
|
|
@@ -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;
|
|
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"}
|
|
@@ -4,6 +4,7 @@ import { useFormContext } from "react-hook-form";
|
|
|
4
4
|
import { Input } from "./Input";
|
|
5
5
|
import { Button } from "./Button";
|
|
6
6
|
import { Dialog, Loader } from "../utils";
|
|
7
|
+
import { normalizeIconClass } from "../utils/iconUtils";
|
|
7
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) {
|
|
8
9
|
const [inputText, setInputText] = useState("");
|
|
9
10
|
const [dialogInputText, setDialogInputText] = useState("");
|
|
@@ -249,7 +250,7 @@ const SearchSelectInputInner = React.forwardRef(function SearchSelectInput({ val
|
|
|
249
250
|
const label = labelGetter(option);
|
|
250
251
|
const description = descriptionGetter(option);
|
|
251
252
|
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:
|
|
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 &&
|
|
253
254
|
description !== null && (_jsx("span", { className: "text-xs text-[var(--color-text-secondary)]", children: description }))] })] })) }, String(valueGetter(option) ?? label ?? index)));
|
|
254
255
|
}) }) })) : (_jsx("div", { className: "px-3 py-8 text-center text-sm text-[var(--color-text-secondary)]", children: noResultsText })) }) })] }));
|
|
255
256
|
};
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export { Button } from "./Button";
|
|
2
|
+
export { LinkButton } from "./LinkButton";
|
|
2
3
|
export { Input } from "./Input";
|
|
3
4
|
export { AutocompleteInput } from "./AutocompleteInput";
|
|
4
5
|
export { SearchSelectInput } from "./SearchSelectInput-OLD";
|
|
@@ -8,6 +9,7 @@ export { Pagination } from "./Pagination";
|
|
|
8
9
|
export { Checkbox } from "./Checkbox";
|
|
9
10
|
export { RadioButtonGroup } from "./RadioButtonGroup";
|
|
10
11
|
export type { ButtonProps } from "./Button";
|
|
12
|
+
export type { LinkButtonProps } from "./LinkButton";
|
|
11
13
|
export type { InputProps } from "./Input";
|
|
12
14
|
export type { AutocompleteInputProps, AutocompleteOption, } from "./AutocompleteInput";
|
|
13
15
|
export type { SearchSelectInputProps, SearchSelectOption, } from "./SearchSelectInput-OLD";
|
|
@@ -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,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
|
+
{"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"}
|
|
@@ -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
|
+
};
|
|
@@ -206,5 +206,5 @@ export const AppLayout = ({ navbar, leftDrawer, children, className = "", }) =>
|
|
|
206
206
|
const mobileDrawerContentClasses = `
|
|
207
207
|
flex-1 overflow-y-auto scrollbar-hide
|
|
208
208
|
`;
|
|
209
|
-
return (_jsxs("div", { className: layoutClasses, children: [fullWidthNavbar ? (_jsxs(_Fragment, { children: [shouldShowNavbar && (_jsx("nav", { className: navbarClasses, style: navbarStyle, children: _jsxs("div", { className: navbarContentClasses, style: navbarContentStyle, children: [_jsxs("div", { className: navbarLeftClasses, children: [shouldShowMobileDrawer && hasLeftDrawerContent && (_jsx("div", { className: "pr-4 lg:px-4 md:px-3", children: _jsx(Button, { variant: "ghost", icon: "fa-bars", onClick: handleMobileDrawerToggle, "aria-label": "Abrir men\u00FA" }) })), navBarLeftNode && (_jsx("div", { children: typeof navBarLeftNode === "string" ? (_jsx("span", { children: navBarLeftNode })) : (navBarLeftNode) }))] }), navBarRightNode && (_jsx("div", { className: navbarRightClasses, children: typeof navBarRightNode === "string" ? (_jsx("span", { children: navBarRightNode })) : (navBarRightNode) }))] }) })), _jsxs("div", { className: mainClasses, style: mainStyle, children: [shouldShowDesktopDrawer && (_jsxs("aside", { className: leftDrawerClasses, style: leftDrawerStyle, children: [leftDrawerHeader && (_jsx("div", { className: leftDrawerHeaderClasses, children: leftDrawerHeader })), leftDrawerContent && (_jsx("div", { className: leftDrawerContentClasses, children: leftDrawerContent })), leftDrawerFooter && (_jsx("div", { className: leftDrawerFooterClasses, children: leftDrawerFooter }))] })), _jsx("main", { ref: contentRef, className: contentClasses, children: children })] })] })) : (_jsx(_Fragment, { children: _jsxs("div", { className: contentWrapperClasses, children: [shouldShowDesktopDrawer && (_jsxs("aside", { className: leftDrawerClasses, style: leftDrawerStyle, children: [leftDrawerHeader && (_jsx("div", { className: leftDrawerHeaderClasses, children: leftDrawerHeader })), leftDrawerContent && (_jsx("div", { className: leftDrawerContentClasses, children: leftDrawerContent })), leftDrawerFooter && (_jsx("div", { className: leftDrawerFooterClasses, children: leftDrawerFooter }))] })), _jsxs("div", { className: drawerAndContentClasses, style: drawerAndContentStyle, children: [shouldShowNavbar && (_jsx("nav", { className: navbarClasses, style: navbarStyle, children: _jsxs("div", { className: navbarContentClasses, style: navbarContentStyle, children: [_jsxs("div", { className: navbarLeftClasses, children: [shouldShowMobileDrawer && hasLeftDrawerContent && (_jsx("div", { className: "pr-4
|
|
209
|
+
return (_jsxs("div", { className: layoutClasses, children: [fullWidthNavbar ? (_jsxs(_Fragment, { children: [shouldShowNavbar && (_jsx("nav", { className: navbarClasses, style: navbarStyle, children: _jsxs("div", { className: navbarContentClasses, style: navbarContentStyle, children: [_jsxs("div", { className: navbarLeftClasses, children: [shouldShowMobileDrawer && hasLeftDrawerContent && (_jsx("div", { className: "absolute top-0 right-0 pr-4 lg:px-4 md:px-3", children: _jsx(Button, { variant: "ghost", icon: "fa-bars", onClick: handleMobileDrawerToggle, "aria-label": "Abrir men\u00FA" }) })), navBarLeftNode && (_jsx("div", { children: typeof navBarLeftNode === "string" ? (_jsx("span", { children: navBarLeftNode })) : (navBarLeftNode) }))] }), navBarRightNode && (_jsx("div", { className: navbarRightClasses, children: typeof navBarRightNode === "string" ? (_jsx("span", { children: navBarRightNode })) : (navBarRightNode) }))] }) })), _jsxs("div", { className: mainClasses, style: mainStyle, children: [shouldShowDesktopDrawer && (_jsxs("aside", { className: leftDrawerClasses, style: leftDrawerStyle, children: [leftDrawerHeader && (_jsx("div", { className: leftDrawerHeaderClasses, children: leftDrawerHeader })), leftDrawerContent && (_jsx("div", { className: leftDrawerContentClasses, children: leftDrawerContent })), leftDrawerFooter && (_jsx("div", { className: leftDrawerFooterClasses, children: leftDrawerFooter }))] })), _jsx("main", { ref: contentRef, className: contentClasses, children: children })] })] })) : (_jsx(_Fragment, { children: _jsxs("div", { className: contentWrapperClasses, children: [shouldShowDesktopDrawer && (_jsxs("aside", { className: leftDrawerClasses, style: leftDrawerStyle, children: [leftDrawerHeader && (_jsx("div", { className: leftDrawerHeaderClasses, children: leftDrawerHeader })), leftDrawerContent && (_jsx("div", { className: leftDrawerContentClasses, children: leftDrawerContent })), leftDrawerFooter && (_jsx("div", { className: leftDrawerFooterClasses, children: leftDrawerFooter }))] })), _jsxs("div", { className: drawerAndContentClasses, style: drawerAndContentStyle, children: [shouldShowNavbar && (_jsx("nav", { className: navbarClasses, style: navbarStyle, children: _jsxs("div", { className: navbarContentClasses, style: navbarContentStyle, children: [_jsxs("div", { className: navbarLeftClasses, children: [shouldShowMobileDrawer && hasLeftDrawerContent && (_jsx("div", { className: "pr-4 px-2", children: _jsx(Button, { variant: "ghost", icon: "fa-bars", onClick: handleMobileDrawerToggle, "aria-label": "Abrir men\u00FA" }) })), navBarLeftNode && (_jsx("div", { children: typeof navBarLeftNode === "string" ? (_jsx("span", { children: navBarLeftNode })) : (navBarLeftNode) }))] }), navBarRightNode && (_jsx("div", { className: navbarRightClasses, children: typeof navBarRightNode === "string" ? (_jsx("span", { children: navBarRightNode })) : (navBarRightNode) }))] }) })), _jsx("main", { ref: contentRef, className: contentClasses, children: children })] })] }) })), shouldShowMobileDrawer && hasLeftDrawerContent && isMobileDrawerOpen && (_jsx("div", { className: overlayClasses, onClick: handleOverlayClick })), shouldShowMobileDrawer && hasLeftDrawerContent && (_jsxs("aside", { className: `${mobileDrawerBaseClasses} ${isMobileDrawerOpen ? mobileDrawerOpenClasses : ""}`, style: mobileDrawerStyle, children: [_jsxs("div", { className: "flex-shrink-0 flex items-center justify-between", children: [leftDrawerHeader ? (_jsx("div", { className: "flex-1", children: leftDrawerHeader })) : (_jsx("div", { className: "flex-1" })), _jsx("div", { className: "absolute top-3 right-2", children: _jsx(Button, { variant: "ghost", icon: "fa-times", onClick: handleMobileDrawerToggle, "aria-label": "Cerrar men\u00FA" }) })] }), leftDrawerContent && (_jsx("div", { className: mobileDrawerContentClasses, children: leftDrawerContent })), leftDrawerFooter && (_jsx("div", { className: "flex-shrink-0", children: leftDrawerFooter }))] }))] }));
|
|
210
210
|
};
|
|
@@ -2,14 +2,19 @@ import React from "react";
|
|
|
2
2
|
export interface CardProps {
|
|
3
3
|
title?: string | React.ReactNode;
|
|
4
4
|
subtitle?: string | React.ReactNode;
|
|
5
|
-
children
|
|
5
|
+
children?: React.ReactNode;
|
|
6
6
|
className?: string;
|
|
7
7
|
/**
|
|
8
|
-
* Acciones para el header de la tarjeta.
|
|
8
|
+
* Acciones para el header de la tarjeta. Se muestra directamente el ReactNode proporcionado.
|
|
9
9
|
*/
|
|
10
|
-
headerActions?:
|
|
10
|
+
headerActions?: React.ReactNode;
|
|
11
11
|
footer?: React.ReactNode;
|
|
12
12
|
variant?: "default" | "elevated" | "outlined";
|
|
13
|
+
/**
|
|
14
|
+
* Si es true, las headerActions siempre se muestran. Si es false, solo se muestran al hacer hover (en pantallas grandes).
|
|
15
|
+
* En resoluciones md e inferiores, siempre se muestran sin importar este valor.
|
|
16
|
+
*/
|
|
17
|
+
alwaysDisplayHeaderActions?: boolean;
|
|
13
18
|
}
|
|
14
19
|
export declare const Card: React.FC<CardProps>;
|
|
15
20
|
//# sourceMappingURL=Card.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Card.d.ts","sourceRoot":"","sources":["../../../src/components/layout/Card.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"Card.d.ts","sourceRoot":"","sources":["../../../src/components/layout/Card.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,MAAM,WAAW,SAAS;IACxB,KAAK,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC,SAAS,CAAC;IACjC,QAAQ,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC,SAAS,CAAC;IACpC,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC3B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;OAEG;IACH,aAAa,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAChC,MAAM,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACzB,OAAO,CAAC,EAAE,SAAS,GAAG,UAAU,GAAG,UAAU,CAAC;IAC9C;;;OAGG;IACH,0BAA0B,CAAC,EAAE,OAAO,CAAC;CACtC;AAED,eAAO,MAAM,IAAI,EAAE,KAAK,CAAC,EAAE,CAAC,SAAS,CA8GpC,CAAC"}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import React from "react";
|
|
3
|
-
|
|
4
|
-
export const Card = ({ title, subtitle, children, className = "", headerActions, footer, variant = "default", }) => {
|
|
3
|
+
export const Card = ({ title, subtitle, children, className = "", headerActions, footer, variant = "default", alwaysDisplayHeaderActions = false, }) => {
|
|
5
4
|
// Separar clases de background del className
|
|
6
5
|
const classArray = className.trim().split(/\s+/).filter(Boolean);
|
|
7
6
|
const bgClasses = [];
|
|
@@ -26,22 +25,11 @@ export const Card = ({ title, subtitle, children, className = "", headerActions,
|
|
|
26
25
|
outlined: `border-[var(--color-gray-300)]`,
|
|
27
26
|
};
|
|
28
27
|
const classes = `${baseClasses} ${variantClasses[variant]} ${otherClasses.join(" ")}`;
|
|
29
|
-
// Convertir array de ReactNode a array de ActionItem para DropdownMenu
|
|
30
|
-
const convertActionsToOptions = (actions) => {
|
|
31
|
-
return actions.map((action, index) => ({
|
|
32
|
-
id: index,
|
|
33
|
-
content: (_jsx("div", { onClick: (e) => {
|
|
34
|
-
// Detener la propagación para que el onClick del DropdownMenu no interfiera
|
|
35
|
-
e.stopPropagation();
|
|
36
|
-
}, children: action })),
|
|
37
|
-
}));
|
|
38
|
-
};
|
|
39
|
-
const headerActionsArray = headerActions?.();
|
|
40
|
-
const hasHeaderActions = headerActionsArray && headerActionsArray.length > 0;
|
|
41
28
|
const [isHovered, setIsHovered] = React.useState(false);
|
|
42
29
|
const [isLargeScreen, setIsLargeScreen] = React.useState(false);
|
|
43
30
|
React.useEffect(() => {
|
|
44
31
|
const checkScreenSize = () => {
|
|
32
|
+
// md breakpoint en Tailwind es 768px, así que lg es 1024px
|
|
45
33
|
setIsLargeScreen(window.innerWidth >= 1024);
|
|
46
34
|
};
|
|
47
35
|
checkScreenSize();
|
|
@@ -50,9 +38,20 @@ export const Card = ({ title, subtitle, children, className = "", headerActions,
|
|
|
50
38
|
window.removeEventListener("resize", checkScreenSize);
|
|
51
39
|
};
|
|
52
40
|
}, []);
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
41
|
+
// Determinar la opacidad de las headerActions
|
|
42
|
+
const getHeaderActionsOpacity = () => {
|
|
43
|
+
if (!headerActions)
|
|
44
|
+
return 0;
|
|
45
|
+
// En pantallas pequeñas (md e inferiores) siempre se muestran
|
|
46
|
+
if (!isLargeScreen)
|
|
47
|
+
return 1;
|
|
48
|
+
// Si alwaysDisplayHeaderActions es true, siempre se muestran
|
|
49
|
+
if (alwaysDisplayHeaderActions)
|
|
50
|
+
return 1;
|
|
51
|
+
// Si es false y pantalla grande, solo al hacer hover
|
|
52
|
+
return isHovered ? 1 : 0;
|
|
53
|
+
};
|
|
54
|
+
return (_jsxs("div", { className: `${classes} relative`, onMouseEnter: () => setIsHovered(true), onMouseLeave: () => setIsHovered(false), children: [(title || subtitle || headerActions) && (_jsx("div", { className: "px-6 pt-4", children: _jsxs("div", { className: "flex items-center justify-between", children: [_jsxs("div", { children: [title && (_jsx("h3", { className: "text-lg font-semibold text-[var(--color-text-primary)]", children: title })), subtitle && (_jsx("div", { className: "text-sm text-[var(--color-text-secondary)] mt-1", children: subtitle }))] }), headerActions && (_jsx("div", { className: "flex items-center transition-opacity", style: {
|
|
55
|
+
opacity: getHeaderActionsOpacity(),
|
|
56
|
+
}, children: headerActions }))] }) })), children && _jsx("div", { className: "px-6 py-4", children: children }), footer && _jsx("div", { className: "px-6 pb-4", children: footer })] }));
|
|
58
57
|
};
|
|
@@ -12,4 +12,6 @@ export { TabPanel } from "./TabPanel";
|
|
|
12
12
|
export type { TabPanelProps } from "./TabPanel";
|
|
13
13
|
export { DataTable } from "./DataTable";
|
|
14
14
|
export type { DataTableProps, DataTableColumn } from "./DataTable";
|
|
15
|
+
export { Accordion } from "./Accordion";
|
|
16
|
+
export type { AccordionProps } from "./Accordion";
|
|
15
17
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/layout/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAC9B,YAAY,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AACxC,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,YAAY,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAClD,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,YAAY,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AACpD,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,YAAY,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAClD,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,YAAY,EAAE,cAAc,EAAE,GAAG,EAAE,MAAM,aAAa,CAAC;AACvD,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,YAAY,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAChD,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,YAAY,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/layout/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAC9B,YAAY,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AACxC,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,YAAY,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAClD,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,YAAY,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AACpD,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,YAAY,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAClD,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,YAAY,EAAE,cAAc,EAAE,GAAG,EAAE,MAAM,aAAa,CAAC;AACvD,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,YAAY,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAChD,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,YAAY,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AACnE,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,YAAY,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Badge.d.ts","sourceRoot":"","sources":["../../../src/components/utils/Badge.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"Badge.d.ts","sourceRoot":"","sources":["../../../src/components/utils/Badge.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAkC1B,MAAM,WAAW,UAAU;IACzB,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,OAAO,CAAC,EAAE,SAAS,GAAG,WAAW,GAAG,SAAS,GAAG,SAAS,GAAG,QAAQ,GAAG,MAAM,CAAC;IAC9E,IAAI,CAAC,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;IAC1B,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,YAAY,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IAChC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,UAAU,CAAC,WAAW,CAAC,KAAK,IAAI,CAAC;CAC1D;AAED,eAAO,MAAM,KAAK,EAAE,KAAK,CAAC,EAAE,CAAC,UAAU,CA2KtC,CAAC"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import React from "react";
|
|
3
|
+
import { normalizeIconClass } from "./iconUtils";
|
|
3
4
|
// Función helper para convertir nombres de colores comunes a valores CSS válidos
|
|
4
5
|
const getColorValue = (color) => {
|
|
5
6
|
if (!color)
|
|
@@ -109,8 +110,8 @@ export const Badge = ({ children, variant = "primary", size = "md", rounded = fa
|
|
|
109
110
|
return null;
|
|
110
111
|
// Si hay onClick y hay iconos, el onClick se aplica solo a los iconos
|
|
111
112
|
const iconClasses = onClick
|
|
112
|
-
?
|
|
113
|
-
:
|
|
113
|
+
? `${normalizeIconClass(icon)} ${iconSizeClasses} cursor-pointer`
|
|
114
|
+
: `${normalizeIconClass(icon)} ${iconSizeClasses}`;
|
|
114
115
|
return (_jsx("span", { className: iconPaddingClasses, children: _jsx("i", { className: iconClasses, "aria-hidden": !iconLabel, "aria-label": iconLabel, onClick: onClick, role: onClick ? "button" : undefined, tabIndex: onClick ? 0 : undefined, onKeyDown: onClick
|
|
115
116
|
? (e) => {
|
|
116
117
|
if (e.key === "Enter" || e.key === " ") {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Dialog.d.ts","sourceRoot":"","sources":["../../../src/components/utils/Dialog.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAoB,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"Dialog.d.ts","sourceRoot":"","sources":["../../../src/components/utils/Dialog.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAoB,MAAM,OAAO,CAAC;AAGzC,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,OAAO,CAAC;IAChB,KAAK,EAAE,KAAK,CAAC,SAAS,CAAC;IACvB,UAAU,EAAE,KAAK,CAAC,SAAS,CAAC;IAC5B,aAAa,EAAE,KAAK,CAAC,SAAS,CAAC;IAC/B,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,mBAAmB,CAAC,EAAE,OAAO,CAAC;CAC/B;AAED,eAAO,MAAM,MAAM,EAAE,KAAK,CAAC,EAAE,CAAC,WAAW,CAyGxC,CAAC"}
|