flysoft-react-ui 0.3.3 → 0.5.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.
Files changed (66) hide show
  1. package/dist/App.d.ts.map +1 -1
  2. package/dist/App.js +5 -2
  3. package/dist/components/form-controls/Pagination.d.ts +16 -0
  4. package/dist/components/form-controls/Pagination.d.ts.map +1 -0
  5. package/dist/components/form-controls/Pagination.js +60 -0
  6. package/dist/components/form-controls/index.d.ts +2 -0
  7. package/dist/components/form-controls/index.d.ts.map +1 -1
  8. package/dist/components/form-controls/index.js +1 -0
  9. package/dist/components/layout/Card.d.ts +4 -1
  10. package/dist/components/layout/Card.d.ts.map +1 -1
  11. package/dist/components/layout/Card.js +30 -1
  12. package/dist/components/layout/DataTable.d.ts +27 -0
  13. package/dist/components/layout/DataTable.d.ts.map +1 -0
  14. package/dist/components/layout/DataTable.js +160 -0
  15. package/dist/components/layout/TabPanel.d.ts +7 -0
  16. package/dist/components/layout/TabPanel.d.ts.map +1 -0
  17. package/dist/components/layout/TabPanel.js +11 -0
  18. package/dist/components/layout/TabsGroup.d.ts +20 -0
  19. package/dist/components/layout/TabsGroup.d.ts.map +1 -0
  20. package/dist/components/layout/TabsGroup.js +52 -0
  21. package/dist/components/layout/index.d.ts +6 -0
  22. package/dist/components/layout/index.d.ts.map +1 -1
  23. package/dist/components/layout/index.js +3 -0
  24. package/dist/components/utils/Dialog.d.ts +11 -0
  25. package/dist/components/utils/Dialog.d.ts.map +1 -0
  26. package/dist/components/utils/Dialog.js +39 -0
  27. package/dist/components/utils/DropdownMenu.d.ts +25 -0
  28. package/dist/components/utils/DropdownMenu.d.ts.map +1 -0
  29. package/dist/components/utils/DropdownMenu.js +145 -0
  30. package/dist/components/utils/Loader.d.ts +11 -0
  31. package/dist/components/utils/Loader.d.ts.map +1 -0
  32. package/dist/components/utils/Loader.js +44 -0
  33. package/dist/components/utils/index.d.ts +4 -0
  34. package/dist/components/utils/index.d.ts.map +1 -1
  35. package/dist/components/utils/index.js +2 -0
  36. package/dist/docs/AuthDocs.tsx/AuthDocsContent.js +3 -1
  37. package/dist/docs/CardDocs.d.ts.map +1 -1
  38. package/dist/docs/CardDocs.js +7 -1
  39. package/dist/docs/DataTableDocs.d.ts +4 -0
  40. package/dist/docs/DataTableDocs.d.ts.map +1 -0
  41. package/dist/docs/DataTableDocs.js +240 -0
  42. package/dist/docs/DialogDocs.d.ts +4 -0
  43. package/dist/docs/DialogDocs.d.ts.map +1 -0
  44. package/dist/docs/DialogDocs.js +12 -0
  45. package/dist/docs/DocsMenu.d.ts.map +1 -1
  46. package/dist/docs/DocsMenu.js +1 -1
  47. package/dist/docs/DocsRouter.d.ts.map +1 -1
  48. package/dist/docs/DocsRouter.js +7 -1
  49. package/dist/docs/DropdownMenuDocs.d.ts +4 -0
  50. package/dist/docs/DropdownMenuDocs.d.ts.map +1 -0
  51. package/dist/docs/DropdownMenuDocs.js +66 -0
  52. package/dist/docs/LoaderDocs.d.ts +4 -0
  53. package/dist/docs/LoaderDocs.d.ts.map +1 -0
  54. package/dist/docs/LoaderDocs.js +33 -0
  55. package/dist/docs/PaginationDocs.d.ts +4 -0
  56. package/dist/docs/PaginationDocs.d.ts.map +1 -0
  57. package/dist/docs/PaginationDocs.js +38 -0
  58. package/dist/docs/TabsGroupDocs.d.ts +4 -0
  59. package/dist/docs/TabsGroupDocs.d.ts.map +1 -0
  60. package/dist/docs/TabsGroupDocs.js +27 -0
  61. package/dist/index.css +1 -1
  62. package/dist/index.d.ts +14 -0
  63. package/dist/index.d.ts.map +1 -1
  64. package/dist/index.js +7 -0
  65. package/dist/index.js.map +1 -1
  66. package/package.json +1 -1
