@pagamio/frontend-commons-lib 0.8.367 → 0.8.368
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/components/ui/FilterComponent.d.ts +1 -1
- package/lib/components/ui/FilterComponent.js +19 -1
- package/lib/pagamio-table/data-table/index.d.ts +1 -1
- package/lib/pagamio-table/data-table/index.js +10 -2
- package/lib/pagamio-table/data-table/types.d.ts +7 -1
- package/lib/styles.css +15 -0
- package/package.json +1 -1
|
@@ -4,7 +4,7 @@ type FilterValue = string | string[] | Date | null | undefined;
|
|
|
4
4
|
interface FilterDefinition {
|
|
5
5
|
name: string;
|
|
6
6
|
placeholder?: string;
|
|
7
|
-
type?: 'select' | 'multi-select' | 'date' | 'date-range';
|
|
7
|
+
type?: 'select' | 'multi-select' | 'date' | 'date-range' | 'amount';
|
|
8
8
|
options?: Array<{
|
|
9
9
|
label: string;
|
|
10
10
|
value: string;
|
|
@@ -12,6 +12,13 @@ import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '.
|
|
|
12
12
|
const FilterComponent = ({ filters, selectedFilters, showApplyFilterButton = true, showClearFilters, searctInputPlaceHolder = 'Search...', showApplyFilters = true, showSearch = false, searchQuery = '', children, isNarrow, handleFilterChange, handleApplyFilters, resetFilters, onSearch = () => { }, }) => {
|
|
13
13
|
const hasSelectedActiveFilters = Object.entries(selectedFilters).some(([key, v]) => !isDefaultFilterValue(v, key));
|
|
14
14
|
const shouldShowActionButtons = hasSelectedActiveFilters || (showSearch && searchQuery.length > 0);
|
|
15
|
+
const normalizeAmountValue = (input) => {
|
|
16
|
+
const cleaned = input.replace(/[^0-9.,]/g, '').replace(/,/g, '.');
|
|
17
|
+
const [whole, ...fractionParts] = cleaned.split('.');
|
|
18
|
+
if (fractionParts.length === 0)
|
|
19
|
+
return whole;
|
|
20
|
+
return `${whole}.${fractionParts.join('')}`;
|
|
21
|
+
};
|
|
15
22
|
const parseDateValue = (value) => {
|
|
16
23
|
if (!value)
|
|
17
24
|
return null;
|
|
@@ -66,6 +73,17 @@ const FilterComponent = ({ filters, selectedFilters, showApplyFilterButton = tru
|
|
|
66
73
|
if (type === 'multi-select') {
|
|
67
74
|
return (_jsx(MultiSelect, { options: Array.isArray(options) ? options : [], placeholder: filter.placeholder ?? `Select ${name}`, value: value || [], onChange: (val) => handleFilterChange(name, val), className: "w-full" }));
|
|
68
75
|
}
|
|
76
|
+
if (type === 'amount') {
|
|
77
|
+
const currentValue = typeof value === 'string' ? value : '';
|
|
78
|
+
return (_jsxs("div", { className: "relative w-full", children: [_jsx("span", { className: "pointer-events-none absolute left-3 top-1/2 -translate-y-1/2 text-sm text-muted-foreground", "aria-hidden": "true", children: "R" }), _jsx("input", { type: "text", inputMode: "decimal", value: currentValue, onChange: (event) => handleFilterChange(name, normalizeAmountValue(event.target.value)), onKeyDown: (event) => {
|
|
79
|
+
if (event.key === 'Enter') {
|
|
80
|
+
handleApplyFilters();
|
|
81
|
+
}
|
|
82
|
+
else if (event.key === 'Escape') {
|
|
83
|
+
handleFilterChange(name, '');
|
|
84
|
+
}
|
|
85
|
+
}, placeholder: filter.placeholder ?? 'Amount', "aria-label": filter.placeholder ?? name, className: cn('h-9 w-full rounded-md border border-border bg-background pl-8 pr-9 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') }), !isDefaultFilterValue(currentValue) && (_jsx("button", { type: "button", className: cn('absolute right-2 top-1/2 -translate-y-1/2 rounded-sm px-1 text-base leading-none text-muted-foreground', 'hover:text-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring'), onClick: () => handleFilterChange(name, ''), "aria-label": "Clear amount filter", children: "\u00D7" }))] }));
|
|
86
|
+
}
|
|
69
87
|
// Default: select — always keep controlled via sentinel to avoid
|
|
70
88
|
// Radix switching to uncontrolled mode when value is cleared.
|
|
71
89
|
const SENTINEL = '__all__';
|
|
@@ -76,7 +94,7 @@ const FilterComponent = ({ filters, selectedFilters, showApplyFilterButton = tru
|
|
|
76
94
|
return (
|
|
77
95
|
// Fluid width: full width on mobile, fluid 180–260px on wider
|
|
78
96
|
// viewports so filters share the row evenly and shrink under pressure.
|
|
79
|
-
_jsx("div", { className:
|
|
97
|
+
_jsx("div", { className: cn('w-full sm:flex-1 min-w-0', type === 'amount' ? 'sm:min-w-[150px] sm:max-w-[220px]' : 'sm:min-w-[180px] sm:max-w-[260px]'), children: renderFilterInput() }, name));
|
|
80
98
|
}), 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 })] }));
|
|
81
99
|
};
|
|
82
100
|
export default FilterComponent;
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import type { PagamioTableProps } from './types';
|
|
2
|
-
declare const PagamioTable: <T extends Record<string, any>>({ columns, data, isLoading, isFetching, rowCount, sorting, pagination, filtering, search, onRowClick, rowClassName, expandable, renderDetailPanel, toolbar, toolbarMode, fetchAllData, 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, }: PagamioTableProps<T>) => import("react/jsx-runtime").JSX.Element;
|
|
2
|
+
declare const PagamioTable: <T extends Record<string, any>>({ columns, data, isLoading, isFetching, rowCount, sorting, pagination, filtering, search, onRowClick, rowClassName, expandable, renderDetailPanel, toolbar, toolbarMode, fetchAllData, 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, disableInternalTableScroll, defaultColumn, mantineTableOptions, }: PagamioTableProps<T>) => import("react/jsx-runtime").JSX.Element;
|
|
3
3
|
export default PagamioTable;
|
|
@@ -101,8 +101,11 @@ function CustomToolbar({ filters, appliedFilters, onFilterChange, onApply, onCle
|
|
|
101
101
|
(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))] }) }));
|
|
102
102
|
}
|
|
103
103
|
// ─── PagamioTable Component ──────────────────────────────────────────
|
|
104
|
-
const PagamioTable = ({ columns, data, isLoading = false, isFetching = false, rowCount, sorting, pagination, filtering, search, onRowClick, rowClassName, expandable = false, renderDetailPanel, toolbar, toolbarMode = 'custom', fetchAllData, 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, }) => {
|
|
104
|
+
const PagamioTable = ({ columns, data, isLoading = false, isFetching = false, rowCount, sorting, pagination, filtering, search, onRowClick, rowClassName, expandable = false, renderDetailPanel, toolbar, toolbarMode = 'custom', fetchAllData, 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, disableInternalTableScroll, defaultColumn, mantineTableOptions, }) => {
|
|
105
105
|
const [expanded, setExpanded] = useState({});
|
|
106
|
+
const externalState = mantineTableOptions?.state;
|
|
107
|
+
const { state: ignoredState, ...mantineOptionsWithoutState } = mantineTableOptions ?? {};
|
|
108
|
+
void ignoredState;
|
|
106
109
|
const tableRef = useRef(null);
|
|
107
110
|
// ── Internal max-height ─────────────────────────────────────────────
|
|
108
111
|
// The mantine table container is height-capped to `viewportHeight - tableTop`
|
|
@@ -138,6 +141,10 @@ const PagamioTable = ({ columns, data, isLoading = false, isFetching = false, ro
|
|
|
138
141
|
const mrtContainer = el.querySelector('.mrt-table-container');
|
|
139
142
|
if (!mrtContainer)
|
|
140
143
|
return;
|
|
144
|
+
if (disableInternalTableScroll) {
|
|
145
|
+
mrtContainer.style.removeProperty('max-height');
|
|
146
|
+
return;
|
|
147
|
+
}
|
|
141
148
|
// If a parent is already handling the scroll, let the table render at
|
|
142
149
|
// its natural height — the user gets one continuous page scroll.
|
|
143
150
|
if (!tableShouldOwnScroll(el)) {
|
|
@@ -244,6 +251,7 @@ const PagamioTable = ({ columns, data, isLoading = false, isFetching = false, ro
|
|
|
244
251
|
pagination: paginationState,
|
|
245
252
|
sorting: sortingState,
|
|
246
253
|
expanded,
|
|
254
|
+
...(externalState ?? {}),
|
|
247
255
|
},
|
|
248
256
|
// Manual modes (server-side)
|
|
249
257
|
manualPagination: hasServerPagination,
|
|
@@ -328,7 +336,7 @@ const PagamioTable = ({ columns, data, isLoading = false, isFetching = false, ro
|
|
|
328
336
|
className: rowClassName,
|
|
329
337
|
}),
|
|
330
338
|
// Escape hatch — OCP: consumer can override anything (spread last)
|
|
331
|
-
...
|
|
339
|
+
...mantineOptionsWithoutState,
|
|
332
340
|
});
|
|
333
341
|
// ── Toolbar rendering ──────────────────────────────────────────────
|
|
334
342
|
const showCustomToolbar = toolbarMode === 'custom' && (!!toolbar || !!search || !!filtering);
|
|
@@ -28,7 +28,7 @@ export interface SortConfig {
|
|
|
28
28
|
export interface BaseFilter {
|
|
29
29
|
columnKey: string;
|
|
30
30
|
label?: string;
|
|
31
|
-
type?: 'select' | 'multi-select' | 'date' | 'date-range' | 'range' | 'boolean';
|
|
31
|
+
type?: 'select' | 'multi-select' | 'date' | 'date-range' | 'amount' | 'range' | 'boolean';
|
|
32
32
|
options?: Array<{
|
|
33
33
|
label: string;
|
|
34
34
|
value: string;
|
|
@@ -209,6 +209,11 @@ export interface PagamioTableProps<T extends Record<string, any>> {
|
|
|
209
209
|
renderTopToolbarCustomActions?: MRT_TableOptions<T>['renderTopToolbarCustomActions'];
|
|
210
210
|
renderBottomToolbarCustomActions?: MRT_TableOptions<T>['renderBottomToolbarCustomActions'];
|
|
211
211
|
layoutMode?: 'semantic' | 'grid';
|
|
212
|
+
/**
|
|
213
|
+
* When true, PagamioTable will not cap `.mrt-table-container` height.
|
|
214
|
+
* Use this when the page itself should own vertical scrolling.
|
|
215
|
+
*/
|
|
216
|
+
disableInternalTableScroll?: boolean;
|
|
212
217
|
defaultColumn?: Partial<MRT_ColumnDef<T>>;
|
|
213
218
|
mantineTableOptions?: Partial<MRT_TableOptions<T>>;
|
|
214
219
|
}
|
|
@@ -259,6 +264,7 @@ export interface UsePagamioTableConfig<T extends BaseEntity> {
|
|
|
259
264
|
rowClassName?: string;
|
|
260
265
|
expandable?: boolean;
|
|
261
266
|
renderDetailPanel?: PagamioTableProps<T>['renderDetailPanel'];
|
|
267
|
+
disableInternalTableScroll?: boolean;
|
|
262
268
|
}
|
|
263
269
|
export interface UsePagamioTableReturn<T extends BaseEntity> {
|
|
264
270
|
tableProps: PagamioTableProps<T>;
|
package/lib/styles.css
CHANGED
|
@@ -2872,6 +2872,10 @@ video {
|
|
|
2872
2872
|
padding-left: 0px;
|
|
2873
2873
|
padding-right: 0px;
|
|
2874
2874
|
}
|
|
2875
|
+
.px-1 {
|
|
2876
|
+
padding-left: 0.25rem;
|
|
2877
|
+
padding-right: 0.25rem;
|
|
2878
|
+
}
|
|
2875
2879
|
.px-1\.5 {
|
|
2876
2880
|
padding-left: 0.375rem;
|
|
2877
2881
|
padding-right: 0.375rem;
|
|
@@ -3011,6 +3015,9 @@ video {
|
|
|
3011
3015
|
.pr-8 {
|
|
3012
3016
|
padding-right: 2rem;
|
|
3013
3017
|
}
|
|
3018
|
+
.pr-9 {
|
|
3019
|
+
padding-right: 2.25rem;
|
|
3020
|
+
}
|
|
3014
3021
|
.ps-5 {
|
|
3015
3022
|
padding-inline-start: 1.25rem;
|
|
3016
3023
|
}
|
|
@@ -6545,6 +6552,10 @@ video {
|
|
|
6545
6552
|
width: auto;
|
|
6546
6553
|
}
|
|
6547
6554
|
|
|
6555
|
+
.sm\:min-w-\[150px\] {
|
|
6556
|
+
min-width: 150px;
|
|
6557
|
+
}
|
|
6558
|
+
|
|
6548
6559
|
.sm\:min-w-\[180px\] {
|
|
6549
6560
|
min-width: 180px;
|
|
6550
6561
|
}
|
|
@@ -6553,6 +6564,10 @@ video {
|
|
|
6553
6564
|
min-width: 200px;
|
|
6554
6565
|
}
|
|
6555
6566
|
|
|
6567
|
+
.sm\:max-w-\[220px\] {
|
|
6568
|
+
max-width: 220px;
|
|
6569
|
+
}
|
|
6570
|
+
|
|
6556
6571
|
.sm\:max-w-\[260px\] {
|
|
6557
6572
|
max-width: 260px;
|
|
6558
6573
|
}
|
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.368",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public",
|
|
7
7
|
"provenance": false
|