@joelbarron/react-web-dev-kit 0.1.5 → 0.1.6

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.
Files changed (81) hide show
  1. package/dist/auth/fuse/fuseIntegration.d.ts +2 -0
  2. package/dist/auth/fuse/fuseIntegration.d.ts.map +1 -1
  3. package/dist/auth/fuse/fuseIntegration.js +18 -0
  4. package/dist/auth/social/providerAuth.d.ts.map +1 -1
  5. package/dist/auth/social/providerAuth.js +12 -4
  6. package/dist/config/createConfig.d.ts.map +1 -1
  7. package/dist/config/createConfig.js +38 -1
  8. package/dist/config/defaults.js +1 -1
  9. package/dist/core/dialogs/JBConfirmDialog.d.ts +15 -0
  10. package/dist/core/dialogs/JBConfirmDialog.d.ts.map +1 -0
  11. package/dist/core/dialogs/JBConfirmDialog.js +6 -0
  12. package/dist/core/dialogs/index.d.ts +2 -0
  13. package/dist/core/dialogs/index.d.ts.map +1 -0
  14. package/dist/core/dialogs/index.js +1 -0
  15. package/dist/core/index.d.ts +4 -0
  16. package/dist/core/index.d.ts.map +1 -0
  17. package/dist/core/index.js +3 -0
  18. package/dist/core/layout/JBContentContainer.d.ts +27 -0
  19. package/dist/core/layout/JBContentContainer.d.ts.map +1 -0
  20. package/dist/core/layout/JBContentContainer.js +42 -0
  21. package/dist/core/layout/JBFormHeader.d.ts +3 -0
  22. package/dist/core/layout/JBFormHeader.d.ts.map +1 -0
  23. package/dist/core/layout/JBFormHeader.js +156 -0
  24. package/dist/core/layout/index.d.ts +3 -0
  25. package/dist/core/layout/index.d.ts.map +1 -0
  26. package/dist/core/layout/index.js +2 -0
  27. package/dist/core/skeletons/JBFormContentSkeleton.d.ts +5 -0
  28. package/dist/core/skeletons/JBFormContentSkeleton.d.ts.map +1 -0
  29. package/dist/core/skeletons/JBFormContentSkeleton.js +12 -0
  30. package/dist/core/skeletons/JBFormHeaderSkeleton.d.ts +6 -0
  31. package/dist/core/skeletons/JBFormHeaderSkeleton.d.ts.map +1 -0
  32. package/dist/core/skeletons/JBFormHeaderSkeleton.js +19 -0
  33. package/dist/core/skeletons/index.d.ts +3 -0
  34. package/dist/core/skeletons/index.d.ts.map +1 -0
  35. package/dist/core/skeletons/index.js +2 -0
  36. package/dist/forms/index.d.ts +1 -0
  37. package/dist/forms/index.d.ts.map +1 -1
  38. package/dist/forms/index.js +1 -0
  39. package/dist/forms/zod.d.ts +4 -0
  40. package/dist/forms/zod.d.ts.map +1 -0
  41. package/dist/forms/zod.js +9 -0
  42. package/dist/grid/JBFormHeader.d.ts +2 -0
  43. package/dist/grid/JBFormHeader.d.ts.map +1 -0
  44. package/dist/grid/JBFormHeader.js +1 -0
  45. package/dist/grid/JBGrid.d.ts.map +1 -1
  46. package/dist/grid/JBGrid.js +210 -18
  47. package/dist/grid/JBGridHeader.d.ts.map +1 -1
  48. package/dist/grid/JBGridHeader.js +84 -15
  49. package/dist/grid/JBGridLoading.d.ts +9 -0
  50. package/dist/grid/JBGridLoading.d.ts.map +1 -0
  51. package/dist/grid/JBGridLoading.js +14 -0
  52. package/dist/grid/JBGridProviders.d.ts +3 -0
  53. package/dist/grid/JBGridProviders.d.ts.map +1 -1
  54. package/dist/grid/JBGridProviders.js +16 -0
  55. package/dist/grid/JBGridSkeleton.d.ts +7 -0
  56. package/dist/grid/JBGridSkeleton.d.ts.map +1 -0
  57. package/dist/grid/JBGridSkeleton.js +6 -0
  58. package/dist/grid/defaults.d.ts +4 -0
  59. package/dist/grid/defaults.d.ts.map +1 -0
  60. package/dist/grid/defaults.js +27 -0
  61. package/dist/grid/index.d.ts +3 -0
  62. package/dist/grid/index.d.ts.map +1 -1
  63. package/dist/grid/index.js +3 -0
  64. package/dist/grid/types.d.ts +110 -3
  65. package/dist/grid/types.d.ts.map +1 -1
  66. package/dist/index.d.ts +1 -0
  67. package/dist/index.d.ts.map +1 -1
  68. package/dist/index.js +1 -0
  69. package/dist/query/index.d.ts +1 -0
  70. package/dist/query/index.d.ts.map +1 -1
  71. package/dist/query/index.js +1 -0
  72. package/dist/query/types.d.ts +7 -0
  73. package/dist/query/types.d.ts.map +1 -0
  74. package/dist/query/types.js +1 -0
  75. package/dist/utils/errors.d.ts +10 -0
  76. package/dist/utils/errors.d.ts.map +1 -0
  77. package/dist/utils/errors.js +55 -0
  78. package/dist/utils/index.d.ts +1 -0
  79. package/dist/utils/index.d.ts.map +1 -1
  80. package/dist/utils/index.js +1 -0
  81. package/package.json +7 -1
@@ -1,26 +1,48 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
2
  import { CustomPaging, FilteringState, GroupingState, IntegratedFiltering, IntegratedGrouping, IntegratedSelection, IntegratedSorting, IntegratedSummary, PagingState, SearchState, SelectionState, SortingState, SummaryState } from '@devexpress/dx-react-grid';
