pixelize-design-library 2.3.1-beta.2 → 2.3.1-beta.20

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 (165) hide show
  1. package/.claude/settings.local.json +28 -1
  2. package/.cursor/TASK-SETUP.md +43 -0
  3. package/.cursor/agents/be-impl.md +37 -0
  4. package/.cursor/agents/fe-impl.md +39 -0
  5. package/.cursor/agents/task-plan.md +56 -0
  6. package/.cursor/agents/test-create.md +31 -0
  7. package/.cursor/agents/test-exec.md +26 -0
  8. package/.cursor/hooks/task-hint.env +1 -0
  9. package/.cursor/hooks/task-skill-nudge.sh +71 -0
  10. package/.cursor/hooks/task-slash-guard.sh +31 -0
  11. package/.cursor/hooks.json +13 -0
  12. package/.cursor/modules/account-management/MODULE.md +16 -0
  13. package/.cursor/modules/buttons/MODULE.md +13 -0
  14. package/.cursor/modules/cards/MODULE.md +13 -0
  15. package/.cursor/modules/charts/MODULE.md +13 -0
  16. package/.cursor/modules/common/MODULE.md +13 -0
  17. package/.cursor/modules/contact-auth/MODULE.md +13 -0
  18. package/.cursor/modules/data-display/MODULE.md +13 -0
  19. package/.cursor/modules/feedback/MODULE.md +14 -0
  20. package/.cursor/modules/form/MODULE.md +13 -0
  21. package/.cursor/modules/inputs-basic/MODULE.md +13 -0
  22. package/.cursor/modules/inputs-date-file/MODULE.md +19 -0
  23. package/.cursor/modules/inputs-select/MODULE.md +14 -0
  24. package/.cursor/modules/inputs-toggle/MODULE.md +13 -0
  25. package/.cursor/modules/kanban/MODULE.md +14 -0
  26. package/.cursor/modules/layout-navigation/MODULE.md +14 -0
  27. package/.cursor/modules/overlays/MODULE.md +13 -0
  28. package/.cursor/modules/playground/MODULE.md +15 -0
  29. package/.cursor/modules/table/MODULE.md +15 -0
  30. package/.cursor/modules/theme/MODULE.md +15 -0
  31. package/.cursor/modules/types-exports/MODULE.md +17 -0
  32. package/.cursor/modules/utility-ui/MODULE.md +15 -0
  33. package/.cursor/modules/utils-hooks/MODULE.md +13 -0
  34. package/.cursor/pixelize-task-statusline.sh +64 -0
  35. package/.cursor/plans/blocked/.gitkeep +0 -0
  36. package/.cursor/plans/current.md +35 -0
  37. package/.cursor/plans/done/.gitkeep +0 -0
  38. package/.cursor/rules +31 -0
  39. package/.cursor/skills/task/SKILL.md +167 -0
  40. package/CLAUDE.md +122 -0
  41. package/dist/Components/Accordion/Accordion.js +26 -5
  42. package/dist/Components/Card/PaymentCard/PaymentCard.d.ts +1 -1
  43. package/dist/Components/Card/PaymentCard/PaymentCard.js +3 -3
  44. package/dist/Components/Card/PaymentCard/PaymentCardProps.d.ts +1 -0
  45. package/dist/Components/CopyButton/CopyButton.d.ts +22 -0
  46. package/dist/Components/CopyButton/CopyButton.js +126 -0
  47. package/dist/Components/CustomModulesTable/CustomModulesTable.d.ts +4 -0
  48. package/dist/Components/CustomModulesTable/CustomModulesTable.js +182 -0
  49. package/dist/Components/CustomModulesTable/CustomModulesTable.test.d.ts +1 -0
  50. package/dist/Components/CustomModulesTable/CustomModulesTable.test.js +84 -0
  51. package/dist/Components/CustomModulesTable/CustomModulesTableProps.d.ts +54 -0
  52. package/dist/Components/CustomModulesTable/CustomModulesTableProps.js +2 -0
  53. package/dist/Components/CustomModulesTable/DeleteModuleModal.d.ts +4 -0
  54. package/dist/Components/CustomModulesTable/DeleteModuleModal.js +33 -0
  55. package/dist/Components/CustomModulesTable/EditModuleModal.d.ts +4 -0
  56. package/dist/Components/CustomModulesTable/EditModuleModal.js +63 -0
  57. package/dist/Components/Dropdown/DropDown.js +110 -28
  58. package/dist/Components/Dropdown/Dropdown.test.d.ts +1 -0
  59. package/dist/Components/Dropdown/Dropdown.test.js +102 -0
  60. package/dist/Components/Dropdown/DropdownProps.d.ts +4 -1
  61. package/dist/Components/EmptyState/EmptyState.d.ts +4 -0
  62. package/dist/Components/EmptyState/EmptyState.js +65 -0
  63. package/dist/Components/EmptyState/EmptyStateProps.d.ts +28 -0
  64. package/dist/Components/EmptyState/EmptyStateProps.js +2 -0
  65. package/dist/Components/FieldSelectModal/FieldSelectModal.d.ts +26 -0
  66. package/dist/Components/FieldSelectModal/FieldSelectModal.js +107 -0
  67. package/dist/Components/FilePreview/FilePreview.d.ts +6 -0
  68. package/dist/Components/FilePreview/FilePreview.js +190 -0
  69. package/dist/Components/FilePreview/FilePreviewProps.d.ts +26 -0
  70. package/dist/Components/FilePreview/FilePreviewProps.js +2 -0
  71. package/dist/Components/KanbanBoard/AccountCard.js +17 -14
  72. package/dist/Components/KanbanBoard/KanbanBoard.js +93 -78
  73. package/dist/Components/LazyWrapper/LazyWrapper.d.ts +10 -0
  74. package/dist/Components/LazyWrapper/LazyWrapper.js +50 -0
  75. package/dist/Components/MoreItems/MoreItems.d.ts +4 -0
  76. package/dist/Components/MoreItems/MoreItems.js +35 -0
  77. package/dist/Components/MoreItems/MoreItemsProps.d.ts +29 -0
  78. package/dist/Components/MoreItems/MoreItemsProps.js +2 -0
  79. package/dist/Components/NavigationBar/NavigationBar.js +4 -4
  80. package/dist/Components/OrgSwitcher/OrgSwitcher.d.ts +4 -0
  81. package/dist/Components/OrgSwitcher/OrgSwitcher.js +121 -0
  82. package/dist/Components/OrgSwitcher/OrgSwitcherProps.d.ts +41 -0
  83. package/dist/Components/OrgSwitcher/OrgSwitcherProps.js +25 -0
  84. package/dist/Components/OrganizationDetails/CreateOrgModal.d.ts +4 -0
  85. package/dist/Components/OrganizationDetails/CreateOrgModal.js +122 -0
  86. package/dist/Components/OrganizationDetails/DeleteOrgModal.d.ts +4 -0
  87. package/dist/Components/OrganizationDetails/DeleteOrgModal.js +29 -0
  88. package/dist/Components/OrganizationDetails/OrganizationDetails.d.ts +4 -0
  89. package/dist/Components/OrganizationDetails/OrganizationDetails.js +264 -0
  90. package/dist/Components/OrganizationDetails/OrganizationDetails.test.d.ts +1 -0
  91. package/dist/Components/OrganizationDetails/OrganizationDetails.test.js +122 -0
  92. package/dist/Components/OrganizationDetails/OrganizationDetailsProps.d.ts +88 -0
  93. package/dist/Components/OrganizationDetails/OrganizationDetailsProps.js +2 -0
  94. package/dist/Components/PdfViewer/PdfViewer.d.ts +15 -0
  95. package/dist/Components/PdfViewer/PdfViewer.js +29 -0
  96. package/dist/Components/ProfilePhotoViewer/ProfilePhotoViewer.d.ts +1 -1
  97. package/dist/Components/ProfilePhotoViewer/ProfilePhotoViewer.js +42 -24
  98. package/dist/Components/ProfilePhotoViewer/ProfilePhotoViewerProps.d.ts +2 -0
  99. package/dist/Components/RolesPermission/DeleteRoleModal.d.ts +4 -0
  100. package/dist/Components/RolesPermission/DeleteRoleModal.js +29 -0
  101. package/dist/Components/RolesPermission/RolesPermission.d.ts +4 -0
  102. package/dist/Components/RolesPermission/RolesPermission.js +243 -0
  103. package/dist/Components/RolesPermission/RolesPermission.test.d.ts +1 -0
  104. package/dist/Components/RolesPermission/RolesPermission.test.js +150 -0
  105. package/dist/Components/RolesPermission/RolesPermissionProps.d.ts +117 -0
  106. package/dist/Components/RolesPermission/RolesPermissionProps.js +2 -0
  107. package/dist/Components/ScrollToTop/ScrollToTop.d.ts +19 -0
  108. package/dist/Components/ScrollToTop/ScrollToTop.js +104 -0
  109. package/dist/Components/SearchSelect/SearchSelect.js +53 -21
  110. package/dist/Components/SideBar/components/OtherApps.test.js +3 -2
  111. package/dist/Components/SignInActivityTable/SignInActivityTable.d.ts +4 -0
  112. package/dist/Components/SignInActivityTable/SignInActivityTable.js +95 -0
  113. package/dist/Components/SignInActivityTable/SignInActivityTable.test.d.ts +1 -0
  114. package/dist/Components/SignInActivityTable/SignInActivityTable.test.js +63 -0
  115. package/dist/Components/SignInActivityTable/SignInActivityTableProps.d.ts +21 -0
  116. package/dist/Components/SignInActivityTable/SignInActivityTableProps.js +2 -0
  117. package/dist/Components/StageProgress/StageItem.d.ts +4 -0
  118. package/dist/Components/StageProgress/StageItem.js +137 -0
  119. package/dist/Components/StageProgress/StageProgress.d.ts +4 -0
  120. package/dist/Components/StageProgress/StageProgress.js +59 -0
  121. package/dist/Components/StageProgress/StageProgressProps.d.ts +85 -0
  122. package/dist/Components/StageProgress/StageProgressProps.js +27 -0
  123. package/dist/Components/StageProgress/StepperStage.d.ts +4 -0
  124. package/dist/Components/StageProgress/StepperStage.js +78 -0
  125. package/dist/Components/Table/Table.d.ts +1 -1
  126. package/dist/Components/Table/Table.js +167 -32
  127. package/dist/Components/Table/TableProps.d.ts +11 -3
  128. package/dist/Components/Table/components/Pagination.js +1 -1
  129. package/dist/Components/Table/components/TableActions.d.ts +2 -2
  130. package/dist/Components/Table/components/TableActions.js +5 -4
  131. package/dist/Components/Table/components/TableBody.js +98 -29
  132. package/dist/Components/Table/components/TableBody.virtualize.test.js +13 -3
  133. package/dist/Components/Table/components/TableHeader.d.ts +1 -1
  134. package/dist/Components/Table/components/TableHeader.js +9 -13
  135. package/dist/Components/Table/hooks/useTable.d.ts +2 -1
  136. package/dist/Components/Table/hooks/useTable.js +24 -10
  137. package/dist/Components/Table/settings/ManageColumns.test.js +1 -0
  138. package/dist/Components/Table/settings/TableSettings.d.ts +3 -2
  139. package/dist/Components/Table/settings/TableSettings.js +30 -6
  140. package/dist/Components/Timeline/Timeline.d.ts +1 -1
  141. package/dist/Components/Timeline/Timeline.js +145 -78
  142. package/dist/Components/Toaster/Toaster.js +40 -20
  143. package/dist/Components/UpgradeButton/UpgradeButton.d.ts +4 -0
  144. package/dist/Components/UpgradeButton/UpgradeButton.js +73 -0
  145. package/dist/Components/UpgradeButton/UpgradeButtonProps.d.ts +43 -0
  146. package/dist/Components/UpgradeButton/UpgradeButtonProps.js +2 -0
  147. package/dist/Components/UserDetails/AddUserModal.d.ts +4 -0
  148. package/dist/Components/UserDetails/AddUserModal.js +218 -0
  149. package/dist/Components/UserDetails/ChangeRoleModal.d.ts +4 -0
  150. package/dist/Components/UserDetails/ChangeRoleModal.js +150 -0
  151. package/dist/Components/UserDetails/DeactivateConfirmModal.d.ts +4 -0
  152. package/dist/Components/UserDetails/DeactivateConfirmModal.js +34 -0
  153. package/dist/Components/UserDetails/UserDetails.d.ts +4 -0
  154. package/dist/Components/UserDetails/UserDetails.js +263 -0
  155. package/dist/Components/UserDetails/UserDetails.test.d.ts +1 -0
  156. package/dist/Components/UserDetails/UserDetails.test.js +129 -0
  157. package/dist/Components/UserDetails/UserDetailsProps.d.ts +151 -0
  158. package/dist/Components/UserDetails/UserDetailsProps.js +2 -0
  159. package/dist/Theme/index.d.ts +4 -4
  160. package/dist/Theme/index.js +4 -4
  161. package/dist/Utils/table.d.ts +6 -1
  162. package/dist/Utils/table.js +47 -27
  163. package/dist/index.d.ts +23 -1
  164. package/dist/index.js +37 -2
  165. package/package.json +1 -1
