@pagamio/frontend-commons-lib 0.8.318 → 0.8.320
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.
- package/lib/pagamio-table/data-table/index.js +60 -10
- package/lib/styles.css +16 -5
- package/package.json +1 -1
|
@@ -104,29 +104,79 @@ function CustomToolbar({ filters, appliedFilters, onFilterChange, onApply, onCle
|
|
|
104
104
|
const PagamioTable = ({ columns, data, isLoading = false, rowCount, sorting, pagination, filtering, search, onRowClick, rowClassName, expandable = false, renderDetailPanel, toolbar, toolbarMode = 'custom', enableColumnResizing, enableColumnPinning, enableColumnOrdering, enableColumnFilters, enableHiding, enableRowSelection, enableRowActions, enableRowVirtualization, enableGrouping, enableEditing, enableDensityToggle, enableFullScreenToggle, enableClickToCopy, enableRowNumbers, enableMultiSort, enableStickyHeader, enableStickyFooter, editDisplayMode, onEditingRowSave, onEditingRowCancel, renderRowActions, renderRowActionMenuItems, positionActionsColumn, renderTopToolbarCustomActions, renderBottomToolbarCustomActions, layoutMode, defaultColumn, mantineTableOptions, }) => {
|
|
105
105
|
const [expanded, setExpanded] = useState({});
|
|
106
106
|
const tableRef = useRef(null);
|
|
107
|
+
// ── Internal max-height ─────────────────────────────────────────────
|
|
108
|
+
// The mantine table container is height-capped to `viewportHeight - tableTop`
|
|
109
|
+
// so that the table is the only scrolling element when its parent layout
|
|
110
|
+
// is fixed (page header + sidebar stay put). Without this, large datasets
|
|
111
|
+
// would push the page itself into a scroll, breaking the toolbar/header
|
|
112
|
+
// sticky behaviour that the rest of the app relies on.
|
|
113
|
+
//
|
|
114
|
+
// Bottom margin reserves space for the bottom toolbar (pagination, ~52px)
|
|
115
|
+
// plus a small gap so the table doesn't sit flush against page edges.
|
|
116
|
+
const TABLE_BOTTOM_MARGIN = 68;
|
|
117
|
+
/**
|
|
118
|
+
* Walk up the DOM looking for the closest scrollable ancestor (i.e. an
|
|
119
|
+
* element with overflow-y: auto/scroll AND scrollHeight > clientHeight).
|
|
120
|
+
* If we find one, the *page* is what's scrolling — we should NOT cap the
|
|
121
|
+
* table's height because that would create a confusing nested scroll
|
|
122
|
+
* (page scroll + table scroll). Returns true when the table itself
|
|
123
|
+
* should manage its own scroll.
|
|
124
|
+
*/
|
|
125
|
+
const tableShouldOwnScroll = (el) => {
|
|
126
|
+
let node = el.parentElement;
|
|
127
|
+
while (node && node !== document.body) {
|
|
128
|
+
const style = window.getComputedStyle(node);
|
|
129
|
+
const overflowY = style.overflowY;
|
|
130
|
+
const isScrollable = (overflowY === 'auto' || overflowY === 'scroll') && node.scrollHeight > node.clientHeight + 1;
|
|
131
|
+
if (isScrollable)
|
|
132
|
+
return false;
|
|
133
|
+
node = node.parentElement;
|
|
134
|
+
}
|
|
135
|
+
return true;
|
|
136
|
+
};
|
|
107
137
|
const applyTableHeight = (el) => {
|
|
108
138
|
const mrtContainer = el.querySelector('.mrt-table-container');
|
|
109
139
|
if (!mrtContainer)
|
|
110
140
|
return;
|
|
141
|
+
// If a parent is already handling the scroll, let the table render at
|
|
142
|
+
// its natural height — the user gets one continuous page scroll.
|
|
143
|
+
if (!tableShouldOwnScroll(el)) {
|
|
144
|
+
mrtContainer.style.removeProperty('max-height');
|
|
145
|
+
return;
|
|
146
|
+
}
|
|
111
147
|
const containerTop = mrtContainer.getBoundingClientRect().top;
|
|
112
|
-
const
|
|
113
|
-
|
|
148
|
+
const newMax = Math.round(Math.max(240, window.innerHeight - containerTop - TABLE_BOTTOM_MARGIN));
|
|
149
|
+
const newMaxStr = `${newMax}px`;
|
|
150
|
+
// Skip the write if the value hasn't changed — avoids re-layout loops
|
|
151
|
+
// with ResizeObserver where mutating the cell's max-height would refire
|
|
152
|
+
// the observer on the next frame.
|
|
153
|
+
if (mrtContainer.style.maxHeight === newMaxStr)
|
|
154
|
+
return;
|
|
155
|
+
mrtContainer.style.setProperty('max-height', newMaxStr, 'important');
|
|
114
156
|
};
|
|
115
|
-
// Runs
|
|
157
|
+
// Runs once on mount + whenever the *window* resizes. We deliberately do
|
|
158
|
+
// NOT run on every render or use a ResizeObserver on the document — both
|
|
159
|
+
// produce loop conditions: applyTableHeight mutates layout, which fires
|
|
160
|
+
// the observer, which calls applyTableHeight again. The window-resize
|
|
161
|
+
// signal is sufficient because tableTop changes during a render get
|
|
162
|
+
// re-applied by useLayoutEffect-on-mount when the table remounts.
|
|
116
163
|
useLayoutEffect(() => {
|
|
117
164
|
if (tableRef.current)
|
|
118
165
|
applyTableHeight(tableRef.current);
|
|
119
|
-
});
|
|
166
|
+
}, []);
|
|
120
167
|
useEffect(() => {
|
|
121
168
|
const el = tableRef.current;
|
|
122
169
|
if (!el)
|
|
123
170
|
return;
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
171
|
+
let frame = 0;
|
|
172
|
+
const handler = () => {
|
|
173
|
+
cancelAnimationFrame(frame);
|
|
174
|
+
frame = requestAnimationFrame(() => applyTableHeight(el));
|
|
175
|
+
};
|
|
176
|
+
window.addEventListener('resize', handler);
|
|
127
177
|
return () => {
|
|
128
|
-
|
|
129
|
-
window.removeEventListener('resize',
|
|
178
|
+
cancelAnimationFrame(frame);
|
|
179
|
+
window.removeEventListener('resize', handler);
|
|
130
180
|
};
|
|
131
181
|
}, []);
|
|
132
182
|
// Process columns (handle showHeader: false)
|
|
@@ -274,6 +324,6 @@ const PagamioTable = ({ columns, data, isLoading = false, rowCount, sorting, pag
|
|
|
274
324
|
});
|
|
275
325
|
// ── Toolbar rendering ──────────────────────────────────────────────
|
|
276
326
|
const showCustomToolbar = toolbarMode === 'custom' && (!!toolbar || !!search || !!filtering);
|
|
277
|
-
return (_jsxs("div", { children: [showCustomToolbar && (_jsx(CustomToolbar, { filters: toolbar?.filters ?? [], appliedFilters: filtering?.appliedFilters ?? {}, onFilterChange: filtering?.onFilterChange ?? (() => { }), onApply: filtering?.onApply ?? (() => { }), onClearFilters: toolbar?.onClearFilters, showClearFilters: toolbar?.showClearFilters ?? false, showApplyFilterButton: toolbar?.showApplyFilterButton ?? true, searchEnabled: !!search, searchQuery: search?.query ?? '', onSearch: search?.onChange ?? (() => { }), searchPlaceholder: search?.placeholder, exportConfig: toolbar?.export, columns: columns, data: data, addButton: toolbar?.addButton, addText: toolbar?.addText, onAdd: toolbar?.onAdd })), _jsx("div", { ref: tableRef, className: "border border-border rounded-md overflow-hidden", children: _jsx(MantineReactTable, { table: table }) })] }));
|
|
327
|
+
return (_jsxs("div", { children: [showCustomToolbar && (_jsx(CustomToolbar, { filters: toolbar?.filters ?? [], appliedFilters: filtering?.appliedFilters ?? {}, onFilterChange: filtering?.onFilterChange ?? (() => { }), onApply: filtering?.onApply ?? (() => { }), onClearFilters: toolbar?.onClearFilters, showClearFilters: toolbar?.showClearFilters ?? false, showApplyFilterButton: toolbar?.showApplyFilterButton ?? true, searchEnabled: !!search, searchQuery: search?.query ?? '', onSearch: search?.onChange ?? (() => { }), searchPlaceholder: search?.placeholder, exportConfig: toolbar?.export, columns: columns, data: data, addButton: toolbar?.addButton, addText: toolbar?.addText, onAdd: toolbar?.onAdd })), _jsx("div", { ref: tableRef, className: "border border-border rounded-md overflow-y-hidden", children: _jsx(MantineReactTable, { table: table }) })] }));
|
|
278
328
|
};
|
|
279
329
|
export default PagamioTable;
|
package/lib/styles.css
CHANGED
|
@@ -3889,14 +3889,25 @@ video {
|
|
|
3889
3889
|
text-overflow: clip !important;
|
|
3890
3890
|
}
|
|
3891
3891
|
|
|
3892
|
-
/* MRT semantic mode
|
|
3893
|
-
|
|
3894
|
-
|
|
3895
|
-
|
|
3896
|
-
|
|
3892
|
+
/* MRT semantic mode column sizing.
|
|
3893
|
+
*
|
|
3894
|
+
* MRT inlines `width: calc(--col-X-size * 1px)` and
|
|
3895
|
+
* `min-width: max(calc(--col-X-size * 1px), 50px)` on every cell. With
|
|
3896
|
+
* `table-layout: auto`, those fixed values cause two problems:
|
|
3897
|
+
* 1. Cells can't shrink below their min-width, leaving dead gaps when
|
|
3898
|
+
* content is short.
|
|
3899
|
+
* 2. The combined widths can exceed the container, leaving a horizontal
|
|
3900
|
+
* gap on the right.
|
|
3901
|
+
*
|
|
3902
|
+
* We override both: cells get `width: auto` and `min-width: 0` so the
|
|
3903
|
+
* browser sizes columns by content, then distributes remaining row space
|
|
3904
|
+
* proportionally. `whiteSpace: normal` (set above) lets long content wrap
|
|
3905
|
+
* instead of being crushed.
|
|
3906
|
+
*/
|
|
3897
3907
|
.mantine-Table-table > thead > tr > .mantine-Table-th,
|
|
3898
3908
|
.mantine-Table-table > tbody > tr > .mantine-Table-td {
|
|
3899
3909
|
width: auto !important;
|
|
3910
|
+
min-width: 0 !important;
|
|
3900
3911
|
}
|
|
3901
3912
|
.file\:-ms-4::file-selector-button {
|
|
3902
3913
|
margin-inline-start: -1rem;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pagamio/frontend-commons-lib",
|
|
3
3
|
"description": "Pagamio library for Frontend reusable components like the form engine and table container",
|
|
4
|
-
"version": "0.8.
|
|
4
|
+
"version": "0.8.320",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public",
|
|
7
7
|
"provenance": false
|