@axzydev/axzy_ui_system 1.2.8 → 1.2.11
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 +109 -51
- package/dist/index.cjs +141 -73
- 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 +141 -5
- package/dist/index.d.ts +141 -5
- package/dist/index.js +141 -73
- 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 +43 -33
- package/src/components/avatar/avatar.props.ts +12 -1
- package/src/components/avatar/avatar.stories.tsx +19 -0
- package/src/components/avatar/avatar.tsx +26 -3
- 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 +24 -13
- package/src/components/date-picker/datePicker.tsx +1 -1
- package/src/components/dialog/dialog.tsx +2 -1
- package/src/components/drawer/drawer.tsx +1 -1
- package/src/components/dropfile/dropfile.props.ts +6 -0
- package/src/components/dropfile/dropfile.tsx +51 -16
- package/src/components/layout/layout.tsx +1 -1
- package/src/components/navbar/navbar.tsx +2 -2
- package/src/components/popover/popover.tsx +1 -1
- package/src/components/search-select/search-select.tsx +4 -4
- package/src/components/select/select.tsx +6 -8
- package/src/components/sidebar/sidebar.tsx +15 -15
- package/src/components/stepper/stepper.props.ts +4 -0
- package/src/components/table/table.props.ts +21 -3
- package/src/components/table/table.tsx +24 -13
- package/src/components/theme-provider/themeProvider.props.ts +21 -3
- package/src/components/time-picker/timePicker.tsx +1 -1
- package/src/components/toast/toast.tsx +1 -1
- package/src/components/tooltip/tooltip.tsx +1 -1
- package/src/components/topbar/topbar.tsx +1 -1
- package/src/dev.css +1 -1
- package/src/hooks/useClickOutside.ts +8 -0
- package/src/hooks/useTableState.ts +5 -2
- package/src/index.css +1 -1
- package/src/showcases/GettingStartedShowcase.tsx +207 -0
- package/src/showcases/HomeShowcase.tsx +95 -3
- package/src/theme/theme.ts +21 -0
- package/src/types/field.types.ts +70 -7
|
@@ -4,6 +4,7 @@ import { useState } from "react";
|
|
|
4
4
|
import { FaAngleDown } from "react-icons/fa";
|
|
5
5
|
import { ITSelectProps } from "./select.props";
|
|
6
6
|
import ITText from "@/components/text/text";
|
|
7
|
+
import { inputError, inputLabel } from "@/utils/styles";
|
|
7
8
|
|
|
8
9
|
export default function ITSelect({
|
|
9
10
|
name,
|
|
@@ -80,10 +81,7 @@ export default function ITSelect({
|
|
|
80
81
|
<ITText
|
|
81
82
|
as="label"
|
|
82
83
|
htmlFor={name}
|
|
83
|
-
className={
|
|
84
|
-
"text-sm font-medium text-gray-700 dark:text-slate-300 pt-0",
|
|
85
|
-
{ "text-red-500": hasError }
|
|
86
|
-
)}
|
|
84
|
+
className={inputLabel(hasError)}
|
|
87
85
|
>
|
|
88
86
|
<ITText as="span">{label}</ITText>
|
|
89
87
|
{required && <ITText as="span" className="text-red-500 ml-1">*</ITText>}
|
|
@@ -110,11 +108,11 @@ export default function ITSelect({
|
|
|
110
108
|
)}
|
|
111
109
|
style={getStyle()}
|
|
112
110
|
>
|
|
113
|
-
<option value=""
|
|
111
|
+
<option value="">{placeholder || "Selecciona una opción"}</option>
|
|
114
112
|
{
|
|
115
113
|
readOnly ? (
|
|
116
114
|
<option value={value} disabled>
|
|
117
|
-
|
|
115
|
+
{options.find((option) => option[valueField] === value)?.[labelField]}
|
|
118
116
|
</option>
|
|
119
117
|
) : (
|
|
120
118
|
options.map((option) => (
|
|
@@ -123,7 +121,7 @@ export default function ITSelect({
|
|
|
123
121
|
value={option[valueField]}
|
|
124
122
|
title={option[labelField]}
|
|
125
123
|
>
|
|
126
|
-
|
|
124
|
+
{option[labelField]}
|
|
127
125
|
</option>
|
|
128
126
|
))
|
|
129
127
|
)
|
|
@@ -136,7 +134,7 @@ export default function ITSelect({
|
|
|
136
134
|
{/* Validation message aligned with select */}
|
|
137
135
|
{hasError && (
|
|
138
136
|
<div className="flex-shrink-0 min-w-[140px] flex items-center pt-3">
|
|
139
|
-
<ITText as="p" className=
|
|
137
|
+
<ITText as="p" className={inputError}>{errorMessage}</ITText>
|
|
140
138
|
</div>
|
|
141
139
|
)}
|
|
142
140
|
</div>
|
|
@@ -126,7 +126,7 @@ export default function ITSidebar({
|
|
|
126
126
|
style={{
|
|
127
127
|
zIndex: 50,
|
|
128
128
|
backgroundColor: "var(--sidebar-bg, rgba(255, 255, 255, 0.90))",
|
|
129
|
-
borderRight: "1px solid var(--sidebar-border,
|
|
129
|
+
borderRight: "1px solid var(--sidebar-border, var(--color-secondary-200))",
|
|
130
130
|
WebkitBackdropFilter: 'blur(12px)',
|
|
131
131
|
backdropFilter: 'blur(12px)',
|
|
132
132
|
}}
|
|
@@ -143,12 +143,12 @@ export default function ITSidebar({
|
|
|
143
143
|
${isSidebarCollapsed ? "justify-center p-2.5 mb-2" : "justify-between px-3.5 py-3 mb-1"}
|
|
144
144
|
`}
|
|
145
145
|
style={{
|
|
146
|
-
backgroundColor: item.isActive ? "var(--sidebar-active-bg,
|
|
146
|
+
backgroundColor: item.isActive ? "var(--sidebar-active-bg, var(--color-secondary-50))" : 'transparent',
|
|
147
147
|
boxShadow: item.isActive ? '0 1px 2px 0 rgba(0, 0, 0, 0.05)' : 'none',
|
|
148
|
-
border: item.isActive ? "1px solid var(--sidebar-border,
|
|
148
|
+
border: item.isActive ? "1px solid var(--sidebar-border, var(--color-secondary-200))" : '1px solid transparent'
|
|
149
149
|
}}
|
|
150
150
|
onMouseEnter={(e) => {
|
|
151
|
-
if (!item.isActive) e.currentTarget.style.backgroundColor = "var(--sidebar-hover-bg,
|
|
151
|
+
if (!item.isActive) e.currentTarget.style.backgroundColor = "var(--sidebar-hover-bg, var(--color-secondary-100))";
|
|
152
152
|
}}
|
|
153
153
|
onMouseLeave={(e) => {
|
|
154
154
|
if (!item.isActive) e.currentTarget.style.backgroundColor = 'transparent';
|
|
@@ -193,7 +193,7 @@ export default function ITSidebar({
|
|
|
193
193
|
|
|
194
194
|
{!isSidebarCollapsed && item.subitems && item.subitems.length > 0 && (
|
|
195
195
|
<div className={`flex-shrink-0 transition-transform duration-300 ease-[cubic-bezier(0.2,0,0,1)] ${expandedItems.has(item.id) ? "rotate-180" : ""}`}
|
|
196
|
-
style={{ color: item.isActive ? "var(--sidebar-active-color,
|
|
196
|
+
style={{ color: item.isActive ? "var(--sidebar-active-color, var(--color-secondary-900))" : "var(--sidebar-icon-color, var(--color-secondary-500))", opacity: 0.7 }}>
|
|
197
197
|
<FaChevronDown className="w-3 h-3" />
|
|
198
198
|
</div>
|
|
199
199
|
)}
|
|
@@ -220,15 +220,15 @@ export default function ITSidebar({
|
|
|
220
220
|
{/* Glassmorphism Collapsed Tooltip / Submenu */}
|
|
221
221
|
{isSidebarCollapsed && (
|
|
222
222
|
<div
|
|
223
|
-
className="absolute left-full top-0 ml-4 rounded-2xl opacity-0 invisible group-hover/navitem:opacity-100 group-hover/navitem:visible transition-all duration-300 pointer-events-none z-
|
|
223
|
+
className="absolute left-full top-0 ml-4 rounded-2xl opacity-0 invisible group-hover/navitem:opacity-100 group-hover/navitem:visible transition-all duration-300 pointer-events-none z-[70] min-w-[220px] overflow-hidden -translate-x-2 group-hover/navitem:translate-x-0 shadow-[0_10px_40px_-10px_rgba(0,0,0,0.15)]"
|
|
224
224
|
style={{
|
|
225
225
|
backgroundColor: "var(--sidebar-bg, #ffffff)",
|
|
226
|
-
border: "1px solid var(--sidebar-border,
|
|
226
|
+
border: "1px solid var(--sidebar-border, var(--color-secondary-200))",
|
|
227
227
|
WebkitBackdropFilter: 'blur(16px)',
|
|
228
228
|
backdropFilter: 'blur(16px)',
|
|
229
229
|
}}
|
|
230
230
|
>
|
|
231
|
-
<div className="px-5 py-4 flex items-center gap-3 font-semibold border-b" style={{ borderColor: "var(--sidebar-border,
|
|
231
|
+
<div className="px-5 py-4 flex items-center gap-3 font-semibold border-b" style={{ borderColor: "var(--sidebar-border, var(--color-secondary-200))", color: "var(--sidebar-active-color, var(--color-secondary-900))" }}>
|
|
232
232
|
{item.icon && <span style={{ color: "var(--sidebar-active-icon, #10b981)" }} className="text-xl drop-shadow-sm">{item.icon}</span>}
|
|
233
233
|
<ITText as="span" className="tracking-wide text-[15px]">{item.label}</ITText>
|
|
234
234
|
</div>
|
|
@@ -249,8 +249,8 @@ export default function ITSidebar({
|
|
|
249
249
|
}}
|
|
250
250
|
/>
|
|
251
251
|
)}
|
|
252
|
-
<span className={`w-1.5 h-1.5 rounded-full transition-all ${subitem.isActive ? "scale-125" : ""}`} style={{ backgroundColor: subitem.isActive ? "var(--sidebar-active-icon, #10b981)" : "var(--sidebar-icon-color,
|
|
253
|
-
<ITText as="span" style={{ color: subitem.isActive ? "var(--sidebar-active-color,
|
|
252
|
+
<span className={`w-1.5 h-1.5 rounded-full transition-all ${subitem.isActive ? "scale-125" : ""}`} style={{ backgroundColor: subitem.isActive ? "var(--sidebar-active-icon, #10b981)" : "var(--sidebar-icon-color, var(--color-secondary-400))" }} />
|
|
253
|
+
<ITText as="span" style={{ color: subitem.isActive ? "var(--sidebar-active-color, var(--color-secondary-900))" : "var(--sidebar-label-color, var(--color-secondary-600))", fontWeight: subitem.isActive ? 600 : 500 }}>{subitem.label}</ITText>
|
|
254
254
|
</div>
|
|
255
255
|
))}
|
|
256
256
|
</div>
|
|
@@ -267,7 +267,7 @@ export default function ITSidebar({
|
|
|
267
267
|
className="ml-5 flex flex-col gap-0.5 py-1"
|
|
268
268
|
style={{
|
|
269
269
|
borderLeft: subitemConnector === '|'
|
|
270
|
-
? "1px solid var(--sidebar-border,
|
|
270
|
+
? "1px solid var(--sidebar-border, var(--color-secondary-200))"
|
|
271
271
|
: 'none'
|
|
272
272
|
}}
|
|
273
273
|
>
|
|
@@ -280,8 +280,8 @@ export default function ITSidebar({
|
|
|
280
280
|
}}
|
|
281
281
|
className={`flex items-center gap-2.5 w-full text-left px-3 py-2 rounded-xl transition-all duration-300`}
|
|
282
282
|
style={{
|
|
283
|
-
color: subitem.isActive ? "var(--sidebar-active-color,
|
|
284
|
-
backgroundColor: subitem.isActive ? "var(--sidebar-active-bg,
|
|
283
|
+
color: subitem.isActive ? "var(--sidebar-active-color, var(--color-secondary-900))" : "var(--sidebar-label-color, var(--color-secondary-600))",
|
|
284
|
+
backgroundColor: subitem.isActive ? "var(--sidebar-active-bg, var(--color-secondary-50))" : 'transparent',
|
|
285
285
|
fontSize: '0.85rem',
|
|
286
286
|
fontWeight: subitem.isActive ? 600 : 500,
|
|
287
287
|
letterSpacing: '0.01em',
|
|
@@ -289,7 +289,7 @@ export default function ITSidebar({
|
|
|
289
289
|
}}
|
|
290
290
|
onMouseEnter={(e) => {
|
|
291
291
|
if (!subitem.isActive) {
|
|
292
|
-
e.currentTarget.style.backgroundColor = "var(--sidebar-hover-bg,
|
|
292
|
+
e.currentTarget.style.backgroundColor = "var(--sidebar-hover-bg, var(--color-secondary-100))";
|
|
293
293
|
e.currentTarget.style.transform = 'translateX(3px)';
|
|
294
294
|
}
|
|
295
295
|
}}
|
|
@@ -315,7 +315,7 @@ export default function ITSidebar({
|
|
|
315
315
|
style={{
|
|
316
316
|
backgroundColor: subitem.isActive
|
|
317
317
|
? "var(--sidebar-active-icon, #10b981)"
|
|
318
|
-
: "var(--sidebar-icon-color,
|
|
318
|
+
: "var(--sidebar-icon-color, var(--color-secondary-400))"
|
|
319
319
|
}}
|
|
320
320
|
/>
|
|
321
321
|
)}
|
|
@@ -2,9 +2,13 @@ import React from "react";
|
|
|
2
2
|
|
|
3
3
|
export type IconType = React.ReactNode;
|
|
4
4
|
|
|
5
|
+
/** A single step in an `ITStepper` flow. */
|
|
5
6
|
export interface Step {
|
|
7
|
+
/** Label shown next to the step indicator. */
|
|
6
8
|
label: string;
|
|
9
|
+
/** Content rendered in the panel while this step is active. */
|
|
7
10
|
content: React.ReactNode;
|
|
11
|
+
/** Custom icon shown in the step indicator when the stepper's `useIcons` is true. */
|
|
8
12
|
icon?: IconType;
|
|
9
13
|
}
|
|
10
14
|
|
|
@@ -1,31 +1,49 @@
|
|
|
1
1
|
import { TableSize, TableVariants } from "@/types/table.types";
|
|
2
2
|
|
|
3
|
+
/** Data type of a table column, controls default rendering, filter UI, and sort comparison. */
|
|
3
4
|
export type ColumnType = "string" | "date" | "number" | "boolean" | "actions" | "catalog";
|
|
4
5
|
|
|
6
|
+
/** A single selectable entry for a `"catalog"`-type column's filter/value lookup. */
|
|
5
7
|
export interface CatalogOption {
|
|
8
|
+
/** Unique identifier matched against the row's field value. */
|
|
6
9
|
id: string | number;
|
|
10
|
+
/** Human-readable label shown in the filter dropdown and resolved cell display. */
|
|
7
11
|
name: string;
|
|
8
12
|
}
|
|
9
13
|
|
|
14
|
+
/** Definition of a single column for ITTable. */
|
|
10
15
|
export interface Column<T = any> {
|
|
16
|
+
/** Field key on the row object this column reads from (supports dot-notation for nested values, e.g. `"address.city"`). */
|
|
11
17
|
key: string;
|
|
18
|
+
/** Column header text. */
|
|
12
19
|
label: string;
|
|
20
|
+
/** Additional CSS classes applied to both the header (`<th>`) and body (`<td>`) cells of this column. */
|
|
13
21
|
className?: string;
|
|
14
|
-
|
|
22
|
+
/** Formats numeric values as Mexican pesos (MXN) via `Intl`-based currency formatting. Only applies when `type` is `"number"`. @default false */
|
|
23
|
+
currencyMX?: boolean;
|
|
24
|
+
/** Custom action buttons/content rendered for a `"actions"`-type column. Receives the full row object. */
|
|
15
25
|
actions?: (row: T) => React.ReactNode;
|
|
26
|
+
/** Enables per-column filtering. Pass `true` for a text/number/boolean filter matching `type`, or `"catalog"` to filter against `catalogOptions`. @default false */
|
|
16
27
|
filter?: boolean | "catalog";
|
|
28
|
+
/** Column data type. Drives default cell rendering, filter UI, and sort comparison. */
|
|
17
29
|
type: ColumnType;
|
|
30
|
+
/** Whether clicking the header sorts by this column. Ignored for `type: "actions"`. @default false */
|
|
18
31
|
sortable?: boolean;
|
|
32
|
+
/** Custom cell renderer, takes precedence over the default type-based rendering. Receives the full row object. */
|
|
19
33
|
render?: (row: T) => React.ReactNode;
|
|
34
|
+
/** Custom inline-edit input renderer (used by table variants that support inline editing). */
|
|
20
35
|
editComponent?: (props: {
|
|
21
36
|
value: any;
|
|
22
37
|
onChange: (value: any) => void;
|
|
23
38
|
rowData: T;
|
|
24
39
|
}) => React.ReactNode;
|
|
25
|
-
|
|
40
|
+
/** Configuration for `type: "catalog"` columns: the lookup options plus loading/error state for async catalogs. */
|
|
26
41
|
catalogOptions?: {
|
|
42
|
+
/** Available catalog entries used to resolve/filter the raw id stored on the row. */
|
|
27
43
|
data: CatalogOption[];
|
|
44
|
+
/** Shows a loading spinner in the filter UI while the catalog is being fetched. @default false */
|
|
28
45
|
loading?: boolean;
|
|
46
|
+
/** Shows an error state in the filter UI when the catalog failed to load. @default false */
|
|
29
47
|
error?: boolean;
|
|
30
48
|
};
|
|
31
49
|
}
|
|
@@ -57,4 +75,4 @@ export interface ITTableProps<T> {
|
|
|
57
75
|
showVerticalBorder?: boolean;
|
|
58
76
|
/** Custom class for vertical borders (overrides the default subtle gray). */
|
|
59
77
|
verticalBorderClassname?: string;
|
|
60
|
-
}
|
|
78
|
+
}
|
|
@@ -15,6 +15,17 @@ import ITPagination from "../pagination/pagination";
|
|
|
15
15
|
import ITSelect from "../select/select";
|
|
16
16
|
import { Column, ITTableProps } from "./table.props";
|
|
17
17
|
import ITText from "@/components/text/text";
|
|
18
|
+
import {
|
|
19
|
+
tableActionsCell,
|
|
20
|
+
tableBody,
|
|
21
|
+
tableCell,
|
|
22
|
+
tableCellText,
|
|
23
|
+
tableContainer,
|
|
24
|
+
tableEmptyContent,
|
|
25
|
+
tableHeaderCell,
|
|
26
|
+
tableHeaderRow,
|
|
27
|
+
tableRow,
|
|
28
|
+
} from "@/utils/styles";
|
|
18
29
|
|
|
19
30
|
const getNestedValue = (obj: unknown, path: string) => {
|
|
20
31
|
return path.split(".").reduce((acc, part) => acc && acc[part], obj);
|
|
@@ -211,7 +222,7 @@ export default function ITTable<T extends Record<string, unknown>>({
|
|
|
211
222
|
}
|
|
212
223
|
|
|
213
224
|
if (col.catalogOptions.error) {
|
|
214
|
-
return <ITText as="span" className="text-
|
|
225
|
+
return <ITText as="span" className="text-danger-500 text-xs">Error cargando</ITText>;
|
|
215
226
|
}
|
|
216
227
|
|
|
217
228
|
return (
|
|
@@ -260,13 +271,13 @@ export default function ITTable<T extends Record<string, unknown>>({
|
|
|
260
271
|
case "boolean":
|
|
261
272
|
return value ? (
|
|
262
273
|
<FaCheck
|
|
263
|
-
className="text-
|
|
274
|
+
className="text-success-500"
|
|
264
275
|
aria-label="Verdadero"
|
|
265
276
|
title="Verdadero"
|
|
266
277
|
/>
|
|
267
278
|
) : (
|
|
268
279
|
<FaTimes
|
|
269
|
-
className="text-
|
|
280
|
+
className="text-danger-500"
|
|
270
281
|
aria-label="Falso"
|
|
271
282
|
title="Falso"
|
|
272
283
|
/>
|
|
@@ -312,7 +323,7 @@ export default function ITTable<T extends Record<string, unknown>>({
|
|
|
312
323
|
|
|
313
324
|
return (
|
|
314
325
|
<div className={clsx("space-y-4 w-full", containerClassName)}>
|
|
315
|
-
<div className=
|
|
326
|
+
<div className={tableContainer} style={{ backgroundColor: 'var(--color-table-rowBg, #ffffff)' }}>
|
|
316
327
|
{/* Header outside overflow */}
|
|
317
328
|
{title && (
|
|
318
329
|
<div className="px-6 py-5 flex items-center justify-between" style={{ backgroundColor: 'var(--color-table-rowBg, #ffffff)' }}>
|
|
@@ -382,7 +393,7 @@ export default function ITTable<T extends Record<string, unknown>>({
|
|
|
382
393
|
</div>
|
|
383
394
|
))
|
|
384
395
|
) : (
|
|
385
|
-
<div className="
|
|
396
|
+
<div className={clsx(tableEmptyContent, "py-12")}>
|
|
386
397
|
<ITText as="span" className="text-lg">No se encontraron resultados</ITText>
|
|
387
398
|
<ITText as="span" className="text-sm mt-1">Intenta ajustar los filtros</ITText>
|
|
388
399
|
</div>
|
|
@@ -400,12 +411,12 @@ export default function ITTable<T extends Record<string, unknown>>({
|
|
|
400
411
|
)}
|
|
401
412
|
>
|
|
402
413
|
<thead>
|
|
403
|
-
<tr className="
|
|
414
|
+
<tr className={clsx(tableHeaderRow, "dark:text-slate-200")}>
|
|
404
415
|
{columns.map((col) => (
|
|
405
416
|
<th
|
|
406
417
|
key={col.key}
|
|
407
418
|
scope="col"
|
|
408
|
-
className={
|
|
419
|
+
className={tableHeaderCell(col.className)}
|
|
409
420
|
>
|
|
410
421
|
<div className="flex flex-col gap-3 min-w-[150px]">
|
|
411
422
|
<div className="flex items-center justify-between gap-2">
|
|
@@ -431,24 +442,24 @@ export default function ITTable<T extends Record<string, unknown>>({
|
|
|
431
442
|
))}
|
|
432
443
|
</tr>
|
|
433
444
|
</thead>
|
|
434
|
-
<tbody className="
|
|
445
|
+
<tbody className={clsx(tableBody, "dark:divide-slate-700/30")}>
|
|
435
446
|
{currentData.length > 0 ? (
|
|
436
447
|
currentData.map((row, rowIndex) => (
|
|
437
448
|
<tr
|
|
438
449
|
key={rowIndex}
|
|
439
|
-
className={clsx(
|
|
450
|
+
className={clsx(tableRow, variant === "striped" && "odd:bg-secondary-50/40 dark:odd:bg-slate-800/20")}
|
|
440
451
|
>
|
|
441
452
|
{columns.map((col) => (
|
|
442
453
|
<td
|
|
443
454
|
key={`${rowIndex}-${col.key}`}
|
|
444
|
-
className={
|
|
455
|
+
className={tableCell(col.className)}
|
|
445
456
|
>
|
|
446
457
|
{col.type === "actions" ? (
|
|
447
|
-
<div className=
|
|
458
|
+
<div className={tableActionsCell}>
|
|
448
459
|
{renderCellContent(col, row) as React.ReactNode}
|
|
449
460
|
</div>
|
|
450
461
|
) : (
|
|
451
|
-
<div className=
|
|
462
|
+
<div className={tableCellText}>
|
|
452
463
|
{renderCellContent(col, row) as React.ReactNode}
|
|
453
464
|
</div>
|
|
454
465
|
)}
|
|
@@ -459,7 +470,7 @@ export default function ITTable<T extends Record<string, unknown>>({
|
|
|
459
470
|
) : (
|
|
460
471
|
<tr>
|
|
461
472
|
<td colSpan={columns.length} className="px-6 py-12 text-center">
|
|
462
|
-
<div className=
|
|
473
|
+
<div className={tableEmptyContent}>
|
|
463
474
|
<ITText as="span" className="text-lg">No se encontraron resultados</ITText>
|
|
464
475
|
<ITText as="span" className="text-sm mt-1">Intenta ajustar los filtros</ITText>
|
|
465
476
|
</div>
|
|
@@ -1,31 +1,49 @@
|
|
|
1
1
|
export interface ITThemePalette {
|
|
2
|
+
/** Main brand accent color (hex). Drives primary buttons, active nav items, focus rings, links, and the `--color-primary` CSS variable. @default "#06b6d4" */
|
|
2
3
|
primary: string;
|
|
4
|
+
/** Secondary/neutral accent color (hex). Used for less prominent actions and secondary badges/buttons. @default "#6b7280" */
|
|
3
5
|
secondary: string;
|
|
6
|
+
/** Tertiary accent color (hex), used for a third level of emphasis (e.g. alternate badges, chart accents). @default "#8b5cf6" */
|
|
4
7
|
ternary: string;
|
|
8
|
+
/** Semantic color for destructive/error states (hex): delete buttons, error badges, invalid form fields. @default "#ef4444" */
|
|
5
9
|
danger: string;
|
|
10
|
+
/** Semantic color for success/confirmation states (hex): success badges, completed steps, positive stats. @default "#22c55e" */
|
|
6
11
|
success: string;
|
|
12
|
+
/** Semantic color for informational states (hex): info banners/badges, neutral notices. @default "#3b82f6" */
|
|
7
13
|
info: string;
|
|
14
|
+
/** Semantic color for alert/caution states (hex), distinct from `warning`. Used by components that need a stronger visual cue than warning. @default "#f97316" */
|
|
8
15
|
alert: string;
|
|
16
|
+
/** Semantic color for warning states (hex): warning badges/banners, pending states. @default "#eab308" */
|
|
9
17
|
warning: string;
|
|
18
|
+
/** Colors for the app shell's sidebar and top navbar (ITSidebar, ITNavbar, ITTopbar, ITLayout). */
|
|
10
19
|
layout: {
|
|
20
|
+
/** Background color of the sidebar (hex). @default "#ffffff" */
|
|
11
21
|
sidebarBg: string;
|
|
22
|
+
/** Text/icon color used on the sidebar. @default "#334155" */
|
|
12
23
|
sidebarText: string;
|
|
24
|
+
/** Background color of the top navigation bar (hex). @default "#ffffff" */
|
|
13
25
|
navbarBg: string;
|
|
26
|
+
/** Text/icon color used on the top navigation bar. @default "#1e293b" */
|
|
14
27
|
navbarText: string;
|
|
15
28
|
};
|
|
29
|
+
/** Colors for ITTable/ITDataTable/ITSearchTable header and rows. */
|
|
16
30
|
table: {
|
|
31
|
+
/** Background color of the table header row (hex). @default "#f8fafc" */
|
|
17
32
|
headerBg: string;
|
|
33
|
+
/** Text color of the table header row. @default "#334155" */
|
|
18
34
|
headerText: string;
|
|
35
|
+
/** Background color of table body rows (hex). @default "#ffffff" */
|
|
19
36
|
rowBg: string;
|
|
37
|
+
/** Text color of table body rows. @default "#1e293b" */
|
|
20
38
|
rowText: string;
|
|
21
39
|
};
|
|
22
40
|
}
|
|
23
41
|
|
|
24
42
|
export interface ITThemeProviderProps {
|
|
25
|
-
/** Partial palette overrides merged with the default theme. Supports primary, secondary,
|
|
43
|
+
/** Partial palette overrides merged (deep merge) with the default theme. Supports primary, secondary, ternary, danger, success, info, alert, warning, layout, and table colors. Persisted to `localStorage` under `"it-theme-palette"` once the user edits it via the FAB/drawer. */
|
|
26
44
|
theme?: Partial<ITThemePalette>;
|
|
27
|
-
/** The subtree that receives the theme context and CSS variables. */
|
|
45
|
+
/** The subtree that receives the theme context and CSS variables. Must wrap your entire app (or the portion that uses AXZY UI System components) once, near the root. */
|
|
28
46
|
children: React.ReactNode;
|
|
29
|
-
/** Whether to
|
|
47
|
+
/** Whether to render the floating action button (bottom-right) that opens the live theme-designer drawer, letting end users tweak colors and persist their choice. Set to `false` to hide the FAB in production and only theme via the `theme` prop. @default true */
|
|
30
48
|
showFab?: boolean;
|
|
31
49
|
}
|
|
@@ -227,7 +227,7 @@ export default function ITTimePicker({
|
|
|
227
227
|
{isOpen && !disabled && (
|
|
228
228
|
<div
|
|
229
229
|
ref={dropdownRef}
|
|
230
|
-
className="fixed z-[
|
|
230
|
+
className="fixed z-[70] bg-white border border-gray-100 shadow-xl rounded-xl w-64 overflow-hidden flex flex-col animate-in fade-in zoom-in-95 duration-200 origin-top it-timepicker-dropdown"
|
|
231
231
|
style={{
|
|
232
232
|
top: `${dropdownPosition.top}px`,
|
|
233
233
|
left: `${dropdownPosition.left}px`,
|
|
@@ -80,7 +80,7 @@ export default function ITToast({
|
|
|
80
80
|
return (
|
|
81
81
|
<div
|
|
82
82
|
className={clsx(
|
|
83
|
-
"fixed z-
|
|
83
|
+
"fixed z-[80] p-4 rounded-xl shadow-xl flex items-center justify-between gap-4 transition-all duration-300 text-white min-w-[300px]",
|
|
84
84
|
positionStyles[position],
|
|
85
85
|
{
|
|
86
86
|
"opacity-100 translate-y-0 scale-100": isVisible,
|
|
@@ -62,7 +62,7 @@ export default function ITTooltip({
|
|
|
62
62
|
>
|
|
63
63
|
{children}
|
|
64
64
|
{visible && (
|
|
65
|
-
<div className={clsx("absolute z-[
|
|
65
|
+
<div className={clsx("absolute z-[70] pointer-events-none", positionClasses[position])}>
|
|
66
66
|
<div className="bg-slate-800 dark:bg-slate-700 text-white text-xs rounded-lg px-2.5 py-1.5 whitespace-nowrap shadow-lg">
|
|
67
67
|
<ITText as="span">{content}</ITText>
|
|
68
68
|
</div>
|
|
@@ -186,7 +186,7 @@ export default function ITTopBar({
|
|
|
186
186
|
<div
|
|
187
187
|
ref={userMenuRef}
|
|
188
188
|
className={`
|
|
189
|
-
absolute right-0 mt-3 w-64 rounded-2xl shadow-[0_10px_40px_-10px_rgba(0,0,0,0.15)] z-
|
|
189
|
+
absolute right-0 mt-3 w-64 rounded-2xl shadow-[0_10px_40px_-10px_rgba(0,0,0,0.15)] z-[70] overflow-hidden transform origin-top-right transition-all duration-200 ease-[cubic-bezier(0.2,0,0,1)]
|
|
190
190
|
${isUserMenuOpen ? "scale-100 opacity-100 translate-y-0" : "scale-95 opacity-0 -translate-y-2 pointer-events-none"}
|
|
191
191
|
`}
|
|
192
192
|
style={{
|
package/src/dev.css
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
@import "tailwindcss";
|
|
2
|
-
@import "./index.css";
|
|
2
|
+
@import "./index.css";
|
|
@@ -6,6 +6,14 @@ const useClickOutside = (
|
|
|
6
6
|
) => {
|
|
7
7
|
useEffect(() => {
|
|
8
8
|
const handleClickOutside = (event: MouseEvent) => {
|
|
9
|
+
const target = event.target as Element | null;
|
|
10
|
+
const clickedDialog = target?.closest("[data-it-dialog]");
|
|
11
|
+
const currentDialog = ref.current?.closest("[data-it-dialog]");
|
|
12
|
+
|
|
13
|
+
// Nested dialogs must not close their parent when interacting with the
|
|
14
|
+
// child overlay or its contents.
|
|
15
|
+
if (clickedDialog && clickedDialog !== currentDialog) return;
|
|
16
|
+
|
|
9
17
|
if (ref.current && !ref.current.contains(event.target as Node)) {
|
|
10
18
|
callback();
|
|
11
19
|
}
|
|
@@ -42,11 +42,14 @@ export function useTableState({
|
|
|
42
42
|
|
|
43
43
|
const goToPage = useCallback(
|
|
44
44
|
(page: number) => {
|
|
45
|
-
|
|
45
|
+
// No limitar contra `totalPages`: ese estado vive en useTableState y
|
|
46
|
+
// nunca se sincroniza con el total real (ITDataTable calcula el suyo).
|
|
47
|
+
// ITPagination ya deshabilita la navegación más allá de la última página.
|
|
48
|
+
if (page >= 1) {
|
|
46
49
|
setCurrentPage(page);
|
|
47
50
|
}
|
|
48
51
|
},
|
|
49
|
-
[
|
|
52
|
+
[]
|
|
50
53
|
);
|
|
51
54
|
|
|
52
55
|
const handleItemsPerPageChange = useCallback((value: number) => {
|