@pagamio/frontend-commons-lib 0.8.319 → 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 +75 -12
- package/lib/styles.css +16 -5
- package/package.json +1 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { MantineReactTable, useMantineReactTable } from 'mantine-react-table';
|
|
3
3
|
import { HiPlusSm } from 'react-icons/hi';
|
|
4
|
-
import { useMemo, useRef, useState } from 'react';
|
|
4
|
+
import { useEffect, useLayoutEffect, useMemo, useRef, useState } from 'react';
|
|
5
5
|
import { FilterComponent, IconButton } from '../../components';
|
|
6
6
|
import { cn } from '../../helpers';
|
|
7
7
|
import { useMediaQueries } from '../../shared';
|
|
@@ -104,18 +104,81 @@ 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
|
-
//
|
|
108
|
-
//
|
|
109
|
-
//
|
|
110
|
-
//
|
|
111
|
-
//
|
|
112
|
-
//
|
|
113
|
-
// before an internal scroll kicked in.
|
|
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.
|
|
114
113
|
//
|
|
115
|
-
//
|
|
116
|
-
//
|
|
117
|
-
|
|
118
|
-
|
|
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
|
+
};
|
|
137
|
+
const applyTableHeight = (el) => {
|
|
138
|
+
const mrtContainer = el.querySelector('.mrt-table-container');
|
|
139
|
+
if (!mrtContainer)
|
|
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
|
+
}
|
|
147
|
+
const containerTop = mrtContainer.getBoundingClientRect().top;
|
|
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');
|
|
156
|
+
};
|
|
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.
|
|
163
|
+
useLayoutEffect(() => {
|
|
164
|
+
if (tableRef.current)
|
|
165
|
+
applyTableHeight(tableRef.current);
|
|
166
|
+
}, []);
|
|
167
|
+
useEffect(() => {
|
|
168
|
+
const el = tableRef.current;
|
|
169
|
+
if (!el)
|
|
170
|
+
return;
|
|
171
|
+
let frame = 0;
|
|
172
|
+
const handler = () => {
|
|
173
|
+
cancelAnimationFrame(frame);
|
|
174
|
+
frame = requestAnimationFrame(() => applyTableHeight(el));
|
|
175
|
+
};
|
|
176
|
+
window.addEventListener('resize', handler);
|
|
177
|
+
return () => {
|
|
178
|
+
cancelAnimationFrame(frame);
|
|
179
|
+
window.removeEventListener('resize', handler);
|
|
180
|
+
};
|
|
181
|
+
}, []);
|
|
119
182
|
// Process columns (handle showHeader: false)
|
|
120
183
|
const processedColumns = useMemo(() => processColumns(columns), [columns]);
|
|
121
184
|
// Convert our SortConfig to MRT's SortingState
|
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
|