@economic/taco 2.14.2 → 2.16.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (117) hide show
  1. package/dist/components/Drawer/Drawer.d.ts +5 -1
  2. package/dist/components/Icon/components/AiChatSolid.d.ts +3 -0
  3. package/dist/components/Icon/components/AiStars.d.ts +3 -0
  4. package/dist/components/Icon/components/EnvelopeSolid.d.ts +3 -0
  5. package/dist/components/Icon/components/PhoneSolid.d.ts +3 -0
  6. package/dist/components/Icon/components/QuestionMarkBold.d.ts +3 -0
  7. package/dist/components/Icon/components/index.d.ts +1 -1
  8. package/dist/components/Input/Input.d.ts +1 -1
  9. package/dist/components/Menu/components/Item.d.ts +1 -1
  10. package/dist/components/Menu/components/Link.d.ts +1 -1
  11. package/dist/components/Navigation2/components/Link.d.ts +1 -1
  12. package/dist/components/Provider/Localization.d.ts +19 -0
  13. package/dist/components/SearchInput2/SearchInput2.d.ts +1 -0
  14. package/dist/components/Select2/components/Option.d.ts +2 -2
  15. package/dist/components/Select2/components/Search.d.ts +1 -1
  16. package/dist/components/Table3/components/alert/ErrorAlert.d.ts +10 -0
  17. package/dist/components/Table3/components/columns/cell/DisplayCell.d.ts +5 -2
  18. package/dist/components/Table3/components/columns/cell/EditingCell.d.ts +3 -0
  19. package/dist/components/Table3/components/columns/cell/Highlight.d.ts +2 -0
  20. package/dist/components/Table3/components/columns/internal/EditingActions.d.ts +1 -1
  21. package/dist/components/Table3/components/rows/Row.d.ts +2 -0
  22. package/dist/components/Table3/components/rows/RowContext.d.ts +1 -0
  23. package/dist/components/Table3/hooks/features/useEditing.d.ts +12 -11
  24. package/dist/components/Table3/hooks/features/usePauseShortcuts.d.ts +5 -0
  25. package/dist/components/Table3/hooks/features/useSearch.d.ts +2 -0
  26. package/dist/components/Table3/hooks/features/useValidation.d.ts +13 -0
  27. package/dist/components/Table3/hooks/useTable.d.ts +4 -0
  28. package/dist/components/Table3/types.d.ts +26 -1
  29. package/dist/components/Table3/util/editing.d.ts +6 -0
  30. package/dist/components/Tag/Tag.d.ts +1 -1
  31. package/dist/components/Tooltip/Tooltip.d.ts +4 -0
  32. package/dist/esm/index.css +112 -33
  33. package/dist/esm/packages/taco/src/components/Drawer/Drawer.js +7 -2
  34. package/dist/esm/packages/taco/src/components/Drawer/Drawer.js.map +1 -1
  35. package/dist/esm/packages/taco/src/components/Field/Field.js +19 -3
  36. package/dist/esm/packages/taco/src/components/Field/Field.js.map +1 -1
  37. package/dist/esm/packages/taco/src/components/Icon/components/AiChatSolid.js +19 -0
  38. package/dist/esm/packages/taco/src/components/Icon/components/AiChatSolid.js.map +1 -0
  39. package/dist/esm/packages/taco/src/components/Icon/components/AiStars.js +30 -0
  40. package/dist/esm/packages/taco/src/components/Icon/components/AiStars.js.map +1 -0
  41. package/dist/esm/packages/taco/src/components/Icon/components/EnvelopeSolid.js +19 -0
  42. package/dist/esm/packages/taco/src/components/Icon/components/EnvelopeSolid.js.map +1 -0
  43. package/dist/esm/packages/taco/src/components/Icon/components/PhoneSolid.js +17 -0
  44. package/dist/esm/packages/taco/src/components/Icon/components/PhoneSolid.js.map +1 -0
  45. package/dist/esm/packages/taco/src/components/Icon/components/QuestionMarkBold.js +17 -0
  46. package/dist/esm/packages/taco/src/components/Icon/components/QuestionMarkBold.js.map +1 -0
  47. package/dist/esm/packages/taco/src/components/Icon/components/index.js +10 -0
  48. package/dist/esm/packages/taco/src/components/Icon/components/index.js.map +1 -1
  49. package/dist/esm/packages/taco/src/components/Provider/Localization.js +19 -0
  50. package/dist/esm/packages/taco/src/components/Provider/Localization.js.map +1 -1
  51. package/dist/esm/packages/taco/src/components/SearchInput2/SearchInput2.js +4 -0
  52. package/dist/esm/packages/taco/src/components/SearchInput2/SearchInput2.js.map +1 -1
  53. package/dist/esm/packages/taco/src/components/Table3/Table3.js +28 -4
  54. package/dist/esm/packages/taco/src/components/Table3/Table3.js.map +1 -1
  55. package/dist/esm/packages/taco/src/components/Table3/components/alert/ErrorAlert.js +154 -0
  56. package/dist/esm/packages/taco/src/components/Table3/components/alert/ErrorAlert.js.map +1 -0
  57. package/dist/esm/packages/taco/src/components/Table3/components/columns/cell/Cell.js +51 -6
  58. package/dist/esm/packages/taco/src/components/Table3/components/columns/cell/Cell.js.map +1 -1
  59. package/dist/esm/packages/taco/src/components/Table3/components/columns/cell/DisplayCell.js +7 -55
  60. package/dist/esm/packages/taco/src/components/Table3/components/columns/cell/DisplayCell.js.map +1 -1
  61. package/dist/esm/packages/taco/src/components/Table3/components/columns/cell/EditingCell.js +69 -37
  62. package/dist/esm/packages/taco/src/components/Table3/components/columns/cell/EditingCell.js.map +1 -1
  63. package/dist/esm/packages/taco/src/components/Table3/components/columns/cell/EditingControl.js +17 -17
  64. package/dist/esm/packages/taco/src/components/Table3/components/columns/cell/EditingControl.js.map +1 -1
  65. package/dist/esm/packages/taco/src/components/Table3/components/columns/cell/Highlight.js +41 -0
  66. package/dist/esm/packages/taco/src/components/Table3/components/columns/cell/Highlight.js.map +1 -0
  67. package/dist/esm/packages/taco/src/components/Table3/components/columns/cell/controls/TextareaControl.js +21 -12
  68. package/dist/esm/packages/taco/src/components/Table3/components/columns/cell/controls/TextareaControl.js.map +1 -1
  69. package/dist/esm/packages/taco/src/components/Table3/components/columns/footer/Footer.js +1 -1
  70. package/dist/esm/packages/taco/src/components/Table3/components/columns/footer/Footer.js.map +1 -1
  71. package/dist/esm/packages/taco/src/components/Table3/components/columns/header/Group.js +6 -5
  72. package/dist/esm/packages/taco/src/components/Table3/components/columns/header/Group.js.map +1 -1
  73. package/dist/esm/packages/taco/src/components/Table3/components/columns/header/Header.js +2 -2
  74. package/dist/esm/packages/taco/src/components/Table3/components/columns/header/Header.js.map +1 -1
  75. package/dist/esm/packages/taco/src/components/Table3/components/columns/internal/EditingActions.js +57 -17
  76. package/dist/esm/packages/taco/src/components/Table3/components/columns/internal/EditingActions.js.map +1 -1
  77. package/dist/esm/packages/taco/src/components/Table3/components/rows/Row.js +42 -32
  78. package/dist/esm/packages/taco/src/components/Table3/components/rows/Row.js.map +1 -1
  79. package/dist/esm/packages/taco/src/components/Table3/components/rows/RowContext.js +2 -1
  80. package/dist/esm/packages/taco/src/components/Table3/components/rows/RowContext.js.map +1 -1
  81. package/dist/esm/packages/taco/src/components/Table3/components/toolbar/Filter/filters/Filters.js +8 -1
  82. package/dist/esm/packages/taco/src/components/Table3/components/toolbar/Filter/filters/Filters.js.map +1 -1
  83. package/dist/esm/packages/taco/src/components/Table3/components/toolbar/PrintButton/hooks/useParentStylesheets.js +2 -1
  84. package/dist/esm/packages/taco/src/components/Table3/components/toolbar/PrintButton/hooks/useParentStylesheets.js.map +1 -1
  85. package/dist/esm/packages/taco/src/components/Table3/components/toolbar/Search.js +48 -1
  86. package/dist/esm/packages/taco/src/components/Table3/components/toolbar/Search.js.map +1 -1
  87. package/dist/esm/packages/taco/src/components/Table3/components/toolbar/Settings.js +2 -2
  88. package/dist/esm/packages/taco/src/components/Table3/components/toolbar/Settings.js.map +1 -1
  89. package/dist/esm/packages/taco/src/components/Table3/components/toolbar/Toolbar.js +1 -1
  90. package/dist/esm/packages/taco/src/components/Table3/components/toolbar/Toolbar.js.map +1 -1
  91. package/dist/esm/packages/taco/src/components/Table3/hooks/features/useEditing.js +185 -101
  92. package/dist/esm/packages/taco/src/components/Table3/hooks/features/useEditing.js.map +1 -1
  93. package/dist/esm/packages/taco/src/components/Table3/hooks/features/usePauseShortcuts.js +12 -0
  94. package/dist/esm/packages/taco/src/components/Table3/hooks/features/usePauseShortcuts.js.map +1 -0
  95. package/dist/esm/packages/taco/src/components/Table3/hooks/features/useSearch.js +4 -1
  96. package/dist/esm/packages/taco/src/components/Table3/hooks/features/useSearch.js.map +1 -1
  97. package/dist/esm/packages/taco/src/components/Table3/hooks/features/useValidation.js +178 -0
  98. package/dist/esm/packages/taco/src/components/Table3/hooks/features/useValidation.js.map +1 -0
  99. package/dist/esm/packages/taco/src/components/Table3/hooks/useConvertChildrenToColumns.js +1 -1
  100. package/dist/esm/packages/taco/src/components/Table3/hooks/useConvertChildrenToColumns.js.map +1 -1
  101. package/dist/esm/packages/taco/src/components/Table3/hooks/useTable.js +8 -2
  102. package/dist/esm/packages/taco/src/components/Table3/hooks/useTable.js.map +1 -1
  103. package/dist/esm/packages/taco/src/components/Table3/strategies/virtualised.js +1 -1
  104. package/dist/esm/packages/taco/src/components/Table3/types.js.map +1 -1
  105. package/dist/esm/packages/taco/src/components/Table3/util/editing.js +21 -1
  106. package/dist/esm/packages/taco/src/components/Table3/util/editing.js.map +1 -1
  107. package/dist/esm/packages/taco/src/components/Tooltip/Tooltip.js +4 -0
  108. package/dist/esm/packages/taco/src/components/Tooltip/Tooltip.js.map +1 -1
  109. package/dist/esm/packages/taco/src/utils/hooks/useTruncated.js +20 -0
  110. package/dist/esm/packages/taco/src/utils/hooks/useTruncated.js.map +1 -0
  111. package/dist/index.css +112 -33
  112. package/dist/taco.cjs.development.js +1735 -957
  113. package/dist/taco.cjs.development.js.map +1 -1
  114. package/dist/taco.cjs.production.min.js +1 -1
  115. package/dist/taco.cjs.production.min.js.map +1 -1
  116. package/package.json +2 -2
  117. package/types.json +23852 -10957
@@ -188,6 +188,47 @@ function IconAccounting(props, svgRef) {
188
188
  }
189
189
  var Accounting = /*#__PURE__*/React.forwardRef(IconAccounting);
190
190
 
