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.
- package/dist/App.d.ts.map +1 -1
- package/dist/App.js +20 -4
- package/dist/components/form-controls/AutocompleteInput.d.ts +11 -3
- package/dist/components/form-controls/AutocompleteInput.d.ts.map +1 -1
- package/dist/components/form-controls/AutocompleteInput.js +410 -31
- package/dist/components/form-controls/Button.js +1 -1
- package/dist/components/form-controls/Checkbox.d.ts +14 -0
- package/dist/components/form-controls/Checkbox.d.ts.map +1 -0
- package/dist/components/form-controls/Checkbox.js +77 -0
- package/dist/components/form-controls/DateInput.d.ts +20 -4
- package/dist/components/form-controls/DateInput.d.ts.map +1 -1
- package/dist/components/form-controls/DateInput.js +425 -70
- package/dist/components/form-controls/DatePicker.d.ts +4 -3
- package/dist/components/form-controls/DatePicker.d.ts.map +1 -1
- package/dist/components/form-controls/DatePicker.js +26 -30
- package/dist/components/form-controls/Input.d.ts +10 -1
- package/dist/components/form-controls/Input.d.ts.map +1 -1
- package/dist/components/form-controls/Input.js +16 -10
- package/dist/components/form-controls/Pagination.d.ts +1 -0
- package/dist/components/form-controls/Pagination.d.ts.map +1 -1
- package/dist/components/form-controls/Pagination.js +3 -40
- package/dist/components/form-controls/RadioButtonGroup.d.ts +62 -0
- package/dist/components/form-controls/RadioButtonGroup.d.ts.map +1 -0
- package/dist/components/form-controls/RadioButtonGroup.js +220 -0
- package/dist/components/form-controls/SearchSelectInput-OLD.d.ts +68 -0
- package/dist/components/form-controls/SearchSelectInput-OLD.d.ts.map +1 -0
- package/dist/components/form-controls/SearchSelectInput-OLD.js +962 -0
- package/dist/components/form-controls/SearchSelectInput.d.ts +70 -0
- package/dist/components/form-controls/SearchSelectInput.d.ts.map +1 -0
- package/dist/components/form-controls/SearchSelectInput.js +335 -0
- package/dist/components/form-controls/index.d.ts +7 -1
- package/dist/components/form-controls/index.d.ts.map +1 -1
- package/dist/components/form-controls/index.js +3 -0
- package/dist/components/layout/AppLayout.d.ts +3 -2
- package/dist/components/layout/AppLayout.d.ts.map +1 -1
- package/dist/components/layout/AppLayout.js +104 -31
- package/dist/components/layout/Card.d.ts +4 -1
- package/dist/components/layout/Card.d.ts.map +1 -1
- package/dist/components/layout/Card.js +30 -1
- package/dist/components/layout/Collection.js +1 -1
- package/dist/components/layout/DataTable.d.ts +29 -0
- package/dist/components/layout/DataTable.d.ts.map +1 -0
- package/dist/components/layout/DataTable.js +165 -0
- 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/Avatar.d.ts +49 -0
- package/dist/components/utils/Avatar.d.ts.map +1 -0
- package/dist/components/utils/Avatar.js +93 -0
- package/dist/components/utils/Badge.d.ts +3 -0
- package/dist/components/utils/Badge.d.ts.map +1 -1
- package/dist/components/utils/Badge.js +130 -26
- package/dist/components/utils/Dialog.d.ts.map +1 -1
- package/dist/components/utils/Dialog.js +5 -1
- package/dist/components/utils/DropdownMenu.d.ts +25 -0
- package/dist/components/utils/DropdownMenu.d.ts.map +1 -0
- package/dist/components/utils/DropdownMenu.js +145 -0
- package/dist/components/utils/Filter.d.ts +57 -0
- package/dist/components/utils/Filter.d.ts.map +1 -0
- package/dist/components/utils/Filter.js +580 -0
- package/dist/components/utils/FiltersDialog.d.ts +21 -0
- package/dist/components/utils/FiltersDialog.d.ts.map +1 -0
- package/dist/components/utils/FiltersDialog.js +104 -0
- package/dist/components/utils/Loader.js +1 -1
- package/dist/components/utils/RoadMap.d.ts +59 -0
- package/dist/components/utils/RoadMap.d.ts.map +1 -0
- package/dist/components/utils/RoadMap.js +138 -0
- package/dist/components/utils/Snackbar.d.ts +13 -0
- package/dist/components/utils/Snackbar.d.ts.map +1 -0
- package/dist/components/utils/Snackbar.js +121 -0
- package/dist/components/utils/SnackbarContainer.d.ts +7 -0
- package/dist/components/utils/SnackbarContainer.d.ts.map +1 -0
- package/dist/components/utils/SnackbarContainer.js +25 -0
- package/dist/components/utils/index.d.ts +12 -0
- package/dist/components/utils/index.d.ts.map +1 -1
- package/dist/components/utils/index.js +6 -0
- package/dist/contexts/AppLayoutContext.d.ts +40 -0
- package/dist/contexts/AppLayoutContext.d.ts.map +1 -0
- package/dist/contexts/AppLayoutContext.js +98 -0
- package/dist/contexts/ListCrudContext.d.ts +29 -0
- package/dist/contexts/ListCrudContext.d.ts.map +1 -0
- package/dist/contexts/ListCrudContext.js +209 -0
- package/dist/contexts/SnackbarContext.d.ts +26 -0
- package/dist/contexts/SnackbarContext.d.ts.map +1 -0
- package/dist/contexts/SnackbarContext.js +34 -0
- package/dist/contexts/index.d.ts +6 -0
- package/dist/contexts/index.d.ts.map +1 -1
- package/dist/contexts/index.js +6 -0
- package/dist/contexts/presets.js +6 -6
- package/dist/docs/AuthDocs.tsx/AuthDocsContent.js +3 -1
- package/dist/docs/AvatarDocs.d.ts +4 -0
- package/dist/docs/AvatarDocs.d.ts.map +1 -0
- package/dist/docs/AvatarDocs.js +7 -0
- package/dist/docs/BadgeDocs.d.ts.map +1 -1
- package/dist/docs/BadgeDocs.js +4 -2
- package/dist/docs/CardDocs.d.ts.map +1 -1
- package/dist/docs/CardDocs.js +7 -1
- package/dist/docs/CheckboxDocs.d.ts +4 -0
- package/dist/docs/CheckboxDocs.d.ts.map +1 -0
- package/dist/docs/CheckboxDocs.js +7 -0
- package/dist/docs/DataTableDocs.d.ts +4 -0
- package/dist/docs/DataTableDocs.d.ts.map +1 -0
- package/dist/docs/DataTableDocs.js +244 -0
- package/dist/docs/DateInputDocs.d.ts +1 -0
- package/dist/docs/DateInputDocs.d.ts.map +1 -1
- package/dist/docs/DateInputDocs.js +7 -9
- package/dist/docs/DatePickerDocs.d.ts +1 -0
- package/dist/docs/DatePickerDocs.d.ts.map +1 -1
- package/dist/docs/DatePickerDocs.js +6 -8
- package/dist/docs/DocAdmin.d.ts +4 -0
- package/dist/docs/DocAdmin.d.ts.map +1 -0
- package/dist/docs/DocAdmin.js +68 -0
- 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 +13 -1
- package/dist/docs/DropdownMenuDocs.d.ts +4 -0
- package/dist/docs/DropdownMenuDocs.d.ts.map +1 -0
- package/dist/docs/DropdownMenuDocs.js +66 -0
- package/dist/docs/ExampleFormDocs.d.ts +4 -0
- package/dist/docs/ExampleFormDocs.d.ts.map +1 -0
- package/dist/docs/ExampleFormDocs.js +148 -0
- package/dist/docs/FilterDocs.d.ts +4 -0
- package/dist/docs/FilterDocs.d.ts.map +1 -0
- package/dist/docs/FilterDocs.js +112 -0
- package/dist/docs/InputDocs.d.ts.map +1 -1
- package/dist/docs/InputDocs.js +11 -1
- package/dist/docs/ListCrudDocs.tsx/ListCrudDocs.d.ts +11 -0
- package/dist/docs/ListCrudDocs.tsx/ListCrudDocs.d.ts.map +1 -0
- package/dist/docs/ListCrudDocs.tsx/ListCrudDocs.js +25 -0
- package/dist/docs/ListCrudDocs.tsx/ListCrudDocsContentPersonas.d.ts +2 -0
- package/dist/docs/ListCrudDocs.tsx/ListCrudDocsContentPersonas.d.ts.map +1 -0
- package/dist/docs/ListCrudDocs.tsx/ListCrudDocsContentPersonas.js +51 -0
- package/dist/docs/PaginationDocs.js +6 -6
- package/dist/docs/RadioButtonGroupDocs.d.ts +4 -0
- package/dist/docs/RadioButtonGroupDocs.d.ts.map +1 -0
- package/dist/docs/RadioButtonGroupDocs.js +46 -0
- package/dist/docs/RoadMapDocs.d.ts +4 -0
- package/dist/docs/RoadMapDocs.d.ts.map +1 -0
- package/dist/docs/RoadMapDocs.js +171 -0
- package/dist/docs/SearchSelectInputDocs.d.ts +4 -0
- package/dist/docs/SearchSelectInputDocs.d.ts.map +1 -0
- package/dist/docs/SearchSelectInputDocs.js +168 -0
- package/dist/docs/SnackbarDocs.d.ts +4 -0
- package/dist/docs/SnackbarDocs.d.ts.map +1 -0
- package/dist/docs/SnackbarDocs.js +50 -0
- package/dist/docs/TabsGroupDocs.d.ts.map +1 -1
- package/dist/docs/TabsGroupDocs.js +12 -1
- package/dist/docs/docMockServices/empresaService.d.ts +38 -0
- package/dist/docs/docMockServices/empresaService.d.ts.map +1 -0
- package/dist/docs/docMockServices/empresaService.js +116 -0
- package/dist/docs/docMockServices/index.d.ts +9 -0
- package/dist/docs/docMockServices/index.d.ts.map +1 -0
- package/dist/docs/docMockServices/index.js +8 -0
- package/dist/docs/docMockServices/initialData.d.ts +6 -0
- package/dist/docs/docMockServices/initialData.d.ts.map +1 -0
- package/dist/docs/docMockServices/initialData.js +132 -0
- package/dist/docs/docMockServices/interfaces.d.ts +26 -0
- package/dist/docs/docMockServices/interfaces.d.ts.map +1 -0
- package/dist/docs/docMockServices/interfaces.js +1 -0
- package/dist/docs/docMockServices/personaEmpresaService.d.ts +43 -0
- package/dist/docs/docMockServices/personaEmpresaService.d.ts.map +1 -0
- package/dist/docs/docMockServices/personaEmpresaService.js +113 -0
- package/dist/docs/docMockServices/personaService.d.ts +39 -0
- package/dist/docs/docMockServices/personaService.d.ts.map +1 -0
- package/dist/docs/docMockServices/personaService.js +180 -0
- package/dist/hooks/index.d.ts +2 -0
- package/dist/hooks/index.d.ts.map +1 -1
- package/dist/hooks/index.js +1 -0
- package/dist/hooks/useAsyncRequest.d.ts +17 -0
- package/dist/hooks/useAsyncRequest.d.ts.map +1 -0
- package/dist/hooks/useAsyncRequest.js +70 -0
- package/dist/index.css +1 -1
- package/dist/index.d.ts +22 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +11 -0
- package/dist/index.js.map +1 -1
- package/package.json +5 -2
|
@@ -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;AAiC1B,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,46 +1,150 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import React from "react";
|
|
3
|
-
|
|
3
|
+
// Función helper para convertir nombres de colores comunes a valores CSS válidos
|
|
4
|
+
const getColorValue = (color) => {
|
|
5
|
+
if (!color)
|
|
6
|
+
return undefined;
|
|
7
|
+
// Si ya es un valor CSS válido (hex, rgb, rgba, hsl, etc.), retornarlo
|
|
8
|
+
if (color.startsWith("#") ||
|
|
9
|
+
color.startsWith("rgb") ||
|
|
10
|
+
color.startsWith("hsl")) {
|
|
11
|
+
return color;
|
|
12
|
+
}
|
|
13
|
+
// Mapeo de nombres de colores comunes
|
|
14
|
+
const colorMap = {
|
|
15
|
+
white: "#ffffff",
|
|
16
|
+
black: "#000000",
|
|
17
|
+
"gray-800": "#1f2937",
|
|
18
|
+
"gray-700": "#374151",
|
|
19
|
+
"gray-600": "#4b5563",
|
|
20
|
+
"gray-500": "#6b7280",
|
|
21
|
+
"gray-400": "#9ca3af",
|
|
22
|
+
"gray-300": "#d1d5db",
|
|
23
|
+
"gray-200": "#e5e7eb",
|
|
24
|
+
"gray-100": "#f3f4f6",
|
|
25
|
+
"gray-50": "#f9fafb",
|
|
26
|
+
};
|
|
27
|
+
return colorMap[color.toLowerCase()] || color;
|
|
28
|
+
};
|
|
29
|
+
export const Badge = ({ children, variant = "primary", size = "md", rounded = false, className = "", icon, iconPosition = "left", iconLabel, bg, textColor, onClick, }) => {
|
|
4
30
|
const baseClasses = "inline-flex items-center font-medium font-[var(--font-default)]";
|
|
5
31
|
const variantClasses = {
|
|
6
|
-
primary: `
|
|
7
|
-
bg-[var(--color-primary-light)] text-
|
|
8
|
-
hover:bg-[var(--color-primary)] hover:text-[var(--color-primary-contrast)]
|
|
32
|
+
primary: `
|
|
33
|
+
bg-[var(--color-primary-light)] text-gray-800
|
|
9
34
|
`,
|
|
10
|
-
secondary: `
|
|
11
|
-
bg-[var(--color-secondary-light)] text-
|
|
12
|
-
hover:bg-[var(--color-secondary)] hover:text-[var(--color-secondary-contrast)]
|
|
35
|
+
secondary: `
|
|
36
|
+
bg-[var(--color-secondary-light)] text-gray-800
|
|
13
37
|
`,
|
|
14
|
-
success: `
|
|
15
|
-
bg-[var(--color-success-light)] text-
|
|
16
|
-
hover:bg-[var(--color-success)] hover:text-[var(--color-success-contrast)]
|
|
38
|
+
success: `
|
|
39
|
+
bg-[var(--color-success-light)] text-gray-800
|
|
17
40
|
`,
|
|
18
|
-
warning: `
|
|
19
|
-
bg-[var(--color-warning-light)] text-
|
|
20
|
-
hover:bg-[var(--color-warning)] hover:text-[var(--color-warning-contrast)]
|
|
41
|
+
warning: `
|
|
42
|
+
bg-[var(--color-warning-light)] text-gray-800
|
|
21
43
|
`,
|
|
22
|
-
danger: `
|
|
23
|
-
bg-[var(--color-danger-light)] text-
|
|
24
|
-
hover:bg-[var(--color-danger)] hover:text-[var(--color-danger-contrast)]
|
|
44
|
+
danger: `
|
|
45
|
+
bg-[var(--color-danger-light)] text-gray-800
|
|
25
46
|
`,
|
|
26
|
-
info: `
|
|
27
|
-
bg-[var(--color-info-light)] text-
|
|
28
|
-
hover:bg-[var(--color-info)] hover:text-[var(--color-info-contrast)]
|
|
47
|
+
info: `
|
|
48
|
+
bg-[var(--color-info-light)] text-gray-800
|
|
29
49
|
`,
|
|
30
50
|
};
|
|
31
51
|
const sizeClasses = {
|
|
32
|
-
sm: "
|
|
33
|
-
md: "
|
|
34
|
-
lg: "
|
|
52
|
+
sm: "py-0.5 text-xs",
|
|
53
|
+
md: "py-0.5 text-sm",
|
|
54
|
+
lg: "py-1 text-base",
|
|
35
55
|
};
|
|
56
|
+
// Padding horizontal: si hay icono, el badge no tiene padding, se aplica a los elementos internos
|
|
57
|
+
const horizontalPaddingClasses = icon
|
|
58
|
+
? "" // Sin padding horizontal en el badge cuando hay icono
|
|
59
|
+
: size === "sm"
|
|
60
|
+
? "px-2"
|
|
61
|
+
: size === "md"
|
|
62
|
+
? "px-2.5"
|
|
63
|
+
: "px-3";
|
|
64
|
+
// Padding para el texto: flex-1 para ocupar el espacio, padding solo en el lado opuesto al icono
|
|
65
|
+
const textPaddingClasses = icon
|
|
66
|
+
? iconPosition === "left"
|
|
67
|
+
? size === "sm"
|
|
68
|
+
? "flex-1 pr-2"
|
|
69
|
+
: size === "md"
|
|
70
|
+
? "flex-1 pr-2.5"
|
|
71
|
+
: "flex-1 pr-3"
|
|
72
|
+
: size === "sm"
|
|
73
|
+
? "flex-1 pl-2"
|
|
74
|
+
: size === "md"
|
|
75
|
+
? "flex-1 pl-2.5"
|
|
76
|
+
: "flex-1 pl-3"
|
|
77
|
+
: "";
|
|
78
|
+
// Padding para el icono: solo en el lado del borde
|
|
79
|
+
const iconPaddingClasses = icon
|
|
80
|
+
? iconPosition === "left"
|
|
81
|
+
? size === "sm"
|
|
82
|
+
? "pl-2"
|
|
83
|
+
: size === "md"
|
|
84
|
+
? "pl-2.5"
|
|
85
|
+
: "pl-3"
|
|
86
|
+
: size === "sm"
|
|
87
|
+
? "pr-2"
|
|
88
|
+
: size === "md"
|
|
89
|
+
? "pr-2.5"
|
|
90
|
+
: "pr-3"
|
|
91
|
+
: "";
|
|
36
92
|
const roundedClasses = rounded ? "rounded-full" : "rounded-md";
|
|
37
|
-
const gapClasses = icon ? "gap-2" : "";
|
|
93
|
+
const gapClasses = icon ? "gap-2" : ""; // Gap entre icono y texto cuando hay icono
|
|
38
94
|
const iconSizeClasses = size === "sm" ? "text-xs" : size === "md" ? "text-sm" : "text-base";
|
|
39
|
-
|
|
95
|
+
// Si se proporciona bg personalizado, usar estilos inline; si no, usar las clases de variante
|
|
96
|
+
const backgroundClasses = bg ? "" : variantClasses[variant];
|
|
97
|
+
// Estilos inline para colores personalizados
|
|
98
|
+
const inlineStyles = bg
|
|
99
|
+
? {
|
|
100
|
+
backgroundColor: getColorValue(bg) || bg,
|
|
101
|
+
color: getColorValue(textColor) || textColor || "#1f2937", // gray-800 por defecto
|
|
102
|
+
}
|
|
103
|
+
: {};
|
|
104
|
+
// Si hay onClick y no hay iconos, agregar cursor-pointer al badge completo
|
|
105
|
+
const cursorClasses = onClick && !icon ? "cursor-pointer" : "";
|
|
106
|
+
const classes = `${baseClasses} ${backgroundClasses} ${sizeClasses[size]} ${horizontalPaddingClasses} ${roundedClasses} ${gapClasses} ${cursorClasses} ${className}`;
|
|
40
107
|
const renderIcon = () => {
|
|
41
108
|
if (!icon)
|
|
42
109
|
return null;
|
|
43
|
-
|
|
110
|
+
// Si hay onClick y hay iconos, el onClick se aplica solo a los iconos
|
|
111
|
+
const iconClasses = onClick
|
|
112
|
+
? `fa ${icon} ${iconSizeClasses} cursor-pointer`
|
|
113
|
+
: `fa ${icon} ${iconSizeClasses}`;
|
|
114
|
+
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
|
+
? (e) => {
|
|
116
|
+
if (e.key === "Enter" || e.key === " ") {
|
|
117
|
+
e.preventDefault();
|
|
118
|
+
// Crear un evento sintético compatible con MouseEvent
|
|
119
|
+
const syntheticEvent = {
|
|
120
|
+
...e,
|
|
121
|
+
currentTarget: e.currentTarget,
|
|
122
|
+
target: e.target,
|
|
123
|
+
};
|
|
124
|
+
onClick(syntheticEvent);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
: undefined }) }));
|
|
44
128
|
};
|
|
45
|
-
|
|
129
|
+
// Si hay onClick y no hay iconos, aplicar onClick al badge completo
|
|
130
|
+
const badgeProps = onClick && !icon
|
|
131
|
+
? {
|
|
132
|
+
onClick,
|
|
133
|
+
role: "button",
|
|
134
|
+
tabIndex: 0,
|
|
135
|
+
onKeyDown: (e) => {
|
|
136
|
+
if (e.key === "Enter" || e.key === " ") {
|
|
137
|
+
e.preventDefault();
|
|
138
|
+
// Crear un evento sintético compatible con MouseEvent
|
|
139
|
+
const syntheticEvent = {
|
|
140
|
+
...e,
|
|
141
|
+
currentTarget: e.currentTarget,
|
|
142
|
+
target: e.target,
|
|
143
|
+
};
|
|
144
|
+
onClick(syntheticEvent);
|
|
145
|
+
}
|
|
146
|
+
},
|
|
147
|
+
}
|
|
148
|
+
: {};
|
|
149
|
+
return (_jsxs("span", { className: classes, style: inlineStyles, ...badgeProps, children: [icon && iconPosition === "left" && renderIcon(), _jsx("span", { className: textPaddingClasses, children: children }), icon && iconPosition === "right" && renderIcon()] }));
|
|
46
150
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Dialog.d.ts","sourceRoot":"","sources":["../../../src/components/utils/Dialog.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAoB,MAAM,OAAO,CAAC;AAEzC,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,
|
|
1
|
+
{"version":3,"file":"Dialog.d.ts","sourceRoot":"","sources":["../../../src/components/utils/Dialog.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAoB,MAAM,OAAO,CAAC;AAEzC,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"}
|
|
@@ -35,5 +35,9 @@ export const Dialog = ({ isOpen, title, dialogBody, dialogActions, onClose, clos
|
|
|
35
35
|
onClose();
|
|
36
36
|
}
|
|
37
37
|
};
|
|
38
|
-
return (_jsxs("div", { className: "fixed inset-0 z-[2000] flex items-center justify-center p-4", role: "dialog", "aria-modal": "true", "aria-labelledby": "dialog-title", children: [_jsx("div", { className: "absolute inset-0 bg-black/50 backdrop-blur-sm", onClick: handleOverlayClick }), _jsxs("div", { className: "relative w-auto max-w-lg min-w-[400px] bg-[var(--color-bg-default)] rounded-lg shadow-[var(--shadow-xl)] border border-[var(--color-border-default)] font-[var(--font-default)] max-h-[90vh] flex flex-col", onClick: (e) => e.stopPropagation(), children: [_jsxs("div", { className: "flex items-center justify-between px-6 py-4 border-b border-[var(--color-border-default)]", children: [_jsx("h2", { id: "dialog-title", className: "text-lg font-semibold text-[var(--color-text-primary)]", children: title }), onClose && (_jsx("button", { onClick: onClose, className: "ml-4 p-1 rounded-md text-[var(--color-text-secondary)] hover:text-[var(--color-text-primary)] hover:bg-[var(--color-bg-hover)] transition-colors cursor-pointer", "aria-label": "Cerrar dialog", children: _jsx("i", { className: "fa fa-times" }) }))] }), _jsx("div", { className: "px-6 py-4
|
|
38
|
+
return (_jsxs("div", { className: "fixed inset-0 z-[2000] flex items-center justify-center p-4", role: "dialog", "aria-modal": "true", "aria-labelledby": "dialog-title", children: [_jsx("div", { className: "absolute inset-0 bg-black/50 backdrop-blur-sm", onClick: handleOverlayClick }), _jsxs("div", { className: "relative w-auto max-w-lg min-w-[400px] bg-[var(--color-bg-default)] rounded-lg shadow-[var(--shadow-xl)] border border-[var(--color-border-default)] font-[var(--font-default)] max-h-[90vh] flex flex-col", onClick: (e) => e.stopPropagation(), style: { overflow: "visible" }, children: [_jsxs("div", { className: "flex items-center justify-between px-6 py-4 border-b border-[var(--color-border-default)] flex-shrink-0", children: [_jsx("h2", { id: "dialog-title", className: "text-lg font-semibold text-[var(--color-text-primary)]", children: title }), onClose && (_jsx("button", { onClick: onClose, className: "ml-4 p-1 rounded-md text-[var(--color-text-secondary)] hover:text-[var(--color-text-primary)] hover:bg-[var(--color-bg-hover)] transition-colors cursor-pointer", "aria-label": "Cerrar dialog", children: _jsx("i", { className: "fa fa-times" }) }))] }), _jsx("div", { className: "px-6 py-4 flex-1 text-[var(--color-text-primary)] min-w-0", style: {
|
|
39
|
+
overflowY: "auto",
|
|
40
|
+
overflowX: "visible",
|
|
41
|
+
maxHeight: "calc(90vh - 200px)"
|
|
42
|
+
}, children: dialogBody }), _jsx("div", { className: "px-6 py-4 border-t border-[var(--color-border-default)] flex items-center justify-end gap-2 flex-shrink-0 flex-wrap", children: dialogActions })] })] }));
|
|
39
43
|
};
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
export interface DropdownMenuProps<T = {
|
|
3
|
+
label: string;
|
|
4
|
+
}> {
|
|
5
|
+
options: T[];
|
|
6
|
+
onOptionSelected: (item: T) => void;
|
|
7
|
+
renderNode?: React.ReactNode;
|
|
8
|
+
/**
|
|
9
|
+
* Obtiene el label que se muestra para cada opción. Por defecto usa la propiedad "label".
|
|
10
|
+
*/
|
|
11
|
+
getOptionLabel?: (item: T) => string;
|
|
12
|
+
/**
|
|
13
|
+
* Renderizado personalizado de cada opción. Si se define, se ignora el render por defecto.
|
|
14
|
+
*/
|
|
15
|
+
renderOption?: (item: T) => React.ReactNode;
|
|
16
|
+
/**
|
|
17
|
+
* Si es true y hay una sola opción, muestra directamente la opción en lugar del trigger.
|
|
18
|
+
* Por defecto es false.
|
|
19
|
+
*/
|
|
20
|
+
replaceOnSingleOption?: boolean;
|
|
21
|
+
}
|
|
22
|
+
export declare const DropdownMenu: <T = {
|
|
23
|
+
label: string;
|
|
24
|
+
}>({ options, onOptionSelected, renderNode, getOptionLabel, renderOption, replaceOnSingleOption, }: DropdownMenuProps<T>) => import("react/jsx-runtime").JSX.Element;
|
|
25
|
+
//# sourceMappingURL=DropdownMenu.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DropdownMenu.d.ts","sourceRoot":"","sources":["../../../src/components/utils/DropdownMenu.tsx"],"names":[],"mappings":"AAAA,OAAO,KAMN,MAAM,OAAO,CAAC;AAGf,MAAM,WAAW,iBAAiB,CAAC,CAAC,GAAG;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE;IACtD,OAAO,EAAE,CAAC,EAAE,CAAC;IACb,gBAAgB,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,IAAI,CAAC;IACpC,UAAU,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC7B;;OAEG;IACH,cAAc,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,MAAM,CAAC;IACrC;;OAEG;IACH,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,KAAK,CAAC,SAAS,CAAC;IAC5C;;;OAGG;IACH,qBAAqB,CAAC,EAAE,OAAO,CAAC;CACjC;AAED,eAAO,MAAM,YAAY,GAAI,CAAC,GAAG;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,EAAG,iGAOlD,iBAAiB,CAAC,CAAC,CAAC,4CAiNtB,CAAC"}
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import React, { useState, useRef, useEffect, useCallback, useMemo, } from "react";
|
|
3
|
+
import { Button } from "../form-controls/Button";
|
|
4
|
+
export const DropdownMenu = ({ options, onOptionSelected, renderNode, getOptionLabel, renderOption, replaceOnSingleOption = false, }) => {
|
|
5
|
+
const [isOpen, setIsOpen] = useState(false);
|
|
6
|
+
const [menuPosition, setMenuPosition] = useState("bottom");
|
|
7
|
+
const [scrollUpdate, setScrollUpdate] = useState(0);
|
|
8
|
+
const triggerRef = useRef(null);
|
|
9
|
+
const menuRef = useRef(null);
|
|
10
|
+
// Calcular posición del menú
|
|
11
|
+
const calculatePosition = useCallback(() => {
|
|
12
|
+
if (isOpen && triggerRef.current) {
|
|
13
|
+
const triggerRect = triggerRef.current.getBoundingClientRect();
|
|
14
|
+
const viewportHeight = window.innerHeight;
|
|
15
|
+
// Estimar altura del menú (aproximadamente 40px por opción + padding)
|
|
16
|
+
const estimatedMenuHeight = options.length * 40 + 16;
|
|
17
|
+
const menuMargin = 4;
|
|
18
|
+
// Calcular espacio disponible arriba y abajo
|
|
19
|
+
const spaceBelow = viewportHeight - triggerRect.bottom - menuMargin;
|
|
20
|
+
const spaceAbove = triggerRect.top - menuMargin;
|
|
21
|
+
// Si no hay suficiente espacio abajo pero sí arriba, mostrar arriba
|
|
22
|
+
// Usamos un margen de seguridad para asegurar que el menú quepa
|
|
23
|
+
if (spaceBelow < estimatedMenuHeight && spaceAbove > spaceBelow) {
|
|
24
|
+
setMenuPosition("top");
|
|
25
|
+
}
|
|
26
|
+
else {
|
|
27
|
+
setMenuPosition("bottom");
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}, [isOpen, options.length]);
|
|
31
|
+
useEffect(() => {
|
|
32
|
+
calculatePosition();
|
|
33
|
+
}, [calculatePosition]);
|
|
34
|
+
// Recalcular posición al hacer scroll o redimensionar
|
|
35
|
+
useEffect(() => {
|
|
36
|
+
if (isOpen) {
|
|
37
|
+
const handleScroll = () => {
|
|
38
|
+
calculatePosition();
|
|
39
|
+
// Forzar actualización del estilo del menú
|
|
40
|
+
setScrollUpdate((prev) => prev + 1);
|
|
41
|
+
};
|
|
42
|
+
window.addEventListener("scroll", handleScroll, true);
|
|
43
|
+
window.addEventListener("resize", handleScroll);
|
|
44
|
+
return () => {
|
|
45
|
+
window.removeEventListener("scroll", handleScroll, true);
|
|
46
|
+
window.removeEventListener("resize", handleScroll);
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
}, [isOpen, calculatePosition]);
|
|
50
|
+
// Cerrar menú al hacer click fuera
|
|
51
|
+
useEffect(() => {
|
|
52
|
+
const handleClickOutside = (event) => {
|
|
53
|
+
if (isOpen &&
|
|
54
|
+
triggerRef.current &&
|
|
55
|
+
menuRef.current &&
|
|
56
|
+
!triggerRef.current.contains(event.target) &&
|
|
57
|
+
!menuRef.current.contains(event.target)) {
|
|
58
|
+
setIsOpen(false);
|
|
59
|
+
}
|
|
60
|
+
};
|
|
61
|
+
if (isOpen) {
|
|
62
|
+
document.addEventListener("mousedown", handleClickOutside);
|
|
63
|
+
}
|
|
64
|
+
return () => {
|
|
65
|
+
document.removeEventListener("mousedown", handleClickOutside);
|
|
66
|
+
};
|
|
67
|
+
}, [isOpen]);
|
|
68
|
+
// Cerrar menú al presionar Escape
|
|
69
|
+
useEffect(() => {
|
|
70
|
+
const handleEscape = (event) => {
|
|
71
|
+
if (event.key === "Escape" && isOpen) {
|
|
72
|
+
setIsOpen(false);
|
|
73
|
+
}
|
|
74
|
+
};
|
|
75
|
+
if (isOpen) {
|
|
76
|
+
document.addEventListener("keydown", handleEscape);
|
|
77
|
+
}
|
|
78
|
+
return () => {
|
|
79
|
+
document.removeEventListener("keydown", handleEscape);
|
|
80
|
+
};
|
|
81
|
+
}, [isOpen]);
|
|
82
|
+
const labelGetter = useCallback((item) => {
|
|
83
|
+
if (getOptionLabel)
|
|
84
|
+
return getOptionLabel(item);
|
|
85
|
+
const anyItem = item;
|
|
86
|
+
return (anyItem.label ?? "").toString();
|
|
87
|
+
}, [getOptionLabel]);
|
|
88
|
+
const handleToggle = () => {
|
|
89
|
+
setIsOpen(!isOpen);
|
|
90
|
+
};
|
|
91
|
+
const handleOptionClick = (item) => {
|
|
92
|
+
onOptionSelected(item);
|
|
93
|
+
setIsOpen(false);
|
|
94
|
+
};
|
|
95
|
+
// Si replaceOnSingleOption es true y hay una sola opción, mostrar directamente la opción
|
|
96
|
+
const shouldReplace = replaceOnSingleOption && options.length === 1;
|
|
97
|
+
const singleOption = shouldReplace ? options[0] : null;
|
|
98
|
+
const menuStyles = useMemo(() => {
|
|
99
|
+
if (!isOpen || !triggerRef.current) {
|
|
100
|
+
return {};
|
|
101
|
+
}
|
|
102
|
+
const triggerRect = triggerRef.current.getBoundingClientRect();
|
|
103
|
+
const menuMargin = 4;
|
|
104
|
+
// Asegurar que el menú no se salga de la pantalla horizontalmente
|
|
105
|
+
let leftPosition = triggerRect.left;
|
|
106
|
+
const menuMinWidth = 160;
|
|
107
|
+
const viewportWidth = window.innerWidth;
|
|
108
|
+
// Si el menú se sale por la derecha, ajustar la posición
|
|
109
|
+
if (leftPosition + menuMinWidth > viewportWidth) {
|
|
110
|
+
leftPosition = viewportWidth - menuMinWidth - 8; // 8px de margen
|
|
111
|
+
}
|
|
112
|
+
// Asegurar que no se salga por la izquierda
|
|
113
|
+
if (leftPosition < 8) {
|
|
114
|
+
leftPosition = 8;
|
|
115
|
+
}
|
|
116
|
+
if (menuPosition === "top") {
|
|
117
|
+
return {
|
|
118
|
+
position: "fixed",
|
|
119
|
+
bottom: window.innerHeight - triggerRect.top + menuMargin,
|
|
120
|
+
left: leftPosition,
|
|
121
|
+
minWidth: Math.max(triggerRect.width, menuMinWidth),
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
else {
|
|
125
|
+
return {
|
|
126
|
+
position: "fixed",
|
|
127
|
+
top: triggerRect.bottom + menuMargin,
|
|
128
|
+
left: leftPosition,
|
|
129
|
+
minWidth: Math.max(triggerRect.width, menuMinWidth),
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
// scrollUpdate se usa intencionalmente para forzar el recálculo en scroll
|
|
133
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
134
|
+
}, [isOpen, menuPosition, scrollUpdate]);
|
|
135
|
+
// Si debe reemplazar con la opción única, mostrar directamente la opción
|
|
136
|
+
if (shouldReplace && singleOption) {
|
|
137
|
+
return (_jsx("div", { onClick: () => handleOptionClick(singleOption), className: "cursor-pointer", children: renderOption ? renderOption(singleOption) : labelGetter(singleOption) }));
|
|
138
|
+
}
|
|
139
|
+
return (_jsxs("div", { className: "relative inline-block", ref: triggerRef, children: [_jsx("div", { onClick: handleToggle, className: "cursor-pointer", children: renderNode ? (renderNode) : (_jsx(Button, { variant: "ghost", icon: "fa-ellipsis-h" })) }), isOpen && (_jsx("div", { ref: menuRef, className: "absolute z-[1000] bg-[var(--color-bg-default)] border border-[var(--color-border-default)] rounded-md shadow-[var(--shadow-lg)] py-1 min-w-[160px] font-[var(--font-default)]", style: menuStyles, children: options.map((option, index) => {
|
|
140
|
+
const key = String(option?.id ??
|
|
141
|
+
labelGetter(option) ??
|
|
142
|
+
index);
|
|
143
|
+
return (_jsx("div", { onClick: () => handleOptionClick(option), className: "px-4 py-2 text-sm text-[var(--color-text-primary)] hover:bg-[var(--color-bg-secondary)] cursor-pointer transition-colors flex items-center", children: renderOption ? renderOption(option) : labelGetter(option) }, key));
|
|
144
|
+
}) }))] }));
|
|
145
|
+
};
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import type { AutocompleteOption } from "../form-controls/AutocompleteInput";
|
|
3
|
+
import type { SearchSelectOption } from "../form-controls/SearchSelectInput";
|
|
4
|
+
import type { PaginationInterface } from "../form-controls/Pagination";
|
|
5
|
+
export interface StaticOption {
|
|
6
|
+
text: string;
|
|
7
|
+
value: string;
|
|
8
|
+
}
|
|
9
|
+
interface BaseFilterProps {
|
|
10
|
+
paramName?: string;
|
|
11
|
+
label?: string;
|
|
12
|
+
staticOptions?: StaticOption[];
|
|
13
|
+
inputWidth?: string;
|
|
14
|
+
value?: string;
|
|
15
|
+
onChange?: (value: string | undefined) => void;
|
|
16
|
+
/**
|
|
17
|
+
* Si es true, el componente solo se renderiza si tiene un valor o existe el queryParam asociado con un valor.
|
|
18
|
+
* Por defecto es false.
|
|
19
|
+
*/
|
|
20
|
+
hideEmpty?: boolean;
|
|
21
|
+
}
|
|
22
|
+
export interface TextFilterProps extends BaseFilterProps {
|
|
23
|
+
filterType?: "text";
|
|
24
|
+
}
|
|
25
|
+
export interface NumberFilterProps extends BaseFilterProps {
|
|
26
|
+
filterType: "number";
|
|
27
|
+
min?: number;
|
|
28
|
+
max?: number;
|
|
29
|
+
}
|
|
30
|
+
export interface DateFilterProps extends BaseFilterProps {
|
|
31
|
+
filterType: "date";
|
|
32
|
+
}
|
|
33
|
+
export interface AutocompleteFilterProps<T = AutocompleteOption, K = string> extends BaseFilterProps {
|
|
34
|
+
filterType: "autocomplete";
|
|
35
|
+
options: T[];
|
|
36
|
+
getOptionLabel?: (item: T) => string;
|
|
37
|
+
getOptionValue?: (item: T) => K;
|
|
38
|
+
renderOption?: (item: T) => React.ReactNode;
|
|
39
|
+
noResultsText?: string;
|
|
40
|
+
}
|
|
41
|
+
export interface SearchFilterProps extends BaseFilterProps {
|
|
42
|
+
filterType: "search";
|
|
43
|
+
}
|
|
44
|
+
export interface SearchSelectFilterProps<T = SearchSelectOption, K = string> extends BaseFilterProps {
|
|
45
|
+
filterType: "searchSelect";
|
|
46
|
+
onSearchPromiseFn: (text: string) => Promise<Array<T> | PaginationInterface<T>>;
|
|
47
|
+
onSingleSearchPromiseFn: (value: K) => Promise<T | undefined>;
|
|
48
|
+
getOptionLabel?: (item: T) => string;
|
|
49
|
+
getOptionValue?: (item: T) => K;
|
|
50
|
+
renderOption?: (item: T) => React.ReactNode;
|
|
51
|
+
dialogTitle?: string;
|
|
52
|
+
noResultsText?: string;
|
|
53
|
+
}
|
|
54
|
+
export type FilterProps = TextFilterProps | NumberFilterProps | DateFilterProps | AutocompleteFilterProps | SearchFilterProps | SearchSelectFilterProps;
|
|
55
|
+
export declare const Filter: React.FC<FilterProps>;
|
|
56
|
+
export {};
|
|
57
|
+
//# sourceMappingURL=Filter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Filter.d.ts","sourceRoot":"","sources":["../../../src/components/utils/Filter.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAsC,MAAM,OAAO,CAAC;AAQ3D,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,oCAAoC,CAAC;AAE7E,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,oCAAoC,CAAC;AAC7E,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,6BAA6B,CAAC;AAGvE,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;CACf;AAGD,UAAU,eAAe;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,aAAa,CAAC,EAAE,YAAY,EAAE,CAAC;IAC/B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,KAAK,IAAI,CAAC;IAC/C;;;OAGG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAGD,MAAM,WAAW,eAAgB,SAAQ,eAAe;IACtD,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,iBAAkB,SAAQ,eAAe;IACxD,UAAU,EAAE,QAAQ,CAAC;IACrB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,eAAgB,SAAQ,eAAe;IACtD,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,uBAAuB,CAAC,CAAC,GAAG,kBAAkB,EAAE,CAAC,GAAG,MAAM,CACzE,SAAQ,eAAe;IACvB,UAAU,EAAE,cAAc,CAAC;IAC3B,OAAO,EAAE,CAAC,EAAE,CAAC;IACb,cAAc,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,MAAM,CAAC;IACrC,cAAc,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC;IAChC,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,KAAK,CAAC,SAAS,CAAC;IAC5C,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,iBAAkB,SAAQ,eAAe;IACxD,UAAU,EAAE,QAAQ,CAAC;CACtB;AAED,MAAM,WAAW,uBAAuB,CAAC,CAAC,GAAG,kBAAkB,EAAE,CAAC,GAAG,MAAM,CACzE,SAAQ,eAAe;IACvB,UAAU,EAAE,cAAc,CAAC;IAC3B,iBAAiB,EAAE,CACjB,IAAI,EAAE,MAAM,KACT,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,mBAAmB,CAAC,CAAC,CAAC,CAAC,CAAC;IAChD,uBAAuB,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,OAAO,CAAC,CAAC,GAAG,SAAS,CAAC,CAAC;IAC9D,cAAc,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,MAAM,CAAC;IACrC,cAAc,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC;IAChC,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,KAAK,CAAC,SAAS,CAAC;IAC5C,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAGD,MAAM,MAAM,WAAW,GACnB,eAAe,GACf,iBAAiB,GACjB,eAAe,GACf,uBAAuB,GACvB,iBAAiB,GACjB,uBAAuB,CAAC;AAE5B,eAAO,MAAM,MAAM,EAAE,KAAK,CAAC,EAAE,CAAC,WAAW,CAu8BxC,CAAC"}
|