@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.esm.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import * as React from 'react';
2
- import React__default, { forwardRef, createElement, useId, useRef, useState, useEffect, useImperativeHandle, useMemo, useCallback, useLayoutEffect, createContext, useContext, cloneElement, PureComponent } from 'react';
2
+ import React__default, { forwardRef, createElement, useId, useRef, useState, useEffect, useImperativeHandle, useMemo, useLayoutEffect, useCallback, createContext, useContext, cloneElement, PureComponent } from 'react';
3
3
  import ReactDOM, { createPortal } from 'react-dom';
4
4
 
5
5
  function _extends() {
@@ -256,26 +256,6 @@ const ChevronUp = createLucideIcon$1("ChevronUp", [
256
256
  */
257
257
 
258
258
 
259
- const ChevronsLeft = createLucideIcon$1("ChevronsLeft", [
260
- ["path", { d: "m11 17-5-5 5-5", key: "13zhaf" }],
261
- ["path", { d: "m18 17-5-5 5-5", key: "h8a8et" }]
262
- ]);
263
-
264
- /**
265
- * lucide-react v0.0.1 - ISC
266
- */
267
-
268
-
269
- const ChevronsRight = createLucideIcon$1("ChevronsRight", [
270
- ["path", { d: "m6 17 5-5-5-5", key: "xnjwq" }],
271
- ["path", { d: "m13 17 5-5-5-5", key: "17xmmf" }]
272
- ]);
273
-
274
- /**
275
- * lucide-react v0.0.1 - ISC
276
- */
277
-
278
-
279
259
  const EyeOff = createLucideIcon$1("EyeOff", [
280
260
  ["path", { d: "M9.88 9.88a3 3 0 1 0 4.24 4.24", key: "1jxqfv" }],
281
261
  [
@@ -3886,98 +3866,6 @@ var Select = /*#__PURE__*/React__default.forwardRef(function (_ref, forwardedRef
3886
3866
  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"];
3887
3867
  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; }
3888
3868
  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; }
3889
-
3890
- // Constants moved outside component
3891
- var DEFAULT_ACTIONS = [{
3892
- name: "edit",
3893
- label: "Edit",
3894
- onClick: function onClick() {
3895
- console.log("Edit action clicked");
3896
- },
3897
- icon: /*#__PURE__*/React__default.createElement(PenSquare, {
3898
- size: 16
3899
- })
3900
- }, {
3901
- name: "delete",
3902
- label: "Delete",
3903
- onClick: function onClick() {
3904
- console.log("Delete action clicked");
3905
- },
3906
- icon: /*#__PURE__*/React__default.createElement(Trash, {
3907
- size: 16
3908
- })
3909
- }, {
3910
- name: "view",
3911
- label: "View",
3912
- onClick: function onClick() {
3913
- console.log("View action clicked");
3914
- },
3915
- icon: /*#__PURE__*/React__default.createElement(Eye, {
3916
- size: 16
3917
- })
3918
- }];
3919
- var RESIZE_DEBOUNCE_MS = 150;
3920
- var MENU_PLACEMENT_THRESHOLD = 160;
3921
-
3922
- // Helper functions
3923
- var getRowKey = function getRowKey(row, globalIndex) {
3924
- if ((row === null || row === void 0 ? void 0 : row.id) != null) return String(row.id);
3925
- if ((row === null || row === void 0 ? void 0 : row._id) != null) return String(row._id);
3926
- return String(globalIndex);
3927
- };
3928
-
3929
- // Calculate pagination numbers
3930
- var getPaginationNumbers = function getPaginationNumbers(currentPage, totalPages) {
3931
- var maxVisible = 5;
3932
- if (totalPages <= maxVisible) {
3933
- return Array.from({
3934
- length: totalPages
3935
- }, function (_, i) {
3936
- return i + 1;
3937
- });
3938
- }
3939
- if (currentPage <= 3) {
3940
- return Array.from({
3941
- length: maxVisible
3942
- }, function (_, i) {
3943
- return i + 1;
3944
- });
3945
- }
3946
- if (currentPage >= totalPages - 2) {
3947
- return Array.from({
3948
- length: maxVisible
3949
- }, function (_, i) {
3950
- return totalPages - 4 + i;
3951
- });
3952
- }
3953
- return Array.from({
3954
- length: maxVisible
3955
- }, function (_, i) {
3956
- return currentPage - 2 + i;
3957
- });
3958
- };
3959
-
3960
- // Empty and Loading state components
3961
- var EmptyState = function EmptyState() {
3962
- return /*#__PURE__*/React__default.createElement("div", {
3963
- className: "flex flex-col items-center gap-2"
3964
- }, /*#__PURE__*/React__default.createElement("div", {
3965
- className: "text-gray-400"
3966
- }, /*#__PURE__*/React__default.createElement(List, {
3967
- className: "h-8 w-8"
3968
- })), /*#__PURE__*/React__default.createElement("span", {
3969
- className: "text-sm text-gray-500"
3970
- }, "No results found."));
3971
- };
3972
- var LoadingState = function LoadingState() {
3973
- return /*#__PURE__*/React__default.createElement("div", {
3974
- className: "flex flex-col items-center gap-2"
3975
- }, /*#__PURE__*/React__default.createElement("div", {
3976
- className: "h-6 w-6 animate-spin rounded-full border-2 border-primary-600 border-t-transparent"
3977
- }), /*#__PURE__*/React__default.createElement("span", {
3978
- className: "text-sm text-gray-500"
3979
- }, "Loading..."));
3980
- };
3981
3869
  var Table = function Table(_ref) {
3982
3870
  var _ref$data = _ref.data,
3983
3871
  data = _ref$data === void 0 ? [] : _ref$data,
@@ -4033,9 +3921,9 @@ var Table = function Table(_ref) {
4033
3921
  serverSide = _ref$serverSide === void 0 ? false : _ref$serverSide,
4034
3922
  _ref$totalRecords = _ref.totalRecords,
4035
3923
  totalRecords = _ref$totalRecords === void 0 ? 0 : _ref$totalRecords,
4036
- pageNumber = _ref.pageNumber,
4037
- onPageChange = _ref.onPageChange,
4038
- props = _objectWithoutProperties$1(_ref, _excluded$k);
3924
+ pageNumber = _ref.pageNumber;
3925
+ _ref.onPageChange;
3926
+ var props = _objectWithoutProperties$1(_ref, _excluded$k);
4039
3927
  // State for responsive view
4040
3928
  var _useState = useState(false),
4041
3929
  _useState2 = _slicedToArray(_useState, 2),
@@ -4043,16 +3931,14 @@ var Table = function Table(_ref) {
4043
3931
  setIsMobileView = _useState2[1];
4044
3932
 
4045
3933
  // Keep original table data / loading
4046
- var _useState3 = useState(function () {
4047
- return Array.isArray(data) ? data : [];
4048
- }),
3934
+ var _useState3 = useState(Array.isArray(data) ? data : []),
4049
3935
  _useState4 = _slicedToArray(_useState3, 2),
4050
3936
  tableData = _useState4[0],
4051
3937
  setTableData = _useState4[1];
4052
3938
  var _useState5 = useState(false),
4053
3939
  _useState6 = _slicedToArray(_useState5, 2),
4054
3940
  loading = _useState6[0],
4055
- _setLoading = _useState6[1];
3941
+ setLoading = _useState6[1];
4056
3942
 
4057
3943
  // Column visibility state
4058
3944
  var _useState7 = useState(function () {
@@ -4064,26 +3950,10 @@ var Table = function Table(_ref) {
4064
3950
  columnsState = _useState8[0],
4065
3951
  setColumnsState = _useState8[1];
4066
3952
  useEffect(function () {
4067
- // Sync when prop changes - only update if columns actually changed
4068
- if (Array.isArray(columns)) {
4069
- setColumnsState(function (prev) {
4070
- var prevKeys = new Set(prev.map(function (c) {
4071
- return c.key;
4072
- }));
4073
- var newKeys = new Set(columns.map(function (c) {
4074
- return c.key;
4075
- }));
4076
- var keysChanged = prevKeys.size !== newKeys.size || _toConsumableArray$1(prevKeys).some(function (k) {
4077
- return !newKeys.has(k);
4078
- });
4079
- if (keysChanged) {
4080
- return columns.map(function (c) {
4081
- return _objectSpread$9({}, c);
4082
- });
4083
- }
4084
- return prev;
4085
- });
4086
- }
3953
+ // Sync when prop changes
3954
+ setColumnsState(Array.isArray(columns) ? columns.map(function (c) {
3955
+ return _objectSpread$9({}, c);
3956
+ }) : []);
4087
3957
  }, [columns]);
4088
3958
 
4089
3959
  // Popover state for column toggler
@@ -4143,44 +4013,39 @@ var Table = function Table(_ref) {
4143
4013
  _useState28 = _slicedToArray(_useState27, 2),
4144
4014
  openActionKey = _useState28[0],
4145
4015
  setOpenActionKey = _useState28[1];
4016
+ var openRef = useRef(null);
4146
4017
  useEffect(function () {
4147
4018
  if (typeof pageNumber === "number" && pageNumber !== currentPage) {
4148
4019
  setCurrentPage(pageNumber);
4149
- // Note: onPageChange is intentionally not called here to avoid loops
4150
- // Parent should handle page changes via controlled component pattern
4151
4020
  }
4152
- }, [pageNumber, currentPage]);
4021
+ }, [pageNumber]);
4153
4022
  useEffect(function () {
4154
4023
  setLimit(pageSize);
4155
4024
  }, [pageSize]);
4156
4025
 
4157
- // Check if mobile view with debouncing
4026
+ // Check if mobile view
4158
4027
  useEffect(function () {
4159
- var timeoutId;
4160
4028
  var checkMobile = function checkMobile() {
4161
4029
  setIsMobileView(window.innerWidth < responsiveBreakpoint);
4162
4030
  };
4163
- var debouncedCheck = function debouncedCheck() {
4164
- clearTimeout(timeoutId);
4165
- timeoutId = setTimeout(checkMobile, RESIZE_DEBOUNCE_MS);
4166
- };
4167
4031
 
4168
4032
  // Initial check
4169
4033
  checkMobile();
4170
4034
 
4171
- // Add event listener with debouncing
4172
- window.addEventListener("resize", debouncedCheck);
4035
+ // Add event listener
4036
+ window.addEventListener("resize", checkMobile);
4173
4037
  return function () {
4174
- clearTimeout(timeoutId);
4175
- window.removeEventListener("resize", debouncedCheck);
4038
+ window.removeEventListener("resize", checkMobile);
4176
4039
  };
4177
4040
  }, [responsiveBreakpoint]);
4041
+ var isValidList = function isValidList(d) {
4042
+ return Array.isArray(d);
4043
+ };
4178
4044
 
4179
4045
  // Close column menu when clicking outside
4180
4046
  useEffect(function () {
4181
- if (!showColumnMenu) return;
4182
4047
  var onDocClick = function onDocClick(e) {
4183
- if (columnMenuRef.current && !columnMenuRef.current.contains(e.target) && columnToggleBtnRef.current && !columnToggleBtnRef.current.contains(e.target)) {
4048
+ if (showColumnMenu && columnMenuRef.current && !columnMenuRef.current.contains(e.target) && columnToggleBtnRef.current && !columnToggleBtnRef.current.contains(e.target)) {
4184
4049
  setShowColumnMenu(false);
4185
4050
  }
4186
4051
  };
@@ -4190,38 +4055,26 @@ var Table = function Table(_ref) {
4190
4055
  };
4191
4056
  }, [showColumnMenu]);
4192
4057
 
4058
+ // Close per-row actionmenu when clicking outside
4059
+ useEffect(function () {
4060
+ var handler = function handler(e) {
4061
+ if (openActionKey && openRef.current && !openRef.current.contains(e.target)) {
4062
+ setOpenActionKey(null);
4063
+ }
4064
+ };
4065
+ document.addEventListener("click", handler);
4066
+ return function () {
4067
+ return document.removeEventListener("click", handler);
4068
+ };
4069
+ }, [openActionKey]);
4070
+
4193
4071
  // Visible columns derived from columnsState
4194
4072
  var visibleColumns = useMemo(function () {
4195
4073
  return columnsState.filter(function (col) {
4196
4074
  return col.isVisible !== false;
4197
4075
  });
4198
4076
  }, [columnsState]);
4199
-
4200
- // Memoize actions
4201
- var actionsToUse = useMemo(function () {
4202
- return actions !== null && actions !== void 0 ? actions : DEFAULT_ACTIONS;
4203
- }, [actions]);
4204
-
4205
- // Memoize visible count
4206
- var visibleCount = useMemo(function () {
4207
- return (showSerial ? 1 : 0) + visibleColumns.length + (selectable ? 1 : 0) + (hasDetails ? 1 : 0) + (withAction ? 1 : 0);
4208
- }, [showSerial, visibleColumns.length, selectable, hasDetails, withAction]);
4209
-
4210
- // Memoize key-to-row mapping for selection
4211
- var keyToRowMap = useMemo(function () {
4212
- var map = new Map();
4213
- filteredData.forEach(function (row, i) {
4214
- map.set(getRowKey(row, i), row);
4215
- });
4216
- return map;
4217
- }, [filteredData]);
4218
-
4219
- // Wrapper for setCurrentPage that also calls onPageChange
4220
- var handlePageChange = useCallback(function (newPage) {
4221
- setCurrentPage(newPage);
4222
- onPageChange === null || onPageChange === void 0 || onPageChange(newPage);
4223
- }, [onPageChange]);
4224
- var toggleColumnVisibility = useCallback(function (key) {
4077
+ var toggleColumnVisibility = function toggleColumnVisibility(key) {
4225
4078
  setColumnsState(function (prev) {
4226
4079
  return prev.map(function (c) {
4227
4080
  return c.key === key ? _objectSpread$9(_objectSpread$9({}, c), {}, {
@@ -4229,23 +4082,58 @@ var Table = function Table(_ref) {
4229
4082
  }) : c;
4230
4083
  });
4231
4084
  });
4232
- handlePageChange(1);
4233
- }, [handlePageChange]);
4085
+ setCurrentPage(1);
4086
+ };
4234
4087
 
4235
4088
  // Handle actions
4236
- var handleOnAction = useCallback(function (action, row) {
4089
+ var handleOnAction = function handleOnAction(action, row) {
4237
4090
  var _action$onClick;
4238
4091
  (_action$onClick = action.onClick) === null || _action$onClick === void 0 || _action$onClick.call(action, {
4239
4092
  action: action,
4240
4093
  row: row
4241
4094
  });
4242
- onAction === null || onAction === void 0 || onAction({
4095
+ onAction && onAction({
4243
4096
  action: action,
4244
4097
  row: row
4245
4098
  });
4246
4099
  setOpenActionKey(null);
4247
4100
  setActionAnchor(null);
4248
- }, [onAction]);
4101
+ };
4102
+ var defaultActions = [{
4103
+ name: "edit",
4104
+ label: "Edit",
4105
+ onClick: function onClick() {
4106
+ console.log("Edit action clicked");
4107
+ },
4108
+ icon: /*#__PURE__*/React__default.createElement(PenSquare, {
4109
+ size: 16
4110
+ })
4111
+ }, {
4112
+ name: "delete",
4113
+ label: "Delete",
4114
+ onClick: function onClick() {
4115
+ console.log("Delete action clicked");
4116
+ },
4117
+ icon: /*#__PURE__*/React__default.createElement(Trash, {
4118
+ size: 16
4119
+ })
4120
+ }, {
4121
+ name: "view",
4122
+ label: "View",
4123
+ onClick: function onClick() {
4124
+ console.log("View action clicked");
4125
+ },
4126
+ icon: /*#__PURE__*/React__default.createElement(Eye, {
4127
+ size: 16
4128
+ })
4129
+ }];
4130
+ var actionsToUse = actions !== undefined ? actions : defaultActions;
4131
+ var getRowKey = function getRowKey(row, globalIndex) {
4132
+ if (row == null) return String(globalIndex);
4133
+ if (row.id !== undefined && row.id !== null) return String(row.id);
4134
+ if (row._id !== undefined && row._id !== null) return String(row._id);
4135
+ return String(globalIndex);
4136
+ };
4249
4137
 
4250
4138
  // Sorting
4251
4139
  var sortedData = useMemo(function () {
@@ -4264,38 +4152,16 @@ var Table = function Table(_ref) {
4264
4152
  // Filtering
4265
4153
  var filteredData = useMemo(function () {
4266
4154
  if (serverSide || !filterable || !Object.keys(filters).length) return sortedData;
4155
+ var q = (filters.global || "").toLowerCase();
4267
4156
  return sortedData.filter(function (row) {
4268
- // Apply global search filter if present
4269
- if (filters.global) {
4270
- var q = filters.global.toLowerCase();
4271
- var matchesGlobal = Object.values(row || {}).some(function (v) {
4272
- return String(v).toLowerCase().includes(q);
4273
- });
4274
- if (!matchesGlobal) return false;
4275
- }
4276
-
4277
- // Apply column-specific filters
4278
- return visibleColumns.every(function (column) {
4279
- var columnFilter = filters[column.key];
4280
- if (!columnFilter) return true; // No filter for this column
4281
-
4282
- var cellValue = row === null || row === void 0 ? void 0 : row[column.key];
4283
- return String(cellValue || "").toLowerCase().includes(columnFilter.toLowerCase());
4157
+ return Object.values(row || {}).some(function (v) {
4158
+ return String(v).toLowerCase().includes(q);
4284
4159
  });
4285
4160
  });
4286
- }, [sortedData, filters, filterable, serverSide, visibleColumns]);
4287
-
4288
- // Pagination indices - memoized
4289
- var _useMemo = useMemo(function () {
4290
- var start = pagination ? (currentPage - 1) * limit : 0;
4291
- var end = pagination ? start + limit : filteredData.length;
4292
- return {
4293
- startIndex: start,
4294
- endIndex: end
4295
- };
4296
- }, [pagination, currentPage, limit, filteredData.length]),
4297
- startIndex = _useMemo.startIndex,
4298
- endIndex = _useMemo.endIndex;
4161
+ }, [sortedData, filters, filterable, serverSide]);
4162
+ // Pagination indices
4163
+ var startIndex = pagination ? (currentPage - 1) * limit : 0;
4164
+ var endIndex = pagination ? startIndex + limit : filteredData.length;
4299
4165
 
4300
4166
  // Paginated view
4301
4167
  var paginatedData = useMemo(function () {
@@ -4309,7 +4175,7 @@ var Table = function Table(_ref) {
4309
4175
  }, [pagination, serverSide, totalRecords, filteredData.length, limit]);
4310
4176
 
4311
4177
  // Sorting handler
4312
- var handleSort = useCallback(function (key) {
4178
+ var handleSort = function handleSort(key) {
4313
4179
  if (!sortable) return;
4314
4180
  var direction = sortConfig.key === key && sortConfig.direction === "asc" ? "desc" : "asc";
4315
4181
  setSortConfig({
@@ -4317,10 +4183,10 @@ var Table = function Table(_ref) {
4317
4183
  direction: direction
4318
4184
  });
4319
4185
  onSort === null || onSort === void 0 || onSort(key, direction);
4320
- }, [sortable, sortConfig, onSort]);
4186
+ };
4321
4187
 
4322
- // Selection handlers - optimized with memoized keyToRowMap
4323
- var handleSelectAll = useCallback(function () {
4188
+ // Selection handlers
4189
+ var handleSelectAll = function handleSelectAll() {
4324
4190
  var newSelection = new Set(selectedRows);
4325
4191
  var pageRowKeys = paginatedData.map(function (r, i) {
4326
4192
  return getRowKey(r, startIndex + i);
@@ -4338,45 +4204,50 @@ var Table = function Table(_ref) {
4338
4204
  });
4339
4205
  }
4340
4206
  setSelectedRows(newSelection);
4207
+ var keyToRow = new Map(filteredData.map(function (r, i) {
4208
+ return [getRowKey(r, i), r];
4209
+ }));
4341
4210
  var selectedData = Array.from(newSelection).map(function (k) {
4342
- return keyToRowMap.get(k);
4211
+ return keyToRow.get(k);
4343
4212
  }).filter(Boolean);
4344
4213
  onSelectionChange === null || onSelectionChange === void 0 || onSelectionChange(selectedData);
4345
- }, [selectedRows, paginatedData, startIndex, keyToRowMap, onSelectionChange]);
4346
- var handleSelectRow = useCallback(function (row, rowIndexInPage) {
4214
+ };
4215
+ var handleSelectRow = function handleSelectRow(row, rowIndexInPage) {
4347
4216
  var globalIndex = startIndex + rowIndexInPage;
4348
4217
  var key = getRowKey(row, globalIndex);
4349
4218
  var newSelection = new Set(selectedRows);
4350
4219
  if (newSelection.has(key)) newSelection["delete"](key);else newSelection.add(key);
4351
4220
  setSelectedRows(newSelection);
4221
+ var keyToRow = new Map(filteredData.map(function (r, i) {
4222
+ return [getRowKey(r, i), r];
4223
+ }));
4352
4224
  var selectedData = Array.from(newSelection).map(function (k) {
4353
- return keyToRowMap.get(k);
4225
+ return keyToRow.get(k);
4354
4226
  }).filter(Boolean);
4355
4227
  onSelectionChange === null || onSelectionChange === void 0 || onSelectionChange(selectedData);
4356
- }, [startIndex, selectedRows, keyToRowMap, onSelectionChange]);
4357
- var toggleExpandRow = useCallback(function (row, rowIndexInPage) {
4228
+ };
4229
+ var toggleExpandRow = function toggleExpandRow(row, rowIndexInPage) {
4358
4230
  var globalIndex = startIndex + rowIndexInPage;
4359
4231
  var key = getRowKey(row, globalIndex);
4360
- setExpandedRows(function (prev) {
4361
- var newExpanded = new Set(prev);
4362
- if (newExpanded.has(key)) newExpanded["delete"](key);else newExpanded.add(key);
4363
- return newExpanded;
4364
- });
4365
- }, [startIndex]);
4366
- var handleFilter = useCallback(function (key, value) {
4367
- setFilters(function (prev) {
4368
- var newFilters = _objectSpread$9(_objectSpread$9({}, prev), {}, _defineProperty$4({}, key, value));
4369
- onFilter === null || onFilter === void 0 || onFilter(newFilters);
4370
- onFilterChange === null || onFilterChange === void 0 || onFilterChange(newFilters);
4371
- return newFilters;
4372
- });
4373
- handlePageChange(1);
4374
- }, [onFilter, onFilterChange, handlePageChange]);
4375
- var renderCell = useCallback(function (column, row, globalIndex) {
4232
+ var newExpanded = new Set(expandedRows);
4233
+ if (newExpanded.has(key)) newExpanded["delete"](key);else newExpanded.add(key);
4234
+ setExpandedRows(newExpanded);
4235
+ };
4236
+ var handleFilter = function handleFilter(key, value) {
4237
+ var newFilters = _objectSpread$9(_objectSpread$9({}, filters), {}, _defineProperty$4({}, key, value));
4238
+ setFilters(newFilters);
4239
+ onFilter === null || onFilter === void 0 || onFilter(newFilters);
4240
+ onFilterChange === null || onFilterChange === void 0 || onFilterChange(newFilters);
4241
+ setCurrentPage(1);
4242
+ };
4243
+ var renderCell = function renderCell(column, row, globalIndex) {
4376
4244
  if (column.render) return column.render(row, globalIndex);
4377
4245
  return row === null || row === void 0 ? void 0 : row[column.key];
4378
- }, []);
4379
- var toggleActions = useCallback(function (e, actionCellKey, row) {
4246
+ };
4247
+
4248
+ // UI counts
4249
+ var visibleCount = (showSerial ? 1 : 0) + visibleColumns.length + (selectable ? 1 : 0) + (hasDetails ? 1 : 0) + (withAction ? 1 : 0);
4250
+ var toggleActions = function toggleActions(e, actionCellKey, row) {
4380
4251
  e.stopPropagation();
4381
4252
  if (actionAnchor && actionAnchor.key === actionCellKey) {
4382
4253
  setOpenActionKey(null);
@@ -4389,7 +4260,7 @@ var Table = function Table(_ref) {
4389
4260
  row: row
4390
4261
  });
4391
4262
  }
4392
- }, [actionAnchor]);
4263
+ };
4393
4264
  useEffect(function () {
4394
4265
  if (!actionAnchor) return;
4395
4266
  var onDocClick = function onDocClick(ev) {
@@ -4400,9 +4271,9 @@ var Table = function Table(_ref) {
4400
4271
  setActionAnchor(null);
4401
4272
  };
4402
4273
  var onScrollResize = function onScrollResize() {
4403
- // Close menu on scroll/resize to prevent positioning issues
4404
- setOpenActionKey(null);
4405
- setActionAnchor(null);
4274
+ setOpenActionKey(function (k) {
4275
+ return k ? k : null;
4276
+ });
4406
4277
  };
4407
4278
  window.addEventListener("click", onDocClick);
4408
4279
  window.addEventListener("scroll", onScrollResize, true);
@@ -4413,163 +4284,58 @@ var Table = function Table(_ref) {
4413
4284
  window.removeEventListener("resize", onScrollResize);
4414
4285
  };
4415
4286
  }, [actionAnchor]);
4416
-
4417
- // Track previous fetch params to prevent unnecessary calls
4418
- var prevFetchParamsRef = useRef(null);
4419
- var isFetchingRef = useRef(false);
4420
- var isMountedRef = useRef(true);
4421
- var onFetchRef = useRef(onFetch);
4422
- var activeFetchIdRef = useRef(0);
4423
-
4424
- // Keep ref in sync with onFetch
4425
4287
  useEffect(function () {
4426
- onFetchRef.current = onFetch;
4427
- }, [onFetch]);
4428
-
4429
- // Track mount status
4430
- useEffect(function () {
4431
- isMountedRef.current = true;
4432
- return function () {
4433
- isMountedRef.current = false;
4434
- isFetchingRef.current = false;
4435
- };
4436
- }, []);
4437
-
4438
- // Serialize fetch params for comparison - serialize filters to avoid object reference issues
4439
- var fetchParams = useMemo(function () {
4440
- return {
4288
+ if (!onFetch) return;
4289
+ onFetch({
4290
+ setData: function setData(rows) {
4291
+ return setTableData(Array.isArray(rows) ? rows : []);
4292
+ },
4293
+ setLoading: setLoading,
4441
4294
  filters: filters,
4442
4295
  page: currentPage,
4443
4296
  limit: limit,
4444
- sortKey: sortConfig.key,
4445
- sortDirection: sortConfig.direction
4446
- };
4447
- }, [filters, currentPage, limit, sortConfig.key, sortConfig.direction]);
4448
- var fetchParamsString = useMemo(function () {
4449
- return JSON.stringify(fetchParams);
4450
- }, [fetchParams]);
4451
-
4452
- // Consolidated data sync effect
4297
+ sort: sortConfig
4298
+ });
4299
+ }, [onFetch, filters, currentPage, limit, sortConfig]);
4453
4300
  useEffect(function () {
4454
- var currentOnFetch = onFetchRef.current;
4455
- if (currentOnFetch) {
4456
- // Only fetch if params actually changed and not already fetching
4457
- if (!isFetchingRef.current && prevFetchParamsRef.current !== fetchParamsString) {
4458
- prevFetchParamsRef.current = fetchParamsString;
4459
- isFetchingRef.current = true;
4460
-
4461
- // Track fetch ID to prevent race conditions
4462
- var fetchId = Date.now();
4463
- activeFetchIdRef.current = fetchId;
4464
- try {
4465
- var result = currentOnFetch({
4466
- setData: function setData(rows) {
4467
- // Only update if component is still mounted and this is the active fetch
4468
- if (isMountedRef.current && activeFetchIdRef.current === fetchId) {
4469
- setTableData(Array.isArray(rows) ? rows : []);
4470
- // Don't set isFetchingRef to false here - let setLoading handle it
4471
- }
4472
- },
4473
- setLoading: function setLoading(loading) {
4474
- // Only update if component is still mounted and this is the active fetch
4475
- if (isMountedRef.current && activeFetchIdRef.current === fetchId) {
4476
- _setLoading(loading);
4477
- if (!loading) {
4478
- isFetchingRef.current = false;
4479
- }
4480
- }
4481
- },
4482
- filters: fetchParams.filters,
4483
- page: fetchParams.page,
4484
- limit: fetchParams.limit,
4485
- sort: {
4486
- key: fetchParams.sortKey,
4487
- direction: fetchParams.sortDirection
4488
- }
4489
- });
4490
-
4491
- // Handle promise if onFetch returns one
4492
- if (result && typeof result.then === "function") {
4493
- result["catch"](function (error) {
4494
- console.error("Table onFetch error:", error);
4495
- if (isMountedRef.current && activeFetchIdRef.current === fetchId) {
4496
- _setLoading(false);
4497
- isFetchingRef.current = false;
4498
- }
4499
- });
4500
- }
4501
- } catch (error) {
4502
- console.error("Table onFetch error:", error);
4503
- if (isMountedRef.current && activeFetchIdRef.current === fetchId) {
4504
- _setLoading(false);
4505
- isFetchingRef.current = false;
4506
- }
4507
- }
4508
- }
4509
- } else if (!serverSide && Array.isArray(data)) {
4510
- setTableData(data);
4511
- }
4512
- }, [serverSide, data, fetchParamsString]);
4301
+ if (!serverSide) setTableData(data);
4302
+ }, [data, serverSide]);
4303
+ useEffect(function () {
4304
+ if (!onFetch && isValidList(data)) setTableData(data);
4305
+ }, [data, onFetch]);
4513
4306
 
4514
4307
  // Global search
4515
4308
  useEffect(function () {
4516
4309
  setSearchInput(filters.global || "");
4517
4310
  }, [filters.global]);
4518
- var applyGlobalSearch = useCallback(function () {
4311
+ var applyGlobalSearch = function applyGlobalSearch() {
4519
4312
  handleFilter("global", searchInput);
4520
- }, [handleFilter, searchInput]);
4521
- var onGlobalKeyDown = useCallback(function (e) {
4313
+ };
4314
+ var onGlobalKeyDown = function onGlobalKeyDown(e) {
4522
4315
  if (e.key === "Enter") {
4523
4316
  e.preventDefault();
4524
4317
  applyGlobalSearch();
4525
4318
  }
4526
- }, [applyGlobalSearch]);
4527
- var handleLimitChange = useCallback(function (nextLimit) {
4319
+ };
4320
+ var handleLimitChange = function handleLimitChange(nextLimit) {
4528
4321
  var parsed = Number(nextLimit);
4529
4322
  if (!Number.isFinite(parsed) || parsed <= 0) return;
4530
4323
  setLimit(parsed);
4531
- handlePageChange(1);
4324
+ setCurrentPage(1);
4532
4325
  onLimitChange === null || onLimitChange === void 0 || onLimitChange(parsed);
4533
- }, [onLimitChange, handlePageChange]);
4534
-
4535
- // Memoize limit options
4536
- var limitOptionsMemo = useMemo(function () {
4537
- var opts = Array.isArray(limitOptions) && limitOptions.length > 0 ? limitOptions : [25, 50, 100];
4538
- return opts.map(function (opt) {
4539
- return {
4540
- label: String(opt),
4541
- value: opt
4542
- };
4543
- });
4544
- }, [limitOptions]);
4326
+ };
4545
4327
 
4546
- // Extract row metadata computation
4547
- var getRowMetadata = useCallback(function (row, rowIndexInPage) {
4328
+ // Render mobile card
4329
+ var renderMobileCard = function renderMobileCard(row, rowIndexInPage) {
4548
4330
  var globalIndex = startIndex + rowIndexInPage;
4549
4331
  var key = getRowKey(row, globalIndex);
4550
4332
  var actionCellKey = "actions-".concat(key);
4551
- var extraRowClass = typeof rowClass === "function" ? (rowClass({
4333
+ var extraRowClass = typeof rowClass === "function" ? rowClass({
4552
4334
  row: row,
4553
4335
  rowIndex: globalIndex
4554
- }) || "").trim() : "";
4336
+ }) : "";
4337
+ var safeExtraRowClass = typeof extraRowClass === "string" ? extraRowClass.trim() : "";
4555
4338
  var stripeBg = stripedRows && !selectedRows.has(key) ? stripedColors[globalIndex % stripedColors.length] : undefined;
4556
- return {
4557
- globalIndex: globalIndex,
4558
- key: key,
4559
- actionCellKey: actionCellKey,
4560
- extraRowClass: extraRowClass,
4561
- stripeBg: stripeBg
4562
- };
4563
- }, [startIndex, rowClass, stripedRows, selectedRows, stripedColors]);
4564
-
4565
- // Render mobile card
4566
- var renderMobileCard = useCallback(function (row, rowIndexInPage) {
4567
- var _getRowMetadata = getRowMetadata(row, rowIndexInPage),
4568
- globalIndex = _getRowMetadata.globalIndex,
4569
- key = _getRowMetadata.key,
4570
- actionCellKey = _getRowMetadata.actionCellKey,
4571
- extraRowClass = _getRowMetadata.extraRowClass,
4572
- stripeBg = _getRowMetadata.stripeBg;
4573
4339
  return /*#__PURE__*/React__default.createElement("div", {
4574
4340
  key: key,
4575
4341
  style: stripeBg ? {
@@ -4579,7 +4345,7 @@ var Table = function Table(_ref) {
4579
4345
  "cursor-pointer": !!onRowClick,
4580
4346
  "bg-primary-50 border-primary-200": selectedRows.has(key),
4581
4347
  "hover:shadow-md": !selectedRows.has(key)
4582
- }, extraRowClass),
4348
+ }, safeExtraRowClass),
4583
4349
  onClick: function onClick() {
4584
4350
  return onRowClick === null || onRowClick === void 0 ? void 0 : onRowClick(row, globalIndex);
4585
4351
  }
@@ -4636,15 +4402,16 @@ var Table = function Table(_ref) {
4636
4402
  }), document.body))), /*#__PURE__*/React__default.createElement("div", {
4637
4403
  className: "p-4"
4638
4404
  }, visibleColumns.map(function (column, colIndex) {
4639
- var extraCellClass = typeof cellClass === "function" ? (cellClass({
4405
+ var extraCellClass = typeof cellClass === "function" ? cellClass({
4640
4406
  row: row,
4641
4407
  rowIndex: globalIndex,
4642
4408
  column: column,
4643
4409
  columnIndex: colIndex
4644
- }) || "").trim() : "";
4410
+ }) : "";
4411
+ var safeExtraCellClass = typeof extraCellClass === "string" ? extraCellClass.trim() : "";
4645
4412
  return /*#__PURE__*/React__default.createElement("div", {
4646
4413
  key: column.key,
4647
- className: cn$1("flex justify-between items-center flex-row py-2 border-b last:border-b-0", extraCellClass)
4414
+ className: cn$1("flex justify-between items-center flex-row py-2 border-b last:border-b-0", safeExtraCellClass)
4648
4415
  }, /*#__PURE__*/React__default.createElement("div", {
4649
4416
  className: "text-xs font-medium text-gray-500 uppercase tracking-wide mb-1 sm:mb-0 sm:w-1/3 sm:pr-2"
4650
4417
  }, column.label), /*#__PURE__*/React__default.createElement("div", {
@@ -4656,10 +4423,10 @@ var Table = function Table(_ref) {
4656
4423
  row: row,
4657
4424
  index: globalIndex
4658
4425
  })));
4659
- }, [getRowMetadata, hasDetails, selectable, showSerial, withAction, expandedRows, selectedRows, onRowClick, visibleColumns, renderCell, cellClass, DetailsComponent, actionsToUse, actionAnchor, openActionKey, handleOnAction, actionMenuRef, toggleActions, toggleExpandRow, handleSelectRow]);
4426
+ };
4660
4427
 
4661
4428
  // Render mobile filters
4662
- var renderMobileFilters = useCallback(function () {
4429
+ var renderMobileFilters = function renderMobileFilters() {
4663
4430
  return /*#__PURE__*/React__default.createElement("div", {
4664
4431
  className: "mb-4 p-3 bg-gray-50 rounded-lg"
4665
4432
  }, /*#__PURE__*/React__default.createElement("div", {
@@ -4701,7 +4468,7 @@ var Table = function Table(_ref) {
4701
4468
  }
4702
4469
  }));
4703
4470
  })));
4704
- }, [showMobileFilters, globalSearch, searchInput, onGlobalKeyDown, filterable, visibleColumns, filters, handleFilter, setShowMobileFilters, setSearchInput]);
4471
+ };
4705
4472
 
4706
4473
  // Render
4707
4474
  return /*#__PURE__*/React__default.createElement("div", {
@@ -4724,11 +4491,23 @@ var Table = function Table(_ref) {
4724
4491
  htmlFor: "pagination-limit",
4725
4492
  className: "text-sm text-gray-600 whitespace-nowrap"
4726
4493
  }, "Show"), /*#__PURE__*/React__default.createElement(Select, {
4727
- options: limitOptionsMemo,
4494
+ options: Array.isArray(limitOptions) && limitOptions.length > 0 ? limitOptions.map(function (opt) {
4495
+ return {
4496
+ label: String(opt),
4497
+ value: opt
4498
+ };
4499
+ }) : [25, 50, 100].map(function (opt) {
4500
+ return {
4501
+ label: String(opt),
4502
+ value: opt
4503
+ };
4504
+ }),
4728
4505
  value: limit,
4729
4506
  allowClear: false,
4730
4507
  placeholder: "",
4731
- onChange: handleLimitChange,
4508
+ onChange: function onChange(e) {
4509
+ return handleLimitChange(e);
4510
+ },
4732
4511
  className: "w-20 md:w-30"
4733
4512
  }), /*#__PURE__*/React__default.createElement("p", {
4734
4513
  className: "text-sm text-gray-600 whitespace-nowrap"
@@ -4744,42 +4523,24 @@ var Table = function Table(_ref) {
4744
4523
  className: "rounded-lg md:rounded-md border border-gray-300 p-2 disabled:opacity-50 hover:bg-gray-50",
4745
4524
  disabled: currentPage === 1,
4746
4525
  onClick: function onClick() {
4747
- return handlePageChange(1);
4748
- },
4749
- "aria-label": "First page",
4750
- title: "First page"
4751
- }, /*#__PURE__*/React__default.createElement(ChevronsLeft, {
4752
- className: "size-4 md:size-5 text-gray-800"
4753
- })), /*#__PURE__*/React__default.createElement("button", {
4754
- className: "rounded-lg md:rounded-md border border-gray-300 p-2 disabled:opacity-50 hover:bg-gray-50",
4755
- disabled: currentPage === 1,
4756
- onClick: function onClick() {
4757
- return handlePageChange(Math.max(1, currentPage - 1));
4526
+ return setCurrentPage(function (p) {
4527
+ return Math.max(1, p - 1);
4528
+ });
4758
4529
  },
4759
- "aria-label": "Previous page",
4760
- title: "Previous page"
4530
+ "aria-label": "Previous page"
4761
4531
  }, /*#__PURE__*/React__default.createElement(ChevronLeft, {
4762
4532
  className: "size-4 md:size-5 text-gray-800"
4763
4533
  })), /*#__PURE__*/React__default.createElement("button", {
4764
4534
  className: "rounded-lg md:rounded-md border border-gray-300 p-2 disabled:opacity-50 hover:bg-gray-50",
4765
4535
  disabled: currentPage === totalPages,
4766
4536
  onClick: function onClick() {
4767
- return handlePageChange(Math.min(totalPages, currentPage + 1));
4537
+ return setCurrentPage(function (p) {
4538
+ return Math.min(totalPages, p + 1);
4539
+ });
4768
4540
  },
4769
- "aria-label": "Next page",
4770
- title: "Next page"
4541
+ "aria-label": "Next page"
4771
4542
  }, /*#__PURE__*/React__default.createElement(ChevronRight, {
4772
4543
  className: "size-4 md:size-5 text-gray-800"
4773
- })), /*#__PURE__*/React__default.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 === totalPages,
4776
- onClick: function onClick() {
4777
- return handlePageChange(totalPages);
4778
- },
4779
- "aria-label": "Last page",
4780
- title: "Last page"
4781
- }, /*#__PURE__*/React__default.createElement(ChevronsRight, {
4782
- className: "size-4 md:size-5 text-gray-800"
4783
4544
  })))))), globalSearch && /*#__PURE__*/React__default.createElement("div", {
4784
4545
  className: "p-4 border-b"
4785
4546
  }, /*#__PURE__*/React__default.createElement("div", {
@@ -4918,16 +4679,33 @@ var Table = function Table(_ref) {
4918
4679
  }, loading ? /*#__PURE__*/React__default.createElement("tr", null, /*#__PURE__*/React__default.createElement("td", {
4919
4680
  colSpan: visibleCount,
4920
4681
  className: "px-6 py-8 text-center"
4921
- }, /*#__PURE__*/React__default.createElement(LoadingState, null))) : paginatedData.length === 0 ? /*#__PURE__*/React__default.createElement("tr", null, /*#__PURE__*/React__default.createElement("td", {
4682
+ }, /*#__PURE__*/React__default.createElement("div", {
4683
+ className: "flex flex-col items-center gap-2"
4684
+ }, /*#__PURE__*/React__default.createElement("div", {
4685
+ className: "h-6 w-6 animate-spin rounded-full border-2 border-primary-600 border-t-transparent"
4686
+ }), /*#__PURE__*/React__default.createElement("span", {
4687
+ className: "text-sm text-gray-500"
4688
+ }, "Loading...")))) : paginatedData.length === 0 ? /*#__PURE__*/React__default.createElement("tr", null, /*#__PURE__*/React__default.createElement("td", {
4922
4689
  colSpan: visibleCount,
4923
4690
  className: "px-6 py-8 text-center"
4924
- }, /*#__PURE__*/React__default.createElement(EmptyState, null))) : paginatedData.map(function (row, rowIndexInPage) {
4925
- var _getRowMetadata2 = getRowMetadata(row, rowIndexInPage),
4926
- globalIndex = _getRowMetadata2.globalIndex,
4927
- key = _getRowMetadata2.key,
4928
- actionCellKey = _getRowMetadata2.actionCellKey,
4929
- extraRowClass = _getRowMetadata2.extraRowClass,
4930
- stripeBg = _getRowMetadata2.stripeBg;
4691
+ }, /*#__PURE__*/React__default.createElement("div", {
4692
+ className: "flex flex-col items-center gap-2"
4693
+ }, /*#__PURE__*/React__default.createElement("div", {
4694
+ className: "text-gray-400"
4695
+ }, /*#__PURE__*/React__default.createElement(List, {
4696
+ className: "h-8 w-8"
4697
+ })), /*#__PURE__*/React__default.createElement("span", {
4698
+ className: "text-sm text-gray-500"
4699
+ }, "No results found.")))) : paginatedData.map(function (row, rowIndexInPage) {
4700
+ var globalIndex = startIndex + rowIndexInPage;
4701
+ var key = getRowKey(row, globalIndex);
4702
+ var actionCellKey = "actions-".concat(key);
4703
+ var extraRowClass = typeof rowClass === "function" ? rowClass({
4704
+ row: row,
4705
+ rowIndex: globalIndex
4706
+ }) : "";
4707
+ var safeExtraRowClass = typeof extraRowClass === "string" ? extraRowClass.trim() : "";
4708
+ var stripeBg = stripedRows && !selectedRows.has(key) ? stripedColors[globalIndex % stripedColors.length] : undefined;
4931
4709
  return /*#__PURE__*/React__default.createElement(React__default.Fragment, {
4932
4710
  key: key
4933
4711
  }, /*#__PURE__*/React__default.createElement("tr", {
@@ -4937,7 +4715,7 @@ var Table = function Table(_ref) {
4937
4715
  className: cn$1("hover:bg-gray-50", {
4938
4716
  "cursor-pointer": !!onRowClick,
4939
4717
  "bg-primary-50": selectedRows.has(key)
4940
- }, extraRowClass),
4718
+ }, safeExtraRowClass),
4941
4719
  onClick: function onClick() {
4942
4720
  return onRowClick === null || onRowClick === void 0 ? void 0 : onRowClick(row, globalIndex);
4943
4721
  }
@@ -4965,15 +4743,16 @@ var Table = function Table(_ref) {
4965
4743
  return handleSelectRow(row, rowIndexInPage);
4966
4744
  }
4967
4745
  })), visibleColumns.map(function (column, columnIndex) {
4968
- var extraCellClass = typeof cellClass === "function" ? (cellClass({
4746
+ var extraCellClass = typeof cellClass === "function" ? cellClass({
4969
4747
  row: row,
4970
4748
  rowIndex: globalIndex,
4971
4749
  column: column,
4972
4750
  columnIndex: columnIndex
4973
- }) || "").trim() : "";
4751
+ }) : "";
4752
+ var safeExtraCellClass = typeof extraCellClass === "string" ? extraCellClass.trim() : "";
4974
4753
  return /*#__PURE__*/React__default.createElement("td", {
4975
4754
  key: column.key,
4976
- className: cn$1("px-6 py-4 whitespace-nowrap text-sm text-gray-900", extraCellClass)
4755
+ className: cn$1("px-6 py-4 whitespace-nowrap text-sm text-gray-900", safeExtraCellClass)
4977
4756
  }, renderCell(column, row, globalIndex));
4978
4757
  }), withAction && /*#__PURE__*/React__default.createElement("td", {
4979
4758
  className: "px-4 py-4 text-sm text-right",
@@ -5016,9 +4795,23 @@ var Table = function Table(_ref) {
5016
4795
  className: "p-4"
5017
4796
  }, loading ? /*#__PURE__*/React__default.createElement("div", {
5018
4797
  className: "py-8 text-center"
5019
- }, /*#__PURE__*/React__default.createElement(LoadingState, null)) : paginatedData.length === 0 ? /*#__PURE__*/React__default.createElement("div", {
4798
+ }, /*#__PURE__*/React__default.createElement("div", {
4799
+ className: "flex flex-col items-center gap-2"
4800
+ }, /*#__PURE__*/React__default.createElement("div", {
4801
+ className: "h-6 w-6 animate-spin rounded-full border-2 border-primary-600 border-t-transparent"
4802
+ }), /*#__PURE__*/React__default.createElement("span", {
4803
+ className: "text-sm text-gray-500"
4804
+ }, "Loading..."))) : paginatedData.length === 0 ? /*#__PURE__*/React__default.createElement("div", {
5020
4805
  className: "py-8 text-center"
5021
- }, /*#__PURE__*/React__default.createElement(EmptyState, null)) : paginatedData.map(function (row, rowIndexInPage) {
4806
+ }, /*#__PURE__*/React__default.createElement("div", {
4807
+ className: "flex flex-col items-center gap-2"
4808
+ }, /*#__PURE__*/React__default.createElement("div", {
4809
+ className: "text-gray-400"
4810
+ }, /*#__PURE__*/React__default.createElement(List, {
4811
+ className: "h-8 w-8"
4812
+ })), /*#__PURE__*/React__default.createElement("span", {
4813
+ className: "text-sm text-gray-500"
4814
+ }, "No results found."))) : paginatedData.map(function (row, rowIndexInPage) {
5022
4815
  return renderMobileCard(row, rowIndexInPage);
5023
4816
  })), pagination && /*#__PURE__*/React__default.createElement("div", {
5024
4817
  className: "p-4 border-t"
@@ -5029,25 +4822,28 @@ var Table = function Table(_ref) {
5029
4822
  }, "Page ", currentPage, " of ", totalPages), /*#__PURE__*/React__default.createElement("div", {
5030
4823
  className: "flex items-center gap-2"
5031
4824
  }, /*#__PURE__*/React__default.createElement("button", {
5032
- 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",
5033
- disabled: currentPage === 1,
5034
- onClick: function onClick() {
5035
- return handlePageChange(1);
5036
- },
5037
- title: "First page"
5038
- }, /*#__PURE__*/React__default.createElement(ChevronsLeft, {
5039
- className: "size-4"
5040
- }), /*#__PURE__*/React__default.createElement("span", {
5041
- className: "hidden sm:inline"
5042
- }, "First")), /*#__PURE__*/React__default.createElement("button", {
5043
4825
  className: "rounded-lg md:rounded-md border border-gray-300 px-4 py-2 text-sm disabled:opacity-50 hover:bg-gray-50",
5044
4826
  disabled: currentPage === 1,
5045
4827
  onClick: function onClick() {
5046
- return handlePageChange(Math.max(1, currentPage - 1));
4828
+ return setCurrentPage(function (p) {
4829
+ return Math.max(1, p - 1);
4830
+ });
5047
4831
  }
5048
4832
  }, "Previous"), /*#__PURE__*/React__default.createElement("div", {
5049
4833
  className: "flex items-center gap-1"
5050
- }, getPaginationNumbers(currentPage, totalPages).map(function (pageNum) {
4834
+ }, Array.from({
4835
+ length: Math.min(5, totalPages)
4836
+ }, function (_, i) {
4837
+ var pageNum;
4838
+ if (totalPages <= 5) {
4839
+ pageNum = i + 1;
4840
+ } else if (currentPage <= 3) {
4841
+ pageNum = i + 1;
4842
+ } else if (currentPage >= totalPages - 2) {
4843
+ pageNum = totalPages - 4 + i;
4844
+ } else {
4845
+ pageNum = currentPage - 2 + i;
4846
+ }
5051
4847
  return /*#__PURE__*/React__default.createElement("button", {
5052
4848
  key: pageNum,
5053
4849
  className: cn$1("h-8 w-8 rounded-lg md:rounded-md text-sm", {
@@ -5055,34 +4851,19 @@ var Table = function Table(_ref) {
5055
4851
  "border border-gray-300 hover:bg-gray-50": pageNum !== currentPage
5056
4852
  }),
5057
4853
  onClick: function onClick() {
5058
- return handlePageChange(pageNum);
4854
+ return setCurrentPage(pageNum);
5059
4855
  }
5060
4856
  }, pageNum);
5061
4857
  })), /*#__PURE__*/React__default.createElement("button", {
5062
4858
  className: "rounded-lg md:rounded-md border border-gray-300 px-4 py-2 text-sm disabled:opacity-50 hover:bg-gray-50",
5063
4859
  disabled: currentPage === totalPages,
5064
4860
  onClick: function onClick() {
5065
- return handlePageChange(Math.min(totalPages, currentPage + 1));
4861
+ return setCurrentPage(function (p) {
4862
+ return Math.min(totalPages, p + 1);
4863
+ });
5066
4864
  }
5067
- }, "Next"), /*#__PURE__*/React__default.createElement("button", {
5068
- 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",
5069
- disabled: currentPage === totalPages,
5070
- onClick: function onClick() {
5071
- return handlePageChange(totalPages);
5072
- },
5073
- title: "Last page"
5074
- }, /*#__PURE__*/React__default.createElement("span", {
5075
- className: "hidden sm:inline"
5076
- }, "Last"), /*#__PURE__*/React__default.createElement(ChevronsRight, {
5077
- className: "size-4"
5078
- }))))));
4865
+ }, "Next")))));
5079
4866
  };
5080
-
5081
- // ActionMenuPortal constants
5082
- var MENU_WIDTH = 180;
5083
- var MAX_MENU_HEIGHT = 320;
5084
- var MENU_MARGIN = 8;
5085
- var MIN_MENU_HEIGHT = 80;
5086
4867
  function ActionMenuPortal(_ref2) {
5087
4868
  var anchorElem = _ref2.anchorElem,
5088
4869
  anchorRow = _ref2.anchorRow,
@@ -5096,12 +4877,16 @@ function ActionMenuPortal(_ref2) {
5096
4877
  top: 0,
5097
4878
  transformOrigin: "top right",
5098
4879
  maxHeight: 300,
5099
- width: MENU_WIDTH,
4880
+ width: 180,
5100
4881
  opacity: 0
5101
4882
  }),
5102
4883
  _useState30 = _slicedToArray(_useState29, 2),
5103
4884
  style = _useState30[0],
5104
4885
  setStyle = _useState30[1];
4886
+ var menuWidth = 180;
4887
+ var maxMenuHeight = 320;
4888
+ var margin = 8;
4889
+ var minMenuHeight = 80;
5105
4890
 
5106
4891
  // compute position using actual menu height (if available) and layout measurements
5107
4892
  var computePosition = function computePosition() {
@@ -5113,17 +4898,17 @@ function ActionMenuPortal(_ref2) {
5113
4898
  var spaceAbove = rect.top;
5114
4899
 
5115
4900
  // allowed max height based on available space
5116
- var allowedMaxHeight = Math.min(MAX_MENU_HEIGHT, Math.max(MIN_MENU_HEIGHT, Math.max(spaceBelow - MENU_MARGIN, spaceAbove - MENU_MARGIN)));
4901
+ var allowedMaxHeight = Math.min(maxMenuHeight, Math.max(minMenuHeight, Math.max(spaceBelow - margin, spaceAbove - margin)));
5117
4902
 
5118
4903
  // choose placement by comparing actual available spaces
5119
4904
  var placement = "bottom";
5120
- if (spaceBelow < MENU_PLACEMENT_THRESHOLD && spaceAbove > spaceBelow) {
4905
+ if (spaceBelow < 160 && spaceAbove > spaceBelow) {
5121
4906
  placement = "top";
5122
4907
  // when placing on top we should cap allowedMaxHeight by spaceAbove
5123
- allowedMaxHeight = Math.min(MAX_MENU_HEIGHT, Math.max(MIN_MENU_HEIGHT, spaceAbove - MENU_MARGIN));
4908
+ allowedMaxHeight = Math.min(maxMenuHeight, Math.max(minMenuHeight, spaceAbove - margin));
5124
4909
  } else {
5125
4910
  // placing bottom: cap by spaceBelow
5126
- allowedMaxHeight = Math.min(MAX_MENU_HEIGHT, Math.max(MIN_MENU_HEIGHT, spaceBelow - MENU_MARGIN));
4911
+ allowedMaxHeight = Math.min(maxMenuHeight, Math.max(minMenuHeight, spaceBelow - margin));
5127
4912
  }
5128
4913
 
5129
4914
  // measure the menu's content height if we can, and compute the actual menu height we'll use.
@@ -5140,23 +4925,23 @@ function ActionMenuPortal(_ref2) {
5140
4925
  var top;
5141
4926
  if (placement === "top") {
5142
4927
  // place menu so its bottom sits just above the anchor (rect.top - margin)
5143
- top = rect.top + scrollY - measuredMenuHeight - MENU_MARGIN;
4928
+ top = rect.top + scrollY - measuredMenuHeight - margin;
5144
4929
  } else {
5145
4930
  // place menu just below the anchor (rect.bottom + margin)
5146
- top = rect.bottom + scrollY + MENU_MARGIN;
4931
+ top = rect.bottom + scrollY + margin;
5147
4932
  }
5148
4933
 
5149
4934
  // clamp top to viewport (so it never goes off-screen)
5150
- var minTop = MENU_MARGIN + scrollY;
5151
- var maxTop = window.innerHeight + scrollY - measuredMenuHeight - MENU_MARGIN;
4935
+ var minTop = margin + scrollY;
4936
+ var maxTop = window.innerHeight + scrollY - measuredMenuHeight - margin;
5152
4937
  if (top < minTop) top = minTop;
5153
4938
  if (top > maxTop) top = maxTop;
5154
4939
 
5155
4940
  // compute left and clamp horizontally
5156
- var left = rect.right + scrollX - MENU_WIDTH;
5157
- if (left < MENU_MARGIN) left = MENU_MARGIN;
5158
- if (left + MENU_WIDTH > window.innerWidth - MENU_MARGIN) {
5159
- left = Math.max(MENU_MARGIN, window.innerWidth - MENU_WIDTH - MENU_MARGIN);
4941
+ var left = rect.right + scrollX - menuWidth;
4942
+ if (left < margin) left = margin;
4943
+ if (left + menuWidth > window.innerWidth - margin) {
4944
+ left = Math.max(margin, window.innerWidth - menuWidth - margin);
5160
4945
  }
5161
4946
  var transformOrigin = placement === "bottom" ? "top right" : "bottom right";
5162
4947
 
@@ -5166,7 +4951,7 @@ function ActionMenuPortal(_ref2) {
5166
4951
  top: top,
5167
4952
  transformOrigin: transformOrigin,
5168
4953
  maxHeight: allowedMaxHeight,
5169
- width: MENU_WIDTH,
4954
+ width: menuWidth,
5170
4955
  opacity: 1
5171
4956
  });
5172
4957
  };
@@ -5189,8 +4974,7 @@ function ActionMenuPortal(_ref2) {
5189
4974
  window.removeEventListener("scroll", onScrollOrResize, true);
5190
4975
  };
5191
4976
  // Recompute when anchor element changes or actions change (content height may change).
5192
- // Note: menuRef is a ref object and never changes, so it's safe to include
5193
- }, [anchorElem, actions]);
4977
+ }, [anchorElem, actions, menuRef]);
5194
4978
  return /*#__PURE__*/createPortal(/*#__PURE__*/React__default.createElement("div", {
5195
4979
  ref: menuRef,
5196
4980
  style: {