@@ -0,0 +1,145 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import React, { useState, useRef, useEffect, useCallback, useMemo, } from "react";
3
+ import { Button } from "../form-controls/Button";
4
+ export const DropdownMenu = ({ options, onOptionSelected, renderNode, getOptionLabel, renderOption, replaceOnSingleOption = false, }) => {
5
+ const [isOpen, setIsOpen] = useState(false);
6
+ const [menuPosition, setMenuPosition] = useState("bottom");
7
+ const [scrollUpdate, setScrollUpdate] = useState(0);
8
+ const triggerRef = useRef(null);
9
+ const menuRef = useRef(null);
10
+ // Calcular posición del menú
11
+ const calculatePosition = useCallback(() => {
12
+ if (isOpen && triggerRef.current) {
13
+ const triggerRect = triggerRef.current.getBoundingClientRect();
14
+ const viewportHeight = window.innerHeight;
15
+ // Estimar altura del menú (aproximadamente 40px por opción + padding)
16
+ const estimatedMenuHeight = options.length * 40 + 16;
17
+ const menuMargin = 4;
18
+ // Calcular espacio disponible arriba y abajo
19
+ const spaceBelow = viewportHeight - triggerRect.bottom - menuMargin;
20
+ const spaceAbove = triggerRect.top - menuMargin;
21
+ // Si no hay suficiente espacio abajo pero sí arriba, mostrar arriba
22
+ // Usamos un margen de seguridad para asegurar que el menú quepa
23
+ if (spaceBelow < estimatedMenuHeight && spaceAbove > spaceBelow) {
24
+ setMenuPosition("top");
25
+ }
26
+ else {
27
+ setMenuPosition("bottom");
28
+ }
29
+ }
30
+ }, [isOpen, options.length]);
31
+ useEffect(() => {
32
+ calculatePosition();
33
+ }, [calculatePosition]);
34
+ // Recalcular posición al hacer scroll o redimensionar
35
+ useEffect(() => {
36
+ if (isOpen) {
37
+ const handleScroll = () => {
38
+ calculatePosition();
39
+ // Forzar actualización del estilo del menú
40
+ setScrollUpdate((prev) => prev + 1);
41
+ };
42
+ window.addEventListener("scroll", handleScroll, true);
43
+ window.addEventListener("resize", handleScroll);
44
+ return () => {
45
+ window.removeEventListener("scroll", handleScroll, true);
46
+ window.removeEventListener("resize", handleScroll);
47
+ };
48
+ }
49
+ }, [isOpen, calculatePosition]);
50
+ // Cerrar menú al hacer click fuera
51
+ useEffect(() => {
52
+ const handleClickOutside = (event) => {
53
+ if (isOpen &&
54
+ triggerRef.current &&
55
+ menuRef.current &&
56
+ !triggerRef.current.contains(event.target) &&
57
+ !menuRef.current.contains(event.target)) {
58
+ setIsOpen(false);
59
+ }
60
+ };
61
+ if (isOpen) {
62
+ document.addEventListener("mousedown", handleClickOutside);
63
+ }
64
+ return () => {
65
+ document.removeEventListener("mousedown", handleClickOutside);
66
+ };
67
+ }, [isOpen]);
68
+ // Cerrar menú al presionar Escape
69
+ useEffect(() => {
70
+ const handleEscape = (event) => {
71
+ if (event.key === "Escape" && isOpen) {
72
+ setIsOpen(false);
73
+ }
74
+ };
75
+ if (isOpen) {
76
+ document.addEventListener("keydown", handleEscape);
77
+ }
78
+ return () => {
79
+ document.removeEventListener("keydown", handleEscape);
80
+ };
81
+ }, [isOpen]);
82
+ const labelGetter = useCallback((item) => {
83
+ if (getOptionLabel)
84
+ return getOptionLabel(item);
85
+ const anyItem = item;
86
+ return (anyItem.label ?? "").toString();
87
+ }, [getOptionLabel]);
88
+ const handleToggle = () => {
89
+ setIsOpen(!isOpen);
90
+ };
91
+ const handleOptionClick = (item) => {
92
+ onOptionSelected(item);
93
+ setIsOpen(false);
94
+ };
95
+ // Si replaceOnSingleOption es true y hay una sola opción, mostrar directamente la opción
96
+ const shouldReplace = replaceOnSingleOption && options.length === 1;
97
+ const singleOption = shouldReplace ? options[0] : null;
98
+ const menuStyles = useMemo(() => {
99
+ if (!isOpen || !triggerRef.current) {
100
+ return {};
101
+ }
102
+ const triggerRect = triggerRef.current.getBoundingClientRect();
103
+ const menuMargin = 4;
104
+ // Asegurar que el menú no se salga de la pantalla horizontalmente
105
+ let leftPosition = triggerRect.left;
106
+ const menuMinWidth = 160;
107
+ const viewportWidth = window.innerWidth;
108
+ // Si el menú se sale por la derecha, ajustar la posición
109
+ if (leftPosition + menuMinWidth > viewportWidth) {
110
+ leftPosition = viewportWidth - menuMinWidth - 8; // 8px de margen
111
+ }
112
+ // Asegurar que no se salga por la izquierda
113
+ if (leftPosition < 8) {
114
+ leftPosition = 8;
115
+ }
116
+ if (menuPosition === "top") {
117
+ return {
118
+ position: "fixed",
119
+ bottom: window.innerHeight - triggerRect.top + menuMargin,
120
+ left: leftPosition,
121
+ minWidth: Math.max(triggerRect.width, menuMinWidth),
122
+ };
123
+ }
124
+ else {
125
+ return {
126
+ position: "fixed",
127
+ top: triggerRect.bottom + menuMargin,
128
+ left: leftPosition,
129
+ minWidth: Math.max(triggerRect.width, menuMinWidth),
130
+ };
131
+ }
132
+ // scrollUpdate se usa intencionalmente para forzar el recálculo en scroll
133
+ // eslint-disable-next-line react-hooks/exhaustive-deps
134
+ }, [isOpen, menuPosition, scrollUpdate]);
135
+ // Si debe reemplazar con la opción única, mostrar directamente la opción
136
+ if (shouldReplace && singleOption) {
137
+ return (_jsx("div", { onClick: () => handleOptionClick(singleOption), className: "cursor-pointer", children: renderOption ? renderOption(singleOption) : labelGetter(singleOption) }));
138
+ }
139
+ return (_jsxs("div", { className: "relative inline-block", ref: triggerRef, children: [_jsx("div", { onClick: handleToggle, className: "cursor-pointer", children: renderNode ? (renderNode) : (_jsx(Button, { variant: "ghost", icon: "fa-ellipsis-h" })) }), isOpen && (_jsx("div", { ref: menuRef, className: "absolute z-[1000] bg-[var(--color-bg-default)] border border-[var(--color-border-default)] rounded-md shadow-[var(--shadow-lg)] py-1 min-w-[160px] font-[var(--font-default)]", style: menuStyles, children: options.map((option, index) => {
140
+ const key = String(option?.id ??
141
+ labelGetter(option) ??
142
+ index);
143
+ return (_jsx("div", { onClick: () => handleOptionClick(option), className: "px-4 py-2 text-sm text-[var(--color-text-primary)] hover:bg-[var(--color-bg-secondary)] cursor-pointer transition-colors flex items-center", children: renderOption ? renderOption(option) : labelGetter(option) }, key));
144
+ }) }))] }));
145
+ };
@@ -0,0 +1,11 @@
1
+ import React from "react";
2
+ export interface LoaderProps {
3
+ isLoading?: boolean;
4
+ text?: string;
5
+ children?: React.ReactNode;
6
+ keepContentWhileLoading?: boolean;
7
+ contentLoadingNode?: React.ReactNode;
8
+ overlayClassName?: string;
9
+ }
10
+ export declare const Loader: React.FC<LoaderProps>;
11
+ //# sourceMappingURL=Loader.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Loader.d.ts","sourceRoot":"","sources":["../../../src/components/utils/Loader.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAG1B,MAAM,WAAW,WAAW;IAC1B,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC3B,uBAAuB,CAAC,EAAE,OAAO,CAAC;IAClC,kBAAkB,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACrC,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED,eAAO,MAAM,MAAM,EAAE,KAAK,CAAC,EAAE,CAAC,WAAW,CAuHxC,CAAC"}
@@ -0,0 +1,44 @@
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
+ import React from "react";
3
+ import { useTheme } from "../../contexts/ThemeContext";
4
+ export const Loader = ({ isLoading = false, text, children, keepContentWhileLoading, contentLoadingNode, overlayClassName, }) => {
5
+ const { theme } = useTheme();
6
+ const displayText = text || "Cargando...";
7
+ // Clases por defecto del overlay (negro semitransparente con blur)
8
+ const defaultOverlayClasses = "bg-black/50 backdrop-blur-sm";
9
+ // Combinar clases por defecto con las personalizadas
10
+ const overlayClasses = overlayClassName
11
+ ? overlayClassName
12
+ : defaultOverlayClasses;
13
+ // Barra de progreso infinita
14
+ const ProgressBar = () => {
15
+ // Variable CSS para el gradiente del color primario
16
+ const gradientColor = `no-repeat linear-gradient(${theme.colors.primary} 0 0)`;
17
+ const bgSecondary = theme.colors.bgSecondary || theme.colors.gray100;
18
+ return (_jsxs("div", { className: "flex flex-col items-center gap-0.5 w-full", role: "status", "aria-live": "polite", children: [_jsx("div", { className: "h-1 w-full rounded", style: {
19
+ "--c": gradientColor,
20
+ background: `var(--c), var(--c), ${bgSecondary}`,
21
+ backgroundSize: "60% 100%",
22
+ animation: "l16 3s infinite",
23
+ } }), displayText && (_jsx("span", { className: "text-xs text-[var(--color-text-secondary)] font-[var(--font-default)]", children: displayText }))] }));
24
+ };
25
+ // Si no está cargando, mostrar solo children (si existen)
26
+ if (!isLoading) {
27
+ return _jsx(_Fragment, { children: children });
28
+ }
29
+ // Variante 1: Con contentLoadingNode
30
+ if (contentLoadingNode) {
31
+ return (_jsxs("div", { className: "relative", children: [_jsx("div", { className: keepContentWhileLoading ? "opacity-50 pointer-events-none" : "", children: contentLoadingNode }), _jsx("div", { className: "absolute inset-0 flex items-center justify-center z-10 pointer-events-none px-4", children: _jsx("div", { className: "bg-[var(--color-bg-default)] rounded-lg p-6 shadow-lg border border-[var(--color-border-default)] pointer-events-auto w-full", children: _jsx(ProgressBar, {}) }) })] }));
32
+ }
33
+ // Variante 2: Con children pero sin contentLoadingNode
34
+ if (children) {
35
+ // Si keepContentWhileLoading es true, mostrar children con overlay
36
+ if (keepContentWhileLoading) {
37
+ return (_jsxs("div", { className: "relative", children: [_jsx("div", { className: "pointer-events-none select-none", children: children }), _jsx("div", { className: `absolute inset-0 flex items-center justify-center z-10 pointer-events-auto px-4 ${overlayClasses}`, children: _jsx("div", { className: "bg-[var(--color-bg-default)] rounded-lg p-6 shadow-lg border border-[var(--color-border-default)] w-full", children: _jsx(ProgressBar, {}) }) })] }));
38
+ }
39
+ // Si no tiene keepContentWhileLoading, ocultar children y mostrar solo loader básico
40
+ return (_jsx("div", { className: "flex items-center justify-center p-6 w-full", children: _jsx("div", { className: "w-full max-w-2xl", children: _jsx(ProgressBar, {}) }) }));
41
+ }
42
+ // Variante 3: Sin contentLoadingNode ni children - solo loader
43
+ return (_jsx("div", { className: "flex items-center justify-center p-6 w-full", children: _jsx("div", { className: "w-full max-w-2xl", children: _jsx(ProgressBar, {}) }) }));
44
+ };
@@ -1,3 +1,7 @@
1
1
  export { Badge } from "./Badge";