@@ -62,14 +62,45 @@ var StatusCell = function (_a) {
62
62
  var EMPTY_SX = {};
63
63
  var EMPTY_HOVER = {};
64
64
  var TableRow = react_2.default.memo(function (_a) {
65
- var _b, _c, _d, _e, _f, _g, _h, _j, _k, _l;
66
- var row = _a.row, rowIndex = _a.rowIndex, index = _a.index, isChecked = _a.isChecked, isExpanded = _a.isExpanded, isContent = _a.isContent, isLink = _a.isLink, isCheckbox = _a.isCheckbox, isLoading = _a.isLoading, isActionFreeze = _a.isActionFreeze, columns = _a.columns, leftOffsets = _a.leftOffsets, noBorders = _a.noBorders, freezedBgColor = _a.freezedBgColor, freezedTextColor = _a.freezedTextColor, theme = _a.theme, borderStyle = _a.borderStyle, hoverStyle = _a.hoverStyle, rowHeight = _a.rowHeight, cellPy = _a.cellPy, palette = _a.palette, accentColor = _a.accentColor, handleCheckbox = _a.handleCheckbox, onRowClick = _a.onRowClick, toggleRowExpansion = _a.toggleRowExpansion;
67
- var checkedSx = (0, react_2.useMemo)(function () {
68
- var _a, _b, _c;
69
- return isChecked ? {
70
- "& td": { backgroundColor: (_c = (_b = (_a = theme.colors.primary) === null || _a === void 0 ? void 0 : _a.opacity) === null || _b === void 0 ? void 0 : _b[16]) !== null && _c !== void 0 ? _c : theme.colors.disabled[100] },
71
- } : EMPTY_SX;
72
- }, [isChecked, (_b = theme.colors.primary) === null || _b === void 0 ? void 0 : _b.opacity, theme.colors.disabled]);
65
+ var _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u;
66
+ var row = _a.row, rowIndex = _a.rowIndex, index = _a.index, isChecked = _a.isChecked, isExpanded = _a.isExpanded, isContent = _a.isContent, isLink = _a.isLink, isCheckbox = _a.isCheckbox, isLoading = _a.isLoading, isActionFreeze = _a.isActionFreeze, columns = _a.columns, leftOffsets = _a.leftOffsets, noBorders = _a.noBorders, freezedBgColor = _a.freezedBgColor, freezedTextColor = _a.freezedTextColor, theme = _a.theme, borderStyle = _a.borderStyle, hoverStyle = _a.hoverStyle, rowHeight = _a.rowHeight, cellPy = _a.cellPy, palette = _a.palette, accentColor = _a.accentColor, handleCheckbox = _a.handleCheckbox, onRowClick = _a.onRowClick, toggleRowExpansion = _a.toggleRowExpansion, onMeasure = _a.onMeasure;
67
+ // Selected-row tint applied per-cell (NOT a blanket `& td` override) so status
68
+ // cells keep their solid color + white text instead of white-on-tint.
69
+ var selectedBg = (_d = (_c = (_b = theme.colors.primary) === null || _b === void 0 ? void 0 : _b.opacity) === null || _c === void 0 ? void 0 : _c[16]) !== null && _d !== void 0 ? _d : (_e = theme.colors.disabled) === null || _e === void 0 ? void 0 : _e[100];
70
+ // Sticky/frozen cells overlay scrolling content, so their selected background
71
+ // must be OPAQUE — paint the (translucent) tint over an opaque base.
72
+ var selectedFrozenBg = "linear-gradient(0deg, ".concat(selectedBg, ", ").concat(selectedBg, "), ").concat((_h = (_g = (_f = theme.colors) === null || _f === void 0 ? void 0 : _f.background) === null || _g === void 0 ? void 0 : _g[50]) !== null && _h !== void 0 ? _h : "#fff");
73
+ // Measured-height virtualization: report this row's real height (main + any
74
+ // expanded panel) so the windower can place variable/expandable rows exactly.
75
+ var mainRowRef = (0, react_2.useRef)(null);
76
+ var expandedRowRef = (0, react_2.useRef)(null);
77
+ var hasContent = !!row.content;
78
+ (0, react_2.useLayoutEffect)(function () {
79
+ if (!onMeasure)
80
+ return;
81
+ var measure = function () {
82
+ var _a, _b, _c, _d;
83
+ var main = (_b = (_a = mainRowRef.current) === null || _a === void 0 ? void 0 : _a.offsetHeight) !== null && _b !== void 0 ? _b : 0;
84
+ var exp = isExpanded && hasContent ? (_d = (_c = expandedRowRef.current) === null || _c === void 0 ? void 0 : _c.offsetHeight) !== null && _d !== void 0 ? _d : 0 : 0;
85
+ var h = main + exp;
86
+ if (h > 0)
87
+ onMeasure(row.id, h);
88
+ };
89
+ measure();
90
+ var raf = requestAnimationFrame(measure);
91
+ var ro;
92
+ if (typeof ResizeObserver !== "undefined") {
93
+ ro = new ResizeObserver(measure);
94
+ if (mainRowRef.current)
95
+ ro.observe(mainRowRef.current);
96
+ if (expandedRowRef.current)
97
+ ro.observe(expandedRowRef.current);
98
+ }
99
+ return function () {
100
+ cancelAnimationFrame(raf);
101
+ ro === null || ro === void 0 ? void 0 : ro.disconnect();
102
+ };
103
+ }, [onMeasure, isExpanded, hasContent, row.id]);
73
104
  var handleCellClick = (0, react_2.useCallback)(function (header) {
74
105
  if (!header.node && onRowClick) {
75
106
  onRowClick(row, { label: header.label, id: header.id });
@@ -77,10 +108,13 @@ var TableRow = react_2.default.memo(function (_a) {
77
108
  }, [row, onRowClick]);
78
109
  var firstDataColIndex = columns.findIndex(function (c) { return !c.isHidden; });
79
110
  var accentSx = accentColor ? "inset 3px 0 0 ".concat(accentColor) : undefined;
111
+ // Pinned/frozen columns get a tinted, opaque background so the frozen pane reads
112
+ // as one piece with its header (and so sticky cells cover scrolling content).
113
+ var frozenCellBg = (_m = freezedBgColor !== null && freezedBgColor !== void 0 ? freezedBgColor : (_l = (_k = (_j = theme.colors) === null || _j === void 0 ? void 0 : _j.table) === null || _k === void 0 ? void 0 : _k.hover) === null || _l === void 0 ? void 0 : _l[100]) !== null && _m !== void 0 ? _m : (_p = (_o = theme.colors) === null || _o === void 0 ? void 0 : _o.background) === null || _p === void 0 ? void 0 : _p[100];
80
114
  return (react_2.default.createElement(react_2.default.Fragment, null,
81
- react_2.default.createElement(react_1.Tr, { opacity: isLoading ? 0.4 : 1, pointerEvents: isLoading ? "none" : "auto", transition: "opacity 0.2s", sx: checkedSx },
82
- isContent && (react_2.default.createElement(react_1.Td, { w: "6", p: 0, fontSize: 14, backgroundColor: (_d = (_c = theme.colors) === null || _c === void 0 ? void 0 : _c.background) === null || _d === void 0 ? void 0 : _d[50], color: freezedTextColor, position: "sticky", borderBottom: borderStyle, boxShadow: accentSx, boxSizing: "border-box", left: 0, zIndex: 1, className: "columns sticky-columns" }, !!(row === null || row === void 0 ? void 0 : row.content) && (react_2.default.createElement(react_1.IconButton, { "aria-label": isExpanded ? "Collapse row" : "Expand row", color: (_e = theme.colors) === null || _e === void 0 ? void 0 : _e.gray[600], icon: isExpanded ? (react_2.default.createElement(lucide_react_1.ChevronDown, { fontSize: 16 })) : (react_2.default.createElement(lucide_react_1.ChevronRight, { fontSize: 16 })), _hover: { transform: "scale(1.1)" }, size: "sm", onClick: function () { return toggleRowExpansion(rowIndex); }, variant: "ghost" })))),
83
- isCheckbox && (react_2.default.createElement(react_1.Td, { w: "6", fontSize: 14, fontWeight: 600, color: (_g = (_f = theme.colors) === null || _f === void 0 ? void 0 : _f.background) === null || _g === void 0 ? void 0 : _g[50], textTransform: "capitalize", backgroundColor: (_j = (_h = theme.colors) === null || _h === void 0 ? void 0 : _h.background) === null || _j === void 0 ? void 0 : _j[50], position: "sticky", borderBottom: borderStyle, boxShadow: !isContent ? accentSx : undefined, boxSizing: "border-box", left: 0, zIndex: 1, className: "columns sticky-columns" },
115
+ react_2.default.createElement(react_1.Tr, { ref: mainRowRef, opacity: isLoading ? 0.4 : 1, pointerEvents: isLoading ? "none" : "auto", transition: "opacity 0.2s" },
116
+ isContent && (react_2.default.createElement(react_1.Td, { w: "6", p: 0, fontSize: 14, background: isChecked ? selectedFrozenBg : frozenCellBg, color: freezedTextColor, position: "sticky", borderBottom: borderStyle, boxShadow: accentSx, boxSizing: "border-box", left: 0, zIndex: 1, className: "columns sticky-columns" }, !!(row === null || row === void 0 ? void 0 : row.content) && (react_2.default.createElement(react_1.IconButton, { "aria-label": isExpanded ? "Collapse row" : "Expand row", color: (_q = theme.colors) === null || _q === void 0 ? void 0 : _q.gray[600], icon: isExpanded ? (react_2.default.createElement(lucide_react_1.ChevronDown, { fontSize: 16 })) : (react_2.default.createElement(lucide_react_1.ChevronRight, { fontSize: 16 })), _hover: { transform: "scale(1.1)" }, size: "sm", onClick: function () { return toggleRowExpansion(rowIndex); }, variant: "ghost" })))),
117
+ isCheckbox && (react_2.default.createElement(react_1.Td, { w: "6", fontSize: 14, fontWeight: 600, color: (_s = (_r = theme.colors) === null || _r === void 0 ? void 0 : _r.background) === null || _s === void 0 ? void 0 : _s[50], textTransform: "capitalize", background: isChecked ? selectedFrozenBg : frozenCellBg, position: "sticky", borderBottom: borderStyle, boxShadow: !isContent ? accentSx : undefined, boxSizing: "border-box", left: 0, zIndex: 1, className: "columns sticky-columns" },
84
118
  react_2.default.createElement(Checkbox_1.default, { "aria-label": "Select all rows", onChange: function () { return handleCheckbox(row.id); }, isChecked: isChecked }))),
85
119
  columns.map(function (header, headerIndex) {
86
120
  var _a, _b, _c, _d, _e, _f, _g;
@@ -93,7 +127,7 @@ var TableRow = react_2.default.memo(function (_a) {
93
127
  var statusColor = isStatus
94
128
  ? (0, table_1.pickTableColor)(rawStatus, palette, (_b = header.statusColors) === null || _b === void 0 ? void 0 : _b[rawStatus])
95
129
  : null;
96
- return (react_2.default.createElement(react_1.Td, { maxWidth: 500, minWidth: 120, height: "".concat(rowHeight, "px"), py: isStatus && statusColor ? 0 : cellPy, px: isStatus && statusColor ? 0 : undefined, key: headerIndex + 1, onClick: function () { return handleCellClick(header); }, fontSize: 14, fontWeight: 400, position: isFrozen ? "sticky" : undefined, left: isFrozen ? leftOffsets[headerIndex] : undefined, zIndex: isFrozen ? 1 : 0, backgroundColor: isStatus && statusColor ? statusColor.solid : (_c = theme.colors.background) === null || _c === void 0 ? void 0 : _c[50], textOverflow: "ellipsis", boxShadow: isFirstDataCell ? accentSx : undefined, borderBottom: noBorders
130
+ return (react_2.default.createElement(react_1.Td, { maxWidth: 500, minWidth: 120, height: "".concat(rowHeight, "px"), py: isStatus && statusColor ? 0 : cellPy, px: isStatus && statusColor ? 0 : undefined, key: headerIndex + 1, onClick: function () { return handleCellClick(header); }, fontSize: 14, fontWeight: 400, position: isFrozen ? "sticky" : undefined, left: isFrozen ? leftOffsets[headerIndex] : undefined, zIndex: isFrozen ? 1 : 0, background: isStatus && statusColor ? statusColor.solid : isChecked ? (isFrozen ? selectedFrozenBg : selectedBg) : isFrozen ? frozenCellBg : (_c = theme.colors.background) === null || _c === void 0 ? void 0 : _c[50], textOverflow: "ellipsis", boxShadow: isFirstDataCell ? accentSx : undefined, borderBottom: noBorders
97
131
  ? "none"
98
132
  : "0.063rem solid ".concat((_d = theme.colors) === null || _d === void 0 ? void 0 : _d.gray[isFrozen || isChecked ? 300 : 200]), className: "columns ".concat(isFrozen ? "sticky-columns" : "scrollable-columns"), boxSizing: "border-box", color: isStatus && statusColor ? "white" : (_f = (_e = theme.colors) === null || _e === void 0 ? void 0 : _e.text) === null || _f === void 0 ? void 0 : _f[500], _hover: isStatus && statusColor
99
133
  ? EMPTY_HOVER
@@ -101,8 +135,8 @@ var TableRow = react_2.default.memo(function (_a) {
101
135
  ? EMPTY_HOVER
102
136
  : hoverStyle }, isStatus && statusColor ? (react_2.default.createElement(StatusCell, { value: (0, table_1.normalizeTableCellValue)(row[header.id]) })) : (react_2.default.createElement(react_1.Box, { display: "block", overflow: "hidden", whiteSpace: "normal", overflowWrap: "break-word" }, (0, table_1.normalizeTableCellValue)(header.node ? header.node(row) : row[header.id])))));
103
137
  }),
104
- isLink && (react_2.default.createElement(react_1.Td, { w: 2, p: 0, fontSize: 14, backgroundColor: (_l = (_k = theme === null || theme === void 0 ? void 0 : theme.colors) === null || _k === void 0 ? void 0 : _k.background) === null || _l === void 0 ? void 0 : _l[50], color: freezedTextColor, position: isActionFreeze ? "sticky" : "relative", borderBottom: borderStyle, boxSizing: "border-box", right: 0, zIndex: 1, className: "columns sticky-columns".concat(isActionFreeze ? "-right" : "") }, (row.onLink || row.onEdit || row.onDelete) && (react_2.default.createElement(TableActions_1.default, { row: row }))))),
105
- row.content && isExpanded && (react_2.default.createElement(react_1.Tr, null,
138
+ isLink && (react_2.default.createElement(react_1.Td, { w: 2, p: 0, fontSize: 14, background: isChecked ? (isActionFreeze ? selectedFrozenBg : selectedBg) : isActionFreeze ? frozenCellBg : (_u = (_t = theme === null || theme === void 0 ? void 0 : theme.colors) === null || _t === void 0 ? void 0 : _t.background) === null || _u === void 0 ? void 0 : _u[50], color: freezedTextColor, position: isActionFreeze ? "sticky" : "relative", borderBottom: borderStyle, boxSizing: "border-box", right: 0, zIndex: 1, className: "columns sticky-columns".concat(isActionFreeze ? "-right" : "") }, (row.onLink || row.onEdit || row.onDelete) && (react_2.default.createElement(TableActions_1.default, { row: row }))))),
139
+ row.content && isExpanded && (react_2.default.createElement(react_1.Tr, { ref: expandedRowRef },
106
140
  react_2.default.createElement(react_1.Td, { colSpan: columns.length +
107
141
  (isCheckbox ? 1 : 0) +
108
142
  (isContent ? 1 : 0) +
@@ -135,19 +169,32 @@ var TableBody = function (_a) {
135
169
  // remaining height with empty spacer rows. Spacer rows (rather than CSS
136
170
  // transforms) keep the table in normal flow so the sticky header and
137
171
  // `position: sticky` frozen columns keep working.
138
- // Disabled when expandable content rows are present, since those break the
139
- // fixed-height assumption.
172
+ // Expandable `content` rows are supported via measured heights (see
173
+ // `measuredHeights` / `onMeasure` below) — each rendered row reports its real
174
+ // height, so the window places variable/expanded rows exactly.
140
175
  var ROW_HEIGHT = rowHeight;
141
176
  var GROUP_HEADER_H = 42;
142
177
  var OVERSCAN = 6;
143
178
  var VIRTUALIZE_THRESHOLD = 30;
144
- var shouldVirtualize = !isContent && data.length > VIRTUALIZE_THRESHOLD;
179
+ var ESTIMATED_EXPAND = 120; // assumed extra height for an expanded-but-not-yet-measured row
180
+ var shouldVirtualize = data.length > VIRTUALIZE_THRESHOLD;
145
181
  // Grouped mode has no pager, so it virtualizes too (when no expandable rows):
146
182
  // group headers + rows form one flat sequence that we window over.
147
183
  var groupRowCount = groups ? groups.reduce(function (n, g) { return n + g.rows.length; }, 0) : 0;
148
184
  var groupVirtualize = !!groups && !isContent && groupRowCount > VIRTUALIZE_THRESHOLD;
149
185
  var _w = (0, react_2.useState)(0), scrollTop = _w[0], setScrollTop = _w[1];
150
186
  var _x = (0, react_2.useState)(0), viewportH = _x[0], setViewportH = _x[1];
187
+ // Measured row heights keyed by row id (stable across scroll/paging).
188
+ var _y = (0, react_2.useState)(new Map()), measuredHeights = _y[0], setMeasuredHeights = _y[1];
189
+ var reportHeight = (0, react_2.useCallback)(function (id, h) {
190
+ setMeasuredHeights(function (prev) {
191
+ if (prev.get(id) === h)
192
+ return prev;
193
+ var next = new Map(prev);
194
+ next.set(id, h);
195
+ return next;
196
+ });
197
+ }, []);
151
198
  (0, react_2.useEffect)(function () {
152
199
  var el = scrollContainerRef === null || scrollContainerRef === void 0 ? void 0 : scrollContainerRef.current;
153
200
  if (!el || !(shouldVirtualize || groupVirtualize))
@@ -175,15 +222,37 @@ var TableBody = function (_a) {
175
222
  var total = data.length;
176
223
  var firstIndex = 0;
177
224
  var lastIndex = total;
225
+ var topPad = 0;
226
+ var bottomPad = 0;
178
227
  if (shouldVirtualize) {
179
228
  var vh = viewportH || 500;
180
- firstIndex = Math.max(0, Math.floor(scrollTop / ROW_HEIGHT) - OVERSCAN);
181
- var count = Math.ceil(vh / ROW_HEIGHT) + OVERSCAN * 2;
182
- lastIndex = Math.min(total, firstIndex + count);
229
+ // Prefix-sum offsets using measured heights (exact for rendered rows) and
230
+ // estimates for not-yet-measured rows (ROW_HEIGHT, + ESTIMATED_EXPAND if expanded).
231
+ var offsets = new Array(total + 1);
232
+ offsets[0] = 0;
233
+ for (var i = 0; i < total; i++) {
234
+ var id = data[i].id;
235
+ var measured = measuredHeights.get(id);
236
+ var h = measured != null
237
+ ? measured
238
+ : ROW_HEIGHT + (expandedRows.has(startRow + i) ? ESTIMATED_EXPAND : 0);
239
+ offsets[i + 1] = offsets[i] + h;
240
+ }
241
+ var totalH = offsets[total];
242
+ var top_1 = scrollTop - OVERSCAN * ROW_HEIGHT;
243
+ var bottom = scrollTop + vh + OVERSCAN * ROW_HEIGHT;
244
+ firstIndex = 0;
245
+ while (firstIndex < total && offsets[firstIndex + 1] <= top_1)
246
+ firstIndex++;
247
+ lastIndex = firstIndex;
248
+ while (lastIndex < total && offsets[lastIndex] < bottom)
249
+ lastIndex++;
250
+ if (lastIndex < firstIndex)
251
+ lastIndex = firstIndex;
252
+ topPad = offsets[firstIndex];
253
+ bottomPad = totalH - offsets[lastIndex];
183
254
  }
184
255
  var visibleRows = shouldVirtualize ? data.slice(firstIndex, lastIndex) : data;
185
- var topPad = firstIndex * ROW_HEIGHT;
186
- var bottomPad = (total - lastIndex) * ROW_HEIGHT;
187
256
  var toggleRowExpansion = (0, react_2.useCallback)(function (rowIndex) {
188
257
  setExpandedRows(function (prev) {
189
258
  var newSet = new Set(prev);
@@ -235,8 +304,8 @@ var TableBody = function (_a) {
235
304
  var g = groups_1[_i];
236
305
  items.push({ kind: "header", g: g });
237
306
  if (!collapsedGroups.has(g.value)) {
238
- for (var _y = 0, _z = g.rows; _y < _z.length; _y++) {
239
- var row = _z[_y];
307
+ for (var _z = 0, _0 = g.rows; _z < _0.length; _z++) {
308
+ var row = _0[_z];
240
309
  items.push({ kind: "row", g: g, row: row });
241
310
  }
242
311
  }
@@ -249,16 +318,16 @@ var TableBody = function (_a) {
249
318
  var heights_2 = items.map(function (it) { return (it.kind === "header" ? GROUP_HEADER_H : rowHeight); });
250
319
  var offsets_1 = [];
251
320
  var acc = 0;
252
- for (var _0 = 0, heights_1 = heights_2; _0 < heights_1.length; _0++) {
253
- var h = heights_1[_0];
321
+ for (var _1 = 0, heights_1 = heights_2; _1 < heights_1.length; _1++) {
322
+ var h = heights_1[_1];
254
323
  offsets_1.push(acc);
255
324
  acc += h;
256
325
  }
257
326
  var totalH = acc;
258
327
  var vh = viewportH || 500;
259
- var top_1 = scrollTop - OVERSCAN * rowHeight;
328
+ var top_2 = scrollTop - OVERSCAN * rowHeight;
260
329
  var bottom = scrollTop + vh + OVERSCAN * rowHeight;
261
- firstI_1 = items.findIndex(function (_, i) { return offsets_1[i] + heights_2[i] > top_1; });
330
+ firstI_1 = items.findIndex(function (_, i) { return offsets_1[i] + heights_2[i] > top_2; });
262
331
  if (firstI_1 < 0)
263
332
  firstI_1 = items.length;
264
333
  lastI = items.length;
@@ -295,7 +364,7 @@ var TableBody = function (_a) {
295
364
  var rowIndex = startRow + index;
296
365
  var isExpanded = expandedRows.has(rowIndex);
297
366
  var isChecked = selectionsSet.has(row.id);
298
- return (react_2.default.createElement(TableRow, { key: (_a = row.id) !== null && _a !== void 0 ? _a : rowIndex, row: row, rowIndex: rowIndex, index: index, isChecked: isChecked, isExpanded: isExpanded, isContent: isContent, isLink: isLink, isCheckbox: isCheckbox, isLoading: isLoading, isActionFreeze: isActionFreeze, columns: columns, leftOffsets: leftOffsets, noBorders: noBorders, freezedBgColor: freezedBgColor, freezedTextColor: freezedTextColor, theme: theme, borderStyle: borderStyle, hoverStyle: hoverStyle, rowHeight: rowHeight, cellPy: cellPy, palette: palette, accentColor: accentColors === null || accentColors === void 0 ? void 0 : accentColors[row.id], handleCheckbox: handleCheckbox, onRowClick: onRowClick, toggleRowExpansion: toggleRowExpansion }));
367
+ return (react_2.default.createElement(TableRow, { key: (_a = row.id) !== null && _a !== void 0 ? _a : rowIndex, row: row, rowIndex: rowIndex, index: index, isChecked: isChecked, isExpanded: isExpanded, isContent: isContent, isLink: isLink, isCheckbox: isCheckbox, isLoading: isLoading, isActionFreeze: isActionFreeze, columns: columns, leftOffsets: leftOffsets, noBorders: noBorders, freezedBgColor: freezedBgColor, freezedTextColor: freezedTextColor, theme: theme, borderStyle: borderStyle, hoverStyle: hoverStyle, rowHeight: rowHeight, cellPy: cellPy, palette: palette, accentColor: accentColors === null || accentColors === void 0 ? void 0 : accentColors[row.id], handleCheckbox: handleCheckbox, onRowClick: onRowClick, toggleRowExpansion: toggleRowExpansion, onMeasure: shouldVirtualize ? reportHeight : undefined }));
299
368
  }),
300
369
  shouldVirtualize && bottomPad > 0 && (react_2.default.createElement("tr", { "aria-hidden": "true", style: { height: bottomPad } },
301
370
  react_2.default.createElement("td", { colSpan: totalVisibleColumns, style: { padding: 0, border: "none", height: bottomPad } })))));
@@ -70,19 +70,29 @@ var Harness = function (_a) {
70
70
  react_1.default.createElement(react_3.Tbody, null,
71
71
  react_1.default.createElement(TableBody_1.default, { data: makeData(count), columns: columns, startRow: 0, endRow: count, columnWidths: [120], isCheckbox: false, isContent: false, isLink: false, isActionFreeze: false, noBorders: false, selections: [], handleCheckbox: function () { }, scrollContainerRef: ref }))))));
72
72
  };
73
+ // Windowing math (normal density): ROW_HEIGHT=40, OVERSCAN=6, viewport falls
74
+ // back to 500px (jsdom clientHeight=0). Rows are unmeasured in jsdom, so every
75
+ // row is estimated at 40px. bottom = 0 + 500 + 6*40 = 740 -> last rendered row
76
+ // is the highest index with offset < 740 -> index 18 (offsets[18]=720). So rows
77
+ // 0..18 (19 rows) render and the trailing spacer reserves (100-19)*40 px.
78
+ var ROW_HEIGHT = 40;
79
+ var VISIBLE_COUNT = 19;
80
+ var LAST_VISIBLE = VISIBLE_COUNT - 1;
73
81
  describe("TableBody virtualization", function () {
74
82
  it("windows large pages and reserves height with spacer rows", function () {
75
83
  var _a = (0, react_2.render)(react_1.default.createElement(Harness, { count: 100 })), container = _a.container, queryByText = _a.queryByText;
76
- // jsdom clientHeight=0 -> 500px fallback -> ceil(500/45)+12 = 24 rows
77
84
  expect(queryByText("Row 0")).toBeInTheDocument();
78
- expect(queryByText("Row 23")).toBeInTheDocument();
85
+ expect(queryByText("Row ".concat(LAST_VISIBLE))).toBeInTheDocument();
79
86
  // Rows beyond the window are not mounted.
87
+ expect(queryByText("Row ".concat(LAST_VISIBLE + 1))).not.toBeInTheDocument();
80
88
  expect(queryByText("Row 50")).not.toBeInTheDocument();
81
89
  expect(queryByText("Row 99")).not.toBeInTheDocument();
82
90
  // A trailing spacer reserves the height of the unrendered rows.
83
91
  var spacers = container.querySelectorAll('tr[aria-hidden="true"]');
84
92
  expect(spacers.length).toBe(1);
85
- expect(spacers[0]).toHaveStyle({ height: "".concat((100 - 24) * 45, "px") });
93
+ expect(spacers[0]).toHaveStyle({
94
+ height: "".concat((100 - VISIBLE_COUNT) * ROW_HEIGHT, "px"),
95
+ });
86
96
  });
87
97
  it("renders every row and no spacers below the threshold", function () {
88
98
  var _a = (0, react_2.render)(react_1.default.createElement(Harness, { count: 30 })), container = _a.container, queryByText = _a.queryByText;
@@ -1,4 +1,4 @@
1
1
  import React from "react";
2
2
  import { TableHeaderPageProps } from "../TableProps";
3
- declare const _default: React.MemoExoticComponent<({ columns, isCheckbox, handleSort, headerRefs, columnWidths, columnsSort, headerBgColor, headerTextColor, freezedBgColor, freezedTextColor, noBorders, handleCheckbox, checked, isLoading, isContent, isLink, isActionFreeze, setColumnsSearch, columnsSearch, isSelecting, }: TableHeaderPageProps) => React.JSX.Element>;
3
+ declare const _default: React.MemoExoticComponent<({ columns, isCheckbox, handleSort, headerRefs, columnWidths, columnsSort, headerBgColor, freezedBgColor, freezedTextColor, noBorders, handleCheckbox, checked, isLoading, isContent, isLink, isActionFreeze, setColumnsSearch, columnsSearch, isSelecting, }: TableHeaderPageProps) => React.JSX.Element>;
4
4
  export default _default;
@@ -55,12 +55,12 @@ var TableFilters_1 = __importDefault(require("../filters/TableFilters"));
55
55
  var lucide_react_1 = require("lucide-react");
56
56
  var Checkbox_1 = __importDefault(require("../../Checkbox/Checkbox"));
57
57
  var TableHeader = function (_a) {
58
- var columns = _a.columns, isCheckbox = _a.isCheckbox, handleSort = _a.handleSort, headerRefs = _a.headerRefs, columnWidths = _a.columnWidths, columnsSort = _a.columnsSort, headerBgColor = _a.headerBgColor, headerTextColor = _a.headerTextColor, freezedBgColor = _a.freezedBgColor, freezedTextColor = _a.freezedTextColor, noBorders = _a.noBorders, handleCheckbox = _a.handleCheckbox, checked = _a.checked, isLoading = _a.isLoading, isContent = _a.isContent, isLink = _a.isLink, isActionFreeze = _a.isActionFreeze, setColumnsSearch = _a.setColumnsSearch, columnsSearch = _a.columnsSearch, isSelecting = _a.isSelecting;
58
+ var columns = _a.columns, isCheckbox = _a.isCheckbox, handleSort = _a.handleSort, headerRefs = _a.headerRefs, columnWidths = _a.columnWidths, columnsSort = _a.columnsSort, headerBgColor = _a.headerBgColor, freezedBgColor = _a.freezedBgColor, freezedTextColor = _a.freezedTextColor, noBorders = _a.noBorders, handleCheckbox = _a.handleCheckbox, checked = _a.checked, isLoading = _a.isLoading, isContent = _a.isContent, isLink = _a.isLink, isActionFreeze = _a.isActionFreeze, setColumnsSearch = _a.setColumnsSearch, columnsSearch = _a.columnsSearch, isSelecting = _a.isSelecting;
59
59
  var theme = (0, useCustomTheme_1.useCustomTheme)();
60
60
  var _b = (0, react_2.useState)(null), openFilterId = _b[0], setOpenFilterId = _b[1];
61
61
  var RenderCheckbox = (0, react_2.useCallback)(function () {
62
- var _a, _b, _c, _d;
63
- return (react_2.default.createElement(react_1.Th, { w: 6, fontSize: 14, fontWeight: 600, color: freezedTextColor, textTransform: "capitalize", backgroundColor: (_b = (_a = theme.colors) === null || _a === void 0 ? void 0 : _a.secondary) === null || _b === void 0 ? void 0 : _b[50], position: "sticky", className: "columns sticky-columns", left: "0px", zIndex: 9 }, isSelecting ? (react_2.default.createElement(react_1.Spinner, { size: "sm", color: (_d = (_c = theme.colors) === null || _c === void 0 ? void 0 : _c.primary) === null || _d === void 0 ? void 0 : _d[500] })) : (react_2.default.createElement(Checkbox_1.default, { "aria-label": "Select all rows", variant: "outline", onChange: function () { return handleCheckbox(0); }, isChecked: isLoading ? false : checked === true, isIndeterminate: checked === "indeterminate" }))));
62
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j;
63
+ return (react_2.default.createElement(react_1.Th, { w: 6, fontSize: 14, fontWeight: 600, color: freezedTextColor, textTransform: "capitalize", backgroundColor: (_d = (_c = (_b = (_a = theme.colors) === null || _a === void 0 ? void 0 : _a.table) === null || _b === void 0 ? void 0 : _b.hover) === null || _c === void 0 ? void 0 : _c[200]) !== null && _d !== void 0 ? _d : (_f = (_e = theme.colors) === null || _e === void 0 ? void 0 : _e.secondary) === null || _f === void 0 ? void 0 : _f[50], position: "sticky", className: "columns sticky-columns", left: "0px", zIndex: 9, borderBottom: noBorders ? "none" : "0.063rem solid ".concat((_g = theme.colors) === null || _g === void 0 ? void 0 : _g.gray[300]) }, isSelecting ? (react_2.default.createElement(react_1.Spinner, { size: "sm", color: (_j = (_h = theme.colors) === null || _h === void 0 ? void 0 : _h.primary) === null || _j === void 0 ? void 0 : _j[500] })) : (react_2.default.createElement(Checkbox_1.default, { "aria-label": "Select all rows", variant: "outline", onChange: function () { return handleCheckbox(0); }, isChecked: isLoading ? false : checked === true, isIndeterminate: checked === "indeterminate" }))));
64
64
  }, [
65
65
  checked,
66
66
  freezedTextColor,
@@ -71,16 +71,12 @@ var TableHeader = function (_a) {
71
71
  theme.colors,
72
72
  ]);
73
73
  var RenderConent = (0, react_2.useCallback)(function () {
74
- var _a, _b, _c;
75
- return (react_2.default.createElement(react_1.Th, { w: 6, minW: "35px", p: 0, backgroundColor: (_b = (_a = theme.colors) === null || _a === void 0 ? void 0 : _a.secondary) === null || _b === void 0 ? void 0 : _b[50], borderY: noBorders ? "none" : "0.063rem solid ".concat((_c = theme.colors) === null || _c === void 0 ? void 0 : _c.gray[300]), position: "sticky", className: "columns sticky-columns", left: "0px", zIndex: 1, boxShadow: theme.shadows.md }));
74
+ var _a, _b, _c, _d, _e, _f, _g;
75
+ return (react_2.default.createElement(react_1.Th, { w: 6, minW: "35px", p: 0, backgroundColor: (_d = (_c = (_b = (_a = theme.colors) === null || _a === void 0 ? void 0 : _a.table) === null || _b === void 0 ? void 0 : _b.hover) === null || _c === void 0 ? void 0 : _c[200]) !== null && _d !== void 0 ? _d : (_f = (_e = theme.colors) === null || _e === void 0 ? void 0 : _e.secondary) === null || _f === void 0 ? void 0 : _f[50], borderBottom: noBorders ? "none" : "0.063rem solid ".concat((_g = theme.colors) === null || _g === void 0 ? void 0 : _g.gray[300]), position: "sticky", className: "columns sticky-columns", left: "0px", zIndex: 1 }));
76
76
  }, [noBorders, theme.colors]);
77
77
  var RenderView = (0, react_2.useCallback)(function () {
78
- var _a, _b;
79
- return (react_2.default.createElement(react_1.Th, { w: 2, p: 0, minW: "2.065rem", backgroundColor: (_b = (_a = theme.colors) === null || _a === void 0 ? void 0 : _a.secondary) === null || _b === void 0 ? void 0 : _b[50],
80
- // borderY={
81
- // noBorders ? "none" : `0.063rem solid ${theme.colors?.gray[300]}`
82
- // }
83
- position: isActionFreeze ? "sticky" : "relative", className: "columns sticky-columns", right: "0px", zIndex: 1 }));
78
+ var _a, _b, _c, _d, _e, _f, _g;
79
+ return (react_2.default.createElement(react_1.Th, { w: 2, p: 0, minW: "2.065rem", backgroundColor: (_d = (_c = (_b = (_a = theme.colors) === null || _a === void 0 ? void 0 : _a.table) === null || _b === void 0 ? void 0 : _b.hover) === null || _c === void 0 ? void 0 : _c[200]) !== null && _d !== void 0 ? _d : (_f = (_e = theme.colors) === null || _e === void 0 ? void 0 : _e.secondary) === null || _f === void 0 ? void 0 : _f[50], borderBottom: noBorders ? "none" : "0.063rem solid ".concat((_g = theme.colors) === null || _g === void 0 ? void 0 : _g.gray[300]), position: isActionFreeze ? "sticky" : "relative", className: "columns sticky-columns", right: "0px", zIndex: 1 }));
84
80
  }, [noBorders, theme.colors, isActionFreeze]);
85
81
  return (react_2.default.createElement(react_1.Tr, { pr: 0 },
86
82
  isContent && react_2.default.createElement(RenderConent, null),
@@ -88,7 +84,7 @@ var TableHeader = function (_a) {
88
84
  columns.map(function (header, index) {
89
85
  if (header === null || header === void 0 ? void 0 : header.isHidden)
90
86
  return null;
91
- return (react_2.default.createElement(ColumnHeader, { header: header, index: index, key: header.label, columnWidths: columnWidths, handleSort: handleSort, isCheckbox: isCheckbox, headerBgColor: headerBgColor, headerTextColor: headerTextColor, freezedBgColor: freezedBgColor, freezedTextColor: freezedTextColor, noBorders: noBorders, columnsSort: columnsSort, headerRefs: headerRefs, columnsSearch: columnsSearch, setColumnsSearch: setColumnsSearch, openFilterId: openFilterId, setOpenFilterId: setOpenFilterId }));
87
+ return (react_2.default.createElement(ColumnHeader, { header: header, index: index, key: header.label, columnWidths: columnWidths, handleSort: handleSort, isCheckbox: isCheckbox, headerBgColor: headerBgColor, freezedBgColor: freezedBgColor, noBorders: noBorders, columnsSort: columnsSort, headerRefs: headerRefs, columnsSearch: columnsSearch, setColumnsSearch: setColumnsSearch, openFilterId: openFilterId, setOpenFilterId: setOpenFilterId }));
92
88
  }),
93
89
  isLink && react_2.default.createElement(RenderView, null)));
94
90
  };
@@ -104,7 +100,7 @@ var SortingIcon = (0, react_2.memo)(function (_a) {
104
100
  });
105
101
  var ColumnHeader = (0, react_2.memo)(function (_a) {
106
102
  var _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u;
107
- var header = _a.header, index = _a.index, columnWidths = _a.columnWidths, isCheckbox = _a.isCheckbox, headerTextColor = _a.headerTextColor, freezedTextColor = _a.freezedTextColor, noBorders = _a.noBorders, columnsSort = _a.columnsSort, headerRefs = _a.headerRefs, columnsSearch = _a.columnsSearch, setColumnsSearch = _a.setColumnsSearch, handleSort = _a.handleSort, openFilterId = _a.openFilterId, setOpenFilterId = _a.setOpenFilterId;
103
+ var header = _a.header, index = _a.index, columnWidths = _a.columnWidths, isCheckbox = _a.isCheckbox, noBorders = _a.noBorders, columnsSort = _a.columnsSort, headerRefs = _a.headerRefs, columnsSearch = _a.columnsSearch, setColumnsSearch = _a.setColumnsSearch, handleSort = _a.handleSort, openFilterId = _a.openFilterId, setOpenFilterId = _a.setOpenFilterId;
108
104
  var _v = (0, react_2.useState)(false), isHovered = _v[0], setIsHovered = _v[1];
109
105
  var theme = (0, useCustomTheme_1.useCustomTheme)();
110
106
  var isFrozen = header.isFreeze;
@@ -41,7 +41,8 @@ declare const useTable: ({ tableBorderColor, data, isPagination, selections, onS
41
41
  rowsPerPage: number;
42
42
  setCurrentPage: import("react").Dispatch<import("react").SetStateAction<number>>;
43
43
  columnsList: TableHeaderProps[];
44
- handleColumnPreferences: (columns: any) => void;
44
+ handleColumnPreferences: (columns: any, extra?: Record<string, any>) => void;
45
45
  isSelecting: boolean;
46
+ selectAllRowsRef: import("react").MutableRefObject<DataObject[] | null>;
46
47
  };
47
48
  export default useTable;
@@ -47,13 +47,13 @@ var useTable = function (_a) {
47
47
  var _f = (0, react_1.useState)([]), columnsSort = _f[0], setColumnsSort = _f[1];
48
48
  var _g = (0, react_1.useState)(0), currentPage = _g[0], setCurrentPage = _g[1];
49
49
  var _h = (0, react_1.useState)(noOfRowsPerPage !== null && noOfRowsPerPage !== void 0 ? noOfRowsPerPage : defaultPageSize), rowsPerPage = _h[0], setRowsPerPage = _h[1];
50
- var prevRowsPerPageProp = (0, react_1.useRef)(noOfRowsPerPage);
51
- if (noOfRowsPerPage !== prevRowsPerPageProp.current) {
52
- prevRowsPerPageProp.current = noOfRowsPerPage;
53
- if (noOfRowsPerPage !== undefined && noOfRowsPerPage !== rowsPerPage) {
50
+ // Keep the internal page size in sync with the `noOfRowsPerPage` prop when the
51
+ // consumer changes it (e.g. a page-size control outside the table).
52
+ (0, react_1.useEffect)(function () {
53
+ if (noOfRowsPerPage !== undefined) {
54
54
  setRowsPerPage(noOfRowsPerPage);
55
55
  }
56
- }
56
+ }, [noOfRowsPerPage]);
57
57
  var tableData = data;
58
58
  var _j = (0, react_1.useState)(function () {
59
59
  return columns.map(function (col, i) {
@@ -162,14 +162,26 @@ var useTable = function (_a) {
162
162
  selectionRef.current = selection;
163
163
  var onSelectionRef = (0, react_1.useRef)(onSelection);
164
164
  onSelectionRef.current = onSelection;
165
+ // Rows that "select all" should toggle. Defaults to `tableData`, but in grouped
166
+ // "load more" mode the parent points this at the accumulated/rendered rows so
167
+ // select-all covers everything on screen (not just the latest page).
168
+ var selectAllRowsRef = (0, react_1.useRef)(null);
165
169
  var handleCheckbox = (0, react_1.useCallback)(function (id) {
166
- var _a;
170
+ var _a, _b;
167
171
  var current = selectionRef.current;
168
172
  if (id === 0) {
173
+ var rows = (_a = selectAllRowsRef.current) !== null && _a !== void 0 ? _a : tableData;
174
+ var ids_1 = rows.map(function (item) { return item.id; });
175
+ var idSet_1 = new Set(ids_1);
176
+ var currentSet_1 = new Set(current);
177
+ var allSelected_1 = ids_1.length > 0 && ids_1.every(function (i) { return currentSet_1.has(i); });
169
178
  setIsSelecting(true);
170
179
  setTimeout(function () {
171
180
  var _a;
172
- var selectedItems = current.length === tableData.length ? [] : tableData.map(function (item) { return item.id; });
181
+ // Toggle the rendered rows while preserving any selection outside them.
182
+ var selectedItems = allSelected_1
183
+ ? current.filter(function (i) { return !idSet_1.has(i); })
184
+ : Array.from(new Set(__spreadArray(__spreadArray([], current, true), ids_1, true)));
173
185
  setSelection(selectedItems);
174
186
  (_a = onSelectionRef.current) === null || _a === void 0 ? void 0 : _a.call(onSelectionRef, selectedItems);
175
187
  setIsSelecting(false);
@@ -184,13 +196,14 @@ var useTable = function (_a) {
184
196
  selectedItems = __spreadArray(__spreadArray([], current, true), [id], false);
185
197
  }
186
198
  setSelection(selectedItems);
187
- (_a = onSelectionRef.current) === null || _a === void 0 ? void 0 : _a.call(onSelectionRef, selectedItems);
199
+ (_b = onSelectionRef.current) === null || _b === void 0 ? void 0 : _b.call(onSelectionRef, selectedItems);
188
200
  }
189
201
  }, [tableData]);
190
- var handleColumnPreferences = function (columns) {
202
+ var handleColumnPreferences = function (columns, extra) {
203
+ if (extra === void 0) { extra = {}; }
191
204
  setColumnsList(columns);
192
205
  savePreferences &&
193
- savePreferences(__assign(__assign({}, tablePreferences), { columns: columns }));
206
+ savePreferences(__assign(__assign(__assign({}, tablePreferences), { columns: columns }), extra));
194
207
  };
195
208
  return {
196
209
  tableData: tableData,
@@ -214,6 +227,7 @@ var useTable = function (_a) {
214
227
  columnsList: columnsList,
215
228
  handleColumnPreferences: handleColumnPreferences,
216
229
  isSelecting: isSelecting,
230
+ selectAllRowsRef: selectAllRowsRef,
217
231
  };
218
232
  };
219
233
  exports.default = useTable;
@@ -97,6 +97,7 @@ jest.mock("../../../Theme/useCustomTheme", function () { return ({
97
97
  },
98
98
  red: { 50: "#fee", 200: "#fcc", 600: "#c00" },
99
99
  border: { 200: "#e2e8f0" },
100
+ text: { 500: "#555", 700: "#333" },
100
101
  white: "#fff",
101
102
  },
102
103
  shadows: { sm: "0 1px 2px rgba(0,0,0,0.05)" },
@@ -1,10 +1,11 @@
1
1
  import React from "react";
2
2
  import { TableDensity, TableProps } from "../TableProps";
3
- declare const TableSettings: ({ columns, onSave, density, onDensityChange, }: {
3
+ declare const TableSettings: ({ columns, onSave, density, onDensityChange, groupBy, }: {
4
4
  columns: TableProps["columns"];
5
- onSave: (updatedColumns: TableProps["columns"]) => void;
5
+ onSave: (updatedColumns: TableProps["columns"], groupBy: string | number | undefined) => void;
6
6
  tableSettings?: TableProps["tableSettings"];
7
7
  density?: TableDensity;
8
8
  onDensityChange?: (d: TableDensity) => void;
9
+ groupBy?: string | number;
9
10
  }) => React.JSX.Element;
10
11
  export default TableSettings;
@@ -43,6 +43,15 @@ var __importStar = (this && this.__importStar) || (function () {
43
43
  return result;
44
44
  };
45
45
  })();
46
+ var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
47
+ if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
48
+ if (ar || !(i in from)) {
49
+ if (!ar) ar = Array.prototype.slice.call(from, 0, i);
50
+ ar[i] = from[i];
51
+ }
52
+ }
53
+ return to.concat(ar || Array.prototype.slice.call(from));
54
+ };
46
55
  var __importDefault = (this && this.__importDefault) || function (mod) {
47
56
  return (mod && mod.__esModule) ? mod : { "default": mod };
48
57
  };
@@ -62,20 +71,23 @@ var DENSITY_OPTIONS = [
62
71
  ];
63
72
  var TableSettings = function (_a) {
64
73
  var _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o;
65
- var columns = _a.columns, onSave = _a.onSave, _p = _a.density, density = _p === void 0 ? "normal" : _p, onDensityChange = _a.onDensityChange;
74
+ var columns = _a.columns, onSave = _a.onSave, _p = _a.density, density = _p === void 0 ? "normal" : _p, onDensityChange = _a.onDensityChange, groupBy = _a.groupBy;
66
75
  var theme = (0, useCustomTheme_1.useCustomTheme)();
67
76
  var childInputMethodsRef = (0, react_2.useRef)({});
68
77
  var _q = (0, react_2.useState)(false), settingsOpen = _q[0], setSettingsOpen = _q[1];
69
78
  var _r = (0, react_2.useState)(0), selectedIndex = _r[0], setSelectedIndex = _r[1];
70
79
  var _s = (0, react_2.useState)(columns), items = _s[0], setItems = _s[1];
80
+ // Group selection is applied on Save (not live), per "click Apply to group".
81
+ var _t = (0, react_2.useState)(groupBy), selectedGroup = _t[0], setSelectedGroup = _t[1];
71
82
  var handleSave = (0, react_2.useCallback)(function () {
72
- onSave(items);
83
+ onSave(items, selectedGroup);
73
84
  setSettingsOpen(false);
74
- }, [onSave, items]);
85
+ }, [onSave, items, selectedGroup]);
75
86
  var handleOpen = (0, react_2.useCallback)(function () {
76
87
  setItems(columns);
88
+ setSelectedGroup(groupBy);
77
89
  setSettingsOpen(true);
78
- }, [columns]);
90
+ }, [columns, groupBy]);
79
91
  var tabStyle = {
80
92
  fontSize: "13px",
81
93
  fontWeight: 500,
@@ -102,7 +114,8 @@ var TableSettings = function (_a) {
102
114
  react_2.default.createElement(react_1.Text, { fontWeight: 600, fontSize: "md", mb: 3 }, "Table Settings"),
103
115
  react_2.default.createElement(react_1.TabList, { gap: 0, borderBottom: "1px solid", borderColor: (_l = (_k = theme.colors) === null || _k === void 0 ? void 0 : _k.border) === null || _l === void 0 ? void 0 : _l[200] },
104
116
  react_2.default.createElement(react_1.Tab, __assign({}, tabStyle), "Density"),
105
- react_2.default.createElement(react_1.Tab, __assign({}, tabStyle), "Manage Columns"))),
117
+ react_2.default.createElement(react_1.Tab, __assign({}, tabStyle), "Manage Columns"),
118
+ react_2.default.createElement(react_1.Tab, __assign({}, tabStyle), "Group"))),
106
119
  react_2.default.createElement(react_1.ModalBody, { px: 4, py: 3, flex: "1", overflowY: "auto", sx: {
107
120
  "&::-webkit-scrollbar": { width: "3px", height: "3px" },
108
121
  "&::-webkit-scrollbar-track": { background: theme.colors.gray[100], borderRadius: "2px" },
@@ -133,7 +146,18 @@ var TableSettings = function (_a) {
133
146
  "& .chakra-checkbox__label": { fontSize: "13px !important" },
134
147
  "& [draggable]": { py: "5px !important" },
135
148
  } },
136
- react_2.default.createElement(ManageColumns_1.default, { columns: columns, items: items, setItems: setItems, childInputMethodsRef: childInputMethodsRef })))))),
149
+ react_2.default.createElement(ManageColumns_1.default, { columns: columns, items: items, setItems: setItems, childInputMethodsRef: childInputMethodsRef }))),
150
+ react_2.default.createElement(react_1.TabPanel, { px: 0, py: 1 },
151
+ react_2.default.createElement(react_1.Text, { fontSize: "12px", color: theme.colors.gray[500], mb: 2 }, "Group rows by a column. Click Save to apply."),
152
+ react_2.default.createElement(react_1.Flex, { direction: "column", gap: 2 }, __spreadArray([{ id: undefined, label: "None (no grouping)" }], columns
153
+ .filter(function (c) { return !!c.columnType && !c.isHidden; })
154
+ .map(function (c) { return ({ id: c.id, label: String(c.label) }); }), true).map(function (opt) {
155
+ var _a, _b;
156
+ var selected = selectedGroup === opt.id;
157
+ return (react_2.default.createElement(react_1.Flex, { as: "button", type: "button", key: String((_a = opt.id) !== null && _a !== void 0 ? _a : "__none__"), align: "center", gap: 3, px: 3, py: 2.5, borderRadius: "0.5rem", border: "1px solid", borderColor: selected ? theme.colors.primary[500] : (_b = theme.colors.boxborder) === null || _b === void 0 ? void 0 : _b[300], bg: selected ? theme.colors.primary.opacity[8] : "transparent", transition: "all 0.15s", _hover: { borderColor: theme.colors.primary[400] }, onClick: function () { return setSelectedGroup(opt.id); } },
158
+ react_2.default.createElement(react_1.Box, { boxSize: "1.1rem", borderRadius: "full", border: "2px solid", borderColor: selected ? theme.colors.primary[500] : theme.colors.gray[400], display: "flex", alignItems: "center", justifyContent: "center", flexShrink: 0 }, selected && react_2.default.createElement(lucide_react_1.Check, { size: 11, color: theme.colors.primary[500], strokeWidth: 3 })),
159
+ react_2.default.createElement(react_1.Text, { fontSize: "13px", fontWeight: 600, color: theme.colors.text[700], textAlign: "left" }, opt.label)));
160
+ })))))),
137
161
  react_2.default.createElement(react_1.ModalFooter, { gap: "0.5rem", borderTop: "1px solid", borderColor: (_o = (_m = theme.colors) === null || _m === void 0 ? void 0 : _m.border) === null || _o === void 0 ? void 0 : _o[200], pt: 3, pb: 3, px: 4 },
138
162
  react_2.default.createElement(Button_1.default, { label: "Close", size: "sm", onClick: function () { return setSettingsOpen(false); }, variant: "outline", colorScheme: "red" }),
139
163
  react_2.default.createElement(Button_1.default, { label: "Save", size: "sm", onClick: handleSave }))))));
@@ -1,4 +1,4 @@
1
1
  import React from "react";
2
2
  import { TimelineProps } from "./TimelineProps";
3
- declare const Timeline: ({ timelineEvents }: TimelineProps) => React.JSX.Element;
3
+ declare const Timeline: ({ timelineEvents, onEventClick }: TimelineProps) => React.JSX.Element;
4
4
  export default Timeline;