@economic/taco 2.45.0-alpha.1 → 2.45.0-alpha.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (115) hide show
  1. package/dist/components/Popover/Popover.d.ts +1 -1
  2. package/dist/components/Provider/Localization.d.ts +2 -0
  3. package/dist/components/Report/Report.d.ts +1 -1
  4. package/dist/components/Select2/components/Search.d.ts +0 -6
  5. package/dist/components/Table3/Table3.d.ts +2 -14
  6. package/dist/components/Table3/components/Columns/Internal/EditingActionsMenu.d.ts +1 -2
  7. package/dist/components/Table3/components/Editing/DiscardChangesConfirmationDialog.d.ts +7 -0
  8. package/dist/components/Table3/components/Row/Editing/CreateNewRow.d.ts +14 -0
  9. package/dist/components/Table3/components/Row/Editing/TemporaryRow.d.ts +11 -0
  10. package/dist/components/Table3/features/useEditingState.d.ts +29 -0
  11. package/dist/components/Table3/features/useTableEditing.d.ts +26 -36
  12. package/dist/components/Table3/listeners/useTableEditingListener.d.ts +1 -1
  13. package/dist/components/Table3/types.d.ts +24 -8
  14. package/dist/components/Table3/useTable3.d.ts +6 -0
  15. package/dist/components/Table3/util/editing.d.ts +7 -1
  16. package/dist/esm/index.css +35 -4
  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/Popover/Popover.js.map +1 -1
  20. package/dist/esm/packages/taco/src/components/Provider/Localization.js +5 -3
  21. package/dist/esm/packages/taco/src/components/Provider/Localization.js.map +1 -1
  22. package/dist/esm/packages/taco/src/components/Select2/Select2.js +21 -40
  23. package/dist/esm/packages/taco/src/components/Select2/Select2.js.map +1 -1
  24. package/dist/esm/packages/taco/src/components/Select2/components/Search.js +2 -12
  25. package/dist/esm/packages/taco/src/components/Select2/components/Search.js.map +1 -1
  26. package/dist/esm/packages/taco/src/components/Select2/components/Trigger.js +19 -1
  27. package/dist/esm/packages/taco/src/components/Select2/components/Trigger.js.map +1 -1
  28. package/dist/esm/packages/taco/src/components/Switch/Switch.js +1 -1
  29. package/dist/esm/packages/taco/src/components/Switch/Switch.js.map +1 -1
  30. package/dist/esm/packages/taco/src/components/Table3/Table3.js +14 -6
  31. package/dist/esm/packages/taco/src/components/Table3/Table3.js.map +1 -1
  32. package/dist/esm/packages/taco/src/components/Table3/components/Columns/Cell/Editing/RowMoveIndicator.js +1 -2
  33. package/dist/esm/packages/taco/src/components/Table3/components/Columns/Cell/Editing/RowMoveIndicator.js.map +1 -1
  34. package/dist/esm/packages/taco/src/components/Table3/components/Columns/Cell/EditingControlCell.js +33 -11
  35. package/dist/esm/packages/taco/src/components/Table3/components/Columns/Cell/EditingControlCell.js.map +1 -1
  36. package/dist/esm/packages/taco/src/components/Table3/components/Columns/Internal/EditingActionsMenu.js +5 -37
  37. package/dist/esm/packages/taco/src/components/Table3/components/Columns/Internal/EditingActionsMenu.js.map +1 -1
  38. package/dist/esm/packages/taco/src/components/Table3/components/Editing/Alert.js +17 -12
  39. package/dist/esm/packages/taco/src/components/Table3/components/Editing/Alert.js.map +1 -1
  40. package/dist/esm/packages/taco/src/components/Table3/components/Editing/DiscardChangesConfirmationDialog.js +34 -0
  41. package/dist/esm/packages/taco/src/components/Table3/components/Editing/DiscardChangesConfirmationDialog.js.map +1 -0
  42. package/dist/esm/packages/taco/src/components/Table3/components/Row/Editing/CreateNewRow.js +103 -0
  43. package/dist/esm/packages/taco/src/components/Table3/components/Row/Editing/CreateNewRow.js.map +1 -0
  44. package/dist/esm/packages/taco/src/components/Table3/components/Row/Editing/SaveStatus.js +2 -14
  45. package/dist/esm/packages/taco/src/components/Table3/components/Row/Editing/SaveStatus.js.map +1 -1
  46. package/dist/esm/packages/taco/src/components/Table3/components/Row/Editing/TemporaryRow.js +96 -0
  47. package/dist/esm/packages/taco/src/components/Table3/components/Row/Editing/TemporaryRow.js.map +1 -0
  48. package/dist/esm/packages/taco/src/components/Table3/components/Row/Row.js +39 -6
  49. package/dist/esm/packages/taco/src/components/Table3/components/Row/Row.js.map +1 -1
  50. package/dist/esm/packages/taco/src/components/Table3/components/Toolbar/Editing/Editing.js +4 -17
  51. package/dist/esm/packages/taco/src/components/Table3/components/Toolbar/Editing/Editing.js.map +1 -1
  52. package/dist/esm/packages/taco/src/components/Table3/features/useEditingState.js +519 -0
  53. package/dist/esm/packages/taco/src/components/Table3/features/useEditingState.js.map +1 -0
  54. package/dist/esm/packages/taco/src/components/Table3/features/useTableEditing.js +29 -406
  55. package/dist/esm/packages/taco/src/components/Table3/features/useTableEditing.js.map +1 -1
  56. package/dist/esm/packages/taco/src/components/Table3/listeners/useTableEditingListener.js +44 -33
  57. package/dist/esm/packages/taco/src/components/Table3/listeners/useTableEditingListener.js.map +1 -1
  58. package/dist/esm/packages/taco/src/components/Table3/useTable3.js +34 -13
  59. package/dist/esm/packages/taco/src/components/Table3/useTable3.js.map +1 -1
  60. package/dist/esm/packages/taco/src/components/Table3/util/editing.js +11 -23
  61. package/dist/esm/packages/taco/src/components/Table3/util/editing.js.map +1 -1
  62. package/dist/esm/packages/taco/src/primitives/Collection/components/Root.js +18 -0
  63. package/dist/esm/packages/taco/src/primitives/Collection/components/Root.js.map +1 -1
  64. package/dist/esm/packages/taco/src/primitives/Listbox2/components/Option.js +0 -5
  65. package/dist/esm/packages/taco/src/primitives/Listbox2/components/Option.js.map +1 -1
  66. package/dist/esm/packages/taco/src/primitives/Listbox2/components/Root.js +1 -0
  67. package/dist/esm/packages/taco/src/primitives/Listbox2/components/Root.js.map +1 -1
  68. package/dist/esm/packages/taco/src/primitives/Table/Core/Table.js +1 -3
  69. package/dist/esm/packages/taco/src/primitives/Table/Core/Table.js.map +1 -1
  70. package/dist/esm/packages/taco/src/primitives/Table/Core/components/Columns/Cell/BuiltIns/GroupedCell.js +9 -3
  71. package/dist/esm/packages/taco/src/primitives/Table/Core/components/Columns/Cell/BuiltIns/GroupedCell.js.map +1 -1
  72. package/dist/esm/packages/taco/src/primitives/Table/Core/components/Columns/Internal/Actions.js +9 -7
  73. package/dist/esm/packages/taco/src/primitives/Table/Core/components/Columns/Internal/Actions.js.map +1 -1
  74. package/dist/esm/packages/taco/src/primitives/Table/Core/components/Footer/Footer.js.map +1 -1
  75. package/dist/esm/packages/taco/src/primitives/Table/Core/components/Row/BuiltIns/DisplayRow.js +2 -2
  76. package/dist/esm/packages/taco/src/primitives/Table/Core/components/Row/BuiltIns/DisplayRow.js.map +1 -1
  77. package/dist/esm/packages/taco/src/primitives/Table/Core/components/Row/Row.js +4 -2
  78. package/dist/esm/packages/taco/src/primitives/Table/Core/components/Row/Row.js.map +1 -1
  79. package/dist/esm/packages/taco/src/primitives/Table/Core/components/Row/RowContext.js +2 -1
  80. package/dist/esm/packages/taco/src/primitives/Table/Core/components/Row/RowContext.js.map +1 -1
  81. package/dist/esm/packages/taco/src/primitives/Table/Core/components/Toolbar/components/Filters/components/FilterValue.js +8 -1
  82. package/dist/esm/packages/taco/src/primitives/Table/Core/components/Toolbar/components/Filters/components/FilterValue.js.map +1 -1
  83. package/dist/esm/packages/taco/src/primitives/Table/Core/features/useTableRenderer.js +29 -7
  84. package/dist/esm/packages/taco/src/primitives/Table/Core/features/useTableRenderer.js.map +1 -1
  85. package/dist/esm/packages/taco/src/primitives/Table/Core/useTable.js +2 -2
  86. package/dist/esm/packages/taco/src/primitives/Table/Core/useTable.js.map +1 -1
  87. package/dist/esm/packages/taco/src/primitives/Table/types.js.map +1 -1
  88. package/dist/esm/packages/taco/src/primitives/Table/useTableManager/features/useTableRowSelection.js +2 -1
  89. package/dist/esm/packages/taco/src/primitives/Table/useTableManager/features/useTableRowSelection.js.map +1 -1
  90. package/dist/esm/packages/taco/src/primitives/Table/useTableManager/useTableManager.js +1 -1
  91. package/dist/esm/packages/taco/src/primitives/Table/useTableManager/useTableManager.js.map +1 -1
  92. package/dist/esm/packages/taco/src/primitives/Table/useTableManager/util/setup.js +11 -0
  93. package/dist/esm/packages/taco/src/primitives/Table/useTableManager/util/setup.js.map +1 -1
  94. package/dist/esm/packages/taco/src/utils/dom.js +20 -10
  95. package/dist/esm/packages/taco/src/utils/dom.js.map +1 -1
  96. package/dist/index.css +35 -4
  97. package/dist/primitives/Collection/components/Root.d.ts +2 -0
  98. package/dist/primitives/Table/Core/components/Body/util.d.ts +4 -4
  99. package/dist/primitives/Table/Core/components/Columns/Internal/Actions.d.ts +3 -1
  100. package/dist/primitives/Table/Core/components/Footer/Footer.d.ts +1 -1
  101. package/dist/primitives/Table/Core/components/Row/RowContext.d.ts +1 -0
  102. package/dist/primitives/Table/Core/features/useTableRenderer.d.ts +2 -2
  103. package/dist/primitives/Table/Core/features/useTableStyle.d.ts +3 -3
  104. package/dist/primitives/Table/Core/types.d.ts +4 -0
  105. package/dist/primitives/Table/Core/useTable.d.ts +2 -2
  106. package/dist/primitives/Table/types.d.ts +2 -2
  107. package/dist/primitives/Table/useTableManager/useTableManager.d.ts +1 -1
  108. package/dist/taco.cjs.development.js +1078 -727
  109. package/dist/taco.cjs.development.js.map +1 -1
  110. package/dist/taco.cjs.production.min.js +1 -1
  111. package/dist/taco.cjs.production.min.js.map +1 -1
  112. package/dist/utils/dom.d.ts +2 -1
  113. package/package.json +17 -17
  114. package/dist/esm/packages/taco/src/components/Table3/components/Row/Editing/CreateRowButton.js +0 -90
  115. 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);
@@ -4169,7 +4170,7 @@ const useMergedRef = ref => {
4169
4170
  };
4170
4171
 
4171
4172
  // taken from react-aria
