react-restyle-components 0.4.45 → 0.4.47

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 (233) hide show
  1. package/lib/index.js +1 -3
  2. package/lib/src/core-components/index.js +1 -1
  3. package/lib/src/core-components/src/components/Accordion/AccordionSection/Accordion.js +1 -15
  4. package/lib/src/core-components/src/components/Accordion/AccordionSection/AccordionContext.js +1 -6
  5. package/lib/src/core-components/src/components/Accordion/AccordionSection/AccordionSection.js +1 -39
  6. package/lib/src/core-components/src/components/Accordion/AccordionSection/Header.js +1 -39
  7. package/lib/src/core-components/src/components/Accordion/AccordionSection/elements.js +57 -94
  8. package/lib/src/core-components/src/components/Accordion/AccordionSection/hooks/useCurrentAccordionIndex.js +1 -13
  9. package/lib/src/core-components/src/components/Accordion/AccordionSection/index.js +1 -3
  10. package/lib/src/core-components/src/components/Accordion/AccordionSection/types.js +1 -9
  11. package/lib/src/core-components/src/components/Accordion/Collapsible/Collapsible2.component.js +1 -249
  12. package/lib/src/core-components/src/components/Action/types.js +1 -8
  13. package/lib/src/core-components/src/components/AlertBanner/AlertBanner.js +1 -45
  14. package/lib/src/core-components/src/components/AlertBanner/elements.js +45 -120
  15. package/lib/src/core-components/src/components/AlertBanner/index.js +1 -2
  16. package/lib/src/core-components/src/components/AlertBanner/types.js +1 -10
  17. package/lib/src/core-components/src/components/AutoComplete/auto-complete-filter-group-by-multiple-select-multiple-fields-display/auto-complete-filter-group-by-multiple-select-multiple-fields-display.component.js +1 -451
  18. package/lib/src/core-components/src/components/AutoComplete/auto-complete-filter-multi-select-multi-fields-display-drag-drop/auto-complete-filter-multi-select-multi-fields-display-drag-drop.component.js +1 -229
  19. package/lib/src/core-components/src/components/AutoComplete/auto-complete-filter-multi-select-selected-top-display/auto-complete-filter-multi-select-selected-top-display.component.js +1 -174
  20. package/lib/src/core-components/src/components/AutoComplete/auto-complete-filter-multiple-select-multiple-fields-display/auto-complete-filter-multiple-select-multiple-fields-display.component.js +2 -129
  21. package/lib/src/core-components/src/components/AutoComplete/auto-complete-filter-single-select/auto-complete-filter-single-select.component.js +1 -55
  22. package/lib/src/core-components/src/components/AutoComplete/auto-complete-filter-single-select-multiple-fields-display/auto-complete-filter-single-select-multiple-fields-display.component.js +2 -308
  23. package/lib/src/core-components/src/components/AutoComplete/auto-complete-group-by/auto-complete-group-by.component.js +1 -115
  24. package/lib/src/core-components/src/components/AutoComplete/autocomplete/autocomplete.js +2 -442
  25. package/lib/src/core-components/src/components/AutoComplete/index.js +1 -8
  26. package/lib/src/core-components/src/components/Avatar/Avatar.js +14 -148
  27. package/lib/src/core-components/src/components/Badge/Badge.js +2 -25
  28. package/lib/src/core-components/src/components/Badge/InnerBadge/Inline.js +1 -25
  29. package/lib/src/core-components/src/components/Badge/InnerBadge/InnerBadge.js +1 -25
  30. package/lib/src/core-components/src/components/Badge/InnerBadge/elements.js +32 -78
  31. package/lib/src/core-components/src/components/Badge/InnerBadge/index.js +1 -1
  32. package/lib/src/core-components/src/components/Badge/index.js +1 -1
  33. package/lib/src/core-components/src/components/Badge/types.js +1 -5
  34. package/lib/src/core-components/src/components/Breadcrumb/Breadcrumb.js +1 -83
  35. package/lib/src/core-components/src/components/Breadcrumb/elements.js +94 -166
  36. package/lib/src/core-components/src/components/Breadcrumb/index.js +1 -3
  37. package/lib/src/core-components/src/components/Breadcrumb/types.js +1 -3
  38. package/lib/src/core-components/src/components/Button/button.component.js +1 -18
  39. package/lib/src/core-components/src/components/Button/buttonGroup/buttonGroup.component.js +1 -4
  40. package/lib/src/core-components/src/components/Button/index.js +1 -2
  41. package/lib/src/core-components/src/components/Button/types.js +1 -1
  42. package/lib/src/core-components/src/components/Chip/Chip.js +1 -64
  43. package/lib/src/core-components/src/components/Chip/elements.js +48 -148
  44. package/lib/src/core-components/src/components/Chip/index.js +1 -2
  45. package/lib/src/core-components/src/components/Chip/types.js +1 -4
  46. package/lib/src/core-components/src/components/Divider/Divider.js +1 -25
  47. package/lib/src/core-components/src/components/Divider/elements.js +31 -68
  48. package/lib/src/core-components/src/components/Divider/index.js +1 -2
  49. package/lib/src/core-components/src/components/Divider/types.js +1 -4
  50. package/lib/src/core-components/src/components/DynamicGrid/DynamicGrid.js +1 -147
  51. package/lib/src/core-components/src/components/DynamicGrid/GridContainer.js +17 -24
  52. package/lib/src/core-components/src/components/DynamicGrid/elements.js +100 -162
  53. package/lib/src/core-components/src/components/DynamicGrid/index.js +1 -3
  54. package/lib/src/core-components/src/components/DynamicGrid/types.js +1 -28
  55. package/lib/src/core-components/src/components/DynamicGrid/utils.js +1 -193
  56. package/lib/src/core-components/src/components/FormField/FormField.js +1 -103
  57. package/lib/src/core-components/src/components/FormField/components/CheckboxGroupInput.js +1 -37
  58. package/lib/src/core-components/src/components/FormField/components/CheckboxInput.js +1 -8
  59. package/lib/src/core-components/src/components/FormField/components/CssMultilineInput.js +1 -192
  60. package/lib/src/core-components/src/components/FormField/components/DatePickerInput.js +1 -99
  61. package/lib/src/core-components/src/components/FormField/components/DropdownInput.js +1 -70
  62. package/lib/src/core-components/src/components/FormField/components/OtpInput.js +1 -81
  63. package/lib/src/core-components/src/components/FormField/components/PasswordInput.js +1 -40
  64. package/lib/src/core-components/src/components/FormField/components/PinInput.js +1 -75
  65. package/lib/src/core-components/src/components/FormField/components/RadioInput.js +1 -54
  66. package/lib/src/core-components/src/components/FormField/components/TextDropdownInput.js +1 -94
  67. package/lib/src/core-components/src/components/FormField/components/ToggleInput.js +1 -36
  68. package/lib/src/core-components/src/components/FormField/components/index.js +1 -11
  69. package/lib/src/core-components/src/components/FormField/css-properties.js +1 -161
  70. package/lib/src/core-components/src/components/FormField/index.js +1 -2
  71. package/lib/src/core-components/src/components/Icon/Icon.js +1 -159
  72. package/lib/src/core-components/src/components/Icon/index.js +1 -2
  73. package/lib/src/core-components/src/components/Icon/types.js +1 -9
  74. package/lib/src/core-components/src/components/Loader/loader.component.js +2 -215
  75. package/lib/src/core-components/src/components/Masonry/Masonry.js +1 -73
  76. package/lib/src/core-components/src/components/Masonry/elements.js +29 -46
  77. package/lib/src/core-components/src/components/Masonry/hooks.js +1 -100
  78. package/lib/src/core-components/src/components/Masonry/index.js +1 -3
  79. package/lib/src/core-components/src/components/Masonry/types.js +1 -1
  80. package/lib/src/core-components/src/components/Modal/BasicModal/modal.component.js +1 -116
  81. package/lib/src/core-components/src/components/Modal/index.js +1 -2
  82. package/lib/src/core-components/src/components/Modal/modal-confirm/modal-confirm.component.js +1 -147
  83. package/lib/src/core-components/src/components/Picker/color-picker/color-picker.component.js +1 -12
  84. package/lib/src/core-components/src/components/Picker/color-picker-modal/color-picker-modal.component.js +1 -40
  85. package/lib/src/core-components/src/components/Picker/index.js +1 -2
  86. package/lib/src/core-components/src/components/Selection/index.js +1 -4
  87. package/lib/src/core-components/src/components/Selection/multi-select/multi-select.component.js +1 -49
  88. package/lib/src/core-components/src/components/Selection/multi-select-with-field/multi-select-with-field.component.js +1 -58
  89. package/lib/src/core-components/src/components/Selection/multi-selection-dropdown/multi-selection-dropdown.component.js +1 -43
  90. package/lib/src/core-components/src/components/Selection/single-select/single-select.component.js +1 -87
  91. package/lib/src/core-components/src/components/Skeleton/Skeleton.js +1 -51
  92. package/lib/src/core-components/src/components/Skeleton/elements.js +54 -143
  93. package/lib/src/core-components/src/components/Skeleton/index.js +1 -2
  94. package/lib/src/core-components/src/components/Skeleton/types.js +1 -4
  95. package/lib/src/core-components/src/components/SpeedDial/SpeedDial.js +1 -128
  96. package/lib/src/core-components/src/components/SpeedDial/elements.js +62 -132
  97. package/lib/src/core-components/src/components/SpeedDial/index.js +1 -2
  98. package/lib/src/core-components/src/components/SpeedDial/types.js +1 -3
  99. package/lib/src/core-components/src/components/Stepper2/stepper.component.js +1 -139
  100. package/lib/src/core-components/src/components/Switch/Switch.js +1 -26
  101. package/lib/src/core-components/src/components/Switch/elements.js +34 -103
  102. package/lib/src/core-components/src/components/Switch/index.js +1 -2
  103. package/lib/src/core-components/src/components/Switch/types.js +1 -3
  104. package/lib/src/core-components/src/components/Table/Table.js +1 -1497
  105. package/lib/src/core-components/src/components/Table/columnReorder.js +36 -332
  106. package/lib/src/core-components/src/components/Table/columnResize.js +21 -284
  107. package/lib/src/core-components/src/components/Table/elements.d.ts +6 -1
  108. package/lib/src/core-components/src/components/Table/elements.js +203 -275
  109. package/lib/src/core-components/src/components/Table/filters.js +30 -555
  110. package/lib/src/core-components/src/components/Table/hooks.js +2 -536
  111. package/lib/src/core-components/src/components/Table/index.js +1 -6
  112. package/lib/src/core-components/src/components/Table/types.d.ts +1 -1
  113. package/lib/src/core-components/src/components/Table/types.js +1 -1
  114. package/lib/src/core-components/src/components/Tabs/tabs.component.js +1 -22
  115. package/lib/src/core-components/src/components/Tags1/Tags.component.js +1 -118
  116. package/lib/src/core-components/src/components/Tags1/types.js +1 -20
  117. package/lib/src/core-components/src/components/Timer1/timer.component.js +1 -76
  118. package/lib/src/core-components/src/components/Toast/Toast.js +1 -50
  119. package/lib/src/core-components/src/components/Toast/elements.js +41 -122
  120. package/lib/src/core-components/src/components/Toast/index.js +1 -2
  121. package/lib/src/core-components/src/components/Toast/types.js +1 -9
  122. package/lib/src/core-components/src/components/Tooltip/Tooltip.js +1 -200
  123. package/lib/src/core-components/src/components/Tooltip/elements.js +55 -117
  124. package/lib/src/core-components/src/components/Tooltip/index.js +1 -2
  125. package/lib/src/core-components/src/components/Tooltip/types.js +1 -17
  126. package/lib/src/core-components/src/components/Tooltip/utils.js +1 -140
  127. package/lib/src/core-components/src/components/TreeSelect/TreeSelect.js +1 -303
  128. package/lib/src/core-components/src/components/TreeSelect/elements.js +117 -216
  129. package/lib/src/core-components/src/components/TreeSelect/hooks.js +1 -252
  130. package/lib/src/core-components/src/components/TreeSelect/index.js +1 -3
  131. package/lib/src/core-components/src/components/TreeSelect/types.js +1 -1
  132. package/lib/src/core-components/src/components/ag-grid/AgGrid.js +1 -1057
  133. package/lib/src/core-components/src/components/ag-grid/elements.js +396 -790
  134. package/lib/src/core-components/src/components/ag-grid/hooks.js +4 -1220
  135. package/lib/src/core-components/src/components/ag-grid/index.js +1 -15
  136. package/lib/src/core-components/src/components/ag-grid/types.js +1 -6
  137. package/lib/src/core-components/src/components/index.js +1 -31
  138. package/lib/src/core-components/src/components/pdf/pdf-images.components.js +1 -7
  139. package/lib/src/core-components/src/components/pdf/pdf-table.components.js +5 -48
  140. package/lib/src/core-components/src/components/pdf/pdf-typography.components.js +1 -70
  141. package/lib/src/core-components/src/components/pdf/pdf-wrapped-view.components.js +1 -50
  142. package/lib/src/core-components/src/core-components/Avatar.js +4 -33
  143. package/lib/src/core-components/src/core-components/CoreButton/CoreButton.js +1 -10
  144. package/lib/src/core-components/src/core-components/CoreButton/elements.js +67 -176
  145. package/lib/src/core-components/src/core-components/CoreButton/index.js +1 -3
  146. package/lib/src/core-components/src/core-components/CoreButton/types.js +1 -6
  147. package/lib/src/core-components/src/core-components/CoreButton/utils.js +1 -12
  148. package/lib/src/core-components/src/core-components/Divider/Divider.js +4 -19
  149. package/lib/src/core-components/src/core-components/Divider/index.js +1 -1
  150. package/lib/src/core-components/src/core-components/SelectionCardStrip/index.js +1 -1
  151. package/lib/src/core-components/src/core-components/SelectionCardStrip/selectionCardStrip.js +10 -33
  152. package/lib/src/core-components/src/core-components/StateLayer.js +3 -5
  153. package/lib/src/core-components/src/core-components/ToggleCore/elements.js +25 -50
  154. package/lib/src/core-components/src/core-components/ToggleCore/index.js +1 -2
  155. package/lib/src/core-components/src/core-components/ToggleCore/toggleCore.js +1 -14
  156. package/lib/src/core-components/src/core-components/atoms/Input/Input.js +1 -22
  157. package/lib/src/core-components/src/core-components/atoms/Label/Label.js +1 -21
  158. package/lib/src/core-components/src/core-components/atoms/Textarea/Textarea.js +1 -19
  159. package/lib/src/core-components/src/core-components/index.js +1 -3
  160. package/lib/src/core-components/src/helpers/constants.js +1 -11
  161. package/lib/src/core-components/src/hooks/index.js +1 -1
  162. package/lib/src/core-components/src/hooks/outside.hook.js +1 -28
  163. package/lib/src/core-components/src/index.js +1 -12
  164. package/lib/src/core-components/src/tc.global.css +3 -0
  165. package/lib/src/core-components/src/utils/abstracts/breakpoints/index.js +1 -28
  166. package/lib/src/core-components/src/utils/abstracts/colors/index.js +1 -49
  167. package/lib/src/core-components/src/utils/abstracts/index.js +1 -5
  168. package/lib/src/core-components/src/utils/abstracts/space/index.js +1 -26
  169. package/lib/src/core-components/src/utils/abstracts/theme/ThemeBoundary.js +1 -8
  170. package/lib/src/core-components/src/utils/abstracts/theme/default-themes.js +1 -30
  171. package/lib/src/core-components/src/utils/abstracts/theme/index.js +1 -3
  172. package/lib/src/core-components/src/utils/abstracts/theme/theme.js +1 -30
  173. package/lib/src/core-components/src/utils/abstracts/theme/types.js +1 -1
  174. package/lib/src/core-components/src/utils/abstracts/theme/useTheme.js +1 -17
  175. package/lib/src/core-components/src/utils/abstracts/typography/index.js +1 -25
  176. package/lib/src/core-components/src/utils/context/DefaultsProvider.js +1 -8
  177. package/lib/src/core-components/src/utils/context/InternalProvider.js +1 -24
  178. package/lib/src/core-components/src/utils/context/index.js +1 -2
  179. package/lib/src/core-components/src/utils/designTokens.js +1 -128
  180. package/lib/src/core-components/src/utils/helpers/attachSubComponents.js +1 -23
  181. package/lib/src/core-components/src/utils/helpers/flattenChildren.js +1 -11
  182. package/lib/src/core-components/src/utils/helpers/getChildByType.js +1 -3
  183. package/lib/src/core-components/src/utils/helpers/index.js +1 -5
  184. package/lib/src/core-components/src/utils/helpers/isComponentType.js +1 -16
  185. package/lib/src/core-components/src/utils/helpers/separateChildrenByType.js +1 -12
  186. package/lib/src/core-components/src/utils/hooks/index.js +1 -18
  187. package/lib/src/core-components/src/utils/hooks/useClickOutside.js +1 -18
  188. package/lib/src/core-components/src/utils/hooks/useCombinedRefs.js +1 -17
  189. package/lib/src/core-components/src/utils/hooks/useDebouncedCallback.js +1 -12
  190. package/lib/src/core-components/src/utils/hooks/useDebouncedValue.js +1 -20
  191. package/lib/src/core-components/src/utils/hooks/useDeprecation.js +1 -40
  192. package/lib/src/core-components/src/utils/hooks/useDeviceDetect.js +1 -10
  193. package/lib/src/core-components/src/utils/hooks/useDeviceForm.js +1 -24
  194. package/lib/src/core-components/src/utils/hooks/useDisableBodyScroll.js +1 -16
  195. package/lib/src/core-components/src/utils/hooks/useHoverState.js +1 -36
  196. package/lib/src/core-components/src/utils/hooks/useId.js +1 -7
  197. package/lib/src/core-components/src/utils/hooks/useIsBrowser.js +1 -11
  198. package/lib/src/core-components/src/utils/hooks/useMediaQuery.js +1 -16
  199. package/lib/src/core-components/src/utils/hooks/useOverflow.js +1 -22
  200. package/lib/src/core-components/src/utils/hooks/useSafeLayoutEffect.js +1 -5
  201. package/lib/src/core-components/src/utils/hooks/useScrollingUp.js +1 -18
  202. package/lib/src/core-components/src/utils/hooks/useTrapFocus.js +1 -30
  203. package/lib/src/core-components/src/utils/hooks/useWindowDimensions.js +1 -23
  204. package/lib/src/core-components/src/utils/index.js +1 -9
  205. package/lib/src/core-components/src/utils/stories/Wrappers.js +8 -23
  206. package/lib/src/core-components/src/utils/stories/cleanProps.js +1 -5
  207. package/lib/src/core-components/src/utils/stories/index.js +1 -4
  208. package/lib/src/core-components/src/utils/stories/sleep.js +1 -4
  209. package/lib/src/core-components/src/utils/stories/view-ports.js +1 -50
  210. package/lib/src/core-components/src/utils/styling/calcWidthOfColumns.js +1 -5
  211. package/lib/src/core-components/src/utils/styling/createGridContainer.js +6 -12
  212. package/lib/src/core-components/src/utils/styling/createTransition.js +2 -7
  213. package/lib/src/core-components/src/utils/styling/forwardProps.js +1 -10
  214. package/lib/src/core-components/src/utils/styling/index.js +1 -5
  215. package/lib/src/core-components/src/utils/styling/pxToRem.js +1 -6
  216. package/lib/src/core-components/src/utils/testing/getComputedStyle.js +1 -3
  217. package/lib/src/core-components/src/utils/testing/index.js +1 -1
  218. package/lib/src/core-components/src/utils/utility.util.js +1 -14
  219. package/lib/src/core-components/tailwind.config.js +1 -233
  220. package/lib/src/core-hooks/index.js +1 -3
  221. package/lib/src/core-hooks/src/useClickOutside/useClickOutside.hook.js +1 -46
  222. package/lib/src/core-hooks/src/useDebounce/useDebounce.hook.js +1 -30
  223. package/lib/src/core-hooks/src/usePreventEKey/usePreventEKey.hook.js +1 -8
  224. package/lib/src/core-utils/index.js +1 -7
  225. package/lib/src/core-utils/src/calculation/calculation.util.js +1 -89
  226. package/lib/src/core-utils/src/colors/color.util.js +1 -15
  227. package/lib/src/core-utils/src/convert/numberToWords/numToWords.util.js +1 -145
  228. package/lib/src/core-utils/src/convert/typography/camelCaseToTitleCase.util.js +1 -5
  229. package/lib/src/core-utils/src/form-helper/form-helper.util.js +1 -82
  230. package/lib/src/core-utils/src/index.js +1 -7
  231. package/lib/src/core-utils/src/utility/utility.util.js +1 -12
  232. package/lib/src/core-utils/src/uuid/uuid.util.js +1 -8
  233. package/package.json +1 -1
