@sustaina/shared-ui 1.68.0 → 1.70.0

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/dist/index.js CHANGED
@@ -6593,7 +6593,7 @@ var MeasureText = React__namespace.forwardRef(({ style, children }, ref) => {
6593
6593
  React__namespace.useImperativeHandle(ref, () => ({
6594
6594
  isExceed: () => {
6595
6595
  const span = spanRef.current;
6596
- return span.scrollHeight > span.clientHeight;
6596
+ return span.scrollHeight > span.clientHeight || span.scrollWidth > span.clientWidth;
6597
6597
  },
6598
6598
  getHeight: () => spanRef.current.clientHeight
6599
6599
  }));
@@ -9020,7 +9020,7 @@ var HeaderCell = ({
9020
9020
  {
9021
9021
  ref,
9022
9022
  className: cn(
9023
- "flex items-center justify-between gap-2",
9023
+ "flex items-center justify-between gap-2 h-full",
9024
9024
  {
9025
9025
  "cursor-pointer": context?.column?.getCanSort()
9026
9026
  },
@@ -9048,13 +9048,17 @@ var HeaderCell = ({
9048
9048
  showSorter && /* @__PURE__ */ jsxRuntime.jsxs(
9049
9049
  "div",
9050
9050
  {
9051
- className: "flex flex-col -space-y-2",
9051
+ className: cn(
9052
+ "flex flex-col -space-y-2 transition-opacity duration-150",
9053
+ sorterProps?.rootClassName
9054
+ ),
9055
+ style: { opacity: hovering || !!context.column.getIsSorted() ? 1 : 0.35 },
9052
9056
  title: context.column.getCanSort() ? context.column.getNextSortingOrder() === "asc" ? "Sort ascending" : context.column.getNextSortingOrder() === "desc" ? "Sort descending" : "Clear sort" : void 0,
9053
9057
  children: [
9054
9058
  /* @__PURE__ */ jsxRuntime.jsx(
9055
9059
  lucideReact.ChevronUp,
9056
9060
  {
9057
- className: cn("stroke-[#BBBBBB]", {
9061
+ className: cn("stroke-[#BBBBBB] transition-colors duration-200", {
9058
9062
  "stroke-sus-gray-5": context?.column?.getIsSorted() === "asc",
9059
9063
  "stroke-sus-gray-5/45": context?.column?.getNextSortingOrder() === "asc" && hovering
9060
9064
  }),
@@ -9065,7 +9069,7 @@ var HeaderCell = ({
9065
9069
  /* @__PURE__ */ jsxRuntime.jsx(
9066
9070
  lucideReact.ChevronDown,
9067
9071
  {
9068
- className: cn("stroke-[#BBBBBB]", {
9072
+ className: cn("stroke-[#BBBBBB] transition-colors duration-200", {
9069
9073
  "stroke-sus-gray-5": context?.column?.getIsSorted() === "desc",
9070
9074
  "stroke-sus-gray-5/45": context?.column?.getNextSortingOrder() === "desc" && hovering
9071
9075
  }),
@@ -9141,7 +9145,7 @@ function TableHead({ className, ...props }) {
9141
9145
  {
9142
9146
  "data-slot": "table-head",
9143
9147
  className: cn(
9144
- "text-foreground h-9 px-2 text-left align-middle font-medium whitespace-nowrap [&:has([role=checkbox])]:pr-0 *:[[role=checkbox]]:translate-y-0.5 hover:bg-gray-200 bg-[#F0F0F0] truncate",
9148
+ "text-foreground h-9 px-2 text-left align-middle font-medium whitespace-nowrap [&:has([role=checkbox])]:pr-0 *:[[role=checkbox]]:translate-y-0.5 hover:bg-gray-200 bg-[#F0F0F0] truncate transition-colors duration-150",
9145
9149
  className
9146
9150
  ),
9147
9151
  ...props
@@ -9500,8 +9504,13 @@ var useScrollFetch = ({ scrollFetch, containerRef }) => {
9500
9504
  }, [fetchMoreOnScrollReached, containerRef]);
9501
9505
  return fetchMoreOnScrollReached;
9502
9506
  };
9507
+
9508
+ // src/components/data-table/constants.ts
9503
9509
  var DEFAULT_ROW_HEIGHT = 40;
9504
9510
  var DEFAULT_OVER_SCAN = 10;
9511
+ var DEFAULT_COLUMN_OVERSCAN = 1;
9512
+
9513
+ // src/components/data-table/hooks/useTableVirtualizer.ts
9505
9514
  var useTableVirtualizer = ({
9506
9515
  enabled,
9507
9516
  table,
@@ -9509,23 +9518,50 @@ var useTableVirtualizer = ({
9509
9518
  virtual
9510
9519
  }) => {
9511
9520
  const rowModel = table.getRowModel().rows;
9521
+ const columnsEnabled = virtual?.columns?.enabled ?? false;
9522
+ const centerColumns = table.getCenterVisibleLeafColumns();
9523
+ const getRowVirtualItemKey = React.useCallback((index) => rowModel[index]?.id ?? index, [rowModel]);
9524
+ const getColumnVirtualItemKey = React.useCallback(
9525
+ (index) => centerColumns[index]?.id ?? index,
9526
+ [centerColumns]
9527
+ );
9512
9528
  const virtualizer = reactVirtual.useVirtualizer({
9513
9529
  count: enabled ? rowModel.length : 0,
9514
9530
  useFlushSync: false,
9515
9531
  getScrollElement: () => containerRef.current,
9516
9532
  estimateSize: () => DEFAULT_ROW_HEIGHT,
9533
+ getItemKey: getRowVirtualItemKey,
9517
9534
  measureElement: typeof window !== "undefined" && navigator.userAgent.indexOf("Firefox") === -1 ? (element) => element?.getBoundingClientRect().height : void 0,
9518
9535
  overscan: virtual?.overscan ?? DEFAULT_OVER_SCAN
9519
9536
  });
9537
+ const columnVirtualizer = reactVirtual.useVirtualizer({
9538
+ count: columnsEnabled ? centerColumns.length : 0,
9539
+ estimateSize: (index) => centerColumns[index]?.getSize() ?? 0,
9540
+ getScrollElement: () => containerRef.current,
9541
+ horizontal: true,
9542
+ getItemKey: getColumnVirtualItemKey,
9543
+ overscan: virtual?.columns?.overscan ?? DEFAULT_COLUMN_OVERSCAN
9544
+ });
9520
9545
  const virtualItems = enabled ? virtualizer.getVirtualItems() : [];
9521
9546
  const paddingTop = enabled && virtualItems.length > 0 ? virtualItems[0].start : 0;
9522
9547
  const paddingBottom = enabled && virtualItems.length > 0 ? virtualizer.getTotalSize() - virtualItems[virtualItems.length - 1].end : 0;
9548
+ let columnVirtual;
9549
+ if (!columnsEnabled) {
9550
+ columnVirtual = { enabled: false };
9551
+ } else {
9552
+ const virtualColumns = columnVirtualizer.getVirtualItems();
9553
+ const virtualPaddingLeft = virtualColumns[0]?.start ?? 0;
9554
+ const virtualPaddingRight = columnVirtualizer.getTotalSize() - (virtualColumns[virtualColumns.length - 1]?.end ?? 0);
9555
+ columnVirtual = { enabled: true, virtualColumns, virtualPaddingLeft, virtualPaddingRight };
9556
+ }
9523
9557
  return {
9524
9558
  virtualizer,
9559
+ columnVirtualizer,
9525
9560
  virtualItems,
9526
9561
  paddingTop,
9527
9562
  paddingBottom,
9528
- rowModel
9563
+ rowModel,
9564
+ columnVirtual
9529
9565
  };
9530
9566
  };
9531
9567
  function useComputedTableState({
@@ -9628,6 +9664,7 @@ var ColumnSeparator = ({ show, className, ...props }) => {
9628
9664
  var ColumnSeparator_default = React__namespace.default.memo(ColumnSeparator);
9629
9665
 
9630
9666
  // src/components/data-table/helpers.ts
9667
+ var toCSSId = (id) => id.replace(/[^a-zA-Z0-9_-]/g, "-");
9631
9668
  function getColumnPinningInfo(column) {
9632
9669
  const isPinned = column.getIsPinned();
9633
9670
  const isLastLeftPinnedColumn = isPinned === "left" && column.getIsLastColumn("left");
@@ -9638,8 +9675,8 @@ function getColumnPinningStyles(column) {
9638
9675
  const { isPinned, isFirstRightPinnedColumn, isLastLeftPinnedColumn } = getColumnPinningInfo(column);
9639
9676
  const classes = cn(isPinned ? "sticky" : "relative");
9640
9677
  const style = {
9641
- left: isPinned === "left" ? column.getStart("left") : void 0,
9642
- right: isPinned === "right" ? column.getAfter("right") : void 0,
9678
+ left: isPinned === "left" ? `calc(var(--col-${toCSSId(column.id)}-pin-start, ${column.getStart("left")}) * 1px)` : void 0,
9679
+ right: isPinned === "right" ? `calc(var(--col-${toCSSId(column.id)}-pin-after, ${column.getAfter("right")}) * 1px)` : void 0,
9643
9680
  zIndex: isPinned ? 1 : 0,
9644
9681
  boxShadow: isLastLeftPinnedColumn ? "inset -1px 0 0 0 black" : isFirstRightPinnedColumn ? "inset 1px 0 0 0 black" : void 0
9645
9682
  };
@@ -9658,102 +9695,223 @@ function getRowClickHandlers(handler, { rowData, row, table }) {
9658
9695
  onClick: handleClick
9659
9696
  };
9660
9697
  }
9698
+ function renderHeaderCell(header, headerGroup, {
9699
+ columnResizing,
9700
+ virtual,
9701
+ components,
9702
+ table
9703
+ }, rowSpan) {
9704
+ const { classes, style } = getColumnPinningStyles(header.column);
9705
+ const useColumnSizing = header.column.columnDef?.meta?.useColumnSizing ?? columnResizing?.enabled ?? virtual?.enabled ?? false;
9706
+ const tableHeadCellProps = typeof components?.tableHeadCellProps === "function" ? components?.tableHeadCellProps({ header, table }) : components?.tableHeadCellProps;
9707
+ const nextHeader = headerGroup.headers?.[header.index + 1] || header;
9708
+ const { isLastLeftPinnedColumn } = getColumnPinningInfo(header.column);
9709
+ const { isFirstRightPinnedColumn } = getColumnPinningInfo(nextHeader.column);
9710
+ const headerGroupLength = headerGroup.headers.length;
9711
+ const showSeparator = header.index !== headerGroupLength - 1 && !isLastLeftPinnedColumn && !isFirstRightPinnedColumn && (!header.isPlaceholder || !nextHeader.isPlaceholder);
9712
+ return /* @__PURE__ */ jsxRuntime.jsxs(
9713
+ TableHead,
9714
+ {
9715
+ "data-testid": `table-head-${header.id}`,
9716
+ colSpan: header.colSpan,
9717
+ rowSpan,
9718
+ ...tableHeadCellProps,
9719
+ ...header.column.columnDef?.meta?.headerProps,
9720
+ className: cn(
9721
+ classes,
9722
+ tableHeadCellProps?.className,
9723
+ header.column.columnDef?.meta?.headerProps?.className
9724
+ ),
9725
+ style: {
9726
+ ...style,
9727
+ width: useColumnSizing ? `calc(var(--header-${toCSSId(header.id)}-size, ${header.getSize()}) * 1px)` : void 0,
9728
+ minWidth: useColumnSizing ? header.column.columnDef.minSize : void 0,
9729
+ maxWidth: useColumnSizing ? header.column.columnDef.maxSize : void 0,
9730
+ ...tableHeadCellProps?.style,
9731
+ ...header.column.columnDef?.meta?.headerProps?.style
9732
+ },
9733
+ children: [
9734
+ !header.isPlaceholder || rowSpan ? reactTable.flexRender(header.column.columnDef.header, header.getContext()) : null,
9735
+ /* @__PURE__ */ jsxRuntime.jsx(
9736
+ ColumnSeparator_default,
9737
+ {
9738
+ ...components?.columnSeparatorProps?.headerCell,
9739
+ ...header.column.columnDef?.meta?.columnSeparatorProps,
9740
+ show: header.column.columnDef?.meta?.columnSeparatorProps?.show ?? components?.columnSeparatorProps?.headerCell?.show ?? showSeparator
9741
+ }
9742
+ ),
9743
+ /* @__PURE__ */ jsxRuntime.jsx(ColumnResizer_default, { header, ...components?.columnResizerProps })
9744
+ ]
9745
+ },
9746
+ header.id
9747
+ );
9748
+ }
9661
9749
  var TableHeaderRows = ({
9662
9750
  table,
9663
9751
  columnResizing,
9664
9752
  virtual,
9753
+ columnVirtual,
9665
9754
  components
9666
9755
  }) => {
9667
- return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: table.getHeaderGroups().map((headerGroup) => {
9668
- return /* @__PURE__ */ jsxRuntime.jsx(TableRow, { children: headerGroup.headers.map((header) => {
9669
- const { classes, style } = getColumnPinningStyles(header.column);
9670
- const useColumnSizing = header.column.columnDef?.meta?.useColumnSizing ?? columnResizing?.enabled ?? virtual?.enabled ?? false;
9671
- const tableHeadCellProps = typeof components?.tableHeadCellProps === "function" ? components?.tableHeadCellProps({ header, table }) : components?.tableHeadCellProps;
9672
- const nextHeader = headerGroup.headers?.[header.index + 1] || header;
9673
- const { isLastLeftPinnedColumn } = getColumnPinningInfo(header.column);
9674
- const { isFirstRightPinnedColumn } = getColumnPinningInfo(nextHeader.column);
9675
- const headerGroupLength = header.headerGroup.headers.length;
9676
- const showSeparator = header.index !== headerGroupLength - 1 && !isLastLeftPinnedColumn && !isFirstRightPinnedColumn && (!header.isPlaceholder || !nextHeader.isPlaceholder);
9677
- return /* @__PURE__ */ jsxRuntime.jsxs(
9678
- TableHead,
9679
- {
9680
- "data-testid": `table-head-${header.id}`,
9681
- colSpan: header.colSpan,
9682
- ...tableHeadCellProps,
9683
- ...header.column.columnDef?.meta?.headerProps,
9684
- className: cn(
9685
- classes,
9686
- tableHeadCellProps?.className,
9687
- header.column.columnDef?.meta?.headerProps?.className
9688
- ),
9689
- style: {
9690
- ...style,
9691
- width: useColumnSizing ? `calc(var(--header-${header.id}-size, ${header.getSize()}) * 1px)` : void 0,
9692
- minWidth: useColumnSizing ? header.column.columnDef.minSize : void 0,
9693
- maxWidth: useColumnSizing ? header.column.columnDef.maxSize : void 0,
9694
- ...tableHeadCellProps?.style,
9695
- ...header.column.columnDef?.meta?.headerProps?.style
9696
- },
9697
- children: [
9698
- header.isPlaceholder ? null : reactTable.flexRender(header.column.columnDef.header, header.getContext()),
9699
- /* @__PURE__ */ jsxRuntime.jsx(
9700
- ColumnSeparator_default,
9701
- {
9702
- ...components?.columnSeparatorProps?.headerCell,
9703
- ...header.column.columnDef?.meta?.columnSeparatorProps,
9704
- show: header.column.columnDef?.meta?.columnSeparatorProps?.show ?? components?.columnSeparatorProps?.headerCell?.show ?? showSeparator
9705
- }
9756
+ const cellProps = { columnResizing, virtual, components, table };
9757
+ const centerLeafCols = columnVirtual.enabled ? table.getCenterVisibleLeafColumns() : [];
9758
+ const totalGroups = table.getHeaderGroups().length;
9759
+ const spannedIds = /* @__PURE__ */ new Set();
9760
+ const resolveHeaderCell = (header, headerGroup, groupIndex) => {
9761
+ if (spannedIds.has(header.column.id)) return null;
9762
+ const remainingRows = totalGroups - groupIndex;
9763
+ if (header.isPlaceholder && header.column.columnDef.meta?.spanRows && remainingRows > 1) {
9764
+ spannedIds.add(header.column.id);
9765
+ return renderHeaderCell(header, headerGroup, cellProps, remainingRows);
9766
+ }
9767
+ return renderHeaderCell(header, headerGroup, cellProps);
9768
+ };
9769
+ return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: table.getHeaderGroups().map((headerGroup, groupIndex) => {
9770
+ if (!columnVirtual.enabled) {
9771
+ return /* @__PURE__ */ jsxRuntime.jsx(TableRow, { children: headerGroup.headers.map((header) => resolveHeaderCell(header, headerGroup, groupIndex)) }, headerGroup.id);
9772
+ }
9773
+ const leftHeaders = table.getLeftHeaderGroups()[groupIndex]?.headers ?? [];
9774
+ const centerHeaders = table.getCenterHeaderGroups()[groupIndex]?.headers ?? [];
9775
+ const rightHeaders = table.getRightHeaderGroups()[groupIndex]?.headers ?? [];
9776
+ const isLeafLevel = !centerHeaders[0] || centerHeaders[0].subHeaders.length === 0;
9777
+ if (isLeafLevel) {
9778
+ return /* @__PURE__ */ jsxRuntime.jsxs(TableRow, { children: [
9779
+ leftHeaders.map((header) => resolveHeaderCell(header, headerGroup, groupIndex)),
9780
+ columnVirtual.virtualPaddingLeft > 0 && /* @__PURE__ */ jsxRuntime.jsx("th", { "aria-hidden": "true", style: { width: columnVirtual.virtualPaddingLeft } }),
9781
+ columnVirtual.virtualColumns.map((vc) => {
9782
+ const header = centerHeaders[vc.index];
9783
+ if (!header) return null;
9784
+ return renderHeaderCell(header, headerGroup, cellProps);
9785
+ }),
9786
+ columnVirtual.virtualPaddingRight > 0 && /* @__PURE__ */ jsxRuntime.jsx("th", { "aria-hidden": "true", style: { width: columnVirtual.virtualPaddingRight } }),
9787
+ rightHeaders.map((header) => resolveHeaderCell(header, headerGroup, groupIndex))
9788
+ ] }, headerGroup.id);
9789
+ }
9790
+ const leafToGroupIdx = [];
9791
+ let leafRunning = 0;
9792
+ for (let gi = 0; gi < centerHeaders.length; gi++) {
9793
+ for (let i = 0; i < centerHeaders[gi].colSpan; i++) {
9794
+ leafToGroupIdx[leafRunning + i] = gi;
9795
+ }
9796
+ leafRunning += centerHeaders[gi].colSpan;
9797
+ }
9798
+ const virtualCols = columnVirtual.virtualColumns;
9799
+ const useColumnSizing = columnResizing?.enabled ?? virtual?.enabled ?? false;
9800
+ return /* @__PURE__ */ jsxRuntime.jsxs(TableRow, { children: [
9801
+ leftHeaders.map((header) => resolveHeaderCell(header, headerGroup, groupIndex)),
9802
+ columnVirtual.virtualPaddingLeft > 0 && /* @__PURE__ */ jsxRuntime.jsx("th", { "aria-hidden": "true", style: { width: columnVirtual.virtualPaddingLeft } }),
9803
+ virtualCols.map((vc, vcIdx) => {
9804
+ const gi = leafToGroupIdx[vc.index];
9805
+ if (gi === void 0) return null;
9806
+ const groupHeader = centerHeaders[gi];
9807
+ const leafCol = centerLeafCols[vc.index];
9808
+ const isFirst = vcIdx === 0 || leafToGroupIdx[virtualCols[vcIdx - 1].index] !== gi;
9809
+ const isLast = vcIdx === virtualCols.length - 1 || leafToGroupIdx[virtualCols[vcIdx + 1].index] !== gi;
9810
+ const { classes, style } = getColumnPinningStyles(groupHeader.column);
9811
+ const tableHeadCellProps = typeof components?.tableHeadCellProps === "function" ? components.tableHeadCellProps({ header: groupHeader, table }) : components?.tableHeadCellProps;
9812
+ return /* @__PURE__ */ jsxRuntime.jsxs(
9813
+ TableHead,
9814
+ {
9815
+ colSpan: 1,
9816
+ ...tableHeadCellProps,
9817
+ ...groupHeader.column.columnDef?.meta?.headerProps,
9818
+ className: cn(
9819
+ classes,
9820
+ tableHeadCellProps?.className,
9821
+ groupHeader.column.columnDef?.meta?.headerProps?.className
9706
9822
  ),
9707
- /* @__PURE__ */ jsxRuntime.jsx(ColumnResizer_default, { header, ...components?.columnResizerProps })
9708
- ]
9709
- },
9710
- header.id
9711
- );
9712
- }) }, headerGroup.id);
9823
+ style: {
9824
+ ...style,
9825
+ width: useColumnSizing ? `calc(var(--col-${toCSSId(leafCol.id)}-size, ${leafCol.getSize()}) * 1px)` : void 0,
9826
+ ...tableHeadCellProps?.style,
9827
+ ...groupHeader.column.columnDef?.meta?.headerProps?.style
9828
+ },
9829
+ children: [
9830
+ isFirst && !groupHeader.isPlaceholder ? reactTable.flexRender(groupHeader.column.columnDef.header, groupHeader.getContext()) : null,
9831
+ /* @__PURE__ */ jsxRuntime.jsx(ColumnSeparator_default, { ...components?.columnSeparatorProps?.headerCell, show: isLast })
9832
+ ]
9833
+ },
9834
+ `${groupHeader.id}-${leafCol.id}`
9835
+ );
9836
+ }),
9837
+ columnVirtual.virtualPaddingRight > 0 && /* @__PURE__ */ jsxRuntime.jsx("th", { "aria-hidden": "true", style: { width: columnVirtual.virtualPaddingRight } }),
9838
+ rightHeaders.map((header) => resolveHeaderCell(header, headerGroup, groupIndex))
9839
+ ] }, headerGroup.id);
9713
9840
  }) });
9714
9841
  };
9842
+ var MemoizedTableHeaderRows = React__namespace.default.memo(
9843
+ TableHeaderRows,
9844
+ (_, next) => next.isResizing === true
9845
+ );
9846
+ function renderFilterCell(column, {
9847
+ columnResizing,
9848
+ virtual,
9849
+ components,
9850
+ table
9851
+ }) {
9852
+ const { classes, style } = getColumnPinningStyles(column);
9853
+ const useColumnSizing = column.columnDef.meta?.useColumnSizing ?? columnResizing?.enabled ?? virtual?.enabled ?? false;
9854
+ const tableFilterCellProps = typeof components?.tableFilterCellProps === "function" ? components?.tableFilterCellProps({ column, table }) : components?.tableFilterCellProps;
9855
+ return /* @__PURE__ */ jsxRuntime.jsx(
9856
+ TableCell,
9857
+ {
9858
+ "data-testid": `table-filter-cell-${column.id}`,
9859
+ ...tableFilterCellProps,
9860
+ ...column.columnDef?.meta?.filterCellProps,
9861
+ className: cn(
9862
+ "bg-white border-b",
9863
+ classes,
9864
+ tableFilterCellProps?.className,
9865
+ column.columnDef?.meta?.filterCellProps?.className
9866
+ ),
9867
+ style: {
9868
+ ...style,
9869
+ width: useColumnSizing ? `calc(var(--col-${toCSSId(column.id)}-size, ${column.getSize()}) * 1px)` : void 0,
9870
+ minWidth: useColumnSizing ? column.columnDef.minSize : void 0,
9871
+ maxWidth: useColumnSizing ? column.columnDef.maxSize : void 0,
9872
+ ...tableFilterCellProps?.style,
9873
+ ...column.columnDef?.meta?.filterCellProps?.style
9874
+ },
9875
+ children: column.getCanFilter() && column.columnDef.meta?.renderColumnFilter?.({
9876
+ column,
9877
+ table
9878
+ })
9879
+ },
9880
+ column.id
9881
+ );
9882
+ }
9715
9883
  var TableFilterRow = ({
9716
9884
  table,
9717
9885
  filterableColumns,
9718
9886
  isSomeColumnsFilterable,
9719
9887
  columnResizing,
9720
9888
  virtual,
9889
+ columnVirtual,
9721
9890
  components
9722
9891
  }) => {
9723
9892
  if (!isSomeColumnsFilterable) return null;
9724
- return /* @__PURE__ */ jsxRuntime.jsx(TableRow, { "data-testid": "table-filter-row", children: filterableColumns.map((column) => {
9725
- const { classes, style } = getColumnPinningStyles(column);
9726
- const useColumnSizing = column.columnDef.meta?.useColumnSizing ?? columnResizing?.enabled ?? virtual?.enabled ?? false;
9727
- const tableFilterCellProps = typeof components?.tableFilterCellProps === "function" ? components?.tableFilterCellProps({ column, table }) : components?.tableFilterCellProps;
9728
- return /* @__PURE__ */ jsxRuntime.jsx(
9729
- TableCell,
9730
- {
9731
- "data-testid": `table-filter-cell-${column.id}`,
9732
- ...tableFilterCellProps,
9733
- ...column.columnDef?.meta?.filterCellProps,
9734
- className: cn(
9735
- "bg-white border-b",
9736
- classes,
9737
- tableFilterCellProps?.className,
9738
- column.columnDef?.meta?.filterCellProps?.className
9739
- ),
9740
- style: {
9741
- ...style,
9742
- width: useColumnSizing ? `calc(var(--col-${column.id}-size, ${column.getSize()}) * 1px)` : void 0,
9743
- minWidth: useColumnSizing ? column.columnDef.minSize : void 0,
9744
- maxWidth: useColumnSizing ? column.columnDef.maxSize : void 0,
9745
- ...tableFilterCellProps?.style,
9746
- ...column.columnDef?.meta?.filterCellProps?.style
9747
- },
9748
- children: column.getCanFilter() && column.columnDef.meta?.renderColumnFilter?.({
9749
- column,
9750
- table
9751
- })
9752
- },
9753
- column.id
9754
- );
9755
- }) });
9893
+ const cellProps = { columnResizing, virtual, components, table };
9894
+ if (!columnVirtual.enabled) {
9895
+ return /* @__PURE__ */ jsxRuntime.jsx(TableRow, { "data-testid": "table-filter-row", children: filterableColumns.map((column) => renderFilterCell(column, cellProps)) });
9896
+ }
9897
+ const centerColumns = table.getCenterVisibleLeafColumns();
9898
+ const leftColumns = filterableColumns.filter((col) => col.getIsPinned() === "left");
9899
+ const centerFilterColumns = filterableColumns.filter((col) => !col.getIsPinned());
9900
+ const rightColumns = filterableColumns.filter((col) => col.getIsPinned() === "right");
9901
+ const centerColumnIndexMap = new Map(centerColumns.map((col, i) => [col.id, i]));
9902
+ const virtualIndexSet = new Set(columnVirtual.virtualColumns.map((vc) => vc.index));
9903
+ return /* @__PURE__ */ jsxRuntime.jsxs(TableRow, { "data-testid": "table-filter-row", children: [
9904
+ leftColumns.map((column) => renderFilterCell(column, cellProps)),
9905
+ columnVirtual.virtualPaddingLeft > 0 && /* @__PURE__ */ jsxRuntime.jsx("td", { "aria-hidden": "true", style: { width: columnVirtual.virtualPaddingLeft } }),
9906
+ centerFilterColumns.filter((col) => virtualIndexSet.has(centerColumnIndexMap.get(col.id) ?? -1)).map((column) => renderFilterCell(column, cellProps)),
9907
+ columnVirtual.virtualPaddingRight > 0 && /* @__PURE__ */ jsxRuntime.jsx("td", { "aria-hidden": "true", style: { width: columnVirtual.virtualPaddingRight } }),
9908
+ rightColumns.map((column) => renderFilterCell(column, cellProps))
9909
+ ] });
9756
9910
  };
9911
+ var MemoizedTableFilterRow = React__namespace.default.memo(
9912
+ TableFilterRow,
9913
+ (_, next) => next.isResizing === true
9914
+ );
9757
9915
  var TableDataRows = ({
9758
9916
  table,
9759
9917
  rowModel,
@@ -9765,6 +9923,7 @@ var TableDataRows = ({
9765
9923
  visibleColumnCount,
9766
9924
  columnResizing,
9767
9925
  virtual,
9926
+ columnVirtual,
9768
9927
  onRowClick,
9769
9928
  components
9770
9929
  }) => {
@@ -9783,6 +9942,56 @@ var TableDataRows = ({
9783
9942
  if (!row) return null;
9784
9943
  const virtualIndex = config.isVirtualize ? item.index : void 0;
9785
9944
  const tableDataRowProps = typeof components?.tableDataRowProps === "function" ? components.tableDataRowProps({ row, table }) || {} : components?.tableDataRowProps || {};
9945
+ const renderCell = (cell) => {
9946
+ const { classes, style } = getColumnPinningStyles(cell.column);
9947
+ const useColumnSizing = cell.column.columnDef.meta?.useColumnSizing ?? columnResizing?.enabled ?? virtual?.enabled ?? false;
9948
+ const tableDataCellProps = typeof components?.tableDataCellProps === "function" ? components?.tableDataCellProps({ row, cell, table }) : components?.tableDataCellProps;
9949
+ return /* @__PURE__ */ jsxRuntime.jsx(
9950
+ TableCell,
9951
+ {
9952
+ "data-testid": `table-data-cell-${cell.id}`,
9953
+ "data-row-id": row.id,
9954
+ "data-column-id": cell.column.id,
9955
+ ...tableDataCellProps,
9956
+ ...cell.column.columnDef?.meta?.cellProps,
9957
+ className: cn(
9958
+ {
9959
+ "bg-[#dfeae3]": row.getIsSelected(),
9960
+ "bg-white group-hover:bg-sus-primary-3-hover transition-colors duration-150": !row.getIsSelected()
9961
+ },
9962
+ classes,
9963
+ tableDataCellProps?.className,
9964
+ cell.column.columnDef?.meta?.cellProps?.className
9965
+ ),
9966
+ style: {
9967
+ ...style,
9968
+ width: useColumnSizing ? `calc(var(--col-${toCSSId(cell.column.id)}-size, ${cell.column.getSize()}) * 1px)` : void 0,
9969
+ minWidth: useColumnSizing ? cell.column.columnDef.minSize : void 0,
9970
+ maxWidth: useColumnSizing ? cell.column.columnDef.maxSize : void 0,
9971
+ ...tableDataCellProps?.style,
9972
+ ...cell.column.columnDef?.meta?.cellProps?.style
9973
+ },
9974
+ children: reactTable.flexRender(cell.column.columnDef.cell, cell.getContext())
9975
+ },
9976
+ cell.id
9977
+ );
9978
+ };
9979
+ const rowContent = columnVirtual.enabled ? (() => {
9980
+ const leftCells = row.getLeftVisibleCells();
9981
+ const centerCells = row.getCenterVisibleCells();
9982
+ const rightCells = row.getRightVisibleCells();
9983
+ return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
9984
+ leftCells.map(renderCell),
9985
+ columnVirtual.virtualPaddingLeft > 0 && /* @__PURE__ */ jsxRuntime.jsx("td", { "aria-hidden": "true", style: { width: columnVirtual.virtualPaddingLeft } }),
9986
+ columnVirtual.virtualColumns.map((vc) => {
9987
+ const cell = centerCells[vc.index];
9988
+ if (!cell) return null;
9989
+ return renderCell(cell);
9990
+ }),
9991
+ columnVirtual.virtualPaddingRight > 0 && /* @__PURE__ */ jsxRuntime.jsx("td", { "aria-hidden": "true", style: { width: columnVirtual.virtualPaddingRight } }),
9992
+ rightCells.map(renderCell)
9993
+ ] });
9994
+ })() : row.getVisibleCells().map(renderCell);
9786
9995
  return /* @__PURE__ */ React.createElement(
9787
9996
  TableRow,
9788
9997
  {
@@ -9800,40 +10009,7 @@ var TableDataRows = ({
9800
10009
  table
9801
10010
  })
9802
10011
  },
9803
- row.getVisibleCells().map((cell) => {
9804
- const { classes, style } = getColumnPinningStyles(cell.column);
9805
- const useColumnSizing = cell.column.columnDef.meta?.useColumnSizing ?? columnResizing?.enabled ?? virtual?.enabled ?? false;
9806
- const tableDataCellProps = typeof components?.tableDataCellProps === "function" ? components?.tableDataCellProps({ row, cell, table }) : components?.tableDataCellProps;
9807
- return /* @__PURE__ */ jsxRuntime.jsx(
9808
- TableCell,
9809
- {
9810
- "data-testid": `table-data-cell-${cell.id}`,
9811
- "data-row-id": row.id,
9812
- "data-column-id": cell.column.id,
9813
- ...tableDataCellProps,
9814
- ...cell.column.columnDef?.meta?.cellProps,
9815
- className: cn(
9816
- {
9817
- "bg-[#dfeae3]": row.getIsSelected(),
9818
- "bg-white group-hover:bg-sus-primary-3-hover": !row.getIsSelected()
9819
- },
9820
- classes,
9821
- tableDataCellProps?.className,
9822
- cell.column.columnDef?.meta?.cellProps?.className
9823
- ),
9824
- style: {
9825
- ...style,
9826
- width: useColumnSizing ? `calc(var(--col-${cell.column.id}-size, ${cell.column.getSize()}) * 1px)` : void 0,
9827
- minWidth: useColumnSizing ? cell.column.columnDef.minSize : void 0,
9828
- maxWidth: useColumnSizing ? cell.column.columnDef.maxSize : void 0,
9829
- ...tableDataCellProps?.style,
9830
- ...cell.column.columnDef?.meta?.cellProps?.style
9831
- },
9832
- children: reactTable.flexRender(cell.column.columnDef.cell, cell.getContext())
9833
- },
9834
- cell.id
9835
- );
9836
- })
10012
+ rowContent
9837
10013
  );
9838
10014
  }),
9839
10015
  virtualEnabled && paddingBottom > 0 && /* @__PURE__ */ jsxRuntime.jsx(TableRow, { "aria-hidden": "true", "data-testid": "table-virtual-padding-bottom", children: /* @__PURE__ */ jsxRuntime.jsx(
@@ -9848,68 +10024,161 @@ var TableDataRows = ({
9848
10024
  };
9849
10025
  var MemoizedTableDataRows = React__namespace.default.memo(
9850
10026
  TableDataRows,
9851
- (prev, next) => prev.table.options.data === next.table.options.data
10027
+ (_, next) => next.isResizing === true
9852
10028
  );
10029
+ function renderFooterCell(footer, footerGroup, {
10030
+ columnResizing,
10031
+ virtual,
10032
+ components,
10033
+ table
10034
+ }, rowSpan) {
10035
+ const { classes, style } = getColumnPinningStyles(footer.column);
10036
+ const useColumnSizing = footer.column.columnDef?.meta?.useColumnSizing ?? columnResizing?.enabled ?? virtual?.enabled ?? false;
10037
+ const tableFooterCellProps = typeof components?.tableFooterCellProps === "function" ? components.tableFooterCellProps({ footer, table }) : components?.tableFooterCellProps;
10038
+ const nextFooter = footerGroup.headers[footer.index + 1] ?? footer;
10039
+ const { isLastLeftPinnedColumn } = getColumnPinningInfo(footer.column);
10040
+ const { isFirstRightPinnedColumn } = getColumnPinningInfo(nextFooter.column);
10041
+ const footerGroupLength = footerGroup.headers.length;
10042
+ const showSeparator = footer.index !== footerGroupLength - 1 && !isLastLeftPinnedColumn && !isFirstRightPinnedColumn && (!footer.isPlaceholder || !nextFooter.isPlaceholder);
10043
+ return /* @__PURE__ */ jsxRuntime.jsxs(
10044
+ TableHead,
10045
+ {
10046
+ "data-testid": `footer-cell-${footer.id}`,
10047
+ colSpan: footer.colSpan,
10048
+ rowSpan,
10049
+ ...tableFooterCellProps,
10050
+ ...footer.column.columnDef?.meta?.footerProps,
10051
+ className: cn(
10052
+ classes,
10053
+ tableFooterCellProps?.className,
10054
+ footer.column.columnDef?.meta?.footerProps?.className
10055
+ ),
10056
+ style: {
10057
+ ...style,
10058
+ width: useColumnSizing ? `calc(var(--col-${toCSSId(footer.column.id)}-size, ${footer.column.getSize()}) * 1px)` : void 0,
10059
+ minWidth: useColumnSizing ? footer.column.columnDef.minSize : void 0,
10060
+ maxWidth: useColumnSizing ? footer.column.columnDef.maxSize : void 0,
10061
+ ...tableFooterCellProps?.style,
10062
+ ...footer.column.columnDef?.meta?.footerProps?.style
10063
+ },
10064
+ children: [
10065
+ footer.isPlaceholder ? null : reactTable.flexRender(footer.column.columnDef.footer, footer.getContext()),
10066
+ /* @__PURE__ */ jsxRuntime.jsx(
10067
+ ColumnSeparator_default,
10068
+ {
10069
+ ...components?.columnSeparatorProps?.headerCell,
10070
+ ...footer.column.columnDef?.meta?.columnSeparatorProps,
10071
+ show: footer.column.columnDef?.meta?.columnSeparatorProps?.show ?? components?.columnSeparatorProps?.headerCell?.show ?? showSeparator
10072
+ }
10073
+ ),
10074
+ !footer.isPlaceholder && /* @__PURE__ */ jsxRuntime.jsx(ColumnResizer_default, { header: footer, ...components?.columnResizerProps })
10075
+ ]
10076
+ },
10077
+ footer.id
10078
+ );
10079
+ }
9853
10080
  var TableFooterRows = ({
9854
10081
  table,
9855
10082
  columnResizing,
9856
- components,
9857
- virtual
10083
+ virtual,
10084
+ columnVirtual,
10085
+ components
9858
10086
  }) => {
9859
- const hasAnyFooter = table.getAllColumns().some((col) => col.columnDef.footer != null);
9860
- if (!hasAnyFooter) return null;
9861
- return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: table.getFooterGroups().map((footerGroup) => {
10087
+ const cellProps = { columnResizing, virtual, components, table };
10088
+ const centerLeafCols = columnVirtual.enabled ? table.getCenterVisibleLeafColumns() : [];
10089
+ const totalFooterGroups = table.getFooterGroups().length;
10090
+ const spannedIds = /* @__PURE__ */ new Set();
10091
+ const resolveFooterCell = (footer, footerGroup, groupIndex) => {
10092
+ if (spannedIds.has(footer.column.id)) return null;
10093
+ const remainingRows = totalFooterGroups - groupIndex;
10094
+ if (!footer.isPlaceholder && footer.column.columnDef.meta?.spanRows && remainingRows > 1) {
10095
+ spannedIds.add(footer.column.id);
10096
+ return renderFooterCell(footer, footerGroup, cellProps, remainingRows);
10097
+ }
10098
+ return renderFooterCell(footer, footerGroup, cellProps);
10099
+ };
10100
+ return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: table.getFooterGroups().map((footerGroup, groupIndex) => {
9862
10101
  const tableFooterRowProps = typeof components?.tableFooterRowProps === "function" ? components.tableFooterRowProps({ footerGroup, table }) : components?.tableFooterRowProps;
9863
- return /* @__PURE__ */ jsxRuntime.jsx(TableRow, { ...tableFooterRowProps, children: footerGroup.headers.map((footer) => {
9864
- const { classes, style } = getColumnPinningStyles(footer.column);
9865
- const useColumnSizing = footer.column.columnDef?.meta?.useColumnSizing ?? columnResizing?.enabled ?? virtual?.enabled ?? false;
9866
- const tableFooterCellProps = typeof components?.tableFooterCellProps === "function" ? components.tableFooterCellProps({ footer, table }) : components?.tableFooterCellProps;
9867
- const nextFooter = footerGroup.headers[footer.index + 1] ?? footer;
9868
- const { isLastLeftPinnedColumn } = getColumnPinningInfo(footer.column);
9869
- const { isFirstRightPinnedColumn } = getColumnPinningInfo(nextFooter.column);
9870
- const footerGroupLength = footer.headerGroup.headers.length;
9871
- const showSeparator = footer.index !== footerGroupLength - 1 && !isLastLeftPinnedColumn && !isFirstRightPinnedColumn && (!footer.isPlaceholder || !nextFooter.isPlaceholder);
9872
- return /* @__PURE__ */ jsxRuntime.jsxs(
9873
- TableHead,
9874
- {
9875
- "data-testid": `footer-cell-${footer.id}`,
9876
- colSpan: footer.colSpan,
9877
- ...tableFooterCellProps,
9878
- ...footer.column.columnDef?.meta?.footerProps,
9879
- className: cn(
9880
- classes,
9881
- tableFooterCellProps?.className,
9882
- footer.column.columnDef?.meta?.footerProps?.className
9883
- ),
9884
- style: {
9885
- ...style,
9886
- width: useColumnSizing ? `calc(var(--col-${footer.column.id}-size, ${footer.column.getSize()}) * 1px)` : void 0,
9887
- minWidth: useColumnSizing ? footer.column.columnDef.minSize : void 0,
9888
- maxWidth: useColumnSizing ? footer.column.columnDef.maxSize : void 0,
9889
- ...tableFooterCellProps?.style,
9890
- ...footer.column.columnDef?.meta?.footerProps?.style
9891
- },
9892
- children: [
9893
- footer.isPlaceholder ? null : reactTable.flexRender(footer.column.columnDef.footer, footer.getContext()),
9894
- /* @__PURE__ */ jsxRuntime.jsx(
9895
- ColumnSeparator_default,
9896
- {
9897
- ...components?.columnSeparatorProps?.headerCell,
9898
- ...footer.column.columnDef?.meta?.columnSeparatorProps,
9899
- show: footer.column.columnDef?.meta?.columnSeparatorProps?.show ?? components?.columnSeparatorProps?.headerCell?.show ?? showSeparator
9900
- }
10102
+ if (!columnVirtual.enabled) {
10103
+ return /* @__PURE__ */ jsxRuntime.jsx(TableRow, { ...tableFooterRowProps, children: footerGroup.headers.map((footer) => resolveFooterCell(footer, footerGroup, groupIndex)) }, footerGroup.id);
10104
+ }
10105
+ const leftFooters = table.getLeftFooterGroups()[groupIndex]?.headers ?? [];
10106
+ const centerFooters = table.getCenterFooterGroups()[groupIndex]?.headers ?? [];
10107
+ const rightFooters = table.getRightFooterGroups()[groupIndex]?.headers ?? [];
10108
+ const isLeafLevel = !centerFooters[0] || centerFooters[0].subHeaders.length === 0;
10109
+ if (isLeafLevel) {
10110
+ return /* @__PURE__ */ jsxRuntime.jsxs(TableRow, { ...tableFooterRowProps, children: [
10111
+ leftFooters.map((footer) => resolveFooterCell(footer, footerGroup, groupIndex)),
10112
+ columnVirtual.virtualPaddingLeft > 0 && /* @__PURE__ */ jsxRuntime.jsx("th", { "aria-hidden": "true", style: { width: columnVirtual.virtualPaddingLeft } }),
10113
+ columnVirtual.virtualColumns.map((vc) => {
10114
+ const footer = centerFooters[vc.index];
10115
+ if (!footer) return null;
10116
+ return renderFooterCell(footer, footerGroup, cellProps);
10117
+ }),
10118
+ columnVirtual.virtualPaddingRight > 0 && /* @__PURE__ */ jsxRuntime.jsx("th", { "aria-hidden": "true", style: { width: columnVirtual.virtualPaddingRight } }),
10119
+ rightFooters.map((footer) => resolveFooterCell(footer, footerGroup, groupIndex))
10120
+ ] }, footerGroup.id);
10121
+ }
10122
+ const leafToGroupIdx = [];
10123
+ let leafRunning = 0;
10124
+ for (let gi = 0; gi < centerFooters.length; gi++) {
10125
+ for (let i = 0; i < centerFooters[gi].colSpan; i++) {
10126
+ leafToGroupIdx[leafRunning + i] = gi;
10127
+ }
10128
+ leafRunning += centerFooters[gi].colSpan;
10129
+ }
10130
+ const virtualCols = columnVirtual.virtualColumns;
10131
+ const useColumnSizing = columnResizing?.enabled ?? virtual?.enabled ?? false;
10132
+ return /* @__PURE__ */ jsxRuntime.jsxs(TableRow, { ...tableFooterRowProps, children: [
10133
+ leftFooters.map((footer) => resolveFooterCell(footer, footerGroup, groupIndex)),
10134
+ columnVirtual.virtualPaddingLeft > 0 && /* @__PURE__ */ jsxRuntime.jsx("th", { "aria-hidden": "true", style: { width: columnVirtual.virtualPaddingLeft } }),
10135
+ virtualCols.map((vc, vcIdx) => {
10136
+ const gi = leafToGroupIdx[vc.index];
10137
+ if (gi === void 0) return null;
10138
+ const groupFooter = centerFooters[gi];
10139
+ const leafCol = centerLeafCols[vc.index];
10140
+ const isFirst = vcIdx === 0 || leafToGroupIdx[virtualCols[vcIdx - 1].index] !== gi;
10141
+ const isLast = vcIdx === virtualCols.length - 1 || leafToGroupIdx[virtualCols[vcIdx + 1].index] !== gi;
10142
+ const { classes, style } = getColumnPinningStyles(groupFooter.column);
10143
+ const tableFooterCellProps = typeof components?.tableFooterCellProps === "function" ? components.tableFooterCellProps({ footer: groupFooter, table }) : components?.tableFooterCellProps;
10144
+ return /* @__PURE__ */ jsxRuntime.jsxs(
10145
+ TableHead,
10146
+ {
10147
+ colSpan: 1,
10148
+ ...tableFooterCellProps,
10149
+ ...groupFooter.column.columnDef?.meta?.footerProps,
10150
+ className: cn(
10151
+ classes,
10152
+ tableFooterCellProps?.className,
10153
+ groupFooter.column.columnDef?.meta?.footerProps?.className
9901
10154
  ),
9902
- !footer.isPlaceholder && /* @__PURE__ */ jsxRuntime.jsx(ColumnResizer_default, { header: footer, ...components?.columnResizerProps })
9903
- ]
9904
- },
9905
- footer.id
9906
- );
9907
- }) }, footerGroup.id);
10155
+ style: {
10156
+ ...style,
10157
+ width: useColumnSizing ? `calc(var(--col-${toCSSId(leafCol.id)}-size, ${leafCol.getSize()}) * 1px)` : void 0,
10158
+ ...tableFooterCellProps?.style,
10159
+ ...groupFooter.column.columnDef?.meta?.footerProps?.style
10160
+ },
10161
+ children: [
10162
+ isFirst && !groupFooter.isPlaceholder ? reactTable.flexRender(groupFooter.column.columnDef.footer, groupFooter.getContext()) : null,
10163
+ /* @__PURE__ */ jsxRuntime.jsx(ColumnSeparator_default, { ...components?.columnSeparatorProps?.headerCell, show: isLast })
10164
+ ]
10165
+ },
10166
+ `${groupFooter.id}-${leafCol.id}`
10167
+ );
10168
+ }),
10169
+ columnVirtual.virtualPaddingRight > 0 && /* @__PURE__ */ jsxRuntime.jsx("th", { "aria-hidden": "true", style: { width: columnVirtual.virtualPaddingRight } }),
10170
+ rightFooters.map((footer) => resolveFooterCell(footer, footerGroup, groupIndex))
10171
+ ] }, footerGroup.id);
9908
10172
  }) });
9909
10173
  };
10174
+ var MemoizedTableFooterRows = React__namespace.default.memo(
10175
+ TableFooterRows,
10176
+ (_, next) => next.isResizing === true
10177
+ );
9910
10178
  var DataTable = ({
9911
10179
  tableRef,
9912
10180
  virtualizerRef,
10181
+ columnVirtualizerRef,
9913
10182
  isInitialLoading,
9914
10183
  columns,
9915
10184
  data,
@@ -9949,7 +10218,15 @@ var DataTable = ({
9949
10218
  rowIdKey,
9950
10219
  childrenKey
9951
10220
  });
9952
- const { virtualizer, virtualItems, paddingTop, paddingBottom, rowModel } = useTableVirtualizer({
10221
+ const {
10222
+ virtualizer,
10223
+ columnVirtualizer,
10224
+ virtualItems,
10225
+ paddingTop,
10226
+ paddingBottom,
10227
+ rowModel,
10228
+ columnVirtual
10229
+ } = useTableVirtualizer({
9953
10230
  enabled: virtualEnabled,
9954
10231
  table,
9955
10232
  containerRef: tableContainerRef,
@@ -9970,14 +10247,21 @@ var DataTable = ({
9970
10247
  const headers = table.getFlatHeaders();
9971
10248
  const colSizes = {};
9972
10249
  for (const header of headers) {
9973
- colSizes[`--header-${header.id}-size`] = header.getSize();
9974
- colSizes[`--col-${header.column.id}-size`] = header.column.getSize();
10250
+ colSizes[`--header-${toCSSId(header.id)}-size`] = header.getSize();
10251
+ colSizes[`--col-${toCSSId(header.column.id)}-size`] = header.column.getSize();
10252
+ if (header.column.getIsPinned() === "left") {
10253
+ colSizes[`--col-${toCSSId(header.column.id)}-pin-start`] = header.column.getStart("left");
10254
+ } else if (header.column.getIsPinned() === "right") {
10255
+ colSizes[`--col-${toCSSId(header.column.id)}-pin-after`] = header.column.getAfter("right");
10256
+ }
9975
10257
  }
9976
10258
  return colSizes;
9977
10259
  }, [columnSizing, columnSizingInfo, columnResizingEnabled, virtualEnabled]);
9978
- const isResizing = columnResizingEnabled && !!columnSizingInfo.isResizingColumn;
10260
+ const isResizing = !columnVirtual.enabled && (columnResizingEnabled ?? false) && !!columnSizingInfo.isResizingColumn;
10261
+ const hasAnyFooter = table.getAllColumns().some((col) => col.columnDef.footer != null);
9979
10262
  useBindRef_default({ ref: tableRef, value: table });
9980
10263
  useBindRef_default({ ref: virtualizerRef, value: virtualizer });
10264
+ useBindRef_default({ ref: columnVirtualizerRef, value: columnVirtualizer });
9981
10265
  return /* @__PURE__ */ jsxRuntime.jsxs(
9982
10266
  TableContainer,
9983
10267
  {
@@ -10013,47 +10297,52 @@ var DataTable = ({
10013
10297
  },
10014
10298
  defaultIcon: /* @__PURE__ */ jsxRuntime.jsx(SuiEmptyDataIcon, { size: 128 })
10015
10299
  }
10016
- ) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
10017
- /* @__PURE__ */ jsxRuntime.jsxs(
10018
- Table,
10019
- {
10020
- ...components?.tableProps,
10021
- style: {
10022
- tableLayout: virtualEnabled ? "fixed" : "auto",
10023
- ...components?.tableProps?.style,
10024
- ...columnSizeVars
10025
- },
10026
- children: [
10027
- /* @__PURE__ */ jsxRuntime.jsxs(
10028
- TableHeader,
10029
- {
10030
- className: cn("sticky top-0 z-10 bg-white", components?.tableHeaderProps?.className),
10031
- ...components?.tableHeaderProps,
10032
- children: [
10033
- /* @__PURE__ */ jsxRuntime.jsx(
10034
- TableHeaderRows,
10035
- {
10036
- table,
10037
- columnResizing,
10038
- virtual,
10039
- components
10040
- }
10041
- ),
10042
- /* @__PURE__ */ jsxRuntime.jsx(
10043
- TableFilterRow,
10044
- {
10045
- table,
10046
- filterableColumns,
10047
- isSomeColumnsFilterable,
10048
- columnResizing,
10049
- virtual,
10050
- components
10051
- }
10052
- )
10053
- ]
10054
- }
10055
- ),
10056
- /* @__PURE__ */ jsxRuntime.jsx(TableBody, { ...components?.tableBodyProps, children: isResizing ? /* @__PURE__ */ jsxRuntime.jsx(
10300
+ ) : /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: /* @__PURE__ */ jsxRuntime.jsxs(
10301
+ Table,
10302
+ {
10303
+ ...components?.tableProps,
10304
+ style: {
10305
+ tableLayout: virtualEnabled ? "fixed" : "auto",
10306
+ minWidth: columnVirtual.enabled ? `${table.getTotalSize()}px` : void 0,
10307
+ ...components?.tableProps?.style,
10308
+ ...columnSizeVars
10309
+ },
10310
+ children: [
10311
+ /* @__PURE__ */ jsxRuntime.jsxs(
10312
+ TableHeader,
10313
+ {
10314
+ className: cn("sticky top-0 z-10 bg-white", components?.tableHeaderProps?.className),
10315
+ ...components?.tableHeaderProps,
10316
+ children: [
10317
+ /* @__PURE__ */ jsxRuntime.jsx(
10318
+ MemoizedTableHeaderRows,
10319
+ {
10320
+ table,
10321
+ columnResizing,
10322
+ virtual,
10323
+ columnVirtual,
10324
+ components,
10325
+ isResizing
10326
+ }
10327
+ ),
10328
+ /* @__PURE__ */ jsxRuntime.jsx(
10329
+ MemoizedTableFilterRow,
10330
+ {
10331
+ table,
10332
+ filterableColumns,
10333
+ isSomeColumnsFilterable,
10334
+ columnResizing,
10335
+ virtual,
10336
+ columnVirtual,
10337
+ components,
10338
+ isResizing
10339
+ }
10340
+ )
10341
+ ]
10342
+ }
10343
+ ),
10344
+ /* @__PURE__ */ jsxRuntime.jsxs(TableBody, { ...components?.tableBodyProps, children: [
10345
+ /* @__PURE__ */ jsxRuntime.jsx(
10057
10346
  MemoizedTableDataRows,
10058
10347
  {
10059
10348
  table,
@@ -10066,82 +10355,70 @@ var DataTable = ({
10066
10355
  visibleColumnCount,
10067
10356
  columnResizing,
10068
10357
  virtual,
10358
+ columnVirtual,
10069
10359
  onRowClick,
10070
- components
10360
+ components,
10361
+ isResizing
10071
10362
  }
10072
- ) : /* @__PURE__ */ jsxRuntime.jsx(
10073
- TableDataRows,
10363
+ ),
10364
+ activeStatusContentComputed === "emptyFilteredData" && /* @__PURE__ */ jsxRuntime.jsx(TableRow, { "data-testid": "status-row-empty-filtered-data", children: /* @__PURE__ */ jsxRuntime.jsx(TableCell, { colSpan: visibleColumnCount, className: "border-b-0 p-0", children: /* @__PURE__ */ jsxRuntime.jsx(
10365
+ StatusContentSlot_default,
10074
10366
  {
10075
- table,
10076
- rowModel,
10077
- virtualEnabled,
10078
- virtualItems,
10079
- virtualizer,
10080
- paddingTop,
10081
- paddingBottom,
10082
- visibleColumnCount,
10083
- columnResizing,
10084
- virtual,
10085
- onRowClick,
10086
- components
10367
+ content: statusContent?.emptyFilteredData?.content ?? "No records found. Please try a different search.",
10368
+ icon: statusContent?.emptyFilteredData?.icon,
10369
+ wrapperProps: statusContent?.emptyFilteredData?.wrapperProps,
10370
+ defaultWrapperProps: {
10371
+ className: "flex flex-col items-center justify-center text-sm py-4 gap-2",
10372
+ ["data-testid"]: "status-content-empty-filtered-data"
10373
+ },
10374
+ defaultIcon: /* @__PURE__ */ jsxRuntime.jsx(SuiEmptyDataIcon, { size: 128 })
10087
10375
  }
10088
- ) }),
10089
- /* @__PURE__ */ jsxRuntime.jsx(
10090
- TableFooter,
10376
+ ) }) }),
10377
+ activeStatusContentComputed === "fetchingMore" && /* @__PURE__ */ jsxRuntime.jsx(TableRow, { "data-testid": "status-row-fetching-more", children: /* @__PURE__ */ jsxRuntime.jsx(TableCell, { colSpan: visibleColumnCount, className: "border-b-0 p-0", children: /* @__PURE__ */ jsxRuntime.jsx(
10378
+ StatusContentSlot_default,
10091
10379
  {
10092
- ...components?.tableFooterProps,
10093
- className: cn("sticky bottom-0 z-10 bg-white", components?.tableFooterProps?.className),
10094
- children: /* @__PURE__ */ jsxRuntime.jsx(
10095
- TableFooterRows,
10096
- {
10097
- table,
10098
- columnResizing,
10099
- virtual,
10100
- components
10101
- }
10102
- )
10380
+ content: statusContent?.fetchingMore?.content ?? "Loading more...",
10381
+ wrapperProps: statusContent?.fetchingMore?.wrapperProps,
10382
+ defaultWrapperProps: {
10383
+ className: "flex flex-col items-center justify-center text-sm py-4 gap-2",
10384
+ ["data-testid"]: "status-content-fetching-more"
10385
+ }
10103
10386
  }
10104
- )
10105
- ]
10106
- }
10107
- ),
10108
- activeStatusContentComputed === "emptyFilteredData" && /* @__PURE__ */ jsxRuntime.jsx(
10109
- StatusContentSlot_default,
10110
- {
10111
- content: statusContent?.emptyFilteredData?.content ?? "No records found. Please try a different search.",
10112
- icon: statusContent?.emptyFilteredData?.icon,
10113
- wrapperProps: statusContent?.emptyFilteredData?.wrapperProps,
10114
- defaultWrapperProps: {
10115
- className: "flex flex-col h-[calc(100%-76px)] items-center justify-center text-sm py-4 gap-2",
10116
- ["data-testid"]: "status-content-empty-filtered-data"
10117
- },
10118
- defaultIcon: /* @__PURE__ */ jsxRuntime.jsx(SuiEmptyDataIcon, { size: 128 })
10119
- }
10120
- ),
10121
- activeStatusContentComputed === "fetchingMore" && /* @__PURE__ */ jsxRuntime.jsx(
10122
- StatusContentSlot_default,
10123
- {
10124
- content: statusContent?.fetchingMore?.content ?? "Loading more...",
10125
- wrapperProps: statusContent?.fetchingMore?.wrapperProps,
10126
- defaultWrapperProps: {
10127
- className: "flex flex-col items-center justify-center text-sm py-4 gap-2",
10128
- ["data-testid"]: "status-content-fetching-more"
10129
- }
10130
- }
10131
- ),
10132
- activeStatusContentComputed === "noMoreData" && /* @__PURE__ */ jsxRuntime.jsx(
10133
- StatusContentSlot_default,
10134
- {
10135
- content: statusContent?.noMoreData?.content,
10136
- icon: statusContent?.noMoreData?.icon,
10137
- wrapperProps: statusContent?.noMoreData?.wrapperProps,
10138
- defaultWrapperProps: {
10139
- className: "flex flex-col items-center justify-center text-sm py-4 gap-2",
10140
- ["data-testid"]: "status-content-no-more-data"
10141
- }
10142
- }
10143
- )
10144
- ] }),
10387
+ ) }) }),
10388
+ activeStatusContentComputed === "noMoreData" && /* @__PURE__ */ jsxRuntime.jsx(TableRow, { "data-testid": "status-row-no-more-data", children: /* @__PURE__ */ jsxRuntime.jsx(TableCell, { colSpan: visibleColumnCount, className: "border-b-0 p-0", children: /* @__PURE__ */ jsxRuntime.jsx(
10389
+ StatusContentSlot_default,
10390
+ {
10391
+ content: statusContent?.noMoreData?.content,
10392
+ icon: statusContent?.noMoreData?.icon,
10393
+ wrapperProps: statusContent?.noMoreData?.wrapperProps,
10394
+ defaultWrapperProps: {
10395
+ className: "flex flex-col items-center justify-center text-sm py-4 gap-2",
10396
+ ["data-testid"]: "status-content-no-more-data"
10397
+ }
10398
+ }
10399
+ ) }) })
10400
+ ] }),
10401
+ hasAnyFooter && /* @__PURE__ */ jsxRuntime.jsx(
10402
+ TableFooter,
10403
+ {
10404
+ ...components?.tableFooterProps,
10405
+ className: cn("sticky bottom-0 z-10 bg-white", components?.tableFooterProps?.className),
10406
+ children: /* @__PURE__ */ jsxRuntime.jsx(
10407
+ MemoizedTableFooterRows,
10408
+ {
10409
+ table,
10410
+ columnResizing,
10411
+ virtual,
10412
+ columnVirtual,
10413
+ components,
10414
+ isResizing
10415
+ }
10416
+ )
10417
+ }
10418
+ )
10419
+ ]
10420
+ }
10421
+ ) }),
10145
10422
  debug && /* @__PURE__ */ jsxRuntime.jsx(DataTableDevTool_default, { table })
10146
10423
  ]
10147
10424
  }
@@ -10264,7 +10541,7 @@ var DateTimePicker = ({
10264
10541
  },
10265
10542
  [currentHour, handleTimeApply]
10266
10543
  );
10267
- const hours = React__namespace.default.useMemo(() => Array.from({ length: 24 }, (_, index) => 23 - index), []);
10544
+ const hours = React__namespace.default.useMemo(() => Array.from({ length: 24 }, (_, index) => index), []);
10268
10545
  const minuteInterval = React__namespace.default.useMemo(() => {
10269
10546
  const safeStep = Math.min(60, Math.max(1, minuteStep));
10270
10547
  return Array.from({ length: Math.ceil(60 / safeStep) }, (_, index) => index * safeStep).filter(
@@ -13395,23 +13672,12 @@ function TooltipProvider2({
13395
13672
  delayDuration = 0,
13396
13673
  ...props
13397
13674
  }) {
13398
- return /* @__PURE__ */ jsxRuntime.jsx(
13399
- TooltipPrimitive__namespace.Provider,
13400
- {
13401
- "data-slot": "tooltip-provider",
13402
- delayDuration,
13403
- ...props
13404
- }
13405
- );
13675
+ return /* @__PURE__ */ jsxRuntime.jsx(TooltipPrimitive__namespace.Provider, { "data-slot": "tooltip-provider", delayDuration, ...props });
13406
13676
  }
13407
- function Tooltip2({
13408
- ...props
13409
- }) {
13677
+ function Tooltip2({ ...props }) {
13410
13678
  return /* @__PURE__ */ jsxRuntime.jsx(TooltipProvider2, { children: /* @__PURE__ */ jsxRuntime.jsx(TooltipPrimitive__namespace.Root, { "data-slot": "tooltip", ...props }) });
13411
13679
  }
13412
- function TooltipTrigger2({
13413
- ...props
13414
- }) {
13680
+ function TooltipTrigger2({ ...props }) {
13415
13681
  return /* @__PURE__ */ jsxRuntime.jsx(TooltipPrimitive__namespace.Trigger, { "data-slot": "tooltip-trigger", ...props });
13416
13682
  }
13417
13683
  function TooltipArrow(props) {
@@ -14017,6 +14283,144 @@ var Image2 = React__namespace.forwardRef(function Image3({
14017
14283
  );
14018
14284
  });
14019
14285
  Image2.displayName = "Image";
14286
+ function LanguageSelector({
14287
+ tenant,
14288
+ selectedLocale,
14289
+ onSelectLocale,
14290
+ errorLocales = [],
14291
+ enableErrorHighlight = false,
14292
+ sortLocales = true,
14293
+ priorityLocale = "en",
14294
+ className,
14295
+ visibleLocalesCount = 3,
14296
+ localeButtonWidth = 35,
14297
+ localeGap = 4
14298
+ }) {
14299
+ const orderedTenant = React__namespace.default.useMemo(() => {
14300
+ const normalizedPriority = priorityLocale.trim().toLowerCase();
14301
+ const localeAwareSorted = sortLocales ? [...tenant].sort(
14302
+ (a, b) => a.locale.localeCompare(b.locale, void 0, { sensitivity: "base", numeric: true })
14303
+ ) : [...tenant];
14304
+ if (!normalizedPriority) {
14305
+ return localeAwareSorted;
14306
+ }
14307
+ return localeAwareSorted.sort((a, b) => {
14308
+ const aIsPriority = a.locale.toLowerCase() === normalizedPriority;
14309
+ const bIsPriority = b.locale.toLowerCase() === normalizedPriority;
14310
+ if (aIsPriority && !bIsPriority) return -1;
14311
+ if (!aIsPriority && bIsPriority) return 1;
14312
+ return 0;
14313
+ });
14314
+ }, [priorityLocale, sortLocales, tenant]);
14315
+ const selectedIndex = orderedTenant.findIndex((t) => t.locale === selectedLocale);
14316
+ const currentIndex = selectedIndex >= 0 ? selectedIndex : 0;
14317
+ const isFirst = currentIndex <= 0;
14318
+ const isLast = currentIndex >= orderedTenant.length - 1;
14319
+ const safeVisibleCount = Math.min(orderedTenant.length, Math.max(1, visibleLocalesCount));
14320
+ const halfWindow = Math.floor((safeVisibleCount - 1) / 2);
14321
+ const maxStart = Math.max(0, orderedTenant.length - safeVisibleCount);
14322
+ const windowStart = Math.min(maxStart, Math.max(0, currentIndex - halfWindow));
14323
+ const visibleLocales = orderedTenant.slice(windowStart, windowStart + safeVisibleCount);
14324
+ const safeLocaleButtonWidth = Math.max(28, localeButtonWidth);
14325
+ const safeLocaleGap = Math.max(0, localeGap);
14326
+ const localeAreaWidth = safeVisibleCount * safeLocaleButtonWidth + (safeVisibleCount - 1) * safeLocaleGap;
14327
+ const localeWindowRef = React__namespace.default.useRef(null);
14328
+ const previousWindowStartRef = React__namespace.default.useRef(windowStart);
14329
+ React__namespace.default.useEffect(() => {
14330
+ const previousWindowStart = previousWindowStartRef.current;
14331
+ if (previousWindowStart === windowStart) {
14332
+ return;
14333
+ }
14334
+ previousWindowStartRef.current = windowStart;
14335
+ const localeWindow = localeWindowRef.current;
14336
+ if (!localeWindow) {
14337
+ return;
14338
+ }
14339
+ if (window.matchMedia("(prefers-reduced-motion: reduce)").matches) {
14340
+ return;
14341
+ }
14342
+ const movingRight = windowStart > previousWindowStart;
14343
+ const offsetX = movingRight ? 10 : -10;
14344
+ localeWindow.animate(
14345
+ [
14346
+ { opacity: 0.86, transform: `translate3d(${offsetX}px, 0, 0) scale(0.992)` },
14347
+ { opacity: 1, transform: "translate3d(0, 0, 0) scale(1)" }
14348
+ ],
14349
+ {
14350
+ duration: 460,
14351
+ easing: "cubic-bezier(0.22, 1, 0.36, 1)"
14352
+ }
14353
+ );
14354
+ }, [windowStart]);
14355
+ if (orderedTenant.length <= 1) {
14356
+ return null;
14357
+ }
14358
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("flex items-center gap-1 min-w-0", className), children: [
14359
+ /* @__PURE__ */ jsxRuntime.jsx(
14360
+ "button",
14361
+ {
14362
+ type: "button",
14363
+ disabled: isFirst,
14364
+ "aria-label": "Select previous locale",
14365
+ onClick: () => !isFirst && onSelectLocale(orderedTenant[currentIndex - 1]),
14366
+ className: cn(
14367
+ "inline-flex h-8 w-8 items-center justify-center rounded-md transform-gpu motion-safe:transition-[transform,background-color,color,box-shadow] motion-safe:duration-400 motion-safe:ease-[cubic-bezier(0.22,1,0.36,1)] active:scale-[0.985]",
14368
+ isFirst ? "text-muted-foreground/30 cursor-not-allowed" : "text-muted-foreground hover:text-foreground hover:bg-muted hover:shadow-sm"
14369
+ ),
14370
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronLeft, { className: "h-4 w-4" })
14371
+ }
14372
+ ),
14373
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "min-w-0 overflow-hidden", style: { width: localeAreaWidth, maxWidth: "100%" }, children: /* @__PURE__ */ jsxRuntime.jsx(
14374
+ "div",
14375
+ {
14376
+ ref: localeWindowRef,
14377
+ className: "grid gap-1",
14378
+ style: {
14379
+ gridTemplateColumns: `repeat(${safeVisibleCount}, minmax(0, 1fr))`,
14380
+ columnGap: safeLocaleGap
14381
+ },
14382
+ children: visibleLocales.map((lang) => /* @__PURE__ */ jsxRuntime.jsx(
14383
+ "button",
14384
+ {
14385
+ type: "button",
14386
+ "data-locale": lang.locale,
14387
+ "aria-label": lang.locale.toUpperCase(),
14388
+ onClick: () => onSelectLocale(lang),
14389
+ className: cn(
14390
+ "h-8 min-w-0 px-2 text-xs font-medium rounded-md transform-gpu motion-safe:transition-[transform,background-color,color,box-shadow] motion-safe:duration-400 motion-safe:ease-[cubic-bezier(0.22,1,0.36,1)] active:scale-[0.985] select-none",
14391
+ selectedLocale === lang.locale ? "bg-primary text-primary-foreground shadow-sm" : "bg-muted text-muted-foreground hover:bg-muted/80 hover:shadow-sm",
14392
+ enableErrorHighlight && errorLocales.includes(lang.locale) && "ring-1 ring-inset ring-red-500"
14393
+ ),
14394
+ children: /* @__PURE__ */ jsxRuntime.jsx(
14395
+ truncated_default,
14396
+ {
14397
+ as: "span",
14398
+ className: "block w-full text-center",
14399
+ tooltipContentProps: { side: "bottom", sideOffset: 6 },
14400
+ children: lang.locale.toUpperCase()
14401
+ }
14402
+ )
14403
+ },
14404
+ lang.locale
14405
+ ))
14406
+ }
14407
+ ) }),
14408
+ /* @__PURE__ */ jsxRuntime.jsx(
14409
+ "button",
14410
+ {
14411
+ type: "button",
14412
+ disabled: isLast,
14413
+ "aria-label": "Select next locale",
14414
+ onClick: () => !isLast && onSelectLocale(orderedTenant[currentIndex + 1]),
14415
+ className: cn(
14416
+ "inline-flex h-8 w-8 items-center justify-center rounded-md transform-gpu motion-safe:transition-[transform,background-color,color,box-shadow] motion-safe:duration-400 motion-safe:ease-[cubic-bezier(0.22,1,0.36,1)] active:scale-[0.985]",
14417
+ isLast ? "text-muted-foreground/30 cursor-not-allowed" : "text-muted-foreground hover:text-foreground hover:bg-muted hover:shadow-sm"
14418
+ ),
14419
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronRight, { className: "h-4 w-4" })
14420
+ }
14421
+ )
14422
+ ] });
14423
+ }
14020
14424
  var AnimatedDots = () => {
14021
14425
  const dotAnimation = `
14022
14426
  @keyframes dot1 {
@@ -18877,6 +19281,7 @@ exports.Input = Input;
18877
19281
  exports.InputMention = InputMention;
18878
19282
  exports.InputNumber = InputNumber_default;
18879
19283
  exports.Label = Label2;
19284
+ exports.LanguageSelector = LanguageSelector;
18880
19285
  exports.LoadingPage = LoadingPage;
18881
19286
  exports.LookupSelect = LookupSelect;
18882
19287
  exports.MailIcon = MailIcon;