@dreamtree-org/twreact-ui 1.3.0 → 1.3.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (234) hide show
  1. package/DESIGN.md +2 -2
  2. package/README.md +258 -10
  3. package/ai-skills/dreamtree-ui.md +111 -15
  4. package/charts/package.json +5 -0
  5. package/dist/_shared/cn-DPPQUJu1.js +138 -0
  6. package/dist/ai-schema.json +1252 -179
  7. package/dist/charts/index.d.ts +9 -0
  8. package/dist/charts/index.d.ts.map +1 -0
  9. package/dist/charts/index.js +769 -0
  10. package/dist/components/charts/AreaChart.d.ts +4 -0
  11. package/dist/components/charts/AreaChart.d.ts.map +1 -0
  12. package/dist/components/charts/BarChart.d.ts +4 -0
  13. package/dist/components/charts/BarChart.d.ts.map +1 -0
  14. package/dist/components/charts/CartesianChart.d.ts +5 -0
  15. package/dist/components/charts/CartesianChart.d.ts.map +1 -0
  16. package/dist/components/charts/ChartFrame.d.ts +18 -0
  17. package/dist/components/charts/ChartFrame.d.ts.map +1 -0
  18. package/dist/components/charts/DonutChart.d.ts +4 -0
  19. package/dist/components/charts/DonutChart.d.ts.map +1 -0
  20. package/dist/components/charts/LineChart.d.ts +4 -0
  21. package/dist/components/charts/LineChart.d.ts.map +1 -0
  22. package/dist/components/charts/Sparkline.d.ts +5 -0
  23. package/dist/components/charts/Sparkline.d.ts.map +1 -0
  24. package/dist/components/charts/chartTheme.d.ts +26 -0
  25. package/dist/components/charts/chartTheme.d.ts.map +1 -0
  26. package/dist/components/core/Accordion.d.ts.map +1 -1
  27. package/dist/components/core/Button.d.ts.map +1 -1
  28. package/dist/components/core/Checkbox.d.ts.map +1 -1
  29. package/dist/components/core/ColorPicker.d.ts.map +1 -1
  30. package/dist/components/core/DatePicker.d.ts.map +1 -1
  31. package/dist/components/core/DateRangePicker.d.ts.map +1 -1
  32. package/dist/components/core/Form.d.ts.map +1 -1
  33. package/dist/components/core/Input.d.ts.map +1 -1
  34. package/dist/components/core/LocationPicker.d.ts.map +1 -1
  35. package/dist/components/core/Popover.d.ts +4 -0
  36. package/dist/components/core/Popover.d.ts.map +1 -0
  37. package/dist/components/core/PriceRangePicker.d.ts.map +1 -1
  38. package/dist/components/core/ProgressBar.d.ts.map +1 -1
  39. package/dist/components/core/Radio.d.ts.map +1 -1
  40. package/dist/components/core/Rate.d.ts.map +1 -1
  41. package/dist/components/core/Select.d.ts.map +1 -1
  42. package/dist/components/core/Skeleton.d.ts.map +1 -1
  43. package/dist/components/core/Slider.d.ts +4 -0
  44. package/dist/components/core/Slider.d.ts.map +1 -0
  45. package/dist/components/core/SpeechToText.d.ts.map +1 -1
  46. package/dist/components/core/Switch.d.ts.map +1 -1
  47. package/dist/components/core/Table/ActionMenu.d.ts.map +1 -1
  48. package/dist/components/core/Table/ColumnMenu.d.ts +2 -1
  49. package/dist/components/core/Table/ColumnMenu.d.ts.map +1 -1
  50. package/dist/components/core/Table/MobileCard.d.ts +2 -2
  51. package/dist/components/core/Table/MobileCard.d.ts.map +1 -1
  52. package/dist/components/core/Table/Table.d.ts.map +1 -1
  53. package/dist/components/core/Table/TableRow.d.ts +4 -2
  54. package/dist/components/core/Table/TableRow.d.ts.map +1 -1
  55. package/dist/components/core/Tabs.d.ts.map +1 -1
  56. package/dist/components/core/Textarea.d.ts +4 -0
  57. package/dist/components/core/Textarea.d.ts.map +1 -0
  58. package/dist/components/core/ThreeDotPopover.d.ts.map +1 -1
  59. package/dist/components/core/Tooltip.d.ts.map +1 -1
  60. package/dist/components/feedback/Dialog.d.ts.map +1 -1
  61. package/dist/components/feedback/Drawer.d.ts +4 -0
  62. package/dist/components/feedback/Drawer.d.ts.map +1 -0
  63. package/dist/components/feedback/Toast.d.ts +14 -5
  64. package/dist/components/feedback/Toast.d.ts.map +1 -1
  65. package/dist/components/feedback/Tour.d.ts +4 -0
  66. package/dist/components/feedback/Tour.d.ts.map +1 -0
  67. package/dist/components/feedback/TourSpotlight.d.ts +9 -0
  68. package/dist/components/feedback/TourSpotlight.d.ts.map +1 -0
  69. package/dist/components/navigation/Breadcrumbs.d.ts.map +1 -1
  70. package/dist/components/navigation/FootNav.d.ts.map +1 -1
  71. package/dist/components/navigation/Navbar.d.ts.map +1 -1
  72. package/dist/components/navigation/Sidebar.d.ts +8 -2
  73. package/dist/components/navigation/Sidebar.d.ts.map +1 -1
  74. package/dist/components/rich-text/RichTextEditor.d.ts +4 -0
  75. package/dist/components/rich-text/RichTextEditor.d.ts.map +1 -0
  76. package/dist/components/rich-text/RichTextToolbar.d.ts +219 -0
  77. package/dist/components/rich-text/RichTextToolbar.d.ts.map +1 -0
  78. package/dist/components/utility/Badge.d.ts.map +1 -1
  79. package/dist/components/utility/FileUpload.d.ts.map +1 -1
  80. package/dist/components/utility/Sortable.d.ts +4 -0
  81. package/dist/components/utility/Sortable.d.ts.map +1 -0
  82. package/dist/esm/_vendor/object-assign/index.js +99 -0
  83. package/dist/esm/_vendor/prop-types/_vendor/react-is/cjs/react-is.development.js +190 -0
  84. package/dist/esm/_vendor/prop-types/_vendor/react-is/cjs/react-is.production.min.js +26 -0
  85. package/dist/esm/_vendor/prop-types/_vendor/react-is/index.js +19 -0
  86. package/dist/esm/_vendor/prop-types/checkPropTypes.js +115 -0
  87. package/dist/esm/_vendor/prop-types/factoryWithThrowingShims.js +74 -0
  88. package/dist/esm/_vendor/prop-types/factoryWithTypeCheckers.js +625 -0
  89. package/dist/esm/_vendor/prop-types/index.js +30 -0
  90. package/dist/esm/_vendor/prop-types/lib/ReactPropTypesSecret.js +21 -0
  91. package/dist/esm/_vendor/prop-types/lib/has.js +11 -0
  92. package/dist/esm/_virtual/_commonjsHelpers.js +5 -0
  93. package/dist/esm/_virtual/_rollupPluginBabelHelpers.js +329 -0
  94. package/dist/esm/_virtual/index.js +3 -0
  95. package/dist/esm/_virtual/index2.js +3 -0
  96. package/dist/esm/_virtual/react-is.development.js +3 -0
  97. package/dist/esm/_virtual/react-is.production.min.js +3 -0
  98. package/dist/esm/charts/index.js +5 -0
  99. package/dist/esm/components/blocks/AppShell.js +205 -0
  100. package/dist/esm/components/blocks/ConfirmDialog.js +57 -0
  101. package/dist/esm/components/blocks/EmptyState.js +44 -0
  102. package/dist/esm/components/blocks/ErrorState.js +53 -0
  103. package/dist/esm/components/blocks/LoadingState.js +134 -0
  104. package/dist/esm/components/blocks/PageHeader.js +51 -0
  105. package/dist/esm/components/blocks/StatCard.js +79 -0
  106. package/dist/esm/components/blocks/StatusPill.js +55 -0
  107. package/dist/esm/components/charts/AreaChart.js +16 -0
  108. package/dist/esm/components/charts/BarChart.js +16 -0
  109. package/dist/esm/components/charts/CartesianChart.js +250 -0
  110. package/dist/esm/components/charts/ChartFrame.js +170 -0
  111. package/dist/esm/components/charts/DonutChart.js +119 -0
  112. package/dist/esm/components/charts/LineChart.js +16 -0
  113. package/dist/esm/components/charts/Sparkline.js +110 -0
  114. package/dist/esm/components/charts/chartTheme.js +109 -0
  115. package/dist/esm/components/core/Accordion.js +260 -0
  116. package/dist/esm/components/core/Button.js +59 -0
  117. package/dist/esm/components/core/Checkbox.js +188 -0
  118. package/dist/esm/components/core/ColorPicker.js +348 -0
  119. package/dist/esm/components/core/DatePicker.js +436 -0
  120. package/dist/esm/components/core/DateRangePicker.js +494 -0
  121. package/dist/esm/components/core/Form.js +522 -0
  122. package/dist/esm/components/core/Input.js +179 -0
  123. package/dist/esm/components/core/Loader.js +141 -0
  124. package/dist/esm/components/core/LocationPicker.js +161 -0
  125. package/dist/esm/components/core/Popover.js +171 -0
  126. package/dist/esm/components/core/PriceRangePicker.js +376 -0
  127. package/dist/esm/components/core/ProgressBar.js +152 -0
  128. package/dist/esm/components/core/Radio.js +156 -0
  129. package/dist/esm/components/core/Rate.js +197 -0
  130. package/dist/esm/components/core/RoundedTag.js +118 -0
  131. package/dist/esm/components/core/Select.js +857 -0
  132. package/dist/esm/components/core/Skeleton.js +100 -0
  133. package/dist/esm/components/core/Slider.js +134 -0
  134. package/dist/esm/components/core/SpeechToText.js +226 -0
  135. package/dist/esm/components/core/Switch.js +207 -0
  136. package/dist/esm/components/core/Table/ActionMenu.js +251 -0
  137. package/dist/esm/components/core/Table/ColumnMenu.js +55 -0
  138. package/dist/esm/components/core/Table/FieldInput.js +157 -0
  139. package/dist/esm/components/core/Table/MobileCard.js +187 -0
  140. package/dist/esm/components/core/Table/MobileFilters.js +72 -0
  141. package/dist/esm/components/core/Table/Pagination.js +157 -0
  142. package/dist/esm/components/core/Table/Table.js +1533 -0
  143. package/dist/esm/components/core/Table/TableRow.js +254 -0
  144. package/dist/esm/components/core/Table/constants.js +35 -0
  145. package/dist/esm/components/core/Table/helpers.js +124 -0
  146. package/dist/esm/components/core/Table/useClickOutside.js +26 -0
  147. package/dist/esm/components/core/Tabs.js +289 -0
  148. package/dist/esm/components/core/TextToSpeech.js +52 -0
  149. package/dist/esm/components/core/Textarea.js +125 -0
  150. package/dist/esm/components/core/ThreeDotPopover.js +160 -0
  151. package/dist/esm/components/core/Tooltip.js +372 -0
  152. package/dist/esm/components/feedback/Alert.js +96 -0
  153. package/dist/esm/components/feedback/Dialog.js +200 -0
  154. package/dist/esm/components/feedback/Drawer.js +171 -0
  155. package/dist/esm/components/feedback/Toast.js +362 -0
  156. package/dist/esm/components/feedback/Tour.js +214 -0
  157. package/dist/esm/components/feedback/TourSpotlight.js +71 -0
  158. package/dist/esm/components/navigation/Breadcrumbs.js +75 -0
  159. package/dist/esm/components/navigation/Dropdown.js +53 -0
  160. package/dist/esm/components/navigation/FootNav.js +51 -0
  161. package/dist/esm/components/navigation/Navbar.js +437 -0
  162. package/dist/esm/components/navigation/Sidebar.js +567 -0
  163. package/dist/esm/components/rich-text/RichTextEditor.js +244 -0
  164. package/dist/esm/components/rich-text/RichTextToolbar.js +397 -0
  165. package/dist/esm/components/utility/Avatar.js +89 -0
  166. package/dist/esm/components/utility/Badge.js +47 -0
  167. package/dist/esm/components/utility/Card.js +85 -0
  168. package/dist/esm/components/utility/Carousel.js +97 -0
  169. package/dist/esm/components/utility/Condition.js +9 -0
  170. package/dist/esm/components/utility/FileUpload.js +177 -0
  171. package/dist/esm/components/utility/Pagination.js +111 -0
  172. package/dist/esm/components/utility/Sortable.js +190 -0
  173. package/dist/esm/components/utility/Stepper.js +101 -0
  174. package/dist/esm/hooks/useApi.js +169 -0
  175. package/dist/esm/hooks/useControllableState.js +32 -0
  176. package/dist/esm/hooks/useFocusTrap.js +85 -0
  177. package/dist/esm/hooks/useLatestRef.js +20 -0
  178. package/dist/esm/hooks/useMixins.js +100 -0
  179. package/dist/esm/hooks/useScrollLock.js +26 -0
  180. package/dist/esm/hooks/useSliderValues.js +135 -0
  181. package/dist/esm/hooks/useSortable.js +188 -0
  182. package/dist/esm/hooks/useTheme.js +53 -0
  183. package/dist/esm/hooks/useTourTarget.js +92 -0
  184. package/dist/esm/index.js +65 -0
  185. package/dist/esm/rich-text/index.js +1 -0
  186. package/dist/esm/store/index.js +26 -0
  187. package/dist/esm/store/store.js +107 -0
  188. package/dist/esm/store/storeSlice.js +45 -0
  189. package/dist/esm/utils/cn.js +11 -0
  190. package/dist/esm/utils/emitter.js +169 -0
  191. package/dist/esm/utils/helpers.js +161 -0
  192. package/dist/esm/utils/position.js +134 -0
  193. package/dist/hooks/useApi.d.ts +2 -1
  194. package/dist/hooks/useApi.d.ts.map +1 -1
  195. package/dist/hooks/useControllableState.d.ts +11 -0
  196. package/dist/hooks/useControllableState.d.ts.map +1 -0
  197. package/dist/hooks/useFocusTrap.d.ts +15 -0
  198. package/dist/hooks/useFocusTrap.d.ts.map +1 -0
  199. package/dist/hooks/useLatestRef.d.ts +8 -0
  200. package/dist/hooks/useLatestRef.d.ts.map +1 -0
  201. package/dist/hooks/useMixins.d.ts.map +1 -1
  202. package/dist/hooks/useScrollLock.d.ts +2 -0
  203. package/dist/hooks/useScrollLock.d.ts.map +1 -0
  204. package/dist/hooks/useSliderValues.d.ts +43 -0
  205. package/dist/hooks/useSliderValues.d.ts.map +1 -0
  206. package/dist/hooks/useSortable.d.ts +32 -0
  207. package/dist/hooks/useSortable.d.ts.map +1 -0
  208. package/dist/hooks/useTheme.d.ts.map +1 -1
  209. package/dist/hooks/useTourTarget.d.ts +15 -0
  210. package/dist/hooks/useTourTarget.d.ts.map +1 -0
  211. package/dist/index.css +1 -1
  212. package/dist/index.d.ts +8 -2
  213. package/dist/index.esm.css +1 -1
  214. package/dist/index.esm.js +4817 -2216
  215. package/dist/index.js +4822 -2214
  216. package/dist/rich-text/index.d.ts +5 -0
  217. package/dist/rich-text/index.d.ts.map +1 -0
  218. package/dist/rich-text/index.js +654 -0
  219. package/dist/tokens/brands/studio.css +14 -0
  220. package/dist/tokens/brands/studio.json +20 -0
  221. package/dist/types/charts.d.ts +97 -0
  222. package/dist/types/charts.d.ts.map +1 -0
  223. package/dist/types/index.d.ts +193 -5
  224. package/dist/types/index.d.ts.map +1 -1
  225. package/dist/types/rich-text.d.ts +50 -0
  226. package/dist/types/rich-text.d.ts.map +1 -0
  227. package/dist/utils/position.d.ts +30 -0
  228. package/dist/utils/position.d.ts.map +1 -0
  229. package/doc/README.md +20 -1
  230. package/mcp/catalog.snapshot.json +2505 -800
  231. package/mcp/server-core.mjs +30 -1
  232. package/package.json +51 -3
  233. package/rich-text/package.json +5 -0
  234. package/tokens/brands/studio.json +20 -0
