@economic/taco 2.44.4 → 2.44.5-create.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (99) hide show
  1. package/dist/components/Provider/Localization.d.ts +2 -0
  2. package/dist/components/Report/Report.d.ts +1 -1
  3. package/dist/components/Table3/Table3.d.ts +2 -14
  4. package/dist/components/Table3/components/Columns/Internal/EditingActionsMenu.d.ts +1 -2
  5. package/dist/components/Table3/components/Editing/DiscardChangesConfirmationDialog.d.ts +7 -0
  6. package/dist/components/Table3/components/Row/Editing/CreateNewRow.d.ts +14 -0
  7. package/dist/components/Table3/components/Row/Editing/TemporaryRow.d.ts +11 -0
  8. package/dist/components/Table3/features/useEditingState.d.ts +28 -0
  9. package/dist/components/Table3/features/useTableEditing.d.ts +25 -36
  10. package/dist/components/Table3/listeners/useTableEditingListener.d.ts +1 -1
  11. package/dist/components/Table3/types.d.ts +23 -8
  12. package/dist/components/Table3/useTable3.d.ts +6 -0
  13. package/dist/components/Table3/util/editing.d.ts +7 -1
  14. package/dist/esm/index.css +28 -4
  15. package/dist/esm/node_modules/babel-plugin-transform-async-to-promises/helpers.mjs.js +17 -17
  16. package/dist/esm/node_modules/babel-plugin-transform-async-to-promises/helpers.mjs.js.map +1 -1
  17. package/dist/esm/packages/taco/src/components/ModeSwitch/ModeSwitch.js +2 -2
  18. package/dist/esm/packages/taco/src/components/ModeSwitch/ModeSwitch.js.map +1 -1
  19. package/dist/esm/packages/taco/src/components/Provider/Localization.js +5 -3
  20. package/dist/esm/packages/taco/src/components/Provider/Localization.js.map +1 -1
  21. package/dist/esm/packages/taco/src/components/Switch/Switch.js +1 -1
  22. package/dist/esm/packages/taco/src/components/Switch/Switch.js.map +1 -1
  23. package/dist/esm/packages/taco/src/components/Table3/Table3.js +20 -7
  24. package/dist/esm/packages/taco/src/components/Table3/Table3.js.map +1 -1
  25. package/dist/esm/packages/taco/src/components/Table3/components/Columns/Cell/Editing/RowMoveIndicator.js +1 -2
  26. package/dist/esm/packages/taco/src/components/Table3/components/Columns/Cell/Editing/RowMoveIndicator.js.map +1 -1
  27. package/dist/esm/packages/taco/src/components/Table3/components/Columns/Cell/EditingControlCell.js +25 -11
  28. package/dist/esm/packages/taco/src/components/Table3/components/Columns/Cell/EditingControlCell.js.map +1 -1
  29. package/dist/esm/packages/taco/src/components/Table3/components/Columns/Internal/EditingActionsMenu.js +5 -37
  30. package/dist/esm/packages/taco/src/components/Table3/components/Columns/Internal/EditingActionsMenu.js.map +1 -1
  31. package/dist/esm/packages/taco/src/components/Table3/components/Editing/Alert.js +17 -12
  32. package/dist/esm/packages/taco/src/components/Table3/components/Editing/Alert.js.map +1 -1
  33. package/dist/esm/packages/taco/src/components/Table3/components/Editing/DiscardChangesConfirmationDialog.js +34 -0
  34. package/dist/esm/packages/taco/src/components/Table3/components/Editing/DiscardChangesConfirmationDialog.js.map +1 -0
  35. package/dist/esm/packages/taco/src/components/Table3/components/Row/Editing/CreateNewRow.js +82 -0
  36. package/dist/esm/packages/taco/src/components/Table3/components/Row/Editing/CreateNewRow.js.map +1 -0
  37. package/dist/esm/packages/taco/src/components/Table3/components/Row/Editing/SaveStatus.js +2 -14
  38. package/dist/esm/packages/taco/src/components/Table3/components/Row/Editing/SaveStatus.js.map +1 -1
  39. package/dist/esm/packages/taco/src/components/Table3/components/Row/Editing/TemporaryRow.js +95 -0
  40. package/dist/esm/packages/taco/src/components/Table3/components/Row/Editing/TemporaryRow.js.map +1 -0
  41. package/dist/esm/packages/taco/src/components/Table3/components/Row/Row.js +39 -6
  42. package/dist/esm/packages/taco/src/components/Table3/components/Row/Row.js.map +1 -1
  43. package/dist/esm/packages/taco/src/components/Table3/components/Toolbar/Editing/Editing.js +4 -17
  44. package/dist/esm/packages/taco/src/components/Table3/components/Toolbar/Editing/Editing.js.map +1 -1
  45. package/dist/esm/packages/taco/src/components/Table3/features/useEditingState.js +512 -0
  46. package/dist/esm/packages/taco/src/components/Table3/features/useEditingState.js.map +1 -0
  47. package/dist/esm/packages/taco/src/components/Table3/features/useTableEditing.js +29 -406
  48. package/dist/esm/packages/taco/src/components/Table3/features/useTableEditing.js.map +1 -1
  49. package/dist/esm/packages/taco/src/components/Table3/listeners/useTableEditingListener.js +44 -33
  50. package/dist/esm/packages/taco/src/components/Table3/listeners/useTableEditingListener.js.map +1 -1
  51. package/dist/esm/packages/taco/src/components/Table3/useTable3.js +26 -9
  52. package/dist/esm/packages/taco/src/components/Table3/useTable3.js.map +1 -1
  53. package/dist/esm/packages/taco/src/components/Table3/util/editing.js +13 -23
  54. package/dist/esm/packages/taco/src/components/Table3/util/editing.js.map +1 -1
  55. package/dist/esm/packages/taco/src/primitives/Collection/components/Root.js +18 -2
  56. package/dist/esm/packages/taco/src/primitives/Collection/components/Root.js.map +1 -1
  57. package/dist/esm/packages/taco/src/primitives/Listbox2/components/Root.js +1 -0
  58. package/dist/esm/packages/taco/src/primitives/Listbox2/components/Root.js.map +1 -1
  59. package/dist/esm/packages/taco/src/primitives/Table/Core/Table.js +3 -4
  60. package/dist/esm/packages/taco/src/primitives/Table/Core/Table.js.map +1 -1
  61. package/dist/esm/packages/taco/src/primitives/Table/Core/components/Columns/Cell/BuiltIns/GroupedCell.js +9 -3
  62. package/dist/esm/packages/taco/src/primitives/Table/Core/components/Columns/Cell/BuiltIns/GroupedCell.js.map +1 -1
  63. package/dist/esm/packages/taco/src/primitives/Table/Core/components/Columns/Internal/Actions.js +6 -3
  64. package/dist/esm/packages/taco/src/primitives/Table/Core/components/Columns/Internal/Actions.js.map +1 -1
  65. package/dist/esm/packages/taco/src/primitives/Table/Core/components/Footer/Footer.js +1 -1
  66. package/dist/esm/packages/taco/src/primitives/Table/Core/components/Footer/Footer.js.map +1 -1
  67. package/dist/esm/packages/taco/src/primitives/Table/Core/components/Row/BuiltIns/DisplayRow.js +1 -1
  68. package/dist/esm/packages/taco/src/primitives/Table/Core/components/Row/BuiltIns/DisplayRow.js.map +1 -1
  69. package/dist/esm/packages/taco/src/primitives/Table/Core/features/useTableRenderer.js +25 -7
  70. package/dist/esm/packages/taco/src/primitives/Table/Core/features/useTableRenderer.js.map +1 -1
  71. package/dist/esm/packages/taco/src/primitives/Table/Core/useTable.js +2 -2
  72. package/dist/esm/packages/taco/src/primitives/Table/Core/useTable.js.map +1 -1
  73. package/dist/esm/packages/taco/src/primitives/Table/types.js.map +1 -1
  74. package/dist/esm/packages/taco/src/primitives/Table/useTableManager/useTableManager.js +1 -1
  75. package/dist/esm/packages/taco/src/primitives/Table/useTableManager/useTableManager.js.map +1 -1
  76. package/dist/esm/packages/taco/src/primitives/Table/useTableManager/util/setup.js +11 -0
  77. package/dist/esm/packages/taco/src/primitives/Table/useTableManager/util/setup.js.map +1 -1
  78. package/dist/esm/packages/taco/src/utils/dom.js +7 -4
  79. package/dist/esm/packages/taco/src/utils/dom.js.map +1 -1
  80. package/dist/index.css +28 -4
  81. package/dist/primitives/Collection/components/Root.d.ts +2 -0
  82. package/dist/primitives/Table/Core/Table.d.ts +1 -0
  83. package/dist/primitives/Table/Core/components/Columns/Internal/Actions.d.ts +3 -1
  84. package/dist/primitives/Table/Core/components/Footer/Footer.d.ts +2 -2
  85. package/dist/primitives/Table/Core/features/useTableRenderer.d.ts +2 -2
  86. package/dist/primitives/Table/Core/features/useTableStyle.d.ts +1 -1
  87. package/dist/primitives/Table/Core/types.d.ts +3 -0
  88. package/dist/primitives/Table/Core/useTable.d.ts +2 -2
  89. package/dist/primitives/Table/types.d.ts +1 -1
  90. package/dist/primitives/Table/useTableManager/useTableManager.d.ts +1 -1
  91. package/dist/taco.cjs.development.js +983 -669
  92. package/dist/taco.cjs.development.js.map +1 -1
  93. package/dist/taco.cjs.production.min.js +1 -1
  94. package/dist/taco.cjs.production.min.js.map +1 -1
  95. package/dist/utils/dom.d.ts +1 -0
  96. package/package.json +3 -5
  97. package/dist/components/Table3/components/Row/Editing/CreateRowButton.d.ts +0 -11
  98. package/dist/esm/packages/taco/src/components/Table3/components/Row/Editing/CreateRowButton.js +0 -90
  99. package/dist/esm/packages/taco/src/components/Table3/components/Row/Editing/CreateRowButton.js.map +0 -1
@@ -43,7 +43,8 @@ var set = _interopDefault(require('lodash/set'));
43
43
  var unset = _interopDefault(require('lodash/unset'));
44
44
  var compact = _interopDefault(require('lodash/compact'));
45
45
  var pullAt = _interopDefault(require('lodash/pullAt'));
46
- var lodash = require('lodash');
46
+ var omit = _interopDefault(require('lodash/omit'));
47
+ var setWith = _interopDefault(require('lodash/setWith'));
47
48
  var TabsPrimitive = require('@radix-ui/react-tabs');
48
49
  var Joyride = require('react-joyride');
49
50
  var Joyride__default = _interopDefault(Joyride);
@@ -4205,7 +4206,7 @@ const getOverlaySelector = element => {
4205
4206
  return undefined;
4206
4207
  }
4207
4208
  };
