flysoft-react-ui 0.5.0 → 0.5.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/App.d.ts.map +1 -1
- package/dist/App.js +19 -7
- 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 +411 -31
- 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 +14 -0
- package/dist/components/form-controls/Checkbox.d.ts.map +1 -0
- package/dist/components/form-controls/Checkbox.js +79 -0
- package/dist/components/form-controls/DateInput.d.ts +24 -4
- package/dist/components/form-controls/DateInput.d.ts.map +1 -1
- package/dist/components/form-controls/DateInput.js +492 -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 +17 -10
- 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/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 +963 -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 +336 -0
- package/dist/components/form-controls/index.d.ts +9 -1
- package/dist/components/form-controls/index.d.ts.map +1 -1
- package/dist/components/form-controls/index.js +4 -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.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 +8 -3
- package/dist/components/layout/Card.d.ts.map +1 -1
- package/dist/components/layout/Card.js +18 -19
- package/dist/components/layout/Collection.js +1 -1
- package/dist/components/layout/DataTable.d.ts +3 -1
- package/dist/components/layout/DataTable.d.ts.map +1 -1
- package/dist/components/layout/DataTable.js +34 -29
- 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 +131 -26
- package/dist/components/utils/Dialog.d.ts.map +1 -1
- package/dist/components/utils/Dialog.js +6 -1
- 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 +581 -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 +2 -2
- 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 +139 -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 +122 -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/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/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 +50 -0
- package/dist/contexts/ListCrudContext.d.ts.map +1 -0
- package/dist/contexts/ListCrudContext.js +253 -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/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/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/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/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.map +1 -1
- package/dist/docs/DataTableDocs.js +9 -5
- 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/DialogDocs.js +1 -1
- 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 +3 -3
- package/dist/docs/DocsRouter.d.ts.map +1 -1
- package/dist/docs/DocsRouter.js +13 -1
- package/dist/docs/DropdownMenuDocs.js +1 -1
- 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/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 +2 -0
- package/dist/docs/ListCrudDocs.tsx/ListCrudDocs.d.ts.map +1 -0
- package/dist/docs/ListCrudDocs.tsx/ListCrudDocs.js +29 -0
- 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 +2 -0
- package/dist/docs/ListCrudDocs.tsx/ListCrudDocsContentPersonas.d.ts.map +1 -0
- package/dist/docs/ListCrudDocs.tsx/ListCrudDocsContentPersonas.js +57 -0
- 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/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 +117 -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 +181 -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 +23 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +11 -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 +5 -2
|
@@ -1,9 +1,20 @@
|
|
|
1
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
2
|
import React, { useState, useRef } from "react";
|
|
3
3
|
import { useBreakpoint } from "../../hooks";
|
|
4
4
|
import { useElementScroll } from "../../hooks/useElementScroll";
|
|
5
5
|
import { Button } from "../form-controls";
|
|
6
|
-
export const AppLayout = ({
|
|
6
|
+
export const AppLayout = ({ navbar, leftDrawer, children, className = "", }) => {
|
|
7
|
+
// Extract values from interfaces
|
|
8
|
+
const navBarLeftNode = navbar?.navBarLeftNode;
|
|
9
|
+
const navBarRightNode = navbar?.navBarRightNode;
|
|
10
|
+
const fullWidthNavbar = navbar?.fullWidthNavbar ?? true;
|
|
11
|
+
const navbarHeight = navbar?.height ?? "64px";
|
|
12
|
+
const navbarClassName = navbar?.className || "";
|
|
13
|
+
const leftDrawerHeader = leftDrawer?.headerNode;
|
|
14
|
+
const leftDrawerContent = leftDrawer?.contentNode;
|
|
15
|
+
const leftDrawerFooter = leftDrawer?.footerNode;
|
|
16
|
+
const leftDrawerClassName = leftDrawer?.className || "";
|
|
17
|
+
const leftDrawerWidth = leftDrawer?.width;
|
|
7
18
|
const { isMobile, isTablet } = useBreakpoint();
|
|
8
19
|
const contentRef = useRef(null);
|
|
9
20
|
const { scrollY, scrollDirection } = useElementScroll(contentRef);
|
|
@@ -12,8 +23,15 @@ export const AppLayout = ({ navBarDrawer, leftDrawer, children, className = "",
|
|
|
12
23
|
const isNavbarVisibleRef = useRef(isNavbarVisible);
|
|
13
24
|
const isTransitioningRef = useRef(false);
|
|
14
25
|
const lastScrollYRef = useRef(0);
|
|
26
|
+
// Determinar si hay algún contenido en el drawer izquierdo
|
|
27
|
+
const hasLeftDrawerContent = leftDrawerHeader || leftDrawerContent || leftDrawerFooter;
|
|
15
28
|
const shouldShowMobileDrawer = isMobile || isTablet;
|
|
16
|
-
const shouldShowDesktopDrawer = !shouldShowMobileDrawer &&
|
|
29
|
+
const shouldShowDesktopDrawer = !shouldShowMobileDrawer && hasLeftDrawerContent;
|
|
30
|
+
// Determinar si debemos mostrar el navbar
|
|
31
|
+
// Se muestra si hay navBarLeftNode o navBarRightNode o si estamos en móvil/tablet con contenido en el drawer
|
|
32
|
+
const shouldShowNavbar = navBarLeftNode ||
|
|
33
|
+
navBarRightNode ||
|
|
34
|
+
(shouldShowMobileDrawer && hasLeftDrawerContent);
|
|
17
35
|
// Mantener el ref sincronizado con el estado
|
|
18
36
|
React.useEffect(() => {
|
|
19
37
|
isNavbarVisibleRef.current = isNavbarVisible;
|
|
@@ -48,7 +66,9 @@ export const AppLayout = ({ navBarDrawer, leftDrawer, children, className = "",
|
|
|
48
66
|
// Siempre mostrar navbar cerca del top
|
|
49
67
|
shouldBeVisible = true;
|
|
50
68
|
}
|
|
51
|
-
else if (scrollDirection === "down" &&
|
|
69
|
+
else if (scrollDirection === "down" &&
|
|
70
|
+
scrollY > HIDE_THRESHOLD &&
|
|
71
|
+
!isNearBottom) {
|
|
52
72
|
// Ocultar navbar al hacer scroll hacia abajo, excepto si estamos cerca del final
|
|
53
73
|
shouldBeVisible = false;
|
|
54
74
|
}
|
|
@@ -87,36 +107,84 @@ export const AppLayout = ({ navBarDrawer, leftDrawer, children, className = "",
|
|
|
87
107
|
${className}
|
|
88
108
|
`;
|
|
89
109
|
// Clases del navbar
|
|
90
|
-
const navbarClasses =
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
110
|
+
const navbarClasses = `${fullWidthNavbar
|
|
111
|
+
? `z-[1000] fixed top-0 left-0 right-0 overflow-hidden`
|
|
112
|
+
: `relative z-[1000] overflow-hidden`} ${navbarClassName}`.trim();
|
|
113
|
+
// Estilos inline para la transformación
|
|
114
|
+
// Cuando fullWidthNavbar es false, solo usamos height para ocultar (sin transform)
|
|
115
|
+
// Cuando fullWidthNavbar es true, usamos transform para ocultar (manteniendo height)
|
|
116
|
+
const navbarStyle = fullWidthNavbar
|
|
117
|
+
? {
|
|
118
|
+
transform: isNavbarVisible ? "translateY(0)" : "translateY(-100%)",
|
|
119
|
+
transition: "transform 300ms ease-in-out",
|
|
120
|
+
willChange: "transform",
|
|
121
|
+
height: navbarHeight, // Override any height classes in className
|
|
122
|
+
}
|
|
123
|
+
: {
|
|
124
|
+
height: isNavbarVisible ? navbarHeight : "0",
|
|
125
|
+
minHeight: isNavbarVisible ? navbarHeight : "0",
|
|
126
|
+
maxHeight: isNavbarVisible ? navbarHeight : "0",
|
|
127
|
+
transition: "height 300ms ease-in-out, min-height 300ms ease-in-out, max-height 300ms ease-in-out",
|
|
128
|
+
overflow: "hidden",
|
|
129
|
+
};
|
|
130
|
+
const navbarContentClasses = `flex items-center justify-between gap-2`;
|
|
131
|
+
// Style for navbar content with dynamic height
|
|
132
|
+
// When fullWidthNavbar is false and hidden, set height to 0 to not occupy space
|
|
133
|
+
// When fullWidthNavbar is true, always maintain height to prevent layout shifts
|
|
134
|
+
const navbarContentStyle = {
|
|
135
|
+
height: fullWidthNavbar || isNavbarVisible ? navbarHeight : "0",
|
|
136
|
+
maxHeight: fullWidthNavbar || isNavbarVisible ? navbarHeight : "0",
|
|
137
|
+
overflow: "hidden",
|
|
138
|
+
transition: "height 300ms ease-in-out, max-height 300ms ease-in-out",
|
|
139
|
+
opacity: isNavbarVisible || fullWidthNavbar ? 1 : 0,
|
|
100
140
|
};
|
|
101
|
-
const
|
|
102
|
-
flex items-center
|
|
103
|
-
md:px-3
|
|
104
|
-
`;
|
|
105
|
-
const navbarDrawerClasses = `flex-1`;
|
|
141
|
+
const navbarLeftClasses = `flex items-center gap-2`;
|
|
142
|
+
const navbarRightClasses = `flex items-center gap-2`;
|
|
106
143
|
// Clases del contenido principal
|
|
107
|
-
const mainClasses = `
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
144
|
+
const mainClasses = `flex flex-1 overflow-hidden transition-all duration-300 ease-in-out`;
|
|
145
|
+
// Style for main content with dynamic navbar height padding
|
|
146
|
+
const mainStyle = fullWidthNavbar && shouldShowNavbar && isNavbarVisible
|
|
147
|
+
? { paddingTop: navbarHeight }
|
|
148
|
+
: {};
|
|
149
|
+
// Clases del drawer izquierdo (contenedor principal)
|
|
150
|
+
// width se aplica como estilo inline para tener prioridad sobre className
|
|
112
151
|
const leftDrawerClasses = `
|
|
113
|
-
w-64 bg-[var(--color-bg-default)]
|
|
114
|
-
|
|
152
|
+
${leftDrawerWidth ? "" : "w-64"} bg-[var(--color-bg-default)]
|
|
153
|
+
flex-shrink-0 flex flex-col
|
|
115
154
|
transition-all duration-300 ease-in-out
|
|
116
|
-
${
|
|
155
|
+
${fullWidthNavbar && shouldShowNavbar && isNavbarVisible ? "pt-4" : "h-full"}
|
|
156
|
+
${leftDrawerClassName}
|
|
157
|
+
`
|
|
158
|
+
.trim()
|
|
159
|
+
.replace(/\s+/g, " ");
|
|
160
|
+
// Style for left drawer with dynamic width
|
|
161
|
+
const leftDrawerStyle = leftDrawerWidth ? { width: leftDrawerWidth } : {};
|
|
162
|
+
// Clases del contenedor que incluye drawer y contenido (cuando fullWidthNavbar es false)
|
|
163
|
+
const contentWrapperClasses = fullWidthNavbar
|
|
164
|
+
? ""
|
|
165
|
+
: `flex flex-row flex-1 overflow-hidden`;
|
|
166
|
+
// Clases del contenedor que incluye navbar y main (cuando fullWidthNavbar es false)
|
|
167
|
+
const drawerAndContentClasses = fullWidthNavbar
|
|
168
|
+
? ""
|
|
169
|
+
: `flex flex-col flex-1 overflow-hidden`;
|
|
170
|
+
// Style for drawer and content wrapper with dynamic navbar height padding
|
|
171
|
+
const drawerAndContentStyle = !fullWidthNavbar && shouldShowNavbar && isNavbarVisible
|
|
172
|
+
? { paddingTop: 0 }
|
|
173
|
+
: {};
|
|
174
|
+
// Clases del header del drawer (fijo arriba)
|
|
175
|
+
const leftDrawerHeaderClasses = `
|
|
176
|
+
flex-shrink-0
|
|
177
|
+
`;
|
|
178
|
+
// Clases del contenido del drawer (scrolleable sin scrollbar visible)
|
|
179
|
+
const leftDrawerContentClasses = `
|
|
180
|
+
flex-1 overflow-y-auto scrollbar-hide
|
|
181
|
+
`;
|
|
182
|
+
// Clases del footer del drawer (fijo abajo)
|
|
183
|
+
const leftDrawerFooterClasses = `
|
|
184
|
+
flex-shrink-0
|
|
117
185
|
`;
|
|
118
186
|
const contentClasses = `
|
|
119
|
-
flex-1 overflow-y-auto px-2
|
|
187
|
+
flex-1 overflow-y-auto px-2 pb-4 lg:px-6 pt-4
|
|
120
188
|
`;
|
|
121
189
|
// Clases del overlay móvil
|
|
122
190
|
const overlayClasses = `
|
|
@@ -128,10 +196,15 @@ export const AppLayout = ({ navBarDrawer, leftDrawer, children, className = "",
|
|
|
128
196
|
bg-[var(--color-bg-default)] shadow-[var(--shadow-xl)]
|
|
129
197
|
transform -translate-x-full transition-transform duration-300 ease-in-out
|
|
130
198
|
z-[1999] flex flex-col
|
|
131
|
-
|
|
199
|
+
${leftDrawerClassName}
|
|
200
|
+
`
|
|
201
|
+
.trim()
|
|
202
|
+
.replace(/\s+/g, " ");
|
|
203
|
+
// Style for mobile drawer with dynamic width
|
|
204
|
+
const mobileDrawerStyle = leftDrawerWidth ? { width: leftDrawerWidth } : {};
|
|
132
205
|
const mobileDrawerOpenClasses = `translate-x-0`;
|
|
133
206
|
const mobileDrawerContentClasses = `
|
|
134
|
-
flex-1 overflow-y-auto
|
|
207
|
+
flex-1 overflow-y-auto scrollbar-hide
|
|
135
208
|
`;
|
|
136
|
-
return (_jsxs("div", { className: layoutClasses, children: [
|
|
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 }))] }))] }));
|
|
137
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
|
};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
import React from "react";
|
|
3
|
-
export const Collection = ({ children, gap = "
|
|
3
|
+
export const Collection = ({ children, gap = "1rem", direction = "column", wrap = false, className = "", }) => {
|
|
4
4
|
const baseClasses = `
|
|
5
5
|
flex
|
|
6
6
|
font-[var(--font-default)]
|
|
@@ -22,6 +22,8 @@ export interface DataTableProps<T> {
|
|
|
22
22
|
className?: string;
|
|
23
23
|
maxRows?: number;
|
|
24
24
|
locale?: string;
|
|
25
|
+
isLoading?: boolean;
|
|
26
|
+
loadingRows?: number;
|
|
25
27
|
}
|
|
26
|
-
export declare const DataTable: <T>({ columns, rows, className, maxRows, locale, }: DataTableProps<T>) => import("react/jsx-runtime").JSX.Element;
|
|
28
|
+
export declare const DataTable: <T>({ columns, rows, className, maxRows, locale, isLoading, loadingRows, }: DataTableProps<T>) => import("react/jsx-runtime").JSX.Element;
|
|
27
29
|
//# sourceMappingURL=DataTable.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DataTable.d.ts","sourceRoot":"","sources":["../../../src/components/layout/DataTable.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAQ1B,MAAM,WAAW,eAAe,CAAC,CAAC;IAChC,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,GAAG,QAAQ,CAAC;IACpC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC,SAAS,CAAC;IAClC,MAAM,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC,SAAS,CAAC;IAClC,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC,KAAK,MAAM,GAAG,KAAK,CAAC,SAAS,CAAC,CAAC;IACjE,OAAO,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC,KAAK,MAAM,GAAG,KAAK,CAAC,SAAS,CAAC;IAC/C,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,GAAG,UAAU,GAAG,MAAM,CAAC;IAChD;;OAEG;IACH,OAAO,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC,KAAK,KAAK,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;IAC7C;;OAEG;IACH,aAAa,CAAC,EAAE,MAAM,KAAK,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;CAC9C;AAED,MAAM,WAAW,cAAc,CAAC,CAAC;IAC/B,OAAO,EAAE,eAAe,CAAC,CAAC,CAAC,EAAE,CAAC;IAC9B,IAAI,EAAE,CAAC,EAAE,CAAC;IACV,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"DataTable.d.ts","sourceRoot":"","sources":["../../../src/components/layout/DataTable.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAQ1B,MAAM,WAAW,eAAe,CAAC,CAAC;IAChC,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,GAAG,QAAQ,CAAC;IACpC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC,SAAS,CAAC;IAClC,MAAM,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC,SAAS,CAAC;IAClC,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC,KAAK,MAAM,GAAG,KAAK,CAAC,SAAS,CAAC,CAAC;IACjE,OAAO,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC,KAAK,MAAM,GAAG,KAAK,CAAC,SAAS,CAAC;IAC/C,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,GAAG,UAAU,GAAG,MAAM,CAAC;IAChD;;OAEG;IACH,OAAO,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC,KAAK,KAAK,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;IAC7C;;OAEG;IACH,aAAa,CAAC,EAAE,MAAM,KAAK,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;CAC9C;AAED,MAAM,WAAW,cAAc,CAAC,CAAC;IAC/B,OAAO,EAAE,eAAe,CAAC,CAAC,CAAC,EAAE,CAAC;IAC9B,IAAI,EAAE,CAAC,EAAE,CAAC;IACV,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,eAAO,MAAM,SAAS,GAAI,CAAC,EAAG,wEAQ3B,cAAc,CAAC,CAAC,CAAC,4CAgTnB,CAAC"}
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import React from "react";
|
|
3
3
|
import { DropdownMenu } from "../utils/DropdownMenu";
|
|
4
|
-
export const DataTable = ({ columns, rows, className = "", maxRows, locale = "es-AR", }) => {
|
|
4
|
+
export const DataTable = ({ columns, rows, className = "", maxRows, locale = "es-AR", isLoading = false, loadingRows = 5, }) => {
|
|
5
5
|
// Calcular si necesitamos scroll
|
|
6
|
-
const
|
|
6
|
+
const displayRows = isLoading ? loadingRows : rows.length;
|
|
7
|
+
const needsScroll = maxRows !== undefined && displayRows > maxRows;
|
|
7
8
|
// Altura aproximada de una fila (px-4 py-3 = ~48px por fila)
|
|
8
9
|
const rowHeight = 48;
|
|
9
10
|
const maxHeight = maxRows ? `${maxRows * rowHeight}px` : undefined;
|
|
@@ -112,6 +113,8 @@ export const DataTable = ({ columns, rows, className = "", maxRows, locale = "es
|
|
|
112
113
|
}, children: action })),
|
|
113
114
|
}));
|
|
114
115
|
};
|
|
116
|
+
// Componente Skeleton para celdas de carga
|
|
117
|
+
const SkeletonCell = () => (_jsx("div", { className: "h-4 bg-[var(--color-border-default)]/40 rounded animate-pulse w-full" }));
|
|
115
118
|
return (_jsx("div", { className: `overflow-x-auto ${className}`, children: _jsx("div", { className: needsScroll ? "relative overflow-y-auto" : "", style: needsScroll && maxHeight ? { maxHeight: maxHeight } : undefined, children: _jsxs("table", { className: "w-full border-collapse font-[var(--font-default)]", children: [_jsx("thead", { className: needsScroll ? "sticky top-0 z-10" : "", children: _jsx("tr", { className: "border-b border-[var(--color-border-default)]", children: columns.map((column, index) => {
|
|
116
119
|
const headerActions = column.headerActions?.();
|
|
117
120
|
const hasHeaderActions = headerActions && headerActions.length > 0;
|
|
@@ -122,39 +125,41 @@ export const DataTable = ({ columns, rows, className = "", maxRows, locale = "es
|
|
|
122
125
|
${hasHeaderActions ? "relative" : ""}
|
|
123
126
|
`, style: {
|
|
124
127
|
...(column.width ? { width: column.width } : {}),
|
|
125
|
-
|
|
126
|
-
}, children: hasHeaderActions ? (_jsxs("div", { className: "flex items-center justify-between gap-2", children: [_jsx("span", { children: column.header || "" }), _jsx(DropdownMenu, { options: convertActionsToOptions(headerActions), onOptionSelected: () => {
|
|
128
|
+
}, children: isLoading ? (_jsx(SkeletonCell, {})) : hasHeaderActions ? (_jsxs("div", { className: "flex items-center justify-between gap-2", children: [_jsx("span", { children: column.header || "" }), _jsx(DropdownMenu, { options: convertActionsToOptions(headerActions), onOptionSelected: () => {
|
|
127
129
|
// Las acciones ya manejan sus propios eventos
|
|
128
130
|
}, renderOption: (item) => item.content, replaceOnSingleOption: true })] })) : (column.header || "") }, index));
|
|
129
|
-
}) }) }), _jsx("tbody", { children:
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
const tooltip = column.tooltip
|
|
135
|
-
? column.tooltip(row)
|
|
136
|
-
: undefined;
|
|
137
|
-
const rowActions = column.actions?.(row);
|
|
138
|
-
const hasRowActions = rowActions && rowActions.length > 0;
|
|
139
|
-
return (_jsx("td", { className: `
|
|
140
|
-
px-4 py-3 text-sm text-[var(--color-text-primary)]
|
|
141
|
-
${getAlignmentClass(column.align, column.type)}
|
|
142
|
-
`, style: {
|
|
131
|
+
}) }) }), _jsx("tbody", { children: isLoading
|
|
132
|
+
? Array.from({ length: loadingRows }).map((_, rowIndex) => (_jsx("tr", { className: "border-b border-[var(--color-border-default)]", children: columns.map((column, colIndex) => (_jsx("td", { className: `
|
|
133
|
+
px-4 py-3 text-sm text-[var(--color-text-primary)]
|
|
134
|
+
${getAlignmentClass(column.align, column.type)}
|
|
135
|
+
`, style: {
|
|
143
136
|
...(column.width ? { width: column.width } : {}),
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
137
|
+
}, children: _jsx(SkeletonCell, {}) }, colIndex))) }, `skeleton-${rowIndex}`)))
|
|
138
|
+
: rows.map((row, rowIndex) => (_jsx("tr", { className: "group/row border-b border-[var(--color-border-default)] transition-colors hover:bg-[var(--color-bg-secondary)]", children: columns.map((column, colIndex) => {
|
|
139
|
+
const cellValue = getCellValue(column, row);
|
|
140
|
+
const formattedValue = formatValue(cellValue, column.type);
|
|
141
|
+
const tooltip = column.tooltip
|
|
142
|
+
? column.tooltip(row)
|
|
143
|
+
: undefined;
|
|
144
|
+
const rowActions = column.actions?.(row);
|
|
145
|
+
const hasRowActions = rowActions && rowActions.length > 0;
|
|
146
|
+
return (_jsx("td", { className: `
|
|
147
|
+
px-4 py-3 text-sm text-[var(--color-text-primary)]
|
|
148
|
+
${getAlignmentClass(column.align, column.type)}
|
|
149
|
+
`, style: {
|
|
150
|
+
...(column.width ? { width: column.width } : {}),
|
|
151
|
+
}, title: tooltip
|
|
152
|
+
? typeof tooltip === "string"
|
|
153
|
+
? tooltip
|
|
154
|
+
: undefined
|
|
155
|
+
: undefined, children: hasRowActions ? (_jsxs("div", { className: "flex items-center justify-between gap-2", children: [_jsx("span", { children: formattedValue }), _jsx("div", { className: "lg:opacity-0 lg:group-hover/row:opacity-100 transition-opacity", children: _jsx(DropdownMenu, { options: convertActionsToOptions(rowActions), onOptionSelected: () => {
|
|
156
|
+
// Las acciones ya manejan sus propios eventos
|
|
157
|
+
}, renderOption: (item) => item.content, replaceOnSingleOption: true }) })] })) : (formattedValue) }, colIndex));
|
|
158
|
+
}) }, rowIndex))) }), hasFooter && (_jsx("tfoot", { className: needsScroll ? "sticky bottom-0 z-10" : "", children: _jsx("tr", { className: "border-t border-[var(--color-border-default)]", children: columns.map((column, index) => (_jsx("td", { className: `
|
|
153
159
|
px-4 py-3 text-sm font-semibold text-[var(--color-text-primary)]
|
|
154
160
|
bg-[var(--color-bg-secondary)]
|
|
155
161
|
${getAlignmentClass(column.align, column.type)}
|
|
156
162
|
`, style: {
|
|
157
163
|
...(column.width ? { width: column.width } : {}),
|
|
158
|
-
|
|
159
|
-
}, children: column.footer || "" }, index))) }) }))] }) }) }));
|
|
164
|
+
}, children: isLoading ? _jsx(SkeletonCell, {}) : column.footer || "" }, index))) }) }))] }) }) }));
|
|
160
165
|
};
|
|
@@ -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"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
export interface AvatarProps {
|
|
3
|
+
/**
|
|
4
|
+
* Text to extract initials from
|
|
5
|
+
* The component will show the first letter of the first word
|
|
6
|
+
* and the first letter of the last word if there are multiple words
|
|
7
|
+
*/
|
|
8
|
+
text: string;
|
|
9
|
+
/**
|
|
10
|
+
* Optional image URL to display instead of initials
|
|
11
|
+
*/
|
|
12
|
+
image?: string;
|
|
13
|
+
/**
|
|
14
|
+
* Optional background color (hexadecimal, rgb, or color name)
|
|
15
|
+
* Default: gray-600 (#4b5563)
|
|
16
|
+
*/
|
|
17
|
+
bgColor?: string;
|
|
18
|
+
/**
|
|
19
|
+
* Optional text color (hexadecimal, rgb, or color name)
|
|
20
|
+
* Default: white (#ffffff)
|
|
21
|
+
*/
|
|
22
|
+
textColor?: string;
|
|
23
|
+
/**
|
|
24
|
+
* Optional size variant
|
|
25
|
+
* Default: md
|
|
26
|
+
*/
|
|
27
|
+
size?: "sm" | "md" | "lg";
|
|
28
|
+
/**
|
|
29
|
+
* Optional additional CSS classes
|
|
30
|
+
*/
|
|
31
|
+
className?: string;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Avatar component displays a circular avatar with initials or an image
|
|
35
|
+
*
|
|
36
|
+
* @example
|
|
37
|
+
* // Basic usage with text
|
|
38
|
+
* <Avatar text="John Doe" />
|
|
39
|
+
*
|
|
40
|
+
* @example
|
|
41
|
+
* // With image
|
|
42
|
+
* <Avatar text="John Doe" image="https://example.com/avatar.jpg" />
|
|
43
|
+
*
|
|
44
|
+
* @example
|
|
45
|
+
* // Custom colors
|
|
46
|
+
* <Avatar text="Jane Smith" bgColor="#3b82f6" textColor="#ffffff" />
|
|
47
|
+
*/
|
|
48
|
+
export declare const Avatar: React.FC<AvatarProps>;
|
|
49
|
+
//# sourceMappingURL=Avatar.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Avatar.d.ts","sourceRoot":"","sources":["../../../src/components/utils/Avatar.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAmB,MAAM,OAAO,CAAC;AAuDxC,MAAM,WAAW,WAAW;IAC1B;;;;OAIG;IACH,IAAI,EAAE,MAAM,CAAC;IACb;;OAEG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;OAGG;IACH,IAAI,CAAC,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;IAC1B;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,MAAM,EAAE,KAAK,CAAC,EAAE,CAAC,WAAW,CA2DxC,CAAC"}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import React, { useState } from "react";
|
|
3
|
+
/**
|
|
4
|
+
* Helper function to convert color names to CSS values
|
|
5
|
+
*/
|
|
6
|
+
const getColorValue = (color) => {
|
|
7
|
+
if (!color)
|
|
8
|
+
return undefined;
|
|
9
|
+
// If already a valid CSS value (hex, rgb, rgba, hsl, etc.), return it
|
|
10
|
+
if (color.startsWith("#") ||
|
|
11
|
+
color.startsWith("rgb") ||
|
|
12
|
+
color.startsWith("hsl")) {
|
|
13
|
+
return color;
|
|
14
|
+
}
|
|
15
|
+
// Map common color names
|
|
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
|
+
/**
|
|
32
|
+
* Helper function to extract initials from text
|
|
33
|
+
* Returns first letter of first word and first letter of last word (if multiple words)
|
|
34
|
+
*/
|
|
35
|
+
const getInitials = (text) => {
|
|
36
|
+
if (!text || text.trim().length === 0)
|
|
37
|
+
return "";
|
|
38
|
+
const words = text.trim().split(/\s+/);
|
|
39
|
+
if (words.length === 0)
|
|
40
|
+
return "";
|
|
41
|
+
const firstLetter = words[0].charAt(0).toUpperCase();
|
|
42
|
+
if (words.length === 1) {
|
|
43
|
+
return firstLetter;
|
|
44
|
+
}
|
|
45
|
+
const lastLetter = words[words.length - 1].charAt(0).toUpperCase();
|
|
46
|
+
return `${firstLetter}${lastLetter}`;
|
|
47
|
+
};
|
|
48
|
+
/**
|
|
49
|
+
* Avatar component displays a circular avatar with initials or an image
|
|
50
|
+
*
|
|
51
|
+
* @example
|
|
52
|
+
* // Basic usage with text
|
|
53
|
+
* <Avatar text="John Doe" />
|
|
54
|
+
*
|
|
55
|
+
* @example
|
|
56
|
+
* // With image
|
|
57
|
+
* <Avatar text="John Doe" image="https://example.com/avatar.jpg" />
|
|
58
|
+
*
|
|
59
|
+
* @example
|
|
60
|
+
* // Custom colors
|
|
61
|
+
* <Avatar text="Jane Smith" bgColor="#3b82f6" textColor="#ffffff" />
|
|
62
|
+
*/
|
|
63
|
+
export const Avatar = ({ text, image, bgColor = "gray-600", textColor = "white", size = "md", className = "", }) => {
|
|
64
|
+
const [imageError, setImageError] = useState(false);
|
|
65
|
+
const initials = getInitials(text);
|
|
66
|
+
const showImage = image && !imageError;
|
|
67
|
+
const sizeClasses = {
|
|
68
|
+
sm: "w-8 h-8 text-xs",
|
|
69
|
+
md: "w-10 h-10 text-sm",
|
|
70
|
+
lg: "w-12 h-12 text-base",
|
|
71
|
+
};
|
|
72
|
+
const baseClasses = `
|
|
73
|
+
rounded-full
|
|
74
|
+
flex
|
|
75
|
+
items-center
|
|
76
|
+
justify-center
|
|
77
|
+
font-semibold
|
|
78
|
+
font-[var(--font-default)]
|
|
79
|
+
overflow-hidden
|
|
80
|
+
flex-shrink-0
|
|
81
|
+
${sizeClasses[size]}
|
|
82
|
+
${className}
|
|
83
|
+
`;
|
|
84
|
+
// Inline styles for colors (only if no image or image failed to load)
|
|
85
|
+
const inlineStyles = showImage
|
|
86
|
+
? {}
|
|
87
|
+
: {
|
|
88
|
+
backgroundColor: getColorValue(bgColor) || bgColor || "#4b5563",
|
|
89
|
+
color: getColorValue(textColor) || textColor || "#ffffff",
|
|
90
|
+
};
|
|
91
|
+
return (_jsx("div", { className: baseClasses, style: inlineStyles, title: text, role: "img", "aria-label": text, children: showImage ? (_jsx("img", { src: image, alt: text, className: "w-full h-full object-cover", onError: () => setImageError(true) })) : (_jsx("span", { children: initials })) }));
|
|
92
|
+
};
|
|
93
|
+
Avatar.displayName = "Avatar";
|
|
@@ -8,6 +8,9 @@ export interface BadgeProps {
|
|
|
8
8
|
icon?: string;
|
|
9
9
|
iconPosition?: "left" | "right";
|
|
10
10
|
iconLabel?: string;
|
|
11
|
+
bg?: string;
|
|
12
|
+
textColor?: string;
|
|
13
|
+
onClick?: (event: React.MouseEvent<HTMLElement>) => void;
|
|
11
14
|
}
|
|
12
15
|
export declare const Badge: React.FC<BadgeProps>;
|
|
13
16
|
//# sourceMappingURL=Badge.d.ts.map
|
|
@@ -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"}
|