@pagamio/frontend-commons-lib 0.8.312 → 0.8.314

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.
@@ -8,9 +8,6 @@ const DetailsCard = ({ data, loading, buttonText, showButton = true, onClickButt
8
8
  }
9
9
  const rightPanelItem = data.find((item) => item.layout === 'rightPanel' || item.id === '__details_right_panel__');
10
10
  const leftData = rightPanelItem ? data.filter((item) => item !== rightPanelItem) : data;
11
- return (_jsx("div", { className: "flex flex-col", children: _jsxs(Card, { children: [loading ? (_jsx("div", { className: "mb-2 grid grid-cols-1 gap-4 sm:grid-cols-2 md:grid-cols-4", children: _jsx("div", { className: "flex items-center justify-center col-span-full", children: _jsx(LoaderComponent, {}) }) })) : (_jsxs("div", { className: `mb-2 ${rightPanelItem ? 'flex flex-col gap-6 lg:flex-row' : ''}`, children: [_jsx("div", { className: `grid grid-cols-1 gap-4 sm:grid-cols-2 ${rightPanelItem ? 'flex-1 lg:grid-cols-3' : 'md:grid-cols-4'}`, children: leftData.map((item, index) => {
12
- const capitalizedLabel = item.label.charAt(0).toUpperCase() + item.label.slice(1);
13
- return (_jsxs("div", { className: "flex flex-col", children: [_jsx("div", { className: "mb-1 font-medium text-sm text-muted-foreground", children: capitalizedLabel }), _jsx("div", { className: "text-foreground text-sm break-words", children: item.value })] }, item.id ?? `${item.label}-${index}`));
14
- }) }), rightPanelItem && (_jsxs("div", { className: "lg:w-[320px] lg:shrink-0 lg:border-l lg:border-border lg:pl-6", children: [_jsx("div", { className: "mb-2 font-medium text-sm text-muted-foreground", children: rightPanelItem.label.charAt(0).toUpperCase() + rightPanelItem.label.slice(1) }), _jsx("div", { className: "text-foreground text-sm break-words", children: rightPanelItem.value })] }))] })), !loading && (_jsxs("div", { className: "flex justify-end gap-2 items-center", children: [actionContent && _jsx("div", { className: "flex-1 flex flex-row text-sm justify-end", children: actionContent }), showButton && (_jsx("div", { className: `flex ${actionContent ? 'justify-end' : 'justify-center sm:justify-end'}`, children: _jsx(Button, { type: "button", variant: "primary", disabled: loading, onClick: onClickButton, className: "text-sm", children: buttonText }) }))] }))] }) }));
11
+ return (_jsx("div", { className: "flex flex-col mb-4", children: _jsxs(Card, { children: [loading ? (_jsx("div", { className: "flex items-center justify-center py-8", children: _jsx(LoaderComponent, {}) })) : (_jsxs("div", { className: "flex flex-col lg:flex-row gap-6", children: [_jsx("div", { className: "flex-1 min-w-0", children: _jsx("div", { className: "grid grid-cols-2 md:grid-cols-3 xl:grid-cols-4 gap-x-6 gap-y-4", children: leftData.map((item, index) => (_jsxs("div", { className: "flex flex-col min-w-0", children: [_jsx("div", { className: "mb-0.5 text-xs font-medium text-muted-foreground uppercase tracking-wide", children: item.label.charAt(0).toUpperCase() + item.label.slice(1) }), _jsx("div", { className: "text-foreground text-sm break-words", children: item.value })] }, item.id ?? `${item.label}-${index}`))) }) }), rightPanelItem && (_jsxs("div", { className: "lg:w-[320px] lg:shrink-0 lg:border-l lg:border-border lg:pl-6 flex flex-col gap-2", children: [_jsx("div", { className: "text-xs font-medium text-muted-foreground uppercase tracking-wide", children: rightPanelItem.label.charAt(0).toUpperCase() + rightPanelItem.label.slice(1) }), _jsx("div", { className: "text-foreground text-sm break-words", children: rightPanelItem.value })] }))] })), !loading && (actionContent || showButton) && (_jsxs("div", { className: "flex flex-wrap justify-end gap-2 items-center mt-2", children: [actionContent && _jsx("div", { className: "flex flex-wrap gap-2", children: actionContent }), showButton && (_jsx(Button, { type: "button", variant: "primary", disabled: loading, onClick: onClickButton, className: "text-sm", children: buttonText }))] }))] }) }));
15
12
  };