4208
- function isElementInsideOrTriggeredFromContainer(element, container) {
4209
+ function isElementTriggeredFromContainer(element, container) {
4209
4210
  var _getOverlaySelector, _element$closest;
4210
4211
  const selector = (_getOverlaySelector = getOverlaySelector(element)) !== null && _getOverlaySelector !== void 0 ? _getOverlaySelector : getOverlaySelector((_element$closest = element === null || element === void 0 ? void 0 : element.closest('[role=dialog],[role=menu]')) !== null && _element$closest !== void 0 ? _element$closest : null);
4211
4212
  if (selector) {
@@ -4215,11 +4216,14 @@ function isElementInsideOrTriggeredFromContainer(element, container) {
4215
4216
  const elementInDocument = document.querySelector(selector);
4216
4217
  // if the element does exist, see if it is itself connected to somethng that was triggered from the container
4217
4218
  if (elementInDocument) {
4218
- return isElementInsideOrTriggeredFromContainer(elementInDocument, container);
4219
+ return isElementTriggeredFromContainer(elementInDocument, container);
4219
4220
  }
4220
4221
  return false;
4221
4222
  }
4222
- return !!(container !== null && container !== void 0 && container.contains(element));
4223
+ return false;
4224
+ }
4225
+ function isElementInsideOrTriggeredFromContainer(element, container) {
4226
+ return isElementTriggeredFromContainer(element, container) || !!(container !== null && container !== void 0 && container.contains(element));
4223
4227
  }
4224
4228
  function isElementInsideOverlay(element) {
4225
4229
  return !!(element !== null && element !== void 0 && element.closest('[role=dialog],[role=menu]'));
@@ -4713,7 +4717,9 @@ const defaultLocalisationTexts = {
4713
4717
  tooltip: 'Edit table'
4714
4718
  },
4715
4719
  create: {
4716
- label: 'New'
4720
+ label: 'New',
4721
+ disabled: 'Existing new row must be saved',
4722
+ saving: 'Saving...'
4717
4723
  }
4718
4724
  },
4719
4725
  clearChangesConfirmationDialog: {
@@ -4735,8 +4741,8 @@ const defaultLocalisationTexts = {
4735
4741
  },
4736
4742
  validation: {
4737
4743
  alert: {
4738
- titleOne: '[COUNT] unsaved entry:',
4739
- titlePlural: '[COUNT] unsaved entries:',
4744
+ titleOne: '[COUNT] unsaved row:',
4745
+ titlePlural: '[COUNT] unsaved rows:',
4740
4746
  messageOne: "[COLUMN] [ROW] is incomplete and hasn't been saved.",
4741
4747
  messagePlural: "[COLUMN] [ROW] are incomplete and haven't been saved.",
4742
4748
  messageRow: 'Row',
@@ -7632,7 +7638,7 @@ const Switch = /*#__PURE__*/React.forwardRef(function Switch(props, ref) {
7632
7638
  onCheckedChange: onChange,
7633
7639
  ref: ref
7634
7640
  }), /*#__PURE__*/React.createElement(PrimitiveSwitch.Thumb, {
7635
- className: "'will-change-transform mt-0.5 h-4 w-4 translate-x-[0.15rem] rounded-full bg-white transition-transform group-disabled:opacity-50 group-aria-checked:translate-x-[1.1rem]"
7641
+ className: "pointer-events-none mt-0.5 h-4 w-4 translate-x-[0.15rem] rounded-full bg-white transition-transform will-change-transform group-disabled:opacity-50 group-aria-checked:translate-x-[1.1rem]"
7636
7642
  }));
7637
7643
  if (label) {
7638
7644
  const labelContainerClassName = cn('flex self-start cursor-pointer', {
@@ -8692,10 +8698,10 @@ const ModeSwitch = /*#__PURE__*/React.forwardRef(function ModeSwitch(props, ref)
8692
8698
  onCheckedChange: onChange,
8693
8699
  ref: ref
8694
8700
  }), /*#__PURE__*/React.createElement(PrimitiveSwitch.Thumb, {
8695
- className: "'will-change-transform flex h-6 w-6 items-center justify-center rounded-full bg-white transition-transform group-disabled:opacity-50 group-aria-checked:translate-x-[100%]"
8701
+ className: "pointer-events-none flex h-6 w-6 items-center justify-center rounded-full bg-white transition-transform will-change-transform group-disabled:opacity-50 group-aria-checked:translate-x-[100%]"
8696
8702
  }, /*#__PURE__*/React.createElement(Icon, {
8697
8703
  name: "edit-simple",
8698
- className: "!h-5 !w-5"
8704
+ className: "pointer-events-none !h-5 !w-5"
8699
8705
  })));
8700
8706
  });
8701
8707
  ModeSwitch.displayName = 'ModeSwitch';
@@ -10398,6 +10404,15 @@ function configureReactTableOptions(options, props, localization) {
10398
10404
  // We don't want to expose internal Tanstack Table row, so we need to wrap enableRowSelection callback into additional function,
10399
10405
  // which receives the React Table Row object and passes row.original to a callback.
10400
10406
  const reactTableEnableRowSelection = typeof options.enableRowSelection === 'function' ? row => options.enableRowSelection(row.original) : options.enableRowSelection;
10407
+ let getRowId;
10408
+ if (props.rowIdentityAccessor) {
10409
+ getRowId = (originalRow, index) => {
10410
+ if (originalRow) {
10411
+ return String(originalRow[props.rowIdentityAccessor]);
10412
+ }
10413
+ return String(index);
10414
+ };
10415
+ }
10401
10416
  const tableOptions = {
10402
10417
  defaultColumn: {
10403
10418
  enableColumnFilter: options.enableFiltering || true,
@@ -10416,11 +10431,13 @@ function configureReactTableOptions(options, props, localization) {
10416
10431
  enableGrouping: true,
10417
10432
  enableHiding: (_options$enableColumn2 = options.enableColumnHiding) !== null && _options$enableColumn2 !== void 0 ? _options$enableColumn2 : false,
10418
10433
  enablePinning: (_options$enableColumn3 = options.enableColumnFreezing) !== null && _options$enableColumn3 !== void 0 ? _options$enableColumn3 : false,
10434
+ enableRowPinning: true,
10419
10435
  enableRowSelection: reactTableEnableRowSelection !== null && reactTableEnableRowSelection !== void 0 ? reactTableEnableRowSelection : false,
10420
10436
  enableSorting: (_options$enableSortin = options.enableSorting) !== null && _options$enableSortin !== void 0 ? _options$enableSortin : false,
10421
10437
  // models for default features
10422
10438
  getExpandedRowModel: reactTable.getExpandedRowModel(),
10423
10439
  getGroupedRowModel: reactTable.getGroupedRowModel(),
10440
+ getRowId,
10424
10441
  groupedColumnMode: false
10425
10442
  };
10426
10443
  if (tableOptions.enableColumnResizing) {
@@ -10964,13 +10981,13 @@ function useTableSearch(isEnabled = false, defaultEnableGlobalFilter = false) {
10964
10981
  }
10965
10982
 
10966
10983
  // A type of promise-like that resolves synchronously and supports only one observer
10967
- const _Pact = /*#__PURE__*/function () {
10984
+ var _Pact = /*#__PURE__*/function () {
10968
10985
  function _Pact() {}
10969
10986
  _Pact.prototype.then = function (onFulfilled, onRejected) {
10970
- const result = new _Pact();
10971
- const state = this.s;
10987
+ var result = new _Pact();
10988
+ var state = this.s;
10972
10989
  if (state) {
10973
- const callback = state & 1 ? onFulfilled : onRejected;
10990
+ var callback = state & 1 ? onFulfilled : onRejected;
10974
10991
  if (callback) {
10975
10992
  try {
10976
10993
  _settle(result, 1, callback(this.v));
@@ -10984,7 +11001,7 @@ const _Pact = /*#__PURE__*/function () {
10984
11001
  }
10985
11002
  this.o = function (_this) {
10986
11003
  try {
10987
- const value = _this.v;
11004
+ var value = _this.v;
10988
11005
  if (_this.s & 1) {
10989
11006
  _settle(result, 1, onFulfilled ? onFulfilled(value) : value);
10990
11007
  } else if (onRejected) {
@@ -11021,7 +11038,7 @@ function _settle(pact, state, value) {
11021
11038
  }
11022
11039
  pact.s = state;
11023
11040
  pact.v = value;
11024
- const observer = pact.o;
11041
+ var observer = pact.o;
11025
11042
  if (observer) {
11026
11043
  observer(pact);
11027
11044
  }
@@ -11061,17 +11078,13 @@ function _forTo(array, body, check) {
11061
11078
  _cycle();
11062
11079
  return pact;
11063
11080
  }
11064
- const _iteratorSymbol = /*#__PURE__*/typeof Symbol !== "undefined" ? Symbol.iterator || (Symbol.iterator = /*#__PURE__*/Symbol("Symbol.iterator")) : "@@iterator";
11081
+ var _iteratorSymbol = /*#__PURE__*/typeof Symbol !== "undefined" ? Symbol.iterator || (Symbol.iterator = /*#__PURE__*/Symbol("Symbol.iterator")) : "@@iterator";
11065
11082
 
11066
11083
  // Asynchronously iterate through an object's values
11067
11084
  // Uses for...of if the runtime supports it, otherwise iterates until length on a copy
11068
11085
  function _forOf(target, body, check) {
11069
11086
  if (typeof target[_iteratorSymbol] === "function") {
11070
- var iterator = target[_iteratorSymbol](),
11071
- step,
11072
- pact,
11073
- reject;
11074
- function _cycle(result) {
11087
+ var _cycle = function _cycle(result) {
11075
11088
  try {
11076
11089
  while (!(step = iterator.next()).done && (!check || !check())) {
11077
11090
  result = body(step.value);
@@ -11092,13 +11105,17 @@ function _forOf(target, body, check) {
11092
11105
  } catch (e) {
11093
11106
  _settle(pact || (pact = new _Pact()), 2, e);
11094
11107
  }
11095
- }
11108
+ };
11109
+ var iterator = target[_iteratorSymbol](),
11110
+ step,
11111
+ pact,
11112
+ reject;
11096
11113
  _cycle();
11097
- if (iterator.return) {
11098
- var _fixup = function (value) {
11114
+ if (iterator["return"]) {
11115
+ var _fixup = function _fixup(value) {
11099
11116
  try {
11100
11117
  if (!step.done) {
11101
- iterator.return();
11118
+ iterator["return"]();
11102
11119
  }
11103
11120
  } catch (e) {}
11104
11121
  return value;
@@ -11125,7 +11142,7 @@ function _forOf(target, body, check) {
11125
11142
  return body(values[i]);
11126
11143
  }, check);
11127
11144
  }
11128
- const _asyncIteratorSymbol = /*#__PURE__*/typeof Symbol !== "undefined" ? Symbol.asyncIterator || (Symbol.asyncIterator = /*#__PURE__*/Symbol("Symbol.asyncIterator")) : "@@asyncIterator";
11145
+ var _asyncIteratorSymbol = /*#__PURE__*/typeof Symbol !== "undefined" ? Symbol.asyncIterator || (Symbol.asyncIterator = /*#__PURE__*/Symbol("Symbol.asyncIterator")) : "@@asyncIterator";
11129
11146
 
11130
11147
  // Asynchronously call a function and send errors to recovery continuation
11131
11148
  function _catch(body, recover) {
@@ -11753,7 +11770,7 @@ function useTableManager(props, meta, internalColumns) {
11753
11770
  rowDrag,
11754
11771
  rowDrop: rowDrop,
11755
11772
  rowExpansion: rowExpansion,
11756
- rowIdentityColumnId: props.rowIdentityColumnId,
11773
+ rowIdentityAccessor: props.rowIdentityAccessor,
11757
11774
  rowGoto,
11758
11775
  rowGroups: rowGroups,
11759
11776
  rowHeight,
@@ -12118,11 +12135,31 @@ function Row(props) {
12118
12135
  })));
12119
12136
  }
12120
12137
 
12121
- function useTableRenderer(renderers, table, tableRef, defaultRowActiveIndex) {
12122
- var _table$getState$group, _virtualItems$padding, _virtualItems$padding2, _virtualItems$padding3, _ref, _virtualItems;
12138
+ // scroll padding end is designed to always show half of the next row
12139
+ function getScrollPaddingEndOffset(table, options) {
12140
+ var _options$virtualiserP;
12141
+ const tableMeta = table.options.meta;
12142
+ let offset = 2 + ((_options$virtualiserP = options === null || options === void 0 ? void 0 : options.virtualiserPaddingEndOffset) !== null && _options$virtualiserP !== void 0 ? _options$virtualiserP : 0);
12143
+ if (tableMeta.footer.isEnabled) {
12144
+ offset += 1;
12145
+ }
12146
+ if (table.getHeaderGroups().length > 1) {
12147
+ offset += table.getHeaderGroups().length - 1;
12148
+ }
12149
+ let height = ROW_HEIGHT_ESTIMATES.medium * offset;
12150
+ const bottomRows = table.getBottomRows();
12151
+ if (bottomRows.length) {
12152
+ // 1.4 offsets for half rows and also accounts for increased row heights (which is likely in pinned rows)
12153
+ height += ROW_HEIGHT_ESTIMATES[tableMeta.rowHeight.height] * 1.4 * bottomRows.length;
12154
+ }
12155
+ return height;
12156
+ }
12157
+ function useTableRenderer(renderers, table, tableRef, defaultRowActiveIndex, options) {
12158
+ var _table$getState$group, _table$getCenterRows, _table$getBottomRows, _virtualItems$padding, _virtualItems$padding2, _virtualItems$padding3, _ref, _virtualItems;
12123
12159
  const tableMeta = table.options.meta;
12124
- const rows = table.getRowModel().rows;
12125
12160
  const isTableRowGrouped = !!((_table$getState$group = table.getState().grouping) !== null && _table$getState$group !== void 0 && _table$getState$group.length);
12161
+ const rows = (_table$getCenterRows = table.getCenterRows()) !== null && _table$getCenterRows !== void 0 ? _table$getCenterRows : [];
12162
+ const bottomRows = (_table$getBottomRows = table.getBottomRows()) !== null && _table$getBottomRows !== void 0 ? _table$getBottomRows : [];
12126
12163
  // expanded rows
12127
12164
  const {
12128
12165
  createRowMeasurer,
@@ -12132,9 +12169,6 @@ function useTableRenderer(renderers, table, tableRef, defaultRowActiveIndex) {
12132
12169
  const rangeExtractor = useRowGroupVirtualisation(table);
12133
12170
  // account for thead and tfoot in the scroll area - both are always medium row height
12134
12171
  const scrollPaddingStart = ROW_HEIGHT_ESTIMATES.medium;
12135
- // column groups offset the bottom padding :shrug:, multiplying by 1.5 ensures the bottom padding remains
12136
- // consistent when there are groups and when there aren't. 1.5 is relatively arbitrary, but it gives alignment
12137
- const scrollPaddingEnd = ROW_HEIGHT_ESTIMATES.medium * (table.getHeaderGroups().length > 1 ? 1.5 : 1);
12138
12172
  const virtualiser = reactVirtual.useVirtualizer({
12139
12173
  count: rows.length,
12140
12174
  estimateSize,
@@ -12143,7 +12177,8 @@ function useTableRenderer(renderers, table, tableRef, defaultRowActiveIndex) {
12143
12177
  rangeExtractor,
12144
12178
  // correctly sets the scroll padding offset, e.g. when keyboard navigating rows in the list
12145
12179
  scrollPaddingStart,
12146
- scrollPaddingEnd: tableMeta.footer.isEnabled ? scrollPaddingEnd * 2 : scrollPaddingEnd
12180
+ scrollPaddingEnd: getScrollPaddingEndOffset(table, options),
12181
+ paddingEnd: ROW_HEIGHT_ESTIMATES.medium * bottomRows.length
12147
12182
  });
12148
12183
  const totalSize = virtualiser.getTotalSize();
12149
12184
  const virtualItems = virtualiser.getVirtualItems();
@@ -12300,12 +12335,14 @@ function Actions$1(props) {
12300
12335
  actionsLength,
12301
12336
  data,
12302
12337
  isActiveRow,
12303
- rowId
12338
+ rowId,
12339
+ table
12304
12340
  } = props;
12305
12341
  const {
12306
12342
  texts
12307
12343
  } = useLocalization();
12308
- const visibleActions = actions.map(action => action(data, rowId)).filter(action => !!action);
12344
+ // we don't want to document passing table, so it isn't on the type
12345
+ const visibleActions = actions.map(action => action(data, rowId, table)).filter(action => !!action);
12309
12346
  const actionsOnRow = visibleActions.length === actionsLength ? visibleActions : visibleActions.slice(0, actionsLength - 1);
12310
12347
  const actionsInMenu = visibleActions.slice(visibleActions.length === actionsLength ? actionsLength : actionsLength - 1);
12311
12348
  const className = cn('flex justify-end text-right bg-[inherit] shadow-[-6px_0px_6px_var(--table-row-actions-shadow)] print:hidden');
@@ -12361,7 +12398,8 @@ const Cell = /*#__PURE__*/React__default.memo(function MemoedCell(context) {
12361
12398
  actionsLength: actionsLength,
12362
12399
  data: row.original,
12363
12400
  isActiveRow: isActiveRow,
12364
- rowId: row.id
12401
+ rowId: row.id,
12402
+ table: table
12365
12403
  });
12366
12404
  }
12367
12405
  return null;
@@ -12611,13 +12649,13 @@ const INTERNAL_RENDERERS = {
12611
12649
  rowExpansion: renderer$2,
12612
12650
  rowSelection: renderer$3
12613
12651
  };
12614
- function useTable(props, externalRef, renderers, meta) {
12652
+ function useTable(props, externalRef, renderers, meta, options) {
12615
12653
  // create a ref and merge with the consumer's ref
12616
12654
  const ref = useMergedRef(externalRef);
12617
12655
  // configure the table
12618
12656
  const manager = useTableManager(props, meta, INTERNAL_RENDERERS);
12619
12657
  // configure the virtualised renderer
12620
- const renderer = useTableRenderer(renderers, manager.instance, ref, props.defaultRowActiveIndex);
12658
+ const renderer = useTableRenderer(renderers, manager.instance, ref, props.defaultRowActiveIndex, options);
12621
12659
  // configure dynamic styling
12622
12660
  const {
12623
12661
  style,
@@ -12718,7 +12756,10 @@ function GroupedCell(props) {
12718
12756
  index,
12719
12757
  isHighlighted
12720
12758
  } = props;
12721
- const tableMeta = cell.getContext().table.options.meta;
12759
+ const {
12760
+ table
12761
+ } = cell.getContext();
12762
+ const tableMeta = table.options.meta;
12722
12763
  const columnMeta = cell.column.columnDef.meta;
12723
12764
  const attributes = getCellAttributes(cell, index, isHighlighted);
12724
12765
  const {
@@ -12736,7 +12777,8 @@ function GroupedCell(props) {
12736
12777
  colSpan: colSpan,
12737
12778
  rowActions: tableMeta.rowGroups.rowActionsForGroup,
12738
12779
  rowId: cell.row.id,
12739
- subRows: subRows
12780
+ subRows: subRows,
12781
+ table: table
12740
12782
  }), content);
12741
12783
  }
12742
12784
  const MemoedGroupedCell = /*#__PURE__*/React__default.memo(function MemoedGroupedCell(props) {
@@ -12748,6 +12790,7 @@ const MemoedGroupedCell = /*#__PURE__*/React__default.memo(function MemoedGroupe
12748
12790
  rowActions,
12749
12791
  rowId,
12750
12792
  subRows,
12793
+ table,
12751
12794
  ...attributes
12752
12795
  } = props;
12753
12796
  return /*#__PURE__*/React__default.createElement("td", Object.assign({}, attributes, {
@@ -12762,7 +12805,8 @@ const MemoedGroupedCell = /*#__PURE__*/React__default.memo(function MemoedGroupe
12762
12805
  actionsLength: 4,
12763
12806
  data: subRows,
12764
12807
  isActiveRow: true,
12765
- rowId: rowId
12808
+ rowId: rowId,
12809
+ table: table
12766
12810
  })) : null);
12767
12811
  });
12768
12812
 
@@ -12902,7 +12946,7 @@ const DisplayRow = /*#__PURE__*/React__default.memo(function DisplayRow(props) {
12902
12946
  const expansionRef = React__default.useRef(null);
12903
12947
  const isExpanded = !!attributes['data-row-expanded'];
12904
12948
  useSetVirtualisedRowHeight(measureRow, ref.current, expansionRef.current, isExpanded);
12905
- const className = cn('group/row', {
12949
+ const className = cn('group/row', otherAttributes.className, {
12906
12950
  'hover:cursor-grab': tableMeta.rowDrag.isEnabled && typeof attributes.onClick !== 'function',
12907
12951
  'hover:cursor-pointer': typeof attributes.onClick === 'function'
12908
12952
  });
@@ -13696,7 +13740,7 @@ function Summary(props) {
13696
13740
 
13697
13741
  function Foot(props) {
13698
13742
  const nonGroupedHeaders = props.table.getFooterGroups()[0].headers.filter(header => !header.column.getIsGrouped());
13699
- return /*#__PURE__*/React__default.createElement("tfoot", null, /*#__PURE__*/React__default.createElement("tr", null, nonGroupedHeaders.map((header, index) => (/*#__PURE__*/React__default.createElement(Footer$3, {
13743
+ return /*#__PURE__*/React__default.createElement("tfoot", null, props.children, /*#__PURE__*/React__default.createElement("tr", null, nonGroupedHeaders.map((header, index) => (/*#__PURE__*/React__default.createElement(Footer$3, {
13700
13744
  key: header.id,
13701
13745
  header: header,
13702
13746
  index: index
@@ -14386,6 +14430,7 @@ const getOptionsFromCollection = (collection, selector) => collection.querySelec
14386
14430
  const Root = /*#__PURE__*/React__default.forwardRef(function CollectionRoot(props, ref) {
14387
14431
  const {
14388
14432
  querySelector,
14433
+ resetOnChange,
14389
14434
  tabIndex = 0,
14390
14435
  ...otherProps
14391
14436
  } = props;
@@ -14416,6 +14461,21 @@ const Root = /*#__PURE__*/React__default.forwardRef(function CollectionRoot(prop
14416
14461
  internalRef.current.setActiveIndexByElement = setActiveIndexByElement;
14417
14462
  }
14418
14463
  }, [internalRef.current]);
14464
+ React__default.useEffect(() => {
14465
+ if (internalRef.current) {
14466
+ const selected = internalRef.current.querySelectorAll(`[aria-current="true"]`);
14467
+ const options = getOptionsFromCollection(internalRef.current, querySelector);
14468
+ if (options.length && selected.length === 1) {
14469
+ const firstSelected = internalRef.current.querySelector(`[aria-selected]`);
14470
+ if (firstSelected) {
14471
+ const selectedIndex = Array.from(options).indexOf(firstSelected);
14472
+ if (selectedIndex > -1) {
14473
+ setActiveOption(selectedIndex, internalRef.current, firstSelected);
14474
+ }
14475
+ }
14476
+ }
14477
+ }
14478
+ }, [resetOnChange]);
14419
14479
  React__default.useEffect(() => {
14420
14480
  if (internalRef.current) {
14421
14481
  const options = getOptionsFromCollection(internalRef.current, querySelector);
@@ -14427,8 +14487,8 @@ const Root = /*#__PURE__*/React__default.forwardRef(function CollectionRoot(prop
14427
14487
  }
14428
14488
  // if one item is selected, make sure it's current
14429
14489
  if (selected.length === 1) {
14430
- const firstSelected = internalRef.current.querySelector(`[aria-selected]`);
14431
- if (firstSelected) {
14490
+ if (options) {
14491
+ const firstSelected = selected.item(0);
14432
14492
  const selectedIndex = Array.from(options).indexOf(firstSelected);
14433
14493
  if (selectedIndex > -1) {
14434
14494
  setActiveOption(selectedIndex, internalRef.current, firstSelected);
@@ -14571,6 +14631,7 @@ const Root$1 = /*#__PURE__*/React__default.forwardRef(function Listbox2(props, r
14571
14631
  id: id,
14572
14632
  querySelector: customSelector ? `${DEFAULT_SELECTOR}, ${customSelector}` : DEFAULT_SELECTOR,
14573
14633
  ref: ref,
14634
+ resetOnChange: value,
14574
14635
  role: "listbox"
14575
14636
  }), children)));
14576
14637
  });
@@ -16755,6 +16816,7 @@ function TableGrid(props) {
16755
16816
  var _table$state$grouping;
16756
16817
  const {
16757
16818
  enableHorizontalArrowKeyNavigation,
16819
+ rowsForFooter,
16758
16820
  table,
16759
16821
  ...attributes
16760
16822
  } = props;
@@ -16762,8 +16824,6 @@ function TableGrid(props) {
16762
16824
  table.meta.rowActive.handleFocus(event, table.meta.length, table.renderer.scrollToIndex);
16763
16825
  } : undefined;
16764
16826
  const filterReason = getFilterReason(table);
16765
- const searchNotApplied = !table.state.globalFilter || table.state.globalFilter === '';
16766
- const filtersNotApplied = !table.state.columnFilters || table.state.columnFilters.length === 0;
16767
16827
  return /*#__PURE__*/React__default.createElement(React__default.Fragment, null, /*#__PURE__*/React__default.createElement("style", null, table.stylesheet), /*#__PURE__*/React__default.createElement(focus.FocusScope, null, /*#__PURE__*/React__default.createElement("table", Object.assign({}, attributes, {
16768
16828
  id: table.id,
16769
16829
  "data-table-font-size": table.meta.fontSize.size,
@@ -16796,9 +16856,9 @@ function TableGrid(props) {
16796
16856
  ...table.renderer.style,
16797
16857
  height: table.renderer.style.height + ROW_HEIGHT_ESTIMATES[table.meta.rowHeight.height]
16798
16858
  } : table.renderer.style
16799
- }, table.renderer.rows, searchNotApplied && filtersNotApplied && props.children), table.meta.footer.isEnabled ? /*#__PURE__*/React__default.createElement(Foot, {
16859
+ }, table.renderer.rows, props.children), table.meta.footer.isEnabled ? /*#__PURE__*/React__default.createElement(Foot, {
16800
16860
  table: table.instance
16801
- }) : null)))));
16861
+ }, rowsForFooter) : null)))));
16802
16862
  }
16803
16863
 
16804
16864
  function Column$1(_) {
@@ -18299,71 +18359,6 @@ const useTableRowCreation = (data, tableRef) => {
18299
18359
  };
18300
18360
  };
18301
18361
 
18302
- function useTableEditingListener(table, tableRef) {
18303
- const tableMeta = table.options.meta;
18304
- const completedRowsCount = tableMeta.editing.getCompletedRowsCount();
18305
- const localization = useLocalization();
18306
- const saveChanges = () => {
18307
- requestAnimationFrame(() => {
18308
- tableMeta.editing.saveChanges();
18309
- });
18310
- };
18311
- // save when the row changes
18312
- useLazyEffect(() => {
18313
- if (tableMeta.editing.isEditing) {
18314
- saveChanges();
18315
- }
18316
- }, [tableMeta.rowActive.rowActiveIndex]);
18317
- useLazyEffect(() => {
18318
- if (tableMeta.editing.isEditing) {
18319
- if (tableMeta.rowActive.rowActiveIndex === undefined) {
18320
- tableMeta.rowActive.setRowActiveIndex(0);
18321
- }
18322
- } else {
18323
- // save
18324
- saveChanges();
18325
- // reset detailed mode
18326
- tableMeta.editing.toggleDetailedMode(false);
18327
- // reset the last index back to the first focusable element, when editing gets turned off
18328
- tableMeta.editing.setLastFocusedCellIndex(undefined);
18329
- }
18330
- }, [tableMeta.editing.isEditing]);
18331
- // show a warning if the user navigates away without triggering save, such as using the browser back/forward button
18332
- const hasChanges = tableMeta.editing.hasChanges();
18333
- React__default.useEffect(() => {
18334
- function showUnsavedChangesWarning(event) {
18335
- if (tableMeta.editing.isEditing && hasChanges) {
18336
- event.returnValue = true;
18337
- return true;
18338
- }
18339
- return false;
18340
- }
18341
- window.addEventListener('beforeunload', showUnsavedChangesWarning);
18342
- return () => {
18343
- window.removeEventListener('beforeunload', showUnsavedChangesWarning);
18344
- };
18345
- }, [tableMeta.editing.isEditing, hasChanges]);
18346
- React__default.useEffect(() => {
18347
- if (completedRowsCount > 0) {
18348
- resetHighlightedColumnIndexes(table.getState().globalFilter, table, localization);
18349
- }
18350
- }, [completedRowsCount]);
18351
- React__default.useEffect(() => {
18352
- const onClickOutside = event => {
18353
- if (tableMeta.editing.isEditing) {
18354
- var _event$target$getAttr, _event$target;
18355
- const element = (_event$target$getAttr = (_event$target = event.target) === null || _event$target === void 0 ? void 0 : _event$target.getAttribute('data-taco')) !== null && _event$target$getAttr !== void 0 ? _event$target$getAttr : '';
18356
- const insideTable = isElementInsideOrTriggeredFromContainer(event.target, tableRef.current) || element === 'backdrop';
18357
- if (!insideTable) {
18358
- saveChanges();
18359
- }
18360
- }
18361
- };
18362
- document.addEventListener('click', onClickOutside);
18363
- return () => document.removeEventListener('click', onClickOutside);
18364
- }, [saveChanges, tableMeta.editing.isEditing]);
18365
- }
18366
-
18367
18362
  function willRowMove(cell, change, rowIndex, localization) {
18368
18363
  const {
18369
18364
  table
@@ -18431,6 +18426,8 @@ function willRowMoveAfterSorting(cell, change, rowIndex) {
18431
18426
  const aUndefined = aValue === undefined;
18432
18427
  const bUndefined = bValue === undefined;
18433
18428
  if (aUndefined || bUndefined) {
18429
+ if (sortUndefined === 'first') return aUndefined ? -1 : 1;
18430
+ if (sortUndefined === 'last') return aUndefined ? 1 : -1;
18434
18431
  return aUndefined && bUndefined ? 0 : aUndefined ? sortUndefined : -sortUndefined;
18435
18432
  }
18436
18433
  }
@@ -18441,444 +18438,635 @@ function willRowMoveAfterSorting(cell, change, rowIndex) {
18441
18438
  }
18442
18439
  return ((_resortedRows$index = resortedRows[index]) === null || _resortedRows$index === void 0 ? void 0 : _resortedRows$index.id) !== cell.row.id;
18443
18440
  }
18444
- function animateCreateRow(id) {
18445
- const templateRow = document.querySelector(`[data-row-id="${id}"]`);
18446
- if (templateRow) {
18447
- const firstCell = templateRow.querySelector(':first-child');
18448
- const checkbox = firstCell === null || firstCell === void 0 ? void 0 : firstCell.querySelector('[data-taco="checkbox"]');
18449
- firstCell === null || firstCell === void 0 ? void 0 : firstCell.focus();
18450
- if (checkbox) {
18451
- setDataFocusAttribute(checkbox);
18452
- }
18453
- templateRow.scrollIntoView();
18454
- const keyframes = [{
18455
- background: '#b2c7ef'
18456
- }, {
18457
- background: '#ebebeb'
18458
- }];
18459
- for (const child of templateRow.children) {
18460
- child.animate(keyframes, {
18461
- duration: 1000,
18462
- easing: 'ease-out'
18463
- });
18464
- }
18441
+ const TEMPORARY_ROW_ID_PREFIX = 'temp-';
18442
+ function isTemporaryRow(rowId) {
18443
+ if (rowId === undefined) {
18444
+ return false;
18465
18445
  }
18446
+ return String(rowId).startsWith(TEMPORARY_ROW_ID_PREFIX);
18466
18447
  }
18448
+ const shortcut = {
18449
+ key: 'e',
18450
+ meta: true,
18451
+ shift: false
18452
+ };
18467
18453
 
18468
- function useTableEditing(isEnabled = false, handleSave, handleChange, validator) {
18469
- // used to switch the table into editing mode
18470
- const [isEditing, toggleEditing] = React__default.useState(false);
18471
- // used to switch the editing between "detailed" mode
18472
- const [isDetailedMode, toggleDetailedMode] = React__default.useState(false);
18473
- // store the last focused cell, so that up/down arrow key navigation remains in the same column
18474
- const [lastFocusedCellIndex, setLastFocusedCellIndex] = useLastFocusedCellIndex();
18475
- // store pending changes for each row
18476
- // changes are saved as soon as the active row changes, so in most cases this will only contain the active row's changes
18477
- // but not always - if validation or server requests fail when saving, those rows remain until the failure is resolved
18478
- const pendingChangesFns = usePendingChanges(isEnabled, handleSave, handleChange, validator);
18479
- useGlobalKeyDown(isEnabled && isEditing ? {
18454
+ function useTableEditingListener(table, tableRef, scrollToIndex) {
18455
+ const tableMeta = table.options.meta;
18456
+ const localization = useLocalization();
18457
+ // save when the row changes
18458
+ // store the last row active index, otherwise everytime tableMeta.editing.saveChanges changes the hook runs again
18459
+ const lastRowActiveIndexRef = React__default.useRef(tableMeta.rowActive.rowActiveIndex);
18460
+ useLazyEffect(() => {
18461
+ if (tableMeta.editing.isEditing && lastRowActiveIndexRef.current !== undefined && tableMeta.rowActive.rowActiveIndex !== lastRowActiveIndexRef.current) {
18462
+ lastRowActiveIndexRef.current = tableMeta.rowActive.rowActiveIndex;
18463
+ tableMeta.editing.saveChanges(table);
18464
+ }
18465
+ }, [tableMeta.rowActive.rowActiveIndex, tableMeta.editing.saveChanges]);
18466
+ // show a warning if the user navigates away without triggering save, such as using the browser back/forward button
18467
+ const hasChanges = tableMeta.editing.hasChanges();
18468
+ React__default.useEffect(() => {
18469
+ function showUnsavedChangesWarning(event) {
18470
+ if (tableMeta.editing.isEditing && hasChanges) {
18471
+ event.returnValue = true;
18472
+ return true;
18473
+ }
18474
+ return false;
18475
+ }
18476
+ window.addEventListener('beforeunload', showUnsavedChangesWarning);
18477
+ return () => {
18478
+ window.removeEventListener('beforeunload', showUnsavedChangesWarning);
18479
+ };
18480
+ }, [tableMeta.editing.isEditing, hasChanges]);
18481
+ const hasSavedChanges = tableMeta.editing.hasSaved();
18482
+ useLazyEffect(() => {
18483
+ if (hasSavedChanges) {
18484
+ resetHighlightedColumnIndexes(table.getState().globalFilter, table, localization);
18485
+ }
18486
+ }, [hasSavedChanges]);
18487
+ React__default.useEffect(() => {
18488
+ const onClickOutside = event => {
18489
+ if (tableMeta.editing.isEditing) {
18490
+ const element = event.target;
18491
+ const insideTable = element.getAttribute('data-taco') === 'backdrop' || element.getAttribute('data-table') === 'editing-toggle' || isElementInsideOrTriggeredFromContainer(element, tableRef.current);
18492
+ // users can click the white space below rows which could be inside the table, but a valid scenario to save
18493
+ if (!insideTable || element.tagName === 'TABLE' || element.tagName === 'TBODY') {
18494
+ tableMeta.editing.saveChanges(table);
18495
+ }
18496
+ }
18497
+ };
18498
+ document.addEventListener('click', onClickOutside);
18499
+ return () => document.removeEventListener('click', onClickOutside);
18500
+ }, [tableMeta.editing.isEditing, tableMeta.editing.saveChanges]);
18501
+ const rows = table.getRowModel().rows;
18502
+ // make sure pending changes are removed for rows that no longer exist
18503
+ useLazyEffect(() => {
18504
+ const pendingChanges = tableMeta.editing.getErrorsShownInAlert();
18505
+ pendingChanges.forEach(pendingChange => {
18506
+ try {
18507
+ table.getRow(pendingChange.rowId);
18508
+ } catch {
18509
+ tableMeta.editing.discardChanges(pendingChange.rowId, table);
18510
+ }
18511
+ });
18512
+ }, [rows.length]);
18513
+ // shortcuts
18514
+ useGlobalKeyDown(tableMeta.editing.isEnabled ? shortcut : undefined, event => {
18515
+ event.preventDefault();
18516
+ tableMeta.editing.toggleEditing(!tableMeta.editing.isEditing, table, scrollToIndex);
18517
+ });
18518
+ useGlobalKeyDown(tableMeta.editing.isEditing ? {
18480
18519
  key: 's',
18481
18520
  meta: true,
18482
18521
  shift: false
18483
18522
  } : undefined, event => {
18484
18523
  event.preventDefault();
18485
- pendingChangesFns.saveChanges();
18524
+ tableMeta.editing.saveChanges(table);
18486
18525
  });
18487
- return {
18488
- isEnabled,
18489
- isEditing,
18490
- isDetailedMode,
18491
- toggleDetailedMode: isEnabled ? toggleDetailedMode : () => undefined,
18492
- toggleEditing: isEnabled ? toggleEditing : () => undefined,
18493
- lastFocusedCellIndex,
18494
- setLastFocusedCellIndex,
18495
- ...pendingChangesFns
18496
- };
18497
18526
  }
18498
- function usePendingChanges(isEnabled, handleSave, handleChange, validator) {
18499
- const saveChanges = function (rowId = undefined) {
18527
+
18528
+ const DELAY_BEFORE_REMOVING_SAVE_STATUS = 3000;
18529
+ function reducer$2(state, action) {
18530
+ const {
18531
+ type,
18532
+ rowId,
18533
+ payload
18534
+ } = action;
18535
+ switch (type) {
18536
+ case 'setCellValue':
18537
+ {
18538
+ const {
18539
+ columnId,
18540
+ row,
18541
+ value
18542
+ } = payload;
18543
+ return {
18544
+ ...state,
18545
+ changes: {
18546
+ ...state.changes,
18547
+ rows: setWith(state.changes.rows, `${rowId}.${columnId}`, value, Object),
18548
+ originals: setWith(state.changes.originals, rowId, row, Object)
18549
+ }
18550
+ };
18551
+ }
18552
+ case 'removeCellValue':
18553
+ {
18554
+ const {
18555
+ columnId,
18556
+ rowIdentityAccessor
18557
+ } = payload;
18558
+ const changes = omit(state.changes.rows, `${rowId}.${columnId}`);
18559
+ // if there are no changes left, remove the row
18560
+ if (!Object.keys(changes[rowId]).length) {
18561
+ return reducer$2(state, {
18562
+ type: 'removeRow',
18563
+ rowId,
18564
+ payload: {
18565
+ rowIdentityAccessor
18566
+ }
18567
+ });
18568
+ }
18569
+ return {
18570
+ ...state,
18571
+ changes: {
18572
+ ...state.changes,
18573
+ rows: omit(state.changes.rows, `${rowId}.${columnId}`),
18574
+ errors: omit(state.changes.errors, `${rowId}.cells.${columnId}`),
18575
+ moveReasons: omit(state.changes.moveReasons, `${rowId}.${columnId}`)
18576
+ }
18577
+ };
18578
+ }
18579
+ case 'updateRow':
18580
+ {
18581
+ const {
18582
+ cellErrors,
18583
+ moveReasons,
18584
+ original,
18585
+ value
18586
+ } = payload;
18587
+ return {
18588
+ ...state,
18589
+ changes: {
18590
+ ...state.changes,
18591
+ rows: setWith(state.changes.rows, rowId, value, Object),
18592
+ errors: setWith(state.changes.errors, `${rowId}.cells`, cellErrors !== null && cellErrors !== void 0 ? cellErrors : state.changes.errors.cells[rowId], Object),
18593
+ originals: setWith(state.changes.originals, rowId, original !== null && original !== void 0 ? original : state.changes.originals[rowId], Object),
18594
+ moveReasons: setWith(state.changes.moveReasons, rowId, moveReasons !== null && moveReasons !== void 0 ? moveReasons : state.changes.moveReasons[rowId], Object),
18595
+ // status can be undefined, so don't use ??
18596
+ status: setWith(state.changes.status, rowId, undefined, Object)
18597
+ }
18598
+ };
18599
+ }
18600
+ case 'removeRow':
18601
+ {
18602
+ const {
18603
+ rowIdentityAccessor
18604
+ } = payload;
18605
+ return {
18606
+ ...state,
18607
+ changes: {
18608
+ ...state.changes,
18609
+ rows: omit(state.changes.rows, rowId),
18610
+ errors: omit(state.changes.errors, rowId),
18611
+ moveReasons: omit(state.changes.moveReasons, rowId),
18612
+ originals: omit(state.changes.originals, rowId),
18613
+ status: omit(state.changes.status, rowId)
18614
+ },
18615
+ temporaryRows: state.temporaryRows.filter(row => row[rowIdentityAccessor] !== rowId)
18616
+ };
18617
+ }
18618
+ case 'setRowStatus':
18619
+ {
18620
+ const {
18621
+ status
18622
+ } = payload;
18623
+ return {
18624
+ ...state,
18625
+ changes: {
18626
+ ...state.changes,
18627
+ status: status ? setWith(state.changes.status, rowId, status, Object) : omit(state.changes.status, rowId)
18628
+ }
18629
+ };
18630
+ }
18631
+ case 'setRowErrors':
18632
+ {
18633
+ const {
18634
+ ...errors
18635
+ } = payload;
18636
+ return {
18637
+ ...state,
18638
+ changes: {
18639
+ ...state.changes,
18640
+ errors: setWith(state.changes.errors, rowId, errors, Object)
18641
+ }
18642
+ };
18643
+ }
18644
+ case 'createRow':
18645
+ {
18646
+ const {
18647
+ value
18648
+ } = payload;
18649
+ return {
18650
+ ...state,
18651
+ temporaryRows: state.temporaryRows.concat(value),
18652
+ changes: {
18653
+ ...state.changes,
18654
+ rows: setWith(state.changes.rows, rowId, value, Object),
18655
+ originals: setWith(state.changes.originals, rowId, value, Object)
18656
+ }
18657
+ };
18658
+ }
18659
+ default:
18660
+ return state;
18661
+ }
18662
+ }
18663
+ function usePendingChangesState(handleSave, handleChange, rowIdentityAccessor, validator) {
18664
+ const saveChanges = function (table, rowId = undefined) {
18500
18665
  try {
18501
18666
  let _exit = false;
18502
18667
  if (!handleSave) {
18503
18668
  console.warn('Tried to save, but Table has no onEditingSave handler');
18504
- return Promise.resolve();
18669
+ return Promise.resolve(false);
18505
18670
  }
18506
- // we save back to pendingChanges, so make a copy of it's state when save was triggered
18507
- const changesToSave = rowId ? {
18508
- [rowId]: pendingChanges[rowId]
18509
- } : {
18510
- ...pendingChanges
18511
- };
18512
- const changes = Object.keys(changesToSave);
18513
- return Promise.resolve(function () {
18514
- if (changes.length) {
18515
- return _forOf(changes, function (rowId) {
18516
- const pendingChange = changesToSave[rowId];
18517
- const changeSet = getChangesetFromChanges(pendingChange);
18518
- return _catch(function () {
18519
- function _temp3(_result) {
18520
- return _exit ? _result : Promise.resolve(handleSave(changeSet)).then(function () {
18521
- // cleanup changes, we don't need them after saving
18522
- resetChanges(rowId);
18523
- setRowSaveStatus(rowId, 'complete');
18524
- });
18525
- }
18526
- if (getRowSaveStatus(rowId) === 'pending') {
18527
- _exit = true;
18528
- return;
18529
- }
18530
- // set saving = true
18531
- setRowSaveStatus(rowId, 'pending');
18532
- // re-run validation, maybe a cell is already invalid but has never been blurred
18533
- const _temp2 = function () {
18534
- if (validator) {
18535
- return Promise.resolve(validator(changeSet)).then(function (errors) {
18536
- if (errors && Object.keys(errors).length) {
18537
- throw errors;
18538
- }
18539
- });
18540
- }
18541
- }();
18542
- return _temp2 && _temp2.then ? _temp2.then(_temp3) : _temp3(_temp2); // send new data to the server
18543
- }, function (error) {
18544
- // the onEditingSave handler should throw errors when something fails, e.g. validation, network errors etc
18545
- // this code handles those errors and maps them either to row errors or cell specific errors
18546
- let rowError;
18547
- let cellErrors;
18548
- if (typeof error === 'string') {
18549
- rowError = error;
18550
- } else if (error instanceof Error) {
18551
- var _error$response;
18552
- rowError = error.message;
18553
- // most of our apis return error objects within this shape
18554
- if (typeof ((_error$response = error.response) === null || _error$response === void 0 ? void 0 : _error$response.data) === 'object') {
18555
- var _error$response2;
18556
- cellErrors = (_error$response2 = error.response) === null || _error$response2 === void 0 ? void 0 : _error$response2.data;
18671
+ // sometimes we only want to save one row
18672
+ const changes = rowId ? {
18673
+ [rowId]: state.changes.rows[rowId]
18674
+ } : state.changes.rows;
18675
+ let completed = true;
18676
+ const _temp9 = _forOf(Object.keys(changes), function (rowId) {
18677
+ const status = getRowStatus(rowId);
18678
+ return _catch(function () {
18679
+ function _temp8(_result) {
18680
+ return _exit ? _result : Promise.resolve(handleSave(changeSet)).then(function () {
18681
+ // cleanup changes, we don't need them after saving
18682
+ discardChanges(rowId, table);
18683
+ // show the saved status, then remove it after a delay
18684
+ setRowStatus(rowId, 'saved');
18685
+ setTimeout(() => {
18686
+ setRowStatus(rowId, undefined);
18687
+ }, DELAY_BEFORE_REMOVING_SAVE_STATUS);
18688
+ });
18689
+ }
18690
+ // don't try to save if - already saving, or there are known errors
18691
+ if (status === 'saving' || status === 'errored') {
18692
+ return;
18693
+ }
18694
+ setRowStatus(rowId, 'saving');
18695
+ const changeSet = {
18696
+ ...state.changes.originals[rowId],
18697
+ ...changes[rowId]
18698
+ };
18699
+ // if we had to create a temporary id, delete it first - it's our data, not theirs
18700
+ if (isTemporaryRow(changeSet[rowIdentityAccessor])) {
18701
+ delete changeSet[rowIdentityAccessor];
18702
+ }
18703
+ // re-run validation, maybe a cell is already invalid but has never been blurred
18704
+ const _temp7 = function () {
18705
+ if (validator) {
18706
+ return Promise.resolve(validator(changeSet)).then(function (errors) {
18707
+ if (errors && Object.keys(errors).length) {
18708
+ throw errors;
18557
18709
  }
18558
- } else if (typeof error === 'object') {
18559
- cellErrors = error;
18560
- }
18561
- if (rowError || cellErrors) {
18562
- setPendingChanges(currentChanges => {
18563
- const nextChanges = {
18564
- ...currentChanges
18565
- };
18566
- nextChanges[rowId]._meta.errors = {
18567
- row: rowError,
18568
- cells: cellErrors,
18569
- shouldShowErrorAlert: true
18570
- };
18571
- return nextChanges;
18572
- });
18710
+ });
18711
+ }
18712
+ }();
18713
+ return _temp7 && _temp7.then ? _temp7.then(_temp8) : _temp8(_temp7); // send new data to the server
18714
+ }, function (error) {
18715
+ var _error$response;
18716
+ if (error instanceof ReferenceError || error instanceof TypeError || (error === null || error === void 0 ? void 0 : (_error$response = error.response) === null || _error$response === void 0 ? void 0 : _error$response.status) >= 500) {
18717
+ console.error(error);
18718
+ }
18719
+ // the onEditingSave handler should throw errors when something fails, e.g. validation, network errors etc
18720
+ // this code handles those errors and maps them either to row errors or cell specific errors
18721
+ let rowError;
18722
+ let cellErrors;
18723
+ if (typeof error === 'string') {
18724
+ rowError = error;
18725
+ } else if (error instanceof Error) {
18726
+ var _error$response2;
18727
+ rowError = error.message;
18728
+ // most of our apis return error objects within this shape
18729
+ if (typeof ((_error$response2 = error.response) === null || _error$response2 === void 0 ? void 0 : _error$response2.data) === 'object') {
18730
+ var _error$response3;
18731
+ cellErrors = (_error$response3 = error.response) === null || _error$response3 === void 0 ? void 0 : _error$response3.data;
18732
+ }
18733
+ } else if (typeof error === 'object') {
18734
+ cellErrors = error;
18735
+ }
18736
+ if (rowError || cellErrors) {
18737
+ dispatch({
18738
+ type: 'setRowErrors',
18739
+ rowId,
18740
+ payload: {
18741
+ row: rowError,
18742
+ cells: cellErrors,
18743
+ shouldShowErrorAlert: true
18573
18744
  }
18574
- setRowSaveStatus(rowId, undefined);
18575
18745
  });
18576
- }, function () {
18577
- return _exit;
18578
- });
18579
- }
18580
- }());
18746
+ }
18747
+ setRowStatus(rowId, 'errored');
18748
+ completed = false;
18749
+ });
18750
+ }, function () {
18751
+ return _exit;
18752
+ });
18753
+ return Promise.resolve(_temp9 && _temp9.then ? _temp9.then(function (_result3) {
18754
+ return _exit ? _result3 : completed;
18755
+ }) : _exit ? _temp9 : completed);
18581
18756
  } catch (e) {
18582
18757
  return Promise.reject(e);
18583
18758
  }
18584
18759
  };
18585
- const validateCell = function (cell) {
18760
+ const onCellChanged = function (cell, rowIndex, shouldRunUpdaters = true) {
18586
18761
  try {
18587
- if (!validator || !isEnabled) {
18588
- return Promise.resolve();
18589
- }
18590
- const changeSet = getChangesetFromChanges(pendingChanges[cell.row.id]);
18591
- // only validate if the cell being blurred actually has any changes
18592
- const _temp = function () {
18593
- if (cell.column.id in changeSet) {
18594
- return Promise.resolve(validator(changeSet)).then(function (errors) {
18595
- setPendingChanges(currentChanges => {
18596
- const nextChanges = {
18597
- ...currentChanges
18598
- };
18599
- nextChanges[cell.row.id]._meta = {
18600
- ...nextChanges[cell.row.id]._meta,
18601
- errors: {
18602
- ...nextChanges[cell.row.id]._meta.errors,
18603
- cells: errors,
18604
- shouldShowErrorAlert: !Object.keys(errors).length ? false : nextChanges[cell.row.id]._meta.errors.shouldShowErrorAlert
18762
+ function _temp6() {
18763
+ var _state$changes$errors8;
18764
+ function _temp4() {
18765
+ // only set errors and move reasons for the cells we're currently acting on
18766
+ // why? because the UX is not good if we set them for cells the user hasn't touched yet
18767
+ const cellsToActOn = [cell.column.id, ...Object.keys(updatesForOtherCells)];
18768
+ const allCells = cell.row._getAllCellsByColumnId();
18769
+ cellsToActOn.forEach(accessor => {
18770
+ if (validationErrors[accessor]) {
18771
+ nextCellErrors[accessor] = validationErrors[accessor];
18772
+ // don't show move indicator for cells with errors, they aren't valid and can't be saved
18773
+ delete nextMoveReasons[accessor];
18774
+ } else {
18775
+ var _allCells$accessor;
18776
+ // there isn't any error in this run, remove any error set in state
18777
+ delete nextCellErrors[accessor];
18778
+ if ((_allCells$accessor = allCells[accessor]) !== null && _allCells$accessor !== void 0 && _allCells$accessor.column.getIsSorted()) {
18779
+ // run row move determination
18780
+ const reason = willRowMove(cell, nextChanges[accessor], rowIndex, localization);
18781
+ // if the row will move based on this change save why, otherwise delete any existing state
18782
+ if (reason) {
18783
+ nextMoveReasons[accessor] = reason;
18784
+ } else {
18785
+ delete nextMoveReasons[accessor];
18605
18786
  }
18606
- };
18607
- return nextChanges;
18787
+ }
18788
+ }
18789
+ });
18790
+ dispatch({
18791
+ type: 'updateRow',
18792
+ rowId: cell.row.id,
18793
+ payload: {
18794
+ cellErrors: nextCellErrors,
18795
+ moveReasons: nextMoveReasons,
18796
+ value: nextChanges
18797
+ }
18798
+ });
18799
+ }
18800
+ // create a projection of the next state, so we can act against it
18801
+ const nextChanges = {
18802
+ ...state.changes.rows[cell.row.id],
18803
+ ...updatesForOtherCells
18804
+ };
18805
+ const nextMoveReasons = {
18806
+ ...state.changes.moveReasons[cell.row.id]
18807
+ };
18808
+ const nextCellErrors = {
18809
+ ...((_state$changes$errors8 = state.changes.errors[cell.row.id]) === null || _state$changes$errors8 === void 0 ? void 0 : _state$changes$errors8.cells)
18810
+ };
18811
+ // run validation
18812
+ let validationErrors = {};
18813
+ const _temp3 = function () {
18814
+ if (validator) {
18815
+ const nextRowValue = {
18816
+ ...state.changes.originals[cell.row.id],
18817
+ ...changes,
18818
+ ...updatesForOtherCells
18819
+ };
18820
+ return Promise.resolve(validator(nextRowValue)).then(function (_validator2) {
18821
+ validationErrors = _validator2 !== null && _validator2 !== void 0 ? _validator2 : {};
18608
18822
  });
18823
+ }
18824
+ }();
18825
+ return _temp3 && _temp3.then ? _temp3.then(_temp4) : _temp4(_temp3);
18826
+ }
18827
+ const changes = state.changes.rows[cell.row.id];
18828
+ if (!changes) {
18829
+ return Promise.resolve();
18830
+ }
18831
+ let updatesForOtherCells = {};
18832
+ // run the updater handler if there is one, to see if there are any other cells to update
18833
+ const _temp5 = function () {
18834
+ if (typeof handleChange === 'function' && shouldRunUpdaters) {
18835
+ const previousRowValue = {
18836
+ ...state.changes.originals[cell.row.id]
18837
+ };
18838
+ const nextRowValue = {
18839
+ ...state.changes.originals[cell.row.id],
18840
+ ...changes
18841
+ };
18842
+ return Promise.resolve(handleChange(cell.column.id, changes[cell.column.id], nextRowValue, previousRowValue)).then(function (_handleChange) {
18843
+ updatesForOtherCells = _handleChange !== null && _handleChange !== void 0 ? _handleChange : {};
18609
18844
  });
18610
18845
  }
18611
18846
  }();
18612
- return Promise.resolve(_temp && _temp.then ? _temp.then(function () {}) : void 0);
18847
+ return Promise.resolve(_temp5 && _temp5.then ? _temp5.then(_temp6) : _temp6(_temp5));
18613
18848
  } catch (e) {
18614
18849
  return Promise.reject(e);
18615
18850
  }
18616
- };
18617
- const setCellValue = function (cell, change, rowIndex) {
18851
+ }; // general
18852
+ const createRow = function (data) {
18618
18853
  try {
18619
- const changes = {
18620
- [cell.column.id]: change
18854
+ const newRowId = `${TEMPORARY_ROW_ID_PREFIX}${uuid.v4()}`;
18855
+ const value = {
18856
+ ...data,
18857
+ [rowIdentityAccessor]: newRowId
18621
18858
  };
18622
- setPendingChanges(currentChanges => {
18623
- const nextChanges = createPendingChangesSetter(currentChanges, cell.row, rowIndex, changes, localization);
18624
- pendingChangesUpdater.syncCellChanges(nextChanges);
18625
- return nextChanges;
18859
+ dispatch({
18860
+ type: 'createRow',
18861
+ rowId: newRowId,
18862
+ payload: {
18863
+ value
18864
+ }
18626
18865
  });
18627
- pendingChangesUpdater.runCellUpdates(changes, cell, rowIndex);
18628
- return Promise.resolve();
18866
+ return Promise.resolve(newRowId);
18629
18867
  } catch (e) {
18630
18868
  return Promise.reject(e);
18631
18869
  }
18632
- };
18633
- const addCreatedRowChangeset = function (row) {
18870
+ }; // cells
18871
+ // rows
18872
+ const setRowValue = function (rowId, original, value) {
18634
18873
  try {
18635
- const cells = row.getAllCells();
18636
- setPendingChanges(currentChanges => {
18637
- return cells.reduce((changes, cell) => {
18638
- if (cell.getValue()) {
18639
- var _currentChanges$cell$, _currentChanges$cell$2, _currentChanges$cell$3;
18640
- return {
18641
- ...changes,
18642
- [cell.row.id]: {
18643
- ...changes[cell.row.id],
18644
- [cell.column.id]: cell.getValue(),
18645
- _meta: {
18646
- ...((_currentChanges$cell$ = currentChanges[cell.row.id]) === null || _currentChanges$cell$ === void 0 ? void 0 : _currentChanges$cell$._meta),
18647
- original: cell.row.original,
18648
- moveReason: {
18649
- ...((_currentChanges$cell$2 = currentChanges[cell.row.id]) === null || _currentChanges$cell$2 === void 0 ? void 0 : _currentChanges$cell$2._meta.moveReason)
18650
- },
18651
- errors: {
18652
- ...((_currentChanges$cell$3 = currentChanges[cell.row.id]) === null || _currentChanges$cell$3 === void 0 ? void 0 : _currentChanges$cell$3._meta.errors)
18653
- }
18654
- }
18655
- }
18656
- };
18657
- } else {
18658
- return changes;
18874
+ function _temp2() {
18875
+ dispatch({
18876
+ type: 'updateRow',
18877
+ rowId,
18878
+ payload: {
18879
+ cellErrors,
18880
+ original,
18881
+ value
18659
18882
  }
18660
- }, currentChanges);
18661
- });
18662
- return Promise.resolve();
18663
- } catch (e) {
18664
- return Promise.reject(e);
18883
+ });
18884
+ }
18885
+ let cellErrors;
18886
+ const _temp = function () {
18887
+ if (validator) {
18888
+ const row = {
18889
+ ...original,
18890
+ ...value
18891
+ };
18892
+ return Promise.resolve(validator(row)).then(function (_validator) {
18893
+ cellErrors = _validator !== null && _validator !== void 0 ? _validator : {};
18894
+ });
18895
+ }
18896
+ }();
18897
+ return Promise.resolve(_temp && _temp.then ? _temp.then(_temp2) : _temp2(_temp));
18898
+ } catch (e) {
18899
+ return Promise.reject(e);
18665
18900
  }
18666
18901
  };
18667
18902
  const localization = useLocalization();
18668
- const [pendingChanges, setPendingChanges] = React__default.useState({});
18669
- // we maintain save status as separate state because 'complete' needs to briefly show after pendingChanges are deleted
18670
- const [saveStates, setSaveState] = React__default.useState({});
18671
- function getCellValue(cell) {
18672
- var _pendingChanges$cell$;
18673
- return (_pendingChanges$cell$ = pendingChanges[cell.row.id]) === null || _pendingChanges$cell$ === void 0 ? void 0 : _pendingChanges$cell$[cell.column.id];
18903
+ const [state, dispatch] = React__default.useReducer(reducer$2, {
18904
+ changes: {
18905
+ rows: {},
18906
+ errors: {},
18907
+ moveReasons: {},
18908
+ originals: {},
18909
+ status: {}
18910
+ },
18911
+ temporaryRows: []
18912
+ });
18913
+ function getRowValue(rowId) {
18914
+ var _state$changes$rows$r, _state$changes$rows;
18915
+ return (_state$changes$rows$r = (_state$changes$rows = state.changes.rows) === null || _state$changes$rows === void 0 ? void 0 : _state$changes$rows[rowId]) !== null && _state$changes$rows$r !== void 0 ? _state$changes$rows$r : undefined;
18674
18916
  }
18675
- function getCellError(cell) {
18676
- var _pendingChanges$cell$2, _pendingChanges$cell$3, _pendingChanges$cell$4;
18677
- return (_pendingChanges$cell$2 = pendingChanges[cell.row.id]) === null || _pendingChanges$cell$2 === void 0 ? void 0 : (_pendingChanges$cell$3 = _pendingChanges$cell$2._meta.errors) === null || _pendingChanges$cell$3 === void 0 ? void 0 : (_pendingChanges$cell$4 = _pendingChanges$cell$3.cells) === null || _pendingChanges$cell$4 === void 0 ? void 0 : _pendingChanges$cell$4[cell.column.id];
18917
+ function getRowMoveReason(rowId) {
18918
+ var _Object$values$, _state$changes$moveRe, _state$changes$moveRe2;
18919
+ return (_Object$values$ = Object.values((_state$changes$moveRe = (_state$changes$moveRe2 = state.changes.moveReasons) === null || _state$changes$moveRe2 === void 0 ? void 0 : _state$changes$moveRe2[rowId]) !== null && _state$changes$moveRe !== void 0 ? _state$changes$moveRe : {})[0]) !== null && _Object$values$ !== void 0 ? _Object$values$ : undefined;
18678
18920
  }
18679
- const pendingChangesUpdater = usePendingChangesUpdater(handleChange, setPendingChanges);
18680
18921
  function hasRowErrors(rowId) {
18681
- var _pendingChanges$rowId, _pendingChanges$rowId2, _pendingChanges$rowId3, _pendingChanges$rowId4, _pendingChanges$rowId5;
18682
- if (!isEnabled) {
18683
- return false;
18684
- }
18685
- return !!((_pendingChanges$rowId = pendingChanges[rowId]) !== null && _pendingChanges$rowId !== void 0 && (_pendingChanges$rowId2 = _pendingChanges$rowId._meta.errors) !== null && _pendingChanges$rowId2 !== void 0 && _pendingChanges$rowId2.row) || !!Object.keys((_pendingChanges$rowId3 = (_pendingChanges$rowId4 = pendingChanges[rowId]) === null || _pendingChanges$rowId4 === void 0 ? void 0 : (_pendingChanges$rowId5 = _pendingChanges$rowId4._meta.errors) === null || _pendingChanges$rowId5 === void 0 ? void 0 : _pendingChanges$rowId5.cells) !== null && _pendingChanges$rowId3 !== void 0 ? _pendingChanges$rowId3 : {}).length;
18686
- }
18687
- function hasRowErrorsSeen(rowId) {
18688
- var _pendingChanges$rowId6;
18689
- if (!isEnabled) {
18690
- return false;
18691
- }
18692
- return hasRowErrors(rowId) && !!((_pendingChanges$rowId6 = pendingChanges[rowId]._meta.errors) !== null && _pendingChanges$rowId6 !== void 0 && _pendingChanges$rowId6.shouldShowErrorAlert);
18922
+ var _state$changes$errors, _state$changes$errors2, _state$changes$errors3;
18923
+ return !!((_state$changes$errors = state.changes.errors[rowId]) !== null && _state$changes$errors !== void 0 && _state$changes$errors.row) || !!Object.keys((_state$changes$errors2 = (_state$changes$errors3 = state.changes.errors[rowId]) === null || _state$changes$errors3 === void 0 ? void 0 : _state$changes$errors3.cells) !== null && _state$changes$errors2 !== void 0 ? _state$changes$errors2 : {}).length;
18693
18924
  }
18694
- function getRowPendingChange(rowId) {
18695
- const rowPendingChanges = pendingChanges[rowId];
18696
- if (rowPendingChanges) {
18697
- const {
18698
- _meta,
18699
- ...pendingChange
18700
- } = rowPendingChanges;
18701
- return pendingChange;
18702
- }
18703
- return undefined;
18925
+ function hasRowErrorsShownInAlert(rowId) {
18926
+ var _state$changes$errors4;
18927
+ return hasRowErrors(rowId) && !!((_state$changes$errors4 = state.changes.errors[rowId]) !== null && _state$changes$errors4 !== void 0 && _state$changes$errors4.shouldShowErrorAlert);
18704
18928
  }
18705
- function getRowSaveStatus(rowId) {
18706
- if (!isEnabled) {
18707
- return false;
18708
- }
18709
- return saveStates[rowId];
18929
+ function getRowStatus(rowId) {
18930
+ return state.changes.status[rowId];
18710
18931
  }
18711
- function setRowSaveStatus(rowId, status) {
18712
- setSaveState(currentStates => {
18713
- const nextStates = {
18714
- ...currentStates
18715
- };
18716
- if (status) {
18717
- nextStates[rowId] = status;
18718
- } else {
18719
- delete nextStates[rowId];
18932
+ function setRowStatus(rowId, status) {
18933
+ dispatch({
18934
+ type: 'setRowStatus',
18935
+ rowId,
18936
+ payload: {
18937
+ status
18720
18938
  }
18721
- return nextStates;
18722
18939
  });
18723
18940
  }
18724
- function getRowMoveReason(rowId) {
18725
- var _pendingChanges$rowId7;
18726
- return (_pendingChanges$rowId7 = pendingChanges[rowId]) !== null && _pendingChanges$rowId7 !== void 0 && _pendingChanges$rowId7._meta.moveReason ? Object.values(pendingChanges[rowId]._meta.moveReason)[0] : undefined;
18727
- }
18728
- function hasChanges(rowId) {
18729
- if (!isEnabled) {
18730
- return false;
18941
+ function setCellValue(cell, value) {
18942
+ const rowId = cell.row.id;
18943
+ const columnId = cell.column.id;
18944
+ // update if the change is different to the original value
18945
+ if (value !== cell.row.original[columnId]) {
18946
+ dispatch({
18947
+ type: 'setCellValue',
18948
+ rowId,
18949
+ payload: {
18950
+ columnId,
18951
+ row: cell.row.original,
18952
+ value
18953
+ }
18954
+ });
18731
18955
  }
18732
- return rowId ? !!pendingChanges[rowId] : !!Object.keys(pendingChanges).length;
18733
- }
18734
- function hasAlertErrors() {
18735
- if (!isEnabled) {
18736
- return false;
18956
+ // otherwise remove any previous change - no point saving the same value
18957
+ else if (cell.row.id in state.changes.rows) {
18958
+ dispatch({
18959
+ type: 'removeCellValue',
18960
+ rowId,
18961
+ payload: {
18962
+ columnId,
18963
+ rowIdentityAccessor
18964
+ }
18965
+ });
18737
18966
  }
18738
- return !!getAlertErrors().length;
18739
18967
  }
18740
- function getAlertErrors() {
18741
- return Object.keys(pendingChanges).filter(hasRowErrorsSeen).map(rowId => ({
18968
+ function getCellValue(cell) {
18969
+ var _state$changes$rows2, _state$changes$rows2$;
18970
+ return (_state$changes$rows2 = state.changes.rows) === null || _state$changes$rows2 === void 0 ? void 0 : (_state$changes$rows2$ = _state$changes$rows2[cell.row.id]) === null || _state$changes$rows2$ === void 0 ? void 0 : _state$changes$rows2$[cell.column.id];
18971
+ }
18972
+ function getCellError(cell) {
18973
+ var _state$changes$errors5, _state$changes$errors6, _state$changes$errors7;
18974
+ return (_state$changes$errors5 = state.changes.errors) === null || _state$changes$errors5 === void 0 ? void 0 : (_state$changes$errors6 = _state$changes$errors5[cell.row.id]) === null || _state$changes$errors6 === void 0 ? void 0 : (_state$changes$errors7 = _state$changes$errors6.cells) === null || _state$changes$errors7 === void 0 ? void 0 : _state$changes$errors7[cell.column.id];
18975
+ }
18976
+ function getErrorsShownInAlert() {
18977
+ const rowsWithErrors = Object.keys(state.changes.errors);
18978
+ if (!rowsWithErrors.length) {
18979
+ return [];
18980
+ }
18981
+ return rowsWithErrors.filter(hasRowErrorsShownInAlert).map(rowId => ({
18742
18982
  rowId,
18743
- pendingChange: pendingChanges[rowId]
18983
+ changes: state.changes.rows[rowId],
18984
+ errors: state.changes.errors[rowId]
18744
18985
  }));
18745
18986
  }
18746
- function resetChanges(rowId) {
18747
- setPendingChanges(currentChanges => {
18748
- const nextChanges = {
18749
- ...currentChanges
18750
- };
18751
- delete nextChanges[rowId];
18752
- return nextChanges;
18753
- });
18987
+ function hasSaved() {
18988
+ return !!Object.values(state.changes.status).filter(value => value === 'saved').length;
18989
+ }
18990
+ function hasChanges(rowId) {
18991
+ return rowId ? !!state.changes.rows[rowId] : !!Object.keys(state.changes.rows).length;
18754
18992
  }
18755
- function getCompletedRowsCount() {
18756
- return Object.values(saveStates).filter(value => value === 'complete').length;
18993
+ function discardChanges(rowId, table) {
18994
+ // remove any new rows from pinned state before discarding them
18995
+ table.resetRowPinning(true);
18996
+ dispatch({
18997
+ type: 'removeRow',
18998
+ rowId,
18999
+ payload: {
19000
+ rowIdentityAccessor
19001
+ }
19002
+ });
18757
19003
  }
18758
19004
  return {
19005
+ // row
19006
+ setRowValue,
19007
+ getRowValue,
19008
+ getRowMoveReason,
19009
+ hasRowErrors,
19010
+ hasRowErrorsShownInAlert,
19011
+ getRowStatus,
19012
+ setRowStatus,
19013
+ // cells
19014
+ setCellValue,
18759
19015
  getCellValue,
18760
19016
  getCellError,
18761
- setCellValue,
18762
- validateCell,
18763
- addCreatedRowChangeset,
19017
+ onCellChanged,
19018
+ // general
19019
+ getErrorsShownInAlert,
18764
19020
  hasChanges,
18765
- hasAlertErrors,
18766
- getAlertErrors,
18767
19021
  saveChanges,
18768
- resetChanges,
18769
- hasRowErrors,
18770
- hasRowErrorsSeen,
18771
- getRowPendingChange,
18772
- getRowSaveStatus,
18773
- setRowSaveStatus,
18774
- getRowMoveReason,
18775
- getCompletedRowsCount
19022
+ discardChanges,
19023
+ hasSaved,
19024
+ // new rows
19025
+ createRow,
19026
+ temporaryRows: state.temporaryRows
18776
19027
  };
18777
19028
  }
18778
- function useLastFocusedCellIndex() {
19029
+
19030
+ function useTableEditing(isEnabled = false, handleSave, handleChange, rowIdentityAccessor, validator) {
19031
+ // used to switch the table into editing mode
19032
+ const [isEditing, setEditing] = React__default.useState(false);
19033
+ // used to switch the editing between "detailed" mode
19034
+ const [isDetailedMode, toggleDetailedMode] = React__default.useState(false);
19035
+ // used to contain ref to the create button
19036
+ const createRowButtonRef = React__default.useRef(null);
18779
19037
  // store the last focused cell, so that up/down arrow key navigation remains in the same column
18780
- const lastFocusedCellIndexRef = React__default.useRef(undefined);
18781
- const setLastFocusedCellIndex = React__default.useCallback(index => {
18782
- lastFocusedCellIndexRef.current = index;
18783
- }, []);
18784
- return [lastFocusedCellIndexRef.current, setLastFocusedCellIndex];
18785
- }
18786
- function usePendingChangesUpdater(handleChange, setPendingChanges) {
18787
- const localization = useLocalization();
18788
- const updatersRef = React__default.useRef({});
18789
- const runCellUpdates = React__default.useCallback(lodash.debounce(function (changes, cell, rowIndex) {
18790
- try {
18791
- const _temp4 = function () {
18792
- if (typeof handleChange === 'function') {
18793
- const previousValues = {
18794
- ...cell.row.original,
18795
- ...getChangesetFromChanges(updatersRef.current[cell.row.id])
18796
- };
18797
- const nextValues = {
18798
- ...previousValues,
18799
- ...changes
18800
- };
18801
- return Promise.resolve(handleChange(cell.column.id, changes[cell.column.id], nextValues, previousValues)).then(function (updates) {
18802
- if (updates && Object.keys(updates).length) {
18803
- setPendingChanges(currentChanges => createPendingChangesSetter(currentChanges, cell.row, rowIndex, updates, localization));
18804
- }
18805
- });
18806
- }
18807
- }();
18808
- return Promise.resolve(_temp4 && _temp4.then ? _temp4.then(function () {}) : void 0);
18809
- } catch (e) {
18810
- return Promise.reject(e);
19038
+ const [lastFocusedCellIndex, setLastFocusedCellIndex] = React__default.useState(undefined);
19039
+ const pendingChangesFns = usePendingChangesState(handleSave, handleChange, rowIdentityAccessor, validator);
19040
+ function toggleEditing(enabled, table, scrollToIndex) {
19041
+ var _tableMeta$rowActive$, _table$getRowModel$ro;
19042
+ if (!enabled) {
19043
+ // save
19044
+ pendingChangesFns.saveChanges(table);
19045
+ // reset detailed mode
19046
+ toggleDetailedMode(false);
19047
+ // reset the last index back to the first focusable element, when editing gets turned off
19048
+ setLastFocusedCellIndex(undefined);
18811
19049
  }
18812
- }, 250), []);
18813
- function syncCellChanges(changes) {
18814
- updatersRef.current = changes;
18815
- }
18816
- return {
18817
- syncCellChanges,
18818
- runCellUpdates
18819
- };
18820
- }
18821
- function createPendingChangesSetter(currentChanges, row, rowIndex, changes, localization) {
18822
- var _currentChanges$row$i, _currentChanges$row$i2, _currentChanges$row$i3;
18823
- // prepare
18824
- const nextChanges = {
18825
- ...currentChanges
18826
- };
18827
- const rowChanges = {
18828
- ...currentChanges[row.id],
18829
- _meta: {
18830
- ...((_currentChanges$row$i = currentChanges[row.id]) === null || _currentChanges$row$i === void 0 ? void 0 : _currentChanges$row$i._meta),
18831
- original: row.original,
18832
- moveReason: {
18833
- ...((_currentChanges$row$i2 = currentChanges[row.id]) === null || _currentChanges$row$i2 === void 0 ? void 0 : _currentChanges$row$i2._meta.moveReason)
18834
- },
18835
- errors: {
18836
- ...((_currentChanges$row$i3 = currentChanges[row.id]) === null || _currentChanges$row$i3 === void 0 ? void 0 : _currentChanges$row$i3._meta.errors)
18837
- }
19050
+ const tableMeta = table.options.meta;
19051
+ const index = (_tableMeta$rowActive$ = tableMeta.rowActive.rowActiveIndex) !== null && _tableMeta$rowActive$ !== void 0 ? _tableMeta$rowActive$ : 0;
19052
+ if (tableMeta.rowActive.rowActiveIndex === undefined) {
19053
+ tableMeta.rowActive.setRowActiveIndex(index);
18838
19054
  }
18839
- };
18840
- // run changes
18841
- const cells = row._getAllCellsByColumnId();
18842
- for (const [accessor, change] of Object.entries(changes)) {
18843
- // update if the change is different to the original (saved) value,
18844
- // otherwise remove any change - no point saving the same value
18845
- if (change !== row.original[accessor]) {
18846
- rowChanges[accessor] = change;
18847
- // consumers sometimes include properties in onEditingChange that aren't rendered as columns, we need to guard against that.
18848
- // eslint-disable-next-line no-prototype-builtins
18849
- if (cells.hasOwnProperty(accessor)) {
18850
- // determine if the row will move position based on this change, and save why it will move
18851
- const reason = willRowMove(cells[accessor], change, rowIndex, localization);
18852
- if (reason) {
18853
- rowChanges._meta.moveReason[accessor] = reason;
18854
- } else {
18855
- delete rowChanges._meta.moveReason[accessor];
18856
- }
18857
- }
18858
- } else {
18859
- delete rowChanges[accessor];
18860
- delete rowChanges._meta.moveReason[accessor];
19055
+ setEditing(enabled);
19056
+ if (!isTemporaryRow((_table$getRowModel$ro = table.getRowModel().rows[index]) === null || _table$getRowModel$ro === void 0 ? void 0 : _table$getRowModel$ro.id)) {
19057
+ scrollToIndex(index);
18861
19058
  }
18862
19059
  }
18863
- // set changes
18864
- // or delete if there are no changes left, so that we don't store changes with unchanged data
18865
- if (Object.keys(rowChanges).filter(k => k !== '_meta').length) {
18866
- nextChanges[row.id] = rowChanges;
18867
- } else {
18868
- delete nextChanges[row.id];
18869
- }
18870
- return nextChanges;
18871
- }
18872
- function getChangesetFromChanges(changes) {
18873
- // extract the original data from the row changes
18874
- const {
18875
- _meta,
18876
- ...changeset
18877
- } = changes !== null && changes !== void 0 ? changes : {};
18878
- // and mix them in with the changes, ready to send to the server
18879
19060
  return {
18880
- ...(_meta === null || _meta === void 0 ? void 0 : _meta.original),
18881
- ...changeset
19061
+ isEnabled,
19062
+ isEditing,
19063
+ isDetailedMode,
19064
+ toggleDetailedMode: isEnabled ? toggleDetailedMode : () => undefined,
19065
+ toggleEditing: isEnabled ? toggleEditing : () => undefined,
19066
+ lastFocusedCellIndex,
19067
+ setLastFocusedCellIndex,
19068
+ createRowButtonRef,
19069
+ ...pendingChangesFns
18882
19070
  };
18883
19071
  }
18884
19072
 
@@ -18922,7 +19110,6 @@ function RowMoveIndicator(props) {
18922
19110
  if (!show) {
18923
19111
  return null;
18924
19112
  }
18925
- const className = 'wcag-blue-500 absolute left-0 top-full ml-1 whitespace-nowrap rounded-b-md px-1 py-1 text-xs font-bold z-10';
18926
19113
  const {
18927
19114
  title,
18928
19115
  description
@@ -18931,7 +19118,7 @@ function RowMoveIndicator(props) {
18931
19118
  placement: "bottom",
18932
19119
  title: description.replace('[COLUMN]', columnMeta.header)
18933
19120
  }, /*#__PURE__*/React__default.createElement("span", {
18934
- className: className
19121
+ "data-row-move-indicator": true
18935
19122
  }, /*#__PURE__*/React__default.createElement(Icon, {
18936
19123
  name: "info",
18937
19124
  className: "-mt-0.5 mr-1 !h-4 !w-4 rounded-full bg-white !p-0 text-blue-500"
@@ -19120,13 +19307,31 @@ function EditingControlCell(props) {
19120
19307
  const {
19121
19308
  rowIndex
19122
19309
  } = React__default.useContext(RowContext);
19123
- const tableMeta = cell.getContext().table.options.meta;
19310
+ const {
19311
+ table
19312
+ } = cell.getContext();
19313
+ const tableMeta = table.options.meta;
19124
19314
  const columnMeta = cell.column.columnDef.meta;
19125
19315
  const isActiveRow = tableMeta.rowActive.rowActiveIndex === rowIndex;
19316
+ const type = (_columnMeta$control = columnMeta.control) !== null && _columnMeta$control !== void 0 ? _columnMeta$control : 'input';
19126
19317
  const handleFocus = useEditingCellAutofocus(props);
19318
+ const value = cell.getValue();
19319
+ // some controls, like select2, should trigger cell changed (validation, updates) as the value changes
19320
+ const hasNonTextControl = React__default.useMemo(() => {
19321
+ var _cellRef$current;
19322
+ return typeof type === 'function' && !!((_cellRef$current = cellRef.current) !== null && _cellRef$current !== void 0 && _cellRef$current.querySelector('[data-taco="Select2"],[data-taco="switch"],[data-taco="checkbox"]'));
19323
+ }, [cellRef.current]);
19324
+ const handleChange = nextValue => {
19325
+ if (nextValue !== value) {
19326
+ tableMeta.editing.setCellValue(cell, nextValue);
19327
+ if (hasNonTextControl) {
19328
+ tableMeta.editing.onCellChanged(cell, rowIndex);
19329
+ }
19330
+ }
19331
+ };
19127
19332
  const handleBlur = () => {
19128
19333
  tableMeta.editing.toggleDetailedMode(false);
19129
- tableMeta.editing.validateCell(cell);
19334
+ tableMeta.editing.onCellChanged(cell, rowIndex, !hasNonTextControl);
19130
19335
  };
19131
19336
  // ensure that blur runs when the cell gets unmounted (when vertically arrow key navigating)
19132
19337
  React__default.useEffect(() => {
@@ -19146,14 +19351,13 @@ function EditingControlCell(props) {
19146
19351
  isDetailedMode: tableMeta.editing.isDetailedMode,
19147
19352
  isTruncated: !!columnMeta.enableTruncate,
19148
19353
  onBlur: handleBlur,
19149
- onChange: value => tableMeta.editing.setCellValue(cell, value, rowIndex),
19354
+ onChange: handleChange,
19150
19355
  row: cell.row.original,
19151
- rowPendingChanges: tableMeta.editing.getRowPendingChange(cell.row.id),
19356
+ rowPendingChanges: tableMeta.editing.getRowValue(cell.row.id),
19152
19357
  tabIndex: isActiveRow ? 0 : -1,
19153
- toggleEditing: tableMeta.editing.toggleEditing,
19154
19358
  toggleDetailedMode: tableMeta.editing.toggleDetailedMode,
19155
- type: (_columnMeta$control = columnMeta.control) !== null && _columnMeta$control !== void 0 ? _columnMeta$control : 'input',
19156
- value: cell.getValue()
19359
+ type,
19360
+ value
19157
19361
  };
19158
19362
  const cellAttributes = {
19159
19363
  ...getCellAttributes(cell, index, isHighlighted),
@@ -19185,7 +19389,6 @@ const MemoedEditingCell = /*#__PURE__*/React__default.memo(function MemoedEditin
19185
19389
  row,
19186
19390
  rowPendingChanges,
19187
19391
  tabIndex = -1,
19188
- toggleEditing,
19189
19392
  toggleDetailedMode,
19190
19393
  type = 'input',
19191
19394
  value
@@ -19244,8 +19447,8 @@ const MemoedEditingCell = /*#__PURE__*/React__default.memo(function MemoedEditin
19244
19447
  }
19245
19448
  // reset the value, or exit edit mode when pressing escape
19246
19449
  if (event.key === 'Escape') {
19247
- event.preventDefault();
19248
19450
  if (isDetailedMode) {
19451
+ event.preventDefault();
19249
19452
  toggleDetailedMode(false);
19250
19453
  if (value !== currentValue) {
19251
19454
  props.onChange(currentValue);
@@ -19255,8 +19458,6 @@ const MemoedEditingCell = /*#__PURE__*/React__default.memo(function MemoedEditin
19255
19458
  var _target$select2;
19256
19459
  return (_target$select2 = target.select) === null || _target$select2 === void 0 ? void 0 : _target$select2.call(target);
19257
19460
  });
19258
- } else {
19259
- toggleEditing(false);
19260
19461
  }
19261
19462
  return;
19262
19463
  }
@@ -19355,12 +19556,37 @@ function Cell$5(props) {
19355
19556
  return /*#__PURE__*/React__default.createElement(DisplayCell, Object.assign({}, props));
19356
19557
  }
19357
19558
 
19559
+ function DiscardChangesConfirmationDialog(props) {
19560
+ const {
19561
+ onDiscard: handleDiscard,
19562
+ ...dialogProps
19563
+ } = props;
19564
+ const {
19565
+ texts
19566
+ } = useLocalization();
19567
+ const handleClickInsideDialogContent = event => {
19568
+ // Prevents the click event from propagating to the table, ensuring the row isn't saved when a click occurs
19569
+ // inside the dialog
19570
+ event.stopPropagation();
19571
+ };
19572
+ return /*#__PURE__*/React__default.createElement(Dialog, Object.assign({}, dialogProps), /*#__PURE__*/React__default.createElement(Dialog.Content, {
19573
+ "aria-label": texts.table3.editing.clearChangesConfirmationDialog.title,
19574
+ onClick: handleClickInsideDialogContent
19575
+ }, /*#__PURE__*/React__default.createElement(Dialog.Title, null, texts.table3.editing.clearChangesConfirmationDialog.title), /*#__PURE__*/React__default.createElement("p", null, texts.table3.editing.clearChangesConfirmationDialog.description), /*#__PURE__*/React__default.createElement(Dialog.Footer, null, /*#__PURE__*/React__default.createElement(Group, null, /*#__PURE__*/React__default.createElement(Dialog.Close, null, /*#__PURE__*/React__default.createElement(Button$1, {
19576
+ tabIndex: 0
19577
+ }, texts.table3.editing.clearChangesConfirmationDialog.cancel)), /*#__PURE__*/React__default.createElement(Dialog.Close, null, /*#__PURE__*/React__default.createElement(Button$1, {
19578
+ autoFocus: true,
19579
+ tabIndex: 0,
19580
+ appearance: "primary",
19581
+ onClick: handleDiscard
19582
+ }, texts.table3.editing.clearChangesConfirmationDialog.confirm))))));
19583
+ }
19584
+
19358
19585
  function EditingActionMenu(props) {
19359
19586
  const {
19360
19587
  hasChanges,
19361
19588
  hasErrors,
19362
- onClear: handleClear,
19363
- onExit: handleExit,
19589
+ onDiscard: handleDiscard,
19364
19590
  onEditingSave: handleSave,
19365
19591
  isLastRow
19366
19592
  } = props;
@@ -19382,7 +19608,6 @@ function EditingActionMenu(props) {
19382
19608
  return /*#__PURE__*/React__default.createElement(IconButton, {
19383
19609
  appearance: "transparent",
19384
19610
  "aria-label": texts.table3.editing.actions.tooltip,
19385
- className: "group-[[data-row-editing-status]]/row:hidden",
19386
19611
  icon: "more",
19387
19612
  onKeyDown: handleKeyDown,
19388
19613
  menu: menuProps => (/*#__PURE__*/React__default.createElement(Menu$1, Object.assign({}, menuProps), /*#__PURE__*/React__default.createElement(Menu$1.Content, {
@@ -19394,42 +19619,13 @@ function EditingActionMenu(props) {
19394
19619
  }, texts.table3.editing.actions.save), /*#__PURE__*/React__default.createElement(Menu$1.Item, {
19395
19620
  icon: "close",
19396
19621
  disabled: !hasChanges,
19397
- dialog: props => /*#__PURE__*/React__default.createElement(ConfirmClearChangesDialog, Object.assign({}, props, {
19398
- onClear: handleClear
19622
+ dialog: props => /*#__PURE__*/React__default.createElement(DiscardChangesConfirmationDialog, Object.assign({}, props, {
19623
+ onDiscard: handleDiscard
19399
19624
  }))
19400
- }, texts.table3.editing.actions.clear), /*#__PURE__*/React__default.createElement(Menu$1.Item, {
19401
- icon: "undo",
19402
- onClick: handleExit
19403
- }, texts.table3.editing.actions.exit))))
19625
+ }, texts.table3.editing.actions.clear))))
19404
19626
  });
19405
19627
  }
19406
- function ConfirmClearChangesDialog(props) {
19407
- const {
19408
- onClear: handleClear,
19409
- ...dialogProps
19410
- } = props;
19411
- const {
19412
- texts
19413
- } = useLocalization();
19414
- const handleClickInsideDialogContent = event => {
19415
- // Prevents the click event from propagating to the table, ensuring the row isn't saved when a click occurs
19416
- // inside the dialog
19417
- event.stopPropagation();
19418
- };
19419
- return /*#__PURE__*/React__default.createElement(Dialog, Object.assign({}, dialogProps), /*#__PURE__*/React__default.createElement(Dialog.Content, {
19420
- "aria-label": texts.table3.editing.clearChangesConfirmationDialog.title,
19421
- onClick: handleClickInsideDialogContent
19422
- }, /*#__PURE__*/React__default.createElement(Dialog.Title, null, texts.table3.editing.clearChangesConfirmationDialog.title), /*#__PURE__*/React__default.createElement("p", null, texts.table3.editing.clearChangesConfirmationDialog.description), /*#__PURE__*/React__default.createElement(Dialog.Footer, null, /*#__PURE__*/React__default.createElement(Group, null, /*#__PURE__*/React__default.createElement(Dialog.Close, null, /*#__PURE__*/React__default.createElement(Button$1, {
19423
- tabIndex: 0
19424
- }, texts.table3.editing.clearChangesConfirmationDialog.cancel)), /*#__PURE__*/React__default.createElement(Dialog.Close, null, /*#__PURE__*/React__default.createElement(Button$1, {
19425
- autoFocus: true,
19426
- tabIndex: 0,
19427
- appearance: "primary",
19428
- onClick: handleClear
19429
- }, texts.table3.editing.clearChangesConfirmationDialog.confirm))))));
19430
- }
19431
19628
 
19432
- const COMPLETE_INDICATOR_DELAY = 3000;
19433
19629
  function SaveStatus(props) {
19434
19630
  const {
19435
19631
  rowId,
@@ -19439,18 +19635,7 @@ function SaveStatus(props) {
19439
19635
  texts
19440
19636
  } = useLocalization();
19441
19637
  const tableMeta = table.options.meta;
19442
- const status = tableMeta.editing.getRowSaveStatus(rowId);
19443
- React__default.useEffect(() => {
19444
- let timeout;
19445
- if (status === 'complete') {
19446
- timeout = setTimeout(() => {
19447
- tableMeta.editing.setRowSaveStatus(rowId, undefined);
19448
- }, COMPLETE_INDICATOR_DELAY);
19449
- }
19450
- return () => {
19451
- clearTimeout(timeout);
19452
- };
19453
- }, [status]);
19638
+ const status = tableMeta.editing.getRowStatus(rowId);
19454
19639
  const className = cn('col-span-full sticky ml-auto right-0 top-0 -mb-[100%] z-10 h-8 bg-[inherit] flex items-center px-1.5 shadow-[-6px_0px_6px_var(--table-row-actions-shadow)]', {
19455
19640
  'mt-0.5': tableMeta.rowHeight.height === 'short',
19456
19641
  'mt-1': tableMeta.rowHeight.height === 'medium',
@@ -19461,7 +19646,7 @@ function SaveStatus(props) {
19461
19646
  className: "!contents"
19462
19647
  }, /*#__PURE__*/React__default.createElement("span", {
19463
19648
  className: className
19464
- }, status === 'pending' ? (/*#__PURE__*/React__default.createElement(Tooltip, {
19649
+ }, status === 'saving' ? (/*#__PURE__*/React__default.createElement(Tooltip, {
19465
19650
  title: texts.table3.editing.saving.progress
19466
19651
  }, /*#__PURE__*/React__default.createElement(Spinner, {
19467
19652
  delay: 0,
@@ -19499,15 +19684,46 @@ function Row$2(props) {
19499
19684
  }
19500
19685
  }
19501
19686
  }, [tableMeta.editing.isEditing, isActiveRow]);
19687
+ const rowStatus = tableMeta.editing.getRowStatus(row.id);
19688
+ // discard new row
19689
+ const [showDiscardDialog, setShowDiscardDialog] = React__default.useState(false);
19690
+ function handleDiscard() {
19691
+ tableMeta.editing.discardChanges(row.id, table);
19692
+ requestAnimationFrame(() => {
19693
+ if (isTemporaryRow(row.id)) {
19694
+ var _tableMeta$editing$cr;
19695
+ (_tableMeta$editing$cr = tableMeta.editing.createRowButtonRef.current) === null || _tableMeta$editing$cr === void 0 ? void 0 : _tableMeta$editing$cr.focus();
19696
+ } else {
19697
+ focusManager.focusFirst();
19698
+ }
19699
+ });
19700
+ }
19701
+ function handleKeyDown(event) {
19702
+ if (props.onKeyDown) {
19703
+ props.onKeyDown(event);
19704
+ }
19705
+ if (event.isDefaultPrevented() || event.isPropagationStopped()) {
19706
+ return;
19707
+ }
19708
+ if (event.key === 'Escape' && tableMeta.editing.hasChanges(row.id) && !isElementTriggeredFromContainer(event.target, event.currentTarget)) {
19709
+ event.preventDefault();
19710
+ setShowDiscardDialog(true);
19711
+ }
19712
+ }
19502
19713
  const attributes = {
19503
- 'data-row-editing-invalid': tableMeta.editing.isEnabled && tableMeta.editing.hasRowErrors(row.id) ? !tableMeta.editing.hasRowErrorsSeen(row.id) ? 'unseen' : true : undefined,
19504
- 'data-row-editing-status': tableMeta.editing.isEnabled && tableMeta.editing.getRowSaveStatus(row.id) ? tableMeta.editing.getRowSaveStatus(row.id) : undefined,
19505
- onFocus: handleFocus
19714
+ 'data-row-editing-invalid': tableMeta.editing.hasRowErrors(row.id) ? !tableMeta.editing.hasRowErrorsShownInAlert(row.id) ? 'unseen' : true : undefined,
19715
+ 'data-row-editing-status': rowStatus,
19716
+ onFocus: handleFocus,
19717
+ onKeyDown: handleKeyDown
19506
19718
  };
19507
- return /*#__PURE__*/React__default.createElement(DisplayRow, Object.assign({}, props, attributes), tableMeta.editing.getRowSaveStatus(row.id) ? /*#__PURE__*/React__default.createElement(SaveStatus, {
19719
+ return /*#__PURE__*/React__default.createElement(React__default.Fragment, null, /*#__PURE__*/React__default.createElement(DisplayRow, Object.assign({}, props, attributes), rowStatus === 'saving' || rowStatus === 'saved' ? /*#__PURE__*/React__default.createElement(SaveStatus, {
19508
19720
  rowId: row.id,
19509
19721
  table: table
19510
- }) : null);
19722
+ }) : null), /*#__PURE__*/React__default.createElement(DiscardChangesConfirmationDialog, {
19723
+ open: showDiscardDialog,
19724
+ onChange: setShowDiscardDialog,
19725
+ onDiscard: handleDiscard
19726
+ }));
19511
19727
  }
19512
19728
 
19513
19729
  const RENDERERS$1 = {
@@ -19515,29 +19731,46 @@ const RENDERERS$1 = {
19515
19731
  cell: Cell$5
19516
19732
  };
19517
19733
  function useTable3(props, ref) {
19518
- const editing = useTableEditing(props.enableEditing, props.onEditingSave, props.onEditingChange, props.validator);
19734
+ const editing = useTableEditing(props.enableEditing, props.onEditingSave, props.onEditingChange, props.rowIdentityAccessor, props.validator);
19519
19735
  const creationEnabled = editing.isEnabled && !!props.onEditingCreate;
19736
+ // this gives me the performance heeby jeebies, but can't think of a better way to internalise the state
19737
+ const data = React__default.useMemo(() => {
19738
+ if (editing.temporaryRows.length) {
19739
+ var _props$data;
19740
+ return ((_props$data = props.data) !== null && _props$data !== void 0 ? _props$data : []).concat(editing.temporaryRows);
19741
+ }
19742
+ return props.data;
19743
+ }, [JSON.stringify(props.data), editing.temporaryRows.length]);
19520
19744
  const extendedProps = {
19521
19745
  ...props,
19746
+ data,
19522
19747
  enableRowActions: editing.isEditing ? true : props.enableRowActions,
19523
- rowActions: editing.isEditing ? [(_, rowId) => (/*#__PURE__*/React__default.createElement(EditingActionMenu, {
19748
+ rowActions: editing.isEditing ? [(_, rowId, table) => (/*#__PURE__*/React__default.createElement(EditingActionMenu, {
19524
19749
  hasChanges: editing.hasChanges(rowId),
19525
19750
  hasErrors: editing.hasRowErrors(rowId),
19526
- onClear: () => editing.resetChanges(rowId),
19527
- onEditingSave: () => editing.saveChanges(rowId),
19528
- onExit: () => editing.toggleEditing(false),
19751
+ onDiscard: () => editing.discardChanges(rowId, table),
19752
+ onEditingSave: function () {
19753
+ try {
19754
+ return Promise.resolve(editing.saveChanges(table, rowId)).then(function () {});
19755
+ } catch (e) {
19756
+ return Promise.reject(e);
19757
+ }
19758
+ },
19529
19759
  isLastRow: !creationEnabled && table.meta.rowActive.rowActiveIndex === table.meta.length - 1
19530
19760
  }))] : props.rowActions
19531
19761
  };
19532
19762
  const meta = {
19533
19763
  editing
19534
19764
  };
19535
- const table = useTable(extendedProps, ref, RENDERERS$1, meta);
19765
+ const options = {
19766
+ virtualiserPaddingEndOffset: props.enableEditing && props.onEditingCreate ? 1 : 0
19767
+ };
19768
+ const table = useTable(extendedProps, ref, RENDERERS$1, meta, options);
19536
19769
  // listeners
19537
- useTableEditingListener(table.instance, table.ref);
19770
+ useTableEditingListener(table.instance, table.ref, table.renderer.scrollToIndex);
19538
19771
  React__default.useEffect(() => {
19539
19772
  if (table.ref.current) {
19540
- table.ref.current.instance.toggleEditing = enabled => table.meta.editing.toggleEditing(enabled !== null && enabled !== void 0 ? enabled : editing => !editing);
19773
+ table.ref.current.instance.toggleEditing = enabled => table.meta.editing.toggleEditing(enabled !== null && enabled !== void 0 ? enabled : editing => !editing, table.instance, table.renderer.scrollToIndex);
19541
19774
  }
19542
19775
  }, [table.ref.current]);
19543
19776
  return table;
@@ -19556,7 +19789,7 @@ function Alert$1(props) {
19556
19789
  const validationTexts = texts.table3.editing.validation;
19557
19790
  const tableMeta = table.options.meta;
19558
19791
  const [showFilterResetDialog, setShowFilterResetDialog] = React__default.useState(false);
19559
- const pendingChangesWithErrors = tableMeta.editing.getAlertErrors();
19792
+ const pendingChangesWithErrors = tableMeta.editing.getErrorsShownInAlert();
19560
19793
  function scrollToRow(rowIndex) {
19561
19794
  tableMeta.rowActive.setRowActiveIndex(rowIndex);
19562
19795
  scrollToIndex(rowIndex, {
@@ -19575,38 +19808,43 @@ function Alert$1(props) {
19575
19808
  const title = (pendingChangesWithErrors.length === 1 ? validationTexts.alert.titleOne : validationTexts.alert.titlePlural).replace('[COUNT]', String(pendingChangesWithErrors.length));
19576
19809
  // generate links to each invalid row, to go into the error message
19577
19810
  const links = [];
19578
- const rowIdentityColumn = tableMeta.rowIdentityColumnId ? table.getColumn(tableMeta.rowIdentityColumnId) : undefined;
19579
- pendingChangesWithErrors.forEach((error, index) => {
19811
+ const visibleColumns = table.getVisibleFlatColumns().map(c => c.id);
19812
+ const rowIdentityColumn = tableMeta.rowIdentityAccessor && visibleColumns.includes(String(tableMeta.rowIdentityAccessor)) ? table.getColumn(String(tableMeta.rowIdentityAccessor)) : undefined;
19813
+ pendingChangesWithErrors.forEach((pendingChangeWithError, index) => {
19580
19814
  // if appropriate, concatenate the item with the text "and"
19581
19815
  if (pendingChangesWithErrors.length > 1 && index === pendingChangesWithErrors.length - 1) {
19582
19816
  // Add space before and after `messageAnd` text
19583
19817
  links.push(` ${validationTexts.alert.messageAnd} `);
19584
19818
  }
19585
- const rowIndex = table.getRowModel().rows.findIndex(row => row.id === error.rowId);
19819
+ const rowIndex = table.getRowModel().rows.findIndex(row => row.id === pendingChangeWithError.rowId);
19586
19820
  const handleClick = () => {
19821
+ // if row is visible
19587
19822
  if (rowIndex > -1) {
19588
19823
  scrollToRow(rowIndex);
19589
- } else {
19590
- setShowFilterResetDialog(error.rowId);
19824
+ }
19825
+ // if row is filtered out
19826
+ else {
19827
+ setShowFilterResetDialog(pendingChangeWithError.rowId);
19591
19828
  }
19592
19829
  };
19593
19830
  let tooltip;
19594
- if (error.pendingChange._meta.errors.row) {
19595
- tooltip = error.pendingChange._meta.errors.row;
19831
+ if (pendingChangeWithError.errors.row) {
19832
+ tooltip = pendingChangeWithError.errors.row;
19596
19833
  } else {
19597
19834
  var _table$getAllColumns$, _table$getAllColumns$2;
19598
- const firstCellErrorColumnId = Object.keys(error.pendingChange._meta.errors.cells)[0];
19835
+ const firstCellErrorColumnId = Object.keys(pendingChangeWithError.errors.cells)[0];
19599
19836
  const columnName = (_table$getAllColumns$ = table.getAllColumns().find(column => column.id === firstCellErrorColumnId)) === null || _table$getAllColumns$ === void 0 ? void 0 : (_table$getAllColumns$2 = _table$getAllColumns$.columnDef.meta) === null || _table$getAllColumns$2 === void 0 ? void 0 : _table$getAllColumns$2.header;
19600
- tooltip = `${columnName}: ${error.pendingChange._meta.errors.cells[firstCellErrorColumnId]}`;
19837
+ tooltip = `${columnName}: ${pendingChangeWithError.errors.cells[firstCellErrorColumnId]}`;
19601
19838
  }
19839
+ const row = table.getRow(pendingChangeWithError.rowId).original;
19602
19840
  links.push(/*#__PURE__*/React__default.createElement(Tooltip, {
19603
- key: error.rowId,
19841
+ key: pendingChangeWithError.rowId,
19604
19842
  title: tooltip
19605
19843
  }, /*#__PURE__*/React__default.createElement("span", {
19606
19844
  className: "text-blue",
19607
19845
  onClick: handleClick,
19608
19846
  role: "button"
19609
- }, rowIdentityColumn ? error.pendingChange._meta.original[rowIdentityColumn.id] : rowIndex + 1)));
19847
+ }, rowIdentityColumn ? row[rowIdentityColumn.id] : rowIndex + 1)));
19610
19848
  // if appropriate, concatenate the item with the text ","
19611
19849
  if (pendingChangesWithErrors.length > 2 && index < pendingChangesWithErrors.length - 2) {
19612
19850
  links.push(', ');
@@ -19662,9 +19900,38 @@ function FilterResetDialog(props) {
19662
19900
  }, texts.table3.editing.validation.resetFiltersDialog.confirm)))));
19663
19901
  }
19664
19902
 
19665
- function CreateNewRowButton(props) {
19903
+ function Editing(props) {
19666
19904
  const {
19667
- onEditingCreate,
19905
+ scrollToIndex,
19906
+ table
19907
+ } = props;
19908
+ const {
19909
+ texts
19910
+ } = useLocalization();
19911
+ const ref = React__default.useRef(null);
19912
+ const tableMeta = table.options.meta;
19913
+ const handleChange = enabled => {
19914
+ tableMeta.editing.toggleEditing(enabled, table, scrollToIndex);
19915
+ };
19916
+ const tooltip = /*#__PURE__*/React__default.createElement(React__default.Fragment, null, texts.table3.editing.buttons.edit.tooltip, /*#__PURE__*/React__default.createElement(Shortcut, {
19917
+ className: "ml-2",
19918
+ keys: shortcut
19919
+ }));
19920
+ return /*#__PURE__*/React__default.createElement(Tooltip, {
19921
+ title: tooltip
19922
+ }, /*#__PURE__*/React__default.createElement(ModeSwitch, {
19923
+ "data-table": "editing-toggle",
19924
+ checked: tableMeta.editing.isEditing,
19925
+ onChange: handleChange,
19926
+ ref: ref
19927
+ }));
19928
+ }
19929
+
19930
+ function CreateNewRow(props) {
19931
+ var _temporaryRows$0$tabl, _temporaryRows$, _table$getState$colum;
19932
+ const {
19933
+ buttonRef,
19934
+ onEditingCreate: handleEditingCreate,
19668
19935
  scrollToIndex,
19669
19936
  table,
19670
19937
  tableMeta
@@ -19672,117 +19939,152 @@ function CreateNewRowButton(props) {
19672
19939
  const {
19673
19940
  texts
19674
19941
  } = useLocalization();
19675
- const rows = table.getCoreRowModel().rows.filter(row => row.original !== undefined);
19676
- const [rowCreated, setRowCreated] = React__default.useState({
19677
- rowFinder: undefined
19678
- });
19679
- const handleKeyDown = event => {
19680
- if (!tableMeta.editing.hasChanges() && event.key === 'Tab') {
19681
- tableMeta.editing.saveChanges();
19682
- }
19683
- };
19684
- const handleCreate = function () {
19942
+ const temporaryRows = tableMeta.editing.temporaryRows;
19943
+ const temporaryRowId = (_temporaryRows$0$tabl = (_temporaryRows$ = temporaryRows[0]) === null || _temporaryRows$ === void 0 ? void 0 : _temporaryRows$[tableMeta.rowIdentityAccessor]) !== null && _temporaryRows$0$tabl !== void 0 ? _temporaryRows$0$tabl : '';
19944
+ const isDisabled = !!table.getState().globalFilter || !!((_table$getState$colum = table.getState().columnFilters) !== null && _table$getState$colum !== void 0 && _table$getState$colum.length) || !!temporaryRowId && !!tableMeta.editing.hasRowErrors(temporaryRowId);
19945
+ const isSaving = !!temporaryRowId && tableMeta.editing.getRowStatus(temporaryRowId) === 'saving';
19946
+ const handleCreate = function (event) {
19685
19947
  try {
19686
- if (!onEditingCreate) {
19948
+ // prevent save being triggered by click outside - TODO: investigate why the button triggers clickoutside
19949
+ event === null || event === void 0 ? void 0 : event.stopPropagation();
19950
+ if (!handleEditingCreate || isDisabled) {
19687
19951
  return Promise.resolve();
19688
19952
  }
19689
- const createdRow = rows.find(row => {
19690
- var _rowCreated$rowFinder;
19691
- return rowCreated === null || rowCreated === void 0 ? void 0 : (_rowCreated$rowFinder = rowCreated.rowFinder) === null || _rowCreated$rowFinder === void 0 ? void 0 : _rowCreated$rowFinder.call(rowCreated, row.original);
19692
- });
19693
- const _temp = function () {
19694
- if (createdRow) {
19695
- return Promise.resolve(tableMeta.editing.saveChanges()).then(function () {
19696
- if (!tableMeta.editing.hasRowErrors(createdRow.id)) {
19697
- const rowFinder = onEditingCreate();
19698
- setRowCreated({
19699
- rowFinder
19953
+ return Promise.resolve(tableMeta.editing.saveChanges(table)).then(function (saved) {
19954
+ if (!saved) {
19955
+ return;
19956
+ }
19957
+ return _catch(function () {
19958
+ const changeset = handleEditingCreate();
19959
+ const _temp = function () {
19960
+ if (changeset) {
19961
+ return Promise.resolve(tableMeta.editing.createRow(changeset)).then(function (rowId) {
19962
+ table.getRow(rowId).pin('bottom');
19963
+ // set the active row to the new row before toggling editing on
19964
+ const nextRowIndex = temporaryRows.length ? tableMeta.length + 1 : tableMeta.length;
19965
+ tableMeta.rowActive.setRowActiveIndex(nextRowIndex);
19966
+ tableMeta.editing.toggleEditing(true, table, scrollToIndex);
19967
+ tableMeta.editing.setLastFocusedCellIndex(0);
19700
19968
  });
19701
19969
  }
19702
- });
19703
- } else {
19704
- const rowFinder = onEditingCreate();
19705
- setRowCreated({
19706
- rowFinder
19707
- });
19708
- }
19709
- }();
19710
- return Promise.resolve(_temp && _temp.then ? _temp.then(function () {}) : void 0);
19970
+ }();
19971
+ if (_temp && _temp.then) return _temp.then(function () {});
19972
+ }, function (error) {
19973
+ console.error(error);
19974
+ });
19975
+ });
19711
19976
  } catch (e) {
19712
19977
  return Promise.reject(e);
19713
19978
  }
19714
19979
  };
19715
- React__default.useEffect(() => {
19716
- if (typeof (rowCreated === null || rowCreated === void 0 ? void 0 : rowCreated.rowFinder) === 'function') {
19717
- const createdRow = rows.find(row => {
19718
- var _rowCreated$rowFinder2;
19719
- return rowCreated === null || rowCreated === void 0 ? void 0 : (_rowCreated$rowFinder2 = rowCreated.rowFinder) === null || _rowCreated$rowFinder2 === void 0 ? void 0 : _rowCreated$rowFinder2.call(rowCreated, row.original);
19720
- });
19721
- if (createdRow) {
19722
- const rowInTable = table.getRowModel().rows.filter(row => row.original !== undefined).find(row => {
19723
- var _rowCreated$rowFinder3;
19724
- return rowCreated === null || rowCreated === void 0 ? void 0 : (_rowCreated$rowFinder3 = rowCreated.rowFinder) === null || _rowCreated$rowFinder3 === void 0 ? void 0 : _rowCreated$rowFinder3.call(rowCreated, row.original);
19725
- });
19726
- if (rowInTable) {
19727
- tableMeta.editing.toggleEditing(true);
19728
- tableMeta.rowActive.setRowActiveIndex(createdRow.index);
19729
- scrollToIndex(createdRow.index);
19730
- requestAnimationFrame(() => animateCreateRow(createdRow.id));
19731
- }
19732
- requestAnimationFrame(() => tableMeta.editing.addCreatedRowChangeset(createdRow));
19733
- }
19734
- }
19735
- }, [rowCreated]);
19980
+ let tooltip;
19981
+ if (isSaving) {
19982
+ tooltip = texts.table3.editing.buttons.create.saving;
19983
+ } else if (isDisabled) {
19984
+ tooltip = texts.table3.editing.buttons.create.disabled;
19985
+ }
19736
19986
  return /*#__PURE__*/React__default.createElement("tr", {
19737
- onClick: handleCreate,
19738
- className: "border-grey-300 hover:bg-grey-100 group !sticky bottom-10 left-0 z-[21] !block cursor-pointer border-t"
19987
+ "data-row-create": true,
19988
+ className: "border-grey-300 group/row",
19989
+ tabIndex: -1
19739
19990
  }, /*#__PURE__*/React__default.createElement("td", {
19740
- className: "!border-t-0 !bg-transparent"
19991
+ className: "!bg-grey-50 col-span-full !border-b-0 !px-1"
19741
19992
  }, /*#__PURE__*/React__default.createElement(Button$1, {
19742
- onKeyDown: handleKeyDown,
19743
- className: "group-hover:bg-grey-200 sticky left-0",
19744
- appearance: "transparent"
19745
- }, "+ ", texts.table3.editing.buttons.create.label)));
19993
+ appearance: "transparent",
19994
+ className: "group-hover:bg-grey-200 sticky left-[4px]",
19995
+ disabled: isDisabled,
19996
+ onClick: handleCreate,
19997
+ ref: buttonRef,
19998
+ tooltip: tooltip
19999
+ }, /*#__PURE__*/React__default.createElement(Icon, {
20000
+ name: "circle-plus"
20001
+ }), texts.table3.editing.buttons.create.label)));
19746
20002
  }
19747
20003
 
19748
- function Editing(props) {
20004
+ function TemporaryRow(props) {
20005
+ var _tableRef$current, _tableRef$current2;
19749
20006
  const {
19750
- scrollToIndex,
19751
- table
20007
+ createRowButtonRef,
20008
+ table,
20009
+ tableMeta,
20010
+ tableRef
19752
20011
  } = props;
19753
- const {
19754
- texts
19755
- } = useLocalization();
19756
- const ref = React__default.useRef(null);
19757
- const tableMeta = table.options.meta;
19758
- const shortcut = {
19759
- key: 'e',
19760
- meta: true,
19761
- shift: false
20012
+ const isScrolled = tableRef.current ? ((_tableRef$current = tableRef.current) === null || _tableRef$current === void 0 ? void 0 : _tableRef$current.scrollHeight) > ((_tableRef$current2 = tableRef.current) === null || _tableRef$current2 === void 0 ? void 0 : _tableRef$current2.clientHeight) : false;
20013
+ const handleKeyDown = function (event) {
20014
+ try {
20015
+ const _temp2 = function () {
20016
+ if (event.key === 'ArrowDown') {
20017
+ event.preventDefault();
20018
+ const _temp = function () {
20019
+ if (!isElementTriggeredFromContainer(event.target, event.currentTarget)) {
20020
+ return Promise.resolve(tableMeta.editing.saveChanges(table)).then(function (saved) {
20021
+ if (saved) {
20022
+ var _createRowButtonRef$c;
20023
+ (_createRowButtonRef$c = createRowButtonRef.current) === null || _createRowButtonRef$c === void 0 ? void 0 : _createRowButtonRef$c.focus();
20024
+ }
20025
+ });
20026
+ }
20027
+ }();
20028
+ if (_temp && _temp.then) return _temp.then(function () {});
20029
+ } else if (event.key === 'ArrowUp') {
20030
+ event.preventDefault();
20031
+ event.stopPropagation();
20032
+ if (tableRef.current) {
20033
+ var _tableRef$current$que, _tableRef$current$que2, _tableRef$current$que3;
20034
+ const availableRows = Array.from((_tableRef$current$que = tableRef.current.querySelectorAll(`tbody tr:not([data-row-id^='${TEMPORARY_ROW_ID_PREFIX}'])`)) !== null && _tableRef$current$que !== void 0 ? _tableRef$current$que : []);
20035
+ const footerHeight = (_tableRef$current$que2 = (_tableRef$current$que3 = tableRef.current.querySelector('tfoot')) === null || _tableRef$current$que3 === void 0 ? void 0 : _tableRef$current$que3.getBoundingClientRect().height) !== null && _tableRef$current$que2 !== void 0 ? _tableRef$current$que2 : 0;
20036
+ const newRowHeight = event.currentTarget.getBoundingClientRect().height;
20037
+ const visibleHeight = tableRef.current.clientHeight - footerHeight - newRowHeight;
20038
+ const tableTopOffset = tableRef.current.getBoundingClientRect().top;
20039
+ let nextRowIndex;
20040
+ // iterate available rows in reverse order, since we're working at the bottom
20041
+ for (let index = availableRows.length - 1; index >= 0; index--) {
20042
+ const rowRect = availableRows[index].getBoundingClientRect();
20043
+ const topPlusHalfRow = rowRect.top + rowRect.height / 2;
20044
+ if (topPlusHalfRow - tableTopOffset <= visibleHeight) {
20045
+ nextRowIndex = index;
20046
+ break;
20047
+ }
20048
+ }
20049
+ if (nextRowIndex) {
20050
+ tableMeta.rowActive.setRowActiveIndex(Number(availableRows[nextRowIndex < 0 ? 0 : nextRowIndex].getAttribute('data-row-index')));
20051
+ }
20052
+ }
20053
+ }
20054
+ }();
20055
+ return Promise.resolve(_temp2 && _temp2.then ? _temp2.then(function () {}) : void 0);
20056
+ } catch (e) {
20057
+ return Promise.reject(e);
20058
+ }
19762
20059
  };
19763
- const tooltip = /*#__PURE__*/React__default.createElement(React__default.Fragment, null, texts.table3.editing.buttons.edit.tooltip, /*#__PURE__*/React__default.createElement(Shortcut, {
19764
- className: "ml-2",
19765
- keys: shortcut
19766
- }));
19767
- useGlobalKeyDown(shortcut, event => {
19768
- var _ref$current;
19769
- event.preventDefault();
19770
- (_ref$current = ref.current) === null || _ref$current === void 0 ? void 0 : _ref$current.click();
19771
- });
19772
- const handleChange = enabled => {
19773
- tableMeta.editing.toggleEditing(enabled);
19774
- requestAnimationFrame(() => {
19775
- var _tableMeta$rowActive$;
19776
- return scrollToIndex((_tableMeta$rowActive$ = tableMeta.rowActive.rowActiveIndex) !== null && _tableMeta$rowActive$ !== void 0 ? _tableMeta$rowActive$ : 0);
19777
- });
20060
+ const handleKeyDownCapture = event => {
20061
+ if (event.key === 'ArrowLeft' && tableMeta.editing.lastFocusedCellIndex === 0) {
20062
+ event.preventDefault();
20063
+ event.stopPropagation();
20064
+ } else if (event.key === 'ArrowRight' && tableMeta.editing.lastFocusedCellIndex) {
20065
+ if (tableMeta.editing.lastFocusedCellIndex === table.getVisibleFlatColumns().length - 1) {
20066
+ event.preventDefault();
20067
+ event.stopPropagation();
20068
+ }
20069
+ }
19778
20070
  };
19779
- return /*#__PURE__*/React__default.createElement(Tooltip, {
19780
- title: tooltip
19781
- }, /*#__PURE__*/React__default.createElement(ModeSwitch, {
19782
- checked: tableMeta.editing.isEditing,
19783
- onChange: handleChange,
19784
- ref: ref
19785
- }));
20071
+ const className = cn('group/row border-grey-300 !sticky z-[21]', {
20072
+ 'bottom-20 data-[row-editing-move]:bottom-[calc(5rem_+_2px)]': tableMeta.footer.isEnabled,
20073
+ 'bottom-10 data-[row-editing-move]:bottom-[calc(2.5rem_+_2px)]': !tableMeta.footer.isEnabled,
20074
+ 'border-b border-t shadow-[0px_-5px_20px_0px_rgba(0,0,0,0.1)] border-t-grey-500/[0.75]': isScrolled
20075
+ });
20076
+ return /*#__PURE__*/React__default.createElement(React__default.Fragment, null, table.getBottomRows().map(row => (/*#__PURE__*/React__default.createElement(Row, {
20077
+ key: row.id,
20078
+ cellRenderer: RENDERERS$1.cell,
20079
+ index: tableMeta.length,
20080
+ measureRow: () => null,
20081
+ renderer: RENDERERS$1.row,
20082
+ row: row,
20083
+ table: table,
20084
+ className: className,
20085
+ onKeyDown: handleKeyDown,
20086
+ onKeyDownCapture: handleKeyDownCapture
20087
+ }))));
19786
20088
  }
19787
20089
 
19788
20090
  function Column$3(_) {
@@ -19800,8 +20102,19 @@ const BaseTable3 = /*#__PURE__*/fixedForwardRef(function BaseTable3(props, ref)
19800
20102
  'data-table-editing-mode': (_table3$meta$editing = table3.meta.editing) !== null && _table3$meta$editing !== void 0 && _table3$meta$editing.isEditing ? (_table3$meta$editing2 = table3.meta.editing) !== null && _table3$meta$editing2 !== void 0 && _table3$meta$editing2.isDetailedMode ? 'detailed' : 'normal' : undefined,
19801
20103
  enableHorizontalArrowKeyNavigation: table3.meta.editing.isEditing
19802
20104
  };
19803
- const hasAlertErrors = table3.meta.editing.hasAlertErrors();
19804
- const showCreateRowButton = table3.meta.editing.isEnabled && props.onEditingCreate;
20105
+ const hasAlertErrors = table3.meta.editing.getErrorsShownInAlert().length;
20106
+ const hasCreateWorkflow = table3.meta.editing.isEnabled && props.onEditingCreate;
20107
+ let footerRows;
20108
+ if (hasCreateWorkflow) {
20109
+ footerRows = /*#__PURE__*/React__default.createElement(React__default.Fragment, null, /*#__PURE__*/React__default.createElement(CreateNewRow, {
20110
+ buttonRef: table3.meta.editing.createRowButtonRef,
20111
+ onEditingCreate: props.onEditingCreate,
20112
+ scrollToIndex: table3.renderer.scrollToIndex,
20113
+ table: table3.instance,
20114
+ tableMeta: table3.meta,
20115
+ tableRef: table3.ref
20116
+ }));
20117
+ }
19805
20118
  return /*#__PURE__*/React__default.createElement(Table, null, /*#__PURE__*/React__default.createElement(Table.Toolbar, {
19806
20119
  table: table3
19807
20120
  }, table3.meta.editing.isEnabled ? (/*#__PURE__*/React__default.createElement(Editing, {
@@ -19814,13 +20127,14 @@ const BaseTable3 = /*#__PURE__*/fixedForwardRef(function BaseTable3(props, ref)
19814
20127
  tableRef: table3.ref
19815
20128
  })) : null, /*#__PURE__*/React__default.createElement(Table.Grid, Object.assign({}, gridAttributes, {
19816
20129
  "data-taco": "table3",
20130
+ rowsForFooter: footerRows,
19817
20131
  table: table3
19818
- }), showCreateRowButton && (/*#__PURE__*/React__default.createElement(CreateNewRowButton, {
20132
+ }), hasCreateWorkflow ? (/*#__PURE__*/React__default.createElement(TemporaryRow, {
20133
+ createRowButtonRef: table3.meta.editing.createRowButtonRef,
19819
20134
  table: table3.instance,
19820
20135
  tableMeta: table3.meta,
19821
- onEditingCreate: props.onEditingCreate,
19822
- scrollToIndex: table3.renderer.scrollToIndex
19823
- }))));
20136
+ tableRef: table3.ref
20137
+ })) : null));
19824
20138
  });
19825
20139
  const Table3 = /*#__PURE__*/fixedForwardRef(function Table3(props, ref) {
19826
20140
  const stringifiedChildren = String(props.children);