4172
- const FOCUSABLE_ELEMENTS = ['input:not([disabled]):not([type=hidden])', 'select:not([disabled])', 'textarea:not([disabled])', 'button:not([disabled])', 'a[href]', 'area[href]', 'summary', 'iframe', 'object', 'embed', 'audio[controls]', 'video[controls]', '[contenteditable]', '[tabindex]:not([tabindex="-1"]):not([disabled])', 'details:not([disabled])', 'summary:not(:disabled)'];
4173
+ const FOCUSABLE_ELEMENTS = ['[tabindex]:not([disabled])', 'input:not([disabled])', 'select:not([disabled])', 'textarea:not([disabled])', 'button:not([disabled])', 'a[href]', 'area[href]', 'summary', 'iframe', 'object', 'embed', 'audio[controls]', 'video[controls]', '[contenteditable]', 'details:not([disabled])', 'summary:not(:disabled)'];
4173
4174
  const hasFocusableElement = element => {
4174
4175
  if (!element) {
4175
4176
  return null;
@@ -4195,13 +4196,20 @@ const getNextFocussableElement = currentElement => {
4195
4196
  if (!currentElement) {
4196
4197
  return null;
4197
4198
  }
4198
- const focussableElements = [...document.querySelectorAll(FOCUSABLE_ELEMENTS.join(','))];
4199
+ let focussableElements = [...document.querySelectorAll(FOCUSABLE_ELEMENTS.join(','))];
4199
4200
  const currentElementIndex = focussableElements.indexOf(currentElement);
4200
- // If the currentElement is not in the focussable elements list or it is the last element
4201
- if (currentElementIndex !== -1 && currentElementIndex === focussableElements.length - 1) {
4202
- return null;
4201
+ if (currentElementIndex > -1) {
4202
+ focussableElements = focussableElements.slice(currentElementIndex + 1).filter(element => element.getAttribute('tabindex') !== '-1');
4203
+ if (focussableElements.length) {
4204
+ var _focussableElements$;
4205
+ focussableElements = focussableElements.filter(element => {
4206
+ var _element$checkVisibil, _element$checkVisibil2;
4207
+ return (_element$checkVisibil = (_element$checkVisibil2 = element.checkVisibility) === null || _element$checkVisibil2 === void 0 ? void 0 : _element$checkVisibil2.call(element)) !== null && _element$checkVisibil !== void 0 ? _element$checkVisibil : true;
4208
+ });
4209
+ return (_focussableElements$ = focussableElements[0]) !== null && _focussableElements$ !== void 0 ? _focussableElements$ : null;
4210
+ }
4203
4211
  }
4204
- return focussableElements[currentElementIndex + 1];
4212
+ return null;
4205
4213
  };
4206
4214
  const getOverlaySelector = element => {
4207
4215
  switch (element === null || element === void 0 ? void 0 : element.getAttribute('role')) {
@@ -4213,7 +4221,7 @@ const getOverlaySelector = element => {
4213
4221
  return undefined;
4214
4222
  }
4215
4223
  };
4216
- function isElementInsideOrTriggeredFromContainer(element, container) {
4224
+ function isElementTriggeredFromContainer(element, container) {
4217
4225
  var _getOverlaySelector, _element$closest;
4218
4226
  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);
4219
4227
  if (selector) {
@@ -4224,11 +4232,14 @@ function isElementInsideOrTriggeredFromContainer(element, container) {
4224
4232
  const elementInDocument = document.querySelector(escapedSelector);
4225
4233
  // if the element does exist, see if it is itself connected to somethng that was triggered from the container
4226
4234
  if (elementInDocument) {
4227
- return isElementInsideOrTriggeredFromContainer(elementInDocument, container);
4235
+ return isElementTriggeredFromContainer(elementInDocument, container);
4228
4236
  }
4229
4237
  return false;
4230
4238
  }
4231
- return !!(container !== null && container !== void 0 && container.contains(element));
4239
+ return false;
4240
+ }
4241
+ function isElementInsideOrTriggeredFromContainer(element, container) {
4242
+ return isElementTriggeredFromContainer(element, container) || !!(container !== null && container !== void 0 && container.contains(element));
4232
4243
  }
4233
4244
  function isElementInsideOverlay(element) {
4234
4245
  return !!(element !== null && element !== void 0 && element.closest('[role=dialog],[role=menu]'));
@@ -4722,7 +4733,9 @@ const defaultLocalisationTexts = {
4722
4733
  tooltip: 'Edit table'
4723
4734
  },
4724
4735
  create: {
4725
- label: 'New'
4736
+ label: 'New',
4737
+ disabled: 'Existing new row must be saved',
4738
+ saving: 'Saving...'
4726
4739
  }
4727
4740
  },
4728
4741
  clearChangesConfirmationDialog: {
@@ -4744,8 +4757,8 @@ const defaultLocalisationTexts = {
4744
4757
  },
4745
4758
  validation: {
4746
4759
  alert: {
4747
- titleOne: '[COUNT] unsaved entry:',
4748
- titlePlural: '[COUNT] unsaved entries:',
4760
+ titleOne: '[COUNT] unsaved row:',
4761
+ titlePlural: '[COUNT] unsaved rows:',
4749
4762
  messageOne: "[COLUMN] [ROW] is incomplete and hasn't been saved.",
4750
4763
  messagePlural: "[COLUMN] [ROW] are incomplete and haven't been saved.",
4751
4764
  messageRow: 'Row',
@@ -7647,7 +7660,7 @@ const Switch = /*#__PURE__*/React.forwardRef(function Switch(props, ref) {
7647
7660
  onCheckedChange: onChange,
7648
7661
  ref: ref
7649
7662
  }), /*#__PURE__*/React.createElement(PrimitiveSwitch.Thumb, {
7650
- 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]"
7663
+ 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]"
7651
7664
  }));
7652
7665
  if (label) {
7653
7666
  const labelContainerClassName = cn('flex self-start cursor-pointer', {
@@ -8707,10 +8720,10 @@ const ModeSwitch = /*#__PURE__*/React.forwardRef(function ModeSwitch(props, ref)
8707
8720
  onCheckedChange: onChange,
8708
8721
  ref: ref
8709
8722
  }), /*#__PURE__*/React.createElement(PrimitiveSwitch.Thumb, {
8710
- 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%]"
8723
+ 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%]"
8711
8724
  }, /*#__PURE__*/React.createElement(Icon, {
8712
8725
  name: "edit-simple",
8713
- className: "!h-5 !w-5"
8726
+ className: "pointer-events-none !h-5 !w-5"
8714
8727
  })));
8715
8728
  });
8716
8729
  ModeSwitch.displayName = 'ModeSwitch';
@@ -10413,6 +10426,15 @@ function configureReactTableOptions(options, props, localization) {
10413
10426
  // We don't want to expose internal Tanstack Table row, so we need to wrap enableRowSelection callback into additional function,
10414
10427
  // which receives the React Table Row object and passes row.original to a callback.
10415
10428
  const reactTableEnableRowSelection = typeof options.enableRowSelection === 'function' ? row => options.enableRowSelection(row.original) : options.enableRowSelection;
10429
+ let getRowId;
10430
+ if (props.rowIdentityAccessor) {
10431
+ getRowId = (originalRow, index) => {
10432
+ if (originalRow) {
10433
+ return String(originalRow[props.rowIdentityAccessor]);
10434
+ }
10435
+ return String(index);
10436
+ };
10437
+ }
10416
10438
  const tableOptions = {
10417
10439
  defaultColumn: {
10418
10440
  enableColumnFilter: options.enableFiltering || true,
@@ -10431,11 +10453,13 @@ function configureReactTableOptions(options, props, localization) {
10431
10453
  enableGrouping: true,
10432
10454
  enableHiding: (_options$enableColumn2 = options.enableColumnHiding) !== null && _options$enableColumn2 !== void 0 ? _options$enableColumn2 : false,
10433
10455
  enablePinning: (_options$enableColumn3 = options.enableColumnFreezing) !== null && _options$enableColumn3 !== void 0 ? _options$enableColumn3 : false,
10456
+ enableRowPinning: true,
10434
10457
  enableRowSelection: reactTableEnableRowSelection !== null && reactTableEnableRowSelection !== void 0 ? reactTableEnableRowSelection : false,
10435
10458
  enableSorting: (_options$enableSortin = options.enableSorting) !== null && _options$enableSortin !== void 0 ? _options$enableSortin : false,
10436
10459
  // models for default features
10437
10460
  getExpandedRowModel: reactTable.getExpandedRowModel(),
10438
10461
  getGroupedRowModel: reactTable.getGroupedRowModel(),
10462
+ getRowId,
10439
10463
  groupedColumnMode: false
10440
10464
  };
10441
10465
  if (tableOptions.enableColumnResizing) {
@@ -10917,6 +10941,7 @@ function useTableRowHeight(isEnabled = false, defaultRowHeight = 'medium') {
10917
10941
  function useTableRowSelection(isEnabled = false) {
10918
10942
  const lastSelectedRowIndex = React__default.useRef();
10919
10943
  const onKeyDown = React__default.useCallback((event, table) => {
10944
+ var _event$target;
10920
10945
  if (!isEnabled || !table.options.enableRowSelection || event.defaultPrevented) {
10921
10946
  return;
10922
10947
  }
@@ -10931,7 +10956,7 @@ function useTableRowSelection(isEnabled = false) {
10931
10956
  (_rows$rowActiveIndex2 = rows[rowActiveIndex]) === null || _rows$rowActiveIndex2 === void 0 ? void 0 : _rows$rowActiveIndex2.toggleSelected();
10932
10957
  }
10933
10958
  return;
10934
- } else if ((event.ctrlKey || event.metaKey) && event.key === 'a') {
10959
+ } else if ((event.ctrlKey || event.metaKey) && event.key === 'a' && !['INPUT', 'TEXTAREA'].includes((_event$target = event.target) === null || _event$target === void 0 ? void 0 : _event$target.tagName)) {
10935
10960
  event.preventDefault();
10936
10961
  table.toggleAllRowsSelected();
10937
10962
  return;
@@ -11768,7 +11793,7 @@ function useTableManager(props, meta, internalColumns) {
11768
11793
  rowDrag,
11769
11794
  rowDrop: rowDrop,
11770
11795
  rowExpansion: rowExpansion,
11771
- rowIdentityColumnId: props.rowIdentityColumnId,
11796
+ rowIdentityAccessor: props.rowIdentityAccessor,
11772
11797
  rowGoto,
11773
11798
  rowGroups: rowGroups,
11774
11799
  rowHeight,
@@ -12106,7 +12131,8 @@ const Skeleton = /*#__PURE__*/React__default.forwardRef(function Skeleton(props,
12106
12131
 
12107
12132
  const RowContext = /*#__PURE__*/React__default.createContext({
12108
12133
  isHovered: false,
12109
- rowIndex: -1
12134
+ rowIndex: -1,
12135
+ hideRowActions: false
12110
12136
  });
12111
12137
 
12112
12138
  /* anonymous functions will break the memoisation on each render, wrap handlers in callbacks */
@@ -12114,6 +12140,7 @@ function Row(props) {
12114
12140
  const {
12115
12141
  renderer: RowRenderer,
12116
12142
  cellRenderer: CellRenderer,
12143
+ hideRowActions = false,
12117
12144
  ...displayRowProps
12118
12145
  } = props;
12119
12146
  const tableMeta = props.table.options.meta;
@@ -12121,8 +12148,9 @@ function Row(props) {
12121
12148
  // context - it must be here for cells to read it, since they render alongside the row inside DisplayRow
12122
12149
  const contextValue = React__default.useMemo(() => ({
12123
12150
  isHovered,
12124
- rowIndex: props.index
12125
- }), [isHovered, props.index]);
12151
+ rowIndex: props.index,
12152
+ hideRowActions
12153
+ }), [isHovered, props.index, hideRowActions]);
12126
12154
  if (props.row.original === undefined) {
12127
12155
  return /*#__PURE__*/React__default.createElement(SkeletonRow, Object.assign({}, props));
12128
12156
  }
@@ -12133,11 +12161,35 @@ function Row(props) {
12133
12161
  })));
12134
12162
  }
12135
12163
 
12136
- function useTableRenderer(renderers, table, tableRef, defaultRowActiveIndex) {
12137
- var _table$getState$group, _virtualItems$padding, _virtualItems$padding2, _virtualItems$padding3, _ref, _virtualItems;
12164
+ // scroll padding end is designed to always show half of the next row
12165
+ function getScrollPaddingEndOffset(table) {
12166
+ const tableMeta = table.options.meta;
12167
+ let offset = 2;
12168
+ if (tableMeta.footer.isEnabled) {
12169
+ offset += 1;
12170
+ }
12171
+ if (table.getHeaderGroups().length > 1) {
12172
+ offset += table.getHeaderGroups().length - 1;
12173
+ }
12174
+ let height = ROW_HEIGHT_ESTIMATES.medium * offset;
12175
+ const bottomRows = table.getBottomRows();
12176
+ if (bottomRows.length) {
12177
+ // 1.4 offsets for half rows and also accounts for increased row heights (which is likely in pinned rows)
12178
+ height += ROW_HEIGHT_ESTIMATES[tableMeta.rowHeight.height] * 1.4 * bottomRows.length;
12179
+ }
12180
+ return height;
12181
+ }
12182
+ // scroll padding end is designed to always show half of the next row
12183
+ function getPaddingEndOffset(table, options) {
12184
+ var _table$getBottomRows, _options$virtualiserP;
12185
+ const bottomRows = (_table$getBottomRows = table.getBottomRows()) !== null && _table$getBottomRows !== void 0 ? _table$getBottomRows : [];
12186
+ return ROW_HEIGHT_ESTIMATES.medium * ((_options$virtualiserP = options === null || options === void 0 ? void 0 : options.virtualiserPaddingEndOffset) !== null && _options$virtualiserP !== void 0 ? _options$virtualiserP : 1) * bottomRows.length;
12187
+ }
12188
+ function useTableRenderer(renderers, table, tableRef, defaultRowActiveIndex, options) {
12189
+ var _table$getState$group, _table$getCenterRows, _virtualItems$padding, _virtualItems$padding2, _virtualItems$padding3, _ref, _virtualItems;
12138
12190
  const tableMeta = table.options.meta;
12139
- const rows = table.getRowModel().rows;
12140
12191
  const isTableRowGrouped = !!((_table$getState$group = table.getState().grouping) !== null && _table$getState$group !== void 0 && _table$getState$group.length);
12192
+ const rows = (_table$getCenterRows = table.getCenterRows()) !== null && _table$getCenterRows !== void 0 ? _table$getCenterRows : [];
12141
12193
  // expanded rows
12142
12194
  const {
12143
12195
  createRowMeasurer,
@@ -12147,9 +12199,6 @@ function useTableRenderer(renderers, table, tableRef, defaultRowActiveIndex) {
12147
12199
  const rangeExtractor = useRowGroupVirtualisation(table);
12148
12200
  // account for thead and tfoot in the scroll area - both are always medium row height
12149
12201
  const scrollPaddingStart = ROW_HEIGHT_ESTIMATES.medium;
12150
- // column groups offset the bottom padding :shrug:, multiplying by 1.5 ensures the bottom padding remains
12151
- // consistent when there are groups and when there aren't. 1.5 is relatively arbitrary, but it gives alignment
12152
- const scrollPaddingEnd = ROW_HEIGHT_ESTIMATES.medium * (table.getHeaderGroups().length > 1 ? 1.5 : 1);
12153
12202
  const virtualiser = reactVirtual.useVirtualizer({
12154
12203
  count: rows.length,
12155
12204
  estimateSize,
@@ -12158,7 +12207,8 @@ function useTableRenderer(renderers, table, tableRef, defaultRowActiveIndex) {
12158
12207
  rangeExtractor,
12159
12208
  // correctly sets the scroll padding offset, e.g. when keyboard navigating rows in the list
12160
12209
  scrollPaddingStart,
12161
- scrollPaddingEnd: tableMeta.footer.isEnabled ? scrollPaddingEnd * 2 : scrollPaddingEnd
12210
+ scrollPaddingEnd: getScrollPaddingEndOffset(table),
12211
+ paddingEnd: getPaddingEndOffset(table, options)
12162
12212
  });
12163
12213
  const totalSize = virtualiser.getTotalSize();
12164
12214
  const virtualItems = virtualiser.getVirtualItems();
@@ -12315,12 +12365,14 @@ function Actions$1(props) {
12315
12365
  actionsLength,
12316
12366
  data,
12317
12367
  isActiveRow,
12318
- rowId
12368
+ rowId,
12369
+ table
12319
12370
  } = props;
12320
12371
  const {
12321
12372
  texts
12322
12373
  } = useLocalization();
12323
- const visibleActions = actions.map(action => action(data, rowId)).filter(action => !!action);
12374
+ // we don't want to document passing table, so it isn't on the type
12375
+ const visibleActions = actions.map(action => action(data, rowId, table)).filter(action => !!action);
12324
12376
  const actionsOnRow = visibleActions.length === actionsLength ? visibleActions : visibleActions.slice(0, actionsLength - 1);
12325
12377
  const actionsInMenu = visibleActions.slice(visibleActions.length === actionsLength ? actionsLength : actionsLength - 1);
12326
12378
  const className = cn('flex justify-end text-right bg-[inherit] shadow-[-6px_0px_6px_var(--table-row-actions-shadow)] print:hidden');
@@ -12360,7 +12412,8 @@ const Cell = /*#__PURE__*/React__default.memo(function MemoedCell(context) {
12360
12412
  } = context;
12361
12413
  const {
12362
12414
  isHovered,
12363
- rowIndex
12415
+ rowIndex,
12416
+ hideRowActions
12364
12417
  } = React__default.useContext(RowContext);
12365
12418
  const tableMeta = table.options.meta;
12366
12419
  const actions = tableMeta.rowActions.rowActions;
@@ -12368,15 +12421,14 @@ const Cell = /*#__PURE__*/React__default.memo(function MemoedCell(context) {
12368
12421
  const isActiveRow = tableMeta.rowActive.rowActiveIndex === rowIndex;
12369
12422
  const isResizingColumn = !!table.getState().columnSizingInfo.isResizingColumn;
12370
12423
  const isHoverStatePaused = tableMeta.rowActive.isHoverStatePaused;
12371
- // We don't want to show actions in edit mode, since we have editing actions,
12372
- // which is shown in edit mode instead.
12373
- if (actions !== null && actions !== void 0 && actions.length && (isActiveRow || isHovered && !isHoverStatePaused && !isResizingColumn)) {
12424
+ if (!hideRowActions && actions !== null && actions !== void 0 && actions.length && (isActiveRow || isHovered && !isHoverStatePaused && !isResizingColumn)) {
12374
12425
  return /*#__PURE__*/React__default.createElement(Actions$1, {
12375
12426
  actions: actions,
12376
12427
  actionsLength: actionsLength,
12377
12428
  data: row.original,
12378
12429
  isActiveRow: isActiveRow,
12379
- rowId: row.id
12430
+ rowId: row.id,
12431
+ table: table
12380
12432
  });
12381
12433
  }
12382
12434
  return null;
@@ -12626,13 +12678,13 @@ const INTERNAL_RENDERERS = {
12626
12678
  rowExpansion: renderer$2,
12627
12679
  rowSelection: renderer$3
12628
12680
  };
12629
- function useTable(props, externalRef, renderers, meta) {
12681
+ function useTable(props, externalRef, renderers, meta, options) {
12630
12682
  // create a ref and merge with the consumer's ref
12631
12683
  const ref = useMergedRef(externalRef);
12632
12684
  // configure the table
12633
12685
  const manager = useTableManager(props, meta, INTERNAL_RENDERERS);
12634
12686
  // configure the virtualised renderer
12635
- const renderer = useTableRenderer(renderers, manager.instance, ref, props.defaultRowActiveIndex);
12687
+ const renderer = useTableRenderer(renderers, manager.instance, ref, props.defaultRowActiveIndex, options);
12636
12688
  // configure dynamic styling
12637
12689
  const {
12638
12690
  style,
@@ -12733,7 +12785,10 @@ function GroupedCell(props) {
12733
12785
  index,
12734
12786
  isHighlighted
12735
12787
  } = props;
12736
- const tableMeta = cell.getContext().table.options.meta;
12788
+ const {
12789
+ table
12790
+ } = cell.getContext();
12791
+ const tableMeta = table.options.meta;
12737
12792
  const columnMeta = cell.column.columnDef.meta;
12738
12793
  const attributes = getCellAttributes(cell, index, isHighlighted);
12739
12794
  const {
@@ -12751,7 +12806,8 @@ function GroupedCell(props) {
12751
12806
  colSpan: colSpan,
12752
12807
  rowActions: tableMeta.rowGroups.rowActionsForGroup,
12753
12808
  rowId: cell.row.id,
12754
- subRows: subRows
12809
+ subRows: subRows,
12810
+ table: table
12755
12811
  }), content);
12756
12812
  }
12757
12813
  const MemoedGroupedCell = /*#__PURE__*/React__default.memo(function MemoedGroupedCell(props) {
@@ -12763,6 +12819,7 @@ const MemoedGroupedCell = /*#__PURE__*/React__default.memo(function MemoedGroupe
12763
12819
  rowActions,
12764
12820
  rowId,
12765
12821
  subRows,
12822
+ table,
12766
12823
  ...attributes
12767
12824
  } = props;
12768
12825
  return /*#__PURE__*/React__default.createElement("td", Object.assign({}, attributes, {
@@ -12777,7 +12834,8 @@ const MemoedGroupedCell = /*#__PURE__*/React__default.memo(function MemoedGroupe
12777
12834
  actionsLength: 4,
12778
12835
  data: subRows,
12779
12836
  isActiveRow: true,
12780
- rowId: rowId
12837
+ rowId: rowId,
12838
+ table: table
12781
12839
  })) : null);
12782
12840
  });
12783
12841
 
@@ -12839,7 +12897,7 @@ const DisplayRow = /*#__PURE__*/React__default.memo(function DisplayRow(props) {
12839
12897
  if (tableMeta.rowActive.isEnabled) {
12840
12898
  attributes['data-row-active'] = tableMeta.rowActive.rowActiveIndex === index ? true : undefined;
12841
12899
  // we use capture because it let's us picks up clicks on components inside the row, e.g. checkboxes
12842
- attributes.onClickCapture = handleClickCapture;
12900
+ attributes.onPointerDown = handleClickCapture;
12843
12901
  }
12844
12902
  // row click
12845
12903
  if (tableMeta.rowClick.isEnabled(row.original)) {
@@ -12917,7 +12975,7 @@ const DisplayRow = /*#__PURE__*/React__default.memo(function DisplayRow(props) {
12917
12975
  const expansionRef = React__default.useRef(null);
12918
12976
  const isExpanded = !!attributes['data-row-expanded'];
12919
12977
  useSetVirtualisedRowHeight(measureRow, ref.current, expansionRef.current, isExpanded);
12920
- const className = cn('group/row', {
12978
+ const className = cn('group/row', otherAttributes.className, {
12921
12979
  'hover:cursor-grab': tableMeta.rowDrag.isEnabled && typeof attributes.onClick !== 'function',
12922
12980
  'hover:cursor-pointer': typeof attributes.onClick === 'function'
12923
12981
  });
@@ -14401,6 +14459,7 @@ const getOptionsFromCollection = (collection, selector) => collection.querySelec
14401
14459
  const Root = /*#__PURE__*/React__default.forwardRef(function CollectionRoot(props, ref) {
14402
14460
  const {
14403
14461
  querySelector,
14462
+ resetOnChange,
14404
14463
  tabIndex = 0,
14405
14464
  ...otherProps
14406
14465
  } = props;
@@ -14431,14 +14490,31 @@ const Root = /*#__PURE__*/React__default.forwardRef(function CollectionRoot(prop
14431
14490
  internalRef.current.setActiveIndexByElement = setActiveIndexByElement;
14432
14491
  }
14433
14492
  }, [internalRef.current]);
14493
+ React__default.useEffect(() => {
14494
+ if (internalRef.current) {
14495
+ const selected = internalRef.current.querySelectorAll(`[aria-current="true"]`);
14496
+ const options = getOptionsFromCollection(internalRef.current, querySelector);
14497
+ if (options.length && selected.length === 1) {
14498
+ const firstSelected = internalRef.current.querySelector(`[aria-selected]`);
14499
+ if (firstSelected) {
14500
+ const selectedIndex = Array.from(options).indexOf(firstSelected);
14501
+ if (selectedIndex > -1) {
14502
+ setActiveOption(selectedIndex, internalRef.current, firstSelected);
14503
+ }
14504
+ }
14505
+ }
14506
+ }
14507
+ }, [resetOnChange]);
14434
14508
  React__default.useEffect(() => {
14435
14509
  if (internalRef.current) {
14436
14510
  const options = getOptionsFromCollection(internalRef.current, querySelector);
14437
14511
  if (options.length) {
14438
14512
  let selected = internalRef.current.querySelectorAll(`[aria-current="true"]`);
14513
+ // if nothing is current (keyboard visible), look for selected items
14439
14514
  if (selected.length === 0) {
14440
14515
  selected = internalRef.current.querySelectorAll(`[aria-selected]`);
14441
14516
  }
14517
+ // if one item is selected, make sure it's current
14442
14518
  if (selected.length === 1) {
14443
14519
  if (options) {
14444
14520
  const firstSelected = selected.item(0);
@@ -14584,6 +14660,7 @@ const Root$1 = /*#__PURE__*/React__default.forwardRef(function Listbox2(props, r
14584
14660
  id: id,
14585
14661
  querySelector: customSelector ? `${DEFAULT_SELECTOR}, ${customSelector}` : DEFAULT_SELECTOR,
14586
14662
  ref: ref,
14663
+ resetOnChange: value,
14587
14664
  role: "listbox"
14588
14665
  }), children)));
14589
14666
  });
@@ -14642,10 +14719,6 @@ const Option = /*#__PURE__*/React__default.forwardRef(function Listbox2Option(pr
14642
14719
  if (disabled || listboxDisabled || listboxReadOnly) {
14643
14720
  event.stopPropagation();
14644
14721
  return;
14645
- }
14646
- // UX requirement: if tab key is pressed and the current option is selected then keydown event is ignored
14647
- else if (event.key === 'Tab' && selected) {
14648
- return;
14649
14722
  } else if (isAriaSelectionKey(event)) {
14650
14723
  setValue(value);
14651
14724
  }
@@ -14656,7 +14729,6 @@ const Option = /*#__PURE__*/React__default.forwardRef(function Listbox2Option(pr
14656
14729
  return /*#__PURE__*/React__default.createElement("div", Object.assign({}, otherProps, {
14657
14730
  "aria-disabled": listboxDisabled || disabled ? 'true' : undefined,
14658
14731
  "aria-selected": selected ? 'true' : undefined,
14659
- key: `${value}_${String(selected)}`,
14660
14732
  id: id,
14661
14733
  onClick: handleClick,
14662
14734
  onKeyDown: handleKeyDown,
@@ -15099,7 +15171,9 @@ const Button$3 = /*#__PURE__*/React__default.forwardRef(function Select2TriggerB
15099
15171
  var _props$className;
15100
15172
  const {
15101
15173
  children,
15174
+ onBlur,
15102
15175
  onClick,
15176
+ onFocus,
15103
15177
  tabIndex = 0,
15104
15178
  ...otherProps
15105
15179
  } = props;
@@ -15130,6 +15204,18 @@ const Button$3 = /*#__PURE__*/React__default.forwardRef(function Select2TriggerB
15130
15204
  onClick(event);
15131
15205
  }
15132
15206
  };
15207
+ let handleBlur;
15208
+ if (typeof onBlur === 'function') {
15209
+ // we might be focusing on an input or something inside the dropdown that was triggered by the select
15210
+ // so see if the element gaining focus is inside a portal and look up its controller
15211
+ // if we don't do this, things like validate on blur occur while simply opening the select
15212
+ handleBlur = event => {
15213
+ if (isElementInsideOrTriggeredFromContainer(event.relatedTarget, event.currentTarget)) {
15214
+ return;
15215
+ }
15216
+ onBlur(event);
15217
+ };
15218
+ }
15133
15219
  // select the value text if the select is readonly
15134
15220
  const handleFocus = event => {
15135
15221
  if (readOnly) {
@@ -15139,6 +15225,9 @@ const Button$3 = /*#__PURE__*/React__default.forwardRef(function Select2TriggerB
15139
15225
  (_window$getSelection = window.getSelection()) === null || _window$getSelection === void 0 ? void 0 : (_window$getSelection$ = _window$getSelection.selectAllChildren) === null || _window$getSelection$ === void 0 ? void 0 : _window$getSelection$.call(_window$getSelection, value);
15140
15226
  }
15141
15227
  }
15228
+ if (typeof onFocus === 'function') {
15229
+ onFocus(event);
15230
+ }
15142
15231
  };
15143
15232
  return /*#__PURE__*/React__default.createElement("button", Object.assign({}, otherProps, {
15144
15233
  "aria-invalid": invalid ? true : undefined,
@@ -15146,6 +15235,7 @@ const Button$3 = /*#__PURE__*/React__default.forwardRef(function Select2TriggerB
15146
15235
  className: className,
15147
15236
  disabled: disabled,
15148
15237
  onClick: handleClick,
15238
+ onBlur: handleBlur,
15149
15239
  onFocus: handleFocus,
15150
15240
  ref: ref,
15151
15241
  role: "combobox",
@@ -15408,17 +15498,12 @@ const BubbleSelect = props => {
15408
15498
  };
15409
15499
 
15410
15500
  const Search$2 = /*#__PURE__*/React__default.forwardRef(function ListboxSearch(props, ref) {
15411
- const {
15412
- onTabKeyPress,
15413
- ...otherProps
15414
- } = props;
15415
15501
  const {
15416
15502
  listboxRef,
15417
15503
  searchQuery,
15418
15504
  setSearchQuery,
15419
15505
  setValidationError,
15420
- validationError,
15421
- setOpen
15506
+ validationError
15422
15507
  } = useSelect2Context();
15423
15508
  const handleChange = event => {
15424
15509
  if (validationError) {
@@ -15431,11 +15516,6 @@ const Search$2 = /*#__PURE__*/React__default.forwardRef(function ListboxSearch(p
15431
15516
  if (event.key === ' ') {
15432
15517
  return;
15433
15518
  }
15434
- // Select2 should close dropdown and receive focus, when user press Tab while searching (UX requirement to support better keyboard navigation)
15435
- if (event.key === 'Tab') {
15436
- setOpen(false);
15437
- onTabKeyPress();
15438
- }
15439
15519
  if (isAriaSelectionKey(event) || event.key === 'ArrowDown' || event.key === 'ArrowUp') {
15440
15520
  var _listboxRef$current;
15441
15521
  event.preventDefault();
@@ -15450,7 +15530,7 @@ const Search$2 = /*#__PURE__*/React__default.forwardRef(function ListboxSearch(p
15450
15530
  }),
15451
15531
  invalid: !!validationError,
15452
15532
  message: validationError === null || validationError === void 0 ? void 0 : validationError.message
15453
- }, /*#__PURE__*/React__default.createElement(Input, Object.assign({}, otherProps, {
15533
+ }, /*#__PURE__*/React__default.createElement(Input, Object.assign({}, props, {
15454
15534
  autoFocus: true,
15455
15535
  invalid: !!validationError,
15456
15536
  onChange: handleChange,
@@ -15674,7 +15754,6 @@ const Select2 = /*#__PURE__*/React__default.forwardRef(function Select2(props, r
15674
15754
  // align the listbox min width with the width of the input - it should never be smaller
15675
15755
  const dimensions = useBoundingClientRectListener(internalRef);
15676
15756
  // state
15677
- const [tabTriggeredClose, setTabTriggeredClose] = React__default.useState(false);
15678
15757
  const [open, setOpen] = React__default.useState(false);
15679
15758
  const [value, _setValue] = reactUseControllableState.useControllableState({
15680
15759
  // uncontrolled
@@ -15751,7 +15830,7 @@ const Select2 = /*#__PURE__*/React__default.forwardRef(function Select2(props, r
15751
15830
  var _listboxRef$current;
15752
15831
  if (open) {
15753
15832
  event.preventDefault();
15754
- } else if (isElementInsideTable3OrReport(event.currentTarget)) {
15833
+ } else if (isElementInsideTable3OrReport(event.currentTarget) && isAriaDirectionKey(event)) {
15755
15834
  return;
15756
15835
  } else if (!event.ctrlKey && !event.metaKey && (event.key === 'ArrowDown' || /^[a-z0-9]$/i.test(event.key))) {
15757
15836
  setOpen(true);
@@ -15762,46 +15841,32 @@ const Select2 = /*#__PURE__*/React__default.forwardRef(function Select2(props, r
15762
15841
  // the focus should always remain on the input, so we forward events on to the listbox
15763
15842
  (_listboxRef$current = listboxRef.current) === null || _listboxRef$current === void 0 ? void 0 : _listboxRef$current.dispatchEvent(createCustomKeyboardEvent(event));
15764
15843
  };
15765
- let handleBlur;
15766
- if (otherProps.onBlur) {
15767
- // we might be focusing on an input or something inside the dropdown that was triggered by the select
15768
- // so see if the element gaining focus is inside a portal and look up its controller
15769
- // if we don't do this, things like validate on blur occur while simply opening the select
15770
- handleBlur = event => {
15771
- var _elementGainingFocus$;
15772
- const elementGainingFocus = event.relatedTarget;
15773
- if (elementGainingFocus === undefined) {
15774
- return;
15775
- }
15776
- const portalId = elementGainingFocus === null || elementGainingFocus === void 0 ? void 0 : (_elementGainingFocus$ = elementGainingFocus.closest('[data-radix-popper-content-wrapper] > :first-child')) === null || _elementGainingFocus$ === void 0 ? void 0 : _elementGainingFocus$.id;
15777
- if (!portalId || event.currentTarget.getAttribute(`aria-controls`) !== portalId) {
15778
- var _otherProps$onBlur;
15779
- (_otherProps$onBlur = otherProps.onBlur) === null || _otherProps$onBlur === void 0 ? void 0 : _otherProps$onBlur.call(otherProps, event);
15780
- }
15781
- };
15782
- }
15844
+ const shouldFocusNextRef = React__default.useRef(false);
15783
15845
  const handleListboxKeyDown = event => {
15784
15846
  if (isAriaDirectionKey(event)) {
15785
15847
  setShouldPauseHoverState(true);
15848
+ return;
15849
+ }
15850
+ if (event.key === 'Tab') {
15851
+ shouldFocusNextRef.current = true;
15852
+ setOpen(false);
15853
+ return;
15786
15854
  }
15855
+ // support typeahead to set the value by typing its text
15787
15856
  if (!hasSearch && /^[a-z0-9]$/i.test(event.key)) {
15788
15857
  setValueIfMatched(event.key);
15858
+ return;
15789
15859
  }
15790
15860
  };
15861
+ // popover closes and unmounts before any event can be used to focus next, so prevent focusing the trigger and focus next
15791
15862
  const handleCloseAutoFocus = event => {
15792
- event.preventDefault();
15793
- event.stopPropagation();
15794
- if (tabTriggeredClose) {
15795
- const nextFocussableElement = getNextFocussableElement(internalRef.current);
15796
- if (nextFocussableElement) {
15797
- // UX requirement: move focus to the next focussable element when tab key is pressed to select the value
15798
- nextFocussableElement.focus();
15799
- // Reset the tabTriggeredClose state
15800
- setTabTriggeredClose(false);
15801
- }
15802
- } else {
15803
- var _internalRef$current;
15804
- (_internalRef$current = internalRef.current) === null || _internalRef$current === void 0 ? void 0 : _internalRef$current.focus();
15863
+ if (shouldFocusNextRef.current) {
15864
+ var _otherProps$onBlur, _getNextFocussableEle;
15865
+ event.preventDefault();
15866
+ shouldFocusNextRef.current = false;
15867
+ (_otherProps$onBlur = otherProps.onBlur) === null || _otherProps$onBlur === void 0 ? void 0 : _otherProps$onBlur.call(otherProps, event);
15868
+ (_getNextFocussableEle = getNextFocussableElement(internalRef.current)) === null || _getNextFocussableEle === void 0 ? void 0 : _getNextFocussableEle.focus();
15869
+ return;
15805
15870
  }
15806
15871
  };
15807
15872
  const areAllSelected = Array.isArray(value) && selectOptions.every(option => value.includes(option));
@@ -15850,18 +15915,14 @@ const Select2 = /*#__PURE__*/React__default.forwardRef(function Select2(props, r
15850
15915
  }, /*#__PURE__*/React__default.createElement(Trigger$7, Object.assign({}, otherProps, {
15851
15916
  "aria-haspopup": "listbox",
15852
15917
  emptyValue: emptyValue,
15853
- onBlur: handleBlur,
15854
15918
  onKeyDown: handleKeyDown,
15855
15919
  placeholder: placeholder,
15856
15920
  ref: internalRef
15857
15921
  }), flattenedChildren)), /*#__PURE__*/React__default.createElement(PopoverPrimitive.Portal, null, /*#__PURE__*/React__default.createElement(PopoverPrimitive.Content, {
15858
15922
  asChild: true,
15859
15923
  align: "start",
15860
- onOpenAutoFocus: () => {
15861
- var _internalRef$current2;
15862
- (_internalRef$current2 = internalRef.current) === null || _internalRef$current2 === void 0 ? void 0 : _internalRef$current2.focus();
15863
- },
15864
15924
  onCloseAutoFocus: handleCloseAutoFocus,
15925
+ onPointerDownOutside: otherProps.onBlur,
15865
15926
  sideOffset: 4,
15866
15927
  tabIndex: -1
15867
15928
  }, /*#__PURE__*/React__default.createElement("div", {
@@ -15871,8 +15932,7 @@ const Select2 = /*#__PURE__*/React__default.forwardRef(function Select2(props, r
15871
15932
  }
15872
15933
  }, hasSearch ? (/*#__PURE__*/React__default.createElement(React__default.Fragment, null, /*#__PURE__*/React__default.createElement(Search$2, {
15873
15934
  placeholder: hasInlineCreation ? texts.select2.searchOrCreate : texts.select2.search,
15874
- ref: searchRef,
15875
- onTabKeyPress: () => setTabTriggeredClose(true)
15935
+ ref: searchRef
15876
15936
  }), multiple && selectOptions.length > 1 && (/*#__PURE__*/React__default.createElement(React__default.Fragment, null, /*#__PURE__*/React__default.createElement(Button$1, {
15877
15937
  className: "!justify-start",
15878
15938
  appearance: "discrete",
@@ -15942,6 +16002,7 @@ const ControlledHiddenField = props => {
15942
16002
  key: String(bubbleValue),
15943
16003
  multiple: multiple,
15944
16004
  name: name,
16005
+ tabIndex: -1,
15945
16006
  value: bubbleValue
15946
16007
  }, emptyValue !== undefined ? /*#__PURE__*/React__default.createElement("option", {
15947
16008
  value: emptyValue
@@ -16393,7 +16454,7 @@ function Control(props) {
16393
16454
  const ref = React__default.useRef(null);
16394
16455
  React.useEffect(() => {
16395
16456
  // Set value to false only after first render of the control (when it's undefined) after setting the FilterColumn value, because we don't want to change then the value every time filter is opened
16396
- if (controlRenderer === 'switch' && value === undefined) {
16457
+ if ((controlRenderer === 'switch' || controlRenderer === 'checkbox') && value === undefined) {
16397
16458
  onChange(false);
16398
16459
  }
16399
16460
  }, [controlRenderer]);
@@ -16418,6 +16479,12 @@ function Control(props) {
16418
16479
  checked: Boolean(value),
16419
16480
  onChange: onChange
16420
16481
  }));
16482
+ } else if (controlRenderer === 'checkbox') {
16483
+ return /*#__PURE__*/React__default.createElement(Checkbox, Object.assign({}, attributes, {
16484
+ className: "!m-1.5",
16485
+ checked: Boolean(value),
16486
+ onChange: onChange
16487
+ }));
16421
16488
  } else if ((controlRenderer === 'input' || controlRenderer === undefined) && dataType === 'number') {
16422
16489
  return /*#__PURE__*/React__default.createElement(Input, Object.assign({}, attributes, {
16423
16490
  className: "flex-grow",
@@ -16777,8 +16844,6 @@ function TableGrid(props) {
16777
16844
  table.meta.rowActive.handleFocus(event, table.meta.length, table.renderer.scrollToIndex);
16778
16845
  } : undefined;
16779
16846
  const filterReason = getFilterReason(table);
16780
- const searchNotApplied = !table.state.globalFilter || table.state.globalFilter === '';
16781
- const filtersNotApplied = !table.state.columnFilters || table.state.columnFilters.length === 0;
16782
16847
  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, {
16783
16848
  id: table.id,
16784
16849
  "data-table-font-size": table.meta.fontSize.size,
@@ -16811,7 +16876,7 @@ function TableGrid(props) {
16811
16876
  ...table.renderer.style,
16812
16877
  height: table.renderer.style.height + ROW_HEIGHT_ESTIMATES[table.meta.rowHeight.height]
16813
16878
  } : table.renderer.style
16814
- }, table.renderer.rows, searchNotApplied && filtersNotApplied && props.children), table.meta.footer.isEnabled ? /*#__PURE__*/React__default.createElement(Foot, {
16879
+ }, table.renderer.rows, props.children), table.meta.footer.isEnabled ? /*#__PURE__*/React__default.createElement(Foot, {
16815
16880
  table: table.instance
16816
16881
  }) : null)))));
16817
16882
  }
@@ -18314,71 +18379,6 @@ const useTableRowCreation = (data, tableRef) => {
18314
18379
  };
18315
18380
  };
18316
18381
 
18317
- function useTableEditingListener(table, tableRef) {
18318
- const tableMeta = table.options.meta;
18319
- const completedRowsCount = tableMeta.editing.getCompletedRowsCount();
18320
- const localization = useLocalization();
18321
- const saveChanges = () => {
18322
- requestAnimationFrame(() => {
18323
- tableMeta.editing.saveChanges();
18324
- });
18325
- };
18326
- // save when the row changes
18327
- useLazyEffect(() => {
18328
- if (tableMeta.editing.isEditing) {
18329
- saveChanges();
18330
- }
18331
- }, [tableMeta.rowActive.rowActiveIndex]);
18332
- useLazyEffect(() => {
18333
- if (tableMeta.editing.isEditing) {
18334
- if (tableMeta.rowActive.rowActiveIndex === undefined) {
18335
- tableMeta.rowActive.setRowActiveIndex(0);
18336
- }
18337
- } else {
18338
- // save
18339
- saveChanges();
18340
- // reset detailed mode
18341
- tableMeta.editing.toggleDetailedMode(false);
18342
- // reset the last index back to the first focusable element, when editing gets turned off
18343
- tableMeta.editing.setLastFocusedCellIndex(undefined);
18344
- }
18345
- }, [tableMeta.editing.isEditing]);
18346
- // show a warning if the user navigates away without triggering save, such as using the browser back/forward button
18347
- const hasChanges = tableMeta.editing.hasChanges();
18348
- React__default.useEffect(() => {
18349
- function showUnsavedChangesWarning(event) {
18350
- if (tableMeta.editing.isEditing && hasChanges) {
18351
- event.returnValue = true;
18352
- return true;
18353
- }
18354
- return false;
18355
- }
18356
- window.addEventListener('beforeunload', showUnsavedChangesWarning);
18357
- return () => {
18358
- window.removeEventListener('beforeunload', showUnsavedChangesWarning);
18359
- };
18360
- }, [tableMeta.editing.isEditing, hasChanges]);
18361
- React__default.useEffect(() => {
18362
- if (completedRowsCount > 0) {
18363
- resetHighlightedColumnIndexes(table.getState().globalFilter, table, localization);
18364
- }
18365
- }, [completedRowsCount]);
18366
- React__default.useEffect(() => {
18367
- const onClickOutside = event => {
18368
- if (tableMeta.editing.isEditing) {
18369
- var _event$target$getAttr, _event$target;
18370
- 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 : '';
18371
- const insideTable = isElementInsideOrTriggeredFromContainer(event.target, tableRef.current) || element === 'backdrop';
18372
- if (!insideTable) {
18373
- saveChanges();
18374
- }
18375
- }
18376
- };
18377
- document.addEventListener('click', onClickOutside);
18378
- return () => document.removeEventListener('click', onClickOutside);
18379
- }, [saveChanges, tableMeta.editing.isEditing]);
18380
- }
18381
-
18382
18382
  function willRowMove(cell, change, rowIndex, localization) {
18383
18383
  const {
18384
18384
  table
@@ -18459,444 +18459,642 @@ function willRowMoveAfterSorting(cell, change, rowIndex) {
18459
18459
  }
18460
18460
  return ((_resortedRows$index = resortedRows[index]) === null || _resortedRows$index === void 0 ? void 0 : _resortedRows$index.id) !== cell.row.id;
18461
18461
  }
18462
- function animateCreateRow(id) {
18463
- const templateRow = document.querySelector(`[data-row-id="${id}"]`);
18464
- if (templateRow) {
18465
- const firstCell = templateRow.querySelector(':first-child');
18466
- const checkbox = firstCell === null || firstCell === void 0 ? void 0 : firstCell.querySelector('[data-taco="checkbox"]');
18467
- firstCell === null || firstCell === void 0 ? void 0 : firstCell.focus();
18468
- if (checkbox) {
18469
- setDataFocusAttribute(checkbox);
18470
- }
18471
- templateRow.scrollIntoView();
18472
- const keyframes = [{
18473
- background: '#b2c7ef'
18474
- }, {
18475
- background: '#ebebeb'
18476
- }];
18477
- for (const child of templateRow.children) {
18478
- child.animate(keyframes, {
18479
- duration: 1000,
18480
- easing: 'ease-out'
18481
- });
18482
- }
18462
+ const TEMPORARY_ROW_ID_PREFIX = 'temp-';
18463
+ function isTemporaryRow(rowId) {
18464
+ if (rowId === undefined) {
18465
+ return false;
18483
18466
  }
18467
+ return String(rowId).startsWith(TEMPORARY_ROW_ID_PREFIX);
18484
18468
  }
18469
+ const shortcut = {
18470
+ key: 'e',
18471
+ meta: true,
18472
+ shift: false
18473
+ };
18485
18474
 
18486
- function useTableEditing(isEnabled = false, handleSave, handleChange, validator) {
18487
- // used to switch the table into editing mode
18488
- const [isEditing, toggleEditing] = React__default.useState(false);
18489
- // used to switch the editing between "detailed" mode
18490
- const [isDetailedMode, toggleDetailedMode] = React__default.useState(false);
18491
- // store the last focused cell, so that up/down arrow key navigation remains in the same column
18492
- const [lastFocusedCellIndex, setLastFocusedCellIndex] = useLastFocusedCellIndex();
18493
- // store pending changes for each row
18494
- // changes are saved as soon as the active row changes, so in most cases this will only contain the active row's changes
18495
- // but not always - if validation or server requests fail when saving, those rows remain until the failure is resolved
18496
- const pendingChangesFns = usePendingChanges(isEnabled, handleSave, handleChange, validator);
18497
- useGlobalKeyDown(isEnabled && isEditing ? {
18475
+ function useTableEditingListener(table, tableRef, scrollToIndex) {
18476
+ const tableMeta = table.options.meta;
18477
+ const localization = useLocalization();
18478
+ // save when the row changes
18479
+ // store the last row active index, otherwise everytime tableMeta.editing.saveChanges changes the hook runs again
18480
+ const lastRowActiveIndexRef = React__default.useRef(tableMeta.rowActive.rowActiveIndex);
18481
+ useLazyEffect(() => {
18482
+ if (tableMeta.editing.isEditing && lastRowActiveIndexRef.current !== undefined && tableMeta.rowActive.rowActiveIndex !== lastRowActiveIndexRef.current) {
18483
+ lastRowActiveIndexRef.current = tableMeta.rowActive.rowActiveIndex;
18484
+ tableMeta.editing.saveChanges(table);
18485
+ }
18486
+ }, [tableMeta.rowActive.rowActiveIndex, tableMeta.editing.saveChanges]);
18487
+ // show a warning if the user navigates away without triggering save, such as using the browser back/forward button
18488
+ const hasChanges = tableMeta.editing.hasChanges();
18489
+ React__default.useEffect(() => {
18490
+ function showUnsavedChangesWarning(event) {
18491
+ if (tableMeta.editing.isEditing && hasChanges) {
18492
+ event.returnValue = true;
18493
+ return true;
18494
+ }
18495
+ return false;
18496
+ }
18497
+ window.addEventListener('beforeunload', showUnsavedChangesWarning);
18498
+ return () => {
18499
+ window.removeEventListener('beforeunload', showUnsavedChangesWarning);
18500
+ };
18501
+ }, [tableMeta.editing.isEditing, hasChanges]);
18502
+ const hasSavedChanges = tableMeta.editing.hasSaved();
18503
+ useLazyEffect(() => {
18504
+ if (hasSavedChanges) {
18505
+ resetHighlightedColumnIndexes(table.getState().globalFilter, table, localization);
18506
+ }
18507
+ }, [hasSavedChanges]);
18508
+ React__default.useEffect(() => {
18509
+ const onClickOutside = event => {
18510
+ if (tableMeta.editing.isEditing) {
18511
+ const element = event.target;
18512
+ const insideTable = element.getAttribute('data-taco') === 'backdrop' || element.getAttribute('data-table') === 'editing-toggle' || isElementInsideOrTriggeredFromContainer(element, tableRef.current);
18513
+ // users can click the white space below rows which could be inside the table, but a valid scenario to save
18514
+ if (!insideTable || element.tagName === 'TABLE' || element.tagName === 'TBODY') {
18515
+ tableMeta.editing.saveChanges(table);
18516
+ }
18517
+ }
18518
+ };
18519
+ document.addEventListener('click', onClickOutside);
18520
+ return () => document.removeEventListener('click', onClickOutside);
18521
+ }, [tableMeta.editing.isEditing, tableMeta.editing.saveChanges]);
18522
+ const rows = table.getRowModel().rows;
18523
+ // make sure pending changes are removed for rows that no longer exist
18524
+ useLazyEffect(() => {
18525
+ const pendingChanges = tableMeta.editing.getErrorsShownInAlert();
18526
+ pendingChanges.forEach(pendingChange => {
18527
+ try {
18528
+ table.getRow(pendingChange.rowId);
18529
+ } catch {
18530
+ tableMeta.editing.discardChanges(pendingChange.rowId, table);
18531
+ }
18532
+ });
18533
+ }, [rows.length]);
18534
+ // shortcuts
18535
+ useGlobalKeyDown(tableMeta.editing.isEnabled ? shortcut : undefined, event => {
18536
+ event.preventDefault();
18537
+ tableMeta.editing.toggleEditing(!tableMeta.editing.isEditing, table, scrollToIndex);
18538
+ });
18539
+ useGlobalKeyDown(tableMeta.editing.isEditing ? {
18498
18540
  key: 's',
18499
18541
  meta: true,
18500
18542
  shift: false
18501
18543
  } : undefined, event => {
18502
18544
  event.preventDefault();
18503
- pendingChangesFns.saveChanges();
18545
+ tableMeta.editing.saveChanges(table);
18504
18546
  });
18505
- return {
18506
- isEnabled,
18507
- isEditing,
18508
- isDetailedMode,
18509
- toggleDetailedMode: isEnabled ? toggleDetailedMode : () => undefined,
18510
- toggleEditing: isEnabled ? toggleEditing : () => undefined,
18511
- lastFocusedCellIndex,
18512
- setLastFocusedCellIndex,
18513
- ...pendingChangesFns
18514
- };
18515
18547
  }
18516
- function usePendingChanges(isEnabled, handleSave, handleChange, validator) {
18517
- const saveChanges = function (rowId = undefined) {
18548
+
18549
+ const DELAY_BEFORE_REMOVING_SAVE_STATUS = 3000;
18550
+ function reducer$2(state, action) {
18551
+ const {
18552
+ type,
18553
+ rowId,
18554
+ payload
18555
+ } = action;
18556
+ switch (type) {
18557
+ case 'setCellValue':
18558
+ {
18559
+ const {
18560
+ columnId,
18561
+ row,
18562
+ value
18563
+ } = payload;
18564
+ return {
18565
+ ...state,
18566
+ changes: {
18567
+ ...state.changes,
18568
+ rows: setWith(state.changes.rows, `${rowId}.${columnId}`, value, Object),
18569
+ originals: setWith(state.changes.originals, rowId, row, Object)
18570
+ }
18571
+ };
18572
+ }
18573
+ case 'removeCellValue':
18574
+ {
18575
+ const {
18576
+ columnId,
18577
+ rowIdentityAccessor
18578
+ } = payload;
18579
+ const changes = omit(state.changes.rows, `${rowId}.${columnId}`);
18580
+ // if there are no changes left, remove the row
18581
+ if (!Object.keys(changes[rowId]).length) {
18582
+ return reducer$2(state, {
18583
+ type: 'removeRow',
18584
+ rowId,
18585
+ payload: {
18586
+ rowIdentityAccessor
18587
+ }
18588
+ });
18589
+ }
18590
+ return {
18591
+ ...state,
18592
+ changes: {
18593
+ ...state.changes,
18594
+ rows: omit(state.changes.rows, `${rowId}.${columnId}`),
18595
+ errors: omit(state.changes.errors, `${rowId}.cells.${columnId}`),
18596
+ moveReasons: omit(state.changes.moveReasons, `${rowId}.${columnId}`)
18597
+ }
18598
+ };
18599
+ }
18600
+ case 'updateRow':
18601
+ {
18602
+ const {
18603
+ cellErrors,
18604
+ moveReasons,
18605
+ original,
18606
+ value
18607
+ } = payload;
18608
+ return {
18609
+ ...state,
18610
+ changes: {
18611
+ ...state.changes,
18612
+ rows: setWith(state.changes.rows, rowId, value, Object),
18613
+ errors: setWith(state.changes.errors, `${rowId}.cells`, cellErrors !== null && cellErrors !== void 0 ? cellErrors : state.changes.errors.cells[rowId], Object),
18614
+ originals: setWith(state.changes.originals, rowId, original !== null && original !== void 0 ? original : state.changes.originals[rowId], Object),
18615
+ moveReasons: setWith(state.changes.moveReasons, rowId, moveReasons !== null && moveReasons !== void 0 ? moveReasons : state.changes.moveReasons[rowId], Object),
18616
+ // status can be undefined, so don't use ??
18617
+ status: setWith(state.changes.status, rowId, undefined, Object)
18618
+ }
18619
+ };
18620
+ }
18621
+ case 'removeRow':
18622
+ {
18623
+ const {
18624
+ rowIdentityAccessor
18625
+ } = payload;
18626
+ return {
18627
+ ...state,
18628
+ changes: {
18629
+ ...state.changes,
18630
+ rows: omit(state.changes.rows, rowId),
18631
+ errors: omit(state.changes.errors, rowId),
18632
+ moveReasons: omit(state.changes.moveReasons, rowId),
18633
+ originals: omit(state.changes.originals, rowId),
18634
+ status: omit(state.changes.status, rowId)
18635
+ },
18636
+ temporaryRows: state.temporaryRows.filter(row => row[rowIdentityAccessor] !== rowId)
18637
+ };
18638
+ }
18639
+ case 'setRowStatus':
18640
+ {
18641
+ const {
18642
+ status
18643
+ } = payload;
18644
+ return {
18645
+ ...state,
18646
+ changes: {
18647
+ ...state.changes,
18648
+ status: status ? setWith(state.changes.status, rowId, status, Object) : omit(state.changes.status, rowId)
18649
+ }
18650
+ };
18651
+ }
18652
+ case 'setRowErrors':
18653
+ {
18654
+ const {
18655
+ ...errors
18656
+ } = payload;
18657
+ return {
18658
+ ...state,
18659
+ changes: {
18660
+ ...state.changes,
18661
+ errors: setWith(state.changes.errors, rowId, errors, Object)
18662
+ }
18663
+ };
18664
+ }
18665
+ case 'createRow':
18666
+ {
18667
+ const {
18668
+ value
18669
+ } = payload;
18670
+ return {
18671
+ ...state,
18672
+ temporaryRows: state.temporaryRows.concat(value),
18673
+ changes: {
18674
+ ...state.changes,
18675
+ rows: setWith(state.changes.rows, rowId, value, Object),
18676
+ originals: setWith(state.changes.originals, rowId, value, Object)
18677
+ }
18678
+ };
18679
+ }
18680
+ default:
18681
+ return state;
18682
+ }
18683
+ }
18684
+ function usePendingChangesState(handleSave, handleChange, rowIdentityAccessor, validator) {
18685
+ const saveChanges = function (table, rowId = undefined) {
18518
18686
  try {
18519
18687
  let _exit = false;
18520
18688
  if (!handleSave) {
18521
18689
  console.warn('Tried to save, but Table has no onEditingSave handler');
18522
- return Promise.resolve();
18690
+ return Promise.resolve(false);
18523
18691
  }
18524
- // we save back to pendingChanges, so make a copy of it's state when save was triggered
18525
- const changesToSave = rowId ? {
18526
- [rowId]: pendingChanges[rowId]
18527
- } : {
18528
- ...pendingChanges
18529
- };
18530
- const changes = Object.keys(changesToSave);
18531
- return Promise.resolve(function () {
18532
- if (changes.length) {
18533
- return _forOf(changes, function (rowId) {
18534
- const pendingChange = changesToSave[rowId];
18535
- const changeSet = getChangesetFromChanges(pendingChange);
18536
- return _catch(function () {
18537
- function _temp3(_result) {
18538
- return _exit ? _result : Promise.resolve(handleSave(changeSet)).then(function () {
18539
- // cleanup changes, we don't need them after saving
18540
- resetChanges(rowId);
18541
- setRowSaveStatus(rowId, 'complete');
18542
- });
18543
- }
18544
- if (getRowSaveStatus(rowId) === 'pending') {
18545
- _exit = true;
18546
- return;
18547
- }
18548
- // set saving = true
18549
- setRowSaveStatus(rowId, 'pending');
18550
- // re-run validation, maybe a cell is already invalid but has never been blurred
18551
- const _temp2 = function () {
18552
- if (validator) {
18553
- return Promise.resolve(validator(changeSet)).then(function (errors) {
18554
- if (errors && Object.keys(errors).length) {
18555
- throw errors;
18556
- }
18557
- });
18558
- }
18559
- }();
18560
- return _temp2 && _temp2.then ? _temp2.then(_temp3) : _temp3(_temp2); // send new data to the server
18561
- }, function (error) {
18562
- // the onEditingSave handler should throw errors when something fails, e.g. validation, network errors etc
18563
- // this code handles those errors and maps them either to row errors or cell specific errors
18564
- let rowError;
18565
- let cellErrors;
18566
- if (typeof error === 'string') {
18567
- rowError = error;
18568
- } else if (error instanceof Error) {
18569
- var _error$response;
18570
- rowError = error.message;
18571
- // most of our apis return error objects within this shape
18572
- if (typeof ((_error$response = error.response) === null || _error$response === void 0 ? void 0 : _error$response.data) === 'object') {
18573
- var _error$response2;
18574
- cellErrors = (_error$response2 = error.response) === null || _error$response2 === void 0 ? void 0 : _error$response2.data;
18575
- }
18576
- } else if (typeof error === 'object') {
18577
- cellErrors = error;
18578
- }
18579
- if (rowError || cellErrors) {
18580
- setPendingChanges(currentChanges => {
18581
- const nextChanges = {
18582
- ...currentChanges
18583
- };
18584
- nextChanges[rowId]._meta.errors = {
18585
- row: rowError,
18586
- cells: cellErrors,
18587
- shouldShowErrorAlert: true
18588
- };
18589
- return nextChanges;
18590
- });
18591
- }
18592
- setRowSaveStatus(rowId, undefined);
18692
+ // sometimes we only want to save one row
18693
+ const changes = rowId ? {
18694
+ [rowId]: state.changes.rows[rowId]
18695
+ } : state.changes.rows;
18696
+ let completed = true;
18697
+ const _temp9 = _forOf(Object.keys(changes), function (rowId) {
18698
+ const status = getRowStatus(rowId);
18699
+ return _catch(function () {
18700
+ function _temp8(_result) {
18701
+ return _exit ? _result : Promise.resolve(handleSave(changeSet)).then(function () {
18702
+ // cleanup changes, we don't need them after saving
18703
+ discardChanges(rowId, table);
18704
+ // show the saved status, then remove it after a delay
18705
+ setRowStatus(rowId, 'saved');
18706
+ setTimeout(() => {
18707
+ setRowStatus(rowId, undefined);
18708
+ }, DELAY_BEFORE_REMOVING_SAVE_STATUS);
18593
18709
  });
18594
- }, function () {
18595
- return _exit;
18596
- });
18597
- }
18598
- }());
18710
+ }
18711
+ // don't try to save if - already saving, or there are known errors
18712
+ if (status === 'saving' || status === 'errored') {
18713
+ return;
18714
+ }
18715
+ setRowStatus(rowId, 'saving');
18716
+ const changeSet = {
18717
+ ...state.changes.originals[rowId],
18718
+ ...changes[rowId]
18719
+ };
18720
+ // if we had to create a temporary id, delete it first - it's our data, not theirs
18721
+ if (isTemporaryRow(changeSet[rowIdentityAccessor])) {
18722
+ delete changeSet[rowIdentityAccessor];
18723
+ }
18724
+ // re-run validation, maybe a cell is already invalid but has never been blurred
18725
+ const _temp7 = function () {
18726
+ if (validator) {
18727
+ return Promise.resolve(validator(changeSet)).then(function (errors) {
18728
+ if (errors && Object.keys(errors).length) {
18729
+ throw errors;
18730
+ }
18731
+ });
18732
+ }
18733
+ }();
18734
+ return _temp7 && _temp7.then ? _temp7.then(_temp8) : _temp8(_temp7); // send new data to the server
18735
+ }, function (error) {
18736
+ var _error$response;
18737
+ 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) {
18738
+ console.error(error);
18739
+ }
18740
+ // the onEditingSave handler should throw errors when something fails, e.g. validation, network errors etc
18741
+ // this code handles those errors and maps them either to row errors or cell specific errors
18742
+ let rowError;
18743
+ let cellErrors;
18744
+ if (typeof error === 'string') {
18745
+ rowError = error;
18746
+ } else if (error instanceof Error) {
18747
+ var _error$response2;
18748
+ rowError = error.message;
18749
+ // most of our apis return error objects within this shape
18750
+ if (typeof ((_error$response2 = error.response) === null || _error$response2 === void 0 ? void 0 : _error$response2.data) === 'object') {
18751
+ var _error$response3;
18752
+ cellErrors = (_error$response3 = error.response) === null || _error$response3 === void 0 ? void 0 : _error$response3.data;
18753
+ }
18754
+ } else if (typeof error === 'object') {
18755
+ cellErrors = error;
18756
+ }
18757
+ if (rowError || cellErrors) {
18758
+ dispatch({
18759
+ type: 'setRowErrors',
18760
+ rowId,
18761
+ payload: {
18762
+ row: rowError,
18763
+ cells: cellErrors,
18764
+ shouldShowErrorAlert: true
18765
+ }
18766
+ });
18767
+ }
18768
+ setRowStatus(rowId, 'errored');
18769
+ completed = false;
18770
+ });
18771
+ }, function () {
18772
+ return _exit;
18773
+ });
18774
+ return Promise.resolve(_temp9 && _temp9.then ? _temp9.then(function (_result3) {
18775
+ return _exit ? _result3 : completed;
18776
+ }) : _exit ? _temp9 : completed);
18599
18777
  } catch (e) {
18600
18778
  return Promise.reject(e);
18601
18779
  }
18602
18780
  };
18603
- const validateCell = function (cell) {
18781
+ const onCellChanged = function (cell, rowIndex, shouldRunUpdaters = true) {
18604
18782
  try {
18605
- if (!validator || !isEnabled) {
18606
- return Promise.resolve();
18607
- }
18608
- const changeSet = getChangesetFromChanges(pendingChanges[cell.row.id]);
18609
- // only validate if the cell being blurred actually has any changes
18610
- const _temp = function () {
18611
- if (cell.column.id in changeSet) {
18612
- return Promise.resolve(validator(changeSet)).then(function (errors) {
18613
- setPendingChanges(currentChanges => {
18614
- const nextChanges = {
18615
- ...currentChanges
18616
- };
18617
- nextChanges[cell.row.id]._meta = {
18618
- ...nextChanges[cell.row.id]._meta,
18619
- errors: {
18620
- ...nextChanges[cell.row.id]._meta.errors,
18621
- cells: errors,
18622
- shouldShowErrorAlert: !Object.keys(errors).length ? false : nextChanges[cell.row.id]._meta.errors.shouldShowErrorAlert
18783
+ function _temp6() {
18784
+ var _state$changes$errors11;
18785
+ function _temp4() {
18786
+ // only set errors and move reasons for the cells we're currently acting on
18787
+ // why? because the UX is not good if we set them for cells the user hasn't touched yet
18788
+ const cellsToActOn = [cell.column.id, ...Object.keys(updatesForOtherCells)];
18789
+ const allCells = cell.row._getAllCellsByColumnId();
18790
+ cellsToActOn.forEach(accessor => {
18791
+ if (validationErrors[accessor]) {
18792
+ nextCellErrors[accessor] = validationErrors[accessor];
18793
+ // don't show move indicator for cells with errors, they aren't valid and can't be saved
18794
+ delete nextMoveReasons[accessor];
18795
+ } else {
18796
+ var _allCells$accessor;
18797
+ // there isn't any error in this run, remove any error set in state
18798
+ delete nextCellErrors[accessor];
18799
+ if ((_allCells$accessor = allCells[accessor]) !== null && _allCells$accessor !== void 0 && _allCells$accessor.column.getIsSorted()) {
18800
+ // run row move determination
18801
+ const reason = willRowMove(cell, nextChanges[accessor], rowIndex, localization);
18802
+ // if the row will move based on this change save why, otherwise delete any existing state
18803
+ if (reason) {
18804
+ nextMoveReasons[accessor] = reason;
18805
+ } else {
18806
+ delete nextMoveReasons[accessor];
18623
18807
  }
18624
- };
18625
- return nextChanges;
18808
+ }
18809
+ }
18810
+ });
18811
+ dispatch({
18812
+ type: 'updateRow',
18813
+ rowId: cell.row.id,
18814
+ payload: {
18815
+ cellErrors: nextCellErrors,
18816
+ moveReasons: nextMoveReasons,
18817
+ value: nextChanges
18818
+ }
18819
+ });
18820
+ }
18821
+ // create a projection of the next state, so we can act against it
18822
+ const nextChanges = {
18823
+ ...state.changes.rows[cell.row.id],
18824
+ ...updatesForOtherCells
18825
+ };
18826
+ const nextMoveReasons = {
18827
+ ...state.changes.moveReasons[cell.row.id]
18828
+ };
18829
+ const nextCellErrors = {
18830
+ ...((_state$changes$errors11 = state.changes.errors[cell.row.id]) === null || _state$changes$errors11 === void 0 ? void 0 : _state$changes$errors11.cells)
18831
+ };
18832
+ // run validation
18833
+ let validationErrors = {};
18834
+ const _temp3 = function () {
18835
+ if (validator) {
18836
+ const nextRowValue = {
18837
+ ...state.changes.originals[cell.row.id],
18838
+ ...changes,
18839
+ ...updatesForOtherCells
18840
+ };
18841
+ return Promise.resolve(validator(nextRowValue)).then(function (_validator2) {
18842
+ validationErrors = _validator2 !== null && _validator2 !== void 0 ? _validator2 : {};
18626
18843
  });
18844
+ }
18845
+ }();
18846
+ return _temp3 && _temp3.then ? _temp3.then(_temp4) : _temp4(_temp3);
18847
+ }
18848
+ const changes = state.changes.rows[cell.row.id];
18849
+ if (!changes) {
18850
+ return Promise.resolve();
18851
+ }
18852
+ let updatesForOtherCells = {};
18853
+ // run the updater handler if there is one, to see if there are any other cells to update
18854
+ const _temp5 = function () {
18855
+ if (typeof handleChange === 'function' && shouldRunUpdaters) {
18856
+ const previousRowValue = {
18857
+ ...state.changes.originals[cell.row.id]
18858
+ };
18859
+ const nextRowValue = {
18860
+ ...state.changes.originals[cell.row.id],
18861
+ ...changes
18862
+ };
18863
+ return Promise.resolve(handleChange(cell.column.id, changes[cell.column.id], nextRowValue, previousRowValue)).then(function (_handleChange) {
18864
+ updatesForOtherCells = _handleChange !== null && _handleChange !== void 0 ? _handleChange : {};
18627
18865
  });
18628
18866
  }
18629
18867
  }();
18630
- return Promise.resolve(_temp && _temp.then ? _temp.then(function () {}) : void 0);
18868
+ return Promise.resolve(_temp5 && _temp5.then ? _temp5.then(_temp6) : _temp6(_temp5));
18631
18869
  } catch (e) {
18632
18870
  return Promise.reject(e);
18633
18871
  }
18634
- };
18635
- const setCellValue = function (cell, change, rowIndex) {
18872
+ }; // general
18873
+ // rows
18874
+ const setRowValue = function (rowId, original, value) {
18636
18875
  try {
18637
- const changes = {
18638
- [cell.column.id]: change
18639
- };
18640
- setPendingChanges(currentChanges => {
18641
- const nextChanges = createPendingChangesSetter(currentChanges, cell.row, rowIndex, changes, localization);
18642
- pendingChangesUpdater.syncCellChanges(nextChanges);
18643
- return nextChanges;
18644
- });
18645
- pendingChangesUpdater.runCellUpdates(changes, cell, rowIndex);
18646
- return Promise.resolve();
18647
- } catch (e) {
18648
- return Promise.reject(e);
18649
- }
18650
- };
18651
- const addCreatedRowChangeset = function (row) {
18652
- try {
18653
- const cells = row.getAllCells();
18654
- setPendingChanges(currentChanges => {
18655
- return cells.reduce((changes, cell) => {
18656
- if (cell.getValue()) {
18657
- var _currentChanges$cell$, _currentChanges$cell$2, _currentChanges$cell$3;
18658
- return {
18659
- ...changes,
18660
- [cell.row.id]: {
18661
- ...changes[cell.row.id],
18662
- [cell.column.id]: cell.getValue(),
18663
- _meta: {
18664
- ...((_currentChanges$cell$ = currentChanges[cell.row.id]) === null || _currentChanges$cell$ === void 0 ? void 0 : _currentChanges$cell$._meta),
18665
- original: cell.row.original,
18666
- moveReason: {
18667
- ...((_currentChanges$cell$2 = currentChanges[cell.row.id]) === null || _currentChanges$cell$2 === void 0 ? void 0 : _currentChanges$cell$2._meta.moveReason)
18668
- },
18669
- errors: {
18670
- ...((_currentChanges$cell$3 = currentChanges[cell.row.id]) === null || _currentChanges$cell$3 === void 0 ? void 0 : _currentChanges$cell$3._meta.errors)
18671
- }
18672
- }
18673
- }
18674
- };
18675
- } else {
18676
- return changes;
18876
+ function _temp2() {
18877
+ dispatch({
18878
+ type: 'updateRow',
18879
+ rowId,
18880
+ payload: {
18881
+ cellErrors,
18882
+ original,
18883
+ value
18677
18884
  }
18678
- }, currentChanges);
18679
- });
18680
- return Promise.resolve();
18885
+ });
18886
+ }
18887
+ let cellErrors;
18888
+ const _temp = function () {
18889
+ if (validator) {
18890
+ const row = {
18891
+ ...original,
18892
+ ...value
18893
+ };
18894
+ return Promise.resolve(validator(row)).then(function (_validator) {
18895
+ cellErrors = _validator !== null && _validator !== void 0 ? _validator : {};
18896
+ });
18897
+ }
18898
+ }();
18899
+ return Promise.resolve(_temp && _temp.then ? _temp.then(_temp2) : _temp2(_temp));
18681
18900
  } catch (e) {
18682
18901
  return Promise.reject(e);
18683
18902
  }
18684
18903
  };
18685
18904
  const localization = useLocalization();
18686
- const [pendingChanges, setPendingChanges] = React__default.useState({});
18687
- // we maintain save status as separate state because 'complete' needs to briefly show after pendingChanges are deleted
18688
- const [saveStates, setSaveState] = React__default.useState({});
18689
- function getCellValue(cell) {
18690
- var _pendingChanges$cell$;
18691
- return (_pendingChanges$cell$ = pendingChanges[cell.row.id]) === null || _pendingChanges$cell$ === void 0 ? void 0 : _pendingChanges$cell$[cell.column.id];
18905
+ const [state, dispatch] = React__default.useReducer(reducer$2, {
18906
+ changes: {
18907
+ rows: {},
18908
+ errors: {},
18909
+ moveReasons: {},
18910
+ originals: {},
18911
+ status: {}
18912
+ },
18913
+ temporaryRows: []
18914
+ });
18915
+ function getRowValue(rowId) {
18916
+ var _state$changes$rows$r, _state$changes$rows;
18917
+ 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;
18692
18918
  }
18693
- function getCellError(cell) {
18694
- var _pendingChanges$cell$2, _pendingChanges$cell$3, _pendingChanges$cell$4;
18695
- 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];
18919
+ function getRowMoveReason(rowId) {
18920
+ var _Object$values$, _state$changes$moveRe, _state$changes$moveRe2;
18921
+ 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;
18696
18922
  }
18697
- const pendingChangesUpdater = usePendingChangesUpdater(handleChange, setPendingChanges);
18698
18923
  function hasRowErrors(rowId) {
18699
- var _pendingChanges$rowId, _pendingChanges$rowId2, _pendingChanges$rowId3, _pendingChanges$rowId4, _pendingChanges$rowId5;
18700
- if (!isEnabled) {
18701
- return false;
18702
- }
18703
- 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;
18924
+ var _state$changes$errors, _state$changes$errors2, _state$changes$errors3;
18925
+ 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;
18926
+ }
18927
+ function hasRowErrorsShownInAlert(rowId) {
18928
+ var _state$changes$errors4;
18929
+ return hasRowErrors(rowId) && !!((_state$changes$errors4 = state.changes.errors[rowId]) !== null && _state$changes$errors4 !== void 0 && _state$changes$errors4.shouldShowErrorAlert);
18704
18930
  }
18705
- function hasRowErrorsSeen(rowId) {
18706
- var _pendingChanges$rowId6;
18707
- if (!isEnabled) {
18931
+ function hasTemporaryRowErrors() {
18932
+ var _state$temporaryRows, _state$changes$errors5, _state$changes$errors6, _state$changes$errors7;
18933
+ const newRow = (_state$temporaryRows = state.temporaryRows) === null || _state$temporaryRows === void 0 ? void 0 : _state$temporaryRows[0];
18934
+ if (!newRow) {
18708
18935
  return false;
18709
18936
  }
18710
- return hasRowErrors(rowId) && !!((_pendingChanges$rowId6 = pendingChanges[rowId]._meta.errors) !== null && _pendingChanges$rowId6 !== void 0 && _pendingChanges$rowId6.shouldShowErrorAlert);
18937
+ const rowId = newRow[rowIdentityAccessor];
18938
+ return !!((_state$changes$errors5 = state.changes.errors[rowId]) !== null && _state$changes$errors5 !== void 0 && _state$changes$errors5.row) || !!Object.keys((_state$changes$errors6 = (_state$changes$errors7 = state.changes.errors[rowId]) === null || _state$changes$errors7 === void 0 ? void 0 : _state$changes$errors7.cells) !== null && _state$changes$errors6 !== void 0 ? _state$changes$errors6 : {}).length;
18711
18939
  }
18712
- function getRowPendingChange(rowId) {
18713
- const rowPendingChanges = pendingChanges[rowId];
18714
- if (rowPendingChanges) {
18715
- const {
18716
- _meta,
18717
- ...pendingChange
18718
- } = rowPendingChanges;
18719
- return pendingChange;
18720
- }
18721
- return undefined;
18940
+ function getRowStatus(rowId) {
18941
+ return state.changes.status[rowId];
18722
18942
  }
18723
- function getRowSaveStatus(rowId) {
18724
- if (!isEnabled) {
18725
- return false;
18726
- }
18727
- return saveStates[rowId];
18943
+ function setRowStatus(rowId, status) {
18944
+ dispatch({
18945
+ type: 'setRowStatus',
18946
+ rowId,
18947
+ payload: {
18948
+ status
18949
+ }
18950
+ });
18728
18951
  }
18729
- function setRowSaveStatus(rowId, status) {
18730
- setSaveState(currentStates => {
18731
- const nextStates = {
18732
- ...currentStates
18733
- };
18734
- if (status) {
18735
- nextStates[rowId] = status;
18736
- } else {
18737
- delete nextStates[rowId];
18952
+ function createRow(data) {
18953
+ const newRowId = `${TEMPORARY_ROW_ID_PREFIX}${uuid.v4()}`;
18954
+ const value = {
18955
+ ...data,
18956
+ [rowIdentityAccessor]: newRowId
18957
+ };
18958
+ dispatch({
18959
+ type: 'createRow',
18960
+ rowId: newRowId,
18961
+ payload: {
18962
+ value
18738
18963
  }
18739
- return nextStates;
18740
18964
  });
18965
+ return newRowId;
18966
+ }
18967
+ // cells
18968
+ function setCellValue(cell, value) {
18969
+ const rowId = cell.row.id;
18970
+ const columnId = cell.column.id;
18971
+ // update if the change is different to the original value
18972
+ if (value !== cell.row.original[columnId]) {
18973
+ dispatch({
18974
+ type: 'setCellValue',
18975
+ rowId,
18976
+ payload: {
18977
+ columnId,
18978
+ row: cell.row.original,
18979
+ value
18980
+ }
18981
+ });
18982
+ }
18983
+ // otherwise remove any previous change - no point saving the same value
18984
+ else if (cell.row.id in state.changes.rows) {
18985
+ dispatch({
18986
+ type: 'removeCellValue',
18987
+ rowId,
18988
+ payload: {
18989
+ columnId,
18990
+ rowIdentityAccessor
18991
+ }
18992
+ });
18993
+ }
18741
18994
  }
18742
- function getRowMoveReason(rowId) {
18743
- var _pendingChanges$rowId7;
18744
- return (_pendingChanges$rowId7 = pendingChanges[rowId]) !== null && _pendingChanges$rowId7 !== void 0 && _pendingChanges$rowId7._meta.moveReason ? Object.values(pendingChanges[rowId]._meta.moveReason)[0] : undefined;
18995
+ function getCellValue(cell) {
18996
+ var _state$changes$rows2, _state$changes$rows2$;
18997
+ 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];
18745
18998
  }
18746
- function hasChanges(rowId) {
18747
- if (!isEnabled) {
18748
- return false;
18749
- }
18750
- return rowId ? !!pendingChanges[rowId] : !!Object.keys(pendingChanges).length;
18999
+ function getCellError(cell) {
19000
+ var _state$changes$errors8, _state$changes$errors9, _state$changes$errors10;
19001
+ return (_state$changes$errors8 = state.changes.errors) === null || _state$changes$errors8 === void 0 ? void 0 : (_state$changes$errors9 = _state$changes$errors8[cell.row.id]) === null || _state$changes$errors9 === void 0 ? void 0 : (_state$changes$errors10 = _state$changes$errors9.cells) === null || _state$changes$errors10 === void 0 ? void 0 : _state$changes$errors10[cell.column.id];
18751
19002
  }
18752
- function hasAlertErrors() {
18753
- if (!isEnabled) {
18754
- return false;
19003
+ function getErrorsShownInAlert() {
19004
+ const rowsWithErrors = Object.keys(state.changes.errors);
19005
+ if (!rowsWithErrors.length) {
19006
+ return [];
18755
19007
  }
18756
- return !!getAlertErrors().length;
18757
- }
18758
- function getAlertErrors() {
18759
- return Object.keys(pendingChanges).filter(hasRowErrorsSeen).map(rowId => ({
19008
+ return rowsWithErrors.filter(hasRowErrorsShownInAlert).map(rowId => ({
18760
19009
  rowId,
18761
- pendingChange: pendingChanges[rowId]
19010
+ changes: state.changes.rows[rowId],
19011
+ errors: state.changes.errors[rowId]
18762
19012
  }));
18763
19013
  }
18764
- function resetChanges(rowId) {
18765
- setPendingChanges(currentChanges => {
18766
- const nextChanges = {
18767
- ...currentChanges
18768
- };
18769
- delete nextChanges[rowId];
18770
- return nextChanges;
18771
- });
19014
+ function hasSaved() {
19015
+ return !!Object.values(state.changes.status).filter(value => value === 'saved').length;
18772
19016
  }
18773
- function getCompletedRowsCount() {
18774
- return Object.values(saveStates).filter(value => value === 'complete').length;
19017
+ function hasChanges(rowId) {
19018
+ return rowId ? !!state.changes.rows[rowId] : !!Object.keys(state.changes.rows).length;
19019
+ }
19020
+ function discardChanges(rowId, table) {
19021
+ // remove any new rows from pinned state before discarding them
19022
+ table.resetRowPinning(true);
19023
+ dispatch({
19024
+ type: 'removeRow',
19025
+ rowId,
19026
+ payload: {
19027
+ rowIdentityAccessor
19028
+ }
19029
+ });
18775
19030
  }
18776
19031
  return {
19032
+ // row
19033
+ setRowValue,
19034
+ getRowValue,
19035
+ getRowMoveReason,
19036
+ hasRowErrors,
19037
+ hasRowErrorsShownInAlert,
19038
+ hasTemporaryRowErrors,
19039
+ getRowStatus,
19040
+ setRowStatus,
19041
+ // cells
19042
+ setCellValue,
18777
19043
  getCellValue,
18778
19044
  getCellError,
18779
- setCellValue,
18780
- validateCell,
18781
- addCreatedRowChangeset,
19045
+ onCellChanged,
19046
+ // general
19047
+ getErrorsShownInAlert,
18782
19048
  hasChanges,
18783
- hasAlertErrors,
18784
- getAlertErrors,
18785
19049
  saveChanges,
18786
- resetChanges,
18787
- hasRowErrors,
18788
- hasRowErrorsSeen,
18789
- getRowPendingChange,
18790
- getRowSaveStatus,
18791
- setRowSaveStatus,
18792
- getRowMoveReason,
18793
- getCompletedRowsCount
19050
+ discardChanges,
19051
+ hasSaved,
19052
+ // new rows
19053
+ createRow,
19054
+ temporaryRows: state.temporaryRows
18794
19055
  };
18795
19056
  }
18796
- function useLastFocusedCellIndex() {
19057
+
19058
+ function useTableEditing(isEnabled = false, handleSave, handleChange, rowIdentityAccessor, validator) {
19059
+ // used to switch the table into editing mode
19060
+ const [isEditing, setEditing] = React__default.useState(false);
19061
+ // used to switch the editing between "detailed" mode
19062
+ const [isDetailedMode, toggleDetailedMode] = React__default.useState(false);
19063
+ // used to contain ref to the create button
19064
+ const createRowButtonRef = React__default.useRef(null);
18797
19065
  // store the last focused cell, so that up/down arrow key navigation remains in the same column
18798
- const lastFocusedCellIndexRef = React__default.useRef(undefined);
18799
- const setLastFocusedCellIndex = React__default.useCallback(index => {
18800
- lastFocusedCellIndexRef.current = index;
18801
- }, []);
18802
- return [lastFocusedCellIndexRef.current, setLastFocusedCellIndex];
18803
- }
18804
- function usePendingChangesUpdater(handleChange, setPendingChanges) {
18805
- const localization = useLocalization();
18806
- const updatersRef = React__default.useRef({});
18807
- const runCellUpdates = React__default.useCallback(lodash.debounce(function (changes, cell, rowIndex) {
18808
- try {
18809
- const _temp4 = function () {
18810
- if (typeof handleChange === 'function') {
18811
- const previousValues = {
18812
- ...cell.row.original,
18813
- ...getChangesetFromChanges(updatersRef.current[cell.row.id])
18814
- };
18815
- const nextValues = {
18816
- ...previousValues,
18817
- ...changes
18818
- };
18819
- return Promise.resolve(handleChange(cell.column.id, changes[cell.column.id], nextValues, previousValues)).then(function (updates) {
18820
- if (updates && Object.keys(updates).length) {
18821
- setPendingChanges(currentChanges => createPendingChangesSetter(currentChanges, cell.row, rowIndex, updates, localization));
18822
- }
18823
- });
18824
- }
18825
- }();
18826
- return Promise.resolve(_temp4 && _temp4.then ? _temp4.then(function () {}) : void 0);
18827
- } catch (e) {
18828
- return Promise.reject(e);
19066
+ const [lastFocusedCellIndex, setLastFocusedCellIndex] = React__default.useState(undefined);
19067
+ const pendingChangesFns = usePendingChangesState(handleSave, handleChange, rowIdentityAccessor, validator);
19068
+ function toggleEditing(enabled, table, scrollToIndex) {
19069
+ var _tableMeta$rowActive$, _table$getRowModel$ro;
19070
+ if (!enabled) {
19071
+ // save
19072
+ pendingChangesFns.saveChanges(table);
19073
+ // reset detailed mode
19074
+ toggleDetailedMode(false);
19075
+ // reset the last index back to the first focusable element, when editing gets turned off
19076
+ setLastFocusedCellIndex(undefined);
18829
19077
  }
18830
- }, 250), []);
18831
- function syncCellChanges(changes) {
18832
- updatersRef.current = changes;
18833
- }
18834
- return {
18835
- syncCellChanges,
18836
- runCellUpdates
18837
- };
18838
- }
18839
- function createPendingChangesSetter(currentChanges, row, rowIndex, changes, localization) {
18840
- var _currentChanges$row$i, _currentChanges$row$i2, _currentChanges$row$i3;
18841
- // prepare
18842
- const nextChanges = {
18843
- ...currentChanges
18844
- };
18845
- const rowChanges = {
18846
- ...currentChanges[row.id],
18847
- _meta: {
18848
- ...((_currentChanges$row$i = currentChanges[row.id]) === null || _currentChanges$row$i === void 0 ? void 0 : _currentChanges$row$i._meta),
18849
- original: row.original,
18850
- moveReason: {
18851
- ...((_currentChanges$row$i2 = currentChanges[row.id]) === null || _currentChanges$row$i2 === void 0 ? void 0 : _currentChanges$row$i2._meta.moveReason)
18852
- },
18853
- errors: {
18854
- ...((_currentChanges$row$i3 = currentChanges[row.id]) === null || _currentChanges$row$i3 === void 0 ? void 0 : _currentChanges$row$i3._meta.errors)
18855
- }
19078
+ const tableMeta = table.options.meta;
19079
+ const index = (_tableMeta$rowActive$ = tableMeta.rowActive.rowActiveIndex) !== null && _tableMeta$rowActive$ !== void 0 ? _tableMeta$rowActive$ : 0;
19080
+ if (tableMeta.rowActive.rowActiveIndex === undefined) {
19081
+ tableMeta.rowActive.setRowActiveIndex(index);
18856
19082
  }
18857
- };
18858
- // run changes
18859
- const cells = row._getAllCellsByColumnId();
18860
- for (const [accessor, change] of Object.entries(changes)) {
18861
- // update if the change is different to the original (saved) value,
18862
- // otherwise remove any change - no point saving the same value
18863
- if (change !== row.original[accessor]) {
18864
- rowChanges[accessor] = change;
18865
- // consumers sometimes include properties in onEditingChange that aren't rendered as columns, we need to guard against that.
18866
- // eslint-disable-next-line no-prototype-builtins
18867
- if (cells.hasOwnProperty(accessor)) {
18868
- // determine if the row will move position based on this change, and save why it will move
18869
- const reason = willRowMove(cells[accessor], change, rowIndex, localization);
18870
- if (reason) {
18871
- rowChanges._meta.moveReason[accessor] = reason;
18872
- } else {
18873
- delete rowChanges._meta.moveReason[accessor];
18874
- }
18875
- }
18876
- } else {
18877
- delete rowChanges[accessor];
18878
- delete rowChanges._meta.moveReason[accessor];
19083
+ setEditing(enabled);
19084
+ if (!isTemporaryRow((_table$getRowModel$ro = table.getRowModel().rows[index]) === null || _table$getRowModel$ro === void 0 ? void 0 : _table$getRowModel$ro.id)) {
19085
+ scrollToIndex(index);
18879
19086
  }
18880
19087
  }
18881
- // set changes
18882
- // or delete if there are no changes left, so that we don't store changes with unchanged data
18883
- if (Object.keys(rowChanges).filter(k => k !== '_meta').length) {
18884
- nextChanges[row.id] = rowChanges;
18885
- } else {
18886
- delete nextChanges[row.id];
18887
- }
18888
- return nextChanges;
18889
- }
18890
- function getChangesetFromChanges(changes) {
18891
- // extract the original data from the row changes
18892
- const {
18893
- _meta,
18894
- ...changeset
18895
- } = changes !== null && changes !== void 0 ? changes : {};
18896
- // and mix them in with the changes, ready to send to the server
18897
19088
  return {
18898
- ...(_meta === null || _meta === void 0 ? void 0 : _meta.original),
18899
- ...changeset
19089
+ isEnabled,
19090
+ isEditing,
19091
+ isDetailedMode,
19092
+ toggleDetailedMode: isEnabled ? toggleDetailedMode : () => undefined,
19093
+ toggleEditing: isEnabled ? toggleEditing : () => undefined,
19094
+ lastFocusedCellIndex,
19095
+ setLastFocusedCellIndex,
19096
+ createRowButtonRef,
19097
+ ...pendingChangesFns
18900
19098
  };
18901
19099
  }
18902
19100
 
@@ -18940,7 +19138,6 @@ function RowMoveIndicator(props) {
18940
19138
  if (!show) {
18941
19139
  return null;
18942
19140
  }
18943
- 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';
18944
19141
  const {
18945
19142
  title,
18946
19143
  description
@@ -18949,7 +19146,7 @@ function RowMoveIndicator(props) {
18949
19146
  placement: "bottom",
18950
19147
  title: description.replace('[COLUMN]', columnMeta.header)
18951
19148
  }, /*#__PURE__*/React__default.createElement("span", {
18952
- className: className
19149
+ "data-row-move-indicator": true
18953
19150
  }, /*#__PURE__*/React__default.createElement(Icon, {
18954
19151
  name: "info",
18955
19152
  className: "-mt-0.5 mr-1 !h-4 !w-4 rounded-full bg-white !p-0 text-blue-500"
@@ -19138,13 +19335,31 @@ function EditingControlCell(props) {
19138
19335
  const {
19139
19336
  rowIndex
19140
19337
  } = React__default.useContext(RowContext);
19141
- const tableMeta = cell.getContext().table.options.meta;
19338
+ const {
19339
+ table
19340
+ } = cell.getContext();
19341
+ const tableMeta = table.options.meta;
19142
19342
  const columnMeta = cell.column.columnDef.meta;
19143
19343
  const isActiveRow = tableMeta.rowActive.rowActiveIndex === rowIndex;
19344
+ const type = (_columnMeta$control = columnMeta.control) !== null && _columnMeta$control !== void 0 ? _columnMeta$control : 'input';
19144
19345
  const handleFocus = useEditingCellAutofocus(props);
19346
+ const value = cell.getValue();
19347
+ // some controls, like select2, should trigger cell changed (validation, updates) as the value changes
19348
+ const hasNonTextControl = React__default.useMemo(() => {
19349
+ var _cellRef$current;
19350
+ 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"]'));
19351
+ }, [cellRef.current]);
19352
+ const handleChange = nextValue => {
19353
+ if (nextValue !== value) {
19354
+ tableMeta.editing.setCellValue(cell, nextValue);
19355
+ if (hasNonTextControl) {
19356
+ tableMeta.editing.onCellChanged(cell, rowIndex);
19357
+ }
19358
+ }
19359
+ };
19145
19360
  const handleBlur = () => {
19146
19361
  tableMeta.editing.toggleDetailedMode(false);
19147
- tableMeta.editing.validateCell(cell);
19362
+ tableMeta.editing.onCellChanged(cell, rowIndex, !hasNonTextControl);
19148
19363
  };
19149
19364
  // ensure that blur runs when the cell gets unmounted (when vertically arrow key navigating)
19150
19365
  React__default.useEffect(() => {
@@ -19164,14 +19379,13 @@ function EditingControlCell(props) {
19164
19379
  isDetailedMode: tableMeta.editing.isDetailedMode,
19165
19380
  isTruncated: !!columnMeta.enableTruncate,
19166
19381
  onBlur: handleBlur,
19167
- onChange: value => tableMeta.editing.setCellValue(cell, value, rowIndex),
19382
+ onChange: handleChange,
19168
19383
  row: cell.row.original,
19169
- rowPendingChanges: tableMeta.editing.getRowPendingChange(cell.row.id),
19384
+ rowPendingChanges: tableMeta.editing.getRowValue(cell.row.id),
19170
19385
  tabIndex: isActiveRow ? 0 : -1,
19171
- toggleEditing: tableMeta.editing.toggleEditing,
19172
19386
  toggleDetailedMode: tableMeta.editing.toggleDetailedMode,
19173
- type: (_columnMeta$control = columnMeta.control) !== null && _columnMeta$control !== void 0 ? _columnMeta$control : 'input',
19174
- value: cell.getValue()
19387
+ type,
19388
+ value
19175
19389
  };
19176
19390
  const cellAttributes = {
19177
19391
  ...getCellAttributes(cell, index, isHighlighted),
@@ -19203,7 +19417,6 @@ const MemoedEditingCell = /*#__PURE__*/React__default.memo(function MemoedEditin
19203
19417
  row,
19204
19418
  rowPendingChanges,
19205
19419
  tabIndex = -1,
19206
- toggleEditing,
19207
19420
  toggleDetailedMode,
19208
19421
  type = 'input',
19209
19422
  value
@@ -19234,6 +19447,13 @@ const MemoedEditingCell = /*#__PURE__*/React__default.memo(function MemoedEditin
19234
19447
  ref: controlRef
19235
19448
  }));
19236
19449
  }
19450
+ if (type === 'checkbox') {
19451
+ return /*#__PURE__*/React__default.createElement(Checkbox, Object.assign({}, commonProps, {
19452
+ checked: Boolean(value),
19453
+ onChange: onChange,
19454
+ ref: controlRef
19455
+ }));
19456
+ }
19237
19457
  const handleInputKeyDown = event => {
19238
19458
  const target = event.target;
19239
19459
  if (target.readOnly) {
@@ -19262,8 +19482,8 @@ const MemoedEditingCell = /*#__PURE__*/React__default.memo(function MemoedEditin
19262
19482
  }
19263
19483
  // reset the value, or exit edit mode when pressing escape
19264
19484
  if (event.key === 'Escape') {
19265
- event.preventDefault();
19266
19485
  if (isDetailedMode) {
19486
+ event.preventDefault();
19267
19487
  toggleDetailedMode(false);
19268
19488
  if (value !== currentValue) {
19269
19489
  props.onChange(currentValue);
@@ -19273,8 +19493,6 @@ const MemoedEditingCell = /*#__PURE__*/React__default.memo(function MemoedEditin
19273
19493
  var _target$select2;
19274
19494
  return (_target$select2 = target.select) === null || _target$select2 === void 0 ? void 0 : _target$select2.call(target);
19275
19495
  });
19276
- } else {
19277
- toggleEditing(false);
19278
19496
  }
19279
19497
  return;
19280
19498
  }
@@ -19373,12 +19591,37 @@ function Cell$5(props) {
19373
19591
  return /*#__PURE__*/React__default.createElement(DisplayCell, Object.assign({}, props));
19374
19592
  }
19375
19593
 
19594
+ function DiscardChangesConfirmationDialog(props) {
19595
+ const {
19596
+ onDiscard: handleDiscard,
19597
+ ...dialogProps
19598
+ } = props;
19599
+ const {
19600
+ texts
19601
+ } = useLocalization();
19602
+ const handleClickInsideDialogContent = event => {
19603
+ // Prevents the click event from propagating to the table, ensuring the row isn't saved when a click occurs
19604
+ // inside the dialog
19605
+ event.stopPropagation();
19606
+ };
19607
+ return /*#__PURE__*/React__default.createElement(Dialog, Object.assign({}, dialogProps), /*#__PURE__*/React__default.createElement(Dialog.Content, {
19608
+ "aria-label": texts.table3.editing.clearChangesConfirmationDialog.title,
19609
+ onClick: handleClickInsideDialogContent
19610
+ }, /*#__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, {
19611
+ tabIndex: 0
19612
+ }, texts.table3.editing.clearChangesConfirmationDialog.cancel)), /*#__PURE__*/React__default.createElement(Dialog.Close, null, /*#__PURE__*/React__default.createElement(Button$1, {
19613
+ autoFocus: true,
19614
+ tabIndex: 0,
19615
+ appearance: "primary",
19616
+ onClick: handleDiscard
19617
+ }, texts.table3.editing.clearChangesConfirmationDialog.confirm))))));
19618
+ }
19619
+
19376
19620
  function EditingActionMenu(props) {
19377
19621
  const {
19378
19622
  hasChanges,
19379
19623
  hasErrors,
19380
- onClear: handleClear,
19381
- onExit: handleExit,
19624
+ onDiscard: handleDiscard,
19382
19625
  onEditingSave: handleSave,
19383
19626
  isLastRow
19384
19627
  } = props;
@@ -19400,7 +19643,6 @@ function EditingActionMenu(props) {
19400
19643
  return /*#__PURE__*/React__default.createElement(IconButton, {
19401
19644
  appearance: "transparent",
19402
19645
  "aria-label": texts.table3.editing.actions.tooltip,
19403
- className: "group-[[data-row-editing-status]]/row:hidden",
19404
19646
  icon: "more",
19405
19647
  onKeyDown: handleKeyDown,
19406
19648
  menu: menuProps => (/*#__PURE__*/React__default.createElement(Menu$1, Object.assign({}, menuProps), /*#__PURE__*/React__default.createElement(Menu$1.Content, {
@@ -19412,42 +19654,13 @@ function EditingActionMenu(props) {
19412
19654
  }, texts.table3.editing.actions.save), /*#__PURE__*/React__default.createElement(Menu$1.Item, {
19413
19655
  icon: "close",
19414
19656
  disabled: !hasChanges,
19415
- dialog: props => /*#__PURE__*/React__default.createElement(ConfirmClearChangesDialog, Object.assign({}, props, {
19416
- onClear: handleClear
19657
+ dialog: props => /*#__PURE__*/React__default.createElement(DiscardChangesConfirmationDialog, Object.assign({}, props, {
19658
+ onDiscard: handleDiscard
19417
19659
  }))
19418
- }, texts.table3.editing.actions.clear), /*#__PURE__*/React__default.createElement(Menu$1.Item, {
19419
- icon: "undo",
19420
- onClick: handleExit
19421
- }, texts.table3.editing.actions.exit))))
19660
+ }, texts.table3.editing.actions.clear))))
19422
19661
  });
19423
19662
  }
19424
- function ConfirmClearChangesDialog(props) {
19425
- const {
19426
- onClear: handleClear,
19427
- ...dialogProps
19428
- } = props;
19429
- const {
19430
- texts
19431
- } = useLocalization();
19432
- const handleClickInsideDialogContent = event => {
19433
- // Prevents the click event from propagating to the table, ensuring the row isn't saved when a click occurs
19434
- // inside the dialog
19435
- event.stopPropagation();
19436
- };
19437
- return /*#__PURE__*/React__default.createElement(Dialog, Object.assign({}, dialogProps), /*#__PURE__*/React__default.createElement(Dialog.Content, {
19438
- "aria-label": texts.table3.editing.clearChangesConfirmationDialog.title,
19439
- onClick: handleClickInsideDialogContent
19440
- }, /*#__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, {
19441
- tabIndex: 0
19442
- }, texts.table3.editing.clearChangesConfirmationDialog.cancel)), /*#__PURE__*/React__default.createElement(Dialog.Close, null, /*#__PURE__*/React__default.createElement(Button$1, {
19443
- autoFocus: true,
19444
- tabIndex: 0,
19445
- appearance: "primary",
19446
- onClick: handleClear
19447
- }, texts.table3.editing.clearChangesConfirmationDialog.confirm))))));
19448
- }
19449
19663
 
19450
- const COMPLETE_INDICATOR_DELAY = 3000;
19451
19664
  function SaveStatus(props) {
19452
19665
  const {
19453
19666
  rowId,
@@ -19457,18 +19670,7 @@ function SaveStatus(props) {
19457
19670
  texts
19458
19671
  } = useLocalization();
19459
19672
  const tableMeta = table.options.meta;
19460
- const status = tableMeta.editing.getRowSaveStatus(rowId);
19461
- React__default.useEffect(() => {
19462
- let timeout;
19463
- if (status === 'complete') {
19464
- timeout = window.setTimeout(() => {
19465
- tableMeta.editing.setRowSaveStatus(rowId, undefined);
19466
- }, COMPLETE_INDICATOR_DELAY);
19467
- }
19468
- return () => {
19469
- clearTimeout(timeout);
19470
- };
19471
- }, [status]);
19673
+ const status = tableMeta.editing.getRowStatus(rowId);
19472
19674
  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)]', {
19473
19675
  'mt-0.5': tableMeta.rowHeight.height === 'short',
19474
19676
  'mt-1': tableMeta.rowHeight.height === 'medium',
@@ -19479,7 +19681,7 @@ function SaveStatus(props) {
19479
19681
  className: "!contents"
19480
19682
  }, /*#__PURE__*/React__default.createElement("span", {
19481
19683
  className: className
19482
- }, status === 'pending' ? (/*#__PURE__*/React__default.createElement(Tooltip, {
19684
+ }, status === 'saving' ? (/*#__PURE__*/React__default.createElement(Tooltip, {
19483
19685
  title: texts.table3.editing.saving.progress
19484
19686
  }, /*#__PURE__*/React__default.createElement(Spinner, {
19485
19687
  delay: 0,
@@ -19520,15 +19722,46 @@ function Row$2(props) {
19520
19722
  }
19521
19723
  }
19522
19724
  }, [tableMeta.editing.isEditing, isActiveRow]);
19725
+ const rowStatus = tableMeta.editing.getRowStatus(row.id);
19726
+ // discard new row
19727
+ const [showDiscardDialog, setShowDiscardDialog] = React__default.useState(false);
19728
+ function handleDiscard() {
19729
+ tableMeta.editing.discardChanges(row.id, table);
19730
+ requestAnimationFrame(() => {
19731
+ if (isTemporaryRow(row.id)) {
19732
+ var _tableMeta$editing$cr;
19733
+ (_tableMeta$editing$cr = tableMeta.editing.createRowButtonRef.current) === null || _tableMeta$editing$cr === void 0 ? void 0 : _tableMeta$editing$cr.focus();
19734
+ } else {
19735
+ focusManager.focusFirst();
19736
+ }
19737
+ });
19738
+ }
19739
+ function handleKeyDown(event) {
19740
+ if (props.onKeyDown) {
19741
+ props.onKeyDown(event);
19742
+ }
19743
+ if (event.isDefaultPrevented() || event.isPropagationStopped()) {
19744
+ return;
19745
+ }
19746
+ if (event.key === 'Escape' && tableMeta.editing.hasChanges(row.id) && !isElementTriggeredFromContainer(event.target, event.currentTarget)) {
19747
+ event.preventDefault();
19748
+ setShowDiscardDialog(true);
19749
+ }
19750
+ }
19523
19751
  const attributes = {
19524
- 'data-row-editing-invalid': tableMeta.editing.isEnabled && tableMeta.editing.hasRowErrors(row.id) ? !tableMeta.editing.hasRowErrorsSeen(row.id) ? 'unseen' : true : undefined,
19525
- 'data-row-editing-status': tableMeta.editing.isEnabled && tableMeta.editing.getRowSaveStatus(row.id) ? tableMeta.editing.getRowSaveStatus(row.id) : undefined,
19526
- onFocus: handleFocus
19752
+ 'data-row-editing-invalid': tableMeta.editing.hasRowErrors(row.id) ? !tableMeta.editing.hasRowErrorsShownInAlert(row.id) ? 'unseen' : true : undefined,
19753
+ 'data-row-editing-status': rowStatus,
19754
+ onFocus: handleFocus,
19755
+ onKeyDown: handleKeyDown
19527
19756
  };
19528
- return /*#__PURE__*/React__default.createElement(DisplayRow, Object.assign({}, props, attributes), tableMeta.editing.getRowSaveStatus(row.id) ? /*#__PURE__*/React__default.createElement(SaveStatus, {
19757
+ 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, {
19529
19758
  rowId: row.id,
19530
19759
  table: table
19531
- }) : null);
19760
+ }) : null), /*#__PURE__*/React__default.createElement(DiscardChangesConfirmationDialog, {
19761
+ open: showDiscardDialog,
19762
+ onChange: setShowDiscardDialog,
19763
+ onDiscard: handleDiscard
19764
+ }));
19532
19765
  }
19533
19766
 
19534
19767
  const RENDERERS$1 = {
@@ -19536,29 +19769,50 @@ const RENDERERS$1 = {
19536
19769
  cell: Cell$5
19537
19770
  };
19538
19771
  function useTable3(props, ref) {
19539
- const editing = useTableEditing(props.enableEditing, props.onEditingSave, props.onEditingChange, props.validator);
19772
+ const editing = useTableEditing(props.enableEditing, props.onEditingSave, props.onEditingChange, props.rowIdentityAccessor, props.validator);
19540
19773
  const creationEnabled = editing.isEnabled && !!props.onEditingCreate;
19774
+ // this gives me the performance heeby jeebies, but can't think of a better way to internalise the state
19775
+ const data = React__default.useMemo(() => {
19776
+ if (editing.temporaryRows.length) {
19777
+ var _props$data;
19778
+ return ((_props$data = props.data) !== null && _props$data !== void 0 ? _props$data : []).concat(editing.temporaryRows);
19779
+ }
19780
+ return props.data;
19781
+ }, [JSON.stringify(props.data), editing.temporaryRows.length]);
19541
19782
  const extendedProps = {
19542
19783
  ...props,
19784
+ data,
19543
19785
  enableRowActions: editing.isEditing ? true : props.enableRowActions,
19544
- rowActions: editing.isEditing ? [(_, rowId) => (/*#__PURE__*/React__default.createElement(EditingActionMenu, {
19545
- hasChanges: editing.hasChanges(rowId),
19546
- hasErrors: editing.hasRowErrors(rowId),
19547
- onClear: () => editing.resetChanges(rowId),
19548
- onEditingSave: () => editing.saveChanges(rowId),
19549
- onExit: () => editing.toggleEditing(false),
19550
- isLastRow: !creationEnabled && table.meta.rowActive.rowActiveIndex === table.meta.length - 1
19551
- }))] : props.rowActions
19786
+ // Display EditingActionMenu instead of row actions while editing
19787
+ rowActions: editing.isEditing ? [(_, rowId, table) => {
19788
+ const tableMeta = table.options.meta;
19789
+ return /*#__PURE__*/React__default.createElement(EditingActionMenu, {
19790
+ hasChanges: editing.hasChanges(rowId),
19791
+ hasErrors: editing.hasRowErrors(rowId),
19792
+ onDiscard: () => editing.discardChanges(rowId, table),
19793
+ onEditingSave: function () {
19794
+ try {
19795
+ return Promise.resolve(editing.saveChanges(table, rowId)).then(function () {});
19796
+ } catch (e) {
19797
+ return Promise.reject(e);
19798
+ }
19799
+ },
19800
+ isLastRow: !creationEnabled && tableMeta.rowActive.rowActiveIndex === tableMeta.length - 1
19801
+ });
19802
+ }] : props.rowActions
19552
19803
  };
19553
19804
  const meta = {
19554
19805
  editing
19555
19806
  };
19556
- const table = useTable(extendedProps, ref, RENDERERS$1, meta);
19807
+ const options = {
19808
+ virtualiserPaddingEndOffset: props.enableEditing && props.onEditingCreate ? editing.hasTemporaryRowErrors() ? 1.4 : 1 : 0
19809
+ };
19810
+ const table = useTable(extendedProps, ref, RENDERERS$1, meta, options);
19557
19811
  // listeners
19558
- useTableEditingListener(table.instance, table.ref);
19812
+ useTableEditingListener(table.instance, table.ref, table.renderer.scrollToIndex);
19559
19813
  React__default.useEffect(() => {
19560
19814
  if (table.ref.current) {
19561
- table.ref.current.instance.toggleEditing = enabled => table.meta.editing.toggleEditing(enabled !== null && enabled !== void 0 ? enabled : editing => !editing);
19815
+ table.ref.current.instance.toggleEditing = enabled => table.meta.editing.toggleEditing(enabled !== null && enabled !== void 0 ? enabled : editing => !editing, table.instance, table.renderer.scrollToIndex);
19562
19816
  }
19563
19817
  }, [table.ref.current]);
19564
19818
  return table;
@@ -19577,7 +19831,7 @@ function Alert$1(props) {
19577
19831
  const validationTexts = texts.table3.editing.validation;
19578
19832
  const tableMeta = table.options.meta;
19579
19833
  const [showFilterResetDialog, setShowFilterResetDialog] = React__default.useState(false);
19580
- const pendingChangesWithErrors = tableMeta.editing.getAlertErrors();
19834
+ const pendingChangesWithErrors = tableMeta.editing.getErrorsShownInAlert();
19581
19835
  function scrollToRow(rowIndex) {
19582
19836
  tableMeta.rowActive.setRowActiveIndex(rowIndex);
19583
19837
  scrollToIndex(rowIndex, {
@@ -19596,38 +19850,43 @@ function Alert$1(props) {
19596
19850
  const title = (pendingChangesWithErrors.length === 1 ? validationTexts.alert.titleOne : validationTexts.alert.titlePlural).replace('[COUNT]', String(pendingChangesWithErrors.length));
19597
19851
  // generate links to each invalid row, to go into the error message
19598
19852
  const links = [];
19599
- const rowIdentityColumn = tableMeta.rowIdentityColumnId ? table.getColumn(tableMeta.rowIdentityColumnId) : undefined;
19600
- pendingChangesWithErrors.forEach((error, index) => {
19853
+ const visibleColumns = table.getVisibleFlatColumns().map(c => c.id);
19854
+ const rowIdentityColumn = tableMeta.rowIdentityAccessor && visibleColumns.includes(String(tableMeta.rowIdentityAccessor)) ? table.getColumn(String(tableMeta.rowIdentityAccessor)) : undefined;
19855
+ pendingChangesWithErrors.forEach((pendingChangeWithError, index) => {
19601
19856
  // if appropriate, concatenate the item with the text "and"
19602
19857
  if (pendingChangesWithErrors.length > 1 && index === pendingChangesWithErrors.length - 1) {
19603
19858
  // Add space before and after `messageAnd` text
19604
19859
  links.push(` ${validationTexts.alert.messageAnd} `);
19605
19860
  }
19606
- const rowIndex = table.getRowModel().rows.findIndex(row => row.id === error.rowId);
19861
+ const rowIndex = table.getRowModel().rows.findIndex(row => row.id === pendingChangeWithError.rowId);
19607
19862
  const handleClick = () => {
19863
+ // if row is visible
19608
19864
  if (rowIndex > -1) {
19609
19865
  scrollToRow(rowIndex);
19610
- } else {
19611
- setShowFilterResetDialog(error.rowId);
19866
+ }
19867
+ // if row is filtered out
19868
+ else {
19869
+ setShowFilterResetDialog(pendingChangeWithError.rowId);
19612
19870
  }
19613
19871
  };
19614
19872
  let tooltip;
19615
- if (error.pendingChange._meta.errors.row) {
19616
- tooltip = error.pendingChange._meta.errors.row;
19873
+ if (pendingChangeWithError.errors.row) {
19874
+ tooltip = pendingChangeWithError.errors.row;
19617
19875
  } else {
19618
19876
  var _table$getAllColumns$, _table$getAllColumns$2;
19619
- const firstCellErrorColumnId = Object.keys(error.pendingChange._meta.errors.cells)[0];
19877
+ const firstCellErrorColumnId = Object.keys(pendingChangeWithError.errors.cells)[0];
19620
19878
  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;
19621
- tooltip = `${columnName}: ${error.pendingChange._meta.errors.cells[firstCellErrorColumnId]}`;
19879
+ tooltip = `${columnName}: ${pendingChangeWithError.errors.cells[firstCellErrorColumnId]}`;
19622
19880
  }
19881
+ const row = table.getRow(pendingChangeWithError.rowId).original;
19623
19882
  links.push(/*#__PURE__*/React__default.createElement(Tooltip, {
19624
- key: error.rowId,
19883
+ key: pendingChangeWithError.rowId,
19625
19884
  title: tooltip
19626
19885
  }, /*#__PURE__*/React__default.createElement("span", {
19627
19886
  className: "text-blue",
19628
19887
  onClick: handleClick,
19629
19888
  role: "button"
19630
- }, rowIdentityColumn ? error.pendingChange._meta.original[rowIdentityColumn.id] : rowIndex + 1)));
19889
+ }, rowIdentityColumn ? row[rowIdentityColumn.id] : rowIndex + 1)));
19631
19890
  // if appropriate, concatenate the item with the text ","
19632
19891
  if (pendingChangesWithErrors.length > 2 && index < pendingChangesWithErrors.length - 2) {
19633
19892
  links.push(', ');
@@ -19683,127 +19942,212 @@ function FilterResetDialog(props) {
19683
19942
  }, texts.table3.editing.validation.resetFiltersDialog.confirm)))));
19684
19943
  }
19685
19944
 
19686
- function CreateNewRowButton(props) {
19945
+ function Editing(props) {
19687
19946
  const {
19688
- onEditingCreate,
19689
19947
  scrollToIndex,
19690
- table,
19691
- tableMeta
19948
+ table
19692
19949
  } = props;
19693
19950
  const {
19694
19951
  texts
19695
19952
  } = useLocalization();
19696
- const rows = table.getCoreRowModel().rows.filter(row => row.original !== undefined);
19697
- const [rowCreated, setRowCreated] = React__default.useState({
19698
- rowFinder: undefined
19699
- });
19700
- const handleKeyDown = event => {
19701
- if (!tableMeta.editing.hasChanges() && event.key === 'Tab') {
19702
- tableMeta.editing.saveChanges();
19703
- }
19953
+ const ref = React__default.useRef(null);
19954
+ const tableMeta = table.options.meta;
19955
+ const handleChange = enabled => {
19956
+ tableMeta.editing.toggleEditing(enabled, table, scrollToIndex);
19704
19957
  };
19705
- const handleCreate = function () {
19958
+ const tooltip = /*#__PURE__*/React__default.createElement(React__default.Fragment, null, texts.table3.editing.buttons.edit.tooltip, /*#__PURE__*/React__default.createElement(Shortcut, {
19959
+ className: "ml-2",
19960
+ keys: shortcut
19961
+ }));
19962
+ return /*#__PURE__*/React__default.createElement(Tooltip, {
19963
+ title: tooltip
19964
+ }, /*#__PURE__*/React__default.createElement(ModeSwitch, {
19965
+ "data-table": "editing-toggle",
19966
+ checked: tableMeta.editing.isEditing,
19967
+ onChange: handleChange,
19968
+ ref: ref
19969
+ }));
19970
+ }
19971
+
19972
+ function CreateNewRow(props) {
19973
+ var _temporaryRows$0$tabl, _temporaryRows$, _table$getState$colum;
19974
+ const {
19975
+ buttonRef,
19976
+ onEditingCreate: handleEditingCreate,
19977
+ scrollToIndex,
19978
+ table,
19979
+ tableMeta,
19980
+ tableRef
19981
+ } = props;
19982
+ const {
19983
+ texts
19984
+ } = useLocalization();
19985
+ const temporaryRows = tableMeta.editing.temporaryRows;
19986
+ 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 : '';
19987
+ 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);
19988
+ const isSaving = !!temporaryRowId && tableMeta.editing.getRowStatus(temporaryRowId) === 'saving';
19989
+ const createRow = function (row) {
19706
19990
  try {
19707
- if (!onEditingCreate) {
19991
+ if (!handleEditingCreate || isDisabled) {
19708
19992
  return Promise.resolve();
19709
19993
  }
19710
- const createdRow = rows.find(row => {
19711
- var _rowCreated$rowFinder;
19712
- 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);
19713
- });
19714
- const _temp = function () {
19715
- if (createdRow) {
19716
- return Promise.resolve(tableMeta.editing.saveChanges()).then(function () {
19717
- if (!tableMeta.editing.hasRowErrors(createdRow.id)) {
19718
- const rowFinder = onEditingCreate();
19719
- setRowCreated({
19720
- rowFinder
19721
- });
19722
- }
19723
- });
19724
- } else {
19725
- const rowFinder = onEditingCreate();
19726
- setRowCreated({
19727
- rowFinder
19728
- });
19994
+ return Promise.resolve(tableMeta.editing.saveChanges(table)).then(function (saved) {
19995
+ if (!saved) {
19996
+ return;
19729
19997
  }
19730
- }();
19731
- return Promise.resolve(_temp && _temp.then ? _temp.then(function () {}) : void 0);
19998
+ const changeset = row !== null && row !== void 0 ? row : handleEditingCreate();
19999
+ try {
20000
+ if (changeset) {
20001
+ const rowId = tableMeta.editing.createRow(changeset);
20002
+ table.getRow(rowId).pin('bottom');
20003
+ // set the active row to the new row before toggling editing on
20004
+ const nextRowIndex = temporaryRows.length ? tableMeta.length + 1 : tableMeta.length;
20005
+ tableMeta.rowActive.setRowActiveIndex(nextRowIndex);
20006
+ tableMeta.editing.toggleEditing(true, table, scrollToIndex);
20007
+ tableMeta.editing.setLastFocusedCellIndex(0);
20008
+ }
20009
+ } catch (error) {
20010
+ console.error(error);
20011
+ }
20012
+ });
19732
20013
  } catch (e) {
19733
20014
  return Promise.reject(e);
19734
20015
  }
19735
20016
  };
20017
+ // allow programmatic access to creating rows from outside the table
19736
20018
  React__default.useEffect(() => {
19737
- if (typeof (rowCreated === null || rowCreated === void 0 ? void 0 : rowCreated.rowFinder) === 'function') {
19738
- const createdRow = rows.find(row => {
19739
- var _rowCreated$rowFinder2;
19740
- 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);
19741
- });
19742
- if (createdRow) {
19743
- const rowInTable = table.getRowModel().rows.filter(row => row.original !== undefined).find(row => {
19744
- var _rowCreated$rowFinder3;
19745
- 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);
19746
- });
19747
- if (rowInTable) {
19748
- tableMeta.editing.toggleEditing(true);
19749
- tableMeta.rowActive.setRowActiveIndex(createdRow.index);
19750
- scrollToIndex(createdRow.index);
19751
- requestAnimationFrame(() => animateCreateRow(createdRow.id));
19752
- }
19753
- requestAnimationFrame(() => tableMeta.editing.addCreatedRowChangeset(createdRow));
19754
- }
20019
+ if (tableRef.current) {
20020
+ tableRef.current.instance.createRow = createRow;
19755
20021
  }
19756
- }, [rowCreated]);
20022
+ }, [tableRef.current, createRow]);
20023
+ const handleCreate = function () {
20024
+ return createRow();
20025
+ };
20026
+ const shortcut = {
20027
+ key: 'Enter',
20028
+ shift: true
20029
+ };
20030
+ let tooltip;
20031
+ if (isSaving) {
20032
+ tooltip = texts.table3.editing.buttons.create.saving;
20033
+ } else if (isDisabled) {
20034
+ tooltip = texts.table3.editing.buttons.create.disabled;
20035
+ } else {
20036
+ tooltip = /*#__PURE__*/React__default.createElement(Shortcut, {
20037
+ keys: shortcut
20038
+ });
20039
+ }
20040
+ const isScrolled = tableRef.current ? tableRef.current.scrollHeight > tableRef.current.clientHeight : false;
20041
+ const className = cn('group/row border-grey-300 !sticky z-[21]', {
20042
+ 'bottom-10': tableMeta.footer.isEnabled,
20043
+ 'bottom-0': !tableMeta.footer.isEnabled,
20044
+ 'border-t-2': isScrolled,
20045
+ 'border-b': !isScrolled
20046
+ });
19757
20047
  return /*#__PURE__*/React__default.createElement("tr", {
19758
- onClick: handleCreate,
19759
- className: "border-grey-300 hover:bg-grey-100 group !sticky bottom-10 left-0 z-[21] !block cursor-pointer border-t"
20048
+ "data-row-create": true,
20049
+ className: className,
20050
+ tabIndex: -1
19760
20051
  }, /*#__PURE__*/React__default.createElement("td", {
19761
- className: "!border-t-0 !bg-transparent"
20052
+ className: "!bg-grey-50 col-span-full !border-b-0 !px-1"
19762
20053
  }, /*#__PURE__*/React__default.createElement(Button$1, {
19763
- onKeyDown: handleKeyDown,
19764
- className: "group-hover:bg-grey-200 sticky left-0",
19765
- appearance: "transparent"
19766
- }, "+ ", texts.table3.editing.buttons.create.label)));
20054
+ appearance: "transparent",
20055
+ className: "group-hover:bg-grey-200 sticky left-[4px]",
20056
+ disabled: isDisabled,
20057
+ onClick: handleCreate,
20058
+ ref: buttonRef,
20059
+ shortcut: shortcut,
20060
+ tooltip: tooltip
20061
+ }, /*#__PURE__*/React__default.createElement(Icon, {
20062
+ name: "circle-plus"
20063
+ }), texts.table3.editing.buttons.create.label)));
19767
20064
  }
19768
20065
 
19769
- function Editing(props) {
20066
+ function TemporaryRow(props) {
19770
20067
  const {
19771
- scrollToIndex,
19772
- table
20068
+ createRowButtonRef,
20069
+ table,
20070
+ tableMeta,
20071
+ tableRef
19773
20072
  } = props;
19774
- const {
19775
- texts
19776
- } = useLocalization();
19777
- const ref = React__default.useRef(null);
19778
- const tableMeta = table.options.meta;
19779
- const shortcut = {
19780
- key: 'e',
19781
- meta: true,
19782
- shift: false
20073
+ const handleKeyDown = function (event) {
20074
+ try {
20075
+ const _temp2 = function () {
20076
+ if (event.key === 'ArrowDown') {
20077
+ event.preventDefault();
20078
+ const _temp = function () {
20079
+ if (!isElementTriggeredFromContainer(event.target, event.currentTarget)) {
20080
+ return Promise.resolve(tableMeta.editing.saveChanges(table)).then(function (saved) {
20081
+ if (saved) {
20082
+ var _createRowButtonRef$c;
20083
+ (_createRowButtonRef$c = createRowButtonRef.current) === null || _createRowButtonRef$c === void 0 ? void 0 : _createRowButtonRef$c.focus();
20084
+ }
20085
+ });
20086
+ }
20087
+ }();
20088
+ if (_temp && _temp.then) return _temp.then(function () {});
20089
+ } else if (event.key === 'ArrowUp') {
20090
+ event.preventDefault();
20091
+ event.stopPropagation();
20092
+ if (tableRef.current) {
20093
+ var _tableRef$current$que, _tableRef$current$que2, _tableRef$current$que3;
20094
+ 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 : []);
20095
+ 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;
20096
+ const newRowHeight = event.currentTarget.getBoundingClientRect().height;
20097
+ const visibleHeight = tableRef.current.clientHeight - footerHeight - newRowHeight;
20098
+ const tableTopOffset = tableRef.current.getBoundingClientRect().top;
20099
+ let nextRowIndex;
20100
+ // iterate available rows in reverse order, since we're working at the bottom
20101
+ for (let index = availableRows.length - 1; index >= 0; index--) {
20102
+ const rowRect = availableRows[index].getBoundingClientRect();
20103
+ const topPlusHalfRow = rowRect.top + rowRect.height / 2;
20104
+ if (topPlusHalfRow - tableTopOffset <= visibleHeight) {
20105
+ nextRowIndex = index;
20106
+ break;
20107
+ }
20108
+ }
20109
+ if (nextRowIndex) {
20110
+ tableMeta.rowActive.setRowActiveIndex(Number(availableRows[nextRowIndex < 0 ? 0 : nextRowIndex].getAttribute('data-row-index')));
20111
+ }
20112
+ }
20113
+ }
20114
+ }();
20115
+ return Promise.resolve(_temp2 && _temp2.then ? _temp2.then(function () {}) : void 0);
20116
+ } catch (e) {
20117
+ return Promise.reject(e);
20118
+ }
19783
20119
  };
19784
- const tooltip = /*#__PURE__*/React__default.createElement(React__default.Fragment, null, texts.table3.editing.buttons.edit.tooltip, /*#__PURE__*/React__default.createElement(Shortcut, {
19785
- className: "ml-2",
19786
- keys: shortcut
19787
- }));
19788
- useGlobalKeyDown(shortcut, event => {
19789
- var _ref$current;
19790
- event.preventDefault();
19791
- (_ref$current = ref.current) === null || _ref$current === void 0 ? void 0 : _ref$current.click();
19792
- });
19793
- const handleChange = enabled => {
19794
- tableMeta.editing.toggleEditing(enabled);
19795
- requestAnimationFrame(() => {
19796
- var _tableMeta$rowActive$;
19797
- return scrollToIndex((_tableMeta$rowActive$ = tableMeta.rowActive.rowActiveIndex) !== null && _tableMeta$rowActive$ !== void 0 ? _tableMeta$rowActive$ : 0);
19798
- });
20120
+ const handleKeyDownCapture = event => {
20121
+ if (event.key === 'ArrowLeft' && tableMeta.editing.lastFocusedCellIndex === 0) {
20122
+ event.preventDefault();
20123
+ event.stopPropagation();
20124
+ } else if (event.key === 'ArrowRight' && tableMeta.editing.lastFocusedCellIndex) {
20125
+ if (tableMeta.editing.lastFocusedCellIndex === table.getVisibleFlatColumns().length - 1) {
20126
+ event.preventDefault();
20127
+ event.stopPropagation();
20128
+ }
20129
+ }
19799
20130
  };
19800
- return /*#__PURE__*/React__default.createElement(Tooltip, {
19801
- title: tooltip
19802
- }, /*#__PURE__*/React__default.createElement(ModeSwitch, {
19803
- checked: tableMeta.editing.isEditing,
19804
- onChange: handleChange,
19805
- ref: ref
19806
- }));
20131
+ const isScrolled = tableRef.current ? tableRef.current.scrollHeight > tableRef.current.clientHeight : false;
20132
+ const className = cn('group/row border-grey-300 !sticky z-[22]', {
20133
+ 'bottom-[calc(5rem_+_3px)] data-[row-editing-move]:bottom-[calc(5rem_+_2px)]': tableMeta.footer.isEnabled,
20134
+ 'bottom-[calc(2.5rem_+_3px)] data-[row-editing-move]:bottom-[calc(2.5rem_+_2px)]': !tableMeta.footer.isEnabled,
20135
+ 'border-t-2 shadow-[0px_-5px_20px_0px_rgba(0,0,0,0.1)] [&>td]:!border-b-0': isScrolled
20136
+ });
20137
+ return /*#__PURE__*/React__default.createElement(React__default.Fragment, null, table.getBottomRows().map(row => (/*#__PURE__*/React__default.createElement(Row, {
20138
+ key: row.id,
20139
+ cellRenderer: RENDERERS$1.cell,
20140
+ index: tableMeta.length,
20141
+ measureRow: () => null,
20142
+ renderer: RENDERERS$1.row,
20143
+ row: row,
20144
+ table: table,
20145
+ className: className,
20146
+ onKeyDown: handleKeyDown,
20147
+ onKeyDownCapture: handleKeyDownCapture,
20148
+ // Row actions should only be hidden on temporary rows when editing is turned off
20149
+ hideRowActions: !tableMeta.editing.isEditing
20150
+ }))));
19807
20151
  }
19808
20152
 
19809
20153
  function Column$3(_) {
@@ -19821,8 +20165,8 @@ const BaseTable3 = /*#__PURE__*/fixedForwardRef(function BaseTable3(props, ref)
19821
20165
  '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,
19822
20166
  enableHorizontalArrowKeyNavigation: table3.meta.editing.isEditing
19823
20167
  };
19824
- const hasAlertErrors = table3.meta.editing.hasAlertErrors();
19825
- const showCreateRowButton = table3.meta.editing.isEnabled && props.onEditingCreate;
20168
+ const hasAlertErrors = table3.meta.editing.getErrorsShownInAlert().length;
20169
+ const hasCreateWorkflow = table3.meta.editing.isEnabled && props.onEditingCreate;
19826
20170
  return /*#__PURE__*/React__default.createElement(Table, null, /*#__PURE__*/React__default.createElement(Table.Toolbar, {
19827
20171
  table: table3
19828
20172
  }, table3.meta.editing.isEnabled ? (/*#__PURE__*/React__default.createElement(Editing, {
@@ -19836,12 +20180,19 @@ const BaseTable3 = /*#__PURE__*/fixedForwardRef(function BaseTable3(props, ref)
19836
20180
  })) : null, /*#__PURE__*/React__default.createElement(Table.Grid, Object.assign({}, gridAttributes, {
19837
20181
  "data-taco": "table3",
19838
20182
  table: table3
19839
- }), showCreateRowButton && (/*#__PURE__*/React__default.createElement(CreateNewRowButton, {
20183
+ }), hasCreateWorkflow ? (/*#__PURE__*/React__default.createElement(React__default.Fragment, null, /*#__PURE__*/React__default.createElement(TemporaryRow, {
20184
+ createRowButtonRef: table3.meta.editing.createRowButtonRef,
19840
20185
  table: table3.instance,
19841
20186
  tableMeta: table3.meta,
20187
+ tableRef: table3.ref
20188
+ }), /*#__PURE__*/React__default.createElement(CreateNewRow, {
20189
+ buttonRef: table3.meta.editing.createRowButtonRef,
19842
20190
  onEditingCreate: props.onEditingCreate,
19843
- scrollToIndex: table3.renderer.scrollToIndex
19844
- }))));
20191
+ scrollToIndex: table3.renderer.scrollToIndex,
20192
+ table: table3.instance,
20193
+ tableMeta: table3.meta,
20194
+ tableRef: table3.ref
20195
+ }))) : null));
19845
20196
  });
19846
20197
  const Table3 = /*#__PURE__*/fixedForwardRef(function Table3(props, ref) {
19847
20198
  const stringifiedChildren = String(props.children);