16
13
  export default DetailsCard;
@@ -45,6 +45,6 @@ const DetailsPage = ({ id, parentId, title, loading, detailsData, canEdit, onEdi
45
45
  }, [id, parentId, entityName, parentEntityName, updateBreadcrumb]);
46
46
  // Capitalize the component for JSX usage
47
47
  const TabComponent = tabComponent;
48
- return (_jsxs("div", { children: [_jsx(AppPageHeader, { title: title }), _jsx(DetailsCard, { loading: loading, data: formattedDetailsData, buttonText: editButtonText, showButton: canEdit, onClickButton: onEdit || (() => { }), actionContent: actionContent }), TabComponent && _jsx(TabComponent, { ...tabProps }), formEngineConfig && (_jsx(FormEngineDrawer, { title: formEngineConfig.title, isOpen: formEngineConfig.isOpen, onClose: formEngineConfig.onClose, onSubmit: formEngineConfig.onSubmit, fields: formEngineConfig.fields, initialValues: formEngineConfig.initialValues, submitButtonText: formEngineConfig.submitButtonText, marginTop: formEngineConfig.marginTop, onFieldChange: formEngineConfig.onFieldChange, onFieldUpdate: formEngineConfig.onFieldUpdate, persistenceKey: formEngineConfig.persistenceKey, children: formEngineConfig.children }, formEngineConfig.drawerKey))] }));
48
+ return (_jsxs("div", { children: [_jsx(AppPageHeader, { title: title }), _jsx(DetailsCard, { loading: loading, data: formattedDetailsData, buttonText: editButtonText, showButton: canEdit, onClickButton: onEdit || (() => { }), actionContent: actionContent }), TabComponent && (_jsx("div", { className: "mt-2", children: _jsx(TabComponent, { ...tabProps }) })), formEngineConfig && (_jsx(FormEngineDrawer, { title: formEngineConfig.title, isOpen: formEngineConfig.isOpen, onClose: formEngineConfig.onClose, onSubmit: formEngineConfig.onSubmit, fields: formEngineConfig.fields, initialValues: formEngineConfig.initialValues, submitButtonText: formEngineConfig.submitButtonText, marginTop: formEngineConfig.marginTop, onFieldChange: formEngineConfig.onFieldChange, onFieldUpdate: formEngineConfig.onFieldUpdate, persistenceKey: formEngineConfig.persistenceKey, children: formEngineConfig.children }, formEngineConfig.drawerKey))] }));
49
49
  };
50
50
  export default DetailsPage;
@@ -31,7 +31,7 @@ const FilterComponent = ({ filters, selectedFilters, showApplyFilterButton = tru
31
31
  resetFilters();
32
32
  }
33
33
  };
