@economic/taco 2.44.3 → 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 (101) 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 -0
  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/Option.js +0 -1
  58. package/dist/esm/packages/taco/src/primitives/Listbox2/components/Option.js.map +1 -1
  59. package/dist/esm/packages/taco/src/primitives/Listbox2/components/Root.js +1 -0
  60. package/dist/esm/packages/taco/src/primitives/Listbox2/components/Root.js.map +1 -1
  61. package/dist/esm/packages/taco/src/primitives/Table/Core/Table.js +3 -4
  62. package/dist/esm/packages/taco/src/primitives/Table/Core/Table.js.map +1 -1
  63. package/dist/esm/packages/taco/src/primitives/Table/Core/components/Columns/Cell/BuiltIns/GroupedCell.js +9 -3
  64. package/dist/esm/packages/taco/src/primitives/Table/Core/components/Columns/Cell/BuiltIns/GroupedCell.js.map +1 -1
  65. package/dist/esm/packages/taco/src/primitives/Table/Core/components/Columns/Internal/Actions.js +6 -3
  66. package/dist/esm/packages/taco/src/primitives/Table/Core/components/Columns/Internal/Actions.js.map +1 -1
  67. package/dist/esm/packages/taco/src/primitives/Table/Core/components/Footer/Footer.js +1 -1
  68. package/dist/esm/packages/taco/src/primitives/Table/Core/components/Footer/Footer.js.map +1 -1
  69. package/dist/esm/packages/taco/src/primitives/Table/Core/components/Row/BuiltIns/DisplayRow.js +1 -1
  70. package/dist/esm/packages/taco/src/primitives/Table/Core/components/Row/BuiltIns/DisplayRow.js.map +1 -1
  71. package/dist/esm/packages/taco/src/primitives/Table/Core/features/useTableRenderer.js +25 -7
  72. package/dist/esm/packages/taco/src/primitives/Table/Core/features/useTableRenderer.js.map +1 -1
  73. package/dist/esm/packages/taco/src/primitives/Table/Core/useTable.js +2 -2
  74. package/dist/esm/packages/taco/src/primitives/Table/Core/useTable.js.map +1 -1
  75. package/dist/esm/packages/taco/src/primitives/Table/types.js.map +1 -1
  76. package/dist/esm/packages/taco/src/primitives/Table/useTableManager/useTableManager.js +1 -1
  77. package/dist/esm/packages/taco/src/primitives/Table/useTableManager/useTableManager.js.map +1 -1
  78. package/dist/esm/packages/taco/src/primitives/Table/useTableManager/util/setup.js +11 -0
  79. package/dist/esm/packages/taco/src/primitives/Table/useTableManager/util/setup.js.map +1 -1
  80. package/dist/esm/packages/taco/src/utils/dom.js +7 -4
  81. package/dist/esm/packages/taco/src/utils/dom.js.map +1 -1
  82. package/dist/index.css +28 -4
  83. package/dist/primitives/Collection/components/Root.d.ts +2 -0
  84. package/dist/primitives/Table/Core/Table.d.ts +1 -0
  85. package/dist/primitives/Table/Core/components/Columns/Internal/Actions.d.ts +3 -1
  86. package/dist/primitives/Table/Core/components/Footer/Footer.d.ts +2 -2
  87. package/dist/primitives/Table/Core/features/useTableRenderer.d.ts +2 -2
  88. package/dist/primitives/Table/Core/features/useTableStyle.d.ts +1 -1
  89. package/dist/primitives/Table/Core/types.d.ts +3 -0
  90. package/dist/primitives/Table/Core/useTable.d.ts +2 -2
  91. package/dist/primitives/Table/types.d.ts +1 -1
  92. package/dist/primitives/Table/useTableManager/useTableManager.d.ts +1 -1
  93. package/dist/taco.cjs.development.js +983 -668
  94. package/dist/taco.cjs.development.js.map +1 -1
  95. package/dist/taco.cjs.production.min.js +1 -1
  96. package/dist/taco.cjs.production.min.js.map +1 -1
  97. package/dist/utils/dom.d.ts +1 -0
  98. package/package.json +3 -5
  99. package/dist/components/Table3/components/Row/Editing/CreateRowButton.d.ts +0 -11
  100. package/dist/esm/packages/taco/src/components/Table3/components/Row/Editing/CreateRowButton.js +0 -90
  101. 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,14 +14461,31 @@ 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);
14422
14482
  if (options.length) {
14423
14483
  let selected = internalRef.current.querySelectorAll(`[aria-current="true"]`);
14484
+ // if nothing is current (keyboard visible), look for selected items
14424
14485
  if (selected.length === 0) {
14425
14486
  selected = internalRef.current.querySelectorAll(`[aria-selected]`);
14426
14487
  }
14488
+ // if one item is selected, make sure it's current
14427
14489
  if (selected.length === 1) {
14428
14490
  if (options) {
14429
14491
  const firstSelected = selected.item(0);
@@ -14569,6 +14631,7 @@ const Root$1 = /*#__PURE__*/React__default.forwardRef(function Listbox2(props, r
14569
14631
  id: id,
14570
14632
  querySelector: customSelector ? `${DEFAULT_SELECTOR}, ${customSelector}` : DEFAULT_SELECTOR,
14571
14633
  ref: ref,
14634
+ resetOnChange: value,
14572
14635
  role: "listbox"
14573
14636
  }), children)));
14574
14637
  });
@@ -14641,7 +14704,6 @@ const Option = /*#__PURE__*/React__default.forwardRef(function Listbox2Option(pr
14641
14704
  return /*#__PURE__*/React__default.createElement("div", Object.assign({}, otherProps, {
14642
14705
  "aria-disabled": listboxDisabled || disabled ? 'true' : undefined,
14643
14706
  "aria-selected": selected ? 'true' : undefined,
14644
- key: `${value}_${String(selected)}`,
14645
14707
  id: id,
14646
14708
  onClick: handleClick,
14647
14709
  onKeyDown: handleKeyDown,
@@ -16754,6 +16816,7 @@ function TableGrid(props) {
16754
16816
  var _table$state$grouping;
16755
16817
  const {
16756
16818
  enableHorizontalArrowKeyNavigation,
16819
+ rowsForFooter,
16757
16820
  table,
16758
16821
  ...attributes
16759
16822
  } = props;
@@ -16761,8 +16824,6 @@ function TableGrid(props) {
16761
16824
  table.meta.rowActive.handleFocus(event, table.meta.length, table.renderer.scrollToIndex);
16762
16825
  } : undefined;
16763
16826
  const filterReason = getFilterReason(table);
16764
- const searchNotApplied = !table.state.globalFilter || table.state.globalFilter === '';
16765
- const filtersNotApplied = !table.state.columnFilters || table.state.columnFilters.length === 0;
16766
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, {
16767
16828
  id: table.id,
16768
16829
  "data-table-font-size": table.meta.fontSize.size,
@@ -16795,9 +16856,9 @@ function TableGrid(props) {
16795
16856
  ...table.renderer.style,
16796
16857
  height: table.renderer.style.height + ROW_HEIGHT_ESTIMATES[table.meta.rowHeight.height]
16797
16858
  } : table.renderer.style
16798
- }, 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, {
16799
16860
  table: table.instance
16800
- }) : null)))));
16861
+ }, rowsForFooter) : null)))));
16801
16862
  }
