@pallasoft/ps-table-components 1.3.0 → 1.5.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 +2 -2
- package/dist/components/ps-data-table.js +10 -9
- package/dist/components/ps-table-bulk-bar.js +1 -1
- package/dist/components/ps-table-card-list.d.ts +17 -0
- package/dist/components/ps-table-card-list.js +30 -0
- package/dist/components/ps-table-column-picker.js +12 -6
- package/dist/components/ps-table-pagination.js +1 -1
- package/dist/components/ps-table-toolbar.js +4 -2
- package/dist/index.d.ts +0 -1
- package/dist/index.js +0 -1
- package/dist/interfaces/table-column.d.ts +1 -0
- package/package.json +5 -4
- package/dist/components/ps-table-row-actions.d.ts +0 -6
- package/dist/components/ps-table-row-actions.js +0 -9
|
@@ -10,8 +10,8 @@ export interface PsDataTableProps<RowData> {
|
|
|
10
10
|
defaultSort?: PsTableSort;
|
|
11
11
|
density?: 'compact' | 'normal';
|
|
12
12
|
expandedRowIds?: string[];
|
|
13
|
+
mobileLayout?: 'cards' | 'table';
|
|
13
14
|
getBulkActions?: (rows: RowData[]) => PsTableRowAction[];
|
|
14
|
-
getRowActions?: (row: RowData) => PsTableRowAction[];
|
|
15
15
|
getRowId: (row: RowData) => string;
|
|
16
16
|
getRowLabel?: (row: RowData) => string;
|
|
17
17
|
getSearchText?: (row: RowData) => string;
|
|
@@ -27,4 +27,4 @@ export interface PsDataTableProps<RowData> {
|
|
|
27
27
|
toolbarActions?: ReactNode;
|
|
28
28
|
totalRows?: number;
|
|
29
29
|
}
|
|
30
|
-
export declare const PsDataTable: <RowData>({ caption, className, columns, defaultSort, density, expandedRowIds,
|
|
30
|
+
export declare const PsDataTable: <RowData>({ caption, className, columns, defaultSort, density, expandedRowIds, mobileLayout, getBulkActions, getRowId, getRowLabel, getSearchText, onPageChange, onQueryChange, onRowClick, page, pageSize, query, renderExpandedRow, rows, searchPlaceholder, toolbarActions, totalRows, }: PsDataTableProps<RowData>) => import("react").JSX.Element;
|
|
@@ -4,13 +4,14 @@ 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_input_components_1 = require("@pallasoft/ps-input-components");
|
|
7
8
|
const ps_motion_components_1 = require("@pallasoft/ps-motion-components");
|
|
8
9
|
const table_config_1 = require("../constants/table-config");
|
|
9
10
|
const ps_table_query_service_1 = require("../services/ps-table-query-service");
|
|
10
11
|
const ps_table_bulk_bar_1 = require("./ps-table-bulk-bar");
|
|
12
|
+
const ps_table_card_list_1 = require("./ps-table-card-list");
|
|
11
13
|
const ps_table_column_picker_1 = require("./ps-table-column-picker");
|
|
12
14
|
const ps_table_pagination_1 = require("./ps-table-pagination");
|
|
13
|
-
const ps_table_row_actions_1 = require("./ps-table-row-actions");
|
|
14
15
|
const ps_table_sort_header_1 = require("./ps-table-sort-header");
|
|
15
16
|
const ps_table_toolbar_1 = require("./ps-table-toolbar");
|
|
16
17
|
const densityClassNames = {
|
|
@@ -29,7 +30,7 @@ const alignClassNames = {
|
|
|
29
30
|
left: 'text-left',
|
|
30
31
|
right: 'text-right tabular-nums',
|
|
31
32
|
};
|
|
32
|
-
const PsDataTable = ({ caption, className, columns, defaultSort, density = 'normal', expandedRowIds,
|
|
33
|
+
const PsDataTable = ({ caption, className, columns, defaultSort, density = 'normal', expandedRowIds, mobileLayout = 'cards', getBulkActions, getRowId, getRowLabel, getSearchText, onPageChange, onQueryChange, onRowClick, page, pageSize, query, renderExpandedRow, rows, searchPlaceholder = table_config_1.PsTableConfig.searchPlaceholder, toolbarActions, totalRows, }) => {
|
|
33
34
|
const containerRef = (0, react_1.useRef)(null);
|
|
34
35
|
const [uncontrolledPage, setUncontrolledPage] = (0, react_1.useState)(1);
|
|
35
36
|
const [uncontrolledQuery, setUncontrolledQuery] = (0, react_1.useState)(() => ps_table_query_service_1.PsTableQueryService.empty(defaultSort ? defaultSort : null));
|
|
@@ -49,7 +50,7 @@ const PsDataTable = ({ caption, className, columns, defaultSort, density = 'norm
|
|
|
49
50
|
const hasFilters = columns.some((column) => column.filter) && !isServerPaginated;
|
|
50
51
|
const hasToolbar = isSearchable || hasFilters || Boolean(toolbarActions);
|
|
51
52
|
const isSelectable = Boolean(getBulkActions);
|
|
52
|
-
const columnCount = visibleColumns.length + (
|
|
53
|
+
const columnCount = visibleColumns.length + (isSelectable ? 1 : 0);
|
|
53
54
|
const queriedRows = (0, react_1.useMemo)(() => isServerPaginated
|
|
54
55
|
? rows
|
|
55
56
|
: ps_table_query_service_1.PsTableQueryService.apply(rows, columns, filters, search, getSearchText, sort), [columns, filters, getSearchText, isServerPaginated, rows, search, sort]);
|
|
@@ -95,7 +96,7 @@ const PsDataTable = ({ caption, className, columns, defaultSort, density = 'norm
|
|
|
95
96
|
? current.filter((rowId) => !pageIds.includes(rowId))
|
|
96
97
|
: [...new Set([...current, ...pageIds])]);
|
|
97
98
|
const toggleRow = (rowId) => setSelectedIds((current) => current.includes(rowId) ? current.filter((id) => id !== rowId) : [...current, rowId]);
|
|
98
|
-
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 })) :
|
|
99
|
+
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
|
|
99
100
|
.filter((column) => column.canHide)
|
|
100
101
|
.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) => {
|
|
101
102
|
updateQuery({ filters: { ...filters, [columnId]: value } });
|
|
@@ -103,7 +104,7 @@ const PsDataTable = ({ caption, className, columns, defaultSort, density = 'norm
|
|
|
103
104
|
}, onSearchChange: (next) => {
|
|
104
105
|
updateQuery({ search: next });
|
|
105
106
|
resetPage();
|
|
106
|
-
}, 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: [(0, jsx_runtime_1.jsx)("div", { className: 'ps-scrollbar overflow-x-auto', 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.jsxs)("tr", { children: [isSelectable ? ((0, jsx_runtime_1.jsx)("th", { className: 'w-10 pl-4 pr-0', scope: 'col', children: (0, jsx_runtime_1.jsx)(
|
|
107
|
+
}, 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.jsx)("div", { className: 'sm:hidden', children: (0, jsx_runtime_1.jsx)(ps_table_card_list_1.PsTableCardList, { columns: visibleColumns, emptyContent: 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-focus-ring mt-2 rounded-full px-3 py-1.5 text-sm font-semibold text-primary', onClick: clearFilters, type: 'button', children: "Clear search and filters" })] })) : null, expandedRowIds: expandedRowIds, footerColumns: hasFooter ? visibleColumns.filter((column) => column.footer !== undefined) : [], getRowId: getRowId, getRowLabel: (row) => (getRowLabel ? getRowLabel(row) : getRowId(row)), isSelectable: isSelectable, onRowClick: onRowClick, onToggleRow: toggleRow, renderExpandedRow: renderExpandedRow, rows: visibleRows, selectedIds: selectedIds }) })) : null, (0, jsx_runtime_1.jsx)("div", { className: ps_design_system_1.PallasoftClassNameService.merge('ps-scrollbar overflow-x-auto', mobileLayout === 'cards' ? 'hidden sm:block' : ''), 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.jsxs)("tr", { children: [isSelectable ? ((0, jsx_runtime_1.jsx)("th", { className: 'w-10 pl-4 pr-0', scope: 'col', children: (0, jsx_runtime_1.jsx)(ps_input_components_1.PsCheckbox, { isIndeterminate: !isPageSelected && pageIds.some((rowId) => selectedIds.includes(rowId)), isSelected: isPageSelected, label: 'Select all rows on this page', onChange: togglePage }) })) : null, visibleColumns.map((column) => {
|
|
107
108
|
const align = column.align !== null && column.align !== undefined ? column.align : 'left';
|
|
108
109
|
const isSorted = sort !== null && sort.columnId === column.id;
|
|
109
110
|
return ((0, jsx_runtime_1.jsx)("th", { "aria-sort": isSorted
|
|
@@ -111,7 +112,7 @@ const PsDataTable = ({ caption, className, columns, defaultSort, density = 'norm
|
|
|
111
112
|
: column.sortValue && !isServerPaginated
|
|
112
113
|
? 'none'
|
|
113
114
|
: undefined, className: ps_design_system_1.PallasoftClassNameService.merge(densityClassNames[density].head, alignClassNames[align], 'whitespace-nowrap'), scope: 'col', style: columnStyle(column), children: column.sortValue && !isServerPaginated ? ((0, jsx_runtime_1.jsx)(ps_table_sort_header_1.PsTableSortHeader, { align: align, columnId: column.id, label: column.label, onSort: updateSort, sort: sort })) : (column.label) }, column.id));
|
|
114
|
-
})
|
|
115
|
+
})] }) }), (0, jsx_runtime_1.jsxs)("tbody", { className: 'divide-y divide-line', children: [visibleRows.length === 0 && isQueried ? ((0, jsx_runtime_1.jsx)("tr", { children: (0, jsx_runtime_1.jsxs)("td", { className: 'px-4 py-12 text-center', colSpan: columnCount, 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)("p", { className: 'mt-1 text-sm text-ink/55', children: table_config_1.PsTableConfig.noMatchesDescription }), (0, jsx_runtime_1.jsx)("button", { className: 'ps-focus-ring mt-3 rounded-full px-3 py-1.5 text-sm font-semibold text-primary hover:underline', onClick: clearFilters, type: 'button', children: "Clear search and filters" })] }) })) : null, visibleRows.map((row) => {
|
|
115
116
|
const rowId = getRowId(row);
|
|
116
117
|
const isExpanded = expandedRowIds ? expandedRowIds.includes(rowId) : false;
|
|
117
118
|
const rowLabel = getRowLabel ? getRowLabel(row) : rowId;
|
|
@@ -126,11 +127,11 @@ const PsDataTable = ({ caption, className, columns, defaultSort, density = 'norm
|
|
|
126
127
|
event.preventDefault();
|
|
127
128
|
onRowClick(row);
|
|
128
129
|
}
|
|
129
|
-
: undefined, tabIndex: onRowClick ? 0 : undefined, children: [isSelectable ? ((0, jsx_runtime_1.jsx)("td", { className: 'w-10 pl-4 pr-0', onClick: (event) => event.stopPropagation(), onKeyDown: (event) => event.stopPropagation(), children: (0, jsx_runtime_1.jsx)(
|
|
130
|
+
: undefined, tabIndex: onRowClick ? 0 : undefined, children: [isSelectable ? ((0, jsx_runtime_1.jsx)("td", { className: 'w-10 pl-4 pr-0', onClick: (event) => event.stopPropagation(), onKeyDown: (event) => event.stopPropagation(), children: (0, jsx_runtime_1.jsx)(ps_input_components_1.PsCheckbox, { isSelected: selectedIds.includes(rowId), label: `Select ${rowLabel}`, onChange: () => toggleRow(rowId) }) })) : null, visibleColumns.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
|
|
130
131
|
? column.align
|
|
131
|
-
: 'left'], column.wrap ? '' : 'whitespace-nowrap', 'text-sm text-ink'), style: columnStyle(column), children: column.render(row) }, column.id)))
|
|
132
|
+
: 'left'], column.wrap ? '' : 'whitespace-nowrap', 'text-sm 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: columnCount, 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));
|
|
132
133
|
})] }), 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: [isSelectable ? (0, jsx_runtime_1.jsx)("td", {}) : null, visibleColumns.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
|
|
133
134
|
? column.align
|
|
134
|
-
: 'left'], 'whitespace-nowrap'), children: column.footer }, column.id)))
|
|
135
|
+
: 'left'], 'whitespace-nowrap'), children: column.footer }, column.id)))] }) })) : null] }) }), pageSize ? ((0, jsx_runtime_1.jsx)(ps_table_pagination_1.PsTablePagination, { onPageChange: changePage, page: safePage, pageCount: pageCount, pageSize: pageSize, totalRows: rowCount })) : null] })] }));
|
|
135
136
|
};
|
|
136
137
|
exports.PsDataTable = PsDataTable;
|
|
@@ -3,5 +3,5 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.PsTableBulkBar = 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
|
-
const PsTableBulkBar = ({ actions, onClear, selectedCount }) => ((0, jsx_runtime_1.jsxs)("div", { "aria-live": 'polite', className: 'flex flex-wrap items-center gap-
|
|
6
|
+
const PsTableBulkBar = ({ actions, onClear, selectedCount }) => ((0, jsx_runtime_1.jsxs)("div", { "aria-live": 'polite', className: 'flex flex-wrap items-center gap-1 rounded-2xl border border-primary/30 bg-primary/10 px-2 py-1.5 sm:gap-2 sm:rounded-full', children: [(0, jsx_runtime_1.jsxs)("span", { className: 'px-2 text-sm font-semibold text-ink', children: [selectedCount, " selected"] }), actions.map((action) => ((0, jsx_runtime_1.jsx)("button", { className: ps_design_system_1.PallasoftClassNameService.merge('ps-focus-ring inline-flex min-h-8 items-center rounded-full px-3 text-sm font-semibold transition-colors disabled:opacity-40', action.isDanger ? 'text-danger hover:bg-danger/10' : 'text-ink hover:bg-ink/5'), disabled: action.isDisabled, onClick: action.onSelect, type: 'button', children: action.label }, action.id))), (0, jsx_runtime_1.jsx)("button", { className: 'ps-focus-ring ml-auto inline-flex min-h-8 items-center rounded-full px-3 text-sm font-semibold text-ink/65 hover:text-ink', onClick: onClear, type: 'button', children: "Clear selection" })] }));
|
|
7
7
|
exports.PsTableBulkBar = PsTableBulkBar;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { ReactNode } from 'react';
|
|
2
|
+
import type { PsTableColumn } from '../interfaces/table-column';
|
|
3
|
+
export interface PsTableCardListProps<RowData> {
|
|
4
|
+
columns: PsTableColumn<RowData>[];
|
|
5
|
+
emptyContent: ReactNode;
|
|
6
|
+
expandedRowIds?: string[];
|
|
7
|
+
footerColumns: PsTableColumn<RowData>[];
|
|
8
|
+
getRowId: (row: RowData) => string;
|
|
9
|
+
getRowLabel: (row: RowData) => string;
|
|
10
|
+
isSelectable: boolean;
|
|
11
|
+
onRowClick?: (row: RowData) => void;
|
|
12
|
+
onToggleRow: (rowId: string) => void;
|
|
13
|
+
renderExpandedRow?: (row: RowData) => ReactNode;
|
|
14
|
+
rows: RowData[];
|
|
15
|
+
selectedIds: string[];
|
|
16
|
+
}
|
|
17
|
+
export declare const PsTableCardList: <RowData>({ columns, emptyContent, expandedRowIds, footerColumns, getRowId, getRowLabel, isSelectable, onRowClick, onToggleRow, renderExpandedRow, rows, selectedIds, }: PsTableCardListProps<RowData>) => import("react").JSX.Element;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.PsTableCardList = 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_input_components_1 = require("@pallasoft/ps-input-components");
|
|
7
|
+
const ps_motion_components_1 = require("@pallasoft/ps-motion-components");
|
|
8
|
+
const PsTableCardList = ({ columns, emptyContent, expandedRowIds, footerColumns, getRowId, getRowLabel, isSelectable, onRowClick, onToggleRow, renderExpandedRow, rows, selectedIds, }) => {
|
|
9
|
+
const [primary, ...details] = columns.filter((column) => !column.hideOnCards);
|
|
10
|
+
const trailing = details.find((column) => column.align === 'right');
|
|
11
|
+
const rest = details.filter((column) => column !== trailing);
|
|
12
|
+
return ((0, jsx_runtime_1.jsxs)("ul", { className: 'divide-y divide-line', children: [rows.length === 0 ? (0, jsx_runtime_1.jsx)("li", { children: emptyContent }) : null, rows.map((row) => {
|
|
13
|
+
const rowId = getRowId(row);
|
|
14
|
+
const isExpanded = expandedRowIds ? expandedRowIds.includes(rowId) : false;
|
|
15
|
+
return ((0, jsx_runtime_1.jsxs)("li", { children: [(0, jsx_runtime_1.jsxs)("div", { "aria-label": onRowClick ? getRowLabel(row) : undefined, className: ps_design_system_1.PallasoftClassNameService.merge('flex gap-3 px-4 py-3.5 transition-colors', onRowClick ? 'ps-focus-ring cursor-pointer active:bg-mist/70' : ''), onClick: onRowClick ? () => onRowClick(row) : undefined, onKeyDown: onRowClick
|
|
16
|
+
? (event) => {
|
|
17
|
+
if (event.target !== event.currentTarget)
|
|
18
|
+
return;
|
|
19
|
+
if (event.key !== 'Enter' && event.key !== ' ')
|
|
20
|
+
return;
|
|
21
|
+
event.preventDefault();
|
|
22
|
+
onRowClick(row);
|
|
23
|
+
}
|
|
24
|
+
: undefined, role: onRowClick ? 'button' : undefined, tabIndex: onRowClick ? 0 : undefined, children: [isSelectable ? ((0, jsx_runtime_1.jsx)("div", { className: 'pt-0.5', onClick: (event) => event.stopPropagation(), onKeyDown: (event) => event.stopPropagation(), children: (0, jsx_runtime_1.jsx)(ps_input_components_1.PsCheckbox, { isSelected: selectedIds.includes(rowId), label: `Select ${getRowLabel(row)}`, onChange: () => onToggleRow(rowId) }) })) : null, (0, jsx_runtime_1.jsxs)("div", { className: 'flex min-w-0 flex-1 flex-col gap-2', children: [(0, jsx_runtime_1.jsxs)("div", { className: 'flex items-start justify-between gap-3', children: [(0, jsx_runtime_1.jsx)("div", { className: 'min-w-0 text-sm font-semibold text-ink', children: primary ? primary.render(row) : null }), trailing ? ((0, jsx_runtime_1.jsx)("div", { className: 'shrink-0 text-right text-sm font-semibold tabular-nums text-ink', children: trailing.render(row) })) : null] }), rest.length > 0 ? ((0, jsx_runtime_1.jsx)("dl", { className: 'grid grid-cols-2 gap-x-4 gap-y-1.5', children: rest
|
|
25
|
+
.map((column) => ({ column, value: column.render(row) }))
|
|
26
|
+
.filter(({ value }) => value !== null && value !== undefined && value !== '')
|
|
27
|
+
.map(({ column, value }) => ((0, jsx_runtime_1.jsxs)("div", { className: 'min-w-0', children: [(0, jsx_runtime_1.jsx)("dt", { className: 'text-[0.68rem] font-semibold uppercase tracking-[0.12em] text-ink/40', children: column.label }), (0, jsx_runtime_1.jsx)("dd", { className: 'truncate text-sm text-ink/80', children: value })] }, column.id))) })) : null] })] }), renderExpandedRow ? ((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));
|
|
28
|
+
}), footerColumns.length > 0 ? ((0, jsx_runtime_1.jsx)("li", { className: 'grid grid-cols-2 gap-x-4 gap-y-1.5 bg-mist/50 px-4 py-3', children: footerColumns.map((column) => ((0, jsx_runtime_1.jsxs)("div", { className: 'min-w-0', children: [(0, jsx_runtime_1.jsx)("p", { className: 'text-[0.68rem] font-semibold uppercase tracking-[0.12em] text-ink/40', children: column.label }), (0, jsx_runtime_1.jsx)("p", { className: 'truncate text-sm font-semibold text-ink', children: column.footer })] }, column.id))) })) : null] }));
|
|
29
|
+
};
|
|
30
|
+
exports.PsTableCardList = PsTableCardList;
|
|
@@ -2,13 +2,19 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.PsTableColumnPicker = void 0;
|
|
4
4
|
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
5
|
+
const ps_core_components_1 = require("@pallasoft/ps-core-components");
|
|
6
|
+
const ps_design_system_1 = require("@pallasoft/ps-design-system");
|
|
5
7
|
const ps_icons_1 = require("@pallasoft/ps-icons");
|
|
8
|
+
const ps_input_components_1 = require("@pallasoft/ps-input-components");
|
|
6
9
|
const react_aria_components_1 = require("react-aria-components");
|
|
7
|
-
const PsTableColumnPicker = ({ columns, hiddenColumnIds, onChange, }) =>
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
10
|
+
const PsTableColumnPicker = ({ columns, hiddenColumnIds, onChange, }) => {
|
|
11
|
+
const zIndex = (0, ps_core_components_1.usePsLayerZIndex)(ps_design_system_1.PallasoftZIndex.Dropdown);
|
|
12
|
+
const visibleCount = columns.filter((column) => !hiddenColumnIds.includes(column.id)).length;
|
|
13
|
+
return ((0, jsx_runtime_1.jsxs)(react_aria_components_1.DialogTrigger, { children: [(0, jsx_runtime_1.jsxs)(react_aria_components_1.Button, { className: 'ps-focus-ring ps-liquid ps-liquid-control inline-flex min-h-10 min-w-10 items-center justify-center gap-2 rounded-full px-3 text-sm font-semibold text-ink outline-none transition-colors hover:border-primary/40 sm:px-4', children: [(0, jsx_runtime_1.jsx)(ps_icons_1.PsIcon, { "aria-hidden": 'true', className: 'block h-4 w-4 sm:hidden', iconKey: ps_icons_1.PsIconKey.Columns }), (0, jsx_runtime_1.jsx)("span", { className: 'sr-only sm:not-sr-only', children: "Columns" }), (0, jsx_runtime_1.jsx)(ps_icons_1.PsIcon, { "aria-hidden": 'true', className: 'hidden h-4 w-4 sm:block', iconKey: ps_icons_1.PsIconKey.Chevron })] }), (0, jsx_runtime_1.jsx)(react_aria_components_1.Popover, { className: 'ps-floating-panel w-60 outline-none', offset: 6, placement: 'bottom end', style: { zIndex }, children: (0, jsx_runtime_1.jsx)(react_aria_components_1.Dialog, { "aria-label": 'Columns', className: 'flex flex-col gap-0.5 p-1.5 outline-none', children: (0, jsx_runtime_1.jsx)(ps_core_components_1.PsLayer, { zIndex: zIndex, children: columns.map((column) => {
|
|
14
|
+
const isVisible = !hiddenColumnIds.includes(column.id);
|
|
15
|
+
return ((0, jsx_runtime_1.jsx)(ps_input_components_1.PsCheckbox, { className: 'ps-floating-option w-full', isDisabled: isVisible && visibleCount <= 1, isSelected: isVisible, label: column.label, onChange: () => onChange(isVisible
|
|
11
16
|
? [...hiddenColumnIds, column.id]
|
|
12
|
-
: hiddenColumnIds.filter((hiddenId) => hiddenId !== column.id)),
|
|
13
|
-
|
|
17
|
+
: hiddenColumnIds.filter((hiddenId) => hiddenId !== column.id)), children: column.label }, column.id));
|
|
18
|
+
}) }) }) })] }));
|
|
19
|
+
};
|
|
14
20
|
exports.PsTableColumnPicker = PsTableColumnPicker;
|
|
@@ -7,6 +7,6 @@ const PsTablePagination = ({ className, onPageChange, page, pageCount, pageSize,
|
|
|
7
7
|
const firstRow = totalRows === 0 ? 0 : (page - 1) * pageSize + 1;
|
|
8
8
|
const lastRow = Math.min(page * pageSize, totalRows);
|
|
9
9
|
const buttonClassName = 'ps-focus-ring inline-flex min-h-9 items-center rounded-full border border-line px-3.5 text-sm font-semibold text-ink transition-colors disabled:cursor-not-allowed disabled:opacity-40 enabled:hover:border-primary/40';
|
|
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-ink/55', children: totalRows === 0 ? 'No rows' : `${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 text-ink/65', 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" })] })] }));
|
|
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-ink/55', children: totalRows === 0 ? 'No rows' : `${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: 'hidden text-sm text-ink/65 sm:inline', 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
11
|
};
|
|
12
12
|
exports.PsTablePagination = PsTablePagination;
|
|
@@ -2,15 +2,17 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.PsTableToolbar = void 0;
|
|
4
4
|
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
5
|
+
const ps_core_components_1 = require("@pallasoft/ps-core-components");
|
|
5
6
|
const ps_design_system_1 = require("@pallasoft/ps-design-system");
|
|
6
7
|
const ps_icons_1 = require("@pallasoft/ps-icons");
|
|
7
8
|
const react_aria_components_1 = require("react-aria-components");
|
|
8
9
|
const ps_table_query_service_1 = require("../services/ps-table-query-service");
|
|
9
10
|
const ps_table_filter_field_1 = require("./ps-table-filter-field");
|
|
10
|
-
const toolbarButtonClassName = 'ps-focus-ring ps-liquid ps-liquid-control inline-flex min-h-10 items-center gap-2 rounded-full px-
|
|
11
|
+
const toolbarButtonClassName = 'ps-focus-ring ps-liquid ps-liquid-control inline-flex min-h-10 min-w-10 items-center justify-center gap-2 rounded-full px-3 text-sm font-semibold text-ink outline-none transition-colors hover:border-primary/40 sm:px-4';
|
|
11
12
|
const PsTableToolbar = ({ actions, columns, filters, isSearchable, onClearFilters, onFilterChange, onSearchChange, rows, search, searchPlaceholder, }) => {
|
|
12
13
|
const filterableColumns = columns.filter((column) => column.filter);
|
|
14
|
+
const zIndex = (0, ps_core_components_1.usePsLayerZIndex)(ps_design_system_1.PallasoftZIndex.Dropdown);
|
|
13
15
|
const activeCount = filterableColumns.filter((column) => ps_table_query_service_1.PsTableQueryService.isActive(filters[column.id])).length;
|
|
14
|
-
return ((0, jsx_runtime_1.jsxs)("div", { className: 'flex flex-wrap items-center gap-2', children: [isSearchable ? ((0, jsx_runtime_1.jsxs)("label", { className: 'relative min-w-[12rem] flex-1 sm:max-w-xs', children: [(0, jsx_runtime_1.jsx)("span", { className: 'sr-only', children: searchPlaceholder }), (0, jsx_runtime_1.jsx)(ps_icons_1.PsIcon, { "aria-hidden": 'true', className: 'pointer-events-none absolute left-3.5 top-1/2 h-4 w-4 -translate-y-1/2 text-ink/45', iconKey: ps_icons_1.PsIconKey.Search }), (0, jsx_runtime_1.jsx)("input", { className: 'ps-input-control ps-focus-ring min-h-10 rounded-full pl-10 text-sm', onChange: (event) => onSearchChange(event.target.value), placeholder: searchPlaceholder, type: 'search', value: search })] })) : null, filterableColumns.length > 0 ? ((0, jsx_runtime_1.jsxs)(react_aria_components_1.DialogTrigger, { children: [(0, jsx_runtime_1.jsxs)(react_aria_components_1.Button, { className: toolbarButtonClassName, children: [(0, jsx_runtime_1.jsx)(ps_icons_1.PsIcon, { "aria-hidden": 'true', className: 'block h-4 w-4', iconKey: ps_icons_1.PsIconKey.Filter }), (0, jsx_runtime_1.jsx)("span", { children: "Filters" }), activeCount > 0 ? ((0, jsx_runtime_1.jsx)("span", { className: 'inline-flex h-5 min-w-5 items-center justify-center rounded-full bg-primary px-1.5 text-xs font-semibold text-[color:var(--ps-color-primary-contrast)]', children: activeCount })) : null] }), (0, jsx_runtime_1.jsx)(react_aria_components_1.Popover, { className: 'ps-floating-panel ps-scrollbar max-h-[min(34rem,80vh)] w-[min(22rem,calc(100vw-2rem))] overflow-y-auto outline-none', offset: 6, placement: 'bottom start', children: (0, jsx_runtime_1.
|
|
16
|
+
return ((0, jsx_runtime_1.jsxs)("div", { className: 'flex flex-wrap items-center gap-2', children: [isSearchable ? ((0, jsx_runtime_1.jsxs)("label", { className: 'relative basis-full sm:min-w-[12rem] sm:flex-1 sm:basis-auto sm:max-w-xs', children: [(0, jsx_runtime_1.jsx)("span", { className: 'sr-only', children: searchPlaceholder }), (0, jsx_runtime_1.jsx)(ps_icons_1.PsIcon, { "aria-hidden": 'true', className: 'pointer-events-none absolute left-3.5 top-1/2 h-4 w-4 -translate-y-1/2 text-ink/45', iconKey: ps_icons_1.PsIconKey.Search }), (0, jsx_runtime_1.jsx)("input", { className: 'ps-input-control ps-focus-ring min-h-10 rounded-full pl-10 text-sm', onChange: (event) => onSearchChange(event.target.value), placeholder: searchPlaceholder, type: 'search', value: search })] })) : null, filterableColumns.length > 0 ? ((0, jsx_runtime_1.jsxs)(react_aria_components_1.DialogTrigger, { children: [(0, jsx_runtime_1.jsxs)(react_aria_components_1.Button, { className: toolbarButtonClassName, children: [(0, jsx_runtime_1.jsx)(ps_icons_1.PsIcon, { "aria-hidden": 'true', className: 'block h-4 w-4', iconKey: ps_icons_1.PsIconKey.Filter }), (0, jsx_runtime_1.jsx)("span", { className: 'sr-only sm:not-sr-only', children: "Filters" }), activeCount > 0 ? ((0, jsx_runtime_1.jsx)("span", { className: 'inline-flex h-5 min-w-5 items-center justify-center rounded-full bg-primary px-1.5 text-xs font-semibold text-[color:var(--ps-color-primary-contrast)]', children: activeCount })) : null] }), (0, jsx_runtime_1.jsx)(react_aria_components_1.Popover, { className: 'ps-floating-panel ps-scrollbar max-h-[min(34rem,80vh)] w-[min(22rem,calc(100vw-2rem))] overflow-y-auto outline-none', offset: 6, placement: 'bottom start', style: { zIndex }, children: (0, jsx_runtime_1.jsx)(react_aria_components_1.Dialog, { "aria-label": 'Filters', className: 'flex flex-col gap-4 p-4 outline-none', children: (0, jsx_runtime_1.jsxs)(ps_core_components_1.PsLayer, { zIndex: zIndex, children: [filterableColumns.map((column) => ((0, jsx_runtime_1.jsx)(ps_table_filter_field_1.PsTableFilterField, { kind: column.filter ? column.filter.kind : 'text', label: column.label, onChange: (value) => onFilterChange(column.id, value), options: ps_table_query_service_1.PsTableQueryService.options(rows, column), value: filters[column.id] ? filters[column.id] : {} }, column.id))), (0, jsx_runtime_1.jsx)("div", { className: 'flex justify-end border-t border-line pt-3', children: (0, jsx_runtime_1.jsx)("button", { className: 'ps-focus-ring rounded-lg px-2 py-1 text-sm font-semibold text-ink/65 hover:text-ink disabled:opacity-40', disabled: activeCount === 0, onClick: onClearFilters, type: 'button', children: "Clear all" }) })] }) }) })] })) : null, activeCount > 0 ? ((0, jsx_runtime_1.jsx)("button", { className: ps_design_system_1.PallasoftClassNameService.merge('ps-focus-ring rounded-full px-3 py-2 text-sm font-semibold text-ink/65 hover:text-ink'), onClick: onClearFilters, type: 'button', children: "Clear filters" })) : null, actions ? (0, jsx_runtime_1.jsx)("div", { className: 'ml-auto flex items-center gap-2', children: actions }) : null] }));
|
|
15
17
|
};
|
|
16
18
|
exports.PsTableToolbar = PsTableToolbar;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
export * from './components/ps-data-table';
|
|
2
2
|
export * from './components/ps-table-pagination';
|
|
3
|
-
export * from './components/ps-table-row-actions';
|
|
4
3
|
export * from './constants/table-filter-kind';
|
|
5
4
|
export * from './interfaces/table-column';
|
|
6
5
|
export * from './interfaces/table-column-filter';
|
package/dist/index.js
CHANGED
|
@@ -16,7 +16,6 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
17
|
__exportStar(require("./components/ps-data-table"), exports);
|
|
18
18
|
__exportStar(require("./components/ps-table-pagination"), exports);
|
|
19
|
-
__exportStar(require("./components/ps-table-row-actions"), exports);
|
|
20
19
|
__exportStar(require("./constants/table-filter-kind"), exports);
|
|
21
20
|
__exportStar(require("./interfaces/table-column"), exports);
|
|
22
21
|
__exportStar(require("./interfaces/table-column-filter"), exports);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pallasoft/ps-table-components",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.5.0",
|
|
4
4
|
"private": false,
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"types": "./dist/index.d.ts",
|
|
@@ -68,9 +68,10 @@
|
|
|
68
68
|
"url": "git+https://github.com/pallasoft/ps-table-components.git"
|
|
69
69
|
},
|
|
70
70
|
"dependencies": {
|
|
71
|
-
"@pallasoft/ps-
|
|
72
|
-
"@pallasoft/ps-
|
|
73
|
-
"@pallasoft/ps-
|
|
71
|
+
"@pallasoft/ps-core-components": "^2.2.0",
|
|
72
|
+
"@pallasoft/ps-design-system": "^1.3.0",
|
|
73
|
+
"@pallasoft/ps-icons": "^1.5.0",
|
|
74
|
+
"@pallasoft/ps-input-components": "^1.6.1",
|
|
74
75
|
"@pallasoft/ps-motion-components": "^1.1.0",
|
|
75
76
|
"react-aria-components": "^1.21.1"
|
|
76
77
|
}
|
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
import type { PsTableRowAction } from '../interfaces/table-row-action';
|
|
2
|
-
export interface PsTableRowActionsProps {
|
|
3
|
-
actions: PsTableRowAction[];
|
|
4
|
-
label: string;
|
|
5
|
-
}
|
|
6
|
-
export declare const PsTableRowActions: ({ actions, label }: PsTableRowActionsProps) => import("react").JSX.Element;
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.PsTableRowActions = 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_icons_1 = require("@pallasoft/ps-icons");
|
|
7
|
-
const react_aria_components_1 = require("react-aria-components");
|
|
8
|
-
const PsTableRowActions = ({ actions, label }) => ((0, jsx_runtime_1.jsxs)(react_aria_components_1.MenuTrigger, { children: [(0, jsx_runtime_1.jsx)(react_aria_components_1.Button, { "aria-label": label, className: 'ps-focus-ring inline-flex h-9 w-9 items-center justify-center rounded-xl text-ink/55 outline-none transition-colors hover:bg-ink/5 hover:text-ink data-[pressed]:bg-ink/10', children: (0, jsx_runtime_1.jsx)(ps_icons_1.PsIcon, { "aria-hidden": 'true', className: 'block h-5 w-5', iconKey: ps_icons_1.PsIconKey.More }) }), (0, jsx_runtime_1.jsx)(react_aria_components_1.Popover, { className: 'ps-floating-panel min-w-44 p-1.5 outline-none', offset: 4, placement: 'bottom end', children: (0, jsx_runtime_1.jsx)(react_aria_components_1.Menu, { className: 'outline-none', disabledKeys: actions.filter((action) => action.isDisabled).map((action) => action.id), onAction: (key) => actions.find((action) => action.id === key)?.onSelect(), children: actions.map((action) => ((0, jsx_runtime_1.jsx)(react_aria_components_1.MenuItem, { className: ps_design_system_1.PallasoftClassNameService.merge('ps-floating-option', action.isDanger ? 'text-danger' : 'text-ink'), id: action.id, textValue: action.label, children: action.label }, action.id))) }) })] }));
|
|
9
|
-
exports.PsTableRowActions = PsTableRowActions;
|