191
+ function IconAiChatSolid(props, svgRef) {
192
+ return /*#__PURE__*/React.createElement("svg", Object.assign({
193
+ fill: "none",
194
+ xmlns: "http://www.w3.org/2000/svg",
195
+ viewBox: "0 0 24 24",
196
+ ref: svgRef
197
+ }, props), /*#__PURE__*/React.createElement("path", {
198
+ fillRule: "evenodd",
199
+ clipRule: "evenodd",
200
+ d: "M18.823 2.122a.188.188 0 01.352 0l.874 2.364c.02.051.06.092.111.11l2.364.875a.188.188 0 010 .352l-2.364.875a.188.188 0 00-.11.11l-.875 2.364a.188.188 0 01-.352 0l-.875-2.364a.187.187 0 00-.11-.11l-2.364-.875a.188.188 0 010-.352l2.364-.874a.187.187 0 00.11-.111l.875-2.364zm1.667 7a.188.188 0 01.351 0l.515 1.39a.19.19 0 00.11.112l1.39.514a.188.188 0 010 .352l-1.39.514a.188.188 0 00-.11.111l-.515 1.39a.187.187 0 01-.351 0l-.515-1.39a.187.187 0 00-.11-.11l-1.391-.515a.188.188 0 010-.352l1.39-.514a.187.187 0 00.111-.111l.515-1.39zm-5.363-2.36c-.889-.328-1.014-1.455-.374-2.008a12.291 12.291 0 00-3.864-.606C5.979 4.148 2 6.884 2 10.26c0 2.393 1.999 4.463 4.91 5.467L4.513 19.99a.556.556 0 00.832.706l5.406-4.325.426-.003c3.493-.076 6.477-1.538 7.829-3.612l-.879-.325c-1.034-.383-1.034-1.845 0-2.228l.234-.086a1.168 1.168 0 01-.476-.595l-.745-2.013-2.013-.745z",
201
+ fill: "currentColor"
202
+ }));
203
+ }
204
+ var AiChatSolid = /*#__PURE__*/React.forwardRef(IconAiChatSolid);
205
+
206
+ function IconAiStars(props, svgRef) {
207
+ return /*#__PURE__*/React.createElement("svg", Object.assign({
208
+ fill: "none",
209
+ xmlns: "http://www.w3.org/2000/svg",
210
+ viewBox: "0 0 24 24",
211
+ ref: svgRef
212
+ }, props), /*#__PURE__*/React.createElement("mask", {
213
+ id: "ai-stars_svg__a",
214
+ fill: "#fff"
215
+ }, /*#__PURE__*/React.createElement("path", {
216
+ fillRule: "evenodd",
217
+ clipRule: "evenodd",
218
+ d: "M17.324 2.476a.188.188 0 01.351 0l.875 2.364c.019.05.06.091.11.11l2.364.875a.188.188 0 010 .352l-2.363.874a.187.187 0 00-.111.11l-.875 2.365a.188.188 0 01-.351 0l-.875-2.364a.188.188 0 00-.11-.11l-2.364-.875a.188.188 0 010-.352l2.363-.875a.188.188 0 00.111-.11l.875-2.364zM8.226 4.931c.266-.719 1.281-.719 1.547 0l1.566 4.23 4.23 1.566c.719.266.719 1.282 0 1.547l-4.23 1.566-1.566 4.23c-.266.72-1.281.72-1.547 0L6.66 13.84l-4.23-1.566c-.719-.265-.719-1.281 0-1.547l4.23-1.566 1.566-4.23zM9 7.16L7.96 9.974a.825.825 0 01-.488.487L4.66 11.5l2.81 1.041a.825.825 0 01.488.487L9 15.84l1.04-2.812a.825.825 0 01.488-.487l2.811-1.04-2.81-1.04a.825.825 0 01-.488-.488L9 7.162zm8.675 7.315a.188.188 0 00-.351 0l-.875 2.364a.188.188 0 01-.11.11l-2.364.875a.188.188 0 000 .352l2.363.874c.052.02.092.06.111.11l.875 2.364c.06.164.291.164.351 0l.875-2.363a.187.187 0 01.11-.11l2.364-.875a.188.188 0 000-.352l-2.363-.875a.187.187 0 01-.111-.11l-.875-2.364z"
219
+ })), /*#__PURE__*/React.createElement("path", {
220
+ fillRule: "evenodd",
221
+ clipRule: "evenodd",
222
+ d: "M17.324 2.476a.188.188 0 01.351 0l.875 2.364c.019.05.06.091.11.11l2.364.875a.188.188 0 010 .352l-2.363.874a.187.187 0 00-.111.11l-.875 2.365a.188.188 0 01-.351 0l-.875-2.364a.188.188 0 00-.11-.11l-2.364-.875a.188.188 0 010-.352l2.363-.875a.188.188 0 00.111-.11l.875-2.364zM8.226 4.931c.266-.719 1.281-.719 1.547 0l1.566 4.23 4.23 1.566c.719.266.719 1.282 0 1.547l-4.23 1.566-1.566 4.23c-.266.72-1.281.72-1.547 0L6.66 13.84l-4.23-1.566c-.719-.265-.719-1.281 0-1.547l4.23-1.566 1.566-4.23zM9 7.16L7.96 9.974a.825.825 0 01-.488.487L4.66 11.5l2.81 1.041a.825.825 0 01.488.487L9 15.84l1.04-2.812a.825.825 0 01.488-.487l2.811-1.04-2.81-1.04a.825.825 0 01-.488-.488L9 7.162zm8.675 7.315a.188.188 0 00-.351 0l-.875 2.364a.188.188 0 01-.11.11l-2.364.875a.188.188 0 000 .352l2.363.874c.052.02.092.06.111.11l.875 2.364c.06.164.291.164.351 0l.875-2.363a.187.187 0 01.11-.11l2.364-.875a.188.188 0 000-.352l-2.363-.875a.187.187 0 01-.111-.11l-.875-2.364z",
223
+ fill: "currentColor"
224
+ }), /*#__PURE__*/React.createElement("path", {
225
+ d: "M17.675 2.476l.704-.26-.704.26zm-.351 0l-.704-.26.704.26zM18.55 4.84l.703-.26-.703.26zm.11.11l-.26.704.26-.704zm2.364.875l.26-.704-.26.704zm0 .352l-.26-.704.26.704zm-2.363.874l-.26-.703.26.703zm-.111.11l.703.261-.703-.26zm-.875 2.365l.704.26-.704-.26zm-.351 0l-.704.26.704-.26zm-.875-2.364l.703-.26-.703.26zm-.11-.11l.26-.704-.26.703zm-2.364-.875l-.26.703.26-.703zm0-.352l-.26-.704.26.704zm2.363-.875l.26.704-.26-.704zm.111-.11l.703.26-.703-.26zm-6.676.09l-.703.26.703-.26zm-1.547 0l.703.26-.703-.26zm3.113 4.231l-.704.26.12.324.323.12.26-.704zm4.23 1.566l-.26.703.26-.703zm0 1.547l-.26-.703.26.704zm-4.23 1.566l-.26-.703-.324.12-.12.323.704.26zm-1.566 4.23l-.703-.26.703.26zm-1.547 0l.703-.26-.703.26zM6.66 13.84l.704-.26-.12-.324-.324-.12-.26.704zm-4.23-1.566l.26-.703-.26.704zm0-1.547l.26.703-.26-.703zm4.23-1.566l.26.704.324-.12.12-.323-.704-.26zm1.3.812l.703.26-.704-.26zM9 7.162l.703-.26L9 5l-.704 1.9.704.26zM7.472 10.46l-.26-.703.26.704zM4.66 11.5l-.26-.703-1.901.704 1.9.703.26-.703zm2.81 1.041l.261-.703-.26.703zm.488.487l.704-.26-.704.26zM9 15.84l-.703.26L9 18l.703-1.9L9 15.84zm1.04-2.812l.704.26-.703-.26zm.488-.487l-.26-.703.26.703zm2.811-1.04l.26.703 1.901-.703-1.9-.704-.26.704zm-2.81-1.04l.26-.704-.26.704zm-.488-.488l.703-.26-.703.26zm7.284 4.503l-.704-.26.704.26zm.351 0l.704-.26-.704.26zM16.45 16.84l.703.26-.703-.26zm-.11.11l.26.704-.26-.704zm-2.364.875l-.26-.703.26.703zm0 .352l.26-.704-.26.704zm2.363.874l-.26.704.26-.704zm.111.11l.703-.26-.703.26zm.875 2.364l-.704.26.704-.26zm.351 0l.704.26-.704-.26zm.875-2.363l.703.26-.703-.26zm.11-.11l.261.703-.26-.704zm2.364-.875l.26.703-.26-.703zm0-.352l.26-.703-.26.703zm-2.363-.875l-.26.704.26-.704zm-.111-.11l.703-.26-.703.26zM18.38 2.216c-.302-.817-1.457-.817-1.759 0l1.407.52a.563.563 0 01-1.055 0l1.407-.52zm.874 2.363l-.874-2.363-1.407.52.875 2.364 1.406-.52zm-.332-.332a.562.562 0 01.332.332l-1.406.52a.937.937 0 00.553.555l.521-1.407zm2.364.874l-2.364-.874-.52 1.407 2.363.874.52-1.407zm0 1.759c.816-.302.816-1.456 0-1.759l-.521 1.407a.563.563 0 010-1.055l.52 1.407zm-2.364.875l2.364-.875-.521-1.407-2.363.875.52 1.407zm.332-.333a.562.562 0 01-.332.333l-.52-1.407a.937.937 0 00-.554.554l1.406.52zm-.874 2.364l.874-2.364-1.406-.52-.875 2.363 1.407.52zm-1.759 0c.302.816 1.457.816 1.759 0l-1.407-.52a.563.563 0 011.055 0l-1.407.52zm-.874-2.364l.874 2.364 1.407-.52-.875-2.364-1.406.52zm.332.333a.562.562 0 01-.332-.333l1.406-.52a.938.938 0 00-.553-.554l-.521 1.407zm-2.364-.875l2.364.875.52-1.407-2.363-.875-.52 1.407zm0-1.759c-.816.303-.816 1.457 0 1.759l.521-1.407c.49.181.49.874 0 1.055l-.52-1.407zm2.364-.874l-2.364.874.521 1.407 2.364-.874-.521-1.407zm-.332.332a.562.562 0 01.332-.332l.52 1.407a.938.938 0 00.555-.554l-1.407-.52zm.874-2.363l-.874 2.363 1.406.52.875-2.363-1.407-.52zM10.477 4.67c-.508-1.37-2.447-1.37-2.955 0l1.407.52a.1.1 0 01.015-.027.041.041 0 01.01-.01A.085.085 0 019 5.142c.021 0 .037.006.045.011a.041.041 0 01.01.01.1.1 0 01.015.028l1.407-.52zm1.565 4.231l-1.565-4.23-1.407.52 1.565 4.23 1.407-.52zm3.788 1.123L11.6 8.458l-.521 1.407 4.23 1.565.521-1.406zm0 2.954c1.371-.508 1.371-2.447 0-2.954l-.52 1.406a.103.103 0 01.028.015.044.044 0 01.009.01.084.084 0 01.011.046.084.084 0 01-.011.045.04.04 0 01-.01.01.102.102 0 01-.028.015l.521 1.407zm-4.23 1.565l4.23-1.565-.52-1.407-4.232 1.566.521 1.406zm-1.123 3.788l1.565-4.23-1.407-.521-1.565 4.23 1.407.521zm-2.955 0c.508 1.371 2.447 1.371 2.955 0l-1.407-.52a.1.1 0 01-.015.028.04.04 0 01-.01.009.085.085 0 01-.045.012.085.085 0 01-.046-.012.04.04 0 01-.01-.01.1.1 0 01-.015-.027l-1.407.52zm-1.565-4.23l1.565 4.23 1.407-.52-1.565-4.231-1.407.52zm-3.788-1.123l4.23 1.565.521-1.406-4.23-1.566-.521 1.407zm0-2.954c-1.371.507-1.371 2.446 0 2.954l.52-1.407a.1.1 0 01-.028-.015.04.04 0 01-.009-.01.085.085 0 01-.011-.045.09.09 0 01.011-.046.043.043 0 01.01-.01.099.099 0 01.028-.015l-.521-1.406zm4.23-1.566l-4.23 1.566.52 1.406L6.92 9.865 6.4 8.458zM7.523 4.67L5.957 8.901l1.407.52 1.565-4.23-1.407-.52zm1.14 5.563l1.04-2.81-1.406-.521-1.04 2.81 1.407.521zm-.93.93c.431-.159.771-.498.93-.93l-1.406-.52a.075.075 0 01-.044.044l.52 1.407zm-2.811 1.041l2.811-1.04-.52-1.407-2.812 1.04.52 1.407zm2.811-.366l-2.811-1.04-.52 1.406 2.81 1.04.521-1.406zm.93.93a1.574 1.574 0 00-.93-.93l-.52 1.406c.02.008.036.024.044.045l1.407-.52zm1.04 2.811l-1.04-2.81-1.406.52 1.04 2.81 1.407-.52zm-.366-2.81l-1.04 2.81 1.407.52 1.04-2.81-1.407-.52zm.93-.931c-.43.16-.77.499-.93.93l1.407.52a.075.075 0 01.044-.044l-.52-1.406zm2.812-1.04l-2.811 1.04.52 1.406 2.812-1.04-.52-1.407zm-2.811.366l2.811 1.04.52-1.407-2.81-1.04-.521 1.407zm-.93-.93c.159.43.499.77.93.93l.52-1.407a.075.075 0 01-.044-.044l-1.407.52zm-1.04-2.812l1.04 2.811 1.406-.52-1.04-2.811-1.407.52zm9.73 7.314a.563.563 0 01-1.055 0l1.407-.52c-.302-.816-1.457-.816-1.759 0l1.407.52zm-.875 2.364l.875-2.364-1.407-.52-.874 2.363 1.406.52zm-.553.554a.938.938 0 00.553-.554l-1.406-.52a.563.563 0 01.332-.333l.52 1.407zm-2.364.874l2.364-.874-.521-1.407-2.364.875.521 1.406zm0-1.055c.49.181.49.874 0 1.055l-.52-1.406c-.817.302-.817 1.456 0 1.758l.52-1.407zm2.364.875l-2.364-.875-.52 1.407 2.363.875.52-1.407zm.553.554a.938.938 0 00-.553-.554l-.521 1.407a.563.563 0 01-.332-.333l1.406-.52zm.875 2.363l-.875-2.363-1.406.52.874 2.364 1.407-.52zm-1.055 0a.563.563 0 011.055 0l-1.407.52c.302.817 1.457.817 1.759 0l-1.407-.52zm.875-2.363l-.875 2.363 1.407.52.874-2.363-1.406-.52zm.553-.554a.937.937 0 00-.553.554l1.406.52a.562.562 0 01-.332.333l-.52-1.407zm2.364-.875l-2.363.875.52 1.407 2.364-.875-.521-1.407zm0 1.055a.563.563 0 010-1.055l.52 1.407c.817-.302.817-1.456 0-1.758l-.52 1.406zm-2.363-.874l2.363.874.52-1.406-2.363-.875-.52 1.407zm-.554-.554a.938.938 0 00.553.554l.521-1.407a.562.562 0 01.332.332l-1.406.52zm-.875-2.364l.875 2.364 1.406-.52-.874-2.364-1.407.52z",
226
+ fill: "currentColor",
227
+ mask: "url(#ai-stars_svg__a)"
228
+ }));
229
+ }
230
+ var AiStars = /*#__PURE__*/React.forwardRef(IconAiStars);
231
+
191
232
  function IconArrowBottom(props, svgRef) {
192
233
  return /*#__PURE__*/React.createElement("svg", Object.assign({
193
234
  xmlns: "http://www.w3.org/2000/svg",
@@ -1471,6 +1512,21 @@ function IconEnvelopeApproved(props, svgRef) {
1471
1512
  }
1472
1513
  var EnvelopeApproved = /*#__PURE__*/React.forwardRef(IconEnvelopeApproved);
1473
1514
 
1515
+ function IconEnvelopeSolid(props, svgRef) {
1516
+ return /*#__PURE__*/React.createElement("svg", Object.assign({
1517
+ fill: "none",
1518
+ xmlns: "http://www.w3.org/2000/svg",
1519
+ viewBox: "0 0 24 24",
1520
+ ref: svgRef
1521
+ }, props), /*#__PURE__*/React.createElement("path", {
1522
+ fillRule: "evenodd",
1523
+ clipRule: "evenodd",
1524
+ d: "M2.137 5.07l8.77 7.016a1.75 1.75 0 002.186 0l8.77-7.016c.088.209.137.439.137.68v12.5A1.75 1.75 0 0120.25 20H3.75A1.75 1.75 0 012 18.25V5.75c0-.241.049-.471.137-.68zM3.28 4.064c.15-.042.307-.064.47-.064h16.5c.163 0 .32.022.47.064l-8.564 6.85a.25.25 0 01-.312 0L3.28 4.064z",
1525
+ fill: "currentColor"
1526
+ }));
1527
+ }
1528
+ var EnvelopeSolid = /*#__PURE__*/React.forwardRef(IconEnvelopeSolid);
1529
+
1474
1530
  function IconEnvelope(props, svgRef) {
1475
1531
  return /*#__PURE__*/React.createElement("svg", Object.assign({
1476
1532
  xmlns: "http://www.w3.org/2000/svg",
@@ -2481,6 +2537,19 @@ function IconPersonTick(props, svgRef) {
2481
2537
  }
2482
2538
  var PersonTick = /*#__PURE__*/React.forwardRef(IconPersonTick);
2483
2539
 
2540
+ function IconPhoneSolid(props, svgRef) {
2541
+ return /*#__PURE__*/React.createElement("svg", Object.assign({
2542
+ fill: "none",
2543
+ xmlns: "http://www.w3.org/2000/svg",
2544
+ viewBox: "0 0 24 24",
2545
+ ref: svgRef
2546
+ }, props), /*#__PURE__*/React.createElement("path", {
2547
+ d: "M5.357 4.384l.891-.58c.835-.542 1.942-.323 2.586.513l1.28 1.663c.56.724.628 1.734.17 2.496l-1.273 2.12c.372.965.962 1.855 1.77 2.67a8.253 8.253 0 002.701 1.844l1.876-1.253c.711-.475 1.645-.398 2.317.19l1.565 1.373c.782.685.99 1.862.487 2.755l-.538.957c-.536.952-1.517 1.508-2.576 1.46-2.498-.115-5.197-1.718-8.096-4.811-2.903-3.098-4.408-5.983-4.514-8.655-.045-1.125.47-2.168 1.354-2.742z",
2548
+ fill: "currentColor"
2549
+ }));
2550
+ }
2551
+ var PhoneSolid = /*#__PURE__*/React.forwardRef(IconPhoneSolid);
2552
+
2484
2553
  function IconPlay(props, svgRef) {
2485
2554
  return /*#__PURE__*/React.createElement("svg", Object.assign({
2486
2555
  xmlns: "http://www.w3.org/2000/svg",
@@ -2587,6 +2656,19 @@ function IconProjects(props, svgRef) {
2587
2656
  }
2588
2657
  var Projects = /*#__PURE__*/React.forwardRef(IconProjects);
2589
2658
 
2659
+ function IconQuestionMarkBold(props, svgRef) {
2660
+ return /*#__PURE__*/React.createElement("svg", Object.assign({
2661
+ fill: "none",
2662
+ xmlns: "http://www.w3.org/2000/svg",
2663
+ viewBox: "0 0 24 24",
2664
+ ref: svgRef
2665
+ }, props), /*#__PURE__*/React.createElement("path", {
2666
+ d: "M5.367 7.727a.476.476 0 00.484.48h3.147c.274 0 .492-.222.537-.493.184-1.108.965-1.9 2.266-1.9 1.161 0 2.252.623 2.252 2.053 0 1.246-.864 1.841-2.195 2.705-1.714 1.09-2.634 2.534-2.422 4.715l.008.173a.5.5 0 00.5.478h3a.5.5 0 00.5-.5v-.18c0-1.514.665-1.953 2.322-3.072 1.374-.934 2.86-2.025 2.86-4.545 0-3.569-3.002-5.325-6.556-5.325-3.361 0-6.618 1.557-6.703 5.411zm3.432 12.247c0 1.388 1.09 2.322 2.776 2.322 1.741 0 2.817-.934 2.817-2.322 0-1.416-1.09-2.35-2.817-2.35-1.7 0-2.776.934-2.776 2.35z",
2667
+ fill: "currentColor"
2668
+ }));
2669
+ }
2670
+ var QuestionMarkBold = /*#__PURE__*/React.forwardRef(IconQuestionMarkBold);
2671
+
2590
2672
  function IconQuestionMark(props, svgRef) {
2591
2673
  return /*#__PURE__*/React.createElement("svg", Object.assign({
2592
2674
  fill: "none",
@@ -3294,6 +3376,8 @@ const icons = {
3294
3376
  'accounting-year-cancel': AccountingYearCancel,
3295
3377
  'accounting-year': AccountingYear,
3296
3378
  accounting: Accounting,
3379
+ 'ai-chat-solid': AiChatSolid,
3380
+ 'ai-stars': AiStars,
3297
3381
  'arrow-bottom': ArrowBottom,
3298
3382
  'arrow-down': ArrowDown,
3299
3383
  'arrow-end': ArrowEnd,
@@ -3391,6 +3475,7 @@ const icons = {
3391
3475
  'entry-type-supplier-invoice': EntryTypeSupplierInvoice,
3392
3476
  'entry-type-supplier-payment': EntryTypeSupplierPayment,
3393
3477
  'envelope-approved': EnvelopeApproved,
3478
+ 'envelope-solid': EnvelopeSolid,
3394
3479
  envelope: Envelope,
3395
3480
  'expand-view': ExpandView,
3396
3481
  expenses: Expenses,
@@ -3466,6 +3551,7 @@ const icons = {
3466
3551
  'person-minus': PersonMinus,
3467
3552
  'person-plus': PersonPlus,
3468
3553
  'person-tick': PersonTick,
3554
+ 'phone-solid': PhoneSolid,
3469
3555
  play: Play,
3470
3556
  'plus-minus': PlusMinus,
3471
3557
  print: Print,
@@ -3474,6 +3560,7 @@ const icons = {
3474
3560
  profile: Profile,
3475
3561
  'project-cards': ProjectCards,
3476
3562
  projects: Projects,
3563
+ 'question-mark-bold': QuestionMarkBold,
3477
3564
  'question-mark': QuestionMark,
3478
3565
  quicklinks: Quicklinks,
3479
3566
  'rating-bankruptcy': RatingBankruptcy,
@@ -4016,9 +4103,13 @@ const Tooltip = /*#__PURE__*/React.forwardRef(function Tooltip(props, ref) {
4016
4103
  title,
4017
4104
  children,
4018
4105
  placement,
4106
+ hide = false,
4019
4107
  ...otherProps
4020
4108
  } = props;
4021
4109
  const className = cn(otherProps.className);
4110
+ if (hide) {
4111
+ return children;
4112
+ }
4022
4113
  return /*#__PURE__*/React.createElement(TooltipPrimitive.Root, {
4023
4114
  delayDuration: 250
4024
4115
  }, /*#__PURE__*/React.createElement(TooltipPrimitive.Trigger, {
@@ -4291,6 +4382,12 @@ const defaultLocalisationTexts = {
4291
4382
  saving: {
4292
4383
  progress: 'Saving...',
4293
4384
  complete: 'Saved'
4385
+ },
4386
+ clearChangesConfirmationDialog: {
4387
+ title: 'Discard changes',
4388
+ description: 'Are you sure you want to discard changes on row ‘[ROW_IDENTIFIER] [ROW_IDENTIFIER_VALUE]’. Your changes will be lost.',
4389
+ cancel: 'Continue edititng',
4390
+ confirm: 'Discard'
4294
4391
  }
4295
4392
  },
4296
4393
  filters: {
@@ -4391,6 +4488,19 @@ const defaultLocalisationTexts = {
4391
4488
  },
4392
4489
  otherOptions: {
4393
4490
  tooltip: 'Table settings'
4491
+ },
4492
+ validation: {
4493
+ index: 'Index',
4494
+ alert: {
4495
+ unsavedEntries: (count = 1) => count === 1 ? 'unsaved entry:' : 'unsaved entries:',
4496
+ incompleteAndHavntBeenSaved: (count = 1) => count === 1 ? 'is incomplete and haven’t been saved.' : 'are incomplete and haven’t been saved.'
4497
+ },
4498
+ resetFiltersDialog: {
4499
+ title: 'Row is hidden',
4500
+ description: 'The row is hidden due to filtering.',
4501
+ cancel: 'Cancel',
4502
+ confirm: 'Remove filters'
4503
+ }
4394
4504
  }
4395
4505
  },
4396
4506
  searchInput: {
@@ -6692,11 +6802,14 @@ const Trigger$4 = /*#__PURE__*/React.forwardRef(function DrawerTrigger(props, re
6692
6802
  }));
6693
6803
  });
6694
6804
 
6805
+ const DEFAULT_OUTLET_NAME = 'default';
6695
6806
  const Outlet = /*#__PURE__*/React.forwardRef(function Outlet(props, ref) {
6807
+ var _props$name;
6696
6808
  const className = cn('h-full ml-auto overflow-hidden flex-shrink-0', props.className);
6697
6809
  return /*#__PURE__*/React.createElement("div", Object.assign({}, props, {
6698
6810
  className: className,
6699
6811
  "data-taco": "drawer-outlet",
6812
+ "data-taco-outlet-name": (_props$name = props.name) !== null && _props$name !== void 0 ? _props$name : DEFAULT_OUTLET_NAME,
6700
6813
  ref: ref
6701
6814
  }));
6702
6815
  });
@@ -6720,6 +6833,7 @@ const Drawer = /*#__PURE__*/React.forwardRef(function Drawer(props, ref) {
6720
6833
  children,
6721
6834
  focusTrap = props.focusTrap === undefined && props.variant === 'overlay' ? true : props.focusTrap,
6722
6835
  showCloseButton = true,
6836
+ outletName,
6723
6837
  ...otherProps
6724
6838
  } = props;
6725
6839
  const [open, setOpen] = reactUseControllableState.useControllableState({
@@ -6749,9 +6863,10 @@ const Drawer = /*#__PURE__*/React.forwardRef(function Drawer(props, ref) {
6749
6863
  }, []);
6750
6864
  React.useEffect(() => {
6751
6865
  var _document$querySelect;
6752
- const outletElement = (_document$querySelect = document.querySelector('[data-taco="drawer-outlet"]')) !== null && _document$querySelect !== void 0 ? _document$querySelect : document.body;
6866
+ const outletSelector = `[data-taco="drawer-outlet"][data-taco-outlet-name="${outletName !== null && outletName !== void 0 ? outletName : DEFAULT_OUTLET_NAME}"]`;
6867
+ const outletElement = (_document$querySelect = document.querySelector(outletSelector)) !== null && _document$querySelect !== void 0 ? _document$querySelect : document.body;
6753
6868
  setOutlet(outletElement);
6754
- }, []);
6869
+ }, [outletName]);
6755
6870
  React.useEffect(() => {
6756
6871
  if (open) {
6757
6872
  // if drawerStack is defined, this means that another drawer was opened before
@@ -6784,7 +6899,30 @@ Drawer.Close = Close$3;
6784
6899
  Drawer.Actions = Actions;
6785
6900
  Drawer.Outlet = Outlet;
6786
6901
 
6902
+ const isTruncated = targetElement => {
6903
+ if (targetElement !== null) {
6904
+ return targetElement.offsetWidth < targetElement.scrollWidth;
6905
+ }
6906
+ return false;
6907
+ };
6908
+ const useTruncated = (element, deps = []) => {
6909
+ const [truncated, setTruncated] = React__default.useState(isTruncated(element));
6910
+ React__default.useEffect(() => {
6911
+ setTruncated(isTruncated(element));
6912
+ }, [element, ...deps]);
6913
+ return {
6914
+ truncated
6915
+ };
6916
+ };
6917
+
6787
6918
  const Field = /*#__PURE__*/React.forwardRef(function Field(props, ref) {
6919
+ const [showTooltip, setShowTooltip] = React.useState(false);
6920
+ const messageRef = React.useRef(null);
6921
+ React.useEffect(() => {
6922
+ // refs are null on the first render so setting showTooltip state forces the rerender to see if message is
6923
+ // truncated or not
6924
+ setShowTooltip(true);
6925
+ }, []);
6788
6926
  const {
6789
6927
  disabled,
6790
6928
  children,
@@ -6802,14 +6940,21 @@ const Field = /*#__PURE__*/React.forwardRef(function Field(props, ref) {
6802
6940
  'text-yellow-700': warning && !invalid,
6803
6941
  'opacity-50': disabled
6804
6942
  });
6943
+ const {
6944
+ truncated: isMessageTrucated
6945
+ } = useTruncated(messageRef.current, [message, showTooltip]);
6805
6946
  return /*#__PURE__*/React.createElement("label", Object.assign({}, otherProps, {
6806
6947
  className: className,
6807
6948
  "data-taco": "label",
6808
6949
  ref: ref
6809
- }), children, message && /*#__PURE__*/React.createElement("span", {
6950
+ }), children, message && /*#__PURE__*/React.createElement(Tooltip, {
6951
+ title: message,
6952
+ hide: !isMessageTrucated
6953
+ }, /*#__PURE__*/React.createElement("span", {
6810
6954
  className: messageClassName,
6955
+ ref: messageRef,
6811
6956
  role: invalid ? 'alert' : undefined
6812
- }, message));
6957
+ }, message)));
6813
6958
  });
6814
6959
 
6815
6960
  const Form = /*#__PURE__*/React.forwardRef(function Form(props, ref) {
@@ -9013,6 +9158,7 @@ const SearchInput2 = /*#__PURE__*/React__default.forwardRef(function SearchInput
9013
9158
  findTotal,
9014
9159
  loading = false,
9015
9160
  onChange: handleChange,
9161
+ onClear: handleClearCallback,
9016
9162
  onClickFindNext: handleClickFindNext,
9017
9163
  onClickFindPrevious: handleClickFindPrevious,
9018
9164
  settingsContent,
@@ -9049,6 +9195,7 @@ const SearchInput2 = /*#__PURE__*/React__default.forwardRef(function SearchInput
9049
9195
  return (_internalRef$current2 = internalRef.current) === null || _internalRef$current2 === void 0 ? void 0 : _internalRef$current2.blur();
9050
9196
  });
9051
9197
  handleChange('');
9198
+ handleClearCallback === null || handleClearCallback === void 0 ? void 0 : handleClearCallback();
9052
9199
  };
9053
9200
  const handleFocus = event => {
9054
9201
  var _attributes$onFocus;
@@ -9170,6 +9317,8 @@ const SearchInput2 = /*#__PURE__*/React__default.forwardRef(function SearchInput
9170
9317
  opacity: 0.999
9171
9318
  }
9172
9319
  }, input, /*#__PURE__*/React__default.createElement("div", {
9320
+ // We need to trigger blur when settings got blured as well, because settings is a part of SearchInput2 component
9321
+ onBlur: handleBlur,
9173
9322
  className: settingsClassname,
9174
9323
  onClickCapture: () => {
9175
9324
  var _internalRef$current5;
@@ -12516,9 +12665,9 @@ const MemoedHeader = /*#__PURE__*/React__default.memo(function MemoedHeader(prop
12516
12665
  sortDirection,
12517
12666
  table
12518
12667
  } = props;
12519
- const className = cn('sticky font-bold border-b-2 box-content group/column relative', '[[role="table"][data-resizing="true"]_&]:pointer-events-none', 'px-[var(--table3-cell-padding-x)]', {
12668
+ const className = cn('font-bold border-b-2 box-content group/column relative', '[[role="table"][data-resizing="true"]_&]:pointer-events-none', 'px-[var(--table3-cell-padding-x)]', {
12520
12669
  '!border-white': isPlaceholder,
12521
- 'h-10 items-center': !isPrinting,
12670
+ 'h-10 items-center sticky': !isPrinting,
12522
12671
  'pb-2': isPrinting,
12523
12672
  'cursor-pointer select-none': canSort,
12524
12673
  'hover:bg-grey-100': !isPlaceholder && (canSort || canResize || hasMenu),
@@ -12598,27 +12747,60 @@ const RowContext = /*#__PURE__*/React__default.createContext({
12598
12747
  setIsHovered: () => {
12599
12748
  /* empty */
12600
12749
  },
12601
- rowIndex: 0
12750
+ rowIndex: 0,
12751
+ hasError: false
12602
12752
  });
12603
12753
  const useRowContext = () => React__default.useContext(RowContext);
12604
12754
 
12755
+ const Highlight = props => {
12756
+ const {
12757
+ current,
12758
+ frozenColumnIndex,
12759
+ index,
12760
+ tableRef,
12761
+ ...attributes
12762
+ } = props;
12763
+ const {
12764
+ hasError: rowHasError
12765
+ } = useRowContext();
12766
+ const ref = React__default.useRef(null);
12767
+ const className = cn('h-full flex [justify-content:inherit] [text-align:inherit]', props.className, {
12768
+ // normal row
12769
+ 'bg-blue-200/25': !current && !rowHasError,
12770
+ // current row
12771
+ 'bg-blue-200/75': current && !rowHasError,
12772
+ // normal row with error
12773
+ 'bg-[#eaeaf5]': !current && rowHasError,
12774
+ // current with error
12775
+ 'bg-[#dadaf5]': current && rowHasError
12776
+ });
12777
+ React__default.useEffect(() => {
12778
+ if (ref.current && current) {
12779
+ scrollColumnIntoView(index, frozenColumnIndex, ref.current, tableRef.current);
12780
+ }
12781
+ }, [current]);
12782
+ return /*#__PURE__*/React__default.createElement("div", Object.assign({}, attributes, {
12783
+ "data-taco": 'highlight',
12784
+ className: className,
12785
+ ref: ref
12786
+ }));
12787
+ };
12788
+
12605
12789
  function DisplayCell(props) {
12606
12790
  const {
12607
12791
  cell,
12608
12792
  className,
12609
12793
  column,
12610
- getValue,
12794
+ value,
12611
12795
  index,
12612
12796
  row,
12613
12797
  table,
12614
- tableRef
12798
+ tableRef,
12799
+ highlighted,
12800
+ highlightedAsCurrent
12615
12801
  } = props;
12616
12802
  const columnMeta = React__default.useMemo(() => column.columnDef.meta, []);
12617
12803
  const tableMeta = table.options.meta;
12618
- const {
12619
- rowIndex
12620
- } = React__default.useContext(RowContext);
12621
- const value = getValue();
12622
12804
  // cells are heavily memoized because performance in our table is critical
12623
12805
  // be careful and selective about props that you pass to the cell
12624
12806
  const memoedProps = React__default.useMemo(() => {
@@ -12636,29 +12818,9 @@ function DisplayCell(props) {
12636
12818
  tableRef
12637
12819
  };
12638
12820
  }, [row.original, props.children, value, tableMeta.columnFreezing.frozenColumnIndex]);
12639
- const memoedHighlight = React__default.useMemo(() => {
12640
- var _tableMeta$search$que;
12641
- if (!tableMeta.search.isHighlightingEnabled || !columnMeta.enableSearch) {
12642
- return false;
12643
- }
12644
- if ((_tableMeta$search$que = tableMeta.search.query) !== null && _tableMeta$search$que !== void 0 && _tableMeta$search$que.length) {
12645
- return isCellHighlighted(tableMeta.search.query, value, columnMeta.dataType);
12646
- }
12647
- return false;
12648
- }, [value, tableMeta.search.isHighlightingEnabled, tableMeta.search.excludeUnmatchedResults, tableMeta.search.query]);
12649
- const memoedHighlightCurrent = React__default.useMemo(() => {
12650
- if (!tableMeta.search.isHighlightingEnabled || !memoedHighlight || tableMeta.search.currentHighlightColumnIndex === undefined) {
12651
- return false;
12652
- }
12653
- const [currentRowIndex, currentColumnIndex] = tableMeta.search.highlightedColumnIndexes[tableMeta.search.currentHighlightColumnIndex];
12654
- if (currentRowIndex === rowIndex && currentColumnIndex === index) {
12655
- return true;
12656
- }
12657
- return false;
12658
- }, [memoedHighlight, tableMeta.search.highlightedColumnIndexes.length, tableMeta.search.currentHighlightColumnIndex]);
12659
12821
  return /*#__PURE__*/React__default.createElement(MemoedDisplayCell, Object.assign({}, memoedProps, {
12660
- highlighted: memoedHighlight,
12661
- highlightedAsCurrent: memoedHighlightCurrent
12822
+ highlighted: highlighted,
12823
+ highlightedAsCurrent: highlightedAsCurrent
12662
12824
  }));
12663
12825
  }
12664
12826
  const MemoedDisplayCell = /*#__PURE__*/React__default.memo(function MemoedDisplayCell(props) {
@@ -12699,31 +12861,6 @@ const MemoedDisplayCell = /*#__PURE__*/React__default.memo(function MemoedDispla
12699
12861
  tableRef: tableRef
12700
12862
  }, content) : content);
12701
12863
  });
12702
- const Highlight = props => {
12703
- const {
12704
- current,
12705
- frozenColumnIndex,
12706
- index,
12707
- tableRef,
12708
- ...attributes
12709
- } = props;
12710
- const ref = React__default.useRef(null);
12711
- const className = cn('h-full flex [justify-content:inherit] [text-align:inherit]', props.className, {
12712
- // normal row
12713
- 'bg-blue-200/25': !current,
12714
- // current row
12715
- 'bg-blue-200/75': current
12716
- });
12717
- React__default.useEffect(() => {
12718
- if (ref.current && current) {
12719
- scrollColumnIntoView(index, frozenColumnIndex, ref.current, tableRef.current);
12720
- }
12721
- }, [current]);
12722
- return /*#__PURE__*/React__default.createElement("div", Object.assign({}, attributes, {
12723
- className: className,
12724
- ref: ref
12725
- }));
12726
- };
12727
12864
 
12728
12865
  function Footer$3(props) {
12729
12866
  const {
@@ -12753,7 +12890,7 @@ const MemoedFooter = /*#__PURE__*/React__default.memo(function MemoedFooter(prop
12753
12890
  meta,
12754
12891
  table
12755
12892
  } = props;
12756
- const className = cn('sticky bottom-0 border-t-2 font-bold h-10 box-content items-center group/column relative', {
12893
+ const className = cn('sticky bottom-0 border-t-2 font-bold h-10 box-content items-center group/column relative z-10', {
12757
12894
  'z-30': isFrozen
12758
12895
  });
12759
12896
  if (table.options.debugAll) {
@@ -13686,238 +13823,701 @@ function useRowClick(onRowClick) {
13686
13823
  };
13687
13824
  }
13688
13825
 
13689
- var SavingStateValue;
13690
- (function (SavingStateValue) {
13691
- SavingStateValue["Saving"] = "saving";
13692
- SavingStateValue["Saved"] = "saved";
13693
- SavingStateValue["Error"] = "error";
13694
- })(SavingStateValue || (SavingStateValue = {}));
13695
- function useEditing(isEnabled, onSave) {
13696
- // used to switch the table into editing mode
13697
- const [isEditing, setIsEditing] = React__default.useState(false);
13698
- // Saving indicator need to show saving state per row, saving state can have at lkeast two states 'saving', 'saved',
13699
- // 'saved' should remain for a few seconds to show tick icon after row has been saved.
13700
- const [savingStates, setSavingStates] = React__default.useState(null);
13701
- // sets of row changes pending save, either they have not saved yet or they have errors
13702
- const [changes, setChanges] = React__default.useState(null);
13703
- const [detailModeEditing, setDetailModeEditing] = React__default.useState(false);
13704
- function getCellValue(cell) {
13705
- var _changes$cell$row$id;
13706
- return changes ? (_changes$cell$row$id = changes[cell.row.id]) === null || _changes$cell$row$id === void 0 ? void 0 : _changes$cell$row$id[cell.column.id] : undefined;
13707
- }
13708
- // Saves editing cell value into editing state.
13709
- function setCellValue(cell, value) {
13710
- setChanges(currentChanges => {
13711
- const nextChanges = {
13712
- ...currentChanges
13713
- };
13714
- if (nextChanges[cell.row.id]) {
13715
- nextChanges[cell.row.id][cell.column.id] = value;
13716
- // we should probably delete the cell if it has just reverted back to its original value
13717
- } else {
13718
- nextChanges[cell.row.id] = {
13719
- ...cell.row.original,
13720
- [cell.column.id]: value
13721
- };
13722
- }
13723
- return nextChanges;
13724
- });
13826
+ const focussableNodeNames = ['A', 'BUTTON', 'INPUT', 'TEXTAREA', 'SELECT', 'DETAILS'];
13827
+ const focusableSelector = /*#__PURE__*/focussableNodeNames.join(', ');
13828
+ const hasChanged = (value, newValue) => {
13829
+ if (dateFns.isDate(value) && dateFns.isDate(newValue)) {
13830
+ return !isWeakEqual(value, newValue);
13831
+ } else if (Array.isArray(value)) {
13832
+ return JSON.stringify(value) !== JSON.stringify(newValue);
13725
13833
  }
13726
- // Removes changes from editing state by row id
13727
- function resetChange(rowId) {
13728
- let currentChanges = changes ? {
13729
- ...changes
13730
- } : {};
13731
- if (currentChanges) {
13732
- delete currentChanges[rowId];
13733
- }
13734
- const changeset = Object.keys(currentChanges);
13735
- if (changeset.length === 0) {
13736
- currentChanges = null;
13834
+ return value !== newValue;
13835
+ };
13836
+ const willRowMoveAfterSorting = (value, cell, rowIndex, rows, desc) => {
13837
+ var _resortedRows$index;
13838
+ const miniSortRows = [{
13839
+ ...cell.row,
13840
+ original: {
13841
+ ...cell.row.original,
13842
+ [cell.column.id]: value
13737
13843
  }
13738
- setChanges(currentChanges);
13844
+ }];
13845
+ // getValue is used by the built-in sort functons, so we need to make sure it returns the changed value
13846
+ miniSortRows[0].getValue = () => value;
13847
+ let index = 0;
13848
+ if (rowIndex > 0) {
13849
+ miniSortRows.unshift(rows[rowIndex - 1]);
13850
+ index = 1;
13739
13851
  }
13740
- const handleKeyDown = React__default.useCallback(event => {
13741
- if (event.defaultPrevented) {
13852
+ if (rowIndex < rows.length - 1) {
13853
+ miniSortRows.push(rows[rowIndex + 1]);
13854
+ }
13855
+ let resortedRows = [...miniSortRows].sort((a, b) => cell.column.getSortingFn()(a, b, cell.column.id));
13856
+ if (desc) {
13857
+ resortedRows = resortedRows.reverse();
13858
+ }
13859
+ return ((_resortedRows$index = resortedRows[index]) === null || _resortedRows$index === void 0 ? void 0 : _resortedRows$index.id) !== cell.row.id;
13860
+ };
13861
+ // Last focused cell state (not react state)
13862
+ class LastCellIndex {
13863
+ constructor() {
13864
+ this._value = '0';
13865
+ }
13866
+ get value() {
13867
+ return this._value;
13868
+ }
13869
+ set value(val) {
13870
+ this._value = val;
13871
+ }
13872
+ }
13873
+ // Returns index of a closest parent column
13874
+ function getColumnIndex(element) {
13875
+ if (element) {
13876
+ var _element$closest;
13877
+ return (_element$closest = element.closest('[role=cell]')) === null || _element$closest === void 0 ? void 0 : _element$closest.getAttribute('data-column-index');
13878
+ }
13879
+ return null;
13880
+ }
13881
+
13882
+ const FOCUS_MANAGER_OPTIONS = {
13883
+ tabbable: true,
13884
+ // Filter out all focusable elelemnts which are not in current row
13885
+ accept: element => !!element.closest('[role="row"][data-current="true"]')
13886
+ };
13887
+ function Row$1(props) {
13888
+ var _tableMeta$validation, _tableMeta$validation2;
13889
+ const focusManager = focus.useFocusManager();
13890
+ const tableMeta = props.table.options.meta;
13891
+ const isCurrentRow = tableMeta.currentRow.currentRowIndex === props.index;
13892
+ const isDraggingRow = tableMeta.rowDrag.dragging[props.row.id];
13893
+ const isFirstRow = props.index === 0;
13894
+ // we use non-css hovered state to determine whether to render actions or not, for performance
13895
+ const [isHovered, setIsHovered] = React__default.useState(false);
13896
+ // tab behaviour is consistent across normal mode and edit mode, handle it here
13897
+ const handleKeyDown = event => {
13898
+ if (event.isDefaultPrevented() || event.isPropagationStopped()) {
13742
13899
  return;
13743
13900
  }
13744
- if (shouldTriggerShortcut(event, {
13745
- key: 'e',
13746
- meta: true,
13747
- shift: false
13748
- })) {
13749
- setIsEditing(editing => !editing);
13750
- } else if (shouldTriggerShortcut(event, {
13751
- key: 's',
13752
- meta: true,
13753
- shift: false
13754
- })) {
13755
- // Prevent default browser save
13756
- event.preventDefault();
13757
- saveChangesIfNeeded();
13758
- }
13759
- }, [isEditing]);
13760
- const handleBlur = React__default.useCallback(event => {
13761
- if (event.target === event.currentTarget) {
13762
- saveChangesIfNeeded();
13763
- }
13764
- }, []);
13765
- // Creates initial saving states from changes object
13766
- const addSavingStates = () => {
13767
- const changeset = Object.keys(changes || {});
13768
- const additionalSavingStates = _.reduce(changeset, (result, value) => {
13769
- return {
13770
- ...result,
13771
- [value]: {
13772
- state: SavingStateValue.Saving
13773
- }
13774
- };
13775
- }, {});
13776
- setSavingStates({
13777
- ...savingStates,
13778
- ...additionalSavingStates
13779
- });
13780
- };
13781
- // Repoves edititng state by row is. Used in delayed saving indicator.
13782
- const removeSavingState = rowId => {
13783
- const newSavingStates = {
13784
- ...savingStates
13785
- };
13786
- delete newSavingStates[rowId];
13787
- setSavingStates(newSavingStates);
13788
- };
13789
- // Checks if we have changes, then saves them
13790
- const saveChangesIfNeeded = function () {
13791
- try {
13792
- if (!changes) {
13793
- return Promise.resolve();
13794
- }
13795
- const changeset = Object.keys(changes);
13796
- const _temp = function () {
13797
- if (onSave && changeset.length) {
13798
- addSavingStates();
13799
- return Promise.resolve(Promise.allSettled(changeset.map(rowId => onSave(changes[rowId])))).then(function (responses) {
13800
- setChanges(currentChanges => {
13801
- const nextChanges = {
13802
- ...currentChanges
13803
- };
13804
- responses.forEach((response, index) => {
13805
- const rowId = changeset[index];
13806
- if (response.status === 'fulfilled') {
13807
- delete nextChanges[rowId];
13808
- }
13809
- });
13810
- return nextChanges;
13811
- });
13812
- setSavingStates(savingStates => {
13813
- const nextSavingStates = savingStates ? {
13814
- ...savingStates
13815
- } : {};
13816
- responses.forEach((response, index) => {
13817
- const rowId = changeset[index];
13818
- if (response.status === 'fulfilled') {
13819
- nextSavingStates[rowId] = {
13820
- state: SavingStateValue.Saved
13821
- };
13822
- } else {
13823
- // add the error when validation is added
13824
- nextSavingStates[rowId] = {
13825
- state: SavingStateValue.Error
13826
- };
13827
- }
13828
- });
13829
- return nextSavingStates;
13830
- });
13831
- });
13901
+ if (event.key === 'Tab') {
13902
+ tableMeta.hoverState.pause(true);
13903
+ let focusedElement;
13904
+ if (event.shiftKey) {
13905
+ // looping backwards
13906
+ focusedElement = focusManager.focusPrevious(FOCUS_MANAGER_OPTIONS);
13907
+ if (focusedElement) {
13908
+ // override default behaviour, since we're handling focus internally now
13909
+ event.preventDefault();
13910
+ } else {
13911
+ // there are no previous elements to focus, go up a row or go outside the table
13912
+ if (!isFirstRow) {
13913
+ event.preventDefault();
13914
+ tableMeta.currentRow.setCurrentRowIndex(props.index - 1);
13915
+ setTimeout(() => focusManager.focusLast(FOCUS_MANAGER_OPTIONS), 1);
13916
+ }
13832
13917
  }
13833
- }();
13834
- return Promise.resolve(_temp && _temp.then ? _temp.then(function () {}) : void 0);
13835
- } catch (e) {
13836
- return Promise.reject(e);
13918
+ } else {
13919
+ // looping forwards
13920
+ focusedElement = focusManager.focusNext(FOCUS_MANAGER_OPTIONS);
13921
+ if (focusedElement) {
13922
+ // override default behaviour, since we're handling focus internally now
13923
+ event.preventDefault();
13924
+ } else {
13925
+ // there are no next elements to focus, go down a row or go outside the table
13926
+ if (!props.isLastRow) {
13927
+ event.preventDefault();
13928
+ tableMeta.currentRow.setCurrentRowIndex(props.index + 1);
13929
+ setTimeout(() => focusManager.focusFirst(FOCUS_MANAGER_OPTIONS), 1);
13930
+ }
13931
+ }
13932
+ }
13837
13933
  }
13838
13934
  };
13839
- const [rowMoveReason, setRowMoveReason] = React__default.useState({});
13840
- const removeRowMoveReason = columnId => {
13841
- setRowMoveReason(prevState => {
13842
- const newState = {
13843
- ...prevState
13844
- };
13845
- delete newState[columnId];
13846
- return newState;
13935
+ const hasError = !!Object.keys((_tableMeta$validation = (_tableMeta$validation2 = tableMeta.validation.errors) === null || _tableMeta$validation2 === void 0 ? void 0 : _tableMeta$validation2[props.row.id]) !== null && _tableMeta$validation !== void 0 ? _tableMeta$validation : {}).length;
13936
+ // rows are heavily memoized because performance in our table is critical
13937
+ // be careful and selective about props that you pass to the row
13938
+ const memoedProps = {
13939
+ // aria-grabbed is being deprecated but there is no current alternative api, we use it until there is
13940
+ 'aria-grabbed': isDraggingRow ? true : tableMeta.rowDrag.isEnabled ? false : undefined,
13941
+ 'data-current': isCurrentRow,
13942
+ 'data-selected': props.row.getIsSelected(),
13943
+ 'data-invalid': hasError,
13944
+ draggable: tableMeta.rowDrag.isEnabled,
13945
+ index: props.index,
13946
+ onClick: tableMeta.rowClick.handleClick,
13947
+ onDrop: tableMeta.rowDrop.isEnabled ? tableMeta.rowDrop.handleDrop : undefined,
13948
+ onKeyDown: handleKeyDown
13949
+ };
13950
+ let output = /*#__PURE__*/React__default.createElement(MemoedRow, Object.assign({}, props, memoedProps));
13951
+ if (tableMeta.editing.isEditing && (isCurrentRow || isHovered && !tableMeta.hoverState.isPaused)) {
13952
+ output = /*#__PURE__*/React__default.createElement(EditingRow, Object.assign({}, props, memoedProps, {
13953
+ isFirstRow: isFirstRow,
13954
+ setCurrentRowIndex: tableMeta.currentRow.setCurrentRowIndex
13955
+ }));
13956
+ }
13957
+ // we store the row index in context because in a virtualised table the row index and the
13958
+ // react table row index do not match when, for example, sorting is applied
13959
+ const contextValue = React__default.useMemo(() => ({
13960
+ isHovered,
13961
+ setIsHovered,
13962
+ rowIndex: props.index,
13963
+ hasError
13964
+ }), [isHovered, hasError, props.index]);
13965
+ return /*#__PURE__*/React__default.createElement(RowContext.Provider, {
13966
+ value: contextValue
13967
+ }, output);
13968
+ }
13969
+ // turns out we might need some kind of "state" for the focused column, but it doesn't need to be react state that re-renders
13970
+ const lastCellIndex = /*#__PURE__*/new LastCellIndex();
13971
+ // This code is needed to avoid multiple rows being hovered at the same time (it happens since we use non-css hovering)
13972
+ let previouslyHoveredIndex;
13973
+ const unhoverPreviousRow = tableRef => {
13974
+ if (previouslyHoveredIndex !== undefined) {
13975
+ var _tableRef$current;
13976
+ const mouseoutEvent = new MouseEvent('mouseout', {
13977
+ view: window,
13978
+ bubbles: true,
13979
+ cancelable: true
13847
13980
  });
13981
+ const previouslyHovered = tableRef === null || tableRef === void 0 ? void 0 : (_tableRef$current = tableRef.current) === null || _tableRef$current === void 0 ? void 0 : _tableRef$current.querySelector(`[data-row-index="${previouslyHoveredIndex}"]`);
13982
+ previouslyHovered === null || previouslyHovered === void 0 ? void 0 : previouslyHovered.dispatchEvent(mouseoutEvent);
13983
+ }
13984
+ };
13985
+ function EditingRow(props) {
13986
+ const {
13987
+ isFirstRow,
13988
+ isLastRow,
13989
+ onKeyDown,
13990
+ setCurrentRowIndex,
13991
+ virtualiser,
13992
+ ...attributes
13993
+ } = props;
13994
+ const focusManager = focus.useFocusManager();
13995
+ const tableMeta = props.table.options.meta;
13996
+ const handleClickCapture = event => {
13997
+ lastCellIndex.value = getColumnIndex(event.target);
13848
13998
  };
13849
- const showWarning = React__default.useCallback(event => {
13850
- if (isEditing && changes && Object.keys(changes).length > 0) {
13851
- event.returnValue = true;
13852
- return true;
13999
+ const handleArrowLeftKey = event => {
14000
+ let focusedElement;
14001
+ if (event.key === 'ArrowLeft') {
14002
+ // We need to perform special behaviour when focus reaches the end of the row,
14003
+ // so we don't need default browser behaviour.
14004
+ event.stopPropagation();
14005
+ event.preventDefault();
14006
+ tableMeta.hoverState.pause(true);
14007
+ // "CTRL + ArrowLeft" or "META + ArrowLeft" should focus first focusable element of the row
14008
+ if (event.ctrlKey || event.metaKey) {
14009
+ event.target.blur();
14010
+ focusedElement = focusManager.focusFirst(FOCUS_MANAGER_OPTIONS);
14011
+ lastCellIndex.value = getColumnIndex(focusedElement);
14012
+ } else {
14013
+ // looping backwards
14014
+ focusedElement = focusManager.focusPrevious(FOCUS_MANAGER_OPTIONS);
14015
+ if (focusedElement) {
14016
+ lastCellIndex.value = getColumnIndex(focusedElement);
14017
+ } else {
14018
+ // there are no previous elements to focus, go up a row (if there are rows above)
14019
+ if (!isFirstRow || !event.currentTarget.contains(focusedElement)) {
14020
+ event.preventDefault();
14021
+ tableMeta.hoverState.pause(true);
14022
+ tableMeta.currentRow.setCurrentRowIndex(props.index - 1);
14023
+ setTimeout(() => {
14024
+ focusedElement = focusManager.focusLast(FOCUS_MANAGER_OPTIONS);
14025
+ // Need to update lastIndex when row got changed and last element got selected.
14026
+ lastCellIndex.value = getColumnIndex(focusedElement);
14027
+ }, 1);
14028
+ }
14029
+ }
14030
+ }
13853
14031
  }
13854
- return false;
13855
- }, [isEditing, changes]);
14032
+ };
14033
+ const handleArrowRightKey = event => {
14034
+ let focusedElement;
14035
+ if (event.key === 'ArrowRight') {
14036
+ // We need to perform special behaviour when focus reaches the end of the row,
14037
+ // so we don't need default browser behaviour.
14038
+ event.stopPropagation();
14039
+ event.preventDefault();
14040
+ tableMeta.hoverState.pause(true);
14041
+ // "CTRL + ArrowRight" or "META + ArrowRight" should focus last focusable element of the row
14042
+ if (event.ctrlKey || event.metaKey) {
14043
+ event.target.blur();
14044
+ focusedElement = focusManager.focusLast(FOCUS_MANAGER_OPTIONS);
14045
+ lastCellIndex.value = getColumnIndex(focusedElement);
14046
+ } else {
14047
+ // looping forwards
14048
+ focusedElement = focusManager.focusNext(FOCUS_MANAGER_OPTIONS);
14049
+ if (focusedElement) {
14050
+ lastCellIndex.value = getColumnIndex(focusedElement);
14051
+ } else {
14052
+ // there are no next elements to focus, go down a row or go outside the table
14053
+ if (!props.isLastRow && !event.currentTarget.contains(focusedElement)) {
14054
+ event.preventDefault();
14055
+ tableMeta.hoverState.pause(true);
14056
+ tableMeta.currentRow.setCurrentRowIndex(props.index + 1);
14057
+ setTimeout(() => {
14058
+ focusedElement = focusManager.focusFirst(FOCUS_MANAGER_OPTIONS);
14059
+ // Need to update lastIndex when row got changed and last element got selected.
14060
+ lastCellIndex.value = getColumnIndex(focusedElement);
14061
+ }, 1);
14062
+ }
14063
+ }
14064
+ }
14065
+ }
14066
+ };
13856
14067
  React__default.useEffect(() => {
13857
- window.addEventListener('beforeunload', showWarning);
13858
- return () => {
13859
- window.removeEventListener('beforeunload', showWarning);
13860
- };
13861
- }, [showWarning]);
13862
- return {
13863
- isEnabled,
13864
- isEditing,
13865
- toggleEditing: setIsEditing,
13866
- changes,
13867
- getCellValue,
13868
- setCellValue,
13869
- saveChangesIfNeeded,
13870
- detailModeEditing,
13871
- setDetailModeEditing,
13872
- rowMoveReason,
13873
- setRowMoveReason,
13874
- removeRowMoveReason,
13875
- handleKeyDown,
13876
- handleBlur,
13877
- resetChange,
13878
- savingStates,
13879
- removeSavingState
14068
+ // if some row stuck in hovered state, we heed to unhover it when hover state is paused
14069
+ if (tableMeta.hoverState.isPaused) {
14070
+ unhoverPreviousRow(props.tableRef);
14071
+ }
14072
+ }, [tableMeta.hoverState.isPaused]);
14073
+ const handleKeyDown = event => {
14074
+ if (event.isDefaultPrevented() || event.isPropagationStopped() || tableMeta.editing.detailModeEditing || tableMeta.shortcutsState.isPaused) {
14075
+ return;
14076
+ }
14077
+ onKeyDown(event); // handles tab behaviour
14078
+ handleArrowLeftKey(event);
14079
+ handleArrowRightKey(event);
13880
14080
  };
14081
+ // this ensures we focus either on a field or on the same column when keyboard navigating up/down
14082
+ React__default.useEffect(() => {
14083
+ // When table in searching state, whe should prevent editing control to be focused, because it will cause search field to loose focus.
14084
+ if (tableMeta.currentRow.currentRowIndex === props.index && !tableMeta.search.isSearching) {
14085
+ if (lastCellIndex.value !== null) {
14086
+ var _props$tableRef$curre;
14087
+ const lastCellElement = (_props$tableRef$curre = props.tableRef.current) === null || _props$tableRef$curre === void 0 ? void 0 : _props$tableRef$curre.querySelector(`[role="row"][data-current="true"] [data-column-index="${lastCellIndex.value}"]`);
14088
+ const focusableElement = lastCellElement === null || lastCellElement === void 0 ? void 0 : lastCellElement.querySelector(focusableSelector);
14089
+ if (focusableElement) {
14090
+ focusableElement.focus();
14091
+ // if we found a cell but it doesn't contain focusable element, then we'll focus the first one in a row.
14092
+ } else if (lastCellElement) {
14093
+ const focusedElement = focusManager.focusFirst(FOCUS_MANAGER_OPTIONS);
14094
+ lastCellIndex.value = getColumnIndex(focusedElement);
14095
+ }
14096
+ } else {
14097
+ const focusedElement = focusManager.focusFirst(FOCUS_MANAGER_OPTIONS);
14098
+ lastCellIndex.value = getColumnIndex(focusedElement);
14099
+ }
14100
+ }
14101
+ // Need to subscribe to current row index and check is it a current row,
14102
+ // for a situation where hovered row is the next row after current row...
14103
+ // In this case row will not be re-rendered if user switch to next row, because hovered row also renders EditingRow.
14104
+ }, [tableMeta.currentRow.currentRowIndex, tableMeta.search.isSearching]);
14105
+ return /*#__PURE__*/React__default.createElement(MemoedRow, Object.assign({}, attributes, {
14106
+ onClickCapture: handleClickCapture,
14107
+ onKeyDown: handleKeyDown
14108
+ }));
13881
14109
  }
13882
-
13883
- const savingIndicatorHideDelay = 3000;
13884
- const COLUMN_ID$1 = '__editing_actions';
13885
- const MemoedCell$1 = /*#__PURE__*/React__default.memo(function MemoedCell(props) {
14110
+ const clickableElements = ['input', 'button', 'a', 'select', 'option', 'label', 'textarea'];
14111
+ const MemoedRow = /*#__PURE__*/React__default.memo(function MemoedRow(props) {
13886
14112
  const {
13887
- hasChanges,
13888
- isCurrentRow,
13889
- isEditing,
14113
+ index,
14114
+ isLastRow: _1,
14115
+ measureRef,
14116
+ onClick,
14117
+ onClickCapture,
14118
+ onDrop,
13890
14119
  row,
13891
- table
14120
+ table,
14121
+ tableRef,
14122
+ ...attributes
13892
14123
  } = props;
14124
+ const ref = React__default.useRef(null);
13893
14125
  const tableMeta = table.options.meta;
13894
- const savingState = tableMeta.editing.savingStates && tableMeta.editing.savingStates[row.id];
13895
- const [isSavedIndicatorVisible, setIsSavingIndicatorVisible] = React__default.useState(false);
13896
14126
  const {
13897
- texts
13898
- } = useLocalization();
13899
- const handleSaved = () => {
13900
- setIsSavingIndicatorVisible(false);
13901
- tableMeta.editing.removeSavingState(row.id);
13902
- };
13903
- const timer = useTimer(savingIndicatorHideDelay, handleSaved);
14127
+ setIsHovered
14128
+ } = useRowContext();
14129
+ // we measure the first cell (since the row has display: contents) so that the virtualiser height is correct
13904
14130
  React__default.useEffect(() => {
13905
- if (savingState && savingState.state === SavingStateValue.Saved && !isSavedIndicatorVisible) {
13906
- setIsSavingIndicatorVisible(true);
13907
- timer.start();
14131
+ var _ref$current;
14132
+ const firstCell = (_ref$current = ref.current) === null || _ref$current === void 0 ? void 0 : _ref$current.querySelector('[role=cell]:first-child');
14133
+ if (firstCell) {
14134
+ measureRef(firstCell);
13908
14135
  }
13909
- }, [savingState]);
13910
- let content;
13911
- if (savingState) {
13912
- if (savingState.state === SavingStateValue.Saving) {
13913
- content = /*#__PURE__*/React__default.createElement(Tooltip, {
13914
- title: texts.table3.editing.saving.progress
13915
- }, /*#__PURE__*/React__default.createElement(Spinner, {
13916
- delay: 0,
13917
- className: "!text-grey-700 mr-1 !h-5 !w-5"
13918
- }));
13919
- } else if (isSavedIndicatorVisible) {
13920
- content = /*#__PURE__*/React__default.createElement(Tooltip, {
14136
+ }, [ref.current]);
14137
+ // we use capture because it also picks up clicks on e.g. select checkboxes
14138
+ const handleClickCapture = event => {
14139
+ if (typeof onClickCapture === 'function') {
14140
+ onClickCapture(event);
14141
+ }
14142
+ // do this in the next frame, otherwise it remounts the row and prevents row actions on hover from being clickable
14143
+ requestAnimationFrame(() => tableMeta.currentRow.setCurrentRowIndex(index));
14144
+ };
14145
+ const handleClick = event => {
14146
+ if (typeof onClick === 'function') {
14147
+ var _ref$current2;
14148
+ const clickedElement = event.target;
14149
+ if (!((_ref$current2 = ref.current) !== null && _ref$current2 !== void 0 && _ref$current2.contains(event.target)) || clickableElements.includes(clickedElement.tagName.toLowerCase()) || clickedElement.closest(clickableElements.map(tag => `[role=row] ${tag}`).join(','))) {
14150
+ return;
14151
+ }
14152
+ onClick(row.original);
14153
+ }
14154
+ };
14155
+ const handleMouseEnter = () => {
14156
+ // When user moving mouse to fast, then some of the rows are getting stuck in hover state,
14157
+ // because mouseleave event never got triggered, to avoid this to happen we're saving the index of last hovered row,
14158
+ // so that we can unhover it when new row got hovered, and saving it in a variable outside of react to save in performance,
14159
+ // since it would be very performance heavy to use state which is bound to mouse events.
14160
+ if (previouslyHoveredIndex !== undefined) {
14161
+ if (previouslyHoveredIndex !== index) {
14162
+ unhoverPreviousRow(tableRef);
14163
+ previouslyHoveredIndex = index;
14164
+ }
14165
+ } else {
14166
+ previouslyHoveredIndex = index;
14167
+ }
14168
+ setIsHovered(true);
14169
+ };
14170
+ const handleMouseLeave = () => {
14171
+ if (previouslyHoveredIndex === index) {
14172
+ previouslyHoveredIndex = undefined;
14173
+ }
14174
+ setIsHovered(false);
14175
+ };
14176
+ const [isDraggedOver, dropTargetProps] = useDropTarget(event => onDrop === null || onDrop === void 0 ? void 0 : onDrop(event, row.original));
14177
+ const className = cn('group/row contents',
14178
+ // resizing column requires dragging, which means the mouse might (on rare occasions) move over rows and trigger hover state
14179
+ // that in turn triggers rendering of e.g. row actions, which could cause janky ui - so don't allow mouse interaction when resizing
14180
+ '[[role="table"][data-resizing="true"]_&]:pointer-events-none', {
14181
+ 'hover:cursor-pointer': typeof onClick === 'function'
14182
+ });
14183
+ return /*#__PURE__*/React__default.createElement("div", Object.assign({}, attributes, onDrop ? dropTargetProps : undefined, {
14184
+ className: className,
14185
+ "data-row-index": index,
14186
+ "data-dragged-over": isDraggedOver,
14187
+ onClick: handleClick,
14188
+ onClickCapture: handleClickCapture,
14189
+ onMouseEnter: handleMouseEnter,
14190
+ onMouseLeave: handleMouseLeave,
14191
+ role: "row",
14192
+ ref: ref
14193
+ }));
14194
+ });
14195
+
14196
+ var SavingStatusValue;
14197
+ (function (SavingStatusValue) {
14198
+ SavingStatusValue["Saving"] = "saving";
14199
+ SavingStatusValue["Saved"] = "saved";
14200
+ SavingStatusValue["Error"] = "error";
14201
+ })(SavingStatusValue || (SavingStatusValue = {}));
14202
+ function useEditing(isEnabled, validation, onSave) {
14203
+ // used to switch the table into editing mode
14204
+ const [isEditing, setIsEditing] = React__default.useState(false);
14205
+ // Saving indicator need to show saving status per row, saving status can have at least two states 'saving', 'saved',
14206
+ // 'saved' should remain for a few seconds to show tick icon after row has been saved.
14207
+ const [savingStatuses, dispatchSavingStatusAction] = React__default.useReducer(savingStatusesReducer, null);
14208
+ // sets of row changes pending save, either they have not saved yet or they have errors
14209
+ const [editingState, dispatchEditingAction] = React__default.useReducer((state, action) => editingReducer(state, action), null);
14210
+ const [detailModeEditing, setDetailModeEditing] = React__default.useState(false);
14211
+ function getCellValue(cell) {
14212
+ var _editingState$cell$ro;
14213
+ return editingState ? (_editingState$cell$ro = editingState[cell.row.id]) === null || _editingState$cell$ro === void 0 ? void 0 : _editingState$cell$ro[cell.column.id] : undefined;
14214
+ }
14215
+ // Saves editing cell value into editing state.
14216
+ function setCellValue(cell, value) {
14217
+ dispatchEditingAction({
14218
+ type: EditingActionType.SET_CELL_VALUE,
14219
+ payload: {
14220
+ rowId: cell.row.id,
14221
+ cellId: cell.column.id,
14222
+ value,
14223
+ originalValues: cell.row.original
14224
+ }
14225
+ });
14226
+ }
14227
+ // Removes changes from editing state by row id
14228
+ function resetChange(rowId) {
14229
+ dispatchEditingAction({
14230
+ type: EditingActionType.RESET_CHANGE,
14231
+ payload: {
14232
+ rowId
14233
+ }
14234
+ });
14235
+ validation.resetErrors(rowId);
14236
+ }
14237
+ const handleKeyDown = React__default.useCallback(event => {
14238
+ if (event.defaultPrevented) {
14239
+ return;
14240
+ }
14241
+ if (shouldTriggerShortcut(event, {
14242
+ key: 'e',
14243
+ meta: true,
14244
+ shift: false
14245
+ })) {
14246
+ setIsEditing(editing => !editing);
14247
+ } else if (shouldTriggerShortcut(event, {
14248
+ key: 's',
14249
+ meta: true,
14250
+ shift: false
14251
+ })) {
14252
+ // Prevent default browser save
14253
+ event.preventDefault();
14254
+ saveChangesIfNeeded();
14255
+ }
14256
+ }, [isEditing]);
14257
+ const handleBlur = React__default.useCallback(event => {
14258
+ if (event.target === event.currentTarget) {
14259
+ saveChangesIfNeeded();
14260
+ }
14261
+ }, []);
14262
+ // Creates initial saving statuses from changes object
14263
+ const addSavingStatuses = () => {
14264
+ const changeset = Object.keys(editingState || {});
14265
+ const additionalSavingStatuses = _.reduce(changeset, (result, rowId) => {
14266
+ return {
14267
+ ...result,
14268
+ [rowId]: SavingStatusValue.Saving
14269
+ };
14270
+ }, {});
14271
+ dispatchSavingStatusAction({
14272
+ type: SavingStatusActionType.SET_SAVING_STATUSES,
14273
+ payload: {
14274
+ states: additionalSavingStatuses
14275
+ }
14276
+ });
14277
+ };
14278
+ // Resets/removes saving status by row id. Used in delayed saving indicator.
14279
+ const resetSavingStatus = rowId => {
14280
+ dispatchSavingStatusAction({
14281
+ type: SavingStatusActionType.RESET_SAVING_STATUS,
14282
+ payload: {
14283
+ rowId
14284
+ }
14285
+ });
14286
+ };
14287
+ // Checks if we have changes, then saves them
14288
+ const saveChangesIfNeeded = function () {
14289
+ try {
14290
+ if (!editingState) {
14291
+ return Promise.resolve();
14292
+ }
14293
+ const changeset = Object.keys(editingState);
14294
+ const _temp = function () {
14295
+ if (onSave && changeset.length) {
14296
+ addSavingStatuses();
14297
+ return Promise.resolve(Promise.allSettled(changeset.map(rowId => {
14298
+ const validationSavePromise = new Promise((resolve, reject) => {
14299
+ const changedRow = editingState === null || editingState === void 0 ? void 0 : editingState[rowId];
14300
+ if (changedRow) {
14301
+ var _validation$validate;
14302
+ (_validation$validate = validation.validate(rowId, changedRow)) === null || _validation$validate === void 0 ? void 0 : _validation$validate.then(() => {
14303
+ const savePromise = onSave(changedRow);
14304
+ savePromise.then(() => {
14305
+ resolve();
14306
+ }).catch(reason => {
14307
+ if (reason.errors) {
14308
+ validation.setRowErrors(rowId, reason.errors);
14309
+ }
14310
+ reject(reason);
14311
+ });
14312
+ }).catch(() => {
14313
+ validation.confirmErrors(rowId);
14314
+ dispatchSavingStatusAction({
14315
+ type: SavingStatusActionType.SET_SAVING_STATUS,
14316
+ payload: {
14317
+ rowId,
14318
+ state: SavingStatusValue.Error
14319
+ }
14320
+ });
14321
+ reject();
14322
+ });
14323
+ } else {
14324
+ reject();
14325
+ }
14326
+ });
14327
+ return validationSavePromise;
14328
+ }))).then(function (responses) {
14329
+ responses.forEach((response, index) => {
14330
+ const rowId = changeset[index];
14331
+ if (response.status === 'fulfilled') {
14332
+ resetChange(rowId);
14333
+ dispatchSavingStatusAction({
14334
+ type: SavingStatusActionType.SET_SAVING_STATUS,
14335
+ payload: {
14336
+ rowId,
14337
+ state: SavingStatusValue.Saved
14338
+ }
14339
+ });
14340
+ } else {
14341
+ dispatchSavingStatusAction({
14342
+ type: SavingStatusActionType.SET_SAVING_STATUS,
14343
+ payload: {
14344
+ rowId,
14345
+ state: SavingStatusValue.Error
14346
+ }
14347
+ });
14348
+ }
14349
+ });
14350
+ });
14351
+ }
14352
+ }();
14353
+ return Promise.resolve(_temp && _temp.then ? _temp.then(function () {}) : void 0);
14354
+ } catch (e) {
14355
+ return Promise.reject(e);
14356
+ }
14357
+ };
14358
+ const [rowMoveReason, setRowMoveReason] = React__default.useState(null);
14359
+ const removeRowMoveReason = () => {
14360
+ setRowMoveReason(null);
14361
+ };
14362
+ const showWarning = React__default.useCallback(event => {
14363
+ if (isEditing && editingState && Object.keys(editingState).length > 0) {
14364
+ event.returnValue = true;
14365
+ return true;
14366
+ }
14367
+ return false;
14368
+ }, [isEditing, editingState]);
14369
+ function getSavingStatus(rowId) {
14370
+ return savingStatuses && savingStatuses[rowId];
14371
+ }
14372
+ React__default.useEffect(() => {
14373
+ window.addEventListener('beforeunload', showWarning);
14374
+ return () => {
14375
+ window.removeEventListener('beforeunload', showWarning);
14376
+ };
14377
+ }, [showWarning]);
14378
+ React__default.useEffect(() => {
14379
+ if (!isEditing) {
14380
+ setDetailModeEditing(false);
14381
+ lastCellIndex.value = null;
14382
+ }
14383
+ }, [isEditing]);
14384
+ return {
14385
+ isEnabled,
14386
+ isEditing,
14387
+ toggleEditing: setIsEditing,
14388
+ changes: editingState,
14389
+ getCellValue,
14390
+ setCellValue,
14391
+ saveChangesIfNeeded,
14392
+ detailModeEditing,
14393
+ setDetailModeEditing,
14394
+ rowMoveReason,
14395
+ setRowMoveReason,
14396
+ removeRowMoveReason,
14397
+ handleKeyDown,
14398
+ handleBlur,
14399
+ resetChange,
14400
+ getSavingStatus,
14401
+ resetSavingStatus
14402
+ };
14403
+ }
14404
+ var EditingActionType;
14405
+ (function (EditingActionType) {
14406
+ EditingActionType[EditingActionType["SET_CELL_VALUE"] = 0] = "SET_CELL_VALUE";
14407
+ EditingActionType[EditingActionType["RESET_CHANGE"] = 1] = "RESET_CHANGE";
14408
+ })(EditingActionType || (EditingActionType = {}));
14409
+ function editingReducer(state, action) {
14410
+ switch (action.type) {
14411
+ // Set cell value of the row
14412
+ case EditingActionType.SET_CELL_VALUE:
14413
+ return {
14414
+ ...state,
14415
+ [action.payload.rowId]: {
14416
+ ...((state === null || state === void 0 ? void 0 : state[action.payload.rowId]) || action.payload.originalValues),
14417
+ [action.payload.cellId]: action.payload.value
14418
+ }
14419
+ };
14420
+ // Reset changes for the row
14421
+ case EditingActionType.RESET_CHANGE:
14422
+ {
14423
+ let currentChanges = {
14424
+ ...state
14425
+ };
14426
+ if (currentChanges) {
14427
+ delete currentChanges[action.payload.rowId];
14428
+ }
14429
+ const changeset = Object.keys(currentChanges);
14430
+ if (changeset.length === 0) {
14431
+ currentChanges = null;
14432
+ }
14433
+ return currentChanges;
14434
+ }
14435
+ default:
14436
+ return state;
14437
+ }
14438
+ }
14439
+ var SavingStatusActionType;
14440
+ (function (SavingStatusActionType) {
14441
+ SavingStatusActionType[SavingStatusActionType["SET_SAVING_STATUS"] = 0] = "SET_SAVING_STATUS";
14442
+ SavingStatusActionType[SavingStatusActionType["SET_SAVING_STATUSES"] = 1] = "SET_SAVING_STATUSES";
14443
+ SavingStatusActionType[SavingStatusActionType["RESET_SAVING_STATUS"] = 2] = "RESET_SAVING_STATUS";
14444
+ })(SavingStatusActionType || (SavingStatusActionType = {}));
14445
+ function savingStatusesReducer(state, action) {
14446
+ switch (action.type) {
14447
+ // Set single saving status for the row
14448
+ case SavingStatusActionType.SET_SAVING_STATUS:
14449
+ return {
14450
+ ...state,
14451
+ [action.payload.rowId]: action.payload.state
14452
+ };
14453
+ // Set multiple saving statuses for multiple rows at the same time
14454
+ case SavingStatusActionType.SET_SAVING_STATUSES:
14455
+ return {
14456
+ ...state,
14457
+ ...action.payload.states
14458
+ };
14459
+ // Reset/remove saving status for particular row
14460
+ case SavingStatusActionType.RESET_SAVING_STATUS:
14461
+ {
14462
+ const newSavingStatus = {
14463
+ ...state
14464
+ };
14465
+ newSavingStatus === null || newSavingStatus === void 0 ? true : delete newSavingStatus[action.payload.rowId];
14466
+ return newSavingStatus;
14467
+ }
14468
+ default:
14469
+ return state;
14470
+ }
14471
+ }
14472
+
14473
+ const savingIndicatorHideDelay = 3000;
14474
+ const COLUMN_ID$1 = '__editing_actions';
14475
+ const MemoedCell$1 = /*#__PURE__*/React__default.memo(function MemoedCell(props) {
14476
+ var _column$columnDef$met;
14477
+ const {
14478
+ hasChanges,
14479
+ isCurrentRow,
14480
+ row,
14481
+ editing,
14482
+ rowIdentifier,
14483
+ table
14484
+ } = props;
14485
+ const savingStatus = editing.getSavingStatus(row.id);
14486
+ const [isSavedIndicatorVisible, setIsSavingIndicatorVisible] = React__default.useState(false);
14487
+ const {
14488
+ texts
14489
+ } = useLocalization();
14490
+ const [clearConfirmationOpen, setClearConfirmationOpen] = React__default.useState(false);
14491
+ const columns = table.getAllFlatColumns();
14492
+ const column = columns.find(column => column.id === rowIdentifier);
14493
+ const rowIdentifierHeader = column === null || column === void 0 ? void 0 : (_column$columnDef$met = column.columnDef.meta) === null || _column$columnDef$met === void 0 ? void 0 : _column$columnDef$met.header;
14494
+ const edititngActionsRef = React__default.useRef(null);
14495
+ const tableMeta = table.options.meta;
14496
+ const handleSaved = () => {
14497
+ setIsSavingIndicatorVisible(false);
14498
+ editing.resetSavingStatus(row.id);
14499
+ };
14500
+ const timer = useTimer(savingIndicatorHideDelay, handleSaved);
14501
+ React__default.useEffect(() => {
14502
+ if (savingStatus && savingStatus === SavingStatusValue.Saved && !isSavedIndicatorVisible) {
14503
+ setIsSavingIndicatorVisible(true);
14504
+ timer.start();
14505
+ }
14506
+ }, [savingStatus]);
14507
+ React__default.useEffect(() => {
14508
+ tableMeta.shortcutsState.pause(clearConfirmationOpen);
14509
+ }, [clearConfirmationOpen]);
14510
+ let content;
14511
+ if (savingStatus) {
14512
+ if (savingStatus === SavingStatusValue.Saving) {
14513
+ content = /*#__PURE__*/React__default.createElement(Tooltip, {
14514
+ title: texts.table3.editing.saving.progress
14515
+ }, /*#__PURE__*/React__default.createElement(Spinner, {
14516
+ delay: 0,
14517
+ className: "!text-grey-700 mr-1 !h-5 !w-5"
14518
+ }));
14519
+ } else if (isSavedIndicatorVisible) {
14520
+ content = /*#__PURE__*/React__default.createElement(Tooltip, {
13921
14521
  title: texts.table3.editing.saving.complete
13922
14522
  }, /*#__PURE__*/React__default.createElement(Icon, {
13923
14523
  name: "tick",
@@ -13925,25 +14525,48 @@ const MemoedCell$1 = /*#__PURE__*/React__default.memo(function MemoedCell(props)
13925
14525
  }));
13926
14526
  }
13927
14527
  }
13928
- if (isEditing && isCurrentRow) {
14528
+ if (editing.isEditing && isCurrentRow) {
13929
14529
  content = /*#__PURE__*/React__default.createElement(React__default.Fragment, null, content, /*#__PURE__*/React__default.createElement(IconButton, {
14530
+ ref: edititngActionsRef,
13930
14531
  appearance: "transparent",
13931
14532
  "aria-label": texts.table3.editing.actions.tooltip,
13932
14533
  icon: "more",
13933
14534
  menu: menuProps => /*#__PURE__*/React__default.createElement(Menu$1, Object.assign({}, menuProps), /*#__PURE__*/React__default.createElement(Menu$1.Content, null, /*#__PURE__*/React__default.createElement(Menu$1.Item, {
13934
14535
  icon: "tick",
13935
14536
  disabled: !hasChanges,
13936
- onClick: () => tableMeta.editing.saveChangesIfNeeded()
14537
+ onClick: () => editing.saveChangesIfNeeded()
13937
14538
  }, texts.table3.editing.actions.save), /*#__PURE__*/React__default.createElement(Menu$1.Item, {
13938
14539
  icon: "close",
13939
14540
  disabled: !hasChanges,
13940
- onClick: () => tableMeta.editing.resetChange(row.id)
14541
+ onClick: () => setClearConfirmationOpen(true)
13941
14542
  }, texts.table3.editing.actions.clear), /*#__PURE__*/React__default.createElement(Menu$1.Item, {
13942
14543
  icon: "undo",
13943
- onClick: () => tableMeta.editing.toggleEditing(false)
14544
+ onClick: () => editing.toggleEditing(false)
13944
14545
  }, texts.table3.editing.actions.exit))),
13945
14546
  tabIndex: isCurrentRow ? 0 : -1
13946
- }));
14547
+ }), /*#__PURE__*/React__default.createElement(Dialog, {
14548
+ size: "xs",
14549
+ open: clearConfirmationOpen,
14550
+ onClose: () => {
14551
+ setClearConfirmationOpen(false);
14552
+ requestAnimationFrame(() => {
14553
+ if (edititngActionsRef.current) {
14554
+ edititngActionsRef.current.focus();
14555
+ // When table looses focus, we need to re-set the last column index
14556
+ lastCellIndex.value = getColumnIndex(edititngActionsRef.current);
14557
+ }
14558
+ });
14559
+ }
14560
+ }, /*#__PURE__*/React__default.createElement(Dialog.Content, {
14561
+ "aria-label": texts.table3.editing.clearChangesConfirmationDialog.title
14562
+ }, /*#__PURE__*/React__default.createElement(Dialog.Title, null, texts.table3.editing.clearChangesConfirmationDialog.title), /*#__PURE__*/React__default.createElement("p", null, texts.table3.editing.clearChangesConfirmationDialog.description.replace('[ROW_IDENTIFIER]', rowIdentifier && rowIdentifierHeader ? rowIdentifierHeader : texts.table3.validation.index).replace('[ROW_IDENTIFIER_VALUE]', rowIdentifier && rowIdentifierHeader ? row.original[rowIdentifier] : row.index)), /*#__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, {
14563
+ tabIndex: 0
14564
+ }, texts.table3.editing.clearChangesConfirmationDialog.cancel)), /*#__PURE__*/React__default.createElement(Dialog.Close, null, /*#__PURE__*/React__default.createElement(Button$1, {
14565
+ tabIndex: 0,
14566
+ appearance: "primary",
14567
+ autoFocus: true,
14568
+ onClick: () => editing.resetChange(row.id)
14569
+ }, texts.table3.editing.clearChangesConfirmationDialog.confirm)))))));
13947
14570
  }
13948
14571
  const contentClassName = cn('flex items-center justify-end text-right', {
13949
14572
  '-mb-2 -mt-2': isCurrentRow
@@ -13965,15 +14588,17 @@ function Cell$1(props) {
13965
14588
  return /*#__PURE__*/React__default.createElement(MemoedCell$1, Object.assign({}, props, {
13966
14589
  hasChanges: changeset.indexOf(props.row.id) >= 0,
13967
14590
  isCurrentRow: tableMeta.currentRow.currentRowIndex === rowIndex,
13968
- isEditing: tableMeta.editing.isEditing
14591
+ editing: tableMeta.editing
13969
14592
  }));
13970
14593
  }
13971
14594
  const EDITING_ACTIONS_WIDTH = 60;
13972
- function createRowEditingActionsColumn() {
14595
+ function createRowEditingActionsColumn(rowIdentifier) {
13973
14596
  return {
13974
14597
  id: COLUMN_ID$1,
13975
14598
  header: Header$1,
13976
- cell: Cell$1,
14599
+ cell: context => /*#__PURE__*/React__default.createElement(Cell$1, Object.assign({}, context, {
14600
+ rowIdentifier: rowIdentifier
14601
+ })),
13977
14602
  footer: Footer$3,
13978
14603
  meta: {
13979
14604
  align: 'right',
@@ -14104,42 +14729,6 @@ const Indicator = ({
14104
14729
  }), indicatorText.title)), container);
14105
14730
  };
14106
14731
 
14107
- const focussableNodeNames = ['A', 'BUTTON', 'INPUT', 'TEXTAREA', 'SELECT', 'DETAILS'];
14108
- const focusableSelector = /*#__PURE__*/focussableNodeNames.join(', ');
14109
- const hasChanged = (value, newValue) => {
14110
- if (dateFns.isDate(value) && dateFns.isDate(newValue)) {
14111
- return !isWeakEqual(value, newValue);
14112
- } else if (Array.isArray(value)) {
14113
- return JSON.stringify(value) !== JSON.stringify(newValue);
14114
- }
14115
- return value !== newValue;
14116
- };
14117
- const willRowMoveAfterSorting = (value, cell, rowIndex, rows, desc) => {
14118
- var _resortedRows$index;
14119
- const miniSortRows = [{
14120
- ...cell.row,
14121
- original: {
14122
- ...cell.row.original,
14123
- [cell.column.id]: value
14124
- }
14125
- }];
14126
- // getValue is used by the built-in sort functons, so we need to make sure it returns the changed value
14127
- miniSortRows[0].getValue = () => value;
14128
- let index = 0;
14129
- if (rowIndex > 0) {
14130
- miniSortRows.unshift(rows[rowIndex - 1]);
14131
- index = 1;
14132
- }
14133
- if (rowIndex < rows.length - 1) {
14134
- miniSortRows.push(rows[rowIndex + 1]);
14135
- }
14136
- let resortedRows = [...miniSortRows].sort((a, b) => cell.column.getSortingFn()(a, b, cell.column.id));
14137
- if (desc) {
14138
- resortedRows = resortedRows.reverse();
14139
- }
14140
- return ((_resortedRows$index = resortedRows[index]) === null || _resortedRows$index === void 0 ? void 0 : _resortedRows$index.id) !== cell.row.id;
14141
- };
14142
-
14143
14732
  const Textarea = /*#__PURE__*/React.forwardRef(function Textarea(props, ref) {
14144
14733
  const {
14145
14734
  defaultValue: _,
@@ -14183,7 +14772,7 @@ const heights = {
14183
14772
  max: 86
14184
14773
  },
14185
14774
  medium: {
14186
- min: 34,
14775
+ min: 32,
14187
14776
  max: 100
14188
14777
  },
14189
14778
  large: {
@@ -14195,6 +14784,7 @@ const TextareaControl = /*#__PURE__*/React__default.forwardRef(function Textarea
14195
14784
  const {
14196
14785
  onKeyDown: handleKeyDown,
14197
14786
  onChange: handleChange,
14787
+ onBlur,
14198
14788
  column,
14199
14789
  isCellInDetailMode,
14200
14790
  align,
@@ -14250,7 +14840,7 @@ const TextareaControl = /*#__PURE__*/React__default.forwardRef(function Textarea
14250
14840
  resizeTextArea(e.target);
14251
14841
  };
14252
14842
  const textareaContainerClassName = cn('w-full', {
14253
- 'focus-within:absolute focus-within:left-0 focus-within:top-0 focus-within:z-20 focus-within:px-[var(--table3-cell-padding-x)] focus-within:pt-[var(--table3-cell-padding-y)]': columnMeta === null || columnMeta === void 0 ? void 0 : columnMeta.enableTruncate
14843
+ 'focus-within:absolute focus-within:left-0 focus-within:top-0 focus-within:z-[9]': columnMeta === null || columnMeta === void 0 ? void 0 : columnMeta.enableTruncate
14254
14844
  });
14255
14845
  const handleTextareaKeyDown = event => {
14256
14846
  // By default Shift + Enter in textarea makes a new line, we want to keep this behaviour
@@ -14260,9 +14850,23 @@ const TextareaControl = /*#__PURE__*/React__default.forwardRef(function Textarea
14260
14850
  handleKeyDown(event);
14261
14851
  }
14262
14852
  };
14853
+ const handleBlur = event => {
14854
+ // If truncation is enabled, then textarea should shring back to min height, when loosing focus.
14855
+ if (columnMeta !== null && columnMeta !== void 0 && columnMeta.enableTruncate) {
14856
+ const textareaElement = event.currentTarget;
14857
+ textareaElement.style.height = `${minMaxHeight.min}px`;
14858
+ }
14859
+ onBlur(event);
14860
+ };
14263
14861
  return /*#__PURE__*/React__default.createElement("div", {
14264
- className: textareaContainerClassName,
14265
14862
  "data-taco": "input-container"
14863
+ }, /*#__PURE__*/React__default.createElement("div", {
14864
+ style: {
14865
+ minHeight: `${minMaxHeight.min}px`
14866
+ },
14867
+ className: "relative"
14868
+ }, /*#__PURE__*/React__default.createElement("div", {
14869
+ className: textareaContainerClassName
14266
14870
  }, /*#__PURE__*/React__default.createElement(Textarea, Object.assign({}, attributes, {
14267
14871
  onChange: event => {
14268
14872
  handleChange(event.target.value);
@@ -14272,14 +14876,8 @@ const TextareaControl = /*#__PURE__*/React__default.forwardRef(function Textarea
14272
14876
  onKeyDown: e => {
14273
14877
  handleTextareaKeyDown(e);
14274
14878
  },
14275
- onBlur: event => {
14276
- // If truncation is enabled, then textarea should shring back to min height, when loosing focus.
14277
- if (columnMeta !== null && columnMeta !== void 0 && columnMeta.enableTruncate) {
14278
- const textareaElement = event.currentTarget;
14279
- textareaElement.style.height = `${minMaxHeight.min}px`;
14280
- }
14281
- },
14282
- className: cn(getCellAlignmentClasses(align), `z-20 h-fit resize-none`, {
14879
+ onBlur: handleBlur,
14880
+ className: cn(getCellAlignmentClasses(align), `h-fit resize-none`, {
14283
14881
  [`!min-h-[${minMaxHeight.min}px]`]: columnMeta === null || columnMeta === void 0 ? void 0 : columnMeta.enableTruncate,
14284
14882
  '!yt-focus-dark': isCellInDetailMode,
14285
14883
  [`h-[${minMaxHeight.min}px]`]: !isCellInDetailMode && (columnMeta === null || columnMeta === void 0 ? void 0 : columnMeta.enableTruncate),
@@ -14288,7 +14886,7 @@ const TextareaControl = /*#__PURE__*/React__default.forwardRef(function Textarea
14288
14886
  }),
14289
14887
  ref: ref,
14290
14888
  value: String(value !== null && value !== void 0 ? value : '')
14291
- })));
14889
+ })))));
14292
14890
  });
14293
14891
 
14294
14892
  const EditingControl = /*#__PURE__*/React__default.forwardRef(function Control(props, externalRef) {
@@ -14303,6 +14901,7 @@ const EditingControl = /*#__PURE__*/React__default.forwardRef(function Control(p
14303
14901
  tableRef,
14304
14902
  value,
14305
14903
  cell,
14904
+ error,
14306
14905
  isCurrentRow,
14307
14906
  ...attributes
14308
14907
  } = props;
@@ -14312,6 +14911,8 @@ const EditingControl = /*#__PURE__*/React__default.forwardRef(function Control(p
14312
14911
  const columnMeta = column.columnDef.meta;
14313
14912
  const controlRenderer = columnMeta === null || columnMeta === void 0 ? void 0 : columnMeta.control;
14314
14913
  const isCellInDetailMode = tableMeta.editing.detailModeEditing && (ref === null || ref === void 0 ? void 0 : (_ref$current = ref.current) === null || _ref$current === void 0 ? void 0 : _ref$current.contains(document.activeElement));
14914
+ const originalRow = cell.row.original;
14915
+ // Revert to initial value if escape was pressed
14315
14916
  const handleKeyDown = event => {
14316
14917
  // For some reason keydown event handler is not propogated to the table when input or other control element is
14317
14918
  // in focus so we need to check for shortcut that toggles the editing.
@@ -14371,7 +14972,7 @@ const EditingControl = /*#__PURE__*/React__default.forwardRef(function Control(p
14371
14972
  return;
14372
14973
  }
14373
14974
  };
14374
- const isNumber = typeof value === 'number';
14975
+ const isNumber = (columnMeta === null || columnMeta === void 0 ? void 0 : columnMeta.dataType) === 'number';
14375
14976
  const handleInputKeyDown = event => {
14376
14977
  handleKeyDown(event);
14377
14978
  // Switching to editing mode, when key pressed any alphabetical character or number
@@ -14379,19 +14980,11 @@ const EditingControl = /*#__PURE__*/React__default.forwardRef(function Control(p
14379
14980
  tableMeta.editing.setDetailModeEditing(true);
14380
14981
  }
14381
14982
  };
14382
- const handleDatepickerChange = event => {
14383
- // When datepicker looses focus, it triggers change event, even if date wasn't changed,
14384
- // so adding additional check here to prevent adding change to the edititng state.
14385
- const originalDate = cell.row.original[cell.column.id];
14386
- const changedDate = event.detail;
14387
- if (hasChanged(originalDate, changedDate)) {
14388
- handleChange(changedDate);
14389
- }
14390
- };
14391
14983
  if (typeof controlRenderer === 'function') {
14392
14984
  return controlRenderer({
14393
14985
  ...attributes,
14394
- ref: ref,
14986
+ ref: refCallback,
14987
+ invalid: !!error,
14395
14988
  setValue: nextValue => {
14396
14989
  if (nextValue !== value) {
14397
14990
  handleChange(nextValue);
@@ -14400,19 +14993,22 @@ const EditingControl = /*#__PURE__*/React__default.forwardRef(function Control(p
14400
14993
  value
14401
14994
  }, data);
14402
14995
  } else if (controlRenderer === 'datepicker') {
14403
- const handleDatepickerKeyDown = event => {
14404
- handleKeyDown(event);
14405
- if (/^[a-z0-9]$/i.test(event.key)) {
14406
- tableMeta.editing.setDetailModeEditing(true);
14407
- return;
14996
+ const handleDatepickerChange = event => {
14997
+ // When datepicker looses focus, it triggers change event, even if date wasn't changed,
14998
+ // so adding additional check here to prevent adding change to the edititng state.
14999
+ const originalDate = originalRow[cell.column.id];
15000
+ const changedDate = event.detail;
15001
+ if (hasChanged(originalDate, changedDate)) {
15002
+ handleChange(changedDate);
14408
15003
  }
14409
15004
  };
14410
15005
  return /*#__PURE__*/React__default.createElement(Datepicker, Object.assign({}, attributes, {
15006
+ invalid: !!error,
14411
15007
  className: cn({
14412
15008
  '[&_input]:!yt-focus-dark': isCellInDetailMode
14413
15009
  }),
14414
15010
  onChange: handleDatepickerChange,
14415
- onKeyDown: handleDatepickerKeyDown,
15011
+ onKeyDown: handleInputKeyDown,
14416
15012
  ref: refCallback,
14417
15013
  value: value
14418
15014
  }));
@@ -14424,6 +15020,7 @@ const EditingControl = /*#__PURE__*/React__default.forwardRef(function Control(p
14424
15020
  }));
14425
15021
  } else if (controlRenderer === 'textarea') {
14426
15022
  return /*#__PURE__*/React__default.createElement(TextareaControl, Object.assign({}, props, {
15023
+ invalid: !!error,
14427
15024
  isCellInDetailMode: isCellInDetailMode,
14428
15025
  onKeyDown: handleInputKeyDown,
14429
15026
  ref: refCallback,
@@ -14431,6 +15028,7 @@ const EditingControl = /*#__PURE__*/React__default.forwardRef(function Control(p
14431
15028
  }));
14432
15029
  }
14433
15030
  return /*#__PURE__*/React__default.createElement(Input, Object.assign({}, attributes, {
15031
+ invalid: !!error,
14434
15032
  className: cn(getInputAppearanceClassnames(), getCellAlignmentClasses(align), {
14435
15033
  '!yt-focus-dark': isCellInDetailMode
14436
15034
  }),
@@ -14445,12 +15043,18 @@ const EditingControl = /*#__PURE__*/React__default.forwardRef(function Control(p
14445
15043
  });
14446
15044
 
14447
15045
  function EditingCell(props) {
15046
+ const {
15047
+ cell,
15048
+ table
15049
+ } = props;
14448
15050
  const {
14449
15051
  isHovered
14450
15052
  } = useRowContext();
14451
15053
  // Need to explicitly pass tableMeta, because just passing the table object will not trigger editing change since table object is not mutatable.
14452
- const tableMeta = props.table.options.meta;
15054
+ const tableMeta = table.options.meta;
15055
+ const error = tableMeta.validation.getCellError(cell);
14453
15056
  return /*#__PURE__*/React__default.createElement(MemoedEditingCell, Object.assign({}, props, {
15057
+ error: error,
14454
15058
  isHovered: isHovered,
14455
15059
  tableMeta: tableMeta
14456
15060
  }));
@@ -14465,8 +15069,10 @@ const MemoedEditingCell = /*#__PURE__*/React__default.memo(function MemoedEditin
14465
15069
  table,
14466
15070
  tableRef,
14467
15071
  row,
14468
- isHovered,
14469
- tableMeta
15072
+ tableMeta,
15073
+ error,
15074
+ highlighted,
15075
+ highlightedAsCurrent
14470
15076
  } = props;
14471
15077
  const columnMeta = column.columnDef.meta;
14472
15078
  const cellRef = React__default.useRef(null);
@@ -14503,31 +15109,38 @@ const MemoedEditingCell = /*#__PURE__*/React__default.memo(function MemoedEditin
14503
15109
  }
14504
15110
  };
14505
15111
  const handleBlur = () => {
15112
+ var _tableMeta$editing$ch;
14506
15113
  tableMeta.editing.setDetailModeEditing(false);
15114
+ if ((_tableMeta$editing$ch = tableMeta.editing.changes) !== null && _tableMeta$editing$ch !== void 0 && _tableMeta$editing$ch[cell.row.id]) {
15115
+ tableMeta.validation.validate(cell.row.id, tableMeta.editing.changes[cell.row.id], cell.column.id);
15116
+ }
14507
15117
  };
14508
15118
  // row move indicator
14509
- const moveReason = (_tableMeta$editing$ro = tableMeta.editing.rowMoveReason[cell.column.id]) !== null && _tableMeta$editing$ro !== void 0 ? _tableMeta$editing$ro : null;
15119
+ const moveReason = ((_tableMeta$editing$ro = tableMeta.editing.rowMoveReason) === null || _tableMeta$editing$ro === void 0 ? void 0 : _tableMeta$editing$ro[cell.column.id]) || null;
14510
15120
  const rows = table.getRowModel().rows;
14511
15121
  const currentRowIndex = tableMeta.currentRow.currentRowIndex;
14512
15122
  const isCurrentRow = currentRowIndex !== undefined && ((_rows$currentRowIndex = rows[currentRowIndex]) === null || _rows$currentRowIndex === void 0 ? void 0 : _rows$currentRowIndex.id) === row.id;
14513
15123
  const mountNode = React__default.useMemo(() => {
14514
- if (moveReason) {
15124
+ if (moveReason !== null && isCurrentRow && !error) {
14515
15125
  var _cellRef$current2, _cellRef$current2$par;
14516
15126
  return (_cellRef$current2 = cellRef.current) === null || _cellRef$current2 === void 0 ? void 0 : (_cellRef$current2$par = _cellRef$current2.parentElement) === null || _cellRef$current2$par === void 0 ? void 0 : _cellRef$current2$par.firstChild;
14517
15127
  }
14518
15128
  return null;
14519
- }, [moveReason, cellRef]);
15129
+ }, [moveReason, isCurrentRow, error, cellRef]);
14520
15130
  const removeMoveReason = () => {
14521
- tableMeta.editing.removeRowMoveReason(cell.column.id);
15131
+ tableMeta.editing.removeRowMoveReason();
14522
15132
  };
14523
15133
  React__default.useEffect(() => {
14524
15134
  // To avoid reseting move reason on another row hover,
14525
15135
  // we need to check for changes only if value got changed in the current row.
14526
- if (!isCurrentRow) {
15136
+ if (!isCurrentRow || error) {
15137
+ if (tableMeta.editing.rowMoveReason) {
15138
+ removeMoveReason();
15139
+ }
14527
15140
  return;
14528
15141
  }
14529
15142
  if (hasChanged(getValue(), value)) {
14530
- const moveReason = getRowMoveReason(table, row.index, row.original, cell, value);
15143
+ const moveReason = getRowMoveReason(table, row.index, row.original, cell, value, tableMeta.search.excludeUnmatchedResults);
14531
15144
  tableMeta.editing.setRowMoveReason({
14532
15145
  [cell.column.id]: moveReason
14533
15146
  });
@@ -14535,28 +15148,19 @@ const MemoedEditingCell = /*#__PURE__*/React__default.memo(function MemoedEditin
14535
15148
  removeMoveReason();
14536
15149
  }
14537
15150
  return removeMoveReason;
14538
- }, [value]);
15151
+ }, [value, tableMeta.currentRow.currentRowIndex, tableMeta.search.excludeUnmatchedResults, error]);
14539
15152
  const controlRenderer = (_column$columnDef$met = column.columnDef.meta) === null || _column$columnDef$met === void 0 ? void 0 : _column$columnDef$met.control;
14540
15153
  const className = cn('py-[calc(var(--table3-cell-padding-y)_-_0.06rem)]', {
14541
- relative: (isCurrentRow || isHovered) && controlRenderer === 'textarea',
14542
- // Need to set higher z-index, so that the current row textarea (in expanded state, when positioned absolute) overlaps rows below,
14543
- // but at the same time it should not overlap the table headers which has z-10.
14544
- 'z-[9]': isCurrentRow && controlRenderer === 'textarea'
14545
- },
14546
- // component overrides - grayscale for editing hover
14547
- '[[role="row"][data-current="false"]:hover_&>*]:!grayscale [[role="row"][data-current="false"]:hover_&_.bg-white]:!bg-grey-100', typeof columnMeta.className === 'function' ? columnMeta.className(row.original) : columnMeta.className);
14548
- return /*#__PURE__*/React__default.createElement(React__default.Fragment, null, moveReason !== null && mountNode && /*#__PURE__*/React__default.createElement(Indicator, {
14549
- reason: moveReason,
14550
- columnName: String(cell.column.columnDef.header),
14551
- mountNode: mountNode,
14552
- validationErrors: []
14553
- }), /*#__PURE__*/React__default.createElement("div", {
14554
- className: className,
14555
- "data-align": columnMeta.align,
14556
- "data-column-index": index,
14557
- "data-editable": true,
14558
- role: "cell",
14559
- ref: cellRef
15154
+ // Textarea control is positioned absolute, when column is in enableTruncate mode, so the cell need to be positioned relative
15155
+ relative: controlRenderer === 'textarea' && columnMeta.enableTruncate
15156
+ }, typeof columnMeta.className === 'function' ? columnMeta.className(row.original) : columnMeta.className);
15157
+ const fieldClassName = cn('!min-h-0 w-full !pb-0', {
15158
+ '!pb-3': !!error
15159
+ });
15160
+ const content = /*#__PURE__*/React__default.createElement(Field, {
15161
+ message: error,
15162
+ invalid: !!error,
15163
+ className: fieldClassName
14560
15164
  }, /*#__PURE__*/React__default.createElement(EditingControl, {
14561
15165
  align: columnMeta.align,
14562
15166
  column: cell.column,
@@ -14570,22 +15174,46 @@ const MemoedEditingCell = /*#__PURE__*/React__default.memo(function MemoedEditin
14570
15174
  tableRef: tableRef,
14571
15175
  value: value,
14572
15176
  cell: cell,
15177
+ error: error,
15178
+ tabIndex: isCurrentRow ? 0 : -1,
14573
15179
  isCurrentRow: isCurrentRow
14574
- })));
15180
+ }));
15181
+ return /*#__PURE__*/React__default.createElement(React__default.Fragment, null, moveReason !== null && mountNode && !error ? /*#__PURE__*/React__default.createElement(Indicator, {
15182
+ reason: moveReason,
15183
+ columnName: String(cell.column.columnDef.header),
15184
+ mountNode: mountNode,
15185
+ validationErrors: []
15186
+ }) : null, /*#__PURE__*/React__default.createElement("div", {
15187
+ className: !highlighted ? className : undefined,
15188
+ "data-align": columnMeta.align,
15189
+ "data-column-index": index,
15190
+ role: "cell",
15191
+ "data-editable": true,
15192
+ ref: cellRef,
15193
+ "data-invalid": !!error,
15194
+ "data-highlighted": highlighted
15195
+ }, highlighted ? /*#__PURE__*/React__default.createElement(Highlight, {
15196
+ current: highlightedAsCurrent,
15197
+ className: className,
15198
+ frozenColumnIndex: tableMeta.columnFreezing.frozenColumnIndex,
15199
+ index: index,
15200
+ tableRef: tableRef
15201
+ }, content) : content));
14575
15202
  });
14576
- function getRowMoveReason(table, rowIndex, rowValues, cell, newValue) {
15203
+ function getRowMoveReason(table, rowIndex, rowValues, cell, newValue, excludeUnmatchedResults) {
14577
15204
  var _table$getState$sorti;
14578
15205
  let rowMoveReason = null;
14579
15206
  const {
14580
15207
  globalFilter
14581
15208
  } = table.getState();
14582
- const isFilteredByGlobalFilter = Object.values({
15209
+ const isFilteredByGlobalFilter = excludeUnmatchedResults ? Object.values({
14583
15210
  ...rowValues,
14584
15211
  [cell.id]: newValue
14585
- }).some(cellValue =>
14586
- // Global filter can be undefined when there is no text being searched so we pass an empty string to
14587
- // globalFilterFn as query in that case.
14588
- globalFilterFn(String(cellValue), globalFilter ? String(globalFilter) : ''));
15212
+ }).some(() => {
15213
+ // Global filter can be undefined when there is no text being searched so we pass an empty string to
15214
+ // globalFilterFn as query in that case.
15215
+ return globalFilterFn(String(newValue), globalFilter ? String(globalFilter) : '');
15216
+ }) : true;
14589
15217
  if (!isFilteredByGlobalFilter) {
14590
15218
  rowMoveReason = IndicatorReason.SEARCH;
14591
15219
  } else if (cell.column.getIsFiltered() && !columnFilterFn(newValue, cell.column.getFilterValue())) {
@@ -14601,20 +15229,64 @@ function Cell$2(props) {
14601
15229
  const {
14602
15230
  column,
14603
15231
  row,
14604
- table
15232
+ table,
15233
+ index,
15234
+ getValue,
15235
+ cell
14605
15236
  } = props;
14606
15237
  const {
14607
- isHovered: isHoveredRow
15238
+ isHovered: isHoveredRow,
15239
+ hasError
14608
15240
  } = useRowContext();
14609
15241
  const rows = table.getRowModel().rows;
14610
15242
  const tableMeta = table.options.meta;
14611
15243
  const columnMeta = column.columnDef.meta;
15244
+ const rowErrors = tableMeta.validation.errors ? tableMeta.validation.errors[row.id] : null;
15245
+ const isColumnError = hasError && rowErrors && !!rowErrors[column.id];
14612
15246
  const currentRowIndex = tableMeta.currentRow.currentRowIndex;
14613
15247
  const isCurrentRow = currentRowIndex !== undefined && ((_rows$currentRowIndex = rows[currentRowIndex]) === null || _rows$currentRowIndex === void 0 ? void 0 : _rows$currentRowIndex.id) === row.id;
14614
- if (tableMeta.editing.isEditing && columnMeta.control && (isCurrentRow || isHoveredRow && !tableMeta.hoverState.isPaused)) {
14615
- return /*#__PURE__*/React__default.createElement(EditingCell, Object.assign({}, props));
15248
+ let value = getValue();
15249
+ // When row has changes we always need to show the editing state value, end revert it to original value only when row got saved successfully.
15250
+ // Otherwise it might confuse user because it will look like display value is getting reverted everytime user leaves the row.
15251
+ if (tableMeta.editing.isEditing) {
15252
+ const editingValue = tableMeta.editing.getCellValue(cell);
15253
+ value = editingValue !== null && editingValue !== void 0 ? editingValue : value;
15254
+ }
15255
+ const {
15256
+ rowIndex
15257
+ } = React__default.useContext(RowContext);
15258
+ const memoedHighlight = React__default.useMemo(() => {
15259
+ var _tableMeta$search$que;
15260
+ if (!tableMeta.search.isHighlightingEnabled || !columnMeta.enableSearch) {
15261
+ return false;
15262
+ }
15263
+ if ((_tableMeta$search$que = tableMeta.search.query) !== null && _tableMeta$search$que !== void 0 && _tableMeta$search$que.length) {
15264
+ return isCellHighlighted(tableMeta.search.query, value, columnMeta.dataType);
15265
+ }
15266
+ return false;
15267
+ }, [value, tableMeta.search.isHighlightingEnabled, tableMeta.search.excludeUnmatchedResults, tableMeta.search.query]);
15268
+ const memoedHighlightCurrent = React__default.useMemo(() => {
15269
+ if (!tableMeta.search.isHighlightingEnabled || !memoedHighlight || tableMeta.search.currentHighlightColumnIndex === undefined) {
15270
+ return false;
15271
+ }
15272
+ const [currentRowIndex, currentColumnIndex] = tableMeta.search.highlightedColumnIndexes[tableMeta.search.currentHighlightColumnIndex];
15273
+ if (currentRowIndex === rowIndex && currentColumnIndex === index) {
15274
+ return true;
15275
+ }
15276
+ return false;
15277
+ }, [memoedHighlight, tableMeta.search.highlightedColumnIndexes.length, tableMeta.search.currentHighlightColumnIndex]);
15278
+ const highlightProps = {
15279
+ highlighted: memoedHighlight,
15280
+ highlightedAsCurrent: memoedHighlightCurrent
15281
+ };
15282
+ if (tableMeta.editing.isEditing && columnMeta.control && (isCurrentRow || isHoveredRow && !tableMeta.hoverState.isPaused ||
15283
+ // When cell has error, we renderimg it in edit mode (UX reqirement)
15284
+ isColumnError)) {
15285
+ return /*#__PURE__*/React__default.createElement(EditingCell, Object.assign({}, props, highlightProps));
14616
15286
  }
14617
- return /*#__PURE__*/React__default.createElement(DisplayCell, Object.assign({}, props));
15287
+ return /*#__PURE__*/React__default.createElement(DisplayCell, Object.assign({}, props, highlightProps, {
15288
+ value: value
15289
+ }));
14618
15290
  }
14619
15291
 
14620
15292
  const COLUMN_ID$2 = '__select';
@@ -14944,11 +15616,11 @@ const MemoedGroup = /*#__PURE__*/React__default.memo(function MemoedGroup(props)
14944
15616
  meta,
14945
15617
  table
14946
15618
  } = props;
14947
- const containerClassName = cn('sticky px-2 mb-[2px]', {
14948
- 'h-10': !isPrinting
14949
- }, colSpan > 1 ? `col-span-${colSpan}` : '');
15619
+ const containerClassName = cn('px-2 z-10 hover:z-20', colSpan > 1 ? `col-span-${colSpan}` : '', {
15620
+ sticky: !isPrinting
15621
+ });
14950
15622
  const innerClassName = cn('font-bold box-content group/column relative', 'px-[var(--table3-cell-padding-x)]', {
14951
- 'h-full items-center': !isPrinting,
15623
+ 'h-10 items-center': !isPrinting,
14952
15624
  'pb-2': isPrinting,
14953
15625
  'border-b-2': !!children
14954
15626
  }, meta.headerClassName);
@@ -14958,7 +15630,8 @@ const MemoedGroup = /*#__PURE__*/React__default.memo(function MemoedGroup(props)
14958
15630
  return /*#__PURE__*/React__default.createElement("div", {
14959
15631
  className: containerClassName,
14960
15632
  "data-taco": "table3-column-group",
14961
- "data-align": align
15633
+ "data-align": align,
15634
+ role: "columnheader"
14962
15635
  }, /*#__PURE__*/React__default.createElement("div", {
14963
15636
  className: innerClassName
14964
15637
  }, /*#__PURE__*/React__default.createElement(Tooltip, {
@@ -15089,7 +15762,7 @@ function useConvertChildrenToColumns(props, options, editing) {
15089
15762
  columns.push(columnHelper.display(createRowActionsColumn()));
15090
15763
  }
15091
15764
  if (editing.isEnabled && editing.isEditing) {
15092
- columns.push(columnHelper.display(createRowEditingActionsColumn()));
15765
+ columns.push(columnHelper.display(createRowEditingActionsColumn(props.rowIdentifier)));
15093
15766
  }
15094
15767
  return {
15095
15768
  columns,
@@ -15183,584 +15856,469 @@ function useEditingStateListener(table) {
15183
15856
  });
15184
15857
  }
15185
15858
  }, [meta.currentRow.currentRowIndex]);
15186
- // save if editing gets toggled off
15187
- React__default.useEffect(() => {
15188
- if (meta.editing.isEnabled) {
15189
- if (!meta.editing.isEditing) {
15190
- requestAnimationFrame(() => {
15191
- meta.editing.saveChangesIfNeeded();
15192
- });
15193
- } else if (meta.currentRow.currentRowIndex === undefined) {
15194
- meta.currentRow.setCurrentRowIndex(0);
15195
- }
15196
- }
15197
- }, [meta.editing.isEditing]);
15198
- }
15199
-
15200
- function useSearch(isEnabled, excludeUnmatchedResultsInSearch = false, loadAll) {
15201
- const [query, setQuery] = React__default.useState();
15202
- const [enableHighlighting, setEnableHighlighting] = React__default.useState(true);
15203
- const [excludeUnmatchedResults, setExcludeUnmatchedResults] = React__default.useState(excludeUnmatchedResultsInSearch);
15204
- // highlighting
15205
- const [highlightedColumnIndexes, setHighlightedColumnIndexes] = React__default.useState([]);
15206
- const [currentHighlightColumnIndex, setCurrentHighlightColumnIndex] = React__default.useState(undefined);
15207
- return {
15208
- isEnabled,
15209
- isHighlightingEnabled: enableHighlighting,
15210
- toggleHighlighting: setEnableHighlighting,
15211
- excludeUnmatchedResults,
15212
- toggleExcludeUnmatchedResults: setExcludeUnmatchedResults,
15213
- query,
15214
- setQuery: isEnabled ? setQuery : () => undefined,
15215
- highlightedColumnIndexes,
15216
- setHighlightedColumnIndexes,
15217
- currentHighlightColumnIndex,
15218
- setCurrentHighlightColumnIndex,
15219
- loadAll
15220
- };
15221
- }
15222
-
15223
- const ACTIONS_ON_ROW_LENGTH = 4;
15224
- function useRowActions$1(actionsForRow, actionsForRowLength = ACTIONS_ON_ROW_LENGTH) {
15225
- return {
15226
- actionsForRow,
15227
- actionsForRowLength
15228
- };
15229
- }
15230
-
15231
- const useLocalStorage = (key, initialValue) => {
15232
- const [state, setState] = React__default.useState(() => {
15233
- if (!key) {
15234
- return initialValue;
15235
- }
15236
- try {
15237
- const localStorageValue = localStorage.getItem(key);
15238
- if (typeof localStorageValue !== 'string') {
15239
- localStorage.setItem(key, JSON.stringify(initialValue));
15240
- return initialValue;
15241
- } else {
15242
- return JSON.parse(localStorageValue || 'null');
15243
- }
15244
- } catch {
15245
- // If user is in private mode or has storage restriction
15246
- // localStorage can throw. JSON.parse and JSON.stringify
15247
- // can throw, too.
15248
- return initialValue;
15249
- }
15250
- });
15251
- React__default.useEffect(() => {
15252
- if (!key) {
15253
- return;
15254
- }
15255
- try {
15256
- const serializedState = JSON.stringify(state);
15257
- localStorage.setItem(key, serializedState);
15258
- } catch {
15259
- // If user is in private mode or has storage restriction
15260
- // localStorage can throw. Also JSON.stringify can throw.
15261
- }
15262
- }, [key, state]);
15263
- const clear = () => {
15264
- if (key) {
15265
- localStorage.removeItem(key);
15266
- }
15267
- };
15268
- return [state, setState, clear];
15269
- };
15270
-
15271
- function useTacoSettings() {
15272
- return React__default.useContext(TacoContext);
15273
- }
15274
-
15275
- function useUniqueTableId(tableId) {
15276
- const tacoSettings = useTacoSettings();
15277
- return `taco.${tacoSettings.uniqueUserIdentifier}.table3.${tableId}.settings`;
15278
- }
15279
- function useSettings(id, defaultSettings = {}, onChangeSettings) {
15280
- const uniqueId = useUniqueTableId(id);
15281
- // If the onChangeSettings prop is provided, we intend to handle settings changes externally rather than saving them
15282
- // to local storage.
15283
- const [persistedSettings, setPersistedSettings] = useLocalStorage(uniqueId, defaultSettings);
15284
- useLazyEffect(() => {
15285
- if (onChangeSettings) {
15286
- onChangeSettings(persistedSettings);
15287
- }
15288
- }, [persistedSettings]);
15289
- return [persistedSettings, setPersistedSettings];
15290
- }
15291
-
15292
- function useTable$1(props) {
15293
- var _ref, _defaultSettings$colu, _defaultSettings$rowH, _props$length;
15294
- // options
15295
- const options = useTablePreset(props);
15296
- const tableOptions = {
15297
- enableColumnFilters: options.enableFiltering,
15298
- enableColumnResizing: options.enableColumnResizing,
15299
- enableExpanding: options.enableRowExpansion,
15300
- enableGlobalFilter: options.enableSearch,
15301
- enableHiding: options.enableColumnHiding,
15302
- enableRowSelection: options.enableRowSelection,
15303
- enableMultiRowSelection: !options.enableRowSelectionSingle,
15304
- enableSorting: options.enableSorting
15305
- };
15306
- // resizing
15307
- if (tableOptions.enableColumnResizing) {
15308
- tableOptions.columnResizeMode = 'onChange';
15309
- }
15310
- // filtering
15311
- if (tableOptions.enableColumnFilters) {
15312
- if (!props.onFilter) {
15313
- tableOptions.filterFns = {
15314
- tacoFilter: (row, columnId, filter) => columnFilterFn(row.getValue(columnId), filter)
15315
- };
15316
- tableOptions.getFilteredRowModel = reactTable$1.getFilteredRowModel();
15317
- }
15318
- // we don't tableOptions.manualFiltering = true; because it breaks global filtering, server filtering still works :shrug:
15319
- }
15320
- // search
15321
- if (tableOptions.enableGlobalFilter) {
15322
- // search is always client side, since we call loadAll when searching
15323
- tableOptions.globalFilterFn = (row, columnId, searchQuery) => {
15324
- try {
15325
- if (row.original) {
15326
- const cell = row.getAllCells().find(cell => cell.column.id === columnId);
15327
- const columnMeta = cell === null || cell === void 0 ? void 0 : cell.column.columnDef.meta;
15328
- if (cell && cell.column.getIsVisible() && columnMeta !== null && columnMeta !== void 0 && columnMeta.enableSearch) {
15329
- const cellValue = getCellValueAsString(row.original[columnId], columnMeta === null || columnMeta === void 0 ? void 0 : columnMeta.dataType);
15330
- if (cellValue !== undefined) {
15331
- return globalFilterFn(cellValue, searchQuery);
15332
- }
15333
- }
15334
- return false;
15335
- }
15336
- } catch {
15337
- //
15338
- }
15339
- return false;
15340
- };
15341
- tableOptions.getFilteredRowModel = reactTable$1.getFilteredRowModel();
15342
- tableOptions.getColumnCanGlobalFilter = column => {
15343
- var _column$columnDef$met;
15344
- return (_column$columnDef$met = column.columnDef.meta.enableSearch) !== null && _column$columnDef$met !== void 0 ? _column$columnDef$met : true;
15345
- };
15346
- }
15347
- // sorting
15348
- if (options.enableSorting) {
15349
- if (props.onSort) {
15350
- tableOptions.manualSorting = true;
15351
- // onSort is called as a listener to let the consumer update their data, so we don't use onSortingChange
15352
- } else {
15353
- tableOptions.getSortedRowModel = reactTable$1.getSortedRowModel();
15354
- }
15355
- }
15356
- const [defaultSettings, setSettings] = useSettings(props.id, props.defaultSettings, props.onChangeSettings);
15357
- // custom features
15358
- const columnFreezing = useColumnFreezing( // temporarily see if deprecated frozenColumnCount is there
15359
- (_ref = (_defaultSettings$colu = defaultSettings.columnFreezingIndex) !== null && _defaultSettings$colu !== void 0 ? _defaultSettings$colu : defaultSettings === null || defaultSettings === void 0 ? void 0 : defaultSettings.frozenColumnCount) !== null && _ref !== void 0 ? _ref : props.defaultColumnFreezingIndex, options);
15360
- const columnOrdering = useColumnOrdering(options);
15361
- const currentRow = useCurrentRow(props.defaultCurrentRowIndex);
15362
- const editing = useEditing(options.enableEditing, props.onSave);
15363
- const fontSize = useFontSize(options.enableFontSize, defaultSettings.fontSize);
15364
- const hoverState = usePauseHoverState();
15365
- const printing = usePrinting(options.enablePrinting, props.loadAll, defaultSettings.showWarningWhenPrintingLargeDataset);
15366
- const rowActions = useRowActions$1(props.actionsForRow, props.actionsForRowLength);
15367
- const rowClick = useRowClick(props.onRowClick);
15368
- const rowDrag = useRowDrag(options.enableRowDrag);
15369
- const rowDrop = useRowDrop(options.enableRowDrop, props.onRowDrop);
15370
- const rowGoto = useRowGoto(options.enableRowGoto, props.onRowGoto);
15371
- const rowHeight = useRowHeight(options.enableRowHeight, // temporarily see if deprecated rowDensity is there
15372
- (_defaultSettings$rowH = defaultSettings.rowHeight) !== null && _defaultSettings$rowH !== void 0 ? _defaultSettings$rowH : defaultSettings === null || defaultSettings === void 0 ? void 0 : defaultSettings.rowDensity);
15373
- const rowSelection = useRowSelection();
15374
- const search = useSearch(options.enableSearch, defaultSettings.excludeUnmatchedRecordsInSearch, props.loadAll);
15375
- // columns
15376
- const {
15377
- columns,
15378
- defaultColumnSizing,
15379
- defaultColumnVisibility,
15380
- defaultSorting
15381
- } = useConvertChildrenToColumns(props, options, editing);
15382
- // built-in features
15383
- const initialState = React__default.useMemo(() => {
15384
- var _defaultSettings$colu2, _defaultSettings$colu3, _props$defaultSetting, _props$defaultSetting3;
15385
- const sanitizeSortedColumns = column => columns.find(definedColumn => definedColumn.id === column.id);
15386
- const state = {
15387
- columnOrder: ensureOrdering(columns, defaultSettings.columnOrder),
15388
- columnSizing: (_defaultSettings$colu2 = defaultSettings.columnSizing) !== null && _defaultSettings$colu2 !== void 0 ? _defaultSettings$colu2 : defaultColumnSizing,
15389
- columnVisibility: (_defaultSettings$colu3 = defaultSettings.columnVisibility) !== null && _defaultSettings$colu3 !== void 0 ? _defaultSettings$colu3 : defaultColumnVisibility,
15390
- sorting: defaultSettings.sorting ? defaultSettings.sorting.filter(sanitizeSortedColumns) : defaultSorting
15391
- };
15392
- // we don't save these outside the table, but they need to be here for print to inherit them - see PrintButton.tsx
15393
- if ((_props$defaultSetting = props.defaultSettings) !== null && _props$defaultSetting !== void 0 && _props$defaultSetting.columnFilters) {
15394
- var _props$defaultSetting2;
15395
- state.columnFilters = (_props$defaultSetting2 = props.defaultSettings) === null || _props$defaultSetting2 === void 0 ? void 0 : _props$defaultSetting2.columnFilters;
15396
- }
15397
- if ((_props$defaultSetting3 = props.defaultSettings) !== null && _props$defaultSetting3 !== void 0 && _props$defaultSetting3.globalFilter) {
15398
- var _props$defaultSetting4;
15399
- state.globalFilter = (_props$defaultSetting4 = props.defaultSettings) === null || _props$defaultSetting4 === void 0 ? void 0 : _props$defaultSetting4.globalFilter;
15400
- }
15401
- return state;
15402
- }, []);
15403
- const getSettings = () => {
15404
- const state = table.getState();
15405
- return {
15406
- columnFreezingIndex: columnFreezing.frozenColumnIndex,
15407
- columnOrder: columnOrdering.isEnabled ? state.columnOrder : undefined,
15408
- columnSizing: table.options.enableColumnResizing ? state.columnSizing : undefined,
15409
- columnVisibility: table.options.enableHiding ? state.columnVisibility : undefined,
15410
- excludeUnmatchedRecordsInSearch: search.excludeUnmatchedResults,
15411
- fontSize: fontSize.isEnabled ? fontSize.size : undefined,
15412
- rowHeight: rowHeight.isEnabled ? rowHeight.height : undefined,
15413
- showWarningWhenPrintingLargeDataset: printing.printWarningDialogVisibility,
15414
- sorting: state.sorting
15415
- };
15416
- };
15417
- const table = reactTable$1.useReactTable({
15418
- data: props.data,
15419
- columns,
15420
- getCoreRowModel: reactTable$1.getCoreRowModel(),
15421
- initialState,
15422
- ...tableOptions,
15423
- //debugAll: true,
15424
- meta: {
15425
- columnFreezing,
15426
- columnOrdering,
15427
- currentRow,
15428
- editing,
15429
- enableFooter: options.enableFooter,
15430
- fontSize,
15431
- getSettings,
15432
- hoverState,
15433
- isPrinting: props.id.endsWith('_print'),
15434
- isUsingServer: !!props.loadPage,
15435
- printing,
15436
- rowActions: rowActions,
15437
- rowClick: rowClick,
15438
- rowDrag,
15439
- rowDrop,
15440
- rowGoto,
15441
- rowHeight,
15442
- rowSelection,
15443
- search
15444
- }
15445
- });
15446
- // listeners
15447
- useCurrentRowListener(table);
15448
- useEditingStateListener(table);
15449
- useFilteringStateListener(table, props.onFilter);
15450
- useRowSelectionListener(table, props.onRowSelect);
15451
- useSettingsStateListener(table, setSettings);
15452
- useShortcutsListener(table, props.shortcuts);
15453
- useServerLoadingListener(table, props.loadPage);
15454
- useSortingStateListener(table, props.onSort);
15455
- return {
15456
- table,
15457
- length: (_props$length = props.length) !== null && _props$length !== void 0 ? _props$length : props.data.length
15458
- };
15459
- }
15460
-
15461
- const FOCUS_MANAGER_OPTIONS = {
15462
- tabbable: true
15463
- };
15464
- function Row$1(props) {
15465
- const focusManager = focus.useFocusManager();
15466
- const tableMeta = props.table.options.meta;
15467
- const isCurrentRow = tableMeta.currentRow.currentRowIndex === props.index;
15468
- const isDraggingRow = tableMeta.rowDrag.dragging[props.row.id];
15469
- const isFirstRow = props.index === 0;
15470
- // we use non-css hovered state to determine whether to render actions or not, for performance
15471
- const [isHovered, setIsHovered] = React__default.useState(false);
15472
- // tab behaviour is consistent across normal mode and edit mode, handle it here
15473
- const handleKeyDown = event => {
15474
- if (event.isDefaultPrevented() || event.isPropagationStopped()) {
15475
- return;
15476
- }
15477
- if (event.key === 'Tab') {
15478
- tableMeta.hoverState.pause(true);
15479
- let focusedElement;
15480
- if (event.shiftKey) {
15481
- // looping backwards
15482
- focusedElement = focusManager.focusPrevious(FOCUS_MANAGER_OPTIONS);
15483
- if (focusedElement) {
15484
- // override default behaviour, since we're handling focus internally now
15485
- event.preventDefault();
15486
- } else {
15487
- // there are no previous elements to focus, go up a row or go outside the table
15488
- if (!isFirstRow) {
15489
- event.preventDefault();
15490
- tableMeta.currentRow.setCurrentRowIndex(props.index - 1);
15491
- setTimeout(() => focusManager.focusLast(FOCUS_MANAGER_OPTIONS), 1);
15492
- }
15493
- }
15494
- } else {
15495
- // looping forwards
15496
- focusedElement = focusManager.focusNext(FOCUS_MANAGER_OPTIONS);
15497
- if (focusedElement) {
15498
- // override default behaviour, since we're handling focus internally now
15499
- event.preventDefault();
15500
- } else {
15501
- // there are no next elements to focus, go down a row or go outside the table
15502
- if (!props.isLastRow) {
15503
- event.preventDefault();
15504
- tableMeta.currentRow.setCurrentRowIndex(props.index + 1);
15505
- setTimeout(() => focusManager.focusFirst(FOCUS_MANAGER_OPTIONS), 1);
15506
- }
15507
- }
15508
- }
15509
- }
15510
- };
15511
- // rows are heavily memoized because performance in our table is critical
15512
- // be careful and selective about props that you pass to the row
15513
- const memoedProps = {
15514
- // aria-grabbed is being deprecated but there is no current alternative api, we use it until there is
15515
- 'aria-grabbed': isDraggingRow ? true : tableMeta.rowDrag.isEnabled ? false : undefined,
15516
- 'data-current': isCurrentRow,
15517
- 'data-selected': props.row.getIsSelected(),
15518
- draggable: tableMeta.rowDrag.isEnabled,
15519
- index: props.index,
15520
- onClick: tableMeta.rowClick.handleClick,
15521
- onDrop: tableMeta.rowDrop.isEnabled ? tableMeta.rowDrop.handleDrop : undefined,
15522
- onKeyDown: handleKeyDown
15523
- };
15524
- let output = /*#__PURE__*/React__default.createElement(MemoedRow, Object.assign({}, props, memoedProps));
15525
- if (tableMeta.editing.isEditing && (isCurrentRow || isHovered && !tableMeta.hoverState.isPaused)) {
15526
- output = /*#__PURE__*/React__default.createElement(EditingRow, Object.assign({}, props, memoedProps, {
15527
- isFirstRow: isFirstRow,
15528
- setCurrentRowIndex: tableMeta.currentRow.setCurrentRowIndex
15529
- }));
15530
- }
15531
- // we store the row index in context because in a virtualised table the row index and the
15532
- // react table row index do not match when, for example, sorting is applied
15533
- const contextValue = React__default.useMemo(() => ({
15534
- isHovered,
15535
- setIsHovered,
15536
- rowIndex: props.index
15537
- }), [isHovered, props.index]);
15538
- return /*#__PURE__*/React__default.createElement(RowContext.Provider, {
15539
- value: contextValue
15540
- }, output);
15541
- }
15542
- // turns out we might need some kind of "state" for the focused column, but it doesn't need to be react state that re-renders
15543
- let lastIndex;
15544
- function getColumnIndex(focusedElement) {
15545
- if (focusedElement) {
15546
- var _focusedElement$close;
15547
- return (_focusedElement$close = focusedElement.closest('[role=cell]')) === null || _focusedElement$close === void 0 ? void 0 : _focusedElement$close.getAttribute('data-column-index');
15548
- }
15549
- return null;
15550
- }
15551
- // This code is needed to avoid multiple rows being hovered at the same time (it happens since we use non-css hovering)
15552
- let previouslyHoveredIndex;
15553
- const unhoverPreviousRow = tableRef => {
15554
- if (previouslyHoveredIndex !== undefined) {
15555
- var _tableRef$current;
15556
- const mouseoutEvent = new MouseEvent('mouseout', {
15557
- view: window,
15558
- bubbles: true,
15559
- cancelable: true
15560
- });
15561
- const previouslyHovered = tableRef === null || tableRef === void 0 ? void 0 : (_tableRef$current = tableRef.current) === null || _tableRef$current === void 0 ? void 0 : _tableRef$current.querySelector(`[data-row-index="${previouslyHoveredIndex}"]`);
15562
- previouslyHovered === null || previouslyHovered === void 0 ? void 0 : previouslyHovered.dispatchEvent(mouseoutEvent);
15563
- }
15564
- };
15565
- function EditingRow(props) {
15566
- const {
15567
- isFirstRow,
15568
- isLastRow,
15569
- onKeyDown,
15570
- setCurrentRowIndex,
15571
- virtualiser,
15572
- ...attributes
15573
- } = props;
15574
- const focusManager = focus.useFocusManager();
15575
- const tableMeta = props.table.options.meta;
15576
- const handleClickCapture = event => {
15577
- lastIndex = getColumnIndex(event.target);
15578
- };
15579
- const handleArrowLeftKey = event => {
15580
- let focusedElement;
15581
- if (event.key === 'ArrowLeft') {
15582
- // We need to perform special behaviour when focus reaches the end of the row,
15583
- // so we don't need default browser behaviour.
15584
- event.stopPropagation();
15585
- event.preventDefault();
15586
- // "CTRL + ArrowLeft" or "META + ArrowLeft" should focus first focusable element of the row
15587
- if (event.ctrlKey || event.metaKey) {
15588
- event.target.blur();
15589
- focusedElement = focusManager.focusFirst(FOCUS_MANAGER_OPTIONS);
15590
- lastIndex = getColumnIndex(focusedElement);
15591
- } else {
15592
- // looping backwards
15593
- focusedElement = focusManager.focusPrevious(FOCUS_MANAGER_OPTIONS);
15594
- if (focusedElement) {
15595
- lastIndex = getColumnIndex(focusedElement);
15596
- } else {
15597
- // there are no previous elements to focus, go up a row (if there are rows above)
15598
- if (!isFirstRow) {
15599
- event.preventDefault();
15600
- tableMeta.hoverState.pause(true);
15601
- tableMeta.currentRow.setCurrentRowIndex(props.index - 1);
15602
- setTimeout(() => {
15603
- focusManager.focusLast(FOCUS_MANAGER_OPTIONS);
15604
- // Need to update lastIndex when row got changed and last element got selected.
15605
- lastIndex = getColumnIndex(focusedElement);
15606
- }, 1);
15607
- }
15608
- }
15859
+ // save if editing gets toggled off
15860
+ React__default.useEffect(() => {
15861
+ if (meta.editing.isEnabled) {
15862
+ if (!meta.editing.isEditing) {
15863
+ requestAnimationFrame(() => {
15864
+ meta.editing.saveChangesIfNeeded();
15865
+ });
15866
+ } else if (meta.currentRow.currentRowIndex === undefined) {
15867
+ meta.currentRow.setCurrentRowIndex(0);
15609
15868
  }
15610
15869
  }
15870
+ }, [meta.editing.isEditing]);
15871
+ }
15872
+
15873
+ function useSearch(isEnabled, excludeUnmatchedResultsInSearch = false, loadAll) {
15874
+ const [isSearching, setIsSearching] = React__default.useState(false);
15875
+ const [query, setQuery] = React__default.useState();
15876
+ const [enableHighlighting, setEnableHighlighting] = React__default.useState(true);
15877
+ const [excludeUnmatchedResults, setExcludeUnmatchedResults] = React__default.useState(excludeUnmatchedResultsInSearch);
15878
+ // highlighting
15879
+ const [highlightedColumnIndexes, setHighlightedColumnIndexes] = React__default.useState([]);
15880
+ const [currentHighlightColumnIndex, setCurrentHighlightColumnIndex] = React__default.useState(undefined);
15881
+ return {
15882
+ isEnabled,
15883
+ isHighlightingEnabled: enableHighlighting,
15884
+ toggleHighlighting: setEnableHighlighting,
15885
+ excludeUnmatchedResults,
15886
+ toggleExcludeUnmatchedResults: setExcludeUnmatchedResults,
15887
+ query,
15888
+ setQuery: isEnabled ? setQuery : () => undefined,
15889
+ highlightedColumnIndexes,
15890
+ setHighlightedColumnIndexes,
15891
+ currentHighlightColumnIndex,
15892
+ setCurrentHighlightColumnIndex,
15893
+ loadAll,
15894
+ isSearching,
15895
+ setIsSearching
15611
15896
  };
15612
- const handleArrowRightKey = event => {
15613
- let focusedElement;
15614
- if (event.key === 'ArrowRight') {
15615
- // We need to perform special behaviour when focus reaches the end of the row,
15616
- // so we don't need default browser behaviour.
15617
- event.stopPropagation();
15618
- event.preventDefault();
15619
- // "CTRL + ArrowRight" or "META + ArrowRight" should focus last focusable element of the row
15620
- if (event.ctrlKey || event.metaKey) {
15621
- event.target.blur();
15622
- focusedElement = focusManager.focusLast(FOCUS_MANAGER_OPTIONS);
15623
- lastIndex = getColumnIndex(focusedElement);
15897
+ }
15898
+
15899
+ const ACTIONS_ON_ROW_LENGTH = 4;
15900
+ function useRowActions$1(actionsForRow, actionsForRowLength = ACTIONS_ON_ROW_LENGTH) {
15901
+ return {
15902
+ actionsForRow,
15903
+ actionsForRowLength
15904
+ };
15905
+ }
15906
+
15907
+ const useLocalStorage = (key, initialValue) => {
15908
+ const [state, setState] = React__default.useState(() => {
15909
+ if (!key) {
15910
+ return initialValue;
15911
+ }
15912
+ try {
15913
+ const localStorageValue = localStorage.getItem(key);
15914
+ if (typeof localStorageValue !== 'string') {
15915
+ localStorage.setItem(key, JSON.stringify(initialValue));
15916
+ return initialValue;
15624
15917
  } else {
15625
- // looping forwards
15626
- focusedElement = focusManager.focusNext(FOCUS_MANAGER_OPTIONS);
15627
- if (focusedElement) {
15628
- lastIndex = getColumnIndex(focusedElement);
15629
- } else {
15630
- // there are no next elements to focus, go down a row or go outside the table
15631
- if (!props.isLastRow) {
15632
- event.preventDefault();
15633
- tableMeta.hoverState.pause(true);
15634
- tableMeta.currentRow.setCurrentRowIndex(props.index + 1);
15635
- setTimeout(() => {
15636
- focusManager.focusFirst(FOCUS_MANAGER_OPTIONS);
15637
- // Need to update lastIndex when row got changed and last element got selected.
15638
- lastIndex = getColumnIndex(focusedElement);
15639
- }, 1);
15640
- }
15641
- }
15918
+ return JSON.parse(localStorageValue || 'null');
15642
15919
  }
15920
+ } catch {
15921
+ // If user is in private mode or has storage restriction
15922
+ // localStorage can throw. JSON.parse and JSON.stringify
15923
+ // can throw, too.
15924
+ return initialValue;
15643
15925
  }
15644
- };
15926
+ });
15645
15927
  React__default.useEffect(() => {
15646
- // if some row stuck in hovered state, we heed to unhover it when hover state is paused
15647
- if (tableMeta.hoverState.isPaused) {
15648
- unhoverPreviousRow(props.tableRef);
15649
- }
15650
- }, [tableMeta.hoverState.isPaused]);
15651
- const handleKeyDown = event => {
15652
- if (event.isDefaultPrevented() || event.isPropagationStopped() || tableMeta.editing.detailModeEditing) {
15928
+ if (!key) {
15653
15929
  return;
15654
15930
  }
15655
- onKeyDown(event); // handles tab behaviour
15656
- handleArrowLeftKey(event);
15657
- handleArrowRightKey(event);
15931
+ try {
15932
+ const serializedState = JSON.stringify(state);
15933
+ localStorage.setItem(key, serializedState);
15934
+ } catch {
15935
+ // If user is in private mode or has storage restriction
15936
+ // localStorage can throw. Also JSON.stringify can throw.
15937
+ }
15938
+ }, [key, state]);
15939
+ const clear = () => {
15940
+ if (key) {
15941
+ localStorage.removeItem(key);
15942
+ }
15658
15943
  };
15659
- // this ensures we focus either on a field or on the same column when keyboard navigating up/down
15660
- React__default.useEffect(() => {
15661
- if (tableMeta.currentRow.currentRowIndex === props.index) {
15662
- if (lastIndex !== undefined) {
15663
- var _props$tableRef$curre, _lastIndexCell$queryS;
15664
- const lastIndexCell = (_props$tableRef$curre = props.tableRef.current) === null || _props$tableRef$curre === void 0 ? void 0 : _props$tableRef$curre.querySelector(`[role="row"][data-current="true"] [data-column-index="${lastIndex}"]`);
15665
- lastIndexCell === null || lastIndexCell === void 0 ? void 0 : (_lastIndexCell$queryS = lastIndexCell.querySelector(focusableSelector)) === null || _lastIndexCell$queryS === void 0 ? void 0 : _lastIndexCell$queryS.focus();
15666
- } else {
15667
- focusManager.focusFirst(FOCUS_MANAGER_OPTIONS);
15668
- }
15944
+ return [state, setState, clear];
15945
+ };
15946
+
15947
+ function useTacoSettings() {
15948
+ return React__default.useContext(TacoContext);
15949
+ }
15950
+
15951
+ function useUniqueTableId(tableId) {
15952
+ const tacoSettings = useTacoSettings();
15953
+ return `taco.${tacoSettings.uniqueUserIdentifier}.table3.${tableId}.settings`;
15954
+ }
15955
+ function useSettings(id, defaultSettings = {}, onChangeSettings) {
15956
+ const uniqueId = useUniqueTableId(id);
15957
+ // If the onChangeSettings prop is provided, we intend to handle settings changes externally rather than saving them
15958
+ // to local storage.
15959
+ const [persistedSettings, setPersistedSettings] = useLocalStorage(uniqueId, defaultSettings);
15960
+ useLazyEffect(() => {
15961
+ if (onChangeSettings) {
15962
+ onChangeSettings(persistedSettings);
15669
15963
  }
15670
- // Need to subscribe to current row index and check is it a current row,
15671
- // for a situation where hovered row is the next row after current row...
15672
- // In this case row will not be re-rendered if user switch to next row, because hovered row also renders EditingRow.
15673
- }, [tableMeta.currentRow.currentRowIndex]);
15674
- return /*#__PURE__*/React__default.createElement(MemoedRow, Object.assign({}, attributes, {
15675
- onClickCapture: handleClickCapture,
15676
- onKeyDown: handleKeyDown
15677
- }));
15964
+ }, [persistedSettings]);
15965
+ return [persistedSettings, setPersistedSettings];
15678
15966
  }
15679
- const clickableElements = ['input', 'button', 'a', 'select', 'option', 'label', 'textarea'];
15680
- const MemoedRow = /*#__PURE__*/React__default.memo(function MemoedRow(props) {
15681
- const {
15682
- index,
15683
- isLastRow: _1,
15684
- measureRef,
15685
- onClick,
15686
- onClickCapture,
15687
- onDrop,
15688
- row,
15689
- table,
15690
- tableRef,
15691
- ...attributes
15692
- } = props;
15693
- const ref = React__default.useRef(null);
15694
- const tableMeta = table.options.meta;
15695
- const {
15696
- setIsHovered
15697
- } = useRowContext();
15698
- // we measure the first cell (since the row has display: contents) so that the virtualiser height is correct
15699
- React__default.useEffect(() => {
15700
- var _ref$current;
15701
- const firstCell = (_ref$current = ref.current) === null || _ref$current === void 0 ? void 0 : _ref$current.querySelector('[role=cell]:first-child');
15702
- if (firstCell) {
15703
- measureRef(firstCell);
15967
+
15968
+ function useValidation(onCellValidate, onRowValidate) {
15969
+ const [validationState, dispatch] = React__default.useReducer(validationReducer, {
15970
+ errors: null,
15971
+ draftErrors: null
15972
+ });
15973
+ function getCellError(cell) {
15974
+ var _validationState$draf, _validationState$erro;
15975
+ return validationState.draftErrors && ((_validationState$draf = validationState.draftErrors[cell.row.id]) === null || _validationState$draf === void 0 ? void 0 : _validationState$draf[cell.column.id]) || (validationState.errors ? (_validationState$erro = validationState.errors[cell.row.id]) === null || _validationState$erro === void 0 ? void 0 : _validationState$erro[cell.column.id] : undefined);
15976
+ }
15977
+ function setCellError(rowId, cellId, error) {
15978
+ dispatch({
15979
+ type: ValidationActionType.SET_CELL_ERROR,
15980
+ payload: {
15981
+ rowId,
15982
+ cellId,
15983
+ error
15984
+ }
15985
+ });
15986
+ }
15987
+ function setRowErrors(rowId, errors) {
15988
+ dispatch({
15989
+ type: ValidationActionType.SET_ROW_ERROR,
15990
+ payload: {
15991
+ rowId,
15992
+ errors
15993
+ }
15994
+ });
15995
+ }
15996
+ function confirmErrors(rowId) {
15997
+ dispatch({
15998
+ type: ValidationActionType.CONFIRN_ERRORS,
15999
+ payload: {
16000
+ rowId
16001
+ }
16002
+ });
16003
+ }
16004
+ function resetErrors(rowId, cellId) {
16005
+ dispatch({
16006
+ type: ValidationActionType.RESET_ERRORS,
16007
+ payload: {
16008
+ rowId,
16009
+ cellId
16010
+ }
16011
+ });
16012
+ }
16013
+ const setErrors = (errors, rowId, cellId) => {
16014
+ if (cellId) {
16015
+ setCellError(rowId, cellId, errors[cellId]);
16016
+ } else {
16017
+ setRowErrors(rowId, errors);
15704
16018
  }
15705
- }, [ref.current]);
15706
- // we use capture because it also picks up clicks on e.g. select checkboxes
15707
- const handleClickCapture = event => {
15708
- if (typeof onClickCapture === 'function') {
15709
- onClickCapture(event);
16019
+ };
16020
+ const validate = (rowId, row, cellId) => {
16021
+ let validationPromise;
16022
+ if (cellId && onCellValidate) {
16023
+ validationPromise = onCellValidate(row[cellId], cellId, row);
16024
+ } else if (onRowValidate) {
16025
+ validationPromise = onRowValidate(row);
16026
+ } else {
16027
+ validationPromise = new Promise(resolve => {
16028
+ resolve();
16029
+ });
15710
16030
  }
15711
- // do this in the next frame, otherwise it remounts the row and prevents row actions on hover from being clickable
15712
- requestAnimationFrame(() => tableMeta.currentRow.setCurrentRowIndex(index));
16031
+ validationPromise.then(() => {
16032
+ // Need to reset previous errors,
16033
+ // since promise resolve is the only place where we consider that previous errors is not relevant anymore.
16034
+ resetErrors(rowId, cellId);
16035
+ }).catch(errors => {
16036
+ setErrors(errors, rowId, cellId);
16037
+ });
16038
+ return validationPromise;
15713
16039
  };
15714
- const handleClick = event => {
15715
- if (typeof onClick === 'function') {
15716
- var _ref$current2;
15717
- const clickedElement = event.target;
15718
- if (!((_ref$current2 = ref.current) !== null && _ref$current2 !== void 0 && _ref$current2.contains(event.target)) || clickableElements.includes(clickedElement.tagName.toLowerCase()) || clickedElement.closest(clickableElements.map(tag => `[role=row] ${tag}`).join(','))) {
15719
- return;
16040
+ return {
16041
+ validate,
16042
+ setCellError,
16043
+ setRowErrors,
16044
+ confirmErrors,
16045
+ getCellError,
16046
+ resetErrors,
16047
+ errors: validationState.errors,
16048
+ draftErrors: validationState.draftErrors
16049
+ };
16050
+ }
16051
+ // Taking care of reseting/removing errors for particular cell/row and reseting errors object to null, when no errors at all.
16052
+ function _resetErrors(errors, rowId, columnId) {
16053
+ let currentErrors = errors ? {
16054
+ ...errors
16055
+ } : {};
16056
+ if (currentErrors && currentErrors[rowId]) {
16057
+ if (columnId) {
16058
+ delete currentErrors[rowId][columnId];
16059
+ const rowErrorsSet = Object.keys(currentErrors[rowId]);
16060
+ if (rowErrorsSet.length === 0) {
16061
+ delete currentErrors[rowId];
15720
16062
  }
15721
- onClick(row.original);
16063
+ } else {
16064
+ delete currentErrors[rowId];
16065
+ }
16066
+ }
16067
+ const errorsSet = Object.keys(currentErrors);
16068
+ if (errorsSet.length === 0) {
16069
+ currentErrors = null;
16070
+ }
16071
+ return currentErrors;
16072
+ }
16073
+ var ValidationActionType;
16074
+ (function (ValidationActionType) {
16075
+ ValidationActionType[ValidationActionType["SET_CELL_ERROR"] = 0] = "SET_CELL_ERROR";
16076
+ ValidationActionType[ValidationActionType["SET_ROW_ERROR"] = 1] = "SET_ROW_ERROR";
16077
+ ValidationActionType[ValidationActionType["CONFIRN_ERRORS"] = 2] = "CONFIRN_ERRORS";
16078
+ ValidationActionType[ValidationActionType["RESET_ERRORS"] = 3] = "RESET_ERRORS";
16079
+ })(ValidationActionType || (ValidationActionType = {}));
16080
+ function validationReducer(state, action) {
16081
+ var _state$draftErrors, _state$draftErrors2;
16082
+ switch (action.type) {
16083
+ // Saves cell error into draft errors state.
16084
+ case ValidationActionType.SET_CELL_ERROR:
16085
+ return {
16086
+ ...state,
16087
+ draftErrors: {
16088
+ ...state.draftErrors,
16089
+ [action.payload.rowId]: {
16090
+ ...((_state$draftErrors = state.draftErrors) === null || _state$draftErrors === void 0 ? void 0 : _state$draftErrors[action.payload.rowId]),
16091
+ [action.payload.cellId]: action.payload.error
16092
+ }
16093
+ }
16094
+ };
16095
+ // Saves row errors into draft errors state.
16096
+ case ValidationActionType.SET_ROW_ERROR:
16097
+ return {
16098
+ ...state,
16099
+ draftErrors: {
16100
+ ...state.draftErrors,
16101
+ [action.payload.rowId]: {
16102
+ ...((_state$draftErrors2 = state.draftErrors) === null || _state$draftErrors2 === void 0 ? void 0 : _state$draftErrors2[action.payload.rowId]),
16103
+ ...action.payload.errors
16104
+ }
16105
+ }
16106
+ };
16107
+ // Promotes errors from draft into confirmed state (When user moves to next/prev row)
16108
+ case ValidationActionType.CONFIRN_ERRORS:
16109
+ {
16110
+ const newDraftErrors = {
16111
+ ...state.draftErrors
16112
+ };
16113
+ const confirmedRow = {
16114
+ ...newDraftErrors[action.payload.rowId]
16115
+ };
16116
+ delete newDraftErrors[action.payload.rowId];
16117
+ return {
16118
+ draftErrors: newDraftErrors,
16119
+ errors: {
16120
+ ...state.errors,
16121
+ [action.payload.rowId]: confirmedRow
16122
+ }
16123
+ };
16124
+ }
16125
+ // Resets all errors for particular row or cell if cell id is passed.
16126
+ // We need to reset both confirmed and draft errors, for the situations,
16127
+ // when user is getting back to the row wich already had error.
16128
+ case ValidationActionType.RESET_ERRORS:
16129
+ {
16130
+ const newDraftErrors = _resetErrors(state.draftErrors, action.payload.rowId, action.payload.cellId);
16131
+ const newErrors = _resetErrors(state.errors, action.payload.rowId, action.payload.cellId);
16132
+ return {
16133
+ errors: newErrors,
16134
+ draftErrors: newDraftErrors
16135
+ };
16136
+ }
16137
+ default:
16138
+ return state;
16139
+ }
16140
+ }
16141
+
16142
+ function usePauseShortcuts() {
16143
+ const [isShortcutsPaused, setIsShortcutsPaused] = React__default.useState(false);
16144
+ return {
16145
+ isPaused: isShortcutsPaused,
16146
+ pause: setIsShortcutsPaused
16147
+ };
16148
+ }
16149
+
16150
+ function useTable$1(props) {
16151
+ var _ref, _defaultSettings$colu, _defaultSettings$rowH, _props$length;
16152
+ // options
16153
+ const options = useTablePreset(props);
16154
+ const tableOptions = {
16155
+ enableColumnFilters: options.enableFiltering,
16156
+ enableColumnResizing: options.enableColumnResizing,
16157
+ enableExpanding: options.enableRowExpansion,
16158
+ enableGlobalFilter: options.enableSearch,
16159
+ enableHiding: options.enableColumnHiding,
16160
+ enableRowSelection: options.enableRowSelection,
16161
+ enableMultiRowSelection: !options.enableRowSelectionSingle,
16162
+ enableSorting: options.enableSorting
16163
+ };
16164
+ // resizing
16165
+ if (tableOptions.enableColumnResizing) {
16166
+ tableOptions.columnResizeMode = 'onChange';
16167
+ }
16168
+ // filtering
16169
+ if (tableOptions.enableColumnFilters) {
16170
+ if (!props.onFilter) {
16171
+ tableOptions.filterFns = {
16172
+ tacoFilter: (row, columnId, filter) => columnFilterFn(row.getValue(columnId), filter)
16173
+ };
16174
+ tableOptions.getFilteredRowModel = reactTable$1.getFilteredRowModel();
15722
16175
  }
15723
- };
15724
- const handleMouseEnter = () => {
15725
- // When user moving mouse to fast, then some of the rows are getting stuck in hover state,
15726
- // because mouseleave event never got triggered, to avoid this to happen we're saving the index of last hovered row,
15727
- // so that we can unhover it when new row got hovered, and saving it in a variable outside of react to save in performance,
15728
- // since it would be very performance heavy to use state which is bound to mouse events.
15729
- if (previouslyHoveredIndex !== undefined) {
15730
- if (previouslyHoveredIndex !== index) {
15731
- unhoverPreviousRow(tableRef);
15732
- previouslyHoveredIndex = index;
16176
+ // we don't tableOptions.manualFiltering = true; because it breaks global filtering, server filtering still works :shrug:
16177
+ }
16178
+ // search
16179
+ if (tableOptions.enableGlobalFilter) {
16180
+ // search is always client side, since we call loadAll when searching
16181
+ tableOptions.globalFilterFn = (row, columnId, searchQuery) => {
16182
+ try {
16183
+ if (row.original) {
16184
+ const cell = row.getAllCells().find(cell => cell.column.id === columnId);
16185
+ const columnMeta = cell === null || cell === void 0 ? void 0 : cell.column.columnDef.meta;
16186
+ if (cell && cell.column.getIsVisible() && columnMeta !== null && columnMeta !== void 0 && columnMeta.enableSearch) {
16187
+ const cellValue = getCellValueAsString(row.original[columnId], columnMeta === null || columnMeta === void 0 ? void 0 : columnMeta.dataType);
16188
+ if (cellValue !== undefined) {
16189
+ return globalFilterFn(cellValue, searchQuery);
16190
+ }
16191
+ }
16192
+ return false;
16193
+ }
16194
+ } catch {
16195
+ //
15733
16196
  }
16197
+ return false;
16198
+ };
16199
+ tableOptions.getFilteredRowModel = reactTable$1.getFilteredRowModel();
16200
+ tableOptions.getColumnCanGlobalFilter = column => {
16201
+ var _column$columnDef$met;
16202
+ return (_column$columnDef$met = column.columnDef.meta.enableSearch) !== null && _column$columnDef$met !== void 0 ? _column$columnDef$met : true;
16203
+ };
16204
+ }
16205
+ // sorting
16206
+ if (options.enableSorting) {
16207
+ if (props.onSort) {
16208
+ tableOptions.manualSorting = true;
16209
+ // onSort is called as a listener to let the consumer update their data, so we don't use onSortingChange
15734
16210
  } else {
15735
- previouslyHoveredIndex = index;
16211
+ tableOptions.getSortedRowModel = reactTable$1.getSortedRowModel();
15736
16212
  }
15737
- setIsHovered(true);
15738
- };
15739
- const handleMouseLeave = () => {
15740
- if (previouslyHoveredIndex === index) {
15741
- previouslyHoveredIndex = undefined;
16213
+ }
16214
+ const [defaultSettings, setSettings] = useSettings(props.id, props.defaultSettings, props.onChangeSettings);
16215
+ // custom features
16216
+ const columnFreezing = useColumnFreezing( // temporarily see if deprecated frozenColumnCount is there
16217
+ (_ref = (_defaultSettings$colu = defaultSettings.columnFreezingIndex) !== null && _defaultSettings$colu !== void 0 ? _defaultSettings$colu : defaultSettings === null || defaultSettings === void 0 ? void 0 : defaultSettings.frozenColumnCount) !== null && _ref !== void 0 ? _ref : props.defaultColumnFreezingIndex, options);
16218
+ const columnOrdering = useColumnOrdering(options);
16219
+ const currentRow = useCurrentRow(props.defaultCurrentRowIndex);
16220
+ const validation = useValidation(props.onCellValidate, props.onRowValidate);
16221
+ const editing = useEditing(options.enableEditing, validation, props.onSave);
16222
+ const fontSize = useFontSize(options.enableFontSize, defaultSettings.fontSize);
16223
+ const hoverState = usePauseHoverState();
16224
+ const printing = usePrinting(options.enablePrinting, props.loadAll, defaultSettings.showWarningWhenPrintingLargeDataset);
16225
+ const rowActions = useRowActions$1(props.actionsForRow, props.actionsForRowLength);
16226
+ const rowClick = useRowClick(props.onRowClick);
16227
+ const rowDrag = useRowDrag(options.enableRowDrag);
16228
+ const rowDrop = useRowDrop(options.enableRowDrop, props.onRowDrop);
16229
+ const rowGoto = useRowGoto(options.enableRowGoto, props.onRowGoto);
16230
+ const rowHeight = useRowHeight(options.enableRowHeight, // temporarily see if deprecated rowDensity is there
16231
+ (_defaultSettings$rowH = defaultSettings.rowHeight) !== null && _defaultSettings$rowH !== void 0 ? _defaultSettings$rowH : defaultSettings === null || defaultSettings === void 0 ? void 0 : defaultSettings.rowDensity);
16232
+ const rowSelection = useRowSelection();
16233
+ const search = useSearch(options.enableSearch, defaultSettings.excludeUnmatchedRecordsInSearch, props.loadAll);
16234
+ const shortcutsState = usePauseShortcuts();
16235
+ // columns
16236
+ const {
16237
+ columns,
16238
+ defaultColumnSizing,
16239
+ defaultColumnVisibility,
16240
+ defaultSorting
16241
+ } = useConvertChildrenToColumns(props, options, editing);
16242
+ // built-in features
16243
+ const initialState = React__default.useMemo(() => {
16244
+ var _defaultSettings$colu2, _defaultSettings$colu3, _props$defaultSetting, _props$defaultSetting3;
16245
+ const sanitizeSortedColumns = column => columns.find(definedColumn => definedColumn.id === column.id);
16246
+ const state = {
16247
+ columnOrder: ensureOrdering(columns, defaultSettings.columnOrder),
16248
+ columnSizing: (_defaultSettings$colu2 = defaultSettings.columnSizing) !== null && _defaultSettings$colu2 !== void 0 ? _defaultSettings$colu2 : defaultColumnSizing,
16249
+ columnVisibility: (_defaultSettings$colu3 = defaultSettings.columnVisibility) !== null && _defaultSettings$colu3 !== void 0 ? _defaultSettings$colu3 : defaultColumnVisibility,
16250
+ sorting: defaultSettings.sorting ? defaultSettings.sorting.filter(sanitizeSortedColumns) : defaultSorting
16251
+ };
16252
+ // we don't save these outside the table, but they need to be here for print to inherit them - see PrintButton.tsx
16253
+ if ((_props$defaultSetting = props.defaultSettings) !== null && _props$defaultSetting !== void 0 && _props$defaultSetting.columnFilters) {
16254
+ var _props$defaultSetting2;
16255
+ state.columnFilters = (_props$defaultSetting2 = props.defaultSettings) === null || _props$defaultSetting2 === void 0 ? void 0 : _props$defaultSetting2.columnFilters;
15742
16256
  }
15743
- setIsHovered(false);
16257
+ if ((_props$defaultSetting3 = props.defaultSettings) !== null && _props$defaultSetting3 !== void 0 && _props$defaultSetting3.globalFilter) {
16258
+ var _props$defaultSetting4;
16259
+ state.globalFilter = (_props$defaultSetting4 = props.defaultSettings) === null || _props$defaultSetting4 === void 0 ? void 0 : _props$defaultSetting4.globalFilter;
16260
+ }
16261
+ return state;
16262
+ }, []);
16263
+ const getSettings = () => {
16264
+ const state = table.getState();
16265
+ return {
16266
+ columnFreezingIndex: columnFreezing.frozenColumnIndex,
16267
+ columnOrder: columnOrdering.isEnabled ? state.columnOrder : undefined,
16268
+ columnSizing: table.options.enableColumnResizing ? state.columnSizing : undefined,
16269
+ columnVisibility: table.options.enableHiding ? state.columnVisibility : undefined,
16270
+ excludeUnmatchedRecordsInSearch: search.excludeUnmatchedResults,
16271
+ fontSize: fontSize.isEnabled ? fontSize.size : undefined,
16272
+ rowHeight: rowHeight.isEnabled ? rowHeight.height : undefined,
16273
+ showWarningWhenPrintingLargeDataset: printing.printWarningDialogVisibility,
16274
+ sorting: state.sorting
16275
+ };
15744
16276
  };
15745
- const [isDraggedOver, dropTargetProps] = useDropTarget(event => onDrop === null || onDrop === void 0 ? void 0 : onDrop(event, row.original));
15746
- const className = cn('group/row contents',
15747
- // resizing column requires dragging, which means the mouse might (on rare occasions) move over rows and trigger hover state
15748
- // that in turn triggers rendering of e.g. row actions, which could cause janky ui - so don't allow mouse interaction when resizing
15749
- '[[role="table"][data-resizing="true"]_&]:pointer-events-none', {
15750
- 'hover:cursor-pointer': typeof onClick === 'function'
16277
+ const table = reactTable$1.useReactTable({
16278
+ data: props.data,
16279
+ columns,
16280
+ getCoreRowModel: reactTable$1.getCoreRowModel(),
16281
+ initialState,
16282
+ ...tableOptions,
16283
+ //debugAll: true,
16284
+ meta: {
16285
+ columnFreezing,
16286
+ columnOrdering,
16287
+ currentRow,
16288
+ editing,
16289
+ enableFooter: options.enableFooter,
16290
+ fontSize,
16291
+ getSettings,
16292
+ hoverState,
16293
+ isPrinting: props.id.endsWith('_print'),
16294
+ isUsingServer: !!props.loadPage,
16295
+ printing,
16296
+ rowActions: rowActions,
16297
+ rowClick: rowClick,
16298
+ rowDrag,
16299
+ rowDrop,
16300
+ rowGoto,
16301
+ rowHeight,
16302
+ rowSelection,
16303
+ search,
16304
+ shortcutsState,
16305
+ validation
16306
+ }
15751
16307
  });
15752
- return /*#__PURE__*/React__default.createElement("div", Object.assign({}, attributes, onDrop ? dropTargetProps : undefined, {
15753
- className: className,
15754
- "data-row-index": index,
15755
- "data-dragged-over": isDraggedOver,
15756
- onClick: handleClick,
15757
- onClickCapture: handleClickCapture,
15758
- onMouseEnter: handleMouseEnter,
15759
- onMouseLeave: handleMouseLeave,
15760
- role: "row",
15761
- ref: ref
15762
- }));
15763
- });
16308
+ // listeners
16309
+ useCurrentRowListener(table);
16310
+ useEditingStateListener(table);
16311
+ useFilteringStateListener(table, props.onFilter);
16312
+ useRowSelectionListener(table, props.onRowSelect);
16313
+ useSettingsStateListener(table, setSettings);
16314
+ useShortcutsListener(table, props.shortcuts);
16315
+ useServerLoadingListener(table, props.loadPage);
16316
+ useSortingStateListener(table, props.onSort);
16317
+ return {
16318
+ table,
16319
+ length: (_props$length = props.length) !== null && _props$length !== void 0 ? _props$length : props.data.length
16320
+ };
16321
+ }
15764
16322
 
15765
16323
  const ExpandedRow = /*#__PURE__*/React__default.memo(function ExpandedRow(props) {
15766
16324
  var _renderer;
@@ -15970,6 +16528,7 @@ function Search$2(props) {
15970
16528
  const tableMeta = table.options.meta;
15971
16529
  const [query, setQuery] = React__default.useState(tableMeta.search.query);
15972
16530
  const [loading, setLoading] = React__default.useState(LoadingState.Incomplete);
16531
+ const [rowIdToNavigate, setRowIdToNavigate] = React__default.useState(null);
15973
16532
  const scrollTo = rowIndex => scrollToIndex(rowIndex, {
15974
16533
  align: 'center'
15975
16534
  });
@@ -15981,6 +16540,12 @@ function Search$2(props) {
15981
16540
  scrollTo(firstRowIndex);
15982
16541
  }
15983
16542
  }, [tableMeta.search.query, tableMeta.search.excludeUnmatchedResults, table.getRowModel().rows.length, JSON.stringify(table.getState().sorting), JSON.stringify(table.getState().columnVisibility), loading]);
16543
+ // Reseting internal search state if search.query is changed from the outside.
16544
+ React__default.useEffect(() => {
16545
+ if (tableMeta.search.query !== query) {
16546
+ setQuery(tableMeta.search.query);
16547
+ }
16548
+ }, [tableMeta.search.query]);
15984
16549
  // update the table search and filtering on a debounce
15985
16550
  useDebouncedEffect(() => {
15986
16551
  tableMeta.search.setQuery(query);
@@ -15994,6 +16559,9 @@ function Search$2(props) {
15994
16559
  }, [query]);
15995
16560
  const handleFocus = function () {
15996
16561
  try {
16562
+ // While Search input is focused, we'll switch into searching mode
16563
+ tableMeta.search.setIsSearching(true);
16564
+ // load all data if that is possible
15997
16565
  const _temp = function () {
15998
16566
  if (tableMeta.search.loadAll && loading === LoadingState.Incomplete) {
15999
16567
  setLoading(LoadingState.Loading);
@@ -16003,15 +16571,48 @@ function Search$2(props) {
16003
16571
  });
16004
16572
  }
16005
16573
  }();
16006
- // load all data if that is possible
16007
16574
  return Promise.resolve(_temp && _temp.then ? _temp.then(function () {}) : void 0);
16008
16575
  } catch (e) {
16009
16576
  return Promise.reject(e);
16010
16577
  }
16011
16578
  };
16579
+ const handleBlur = () => {
16580
+ // As soon as search input loose a focus, we'll turn of searching mode.
16581
+ tableMeta.search.setIsSearching(false);
16582
+ };
16012
16583
  const handleChange = query => {
16013
16584
  setQuery(String(query !== null && query !== void 0 ? query : ''));
16014
16585
  };
16586
+ const handleClear = () => {
16587
+ var _rows$rowIndex;
16588
+ const [rowIndex, cellIndex] = tableMeta.search.highlightedColumnIndexes[tableMeta.search.currentHighlightColumnIndex || 0];
16589
+ const rows = table.getRowModel().rows;
16590
+ const rowId = ((_rows$rowIndex = rows[rowIndex]) === null || _rows$rowIndex === void 0 ? void 0 : _rows$rowIndex.id) || null;
16591
+ tableMeta.search.setQuery('');
16592
+ // Need to save row id and cell index, to be able to find the row in the table with updated indexes, after global filter will be reset.
16593
+ lastCellIndex.value = String(cellIndex);
16594
+ setRowIdToNavigate(rowId);
16595
+ };
16596
+ const handleKeyDown = event => {
16597
+ if (event.key === 'Escape') {
16598
+ handleClear();
16599
+ event.preventDefault();
16600
+ }
16601
+ };
16602
+ const {
16603
+ globalFilter
16604
+ } = table.getState();
16605
+ React__default.useEffect(() => {
16606
+ // need to wait when table global filter will be reset and rows will be re-rendered
16607
+ if (rowIdToNavigate !== null && !globalFilter) {
16608
+ const rows = table.getRowModel().rows;
16609
+ const rowIndex = rows.findIndex(row => row.id === rowIdToNavigate);
16610
+ tableMeta.search.setIsSearching(false);
16611
+ tableMeta.currentRow.setCurrentRowIndex(rowIndex);
16612
+ scrollTo(rowIndex);
16613
+ setRowIdToNavigate(null);
16614
+ }
16615
+ }, [rowIdToNavigate, globalFilter]);
16015
16616
  const handleToggleExcludeUnmatchedResults = enabled => {
16016
16617
  tableMeta.search.toggleExcludeUnmatchedResults(enabled);
16017
16618
  if (enabled) {
@@ -16061,6 +16662,9 @@ function Search$2(props) {
16061
16662
  onClickFindNext: handleNextResult,
16062
16663
  onChange: handleChange,
16063
16664
  onFocus: handleFocus,
16665
+ onBlur: handleBlur,
16666
+ onKeyDown: handleKeyDown,
16667
+ onClear: handleClear,
16064
16668
  placeholder: texts.table3.search.placeholder,
16065
16669
  settingsContent: settings,
16066
16670
  ref: ref,
@@ -16513,7 +17117,7 @@ function FiltersButton(props) {
16513
17117
  (_ref$current = ref.current) === null || _ref$current === void 0 ? void 0 : _ref$current.click();
16514
17118
  });
16515
17119
  // state, since we "apply" filters
16516
- const [filters, setFilters] = React__default.useState(table.getState().columnFilters);
17120
+ const [filters, setFilters] = React__default.useState(appliedFilters);
16517
17121
  const [placeholderCount, setPlaceholderCount] = React__default.useState(1);
16518
17122
  // filters
16519
17123
  const handleChangeFilter = (currentId, filter) => {
@@ -16570,6 +17174,13 @@ function FiltersButton(props) {
16570
17174
  setFilters([]);
16571
17175
  setPlaceholderCount(1);
16572
17176
  };
17177
+ // Because filters can be reset from outside
17178
+ React__default.useEffect(() => {
17179
+ if (appliedFilters.length === 0) {
17180
+ setFilters([]);
17181
+ setPlaceholderCount(1);
17182
+ }
17183
+ }, [appliedFilters]);
16573
17184
  const buttonProps = {
16574
17185
  'aria-label': texts.table3.filters.tooltip,
16575
17186
  className: cn({
@@ -16683,7 +17294,8 @@ const PRINT_STYLES = `
16683
17294
  overflow-y: hidden !important;
16684
17295
  }
16685
17296
 
16686
- [role="table"] [role="columnheader"] {
17297
+ // all column headers except column group column header
17298
+ [role="table"] [role="columnheader"]:not([data-taco='table3-column-group']) {
16687
17299
  border-bottom-width: 1px !important;
16688
17300
  }
16689
17301
 
@@ -17402,10 +18014,10 @@ function SettingsButton(props) {
17402
18014
  icon: "sliders",
17403
18015
  menu: popoverElement ? undefined : menuProps => /*#__PURE__*/React__default.createElement(Menu$1, Object.assign({}, menuProps), /*#__PURE__*/React__default.createElement(Menu$1.Content, {
17404
18016
  align: "end"
17405
- }, table.options.enableHiding || tableMeta.columnOrdering.isEnabled ? /*#__PURE__*/React__default.createElement(React__default.Fragment, null, /*#__PURE__*/React__default.createElement(Menu$1.Item, {
18017
+ }, table.options.enableHiding || tableMeta.columnOrdering.isEnabled ? /*#__PURE__*/React__default.createElement(Menu$1.Item, {
17406
18018
  icon: "columns",
17407
18019
  onClick: () => setPopover('columnSettings')
17408
- }, texts.table3.columnSettings.button), /*#__PURE__*/React__default.createElement(Menu$1.Separator, null)) : null, tableMeta.rowHeight.isEnabled ? /*#__PURE__*/React__default.createElement(Menu$1.Item, {
18020
+ }, texts.table3.columnSettings.button) : null, tableMeta.rowHeight.isEnabled || tableMeta.fontSize.isEnabled ? /*#__PURE__*/React__default.createElement(Menu$1.Separator, null) : null, tableMeta.rowHeight.isEnabled ? /*#__PURE__*/React__default.createElement(Menu$1.Item, {
17409
18021
  icon: `height-${tableMeta.rowHeight.height}`,
17410
18022
  subMenu: () => /*#__PURE__*/React__default.createElement(RowHeight, {
17411
18023
  table: table
@@ -17465,7 +18077,7 @@ function isSettingsVisible(props) {
17465
18077
  table
17466
18078
  } = props;
17467
18079
  const tableMeta = table.options.meta;
17468
- return tableMeta.fontSize.isEnabled || tableMeta.rowHeight.isEnabled;
18080
+ return tableMeta.fontSize.isEnabled || tableMeta.rowHeight.isEnabled || tableMeta.columnOrdering.isEnabled;
17469
18081
  }
17470
18082
  function isToolbarVisible(props) {
17471
18083
  const {
@@ -17621,6 +18233,149 @@ function useHeaderOffsetStyle(tableId, table) {
17621
18233
  return style;
17622
18234
  }
17623
18235
 
18236
+ function ErrorAlert(props) {
18237
+ var _column$columnDef$met;
18238
+ const {
18239
+ table,
18240
+ tableRef,
18241
+ scrollToIndex,
18242
+ rowIdentifier
18243
+ } = props;
18244
+ const tableMeta = table.options.meta;
18245
+ const errors = tableMeta.validation.errors;
18246
+ const errorsRowIds = errors ? Object.keys(errors) : [];
18247
+ const rows = table.getRowModel().rows;
18248
+ const coreRows = table.getCoreRowModel().rows;
18249
+ const {
18250
+ texts
18251
+ } = useLocalization();
18252
+ const [resetFiltersConfirmationOpen, setResetFiltersConfirmationOpen] = React__default.useState(false);
18253
+ const [internalRowId, setInternalRowId] = React__default.useState(null);
18254
+ const [internalRowIndex, setInternalRowIndex] = React__default.useState(null);
18255
+ const [isFiltersReset, setIsFiltersReset] = React__default.useState(false);
18256
+ const columns = table.getAllFlatColumns();
18257
+ const column = columns.find(column => column.id === rowIdentifier);
18258
+ const rowIdentifierHeader = column === null || column === void 0 ? void 0 : (_column$columnDef$met = column.columnDef.meta) === null || _column$columnDef$met === void 0 ? void 0 : _column$columnDef$met.header;
18259
+ // Find and focus first invalid cell
18260
+ const navigateToFirstInvalidCell = () => {
18261
+ var _tableRef$current;
18262
+ const firstInvalidCell = (_tableRef$current = tableRef.current) === null || _tableRef$current === void 0 ? void 0 : _tableRef$current.querySelector('[role="row"][data-current="true"] [role="cell"][data-invalid="true"]');
18263
+ const firstInvalidElement = firstInvalidCell === null || firstInvalidCell === void 0 ? void 0 : firstInvalidCell.querySelector(focusableSelector);
18264
+ if (firstInvalidElement) {
18265
+ firstInvalidElement === null || firstInvalidElement === void 0 ? void 0 : firstInvalidElement.focus();
18266
+ lastCellIndex.value = firstInvalidCell === null || firstInvalidCell === void 0 ? void 0 : firstInvalidCell.getAttribute('data-column-index');
18267
+ }
18268
+ };
18269
+ // Navigate to row and focus first invalid cell
18270
+ const navigateToRow = rowIndex => {
18271
+ tableMeta.currentRow.setCurrentRowIndex(rowIndex);
18272
+ scrollToIndex(rowIndex, {
18273
+ align: 'center'
18274
+ });
18275
+ lastCellIndex.value = undefined;
18276
+ // Need to request animation frame here, because newly selected row is not rendered yet.
18277
+ requestAnimationFrame(() => {
18278
+ navigateToFirstInvalidCell();
18279
+ });
18280
+ };
18281
+ // When internal row index is changed after click on row link, we should navigate to the row.
18282
+ React__default.useEffect(() => {
18283
+ if (internalRowIndex !== null && internalRowIndex >= 0) {
18284
+ navigateToRow(internalRowIndex);
18285
+ }
18286
+ }, [internalRowIndex]);
18287
+ // When filters are reset, we're able to get the real row index by rowId
18288
+ React__default.useEffect(() => {
18289
+ if (isFiltersReset) {
18290
+ const rowIndex = rows.findIndex(row => row.id === internalRowId);
18291
+ if (rowIndex === -1) {
18292
+ return;
18293
+ }
18294
+ setInternalRowIndex(rowIndex);
18295
+ }
18296
+ }, [isFiltersReset]);
18297
+ const onRowNumberClick = React__default.useCallback(rowId => {
18298
+ // When row is hidden due filtering it will not be present in rows (but it still will be present in coreRows)
18299
+ const foundIndex = rows.findIndex(row => row.id === rowId);
18300
+ if (foundIndex === -1) {
18301
+ setIsFiltersReset(false);
18302
+ setResetFiltersConfirmationOpen(true);
18303
+ // Since row indexes changed due filtering, we need to save row id, so that we can find it when filters will be reset
18304
+ setInternalRowId(rowId);
18305
+ return;
18306
+ }
18307
+ // In cases when user clicked on a row link multiple times we still need to navigate to the row, and focus the cell,
18308
+ // because row/cell will loose focus on next click, but row index will not change.
18309
+ if (foundIndex === internalRowIndex) {
18310
+ navigateToRow(foundIndex);
18311
+ } else {
18312
+ setInternalRowIndex(foundIndex);
18313
+ }
18314
+ }, [rows, internalRowIndex]);
18315
+ const onResetFiltersConfirm = () => {
18316
+ setIsFiltersReset(true);
18317
+ };
18318
+ // Getting the row from core rows (ignoring search and filtering)
18319
+ const getCoreRow = React__default.useCallback(rowId => coreRows.find(coreRow => coreRow.id === rowId), [coreRows]);
18320
+ return /*#__PURE__*/React__default.createElement("div", {
18321
+ className: "mb-4"
18322
+ }, errorsRowIds.length ? /*#__PURE__*/React__default.createElement(Alert, {
18323
+ state: "error",
18324
+ className: "mb-1"
18325
+ }, /*#__PURE__*/React__default.createElement(React__default.Fragment, null, /*#__PURE__*/React__default.createElement("b", null, errorsRowIds.length, " ", texts.table3.validation.alert.unsavedEntries(errorsRowIds.length)), ' '), rowIdentifierHeader || texts.table3.validation.index, ' ', errorsRowIds.map((rowId, index) => {
18326
+ const coreRow = getCoreRow(rowId);
18327
+ return /*#__PURE__*/React__default.createElement(React__default.Fragment, null, /*#__PURE__*/React__default.createElement(Button$1, {
18328
+ key: rowId,
18329
+ className: "!min-h-[theme(spacing.2)] !min-w-[theme(spacing.2)] !px-1",
18330
+ appearance: "discrete",
18331
+ onClick: () => {
18332
+ onRowNumberClick(rowId);
18333
+ }
18334
+ }, rowIdentifier ? coreRow === null || coreRow === void 0 ? void 0 : coreRow.original[rowIdentifier] : coreRow === null || coreRow === void 0 ? void 0 : coreRow.index), /*#__PURE__*/React__default.createElement("span", {
18335
+ key: `${rowId}_comma`
18336
+ }, index < errorsRowIds.length - 1 ? ',' : ''));
18337
+ }), texts.table3.validation.alert.incompleteAndHavntBeenSaved(errorsRowIds.length)) : null, /*#__PURE__*/React__default.createElement(FilterResetDialog, {
18338
+ open: resetFiltersConfirmationOpen,
18339
+ onClose: () => {
18340
+ setResetFiltersConfirmationOpen(false);
18341
+ },
18342
+ onConfirm: onResetFiltersConfirm,
18343
+ table: table
18344
+ }));
18345
+ }
18346
+ function FilterResetDialog(props) {
18347
+ const {
18348
+ open,
18349
+ onClose,
18350
+ onConfirm,
18351
+ table
18352
+ } = props;
18353
+ const tableMeta = table.options.meta;
18354
+ const {
18355
+ texts
18356
+ } = useLocalization();
18357
+ const resetFilters = React__default.useCallback(() => {
18358
+ tableMeta.search.setQuery('');
18359
+ table.resetGlobalFilter();
18360
+ table.resetColumnFilters();
18361
+ }, [table, tableMeta.search]);
18362
+ const handleConfirmClick = () => {
18363
+ resetFilters();
18364
+ onConfirm();
18365
+ onClose();
18366
+ };
18367
+ return /*#__PURE__*/React__default.createElement(Dialog, {
18368
+ open: open,
18369
+ onClose: onClose,
18370
+ size: "xs"
18371
+ }, /*#__PURE__*/React__default.createElement(Dialog.Content, {
18372
+ "aria-label": "Create a new account"
18373
+ }, /*#__PURE__*/React__default.createElement(Dialog.Title, null, texts.table3.validation.resetFiltersDialog.title), /*#__PURE__*/React__default.createElement("p", null, texts.table3.validation.resetFiltersDialog.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, null, texts.table3.validation.resetFiltersDialog.cancel)), /*#__PURE__*/React__default.createElement(Button$1, {
18374
+ appearance: "primary",
18375
+ onClick: handleConfirmClick
18376
+ }, texts.table3.validation.resetFiltersDialog.confirm)))));
18377
+ }
18378
+
17624
18379
  function useTable3DataLoader(fetch, fetchAll, options = {
17625
18380
  pageSize: 100
17626
18381
  }) {
@@ -17761,7 +18516,8 @@ const Table$1 = /*#__PURE__*/fixedForwardRef(function Table3(props, ref) {
17761
18516
  emptyState: EmptyState,
17762
18517
  customSettings,
17763
18518
  toolbarLeft,
17764
- toolbarRight
18519
+ toolbarRight,
18520
+ defaultCurrentRowIndex
17765
18521
  } = props;
17766
18522
  const internalRef = useMergedRef(ref);
17767
18523
  const {
@@ -17782,6 +18538,20 @@ const Table$1 = /*#__PURE__*/fixedForwardRef(function Table3(props, ref) {
17782
18538
  const tableMeta = table.options.meta;
17783
18539
  const state = table.getState();
17784
18540
  const bodyRef = React__default.useRef(null);
18541
+ React__default.useEffect(() => {
18542
+ // On a very first render, the tanstack table rendered without any rows,
18543
+ // so we delaying default row scrolling logic with using of requestAnimation frame
18544
+ const animationFrameId = requestAnimationFrame(() => {
18545
+ if (defaultCurrentRowIndex) {
18546
+ scrollToIndex(defaultCurrentRowIndex, {
18547
+ align: 'center'
18548
+ });
18549
+ }
18550
+ });
18551
+ return () => {
18552
+ cancelAnimationFrame(animationFrameId);
18553
+ };
18554
+ }, []);
17785
18555
  React__default.useEffect(() => {
17786
18556
  const handleKeyDown = event => {
17787
18557
  const target = event.target;
@@ -17789,7 +18559,7 @@ const Table$1 = /*#__PURE__*/fixedForwardRef(function Table3(props, ref) {
17789
18559
  const eventOriginatedFromCombobox = !!target.closest('[role="combobox"]');
17790
18560
  // Don't trigger global shortcuts on the table if event originated from a combobox or if table is
17791
18561
  // outside the dialog
17792
- if (eventOriginatedFromCombobox || dialog && !(dialog !== null && dialog !== void 0 && dialog.contains(internalRef.current))) {
18562
+ if (eventOriginatedFromCombobox || dialog && !(dialog !== null && dialog !== void 0 && dialog.contains(internalRef.current)) || tableMeta.shortcutsState.isPaused) {
17793
18563
  return;
17794
18564
  }
17795
18565
  tableMeta.hoverState.handleKeyDown(event);
@@ -17848,9 +18618,10 @@ const Table$1 = /*#__PURE__*/fixedForwardRef(function Table3(props, ref) {
17848
18618
  const columnFreezingStyle = useColumnFreezingStyle(props.id, table);
17849
18619
  const headerOffsetStyle = useHeaderOffsetStyle(props.id, table);
17850
18620
  const isServerLoadingAndNotReady = tableMeta.isUsingServer && props.length === undefined;
18621
+ const isPrinting = tableMeta.isPrinting;
17851
18622
  return /*#__PURE__*/React__default.createElement(React__default.Fragment, null, columnFreezingStyle ? /*#__PURE__*/React__default.createElement("style", {
17852
18623
  "data-taco": "table3-column-freezing-styles"
17853
- }, columnFreezingStyle) : null, headerOffsetStyle ? /*#__PURE__*/React__default.createElement("style", {
18624
+ }, columnFreezingStyle) : null, headerOffsetStyle && !isPrinting ? /*#__PURE__*/React__default.createElement("style", {
17854
18625
  "data-taco": "table3-column-header-offset-styles"
17855
18626
  }, headerOffsetStyle) : null, /*#__PURE__*/React__default.createElement(Toolbar, {
17856
18627
  table: table,
@@ -17860,6 +18631,11 @@ const Table$1 = /*#__PURE__*/fixedForwardRef(function Table3(props, ref) {
17860
18631
  right: toolbarRight,
17861
18632
  customSettings: customSettings,
17862
18633
  scrollToIndex: scrollToIndex
18634
+ }), /*#__PURE__*/React__default.createElement(ErrorAlert, {
18635
+ table: table,
18636
+ tableRef: internalRef,
18637
+ scrollToIndex: scrollToIndex,
18638
+ rowIdentifier: props.rowIdentifier
17863
18639
  }), /*#__PURE__*/React__default.createElement("div", {
17864
18640
  className: className,
17865
18641
  id: props.id,
@@ -17910,7 +18686,9 @@ const Table$1 = /*#__PURE__*/fixedForwardRef(function Table3(props, ref) {
17910
18686
  className: "group/footer contents",
17911
18687
  "data-taco": "table2-footer",
17912
18688
  role: "rowgroup"
17913
- }, table.getFooterGroups().map(footerGroup => /*#__PURE__*/React__default.createElement("div", {
18689
+ },
18690
+ // Render the footer cell only for individual columns, excluding column groups.
18691
+ table.getFooterGroups().slice(0, 1).map(footerGroup => /*#__PURE__*/React__default.createElement("div", {
17914
18692
  className: "contents",
17915
18693
  key: footerGroup.id,
17916
18694
  role: "row"