@dreamtree-org/twreact-ui 1.0.77 → 1.0.78

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
@@ -3883,279 +3883,372 @@ var Select = /*#__PURE__*/React.forwardRef(function (_ref, forwardedRef) {
3883
3883
  }, error));
3884
3884
  });
3885
3885
 
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"];
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"];
3887
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; }
3888
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; }
3889
- var Table = function Table(_ref) {
3890
- var _ref$data = _ref.data,
3891
- data = _ref$data === void 0 ? [] : _ref$data,
3892
- _ref$columns = _ref.columns,
3893
- columns = _ref$columns === void 0 ? [] : _ref$columns,
3894
- _ref$sortable = _ref.sortable,
3895
- sortable = _ref$sortable === void 0 ? true : _ref$sortable,
3896
- _ref$filterable = _ref.filterable,
3897
- filterable = _ref$filterable === void 0 ? false : _ref$filterable,
3898
- _ref$selectable = _ref.selectable,
3899
- selectable = _ref$selectable === void 0 ? false : _ref$selectable,
3900
- _ref$pagination = _ref.pagination,
3901
- pagination = _ref$pagination === void 0 ? false : _ref$pagination,
3902
- _ref$pageSize = _ref.pageSize,
3903
- pageSize = _ref$pageSize === void 0 ? 25 : _ref$pageSize,
3904
- onSort = _ref.onSort,
3905
- onFilter = _ref.onFilter,
3906
- onFetch = _ref.onFetch,
3907
- onFilterChange = _ref.onFilterChange,
3908
- onSelectionChange = _ref.onSelectionChange,
3909
- onRowClick = _ref.onRowClick,
3910
- _ref$hasDetails = _ref.hasDetails,
3911
- hasDetails = _ref$hasDetails === void 0 ? false : _ref$hasDetails,
3912
- _ref$DetailsComponent = _ref.DetailsComponent,
3913
- DetailsComponent = _ref$DetailsComponent === void 0 ? null : _ref$DetailsComponent,
3914
- className = _ref.className,
3915
- _ref$withAction = _ref.withAction,
3916
- withAction = _ref$withAction === void 0 ? true : _ref$withAction,
3889
+
3890
+ // Move static default actions outside component to prevent recreation
3891
+ var DEFAULT_ACTIONS = [{
3892
+ name: "edit",
3893
+ label: "Edit",
3894
+ onClick: function onClick() {
3895
+ return console.log("Edit action clicked");
3896
+ },
3897
+ icon: /*#__PURE__*/React.createElement(PenSquare, {
3898
+ size: 16
3899
+ })
3900
+ }, {
3901
+ name: "delete",
3902
+ label: "Delete",
3903
+ onClick: function onClick() {
3904
+ return console.log("Delete action clicked");
3905
+ },
3906
+ icon: /*#__PURE__*/React.createElement(Trash, {
3907
+ size: 16
3908
+ })
3909
+ }, {
3910
+ name: "view",
3911
+ label: "View",
3912
+ onClick: function onClick() {
3913
+ return console.log("View action clicked");
3914
+ },
3915
+ icon: /*#__PURE__*/React.createElement(Eye, {
3916
+ size: 16
3917
+ })
3918
+ }];
3919
+
3920
+ // Memoized ActionMenuPortal to prevent unnecessary re-renders
3921
+ var ActionMenuPortal = /*#__PURE__*/React.memo(function ActionMenuPortal(_ref) {
3922
+ var anchorElem = _ref.anchorElem,
3923
+ _ref$actions = _ref.actions,
3924
+ actions = _ref$actions === void 0 ? [] : _ref$actions,
3925
+ anchorRow = _ref.anchorRow,
3917
3926
  onAction = _ref.onAction,
3918
- actions = _ref.actions,
3919
- _ref$showSerial = _ref.showSerial,
3920
- showSerial = _ref$showSerial === void 0 ? true : _ref$showSerial,
3921
- cellClass = _ref.cellClass,
3922
- rowClass = _ref.rowClass,
3923
- _ref$globalSearch = _ref.globalSearch,
3924
- globalSearch = _ref$globalSearch === void 0 ? false : _ref$globalSearch,
3925
- _ref$limitOptions = _ref.limitOptions,
3926
- limitOptions = _ref$limitOptions === void 0 ? [10, 25, 50, 100] : _ref$limitOptions,
3927
- _ref$showLimitSelecto = _ref.showLimitSelector,
3928
- showLimitSelector = _ref$showLimitSelecto === void 0 ? true : _ref$showLimitSelecto,
3929
- onLimitChange = _ref.onLimitChange,
3930
- _ref$showReloadButton = _ref.showReloadButton,
3931
- showReloadButton = _ref$showReloadButton === void 0 ? true : _ref$showReloadButton,
3932
- renderReloadButton = _ref.renderReloadButton,
3933
- onReload = _ref.onReload,
3934
- _ref$stripedRows = _ref.stripedRows,
3935
- stripedRows = _ref$stripedRows === void 0 ? true : _ref$stripedRows,
3936
- _ref$stripedColors = _ref.stripedColors,
3937
- stripedColors = _ref$stripedColors === void 0 ? ["#ffffff", "#f7fafc"] : _ref$stripedColors,
3938
- _ref$responsiveBreakp = _ref.responsiveBreakpoint,
3939
- responsiveBreakpoint = _ref$responsiveBreakp === void 0 ? 768 : _ref$responsiveBreakp,
3940
- _ref$serverSide = _ref.serverSide,
3941
- serverSide = _ref$serverSide === void 0 ? false : _ref$serverSide,
3942
- _ref$totalRecords = _ref.totalRecords,
3943
- totalRecords = _ref$totalRecords === void 0 ? 0 : _ref$totalRecords,
3944
- pageNumber = _ref.pageNumber;
3945
- _ref.onPageChange;
3946
- var props = _objectWithoutProperties$1(_ref, _excluded$k);
3947
- // State for responsive view
3948
- var _useState = React.useState(false),
3927
+ menuRef = _ref.menuRef;
3928
+ var _useState = React.useState({
3929
+ left: 0,
3930
+ top: 0,
3931
+ transformOrigin: "top right",
3932
+ maxHeight: 300,
3933
+ width: 180,
3934
+ opacity: 0
3935
+ }),
3949
3936
  _useState2 = _slicedToArray(_useState, 2),
3950
- isMobileView = _useState2[0],
3951
- setIsMobileView = _useState2[1];
3937
+ style = _useState2[0],
3938
+ setStyle = _useState2[1];
3939
+ var menuWidth = 180;
3940
+ var maxMenuHeight = 320;
3941
+ var margin = 8;
3942
+ var minMenuHeight = 80;
3943
+ React.useLayoutEffect(function () {
3944
+ if (!anchorElem) return;
3945
+ var computePosition = function computePosition() {
3946
+ var rect = anchorElem.getBoundingClientRect();
3947
+ var scrollY = window.scrollY || window.pageYOffset;
3948
+ var scrollX = window.scrollX || window.pageXOffset;
3949
+ var spaceBelow = window.innerHeight - rect.bottom;
3950
+ var spaceAbove = rect.top;
3951
+ var placement = "bottom";
3952
+ var allowedMaxHeight;
3953
+ if (spaceBelow < 160 && spaceAbove > spaceBelow) {
3954
+ placement = "top";
3955
+ allowedMaxHeight = Math.min(maxMenuHeight, Math.max(minMenuHeight, spaceAbove - margin));
3956
+ } else {
3957
+ allowedMaxHeight = Math.min(maxMenuHeight, Math.max(minMenuHeight, spaceBelow - margin));
3958
+ }
3959
+ var measuredMenuHeight = allowedMaxHeight;
3960
+ var menuEl = menuRef === null || menuRef === void 0 ? void 0 : menuRef.current;
3961
+ if (menuEl) {
3962
+ var contentHeight = menuEl.scrollHeight || menuEl.offsetHeight || allowedMaxHeight;
3963
+ measuredMenuHeight = Math.min(contentHeight, allowedMaxHeight);
3964
+ }
3965
+ var top = placement === "top" ? rect.top + scrollY - measuredMenuHeight - margin : rect.bottom + scrollY + margin;
3966
+ var minTop = margin + scrollY;
3967
+ var maxTop = window.innerHeight + scrollY - measuredMenuHeight - margin;
3968
+ top = Math.max(minTop, Math.min(top, maxTop));
3969
+ var left = rect.right + scrollX - menuWidth;
3970
+ left = Math.max(margin, Math.min(left, window.innerWidth - menuWidth - margin));
3971
+ setStyle({
3972
+ left: left,
3973
+ top: top,
3974
+ transformOrigin: placement === "bottom" ? "top right" : "bottom right",
3975
+ maxHeight: allowedMaxHeight,
3976
+ width: menuWidth,
3977
+ opacity: 1
3978
+ });
3979
+ };
3980
+ computePosition();
3981
+ var onScrollOrResize = function onScrollOrResize() {
3982
+ window.requestAnimationFrame(computePosition);
3983
+ };
3984
+ window.addEventListener("resize", onScrollOrResize);
3985
+ window.addEventListener("scroll", onScrollOrResize, true);
3986
+ return function () {
3987
+ window.removeEventListener("resize", onScrollOrResize);
3988
+ window.removeEventListener("scroll", onScrollOrResize, true);
3989
+ };
3990
+ }, [anchorElem, menuRef]);
3991
+ return /*#__PURE__*/React.createElement("div", {
3992
+ ref: menuRef,
3993
+ style: {
3994
+ position: "absolute",
3995
+ top: style.top,
3996
+ left: style.left,
3997
+ width: style.width,
3998
+ maxHeight: style.maxHeight,
3999
+ transformOrigin: style.transformOrigin,
4000
+ opacity: style.opacity
4001
+ },
4002
+ className: "absolute z-50 bg-white rounded-lg shadow-lg ring-1 ring-black ring-opacity-5 overflow-y-auto transition-opacity duration-150 ease-out",
4003
+ onClick: function onClick(e) {
4004
+ return e.stopPropagation();
4005
+ }
4006
+ }, /*#__PURE__*/React.createElement("div", {
4007
+ className: "p-1"
4008
+ }, actions.length === 0 ? /*#__PURE__*/React.createElement("div", {
4009
+ className: "px-3 py-2 text-sm text-gray-500"
4010
+ }, "No actions") : actions.map(function (action) {
4011
+ return /*#__PURE__*/React.createElement("div", {
4012
+ key: action.name,
4013
+ className: "px-1"
4014
+ }, /*#__PURE__*/React.createElement("button", {
4015
+ className: "w-full text-left px-3 py-2 text-sm hover:bg-gray-100 flex items-center gap-2 rounded-md",
4016
+ onClick: function onClick(e) {
4017
+ e.stopPropagation();
4018
+ onAction === null || onAction === void 0 || onAction(action, anchorRow);
4019
+ }
4020
+ }, action.render ? action.render(anchorRow) : /*#__PURE__*/React.createElement(React.Fragment, null, action.icon && /*#__PURE__*/React.createElement("span", {
4021
+ className: "inline-flex"
4022
+ }, action.icon), /*#__PURE__*/React.createElement("span", null, action.label))));
4023
+ })));
4024
+ });
3952
4025
 
3953
- // Keep original table data / loading
3954
- var _useState3 = React.useState(Array.isArray(data) ? data : []),
4026
+ // Custom hook for click-outside detection (consolidates 3 handlers into 1)
4027
+ function useClickOutside(refs, isActive, onClickOutside) {
4028
+ React.useEffect(function () {
4029
+ if (!isActive) return;
4030
+ var handler = function handler(e) {
4031
+ var isOutside = refs.every(function (ref) {
4032
+ return !ref.current || !ref.current.contains(e.target);
4033
+ });
4034
+ if (isOutside) onClickOutside();
4035
+ };
4036
+ document.addEventListener("click", handler);
4037
+ return function () {
4038
+ return document.removeEventListener("click", handler);
4039
+ };
4040
+ }, [refs, isActive, onClickOutside]);
4041
+ }
4042
+
4043
+ // Helper to get row key - stable function
4044
+ var getRowKey = function getRowKey(row, globalIndex) {
4045
+ if (row == null) return String(globalIndex);
4046
+ if (row.id !== undefined && row.id !== null) return String(row.id);
4047
+ if (row._id !== undefined && row._id !== null) return String(row._id);
4048
+ return String(globalIndex);
4049
+ };
4050
+ var Table = function Table(_ref2) {
4051
+ var _ref2$data = _ref2.data,
4052
+ data = _ref2$data === void 0 ? [] : _ref2$data,
4053
+ _ref2$columns = _ref2.columns,
4054
+ columns = _ref2$columns === void 0 ? [] : _ref2$columns,
4055
+ _ref2$sortable = _ref2.sortable,
4056
+ sortable = _ref2$sortable === void 0 ? true : _ref2$sortable,
4057
+ _ref2$filterable = _ref2.filterable,
4058
+ filterable = _ref2$filterable === void 0 ? false : _ref2$filterable,
4059
+ _ref2$selectable = _ref2.selectable,
4060
+ selectable = _ref2$selectable === void 0 ? false : _ref2$selectable,
4061
+ _ref2$pagination = _ref2.pagination,
4062
+ pagination = _ref2$pagination === void 0 ? false : _ref2$pagination,
4063
+ _ref2$pageSize = _ref2.pageSize,
4064
+ pageSize = _ref2$pageSize === void 0 ? 25 : _ref2$pageSize,
4065
+ onSort = _ref2.onSort,
4066
+ onFilter = _ref2.onFilter,
4067
+ onFetch = _ref2.onFetch,
4068
+ onFilterChange = _ref2.onFilterChange,
4069
+ onSelectionChange = _ref2.onSelectionChange,
4070
+ onRowClick = _ref2.onRowClick,
4071
+ _ref2$hasDetails = _ref2.hasDetails,
4072
+ hasDetails = _ref2$hasDetails === void 0 ? false : _ref2$hasDetails,
4073
+ _ref2$DetailsComponen = _ref2.DetailsComponent,
4074
+ DetailsComponent = _ref2$DetailsComponen === void 0 ? null : _ref2$DetailsComponen,
4075
+ className = _ref2.className,
4076
+ _ref2$withAction = _ref2.withAction,
4077
+ withAction = _ref2$withAction === void 0 ? true : _ref2$withAction,
4078
+ onAction = _ref2.onAction,
4079
+ actions = _ref2.actions,
4080
+ _ref2$showSerial = _ref2.showSerial,
4081
+ showSerial = _ref2$showSerial === void 0 ? true : _ref2$showSerial,
4082
+ cellClass = _ref2.cellClass,
4083
+ rowClass = _ref2.rowClass,
4084
+ _ref2$globalSearch = _ref2.globalSearch,
4085
+ globalSearch = _ref2$globalSearch === void 0 ? false : _ref2$globalSearch,
4086
+ _ref2$limitOptions = _ref2.limitOptions,
4087
+ limitOptions = _ref2$limitOptions === void 0 ? [10, 25, 50, 100] : _ref2$limitOptions,
4088
+ _ref2$showLimitSelect = _ref2.showLimitSelector,
4089
+ showLimitSelector = _ref2$showLimitSelect === void 0 ? true : _ref2$showLimitSelect,
4090
+ onLimitChange = _ref2.onLimitChange,
4091
+ _ref2$showReloadButto = _ref2.showReloadButton,
4092
+ showReloadButton = _ref2$showReloadButto === void 0 ? true : _ref2$showReloadButto,
4093
+ renderReloadButton = _ref2.renderReloadButton,
4094
+ onReload = _ref2.onReload,
4095
+ _ref2$stripedRows = _ref2.stripedRows,
4096
+ stripedRows = _ref2$stripedRows === void 0 ? true : _ref2$stripedRows,
4097
+ _ref2$stripedColors = _ref2.stripedColors,
4098
+ stripedColors = _ref2$stripedColors === void 0 ? ["#ffffff", "#f7fafc"] : _ref2$stripedColors,
4099
+ _ref2$responsiveBreak = _ref2.responsiveBreakpoint,
4100
+ responsiveBreakpoint = _ref2$responsiveBreak === void 0 ? 768 : _ref2$responsiveBreak,
4101
+ _ref2$serverSide = _ref2.serverSide,
4102
+ serverSide = _ref2$serverSide === void 0 ? false : _ref2$serverSide,
4103
+ _ref2$totalRecords = _ref2.totalRecords,
4104
+ totalRecords = _ref2$totalRecords === void 0 ? 0 : _ref2$totalRecords,
4105
+ pageNumber = _ref2.pageNumber,
4106
+ props = _objectWithoutProperties$1(_ref2, _excluded$k);
4107
+ // Core state
4108
+ var _useState3 = React.useState(false),
3955
4109
  _useState4 = _slicedToArray(_useState3, 2),
3956
- tableData = _useState4[0],
3957
- setTableData = _useState4[1];
3958
- var _useState5 = React.useState(false),
4110
+ isMobileView = _useState4[0],
4111
+ setIsMobileView = _useState4[1];
4112
+ var _useState5 = React.useState(function () {
4113
+ return Array.isArray(data) ? data : [];
4114
+ }),
3959
4115
  _useState6 = _slicedToArray(_useState5, 2),
3960
- loading = _useState6[0],
3961
- setLoading = _useState6[1];
4116
+ tableData = _useState6[0],
4117
+ setTableData = _useState6[1];
4118
+ var _useState7 = React.useState(false),
4119
+ _useState8 = _slicedToArray(_useState7, 2),
4120
+ loading = _useState8[0],
4121
+ setLoading = _useState8[1];
4122
+ var _useState9 = React.useState(pageSize),
4123
+ _useState0 = _slicedToArray(_useState9, 2),
4124
+ limit = _useState0[0],
4125
+ setLimit = _useState0[1];
4126
+ var _useState1 = React.useState(function () {
4127
+ return typeof pageNumber === "number" ? pageNumber : 1;
4128
+ }),
4129
+ _useState10 = _slicedToArray(_useState1, 2),
4130
+ currentPage = _useState10[0],
4131
+ setCurrentPage = _useState10[1];
3962
4132
 
3963
- // Column visibility state
3964
- var _useState7 = React.useState(function () {
4133
+ // Column state
4134
+ var _useState11 = React.useState(function () {
3965
4135
  return Array.isArray(columns) ? columns.map(function (c) {
3966
4136
  return _objectSpread$9({}, c);
3967
4137
  }) : [];
3968
4138
  }),
3969
- _useState8 = _slicedToArray(_useState7, 2),
3970
- columnsState = _useState8[0],
3971
- setColumnsState = _useState8[1];
3972
- React.useEffect(function () {
3973
- // Sync when prop changes
3974
- setColumnsState(Array.isArray(columns) ? columns.map(function (c) {
3975
- return _objectSpread$9({}, c);
3976
- }) : []);
3977
- }, [columns]);
3978
-
3979
- // Popover state for column toggler
3980
- var _useState9 = React.useState(false),
3981
- _useState0 = _slicedToArray(_useState9, 2),
3982
- showColumnMenu = _useState0[0],
3983
- setShowColumnMenu = _useState0[1];
3984
- var columnMenuRef = React.useRef(null);
3985
- var columnToggleBtnRef = React.useRef(null);
3986
- var _useState1 = React.useState(pageSize),
3987
- _useState10 = _slicedToArray(_useState1, 2),
3988
- limit = _useState10[0],
3989
- setLimit = _useState10[1];
4139
+ _useState12 = _slicedToArray(_useState11, 2),
4140
+ columnsState = _useState12[0],
4141
+ setColumnsState = _useState12[1];
4142
+ var _useState13 = React.useState(false),
4143
+ _useState14 = _slicedToArray(_useState13, 2),
4144
+ showColumnMenu = _useState14[0],
4145
+ setShowColumnMenu = _useState14[1];
3990
4146
 
3991
- // Other states
3992
- var _useState11 = React.useState({
4147
+ // Sorting/filtering state
4148
+ var _useState15 = React.useState({
3993
4149
  key: null,
3994
4150
  direction: "asc"
3995
4151
  }),
3996
- _useState12 = _slicedToArray(_useState11, 2),
3997
- sortConfig = _useState12[0],
3998
- setSortConfig = _useState12[1];
3999
- var _useState13 = React.useState(new Set()),
4000
- _useState14 = _slicedToArray(_useState13, 2),
4001
- selectedRows = _useState14[0],
4002
- setSelectedRows = _useState14[1];
4003
- var _useState15 = React.useState(new Set()),
4004
4152
  _useState16 = _slicedToArray(_useState15, 2),
4005
- expandedRows = _useState16[0],
4006
- setExpandedRows = _useState16[1];
4007
- var _useState17 = React.useState(typeof pageNumber === "number" ? pageNumber : 1),
4153
+ sortConfig = _useState16[0],
4154
+ setSortConfig = _useState16[1];
4155
+ var _useState17 = React.useState({}),
4008
4156
  _useState18 = _slicedToArray(_useState17, 2),
4009
- currentPage = _useState18[0],
4010
- setCurrentPage = _useState18[1];
4011
- var _useState19 = React.useState({}),
4157
+ filters = _useState18[0],
4158
+ setFilters = _useState18[1];
4159
+ var _useState19 = React.useState(""),
4012
4160
  _useState20 = _slicedToArray(_useState19, 2),
4013
- filters = _useState20[0],
4014
- setFilters = _useState20[1];
4015
- var _useState21 = React.useState(filters.global || ""),
4161
+ searchInput = _useState20[0],
4162
+ setSearchInput = _useState20[1];
4163
+
4164
+ // Selection/expansion state
4165
+ var _useState21 = React.useState(function () {
4166
+ return new Set();
4167
+ }),
4016
4168
  _useState22 = _slicedToArray(_useState21, 2),
4017
- searchInput = _useState22[0],
4018
- setSearchInput = _useState22[1];
4019
- var _useState23 = React.useState(false),
4169
+ selectedRows = _useState22[0],
4170
+ setSelectedRows = _useState22[1];
4171
+ var _useState23 = React.useState(function () {
4172
+ return new Set();
4173
+ }),
4020
4174
  _useState24 = _slicedToArray(_useState23, 2),
4021
- showMobileFilters = _useState24[0],
4022
- setShowMobileFilters = _useState24[1];
4175
+ expandedRows = _useState24[0],
4176
+ setExpandedRows = _useState24[1];
4023
4177
 
4024
- // Popover per-row
4178
+ // Action menu state
4025
4179
  var _useState25 = React.useState(null),
4026
4180
  _useState26 = _slicedToArray(_useState25, 2),
4027
4181
  actionAnchor = _useState26[0],
4028
4182
  setActionAnchor = _useState26[1];
4183
+ var _useState27 = React.useState(false),
4184
+ _useState28 = _slicedToArray(_useState27, 2),
4185
+ showMobileFilters = _useState28[0],
4186
+ setShowMobileFilters = _useState28[1];
4187
+
4188
+ // Refs
4189
+ var columnMenuRef = React.useRef(null);
4190
+ var columnToggleBtnRef = React.useRef(null);
4029
4191
  var actionMenuRef = React.useRef(null);
4030
4192
 
4031
- // Per-row action menu open key
4032
- var _useState27 = React.useState(null),
4033
- _useState28 = _slicedToArray(_useState27, 2),
4034
- openActionKey = _useState28[0],
4035
- setOpenActionKey = _useState28[1];
4036
- var openRef = React.useRef(null);
4193
+ // Actions to use (memoized)
4194
+ var actionsToUse = React.useMemo(function () {
4195
+ return actions !== undefined ? actions : DEFAULT_ACTIONS;
4196
+ }, [actions]);
4197
+
4198
+ // Sync external props
4037
4199
  React.useEffect(function () {
4038
4200
  if (typeof pageNumber === "number" && pageNumber !== currentPage) {
4039
4201
  setCurrentPage(pageNumber);
4040
4202
  }
4041
- }, [pageNumber]);
4203
+ }, [pageNumber]); // eslint-disable-line react-hooks/exhaustive-deps
4204
+
4042
4205
  React.useEffect(function () {
4043
4206
  setLimit(pageSize);
4044
4207
  }, [pageSize]);
4208
+ React.useEffect(function () {
4209
+ setColumnsState(Array.isArray(columns) ? columns.map(function (c) {
4210
+ return _objectSpread$9({}, c);
4211
+ }) : []);
4212
+ }, [columns]);
4045
4213
 
4046
- // Check if mobile view
4214
+ // Single effect for data sync (consolidated from 3 effects)
4215
+ React.useEffect(function () {
4216
+ if (serverSide || onFetch) return;
4217
+ if (Array.isArray(data)) {
4218
+ setTableData(data);
4219
+ }
4220
+ }, [data, serverSide, onFetch]);
4221
+
4222
+ // Mobile view detection
4047
4223
  React.useEffect(function () {
4048
4224
  var checkMobile = function checkMobile() {
4049
- setIsMobileView(window.innerWidth < responsiveBreakpoint);
4225
+ return setIsMobileView(window.innerWidth < responsiveBreakpoint);
4050
4226
  };
4051
-
4052
- // Initial check
4053
4227
  checkMobile();
4054
-
4055
- // Add event listener
4056
4228
  window.addEventListener("resize", checkMobile);
4057
4229
  return function () {
4058
- window.removeEventListener("resize", checkMobile);
4230
+ return window.removeEventListener("resize", checkMobile);
4059
4231
  };
4060
4232
  }, [responsiveBreakpoint]);
4061
- var isValidList = function isValidList(d) {
4062
- return Array.isArray(d);
4063
- };
4064
4233
 
4065
- // Close column menu when clicking outside
4066
- React.useEffect(function () {
4067
- var onDocClick = function onDocClick(e) {
4068
- if (showColumnMenu && columnMenuRef.current && !columnMenuRef.current.contains(e.target) && columnToggleBtnRef.current && !columnToggleBtnRef.current.contains(e.target)) {
4069
- setShowColumnMenu(false);
4070
- }
4071
- };
4072
- document.addEventListener("click", onDocClick);
4073
- return function () {
4074
- return document.removeEventListener("click", onDocClick);
4075
- };
4076
- }, [showColumnMenu]);
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]);
4234
+ // Click-outside handlers (using consolidated hook)
4235
+ var closeColumnMenu = React.useCallback(function () {
4236
+ return setShowColumnMenu(false);
4237
+ }, []);
4238
+ var closeActionMenu = React.useCallback(function () {
4239
+ return setActionAnchor(null);
4240
+ }, []);
4241
+ useClickOutside([columnMenuRef, columnToggleBtnRef], showColumnMenu, closeColumnMenu);
4242
+ useClickOutside([actionMenuRef], !!actionAnchor, closeActionMenu);
4090
4243
 
4091
- // Visible columns derived from columnsState
4244
+ // Visible columns (memoized)
4092
4245
  var visibleColumns = React.useMemo(function () {
4093
4246
  return columnsState.filter(function (col) {
4094
4247
  return col.isVisible !== false;
4095
4248
  });
4096
4249
  }, [columnsState]);
4097
- var toggleColumnVisibility = function toggleColumnVisibility(key) {
4098
- setColumnsState(function (prev) {
4099
- return prev.map(function (c) {
4100
- return c.key === key ? _objectSpread$9(_objectSpread$9({}, c), {}, {
4101
- isVisible: !(c.isVisible !== false)
4102
- }) : c;
4103
- });
4104
- });
4105
- setCurrentPage(1);
4106
- };
4107
4250
 
4108
- // Handle actions
4109
- var handleOnAction = function handleOnAction(action, row) {
4110
- var _action$onClick;
4111
- (_action$onClick = action.onClick) === null || _action$onClick === void 0 || _action$onClick.call(action, {
4112
- action: action,
4113
- row: row
4114
- });
4115
- onAction && onAction({
4116
- action: action,
4117
- row: row
4118
- });
4119
- setOpenActionKey(null);
4120
- setActionAnchor(null);
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
- };
4157
-
4158
- // Sorting
4251
+ // Sorted data (memoized)
4159
4252
  var sortedData = React.useMemo(function () {
4160
4253
  if (serverSide || !sortConfig.key) return tableData;
4161
4254
  var key = sortConfig.key,
@@ -4164,12 +4257,14 @@ var Table = function Table(_ref) {
4164
4257
  var av = a === null || a === void 0 ? void 0 : a[key];
4165
4258
  var bv = b === null || b === void 0 ? void 0 : b[key];
4166
4259
  if (av == null || bv == null) return 0;
4167
- if (typeof av === "number") return direction === "asc" ? av - bv : bv - av;
4260
+ if (typeof av === "number") {
4261
+ return direction === "asc" ? av - bv : bv - av;
4262
+ }
4168
4263
  return direction === "asc" ? String(av).localeCompare(String(bv)) : String(bv).localeCompare(String(av));
4169
4264
  });
4170
4265
  }, [tableData, sortConfig, serverSide]);
4171
4266
 
4172
- // Filtering
4267
+ // Filtered data (memoized)
4173
4268
  var filteredData = React.useMemo(function () {
4174
4269
  if (serverSide || !filterable || !Object.keys(filters).length) return sortedData;
4175
4270
  var q = (filters.global || "").toLowerCase();
@@ -4179,131 +4274,170 @@ var Table = function Table(_ref) {
4179
4274
  });
4180
4275
  });
