@pallasoft/ps-table-components 1.22.0 → 1.22.2
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.js +3 -2
- package/dist/components/ps-table-bulk-bar.js +3 -2
- package/dist/components/ps-table-column-picker.js +2 -1
- package/dist/components/ps-table-export-button.js +1 -1
- package/dist/components/ps-table-group-header.js +1 -1
- package/dist/components/ps-table-pagination.js +2 -2
- package/dist/components/ps-table-reorder-handle.js +1 -1
- package/dist/components/ps-table-sort-header.js +1 -1
- package/dist/components/ps-table-toolbar.js +2 -2
- package/dist/constants/ps-table-control-classes.d.ts +9 -0
- package/dist/constants/ps-table-control-classes.js +12 -0
- package/dist/esm/components/ps-data-table.js +3 -2
- package/dist/esm/components/ps-table-bulk-bar.js +3 -2
- package/dist/esm/components/ps-table-column-picker.js +2 -1
- package/dist/esm/components/ps-table-export-button.js +1 -1
- package/dist/esm/components/ps-table-group-header.js +1 -1
- package/dist/esm/components/ps-table-pagination.js +2 -2
- package/dist/esm/components/ps-table-reorder-handle.js +1 -1
- package/dist/esm/components/ps-table-sort-header.js +1 -1
- package/dist/esm/components/ps-table-toolbar.js +2 -2
- package/dist/esm/constants/ps-table-control-classes.js +9 -0
- package/package.json +3 -3
|
@@ -41,6 +41,7 @@ const ps_design_system_1 = require("@pallasoft/ps-design-system");
|
|
|
41
41
|
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
|
+
const ps_table_control_classes_1 = require("../constants/ps-table-control-classes");
|
|
44
45
|
const table_config_1 = require("../constants/table-config");
|
|
45
46
|
const use_ps_incremental_count_1 = require("../hooks/use-ps-incremental-count");
|
|
46
47
|
const use_ps_scroll_anchor_1 = require("../hooks/use-ps-scroll-anchor");
|
|
@@ -312,7 +313,7 @@ const PsDataTable = ({ caption, className, columns, defaultSort, density = 'norm
|
|
|
312
313
|
? grouping.renderGroupSummary(group.rows)
|
|
313
314
|
: 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}`));
|
|
314
315
|
})
|
|
315
|
-
: 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: '
|
|
316
|
+
: 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', mobileLayout === 'cards' ? 'hidden sm:block' : ''), 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: 'w-9 pl-3 pr-0', 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: 'w-10 pl-4 pr-0', 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) => {
|
|
316
317
|
const align = column.align !== null && column.align !== undefined ? column.align : 'left';
|
|
317
318
|
const isSorted = sort !== null && sort.columnId === column.id;
|
|
318
319
|
return ((0, jsx_runtime_1.jsx)("th", { "aria-sort": isSorted
|
|
@@ -320,7 +321,7 @@ const PsDataTable = ({ caption, className, columns, defaultSort, density = 'norm
|
|
|
320
321
|
: column.sortValue && isQueryable
|
|
321
322
|
? 'none'
|
|
322
323
|
: undefined, className: ps_design_system_1.PallasoftClassNameService.merge(densityClassNames[density].head, alignClassNames[align], 'whitespace-nowrap'), scope: 'col', style: columnStyle(column), children: column.sortValue && isQueryable ? ((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));
|
|
323
|
-
})] }) }), (0, jsx_runtime_1.jsxs)("tbody", { className: 'divide-y divide-line', ref: bodyRef, children: [visibleRows.length === 0 && isSearching ? ((0, jsx_runtime_1.jsx)("tr", { children: (0, jsx_runtime_1.jsx)("td", { className: 'p-0', colSpan: columnCount, children: (0, jsx_runtime_1.jsx)(ps_table_searching_state_1.PsTableSearchingState, { label: searchingLabel, skeletonRows: table_config_1.PsTableConfig.searchingSkeletonRows }) }) })) : null, visibleRows.length === 0 && isQueried && !isSearching ? ((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: '
|
|
324
|
+
})] }) }), (0, jsx_runtime_1.jsxs)("tbody", { className: 'divide-y divide-line', ref: bodyRef, children: [visibleRows.length === 0 && isSearching ? ((0, jsx_runtime_1.jsx)("tr", { children: (0, jsx_runtime_1.jsx)("td", { className: 'p-0', colSpan: columnCount, children: (0, jsx_runtime_1.jsx)(ps_table_searching_state_1.PsTableSearchingState, { label: searchingLabel, skeletonRows: table_config_1.PsTableConfig.searchingSkeletonRows }) }) })) : null, visibleRows.length === 0 && isQueried && !isSearching ? ((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_design_system_1.PallasoftClassNameService.merge(ps_table_control_classes_1.PsTableControlClasses.textButton, 'mt-3 text-primary hover:underline'), onClick: clearFilters, type: 'button', children: "Clear search and filters" })] }) })) : null, grouping
|
|
324
325
|
? groups.map((group, groupIndex) => {
|
|
325
326
|
const isExpanded = isGroupExpanded(group.key, groupIndex);
|
|
326
327
|
return ((0, jsx_runtime_1.jsxs)(react_1.Fragment, { children: [(0, jsx_runtime_1.jsx)("tr", { children: (0, jsx_runtime_1.jsx)("td", { className: 'p-0', colSpan: columnCount, 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
|
|
@@ -4,10 +4,11 @@ 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
6
|
const ps_icons_1 = require("@pallasoft/ps-icons");
|
|
7
|
+
const ps_table_control_classes_1 = require("../constants/ps-table-control-classes");
|
|
7
8
|
const PsTableBulkBar = ({ actions, onClear, selectedCount }) => {
|
|
8
9
|
const safeActions = actions.filter((action) => !action.isDanger);
|
|
9
10
|
const dangerActions = actions.filter((action) => action.isDanger);
|
|
10
|
-
const renderAction = (action) => ((0, jsx_runtime_1.jsx)("button", { className: ps_design_system_1.PallasoftClassNameService.merge(
|
|
11
|
-
return ((0, jsx_runtime_1.jsxs)("div", { "aria-live": 'polite', className:
|
|
11
|
+
const renderAction = (action) => ((0, jsx_runtime_1.jsx)("button", { className: ps_design_system_1.PallasoftClassNameService.merge(ps_table_control_classes_1.PsTableControlClasses.bulkAction, 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));
|
|
12
|
+
return ((0, jsx_runtime_1.jsxs)("div", { "aria-live": 'polite', className: ps_table_control_classes_1.PsTableControlClasses.bulkBar, children: [(0, jsx_runtime_1.jsxs)("span", { className: ps_table_control_classes_1.PsTableControlClasses.bulkCount, children: [selectedCount, " selected"] }), (0, jsx_runtime_1.jsxs)("div", { className: 'ps-scrollbar-hidden flex min-w-0 flex-1 items-center gap-1 overflow-x-auto', children: [safeActions.map(renderAction), dangerActions.length > 0 && safeActions.length > 0 ? ((0, jsx_runtime_1.jsx)("span", { "aria-hidden": 'true', className: 'mx-1 h-5 w-px shrink-0 bg-line' })) : null, dangerActions.map(renderAction)] }), (0, jsx_runtime_1.jsx)("button", { "aria-label": 'Clear selection', className: ps_table_control_classes_1.PsTableControlClasses.iconButton, onClick: onClear, title: 'Clear selection', type: 'button', children: (0, jsx_runtime_1.jsx)(ps_icons_1.PsIcon, { "aria-hidden": 'true', className: 'h-4 w-4', iconKey: ps_icons_1.PsIconKey.Close }) })] }));
|
|
12
13
|
};
|
|
13
14
|
exports.PsTableBulkBar = PsTableBulkBar;
|
|
@@ -7,10 +7,11 @@ const ps_design_system_1 = require("@pallasoft/ps-design-system");
|
|
|
7
7
|
const ps_icons_1 = require("@pallasoft/ps-icons");
|
|
8
8
|
const ps_input_components_1 = require("@pallasoft/ps-input-components");
|
|
9
9
|
const react_aria_components_1 = require("react-aria-components");
|
|
10
|
+
const ps_table_control_classes_1 = require("../constants/ps-table-control-classes");
|
|
10
11
|
const PsTableColumnPicker = ({ columns, hiddenColumnIds, onChange, }) => {
|
|
11
12
|
const zIndex = (0, ps_core_components_1.usePsLayerZIndex)(ps_design_system_1.PallasoftZIndex.Dropdown);
|
|
12
13
|
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:
|
|
14
|
+
return ((0, jsx_runtime_1.jsxs)(react_aria_components_1.DialogTrigger, { children: [(0, jsx_runtime_1.jsxs)(react_aria_components_1.Button, { className: ps_table_control_classes_1.PsTableControlClasses.toolbarButton, 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
15
|
const isVisible = !hiddenColumnIds.includes(column.id);
|
|
15
16
|
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
17
|
? [...hiddenColumnIds, column.id]
|
|
@@ -3,5 +3,5 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.PsTableExportButton = void 0;
|
|
4
4
|
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
5
5
|
const ps_icons_1 = require("@pallasoft/ps-icons");
|
|
6
|
-
const PsTableExportButton = ({ label, onExport }) => ((0, jsx_runtime_1.jsxs)("button", { className: 'ps-focus-ring ps-liquid ps-liquid-control
|
|
6
|
+
const PsTableExportButton = ({ label, onExport }) => ((0, jsx_runtime_1.jsxs)("button", { className: 'ps-focus-ring ps-liquid ps-liquid-control ps-control ps-control-padding inline-flex min-w-ps-control items-center justify-center gap-2 rounded-ps-control border border-ps-control text-sm font-semibold text-ink transition-colors hover:border-primary/40', onClick: onExport, type: 'button', children: [(0, jsx_runtime_1.jsx)(ps_icons_1.PsIcon, { "aria-hidden": 'true', className: 'block h-4 w-4', iconKey: ps_icons_1.PsIconKey.Download }), (0, jsx_runtime_1.jsx)("span", { className: 'sr-only sm:not-sr-only', children: label })] }));
|
|
7
7
|
exports.PsTableExportButton = PsTableExportButton;
|
|
@@ -4,5 +4,5 @@ exports.PsTableGroupHeader = 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_icons_1 = require("@pallasoft/ps-icons");
|
|
7
|
-
const PsTableGroupHeader = ({ count, isExpanded, label, onToggle, summary, }) => ((0, jsx_runtime_1.jsxs)("button", { "aria-expanded": isExpanded, className: 'ps-focus-ring flex w-full flex-wrap items-center gap-x-3 gap-y-2 bg-mist/60 px-4 py-3 text-left transition-colors hover:bg-mist', onClick: onToggle, type: 'button', children: [(0, jsx_runtime_1.jsx)(ps_icons_1.PsIcon, { "aria-hidden": 'true', className: ps_design_system_1.PallasoftClassNameService.merge('h-4 w-4 shrink-0 text-ink/50 transition-transform duration-200', isExpanded ? '' : '-rotate-90'), iconKey: ps_icons_1.PsIconKey.Chevron }), (0, jsx_runtime_1.jsx)("span", { className: 'text-sm font-semibold text-ink', children: label }), (0, jsx_runtime_1.jsx)("span", { className: 'rounded-
|
|
7
|
+
const PsTableGroupHeader = ({ count, isExpanded, label, onToggle, summary, }) => ((0, jsx_runtime_1.jsxs)("button", { "aria-expanded": isExpanded, className: 'ps-focus-ring flex w-full flex-wrap items-center gap-x-3 gap-y-2 bg-mist/60 px-4 py-3 text-left transition-colors hover:bg-mist', onClick: onToggle, type: 'button', children: [(0, jsx_runtime_1.jsx)(ps_icons_1.PsIcon, { "aria-hidden": 'true', className: ps_design_system_1.PallasoftClassNameService.merge('h-4 w-4 shrink-0 text-ink/50 transition-transform duration-200', isExpanded ? '' : '-rotate-90'), iconKey: ps_icons_1.PsIconKey.Chevron }), (0, jsx_runtime_1.jsx)("span", { className: 'text-sm font-semibold text-ink', children: label }), (0, jsx_runtime_1.jsx)("span", { className: 'rounded-ps-control bg-surface px-2 py-0.5 text-xs font-semibold tabular-nums text-ink/60', children: count }), summary ? ((0, jsx_runtime_1.jsx)("span", { className: 'ml-auto flex flex-wrap items-center justify-end gap-2', children: summary })) : null] }));
|
|
8
8
|
exports.PsTableGroupHeader = PsTableGroupHeader;
|
|
@@ -3,13 +3,13 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
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
|
+
const ps_table_control_classes_1 = require("../constants/ps-table-control-classes");
|
|
6
7
|
const PsTablePagination = ({ className, isPartial = false, loadedPageCount, onPageChange, page, pageCount, pageSize, totalRows, }) => {
|
|
7
8
|
const firstRow = totalRows === 0 ? 0 : (page - 1) * pageSize + 1;
|
|
8
9
|
const lastRow = Math.min(page * pageSize, totalRows);
|
|
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
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
|
|
11
11
|
? '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:
|
|
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
13
|
(loadedPageCount === undefined ? pageCount : Math.min(loadedPageCount, pageCount)), onClick: () => onPageChange(page + 1), type: 'button', children: "Next" })] })] }));
|
|
14
14
|
};
|
|
15
15
|
exports.PsTablePagination = PsTablePagination;
|
|
@@ -4,5 +4,5 @@ exports.PsTableReorderHandle = void 0;
|
|
|
4
4
|
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
5
5
|
const ps_core_components_1 = require("@pallasoft/ps-core-components");
|
|
6
6
|
const ps_design_system_1 = require("@pallasoft/ps-design-system");
|
|
7
|
-
const PsTableReorderHandle = ({ activatorRef, className, label, ...buttonProps }) => ((0, jsx_runtime_1.jsx)("button", { ...buttonProps, "aria-label": label, className: ps_design_system_1.PallasoftClassNameService.merge('ps-focus-ring flex h-7 w-6 shrink-0 cursor-grab touch-none items-center justify-center rounded-
|
|
7
|
+
const PsTableReorderHandle = ({ activatorRef, className, label, ...buttonProps }) => ((0, jsx_runtime_1.jsx)("button", { ...buttonProps, "aria-label": label, className: ps_design_system_1.PallasoftClassNameService.merge('ps-focus-ring flex h-7 w-6 shrink-0 cursor-grab touch-none items-center justify-center rounded-ps-control text-ink/40 transition-colors hover:bg-mist hover:text-ink active:cursor-grabbing', className), onClick: (event) => event.stopPropagation(), ref: activatorRef, title: label, type: 'button', children: (0, jsx_runtime_1.jsx)(ps_core_components_1.PsDragGrip, {}) }));
|
|
8
8
|
exports.PsTableReorderHandle = PsTableReorderHandle;
|
|
@@ -11,7 +11,7 @@ const PsTableSortHeader = ({ align, columnId, label, onSort, sort, }) => {
|
|
|
11
11
|
: sort.direction === 'ascending'
|
|
12
12
|
? ps_icons_1.PsIconKey.SortAscending
|
|
13
13
|
: ps_icons_1.PsIconKey.SortDescending;
|
|
14
|
-
return ((0, jsx_runtime_1.jsxs)("button", { className: ps_design_system_1.PallasoftClassNameService.merge('ps-focus-ring group inline-flex items-center gap-1 rounded-
|
|
14
|
+
return ((0, jsx_runtime_1.jsxs)("button", { className: ps_design_system_1.PallasoftClassNameService.merge('ps-focus-ring group inline-flex items-center gap-1 rounded-ps-control uppercase tracking-[0.18em] transition-colors hover:text-ink', align === 'right' ? 'flex-row-reverse' : '', isSorted ? 'text-ink' : ''), onClick: () => onSort(columnId), type: 'button', children: [(0, jsx_runtime_1.jsx)("span", { children: label }), (0, jsx_runtime_1.jsx)(ps_icons_1.PsIcon, { "aria-hidden": 'true', className: ps_design_system_1.PallasoftClassNameService.merge('block h-3.5 w-3.5 shrink-0', isSorted
|
|
15
15
|
? 'text-primary'
|
|
16
16
|
: 'opacity-0 group-hover:opacity-60 group-focus-visible:opacity-60'), iconKey: iconKey })] }));
|
|
17
17
|
};
|
|
@@ -6,13 +6,13 @@ const ps_core_components_1 = require("@pallasoft/ps-core-components");
|
|
|
6
6
|
const ps_design_system_1 = require("@pallasoft/ps-design-system");
|
|
7
7
|
const ps_icons_1 = require("@pallasoft/ps-icons");
|
|
8
8
|
const react_aria_components_1 = require("react-aria-components");
|
|
9
|
+
const ps_table_control_classes_1 = require("../constants/ps-table-control-classes");
|
|
9
10
|
const ps_table_query_service_1 = require("../services/ps-table-query-service");
|
|
10
11
|
const ps_table_filter_field_1 = require("./ps-table-filter-field");
|
|
11
|
-
const toolbarButtonClassName = 'ps-input-control ps-control-trigger ps-focus-ring ps-control ps-control-padding inline-flex min-w-11 items-center justify-center gap-2 rounded-ps-control text-sm font-semibold text-ink outline-none transition-colors hover:border-primary/40';
|
|
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 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 flex-1 items-center gap-2 overflow-x-auto sm:w-auto', 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:
|
|
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 flex-1 items-center gap-2 overflow-x-auto sm:w-auto', 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: ps_table_control_classes_1.PsTableControlClasses.toolbarButton, 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_design_system_1.PallasoftClassNameService.merge(ps_table_control_classes_1.PsTableControlClasses.textButton, '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_table_control_classes_1.PsTableControlClasses.textButton, '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;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export declare const PsTableControlClasses: {
|
|
2
|
+
readonly bulkAction: "ps-focus-ring ps-control-compact ps-control-padding-compact inline-flex shrink-0 items-center whitespace-nowrap rounded-ps-control text-sm font-semibold transition-colors disabled:opacity-40";
|
|
3
|
+
readonly bulkBar: "ps-control-large flex items-center gap-2 rounded-ps-control border border-primary/30 bg-primary/10 py-1 pl-1 pr-1";
|
|
4
|
+
readonly bulkCount: "ps-control-compact ps-control-padding-compact inline-flex shrink-0 items-center rounded-ps-control bg-primary text-sm font-semibold tabular-nums text-white";
|
|
5
|
+
readonly iconButton: "ps-focus-ring ps-control-square ps-control-compact inline-flex shrink-0 items-center justify-center rounded-ps-control text-ink/60 transition-colors hover:bg-ink/5 hover:text-ink";
|
|
6
|
+
readonly paginationButton: "ps-focus-ring ps-control-compact ps-control-padding-compact inline-flex items-center rounded-ps-control border border-ps-control border-line text-sm font-semibold text-ink transition-colors disabled:cursor-not-allowed disabled:opacity-40 enabled:hover:border-primary/40";
|
|
7
|
+
readonly textButton: "ps-focus-ring ps-control-compact ps-control-padding-compact inline-flex items-center rounded-ps-control text-sm font-semibold";
|
|
8
|
+
readonly toolbarButton: "ps-input-control ps-control-trigger ps-focus-ring ps-control ps-control-padding inline-flex min-w-ps-control items-center justify-center gap-2 rounded-ps-control text-sm font-semibold text-ink outline-none transition-colors hover:border-primary/40";
|
|
9
|
+
};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.PsTableControlClasses = void 0;
|
|
4
|
+
exports.PsTableControlClasses = {
|
|
5
|
+
bulkAction: 'ps-focus-ring ps-control-compact ps-control-padding-compact inline-flex shrink-0 items-center whitespace-nowrap rounded-ps-control text-sm font-semibold transition-colors disabled:opacity-40',
|
|
6
|
+
bulkBar: 'ps-control-large flex items-center gap-2 rounded-ps-control border border-primary/30 bg-primary/10 py-1 pl-1 pr-1',
|
|
7
|
+
bulkCount: 'ps-control-compact ps-control-padding-compact inline-flex shrink-0 items-center rounded-ps-control bg-primary text-sm font-semibold tabular-nums text-white',
|
|
8
|
+
iconButton: 'ps-focus-ring ps-control-square ps-control-compact inline-flex shrink-0 items-center justify-center rounded-ps-control text-ink/60 transition-colors hover:bg-ink/5 hover:text-ink',
|
|
9
|
+
paginationButton: 'ps-focus-ring ps-control-compact ps-control-padding-compact inline-flex items-center rounded-ps-control border border-ps-control border-line text-sm font-semibold text-ink transition-colors disabled:cursor-not-allowed disabled:opacity-40 enabled:hover:border-primary/40',
|
|
10
|
+
textButton: 'ps-focus-ring ps-control-compact ps-control-padding-compact inline-flex items-center rounded-ps-control text-sm font-semibold',
|
|
11
|
+
toolbarButton: 'ps-input-control ps-control-trigger ps-focus-ring ps-control ps-control-padding inline-flex min-w-ps-control items-center justify-center gap-2 rounded-ps-control text-sm font-semibold text-ink outline-none transition-colors hover:border-primary/40',
|
|
12
|
+
};
|
|
@@ -5,6 +5,7 @@ import { PallasoftClassNameService } from '@pallasoft/ps-design-system';
|
|
|
5
5
|
import { PsCheckbox } from '@pallasoft/ps-input-components';
|
|
6
6
|
import { PsCollapse } from '@pallasoft/ps-motion-components';
|
|
7
7
|
import { useVirtualizer, useWindowVirtualizer } from '@tanstack/react-virtual';
|
|
8
|
+
import { PsTableControlClasses } from '../constants/ps-table-control-classes';
|
|
8
9
|
import { PsTableConfig } from '../constants/table-config';
|
|
9
10
|
import { usePsIncrementalCount } from '../hooks/use-ps-incremental-count';
|
|
10
11
|
import { usePsScrollAnchor } from '../hooks/use-ps-scroll-anchor';
|
|
@@ -276,7 +277,7 @@ export const PsDataTable = ({ caption, className, columns, defaultSort, density
|
|
|
276
277
|
? grouping.renderGroupSummary(group.rows)
|
|
277
278
|
: undefined }), _jsx(PsCollapse, { isOpen: isExpanded && !closingGroupKeys.includes(group.key), children: renderCardList(group.rows, null) })] }, `group-${group.key}`));
|
|
278
279
|
})
|
|
279
|
-
: renderCardList(shouldVirtualize ? visibleRows.slice(0, cards.count) : visibleRows, visibleRows.length === 0 && isSearching ? (_jsx(PsTableSearchingState, { label: searchingLabel, skeletonRows: PsTableConfig.searchingSkeletonRows })) : 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: '
|
|
280
|
+
: renderCardList(shouldVirtualize ? visibleRows.slice(0, cards.count) : visibleRows, visibleRows.length === 0 && isSearching ? (_jsx(PsTableSearchingState, { label: searchingLabel, skeletonRows: PsTableConfig.searchingSkeletonRows })) : 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: PallasoftClassNameService.merge(PsTableControlClasses.textButton, 'mt-2 text-primary'), onClick: clearFilters, type: 'button', children: "Clear search and filters" })] })) : null), !grouping && shouldVirtualize && cards.count < visibleRows.length ? (_jsx("div", { "aria-hidden": 'true', className: 'h-px', ref: cards.sentinelRef })) : null] })) : null, _jsx("div", { className: PallasoftClassNameService.merge('ps-scrollbar overflow-x-auto overflow-y-hidden', mobileLayout === 'cards' ? 'hidden sm:block' : ''), children: renderReorder((api) => (_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: [reorder ? (_jsx("th", { className: 'w-9 pl-3 pr-0', scope: 'col', children: reorder.enabled ? (_jsx("span", { className: 'sr-only', children: reorder.columnLabel })) : reorder.disabledReason ? (_jsx("span", { "aria-label": reorder.disabledReason, className: 'inline-flex cursor-help opacity-40', role: 'img', title: reorder.disabledReason, children: _jsx(PsDragGrip, {}) })) : null })) : null, isSelectable ? (_jsx("th", { className: 'w-10 pl-4 pr-0', scope: 'col', children: _jsx(PsCheckbox, { isIndeterminate: !isPageSelected && pageIds.some((rowId) => selectedIdSet.has(rowId)), isSelected: isPageSelected, label: 'Select all rows on this page', onChange: togglePage }) })) : null, visibleColumns.map((column) => {
|
|
280
281
|
const align = column.align !== null && column.align !== undefined ? column.align : 'left';
|
|
281
282
|
const isSorted = sort !== null && sort.columnId === column.id;
|
|
282
283
|
return (_jsx("th", { "aria-sort": isSorted
|
|
@@ -284,7 +285,7 @@ export const PsDataTable = ({ caption, className, columns, defaultSort, density
|
|
|
284
285
|
: column.sortValue && isQueryable
|
|
285
286
|
? 'none'
|
|
286
287
|
: undefined, className: PallasoftClassNameService.merge(densityClassNames[density].head, alignClassNames[align], 'whitespace-nowrap'), scope: 'col', style: columnStyle(column), children: column.sortValue && isQueryable ? (_jsx(PsTableSortHeader, { align: align, columnId: column.id, label: column.label, onSort: updateSort, sort: sort })) : (column.label) }, column.id));
|
|
287
|
-
})] }) }), _jsxs("tbody", { className: 'divide-y divide-line', ref: bodyRef, children: [visibleRows.length === 0 && isSearching ? (_jsx("tr", { children: _jsx("td", { className: 'p-0', colSpan: columnCount, children: _jsx(PsTableSearchingState, { label: searchingLabel, skeletonRows: PsTableConfig.searchingSkeletonRows }) }) })) : null, visibleRows.length === 0 && isQueried && !isSearching ? (_jsx("tr", { children: _jsxs("td", { className: 'px-4 py-12 text-center', colSpan: columnCount, children: [_jsx("p", { className: 'text-sm font-semibold text-ink', children: PsTableConfig.noMatchesTitle }), _jsx("p", { className: 'mt-1 text-sm text-ink/55', children: PsTableConfig.noMatchesDescription }), _jsx("button", { className: '
|
|
288
|
+
})] }) }), _jsxs("tbody", { className: 'divide-y divide-line', ref: bodyRef, children: [visibleRows.length === 0 && isSearching ? (_jsx("tr", { children: _jsx("td", { className: 'p-0', colSpan: columnCount, children: _jsx(PsTableSearchingState, { label: searchingLabel, skeletonRows: PsTableConfig.searchingSkeletonRows }) }) })) : null, visibleRows.length === 0 && isQueried && !isSearching ? (_jsx("tr", { children: _jsxs("td", { className: 'px-4 py-12 text-center', colSpan: columnCount, children: [_jsx("p", { className: 'text-sm font-semibold text-ink', children: PsTableConfig.noMatchesTitle }), _jsx("p", { className: 'mt-1 text-sm text-ink/55', children: PsTableConfig.noMatchesDescription }), _jsx("button", { className: PallasoftClassNameService.merge(PsTableControlClasses.textButton, 'mt-3 text-primary hover:underline'), onClick: clearFilters, type: 'button', children: "Clear search and filters" })] }) })) : null, grouping
|
|
288
289
|
? groups.map((group, groupIndex) => {
|
|
289
290
|
const isExpanded = isGroupExpanded(group.key, groupIndex);
|
|
290
291
|
return (_jsxs(Fragment, { children: [_jsx("tr", { children: _jsx("td", { className: 'p-0', colSpan: columnCount, children: _jsx(PsTableGroupHeader, { count: group.rows.length, isExpanded: isExpanded, label: grouping.getGroupLabel(group.key, group.rows), onToggle: () => toggleGroup(group.key, isExpanded), summary: grouping.renderGroupSummary
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { PallasoftClassNameService } from '@pallasoft/ps-design-system';
|
|
3
3
|
import { PsIcon, PsIconKey } from '@pallasoft/ps-icons';
|
|
4
|
+
import { PsTableControlClasses } from '../constants/ps-table-control-classes';
|
|
4
5
|
export const PsTableBulkBar = ({ actions, onClear, selectedCount }) => {
|
|
5
6
|
const safeActions = actions.filter((action) => !action.isDanger);
|
|
6
7
|
const dangerActions = actions.filter((action) => action.isDanger);
|
|
7
|
-
const renderAction = (action) => (_jsx("button", { className: PallasoftClassNameService.merge(
|
|
8
|
-
return (_jsxs("div", { "aria-live": 'polite', className:
|
|
8
|
+
const renderAction = (action) => (_jsx("button", { className: PallasoftClassNameService.merge(PsTableControlClasses.bulkAction, 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));
|
|
9
|
+
return (_jsxs("div", { "aria-live": 'polite', className: PsTableControlClasses.bulkBar, children: [_jsxs("span", { className: PsTableControlClasses.bulkCount, children: [selectedCount, " selected"] }), _jsxs("div", { className: 'ps-scrollbar-hidden flex min-w-0 flex-1 items-center gap-1 overflow-x-auto', children: [safeActions.map(renderAction), dangerActions.length > 0 && safeActions.length > 0 ? (_jsx("span", { "aria-hidden": 'true', className: 'mx-1 h-5 w-px shrink-0 bg-line' })) : null, dangerActions.map(renderAction)] }), _jsx("button", { "aria-label": 'Clear selection', className: PsTableControlClasses.iconButton, onClick: onClear, title: 'Clear selection', type: 'button', children: _jsx(PsIcon, { "aria-hidden": 'true', className: 'h-4 w-4', iconKey: PsIconKey.Close }) })] }));
|
|
9
10
|
};
|
|
@@ -4,10 +4,11 @@ import { PallasoftZIndex } from '@pallasoft/ps-design-system';
|
|
|
4
4
|
import { PsIcon, PsIconKey } from '@pallasoft/ps-icons';
|
|
5
5
|
import { PsCheckbox } from '@pallasoft/ps-input-components';
|
|
6
6
|
import { Button, Dialog, DialogTrigger, Popover } from 'react-aria-components';
|
|
7
|
+
import { PsTableControlClasses } from '../constants/ps-table-control-classes';
|
|
7
8
|
export const PsTableColumnPicker = ({ columns, hiddenColumnIds, onChange, }) => {
|
|
8
9
|
const zIndex = usePsLayerZIndex(PallasoftZIndex.Dropdown);
|
|
9
10
|
const visibleCount = columns.filter((column) => !hiddenColumnIds.includes(column.id)).length;
|
|
10
|
-
return (_jsxs(DialogTrigger, { children: [_jsxs(Button, { className:
|
|
11
|
+
return (_jsxs(DialogTrigger, { children: [_jsxs(Button, { className: PsTableControlClasses.toolbarButton, 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
12
|
const isVisible = !hiddenColumnIds.includes(column.id);
|
|
12
13
|
return (_jsx(PsCheckbox, { className: 'ps-floating-option w-full', isDisabled: isVisible && visibleCount <= 1, isSelected: isVisible, label: column.label, onChange: () => onChange(isVisible
|
|
13
14
|
? [...hiddenColumnIds, column.id]
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { PsIcon, PsIconKey } from '@pallasoft/ps-icons';
|
|
3
|
-
export const PsTableExportButton = ({ label, onExport }) => (_jsxs("button", { className: 'ps-focus-ring ps-liquid ps-liquid-control
|
|
3
|
+
export const PsTableExportButton = ({ label, onExport }) => (_jsxs("button", { className: 'ps-focus-ring ps-liquid ps-liquid-control ps-control ps-control-padding inline-flex min-w-ps-control items-center justify-center gap-2 rounded-ps-control border border-ps-control text-sm font-semibold text-ink transition-colors hover:border-primary/40', onClick: onExport, type: 'button', children: [_jsx(PsIcon, { "aria-hidden": 'true', className: 'block h-4 w-4', iconKey: PsIconKey.Download }), _jsx("span", { className: 'sr-only sm:not-sr-only', children: label })] }));
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { PallasoftClassNameService } from '@pallasoft/ps-design-system';
|
|
3
3
|
import { PsIcon, PsIconKey } from '@pallasoft/ps-icons';
|
|
4
|
-
export const PsTableGroupHeader = ({ count, isExpanded, label, onToggle, summary, }) => (_jsxs("button", { "aria-expanded": isExpanded, className: 'ps-focus-ring flex w-full flex-wrap items-center gap-x-3 gap-y-2 bg-mist/60 px-4 py-3 text-left transition-colors hover:bg-mist', onClick: onToggle, type: 'button', children: [_jsx(PsIcon, { "aria-hidden": 'true', className: PallasoftClassNameService.merge('h-4 w-4 shrink-0 text-ink/50 transition-transform duration-200', isExpanded ? '' : '-rotate-90'), iconKey: PsIconKey.Chevron }), _jsx("span", { className: 'text-sm font-semibold text-ink', children: label }), _jsx("span", { className: 'rounded-
|
|
4
|
+
export const PsTableGroupHeader = ({ count, isExpanded, label, onToggle, summary, }) => (_jsxs("button", { "aria-expanded": isExpanded, className: 'ps-focus-ring flex w-full flex-wrap items-center gap-x-3 gap-y-2 bg-mist/60 px-4 py-3 text-left transition-colors hover:bg-mist', onClick: onToggle, type: 'button', children: [_jsx(PsIcon, { "aria-hidden": 'true', className: PallasoftClassNameService.merge('h-4 w-4 shrink-0 text-ink/50 transition-transform duration-200', isExpanded ? '' : '-rotate-90'), iconKey: PsIconKey.Chevron }), _jsx("span", { className: 'text-sm font-semibold text-ink', children: label }), _jsx("span", { className: 'rounded-ps-control bg-surface px-2 py-0.5 text-xs font-semibold tabular-nums text-ink/60', children: count }), summary ? (_jsx("span", { className: 'ml-auto flex flex-wrap items-center justify-end gap-2', children: summary })) : null] }));
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { PallasoftClassNameService } from '@pallasoft/ps-design-system';
|
|
3
|
+
import { PsTableControlClasses } from '../constants/ps-table-control-classes';
|
|
3
4
|
export const PsTablePagination = ({ className, isPartial = false, loadedPageCount, onPageChange, page, pageCount, pageSize, totalRows, }) => {
|
|
4
5
|
const firstRow = totalRows === 0 ? 0 : (page - 1) * pageSize + 1;
|
|
5
6
|
const lastRow = Math.min(page * pageSize, totalRows);
|
|
6
|
-
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';
|
|
7
7
|
return (_jsxs("nav", { "aria-label": 'Pagination', className: PallasoftClassNameService.merge('flex flex-wrap items-center justify-between gap-3 border-t border-line px-4 py-3', className), children: [_jsx("p", { className: 'text-sm text-ink/55', children: totalRows === 0
|
|
8
8
|
? 'No rows'
|
|
9
|
-
: `${firstRow}–${lastRow} of ${totalRows}${isPartial ? '+' : ''}` }), _jsxs("div", { className: 'flex items-center gap-2', children: [_jsx("button", { className:
|
|
9
|
+
: `${firstRow}–${lastRow} of ${totalRows}${isPartial ? '+' : ''}` }), _jsxs("div", { className: 'flex items-center gap-2', children: [_jsx("button", { className: PsTableControlClasses.paginationButton, disabled: page <= 1, onClick: () => onPageChange(page - 1), type: 'button', children: "Previous" }), _jsxs("span", { className: 'hidden text-sm text-ink/65 sm:inline', children: ["Page ", Math.min(page, pageCount), " of ", pageCount] }), _jsx("button", { className: PsTableControlClasses.paginationButton, disabled: page >=
|
|
10
10
|
(loadedPageCount === undefined ? pageCount : Math.min(loadedPageCount, pageCount)), onClick: () => onPageChange(page + 1), type: 'button', children: "Next" })] })] }));
|
|
11
11
|
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
import { PsDragGrip } from '@pallasoft/ps-core-components';
|
|
3
3
|
import { PallasoftClassNameService } from '@pallasoft/ps-design-system';
|
|
4
|
-
export const PsTableReorderHandle = ({ activatorRef, className, label, ...buttonProps }) => (_jsx("button", { ...buttonProps, "aria-label": label, className: PallasoftClassNameService.merge('ps-focus-ring flex h-7 w-6 shrink-0 cursor-grab touch-none items-center justify-center rounded-
|
|
4
|
+
export const PsTableReorderHandle = ({ activatorRef, className, label, ...buttonProps }) => (_jsx("button", { ...buttonProps, "aria-label": label, className: PallasoftClassNameService.merge('ps-focus-ring flex h-7 w-6 shrink-0 cursor-grab touch-none items-center justify-center rounded-ps-control text-ink/40 transition-colors hover:bg-mist hover:text-ink active:cursor-grabbing', className), onClick: (event) => event.stopPropagation(), ref: activatorRef, title: label, type: 'button', children: _jsx(PsDragGrip, {}) }));
|
|
@@ -8,7 +8,7 @@ export const PsTableSortHeader = ({ align, columnId, label, onSort, sort, }) =>
|
|
|
8
8
|
: sort.direction === 'ascending'
|
|
9
9
|
? PsIconKey.SortAscending
|
|
10
10
|
: PsIconKey.SortDescending;
|
|
11
|
-
return (_jsxs("button", { className: PallasoftClassNameService.merge('ps-focus-ring group inline-flex items-center gap-1 rounded-
|
|
11
|
+
return (_jsxs("button", { className: PallasoftClassNameService.merge('ps-focus-ring group inline-flex items-center gap-1 rounded-ps-control uppercase tracking-[0.18em] transition-colors hover:text-ink', align === 'right' ? 'flex-row-reverse' : '', isSorted ? 'text-ink' : ''), onClick: () => onSort(columnId), type: 'button', children: [_jsx("span", { children: label }), _jsx(PsIcon, { "aria-hidden": 'true', className: PallasoftClassNameService.merge('block h-3.5 w-3.5 shrink-0', isSorted
|
|
12
12
|
? 'text-primary'
|
|
13
13
|
: 'opacity-0 group-hover:opacity-60 group-focus-visible:opacity-60'), iconKey: iconKey })] }));
|
|
14
14
|
};
|
|
@@ -3,12 +3,12 @@ import { PsLayer, usePsLayerZIndex } from '@pallasoft/ps-core-components';
|
|
|
3
3
|
import { PallasoftClassNameService, PallasoftZIndex } from '@pallasoft/ps-design-system';
|
|
4
4
|
import { PsIcon, PsIconKey } from '@pallasoft/ps-icons';
|
|
5
5
|
import { Button, Dialog, DialogTrigger, Popover } from 'react-aria-components';
|
|
6
|
+
import { PsTableControlClasses } from '../constants/ps-table-control-classes';
|
|
6
7
|
import { PsTableQueryService } from '../services/ps-table-query-service';
|
|
7
8
|
import { PsTableFilterField } from './ps-table-filter-field';
|
|
8
|
-
const toolbarButtonClassName = 'ps-input-control ps-control-trigger ps-focus-ring ps-control ps-control-padding inline-flex min-w-11 items-center justify-center gap-2 rounded-ps-control text-sm font-semibold text-ink outline-none transition-colors hover:border-primary/40';
|
|
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 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 flex-1 items-center gap-2 overflow-x-auto sm:w-auto', children: [filterableColumns.length > 0 ? (_jsxs(DialogTrigger, { children: [_jsxs(Button, { className:
|
|
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 flex-1 items-center gap-2 overflow-x-auto sm:w-auto', children: [filterableColumns.length > 0 ? (_jsxs(DialogTrigger, { children: [_jsxs(Button, { className: PsTableControlClasses.toolbarButton, 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: PallasoftClassNameService.merge(PsTableControlClasses.textButton, '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(PsTableControlClasses.textButton, '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
|
};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export const PsTableControlClasses = {
|
|
2
|
+
bulkAction: 'ps-focus-ring ps-control-compact ps-control-padding-compact inline-flex shrink-0 items-center whitespace-nowrap rounded-ps-control text-sm font-semibold transition-colors disabled:opacity-40',
|
|
3
|
+
bulkBar: 'ps-control-large flex items-center gap-2 rounded-ps-control border border-primary/30 bg-primary/10 py-1 pl-1 pr-1',
|
|
4
|
+
bulkCount: 'ps-control-compact ps-control-padding-compact inline-flex shrink-0 items-center rounded-ps-control bg-primary text-sm font-semibold tabular-nums text-white',
|
|
5
|
+
iconButton: 'ps-focus-ring ps-control-square ps-control-compact inline-flex shrink-0 items-center justify-center rounded-ps-control text-ink/60 transition-colors hover:bg-ink/5 hover:text-ink',
|
|
6
|
+
paginationButton: 'ps-focus-ring ps-control-compact ps-control-padding-compact inline-flex items-center rounded-ps-control border border-ps-control border-line text-sm font-semibold text-ink transition-colors disabled:cursor-not-allowed disabled:opacity-40 enabled:hover:border-primary/40',
|
|
7
|
+
textButton: 'ps-focus-ring ps-control-compact ps-control-padding-compact inline-flex items-center rounded-ps-control text-sm font-semibold',
|
|
8
|
+
toolbarButton: 'ps-input-control ps-control-trigger ps-focus-ring ps-control ps-control-padding inline-flex min-w-ps-control items-center justify-center gap-2 rounded-ps-control text-sm font-semibold text-ink outline-none transition-colors hover:border-primary/40',
|
|
9
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pallasoft/ps-table-components",
|
|
3
|
-
"version": "1.22.
|
|
3
|
+
"version": "1.22.2",
|
|
4
4
|
"private": false,
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"module": "./dist/esm/index.js",
|
|
@@ -39,6 +39,7 @@
|
|
|
39
39
|
"@commitlint/config-conventional": "^20.0.0",
|
|
40
40
|
"@eslint/compat": "^2.0.0",
|
|
41
41
|
"@ianvs/prettier-plugin-sort-imports": "^4.7.0",
|
|
42
|
+
"@pallasoft/ps-design-system": "^1.14.0",
|
|
42
43
|
"@semantic-release/changelog": "^6.0.3",
|
|
43
44
|
"@semantic-release/commit-analyzer": "^13.0.0",
|
|
44
45
|
"@semantic-release/git": "^10.0.1",
|
|
@@ -78,9 +79,8 @@
|
|
|
78
79
|
"@dnd-kit/sortable": "^10.0.0",
|
|
79
80
|
"@dnd-kit/utilities": "^3.2.2",
|
|
80
81
|
"@pallasoft/ps-core-components": "^2.23.0",
|
|
81
|
-
"@pallasoft/ps-design-system": "^1.5.0",
|
|
82
82
|
"@pallasoft/ps-icons": "^1.5.4",
|
|
83
|
-
"@pallasoft/ps-input-components": "^1.14.0",
|
|
83
|
+
"@pallasoft/ps-input-components": "^1.14.0 || ^2.0.0",
|
|
84
84
|
"@pallasoft/ps-motion-components": "^1.2.0",
|
|
85
85
|
"@tanstack/react-virtual": "^3.14.13",
|
|
86
86
|
"react-aria-components": "^1.21.1"
|