@pallasoft/ps-table-components 1.25.0 → 1.27.0

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 (59) hide show
  1. package/dist/components/ps-data-table.d.ts +10 -1
  2. package/dist/components/ps-data-table.js +93 -17
  3. package/dist/components/ps-select-all-matching-banner.d.ts +10 -0
  4. package/dist/components/ps-select-all-matching-banner.js +10 -0
  5. package/dist/components/ps-table-pagination.d.ts +3 -1
  6. package/dist/components/ps-table-pagination.js +11 -3
  7. package/dist/components/ps-table-reorder-frame.d.ts +2 -1
  8. package/dist/components/ps-table-reorder-frame.js +8 -4
  9. package/dist/constants/ps-server-rows-config.d.ts +8 -0
  10. package/dist/constants/ps-server-rows-config.js +11 -0
  11. package/dist/constants/ps-table-drop-classes.js +2 -2
  12. package/dist/constants/ps-table-pagination-position.d.ts +6 -0
  13. package/dist/constants/ps-table-pagination-position.js +8 -0
  14. package/dist/esm/components/ps-data-table.js +94 -18
  15. package/dist/esm/components/ps-select-all-matching-banner.js +6 -0
  16. package/dist/esm/components/ps-table-pagination.js +11 -3
  17. package/dist/esm/components/ps-table-reorder-frame.js +8 -4
  18. package/dist/esm/constants/ps-server-rows-config.js +8 -0
  19. package/dist/esm/constants/ps-table-drop-classes.js +2 -2
  20. package/dist/esm/constants/ps-table-pagination-position.js +5 -0
  21. package/dist/esm/hooks/use-ps-server-rows.js +209 -0
  22. package/dist/esm/hooks/use-ps-table-reorder.js +8 -1
  23. package/dist/esm/index.js +12 -0
  24. package/dist/esm/interfaces/ps-server-entry.js +1 -0
  25. package/dist/esm/interfaces/ps-server-page.js +1 -0
  26. package/dist/esm/interfaces/ps-server-rows-input.js +1 -0
  27. package/dist/esm/interfaces/ps-server-rows-result.js +1 -0
  28. package/dist/esm/interfaces/ps-table-cursor-paging.js +1 -0
  29. package/dist/esm/interfaces/ps-table-select-all-matching.js +1 -0
  30. package/dist/esm/interfaces/table-drag-size.js +1 -0
  31. package/dist/esm/services/ps-server-rows-service.js +36 -0
  32. package/dist/esm/services/ps-table-reorder-service.js +12 -0
  33. package/dist/hooks/use-ps-server-rows.d.ts +3 -0
  34. package/dist/hooks/use-ps-server-rows.js +213 -0
  35. package/dist/hooks/use-ps-table-reorder.d.ts +2 -0
  36. package/dist/hooks/use-ps-table-reorder.js +8 -1
  37. package/dist/index.d.ts +12 -0
  38. package/dist/index.js +12 -0
  39. package/dist/interfaces/ps-server-entry.d.ts +6 -0
  40. package/dist/interfaces/ps-server-entry.js +2 -0
  41. package/dist/interfaces/ps-server-page.d.ts +7 -0
  42. package/dist/interfaces/ps-server-page.js +2 -0
  43. package/dist/interfaces/ps-server-rows-input.d.ts +13 -0
  44. package/dist/interfaces/ps-server-rows-input.js +2 -0
  45. package/dist/interfaces/ps-server-rows-result.d.ts +18 -0
  46. package/dist/interfaces/ps-server-rows-result.js +2 -0
  47. package/dist/interfaces/ps-table-cursor-paging.d.ts +12 -0
  48. package/dist/interfaces/ps-table-cursor-paging.js +2 -0
  49. package/dist/interfaces/ps-table-select-all-matching.d.ts +7 -0
  50. package/dist/interfaces/ps-table-select-all-matching.js +2 -0
  51. package/dist/interfaces/table-drag-size.d.ts +5 -0
  52. package/dist/interfaces/table-drag-size.js +2 -0
  53. package/dist/interfaces/table-reorder-item.d.ts +1 -0
  54. package/dist/interfaces/table-reorder.d.ts +1 -0
  55. package/dist/services/ps-server-rows-service.d.ts +11 -0
  56. package/dist/services/ps-server-rows-service.js +40 -0
  57. package/dist/services/ps-table-reorder-service.d.ts +2 -0
  58. package/dist/services/ps-table-reorder-service.js +12 -0
  59. package/package.json +2 -2
@@ -1,4 +1,7 @@
1
1
  import { type ReactNode } from 'react';
2
+ import { PsTablePaginationPosition } from '../constants/ps-table-pagination-position';
3
+ import type { PsTableCursorPaging } from '../interfaces/ps-table-cursor-paging';
4
+ import type { PsTableSelectAllMatching } from '../interfaces/ps-table-select-all-matching';
2
5
  import type { PsTableColumn } from '../interfaces/table-column';
3
6
  import type { PsTableGrouping } from '../interfaces/table-grouping';
4
7
  import type { PsTableQuery } from '../interfaces/table-query';
