flysoft-react-ui 1.0.9 → 1.1.0
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/components/layout/Card.d.ts.map +1 -1
- package/dist/components/layout/Card.js +20 -23
- package/dist/components/layout/DataTable.d.ts +7 -1
- package/dist/components/layout/DataTable.d.ts.map +1 -1
- package/dist/components/layout/DataTable.js +24 -25
- package/dist/components/utils/Snackbar.d.ts.map +1 -1
- package/dist/components/utils/Snackbar.js +23 -9
- package/dist/components/utils/SnackbarContainer.d.ts.map +1 -1
- package/dist/components/utils/SnackbarContainer.js +2 -2
- package/dist/contexts/SnackbarContext.d.ts +1 -15
- package/dist/contexts/SnackbarContext.d.ts.map +1 -1
- package/dist/contexts/SnackbarContext.js +2 -15
- package/dist/contexts/index.d.ts +1 -1
- package/dist/contexts/index.d.ts.map +1 -1
- package/dist/contexts/index.js +1 -1
- package/dist/docs/DataTableDocs.d.ts.map +1 -1
- package/dist/docs/DataTableDocs.js +1 -1
- package/dist/docs/SnackbarDocs.d.ts.map +1 -1
- package/dist/docs/SnackbarDocs.js +14 -2
- package/dist/index.css +1 -1
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
|
@@ -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;AAG1B,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,CA6GpC,CAAC"}
|
|
@@ -1,30 +1,27 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import React from "react";
|
|
3
|
+
import { twMerge } from "tailwind-merge";
|
|
3
4
|
export const Card = ({ title, subtitle, children, className = "", headerActions, footer, variant = "default", alwaysDisplayHeaderActions = false, }) => {
|
|
4
|
-
// Separar clases de background del className
|
|
5
|
-
const classArray = className.trim().split(/\s+/).filter(Boolean);
|
|
6
|
-
const bgClasses = [];
|
|
7
|
-
const otherClasses = [];
|
|
8
|
-
classArray.forEach((cls) => {
|
|
9
|
-
// Detectar clases de background (bg-*, bg-gradient-*, bg-[...])
|
|
10
|
-
if (cls.startsWith("bg-") || cls.startsWith("bg-gradient-")) {
|
|
11
|
-
bgClasses.push(cls);
|
|
12
|
-
}
|
|
13
|
-
else {
|
|
14
|
-
otherClasses.push(cls);
|
|
15
|
-
}
|
|
16
|
-
});
|
|
17
|
-
const backgroundClass = bgClasses.length > 0 ? bgClasses.join(" ") : "bg-[var(--color-bg-default)]";
|
|
18
|
-
const baseClasses = `
|
|
19
|
-
${backgroundClass} rounded-lg border
|
|
20
|
-
font-[var(--font-default)]
|
|
21
|
-
`;
|
|
22
5
|
const variantClasses = {
|
|
23
|
-
default:
|
|
24
|
-
elevated:
|
|
25
|
-
outlined:
|
|
6
|
+
default: "border-[var(--color-border-default)]",
|
|
7
|
+
elevated: "border-[var(--color-border-default)] shadow-[var(--shadow-lg)]",
|
|
8
|
+
outlined: "border-[var(--color-gray-300)]",
|
|
26
9
|
};
|
|
27
|
-
|
|
10
|
+
// Unimos las clases usando twMerge para consistencia
|
|
11
|
+
const mergedClasses = twMerge("bg-[var(--color-bg-default)] rounded-lg border font-[var(--font-default)]", variantClasses[variant], className);
|
|
12
|
+
// Verificamos si existe alguna clase de ancho (w-*) que no sea w-auto.
|
|
13
|
+
// Es importante distinguir entre w-* (ancho) y max-w-*/min-w-* (límites),
|
|
14
|
+
// ya que un max-w-* sin un w-full puede hacer que la card colapse a su contenido.
|
|
15
|
+
const hasExplicitWidth = mergedClasses.split(/\s+/).some((cls) => {
|
|
16
|
+
const mainClass = cls.split(":").pop() || "";
|
|
17
|
+
return (mainClass.startsWith("w-") &&
|
|
18
|
+
mainClass !== "w-auto" &&
|
|
19
|
+
!mainClass.startsWith("max-w-") &&
|
|
20
|
+
!mainClass.startsWith("min-w-"));
|
|
21
|
+
});
|
|
22
|
+
// Si no hay un ancho explícito, forzamos w-full para que ocupe todo el espacio disponible
|
|
23
|
+
// (incluyendo el espacio limitado por un posible max-w- en la misma card o en su padre).
|
|
24
|
+
const classes = hasExplicitWidth ? mergedClasses : `${mergedClasses} w-full`;
|
|
28
25
|
const [isHovered, setIsHovered] = React.useState(false);
|
|
29
26
|
const [isLargeScreen, setIsLargeScreen] = React.useState(false);
|
|
30
27
|
React.useEffect(() => {
|
|
@@ -53,5 +50,5 @@ export const Card = ({ title, subtitle, children, className = "", headerActions,
|
|
|
53
50
|
};
|
|
54
51
|
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
52
|
opacity: getHeaderActionsOpacity(),
|
|
56
|
-
}, children: headerActions }))] }) })), children && _jsx("div", { className: "px-6 py-4", children: children }), footer && _jsx("div", { className: "px-6 pb-4 flex items-center justify-end", children: footer })] }));
|
|
53
|
+
}, children: headerActions }))] }) })), children && _jsx("div", { className: "px-6 py-4", children: children }), footer && (_jsx("div", { className: "px-6 pb-4 flex items-center justify-end", children: footer }))] }));
|
|
57
54
|
};
|
|
@@ -28,6 +28,12 @@ export interface DataTableProps<T> {
|
|
|
28
28
|
* Función opcional para aplicar clases CSS a una fila específica basada en sus datos.
|
|
29
29
|
*/
|
|
30
30
|
rowClassName?: (row: T) => string;
|
|
31
|
+
headerClassName?: string;
|
|
32
|
+
footerClassName?: string;
|
|
33
|
+
headerCellClassName?: string;
|
|
34
|
+
footerCellClassName?: string;
|
|
35
|
+
cellClassName?: string | ((row: T, column: DataTableColumn<T>) => string);
|
|
36
|
+
compact?: boolean;
|
|
31
37
|
}
|
|
32
|
-
export declare const DataTable: <T>({ columns, rows, className, maxRows, locale, isLoading, loadingRows, rowClassName, }: DataTableProps<T>) => import("react/jsx-runtime").JSX.Element;
|
|
38
|
+
export declare const DataTable: <T>({ columns, rows, className, maxRows, locale, isLoading, loadingRows, rowClassName, headerClassName, footerClassName, headerCellClassName, footerCellClassName, cellClassName, compact, }: DataTableProps<T>) => import("react/jsx-runtime").JSX.Element;
|
|
33
39
|
//# 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;
|
|
1
|
+
{"version":3,"file":"DataTable.d.ts","sourceRoot":"","sources":["../../../src/components/layout/DataTable.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAS1B,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;IACrB;;OAEG;IACH,YAAY,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC,KAAK,MAAM,CAAC;IAClC,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,aAAa,CAAC,EAAE,MAAM,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,MAAM,EAAE,eAAe,CAAC,CAAC,CAAC,KAAK,MAAM,CAAC,CAAC;IAC1E,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,eAAO,MAAM,SAAS,GAAI,CAAC,EAAG,0LAe3B,cAAc,CAAC,CAAC,CAAC,4CAmVnB,CAAC"}
|
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import React from "react";
|
|
3
|
+
import { twMerge } from "tailwind-merge";
|
|
3
4
|
import { DropdownMenu } from "./DropdownMenu";
|
|
4
|
-
export const DataTable = ({ columns, rows, className = "", maxRows, locale = "es-AR", isLoading = false, loadingRows = 5, rowClassName, }) => {
|
|
5
|
+
export const DataTable = ({ columns, rows, className = "", maxRows, locale = "es-AR", isLoading = false, loadingRows = 5, rowClassName, headerClassName = "", footerClassName = "", headerCellClassName = "", footerCellClassName = "", cellClassName = "", compact = false, }) => {
|
|
5
6
|
// Calcular si necesitamos scroll
|
|
6
7
|
const displayRows = isLoading ? loadingRows : rows.length;
|
|
7
8
|
const needsScroll = maxRows !== undefined && displayRows > maxRows;
|
|
8
|
-
// Altura aproximada de una fila (px-4 py-3 = ~48px por fila)
|
|
9
|
-
const rowHeight = 48;
|
|
9
|
+
// Altura aproximada de una fila (px-4 py-3 = ~48px por fila, compact es menos)
|
|
10
|
+
const rowHeight = compact ? 32 : 48;
|
|
10
11
|
const maxHeight = maxRows ? `${maxRows * rowHeight}px` : undefined;
|
|
12
|
+
const cellPadding = compact ? "px-2 py-1" : "px-4 py-3";
|
|
11
13
|
// Verificar si alguna columna tiene footer
|
|
12
14
|
const hasFooter = columns.some((column) => column.footer !== undefined);
|
|
13
15
|
const getCellValue = (column, row) => {
|
|
@@ -115,24 +117,20 @@ export const DataTable = ({ columns, rows, className = "", maxRows, locale = "es
|
|
|
115
117
|
};
|
|
116
118
|
// Componente Skeleton para celdas de carga
|
|
117
119
|
const SkeletonCell = () => (_jsx("div", { className: "h-4 bg-[var(--color-border-default)]/40 rounded animate-pulse w-full" }));
|
|
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) => {
|
|
120
|
+
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: twMerge("border-b border-[var(--color-border-default)]", headerClassName), children: columns.map((column, index) => {
|
|
119
121
|
const headerActions = column.headerActions?.();
|
|
120
122
|
const hasHeaderActions = headerActions && headerActions.length > 0;
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
`, style: {
|
|
123
|
+
const headerBgClasses = headerClassName
|
|
124
|
+
.split(/\s+/)
|
|
125
|
+
.filter((cls) => cls.split(":").pop()?.startsWith("bg-"))
|
|
126
|
+
.join(" ");
|
|
127
|
+
return (_jsx("th", { className: twMerge(cellPadding, "text-sm font-semibold text-[var(--color-text-primary)]", headerBgClasses || "bg-[var(--color-bg-secondary)]", getAlignmentClass(column.align, column.type), hasHeaderActions ? "relative" : "", headerCellClassName), style: {
|
|
127
128
|
...(column.width ? { width: column.width } : {}),
|
|
128
129
|
}, 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: () => {
|
|
129
130
|
// Las acciones ya manejan sus propios eventos
|
|
130
131
|
}, renderOption: (item) => item.content, replaceOnSingleOption: true })] })) : (column.header || "") }, index));
|
|
131
132
|
}) }) }), _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: {
|
|
133
|
+
? Array.from({ length: loadingRows }).map((_, rowIndex) => (_jsx("tr", { className: "border-b border-[var(--color-border-default)]", children: columns.map((column, colIndex) => (_jsx("td", { className: twMerge(cellPadding, "text-sm text-[var(--color-text-primary)]", getAlignmentClass(column.align, column.type)), style: {
|
|
136
134
|
...(column.width ? { width: column.width } : {}),
|
|
137
135
|
}, children: _jsx(SkeletonCell, {}) }, colIndex))) }, `skeleton-${rowIndex}`)))
|
|
138
136
|
: rows.map((row, rowIndex) => (_jsx("tr", { className: `group/row border-b border-[var(--color-border-default)] transition-colors hover:bg-[var(--color-bg-secondary)] ${rowClassName ? rowClassName(row) : ""}`, children: columns.map((column, colIndex) => {
|
|
@@ -143,10 +141,9 @@ export const DataTable = ({ columns, rows, className = "", maxRows, locale = "es
|
|
|
143
141
|
: undefined;
|
|
144
142
|
const rowActions = column.actions?.(row);
|
|
145
143
|
const hasRowActions = rowActions && rowActions.length > 0;
|
|
146
|
-
return (_jsx("td", { className:
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
`, style: {
|
|
144
|
+
return (_jsx("td", { className: twMerge(cellPadding, "text-sm text-[var(--color-text-primary)]", getAlignmentClass(column.align, column.type), typeof cellClassName === "function"
|
|
145
|
+
? cellClassName(row, column)
|
|
146
|
+
: cellClassName), style: {
|
|
150
147
|
...(column.width ? { width: column.width } : {}),
|
|
151
148
|
}, title: tooltip
|
|
152
149
|
? typeof tooltip === "string"
|
|
@@ -155,11 +152,13 @@ export const DataTable = ({ columns, rows, className = "", maxRows, locale = "es
|
|
|
155
152
|
: 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
153
|
// Las acciones ya manejan sus propios eventos
|
|
157
154
|
}, 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) =>
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
155
|
+
}) }, rowIndex))) }), hasFooter && (_jsx("tfoot", { className: needsScroll ? "sticky bottom-0 z-10" : "", children: _jsx("tr", { className: twMerge("border-t border-[var(--color-border-default)]", footerClassName), children: columns.map((column, index) => {
|
|
156
|
+
const footerBgClasses = footerClassName
|
|
157
|
+
.split(/\s+/)
|
|
158
|
+
.filter((cls) => cls.split(":").pop()?.startsWith("bg-"))
|
|
159
|
+
.join(" ");
|
|
160
|
+
return (_jsx("td", { className: twMerge(cellPadding, "text-sm font-semibold text-[var(--color-text-primary)]", footerBgClasses || "bg-[var(--color-bg-secondary)]", getAlignmentClass(column.align, column.type), footerCellClassName), style: {
|
|
161
|
+
...(column.width ? { width: column.width } : {}),
|
|
162
|
+
}, children: isLoading ? _jsx(SkeletonCell, {}) : column.footer || "" }, index));
|
|
163
|
+
}) }) }))] }) }) }));
|
|
165
164
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Snackbar.d.ts","sourceRoot":"","sources":["../../../src/components/utils/Snackbar.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAmD,MAAM,OAAO,CAAC;AACxE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAC;AAGtE,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,eAAe,CAAC;IACzB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;CAC/B;AAED,eAAO,MAAM,QAAQ,EAAE,KAAK,CAAC,EAAE,CAAC,aAAa,
|
|
1
|
+
{"version":3,"file":"Snackbar.d.ts","sourceRoot":"","sources":["../../../src/components/utils/Snackbar.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAmD,MAAM,OAAO,CAAC;AACxE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAC;AAGtE,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,eAAe,CAAC;IACzB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;CAC/B;AAED,eAAO,MAAM,QAAQ,EAAE,KAAK,CAAC,EAAE,CAAC,aAAa,CA8M5C,CAAC"}
|
|
@@ -7,6 +7,7 @@ export const Snackbar = React.memo(({ id, message, variant, duration = 3000, ico
|
|
|
7
7
|
const intervalRef = useRef(null);
|
|
8
8
|
const startTimeRef = useRef(Date.now());
|
|
9
9
|
const remainingTimeRef = useRef(duration);
|
|
10
|
+
const closingRef = useRef(false);
|
|
10
11
|
// Mapeo de variantes a colores y clases
|
|
11
12
|
const variantConfig = {
|
|
12
13
|
primary: {
|
|
@@ -49,19 +50,27 @@ export const Snackbar = React.memo(({ id, message, variant, duration = 3000, ico
|
|
|
49
50
|
const config = variantConfig[variant];
|
|
50
51
|
// Función para cerrar el snackbar
|
|
51
52
|
const handleClose = useCallback(() => {
|
|
53
|
+
if (closingRef.current)
|
|
54
|
+
return;
|
|
55
|
+
closingRef.current = true;
|
|
52
56
|
setIsClosing(true);
|
|
53
|
-
//
|
|
57
|
+
// Limpiar intervalo inmediatamente
|
|
58
|
+
if (intervalRef.current) {
|
|
59
|
+
clearInterval(intervalRef.current);
|
|
60
|
+
intervalRef.current = null;
|
|
61
|
+
}
|
|
62
|
+
// Esperar a que termine la animación antes de remover del estado global
|
|
54
63
|
setTimeout(() => {
|
|
55
64
|
onClose(id);
|
|
56
|
-
}, 300);
|
|
65
|
+
}, 300);
|
|
57
66
|
}, [id, onClose]);
|
|
58
67
|
// Efecto para la barra de progreso
|
|
59
68
|
useEffect(() => {
|
|
60
|
-
if (duration <= 0)
|
|
61
|
-
// Si duration es 0 o negativo, no se cierra automáticamente
|
|
69
|
+
if (duration <= 0)
|
|
62
70
|
return;
|
|
63
|
-
}
|
|
64
71
|
const updateProgress = () => {
|
|
72
|
+
if (closingRef.current)
|
|
73
|
+
return;
|
|
65
74
|
const elapsed = Date.now() - startTimeRef.current;
|
|
66
75
|
const newProgress = Math.max(0, 100 - (elapsed / duration) * 100);
|
|
67
76
|
setProgress(newProgress);
|
|
@@ -69,16 +78,17 @@ export const Snackbar = React.memo(({ id, message, variant, duration = 3000, ico
|
|
|
69
78
|
handleClose();
|
|
70
79
|
}
|
|
71
80
|
};
|
|
72
|
-
|
|
73
|
-
intervalRef.current = setInterval(updateProgress, 50);
|
|
81
|
+
intervalRef.current = window.setInterval(updateProgress, 50);
|
|
74
82
|
return () => {
|
|
75
83
|
if (intervalRef.current) {
|
|
76
|
-
clearInterval(intervalRef.current);
|
|
84
|
+
window.clearInterval(intervalRef.current);
|
|
77
85
|
}
|
|
78
86
|
};
|
|
79
87
|
}, [duration, handleClose]);
|
|
80
88
|
// Pausar el progreso cuando el mouse está sobre el snackbar
|
|
81
89
|
const handleMouseEnter = () => {
|
|
90
|
+
if (closingRef.current)
|
|
91
|
+
return;
|
|
82
92
|
if (intervalRef.current) {
|
|
83
93
|
clearInterval(intervalRef.current);
|
|
84
94
|
intervalRef.current = null;
|
|
@@ -88,9 +98,13 @@ export const Snackbar = React.memo(({ id, message, variant, duration = 3000, ico
|
|
|
88
98
|
};
|
|
89
99
|
// Reanudar el progreso cuando el mouse sale del snackbar
|
|
90
100
|
const handleMouseLeave = () => {
|
|
101
|
+
if (closingRef.current)
|
|
102
|
+
return;
|
|
91
103
|
if (remainingTimeRef.current > 0) {
|
|
92
104
|
startTimeRef.current = Date.now();
|
|
93
105
|
const updateProgress = () => {
|
|
106
|
+
if (closingRef.current)
|
|
107
|
+
return;
|
|
94
108
|
const elapsed = Date.now() - startTimeRef.current;
|
|
95
109
|
const newProgress = Math.max(0, ((remainingTimeRef.current - elapsed) / duration) * 100);
|
|
96
110
|
setProgress(newProgress);
|
|
@@ -98,7 +112,7 @@ export const Snackbar = React.memo(({ id, message, variant, duration = 3000, ico
|
|
|
98
112
|
handleClose();
|
|
99
113
|
}
|
|
100
114
|
};
|
|
101
|
-
intervalRef.current = setInterval(updateProgress, 50);
|
|
115
|
+
intervalRef.current = window.setInterval(updateProgress, 50);
|
|
102
116
|
}
|
|
103
117
|
};
|
|
104
118
|
// Íconos por defecto según la variante
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SnackbarContainer.d.ts","sourceRoot":"","sources":["../../../src/components/utils/SnackbarContainer.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"SnackbarContainer.d.ts","sourceRoot":"","sources":["../../../src/components/utils/SnackbarContainer.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAI1B,MAAM,WAAW,sBAAsB;IACrC,QAAQ,CAAC,EACL,WAAW,GACX,UAAU,GACV,cAAc,GACd,aAAa,GACb,YAAY,GACZ,eAAe,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,eAAO,MAAM,iBAAiB,EAAE,KAAK,CAAC,EAAE,CAAC,sBAAsB,CAiD9D,CAAC"}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
import React from "react";
|
|
3
|
-
import { useSnackbarState,
|
|
3
|
+
import { useSnackbarState, useSnackbar } from "../../contexts/SnackbarContext";
|
|
4
4
|
import { Snackbar } from "./Snackbar";
|
|
5
5
|
export const SnackbarContainer = ({ position = "top-right", maxSnackbars = 5, }) => {
|
|
6
6
|
const snackbars = useSnackbarState();
|
|
7
|
-
const { removeSnackbar } =
|
|
7
|
+
const { removeSnackbar } = useSnackbar();
|
|
8
8
|
// Limitar el número de snackbars visibles
|
|
9
9
|
const visibleSnackbars = snackbars.slice(-maxSnackbars);
|
|
10
10
|
// Clases de posición
|
|
@@ -23,21 +23,7 @@ interface SnackbarProviderProps {
|
|
|
23
23
|
children: ReactNode;
|
|
24
24
|
}
|
|
25
25
|
export declare const SnackbarProvider: React.FC<SnackbarProviderProps>;
|
|
26
|
-
export declare const
|
|
26
|
+
export declare const useSnackbar: () => SnackbarActionsType;
|
|
27
27
|
export declare const useSnackbarState: () => SnackbarMessage[];
|
|
28
|
-
/**
|
|
29
|
-
* Hook para acceder a todo el contexto de snackbars.
|
|
30
|
-
* NOTA: El uso de este hook causará re-renders cada vez que la lista de snackbars cambie.
|
|
31
|
-
* Si solo necesitas disparar snackbars, usa `useSnackbarActions`.
|
|
32
|
-
*/
|
|
33
|
-
export declare const useSnackbar: () => {
|
|
34
|
-
snackbars: SnackbarMessage[];
|
|
35
|
-
showSnackbar: (message: string, variant?: SnackbarVariant, options?: {
|
|
36
|
-
duration?: number;
|
|
37
|
-
icon?: string;
|
|
38
|
-
iconLabel?: string;
|
|
39
|
-
}) => void;
|
|
40
|
-
removeSnackbar: (id: string) => void;
|
|
41
|
-
};
|
|
42
28
|
export {};
|
|
43
29
|
//# sourceMappingURL=SnackbarContext.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SnackbarContext.d.ts","sourceRoot":"","sources":["../../src/contexts/SnackbarContext.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAMZ,KAAK,SAAS,EACf,MAAM,OAAO,CAAC;AAEf,MAAM,MAAM,eAAe,GACvB,SAAS,GACT,WAAW,GACX,SAAS,GACT,SAAS,GACT,QAAQ,GACR,MAAM,CAAC;AAEX,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,eAAe,CAAC;IACzB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,mBAAmB;IAClC,YAAY,EAAE,CACZ,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE,eAAe,EACzB,OAAO,CAAC,EAAE;QACR,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,SAAS,CAAC,EAAE,MAAM,CAAC;KACpB,KACE,IAAI,CAAC;IACV,cAAc,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;CACtC;AAED,MAAM,WAAW,mBAAoB,SAAQ,mBAAmB;IAC9D,SAAS,EAAE,eAAe,EAAE,CAAC;CAC9B;AASD,UAAU,qBAAqB;IAC7B,QAAQ,EAAE,SAAS,CAAC;CACrB;AAED,eAAO,MAAM,gBAAgB,EAAE,KAAK,CAAC,EAAE,CAAC,qBAAqB,CAiD5D,CAAC;AAEF,eAAO,MAAM,
|
|
1
|
+
{"version":3,"file":"SnackbarContext.d.ts","sourceRoot":"","sources":["../../src/contexts/SnackbarContext.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAMZ,KAAK,SAAS,EACf,MAAM,OAAO,CAAC;AAEf,MAAM,MAAM,eAAe,GACvB,SAAS,GACT,WAAW,GACX,SAAS,GACT,SAAS,GACT,QAAQ,GACR,MAAM,CAAC;AAEX,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,eAAe,CAAC;IACzB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,mBAAmB;IAClC,YAAY,EAAE,CACZ,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE,eAAe,EACzB,OAAO,CAAC,EAAE;QACR,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,SAAS,CAAC,EAAE,MAAM,CAAC;KACpB,KACE,IAAI,CAAC;IACV,cAAc,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;CACtC;AAED,MAAM,WAAW,mBAAoB,SAAQ,mBAAmB;IAC9D,SAAS,EAAE,eAAe,EAAE,CAAC;CAC9B;AASD,UAAU,qBAAqB;IAC7B,QAAQ,EAAE,SAAS,CAAC;CACrB;AAED,eAAO,MAAM,gBAAgB,EAAE,KAAK,CAAC,EAAE,CAAC,qBAAqB,CAiD5D,CAAC;AAEF,eAAO,MAAM,WAAW,QAAO,mBAM9B,CAAC;AAEF,eAAO,MAAM,gBAAgB,QAAO,eAAe,EAMlD,CAAC"}
|
|
@@ -25,10 +25,10 @@ export const SnackbarProvider = ({ children, }) => {
|
|
|
25
25
|
}), [showSnackbar, removeSnackbar]);
|
|
26
26
|
return (_jsx(SnackbarActionsContext.Provider, { value: actions, children: _jsx(SnackbarStateContext.Provider, { value: snackbars, children: children }) }));
|
|
27
27
|
};
|
|
28
|
-
export const
|
|
28
|
+
export const useSnackbar = () => {
|
|
29
29
|
const context = useContext(SnackbarActionsContext);
|
|
30
30
|
if (context === undefined) {
|
|
31
|
-
throw new Error("
|
|
31
|
+
throw new Error("useSnackbar must be used within a SnackbarProvider");
|
|
32
32
|
}
|
|
33
33
|
return context;
|
|
34
34
|
};
|
|
@@ -39,16 +39,3 @@ export const useSnackbarState = () => {
|
|
|
39
39
|
}
|
|
40
40
|
return context;
|
|
41
41
|
};
|
|
42
|
-
/**
|
|
43
|
-
* Hook para acceder a todo el contexto de snackbars.
|
|
44
|
-
* NOTA: El uso de este hook causará re-renders cada vez que la lista de snackbars cambie.
|
|
45
|
-
* Si solo necesitas disparar snackbars, usa `useSnackbarActions`.
|
|
46
|
-
*/
|
|
47
|
-
export const useSnackbar = () => {
|
|
48
|
-
const state = useSnackbarState();
|
|
49
|
-
const actions = useSnackbarActions();
|
|
50
|
-
return useMemo(() => ({
|
|
51
|
-
...actions,
|
|
52
|
-
snackbars: state,
|
|
53
|
-
}), [actions, state]);
|
|
54
|
-
};
|
package/dist/contexts/index.d.ts
CHANGED
|
@@ -8,6 +8,6 @@ export { CrudProvider, CrudContext, useCrud } from "./CrudContext";
|
|
|
8
8
|
export type { CrudContextType } from "./CrudContext";
|
|
9
9
|
export { AppLayoutProvider, useAppLayout, useAppLayoutContext } from "./AppLayoutContext";
|
|
10
10
|
export type { AppLayoutContextType, NavbarInterface, LeftDrawerInterface, } from "./AppLayoutContext";
|
|
11
|
-
export { SnackbarProvider, useSnackbar,
|
|
11
|
+
export { SnackbarProvider, useSnackbar, useSnackbarState, } from "./SnackbarContext";
|
|
12
12
|
export type { SnackbarContextType, SnackbarActionsType, SnackbarMessage, SnackbarVariant, } from "./SnackbarContext";
|
|
13
13
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/contexts/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAC1E,OAAO,EACL,gBAAgB,EAChB,oBAAoB,GACrB,MAAM,2BAA2B,CAAC;AAGnC,YAAY,EAAE,KAAK,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAGtE,OAAO,EACL,UAAU,EACV,SAAS,EACT,SAAS,EACT,UAAU,EACV,YAAY,EACZ,MAAM,GACP,MAAM,WAAW,CAAC;AAGnB,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC1D,YAAY,EACV,eAAe,EACf,wBAAwB,EACxB,kBAAkB,GACnB,MAAM,eAAe,CAAC;AAGvB,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AACnE,YAAY,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAGrD,OAAO,EAAE,iBAAiB,EAAE,YAAY,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAC1F,YAAY,EACV,oBAAoB,EACpB,eAAe,EACf,mBAAmB,GACpB,MAAM,oBAAoB,CAAC;AAG5B,OAAO,EACL,gBAAgB,EAChB,WAAW,EACX,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/contexts/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAC1E,OAAO,EACL,gBAAgB,EAChB,oBAAoB,GACrB,MAAM,2BAA2B,CAAC;AAGnC,YAAY,EAAE,KAAK,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAGtE,OAAO,EACL,UAAU,EACV,SAAS,EACT,SAAS,EACT,UAAU,EACV,YAAY,EACZ,MAAM,GACP,MAAM,WAAW,CAAC;AAGnB,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC1D,YAAY,EACV,eAAe,EACf,wBAAwB,EACxB,kBAAkB,GACnB,MAAM,eAAe,CAAC;AAGvB,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AACnE,YAAY,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAGrD,OAAO,EAAE,iBAAiB,EAAE,YAAY,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAC1F,YAAY,EACV,oBAAoB,EACpB,eAAe,EACf,mBAAmB,GACpB,MAAM,oBAAoB,CAAC;AAG5B,OAAO,EACL,gBAAgB,EAChB,WAAW,EACX,gBAAgB,GACjB,MAAM,mBAAmB,CAAC;AAC3B,YAAY,EACV,mBAAmB,EACnB,mBAAmB,EACnB,eAAe,EACf,eAAe,GAChB,MAAM,mBAAmB,CAAC"}
|
package/dist/contexts/index.js
CHANGED
|
@@ -10,4 +10,4 @@ export { CrudProvider, CrudContext, useCrud } from "./CrudContext";
|
|
|
10
10
|
// AppLayout system exports
|
|
11
11
|
export { AppLayoutProvider, useAppLayout, useAppLayoutContext } from "./AppLayoutContext";
|
|
12
12
|
// Snackbar system exports
|
|
13
|
-
export { SnackbarProvider, useSnackbar,
|
|
13
|
+
export { SnackbarProvider, useSnackbar, useSnackbarState, } from "./SnackbarContext";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DataTableDocs.d.ts","sourceRoot":"","sources":["../../src/docs/DataTableDocs.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAmB,MAAM,OAAO,CAAC;AAaxC,QAAA,MAAM,aAAa,EAAE,KAAK,CAAC,
|
|
1
|
+
{"version":3,"file":"DataTableDocs.d.ts","sourceRoot":"","sources":["../../src/docs/DataTableDocs.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAmB,MAAM,OAAO,CAAC;AAaxC,QAAA,MAAM,aAAa,EAAE,KAAK,CAAC,EAy+B1B,CAAC;AAEF,eAAe,aAAa,CAAC"}
|
|
@@ -239,6 +239,6 @@ const DataTableDocs = () => {
|
|
|
239
239
|
return (_jsx("div", { className: "max-w-5xl mx-auto space-y-8", children: _jsx(Card, { title: "DataTable - Variantes y Ejemplos", children: _jsxs("div", { className: "space-y-10", children: [_jsxs("section", { children: [_jsx("h3", { className: "text-lg font-semibold mb-4", style: { color: "var(--flysoft-text-primary)" }, children: "Tabla b\u00E1sica" }), _jsx("p", { className: "mb-4 text-sm", style: { color: "var(--flysoft-text-secondary)" }, children: "Ejemplo b\u00E1sico de una tabla con columnas simples usando nombres de propiedades." }), _jsx(Card, { children: _jsx(DataTable, { columns: basicColumns, rows: products }) })] }), _jsxs("section", { children: [_jsx("h3", { className: "text-lg font-semibold mb-4", style: { color: "var(--flysoft-text-primary)" }, children: "Tabla completa con tipos de datos" }), _jsx("p", { className: "mb-4 text-sm", style: { color: "var(--flysoft-text-secondary)" }, children: "Tabla con diferentes tipos de datos: currency, numeric y date. Las columnas se formatean autom\u00E1ticamente seg\u00FAn su tipo." }), _jsx(Card, { children: _jsx(DataTable, { columns: fullColumns, rows: products }) })] }), _jsxs("section", { children: [_jsx("h3", { className: "text-lg font-semibold mb-4", style: { color: "var(--flysoft-text-primary)" }, children: "Tabla con contenido personalizado y acciones" }), _jsxs("p", { className: "mb-4 text-sm", style: { color: "var(--flysoft-text-secondary)" }, children: ["Ejemplo con valores personalizados usando funciones, tooltips y componentes React como Badges. La columna de acciones usa la propiedad ", _jsx("code", { children: "actions" }), " que muestra un DropdownMenu con las acciones disponibles para cada fila. Cuando hay una sola acci\u00F3n (como en la columna \"Ver\"), se muestra directamente gracias a", " ", _jsx("code", { children: "replaceOnSingleOption" }), ", sin necesidad de abrir un men\u00FA."] }), _jsx(Card, { children: _jsx(DataTable, { columns: customColumns, rows: products }) })] }), _jsxs("section", { children: [_jsx("h3", { className: "text-lg font-semibold mb-4", style: { color: "var(--flysoft-text-primary)" }, children: "Tabla con headers personalizados y acciones en header" }), _jsxs("p", { className: "mb-4 text-sm", style: { color: "var(--flysoft-text-secondary)" }, children: ["Los headers pueden ser ReactNode, permitiendo incluir iconos u otros componentes personalizados. Tambi\u00E9n puedes usar", " ", _jsx("code", { children: "headerActions" }), " para agregar un DropdownMenu con acciones en el header de la columna."] }), _jsx(Card, { children: _jsx(DataTable, { columns: headerCustomColumns, rows: products }) })] }), _jsxs("section", { children: [_jsx("h3", { className: "text-lg font-semibold mb-4", style: { color: "var(--flysoft-text-primary)" }, children: "Tabla con scroll limitado (maxRows) y footer" }), _jsxs("p", { className: "mb-4 text-sm", style: { color: "var(--flysoft-text-secondary)" }, children: ["Usando la prop ", _jsx("code", { children: "maxRows" }), " puedes limitar el n\u00FAmero de filas visibles. Si hay m\u00E1s filas que el m\u00E1ximo, la tabla mostrar\u00E1 scroll solo en las filas mientras el header y el footer permanecen fijos. El footer se muestra usando la propiedad", " ", _jsx("code", { children: "footer" }), " en las columnas."] }), _jsx(Card, { children: _jsx(DataTable, { columns: fullColumns, rows: allProducts, maxRows: 5 }) })] }), _jsxs("section", { children: [_jsx("h3", { className: "text-lg font-semibold mb-4", style: { color: "var(--flysoft-text-primary)" }, children: "Tabla con locale personalizado" }), _jsxs("p", { className: "mb-4 text-sm", style: { color: "var(--flysoft-text-secondary)" }, children: ["Usando la prop ", _jsx("code", { children: "locale" }), " puedes cambiar el formato de los n\u00FAmeros (separador de miles y decimales). Por defecto usa", " ", _jsx("code", { children: "'es-AR'" }), ". En este ejemplo se usa ", _jsx("code", { children: "'en-US'" }), " ", "que formatea los n\u00FAmeros con coma como separador de miles y punto como separador decimal."] }), _jsx(Card, { children: _jsx(DataTable, { columns: fullColumns, rows: products, locale: "en-US" }) })] }), _jsxs("section", { children: [_jsx("h3", { className: "text-lg font-semibold mb-4", style: { color: "var(--flysoft-text-primary)" }, children: "Tabla con estado de carga (Loading)" }), _jsxs("p", { className: "mb-4 text-sm", style: { color: "var(--flysoft-text-secondary)" }, children: ["Usando las props ", _jsx("code", { children: "isLoading" }), " y ", _jsx("code", { children: "loadingRows" }), " ", "puedes mostrar un estado de carga con skeleton loaders. Cuando", " ", _jsx("code", { children: "isLoading" }), " es ", _jsx("code", { children: "true" }), ", la tabla muestra las columnas pero reemplaza las filas de datos con filas skeleton que simulan el contenido. El n\u00FAmero de filas skeleton se controla con", " ", _jsx("code", { children: "loadingRows" }), " (por defecto 5)."] }), _jsx("div", { className: "mb-4", children: _jsx(Button, { variant: "primary", icon: "fa-sync-alt", onClick: () => {
|
|
240
240
|
setIsLoading(true);
|
|
241
241
|
setTimeout(() => setIsLoading(false), 3000);
|
|
242
|
-
}, disabled: isLoading, children: isLoading ? "Cargando..." : "Simular carga" }) }), _jsx(Card, { children: _jsx(DataTable, { columns: fullColumns, rows: products, isLoading: isLoading, loadingRows: 5 }) })] }), _jsxs("section", { children: [_jsx("h3", { className: "text-lg font-semibold mb-4", style: { color: "var(--flysoft-text-primary)" }, children: "Tabla con estilos condicionales (rowClassName)" }), _jsxs("p", { className: "mb-4 text-sm", style: { color: "var(--flysoft-text-secondary)" }, children: ["Usando la prop ", _jsx("code", { children: "rowClassName" }), " puedes aplicar clases CSS a filas espec\u00EDficas bas\u00E1ndote en sus datos. En este ejemplo, los productos sin stock se resaltan con un fondo rojo suave."] }), _jsx(Card, { children: _jsx(DataTable, { columns: basicColumns, rows: products, rowClassName: (row) => row.stock === 0 ? "bg-red-50 dark:bg-red-900/20" : "" }) })] }), _jsxs("section", { children: [_jsx("h3", { className: "text-lg font-semibold mb-4", style: { color: "var(--flysoft-text-primary)" }, children: "Caracter\u00EDsticas" }), _jsx("div", { className: "space-y-3", children: _jsx("div", { className: "p-3 bg-[var(--color-bg-default)] border border-[var(--color-border-default)] rounded", children: _jsxs("ul", { className: "list-disc list-inside space-y-2 text-sm", style: { color: "var(--flysoft-text-secondary)" }, children: [_jsxs("li", { children: [_jsx("strong", { children: "Tipos de datos:" }), " Soporta text, numeric, currency y date con formateo autom\u00E1tico"] }), _jsxs("li", { children: [_jsx("strong", { children: "Acciones por fila:" }), " Usa la propiedad", " ", _jsx("code", { children: "actions" }), " para mostrar un DropdownMenu con acciones espec\u00EDficas para cada fila"] }), _jsxs("li", { children: [_jsx("strong", { children: "Acciones en header:" }), " Usa la propiedad", " ", _jsx("code", { children: "headerActions" }), " para mostrar un DropdownMenu con acciones en el header de la columna"] }), _jsxs("li", { children: [_jsx("strong", { children: "Alineaci\u00F3n:" }), " Cada columna puede tener su propia alineaci\u00F3n (left, right, center)"] }), _jsxs("li", { children: [_jsx("strong", { children: "Ancho personalizado:" }), " Puedes definir el ancho de cada columna usando la propiedad width"] }), _jsxs("li", { children: [_jsx("strong", { children: "Valores personalizados:" }), " El value puede ser una funci\u00F3n que recibe la fila completa y retorna ReactNode"] }), _jsxs("li", { children: [_jsx("strong", { children: "Tooltips:" }), " Soporte para tooltips personalizados por celda"] }), _jsxs("li", { children: [_jsx("strong", { children: "Headers personalizados:" }), " Los headers pueden ser ReactNode para incluir iconos o componentes"] }), _jsxs("li", { children: [_jsx("strong", { children: "Hover effect:" }), " Las filas tienen un efecto hover para mejor UX"] }), _jsxs("li", { children: [_jsx("strong", { children: "Responsive:" }), " La tabla tiene scroll horizontal autom\u00E1tico en pantallas peque\u00F1as"] }), _jsxs("li", { children: [_jsx("strong", { children: "Scroll limitado:" }), " Con maxRows puedes limitar el n\u00FAmero de filas visibles, manteniendo el header fijo y permitiendo scroll solo en las filas"] }), _jsxs("li", { children: [_jsx("strong", { children: "Estilos condicionales:" }), " Usa", " ", _jsx("code", { children: "rowClassName" }), " para aplicar clases CSS a filas espec\u00EDficas seg\u00FAn sus datos"] })] }) }) })] }), _jsxs("section", { children: [_jsx("h3", { className: "text-lg font-semibold mb-4", style: { color: "var(--flysoft-text-primary)" }, children: "Props" }), _jsx("div", { className: "overflow-x-auto", children: _jsxs("table", { className: "w-full border-collapse", children: [_jsx("thead", { children: _jsxs("tr", { className: "border-b border-[var(--color-border-default)]", children: [_jsx("th", { className: "text-left p-3 font-semibold", style: { color: "var(--flysoft-text-primary)" }, children: "Prop" }), _jsx("th", { className: "text-left p-3 font-semibold", style: { color: "var(--flysoft-text-primary)" }, children: "Tipo" }), _jsx("th", { className: "text-left p-3 font-semibold", style: { color: "var(--flysoft-text-primary)" }, children: "Descripci\u00F3n" })] }) }), _jsxs("tbody", { children: [_jsxs("tr", { className: "border-b border-[var(--color-border-default)]", children: [_jsx("td", { className: "p-3", children: _jsx("code", { className: "text-sm text-[var(--color-primary)]", children: "columns" }) }), _jsx("td", { className: "p-3 text-sm", children: "DataTableColumn<T>[]" }), _jsx("td", { className: "p-3 text-sm", children: "Array de columnas que define la estructura de la tabla" })] }), _jsxs("tr", { className: "border-b border-[var(--color-border-default)]", children: [_jsx("td", { className: "p-3", children: _jsx("code", { className: "text-sm text-[var(--color-primary)]", children: "rows" }) }), _jsx("td", { className: "p-3 text-sm", children: "T[]" }), _jsx("td", { className: "p-3 text-sm", children: "Array de objetos que representan las filas de la tabla" })] }), _jsxs("tr", { className: "border-b border-[var(--color-border-default)]", children: [_jsx("td", { className: "p-3", children: _jsx("code", { className: "text-sm text-[var(--color-primary)]", children: "className" }) }), _jsx("td", { className: "p-3 text-sm", children: "string" }), _jsx("td", { className: "p-3 text-sm", children: "Clases CSS adicionales para el contenedor de la tabla" })] }), _jsxs("tr", { className: "border-b border-[var(--color-border-default)]", children: [_jsx("td", { className: "p-3", children: _jsx("code", { className: "text-sm text-[var(--color-primary)]", children: "maxRows" }) }), _jsx("td", { className: "p-3 text-sm", children: "number" }), _jsx("td", { className: "p-3 text-sm", children: "M\u00E1ximo n\u00FAmero de filas visibles. Si hay m\u00E1s filas, se activa scroll vertical manteniendo el header fijo" })] }), _jsxs("tr", { className: "border-b border-[var(--color-border-default)]", children: [_jsx("td", { className: "p-3", children: _jsx("code", { className: "text-sm text-[var(--color-primary)]", children: "locale" }) }), _jsx("td", { className: "p-3 text-sm", children: "string" }), _jsxs("td", { className: "p-3 text-sm", children: ["Locale para formateo de n\u00FAmeros (currency y numeric). Por defecto es ", _jsx("code", { children: "'es-AR'" }), ". Ejemplos:", " ", _jsx("code", { children: "'en-US'" }), ", ", _jsx("code", { children: "'es-ES'" }), ",", " ", _jsx("code", { children: "'de-DE'" })] })] }), _jsxs("tr", { className: "border-b border-[var(--color-border-default)]", children: [_jsx("td", { className: "p-3", children: _jsx("code", { className: "text-sm text-[var(--color-primary)]", children: "isLoading" }) }), _jsx("td", { className: "p-3 text-sm", children: "boolean" }), _jsxs("td", { className: "p-3 text-sm", children: ["Estado de carga. Cuando es ", _jsx("code", { children: "true" }), ", muestra filas skeleton en lugar de los datos. Por defecto es", " ", _jsx("code", { children: "false" })] })] }), _jsxs("tr", { className: "border-b border-[var(--color-border-default)]", children: [_jsx("td", { className: "p-3", children: _jsx("code", { className: "text-sm text-[var(--color-primary)]", children: "loadingRows" }) }), _jsx("td", { className: "p-3 text-sm", children: "number" }), _jsxs("td", { className: "p-3 text-sm", children: ["N\u00FAmero de filas skeleton a mostrar cuando", " ", _jsx("code", { children: "isLoading" }), " es ", _jsx("code", { children: "true" }), ". Por defecto es ", _jsx("code", { children: "isLoading" }), " es ", _jsx("code", { children: "true" }), ". Por defecto es ", _jsx("code", { children: "5" })] })] }), _jsxs("tr", { className: "border-b border-[var(--color-border-default)]", children: [_jsx("td", { className: "p-3", children: _jsx("code", { className: "text-sm text-[var(--color-primary)]", children: "rowClassName" }) }), _jsx("td", { className: "p-3 text-sm", children: "(row: T) => string" }), _jsx("td", { className: "p-3 text-sm", children: "Funci\u00F3n opcional para aplicar clases CSS a una fila espec\u00EDfica basada en sus datos" })] })] })] }) })] }), _jsxs("section", { children: [_jsx("h3", { className: "text-lg font-semibold mb-4", style: { color: "var(--flysoft-text-primary)" }, children: "DataTableColumn Props" }), _jsx("div", { className: "overflow-x-auto", children: _jsxs("table", { className: "w-full border-collapse", children: [_jsx("thead", { children: _jsxs("tr", { className: "border-b border-[var(--color-border-default)]", children: [_jsx("th", { className: "text-left p-3 font-semibold", style: { color: "var(--flysoft-text-primary)" }, children: "Prop" }), _jsx("th", { className: "text-left p-3 font-semibold", style: { color: "var(--flysoft-text-primary)" }, children: "Tipo" }), _jsx("th", { className: "text-left p-3 font-semibold", style: { color: "var(--flysoft-text-primary)" }, children: "Descripci\u00F3n" })] }) }), _jsxs("tbody", { children: [_jsxs("tr", { className: "border-b border-[var(--color-border-default)]", children: [_jsx("td", { className: "p-3", children: _jsx("code", { className: "text-sm text-[var(--color-primary)]", children: "align" }) }), _jsx("td", { className: "p-3 text-sm", children: "\"left\" | \"right\" | \"center\"" }), _jsx("td", { className: "p-3 text-sm", children: "Alineaci\u00F3n del contenido de la columna" })] }), _jsxs("tr", { className: "border-b border-[var(--color-border-default)]", children: [_jsx("td", { className: "p-3", children: _jsx("code", { className: "text-sm text-[var(--color-primary)]", children: "width" }) }), _jsx("td", { className: "p-3 text-sm", children: "string" }), _jsx("td", { className: "p-3 text-sm", children: "Ancho de la columna (ej: \"100px\", \"20%\")" })] }), _jsxs("tr", { className: "border-b border-[var(--color-border-default)]", children: [_jsx("td", { className: "p-3", children: _jsx("code", { className: "text-sm text-[var(--color-primary)]", children: "header" }) }), _jsx("td", { className: "p-3 text-sm", children: "string | ReactNode" }), _jsx("td", { className: "p-3 text-sm", children: "Texto o componente React para el header de la columna" })] }), _jsxs("tr", { className: "border-b border-[var(--color-border-default)]", children: [_jsx("td", { className: "p-3", children: _jsx("code", { className: "text-sm text-[var(--color-primary)]", children: "value" }) }), _jsx("td", { className: "p-3 text-sm", children: "string | number | ((row: T) => string | ReactNode)" }), _jsx("td", { className: "p-3 text-sm", children: "Nombre de la propiedad del objeto, valor directo, o funci\u00F3n que retorna el valor a mostrar" })] }), _jsxs("tr", { className: "border-b border-[var(--color-border-default)]", children: [_jsx("td", { className: "p-3", children: _jsx("code", { className: "text-sm text-[var(--color-primary)]", children: "tooltip" }) }), _jsx("td", { className: "p-3 text-sm", children: "(row: T) => string | ReactNode" }), _jsx("td", { className: "p-3 text-sm", children: "Funci\u00F3n que retorna el tooltip a mostrar al hacer hover sobre la celda" })] }), _jsxs("tr", { className: "border-b border-[var(--color-border-default)]", children: [_jsx("td", { className: "p-3", children: _jsx("code", { className: "text-sm text-[var(--color-primary)]", children: "type" }) }), _jsx("td", { className: "p-3 text-sm", children: "\"text\" | \"numeric\" | \"currency\" | \"date\"" }), _jsx("td", { className: "p-3 text-sm", children: "Tipo de dato que determina el formateo autom\u00E1tico" })] }), _jsxs("tr", { className: "border-b border-[var(--color-border-default)]", children: [_jsx("td", { className: "p-3", children: _jsx("code", { className: "text-sm text-[var(--color-primary)]", children: "actions" }) }), _jsx("td", { className: "p-3 text-sm", children: "(row: T) => Array<ReactNode>" }), _jsx("td", { className: "p-3 text-sm", children: "Funci\u00F3n que retorna un array de ReactNode que se mostrar\u00E1n en un DropdownMenu para cada fila. Las acciones deben manejar sus propios eventos onClick." })] }), _jsxs("tr", { className: "border-b border-[var(--color-border-default)]", children: [_jsx("td", { className: "p-3", children: _jsx("code", { className: "text-sm text-[var(--color-primary)]", children: "headerActions" }) }), _jsx("td", { className: "p-3 text-sm", children: "() => Array<ReactNode>" }), _jsx("td", { className: "p-3 text-sm", children: "Funci\u00F3n que retorna un array de ReactNode que se mostrar\u00E1n en un DropdownMenu en el header de la columna. Las acciones deben manejar sus propios eventos onClick." })] })] })] }) })] })] }) }) }));
|
|
242
|
+
}, disabled: isLoading, children: isLoading ? "Cargando..." : "Simular carga" }) }), _jsx(Card, { children: _jsx(DataTable, { columns: fullColumns, rows: products, isLoading: isLoading, loadingRows: 5 }) })] }), _jsxs("section", { children: [_jsx("h3", { className: "text-lg font-semibold mb-4", style: { color: "var(--flysoft-text-primary)" }, children: "Tabla con estilos condicionales (rowClassName)" }), _jsxs("p", { className: "mb-4 text-sm", style: { color: "var(--flysoft-text-secondary)" }, children: ["Usando la prop ", _jsx("code", { children: "rowClassName" }), " puedes aplicar clases CSS a filas espec\u00EDficas bas\u00E1ndote en sus datos. En este ejemplo, los productos sin stock se resaltan con un fondo rojo suave."] }), _jsx(Card, { children: _jsx(DataTable, { columns: basicColumns, rows: products, rowClassName: (row) => row.stock === 0 ? "bg-red-50 dark:bg-red-900/20" : "" }) })] }), _jsxs("section", { children: [_jsx("h3", { className: "text-lg font-semibold mb-4", style: { color: "var(--flysoft-text-primary)" }, children: "Tabla con estilos de Header y Footer" }), _jsxs("p", { className: "mb-4 text-sm", style: { color: "var(--flysoft-text-secondary)" }, children: ["Usando las props ", _jsx("code", { children: "headerClassName" }), " y", " ", _jsx("code", { children: "footerClassName" }), " puedes aplicar clases CSS directamente a las filas del header y footer. En este ejemplo, se aplica un fondo azul suave al header y un borde superior m\u00E1s grueso al footer."] }), _jsx(Card, { children: _jsx(DataTable, { columns: fullColumns, rows: products, headerClassName: "bg-red-50/50 border-b-2 border-primary", footerClassName: "border-t-2 border-primary bg-green-500" }) })] }), _jsxs("section", { children: [_jsx("h3", { className: "text-lg font-semibold mb-4", style: { color: "var(--flysoft-text-primary)" }, children: "Tabla con estilos de Celdas (Cell ClassNames)" }), _jsxs("p", { className: "mb-4 text-sm", style: { color: "var(--flysoft-text-secondary)" }, children: ["Adem\u00E1s de las filas, puedes aplicar clases espec\u00EDficamente a las celdas del header, footer y body. El ", _jsx("code", { children: "cellClassName" }), " ", "del body puede ser un string o una funci\u00F3n que recibe la fila y la columna para un control total."] }), _jsx(Card, { children: _jsx(DataTable, { columns: basicColumns, rows: products, headerCellClassName: "text-primary italic uppercase tracking-wider", cellClassName: (_row, column) => column.value === "name" ? "font-bold text-blue-600" : "" }) })] }), _jsxs("section", { children: [_jsx("h3", { className: "text-lg font-semibold mb-4", style: { color: "var(--flysoft-text-primary)" }, children: "Tabla Compacta" }), _jsxs("p", { className: "mb-4 text-sm", style: { color: "var(--flysoft-text-secondary)" }, children: ["Usando la prop ", _jsx("code", { children: "compact" }), " puedes reducir significativamente el espacio que ocupa la tabla. Este modo elimina los paddings superiores y reduce los horizontales, ideal para mostrar grandes cantidades de datos en espacios reducidos."] }), _jsx(Card, { children: _jsx(DataTable, { columns: basicColumns, rows: products, compact: true }) })] }), _jsxs("section", { children: [_jsx("h3", { className: "text-lg font-semibold mb-4", style: { color: "var(--flysoft-text-primary)" }, children: "Caracter\u00EDsticas" }), _jsx("div", { className: "space-y-3", children: _jsx("div", { className: "p-3 bg-[var(--color-bg-default)] border border-[var(--color-border-default)] rounded", children: _jsxs("ul", { className: "list-disc list-inside space-y-2 text-sm", style: { color: "var(--flysoft-text-secondary)" }, children: [_jsxs("li", { children: [_jsx("strong", { children: "Tipos de datos:" }), " Soporta text, numeric, currency y date con formateo autom\u00E1tico"] }), _jsxs("li", { children: [_jsx("strong", { children: "Acciones por fila:" }), " Usa la propiedad", " ", _jsx("code", { children: "actions" }), " para mostrar un DropdownMenu con acciones espec\u00EDficas para cada fila"] }), _jsxs("li", { children: [_jsx("strong", { children: "Acciones en header:" }), " Usa la propiedad", " ", _jsx("code", { children: "headerActions" }), " para mostrar un DropdownMenu con acciones en el header de la columna"] }), _jsxs("li", { children: [_jsx("strong", { children: "Alineaci\u00F3n:" }), " Cada columna puede tener su propia alineaci\u00F3n (left, right, center)"] }), _jsxs("li", { children: [_jsx("strong", { children: "Ancho personalizado:" }), " Puedes definir el ancho de cada columna usando la propiedad width"] }), _jsxs("li", { children: [_jsx("strong", { children: "Valores personalizados:" }), " El value puede ser una funci\u00F3n que recibe la fila completa y retorna ReactNode"] }), _jsxs("li", { children: [_jsx("strong", { children: "Tooltips:" }), " Soporte para tooltips personalizados por celda"] }), _jsxs("li", { children: [_jsx("strong", { children: "Headers personalizados:" }), " Los headers pueden ser ReactNode para incluir iconos o componentes"] }), _jsxs("li", { children: [_jsx("strong", { children: "Hover effect:" }), " Las filas tienen un efecto hover para mejor UX"] }), _jsxs("li", { children: [_jsx("strong", { children: "Responsive:" }), " La tabla tiene scroll horizontal autom\u00E1tico en pantallas peque\u00F1as"] }), _jsxs("li", { children: [_jsx("strong", { children: "Scroll limitado:" }), " Con maxRows puedes limitar el n\u00FAmero de filas visibles, manteniendo el header fijo y permitiendo scroll solo en las filas"] }), _jsxs("li", { children: [_jsx("strong", { children: "Estilos condicionales:" }), " Usa", " ", _jsx("code", { children: "rowClassName" }), " para aplicar clases CSS a filas espec\u00EDficas seg\u00FAn sus datos"] })] }) }) })] }), _jsxs("section", { children: [_jsx("h3", { className: "text-lg font-semibold mb-4", style: { color: "var(--flysoft-text-primary)" }, children: "Props" }), _jsx("div", { className: "overflow-x-auto", children: _jsxs("table", { className: "w-full border-collapse", children: [_jsx("thead", { children: _jsxs("tr", { className: "border-b border-[var(--color-border-default)]", children: [_jsx("th", { className: "text-left p-3 font-semibold", style: { color: "var(--flysoft-text-primary)" }, children: "Prop" }), _jsx("th", { className: "text-left p-3 font-semibold", style: { color: "var(--flysoft-text-primary)" }, children: "Tipo" }), _jsx("th", { className: "text-left p-3 font-semibold", style: { color: "var(--flysoft-text-primary)" }, children: "Descripci\u00F3n" })] }) }), _jsxs("tbody", { children: [_jsxs("tr", { className: "border-b border-[var(--color-border-default)]", children: [_jsx("td", { className: "p-3", children: _jsx("code", { className: "text-sm text-[var(--color-primary)]", children: "columns" }) }), _jsx("td", { className: "p-3 text-sm", children: "DataTableColumn<T>[]" }), _jsx("td", { className: "p-3 text-sm", children: "Array de columnas que define la estructura de la tabla" })] }), _jsxs("tr", { className: "border-b border-[var(--color-border-default)]", children: [_jsx("td", { className: "p-3", children: _jsx("code", { className: "text-sm text-[var(--color-primary)]", children: "rows" }) }), _jsx("td", { className: "p-3 text-sm", children: "T[]" }), _jsx("td", { className: "p-3 text-sm", children: "Array de objetos que representan las filas de la tabla" })] }), _jsxs("tr", { className: "border-b border-[var(--color-border-default)]", children: [_jsx("td", { className: "p-3", children: _jsx("code", { className: "text-sm text-[var(--color-primary)]", children: "className" }) }), _jsx("td", { className: "p-3 text-sm", children: "string" }), _jsx("td", { className: "p-3 text-sm", children: "Clases CSS adicionales para el contenedor de la tabla" })] }), _jsxs("tr", { className: "border-b border-[var(--color-border-default)]", children: [_jsx("td", { className: "p-3", children: _jsx("code", { className: "text-sm text-[var(--color-primary)]", children: "maxRows" }) }), _jsx("td", { className: "p-3 text-sm", children: "number" }), _jsx("td", { className: "p-3 text-sm", children: "M\u00E1ximo n\u00FAmero de filas visibles. Si hay m\u00E1s filas, se activa scroll vertical manteniendo el header fijo" })] }), _jsxs("tr", { className: "border-b border-[var(--color-border-default)]", children: [_jsx("td", { className: "p-3", children: _jsx("code", { className: "text-sm text-[var(--color-primary)]", children: "locale" }) }), _jsx("td", { className: "p-3 text-sm", children: "string" }), _jsxs("td", { className: "p-3 text-sm", children: ["Locale para formateo de n\u00FAmeros (currency y numeric). Por defecto es ", _jsx("code", { children: "'es-AR'" }), ". Ejemplos:", " ", _jsx("code", { children: "'en-US'" }), ", ", _jsx("code", { children: "'es-ES'" }), ",", " ", _jsx("code", { children: "'de-DE'" })] })] }), _jsxs("tr", { className: "border-b border-[var(--color-border-default)]", children: [_jsx("td", { className: "p-3", children: _jsx("code", { className: "text-sm text-[var(--color-primary)]", children: "isLoading" }) }), _jsx("td", { className: "p-3 text-sm", children: "boolean" }), _jsxs("td", { className: "p-3 text-sm", children: ["Estado de carga. Cuando es ", _jsx("code", { children: "true" }), ", muestra filas skeleton en lugar de los datos. Por defecto es", " ", _jsx("code", { children: "false" })] })] }), _jsxs("tr", { className: "border-b border-[var(--color-border-default)]", children: [_jsx("td", { className: "p-3", children: _jsx("code", { className: "text-sm text-[var(--color-primary)]", children: "loadingRows" }) }), _jsx("td", { className: "p-3 text-sm", children: "number" }), _jsxs("td", { className: "p-3 text-sm", children: ["N\u00FAmero de filas skeleton a mostrar cuando", " ", _jsx("code", { children: "isLoading" }), " es ", _jsx("code", { children: "true" }), ". Por defecto es ", _jsx("code", { children: "isLoading" }), " es ", _jsx("code", { children: "true" }), ". Por defecto es ", _jsx("code", { children: "5" })] })] }), _jsxs("tr", { className: "border-b border-[var(--color-border-default)]", children: [_jsx("td", { className: "p-3", children: _jsx("code", { className: "text-sm text-[var(--color-primary)]", children: "rowClassName" }) }), _jsx("td", { className: "p-3 text-sm", children: "(row: T) => string" }), _jsx("td", { className: "p-3 text-sm", children: "Funci\u00F3n opcional para aplicar clases CSS a una fila espec\u00EDfica basada en sus datos" })] }), _jsxs("tr", { className: "border-b border-[var(--color-border-default)]", children: [_jsx("td", { className: "p-3", children: _jsx("code", { className: "text-sm text-[var(--color-primary)]", children: "headerClassName" }) }), _jsx("td", { className: "p-3 text-sm", children: "string" }), _jsx("td", { className: "p-3 text-sm", children: "Clases CSS adicionales para la fila del header (tr)" })] }), _jsxs("tr", { className: "border-b border-[var(--color-border-default)]", children: [_jsx("td", { className: "p-3", children: _jsx("code", { className: "text-sm text-[var(--color-primary)]", children: "footerClassName" }) }), _jsx("td", { className: "p-3 text-sm", children: "string" }), _jsx("td", { className: "p-3 text-sm", children: "Clases CSS adicionales para la fila del footer (tr)" })] }), _jsxs("tr", { className: "border-b border-[var(--color-border-default)]", children: [_jsx("td", { className: "p-3", children: _jsx("code", { className: "text-sm text-[var(--color-primary)]", children: "headerCellClassName" }) }), _jsx("td", { className: "p-3 text-sm", children: "string" }), _jsx("td", { className: "p-3 text-sm", children: "Clases CSS adicionales para todas las celdas del header (th)" })] }), _jsxs("tr", { className: "border-b border-[var(--color-border-default)]", children: [_jsx("td", { className: "p-3", children: _jsx("code", { className: "text-sm text-[var(--color-primary)]", children: "footerCellClassName" }) }), _jsx("td", { className: "p-3 text-sm", children: "string" }), _jsx("td", { className: "p-3 text-sm", children: "Clases CSS adicionales para todas las celdas del footer (td)" })] }), _jsxs("tr", { className: "border-b border-[var(--color-border-default)]", children: [_jsx("td", { className: "p-3", children: _jsx("code", { className: "text-sm text-[var(--color-primary)]", children: "cellClassName" }) }), _jsx("td", { className: "p-3 text-sm", children: "string | ((row: T, col: Col) => string)" }), _jsx("td", { className: "p-3 text-sm", children: "Clases CSS para celdas del body. Puede ser una funci\u00F3n para l\u00F3gica condicional por celda" })] }), _jsxs("tr", { className: "border-b border-[var(--color-border-default)]", children: [_jsx("td", { className: "p-3", children: _jsx("code", { className: "text-sm text-[var(--color-primary)]", children: "compact" }) }), _jsx("td", { className: "p-3 text-sm", children: "boolean" }), _jsx("td", { className: "p-3 text-sm", children: "Si es true, reduce el padding de todas las celdas para una visualizaci\u00F3n m\u00E1s densa. Por defecto es false." })] })] })] }) })] }), _jsxs("section", { children: [_jsx("h3", { className: "text-lg font-semibold mb-4", style: { color: "var(--flysoft-text-primary)" }, children: "DataTableColumn Props" }), _jsx("div", { className: "overflow-x-auto", children: _jsxs("table", { className: "w-full border-collapse", children: [_jsx("thead", { children: _jsxs("tr", { className: "border-b border-[var(--color-border-default)]", children: [_jsx("th", { className: "text-left p-3 font-semibold", style: { color: "var(--flysoft-text-primary)" }, children: "Prop" }), _jsx("th", { className: "text-left p-3 font-semibold", style: { color: "var(--flysoft-text-primary)" }, children: "Tipo" }), _jsx("th", { className: "text-left p-3 font-semibold", style: { color: "var(--flysoft-text-primary)" }, children: "Descripci\u00F3n" })] }) }), _jsxs("tbody", { children: [_jsxs("tr", { className: "border-b border-[var(--color-border-default)]", children: [_jsx("td", { className: "p-3", children: _jsx("code", { className: "text-sm text-[var(--color-primary)]", children: "align" }) }), _jsx("td", { className: "p-3 text-sm", children: "\"left\" | \"right\" | \"center\"" }), _jsx("td", { className: "p-3 text-sm", children: "Alineaci\u00F3n del contenido de la columna" })] }), _jsxs("tr", { className: "border-b border-[var(--color-border-default)]", children: [_jsx("td", { className: "p-3", children: _jsx("code", { className: "text-sm text-[var(--color-primary)]", children: "width" }) }), _jsx("td", { className: "p-3 text-sm", children: "string" }), _jsx("td", { className: "p-3 text-sm", children: "Ancho de la columna (ej: \"100px\", \"20%\")" })] }), _jsxs("tr", { className: "border-b border-[var(--color-border-default)]", children: [_jsx("td", { className: "p-3", children: _jsx("code", { className: "text-sm text-[var(--color-primary)]", children: "header" }) }), _jsx("td", { className: "p-3 text-sm", children: "string | ReactNode" }), _jsx("td", { className: "p-3 text-sm", children: "Texto o componente React para el header de la columna" })] }), _jsxs("tr", { className: "border-b border-[var(--color-border-default)]", children: [_jsx("td", { className: "p-3", children: _jsx("code", { className: "text-sm text-[var(--color-primary)]", children: "value" }) }), _jsx("td", { className: "p-3 text-sm", children: "string | number | ((row: T) => string | ReactNode)" }), _jsx("td", { className: "p-3 text-sm", children: "Nombre de la propiedad del objeto, valor directo, o funci\u00F3n que retorna el valor a mostrar" })] }), _jsxs("tr", { className: "border-b border-[var(--color-border-default)]", children: [_jsx("td", { className: "p-3", children: _jsx("code", { className: "text-sm text-[var(--color-primary)]", children: "tooltip" }) }), _jsx("td", { className: "p-3 text-sm", children: "(row: T) => string | ReactNode" }), _jsx("td", { className: "p-3 text-sm", children: "Funci\u00F3n que retorna el tooltip a mostrar al hacer hover sobre la celda" })] }), _jsxs("tr", { className: "border-b border-[var(--color-border-default)]", children: [_jsx("td", { className: "p-3", children: _jsx("code", { className: "text-sm text-[var(--color-primary)]", children: "type" }) }), _jsx("td", { className: "p-3 text-sm", children: "\"text\" | \"numeric\" | \"currency\" | \"date\"" }), _jsx("td", { className: "p-3 text-sm", children: "Tipo de dato que determina el formateo autom\u00E1tico" })] }), _jsxs("tr", { className: "border-b border-[var(--color-border-default)]", children: [_jsx("td", { className: "p-3", children: _jsx("code", { className: "text-sm text-[var(--color-primary)]", children: "actions" }) }), _jsx("td", { className: "p-3 text-sm", children: "(row: T) => Array<ReactNode>" }), _jsx("td", { className: "p-3 text-sm", children: "Funci\u00F3n que retorna un array de ReactNode que se mostrar\u00E1n en un DropdownMenu para cada fila. Las acciones deben manejar sus propios eventos onClick." })] }), _jsxs("tr", { className: "border-b border-[var(--color-border-default)]", children: [_jsx("td", { className: "p-3", children: _jsx("code", { className: "text-sm text-[var(--color-primary)]", children: "headerActions" }) }), _jsx("td", { className: "p-3 text-sm", children: "() => Array<ReactNode>" }), _jsx("td", { className: "p-3 text-sm", children: "Funci\u00F3n que retorna un array de ReactNode que se mostrar\u00E1n en un DropdownMenu en el header de la columna. Las acciones deben manejar sus propios eventos onClick." })] })] })] }) })] })] }) }) }));
|
|
243
243
|
};
|
|
244
244
|
export default DataTableDocs;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SnackbarDocs.d.ts","sourceRoot":"","sources":["../../src/docs/SnackbarDocs.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"SnackbarDocs.d.ts","sourceRoot":"","sources":["../../src/docs/SnackbarDocs.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAgiB1B,QAAA,MAAM,YAAY,EAAE,KAAK,CAAC,EAWzB,CAAC;AAEF,eAAe,YAAY,CAAC"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import React from "react";
|
|
3
|
-
import { Card, Button, SnackbarProvider, SnackbarContainer, useSnackbar } from "../index";
|
|
3
|
+
import { Card, Button, SnackbarProvider, SnackbarContainer, useSnackbar, } from "../index";
|
|
4
4
|
// Componente wrapper para usar el hook dentro del provider
|
|
5
5
|
const SnackbarExamples = () => {
|
|
6
6
|
const { showSnackbar } = useSnackbar();
|
|
@@ -42,8 +42,20 @@ const SnackbarExamples = () => {
|
|
|
42
42
|
}), children: "Validar formulario" })] }), _jsxs("div", { children: [_jsx("h4", { className: "text-md font-medium mb-2", style: { color: "var(--flysoft-text-primary)" }, children: "Informaci\u00F3n importante" }), _jsx(Button, { variant: "primary", icon: "fa-info-circle", onClick: () => showSnackbar("Tu sesión expirará en 5 minutos. Guarda tu trabajo.", "warning", {
|
|
43
43
|
icon: "fa-clock",
|
|
44
44
|
duration: 8000,
|
|
45
|
-
}), children: "Mostrar advertencia" })] })] })] }), _jsxs("section", { children: [_jsx("h3", { className: "text-lg font-semibold mb-4", style: { color: "var(--flysoft-text-primary)" }, children: "Posiciones del contenedor" }), _jsxs("p", { className: "mb-4 text-sm", style: { color: "var(--flysoft-text-secondary)" }, children: ["El ", _jsx("code", { children: "SnackbarContainer" }), " puede posicionarse en diferentes lugares de la pantalla. En esta documentaci\u00F3n est\u00E1 configurado en", " ", _jsx("code", { children: "top-right" }), ". Las opciones disponibles son:"] }), _jsxs("ul", { className: "list-disc list-inside space-y-1 text-sm mb-4", style: { color: "var(--flysoft-text-secondary)" }, children: [_jsxs("li", { children: [_jsx("code", { children: "top-right" }), " - Esquina superior derecha (por defecto)"] }), _jsxs("li", { children: [_jsx("code", { children: "top-left" }), " - Esquina superior izquierda"] }), _jsxs("li", { children: [_jsx("code", { children: "bottom-right" }), " - Esquina inferior derecha"] }), _jsxs("li", { children: [_jsx("code", { children: "bottom-left" }), " - Esquina inferior izquierda"] }), _jsxs("li", { children: [_jsx("code", { children: "top-center" }), " - Centro superior"] }), _jsxs("li", { children: [_jsx("code", { children: "bottom-center" }), " - Centro inferior"] })] }), _jsx("div", { className: "bg-gray-100 dark:bg-gray-800 p-4 rounded-md", children: _jsx("code", { className: "text-sm", children: `<SnackbarContainer position="top-right" />` }) })] }), _jsxs("section", { children: [_jsx("h3", { className: "text-lg font-semibold mb-4", style: { color: "var(--flysoft-text-primary)" }, children: "Caracter\u00EDsticas" }), _jsxs("ul", { className: "list-disc list-inside space-y-2 text-sm", style: { color: "var(--flysoft-text-secondary)" }, children: [_jsxs("li", { children: [_jsx("strong", { children: "Ancho fijo:" }), " 18rem (288px)"] }), _jsxs("li", { children: [_jsx("strong", { children: "Barra de progreso:" }), " Muestra el tiempo restante en el borde inferior con el color de la variante"] }), _jsxs("li", { children: [_jsx("strong", { children: "Auto-cierre:" }), " Se cierra autom\u00E1ticamente despu\u00E9s de la duraci\u00F3n especificada (default: 3 segundos)"] }), _jsxs("li", { children: [_jsx("strong", { children: "Pausa al hover:" }), " La barra de progreso se pausa cuando pasas el mouse sobre el snackbar"] }), _jsxs("li", { children: [_jsx("strong", { children: "Cierre manual:" }), " Bot\u00F3n X en la esquina superior derecha"] }), _jsxs("li", { children: [_jsx("strong", { children: "\u00CDconos:" }), " Soporte para \u00EDconos FontAwesome 5 con \u00EDconos por defecto seg\u00FAn la variante"] }), _jsxs("li", { children: [_jsx("strong", { children: "Mensajes largos:" }), " El texto se ajusta autom\u00E1ticamente en m\u00FAltiples l\u00EDneas"] }), _jsxs("li", { children: [_jsx("strong", { children: "M\u00FAltiples snackbars:" }), " Soporte para mostrar varios snackbars apilados verticalmente"] }), _jsxs("li", { children: [_jsx("strong", { children: "Posiciones:" }), " Configurable en el SnackbarContainer (top-right, top-left, bottom-right, bottom-left, top-center, bottom-center)"] })] })] })] }));
|
|
45
|
+
}), children: "Mostrar advertencia" })] })] })] }), _jsxs("section", { children: [_jsx("h3", { className: "text-lg font-semibold mb-4", style: { color: "var(--flysoft-text-primary)" }, children: "Posiciones del contenedor" }), _jsxs("p", { className: "mb-4 text-sm", style: { color: "var(--flysoft-text-secondary)" }, children: ["El ", _jsx("code", { children: "SnackbarContainer" }), " puede posicionarse en diferentes lugares de la pantalla. En esta documentaci\u00F3n est\u00E1 configurado en", " ", _jsx("code", { children: "top-right" }), ". Las opciones disponibles son:"] }), _jsxs("ul", { className: "list-disc list-inside space-y-1 text-sm mb-4", style: { color: "var(--flysoft-text-secondary)" }, children: [_jsxs("li", { children: [_jsx("code", { children: "top-right" }), " - Esquina superior derecha (por defecto)"] }), _jsxs("li", { children: [_jsx("code", { children: "top-left" }), " - Esquina superior izquierda"] }), _jsxs("li", { children: [_jsx("code", { children: "bottom-right" }), " - Esquina inferior derecha"] }), _jsxs("li", { children: [_jsx("code", { children: "bottom-left" }), " - Esquina inferior izquierda"] }), _jsxs("li", { children: [_jsx("code", { children: "top-center" }), " - Centro superior"] }), _jsxs("li", { children: [_jsx("code", { children: "bottom-center" }), " - Centro inferior"] })] }), _jsx("div", { className: "bg-gray-100 dark:bg-gray-800 p-4 rounded-md", children: _jsx("code", { className: "text-sm", children: `<SnackbarContainer position="top-right" />` }) })] }), _jsxs("section", { children: [_jsx("h3", { className: "text-lg font-semibold mb-4", style: { color: "var(--flysoft-text-primary)" }, children: "Caracter\u00EDsticas" }), _jsxs("ul", { className: "list-disc list-inside space-y-2 text-sm", style: { color: "var(--flysoft-text-secondary)" }, children: [_jsxs("li", { children: [_jsx("strong", { children: "Ancho fijo:" }), " 18rem (288px)"] }), _jsxs("li", { children: [_jsx("strong", { children: "Barra de progreso:" }), " Muestra el tiempo restante en el borde inferior con el color de la variante"] }), _jsxs("li", { children: [_jsx("strong", { children: "Auto-cierre:" }), " Se cierra autom\u00E1ticamente despu\u00E9s de la duraci\u00F3n especificada (default: 3 segundos)"] }), _jsxs("li", { children: [_jsx("strong", { children: "Pausa al hover:" }), " La barra de progreso se pausa cuando pasas el mouse sobre el snackbar"] }), _jsxs("li", { children: [_jsx("strong", { children: "Cierre manual:" }), " Bot\u00F3n X en la esquina superior derecha"] }), _jsxs("li", { children: [_jsx("strong", { children: "\u00CDconos:" }), " Soporte para \u00EDconos FontAwesome 5 con \u00EDconos por defecto seg\u00FAn la variante"] }), _jsxs("li", { children: [_jsx("strong", { children: "Mensajes largos:" }), " El texto se ajusta autom\u00E1ticamente en m\u00FAltiples l\u00EDneas"] }), _jsxs("li", { children: [_jsx("strong", { children: "M\u00FAltiples snackbars:" }), " Soporte para mostrar varios snackbars apilados verticalmente"] }), _jsxs("li", { children: [_jsx("strong", { children: "Posiciones:" }), " Configurable en el SnackbarContainer (top-right, top-left, bottom-right, bottom-left, top-center, bottom-center)"] })] })] }), _jsxs("section", { children: [_jsx("h3", { className: "text-lg font-semibold mb-4", style: { color: "var(--flysoft-text-primary)" }, children: "Mejor Pr\u00E1ctica: Rendimiento" }), _jsxs("p", { className: "mb-4 text-sm", style: { color: "var(--flysoft-text-secondary)" }, children: ["Para un rendimiento \u00F3ptimo, utiliza el hook", " ", _jsx("code", { children: "useSnackbarActions" }), ". Este hook solo proporciona las funciones para disparar notificaciones, evitando que tu componente se re-renderice innecesariamente cuando la lista de snackbars cambie o se actualice su progreso."] }), _jsx("div", { className: "max-w-md mx-auto", children: _jsxs(Card, { className: "p-4 border-dashed", children: [_jsx("h4", { className: "font-medium mb-2 text-green-600", children: "Componente Optimizado" }), _jsxs("p", { className: "text-xs mb-3 text-gray-500", children: ["Este componente utiliza ", _jsx("code", { children: "useSnackbarActions" }), ". Observa c\u00F3mo el contador no aumenta mientras el snackbar est\u00E1 en pantalla."] }), _jsx(OptimizedComponent, {})] }) })] })] }));
|
|
46
46
|
};
|
|
47
|
+
// --- Componentes de Prueba de Rendimiento ---
|
|
48
|
+
const OptimizedComponent = React.memo(() => {
|
|
49
|
+
const { showSnackbar } = useSnackbar();
|
|
50
|
+
// Para detectar renders
|
|
51
|
+
const renderRef = React.useRef(0);
|
|
52
|
+
renderRef.current++;
|
|
53
|
+
// Log para consola
|
|
54
|
+
React.useEffect(() => {
|
|
55
|
+
console.log("%c[Optimized] Renderizado #" + renderRef.current, "color: green");
|
|
56
|
+
});
|
|
57
|
+
return (_jsxs("div", { className: "space-y-3", children: [_jsxs("div", { className: "flex justify-between items-center bg-gray-50 p-2 rounded", children: [_jsx("span", { className: "text-sm", children: "Contador de Renders:" }), _jsx("span", { className: "font-bold text-green-600 px-2 py-0.5 bg-green-50 rounded", children: renderRef.current })] }), _jsx(Button, { variant: "primary", className: "w-full", onClick: () => showSnackbar("Este componente es eficiente", "success"), children: "Disparar Snackbar" }), _jsx("p", { className: "text-[10px] text-gray-400 italic text-center", children: "El contador NO aumenta con los cambios de estado de otros snackbars." })] }));
|
|
58
|
+
});
|
|
47
59
|
const SnackbarDocs = () => {
|
|
48
60
|
return (_jsxs(SnackbarProvider, { children: [_jsx("div", { className: "max-w-5xl mx-auto space-y-8", children: _jsx(Card, { title: "Snackbar - Notificaciones y Mensajes", children: _jsx(SnackbarExamples, {}) }) }), _jsx(SnackbarContainer, { position: "top-right" })] }));
|
|
49
61
|
};
|