@axzydev/axzy_ui_system 1.2.9 → 1.2.12
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/README.md +6 -0
- package/dist/index.cjs +313 -242
- package/dist/index.cjs.map +1 -1
- package/dist/index.css +1 -1
- package/dist/index.css.map +1 -1
- package/dist/index.d.cts +142 -6
- package/dist/index.d.ts +142 -6
- package/dist/index.js +313 -242
- package/dist/index.js.map +1 -1
- package/package.json +4 -3
- package/snippets/axzy-ui-system.code-snippets +547 -0
- package/src/App.tsx +37 -34
- package/src/components/avatar/avatar.props.ts +12 -1
- package/src/components/avatar/avatar.stories.tsx +19 -0
- package/src/components/avatar/avatar.tsx +27 -4
- package/src/components/calendar/calendar.tsx +1 -1
- package/src/components/card/card.tsx +11 -8
- package/src/components/confirm-dialog/confirm-dialog.tsx +1 -1
- package/src/components/data-table/dataTable.props.ts +10 -0
- package/src/components/data-table/dataTable.tsx +27 -16
- package/src/components/date-picker/datePicker.tsx +1 -1
- package/src/components/dialog/dialog.tsx +3 -2
- package/src/components/divider/divider.tsx +1 -1
- package/src/components/drawer/drawer.tsx +1 -1
- package/src/components/dropfile/dropfile.props.ts +6 -0
- package/src/components/dropfile/dropfile.tsx +65 -30
- package/src/components/form-builder/fieldRenderer.tsx +3 -3
- package/src/components/input/input.tsx +7 -7
- package/src/components/layout/layout.tsx +1 -1
- package/src/components/loader/loader.tsx +1 -1
- package/src/components/navbar/navbar.tsx +10 -10
- package/src/components/pagination/pagination.tsx +11 -11
- package/src/components/popover/popover.tsx +1 -1
- package/src/components/search-select/search-select.tsx +11 -11
- package/src/components/searchTable/components/EditableCell.tsx +1 -1
- package/src/components/searchTable/components/PaginationControls.tsx +2 -2
- package/src/components/searchTable/components/PaginationInfo.tsx +1 -1
- package/src/components/searchTable/components/SearchAndSortBar.tsx +1 -1
- package/src/components/searchTable/components/SearchInput.tsx +1 -1
- package/src/components/searchTable/components/SortButton.tsx +3 -3
- package/src/components/searchTable/components/TableHeader.tsx +1 -1
- package/src/components/searchTable/components/TableRow.tsx +4 -4
- package/src/components/searchTable/searchTable.tsx +2 -2
- package/src/components/select/select.tsx +8 -10
- package/src/components/sidebar/sidebar.tsx +29 -29
- package/src/components/slider/slider.tsx +3 -3
- package/src/components/stepper/stepper.props.ts +4 -0
- package/src/components/stepper/stepper.tsx +5 -5
- package/src/components/table/table.props.ts +21 -3
- package/src/components/table/table.tsx +27 -16
- package/src/components/tabs/tabs.tsx +4 -4
- package/src/components/textarea/textarea.tsx +3 -3
- package/src/components/theme-provider/themeProvider.props.ts +21 -3
- package/src/components/theme-provider/themeProvider.tsx +32 -32
- package/src/components/time-picker/timePicker.tsx +5 -5
- package/src/components/toast/toast.tsx +1 -1
- package/src/components/tooltip/tooltip.tsx +1 -1
- package/src/components/topbar/topbar.tsx +7 -7
- package/src/dev.css +1 -1
- package/src/hooks/useClickOutside.ts +8 -0
- package/src/hooks/useTableState.ts +5 -2
- package/src/index.css +24 -1
- package/src/showcases/HomeShowcase.tsx +95 -3
- package/src/theme/theme.ts +38 -17
- package/src/types/field.types.ts +70 -7
- package/src/utils/styles.ts +5 -5
package/src/App.tsx
CHANGED
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
import React, { useEffect, useMemo, useState } from "react";
|
|
2
2
|
import {
|
|
3
3
|
FaCreditCard,
|
|
4
|
-
FaHome,
|
|
4
|
+
FaHome,
|
|
5
5
|
FaKeyboard,
|
|
6
6
|
FaRegBell,
|
|
7
|
-
FaSearch,
|
|
8
7
|
FaSlidersH,
|
|
9
8
|
FaTable,
|
|
10
9
|
} from "react-icons/fa";
|
|
@@ -61,36 +60,35 @@ import {
|
|
|
61
60
|
ThemeProviderShowcase,
|
|
62
61
|
} from "./showcases/FeedbackShowcases";
|
|
63
62
|
|
|
63
|
+
type ViewMode = "home" | "ui-system";
|
|
64
|
+
|
|
64
65
|
function App() {
|
|
65
|
-
const [
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
const [
|
|
66
|
+
const [view, setView] = useState<ViewMode>(() => {
|
|
67
|
+
const hash = window.location.hash.replace("#", "");
|
|
68
|
+
return hash.startsWith("ui-system") ? "ui-system" : "home";
|
|
69
|
+
});
|
|
70
|
+
const [showroomActive, setShowroomActive] = useState("getting-started");
|
|
71
|
+
const [searchTerm] = useState("");
|
|
72
|
+
const [subitemConnector] = useState<
|
|
70
73
|
"dot" | "|" | "none"
|
|
71
74
|
>("dot");
|
|
72
75
|
|
|
73
76
|
useEffect(() => {
|
|
74
77
|
const onHashChange = () => {
|
|
75
|
-
const
|
|
76
|
-
|
|
78
|
+
const hash = window.location.hash.replace("#", "");
|
|
79
|
+
setView(hash.startsWith("ui-system") ? "ui-system" : "home");
|
|
77
80
|
};
|
|
78
81
|
window.addEventListener("hashchange", onHashChange);
|
|
79
82
|
return () => window.removeEventListener("hashchange", onHashChange);
|
|
80
83
|
}, []);
|
|
81
84
|
|
|
82
|
-
|
|
83
|
-
window.location.hash = activeComponentId;
|
|
84
|
-
}, [activeComponentId]);
|
|
85
|
-
|
|
86
|
-
// Group definitions for the sidebar
|
|
85
|
+
// Group definitions for the sidebar (UI System showroom)
|
|
87
86
|
const categories = [
|
|
88
87
|
{
|
|
89
88
|
id: "general",
|
|
90
89
|
label: "General",
|
|
91
90
|
icon: <FaHome />,
|
|
92
91
|
subitems: [
|
|
93
|
-
{ id: "home", label: "Home" },
|
|
94
92
|
{ id: "getting-started", label: "Getting Started" },
|
|
95
93
|
],
|
|
96
94
|
},
|
|
@@ -174,8 +172,8 @@ function App() {
|
|
|
174
172
|
if (matches) {
|
|
175
173
|
return {
|
|
176
174
|
...cat,
|
|
177
|
-
isActive:
|
|
178
|
-
action: () =>
|
|
175
|
+
isActive: showroomActive === cat.id,
|
|
176
|
+
action: () => setShowroomActive(cat.id),
|
|
179
177
|
};
|
|
180
178
|
}
|
|
181
179
|
return null;
|
|
@@ -190,8 +188,8 @@ function App() {
|
|
|
190
188
|
const mappedSubitems = matchingSubitems.map((sub) => ({
|
|
191
189
|
id: sub.id,
|
|
192
190
|
label: sub.label,
|
|
193
|
-
isActive:
|
|
194
|
-
action: () =>
|
|
191
|
+
isActive: showroomActive === sub.id,
|
|
192
|
+
action: () => setShowroomActive(sub.id),
|
|
195
193
|
}));
|
|
196
194
|
|
|
197
195
|
const isAnySubitemActive = mappedSubitems.some((sub) => sub.isActive);
|
|
@@ -207,7 +205,7 @@ function App() {
|
|
|
207
205
|
if (cat.subitems) return cat.subitems.length > 0;
|
|
208
206
|
return true;
|
|
209
207
|
});
|
|
210
|
-
}, [searchTerm,
|
|
208
|
+
}, [searchTerm, showroomActive]);
|
|
211
209
|
|
|
212
210
|
const sidebarProps = {
|
|
213
211
|
navigationItems: filteredNavigationItems,
|
|
@@ -215,27 +213,24 @@ function App() {
|
|
|
215
213
|
};
|
|
216
214
|
|
|
217
215
|
const topBarProps = {
|
|
218
|
-
logoText: "AXZY
|
|
216
|
+
logoText: "AXZY UI System",
|
|
219
217
|
userMenu: {
|
|
220
218
|
userName: "Alex Dev",
|
|
221
219
|
userEmail: "alex@axzy.dev",
|
|
222
220
|
menuItems: [
|
|
223
221
|
{
|
|
224
|
-
label: "
|
|
222
|
+
label: "Ir al Portafolio",
|
|
225
223
|
onClick: () => {
|
|
226
|
-
|
|
227
|
-
setSearchTerm("");
|
|
224
|
+
window.location.hash = "home";
|
|
228
225
|
},
|
|
229
226
|
},
|
|
230
227
|
],
|
|
231
228
|
},
|
|
232
229
|
};
|
|
233
230
|
|
|
234
|
-
// Render correct component based on active navigation
|
|
231
|
+
// Render correct component based on active showroom navigation
|
|
235
232
|
const renderShowcase = () => {
|
|
236
|
-
switch (
|
|
237
|
-
case "home":
|
|
238
|
-
return <HomeShowcase />;
|
|
233
|
+
switch (showroomActive) {
|
|
239
234
|
case "getting-started":
|
|
240
235
|
return <GettingStartedShowcase />;
|
|
241
236
|
// Structure
|
|
@@ -308,17 +303,25 @@ function App() {
|
|
|
308
303
|
case "themeprovider":
|
|
309
304
|
return <ThemeProviderShowcase />;
|
|
310
305
|
default:
|
|
311
|
-
return <
|
|
306
|
+
return <GettingStartedShowcase />;
|
|
312
307
|
}
|
|
313
308
|
};
|
|
314
309
|
|
|
315
310
|
return (
|
|
316
|
-
<ITThemeProvider showFab={
|
|
317
|
-
|
|
318
|
-
<div className="
|
|
319
|
-
|
|
311
|
+
<ITThemeProvider showFab={false}>
|
|
312
|
+
{view === "home" ? (
|
|
313
|
+
<div className="min-h-screen bg-slate-50 dark:bg-slate-950 py-10 px-4 sm:px-6 lg:px-8">
|
|
314
|
+
<div className="max-w-6xl mx-auto">
|
|
315
|
+
<HomeShowcase />
|
|
316
|
+
</div>
|
|
320
317
|
</div>
|
|
321
|
-
|
|
318
|
+
) : (
|
|
319
|
+
<ITLayout sidebar={sidebarProps} topBar={topBarProps}>
|
|
320
|
+
<div className="max-w-7xl mx-auto">
|
|
321
|
+
{renderShowcase()}
|
|
322
|
+
</div>
|
|
323
|
+
</ITLayout>
|
|
324
|
+
)}
|
|
322
325
|
</ITThemeProvider>
|
|
323
326
|
);
|
|
324
327
|
}
|
|
@@ -11,7 +11,18 @@ export interface ITAvatarProps {
|
|
|
11
11
|
initials?: string;
|
|
12
12
|
/** Avatar dimensions. Valid values: `"xs"`, `"sm"`, `"md"`, `"lg"`, `"xl"`. @default "md" */
|
|
13
13
|
size?: AvatarSize;
|
|
14
|
-
/**
|
|
14
|
+
/**
|
|
15
|
+
* Color de fondo para el fallback de iniciales. Acepta un valor de color
|
|
16
|
+
* real (`"#8b5cf6"`, `"rgb(...)"`, `"hsl(...)"`, `"var(--...)"`) — se
|
|
17
|
+
* aplica como `style` inline y SIEMPRE se renderiza — o una clase de
|
|
18
|
+
* Tailwind (`"bg-purple-600"`) por compatibilidad con código existente.
|
|
19
|
+
* Una clase de Tailwind solo se ve si esa clase exacta ya existe en el
|
|
20
|
+
* CSS compilado que consume la app (esta librería se distribuye con un
|
|
21
|
+
* CSS estático pre-compilado, ver scripts/build-css.mjs), así que para
|
|
22
|
+
* cualquier color calculado en tiempo de ejecución (p.ej. un hash por
|
|
23
|
+
* usuario) se recomienda pasar el valor de color directamente.
|
|
24
|
+
* @default "bg-primary-600"
|
|
25
|
+
*/
|
|
15
26
|
color?: string;
|
|
16
27
|
/** Additional CSS class names for the avatar container. */
|
|
17
28
|
className?: string;
|
|
@@ -44,3 +44,22 @@ export const Sizes: Story = {
|
|
|
44
44
|
</div>
|
|
45
45
|
),
|
|
46
46
|
};
|
|
47
|
+
|
|
48
|
+
export const WithRawColor: Story = {
|
|
49
|
+
name: "Con color calculado en runtime",
|
|
50
|
+
parameters: {
|
|
51
|
+
docs: {
|
|
52
|
+
description: {
|
|
53
|
+
story:
|
|
54
|
+
"Cuando el color se calcula dinámicamente (por ejemplo, un hash por usuario o etiqueta), pasa un valor de color real en vez de una clase de Tailwind. Una clase de Tailwind arbitraria solo se ve si ya existe en el CSS pre-compilado de esta librería; un color inline siempre se aplica.",
|
|
55
|
+
},
|
|
56
|
+
},
|
|
57
|
+
},
|
|
58
|
+
render: () => (
|
|
59
|
+
<div className="flex items-center gap-4">
|
|
60
|
+
{["#3b82f6", "#a855f7", "#059669", "#f59e0b", "#ec4899"].map((hex) => (
|
|
61
|
+
<ITAvatar key={hex} initials="JD" size="md" color={hex} />
|
|
62
|
+
))}
|
|
63
|
+
</div>
|
|
64
|
+
),
|
|
65
|
+
};
|
|
@@ -12,7 +12,18 @@ const sizeMap: Record<AvatarSize, { container: string; text: string }> = {
|
|
|
12
12
|
|
|
13
13
|
const DEFAULT_COLOR = "bg-primary-600";
|
|
14
14
|
const DEFAULT_BG = "var(--color-primary-600)";
|
|
15
|
-
const DEFAULT_SHADOW = "0
|
|
15
|
+
const DEFAULT_SHADOW = "0 6px 16px -2px rgba(37, 99, 235, 0.25)";
|
|
16
|
+
|
|
17
|
+
// Un valor tipo "#8b5cf6", "rgb(...)", "hsl(...)" o "var(--...)" se aplica
|
|
18
|
+
// como color inline; cualquier otra cosa se trata como clase de Tailwind
|
|
19
|
+
// (comportamiento previo, sin romper a quien ya pasa "bg-purple-600" etc.).
|
|
20
|
+
// Motivo: esta librería se consume vía un CSS estático pre-compilado
|
|
21
|
+
// (ver scripts/build-css.mjs) que solo contiene las clases usadas en el
|
|
22
|
+
// código FUENTE de la librería. Si una app consumidora pasa un color de
|
|
23
|
+
// Tailwind que la librería nunca usa en ningún otro lado, esa clase no
|
|
24
|
+
// existe en el CSS entregado y el avatar se renderiza sin color visible.
|
|
25
|
+
// Un valor de color inline no tiene ese problema: siempre se aplica.
|
|
26
|
+
const isRawColorValue = (value: string) => /^#|^rgb|^hsl|^var\(/i.test(value.trim());
|
|
16
27
|
|
|
17
28
|
/**
|
|
18
29
|
* Circular avatar component with image, initials fallback, and optional badge overlay.
|
|
@@ -22,6 +33,11 @@ const DEFAULT_SHADOW = "0 4px 14px 0 rgba(37, 99, 235, 0.35)";
|
|
|
22
33
|
*
|
|
23
34
|
* @example
|
|
24
35
|
* <ITAvatar initials="JD" size="md" color="bg-purple-600" />
|
|
36
|
+
*
|
|
37
|
+
* @example
|
|
38
|
+
* // Recomendado cuando el color se calcula en tiempo de ejecución (p.ej. un
|
|
39
|
+
* // hash por usuario/etiqueta): pasa un valor de color real, no una clase.
|
|
40
|
+
* <ITAvatar initials="JD" size="md" color="#8b5cf6" />
|
|
25
41
|
*/
|
|
26
42
|
export default function ITAvatar({
|
|
27
43
|
src,
|
|
@@ -34,17 +50,24 @@ export default function ITAvatar({
|
|
|
34
50
|
onClick,
|
|
35
51
|
}: ITAvatarProps) {
|
|
36
52
|
const { container, text } = sizeMap[size];
|
|
37
|
-
const
|
|
53
|
+
const useDefaultStyle = !color || color === DEFAULT_COLOR;
|
|
54
|
+
const useRawColorStyle = !useDefaultStyle && isRawColorValue(color);
|
|
38
55
|
|
|
39
56
|
return (
|
|
40
57
|
<div
|
|
41
58
|
className={clsx(
|
|
42
59
|
"relative inline-flex items-center justify-center rounded-full flex-shrink-0 overflow-hidden text-white font-bold tracking-wide",
|
|
43
60
|
container,
|
|
44
|
-
!
|
|
61
|
+
!useDefaultStyle && !useRawColorStyle && color,
|
|
45
62
|
className,
|
|
46
63
|
)}
|
|
47
|
-
style={
|
|
64
|
+
style={
|
|
65
|
+
useDefaultStyle
|
|
66
|
+
? { backgroundColor: DEFAULT_BG, boxShadow: DEFAULT_SHADOW }
|
|
67
|
+
: useRawColorStyle
|
|
68
|
+
? { backgroundColor: color }
|
|
69
|
+
: undefined
|
|
70
|
+
}
|
|
48
71
|
onClick={onClick}
|
|
49
72
|
role={onClick ? "button" : undefined}
|
|
50
73
|
tabIndex={onClick ? 0 : undefined}
|
|
@@ -371,7 +371,7 @@ export const ITCalendar: React.FC<ITCalendarProps> = ({
|
|
|
371
371
|
{/* Weekday Headers */}
|
|
372
372
|
<div className="grid grid-cols-7 mb-2">
|
|
373
373
|
{['Lun', 'Mar', 'Mié', 'Jue', 'Vie', 'Sáb', 'Dom'].map(day => (
|
|
374
|
-
<ITText key={day} as="div" className="text-center text-xs font-semibold text-
|
|
374
|
+
<ITText key={day} as="div" className="text-center text-xs font-semibold text-secondary-400 uppercase py-1">
|
|
375
375
|
{day}
|
|
376
376
|
</ITText>
|
|
377
377
|
))}
|
|
@@ -33,15 +33,18 @@ export default function ITCard({
|
|
|
33
33
|
|
|
34
34
|
const containerStyle: React.CSSProperties = {
|
|
35
35
|
backgroundColor: "var(--card-bg, #ffffff)",
|
|
36
|
-
borderColor: "var(--card-border,
|
|
36
|
+
borderColor: "var(--card-border, rgba(15, 23, 42, 0.06))",
|
|
37
37
|
borderWidth: "1px",
|
|
38
|
-
borderRadius: "var(--card-radius,
|
|
38
|
+
borderRadius: "var(--card-radius, var(--radius-2xl))",
|
|
39
|
+
// Soft depth: every card floats a little at rest; interactive cards
|
|
40
|
+
// gain visual weight on hover instead of appearing flat until clicked.
|
|
39
41
|
boxShadow: onClick
|
|
40
42
|
? isHovered
|
|
41
|
-
? "
|
|
42
|
-
: "
|
|
43
|
-
: "
|
|
44
|
-
transition: onClick ? "
|
|
43
|
+
? "var(--shadow-lg)"
|
|
44
|
+
: "var(--shadow-sm)"
|
|
45
|
+
: "var(--shadow-sm)",
|
|
46
|
+
transition: onClick ? "box-shadow 0.2s ease-in-out, transform 0.2s ease-in-out" : "none",
|
|
47
|
+
transform: onClick && isHovered ? "translateY(-2px)" : "translateY(0)",
|
|
45
48
|
cursor: onClick ? "pointer" : "default",
|
|
46
49
|
};
|
|
47
50
|
|
|
@@ -74,12 +77,12 @@ export default function ITCard({
|
|
|
74
77
|
{title}
|
|
75
78
|
</ITText>
|
|
76
79
|
)}
|
|
77
|
-
<ITText as="div" className="text-
|
|
80
|
+
<ITText as="div" className="text-secondary-600">{children}</ITText>
|
|
78
81
|
</div>
|
|
79
82
|
{actions && (
|
|
80
83
|
<div
|
|
81
84
|
className={clsx(
|
|
82
|
-
"p-4 border-t border-
|
|
85
|
+
"p-4 border-t border-secondary-100 mt-auto",
|
|
83
86
|
actionClassName,
|
|
84
87
|
)}
|
|
85
88
|
>
|
|
@@ -37,7 +37,7 @@ export default function ITConfirmDialog({
|
|
|
37
37
|
if (!isOpen) return null;
|
|
38
38
|
|
|
39
39
|
return (
|
|
40
|
-
<div className="fixed inset-0 z-[
|
|
40
|
+
<div className="fixed inset-0 z-[60] flex items-center justify-center p-4">
|
|
41
41
|
<div className="absolute inset-0 bg-black/40 backdrop-blur-sm" onClick={onClose} />
|
|
42
42
|
<div
|
|
43
43
|
className={clsx(
|
|
@@ -1,18 +1,28 @@
|
|
|
1
1
|
import { ReactNode } from "react";
|
|
2
2
|
import { Column } from "../table/table.props";
|
|
3
3
|
|
|
4
|
+
/** Parameters passed to `fetchData` every time pagination, filters, or sorting change. */
|
|
4
5
|
export interface ITDataTableFetchParams {
|
|
6
|
+
/** 1-indexed current page number. */
|
|
5
7
|
page: number;
|
|
8
|
+
/** Number of rows requested per page. */
|
|
6
9
|
limit: number;
|
|
10
|
+
/** Active per-column filter values (from `Column.filter`), keyed by column `key`. */
|
|
7
11
|
filters: Record<string, string | number | boolean | Date>;
|
|
12
|
+
/** Active sort, present only when the user has clicked a sortable column header. */
|
|
8
13
|
sort?: {
|
|
14
|
+
/** Column `key` currently sorted by. */
|
|
9
15
|
key: string;
|
|
16
|
+
/** Sort direction. */
|
|
10
17
|
direction: "asc" | "desc";
|
|
11
18
|
};
|
|
12
19
|
}
|
|
13
20
|
|
|
21
|
+
/** Expected shape of the Promise returned by `fetchData`. */
|
|
14
22
|
export interface ITDataTableResponse<T> {
|
|
23
|
+
/** Rows for the requested page. */
|
|
15
24
|
data: T[];
|
|
25
|
+
/** Total row count across all pages (used to compute the paginator's total pages). */
|
|
16
26
|
total: number;
|
|
17
27
|
}
|
|
18
28
|
|
|
@@ -11,6 +11,17 @@ import { Column } from "../table/table.props";
|
|
|
11
11
|
import { formatCurrencyMX } from "../table/table";
|
|
12
12
|
import { ITDataTableProps } from "./dataTable.props";
|
|
13
13
|
import ITText from "@/components/text/text";
|
|
14
|
+
import {
|
|
15
|
+
tableActionsCell,
|
|
16
|
+
tableBody,
|
|
17
|
+
tableCell,
|
|
18
|
+
tableCellText,
|
|
19
|
+
tableContainer,
|
|
20
|
+
tableEmptyContent,
|
|
21
|
+
tableHeaderCell,
|
|
22
|
+
tableHeaderRow,
|
|
23
|
+
tableRow,
|
|
24
|
+
} from "@/utils/styles";
|
|
14
25
|
|
|
15
26
|
const getNestedValue = (obj: unknown, path: string) => {
|
|
16
27
|
return path.split(".").reduce((acc, part) => acc && acc[part], obj);
|
|
@@ -136,14 +147,14 @@ export default function ITDataTable<T extends Record<string, unknown>>({
|
|
|
136
147
|
title={`${getToggleLabel()} para ${col.label}`}
|
|
137
148
|
disabled={isLoading}
|
|
138
149
|
>
|
|
139
|
-
<div className="relative w-10 h-5 bg-
|
|
150
|
+
<div className="relative w-10 h-5 bg-secondary-300 rounded-full">
|
|
140
151
|
<div
|
|
141
152
|
className={clsx(
|
|
142
153
|
"absolute top-0.5 w-4 h-4 rounded-full transition-all duration-300 shadow-sm",
|
|
143
154
|
{
|
|
144
|
-
"left-0.5 bg-
|
|
155
|
+
"left-0.5 bg-secondary-400": currentValue === undefined,
|
|
145
156
|
"left-5 bg-slate-500": currentValue === true,
|
|
146
|
-
"left-0.5 bg-
|
|
157
|
+
"left-0.5 bg-secondary-500": currentValue === false,
|
|
147
158
|
}
|
|
148
159
|
)}
|
|
149
160
|
/>
|
|
@@ -157,7 +168,7 @@ export default function ITDataTable<T extends Record<string, unknown>>({
|
|
|
157
168
|
return <FaSpinner className="animate-spin" aria-label="Cargando opciones" title="Cargando opciones" />;
|
|
158
169
|
}
|
|
159
170
|
if (col.catalogOptions.error) {
|
|
160
|
-
return <ITText as="span" className="text-
|
|
171
|
+
return <ITText as="span" className="text-danger-500 text-xs">Error cargando</ITText>;
|
|
161
172
|
}
|
|
162
173
|
return (
|
|
163
174
|
<ITSelect
|
|
@@ -203,9 +214,9 @@ export default function ITDataTable<T extends Record<string, unknown>>({
|
|
|
203
214
|
return typeof value === "number" && col.currencyMX ? formatCurrencyMX(value) : value;
|
|
204
215
|
case "boolean":
|
|
205
216
|
return value ? (
|
|
206
|
-
<FaCheck className="text-
|
|
217
|
+
<FaCheck className="text-success-500" aria-label="Verdadero" title="Verdadero" />
|
|
207
218
|
) : (
|
|
208
|
-
<FaTimes className="text-
|
|
219
|
+
<FaTimes className="text-danger-500" aria-label="Falso" title="Falso" />
|
|
209
220
|
);
|
|
210
221
|
case "actions":
|
|
211
222
|
return col.actions ? col.actions(row) : null;
|
|
@@ -253,7 +264,7 @@ export default function ITDataTable<T extends Record<string, unknown>>({
|
|
|
253
264
|
|
|
254
265
|
return (
|
|
255
266
|
<div className={clsx("space-y-4 w-full relative", containerClassName)}>
|
|
256
|
-
<div className=
|
|
267
|
+
<div className={tableContainer} style={{ backgroundColor: 'var(--color-table-rowBg, #ffffff)' }}>
|
|
257
268
|
{title && (
|
|
258
269
|
<div className="px-6 py-5 flex items-center justify-between" style={{ backgroundColor: 'var(--color-table-rowBg, #ffffff)' }}>
|
|
259
270
|
<ITText as="h2" className="text-xl font-bold text-secondary-900 leading-tight">{title}</ITText>
|
|
@@ -316,7 +327,7 @@ export default function ITDataTable<T extends Record<string, unknown>>({
|
|
|
316
327
|
))
|
|
317
328
|
) : (
|
|
318
329
|
!isLoading && (
|
|
319
|
-
<div className="
|
|
330
|
+
<div className={clsx(tableEmptyContent, "py-12")}>
|
|
320
331
|
<ITText as="span" className="text-lg">No se encontraron resultados</ITText>
|
|
321
332
|
<ITText as="span" className="text-sm mt-1">Intenta ajustar los filtros</ITText>
|
|
322
333
|
</div>
|
|
@@ -336,9 +347,9 @@ export default function ITDataTable<T extends Record<string, unknown>>({
|
|
|
336
347
|
)}
|
|
337
348
|
>
|
|
338
349
|
<thead>
|
|
339
|
-
<tr className="
|
|
350
|
+
<tr className={clsx(tableHeaderRow, "dark:text-slate-200")}>
|
|
340
351
|
{columns.map((col) => (
|
|
341
|
-
<th key={col.key} scope="col" className={
|
|
352
|
+
<th key={col.key} scope="col" className={tableHeaderCell(col.className)}>
|
|
342
353
|
<div className="flex flex-col gap-3 min-w-[150px]">
|
|
343
354
|
<div className="flex items-center justify-between gap-2">
|
|
344
355
|
<ITText as="span" className="text-slate-900 dark:text-white font-bold">{col.label}</ITText>
|
|
@@ -364,18 +375,18 @@ export default function ITDataTable<T extends Record<string, unknown>>({
|
|
|
364
375
|
))}
|
|
365
376
|
</tr>
|
|
366
377
|
</thead>
|
|
367
|
-
<tbody className="
|
|
378
|
+
<tbody className={clsx(tableBody, "dark:divide-slate-700/30")}>
|
|
368
379
|
{data.length > 0 ? (
|
|
369
380
|
data.map((row, rowIndex) => (
|
|
370
|
-
<tr key={rowIndex} className={clsx(
|
|
381
|
+
<tr key={rowIndex} className={clsx(tableRow, variant === "striped" && "odd:bg-secondary-50/40 dark:odd:bg-slate-800/20")}>
|
|
371
382
|
{columns.map((col) => (
|
|
372
|
-
<td key={`${rowIndex}-${col.key}`} className={
|
|
383
|
+
<td key={`${rowIndex}-${col.key}`} className={tableCell(col.className)}>
|
|
373
384
|
{col.type === "actions" ? (
|
|
374
|
-
<div className=
|
|
385
|
+
<div className={tableActionsCell}>
|
|
375
386
|
{renderCellContent(col, row) as React.ReactNode}
|
|
376
387
|
</div>
|
|
377
388
|
) : (
|
|
378
|
-
<div className=
|
|
389
|
+
<div className={tableCellText}>
|
|
379
390
|
{renderCellContent(col, row) as React.ReactNode}
|
|
380
391
|
</div>
|
|
381
392
|
)}
|
|
@@ -387,7 +398,7 @@ export default function ITDataTable<T extends Record<string, unknown>>({
|
|
|
387
398
|
<tr>
|
|
388
399
|
<td colSpan={columns.length} className="px-6 py-12 text-center">
|
|
389
400
|
{!isLoading && (
|
|
390
|
-
<div className=
|
|
401
|
+
<div className={tableEmptyContent}>
|
|
391
402
|
<ITText as="span" className="text-lg">No se encontraron resultados</ITText>
|
|
392
403
|
<ITText as="span" className="text-sm mt-1">Intenta ajustar los filtros</ITText>
|
|
393
404
|
</div>
|
|
@@ -67,9 +67,10 @@ export default function ITDialog({
|
|
|
67
67
|
|
|
68
68
|
const content = (
|
|
69
69
|
<div
|
|
70
|
+
data-it-dialog="true"
|
|
70
71
|
className={`fixed inset-0 flex ${
|
|
71
72
|
fullScreen ? "items-stretch" : "items-center justify-center"
|
|
72
|
-
} bg-
|
|
73
|
+
} bg-slate-900/50 z-[60]`}
|
|
73
74
|
>
|
|
74
75
|
<div
|
|
75
76
|
ref={modalRef}
|
|
@@ -97,7 +98,7 @@ export default function ITDialog({
|
|
|
97
98
|
) : (
|
|
98
99
|
<>
|
|
99
100
|
<button
|
|
100
|
-
className="absolute top-2 right-2 text-
|
|
101
|
+
className="absolute top-2 right-2 text-secondary-600 hover:text-secondary-900"
|
|
101
102
|
onClick={onClose}
|
|
102
103
|
>
|
|
103
104
|
<FaRegTimesCircle />
|
|
@@ -14,7 +14,7 @@ import { ITDividerProps } from "./divider.props";
|
|
|
14
14
|
*
|
|
15
15
|
* @example
|
|
16
16
|
* ```tsx
|
|
17
|
-
* <ITDivider orientation="vertical" color="bg-
|
|
17
|
+
* <ITDivider orientation="vertical" color="bg-danger-500" thickness="w-1" />
|
|
18
18
|
* ```
|
|
19
19
|
*/
|
|
20
20
|
export default function ITDivider({
|
|
@@ -41,7 +41,7 @@ export default function ITDrawer({
|
|
|
41
41
|
return (
|
|
42
42
|
<>
|
|
43
43
|
{isOpen && (
|
|
44
|
-
<div className="fixed inset-0 z-[
|
|
44
|
+
<div className="fixed inset-0 z-[50] flex">
|
|
45
45
|
<div className="absolute inset-0 bg-black/40 backdrop-blur-sm transition-opacity" />
|
|
46
46
|
<div
|
|
47
47
|
ref={panelRef}
|
|
@@ -7,6 +7,12 @@ export enum FileTypeEnum {
|
|
|
7
7
|
PNG = "image/png",
|
|
8
8
|
JPG = "image/jpg",
|
|
9
9
|
JPEG = "image/jpeg",
|
|
10
|
+
MP4 = "video/mp4",
|
|
11
|
+
MOV = "video/quicktime",
|
|
12
|
+
AVI = "video/x-msvideo",
|
|
13
|
+
MKV = "video/x-matroska",
|
|
14
|
+
VIDEO_3GPP = "video/3gpp",
|
|
15
|
+
WEBM = "video/webm",
|
|
10
16
|
}
|
|
11
17
|
|
|
12
18
|
/** Upload lifecycle status */
|