@ackplus/react-tanstack-data-table 1.1.6 → 1.1.10

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.
@@ -13,7 +13,6 @@ export interface TableHeaderProps extends TableHeadProps {
13
13
  draggable?: boolean;
14
14
  enableColumnResizing?: boolean;
15
15
  enableStickyHeader?: boolean;
16
- fitToScreen?: boolean;
17
16
  onColumnReorder?: (draggedColumnId: string, targetColumnId: string) => void;
18
17
  headerRowProps?: TableRowProps;
19
18
  headerCellProps?: TableCellProps;
@@ -1 +1 @@
1
- {"version":3,"file":"table-header.d.ts","sourceRoot":"","sources":["../../../../src/lib/components/headers/table-header.tsx"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAc,EAAE,YAAY,EAAE,MAAM,OAAO,CAAC;AAC5C,OAAO,EAAiD,cAAc,EAAE,aAAa,EAAE,cAAc,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAQtI,MAAM,WAAW,gBAAiB,SAAQ,cAAc;IACpD,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,eAAe,CAAC,EAAE,CAAC,eAAe,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,KAAK,IAAI,CAAC;IAE5E,cAAc,CAAC,EAAE,aAAa,CAAC;IAC/B,eAAe,CAAC,EAAE,cAAc,CAAC;IACjC,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC5B,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAChC,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;CACtB;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,CAAC,EAAE,KAAK,EAAE,gBAAgB,GAAG,YAAY,CAuIpE"}
1
+ {"version":3,"file":"table-header.d.ts","sourceRoot":"","sources":["../../../../src/lib/components/headers/table-header.tsx"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAc,EAAE,YAAY,EAAE,MAAM,OAAO,CAAC;AAC5C,OAAO,EAAiD,cAAc,EAAE,aAAa,EAAE,cAAc,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAQtI,MAAM,WAAW,gBAAiB,SAAQ,cAAc;IACpD,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,eAAe,CAAC,EAAE,CAAC,eAAe,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,KAAK,IAAI,CAAC;IAE5E,cAAc,CAAC,EAAE,aAAa,CAAC;IAC/B,eAAe,CAAC,EAAE,cAAc,CAAC;IACjC,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC5B,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAChC,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;CACtB;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,CAAC,EAAE,KAAK,EAAE,gBAAgB,GAAG,YAAY,CA0IpE"}
@@ -24,7 +24,7 @@ const slot_helpers_1 = require("../../utils/slot-helpers");
24
24
  * Renders table headers with sorting, dragging, and resizing capabilities
25
25
  */
26
26
  function TableHeader(props) {
27
- const { draggable = false, enableColumnResizing = false, enableStickyHeader = false, fitToScreen = true, onColumnReorder, headerRowProps, headerCellProps, containerSx, resizeHandleSx, slots, slotProps, ...otherProps } = props;
27
+ const { draggable = false, enableColumnResizing = false, enableStickyHeader = false, onColumnReorder, headerRowProps, headerCellProps, containerSx, resizeHandleSx, slots, slotProps, ...otherProps } = props;
28
28
  const theme = (0, material_1.useTheme)();
29
29
  const { table } = (0, data_table_context_1.useDataTableContext)();
30
30
  // Extract slot-specific props with enhanced merging
@@ -47,12 +47,16 @@ function TableHeader(props) {
47
47
  const alignment = (0, utils_1.getColumnAlignment)(header.column.columnDef);
48
48
  const enableSorting = header.column.getCanSort();
49
49
  const wrapText = (_a = header.column.columnDef.wrapText) !== null && _a !== void 0 ? _a : false;
50
+ const minSize = header.column.columnDef.minSize;
51
+ const maxSize = header.column.columnDef.maxSize;
50
52
  const canResize = enableColumnResizing && header.column.getCanResize();
51
53
  const mergedHeaderCellProps = (0, slot_helpers_1.mergeSlotProps)({
52
54
  align: alignment,
53
55
  sx: {
54
56
  ...(0, utils_1.getPinnedColumnStyle)({
55
- width: fitToScreen ? 'auto' : header.getSize(),
57
+ width: header.getSize(),
58
+ minWidth: minSize !== undefined ? minSize : undefined,
59
+ maxWidth: maxSize !== undefined ? maxSize : undefined,
56
60
  isPinned,
57
61
  pinnedPosition,
58
62
  isLastLeftPinnedColumn: isPinned === 'left' && header.column.getIsLastColumn('left'),
@@ -97,7 +97,7 @@ function DataTableRow(props) {
97
97
  align: alignment,
98
98
  sx: {
99
99
  ...(0, utils_1.getPinnedColumnStyle)({
100
- width: cell.column.getSize() || 'auto',
100
+ width: cell.column.getSize(),
101
101
  minWidth: minSize !== undefined ? minSize : undefined,
102
102
  maxWidth: maxSize !== undefined ? maxSize : undefined,
103
103
  isPinned,
@@ -1 +1 @@
1
- {"version":3,"file":"loading-rows.d.ts","sourceRoot":"","sources":["../../../../src/lib/components/rows/loading-rows.tsx"],"names":[],"mappings":"AAAA,OAAc,EAAE,YAAY,EAAE,MAAM,OAAO,CAAC;AAC5C,OAAO,EAAiC,aAAa,EAAE,cAAc,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAMtG,MAAM,WAAW,gBAAgB;IAC7B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB,QAAQ,CAAC,EAAE,aAAa,CAAC;IACzB,SAAS,CAAC,EAAE,cAAc,CAAC;IAC3B,aAAa,CAAC,EAAE,GAAG,CAAC;IACpB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC5B,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAChC,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;CACtB;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,gBAAgB,GAAG,YAAY,CA4IjE"}
1
+ {"version":3,"file":"loading-rows.d.ts","sourceRoot":"","sources":["../../../../src/lib/components/rows/loading-rows.tsx"],"names":[],"mappings":"AAAA,OAAc,EAAE,YAAY,EAAE,MAAM,OAAO,CAAC;AAC5C,OAAO,EAAiC,aAAa,EAAE,cAAc,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAMtG,MAAM,WAAW,gBAAgB;IAC7B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB,QAAQ,CAAC,EAAE,aAAa,CAAC;IACzB,SAAS,CAAC,EAAE,cAAc,CAAC;IAC3B,aAAa,CAAC,EAAE,GAAG,CAAC;IACpB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC5B,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAChC,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;CACtB;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,gBAAgB,GAAG,YAAY,CAgJjE"}
@@ -24,12 +24,14 @@ function LoadingRows(props) {
24
24
  sx: containerSx,
25
25
  }, rowSlotProps, rowProps || {});
26
26
  return ((0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: Array.from({ length: rowCount }, (_, rowIndex) => ((0, jsx_runtime_1.jsx)(TableRowSlot, { ...mergedRowProps, children: visibleColumns.map((column, colIndex) => {
27
- var _a;
27
+ var _a, _b, _c;
28
28
  const isPinned = column.getIsPinned();
29
29
  const pinnedPosition = isPinned ? column.getStart('left') : undefined;
30
30
  const pinnedRightPosition = isPinned === 'right' ? column.getAfter('right') : undefined;
31
+ const minSize = (_a = column.columnDef) === null || _a === void 0 ? void 0 : _a.minSize;
32
+ const maxSize = (_b = column.columnDef) === null || _b === void 0 ? void 0 : _b.maxSize;
31
33
  // Determine skeleton type based on column meta or content
32
- const columnMeta = (_a = column.columnDef) === null || _a === void 0 ? void 0 : _a.meta;
34
+ const columnMeta = (_c = column.columnDef) === null || _c === void 0 ? void 0 : _c.meta;
33
35
  const isDateColumn = (columnMeta === null || columnMeta === void 0 ? void 0 : columnMeta.type) === 'date';
34
36
  const isBooleanColumn = (columnMeta === null || columnMeta === void 0 ? void 0 : columnMeta.type) === 'boolean';
35
37
  const isNumberColumn = (columnMeta === null || columnMeta === void 0 ? void 0 : columnMeta.type) === 'number';
@@ -37,7 +39,9 @@ function LoadingRows(props) {
37
39
  const mergedCellProps = (0, slot_helpers_1.mergeSlotProps)({
38
40
  sx: {
39
41
  ...(0, utils_1.getPinnedColumnStyle)({
40
- width: column.getSize() || 'auto',
42
+ width: column.getSize(),
43
+ minWidth: minSize !== undefined ? minSize : undefined,
44
+ maxWidth: maxSize !== undefined ? maxSize : undefined,
41
45
  isPinned,
42
46
  pinnedPosition,
43
47
  pinnedRightPosition,
@@ -1 +1 @@
1
- {"version":3,"file":"data-table.d.ts","sourceRoot":"","sources":["../../src/lib/data-table.tsx"],"names":[],"mappings":"AA6EA;;GAEG;AACH,eAAO,MAAM,SAAS,KA2yDpB,CAAC"}
1
+ {"version":3,"file":"data-table.d.ts","sourceRoot":"","sources":["../../src/lib/data-table.tsx"],"names":[],"mappings":"AA8EA;;GAEG;AACH,eAAO,MAAM,SAAS,KAyzDpB,CAAC"}
@@ -113,7 +113,7 @@ enableGlobalFilter = true, enableColumnFilter = false, filterMode = 'client',
113
113
  // Sorting props
114
114
  enableSorting = true, sortingMode = 'client', onSortingChange, exportFilename = 'export', onExportProgress, onExportComplete, onExportError, onServerExport, onExportCancel,
115
115
  // Styling props
116
- enableHover = true, enableStripes = false, tableProps = {}, fitToScreen = false, tableSize: initialTableSize = 'medium',
116
+ enableHover = true, enableStripes = false, tableProps = {}, fitToScreen = true, tableSize: initialTableSize = 'medium',
117
117
  // Sticky header/footer props
118
118
  enableStickyHeaderOrFooter = false, maxHeight = '400px',
119
119
  // Virtualization props
@@ -133,6 +133,7 @@ logging, }, ref) {
133
133
  const isServerPagination = paginationMode === 'server' || isServerMode;
134
134
  const isServerFiltering = filterMode === 'server' || isServerMode;
135
135
  const isServerSorting = sortingMode === 'server' || isServerMode;
136
+ const theme = (0, material_1.useTheme)();
136
137
  const logger = (0, react_1.useMemo)(() => (0, utils_1.createLogger)('DataTable', logging), [logging]);
137
138
  (0, react_1.useEffect)(() => {
138
139
  if (logger.isLevelEnabled('info')) {
@@ -237,7 +238,7 @@ logging, }, ref) {
237
238
  // -------------------------------
238
239
  // Callback hooks (grouped together)
239
240
  // -------------------------------
240
- const fetchData = (0, react_1.useCallback)(async (overrides = {}) => {
241
+ const fetchData = (0, react_1.useCallback)(async (overrides = {}, options) => {
241
242
  var _a, _b;
242
243
  if (!onFetchData) {
243
244
  if (logger.isLevelEnabled('debug')) {
@@ -256,7 +257,7 @@ logging, }, ref) {
256
257
  logger.info('Requesting data', { filters });
257
258
  }
258
259
  try {
259
- const result = await debouncedFetch(filters);
260
+ const result = await debouncedFetch(filters, options === undefined ? 0 : options.delay || 300);
260
261
  if (logger.isLevelEnabled('info')) {
261
262
  logger.info('Fetch resolved', {
262
263
  rows: (_b = (_a = result === null || result === void 0 ? void 0 : result.data) === null || _a === void 0 ? void 0 : _a.length) !== null && _b !== void 0 ? _b : 0,
@@ -611,6 +612,7 @@ logging, }, ref) {
611
612
  // Column resizing
612
613
  enableColumnResizing: enableColumnResizing,
613
614
  columnResizeMode: columnResizeMode,
615
+ columnResizeDirection: theme.direction,
614
616
  // Column pinning
615
617
  enableColumnPinning: enableColumnPinning,
616
618
  // Expanding
@@ -626,19 +628,20 @@ logging, }, ref) {
626
628
  debugAll: false, // Disabled for production
627
629
  });
628
630
  // Compute width after table is created so column resizing is safe and reflects changes
629
- const tableWidth = (0, react_1.useMemo)(() => {
630
- if (fitToScreen) {
631
- return '100%';
632
- }
633
- if (enableColumnResizing) {
634
- return table.getCenterTotalSize();
635
- }
636
- return '100%';
637
- }, [fitToScreen, enableColumnResizing, table]);
638
- const tableStyle = (0, react_1.useMemo)(() => ({
631
+ const allLeafColumns = table.getAllLeafColumns();
632
+ const visibleLeafColumns = table.getVisibleLeafColumns();
633
+ const hasExplicitSizing = allLeafColumns.some((column) => {
634
+ const { size, minSize, maxSize } = column.columnDef;
635
+ return size !== undefined || minSize !== undefined || maxSize !== undefined;
636
+ });
637
+ const useFixedLayout = fitToScreen || enableColumnResizing || hasExplicitSizing;
638
+ const tableTotalSize = table.getTotalSize();
639
+ const tableWidth = fitToScreen ? '100%' : (useFixedLayout ? tableTotalSize : '100%');
640
+ const tableStyle = {
639
641
  width: tableWidth,
640
- minWidth: '100%',
641
- }), [tableWidth]);
642
+ minWidth: fitToScreen ? tableTotalSize : undefined,
643
+ tableLayout: useFixedLayout ? 'fixed' : 'auto',
644
+ };
642
645
  // -------------------------------
643
646
  // Virtualization and row memo
644
647
  // -------------------------------
@@ -686,7 +689,7 @@ logging, }, ref) {
686
689
  if (logger.isLevelEnabled('info')) {
687
690
  logger.info('Initial data load triggered', { initialLoadData });
688
691
  }
689
- fetchData();
692
+ fetchData({});
690
693
  }
691
694
  else if (logger.isLevelEnabled('debug')) {
692
695
  logger.debug('Skipping initial data load', {
@@ -1016,7 +1019,7 @@ logging, }, ref) {
1016
1019
  reload: () => {
1017
1020
  const allState = table.getState();
1018
1021
  onDataStateChange === null || onDataStateChange === void 0 ? void 0 : onDataStateChange(allState);
1019
- onFetchData === null || onFetchData === void 0 ? void 0 : onFetchData({});
1022
+ fetchData === null || fetchData === void 0 ? void 0 : fetchData({});
1020
1023
  if (logger.isLevelEnabled('debug')) {
1021
1024
  logger.info('Reloading data', allState);
1022
1025
  }
@@ -1441,7 +1444,7 @@ logging, }, ref) {
1441
1444
  handleColumnFilterStateChange,
1442
1445
  idKey,
1443
1446
  onDataStateChange,
1444
- onFetchData,
1447
+ fetchData,
1445
1448
  enableColumnPinning,
1446
1449
  enablePagination,
1447
1450
  // Export dependencies
@@ -1557,9 +1560,12 @@ logging, }, ref) {
1557
1560
  ...tableContainerSlotProps === null || tableContainerSlotProps === void 0 ? void 0 : tableContainerSlotProps.sx,
1558
1561
  }, ...tableContainerSlotProps, children: (0, jsx_runtime_1.jsxs)(TableComponent, { size: tableSize, stickyHeader: enableStickyHeaderOrFooter, style: {
1559
1562
  ...tableStyle,
1560
- tableLayout: fitToScreen ? 'fixed' : 'auto',
1561
1563
  ...tableProps === null || tableProps === void 0 ? void 0 : tableProps.style,
1562
- }, ...(0, slot_helpers_1.mergeSlotProps)(tableProps || {}, tableComponentSlotProps), children: [(0, jsx_runtime_1.jsx)(headers_1.TableHeader, { draggable: enableColumnDragging, enableColumnResizing: enableColumnResizing, enableStickyHeader: enableStickyHeaderOrFooter, fitToScreen: fitToScreen, onColumnReorder: handleColumnReorder, slots: slots, slotProps: slotProps }), (0, jsx_runtime_1.jsx)(BodyComponent, { ...bodySlotProps, children: renderTableRows() })] }) }), enablePagination ? ((0, jsx_runtime_1.jsx)(FooterComponent, { sx: {
1564
+ }, ...(0, slot_helpers_1.mergeSlotProps)(tableProps || {}, tableComponentSlotProps), children: [useFixedLayout ? ((0, jsx_runtime_1.jsx)("colgroup", { children: visibleLeafColumns.map((column) => ((0, jsx_runtime_1.jsx)("col", { style: {
1565
+ width: column.getSize(),
1566
+ minWidth: column.columnDef.minSize,
1567
+ maxWidth: column.columnDef.maxSize,
1568
+ } }, column.id))) })) : null, (0, jsx_runtime_1.jsx)(headers_1.TableHeader, { draggable: enableColumnDragging, enableColumnResizing: enableColumnResizing, enableStickyHeader: enableStickyHeaderOrFooter, onColumnReorder: handleColumnReorder, slots: slots, slotProps: slotProps }), (0, jsx_runtime_1.jsx)(BodyComponent, { ...bodySlotProps, children: renderTableRows() })] }) }), enablePagination ? ((0, jsx_runtime_1.jsx)(FooterComponent, { sx: {
1563
1569
  ...(enableStickyHeaderOrFooter && {
1564
1570
  position: 'sticky',
1565
1571
  bottom: 0,
@@ -1,9 +1,14 @@
1
1
  import { TableFiltersForFetch } from '../types';
2
+ interface useDebouncedFetchReturn<T extends Record<string, any>> {
3
+ debouncedFetch: (filters: TableFiltersForFetch, debounceDelay?: number) => Promise<{
4
+ data: T[];
5
+ total: number;
6
+ }>;
7
+ isLoading: boolean;
8
+ }
2
9
  export declare function useDebouncedFetch<T extends Record<string, any>>(onFetchData: ((filters: TableFiltersForFetch) => Promise<{
3
10
  data: T[];
4
11
  total: number;
5
- }>) | undefined, delay?: number): {
6
- debouncedFetch: any;
7
- isLoading: any;
8
- };
12
+ }>) | undefined): useDebouncedFetchReturn<T>;
13
+ export {};
9
14
  //# sourceMappingURL=debounced-fetch.utils.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"debounced-fetch.utils.d.ts","sourceRoot":"","sources":["../../../src/lib/utils/debounced-fetch.utils.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,oBAAoB,EAAE,MAAM,UAAU,CAAC;AAGhD,wBAAgB,iBAAiB,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAC3D,WAAW,EAAE,CAAC,CAAC,OAAO,EAAE,oBAAoB,KAAK,OAAO,CAAC;IAAE,IAAI,EAAE,CAAC,EAAE,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC,GAAG,SAAS,EACnG,KAAK,SAAM;;;EA8Cd"}
1
+ {"version":3,"file":"debounced-fetch.utils.d.ts","sourceRoot":"","sources":["../../../src/lib/utils/debounced-fetch.utils.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,oBAAoB,EAAE,MAAM,UAAU,CAAC;AAI/C,UAAU,uBAAuB,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC;IAC5D,cAAc,EAAE,CAAC,OAAO,EAAE,oBAAoB,EAAE,aAAa,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC;QAAE,IAAI,EAAE,CAAC,EAAE,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACjH,SAAS,EAAE,OAAO,CAAC;CACtB;AAED,wBAAgB,iBAAiB,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAC3D,WAAW,EAAE,CAAC,CAAC,OAAO,EAAE,oBAAoB,KAAK,OAAO,CAAC;IAAE,IAAI,EAAE,CAAC,EAAE,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC,GAAG,SAAS,GACpG,uBAAuB,CAAC,CAAC,CAAC,CA6C5B"}
@@ -2,10 +2,11 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.useDebouncedFetch = useDebouncedFetch;
4
4
  const react_1 = require("react");
5
- function useDebouncedFetch(onFetchData, delay = 300) {
5
+ const DEFAULT_DEBOUNCE_DELAY = 300;
6
+ function useDebouncedFetch(onFetchData) {
6
7
  const [isLoading, setIsLoading] = (0, react_1.useState)(false);
7
8
  const debounceTimer = (0, react_1.useRef)(null);
8
- const debouncedFetch = (0, react_1.useCallback)(async (filters) => {
9
+ const debouncedFetch = (0, react_1.useCallback)(async (filters, debounceDelay = DEFAULT_DEBOUNCE_DELAY) => {
9
10
  if (!onFetchData)
10
11
  return null;
11
12
  // Create a unique key for the current fetch parameters
@@ -29,9 +30,9 @@ function useDebouncedFetch(onFetchData, delay = 300) {
29
30
  finally {
30
31
  setIsLoading(false);
31
32
  }
32
- }, delay);
33
+ }, debounceDelay);
33
34
  });
34
- }, [onFetchData, delay]);
35
+ }, [onFetchData]);
35
36
  // Cleanup timer on unmount
36
37
  (0, react_1.useEffect)(() => {
37
38
  // Fetch data when dependencies change
@@ -14,10 +14,10 @@ export declare function getPinnedColumnStyle(options: PinnedColumnStyleOptions):
14
14
  zIndex?: number;
15
15
  whiteSpace: "normal";
16
16
  wordBreak: "break-word";
17
- overflow: "visible";
17
+ overflow: "hidden";
18
18
  textOverflow?: undefined;
19
19
  boxSizing: string;
20
- maxWidth: string | number;
20
+ maxWidth: number;
21
21
  minWidth: number;
22
22
  width: string | number;
23
23
  } | {
@@ -28,10 +28,10 @@ export declare function getPinnedColumnStyle(options: PinnedColumnStyleOptions):
28
28
  zIndex?: number;
29
29
  whiteSpace: "normal";
30
30
  wordBreak: "break-word";
31
- overflow: "visible";
31
+ overflow: "hidden";
32
32
  textOverflow?: undefined;
33
33
  boxSizing: string;
34
- maxWidth: string | number;
34
+ maxWidth: number;
35
35
  minWidth: number;
36
36
  width: string | number;
37
37
  } | {
@@ -46,7 +46,7 @@ export declare function getPinnedColumnStyle(options: PinnedColumnStyleOptions):
46
46
  textOverflow: "ellipsis";
47
47
  wordBreak?: undefined;
48
48
  boxSizing: string;
49
- maxWidth: string | number;
49
+ maxWidth: number;
50
50
  minWidth: number;
51
51
  width: string | number;
52
52
  } | {
@@ -60,7 +60,7 @@ export declare function getPinnedColumnStyle(options: PinnedColumnStyleOptions):
60
60
  textOverflow: "ellipsis";
61
61
  wordBreak?: undefined;
62
62
  boxSizing: string;
63
- maxWidth: string | number;
63
+ maxWidth: number;
64
64
  minWidth: number;
65
65
  width: string | number;
66
66
  };
@@ -30,7 +30,7 @@ function getPinnedColumnStyle(options) {
30
30
  ? {
31
31
  whiteSpace: 'normal',
32
32
  wordBreak: 'break-word',
33
- overflow: 'visible',
33
+ overflow: 'hidden',
34
34
  }
35
35
  : {
36
36
  overflow: 'hidden',
@@ -41,7 +41,7 @@ function getPinnedColumnStyle(options) {
41
41
  // Width constraints - more strict for narrow columns
42
42
  width,
43
43
  ...(minWidth !== undefined && { minWidth }),
44
- ...(maxWidth !== undefined ? { maxWidth } : { maxWidth: width }),
44
+ ...(maxWidth !== undefined && { maxWidth }),
45
45
  boxSizing: 'border-box',
46
46
  ...textWrappingStyles,
47
47
  // Position handling
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@ackplus/react-tanstack-data-table",
3
3
  "type": "commonjs",
4
- "version": "1.1.6",
4
+ "version": "1.1.10",
5
5
  "description": "A powerful React data table component built with MUI and TanStack Table",
6
6
  "keywords": [
7
7
  "react",
@@ -20,7 +20,6 @@ export interface TableHeaderProps extends TableHeadProps {
20
20
  draggable?: boolean;
21
21
  enableColumnResizing?: boolean;
22
22
  enableStickyHeader?: boolean;
23
- fitToScreen?: boolean;
24
23
  onColumnReorder?: (draggedColumnId: string, targetColumnId: string) => void;
25
24
  // Enhanced customization props
26
25
  headerRowProps?: TableRowProps;
@@ -40,7 +39,6 @@ export function TableHeader<T>(props: TableHeaderProps): ReactElement {
40
39
  draggable = false,
41
40
  enableColumnResizing = false,
42
41
  enableStickyHeader = false,
43
- fitToScreen = true,
44
42
  onColumnReorder,
45
43
  headerRowProps,
46
44
  headerCellProps,
@@ -85,6 +83,8 @@ export function TableHeader<T>(props: TableHeaderProps): ReactElement {
85
83
  const alignment = getColumnAlignment(header.column.columnDef);
86
84
  const enableSorting = header.column.getCanSort();
87
85
  const wrapText = header.column.columnDef.wrapText ?? false;
86
+ const minSize = header.column.columnDef.minSize;
87
+ const maxSize = header.column.columnDef.maxSize;
88
88
  const canResize = enableColumnResizing && header.column.getCanResize();
89
89
 
90
90
  const mergedHeaderCellProps = mergeSlotProps(
@@ -92,7 +92,9 @@ export function TableHeader<T>(props: TableHeaderProps): ReactElement {
92
92
  align: alignment,
93
93
  sx: {
94
94
  ...getPinnedColumnStyle({
95
- width: fitToScreen ? 'auto' : header.getSize(),
95
+ width: header.getSize(),
96
+ minWidth: minSize !== undefined ? minSize : undefined,
97
+ maxWidth: maxSize !== undefined ? maxSize : undefined,
96
98
  isPinned,
97
99
  pinnedPosition,
98
100
  isLastLeftPinnedColumn: isPinned === 'left' && header.column.getIsLastColumn('left'),
@@ -158,7 +158,7 @@ export function DataTableRow<T>(props: DataTableRowProps<T>): ReactElement {
158
158
  align: alignment,
159
159
  sx: {
160
160
  ...getPinnedColumnStyle({
161
- width: cell.column.getSize() || 'auto',
161
+ width: cell.column.getSize(),
162
162
  minWidth: minSize !== undefined ? minSize : undefined,
163
163
  maxWidth: maxSize !== undefined ? maxSize : undefined,
164
164
  isPinned,
@@ -58,6 +58,8 @@ export function LoadingRows(props: LoadingRowsProps): ReactElement {
58
58
  const isPinned = column.getIsPinned();
59
59
  const pinnedPosition = isPinned ? column.getStart('left') : undefined;
60
60
  const pinnedRightPosition = isPinned === 'right' ? column.getAfter('right') : undefined;
61
+ const minSize = column.columnDef?.minSize;
62
+ const maxSize = column.columnDef?.maxSize;
61
63
 
62
64
  // Determine skeleton type based on column meta or content
63
65
  const columnMeta = column.columnDef?.meta;
@@ -70,7 +72,9 @@ export function LoadingRows(props: LoadingRowsProps): ReactElement {
70
72
  {
71
73
  sx: {
72
74
  ...getPinnedColumnStyle({
73
- width: column.getSize() || 'auto',
75
+ width: column.getSize(),
76
+ minWidth: minSize !== undefined ? minSize : undefined,
77
+ maxWidth: maxSize !== undefined ? maxSize : undefined,
74
78
  isPinned,
75
79
  pinnedPosition,
76
80
  pinnedRightPosition,
@@ -12,6 +12,7 @@ import {
12
12
  TableBody,
13
13
  Box,
14
14
  Paper,
15
+ useTheme,
15
16
  } from '@mui/material';
16
17
  import {
17
18
  getCoreRowModel,
@@ -154,7 +155,7 @@ export const DataTable = forwardRef<DataTableApi<any>, DataTableProps<any>>(func
154
155
  enableHover = true,
155
156
  enableStripes = false,
156
157
  tableProps = {},
157
- fitToScreen = false,
158
+ fitToScreen = true,
158
159
  tableSize: initialTableSize = 'medium',
159
160
 
160
161
  // Sticky header/footer props
@@ -194,6 +195,7 @@ export const DataTable = forwardRef<DataTableApi<any>, DataTableProps<any>>(func
194
195
  const isServerFiltering = filterMode === 'server' || isServerMode;
195
196
  const isServerSorting = sortingMode === 'server' || isServerMode;
196
197
 
198
+ const theme = useTheme();
197
199
  const logger = useMemo(() => createLogger('DataTable', logging), [logging]);
198
200
 
199
201
  useEffect(() => {
@@ -306,7 +308,7 @@ export const DataTable = forwardRef<DataTableApi<any>, DataTableProps<any>>(func
306
308
  // -------------------------------
307
309
  // Callback hooks (grouped together)
308
310
  // -------------------------------
309
- const fetchData = useCallback(async (overrides: Partial<TableState> = {}) => {
311
+ const fetchData = useCallback(async (overrides: Partial<TableState> = {}, options?: { delay?: number }) => {
310
312
  if (!onFetchData) {
311
313
  if (logger.isLevelEnabled('debug')) {
312
314
  logger.debug('onFetchData not provided, skipping fetch', { overrides, columnFilter, sorting, pagination });
@@ -327,7 +329,7 @@ export const DataTable = forwardRef<DataTableApi<any>, DataTableProps<any>>(func
327
329
  }
328
330
 
329
331
  try {
330
- const result = await debouncedFetch(filters);
332
+ const result = await debouncedFetch(filters, options === undefined ? 0 : options.delay || 300);
331
333
 
332
334
  if (logger.isLevelEnabled('info')) {
333
335
  logger.info('Fetch resolved', {
@@ -720,6 +722,7 @@ export const DataTable = forwardRef<DataTableApi<any>, DataTableProps<any>>(func
720
722
  // Column resizing
721
723
  enableColumnResizing: enableColumnResizing,
722
724
  columnResizeMode: columnResizeMode,
725
+ columnResizeDirection: theme.direction,
723
726
  // Column pinning
724
727
  enableColumnPinning: enableColumnPinning,
725
728
  // Expanding
@@ -736,20 +739,20 @@ export const DataTable = forwardRef<DataTableApi<any>, DataTableProps<any>>(func
736
739
  });
737
740
 
738
741
  // Compute width after table is created so column resizing is safe and reflects changes
739
- const tableWidth = useMemo(() => {
740
- if (fitToScreen) {
741
- return '100%';
742
- }
743
- if (enableColumnResizing) {
744
- return table.getCenterTotalSize();
745
- }
746
- return '100%';
747
- }, [fitToScreen, enableColumnResizing, table]);
748
-
749
- const tableStyle = useMemo(() => ({
742
+ const allLeafColumns = table.getAllLeafColumns();
743
+ const visibleLeafColumns = table.getVisibleLeafColumns();
744
+ const hasExplicitSizing = allLeafColumns.some((column) => {
745
+ const { size, minSize, maxSize } = column.columnDef;
746
+ return size !== undefined || minSize !== undefined || maxSize !== undefined;
747
+ });
748
+ const useFixedLayout = fitToScreen || enableColumnResizing || hasExplicitSizing;
749
+ const tableTotalSize = table.getTotalSize();
750
+ const tableWidth = fitToScreen ? '100%' : (useFixedLayout ? tableTotalSize : '100%');
751
+ const tableStyle = {
750
752
  width: tableWidth,
751
- minWidth: '100%',
752
- }), [tableWidth]);
753
+ minWidth: fitToScreen ? tableTotalSize : undefined,
754
+ tableLayout: useFixedLayout ? 'fixed' : 'auto',
755
+ };
753
756
 
754
757
 
755
758
  // -------------------------------
@@ -800,7 +803,7 @@ export const DataTable = forwardRef<DataTableApi<any>, DataTableProps<any>>(func
800
803
  if (logger.isLevelEnabled('info')) {
801
804
  logger.info('Initial data load triggered', { initialLoadData });
802
805
  }
803
- fetchData();
806
+ fetchData({});
804
807
  } else if (logger.isLevelEnabled('debug')) {
805
808
  logger.debug('Skipping initial data load', {
806
809
  initialLoadData,
@@ -1140,7 +1143,7 @@ export const DataTable = forwardRef<DataTableApi<any>, DataTableProps<any>>(func
1140
1143
  const allState = table.getState();
1141
1144
 
1142
1145
  onDataStateChange?.(allState);
1143
- onFetchData?.({});
1146
+ fetchData?.({});
1144
1147
  if (logger.isLevelEnabled('debug')) {
1145
1148
  logger.info('Reloading data', allState);
1146
1149
  }
@@ -1550,14 +1553,14 @@ export const DataTable = forwardRef<DataTableApi<any>, DataTableProps<any>>(func
1550
1553
  }
1551
1554
  },
1552
1555
  },
1553
- // eslint-disable-next-line react-hooks/exhaustive-deps
1556
+ // eslint-disable-next-line react-hooks/exhaustive-deps
1554
1557
  }), [
1555
1558
  table,
1556
1559
  enhancedColumns,
1557
1560
  handleColumnFilterStateChange,
1558
1561
  idKey,
1559
1562
  onDataStateChange,
1560
- onFetchData,
1563
+ fetchData,
1561
1564
  enableColumnPinning,
1562
1565
  enablePagination,
1563
1566
  // Export dependencies
@@ -1861,17 +1864,29 @@ export const DataTable = forwardRef<DataTableApi<any>, DataTableProps<any>>(func
1861
1864
  stickyHeader={enableStickyHeaderOrFooter}
1862
1865
  style={{
1863
1866
  ...tableStyle,
1864
- tableLayout: fitToScreen ? 'fixed' : 'auto',
1865
1867
  ...tableProps?.style,
1866
1868
  }}
1867
1869
  {...mergeSlotProps(tableProps || {}, tableComponentSlotProps)}
1868
1870
  >
1871
+ {useFixedLayout ? (
1872
+ <colgroup>
1873
+ {visibleLeafColumns.map((column) => (
1874
+ <col
1875
+ key={column.id}
1876
+ style={{
1877
+ width: column.getSize(),
1878
+ minWidth: column.columnDef.minSize,
1879
+ maxWidth: column.columnDef.maxSize,
1880
+ }}
1881
+ />
1882
+ ))}
1883
+ </colgroup>
1884
+ ) : null}
1869
1885
  {/* Table Headers */}
1870
1886
  <TableHeader
1871
1887
  draggable={enableColumnDragging}
1872
1888
  enableColumnResizing={enableColumnResizing}
1873
1889
  enableStickyHeader={enableStickyHeaderOrFooter}
1874
- fitToScreen={fitToScreen}
1875
1890
  onColumnReorder={handleColumnReorder}
1876
1891
  slots={slots}
1877
1892
  slotProps={slotProps}
@@ -1913,4 +1928,4 @@ export const DataTable = forwardRef<DataTableApi<any>, DataTableProps<any>>(func
1913
1928
  </RootComponent>
1914
1929
  </DataTableProvider>
1915
1930
  );
1916
- });
1931
+ });
@@ -2,15 +2,20 @@ import { useCallback, useEffect, useRef, useState } from 'react';
2
2
 
3
3
  import { TableFiltersForFetch } from '../types';
4
4
 
5
+ const DEFAULT_DEBOUNCE_DELAY = 300;
6
+
7
+ interface useDebouncedFetchReturn<T extends Record<string, any>> {
8
+ debouncedFetch: (filters: TableFiltersForFetch, debounceDelay?: number) => Promise<{ data: T[]; total: number }>;
9
+ isLoading: boolean;
10
+ }
5
11
 
6
12
  export function useDebouncedFetch<T extends Record<string, any>>(
7
- onFetchData: ((filters: TableFiltersForFetch) => Promise<{ data: T[]; total: number }>) | undefined,
8
- delay = 300,
9
- ) {
13
+ onFetchData: ((filters: TableFiltersForFetch) => Promise<{ data: T[]; total: number }>) | undefined
14
+ ): useDebouncedFetchReturn<T> {
10
15
  const [isLoading, setIsLoading] = useState(false);
11
16
  const debounceTimer = useRef<ReturnType<typeof setTimeout> | null>(null);
12
17
 
13
- const debouncedFetch = useCallback(async (filters: TableFiltersForFetch) => {
18
+ const debouncedFetch = useCallback(async (filters: TableFiltersForFetch, debounceDelay = DEFAULT_DEBOUNCE_DELAY) => {
14
19
  if (!onFetchData) return null;
15
20
 
16
21
  // Create a unique key for the current fetch parameters
@@ -33,9 +38,9 @@ export function useDebouncedFetch<T extends Record<string, any>>(
33
38
  } finally {
34
39
  setIsLoading(false);
35
40
  }
36
- }, delay);
41
+ }, debounceDelay);
37
42
  });
38
- }, [onFetchData, delay]);
43
+ }, [onFetchData]);
39
44
 
40
45
  // Cleanup timer on unmount
41
46
  useEffect(() => {
@@ -43,7 +43,7 @@ export function getPinnedColumnStyle(options: PinnedColumnStyleOptions) {
43
43
  ? {
44
44
  whiteSpace: 'normal' as const,
45
45
  wordBreak: 'break-word' as const,
46
- overflow: 'visible' as const,
46
+ overflow: 'hidden' as const,
47
47
  }
48
48
  : {
49
49
  overflow: 'hidden' as const,
@@ -55,7 +55,7 @@ export function getPinnedColumnStyle(options: PinnedColumnStyleOptions) {
55
55
  // Width constraints - more strict for narrow columns
56
56
  width,
57
57
  ...(minWidth !== undefined && { minWidth }),
58
- ...(maxWidth !== undefined ? { maxWidth } : { maxWidth: width }),
58
+ ...(maxWidth !== undefined && { maxWidth }),
59
59
  boxSizing: 'border-box',
60
60
  ...textWrappingStyles,
61
61
  // Position handling