16802
16863
 
16803
16864
  function Column$1(_) {
@@ -18298,71 +18359,6 @@ const useTableRowCreation = (data, tableRef) => {
18298
18359
  };
18299
18360
  };
18300
18361
 
18301
- function useTableEditingListener(table, tableRef) {
18302
- const tableMeta = table.options.meta;
18303
- const completedRowsCount = tableMeta.editing.getCompletedRowsCount();
18304
- const localization = useLocalization();
18305
- const saveChanges = () => {
18306
- requestAnimationFrame(() => {
18307
- tableMeta.editing.saveChanges();
18308
- });
18309
- };
18310
- // save when the row changes
18311
- useLazyEffect(() => {
18312
- if (tableMeta.editing.isEditing) {
18313
- saveChanges();
18314
- }
18315
- }, [tableMeta.rowActive.rowActiveIndex]);
18316
- useLazyEffect(() => {
18317
- if (tableMeta.editing.isEditing) {
18318
- if (tableMeta.rowActive.rowActiveIndex === undefined) {
18319
- tableMeta.rowActive.setRowActiveIndex(0);
18320
- }
18321
- } else {
18322
- // save
18323
- saveChanges();
18324
- // reset detailed mode
18325
- tableMeta.editing.toggleDetailedMode(false);
18326
- // reset the last index back to the first focusable element, when editing gets turned off
18327
- tableMeta.editing.setLastFocusedCellIndex(undefined);
18328
- }
18329
- }, [tableMeta.editing.isEditing]);
18330
- // show a warning if the user navigates away without triggering save, such as using the browser back/forward button
18331
- const hasChanges = tableMeta.editing.hasChanges();
18332
- React__default.useEffect(() => {
18333
- function showUnsavedChangesWarning(event) {
18334
- if (tableMeta.editing.isEditing && hasChanges) {
18335
- event.returnValue = true;
18336
- return true;
18337
- }
18338
- return false;
18339
- }
18340
- window.addEventListener('beforeunload', showUnsavedChangesWarning);
18341
- return () => {
18342
- window.removeEventListener('beforeunload', showUnsavedChangesWarning);
18343
- };
18344
- }, [tableMeta.editing.isEditing, hasChanges]);
18345
- React__default.useEffect(() => {
18346
- if (completedRowsCount > 0) {
18347
- resetHighlightedColumnIndexes(table.getState().globalFilter, table, localization);
18348
- }
18349
- }, [completedRowsCount]);
18350
- React__default.useEffect(() => {
18351
- const onClickOutside = event => {
18352
- if (tableMeta.editing.isEditing) {
18353
- var _event$target$getAttr, _event$target;
18354
- 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 : '';
18355
- const insideTable = isElementInsideOrTriggeredFromContainer(event.target, tableRef.current) || element === 'backdrop';
18356
- if (!insideTable) {
18357
- saveChanges();
18358
- }
18359
- }
18360
- };
18361
- document.addEventListener('click', onClickOutside);
18362
- return () => document.removeEventListener('click', onClickOutside);
18363
- }, [saveChanges, tableMeta.editing.isEditing]);
18364
- }
18365
-
18366
18362
  function willRowMove(cell, change, rowIndex, localization) {
18367
18363
  const {
18368
18364
  table
@@ -18430,6 +18426,8 @@ function willRowMoveAfterSorting(cell, change, rowIndex) {
18430
18426
  const aUndefined = aValue === undefined;
18431
18427
  const bUndefined = bValue === undefined;
18432
18428
  if (aUndefined || bUndefined) {
18429
+ if (sortUndefined === 'first') return aUndefined ? -1 : 1;
18430
+ if (sortUndefined === 'last') return aUndefined ? 1 : -1;
18433
18431
  return aUndefined && bUndefined ? 0 : aUndefined ? sortUndefined : -sortUndefined;
18434
18432
  }
18435
18433
  }
@@ -18440,444 +18438,635 @@ function willRowMoveAfterSorting(cell, change, rowIndex) {
18440
18438
  }
18441
18439
  return ((_resortedRows$index = resortedRows[index]) === null || _resortedRows$index === void 0 ? void 0 : _resortedRows$index.id) !== cell.row.id;
18442
18440
  }
18443
- function animateCreateRow(id) {
18444
- const templateRow = document.querySelector(`[data-row-id="${id}"]`);
18445
- if (templateRow) {
18446
- const firstCell = templateRow.querySelector(':first-child');
18447
- const checkbox = firstCell === null || firstCell === void 0 ? void 0 : firstCell.querySelector('[data-taco="checkbox"]');
18448
- firstCell === null || firstCell === void 0 ? void 0 : firstCell.focus();
18449
- if (checkbox) {
18450
- setDataFocusAttribute(checkbox);
18451
- }
18452
- templateRow.scrollIntoView();
18453
- const keyframes = [{
18454
- background: '#b2c7ef'
18455
- }, {
18456
- background: '#ebebeb'
18457
- }];
18458
- for (const child of templateRow.children) {
18459
- child.animate(keyframes, {
18460
- duration: 1000,
18461
- easing: 'ease-out'
18462
- });
18463
- }
18441
+ const TEMPORARY_ROW_ID_PREFIX = 'temp-';
18442
+ function isTemporaryRow(rowId) {
18443
+ if (rowId === undefined) {
18444
+ return false;
18464
18445
  }
18446
+ return String(rowId).startsWith(TEMPORARY_ROW_ID_PREFIX);
18465
18447
  }
18448
+ const shortcut = {
18449
+ key: 'e',
18450
+ meta: true,
18451
+ shift: false
18452
+ };
18466
18453
 
18467
- function useTableEditing(isEnabled = false, handleSave, handleChange, validator) {
18468
- // used to switch the table into editing mode
18469
- const [isEditing, toggleEditing] = React__default.useState(false);
18470
- // used to switch the editing between "detailed" mode
18471
- const [isDetailedMode, toggleDetailedMode] = React__default.useState(false);
18472
- // store the last focused cell, so that up/down arrow key navigation remains in the same column
18473
- const [lastFocusedCellIndex, setLastFocusedCellIndex] = useLastFocusedCellIndex();
18474
- // store pending changes for each row
18475
- // changes are saved as soon as the active row changes, so in most cases this will only contain the active row's changes
18476
- // but not always - if validation or server requests fail when saving, those rows remain until the failure is resolved
18477
- const pendingChangesFns = usePendingChanges(isEnabled, handleSave, handleChange, validator);
18478
- 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 ? {
18479
18519
  key: 's',
18480
18520
  meta: true,
18481
18521
  shift: false
18482
18522
  } : undefined, event => {
18483
18523
  event.preventDefault();
18484
- pendingChangesFns.saveChanges();
18524
+ tableMeta.editing.saveChanges(table);
18485
18525
  });
18486
- return {
18487
- isEnabled,
18488
- isEditing,
18489
- isDetailedMode,
18490
- toggleDetailedMode: isEnabled ? toggleDetailedMode : () => undefined,
18491
- toggleEditing: isEnabled ? toggleEditing : () => undefined,
18492
- lastFocusedCellIndex,
18493
- setLastFocusedCellIndex,
18494
- ...pendingChangesFns
18495
- };
18496
18526
  }
18497
- function usePendingChanges(isEnabled, handleSave, handleChange, validator) {
18498
- 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) {
18499
18665
  try {
18500
18666
  let _exit = false;
18501
18667
  if (!handleSave) {
18502
18668
  console.warn('Tried to save, but Table has no onEditingSave handler');
18503
- return Promise.resolve();
18669
+ return Promise.resolve(false);
18504
18670
  }
18505
- // we save back to pendingChanges, so make a copy of it's state when save was triggered
18506
- const changesToSave = rowId ? {
18507
- [rowId]: pendingChanges[rowId]
18508
- } : {
18509
- ...pendingChanges
18510
- };
18511
- const changes = Object.keys(changesToSave);
18512
- return Promise.resolve(function () {
18513
- if (changes.length) {
18514
- return _forOf(changes, function (rowId) {
18515
- const pendingChange = changesToSave[rowId];
18516
- const changeSet = getChangesetFromChanges(pendingChange);
18517
- return _catch(function () {
18518
- function _temp3(_result) {
18519
- return _exit ? _result : Promise.resolve(handleSave(changeSet)).then(function () {
18520
- // cleanup changes, we don't need them after saving
18521
- resetChanges(rowId);
18522
- setRowSaveStatus(rowId, 'complete');
18523
- });
18524
- }
18525
- if (getRowSaveStatus(rowId) === 'pending') {
18526
- _exit = true;
18527
- return;
18528
- }
18529
- // set saving = true
18530
- setRowSaveStatus(rowId, 'pending');
18531
- // re-run validation, maybe a cell is already invalid but has never been blurred
18532
- const _temp2 = function () {
18533
- if (validator) {
18534
- return Promise.resolve(validator(changeSet)).then(function (errors) {
18535
- if (errors && Object.keys(errors).length) {
18536
- throw errors;
18537
- }
18538
- });
18539
- }
18540
- }();
18541
- return _temp2 && _temp2.then ? _temp2.then(_temp3) : _temp3(_temp2); // send new data to the server
18542
- }, function (error) {
18543
- // the onEditingSave handler should throw errors when something fails, e.g. validation, network errors etc
18544
- // this code handles those errors and maps them either to row errors or cell specific errors
18545
- let rowError;
18546
- let cellErrors;
18547
- if (typeof error === 'string') {
18548
- rowError = error;
18549
- } else if (error instanceof Error) {
18550
- var _error$response;
18551
- rowError = error.message;
18552
- // most of our apis return error objects within this shape
18553
- if (typeof ((_error$response = error.response) === null || _error$response === void 0 ? void 0 : _error$response.data) === 'object') {
18554
- var _error$response2;
18555
- 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;
18556
18709
  }
18557
- } else if (typeof error === 'object') {
18558
- cellErrors = error;
18559
- }
18560
- if (rowError || cellErrors) {
18561
- setPendingChanges(currentChanges => {
18562
- const nextChanges = {
18563
- ...currentChanges
18564
- };
18565
- nextChanges[rowId]._meta.errors = {
18566
- row: rowError,
18567
- cells: cellErrors,
18568
- shouldShowErrorAlert: true
18569
- };
18570
- return nextChanges;
18571
- });
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
18572
18744
  }
18573
- setRowSaveStatus(rowId, undefined);
18574
18745
  });
18575
- }, function () {
18576
- return _exit;
18577
- });
18578
- }
18579
- }());
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);
18580
18756
  } catch (e) {
18581
18757
  return Promise.reject(e);
18582
18758
  }
18583
18759
  };
18584
- const validateCell = function (cell) {
18760
+ const onCellChanged = function (cell, rowIndex, shouldRunUpdaters = true) {
18585
18761
  try {
18586
- if (!validator || !isEnabled) {
18587
- return Promise.resolve();
18588
- }
18589
- const changeSet = getChangesetFromChanges(pendingChanges[cell.row.id]);
18590
- // only validate if the cell being blurred actually has any changes
18591
- const _temp = function () {
18592
- if (cell.column.id in changeSet) {
18593
- return Promise.resolve(validator(changeSet)).then(function (errors) {
18594
- setPendingChanges(currentChanges => {
18595
- const nextChanges = {
18596
- ...currentChanges
18597
- };
18598
- nextChanges[cell.row.id]._meta = {
18599
- ...nextChanges[cell.row.id]._meta,
18600
- errors: {
18601
- ...nextChanges[cell.row.id]._meta.errors,
18602
- cells: errors,
18603
- 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];
18604
18786
  }
18605
- };
18606
- 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 : {};
18607
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 : {};
18608
18844
  });
18609
18845
  }
18610
18846
  }();
18611
- return Promise.resolve(_temp && _temp.then ? _temp.then(function () {}) : void 0);
18847
+ return Promise.resolve(_temp5 && _temp5.then ? _temp5.then(_temp6) : _temp6(_temp5));
18612
18848
  } catch (e) {
18613
18849
  return Promise.reject(e);
18614
18850
  }
18615
- };
18616
- const setCellValue = function (cell, change, rowIndex) {
18851
+ }; // general
18852
+ const createRow = function (data) {
18617
18853
  try {
18618
- const changes = {
18619
- [cell.column.id]: change
18854
+ const newRowId = `${TEMPORARY_ROW_ID_PREFIX}${uuid.v4()}`;
18855
+ const value = {
18856
+ ...data,
18857
+ [rowIdentityAccessor]: newRowId
18620
18858
  };
18621
- setPendingChanges(currentChanges => {
18622
- const nextChanges = createPendingChangesSetter(currentChanges, cell.row, rowIndex, changes, localization);
18623
- pendingChangesUpdater.syncCellChanges(nextChanges);
18624
- return nextChanges;
18859
+ dispatch({
18860
+ type: 'createRow',
18861
+ rowId: newRowId,
18862
+ payload: {
18863
+ value
18864
+ }
18625
18865
  });
18626
- pendingChangesUpdater.runCellUpdates(changes, cell, rowIndex);
18627
- return Promise.resolve();
18866
+ return Promise.resolve(newRowId);
18628
18867
  } catch (e) {
18629
18868
  return Promise.reject(e);
18630
18869
  }
18631
- };
18632
- const addCreatedRowChangeset = function (row) {
18870
+ }; // cells
18871
+ // rows
18872
+ const setRowValue = function (rowId, original, value) {
18633
18873
  try {
18634
- const cells = row.getAllCells();
18635
- setPendingChanges(currentChanges => {
18636
- return cells.reduce((changes, cell) => {
18637
- if (cell.getValue()) {
18638
- var _currentChanges$cell$, _currentChanges$cell$2, _currentChanges$cell$3;
18639
- return {
18640
- ...changes,
18641
- [cell.row.id]: {
18642
- ...changes[cell.row.id],
18643
- [cell.column.id]: cell.getValue(),
18644
- _meta: {
18645
- ...((_currentChanges$cell$ = currentChanges[cell.row.id]) === null || _currentChanges$cell$ === void 0 ? void 0 : _currentChanges$cell$._meta),
18646
- original: cell.row.original,
18647
- moveReason: {
18648
- ...((_currentChanges$cell$2 = currentChanges[cell.row.id]) === null || _currentChanges$cell$2 === void 0 ? void 0 : _currentChanges$cell$2._meta.moveReason)
18649
- },
18650
- errors: {
18651
- ...((_currentChanges$cell$3 = currentChanges[cell.row.id]) === null || _currentChanges$cell$3 === void 0 ? void 0 : _currentChanges$cell$3._meta.errors)
18652
- }
18653
- }
18654
- }
18655
- };
18656
- } else {
18657
- return changes;
18874
+ function _temp2() {
18875
+ dispatch({
18876
+ type: 'updateRow',
18877
+ rowId,
18878
+ payload: {
18879
+ cellErrors,
18880
+ original,
18881
+ value
18658
18882
  }
18659
- }, currentChanges);
18660
- });
18661
- return Promise.resolve();
18662
- } catch (e) {
18663
- 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);
18664
18900
  }
18665
18901
  };
18666
18902
  const localization = useLocalization();
18667
- const [pendingChanges, setPendingChanges] = React__default.useState({});
18668
- // we maintain save status as separate state because 'complete' needs to briefly show after pendingChanges are deleted
18669
- const [saveStates, setSaveState] = React__default.useState({});
18670
- function getCellValue(cell) {
18671
- var _pendingChanges$cell$;
18672
- 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;
18673
18916
  }
18674
- function getCellError(cell) {
18675
- var _pendingChanges$cell$2, _pendingChanges$cell$3, _pendingChanges$cell$4;
18676
- 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;
18677
18920
  }
18678
- const pendingChangesUpdater = usePendingChangesUpdater(handleChange, setPendingChanges);
18679
18921
  function hasRowErrors(rowId) {
18680
- var _pendingChanges$rowId, _pendingChanges$rowId2, _pendingChanges$rowId3, _pendingChanges$rowId4, _pendingChanges$rowId5;
18681
- if (!isEnabled) {
18682
- return false;
18683
- }
18684
- 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;
18685
- }
18686
- function hasRowErrorsSeen(rowId) {
18687
- var _pendingChanges$rowId6;
18688
- if (!isEnabled) {
18689
- return false;
18690
- }
18691
- 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;
18692
18924
  }
18693
- function getRowPendingChange(rowId) {
18694
- const rowPendingChanges = pendingChanges[rowId];
18695
- if (rowPendingChanges) {
18696
- const {
18697
- _meta,
18698
- ...pendingChange
18699
- } = rowPendingChanges;
18700
- return pendingChange;
18701
- }
18702
- 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);
18703
18928
  }
18704
- function getRowSaveStatus(rowId) {
18705
- if (!isEnabled) {
18706
- return false;
18707
- }
18708
- return saveStates[rowId];
18929
+ function getRowStatus(rowId) {
18930
+ return state.changes.status[rowId];
18709
18931
  }
18710
- function setRowSaveStatus(rowId, status) {
18711
- setSaveState(currentStates => {
18712
- const nextStates = {
18713
- ...currentStates
18714
- };
18715
- if (status) {
18716
- nextStates[rowId] = status;
18717
- } else {
18718
- delete nextStates[rowId];
18932
+ function setRowStatus(rowId, status) {
18933
+ dispatch({
18934
+ type: 'setRowStatus',
18935
+ rowId,
18936
+ payload: {
18937
+ status
18719
18938
  }
18720
- return nextStates;
18721
18939
  });
18722
18940
  }
18723
- function getRowMoveReason(rowId) {
18724
- var _pendingChanges$rowId7;
18725
- return (_pendingChanges$rowId7 = pendingChanges[rowId]) !== null && _pendingChanges$rowId7 !== void 0 && _pendingChanges$rowId7._meta.moveReason ? Object.values(pendingChanges[rowId]._meta.moveReason)[0] : undefined;
18726
- }
18727
- function hasChanges(rowId) {
18728
- if (!isEnabled) {
18729
- 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
+ });
18730
18955
  }
18731
- return rowId ? !!pendingChanges[rowId] : !!Object.keys(pendingChanges).length;
18732
- }
18733
- function hasAlertErrors() {
18734
- if (!isEnabled) {
18735
- 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
+ });
18736
18966
  }
18737
- return !!getAlertErrors().length;
18738
18967
  }
18739
- function getAlertErrors() {
18740
- 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 => ({
18741
18982
  rowId,
18742
- pendingChange: pendingChanges[rowId]
18983
+ changes: state.changes.rows[rowId],
18984
+ errors: state.changes.errors[rowId]
18743
18985
  }));
18744
18986
  }
18745
- function resetChanges(rowId) {
18746
- setPendingChanges(currentChanges => {
18747
- const nextChanges = {
18748
- ...currentChanges
18749
- };
18750
- delete nextChanges[rowId];
18751
- return nextChanges;
18752
- });
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;
18753
18992
  }
18754
- function getCompletedRowsCount() {
18755
- 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
+ });
18756
19003
  }
18757
19004
  return {
19005
+ // row
19006
+ setRowValue,
19007
+ getRowValue,
19008
+ getRowMoveReason,
19009
+ hasRowErrors,
19010
+ hasRowErrorsShownInAlert,
19011
+ getRowStatus,
19012
+ setRowStatus,
19013
+ // cells
19014
+ setCellValue,
18758
19015
  getCellValue,
18759
19016
  getCellError,
18760
- setCellValue,
18761
- validateCell,
18762
- addCreatedRowChangeset,
19017
+ onCellChanged,
19018
+ // general
19019
+ getErrorsShownInAlert,
18763
19020
  hasChanges,
18764
- hasAlertErrors,
18765
- getAlertErrors,
18766
19021
  saveChanges,
18767
- resetChanges,
18768
- hasRowErrors,
18769
- hasRowErrorsSeen,
18770
- getRowPendingChange,
18771
- getRowSaveStatus,
18772
- setRowSaveStatus,
18773
- getRowMoveReason,
18774
- getCompletedRowsCount
19022
+ discardChanges,
19023
+ hasSaved,
19024
+ // new rows
19025
+ createRow,
19026
+ temporaryRows: state.temporaryRows
18775
19027
  };
18776
19028
  }
18777
- 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);
18778
19037
  // store the last focused cell, so that up/down arrow key navigation remains in the same column
18779
- const lastFocusedCellIndexRef = React__default.useRef(undefined);
18780
- const setLastFocusedCellIndex = React__default.useCallback(index => {
18781
- lastFocusedCellIndexRef.current = index;
18782
- }, []);
18783
- return [lastFocusedCellIndexRef.current, setLastFocusedCellIndex];
18784
- }
18785
- function usePendingChangesUpdater(handleChange, setPendingChanges) {
18786
- const localization = useLocalization();
18787
- const updatersRef = React__default.useRef({});
18788
- const runCellUpdates = React__default.useCallback(lodash.debounce(function (changes, cell, rowIndex) {
18789
- try {
18790
- const _temp4 = function () {
18791
- if (typeof handleChange === 'function') {
18792
- const previousValues = {
18793
- ...cell.row.original,
18794
- ...getChangesetFromChanges(updatersRef.current[cell.row.id])
18795
- };
18796
- const nextValues = {
18797
- ...previousValues,
18798
- ...changes
18799
- };
18800
- return Promise.resolve(handleChange(cell.column.id, changes[cell.column.id], nextValues, previousValues)).then(function (updates) {
18801
- if (updates && Object.keys(updates).length) {
18802
- setPendingChanges(currentChanges => createPendingChangesSetter(currentChanges, cell.row, rowIndex, updates, localization));
18803
- }
18804
- });
18805
- }
18806
- }();
18807
- return Promise.resolve(_temp4 && _temp4.then ? _temp4.then(function () {}) : void 0);
18808
- } catch (e) {
18809
- 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);
18810
19049
  }
18811
- }, 250), []);
18812
- function syncCellChanges(changes) {
18813
- updatersRef.current = changes;
18814
- }
18815
- return {
18816
- syncCellChanges,
18817
- runCellUpdates
18818
- };
18819
- }
18820
- function createPendingChangesSetter(currentChanges, row, rowIndex, changes, localization) {
18821
- var _currentChanges$row$i, _currentChanges$row$i2, _currentChanges$row$i3;
18822
- // prepare
18823
- const nextChanges = {
18824
- ...currentChanges
18825
- };
18826
- const rowChanges = {
18827
- ...currentChanges[row.id],
18828
- _meta: {
18829
- ...((_currentChanges$row$i = currentChanges[row.id]) === null || _currentChanges$row$i === void 0 ? void 0 : _currentChanges$row$i._meta),
18830
- original: row.original,
18831
- moveReason: {
18832
- ...((_currentChanges$row$i2 = currentChanges[row.id]) === null || _currentChanges$row$i2 === void 0 ? void 0 : _currentChanges$row$i2._meta.moveReason)
18833
- },
18834
- errors: {
18835
- ...((_currentChanges$row$i3 = currentChanges[row.id]) === null || _currentChanges$row$i3 === void 0 ? void 0 : _currentChanges$row$i3._meta.errors)
18836
- }
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);
18837
19054
  }
18838
- };
18839
- // run changes
18840
- const cells = row._getAllCellsByColumnId();
18841
- for (const [accessor, change] of Object.entries(changes)) {
18842
- // update if the change is different to the original (saved) value,
18843
- // otherwise remove any change - no point saving the same value
18844
- if (change !== row.original[accessor]) {
18845
- rowChanges[accessor] = change;
18846
- // consumers sometimes include properties in onEditingChange that aren't rendered as columns, we need to guard against that.
18847
- // eslint-disable-next-line no-prototype-builtins
18848
- if (cells.hasOwnProperty(accessor)) {
18849
- // determine if the row will move position based on this change, and save why it will move
18850
- const reason = willRowMove(cells[accessor], change, rowIndex, localization);
18851
- if (reason) {
18852
- rowChanges._meta.moveReason[accessor] = reason;
18853
- } else {
18854
- delete rowChanges._meta.moveReason[accessor];
18855
- }
18856
- }
18857
- } else {
18858
- delete rowChanges[accessor];
18859
- 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);
18860
19058
  }
18861
19059
  }
18862
- // set changes
18863
- // or delete if there are no changes left, so that we don't store changes with unchanged data
18864
- if (Object.keys(rowChanges).filter(k => k !== '_meta').length) {
18865
- nextChanges[row.id] = rowChanges;
18866
- } else {
18867
- delete nextChanges[row.id];
18868
- }
18869
- return nextChanges;
18870
- }
18871
- function getChangesetFromChanges(changes) {
18872
- // extract the original data from the row changes
18873
- const {
18874
- _meta,
18875
- ...changeset
18876
- } = changes !== null && changes !== void 0 ? changes : {};
18877
- // and mix them in with the changes, ready to send to the server
18878
19060
  return {
18879
- ...(_meta === null || _meta === void 0 ? void 0 : _meta.original),
18880
- ...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
18881
19070
  };
18882
19071
  }