@@ -0,0 +1,1533 @@
1
+ 'use client';
2
+ import { objectWithoutProperties as _objectWithoutProperties, objectSpread2 as _objectSpread2, slicedToArray as _slicedToArray, toConsumableArray as _toConsumableArray, defineProperty as _defineProperty, asyncToGenerator as _asyncToGenerator, regenerator as _regenerator } from '../../../_virtual/_rollupPluginBabelHelpers.js';
3
+ import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
4
+ import { forwardRef, useState, useRef, useId, useMemo, useCallback, useImperativeHandle, useEffect } from 'react';
5
+ import { cn } from '../../../utils/cn.js';
6
+ import { useLatestRef } from '../../../hooks/useLatestRef.js';
7
+ import { Plus, RefreshCcw, Save, X, AlertCircle, Search, ChevronUp, ChevronDown, MoreVertical, List } from 'lucide-react';
8
+ import Select from '../Select.js';
9
+ import { DEFAULT_ACTIONS } from './constants.js';
10
+ import { getRowKey, mergeDefaultActions } from './helpers.js';
11
+ import { useClickOutside } from './useClickOutside.js';
12
+ import { PaginationHeader, PaginationFooter } from './Pagination.js';
13
+ import ColumnMenu from './ColumnMenu.js';
14
+ import MobileFilters from './MobileFilters.js';
15
+ import TableRow from './TableRow.js';
16
+ import MobileCard from './MobileCard.js';
17
+ import FieldInput from './FieldInput.js';
18
+
19
+ var _excluded = ["data", "columns", "sortable", "filterable", "selectable", "pagination", "pageSize", "onSort", "onFilter", "onFetch", "onFilterChange", "onSelectionChange", "onRowClick", "hasDetails", "DetailsComponent", "className", "withAction", "onAction", "actions", "replaceDefaultActions", "showSerial", "cellClass", "rowClass", "globalSearch", "limitOptions", "showLimitSelector", "onLimitChange", "showReloadButton", "renderReloadButton", "onReload", "stripedRows", "theme", "responsiveBreakpoint", "showToolbar", "showColumnPicker", "wrapCells", "mobileMaxFields", "serverSide", "totalRecords", "pageNumber", "onPageChange", "TheadComponent", "TfootComponent", "interactive", "onSave", "onEdit", "onRowAdd", "onRowDelete", "editKeyBinding", "newRowPosition", "addRowRef", "onInitAddRow", "renderAddRowButton", "renderExternalAddRow"],
20
+ _excluded2 = ["_key", "_isNew"];
21
+ var DEFAULT_DATA = [];
22
+ var DEFAULT_COLUMNS = [];
23
+ var DEFAULT_THEME = {
24
+ stripedColors: ["bg-[#ffffff]", "bg-[#f7fafc]"],
25
+ rowHover: "bg-gray-50",
26
+ accentColor: "bg-gray-50",
27
+ menuBg: "bg-white",
28
+ menuItemHover: "hover:bg-gray-50"
29
+ };
30
+ var Table = /*#__PURE__*/forwardRef(function Table(_ref, ref) {
31
+ var _validationErrors$;
32
+ var _ref$data = _ref.data,
33
+ initialData = _ref$data === void 0 ? DEFAULT_DATA : _ref$data,
34
+ _ref$columns = _ref.columns,
35
+ initialColumns = _ref$columns === void 0 ? DEFAULT_COLUMNS : _ref$columns,
36
+ _ref$sortable = _ref.sortable,
37
+ sortable = _ref$sortable === void 0 ? true : _ref$sortable,
38
+ _ref$filterable = _ref.filterable,
39
+ filterable = _ref$filterable === void 0 ? false : _ref$filterable,
40
+ _ref$selectable = _ref.selectable,
41
+ selectable = _ref$selectable === void 0 ? false : _ref$selectable,
42
+ _ref$pagination = _ref.pagination,
43
+ pagination = _ref$pagination === void 0 ? false : _ref$pagination,
44
+ _ref$pageSize = _ref.pageSize,
45
+ pageSize = _ref$pageSize === void 0 ? 25 : _ref$pageSize,
46
+ onSort = _ref.onSort,
47
+ onFilter = _ref.onFilter,
48
+ onFetch = _ref.onFetch,
49
+ onFilterChange = _ref.onFilterChange,
50
+ onSelectionChange = _ref.onSelectionChange,
51
+ onRowClick = _ref.onRowClick,
52
+ _ref$hasDetails = _ref.hasDetails,
53
+ hasDetails = _ref$hasDetails === void 0 ? false : _ref$hasDetails,
54
+ _ref$DetailsComponent = _ref.DetailsComponent,
55
+ DetailsComponent = _ref$DetailsComponent === void 0 ? null : _ref$DetailsComponent,
56
+ className = _ref.className,
57
+ _ref$withAction = _ref.withAction,
58
+ withAction = _ref$withAction === void 0 ? true : _ref$withAction,
59
+ onAction = _ref.onAction,
60
+ actions = _ref.actions,
61
+ _ref$replaceDefaultAc = _ref.replaceDefaultActions,
62
+ replaceDefaultActions = _ref$replaceDefaultAc === void 0 ? false : _ref$replaceDefaultAc,
63
+ _ref$showSerial = _ref.showSerial,
64
+ showSerial = _ref$showSerial === void 0 ? true : _ref$showSerial,
65
+ cellClass = _ref.cellClass,
66
+ rowClass = _ref.rowClass,
67
+ _ref$globalSearch = _ref.globalSearch,
68
+ globalSearch = _ref$globalSearch === void 0 ? false : _ref$globalSearch,
69
+ _ref$limitOptions = _ref.limitOptions,
70
+ limitOptions = _ref$limitOptions === void 0 ? [10, 25, 50, 100] : _ref$limitOptions,
71
+ _ref$showLimitSelecto = _ref.showLimitSelector,
72
+ showLimitSelector = _ref$showLimitSelecto === void 0 ? true : _ref$showLimitSelecto,
73
+ onLimitChange = _ref.onLimitChange,
74
+ _ref$showReloadButton = _ref.showReloadButton,
75
+ showReloadButton = _ref$showReloadButton === void 0 ? true : _ref$showReloadButton,
76
+ renderReloadButton = _ref.renderReloadButton,
77
+ onReload = _ref.onReload,
78
+ _ref$stripedRows = _ref.stripedRows,
79
+ stripedRows = _ref$stripedRows === void 0 ? true : _ref$stripedRows,
80
+ _ref$theme = _ref.theme,
81
+ theme = _ref$theme === void 0 ? DEFAULT_THEME : _ref$theme,
82
+ _ref$responsiveBreakp = _ref.responsiveBreakpoint,
83
+ responsiveBreakpoint = _ref$responsiveBreakp === void 0 ? 768 : _ref$responsiveBreakp,
84
+ _ref$showToolbar = _ref.showToolbar,
85
+ showToolbar = _ref$showToolbar === void 0 ? true : _ref$showToolbar,
86
+ _ref$showColumnPicker = _ref.showColumnPicker,
87
+ showColumnPicker = _ref$showColumnPicker === void 0 ? true : _ref$showColumnPicker,
88
+ _ref$wrapCells = _ref.wrapCells,
89
+ wrapCells = _ref$wrapCells === void 0 ? false : _ref$wrapCells,
90
+ mobileMaxFields = _ref.mobileMaxFields,
91
+ _ref$serverSide = _ref.serverSide,
92
+ serverSide = _ref$serverSide === void 0 ? false : _ref$serverSide,
93
+ _ref$totalRecords = _ref.totalRecords,
94
+ totalRecords = _ref$totalRecords === void 0 ? 0 : _ref$totalRecords,
95
+ pageNumber = _ref.pageNumber,
96
+ onPageChange = _ref.onPageChange,
97
+ _ref$TheadComponent = _ref.TheadComponent,
98
+ TheadComponent = _ref$TheadComponent === void 0 ? null : _ref$TheadComponent,
99
+ _ref$TfootComponent = _ref.TfootComponent,
100
+ TfootComponent = _ref$TfootComponent === void 0 ? null : _ref$TfootComponent,
101
+ _ref$interactive = _ref.interactive,
102
+ interactive = _ref$interactive === void 0 ? false : _ref$interactive,
103
+ onSave = _ref.onSave,
104
+ onEdit = _ref.onEdit,
105
+ onRowAdd = _ref.onRowAdd,
106
+ onRowDelete = _ref.onRowDelete,
107
+ _ref$editKeyBinding = _ref.editKeyBinding,
108
+ editKeyBinding = _ref$editKeyBinding === void 0 ? "e" : _ref$editKeyBinding,
109
+ _ref$newRowPosition = _ref.newRowPosition,
110
+ newRowPosition = _ref$newRowPosition === void 0 ? "bottom" : _ref$newRowPosition,
111
+ addRowRef = _ref.addRowRef,
112
+ onInitAddRow = _ref.onInitAddRow,
113
+ renderAddRowButton = _ref.renderAddRowButton,
114
+ renderExternalAddRow = _ref.renderExternalAddRow,
115
+ props = _objectWithoutProperties(_ref, _excluded);
116
+ theme = _objectSpread2(_objectSpread2({}, DEFAULT_THEME), theme);
117
+ // State
118
+ var _useState = useState(false),
119
+ _useState2 = _slicedToArray(_useState, 2),
120
+ isMobileView = _useState2[0],
121
+ setIsMobileView = _useState2[1];
122
+ var _useState3 = useState(function () {
123
+ return Array.isArray(initialData) ? initialData : [];
124
+ }),
125
+ _useState4 = _slicedToArray(_useState3, 2),
126
+ tableData = _useState4[0],
127
+ setTableData = _useState4[1];
128
+ var _useState5 = useState(false),
129
+ _useState6 = _slicedToArray(_useState5, 2),
130
+ loading = _useState6[0],
131
+ _setLoading = _useState6[1];
132
+ var _useState7 = useState(pageSize),
133
+ _useState8 = _slicedToArray(_useState7, 2),
134
+ limit = _useState8[0],
135
+ setLimit = _useState8[1];
136
+ var _useState9 = useState(function () {
137
+ return typeof pageNumber === "number" ? pageNumber : 1;
138
+ }),
139
+ _useState0 = _slicedToArray(_useState9, 2),
140
+ currentPage = _useState0[0],
141
+ setCurrentPage = _useState0[1];
142
+ var _useState1 = useState(function () {
143
+ return Array.isArray(initialColumns) ? initialColumns.map(function (c) {
144
+ return _objectSpread2({}, c);
145
+ }) : [];
146
+ }),
147
+ _useState10 = _slicedToArray(_useState1, 2),
148
+ columnsState = _useState10[0],
149
+ setColumnsState = _useState10[1];
150
+ var _useState11 = useState(false),
151
+ _useState12 = _slicedToArray(_useState11, 2),
152
+ showColumnMenu = _useState12[0],
153
+ setShowColumnMenu = _useState12[1];
154
+ var _useState13 = useState({
155
+ key: null,
156
+ direction: "asc"
157
+ }),
158
+ _useState14 = _slicedToArray(_useState13, 2),
159
+ sortConfig = _useState14[0],
160
+ setSortConfig = _useState14[1];
161
+ var _useState15 = useState({}),
162
+ _useState16 = _slicedToArray(_useState15, 2),
163
+ filters = _useState16[0],
164
+ setFilters = _useState16[1];
165
+ var _useState17 = useState(""),
166
+ _useState18 = _slicedToArray(_useState17, 2),
167
+ searchInput = _useState18[0],
168
+ setSearchInput = _useState18[1];
169
+ var _useState19 = useState(function () {
170
+ return new Set();
171
+ }),
172
+ _useState20 = _slicedToArray(_useState19, 2),
173
+ selectedRows = _useState20[0],
174
+ setSelectedRows = _useState20[1];
175
+ var _useState21 = useState(function () {
176
+ return new Set();
177
+ }),
178
+ _useState22 = _slicedToArray(_useState21, 2),
179
+ expandedRows = _useState22[0],
180
+ setExpandedRows = _useState22[1];
181
+ var _useState23 = useState(null),
182
+ _useState24 = _slicedToArray(_useState23, 2),
183
+ activeActionRowKey = _useState24[0],
184
+ setActiveActionRowKey = _useState24[1];
185
+ var _useState25 = useState(false),
186
+ _useState26 = _slicedToArray(_useState25, 2),
187
+ showMobileFilters = _useState26[0],
188
+ setShowMobileFilters = _useState26[1];
189
+ // Interactive Mode State
190
+ var _useState27 = useState({}),
191
+ _useState28 = _slicedToArray(_useState27, 2),
192
+ pendingEdits = _useState28[0],
193
+ setPendingEdits = _useState28[1];
194
+ var _useState29 = useState([]),
195
+ _useState30 = _slicedToArray(_useState29, 2),
196
+ newRows = _useState30[0],
197
+ setNewRows = _useState30[1];
198
+ var _useState31 = useState(null),
199
+ _useState32 = _slicedToArray(_useState31, 2),
200
+ activeCell = _useState32[0],
201
+ setActiveCell = _useState32[1];
202
+ var _useState33 = useState(null),
203
+ _useState34 = _slicedToArray(_useState33, 2),
204
+ editingCell = _useState34[0],
205
+ setEditingCell = _useState34[1];
206
+ var _useState35 = useState(false),
207
+ _useState36 = _slicedToArray(_useState35, 2),
208
+ isSaving = _useState36[0],
209
+ setIsSaving = _useState36[1];
210
+ var tableContainerRef = useRef(null);
211
+ // Refs
212
+ var columnMenuRef = useRef(null);
213
+ var columnToggleBtnRef = useRef(null);
214
+ var columnMenuId = "table-column-menu-".concat(useId());
215
+ var actionMenuRef = useRef(null);
216
+ // Calculate pending changes & dirty state
217
+ var _useMemo = useMemo(function () {
218
+ if (!interactive) return {
219
+ dirtyEdits: {},
220
+ pendingCount: 0
221
+ };
222
+ var dirtyMap = {};
223
+ var count = 0;
224
+ Object.keys(pendingEdits).forEach(function (rowKey) {
225
+ var rowEdits = pendingEdits[rowKey];
226
+ if (!rowEdits) return;
227
+ var originalRow = tableData.find(function (r, i) {
228
+ return getRowKey(r, i) === rowKey;
229
+ });
230
+ Object.keys(rowEdits).forEach(function (colKey) {
231
+ var newVal = rowEdits[colKey];
232
+ var origVal = originalRow === null || originalRow === void 0 ? void 0 : originalRow[colKey];
233
+ if (newVal !== origVal) {
234
+ if (!dirtyMap[rowKey]) dirtyMap[rowKey] = {};
235
+ dirtyMap[rowKey][colKey] = newVal;
236
+ count++;
237
+ }
238
+ });
239
+ });
240
+ count += newRows.length;
241
+ return {
242
+ dirtyEdits: dirtyMap,
243
+ pendingCount: count
244
+ };
245
+ }, [interactive, pendingEdits, newRows, tableData]),
246
+ dirtyEdits = _useMemo.dirtyEdits,
247
+ pendingCount = _useMemo.pendingCount;
248
+ var isDirty = pendingCount > 0;
249
+ // Calculate validation errors for pending edits and new rows
250
+ var validationErrors = useMemo(function () {
251
+ if (!interactive) return [];
252
+ var errors = [];
253
+ var isEmpty = function isEmpty(val) {
254
+ return val === null || val === undefined || String(val).trim() === "";
255
+ };
256
+ // 1. Validate pending edits on existing rows
257
+ Object.keys(dirtyEdits).forEach(function (rowKey) {
258
+ var origRow = tableData.find(function (r, i) {
259
+ return getRowKey(r, i) === rowKey;
260
+ });
261
+ if (!origRow) return;
262
+ var effectiveRow = _objectSpread2(_objectSpread2({}, origRow), pendingEdits[rowKey] || {});
263
+ columnsState.forEach(function (col) {
264
+ var _col$rules;
265
+ if (col.isVisible === false) return;
266
+ var val = effectiveRow[col.key];
267
+ var isReq = col.required || ((_col$rules = col.rules) === null || _col$rules === void 0 ? void 0 : _col$rules.required);
268
+ if (isReq && isEmpty(val)) {
269
+ errors.push({
270
+ rowKey: rowKey,
271
+ colKey: col.key,
272
+ message: "\"".concat(col.label || col.key, "\" is required")
273
+ });
274
+ } else if (typeof col.validate === "function") {
275
+ var res = col.validate(val, effectiveRow);
276
+ if (res === false || typeof res === "string") {
277
+ errors.push({
278
+ rowKey: rowKey,
279
+ colKey: col.key,
280
+ message: typeof res === "string" ? res : "\"".concat(col.label || col.key, "\" is invalid")
281
+ });
282
+ }
283
+ }
284
+ });
285
+ });
286
+ // 2. Validate newly added rows
287
+ newRows.forEach(function (newRow) {
288
+ var rowKey = newRow._key;
289
+ columnsState.forEach(function (col) {
290
+ var _col$rules2;
291
+ if (col.isVisible === false) return;
292
+ var val = newRow[col.key];
293
+ var isReq = col.required || ((_col$rules2 = col.rules) === null || _col$rules2 === void 0 ? void 0 : _col$rules2.required);
294
+ if (isReq && isEmpty(val)) {
295
+ errors.push({
296
+ rowKey: rowKey,
297
+ colKey: col.key,
298
+ message: "\"".concat(col.label || col.key, "\" is required")
299
+ });
300
+ } else if (typeof col.validate === "function") {
301
+ var res = col.validate(val, newRow);
302
+ if (res === false || typeof res === "string") {
303
+ errors.push({
304
+ rowKey: rowKey,
305
+ colKey: col.key,
306
+ message: typeof res === "string" ? res : "\"".concat(col.label || col.key, "\" is invalid")
307
+ });
308
+ }
309
+ }
310
+ });
311
+ });
312
+ return errors;
313
+ }, [interactive, dirtyEdits, pendingEdits, newRows, tableData, columnsState]);
314
+ var isValid = validationErrors.length === 0;
315
+ var invalidCellSet = useMemo(function () {
316
+ var set = new Set();
317
+ validationErrors.forEach(function (err) {
318
+ set.add("".concat(err.rowKey, ":").concat(err.colKey));
319
+ });
320
+ return set;
321
+ }, [validationErrors]);
322
+ var handleCellValueChange = useCallback(function (rowKey, colKey, newValue) {
323
+ var newRowIdx = newRows.findIndex(function (r) {
324
+ return r._key === rowKey;
325
+ });
326
+ if (newRowIdx !== -1) {
327
+ setNewRows(function (prev) {
328
+ var next = _toConsumableArray(prev);
329
+ next[newRowIdx] = _objectSpread2(_objectSpread2({}, next[newRowIdx]), {}, _defineProperty({}, colKey, newValue));
330
+ onEdit === null || onEdit === void 0 || onEdit({
331
+ rowKey: rowKey,
332
+ colKey: colKey,
333
+ newValue: newValue,
334
+ row: next[newRowIdx],
335
+ isNew: true
336
+ });
337
+ return next;
338
+ });
339
+ return;
340
+ }
341
+ setPendingEdits(function (prev) {
342
+ var nextRowEdits = _objectSpread2(_objectSpread2({}, prev[rowKey] || {}), {}, _defineProperty({}, colKey, newValue));
343
+ var origRow = tableData.find(function (r, i) {
344
+ return getRowKey(r, i) === rowKey;
345
+ });
346
+ var updatedRow = _objectSpread2(_objectSpread2({}, origRow), nextRowEdits);
347
+ onEdit === null || onEdit === void 0 || onEdit({
348
+ rowKey: rowKey,
349
+ colKey: colKey,
350
+ newValue: newValue,
351
+ row: updatedRow,
352
+ isNew: false
353
+ });
354
+ return _objectSpread2(_objectSpread2({}, prev), {}, _defineProperty({}, rowKey, nextRowEdits));
355
+ });
356
+ }, [newRows, tableData, onEdit]);
357
+ var _handleAddRow = useCallback(function (positionOverride) {
358
+ var _columnsState$find, _columnsState$;
359
+ var targetPos = typeof positionOverride === "string" && (positionOverride === "top" || positionOverride === "bottom") ? positionOverride : newRowPosition || "bottom";
360
+ var newKey = "new-".concat(Date.now(), "-").concat(Math.random().toString(36).substring(2, 6));
361
+ var newRowObj = {
362
+ _key: newKey,
363
+ _isNew: true
364
+ };
365
+ columnsState.forEach(function (col) {
366
+ var _col$defaultValue;
367
+ newRowObj[col.key] = (_col$defaultValue = col.defaultValue) !== null && _col$defaultValue !== void 0 ? _col$defaultValue : "";
368
+ });
369
+ setNewRows(function (prev) {
370
+ if (targetPos === "top") {
371
+ return [newRowObj].concat(_toConsumableArray(prev));
372
+ }
373
+ return [].concat(_toConsumableArray(prev), [newRowObj]);
374
+ });
375
+ var firstColKey = ((_columnsState$find = columnsState.find(function (c) {
376
+ return c.isVisible !== false;
377
+ })) === null || _columnsState$find === void 0 ? void 0 : _columnsState$find.key) || ((_columnsState$ = columnsState[0]) === null || _columnsState$ === void 0 ? void 0 : _columnsState$.key);
378
+ var initialRowIndex = targetPos === "top" ? 0 : tableData.length + newRows.length;
379
+ setActiveCell({
380
+ rowKey: newKey,
381
+ colKey: firstColKey,
382
+ rowIndex: initialRowIndex
383
+ });
384
+ setEditingCell({
385
+ rowKey: newKey,
386
+ colKey: firstColKey,
387
+ rowIndex: initialRowIndex
388
+ });
389
+ onRowAdd === null || onRowAdd === void 0 || onRowAdd(newRowObj, targetPos);
390
+ }, [columnsState, tableData.length, newRows.length, onRowAdd, newRowPosition]);
391
+ useImperativeHandle(ref, function () {
392
+ return {
393
+ addRow: function addRow(pos) {
394
+ return _handleAddRow(pos);
395
+ },
396
+ addNewRow: function addNewRow(pos) {
397
+ return _handleAddRow(pos);
398
+ },
399
+ handleAddRow: function handleAddRow(pos) {
400
+ return _handleAddRow(pos);
401
+ },
402
+ tableContainerRef: tableContainerRef.current
403
+ };
404
+ }, [_handleAddRow]);
405
+ useEffect(function () {
406
+ if (addRowRef) {
407
+ addRowRef.current = function (pos) {
408
+ return _handleAddRow(pos);
409
+ };
410
+ }
411
+ onInitAddRow === null || onInitAddRow === void 0 || onInitAddRow(function (pos) {
412
+ return _handleAddRow(pos);
413
+ });
414
+ }, [addRowRef, onInitAddRow, _handleAddRow]);
415
+ var handleDeleteNewRow = useCallback(function (rowKey) {
416
+ setNewRows(function (prev) {
417
+ return prev.filter(function (r) {
418
+ return r._key !== rowKey;
419
+ });
420
+ });
421
+ setPendingEdits(function (prev) {
422
+ var next = _objectSpread2({}, prev);
423
+ delete next[rowKey];
424
+ return next;
425
+ });
426
+ if ((activeCell === null || activeCell === void 0 ? void 0 : activeCell.rowKey) === rowKey) {
427
+ setActiveCell(null);
428
+ setEditingCell(null);
429
+ }
430
+ onRowDelete === null || onRowDelete === void 0 || onRowDelete(rowKey);
431
+ }, [activeCell, onRowDelete]);
432
+ var handleSave = useCallback(/*#__PURE__*/_asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee() {
433
+ var _customSaveResult, _customSaveResult2, updatedTableData, finalNewRows, finalData, customSaveResult, nextData, _t;
434
+ return _regenerator().w(function (_context) {
435
+ while (1) switch (_context.p = _context.n) {
436
+ case 0:
437
+ if (!(!isDirty || isSaving)) {
438
+ _context.n = 1;
439
+ break;
440
+ }
441
+ return _context.a(2);
442
+ case 1:
443
+ setIsSaving(true);
444
+ _context.p = 2;
445
+ updatedTableData = tableData.map(function (row, i) {
446
+ var rKey = getRowKey(row, i);
447
+ if (dirtyEdits[rKey]) {
448
+ return _objectSpread2(_objectSpread2({}, row), dirtyEdits[rKey]);
449
+ }
450
+ return row;
451
+ });
452
+ finalNewRows = newRows.map(function (_ref3) {
453
+ _ref3._key;
454
+ _ref3._isNew;
455
+ var rest = _objectWithoutProperties(_ref3, _excluded2);
456
+ return rest;
457
+ });
458
+ finalData = [].concat(_toConsumableArray(updatedTableData), _toConsumableArray(finalNewRows));
459
+ if (!onSave) {
460
+ _context.n = 4;
461
+ break;
462
+ }
463
+ _context.n = 3;
464
+ return onSave({
465
+ updatedRows: dirtyEdits,
466
+ newRows: finalNewRows,
467
+ allData: finalData,
468
+ tableData: updatedTableData
469
+ });
470
+ case 3:
471
+ customSaveResult = _context.v;
472
+ case 4:
473
+ nextData = Array.isArray(customSaveResult) ? customSaveResult : ((_customSaveResult = customSaveResult) === null || _customSaveResult === void 0 ? void 0 : _customSaveResult.data) || ((_customSaveResult2 = customSaveResult) === null || _customSaveResult2 === void 0 ? void 0 : _customSaveResult2.allData) || finalData;
474
+ setTableData(nextData);
475
+ initialDataRef.current = nextData;
476
+ setPendingEdits({});
477
+ setNewRows([]);
478
+ setEditingCell(null);
479
+ _context.n = 6;
480
+ break;
481
+ case 5:
482
+ _context.p = 5;
483
+ _t = _context.v;
484
+ console.error("Save error:", _t);
485
+ case 6:
486
+ _context.p = 6;
487
+ setIsSaving(false);
488
+ return _context.f(6);
489
+ case 7:
490
+ return _context.a(2);
491
+ }
492
+ }, _callee, null, [[2, 5, 6, 7]]);
493
+ })), [isDirty, isSaving, tableData, dirtyEdits, newRows, onSave]);
494
+ var handleClearChanges = useCallback(function () {
495
+ setPendingEdits({});
496
+ setNewRows([]);
497
+ setEditingCell(null);
498
+ setActiveCell(null);
499
+ }, []);
500
+ var handleCellClick = useCallback(function (rowKey, colKey, row, column, globalIndex) {
501
+ setActiveCell({
502
+ rowKey: rowKey,
503
+ colKey: colKey,
504
+ rowIndex: globalIndex
505
+ });
506
+ setEditingCell(function (prev) {
507
+ if (prev && prev.rowKey === rowKey && prev.colKey === colKey) {
508
+ return prev;
509
+ }
510
+ return null;
511
+ });
512
+ }, []);
513
+ var handleCellDoubleClick = useCallback(function (rowKey, colKey, row, column, globalIndex) {
514
+ setActiveCell({
515
+ rowKey: rowKey,
516
+ colKey: colKey,
517
+ rowIndex: globalIndex
518
+ });
519
+ if (column.editable !== false) {
520
+ setEditingCell({
521
+ rowKey: rowKey,
522
+ colKey: colKey,
523
+ rowIndex: globalIndex
524
+ });
525
+ }
526
+ }, []);
527
+ useClickOutside([tableContainerRef], interactive && Boolean(editingCell), function () {
528
+ setEditingCell(null);
529
+ });
530
+ var actionButtonRefs = useRef({});
531
+ // Row components register their kebab buttons through this callback rather
532
+ // than mutating `actionButtonRefs` directly (props must stay immutable).
533
+ var registerActionButton = useCallback(function (key, el) {
534
+ if (el) actionButtonRefs.current[key] = el;
535
+ }, []);
536
+ // Memoized values
537
+ //
538
+ // Supplied actions PATCH the built-in set by `name` (so `{ name: "edit",
539
+ // onClick }` keeps the default label + icon) unless `replaceDefaultActions`
540
+ // is set. Stays either an array or a `(row, index) => array` producer, and
541
+ // keeps a stable identity so the per-row memo in TableRow/MobileCard pays off.
542
+ var actionsToUse = useMemo(function () {
543
+ if (actions === undefined) return DEFAULT_ACTIONS;
544
+ if (replaceDefaultActions) return actions;
545
+ if (typeof actions === "function") {
546
+ return function (row, index) {
547
+ return mergeDefaultActions(actions(row, index), DEFAULT_ACTIONS);
548
+ };
549
+ }
550
+ return mergeDefaultActions(actions, DEFAULT_ACTIONS);
551
+ }, [actions, replaceDefaultActions]);
552
+ // `hasDetails` may be a predicate. The expand COLUMN exists whenever the prop
553
+ // is truthy at all; whether a given row gets a toggle is decided per row.
554
+ var hasDetailsColumn = useMemo(function () {
555
+ return typeof hasDetails === "function" || !!hasDetails;
556
+ }, [hasDetails]);
557
+ // Refs for stable initial values
558
+ var initialColumnsRef = useRef(initialColumns);
559
+ var initialDataRef = useRef(initialData);
560
+ useEffect(function () {
561
+ setLimit(pageSize);
562
+ }, [pageSize]);
563
+ // Follow an external `pageNumber` change (adjust-during-render pattern);
564
+ // internal page navigation is left alone while the prop is unchanged.
565
+ var _useState37 = useState(pageNumber),
566
+ _useState38 = _slicedToArray(_useState37, 2),
567
+ prevPageNumber = _useState38[0],
568
+ setPrevPageNumber = _useState38[1];
569
+ if (pageNumber !== prevPageNumber) {
570
+ setPrevPageNumber(pageNumber);
571
+ if (typeof pageNumber === "number" && pageNumber !== currentPage) {
572
+ setCurrentPage(pageNumber);
573
+ }
574
+ }
575
+ useEffect(function () {
576
+ if (initialColumns !== initialColumnsRef.current) {
577
+ setColumnsState(Array.isArray(initialColumns) ? initialColumns.map(function (c) {
578
+ return _objectSpread2({}, c);
579
+ }) : []);
580
+ initialColumnsRef.current = initialColumns;
581
+ }
582
+ }, [initialColumns]);
583
+ useEffect(function () {
584
+ if (initialData !== initialDataRef.current && Array.isArray(initialData)) {
585
+ setTableData(initialData);
586
+ initialDataRef.current = initialData;
587
+ }
588
+ }, [initialData]);
589
+ useEffect(function () {
590
+ var checkMobile = function checkMobile() {
591
+ return setIsMobileView(window.innerWidth < responsiveBreakpoint);
592
+ };
593
+ checkMobile();
594
+ window.addEventListener("resize", checkMobile);
595
+ return function () {
596
+ return window.removeEventListener("resize", checkMobile);
597
+ };
598
+ }, [responsiveBreakpoint]);
599
+ // Click-outside handlers
600
+ var closeColumnMenu = useCallback(function () {
601
+ return setShowColumnMenu(false);
602
+ }, []);
603
+ var closeActionMenu = useCallback(function () {
604
+ return setActiveActionRowKey(null);
605
+ }, []);
606
+ useClickOutside([columnMenuRef, columnToggleBtnRef], showColumnMenu, closeColumnMenu);
607
+ useClickOutside([actionMenuRef], activeActionRowKey !== null, closeActionMenu);
608
+ // Computed values
609
+ var activeAnchorEl = useMemo(function () {
610
+ if (activeActionRowKey === null) return null;
611
+ return actionButtonRefs.current[activeActionRowKey];
612
+ }, [activeActionRowKey]);
613
+ var visibleColumns = useMemo(function () {
614
+ return columnsState.filter(function (col) {
615
+ return col.isVisible !== false;
616
+ });
617
+ }, [columnsState]);
618
+ // The column picker lives in the toolbar's sense of "table chrome": hiding
619
+ // the toolbar hides it too, and it can also be hidden on its own.
620
+ var columnPickerVisible = showToolbar && showColumnPicker;
621
+ // Mobile cards show only the columns that earn a line on a phone: columns
622
+ // flagged `hideOnMobile` are dropped, then `mobileMaxFields` caps the rest
623
+ // in column order. Defaults keep every visible column.
624
+ var mobileColumns = useMemo(function () {
625
+ var cols = visibleColumns.filter(function (col) {
626
+ return !col.hideOnMobile;
627
+ });
628
+ var max = Number(mobileMaxFields);
629
+ return Number.isInteger(max) && max >= 0 ? cols.slice(0, max) : cols;
630
+ }, [visibleColumns, mobileMaxFields]);
631
+ // Columns that opt out of the global search with `searchable: false`.
632
+ var unsearchableKeys = useMemo(function () {
633
+ return new Set(columnsState.filter(function (col) {
634
+ return col.searchable === false;
635
+ }).map(function (col) {
636
+ return col.key;
637
+ }));
638
+ }, [columnsState]);
639
+ var sortedData = useMemo(function () {
640
+ var data = Array.isArray(tableData) ? tableData : [];
641
+ if (serverSide || !sortConfig.key) return data;
642
+ var key = sortConfig.key,
643
+ direction = sortConfig.direction;
644
+ return _toConsumableArray(data).sort(function (a, b) {
645
+ var av = a === null || a === void 0 ? void 0 : a[key];
646
+ var bv = b === null || b === void 0 ? void 0 : b[key];
647
+ if (av == null || bv == null) return 0;
648
+ if (typeof av === "number") {
649
+ return direction === "asc" ? av - bv : bv - av;
650
+ }
651
+ return direction === "asc" ? String(av).localeCompare(String(bv)) : String(bv).localeCompare(String(av));
652
+ });
653
+ }, [tableData, sortConfig, serverSide]);
654
+ // Client-side filtering. `filters.global` (the global search box) matches a
655
+ // row when any value outside a `searchable: false` column contains the
656
+ // term; every other non-empty `filters[columnKey]` (the per-column filter
657
+ // inputs) must match that column's raw value. All matches are
658
+ // case-insensitive substring tests. In `serverSide` mode the table never
659
+ // filters locally — filters are delegated to `onFetch` / `onFilter` /
660
+ // `onFilterChange`.
661
+ var filteredData = useMemo(function () {
662
+ var data = Array.isArray(sortedData) ? sortedData : [];
663
+ if (serverSide) return data;
664
+ var toText = function toText(v) {
665
+ return v == null ? "" : String(v).toLowerCase();
666
+ };
667
+ var globalTerm = toText(filters.global).trim();
668
+ var columnTerms = Object.entries(filters || {}).filter(function (_ref4) {
669
+ var _ref5 = _slicedToArray(_ref4, 2),
670
+ key = _ref5[0],
671
+ value = _ref5[1];
672
+ return key !== "global" && toText(value).trim() !== "";
673
+ }).map(function (_ref6) {
674
+ var _ref7 = _slicedToArray(_ref6, 2),
675
+ key = _ref7[0],
676
+ value = _ref7[1];
677
+ return [key, toText(value).trim()];
678
+ });
679
+ if (!globalTerm && columnTerms.length === 0) return data;
680
+ return data.filter(function (row) {
681
+ var r = row || {};
682
+ if (globalTerm && !Object.entries(r).some(function (_ref8) {
683
+ var _ref9 = _slicedToArray(_ref8, 2),
684
+ k = _ref9[0],
685
+ v = _ref9[1];
686
+ return !unsearchableKeys.has(k) && toText(v).includes(globalTerm);
687
+ })) {
688
+ return false;
689
+ }
690
+ return columnTerms.every(function (_ref0) {
691
+ var _ref1 = _slicedToArray(_ref0, 2),
692
+ key = _ref1[0],
693
+ term = _ref1[1];
694
+ return toText(r[key]).includes(term);
695
+ });
696
+ });
697
+ }, [sortedData, filters, serverSide, unsearchableKeys]);
698
+ // Client-side pages that no longer exist (the data shrank through
699
+ // filtering, deletion or a new `data` prop) are clamped to the last valid
700
+ // page. `pageIndex` is what this render shows; an effect below commits it.
701
+ var clientTotalPages = Math.max(1, Math.ceil(filteredData.length / limit));
702
+ var pageIndex = pagination && !serverSide && currentPage > clientTotalPages ? clientTotalPages : currentPage;
703
+ var _useMemo2 = useMemo(function () {
704
+ var data = Array.isArray(filteredData) ? filteredData : [];
705
+ var start = pagination ? (pageIndex - 1) * limit : 0;
706
+ var end = pagination ? start + limit : data.length;
707
+ var paginated = !pagination || serverSide ? data : data.slice(start, start + limit);
708
+ var pages = !pagination ? 1 : serverSide ? Math.max(1, Math.ceil((totalRecords || 0) / limit)) : Math.max(1, Math.ceil(data.length / limit));
709
+ return {
710
+ startIndex: start,
711
+ endIndex: end,
712
+ paginatedData: paginated,
713
+ totalPages: pages
714
+ };
715
+ }, [filteredData, pagination, serverSide, pageIndex, limit, totalRecords]),
716
+ startIndex = _useMemo2.startIndex,
717
+ endIndex = _useMemo2.endIndex,
718
+ paginatedData = _useMemo2.paginatedData,
719
+ totalPages = _useMemo2.totalPages;
720
+ var visibleCount = useMemo(function () {
721
+ return (showSerial ? 1 : 0) + visibleColumns.length + (selectable ? 1 : 0) + (hasDetailsColumn ? 1 : 0) + (withAction ? 1 : 0) + (columnPickerVisible ? 1 : 0);
722
+ }, [showSerial, visibleColumns.length, selectable, hasDetailsColumn, withAction, columnPickerVisible]);
723
+ // "start – end of total" for the toolbar. In serverSide mode `filteredData`
724
+ // is only the current page, so the total comes from `totalRecords` (falling
725
+ // back to the rows seen so far when the consumer does not supply it).
726
+ var resultRange = useMemo(function () {
727
+ if (serverSide) {
728
+ var pageRows = filteredData.length;
729
+ var _total = Number(totalRecords) > 0 ? Number(totalRecords) : startIndex + pageRows;
730
+ return {
731
+ start: pageRows === 0 ? 0 : startIndex + 1,
732
+ end: startIndex + pageRows,
733
+ total: _total
734
+ };
735
+ }
736
+ var total = filteredData.length;
737
+ return {
738
+ start: total === 0 ? 0 : startIndex + 1,
739
+ end: Math.min(endIndex, total),
740
+ total: total
741
+ };
742
+ }, [serverSide, filteredData.length, totalRecords, startIndex, endIndex]);
743
+ var rowKeyMap = useMemo(function () {
744
+ return new Map(filteredData.map(function (r, i) {
745
+ return [getRowKey(r, i), r];
746
+ }));
747
+ }, [filteredData]);
748
+ var allPageSelected = useMemo(function () {
749
+ if (paginatedData.length === 0) return false;
750
+ return paginatedData.every(function (r, i) {
751
+ return selectedRows.has(getRowKey(r, startIndex + i));
752
+ });
753
+ }, [paginatedData, selectedRows, startIndex]);
754
+ var limitOptionsForSelect = useMemo(function () {
755
+ var opts = Array.isArray(limitOptions) && limitOptions.length > 0 ? limitOptions : [25, 50, 100];
756
+ return opts.map(function (opt) {
757
+ return {
758
+ label: String(opt),
759
+ value: opt
760
+ };
761
+ });
762
+ }, [limitOptions]);
763
+ var isEditKey = useCallback(function (key, e) {
764
+ if (typeof editKeyBinding === "function") {
765
+ return editKeyBinding(e);
766
+ }
767
+ if (typeof editKeyBinding === "string" && editKeyBinding.trim() !== "") {
768
+ return key.toLowerCase() === editKeyBinding.toLowerCase();
769
+ }
770
+ return key.toLowerCase() === "e" || key === "Insert";
771
+ }, [editKeyBinding]);
772
+ var handleTableKeyDown = useCallback(function (e) {
773
+ if (!interactive) return;
774
+ var key = e.key,
775
+ shiftKey = e.shiftKey;
776
+ // Escape: stop editing
777
+ if (key === "Escape") {
778
+ if (editingCell) {
779
+ e.preventDefault();
780
+ setEditingCell(null);
781
+ }
782
+ return;
783
+ }
784
+ // Enter: Save changes when there are modified changes (isDirty)
785
+ if (key === "Enter" && isDirty) {
786
+ var _e$target;
787
+ if (((_e$target = e.target) === null || _e$target === void 0 ? void 0 : _e$target.tagName) === "TEXTAREA" && shiftKey) {
788
+ return;
789
+ }
790
+ e.preventDefault();
791
+ setEditingCell(null);
792
+ if (isValid && !isSaving) {
793
+ handleSave();
794
+ }
795
+ return;
796
+ }
797
+ // Standard Edit Key ('e' or custom editKeyBinding) when focused on active cell and not editing: enter edit mode
798
+ if (isEditKey(key, e) && activeCell && !editingCell) {
799
+ var col = visibleColumns.find(function (c) {
800
+ return c.key === activeCell.colKey;
801
+ });
802
+ if (col && col.editable !== false) {
803
+ e.preventDefault();
804
+ setEditingCell(activeCell);
805
+ return;
806
+ }
807
+ }
808
+ var currentCell = activeCell || editingCell;
809
+ if (!currentCell) return;
810
+ var allRows = newRowPosition === "top" ? [].concat(_toConsumableArray(newRows), _toConsumableArray(paginatedData)) : [].concat(_toConsumableArray(paginatedData), _toConsumableArray(newRows));
811
+ if (allRows.length === 0 || visibleColumns.length === 0) return;
812
+ var rIdx = allRows.findIndex(function (r, idx) {
813
+ var rKey = r._key || getRowKey(r, startIndex + idx);
814
+ return rKey === currentCell.rowKey;
815
+ });
816
+ var cIdx = visibleColumns.findIndex(function (c) {
817
+ return c.key === currentCell.colKey;
818
+ });
819
+ if (rIdx === -1 || cIdx === -1) return;
820
+ var nextRIdx = rIdx;
821
+ var nextCIdx = cIdx;
822
+ if (key === "Tab") {
823
+ e.preventDefault();
824
+ if (shiftKey) {
825
+ if (cIdx > 0) {
826
+ nextCIdx = cIdx - 1;
827
+ } else if (rIdx > 0) {
828
+ nextRIdx = rIdx - 1;
829
+ nextCIdx = visibleColumns.length - 1;
830
+ }
831
+ } else {
832
+ if (cIdx < visibleColumns.length - 1) {
833
+ nextCIdx = cIdx + 1;
834
+ } else if (rIdx < allRows.length - 1) {
835
+ nextRIdx = rIdx + 1;
836
+ nextCIdx = 0;
837
+ }
838
+ }
839
+ } else if (key === "ArrowRight") {
840
+ var _e$target2, _e$target$value;
841
+ if (editingCell && ((_e$target2 = e.target) === null || _e$target2 === void 0 ? void 0 : _e$target2.selectionStart) !== undefined && e.target.selectionStart < String((_e$target$value = e.target.value) !== null && _e$target$value !== void 0 ? _e$target$value : "").length) {
842
+ return;
843
+ }
844
+ if (cIdx < visibleColumns.length - 1) {
845
+ e.preventDefault();
846
+ nextCIdx = cIdx + 1;
847
+ }
848
+ } else if (key === "ArrowLeft") {
849
+ var _e$target3;
850
+ if (editingCell && ((_e$target3 = e.target) === null || _e$target3 === void 0 ? void 0 : _e$target3.selectionStart) !== undefined && e.target.selectionStart > 0) {
851
+ return;
852
+ }
853
+ if (cIdx > 0) {
854
+ e.preventDefault();
855
+ nextCIdx = cIdx - 1;
856
+ }
857
+ } else if (key === "ArrowDown") {
858
+ var _e$target4;
859
+ if (((_e$target4 = e.target) === null || _e$target4 === void 0 ? void 0 : _e$target4.tagName) === "SELECT") return;
860
+ if (rIdx < allRows.length - 1) {
861
+ e.preventDefault();
862
+ nextRIdx = rIdx + 1;
863
+ }
864
+ } else if (key === "ArrowUp") {
865
+ var _e$target5;
866
+ if (((_e$target5 = e.target) === null || _e$target5 === void 0 ? void 0 : _e$target5.tagName) === "SELECT") return;
867
+ if (rIdx > 0) {
868
+ e.preventDefault();
869
+ nextRIdx = rIdx - 1;
870
+ }
871
+ } else {
872
+ return;
873
+ }
874
+ var targetRow = allRows[nextRIdx];
875
+ var targetCol = visibleColumns[nextCIdx];
876
+ if (!targetRow || !targetCol) return;
877
+ var targetRowKey = targetRow._key || getRowKey(targetRow, startIndex + nextRIdx);
878
+ var nextCellObj = {
879
+ rowKey: targetRowKey,
880
+ colKey: targetCol.key,
881
+ rowIndex: startIndex + nextRIdx
882
+ };
883
+ setActiveCell(nextCellObj);
884
+ if (editingCell && targetCol.editable !== false) {
885
+ setEditingCell(nextCellObj);
886
+ }
887
+ }, [interactive, editingCell, activeCell, isDirty, isValid, isSaving, handleSave, paginatedData, newRows, visibleColumns, startIndex, isEditKey, newRowPosition]);
888
+ var renderInteractiveCellInput = useCallback(function (column, row, globalIndex, rowKey) {
889
+ var _row$column$key;
890
+ var value = pendingEdits[rowKey] && pendingEdits[rowKey][column.key] !== undefined ? pendingEdits[rowKey][column.key] : (_row$column$key = row[column.key]) !== null && _row$column$key !== void 0 ? _row$column$key : "";
891
+ return jsx(FieldInput, {
892
+ column: column,
893
+ value: value,
894
+ onChange: function onChange(newVal) {
895
+ return handleCellValueChange(rowKey, column.key, newVal);
896
+ },
897
+ onKeyDown: handleTableKeyDown,
898
+ isEditing: true,
899
+ row: row,
900
+ rowIndex: globalIndex,
901
+ autoFocus: (editingCell === null || editingCell === void 0 ? void 0 : editingCell.rowKey) === rowKey && (editingCell === null || editingCell === void 0 ? void 0 : editingCell.colKey) === column.key
902
+ });
903
+ }, [pendingEdits, handleCellValueChange, handleTableKeyDown, editingCell]);
904
+ // Callbacks
905
+ var toggleColumnVisibility = useCallback(function (key) {
906
+ setColumnsState(function (prev) {
907
+ return prev.map(function (c) {
908
+ return c.key === key ? _objectSpread2(_objectSpread2({}, c), {}, {
909
+ isVisible: !(c.isVisible !== false)
910
+ }) : c;
911
+ });
912
+ });
913
+ }, []);
914
+ var handleSort = useCallback(function (key) {
915
+ if (!sortable) return;
916
+ setSortConfig(function (prev) {
917
+ var direction = prev.key === key && prev.direction === "asc" ? "desc" : "asc";
918
+ onSort === null || onSort === void 0 || onSort(key, direction);
919
+ return {
920
+ key: key,
921
+ direction: direction
922
+ };
923
+ });
924
+ }, [sortable, onSort]);
925
+ var handleFilter = useCallback(function (key, value) {
926
+ setFilters(function (prev) {
927
+ var newFilters = _objectSpread2(_objectSpread2({}, prev), {}, _defineProperty({}, key, value));
928
+ onFilter === null || onFilter === void 0 || onFilter(newFilters);
929
+ onFilterChange === null || onFilterChange === void 0 || onFilterChange(newFilters);
930
+ return newFilters;
931
+ });
932
+ setCurrentPage(1);
933
+ }, [onFilter, onFilterChange]);
934
+ var handleSelectAll = useCallback(function () {
935
+ setSelectedRows(function (prev) {
936
+ var newSelection = new Set(prev);
937
+ var pageRowKeys = paginatedData.map(function (r, i) {
938
+ return getRowKey(r, startIndex + i);
939
+ });
940
+ var allSelected = pageRowKeys.every(function (k) {
941
+ return newSelection.has(k);
942
+ });
943
+ if (allSelected) {
944
+ pageRowKeys.forEach(function (k) {
945
+ return newSelection["delete"](k);
946
+ });
947
+ } else {
948
+ pageRowKeys.forEach(function (k) {
949
+ return newSelection.add(k);
950
+ });
951
+ }
952
+ var selectedData = Array.from(newSelection).map(function (k) {
953
+ return rowKeyMap.get(k);
954
+ }).filter(Boolean);
955
+ onSelectionChange === null || onSelectionChange === void 0 || onSelectionChange(selectedData);
956
+ return newSelection;
957
+ });
958
+ }, [paginatedData, startIndex, rowKeyMap, onSelectionChange]);
959
+ var handleSelectRow = useCallback(function (row, rowIndexInPage) {
960
+ var globalIndex = startIndex + rowIndexInPage;
961
+ var key = getRowKey(row, globalIndex);
962
+ setSelectedRows(function (prev) {
963
+ var newSelection = new Set(prev);
964
+ if (newSelection.has(key)) {
965
+ newSelection["delete"](key);
966
+ } else {
967
+ newSelection.add(key);
968
+ }
969
+ var selectedData = Array.from(newSelection).map(function (k) {
970
+ return rowKeyMap.get(k);
971
+ }).filter(Boolean);
972
+ onSelectionChange === null || onSelectionChange === void 0 || onSelectionChange(selectedData);
973
+ return newSelection;
974
+ });
975
+ }, [startIndex, rowKeyMap, onSelectionChange]);
976
+ var toggleExpandRow = useCallback(function (row, rowIndexInPage) {
977
+ var globalIndex = startIndex + rowIndexInPage;
978
+ var key = getRowKey(row, globalIndex);
979
+ setExpandedRows(function (prev) {
980
+ var newExpanded = new Set(prev);
981
+ if (newExpanded.has(key)) {
982
+ newExpanded["delete"](key);
983
+ } else {
984
+ newExpanded.add(key);
985
+ }
986
+ return newExpanded;
987
+ });
988
+ }, [startIndex]);
989
+ var toggleActions = useCallback(function (e, actionCellKey) {
990
+ e.stopPropagation();
991
+ e.preventDefault();
992
+ if (e.currentTarget) {
993
+ actionButtonRefs.current[actionCellKey] = e.currentTarget;
994
+ }
995
+ setActiveActionRowKey(function (prev) {
996
+ if (prev === actionCellKey) {
997
+ return null;
998
+ }
999
+ return actionCellKey;
1000
+ });
1001
+ }, []);
1002
+ var handleOnAction = useCallback(function (action, row) {
1003
+ var _action$onClick;
1004
+ (_action$onClick = action.onClick) === null || _action$onClick === void 0 || _action$onClick.call(action, {
1005
+ action: action,
1006
+ row: row
1007
+ });
1008
+ if ((action === null || action === void 0 ? void 0 : action.name) === "edit" || (action === null || action === void 0 ? void 0 : action.name) === "Edit") {
1009
+ if (interactive) {
1010
+ var _columnsState$find2, _columnsState$2;
1011
+ var firstColKey = ((_columnsState$find2 = columnsState.find(function (c) {
1012
+ return c.isVisible !== false && c.editable !== false;
1013
+ })) === null || _columnsState$find2 === void 0 ? void 0 : _columnsState$find2.key) || ((_columnsState$2 = columnsState[0]) === null || _columnsState$2 === void 0 ? void 0 : _columnsState$2.key);
1014
+ var globalIndex = tableData.findIndex(function (r, i) {
1015
+ return getRowKey(r, i) === getRowKey(row);
1016
+ });
1017
+ if (firstColKey && globalIndex !== -1) {
1018
+ var rKey = getRowKey(row, globalIndex);
1019
+ setActiveCell({
1020
+ rowKey: rKey,
1021
+ colKey: firstColKey,
1022
+ rowIndex: globalIndex
1023
+ });
1024
+ setEditingCell({
1025
+ rowKey: rKey,
1026
+ colKey: firstColKey,
1027
+ rowIndex: globalIndex
1028
+ });
1029
+ }
1030
+ }
1031
+ onEdit === null || onEdit === void 0 || onEdit({
1032
+ action: action,
1033
+ row: row
1034
+ });
1035
+ }
1036
+ onAction === null || onAction === void 0 || onAction({
1037
+ action: action,
1038
+ row: row
1039
+ });
1040
+ setActiveActionRowKey(null);
1041
+ }, [onAction, onEdit, interactive, columnsState, tableData]);
1042
+ var handleLimitChange = useCallback(function (nextLimit) {
1043
+ var parsed = Number(nextLimit);
1044
+ if (!Number.isFinite(parsed) || parsed <= 0) return;
1045
+ setLimit(parsed);
1046
+ setCurrentPage(1);
1047
+ onLimitChange === null || onLimitChange === void 0 || onLimitChange(parsed);
1048
+ }, [onLimitChange]);
1049
+ var applyGlobalSearch = useCallback(function () {
1050
+ handleFilter("global", searchInput);
1051
+ }, [handleFilter, searchInput]);
1052
+ var onGlobalKeyDown = useCallback(function (e) {
1053
+ if (e.key === "Enter") {
1054
+ e.preventDefault();
1055
+ applyGlobalSearch();
1056
+ }
1057
+ }, [applyGlobalSearch]);
1058
+ var handlePageChange = useCallback(function (newPage) {
1059
+ setCurrentPage(newPage);
1060
+ onPageChange === null || onPageChange === void 0 || onPageChange(newPage);
1061
+ }, [onPageChange]);
1062
+ // Commit a clamped page and report it through `onPageChange`, so a parent
1063
+ // driving `pageNumber` stays in sync. Skipped while loading or while there
1064
+ // are no rows (e.g. data not fetched yet), so a restored page survives
1065
+ // until the rows arrive.
1066
+ var onPageChangeRef = useLatestRef(onPageChange);
1067
+ var hasRows = filteredData.length > 0;
1068
+ useEffect(function () {
1069
+ var _onPageChangeRef$curr;
1070
+ if (loading || !hasRows || pageIndex === currentPage) return;
1071
+ setCurrentPage(pageIndex);
1072
+ (_onPageChangeRef$curr = onPageChangeRef.current) === null || _onPageChangeRef$curr === void 0 || _onPageChangeRef$curr.call(onPageChangeRef, pageIndex);
1073
+ }, [pageIndex, currentPage, loading, hasRows, onPageChangeRef]);
1074
+ var renderCell = useCallback(function (column, row, globalIndex) {
1075
+ if (column.render) return column.render(row, globalIndex);
1076
+ return row === null || row === void 0 ? void 0 : row[column.key];
1077
+ }, []);
1078
+ // Data fetching effect. Reads the latest onFetch through a ref so an inline
1079
+ // consumer callback does not refetch on every render.
1080
+ var onFetchRef = useLatestRef(onFetch);
1081
+ useEffect(function () {
1082
+ var fetchRows = onFetchRef.current;
1083
+ if (!fetchRows) return;
1084
+ var mounted = true;
1085
+ fetchRows({
1086
+ setData: function setData(rows) {
1087
+ if (mounted) setTableData(Array.isArray(rows) ? rows : []);
1088
+ },
1089
+ setLoading: function setLoading(v) {
1090
+ if (mounted) _setLoading(v);
1091
+ },
1092
+ filters: filters,
1093
+ page: currentPage,
1094
+ limit: limit,
1095
+ sort: sortConfig
1096
+ });
1097
+ return function () {
1098
+ mounted = false;
1099
+ };
1100
+ }, [filters, currentPage, limit, sortConfig, onFetchRef]);
1101
+ useEffect(function () {
1102
+ setSearchInput(filters.global || "");
1103
+ }, [filters.global]);
1104
+ // Shared props for row components (MobileCard expects stripedColors array)
1105
+ var safeTheme = theme || DEFAULT_THEME;
1106
+ var stripedColorsArray = Array.isArray(safeTheme.stripedColors) ? safeTheme.stripedColors : DEFAULT_THEME.stripedColors;
1107
+ var rowSharedProps = {
1108
+ selectedRows: selectedRows,
1109
+ expandedRows: expandedRows,
1110
+ rowClass: rowClass,
1111
+ stripedRows: stripedRows,
1112
+ theme: safeTheme,
1113
+ stripedColors: stripedColorsArray,
1114
+ onRowClick: onRowClick,
1115
+ hasDetails: hasDetails,
1116
+ hasDetailsColumn: hasDetailsColumn,
1117
+ showSerial: showSerial,
1118
+ selectable: selectable,
1119
+ visibleColumns: Array.isArray(visibleColumns) ? visibleColumns : [],
1120
+ showColumnPicker: columnPickerVisible,
1121
+ wrapCells: wrapCells,
1122
+ cellClass: cellClass,
1123
+ withAction: withAction,
1124
+ DetailsComponent: DetailsComponent,
1125
+ actionsToUse: actionsToUse,
1126
+ activeActionRowKey: activeActionRowKey,
1127
+ activeAnchorEl: activeAnchorEl,
1128
+ registerActionButton: registerActionButton,
1129
+ actionMenuRef: actionMenuRef,
1130
+ toggleExpandRow: toggleExpandRow,
1131
+ handleSelectRow: handleSelectRow,
1132
+ toggleActions: toggleActions,
1133
+ handleOnAction: handleOnAction,
1134
+ closeActionMenu: closeActionMenu,
1135
+ renderCell: renderCell,
1136
+ className: className,
1137
+ interactive: interactive,
1138
+ activeCell: activeCell,
1139
+ editingCell: editingCell,
1140
+ onCellClick: handleCellClick,
1141
+ onCellDoubleClick: handleCellDoubleClick,
1142
+ renderInteractiveCellInput: renderInteractiveCellInput,
1143
+ invalidCellSet: invalidCellSet,
1144
+ pendingEdits: pendingEdits
1145
+ };
1146
+ var showToolbarBar = showToolbar || interactive && (isDirty || !!renderAddRowButton || !!renderExternalAddRow);
1147
+ var renderAddRowClickableRow = useCallback(function () {
1148
+ return jsx("tr", {
1149
+ onClick: function onClick() {
1150
+ return _handleAddRow(newRowPosition);
1151
+ },
1152
+ className: "bg-primary-50/40 hover:bg-primary-100/70 active:bg-primary-100 transition-colors border-t-2 border-b-2 border-dashed border-primary-300 cursor-pointer group",
1153
+ children: jsx("td", {
1154
+ colSpan: visibleCount,
1155
+ className: "px-6 py-3.5 text-left text-sm font-semibold text-primary-700 group-hover:text-primary-800",
1156
+ children: jsxs("div", {
1157
+ className: "flex items-center justify-start gap-2",
1158
+ children: [jsx(Plus, {
1159
+ className: "w-4 h-4 text-primary-600 group-hover:scale-110 transition-transform"
1160
+ }), jsx("span", {
1161
+ children: "Click here to add new record instantly...."
1162
+ })]
1163
+ })
1164
+ })
1165
+ });
1166
+ }, [_handleAddRow, newRowPosition, visibleCount]);
1167
+ return jsxs("div", {
1168
+ ref: tableContainerRef,
1169
+ tabIndex: interactive ? 0 : undefined,
1170
+ onKeyDown: handleTableKeyDown,
1171
+ className: cn("w-full border rounded-lg md:rounded-md outline-none focus:ring-1 focus:ring-primary-400", className),
1172
+ children: [TheadComponent && typeof TheadComponent === "function" ? jsx(TheadComponent, {
1173
+ columns: columnsState,
1174
+ data: filteredData
1175
+ }) : TheadComponent, showToolbarBar && jsxs("div", {
1176
+ className: "flex flex-col md:flex-row justify-between items-start md:items-center gap-3 p-4 border-b",
1177
+ children: [showToolbar && jsxs("div", {
1178
+ className: "flex flex-col sm:flex-row items-start sm:items-center gap-3 w-full md:w-auto",
1179
+ children: [showReloadButton && jsx(Fragment, {
1180
+ children: renderReloadButton ? typeof renderReloadButton === "function" ? renderReloadButton() : renderReloadButton : jsxs("button", {
1181
+ type: "button",
1182
+ className: "px-4 py-2 bg-primary-100 flex items-center gap-2 rounded-lg md:rounded text-primary-700 hover:bg-primary-200 transition-colors",
1183
+ onClick: onReload,
1184
+ children: [jsx(RefreshCcw, {
1185
+ className: "size-4"
1186
+ }), jsx("span", {
1187
+ className: "hidden sm:inline",
1188
+ children: "Reload"
1189
+ })]
1190
+ })
1191
+ }), showLimitSelector && jsxs("div", {
1192
+ className: "flex items-center gap-2",
1193
+ children: [jsx("label", {
1194
+ htmlFor: "pagination-limit",
1195
+ className: "text-sm whitespace-nowrap",
1196
+ children: "Show"
1197
+ }), jsx(Select, {
1198
+ options: limitOptionsForSelect,
1199
+ value: limit,
1200
+ allowClear: false,
1201
+ placeholder: "",
1202
+ onChange: handleLimitChange,
1203
+ className: "w-20 md:w-30"
1204
+ }), jsx("p", {
1205
+ className: "text-sm whitespace-nowrap",
1206
+ children: "entries"
1207
+ })]
1208
+ })]
1209
+ }), jsxs("div", {
1210
+ className: "flex flex-col sm:flex-row items-start sm:items-center gap-3 w-full md:w-auto",
1211
+ children: [interactive && (renderAddRowButton || renderExternalAddRow) && jsx("div", {
1212
+ className: "flex items-center gap-2",
1213
+ children: typeof (renderAddRowButton || renderExternalAddRow) === "function" ? (renderAddRowButton || renderExternalAddRow)({
1214
+ addRow: _handleAddRow,
1215
+ handleAddRow: _handleAddRow,
1216
+ newRowPosition: newRowPosition
1217
+ }) : renderAddRowButton || renderExternalAddRow
1218
+ }), interactive && isDirty && jsxs("div", {
1219
+ className: "flex items-center gap-2 flex-wrap",
1220
+ children: [jsxs("button", {
1221
+ type: "button",
1222
+ onClick: handleSave,
1223
+ disabled: !isValid || isSaving,
1224
+ title: !isValid ? "Cannot save: ".concat(((_validationErrors$ = validationErrors[0]) === null || _validationErrors$ === void 0 ? void 0 : _validationErrors$.message) || "Validation failed") : "Save changes",
1225
+ className: cn("px-4 py-2 font-medium rounded-lg text-sm flex items-center gap-2 transition-all shadow-sm", isValid ? "bg-primary-600 hover:bg-primary-700 active:bg-primary-800 text-white cursor-pointer" : "bg-gray-200 text-gray-400 border border-gray-300 cursor-not-allowed opacity-75"),
1226
+ children: [jsx(Save, {
1227
+ className: "w-4 h-4"
1228
+ }), jsx("span", {
1229
+ children: isSaving ? "Saving..." : "Save Changes"
1230
+ }), pendingCount > 0 && jsx("span", {
1231
+ className: cn("ml-1 px-2 py-0.5 text-xs rounded-full font-bold", isValid ? "bg-primary-700 text-white" : "bg-gray-300 text-gray-600"),
1232
+ children: pendingCount
1233
+ })]
1234
+ }), jsxs("button", {
1235
+ type: "button",
1236
+ onClick: handleClearChanges,
1237
+ disabled: isSaving,
1238
+ title: "Discard all pending modifications",
1239
+ className: "px-4 py-2 font-medium rounded-lg text-sm flex items-center gap-2 transition-all border border-primary-300 text-primary-700 bg-white hover:bg-primary-50 active:bg-primary-100 cursor-pointer shadow-sm disabled:opacity-50",
1240
+ children: [jsx(X, {
1241
+ className: "w-4 h-4 text-primary-600"
1242
+ }), jsx("span", {
1243
+ children: "Clear Changes"
1244
+ })]
1245
+ }), !isValid && validationErrors.length > 0 && jsxs("div", {
1246
+ className: "flex items-center gap-1.5 px-3 py-1.5 bg-warning-50 border border-warning-200 text-warning-800 rounded-md text-xs font-medium",
1247
+ children: [jsx(AlertCircle, {
1248
+ className: "w-4 h-4 text-warning-600 flex-shrink-0"
1249
+ }), jsx("span", {
1250
+ children: validationErrors[0].message
1251
+ }), validationErrors.length > 1 && jsxs("span", {
1252
+ className: "text-warning-600 font-bold ml-1",
1253
+ children: ["(+", validationErrors.length - 1, " more)"]
1254
+ })]
1255
+ })]
1256
+ }), showToolbar && jsxs("div", {
1257
+ className: "text-sm whitespace-nowrap",
1258
+ children: [resultRange.start, " - ", resultRange.end, " of ", resultRange.total, " ", "results"]
1259
+ }), showToolbar && pagination && jsx(PaginationHeader, {
1260
+ currentPage: pageIndex,
1261
+ totalPages: totalPages,
1262
+ onPageChange: handlePageChange,
1263
+ theme: safeTheme
1264
+ })]
1265
+ })]
1266
+ }), globalSearch && jsx("div", {
1267
+ className: "p-4 border-b",
1268
+ children: jsxs("div", {
1269
+ className: "flex flex-col sm:flex-row items-start sm:items-center gap-2",
1270
+ children: [jsxs("div", {
1271
+ className: "relative w-full",
1272
+ children: [jsx("input", {
1273
+ type: "text",
1274
+ placeholder: "Search...",
1275
+ className: "w-full rounded-lg md:rounded-md border border-gray-300 px-4 py-3 md:py-2 text-sm flex-1 outline-none pr-12",
1276
+ value: searchInput,
1277
+ onChange: function onChange(e) {
1278
+ return setSearchInput(e.target.value);
1279
+ },
1280
+ onKeyDown: onGlobalKeyDown
1281
+ }), jsx("button", {
1282
+ onClick: applyGlobalSearch,
1283
+ className: "absolute right-2 top-1/2 transform -translate-y-1/2 p-2 rounded-lg hover:bg-gray-100",
1284
+ title: "Search",
1285
+ children: jsx(Search, {
1286
+ className: "h-4 w-4 text-primary-400"
1287
+ })
1288
+ })]
1289
+ }), jsx("button", {
1290
+ onClick: function onClick() {
1291
+ setSearchInput("");
1292
+ handleFilter("global", "");
1293
+ },
1294
+ className: "whitespace-nowrap rounded-lg md:rounded-md border border-gray-300 px-4 py-3 md:py-2 text-sm hover:bg-gray-100 w-full sm:w-auto",
1295
+ children: "Clear"
1296
+ })]
1297
+ })
1298
+ }), filterable && isMobileView && jsx(MobileFilters, {
1299
+ showMobileFilters: showMobileFilters,
1300
+ setShowMobileFilters: setShowMobileFilters,
1301
+ globalSearch: globalSearch,
1302
+ searchInput: searchInput,
1303
+ setSearchInput: setSearchInput,
1304
+ onGlobalKeyDown: onGlobalKeyDown,
1305
+ filterable: filterable,
1306
+ visibleColumns: visibleColumns,
1307
+ filters: filters,
1308
+ handleFilter: handleFilter
1309
+ }), columnPickerVisible && showColumnMenu && jsx(ColumnMenu, {
1310
+ id: columnMenuId,
1311
+ columns: columnsState,
1312
+ onToggle: toggleColumnVisibility,
1313
+ menuRef: columnMenuRef,
1314
+ theme: safeTheme
1315
+ }), !isMobileView && jsx("div", {
1316
+ className: "overflow-x-auto overflow-y-visible",
1317
+ children: jsxs("table", _objectSpread2(_objectSpread2({
1318
+ className: cn("min-w-full divide-y divide-gray-200", className)
1319
+ }, props), {}, {
1320
+ children: [jsxs("thead", {
1321
+ className: safeTheme.accentColor,
1322
+ children: [jsxs("tr", {
1323
+ children: [hasDetailsColumn && jsx("th", {
1324
+ className: "w-8 px-4 py-3"
1325
+ }), showSerial && jsx("th", {
1326
+ className: "w-8 px-4 py-3 text-left text-xs font-medium text-primary-500 uppercase tracking-wider",
1327
+ children: "#"
1328
+ }), selectable && jsx("th", {
1329
+ className: "w-12 px-6 py-3",
1330
+ children: jsx("input", {
1331
+ type: "checkbox",
1332
+ className: "rounded border-gray-300",
1333
+ checked: allPageSelected,
1334
+ onChange: handleSelectAll
1335
+ })
1336
+ }), visibleColumns.map(function (column) {
1337
+ var _column$rules;
1338
+ return jsx("th", {
1339
+ className: cn("px-6 py-3 text-left text-xs font-medium text-primary-500 uppercase tracking-wider", {
1340
+ "cursor-pointer hover:bg-gray-100": sortable && column.sortable !== false
1341
+ }),
1342
+ onClick: function onClick() {
1343
+ return column.sortable !== false && handleSort(column.key);
1344
+ },
1345
+ children: jsxs("div", {
1346
+ className: "flex items-center gap-1",
1347
+ children: [jsx("span", {
1348
+ children: column.label
1349
+ }), (column.required || ((_column$rules = column.rules) === null || _column$rules === void 0 ? void 0 : _column$rules.required)) && jsx("span", {
1350
+ className: "text-error-500 font-bold ml-0.5",
1351
+ title: "Required field",
1352
+ children: "*"
1353
+ }), sortable && column.sortable !== false && jsxs("div", {
1354
+ className: "flex flex-col",
1355
+ children: [jsx(ChevronUp, {
1356
+ className: cn("h-3 w-3", {
1357
+ "text-primary-600": sortConfig.key === column.key && sortConfig.direction === "asc"
1358
+ })
1359
+ }), jsx(ChevronDown, {
1360
+ className: cn("h-3 w-3 -mt-1", {
1361
+ "text-primary-600": sortConfig.key === column.key && sortConfig.direction === "desc"
1362
+ })
1363
+ })]
1364
+ })]
1365
+ })
1366
+ }, column.key);
1367
+ }), columnPickerVisible && jsx("th", {
1368
+ className: "w-12 px-4 py-3",
1369
+ children: jsx("div", {
1370
+ className: "relative inline-block",
1371
+ children: jsx("button", {
1372
+ type: "button",
1373
+ ref: columnToggleBtnRef,
1374
+ title: "Choose columns",
1375
+ "aria-label": "Choose columns",
1376
+ "aria-expanded": showColumnMenu,
1377
+ "aria-controls": showColumnMenu ? columnMenuId : undefined,
1378
+ onClick: function onClick(e) {
1379
+ e.stopPropagation();
1380
+ setShowColumnMenu(function (s) {
1381
+ return !s;
1382
+ });
1383
+ },
1384
+ className: "p-1 rounded hover:bg-gray-100",
1385
+ children: jsx(MoreVertical, {
1386
+ className: "h-4 w-4"
1387
+ })
1388
+ })
1389
+ })
1390
+ }), withAction && jsx("th", {
1391
+ className: "w-12 px-4 py-3"
1392
+ })]
1393
+ }), filterable && jsxs("tr", {
1394
+ children: [hasDetailsColumn && jsx("th", {
1395
+ className: "pb-4"
1396
+ }), showSerial && jsx("th", {
1397
+ className: "pb-4"
1398
+ }), selectable && jsx("th", {
1399
+ className: "pb-4"
1400
+ }), visibleColumns.map(function (column) {
1401
+ return jsx("th", {
1402
+ className: "px-6 pb-4",
1403
+ children: jsx("input", {
1404
+ type: "text",
1405
+ placeholder: "Filter ".concat(column.label),
1406
+ className: "w-full rounded-md border border-gray-300 px-3 py-1.5 text-sm font-normal",
1407
+ value: filters[column.key] || "",
1408
+ onChange: function onChange(e) {
1409
+ return handleFilter(column.key, e.target.value);
1410
+ }
1411
+ })
1412
+ }, column.key);
1413
+ }), columnPickerVisible && jsx("th", {
1414
+ className: "pb-4"
1415
+ }), withAction && jsx("th", {
1416
+ className: "pb-4"
1417
+ })]
1418
+ })]
1419
+ }), jsx("tbody", {
1420
+ className: "divide-y divide-gray-200",
1421
+ children: loading ? jsx("tr", {
1422
+ children: jsx("td", {
1423
+ colSpan: visibleCount,
1424
+ className: "px-6 py-8 text-center",
1425
+ children: jsxs("div", {
1426
+ className: "flex flex-col items-center gap-2",
1427
+ children: [jsx("div", {
1428
+ className: "h-6 w-6 animate-spin rounded-full border-2 border-primary-600 border-t-transparent"
1429
+ }), jsx("span", {
1430
+ className: "text-sm text-primary-500",
1431
+ children: "Loading..."
1432
+ })]
1433
+ })
1434
+ })
1435
+ }) : paginatedData.length === 0 && newRows.length === 0 ? jsxs(Fragment, {
1436
+ children: [interactive && newRowPosition === "top" && renderAddRowClickableRow(), jsx("tr", {
1437
+ children: jsx("td", {
1438
+ colSpan: visibleCount,
1439
+ className: "px-6 py-8 text-center",
1440
+ children: jsxs("div", {
1441
+ className: "flex flex-col items-center gap-2",
1442
+ children: [jsx("div", {
1443
+ className: "text-primary-400",
1444
+ children: jsx(List, {
1445
+ className: "h-8 w-8"
1446
+ })
1447
+ }), jsx("span", {
1448
+ className: "text-sm text-primary-500",
1449
+ children: "No results found."
1450
+ })]
1451
+ })
1452
+ })
1453
+ }), interactive && newRowPosition !== "top" && renderAddRowClickableRow()]
1454
+ }) : jsxs(Fragment, {
1455
+ children: [interactive && newRowPosition === "top" && renderAddRowClickableRow(), interactive && newRowPosition === "top" && newRows.map(function (newRow, newIdx) {
1456
+ return jsx(TableRow, _objectSpread2({
1457
+ row: newRow,
1458
+ rowIndexInPage: newIdx,
1459
+ startIndex: 0,
1460
+ visibleCount: visibleCount,
1461
+ isNewRow: true,
1462
+ onDeleteNewRow: handleDeleteNewRow
1463
+ }, rowSharedProps), newRow._key);
1464
+ }), paginatedData.map(function (row, rowIndexInPage) {
1465
+ return jsx(TableRow, _objectSpread2({
1466
+ row: row,
1467
+ rowIndexInPage: rowIndexInPage,
1468
+ startIndex: startIndex,
1469
+ visibleCount: visibleCount
1470
+ }, rowSharedProps), getRowKey(row, startIndex + rowIndexInPage));
1471
+ }), interactive && newRowPosition !== "top" && newRows.map(function (newRow, newIdx) {
1472
+ return jsx(TableRow, _objectSpread2({
1473
+ row: newRow,
1474
+ rowIndexInPage: paginatedData.length + newIdx,
1475
+ startIndex: 0,
1476
+ visibleCount: visibleCount,
1477
+ isNewRow: true,
1478
+ onDeleteNewRow: handleDeleteNewRow
1479
+ }, rowSharedProps), newRow._key);
1480
+ }), interactive && newRowPosition !== "top" && renderAddRowClickableRow()]
1481
+ })
1482
+ })]
1483
+ }))
1484
+ }), isMobileView && jsx("div", {
1485
+ className: "p-4",
1486
+ children: loading ? jsx("div", {
1487
+ className: "py-8 text-center",
1488
+ children: jsxs("div", {
1489
+ className: "flex flex-col items-center gap-2",
1490
+ children: [jsx("div", {
1491
+ className: "h-6 w-6 animate-spin rounded-full border-2 border-primary-600 border-t-transparent"
1492
+ }), jsx("span", {
1493
+ className: "text-sm text-primary-500",
1494
+ children: "Loading..."
1495
+ })]
1496
+ })
1497
+ }) : paginatedData.length === 0 ? jsx("div", {
1498
+ className: "py-8 text-center",
1499
+ children: jsxs("div", {
1500
+ className: "flex flex-col items-center gap-2",
1501
+ children: [jsx("div", {
1502
+ className: "text-primary-400",
1503
+ children: jsx(List, {
1504
+ className: "h-8 w-8"
1505
+ })
1506
+ }), jsx("span", {
1507
+ className: "text-sm text-primary-500",
1508
+ children: "No results found."
1509
+ })]
1510
+ })
1511
+ }) : paginatedData.map(function (row, rowIndexInPage) {
1512
+ return jsx(MobileCard, _objectSpread2(_objectSpread2({
1513
+ row: row,
1514
+ rowIndexInPage: rowIndexInPage,
1515
+ startIndex: startIndex
1516
+ }, rowSharedProps), {}, {
1517
+ visibleColumns: mobileColumns
1518
+ }), getRowKey(row, startIndex + rowIndexInPage));
1519
+ })
1520
+ }), TfootComponent && typeof TfootComponent === "function" ? jsx(TfootComponent, {
1521
+ columns: columnsState,
1522
+ data: filteredData
1523
+ }) : TfootComponent, pagination && jsx(PaginationFooter, {
1524
+ currentPage: pageIndex,
1525
+ totalPages: totalPages,
1526
+ onPageChange: handlePageChange,
1527
+ isMobileView: isMobileView,
1528
+ theme: safeTheme
1529
+ })]
1530
+ });
1531
+ });
1532
+
1533
+ export { Table as default };