@pagamio/frontend-commons-lib 0.8.313 → 0.8.315
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.
|
@@ -26,7 +26,7 @@ const sizeStyles = {
|
|
|
26
26
|
const Spinner = () => (_jsxs("svg", { className: "mr-2 h-4 w-4 animate-spin", xmlns: "http://www.w3.org/2000/svg", fill: "none", viewBox: "0 0 24 24", "aria-hidden": "true", children: [_jsx("circle", { className: "opacity-25", cx: "12", cy: "12", r: "10", stroke: "currentColor", strokeWidth: "4" }), _jsx("path", { className: "opacity-75", fill: "currentColor", d: "M4 12a8 8 0 018-8v4a4 4 0 00-4 4H4z" })] }));
|
|
27
27
|
const Button = React.forwardRef(({ className, variant = 'primary', size = 'default', asChild = false, href, pill = false, loading = false, fullWidth = false, disabled = false, children, ...props }, ref) => {
|
|
28
28
|
const isDisabled = disabled || loading;
|
|
29
|
-
const baseStyles = 'inline-flex items-center justify-center font-semibold transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50';
|
|
29
|
+
const baseStyles = 'inline-flex items-center justify-center gap-2 font-semibold transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50';
|
|
30
30
|
const classes = cn(baseStyles, variantStyles[variant], sizeStyles[size], pill ? 'rounded-full' : 'rounded-md', fullWidth && 'w-full', loading && 'cursor-wait', isDisabled && !loading && 'bg-gray-400 text-white cursor-not-allowed', className);
|
|
31
31
|
// Render as <a> when href is provided
|
|
32
32
|
if (href) {
|
|
@@ -19,11 +19,15 @@ export function getDefaultTableOptions() {
|
|
|
19
19
|
enableStickyHeader: true,
|
|
20
20
|
enableTopToolbar: false,
|
|
21
21
|
enableBottomToolbar: true,
|
|
22
|
+
// ── Density: compact rows by default (per MRT v2 docs) ──
|
|
23
|
+
initialState: { density: 'xs' },
|
|
22
24
|
// ── Layout: columns fill the row width, no horizontal scroll, no gaps ──
|
|
25
|
+
// In `grid` mode, leftover row width is distributed proportionally to
|
|
26
|
+
// each column's `size`, so larger columns naturally get more room.
|
|
23
27
|
layoutMode: 'grid',
|
|
24
28
|
defaultColumn: {
|
|
25
|
-
minSize:
|
|
26
|
-
size:
|
|
29
|
+
minSize: 50,
|
|
30
|
+
size: 140,
|
|
27
31
|
grow: true,
|
|
28
32
|
},
|
|
29
33
|
// ── Brand styling ──
|
|
@@ -20,14 +20,11 @@ function isInteractiveTarget(target) {
|
|
|
20
20
|
/**
|
|
21
21
|
* Auto-size buckets based on column id/accessor key.
|
|
22
22
|
* Consumer can always override by setting `size` explicitly on the column.
|
|
23
|
+
* Per MRT v2 docs, in `grid` layoutMode columns share leftover width
|
|
24
|
+
* proportionally to `size` — bigger size = bigger share of row.
|
|
23
25
|
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
* - small (90): total, price, amount, balance, fee, rate, percent, date, time
|
|
27
|
-
* - medium (140): status, type, role, category, unit, sku, code, currency, country
|
|
28
|
-
* - actions (110): the actions column
|
|
29
|
-
* - large (220): name, description, address, email, message, label, title, product
|
|
30
|
-
* - default (160): everything else
|
|
26
|
+
* Pinned columns (`grow: false`) stay at their fixed pixel size and don't
|
|
27
|
+
* eat extra space, so the flexible columns get the slack instead.
|
|
31
28
|
*/
|
|
32
29
|
const TINY_PATTERNS = /^(qty|quantity|count|position|order|index|no|num|number)$/i;
|
|
33
30
|
const SMALL_PATTERNS = /(total|price|amount|balance|fee|rate|percent|created|updated|deleted|date|time|expires|due)/i;
|
|
@@ -36,18 +33,18 @@ const MEDIUM_PATTERNS = /^(type|role|category|unit|sku|code|currency|country|met
|
|
|
36
33
|
const LARGE_PATTERNS = /(name|description|address|email|message|label|title|product|item|note)/i;
|
|
37
34
|
function inferColumnSize(id) {
|
|
38
35
|
if (id === 'actions')
|
|
39
|
-
return
|
|
36
|
+
return { size: 100, grow: false };
|
|
40
37
|
if (TINY_PATTERNS.test(id))
|
|
41
|
-
return 60;
|
|
38
|
+
return { size: 60, grow: false };
|
|
42
39
|
if (STATUS_PATTERNS.test(id))
|
|
43
|
-
return
|
|
44
|
-
if (MEDIUM_PATTERNS.test(id))
|
|
45
|
-
return 140;
|
|
40
|
+
return { size: 170, grow: true };
|
|
46
41
|
if (SMALL_PATTERNS.test(id))
|
|
47
|
-
return 90;
|
|
42
|
+
return { size: 90, grow: false };
|
|
43
|
+
if (MEDIUM_PATTERNS.test(id))
|
|
44
|
+
return { size: 130, grow: true };
|
|
48
45
|
if (LARGE_PATTERNS.test(id))
|
|
49
|
-
return
|
|
50
|
-
return
|
|
46
|
+
return { size: 200, grow: true };
|
|
47
|
+
return { size: 140, grow: true };
|
|
51
48
|
}
|
|
52
49
|
/**
|
|
53
50
|
* Applies the `showHeader: false` column config and auto-sizes columns.
|
|
@@ -60,8 +57,10 @@ function processColumns(columns) {
|
|
|
60
57
|
return columns.map((col) => {
|
|
61
58
|
const id = (col.id ?? col.accessorKey ?? '');
|
|
62
59
|
const inferred = inferColumnSize(id);
|
|
63
|
-
const finalSize = col.size === undefined ? inferred : Math.max(col.size, inferred);
|
|
64
|
-
const
|
|
60
|
+
const finalSize = col.size === undefined ? inferred.size : Math.max(col.size, inferred.size);
|
|
61
|
+
const colWithGrow = col;
|
|
62
|
+
const finalGrow = colWithGrow.grow ?? inferred.grow;
|
|
63
|
+
const sized = { ...col, size: finalSize, grow: finalGrow };
|
|
65
64
|
if (sized.showHeader === false) {
|
|
66
65
|
return {
|
|
67
66
|
...sized,
|
|
@@ -204,6 +203,17 @@ const PagamioTable = ({ columns, data, isLoading = false, rowCount, sorting, pag
|
|
|
204
203
|
enableExpanding: expandable,
|
|
205
204
|
renderDetailPanel,
|
|
206
205
|
onExpandedChange: setExpanded,
|
|
206
|
+
// Force detail panel to span the entire row in grid layoutMode.
|
|
207
|
+
// The actual `width: var(--mrt-inner-width)` cap is overridden via global
|
|
208
|
+
// CSS in src/index.css — these inline styles complement that.
|
|
209
|
+
mantineDetailPanelProps: {
|
|
210
|
+
style: {
|
|
211
|
+
width: '100%',
|
|
212
|
+
maxWidth: '100%',
|
|
213
|
+
gridColumn: '1 / -1',
|
|
214
|
+
flex: '1 1 100%',
|
|
215
|
+
},
|
|
216
|
+
},
|
|
207
217
|
// Toolbar visibility
|
|
208
218
|
enableTopToolbar: usesMrtToolbar,
|
|
209
219
|
enableBottomToolbar: hasServerPagination || defaults.enableBottomToolbar,
|
|
@@ -246,6 +256,23 @@ const PagamioTable = ({ columns, data, isLoading = false, rowCount, sorting, pag
|
|
|
246
256
|
},
|
|
247
257
|
},
|
|
248
258
|
mantineTableProps: defaults.mantineTableProps,
|
|
259
|
+
// Allow body cells to wrap their content instead of truncating with ellipsis.
|
|
260
|
+
mantineTableBodyCellProps: {
|
|
261
|
+
style: {
|
|
262
|
+
whiteSpace: 'normal',
|
|
263
|
+
overflow: 'visible',
|
|
264
|
+
textOverflow: 'clip',
|
|
265
|
+
wordBreak: 'break-word',
|
|
266
|
+
},
|
|
267
|
+
},
|
|
268
|
+
// Allow header cells to wrap too so long titles don't clip.
|
|
269
|
+
mantineTableHeadCellProps: {
|
|
270
|
+
style: {
|
|
271
|
+
whiteSpace: 'normal',
|
|
272
|
+
overflow: 'visible',
|
|
273
|
+
textOverflow: 'clip',
|
|
274
|
+
},
|
|
275
|
+
},
|
|
249
276
|
// Row interaction styling
|
|
250
277
|
mantineTableBodyRowProps: ({ row }) => ({
|
|
251
278
|
onClick: onRowClick ? (event) => handleRowClick(row, event) : undefined,
|
package/lib/styles.css
CHANGED
|
@@ -3875,6 +3875,34 @@ video {
|
|
|
3875
3875
|
.dark .apexcharts-xaxistooltip-bottom::after {
|
|
3876
3876
|
border-bottom-color: hsl(var(--border)) !important;
|
|
3877
3877
|
}
|
|
3878
|
+
|
|
3879
|
+
/* ─────────────────────────────────────────────────────────────────
|
|
3880
|
+
Mantine React Table — detail panel full-width override.
|
|
3881
|
+
In `layoutMode: 'grid'`, MRT sets the cell width to
|
|
3882
|
+
`var(--mrt-inner-width)` which equals the sum of column sizes.
|
|
3883
|
+
Override it so the detail panel always spans the full row width,
|
|
3884
|
+
and force the inner Collapse wrapper to fill the cell.
|
|
3885
|
+
───────────────────────────────────────────────────────────────── */
|
|
3886
|
+
.mantine-Table-td-detail-panel {
|
|
3887
|
+
width: 100% !important;
|
|
3888
|
+
max-width: 100% !important;
|
|
3889
|
+
}
|
|
3890
|
+
.mantine-Table-td-detail-panel > div {
|
|
3891
|
+
width: 100%;
|
|
3892
|
+
}
|
|
3893
|
+
|
|
3894
|
+
/* Ensure body cells wrap content instead of clipping in grid mode. */
|
|
3895
|
+
.mantine-Table-td {
|
|
3896
|
+
white-space: normal !important;
|
|
3897
|
+
overflow: visible !important;
|
|
3898
|
+
text-overflow: clip !important;
|
|
3899
|
+
word-break: break-word;
|
|
3900
|
+
}
|
|
3901
|
+
.mantine-Table-th {
|
|
3902
|
+
white-space: normal !important;
|
|
3903
|
+
overflow: visible !important;
|
|
3904
|
+
text-overflow: clip !important;
|
|
3905
|
+
}
|
|
3878
3906
|
.file\:-ms-4::file-selector-button {
|
|
3879
3907
|
margin-inline-start: -1rem;
|
|
3880
3908
|
}
|
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.315",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public",
|
|
7
7
|
"provenance": false
|