18883
19072
 
@@ -18921,7 +19110,6 @@ function RowMoveIndicator(props) {
18921
19110
  if (!show) {
18922
19111
  return null;
18923
19112
  }
18924
- 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';
18925
19113
  const {
18926
19114
  title,
18927
19115
  description
@@ -18930,7 +19118,7 @@ function RowMoveIndicator(props) {
18930
19118
  placement: "bottom",
18931
19119
  title: description.replace('[COLUMN]', columnMeta.header)
18932
19120
  }, /*#__PURE__*/React__default.createElement("span", {
18933
- className: className
19121
+ "data-row-move-indicator": true
18934
19122
  }, /*#__PURE__*/React__default.createElement(Icon, {
18935
19123
  name: "info",
18936
19124
  className: "-mt-0.5 mr-1 !h-4 !w-4 rounded-full bg-white !p-0 text-blue-500"
@@ -19119,13 +19307,31 @@ function EditingControlCell(props) {
19119
19307
  const {
19120
19308
  rowIndex
19121
19309
  } = React__default.useContext(RowContext);
19122
- const tableMeta = cell.getContext().table.options.meta;
19310
+ const {
19311
+ table
19312
+ } = cell.getContext();
19313
+ const tableMeta = table.options.meta;
19123
19314
  const columnMeta = cell.column.columnDef.meta;
19124
19315
  const isActiveRow = tableMeta.rowActive.rowActiveIndex === rowIndex;
19316
+ const type = (_columnMeta$control = columnMeta.control) !== null && _columnMeta$control !== void 0 ? _columnMeta$control : 'input';
19125
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
+ };
19126
19332
  const handleBlur = () => {
19127
19333
  tableMeta.editing.toggleDetailedMode(false);
19128
- tableMeta.editing.validateCell(cell);
19334
+ tableMeta.editing.onCellChanged(cell, rowIndex, !hasNonTextControl);
19129
19335
  };
19130
19336
  // ensure that blur runs when the cell gets unmounted (when vertically arrow key navigating)
19131
19337
  React__default.useEffect(() => {
@@ -19145,14 +19351,13 @@ function EditingControlCell(props) {
19145
19351
  isDetailedMode: tableMeta.editing.isDetailedMode,
19146
19352
  isTruncated: !!columnMeta.enableTruncate,
19147
19353
  onBlur: handleBlur,
19148
- onChange: value => tableMeta.editing.setCellValue(cell, value, rowIndex),
19354
+ onChange: handleChange,
19149
19355
  row: cell.row.original,
19150
- rowPendingChanges: tableMeta.editing.getRowPendingChange(cell.row.id),
19356
+ rowPendingChanges: tableMeta.editing.getRowValue(cell.row.id),
19151
19357
  tabIndex: isActiveRow ? 0 : -1,
19152
- toggleEditing: tableMeta.editing.toggleEditing,
19153
19358
  toggleDetailedMode: tableMeta.editing.toggleDetailedMode,
19154
- type: (_columnMeta$control = columnMeta.control) !== null && _columnMeta$control !== void 0 ? _columnMeta$control : 'input',
19155
- value: cell.getValue()
19359
+ type,
19360
+ value
19156
19361
  };
19157
19362
  const cellAttributes = {
19158
19363
  ...getCellAttributes(cell, index, isHighlighted),
@@ -19184,7 +19389,6 @@ const MemoedEditingCell = /*#__PURE__*/React__default.memo(function MemoedEditin
19184
19389
  row,
19185
19390
  rowPendingChanges,
19186
19391
  tabIndex = -1,
19187
- toggleEditing,
19188
19392
  toggleDetailedMode,
19189
19393
  type = 'input',
19190
19394
  value
@@ -19243,8 +19447,8 @@ const MemoedEditingCell = /*#__PURE__*/React__default.memo(function MemoedEditin
19243
19447
  }
19244
19448
  // reset the value, or exit edit mode when pressing escape
19245
19449
  if (event.key === 'Escape') {
19246
- event.preventDefault();
19247
19450
  if (isDetailedMode) {
19451
+ event.preventDefault();
19248
19452
  toggleDetailedMode(false);
19249
19453
  if (value !== currentValue) {
19250
19454
  props.onChange(currentValue);
@@ -19254,8 +19458,6 @@ const MemoedEditingCell = /*#__PURE__*/React__default.memo(function MemoedEditin
19254
19458
  var _target$select2;
19255
19459
  return (_target$select2 = target.select) === null || _target$select2 === void 0 ? void 0 : _target$select2.call(target);
19256
19460
  });
19257
- } else {
19258
- toggleEditing(false);
19259
19461
  }
19260
19462
  return;
19261
19463
  }
@@ -19354,12 +19556,37 @@ function Cell$5(props) {
19354
19556
  return /*#__PURE__*/React__default.createElement(DisplayCell, Object.assign({}, props));
19355
19557
  }
19356
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
+
19357
19585
  function EditingActionMenu(props) {
19358
19586
  const {
19359
19587
  hasChanges,
19360
19588
  hasErrors,
19361
- onClear: handleClear,
19362
- onExit: handleExit,
19589
+ onDiscard: handleDiscard,
19363
19590
  onEditingSave: handleSave,
19364
19591
  isLastRow
19365
19592
  } = props;
@@ -19381,7 +19608,6 @@ function EditingActionMenu(props) {
19381
19608
  return /*#__PURE__*/React__default.createElement(IconButton, {
19382
19609
  appearance: "transparent",
19383
19610
  "aria-label": texts.table3.editing.actions.tooltip,
19384
- className: "group-[[data-row-editing-status]]/row:hidden",
19385
19611
  icon: "more",
19386
19612
  onKeyDown: handleKeyDown,
19387
19613
  menu: menuProps => (/*#__PURE__*/React__default.createElement(Menu$1, Object.assign({}, menuProps), /*#__PURE__*/React__default.createElement(Menu$1.Content, {
@@ -19393,42 +19619,13 @@ function EditingActionMenu(props) {
19393
19619
  }, texts.table3.editing.actions.save), /*#__PURE__*/React__default.createElement(Menu$1.Item, {
19394
19620
  icon: "close",
19395
19621
  disabled: !hasChanges,
19396
- dialog: props => /*#__PURE__*/React__default.createElement(ConfirmClearChangesDialog, Object.assign({}, props, {
19397
- onClear: handleClear
19622
+ dialog: props => /*#__PURE__*/React__default.createElement(DiscardChangesConfirmationDialog, Object.assign({}, props, {
19623
+ onDiscard: handleDiscard
19398
19624
  }))
19399
- }, texts.table3.editing.actions.clear), /*#__PURE__*/React__default.createElement(Menu$1.Item, {
19400
- icon: "undo",
19401
- onClick: handleExit
19402
- }, texts.table3.editing.actions.exit))))
19625
+ }, texts.table3.editing.actions.clear))))
19403
19626
  });
19404
19627
  }
19405
- function ConfirmClearChangesDialog(props) {
19406
- const {
19407
- onClear: handleClear,
19408
- ...dialogProps
19409
- } = props;
19410
- const {
19411
- texts
19412
- } = useLocalization();
19413
- const handleClickInsideDialogContent = event => {
19414
- // Prevents the click event from propagating to the table, ensuring the row isn't saved when a click occurs
19415
- // inside the dialog
19416
- event.stopPropagation();
19417
- };
19418
- return /*#__PURE__*/React__default.createElement(Dialog, Object.assign({}, dialogProps), /*#__PURE__*/React__default.createElement(Dialog.Content, {
19419
- "aria-label": texts.table3.editing.clearChangesConfirmationDialog.title,
19420
- onClick: handleClickInsideDialogContent
19421
- }, /*#__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, {
19422
- tabIndex: 0
19423
- }, texts.table3.editing.clearChangesConfirmationDialog.cancel)), /*#__PURE__*/React__default.createElement(Dialog.Close, null, /*#__PURE__*/React__default.createElement(Button$1, {
19424
- autoFocus: true,
19425
- tabIndex: 0,
19426
- appearance: "primary",
19427
- onClick: handleClear
19428
- }, texts.table3.editing.clearChangesConfirmationDialog.confirm))))));
19429
- }
19430
19628
 
19431
- const COMPLETE_INDICATOR_DELAY = 3000;
19432
19629
  function SaveStatus(props) {
19433
19630
  const {
19434
19631
  rowId,
@@ -19438,18 +19635,7 @@ function SaveStatus(props) {
19438
19635
  texts
19439
19636
  } = useLocalization();
19440
19637
  const tableMeta = table.options.meta;
19441
- const status = tableMeta.editing.getRowSaveStatus(rowId);
19442
- React__default.useEffect(() => {
19443
- let timeout;
19444
- if (status === 'complete') {
19445
- timeout = setTimeout(() => {
19446
- tableMeta.editing.setRowSaveStatus(rowId, undefined);
19447
- }, COMPLETE_INDICATOR_DELAY);
19448
- }
19449
- return () => {
19450
- clearTimeout(timeout);
19451
- };
19452
- }, [status]);
19638
+ const status = tableMeta.editing.getRowStatus(rowId);
19453
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)]', {
19454
19640
  'mt-0.5': tableMeta.rowHeight.height === 'short',
19455
19641
  'mt-1': tableMeta.rowHeight.height === 'medium',
@@ -19460,7 +19646,7 @@ function SaveStatus(props) {
19460
19646
  className: "!contents"
19461
19647
  }, /*#__PURE__*/React__default.createElement("span", {
19462
19648
  className: className
19463
- }, status === 'pending' ? (/*#__PURE__*/React__default.createElement(Tooltip, {
19649
+ }, status === 'saving' ? (/*#__PURE__*/React__default.createElement(Tooltip, {
19464
19650
  title: texts.table3.editing.saving.progress
19465
19651
  }, /*#__PURE__*/React__default.createElement(Spinner, {
19466
19652
  delay: 0,
@@ -19498,15 +19684,46 @@ function Row$2(props) {
19498
19684
  }
19499
19685
  }
19500
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
+ }
19501
19713
  const attributes = {
19502
- 'data-row-editing-invalid': tableMeta.editing.isEnabled && tableMeta.editing.hasRowErrors(row.id) ? !tableMeta.editing.hasRowErrorsSeen(row.id) ? 'unseen' : true : undefined,
19503
- 'data-row-editing-status': tableMeta.editing.isEnabled && tableMeta.editing.getRowSaveStatus(row.id) ? tableMeta.editing.getRowSaveStatus(row.id) : undefined,
19504
- 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
19505
19718
  };
19506
- 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, {
19507
19720
  rowId: row.id,
19508
19721
  table: table
19509
- }) : null);
19722
+ }) : null), /*#__PURE__*/React__default.createElement(DiscardChangesConfirmationDialog, {
19723
+ open: showDiscardDialog,
19724
+ onChange: setShowDiscardDialog,
19725
+ onDiscard: handleDiscard
19726
+ }));
19510
19727
  }
19511
19728
 
19512
19729
  const RENDERERS$1 = {
@@ -19514,29 +19731,46 @@ const RENDERERS$1 = {
19514
19731
  cell: Cell$5
19515
19732
  };
19516
19733
  function useTable3(props, ref) {
19517
- 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);
19518
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]);
19519
19744
  const extendedProps = {
19520
19745
  ...props,
19746
+ data,
19521
19747
  enableRowActions: editing.isEditing ? true : props.enableRowActions,
19522
- rowActions: editing.isEditing ? [(_, rowId) => (/*#__PURE__*/React__default.createElement(EditingActionMenu, {
19748
+ rowActions: editing.isEditing ? [(_, rowId, table) => (/*#__PURE__*/React__default.createElement(EditingActionMenu, {
19523
19749
  hasChanges: editing.hasChanges(rowId),
19524
19750
  hasErrors: editing.hasRowErrors(rowId),
19525
- onClear: () => editing.resetChanges(rowId),
19526
- onEditingSave: () => editing.saveChanges(rowId),
19527
- 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
+ },
19528
19759
  isLastRow: !creationEnabled && table.meta.rowActive.rowActiveIndex === table.meta.length - 1
19529
19760
  }))] : props.rowActions
19530
19761
  };
19531
19762
  const meta = {
19532
19763
  editing
19533
19764
  };
19534
- 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);
19535
19769
  // listeners
19536
- useTableEditingListener(table.instance, table.ref);
19770
+ useTableEditingListener(table.instance, table.ref, table.renderer.scrollToIndex);
19537
19771
  React__default.useEffect(() => {
19538
19772
  if (table.ref.current) {
19539
- 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);
19540
19774
  }
19541
19775
  }, [table.ref.current]);
19542
19776
  return table;
@@ -19555,7 +19789,7 @@ function Alert$1(props) {
19555
19789
  const validationTexts = texts.table3.editing.validation;
19556
19790
  const tableMeta = table.options.meta;
19557
19791
  const [showFilterResetDialog, setShowFilterResetDialog] = React__default.useState(false);
19558
- const pendingChangesWithErrors = tableMeta.editing.getAlertErrors();
19792
+ const pendingChangesWithErrors = tableMeta.editing.getErrorsShownInAlert();
19559
19793
  function scrollToRow(rowIndex) {
19560
19794
  tableMeta.rowActive.setRowActiveIndex(rowIndex);
19561
19795
  scrollToIndex(rowIndex, {
@@ -19574,38 +19808,43 @@ function Alert$1(props) {
19574
19808
  const title = (pendingChangesWithErrors.length === 1 ? validationTexts.alert.titleOne : validationTexts.alert.titlePlural).replace('[COUNT]', String(pendingChangesWithErrors.length));
19575
19809
  // generate links to each invalid row, to go into the error message
19576
19810
  const links = [];
19577
- const rowIdentityColumn = tableMeta.rowIdentityColumnId ? table.getColumn(tableMeta.rowIdentityColumnId) : undefined;
19578
- 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) => {
19579
19814
  // if appropriate, concatenate the item with the text "and"
19580
19815
  if (pendingChangesWithErrors.length > 1 && index === pendingChangesWithErrors.length - 1) {
19581
19816
  // Add space before and after `messageAnd` text
19582
19817
  links.push(` ${validationTexts.alert.messageAnd} `);
19583
19818
  }
19584
- const rowIndex = table.getRowModel().rows.findIndex(row => row.id === error.rowId);
19819
+ const rowIndex = table.getRowModel().rows.findIndex(row => row.id === pendingChangeWithError.rowId);
19585
19820
  const handleClick = () => {
19821
+ // if row is visible
19586
19822
  if (rowIndex > -1) {
19587
19823
  scrollToRow(rowIndex);
19588
- } else {
19589
- setShowFilterResetDialog(error.rowId);
19824
+ }
19825
+ // if row is filtered out
19826
+ else {
19827
+ setShowFilterResetDialog(pendingChangeWithError.rowId);
19590
19828
  }
19591
19829
  };
19592
19830
  let tooltip;
19593
- if (error.pendingChange._meta.errors.row) {
19594
- tooltip = error.pendingChange._meta.errors.row;
19831
+ if (pendingChangeWithError.errors.row) {
19832
+ tooltip = pendingChangeWithError.errors.row;
19595
19833
  } else {
19596
19834
  var _table$getAllColumns$, _table$getAllColumns$2;
19597
- const firstCellErrorColumnId = Object.keys(error.pendingChange._meta.errors.cells)[0];
19835
+ const firstCellErrorColumnId = Object.keys(pendingChangeWithError.errors.cells)[0];
19598
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;
19599
- tooltip = `${columnName}: ${error.pendingChange._meta.errors.cells[firstCellErrorColumnId]}`;
19837
+ tooltip = `${columnName}: ${pendingChangeWithError.errors.cells[firstCellErrorColumnId]}`;
19600
19838
  }
19839
+ const row = table.getRow(pendingChangeWithError.rowId).original;
19601
19840
  links.push(/*#__PURE__*/React__default.createElement(Tooltip, {
19602
- key: error.rowId,
19841
+ key: pendingChangeWithError.rowId,
19603
19842
  title: tooltip
19604
19843
  }, /*#__PURE__*/React__default.createElement("span", {
19605
19844
  className: "text-blue",
19606
19845
  onClick: handleClick,
19607
19846
  role: "button"
19608
- }, rowIdentityColumn ? error.pendingChange._meta.original[rowIdentityColumn.id] : rowIndex + 1)));
19847
+ }, rowIdentityColumn ? row[rowIdentityColumn.id] : rowIndex + 1)));
19609
19848
  // if appropriate, concatenate the item with the text ","
19610
19849
  if (pendingChangesWithErrors.length > 2 && index < pendingChangesWithErrors.length - 2) {
19611
19850
  links.push(', ');
@@ -19661,9 +19900,38 @@ function FilterResetDialog(props) {
19661
19900
  }, texts.table3.editing.validation.resetFiltersDialog.confirm)))));
19662
19901
  }
19663
19902
 
19664
- function CreateNewRowButton(props) {
19903
+ function Editing(props) {
19665
19904
  const {
19666
- 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,
19667
19935
  scrollToIndex,
19668
19936
  table,
19669
19937
  tableMeta
@@ -19671,117 +19939,152 @@ function CreateNewRowButton(props) {
19671
19939
  const {
19672
19940
  texts
19673
19941
  } = useLocalization();
19674
- const rows = table.getCoreRowModel().rows.filter(row => row.original !== undefined);
19675
- const [rowCreated, setRowCreated] = React__default.useState({
19676
- rowFinder: undefined
19677
- });
19678
- const handleKeyDown = event => {
19679
- if (!tableMeta.editing.hasChanges() && event.key === 'Tab') {
19680
- tableMeta.editing.saveChanges();
19681
- }
19682
- };
19683
- 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) {
19684
19947
  try {
19685
- 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) {
19686
19951
  return Promise.resolve();
19687
19952
  }
19688
- const createdRow = rows.find(row => {
19689
- var _rowCreated$rowFinder;
19690
- 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);
19691
- });
19692
- const _temp = function () {
19693
- if (createdRow) {
19694
- return Promise.resolve(tableMeta.editing.saveChanges()).then(function () {
19695
- if (!tableMeta.editing.hasRowErrors(createdRow.id)) {
19696
- const rowFinder = onEditingCreate();
19697
- setRowCreated({
19698
- 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);
19699
19968
  });
19700
19969
  }
19701
- });
19702
- } else {
19703
- const rowFinder = onEditingCreate();
19704
- setRowCreated({
19705
- rowFinder
19706
- });
19707
- }
19708
- }();
19709
- 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
+ });
19710
19976
  } catch (e) {
19711
19977
  return Promise.reject(e);
19712
19978
  }
