@axzydev/axzy_ui_system 1.3.4 → 1.3.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -225,7 +225,7 @@ estas variables en cualquier contenedor estila solo ese subárbol.
225
225
  - **ITSlideToggle** – Switch toggle
226
226
  - **ITDropfile** – Área de arrastrar y soltar archivos
227
227
  - **ITFormBuilder** – Generador dinámico de formularios desde JSON
228
- - **ITTable** / **ITDataTable** – Tablas con filtros, ordenamiento y paginación
228
+ - **ITTable** / **ITDataTable** – Tablas con filtros, ordenamiento, paginación y columnas fijas (`pinned`)
229
229
  - **ITCard** / **ITStatCard** – Tarjetas de contenido y métricas
230
230
  - **ITLayout** / **ITNavbar** – Sistema de layout con sidebar colapsable
231
231
  - **ITFlex** / **ITStack** / **ITGrid** – Layout helpers
package/dist/index.cjs CHANGED
@@ -3688,7 +3688,7 @@ function useVirtualRows({
3688
3688
 
3689
3689
  // src/components/organisms/data-table/dataTable.tsx
3690
3690
  var import_clsx23 = __toESM(require("clsx"), 1);
3691
- var import_react21 = require("react");
3691
+ var import_react21 = __toESM(require("react"), 1);
3692
3692
  var import_fa13 = require("react-icons/fa");
3693
3693
  var import_md = require("react-icons/md");
3694
3694
 
@@ -4483,6 +4483,32 @@ function isInteractiveTarget(target, boundary = null) {
4483
4483
  if (boundary instanceof Node && interactive === boundary) return false;
4484
4484
  return true;
4485
4485
  }
4486
+ function pinnedColumnWidth(col) {
4487
+ if (typeof col.width === "number") return col.width;
4488
+ if (typeof col.width === "string" && /^\d+(\.\d+)?px$/.test(col.width.trim())) {
4489
+ return parseFloat(col.width);
4490
+ }
4491
+ return col.minWidth ?? 0;
4492
+ }
4493
+ function getPinnedColumnMeta(columns) {
4494
+ const meta = {};
4495
+ let leftOffset = 0;
4496
+ for (const col of columns) {
4497
+ if (col.pinned === "left") {
4498
+ meta[col.key] = { side: "left", offset: leftOffset };
4499
+ leftOffset += pinnedColumnWidth(col);
4500
+ }
4501
+ }
4502
+ let rightOffset = 0;
4503
+ for (let i = columns.length - 1; i >= 0; i--) {
4504
+ const col = columns[i];
4505
+ if (col.pinned === "right") {
4506
+ meta[col.key] = { side: "right", offset: rightOffset };
4507
+ rightOffset += pinnedColumnWidth(col);
4508
+ }
4509
+ }
4510
+ return meta;
4511
+ }
4486
4512
 
4487
4513
  // src/components/organisms/data-table/dataTable.tsx
4488
4514
  var import_jsx_runtime23 = require("react/jsx-runtime");
@@ -4533,6 +4559,7 @@ function ITDataTable({
4533
4559
  const isStickyHeader = stickyHeader && isTableVirtual;
4534
4560
  const resolvedRowHeight = rowHeight ?? getRowHeight(size, density);
4535
4561
  const columnCount = columns.length;
4562
+ const pinnedMeta = import_react21.default.useMemo(() => getPinnedColumnMeta(columns), [columns]);
4536
4563
  const scrollOuterClass = isTableVirtual ? "relative min-h-[200px]" : "overflow-x-auto relative min-h-[200px]";
4537
4564
  const {
4538
4565
  currentPage,
@@ -4812,38 +4839,46 @@ function ITDataTable({
4812
4839
  {
4813
4840
  className: (0, import_clsx23.default)(tableHeaderRow, "dark:text-slate-200"),
4814
4841
  "aria-rowindex": isTableVirtual ? 1 : void 0,
4815
- children: columns.map((col) => /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
4816
- "th",
4817
- {
4818
- scope: "col",
4819
- className: (0, import_clsx23.default)(
4820
- tableHeaderCell(col.className, density),
4821
- col.align && tableAlignClasses[col.align],
4822
- isStickyHeader && "sticky top-0 z-10 bg-secondary-50"
4823
- ),
4824
- style: col.minWidth != null || isStickyHeader ? {
4825
- ...col.minWidth != null ? { minWidth: `${col.minWidth}px` } : {},
4826
- ...isStickyHeader ? { backgroundColor: "var(--color-table-headerBg, #f8fafc)" } : {}
4827
- } : void 0,
4828
- children: /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: isFixed ? "flex flex-col gap-3" : "flex flex-col gap-3 min-w-[150px]", children: [
4829
- /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex items-center justify-between gap-2", children: [
4830
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(ITText, { as: "span", className: "text-slate-900 dark:text-white font-bold", children: col.label }),
4831
- col.sortable && col.type !== "actions" && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
4832
- "button",
4833
- {
4834
- onClick: () => handleSort(col.key),
4835
- disabled: isLoading,
4836
- 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`,
4837
- title: `Ordenar por ${col.label}`,
4838
- children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_md.MdOutlineSwapVert, { className: "w-4 h-4", "aria-hidden": "true" })
4839
- }
4840
- )
4841
- ] }),
4842
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "w-full", children: col.filter ? renderFilterInput(col) : null })
4843
- ] })
4844
- },
4845
- col.key
4846
- ))
4842
+ children: columns.map((col) => {
4843
+ const pin = pinnedMeta[col.key];
4844
+ const isPinned = pin != null;
4845
+ return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
4846
+ "th",
4847
+ {
4848
+ scope: "col",
4849
+ className: (0, import_clsx23.default)(
4850
+ tableHeaderCell(col.className, density),
4851
+ col.align && tableAlignClasses[col.align],
4852
+ isPinned && "sticky",
4853
+ isStickyHeader && "sticky top-0 bg-secondary-50",
4854
+ isPinned ? "z-[15]" : isStickyHeader && "z-10",
4855
+ isPinned && (col.pinned === "left" ? "it-table-pinned-left" : "it-table-pinned-right")
4856
+ ),
4857
+ style: col.minWidth != null || isStickyHeader || isPinned ? {
4858
+ ...col.minWidth != null ? { minWidth: `${col.minWidth}px` } : {},
4859
+ ...isStickyHeader || isPinned ? { backgroundColor: "var(--color-table-headerBg, #f8fafc)" } : {},
4860
+ ...isPinned ? pin.side === "left" ? { left: pin.offset } : { right: pin.offset } : {}
4861
+ } : void 0,
4862
+ children: /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: isFixed ? "flex flex-col gap-3" : "flex flex-col gap-3 min-w-[150px]", children: [
4863
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex items-center justify-between gap-2", children: [
4864
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(ITText, { as: "span", className: "text-slate-900 dark:text-white font-bold", children: col.label }),
4865
+ col.sortable && col.type !== "actions" && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
4866
+ "button",
4867
+ {
4868
+ onClick: () => handleSort(col.key),
4869
+ disabled: isLoading,
4870
+ 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`,
4871
+ title: `Ordenar por ${col.label}`,
4872
+ children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_md.MdOutlineSwapVert, { className: "w-4 h-4", "aria-hidden": "true" })
4873
+ }
4874
+ )
4875
+ ] }),
4876
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "w-full", children: col.filter ? renderFilterInput(col) : null })
4877
+ ] })
4878
+ },
4879
+ col.key
4880
+ );
4881
+ })
4847
4882
  }