4181
4276
  }, [sortedData, filters, filterable, serverSide]);
4182
- // Pagination indices
4183
- var startIndex = pagination ? (currentPage - 1) * limit : 0;
4184
- var endIndex = pagination ? startIndex + limit : filteredData.length;
4185
-
4186
- // Paginated view
4187
- var paginatedData = React.useMemo(function () {
4188
- if (!pagination || serverSide) return filteredData;
4189
- var start = (currentPage - 1) * limit;
4190
- return filteredData.slice(start, start + limit);
4191
- }, [filteredData, pagination, serverSide, currentPage, limit]);
4192
- var totalPages = React.useMemo(function () {
4193
- if (!pagination) return 1;
4194
- return serverSide ? Math.max(1, Math.ceil((totalRecords || 0) / limit)) : Math.max(1, Math.ceil(filteredData.length / limit));
4195
- }, [pagination, serverSide, totalRecords, filteredData.length, limit]);
4196
-
4197
- // Sorting handler
4198
- var handleSort = function handleSort(key) {
4199
- if (!sortable) return;
4200
- var direction = sortConfig.key === key && sortConfig.direction === "asc" ? "desc" : "asc";
4201
- setSortConfig({
4202
- key: key,
4203
- direction: direction
4204
- });
4205
- onSort === null || onSort === void 0 || onSort(key, direction);
4206
- };
4207
4277
 