19713
19979
  };
19714
- React__default.useEffect(() => {
19715
- if (typeof (rowCreated === null || rowCreated === void 0 ? void 0 : rowCreated.rowFinder) === 'function') {
19716
- const createdRow = rows.find(row => {
19717
- var _rowCreated$rowFinder2;
19718
- 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);
19719
- });
19720
- if (createdRow) {
19721
- const rowInTable = table.getRowModel().rows.filter(row => row.original !== undefined).find(row => {
19722
- var _rowCreated$rowFinder3;
19723
- 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);
19724
- });
19725
- if (rowInTable) {
19726
- tableMeta.editing.toggleEditing(true);
19727
- tableMeta.rowActive.setRowActiveIndex(createdRow.index);
19728
- scrollToIndex(createdRow.index);
19729
- requestAnimationFrame(() => animateCreateRow(createdRow.id));
19730
- }
19731
- requestAnimationFrame(() => tableMeta.editing.addCreatedRowChangeset(createdRow));
19732
- }
19733
- }
19734
- }, [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
+ }
19735
19986
  return /*#__PURE__*/React__default.createElement("tr", {
19736
- onClick: handleCreate,
19737
- 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
19738
19990
  }, /*#__PURE__*/React__default.createElement("td", {
19739
- className: "!border-t-0 !bg-transparent"
19991
+ className: "!bg-grey-50 col-span-full !border-b-0 !px-1"
19740
19992
  }, /*#__PURE__*/React__default.createElement(Button$1, {
19741
- onKeyDown: handleKeyDown,
19742
- className: "group-hover:bg-grey-200 sticky left-0",
19743
- appearance: "transparent"
19744
- }, "+ ", 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)));
19745
20002
  }