2
2
  export type { BadgeProps } from "./Badge";
3
+ export { Dialog } from "./Dialog";
4
+ export type { DialogProps } from "./Dialog";
5
+ export { Loader } from "./Loader";
6
+ export type { LoaderProps } from "./Loader";
3
7
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/utils/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAChC,YAAY,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/utils/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAChC,YAAY,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAC1C,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAClC,YAAY,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAC5C,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAClC,YAAY,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC"}
@@ -1 +1,3 @@
1
1
  export { Badge } from "./Badge";
2
+ export { Dialog } from "./Dialog";
3
+ export { Loader } from "./Loader";
@@ -16,7 +16,9 @@ export const AuthDocsContent = () => {
16
16
  return (_jsxs("div", { className: "space-y-4", children: [_jsx(InterfacesDocumentation, {}), _jsx(Card, { children: _jsx("div", { className: "flex items-center justify-center py-8", children: _jsxs("div", { className: "flex items-center gap-3", children: [_jsx("i", { className: "fa fa-spinner fa-spin text-[var(--color-primary)] text-xl" }), _jsx("span", { className: "text-[var(--color-text-secondary)]", children: "Iniciando sesi\u00F3n..." })] }) }) })] }));
17
17
  }
18
18
  if (isAuthenticated && user) {
19
- return (_jsxs("div", { className: "space-y-4", children: [_jsx(InterfacesDocumentation, {}), _jsx(Card, { title: "Sesi\u00F3n Activa", subtitle: "Informaci\u00F3n del usuario autenticado", headerActions: _jsx(Badge, { variant: "success", icon: "fa-check-circle", iconPosition: "left", children: "Autenticado" }), children: _jsxs("div", { className: "space-y-4", children: [_jsxs("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4", children: [_jsx(DataField, { label: "ID de Usuario", value: user.id }), _jsx(DataField, { label: "Nombre", value: user.name || "No disponible" })] }), user.aditionalData && (_jsxs("div", { className: "mt-4 pt-4 border-t border-[var(--color-border-default)]", children: [_jsx("h4", { className: "text-sm font-semibold text-[var(--color-text-primary)] mb-3", children: "Datos Adicionales" }), _jsxs("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4", children: [user.aditionalData.role && (_jsx(DataField, { label: "Rol", value: _jsx(Badge, { variant: "primary", icon: "fa-user-shield", children: user.aditionalData.role }) })), user.aditionalData.email && (_jsx(DataField, { label: "Email", value: user.aditionalData.email })), user.aditionalData.createdAt && (_jsx(DataField, { label: "Fecha de Creaci\u00F3n", value: new Date(user.aditionalData.createdAt).toLocaleString() })), user.aditionalData.permissions && (_jsx(DataField, { label: "Permisos", value: _jsx("div", { className: "flex flex-wrap gap-2", children: user.aditionalData.permissions.map((permission, index) => (_jsx(Badge, { variant: "info", size: "sm", icon: "fa-key", children: permission }, index))) }) }))] })] })), user.token && (_jsxs("div", { className: "mt-4 pt-4 border-t border-[var(--color-border-default)]", children: [_jsx("h4", { className: "text-sm font-semibold text-[var(--color-text-primary)] mb-3", children: "Informaci\u00F3n del Token" }), _jsxs("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4", children: [_jsx(DataField, { label: "Tipo de Token", value: _jsx(Badge, { variant: "secondary", icon: "fa-tag", children: user.token.tokenType || "Bearer" }) }), user.token.expires && (_jsx(DataField, { label: "Expira", value: new Date(user.token.expires).toLocaleString() })), user.token.accessToken && (_jsx(DataField, { label: "Access Token", value: _jsxs("code", { className: "text-xs bg-[var(--color-bg-secondary)] px-2 py-1 rounded break-all", children: [user.token.accessToken.substring(0, 30), "..."] }) }))] })] })), _jsx("div", { className: "mt-6 pt-4 border-t border-[var(--color-border-default)]", children: _jsx(Button, { variant: "outline", icon: "fa-sign-out-alt", iconPosition: "left", onClick: handleLogout, className: "w-full md:w-auto", children: "Cerrar Sesi\u00F3n" }) })] }) })] }));
19
+ return (_jsxs("div", { className: "space-y-4", children: [_jsx(InterfacesDocumentation, {}), _jsx(Card, { title: "Sesi\u00F3n Activa", subtitle: "Informaci\u00F3n del usuario autenticado", headerActions: () => [
20
+ _jsx(Badge, { variant: "success", icon: "fa-check-circle", iconPosition: "left", children: "Autenticado" }),
21
+ ], children: _jsxs("div", { className: "space-y-4", children: [_jsxs("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4", children: [_jsx(DataField, { label: "ID de Usuario", value: user.id }), _jsx(DataField, { label: "Nombre", value: user.name || "No disponible" })] }), user.aditionalData && (_jsxs("div", { className: "mt-4 pt-4 border-t border-[var(--color-border-default)]", children: [_jsx("h4", { className: "text-sm font-semibold text-[var(--color-text-primary)] mb-3", children: "Datos Adicionales" }), _jsxs("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4", children: [user.aditionalData.role && (_jsx(DataField, { label: "Rol", value: _jsx(Badge, { variant: "primary", icon: "fa-user-shield", children: user.aditionalData.role }) })), user.aditionalData.email && (_jsx(DataField, { label: "Email", value: user.aditionalData.email })), user.aditionalData.createdAt && (_jsx(DataField, { label: "Fecha de Creaci\u00F3n", value: new Date(user.aditionalData.createdAt).toLocaleString() })), user.aditionalData.permissions && (_jsx(DataField, { label: "Permisos", value: _jsx("div", { className: "flex flex-wrap gap-2", children: user.aditionalData.permissions.map((permission, index) => (_jsx(Badge, { variant: "info", size: "sm", icon: "fa-key", children: permission }, index))) }) }))] })] })), user.token && (_jsxs("div", { className: "mt-4 pt-4 border-t border-[var(--color-border-default)]", children: [_jsx("h4", { className: "text-sm font-semibold text-[var(--color-text-primary)] mb-3", children: "Informaci\u00F3n del Token" }), _jsxs("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4", children: [_jsx(DataField, { label: "Tipo de Token", value: _jsx(Badge, { variant: "secondary", icon: "fa-tag", children: user.token.tokenType || "Bearer" }) }), user.token.expires && (_jsx(DataField, { label: "Expira", value: new Date(user.token.expires).toLocaleString() })), user.token.accessToken && (_jsx(DataField, { label: "Access Token", value: _jsxs("code", { className: "text-xs bg-[var(--color-bg-secondary)] px-2 py-1 rounded break-all", children: [user.token.accessToken.substring(0, 30), "..."] }) }))] })] })), _jsx("div", { className: "mt-6 pt-4 border-t border-[var(--color-border-default)]", children: _jsx(Button, { variant: "outline", icon: "fa-sign-out-alt", iconPosition: "left", onClick: handleLogout, className: "w-full md:w-auto", children: "Cerrar Sesi\u00F3n" }) })] }) })] }));
20
22
  }