@@ -8,7 +11,9 @@ import type { PsTableSort } from '../interfaces/table-sort';
8
11
  export interface PsDataTableProps<RowData> {
9
12
  caption?: string;
10
13
  className?: string;
14
+ clearSelectionKey?: number | string;
11
15
  columns: PsTableColumn<RowData>[];
16
+ cursorPaging?: PsTableCursorPaging;
12
17
  defaultSort?: PsTableSort;
13
18
  density?: 'compact' | 'normal';
14
19
  expandedRowIds?: string[];
@@ -20,6 +25,7 @@ export interface PsDataTableProps<RowData> {
20
25
  grouping?: PsTableGrouping<RowData>;
21
26
  isLoading?: boolean;
22
27
  isPending?: boolean;
28
+ isRefreshing?: boolean;
23
29
  layout?: 'auto' | 'fixed';
24
30
  onPageChange?: (page: number) => void;
25
31
  onQueryChange?: (query: PsTableQuery) => void;
@@ -27,6 +33,7 @@ export interface PsDataTableProps<RowData> {
27
33
  onRowHover?: (row: RowData) => void;
28
34
  page?: number;
29
35
  pageSize?: number;
36
+ paginationPosition?: PsTablePaginationPosition;
30
37
  pinFirstColumn?: boolean;
31
38
  query?: PsTableQuery;
32
39
  renderExpandedRow?: (row: RowData) => ReactNode;
@@ -34,7 +41,9 @@ export interface PsDataTableProps<RowData> {
34
41
  rows: RowData[];
35
42
  searchingLabel?: string;
36
43
  searchPlaceholder?: string;
44
+ selectAllMatching?: PsTableSelectAllMatching;
45
+ stickyTop?: string;
37
46
  toolbarActions?: ReactNode;
38
47
  totalRows?: number;
39
48
  }
40
- export declare const PsDataTable: <RowData>({ caption, className, columns, defaultSort, density, expandedRowIds, mobileLayout, getBulkActions, getRowId, getRowLabel, getSearchText, grouping, isLoading, isPending, layout, onPageChange, onQueryChange, onRowClick, onRowHover, page, pageSize, pinFirstColumn, query, renderExpandedRow, reorder, rows, searchingLabel, searchPlaceholder, toolbarActions, totalRows, }: PsDataTableProps<RowData>) => import("react").JSX.Element;
49
+ export declare const PsDataTable: <RowData>({ caption, className, clearSelectionKey, columns, cursorPaging, defaultSort, density, expandedRowIds, mobileLayout, getBulkActions, getRowId, getRowLabel, getSearchText, grouping, isLoading, isPending, isRefreshing, layout, onPageChange, onQueryChange, onRowClick, onRowHover, page, pageSize, paginationPosition, pinFirstColumn, query, renderExpandedRow, reorder, rows, searchingLabel, searchPlaceholder, selectAllMatching, stickyTop, toolbarActions, totalRows, }: PsDataTableProps<RowData>) => import("react").JSX.Element;
@@ -42,6 +42,7 @@ const ps_input_components_1 = require("@pallasoft/ps-input-components");
42
42
  const ps_motion_components_1 = require("@pallasoft/ps-motion-components");
43
43
  const react_virtual_1 = require("@tanstack/react-virtual");
44
44
  const ps_table_control_classes_1 = require("../constants/ps-table-control-classes");
45
+ const ps_table_pagination_position_1 = require("../constants/ps-table-pagination-position");
45
46
  const table_breakpoint_1 = require("../constants/table-breakpoint");
46
47
  const table_config_1 = require("../constants/table-config");
47
48
  const use_ps_incremental_count_1 = require("../hooks/use-ps-incremental-count");
@@ -55,6 +56,7 @@ const ps_table_pin_service_1 = require("../services/ps-table-pin-service");
55
56
  const ps_table_query_service_1 = require("../services/ps-table-query-service");
56
57
  const ps_table_reorder_service_1 = require("../services/ps-table-reorder-service");
57
58
  const ps_table_scroll_service_1 = require("../services/ps-table-scroll-service");
59
+ const ps_select_all_matching_banner_1 = require("./ps-select-all-matching-banner");
58
60
  const ps_table_bulk_bar_1 = require("./ps-table-bulk-bar");
59
61
  const ps_table_card_list_1 = require("./ps-table-card-list");
60
62
  const ps_table_column_picker_1 = require("./ps-table-column-picker");
@@ -84,7 +86,7 @@ const alignClassNames = {
84
86
  left: 'text-left',
85
87
  right: 'text-right tabular-nums',
86
88
  };
87
- const PsDataTable = ({ caption, className, columns, defaultSort, density = 'normal', expandedRowIds, mobileLayout = 'cards', getBulkActions, getRowId, getRowLabel, getSearchText, grouping, isLoading = false, isPending = false, layout = 'auto', onPageChange, onQueryChange, onRowClick, onRowHover, page, pageSize, pinFirstColumn = true, query, renderExpandedRow, reorder, rows, searchingLabel = table_config_1.PsTableConfig.searchingLabel, searchPlaceholder = table_config_1.PsTableConfig.searchPlaceholder, toolbarActions, totalRows, }) => {
89
+ const PsDataTable = ({ caption, className, clearSelectionKey, columns, cursorPaging, defaultSort, density = 'normal', expandedRowIds, mobileLayout = 'cards', getBulkActions, getRowId, getRowLabel, getSearchText, grouping, isLoading = false, isPending = false, isRefreshing = false, layout = 'auto', onPageChange, onQueryChange, onRowClick, onRowHover, page, pageSize, paginationPosition = ps_table_pagination_position_1.PsTablePaginationPosition.bottom, pinFirstColumn = true, query, renderExpandedRow, reorder, rows, searchingLabel = table_config_1.PsTableConfig.searchingLabel, searchPlaceholder = table_config_1.PsTableConfig.searchPlaceholder, selectAllMatching, stickyTop, toolbarActions, totalRows, }) => {
88
90
  const containerRef = (0, react_1.useRef)(null);
89
91
  const [uncontrolledPage, setUncontrolledPage] = (0, react_1.useState)(1);
90
92
  const [uncontrolledQuery, setUncontrolledQuery] = (0, react_1.useState)(() => ps_table_query_service_1.PsTableQueryService.empty(defaultSort ? defaultSort : null));
@@ -92,7 +94,50 @@ const PsDataTable = ({ caption, className, columns, defaultSort, density = 'norm
92
94
  const [toggledGroupKeys, setToggledGroupKeys] = (0, react_1.useState)([]);
93
95
  const [closingGroupKeys, setClosingGroupKeys] = (0, react_1.useState)([]);
94
96
  const [openedGroupKeys, setOpenedGroupKeys] = (0, react_1.useState)([]);
97
+ const [seenClearKey, setSeenClearKey] = (0, react_1.useState)(clearSelectionKey);
98
+ const stickyRegionRef = (0, react_1.useRef)(null);
99
+ const stickySentinelRef = (0, react_1.useRef)(null);
100
+ const [stickyHeight, setStickyHeight] = (0, react_1.useState)(0);
101
+ const [isStuck, setIsStuck] = (0, react_1.useState)(false);
95
102
  const currentQuery = query ? query : uncontrolledQuery;
103
+ if (seenClearKey !== clearSelectionKey) {
104
+ setSeenClearKey(clearSelectionKey);
105
+ setSelectedIds([]);
106
+ }
107
+ (0, react_1.useLayoutEffect)(() => {
108
+ const region = stickyRegionRef.current;
109
+ if (stickyTop === undefined || region === null)
110
+ return;
111
+ const measure = () => setStickyHeight(region.offsetHeight);
112
+ const observer = new ResizeObserver(measure);
113
+ measure();
114
+ observer.observe(region);
115
+ return () => observer.disconnect();
116
+ }, [stickyTop]);
117
+ (0, react_1.useEffect)(() => {
118
+ const region = stickyRegionRef.current;
119
+ const sentinel = stickySentinelRef.current;
120
+ if (stickyTop === undefined || region === null || sentinel === null)
121
+ return;
122
+ let frame = 0;
123
+ const check = () => {
124
+ frame = 0;
125
+ setIsStuck(sentinel.getBoundingClientRect().top < Number.parseFloat(getComputedStyle(region).top));
126
+ };
127
+ const schedule = () => {
128
+ if (frame === 0)
129
+ frame = window.requestAnimationFrame(check);
130
+ };
131
+ check();
132
+ window.addEventListener('scroll', schedule, { passive: true });
133
+ window.addEventListener('resize', schedule);
134
+ return () => {
135
+ window.removeEventListener('scroll', schedule);
136
+ window.removeEventListener('resize', schedule);
137
+ if (frame !== 0)
138
+ window.cancelAnimationFrame(frame);
139
+ };
140
+ }, [stickyTop]);
96
141
  const { filters, hiddenColumnIds, search, sort } = currentQuery;
97
142
  const visibleColumns = columns.filter((column) => !hiddenColumnIds.includes(column.id));
98
143
  const fittedWidths = (0, react_1.useMemo)(() => new Map(columns
@@ -194,7 +239,9 @@ const PsDataTable = ({ caption, className, columns, defaultSort, density = 'norm
194
239
  announcements: nesting.announcements,
195
240
  canDrag: (id) => {
196
241
  const row = find(id);
197
- return row !== undefined && nesting.canDrag(row);
242
+ return (row !== undefined &&
243
+ (reorder.isRowDraggable === undefined || reorder.isRowDraggable(row)) &&
244
+ nesting.canDrag(row));
198
245
  },
199
246
  canDrop: (activeId, targetId, placement) => {
200
247
  const active = find(activeId);
@@ -226,13 +273,16 @@ const PsDataTable = ({ caption, className, columns, defaultSort, density = 'norm
226
273
  groupKey: reorderKey(row),
227
274
  handleLabel: reorder.getHandleLabel(label),
228
275
  id: rowId,
276
+ isDraggable: reorder.isRowDraggable === undefined || reorder.isRowDraggable(row),
229
277
  label,
230
278
  };
231
279
  })
232
280
  : [], [getRowId, getRowLabel, reorder, reorderKey, visibleRows]);
233
- const renderOverlayRow = (rowId) => {
281
+ const showsPagination = Boolean(pageSize) && (!grouping || isServerPaginated);
282
+ const renderPagination = (paginationClassName) => pageSize ? ((0, jsx_runtime_1.jsx)(ps_table_pagination_1.PsTablePagination, { className: paginationClassName, cursor: cursorPaging, isPartial: isPartial, loadedPageCount: pageCountOf(loadedRowCount), onPageChange: changePage, page: safePage, pageCount: pageCount, pageSize: pageSize, totalRows: rowCount })) : null;
283
+ const renderOverlayRow = (rowId, size) => {
234
284
  const row = visibleRows.find((candidate) => getRowId(candidate) === rowId);
235
- return row === undefined ? null : ((0, jsx_runtime_1.jsx)("table", { className: 'w-full table-fixed border-collapse bg-surface text-left', children: (0, jsx_runtime_1.jsx)("tbody", { children: renderRow(ps_table_reorder_service_1.PsTableReorderService.plain, row) }) }));
285
+ return row === undefined ? null : ((0, jsx_runtime_1.jsxs)("table", { className: 'pointer-events-none w-full table-fixed border-collapse bg-surface text-left', style: size === null ? undefined : { width: size.width }, children: [size === null ? null : ((0, jsx_runtime_1.jsx)("colgroup", { children: size.columnWidths.map((width, index) => ((0, jsx_runtime_1.jsx)("col", { style: { width } }, index))) })), (0, jsx_runtime_1.jsx)("tbody", { children: renderRow(ps_table_reorder_service_1.PsTableReorderService.plain, row, undefined, undefined, true) })] }));
236
286
  };
237
287
  const renderReorder = (children) => reorder === undefined ? (children(ps_table_reorder_service_1.PsTableReorderService.plain)) : ((0, jsx_runtime_1.jsx)(react_1.Suspense, { fallback: children(ps_table_reorder_service_1.PsTableReorderService.plain), children: (0, jsx_runtime_1.jsx)(LazyReorderFrame, { announcements: reorder.announcements, enabled: reorder.enabled, instructions: reorder.instructions, items: reorderItems, nesting: nestingBinding, onReorder: reorder.onReorder, renderOverlay: renderOverlayRow, children: children }) }));
238
288
  const changePage = (next) => {
@@ -263,12 +313,16 @@ const PsDataTable = ({ caption, className, columns, defaultSort, density = 'norm
263
313
  const selectedRows = selectedIds.length === 0 ? [] : queriedRows.filter((row) => selectedIdSet.has(getRowId(row)));
264
314
  const pageIds = visibleRows.map((row) => getRowId(row));
265
315
  const isPageSelected = pageIds.length > 0 && pageIds.every((rowId) => selectedIdSet.has(rowId));
266
- const togglePage = () => setSelectedIds((current) => {
267
- const pageIdSet = new Set(pageIds);
268
- return isPageSelected
269
- ? current.filter((rowId) => !pageIdSet.has(rowId))
270
- : [...new Set([...current, ...pageIds])];
271
- });
316
+ const togglePage = () => {
317
+ if (isPageSelected && selectAllMatching !== undefined && selectAllMatching.isActive)
318
+ selectAllMatching.onDeactivate();
319
+ setSelectedIds((current) => {
320
+ const pageIdSet = new Set(pageIds);
321
+ return isPageSelected
322
+ ? current.filter((rowId) => !pageIdSet.has(rowId))
323
+ : [...new Set([...current, ...pageIds])];
324
+ });
325
+ };
272
326
  const bodyRef = (0, react_1.useRef)(null);
273
327
  const [scrollParent, setScrollParent] = (0, react_1.useState)(null);
274
328
  const [scrollMargin, setScrollMargin] = (0, react_1.useState)(0);
@@ -312,7 +366,7 @@ const PsDataTable = ({ caption, className, columns, defaultSort, density = 'norm
312
366
  }, [shouldVirtualize, visibleRows.length]);
313
367
  const toggleRow = (rowId) => setSelectedIds((current) => current.includes(rowId) ? current.filter((id) => id !== rowId) : [...current, rowId]);
314
368
  const renderCardList = (cardRows, emptyContent) => ((0, jsx_runtime_1.jsx)(ps_table_card_list_1.PsTableCardList, { columns: visibleColumns, emptyContent: emptyContent, expandedRowIds: expandedRowIds, footerColumns: hasFooter ? visibleColumns.filter((column) => column.footer !== undefined) : [], getRowId: getRowId, getRowLabel: (row) => (getRowLabel ? getRowLabel(row) : getRowId(row)), isSelectable: isSelectable, onRowClick: onRowClick, onRowHover: onRowHover, onToggleRow: toggleRow, renderExpandedRow: renderExpandedRow, rows: cardRows, selectedIds: selectedIds }));
315
- const renderRow = (api, row, motion, virtualItem) => {
369
+ const renderRow = (api, row, motion, virtualItem, isOverlay = false) => {
316
370
  const rowId = getRowId(row);
317
371
  const isExpanded = expandedRowIds ? expandedRowIds.includes(rowId) : false;
318
372
  const rowLabel = getRowLabel ? getRowLabel(row) : rowId;
@@ -324,7 +378,7 @@ const PsDataTable = ({ caption, className, columns, defaultSort, density = 'norm
324
378
  measureRef: virtualItem ? virtualizer.measureElement : undefined,
325
379
  }
326
380
  : { ref: virtualItem ? virtualizer.measureElement : undefined };
327
- return ((0, jsx_runtime_1.jsxs)(react_1.Fragment, { children: [(0, jsx_runtime_1.jsxs)(Row, { ...rowExtras, "data-index": virtualItem ? virtualItem.index : undefined, "aria-expanded": renderExpandedRow ? isExpanded : undefined, "aria-label": onRowClick ? rowLabel : undefined, className: ps_design_system_1.PallasoftClassNameService.merge('align-middle transition-colors', motion ? motion.className : '', onRowClick ? 'ps-focus-ring cursor-pointer hover:bg-mist/60' : 'hover:bg-mist/40', isExpanded ? 'bg-mist/40' : ''), onClick: onRowClick ? () => onRowClick(row) : undefined, onFocus: onRowHover ? () => onRowHover(row) : undefined, onPointerEnter: onRowHover ? () => onRowHover(row) : undefined, onKeyDown: onRowClick
381
+ return ((0, jsx_runtime_1.jsxs)(react_1.Fragment, { children: [(0, jsx_runtime_1.jsxs)(Row, { ...rowExtras, "data-index": virtualItem ? virtualItem.index : undefined, "aria-expanded": renderExpandedRow ? isExpanded : undefined, "aria-label": onRowClick ? rowLabel : undefined, className: ps_design_system_1.PallasoftClassNameService.merge('align-middle hover:bg-mist/60', motion ? motion.className : '', onRowClick ? 'ps-focus-ring cursor-pointer' : '', isExpanded ? 'bg-mist/60' : ''), onClick: onRowClick ? () => onRowClick(row) : undefined, onFocus: onRowHover ? () => onRowHover(row) : undefined, onPointerEnter: onRowHover ? () => onRowHover(row) : undefined, onKeyDown: onRowClick
328
382
  ? (event) => {
329
383
  if (event.target !== event.currentTarget)
330
384
  return;
@@ -339,14 +393,25 @@ const PsDataTable = ({ caption, className, columns, defaultSort, density = 'norm
339
393
  ((layout === 'fixed' && !column.wrap) ||
340
394
  ps_table_column_size_service_1.PsTableColumnSizeService.maxWidthOf(column) !== undefined)
341
395
  ? 'truncate'
342
- : '', 'text-sm text-ink'), style: columnStyle(column, fittedWidths.get(column.id)), title: ps_table_cell_tooltip_service_1.PsTableCellTooltipService.forCell(column, row), children: column.render(row) }, column.id)))] }), renderExpandedRow ? ((0, jsx_runtime_1.jsx)("tr", { "aria-hidden": !isExpanded, className: isExpanded ? 'border-t-0' : 'border-0', children: (0, jsx_runtime_1.jsx)("td", { className: 'p-0', colSpan: columnCount, children: (0, jsx_runtime_1.jsx)(ps_motion_components_1.PsCollapse, { isOpen: isExpanded, children: (0, jsx_runtime_1.jsx)("div", { className: 'w-0 min-w-full border-l-2 border-primary bg-mist/40 px-4 py-4', children: renderExpandedRow(row) }) }) }) })) : null] }, rowId));
396
+ : '', 'text-sm text-ink'), style: columnStyle(column, fittedWidths.get(column.id)), title: ps_table_cell_tooltip_service_1.PsTableCellTooltipService.forCell(column, row), children: column.render(row) }, column.id)))] }), renderExpandedRow && !isOverlay ? ((0, jsx_runtime_1.jsx)("tr", { "aria-hidden": !isExpanded, className: isExpanded ? 'border-t-0' : 'border-0', children: (0, jsx_runtime_1.jsx)("td", { className: 'p-0', colSpan: columnCount, children: (0, jsx_runtime_1.jsx)(ps_motion_components_1.PsCollapse, { isOpen: isExpanded, children: (0, jsx_runtime_1.jsx)("div", { className: 'w-0 min-w-full border-l-2 border-primary bg-mist/40 px-4 py-4', children: renderExpandedRow(row) }) }) }) })) : null] }, rowId));
343
397
  };
344
398
  const renderEntries = (api, entries) => reorder
345
399
  ? ps_table_reorder_service_1.PsTableReorderService.runs(entries, (entry) => reorderKey(entry.row), (entry) => getRowId(entry.row)).map((run) => api.run(run.id, run.items.map((entry) => getRowId(entry.row)), run.items.map((entry) => renderRow(api, entry.row, entry.motion, entry.virtualItem))))
346
400
  : entries.map((entry) => renderRow(api, entry.row, entry.motion, entry.virtualItem));
347
401
  if (isLoading)
348
402
  return ((0, jsx_runtime_1.jsx)(ps_core_components_1.PsSkeletonTable, { className: className, columns: visibleColumns.length, hasToolbar: hasToolbar, rows: table_config_1.PsTableConfig.skeletonRows }));
349
- return ((0, jsx_runtime_1.jsxs)("div", { ref: containerRef, className: ps_design_system_1.PallasoftClassNameService.merge('flex min-w-0 flex-col gap-3', className), children: [isSelectable && selectedRows.length > 0 && getBulkActions ? ((0, jsx_runtime_1.jsx)(ps_table_bulk_bar_1.PsTableBulkBar, { actions: getBulkActions(selectedRows), onClear: () => setSelectedIds([]), selectedCount: selectedRows.length })) : hasToolbar || columns.some((column) => column.canHide) ? ((0, jsx_runtime_1.jsx)(ps_table_toolbar_1.PsTableToolbar, { actions: (0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [toolbarActions, columns.some((column) => column.canHide) ? ((0, jsx_runtime_1.jsx)(ps_table_column_picker_1.PsTableColumnPicker, { columns: columns
403
+ const clearSelection = () => {
404
+ setSelectedIds([]);
405
+ if (selectAllMatching !== undefined && selectAllMatching.isActive)
406
+ selectAllMatching.onDeactivate();
407
+ };
408
+ const banner = selectAllMatching !== undefined &&
409
+ selectedRows.length > 0 &&
410
+ selectAllMatching.total > pageIds.length &&
411
+ (isPageSelected || selectAllMatching.isActive) ? ((0, jsx_runtime_1.jsx)(ps_select_all_matching_banner_1.PsSelectAllMatchingBanner, { isActive: selectAllMatching.isActive, noun: selectAllMatching.noun, onActivate: selectAllMatching.onActivate, onDeactivate: clearSelection, pageCount: pageIds.length, total: selectAllMatching.total })) : null;
412
+ const topContent = ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [isSelectable && selectedRows.length > 0 && getBulkActions ? ((0, jsx_runtime_1.jsx)(ps_table_bulk_bar_1.PsTableBulkBar, { actions: getBulkActions(selectedRows), onClear: clearSelection, selectedCount: selectAllMatching !== undefined && selectAllMatching.isActive
413
+ ? selectAllMatching.total
414
+ : selectedRows.length })) : hasToolbar || columns.some((column) => column.canHide) ? ((0, jsx_runtime_1.jsx)(ps_table_toolbar_1.PsTableToolbar, { actions: (0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [toolbarActions, columns.some((column) => column.canHide) ? ((0, jsx_runtime_1.jsx)(ps_table_column_picker_1.PsTableColumnPicker, { columns: columns
350
415
  .filter((column) => column.canHide)
351
416
  .map((column) => ({ id: column.id, label: column.label })), hiddenColumnIds: hiddenColumnIds, onChange: (nextHidden) => updateQuery({ hiddenColumnIds: nextHidden }) })) : null] }), columns: hasFilters ? columns : [], filters: filters, isSearchable: isSearchable, onClearFilters: clearFilters, onFilterChange: (columnId, value) => {
352
417
  updateQuery({ filters: { ...filters, [columnId]: value } });
@@ -354,14 +419,23 @@ const PsDataTable = ({ caption, className, columns, defaultSort, density = 'norm
354
419
  }, onSearchChange: (next) => {
355
420
  updateQuery({ search: next });
356
421
  resetPage();
357
- }, rows: rows, search: search, searchPlaceholder: searchPlaceholder })) : null, (0, jsx_runtime_1.jsxs)("div", { className: 'min-w-0 overflow-hidden rounded-[1.25rem] border border-line bg-surface', children: [mobileLayout === 'cards' ? ((0, jsx_runtime_1.jsxs)("div", { className: 'sm:hidden', children: [reorder && reorder.cardsReason ? ((0, jsx_runtime_1.jsx)("p", { className: 'border-b border-line px-4 py-2 text-xs text-ink/55', children: reorder.cardsReason })) : null, grouping
422
+ }, rows: rows, search: search, searchPlaceholder: searchPlaceholder })) : null, banner] }));
423
+ return ((0, jsx_runtime_1.jsxs)("div", { ref: containerRef, className: ps_design_system_1.PallasoftClassNameService.merge('flex min-w-0 flex-col gap-3', className), children: [stickyTop === undefined ? (topContent) : ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)("div", { "aria-hidden": 'true', className: '-mb-3 h-0', ref: stickySentinelRef }), (0, jsx_runtime_1.jsx)("div", { className: ps_design_system_1.PallasoftClassNameService.merge('sticky z-sticky -mx-1 flex flex-col gap-3 bg-canvas px-1 pb-2 pt-1 transition-shadow', isStuck ? 'shadow-[0_8px_8px_-8px_rgb(var(--ps-color-ink-rgb,15_23_42)/0.18)]' : ''), ref: stickyRegionRef, style: { top: stickyTop }, children: topContent })] })), (0, jsx_runtime_1.jsxs)("div", { "aria-busy": isRefreshing, className: ps_design_system_1.PallasoftClassNameService.merge('min-w-0 rounded-[1.25rem] border border-line bg-surface', stickyTop === undefined ? 'overflow-hidden' : 'overflow-clip'), children: [showsPagination && paginationPosition !== ps_table_pagination_position_1.PsTablePaginationPosition.bottom
424
+ ? renderPagination('border-b border-t-0')
425
+ : null, mobileLayout === 'cards' ? ((0, jsx_runtime_1.jsxs)("div", { className: ps_design_system_1.PallasoftClassNameService.merge('transition-opacity duration-150 sm:hidden', isRefreshing ? 'opacity-60' : ''), children: [reorder && reorder.cardsReason ? ((0, jsx_runtime_1.jsx)("p", { className: 'border-b border-line px-4 py-2 text-xs text-ink/55', children: reorder.cardsReason })) : null, grouping
358
426
  ? groups.map((group, groupIndex) => {
359
427
  const isExpanded = isGroupExpanded(group.key, groupIndex);
360
428
  return ((0, jsx_runtime_1.jsxs)("div", { className: 'border-b border-line last:border-b-0', children: [(0, jsx_runtime_1.jsx)(ps_table_group_header_1.PsTableGroupHeader, { count: group.rows.length, isExpanded: isExpanded, label: grouping.getGroupLabel(group.key, group.rows), onToggle: () => toggleGroup(group.key, isExpanded), summary: grouping.renderGroupSummary
361
429
  ? grouping.renderGroupSummary(group.rows)
362
430
  : undefined }), (0, jsx_runtime_1.jsx)(ps_motion_components_1.PsCollapse, { isOpen: isExpanded && !closingGroupKeys.includes(group.key), children: renderCardList(group.rows, null) })] }, `group-${group.key}`));
363
431
  })
364
- : renderCardList(shouldVirtualize ? visibleRows.slice(0, cards.count) : visibleRows, visibleRows.length === 0 && isSearching ? ((0, jsx_runtime_1.jsx)(ps_table_searching_state_1.PsTableSearchingState, { label: searchingLabel, skeletonRows: table_config_1.PsTableConfig.searchingSkeletonRows })) : visibleRows.length === 0 && isQueried ? ((0, jsx_runtime_1.jsxs)("div", { className: 'px-4 py-10 text-center', children: [(0, jsx_runtime_1.jsx)("p", { className: 'text-sm font-semibold text-ink', children: table_config_1.PsTableConfig.noMatchesTitle }), (0, jsx_runtime_1.jsx)("button", { className: ps_design_system_1.PallasoftClassNameService.merge(ps_table_control_classes_1.PsTableControlClasses.textButton, 'mt-2 text-primary'), onClick: clearFilters, type: 'button', children: "Clear search and filters" })] })) : null), !grouping && shouldVirtualize && cards.count < visibleRows.length ? ((0, jsx_runtime_1.jsx)("div", { "aria-hidden": 'true', className: 'h-px', ref: cards.sentinelRef })) : null] })) : null, (0, jsx_runtime_1.jsx)("div", { className: ps_design_system_1.PallasoftClassNameService.merge('ps-scrollbar overflow-x-auto overflow-y-hidden overscroll-x-contain', mobileLayout === 'cards' ? 'hidden sm:block' : ''), "data-overflow-end": overflow.edges.end, "data-overflow-start": overflow.edges.start, onScroll: overflow.update, ref: overflow.ref, children: renderReorder((api) => ((0, jsx_runtime_1.jsxs)("table", { className: ps_design_system_1.PallasoftClassNameService.merge('w-full border-collapse text-left', layout === 'fixed' ? 'table-fixed' : ''), children: [caption ? (0, jsx_runtime_1.jsx)("caption", { className: 'sr-only', children: caption }) : null, (0, jsx_runtime_1.jsx)("thead", { className: 'bg-mist/70 text-[0.68rem] font-semibold uppercase tracking-[0.18em] text-ink/45', children: (0, jsx_runtime_1.jsxs)("tr", { children: [reorder ? ((0, jsx_runtime_1.jsx)("th", { className: ps_design_system_1.PallasoftClassNameService.merge('w-9 min-w-9 pl-3 pr-0', pins.reorder), scope: 'col', children: reorder.enabled ? ((0, jsx_runtime_1.jsx)("span", { className: 'sr-only', children: reorder.columnLabel })) : reorder.disabledReason ? ((0, jsx_runtime_1.jsx)("span", { "aria-label": reorder.disabledReason, className: 'inline-flex cursor-help opacity-40', role: 'img', title: reorder.disabledReason, children: (0, jsx_runtime_1.jsx)(ps_core_components_1.PsDragGrip, {}) })) : null })) : null, isSelectable ? ((0, jsx_runtime_1.jsx)("th", { className: ps_design_system_1.PallasoftClassNameService.merge('w-10 min-w-10 pl-4 pr-0', pins.select), scope: 'col', children: (0, jsx_runtime_1.jsx)(ps_input_components_1.PsCheckbox, { isIndeterminate: !isPageSelected && pageIds.some((rowId) => selectedIdSet.has(rowId)), isSelected: isPageSelected, label: 'Select all rows on this page', onChange: togglePage }) })) : null, visibleColumns.map((column, columnIndex) => {
432
+ : renderCardList(shouldVirtualize ? visibleRows.slice(0, cards.count) : visibleRows, visibleRows.length === 0 && isSearching ? ((0, jsx_runtime_1.jsx)(ps_table_searching_state_1.PsTableSearchingState, { label: searchingLabel, skeletonRows: table_config_1.PsTableConfig.searchingSkeletonRows })) : visibleRows.length === 0 && isQueried ? ((0, jsx_runtime_1.jsxs)("div", { className: 'px-4 py-10 text-center', children: [(0, jsx_runtime_1.jsx)("p", { className: 'text-sm font-semibold text-ink', children: table_config_1.PsTableConfig.noMatchesTitle }), (0, jsx_runtime_1.jsx)("button", { className: ps_design_system_1.PallasoftClassNameService.merge(ps_table_control_classes_1.PsTableControlClasses.textButton, 'mt-2 text-primary'), onClick: clearFilters, type: 'button', children: "Clear search and filters" })] })) : null), !grouping && shouldVirtualize && cards.count < visibleRows.length ? ((0, jsx_runtime_1.jsx)("div", { "aria-hidden": 'true', className: 'h-px', ref: cards.sentinelRef })) : null] })) : null, (0, jsx_runtime_1.jsx)("div", { className: ps_design_system_1.PallasoftClassNameService.merge(stickyTop === undefined
433
+ ? 'ps-scrollbar overflow-x-auto overflow-y-hidden overscroll-x-contain'
434
+ : 'overflow-x-clip', 'transition-opacity duration-150', isRefreshing ? 'opacity-60' : '', mobileLayout === 'cards' ? 'hidden sm:block' : ''), "data-overflow-end": overflow.edges.end, "data-overflow-start": overflow.edges.start, onScroll: overflow.update, ref: overflow.ref, children: renderReorder((api) => ((0, jsx_runtime_1.jsxs)("table", { className: ps_design_system_1.PallasoftClassNameService.merge('w-full border-collapse text-left', layout === 'fixed' ? 'table-fixed' : ''), children: [caption ? (0, jsx_runtime_1.jsx)("caption", { className: 'sr-only', children: caption }) : null, (0, jsx_runtime_1.jsx)("thead", { className: ps_design_system_1.PallasoftClassNameService.merge('bg-mist/70 text-[0.68rem] font-semibold uppercase tracking-[0.18em] text-ink/45', stickyTop === undefined
435
+ ? ''
436
+ : 'sticky z-docked bg-surface [&_th]:border-b [&_th]:border-line [&>tr]:bg-mist/70'), style: stickyTop === undefined
437
+ ? undefined
438
+ : { top: `calc(${stickyTop} + ${stickyHeight}px)` }, children: (0, jsx_runtime_1.jsxs)("tr", { children: [reorder ? ((0, jsx_runtime_1.jsx)("th", { className: ps_design_system_1.PallasoftClassNameService.merge('w-9 min-w-9 pl-3 pr-0', pins.reorder), scope: 'col', children: reorder.enabled ? ((0, jsx_runtime_1.jsx)("span", { className: 'sr-only', children: reorder.columnLabel })) : reorder.disabledReason ? ((0, jsx_runtime_1.jsx)("span", { "aria-label": reorder.disabledReason, className: 'inline-flex cursor-help opacity-40', role: 'img', title: reorder.disabledReason, children: (0, jsx_runtime_1.jsx)(ps_core_components_1.PsDragGrip, {}) })) : null })) : null, isSelectable ? ((0, jsx_runtime_1.jsx)("th", { className: ps_design_system_1.PallasoftClassNameService.merge('w-10 min-w-10 pl-4 pr-0', pins.select), scope: 'col', children: (0, jsx_runtime_1.jsx)(ps_input_components_1.PsCheckbox, { isIndeterminate: !isPageSelected && pageIds.some((rowId) => selectedIdSet.has(rowId)), isSelected: isPageSelected, label: 'Select all rows on this page', onChange: togglePage }) })) : null, visibleColumns.map((column, columnIndex) => {
365
439
  const align = column.align !== null && column.align !== undefined ? column.align : 'left';
366
440
  const isSorted = sort !== null && sort.columnId === column.id;
367
441
  return ((0, jsx_runtime_1.jsx)("th", { "aria-sort": isSorted
@@ -392,6 +466,8 @@ const PsDataTable = ({ caption, className, columns, defaultSort, density = 'norm
392
466
  ]
393
467
  : renderEntries(api, visibleRows.map((row) => ({ row })))] }), hasFooter ? ((0, jsx_runtime_1.jsx)("tfoot", { className: 'border-t-2 border-line bg-mist/50 text-sm font-semibold text-ink', children: (0, jsx_runtime_1.jsxs)("tr", { children: [reorder ? (0, jsx_runtime_1.jsx)("td", { className: pins.reorder }) : null, isSelectable ? (0, jsx_runtime_1.jsx)("td", { className: pins.select }) : null, visibleColumns.map((column, columnIndex) => ((0, jsx_runtime_1.jsx)("td", { className: ps_design_system_1.PallasoftClassNameService.merge(densityClassNames[density].cell, placementOf(column, columnIndex), alignClassNames[column.align !== null && column.align !== undefined
394
468
  ? column.align
395
- : 'left'], 'whitespace-nowrap'), children: column.footer }, column.id)))] }) })) : null] }))) }), visibleRows.length > 0 && isSearching ? ((0, jsx_runtime_1.jsx)(ps_table_searching_state_1.PsTableSearchingState, { className: 'border-t border-line py-3', label: searchingLabel })) : null, pageSize && (!grouping || isServerPaginated) ? ((0, jsx_runtime_1.jsx)(ps_table_pagination_1.PsTablePagination, { isPartial: isPartial, loadedPageCount: pageCountOf(loadedRowCount), onPageChange: changePage, page: safePage, pageCount: pageCount, pageSize: pageSize, totalRows: rowCount })) : null] })] }));
469
+ : 'left'], 'whitespace-nowrap'), children: column.footer }, column.id)))] }) })) : null] }))) }), visibleRows.length > 0 && isSearching ? ((0, jsx_runtime_1.jsx)(ps_table_searching_state_1.PsTableSearchingState, { className: 'border-t border-line py-3', label: searchingLabel })) : null, showsPagination && paginationPosition !== ps_table_pagination_position_1.PsTablePaginationPosition.top
470
+ ? renderPagination('')
471
+ : null] })] }));
396
472
  };
397
473
  exports.PsDataTable = PsDataTable;
@@ -0,0 +1,10 @@
1
+ export interface PsSelectAllMatchingBannerProps {
2
+ className?: string;
3
+ isActive: boolean;
4
+ noun?: string;
5
+ onActivate: () => void;
6
+ onDeactivate: () => void;
7
+ pageCount: number;
8
+ total: number;
9
+ }
10
+ export declare const PsSelectAllMatchingBanner: ({ className, isActive, noun, onActivate, onDeactivate, pageCount, total, }: PsSelectAllMatchingBannerProps) => import("react").JSX.Element;
@@ -0,0 +1,10 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.PsSelectAllMatchingBanner = void 0;
4
+ const jsx_runtime_1 = require("react/jsx-runtime");
5
+ const ps_design_system_1 = require("@pallasoft/ps-design-system");
6
+ const ps_table_control_classes_1 = require("../constants/ps-table-control-classes");
7
+ const PsSelectAllMatchingBanner = ({ className, isActive, noun = 'rows', onActivate, onDeactivate, pageCount, total, }) => ((0, jsx_runtime_1.jsxs)("div", { "aria-live": 'polite', className: ps_design_system_1.PallasoftClassNameService.merge('flex flex-wrap items-center justify-center gap-x-2 gap-y-1 rounded-ps-control bg-primary/10 px-3 py-2 text-sm text-ink', className), role: 'status', children: [(0, jsx_runtime_1.jsx)("span", { children: isActive
8
+ ? `All ${total.toLocaleString()} ${noun} matching are selected.`
9
+ : `${pageCount.toLocaleString()} ${noun} on this page are selected.` }), (0, jsx_runtime_1.jsx)("button", { className: ps_design_system_1.PallasoftClassNameService.merge(ps_table_control_classes_1.PsTableControlClasses.textButton, 'text-primary'), onClick: isActive ? onDeactivate : onActivate, type: 'button', children: isActive ? 'Clear selection' : `Select all ${total.toLocaleString()} matching` })] }));
10
+ exports.PsSelectAllMatchingBanner = PsSelectAllMatchingBanner;
@@ -1,5 +1,7 @@
1
+ import type { PsTableCursorPaging } from '../interfaces/ps-table-cursor-paging';
1
2
  export interface PsTablePaginationProps {
2
3
  className?: string;
4
+ cursor?: PsTableCursorPaging;
3
5
  isPartial?: boolean;
4
6
  loadedPageCount?: number;
5
7
  onPageChange: (page: number) => void;
@@ -8,4 +10,4 @@ export interface PsTablePaginationProps {
8
10
  pageSize: number;
9
11
  totalRows: number;
10
12
  }
11
- export declare const PsTablePagination: ({ className, isPartial, loadedPageCount, onPageChange, page, pageCount, pageSize, totalRows, }: PsTablePaginationProps) => import("react").JSX.Element;
13
+ export declare const PsTablePagination: ({ className, cursor, isPartial, loadedPageCount, onPageChange, page, pageCount, pageSize, totalRows, }: PsTablePaginationProps) => import("react").JSX.Element;
@@ -4,12 +4,20 @@ exports.PsTablePagination = void 0;
4
4
  const jsx_runtime_1 = require("react/jsx-runtime");
5
5
  const ps_design_system_1 = require("@pallasoft/ps-design-system");
6
6
  const ps_table_control_classes_1 = require("../constants/ps-table-control-classes");
7
- const PsTablePagination = ({ className, isPartial = false, loadedPageCount, onPageChange, page, pageCount, pageSize, totalRows, }) => {
7
+ const PsTablePagination = ({ className, cursor, isPartial = false, loadedPageCount, onPageChange, page, pageCount, pageSize, totalRows, }) => {
8
8
  const firstRow = totalRows === 0 ? 0 : (page - 1) * pageSize + 1;
9
9
  const lastRow = Math.min(page * pageSize, totalRows);
10
+ const approximately = cursor !== undefined && cursor.isEstimate ? 'about ' : '';
11
+ const pageNumber = cursor === undefined ? Math.min(page, pageCount) : cursor.pageNumber;
12
+ const cursorFirst = cursor === undefined ? firstRow : (cursor.pageNumber - 1) * pageSize + 1;
13
+ const cursorLast = cursor === undefined ? lastRow : Math.min(cursor.pageNumber * pageSize, totalRows);
10
14
  return ((0, jsx_runtime_1.jsxs)("nav", { "aria-label": 'Pagination', className: ps_design_system_1.PallasoftClassNameService.merge('flex flex-wrap items-center justify-between gap-3 border-t border-line px-4 py-3', className), children: [(0, jsx_runtime_1.jsx)("p", { className: 'text-sm text-ink/55', children: totalRows === 0
11
15
  ? 'No rows'
12
- : `${firstRow}–${lastRow} of ${totalRows}${isPartial ? '+' : ''}` }), (0, jsx_runtime_1.jsxs)("div", { className: 'flex items-center gap-2', children: [(0, jsx_runtime_1.jsx)("button", { className: ps_table_control_classes_1.PsTableControlClasses.paginationButton, disabled: page <= 1, onClick: () => onPageChange(page - 1), type: 'button', children: "Previous" }), (0, jsx_runtime_1.jsxs)("span", { className: 'hidden text-sm text-ink/65 sm:inline', children: ["Page ", Math.min(page, pageCount), " of ", pageCount] }), (0, jsx_runtime_1.jsx)("button", { className: ps_table_control_classes_1.PsTableControlClasses.paginationButton, disabled: page >=
13
- (loadedPageCount === undefined ? pageCount : Math.min(loadedPageCount, pageCount)), onClick: () => onPageChange(page + 1), type: 'button', children: "Next" })] })] }));
16
+ : cursor === undefined
17
+ ? `${firstRow}–${lastRow} of ${totalRows}${isPartial ? '+' : ''}`
18
+ : `${cursorFirst}–${cursorLast} of ${approximately}${totalRows.toLocaleString()}` }), (0, jsx_runtime_1.jsxs)("div", { className: 'flex items-center gap-2', children: [cursor !== undefined && cursor.pageSizeOptions !== undefined && cursor.onPageSizeChange ? ((0, jsx_runtime_1.jsxs)("label", { className: 'flex items-center gap-2 text-sm text-ink/65', children: [(0, jsx_runtime_1.jsx)("span", { className: 'hidden sm:inline', children: "Rows per page" }), (0, jsx_runtime_1.jsx)("select", { "aria-label": 'Rows per page', className: 'ps-input-control ps-focus-ring ps-control ps-control-padding rounded-ps-control text-sm', onChange: (event) => cursor.onPageSizeChange?.(Number(event.target.value)), value: pageSize, children: cursor.pageSizeOptions.map((option) => ((0, jsx_runtime_1.jsx)("option", { value: option, children: option }, option))) })] })) : null, (0, jsx_runtime_1.jsx)("button", { className: ps_table_control_classes_1.PsTableControlClasses.paginationButton, disabled: cursor === undefined ? page <= 1 : !cursor.hasPrevious, onClick: () => (cursor === undefined ? onPageChange(page - 1) : cursor.onPrevious()), type: 'button', children: "Previous" }), (0, jsx_runtime_1.jsxs)("span", { className: 'hidden text-sm text-ink/65 sm:inline', children: ["Page ", pageNumber, " of ", approximately, pageCount] }), (0, jsx_runtime_1.jsx)("button", { className: ps_table_control_classes_1.PsTableControlClasses.paginationButton, disabled: cursor === undefined
19
+ ? page >=
20
+ (loadedPageCount === undefined ? pageCount : Math.min(loadedPageCount, pageCount))
21
+ : !cursor.hasNext, onClick: () => (cursor === undefined ? onPageChange(page + 1) : cursor.onNext()), onFocus: cursor === undefined ? undefined : cursor.onNextIntent, onPointerEnter: cursor === undefined ? undefined : cursor.onNextIntent, type: 'button', children: "Next" })] })] }));
14
22
  };
15
23
  exports.PsTablePagination = PsTablePagination;
@@ -1,8 +1,9 @@
1
1
  import type { ReactNode } from 'react';
2
2
  import { type UsePsTableReorderInput } from '../hooks/use-ps-table-reorder';
3
+ import type { PsTableDragSize } from '../interfaces/table-drag-size';
3
4
  import type { PsTableReorderApi } from '../interfaces/table-reorder-api';
4
5
  export interface PsTableReorderFrameProps extends UsePsTableReorderInput {
5
6
  children: (api: PsTableReorderApi) => ReactNode;
6
- renderOverlay: (rowId: string) => ReactNode;
7
+ renderOverlay: (rowId: string, size: PsTableDragSize | null) => ReactNode;
7
8
  }
8
9
  export declare const PsTableReorderFrame: ({ children, renderOverlay, ...input }: PsTableReorderFrameProps) => import("react").JSX.Element;
@@ -9,7 +9,7 @@ const use_ps_table_reorder_1 = require("../hooks/use-ps-table-reorder");
9
9
  const ps_table_reorder_service_1 = require("../services/ps-table-reorder-service");
10
10
  const ps_table_sortable_row_1 = require("./ps-table-sortable-row");
11
11
  const PsTableReorderFrame = ({ children, renderOverlay, ...input }) => {
12
- const { activeId, activeRunId, blockedReason, contextProps, drop, placements } = (0, use_ps_table_reorder_1.usePsTableReorder)(input);
12
+ const { activeId, activeRunId, activeSize, blockedReason, contextProps, drop, placements } = (0, use_ps_table_reorder_1.usePsTableReorder)(input);
13
13
  const itemById = new Map(input.items.map((item) => [item.id, item]));
14
14
  const { nesting } = input;
15
15
  const api = {
@@ -22,7 +22,7 @@ const PsTableReorderFrame = ({ children, renderOverlay, ...input }) => {
22
22
  return {
23
23
  dropPlacement: drop !== null && drop.overId === rowId ? drop.placement : null,
24
24
  handleLabel: item === undefined ? '' : item.handleLabel,
25
- hasHandle: item !== undefined && input.enabled && nesting.canDrag(rowId),
25
+ hasHandle: item !== undefined && item.isDraggable && input.enabled && nesting.canDrag(rowId),
26
26
  isDisabled: !input.enabled,
27
27
  isDropTarget: item !== undefined,
28
28
  rowId,
@@ -30,7 +30,11 @@ const PsTableReorderFrame = ({ children, renderOverlay, ...input }) => {
30
30
  return {
31
31
  dropPlacement: null,
32
32
  handleLabel: item === undefined ? '' : item.handleLabel,
33
- hasHandle: item !== undefined && input.enabled && placement !== undefined && placement.size > 1,
33
+ hasHandle: item !== undefined &&
34
+ item.isDraggable &&
35
+ input.enabled &&
36
+ placement !== undefined &&
37
+ placement.size > 1,
34
38
  isDisabled: activeRunId !== null && (placement === undefined || placement.runId !== activeRunId),
35
39
  isDropTarget: false,
36
40
  rowId,
@@ -38,6 +42,6 @@ const PsTableReorderFrame = ({ children, renderOverlay, ...input }) => {
38
42
  },
39
43
  run: (runId, ids, runChildren) => ((0, jsx_runtime_1.jsx)(sortable_1.SortableContext, { items: ids, strategy: nesting === undefined ? sortable_1.verticalListSortingStrategy : ps_table_reorder_service_1.PsTableReorderService.still, children: runChildren }, runId)),
40
44
  };
41
- return ((0, jsx_runtime_1.jsxs)(core_1.DndContext, { ...contextProps, children: [children(api), blockedReason === null ? null : ((0, jsx_runtime_1.jsx)("p", { className: 'pointer-events-none fixed bottom-6 left-1/2 z-50 max-w-sm -translate-x-1/2 rounded-ps-control bg-ink px-3 py-2 text-sm text-white shadow-lg', role: 'status', children: blockedReason })), (0, jsx_runtime_1.jsx)(ps_core_components_1.PsDragOverlay, { className: ps_core_components_1.PsDragClasses.lifted, frames: ps_core_components_1.PsDragListLiftFrames, children: activeId === null ? null : renderOverlay(activeId) })] }));
45
+ return ((0, jsx_runtime_1.jsxs)(core_1.DndContext, { ...contextProps, children: [children(api), blockedReason === null ? null : ((0, jsx_runtime_1.jsx)("p", { className: 'pointer-events-none fixed bottom-6 left-1/2 z-50 max-w-sm -translate-x-1/2 rounded-ps-control bg-ink px-3 py-2 text-sm text-white shadow-lg', role: 'status', children: blockedReason })), (0, jsx_runtime_1.jsx)(ps_core_components_1.PsDragOverlay, { className: ps_core_components_1.PsDragClasses.lifted, frames: ps_core_components_1.PsDragListLiftFrames, isDropAnimated: nesting === undefined, children: activeId === null ? null : renderOverlay(activeId, activeSize) })] }));
42
46
  };
43
47
  exports.PsTableReorderFrame = PsTableReorderFrame;
@@ -0,0 +1,8 @@
1
+ export declare const PsServerRowsConfig: {
2
+ readonly cacheSize: 8;
3
+ readonly debounceMs: 250;
4
+ readonly defaultPageSize: 100;
5
+ readonly idleFallbackMs: 200;
6
+ readonly idleTimeoutMs: 1000;
7
+ readonly pageSizes: readonly [50, 100, 200];
8
+ };
@@ -0,0 +1,11 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.PsServerRowsConfig = void 0;
4
+ exports.PsServerRowsConfig = {
5
+ cacheSize: 8,
6
+ debounceMs: 250,
7
+ defaultPageSize: 100,
8
+ idleFallbackMs: 200,
9
+ idleTimeoutMs: 1000,
10
+ pageSizes: [50, 100, 200],
11
+ };
@@ -2,7 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.PsTableDropClasses = void 0;
4
4
  exports.PsTableDropClasses = {
5
- after: '[&>td]:shadow-[inset_0_-2px_0_0_rgb(var(--ps-color-primary-rgb))]',
6
- before: '[&>td]:shadow-[inset_0_2px_0_0_rgb(var(--ps-color-primary-rgb))]',
5
+ after: '[&>td]:bg-[linear-gradient(rgb(var(--ps-color-primary-rgb)),rgb(var(--ps-color-primary-rgb)))] [&>td]:bg-[length:100%_2px] [&>td]:bg-bottom [&>td]:bg-no-repeat',
6
+ before: '[&>td]:bg-[linear-gradient(rgb(var(--ps-color-primary-rgb)),rgb(var(--ps-color-primary-rgb)))] [&>td]:bg-[length:100%_2px] [&>td]:bg-top [&>td]:bg-no-repeat',
7
7
  into: 'bg-primary/10 [&>td]:shadow-[inset_0_0_0_2px_rgb(var(--ps-color-primary-rgb)/0.5)]',
8
8
  };
@@ -0,0 +1,6 @@
1
+ export declare const PsTablePaginationPosition: {
2
+ readonly both: "both";
3
+ readonly bottom: "bottom";
4
+ readonly top: "top";
5
+ };
6
+ export type PsTablePaginationPosition = (typeof PsTablePaginationPosition)[keyof typeof PsTablePaginationPosition];
@@ -0,0 +1,8 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.PsTablePaginationPosition = void 0;
4
+ exports.PsTablePaginationPosition = {
5
+ both: 'both',
6
+ bottom: 'bottom',
7
+ top: 'top',
8
+ };