@pallasoft/ps-table-components 1.11.0 → 1.13.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 -1
- package/dist/components/ps-data-table.js +5 -3
- package/dist/components/ps-table-column-picker.js +1 -1
- package/dist/components/ps-table-toolbar.js +2 -2
- package/dist/constants/table-config.d.ts +1 -0
- package/dist/constants/table-config.js +1 -0
- package/dist/esm/components/ps-data-table.js +5 -3
- package/dist/esm/components/ps-table-column-picker.js +1 -1
- package/dist/esm/components/ps-table-toolbar.js +2 -2
- package/dist/esm/constants/table-config.js +1 -0
- package/package.json +6 -6
|
@@ -18,6 +18,7 @@ export interface PsDataTableProps<RowData> {
|
|
|
18
18
|
getSearchText?: (row: RowData) => string;
|
|
19
19
|
grouping?: PsTableGrouping<RowData>;
|
|
20
20
|
isLoading?: boolean;
|
|
21
|
+
layout?: 'auto' | 'fixed';
|
|
21
22
|
onPageChange?: (page: number) => void;
|
|
22
23
|
onQueryChange?: (query: PsTableQuery) => void;
|
|
23
24
|
onRowClick?: (row: RowData) => void;
|
|
@@ -31,4 +32,4 @@ export interface PsDataTableProps<RowData> {
|
|
|
31
32
|
toolbarActions?: ReactNode;
|
|
32
33
|
totalRows?: number;
|
|
33
34
|
}
|
|
34
|
-
export declare const PsDataTable: <RowData>({ caption, className, columns, defaultSort, density, expandedRowIds, mobileLayout, getBulkActions, getRowId, getRowLabel, getSearchText, grouping, isLoading, onPageChange, onQueryChange, onRowClick, onRowHover, page, pageSize, query, renderExpandedRow, rows, searchPlaceholder, toolbarActions, totalRows, }: PsDataTableProps<RowData>) => import("react").JSX.Element;
|
|
35
|
+
export declare const PsDataTable: <RowData>({ caption, className, columns, defaultSort, density, expandedRowIds, mobileLayout, getBulkActions, getRowId, getRowLabel, getSearchText, grouping, isLoading, layout, onPageChange, onQueryChange, onRowClick, onRowHover, page, pageSize, query, renderExpandedRow, rows, searchPlaceholder, toolbarActions, totalRows, }: PsDataTableProps<RowData>) => import("react").JSX.Element;
|
|
@@ -33,7 +33,7 @@ const alignClassNames = {
|
|
|
33
33
|
left: 'text-left',
|
|
34
34
|
right: 'text-right tabular-nums',
|
|
35
35
|
};
|
|
36
|
-
const PsDataTable = ({ caption, className, columns, defaultSort, density = 'normal', expandedRowIds, mobileLayout = 'cards', getBulkActions, getRowId, getRowLabel, getSearchText, grouping, isLoading = false, onPageChange, onQueryChange, onRowClick, onRowHover, page, pageSize, query, renderExpandedRow, rows, searchPlaceholder = table_config_1.PsTableConfig.searchPlaceholder, toolbarActions, totalRows, }) => {
|
|
36
|
+
const PsDataTable = ({ caption, className, columns, defaultSort, density = 'normal', expandedRowIds, mobileLayout = 'cards', getBulkActions, getRowId, getRowLabel, getSearchText, grouping, isLoading = false, layout = 'auto', onPageChange, onQueryChange, onRowClick, onRowHover, page, pageSize, query, renderExpandedRow, rows, searchPlaceholder = table_config_1.PsTableConfig.searchPlaceholder, toolbarActions, totalRows, }) => {
|
|
37
37
|
const containerRef = (0, react_1.useRef)(null);
|
|
38
38
|
const [uncontrolledPage, setUncontrolledPage] = (0, react_1.useState)(1);
|
|
39
39
|
const [uncontrolledQuery, setUncontrolledQuery] = (0, react_1.useState)(() => ps_table_query_service_1.PsTableQueryService.empty(defaultSort ? defaultSort : null));
|
|
@@ -78,6 +78,8 @@ const PsDataTable = ({ caption, className, columns, defaultSort, density = 'norm
|
|
|
78
78
|
if (!isExpanded) {
|
|
79
79
|
setOpenedGroupKeys((current) => [...current.filter((key) => key !== groupKey), groupKey]);
|
|
80
80
|
flipGroup(groupKey);
|
|
81
|
+
window.setTimeout(() => setOpenedGroupKeys((current) => current.filter((key) => key !== groupKey)), table_config_1.PsTableConfig.groupOpenMs +
|
|
82
|
+
table_config_1.PsTableConfig.groupStaggerLimit * table_config_1.PsTableConfig.groupRowStaggerMs);
|
|
81
83
|
return;
|
|
82
84
|
}
|
|
83
85
|
setClosingGroupKeys((current) => [...current, groupKey]);
|
|
@@ -163,7 +165,7 @@ const PsDataTable = ({ caption, className, columns, defaultSort, density = 'norm
|
|
|
163
165
|
}
|
|
164
166
|
: undefined, style: motion && motion.delayMs !== undefined
|
|
165
167
|
? { animationDelay: `${motion.delayMs}ms` }
|
|
166
|
-
: 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 ? column.align : '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", { "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));
|
|
168
|
+
: 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 ? column.align : 'left'], column.wrap ? '' : 'whitespace-nowrap', layout === 'fixed' && !column.wrap ? 'truncate' : '', 'text-sm text-ink'), style: columnStyle(column), 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));
|
|
167
169
|
};
|
|
168
170
|
if (isLoading)
|
|
169
171
|
return ((0, jsx_runtime_1.jsx)(ps_core_components_1.PsSkeletonTable, { className: className, columns: visibleColumns.length, hasToolbar: hasToolbar, rows: table_config_1.PsTableConfig.skeletonRows }));
|
|
@@ -182,7 +184,7 @@ const PsDataTable = ({ caption, className, columns, defaultSort, density = 'norm
|
|
|
182
184
|
? grouping.renderGroupSummary(group.rows)
|
|
183
185
|
: 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}`));
|
|
184
186
|
})
|
|
185
|
-
: renderCardList(visibleRows, 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) })) : 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) => {
|
|
187
|
+
: renderCardList(visibleRows, 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) })) : 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: 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: [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) => {
|
|
186
188
|
const align = column.align !== null && column.align !== undefined ? column.align : 'left';
|
|
187
189
|
const isSorted = sort !== null && sort.columnId === column.id;
|
|
188
190
|
return ((0, jsx_runtime_1.jsx)("th", { "aria-sort": isSorted
|
|
@@ -10,7 +10,7 @@ const react_aria_components_1 = require("react-aria-components");
|
|
|
10
10
|
const PsTableColumnPicker = ({ columns, hiddenColumnIds, onChange, }) => {
|
|
11
11
|
const zIndex = (0, ps_core_components_1.usePsLayerZIndex)(ps_design_system_1.PallasoftZIndex.Dropdown);
|
|
12
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-
|
|
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-input-control ps-focus-ring ps-control inline-flex w-auto min-w-11 items-center justify-center gap-2 rounded-ps-control 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
14
|
const isVisible = !hiddenColumnIds.includes(column.id);
|
|
15
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
|
|
16
16
|
? [...hiddenColumnIds, column.id]
|
|
@@ -8,11 +8,11 @@ const ps_icons_1 = require("@pallasoft/ps-icons");
|
|
|
8
8
|
const react_aria_components_1 = require("react-aria-components");
|
|
9
9
|
const ps_table_query_service_1 = require("../services/ps-table-query-service");
|
|
10
10
|
const ps_table_filter_field_1 = require("./ps-table-filter-field");
|
|
11
|
-
const toolbarButtonClassName = 'ps-
|
|
11
|
+
const toolbarButtonClassName = 'ps-input-control ps-focus-ring ps-control inline-flex w-auto min-w-11 items-center justify-center gap-2 rounded-ps-control px-3 text-sm font-semibold text-ink outline-none transition-colors hover:border-primary/40 sm:px-4';
|
|
12
12
|
const PsTableToolbar = ({ actions, columns, filters, isSearchable, onClearFilters, onFilterChange, onSearchChange, rows, search, searchPlaceholder, }) => {
|
|
13
13
|
const filterableColumns = columns.filter((column) => column.filter);
|
|
14
14
|
const zIndex = (0, ps_core_components_1.usePsLayerZIndex)(ps_design_system_1.PallasoftZIndex.Dropdown);
|
|
15
15
|
const activeCount = filterableColumns.filter((column) => ps_table_query_service_1.PsTableQueryService.isActive(filters[column.id])).length;
|
|
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
|
|
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 ps-control rounded-ps-control pl-10 text-sm', onChange: (event) => onSearchChange(event.target.value), placeholder: searchPlaceholder, type: 'search', value: search })] })) : null, (0, jsx_runtime_1.jsxs)("div", { className: 'ps-scrollbar-hidden flex w-full min-w-0 items-center gap-2 overflow-x-auto sm:w-auto sm:flex-1 sm:overflow-visible', children: [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-hidden 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 shrink-0 items-center gap-2', children: actions }) : null] })] }));
|
|
17
17
|
};
|
|
18
18
|
exports.PsTableToolbar = PsTableToolbar;
|
|
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.PsTableConfig = void 0;
|
|
4
4
|
exports.PsTableConfig = {
|
|
5
5
|
groupCloseMs: 160,
|
|
6
|
+
groupOpenMs: 280,
|
|
6
7
|
groupRowStaggerMs: 16,
|
|
7
8
|
groupStaggerLimit: 12,
|
|
8
9
|
noMatchesDescription: 'Try a different search or clear the filters.',
|
|
@@ -30,7 +30,7 @@ const alignClassNames = {
|
|
|
30
30
|
left: 'text-left',
|
|
31
31
|
right: 'text-right tabular-nums',
|
|
32
32
|
};
|
|
33
|
-
export const PsDataTable = ({ caption, className, columns, defaultSort, density = 'normal', expandedRowIds, mobileLayout = 'cards', getBulkActions, getRowId, getRowLabel, getSearchText, grouping, isLoading = false, onPageChange, onQueryChange, onRowClick, onRowHover, page, pageSize, query, renderExpandedRow, rows, searchPlaceholder = PsTableConfig.searchPlaceholder, toolbarActions, totalRows, }) => {
|
|
33
|
+
export const PsDataTable = ({ caption, className, columns, defaultSort, density = 'normal', expandedRowIds, mobileLayout = 'cards', getBulkActions, getRowId, getRowLabel, getSearchText, grouping, isLoading = false, layout = 'auto', onPageChange, onQueryChange, onRowClick, onRowHover, page, pageSize, query, renderExpandedRow, rows, searchPlaceholder = PsTableConfig.searchPlaceholder, toolbarActions, totalRows, }) => {
|
|
34
34
|
const containerRef = useRef(null);
|
|
35
35
|
const [uncontrolledPage, setUncontrolledPage] = useState(1);
|
|
36
36
|
const [uncontrolledQuery, setUncontrolledQuery] = useState(() => PsTableQueryService.empty(defaultSort ? defaultSort : null));
|
|
@@ -75,6 +75,8 @@ export const PsDataTable = ({ caption, className, columns, defaultSort, density
|
|
|
75
75
|
if (!isExpanded) {
|
|
76
76
|
setOpenedGroupKeys((current) => [...current.filter((key) => key !== groupKey), groupKey]);
|
|
77
77
|
flipGroup(groupKey);
|
|
78
|
+
window.setTimeout(() => setOpenedGroupKeys((current) => current.filter((key) => key !== groupKey)), PsTableConfig.groupOpenMs +
|
|
79
|
+
PsTableConfig.groupStaggerLimit * PsTableConfig.groupRowStaggerMs);
|
|
78
80
|
return;
|
|
79
81
|
}
|
|
80
82
|
setClosingGroupKeys((current) => [...current, groupKey]);
|
|
@@ -160,7 +162,7 @@ export const PsDataTable = ({ caption, className, columns, defaultSort, density
|
|
|
160
162
|
}
|
|
161
163
|
: undefined, style: motion && motion.delayMs !== undefined
|
|
162
164
|
? { animationDelay: `${motion.delayMs}ms` }
|
|
163
|
-
: undefined, tabIndex: onRowClick ? 0 : undefined, children: [isSelectable ? (_jsx("td", { className: 'w-10 pl-4 pr-0', onClick: (event) => event.stopPropagation(), onKeyDown: (event) => event.stopPropagation(), children: _jsx(PsCheckbox, { isSelected: selectedIds.includes(rowId), label: `Select ${rowLabel}`, onChange: () => toggleRow(rowId) }) })) : null, visibleColumns.map((column) => (_jsx("td", { className: PallasoftClassNameService.merge(densityClassNames[density].cell, alignClassNames[column.align !== null && column.align !== undefined ? column.align : 'left'], column.wrap ? '' : 'whitespace-nowrap', 'text-sm text-ink'), style: columnStyle(column), children: column.render(row) }, column.id)))] }), renderExpandedRow ? (_jsx("tr", { "aria-hidden": !isExpanded, className: isExpanded ? 'border-t-0' : 'border-0', children: _jsx("td", { className: 'p-0', colSpan: columnCount, children: _jsx(PsCollapse, { isOpen: isExpanded, children: _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));
|
|
165
|
+
: undefined, tabIndex: onRowClick ? 0 : undefined, children: [isSelectable ? (_jsx("td", { className: 'w-10 pl-4 pr-0', onClick: (event) => event.stopPropagation(), onKeyDown: (event) => event.stopPropagation(), children: _jsx(PsCheckbox, { isSelected: selectedIds.includes(rowId), label: `Select ${rowLabel}`, onChange: () => toggleRow(rowId) }) })) : null, visibleColumns.map((column) => (_jsx("td", { className: PallasoftClassNameService.merge(densityClassNames[density].cell, alignClassNames[column.align !== null && column.align !== undefined ? column.align : 'left'], column.wrap ? '' : 'whitespace-nowrap', layout === 'fixed' && !column.wrap ? 'truncate' : '', 'text-sm text-ink'), style: columnStyle(column), children: column.render(row) }, column.id)))] }), renderExpandedRow ? (_jsx("tr", { "aria-hidden": !isExpanded, className: isExpanded ? 'border-t-0' : 'border-0', children: _jsx("td", { className: 'p-0', colSpan: columnCount, children: _jsx(PsCollapse, { isOpen: isExpanded, children: _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));
|
|
164
166
|
};
|
|
165
167
|
if (isLoading)
|
|
166
168
|
return (_jsx(PsSkeletonTable, { className: className, columns: visibleColumns.length, hasToolbar: hasToolbar, rows: PsTableConfig.skeletonRows }));
|
|
@@ -179,7 +181,7 @@ export const PsDataTable = ({ caption, className, columns, defaultSort, density
|
|
|
179
181
|
? grouping.renderGroupSummary(group.rows)
|
|
180
182
|
: undefined }), _jsx(PsCollapse, { isOpen: isExpanded && !closingGroupKeys.includes(group.key), children: renderCardList(group.rows, null) })] }, `group-${group.key}`));
|
|
181
183
|
})
|
|
182
|
-
: renderCardList(visibleRows, visibleRows.length === 0 && isQueried ? (_jsxs("div", { className: 'px-4 py-10 text-center', children: [_jsx("p", { className: 'text-sm font-semibold text-ink', children: PsTableConfig.noMatchesTitle }), _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) })) : null, _jsx("div", { className: PallasoftClassNameService.merge('ps-scrollbar overflow-x-auto', mobileLayout === 'cards' ? 'hidden sm:block' : ''), children: _jsxs("table", { className: 'w-full border-collapse text-left', children: [caption ? _jsx("caption", { className: 'sr-only', children: caption }) : null, _jsx("thead", { className: 'bg-mist/70 text-[0.68rem] font-semibold uppercase tracking-[0.18em] text-ink/45', children: _jsxs("tr", { children: [isSelectable ? (_jsx("th", { className: 'w-10 pl-4 pr-0', scope: 'col', children: _jsx(PsCheckbox, { isIndeterminate: !isPageSelected && pageIds.some((rowId) => selectedIds.includes(rowId)), isSelected: isPageSelected, label: 'Select all rows on this page', onChange: togglePage }) })) : null, visibleColumns.map((column) => {
|
|
184
|
+
: renderCardList(visibleRows, visibleRows.length === 0 && isQueried ? (_jsxs("div", { className: 'px-4 py-10 text-center', children: [_jsx("p", { className: 'text-sm font-semibold text-ink', children: PsTableConfig.noMatchesTitle }), _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) })) : null, _jsx("div", { className: PallasoftClassNameService.merge('ps-scrollbar overflow-x-auto', mobileLayout === 'cards' ? 'hidden sm:block' : ''), children: _jsxs("table", { className: PallasoftClassNameService.merge('w-full border-collapse text-left', layout === 'fixed' ? 'table-fixed' : ''), children: [caption ? _jsx("caption", { className: 'sr-only', children: caption }) : null, _jsx("thead", { className: 'bg-mist/70 text-[0.68rem] font-semibold uppercase tracking-[0.18em] text-ink/45', children: _jsxs("tr", { children: [isSelectable ? (_jsx("th", { className: 'w-10 pl-4 pr-0', scope: 'col', children: _jsx(PsCheckbox, { isIndeterminate: !isPageSelected && pageIds.some((rowId) => selectedIds.includes(rowId)), isSelected: isPageSelected, label: 'Select all rows on this page', onChange: togglePage }) })) : null, visibleColumns.map((column) => {
|
|
183
185
|
const align = column.align !== null && column.align !== undefined ? column.align : 'left';
|
|
184
186
|
const isSorted = sort !== null && sort.columnId === column.id;
|
|
185
187
|
return (_jsx("th", { "aria-sort": isSorted
|
|
@@ -7,7 +7,7 @@ import { Button, Dialog, DialogTrigger, Popover } from 'react-aria-components';
|
|
|
7
7
|
export const PsTableColumnPicker = ({ columns, hiddenColumnIds, onChange, }) => {
|
|
8
8
|
const zIndex = usePsLayerZIndex(PallasoftZIndex.Dropdown);
|
|
9
9
|
const visibleCount = columns.filter((column) => !hiddenColumnIds.includes(column.id)).length;
|
|
10
|
-
return (_jsxs(DialogTrigger, { children: [_jsxs(Button, { className: 'ps-
|
|
10
|
+
return (_jsxs(DialogTrigger, { children: [_jsxs(Button, { className: 'ps-input-control ps-focus-ring ps-control inline-flex w-auto min-w-11 items-center justify-center gap-2 rounded-ps-control px-3 text-sm font-semibold text-ink outline-none transition-colors hover:border-primary/40 sm:px-4', children: [_jsx(PsIcon, { "aria-hidden": 'true', className: 'block h-4 w-4 sm:hidden', iconKey: PsIconKey.Columns }), _jsx("span", { className: 'sr-only sm:not-sr-only', children: "Columns" }), _jsx(PsIcon, { "aria-hidden": 'true', className: 'hidden h-4 w-4 sm:block', iconKey: PsIconKey.Chevron })] }), _jsx(Popover, { className: 'ps-floating-panel w-60 outline-none', offset: 6, placement: 'bottom end', style: { zIndex }, children: _jsx(Dialog, { "aria-label": 'Columns', className: 'flex flex-col gap-0.5 p-1.5 outline-none', children: _jsx(PsLayer, { zIndex: zIndex, children: columns.map((column) => {
|
|
11
11
|
const isVisible = !hiddenColumnIds.includes(column.id);
|
|
12
12
|
return (_jsx(PsCheckbox, { className: 'ps-floating-option w-full', isDisabled: isVisible && visibleCount <= 1, isSelected: isVisible, label: column.label, onChange: () => onChange(isVisible
|
|
13
13
|
? [...hiddenColumnIds, column.id]
|
|
@@ -5,10 +5,10 @@ import { PsIcon, PsIconKey } from '@pallasoft/ps-icons';
|
|
|
5
5
|
import { Button, Dialog, DialogTrigger, Popover } from 'react-aria-components';
|
|
6
6
|
import { PsTableQueryService } from '../services/ps-table-query-service';
|
|
7
7
|
import { PsTableFilterField } from './ps-table-filter-field';
|
|
8
|
-
const toolbarButtonClassName = 'ps-
|
|
8
|
+
const toolbarButtonClassName = 'ps-input-control ps-focus-ring ps-control inline-flex w-auto min-w-11 items-center justify-center gap-2 rounded-ps-control px-3 text-sm font-semibold text-ink outline-none transition-colors hover:border-primary/40 sm:px-4';
|
|
9
9
|
export const PsTableToolbar = ({ actions, columns, filters, isSearchable, onClearFilters, onFilterChange, onSearchChange, rows, search, searchPlaceholder, }) => {
|
|
10
10
|
const filterableColumns = columns.filter((column) => column.filter);
|
|
11
11
|
const zIndex = usePsLayerZIndex(PallasoftZIndex.Dropdown);
|
|
12
12
|
const activeCount = filterableColumns.filter((column) => PsTableQueryService.isActive(filters[column.id])).length;
|
|
13
|
-
return (_jsxs("div", { className: 'flex flex-wrap items-center gap-2', children: [isSearchable ? (_jsxs("label", { className: 'relative basis-full sm:min-w-[12rem] sm:flex-1 sm:basis-auto sm:max-w-xs', children: [_jsx("span", { className: 'sr-only', children: searchPlaceholder }), _jsx(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: PsIconKey.Search }), _jsx("input", { className: 'ps-input-control ps-focus-ring
|
|
13
|
+
return (_jsxs("div", { className: 'flex flex-wrap items-center gap-2', children: [isSearchable ? (_jsxs("label", { className: 'relative basis-full sm:min-w-[12rem] sm:flex-1 sm:basis-auto sm:max-w-xs', children: [_jsx("span", { className: 'sr-only', children: searchPlaceholder }), _jsx(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: PsIconKey.Search }), _jsx("input", { className: 'ps-input-control ps-focus-ring ps-control rounded-ps-control pl-10 text-sm', onChange: (event) => onSearchChange(event.target.value), placeholder: searchPlaceholder, type: 'search', value: search })] })) : null, _jsxs("div", { className: 'ps-scrollbar-hidden flex w-full min-w-0 items-center gap-2 overflow-x-auto sm:w-auto sm:flex-1 sm:overflow-visible', children: [filterableColumns.length > 0 ? (_jsxs(DialogTrigger, { children: [_jsxs(Button, { className: toolbarButtonClassName, children: [_jsx(PsIcon, { "aria-hidden": 'true', className: 'block h-4 w-4', iconKey: PsIconKey.Filter }), _jsx("span", { className: 'sr-only sm:not-sr-only', children: "Filters" }), activeCount > 0 ? (_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] }), _jsx(Popover, { className: 'ps-floating-panel ps-scrollbar-hidden max-h-[min(34rem,80vh)] w-[min(22rem,calc(100vw-2rem))] overflow-y-auto outline-none', offset: 6, placement: 'bottom start', style: { zIndex }, children: _jsx(Dialog, { "aria-label": 'Filters', className: 'flex flex-col gap-4 p-4 outline-none', children: _jsxs(PsLayer, { zIndex: zIndex, children: [filterableColumns.map((column) => (_jsx(PsTableFilterField, { kind: column.filter ? column.filter.kind : 'text', label: column.label, onChange: (value) => onFilterChange(column.id, value), options: PsTableQueryService.options(rows, column), value: filters[column.id] ? filters[column.id] : {} }, column.id))), _jsx("div", { className: 'flex justify-end border-t border-line pt-3', children: _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 ? (_jsx("button", { className: 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 ? _jsx("div", { className: 'ml-auto flex shrink-0 items-center gap-2', children: actions }) : null] })] }));
|
|
14
14
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pallasoft/ps-table-components",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.13.0",
|
|
4
4
|
"private": false,
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"module": "./dist/esm/index.js",
|
|
@@ -71,11 +71,11 @@
|
|
|
71
71
|
"url": "git+https://github.com/pallasoft/ps-table-components.git"
|
|
72
72
|
},
|
|
73
73
|
"dependencies": {
|
|
74
|
-
"@pallasoft/ps-core-components": "^2.
|
|
75
|
-
"@pallasoft/ps-design-system": "^1.
|
|
76
|
-
"@pallasoft/ps-icons": "^1.5.
|
|
77
|
-
"@pallasoft/ps-input-components": "^1.
|
|
78
|
-
"@pallasoft/ps-motion-components": "^1.
|
|
74
|
+
"@pallasoft/ps-core-components": "^2.10.0",
|
|
75
|
+
"@pallasoft/ps-design-system": "^1.5.0",
|
|
76
|
+
"@pallasoft/ps-icons": "^1.5.4",
|
|
77
|
+
"@pallasoft/ps-input-components": "^1.14.0",
|
|
78
|
+
"@pallasoft/ps-motion-components": "^1.2.0",
|
|
79
79
|
"react-aria-components": "^1.21.1"
|
|
80
80
|
}
|
|
81
81
|
}
|