21
23
  return (_jsxs("div", { className: "space-y-4", children: [_jsx(InterfacesDocumentation, {}), _jsx(Card, { title: "Autenticaci\u00F3n", subtitle: "Inicia sesi\u00F3n para ver el AuthContext en acci\u00F3n", children: _jsxs("div", { className: "space-y-4", children: [_jsx("div", { className: "bg-[var(--color-info-light)] border border-[var(--color-info)] rounded-lg p-4", children: _jsxs("div", { className: "flex items-start gap-3", children: [_jsx("i", { className: "fa fa-info-circle text-[var(--color-info)] mt-1" }), _jsx("div", { className: "flex-1", children: _jsxs("p", { className: "text-sm text-[var(--color-text-primary)]", children: ["Esta es una demostraci\u00F3n del", " ", _jsx("code", { className: "text-xs bg-white/50 px-1 rounded", children: "AuthContext" }), " ", "usando un servicio mock. Haz clic en el bot\u00F3n para simular un inicio de sesi\u00F3n."] }) })] }) }), _jsx("div", { className: "flex justify-center pt-4", children: _jsx(Button, { variant: "primary", size: "lg", icon: "fa-sign-in-alt", iconPosition: "left", onClick: handleLogin, children: "Iniciar Sesi\u00F3n" }) })] }) })] }));
22
24
  };
