@economic/taco 2.14.2 → 2.16.0

Sign up to get free protection for your applications and to get access to all the features.
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"