@dreamtree-org/twreact-ui 1.1.65 → 1.1.67

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
@@ -70,17 +70,17 @@ function _iterableToArrayLimit(r, l) {
70
70
  }
71
71
  }
72
72
 
73
- function _arrayLikeToArray$1(r, a) {
73
+ function _arrayLikeToArray$2(r, a) {
74
74
  (null == a || a > r.length) && (a = r.length);
75
75
  for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e];
76
76
  return n;
77
77
  }
78
78
 
79
- function _unsupportedIterableToArray$1(r, a) {
79
+ function _unsupportedIterableToArray$2(r, a) {
80
80
  if (r) {
81
- if ("string" == typeof r) return _arrayLikeToArray$1(r, a);
81
+ if ("string" == typeof r) return _arrayLikeToArray$2(r, a);
82
82
  var t = {}.toString.call(r).slice(8, -1);
83
- return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray$1(r, a) : void 0;
83
+ return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray$2(r, a) : void 0;
84
84
  }
85
85
  }
86
86
 
@@ -89,7 +89,7 @@ function _nonIterableRest() {
89
89
  }
90
90
 
91
91
  function _slicedToArray(r, e) {
92
- return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray$1(r, e) || _nonIterableRest();
92
+ return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray$2(r, e) || _nonIterableRest();
93
93
  }
94
94
 
95
95
  function _objectWithoutPropertiesLoose$1(r, e) {
@@ -3141,8 +3141,8 @@ function cn$1() {
3141
3141
  }
3142
3142
 
3143
3143
  var _excluded$A = ["id", "className", "type", "label", "placeholder", "error", "success", "disabled", "required", "clearable", "icon", "iconPosition", "onClear", "showCount", "maxLength", "readOnly", "onChange", "value", "defaultValue"];
3144
- function ownKeys$E(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; }
3145
- function _objectSpread$E(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys$E(Object(t), true).forEach(function (r) { _defineProperty$4(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys$E(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
3144
+ function ownKeys$F(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; }
3145
+ function _objectSpread$F(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys$F(Object(t), true).forEach(function (r) { _defineProperty$4(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys$F(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
3146
3146
  var Input = /*#__PURE__*/forwardRef(function (props, forwardedRef) {
3147
3147
  var _ref$current$value2, _ref$current;
3148
3148
  var id = props.id,
@@ -3257,7 +3257,7 @@ var Input = /*#__PURE__*/forwardRef(function (props, forwardedRef) {
3257
3257
  className: "text-primary-400",
3258
3258
  children: icon
3259
3259
  })
3260
- }), jsx("input", _objectSpread$E({
3260
+ }), jsx("input", _objectSpread$F({
3261
3261
  id: inputId,
3262
3262
  ref: ref,
3263
3263
  type: inputType,
@@ -3318,8 +3318,8 @@ var Input = /*#__PURE__*/forwardRef(function (props, forwardedRef) {
3318
3318
  });
3319
3319
 
3320
3320
  var _excluded$z = ["className", "variant", "size", "disabled", "loading", "children", "leftIcon", "rightIcon", "fullWidth"];
3321
- function ownKeys$D(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; }
3322
- function _objectSpread$D(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys$D(Object(t), true).forEach(function (r) { _defineProperty$4(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys$D(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
3321
+ function ownKeys$E(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; }
3322
+ function _objectSpread$E(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys$E(Object(t), true).forEach(function (r) { _defineProperty$4(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys$E(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
3323
3323
  var Button = /*#__PURE__*/forwardRef(function (_ref, ref) {
3324
3324
  var className = _ref.className,
3325
3325
  _ref$variant = _ref.variant,
@@ -3349,7 +3349,7 @@ var Button = /*#__PURE__*/forwardRef(function (_ref, ref) {
3349
3349
  // Full width
3350
3350
  'w-full': fullWidth
3351
3351
  }, className);
3352
- return jsxs("button", _objectSpread$D(_objectSpread$D({
3352
+ return jsxs("button", _objectSpread$E(_objectSpread$E({
3353
3353
  ref: ref,
3354
3354
  className: baseClasses,
3355
3355
  disabled: disabled || loading
@@ -3368,7 +3368,7 @@ var Button = /*#__PURE__*/forwardRef(function (_ref, ref) {
3368
3368
  Button.displayName = 'Button';
3369
3369
 
3370
3370
  function _arrayWithoutHoles$1(r) {
3371
- if (Array.isArray(r)) return _arrayLikeToArray$1(r);
3371
+ if (Array.isArray(r)) return _arrayLikeToArray$2(r);
3372
3372
  }
3373
3373
 
3374
3374
  function _iterableToArray$1(r) {
@@ -3380,12 +3380,12 @@ function _nonIterableSpread$1() {
3380
3380
  }
3381
3381
 
3382
3382
  function _toConsumableArray$1(r) {
3383
- return _arrayWithoutHoles$1(r) || _iterableToArray$1(r) || _unsupportedIterableToArray$1(r) || _nonIterableSpread$1();
3383
+ return _arrayWithoutHoles$1(r) || _iterableToArray$1(r) || _unsupportedIterableToArray$2(r) || _nonIterableSpread$1();
3384
3384
  }
3385
3385
 
3386
3386
  var _excluded$y = ["options", "value", "onChange", "placeholder", "label", "error", "disabled", "required", "multiSelect", "searchable", "grouped", "onMenuItemRender", "className", "allowClear", "creatable", "onCreateOption", "onSearch", "loading", "selectAllOption", "closeOnSelect", "maxTagCount", "renderGroupLabel", "name"];
3387
- function ownKeys$C(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; }
3388
- function _objectSpread$C(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys$C(Object(t), true).forEach(function (r) { _defineProperty$4(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys$C(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
3387
+ function ownKeys$D(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; }
3388
+ function _objectSpread$D(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys$D(Object(t), true).forEach(function (r) { _defineProperty$4(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys$D(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
3389
3389
  /**
3390
3390
  * Enhanced Select component (debounce removed)
3391
3391
  * - Supports single and multi select
@@ -3406,7 +3406,7 @@ var flattenGroups = function flattenGroups() {
3406
3406
  return groups.reduce(function (acc, g) {
3407
3407
  var groupLabel = g.label;
3408
3408
  g.options.forEach(function (opt) {
3409
- return acc.push(_objectSpread$C(_objectSpread$C({}, opt), {}, {
3409
+ return acc.push(_objectSpread$D(_objectSpread$D({}, opt), {}, {
3410
3410
  _group: groupLabel
3411
3411
  }));
3412
3412
  });
@@ -3502,7 +3502,7 @@ var Select = /*#__PURE__*/React__default.forwardRef(function (_ref, forwardedRef
3502
3502
  var flatOptions = useMemo(function () {
3503
3503
  if (grouped) return flattenGroups(options);
3504
3504
  return options.map(function (opt) {
3505
- return _objectSpread$C({}, opt);
3505
+ return _objectSpread$D({}, opt);
3506
3506
  });
3507
3507
  }, [options, grouped]);
3508
3508
  var selectedValues = multiSelect ? Array.isArray(value) ? value : [] : value;
@@ -3527,7 +3527,7 @@ var Select = /*#__PURE__*/React__default.forwardRef(function (_ref, forwardedRef
3527
3527
  }
3528
3528
  if (grouped) {
3529
3529
  return options.map(function (g) {
3530
- return _objectSpread$C(_objectSpread$C({}, g), {}, {
3530
+ return _objectSpread$D(_objectSpread$D({}, g), {}, {
3531
3531
  options: g.options.filter(function (o) {
3532
3532
  return o.label.toLowerCase().includes(searchTerm.toLowerCase());
3533
3533
  })
@@ -3797,7 +3797,7 @@ var Select = /*#__PURE__*/React__default.forwardRef(function (_ref, forwardedRef
3797
3797
  className: "text-xs border border-slate-200 p-0.5 rounded-md cursor-pointer hover:bg-gray-100",
3798
3798
  onClick: function onClick() {
3799
3799
  return setCollapsedGroups(function (prev) {
3800
- return _objectSpread$C(_objectSpread$C({}, prev), {}, _defineProperty$4({}, group.label, !prev[group.label]));
3800
+ return _objectSpread$D(_objectSpread$D({}, prev), {}, _defineProperty$4({}, group.label, !prev[group.label]));
3801
3801
  });
3802
3802
  },
3803
3803
  children: jsx(ChevronDown, {
@@ -3891,7 +3891,7 @@ var Select = /*#__PURE__*/React__default.forwardRef(function (_ref, forwardedRef
3891
3891
  }), jsxs("div", {
3892
3892
  ref: selectRef,
3893
3893
  className: "relative",
3894
- children: [jsxs("button", _objectSpread$C(_objectSpread$C({
3894
+ children: [jsxs("button", _objectSpread$D(_objectSpread$D({
3895
3895
  type: "button",
3896
3896
  "aria-haspopup": "listbox",
3897
3897
  "aria-expanded": isOpen,
@@ -3958,7 +3958,7 @@ var Select = /*#__PURE__*/React__default.forwardRef(function (_ref, forwardedRef
3958
3958
  // escapes any ancestor overflow:hidden|auto|scroll. Coordinates
3959
3959
  // are anchored to the trigger's viewport rect; width matches the
3960
3960
  // trigger; maxHeight is driven by available space.
3961
- style: _objectSpread$C({
3961
+ style: _objectSpread$D({
3962
3962
  left: menuCoords ? "".concat(menuCoords.left, "px") : undefined,
3963
3963
  top: menuCoords ? "".concat(menuCoords.top, "px") : undefined,
3964
3964
  width: menuCoords ? "".concat(menuCoords.width, "px") : undefined
@@ -4045,6 +4045,11 @@ var DEFAULT_ACTIONS = [{
4045
4045
  })
4046
4046
  }];
4047
4047
 
4048
+ function ownKeys$C(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; }
4049
+ function _objectSpread$C(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys$C(Object(t), true).forEach(function (r) { _defineProperty$4(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys$C(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
4050
+ function _createForOfIteratorHelper$1(r, e) { var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (!t) { if (Array.isArray(r) || (t = _unsupportedIterableToArray$1(r)) || e) { t && (r = t); var _n = 0, F = function F() {}; return { s: F, n: function n() { return _n >= r.length ? { done: true } : { done: false, value: r[_n++] }; }, e: function e(r) { throw r; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var o, a = true, u = false; return { s: function s() { t = t.call(r); }, n: function n() { var r = t.next(); return a = r.done, r; }, e: function e(r) { u = true, o = r; }, f: function f() { try { a || null == t["return"] || t["return"](); } finally { if (u) throw o; } } }; }
4051
+ function _unsupportedIterableToArray$1(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray$1(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray$1(r, a) : void 0; } }
4052
+ function _arrayLikeToArray$1(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
4048
4053
  /**
4049
4054
  * Generate a unique key for a row based on id, _id, or index
4050
4055
  */
@@ -4054,6 +4059,116 @@ var getRowKey = function getRowKey(row, globalIndex) {
4054
4059
  if (row._id !== undefined && row._id !== null) return String(row._id);
4055
4060
  return String(globalIndex);
4056
4061
  };
4062
+ /**
4063
+ * Resolve a value that may be supplied directly or as a per-row producer.
4064
+ * Used for an action's `label`, `icon`, `hidden` and `disabled`.
4065
+ */
4066
+ var callIfFn = function callIfFn(value, row, index) {
4067
+ return typeof value === "function" ? value(row, index) : value;
4068
+ };
4069
+ /**
4070
+ * Does THIS row get an expand toggle?
4071
+ * `hasDetails` is either a boolean (every row) or a `(row, index)` predicate.
4072
+ */
4073
+ var rowHasDetails = function rowHasDetails(hasDetails, row, index) {
4074
+ return typeof hasDetails === "function" ? !!hasDetails(row, index) : !!hasDetails;
4075
+ };
4076
+ /**
4077
+ * Best-effort accessible name for an action. `label` may be an arbitrary
4078
+ * ReactNode, so fall back to `name` and finally to a generic string.
4079
+ */
4080
+ var getActionLabelText = function getActionLabelText(action) {
4081
+ return typeof (action === null || action === void 0 ? void 0 : action.label) === "string" && action.label.trim() || typeof (action === null || action === void 0 ? void 0 : action.name) === "string" && action.name.trim() || "Action";
4082
+ };
4083
+ /**
4084
+ * Patch `defaults` with `overrides`, matched by `name`.
4085
+ *
4086
+ * Result order is the defaults' order, then any unmatched or unnamed overrides
4087
+ * appended. Each match is a shallow spread, so `{ name: "edit", onClick }`
4088
+ * keeps the default's `label` and `icon`, and `{ name: "delete", hidden: true }`
4089
+ * removes a default without needing a dedicated API.
4090
+ *
4091
+ * @param {Array} overrides consumer-supplied actions
4092
+ * @param {Array} defaults the built-in action set
4093
+ * @returns {Array}
4094
+ */
4095
+ var mergeDefaultActions = function mergeDefaultActions(overrides, defaults) {
4096
+ if (!Array.isArray(overrides)) return defaults;
4097
+ if (!Array.isArray(defaults) || defaults.length === 0) return overrides;
4098
+ var byName = new Map();
4099
+ var _iterator = _createForOfIteratorHelper$1(overrides),
4100
+ _step;
4101
+ try {
4102
+ for (_iterator.s(); !(_step = _iterator.n()).done;) {
4103
+ var action = _step.value;
4104
+ if (action && action.name) byName.set(action.name, action);
4105
+ }
4106
+ } catch (err) {
4107
+ _iterator.e(err);
4108
+ } finally {
4109
+ _iterator.f();
4110
+ }
4111
+ var merged = defaults.map(function (d) {
4112
+ return d !== null && d !== void 0 && d.name && byName.has(d.name) ? _objectSpread$C(_objectSpread$C({}, d), byName.get(d.name)) : d;
4113
+ });
4114
+ var defaultNames = new Set(defaults.map(function (d) {
4115
+ return d === null || d === void 0 ? void 0 : d.name;
4116
+ }).filter(Boolean));
4117
+ var appended = overrides.filter(function (a) {
4118
+ return a && (!a.name || !defaultNames.has(a.name));
4119
+ });
4120
+ return [].concat(_toConsumableArray$1(merged), _toConsumableArray$1(appended));
4121
+ };
4122
+ var EMPTY_RESOLVED = Object.freeze({
4123
+ inlineActions: Object.freeze([]),
4124
+ menuActions: Object.freeze([])
4125
+ });
4126
+ /**
4127
+ * Normalize the `actions` prop for a single row.
4128
+ *
4129
+ * Accepts either an array or a `(row, index) => array` producer. Entries whose
4130
+ * `hidden` resolves truthy are dropped; `label`/`icon` are resolved against the
4131
+ * row; `disabled` is coerced to a boolean; `inline` entries are split out so
4132
+ * they can render as icon buttons in the cell rather than inside the menu.
4133
+ *
4134
+ * `render` is deliberately passed through untouched — it is already a
4135
+ * `(row) => ReactNode` renderer with its own contract, not a value producer.
4136
+ *
4137
+ * @param {Array|Function} actions array, or (row, index) => array
4138
+ * @param {object} row
4139
+ * @param {number} index the GLOBAL row index (startIndex + rowIndexInPage)
4140
+ * @returns {{ inlineActions: Array, menuActions: Array }}
4141
+ */
4142
+ var resolveActions = function resolveActions(actions, row, index) {
4143
+ var source = typeof actions === "function" ? actions(row, index) : actions;
4144
+ if (!Array.isArray(source) || source.length === 0) return EMPTY_RESOLVED;
4145
+ var inlineActions = [];
4146
+ var menuActions = [];
4147
+ var _iterator2 = _createForOfIteratorHelper$1(source),
4148
+ _step2;
4149
+ try {
4150
+ for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
4151
+ var action = _step2.value;
4152
+ if (!action || _typeof$4(action) !== "object") continue;
4153
+ if (callIfFn(action.hidden, row, index)) continue;
4154
+ var resolved = _objectSpread$C(_objectSpread$C({}, action), {}, {
4155
+ label: callIfFn(action.label, row, index),
4156
+ icon: callIfFn(action.icon, row, index),
4157
+ disabled: !!callIfFn(action.disabled, row, index),
4158
+ inline: !!action.inline
4159
+ });
4160
+ (resolved.inline ? inlineActions : menuActions).push(resolved);
4161
+ }
4162
+ } catch (err) {
4163
+ _iterator2.e(err);
4164
+ } finally {
4165
+ _iterator2.f();
4166
+ }
4167
+ return {
4168
+ inlineActions: inlineActions,
4169
+ menuActions: menuActions
4170
+ };
4171
+ };
4057
4172
 
4058
4173
  /**
4059
4174
  * Custom hook to detect clicks outside of specified refs
@@ -4365,23 +4480,6 @@ function ActionMenu(_ref) {
4365
4480
  var maxMenuHeight = 320;
4366
4481
  var minMenuHeight = 80;
4367
4482
  var margin = 8;
4368
- useLayoutEffect(function () {
4369
- computePosition();
4370
- var handleResize = function handleResize() {
4371
- window.requestAnimationFrame(function () {
4372
- return computePosition();
4373
- });
4374
- };
4375
- var handleScroll = function handleScroll() {
4376
- onClose === null || onClose === void 0 || onClose();
4377
- };
4378
- window.addEventListener("resize", handleResize);
4379
- window.addEventListener("scroll", handleScroll, true);
4380
- return function () {
4381
- window.removeEventListener("resize", handleResize);
4382
- window.removeEventListener("scroll", handleScroll, true);
4383
- };
4384
- }, [anchorEl, actions, menuRef, onClose]);
4385
4483
  var computePosition = function computePosition() {
4386
4484
  if (!anchorEl || typeof window === "undefined") return;
4387
4485
  var rect = anchorEl.getBoundingClientRect();
@@ -4432,25 +4530,30 @@ function ActionMenu(_ref) {
4432
4530
  transformOrigin: transformOrigin,
4433
4531
  maxHeight: allowedMaxHeight,
4434
4532
  width: menuWidth,
4435
- opacity: 0.8
4533
+ opacity: 1
4436
4534
  });
4437
4535
  };
4438
- // measure & position before paint
4536
+ // Measure & position before paint. A single effect owns both listeners:
4537
+ // resize repositions the menu, scroll closes it (repositioning a portaled
4538
+ // menu against a scrolling ancestor is not worth the jank).
4439
4539
  useLayoutEffect(function () {
4440
4540
  computePosition();
4441
- var onScrollOrResize = function onScrollOrResize() {
4541
+ var handleResize = function handleResize() {
4442
4542
  window.requestAnimationFrame(function () {
4443
4543
  return computePosition();
4444
4544
  });
4445
4545
  };
4446
- window.addEventListener("resize", onScrollOrResize);
4447
- window.addEventListener("scroll", onScrollOrResize, true);
4546
+ var handleScroll = function handleScroll() {
4547
+ onClose === null || onClose === void 0 || onClose();
4548
+ };
4549
+ window.addEventListener("resize", handleResize);
4550
+ window.addEventListener("scroll", handleScroll, true);
4448
4551
  return function () {
4449
- window.removeEventListener("resize", onScrollOrResize);
4450
- window.removeEventListener("scroll", onScrollOrResize, true);
4552
+ window.removeEventListener("resize", handleResize);
4553
+ window.removeEventListener("scroll", handleScroll, true);
4451
4554
  };
4452
4555
  // recompute when anchor or actions change (content height may change)
4453
- }, [anchorEl, actions, menuRef]);
4556
+ }, [anchorEl, actions, menuRef, onClose]);
4454
4557
  // Render into body
4455
4558
  return /*#__PURE__*/createPortal(jsx("div", {
4456
4559
  ref: menuRef,
@@ -4472,32 +4575,34 @@ function ActionMenu(_ref) {
4472
4575
  children: !Array.isArray(actions) || actions.length === 0 ? jsx("div", {
4473
4576
  className: "px-3 py-2 text-sm text-primary-500",
4474
4577
  children: "No actions"
4475
- }) : actions.map(function (action) {
4578
+ }) : actions.map(function (action, idx) {
4579
+ var _action$name;
4580
+ var isDisabled = !!action.disabled;
4476
4581
  return jsx("div", {
4477
4582
  className: "px-1",
4478
- children: action.render ? jsx("button", {
4479
- className: cn$1("w-full text-left px-3 py-2 text-sm opacity-75 hover:opacity-100 flex items-center gap-2 rounded-md", menuBg, menuItemHover),
4480
- onClick: function onClick(e) {
4481
- e.stopPropagation();
4482
- onAction === null || onAction === void 0 || onAction(action, row);
4483
- onClose === null || onClose === void 0 || onClose();
4484
- },
4485
- children: action.render(row)
4486
- }) : jsxs("button", {
4487
- className: cn$1("w-full text-left px-3 py-2 text-sm opacity-75 hover:opacity-100 flex items-center gap-2 rounded-md", menuBg, menuItemHover),
4583
+ children: jsx("button", {
4584
+ type: "button",
4585
+ disabled: isDisabled,
4586
+ "aria-disabled": isDisabled || undefined,
4587
+ className: cn$1("w-full text-left px-3 py-2 text-sm flex items-center gap-2 rounded-md", menuBg, isDisabled ? "opacity-50 cursor-not-allowed" : ["opacity-75 hover:opacity-100", menuItemHover]),
4488
4588
  onClick: function onClick(e) {
4489
4589
  e.stopPropagation();
4590
+ // Belt-and-braces: `action.render` output may contain its
4591
+ // own clickable content that bypasses the `disabled` attr.
4592
+ if (isDisabled) return;
4490
4593
  onAction === null || onAction === void 0 || onAction(action, row);
4491
4594
  onClose === null || onClose === void 0 || onClose();
4492
4595
  },
4493
- children: [action.icon && jsx("span", {
4494
- className: "inline-flex",
4495
- children: action.icon
4496
- }), jsx("span", {
4497
- children: action.label
4498
- })]
4596
+ children: action.render ? action.render(row) : jsxs(Fragment, {
4597
+ children: [action.icon && jsx("span", {
4598
+ className: "inline-flex",
4599
+ children: action.icon
4600
+ }), jsx("span", {
4601
+ children: action.label
4602
+ })]
4603
+ })
4499
4604
  })
4500
- }, action.name);
4605
+ }, (_action$name = action.name) !== null && _action$name !== void 0 ? _action$name : "action-".concat(idx));
4501
4606
  })
4502
4607
  })
4503
4608
  }), document.body);
@@ -4518,6 +4623,7 @@ function TableRow(_ref) {
4518
4623
  theme = _ref.theme,
4519
4624
  onRowClick = _ref.onRowClick,
4520
4625
  hasDetails = _ref.hasDetails,
4626
+ hasDetailsColumn = _ref.hasDetailsColumn,
4521
4627
  showSerial = _ref.showSerial,
4522
4628
  selectable = _ref.selectable,
4523
4629
  visibleColumns = _ref.visibleColumns,
@@ -4541,6 +4647,15 @@ function TableRow(_ref) {
4541
4647
  var actionCellKey = "actions-".concat(key);
4542
4648
  var isSelected = selectedRows.has(key);
4543
4649
  var isExpanded = expandedRows.has(key);
4650
+ // Only this row's actions are resolved. Memoized so that opening one row's
4651
+ // menu (which re-renders every row) does not re-invoke a function-valued
4652
+ // `actions` prop for all the other rows.
4653
+ var _React$useMemo = React__default.useMemo(function () {
4654
+ return resolveActions(actionsToUse, row, globalIndex);
4655
+ }, [actionsToUse, row, globalIndex]),
4656
+ inlineActions = _React$useMemo.inlineActions,
4657
+ menuActions = _React$useMemo.menuActions;
4658
+ var showDetailsToggle = rowHasDetails(hasDetails, row, globalIndex);
4544
4659
  var extraRowClass = typeof rowClass === "function" ? rowClass({
4545
4660
  row: row,
4546
4661
  rowIndex: globalIndex
@@ -4560,14 +4675,16 @@ function TableRow(_ref) {
4560
4675
  onClick: function onClick() {
4561
4676
  return onRowClick === null || onRowClick === void 0 ? void 0 : onRowClick(row, globalIndex);
4562
4677
  },
4563
- children: [hasDetails && jsx("td", {
4678
+ children: [hasDetailsColumn && jsx("td", {
4564
4679
  className: "px-4 py-4 text-sm",
4565
- children: jsx("button", {
4680
+ children: showDetailsToggle && jsx("button", {
4681
+ type: "button",
4566
4682
  onClick: function onClick(e) {
4567
4683
  e.stopPropagation();
4568
4684
  toggleExpandRow(row, rowIndexInPage);
4569
4685
  },
4570
4686
  "aria-expanded": isExpanded,
4687
+ "aria-label": isExpanded ? "Collapse row details" : "Expand row details",
4571
4688
  className: "p-1 rounded hover:bg-gray-100",
4572
4689
  children: isExpanded ? "▾" : "▸"
4573
4690
  })
@@ -4607,36 +4724,58 @@ function TableRow(_ref) {
4607
4724
  return e.stopPropagation();
4608
4725
  },
4609
4726
  children: jsxs("div", {
4610
- className: "relative inline-block",
4611
- children: [jsx("button", {
4612
- ref: function ref(el) {
4613
- if (el) {
4614
- actionButtonRefs.current[actionCellKey] = el;
4615
- }
4616
- },
4617
- onClick: function onClick(e) {
4618
- return toggleActions(e, actionCellKey, row);
4619
- },
4620
- "aria-expanded": activeActionRowKey === actionCellKey,
4621
- className: "p-1 rounded hover:bg-gray-100",
4622
- title: "Actions",
4623
- children: jsx(MoreVertical, {
4624
- className: "h-4 w-4"
4625
- })
4626
- }), activeActionRowKey === actionCellKey && jsx(ActionMenu, {
4627
- actions: actionsToUse,
4628
- row: row,
4629
- onAction: function onAction(action) {
4630
- return handleOnAction(action, row);
4631
- },
4632
- menuRef: actionMenuRef,
4633
- anchorEl: activeAnchorEl,
4634
- onClose: closeActionMenu,
4635
- theme: theme
4727
+ className: "flex items-center justify-end gap-1",
4728
+ children: [inlineActions.map(function (action, idx) {
4729
+ var _action$icon, _action$name;
4730
+ var actionLabel = getActionLabelText(action);
4731
+ return jsx("button", {
4732
+ type: "button",
4733
+ title: actionLabel,
4734
+ "aria-label": actionLabel,
4735
+ disabled: action.disabled,
4736
+ onClick: function onClick(e) {
4737
+ e.stopPropagation();
4738
+ if (action.disabled) return;
4739
+ handleOnAction(action, row);
4740
+ },
4741
+ className: cn$1("p-1 rounded", action.disabled ? "opacity-50 cursor-not-allowed" : "hover:bg-gray-100"),
4742
+ children: action.render ? action.render(row) : (_action$icon = action.icon) !== null && _action$icon !== void 0 ? _action$icon : jsx("span", {
4743
+ className: "text-xs",
4744
+ children: actionLabel
4745
+ })
4746
+ }, (_action$name = action.name) !== null && _action$name !== void 0 ? _action$name : "inline-".concat(idx));
4747
+ }), menuActions.length > 0 && jsxs("div", {
4748
+ className: "relative inline-block",
4749
+ children: [jsx("button", {
4750
+ ref: function ref(el) {
4751
+ if (el) {
4752
+ actionButtonRefs.current[actionCellKey] = el;
4753
+ }
4754
+ },
4755
+ onClick: function onClick(e) {
4756
+ return toggleActions(e, actionCellKey, row);
4757
+ },
4758
+ "aria-expanded": activeActionRowKey === actionCellKey,
4759
+ className: "p-1 rounded hover:bg-gray-100",
4760
+ title: "Actions",
4761
+ children: jsx(MoreVertical, {
4762
+ className: "h-4 w-4"
4763
+ })
4764
+ }), activeActionRowKey === actionCellKey && jsx(ActionMenu, {
4765
+ actions: menuActions,
4766
+ row: row,
4767
+ onAction: function onAction(action) {
4768
+ return handleOnAction(action, row);
4769
+ },
4770
+ menuRef: actionMenuRef,
4771
+ anchorEl: activeAnchorEl,
4772
+ onClose: closeActionMenu,
4773
+ theme: theme
4774
+ })]
4636
4775
  })]
4637
4776
  })
4638
4777
  })]
4639
- }), hasDetails && isExpanded && DetailsComponent && jsx("tr", {
4778
+ }), showDetailsToggle && isExpanded && DetailsComponent && jsx("tr", {
4640
4779
  children: jsx("td", {
4641
4780
  colSpan: visibleCount,
4642
4781
  className: cn$1(_defineProperty$4(_defineProperty$4({
@@ -4688,6 +4827,14 @@ function MobileCard(_ref) {
4688
4827
  var actionCellKey = "actions-".concat(key);
4689
4828
  var isSelected = selectedRows.has(key);
4690
4829
  var isExpanded = expandedRows.has(key);
4830
+ var _React$useMemo = React__default.useMemo(function () {
4831
+ return resolveActions(actionsToUse, row, globalIndex);
4832
+ }, [actionsToUse, row, globalIndex]),
4833
+ inlineActions = _React$useMemo.inlineActions,
4834
+ menuActions = _React$useMemo.menuActions;
4835
+ // Unlike the desktop row there is no column grid to keep aligned, so a
4836
+ // non-qualifying row simply renders no toggle and no placeholder.
4837
+ var showDetailsToggle = rowHasDetails(hasDetails, row, globalIndex);
4691
4838
  var extraRowClass = typeof rowClass === "function" ? rowClass({
4692
4839
  row: row,
4693
4840
  rowIndex: globalIndex
@@ -4710,12 +4857,14 @@ function MobileCard(_ref) {
4710
4857
  className: "flex items-center justify-between p-4 border-b bg-gray-50",
4711
4858
  children: [jsxs("div", {
4712
4859
  className: "flex items-center gap-3",
4713
- children: [hasDetails && jsx("button", {
4860
+ children: [showDetailsToggle && jsx("button", {
4861
+ type: "button",
4714
4862
  onClick: function onClick(e) {
4715
4863
  e.stopPropagation();
4716
4864
  toggleExpandRow(row, rowIndexInPage);
4717
4865
  },
4718
4866
  "aria-expanded": isExpanded,
4867
+ "aria-label": isExpanded ? "Collapse row details" : "Expand row details",
4719
4868
  className: "p-1 rounded hover:bg-gray-200",
4720
4869
  children: isExpanded ? "▾" : "▸"
4721
4870
  }), selectable && jsx("input", {
@@ -4734,32 +4883,56 @@ function MobileCard(_ref) {
4734
4883
  children: ["#", globalIndex + 1]
4735
4884
  })]
4736
4885
  }), withAction && jsxs("div", {
4737
- className: "relative",
4738
- children: [jsx("button", {
4739
- ref: function ref(el) {
4740
- if (el) {
4741
- actionButtonRefs.current[actionCellKey] = el;
4742
- }
4743
- },
4744
- onClick: function onClick(e) {
4745
- return toggleActions(e, actionCellKey, row);
4746
- },
4747
- "aria-expanded": activeActionRowKey === actionCellKey,
4748
- className: "p-1.5 rounded hover:bg-gray-200",
4749
- title: "Actions",
4750
- children: jsx(MoreVertical, {
4751
- className: "h-4 w-4"
4752
- })
4753
- }), activeActionRowKey === actionCellKey && jsx(ActionMenu, {
4754
- actions: actionsToUse,
4755
- row: row,
4756
- onAction: function onAction(action) {
4757
- return handleOnAction(action, row);
4758
- },
4759
- menuRef: actionMenuRef,
4760
- anchorEl: activeAnchorEl,
4761
- onClose: closeActionMenu,
4762
- theme: theme
4886
+ className: "flex items-center gap-1",
4887
+ children: [inlineActions.map(function (action, idx) {
4888
+ var _action$icon, _action$name;
4889
+ var actionLabel = getActionLabelText(action);
4890
+ return jsx("button", {
4891
+ type: "button",
4892
+ title: actionLabel,
4893
+ "aria-label": actionLabel,
4894
+ disabled: action.disabled,
4895
+ onClick: function onClick(e) {
4896
+ // The card root binds onRowClick and there is no stopping
4897
+ // ancestor here, unlike the desktop actions <td>.
4898
+ e.stopPropagation();
4899
+ if (action.disabled) return;
4900
+ handleOnAction(action, row);
4901
+ },
4902
+ className: cn$1("p-1.5 rounded", action.disabled ? "opacity-50 cursor-not-allowed" : "hover:bg-gray-200"),
4903
+ children: action.render ? action.render(row) : (_action$icon = action.icon) !== null && _action$icon !== void 0 ? _action$icon : jsx("span", {
4904
+ className: "text-xs",
4905
+ children: actionLabel
4906
+ })
4907
+ }, (_action$name = action.name) !== null && _action$name !== void 0 ? _action$name : "inline-".concat(idx));
4908
+ }), menuActions.length > 0 && jsxs("div", {
4909
+ className: "relative",
4910
+ children: [jsx("button", {
4911
+ ref: function ref(el) {
4912
+ if (el) {
4913
+ actionButtonRefs.current[actionCellKey] = el;
4914
+ }
4915
+ },
4916
+ onClick: function onClick(e) {
4917
+ return toggleActions(e, actionCellKey, row);
4918
+ },
4919
+ "aria-expanded": activeActionRowKey === actionCellKey,
4920
+ className: "p-1.5 rounded hover:bg-gray-200",
4921
+ title: "Actions",
4922
+ children: jsx(MoreVertical, {
4923
+ className: "h-4 w-4"
4924
+ })
4925
+ }), activeActionRowKey === actionCellKey && jsx(ActionMenu, {
4926
+ actions: menuActions,
4927
+ row: row,
4928
+ onAction: function onAction(action) {
4929
+ return handleOnAction(action, row);
4930
+ },
4931
+ menuRef: actionMenuRef,
4932
+ anchorEl: activeAnchorEl,
4933
+ onClose: closeActionMenu,
4934
+ theme: theme
4935
+ })]
4763
4936
  })]
4764
4937
  })]
4765
4938
  }), jsx("div", {
@@ -4783,7 +4956,7 @@ function MobileCard(_ref) {
4783
4956
  })]
4784
4957
  }, column.key);
4785
4958
  })
4786
- }), hasDetails && isExpanded && DetailsComponent && jsx("div", {
4959
+ }), showDetailsToggle && isExpanded && DetailsComponent && jsx("div", {
4787
4960
  className: "border-t bg-gray-50 p-4",
4788
4961
  children: jsx(DetailsComponent, {
4789
4962
  row: row,
@@ -4793,7 +4966,7 @@ function MobileCard(_ref) {
4793
4966
  }, key);
4794
4967
  }
4795
4968
 
4796
- var _excluded$x = ["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", "theme", "responsiveBreakpoint", "serverSide", "totalRecords", "pageNumber", "onPageChange", "TheadComponent", "TfootComponent"];
4969
+ var _excluded$x = ["data", "columns", "sortable", "filterable", "selectable", "pagination", "pageSize", "onSort", "onFilter", "onFetch", "onFilterChange", "onSelectionChange", "onRowClick", "hasDetails", "DetailsComponent", "className", "withAction", "onAction", "actions", "replaceDefaultActions", "showSerial", "cellClass", "rowClass", "globalSearch", "limitOptions", "showLimitSelector", "onLimitChange", "showReloadButton", "renderReloadButton", "onReload", "stripedRows", "theme", "responsiveBreakpoint", "serverSide", "totalRecords", "pageNumber", "onPageChange", "TheadComponent", "TfootComponent"];
4797
4970
  function ownKeys$B(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; }
4798
4971
  function _objectSpread$B(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys$B(Object(t), true).forEach(function (r) { _defineProperty$4(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys$B(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
4799
4972
  var DEFAULT_DATA = [];
@@ -4835,6 +5008,8 @@ var Table = function Table(_ref) {
4835
5008
  withAction = _ref$withAction === void 0 ? true : _ref$withAction,
4836
5009
  onAction = _ref.onAction,
4837
5010
  actions = _ref.actions,
5011
+ _ref$replaceDefaultAc = _ref.replaceDefaultActions,
5012
+ replaceDefaultActions = _ref$replaceDefaultAc === void 0 ? false : _ref$replaceDefaultAc,
4838
5013
  _ref$showSerial = _ref.showSerial,
4839
5014
  showSerial = _ref$showSerial === void 0 ? true : _ref$showSerial,
4840
5015
  cellClass = _ref.cellClass,
@@ -4946,9 +5121,26 @@ var Table = function Table(_ref) {
4946
5121
  var actionMenuRef = useRef(null);
4947
5122
  var actionButtonRefs = useRef({});
4948
5123
  // Memoized values
5124
+ //
5125
+ // Supplied actions PATCH the built-in set by `name` (so `{ name: "edit",
5126
+ // onClick }` keeps the default label + icon) unless `replaceDefaultActions`
5127
+ // is set. Stays either an array or a `(row, index) => array` producer, and
5128
+ // keeps a stable identity so the per-row memo in TableRow/MobileCard pays off.
4949
5129
  var actionsToUse = useMemo(function () {
4950
- return actions !== undefined ? actions : DEFAULT_ACTIONS;
4951
- }, [actions]);
5130
+ if (actions === undefined) return DEFAULT_ACTIONS;
5131
+ if (replaceDefaultActions) return actions;
5132
+ if (typeof actions === "function") {
5133
+ return function (row, index) {
5134
+ return mergeDefaultActions(actions(row, index), DEFAULT_ACTIONS);
5135
+ };
5136
+ }
5137
+ return mergeDefaultActions(actions, DEFAULT_ACTIONS);
5138
+ }, [actions, replaceDefaultActions]);
5139
+ // `hasDetails` may be a predicate. The expand COLUMN exists whenever the prop
5140
+ // is truthy at all; whether a given row gets a toggle is decided per row.
5141
+ var hasDetailsColumn = useMemo(function () {
5142
+ return typeof hasDetails === "function" || !!hasDetails;
5143
+ }, [hasDetails]);
4952
5144
  // Refs for stable initial values
4953
5145
  var initialPageNumber = useRef(pageNumber);
4954
5146
  var initialColumnsRef = useRef(initialColumns);
@@ -5052,8 +5244,8 @@ var Table = function Table(_ref) {
5052
5244
  paginatedData = _useMemo.paginatedData,
5053
5245
  totalPages = _useMemo.totalPages;
5054
5246
  var visibleCount = useMemo(function () {
5055
- return (showSerial ? 1 : 0) + visibleColumns.length + (selectable ? 1 : 0) + (hasDetails ? 1 : 0) + (withAction ? 1 : 0) + 1;
5056
- }, [showSerial, visibleColumns.length, selectable, hasDetails, withAction]);
5247
+ return (showSerial ? 1 : 0) + visibleColumns.length + (selectable ? 1 : 0) + (hasDetailsColumn ? 1 : 0) + (withAction ? 1 : 0) + 1;
5248
+ }, [showSerial, visibleColumns.length, selectable, hasDetailsColumn, withAction]);
5057
5249
  var rowKeyMap = useMemo(function () {
5058
5250
  return new Map(filteredData.map(function (r, i) {
5059
5251
  return [getRowKey(r, i), r];
@@ -5243,6 +5435,7 @@ var Table = function Table(_ref) {
5243
5435
  stripedColors: stripedColorsArray,
5244
5436
  onRowClick: onRowClick,
5245
5437
  hasDetails: hasDetails,
5438
+ hasDetailsColumn: hasDetailsColumn,
5246
5439
  showSerial: showSerial,
5247
5440
  selectable: selectable,
5248
5441
  visibleColumns: Array.isArray(visibleColumns) ? visibleColumns : [],
@@ -5372,7 +5565,7 @@ var Table = function Table(_ref) {
5372
5565
  children: [jsxs("thead", {
5373
5566
  className: safeTheme.accentColor,
5374
5567
  children: [jsxs("tr", {
5375
- children: [hasDetails && jsx("th", {
5568
+ children: [hasDetailsColumn && jsx("th", {
5376
5569
  className: "w-8 px-4 py-3"
5377
5570
  }), showSerial && jsx("th", {
5378
5571
  className: "w-8 px-4 py-3 text-left text-xs font-medium text-primary-500 uppercase tracking-wider",
@@ -5432,7 +5625,7 @@ var Table = function Table(_ref) {
5432
5625
  className: "w-12 px-4 py-3"
5433
5626
  })]
5434
5627
  }), filterable && jsxs("tr", {
5435
- children: [hasDetails && jsx("th", {
5628
+ children: [hasDetailsColumn && jsx("th", {
5436
5629
  className: "pb-4"
5437
5630
  }), showSerial && jsx("th", {
5438
5631
  className: "pb-4"