@@ -1 +1 @@
1
- {"version":3,"file":"CardDocs.d.ts","sourceRoot":"","sources":["../../src/docs/CardDocs.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAG1B,QAAA,MAAM,QAAQ,EAAE,KAAK,CAAC,EA+IrB,CAAC;AAEF,eAAe,QAAQ,CAAC"}
1
+ {"version":3,"file":"CardDocs.d.ts","sourceRoot":"","sources":["../../src/docs/CardDocs.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAG1B,QAAA,MAAM,QAAQ,EAAE,KAAK,CAAC,EA2drB,CAAC;AAEF,eAAe,QAAQ,CAAC"}
@@ -2,6 +2,12 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import React from "react";
3
3
  import { Card, Button } from "../index";
4
4
  const CardDocs = () => {
5
- return (_jsx("div", { className: "max-w-5xl mx-auto space-y-8", children: _jsx(Card, { title: "Card - 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: "Variantes" }), _jsxs("div", { className: "grid grid-cols-1 md:grid-cols-3 gap-6", children: [_jsx(Card, { variant: "default", title: "Default", children: _jsx("p", { style: { color: "var(--flysoft-text-secondary)" }, children: "card por defecto" }) }), _jsx(Card, { variant: "elevated", title: "Elevated", children: _jsx("p", { style: { color: "var(--flysoft-text-secondary)" }, children: "card con sombra elevada" }) }), _jsx(Card, { variant: "outlined", title: "Outlined", children: _jsx("p", { style: { color: "var(--flysoft-text-secondary)" }, children: "card con borde destacado" }) })] })] }), _jsxs("section", { children: [_jsx("h3", { className: "text-lg font-semibold mb-4", style: { color: "var(--flysoft-text-primary)" }, children: "Header y Footer" }), _jsx(Card, { title: "Card con Acciones", subtitle: "Ejemplo de header y footer", headerActions: _jsxs("div", { className: "flex gap-2", children: [_jsx(Button, { size: "sm", variant: "outline", icon: "fa-edit", children: "Editar" }), _jsx(Button, { size: "sm", variant: "primary", icon: "fa-save", children: "Guardar" })] }), footer: _jsxs("div", { className: "flex justify-end gap-2", children: [_jsx(Button, { size: "sm", variant: "outline", children: "Cancelar" }), _jsx(Button, { size: "sm", variant: "primary", icon: "fa-check", children: "Aceptar" })] }), children: _jsx("p", { style: { color: "var(--flysoft-text-secondary)" }, children: "card con acciones en header y contenido descriptivo" }) })] }), _jsxs("section", { children: [_jsx("h3", { className: "text-lg font-semibold mb-4", style: { color: "var(--flysoft-text-primary)" }, children: "Title y Subtitle como ReactNode" }), _jsx(Card, { title: _jsxs("div", { className: "flex items-center gap-2", children: [_jsx("i", { className: "fa fa-user-circle" }), _jsx("span", { children: "Usuario Personalizado" })] }), subtitle: _jsxs("div", { className: "flex items-center gap-2", children: [_jsx("i", { className: "fa fa-envelope" }), _jsx("span", { children: "usuario@ejemplo.com" })] }), children: _jsx("p", { style: { color: "var(--flysoft-text-secondary)" }, children: "El t\u00EDtulo y subt\u00EDtulo pueden ser ReactNode, permitiendo incluir iconos, badges, o cualquier componente personalizado." }) })] }), _jsxs("section", { children: [_jsx("h3", { className: "text-lg font-semibold mb-4", style: { color: "var(--flysoft-text-primary)" }, children: "Background Personalizado" }), _jsx("p", { className: "mb-4 text-sm", style: { color: "var(--flysoft-text-secondary)" }, children: "El componente detecta autom\u00E1ticamente las clases de background (bg-*) desde la prop className y las aplica al background de la card. Las dem\u00E1s clases se aplican normalmente al contenedor." }), _jsxs("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-6", children: [_jsx(Card, { title: "Card con bg-blue-50", className: "bg-blue-50", children: _jsx("p", { style: { color: "var(--flysoft-text-secondary)" }, children: "Card con background personalizado usando clases de Tailwind" }) }), _jsx(Card, { title: "Card con bg-gradient", className: "bg-gradient-to-br from-purple-100 to-pink-100", children: _jsx("p", { style: { color: "var(--flysoft-text-secondary)" }, children: "Card con gradiente personalizado" }) }), _jsx(Card, { title: "Card con bg y otras clases", className: "bg-green-50 p-8", children: _jsx("p", { style: { color: "var(--flysoft-text-secondary)" }, children: "Puedes combinar clases de background con otras clases de Tailwind" }) })] })] })] }) }) }));
5
+ return (_jsx("div", { className: "max-w-5xl mx-auto space-y-8", children: _jsx(Card, { title: "Card - 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: "Variantes" }), _jsxs("div", { className: "grid grid-cols-1 md:grid-cols-3 gap-6", children: [_jsx(Card, { variant: "default", title: "Default", children: _jsx("p", { style: { color: "var(--flysoft-text-secondary)" }, children: "card por defecto" }) }), _jsx(Card, { variant: "elevated", title: "Elevated", children: _jsx("p", { style: { color: "var(--flysoft-text-secondary)" }, children: "card con sombra elevada" }) }), _jsx(Card, { variant: "outlined", title: "Outlined", children: _jsx("p", { style: { color: "var(--flysoft-text-secondary)" }, children: "card con borde destacado" }) })] })] }), _jsxs("section", { children: [_jsx("h3", { className: "text-lg font-semibold mb-4", style: { color: "var(--flysoft-text-primary)" }, children: "Header y Footer" }), _jsxs("p", { className: "mb-4 text-sm", style: { color: "var(--flysoft-text-secondary)" }, children: ["El componente Card soporta acciones en el header usando la propiedad ", _jsx("code", { children: "headerActions" }), ". Las acciones se muestran en un DropdownMenu. En pantallas grandes (lg+), las acciones solo se muestran al hacer hover sobre el Card. En pantallas peque\u00F1as, siempre son visibles."] }), _jsxs("div", { className: "space-y-4", children: [_jsx(Card, { title: "Card con m\u00FAltiples acciones", subtitle: "Ejemplo con DropdownMenu", headerActions: () => [
6
+ _jsx(Button, { size: "sm", variant: "ghost", icon: "fa-edit", onClick: () => console.log("Editar"), children: "Editar" }, "edit"),
7
+ _jsx(Button, { size: "sm", variant: "ghost", icon: "fa-trash", onClick: () => console.log("Eliminar"), children: "Eliminar" }, "delete"),
8
+ _jsx(Button, { size: "sm", variant: "ghost", icon: "fa-share", onClick: () => console.log("Compartir"), children: "Compartir" }, "share"),
9
+ ], footer: _jsxs("div", { className: "flex justify-end gap-2", children: [_jsx(Button, { size: "sm", variant: "outline", children: "Cancelar" }), _jsx(Button, { size: "sm", variant: "primary", icon: "fa-check", children: "Aceptar" })] }), children: _jsx("p", { style: { color: "var(--flysoft-text-secondary)" }, children: "Card con m\u00FAltiples acciones en el header. En pantallas grandes, pasa el mouse sobre el Card para ver las acciones." }) }), _jsx(Card, { title: "Card con una sola acci\u00F3n", subtitle: "Se muestra directamente sin men\u00FA", headerActions: () => [
10
+ _jsx(Button, { size: "sm", variant: "ghost", icon: "fa-search", onClick: () => console.log("Ver detalles") }, "view"),
11
+ ], children: _jsxs("p", { style: { color: "var(--flysoft-text-secondary)" }, children: ["Cuando hay una sola acci\u00F3n, se muestra directamente gracias a", " ", _jsx("code", { children: "replaceOnSingleOption" }), ", sin necesidad de abrir un men\u00FA."] }) })] })] }), _jsxs("section", { children: [_jsx("h3", { className: "text-lg font-semibold mb-4", style: { color: "var(--flysoft-text-primary)" }, children: "Title y Subtitle como ReactNode" }), _jsx(Card, { title: _jsxs("div", { className: "flex items-center gap-2", children: [_jsx("i", { className: "fa fa-user-circle" }), _jsx("span", { children: "Usuario Personalizado" })] }), subtitle: _jsxs("div", { className: "flex items-center gap-2", children: [_jsx("i", { className: "fa fa-envelope" }), _jsx("span", { children: "usuario@ejemplo.com" })] }), children: _jsx("p", { style: { color: "var(--flysoft-text-secondary)" }, children: "El t\u00EDtulo y subt\u00EDtulo pueden ser ReactNode, permitiendo incluir iconos, badges, o cualquier componente personalizado." }) })] }), _jsxs("section", { children: [_jsx("h3", { className: "text-lg font-semibold mb-4", style: { color: "var(--flysoft-text-primary)" }, children: "Background Personalizado" }), _jsx("p", { className: "mb-4 text-sm", style: { color: "var(--flysoft-text-secondary)" }, children: "El componente detecta autom\u00E1ticamente las clases de background (bg-*) desde la prop className y las aplica al background de la card. Las dem\u00E1s clases se aplican normalmente al contenedor." }), _jsxs("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-6", children: [_jsx(Card, { title: "Card con bg-blue-50", className: "bg-blue-50", children: _jsx("p", { style: { color: "var(--flysoft-text-secondary)" }, children: "Card con background personalizado usando clases de Tailwind" }) }), _jsx(Card, { title: "Card con bg-gradient", className: "bg-gradient-to-br from-purple-100 to-pink-100", children: _jsx("p", { style: { color: "var(--flysoft-text-secondary)" }, children: "Card con gradiente personalizado" }) }), _jsx(Card, { title: "Card con bg y otras clases", className: "bg-green-50 p-8", children: _jsx("p", { style: { color: "var(--flysoft-text-secondary)" }, children: "Puedes combinar clases de background con otras clases de Tailwind" }) })] })] }), _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: "Variantes:" }), " Soporta tres variantes: default, elevated (con sombra) y outlined (con borde destacado)"] }), _jsxs("li", { children: [_jsx("strong", { children: "HeaderActions:" }), " Usa la propiedad", " ", _jsx("code", { children: "headerActions" }), " para mostrar un DropdownMenu con acciones en el header. Las acciones se muestran en un men\u00FA desplegable."] }), _jsxs("li", { children: [_jsx("strong", { children: "Comportamiento responsive:" }), " En pantallas grandes (lg+), las acciones del header solo se muestran al hacer hover sobre el Card. En pantallas peque\u00F1as, siempre son visibles."] }), _jsxs("li", { children: [_jsx("strong", { children: "Opci\u00F3n \u00FAnica:" }), " Cuando hay una sola acci\u00F3n, se muestra directamente gracias a", " ", _jsx("code", { children: "replaceOnSingleOption" }), ", sin necesidad de abrir un men\u00FA."] }), _jsxs("li", { children: [_jsx("strong", { children: "Title y Subtitle flexibles:" }), " Pueden ser strings o ReactNode, permitiendo incluir iconos, badges u otros componentes."] }), _jsxs("li", { children: [_jsx("strong", { children: "Background personalizado:" }), " El componente detecta autom\u00E1ticamente las clases de background (bg-*) y las aplica correctamente."] }), _jsxs("li", { children: [_jsx("strong", { children: "Footer opcional:" }), " Puedes agregar contenido en el footer de la card."] })] }) }) })] }), _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: "px-4 py-2 text-left text-sm font-semibold", style: { color: "var(--flysoft-text-primary)" }, children: "Prop" }), _jsx("th", { className: "px-4 py-2 text-left text-sm font-semibold", style: { color: "var(--flysoft-text-primary)" }, children: "Tipo" }), _jsx("th", { className: "px-4 py-2 text-left text-sm font-semibold", style: { color: "var(--flysoft-text-primary)" }, children: "Requerido" }), _jsx("th", { className: "px-4 py-2 text-left text-sm 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: "px-4 py-2 text-sm font-mono", style: { color: "var(--flysoft-text-primary)" }, children: "children" }), _jsx("td", { className: "px-4 py-2 text-sm", style: { color: "var(--flysoft-text-secondary)" }, children: "ReactNode" }), _jsx("td", { className: "px-4 py-2 text-sm", style: { color: "var(--flysoft-text-secondary)" }, children: "S\u00ED" }), _jsx("td", { className: "px-4 py-2 text-sm", style: { color: "var(--flysoft-text-secondary)" }, children: "Contenido principal de la card." })] }), _jsxs("tr", { className: "border-b border-[var(--color-border-default)]", children: [_jsx("td", { className: "px-4 py-2 text-sm font-mono", style: { color: "var(--flysoft-text-primary)" }, children: "title" }), _jsx("td", { className: "px-4 py-2 text-sm", style: { color: "var(--flysoft-text-secondary)" }, children: "string | ReactNode" }), _jsx("td", { className: "px-4 py-2 text-sm", style: { color: "var(--flysoft-text-secondary)" }, children: "No" }), _jsx("td", { className: "px-4 py-2 text-sm", style: { color: "var(--flysoft-text-secondary)" }, children: "T\u00EDtulo de la card. Puede ser un string o un ReactNode." })] }), _jsxs("tr", { className: "border-b border-[var(--color-border-default)]", children: [_jsx("td", { className: "px-4 py-2 text-sm font-mono", style: { color: "var(--flysoft-text-primary)" }, children: "subtitle" }), _jsx("td", { className: "px-4 py-2 text-sm", style: { color: "var(--flysoft-text-secondary)" }, children: "string | ReactNode" }), _jsx("td", { className: "px-4 py-2 text-sm", style: { color: "var(--flysoft-text-secondary)" }, children: "No" }), _jsx("td", { className: "px-4 py-2 text-sm", style: { color: "var(--flysoft-text-secondary)" }, children: "Subt\u00EDtulo de la card. Se muestra debajo del t\u00EDtulo." })] }), _jsxs("tr", { className: "border-b border-[var(--color-border-default)]", children: [_jsx("td", { className: "px-4 py-2 text-sm font-mono", style: { color: "var(--flysoft-text-primary)" }, children: "headerActions" }), _jsx("td", { className: "px-4 py-2 text-sm", style: { color: "var(--flysoft-text-secondary)" }, children: "() => Array<ReactNode>" }), _jsx("td", { className: "px-4 py-2 text-sm", style: { color: "var(--flysoft-text-secondary)" }, children: "No" }), _jsx("td", { className: "px-4 py-2 text-sm", style: { color: "var(--flysoft-text-secondary)" }, children: "Funci\u00F3n que retorna un array de ReactNode que se mostrar\u00E1n en un DropdownMenu en el header. En pantallas grandes (lg+), solo se muestran al hacer hover. Las acciones deben manejar sus propios eventos onClick." })] }), _jsxs("tr", { className: "border-b border-[var(--color-border-default)]", children: [_jsx("td", { className: "px-4 py-2 text-sm font-mono", style: { color: "var(--flysoft-text-primary)" }, children: "footer" }), _jsx("td", { className: "px-4 py-2 text-sm", style: { color: "var(--flysoft-text-secondary)" }, children: "ReactNode" }), _jsx("td", { className: "px-4 py-2 text-sm", style: { color: "var(--flysoft-text-secondary)" }, children: "No" }), _jsx("td", { className: "px-4 py-2 text-sm", style: { color: "var(--flysoft-text-secondary)" }, children: "Contenido del footer de la card." })] }), _jsxs("tr", { className: "border-b border-[var(--color-border-default)]", children: [_jsx("td", { className: "px-4 py-2 text-sm font-mono", style: { color: "var(--flysoft-text-primary)" }, children: "variant" }), _jsx("td", { className: "px-4 py-2 text-sm", style: { color: "var(--flysoft-text-secondary)" }, children: "\"default\" | \"elevated\" | \"outlined\"" }), _jsx("td", { className: "px-4 py-2 text-sm", style: { color: "var(--flysoft-text-secondary)" }, children: "No" }), _jsx("td", { className: "px-4 py-2 text-sm", style: { color: "var(--flysoft-text-secondary)" }, children: "Variante visual de la card. Por defecto es \"default\"." })] }), _jsxs("tr", { className: "border-b border-[var(--color-border-default)]", children: [_jsx("td", { className: "px-4 py-2 text-sm font-mono", style: { color: "var(--flysoft-text-primary)" }, children: "className" }), _jsx("td", { className: "px-4 py-2 text-sm", style: { color: "var(--flysoft-text-secondary)" }, children: "string" }), _jsx("td", { className: "px-4 py-2 text-sm", style: { color: "var(--flysoft-text-secondary)" }, children: "No" }), _jsx("td", { className: "px-4 py-2 text-sm", style: { color: "var(--flysoft-text-secondary)" }, children: "Clases CSS adicionales. Las clases de background (bg-*) se aplican autom\u00E1ticamente al background de la card." })] })] })] }) })] })] }) }) }));
6
12
  };
