@axzydev/axzy_ui_system 1.3.1 → 1.3.2

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 (45) hide show
  1. package/README.md +6 -2
  2. package/dist/index.cjs +930 -544
  3. package/dist/index.cjs.map +1 -1
  4. package/dist/index.css +1 -1
  5. package/dist/index.d.cts +187 -9
  6. package/dist/index.d.ts +187 -9
  7. package/dist/index.js +881 -495
  8. package/dist/index.js.map +1 -1
  9. package/package.json +1 -1
  10. package/src/App.tsx +150 -154
  11. package/src/components/molecules/table/table.doc.mdx +64 -21
  12. package/src/components/molecules/table/table.props.ts +81 -2
  13. package/src/components/molecules/table/table.stories.tsx +155 -0
  14. package/src/components/molecules/table/table.tsx +177 -36
  15. package/src/components/organisms/data-table/ITDataTable.doc.mdx +37 -3
  16. package/src/components/organisms/data-table/ITDataTable.stories.tsx +43 -0
  17. package/src/components/organisms/data-table/dataTable.props.ts +64 -0
  18. package/src/components/organisms/data-table/dataTable.tsx +240 -82
  19. package/src/components/organisms/sidebar/sidebar.doc.mdx +5 -0
  20. package/src/components/organisms/sidebar/sidebar.props.ts +5 -0
  21. package/src/components/organisms/sidebar/sidebar.stories.tsx +1 -1
  22. package/src/components/organisms/sidebar/sidebar.tsx +27 -7
  23. package/src/components/organisms/topbar/topbar.doc.mdx +3 -0
  24. package/src/components/organisms/topbar/topbar.props.ts +16 -0
  25. package/src/components/organisms/topbar/topbar.tsx +133 -98
  26. package/src/components/templates/layout/layout.doc.mdx +2 -0
  27. package/src/components/templates/layout/layout.tsx +7 -1
  28. package/src/components/templates/page/page.doc.mdx +8 -2
  29. package/src/components/templates/page/page.props.ts +11 -1
  30. package/src/components/templates/page/page.tsx +11 -1
  31. package/src/dev.css +58 -1
  32. package/src/hooks/useElementSize.ts +46 -0
  33. package/src/hooks/useVirtualRows.ts +123 -0
  34. package/src/index.ts +2 -0
  35. package/src/sandbox/LandingShowcase.tsx +465 -0
  36. package/src/sandbox/NotFoundShowcase.tsx +70 -0
  37. package/src/sandbox/TopbarSearch.tsx +85 -0
  38. package/src/sandbox/navigation.ts +148 -0
  39. package/src/sandbox/useHashRoute.ts +149 -0
  40. package/src/showcases/DataShowcases.tsx +321 -24
  41. package/src/showcases/PageShowcases.tsx +31 -0
  42. package/src/showcases/StructureShowcases.tsx +42 -4
  43. package/src/types/table.types.ts +48 -0
  44. package/src/utils/styles.ts +9 -4
  45. package/src/utils/table.utils.ts +31 -0
package/dist/index.js CHANGED
@@ -2032,6 +2032,34 @@ import { useRef as useRef4, useState as useState9 } from "react";
2032
2032
 
2033
2033
  // src/utils/styles.ts
2034
2034
  import clsx11 from "clsx";