34
- return (_jsxs(FilterWrapper, { isNarrow: isNarrow, children: [_jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [showSearch && (_jsxs("div", { className: "relative w-full sm:w-[300px]", children: [_jsx(IconSearch, { size: 16, className: "pointer-events-none absolute left-3 top-1/2 -translate-y-1/2 text-muted-foreground" }), _jsx("input", { type: "text", placeholder: searctInputPlaceHolder, value: searchQuery, onChange: onSearch, onKeyDown: handleSearchKeyDown, "aria-label": "Search", className: cn('h-9 w-full rounded-md border border-border bg-background pl-9 pr-3 text-sm text-foreground', 'placeholder:text-muted-foreground', 'focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring', 'disabled:cursor-not-allowed disabled:opacity-50') })] })), filters.map((filter) => {
34
+ return (_jsxs(FilterWrapper, { isNarrow: isNarrow, children: [_jsxs("div", { className: "flex shrink-0 flex-wrap items-center gap-2", children: [showSearch && (_jsxs("div", { className: "relative w-full sm:w-[300px]", children: [_jsx(IconSearch, { size: 16, className: "pointer-events-none absolute left-3 top-1/2 -translate-y-1/2 text-muted-foreground" }), _jsx("input", { type: "text", placeholder: searctInputPlaceHolder, value: searchQuery, onChange: onSearch, onKeyDown: handleSearchKeyDown, "aria-label": "Search", className: cn('h-9 w-full rounded-md border border-border bg-background pl-9 pr-3 text-sm text-foreground', 'placeholder:text-muted-foreground', 'focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring', 'disabled:cursor-not-allowed disabled:opacity-50') })] })), filters.map((filter) => {
35
35
  const { name, type, options } = filter;
36
36
  const value = selectedFilters[name];
37
37
  const renderFilterInput = () => {
@@ -71,6 +71,6 @@ const FilterComponent = ({ filters, selectedFilters, showApplyFilterButton = tru
71
71
  return (_jsxs(Select, { value: currentValue || undefined, onValueChange: (val) => handleFilterChange(name, val === '__clear__' ? '' : val), children: [_jsx(SelectTrigger, { className: "h-9 w-full border-border bg-background text-sm text-foreground", "aria-label": filter.placeholder ?? name, children: _jsx(SelectValue, { placeholder: filter.placeholder ?? `Select ${name}` }) }), _jsxs(SelectContent, { children: [currentValue && (_jsx(SelectItem, { value: "__clear__", className: "text-muted-foreground", children: filter.placeholder ?? 'All' })), (options ?? []).map((opt) => (_jsx(SelectItem, { value: opt.value, children: opt.label }, opt.value)))] })] }));
72
72
  };
73
73
  return (_jsx("div", { className: "w-full sm:w-[240px]", children: renderFilterInput() }, name));
74
- }), showApplyFilterButton && shouldShowActionButtons && (_jsx(Button, { onClick: handleApplyFilters, variant: "primary", className: "w-full sm:w-auto", style: { height: 36 }, tabIndex: 0, "aria-label": "Apply Filters", children: "Apply Filters" })), showClearFilters && shouldShowActionButtons && (_jsx(Button, { onClick: resetFilters, variant: "outline-primary", className: "w-full sm:w-auto", style: { height: 36 }, tabIndex: 0, "aria-label": "Clear Filters", children: "Clear Filters" }))] }), children] }));
74
+ }), showApplyFilterButton && shouldShowActionButtons && (_jsx(Button, { onClick: handleApplyFilters, variant: "primary", className: "w-full sm:w-auto", style: { height: 36 }, tabIndex: 0, "aria-label": "Apply Filters", children: "Apply Filters" })), showClearFilters && shouldShowActionButtons && (_jsx(Button, { onClick: resetFilters, variant: "outline-primary", className: "w-full sm:w-auto", style: { height: 36 }, tabIndex: 0, "aria-label": "Clear Filters", children: "Clear Filters" }))] }), _jsx("div", { className: "ml-auto flex flex-wrap items-center justify-end gap-2", children: children })] }));
75
75
  };
76
76
  export default FilterComponent;
@@ -1,7 +1,5 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
2
  const FilterWrapper = ({ isNarrow, children }) => {
3
- return (_jsx("div", { className: "bg-card shadow-xl rounded-lg p-4 mb-2", children: _jsx("div", { className: isNarrow
4
- ? 'flex flex-col w-full space-y-4'
5
- : 'flex flex-row justify-between items-start w-full space-y-0 space-x-0 sm:space-x-4', children: children }) }));
3
+ return (_jsx("div", { className: "bg-card shadow-xl rounded-lg p-4 mb-2", children: _jsx("div", { className: isNarrow ? 'flex flex-col w-full gap-3' : 'flex items-start justify-between gap-4 w-full', children: children }) }));
6
4
  };
7
5
  export default FilterWrapper;
@@ -4,6 +4,6 @@ function StatusCell({ displayValue, className = '', icon }) {
4
4
  if (icon) {
5
5
  return (_jsxs("span", { className: `inline-flex items-center gap-1.5 pl-2.5 pr-3 ${baseClass} ${className}`.trim(), children: [icon, displayValue] }));
6
6
  }
7
- return _jsx("span", { className: `px-4 ${baseClass} ${className}`.trim(), children: displayValue });
7
+ return _jsx("span", { className: `inline-block px-4 ${baseClass} ${className}`.trim(), children: displayValue });
8
8
  }
