@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
|
@@ -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
|
}
|
|
@@ -799,23 +799,23 @@ export default function ITThemeProvider({
|
|
|
799
799
|
color: #cbd5e1;
|
|
800
800
|
}
|
|
801
801
|
.dark .text-slate-800, [data-theme="dark"] .text-slate-800,
|
|
802
|
-
.dark .text-
|
|
802
|
+
.dark .text-secondary-800, [data-theme="dark"] .text-secondary-800 {
|
|
803
803
|
color: #f8fafc !important;
|
|
804
804
|
}
|
|
805
805
|
.dark .text-slate-700, [data-theme="dark"] .text-slate-700,
|
|
806
|
-
.dark .text-
|
|
806
|
+
.dark .text-secondary-700, [data-theme="dark"] .text-secondary-700 {
|
|
807
807
|
color: #cbd5e1 !important;
|
|
808
808
|
}
|
|
809
809
|
.dark .text-slate-600, [data-theme="dark"] .text-slate-600,
|
|
810
|
-
.dark .text-
|
|
810
|
+
.dark .text-secondary-600, [data-theme="dark"] .text-secondary-600 {
|
|
811
811
|
color: #cbd5e1 !important;
|
|
812
812
|
}
|
|
813
813
|
.dark .text-slate-500, [data-theme="dark"] .text-slate-500,
|
|
814
|
-
.dark .text-
|
|
814
|
+
.dark .text-secondary-500, [data-theme="dark"] .text-secondary-500 {
|
|
815
815
|
color: #94a3b8 !important;
|
|
816
816
|
}
|
|
817
817
|
.dark .text-slate-400, [data-theme="dark"] .text-slate-400,
|
|
818
|
-
.dark .text-
|
|
818
|
+
.dark .text-secondary-400, [data-theme="dark"] .text-secondary-400 {
|
|
819
819
|
color: #64748b !important;
|
|
820
820
|
}
|
|
821
821
|
|
|
@@ -823,25 +823,25 @@ export default function ITThemeProvider({
|
|
|
823
823
|
background-color: var(--card-bg, #111827) !important;
|
|
824
824
|
}
|
|
825
825
|
.dark .bg-slate-50, [data-theme="dark"] .bg-slate-50,
|
|
826
|
-
.dark .bg-
|
|
826
|
+
.dark .bg-secondary-50, [data-theme="dark"] .bg-secondary-50 {
|
|
827
827
|
background-color: #1f2937 !important;
|
|
828
828
|
}
|
|
829
829
|
.dark .border-slate-100, [data-theme="dark"] .border-slate-100,
|
|
830
|
-
.dark .border-
|
|
830
|
+
.dark .border-secondary-100, [data-theme="dark"] .border-secondary-100,
|
|
831
831
|
.dark .border-slate-200, [data-theme="dark"] .border-slate-200,
|
|
832
|
-
.dark .border-
|
|
832
|
+
.dark .border-secondary-200, [data-theme="dark"] .border-secondary-200 {
|
|
833
833
|
border-color: #374151 !important;
|
|
834
834
|
}
|
|
835
835
|
|
|
836
|
-
.dark .bg-
|
|
836
|
+
.dark .bg-secondary-100, [data-theme="dark"] .bg-secondary-100,
|
|
837
837
|
.dark .bg-slate-100, [data-theme="dark"] .bg-slate-100 {
|
|
838
838
|
background-color: #1f2937 !important;
|
|
839
839
|
}
|
|
840
|
-
.dark .border-
|
|
840
|
+
.dark .border-secondary-300, [data-theme="dark"] .border-secondary-300,
|
|
841
841
|
.dark .border-slate-300, [data-theme="dark"] .border-slate-300 {
|
|
842
842
|
border-color: #4b5563 !important;
|
|
843
843
|
}
|
|
844
|
-
.dark .bg-
|
|
844
|
+
.dark .bg-secondary-200, [data-theme="dark"] .bg-secondary-200,
|
|
845
845
|
.dark .bg-slate-200, [data-theme="dark"] .bg-slate-200 {
|
|
846
846
|
background-color: #374151 !important;
|
|
847
847
|
}
|
|
@@ -909,23 +909,23 @@ export default function ITThemeProvider({
|
|
|
909
909
|
}
|
|
910
910
|
|
|
911
911
|
[data-theme="light"] .text-slate-800,
|
|
912
|
-
[data-theme="light"] .text-
|
|
912
|
+
[data-theme="light"] .text-secondary-800 {
|
|
913
913
|
color: #1e293b !important;
|
|
914
914
|
}
|
|
915
915
|
[data-theme="light"] .text-slate-700,
|
|
916
|
-
[data-theme="light"] .text-
|
|
916
|
+
[data-theme="light"] .text-secondary-700 {
|
|
917
917
|
color: #334155 !important;
|
|
918
918
|
}
|
|
919
919
|
[data-theme="light"] .text-slate-600,
|
|
920
|
-
[data-theme="light"] .text-
|
|
920
|
+
[data-theme="light"] .text-secondary-600 {
|
|
921
921
|
color: #475569 !important;
|
|
922
922
|
}
|
|
923
923
|
[data-theme="light"] .text-slate-500,
|
|
924
|
-
[data-theme="light"] .text-
|
|
924
|
+
[data-theme="light"] .text-secondary-500 {
|
|
925
925
|
color: #64748b !important;
|
|
926
926
|
}
|
|
927
927
|
[data-theme="light"] .text-slate-400,
|
|
928
|
-
[data-theme="light"] .text-
|
|
928
|
+
[data-theme="light"] .text-secondary-400 {
|
|
929
929
|
color: #94a3b8 !important;
|
|
930
930
|
}
|
|
931
931
|
|
|
@@ -933,24 +933,24 @@ export default function ITThemeProvider({
|
|
|
933
933
|
background-color: #ffffff !important;
|
|
934
934
|
}
|
|
935
935
|
[data-theme="light"] .bg-slate-50,
|
|
936
|
-
[data-theme="light"] .bg-
|
|
936
|
+
[data-theme="light"] .bg-secondary-50 {
|
|
937
937
|
background-color: #f8fafc !important;
|
|
938
938
|
}
|
|
939
939
|
[data-theme="light"] .border-slate-100,
|
|
940
|
-
[data-theme="light"] .border-
|
|
940
|
+
[data-theme="light"] .border-secondary-100,
|
|
941
941
|
[data-theme="light"] .border-slate-200,
|
|
942
|
-
[data-theme="light"] .border-
|
|
942
|
+
[data-theme="light"] .border-secondary-200 {
|
|
943
943
|
border-color: #e2e8f0 !important;
|
|
944
944
|
}
|
|
945
|
-
[data-theme="light"] .bg-
|
|
945
|
+
[data-theme="light"] .bg-secondary-100,
|
|
946
946
|
[data-theme="light"] .bg-slate-100 {
|
|
947
947
|
background-color: #f1f5f9 !important;
|
|
948
948
|
}
|
|
949
|
-
[data-theme="light"] .border-
|
|
949
|
+
[data-theme="light"] .border-secondary-300,
|
|
950
950
|
[data-theme="light"] .border-slate-300 {
|
|
951
951
|
border-color: #cbd5e1 !important;
|
|
952
952
|
}
|
|
953
|
-
[data-theme="light"] .bg-
|
|
953
|
+
[data-theme="light"] .bg-secondary-200,
|
|
954
954
|
[data-theme="light"] .bg-slate-200 {
|
|
955
955
|
background-color: #e2e8f0 !important;
|
|
956
956
|
}
|
|
@@ -978,13 +978,13 @@ export default function ITThemeProvider({
|
|
|
978
978
|
.hover\\:bg-green-600:hover { background-color: var(--color-success-hover) !important; }
|
|
979
979
|
|
|
980
980
|
/* Danger overrides (red mappings in UI library) */
|
|
981
|
-
.bg-
|
|
982
|
-
.hover\\:bg-
|
|
983
|
-
.focus\\:ring-
|
|
984
|
-
.text-
|
|
985
|
-
.border-
|
|
986
|
-
.bg-
|
|
987
|
-
.hover\\:bg-
|
|
981
|
+
.bg-danger-700 { background-color: var(--color-danger) !important; }
|
|
982
|
+
.hover\\:bg-danger-800:hover { background-color: var(--color-danger-hover) !important; }
|
|
983
|
+
.focus\\:ring-danger-300:focus { --tw-ring-color: var(--color-danger-ring) !important; }
|
|
984
|
+
.text-danger-700 { color: var(--color-danger) !important; }
|
|
985
|
+
.border-danger-700 { border-color: var(--color-danger) !important; }
|
|
986
|
+
.bg-danger-500 { background-color: var(--color-danger) !important; }
|
|
987
|
+
.hover\\:bg-danger-600:hover { background-color: var(--color-danger-hover) !important; }
|
|
988
988
|
|
|
989
989
|
/* Warning overrides (yellow mappings in UI library) */
|
|
990
990
|
.bg-yellow-400 { background-color: var(--color-warning) !important; }
|
|
@@ -1014,12 +1014,12 @@ export default function ITThemeProvider({
|
|
|
1014
1014
|
.border-blue-500 { border-color: var(--color-info) !important; }
|
|
1015
1015
|
|
|
1016
1016
|
/* Secondary elements overrides */
|
|
1017
|
-
button[class*="bg-white"][class*="hover:bg-
|
|
1017
|
+
button[class*="bg-white"][class*="hover:bg-secondary-100"] {
|
|
1018
1018
|
background-color: var(--color-secondary) !important;
|
|
1019
1019
|
border-color: var(--color-secondary-soft-border) !important;
|
|
1020
1020
|
color: #111827 !important;
|
|
1021
1021
|
}
|
|
1022
|
-
button[class*="bg-white"][class*="hover:bg-
|
|
1022
|
+
button[class*="bg-white"][class*="hover:bg-secondary-100"]:hover {
|
|
1023
1023
|
background-color: var(--color-secondary-hover) !important;
|
|
1024
1024
|
}
|
|
1025
1025
|
|
|
@@ -1625,7 +1625,7 @@ export default function ITThemeProvider({
|
|
|
1625
1625
|
e.stopPropagation();
|
|
1626
1626
|
handleDeletePreset(preset.name, e);
|
|
1627
1627
|
}}
|
|
1628
|
-
className="absolute top-1.5 right-1.5 opacity-0 group-hover:opacity-100 p-0.5 rounded-md hover:bg-
|
|
1628
|
+
className="absolute top-1.5 right-1.5 opacity-0 group-hover:opacity-100 p-0.5 rounded-md hover:bg-danger-500/10 hover:text-danger-500 text-slate-400 dark:text-slate-500 cursor-pointer transition-all z-10"
|
|
1629
1629
|
title="Eliminar"
|
|
1630
1630
|
>
|
|
1631
1631
|
<MdClose size={12} />
|
|
@@ -227,14 +227,14 @@ 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-secondary-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`,
|
|
234
234
|
}}
|
|
235
235
|
>
|
|
236
|
-
<div className="flex bg-
|
|
237
|
-
<ITText as="div" className="flex-1 text-center py-2 border-r border-
|
|
236
|
+
<div className="flex bg-secondary-50 border-b border-secondary-100 text-xs font-semibold text-secondary-500 uppercase tracking-wider">
|
|
237
|
+
<ITText as="div" className="flex-1 text-center py-2 border-r border-secondary-100">
|
|
238
238
|
Horas
|
|
239
239
|
</ITText>
|
|
240
240
|
<ITText as="div" className="flex-1 text-center py-2">Minutos</ITText>
|
|
@@ -244,7 +244,7 @@ export default function ITTimePicker({
|
|
|
244
244
|
{/* Hours Column */}
|
|
245
245
|
<div
|
|
246
246
|
ref={hoursRef}
|
|
247
|
-
className="flex-1 overflow-y-auto no-scrollbar border-r border-
|
|
247
|
+
className="flex-1 overflow-y-auto no-scrollbar border-r border-secondary-50 scroll-smooth relative"
|
|
248
248
|
>
|
|
249
249
|
<div className="py-2">
|
|
250
250
|
{hoursList.map((h) => {
|
|
@@ -321,7 +321,7 @@ export default function ITTimePicker({
|
|
|
321
321
|
<div className="absolute top-1/2 left-0 right-0 h-10 -mt-5 bg-black/5 pointer-events-none border-y border-black/10 z-10" />
|
|
322
322
|
</div>
|
|
323
323
|
|
|
324
|
-
<div className="p-3 bg-
|
|
324
|
+
<div className="p-3 bg-secondary-50 border-t border-secondary-100 flex justify-end">
|
|
325
325
|
<ITButton
|
|
326
326
|
variant="solid"
|
|
327
327
|
color={color as any}
|
|
@@ -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>
|
|
@@ -61,8 +61,8 @@ export default function ITTopBar({
|
|
|
61
61
|
className="sticky top-0 z-40 backdrop-blur-md transition-all duration-300"
|
|
62
62
|
style={{
|
|
63
63
|
backgroundColor: "var(--topbar-bg, rgba(255, 255, 255, 0.9))",
|
|
64
|
-
borderBottom: "1px solid var(--topbar-border,
|
|
65
|
-
boxShadow: "
|
|
64
|
+
borderBottom: "1px solid var(--topbar-border, rgba(15, 23, 42, 0.06))",
|
|
65
|
+
boxShadow: "var(--shadow-xs)",
|
|
66
66
|
}}
|
|
67
67
|
>
|
|
68
68
|
<div className="flex items-center justify-between h-[72px] px-6 lg:px-8">
|
|
@@ -105,7 +105,7 @@ export default function ITTopBar({
|
|
|
105
105
|
|
|
106
106
|
{/* Top Navigation Items (Desktop) */}
|
|
107
107
|
{navItems && navItems.length > 0 && (
|
|
108
|
-
<nav className="hidden md:flex ml-8 space-x-1 border-l pl-8" style={{ borderColor: "var(--topbar-border,
|
|
108
|
+
<nav className="hidden md:flex ml-8 space-x-1 border-l pl-8" style={{ borderColor: "var(--topbar-border, rgba(15, 23, 42, 0.06))" }}>
|
|
109
109
|
{navItems.map((item) => (
|
|
110
110
|
<button
|
|
111
111
|
key={item.id}
|
|
@@ -136,7 +136,7 @@ export default function ITTopBar({
|
|
|
136
136
|
<div className="relative">
|
|
137
137
|
<button
|
|
138
138
|
type="button"
|
|
139
|
-
className="flex items-center gap-3 rounded-full pl-2 pr-4 py-1.5 transition-all duration-200 ease-[cubic-bezier(0.2,0,0,1)] border border-transparent hover:border-
|
|
139
|
+
className="flex items-center gap-3 rounded-full pl-2 pr-4 py-1.5 transition-all duration-200 ease-[cubic-bezier(0.2,0,0,1)] border border-transparent hover:border-secondary-200"
|
|
140
140
|
style={{
|
|
141
141
|
backgroundColor: isUserMenuOpen ? "var(--topbar-user-hover, #f1f5f9)" : "transparent",
|
|
142
142
|
}}
|
|
@@ -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={{
|
|
@@ -220,9 +220,9 @@ export default function ITTopBar({
|
|
|
220
220
|
setIsUserMenuOpen(false);
|
|
221
221
|
}}
|
|
222
222
|
className="block w-full text-left px-3 py-2.5 rounded-xl text-[0.875rem] font-medium transition-colors duration-150"
|
|
223
|
-
style={{ color: isDestructive ? '
|
|
223
|
+
style={{ color: isDestructive ? 'var(--color-danger-500)' : "var(--topbar-user-text, #334155)" }}
|
|
224
224
|
onMouseEnter={(e) => {
|
|
225
|
-
e.currentTarget.style.backgroundColor = isDestructive ? '
|
|
225
|
+
e.currentTarget.style.backgroundColor = isDestructive ? 'var(--color-danger-50)' : "var(--topbar-user-item-hover, #f8fafc)";
|
|
226
226
|
}}
|
|
227
227
|
onMouseLeave={(e) => {
|
|
228
228
|
e.currentTarget.style.backgroundColor = "transparent";
|
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) => {
|
package/src/index.css
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
|
|
6
6
|
@variant dark (&:is(.dark &));
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
@theme {
|
|
9
9
|
--animate-fadeIn: fadeIn 0.5s ease-out forwards;
|
|
10
10
|
--animate-fade-in: fadeIn 0.5s ease-out forwards;
|
|
11
11
|
|
|
@@ -94,6 +94,29 @@
|
|
|
94
94
|
--color-info-800: #075985;
|
|
95
95
|
--color-info-900: #0c4a6e;
|
|
96
96
|
--color-info-950: #082f49;
|
|
97
|
+
|
|
98
|
+
/* Soft-depth radius scale: larger, more consistent rounding across the system */
|
|
99
|
+
--radius-xs: 0.25rem;
|
|
100
|
+
--radius-sm: 0.375rem;
|
|
101
|
+
--radius-md: 0.625rem;
|
|
102
|
+
--radius-lg: 0.875rem;
|
|
103
|
+
--radius-xl: 1.125rem;
|
|
104
|
+
--radius-2xl: 1.5rem;
|
|
105
|
+
--radius-3xl: 2rem;
|
|
106
|
+
|
|
107
|
+
/* Soft-depth shadow scale: cool slate-tinted, low-opacity, multi-layer.
|
|
108
|
+
Overrides Tailwind's default shadow-* tokens system-wide so every
|
|
109
|
+
existing shadow-* usage picks up the new "floating" look with no
|
|
110
|
+
per-component changes. */
|
|
111
|
+
--shadow-2xs: 0 1px 2px 0 rgb(15 23 42 / 0.04);
|
|
112
|
+
--shadow-xs: 0 1px 3px 0 rgb(15 23 42 / 0.05), 0 1px 2px -1px rgb(15 23 42 / 0.04);
|
|
113
|
+
--shadow-sm: 0 2px 6px -1px rgb(15 23 42 / 0.06), 0 1px 3px -1px rgb(15 23 42 / 0.05);
|
|
114
|
+
--shadow-md: 0 6px 16px -4px rgb(15 23 42 / 0.08), 0 3px 6px -3px rgb(15 23 42 / 0.05);
|
|
115
|
+
--shadow-lg: 0 12px 28px -6px rgb(15 23 42 / 0.1), 0 6px 12px -6px rgb(15 23 42 / 0.06);
|
|
116
|
+
--shadow-xl: 0 20px 40px -8px rgb(15 23 42 / 0.12), 0 10px 20px -8px rgb(15 23 42 / 0.06);
|
|
117
|
+
--shadow-2xl: 0 32px 64px -16px rgb(15 23 42 / 0.18);
|
|
118
|
+
--shadow: 0 2px 6px -1px rgb(15 23 42 / 0.06), 0 1px 3px -1px rgb(15 23 42 / 0.05);
|
|
119
|
+
--shadow-inner: inset 0 2px 4px 0 rgb(15 23 42 / 0.04);
|
|
97
120
|
}
|
|
98
121
|
|
|
99
122
|
@keyframes fadeIn {
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { useState } from "react";
|
|
2
|
-
import { FaCloud, FaCode, FaDatabase, FaDownload, FaGithub, FaLayerGroup, FaLinkedin, FaMapMarkerAlt, FaMobileAlt, FaSearch, FaServer, FaMedium } from "react-icons/fa";
|
|
2
|
+
import { FaArrowRight, FaCheck, FaCloud, FaCode, FaDatabase, FaDownload, FaExternalLinkAlt, FaGithub, FaLayerGroup, FaLinkedin, FaMapMarkerAlt, FaMobileAlt, FaSearch, FaServer, FaMedium } from "react-icons/fa";
|
|
3
|
+
import { SiReact, SiNodedotjs } from "react-icons/si";
|
|
3
4
|
import ITBadget from "../components/badget/badget";
|
|
4
5
|
import ITButton from "../components/button/button";
|
|
5
6
|
import ITCard from "../components/card/card";
|
|
@@ -94,7 +95,7 @@ export const HomeShowcase = () => {
|
|
|
94
95
|
<div className="w-56 h-56 md:w-64 md:h-64 rounded-full shadow-xl overflow-hidden ring-2 ring-slate-200 dark:ring-slate-700">
|
|
95
96
|
<img
|
|
96
97
|
src="/personalFoto.jpg"
|
|
97
|
-
alt="Asael
|
|
98
|
+
alt="Asael Amaro"
|
|
98
99
|
className="w-full h-full object-cover"
|
|
99
100
|
/>
|
|
100
101
|
</div>
|
|
@@ -109,7 +110,7 @@ export const HomeShowcase = () => {
|
|
|
109
110
|
<ITStack spacing={2}>
|
|
110
111
|
<ITBadget label="Portafolio Personal" color="primary" variant="outlined" className="w-fit" />
|
|
111
112
|
<ITText as="h1" className="text-4xl md:text-5xl font-bold tracking-tight text-slate-900 dark:text-white">
|
|
112
|
-
Hola, soy <span className="text-primary-600 dark:text-primary-400">Asael
|
|
113
|
+
Hola, soy <span className="text-primary-600 dark:text-primary-400">Asael Amaro</span>
|
|
113
114
|
</ITText>
|
|
114
115
|
<ITText as="p" muted className="text-base leading-relaxed max-w-xl">
|
|
115
116
|
Fullstack Developer con 4+ años de experiencia creando aplicaciones web modernas.
|
|
@@ -299,6 +300,97 @@ export const HomeShowcase = () => {
|
|
|
299
300
|
</ITText>
|
|
300
301
|
</ITStack>
|
|
301
302
|
</ITCard>
|
|
303
|
+
|
|
304
|
+
{/* ─── MIS PRODUCTOS ─── */}
|
|
305
|
+
<ITCard
|
|
306
|
+
title="Mis Productos"
|
|
307
|
+
className="border-slate-200/60 dark:border-slate-800/60 shadow-sm"
|
|
308
|
+
>
|
|
309
|
+
<ITText as="p" muted className="!text-sm !mb-4">
|
|
310
|
+
Productos destacados que he construido.
|
|
311
|
+
</ITText>
|
|
312
|
+
<ITGrid container spacing={5}>
|
|
313
|
+
{/* AXZY UI System */}
|
|
314
|
+
<ITGrid item xs={12} md={6}>
|
|
315
|
+
<a
|
|
316
|
+
href="#ui-system"
|
|
317
|
+
className="group block h-full rounded-2xl border border-slate-200 dark:border-slate-800 bg-white dark:bg-slate-900/50 p-6 hover:border-primary-400/40 hover:shadow-lg hover:-translate-y-1 transition-all duration-200"
|
|
318
|
+
>
|
|
319
|
+
<ITStack spacing={4} className="h-full" justifyContent="between">
|
|
320
|
+
<ITStack spacing={3}>
|
|
321
|
+
<ITFlex align="center" justify="between">
|
|
322
|
+
<div className="w-12 h-12 rounded-xl bg-gradient-to-br from-primary-500 to-purple-500 text-white flex items-center justify-center shadow-md">
|
|
323
|
+
<FaLayerGroup size={20} />
|
|
324
|
+
</div>
|
|
325
|
+
<ITBadget label="Propio" color="primary" variant="filled" />
|
|
326
|
+
</ITFlex>
|
|
327
|
+
<div>
|
|
328
|
+
<ITText as="h3" className="!text-lg !font-bold flex items-center gap-2">
|
|
329
|
+
AXZY UI System
|
|
330
|
+
<FaArrowRight size={14} className="text-primary-500 opacity-0 -translate-x-1 group-hover:opacity-100 group-hover:translate-x-0 transition-all duration-200" />
|
|
331
|
+
</ITText>
|
|
332
|
+
<ITText as="p" muted className="!text-sm !leading-relaxed mt-1.5">
|
|
333
|
+
Librería de componentes React con Tailwind CSS v4. Más de 50
|
|
334
|
+
componentes enterprise con theming en runtime, TypeScript nativo y
|
|
335
|
+
accesibilidad.
|
|
336
|
+
</ITText>
|
|
337
|
+
</div>
|
|
338
|
+
<ITFlex gap={2} wrap="wrap">
|
|
339
|
+
<ITBadget label="React" color="gray" variant="outlined" />
|
|
340
|
+
<ITBadget label="TypeScript" color="gray" variant="outlined" />
|
|
341
|
+
<ITBadget label="Tailwind" color="gray" variant="outlined" />
|
|
342
|
+
<ITBadget label="npm" color="gray" variant="outlined" />
|
|
343
|
+
</ITFlex>
|
|
344
|
+
</ITStack>
|
|
345
|
+
<ITText as="span" className="!text-xs !font-semibold !text-primary-600 dark:!text-primary-400 inline-flex items-center gap-1.5">
|
|
346
|
+
<SiReact size={12} />
|
|
347
|
+
Ver proyecto
|
|
348
|
+
</ITText>
|
|
349
|
+
</ITStack>
|
|
350
|
+
</a>
|
|
351
|
+
</ITGrid>
|
|
352
|
+
|
|
353
|
+
{/* CheckApp */}
|
|
354
|
+
<ITGrid item xs={12} md={6}>
|
|
355
|
+
<a
|
|
356
|
+
href="https://checkapp.axzy.dev/"
|
|
357
|
+
target="_blank"
|
|
358
|
+
rel="noopener noreferrer"
|
|
359
|
+
className="group block h-full rounded-2xl border border-slate-200 dark:border-slate-800 bg-white dark:bg-slate-900/50 p-6 hover:border-emerald-400/40 hover:shadow-lg hover:-translate-y-1 transition-all duration-200"
|
|
360
|
+
>
|
|
361
|
+
<ITStack spacing={4} className="h-full" justifyContent="between">
|
|
362
|
+
<ITStack spacing={3}>
|
|
363
|
+
<ITFlex align="center" justify="between">
|
|
364
|
+
<div className="w-12 h-12 rounded-xl bg-gradient-to-br from-emerald-500 to-cyan-500 text-white flex items-center justify-center shadow-md">
|
|
365
|
+
<FaCheck size={20} />
|
|
366
|
+
</div>
|
|
367
|
+
<ITBadget label="En vivo" color="gray" variant="outlined" />
|
|
368
|
+
</ITFlex>
|
|
369
|
+
<div>
|
|
370
|
+
<ITText as="h3" className="!text-lg !font-bold flex items-center gap-2">
|
|
371
|
+
CheckApp
|
|
372
|
+
<FaExternalLinkAlt size={12} className="text-slate-400 opacity-0 -translate-x-1 group-hover:opacity-100 group-hover:translate-x-0 transition-all duration-200" />
|
|
373
|
+
</ITText>
|
|
374
|
+
<ITText as="p" muted className="!text-sm !leading-relaxed mt-1.5">
|
|
375
|
+
Aplicación web para consultar información de manera rápida y
|
|
376
|
+
sencilla. Desplegada y disponible en línea.
|
|
377
|
+
</ITText>
|
|
378
|
+
</div>
|
|
379
|
+
<ITFlex gap={2} wrap="wrap">
|
|
380
|
+
<ITBadget label="Node.js" color="gray" variant="outlined" />
|
|
381
|
+
<ITBadget label="React" color="gray" variant="outlined" />
|
|
382
|
+
<ITBadget label="Deploy" color="gray" variant="outlined" />
|
|
383
|
+
</ITFlex>
|
|
384
|
+
</ITStack>
|
|
385
|
+
<ITText as="span" className="!text-xs !font-semibold !text-emerald-600 dark:!text-emerald-400 inline-flex items-center gap-1.5">
|
|
386
|
+
<SiNodedotjs size={12} />
|
|
387
|
+
Abrir CheckApp
|
|
388
|
+
</ITText>
|
|
389
|
+
</ITStack>
|
|
390
|
+
</a>
|
|
391
|
+
</ITGrid>
|
|
392
|
+
</ITGrid>
|
|
393
|
+
</ITCard>
|
|
302
394
|
</ITStack>
|
|
303
395
|
);
|
|
304
396
|
};
|