7
13
  export default CardDocs;
@@ -0,0 +1,4 @@
1
+ import React from "react";
2
+ declare const DataTableDocs: React.FC;
3
+ export default DataTableDocs;
4
+ //# sourceMappingURL=DataTableDocs.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DataTableDocs.d.ts","sourceRoot":"","sources":["../../src/docs/DataTableDocs.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAa1B,QAAA,MAAM,aAAa,EAAE,KAAK,CAAC,EAguB1B,CAAC;AAEF,eAAe,aAAa,CAAC"}
@@ -0,0 +1,240 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import React from "react";
3
+ import { Card, DataTable, Button, Badge } from "../index";
4
+ const DataTableDocs = () => {
5
+ const allProducts = [
6
+ {
7
+ id: 1,
8
+ name: "Laptop Dell XPS 15",
9
+ price: 1299.1,
10
+ stock: 45,
11
+ category: "Electrónica",
12
+ createdAt: "2024-01-15",
13
+ },
14
+ {
15
+ id: 2,
16
+ name: "Mouse Logitech MX Master",
17
+ price: 89.99,
18
+ stock: 1200,
19
+ category: "Accesorios",
20
+ createdAt: "2024-02-20",
21
+ },
22
+ {
23
+ id: 3,
24
+ name: "Teclado Mecánico RGB",
25
+ price: 149,
26
+ stock: 0,
27
+ category: "Accesorios",
28
+ createdAt: "2024-03-10",
29
+ },
30
+ {
31
+ id: 4,
32
+ name: "Monitor 4K 27 pulgadas",
33
+ price: 599,
34
+ stock: 15,
35
+ category: "Electrónica",
36
+ createdAt: "2024-01-05",
37
+ },
38
+ {
39
+ id: 5,
40
+ name: "Auriculares Sony WH-1000XM5",
41
+ price: 399.1,
42
+ stock: 30,
43
+ category: "Audio",
44
+ createdAt: "2024-02-12",
45
+ },
46
+ {
47
+ id: 6,
48
+ name: "Webcam Logitech C920",
49
+ price: 79.99,
50
+ stock: 85,
51
+ category: "Accesorios",
52
+ createdAt: "2024-03-22",
53
+ },
54
+ {
55
+ id: 7,
56
+ name: "SSD Samsung 1TB",
57
+ price: 129.99,
58
+ stock: 200,
59
+ category: "Almacenamiento",
60
+ createdAt: "2024-01-28",
61
+ },
62
+ {
63
+ id: 8,
64
+ name: "Tablet iPad Pro 12.9",
65
+ price: 1099.99,
66
+ stock: 12,
67
+ category: "Electrónica",
68
+ createdAt: "2024-02-05",
69
+ },
70
+ {
71
+ id: 9,
72
+ name: "Cable USB-C Premium",
73
+ price: 24.99,
74
+ stock: 500,
75
+ category: "Accesorios",
76
+ createdAt: "2024-03-15",
77
+ },
78
+ {
79
+ id: 10,
80
+ name: "Router WiFi 6 ASUS",
81
+ price: 199.99,
82
+ stock: 25,
83
+ category: "Redes",
84
+ createdAt: "2024-01-20",
85
+ },
86
+ {
87
+ id: 11,
88
+ name: "Micrófono Blue Yeti",
89
+ price: 129.99,
90
+ stock: 40,
91
+ category: "Audio",
92
+ createdAt: "2024-02-18",
93
+ },
94
+ {
95
+ id: 12,
96
+ name: "Disco Duro Externo 2TB",
97
+ price: 89.99,
98
+ stock: 60,
99
+ category: "Almacenamiento",
100
+ createdAt: "2024-03-08",
101
+ },
102
+ ];
103
+ // Solo 4 productos para los ejemplos normales
104
+ const products = allProducts.slice(0, 4);
105
+ const basicColumns = [
106
+ {
107
+ header: "ID",
108
+ value: "id",
109
+ align: "center",
110
+ width: "80px",
111
+ type: "numeric",
112
+ },
113
+ {
114
+ header: "Nombre",
115
+ value: "name",
116
+ align: "left",
117
+ },
118
+ {
119
+ header: "Categoría",
120
+ value: "category",
121
+ align: "left",
122
+ },
123
+ ];
124
+ const fullColumns = [
125
+ {
126
+ header: "ID",
127
+ value: "id",
128
+ align: "center",
129
+ width: "80px",
130
+ type: "numeric",
131
+ footer: `Total`,
132
+ },
133
+ {
134
+ header: "Nombre del Producto",
135
+ value: "name",
136
+ align: "left",
137
+ },
138
+ {
139
+ header: "Precio",
140
+ value: "price",
141
+ align: "right",
142
+ type: "currency",
143
+ footer: `${allProducts
144
+ .reduce((sum, p) => sum + p.price, 0)
145
+ .toLocaleString("es-AR", {
146
+ minimumFractionDigits: 2,
147
+ maximumFractionDigits: 2,
148
+ })}`,
149
+ },
150
+ {
151
+ header: "Stock",
152
+ value: "stock",
153
+ align: "center",
154
+ type: "numeric",
155
+ footer: `${allProducts
156
+ .reduce((sum, p) => sum + p.stock, 0)
157
+ .toLocaleString("es-AR")}`,
158
+ },
159
+ {
160
+ header: "Categoría",
161
+ value: "category",
162
+ align: "left",
163
+ },
164
+ {
165
+ header: "Fecha de Creación",
166
+ value: "createdAt",
167
+ align: "center",
168
+ type: "date",
169
+ },
170
+ ];
171
+ const customColumns = [
172
+ {
173
+ header: "ID",
174
+ value: "id",
175
+ align: "center",
176
+ width: "80px",
177
+ type: "numeric",
178
+ },
179
+ {
180
+ header: "Nombre",
181
+ value: "name",
182
+ align: "left",
183
+ },
184
+ {
185
+ header: "Precio",
186
+ value: "price",
187
+ align: "right",
188
+ type: "currency",
189
+ tooltip: (row) => `Precio original: ${row.price}€`,
190
+ },
191
+ {
192
+ header: "Stock",
193
+ value: (row) => (_jsx(Badge, { variant: row.stock > 0 ? "success" : "danger", icon: row.stock > 0 ? "fa-check-circle" : "fa-times-circle", children: row.stock > 0 ? `${row.stock} unidades` : "Sin stock" })),
194
+ align: "center",
195
+ },
196
+ {
197
+ header: "Acciones",
198
+ value: "",
199
+ align: "center",
200
+ actions: (row) => [
201
+ _jsx(Button, { size: "sm", variant: "ghost", icon: "fa-edit", onClick: () => console.log("Editar", row), children: "Editar" }, "edit"),
202
+ _jsx(Button, { size: "sm", variant: "ghost", icon: "fa-trash", onClick: () => console.log("Eliminar", row), children: "Eliminar" }, "delete"),
203
+ ],
204
+ },
205
+ {
206
+ header: "Ver",
207
+ value: "",
208
+ align: "center",
209
+ actions: (row) => [
210
+ _jsx(Button, { size: "sm", variant: "ghost", icon: "fa-search", onClick: () => console.log("Ver detalles", row) }, "view"),
211
+ ],
212
+ },
213
+ ];
214
+ const headerCustomColumns = [
215
+ {
216
+ header: (_jsxs("div", { className: "flex items-center gap-2", children: [_jsx("i", { className: "fa fa-hashtag" }), _jsx("span", { children: "ID" })] })),
217
+ value: "id",
218
+ align: "center",
219
+ width: "80px",
220
+ type: "numeric",
221
+ },
222
+ {
223
+ header: (_jsxs("div", { className: "flex items-center gap-2", children: [_jsx("i", { className: "fa fa-box" }), _jsx("span", { children: "Producto" })] })),
224
+ value: "name",
225
+ align: "left",
226
+ },
227
+ {
228
+ header: (_jsxs("div", { className: "flex items-center gap-2", children: [_jsx("i", { className: "fa fa-euro-sign" }), _jsx("span", { children: "Precio" })] })),
229
+ value: "price",
230
+ align: "right",
231
+ type: "currency",
232
+ headerActions: () => [
233
+ _jsx(Button, { size: "sm", variant: "ghost", icon: "fa-download", onClick: () => console.log("Exportar precios"), children: "Exportar" }, "export"),
234
+ _jsx(Button, { size: "sm", variant: "ghost", icon: "fa-filter", onClick: () => console.log("Filtrar precios"), children: "Filtrar" }, "filter"),
235
+ ],
236
+ },
237
+ ];
238
+ 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: "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("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("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." })] })] })] }) })] })] }) }) }));
239
+ };
240
+ export default DataTableDocs;
@@ -0,0 +1,4 @@
1
+ import React from "react";
2
+ declare const DialogDocs: React.FC;
3
+ export default DialogDocs;
4
+ //# sourceMappingURL=DialogDocs.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DialogDocs.d.ts","sourceRoot":"","sources":["../../src/docs/DialogDocs.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAmB,MAAM,OAAO,CAAC;AAGxC,QAAA,MAAM,UAAU,EAAE,KAAK,CAAC,EAgYvB,CAAC;AAEF,eAAe,UAAU,CAAC"}