@pallasoft/ps-table-components 1.1.0 → 1.2.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.
@@ -1,15 +1,19 @@
1
+ import { type ReactNode } from 'react';
1
2
  import type { PsTableColumn } from '../interfaces/table-column';
2
3
  export interface PsDataTableProps<RowData> {
3
4
  caption?: string;
4
5
  className?: string;
5
6
  columns: PsTableColumn<RowData>[];
6
7
  density?: 'compact' | 'normal';
8
+ /** Ids of rows whose `renderExpandedRow` content is shown beneath them. */
9
+ expandedRowIds?: string[];
7
10
  getRowId: (row: RowData) => string;
8
11
  onPageChange?: (page: number) => void;
9
12
  onRowClick?: (row: RowData) => void;
10
13
  page?: number;
11
14
  pageSize?: number;
15
+ renderExpandedRow?: (row: RowData) => ReactNode;
12
16
  rows: RowData[];
13
17
  totalRows?: number;
14
18
  }
15
- export declare const PsDataTable: <RowData>({ caption, className, columns, density, getRowId, onPageChange, onRowClick, page, pageSize, rows, totalRows, }: PsDataTableProps<RowData>) => import("react").JSX.Element;
19
+ export declare const PsDataTable: <RowData>({ caption, className, columns, density, expandedRowIds, getRowId, onPageChange, onRowClick, page, pageSize, renderExpandedRow, rows, totalRows, }: PsDataTableProps<RowData>) => import("react").JSX.Element;
@@ -4,6 +4,7 @@ exports.PsDataTable = void 0;
4
4
  const jsx_runtime_1 = require("react/jsx-runtime");
5
5
  const react_1 = require("react");
6
6
  const ps_design_system_1 = require("@pallasoft/ps-design-system");
7
+ const ps_motion_components_1 = require("@pallasoft/ps-motion-components");
7
8
  const ps_table_pagination_1 = require("./ps-table-pagination");
8
9
  const densityClassNames = {
9
10
  compact: {
@@ -15,12 +16,13 @@ const densityClassNames = {
15
16
  head: 'px-4 py-3.5',
16
17
  },
17
18
  };
19
+ const columnStyle = (column) => column.width || column.minWidth ? { minWidth: column.minWidth, width: column.width } : undefined;
18
20
  const alignClassNames = {
19
21
  center: 'text-center',
20
22
  left: 'text-left',
21
23
  right: 'text-right tabular-nums',
22
24
  };
23
- const PsDataTable = ({ caption, className, columns, density = 'normal', getRowId, onPageChange, onRowClick, page, pageSize, rows, totalRows, }) => {
25
+ const PsDataTable = ({ caption, className, columns, density = 'normal', expandedRowIds, getRowId, onPageChange, onRowClick, page, pageSize, renderExpandedRow, rows, totalRows, }) => {
24
26
  const containerRef = (0, react_1.useRef)(null);
25
27
  const hasFooter = columns.some((column) => column.footer !== undefined);
26
28
  const [uncontrolledPage, setUncontrolledPage] = (0, react_1.useState)(1);
@@ -43,13 +45,21 @@ const PsDataTable = ({ caption, className, columns, density = 'normal', getRowId
43
45
  containerRef.current?.scrollIntoView({ behavior: 'smooth', block: 'start' });
44
46
  setUncontrolledPage(next);
45
47
  };
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] }));
48
+ 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: columnStyle(column), children: column.label }, column.id))) }) }), (0, jsx_runtime_1.jsx)("tbody", { className: 'divide-y divide-line', children: visibleRows.map((row) => {
49
+ const rowId = getRowId(row);
50
+ const isExpanded = expandedRowIds ? expandedRowIds.includes(rowId) : false;
51
+ return ((0, jsx_runtime_1.jsxs)(react_1.Fragment, { children: [(0, jsx_runtime_1.jsx)("tr", { className: ps_design_system_1.PallasoftClassNameService.merge('align-middle transition', onRowClick
52
+ ? 'ps-focus-ring cursor-pointer hover:bg-mist/60'
53
+ : 'hover:bg-mist/40'), onClick: onRowClick ? () => onRowClick(row) : undefined, onKeyDown: onRowClick
54
+ ? (event) => {
55
+ if (event.key !== 'Enter' && event.key !== ' ')
56
+ return;
57
+ event.preventDefault();
58
+ onRowClick(row);
59
+ }
60
+ : 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
61
+ ? column.align
62
+ : 'left'], column.wrap ? '' : 'whitespace-nowrap', 'text-ink'), style: columnStyle(column), children: column.render(row) }, column.id))) }), renderExpandedRow ? ((0, jsx_runtime_1.jsx)("tr", { className: isExpanded ? '' : 'border-t-0', children: (0, jsx_runtime_1.jsx)("td", { className: 'p-0', colSpan: columns.length, children: (0, jsx_runtime_1.jsx)(ps_motion_components_1.PsCollapse, { isOpen: isExpanded, children: (0, jsx_runtime_1.jsx)("div", { className: 'bg-mist/40 px-4 py-4', children: renderExpandedRow(row) }) }) }) })) : null] }, rowId));
63
+ }) }), 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
64
  };
55
65
  exports.PsDataTable = PsDataTable;
@@ -4,6 +4,10 @@ export interface PsTableColumn<RowData> {
4
4
  footer?: ReactNode;
5
5
  id: string;
6
6
  label: string;
7
+ /** Stops the table squeezing this column below the given CSS width. */
8
+ minWidth?: string;
7
9
  render: (row: RowData) => ReactNode;
8
10
  width?: string;
11
+ /** Lets long cell content wrap onto several lines. Cells stay on one line by default. */
12
+ wrap?: boolean;
9
13
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pallasoft/ps-table-components",
3
- "version": "1.1.0",
3
+ "version": "1.2.0",
4
4
  "private": false,
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",
@@ -68,6 +68,7 @@
68
68
  "url": "git+https://github.com/pallasoft/ps-table-components.git"
69
69
  },
70
70
  "dependencies": {
71
- "@pallasoft/ps-design-system": "^1.1.0"
71
+ "@pallasoft/ps-design-system": "^1.1.0",
72
+ "@pallasoft/ps-motion-components": "^1.1.0"
72
73
  }
73
74
  }