2035
+
2036
+ // src/types/table.types.ts
2037
+ var variantStyles = {
2038
+ default: "",
2039
+ striped: "",
2040
+ bordered: "border border-gray-200"
2041
+ };
2042
+ var sizeStyles = {
2043
+ sm: "text-xs",
2044
+ md: "text-sm",
2045
+ lg: "text-lg"
2046
+ };
2047
+ var densityStyles = {
2048
+ compact: { header: "px-3 py-2", cell: "px-3 py-1.5", rowHeight: 33 },
2049
+ normal: { header: "px-4 py-4", cell: "px-4 py-3", rowHeight: 45 },
2050
+ comfortable: { header: "px-4 py-5", cell: "px-4 py-4", rowHeight: 53 }
2051
+ };
2052
+ var sizeLineHeights = { sm: 16, md: 20, lg: 28 };
2053
+ function getRowHeight(size, density) {
2054
+ return densityStyles[density].rowHeight - sizeLineHeights.md + sizeLineHeights[size];
2055
+ }
2056
+ var tableAlignClasses = {
2057
+ left: "text-left",
2058
+ center: "text-center",
2059
+ right: "text-right"
2060
+ };
2061
+
2062
+ // src/utils/styles.ts
2035
2063
  function inputFieldStyle(inputTheme, size = "md", extra) {
2036
2064
  const sizeConfig = inputSizeTokens[size] ?? inputSizeTokens.md;
2037
2065
  return {
@@ -2061,13 +2089,15 @@ var iconAbsoluteLeft = "absolute inset-y-0 left-0 flex items-center pl-3 z-10";
2061
2089
  var iconAbsoluteRight = "absolute inset-y-0 right-0 flex items-center pr-3 z-10";
2062
2090
  var tableContainer = "rounded-xl shadow-sm border border-secondary-200 overflow-hidden";
2063
2091
  var tableHeaderRow = "bg-secondary-50 border-b border-secondary-200 text-xs uppercase tracking-wider font-semibold text-secondary-500";
2064
- function tableHeaderCell(className) {
2065
- return clsx11("px-4 py-4 align-top", className);
2092
+ function tableHeaderCell(className, density = "normal") {
2093
+ return clsx11(densityStyles[density].header, "align-top", className);
2066
2094
  }
2067
2095
  var tableBody = "divide-y divide-secondary-100";
2068
2096
  var tableRow = "hover:bg-secondary-50/50 transition-colors duration-150 group";
2069
- function tableCell(className) {
2070
- return clsx11("px-4 py-3 align-middle", className);
2097
+ var tableRowClickable = "cursor-pointer focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary-500 focus-visible:ring-inset";
2098
+ var tableCardClickable = "cursor-pointer rounded-lg focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary-500";
2099
+ function tableCell(className, density = "normal") {
2100
+ return clsx11(densityStyles[density].cell, "align-middle", className);
2071
2101
  }
2072
2102
  var tableActionsCell = "flex items-center justify-center gap-2";
2073
2103
  var tableCellText = "text-secondary-700 font-medium";
@@ -3484,21 +3514,88 @@ function ITConfirmDialog({
3484
3514
  ] });
3485
3515
  }
3486
3516
 
3487
- // src/types/table.types.ts
3488
- var variantStyles = {
3489
- default: "",
3490
- striped: "",
3491
- bordered: "border border-gray-200"
3492
- };
3493
- var sizeStyles = {
3494
- sm: "text-xs",
3495
- md: "text-sm",
3496
- lg: "text-lg"
3497
- };
3517
+ // src/hooks/useElementSize.ts
3518
+ import { useLayoutEffect as useLayoutEffect2, useRef as useRef9, useState as useState14 } from "react";
3519
+ function useElementSize() {
3520
+ const ref = useRef9(null);
3521
+ const [size, setSize] = useState14({ width: 0, height: 0 });
3522
+ useLayoutEffect2(() => {
3523
+ const element = ref.current;
3524
+ if (!element) return;
3525
+ const update = () => {
3526
+ const rect = element.getBoundingClientRect();
3527
+ setSize({ width: rect.width, height: rect.height });
3528
+ };
3529
+ update();
3530
+ const observer = new ResizeObserver(update);
3531
+ observer.observe(element);
3532
+ return () => observer.disconnect();
3533
+ }, []);
3534
+ return { ref, width: size.width, height: size.height };
3535
+ }
3536
+
3537
+ // src/hooks/useVirtualRows.ts
3538
+ import { useCallback as useCallback6, useLayoutEffect as useLayoutEffect3, useRef as useRef10, useState as useState15 } from "react";
3539
+ function useVirtualRows({
3540
+ count,
3541
+ rowHeight,
3542
+ overscan = 5,
3543
+ enabled = true,
3544
+ resetKey
3545
+ }) {
3546
+ const scrollRef = useRef10(null);
3547
+ const [scrollTop, setScrollTop] = useState15(0);
3548
+ const [viewportHeight, setViewportHeight] = useState15(0);
3549
+ const scrollToTop = useCallback6(() => {
3550
+ setScrollTop(0);
3551
+ const element = scrollRef.current;
3552
+ if (element) element.scrollTop = 0;
3553
+ }, []);
3554
+ useLayoutEffect3(() => {
3555
+ if (!enabled) return;
3556
+ const element = scrollRef.current;
3557
+ if (!element) return;
3558
+ const onScroll = () => setScrollTop(element.scrollTop);
3559
+ const measure = () => setViewportHeight(element.clientHeight);
3560
+ measure();
3561
+ setScrollTop(element.scrollTop);
3562
+ element.addEventListener("scroll", onScroll, { passive: true });
3563
+ const observer = new ResizeObserver(measure);
3564
+ observer.observe(element);
3565
+ return () => {
3566
+ element.removeEventListener("scroll", onScroll);
3567
+ observer.disconnect();
3568
+ };
3569
+ }, [enabled]);
3570
+ useLayoutEffect3(() => {
3571
+ if (!enabled) return;
3572
+ const element = scrollRef.current;
3573
+ if (element) element.scrollTop = 0;
3574
+ setScrollTop(0);
3575
+ }, [resetKey, enabled]);
3576
+ const valid = enabled && rowHeight > 0 && count > 0;
3577
+ const safeScrollTop = valid ? scrollTop : 0;
3578
+ const startIndex = valid ? Math.min(count - 1, Math.max(0, Math.floor(safeScrollTop / rowHeight) - overscan)) : 0;
3579
+ const endIndex = valid ? Math.min(
3580
+ count - 1,
3581
+ Math.ceil((safeScrollTop + viewportHeight) / rowHeight) + overscan
3582
+ ) : Math.max(0, count - 1);
3583
+ const topSpacerHeight = valid ? startIndex * rowHeight : 0;
3584
+ const bottomSpacerHeight = valid ? Math.max(0, (count - 1 - endIndex) * rowHeight) : 0;
3585
+ return {
3586
+ scrollRef,
3587
+ startIndex,
3588
+ endIndex,
3589
+ topSpacerHeight,
3590
+ bottomSpacerHeight,
3591
+ scrollTop: safeScrollTop,
3592
+ scrollToTop
3593
+ };
3594
+ }
3498
3595
 
3499
3596
  // src/components/organisms/data-table/dataTable.tsx
3500
3597
  import clsx21 from "clsx";
3501
- import { useState as useState15, useEffect as useEffect7, useCallback as useCallback6, useRef as useRef9 } from "react";
3598
+ import { useState as useState17, useEffect as useEffect7, useCallback as useCallback7, useRef as useRef11 } from "react";
3502
3599
  import { FaCheck as FaCheck2, FaSpinner, FaTimes as FaTimes4, FaTable, FaThLarge } from "react-icons/fa";
3503
3600
  import { MdOutlineSwapVert } from "react-icons/md";
3504
3601
 
@@ -3509,7 +3606,7 @@ import { FaChevronLeft as FaChevronLeft2, FaChevronRight as FaChevronRight3 } fr
3509
3606
 
3510
3607
  // src/components/molecules/select/select.tsx
3511
3608
  import clsx19 from "clsx";
3512
- import { useState as useState14 } from "react";
3609
+ import { useState as useState16 } from "react";
3513
3610
  import { FaAngleDown } from "react-icons/fa";
3514
3611
  import { jsx as jsx19, jsxs as jsxs16 } from "react/jsx-runtime";
3515
3612
  function ITSelect({
@@ -3530,8 +3627,8 @@ function ITSelect({
3530
3627
  readOnly = false,
3531
3628
  size = "md"
3532
3629
  }) {
3533
- const [isFocused, setIsFocused] = useState14(false);
3534
- const [localTouched, setLocalTouched] = useState14(false);
3630
+ const [isFocused, setIsFocused] = useState16(false);
3631
+ const [localTouched, setLocalTouched] = useState16(false);
3535
3632
  const inputTheme = theme.input || {};
3536
3633
  const isTouched = touched !== void 0 ? touched : localTouched;
3537
3634
  const isEmpty = value === void 0 || value === null || String(value).trim() === "";
@@ -3802,6 +3899,14 @@ var formatCurrencyMX = (value) => {
3802
3899
  var getNestedValue = (obj, path) => {
3803
3900
  return path.split(".").reduce((acc, part) => acc && acc[part], obj);
3804
3901
  };
3902
+ var ROW_CLICK_IGNORE_SELECTOR = 'button, a, input, select, textarea, [role="button"], [role="link"], [data-row-click-ignore]';
3903
+ function isInteractiveTarget(target, boundary = null) {
3904
+ if (!(target instanceof Element)) return false;
3905
+ const interactive = target.closest(ROW_CLICK_IGNORE_SELECTOR);
3906
+ if (!interactive) return false;
3907
+ if (boundary instanceof Node && interactive === boundary) return false;
3908
+ return true;
3909
+ }
3805
3910
 
3806
3911
  // src/components/organisms/data-table/dataTable.tsx
3807
3912
  import { Fragment as Fragment4, jsx as jsx21, jsxs as jsxs18 } from "react/jsx-runtime";
@@ -3827,12 +3932,32 @@ function ITDataTable({
3827
3932
  renderCard,
3828
3933
  defaultView,
3829
3934
  showVerticalBorder = true,
3830
- verticalBorderClassname
3935
+ verticalBorderClassname,
3936
+ onRowClick,
3937
+ layout = "auto",
3938
+ density = "normal",
3939
+ autoCardBreakpoint = 0,
3940
+ virtualized = false,
3941
+ virtualizedMaxHeight = 400,
3942
+ rowHeight,
3943
+ overscan = 5,
3944
+ stickyHeader = false
3831
3945
  }) {
3832
- const [viewMode, setViewMode] = useState15(defaultView || "table");
3833
- const [data, setData] = useState15([]);
3834
- const [totalItems, setTotalItems] = useState15(0);
3835
- const [isLoading, setIsLoading] = useState15(fetchOnMount);
3946
+ const [viewMode, setViewMode] = useState17(defaultView || "table");
3947
+ const { ref: rootRef, width: containerWidth } = useElementSize();
3948
+ const [data, setData] = useState17([]);
3949
+ const [totalItems, setTotalItems] = useState17(0);
3950
+ const [isLoading, setIsLoading] = useState17(fetchOnMount);
3951
+ const isFixed = layout === "fixed";
3952
+ const forcedCards = autoCardBreakpoint > 0 && containerWidth > 0 && containerWidth < autoCardBreakpoint;
3953
+ const effectiveView = forcedCards ? "cards" : viewMode;
3954
+ const hasColumnWidths = columns.some((col) => col.width != null);
3955
+ const tableLayoutClass = isFixed ? "w-full text-sm text-left text-secondary-600 transition-opacity duration-300" : "min-w-max w-full text-sm text-left text-secondary-600 transition-opacity duration-300";
3956
+ const isTableVirtual = virtualized && effectiveView === "table";
3957
+ const isStickyHeader = stickyHeader && isTableVirtual;
3958
+ const resolvedRowHeight = rowHeight ?? getRowHeight(size, density);
3959
+ const columnCount = columns.length;
3960
+ const scrollOuterClass = isTableVirtual ? "relative min-h-[200px]" : "overflow-x-auto relative min-h-[200px]";
3836
3961
  const {
3837
3962
  currentPage,
3838
3963
  itemsPerPage,
@@ -3843,15 +3968,29 @@ function ITDataTable({
3843
3968
  handleSort,
3844
3969
  handleItemsPerPageChange
3845
3970
  } = useTableState({ defaultItemsPerPage });
3846
- const debounceTimerRef = useRef9(null);
3847
- const hasFetchedRef = useRef9(false);
3848
- const fetchDataRef = useRef9(fetchData);
3971
+ const {
3972
+ scrollRef,
3973
+ startIndex,
3974
+ endIndex,
3975
+ topSpacerHeight,
3976
+ bottomSpacerHeight
3977
+ } = useVirtualRows({
3978
+ count: data.length,
3979
+ rowHeight: resolvedRowHeight,
3980
+ overscan,
3981
+ enabled: isTableVirtual,
3982
+ resetKey: `${currentPage}-${itemsPerPage}`
3983
+ });
3984
+ const windowData = isTableVirtual ? data.slice(startIndex, endIndex + 1) : data;
3985
+ const debounceTimerRef = useRef11(null);
3986
+ const hasFetchedRef = useRef11(false);
3987
+ const fetchDataRef = useRef11(fetchData);
3849
3988
  fetchDataRef.current = fetchData;
3850
- const externalFiltersRef = useRef9(externalFilters);
3989
+ const externalFiltersRef = useRef11(externalFilters);
3851
3990
  externalFiltersRef.current = externalFilters;
3852
3991
  const externalKey = JSON.stringify(externalFilters);
3853
3992
  const computedTotalPages = Math.ceil(totalItems / itemsPerPage) || 1;
3854
- const performFetch = useCallback6(async () => {
3993
+ const performFetch = useCallback7(async () => {
3855
3994
  setIsLoading(true);
3856
3995
  try {
3857
3996
  const response = await fetchDataRef.current({
@@ -3872,7 +4011,7 @@ function ITDataTable({
3872
4011
  setIsLoading(false);
3873
4012
  }
3874
4013
  }, [currentPage, itemsPerPage, filters, sortConfig]);
3875
- const performFetchRef = useRef9(performFetch);
4014
+ const performFetchRef = useRef11(performFetch);
3876
4015
  performFetchRef.current = performFetch;
3877
4016
  useEffect7(() => {
3878
4017
  if (!fetchOnMount && !hasFetchedRef.current) return;
@@ -3993,15 +4132,132 @@ function ITDataTable({
3993
4132
  actionCol?.actions && /* @__PURE__ */ jsx21("div", { className: "flex items-center justify-end gap-2 pt-2 border-t border-slate-100 dark:border-slate-700", children: actionCol.actions(row) })
3994
4133
  ] });
3995
4134
  };
3996
- const segCtrlClass = (mode) => `flex items-center gap-1.5 px-3 py-1.5 rounded-md text-xs font-semibold transition-all ${viewMode === mode ? "bg-white dark:bg-slate-900 text-slate-900 dark:text-white shadow-sm border border-slate-200/50 dark:border-slate-700" : "text-slate-500 dark:text-slate-400 hover:text-slate-700 dark:hover:text-slate-200"}`;
3997
- return /* @__PURE__ */ jsxs18("div", { className: clsx21("space-y-4 w-full relative", containerClassName), children: [
4135
+ const segCtrlClass = (mode) => `flex items-center gap-1.5 px-3 py-1.5 rounded-md text-xs font-semibold transition-all ${effectiveView === mode ? "bg-white dark:bg-slate-900 text-slate-900 dark:text-white shadow-sm border border-slate-200/50 dark:border-slate-700" : "text-slate-500 dark:text-slate-400 hover:text-slate-700 dark:hover:text-slate-200"}`;
4136
+ const handleRowClick = (row) => (event) => {
4137
+ if (!onRowClick || isLoading || isInteractiveTarget(event.target, event.currentTarget)) return;
4138
+ onRowClick(row, event);
4139
+ };
4140
+ const handleRowKeyDown = (row) => (event) => {
4141
+ if (!onRowClick || isLoading) return;
4142
+ if (event.target !== event.currentTarget) return;
4143
+ if (event.key !== "Enter" && event.key !== " ") return;
4144
+ event.preventDefault();
4145
+ onRowClick(row, event);
4146
+ };
4147
+ const tableEl = /* @__PURE__ */ jsxs18(
4148
+ "table",
4149
+ {
4150
+ className: clsx21(
4151
+ tableLayoutClass,
4152
+ showVerticalBorder && "[&_th]:border-r [&_th:last-child]:border-r-0 [&_td]:border-r [&_td:last-child]:border-r-0",
4153
+ showVerticalBorder && (verticalBorderClassname || "[&_th]:border-slate-100 dark:[&_th]:border-slate-700/30 [&_td]:border-slate-100 dark:[&_td]:border-slate-700/30"),
4154
+ isLoading ? "opacity-50" : "opacity-100",
4155
+ variantStyles[variant],
4156
+ sizeStyles[size],
4157
+ className
4158
+ ),
4159
+ style: isFixed ? { tableLayout: "fixed" } : void 0,
4160
+ "aria-rowcount": isTableVirtual ? data.length + 1 : void 0,
4161
+ children: [
4162
+ hasColumnWidths && /* @__PURE__ */ jsx21("colgroup", { children: columns.map((col) => /* @__PURE__ */ jsx21(
4163
+ "col",
4164
+ {
4165
+ style: col.width != null ? { width: typeof col.width === "number" ? `${col.width}px` : col.width } : void 0
4166
+ },
4167
+ col.key
4168
+ )) }),
4169
+ /* @__PURE__ */ jsx21("thead", { children: /* @__PURE__ */ jsx21(
4170
+ "tr",
4171
+ {
4172
+ className: clsx21(tableHeaderRow, "dark:text-slate-200"),
4173
+ "aria-rowindex": isTableVirtual ? 1 : void 0,
4174
+ children: columns.map((col) => /* @__PURE__ */ jsx21(
4175
+ "th",
4176
+ {
4177
+ scope: "col",
4178
+ className: clsx21(
4179
+ tableHeaderCell(col.className, density),
4180
+ col.align && tableAlignClasses[col.align],
4181
+ isStickyHeader && "sticky top-0 z-10 bg-secondary-50"
4182
+ ),
4183
+ style: col.minWidth != null || isStickyHeader ? {
4184
+ ...col.minWidth != null ? { minWidth: `${col.minWidth}px` } : {},
4185
+ ...isStickyHeader ? { backgroundColor: "var(--color-table-headerBg, #f8fafc)" } : {}
4186
+ } : void 0,
4187
+ children: /* @__PURE__ */ jsxs18("div", { className: isFixed ? "flex flex-col gap-3" : "flex flex-col gap-3 min-w-[150px]", children: [
4188
+ /* @__PURE__ */ jsxs18("div", { className: "flex items-center justify-between gap-2", children: [
4189
+ /* @__PURE__ */ jsx21(ITText, { as: "span", className: "text-slate-900 dark:text-white font-bold", children: col.label }),
4190
+ col.sortable && col.type !== "actions" && /* @__PURE__ */ jsx21(
4191
+ "button",
4192
+ {
4193
+ onClick: () => handleSort(col.key),
4194
+ disabled: isLoading,
4195
+ className: `p-1 rounded-md transition-colors ${sortConfig?.key === col.key ? "bg-secondary-200 text-secondary-900" : "hover:bg-secondary-200 text-secondary-400 hover:text-secondary-700"} disabled:opacity-50`,
4196
+ title: `Ordenar por ${col.label}`,
4197
+ children: /* @__PURE__ */ jsx21(MdOutlineSwapVert, { className: "w-4 h-4", "aria-hidden": "true" })
4198
+ }
4199
+ )
4200
+ ] }),
4201
+ /* @__PURE__ */ jsx21("div", { className: "w-full", children: col.filter ? renderFilterInput(col) : null })
4202
+ ] })
4203
+ },
4204
+ col.key
4205
+ ))
4206
+ }
4207
+ ) }),
4208
+ /* @__PURE__ */ jsx21("tbody", { className: clsx21(tableBody, "dark:divide-slate-700/30"), children: data.length > 0 ? /* @__PURE__ */ jsxs18(Fragment4, { children: [
4209
+ isTableVirtual && topSpacerHeight > 0 && /* @__PURE__ */ jsx21("tr", { "aria-hidden": "true", style: { height: topSpacerHeight }, children: /* @__PURE__ */ jsx21("td", { colSpan: columnCount, style: { padding: 0, border: 0 } }) }),
4210
+ windowData.map((row, windowIndex) => {
4211
+ const absoluteIndex = isTableVirtual ? startIndex + windowIndex : windowIndex;
4212
+ return /* @__PURE__ */ jsx21(
4213
+ "tr",
4214
+ {
4215
+ "aria-rowindex": isTableVirtual ? absoluteIndex + 2 : void 0,
4216
+ className: clsx21(
4217
+ tableRow,
4218
+ variant === "striped" && absoluteIndex % 2 === 0 && "bg-secondary-50/40 dark:bg-slate-800/20",
4219
+ onRowClick && !isLoading && tableRowClickable
4220
+ ),
4221
+ tabIndex: onRowClick && !isLoading ? 0 : void 0,
4222
+ onClick: onRowClick && !isLoading ? handleRowClick(row) : void 0,
4223
+ onKeyDown: onRowClick && !isLoading ? handleRowKeyDown(row) : void 0,
4224
+ children: columns.map((col) => {
4225
+ const rawValue = getNestedValue2(row, col.key);
4226
+ const truncateTitle = col.truncate && (typeof rawValue === "string" || typeof rawValue === "number") ? String(rawValue) : void 0;
4227
+ return /* @__PURE__ */ jsx21(
4228
+ "td",
4229
+ {
4230
+ className: clsx21(
4231
+ tableCell(col.className, density),
4232
+ col.align && tableAlignClasses[col.align]
4233
+ ),
4234
+ style: col.minWidth != null ? { minWidth: `${col.minWidth}px` } : void 0,
4235
+ title: truncateTitle,
4236
+ children: col.type === "actions" ? /* @__PURE__ */ jsx21("div", { className: tableActionsCell, children: renderCellContent(col, row) }) : /* @__PURE__ */ jsx21("div", { className: clsx21(tableCellText, col.truncate && "truncate"), children: renderCellContent(col, row) })
4237
+ },
4238
+ `${absoluteIndex}-${col.key}`
4239
+ );
4240
+ })
4241
+ },
4242
+ absoluteIndex
4243
+ );
4244
+ }),
4245
+ isTableVirtual && bottomSpacerHeight > 0 && /* @__PURE__ */ jsx21("tr", { "aria-hidden": "true", style: { height: bottomSpacerHeight }, children: /* @__PURE__ */ jsx21("td", { colSpan: columnCount, style: { padding: 0, border: 0 } }) })
4246
+ ] }) : /* @__PURE__ */ jsx21("tr", { children: /* @__PURE__ */ jsx21("td", { colSpan: columns.length, className: "px-6 py-12 text-center", children: !isLoading && /* @__PURE__ */ jsxs18("div", { className: tableEmptyContent, children: [
4247
+ /* @__PURE__ */ jsx21(ITText, { as: "span", className: "text-lg", children: "No se encontraron resultados" }),
4248
+ /* @__PURE__ */ jsx21(ITText, { as: "span", className: "text-sm mt-1", children: "Intenta ajustar los filtros" })
4249
+ ] }) }) }) })
4250
+ ]
4251
+ }
4252
+ );
4253
+ return /* @__PURE__ */ jsxs18("div", { ref: rootRef, className: clsx21("space-y-4 w-full relative", containerClassName), children: [
3998
4254
  /* @__PURE__ */ jsxs18("div", { className: tableContainer, style: { backgroundColor: "var(--color-table-rowBg, #ffffff)" }, children: [
3999
4255
  title && /* @__PURE__ */ jsxs18("div", { className: "px-6 py-5 flex items-center justify-between", style: { backgroundColor: "var(--color-table-rowBg, #ffffff)" }, children: [
4000
4256
  /* @__PURE__ */ jsx21(ITText, { as: "h2", className: "text-xl font-bold text-secondary-900 leading-tight", children: title }),
4001
4257
  /* @__PURE__ */ jsxs18("div", { className: "flex items-center gap-3", children: [
4002
4258
  isLoading && /* @__PURE__ */ jsx21("div", { className: "text-secondary-400", children: loadingIndicator || /* @__PURE__ */ jsx21(FaSpinner, { className: "animate-spin text-primary-500 text-xl" }) }),
4003
4259
  /* @__PURE__ */ jsxs18("div", { className: "flex items-center bg-slate-100 dark:bg-slate-800/80 rounded-lg p-0.5 border border-slate-200 dark:border-slate-700/50", children: [
4004
- /* @__PURE__ */ jsxs18("button", { onClick: () => setViewMode("table"), className: segCtrlClass("table"), children: [
4260
+ /* @__PURE__ */ jsxs18("button", { onClick: () => setViewMode("table"), disabled: forcedCards, className: segCtrlClass("table"), children: [
4005
4261
  /* @__PURE__ */ jsx21(FaTable, { size: 11 }),
4006
4262
  "Table"
4007
4263
  ] }),
@@ -4013,7 +4269,7 @@ function ITDataTable({
4013
4269
  ] })
4014
4270
  ] }),
4015
4271
  !title && /* @__PURE__ */ jsx21("div", { className: "flex justify-end px-4 pt-3", children: /* @__PURE__ */ jsxs18("div", { className: "flex items-center bg-slate-100 dark:bg-slate-800/80 rounded-lg p-0.5 border border-slate-200 dark:border-slate-700/50", children: [
4016
- /* @__PURE__ */ jsxs18("button", { onClick: () => setViewMode("table"), className: segCtrlClass("table"), children: [
4272
+ /* @__PURE__ */ jsxs18("button", { onClick: () => setViewMode("table"), disabled: forcedCards, className: segCtrlClass("table"), children: [
4017
4273
  /* @__PURE__ */ jsx21(FaTable, { size: 11 }),
4018
4274
  "Table"
4019
4275
  ] }),
@@ -4022,50 +4278,34 @@ function ITDataTable({
4022
4278
  "Cards"
4023
4279
  ] })
4024
4280
  ] }) }),
4025
- /* @__PURE__ */ jsxs18("div", { className: "overflow-x-auto relative min-h-[200px]", children: [
4281
+ /* @__PURE__ */ jsxs18("div", { className: scrollOuterClass, children: [
4026
4282
  isLoading && /* @__PURE__ */ jsx21("div", { className: "absolute inset-0 z-20 flex items-center justify-center bg-white/40 backdrop-blur-[2px] transition-all duration-300", children: /* @__PURE__ */ jsx21("div", { className: "flex flex-col items-center gap-3 p-6 rounded-2xl shadow-xl border border-secondary-100 animate-in fade-in zoom-in duration-300", style: { backgroundColor: "var(--color-table-rowBg, #ffffff)" }, children: loadingIndicator || /* @__PURE__ */ jsxs18(Fragment4, { children: [
4027
4283
  /* @__PURE__ */ jsx21(FaSpinner, { className: "animate-spin text-primary-500 text-4xl" }),
4028
4284
  /* @__PURE__ */ jsx21(ITText, { as: "span", className: "text-sm font-semibold text-secondary-600 animate-pulse", children: "Cargando datos..." })
4029
4285
  ] }) }) }),
4030
- viewMode === "cards" ? /* @__PURE__ */ jsx21("div", { className: "p-4 space-y-3 max-h-[400px] overflow-y-auto", children: data.length > 0 ? data.map((row, i) => /* @__PURE__ */ jsx21("div", { children: renderCard ? renderCard(row) : renderDefaultCard(row) }, i)) : !isLoading && /* @__PURE__ */ jsxs18("div", { className: clsx21(tableEmptyContent, "py-12"), children: [
4286
+ effectiveView === "cards" ? /* @__PURE__ */ jsx21("div", { className: "p-4 space-y-3 max-h-[400px] overflow-y-auto", children: data.length > 0 ? data.map((row, i) => /* @__PURE__ */ jsx21(
4287
+ "div",
4288
+ {
4289
+ className: clsx21(onRowClick && !isLoading && tableCardClickable),
4290
+ role: onRowClick && !isLoading ? "button" : void 0,
4291
+ tabIndex: onRowClick && !isLoading ? 0 : void 0,
4292
+ onClick: onRowClick && !isLoading ? handleRowClick(row) : void 0,
4293
+ onKeyDown: onRowClick && !isLoading ? handleRowKeyDown(row) : void 0,
4294
+ children: renderCard ? renderCard(row) : renderDefaultCard(row)
4295
+ },
4296
+ i
4297
+ )) : !isLoading && /* @__PURE__ */ jsxs18("div", { className: clsx21(tableEmptyContent, "py-12"), children: [
4031
4298
  /* @__PURE__ */ jsx21(ITText, { as: "span", className: "text-lg", children: "No se encontraron resultados" }),
4032
4299
  /* @__PURE__ */ jsx21(ITText, { as: "span", className: "text-sm mt-1", children: "Intenta ajustar los filtros" })
4033
- ] }) }) : /* @__PURE__ */ jsxs18(
4034
- "table",
4300
+ ] }) }) : isTableVirtual ? /* @__PURE__ */ jsx21(
4301
+ "div",
4035
4302
  {
4036
- className: clsx21(
4037
- "min-w-max w-full text-sm text-left text-secondary-600 transition-opacity duration-300",
4038
- showVerticalBorder && "[&_th]:border-r [&_th:last-child]:border-r-0 [&_td]:border-r [&_td:last-child]:border-r-0",
4039
- showVerticalBorder && (verticalBorderClassname || "[&_th]:border-slate-100 dark:[&_th]:border-slate-700/30 [&_td]:border-slate-100 dark:[&_td]:border-slate-700/30"),
4040
- isLoading ? "opacity-50" : "opacity-100",
4041
- variantStyles[variant],
4042
- sizeStyles[size],
4043
- className
4044
- ),
4045
- children: [
4046
- /* @__PURE__ */ jsx21("thead", { children: /* @__PURE__ */ jsx21("tr", { className: clsx21(tableHeaderRow, "dark:text-slate-200"), children: columns.map((col) => /* @__PURE__ */ jsx21("th", { scope: "col", className: tableHeaderCell(col.className), children: /* @__PURE__ */ jsxs18("div", { className: "flex flex-col gap-3 min-w-[150px]", children: [
4047
- /* @__PURE__ */ jsxs18("div", { className: "flex items-center justify-between gap-2", children: [
4048
- /* @__PURE__ */ jsx21(ITText, { as: "span", className: "text-slate-900 dark:text-white font-bold", children: col.label }),
4049
- col.sortable && col.type !== "actions" && /* @__PURE__ */ jsx21(
4050
- "button",
4051
- {
4052
- onClick: () => handleSort(col.key),
4053
- disabled: isLoading,
4054
- className: `p-1 rounded-md transition-colors ${sortConfig?.key === col.key ? "bg-secondary-200 text-secondary-900" : "hover:bg-secondary-200 text-secondary-400 hover:text-secondary-700"} disabled:opacity-50`,
4055
- title: `Ordenar por ${col.label}`,
4056
- children: /* @__PURE__ */ jsx21(MdOutlineSwapVert, { className: "w-4 h-4", "aria-hidden": "true" })
4057
- }
4058
- )
4059
- ] }),
4060
- /* @__PURE__ */ jsx21("div", { className: "w-full", children: col.filter ? renderFilterInput(col) : null })
4061
- ] }) }, col.key)) }) }),
4062
- /* @__PURE__ */ jsx21("tbody", { className: clsx21(tableBody, "dark:divide-slate-700/30"), children: data.length > 0 ? data.map((row, rowIndex) => /* @__PURE__ */ jsx21("tr", { className: clsx21(tableRow, variant === "striped" && "odd:bg-secondary-50/40 dark:odd:bg-slate-800/20"), children: columns.map((col) => /* @__PURE__ */ jsx21("td", { className: tableCell(col.className), children: col.type === "actions" ? /* @__PURE__ */ jsx21("div", { className: tableActionsCell, children: renderCellContent(col, row) }) : /* @__PURE__ */ jsx21("div", { className: tableCellText, children: renderCellContent(col, row) }) }, `${rowIndex}-${col.key}`)) }, rowIndex)) : /* @__PURE__ */ jsx21("tr", { children: /* @__PURE__ */ jsx21("td", { colSpan: columns.length, className: "px-6 py-12 text-center", children: !isLoading && /* @__PURE__ */ jsxs18("div", { className: tableEmptyContent, children: [
4063
- /* @__PURE__ */ jsx21(ITText, { as: "span", className: "text-lg", children: "No se encontraron resultados" }),
4064
- /* @__PURE__ */ jsx21(ITText, { as: "span", className: "text-sm mt-1", children: "Intenta ajustar los filtros" })
4065
- ] }) }) }) })
4066
- ]
4303
+ ref: scrollRef,
4304
+ className: "overflow-x-auto overflow-y-auto",
4305
+ style: { maxHeight: virtualizedMaxHeight },
4306
+ children: tableEl
4067
4307
  }
4068
- )
4308
+ ) : tableEl
4069
4309
  ] })
4070
4310
  ] }),
4071
4311
  /* @__PURE__ */ jsx21("div", { className: "rounded-b-xl px-6 py-4", style: { backgroundColor: "var(--color-table-rowBg, #ffffff)" }, children: /* @__PURE__ */ jsx21(
@@ -4086,7 +4326,7 @@ function ITDataTable({
4086
4326
 
4087
4327
  // src/components/molecules/date-picker/datePicker.tsx
4088
4328
  import clsx22 from "clsx";
4089
- import React5, { useEffect as useEffect8, useRef as useRef10, useState as useState16 } from "react";
4329
+ import React5, { useEffect as useEffect8, useRef as useRef12, useState as useState18 } from "react";
4090
4330
  import { createPortal as createPortal3 } from "react-dom";
4091
4331
  import { FaCalendarAlt } from "react-icons/fa";
4092
4332
  import { isBefore as isBefore2 } from "date-fns";
@@ -4110,11 +4350,11 @@ function ITDatePicker({
4110
4350
  maxDate,
4111
4351
  range = false
4112
4352
  }) {
4113
- const [isOpen, setIsOpen] = useState16(false);
4114
- const [inputValue, setInputValue] = useState16("");
4115
- const [isValidDate, setIsValidDate] = useState16(true);
4116
- const [internalRange, setInternalRange] = useState16([null, null]);
4117
- const wrapperRef = useRef10(null);
4353
+ const [isOpen, setIsOpen] = useState18(false);
4354
+ const [inputValue, setInputValue] = useState18("");
4355
+ const [isValidDate, setIsValidDate] = useState18(true);
4356
+ const [internalRange, setInternalRange] = useState18([null, null]);
4357
+ const wrapperRef = useRef12(null);
4118
4358
  const { panelRef, style: panelStyle } = useFloatingPanel(wrapperRef, isOpen, {
4119
4359
  estimatedHeight: 360,
4120
4360
  matchWidth: false
@@ -4339,7 +4579,7 @@ function ITDatePicker({
4339
4579
 
4340
4580
  // src/components/organisms/dialog/dialog.tsx
4341
4581
  import { createPortal as createPortal4 } from "react-dom";
4342
- import { useEffect as useEffect9, useRef as useRef11 } from "react";
4582
+ import { useEffect as useEffect9, useRef as useRef13 } from "react";
4343
4583
  import { FaRegTimesCircle } from "react-icons/fa";
4344
4584
 
4345
4585
  // src/components/molecules/form-header/form-header.tsx
@@ -4476,7 +4716,7 @@ function ITDialog({
4476
4716
  useFormHeader = false,
4477
4717
  fullScreen = false
4478
4718
  }) {
4479
- const modalRef = useRef11(null);
4719
+ const modalRef = useRef13(null);
4480
4720
  useClickOutside_default(modalRef, onClose);
4481
4721
  useEffect9(() => {
4482
4722
  const handleEscape = (event) => {
@@ -4559,7 +4799,7 @@ function ITDivider({
4559
4799
  // src/components/organisms/drawer/drawer.tsx
4560
4800
  import clsx24 from "clsx";
4561
4801
  import { FaTimes as FaTimes6 } from "react-icons/fa";
4562
- import { useRef as useRef12 } from "react";
4802
+ import { useRef as useRef14 } from "react";
4563
4803
  import { Fragment as Fragment6, jsx as jsx26, jsxs as jsxs22 } from "react/jsx-runtime";
4564
4804
  function ITDrawer({
4565
4805
  isOpen,
@@ -4571,7 +4811,7 @@ function ITDrawer({
4571
4811
  className,
4572
4812
  style
4573
4813
  }) {
4574
- const panelRef = useRef12(null);
4814
+ const panelRef = useRef14(null);
4575
4815
  useClickOutside_default(panelRef, onClose);
4576
4816
  return /* @__PURE__ */ jsx26(Fragment6, { children: isOpen && /* @__PURE__ */ jsxs22("div", { className: "fixed inset-0 z-[50] flex", children: [
4577
4817
  /* @__PURE__ */ jsx26("div", { className: "absolute inset-0 bg-black/40 backdrop-blur-sm transition-opacity" }),
@@ -4697,14 +4937,14 @@ function ITFlex({
4697
4937
  import { useMemo as useMemo10 } from "react";
4698
4938
 
4699
4939
  // src/components/organisms/form-builder/formBuilder.context.tsx
4700
- import React6, { createContext as createContext2, useContext as useContext2, useState as useState17 } from "react";
4940
+ import React6, { createContext as createContext2, useContext as useContext2, useState as useState19 } from "react";
4701
4941
  import { jsx as jsx29 } from "react/jsx-runtime";
4702
4942
  var ITFormBuilderContext = createContext2(void 0);
4703
4943
  var ITFormBuilderProvider = ({
4704
4944
  children,
4705
4945
  value
4706
4946
  }) => {
4707
- const [fieldRegistry, setFieldRegistry] = useState17({});
4947
+ const [fieldRegistry, setFieldRegistry] = useState19({});
4708
4948
  const registerField = React6.useCallback((name, config2) => {
4709
4949
  setFieldRegistry((prev) => ({ ...prev, [name]: config2 }));
4710
4950
  }, []);
@@ -4744,12 +4984,12 @@ var useITFormBuilderContext = () => {
4744
4984
  };
4745
4985
 
4746
4986
  // src/components/organisms/form-builder/fieldRenderer.tsx
4747
- import { memo, useCallback as useCallback7, useEffect as useEffect12, useMemo as useMemo9, useState as useState20, useRef as useRef15 } from "react";
4987
+ import { memo, useCallback as useCallback8, useEffect as useEffect12, useMemo as useMemo9, useState as useState22, useRef as useRef17 } from "react";
4748
4988
  import clsx29 from "clsx";
4749
4989
 
4750
4990
  // src/components/molecules/time-picker/timePicker.tsx
4751
4991
  import clsx27 from "clsx";
4752
- import { useEffect as useEffect10, useRef as useRef13, useState as useState18 } from "react";
4992
+ import { useEffect as useEffect10, useRef as useRef15, useState as useState20 } from "react";
4753
4993
  import { createPortal as createPortal5 } from "react-dom";
4754
4994
  import { FaClock } from "react-icons/fa";
4755
4995
  import { jsx as jsx30, jsxs as jsxs24 } from "react/jsx-runtime";
@@ -4769,12 +5009,12 @@ function ITTimePicker({
4769
5009
  variant = "primary",
4770
5010
  color = "primary"
4771
5011
  }) {
4772
- const [isOpen, setIsOpen] = useState18(false);
4773
- const [inputValue, setInputValue] = useState18(value || "");
4774
- const [isValidTime, setIsValidTime] = useState18(true);
4775
- const wrapperRef = useRef13(null);
4776
- const hoursRef = useRef13(null);
4777
- const minutesRef = useRef13(null);
5012
+ const [isOpen, setIsOpen] = useState20(false);
5013
+ const [inputValue, setInputValue] = useState20(value || "");
5014
+ const [isValidTime, setIsValidTime] = useState20(true);
5015
+ const wrapperRef = useRef15(null);
5016
+ const hoursRef = useRef15(null);
5017
+ const minutesRef = useRef15(null);
4778
5018
  const { panelRef: dropdownRef, style: panelStyle } = useFloatingPanel(
4779
5019
  wrapperRef,
4780
5020
  isOpen && !disabled,
@@ -5003,7 +5243,7 @@ function ITTimePicker({
5003
5243
  }
5004
5244
 
5005
5245
  // src/components/molecules/search-select/search-select.tsx
5006
- import { useState as useState19, useEffect as useEffect11, useRef as useRef14, useMemo as useMemo7 } from "react";
5246
+ import { useState as useState21, useEffect as useEffect11, useRef as useRef16, useMemo as useMemo7 } from "react";
5007
5247
  import { createPortal as createPortal6 } from "react-dom";
5008
5248
  import clsx28 from "clsx";
5009
5249
  import { FaSearch as FaSearch2, FaTimes as FaTimes7 } from "react-icons/fa";
@@ -5032,13 +5272,13 @@ function ITSearchSelect({
5032
5272
  clearable = true,
5033
5273
  onClear
5034
5274
  }) {
5035
- const [isOpen, setIsOpen] = useState19(false);
5036
- const [searchTerm, setSearchTerm] = useState19("");
5037
- const [isFocused, setIsFocused] = useState19(false);
5038
- const [localTouched, setLocalTouched] = useState19(false);
5039
- const containerRef = useRef14(null);
5040
- const inputWrapperRef = useRef14(null);
5041
- const timeoutRef = useRef14(null);
5275
+ const [isOpen, setIsOpen] = useState21(false);
5276
+ const [searchTerm, setSearchTerm] = useState21("");
5277
+ const [isFocused, setIsFocused] = useState21(false);
5278
+ const [localTouched, setLocalTouched] = useState21(false);
5279
+ const containerRef = useRef16(null);
5280
+ const inputWrapperRef = useRef16(null);
5281
+ const timeoutRef = useRef16(null);
5042
5282
  const { panelRef, style: panelStyle } = useFloatingPanel(inputWrapperRef, isOpen, {
5043
5283
  estimatedHeight: 260,
5044
5284
  matchWidth: true
@@ -5266,9 +5506,9 @@ var useFieldRules = (config2, dependentValues) => {
5266
5506
  import { FaSpinner as FaSpinner2 } from "react-icons/fa";
5267
5507
  import { jsx as jsx32, jsxs as jsxs26 } from "react/jsx-runtime";
5268
5508
  function useAsyncOptions(options, deps) {
5269
- const [resolved, setResolved] = useState20([]);
5270
- const [loading, setLoading] = useState20(false);
5271
- const optionsRef = useRef15(options);
5509
+ const [resolved, setResolved] = useState22([]);
5510
+ const [loading, setLoading] = useState22(false);
5511
+ const optionsRef = useRef17(options);
5272
5512
  optionsRef.current = options;
5273
5513
  useEffect12(() => {
5274
5514
  const opts = optionsRef.current;
@@ -5345,7 +5585,7 @@ var ITFieldRenderer = ({
5345
5585
  options,
5346
5586
  [options, dependentValues]
5347
5587
  );
5348
- const handleChangeWrapper = useCallback7(
5588
+ const handleChangeWrapper = useCallback8(
5349
5589
  async (val) => {
5350
5590
  const finalValue = val && typeof val === "object" && "target" in val ? val.target.value : val;
5351
5591
  await context.setFieldValue(name, finalValue);
@@ -5807,7 +6047,7 @@ function ITGrid({
5807
6047
  }
5808
6048
 
5809
6049
  // src/components/atoms/image/image.tsx
5810
- import { useState as useState21 } from "react";
6050
+ import { useState as useState23 } from "react";
5811
6051
  import { jsx as jsx35 } from "react/jsx-runtime";
5812
6052
  var ITImage = ({
5813
6053
  src,
@@ -5815,7 +6055,7 @@ var ITImage = ({
5815
6055
  className = "",
5816
6056
  fallback = ""
5817
6057
  }) => {
5818
- const [imageError, setImageError] = useState21(false);
6058
+ const [imageError, setImageError] = useState23(false);
5819
6059
  const handleImageError = () => {
5820
6060
  setImageError(true);
5821
6061
  };
@@ -5845,7 +6085,7 @@ var ITImage = ({
5845
6085
  var image_default = ITImage;
5846
6086
 
5847
6087
  // src/components/organisms/navbar/navbar.tsx
5848
- import { useRef as useRef16, useState as useState22 } from "react";
6088
+ import { useRef as useRef18, useState as useState24 } from "react";
5849
6089
  import { FaChevronDown as FaChevronDown3, FaChevronRight as FaChevronRight4, FaUserCircle } from "react-icons/fa";
5850
6090
  import { jsx as jsx36, jsxs as jsxs28 } from "react/jsx-runtime";
5851
6091
  function ITNavbar({
@@ -5860,9 +6100,9 @@ function ITNavbar({
5860
6100
  showSidebarOnMobile = false,
5861
6101
  sidebarItems
5862
6102
  }) {
5863
- const [isUserMenuOpen, setIsUserMenuOpen] = useState22(false);
5864
- const [expandedItems, setExpandedItems] = useState22(/* @__PURE__ */ new Set());
5865
- const userMenuRef = useRef16(null);
6103
+ const [isUserMenuOpen, setIsUserMenuOpen] = useState24(false);
6104
+ const [expandedItems, setExpandedItems] = useState24(/* @__PURE__ */ new Set());
6105
+ const userMenuRef = useRef18(null);
5866
6106
  useClickOutside_default(userMenuRef, () => setIsUserMenuOpen(false));
5867
6107
  const toggleUserMenu = () => {
5868
6108
  setIsUserMenuOpen(!isUserMenuOpen);
@@ -6301,11 +6541,13 @@ function ITPage(props) {
6301
6541
  className,
6302
6542
  children,
6303
6543
  maxWidth = "7xl",
6304
- noPadding = false
6544
+ noPadding = false,
6545
+ horizontalPadding = "px-4 sm:px-6 lg:px-8"
6305
6546
  } = props;
6306
6547
  const wrapperClass = clsx33(
6307
6548
  "mx-auto w-full",
6308
- !noPadding && "px-4 sm:px-6 lg:px-8 py-6",
6549
+ !noPadding && horizontalPadding,
6550
+ !noPadding && "py-6",
6309
6551
  `max-w-${maxWidth}`,
6310
6552
  "space-y-8",
6311
6553
  className
@@ -6360,7 +6602,7 @@ function ITPage(props) {
6360
6602
  }
6361
6603
 
6362
6604
  // src/components/atoms/popover/popover.tsx
6363
- import { useState as useState23, useRef as useRef17 } from "react";
6605
+ import { useState as useState25, useRef as useRef19 } from "react";
6364
6606
  import clsx34 from "clsx";
6365
6607
  import { jsx as jsx41, jsxs as jsxs32 } from "react/jsx-runtime";
6366
6608
  var positionClasses = {
@@ -6377,10 +6619,10 @@ function ITPopover({
6377
6619
  onClose,
6378
6620
  className
6379
6621
  }) {
6380
- const [internalOpen, setInternalOpen] = useState23(false);
6622
+ const [internalOpen, setInternalOpen] = useState25(false);
6381
6623
  const isControlled = controlledOpen !== void 0;
6382
6624
  const open = isControlled ? controlledOpen : internalOpen;
6383
- const ref = useRef17(null);
6625
+ const ref = useRef19(null);
6384
6626
  useClickOutside_default(ref, () => {
6385
6627
  if (isControlled) onClose?.();
6386
6628
  else setInternalOpen(false);
@@ -6508,7 +6750,7 @@ function ITRadioGroup({
6508
6750
 
6509
6751
  // src/components/organisms/searchTable/searchTable.tsx
6510
6752
  import clsx38 from "clsx";
6511
- import { useState as useState24 } from "react";
6753
+ import { useState as useState26 } from "react";
6512
6754
 
6513
6755
  // src/components/organisms/searchTable/components/SearchInput.tsx
6514
6756
  import { FaSearch as FaSearch3 } from "react-icons/fa";
@@ -7001,7 +7243,7 @@ function ITSearchTable({
7001
7243
  onSave,
7002
7244
  onCancel
7003
7245
  }) {
7004
- const [itemsPerPage, setItemsPerPage] = useState24(defaultItemsPerPage);
7246
+ const [itemsPerPage, setItemsPerPage] = useState26(defaultItemsPerPage);
7005
7247
  const { searchTerm, handleSearchChange, handleClearSearch } = useDebouncedSearch({
7006
7248
  initialValue: searchTermInitial,
7007
7249
  onSearch: (value) => {
@@ -7164,7 +7406,7 @@ function ITSegmentedControl({
7164
7406
  }
7165
7407
 
7166
7408
  // src/components/organisms/sidebar/sidebar.tsx
7167
- import { useEffect as useEffect13, useRef as useRef18, useState as useState25 } from "react";
7409
+ import { useEffect as useEffect13, useRef as useRef20, useState as useState27 } from "react";
7168
7410
  import { FaChevronDown as FaChevronDown4 } from "react-icons/fa";
7169
7411
  import { jsx as jsx55, jsxs as jsxs43 } from "react/jsx-runtime";
7170
7412
  function ITSidebar({
@@ -7174,13 +7416,14 @@ function ITSidebar({
7174
7416
  visibleOnMobile = false,
7175
7417
  onItemClick,
7176
7418
  onSubItemClick,
7177
- subitemConnector = "dot"
7419
+ subitemConnector = "dot",
7420
+ header
7178
7421
  }) {
7179
- const [expandedItems, setExpandedItems] = useState25(/* @__PURE__ */ new Set());
7180
- const [isHovering, setIsHovering] = useState25(false);
7181
- const sidebarRef = useRef18(null);
7182
- const hoverTimeoutRef = useRef18(null);
7183
- const leaveTimeoutRef = useRef18(null);
7422
+ const [expandedItems, setExpandedItems] = useState27(/* @__PURE__ */ new Set());
7423
+ const [isHovering, setIsHovering] = useState27(false);
7424
+ const sidebarRef = useRef20(null);
7425
+ const hoverTimeoutRef = useRef20(null);
7426
+ const leaveTimeoutRef = useRef20(null);
7184
7427
  useEffect13(() => {
7185
7428
  const hoverTimer = hoverTimeoutRef.current;
7186
7429
  const leaveTimer = leaveTimeoutRef.current;
@@ -7245,7 +7488,7 @@ function ITSidebar({
7245
7488
  };
7246
7489
  const isSidebarCollapsed = visibleOnMobile ? false : !isHovering && isCollapsed;
7247
7490
  const sidebarWidth = isSidebarCollapsed ? "w-[88px]" : "w-[280px]";
7248
- return /* @__PURE__ */ jsx55(
7491
+ return /* @__PURE__ */ jsxs43(
7249
7492
  "aside",
7250
7493
  {
7251
7494
  ref: sidebarRef,
@@ -7264,196 +7507,215 @@ function ITSidebar({
7264
7507
  WebkitBackdropFilter: "blur(12px)",
7265
7508
  backdropFilter: "blur(12px)"
7266
7509
  },
7267
- children: /* @__PURE__ */ jsx55("nav", { className: "flex-1 py-4 overflow-y-auto overflow-x-hidden custom-scrollbar px-4", children: /* @__PURE__ */ jsx55("ul", { className: "space-y-1", children: navigationItems.map((item) => /* @__PURE__ */ jsxs43("li", { className: "relative group/navitem", children: [
7268
- /* @__PURE__ */ jsxs43(
7269
- "div",
7270
- {
7271
- className: `flex items-center cursor-pointer
7510
+ children: [
7511
+ header && !isSidebarCollapsed && /* @__PURE__ */ jsx55("div", { className: "px-4 pt-4 pb-1 flex-shrink-0", children: header }),
7512
+ /* @__PURE__ */ jsx55("nav", { "aria-label": "Componentes de la librer\xEDa", className: "flex-1 py-4 overflow-y-auto overflow-x-hidden custom-scrollbar px-4", children: /* @__PURE__ */ jsx55("ul", { className: "space-y-1", children: navigationItems.map((item) => {
7513
+ const hasSubmenu = !!item.subitems && item.subitems.length > 0;
7514
+ const submenuId = `it-sidebar-submenu-${item.id}`;
7515
+ return /* @__PURE__ */ jsxs43("li", { className: "relative group/navitem", children: [
7516
+ /* @__PURE__ */ jsxs43(
7517
+ "div",
7518
+ {
7519
+ role: "button",
7520
+ tabIndex: 0,
7521
+ "aria-label": item.label,
7522
+ "aria-expanded": hasSubmenu ? expandedItems.has(item.id) : void 0,
7523
+ "aria-controls": hasSubmenu ? submenuId : void 0,
7524
+ className: `flex items-center cursor-pointer
7272
7525
  transition-all duration-300 ease-[cubic-bezier(0.2,0,0,1)]
7273
7526
  rounded-xl relative overflow-visible
7274
7527
  ${isSidebarCollapsed ? "justify-center p-2 mb-1" : "justify-between px-3 py-2 mb-0.5"}
7275
7528
  `,
7276
- style: {
7277
- backgroundColor: item.isActive ? "var(--it-sidebar-active-bg, var(--color-secondary-50))" : "transparent",
7278
- boxShadow: item.isActive ? "var(--shadow-xs)" : "none",
7279
- border: item.isActive ? "1px solid var(--it-sidebar-border, var(--color-secondary-200))" : "1px solid transparent"
7280
- },
7281
- onMouseEnter: (e) => {
7282
- if (!item.isActive) e.currentTarget.style.backgroundColor = "var(--it-sidebar-hover-bg, var(--color-secondary-100))";
7283
- },
7284
- onMouseLeave: (e) => {
7285
- if (!item.isActive) e.currentTarget.style.backgroundColor = "transparent";
7286
- },
7287
- onClick: () => handleItemClick(item),
7288
- children: [
7289
- item.isActive && !isSidebarCollapsed && /* @__PURE__ */ jsx55(
7290
- "div",
7291
- {
7292
- className: "absolute left-0 top-1/4 bottom-1/4 w-[3px] rounded-r-full transition-all",
7293
- style: { backgroundColor: "var(--it-sidebar-active-icon, var(--color-primary-500))", boxShadow: "0 0 10px var(--it-sidebar-active-icon, var(--color-primary-500))" }
7294
- }
7295
- ),
7296
- /* @__PURE__ */ jsxs43("div", { className: `flex items-center ${!isSidebarCollapsed ? "gap-2.5" : "justify-center"} relative z-10 w-full`, children: [
7297
- item.icon && /* @__PURE__ */ jsx55(
7298
- "div",
7299
- {
7300
- className: `transition-all duration-300 flex-shrink-0 flex items-center justify-center`,
7301
- style: {
7302
- color: item.isActive ? "var(--it-sidebar-active-icon, var(--color-primary-500))" : "var(--it-sidebar-icon-color, #9ca3af)",
7303
- opacity: item.isActive ? 1 : 0.8,
7304
- fontSize: item.isActive ? "1.12rem" : "1.05rem",
7305
- filter: item.isActive ? "drop-shadow(0 0 8px rgba(255,255,255,0.2))" : "none"
7306
- },
7307
- children: item.icon
7308
- }
7309
- ),
7310
- !isSidebarCollapsed && /* @__PURE__ */ jsx55(
7311
- ITText,
7312
- {
7313
- as: "span",
7314
- className: `transition-all duration-300 truncate tracking-wide`,
7315
- style: {
7316
- color: item.isActive ? "var(--it-sidebar-active-color, #ffffff)" : "var(--it-sidebar-label-color, var(--color-secondary-300))",
7317
- fontSize: "0.8rem",
7318
- fontWeight: item.isActive ? "600" : "500"
7319
- },
7320
- children: item.label
7321
- }
7322
- )
7323
- ] }),
7324
- !isSidebarCollapsed && item.subitems && item.subitems.length > 0 && /* @__PURE__ */ jsx55(
7325
- "div",
7326
- {
7327
- className: `flex-shrink-0 transition-transform duration-300 ease-[cubic-bezier(0.2,0,0,1)] ${expandedItems.has(item.id) ? "rotate-180" : ""}`,
7328
- style: { color: item.isActive ? "var(--it-sidebar-active-color, var(--color-secondary-900))" : "var(--it-sidebar-icon-color, var(--color-secondary-500))", opacity: 0.7 },
7329
- children: /* @__PURE__ */ jsx55(FaChevronDown4, { className: "w-3 h-3" })
7330
- }
7331
- ),
7332
- item.badge && /* @__PURE__ */ jsx55(
7333
- "span",
7334
- {
7335
- className: `
7336
- absolute flex items-center justify-center font-bold shadow-md
7337
- ${isSidebarCollapsed ? "top-1 right-1 w-2.5 h-2.5 rounded-full ring-2 ring-white" : "right-3 top-1/2 transform -translate-y-1/2 px-1.5 py-0 text-[9px] rounded-full backdrop-blur-sm"}
7338
- `,
7339
- style: {
7340
- backgroundColor: "var(--it-sidebar-badge-bg, var(--color-primary-500))",
7341
- color: "var(--it-sidebar-badge-color, #ffffff)",
7342
- boxShadow: isSidebarCollapsed ? "0 0 0 2px var(--it-sidebar-bg, var(--color-secondary-900))" : "none"
7343
- },
7344
- children: isSidebarCollapsed ? "" : item.badge
7345
- }
7346
- )
7347
- ]
7348
- }
7349
- ),
7350
- isSidebarCollapsed && /* @__PURE__ */ jsxs43(
7351
- "div",
7352
- {
7353
- 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)]",
7354
- style: {
7355
- backgroundColor: "var(--it-sidebar-bg, #ffffff)",
7356
- border: "1px solid var(--it-sidebar-border, var(--color-secondary-200))",
7357
- WebkitBackdropFilter: "blur(16px)",
7358
- backdropFilter: "blur(16px)"
7359
- },
7360
- children: [
7361
- /* @__PURE__ */ jsxs43("div", { className: "px-5 py-4 flex items-center gap-3 font-semibold border-b", style: { borderColor: "var(--it-sidebar-border, var(--color-secondary-200))", color: "var(--it-sidebar-active-color, var(--color-secondary-900))" }, children: [
7362
- item.icon && /* @__PURE__ */ jsx55("span", { style: { color: "var(--it-sidebar-active-icon, var(--color-primary-500))" }, className: "text-xl drop-shadow-sm", children: item.icon }),
7363
- /* @__PURE__ */ jsx55(ITText, { as: "span", className: "tracking-wide text-[15px]", children: item.label })
7364
- ] }),
7365
- item.subitems && item.subitems.length > 0 ? /* @__PURE__ */ jsx55("div", { className: "py-2", children: item.subitems.map((subitem) => /* @__PURE__ */ jsxs43(
7366
- "div",
7367
- {
7368
- className: `px-5 py-2.5 text-sm flex items-center gap-3 transition-colors relative`,
7369
- children: [
7370
- subitem.isActive && subitemConnector === "|" && /* @__PURE__ */ jsx55(
7371
- "div",
7372
- {
7373
- className: "absolute left-0 top-1/3 bottom-1/3 w-[2.5px] rounded-r-full",
7374
- style: {
7375
- backgroundColor: "var(--it-sidebar-active-icon, var(--color-primary-500))",
7376
- boxShadow: "0 0 6px color-mix(in srgb, var(--it-sidebar-active-icon, var(--color-primary-500)) 25%, transparent)"
7377
- }
7378
- }
7379
- ),
7380
- /* @__PURE__ */ jsx55("span", { className: `w-1.5 h-1.5 rounded-full transition-all ${subitem.isActive ? "scale-125" : ""}`, style: { backgroundColor: subitem.isActive ? "var(--it-sidebar-active-icon, var(--color-primary-500))" : "var(--it-sidebar-icon-color, var(--color-secondary-400))" } }),
7381
- /* @__PURE__ */ jsx55(ITText, { as: "span", style: { color: subitem.isActive ? "var(--it-sidebar-active-color, var(--color-secondary-900))" : "var(--it-sidebar-label-color, var(--color-secondary-600))", fontWeight: subitem.isActive ? 600 : 500 }, children: subitem.label })
7382
- ]
7383
- },
7384
- subitem.id
7385
- )) }) : /* @__PURE__ */ jsx55(ITText, { as: "div", className: "px-5 py-3 text-sm italic", style: { color: "var(--it-sidebar-label-color, var(--color-secondary-400))" }, children: "No hay submen\xFA" })
7386
- ]
7387
- }
7388
- ),
7389
- !isSidebarCollapsed && item.subitems && item.subitems.length > 0 && /* @__PURE__ */ jsx55("div", { className: `overflow-hidden transition-all duration-400 ease-[cubic-bezier(0.2,0,0,1)] ${expandedItems.has(item.id) ? "max-h-[500px] opacity-100 mt-1" : "max-h-0 opacity-0"}`, children: /* @__PURE__ */ jsx55(
7390
- "ul",
7391
- {
7392
- className: "ml-4 flex flex-col gap-0 py-0.5",
7393
- style: {
7394
- borderLeft: subitemConnector === "|" ? "1px solid var(--it-sidebar-border, var(--color-secondary-200))" : "none"
7395
- },
7396
- children: item.subitems.map((subitem) => /* @__PURE__ */ jsx55("li", { className: "relative", children: /* @__PURE__ */ jsxs43(
7397
- "button",
7398
- {
7399
- onClick: () => {
7400
- if (subitem.action) subitem.action();
7401
- if (onSubItemClick) onSubItemClick(subitem);
7402
- },
7403
- className: `flex items-center gap-2 w-full text-left px-3 py-1.5 rounded-xl transition-all duration-300`,
7404
7529
  style: {
7405
- color: subitem.isActive ? "var(--it-sidebar-active-color, var(--color-secondary-900))" : "var(--it-sidebar-label-color, var(--color-secondary-600))",
7406
- backgroundColor: subitem.isActive ? "var(--it-sidebar-active-bg, var(--color-secondary-50))" : "transparent",
7407
- fontSize: "0.78rem",
7408
- fontWeight: subitem.isActive ? 600 : 500,
7409
- letterSpacing: "0.01em",
7410
- marginLeft: subitemConnector === "|" ? "-1px" : "0"
7530
+ backgroundColor: item.isActive ? "var(--it-sidebar-active-bg, var(--color-secondary-50))" : "transparent",
7531
+ boxShadow: item.isActive ? "var(--shadow-xs)" : "none",
7532
+ border: item.isActive ? "1px solid var(--it-sidebar-border, var(--color-secondary-200))" : "1px solid transparent"
7411
7533
  },
7412
7534
  onMouseEnter: (e) => {
7413
- if (!subitem.isActive) {
7414
- e.currentTarget.style.backgroundColor = "var(--it-sidebar-hover-bg, var(--color-secondary-100))";
7415
- e.currentTarget.style.transform = "translateX(3px)";
7416
- }
7535
+ if (!item.isActive) e.currentTarget.style.backgroundColor = "var(--it-sidebar-hover-bg, var(--color-secondary-100))";
7417
7536
  },
7418
7537
  onMouseLeave: (e) => {
7419
- if (!subitem.isActive) {
7420
- e.currentTarget.style.backgroundColor = "transparent";
7421
- e.currentTarget.style.transform = "translateX(0)";
7538
+ if (!item.isActive) e.currentTarget.style.backgroundColor = "transparent";
7539
+ },
7540
+ onClick: () => handleItemClick(item),
7541
+ onKeyDown: (e) => {
7542
+ if (e.key === "Enter" || e.key === " ") {
7543
+ e.preventDefault();
7544
+ handleItemClick(item);
7422
7545
  }
7423
7546
  },
7424
7547
  children: [
7425
- subitem.isActive && subitemConnector === "|" && /* @__PURE__ */ jsx55(
7548
+ item.isActive && !isSidebarCollapsed && /* @__PURE__ */ jsx55(
7426
7549
  "div",
7427
7550
  {
7428
- className: "absolute left-0 top-1/3 bottom-1/3 w-[2.5px] rounded-r-full transition-all",
7429
- style: {
7430
- backgroundColor: "var(--it-sidebar-active-icon, var(--color-primary-500))",
7431
- boxShadow: "0 0 6px color-mix(in srgb, var(--it-sidebar-active-icon, var(--color-primary-500)) 25%, transparent)"
7551
+ className: "absolute left-0 top-1/4 bottom-1/4 w-[3px] rounded-r-full transition-all",
7552
+ style: { backgroundColor: "var(--it-sidebar-active-icon, var(--color-primary-500))", boxShadow: "0 0 10px var(--it-sidebar-active-icon, var(--color-primary-500))" }
7553
+ }
7554
+ ),
7555
+ /* @__PURE__ */ jsxs43("div", { className: `flex items-center ${!isSidebarCollapsed ? "gap-2.5" : "justify-center"} relative z-10 w-full`, children: [
7556
+ item.icon && /* @__PURE__ */ jsx55(
7557
+ "div",
7558
+ {
7559
+ className: `transition-all duration-300 flex-shrink-0 flex items-center justify-center`,
7560
+ style: {
7561
+ color: item.isActive ? "var(--it-sidebar-active-icon, var(--color-primary-500))" : "var(--it-sidebar-icon-color, #9ca3af)",
7562
+ opacity: item.isActive ? 1 : 0.8,
7563
+ fontSize: item.isActive ? "1.12rem" : "1.05rem",
7564
+ filter: item.isActive ? "drop-shadow(0 0 8px rgba(255,255,255,0.2))" : "none"
7565
+ },
7566
+ children: item.icon
7567
+ }
7568
+ ),
7569
+ !isSidebarCollapsed && /* @__PURE__ */ jsx55(
7570
+ ITText,
7571
+ {
7572
+ as: "span",
7573
+ className: `transition-all duration-300 truncate tracking-wide`,
7574
+ style: {
7575
+ color: item.isActive ? "var(--it-sidebar-active-color, #ffffff)" : "var(--it-sidebar-label-color, var(--color-secondary-300))",
7576
+ fontSize: "0.8rem",
7577
+ fontWeight: item.isActive ? "600" : "500"
7578
+ },
7579
+ children: item.label
7432
7580
  }
7581
+ )
7582
+ ] }),
7583
+ !isSidebarCollapsed && item.subitems && item.subitems.length > 0 && /* @__PURE__ */ jsx55(
7584
+ "div",
7585
+ {
7586
+ className: `flex-shrink-0 transition-transform duration-300 ease-[cubic-bezier(0.2,0,0,1)] ${expandedItems.has(item.id) ? "rotate-180" : ""}`,
7587
+ style: { color: item.isActive ? "var(--it-sidebar-active-color, var(--color-secondary-900))" : "var(--it-sidebar-icon-color, var(--color-secondary-500))", opacity: 0.7 },
7588
+ children: /* @__PURE__ */ jsx55(FaChevronDown4, { className: "w-3 h-3" })
7433
7589
  }
7434
7590
  ),
7435
- subitemConnector === "dot" && /* @__PURE__ */ jsx55(
7591
+ item.badge && /* @__PURE__ */ jsx55(
7436
7592
  "span",
7437
7593
  {
7438
- className: `w-1.5 h-1.5 rounded-full flex-shrink-0 transition-all duration-300 ${subitem.isActive ? "scale-125" : ""}`,
7594
+ className: `
7595
+ absolute flex items-center justify-center font-bold shadow-md
7596
+ ${isSidebarCollapsed ? "top-1 right-1 w-2.5 h-2.5 rounded-full ring-2 ring-white" : "right-3 top-1/2 transform -translate-y-1/2 px-1.5 py-0 text-[9px] rounded-full backdrop-blur-sm"}
7597
+ `,
7439
7598
  style: {
7440
- backgroundColor: subitem.isActive ? "var(--it-sidebar-active-icon, var(--color-primary-500))" : "var(--it-sidebar-icon-color, var(--color-secondary-400))"
7441
- }
7599
+ backgroundColor: "var(--it-sidebar-badge-bg, var(--color-primary-500))",
7600
+ color: "var(--it-sidebar-badge-color, #ffffff)",
7601
+ boxShadow: isSidebarCollapsed ? "0 0 0 2px var(--it-sidebar-bg, var(--color-secondary-900))" : "none"
7602
+ },
7603
+ children: isSidebarCollapsed ? "" : item.badge
7442
7604
  }
7443
- ),
7444
- /* @__PURE__ */ jsx55(ITText, { as: "span", className: "truncate", children: subitem.label })
7605
+ )
7445
7606
  ]
7446
7607
  }
7447
- ) }, subitem.id))
7448
- }
7449
- ) })
7450
- ] }, item.id)) }) })
7608
+ ),
7609
+ isSidebarCollapsed && /* @__PURE__ */ jsxs43(
7610
+ "div",
7611
+ {
7612
+ 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)]",
7613
+ style: {
7614
+ backgroundColor: "var(--it-sidebar-bg, #ffffff)",
7615
+ border: "1px solid var(--it-sidebar-border, var(--color-secondary-200))",
7616
+ WebkitBackdropFilter: "blur(16px)",
7617
+ backdropFilter: "blur(16px)"
7618
+ },
7619
+ children: [
7620
+ /* @__PURE__ */ jsxs43("div", { className: "px-5 py-4 flex items-center gap-3 font-semibold border-b", style: { borderColor: "var(--it-sidebar-border, var(--color-secondary-200))", color: "var(--it-sidebar-active-color, var(--color-secondary-900))" }, children: [
7621
+ item.icon && /* @__PURE__ */ jsx55("span", { style: { color: "var(--it-sidebar-active-icon, var(--color-primary-500))" }, className: "text-xl drop-shadow-sm", children: item.icon }),
7622
+ /* @__PURE__ */ jsx55(ITText, { as: "span", className: "tracking-wide text-[15px]", children: item.label })
7623
+ ] }),
7624
+ item.subitems && item.subitems.length > 0 ? /* @__PURE__ */ jsx55("div", { className: "py-2", children: item.subitems.map((subitem) => /* @__PURE__ */ jsxs43(
7625
+ "div",
7626
+ {
7627
+ className: `px-5 py-2.5 text-sm flex items-center gap-3 transition-colors relative`,
7628
+ children: [
7629
+ subitem.isActive && subitemConnector === "|" && /* @__PURE__ */ jsx55(
7630
+ "div",
7631
+ {
7632
+ className: "absolute left-0 top-1/3 bottom-1/3 w-[2.5px] rounded-r-full",
7633
+ style: {
7634
+ backgroundColor: "var(--it-sidebar-active-icon, var(--color-primary-500))",
7635
+ boxShadow: "0 0 6px color-mix(in srgb, var(--it-sidebar-active-icon, var(--color-primary-500)) 25%, transparent)"
7636
+ }
7637
+ }
7638
+ ),
7639
+ /* @__PURE__ */ jsx55("span", { className: `w-1.5 h-1.5 rounded-full transition-all ${subitem.isActive ? "scale-125" : ""}`, style: { backgroundColor: subitem.isActive ? "var(--it-sidebar-active-icon, var(--color-primary-500))" : "var(--it-sidebar-icon-color, var(--color-secondary-400))" } }),
7640
+ /* @__PURE__ */ jsx55(ITText, { as: "span", style: { color: subitem.isActive ? "var(--it-sidebar-active-color, var(--color-secondary-900))" : "var(--it-sidebar-label-color, var(--color-secondary-600))", fontWeight: subitem.isActive ? 600 : 500 }, children: subitem.label })
7641
+ ]
7642
+ },
7643
+ subitem.id
7644
+ )) }) : /* @__PURE__ */ jsx55(ITText, { as: "div", className: "px-5 py-3 text-sm italic", style: { color: "var(--it-sidebar-label-color, var(--color-secondary-400))" }, children: "No hay submen\xFA" })
7645
+ ]
7646
+ }
7647
+ ),
7648
+ !isSidebarCollapsed && item.subitems && item.subitems.length > 0 && /* @__PURE__ */ jsx55("div", { id: submenuId, role: "group", "aria-label": item.label, className: `overflow-hidden transition-all duration-400 ease-[cubic-bezier(0.2,0,0,1)] ${expandedItems.has(item.id) ? "max-h-[500px] opacity-100 mt-1" : "max-h-0 opacity-0"}`, children: /* @__PURE__ */ jsx55(
7649
+ "ul",
7650
+ {
7651
+ className: "ml-4 flex flex-col gap-0 py-0.5",
7652
+ style: {
7653
+ borderLeft: subitemConnector === "|" ? "1px solid var(--it-sidebar-border, var(--color-secondary-200))" : "none"
7654
+ },
7655
+ children: item.subitems.map((subitem) => /* @__PURE__ */ jsx55("li", { className: "relative", children: /* @__PURE__ */ jsxs43(
7656
+ "button",
7657
+ {
7658
+ "aria-current": subitem.isActive ? "page" : void 0,
7659
+ onClick: () => {
7660
+ if (subitem.action) subitem.action();
7661
+ if (onSubItemClick) onSubItemClick(subitem);
7662
+ },
7663
+ className: `flex items-center gap-2 w-full text-left px-3 py-1.5 rounded-xl transition-all duration-300`,
7664
+ style: {
7665
+ color: subitem.isActive ? "var(--it-sidebar-active-color, var(--color-secondary-900))" : "var(--it-sidebar-label-color, var(--color-secondary-600))",
7666
+ backgroundColor: subitem.isActive ? "var(--it-sidebar-active-bg, var(--color-secondary-50))" : "transparent",
7667
+ fontSize: "0.78rem",
7668
+ fontWeight: subitem.isActive ? 600 : 500,
7669
+ letterSpacing: "0.01em",
7670
+ marginLeft: subitemConnector === "|" ? "-1px" : "0"
7671
+ },
7672
+ onMouseEnter: (e) => {
7673
+ if (!subitem.isActive) {
7674
+ e.currentTarget.style.backgroundColor = "var(--it-sidebar-hover-bg, var(--color-secondary-100))";
7675
+ e.currentTarget.style.transform = "translateX(3px)";
7676
+ }
7677
+ },
7678
+ onMouseLeave: (e) => {
7679
+ if (!subitem.isActive) {
7680
+ e.currentTarget.style.backgroundColor = "transparent";
7681
+ e.currentTarget.style.transform = "translateX(0)";
7682
+ }
7683
+ },
7684
+ children: [
7685
+ subitem.isActive && subitemConnector === "|" && /* @__PURE__ */ jsx55(
7686
+ "div",
7687
+ {
7688
+ className: "absolute left-0 top-1/3 bottom-1/3 w-[2.5px] rounded-r-full transition-all",
7689
+ style: {
7690
+ backgroundColor: "var(--it-sidebar-active-icon, var(--color-primary-500))",
7691
+ boxShadow: "0 0 6px color-mix(in srgb, var(--it-sidebar-active-icon, var(--color-primary-500)) 25%, transparent)"
7692
+ }
7693
+ }
7694
+ ),
7695
+ subitemConnector === "dot" && /* @__PURE__ */ jsx55(
7696
+ "span",
7697
+ {
7698
+ className: `w-1.5 h-1.5 rounded-full flex-shrink-0 transition-all duration-300 ${subitem.isActive ? "scale-125" : ""}`,
7699
+ style: {
7700
+ backgroundColor: subitem.isActive ? "var(--it-sidebar-active-icon, var(--color-primary-500))" : "var(--it-sidebar-icon-color, var(--color-secondary-400))"
7701
+ }
7702
+ }
7703
+ ),
7704
+ /* @__PURE__ */ jsx55(ITText, { as: "span", className: "truncate", children: subitem.label })
7705
+ ]
7706
+ }
7707
+ ) }, subitem.id))
7708
+ }
7709
+ ) })
7710
+ ] }, item.id);
7711
+ }) }) })
7712
+ ]
7451
7713
  }
7452
7714
  );
7453
7715
  }
7454
7716
 
7455
7717
  // src/components/atoms/slide/slide.tsx
7456
- import { useState as useState26, useEffect as useEffect14 } from "react";
7718
+ import { useState as useState28, useEffect as useEffect14 } from "react";
7457
7719
  import clsx40 from "clsx";
7458
7720
  import { jsx as jsx56 } from "react/jsx-runtime";
7459
7721
  function ITSlideToggle({
@@ -7468,7 +7730,7 @@ function ITSlideToggle({
7468
7730
  className = ""
7469
7731
  }) {
7470
7732
  const isControlled = controlledIsOn !== void 0;
7471
- const [internalIsOn, setInternalIsOn] = useState26(initialState);
7733
+ const [internalIsOn, setInternalIsOn] = useState28(initialState);
7472
7734
  useEffect14(() => {
7473
7735
  if (isControlled) {
7474
7736
  setInternalIsOn(controlledIsOn);
@@ -7633,7 +7895,7 @@ function ITStatCard({
7633
7895
 
7634
7896
  // src/components/molecules/table/table.tsx
7635
7897
  import clsx43 from "clsx";
7636
- import React11, { useState as useState27 } from "react";
7898
+ import React11, { useState as useState29 } from "react";
7637
7899
  import {
7638
7900
  FaCheck as FaCheck4,
7639
7901
  FaSpinner as FaSpinner3,
@@ -7642,7 +7904,7 @@ import {
7642
7904
  FaThLarge as FaThLarge2
7643
7905
  } from "react-icons/fa";
7644
7906
  import { MdOutlineSwapVert as MdOutlineSwapVert2 } from "react-icons/md";
7645
- import { jsx as jsx59, jsxs as jsxs46 } from "react/jsx-runtime";
7907
+ import { Fragment as Fragment9, jsx as jsx59, jsxs as jsxs46 } from "react/jsx-runtime";
7646
7908
  function ITTable({
7647
7909
  columns,
7648
7910
  data = [],
@@ -7655,9 +7917,24 @@ function ITTable({
7655
7917
  renderCard,
7656
7918
  defaultView = "table",
7657
7919
  showVerticalBorder = true,
7658
- verticalBorderClassname
7920
+ verticalBorderClassname,
7921
+ onRowClick,
7922
+ layout = "auto",
7923
+ density = "normal",
7924
+ autoCardBreakpoint = 0,
7925
+ virtualized = false,
7926
+ virtualizedMaxHeight = 400,
7927
+ rowHeight,
7928
+ overscan = 5,
7929
+ stickyHeader = false
7659
7930
  }) {
7660
- const [viewMode, setViewMode] = useState27(defaultView);
7931
+ const [viewMode, setViewMode] = useState29(defaultView);
7932
+ const { ref: rootRef, width: containerWidth } = useElementSize();
7933
+ const isFixed = layout === "fixed";
7934
+ const forcedCards = autoCardBreakpoint > 0 && containerWidth > 0 && containerWidth < autoCardBreakpoint;
7935
+ const effectiveView = forcedCards ? "cards" : viewMode;
7936
+ const hasColumnWidths = columns.some((col) => col.width != null);
7937
+ const tableLayoutClass = isFixed ? "w-full text-sm text-left text-secondary-600" : "min-w-max w-full text-sm text-left text-secondary-600";
7661
7938
  const {
7662
7939
  currentPage,
7663
7940
  itemsPerPage,
@@ -7737,6 +8014,24 @@ function ITTable({
7737
8014
  (currentPage - 1) * itemsPerPage,
7738
8015
  currentPage * itemsPerPage
7739
8016
  );
8017
+ const isTableVirtual = virtualized && effectiveView === "table";
8018
+ const isStickyHeader = stickyHeader && isTableVirtual;
8019
+ const resolvedRowHeight = rowHeight ?? getRowHeight(size, density);
8020
+ const columnCount = columns.length;
8021
+ const {
8022
+ scrollRef,
8023
+ startIndex,
8024
+ endIndex,
8025
+ topSpacerHeight,
8026
+ bottomSpacerHeight
8027
+ } = useVirtualRows({
8028
+ count: currentData.length,
8029
+ rowHeight: resolvedRowHeight,
8030
+ overscan,
8031
+ enabled: isTableVirtual,
8032
+ resetKey: `${currentPage}-${itemsPerPage}`
8033
+ });
8034
+ const windowData = isTableVirtual ? currentData.slice(startIndex, endIndex + 1) : currentData;
7740
8035
  const renderFilterInput = (col) => {
7741
8036
  if (!col.filter) return null;
7742
8037
  if (col.type === "boolean") {
@@ -7868,7 +8163,18 @@ function ITTable({
7868
8163
  actionCol?.actions && /* @__PURE__ */ jsx59("div", { className: "flex items-center justify-end gap-2 pt-2 border-t border-slate-100 dark:border-slate-700", children: actionCol.actions(row) })
7869
8164
  ] });
7870
8165
  };
7871
- return /* @__PURE__ */ jsx59("div", { className: clsx43("space-y-4 w-full", containerClassName), children: /* @__PURE__ */ jsxs46("div", { className: tableContainer, style: { backgroundColor: "var(--color-table-rowBg, #ffffff)" }, children: [
8166
+ const handleRowClick = (row) => (event) => {
8167
+ if (!onRowClick || isInteractiveTarget(event.target, event.currentTarget)) return;
8168
+ onRowClick(row, event);
8169
+ };
8170
+ const handleRowKeyDown = (row) => (event) => {
8171
+ if (!onRowClick) return;
8172
+ if (event.target !== event.currentTarget) return;
8173
+ if (event.key !== "Enter" && event.key !== " ") return;
8174
+ event.preventDefault();
8175
+ onRowClick(row, event);
8176
+ };
8177
+ return /* @__PURE__ */ jsx59("div", { ref: rootRef, className: clsx43("space-y-4 w-full", containerClassName), children: /* @__PURE__ */ jsxs46("div", { className: tableContainer, style: { backgroundColor: "var(--color-table-rowBg, #ffffff)" }, children: [
7872
8178
  title && /* @__PURE__ */ jsxs46("div", { className: "px-6 py-5 flex items-center justify-between", style: { backgroundColor: "var(--color-table-rowBg, #ffffff)" }, children: [
7873
8179
  /* @__PURE__ */ jsx59(ITText, { as: "h2", className: "text-xl font-bold text-secondary-900 leading-tight", children: title }),
7874
8180
  /* @__PURE__ */ jsxs46("div", { className: "flex items-center bg-slate-100 dark:bg-slate-800/80 rounded-lg p-0.5 border border-slate-200 dark:border-slate-700/50", children: [
@@ -7876,7 +8182,8 @@ function ITTable({
7876
8182
  "button",
7877
8183
  {
7878
8184
  onClick: () => setViewMode("table"),
7879
- className: `flex items-center gap-1.5 px-3 py-1.5 rounded-md text-xs font-semibold transition-all ${viewMode === "table" ? "bg-white dark:bg-slate-900 text-slate-900 dark:text-white shadow-sm border border-slate-200/50 dark:border-slate-700" : "text-slate-500 dark:text-slate-400 hover:text-slate-700 dark:hover:text-slate-200"}`,
8185
+ disabled: forcedCards,
8186
+ className: `flex items-center gap-1.5 px-3 py-1.5 rounded-md text-xs font-semibold transition-all ${effectiveView === "table" ? "bg-white dark:bg-slate-900 text-slate-900 dark:text-white shadow-sm border border-slate-200/50 dark:border-slate-700" : "text-slate-500 dark:text-slate-400 hover:text-slate-700 dark:hover:text-slate-200"}`,
7880
8187
  children: [
7881
8188
  /* @__PURE__ */ jsx59(FaTable2, { size: 11 }),
7882
8189
  "Table"
@@ -7887,7 +8194,7 @@ function ITTable({
7887
8194
  "button",
7888
8195
  {
7889
8196
  onClick: () => setViewMode("cards"),
7890
- className: `flex items-center gap-1.5 px-3 py-1.5 rounded-md text-xs font-semibold transition-all ${viewMode === "cards" ? "bg-white dark:bg-slate-900 text-slate-900 dark:text-white shadow-sm border border-slate-200/50 dark:border-slate-700" : "text-slate-500 dark:text-slate-400 hover:text-slate-700 dark:hover:text-slate-200"}`,
8197
+ className: `flex items-center gap-1.5 px-3 py-1.5 rounded-md text-xs font-semibold transition-all ${effectiveView === "cards" ? "bg-white dark:bg-slate-900 text-slate-900 dark:text-white shadow-sm border border-slate-200/50 dark:border-slate-700" : "text-slate-500 dark:text-slate-400 hover:text-slate-700 dark:hover:text-slate-200"}`,
7891
8198
  children: [
7892
8199
  /* @__PURE__ */ jsx59(FaThLarge2, { size: 11 }),
7893
8200
  "Cards"
@@ -7901,7 +8208,8 @@ function ITTable({
7901
8208
  "button",
7902
8209
  {
7903
8210
  onClick: () => setViewMode("table"),
7904
- className: `flex items-center gap-1.5 px-3 py-1.5 rounded-md text-xs font-semibold transition-all ${viewMode === "table" ? "bg-white dark:bg-slate-900 text-slate-900 dark:text-white shadow-sm border border-slate-200/50 dark:border-slate-700" : "text-slate-500 dark:text-slate-400 hover:text-slate-700 dark:hover:text-slate-200"}`,
8211
+ disabled: forcedCards,
8212
+ className: `flex items-center gap-1.5 px-3 py-1.5 rounded-md text-xs font-semibold transition-all ${effectiveView === "table" ? "bg-white dark:bg-slate-900 text-slate-900 dark:text-white shadow-sm border border-slate-200/50 dark:border-slate-700" : "text-slate-500 dark:text-slate-400 hover:text-slate-700 dark:hover:text-slate-200"}`,
7905
8213
  children: [
7906
8214
  /* @__PURE__ */ jsx59(FaTable2, { size: 11 }),
7907
8215
  "Table"
@@ -7912,7 +8220,7 @@ function ITTable({
7912
8220
  "button",
7913
8221
  {
7914
8222
  onClick: () => setViewMode("cards"),
7915
- className: `flex items-center gap-1.5 px-3 py-1.5 rounded-md text-xs font-semibold transition-all ${viewMode === "cards" ? "bg-white dark:bg-slate-900 text-slate-900 dark:text-white shadow-sm border border-slate-200/50 dark:border-slate-700" : "text-slate-500 dark:text-slate-400 hover:text-slate-700 dark:hover:text-slate-200"}`,
8223
+ className: `flex items-center gap-1.5 px-3 py-1.5 rounded-md text-xs font-semibold transition-all ${effectiveView === "cards" ? "bg-white dark:bg-slate-900 text-slate-900 dark:text-white shadow-sm border border-slate-200/50 dark:border-slate-700" : "text-slate-500 dark:text-slate-400 hover:text-slate-700 dark:hover:text-slate-200"}`,
7916
8224
  children: [
7917
8225
  /* @__PURE__ */ jsx59(FaThLarge2, { size: 11 }),
7918
8226
  "Cards"
@@ -7920,64 +8228,131 @@ function ITTable({
7920
8228
  }
7921
8229
  )
7922
8230
  ] }) }),
7923
- viewMode === "cards" ? /* @__PURE__ */ jsx59("div", { className: "p-4 space-y-3 max-h-[400px] overflow-y-auto", children: currentData.length > 0 ? currentData.map((row, i) => /* @__PURE__ */ jsx59("div", { children: renderCard ? renderCard(row) : renderDefaultCard(row) }, i)) : /* @__PURE__ */ jsxs46("div", { className: clsx43(tableEmptyContent, "py-12"), children: [
8231
+ effectiveView === "cards" ? /* @__PURE__ */ jsx59("div", { className: "p-4 space-y-3 max-h-[400px] overflow-y-auto", children: currentData.length > 0 ? currentData.map((row, i) => /* @__PURE__ */ jsx59(
8232
+ "div",
8233
+ {
8234
+ className: clsx43(onRowClick && tableCardClickable),
8235
+ role: onRowClick ? "button" : void 0,
8236
+ tabIndex: onRowClick ? 0 : void 0,
8237
+ onClick: onRowClick ? handleRowClick(row) : void 0,
8238
+ onKeyDown: onRowClick ? handleRowKeyDown(row) : void 0,
8239
+ children: renderCard ? renderCard(row) : renderDefaultCard(row)
8240
+ },
8241
+ i
8242
+ )) : /* @__PURE__ */ jsxs46("div", { className: clsx43(tableEmptyContent, "py-12"), children: [
7924
8243
  /* @__PURE__ */ jsx59(ITText, { as: "span", className: "text-lg", children: "No se encontraron resultados" }),
7925
8244
  /* @__PURE__ */ jsx59(ITText, { as: "span", className: "text-sm mt-1", children: "Intenta ajustar los filtros" })
7926
- ] }) }) : /* @__PURE__ */ jsx59("div", { className: "overflow-x-auto", children: /* @__PURE__ */ jsxs46(
7927
- "table",
8245
+ ] }) }) : /* @__PURE__ */ jsx59(
8246
+ "div",
7928
8247
  {
7929
- className: clsx43(
7930
- "min-w-max w-full text-sm text-left text-secondary-600",
7931
- showVerticalBorder && "[&_th]:border-r [&_th:last-child]:border-r-0 [&_td]:border-r [&_td:last-child]:border-r-0",
7932
- showVerticalBorder && (verticalBorderClassname || "[&_th]:border-slate-100 dark:[&_th]:border-slate-700/30 [&_td]:border-slate-100 dark:[&_td]:border-slate-700/30"),
7933
- variantStyles[variant],
7934
- sizeStyles[size]
7935
- ),
7936
- children: [
7937
- /* @__PURE__ */ jsx59("thead", { children: /* @__PURE__ */ jsx59("tr", { className: clsx43(tableHeaderRow, "dark:text-slate-200"), children: columns.map((col) => /* @__PURE__ */ jsx59(
7938
- "th",
7939
- {
7940
- scope: "col",
7941
- className: tableHeaderCell(col.className),
7942
- children: /* @__PURE__ */ jsxs46("div", { className: "flex flex-col gap-3 min-w-[150px]", children: [
7943
- /* @__PURE__ */ jsxs46("div", { className: "flex items-center justify-between gap-2", children: [
7944
- /* @__PURE__ */ jsx59(ITText, { as: "span", className: "text-slate-900 dark:text-white font-bold", children: col.label }),
7945
- col.sortable && col.type !== "actions" && /* @__PURE__ */ jsx59(
7946
- "button",
7947
- {
7948
- onClick: () => handleSort(col.key),
7949
- className: `p-1 rounded-md transition-colors ${sortConfig?.key === col.key ? "bg-secondary-200 text-secondary-900" : "hover:bg-secondary-200 text-secondary-400 hover:text-secondary-700"}`,
7950
- title: `Ordenar por ${col.label}`,
7951
- children: /* @__PURE__ */ jsx59(MdOutlineSwapVert2, { className: "w-4 h-4", "aria-hidden": "true" })
7952
- }
7953
- )
7954
- ] }),
7955
- /* @__PURE__ */ jsx59("div", { className: "w-full", children: col.filter ? renderFilterInput(col) : null })
7956
- ] })
7957
- },
7958
- col.key
7959
- )) }) }),
7960
- /* @__PURE__ */ jsx59("tbody", { className: clsx43(tableBody, "dark:divide-slate-700/30"), children: currentData.length > 0 ? currentData.map((row, rowIndex) => /* @__PURE__ */ jsx59(
7961
- "tr",
7962
- {
7963
- className: clsx43(tableRow, variant === "striped" && "odd:bg-secondary-50/40 dark:odd:bg-slate-800/20"),
7964
- children: columns.map((col) => /* @__PURE__ */ jsx59(
7965
- "td",
8248
+ ref: isTableVirtual ? scrollRef : void 0,
8249
+ className: isTableVirtual ? "overflow-x-auto overflow-y-auto" : "overflow-x-auto",
8250
+ style: isTableVirtual ? { maxHeight: virtualizedMaxHeight } : void 0,
8251
+ children: /* @__PURE__ */ jsxs46(
8252
+ "table",
8253
+ {
8254
+ className: clsx43(
8255
+ tableLayoutClass,
8256
+ showVerticalBorder && "[&_th]:border-r [&_th:last-child]:border-r-0 [&_td]:border-r [&_td:last-child]:border-r-0",
8257
+ showVerticalBorder && (verticalBorderClassname || "[&_th]:border-slate-100 dark:[&_th]:border-slate-700/30 [&_td]:border-slate-100 dark:[&_td]:border-slate-700/30"),
8258
+ variantStyles[variant],
8259
+ sizeStyles[size]
8260
+ ),
8261
+ style: isFixed ? { tableLayout: "fixed" } : void 0,
8262
+ "aria-rowcount": isTableVirtual ? currentData.length + 1 : void 0,
8263
+ children: [
8264
+ hasColumnWidths && /* @__PURE__ */ jsx59("colgroup", { children: columns.map((col) => /* @__PURE__ */ jsx59(
8265
+ "col",
7966
8266
  {
7967
- className: tableCell(col.className),
7968
- children: col.type === "actions" ? /* @__PURE__ */ jsx59("div", { className: tableActionsCell, children: renderCellContent(col, row) }) : /* @__PURE__ */ jsx59("div", { className: tableCellText, children: renderCellContent(col, row) })
8267
+ style: col.width != null ? { width: typeof col.width === "number" ? `${col.width}px` : col.width } : void 0
7969
8268
  },
7970
- `${rowIndex}-${col.key}`
7971
- ))
7972
- },
7973
- rowIndex
7974
- )) : /* @__PURE__ */ jsx59("tr", { children: /* @__PURE__ */ jsx59("td", { colSpan: columns.length, className: "px-6 py-12 text-center", children: /* @__PURE__ */ jsxs46("div", { className: tableEmptyContent, children: [
7975
- /* @__PURE__ */ jsx59(ITText, { as: "span", className: "text-lg", children: "No se encontraron resultados" }),
7976
- /* @__PURE__ */ jsx59(ITText, { as: "span", className: "text-sm mt-1", children: "Intenta ajustar los filtros" })
7977
- ] }) }) }) })
7978
- ]
8269
+ col.key
8270
+ )) }),
8271
+ /* @__PURE__ */ jsx59("thead", { children: /* @__PURE__ */ jsx59(
8272
+ "tr",
8273
+ {
8274
+ className: clsx43(tableHeaderRow, "dark:text-slate-200"),
8275
+ "aria-rowindex": isTableVirtual ? 1 : void 0,
8276
+ children: columns.map((col) => /* @__PURE__ */ jsx59(
8277
+ "th",
8278
+ {
8279
+ scope: "col",
8280
+ className: clsx43(
8281
+ tableHeaderCell(col.className, density),
8282
+ col.align && tableAlignClasses[col.align],
8283
+ isStickyHeader && "sticky top-0 z-10 bg-secondary-50"
8284
+ ),
8285
+ style: col.minWidth != null || isStickyHeader ? {
8286
+ ...col.minWidth != null ? { minWidth: `${col.minWidth}px` } : {},
8287
+ ...isStickyHeader ? { backgroundColor: "var(--color-table-headerBg, #f8fafc)" } : {}
8288
+ } : void 0,
8289
+ children: /* @__PURE__ */ jsxs46("div", { className: isFixed ? "flex flex-col gap-3" : "flex flex-col gap-3 min-w-[150px]", children: [
8290
+ /* @__PURE__ */ jsxs46("div", { className: "flex items-center justify-between gap-2", children: [
8291
+ /* @__PURE__ */ jsx59(ITText, { as: "span", className: "text-slate-900 dark:text-white font-bold", children: col.label }),
8292
+ col.sortable && col.type !== "actions" && /* @__PURE__ */ jsx59(
8293
+ "button",
8294
+ {
8295
+ onClick: () => handleSort(col.key),
8296
+ className: `p-1 rounded-md transition-colors ${sortConfig?.key === col.key ? "bg-secondary-200 text-secondary-900" : "hover:bg-secondary-200 text-secondary-400 hover:text-secondary-700"}`,
8297
+ title: `Ordenar por ${col.label}`,
8298
+ children: /* @__PURE__ */ jsx59(MdOutlineSwapVert2, { className: "w-4 h-4", "aria-hidden": "true" })
8299
+ }
8300
+ )
8301
+ ] }),
8302
+ /* @__PURE__ */ jsx59("div", { className: "w-full", children: col.filter ? renderFilterInput(col) : null })
8303
+ ] })
8304
+ },
8305
+ col.key
8306
+ ))
8307
+ }
8308
+ ) }),
8309
+ /* @__PURE__ */ jsx59("tbody", { className: clsx43(tableBody, "dark:divide-slate-700/30"), children: currentData.length > 0 ? /* @__PURE__ */ jsxs46(Fragment9, { children: [
8310
+ isTableVirtual && topSpacerHeight > 0 && /* @__PURE__ */ jsx59("tr", { "aria-hidden": "true", style: { height: topSpacerHeight }, children: /* @__PURE__ */ jsx59("td", { colSpan: columnCount, style: { padding: 0, border: 0 } }) }),
8311
+ windowData.map((row, windowIndex) => {
8312
+ const absoluteIndex = isTableVirtual ? startIndex + windowIndex : windowIndex;
8313
+ return /* @__PURE__ */ jsx59(
8314
+ "tr",
8315
+ {
8316
+ "aria-rowindex": isTableVirtual ? absoluteIndex + 2 : void 0,
8317
+ className: clsx43(
8318
+ tableRow,
8319
+ variant === "striped" && absoluteIndex % 2 === 0 && "bg-secondary-50/40 dark:bg-slate-800/20",
8320
+ onRowClick && tableRowClickable
8321
+ ),
8322
+ tabIndex: onRowClick ? 0 : void 0,
8323
+ onClick: onRowClick ? handleRowClick(row) : void 0,
8324
+ onKeyDown: onRowClick ? handleRowKeyDown(row) : void 0,
8325
+ children: columns.map((col) => {
8326
+ const rawValue = getNestedValue(row, col.key);
8327
+ const truncateTitle = col.truncate && (typeof rawValue === "string" || typeof rawValue === "number") ? String(rawValue) : void 0;
8328
+ return /* @__PURE__ */ jsx59(
8329
+ "td",
8330
+ {
8331
+ className: clsx43(
8332
+ tableCell(col.className, density),
8333
+ col.align && tableAlignClasses[col.align]
8334
+ ),
8335
+ style: col.minWidth != null ? { minWidth: `${col.minWidth}px` } : void 0,
8336
+ title: truncateTitle,
8337
+ children: col.type === "actions" ? /* @__PURE__ */ jsx59("div", { className: tableActionsCell, children: renderCellContent(col, row) }) : /* @__PURE__ */ jsx59("div", { className: clsx43(tableCellText, col.truncate && "truncate"), children: renderCellContent(col, row) })
8338
+ },
8339
+ `${absoluteIndex}-${col.key}`
8340
+ );
8341
+ })
8342
+ },
8343
+ absoluteIndex
8344
+ );
8345
+ }),
8346
+ isTableVirtual && bottomSpacerHeight > 0 && /* @__PURE__ */ jsx59("tr", { "aria-hidden": "true", style: { height: bottomSpacerHeight }, children: /* @__PURE__ */ jsx59("td", { colSpan: columnCount, style: { padding: 0, border: 0 } }) })
8347
+ ] }) : /* @__PURE__ */ jsx59("tr", { children: /* @__PURE__ */ jsx59("td", { colSpan: columns.length, className: "px-6 py-12 text-center", children: /* @__PURE__ */ jsxs46("div", { className: tableEmptyContent, children: [
8348
+ /* @__PURE__ */ jsx59(ITText, { as: "span", className: "text-lg", children: "No se encontraron resultados" }),
8349
+ /* @__PURE__ */ jsx59(ITText, { as: "span", className: "text-sm mt-1", children: "Intenta ajustar los filtros" })
8350
+ ] }) }) }) })
8351
+ ]
8352
+ }
8353
+ )
7979
8354
  }
7980
- ) }),
8355
+ ),
7981
8356
  /* @__PURE__ */ jsx59("div", { className: "rounded-b-xl px-6 py-4", style: { backgroundColor: "var(--color-table-rowBg, #ffffff)" }, children: /* @__PURE__ */ jsx59(
7982
8357
  ITPagination,
7983
8358
  {
@@ -8043,7 +8418,7 @@ function ITTextarea({
8043
8418
  }
8044
8419
 
8045
8420
  // src/components/molecules/tabs/tabs.tsx
8046
- import { useState as useState28 } from "react";
8421
+ import { useState as useState30 } from "react";
8047
8422
  import { clsx as clsx45 } from "clsx";
8048
8423
  import { jsx as jsx61, jsxs as jsxs48 } from "react/jsx-runtime";
8049
8424
  var ITTabs = ({
@@ -8054,7 +8429,7 @@ var ITTabs = ({
8054
8429
  className = "",
8055
8430
  containerClassName = ""
8056
8431
  }) => {
8057
- const [activeId, setActiveId] = useState28(defaultActiveId || items[0]?.id);
8432
+ const [activeId, setActiveId] = useState30(defaultActiveId || items[0]?.id);
8058
8433
  const handleTabClick = (id, disabled) => {
8059
8434
  if (disabled) return;
8060
8435
  setActiveId(id);
@@ -8154,7 +8529,7 @@ var positionStyles = {
8154
8529
 
8155
8530
  // src/components/organisms/toast/toast.tsx
8156
8531
  import clsx47 from "clsx";
8157
- import { useEffect as useEffect15, useState as useState29 } from "react";
8532
+ import { useEffect as useEffect15, useState as useState31 } from "react";
8158
8533
  import { FaTimesCircle as FaTimesCircle2, FaCheckCircle as FaCheckCircle2, FaExclamationTriangle as FaExclamationTriangle3, FaInfoCircle as FaInfoCircle2, FaTimes as FaTimes10 } from "react-icons/fa";
8159
8534
  import { jsx as jsx63, jsxs as jsxs49 } from "react/jsx-runtime";
8160
8535
  function ITToast({
@@ -8164,7 +8539,7 @@ function ITToast({
8164
8539
  position = "top-right",
8165
8540
  onClose
8166
8541
  }) {
8167
- const [isVisible, setIsVisible] = useState29(true);
8542
+ const [isVisible, setIsVisible] = useState31(true);
8168
8543
  useEffect15(() => {
8169
8544
  const timer = setTimeout(() => {
8170
8545
  setIsVisible(false);
@@ -8232,10 +8607,10 @@ function ITToast({
8232
8607
 
8233
8608
  // src/components/molecules/wysiwyg/wysiwyg.tsx
8234
8609
  import {
8235
- useCallback as useCallback8,
8610
+ useCallback as useCallback9,
8236
8611
  useEffect as useEffect16,
8237
- useRef as useRef19,
8238
- useState as useState31
8612
+ useRef as useRef21,
8613
+ useState as useState33
8239
8614
  } from "react";
8240
8615
  import clsx49 from "clsx";
8241
8616
  import {
@@ -8260,7 +8635,7 @@ var toolbarActions = [
8260
8635
  ];
8261
8636
 
8262
8637
  // src/components/atoms/tooltip/tooltip.tsx
8263
- import { useState as useState30 } from "react";
8638
+ import { useState as useState32 } from "react";
8264
8639
  import clsx48 from "clsx";
8265
8640
  import { jsx as jsx64, jsxs as jsxs50 } from "react/jsx-runtime";
8266
8641
  var positionClasses2 = {
@@ -8282,7 +8657,7 @@ function ITTooltip({
8282
8657
  delay = 200,
8283
8658
  className
8284
8659
  }) {
8285
- const [visible, setVisible] = useState30(false);
8660
+ const [visible, setVisible] = useState32(false);
8286
8661
  let timeout;
8287
8662
  const handleMouseEnter = () => {
8288
8663
  timeout = setTimeout(() => setVisible(true), delay);
@@ -8335,12 +8710,12 @@ function ITWysiwyg({
8335
8710
  toolbar = toolbarActions,
8336
8711
  className
8337
8712
  }) {
8338
- const editorRef = useRef19(null);
8339
- const focusedRef = useRef19(false);
8340
- const [active, setActive] = useState31({});
8713
+ const editorRef = useRef21(null);
8714
+ const focusedRef = useRef21(false);
8715
+ const [active, setActive] = useState33({});
8341
8716
  const isLocked = disabled || readOnly;
8342
8717
  const sizeConfig = inputSizeTokens[size] ?? inputSizeTokens.md;
8343
- const findAncestor = useCallback8(
8718
+ const findAncestor = useCallback9(
8344
8719
  (node, predicate) => {
8345
8720
  const editor = editorRef.current;
8346
8721
  if (!editor) return null;
@@ -8353,7 +8728,7 @@ function ITWysiwyg({
8353
8728
  },
8354
8729
  []
8355
8730
  );
8356
- const isInlineTag = useCallback8((el, tag) => {
8731
+ const isInlineTag = useCallback9((el, tag) => {
8357
8732
  if (tag === "STRONG" || tag === "B") {
8358
8733
  return el.tagName === "STRONG" || el.tagName === "B";
8359
8734
  }
@@ -8362,7 +8737,7 @@ function ITWysiwyg({
8362
8737
  }
8363
8738
  return el.tagName === tag;
8364
8739
  }, []);
8365
- const getTextNodesInRange = useCallback8((range) => {
8740
+ const getTextNodesInRange = useCallback9((range) => {
8366
8741
  const editor = editorRef.current;
8367
8742
  if (!editor) return [];
8368
8743
  const out = [];
@@ -8373,7 +8748,7 @@ function ITWysiwyg({
8373
8748
  }
8374
8749
  return out;
8375
8750
  }, []);
8376
- const placeCaretAtEnd = useCallback8((target) => {
8751
+ const placeCaretAtEnd = useCallback9((target) => {
8377
8752
  const editor = editorRef.current;
8378
8753
  const sel = window.getSelection();
8379
8754
  if (!editor || !sel) return;
@@ -8384,11 +8759,11 @@ function ITWysiwyg({
8384
8759
  sel.addRange(range);
8385
8760
  if (document.activeElement !== editor) editor.focus();
8386
8761
  }, []);
8387
- const emitChange = useCallback8(() => {
8762
+ const emitChange = useCallback9(() => {
8388
8763
  const editor = editorRef.current;
8389
8764
  if (editor) onChange?.(editor.innerHTML);
8390
8765
  }, [onChange]);
8391
- const updateActive = useCallback8(() => {
8766
+ const updateActive = useCallback9(() => {
8392
8767
  const editor = editorRef.current;
8393
8768
  const sel = window.getSelection();
8394
8769
  const node = sel?.anchorNode ?? null;
@@ -8407,13 +8782,13 @@ function ITWysiwyg({
8407
8782
  (prev) => JSON.stringify(prev) === JSON.stringify(next) ? prev : next
8408
8783
  );
8409
8784
  }, [findAncestor, isInlineTag]);
8410
- const unwrapElement = useCallback8((el) => {
8785
+ const unwrapElement = useCallback9((el) => {
8411
8786
  const parent = el.parentNode;
8412
8787
  if (!parent) return;
8413
8788
  while (el.firstChild) parent.insertBefore(el.firstChild, el);
8414
8789
  el.remove();
8415
8790
  }, []);
8416
- const applyInline = useCallback8(
8791
+ const applyInline = useCallback9(
8417
8792
  (tag, prepare) => {
8418
8793
  const editor = editorRef.current;
8419
8794
  const sel = window.getSelection();
@@ -8495,7 +8870,7 @@ function ITWysiwyg({
8495
8870
  updateActive
8496
8871
  ]
8497
8872
  );
8498
- const normalizeBlocks = useCallback8(() => {
8873
+ const normalizeBlocks = useCallback9(() => {
8499
8874
  const editor = editorRef.current;
8500
8875
  if (!editor) return;
8501
8876
  const children = Array.from(editor.childNodes);
@@ -8517,7 +8892,7 @@ function ITWysiwyg({
8517
8892
  }
8518
8893
  flush();
8519
8894
  }, []);
8520
- const convertLiToDiv = useCallback8((li) => {
8895
+ const convertLiToDiv = useCallback9((li) => {
8521
8896
  const list = li.parentElement;
8522
8897
  if (!list || !list.parentNode) return;
8523
8898
  const div = document.createElement("div");
@@ -8525,20 +8900,20 @@ function ITWysiwyg({
8525
8900
  list.parentNode.insertBefore(div, list);
8526
8901
  li.remove();
8527
8902
  }, []);
8528
- const cleanupEmptyLists = useCallback8(() => {
8903
+ const cleanupEmptyLists = useCallback9(() => {
8529
8904
  const editor = editorRef.current;
8530
8905
  if (!editor) return;
8531
8906
  editor.querySelectorAll("ul, ol").forEach((list) => {
8532
8907
  if (!list.querySelector("li")) list.remove();
8533
8908
  });
8534
8909
  }, []);
8535
- const retagList = useCallback8((list, type) => {
8910
+ const retagList = useCallback9((list, type) => {
8536
8911
  if (!list.parentNode) return;
8537
8912
  const nl = document.createElement(type);
8538
8913
  while (list.firstChild) nl.appendChild(list.firstChild);
8539
8914
  list.parentNode.replaceChild(nl, list);
8540
8915
  }, []);
8541
- const toggleList = useCallback8(
8916
+ const toggleList = useCallback9(
8542
8917
  (type) => {
8543
8918
  const editor = editorRef.current;
8544
8919
  const sel = window.getSelection();
@@ -8636,7 +9011,7 @@ function ITWysiwyg({
8636
9011
  updateActive
8637
9012
  ]
8638
9013
  );
8639
- const clearFormatting = useCallback8(() => {
9014
+ const clearFormatting = useCallback9(() => {
8640
9015
  const editor = editorRef.current;
8641
9016
  const sel = window.getSelection();
8642
9017
  if (!editor || !sel || sel.rangeCount === 0) return;
@@ -8817,7 +9192,7 @@ function ITWysiwyg({
8817
9192
  }
8818
9193
 
8819
9194
  // src/components/organisms/dropfile/dropfile.tsx
8820
- import { useState as useState32, useEffect as useEffect17 } from "react";
9195
+ import { useState as useState34, useEffect as useEffect17 } from "react";
8821
9196
  import { useDropzone } from "react-dropzone";
8822
9197
  import clsx50 from "clsx";
8823
9198
 
@@ -8847,7 +9222,7 @@ var UploadStatus = /* @__PURE__ */ ((UploadStatus2) => {
8847
9222
  })(UploadStatus || {});
8848
9223
 
8849
9224
  // src/components/organisms/dropfile/dropfile.tsx
8850
- import { Fragment as Fragment9, jsx as jsx66, jsxs as jsxs52 } from "react/jsx-runtime";
9225
+ import { Fragment as Fragment10, jsx as jsx66, jsxs as jsxs52 } from "react/jsx-runtime";
8851
9226
  var ITDropfile = ({
8852
9227
  onFileSelect,
8853
9228
  onCancel,
@@ -8863,12 +9238,12 @@ var ITDropfile = ({
8863
9238
  buttonLabel = "Subir archivo",
8864
9239
  modalTitle
8865
9240
  }) => {
8866
- const [isModalOpen, setIsModalOpen] = useState32(false);
8867
- const [selectedFile, setSelectedFile] = useState32(null);
8868
- const [fileType, setFileType] = useState32(null);
8869
- const [imagePreview, setImagePreview] = useState32(initialPreviewUrl || null);
8870
- const [isConfirmed, setIsConfirmed] = useState32(false);
8871
- const [internalUploadStatus, setInternalUploadStatus] = useState32(
9241
+ const [isModalOpen, setIsModalOpen] = useState34(false);
9242
+ const [selectedFile, setSelectedFile] = useState34(null);
9243
+ const [fileType, setFileType] = useState34(null);
9244
+ const [imagePreview, setImagePreview] = useState34(initialPreviewUrl || null);
9245
+ const [isConfirmed, setIsConfirmed] = useState34(false);
9246
+ const [internalUploadStatus, setInternalUploadStatus] = useState34(
8872
9247
  initialPreviewUrl ? "subido" /* UPLOADED */ : "pendiente" /* PENDING */
8873
9248
  );
8874
9249
  useEffect17(() => {
@@ -9090,7 +9465,7 @@ var ITDropfile = ({
9090
9465
  ] }),
9091
9466
  showStatusBadge && selectedFile && /* @__PURE__ */ jsx66(StatusBadge, { status: uploadStatus })
9092
9467
  ] });
9093
- const dropZoneOrPreview = /* @__PURE__ */ jsx66(Fragment9, { children: !selectedFile && !imagePreview ? /* @__PURE__ */ jsxs52(
9468
+ const dropZoneOrPreview = /* @__PURE__ */ jsx66(Fragment10, { children: !selectedFile && !imagePreview ? /* @__PURE__ */ jsxs52(
9094
9469
  "div",
9095
9470
  {
9096
9471
  ...getRootProps(),
@@ -9133,7 +9508,7 @@ var ITDropfile = ({
9133
9508
  /* @__PURE__ */ jsx66("svg", { className: "w-10 h-10 mb-2 opacity-50", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ jsx66("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 1.5, d: "M7 21h10a2 2 0 002-2V9.414a1 1 0 00-.293-.707l-5.414-5.414A1 1 0 0012.586 3H7a2 2 0 00-2 2v14a2 2 0 002 2z" }) }),
9134
9509
  /* @__PURE__ */ jsx66(ITText, { as: "span", className: "text-xs", children: "Sin vista previa" })
9135
9510
  ] }) }),
9136
- /* @__PURE__ */ jsx66("div", { className: "px-3 py-2 bg-white border-t border-secondary-100 flex justify-end gap-2", children: !isConfirmed ? /* @__PURE__ */ jsxs52(Fragment9, { children: [
9511
+ /* @__PURE__ */ jsx66("div", { className: "px-3 py-2 bg-white border-t border-secondary-100 flex justify-end gap-2", children: !isConfirmed ? /* @__PURE__ */ jsxs52(Fragment10, { children: [
9137
9512
  /* @__PURE__ */ jsx66(
9138
9513
  ITButton,
9139
9514
  {
@@ -9216,24 +9591,26 @@ var ITDropfile = ({
9216
9591
  var dropfile_default = ITDropfile;
9217
9592
 
9218
9593
  // src/components/templates/layout/layout.tsx
9219
- import { useState as useState34 } from "react";
9594
+ import { useState as useState36 } from "react";
9220
9595
  import clsx51 from "clsx";
9221
9596
 
9222
9597
  // src/components/organisms/topbar/topbar.tsx
9223
9598
  import { FaUserCircle as FaUserCircle2, FaBars } from "react-icons/fa";
9224
- import { useRef as useRef20, useState as useState33 } from "react";
9599
+ import { useRef as useRef22, useState as useState35 } from "react";
9225
9600
  import { jsx as jsx67, jsxs as jsxs53 } from "react/jsx-runtime";
9226
9601
  function ITTopBar({
9227
9602
  logo,
9228
9603
  logoText,
9604
+ centerContent,
9229
9605
  userMenu,
9606
+ children,
9230
9607
  showMobileMenuButton,
9231
9608
  onToggleMobileMenu,
9232
9609
  navItems,
9233
9610
  onNavItemClick
9234
9611
  }) {
9235
- const [isUserMenuOpen, setIsUserMenuOpen] = useState33(false);
9236
- const userMenuRef = useRef20(null);
9612
+ const [isUserMenuOpen, setIsUserMenuOpen] = useState35(false);
9613
+ const userMenuRef = useRef22(null);
9237
9614
  useClickOutside_default(userMenuRef, () => setIsUserMenuOpen(false));
9238
9615
  return /* @__PURE__ */ jsx67(
9239
9616
  "header",
@@ -9293,101 +9670,105 @@ function ITTopBar({
9293
9670
  item.id
9294
9671
  )) })
9295
9672
  ] }),
9296
- userMenu && /* @__PURE__ */ jsxs53("div", { className: "relative", children: [
9297
- /* @__PURE__ */ jsxs53(
9298
- "button",
9299
- {
9300
- type: "button",
9301
- 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",
9302
- style: {
9303
- backgroundColor: isUserMenuOpen ? "var(--it-topbar-user-hover, #f1f5f9)" : "transparent"
9304
- },
9305
- onMouseEnter: (e) => {
9306
- if (!isUserMenuOpen) e.currentTarget.style.backgroundColor = "var(--it-topbar-user-hover, #f1f5f9)";
9307
- },
9308
- onMouseLeave: (e) => {
9309
- if (!isUserMenuOpen) e.currentTarget.style.backgroundColor = "transparent";
9310
- },
9311
- onClick: () => setIsUserMenuOpen(!isUserMenuOpen),
9312
- children: [
9313
- /* @__PURE__ */ jsxs53("div", { className: "relative", children: [
9314
- userMenu.userImage ? /* @__PURE__ */ jsx67(
9315
- "img",
9316
- {
9317
- className: "w-9 h-9 rounded-full object-cover ring-2 ring-white shadow-sm",
9318
- src: userMenu.userImage,
9319
- alt: "Current user"
9320
- }
9321
- ) : /* @__PURE__ */ jsx67("div", { className: "w-9 h-9 rounded-full bg-slate-100 flex items-center justify-center ring-2 ring-white shadow-sm", children: /* @__PURE__ */ jsx67(FaUserCircle2, { className: "w-6 h-6", style: { color: "var(--it-topbar-icon, #94a3b8)" } }) }),
9322
- /* @__PURE__ */ jsx67("div", { className: "absolute bottom-0 right-0 w-2.5 h-2.5 bg-green-500 border-2 border-white rounded-full" })
9323
- ] }),
9324
- /* @__PURE__ */ jsxs53("div", { className: "hidden sm:flex flex-col text-left py-0.5", children: [
9325
- /* @__PURE__ */ jsx67(
9326
- ITText,
9327
- {
9328
- as: "span",
9329
- className: "font-semibold text-[0.85rem] leading-tight",
9330
- style: { color: "var(--it-topbar-user-text, #0f172a)" },
9331
- children: userMenu.userName
9332
- }
9333
- ),
9334
- /* @__PURE__ */ jsx67(
9335
- ITText,
9336
- {
9337
- as: "span",
9338
- className: "text-[0.7rem] font-medium",
9339
- style: { color: "var(--it-topbar-user-subtitle, #64748b)" },
9340
- children: userMenu.userEmail
9341
- }
9342
- )
9343
- ] })
9344
- ]
9345
- }
9346
- ),
9347
- /* @__PURE__ */ jsxs53(
9348
- "div",
9349
- {
9350
- ref: userMenuRef,
9351
- className: `
9352
- 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)]
9353
- ${isUserMenuOpen ? "scale-100 opacity-100 translate-y-0" : "scale-95 opacity-0 -translate-y-2 pointer-events-none"}
9354
- `,
9355
- style: {
9356
- backgroundColor: "var(--it-topbar-user-dropdown-bg, #ffffff)",
9357
- border: "1px solid var(--it-topbar-user-dropdown-border, #f1f5f9)"
9358
- },
9359
- children: [
9360
- /* @__PURE__ */ jsxs53("div", { className: "px-5 py-4 border-b", style: { borderColor: "var(--it-topbar-user-dropdown-border, #f1f5f9)", backgroundColor: "var(--it-topbar-user-bg, #f8fafc)" }, children: [
9361
- /* @__PURE__ */ jsx67(ITText, { as: "span", className: "block font-bold text-[0.9rem]", style: { color: "var(--it-topbar-user-text, #0f172a)" }, children: userMenu.userName }),
9362
- /* @__PURE__ */ jsx67(ITText, { as: "span", className: "block text-xs font-medium truncate mt-0.5", style: { color: "var(--it-topbar-user-subtitle, #64748b)" }, children: userMenu.userEmail })
9363
- ] }),
9364
- /* @__PURE__ */ jsx67("ul", { className: "py-2", children: userMenu.menuItems.map((m, i) => {
9365
- const isDestructive = m.label.toLowerCase().includes("salir") || m.label.toLowerCase().includes("cerrar") || m.label.toLowerCase().includes("logout");
9366
- return /* @__PURE__ */ jsxs53("li", { className: "px-2", children: [
9367
- i === userMenu.menuItems.length - 1 && isDestructive && i > 0 && /* @__PURE__ */ jsx67("div", { className: "h-px bg-slate-100 my-1 mx-2" }),
9673
+ centerContent && /* @__PURE__ */ jsx67("div", { className: "hidden lg:flex flex-1 min-w-0 items-center justify-center px-4", children: /* @__PURE__ */ jsx67("div", { className: "w-full max-w-[420px]", children: centerContent }) }),
9674
+ (children || userMenu) && /* @__PURE__ */ jsxs53("div", { className: "flex items-center gap-2", children: [
9675
+ children,
9676
+ userMenu && /* @__PURE__ */ jsxs53("div", { className: "relative", children: [
9677
+ /* @__PURE__ */ jsxs53(
9678
+ "button",
9679
+ {
9680
+ type: "button",
9681
+ 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",
9682
+ style: {
9683
+ backgroundColor: isUserMenuOpen ? "var(--it-topbar-user-hover, #f1f5f9)" : "transparent"
9684
+ },
9685
+ onMouseEnter: (e) => {
9686
+ if (!isUserMenuOpen) e.currentTarget.style.backgroundColor = "var(--it-topbar-user-hover, #f1f5f9)";
9687
+ },
9688
+ onMouseLeave: (e) => {
9689
+ if (!isUserMenuOpen) e.currentTarget.style.backgroundColor = "transparent";
9690
+ },
9691
+ onClick: () => setIsUserMenuOpen(!isUserMenuOpen),
9692
+ children: [
9693
+ /* @__PURE__ */ jsxs53("div", { className: "relative", children: [
9694
+ userMenu.userImage ? /* @__PURE__ */ jsx67(
9695
+ "img",
9696
+ {
9697
+ className: "w-9 h-9 rounded-full object-cover ring-2 ring-white shadow-sm",
9698
+ src: userMenu.userImage,
9699
+ alt: "Current user"
9700
+ }
9701
+ ) : /* @__PURE__ */ jsx67("div", { className: "w-9 h-9 rounded-full bg-slate-100 flex items-center justify-center ring-2 ring-white shadow-sm", children: /* @__PURE__ */ jsx67(FaUserCircle2, { className: "w-6 h-6", style: { color: "var(--it-topbar-icon, #94a3b8)" } }) }),
9702
+ /* @__PURE__ */ jsx67("div", { className: "absolute bottom-0 right-0 w-2.5 h-2.5 bg-green-500 border-2 border-white rounded-full" })
9703
+ ] }),
9704
+ /* @__PURE__ */ jsxs53("div", { className: "hidden sm:flex flex-col text-left py-0.5", children: [
9368
9705
  /* @__PURE__ */ jsx67(
9369
- "button",
9706
+ ITText,
9370
9707
  {
9371
- onClick: () => {
9372
- m.onClick();
9373
- setIsUserMenuOpen(false);
9374
- },
9375
- className: "block w-full text-left px-3 py-2.5 rounded-xl text-[0.875rem] font-medium transition-colors duration-150",
9376
- style: { color: isDestructive ? "var(--color-danger-500)" : "var(--it-topbar-user-text, #334155)" },
9377
- onMouseEnter: (e) => {
9378
- e.currentTarget.style.backgroundColor = isDestructive ? "var(--color-danger-50)" : "var(--it-topbar-user-item-hover, #f8fafc)";
9379
- },
9380
- onMouseLeave: (e) => {
9381
- e.currentTarget.style.backgroundColor = "transparent";
9382
- },
9383
- children: /* @__PURE__ */ jsx67(ITText, { as: "span", children: m.label })
9708
+ as: "span",
9709
+ className: "font-semibold text-[0.85rem] leading-tight",
9710
+ style: { color: "var(--it-topbar-user-text, #0f172a)" },
9711
+ children: userMenu.userName
9712
+ }
9713
+ ),
9714
+ /* @__PURE__ */ jsx67(
9715
+ ITText,
9716
+ {
9717
+ as: "span",
9718
+ className: "text-[0.7rem] font-medium",
9719
+ style: { color: "var(--it-topbar-user-subtitle, #64748b)" },
9720
+ children: userMenu.userEmail
9384
9721
  }
9385
9722
  )
9386
- ] }, i);
9387
- }) })
9388
- ]
9389
- }
9390
- )
9723
+ ] })
9724
+ ]
9725
+ }
9726
+ ),
9727
+ /* @__PURE__ */ jsxs53(
9728
+ "div",
9729
+ {
9730
+ ref: userMenuRef,
9731
+ className: `
9732
+ 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)]
9733
+ ${isUserMenuOpen ? "scale-100 opacity-100 translate-y-0" : "scale-95 opacity-0 -translate-y-2 pointer-events-none"}
9734
+ `,
9735
+ style: {
9736
+ backgroundColor: "var(--it-topbar-user-dropdown-bg, #ffffff)",
9737
+ border: "1px solid var(--it-topbar-user-dropdown-border, #f1f5f9)"
9738
+ },
9739
+ children: [
9740
+ /* @__PURE__ */ jsxs53("div", { className: "px-5 py-4 border-b", style: { borderColor: "var(--it-topbar-user-dropdown-border, #f1f5f9)", backgroundColor: "var(--it-topbar-user-bg, #f8fafc)" }, children: [
9741
+ /* @__PURE__ */ jsx67(ITText, { as: "span", className: "block font-bold text-[0.9rem]", style: { color: "var(--it-topbar-user-text, #0f172a)" }, children: userMenu.userName }),
9742
+ /* @__PURE__ */ jsx67(ITText, { as: "span", className: "block text-xs font-medium truncate mt-0.5", style: { color: "var(--it-topbar-user-subtitle, #64748b)" }, children: userMenu.userEmail })
9743
+ ] }),
9744
+ /* @__PURE__ */ jsx67("ul", { className: "py-2", children: userMenu.menuItems.map((m, i) => {
9745
+ const isDestructive = m.label.toLowerCase().includes("salir") || m.label.toLowerCase().includes("cerrar") || m.label.toLowerCase().includes("logout");
9746
+ return /* @__PURE__ */ jsxs53("li", { className: "px-2", children: [
9747
+ i === userMenu.menuItems.length - 1 && isDestructive && i > 0 && /* @__PURE__ */ jsx67("div", { className: "h-px bg-slate-100 my-1 mx-2" }),
9748
+ /* @__PURE__ */ jsx67(
9749
+ "button",
9750
+ {
9751
+ onClick: () => {
9752
+ m.onClick();
9753
+ setIsUserMenuOpen(false);
9754
+ },
9755
+ className: "block w-full text-left px-3 py-2.5 rounded-xl text-[0.875rem] font-medium transition-colors duration-150",
9756
+ style: { color: isDestructive ? "var(--color-danger-500)" : "var(--it-topbar-user-text, #334155)" },
9757
+ onMouseEnter: (e) => {
9758
+ e.currentTarget.style.backgroundColor = isDestructive ? "var(--color-danger-50)" : "var(--it-topbar-user-item-hover, #f8fafc)";
9759
+ },
9760
+ onMouseLeave: (e) => {
9761
+ e.currentTarget.style.backgroundColor = "transparent";
9762
+ },
9763
+ children: /* @__PURE__ */ jsx67(ITText, { as: "span", children: m.label })
9764
+ }
9765
+ )
9766
+ ] }, i);
9767
+ }) })
9768
+ ]
9769
+ }
9770
+ )
9771
+ ] })
9391
9772
  ] })
9392
9773
  ] })
9393
9774
  }
@@ -9403,8 +9784,8 @@ function ITLayout({
9403
9784
  className = "",
9404
9785
  contentClassName = ""
9405
9786
  }) {
9406
- const [internalCollapsed, setInternalCollapsed] = useState34(true);
9407
- const [mobileSidebarOpen, setMobileSidebarOpen] = useState34(false);
9787
+ const [internalCollapsed, setInternalCollapsed] = useState36(true);
9788
+ const [mobileSidebarOpen, setMobileSidebarOpen] = useState36(false);
9408
9789
  const isControlled = sidebar.isCollapsed !== void 0;
9409
9790
  const desktopCollapsed = isControlled ? sidebar.isCollapsed : internalCollapsed;
9410
9791
  const handleToggleCollapse = isControlled ? sidebar.onToggleCollapse ?? (() => {
@@ -9426,7 +9807,12 @@ function ITLayout({
9426
9807
  style: { backgroundColor: layoutTokens.backgroundColor },
9427
9808
  children: [
9428
9809
  /* @__PURE__ */ jsxs54("div", { className: "hidden lg:block relative z-40 h-full", children: [
9429
- /* @__PURE__ */ jsx68("div", { className: "w-[88px] h-full flex-shrink-0" }),
9810
+ /* @__PURE__ */ jsx68(
9811
+ "div",
9812
+ {
9813
+ className: `${desktopCollapsed ? "w-[88px]" : "w-[280px]"} h-full flex-shrink-0`
9814
+ }
9815
+ ),
9430
9816
  /* @__PURE__ */ jsx68("div", { className: "absolute top-0 left-0 h-full", children: /* @__PURE__ */ jsx68(
9431
9817
  ITSidebar,
9432
9818
  {
@@ -9558,7 +9944,7 @@ function ITLoader({
9558
9944
 
9559
9945
  // src/components/molecules/stepper/stepper.tsx
9560
9946
  import clsx52 from "clsx";
9561
- import { useEffect as useEffect18, useRef as useRef21, useState as useState35 } from "react";
9947
+ import { useEffect as useEffect18, useRef as useRef23, useState as useState37 } from "react";
9562
9948
  import { FaChevronLeft as FaChevronLeft4, FaChevronRight as FaChevronRight5, FaCheck as FaCheck5 } from "react-icons/fa";
9563
9949
  import { jsx as jsx70, jsxs as jsxs55 } from "react/jsx-runtime";
9564
9950
  function ITStepper({
@@ -9575,9 +9961,9 @@ function ITStepper({
9575
9961
  maxContentHeight = "400px",
9576
9962
  color = "primary"
9577
9963
  }) {
9578
- const [direction, setDirection] = useState35("next");
9579
- const contentRef = useRef21(null);
9580
- const progressRef = useRef21(null);
9964
+ const [direction, setDirection] = useState37("next");
9965
+ const contentRef = useRef23(null);
9966
+ const progressRef = useRef23(null);
9581
9967
  const isThemeColor = color in theme.colors;
9582
9968
  const resolvedColor = isThemeColor ? theme.colors[color][500] : color;
9583
9969
  useEffect18(() => {
@@ -9754,7 +10140,7 @@ function ITStepper({
9754
10140
  }
9755
10141
 
9756
10142
  // src/components/theme-provider/themeProvider.tsx
9757
- import { useState as useState36, useEffect as useEffect19, useLayoutEffect as useLayoutEffect2 } from "react";
10143
+ import { useState as useState38, useEffect as useEffect19, useLayoutEffect as useLayoutEffect4 } from "react";
9758
10144
  import { MdPalette, MdClose, MdRefresh } from "react-icons/md";
9759
10145
 
9760
10146
  // src/components/theme-provider/themePresets.ts
@@ -10019,7 +10405,7 @@ function ITThemeProvider({
10019
10405
  radius,
10020
10406
  shadow
10021
10407
  }) {
10022
- const [palette2, setPaletteState] = useState36(() => {
10408
+ const [palette2, setPaletteState] = useState38(() => {
10023
10409
  const basePalette = {
10024
10410
  ...DEFAULT_PALETTE,
10025
10411
  ...theme2,
@@ -10045,8 +10431,8 @@ function ITThemeProvider({
10045
10431
  }
10046
10432
  return basePalette;
10047
10433
  });
10048
- const [isOpen, setIsOpen] = useState36(false);
10049
- const [customPresets, setCustomPresets] = useState36(() => {
10434
+ const [isOpen, setIsOpen] = useState38(false);
10435
+ const [customPresets, setCustomPresets] = useState38(() => {
10050
10436
  try {
10051
10437
  const saved = localStorage.getItem("it-theme-custom-presets");
10052
10438
  return saved ? JSON.parse(saved) : [];
@@ -10055,8 +10441,8 @@ function ITThemeProvider({
10055
10441
  return [];
10056
10442
  }
10057
10443
  });
10058
- const [newPresetName, setNewPresetName] = useState36("");
10059
- const [isSavingPreset, setIsSavingPreset] = useState36(false);
10444
+ const [newPresetName, setNewPresetName] = useState38("");
10445
+ const [isSavingPreset, setIsSavingPreset] = useState38(false);
10060
10446
  const handleSavePreset = () => {
10061
10447
  if (!newPresetName.trim()) return;
10062
10448
  const newPreset = {
@@ -10075,8 +10461,8 @@ function ITThemeProvider({
10075
10461
  setCustomPresets(updated);
10076
10462
  localStorage.setItem("it-theme-custom-presets", JSON.stringify(updated));
10077
10463
  };
10078
- const [resolvedTheme, setResolvedTheme] = useState36("light");
10079
- const [darkModeMode, setDarkModeMode] = useState36(
10464
+ const [resolvedTheme, setResolvedTheme] = useState38("light");
10465
+ const [darkModeMode, setDarkModeMode] = useState38(
10080
10466
  () => {
10081
10467
  const saved = localStorage.getItem("it-theme-dark-mode");
10082
10468
  if (saved === "light" || saved === "dark" || saved === "system") {
@@ -10120,7 +10506,7 @@ function ITThemeProvider({
10120
10506
  });
10121
10507
  }
10122
10508
  }, [theme2, showFab]);
10123
- useLayoutEffect2(() => {
10509
+ useLayoutEffect4(() => {
10124
10510
  const root = document.documentElement;
10125
10511
  const scale = typeof density === "number" && isFinite(density) ? Math.min(Math.max(density, 0.5), 1.5) : 1;
10126
10512
  root.style.setProperty("--it-density", String(scale));
@@ -10130,7 +10516,7 @@ function ITThemeProvider({
10130
10516
  root.style.fontSize = "";
10131
10517
  };
10132
10518
  }, [density]);
10133
- useLayoutEffect2(() => {
10519
+ useLayoutEffect4(() => {
10134
10520
  const root = document.documentElement;
10135
10521
  const radiusTokens = ["xs", "sm", "md", "lg", "xl", "2xl", "3xl"];
10136
10522
  if (typeof radius === "number" && isFinite(radius)) {