4208
- // Selection handlers
4209
- var handleSelectAll = function handleSelectAll() {
4210
- var newSelection = new Set(selectedRows);
4211
- var pageRowKeys = paginatedData.map(function (r, i) {
4212
- return getRowKey(r, startIndex + i);
4278
+ // Pagination calculations (memoized)
4279
+ var _useMemo = React.useMemo(function () {
4280
+ var start = pagination ? (currentPage - 1) * limit : 0;
4281
+ var end = pagination ? start + limit : filteredData.length;
4282
+ var paginated = !pagination || serverSide ? filteredData : filteredData.slice(start, start + limit);
4283
+ var pages = !pagination ? 1 : serverSide ? Math.max(1, Math.ceil((totalRecords || 0) / limit)) : Math.max(1, Math.ceil(filteredData.length / limit));
4284
+ return {
4285
+ startIndex: start,
4286
+ endIndex: end,
4287
+ paginatedData: paginated,
4288
+ totalPages: pages
4289
+ };
4290
+ }, [filteredData, pagination, serverSide, currentPage, limit, totalRecords]),
4291
+ startIndex = _useMemo.startIndex,
4292
+ endIndex = _useMemo.endIndex,
4293
+ paginatedData = _useMemo.paginatedData,
4294
+ totalPages = _useMemo.totalPages;
4295
+
4296
+ // Column count for colspan (memoized)
4297
+ var visibleCount = React.useMemo(function () {
4298
+ return (showSerial ? 1 : 0) + visibleColumns.length + (selectable ? 1 : 0) + (hasDetails ? 1 : 0) + (withAction ? 1 : 0) + 1;
4299
+ },
4300
+ // column toggler
4301
+ [showSerial, visibleColumns.length, selectable, hasDetails, withAction]);
4302
+
4303
+ // Row key map for selection (memoized per filtered data)
4304
+ var rowKeyMap = React.useMemo(function () {
4305
+ return new Map(filteredData.map(function (r, i) {
4306
+ return [getRowKey(r, i), r];
4307
+ }));
4308
+ }, [filteredData]);
4309
+
4310
+ // Callbacks (memoized to prevent child re-renders)
4311
+ var toggleColumnVisibility = React.useCallback(function (key) {
4312
+ setColumnsState(function (prev) {
4313
+ return prev.map(function (c) {
4314
+ return c.key === key ? _objectSpread$9(_objectSpread$9({}, c), {}, {
4315
+ isVisible: !(c.isVisible !== false)
4316
+ }) : c;
4317
+ });
4318
+ });
4319
+ }, []);
4320
+ var handleSort = React.useCallback(function (key) {
4321
+ if (!sortable) return;
4322
+ setSortConfig(function (prev) {
4323
+ var direction = prev.key === key && prev.direction === "asc" ? "desc" : "asc";
4324
+ onSort === null || onSort === void 0 || onSort(key, direction);
4325
+ return {
4326
+ key: key,
4327
+ direction: direction
4328
+ };
4213
4329
  });
4214
- var allSelected = pageRowKeys.every(function (k) {
4215
- return newSelection.has(k);
4330
+ }, [sortable, onSort]);
4331
+ var handleFilter = React.useCallback(function (key, value) {
4332
+ setFilters(function (prev) {
4333
+ var newFilters = _objectSpread$9(_objectSpread$9({}, prev), {}, _defineProperty$4({}, key, value));
4334
+ onFilter === null || onFilter === void 0 || onFilter(newFilters);
4335
+ onFilterChange === null || onFilterChange === void 0 || onFilterChange(newFilters);
4336
+ return newFilters;
4216
4337
  });
4217
- if (allSelected) {
4218
- pageRowKeys.forEach(function (k) {
4219
- return newSelection["delete"](k);
4338
+ setCurrentPage(1);
4339
+ }, [onFilter, onFilterChange]);
4340
+ var handleSelectAll = React.useCallback(function () {
4341
+ setSelectedRows(function (prev) {
4342
+ var newSelection = new Set(prev);
4343
+ var pageRowKeys = paginatedData.map(function (r, i) {
4344
+ return getRowKey(r, startIndex + i);
4220
4345
  });
4221
- } else {
4222
- pageRowKeys.forEach(function (k) {
4223
- return newSelection.add(k);
4346
+ var allSelected = pageRowKeys.every(function (k) {
4347
+ return newSelection.has(k);
4224
4348
  });
4225
- }
4226
- setSelectedRows(newSelection);
4227
- var keyToRow = new Map(filteredData.map(function (r, i) {
4228
- return [getRowKey(r, i), r];
4229
- }));
4230
- var selectedData = Array.from(newSelection).map(function (k) {
4231
- return keyToRow.get(k);
4232
- }).filter(Boolean);
4233
- onSelectionChange === null || onSelectionChange === void 0 || onSelectionChange(selectedData);
4234
- };
4235
- var handleSelectRow = function handleSelectRow(row, rowIndexInPage) {
4349
+ if (allSelected) {
4350
+ pageRowKeys.forEach(function (k) {
4351
+ return newSelection["delete"](k);
4352
+ });
4353
+ } else {
4354
+ pageRowKeys.forEach(function (k) {
4355
+ return newSelection.add(k);
4356
+ });
4357
+ }
4358
+
4359
+ // Notify parent
4360
+ var selectedData = Array.from(newSelection).map(function (k) {
4361
+ return rowKeyMap.get(k);
4362
+ }).filter(Boolean);
4363
+ onSelectionChange === null || onSelectionChange === void 0 || onSelectionChange(selectedData);
4364
+ return newSelection;
4365
+ });
4366
+ }, [paginatedData, startIndex, rowKeyMap, onSelectionChange]);
4367
+ var handleSelectRow = React.useCallback(function (row, rowIndexInPage) {
4236
4368
  var globalIndex = startIndex + rowIndexInPage;
4237
4369
  var key = getRowKey(row, globalIndex);
4238
- var newSelection = new Set(selectedRows);
4239
- if (newSelection.has(key)) newSelection["delete"](key);else newSelection.add(key);
4240
- setSelectedRows(newSelection);
4241
- var keyToRow = new Map(filteredData.map(function (r, i) {
4242
- return [getRowKey(r, i), r];
4243
- }));
4244
- var selectedData = Array.from(newSelection).map(function (k) {
4245
- return keyToRow.get(k);
4246
- }).filter(Boolean);
4247
- onSelectionChange === null || onSelectionChange === void 0 || onSelectionChange(selectedData);
4248
- };
4249
- var toggleExpandRow = function toggleExpandRow(row, rowIndexInPage) {
4370
+ setSelectedRows(function (prev) {
4371
+ var newSelection = new Set(prev);
4372
+ if (newSelection.has(key)) {
4373
+ newSelection["delete"](key);
4374
+ } else {
4375
+ newSelection.add(key);
4376
+ }
4377
+ var selectedData = Array.from(newSelection).map(function (k) {
4378
+ return rowKeyMap.get(k);
4379
+ }).filter(Boolean);
4380
+ onSelectionChange === null || onSelectionChange === void 0 || onSelectionChange(selectedData);
4381
+ return newSelection;
4382
+ });
4383
+ }, [startIndex, rowKeyMap, onSelectionChange]);
4384
+ var toggleExpandRow = React.useCallback(function (row, rowIndexInPage) {
4250
4385
  var globalIndex = startIndex + rowIndexInPage;
4251
4386
  var key = getRowKey(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) {
4264
- if (column.render) return column.render(row, globalIndex);
4265
- return row === null || row === void 0 ? void 0 : row[column.key];
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) {
4387
+ setExpandedRows(function (prev) {
4388
+ var newExpanded = new Set(prev);
4389
+ if (newExpanded.has(key)) {
4390
+ newExpanded["delete"](key);
4391
+ } else {
4392
+ newExpanded.add(key);
4393
+ }
4394
+ return newExpanded;
4395
+ });
4396
+ }, [startIndex]);
4397
+ var toggleActions = React.useCallback(function (e, actionCellKey, row) {
4271
4398
  e.stopPropagation();
4272
- if (actionAnchor && actionAnchor.key === actionCellKey) {
4273
- setOpenActionKey(null);
4274
- setActionAnchor(null);
4275
- } else {
4276
- setOpenActionKey(actionCellKey);
4277
- setActionAnchor({
4399
+ setActionAnchor(function (prev) {
4400
+ if (prev && prev.key === actionCellKey) return null;
4401
+ return {
4278
4402
  elem: e.currentTarget,
4279
4403
  key: actionCellKey,
4280
4404
  row: row
4281
- });
4405
+ };
4406
+ });
4407
+ }, []);
4408
+ var handleOnAction = React.useCallback(function (action, row) {
4409
+ var _action$onClick;
4410
+ (_action$onClick = action.onClick) === null || _action$onClick === void 0 || _action$onClick.call(action, {
4411
+ action: action,
4412
+ row: row
4413
+ });
4414
+ onAction === null || onAction === void 0 || onAction({
4415
+ action: action,
4416
+ row: row
4417
+ });
4418
+ setActionAnchor(null);
4419
+ }, [onAction]);
4420
+ var handleLimitChange = React.useCallback(function (nextLimit) {
4421
+ var parsed = Number(nextLimit);
4422
+ if (!Number.isFinite(parsed) || parsed <= 0) return;
4423
+ setLimit(parsed);
4424
+ setCurrentPage(1);
4425
+ onLimitChange === null || onLimitChange === void 0 || onLimitChange(parsed);
4426
+ }, [onLimitChange]);
4427
+ var applyGlobalSearch = React.useCallback(function () {
4428
+ handleFilter("global", searchInput);
4429
+ }, [handleFilter, searchInput]);
4430
+ var onGlobalKeyDown = React.useCallback(function (e) {
4431
+ if (e.key === "Enter") {
4432
+ e.preventDefault();
4433
+ applyGlobalSearch();
4282
4434
  }
4283
- };
4284
- React.useEffect(function () {
4285
- if (!actionAnchor) return;
4286
- var onDocClick = function onDocClick(ev) {
4287
- if (actionMenuRef.current && (actionMenuRef.current.contains(ev.target) || actionAnchor.elem && actionAnchor.elem.contains(ev.target))) {
4288
- return;
4289
- }
4290
- setOpenActionKey(null);
4291
- setActionAnchor(null);
4292
- };
4293
- var onScrollResize = function onScrollResize() {
4294
- setOpenActionKey(function (k) {
4295
- return k ? k : null;
4296
- });
4297
- };
4298
- window.addEventListener("click", onDocClick);
4299
- window.addEventListener("scroll", onScrollResize, true);
4300
- window.addEventListener("resize", onScrollResize);
4301
- return function () {
4302
- window.removeEventListener("click", onDocClick);
4303
- window.removeEventListener("scroll", onScrollResize, true);
4304
- window.removeEventListener("resize", onScrollResize);
4305
- };
4306
- }, [actionAnchor]);
4435
+ }, [applyGlobalSearch]);
4436
+ var handlePageChange = React.useCallback(function (newPage) {
4437
+ setCurrentPage(newPage);
4438
+ }, []);
4439
+
4440
+ // Data fetching effect
4307
4441
  React.useEffect(function () {
4308
4442
  if (!onFetch) return;
4309
4443
  onFetch({
@@ -4317,45 +4451,31 @@ var Table = function Table(_ref) {
4317
4451
  sort: sortConfig
4318
4452
  });
4319
4453
  }, [onFetch, filters, currentPage, limit, sortConfig]);
4320
- React.useEffect(function () {
4321
- if (!serverSide) setTableData(data);
4322
- }, [data, serverSide]);
4323
- React.useEffect(function () {
4324
- if (!onFetch && isValidList(data)) setTableData(data);
4325
- }, [data, onFetch]);
4326
4454
 
4327
- // Global search
4455
+ // Sync searchInput with filters.global
4328
4456
  React.useEffect(function () {
4329
4457
  setSearchInput(filters.global || "");
4330
4458
  }, [filters.global]);
4331
- var applyGlobalSearch = function applyGlobalSearch() {
4332
- handleFilter("global", searchInput);
4333
- };
4334
- var onGlobalKeyDown = function onGlobalKeyDown(e) {
4335
- if (e.key === "Enter") {
4336
- e.preventDefault();
4337
- applyGlobalSearch();
4338
- }
4339
- };
4340
- var handleLimitChange = function handleLimitChange(nextLimit) {
4341
- var parsed = Number(nextLimit);
4342
- if (!Number.isFinite(parsed) || parsed <= 0) return;
4343
- setLimit(parsed);
4344
- setCurrentPage(1);
4345
- onLimitChange === null || onLimitChange === void 0 || onLimitChange(parsed);
4346
- };
4459
+
4460
+ // Render cell helper
4461
+ var renderCell = React.useCallback(function (column, row, globalIndex) {
4462
+ if (column.render) return column.render(row, globalIndex);
4463
+ return row === null || row === void 0 ? void 0 : row[column.key];
4464
+ }, []);
4347
4465
 
4348
4466
  // Render mobile card
4349
- var renderMobileCard = function renderMobileCard(row, rowIndexInPage) {
4467
+ var renderMobileCard = React.useCallback(function (row, rowIndexInPage) {
4350
4468
  var globalIndex = startIndex + rowIndexInPage;
4351
4469
  var key = getRowKey(row, globalIndex);
4352
4470
  var actionCellKey = "actions-".concat(key);
4471
+ var isSelected = selectedRows.has(key);
4472
+ var isExpanded = expandedRows.has(key);
4353
4473
  var extraRowClass = typeof rowClass === "function" ? rowClass({
4354
4474
  row: row,
4355
4475
  rowIndex: globalIndex
4356
4476
  }) : "";
4357
4477
  var safeExtraRowClass = typeof extraRowClass === "string" ? extraRowClass.trim() : "";
4358
- var stripeBg = stripedRows && !selectedRows.has(key) ? stripedColors[globalIndex % stripedColors.length] : undefined;
4478
+ var stripeBg = stripedRows && !isSelected ? stripedColors[globalIndex % stripedColors.length] : undefined;
4359
4479
  return /*#__PURE__*/React.createElement("div", {
4360
4480
  key: key,
4361
4481
  style: stripeBg ? {
@@ -4363,8 +4483,8 @@ var Table = function Table(_ref) {
4363
4483
  } : undefined,
4364
4484
  className: cn$1("border rounded-lg mb-3 shadow-sm overflow-hidden transition-all duration-200", {
4365
4485
  "cursor-pointer": !!onRowClick,
4366
- "bg-primary-50 border-primary-200": selectedRows.has(key),
4367
- "hover:shadow-md": !selectedRows.has(key)
4486
+ "bg-primary-50 border-primary-200": isSelected,
4487
+ "hover:shadow-md": !isSelected
4368
4488
  }, safeExtraRowClass),
4369
4489
  onClick: function onClick() {
4370
4490
  return onRowClick === null || onRowClick === void 0 ? void 0 : onRowClick(row, globalIndex);
@@ -4378,12 +4498,12 @@ var Table = function Table(_ref) {
4378
4498
  e.stopPropagation();
4379
4499
  toggleExpandRow(row, rowIndexInPage);
4380
4500
  },
4381
- "aria-expanded": expandedRows.has(key),
4501
+ "aria-expanded": isExpanded,
4382
4502
  className: "p-1 rounded hover:bg-gray-200"
4383
- }, expandedRows.has(key) ? "▾" : "▸"), selectable && /*#__PURE__*/React.createElement("input", {
4503
+ }, isExpanded ? "▾" : "▸"), selectable && /*#__PURE__*/React.createElement("input", {
4384
4504
  type: "checkbox",
4385
4505
  className: "rounded border-gray-300 h-4 w-4",
4386
- checked: selectedRows.has(key),
4506
+ checked: isSelected,
4387
4507
  onChange: function onChange(e) {
4388
4508
  e.stopPropagation();
4389
4509
  handleSelectRow(row, rowIndexInPage);
@@ -4397,26 +4517,19 @@ var Table = function Table(_ref) {
4397
4517
  className: "relative"
4398
4518
  }, /*#__PURE__*/React.createElement("button", {
4399
4519
  onClick: function onClick(e) {
4400
- e.stopPropagation();
4401
- toggleActions(e, actionCellKey, row);
4520
+ return toggleActions(e, actionCellKey, row);
4402
4521
  },
4403
- "aria-expanded": openActionKey === actionCellKey,
4522
+ "aria-expanded": (actionAnchor === null || actionAnchor === void 0 ? void 0 : actionAnchor.key) === actionCellKey,
4404
4523
  className: "p-1.5 rounded hover:bg-gray-200",
4405
4524
  title: "Actions"
4406
4525
  }, /*#__PURE__*/React.createElement(MoreVertical, {
4407
4526
  className: "h-4 w-4"
4408
- })), actionAnchor && actionAnchor.key === actionCellKey && /*#__PURE__*/ReactDOM.createPortal(/*#__PURE__*/React.createElement(ActionMenuPortal, {
4527
+ })), (actionAnchor === null || actionAnchor === void 0 ? void 0 : actionAnchor.key) === actionCellKey && /*#__PURE__*/ReactDOM.createPortal(/*#__PURE__*/React.createElement(ActionMenuPortal, {
4409
4528
  anchorElem: actionAnchor.elem,
4410
4529
  anchorRow: actionAnchor.row,
4411
4530
  actions: actionsToUse,
4412
- onClose: function onClose() {
4413
- setOpenActionKey(null);
4414
- setActionAnchor(null);
4415
- },
4416
4531
  onAction: function onAction(action) {
4417
- handleOnAction(action, row);
4418
- setOpenActionKey(null);
4419
- setActionAnchor(null);
4532
+ return handleOnAction(action, row);
4420
4533
  },
4421
4534
  menuRef: actionMenuRef
4422
4535
  }), document.body))), /*#__PURE__*/React.createElement("div", {
@@ -4437,16 +4550,16 @@ var Table = function Table(_ref) {
4437
4550
  }, column.label), /*#__PURE__*/React.createElement("div", {
4438
4551
  className: "text-sm text-gray-900 sm:w-2/3 sm:pl-2 break-words"
4439
4552
  }, renderCell(column, row, globalIndex)));
4440
- })), hasDetails && expandedRows.has(key) && DetailsComponent && /*#__PURE__*/React.createElement("div", {
4553
+ })), hasDetails && isExpanded && DetailsComponent && /*#__PURE__*/React.createElement("div", {
4441
4554
  className: "border-t bg-gray-50 p-4"
4442
4555
  }, /*#__PURE__*/React.createElement(DetailsComponent, {
4443
4556
  row: row,
4444
4557
  index: globalIndex
4445
4558
  })));
4446
- };
4559
+ }, [startIndex, selectedRows, expandedRows, rowClass, stripedRows, stripedColors, onRowClick, hasDetails, selectable, showSerial, withAction, visibleColumns, cellClass, DetailsComponent, actionsToUse, actionAnchor, toggleExpandRow, handleSelectRow, toggleActions, handleOnAction, renderCell]);
4447
4560
 
4448
4561
  // Render mobile filters
4449
- var renderMobileFilters = function renderMobileFilters() {
4562
+ var renderMobileFilters = React.useCallback(function () {
4450
4563
  return /*#__PURE__*/React.createElement("div", {
4451
4564
  className: "mb-4 p-3 bg-gray-50 rounded-lg"
4452
4565
  }, /*#__PURE__*/React.createElement("div", {
@@ -4455,12 +4568,14 @@ var Table = function Table(_ref) {
4455
4568
  className: "text-sm font-medium text-gray-700"
4456
4569
  }, "Filters"), /*#__PURE__*/React.createElement("button", {
4457
4570
  onClick: function onClick() {
4458
- return setShowMobileFilters(!showMobileFilters);
4571
+ return setShowMobileFilters(function (s) {
4572
+ return !s;
4573
+ });
4459
4574
  },
4460
4575
  className: "text-xs text-gray-500 hover:text-gray-700"
4461
4576
  }, showMobileFilters ? "Hide" : "Show")), showMobileFilters && /*#__PURE__*/React.createElement("div", {
4462
4577
  className: "space-y-3"
4463
- }, globalSearch && /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("div", {
4578
+ }, globalSearch && /*#__PURE__*/React.createElement("div", {
4464
4579
  className: "relative"
4465
4580
  }, /*#__PURE__*/React.createElement("input", {
4466
4581
  type: "text",
@@ -4473,7 +4588,7 @@ var Table = function Table(_ref) {
4473
4588
  onKeyDown: onGlobalKeyDown
4474
4589
  }), /*#__PURE__*/React.createElement(Search, {
4475
4590
  className: "absolute right-3 top-2.5 h-4 w-4 text-gray-400"
4476
- }))), filterable && visibleColumns.map(function (column) {
4591
+ })), filterable && visibleColumns.map(function (column) {
4477
4592
  return /*#__PURE__*/React.createElement("div", {
4478
4593
  key: column.key
4479
4594
  }, /*#__PURE__*/React.createElement("label", {
@@ -4488,9 +4603,26 @@ var Table = function Table(_ref) {
4488
4603
  }
4489
4604
  }));
4490
4605
  })));
4491
- };
4606
+ }, [showMobileFilters, globalSearch, searchInput, onGlobalKeyDown, filterable, visibleColumns, filters, handleFilter]);
4607
+
4608
+ // Check if all page rows are selected
4609
+ var allPageSelected = React.useMemo(function () {
4610
+ if (paginatedData.length === 0) return false;
4611
+ return paginatedData.every(function (r, i) {
4612
+ return selectedRows.has(getRowKey(r, startIndex + i));
4613
+ });
4614
+ }, [paginatedData, selectedRows, startIndex]);
4492
4615
 
4493
- // Render
4616
+ // Limit options for selector
4617
+ var limitOptionsForSelect = React.useMemo(function () {
4618
+ var opts = Array.isArray(limitOptions) && limitOptions.length > 0 ? limitOptions : [25, 50, 100];
4619
+ return opts.map(function (opt) {
4620
+ return {
4621
+ label: String(opt),
4622
+ value: opt
4623
+ };
4624
+ });
4625
+ }, [limitOptions]);
4494
4626
  return /*#__PURE__*/React.createElement("div", {
4495
4627
  className: "w-full border rounded-lg md:rounded-md bg-white"
4496
4628
  }, /*#__PURE__*/React.createElement("div", {
@@ -4511,23 +4643,11 @@ var Table = function Table(_ref) {
4511
4643
  htmlFor: "pagination-limit",
4512
4644
  className: "text-sm text-gray-600 whitespace-nowrap"
4513
4645
  }, "Show"), /*#__PURE__*/React.createElement(Select, {
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
- }),
4646
+ options: limitOptionsForSelect,
4525
4647
  value: limit,
4526
4648
  allowClear: false,
4527
4649
  placeholder: "",
4528
- onChange: function onChange(e) {
4529
- return handleLimitChange(e);
4530
- },
4650
+ onChange: handleLimitChange,
4531
4651
  className: "w-20 md:w-30"
4532
4652
  }), /*#__PURE__*/React.createElement("p", {
4533
4653
  className: "text-sm text-gray-600 whitespace-nowrap"
@@ -4535,17 +4655,13 @@ var Table = function Table(_ref) {
4535
4655
  className: "flex flex-col sm:flex-row items-start sm:items-center gap-3 w-full md:w-auto"
4536
4656
  }, /*#__PURE__*/React.createElement("div", {
4537
4657
  className: "text-sm text-gray-700 whitespace-nowrap"
4538
- }, filteredData.length === 0 ? 0 : startIndex + 1, " -", " ", Math.min(endIndex, filteredData.length), " of ", filteredData.length, " ", "results"), pagination && /*#__PURE__*/React.createElement("div", {
4658
+ }, filteredData.length === 0 ? 0 : startIndex + 1, " -", " ", Math.min(endIndex, filteredData.length), " of ", filteredData.length, " results"), pagination && /*#__PURE__*/React.createElement("div", {
4539
4659
  className: "flex items-center gap-1"
4540
- }, /*#__PURE__*/React.createElement("div", {
4541
- className: "flex gap-1"
4542
4660
  }, /*#__PURE__*/React.createElement("button", {
4543
4661
  className: "rounded-lg md:rounded-md border border-gray-300 p-2 disabled:opacity-50 hover:bg-gray-50",
4544
4662
  disabled: currentPage === 1,
4545
4663
  onClick: function onClick() {
4546
- return setCurrentPage(function (p) {
4547
- return Math.max(1, p - 1);
4548
- });
4664
+ return handlePageChange(Math.max(1, currentPage - 1));
4549
4665
  },
4550
4666
  "aria-label": "Previous page"
4551
4667
  }, /*#__PURE__*/React.createElement(ChevronLeft, {
@@ -4554,14 +4670,12 @@ var Table = function Table(_ref) {
4554
4670
  className: "rounded-lg md:rounded-md border border-gray-300 p-2 disabled:opacity-50 hover:bg-gray-50",
4555
4671
  disabled: currentPage === totalPages,
4556
4672
  onClick: function onClick() {
4557
- return setCurrentPage(function (p) {
4558
- return Math.min(totalPages, p + 1);
4559
- });
4673
+ return handlePageChange(Math.min(totalPages, currentPage + 1));
4560
4674
  },
4561
4675
  "aria-label": "Next page"
4562
4676
  }, /*#__PURE__*/React.createElement(ChevronRight, {
4563
4677
  className: "size-4 md:size-5 text-gray-800"
4564
- })))))), globalSearch && /*#__PURE__*/React.createElement("div", {
4678
+ }))))), globalSearch && /*#__PURE__*/React.createElement("div", {
4565
4679
  className: "p-4 border-b"
4566
4680
  }, /*#__PURE__*/React.createElement("div", {
4567
4681
  className: "flex flex-col sm:flex-row items-start sm:items-center gap-2"
@@ -4627,9 +4741,7 @@ var Table = function Table(_ref) {
4627
4741
  }, /*#__PURE__*/React.createElement("input", {
4628
4742
  type: "checkbox",
4629
4743
  className: "rounded border-gray-300",
4630
- checked: paginatedData.length > 0 && paginatedData.every(function (r, i) {
4631
- return selectedRows.has(getRowKey(r, startIndex + i));
4632
- }),
4744
+ checked: allPageSelected,
4633
4745
  onChange: handleSelectAll
4634
4746
  })), visibleColumns.map(function (column) {
4635
4747
  return /*#__PURE__*/React.createElement("th", {
@@ -4720,12 +4832,14 @@ var Table = function Table(_ref) {
4720
4832
  var globalIndex = startIndex + rowIndexInPage;
4721
4833
  var key = getRowKey(row, globalIndex);
4722
4834
  var actionCellKey = "actions-".concat(key);
4835
+ var isSelected = selectedRows.has(key);
4836
+ var isExpanded = expandedRows.has(key);
4723
4837
  var extraRowClass = typeof rowClass === "function" ? rowClass({
4724
4838
  row: row,
4725
4839
  rowIndex: globalIndex
4726
4840
  }) : "";
4727
4841
  var safeExtraRowClass = typeof extraRowClass === "string" ? extraRowClass.trim() : "";
4728
- var stripeBg = stripedRows && !selectedRows.has(key) ? stripedColors[globalIndex % stripedColors.length] : undefined;
4842
+ var stripeBg = stripedRows && !isSelected ? stripedColors[globalIndex % stripedColors.length] : undefined;
4729
4843
  return /*#__PURE__*/React.createElement(React.Fragment, {
4730
4844
  key: key
4731
4845
  }, /*#__PURE__*/React.createElement("tr", {
@@ -4734,7 +4848,7 @@ var Table = function Table(_ref) {
4734
4848
  } : undefined,
4735
4849
  className: cn$1("hover:bg-gray-50", {
4736
4850
  "cursor-pointer": !!onRowClick,
4737
- "bg-primary-50": selectedRows.has(key)
4851
+ "bg-primary-50": isSelected
4738
4852
  }, safeExtraRowClass),
4739
4853
  onClick: function onClick() {
4740
4854
  return onRowClick === null || onRowClick === void 0 ? void 0 : onRowClick(row, globalIndex);
@@ -4746,19 +4860,19 @@ var Table = function Table(_ref) {
4746
4860
  e.stopPropagation();
4747
4861
  toggleExpandRow(row, rowIndexInPage);
4748
4862
  },
4749
- "aria-expanded": expandedRows.has(key),
4863
+ "aria-expanded": isExpanded,
4750
4864
  className: "p-1 rounded hover:bg-gray-100"
4751
- }, expandedRows.has(key) ? "▾" : "▸")), showSerial && /*#__PURE__*/React.createElement("td", {
4865
+ }, isExpanded ? "▾" : "▸")), showSerial && /*#__PURE__*/React.createElement("td", {
4752
4866
  className: "px-4 py-4 whitespace-nowrap text-sm text-gray-900"
4753
4867
  }, globalIndex + 1), selectable && /*#__PURE__*/React.createElement("td", {
4754
4868
  className: "px-6 py-4",
4755
4869
  onClick: function onClick(e) {
4756
- e.stopPropagation();
4870
+ return e.stopPropagation();
4757
4871
  }
4758
4872
  }, /*#__PURE__*/React.createElement("input", {
4759
4873
  type: "checkbox",
4760
4874
  className: "rounded border-gray-300",
4761
- checked: selectedRows.has(key),
4875
+ checked: isSelected,
4762
4876
  onChange: function onChange() {
4763
4877
  return handleSelectRow(row, rowIndexInPage);
4764
4878
  }
@@ -4774,6 +4888,8 @@ var Table = function Table(_ref) {
4774
4888
  key: column.key,
4775
4889
  className: cn$1("px-6 py-4 whitespace-nowrap text-sm text-gray-900", safeExtraCellClass)
4776
4890
  }, renderCell(column, row, globalIndex));
4891
+ }), /*#__PURE__*/React.createElement("td", {
4892
+ className: "px-4 py-4"
4777
4893
  }), withAction && /*#__PURE__*/React.createElement("td", {
4778
4894
  className: "px-4 py-4 text-sm text-right",
4779
4895
  onClick: function onClick(e) {
@@ -4785,32 +4901,26 @@ var Table = function Table(_ref) {
4785
4901
  onClick: function onClick(e) {
4786
4902
  return toggleActions(e, actionCellKey, row);
4787
4903
  },
4788
- "aria-expanded": openActionKey === actionCellKey,
4904
+ "aria-expanded": (actionAnchor === null || actionAnchor === void 0 ? void 0 : actionAnchor.key) === actionCellKey,
4789
4905
  className: "p-1 rounded hover:bg-gray-100",
4790
4906
  title: "Actions"
4791
4907
  }, /*#__PURE__*/React.createElement(MoreVertical, {
4792
4908
  className: "h-4 w-4"
4793
- }))), actionAnchor && actionAnchor.key === actionCellKey && /*#__PURE__*/ReactDOM.createPortal(/*#__PURE__*/React.createElement(ActionMenuPortal, {
4909
+ }))), (actionAnchor === null || actionAnchor === void 0 ? void 0 : actionAnchor.key) === actionCellKey && /*#__PURE__*/ReactDOM.createPortal(/*#__PURE__*/React.createElement(ActionMenuPortal, {
4794
4910
  anchorElem: actionAnchor.elem,
4795
4911
  anchorRow: actionAnchor.row,
4796
4912
  actions: actionsToUse,
4797
- onClose: function onClose() {
4798
- setOpenActionKey(null);
4799
- setActionAnchor(null);
4800
- },
4801
4913
  onAction: function onAction(action) {
4802
- handleOnAction(action, row);
4803
- setOpenActionKey(null);
4804
- setActionAnchor(null);
4914
+ return handleOnAction(action, row);
4805
4915
  },
4806
4916
  menuRef: actionMenuRef
4807
- }), document.body))), hasDetails && expandedRows.has(key) && DetailsComponent && /*#__PURE__*/React.createElement("tr", null, /*#__PURE__*/React.createElement("td", {
4917
+ }), document.body))), hasDetails && isExpanded && DetailsComponent && /*#__PURE__*/React.createElement("tr", null, /*#__PURE__*/React.createElement("td", {
4808
4918
  colSpan: visibleCount,
4809
4919
  className: "px-6 py-4 bg-gray-50"
4810
- }, /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement(DetailsComponent, {
4920
+ }, /*#__PURE__*/React.createElement(DetailsComponent, {
4811
4921
  row: row,
4812
4922
  index: globalIndex
4813
- })))));
4923
+ }))));
4814
4924
  })))), isMobileView && /*#__PURE__*/React.createElement("div", {
4815
4925
  className: "p-4"
4816
4926
  }, loading ? /*#__PURE__*/React.createElement("div", {
@@ -4845,9 +4955,7 @@ var Table = function Table(_ref) {
4845
4955
  className: "rounded-lg md:rounded-md border border-gray-300 px-4 py-2 text-sm disabled:opacity-50 hover:bg-gray-50",
4846
4956
  disabled: currentPage === 1,
4847
4957
  onClick: function onClick() {
4848
- return setCurrentPage(function (p) {
4849
- return Math.max(1, p - 1);
4850
- });
4958
+ return handlePageChange(Math.max(1, currentPage - 1));
4851
4959
  }
4852
4960
  }, "Previous"), /*#__PURE__*/React.createElement("div", {
4853
4961
  className: "flex items-center gap-1"
@@ -4871,170 +4979,17 @@ var Table = function Table(_ref) {
4871
4979
  "border border-gray-300 hover:bg-gray-50": pageNum !== currentPage
4872
4980
  }),
4873
4981
  onClick: function onClick() {
4874
- return setCurrentPage(pageNum);
4982
+ return handlePageChange(pageNum);
4875
4983
  }
4876
4984
  }, pageNum);
4877
4985
  })), /*#__PURE__*/React.createElement("button", {
4878
4986
  className: "rounded-lg md:rounded-md border border-gray-300 px-4 py-2 text-sm disabled:opacity-50 hover:bg-gray-50",
4879
4987
  disabled: currentPage === totalPages,
4880
4988
  onClick: function onClick() {
4881
- return setCurrentPage(function (p) {
4882
- return Math.min(totalPages, p + 1);
4883
- });
4989
+ return handlePageChange(Math.min(totalPages, currentPage + 1));
4884
4990
  }
4885
4991
  }, "Next")))));