@@ -1,1497 +1 @@
1
- 'use client';
2
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
- import React, { forwardRef, useState, useCallback, useMemo, useEffect, useRef, } from 'react';
4
- import { TableRoot, Toolbar, ToolbarGroup, SearchInput, ToolbarButton, TableWrapper, StyledTable, TableHeader, HeaderRow, HeaderCell, TableBody, TableRow, TableCell, Checkbox, ExpandButton, ExpandedRow, ExpandedCell, TableFooter, FooterRow, FooterCell, PaginationWrapper, PaginationInfo, PaginationControls, PageButton, PageSizeSelect, QuickJumper, EmptyState, LoadingOverlay, LoadingSpinner, EditableCell, CellEditor, ColumnTogglePanel, ColumnToggleHeader, ColumnToggleSearch, ColumnToggleList, ColumnToggleItem, ColumnToggleDragHandle, SelectionIndicator, SelectionCount, } from './elements';
5
- import { useSortState, useFilterState, usePaginationState, useRowSelection, useRowExpansion, useColumnVisibility, useTableDebounce, sortData, filterData, paginateData, getNestedValue, exportToCSV, exportToExcel, } from './hooks';
6
- import { getFilterComponent } from './filters';
7
- import { Tooltip } from '../Tooltip';
8
- import { useColumnResize, getColumnStyle } from './columnResize';
9
- // Column reorder is handled internally via popup drag & drop
10
- // Icons
11
- const SearchIcon = () => (_jsxs("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: [_jsx("circle", { cx: "11", cy: "11", r: "8" }), _jsx("path", { d: "M21 21l-4.35-4.35", strokeLinecap: "round" })] }));
12
- // Arrow Up Icon with configurable size
13
- // Arrow Up Icon - stroke-based arrow pointing up (like BsArrowUp)
14
- const ArrowUpIcon = ({ size = 16, color = 'white', }) => (_jsx("svg", { viewBox: "0 0 16 16", fill: color, style: { width: size, height: size, display: 'block' }, children: _jsx("path", { fillRule: "evenodd", d: "M8 15a.5.5 0 0 0 .5-.5V2.707l3.146 3.147a.5.5 0 0 0 .708-.708l-4-4a.5.5 0 0 0-.708 0l-4 4a.5.5 0 1 0 .708.708L7.5 2.707V14.5a.5.5 0 0 0 .5.5z" }) }));
15
- // Arrow Down Icon - stroke-based arrow pointing down (like BsArrowDown)
16
- const ArrowDownIcon = ({ size = 16, color = 'white', }) => (_jsx("svg", { viewBox: "0 0 16 16", fill: color, style: { width: size, height: size, display: 'block' }, children: _jsx("path", { fillRule: "evenodd", d: "M8 1a.5.5 0 0 1 .5.5v11.793l3.146-3.147a.5.5 0 0 1 .708.708l-4 4a.5.5 0 0 1-.708 0l-4-4a.5.5 0 0 1 .708-.708L7.5 13.293V1.5A.5.5 0 0 1 8 1z" }) }));
17
- // Default sort caret component with arrow icons (matches BsArrowUp/BsArrowDown style)
18
- const DefaultSortCaret = ({ order, }) => {
19
- // Size configuration based on sort order (like your custom sortCaret)
20
- const getSizeConfig = () => {
21
- switch (order) {
22
- case 'asc':
23
- return { up: 18, down: 12 };
24
- case 'desc':
25
- return { up: 12, down: 18 };
26
- default:
27
- return { up: 16, down: 16 };
28
- }
29
- };
30
- const { up, down } = getSizeConfig();
31
- return (_jsxs("div", { style: {
32
- display: 'flex',
33
- flexDirection: 'row',
34
- alignItems: 'center',
35
- justifyContent: 'center',
36
- gap: 0,
37
- }, children: [_jsx(ArrowUpIcon, { size: up, color: "white" }), _jsx(ArrowDownIcon, { size: down, color: "white" })] }));
38
- };
39
- const ChevronLeftIcon = () => (_jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: _jsx("path", { d: "M15 18l-6-6 6-6", strokeLinecap: "round", strokeLinejoin: "round" }) }));
40
- const ChevronRightIcon = () => (_jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: _jsx("path", { d: "M9 18l6-6-6-6", strokeLinecap: "round", strokeLinejoin: "round" }) }));
41
- const ChevronsLeftIcon = () => (_jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: _jsx("path", { d: "M11 17l-5-5 5-5M18 17l-5-5 5-5", strokeLinecap: "round", strokeLinejoin: "round" }) }));
42
- const ChevronsRightIcon = () => (_jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: _jsx("path", { d: "M13 7l5 5-5 5M6 7l5 5-5 5", strokeLinecap: "round", strokeLinejoin: "round" }) }));
43
- const ExpandIcon = () => (_jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: _jsx("path", { d: "M9 18l6-6-6-6", strokeLinecap: "round", strokeLinejoin: "round" }) }));
44
- const CloseIcon = () => (_jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: _jsx("path", { d: "M18 6L6 18M6 6l12 12", strokeLinecap: "round", strokeLinejoin: "round" }) }));
45
- const FilterIcon = () => (_jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: _jsx("path", { d: "M22 3H2l8 9.46V19l4 2v-8.54L22 3z", strokeLinecap: "round", strokeLinejoin: "round" }) }));
46
- const DownloadIcon = () => (_jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: _jsx("path", { d: "M21 15v4a2 2 0 01-2 2H5a2 2 0 01-2-2v-4M7 10l5 5 5-5M12 15V3", strokeLinecap: "round", strokeLinejoin: "round" }) }));
47
- const ColumnsIcon = () => (_jsxs("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: [_jsx("rect", { x: "3", y: "3", width: "7", height: "18", rx: "1" }), _jsx("rect", { x: "14", y: "3", width: "7", height: "18", rx: "1" })] }));
48
- const EmptyIcon = () => (_jsxs("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "1.5", children: [_jsx("rect", { x: "3", y: "3", width: "18", height: "18", rx: "2" }), _jsx("path", { d: "M3 9h18M9 3v18", strokeLinecap: "round" })] }));
49
- const RefreshIcon = () => (_jsxs("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: [_jsx("path", { d: "M23 4v6h-6M1 20v-6h6", strokeLinecap: "round", strokeLinejoin: "round" }), _jsx("path", { d: "M3.51 9a9 9 0 0114.85-3.36L23 10M1 14l4.64 4.36A9 9 0 0020.49 15", strokeLinecap: "round", strokeLinejoin: "round" })] }));
50
- const PrintIcon = () => (_jsxs("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: [_jsx("path", { d: "M6 9V2h12v7M6 18H4a2 2 0 01-2-2v-5a2 2 0 012-2h16a2 2 0 012 2v5a2 2 0 01-2 2h-2", strokeLinecap: "round", strokeLinejoin: "round" }), _jsx("rect", { x: "6", y: "14", width: "12", height: "8" })] }));
51
- const ErrorIcon = () => (_jsxs("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: [_jsx("circle", { cx: "12", cy: "12", r: "10" }), _jsx("path", { d: "M12 8v4M12 16h.01", strokeLinecap: "round", strokeLinejoin: "round" })] }));
52
- export const Table = forwardRef(function TableComponent(props, ref) {
53
- const { id, data, columns, keyField = '_id', loading = false, loadingIndicator, pagination = true, paginationConfig, totalSize, remote = true, defaultSort, sort: controlledSort, filterable = false, defaultFilters, filters: controlledFilters, defaultShowFilters = true, showFilters: controlledShowFilters, onShowFiltersChange, showFilterToggle = true, searchable = true, searchPlaceholder = 'Search...', defaultSearchValue = '', searchValue: controlledSearchValue, searchDebounce = 300, rowSelection, expandable, editMode = 'dblclick', showEditIcon = false, onCellEdit, exportable = true, exportFileName = 'table_export', exportFormat = 'csv', columnToggle = false, bordered = true, striped = false, hover = true, compact = false, cellPadding, stickyHeader = false, maxHeight, rowClassName, rowStyle, classNames = {}, styles = {}, className, style, emptyText = 'No data available', onChange, onPageChange, onSortChange, onFilterChange, onSearch, onRowClick, onRowDoubleClick, onClearFilters, toolbar, hideToolbar = false, showFooter = false, caption,
54
- // Quick configuration props
55
- isDelete = false, isEditModify, isUpdate, isExport, isSelectRow, getNonSelectableRows, nonSelectableStyle, isView = false, fileName, hideExcelSheet = false,
56
- // Quick callbacks
57
- onSelectedRow, selectedRowStyle, selectedRowClassName, onUpdateItem, onPageSizeChange, onFilter, clearAllFilter, onDelete, onEdit, onView,
58
- // Dynamic configuration
59
- dynamicStylingFields, fieldTypeConfig,
60
- // Row number
61
- showRowNumber = false, rowNumberWidth = 50, rowNumberTitle = '#', rowNumberRender,
62
- // Toolbar customization
63
- toolbarPosition = 'top', toolbarLeft, toolbarRight, toolbarCenter,
64
- // Refresh
65
- refreshable = false, onRefresh,
66
- // Print
67
- printable = false, onPrint,
68
- // Size
69
- size = 'medium',
70
- // Error state
71
- error, onRetry,
72
- // Skeleton loading
73
- skeletonLoading = false, skeletonRowCount = 5,
74
- // Hide header
75
- hideHeader = false,
76
- // Highlighted rows
77
- highlightedRowKeys = [], highlightRowStyle, highlightRowClassName,
78
- // Events
79
- onRowMouseEnter, onRowMouseLeave, onCellClick, onHeaderClick,
80
- // Column Resizing
81
- resizable = true, resizeConfig,
82
- // Column Reordering
83
- reorderable = true, reorderConfig, ...rest } = props;
84
- // Resolve aliases
85
- const resolvedExportable = isExport ?? exportable;
86
- const resolvedExportFileName = fileName ?? exportFileName;
87
- // Auto-detect remote mode: if totalSize <= data.length, use client-side (remote=false)
88
- const resolvedRemote = useMemo(() => {
89
- // If totalSize is provided and is <= data.length, all data is loaded - use client-side
90
- if (totalSize !== undefined &&
91
- totalSize > 0 &&
92
- totalSize <= data.length) {
93
- return false;
94
- }
95
- // Otherwise use the prop value (default: true)
96
- return remote;
97
- }, [remote, totalSize, data.length]);
98
- // Handle isSelectRow shorthand
99
- const resolvedRowSelection = isSelectRow
100
- ? {
101
- mode: 'checkbox',
102
- selectedRowStyle: selectedRowStyle || rowSelection?.selectedRowStyle,
103
- selectedRowClassName: selectedRowClassName || rowSelection?.selectedRowClassName,
104
- ...rowSelection,
105
- // Merge getNonSelectableRows with existing getCheckboxProps
106
- getCheckboxProps: (row) => {
107
- const rowKey = row[keyField];
108
- const isNonSelectable = getNonSelectableRows?.includes(rowKey);
109
- const existingProps = rowSelection?.getCheckboxProps?.(row);
110
- return {
111
- ...existingProps,
112
- disabled: isNonSelectable || existingProps?.disabled,
113
- };
114
- },
115
- onChange: (keys, rows) => {
116
- rowSelection?.onChange?.(keys, rows);
117
- // Note: onSelectedRow is only called when user clicks the "X Selected" button
118
- },
119
- }
120
- : rowSelection;
121
- // Default pagination config - users don't need to pass these
122
- const resolvedPaginationConfig = pagination
123
- ? {
124
- page: 0,
125
- pageSize: 10,
126
- showSizeChanger: true,
127
- showQuickJumper: true,
128
- showTotal: true,
129
- pageSizeOptions: [10, 20, 30, 50],
130
- ...paginationConfig,
131
- }
132
- : paginationConfig;
133
- // Size configuration
134
- const sizeConfig = {
135
- small: { padding: '4px 8px', fontSize: '12px' },
136
- medium: { padding: '8px 12px', fontSize: '14px' },
137
- large: { padding: '12px 16px', fontSize: '16px' },
138
- };
139
- // Refs
140
- const tableRef = useRef(null);
141
- const columnToggleRef = useRef(null);
142
- const prevSelectionCountRef = useRef(0);
143
- // State
144
- const [internalSearchValue, setInternalSearchValue] = useState(defaultSearchValue);
145
- const [internalShowFilters, setInternalShowFilters] = useState(defaultShowFilters);
146
- const [columnToggleOpen, setColumnToggleOpen] = useState(false);
147
- const [columnSearch, setColumnSearch] = useState('');
148
- const [selectionAnimation, setSelectionAnimation] = useState('none');
149
- // Column toggle reorder state
150
- const [toggleDraggingColumn, setToggleDraggingColumn] = useState(null);
151
- const [toggleDragOverColumn, setToggleDragOverColumn] = useState(null);
152
- // Internal state for reordered columns (used in popup and for rendering)
153
- const [reorderedColumns, setReorderedColumns] = useState(columns);
154
- // Sync reorderedColumns when columns prop structure changes (columns added/removed)
155
- // We only reset when the actual column dataFields change, not on every reference change
156
- useEffect(() => {
157
- const currentDataFields = reorderedColumns
158
- .map((c) => c.dataField)
159
- .sort()
160
- .join(',');
161
- const newDataFields = columns
162
- .map((c) => c.dataField)
163
- .sort()
164
- .join(',');
165
- if (currentDataFields !== newDataFields) {
166
- // Columns structure changed - merge new columns while preserving order where possible
167
- const newColumnMap = new Map(columns.map((c) => [c.dataField, c]));
168
- const existingDataFields = new Set(reorderedColumns.map((c) => c.dataField));
169
- // Keep existing order for columns that still exist, update their data
170
- const preserved = reorderedColumns
171
- .filter((c) => newColumnMap.has(c.dataField))
172
- .map((c) => newColumnMap.get(c.dataField));
173
- // Add new columns at the end
174
- const added = columns.filter((c) => !existingDataFields.has(c.dataField));
175
- setReorderedColumns([...preserved, ...added]);
176
- }
177
- else {
178
- // Same columns but maybe different data - update column data while preserving order
179
- const columnMap = new Map(columns.map((c) => [c.dataField, c]));
180
- setReorderedColumns(reorderedColumns.map((c) => columnMap.get(c.dataField) || c));
181
- }
182
- }, [columns]);
183
- // Close column toggle panel on outside click
184
- useEffect(() => {
185
- if (!columnToggleOpen)
186
- return;
187
- const handleClickOutside = (event) => {
188
- if (columnToggleRef.current &&
189
- !columnToggleRef.current.contains(event.target)) {
190
- setColumnToggleOpen(false);
191
- }
192
- };
193
- document.addEventListener('mousedown', handleClickOutside);
194
- return () => {
195
- document.removeEventListener('mousedown', handleClickOutside);
196
- };
197
- }, [columnToggleOpen]);
198
- // Filter visibility (controlled or uncontrolled)
199
- const isFilterVisibilityControlled = controlledShowFilters !== undefined;
200
- const showFilterRow = isFilterVisibilityControlled
201
- ? controlledShowFilters
202
- : internalShowFilters;
203
- const handleToggleFilters = useCallback(() => {
204
- const newValue = !showFilterRow;
205
- if (!isFilterVisibilityControlled) {
206
- setInternalShowFilters(newValue);
207
- }
208
- onShowFiltersChange?.(newValue);
209
- }, [showFilterRow, isFilterVisibilityControlled, onShowFiltersChange]);
210
- const [editingCell, setEditingCell] = useState(null);
211
- const [editValue, setEditValue] = useState(null);
212
- // Cache custom editor render to avoid repeated renders while editing the same cell
213
- const editorRendererCacheRef = useRef(new Map());
214
- useEffect(() => {
215
- // Clear cache when editing target changes
216
- editorRendererCacheRef.current.clear();
217
- }, [editingCell]);
218
- const searchValue = controlledSearchValue ?? internalSearchValue;
219
- const debouncedSearchValue = useTableDebounce(searchValue, searchDebounce);
220
- // Sort state
221
- const { sort, handleSort } = useSortState(defaultSort, controlledSort);
222
- // Filter state
223
- const { filters, setFilter, clearFilters } = useFilterState(defaultFilters, controlledFilters);
224
- // Track if onFilter should be called (only after user interaction)
225
- const shouldCallOnFilter = useRef(false);
226
- const filterTypeRef = useRef('filter');
227
- const onFilterRef = useRef(onFilter);
228
- // Track last called values to prevent duplicate calls
229
- const lastOnFilterCallRef = useRef(null);
230
- // Track focused filter field to restore focus after data changes
231
- const focusedFilterFieldRef = useRef(null);
232
- const tableContainerRef = useRef(null);
233
- // Clear focus ref when clicking outside the table
234
- useEffect(() => {
235
- const handleClickOutside = (event) => {
236
- if (tableContainerRef.current &&
237
- !tableContainerRef.current.contains(event.target)) {
238
- focusedFilterFieldRef.current = null;
239
- }
240
- };
241
- document.addEventListener('mousedown', handleClickOutside);
242
- return () => {
243
- document.removeEventListener('mousedown', handleClickOutside);
244
- };
245
- }, []);
246
- // Restore filter focus after data changes
247
- useEffect(() => {
248
- const restoreFocus = () => {
249
- if (focusedFilterFieldRef.current && tableContainerRef.current) {
250
- const filterInput = tableContainerRef.current.querySelector(`[data-filter-field="${focusedFilterFieldRef.current}"]`);
251
- if (filterInput && document.activeElement !== filterInput) {
252
- filterInput.focus();
253
- // Move cursor to end of input
254
- const len = filterInput.value?.length || 0;
255
- filterInput.setSelectionRange(len, len);
256
- }
257
- }
258
- };
259
- // Try multiple times with increasing delays to handle async renders
260
- const timers = [
261
- requestAnimationFrame(() => restoreFocus()),
262
- setTimeout(() => restoreFocus(), 50),
263
- setTimeout(() => restoreFocus(), 150),
264
- ];
265
- return () => {
266
- timers.forEach((timer) => {
267
- if (typeof timer === 'number') {
268
- cancelAnimationFrame(timer);
269
- clearTimeout(timer);
270
- }
271
- });
272
- };
273
- }, [data]);
274
- // Pagination state
275
- const { page, pageSize, totalPages, goToPage, goToNextPage, goToPrevPage, goToFirstPage, goToLastPage, changePageSize, } = usePaginationState(resolvedPaginationConfig?.page || 0, resolvedPaginationConfig?.pageSize || 10, totalSize ?? data.length);
276
- // Row selection
277
- const { selectedKeys, isSelected, toggleRow, toggleAll, isAllSelected, isIndeterminate, } = useRowSelection(data, resolvedRowSelection?.keyField || keyField, resolvedRowSelection?.mode || 'none', resolvedRowSelection?.selectedRowKeys, resolvedRowSelection?.getCheckboxProps);
278
- // Row expansion
279
- const { expandedKeys, isExpanded, toggleExpand } = useRowExpansion(expandable?.keyField || keyField, expandable?.defaultExpandedRowKeys, expandable?.expandedRowKeys, expandable?.accordion);
280
- // Column visibility
281
- const { visibleColumns, toggleColumn, isColumnHidden } = useColumnVisibility(columns, id);
282
- // Column resizing hook
283
- const { columnWidths, getResizeHandle, resetWidths: resetColumnWidths, isResizing, } = useColumnResize({
284
- columns: visibleColumns,
285
- config: resizeConfig,
286
- enabled: resizable,
287
- tableId: id,
288
- });
289
- // Get visible columns from reordered columns (filter hidden ones)
290
- const visibleRereorderedColumns = useMemo(() => {
291
- return reorderedColumns.filter((col) => !isColumnHidden(col.dataField));
292
- }, [reorderedColumns, isColumnHidden]);
293
- // Use reordered visible columns for rendering
294
- const renderColumns = reorderable
295
- ? visibleRereorderedColumns
296
- : visibleColumns;
297
- // Keep onFilter ref updated
298
- useEffect(() => {
299
- onFilterRef.current = onFilter;
300
- }, [onFilter]);
301
- // Track previous values to detect actual changes
302
- const prevSearchRef = useRef(debouncedSearchValue);
303
- const prevFiltersRef = useRef(JSON.stringify(filters));
304
- // Call onFilter when filter/search values actually change
305
- // Note: filter components already debounce internally, so we use filters directly
306
- useEffect(() => {
307
- if (!shouldCallOnFilter.current)
308
- return;
309
- const currentFiltersStr = JSON.stringify(filters);
310
- const searchChanged = prevSearchRef.current !== debouncedSearchValue;
311
- const filtersChanged = prevFiltersRef.current !== currentFiltersStr;
312
- // Only proceed if search or filters actually changed
313
- if (!searchChanged && !filtersChanged) {
314
- shouldCallOnFilter.current = false;
315
- return;
316
- }
317
- // Update previous values
318
- prevSearchRef.current = debouncedSearchValue;
319
- prevFiltersRef.current = currentFiltersStr;
320
- // Clean up filters - remove null, undefined, and empty string values
321
- const cleanFilters = {};
322
- Object.keys(filters).forEach((key) => {
323
- const value = filters[key];
324
- if (value !== null && value !== undefined && value !== '') {
325
- cleanFilters[key] = value;
326
- }
327
- });
328
- const hasFilters = Object.keys(cleanFilters).length > 0;
329
- // Build filter data based on what type of filter changed
330
- // For 'search' type, include srText if not empty; for 'filter' type, only pass filters
331
- const filterData = { ...cleanFilters };
332
- if (filterTypeRef.current === 'search' && debouncedSearchValue) {
333
- filterData.srText = debouncedSearchValue;
334
- }
335
- // Always call onFilter when filters change (including when cleared)
336
- // Case 1: Global search cleared, column filters exist → filters only
337
- // Case 2: Global search cleared, no column filters → empty filters (reload all)
338
- // Case 3: Specific column cleared → remaining filters
339
- // Note: page is 0-indexed internally, but onFilter expects 1-indexed page
340
- onFilterRef.current?.(filterTypeRef.current, filterData, page + 1, pageSize);
341
- // Reset the flag after processing to prevent duplicate calls
342
- shouldCallOnFilter.current = false;
343
- }, [debouncedSearchValue, filters, page, pageSize]);
344
- // Track selection count changes for animation
345
- useEffect(() => {
346
- const currentCount = selectedKeys.size;
347
- const prevCount = prevSelectionCountRef.current;
348
- if (currentCount > prevCount) {
349
- setSelectionAnimation('up');
350
- }
351
- else if (currentCount < prevCount) {
352
- setSelectionAnimation('down');
353
- }
354
- prevSelectionCountRef.current = currentCount;
355
- // Reset animation after it completes
356
- const timer = setTimeout(() => {
357
- setSelectionAnimation('none');
358
- }, 300);
359
- return () => clearTimeout(timer);
360
- }, [selectedKeys.size]);
361
- // Process data (filter, sort, paginate)
362
- const processedData = useMemo(() => {
363
- if (resolvedRemote) {
364
- // Server-side processing - data is already processed
365
- return data;
366
- }
367
- let result = [...data];
368
- // Filter
369
- result = filterData(result, filters, columns, debouncedSearchValue);
370
- // Sort
371
- result = sortData(result, sort, columns);
372
- // Paginate
373
- if (pagination) {
374
- result = paginateData(result, page, pageSize);
375
- }
376
- return result;
377
- }, [
378
- data,
379
- filters,
380
- sort,
381
- page,
382
- pageSize,
383
- debouncedSearchValue,
384
- resolvedRemote,
385
- pagination,
386
- columns,
387
- ]);
388
- // Calculate total for pagination
389
- const calculatedTotal = useMemo(() => {
390
- // If totalSize is explicitly provided, use it for server-side pagination
391
- if (totalSize !== undefined && totalSize > 0)
392
- return totalSize;
393
- if (resolvedRemote)
394
- return data.length;
395
- return filterData(data, filters, columns, debouncedSearchValue).length;
396
- }, [
397
- data,
398
- filters,
399
- columns,
400
- debouncedSearchValue,
401
- resolvedRemote,
402
- totalSize,
403
- ]);
404
- // Handle search
405
- const handleSearchChange = useCallback((value) => {
406
- setInternalSearchValue(value);
407
- onSearch?.(value);
408
- // Enable debounced onFilter callback with 'search' type
409
- shouldCallOnFilter.current = true;
410
- filterTypeRef.current = 'search';
411
- onChange?.({ type: 'search', search: value });
412
- }, [onSearch, onChange]);
413
- // Handle sort
414
- const handleSortClick = useCallback((column) => {
415
- if (!column.sort)
416
- return;
417
- const newSort = handleSort(column.dataField, sort.order);
418
- onSortChange?.(newSort);
419
- onChange?.({ type: 'sort', sort: newSort });
420
- }, [sort, handleSort, onSortChange, onChange]);
421
- // Handle filter
422
- const handleFilterChange = useCallback((field, value) => {
423
- setFilter(field, value);
424
- const newFilters = { ...filters, [field]: value };
425
- onFilterChange?.(newFilters);
426
- // Enable debounced onFilter callback with 'filter' type
427
- shouldCallOnFilter.current = true;
428
- filterTypeRef.current = 'filter';
429
- onChange?.({ type: 'filter', filters: newFilters });
430
- }, [filters, setFilter, onFilterChange, onChange]);
431
- // Handle clear all filters
432
- const handleClearFilters = useCallback(() => {
433
- clearFilters();
434
- setInternalSearchValue('');
435
- onClearFilters?.();
436
- clearAllFilter?.();
437
- onFilterChange?.({});
438
- onChange?.({ type: 'filter', filters: {} });
439
- // Reset the tracking ref so subsequent filters can trigger onFilter
440
- lastOnFilterCallRef.current = null;
441
- }, [clearFilters, onClearFilters, onFilterChange, onChange]);
442
- // Handle page change
443
- const handlePageChange = useCallback((newPage) => {
444
- goToPage(newPage);
445
- // Pass 1-indexed page number to callbacks (user-friendly)
446
- const displayPage = newPage + 1;
447
- // onPageSizeChange is the primary callback
448
- onPageSizeChange?.(displayPage, pageSize);
449
- onPageChange?.(displayPage, pageSize);
450
- onChange?.({
451
- type: 'pagination',
452
- pagination: { page: displayPage, pageSize },
453
- });
454
- }, [goToPage, pageSize, onPageSizeChange, onPageChange, onChange]);
455
- // Handle page size change
456
- const handlePageSizeChange = useCallback((newSize) => {
457
- changePageSize(newSize);
458
- // Pass 1-indexed page number to callbacks (page 1 after size change)
459
- onPageSizeChange?.(1, newSize);
460
- onPageChange?.(1, newSize);
461
- onChange?.({
462
- type: 'pagination',
463
- pagination: { page: 1, pageSize: newSize },
464
- });
465
- }, [changePageSize, onPageSizeChange, onPageChange, onChange]);
466
- // Handle row click
467
- const handleRowClick = useCallback((row, rowIndex, e) => {
468
- // Prevent clicks on disabled rows
469
- const checkboxProps = resolvedRowSelection?.getCheckboxProps?.(row);
470
- if (checkboxProps?.disabled) {
471
- return;
472
- }
473
- // Selection handling - only for 'single' mode (checkbox mode uses checkbox click only)
474
- if (resolvedRowSelection?.mode === 'single') {
475
- const result = toggleRow(row);
476
- if (result) {
477
- resolvedRowSelection?.onChange?.(result.selectedKeys, result.selectedRows);
478
- }
479
- }
480
- // Expand by click
481
- if (expandable?.expandRowByClick) {
482
- const result = toggleExpand(row);
483
- if (result) {
484
- expandable.onExpandChange?.(result.expandedKeys, result.expanded, row);
485
- }
486
- }
487
- onRowClick?.(row, rowIndex, e);
488
- }, [rowSelection, expandable, toggleRow, toggleExpand, onRowClick, resolvedRowSelection]);
489
- // Helper to check if cell is editable and get custom editor
490
- const getCellEditableInfo = useCallback((column, row, rowIndex, colIndex) => {
491
- // If editorRenderer is provided, column is editable by default (unless editable explicitly returns false)
492
- const hasEditorRenderer = !!column.editorRenderer;
493
- if (column.editable === undefined) {
494
- // No editable prop - editable if has editorRenderer
495
- return { isEditable: hasEditorRenderer };
496
- }
497
- if (column.editable === false) {
498
- return { isEditable: false };
499
- }
500
- if (column.editable === true) {
501
- return { isEditable: true };
502
- }
503
- // It's a function
504
- const cellValue = getNestedValue(row, column.dataField);
505
- const result = column.editable(cellValue, row, rowIndex, colIndex);
506
- if (typeof result === 'boolean') {
507
- return { isEditable: result };
508
- }
509
- // Result is a custom editor (ReactNode)
510
- return { isEditable: true, customEditor: result };
511
- }, []);
512
- // Handle cell edit
513
- const handleCellDoubleClick = useCallback((row, rowIndex, column, colIndex, e) => {
514
- // Only apply allowRows logic if rowSelection is configured
515
- if (resolvedRowSelection) {
516
- // Check if row is disabled
517
- const checkboxProps = resolvedRowSelection.getCheckboxProps?.(row);
518
- const isRowDisabled = !!checkboxProps?.disabled;
519
- // Only apply allowRows logic when row is disabled
520
- if (isRowDisabled) {
521
- // Check if allowRows is provided
522
- const hasAllowRows = resolvedRowSelection.allowRows && resolvedRowSelection.allowRows.length > 0;
523
- // If allowRows is NOT provided, block all clicks
524
- if (!hasAllowRows) {
525
- return;
526
- }
527
- // If allowRows IS provided, only allow clicks on columns in allowRows
528
- const isInAllowRows = resolvedRowSelection.allowRows.includes(column.dataField);
529
- if (!isInAllowRows) {
530
- return;
531
- }
532
- }
533
- }
534
- // Check if column is editable
535
- const { isEditable } = getCellEditableInfo(column, row, rowIndex, colIndex);
536
- // Call column's onDoubleClick event if defined
537
- column.events?.onDoubleClick?.(e, row, rowIndex, column, colIndex);
538
- // Handle cell editing
539
- if (editMode !== 'none') {
540
- // Only apply allowRows logic if rowSelection is configured and row is disabled
541
- if (resolvedRowSelection) {
542
- const checkboxProps = resolvedRowSelection.getCheckboxProps?.(row);
543
- const isRowDisabled = !!checkboxProps?.disabled;
544
- if (isRowDisabled) {
545
- const hasAllowRows = resolvedRowSelection.allowRows && resolvedRowSelection.allowRows.length > 0;
546
- if (hasAllowRows) {
547
- const isInAllowRows = resolvedRowSelection.allowRows.includes(column.dataField);
548
- if (isInAllowRows && editMode === 'dblclick') {
549
- setEditingCell({ row: rowIndex, field: column.dataField });
550
- setEditValue(getNestedValue(row, column.dataField));
551
- }
552
- }
553
- // If row is disabled and no allowRows, don't allow editing (already returned above)
554
- }
555
- else if (isEditable && editMode === 'dblclick') {
556
- // Row is not disabled, allow normal editing
557
- setEditingCell({ row: rowIndex, field: column.dataField });
558
- setEditValue(getNestedValue(row, column.dataField));
559
- }
560
- }
561
- else if (isEditable && editMode === 'dblclick') {
562
- // No rowSelection configured, allow normal editing
563
- setEditingCell({ row: rowIndex, field: column.dataField });
564
- setEditValue(getNestedValue(row, column.dataField));
565
- }
566
- }
567
- // Call row double click callback
568
- onRowDoubleClick?.(row, rowIndex, e);
569
- }, [editMode, onRowDoubleClick, getCellEditableInfo, resolvedRowSelection]);
570
- const handleCellClick = useCallback((row, rowIndex, column, colIndex, e) => {
571
- // Only apply allowRows logic if rowSelection is configured
572
- if (resolvedRowSelection) {
573
- // Check if row is disabled
574
- const checkboxProps = resolvedRowSelection.getCheckboxProps?.(row);
575
- const isRowDisabled = !!checkboxProps?.disabled;
576
- // Only apply allowRows logic when row is disabled
577
- if (isRowDisabled) {
578
- // Check if allowRows is provided
579
- const hasAllowRows = resolvedRowSelection.allowRows && resolvedRowSelection.allowRows.length > 0;
580
- // If allowRows is NOT provided, block all clicks
581
- if (!hasAllowRows) {
582
- return;
583
- }
584
- // If allowRows IS provided, only allow clicks on columns in allowRows
585
- const isInAllowRows = resolvedRowSelection.allowRows.includes(column.dataField);
586
- if (!isInAllowRows) {
587
- return;
588
- }
589
- }
590
- }
591
- // Check if column is editable
592
- const { isEditable } = getCellEditableInfo(column, row, rowIndex, colIndex);
593
- // Call column's onClick event if defined
594
- if (e) {
595
- column.events?.onClick?.(e, row, rowIndex, column, colIndex);
596
- }
597
- // Handle cell editing on click
598
- if (editMode === 'click') {
599
- // Only apply allowRows logic if rowSelection is configured and row is disabled
600
- if (resolvedRowSelection) {
601
- const checkboxProps = resolvedRowSelection.getCheckboxProps?.(row);
602
- const isRowDisabled = !!checkboxProps?.disabled;
603
- if (isRowDisabled) {
604
- const hasAllowRows = resolvedRowSelection.allowRows && resolvedRowSelection.allowRows.length > 0;
605
- if (hasAllowRows) {
606
- const isInAllowRows = resolvedRowSelection.allowRows.includes(column.dataField);
607
- if (isInAllowRows) {
608
- setEditingCell({ row: rowIndex, field: column.dataField });
609
- setEditValue(getNestedValue(row, column.dataField));
610
- }
611
- }
612
- // If row is disabled and no allowRows, don't allow editing (already returned above)
613
- }
614
- else if (isEditable) {
615
- // Row is not disabled, allow normal editing
616
- setEditingCell({ row: rowIndex, field: column.dataField });
617
- setEditValue(getNestedValue(row, column.dataField));
618
- }
619
- }
620
- else if (isEditable) {
621
- // No rowSelection configured, allow normal editing
622
- setEditingCell({ row: rowIndex, field: column.dataField });
623
- setEditValue(getNestedValue(row, column.dataField));
624
- }
625
- }
626
- }, [editMode, getCellEditableInfo, resolvedRowSelection]);
627
- const handleCellEditComplete = useCallback((row, rowIndex, column) => {
628
- if (editingCell) {
629
- // Validate
630
- if (column.validator) {
631
- const result = column.validator(editValue, row);
632
- if (result !== true) {
633
- alert(typeof result === 'string' ? result : 'Invalid value');
634
- setEditingCell(null);
635
- return;
636
- }
637
- }
638
- const rowId = row[keyField];
639
- onCellEdit?.(editValue, column.dataField, row, rowIndex);
640
- onUpdateItem?.(editValue, column.dataField, rowId);
641
- }
642
- setEditingCell(null);
643
- }, [editingCell, editValue, onCellEdit, onUpdateItem, keyField]);
644
- // Helper to get nested value from object
645
- const getNestedValueLocal = (obj, path) => {
646
- return path.split('.').reduce((acc, key) => acc?.[key], obj);
647
- };
648
- // Process field value based on fieldTypeConfig (matching reference implementation)
649
- const processFieldValue = useCallback((value, dataField, row) => {
650
- const configOrType = fieldTypeConfig?.[dataField];
651
- // Handle both object config and string shorthand (e.g., 'boolean', 'date')
652
- const config = typeof configOrType === 'string'
653
- ? { type: configOrType }
654
- : configOrType;
655
- const fieldType = config?.type || 'string';
656
- switch (fieldType) {
657
- case 'array':
658
- if (config?.fields && config.fields.length > 0) {
659
- // Array of objects with specific fields to extract
660
- if (!Array.isArray(value))
661
- return value || '';
662
- return value
663
- .slice(0, config.maxItems || value.length)
664
- .map((item) => {
665
- if (typeof item === 'object' && config.fields) {
666
- // Extract only specified fields from the object
667
- return config.fields
668
- .map((field) => item[field])
669
- .filter(Boolean)
670
- .join(', ');
671
- }
672
- else if (typeof item === 'string') {
673
- return item;
674
- }
675
- return '';
676
- })
677
- .filter(Boolean)
678
- .join(config.separator || '; ');
679
- }
680
- else {
681
- // Default array handling
682
- if (!Array.isArray(value))
683
- return value || '';
684
- return value
685
- .map((item) => typeof item === 'object' ? JSON.stringify(item) : item)
686
- .join('; ');
687
- }
688
- case 'object':
689
- if (!value || typeof value !== 'object')
690
- return '';
691
- const fields = config?.fields || config?.keys || [];
692
- const labelMap = config?.labelMap || {};
693
- if (fields.length > 0) {
694
- // Extract specific fields with optional label mapping
695
- return fields
696
- .map((field) => {
697
- const nestedValue = getNestedValueLocal(value, field);
698
- if (nestedValue !== undefined && nestedValue !== null) {
699
- const label = labelMap[field] || field;
700
- return `${label}: ${nestedValue}`;
701
- }
702
- return null;
703
- })
704
- .filter(Boolean)
705
- .join(', ');
706
- }
707
- else {
708
- // Default object handling
709
- return Object.entries(value)
710
- .map(([key, val]) => typeof val === 'boolean'
711
- ? `${key}: ${val ? 'Yes' : 'No'}`
712
- : `${key}: ${val}`)
713
- .join(', ');
714
- }
715
- case 'date':
716
- if (!value)
717
- return '';
718
- try {
719
- const date = new Date(value);
720
- const format = config?.dateFormat || 'YYYY-MM-DD HH:mm:ss';
721
- // Simple date formatting
722
- return date.toISOString().slice(0, 19).replace('T', ' ');
723
- }
724
- catch {
725
- return String(value);
726
- }
727
- case 'number':
728
- return value !== undefined && value !== null
729
- ? String(Number(value))
730
- : '';
731
- case 'boolean':
732
- return typeof value === 'boolean' ? (value ? 'Yes' : 'No') : '';
733
- case 'string':
734
- case 'text':
735
- default:
736
- if (typeof value === 'boolean')
737
- return value ? 'Yes' : 'No';
738
- return value !== undefined && value !== null ? String(value) : '';
739
- }
740
- }, [fieldTypeConfig]);
741
- // Handle export
742
- const handleExport = useCallback(async () => {
743
- const exportData = resolvedRemote
744
- ? data
745
- : filterData(data, filters, columns, debouncedSearchValue);
746
- // Filter columns based on hideExcelSheet array and csvExport !== false
747
- let exportColumns = visibleColumns.filter((col) => col.csvExport !== false);
748
- if (Array.isArray(hideExcelSheet)) {
749
- exportColumns = exportColumns.filter((col) => !hideExcelSheet.includes(col.dataField));
750
- }
751
- // Also filter based on fieldTypeConfig hideFromExport or csvExport
752
- if (fieldTypeConfig) {
753
- exportColumns = exportColumns.filter((col) => {
754
- const configOrType = fieldTypeConfig[col.dataField];
755
- const config = typeof configOrType === 'string'
756
- ? { type: configOrType }
757
- : configOrType;
758
- if (config?.hideFromExport)
759
- return false;
760
- if (config?.csvExport === false)
761
- return false;
762
- return true;
763
- });
764
- }
765
- // Create enhanced columns with export formatters
766
- const enhancedColumns = exportColumns.map((col) => {
767
- const configOrType = fieldTypeConfig?.[col.dataField];
768
- const config = typeof configOrType === 'string'
769
- ? { type: configOrType }
770
- : configOrType;
771
- // If column already has csvFormatter, use it
772
- if (col.csvFormatter) {
773
- return col;
774
- }
775
- // If config has exportFormatter, use it
776
- if (config?.exportFormatter) {
777
- return { ...col, csvFormatter: config.exportFormatter };
778
- }
779
- // If config has type, create formatter based on type
780
- if (config?.type) {
781
- return {
782
- ...col,
783
- csvFormatter: (cell, row) => processFieldValue(cell, col.dataField, row),
784
- };
785
- }
786
- return col;
787
- });
788
- // Export based on format
789
- if (exportFormat === 'excel') {
790
- await exportToExcel(exportData, enhancedColumns, resolvedExportFileName);
791
- }
792
- else {
793
- exportToCSV(exportData, enhancedColumns, resolvedExportFileName);
794
- }
795
- }, [
796
- data,
797
- filters,
798
- columns,
799
- debouncedSearchValue,
800
- visibleColumns,
801
- hideExcelSheet,
802
- fieldTypeConfig,
803
- processFieldValue,
804
- resolvedExportFileName,
805
- resolvedRemote,
806
- exportFormat,
807
- ]);
808
- // Handle checkbox change
809
- const handleCheckboxChange = useCallback((row, e) => {
810
- e.stopPropagation();
811
- const result = toggleRow(row);
812
- if (result) {
813
- resolvedRowSelection?.onChange?.(result.selectedKeys, result.selectedRows);
814
- }
815
- }, [toggleRow, rowSelection]);
816
- // Handle select all
817
- const handleSelectAllChange = useCallback(() => {
818
- const result = toggleAll(!isAllSelected);
819
- if (result) {
820
- resolvedRowSelection?.onChange?.(result.selectedKeys, result.selectedRows);
821
- }
822
- }, [toggleAll, isAllSelected, resolvedRowSelection]);
823
- // Handle expand toggle
824
- const handleExpandClick = useCallback((row, e) => {
825
- // Prevent expand on disabled rows
826
- const checkboxProps = resolvedRowSelection?.getCheckboxProps?.(row);
827
- if (checkboxProps?.disabled) {
828
- return;
829
- }
830
- e.stopPropagation();
831
- const result = toggleExpand(row);
832
- expandable?.onExpandChange?.(result.expandedKeys, result.expanded, row);
833
- }, [toggleExpand, expandable, resolvedRowSelection]);
834
- // Filtered column list for toggle panel - use reorderedColumns to preserve reorder state
835
- const filteredToggleColumns = useMemo(() => {
836
- return reorderedColumns.filter((c) => c.dataField !== keyField &&
837
- c.text.toLowerCase().includes(columnSearch.toLowerCase()));
838
- }, [reorderedColumns, keyField, columnSearch]);
839
- // Get row key
840
- const getRowKey = useCallback((row) => row[keyField], [keyField]);
841
- // Render cell content
842
- const renderCellContent = useCallback((row, column, rowIndex, colIndex) => {
843
- const value = getNestedValue(row, column.dataField);
844
- const isEditing = editingCell?.row === rowIndex &&
845
- editingCell?.field === column.dataField;
846
- if (isEditing) {
847
- // Check for custom editorRenderer
848
- if (column.editorRenderer) {
849
- const rowId = row[keyField];
850
- const cacheKey = `${rowId ?? rowIndex}-${column.dataField}`;
851
- if (!editorRendererCacheRef.current.has(cacheKey)) {
852
- const editorProps = {
853
- value: editValue,
854
- onUpdate: (newValue) => {
855
- setEditValue(newValue);
856
- // Call onUpdateItem directly for custom editors
857
- onUpdateItem?.(newValue, column.dataField, rowId);
858
- setEditingCell(null);
859
- },
860
- onCancel: () => setEditingCell(null),
861
- onBlur: () => {
862
- // Only complete if value changed
863
- if (editValue !== value) {
864
- onUpdateItem?.(editValue, column.dataField, rowId);
865
- }
866
- setEditingCell(null);
867
- },
868
- row,
869
- column,
870
- rowIndex,
871
- columnIndex: colIndex,
872
- // Additional helpers for direct update
873
- rowId,
874
- dataField: column.dataField,
875
- onUpdateItem: (newValue) => {
876
- onUpdateItem?.(newValue, column.dataField, rowId);
877
- setEditingCell(null);
878
- },
879
- };
880
- editorRendererCacheRef.current.set(cacheKey, column.editorRenderer(editorProps, editValue, row, column, rowIndex, colIndex));
881
- }
882
- return editorRendererCacheRef.current.get(cacheKey);
883
- }
884
- // Default editor
885
- return (_jsx(CellEditor, { type: column.editorType === 'number' ? 'number' : 'text', value: editValue ?? '', onChange: (e) => setEditValue(e.target.value), onBlur: () => handleCellEditComplete(row, rowIndex, column), onKeyDown: (e) => {
886
- if (e.key === 'Enter') {
887
- handleCellEditComplete(row, rowIndex, column);
888
- }
889
- if (e.key === 'Escape') {
890
- setEditingCell(null);
891
- }
892
- }, className: column.editorClasses, style: column.editorStyle, autoFocus: true }));
893
- }
894
- if (column.formatter) {
895
- return column.formatter(value, row, rowIndex, colIndex);
896
- }
897
- if (value === null || value === undefined)
898
- return '';
899
- if (typeof value === 'boolean')
900
- return value ? 'Yes' : 'No';
901
- if (typeof value === 'object')
902
- return JSON.stringify(value);
903
- return String(value);
904
- }, [editingCell, editValue, handleCellEditComplete]);
905
- // Render toolbar
906
- const renderToolbar = () => {
907
- if (hideToolbar)
908
- return null;
909
- if (typeof toolbar === 'function') {
910
- return toolbar({
911
- searchValue,
912
- onSearch: handleSearchChange,
913
- onClearFilters: handleClearFilters,
914
- onExport: handleExport,
915
- });
916
- }
917
- if (toolbar)
918
- return toolbar;
919
- const hasFilters = Object.keys(filters).length > 0 || searchValue;
920
- return (_jsxs(Toolbar, { className: classNames.toolbar, style: styles.toolbar, children: [_jsxs(ToolbarGroup, { children: [toolbarLeft, searchable && (_jsxs(SearchInput, { children: [_jsx(SearchIcon, {}), _jsx("input", { type: "text", value: searchValue, onChange: (e) => handleSearchChange(e.target.value), onFocus: () => {
921
- // Clear column filter focus when global search is focused
922
- focusedFilterFieldRef.current = null;
923
- }, placeholder: searchPlaceholder })] })), searchable && (_jsx(ToolbarButton, { onClick: () => handleSearchChange(''), disabled: !searchValue, style: { opacity: searchValue ? 1 : 0.6 }, children: "Clear" })), _jsx(ToolbarButton, { onClick: handleClearFilters, disabled: !hasFilters, style: { opacity: hasFilters ? 1 : 0.6 }, children: "Clear all filters" }), resolvedExportable && hideExcelSheet !== true && (_jsxs(ToolbarButton, { onClick: handleExport, children: [_jsx(DownloadIcon, {}), exportFormat === 'excel' ? 'Export Excel' : 'Export CSV'] })), showFilterToggle && (_jsxs("div", { ref: columnToggleRef, style: { position: 'relative' }, children: [_jsx(Tooltip, { content: "Show/Hide Columns", position: "bottom", children: _jsx(ToolbarButton, { "$active": columnToggleOpen, onClick: () => setColumnToggleOpen(!columnToggleOpen), "aria-label": "Toggle column visibility", style: { padding: '0 8px' }, children: _jsx(FilterIcon, {}) }) }), columnToggleOpen && (_jsxs(ColumnTogglePanel, { children: [_jsxs(ColumnToggleHeader, { children: [_jsx("span", { children: "Show/Hide Columns" }), _jsx("button", { onClick: () => setColumnToggleOpen(false), children: _jsx(CloseIcon, {}) })] }), _jsx(ColumnToggleSearch, { children: _jsx("input", { type: "text", value: columnSearch, onChange: (e) => setColumnSearch(e.target.value), placeholder: "Search columns..." }) }), _jsxs(ColumnToggleList, { children: [_jsxs(ColumnToggleItem, { style: {
924
- borderBottom: '1px solid #e5e7eb',
925
- paddingBottom: 8,
926
- marginBottom: 4,
927
- }, children: [_jsx("input", { type: "checkbox", checked: filteredToggleColumns.length > 0 &&
928
- filteredToggleColumns.every((col) => !isColumnHidden(col.dataField)), onChange: (e) => {
929
- filteredToggleColumns.forEach((col) => {
930
- if (e.target.checked) {
931
- if (isColumnHidden(col.dataField)) {
932
- toggleColumn(col.dataField);
933
- }
934
- }
935
- else {
936
- if (!isColumnHidden(col.dataField)) {
937
- toggleColumn(col.dataField);
938
- }
939
- }
940
- });
941
- } }), _jsx("span", { style: { fontWeight: 600 }, children: "Select All" })] }), filteredToggleColumns.map((column, index) => (_jsxs(ColumnToggleItem, { "$reorderable": reorderable, "$isDragging": toggleDraggingColumn === column.dataField, "$isDragOver": toggleDragOverColumn === column.dataField, draggable: reorderable, onDragStart: (e) => {
942
- if (!reorderable)
943
- return;
944
- setToggleDraggingColumn(column.dataField);
945
- e.dataTransfer.effectAllowed = 'move';
946
- e.dataTransfer.setData('text/plain', column.dataField);
947
- }, onDragEnd: () => {
948
- setToggleDraggingColumn(null);
949
- setToggleDragOverColumn(null);
950
- }, onDragOver: (e) => {
951
- if (!reorderable)
952
- return;
953
- e.preventDefault();
954
- if (toggleDraggingColumn &&
955
- toggleDraggingColumn !== column.dataField) {
956
- setToggleDragOverColumn(column.dataField);
957
- }
958
- }, onDragLeave: () => {
959
- setToggleDragOverColumn(null);
960
- }, onDrop: (e) => {
961
- if (!reorderable)
962
- return;
963
- e.preventDefault();
964
- const draggedField = e.dataTransfer.getData('text/plain');
965
- if (draggedField &&
966
- draggedField !== column.dataField) {
967
- // Find indices
968
- const fromIdx = reorderedColumns.findIndex((c) => c.dataField === draggedField);
969
- const toIdx = reorderedColumns.findIndex((c) => c.dataField === column.dataField);
970
- if (fromIdx !== -1 && toIdx !== -1) {
971
- // Reorder columns
972
- const newColumns = [...reorderedColumns];
973
- const [removed] = newColumns.splice(fromIdx, 1);
974
- newColumns.splice(toIdx, 0, removed);
975
- // Update local state
976
- setReorderedColumns(newColumns);
977
- // Call reorder callback
978
- reorderConfig?.onReorder?.(newColumns, fromIdx, toIdx);
979
- }
980
- }
981
- setToggleDraggingColumn(null);
982
- setToggleDragOverColumn(null);
983
- }, children: [_jsx("input", { type: "checkbox", checked: !isColumnHidden(column.dataField), onChange: () => toggleColumn(column.dataField), onClick: (e) => e.stopPropagation() }), _jsx("span", { children: column.text }), reorderable && (_jsx(ColumnToggleDragHandle, { "$isDragging": toggleDraggingColumn === column.dataField, title: "Drag to reorder" }))] }, column.dataField)))] })] }))] }))] }), toolbarCenter, _jsxs(ToolbarGroup, { children: [refreshable && (_jsxs(ToolbarButton, { onClick: onRefresh, children: [_jsx(RefreshIcon, {}), "Refresh"] })), printable && (_jsxs(ToolbarButton, { onClick: onPrint, children: [_jsx(PrintIcon, {}), "Print"] })), columnToggle && (_jsxs("div", { ref: !showFilterToggle ? columnToggleRef : undefined, style: { position: 'relative' }, children: [_jsxs(ToolbarButton, { "$active": columnToggleOpen, onClick: () => setColumnToggleOpen(!columnToggleOpen), children: [_jsx(ColumnsIcon, {}), "Columns"] }), columnToggleOpen && (_jsxs(ColumnTogglePanel, { children: [_jsxs(ColumnToggleHeader, { children: [_jsx("span", { children: "Toggle Columns" }), _jsx("button", { onClick: () => setColumnToggleOpen(false), children: _jsx(CloseIcon, {}) })] }), _jsx(ColumnToggleSearch, { children: _jsx("input", { type: "text", value: columnSearch, onChange: (e) => setColumnSearch(e.target.value), placeholder: "Search columns..." }) }), _jsx(ColumnToggleList, { children: filteredToggleColumns.map((column, index) => (_jsxs(ColumnToggleItem, { "$reorderable": reorderable, "$isDragging": toggleDraggingColumn === column.dataField, "$isDragOver": toggleDragOverColumn === column.dataField, draggable: reorderable, onDragStart: (e) => {
984
- if (!reorderable)
985
- return;
986
- setToggleDraggingColumn(column.dataField);
987
- e.dataTransfer.effectAllowed = 'move';
988
- e.dataTransfer.setData('text/plain', column.dataField);
989
- }, onDragEnd: () => {
990
- setToggleDraggingColumn(null);
991
- setToggleDragOverColumn(null);
992
- }, onDragOver: (e) => {
993
- if (!reorderable)
994
- return;
995
- e.preventDefault();
996
- if (toggleDraggingColumn &&
997
- toggleDraggingColumn !== column.dataField) {
998
- setToggleDragOverColumn(column.dataField);
999
- }
1000
- }, onDragLeave: () => {
1001
- setToggleDragOverColumn(null);
1002
- }, onDrop: (e) => {
1003
- if (!reorderable)
1004
- return;
1005
- e.preventDefault();
1006
- const draggedField = e.dataTransfer.getData('text/plain');
1007
- if (draggedField &&
1008
- draggedField !== column.dataField) {
1009
- const fromIdx = reorderedColumns.findIndex((c) => c.dataField === draggedField);
1010
- const toIdx = reorderedColumns.findIndex((c) => c.dataField === column.dataField);
1011
- if (fromIdx !== -1 && toIdx !== -1) {
1012
- const newColumns = [...reorderedColumns];
1013
- const [removed] = newColumns.splice(fromIdx, 1);
1014
- newColumns.splice(toIdx, 0, removed);
1015
- // Update local state
1016
- setReorderedColumns(newColumns);
1017
- reorderConfig?.onReorder?.(newColumns, fromIdx, toIdx);
1018
- }
1019
- }
1020
- setToggleDraggingColumn(null);
1021
- setToggleDragOverColumn(null);
1022
- }, children: [_jsx("input", { type: "checkbox", checked: !isColumnHidden(column.dataField), onChange: () => toggleColumn(column.dataField), onClick: (e) => e.stopPropagation() }), _jsx("span", { children: column.text }), reorderable && (_jsx(ColumnToggleDragHandle, { "$isDragging": toggleDraggingColumn === column.dataField, title: "Drag to reorder" }))] }, column.dataField))) })] }))] })), toolbarRight] })] }));
1023
- };
1024
- // Render pagination
1025
- const renderPagination = () => {
1026
- if (!pagination)
1027
- return null;
1028
- const actualTotalPages = Math.ceil(calculatedTotal / pageSize) || 1;
1029
- const startItem = calculatedTotal > 0 ? page * pageSize + 1 : 0;
1030
- // Use actual data length for endItem to show correct count
1031
- const actualDataCount = resolvedRemote
1032
- ? data.length
1033
- : processedData.length;
1034
- const endItem = Math.min(page * pageSize + actualDataCount, calculatedTotal);
1035
- const showTotal = resolvedPaginationConfig?.showTotal === true
1036
- ? `Showing ${startItem} to ${endItem} of ${calculatedTotal} Results`
1037
- : typeof resolvedPaginationConfig?.showTotal === 'function'
1038
- ? resolvedPaginationConfig.showTotal(calculatedTotal, [
1039
- startItem,
1040
- endItem,
1041
- ])
1042
- : null;
1043
- // Generate page numbers
1044
- const getPageNumbers = () => {
1045
- const pages = [];
1046
- const maxVisible = 5;
1047
- if (actualTotalPages <= maxVisible) {
1048
- for (let i = 0; i < actualTotalPages; i++)
1049
- pages.push(i);
1050
- }
1051
- else {
1052
- if (page < 3) {
1053
- for (let i = 0; i < 4; i++)
1054
- pages.push(i);
1055
- pages.push('...');
1056
- pages.push(actualTotalPages - 1);
1057
- }
1058
- else if (page > actualTotalPages - 4) {
1059
- pages.push(0);
1060
- pages.push('...');
1061
- for (let i = actualTotalPages - 4; i < actualTotalPages; i++)
1062
- pages.push(i);
1063
- }
1064
- else {
1065
- pages.push(0);
1066
- pages.push('...');
1067
- for (let i = page - 1; i <= page + 1; i++)
1068
- pages.push(i);
1069
- pages.push('...');
1070
- pages.push(actualTotalPages - 1);
1071
- }
1072
- }
1073
- return pages;
1074
- };
1075
- return (_jsxs(PaginationWrapper, { className: classNames.pagination, style: styles.pagination, children: [_jsxs(ToolbarGroup, { children: [(resolvedRowSelection?.mode === 'checkbox' || isSelectRow) &&
1076
- selectedKeys.size > 0 && (_jsxs(SelectionIndicator, { onClick: () => {
1077
- const selectedRows = data.filter((row) => selectedKeys.has(getRowKey(row)));
1078
- resolvedRowSelection?.onChange?.(Array.from(selectedKeys), selectedRows);
1079
- // Call onSelectedRow only when user clicks this button
1080
- onSelectedRow?.(selectedRows);
1081
- }, children: [_jsx(SelectionCount, { "$animate": selectionAnimation, children: selectedKeys.size }, selectedKeys.size), _jsx("span", { children: "Selected" })] })), resolvedPaginationConfig?.showSizeChanger !== false && (_jsx(PageSizeSelect, { value: pageSize, onChange: (e) => handlePageSizeChange(Number(e.target.value)), children: (resolvedPaginationConfig?.pageSizeOptions || [10, 20, 30, 50]).map((size) => (_jsx("option", { value: size, children: size }, size))) }))] }), _jsxs(PaginationControls, { children: [_jsx(PageButton, { onClick: () => handlePageChange(0), disabled: page === 0, children: _jsx(ChevronsLeftIcon, {}) }), _jsx(PageButton, { onClick: () => handlePageChange(page - 1), disabled: page === 0, children: _jsx(ChevronLeftIcon, {}) }), getPageNumbers().map((p, i) => typeof p === 'string' ? (_jsx("span", { style: { padding: '0 4px', color: 'white' }, children: p }, `ellipsis-${i}`)) : (_jsx(PageButton, { "$active": p === page, onClick: () => handlePageChange(p), children: p + 1 }, p))), _jsx(PageButton, { onClick: () => handlePageChange(page + 1), disabled: page >= actualTotalPages - 1, children: _jsx(ChevronRightIcon, {}) }), _jsx(PageButton, { onClick: () => handlePageChange(actualTotalPages - 1), disabled: page >= actualTotalPages - 1, children: _jsx(ChevronsRightIcon, {}) })] }), showTotal && _jsx(PaginationInfo, { children: showTotal }), resolvedPaginationConfig?.showQuickJumper &&
1082
- (() => {
1083
- const handleQuickJump = (input) => {
1084
- const pageNum = parseInt(input.value, 10);
1085
- if (!isNaN(pageNum) &&
1086
- pageNum >= 1 &&
1087
- pageNum <= actualTotalPages) {
1088
- handlePageChange(pageNum - 1); // Convert to 0-indexed
1089
- input.value = '';
1090
- return true;
1091
- }
1092
- return false;
1093
- };
1094
- return (_jsxs(QuickJumper, { children: ["Go to", _jsx("input", { type: "number", min: 1, max: actualTotalPages, placeholder: `1-${actualTotalPages}`, onKeyDown: (e) => {
1095
- if (e.key === 'Enter') {
1096
- e.preventDefault();
1097
- const target = e.target;
1098
- if (handleQuickJump(target)) {
1099
- target.blur();
1100
- }
1101
- }
1102
- }, onBlur: (e) => {
1103
- const target = e.target;
1104
- handleQuickJump(target);
1105
- } }), _jsx(PageButton, { onClick: () => {
1106
- const input = document.querySelector(`#${id} input[type="number"]`);
1107
- if (input) {
1108
- handleQuickJump(input);
1109
- input.blur();
1110
- }
1111
- }, style: { marginLeft: '4px', padding: '2px 8px' }, children: "Go" })] }));
1112
- })()] }));
1113
- };
1114
- // Check if any columns have filters
1115
- const hasFilterableColumns = filterable ||
1116
- columns.some((c) => typeof c.filter === 'function' ||
1117
- c.filterComponent ||
1118
- c.filter === true);
1119
- // Should show filter row - check if there are filterable columns AND filters are visible
1120
- const shouldShowFilterRow = hasFilterableColumns && showFilterRow;
1121
- return (_jsxs(TableRoot, { ref: (node) => {
1122
- // Handle forwarded ref
1123
- if (typeof ref === 'function') {
1124
- ref(node);
1125
- }
1126
- else if (ref) {
1127
- ref.current = node;
1128
- }
1129
- // Also store in our container ref
1130
- tableContainerRef.current = node;
1131
- }, "$bordered": bordered, "$compact": compact, className: className || classNames.root, style: { ...styles.root, ...style, position: 'relative' }, "aria-label": rest['aria-label'], "aria-labelledby": rest['aria-labelledby'], children: [loading && (_jsx(LoadingOverlay, { className: classNames.loading, style: styles.loading, children: loadingIndicator || _jsx(LoadingSpinner, {}) })), renderToolbar(), _jsx(TableWrapper, { "$maxHeight": maxHeight, "$stickyHeader": stickyHeader, className: classNames.wrapper, style: styles.wrapper, children: _jsxs(StyledTable, { ref: tableRef, "$striped": striped, "$hover": hover, "$compact": compact, role: "grid", children: [caption && _jsx("caption", { className: "sr-only", children: caption }), _jsx(TableHeader, { "$sticky": stickyHeader, className: classNames.header, style: styles.header, children: _jsxs(HeaderRow, { className: classNames.headerRow, style: styles.headerRow, children: [resolvedRowSelection?.mode === 'checkbox' && (_jsx(HeaderCell, { "$align": "center", "$sortable": false, "$compact": compact, "$width": resolvedRowSelection.columnWidth || 40, children: !resolvedRowSelection.hideSelectAll && (_jsx(Checkbox, { checked: isAllSelected, ref: (el) => {
1132
- if (el)
1133
- el.indeterminate = isIndeterminate;
1134
- }, onChange: handleSelectAllChange })) })), expandable && (_jsx(HeaderCell, { "$align": "center", "$sortable": false, "$compact": compact, "$width": expandable.columnWidth || 40 })), showRowNumber && (_jsx(HeaderCell, { "$align": "center", "$sortable": false, "$compact": compact, "$width": rowNumberWidth, children: rowNumberTitle })), renderColumns.map((column, colIndex) => {
1135
- // Determine if column has a filter
1136
- const hasColumnFilter = typeof column.filter === 'function' ||
1137
- column.filter === true ||
1138
- column.filterComponent ||
1139
- column.filterRenderer;
1140
- // Get the filter component
1141
- const FilterComponent = hasColumnFilter
1142
- ? (typeof column.filter === 'function'
1143
- ? column.filter
1144
- : null) ||
1145
- column.filterComponent ||
1146
- getFilterComponent(column.filterType || 'text')
1147
- : null;
1148
- const onFilter = (value) => handleFilterChange(column.dataField, value);
1149
- // Get resized column style
1150
- const resizeStyle = resizable
1151
- ? getColumnStyle(column, columnWidths, resizable, isResizing)
1152
- : {};
1153
- // Render header cell with resize handle
1154
- // Note: Using callback ref pattern for resize functionality
1155
- const headerCellRef = (node) => {
1156
- if (node && resizable) {
1157
- // Store ref for resize handle
1158
- const refObj = {
1159
- current: node,
1160
- };
1161
- // Attach resize handle via DOM if needed
1162
- }
1163
- };
1164
- return (_jsxs(HeaderCell, { ref: headerCellRef, "$align": column.headerAlign || column.align || 'left', "$sortable": !!column.sort, "$compact": compact, "$width": resizable && columnWidths[column.dataField]
1165
- ? columnWidths[column.dataField]
1166
- : column.width, "$minWidth": column.minWidth, "$pinned": column.pinned, "$customClass": !!column.headerClasses, className: [column.headerClasses, classNames.headerCell]
1167
- .filter(Boolean)
1168
- .join(' '), style: {
1169
- ...(typeof column.headerStyle === 'function'
1170
- ? column.headerStyle(column)
1171
- : column.headerStyle || styles.headerCell),
1172
- ...resizeStyle,
1173
- position: 'relative',
1174
- }, role: "columnheader", "aria-sort": sort.field === column.dataField
1175
- ? sort.order === 'asc'
1176
- ? 'ascending'
1177
- : sort.order === 'desc'
1178
- ? 'descending'
1179
- : 'none'
1180
- : undefined, "data-column": column.dataField, children: [(() => {
1181
- // Check visibility props (default to true if not specified)
1182
- const headerStyleObj = typeof column.headerStyle === 'function'
1183
- ? column.headerStyle(column)
1184
- : column.headerStyle;
1185
- // isHeaderTitle: show title (default true, false to hide)
1186
- const showTitle = column.isHeaderTitle !== false &&
1187
- column.hideHeaderText !== true &&
1188
- !(headerStyleObj && headerStyleObj.fontSize === 0);
1189
- // isHeaderFilterComp: show filter (default true)
1190
- const showFilter = column.isHeaderFilterComp !== false &&
1191
- shouldShowFilterRow &&
1192
- hasColumnFilter &&
1193
- FilterComponent;
1194
- // isHeaderSort: show sort icon (default true)
1195
- const showSort = column.isHeaderSort !== false && column.sort;
1196
- // If no filter, show title and sort on single line
1197
- if (!showFilter) {
1198
- return (_jsxs("div", { style: {
1199
- display: 'flex',
1200
- alignItems: 'center',
1201
- justifyContent: column.headerAlign || column.align || 'left',
1202
- gap: 6,
1203
- width: '100%',
1204
- cursor: showSort ? 'pointer' : 'default',
1205
- paddingRight: resizable ? 12 : 0,
1206
- position: 'relative',
1207
- zIndex: 2, // Above resize handle
1208
- }, onClick: () => showSort && handleSortClick(column), children: [showTitle && (_jsx("span", { style: {
1209
- color: 'white',
1210
- fontWeight: 600,
1211
- fontSize: 12,
1212
- whiteSpace: 'nowrap',
1213
- flex: 1,
1214
- }, children: column.headerFormatter
1215
- ? column.headerFormatter(column, colIndex)
1216
- : column.headerText || column.text })), showSort && (_jsx("div", { style: {
1217
- display: 'flex',
1218
- alignItems: 'center',
1219
- justifyContent: 'center',
1220
- flexShrink: 0,
1221
- minWidth: 40,
1222
- minHeight: 24,
1223
- position: 'relative',
1224
- overflow: 'visible',
1225
- }, title: `Sort by ${column.text}`, children: column.sortCaret ? (column.sortCaret(sort.field === column.dataField
1226
- ? sort.order
1227
- : null, column)) : (_jsx(DefaultSortCaret, { order: sort.field === column.dataField
1228
- ? sort.order
1229
- : null, column: column })) }))] }));
1230
- }
1231
- // With filter: layout with filter + sort
1232
- return (_jsxs("div", { style: {
1233
- display: 'flex',
1234
- flexDirection: 'column',
1235
- gap: showTitle ? 4 : 0,
1236
- width: '100%',
1237
- paddingRight: resizable ? 12 : 0,
1238
- position: 'relative',
1239
- zIndex: 2, // Above resize handle
1240
- }, children: [showTitle && (_jsx("div", { style: {
1241
- display: 'flex',
1242
- alignItems: 'center',
1243
- justifyContent: 'space-between',
1244
- gap: 4,
1245
- }, children: _jsx("span", { style: {
1246
- color: 'white',
1247
- fontWeight: 600,
1248
- fontSize: 12,
1249
- whiteSpace: 'nowrap',
1250
- cursor: showSort ? 'pointer' : 'default',
1251
- flex: 1,
1252
- }, onClick: () => showSort && handleSortClick(column), children: column.headerFormatter
1253
- ? column.headerFormatter(column, colIndex)
1254
- : column.headerText || column.text }) })), _jsxs("div", { style: {
1255
- display: 'flex',
1256
- alignItems: 'center',
1257
- justifyContent: 'flex-start',
1258
- gap: 4,
1259
- width: '100%',
1260
- minHeight: 24,
1261
- }, children: [_jsx("div", { style: {
1262
- flex: showSort ? '0 1 auto' : 1,
1263
- width: showSort
1264
- ? 'calc(100% - 48px)'
1265
- : '100%',
1266
- minWidth: 0,
1267
- maxWidth: showSort
1268
- ? 'calc(100% - 48px)'
1269
- : '100%',
1270
- display: 'flex',
1271
- alignItems: 'center',
1272
- overflow: 'hidden',
1273
- }, onClick: (e) => e.stopPropagation(), children: column.filterRenderer ? (column.filterRenderer(onFilter, column)) : (_jsx("div", { onFocusCapture: () => {
1274
- focusedFilterFieldRef.current =
1275
- column.dataField;
1276
- }, "data-filter-wrapper": column.dataField, style: { width: '100%' }, children: _jsx(FilterComponent, { column: column, value: filters[column.dataField], onChange: onFilter, onClear: () => handleFilterChange(column.dataField, null) }, `filter-${column.dataField}`) })) }), showSort && (_jsx("div", { style: {
1277
- minWidth: 40,
1278
- minHeight: 24,
1279
- display: 'flex',
1280
- alignItems: 'center',
1281
- justifyContent: 'center',
1282
- flexShrink: 0,
1283
- flexGrow: 0,
1284
- cursor: 'pointer',
1285
- marginLeft: 'auto',
1286
- position: 'relative',
1287
- overflow: 'visible',
1288
- }, onClick: (e) => {
1289
- e.stopPropagation();
1290
- handleSortClick(column);
1291
- }, title: `Sort by ${column.text}`, children: column.sortCaret ? (column.sortCaret(sort.field === column.dataField
1292
- ? sort.order
1293
- : null, column)) : (_jsx(DefaultSortCaret, { order: sort.field === column.dataField
1294
- ? sort.order
1295
- : null, column: column })) }))] })] }));
1296
- })(), resizable && (_jsx("div", { style: {
1297
- position: 'absolute',
1298
- top: 0,
1299
- right: 0,
1300
- bottom: 0,
1301
- width: 6,
1302
- cursor: 'col-resize',
1303
- zIndex: 1,
1304
- display: 'flex',
1305
- alignItems: 'center',
1306
- justifyContent: 'center',
1307
- }, onMouseDown: (e) => {
1308
- e.preventDefault();
1309
- e.stopPropagation();
1310
- const cell = e.currentTarget
1311
- .parentElement;
1312
- if (cell) {
1313
- const startX = e.clientX;
1314
- const startWidth = cell.offsetWidth;
1315
- const dataField = column.dataField;
1316
- const handleMouseMove = (moveEvent) => {
1317
- const deltaX = moveEvent.clientX - startX;
1318
- const newWidth = Math.max(50, Math.min(800, startWidth + deltaX));
1319
- // Update via CSS for smooth resize
1320
- cell.style.width = `${newWidth}px`;
1321
- cell.style.minWidth = `${newWidth}px`;
1322
- cell.style.maxWidth = `${newWidth}px`;
1323
- // Update body cells too
1324
- document
1325
- .querySelectorAll(`[data-column="${dataField}"]`)
1326
- .forEach((el) => {
1327
- el.style.width =
1328
- `${newWidth}px`;
1329
- el.style.minWidth =
1330
- `${newWidth}px`;
1331
- el.style.maxWidth =
1332
- `${newWidth}px`;
1333
- });
1334
- };
1335
- const handleMouseUp = () => {
1336
- document.removeEventListener('mousemove', handleMouseMove);
1337
- document.removeEventListener('mouseup', handleMouseUp);
1338
- document.body.style.cursor = '';
1339
- document.body.style.userSelect = '';
1340
- // Trigger resize callback
1341
- const finalWidth = cell.offsetWidth;
1342
- resizeConfig?.onResizeEnd?.(dataField, finalWidth);
1343
- };
1344
- document.addEventListener('mousemove', handleMouseMove);
1345
- document.addEventListener('mouseup', handleMouseUp);
1346
- document.body.style.cursor = 'col-resize';
1347
- document.body.style.userSelect = 'none';
1348
- resizeConfig?.onResizeStart?.(dataField, startWidth);
1349
- }
1350
- }, children: _jsx("div", { style: {
1351
- width: 3,
1352
- height: '60%',
1353
- background: 'rgba(255,255,255,0.3)',
1354
- borderRadius: 2,
1355
- transition: 'background 0.2s',
1356
- }, onMouseEnter: (e) => {
1357
- e.currentTarget.style.background =
1358
- resizeConfig?.handleHoverColor || '#3b82f6';
1359
- }, onMouseLeave: (e) => {
1360
- e.currentTarget.style.background = 'rgba(255,255,255,0.3)';
1361
- } }) }))] }, column.dataField));
1362
- })] }) }), _jsx(TableBody, { className: classNames.body, style: styles.body, children: processedData.length === 0 ? (_jsx("tr", { children: _jsx("td", { colSpan: visibleColumns.length +
1363
- (resolvedRowSelection?.mode === 'checkbox' ? 1 : 0) +
1364
- (expandable ? 1 : 0) +
1365
- (showRowNumber ? 1 : 0), children: _jsxs(EmptyState, { className: classNames.empty, style: styles.empty, children: [_jsx(EmptyIcon, {}), _jsx("span", { children: emptyText })] }) }) })) : (processedData.map((row, rowIndex) => {
1366
- const rowKey = getRowKey(row);
1367
- const rowSelected = isSelected(rowKey);
1368
- const rowExpanded = isExpanded(rowKey);
1369
- const checkboxProps = resolvedRowSelection?.getCheckboxProps?.(row);
1370
- const isExpandable = expandable?.rowExpandable?.(row) ?? true;
1371
- const rowClass = typeof rowClassName === 'function'
1372
- ? rowClassName(row, rowIndex)
1373
- : rowClassName;
1374
- const rowStyles = typeof rowStyle === 'function'
1375
- ? rowStyle(row, rowIndex)
1376
- : rowStyle;
1377
- const selectedStyle = rowSelected
1378
- ? typeof resolvedRowSelection?.selectedRowStyle ===
1379
- 'function'
1380
- ? resolvedRowSelection.selectedRowStyle(row)
1381
- : resolvedRowSelection?.selectedRowStyle
1382
- : undefined;
1383
- // Check if custom selected style has a background color
1384
- const hasCustomBgColor = rowSelected &&
1385
- selectedStyle &&
1386
- (selectedStyle.backgroundColor || selectedStyle.background);
1387
- // Apply non-selectable style ONLY if row is disabled
1388
- // When disabled: false or not disabled, no styles should be applied
1389
- const isRowDisabled = !!checkboxProps?.disabled;
1390
- const disabledStyle = isRowDisabled
1391
- ? nonSelectableStyle || {
1392
- backgroundColor: '#f3f4f6',
1393
- opacity: 0.7,
1394
- }
1395
- : undefined;
1396
- return (_jsxs(React.Fragment, { children: [_jsxs(TableRow, { "$selected": rowSelected, "$clickable": !!onRowClick ||
1397
- resolvedRowSelection?.mode === 'single' ||
1398
- expandable?.expandRowByClick === true, "$disabled": isRowDisabled, "$hasCustomSelectedStyle": !!hasCustomBgColor, "data-custom-selected": hasCustomBgColor ? 'true' : undefined, className: `${classNames.row || ''} ${rowClass || ''} ${rowSelected
1399
- ? typeof resolvedRowSelection?.selectedRowClassName ===
1400
- 'function'
1401
- ? resolvedRowSelection.selectedRowClassName(row)
1402
- : resolvedRowSelection?.selectedRowClassName || ''
1403
- : ''}`, style: {
1404
- ...styles.row,
1405
- ...rowStyles,
1406
- ...selectedStyle,
1407
- ...disabledStyle,
1408
- }, onClick: (e) => handleRowClick(row, rowIndex, e), onDoubleClick: (e) => {
1409
- // Prevent double clicks ONLY on disabled rows
1410
- // When disabled: false, allow normal behavior
1411
- if (isRowDisabled) {
1412
- return;
1413
- }
1414
- // Only trigger row-level double click if not handled by a cell
1415
- // Cells handle their own double-clicks for editing
1416
- onRowDoubleClick?.(row, rowIndex, e);
1417
- }, role: "row", "aria-selected": rowSelected, children: [resolvedRowSelection?.mode === 'checkbox' && (_jsx(TableCell, { "$align": "center", "$compact": compact, "$padding": cellPadding, "$disabled": isRowDisabled, children: _jsx(Checkbox, { checked: rowSelected, disabled: checkboxProps?.disabled, onChange: (e) => handleCheckboxChange(row, e), onClick: (e) => e.stopPropagation() }) })), expandable && (_jsx(TableCell, { "$align": "center", "$compact": compact, "$padding": cellPadding, "$disabled": isRowDisabled, children: isExpandable && (_jsx(ExpandButton, { "$expanded": rowExpanded, onClick: (e) => handleExpandClick(row, e), children: expandable.expandIcon ? (expandable.expandIcon({
1418
- expanded: rowExpanded,
1419
- row,
1420
- onExpand: () => toggleExpand(row),
1421
- })) : (_jsx(ExpandIcon, {})) })) })), showRowNumber && (_jsx(TableCell, { "$align": "center", "$compact": compact, "$padding": cellPadding, "$disabled": isRowDisabled, style: {
1422
- width: rowNumberWidth,
1423
- color: '#6b7280',
1424
- fontWeight: 500,
1425
- }, children: rowNumberRender
1426
- ? rowNumberRender(rowIndex + 1, row)
1427
- : rowIndex + 1 + page * pageSize })), renderColumns.map((column, colIndex) => {
1428
- const cellClass = typeof column.classes === 'function'
1429
- ? column.classes(getNestedValue(row, column.dataField), row, rowIndex, colIndex)
1430
- : column.classes;
1431
- const cellStyle = typeof column.style === 'function'
1432
- ? column.style(getNestedValue(row, column.dataField), row, rowIndex, colIndex)
1433
- : column.style;
1434
- // Get resized column style for body cells
1435
- const cellResizeStyle = resizable
1436
- ? getColumnStyle(column, columnWidths, resizable, isResizing)
1437
- : {};
1438
- // Check if column is editable (needed for disabled row handling)
1439
- const editInfo = getCellEditableInfo(column, row, rowIndex, colIndex);
1440
- // Determine if column is effectively editable:
1441
- // - If rowSelection is configured AND row is disabled AND allowRows is NOT provided: NOT editable (even if marked as editable)
1442
- // - If rowSelection is configured AND row is disabled AND allowRows IS provided: editable only if in allowRows
1443
- // - Otherwise: editable if marked as editable
1444
- const isRowDisabled = !!checkboxProps?.disabled;
1445
- let isEffectivelyEditable = editInfo.isEditable;
1446
- // Only apply allowRows logic if rowSelection is configured and row is disabled
1447
- if (resolvedRowSelection && isRowDisabled) {
1448
- const hasAllowRows = resolvedRowSelection.allowRows && resolvedRowSelection.allowRows.length > 0;
1449
- if (!hasAllowRows) {
1450
- // No allowRows provided: disable all columns
1451
- isEffectivelyEditable = false;
1452
- }
1453
- else {
1454
- // allowRows provided: only columns in allowRows are editable
1455
- const isInAllowRows = resolvedRowSelection.allowRows.includes(column.dataField);
1456
- isEffectivelyEditable = isInAllowRows;
1457
- }
1458
- }
1459
- // Check if column is in allowRows (for styling purposes)
1460
- const isInAllowRows = !!(resolvedRowSelection &&
1461
- isRowDisabled &&
1462
- resolvedRowSelection.allowRows &&
1463
- resolvedRowSelection.allowRows.length > 0 &&
1464
- resolvedRowSelection.allowRows.includes(column.dataField));
1465
- return (_jsx(TableCell, { "$align": column.align || 'left', "$compact": compact, "$padding": cellPadding, "$pinned": column.pinned, "$hasCustomClass": !!cellClass, "$disabled": isRowDisabled, "$isEditable": isEffectivelyEditable, "$isInAllowRows": isInAllowRows, className: cellClass || classNames.cell, style: {
1466
- ...styles.cell,
1467
- ...cellStyle,
1468
- ...cellResizeStyle,
1469
- }, "data-column": column.dataField, onClick: (e) => handleCellClick(row, rowIndex, column, colIndex, e), onDoubleClick: (e) => {
1470
- e.stopPropagation(); // Prevent row-level double-click from interfering
1471
- handleCellDoubleClick(row, rowIndex, column, colIndex, e);
1472
- }, role: "gridcell", children: (() => {
1473
- if (isEffectivelyEditable &&
1474
- editMode !== 'none') {
1475
- // Check for custom editor
1476
- if (editInfo.customEditor) {
1477
- return editInfo.customEditor;
1478
- }
1479
- return (_jsx(EditableCell, { "$editing": editingCell?.row === rowIndex &&
1480
- editingCell?.field === column.dataField, "$showEditIcon": showEditIcon, children: renderCellContent(row, column, rowIndex, colIndex) }));
1481
- }
1482
- return renderCellContent(row, column, rowIndex, colIndex);
1483
- })() }, column.dataField));
1484
- })] }), expandable && rowExpanded && isExpandable && (_jsx(ExpandedRow, { children: _jsx(ExpandedCell, { colSpan: visibleColumns.length +
1485
- (resolvedRowSelection?.mode === 'checkbox'
1486
- ? 1
1487
- : 0) +
1488
- (expandable ? 1 : 0) +
1489
- (showRowNumber ? 1 : 0), children: expandable.expandedRowRender?.(row, rowIndex, rowExpanded) }) }))] }, rowKey));
1490
- })) }), showFooter && (_jsx(TableFooter, { className: classNames.footer, style: styles.footer, children: _jsxs(FooterRow, { className: classNames.footerRow, style: styles.footerRow, children: [resolvedRowSelection?.mode === 'checkbox' && (_jsx(FooterCell, { "$align": "center", "$compact": compact })), expandable && (_jsx(FooterCell, { "$align": "center", "$compact": compact })), showRowNumber && (_jsx(FooterCell, { "$align": "center", "$compact": compact })), renderColumns.map((column) => (_jsx(FooterCell, { "$align": column.align || 'left', "$compact": compact, className: classNames.footerCell, style: styles.footerCell, children: typeof column.footer === 'function'
1491
- ? column.footer(column, data)
1492
- : column.footerFormatter
1493
- ? column.footerFormatter(column, data)
1494
- : column.footer }, column.dataField)))] }) }))] }) }), renderPagination()] }));
1495
- });
1496
- Table.displayName = 'Table';
1497
- export default Table;
1
+ "use strict";"use client";import{jsx as n,jsxs as c}from"react/jsx-runtime";import Fr,{forwardRef as kr,useState as z,useCallback as u,useMemo as ce,useEffect as Q,useRef as L}from"react";import{TableRoot as xr,Toolbar as mr,ToolbarGroup as ft,SearchInput as Sr,ToolbarButton as te,TableWrapper as vr,StyledTable as wr,TableHeader as Rr,HeaderRow as $r,HeaderCell as Ke,TableBody as Er,TableRow as Tr,TableCell as Je,TableCellContent as Dr,Checkbox as _t,ExpandButton as Pr,ExpandedRow as Lr,ExpandedCell as Nr,TableFooter as Mr,FooterRow as jr,FooterCell as Ye,PaginationWrapper as Wr,PaginationInfo as zr,PaginationControls as Br,PageButton as he,PageSizeSelect as Ar,QuickJumper as Or,EmptyState as Hr,LoadingOverlay as Vr,LoadingSpinner as Ir,EditableCell as Kr,CellEditor as Jr,ColumnTogglePanel as Zt,ColumnToggleHeader as en,ColumnToggleSearch as tn,ColumnToggleList as nn,ColumnToggleItem as pt,ColumnToggleDragHandle as rn,SelectionIndicator as Yr,SelectionCount as Ur}from"./elements";import{useSortState as qr,useFilterState as Gr,usePaginationState as Qr,useRowSelection as Xr,useRowExpansion as _r,useColumnVisibility as Zr,useTableDebounce as ei,sortData as ti,filterData as gt,paginateData as ni,getNestedValue as B,exportToCSV as ri,exportToExcel as ii}from"./hooks";import{getFilterComponent as oi}from"./filters";import{Tooltip as li}from"../Tooltip";import{useColumnResize as ai,getColumnStyle as on}from"./columnResize";const si=()=>c("svg",{viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",children:[n("circle",{cx:"11",cy:"11",r:"8"}),n("path",{d:"M21 21l-4.35-4.35",strokeLinecap:"round"})]}),di=({size:O=16,color:X="white"})=>n("svg",{viewBox:"0 0 16 16",fill:X,style:{width:O,height:O,display:"block"},children:n("path",{fillRule:"evenodd",d:"M8 15a.5.5 0 0 0 .5-.5V2.707l3.146 3.147a.5.5 0 0 0 .708-.708l-4-4a.5.5 0 0 0-.708 0l-4 4a.5.5 0 1 0 .708.708L7.5 2.707V14.5a.5.5 0 0 0 .5.5z"})}),ci=({size:O=16,color:X="white"})=>n("svg",{viewBox:"0 0 16 16",fill:X,style:{width:O,height:O,display:"block"},children:n("path",{fillRule:"evenodd",d:"M8 1a.5.5 0 0 1 .5.5v11.793l3.146-3.147a.5.5 0 0 1 .708.708l-4 4a.5.5 0 0 1-.708 0l-4-4a.5.5 0 0 1 .708-.708L7.5 13.293V1.5A.5.5 0 0 1 8 1z"})}),ln=({order:O})=>{const X=()=>{switch(O){case"asc":return{up:18,down:12};case"desc":return{up:12,down:18};default:return{up:16,down:16}}},{up:ne,down:fe}=X();return c("div",{style:{display:"flex",flexDirection:"row",alignItems:"center",justifyContent:"center",gap:0},children:[n(di,{size:ne,color:"white"}),n(ci,{size:fe,color:"white"})]})},hi=()=>n("svg",{viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",children:n("path",{d:"M15 18l-6-6 6-6",strokeLinecap:"round",strokeLinejoin:"round"})}),fi=()=>n("svg",{viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",children:n("path",{d:"M9 18l6-6-6-6",strokeLinecap:"round",strokeLinejoin:"round"})}),pi=()=>n("svg",{viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",children:n("path",{d:"M11 17l-5-5 5-5M18 17l-5-5 5-5",strokeLinecap:"round",strokeLinejoin:"round"})}),gi=()=>n("svg",{viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",children:n("path",{d:"M13 7l5 5-5 5M6 7l5 5-5 5",strokeLinecap:"round",strokeLinejoin:"round"})}),ui=()=>n("svg",{viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",children:n("path",{d:"M9 18l6-6-6-6",strokeLinecap:"round",strokeLinejoin:"round"})}),an=()=>n("svg",{viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",children:n("path",{d:"M18 6L6 18M6 6l12 12",strokeLinecap:"round",strokeLinejoin:"round"})}),Ci=()=>n("svg",{viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",children:n("path",{d:"M22 3H2l8 9.46V19l4 2v-8.54L22 3z",strokeLinecap:"round",strokeLinejoin:"round"})}),yi=()=>n("svg",{viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",children:n("path",{d:"M21 15v4a2 2 0 01-2 2H5a2 2 0 01-2-2v-4M7 10l5 5 5-5M12 15V3",strokeLinecap:"round",strokeLinejoin:"round"})}),bi=()=>c("svg",{viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",children:[n("rect",{x:"3",y:"3",width:"7",height:"18",rx:"1"}),n("rect",{x:"14",y:"3",width:"7",height:"18",rx:"1"})]}),Fi=()=>c("svg",{viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"1.5",children:[n("rect",{x:"3",y:"3",width:"18",height:"18",rx:"2"}),n("path",{d:"M3 9h18M9 3v18",strokeLinecap:"round"})]}),ki=()=>c("svg",{viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",children:[n("path",{d:"M23 4v6h-6M1 20v-6h6",strokeLinecap:"round",strokeLinejoin:"round"}),n("path",{d:"M3.51 9a9 9 0 0114.85-3.36L23 10M1 14l4.64 4.36A9 9 0 0020.49 15",strokeLinecap:"round",strokeLinejoin:"round"})]}),xi=()=>c("svg",{viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",children:[n("path",{d:"M6 9V2h12v7M6 18H4a2 2 0 01-2-2v-5a2 2 0 012-2h16a2 2 0 012 2v5a2 2 0 01-2 2h-2",strokeLinecap:"round",strokeLinejoin:"round"}),n("rect",{x:"6",y:"14",width:"12",height:"8"})]}),so=()=>c("svg",{viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",children:[n("circle",{cx:"12",cy:"12",r:"10"}),n("path",{d:"M12 8v4M12 16h.01",strokeLinecap:"round",strokeLinejoin:"round"})]});export const Table=kr(function(X,ne){const{id:fe,data:C,columns:F,keyField:M="_id",loading:sn=!1,loadingIndicator:dn,pagination:we=!0,paginationConfig:ut,totalSize:A,remote:Ct=!0,defaultSort:cn,sort:hn,filterable:fn=!1,defaultFilters:pn,filters:gn,defaultShowFilters:un=!0,showFilters:yt,onShowFiltersChange:bt,showFilterToggle:Ft=!0,searchable:kt=!0,searchPlaceholder:Cn="Search...",defaultSearchValue:yn="",searchValue:bn,searchDebounce:Fn=300,rowSelection:H,expandable:g,editMode:V="dblclick",showEditIcon:kn=!1,onCellEdit:xt,exportable:xn=!0,exportFileName:mn="table_export",exportFormat:Ue="csv",columnToggle:Sn=!1,bordered:vn=!0,striped:wn=!1,hover:Rn=!0,compact:v=!1,cellPadding:Re,stickyHeader:mt=!1,maxHeight:$n,rowClassName:qe,rowStyle:Ge,classNames:k={},styles:x={},className:En,style:Tn,emptyText:Dn="No data available",onChange:D,onPageChange:$e,onSortChange:St,onFilterChange:Ee,onSearch:vt,onRowClick:Qe,onRowDoubleClick:Xe,onClearFilters:wt,toolbar:Te,hideToolbar:Pn=!1,showFooter:Ln=!1,caption:Rt,isDelete:mi=!1,isEditModify:Si,isUpdate:vi,isExport:Nn,isSelectRow:$t,getNonSelectableRows:Mn,nonSelectableStyle:jn,isView:wi=!1,fileName:Wn,hideExcelSheet:De=!1,onSelectedRow:zn,selectedRowStyle:Bn,selectedRowClassName:An,onUpdateItem:pe,onPageSizeChange:Pe,onFilter:_e,clearAllFilter:On,onDelete:Ri,onEdit:$i,onView:Ei,dynamicStylingFields:Ti,fieldTypeConfig:re,showRowNumber:ge=!1,rowNumberWidth:Et=50,rowNumberTitle:Hn="#",rowNumberRender:Tt,toolbarPosition:Di="top",toolbarLeft:Vn,toolbarRight:In,toolbarCenter:Kn,refreshable:Jn=!1,onRefresh:Yn,printable:Un=!1,onPrint:qn,size:Pi="medium",error:Li,onRetry:Ni,skeletonLoading:Mi=!1,skeletonRowCount:ji=5,hideHeader:Wi=!1,highlightedRowKeys:zi=[],highlightRowStyle:Bi,highlightRowClassName:Ai,onRowMouseEnter:Oi,onRowMouseLeave:Hi,onCellClick:Vi,onHeaderClick:Ii,resizable:j=!0,resizeConfig:Le,reorderable:$=!0,reorderConfig:Dt,...Pt}=X,Gn=Nn??xn,Ze=Wn??mn,_=ce(()=>A!==void 0&&A>0&&A<=C.length?!1:Ct,[Ct,A,C.length]),d=$t?{mode:"checkbox",selectedRowStyle:Bn||H?.selectedRowStyle,selectedRowClassName:An||H?.selectedRowClassName,...H,getCheckboxProps:e=>{const t=e[M],r=Mn?.includes(t),i=H?.getCheckboxProps?.(e);return{...i,disabled:r||i?.disabled}},onChange:(e,t)=>{H?.onChange?.(e,t)}}:H,et=ce(()=>d?d.allowEditingCells||[]:[],[d]),ie=et.length>0,oe=u(e=>ie?et.includes(e):!1,[ie,et]),I=we?{page:0,pageSize:10,showSizeChanger:!0,showQuickJumper:!0,showTotal:!0,pageSizeOptions:[10,20,30,50],...ut}:ut,Ki={small:{padding:"4px 8px",fontSize:"12px"},medium:{padding:"8px 12px",fontSize:"14px"},large:{padding:"12px 16px",fontSize:"16px"}},Qn=L(null),Ne=L(null),Lt=L(0),[Xn,Nt]=z(yn),[_n,Zn]=z(un),[K,ue]=z(!1),[Me,Mt]=z(""),[er,tt]=z("none"),[J,le]=z(null),[jt,Y]=z(null),[w,je]=z(F);Q(()=>{const e=w.map(r=>r.dataField).sort().join(","),t=F.map(r=>r.dataField).sort().join(",");if(e!==t){const r=new Map(F.map(o=>[o.dataField,o])),i=new Set(w.map(o=>o.dataField)),l=w.filter(o=>r.has(o.dataField)).map(o=>r.get(o.dataField)),h=F.filter(o=>!i.has(o.dataField));je([...l,...h])}else{const r=new Map(F.map(i=>[i.dataField,i]));je(w.map(i=>r.get(i.dataField)||i))}},[F]),Q(()=>{if(!K)return;const e=t=>{Ne.current&&!Ne.current.contains(t.target)&&ue(!1)};return document.addEventListener("mousedown",e),()=>{document.removeEventListener("mousedown",e)}},[K]);const nt=yt!==void 0,rt=nt?yt:_n,Ji=u(()=>{const e=!rt;nt||Zn(e),bt?.(e)},[rt,nt,bt]),[U,E]=z(null),[W,q]=z(null),We=L(new Map);Q(()=>{We.current.clear()},[U]);const ae=bn??Xn,P=ei(ae,Fn),{sort:m,handleSort:Wt}=qr(cn,hn),{filters:S,setFilter:zt,clearFilters:Bt}=Gr(pn,gn),Ce=L(!1),ze=L("filter"),At=L(_e),tr=L(null),ye=L(null),be=L(null);Q(()=>{const e=t=>{be.current&&!be.current.contains(t.target)&&(ye.current=null)};return document.addEventListener("mousedown",e),()=>{document.removeEventListener("mousedown",e)}},[]),Q(()=>{const e=()=>{if(ye.current&&be.current){const r=be.current.querySelector(`[data-filter-field="${ye.current}"]`);if(r&&document.activeElement!==r){r.focus();const i=r.value?.length||0;r.setSelectionRange(i,i)}}},t=[requestAnimationFrame(()=>e()),setTimeout(()=>e(),50),setTimeout(()=>e(),150)];return()=>{t.forEach(r=>{typeof r=="number"&&(cancelAnimationFrame(r),clearTimeout(r))})}},[C]);const{page:y,pageSize:T,totalPages:Yi,goToPage:Ot,goToNextPage:Ui,goToPrevPage:qi,goToFirstPage:Gi,goToLastPage:Qi,changePageSize:Ht}=Qr(I?.page||0,I?.pageSize||10,A??C.length),{selectedKeys:Z,isSelected:nr,toggleRow:Be,toggleAll:Vt,isAllSelected:it,isIndeterminate:rr}=Xr(C,d?.keyField||M,d?.mode||"none",d?.selectedRowKeys,d?.getCheckboxProps),{expandedKeys:Xi,isExpanded:ir,toggleExpand:Fe}=_r(g?.keyField||M,g?.defaultExpandedRowKeys,g?.expandedRowKeys,g?.accordion),{visibleColumns:se,toggleColumn:Ae,isColumnHidden:ee}=Zr(F,fe),{columnWidths:Oe,getResizeHandle:_i,resetWidths:Zi,isResizing:It}=ai({columns:se,config:Le,enabled:j,tableId:fe}),or=ce(()=>w.filter(e=>!ee(e.dataField)),[w,ee]),ot=$?or:se;Q(()=>{At.current=_e},[_e]);const Kt=L(P),Jt=L(JSON.stringify(S));Q(()=>{if(!Ce.current)return;const e=JSON.stringify(S),t=Kt.current!==P,r=Jt.current!==e;if(!t&&!r){Ce.current=!1;return}Kt.current=P,Jt.current=e;const i={};Object.keys(S).forEach(o=>{const a=S[o];a!=null&&a!==""&&(i[o]=a)});const l=Object.keys(i).length>0,h={...i};ze.current==="search"&&P&&(h.srText=P),At.current?.(ze.current,h,y+1,T),Ce.current=!1},[P,S,y,T]),Q(()=>{const e=Z.size,t=Lt.current;e>t?tt("up"):e<t&&tt("down"),Lt.current=e;const r=setTimeout(()=>{tt("none")},300);return()=>clearTimeout(r)},[Z.size]);const lt=ce(()=>{if(_)return C;let e=[...C];return e=gt(e,S,F,P),e=ti(e,m,F),we&&(e=ni(e,y,T)),e},[C,S,m,y,T,P,_,we,F]),ke=ce(()=>A!==void 0&&A>0?A:_?C.length:gt(C,S,F,P).length,[C,S,F,P,_,A]),at=u(e=>{Nt(e),vt?.(e),Ce.current=!0,ze.current="search",D?.({type:"search",search:e})},[vt,D]),st=u(e=>{if(!e.sort)return;const t=Wt(e.dataField,m.order);St?.(t),D?.({type:"sort",sort:t})},[m,Wt,St,D]),Yt=u((e,t)=>{zt(e,t);const r={...S,[e]:t};Ee?.(r),Ce.current=!0,ze.current="filter",D?.({type:"filter",filters:r})},[S,zt,Ee,D]),Ut=u(()=>{Bt(),Nt(""),wt?.(),On?.(),Ee?.({}),D?.({type:"filter",filters:{}}),tr.current=null},[Bt,wt,Ee,D]),de=u(e=>{Ot(e);const t=e+1;Pe?.(t,T),$e?.(t,T),D?.({type:"pagination",pagination:{page:t,pageSize:T}})},[Ot,T,Pe,$e,D]),lr=u(e=>{Ht(e),Pe?.(1,e),$e?.(1,e),D?.({type:"pagination",pagination:{page:1,pageSize:e}})},[Ht,Pe,$e,D]),ar=u((e,t,r)=>{if(!d?.getCheckboxProps?.(e)?.disabled){if(d?.mode==="single"){const l=Be(e);l&&d?.onChange?.(l.selectedKeys,l.selectedRows)}if(g?.expandRowByClick){const l=Fe(e);l&&g.onExpandChange?.(l.expandedKeys,l.expanded,e)}Qe?.(e,t,r)}},[H,g,Be,Fe,Qe,d]),xe=u((e,t,r,i)=>{const l=!!e.editorRenderer;if(e.editable===void 0)return{isEditable:l};if(e.editable===!1)return{isEditable:!1};if(e.editable===!0)return{isEditable:!0};const h=B(t,e.dataField),o=e.editable(h,t,r,i);return typeof o=="boolean"?{isEditable:o}:{isEditable:!0,customEditor:o}},[]),sr=u((e,t,r,i,l)=>{if(d&&!!d.getCheckboxProps?.(e)?.disabled&&(!ie||!oe(r.dataField)))return;const{isEditable:h}=xe(r,e,t,i);r.events?.onDoubleClick?.(l,e,t,r,i),V!=="none"&&(d?!!d.getCheckboxProps?.(e)?.disabled?oe(r.dataField)&&V==="dblclick"&&(E({row:t,field:r.dataField}),q(B(e,r.dataField))):h&&V==="dblclick"&&(E({row:t,field:r.dataField}),q(B(e,r.dataField))):h&&V==="dblclick"&&(E({row:t,field:r.dataField}),q(B(e,r.dataField)))),Xe?.(e,t,l)},[V,Xe,xe,d]),dr=u((e,t,r,i,l)=>{if(d&&!!d.getCheckboxProps?.(e)?.disabled&&(!ie||!oe(r.dataField)))return;const{isEditable:h}=xe(r,e,t,i);l&&r.events?.onClick?.(l,e,t,r,i),V==="click"&&(d?!!d.getCheckboxProps?.(e)?.disabled?oe(r.dataField)&&(E({row:t,field:r.dataField}),q(B(e,r.dataField))):h&&(E({row:t,field:r.dataField}),q(B(e,r.dataField))):h&&(E({row:t,field:r.dataField}),q(B(e,r.dataField))))},[V,xe,d]),dt=u((e,t,r)=>{if(U){if(r.validator){const l=r.validator(W,e);if(l!==!0){alert(typeof l=="string"?l:"Invalid value"),E(null);return}}const i=e[M];xt?.(W,r.dataField,e,t),pe?.(W,r.dataField,i)}E(null)},[U,W,xt,pe,M]),cr=(e,t)=>t.split(".").reduce((r,i)=>r?.[i],e),qt=u((e,t,r)=>{const i=re?.[t],l=typeof i=="string"?{type:i}:i;switch(l?.type||"string"){case"array":return l?.fields&&l.fields.length>0?Array.isArray(e)?e.slice(0,l.maxItems||e.length).map(s=>typeof s=="object"&&l.fields?l.fields.map(p=>s[p]).filter(Boolean).join(", "):typeof s=="string"?s:"").filter(Boolean).join(l.separator||"; "):e||"":Array.isArray(e)?e.map(s=>typeof s=="object"?JSON.stringify(s):s).join("; "):e||"";case"object":if(!e||typeof e!="object")return"";const o=l?.fields||l?.keys||[],a=l?.labelMap||{};return o.length>0?o.map(s=>{const p=cr(e,s);return p!=null?`${a[s]||s}: ${p}`:null}).filter(Boolean).join(", "):Object.entries(e).map(([s,p])=>typeof p=="boolean"?`${s}: ${p?"Yes":"No"}`:`${s}: ${p}`).join(", ");case"date":if(!e)return"";try{const s=new Date(e),p=l?.dateFormat||"YYYY-MM-DD HH:mm:ss";return s.toISOString().slice(0,19).replace("T"," ")}catch{return String(e)}case"number":return e!=null?String(Number(e)):"";case"boolean":return typeof e=="boolean"?e?"Yes":"No":"";default:return typeof e=="boolean"?e?"Yes":"No":e!=null?String(e):""}},[re]),Gt=u(async()=>{const e=_?C:gt(C,S,F,P);let t=se.filter(i=>i.csvExport!==!1);Array.isArray(De)&&(t=t.filter(i=>!De.includes(i.dataField))),re&&(t=t.filter(i=>{const l=re[i.dataField],h=typeof l=="string"?{type:l}:l;return!(h?.hideFromExport||h?.csvExport===!1)}));const r=t.map(i=>{const l=re?.[i.dataField],h=typeof l=="string"?{type:l}:l;return i.csvFormatter?i:h?.exportFormatter?{...i,csvFormatter:h.exportFormatter}:h?.type?{...i,csvFormatter:(o,a)=>qt(o,i.dataField,a)}:i});Ue==="excel"?await ii(e,r,Ze):ri(e,r,Ze)},[C,S,F,P,se,De,re,qt,Ze,_,Ue]),hr=u((e,t)=>{t.stopPropagation();const r=Be(e);r&&d?.onChange?.(r.selectedKeys,r.selectedRows)},[Be,H]),fr=u(()=>{const e=Vt(!it);e&&d?.onChange?.(e.selectedKeys,e.selectedRows)},[Vt,it,d]),pr=u((e,t)=>{if(d?.getCheckboxProps?.(e)?.disabled)return;t.stopPropagation();const i=Fe(e);g?.onExpandChange?.(i.expandedKeys,i.expanded,e)},[Fe,g,d]),me=ce(()=>w.filter(e=>e.dataField!==M&&e.text.toLowerCase().includes(Me.toLowerCase())),[w,M,Me]),Qt=u(e=>e[M],[M]),Xt=u((e,t,r,i)=>{const l=B(e,t.dataField);if(U?.row===r&&U?.field===t.dataField){if(t.editorRenderer){const o=e[M],a=`${o??r}-${t.dataField}`;if(!We.current.has(a)){const s={value:W,onUpdate:p=>{q(p),pe?.(p,t.dataField,o),E(null)},onCancel:()=>E(null),onBlur:()=>{W!==l&&pe?.(W,t.dataField,o),E(null)},row:e,column:t,rowIndex:r,columnIndex:i,rowId:o,dataField:t.dataField,onUpdateItem:p=>{pe?.(p,t.dataField,o),E(null)}};We.current.set(a,t.editorRenderer(s,W,e,t,r,i))}return We.current.get(a)}return n(Jr,{type:t.editorType==="number"?"number":"text",value:W??"",onChange:o=>q(o.target.value),onBlur:()=>dt(e,r,t),onKeyDown:o=>{o.key==="Enter"&&dt(e,r,t),o.key==="Escape"&&E(null)},className:t.editorClasses,style:t.editorStyle,autoFocus:!0})}return t.formatter?t.formatter(l,e,r,i):l==null?"":typeof l=="boolean"?l?"Yes":"No":typeof l=="object"?JSON.stringify(l):String(l)},[U,W,dt]),gr=()=>{if(Pn)return null;if(typeof Te=="function")return Te({searchValue:ae,onSearch:at,onClearFilters:Ut,onExport:Gt});if(Te)return Te;const e=Object.keys(S).length>0||ae;return c(mr,{className:k.toolbar,style:x.toolbar,children:[c(ft,{children:[Vn,kt&&c(Sr,{children:[n(si,{}),n("input",{type:"text",value:ae,onChange:t=>at(t.target.value),onFocus:()=>{ye.current=null},placeholder:Cn})]}),kt&&n(te,{onClick:()=>at(""),disabled:!ae,style:{opacity:ae?1:.6},children:"Clear"}),n(te,{onClick:Ut,disabled:!e,style:{opacity:e?1:.6},children:"Clear all filters"}),Gn&&De!==!0&&c(te,{onClick:Gt,children:[n(yi,{}),Ue==="excel"?"Export Excel":"Export CSV"]}),Ft&&c("div",{ref:Ne,style:{position:"relative"},children:[n(li,{content:"Show/Hide Columns",position:"bottom",children:n(te,{$active:K,onClick:()=>ue(!K),"aria-label":"Toggle column visibility",style:{padding:"0 8px"},children:n(Ci,{})})}),K&&c(Zt,{children:[c(en,{children:[n("span",{children:"Show/Hide Columns"}),n("button",{onClick:()=>ue(!1),children:n(an,{})})]}),n(tn,{children:n("input",{type:"text",value:Me,onChange:t=>Mt(t.target.value),placeholder:"Search columns..."})}),c(nn,{children:[c(pt,{style:{borderBottom:"1px solid #e5e7eb",paddingBottom:8,marginBottom:4},children:[n("input",{type:"checkbox",checked:me.length>0&&me.every(t=>!ee(t.dataField)),onChange:t=>{me.forEach(r=>{t.target.checked?ee(r.dataField)&&Ae(r.dataField):ee(r.dataField)||Ae(r.dataField)})}}),n("span",{style:{fontWeight:600},children:"Select All"})]}),me.map((t,r)=>c(pt,{$reorderable:$,$isDragging:J===t.dataField,$isDragOver:jt===t.dataField,draggable:$,onDragStart:i=>{$&&(le(t.dataField),i.dataTransfer.effectAllowed="move",i.dataTransfer.setData("text/plain",t.dataField))},onDragEnd:()=>{le(null),Y(null)},onDragOver:i=>{$&&(i.preventDefault(),J&&J!==t.dataField&&Y(t.dataField))},onDragLeave:()=>{Y(null)},onDrop:i=>{if(!$)return;i.preventDefault();const l=i.dataTransfer.getData("text/plain");if(l&&l!==t.dataField){const h=w.findIndex(a=>a.dataField===l),o=w.findIndex(a=>a.dataField===t.dataField);if(h!==-1&&o!==-1){const a=[...w],[s]=a.splice(h,1);a.splice(o,0,s),je(a),Dt?.onReorder?.(a,h,o)}}le(null),Y(null)},children:[n("input",{type:"checkbox",checked:!ee(t.dataField),onChange:()=>Ae(t.dataField),onClick:i=>i.stopPropagation()}),n("span",{children:t.text}),$&&n(rn,{$isDragging:J===t.dataField,title:"Drag to reorder"})]},t.dataField))]})]})]})]}),Kn,c(ft,{children:[Jn&&c(te,{onClick:Yn,children:[n(ki,{}),"Refresh"]}),Un&&c(te,{onClick:qn,children:[n(xi,{}),"Print"]}),Sn&&c("div",{ref:Ft?void 0:Ne,style:{position:"relative"},children:[c(te,{$active:K,onClick:()=>ue(!K),children:[n(bi,{}),"Columns"]}),K&&c(Zt,{children:[c(en,{children:[n("span",{children:"Toggle Columns"}),n("button",{onClick:()=>ue(!1),children:n(an,{})})]}),n(tn,{children:n("input",{type:"text",value:Me,onChange:t=>Mt(t.target.value),placeholder:"Search columns..."})}),n(nn,{children:me.map((t,r)=>c(pt,{$reorderable:$,$isDragging:J===t.dataField,$isDragOver:jt===t.dataField,draggable:$,onDragStart:i=>{$&&(le(t.dataField),i.dataTransfer.effectAllowed="move",i.dataTransfer.setData("text/plain",t.dataField))},onDragEnd:()=>{le(null),Y(null)},onDragOver:i=>{$&&(i.preventDefault(),J&&J!==t.dataField&&Y(t.dataField))},onDragLeave:()=>{Y(null)},onDrop:i=>{if(!$)return;i.preventDefault();const l=i.dataTransfer.getData("text/plain");if(l&&l!==t.dataField){const h=w.findIndex(a=>a.dataField===l),o=w.findIndex(a=>a.dataField===t.dataField);if(h!==-1&&o!==-1){const a=[...w],[s]=a.splice(h,1);a.splice(o,0,s),je(a),Dt?.onReorder?.(a,h,o)}}le(null),Y(null)},children:[n("input",{type:"checkbox",checked:!ee(t.dataField),onChange:()=>Ae(t.dataField),onClick:i=>i.stopPropagation()}),n("span",{children:t.text}),$&&n(rn,{$isDragging:J===t.dataField,title:"Drag to reorder"})]},t.dataField))})]})]}),In]})]})},ur=()=>{if(!we)return null;const e=Math.ceil(ke/T)||1,t=ke>0?y*T+1:0,r=_?C.length:lt.length,i=Math.min(y*T+r,ke),l=I?.showTotal===!0?`Showing ${t} to ${i} of ${ke} Results`:typeof I?.showTotal=="function"?I.showTotal(ke,[t,i]):null,h=()=>{const o=[];if(e<=5)for(let s=0;s<e;s++)o.push(s);else if(y<3){for(let s=0;s<4;s++)o.push(s);o.push("..."),o.push(e-1)}else if(y>e-4){o.push(0),o.push("...");for(let s=e-4;s<e;s++)o.push(s)}else{o.push(0),o.push("...");for(let s=y-1;s<=y+1;s++)o.push(s);o.push("..."),o.push(e-1)}return o};return c(Wr,{className:k.pagination,style:x.pagination,children:[c(ft,{children:[(d?.mode==="checkbox"||$t)&&Z.size>0&&c(Yr,{onClick:()=>{const o=C.filter(a=>Z.has(Qt(a)));d?.onChange?.(Array.from(Z),o),zn?.(o)},children:[n(Ur,{$animate:er,children:Z.size},Z.size),n("span",{children:"Selected"})]}),I?.showSizeChanger!==!1&&n(Ar,{value:T,onChange:o=>lr(Number(o.target.value)),children:(I?.pageSizeOptions||[10,20,30,50]).map(o=>n("option",{value:o,children:o},o))})]}),c(Br,{children:[n(he,{onClick:()=>de(0),disabled:y===0,children:n(pi,{})}),n(he,{onClick:()=>de(y-1),disabled:y===0,children:n(hi,{})}),h().map((o,a)=>typeof o=="string"?n("span",{style:{padding:"0 4px",color:"white"},children:o},`ellipsis-${a}`):n(he,{$active:o===y,onClick:()=>de(o),children:o+1},o)),n(he,{onClick:()=>de(y+1),disabled:y>=e-1,children:n(fi,{})}),n(he,{onClick:()=>de(e-1),disabled:y>=e-1,children:n(gi,{})})]}),l&&n(zr,{children:l}),I?.showQuickJumper&&(()=>{const o=a=>{const s=parseInt(a.value,10);return!isNaN(s)&&s>=1&&s<=e?(de(s-1),a.value="",!0):!1};return c(Or,{children:["Go to",n("input",{type:"number",min:1,max:e,placeholder:`1-${e}`,onKeyDown:a=>{if(a.key==="Enter"){a.preventDefault();const s=a.target;o(s)&&s.blur()}},onBlur:a=>{const s=a.target;o(s)}}),n(he,{onClick:()=>{const a=document.querySelector(`#${fe} input[type="number"]`);a&&(o(a),a.blur())},style:{marginLeft:"4px",padding:"2px 8px"},children:"Go"})]})})()]})},Cr=(fn||F.some(e=>typeof e.filter=="function"||e.filterComponent||e.filter===!0))&&rt;return c(xr,{ref:e=>{typeof ne=="function"?ne(e):ne&&(ne.current=e),be.current=e},$bordered:vn,$compact:v,className:En||k.root,style:{...x.root,...Tn,position:"relative"},"aria-label":Pt["aria-label"],"aria-labelledby":Pt["aria-labelledby"],children:[sn&&n(Vr,{className:k.loading,style:x.loading,children:dn||n(Ir,{})}),gr(),n(vr,{$maxHeight:$n,$stickyHeader:mt,className:k.wrapper,style:x.wrapper,children:c(wr,{ref:Qn,$striped:wn,$hover:Rn,$compact:v,role:"grid",children:[Rt&&n("caption",{className:"sr-only",children:Rt}),n(Rr,{$sticky:mt,className:k.header,style:x.header,children:c($r,{className:k.headerRow,style:x.headerRow,children:[d?.mode==="checkbox"&&n(Ke,{$align:"center",$sortable:!1,$compact:v,$width:d.columnWidth||40,children:!d.hideSelectAll&&n(_t,{checked:it,ref:e=>{e&&(e.indeterminate=rr)},onChange:fr})}),g&&n(Ke,{$align:"center",$sortable:!1,$compact:v,$width:g.columnWidth||40}),ge&&n(Ke,{$align:"center",$sortable:!1,$compact:v,$width:Et,children:Hn}),ot.map((e,t)=>{const r=typeof e.filter=="function"||e.filter===!0||e.filterComponent||e.filterRenderer,i=r?(typeof e.filter=="function"?e.filter:null)||e.filterComponent||oi(e.filterType||"text"):null,l=a=>Yt(e.dataField,a),h=j?on(e,Oe,j,It):{};return c(Ke,{ref:a=>{if(a&&j){const s={current:a}}},$align:e.headerAlign||e.align||"left",$sortable:!!e.sort,$compact:v,$width:j&&Oe[e.dataField]?Oe[e.dataField]:e.width,$minWidth:e.minWidth,$pinned:e.pinned,$customClass:!!e.headerClasses,className:[e.headerClasses,k.headerCell].filter(Boolean).join(" "),style:{...typeof e.headerStyle=="function"?e.headerStyle(e):e.headerStyle||x.headerCell,...h,position:"relative"},role:"columnheader","aria-sort":m.field===e.dataField?m.order==="asc"?"ascending":m.order==="desc"?"descending":"none":void 0,"data-column":e.dataField,children:[(()=>{const a=typeof e.headerStyle=="function"?e.headerStyle(e):e.headerStyle,s=e.isHeaderTitle!==!1&&e.hideHeaderText!==!0&&!(a&&a.fontSize===0),p=e.isHeaderFilterComp!==!1&&Cr&&r&&i,b=e.isHeaderSort!==!1&&e.sort;return p?c("div",{style:{display:"flex",flexDirection:"column",gap:s?4:0,width:"100%",paddingRight:j?12:0,position:"relative",zIndex:2},children:[s&&n("div",{style:{display:"flex",alignItems:"center",justifyContent:"space-between",gap:4},children:n("span",{style:{color:"white",fontWeight:600,fontSize:12,whiteSpace:"nowrap",cursor:b?"pointer":"default",flex:1},onClick:()=>b&&st(e),children:e.headerFormatter?e.headerFormatter(e,t):e.headerText||e.text})}),c("div",{style:{display:"flex",alignItems:"center",justifyContent:"flex-start",gap:4,width:"100%",minHeight:24},children:[n("div",{style:{flex:b?"0 1 auto":1,width:b?"calc(100% - 48px)":"100%",minWidth:0,maxWidth:b?"calc(100% - 48px)":"100%",display:"flex",alignItems:"center",overflow:"hidden"},onClick:R=>R.stopPropagation(),children:e.filterRenderer?e.filterRenderer(l,e):n("div",{onFocusCapture:()=>{ye.current=e.dataField},"data-filter-wrapper":e.dataField,style:{width:"100%"},children:n(i,{column:e,value:S[e.dataField],onChange:l,onClear:()=>Yt(e.dataField,null)},`filter-${e.dataField}`)})}),b&&n("div",{style:{minWidth:40,minHeight:24,display:"flex",alignItems:"center",justifyContent:"center",flexShrink:0,flexGrow:0,cursor:"pointer",marginLeft:"auto",position:"relative",overflow:"visible"},onClick:R=>{R.stopPropagation(),st(e)},title:`Sort by ${e.text}`,children:e.sortCaret?e.sortCaret(m.field===e.dataField?m.order:null,e):n(ln,{order:m.field===e.dataField?m.order:null,column:e})})]})]}):c("div",{style:{display:"flex",alignItems:"center",justifyContent:e.headerAlign||e.align||"left",gap:6,width:"100%",cursor:b?"pointer":"default",paddingRight:j?12:0,position:"relative",zIndex:2},onClick:()=>b&&st(e),children:[s&&n("span",{style:{color:"white",fontWeight:600,fontSize:12,whiteSpace:"nowrap",flex:1},children:e.headerFormatter?e.headerFormatter(e,t):e.headerText||e.text}),b&&n("div",{style:{display:"flex",alignItems:"center",justifyContent:"center",flexShrink:0,minWidth:40,minHeight:24,position:"relative",overflow:"visible"},title:`Sort by ${e.text}`,children:e.sortCaret?e.sortCaret(m.field===e.dataField?m.order:null,e):n(ln,{order:m.field===e.dataField?m.order:null,column:e})})]})})(),j&&n("div",{style:{position:"absolute",top:0,right:0,bottom:0,width:6,cursor:"col-resize",zIndex:1,display:"flex",alignItems:"center",justifyContent:"center"},onMouseDown:a=>{a.preventDefault(),a.stopPropagation();const s=a.currentTarget.parentElement;if(s){const p=a.clientX,b=s.offsetWidth,R=e.dataField,He=N=>{const Ve=N.clientX-p,G=Math.max(50,Math.min(800,b+Ve));s.style.width=`${G}px`,s.style.minWidth=`${G}px`,s.style.maxWidth=`${G}px`,document.querySelectorAll(`[data-column="${R}"]`).forEach(Se=>{Se.style.width=`${G}px`,Se.style.minWidth=`${G}px`,Se.style.maxWidth=`${G}px`})},f=()=>{document.removeEventListener("mousemove",He),document.removeEventListener("mouseup",f),document.body.style.cursor="",document.body.style.userSelect="";const N=s.offsetWidth;Le?.onResizeEnd?.(R,N)};document.addEventListener("mousemove",He),document.addEventListener("mouseup",f),document.body.style.cursor="col-resize",document.body.style.userSelect="none",Le?.onResizeStart?.(R,b)}},children:n("div",{style:{width:3,height:"60%",background:"rgba(255,255,255,0.3)",borderRadius:2,transition:"background 0.2s"},onMouseEnter:a=>{a.currentTarget.style.background=Le?.handleHoverColor||"#3b82f6"},onMouseLeave:a=>{a.currentTarget.style.background="rgba(255,255,255,0.3)"}})})]},e.dataField)})]})}),n(Er,{className:k.body,style:x.body,children:lt.length===0?n("tr",{children:n("td",{colSpan:se.length+(d?.mode==="checkbox"?1:0)+(g?1:0)+(ge?1:0),children:c(Hr,{className:k.empty,style:x.empty,children:[n(Fi,{}),n("span",{children:Dn})]})})}):lt.map((e,t)=>{const r=Qt(e),i=nr(r),l=ir(r),h=d?.getCheckboxProps?.(e),o=g?.rowExpandable?.(e)??!0,a=typeof qe=="function"?qe(e,t):qe,s=typeof Ge=="function"?Ge(e,t):Ge,p=i?typeof d?.selectedRowStyle=="function"?d.selectedRowStyle(e):d?.selectedRowStyle:void 0,b=i&&p&&(p.backgroundColor||p.background),R=!!h?.disabled,He=R?jn||{backgroundColor:"#f3f4f6",opacity:.7}:void 0;return c(Fr.Fragment,{children:[c(Tr,{$selected:i,$clickable:!!Qe||d?.mode==="single"||g?.expandRowByClick===!0,$disabled:R,$hasCustomSelectedStyle:!!b,"data-custom-selected":b?"true":void 0,className:`${k.row||""} ${a||""} ${i?typeof d?.selectedRowClassName=="function"?d.selectedRowClassName(e):d?.selectedRowClassName||"":""}`,style:{...x.row,...s,...p,...He},onClick:f=>ar(e,t,f),onDoubleClick:f=>{R||Xe?.(e,t,f)},role:"row","aria-selected":i,children:[d?.mode==="checkbox"&&n(Je,{$align:"center",$compact:v,$padding:Re,$disabled:R,children:n(_t,{checked:i,disabled:h?.disabled,onChange:f=>hr(e,f),onClick:f=>f.stopPropagation()})}),g&&n(Je,{$align:"center",$compact:v,$padding:Re,$disabled:R,children:o&&n(Pr,{$expanded:l,onClick:f=>pr(e,f),children:g.expandIcon?g.expandIcon({expanded:l,row:e,onExpand:()=>Fe(e)}):n(ui,{})})}),ge&&n(Je,{$align:"center",$compact:v,$padding:Re,$disabled:R,style:{width:Et,color:"#6b7280",fontWeight:500},children:Tt?Tt(t+1,e):t+1+y*T}),ot.map((f,N)=>{const Ve=typeof f.classes=="function"?f.classes(B(e,f.dataField),e,t,N):f.classes,G=typeof f.style=="function"?f.style(B(e,f.dataField),e,t,N):f.style,Se=j?on(f,Oe,j,It):{},ct=xe(f,e,t,N),ht=!!h?.disabled;let Ie=ct.isEditable;d&&ht&&(ie?Ie=oe(f.dataField):Ie=!1);const yr=!!(d&&ht&&ie&&oe(f.dataField)),br=Ie&&V!=="none"?ct.customEditor?ct.customEditor:n(Kr,{$editing:U?.row===t&&U?.field===f.dataField,$showEditIcon:kn,children:Xt(e,f,t,N)}):Xt(e,f,t,N);return n(Je,{$align:f.align||"left",$compact:v,$padding:Re,$pinned:f.pinned,$hasCustomClass:!!Ve,$disabled:ht,$isEditable:Ie,$isInAllowedCells:yr,className:Ve||k.cell,style:{...x.cell,...G,...Se},"data-column":f.dataField,onClick:ve=>dr(e,t,f,N,ve),onDoubleClick:ve=>{ve.stopPropagation(),sr(e,t,f,N,ve)},role:"gridcell",children:n(Dr,{$hasFormatter:!!f.formatter,children:br})},f.dataField)})]}),g&&l&&o&&n(Lr,{children:n(Nr,{colSpan:se.length+(d?.mode==="checkbox"?1:0)+(g?1:0)+(ge?1:0),children:g.expandedRowRender?.(e,t,l)})})]},r)})}),Ln&&n(Mr,{className:k.footer,style:x.footer,children:c(jr,{className:k.footerRow,style:x.footerRow,children:[d?.mode==="checkbox"&&n(Ye,{$align:"center",$compact:v}),g&&n(Ye,{$align:"center",$compact:v}),ge&&n(Ye,{$align:"center",$compact:v}),ot.map(e=>n(Ye,{$align:e.align||"left",$compact:v,className:k.footerCell,style:x.footerCell,children:typeof e.footer=="function"?e.footer(e,C):e.footerFormatter?e.footerFormatter(e,C):e.footer},e.dataField))]})})]})}),ur()]})});Table.displayName="Table";export default Table;