19746
20003
 
19747
- function Editing(props) {
20004
+ function TemporaryRow(props) {
20005
+ var _tableRef$current, _tableRef$current2;
19748
20006
  const {
19749
- scrollToIndex,
19750
- table
20007
+ createRowButtonRef,
20008
+ table,
20009
+ tableMeta,
20010
+ tableRef
19751
20011
  } = props;
19752
- const {
19753
- texts
19754
- } = useLocalization();
19755
- const ref = React__default.useRef(null);
19756
- const tableMeta = table.options.meta;
19757
- const shortcut = {
19758
- key: 'e',
19759
- meta: true,
19760
- 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
+ }
19761
20059
  };
19762
- const tooltip = /*#__PURE__*/React__default.createElement(React__default.Fragment, null, texts.table3.editing.buttons.edit.tooltip, /*#__PURE__*/React__default.createElement(Shortcut, {
19763
- className: "ml-2",
19764
- keys: shortcut
19765
- }));
19766
- useGlobalKeyDown(shortcut, event => {
19767
- var _ref$current;
19768
- event.preventDefault();
19769
- (_ref$current = ref.current) === null || _ref$current === void 0 ? void 0 : _ref$current.click();
19770
- });
19771
- const handleChange = enabled => {
19772
- tableMeta.editing.toggleEditing(enabled);
19773
- requestAnimationFrame(() => {
19774
- var _tableMeta$rowActive$;
19775
- return scrollToIndex((_tableMeta$rowActive$ = tableMeta.rowActive.rowActiveIndex) !== null && _tableMeta$rowActive$ !== void 0 ? _tableMeta$rowActive$ : 0);
19776
- });
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
+ }
19777
20070
  };