4848
4883
  ) }),
4849
4884
  /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("tbody", { className: (0, import_clsx23.default)(tableBody, "dark:divide-slate-700/30"), children: data.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(import_jsx_runtime23.Fragment, { children: [
@@ -4865,14 +4900,22 @@ function ITDataTable({
4865
4900
  children: columns.map((col) => {
4866
4901
  const rawValue = getNestedValue2(row, col.key);
4867
4902
  const truncateTitle = col.truncate && (typeof rawValue === "string" || typeof rawValue === "number") ? String(rawValue) : void 0;
4903
+ const pin = pinnedMeta[col.key];
4904
+ const isPinned = pin != null;
4868
4905
  return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
4869
4906
  "td",
4870
4907
  {
4871
4908
  className: (0, import_clsx23.default)(
4872
4909
  tableCell(col.className, density),
4873
- col.align && tableAlignClasses[col.align]
4910
+ col.align && tableAlignClasses[col.align],
4911
+ isPinned && "sticky bg-[var(--color-table-rowBg,white)] group-hover:bg-[var(--color-table-rowHover,var(--color-secondary-50))]",
4912
+ isPinned && (col.pinned === "left" ? "it-table-pinned-left" : "it-table-pinned-right"),
4913
+ isPinned && "z-[1]"
4874
4914
  ),
4875
- style: col.minWidth != null ? { minWidth: `${col.minWidth}px` } : void 0,
4915
+ style: col.minWidth != null || isPinned ? {
4916
+ ...col.minWidth != null ? { minWidth: `${col.minWidth}px` } : {},
4917
+ ...isPinned ? pin.side === "left" ? { left: pin.offset } : { right: pin.offset } : {}
4918
+ } : void 0,
4876
4919
  title: truncateTitle,
4877
4920
  children: col.type === "actions" ? /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: tableActionsCell, children: renderCellContent(col, row) }) : /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: (0, import_clsx23.default)(tableCellText, col.truncate && "truncate"), children: renderCellContent(col, row) })
4878
4921
  },
@@ -7567,6 +7610,14 @@ function ITSegmentedControl({
7567
7610
  var import_react35 = require("react");
7568
7611
  var import_fa26 = require("react-icons/fa");
7569
7612
  var import_jsx_runtime56 = require("react/jsx-runtime");
7613
+ function isSubItemGroup(entry) {
7614
+ return "items" in entry;
7615
+ }
7616
+ function flattenSubItems(entries) {
7617
+ return entries.flatMap(
7618
+ (entry) => isSubItemGroup(entry) ? entry.items : [entry]
7619
+ );
7620
+ }
7570
7621
  function ITSidebar({
7571
7622
  navigationItems = [],
7572
7623
  isCollapsed = false,
@@ -7612,7 +7663,7 @@ function ITSidebar({
7612
7663
  (0, import_react35.useEffect)(() => {
7613
7664
  const activeParents = /* @__PURE__ */ new Set();
7614
7665
  navigationItems.forEach((item) => {
7615
- if (item.subitems && item.subitems.some((sub) => sub.isActive)) {
7666
+ if (item.subitems && flattenSubItems(item.subitems).some((sub) => sub.isActive)) {
7616
7667
  activeParents.add(item.id);
7617
7668
  }
7618
7669
  });
@@ -7646,6 +7697,80 @@ function ITSidebar({
7646
7697
  };
7647
7698
  const isSidebarCollapsed = visibleOnMobile ? false : !isHovering && isCollapsed;
7648
7699
  const sidebarWidth = isSidebarCollapsed ? "w-[88px]" : "w-[280px]";
7700
+ const renderSubItem = (subitem) => /* @__PURE__ */ (0, import_jsx_runtime56.jsx)("li", { className: "relative", children: /* @__PURE__ */ (0, import_jsx_runtime56.jsxs)(
7701
+ "button",
7702
+ {
7703
+ "aria-current": subitem.isActive ? "page" : void 0,
7704
+ onClick: () => {
7705
+ if (subitem.action) subitem.action();
7706
+ if (onSubItemClick) onSubItemClick(subitem);
7707
+ },
7708
+ className: `flex items-center gap-2 w-full text-left px-3 py-1.5 rounded-xl transition-all duration-300`,
7709
+ style: {
7710
+ color: subitem.isActive ? "var(--it-sidebar-active-color, var(--color-secondary-900))" : "var(--it-sidebar-label-color, var(--color-secondary-600))",
7711
+ backgroundColor: subitem.isActive ? "var(--it-sidebar-active-bg, var(--color-secondary-50))" : "transparent",
7712
+ fontSize: "0.78rem",
7713
+ fontWeight: subitem.isActive ? 600 : 500,
7714
+ letterSpacing: "0.01em",
7715
+ marginLeft: subitemConnector === "|" ? "-1px" : "0"
7716
+ },
7717
+ onMouseEnter: (e) => {
7718
+ if (!subitem.isActive) {
7719
+ e.currentTarget.style.backgroundColor = "var(--it-sidebar-hover-bg, var(--color-secondary-100))";
7720
+ e.currentTarget.style.transform = "translateX(3px)";
7721
+ }
7722
+ },
7723
+ onMouseLeave: (e) => {
7724
+ if (!subitem.isActive) {
7725
+ e.currentTarget.style.backgroundColor = "transparent";
7726
+ e.currentTarget.style.transform = "translateX(0)";
7727
+ }
7728
+ },
7729
+ children: [
7730
+ subitem.isActive && subitemConnector === "|" && /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(
7731
+ "div",
7732
+ {
7733
+ className: "absolute left-0 top-1/3 bottom-1/3 w-[2.5px] rounded-r-full transition-all",
7734
+ style: {
7735
+ backgroundColor: "var(--it-sidebar-active-icon, var(--color-primary-500))",
7736
+ boxShadow: "0 0 6px color-mix(in srgb, var(--it-sidebar-active-icon, var(--color-primary-500)) 25%, transparent)"
7737
+ }
7738
+ }
7739
+ ),
7740
+ subitemConnector === "dot" && /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(
7741
+ "span",
7742
+ {
7743
+ className: `w-1.5 h-1.5 rounded-full flex-shrink-0 transition-all duration-300 ${subitem.isActive ? "scale-125" : ""}`,
7744
+ style: {
7745
+ backgroundColor: subitem.isActive ? "var(--it-sidebar-active-icon, var(--color-primary-500))" : "var(--it-sidebar-icon-color, var(--color-secondary-400))"
7746
+ }
7747
+ }
7748
+ ),
7749
+ /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(ITText, { as: "span", className: "truncate", children: subitem.label })
7750
+ ]
7751
+ }
7752
+ ) }, subitem.id);
7753
+ const renderSubItemGroup = (group, itemId) => {
7754
+ const headingId = `it-sidebar-subgroup-${itemId}-${group.id}`;
7755
+ return /* @__PURE__ */ (0, import_jsx_runtime56.jsxs)("li", { className: "relative", children: [
7756
+ /* @__PURE__ */ (0, import_jsx_runtime56.jsx)("div", { id: headingId, className: "px-3 pt-2.5 pb-1 mt-1", children: /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(
7757
+ ITText,
7758
+ {
7759
+ as: "span",
7760
+ className: "block",
7761
+ style: {
7762
+ color: "var(--it-sidebar-icon-color, var(--color-secondary-400))",
7763
+ fontSize: "0.68rem",
7764
+ fontWeight: 700,
7765
+ letterSpacing: "0.08em",
7766
+ textTransform: "uppercase"
7767
+ },
7768
+ children: group.label
7769
+ }
7770
+ ) }),
7771
+ /* @__PURE__ */ (0, import_jsx_runtime56.jsx)("ul", { "aria-labelledby": headingId, className: "flex flex-col gap-0", children: group.items.map(renderSubItem) })
7772
+ ] }, group.id);
7773
+ };
7649
7774
  return /* @__PURE__ */ (0, import_jsx_runtime56.jsxs)(
7650
7775
  "aside",
7651
7776
  {
@@ -7779,7 +7904,7 @@ function ITSidebar({
7779
7904
  item.icon && /* @__PURE__ */ (0, import_jsx_runtime56.jsx)("span", { style: { color: "var(--it-sidebar-active-icon, var(--color-primary-500))" }, className: "text-xl drop-shadow-sm", children: item.icon }),
7780
7905
  /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(ITText, { as: "span", className: "tracking-wide text-[15px]", children: item.label })
7781
7906
  ] }),
7782
- item.subitems && item.subitems.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime56.jsx)("div", { className: "py-2", children: item.subitems.map((subitem) => /* @__PURE__ */ (0, import_jsx_runtime56.jsxs)(
7907
+ item.subitems && item.subitems.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime56.jsx)("div", { className: "py-2", children: flattenSubItems(item.subitems).map((subitem) => /* @__PURE__ */ (0, import_jsx_runtime56.jsxs)(
7783
7908
  "div",
7784
7909
  {
7785
7910
  className: `px-5 py-2.5 text-sm flex items-center gap-3 transition-colors relative`,
@@ -7803,66 +7928,16 @@ function ITSidebar({
7803
7928
  ]
7804
7929
  }
7805
7930
  ),
7806
- !isSidebarCollapsed && item.subitems && item.subitems.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime56.jsx)("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__ */ (0, import_jsx_runtime56.jsx)(
7931
+ !isSidebarCollapsed && item.subitems && item.subitems.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime56.jsx)("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-[1000px] opacity-100 mt-1" : "max-h-0 opacity-0"}`, children: /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(
7807
7932
  "ul",
7808
7933
  {
7809
7934
  className: "ml-4 flex flex-col gap-0 py-0.5",
7810
7935
  style: {
7811
7936
  borderLeft: subitemConnector === "|" ? "1px solid var(--it-sidebar-border, var(--color-secondary-200))" : "none"
7812
7937
  },
7813
- children: item.subitems.map((subitem) => /* @__PURE__ */ (0, import_jsx_runtime56.jsx)("li", { className: "relative", children: /* @__PURE__ */ (0, import_jsx_runtime56.jsxs)(
7814
- "button",
7815
- {
7816
- "aria-current": subitem.isActive ? "page" : void 0,
7817
- onClick: () => {
7818
- if (subitem.action) subitem.action();
7819
- if (onSubItemClick) onSubItemClick(subitem);
7820
- },
7821
- className: `flex items-center gap-2 w-full text-left px-3 py-1.5 rounded-xl transition-all duration-300`,
7822
- style: {
7823
- color: subitem.isActive ? "var(--it-sidebar-active-color, var(--color-secondary-900))" : "var(--it-sidebar-label-color, var(--color-secondary-600))",
7824
- backgroundColor: subitem.isActive ? "var(--it-sidebar-active-bg, var(--color-secondary-50))" : "transparent",
7825
- fontSize: "0.78rem",
7826
- fontWeight: subitem.isActive ? 600 : 500,
7827
- letterSpacing: "0.01em",
7828
- marginLeft: subitemConnector === "|" ? "-1px" : "0"
7829
- },
7830
- onMouseEnter: (e) => {
7831
- if (!subitem.isActive) {
7832
- e.currentTarget.style.backgroundColor = "var(--it-sidebar-hover-bg, var(--color-secondary-100))";
7833
- e.currentTarget.style.transform = "translateX(3px)";
7834
- }
7835
- },
7836
- onMouseLeave: (e) => {
7837
- if (!subitem.isActive) {
7838
- e.currentTarget.style.backgroundColor = "transparent";
7839
- e.currentTarget.style.transform = "translateX(0)";
7840
- }
7841
- },
7842
- children: [
7843
- subitem.isActive && subitemConnector === "|" && /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(
7844
- "div",
7845
- {
7846
- className: "absolute left-0 top-1/3 bottom-1/3 w-[2.5px] rounded-r-full transition-all",
7847
- style: {
7848
- backgroundColor: "var(--it-sidebar-active-icon, var(--color-primary-500))",
7849
- boxShadow: "0 0 6px color-mix(in srgb, var(--it-sidebar-active-icon, var(--color-primary-500)) 25%, transparent)"
7850
- }
7851
- }
7852
- ),
7853
- subitemConnector === "dot" && /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(
7854
- "span",
7855
- {
7856
- className: `w-1.5 h-1.5 rounded-full flex-shrink-0 transition-all duration-300 ${subitem.isActive ? "scale-125" : ""}`,
7857
- style: {
7858
- backgroundColor: subitem.isActive ? "var(--it-sidebar-active-icon, var(--color-primary-500))" : "var(--it-sidebar-icon-color, var(--color-secondary-400))"
7859
- }
7860
- }
7861
- ),
7862
- /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(ITText, { as: "span", className: "truncate", children: subitem.label })
7863
- ]
7864
- }
7865
- ) }, subitem.id))
7938
+ children: item.subitems.map(
7939
+ (entry) => isSubItemGroup(entry) ? renderSubItemGroup(entry, item.id) : renderSubItem(entry)
7940
+ )
7866
7941
  }
7867
7942
  ) })
7868
7943
  ] }, item.id);
@@ -8188,6 +8263,7 @@ function ITTable({
8188
8263
  const isStickyHeader = stickyHeader && isTableVirtual;
8189
8264
  const resolvedRowHeight = rowHeight ?? getRowHeight(size, density);
8190
8265
  const columnCount = columns.length;
8266
+ const pinnedMeta = import_react37.default.useMemo(() => getPinnedColumnMeta(columns), [columns]);
8191
8267
  const {
8192
8268
  scrollRef,
8193
8269
  startIndex,
@@ -8512,37 +8588,45 @@ function ITTable({
8512
8588
  {
8513
8589
  className: (0, import_clsx43.default)(tableHeaderRow, "dark:text-slate-200"),
8514
8590
  "aria-rowindex": isTableVirtual ? 1 : void 0,
8515
- children: columns.map((col) => /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(
8516
- "th",
8517
- {
8518
- scope: "col",
8519
- className: (0, import_clsx43.default)(
8520
- tableHeaderCell(col.className, density),
8521
- col.align && tableAlignClasses[col.align],
8522
- isStickyHeader && "sticky top-0 z-10 bg-secondary-50"
8523
- ),
8524
- style: col.minWidth != null || isStickyHeader ? {
8525
- ...col.minWidth != null ? { minWidth: `${col.minWidth}px` } : {},
8526
- ...isStickyHeader ? { backgroundColor: "var(--color-table-headerBg, #f8fafc)" } : {}
8527
- } : void 0,
8528
- children: /* @__PURE__ */ (0, import_jsx_runtime60.jsxs)("div", { className: isFixed ? "flex flex-col gap-3" : "flex flex-col gap-3 min-w-[150px]", children: [
8529
- /* @__PURE__ */ (0, import_jsx_runtime60.jsxs)("div", { className: "flex items-center justify-between gap-2", children: [
8530
- /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(ITText, { as: "span", className: "text-slate-900 dark:text-white font-bold", children: col.label }),
8531
- col.sortable && col.type !== "actions" && /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(
8532
- "button",
8533
- {
8534
- onClick: () => handleSort(col.key),
8535
- 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"}`,
8536
- title: `Ordenar por ${col.label}`,
8537
- children: /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(import_md2.MdOutlineSwapVert, { className: "w-4 h-4", "aria-hidden": "true" })
8538
- }
8539
- )
8540
- ] }),
8541
- /* @__PURE__ */ (0, import_jsx_runtime60.jsx)("div", { className: "w-full", children: col.filter ? renderFilterInput(col) : null })
8542
- ] })
8543
- },
8544
- col.key
8545
- ))
8591
+ children: columns.map((col) => {
8592
+ const pin = pinnedMeta[col.key];
8593
+ const isPinned = pin != null;
8594
+ return /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(
8595
+ "th",
8596
+ {
8597
+ scope: "col",
8598
+ className: (0, import_clsx43.default)(
8599
+ tableHeaderCell(col.className, density),
8600
+ col.align && tableAlignClasses[col.align],
8601
+ isPinned && "sticky",
8602
+ isStickyHeader && "sticky top-0 bg-secondary-50",
8603
+ isPinned ? "z-[15]" : isStickyHeader && "z-10",
8604
+ isPinned && (col.pinned === "left" ? "it-table-pinned-left" : "it-table-pinned-right")
8605
+ ),
8606
+ style: col.minWidth != null || isStickyHeader || isPinned ? {
8607
+ ...col.minWidth != null ? { minWidth: `${col.minWidth}px` } : {},
8608
+ ...isStickyHeader || isPinned ? { backgroundColor: "var(--color-table-headerBg, #f8fafc)" } : {},
8609
+ ...isPinned ? pin.side === "left" ? { left: pin.offset } : { right: pin.offset } : {}
8610
+ } : void 0,
8611
+ children: /* @__PURE__ */ (0, import_jsx_runtime60.jsxs)("div", { className: isFixed ? "flex flex-col gap-3" : "flex flex-col gap-3 min-w-[150px]", children: [
8612
+ /* @__PURE__ */ (0, import_jsx_runtime60.jsxs)("div", { className: "flex items-center justify-between gap-2", children: [
8613
+ /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(ITText, { as: "span", className: "text-slate-900 dark:text-white font-bold", children: col.label }),
8614
+ col.sortable && col.type !== "actions" && /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(
8615
+ "button",
8616
+ {
8617
+ onClick: () => handleSort(col.key),
8618
+ 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"}`,
8619
+ title: `Ordenar por ${col.label}`,
8620
+ children: /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(import_md2.MdOutlineSwapVert, { className: "w-4 h-4", "aria-hidden": "true" })
8621
+ }
8622
+ )
8623
+ ] }),
8624
+ /* @__PURE__ */ (0, import_jsx_runtime60.jsx)("div", { className: "w-full", children: col.filter ? renderFilterInput(col) : null })
8625
+ ] })
8626
+ },
8627
+ col.key
8628
+ );
8629
+ })
8546
8630
  }
8547
8631
  ) }),
8548
8632
  /* @__PURE__ */ (0, import_jsx_runtime60.jsx)("tbody", { className: (0, import_clsx43.default)(tableBody, "dark:divide-slate-700/30"), children: currentData.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime60.jsxs)(import_jsx_runtime60.Fragment, { children: [
@@ -8564,14 +8648,22 @@ function ITTable({
8564
8648
  children: columns.map((col) => {
8565
8649
  const rawValue = getNestedValue(row, col.key);
8566
8650
  const truncateTitle = col.truncate && (typeof rawValue === "string" || typeof rawValue === "number") ? String(rawValue) : void 0;
8651
+ const pin = pinnedMeta[col.key];
8652
+ const isPinned = pin != null;
8567
8653
  return /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(
8568
8654
  "td",
8569
8655
  {
8570
8656
  className: (0, import_clsx43.default)(
8571
8657
  tableCell(col.className, density),
8572
- col.align && tableAlignClasses[col.align]
8658
+ col.align && tableAlignClasses[col.align],
8659
+ isPinned && "sticky bg-[var(--color-table-rowBg,white)] group-hover:bg-[var(--color-table-rowHover,var(--color-secondary-50))]",
8660
+ isPinned && (col.pinned === "left" ? "it-table-pinned-left" : "it-table-pinned-right"),
8661
+ isPinned && "z-[1]"
8573
8662
  ),
8574
- style: col.minWidth != null ? { minWidth: `${col.minWidth}px` } : void 0,
8663
+ style: col.minWidth != null || isPinned ? {
8664
+ ...col.minWidth != null ? { minWidth: `${col.minWidth}px` } : {},
8665
+ ...isPinned ? pin.side === "left" ? { left: pin.offset } : { right: pin.offset } : {}
8666
+ } : void 0,
8575
8667
  title: truncateTitle,
8576
8668
  children: col.type === "actions" ? /* @__PURE__ */ (0, import_jsx_runtime60.jsx)("div", { className: tableActionsCell, children: renderCellContent(col, row) }) : /* @__PURE__ */ (0, import_jsx_runtime60.jsx)("div", { className: (0, import_clsx43.default)(tableCellText, col.truncate && "truncate"), children: renderCellContent(col, row) })
8577
8669
  },