9
9
  export default StatusCell;
@@ -19,11 +19,28 @@ 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' },
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.
27
+ layoutMode: 'grid',
28
+ defaultColumn: {
29
+ minSize: 50,
30
+ size: 140,
31
+ grow: true,
32
+ },
22
33
  // ── Brand styling ──
23
34
  mantineTableContainerProps: {
24
35
  style: {
25
36
  border: 'transparent',
26
37
  borderRadius: '4px',
38
+ overflowX: 'hidden',
39
+ },
40
+ },
41
+ mantineTableProps: {
42
+ style: {
43
+ width: '100%',
27
44
  },
28
45
  },
29
46
  mantineLoadingOverlayProps: {
@@ -3,6 +3,7 @@ import { MantineReactTable, useMantineReactTable } from 'mantine-react-table';
3
3
  import { HiPlusSm } from 'react-icons/hi';
4
4
  import { useEffect, useLayoutEffect, useMemo, useRef, useState } from 'react';
5
5
  import { FilterComponent, IconButton } from '../../components';
6
+ import { cn } from '../../helpers';
6
7
  import { useMediaQueries } from '../../shared';
7
8
  import { getDefaultTableOptions } from './Defaults';
8
9
  import ExportDropdown from './ExportButton';
@@ -16,12 +17,53 @@ function isInteractiveTarget(target) {
16
17
  !!target.closest('[data-mantine-stop-propagation]') ||
17
18
  !!target.closest('.mantine-ActionIcon-root'));
18
19
  }
19
- /** Applies the `showHeader: false` column config (hides header visually). */
20
+ /**
21
+ * Auto-size buckets based on column id/accessor key.
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.
25
+ *
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.
28
+ */
29
+ const TINY_PATTERNS = /^(qty|quantity|count|position|order|index|no|num|number)$/i;
30
+ const SMALL_PATTERNS = /(total|price|amount|balance|fee|rate|percent|created|updated|deleted|date|time|expires|due)/i;
31
+ const STATUS_PATTERNS = /(status|state)$/i;
32
+ const MEDIUM_PATTERNS = /^(type|role|category|unit|sku|code|currency|country|method|source|kind)$/i;
33
+ const LARGE_PATTERNS = /(name|description|address|email|message|label|title|product|item|note)/i;
34
+ function inferColumnSize(id) {
35
+ if (id === 'actions')
36
+ return { size: 100, grow: false };
37
+ if (TINY_PATTERNS.test(id))
38
+ return { size: 60, grow: false };
39
+ if (STATUS_PATTERNS.test(id))
40
+ return { size: 170, grow: true };
41
+ if (SMALL_PATTERNS.test(id))
42
+ return { size: 90, grow: false };
43
+ if (MEDIUM_PATTERNS.test(id))
44
+ return { size: 130, grow: true };
45
+ if (LARGE_PATTERNS.test(id))
46
+ return { size: 200, grow: true };
47
+ return { size: 140, grow: true };
48
+ }
49
+ /**
50
+ * Applies the `showHeader: false` column config and auto-sizes columns.
51
+ * Inferred size is treated as a minimum — any explicit `col.size` is honoured
52
+ * only if it is at least the inferred minimum. This guarantees columns like
53
+ * `status` always have enough room for their chips even if a consumer hardcoded
54
+ * a too-narrow size.
55
+ */
20
56
  function processColumns(columns) {
21
57
  return columns.map((col) => {
22
- if (col.showHeader === false) {
58
+ const id = (col.id ?? col.accessorKey ?? '');
59
+ const inferred = inferColumnSize(id);
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 };
64
+ if (sized.showHeader === false) {
23
65
  return {
24
- ...col,
66
+ ...sized,
25
67
  header: '',
26
68
  enableSorting: false,
27
69
  enableColumnFilter: false,
@@ -31,7 +73,7 @@ function processColumns(columns) {
31
73
  },
32
74
  };
33
75
  }
34
- return col;
76
+ return sized;
35
77
  });
36
78
  }
37
79
  /** Maps BaseFilter[] to FilterComponent's FilterDefinition[]. */
