@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.
Files changed (66) hide show
  1. package/README.md +6 -0
  2. package/dist/index.cjs +313 -242
  3. package/dist/index.cjs.map +1 -1
  4. package/dist/index.css +1 -1
  5. package/dist/index.css.map +1 -1
  6. package/dist/index.d.cts +142 -6
  7. package/dist/index.d.ts +142 -6
  8. package/dist/index.js +313 -242
  9. package/dist/index.js.map +1 -1
  10. package/package.json +4 -3
  11. package/snippets/axzy-ui-system.code-snippets +547 -0
  12. package/src/App.tsx +37 -34
  13. package/src/components/avatar/avatar.props.ts +12 -1
  14. package/src/components/avatar/avatar.stories.tsx +19 -0
  15. package/src/components/avatar/avatar.tsx +27 -4
  16. package/src/components/calendar/calendar.tsx +1 -1
  17. package/src/components/card/card.tsx +11 -8
  18. package/src/components/confirm-dialog/confirm-dialog.tsx +1 -1
  19. package/src/components/data-table/dataTable.props.ts +10 -0
  20. package/src/components/data-table/dataTable.tsx +27 -16
  21. package/src/components/date-picker/datePicker.tsx +1 -1
  22. package/src/components/dialog/dialog.tsx +3 -2
  23. package/src/components/divider/divider.tsx +1 -1
  24. package/src/components/drawer/drawer.tsx +1 -1
  25. package/src/components/dropfile/dropfile.props.ts +6 -0
  26. package/src/components/dropfile/dropfile.tsx +65 -30
  27. package/src/components/form-builder/fieldRenderer.tsx +3 -3
  28. package/src/components/input/input.tsx +7 -7
  29. package/src/components/layout/layout.tsx +1 -1
  30. package/src/components/loader/loader.tsx +1 -1
  31. package/src/components/navbar/navbar.tsx +10 -10
  32. package/src/components/pagination/pagination.tsx +11 -11
  33. package/src/components/popover/popover.tsx +1 -1
  34. package/src/components/search-select/search-select.tsx +11 -11
  35. package/src/components/searchTable/components/EditableCell.tsx +1 -1
  36. package/src/components/searchTable/components/PaginationControls.tsx +2 -2
  37. package/src/components/searchTable/components/PaginationInfo.tsx +1 -1
  38. package/src/components/searchTable/components/SearchAndSortBar.tsx +1 -1
  39. package/src/components/searchTable/components/SearchInput.tsx +1 -1
  40. package/src/components/searchTable/components/SortButton.tsx +3 -3
  41. package/src/components/searchTable/components/TableHeader.tsx +1 -1
  42. package/src/components/searchTable/components/TableRow.tsx +4 -4
  43. package/src/components/searchTable/searchTable.tsx +2 -2
  44. package/src/components/select/select.tsx +8 -10
  45. package/src/components/sidebar/sidebar.tsx +29 -29
  46. package/src/components/slider/slider.tsx +3 -3
  47. package/src/components/stepper/stepper.props.ts +4 -0
  48. package/src/components/stepper/stepper.tsx +5 -5
  49. package/src/components/table/table.props.ts +21 -3
  50. package/src/components/table/table.tsx +27 -16
  51. package/src/components/tabs/tabs.tsx +4 -4
  52. package/src/components/textarea/textarea.tsx +3 -3
  53. package/src/components/theme-provider/themeProvider.props.ts +21 -3
  54. package/src/components/theme-provider/themeProvider.tsx +32 -32
  55. package/src/components/time-picker/timePicker.tsx +5 -5
  56. package/src/components/toast/toast.tsx +1 -1
  57. package/src/components/tooltip/tooltip.tsx +1 -1
  58. package/src/components/topbar/topbar.tsx +7 -7
  59. package/src/dev.css +1 -1
  60. package/src/hooks/useClickOutside.ts +8 -0
  61. package/src/hooks/useTableState.ts +5 -2
  62. package/src/index.css +24 -1
  63. package/src/showcases/HomeShowcase.tsx +95 -3
  64. package/src/theme/theme.ts +38 -17
  65. package/src/types/field.types.ts +70 -7
  66. 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, tertiary, danger, success, info, alert, warning, layout, and table colors. */
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 show the floating action button for opening the theme designer drawer. */
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-gray-800, [data-theme="dark"] .text-gray-800 {
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-gray-700, [data-theme="dark"] .text-gray-700 {
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-gray-600, [data-theme="dark"] .text-gray-600 {
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-gray-500, [data-theme="dark"] .text-gray-500 {
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-gray-400, [data-theme="dark"] .text-gray-400 {
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-gray-50, [data-theme="dark"] .bg-gray-50 {
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-gray-100, [data-theme="dark"] .border-gray-100,
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-gray-200, [data-theme="dark"] .border-gray-200 {
832
+ .dark .border-secondary-200, [data-theme="dark"] .border-secondary-200 {
833
833
  border-color: #374151 !important;
834
834
  }
835
835
 
836
- .dark .bg-gray-100, [data-theme="dark"] .bg-gray-100,
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-gray-300, [data-theme="dark"] .border-gray-300,
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-gray-200, [data-theme="dark"] .bg-gray-200,
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-gray-800 {
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-gray-700 {
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-gray-600 {
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-gray-500 {
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-gray-400 {
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-gray-50 {
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-gray-100,
940
+ [data-theme="light"] .border-secondary-100,
941
941
  [data-theme="light"] .border-slate-200,
942
- [data-theme="light"] .border-gray-200 {
942
+ [data-theme="light"] .border-secondary-200 {
943
943
  border-color: #e2e8f0 !important;
944
944
  }
945
- [data-theme="light"] .bg-gray-100,
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-gray-300,
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-gray-200,
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-red-700 { background-color: var(--color-danger) !important; }
982
- .hover\\:bg-red-800:hover { background-color: var(--color-danger-hover) !important; }
983
- .focus\\:ring-red-300:focus { --tw-ring-color: var(--color-danger-ring) !important; }
984
- .text-red-700 { color: var(--color-danger) !important; }
985
- .border-red-700 { border-color: var(--color-danger) !important; }
986
- .bg-red-500 { background-color: var(--color-danger) !important; }
987
- .hover\\:bg-red-600:hover { background-color: var(--color-danger-hover) !important; }
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-gray-100"] {
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-gray-100"]:hover {
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-red-500/10 hover:text-red-500 text-slate-400 dark:text-slate-500 cursor-pointer transition-all z-10"
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-[9999] 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"
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-gray-50 border-b border-gray-100 text-xs font-semibold text-gray-500 uppercase tracking-wider">
237
- <ITText as="div" className="flex-1 text-center py-2 border-r border-gray-100">
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-gray-50 scroll-smooth relative"
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-gray-50 border-t border-gray-100 flex justify-end">
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-50 p-4 rounded-xl shadow-xl flex items-center justify-between gap-4 transition-all duration-300 text-white min-w-[300px]",
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-[200] pointer-events-none", positionClasses[position])}>
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, #e2e8f0)",
65
- boxShadow: "none",
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, #e2e8f0)" }}>
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-gray-200"
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-50 overflow-hidden transform origin-top-right transition-all duration-200 ease-[cubic-bezier(0.2,0,0,1)]
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 ? '#ef4444' : "var(--topbar-user-text, #334155)" }}
223
+ style={{ color: isDestructive ? 'var(--color-danger-500)' : "var(--topbar-user-text, #334155)" }}
224
224
  onMouseEnter={(e) => {
225
- e.currentTarget.style.backgroundColor = isDestructive ? '#fef2f2' : "var(--topbar-user-item-hover, #f8fafc)";
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
- if (page >= 1 && page <= totalPages) {
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
- [totalPages]
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
- :root, :host {
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 Amaroaqui"
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 Amaroaqui</span>
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
  };