19778
- return /*#__PURE__*/React__default.createElement(Tooltip, {
19779
- title: tooltip
19780
- }, /*#__PURE__*/React__default.createElement(ModeSwitch, {
19781
- checked: tableMeta.editing.isEditing,
19782
- onChange: handleChange,
19783
- ref: ref
19784
- }));
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
+ }))));
19785
20088
  }
19786
20089
 
19787
20090
  function Column$3(_) {
@@ -19799,8 +20102,19 @@ const BaseTable3 = /*#__PURE__*/fixedForwardRef(function BaseTable3(props, ref)
19799
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,
19800
20103
  enableHorizontalArrowKeyNavigation: table3.meta.editing.isEditing
19801
20104
  };
19802
- const hasAlertErrors = table3.meta.editing.hasAlertErrors();
19803
- 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
+ }
19804
20118
  return /*#__PURE__*/React__default.createElement(Table, null, /*#__PURE__*/React__default.createElement(Table.Toolbar, {
19805
20119
  table: table3
19806
20120
  }, table3.meta.editing.isEnabled ? (/*#__PURE__*/React__default.createElement(Editing, {
@@ -19813,13 +20127,14 @@ const BaseTable3 = /*#__PURE__*/fixedForwardRef(function BaseTable3(props, ref)
19813
20127
  tableRef: table3.ref
19814
20128
  })) : null, /*#__PURE__*/React__default.createElement(Table.Grid, Object.assign({}, gridAttributes, {
19815
20129
  "data-taco": "table3",
20130
+ rowsForFooter: footerRows,
19816
20131
  table: table3
19817
- }), showCreateRowButton && (/*#__PURE__*/React__default.createElement(CreateNewRowButton, {
20132
+ }), hasCreateWorkflow ? (/*#__PURE__*/React__default.createElement(TemporaryRow, {
20133
+ createRowButtonRef: table3.meta.editing.createRowButtonRef,
19818
20134
  table: table3.instance,
19819
20135
  tableMeta: table3.meta,
19820
- onEditingCreate: props.onEditingCreate,
19821
- scrollToIndex: table3.renderer.scrollToIndex
19822
- }))));
20136
+ tableRef: table3.ref
20137
+ })) : null));
19823
20138
  });
19824
20139
  const Table3 = /*#__PURE__*/fixedForwardRef(function Table3(props, ref) {
19825
20140
  const stringifiedChildren = String(props.children);