@pallasoft/ps-table-components 1.0.0 → 1.1.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.
- package/dist/components/ps-data-table.d.ts +7 -1
- package/dist/components/ps-data-table.js +40 -1
- package/dist/components/ps-table-pagination.d.ts +9 -0
- package/dist/components/ps-table-pagination.js +12 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/interfaces/table-column.d.ts +3 -0
- package/package.json +6 -2
|
@@ -1,9 +1,15 @@
|
|
|
1
1
|
import type { PsTableColumn } from '../interfaces/table-column';
|
|
2
2
|
export interface PsDataTableProps<RowData> {
|
|
3
3
|
caption?: string;
|
|
4
|
+
className?: string;
|
|
4
5
|
columns: PsTableColumn<RowData>[];
|
|
5
6
|
density?: 'compact' | 'normal';
|
|
6
7
|
getRowId: (row: RowData) => string;
|
|
8
|
+
onPageChange?: (page: number) => void;
|
|
9
|
+
onRowClick?: (row: RowData) => void;
|
|
10
|
+
page?: number;
|
|
11
|
+
pageSize?: number;
|
|
7
12
|
rows: RowData[];
|
|
13
|
+
totalRows?: number;
|
|
8
14
|
}
|
|
9
|
-
export declare const PsDataTable: <RowData>({ caption, columns, density, getRowId, rows, }: PsDataTableProps<RowData>) => import("react").JSX.Element;
|
|
15
|
+
export declare const PsDataTable: <RowData>({ caption, className, columns, density, getRowId, onPageChange, onRowClick, page, pageSize, rows, totalRows, }: PsDataTableProps<RowData>) => import("react").JSX.Element;
|
|
@@ -2,6 +2,9 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.PsDataTable = void 0;
|
|
4
4
|
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
5
|
+
const react_1 = require("react");
|
|
6
|
+
const ps_design_system_1 = require("@pallasoft/ps-design-system");
|
|
7
|
+
const ps_table_pagination_1 = require("./ps-table-pagination");
|
|
5
8
|
const densityClassNames = {
|
|
6
9
|
compact: {
|
|
7
10
|
cell: 'px-4 py-3',
|
|
@@ -12,5 +15,41 @@ const densityClassNames = {
|
|
|
12
15
|
head: 'px-4 py-3.5',
|
|
13
16
|
},
|
|
14
17
|
};
|
|
15
|
-
const
|
|
18
|
+
const alignClassNames = {
|
|
19
|
+
center: 'text-center',
|
|
20
|
+
left: 'text-left',
|
|
21
|
+
right: 'text-right tabular-nums',
|
|
22
|
+
};
|
|
23
|
+
const PsDataTable = ({ caption, className, columns, density = 'normal', getRowId, onPageChange, onRowClick, page, pageSize, rows, totalRows, }) => {
|
|
24
|
+
const containerRef = (0, react_1.useRef)(null);
|
|
25
|
+
const hasFooter = columns.some((column) => column.footer !== undefined);
|
|
26
|
+
const [uncontrolledPage, setUncontrolledPage] = (0, react_1.useState)(1);
|
|
27
|
+
const isPaginated = Boolean(pageSize);
|
|
28
|
+
const isServerPaginated = totalRows !== undefined;
|
|
29
|
+
const currentPage = page !== null && page !== undefined ? page : uncontrolledPage;
|
|
30
|
+
const rowCount = totalRows !== null && totalRows !== undefined ? totalRows : rows.length;
|
|
31
|
+
const pageCount = pageSize ? Math.max(Math.ceil(rowCount / pageSize), 1) : 1;
|
|
32
|
+
const safePage = Math.min(Math.max(currentPage, 1), pageCount);
|
|
33
|
+
const visibleRows = (0, react_1.useMemo)(() => {
|
|
34
|
+
if (!pageSize || isServerPaginated)
|
|
35
|
+
return rows;
|
|
36
|
+
return rows.slice((safePage - 1) * pageSize, safePage * pageSize);
|
|
37
|
+
}, [isServerPaginated, pageSize, rows, safePage]);
|
|
38
|
+
const changePage = (next) => {
|
|
39
|
+
if (onPageChange) {
|
|
40
|
+
onPageChange(next);
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
containerRef.current?.scrollIntoView({ behavior: 'smooth', block: 'start' });
|
|
44
|
+
setUncontrolledPage(next);
|
|
45
|
+
};
|
|
46
|
+
return ((0, jsx_runtime_1.jsxs)("div", { ref: containerRef, className: ps_design_system_1.PallasoftClassNameService.merge('ps-scrollbar overflow-x-auto rounded-[1.25rem] border border-line bg-surface', className), children: [(0, jsx_runtime_1.jsxs)("table", { className: 'w-full border-collapse text-left', 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.jsx)("tr", { children: columns.map((column) => ((0, jsx_runtime_1.jsx)("th", { className: ps_design_system_1.PallasoftClassNameService.merge(densityClassNames[density].head, alignClassNames[column.align !== null && column.align !== undefined ? column.align : 'left'], 'whitespace-nowrap'), scope: 'col', style: column.width ? { width: column.width } : undefined, children: column.label }, column.id))) }) }), (0, jsx_runtime_1.jsx)("tbody", { className: 'divide-y divide-line', children: visibleRows.map((row) => ((0, jsx_runtime_1.jsx)("tr", { className: ps_design_system_1.PallasoftClassNameService.merge('align-top transition', onRowClick ? 'ps-focus-ring cursor-pointer hover:bg-mist/60' : 'hover:bg-mist/40'), onClick: onRowClick ? () => onRowClick(row) : undefined, onKeyDown: onRowClick
|
|
47
|
+
? (event) => {
|
|
48
|
+
if (event.key !== 'Enter' && event.key !== ' ')
|
|
49
|
+
return;
|
|
50
|
+
event.preventDefault();
|
|
51
|
+
onRowClick(row);
|
|
52
|
+
}
|
|
53
|
+
: undefined, tabIndex: onRowClick ? 0 : undefined, children: columns.map((column) => ((0, jsx_runtime_1.jsx)("td", { className: ps_design_system_1.PallasoftClassNameService.merge(densityClassNames[density].cell, alignClassNames[column.align !== null && column.align !== undefined ? column.align : 'left'], 'text-ink'), children: column.render(row) }, column.id))) }, getRowId(row)))) }), hasFooter ? ((0, jsx_runtime_1.jsx)("tfoot", { className: 'border-t-2 border-line bg-mist/50 font-semibold text-ink', children: (0, jsx_runtime_1.jsx)("tr", { children: columns.map((column) => ((0, jsx_runtime_1.jsx)("td", { className: ps_design_system_1.PallasoftClassNameService.merge(densityClassNames[density].cell, alignClassNames[column.align !== null && column.align !== undefined ? column.align : 'left']), children: column.footer }, column.id))) }) })) : null] }), isPaginated && pageSize ? ((0, jsx_runtime_1.jsx)(ps_table_pagination_1.PsTablePagination, { onPageChange: changePage, page: safePage, pageCount: pageCount, pageSize: pageSize, totalRows: rowCount })) : null] }));
|
|
54
|
+
};
|
|
16
55
|
exports.PsDataTable = PsDataTable;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export interface PsTablePaginationProps {
|
|
2
|
+
className?: string;
|
|
3
|
+
onPageChange: (page: number) => void;
|
|
4
|
+
page: number;
|
|
5
|
+
pageCount: number;
|
|
6
|
+
pageSize: number;
|
|
7
|
+
totalRows: number;
|
|
8
|
+
}
|
|
9
|
+
export declare const PsTablePagination: ({ className, onPageChange, page, pageCount, pageSize, totalRows, }: PsTablePaginationProps) => import("react").JSX.Element;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.PsTablePagination = void 0;
|
|
4
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
5
|
+
const ps_design_system_1 = require("@pallasoft/ps-design-system");
|
|
6
|
+
const PsTablePagination = ({ className, onPageChange, page, pageCount, pageSize, totalRows, }) => {
|
|
7
|
+
const firstRow = totalRows === 0 ? 0 : (page - 1) * pageSize + 1;
|
|
8
|
+
const lastRow = Math.min(page * pageSize, totalRows);
|
|
9
|
+
const buttonClassName = 'ps-focus-ring rounded-ps-control border border-line px-3 py-1.5 text-sm font-semibold text-ink transition disabled:cursor-not-allowed disabled:opacity-40 enabled:hover:border-primary/40 enabled:hover:text-primary';
|
|
10
|
+
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-muted', children: totalRows === 0 ? 'No rows' : `Showing ${firstRow}-${lastRow} of ${totalRows}` }), (0, jsx_runtime_1.jsxs)("div", { className: 'flex items-center gap-2', children: [(0, jsx_runtime_1.jsx)("button", { className: buttonClassName, disabled: page <= 1, onClick: () => onPageChange(page - 1), type: 'button', children: "Previous" }), (0, jsx_runtime_1.jsxs)("span", { className: 'text-sm font-semibold text-ink', children: ["Page ", Math.min(page, pageCount), " of ", pageCount] }), (0, jsx_runtime_1.jsx)("button", { className: buttonClassName, disabled: page >= pageCount, onClick: () => onPageChange(page + 1), type: 'button', children: "Next" })] })] }));
|
|
11
|
+
};
|
|
12
|
+
exports.PsTablePagination = PsTablePagination;
|
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
|
@@ -15,4 +15,5 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
15
15
|
};
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
17
|
__exportStar(require("./components/ps-data-table"), exports);
|
|
18
|
+
__exportStar(require("./components/ps-table-pagination"), exports);
|
|
18
19
|
__exportStar(require("./interfaces/table-column"), exports);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pallasoft/ps-table-components",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.1.0",
|
|
4
4
|
"private": false,
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"types": "./dist/index.d.ts",
|
|
@@ -53,7 +53,8 @@
|
|
|
53
53
|
"husky": "^9.1.7",
|
|
54
54
|
"lint-staged": "^16.2.7",
|
|
55
55
|
"prettier": "^3.6.2",
|
|
56
|
-
"react": "^
|
|
56
|
+
"react": "^19.3.0",
|
|
57
|
+
"react-dom": "^19.3.0",
|
|
57
58
|
"semantic-release": "^24.2.0",
|
|
58
59
|
"ts-node": "^10.9.2",
|
|
59
60
|
"typescript": "^5.9.3"
|
|
@@ -65,5 +66,8 @@
|
|
|
65
66
|
"repository": {
|
|
66
67
|
"type": "git",
|
|
67
68
|
"url": "git+https://github.com/pallasoft/ps-table-components.git"
|
|
69
|
+
},
|
|
70
|
+
"dependencies": {
|
|
71
|
+
"@pallasoft/ps-design-system": "^1.1.0"
|
|
68
72
|
}
|
|
69
73
|
}
|