@@ -57,7 +99,8 @@ function CustomToolbar({ filters, appliedFilters, onFilterChange, onApply, onCle
57
99
  else {
58
100
  handleFilter(name, value);
59
101
  }
60
- }, handleApplyFilters: onApply, resetFilters: onClearFilters ?? (() => { }), showSearch: searchEnabled, searchQuery: searchQuery, onSearch: onSearch, isNarrow: isNarrow, children: _jsxs("div", { className: isNarrow ? 'flex flex-col items-stretch space-y-2 pt-5' : 'flex items-center flex-wrap gap-2', children: [exportConfig?.enabled && (_jsx("div", { className: isNarrow ? 'w-full' : 'flex-grow', children: _jsx(ExportDropdown, { containerClassName: "w-full", columns: columns, data: data, buttonClassName: "h-10", extraOptions: exportConfig.extraOptions, pdfOptions: exportConfig.pdf, xlsxOptions: exportConfig.xlsx, csvOptions: exportConfig.csv, exportAll: !!exportConfig.fetchAllData, fetchData: exportConfig.fetchAllData, enableEmailExport: !!exportConfig.email, emailExportApiUrl: exportConfig.email?.apiUrl, onEmailExportSuccess: exportConfig.email?.onSuccess, onEmailExportError: exportConfig.email?.onError }) })), addButton && (_jsx("div", { className: isNarrow ? 'w-full' : 'flex-grow', children: typeof addButton === 'boolean' ? (_jsx(IconButton, { onClick: onAdd ?? (() => { }), icon: HiPlusSm, label: "add-new-entry", className: "items-center w-full text-nowrap", children: addText ?? 'Add New Entry' })) : (addButton) }))] }) }));
102
+ }, handleApplyFilters: onApply, resetFilters: onClearFilters ?? (() => { }), showSearch: searchEnabled, searchQuery: searchQuery, onSearch: onSearch, isNarrow: isNarrow, children: _jsxs("div", { className: "flex flex-wrap items-center justify-end gap-2", children: [exportConfig?.enabled && (_jsx(ExportDropdown, { containerClassName: isNarrow ? 'w-full' : undefined, columns: columns, data: data, buttonClassName: "h-10", extraOptions: exportConfig.extraOptions, pdfOptions: exportConfig.pdf, xlsxOptions: exportConfig.xlsx, csvOptions: exportConfig.csv, exportAll: !!exportConfig.fetchAllData, fetchData: exportConfig.fetchAllData, enableEmailExport: !!exportConfig.email, emailExportApiUrl: exportConfig.email?.apiUrl, onEmailExportSuccess: exportConfig.email?.onSuccess, onEmailExportError: exportConfig.email?.onError })), addButton &&
103
+ (typeof addButton === 'boolean' ? (_jsx(IconButton, { onClick: onAdd ?? (() => { }), icon: HiPlusSm, label: "add-new-entry", className: cn('items-center text-nowrap', isNarrow ? 'w-full' : undefined), children: addText ?? 'Add New Entry' })) : (addButton))] }) }));
61
104
  }
62
105
  // ─── PagamioTable Component ──────────────────────────────────────────
