@dreamtree-org/twreact-ui 1.0.76 → 1.0.77

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
@@ -276,26 +276,6 @@ const ChevronUp = createLucideIcon$1("ChevronUp", [
276
276
  */
277
277
 
278
278
 
279
- const ChevronsLeft = createLucideIcon$1("ChevronsLeft", [
280
- ["path", { d: "m11 17-5-5 5-5", key: "13zhaf" }],
281
- ["path", { d: "m18 17-5-5 5-5", key: "h8a8et" }]
282
- ]);
283
-
284
- /**
285
- * lucide-react v0.0.1 - ISC
286
- */
287
-
288
-
289
- const ChevronsRight = createLucideIcon$1("ChevronsRight", [
290
- ["path", { d: "m6 17 5-5-5-5", key: "xnjwq" }],
291
- ["path", { d: "m13 17 5-5-5-5", key: "17xmmf" }]
292
- ]);
293
-
294
- /**
295
- * lucide-react v0.0.1 - ISC
296
- */
297
-
298
-
299
279
  const EyeOff = createLucideIcon$1("EyeOff", [
300
280
  ["path", { d: "M9.88 9.88a3 3 0 1 0 4.24 4.24", key: "1jxqfv" }],
301
281
  [
@@ -3906,98 +3886,6 @@ var Select = /*#__PURE__*/React.forwardRef(function (_ref, forwardedRef) {
3906
3886
  var _excluded$k = ["data", "columns", "sortable", "filterable", "selectable", "pagination", "pageSize", "onSort", "onFilter", "onFetch", "onFilterChange", "onSelectionChange", "onRowClick", "hasDetails", "DetailsComponent", "className", "withAction", "onAction", "actions", "showSerial", "cellClass", "rowClass", "globalSearch", "limitOptions", "showLimitSelector", "onLimitChange", "showReloadButton", "renderReloadButton", "onReload", "stripedRows", "stripedColors", "responsiveBreakpoint", "serverSide", "totalRecords", "pageNumber", "onPageChange"];
3907
3887
  function ownKeys$9(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
3908
3888
  function _objectSpread$9(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys$9(Object(t), true).forEach(function (r) { _defineProperty$4(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys$9(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
3909
-
3910
- // Constants moved outside component
3911
- var DEFAULT_ACTIONS = [{
3912
- name: "edit",
3913
- label: "Edit",
3914
- onClick: function onClick() {
3915
- console.log("Edit action clicked");
3916
- },
3917
- icon: /*#__PURE__*/React.createElement(PenSquare, {
3918
- size: 16
3919
- })
3920
- }, {
3921
- name: "delete",
3922
- label: "Delete",
3923
- onClick: function onClick() {
3924
- console.log("Delete action clicked");
3925
- },
3926
- icon: /*#__PURE__*/React.createElement(Trash, {
3927
- size: 16
3928
- })
3929
- }, {
3930
- name: "view",
3931
- label: "View",
3932
- onClick: function onClick() {
3933
- console.log("View action clicked");
3934
- },
3935
- icon: /*#__PURE__*/React.createElement(Eye, {
3936
- size: 16
3937
- })
3938
- }];
3939
- var RESIZE_DEBOUNCE_MS = 150;
3940
- var MENU_PLACEMENT_THRESHOLD = 160;
3941
-
3942
- // Helper functions
3943
- var getRowKey = function getRowKey(row, globalIndex) {
3944
- if ((row === null || row === void 0 ? void 0 : row.id) != null) return String(row.id);
3945
- if ((row === null || row === void 0 ? void 0 : row._id) != null) return String(row._id);
3946
- return String(globalIndex);
3947
- };
3948
-
3949
- // Calculate pagination numbers
3950
- var getPaginationNumbers = function getPaginationNumbers(currentPage, totalPages) {
3951
- var maxVisible = 5;
3952
- if (totalPages <= maxVisible) {
3953
- return Array.from({
3954
- length: totalPages
3955
- }, function (_, i) {
3956
- return i + 1;
3957
- });
3958
- }
3959
- if (currentPage <= 3) {
3960
- return Array.from({
3961
- length: maxVisible
3962
- }, function (_, i) {
3963
- return i + 1;
3964
- });
3965
- }
3966
- if (currentPage >= totalPages - 2) {
3967
- return Array.from({
3968
- length: maxVisible
3969
- }, function (_, i) {
3970
- return totalPages - 4 + i;
3971
- });
3972
- }
3973
- return Array.from({
3974
- length: maxVisible
3975
- }, function (_, i) {
3976
- return currentPage - 2 + i;
3977
- });
3978
- };
3979
-
3980
- // Empty and Loading state components
3981
- var EmptyState = function EmptyState() {
3982
- return /*#__PURE__*/React.createElement("div", {
3983
- className: "flex flex-col items-center gap-2"
3984
- }, /*#__PURE__*/React.createElement("div", {
3985
- className: "text-gray-400"
3986
- }, /*#__PURE__*/React.createElement(List, {
3987
- className: "h-8 w-8"
3988
- })), /*#__PURE__*/React.createElement("span", {
3989
- className: "text-sm text-gray-500"
3990
- }, "No results found."));
3991
- };
3992
- var LoadingState = function LoadingState() {
3993
- return /*#__PURE__*/React.createElement("div", {
3994
- className: "flex flex-col items-center gap-2"
3995
- }, /*#__PURE__*/React.createElement("div", {
3996
- className: "h-6 w-6 animate-spin rounded-full border-2 border-primary-600 border-t-transparent"
3997
- }), /*#__PURE__*/React.createElement("span", {
3998
- className: "text-sm text-gray-500"
3999
- }, "Loading..."));
4000
- };
4001
3889
  var Table = function Table(_ref) {
4002
3890
  var _ref$data = _ref.data,
4003
3891
  data = _ref$data === void 0 ? [] : _ref$data,
@@ -4053,9 +3941,9 @@ var Table = function Table(_ref) {
4053
3941
  serverSide = _ref$serverSide === void 0 ? false : _ref$serverSide,
4054
3942
  _ref$totalRecords = _ref.totalRecords,
4055
3943
  totalRecords = _ref$totalRecords === void 0 ? 0 : _ref$totalRecords,
4056
- pageNumber = _ref.pageNumber,
4057
- onPageChange = _ref.onPageChange,
4058
- props = _objectWithoutProperties$1(_ref, _excluded$k);
3944
+ pageNumber = _ref.pageNumber;
3945
+ _ref.onPageChange;
3946
+ var props = _objectWithoutProperties$1(_ref, _excluded$k);
4059
3947
  // State for responsive view
4060
3948
  var _useState = React.useState(false),
4061
3949
  _useState2 = _slicedToArray(_useState, 2),
@@ -4063,16 +3951,14 @@ var Table = function Table(_ref) {
4063
3951
  setIsMobileView = _useState2[1];
4064
3952
 
4065
3953
  // Keep original table data / loading
4066
- var _useState3 = React.useState(function () {
4067
- return Array.isArray(data) ? data : [];
4068
- }),
3954
+ var _useState3 = React.useState(Array.isArray(data) ? data : []),
4069
3955
  _useState4 = _slicedToArray(_useState3, 2),
4070
3956
  tableData = _useState4[0],
4071
3957
  setTableData = _useState4[1];
4072
3958
  var _useState5 = React.useState(false),
4073
3959
  _useState6 = _slicedToArray(_useState5, 2),
4074
3960
  loading = _useState6[0],
4075
- _setLoading = _useState6[1];
3961
+ setLoading = _useState6[1];
4076
3962
 
4077
3963
  // Column visibility state
4078
3964
  var _useState7 = React.useState(function () {
@@ -4084,26 +3970,10 @@ var Table = function Table(_ref) {
4084
3970
  columnsState = _useState8[0],
4085
3971
  setColumnsState = _useState8[1];
4086
3972
  React.useEffect(function () {
4087
- // Sync when prop changes - only update if columns actually changed
4088
- if (Array.isArray(columns)) {
4089
- setColumnsState(function (prev) {
4090
- var prevKeys = new Set(prev.map(function (c) {
4091
- return c.key;
4092
- }));
4093
- var newKeys = new Set(columns.map(function (c) {
4094
- return c.key;
4095
- }));
4096
- var keysChanged = prevKeys.size !== newKeys.size || _toConsumableArray$1(prevKeys).some(function (k) {
4097
- return !newKeys.has(k);
4098
- });
4099
- if (keysChanged) {
4100
- return columns.map(function (c) {
4101
- return _objectSpread$9({}, c);
4102
- });
4103
- }
4104
- return prev;
4105
- });
4106
- }
3973
+ // Sync when prop changes
3974
+ setColumnsState(Array.isArray(columns) ? columns.map(function (c) {
3975
+ return _objectSpread$9({}, c);
3976
+ }) : []);
4107
3977
  }, [columns]);
4108
3978
 
4109
3979
  // Popover state for column toggler
@@ -4163,44 +4033,39 @@ var Table = function Table(_ref) {
4163
4033
  _useState28 = _slicedToArray(_useState27, 2),
4164
4034
  openActionKey = _useState28[0],
4165
4035
  setOpenActionKey = _useState28[1];
4036
+ var openRef = React.useRef(null);
4166
4037
  React.useEffect(function () {
4167
4038
  if (typeof pageNumber === "number" && pageNumber !== currentPage) {
4168
4039
  setCurrentPage(pageNumber);
4169
- // Note: onPageChange is intentionally not called here to avoid loops
4170
- // Parent should handle page changes via controlled component pattern
4171
4040
  }
4172
- }, [pageNumber, currentPage]);
4041
+ }, [pageNumber]);
4173
4042
  React.useEffect(function () {
4174
4043
  setLimit(pageSize);
4175
4044
  }, [pageSize]);
4176
4045
 
4177
- // Check if mobile view with debouncing
4046
+ // Check if mobile view
4178
4047
  React.useEffect(function () {
4179
- var timeoutId;
4180
4048
  var checkMobile = function checkMobile() {
4181
4049
  setIsMobileView(window.innerWidth < responsiveBreakpoint);
4182
4050
  };
4183
- var debouncedCheck = function debouncedCheck() {
4184
- clearTimeout(timeoutId);
4185
- timeoutId = setTimeout(checkMobile, RESIZE_DEBOUNCE_MS);
4186
- };
4187
4051
 
4188
4052
  // Initial check
4189
4053
  checkMobile();
4190
4054
 
4191
- // Add event listener with debouncing
4192
- window.addEventListener("resize", debouncedCheck);
4055
+ // Add event listener
4056
+ window.addEventListener("resize", checkMobile);
4193
4057
  return function () {
4194
- clearTimeout(timeoutId);
4195
- window.removeEventListener("resize", debouncedCheck);
4058
+ window.removeEventListener("resize", checkMobile);
4196
4059
  };
4197
4060
  }, [responsiveBreakpoint]);
4061
+ var isValidList = function isValidList(d) {
4062
+ return Array.isArray(d);
4063
+ };
4198
4064
 
4199
4065
  // Close column menu when clicking outside
4200
4066
  React.useEffect(function () {
4201
- if (!showColumnMenu) return;
4202
4067
  var onDocClick = function onDocClick(e) {
4203
- if (columnMenuRef.current && !columnMenuRef.current.contains(e.target) && columnToggleBtnRef.current && !columnToggleBtnRef.current.contains(e.target)) {
4068
+ if (showColumnMenu && columnMenuRef.current && !columnMenuRef.current.contains(e.target) && columnToggleBtnRef.current && !columnToggleBtnRef.current.contains(e.target)) {
4204
4069
  setShowColumnMenu(false);
4205
4070
  }
4206
4071
  };
@@ -4210,38 +4075,26 @@ var Table = function Table(_ref) {
4210
4075
  };
4211
4076
  }, [showColumnMenu]);
4212
4077
 
4078
+ // Close per-row actionmenu when clicking outside
4079
+ React.useEffect(function () {
4080
+ var handler = function handler(e) {
4081
+ if (openActionKey && openRef.current && !openRef.current.contains(e.target)) {
4082
+ setOpenActionKey(null);
4083
+ }
4084
+ };
4085
+ document.addEventListener("click", handler);
4086
+ return function () {
4087
+ return document.removeEventListener("click", handler);
4088
+ };
4089
+ }, [openActionKey]);
4090
+
4213
4091
  // Visible columns derived from columnsState
4214
4092
  var visibleColumns = React.useMemo(function () {
4215
4093
  return columnsState.filter(function (col) {
4216
4094
  return col.isVisible !== false;
4217
4095
  });
4218
4096
  }, [columnsState]);
4219
-
4220
- // Memoize actions
4221
- var actionsToUse = React.useMemo(function () {
4222
- return actions !== null && actions !== void 0 ? actions : DEFAULT_ACTIONS;
4223
- }, [actions]);
4224
-
4225
- // Memoize visible count
4226
- var visibleCount = React.useMemo(function () {
4227
- return (showSerial ? 1 : 0) + visibleColumns.length + (selectable ? 1 : 0) + (hasDetails ? 1 : 0) + (withAction ? 1 : 0);
4228
- }, [showSerial, visibleColumns.length, selectable, hasDetails, withAction]);
4229
-
4230
- // Memoize key-to-row mapping for selection
4231
- var keyToRowMap = React.useMemo(function () {
4232
- var map = new Map();
4233
- filteredData.forEach(function (row, i) {
4234
- map.set(getRowKey(row, i), row);
4235
- });
4236
- return map;
4237
- }, [filteredData]);
4238
-
4239
- // Wrapper for setCurrentPage that also calls onPageChange
4240
- var handlePageChange = React.useCallback(function (newPage) {
4241
- setCurrentPage(newPage);
4242
- onPageChange === null || onPageChange === void 0 || onPageChange(newPage);
4243
- }, [onPageChange]);
4244
- var toggleColumnVisibility = React.useCallback(function (key) {
4097
+ var toggleColumnVisibility = function toggleColumnVisibility(key) {
4245
4098
  setColumnsState(function (prev) {
4246
4099
  return prev.map(function (c) {
4247
4100
  return c.key === key ? _objectSpread$9(_objectSpread$9({}, c), {}, {
@@ -4249,23 +4102,58 @@ var Table = function Table(_ref) {
4249
4102
  }) : c;
4250
4103
  });
4251
4104
  });
4252
- handlePageChange(1);
4253
- }, [handlePageChange]);
4105
+ setCurrentPage(1);
4106
+ };
4254
4107
 
4255
4108
  // Handle actions
4256
- var handleOnAction = React.useCallback(function (action, row) {
4109
+ var handleOnAction = function handleOnAction(action, row) {
4257
4110
  var _action$onClick;
4258
4111
  (_action$onClick = action.onClick) === null || _action$onClick === void 0 || _action$onClick.call(action, {
4259
4112
  action: action,
4260
4113
  row: row
4261
4114
  });
4262
- onAction === null || onAction === void 0 || onAction({
4115
+ onAction && onAction({
4263
4116
  action: action,
4264
4117
  row: row
4265
4118
  });
4266
4119
  setOpenActionKey(null);
4267
4120
  setActionAnchor(null);
4268
- }, [onAction]);
4121
+ };
4122
+ var defaultActions = [{
4123
+ name: "edit",
4124
+ label: "Edit",
4125
+ onClick: function onClick() {
4126
+ console.log("Edit action clicked");
4127
+ },
4128
+ icon: /*#__PURE__*/React.createElement(PenSquare, {
4129
+ size: 16
4130
+ })
4131
+ }, {
4132
+ name: "delete",
4133
+ label: "Delete",
4134
+ onClick: function onClick() {
4135
+ console.log("Delete action clicked");
4136
+ },
4137
+ icon: /*#__PURE__*/React.createElement(Trash, {
4138
+ size: 16
4139
+ })
4140
+ }, {
4141
+ name: "view",
4142
+ label: "View",
4143
+ onClick: function onClick() {
4144
+ console.log("View action clicked");
4145
+ },
4146
+ icon: /*#__PURE__*/React.createElement(Eye, {
4147
+ size: 16
4148
+ })
4149
+ }];
4150
+ var actionsToUse = actions !== undefined ? actions : defaultActions;
4151
+ var getRowKey = function getRowKey(row, globalIndex) {
4152
+ if (row == null) return String(globalIndex);
4153
+ if (row.id !== undefined && row.id !== null) return String(row.id);
4154
+ if (row._id !== undefined && row._id !== null) return String(row._id);
4155
+ return String(globalIndex);
4156
+ };
4269
4157
 
4270
4158
  // Sorting
4271
4159
  var sortedData = React.useMemo(function () {
@@ -4284,38 +4172,16 @@ var Table = function Table(_ref) {
4284
4172
  // Filtering
4285
4173
  var filteredData = React.useMemo(function () {
4286
4174
  if (serverSide || !filterable || !Object.keys(filters).length) return sortedData;
4175
+ var q = (filters.global || "").toLowerCase();
4287
4176
  return sortedData.filter(function (row) {
4288
- // Apply global search filter if present
4289
- if (filters.global) {
4290
- var q = filters.global.toLowerCase();
4291
- var matchesGlobal = Object.values(row || {}).some(function (v) {
4292
- return String(v).toLowerCase().includes(q);
4293
- });
4294
- if (!matchesGlobal) return false;
4295
- }
4296
-
4297
- // Apply column-specific filters
4298
- return visibleColumns.every(function (column) {
4299
- var columnFilter = filters[column.key];
4300
- if (!columnFilter) return true; // No filter for this column
4301
-
4302
- var cellValue = row === null || row === void 0 ? void 0 : row[column.key];
4303
- return String(cellValue || "").toLowerCase().includes(columnFilter.toLowerCase());
4177
+ return Object.values(row || {}).some(function (v) {
4178
+ return String(v).toLowerCase().includes(q);
4304
4179
  });
4305
4180
  });
4306
- }, [sortedData, filters, filterable, serverSide, visibleColumns]);
4307
-
4308
- // Pagination indices - memoized
4309
- var _useMemo = React.useMemo(function () {
4310
- var start = pagination ? (currentPage - 1) * limit : 0;
4311
- var end = pagination ? start + limit : filteredData.length;
4312
- return {
4313
- startIndex: start,
4314
- endIndex: end
4315
- };
4316
- }, [pagination, currentPage, limit, filteredData.length]),
4317
- startIndex = _useMemo.startIndex,
4318
- endIndex = _useMemo.endIndex;
4181
+ }, [sortedData, filters, filterable, serverSide]);
4182
+ // Pagination indices
4183
+ var startIndex = pagination ? (currentPage - 1) * limit : 0;
4184
+ var endIndex = pagination ? startIndex + limit : filteredData.length;
4319
4185
 
4320
4186
  // Paginated view
4321
4187
  var paginatedData = React.useMemo(function () {
@@ -4329,7 +4195,7 @@ var Table = function Table(_ref) {
4329
4195
  }, [pagination, serverSide, totalRecords, filteredData.length, limit]);
4330
4196
 
4331
4197
  // Sorting handler
4332
- var handleSort = React.useCallback(function (key) {
4198
+ var handleSort = function handleSort(key) {
4333
4199
  if (!sortable) return;
4334
4200
  var direction = sortConfig.key === key && sortConfig.direction === "asc" ? "desc" : "asc";
4335
4201
  setSortConfig({
@@ -4337,10 +4203,10 @@ var Table = function Table(_ref) {
4337
4203
  direction: direction
4338
4204
  });
4339
4205
  onSort === null || onSort === void 0 || onSort(key, direction);
4340
- }, [sortable, sortConfig, onSort]);
4206
+ };
4341
4207
 
4342
- // Selection handlers - optimized with memoized keyToRowMap
4343
- var handleSelectAll = React.useCallback(function () {
4208
+ // Selection handlers
4209
+ var handleSelectAll = function handleSelectAll() {
4344
4210
  var newSelection = new Set(selectedRows);
4345
4211
  var pageRowKeys = paginatedData.map(function (r, i) {
4346
4212
  return getRowKey(r, startIndex + i);
@@ -4358,45 +4224,50 @@ var Table = function Table(_ref) {
4358
4224
  });
4359
4225
  }
4360
4226
  setSelectedRows(newSelection);
4227
+ var keyToRow = new Map(filteredData.map(function (r, i) {
4228
+ return [getRowKey(r, i), r];
4229
+ }));
4361
4230
  var selectedData = Array.from(newSelection).map(function (k) {
4362
- return keyToRowMap.get(k);
4231
+ return keyToRow.get(k);
4363
4232
  }).filter(Boolean);
4364
4233
  onSelectionChange === null || onSelectionChange === void 0 || onSelectionChange(selectedData);
4365
- }, [selectedRows, paginatedData, startIndex, keyToRowMap, onSelectionChange]);
4366
- var handleSelectRow = React.useCallback(function (row, rowIndexInPage) {
4234
+ };
4235
+ var handleSelectRow = function handleSelectRow(row, rowIndexInPage) {
4367
4236
  var globalIndex = startIndex + rowIndexInPage;
4368
4237
  var key = getRowKey(row, globalIndex);
4369
4238
  var newSelection = new Set(selectedRows);
4370
4239
  if (newSelection.has(key)) newSelection["delete"](key);else newSelection.add(key);
4371
4240
  setSelectedRows(newSelection);
4241
+ var keyToRow = new Map(filteredData.map(function (r, i) {
4242
+ return [getRowKey(r, i), r];
4243
+ }));
4372
4244
  var selectedData = Array.from(newSelection).map(function (k) {
4373
- return keyToRowMap.get(k);
4245
+ return keyToRow.get(k);
4374
4246
  }).filter(Boolean);
4375
4247
  onSelectionChange === null || onSelectionChange === void 0 || onSelectionChange(selectedData);
4376
- }, [startIndex, selectedRows, keyToRowMap, onSelectionChange]);
4377
- var toggleExpandRow = React.useCallback(function (row, rowIndexInPage) {
4248
+ };
4249
+ var toggleExpandRow = function toggleExpandRow(row, rowIndexInPage) {
4378
4250
  var globalIndex = startIndex + rowIndexInPage;
4379
4251
  var key = getRowKey(row, globalIndex);
4380
- setExpandedRows(function (prev) {
4381
- var newExpanded = new Set(prev);
4382
- if (newExpanded.has(key)) newExpanded["delete"](key);else newExpanded.add(key);
4383
- return newExpanded;
4384
- });
4385
- }, [startIndex]);
4386
- var handleFilter = React.useCallback(function (key, value) {
4387
- setFilters(function (prev) {
4388
- var newFilters = _objectSpread$9(_objectSpread$9({}, prev), {}, _defineProperty$4({}, key, value));
4389
- onFilter === null || onFilter === void 0 || onFilter(newFilters);
4390
- onFilterChange === null || onFilterChange === void 0 || onFilterChange(newFilters);
4391
- return newFilters;
4392
- });
4393
- handlePageChange(1);
4394
- }, [onFilter, onFilterChange, handlePageChange]);
4395
- var renderCell = React.useCallback(function (column, row, globalIndex) {
4252
+ var newExpanded = new Set(expandedRows);
4253
+ if (newExpanded.has(key)) newExpanded["delete"](key);else newExpanded.add(key);
4254
+ setExpandedRows(newExpanded);
4255
+ };
4256
+ var handleFilter = function handleFilter(key, value) {
4257
+ var newFilters = _objectSpread$9(_objectSpread$9({}, filters), {}, _defineProperty$4({}, key, value));
4258
+ setFilters(newFilters);
4259
+ onFilter === null || onFilter === void 0 || onFilter(newFilters);
4260
+ onFilterChange === null || onFilterChange === void 0 || onFilterChange(newFilters);
4261
+ setCurrentPage(1);
4262
+ };
4263
+ var renderCell = function renderCell(column, row, globalIndex) {
4396
4264
  if (column.render) return column.render(row, globalIndex);
4397
4265
  return row === null || row === void 0 ? void 0 : row[column.key];
4398
- }, []);
4399
- var toggleActions = React.useCallback(function (e, actionCellKey, row) {
4266
+ };
4267
+
4268
+ // UI counts
4269
+ var visibleCount = (showSerial ? 1 : 0) + visibleColumns.length + (selectable ? 1 : 0) + (hasDetails ? 1 : 0) + (withAction ? 1 : 0);
4270
+ var toggleActions = function toggleActions(e, actionCellKey, row) {
4400
4271
  e.stopPropagation();
4401
4272
  if (actionAnchor && actionAnchor.key === actionCellKey) {
4402
4273
  setOpenActionKey(null);
@@ -4409,7 +4280,7 @@ var Table = function Table(_ref) {
4409
4280
  row: row
4410
4281
  });
4411
4282
  }
4412
- }, [actionAnchor]);
4283
+ };
4413
4284
  React.useEffect(function () {
4414
4285
  if (!actionAnchor) return;
4415
4286
  var onDocClick = function onDocClick(ev) {
@@ -4420,9 +4291,9 @@ var Table = function Table(_ref) {
4420
4291
  setActionAnchor(null);
4421
4292
  };
4422
4293
  var onScrollResize = function onScrollResize() {
4423
- // Close menu on scroll/resize to prevent positioning issues
4424
- setOpenActionKey(null);
4425
- setActionAnchor(null);
4294
+ setOpenActionKey(function (k) {
4295
+ return k ? k : null;
4296
+ });
4426
4297
  };
4427
4298
  window.addEventListener("click", onDocClick);
4428
4299
  window.addEventListener("scroll", onScrollResize, true);
@@ -4433,163 +4304,58 @@ var Table = function Table(_ref) {
4433
4304
  window.removeEventListener("resize", onScrollResize);
4434
4305
  };
4435
4306
  }, [actionAnchor]);
4436
-
4437
- // Track previous fetch params to prevent unnecessary calls
4438
- var prevFetchParamsRef = React.useRef(null);
4439
- var isFetchingRef = React.useRef(false);
4440
- var isMountedRef = React.useRef(true);
4441
- var onFetchRef = React.useRef(onFetch);
4442
- var activeFetchIdRef = React.useRef(0);
4443
-
4444
- // Keep ref in sync with onFetch
4445
4307
  React.useEffect(function () {
4446
- onFetchRef.current = onFetch;
4447
- }, [onFetch]);
4448
-
4449
- // Track mount status
4450
- React.useEffect(function () {
4451
- isMountedRef.current = true;
4452
- return function () {
4453
- isMountedRef.current = false;
4454
- isFetchingRef.current = false;
4455
- };
4456
- }, []);
4457
-
4458
- // Serialize fetch params for comparison - serialize filters to avoid object reference issues
4459
- var fetchParams = React.useMemo(function () {
4460
- return {
4308
+ if (!onFetch) return;
4309
+ onFetch({
4310
+ setData: function setData(rows) {
4311
+ return setTableData(Array.isArray(rows) ? rows : []);
4312
+ },
4313
+ setLoading: setLoading,
4461
4314
  filters: filters,
4462
4315
  page: currentPage,
4463
4316
  limit: limit,
4464
- sortKey: sortConfig.key,
4465
- sortDirection: sortConfig.direction
4466
- };
4467
- }, [filters, currentPage, limit, sortConfig.key, sortConfig.direction]);
4468
- var fetchParamsString = React.useMemo(function () {
4469
- return JSON.stringify(fetchParams);
4470
- }, [fetchParams]);
4471
-
4472
- // Consolidated data sync effect
4317
+ sort: sortConfig
4318
+ });
4319
+ }, [onFetch, filters, currentPage, limit, sortConfig]);
4473
4320
  React.useEffect(function () {
4474
- var currentOnFetch = onFetchRef.current;
4475
- if (currentOnFetch) {
4476
- // Only fetch if params actually changed and not already fetching
4477
- if (!isFetchingRef.current && prevFetchParamsRef.current !== fetchParamsString) {
4478
- prevFetchParamsRef.current = fetchParamsString;
4479
- isFetchingRef.current = true;
4480
-
4481
- // Track fetch ID to prevent race conditions
4482
- var fetchId = Date.now();
4483
- activeFetchIdRef.current = fetchId;
4484
- try {
4485
- var result = currentOnFetch({
4486
- setData: function setData(rows) {
4487
- // Only update if component is still mounted and this is the active fetch
4488
- if (isMountedRef.current && activeFetchIdRef.current === fetchId) {
4489
- setTableData(Array.isArray(rows) ? rows : []);
4490
- // Don't set isFetchingRef to false here - let setLoading handle it
4491
- }
4492
- },
4493
- setLoading: function setLoading(loading) {
4494
- // Only update if component is still mounted and this is the active fetch
4495
- if (isMountedRef.current && activeFetchIdRef.current === fetchId) {
4496
- _setLoading(loading);
4497
- if (!loading) {
4498
- isFetchingRef.current = false;
4499
- }
4500
- }
4501
- },
4502
- filters: fetchParams.filters,
4503
- page: fetchParams.page,
4504
- limit: fetchParams.limit,
4505
- sort: {
4506
- key: fetchParams.sortKey,
4507
- direction: fetchParams.sortDirection
4508
- }
4509
- });
4510
-
4511
- // Handle promise if onFetch returns one
4512
- if (result && typeof result.then === "function") {
4513
- result["catch"](function (error) {
4514
- console.error("Table onFetch error:", error);
4515
- if (isMountedRef.current && activeFetchIdRef.current === fetchId) {
4516
- _setLoading(false);
4517
- isFetchingRef.current = false;
4518
- }
4519
- });
4520
- }
4521
- } catch (error) {
4522
- console.error("Table onFetch error:", error);
4523
- if (isMountedRef.current && activeFetchIdRef.current === fetchId) {
4524
- _setLoading(false);
4525
- isFetchingRef.current = false;
4526
- }
4527
- }
4528
- }
4529
- } else if (!serverSide && Array.isArray(data)) {
4530
- setTableData(data);
4531
- }
4532
- }, [serverSide, data, fetchParamsString]);
4321
+ if (!serverSide) setTableData(data);
4322
+ }, [data, serverSide]);
4323
+ React.useEffect(function () {
4324
+ if (!onFetch && isValidList(data)) setTableData(data);
4325
+ }, [data, onFetch]);
4533
4326
 
4534
4327
  // Global search
4535
4328
  React.useEffect(function () {
4536
4329
  setSearchInput(filters.global || "");
4537
4330
  }, [filters.global]);
4538
- var applyGlobalSearch = React.useCallback(function () {
4331
+ var applyGlobalSearch = function applyGlobalSearch() {
4539
4332
  handleFilter("global", searchInput);
4540
- }, [handleFilter, searchInput]);
4541
- var onGlobalKeyDown = React.useCallback(function (e) {
4333
+ };
4334
+ var onGlobalKeyDown = function onGlobalKeyDown(e) {
4542
4335
  if (e.key === "Enter") {
4543
4336
  e.preventDefault();
4544
4337
  applyGlobalSearch();
4545
4338
  }
4546
- }, [applyGlobalSearch]);
4547
- var handleLimitChange = React.useCallback(function (nextLimit) {
4339
+ };
4340
+ var handleLimitChange = function handleLimitChange(nextLimit) {
4548
4341
  var parsed = Number(nextLimit);
4549
4342
  if (!Number.isFinite(parsed) || parsed <= 0) return;
4550
4343
  setLimit(parsed);
4551
- handlePageChange(1);
4344
+ setCurrentPage(1);
4552
4345
  onLimitChange === null || onLimitChange === void 0 || onLimitChange(parsed);
4553
- }, [onLimitChange, handlePageChange]);
4554
-
4555
- // Memoize limit options
4556
- var limitOptionsMemo = React.useMemo(function () {
4557
- var opts = Array.isArray(limitOptions) && limitOptions.length > 0 ? limitOptions : [25, 50, 100];
4558
- return opts.map(function (opt) {
4559
- return {
4560
- label: String(opt),
4561
- value: opt
4562
- };
4563
- });
4564
- }, [limitOptions]);
4346
+ };
4565
4347
 
4566
- // Extract row metadata computation
4567
- var getRowMetadata = React.useCallback(function (row, rowIndexInPage) {
4348
+ // Render mobile card
4349
+ var renderMobileCard = function renderMobileCard(row, rowIndexInPage) {
4568
4350
  var globalIndex = startIndex + rowIndexInPage;
4569
4351
  var key = getRowKey(row, globalIndex);
4570
4352
  var actionCellKey = "actions-".concat(key);
4571
- var extraRowClass = typeof rowClass === "function" ? (rowClass({
4353
+ var extraRowClass = typeof rowClass === "function" ? rowClass({
4572
4354
  row: row,
4573
4355
  rowIndex: globalIndex
4574
- }) || "").trim() : "";
4356
+ }) : "";
4357
+ var safeExtraRowClass = typeof extraRowClass === "string" ? extraRowClass.trim() : "";
4575
4358
  var stripeBg = stripedRows && !selectedRows.has(key) ? stripedColors[globalIndex % stripedColors.length] : undefined;
4576
- return {
4577
- globalIndex: globalIndex,
4578
- key: key,
4579
- actionCellKey: actionCellKey,
4580
- extraRowClass: extraRowClass,
4581
- stripeBg: stripeBg
4582
- };
4583
- }, [startIndex, rowClass, stripedRows, selectedRows, stripedColors]);
4584
-
4585
- // Render mobile card
4586
- var renderMobileCard = React.useCallback(function (row, rowIndexInPage) {
4587
- var _getRowMetadata = getRowMetadata(row, rowIndexInPage),
4588
- globalIndex = _getRowMetadata.globalIndex,
4589
- key = _getRowMetadata.key,
4590
- actionCellKey = _getRowMetadata.actionCellKey,
4591
- extraRowClass = _getRowMetadata.extraRowClass,
4592
- stripeBg = _getRowMetadata.stripeBg;
4593
4359
  return /*#__PURE__*/React.createElement("div", {
4594
4360
  key: key,
4595
4361
  style: stripeBg ? {
@@ -4599,7 +4365,7 @@ var Table = function Table(_ref) {
4599
4365
  "cursor-pointer": !!onRowClick,
4600
4366
  "bg-primary-50 border-primary-200": selectedRows.has(key),
4601
4367
  "hover:shadow-md": !selectedRows.has(key)
4602
- }, extraRowClass),
4368
+ }, safeExtraRowClass),
4603
4369
  onClick: function onClick() {
4604
4370
  return onRowClick === null || onRowClick === void 0 ? void 0 : onRowClick(row, globalIndex);
4605
4371
  }
@@ -4656,15 +4422,16 @@ var Table = function Table(_ref) {
4656
4422
  }), document.body))), /*#__PURE__*/React.createElement("div", {
4657
4423
  className: "p-4"
4658
4424
  }, visibleColumns.map(function (column, colIndex) {
4659
- var extraCellClass = typeof cellClass === "function" ? (cellClass({
4425
+ var extraCellClass = typeof cellClass === "function" ? cellClass({
4660
4426
  row: row,
4661
4427
  rowIndex: globalIndex,
4662
4428
  column: column,
4663
4429
  columnIndex: colIndex
4664
- }) || "").trim() : "";
4430
+ }) : "";
4431
+ var safeExtraCellClass = typeof extraCellClass === "string" ? extraCellClass.trim() : "";
4665
4432
  return /*#__PURE__*/React.createElement("div", {
4666
4433
  key: column.key,
4667
- className: cn$1("flex justify-between items-center flex-row py-2 border-b last:border-b-0", extraCellClass)
4434
+ className: cn$1("flex justify-between items-center flex-row py-2 border-b last:border-b-0", safeExtraCellClass)
4668
4435
  }, /*#__PURE__*/React.createElement("div", {
4669
4436
  className: "text-xs font-medium text-gray-500 uppercase tracking-wide mb-1 sm:mb-0 sm:w-1/3 sm:pr-2"
4670
4437
  }, column.label), /*#__PURE__*/React.createElement("div", {
@@ -4676,10 +4443,10 @@ var Table = function Table(_ref) {
4676
4443
  row: row,
4677
4444
  index: globalIndex
4678
4445
  })));
4679
- }, [getRowMetadata, hasDetails, selectable, showSerial, withAction, expandedRows, selectedRows, onRowClick, visibleColumns, renderCell, cellClass, DetailsComponent, actionsToUse, actionAnchor, openActionKey, handleOnAction, actionMenuRef, toggleActions, toggleExpandRow, handleSelectRow]);
4446
+ };
4680
4447
 
4681
4448
  // Render mobile filters
4682
- var renderMobileFilters = React.useCallback(function () {
4449
+ var renderMobileFilters = function renderMobileFilters() {
4683
4450
  return /*#__PURE__*/React.createElement("div", {
4684
4451
  className: "mb-4 p-3 bg-gray-50 rounded-lg"
4685
4452
  }, /*#__PURE__*/React.createElement("div", {
@@ -4721,7 +4488,7 @@ var Table = function Table(_ref) {
4721
4488
  }
4722
4489
  }));
4723
4490
  })));
4724
- }, [showMobileFilters, globalSearch, searchInput, onGlobalKeyDown, filterable, visibleColumns, filters, handleFilter, setShowMobileFilters, setSearchInput]);
4491
+ };
4725
4492
 
4726
4493
  // Render
4727
4494
  return /*#__PURE__*/React.createElement("div", {
@@ -4744,11 +4511,23 @@ var Table = function Table(_ref) {
4744
4511
  htmlFor: "pagination-limit",
4745
4512
  className: "text-sm text-gray-600 whitespace-nowrap"
4746
4513
  }, "Show"), /*#__PURE__*/React.createElement(Select, {
4747
- options: limitOptionsMemo,
4514
+ options: Array.isArray(limitOptions) && limitOptions.length > 0 ? limitOptions.map(function (opt) {
4515
+ return {
4516
+ label: String(opt),
4517
+ value: opt
4518
+ };
4519
+ }) : [25, 50, 100].map(function (opt) {
4520
+ return {
4521
+ label: String(opt),
4522
+ value: opt
4523
+ };
4524
+ }),
4748
4525
  value: limit,
4749
4526
  allowClear: false,
4750
4527
  placeholder: "",
4751
- onChange: handleLimitChange,
4528
+ onChange: function onChange(e) {
4529
+ return handleLimitChange(e);
4530
+ },
4752
4531
  className: "w-20 md:w-30"
4753
4532
  }), /*#__PURE__*/React.createElement("p", {
4754
4533
  className: "text-sm text-gray-600 whitespace-nowrap"
@@ -4764,42 +4543,24 @@ var Table = function Table(_ref) {
4764
4543
  className: "rounded-lg md:rounded-md border border-gray-300 p-2 disabled:opacity-50 hover:bg-gray-50",
4765
4544
  disabled: currentPage === 1,
4766
4545
  onClick: function onClick() {
4767
- return handlePageChange(1);
4768
- },
4769
- "aria-label": "First page",
4770
- title: "First page"
4771
- }, /*#__PURE__*/React.createElement(ChevronsLeft, {
4772
- className: "size-4 md:size-5 text-gray-800"
4773
- })), /*#__PURE__*/React.createElement("button", {
4774
- className: "rounded-lg md:rounded-md border border-gray-300 p-2 disabled:opacity-50 hover:bg-gray-50",
4775
- disabled: currentPage === 1,
4776
- onClick: function onClick() {
4777
- return handlePageChange(Math.max(1, currentPage - 1));
4546
+ return setCurrentPage(function (p) {
4547
+ return Math.max(1, p - 1);
4548
+ });
4778
4549
  },
4779
- "aria-label": "Previous page",
4780
- title: "Previous page"
4550
+ "aria-label": "Previous page"
4781
4551
  }, /*#__PURE__*/React.createElement(ChevronLeft, {
4782
4552
  className: "size-4 md:size-5 text-gray-800"
4783
4553
  })), /*#__PURE__*/React.createElement("button", {
4784
4554
  className: "rounded-lg md:rounded-md border border-gray-300 p-2 disabled:opacity-50 hover:bg-gray-50",
4785
4555
  disabled: currentPage === totalPages,
4786
4556
  onClick: function onClick() {
4787
- return handlePageChange(Math.min(totalPages, currentPage + 1));
4557
+ return setCurrentPage(function (p) {
4558
+ return Math.min(totalPages, p + 1);
4559
+ });
4788
4560
  },
4789
- "aria-label": "Next page",
4790
- title: "Next page"
4561
+ "aria-label": "Next page"
4791
4562
  }, /*#__PURE__*/React.createElement(ChevronRight, {
4792
4563
  className: "size-4 md:size-5 text-gray-800"
4793
- })), /*#__PURE__*/React.createElement("button", {
4794
- className: "rounded-lg md:rounded-md border border-gray-300 p-2 disabled:opacity-50 hover:bg-gray-50",
4795
- disabled: currentPage === totalPages,
4796
- onClick: function onClick() {
4797
- return handlePageChange(totalPages);
4798
- },
4799
- "aria-label": "Last page",
4800
- title: "Last page"
4801
- }, /*#__PURE__*/React.createElement(ChevronsRight, {
4802
- className: "size-4 md:size-5 text-gray-800"
4803
4564
  })))))), globalSearch && /*#__PURE__*/React.createElement("div", {
4804
4565
  className: "p-4 border-b"
4805
4566
  }, /*#__PURE__*/React.createElement("div", {
@@ -4938,16 +4699,33 @@ var Table = function Table(_ref) {
4938
4699
  }, loading ? /*#__PURE__*/React.createElement("tr", null, /*#__PURE__*/React.createElement("td", {
4939
4700
  colSpan: visibleCount,
4940
4701
  className: "px-6 py-8 text-center"
4941
- }, /*#__PURE__*/React.createElement(LoadingState, null))) : paginatedData.length === 0 ? /*#__PURE__*/React.createElement("tr", null, /*#__PURE__*/React.createElement("td", {
4702
+ }, /*#__PURE__*/React.createElement("div", {
4703
+ className: "flex flex-col items-center gap-2"
4704
+ }, /*#__PURE__*/React.createElement("div", {
4705
+ className: "h-6 w-6 animate-spin rounded-full border-2 border-primary-600 border-t-transparent"
4706
+ }), /*#__PURE__*/React.createElement("span", {
4707
+ className: "text-sm text-gray-500"
4708
+ }, "Loading...")))) : paginatedData.length === 0 ? /*#__PURE__*/React.createElement("tr", null, /*#__PURE__*/React.createElement("td", {
4942
4709
  colSpan: visibleCount,
4943
4710
  className: "px-6 py-8 text-center"
4944
- }, /*#__PURE__*/React.createElement(EmptyState, null))) : paginatedData.map(function (row, rowIndexInPage) {
4945
- var _getRowMetadata2 = getRowMetadata(row, rowIndexInPage),
4946
- globalIndex = _getRowMetadata2.globalIndex,
4947
- key = _getRowMetadata2.key,
4948
- actionCellKey = _getRowMetadata2.actionCellKey,
4949
- extraRowClass = _getRowMetadata2.extraRowClass,
4950
- stripeBg = _getRowMetadata2.stripeBg;
4711
+ }, /*#__PURE__*/React.createElement("div", {
4712
+ className: "flex flex-col items-center gap-2"
4713
+ }, /*#__PURE__*/React.createElement("div", {
4714
+ className: "text-gray-400"
4715
+ }, /*#__PURE__*/React.createElement(List, {
4716
+ className: "h-8 w-8"
4717
+ })), /*#__PURE__*/React.createElement("span", {
4718
+ className: "text-sm text-gray-500"
4719
+ }, "No results found.")))) : paginatedData.map(function (row, rowIndexInPage) {
4720
+ var globalIndex = startIndex + rowIndexInPage;
4721
+ var key = getRowKey(row, globalIndex);
4722
+ var actionCellKey = "actions-".concat(key);
4723
+ var extraRowClass = typeof rowClass === "function" ? rowClass({
4724
+ row: row,
4725
+ rowIndex: globalIndex
4726
+ }) : "";
4727
+ var safeExtraRowClass = typeof extraRowClass === "string" ? extraRowClass.trim() : "";
4728
+ var stripeBg = stripedRows && !selectedRows.has(key) ? stripedColors[globalIndex % stripedColors.length] : undefined;
4951
4729
  return /*#__PURE__*/React.createElement(React.Fragment, {
4952
4730
  key: key
4953
4731
  }, /*#__PURE__*/React.createElement("tr", {
@@ -4957,7 +4735,7 @@ var Table = function Table(_ref) {
4957
4735
  className: cn$1("hover:bg-gray-50", {
4958
4736
  "cursor-pointer": !!onRowClick,
4959
4737
  "bg-primary-50": selectedRows.has(key)
4960
- }, extraRowClass),
4738
+ }, safeExtraRowClass),
4961
4739
  onClick: function onClick() {
4962
4740
  return onRowClick === null || onRowClick === void 0 ? void 0 : onRowClick(row, globalIndex);
4963
4741
  }
@@ -4985,15 +4763,16 @@ var Table = function Table(_ref) {
4985
4763
  return handleSelectRow(row, rowIndexInPage);
4986
4764
  }
4987
4765
  })), visibleColumns.map(function (column, columnIndex) {
4988
- var extraCellClass = typeof cellClass === "function" ? (cellClass({
4766
+ var extraCellClass = typeof cellClass === "function" ? cellClass({
4989
4767
  row: row,
4990
4768
  rowIndex: globalIndex,
4991
4769
  column: column,
4992
4770
  columnIndex: columnIndex
4993
- }) || "").trim() : "";
4771
+ }) : "";
4772
+ var safeExtraCellClass = typeof extraCellClass === "string" ? extraCellClass.trim() : "";
4994
4773
  return /*#__PURE__*/React.createElement("td", {
4995
4774
  key: column.key,
4996
- className: cn$1("px-6 py-4 whitespace-nowrap text-sm text-gray-900", extraCellClass)
4775
+ className: cn$1("px-6 py-4 whitespace-nowrap text-sm text-gray-900", safeExtraCellClass)
4997
4776
  }, renderCell(column, row, globalIndex));
4998
4777
  }), withAction && /*#__PURE__*/React.createElement("td", {
4999
4778
  className: "px-4 py-4 text-sm text-right",
@@ -5036,9 +4815,23 @@ var Table = function Table(_ref) {
5036
4815
  className: "p-4"
5037
4816
  }, loading ? /*#__PURE__*/React.createElement("div", {
5038
4817
  className: "py-8 text-center"
5039
- }, /*#__PURE__*/React.createElement(LoadingState, null)) : paginatedData.length === 0 ? /*#__PURE__*/React.createElement("div", {
4818
+ }, /*#__PURE__*/React.createElement("div", {
4819
+ className: "flex flex-col items-center gap-2"
4820
+ }, /*#__PURE__*/React.createElement("div", {
4821
+ className: "h-6 w-6 animate-spin rounded-full border-2 border-primary-600 border-t-transparent"
4822
+ }), /*#__PURE__*/React.createElement("span", {
4823
+ className: "text-sm text-gray-500"
4824
+ }, "Loading..."))) : paginatedData.length === 0 ? /*#__PURE__*/React.createElement("div", {
5040
4825
  className: "py-8 text-center"
5041
- }, /*#__PURE__*/React.createElement(EmptyState, null)) : paginatedData.map(function (row, rowIndexInPage) {
4826
+ }, /*#__PURE__*/React.createElement("div", {
4827
+ className: "flex flex-col items-center gap-2"
4828
+ }, /*#__PURE__*/React.createElement("div", {
4829
+ className: "text-gray-400"
4830
+ }, /*#__PURE__*/React.createElement(List, {
4831
+ className: "h-8 w-8"
4832
+ })), /*#__PURE__*/React.createElement("span", {
4833
+ className: "text-sm text-gray-500"
4834
+ }, "No results found."))) : paginatedData.map(function (row, rowIndexInPage) {
5042
4835
  return renderMobileCard(row, rowIndexInPage);
5043
4836
  })), pagination && /*#__PURE__*/React.createElement("div", {
5044
4837
  className: "p-4 border-t"
@@ -5049,25 +4842,28 @@ var Table = function Table(_ref) {
5049
4842
  }, "Page ", currentPage, " of ", totalPages), /*#__PURE__*/React.createElement("div", {
5050
4843
  className: "flex items-center gap-2"
5051
4844
  }, /*#__PURE__*/React.createElement("button", {
5052
- className: "rounded-lg md:rounded-md border border-gray-300 px-3 py-2 text-sm disabled:opacity-50 hover:bg-gray-50 flex items-center gap-1",
5053
- disabled: currentPage === 1,
5054
- onClick: function onClick() {
5055
- return handlePageChange(1);
5056
- },
5057
- title: "First page"
5058
- }, /*#__PURE__*/React.createElement(ChevronsLeft, {
5059
- className: "size-4"
5060
- }), /*#__PURE__*/React.createElement("span", {
5061
- className: "hidden sm:inline"
5062
- }, "First")), /*#__PURE__*/React.createElement("button", {
5063
4845
  className: "rounded-lg md:rounded-md border border-gray-300 px-4 py-2 text-sm disabled:opacity-50 hover:bg-gray-50",
5064
4846
  disabled: currentPage === 1,
5065
4847
  onClick: function onClick() {
5066
- return handlePageChange(Math.max(1, currentPage - 1));
4848
+ return setCurrentPage(function (p) {
4849
+ return Math.max(1, p - 1);
4850
+ });
5067
4851
  }
5068
4852
  }, "Previous"), /*#__PURE__*/React.createElement("div", {
5069
4853
  className: "flex items-center gap-1"
5070
- }, getPaginationNumbers(currentPage, totalPages).map(function (pageNum) {
4854
+ }, Array.from({
4855
+ length: Math.min(5, totalPages)
4856
+ }, function (_, i) {
4857
+ var pageNum;
4858
+ if (totalPages <= 5) {
4859
+ pageNum = i + 1;
4860
+ } else if (currentPage <= 3) {
4861
+ pageNum = i + 1;
4862
+ } else if (currentPage >= totalPages - 2) {
4863
+ pageNum = totalPages - 4 + i;
4864
+ } else {
4865
+ pageNum = currentPage - 2 + i;
4866
+ }
5071
4867
  return /*#__PURE__*/React.createElement("button", {
5072
4868
  key: pageNum,
5073
4869
  className: cn$1("h-8 w-8 rounded-lg md:rounded-md text-sm", {
@@ -5075,34 +4871,19 @@ var Table = function Table(_ref) {
5075
4871
  "border border-gray-300 hover:bg-gray-50": pageNum !== currentPage
5076
4872
  }),
5077
4873
  onClick: function onClick() {
5078
- return handlePageChange(pageNum);
4874
+ return setCurrentPage(pageNum);
5079
4875
  }
5080
4876
  }, pageNum);
5081
4877
  })), /*#__PURE__*/React.createElement("button", {
5082
4878
  className: "rounded-lg md:rounded-md border border-gray-300 px-4 py-2 text-sm disabled:opacity-50 hover:bg-gray-50",
5083
4879
  disabled: currentPage === totalPages,
5084
4880
  onClick: function onClick() {
5085
- return handlePageChange(Math.min(totalPages, currentPage + 1));
4881
+ return setCurrentPage(function (p) {
4882
+ return Math.min(totalPages, p + 1);
4883
+ });
5086
4884
  }
5087
- }, "Next"), /*#__PURE__*/React.createElement("button", {
5088
- className: "rounded-lg md:rounded-md border border-gray-300 px-3 py-2 text-sm disabled:opacity-50 hover:bg-gray-50 flex items-center gap-1",
5089
- disabled: currentPage === totalPages,
5090
- onClick: function onClick() {
5091
- return handlePageChange(totalPages);
5092
- },
5093
- title: "Last page"
5094
- }, /*#__PURE__*/React.createElement("span", {
5095
- className: "hidden sm:inline"
5096
- }, "Last"), /*#__PURE__*/React.createElement(ChevronsRight, {
5097
- className: "size-4"
5098
- }))))));
4885
+ }, "Next")))));
5099
4886
  };
5100
-
5101
- // ActionMenuPortal constants
5102
- var MENU_WIDTH = 180;
5103
- var MAX_MENU_HEIGHT = 320;
5104
- var MENU_MARGIN = 8;
5105
- var MIN_MENU_HEIGHT = 80;
5106
4887
  function ActionMenuPortal(_ref2) {
5107
4888
  var anchorElem = _ref2.anchorElem,
5108
4889
  anchorRow = _ref2.anchorRow,
@@ -5116,12 +4897,16 @@ function ActionMenuPortal(_ref2) {
5116
4897
  top: 0,
5117
4898
  transformOrigin: "top right",
5118
4899
  maxHeight: 300,
5119
- width: MENU_WIDTH,
4900
+ width: 180,
5120
4901
  opacity: 0
5121
4902
  }),
5122
4903
  _useState30 = _slicedToArray(_useState29, 2),
5123
4904
  style = _useState30[0],
5124
4905
  setStyle = _useState30[1];
4906
+ var menuWidth = 180;
4907
+ var maxMenuHeight = 320;
4908
+ var margin = 8;
4909
+ var minMenuHeight = 80;
5125
4910
 
5126
4911
  // compute position using actual menu height (if available) and layout measurements
5127
4912
  var computePosition = function computePosition() {
@@ -5133,17 +4918,17 @@ function ActionMenuPortal(_ref2) {
5133
4918
  var spaceAbove = rect.top;
5134
4919
 
5135
4920
  // allowed max height based on available space
5136
- var allowedMaxHeight = Math.min(MAX_MENU_HEIGHT, Math.max(MIN_MENU_HEIGHT, Math.max(spaceBelow - MENU_MARGIN, spaceAbove - MENU_MARGIN)));
4921
+ var allowedMaxHeight = Math.min(maxMenuHeight, Math.max(minMenuHeight, Math.max(spaceBelow - margin, spaceAbove - margin)));
5137
4922
 
5138
4923
  // choose placement by comparing actual available spaces
5139
4924
  var placement = "bottom";
5140
- if (spaceBelow < MENU_PLACEMENT_THRESHOLD && spaceAbove > spaceBelow) {
4925
+ if (spaceBelow < 160 && spaceAbove > spaceBelow) {
5141
4926
  placement = "top";
5142
4927
  // when placing on top we should cap allowedMaxHeight by spaceAbove
5143
- allowedMaxHeight = Math.min(MAX_MENU_HEIGHT, Math.max(MIN_MENU_HEIGHT, spaceAbove - MENU_MARGIN));
4928
+ allowedMaxHeight = Math.min(maxMenuHeight, Math.max(minMenuHeight, spaceAbove - margin));
5144
4929
  } else {
5145
4930
  // placing bottom: cap by spaceBelow
5146
- allowedMaxHeight = Math.min(MAX_MENU_HEIGHT, Math.max(MIN_MENU_HEIGHT, spaceBelow - MENU_MARGIN));
4931
+ allowedMaxHeight = Math.min(maxMenuHeight, Math.max(minMenuHeight, spaceBelow - margin));
5147
4932
  }
5148
4933
 
5149
4934
  // measure the menu's content height if we can, and compute the actual menu height we'll use.
@@ -5160,23 +4945,23 @@ function ActionMenuPortal(_ref2) {
5160
4945
  var top;
5161
4946
  if (placement === "top") {
5162
4947
  // place menu so its bottom sits just above the anchor (rect.top - margin)
5163
- top = rect.top + scrollY - measuredMenuHeight - MENU_MARGIN;
4948
+ top = rect.top + scrollY - measuredMenuHeight - margin;
5164
4949
  } else {
5165
4950
  // place menu just below the anchor (rect.bottom + margin)
5166
- top = rect.bottom + scrollY + MENU_MARGIN;
4951
+ top = rect.bottom + scrollY + margin;
5167
4952
  }
5168
4953
 
5169
4954
  // clamp top to viewport (so it never goes off-screen)
5170
- var minTop = MENU_MARGIN + scrollY;
5171
- var maxTop = window.innerHeight + scrollY - measuredMenuHeight - MENU_MARGIN;
4955
+ var minTop = margin + scrollY;
4956
+ var maxTop = window.innerHeight + scrollY - measuredMenuHeight - margin;
5172
4957
  if (top < minTop) top = minTop;
5173
4958
  if (top > maxTop) top = maxTop;
5174
4959
 
5175
4960
  // compute left and clamp horizontally
5176
- var left = rect.right + scrollX - MENU_WIDTH;
5177
- if (left < MENU_MARGIN) left = MENU_MARGIN;
5178
- if (left + MENU_WIDTH > window.innerWidth - MENU_MARGIN) {
5179
- left = Math.max(MENU_MARGIN, window.innerWidth - MENU_WIDTH - MENU_MARGIN);
4961
+ var left = rect.right + scrollX - menuWidth;
4962
+ if (left < margin) left = margin;
4963
+ if (left + menuWidth > window.innerWidth - margin) {
4964
+ left = Math.max(margin, window.innerWidth - menuWidth - margin);
5180
4965
  }
5181
4966
  var transformOrigin = placement === "bottom" ? "top right" : "bottom right";
5182
4967
 
@@ -5186,7 +4971,7 @@ function ActionMenuPortal(_ref2) {
5186
4971
  top: top,
5187
4972
  transformOrigin: transformOrigin,
5188
4973
  maxHeight: allowedMaxHeight,
5189
- width: MENU_WIDTH,
4974
+ width: menuWidth,
5190
4975
  opacity: 1
5191
4976
  });
5192
4977
  };
@@ -5209,8 +4994,7 @@ function ActionMenuPortal(_ref2) {
5209
4994
  window.removeEventListener("scroll", onScrollOrResize, true);
5210
4995
  };
5211
4996
  // Recompute when anchor element changes or actions change (content height may change).
5212
- // Note: menuRef is a ref object and never changes, so it's safe to include
5213
- }, [anchorElem, actions]);
4997
+ }, [anchorElem, actions, menuRef]);
5214
4998
  return /*#__PURE__*/ReactDOM.createPortal(/*#__PURE__*/React.createElement("div", {
5215
4999
  ref: menuRef,
5216
5000
  style: {