@economic/taco 2.44.4 → 2.44.5-create.10

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