4886
4992
  };
4887
- function ActionMenuPortal(_ref2) {
4888
- var anchorElem = _ref2.anchorElem,
4889
- anchorRow = _ref2.anchorRow,
4890
- _ref2$actions = _ref2.actions,
4891
- actions = _ref2$actions === void 0 ? [] : _ref2$actions;
4892
- _ref2.onClose;
4893
- var onAction = _ref2.onAction,
4894
- menuRef = _ref2.menuRef;
4895
- var _useState29 = React.useState({
4896
- left: 0,
4897
- top: 0,
4898
- transformOrigin: "top right",
4899
- maxHeight: 300,
4900
- width: 180,
4901
- opacity: 0
4902
- }),
4903
- _useState30 = _slicedToArray(_useState29, 2),
4904
- style = _useState30[0],
4905
- setStyle = _useState30[1];
4906
- var menuWidth = 180;
4907
- var maxMenuHeight = 320;
4908
- var margin = 8;
4909
- var minMenuHeight = 80;
4910
-
4911
- // compute position using actual menu height (if available) and layout measurements
4912
- var computePosition = function computePosition() {
4913
- if (!anchorElem) return;
4914
- var rect = anchorElem.getBoundingClientRect();
4915
- var scrollY = window.scrollY || window.pageYOffset;
4916
- var scrollX = window.scrollX || window.pageXOffset;
4917
- var spaceBelow = window.innerHeight - rect.bottom;
4918
- var spaceAbove = rect.top;
4919
-
4920
- // allowed max height based on available space
4921
- var allowedMaxHeight = Math.min(maxMenuHeight, Math.max(minMenuHeight, Math.max(spaceBelow - margin, spaceAbove - margin)));
4922
-
4923
- // choose placement by comparing actual available spaces
4924
- var placement = "bottom";
4925
- if (spaceBelow < 160 && spaceAbove > spaceBelow) {
4926
- placement = "top";
4927
- // when placing on top we should cap allowedMaxHeight by spaceAbove
4928
- allowedMaxHeight = Math.min(maxMenuHeight, Math.max(minMenuHeight, spaceAbove - margin));
4929
- } else {
4930
- // placing bottom: cap by spaceBelow
4931
- allowedMaxHeight = Math.min(maxMenuHeight, Math.max(minMenuHeight, spaceBelow - margin));
4932
- }
4933
-
4934
- // measure the menu's content height if we can, and compute the actual menu height we'll use.
4935
- var measuredMenuHeight = allowedMaxHeight;
4936
- var menuEl = menuRef === null || menuRef === void 0 ? void 0 : menuRef.current;
4937
- if (menuEl) {
4938
- // scrollHeight is the content height; offsetHeight may reflect current rendered height.
4939
- var contentHeight = menuEl.scrollHeight || menuEl.offsetHeight || allowedMaxHeight;
4940
- // actual height will be min(contentHeight, allowedMaxHeight)
4941
- measuredMenuHeight = Math.min(contentHeight, allowedMaxHeight);
4942
- }
4943
-
4944
- // compute top according to placement and measuredMenuHeight
4945
- var top;
4946
- if (placement === "top") {
4947
- // place menu so its bottom sits just above the anchor (rect.top - margin)
4948
- top = rect.top + scrollY - measuredMenuHeight - margin;
4949
- } else {
4950
- // place menu just below the anchor (rect.bottom + margin)
4951
- top = rect.bottom + scrollY + margin;
4952
- }
4953
-
4954
- // clamp top to viewport (so it never goes off-screen)
4955
- var minTop = margin + scrollY;
4956
- var maxTop = window.innerHeight + scrollY - measuredMenuHeight - margin;
4957
- if (top < minTop) top = minTop;
4958
- if (top > maxTop) top = maxTop;
4959
-
4960
- // compute left and clamp horizontally
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);
4965
- }
4966
- var transformOrigin = placement === "bottom" ? "top right" : "bottom right";
4967
-
4968
- // set style (opacity 1 to fade-in)
4969
- setStyle({
4970
- left: left,
4971
- top: top,
4972
- transformOrigin: transformOrigin,
4973
- maxHeight: allowedMaxHeight,
4974
- width: menuWidth,
4975
- opacity: 1
4976
- });
4977
- };
4978
-
4979
- // useLayoutEffect so the position is measured & applied before paint
4980
- React.useLayoutEffect(function () {
4981
- // compute once after mount
4982
- computePosition();
4983
- var onScrollOrResize = function onScrollOrResize() {
4984
- // using requestAnimationFrame to avoid layout thrash on fast scroll/resize
4985
- window.requestAnimationFrame(function () {
4986
- return computePosition();
4987
- });
4988
- };
4989
- window.addEventListener("resize", onScrollOrResize);
4990
- // capture scrolls (true) so position updates even when scrolling ancestor elements
4991
- window.addEventListener("scroll", onScrollOrResize, true);
4992
- return function () {
4993
- window.removeEventListener("resize", onScrollOrResize);
4994
- window.removeEventListener("scroll", onScrollOrResize, true);
4995
- };
4996
- // Recompute when anchor element changes or actions change (content height may change).
4997
- }, [anchorElem, actions, menuRef]);
4998
- return /*#__PURE__*/ReactDOM.createPortal(/*#__PURE__*/React.createElement("div", {
4999
- ref: menuRef,
5000
- style: {
5001
- position: "absolute",
5002
- top: style.top,
5003
- left: style.left,
5004
- width: style.width,
5005
- maxHeight: style.maxHeight,
5006
- transformOrigin: style.transformOrigin,
5007
- opacity: style.opacity
5008
- },
5009
- className: "absolute z-50 bg-white rounded-lg shadow-lg ring-1 ring-black ring-opacity-5 overflow-y-auto transition-opacity duration-150 ease-out",
5010
- onClick: function onClick(e) {
5011
- return e.stopPropagation();
5012
- }
5013
- }, /*#__PURE__*/React.createElement("div", {
5014
- className: "p-1"
5015
- }, actions.length === 0 ? /*#__PURE__*/React.createElement("div", {
5016
- className: "px-3 py-2 text-sm text-gray-500"
5017
- }, "No actions") : actions.map(function (action) {
5018
- return /*#__PURE__*/React.createElement("div", {
5019
- key: action.name,
5020
- className: "px-1"
5021
- }, action.render ? /*#__PURE__*/React.createElement("button", {
5022
- className: "w-full text-left px-3 py-2 text-sm hover:bg-gray-100 flex items-center gap-2 rounded-md",
5023
- onClick: function onClick(e) {
5024
- e.stopPropagation();
5025
- onAction === null || onAction === void 0 || onAction(action, anchorRow);
5026
- }
5027
- }, action.render(anchorRow)) : /*#__PURE__*/React.createElement("button", {
5028
- className: "w-full text-left px-3 py-2 text-sm hover:bg-gray-100 flex items-center gap-2 rounded-md",
5029
- onClick: function onClick(e) {
5030
- e.stopPropagation();
5031
- onAction === null || onAction === void 0 || onAction(action, anchorRow);
5032
- }
5033
- }, action.icon && /*#__PURE__*/React.createElement("span", {
5034
- className: "inline-flex"
5035
- }, action.icon), /*#__PURE__*/React.createElement("span", null, action.label)));
5036
- }))), document.body);
5037
- }
5038
4993
 
5039
4994
  var isCheckBoxInput = (element) => element.type === 'checkbox';
5040
4995