63
106
  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, }) => {
@@ -160,6 +203,17 @@ const PagamioTable = ({ columns, data, isLoading = false, rowCount, sorting, pag
160
203
  enableExpanding: expandable,
161
204
  renderDetailPanel,
162
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
+ },
163
217
  // Toolbar visibility
164
218
  enableTopToolbar: usesMrtToolbar,
165
219
  enableBottomToolbar: hasServerPagination || defaults.enableBottomToolbar,
@@ -191,13 +245,32 @@ const PagamioTable = ({ columns, data, isLoading = false, rowCount, sorting, pag
191
245
  // Custom MRT toolbar actions
192
246
  ...(renderTopToolbarCustomActions && { renderTopToolbarCustomActions }),
193
247
  ...(renderBottomToolbarCustomActions && { renderBottomToolbarCustomActions }),
194
- // Layout
195
- ...(layoutMode && { layoutMode }),
196
- ...(defaultColumn && { defaultColumn }),
248
+ // Layout — columns fill row, no horizontal scroll
249
+ layoutMode: layoutMode ?? defaults.layoutMode,
250
+ defaultColumn: defaultColumn ?? defaults.defaultColumn,
197
251
  mantineTableContainerProps: {
198
252
  style: {
199
253
  border: 'transparent',
200
254
  borderRadius: '4px',
255
+ overflowX: 'hidden',
256
+ },
257
+ },
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',
201
274
  },
202
275
  },
203
276
  // Row interaction styling
package/lib/styles.css CHANGED
@@ -893,9 +893,6 @@ video {
893
893
  .col-span-9 {
894
894
  grid-column: span 9 / span 9;
895
895
  }
896
- .col-span-full {
897
- grid-column: 1 / -1;
898
- }
899
896
  .-m-1\.5 {
900
897
  margin: -0.375rem;
901
898
  }
@@ -977,6 +974,9 @@ video {
977
974
  .mb-0 {
978
975
  margin-bottom: 0px;
979
976
  }
977
+ .mb-0\.5 {
978
+ margin-bottom: 0.125rem;
979
+ }
980
980
  .mb-1 {
981
981
  margin-bottom: 0.25rem;
982
982
  }
@@ -1557,6 +1557,9 @@ video {
1557
1557
  .flex-grow {
1558
1558
  flex-grow: 1;
1559
1559
  }
1560
+ .grow {
1561
+ flex-grow: 1;
1562
+ }
1560
1563
  .border-collapse {
1561
1564
  border-collapse: collapse;
1562
1565
  }
@@ -1777,9 +1780,6 @@ video {
1777
1780
  .items-baseline {
1778
1781
  align-items: baseline;
1779
1782
  }
1780
- .items-stretch {
1781
- align-items: stretch;
1782
- }
1783
1783
  .justify-start {
1784
1784
  justify-content: flex-start;
1785
1785
  }
@@ -1834,9 +1834,16 @@ video {
1834
1834
  -moz-column-gap: 1rem;
1835
1835
  column-gap: 1rem;
1836
1836
  }
1837
+ .gap-x-6 {
1838
+ -moz-column-gap: 1.5rem;
1839
+ column-gap: 1.5rem;
1840
+ }
1837
1841
  .gap-y-2 {
1838
1842
  row-gap: 0.5rem;
1839
1843
  }
1844
+ .gap-y-4 {
1845
+ row-gap: 1rem;
1846
+ }
1840
1847
  .-space-x-4 > :not([hidden]) ~ :not([hidden]) {
1841
1848
  --tw-space-x-reverse: 0;
1842
1849
  margin-right: calc(-1rem * var(--tw-space-x-reverse));
@@ -1847,11 +1854,6 @@ video {
1847
1854
  margin-right: calc(-1px * var(--tw-space-x-reverse));
1848
1855
  margin-left: calc(-1px * calc(1 - var(--tw-space-x-reverse)));
1849
1856
  }
1850
- .space-x-0 > :not([hidden]) ~ :not([hidden]) {
1851
- --tw-space-x-reverse: 0;
1852
- margin-right: calc(0px * var(--tw-space-x-reverse));
1853
- margin-left: calc(0px * calc(1 - var(--tw-space-x-reverse)));
1854
- }
1855
1857
  .space-x-1 > :not([hidden]) ~ :not([hidden]) {
1856
1858
  --tw-space-x-reverse: 0;
1857
1859
  margin-right: calc(0.25rem * var(--tw-space-x-reverse));
@@ -3873,6 +3875,34 @@ video {
3873
3875
  .dark .apexcharts-xaxistooltip-bottom::after {
3874
3876
  border-bottom-color: hsl(var(--border)) !important;
3875
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
+ }
3876
3906
  .file\:-ms-4::file-selector-button {
3877
3907
  margin-inline-start: -1rem;
3878
3908
  }
@@ -6939,6 +6969,10 @@ video {
6939
6969
  display: none;
6940
6970
  }
6941
6971
 
6972
+ .xl\:grid-cols-4 {
6973
+ grid-template-columns: repeat(4, minmax(0, 1fr));
6974
+ }
6975
+
6942
6976
  .xl\:grid-cols-6 {
6943
6977
  grid-template-columns: repeat(6, minmax(0, 1fr));
6944
6978
  }
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.312",
4
+ "version": "0.8.314",
5
5
  "publishConfig": {
6
6
  "access": "public",
7
7
  "provenance": false