3
- import { DragDropProvider, Grid, GroupingPanel, PagingPanel, Table, TableColumnResizing, TableFilterRow, TableGroupRow, TableHeaderRow, TableSelection, TableSummaryRow, Toolbar, } from '@devexpress/dx-react-grid-material-ui';
4
- import { useEffect, useMemo, useState } from 'react';
5
- import { JBBooleanTypeProvider, JBCurrencyTypeProvider, JBImageTypeProvider } from './JBGridProviders';
6
- const DEFAULT_PAGE_SIZES = [10, 30, 50, 100, 200, 500, 1000];
3
+ import { DragDropProvider, Grid, GroupingPanel, PagingPanel, Table, TableColumnResizing, TableFilterRow, TableGroupRow, TableHeaderRow, TableSelection, TableSummaryRow, Toolbar, VirtualTable, } from '@devexpress/dx-react-grid-material-ui';
4
+ import { Box, CircularProgress, TablePagination, Typography } from '@mui/material';
5
+ import { useEffect, useMemo, useRef, useState } from 'react';
6
+ import { resolveGridDefaults } from './defaults';
7
+ import { JBGridLoading } from './JBGridLoading';
8
+ import { JBBooleanTypeProvider, JBCurrencyTypeProvider, JBDateTypeProvider, JBImageTypeProvider } from './JBGridProviders';
7
9
  export function JBGrid(props) {
8
- const { gridConfig, service, rows: controlledRows, searchText, onSearchTextChange, onRowSelected, loadData, loadingComponent, getRowId } = props;
9
- const { defaults } = gridConfig;
10
- const pageSizes = defaults.pageSizes ?? DEFAULT_PAGE_SIZES;
10
+ let error = props.error;
11
+ error = error ? 'No se pudo cargar el listado.' : undefined;
12
+ const { gridConfig, service, rows: controlledRows, totalCount: controlledTotalCount, loading: controlledLoading, currentPage: controlledCurrentPage, onCurrentPageChange, pageSize: controlledPageSize, onPageSizeChange, searchText, onSearchTextChange, onRowSelected, loadData, loadingComponent, getRowId, paginationPosition = 'top', stickyPagination = true, height = '100%', stickyHeader = true, infiniteScroll = false, hasMore = false, isLoadingMore = false, loadMoreThreshold = 200, onLoadMore } = props;
13
+ const defaults = resolveGridDefaults(gridConfig.defaults);
14
+ const pageSizes = defaults.pageSizes;
15
+ const virtualScrolling = defaults.virtualScrolling;
16
+ const rootRef = useRef(null);
17
+ const [containerHeight, setContainerHeight] = useState(defaults.virtualTableHeight);
18
+ const resolvedVirtualTableHeight = defaults.virtualTableHeightMode === 'fill'
19
+ ? Math.max(240, Math.floor(containerHeight * defaults.virtualTableHeightRatio))
20
+ : defaults.virtualTableHeight;
21
+ const isControlledPaging = controlledCurrentPage !== undefined && controlledPageSize !== undefined;
11
22
  const [rows, setRows] = useState(controlledRows ?? []);
12
23
  const [totalCount, setTotalCount] = useState(0);
13
- const [pageSize, setPageSize] = useState(defaults.pageSize || 10);
14
- const [currentPage, setCurrentPage] = useState(0);
15
- const [loading, setLoading] = useState(false);
24
+ const [internalPageSize, setInternalPageSize] = useState(defaults.pageSize);
25
+ const [internalCurrentPage, setInternalCurrentPage] = useState(0);
26
+ const [internalLoading, setInternalLoading] = useState(false);
16
27
  const [lastQuery, setLastQuery] = useState('');
17
28
  const [selection, setSelection] = useState([]);
29
+ const currentPage = isControlledPaging ? controlledCurrentPage : internalCurrentPage;
30
+ const pageSize = isControlledPaging ? controlledPageSize : internalPageSize;
31
+ const loading = controlledLoading ?? internalLoading;
18
32
  useEffect(() => {
19
33
  if (controlledRows) {
20
34
  setRows(controlledRows);
21
- setTotalCount(controlledRows.length);
22
35
  }
23
36
  }, [controlledRows]);
37
+ useEffect(() => {
38
+ if (controlledTotalCount !== undefined) {
39
+ setTotalCount(controlledTotalCount);
40
+ return;
41
+ }
42
+ if (controlledRows) {
43
+ setTotalCount(controlledRows.length);
44
+ }
45
+ }, [controlledRows, controlledTotalCount]);
24
46
  const computeQueryString = useMemo(() => () => `pageSize=${pageSize}&skip=${pageSize * currentPage}&terms=${searchText || ''}`, [currentPage, pageSize, searchText]);
25
47
  useEffect(() => {
26
48
  if (controlledRows)
@@ -33,7 +55,7 @@ export function JBGrid(props) {
33
55
  setRows,
34
56
  setTotalCount,
35
57
  setLastQuery,
36
- setLoading,
58
+ setLoading: setInternalLoading,
37
59
  getQueryString: computeQueryString,
38
60
  currentPage,
39
61
  pageSize,
@@ -47,14 +69,14 @@ export function JBGrid(props) {
47
69
  if (queryString === lastQuery || loading)
48
70
  return;
49
71
  try {
50
- setLoading(true);
72
+ setInternalLoading(true);
51
73
  const response = await service.list(currentPage, pageSize, searchText);
52
74
  setRows(response?.data?.results ?? []);
53
75
  setTotalCount(response?.data?.count ?? 0);
54
76
  setLastQuery(queryString);
55
77
  }
56
78
  finally {
57
- setLoading(false);
79
+ setInternalLoading(false);
58
80
  }
59
81
  };
60
82
  void execute();
@@ -69,6 +91,20 @@ export function JBGrid(props) {
69
91
  searchText,
70
92
  service
71
93
  ]);
94
+ const handleCurrentPageChange = (nextPage) => {
95
+ if (isControlledPaging) {
96
+ onCurrentPageChange?.(nextPage);
97
+ return;
98
+ }
99
+ setInternalCurrentPage(nextPage);
100
+ };
101
+ const handlePageSizeChange = (nextPageSize) => {
102
+ if (isControlledPaging) {
103
+ onPageSizeChange?.(nextPageSize);
104
+ return;
105
+ }
106
+ setInternalPageSize(nextPageSize);
107
+ };
72
108
  const handleSelection = (nextSelection) => {
73
109
  const lastSelected = nextSelection.find((selected) => selection.indexOf(selected) === -1);
74
110
  if (lastSelected === undefined) {
@@ -76,8 +112,7 @@ export function JBGrid(props) {
76
112
  return;
77
113
  }
78
114
  setSelection([lastSelected]);
79
- const selectedIndex = typeof lastSelected === 'number' ? lastSelected : Number.parseInt(String(lastSelected), 10);
80
- const selectedRow = rows[selectedIndex];
115
+ const selectedRow = rows.find((row) => rowIdGetter(row) === lastSelected);
81
116
  if (selectedRow && onRowSelected) {
82
117
  onRowSelected(selectedRow);
83
118
  }
@@ -85,5 +120,162 @@ export function JBGrid(props) {
85
120
  const rowIdGetter = getRowId
86
121
  ? (row) => getRowId(row)
87
122
  : (row) => row.id;
88
- return (_jsx("div", { style: { width: '100%', height: '100%' }, children: loading ? (_jsx("div", { children: loadingComponent ?? _jsx("span", { children: "Loading..." }) })) : (_jsxs(Grid, { rows: rows, columns: gridConfig.columns, getRowId: rowIdGetter, children: [_jsx(SortingState, { defaultSorting: defaults.sorting }), _jsx(PagingState, { currentPage: currentPage, onCurrentPageChange: setCurrentPage, pageSize: pageSize, onPageSizeChange: setPageSize }), _jsx(GroupingState, { defaultGrouping: defaults.grouping, defaultExpandedGroups: defaults.expandedGroups }), _jsx(SummaryState, { totalItems: gridConfig.totalSummaryItems, groupItems: gridConfig.groupSummaryItems }), _jsx(FilteringState, { defaultFilters: defaults.filters }), _jsx(SearchState, { value: searchText, onValueChange: onSearchTextChange }), _jsx(SelectionState, { selection: selection, onSelectionChange: handleSelection }), defaults.allowGrouping !== false ? _jsx(IntegratedGrouping, {}) : null, _jsx(IntegratedFiltering, {}), _jsx(IntegratedSorting, {}), _jsx(IntegratedSelection, {}), _jsx(IntegratedSummary, {}), _jsx(DragDropProvider, {}), gridConfig.booleanColumns?.length ? (_jsx(JBBooleanTypeProvider, { for: gridConfig.booleanColumns })) : null, gridConfig.imageColumns?.length ? _jsx(JBImageTypeProvider, { for: gridConfig.imageColumns }) : null, gridConfig.currencyColumns?.length ? (_jsx(JBCurrencyTypeProvider, { for: gridConfig.currencyColumns })) : null, _jsx(Table, { columnExtensions: gridConfig.tableColumnExtensions }), defaults.allowColumnResizing !== false ? (_jsx(TableColumnResizing, { defaultColumnWidths: gridConfig.columnsWidths })) : null, defaults.allowSelection !== false ? (_jsx(TableSelection, { showSelectAll: defaults.allowSelectAll, showSelectionColumn: defaults.showSelectionColumn, selectByRowClick: true, highlightRow: true })) : null, _jsx(TableHeaderRow, { showSortingControls: defaults.allowSorting !== false }), defaults.allowFiltering ? (_jsx(TableFilterRow, { showFilterSelector: defaults.advancedFiltering })) : null, _jsx(PagingPanel, { pageSizes: pageSizes }), defaults.allowGrouping !== false ? (_jsx(TableGroupRow, { showColumnsWhenGrouped: false })) : null, _jsx(Toolbar, {}), defaults.allowGrouping !== false ? _jsx(GroupingPanel, { showSortingControls: true }) : null, _jsx(TableSummaryRow, {}), _jsx(CustomPaging, { totalCount: totalCount })] })) }));
123
+ const showTopPagination = paginationPosition === 'top' || paginationPosition === 'both';
124
+ const showBottomPagination = paginationPosition === 'bottom' || paginationPosition === 'both';
125
+ const showPaging = paginationPosition !== 'none';
126
+ const handleRowsPerPageChange = (event) => {
127
+ const nextPageSize = Number.parseInt(event.target.value, 10);
128
+ handlePageSizeChange(nextPageSize);
129
+ handleCurrentPageChange(0);
130
+ };
131
+ useEffect(() => {
132
+ if (!virtualScrolling || defaults.virtualTableHeightMode !== 'fill' || !rootRef.current)
133
+ return;
134
+ const node = rootRef.current;
135
+ const observer = new ResizeObserver((entries) => {
136
+ const entry = entries[0];
137
+ if (!entry)
138
+ return;
139
+ setContainerHeight(entry.contentRect.height);
140
+ });
141
+ observer.observe(node);
142
+ return () => observer.disconnect();
143
+ }, [defaults.virtualTableHeightMode, virtualScrolling]);
144
+ useEffect(() => {
145
+ if (!virtualScrolling || !infiniteScroll || !onLoadMore || !rootRef.current)
146
+ return;
147
+ const tableContainer = rootRef.current.querySelector('.MuiTableContainer-root');
148
+ if (!tableContainer)
149
+ return;
150
+ const handleScroll = () => {
151
+ const target = tableContainer;
152
+ const distanceToBottom = target.scrollHeight - (target.scrollTop + target.clientHeight);
153
+ if (distanceToBottom <= loadMoreThreshold && hasMore && !isLoadingMore) {
154
+ onLoadMore();
155
+ }
156
+ };
157
+ tableContainer.addEventListener('scroll', handleScroll, { passive: true });
158
+ return () => tableContainer.removeEventListener('scroll', handleScroll);
159
+ }, [hasMore, infiniteScroll, isLoadingMore, loadMoreThreshold, onLoadMore, rows.length, virtualScrolling]);
160
+ useEffect(() => {
161
+ if (!rootRef.current)
162
+ return;
163
+ const contentWrapper = rootRef.current.closest('.FusePageCarded-contentWrapper');
164
+ const contentNode = rootRef.current.closest('.FusePageCarded-content');
165
+ if (!contentWrapper)
166
+ return;
167
+ const lockCount = Number.parseInt(contentWrapper.dataset.jbGridLockCount ?? '0', 10) || 0;
168
+ contentWrapper.dataset.jbGridLockCount = String(lockCount + 1);
169
+ if (lockCount === 0) {
170
+ const prevWrapperOverflow = contentWrapper.style.overflow;
171
+ const prevWrapperScrollbarWidth = contentWrapper.style.scrollbarWidth;
172
+ const prevContentOverflow = contentNode?.style.overflow ?? '';
173
+ const prevContentHeight = contentNode?.style.height ?? '';
174
+ const prevContentMinHeight = contentNode?.style.minHeight ?? '';
175
+ contentWrapper.dataset.jbGridPrevOverflow = prevWrapperOverflow;
176
+ contentWrapper.dataset.jbGridPrevScrollbarWidth = prevWrapperScrollbarWidth ?? '';
177
+ contentWrapper.dataset.jbGridPrevContentOverflow = prevContentOverflow;
178
+ contentWrapper.dataset.jbGridPrevContentHeight = prevContentHeight;
179
+ contentWrapper.dataset.jbGridPrevContentMinHeight = prevContentMinHeight;
180
+ contentWrapper.style.overflow = 'hidden';
181
+ contentWrapper.style.scrollbarWidth = 'none';
182
+ // Hide perfect-scrollbar rails when present in Fuse wrappers.
183
+ const rails = contentWrapper.querySelectorAll('.ps__rail-x, .ps__rail-y');
184
+ rails.forEach((rail) => {
185
+ rail.dataset.jbGridPrevDisplay = rail.style.display ?? '';
186
+ rail.style.display = 'none';
187
+ });
188
+ if (contentNode) {
189
+ contentNode.style.overflow = 'hidden';
190
+ contentNode.style.height = '100%';
191
+ contentNode.style.minHeight = '0';
192
+ }
193
+ }
194
+ return () => {
195
+ const currentCount = Number.parseInt(contentWrapper.dataset.jbGridLockCount ?? '1', 10) || 1;
196
+ const nextCount = Math.max(0, currentCount - 1);
197
+ contentWrapper.dataset.jbGridLockCount = String(nextCount);
198
+ if (nextCount > 0)
199
+ return;
200
+ contentWrapper.style.overflow = contentWrapper.dataset.jbGridPrevOverflow ?? '';
201
+ contentWrapper.style.scrollbarWidth =
202
+ contentWrapper.dataset.jbGridPrevScrollbarWidth ?? '';
203
+ const rails = contentWrapper.querySelectorAll('.ps__rail-x, .ps__rail-y');
204
+ rails.forEach((rail) => {
205
+ rail.style.display = rail.dataset.jbGridPrevDisplay ?? '';
206
+ delete rail.dataset.jbGridPrevDisplay;
207
+ });
208
+ if (contentNode) {
209
+ contentNode.style.overflow = contentWrapper.dataset.jbGridPrevContentOverflow ?? '';
210
+ contentNode.style.height = contentWrapper.dataset.jbGridPrevContentHeight ?? '';
211
+ contentNode.style.minHeight = contentWrapper.dataset.jbGridPrevContentMinHeight ?? '';
212
+ }
213
+ delete contentWrapper.dataset.jbGridPrevOverflow;
214
+ delete contentWrapper.dataset.jbGridPrevScrollbarWidth;
215
+ delete contentWrapper.dataset.jbGridPrevContentOverflow;
216
+ delete contentWrapper.dataset.jbGridPrevContentHeight;
217
+ delete contentWrapper.dataset.jbGridPrevContentMinHeight;
218
+ };
219
+ }, []);
220
+ return (_jsx(Box, { className: "jb-grid-root", ref: rootRef, sx: {
221
+ width: '100%',
222
+ height,
223
+ minHeight: 0,
224
+ overflow: virtualScrolling ? 'hidden !important' : 'auto',
225
+ ...(!virtualScrolling && stickyHeader
226
+ ? {
227
+ '& .MuiTableCell-head': {
228
+ position: 'sticky',
229
+ top: 0,
230
+ zIndex: 2,
231
+ backgroundColor: 'background.paper'
232
+ }
233
+ }
234
+ : undefined),
235
+ ...(virtualScrolling
236
+ ? {
237
+ '& .dx-rg-grid': {
238
+ height: '100%',
239
+ minHeight: 0
240
+ },
241
+ '& .MuiTableContainer-root': {
242
+ overflowY: 'auto !important',
243
+ overflowX: 'auto',
244
+ overscrollBehavior: 'contain',
245
+ maxHeight: `${resolvedVirtualTableHeight}px`
246
+ }
247
+ }
248
+ : undefined)
249
+ }, children: error ? (_jsx(Box, { sx: { p: 2 }, children: typeof error === 'string' ? _jsx(Typography, { color: "error.main", children: error }) : error })) : loading ? (_jsx("div", { children: loadingComponent ?? _jsx(JBGridLoading, { message: "" }) })) : rows.length === 0 ? (_jsx(Box, { sx: {
250
+ width: '100%',
251
+ minHeight: 280,
252
+ display: 'flex',
253
+ alignItems: 'center',
254
+ justifyContent: 'center',
255
+ textAlign: 'center',
256
+ p: 3
257
+ }, children: props.emptyComponent ?? (_jsx(Typography, { variant: "h5", sx: { fontWeight: 600 }, color: "text.secondary", children: "No hay resultados." })) })) : (_jsxs(_Fragment, { children: [showTopPagination ? (_jsx(Box, { sx: {
258
+ display: 'flex',
259
+ justifyContent: 'flex-end',
260
+ px: 1,
261
+ ...(stickyPagination
262
+ ? {
263
+ position: 'sticky',
264
+ top: 0,
265
+ zIndex: 3,
266
+ backgroundColor: 'background.paper',
267
+ borderBottom: '1px solid',
268
+ borderColor: 'divider'
269
+ }
270
+ : undefined)
271
+ }, children: _jsx(TablePagination, { component: "div", count: totalCount, page: currentPage, onPageChange: (_, nextPage) => handleCurrentPageChange(nextPage), rowsPerPage: pageSize, onRowsPerPageChange: handleRowsPerPageChange, rowsPerPageOptions: pageSizes }) })) : null, _jsxs(Grid, { rows: rows, columns: gridConfig.columns, getRowId: rowIdGetter, children: [_jsx(SortingState, { defaultSorting: defaults.sorting }), showPaging ? (_jsx(PagingState, { currentPage: currentPage, onCurrentPageChange: handleCurrentPageChange, pageSize: pageSize, onPageSizeChange: handlePageSizeChange })) : null, _jsx(GroupingState, { defaultGrouping: defaults.grouping, defaultExpandedGroups: defaults.expandedGroups }), _jsx(SummaryState, { totalItems: gridConfig.totalSummaryItems, groupItems: gridConfig.groupSummaryItems }), _jsx(FilteringState, { defaultFilters: defaults.filters }), _jsx(SearchState, { value: searchText, onValueChange: onSearchTextChange }), _jsx(SelectionState, { selection: selection, onSelectionChange: handleSelection }), defaults.allowGrouping !== false ? _jsx(IntegratedGrouping, {}) : null, _jsx(IntegratedFiltering, {}), _jsx(IntegratedSorting, {}), _jsx(IntegratedSelection, {}), _jsx(IntegratedSummary, {}), _jsx(DragDropProvider, {}), gridConfig.booleanColumns?.length ? (_jsx(JBBooleanTypeProvider, { for: gridConfig.booleanColumns })) : null, gridConfig.imageColumns?.length ? _jsx(JBImageTypeProvider, { for: gridConfig.imageColumns }) : null, gridConfig.currencyColumns?.length ? (_jsx(JBCurrencyTypeProvider, { for: gridConfig.currencyColumns })) : null, gridConfig.dateColumns?.length ? _jsx(JBDateTypeProvider, { for: gridConfig.dateColumns }) : null, virtualScrolling ? (_jsx(VirtualTable, { columnExtensions: gridConfig.tableColumnExtensions, estimatedRowHeight: defaults.estimatedRowHeight, height: resolvedVirtualTableHeight })) : (_jsx(Table, { columnExtensions: gridConfig.tableColumnExtensions })), defaults.allowColumnResizing !== false ? (_jsx(TableColumnResizing, { defaultColumnWidths: gridConfig.columnsWidths })) : null, defaults.allowSelection !== false ? (_jsx(TableSelection, { showSelectAll: defaults.allowSelectAll, showSelectionColumn: defaults.showSelectionColumn, selectByRowClick: true, highlightRow: true })) : null, _jsx(TableHeaderRow, { showSortingControls: defaults.allowSorting !== false }), defaults.allowFiltering ? (_jsx(TableFilterRow, { showFilterSelector: defaults.advancedFiltering })) : null, showBottomPagination ? (_jsx(Box, { sx: stickyPagination
272
+ ? {
273
+ position: 'sticky',
274
+ bottom: 0,
275
+ zIndex: 3,
276
+ backgroundColor: 'background.paper',
277
+ borderTop: '1px solid',
278
+ borderColor: 'divider'
279
+ }
280
+ : undefined, children: _jsx(PagingPanel, { pageSizes: pageSizes }) })) : null, defaults.allowGrouping !== false ? (_jsx(TableGroupRow, { showColumnsWhenGrouped: false })) : null, _jsx(Toolbar, {}), defaults.allowGrouping !== false ? _jsx(GroupingPanel, { showSortingControls: true }) : null, _jsx(TableSummaryRow, {}), showPaging ? _jsx(CustomPaging, { totalCount: totalCount }) : null] }), virtualScrolling && infiniteScroll && isLoadingMore ? (_jsx(Box, { sx: { py: 1, display: 'flex', justifyContent: 'center' }, children: _jsx(CircularProgress, { size: 20 }) })) : null] })) }));
89
281
  }
@@ -1 +1 @@
1
- {"version":3,"file":"JBGridHeader.d.ts","sourceRoot":"","sources":["../../src/grid/JBGridHeader.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC;AAE5C,wBAAgB,YAAY,CAAC,KAAK,EAAE,iBAAiB,2CAiEpD"}
1
+ {"version":3,"file":"JBGridHeader.d.ts","sourceRoot":"","sources":["../../src/grid/JBGridHeader.tsx"],"names":[],"mappings":"AAIA,OAAO,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC;AAE5C,wBAAgB,YAAY,CAAC,KAAK,EAAE,iBAAiB,2CAoKpD"}
@@ -1,22 +1,91 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { Box, Button, InputBase, Paper, Typography } from '@mui/material';
3
+ import SearchRoundedIcon from '@mui/icons-material/SearchRounded';
4
+ import AddRoundedIcon from '@mui/icons-material/AddRounded';
3
5
  export function JBGridHeader(props) {
4
- const { title, icon, searchText, onSearchTextChange, searchPlaceholder = 'Search...', allowCreate = true, createButtonLabel = 'Create', onCreateClick, rightContent } = props;
6
+ const { moduleConfig, iconNameRenderer, animated = true, animationDurationMs = 240, animationStaggerMs = 60, animationPreset = 'vertical', breadcrumb, title, subtitle, icon, searchText, onSearchTextChange, searchPlaceholder, allowCreate = true, createButtonLabel, onCreateClick, rightContent } = props;
7
+ const resolvedTitle = title ?? moduleConfig?.texts?.moduleName ?? '';
8
+ const resolvedSubtitle = subtitle ?? moduleConfig?.texts?.formHeaderSubtitle ?? '';
9
+ const resolvedSearchPlaceholder = searchPlaceholder ?? moduleConfig?.texts?.searchPlaceholder ?? 'Search...';
10
+ const resolvedCreateLabel = createButtonLabel ?? moduleConfig?.texts?.newText ?? 'Create';
11
+ const resolvedIcon = icon ?? (moduleConfig?.texts?.iconName && iconNameRenderer
12
+ ? iconNameRenderer(moduleConfig.texts.iconName)
13
+ : null);
14
+ const animateSx = (delayMs) => animated
15
+ ? {
16
+ animation: `jbGridHeaderFadeIn ${animationDurationMs}ms ease-out ${delayMs}ms both`
17
+ }
18
+ : undefined;
19
+ const animateFromLeftSx = (delayMs) => animated && animationPreset === 'sides'
20
+ ? {
21
+ animation: `jbGridHeaderFadeInLeft ${animationDurationMs}ms ease-out ${delayMs}ms both`
22
+ }
23
+ : animateSx(delayMs);
24
+ const animateFromRightSx = (delayMs) => animated && animationPreset === 'sides'
25
+ ? {
26
+ animation: `jbGridHeaderFadeInRight ${animationDurationMs}ms ease-out ${delayMs}ms both`
27
+ }
28
+ : animateSx(delayMs);
5
29
  return (_jsxs(Box, { sx: {
30
+ width: '100%',
6
31
  display: 'flex',
7
- flexDirection: { xs: 'column', sm: 'row' },
8
- alignItems: { xs: 'stretch', sm: 'center' },
9
- justifyContent: 'space-between',
32
+ flexDirection: 'column',
10
33
  gap: 2,
11
- p: 2
12
- }, children: [_jsxs(Box, { sx: { display: 'flex', alignItems: 'center', gap: 1 }, children: [icon, _jsx(Typography, { variant: "h5", sx: { fontWeight: 700 }, children: title })] }), _jsxs(Box, { sx: {
13
- display: 'flex',
14
- alignItems: 'center',
15
- gap: 1,
16
- width: { xs: '100%', sm: 'auto' }
17
- }, children: [_jsx(Paper, { sx: {
18
- px: 1.5,
19
- py: 0.5,
20
- width: { xs: '100%', sm: 300 }
21
- }, children: _jsx(InputBase, { fullWidth: true, placeholder: searchPlaceholder, value: searchText, onChange: (event) => onSearchTextChange(event.target.value) }) }), rightContent, allowCreate && onCreateClick ? (_jsx(Button, { variant: "contained", onClick: onCreateClick, children: createButtonLabel })) : null] })] }));
34
+ p: { xs: 2, sm: 3 },
35
+ '@keyframes jbGridHeaderFadeIn': {
36
+ from: { opacity: 0, transform: 'translateY(8px)' },
37
+ to: { opacity: 1, transform: 'translateY(0)' }
38
+ },
39
+ '@keyframes jbGridHeaderFadeInLeft': {
40
+ from: { opacity: 0, transform: 'translateX(-14px)' },
41
+ to: { opacity: 1, transform: 'translateX(0)' }
42
+ },
43
+ '@keyframes jbGridHeaderFadeInRight': {
44
+ from: { opacity: 0, transform: 'translateX(14px)' },
45
+ to: { opacity: 1, transform: 'translateX(0)' }
46
+ }
47
+ }, children: [breadcrumb ? _jsx(Box, { sx: animateSx(0), children: breadcrumb }) : null, _jsxs(Box, { sx: {
48
+ display: { xs: 'flex', sm: 'grid' },
49
+ flexDirection: { xs: 'column', sm: 'row' },
50
+ gridTemplateColumns: { sm: 'minmax(0, 1fr) auto' },
51
+ alignItems: { xs: 'stretch', sm: 'center' },
52
+ gap: 2,
53
+ width: '100%'
54
+ }, children: [_jsxs(Box, { sx: {
55
+ display: 'flex',
56
+ alignItems: 'center',
57
+ gap: 1,
58
+ minWidth: 0,
59
+ ...animateFromLeftSx(animationStaggerMs)
60
+ }, children: [resolvedIcon ? _jsx(Box, { sx: { display: 'inline-flex', alignItems: 'center' }, children: resolvedIcon }) : null, _jsxs(Box, { sx: { minWidth: 0 }, children: [_jsx(Typography, { variant: "h4", sx: { fontWeight: 700, lineHeight: 1.15 }, children: resolvedTitle }), resolvedSubtitle ? (_jsx(Typography, { variant: "body2", color: "text.secondary", children: resolvedSubtitle })) : null] })] }), _jsxs(Box, { sx: {
61
+ width: { xs: '100%', sm: 'auto' },
62
+ display: 'flex',
63
+ alignItems: { xs: 'stretch', sm: 'center' },
64
+ justifySelf: { sm: 'end' },
65
+ justifyContent: { xs: 'flex-start', sm: 'flex-end' },
66
+ flexWrap: 'wrap',
67
+ gap: 1,
68
+ minWidth: 0,
69
+ ...animateFromRightSx(animationStaggerMs * 2)
70
+ }, children: [_jsxs(Paper, { sx: {
71
+ px: 1.5,
72
+ py: 0.5,
73
+ width: { xs: '100%', sm: 320 },
74
+ display: 'flex',
75
+ alignItems: 'center',
76
+ gap: 1,
77
+ borderRadius: 1.5
78
+ }, children: [_jsx(SearchRoundedIcon, { sx: { color: 'text.secondary', fontSize: 20 } }), _jsx(InputBase, { fullWidth: true, placeholder: resolvedSearchPlaceholder, value: searchText, onChange: (event) => onSearchTextChange(event.target.value) })] }), rightContent, allowCreate && onCreateClick ? (_jsx(Button, { variant: "contained", startIcon: _jsx(AddRoundedIcon, { fontSize: "small" }), sx: (theme) => ({
79
+ borderRadius: 1.5,
80
+ minHeight: 42,
81
+ px: 2.25,
82
+ fontWeight: 700,
83
+ boxShadow: 'none',
84
+ backgroundImage: 'none',
85
+ '&:hover': {
86
+ boxShadow: 'none',
87
+ backgroundImage: 'none',
88
+ backgroundColor: theme.palette.primary.dark
89
+ }
90
+ }), onClick: onCreateClick, children: resolvedCreateLabel })) : null] })] })] }));
22
91
  }
@@ -0,0 +1,9 @@
1
+ type JBGridLoadingProps = {
2
+ minHeight?: number;
3
+ size?: number;
4
+ message?: string;
5
+ color?: 'primary' | 'secondary' | 'inherit';
6
+ };
7
+ export declare function JBGridLoading(props: JBGridLoadingProps): import("react/jsx-runtime").JSX.Element;
8
+ export {};
9
+ //# sourceMappingURL=JBGridLoading.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"JBGridLoading.d.ts","sourceRoot":"","sources":["../../src/grid/JBGridLoading.tsx"],"names":[],"mappings":"AAEA,KAAK,kBAAkB,GAAG;IACxB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,SAAS,GAAG,WAAW,GAAG,SAAS,CAAC;CAC7C,CAAC;AAEF,wBAAgB,aAAa,CAAC,KAAK,EAAE,kBAAkB,2CA2BtD"}
@@ -0,0 +1,14 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Box, CircularProgress, Typography } from '@mui/material';
3
+ export function JBGridLoading(props) {
4
+ const { minHeight = 320, size = 40, message, color = 'primary' } = props;
5
+ return (_jsxs(Box, { sx: {
6
+ width: '100%',
7
+ minHeight,
8
+ display: 'flex',
9
+ flexDirection: 'column',
10
+ alignItems: 'center',
11
+ justifyContent: 'center',
12
+ gap: 1.25
13
+ }, children: [_jsx(CircularProgress, { size: size, color: color }), message ? (_jsx(Typography, { variant: "body2", color: "text.secondary", children: message })) : null] }));
14
+ }
@@ -4,6 +4,9 @@ export declare const JBBooleanTypeProvider: (props: {
4
4
  export declare const JBCurrencyTypeProvider: (props: {
5
5
  for: string[];
6
6
  }) => import("react/jsx-runtime").JSX.Element;
7
+ export declare const JBDateTypeProvider: (props: {
8
+ for: string[];
9
+ }) => import("react/jsx-runtime").JSX.Element;
7
10
  export declare const JBImageTypeProvider: (props: {
8
11
  for: string[];
9
12
  }) => import("react/jsx-runtime").JSX.Element;
@@ -1 +1 @@
1
- {"version":3,"file":"JBGridProviders.d.ts","sourceRoot":"","sources":["../../src/grid/JBGridProviders.tsx"],"names":[],"mappings":"AA2DA,eAAO,MAAM,qBAAqB,GAAI,OAAO;IAAE,GAAG,EAAE,MAAM,EAAE,CAAA;CAAE,4CAK7D,CAAC;AAEF,eAAO,MAAM,sBAAsB,GAAI,OAAO;IAAE,GAAG,EAAE,MAAM,EAAE,CAAA;CAAE,4CAK9D,CAAC;AAEF,eAAO,MAAM,mBAAmB,GAAI,OAAO;IAAE,GAAG,EAAE,MAAM,EAAE,CAAA;CAAE,4CAK3D,CAAC"}
1
+ {"version":3,"file":"JBGridProviders.d.ts","sourceRoot":"","sources":["../../src/grid/JBGridProviders.tsx"],"names":[],"mappings":"AA0EA,eAAO,MAAM,qBAAqB,GAAI,OAAO;IAAE,GAAG,EAAE,MAAM,EAAE,CAAA;CAAE,4CAK7D,CAAC;AAEF,eAAO,MAAM,sBAAsB,GAAI,OAAO;IAAE,GAAG,EAAE,MAAM,EAAE,CAAA;CAAE,4CAK9D,CAAC;AAEF,eAAO,MAAM,kBAAkB,GAAI,OAAO;IAAE,GAAG,EAAE,MAAM,EAAE,CAAA;CAAE,4CAK1D,CAAC;AAEF,eAAO,MAAM,mBAAmB,GAAI,OAAO;IAAE,GAAG,EAAE,MAAM,EAAE,CAAA;CAAE,4CAK3D,CAAC"}
@@ -10,6 +10,18 @@ const formatCurrency = (value, currency = 'USD') => {
10
10
  currency
11
11
  }).format(amount);
12
12
  };
13
+ const formatDate = (value) => {
14
+ if (!value)
15
+ return '';
16
+ const date = value instanceof Date ? value : new Date(String(value));
17
+ if (Number.isNaN(date.getTime()))
18
+ return String(value);
19
+ return new Intl.DateTimeFormat('es-MX', {
20
+ year: 'numeric',
21
+ month: '2-digit',
22
+ day: '2-digit'
23
+ }).format(date);
24
+ };
13
25
  const BooleanFormatter = ({ value }) => {
14
26
  return _jsx("span", { children: value ? 'Yes' : 'No' });
15
27
  };
@@ -17,6 +29,9 @@ const CurrencyFormatter = ({ value, column }) => {
17
29
  const currency = column?.currency ?? 'USD';
18
30
  return _jsx("span", { children: formatCurrency(value, currency) });
19
31
  };
32
+ const DateFormatter = ({ value }) => {
33
+ return _jsx("span", { children: formatDate(value) });
34
+ };
20
35
  const ImageFormatter = ({ value, column }) => {
21
36
  const src = typeof value === 'string' ? value : '';
22
37
  const type = column?.type ?? 'square';
@@ -28,4 +43,5 @@ const ImageFormatter = ({ value, column }) => {
28
43
  };
29
44
  export const JBBooleanTypeProvider = (props) => (_jsx(DataTypeProvider, { formatterComponent: BooleanFormatter, ...props }));
30
45
  export const JBCurrencyTypeProvider = (props) => (_jsx(DataTypeProvider, { formatterComponent: CurrencyFormatter, ...props }));
46
+ export const JBDateTypeProvider = (props) => (_jsx(DataTypeProvider, { formatterComponent: DateFormatter, ...props }));
31
47
  export const JBImageTypeProvider = (props) => (_jsx(DataTypeProvider, { formatterComponent: ImageFormatter, ...props }));
@@ -0,0 +1,7 @@
1
+ type JBGridSkeletonProps = {
2
+ rows?: number;
3
+ showToolbar?: boolean;
4
+ };
5
+ export declare function JBGridSkeleton(props: JBGridSkeletonProps): import("react/jsx-runtime").JSX.Element;
6
+ export {};
7
+ //# sourceMappingURL=JBGridSkeleton.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"JBGridSkeleton.d.ts","sourceRoot":"","sources":["../../src/grid/JBGridSkeleton.tsx"],"names":[],"mappings":"AAEA,KAAK,mBAAmB,GAAG;IACzB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB,CAAC;AAEF,wBAAgB,cAAc,CAAC,KAAK,EAAE,mBAAmB,2CA0BxD"}
@@ -0,0 +1,6 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Box, Skeleton } from '@mui/material';
3
+ export function JBGridSkeleton(props) {
4
+ const { rows = 8, showToolbar = true } = props;
5
+ return (_jsxs(Box, { sx: { width: '100%', p: 1.5 }, children: [showToolbar ? (_jsxs(Box, { sx: { mb: 1.5, display: 'flex', justifyContent: 'space-between', gap: 1.5 }, children: [_jsx(Skeleton, { variant: "rounded", width: 240, height: 36 }), _jsx(Skeleton, { variant: "rounded", width: 160, height: 36 })] })) : null, _jsx(Skeleton, { variant: "rounded", width: "100%", height: 44 }), _jsx(Box, { sx: { mt: 1, display: 'grid', gap: 1 }, children: Array.from({ length: rows }).map((_, index) => (_jsx(Skeleton, { variant: "rounded", width: "100%", height: 40 }, index))) })] }));
6
+ }
@@ -0,0 +1,4 @@
1
+ import { JBGridDefaults } from './types';
2
+ export declare const DEFAULT_GRID_DEFAULTS: Required<JBGridDefaults>;
3
+ export declare function resolveGridDefaults(defaults?: JBGridDefaults): Required<JBGridDefaults>;
4
+ //# sourceMappingURL=defaults.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"defaults.d.ts","sourceRoot":"","sources":["../../src/grid/defaults.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAEzC,eAAO,MAAM,qBAAqB,EAAE,QAAQ,CAAC,cAAc,CAoB1D,CAAC;AAEF,wBAAgB,mBAAmB,CAAC,QAAQ,CAAC,EAAE,cAAc,GAAG,QAAQ,CAAC,cAAc,CAAC,CAKvF"}
@@ -0,0 +1,27 @@
1
+ export const DEFAULT_GRID_DEFAULTS = {
2
+ pageSize: 30,
3
+ virtualScrolling: false,
4
+ estimatedRowHeight: 48,
5
+ virtualTableHeight: 640,
6
+ virtualTableHeightMode: 'fixed',
7
+ virtualTableHeightRatio: 1,
8
+ allowSorting: true,
9
+ allowColumnResizing: true,
10
+ allowSelection: true,
11
+ allowSelectAll: false,
12
+ showSelectionColumn: false,
13
+ allowFiltering: false,
14
+ advancedFiltering: false,
15
+ allowGrouping: true,
16
+ filters: [],
17
+ sorting: [],
18
+ grouping: [],
19
+ expandedGroups: [],
20
+ pageSizes: [10, 30, 50, 100, 200, 500, 1000]
21
+ };
22
+ export function resolveGridDefaults(defaults) {
23
+ return {
24
+ ...DEFAULT_GRID_DEFAULTS,
25
+ ...(defaults ?? {})
26
+ };
27
+ }
@@ -2,4 +2,7 @@ export * from './types';
2
2
  export * from './JBGridProviders';
3
3
  export * from './JBGridHeader';
4
4
  export * from './JBGrid';
5
+ export * from './JBGridSkeleton';
6
+ export * from './JBGridLoading';
7
+ export * from './defaults';
5
8
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/grid/index.ts"],"names":[],"mappings":"AAAA,cAAc,SAAS,CAAC;AACxB,cAAc,mBAAmB,CAAC;AAClC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,UAAU,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/grid/index.ts"],"names":[],"mappings":"AAAA,cAAc,SAAS,CAAC;AACxB,cAAc,mBAAmB,CAAC;AAClC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,UAAU,CAAC;AACzB,cAAc,kBAAkB,CAAC;AACjC,cAAc,iBAAiB,CAAC;AAChC,cAAc,YAAY,CAAC"}
@@ -2,3 +2,6 @@ export * from './types';
2
2
  export * from './JBGridProviders';
3
3
  export * from './JBGridHeader';
4
4
  export * from './JBGrid';
5
+ export * from './JBGridSkeleton';
6
+ export * from './JBGridLoading';
7
+ export * from './defaults';